diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 116c4b0..5a5d8db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,15 +39,14 @@ jobs: run: | test_dir="$(mktemp -d)" trap 'rm -rf "$test_dir"' EXIT - mkdir -p "$test_dir/skill/scripts" "$test_dir/fake-path" + mkdir -p "$test_dir/skill/scripts" "$test_dir/skill/bin" "$test_dir/fake-path" cp skills/lexmount-webfetch/scripts/doctor.sh "$test_dir/skill/scripts/doctor.sh" + printf '#!/bin/sh\nprintf "%%s\\n" "$*"\n' > "$test_dir/skill/bin/webfetch-cli" + chmod +x "$test_dir/skill/bin/webfetch-cli" ln -s /usr/bin/true "$test_dir/fake-path/webfetch-cli" - set +e output="$(PATH="$test_dir/fake-path:/usr/bin:/bin" "$test_dir/skill/scripts/doctor.sh")" - status=$? - set -e - test "$status" -eq 2 - test "$output" = '{"ok":false,"error":"unsupported_platform","message":"This Skill supports macOS arm64 through scripts/doctor.sh and Windows x64 through scripts/doctor.ps1."}' + test "$output" = 'doctor --json' + grep -Fq 'Linux-x86_64) target="x86_64-unknown-linux-musl"' skills/lexmount-webfetch/scripts/bootstrap.sh ! grep -q 'command -v webfetch-cli' skills/lexmount-webfetch/scripts/doctor.sh ! grep -q 'Get-Command webfetch-cli' skills/lexmount-webfetch/scripts/doctor.ps1 - name: Verify runtime packaging contract @@ -93,6 +92,21 @@ jobs: & .\skills\lexmount-webfetch\scripts\bootstrap.ps1 & (Join-Path $env:LEXMOUNT_WEBFETCH_CLI_INSTALL_DIR "webfetch-cli.exe") version + linux-bootstrap: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Bootstrap static Linux x64 binary from COS + run: | + latest_tag="$(git tag --list 'v*' --sort=-version:refname | head -n 1)" + test -n "$latest_tag" + export LEXMOUNT_WEBFETCH_CLI_VERSION="${latest_tag#v}" + export LEXMOUNT_WEBFETCH_CLI_INSTALL_DIR="$RUNNER_TEMP/webfetch-cli-bootstrap" + ./skills/lexmount-webfetch/scripts/bootstrap.sh + "$LEXMOUNT_WEBFETCH_CLI_INSTALL_DIR/webfetch-cli" version + linux-release: runs-on: ubuntu-22.04 steps: diff --git a/Cargo.lock b/Cargo.lock index 5934c6d..99b3f42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1202,7 +1202,7 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "lexmount-webfetch" -version = "0.1.4" +version = "0.1.5" dependencies = [ "base64 0.22.1", "clap", diff --git a/Cargo.toml b/Cargo.toml index 99e7901..445e9e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lexmount-webfetch" -version = "0.1.4" +version = "0.1.5" edition = "2024" license = "MIT" description = "Native Rust SDK and CLI for Lexmount WebFetch" diff --git a/README.md b/README.md index 5c71275..5d90737 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Claude Code uses `${CLAUDE_SKILL_DIR}`, and WorkBuddy/CodeBuddy uses the Skill directory from their own path. The ZIP contains exactly eight files: `SKILL.md`, three references, and the -bootstrap/doctor scripts for both platforms. Native executables are published +bootstrap/doctor scripts for all supported platforms. Native executables are published separately. On first use, the matching script downloads the pinned release from Tencent Cloud COS and verifies its SHA-256 digest. Tagged releases publish the Skill ZIP, `SHA256SUMS`, and exactly three standalone binaries: signed and diff --git a/skills/lexmount-webfetch/SKILL.md b/skills/lexmount-webfetch/SKILL.md index bb184d7..d8e1b9b 100644 --- a/skills/lexmount-webfetch/SKILL.md +++ b/skills/lexmount-webfetch/SKILL.md @@ -17,6 +17,7 @@ Do not infer `` from the working directory. Select the native Rust binary for the current platform: - macOS arm64: run `sh "/scripts/bootstrap.sh"` when `/bin/webfetch-cli` is missing, then invoke `"/bin/webfetch-cli"`. +- Linux x64: run `sh "/scripts/bootstrap.sh"` when `/bin/webfetch-cli` is missing, then invoke `"/bin/webfetch-cli"`. - Windows x64: run `& "\scripts\bootstrap.ps1"` in PowerShell when `\bin\webfetch-cli.exe` is missing, then invoke `& "\bin\webfetch-cli.exe"`. Both bootstrap scripts download the fixed release version from Tencent Cloud COS @@ -29,7 +30,7 @@ Do not run the binary for the other platform or assume `webfetch-cli` is on `PAT ## Setup 1. Resolve `` from this `SKILL.md` and select the matching platform paths above. -2. Run the Skill-local bootstrap script if the binary is missing. Then run `sh "/scripts/doctor.sh"` on macOS arm64 or `& "\scripts\doctor.ps1"` in Windows PowerShell. +2. Run the Skill-local bootstrap script if the binary is missing. Then run `sh "/scripts/doctor.sh"` on macOS arm64 or Linux x64, or `& "\scripts\doctor.ps1"` in Windows PowerShell. 3. If credentials are missing, run the Skill-local CLI's `auth login --open`. Pass `--client-name ""` when the current Agent has a user-facing name; otherwise omit it and the CLI uses `Agent`. Let the user approve in diff --git a/skills/lexmount-webfetch/references/commands.md b/skills/lexmount-webfetch/references/commands.md index 3405c24..5889a7c 100644 --- a/skills/lexmount-webfetch/references/commands.md +++ b/skills/lexmount-webfetch/references/commands.md @@ -1,7 +1,7 @@ # Command reference -Resolve `` from the loaded `SKILL.md`. On macOS, `` -below means `"/bin/webfetch-cli"`; on Windows PowerShell it means +Resolve `` from the loaded `SKILL.md`. On macOS and Linux, +`` below means `"/bin/webfetch-cli"`; on Windows PowerShell it means `& "\bin\webfetch-cli.exe"`. These are Skill-local absolute invocations, not `PATH` lookups. diff --git a/skills/lexmount-webfetch/references/troubleshooting.md b/skills/lexmount-webfetch/references/troubleshooting.md index 61fdb25..067127c 100644 --- a/skills/lexmount-webfetch/references/troubleshooting.md +++ b/skills/lexmount-webfetch/references/troubleshooting.md @@ -6,9 +6,9 @@ WorkBuddy/CodeBuddy provides `${CODEBUDDY_SKILL_DIR}`. Do not infer it from the working directory or search the user's home directory. 2. Missing command: run `sh "/scripts/bootstrap.sh"` on macOS arm64 - or `& "\scripts\bootstrap.ps1"` on Windows x64, then run the - matching doctor script. Invoke only the Skill-local binary afterward; do not - rely on `PATH`. + or Linux x64, or `& "\scripts\bootstrap.ps1"` on Windows x64, + then run the matching doctor script. Invoke only the Skill-local binary + afterward; do not rely on `PATH`. 3. Missing or expired credentials: run the Skill-local CLI's `auth login --open`. Pass `--client-name ""` when the current Agent has a user-facing name; otherwise omit it to use `Agent`. diff --git a/skills/lexmount-webfetch/scripts/bootstrap.ps1 b/skills/lexmount-webfetch/scripts/bootstrap.ps1 index 6bce2bb..29d685e 100644 --- a/skills/lexmount-webfetch/scripts/bootstrap.ps1 +++ b/skills/lexmount-webfetch/scripts/bootstrap.ps1 @@ -12,7 +12,7 @@ function Invoke-Tls12Download { } } -$version = if ($env:LEXMOUNT_WEBFETCH_CLI_VERSION) { $env:LEXMOUNT_WEBFETCH_CLI_VERSION } else { "0.1.4" } +$version = if ($env:LEXMOUNT_WEBFETCH_CLI_VERSION) { $env:LEXMOUNT_WEBFETCH_CLI_VERSION } else { "0.1.5" } $downloadBaseUrl = if ($env:LEXMOUNT_WEBFETCH_CLI_DOWNLOAD_BASE_URL) { $env:LEXMOUNT_WEBFETCH_CLI_DOWNLOAD_BASE_URL.TrimEnd('/') } else { "https://cli-bin-1377899528.cos.ap-nanjing.myqcloud.com/releases/webfetch-cli" } $architecture = if ($env:PROCESSOR_ARCHITEW6432) { $env:PROCESSOR_ARCHITEW6432 } else { $env:PROCESSOR_ARCHITECTURE } if ($architecture -ne "AMD64") { throw "Only Windows x64 is supported" } diff --git a/skills/lexmount-webfetch/scripts/bootstrap.sh b/skills/lexmount-webfetch/scripts/bootstrap.sh index ab253e6..ba2b111 100755 --- a/skills/lexmount-webfetch/scripts/bootstrap.sh +++ b/skills/lexmount-webfetch/scripts/bootstrap.sh @@ -1,12 +1,13 @@ #!/bin/sh set -eu -version="${LEXMOUNT_WEBFETCH_CLI_VERSION:-0.1.4}" +version="${LEXMOUNT_WEBFETCH_CLI_VERSION:-0.1.5}" download_base_url="${LEXMOUNT_WEBFETCH_CLI_DOWNLOAD_BASE_URL:-https://cli-bin-1377899528.cos.ap-nanjing.myqcloud.com/releases/webfetch-cli}" repo="${download_base_url%/}/v${version}" case "$(uname -s)-$(uname -m)" in Darwin-arm64) target="aarch64-apple-darwin" ;; - *) echo "Unsupported platform: $(uname -s) $(uname -m). This release supports macOS ARM64 and Windows x64." >&2; exit 2 ;; + Linux-x86_64) target="x86_64-unknown-linux-musl" ;; + *) echo "Unsupported platform: $(uname -s) $(uname -m). This release supports macOS ARM64, Linux x64, and Windows x64." >&2; exit 2 ;; esac asset="webfetch-cli-v${version}-${target}" tmp_dir="$(mktemp -d)" @@ -15,7 +16,10 @@ curl --proto '=https' --tlsv1.2 -fsSL "$repo/$asset" -o "$tmp_dir/$asset" curl --proto '=https' --tlsv1.2 -fsSL "$repo/SHA256SUMS" -o "$tmp_dir/SHA256SUMS" expected="$(awk -v name="$asset" '$2 == name {print $1}' "$tmp_dir/SHA256SUMS")" [ -n "$expected" ] || { echo "No checksum published for $asset" >&2; exit 3; } -actual="$(openssl dgst -sha256 "$tmp_dir/$asset" | awk '{print $NF}')" +case "$(uname -s)" in + Darwin) actual="$(openssl dgst -sha256 "$tmp_dir/$asset" | awk '{print $NF}')" ;; + Linux) actual="$(sha256sum "$tmp_dir/$asset" | awk '{print $1}')" ;; +esac [ "$expected" = "$actual" ] || { echo "SHA-256 mismatch for $asset" >&2; exit 4; } skill_dir="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" install_dir="${LEXMOUNT_WEBFETCH_CLI_INSTALL_DIR:-$skill_dir/bin}" diff --git a/skills/lexmount-webfetch/scripts/doctor.ps1 b/skills/lexmount-webfetch/scripts/doctor.ps1 index ebfad67..35c958b 100644 --- a/skills/lexmount-webfetch/scripts/doctor.ps1 +++ b/skills/lexmount-webfetch/scripts/doctor.ps1 @@ -1,7 +1,7 @@ $ErrorActionPreference = "Stop" $architecture = if ($env:PROCESSOR_ARCHITEW6432) { $env:PROCESSOR_ARCHITEW6432 } else { $env:PROCESSOR_ARCHITECTURE } if ($architecture -ne "AMD64") { - Write-Output '{"ok":false,"error":"unsupported_platform","message":"This Skill supports Windows x64 through scripts/doctor.ps1 and macOS arm64 through scripts/doctor.sh."}' + Write-Output '{"ok":false,"error":"unsupported_platform","message":"This Skill supports Windows x64 through scripts/doctor.ps1, and macOS arm64 and Linux x64 through scripts/doctor.sh."}' exit 2 } $skillBinary = Join-Path (Split-Path -Parent $PSScriptRoot) "bin\webfetch-cli.exe" diff --git a/skills/lexmount-webfetch/scripts/doctor.sh b/skills/lexmount-webfetch/scripts/doctor.sh index cad579a..7d12ca9 100755 --- a/skills/lexmount-webfetch/scripts/doctor.sh +++ b/skills/lexmount-webfetch/scripts/doctor.sh @@ -1,8 +1,8 @@ #!/bin/sh set -eu case "$(uname -s)-$(uname -m)" in - Darwin-arm64) ;; - *) echo '{"ok":false,"error":"unsupported_platform","message":"This Skill supports macOS arm64 through scripts/doctor.sh and Windows x64 through scripts/doctor.ps1."}'; exit 2 ;; + Darwin-arm64|Linux-x86_64) ;; + *) echo '{"ok":false,"error":"unsupported_platform","message":"This Skill supports macOS arm64 and Linux x64 through scripts/doctor.sh, and Windows x64 through scripts/doctor.ps1."}'; exit 2 ;; esac skill_dir="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" if [ -x "$skill_dir/bin/webfetch-cli" ]; then exec "$skill_dir/bin/webfetch-cli" doctor --json; fi