Skip to content

feat(cli): install without Node.js and upgrade from signed releases - #141

Merged
harlan-zw merged 2 commits into
mainfrom
feat/cli-upgrade
Sep 16, 2026
Merged

harlan-zw merged 2 commits into
mainfrom
feat/cli-upgrade

Conversation

@harlan-zw

Copy link
Copy Markdown
Collaborator

❓ Type of change

  • ✨ New feature

📚 Description

Using skilld without Node.js wasn't possible, and no install ever heard about a newer release. install.sh and install.ps1 now install one native binary from the GitHub release. That install upgrades itself in the background, and the command prints "Restart skilld to use it". An npm install prints the upgrade command for its runner: npx skilld@latest, pnpm add --global skilld, and so on.

A digest file downloaded from the same release protects nothing: whoever can change the release can change both files. So release CI signs a release manifest with an Ed25519 key that exists only as a secret in the one signing step. The CLI checks the signature, the exact version, and the binary digest before it writes a file beside the executable. It never downgrades, and a build without a compiled release key never upgrades itself.

Architecture: release CI signs the release manifest, and install.sh and the standalone CLI verify it before they install a binary

Upgrades only run for a person at a terminal: not in CI, not under an Agent, and not with SKILLD_NO_UPGRADE=1.

Open questions:

  • install.sh checks the signature only where OpenSSL supports Ed25519, and macOS LibreSSL doesn't. There it falls back to HTTPS plus the digest, as rustup and bun do. install.ps1 always does. Worth serving install.sh from skilld.dev too, so the script and the binaries come from two different origins?
  • I added CLI upgrade and release manifest to GLOSSARY.md. "Upgrade" keeps it apart from skilld update, which updates Skills.
  • The Windows swap code compiled with a zig cross build, but PR CI skips the Windows runners, so it hasn't run yet.

📝 Migration

Before the next release tag, create the release key. Run this once, then store the printed seed somewhere offline:

node scripts/release/release-signing.mjs generate-key --print-seed

It sets the SKILLD_RELEASE_SIGNING_KEY secret and the SKILLD_RELEASE_PUBLIC_KEY variable. The release workflow fails without them. If the seed is lost, installs on older versions cannot verify newer releases, and those users must run the install script again.

🤖 AI disclosure: Harlan Agent Kit modified this description. My AI open-source policy.

Users without Node.js had no way to install the CLI, and no install ever
learned about a newer release. A standalone install now upgrades itself
only after a signed release manifest verifies, and an npm install prints
the command for its package runner.
@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. labels Sep 16, 2026
@harlan-github-agent

harlan-github-agent Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

🤖 MERGED

Harlan Agent Kit posted this automated review. It is not Harlan's personal review or approval. AI open source policy. Last updated: 2026-09-16 12:24 UTC.

GitHub merged this pull request.

No material findings were recorded.

3688a912-9b12-4a9a-988e-00d41290d0ba

@harlan-github-agent harlan-github-agent Bot added harlan-agent-blocked The automated Review found a material defect in this head commit. harlan-agent-running An Agent holds a Task on this issue or pull request right now. and removed harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. harlan-agent-blocked The automated Review found a material defect in this head commit. labels Sep 16, 2026
@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-ready The automated Review passed every gate on this head commit. and removed harlan-agent-running An Agent holds a Task on this issue or pull request right now. labels Sep 16, 2026
@harlan-zw
harlan-zw merged commit 48f6ff1 into main Sep 16, 2026
2 checks passed
@harlan-github-agent harlan-github-agent Bot removed the harlan-agent-ready The automated Review passed every gate on this head commit. label Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant