diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index ac1f4df..9968684 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -26,7 +26,7 @@ - WebKit2GTK has no WebGL — xterm.js must use Canvas addon explicitly. - Agent sessions use `claude` CLI with `--output-format stream-json` (not Agent SDK npm package). All output goes through the adapter layer (`src/lib/adapters/sdk-messages.ts`). -- Sidecar uses Deno-first + Node.js fallback (`sidecar/agent-runner-deno.ts` preferred, `sidecar/agent-runner.ts` fallback). SidecarCommand struct in sidecar.rs abstracts runtime. Communicates with Rust via stdio NDJSON. +- Sidecar uses Deno-first + Node.js fallback (`sidecar/agent-runner-deno.ts` preferred, `sidecar/agent-runner.ts` fallback). SidecarCommand struct in sidecar.rs abstracts runtime. Communicates with Rust via stdio NDJSON. Both runners MUST strip ALL `CLAUDE*` prefixed env vars before spawning the claude CLI — without this, the CLI silently hangs due to nesting detection when BTerminal is launched from a Claude Code terminal. - Agent dispatcher (`src/lib/agent-dispatcher.ts`) is a singleton that routes sidecar events to the agent store. Also handles subagent pane spawning (SUBAGENT_TOOL_NAMES detection, toolUseToChildPane routing map). - Maximum 4 active xterm.js instances to avoid WebKit2GTK memory issues. - Store files using Svelte 5 runes (`$state`, `$derived`) MUST have `.svelte.ts` extension (not `.ts`). Import with `.svelte` suffix. Plain `.ts` compiles but fails at runtime with "rune_outside_svelte". diff --git a/CHANGELOG.md b/CHANGELOG.md index 21afc51..bd9f9f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Cargo test suite: session.rs tests (SessionDb CRUD for sessions, SSH sessions, settings, layout) and ctx.rs tests (CtxDb error handling with missing database) - tempfile dev dependency for Rust test isolation +### Fixed +- Sidecar env var leak: both agent-runner.ts and agent-runner-deno.ts now strip ALL `CLAUDE*` prefixed env vars before spawning the claude CLI, preventing silent hangs when BTerminal is launched from within a Claude Code terminal session (previously only CLAUDECODE was removed) + ### Changed - RemoteManager reconnection probe refactored from attempt_ws_connect() (full WS handshake + auth) to attempt_tcp_probe() (TCP-only connect, no resource allocation on relay) - bterminal-relay command handlers refactored: all error paths now use send_error() helper instead of log::error!() only; pong response sent via event channel instead of no-op diff --git a/TODO.md b/TODO.md index 02ef8f1..09fb741 100644 --- a/TODO.md +++ b/TODO.md @@ -10,6 +10,7 @@ ## Completed +- [x] **Sidecar CLAUDE* env var leak fix** -- Both sidecar runners now strip ALL CLAUDE-prefixed env vars before spawning claude CLI. Prevents silent hang when BTerminal launched from Claude Code terminal. | Done: 2026-03-06 - [x] **Multi-machine reconnection** -- Exponential backoff reconnection (1s-30s cap) in RemoteManager, attempt_tcp_probe() (TCP-only), frontend reconnection listeners + auto-reconnect. | Done: 2026-03-06 - [x] **Relay command response propagation** -- Structured responses (pty_created, pong, error) with commandId correlation, send_error() helper. | Done: 2026-03-06 - [x] **Multi-machine support (Phases A-D)** -- bterminal-core crate extraction, bterminal-relay WebSocket binary, RemoteManager, frontend integration. | Done: 2026-03-06 @@ -19,4 +20,3 @@ - [x] **Session groups/folders** -- group_name column in sessions table, setPaneGroup in layout store, collapsible group headers in sidebar, right-click to set group. | Done: 2026-03-06 - [x] **Deno sidecar integration** -- SidecarCommand struct, resolve_sidecar_command() with Deno-first + Node.js fallback, both runners bundled in tauri.conf.json resources. | Done: 2026-03-06 - [x] **E2E/integration test suite** -- 114 vitest tests + 29 cargo tests. | Done: 2026-03-06 -- [x] **Set TAURI_SIGNING_PRIVATE_KEY secret** -- Set via `gh secret set` on DexterFromLab/BTerminal. | Done: 2026-03-06 diff --git a/docs/progress.md b/docs/progress.md index 183daa6..aa80414 100644 --- a/docs/progress.md +++ b/docs/progress.md @@ -345,6 +345,15 @@ Design: No separate sidecar process per subagent. Parent's sidecar handles all; - [x] machines.svelte.ts: reconnect-ready handler auto-calls connectMachine() to re-establish full WebSocket connection - [x] Updated docs/multi-machine.md to reflect TCP probe and frontend listener changes +### Session: 2026-03-06 (continued) — Sidecar Env Var Bug Fix + +#### CLAUDE* Environment Variable Leak (critical fix) +- [x] Diagnosed silent hang in agent sessions when BTerminal launched from Claude Code terminal +- [x] Root cause: Claude Code sets ~8 CLAUDE* env vars (CLAUDECODE, CLAUDE_ORIGPROMPT, CLAUDE_BASH_MAINTAIN_CWD, CLAUDE_BASH_SANDBOX_DIR, etc.) for nesting/sandbox detection. Previous fix only removed CLAUDECODE, but the CLI checks multiple indicators. +- [x] Fixed agent-runner.ts: replaced `{ ...process.env, CLAUDECODE: undefined }` with clean env object filtering out all keys starting with 'CLAUDE' +- [x] Fixed agent-runner-deno.ts: same approach, iterate Deno.env.toObject() and skip CLAUDE-prefixed keys +- [x] Pre-built dist/agent-runner.mjs already updated with the fix + ### Next Steps - [ ] Real-world relay testing (2 machines) - [ ] TLS/certificate pinning for relay connections