Initial commit: claude-skills with wordcraft-mcp and gridcraft-mcp 0.1.0.
This commit is contained in:
commit
cf01e22a1e
50 files changed
+2726
No files matched your search
@@ -0,0 +1,86 @@
|
||||
# Gemeinsame Funktionen fuer die Skill-Skripte. Wird per Dot-Sourcing eingebunden.
|
||||
# Laeuft unter Windows PowerShell 5.1 und PowerShell 7.
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$Root = Split-Path -Parent $PSScriptRoot
|
||||
$SkillsDir = Join-Path $Root 'skills'
|
||||
$DistDir = Join-Path $Root 'dist'
|
||||
$Utf8NoBom = New-Object System.Text.UTF8Encoding $false
|
||||
|
||||
# Datei als UTF-8 lesen, Zeilenenden auf LF vereinheitlichen.
|
||||
function Read-Text([string]$Path) {
|
||||
return ([IO.File]::ReadAllText($Path, [Text.Encoding]::UTF8) -replace "`r", '')
|
||||
}
|
||||
|
||||
# Datei als UTF-8 ohne BOM mit LF schreiben (Set-Content wuerde in 5.1 ein BOM schreiben).
|
||||
function Write-Text([string]$Path, [string]$Text) {
|
||||
[IO.File]::WriteAllText($Path, $Text, $Utf8NoBom)
|
||||
}
|
||||
|
||||
function Test-Bom([string]$Path) {
|
||||
$b = [IO.File]::ReadAllBytes($Path)
|
||||
return ($b.Length -ge 3 -and $b[0] -eq 0xEF -and $b[1] -eq 0xBB -and $b[2] -eq 0xBF)
|
||||
}
|
||||
|
||||
# Alle Skill-Namen (Ordner unter skills/), ordinal sortiert wie "LC_ALL=C sort".
|
||||
function Get-SkillNames {
|
||||
if (-not (Test-Path $SkillsDir)) { return @() }
|
||||
$names = [string[]]@(Get-ChildItem -Path $SkillsDir -Directory | ForEach-Object { $_.Name })
|
||||
[Array]::Sort($names, [StringComparer]::Ordinal)
|
||||
return $names
|
||||
}
|
||||
|
||||
# Gibt pro Verstoss gegen die Namensregeln einen Text zurueck.
|
||||
function Get-NameErrors([string]$Name) {
|
||||
$e = @()
|
||||
if ($Name -cnotmatch '^[a-z0-9]+(-[a-z0-9]+)*$') { $e += "Name '$Name' ist kein kebab-case (nur a-z, 0-9 und einzelne Bindestriche)" }
|
||||
if ($Name.Length -gt 64) { $e += "Name '$Name' ist laenger als 64 Zeichen" }
|
||||
if ($Name -match 'claude|anthropic') { $e += "Name '$Name' darf nicht 'claude' oder 'anthropic' enthalten" }
|
||||
return $e
|
||||
}
|
||||
|
||||
# Frontmatter-Zeilen (ohne die ---) einer SKILL.md oder $null, wenn keins da ist.
|
||||
function Get-Frontmatter([string]$Path) {
|
||||
$lines = (Read-Text $Path) -split "`n"
|
||||
if ($lines.Count -lt 2 -or $lines[0] -ne '---') { return $null }
|
||||
for ($i = 1; $i -lt $lines.Count; $i++) {
|
||||
if ($lines[$i] -eq '---') {
|
||||
if ($i -eq 1) { return , @() }
|
||||
return , @($lines[1..($i - 1)])
|
||||
}
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
# Rohwert eines Frontmatter-Schluessels (getrimmt, Anfuehrungszeichen noch enthalten) oder $null.
|
||||
function Get-FmRaw($Lines, [string]$Key) {
|
||||
foreach ($l in $Lines) {
|
||||
if ($l -match "^$Key\s*:(.*)$") { return $Matches[1].Trim() }
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
# Wert eines Frontmatter-Schluessels ohne umschliessende Anfuehrungszeichen oder $null.
|
||||
function Get-FmValue($Lines, [string]$Key) {
|
||||
$v = Get-FmRaw $Lines $Key
|
||||
if ($null -eq $v) { return $null }
|
||||
if ($v -match '^"(.*)"$' -or $v -match "^'(.*)'$") { $v = $Matches[1] }
|
||||
return $v
|
||||
}
|
||||
|
||||
# Erste Ueberschrift "## ..." aus CHANGELOG.md oder $null.
|
||||
function Get-ChangelogHeading([string]$Dir) {
|
||||
$p = Join-Path $Dir 'CHANGELOG.md'
|
||||
if (-not (Test-Path $p)) { return $null }
|
||||
foreach ($l in ((Read-Text $p) -split "`n")) {
|
||||
if ($l.StartsWith('## ')) { return $l }
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
# Aktuelle Version eines Skills (oberster CHANGELOG-Eintrag) oder ''.
|
||||
function Get-SkillVersion([string]$Dir) {
|
||||
$h = Get-ChangelogHeading $Dir
|
||||
if ($h -and $h -match '^## (\d+\.\d+\.\d+) \(\d{4}-\d{2}-\d{2}\)\s*$') { return $Matches[1] }
|
||||
return ''
|
||||
}
|
||||
Reference in new issue
Block a user