Skip to content

refactor(cos): delegate sandbox verbs to createos CLI - #70

Draft
pratikbin wants to merge 5 commits into
mainfrom
feat/cos-to-createos-cli
Draft

pratikbin wants to merge 5 commits into
mainfrom
feat/cos-to-createos-cli

Conversation

@pratikbin

@pratikbin pratikbin commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Blocked on NodeOps-app/createos-cli#95 (supersedes CLI #84 and #94). It is not merged or in a release yet; the latest is v0.0.29. Merging this PR first breaks offload, fanout, matrix, fork, desktop and computer for every user.

Supersedes #30 and #60. Both move cos verbs onto the createos CLI (ADR-0001), so they ship together here.

From #30: offload, fanout, matrix, fork

  • cos offload → createos sandbox offload
  • cos fanout → createos sandbox matrix (forks one staged box)
  • new cos matrix / /createos-sandbox:matrix: -P setup runs once before forking
  • cos fork → createos sandbox fork -o json (also supports -c N)

From #60: desktop, computer

  • cos desktop / cos computer → createos sandbox desktop|computer
  • removed the REST layer (api(), api_auth(), api_check(), desktop_wait())

Conflict resolution (main moved on after #30)

  • cos agent and cos exec are kept. agent no longer takes -w, because feat(sandbox): thin cos onto createos-cli's offload/matrix/fork --count #30 removed the swap flag.
  • -v KEY[=VAL] still works on offload, fanout and matrix; cos passes it through as --env.
  • cos expands -p presets into --egress itself, because CLI #84 has no openrouter, openai, anthropic or cursor preset, and cos agent needs them.
  • cos exec still has its on_offload_exit teardown trap.
  • codex-plugin cos and its skill are re-synced as byte mirrors of claude-code-plugin.
  • Plugin version 0.9.0, 23 commands.

Verification

  • bash -n and shellcheck -S warning pass.
  • With a fake createos binary, checked the argv each verb builds: offload, fanout, matrix, matrix -F, and agent with provider env and presets. Also checked that a bad preset fails.
  • Not yet run against a real CLI, because the #84 and #94 commands are not released.

scripts/cos's offload and fanout bodies (stage, push, exec, keepalive,
pull, destroy — one copy per verb) are replaced with thin delegates to
`createos sandbox offload` and `createos sandbox matrix`, which already
do this composition in Go with retry, no billable leaks on failure, and
a teardown failure that fails the command instead of hiding it.

- `cos offload` -> `createos sandbox offload <dir> -- <cmd>`
- `cos fanout` -> `createos sandbox matrix <dir> --job ... --job ...`
  (no --prepare) — a fork of one staged box per job, not an
  independently-staged box per job. Same isolation, faster.
- new `cos matrix` / `/createos-sandbox:matrix` — fanout plus -P
  '<setup>' to run once on the golden box before forking, for the case
  every job shares the same dependency install or toolchain prep.
- `cos fork` keeps its own pause-then-resume orchestration around the
  project box (legitimate: it is forking a box it owns, on request),
  but the fork step itself and id resolution now delegate to
  `createos sandbox fork -o json`, which returns the new id directly.
  This deletes the comm-diff-against-`sandbox ls` hack and the
  documented multibyte/set -u trap that came with it. Gained -c N for
  direct N-way cloning of the project box.
- -w/--swap dropped from offload (per discussion): devbox:1 can't
  swapon a file added post-boot anyway, so the flag bought little.
  Documented as something to compose into the command string instead.

Docs updated throughout (skill, references, command frontmatter, README)
for the new/changed verbs and to correct a stale "2 concurrent boxes"
quota claim to the observed number (10).

Verified live via tmux against createos-cli's feat/sandbox-compositions
branch (COS_CLI override), running five scenarios pulled from the
product's own use-case catalog: untrusted-code offload with locked
egress, independent-job fanout, shared-setup matrix (-P ran exactly
once across all forks), project-box fork -c N, and a background job
ending its own box via the loopback self-signal endpoint.

That live run caught a real bug in createos-cli: `fork <sandbox>
--count 2` silently created one clone instead of two, with no error —
Go's stdlib flag parser stops at the first non-flag argument, so
--count written after the sandbox id (the order every caller actually
writes, cos included) was never parsed at all. Fixed on the
createos-cli side (feat/sandbox-compositions, reusing the raw-argv
fallback already built for `process run --cwd`) and confirmed fixed
here before writing this up.
The CLI grew `sandbox desktop` and `sandbox computer`, so the REST layer
this driver carried for them has no reason to exist. Delete api(),
api_auth(), api_check() and desktop_wait(), and shell out like every
other verb.

That layer was the one place cos bypassed the CLI, and the cost of it
was a second implementation of things the CLI already knew: its own auth
precedence, its own error-code map, its own readiness poll. It also held
a false premise — a comment claiming the CLI does not read
CREATEOS_API_KEY, which it has (cmd/root/root.go). The same code now
serves pi, opencode and herdr, which could not do computer-use at all.

cos keeps what the CLI cannot know: which box belongs to this project,
and creating one on a desktop image when there is none. The rootfs guard
stays too, because the CLI tells you to create a new sandbox, and for a
project box the fix is to replace the one you have.

Two details preserved for callers:

- `cos computer screenshot -o file` still works. The CLI spells it
  --out, since -o is its global output-format flag, so cos translates.
- `cos resume` now says to re-run `cos desktop` on a box that had one. A
  resumed desktop answers reads before its input stack is back, so a
  click can 409 for a moment after the screen route already succeeds.

Requires a createos CLI carrying those commands. cos probes for them and
tells the user to upgrade rather than failing with "unknown command".

Blocked on NodeOps-app/createos-cli#94.
Combines #30 (offload/fanout/matrix/fork onto createos-cli) with #60
(desktop/computer onto createos-cli). Conflict resolution keeps main's
newer surface that #30 predated:

- cos agent / cos exec kept; agent drops -w (swap flag removed by #30)
- -v KEY[=VAL] env passthrough wired into offload/fanout/matrix as --env
- -p presets expanded to --egress locally: CLI #84 lacks the
  openrouter/openai/anthropic/cursor presets agent relies on
- on_offload_exit trap restored for cos exec
- codex-plugin cos + skill re-synced (byte mirror of claude-code-plugin)
- plugin 0.9.0, 23 commands
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