Skip to content

Nix-free plugin launcher — consumers launch via bun on PATH - #2

Merged
GraemeF merged 1 commit into
mainfrom
comms-ip4q-pr
Jun 11, 2026
Merged

GraemeF merged 1 commit into
mainfrom
comms-ip4q-pr

Conversation

@GraemeF

@GraemeF GraemeF commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

What

The Claude Code plugin required Nix on the consumer's PATH: .mcp.json launched the MCP server via nix run path:${CLAUDE_PLUGIN_ROOT}#default -- … server.ts, and the PreToolUse hook resolved bun via nix build. The plugin's flake only ever provided pkgs.bun, so every external installer of commy@commy needed Nix for no reason beyond pinning bun.

Nix stays fully supported for those who use it (the flake and dev shell are untouched) — it just no longer sits in the consumer launch path. Vanilla bun-on-PATH is the baseline; nix is an opt-in addition.

How

  • Launcher → clients/claude-code/launch.sh, a POSIX-sh bun-on-PATH bootstrap (no bashisms, so it imposes no shell of our choosing — dash/ash/busybox/bash all run it). Claude Code installs a plugin by cloning the marketplace repo and installs no JS deps, so a fresh checkout has no node_modules; the launcher stages the workspace deps once — bun install --frozen-lockfile at the workspace root, guarded by a portable mkdir mutex + a re-check so concurrently-booting sessions can't race to EEXIST — then execs bun against the server entrypoint.
    • exec keeps the server Claude Code's direct child, so a session disconnect reaches it (no orphaned server).
    • The stage runs only when node_modules is absent; every launch after the first is a plain exec, no install at connect.
  • PreToolUse hook → bun on PATH directly; the now-vestigial hooks/bun-wrap.sh (the nix-build wrapper) and its test are removed. The hook entrypoint imports no workspace packages, so it needs only bun, nothing staged.
  • Bun pin moves from the flake to packageManager: "bun@1.3.13" + a documented minimum (bun ≥ 1.3.13) in the plugin README.

Prereq for consumers

bun ≥ 1.3.13 on PATH — that's the whole prerequisite. No Nix, no global installs.

Verification

  • Clean clone + launch.sh cold-boots (stages deps, answers MCP initialize with serverInfo) and warm-boots (no reinstall, pure exec) — both under POSIX sh.
  • shellcheck -s sh clean; sh -n clean.
  • Full bun run check green; new tests pin the contracts (bun-not-nix, exec direct-child, no run/start indirection, guarded one-time stage, POSIX-sh shebath/no-bashisms).

The plugin launcher required Nix on the consumer's PATH: .mcp.json ran
'nix run path:${CLAUDE_PLUGIN_ROOT}#default -- ... server.ts' and the
PreToolUse hook resolved bun via 'nix build'. The flake only ever
provided pkgs.bun, so every external installer of commy@commy needed Nix
for no reason beyond pinning bun. Nix stays supported for those who use
it (the flake and dev shell are untouched) — it just no longer sits in
the consumer launch path. Vanilla bun-on-PATH is the baseline; nix is an
opt-in addition.

Replace the nix launcher with launch.sh: a POSIX-sh bun-on-PATH bootstrap
(no bashisms, so it imposes no shell of our choosing — dash/ash/busybox/
bash all run it) that stages the workspace deps once (bun install
--frozen-lockfile at the workspace root, guarded by a portable mkdir
mutex so concurrently-booting sessions can't race to EEXIST — the
comms-ae3 regression), then execs bun against the server entrypoint. The
exec keeps the server claude's direct child so a disconnect reaches it
(comms-hfhm); the stage runs only when node_modules is absent, so every
launch after the first is a plain exec. The frozen marketplace copy ships
node_modules pre-staged, so fleet seats skip the install branch entirely.

Point the PreToolUse hook at bun on PATH directly and drop the now-vestigial
hooks/bun-wrap.sh (the nix-build wrapper). The hook entrypoint imports no
workspace packages, so it needs only bun, nothing staged.

Bun pin moves from the flake to packageManager: 'bun@1.3.13' plus a
documented minimum (bun >= 1.3.13) in the plugin README.

Verified: clean clone + launch.sh cold-boots (stages deps, answers MCP
initialize with serverInfo) and warm-boots (no reinstall, pure exec)
under POSIX sh; shellcheck -s sh clean; full bun run check green.
@GraemeF
GraemeF merged commit a2827ac into main Jun 11, 2026
2 checks passed
@GraemeF
GraemeF deleted the comms-ip4q-pr branch June 11, 2026 10:52
GraemeF added a commit that referenced this pull request Jun 11, 2026
The README targeted developers — architecture map, workspace package
table, the full self-hosting env contract. This rewrites it to address
**consumers**: people installing the commy plugin so their Claude Code
agents (and the humans alongside them) can talk to each other across
sessions and machines. The register leans into the "commie" pun —
comrades, the collective, seize the means of communication — confidently
silly, but the install path stays plain underneath.

**Install path kept accurate:** `claude plugin marketplace add
CodeForBreakfast/commy`, `claude plugin install commy@commy`, the three
required userConfig, and the sole prerequisite — `bun ≥ 1.3.13` on PATH,
no Nix (matching the launcher landed in #2). Versioning section stays
truthful (curated GitHub Release model).

**Displaced developer/operator content is relocated, not dropped:**
- `docs/architecture.md` — hexagonal overview, workspace package map,
substrate-rationale and inbound-contract pointers.
- `docs/self-hosting.md` — full environment contract, running outside
Claude Code, the persistent post-only bot shape, and the
inbound-is-host-work contract.
- `AGENTS.md` front-door pointer repointed from the README to those two
docs.

Gate green locally on this base (`nix develop .#ci` → `bun install
--frozen-lockfile && bun run check`: 847 tests, 0 fail, all 4 turbo
tasks).
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