Skip to content

chore: re-pin agent-bundle preview cd0b4a62c — MCP server stands by instead of exiting on a socket collision - #85

Merged
ScriptedAlchemy merged 1 commit into
masterfrom
chore/repin-agent-bundle-cd0b4a62c
Sep 5, 2026
Merged

ScriptedAlchemy merged 1 commit into
masterfrom
chore/repin-agent-bundle-cd0b4a62c

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Why

Every host session launches its own hauler MCP server from the same installed pack, and only one of them can own the pack's event-runtime Unix socket. On 0.4.8 the second server exited before answering initialize (EventRuntimeTransportError: Event runtime endpoint already has a live server.), which is why the hauler_* tools were invisible in a second concurrent Claude Code / Codex / Cursor session.

agent-bundle fixed this in #561 (closes #559), squash cd0b4a62c: the generated server starts in the standby role when the socket is owned, serves its own MCP session, probes ~1 s (jittered), and takes the socket over when the owner exits. Both transitions, and any takeover failure other than "still owned", go to stderr only.

What changed

  • package.json: agent-bundle and @agent-bundle/runtime re-pinned from the c2ffe5ec5 pkg.pr.new preview to cd0b4a62cd92b3fbced6742b3cead32d9639c3e4 (the way this repo already consumes the framework — pkg.pr.new tarballs pinned by full SHA in devDependencies); pnpm-lock.yaml regenerated.
  • pnpm-workspace.yaml: blockExoticSubdeps: false, with a comment. The only change the new framework needed: the cd0b4a62c @agent-bundle/runtime preview depends on the same-commit preview tarball of rsc-markdown-stream (behind MarkdownContent; not on npm), and pnpm 11 rejects URL-resolved transitive dependencies by default (ERR_PNPM_EXOTIC_SUBDEP). Neither a direct devDependency on the same URL nor an overrides entry satisfies the check (both probed), so the setting is the fix the diagnostic names. Development-only: the published package still declares no dependencies.
  • README.md: the pinned-commit note.
  • .changeset/repin-cd0b4a62c-standby.md (patch).

No source, generated-file, or diagnostic changes were needed: agent-bundle validate/build pass clean on the new framework (no AB7014/AB7015), Claude host validation passes (Claude Code 2.1.260).

Verification

  • pnpm check: validate, build, typecheck, Effect diagnostics (0 errors, 0 warnings), rstest 811/811, route-unit 45/45.

  • pnpm prepack: Prepack validated 77 file(s) for cargo-hauler; npm pack → 77 files, dependencies absent.

  • Standby proof in the built artifact — two node artifact/claude/mcp/mcp-hauler-2b8242f9.mjs processes from the same install root, same env and cwd, each fed a JSON-RPC initialize on stdin (harness and full transcripts under /tmp/hauler-standby/).

    Before, 0.4.8 as installed from npm (before-0.4.8/transcript.log):

    +   350ms A stdout: id=1 result serverInfo={"name":"cargo-hauler","version":"0.4.8"}
    +  1915ms B: spawned pid 3044137
    +  2227ms B stderr: EventRuntimeTransportError: Event runtime endpoint already has a live server.
    +  2227ms B stderr:   code: 'runtime-failed'
    +  2264ms B: exited code=1 signal=null
    +  5996ms summary: … B initialize=NO REPLY tools/list#2=NO REPLY
    

    After, this branch's build (after-cd0b4a62c/transcript.log):

    +  1965ms B: spawned pid 3715500
    +  2249ms B stderr: agent-bundle event runtime: /tmp/agent-bundle-1000/event-c39012e1204575401879b1f2f08980c4.sock is owned by another process; standing by
    +  2289ms B stdout: id=1 result serverInfo={"name":"cargo-hauler","version":"0.4.8"} protocolVersion=2025-06-18
    +  2329ms B stdout: id=2 result tools=[hauler_await, hauler_kill, hauler_last, hauler_log, hauler_request, hauler_result, hauler_status]
    +  5651ms B stdout: id=10 result content[0]="cargo-hauler · daemon running (pid 132023) · 1/5 permits, 4 queued · …"
    +  5670ms killing A with SIGTERM
    +  5703ms A: exited code=143 signal=null
    +  6562ms B stderr: agent-bundle event runtime: /tmp/agent-bundle-1000/event-c39012e1204575401879b1f2f08980c4.sock was released by its owner; took it over
    +  6585ms B stdout: id=3 result tools=[hauler_await, hauler_kill, hauler_last, hauler_log, hauler_request, hauler_result, hauler_status]
    +  6715ms B stdout: id=11 result content[0]="cargo-hauler · daemon running (pid 132023) · …"
    

    The second server answers initialize, tools/list, and a real hauler_status call while standing by, takes the socket over ~0.9 s after the owner exits, and keeps answering afterwards. The socket file is removed on exit; no stray processes.

  • CLI smoke from the build: node dist/bin/hauler.js status --json → daemon running, state dir /fast/cache/cargo-hauler.

Self-review

Reviewed the diff against origin/master by hand (no second-model reviewer was run for this dependency re-pin):

  • Lockfile: only the two pins move plus the new transitive closure of the cd0b4a62c previews (rsc-markdown-stream preview, npm-package-arg, hosted-git-info, lru-cache, proc-log, validate-npm-package-name); nothing else changes.
  • blockExoticSubdeps: false widens what transitive dependencies may come from URLs. Accepted: the repo already trusts the same pkg.pr.new namespace for its direct pins, the setting is dev-only, and the comment ties it to the preview pin so it goes when agent-bundle is on npm.
  • Version string: the build still reports 0.4.8 because the version bump lands through the Version Packages PR (Version Packages #84), as for every release here.

… by instead of exiting on a socket collision

The pkg.pr.new preview of agent-bundle main cd0b4a62cd92b3fbced6742b3cead32d9639c3e4
(#561, closes agent-bundle #559): a generated MCP server that finds the pack's
event-runtime Unix socket owned by another process from the same install no
longer exits before answering `initialize`; it starts in the standby role,
serves its own MCP session, probes the socket ~1 s (jittered), and takes it
over when the owner exits. Both transitions and any takeover failure other
than "still owned" go to stderr only. This is why the `hauler_*` tools were
missing from a second concurrent Claude Code / Codex / Cursor session on 0.4.8.

Development only: the `@agent-bundle/runtime` preview now depends on the
same-commit preview tarball of `rsc-markdown-stream` (not on npm), which pnpm
11's default `blockExoticSubdeps` rejects as a URL-resolved transitive
dependency, so pnpm-workspace.yaml sets `blockExoticSubdeps: false`. The
published package still declares no runtime dependencies.

Verified: `pnpm check` (validate, build, typecheck, diagnostics, 811 + 45
tests) and `agent-bundle prepack` pass; two servers started from one built
pack — the second answers `initialize`, logs
"is owned by another process; standing by", and after the first is killed logs
"was released by its owner; took it over" and keeps answering `tools/list`
and `hauler_status`.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@changeset-bot

changeset-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2de28b7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
cargo-hauler Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@ScriptedAlchemy
ScriptedAlchemy merged commit 23b3bb8 into master Sep 5, 2026
2 checks passed
@ScriptedAlchemy
ScriptedAlchemy deleted the chore/repin-agent-bundle-cd0b4a62c branch September 5, 2026 00:18
@github-actions github-actions Bot mentioned this pull request Sep 5, 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.

Generated MCP server exits when another session already owns the event runtime socket

1 participant