Skip to content

Releases: wastedcode/claudemux

v0.2.4

19 Jun 13:51
bdeb4a4

Choose a tag to compare

Fixes a delivered turn surfacing as lost (DELIVERY_UNCONFIRMED / empty messagesSince) when claude's first transcript flush is late under MCP/tool load (ADR 0009).

📦 npm install @wastedcode/claudemux@0.2.4

Fixed

  • A late first transcript flush under MCP/tool load no longer surfaces a delivered turn as lost. Under contention, claude defers a fresh session's first <id>.jsonl write by 3–9 s — past the fixed anchor window — so send() returned the DELIVERY_UNCONFIRMED sentinel and a reader that saw wait()→completed still read an empty messagesSince("0") / turnComplete === false, even though the turn had landed. claudemux now tolerates the late flush at both seams against one shared budget: the write-side cursor anchor keeps polling while the transcript file is addressable-but-absent, and a read-side settle waits the first records out once. A present / fast-flush session is untouched (the anchor keeps its exact window; the settle returns on the first poll), and the settle is bounded on both success and exhaustion, so a never-flushing session (a crashed/slow resume) is never re-stalled. Verified live (claude 2.1.181): 1/20 → 0/20 sentinels under 20 concurrent heavy tool-MCP sessions. See ADR 0009.

Full changelog: https://github.com/wastedcode/claudemux/blob/v0.2.4/CHANGELOG.md
Compare: v0.2.3...v0.2.4

v0.2.3

09 Jun 18:49
10ccbac

Choose a tag to compare

Fixes empty agent transcripts when claudemux runs inside another Claude Code session (parent-agent env scrub, ADR 0008).

📦 npm install @wastedcode/claudemux@0.2.3

Fixed

  • Spawned agents now persist their conversation transcript when claudemux is run from inside another Claude Code session. An inherited CLAUDECODE / CLAUDE_CODE_* / AI_AGENT environment could trip claude's nested-session detection and suppress the agent's transcript — leaving claudemux, which drives agents by reading that transcript, with an empty conversation (stalled gating, empty messagesSince, delivery never confirmed). claudemux now scrubs those variables at the pane-launch boundary (env -u … -- claude …, a true unset that survives the shared/persistent tmux server) so a spawned agent always owns its own transcript. Root-caused via A/B across claude 2.1.168–2.1.170 (not a version regression; the suppression is environment-fragile). The existing env passthrough remains the escape hatch. See ADR 0008.

Security

  • Validate unsetEnv names at the backend boundary (InvalidEnvVarName). Defense-in-depth: env-var names spliced into the env -u launch prefix must be POSIX identifiers. Not consumer-exploitable today (the sole producer is a trusted constant and the spawn path is shell-free execFile argv), but it closes the seam against any future untrusted producer.

Full changelog: https://github.com/wastedcode/claudemux/blob/v0.2.3/CHANGELOG.md
Compare: v0.2.2...v0.2.3

v0.2.2

08 Jun 04:06
a5b7cad

Choose a tag to compare

Adds claudemux --version and resolves all open security alerts (CodeQL + Dependabot).

📦 npm install @wastedcode/claudemux@0.2.2

Added

  • claudemux --version prints the package version. Previously rejected as an unknown option. Thanks to an external contributor (#7).

Security

  • No consumer-facing vulnerabilities — the items below are dev/CI hardening only. The published package ships dist/ + bin/ (no node_modules), so none of these reached installs of @wastedcode/claudemux.
  • Upgraded vitest 2 → 4, clearing three dev-dependency advisories (vitest UI arbitrary file read/exec — the UI server is never run here; transitive vite .map path traversal; esbuild dev-server). npm audit is now clean. Supersedes Dependabot #10/#11.
  • Hardened subprocess calls in the test/dev scripts to build argv arrays via execFile instead of interpolating values (incl. CLAUDEMUX_SOCKET) into a shell string. Shipped src/ was already shell-free.
  • CI workflow now declares least-privilege permissions: contents: read.

Full changelog: https://github.com/wastedcode/claudemux/blob/v0.2.2/CHANGELOG.md
Compare: v0.2.1...v0.2.2

v0.2.1

07 Jun 16:15
0d2b0a0

Choose a tag to compare

Patch release. Three fixes — one correctness bug against an advertised guarantee, one CLI parity gap, one test-isolation bug.

📦 npm install @wastedcode/claudemux@0.2.1

Fixed

  • completed now guarantees the reply is on disk across processes. A stable idle pane can settle before the transcript flush of a large reply, so a SEPARATE process calling messages/messagesSince right after a wait that reported completed could read [] while capture showed the full reply — a silent empty read for orchestrators using the structured path. The "race-free after completed" guarantee held only for a single in-process observer; the CLI sendwaitmessages flow crosses three processes whose only shared channel is the on-disk transcript. wait now holds completed until the reply record is on disk (newest transcript message is assistant; a claude tool-result is user-role, so a tool turn waits for its FINAL answer). No deadline is introduced — a blind transcript falls back to the pane, and a readable-but-unflushed reply is bounded by the consumer's existing patience ("time is the policy's"). In-process it's a no-op. Easiest trigger: a long reply.
  • resume forwards -- <agent flags> like spawn. The post--- passthrough had landed on spawn only; both boot constructors now share one withBootOptions builder so they can't drift again.
  • CLI subprocess tests no longer leak onto the default socket. The harness exported TMUX_SOCKET (read by nobody — tmux uses -L, the substrate uses CLAUDEMUX_SOCKET), so harness-spawned CLI processes silently used the default socket.

Full changelog: https://github.com/wastedcode/claudemux/blob/v0.2.1/CHANGELOG.md
Compare: v0.2.0...v0.2.1