feat: sync harness plugins to the Claude Code plugin's surface - #49
Merged
Conversation
The repository is now NodeOps-app/createos-plugin; these install paths still named createos-claude-plugins, which resolved only through GitHub's rename redirect.
The TypeScript plugins drove `createos sandbox create/exec/rm` directly, which looks like an offload and is not: it drops egress restriction, the keepalive that survives a dropped stream on a long build, guaranteed auto-destroy, and the staging excludes that keep a large .git off the wire. sandbox-engine.ts ports those semantics from scripts/cos so both plugins can share one implementation. Egress selection and box retention are pure functions because they are the two decisions that fail silently: an unrestricted box works perfectly, and a box destroyed after a failed artifact pull takes the only copy of the output with it.
Adds sandbox_offload, sandbox_fanout, sandbox_desktop, sandbox_computer and sandbox_screenshot over the shared engine, taking the plugin from 33 to 38 tools. The compaction context now carries the verb rule as well, so "work with a finish line goes to sandbox_offload" survives a compact instead of the agent falling back to create plus exec.
Adds sandbox_offload plus a compact desktop surface — sandbox_desktop, sandbox_computer and sandbox_screenshot — matching the OpenCode plugin, taking the extension from 34 to 38 sandbox tools (45 registered).
The Codex plugin shipped a skill that taught raw `createos` CLI verbs and
a session hook that printed plain text. Three things were wrong with it:
- The plugin could not be installed at all. Codex rejects scoped names
("only ASCII letters, digits, . _ and -"), so @createos/codex was
refused; it is now createos-sandbox-codex.
- The hook injected nothing. Codex parses hookSpecificOutput the same way
Claude Code does, so plain stdout was discarded and the agent never
learned the driver path.
- Its skill had drifted 77 lines behind the canonical one.
It now ships the same cos driver and skill as the Claude Code plugin, with
session-start and pre-tool-use hooks. scripts/sync-shared.sh copies the
shared files and CI fails on drift; symlinks are not an option because the
Codex installer copies regular files only, so a symlinked repo installs
with no driver and no skill at all.
pullArtifacts interpolates `out` into a remote shell command unquoted, so that globs like dist/* keep working — the same trade scripts/cos makes. The local shell was never exposed: the whole remote script is a single quoted argv element. And the caller that supplies `out` also supplies `command`, which is arbitrary remote code by design, so injection through `out` granted nothing that was not already on offer. Guarding it anyway. It costs one regex, it keeps a future caller that pins `command` but forwards `out` from handing over the box's shell, and it turns a path containing a space into a clear error rather than a baffling tar failure. Paths that would escape /work are refused too.
Codex resolves plugin manifests from .codex-plugin/plugin.json first, then falls back to .claude-plugin/plugin.json and .cursor-plugin/plugin.json, so the plugin was living in Claude Code's namespace on that fallback. The marketplace entry stays in .claude-plugin/marketplace.json because that is the only marketplace path the Codex binary knows — there is no .codex-plugin/marketplace.json. Removing the entry makes `codex plugin add createos-sandbox-codex` fail outright.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
@createos/codex→createos-sandbox-codex; now ships the samecosdriver + skill + session-start/pre-tool-use hookssandbox-engine.ts— TypeScript port ofcos(offload, keepalive, egress presets, auto-destroy, staging excludes, computer use)scripts/sync-shared.sh+ CI drift check keeps the shared driver/skill/engine copies honestcreateos-claude-plugins→createos-pluginthroughoutBugs fixed
hookSpecificOutputlike Claude Code does, so it injected nothingpullArtifactsreported success for a pull that never happened — GNU tar writes a valid empty archive for a missing path, and/bin/shpipelines report only the last command's status, so the box holding the only copy of the output was destroyedoutis now validated before reaching a shellVerified
Not included
website-04(7 pages, incl. the broken Codex install path)