Do not bundle CLIs in MCPB packages.

Point extensions at ArtCraft Launcher installs and require WordCraft/GridCraft on the machine.
This commit is contained in:
Dominic Gundel committed 2026-10-19 16:15:08 +02:00
1 parent 2fd4164ee7
commit 2c02038e8c
20 files changed
+96 -69

No files matched your search

+17 -10
View File
@@ -1,6 +1,5 @@
# Copies the ArtCraft-Launcher CLI into skills\<name>\extension\server\
# and writes upstream.json plus LICENSES from the matching upstream tag.
# No GitHub binary download. Requires WordCraft/GridCraft installed via ArtCraft Launcher.
# Checks that the ArtCraft-Launcher CLI is installed and refreshes upstream.json + LICENSES.
# Does NOT copy or ship the EXE into the extension package.
# Usage: scripts\fetch-cli.ps1 -Name <skill-name> [-CliPath <path>]
param(
[Parameter(Mandatory = $true)][string]$Name,
@@ -42,14 +41,22 @@ if (-not (Test-Path -LiteralPath $src)) {
exit 1
}
# Ensure no EXE is left in the extension package from older builds.
$serverDir = Join-Path $ext 'server'
New-Item -ItemType Directory -Force -Path $serverDir | Out-Null
$dest = Join-Path $serverDir $meta.ExeName
Copy-Item -LiteralPath $src -Destination $dest -Force
Get-ChildItem -LiteralPath $serverDir -Filter '*.exe' -ErrorAction SilentlyContinue | Remove-Item -Force
$readme = Join-Path $serverDir 'README.txt'
if (-not (Test-Path $readme)) {
Write-Text $readme @"
Diese Erweiterung enthaelt keine CLI.
Installiere die App ueber den ArtCraft-Launcher.
Erwarteter Pfad: $src
"@
}
$verOut = & $dest --version 2>&1 | Out-String
$verOut = & $src --version 2>&1 | Out-String
if ($LASTEXITCODE -ne 0 -and $Name -eq 'gridcraft-mcp') {
$verOut = & $dest version 2>&1 | Out-String
$verOut = & $src version 2>&1 | Out-String
}
$ver = ''
if ($verOut -match '(\d+\.\d+\.\d+)') { $ver = $Matches[1] }
@@ -58,7 +65,7 @@ if (-not $ver) {
exit 1
}
$hash = (Get-FileHash -LiteralPath $dest -Algorithm SHA256).Hash.ToLowerInvariant()
$hash = (Get-FileHash -LiteralPath $src -Algorithm SHA256).Hash.ToLowerInvariant()
$upstream = @{
source = 'ArtCraft-Launcher'
path = $src
@@ -67,6 +74,7 @@ $upstream = @{
sha256 = $hash
repository = $meta.Repo
tag = "v$ver"
bundled = $false
} | ConvertTo-Json -Compress
Write-Text (Join-Path $ext 'upstream.json') ($upstream + "`n")
@@ -86,5 +94,4 @@ foreach ($f in @('LICENSE-MIT', 'LICENSE-APACHE', 'NOTICE')) {
}
}
Write-Host "OK $Name $ver $hash"
Write-Host " $dest"
Write-Host "OK $Name $ver (nicht gebundelt) $src"
+18 -17
View File
@@ -1,7 +1,6 @@
#!/usr/bin/env bash
# Copies the ArtCraft-Launcher CLI into skills/<name>/extension/server/
# and writes upstream.json plus LICENSES from the matching upstream tag.
# No GitHub binary download. Requires WordCraft/GridCraft via ArtCraft Launcher.
# Checks that the ArtCraft-Launcher CLI is installed and refreshes upstream.json + LICENSES.
# Does NOT copy or ship the EXE into the extension package.
# Usage: scripts/fetch-cli.sh <skill-name> [cli-path]
set -euo pipefail
source "$(dirname "$0")/lib.sh"
@@ -22,15 +21,13 @@ fi
case "$name" in
wordcraft-mcp)
exe_name=wordcraft-cli.exe
default='/mnt/c/Program Files/WordCraft/wordcraft-cli.exe'
[[ -f "$default" ]] || default='C:/Program Files/WordCraft/wordcraft-cli.exe'
default='C:/Program Files/WordCraft/wordcraft-cli.exe'
repo='https://github.com/storytold/wordcraft'
repo_slug='storytold/wordcraft'
;;
gridcraft-mcp)
exe_name=gridcraft-cli.exe
default='/mnt/c/Program Files/GridCraft/gridcraft-cli.exe'
[[ -f "$default" ]] || default='C:/Program Files/GridCraft/gridcraft-cli.exe'
default='C:/Program Files/GridCraft/gridcraft-cli.exe'
repo='https://github.com/storytold/gridcraft'
repo_slug='storytold/gridcraft'
;;
@@ -48,13 +45,17 @@ if [[ ! -f "$src" ]]; then
fi
mkdir -p "$ext/server"
dest="$ext/server/$exe_name"
cp -f "$src" "$dest"
chmod +x "$dest" 2>/dev/null || true
rm -f "$ext/server"/*.exe
if [[ ! -f "$ext/server/README.txt" ]]; then
printf '%s\n' \
'Diese Erweiterung enthaelt keine CLI.' \
'Installiere die App ueber den ArtCraft-Launcher.' \
"Erwarteter Pfad: $src" > "$ext/server/README.txt"
fi
ver_out="$("$dest" --version 2>&1 || true)"
ver_out="$("$src" --version 2>&1 || true)"
if [[ ! "$ver_out" =~ [0-9]+\.[0-9]+\.[0-9]+ ]] && [[ "$name" == gridcraft-mcp ]]; then
ver_out="$("$dest" version 2>&1 || true)"
ver_out="$("$src" version 2>&1 || true)"
fi
if [[ ! "$ver_out" =~ ([0-9]+\.[0-9]+\.[0-9]+) ]]; then
echo "Version der CLI nicht lesbar: $ver_out" >&2
@@ -63,11 +64,11 @@ fi
ver="${BASH_REMATCH[1]}"
if command -v sha256sum >/dev/null 2>&1; then
hash="$(sha256sum "$dest" | awk '{print $1}')"
hash="$(sha256sum "$src" | awk '{print $1}')"
elif command -v shasum >/dev/null 2>&1; then
hash="$(shasum -a 256 "$dest" | awk '{print $1}')"
hash="$(shasum -a 256 "$src" | awk '{print $1}')"
else
hash="$(python3 -c "import hashlib,sys; print(hashlib.sha256(open(sys.argv[1],'rb').read()).hexdigest())" "$dest")"
hash="$(python3 -c "import hashlib,sys; print(hashlib.sha256(open(sys.argv[1],'rb').read()).hexdigest())" "$src")"
fi
python3 -c "
@@ -80,6 +81,7 @@ print(json.dumps({
'sha256': sys.argv[4],
'repository': sys.argv[5],
'tag': 'v' + sys.argv[3],
'bundled': False,
}, separators=(',', ':')))
" "$src" "$exe_name" "$ver" "$hash" "$repo" > "$ext/upstream.json"
printf '\n' >> "$ext/upstream.json" || true
@@ -94,5 +96,4 @@ for f in LICENSE-MIT LICENSE-APACHE NOTICE; do
fi
done
echo "OK $name $ver $hash"
echo " $dest"
echo "OK $name $ver (nicht gebundelt) $src"
+20 -4
View File
@@ -5,9 +5,25 @@
param([Parameter(Mandatory = $true)][string]$Name)
. (Join-Path $PSScriptRoot 'lib.ps1')
$Token = $env:GITEA_TOKEN
if (-not $Token) {
Write-Host 'GITEA_TOKEN fehlt. Persoenliches Zugangs-Token mit Schreibrecht (write:repository), nur in der Umgebung.'
# Prefer GITEA_TOKEN; otherwise reuse git credential helper (same auth as git push).
$AuthHeader = $null
if ($env:GITEA_TOKEN) {
$AuthHeader = "token $($env:GITEA_TOKEN)"
}
else {
$credRaw = "protocol=https`nhost=git.gundel.dev`n`n" | git credential fill 2>$null
$user = $null; $pass = $null
foreach ($line in $credRaw) {
if ($line -match '^username=(.*)$') { $user = $Matches[1] }
if ($line -match '^password=(.*)$') { $pass = $Matches[1] }
}
if ($user -and $pass) {
$pair = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${user}:${pass}"))
$AuthHeader = "Basic $pair"
}
}
if (-not $AuthHeader) {
Write-Host 'Keine Auth: GITEA_TOKEN setzen oder git credential fuer git.gundel.dev hinterlegen.'
exit 1
}
@@ -58,7 +74,7 @@ $api = 'https://git.gundel.dev/api/v1/repos/dg/claude-skills'
function Invoke-Gitea([string]$Method, [string]$Url, [byte[]]$Body, [string]$ContentType) {
$req = [Net.HttpWebRequest]::Create($Url)
$req.Method = $Method
$req.Headers.Add('Authorization', "token $Token")
$req.Headers.Add('Authorization', $AuthHeader)
$req.Accept = 'application/json'
if ($null -ne $Body) {
$req.ContentType = $ContentType