# Erzeugt die Skill-Uebersicht in README.md zwischen und # neu. Mit -Check wird nur geprueft, ob sie aktuell ist (Exit-Code 1, wenn nicht). # Aufruf: scripts\update-index.ps1 [-Check] param([switch]$Check) . (Join-Path $PSScriptRoot 'lib.ps1') . (Join-Path $PSScriptRoot 'cursor-deeplink.ps1') $RepoWeb = 'https://git.gundel.dev/dg/claude-skills' $readme = Join-Path $Root 'README.md' $current = Read-Text $readme $lines = $current -split "`n" $start = [Array]::IndexOf($lines, '') $end = [Array]::IndexOf($lines, '') if ($start -lt 0 -or $end -lt $start) { Write-Error 'README.md enthaelt die Marker / nicht.' exit 1 } function ConvertTo-MdText([string]$s) { if ([string]::IsNullOrEmpty($s)) { return '' } $map = [ordered]@{ '\' = '\\' '*' = '\*' '_' = '\_' '`' = '\`' '[' = '\[' } foreach ($k in @($map.Keys)) { $s = $s.Replace($k, $map[$k]) } return $s } $ServerKeys = @{ 'wordcraft-mcp' = 'wordcraft' 'gridcraft-mcp' = 'gridcraft' 'pdfcraft-mcp' = 'pdfcraft' 'figcraft-mcp' = 'figcraft' 'vectorcraft-mcp' = 'vectorcraft' 'solidcraft-mcp' = 'solidcraft' } function Get-McpServerKey([string]$SkillName) { if ($ServerKeys.ContainsKey($SkillName)) { return $ServerKeys[$SkillName] } if ($SkillName -match '^(.+)-mcp$') { return $Matches[1] } return $SkillName } # Mittelpunkt als Zeichencode: Windows PowerShell 5.1 liest .ps1 ohne BOM als ANSI. $dot = [char]0x00B7 $table = @() foreach ($n in (Get-SkillNames)) { $dir = Join-Path $SkillsDir $n $desc = '' $skill = Join-Path $dir 'SKILL.md' if (Test-Path $skill) { $fm = Get-Frontmatter $skill if ($null -ne $fm) { $d = Get-FmValue $fm 'description' if ($d) { $desc = $d } } } $lead = $desc.Trim() $note = '' $cut = $lead.IndexOf(' Verwenden') if ($cut -gt 0) { $note = $lead.Substring($cut + 1).Trim() $lead = $lead.Substring(0, $cut).Trim() } if ($lead.Length -gt 0 -and [char]::IsLower($lead[0])) { $lead = $lead.Substring(0, 1).ToUpperInvariant() + $lead.Substring(1) } $ver = Get-SkillVersion $dir $tagEnc = [Uri]::EscapeDataString("$n/v$ver") $base = "$RepoWeb/releases/download/$tagEnc" $zipName = "$n-v$ver.zip" $links = @( "[Doku](skills/$n/README.md)", "[Skill-ZIP]($base/$zipName `"$zipName`")" ) $extPath = Join-Path $dir 'extension\manifest.json' if (Test-Path $extPath) { $mcpbName = "$n-v$ver.mcpb" $cursorName = "$n-cursor-v$ver.zip" $links += "[Erweiterung]($base/$mcpbName `"$mcpbName`")" $links += "[Cursor-Plugin]($base/$cursorName `"$cursorName`")" $man = (Read-Text $extPath) | ConvertFrom-Json $serverKey = Get-McpServerKey $n $cmd = [string]$man.server.mcp_config.command $argsList = New-Object System.Collections.Generic.List[string] foreach ($a in @($man.server.mcp_config.args)) { $s = [string]$a if ($s -eq '${user_config.author}') { $argsList.Add('Claude'); continue } if ($s -eq '${user_config.read_root}') { $argsList.Add('${userHome}/Documents'); continue } if ($s -eq '${user_config.write_root}') { $argsList.Add('${userHome}/Documents/Claude'); continue } $argsList.Add($s) } $transport = @{ command = $cmd; args = @($argsList) } $link = New-CursorDeeplink -ServerName $serverKey -Config $transport $links += "[Add to Cursor]($link)" } if ($table.Count -gt 0) { $table += ''; $table += '---'; $table += '' } $table += "### [$n](skills/$n/) $dot ``v$ver``" $table += '' $table += '> ' + (ConvertTo-MdText $lead) $table += '' if ($note) { $table += '*' + (ConvertTo-MdText $note) + '*' $table += '' } $table += ($links -join " $dot ") } $newLines = @() if ($start -ge 0) { $newLines += $lines[0..$start] } $newLines += $table $newLines += $lines[$end..($lines.Count - 1)] $new = $newLines -join "`n" if ($Check) { if ($new -cne $current) { Write-Host 'README.md ist nicht aktuell - scripts\update-index.ps1 ausfuehren und committen.' exit 1 } Write-Host 'README.md ist aktuell.' } else { Write-Text $readme $new Write-Host 'README.md aktualisiert.' }