From e7fef708a6e651ec894924e2b40355264b0ffd12 Mon Sep 17 00:00:00 2001 From: chenchen Date: Mon, 9 Nov 2026 23:30:04 +0800 Subject: [PATCH 1/2] Claude plugin: pin the offload skill to the Rust CLI 1.0.0 The box-offload skill ran npx -y @simular-ai/box@0.2.0, the JavaScript CLI. 1.0.0, the Rust CLI from simular-ai/box-cli, is now latest on npm, and the Claude directory review reads the exact pin, so pin 1.0.0 before submitting. - SKILL.md: pin @simular-ai/box@1.0.0; warnings exit 5 (the JS CLI used 4). - plugin.json: 0.2.1 -> 0.2.2. - publish-cli.yml: the pin check no longer compares with cli/package.json; it requires one exact version across claude/ that exists on npm. - README: the pin follows box-cli releases; cli/ no longer publishes. Closes #45. --- .github/workflows/publish-cli.yml | 16 ++++++++++------ README.md | 3 ++- claude/.claude-plugin/plugin.json | 2 +- claude/skills/box-offload/SKILL.md | 4 ++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish-cli.yml b/.github/workflows/publish-cli.yml index 4923515..8975e0f 100644 --- a/.github/workflows/publish-cli.yml +++ b/.github/workflows/publish-cli.yml @@ -124,14 +124,18 @@ jobs: export HOME="$(mktemp -d)" claude plugin validate . claude plugin validate ./claude - - name: Plugin pins the CLI to the exact version in cli/package.json - # A range (^0.2.0) lets npx run a version published after review; the Claude directory - # review asks for an exact pin, and it must be the CLI version this ref ships. + - name: Plugin pins the CLI to one exact version that is on npm + # A range (^1.0.0) lets npx run a version published after review; the Claude directory + # review asks for an exact pin. Since 1.0.0 the CLI is the Rust simular-box, released from + # simular-ai/box-cli, so the pin follows its npm releases, not cli/package.json. run: | set -euo pipefail - want="@simular-ai/box@$(node -p "require('./cli/package.json').version")" - bad=$(grep -rnoE '@simular-ai/box@[^ `"]*' claude | grep -vF ":$want" || true) - if [ -n "$bad" ]; then echo "pin npx to $want in claude/:"; echo "$bad"; exit 1; fi + pins=$(grep -rhoE '@simular-ai/box@[^ `"]*' claude | sort -u) + if [ "$(printf '%s\n' "$pins" | grep -c .)" -ne 1 ]; then echo "claude/ must pin one CLI version, found:"; echo "$pins"; exit 1; fi + v=${pins#@simular-ai/box@} + if ! printf '%s' "$v" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then echo "pin an exact release, not $pins"; exit 1; fi + if [ "$(npm view "@simular-ai/box@$v" version)" != "$v" ]; then echo "$pins is not on npm"; exit 1; fi + echo "claude/ pins $pins" - name: DeepSeek Harness package run: npm pack ./dsh --dry-run - name: Hermes plugin diff --git a/README.md b/README.md index 3f6a683..ceba78c 100644 --- a/README.md +++ b/README.md @@ -28,4 +28,5 @@ Add a folder named after the agent with its own manifest, MCP config and, where - `dsh/`: bump `version` in `dsh/package.json`, then push a tag `dsh-vX.Y.Z`. The release workflow attaches `dsh-box.tgz`. - `openai/`: bump `version` in `openai/plugin.json` and `publication.release_notes`, run `openai/build-zip.sh`, upload the ZIP at platform.openai.com/plugins. - `hermes/`: bump `version` in `hermes/plugin.json`. Users copy the folder by hand until box is in the Hermes plugin catalog. -- `cli/`: bump `version` in `cli/package.json`, and, in the same PR, the exact pin `npx -y @simular-ai/box@X.Y.Z` in `claude/skills/box-offload/SKILL.md` plus `version` in `claude/.claude-plugin/plugin.json` (CI fails while the pin and `cli/package.json` disagree; never a range, because the Claude directory review requires that what runs is what it read). Then push a tag `cli-vX.Y.Z` right after the merge. The `publish-cli.yml` workflow tests it and publishes `@simular-ai/box` to npm through trusted publishing (OIDC), with provenance; the one-time npm setup is in [cli/README.md](cli/README.md#releasing). When the box endpoint moves, change `DEFAULT_MCP_URL` in `cli/src/constants.js`, add the old host to `OLD_HOSTS` there, change the URL in every plugin folder, and release each one. +- The Claude plugin's CLI pin: since 1.0.0, `@simular-ai/box` on npm is the Rust CLI released from [simular-ai/box-cli](https://github.com/simular-ai/box-cli). To move the plugin to a new CLI release, change the exact pin `npx -y @simular-ai/box@X.Y.Z` in `claude/skills/box-offload/SKILL.md` and bump `version` in `claude/.claude-plugin/plugin.json` in one PR (CI fails unless every pin under `claude/` names the same exact version and that version is on npm; never a range, because the Claude directory review requires that what runs is what it read). +- `cli/`: the JavaScript CLI (0.2.x). It no longer publishes to npm: its trusted publisher on `@simular-ai/box` was removed when the Rust 1.0.0 shipped, so do not push `cli-v*` tags. The endpoint and CLI changes now go to simular-ai/box-cli. diff --git a/claude/.claude-plugin/plugin.json b/claude/.claude-plugin/plugin.json index 2592a04..984bf7f 100644 --- a/claude/.claude-plugin/plugin.json +++ b/claude/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "box", "displayName": "box by Simular", - "version": "0.2.1", + "version": "0.2.2", "description": "Give Claude a computer of its own: a cloud Linux desktop with Chrome and a shell that it drives over MCP, while your own computer stays free. You sign in once in the browser; no key to paste.", "author": { "name": "Simular", diff --git a/claude/skills/box-offload/SKILL.md b/claude/skills/box-offload/SKILL.md index 476bf20..87f571d 100644 --- a/claude/skills/box-offload/SKILL.md +++ b/claude/skills/box-offload/SKILL.md @@ -5,7 +5,7 @@ description: Hand this coding task to an agent in the user's box (their cloud co The agent in the box starts fresh. It knows only what your hand-over says, plus the repo. Write the hand-over as if for a capable engineer who has never seen this conversation. -`box` below is `npx -y @simular-ai/box@0.2.0`. Run it in the repo the user works in. It does every +`box` below is `npx -y @simular-ai/box@1.0.0`. Run it in the repo the user works in. It does every mechanical step: never copy files or secrets yourself, never print a secret, never edit the files it writes. @@ -24,7 +24,7 @@ files it writes. missing or signed out, tell the user to run, in their own terminal, `box offload install-cli --kind ` and then `box offload sign-in --kind ` (the sign-in asks them to approve in the browser and paste a code, so you cannot do it). - - Exit 4 is warnings: tell the user each one, and run again with `--yes` only when they + - Exit 5 is warnings: tell the user each one, and run again with `--yes` only when they agree, or said beforehand to go ahead. - For a secret it warns about, ask the user; only they opt one in (`box offload secrets add file:.env`). Never opt in on your own. From 5a7113c87e2776d80298c5e47aeaa41e71b05e39 Mon Sep 17 00:00:00 2001 From: chenchen Date: Mon, 9 Nov 2026 23:32:23 +0800 Subject: [PATCH 2/2] Offload skill: name printed commands as box, handle exit 4; workflow header - 1.0.0 prints follow-up commands as simular-box, which is not on PATH under npx; the skill tells the agent to hand them to the user as box. - Exit 4 in 1.0.0 is a refused sign-in: ask the user to run box login. - publish-cli.yml header no longer tells you to push cli-v* tags. --- .github/workflows/publish-cli.yml | 5 +++-- claude/skills/box-offload/SKILL.md | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-cli.yml b/.github/workflows/publish-cli.yml index 8975e0f..c1cc269 100644 --- a/.github/workflows/publish-cli.yml +++ b/.github/workflows/publish-cli.yml @@ -11,8 +11,9 @@ name: Publish CLI # headless clients reach box and list its tools. Never on PRs from forks. # Publishing happens only when a tag `cli-vX.Y.Z` (or `cli-vX.Y.Z-rc.N`, dist-tag "next") is pushed. # -# Cutting a release: bump "version" in cli/package.json, merge to main, then -# git tag cli-v && git push origin cli-v +# Since @simular-ai/box 1.0.0 (the Rust CLI from simular-ai/box-cli) this repo no longer +# publishes the CLI: its npm trusted publisher was removed, so do not push cli-v* tags. The +# publish job below is kept only until cli/ is retired. # # Auth: npm trusted publishing (OIDC). The publish job's `id-token: write` lets the npm CLI swap # a GitHub OIDC token for a short-lived publish token, so no long-lived npm token is stored. diff --git a/claude/skills/box-offload/SKILL.md b/claude/skills/box-offload/SKILL.md index 87f571d..49e1215 100644 --- a/claude/skills/box-offload/SKILL.md +++ b/claude/skills/box-offload/SKILL.md @@ -8,6 +8,8 @@ Write the hand-over as if for a capable engineer who has never seen this convers `box` below is `npx -y @simular-ai/box@1.0.0`. Run it in the repo the user works in. It does every mechanical step: never copy files or secrets yourself, never print a secret, never edit the files it writes. +The CLI prints follow-up commands as `simular-box ...`; that name is not on PATH under npx, so +when you pass one to the user, write it with `box` (the npx command above) instead. ## OFFLOAD @@ -20,6 +22,8 @@ files it writes. `codex`, `cursor`). Add `--box NAME` when the user names a box. - "not signed in": ask the user to run `box login` in their terminal (it opens the browser), then run offload again. + - Exit 4 is a refused sign-in (expired or revoked): ask the user to run `box login`, then + run offload again. - Exit 3 is a block: stop and tell the user why, one line per finding. If the box CLI is missing or signed out, tell the user to run, in their own terminal, `box offload install-cli --kind ` and then `box offload sign-in --kind `