From 658dc4715e7885529f6b761f92eba50302e3793f Mon Sep 17 00:00:00 2001 From: Hibryda Date: Fri, 6 Mar 2026 23:34:09 +0100 Subject: [PATCH] docs: update meta files for permission mode, agent stop-on-close fix, SDK bundling --- .claude/CLAUDE.md | 3 +++ CHANGELOG.md | 9 +++++++-- TODO.md | 8 +++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index f7fb66c..0e4b930 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -27,7 +27,10 @@ - WebKit2GTK has no WebGL — xterm.js must use Canvas addon explicitly. - Agent sessions use `@anthropic-ai/claude-agent-sdk` query() function (migrated from raw CLI spawning due to piped stdio hang bug). SDK handles subprocess management internally. All output goes through the adapter layer (`src/lib/adapters/sdk-messages.ts`) — SDK message format matches CLI stream-json. - 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 via SDK's `env` option — without this, nesting detection triggers when BTerminal is launched from a Claude Code terminal. Session stop uses AbortController.abort() (not process.kill()). +- AgentPane does NOT stop agents in onDestroy — onDestroy fires on layout remounts, not just explicit close. Stop-on-close is handled by TilingGrid.svelte's onClose handler (checks pane type + session status before calling stopAgent). - 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). +- AgentQueryOptions supports `permission_mode` field (flows Rust -> sidecar -> SDK). Defaults to 'bypassPermissions', supports 'default' mode. allowDangerouslySkipPermissions is conditionally set. +- Sidecar build: `npm run build:sidecar` bundles SDK into agent-runner.mjs via esbuild (no --external, SDK included in bundle). - 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". - Session persistence uses rusqlite (bundled) with WAL mode. Data dir: `dirs::data_dir()/bterminal/sessions.db`. diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b58090..bb73bf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `@anthropic-ai/claude-agent-sdk` ^0.2.70 npm dependency for sidecar agent session management -- `build:sidecar` npm script for esbuild bundling of agent-runner.ts with SDK as external +- `build:sidecar` npm script for esbuild bundling of agent-runner.ts (SDK bundled in, no external dependency at runtime) +- `permission_mode` field in AgentQueryOptions (Rust, TypeScript) — flows from controller through sidecar to SDK, defaults to 'bypassPermissions', supports 'default' mode ### Changed - Sidecar agent runners migrated from raw `claude` CLI spawning (`child_process.spawn`/`Deno.Command`) to `@anthropic-ai/claude-agent-sdk` query() function — fixes silent hang when CLI spawned with piped stdio (known bug github.com/anthropics/claude-code/issues/6775) @@ -17,7 +18,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - agent-runner-deno.ts: sessions now use `AbortController` map; uses `npm:@anthropic-ai/claude-agent-sdk` import specifier - Deno sidecar permissions expanded: added `--allow-write` and `--allow-net` flags in sidecar.rs (required by SDK) - CLAUDE* env var stripping now passes clean env via SDK's `env` option in query() instead of filtering process.env before spawn -- SDK query() options: `permissionMode: 'bypassPermissions'`, `allowDangerouslySkipPermissions: true`, 10 allowedTools (Bash, Read, Write, Edit, Glob, Grep, WebSearch, WebFetch, TodoWrite, NotebookEdit) +- SDK permissionMode and allowDangerouslySkipPermissions now dynamically set based on permission_mode option (was hardcoded to bypassPermissions) +- build:sidecar esbuild command no longer uses --external for SDK (SDK bundled into output) + +### Fixed +- AgentPane onDestroy no longer kills running agent sessions on component remount — stopAgent() moved from AgentPane.svelte onDestroy to TilingGrid.svelte onClose handler, ensuring agents only stop on explicit user close action ### Previously Added - Exponential backoff reconnection in RemoteManager: on disconnect, spawns async task with 1s/2s/4s/8s/16s/30s-cap backoff, uses attempt_tcp_probe() (TCP-only, no WS upgrade, 5s timeout, default port 9750), emits remote-machine-reconnecting and remote-machine-reconnect-ready events diff --git a/TODO.md b/TODO.md index e76bf08..ef99fe5 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,6 @@ ## Active -- [ ] **AgentPane onDestroy session kill bug** -- AgentPane.svelte onDestroy calls stopAgent() on component unmount, killing running sessions when panes are switched/collapsed. Fix: decouple session lifecycle from component lifecycle. - [ ] **E2E testing (Playwright/WebDriver)** -- Scaffold at v2/tests/e2e/README.md. Needs display server to run. Test: open terminal, run command, open agent, verify output. - [ ] **Multi-machine real-world testing** -- Test bterminal-relay with 2 machines (local + 1 remote). Verify PTY + agent operations over WebSocket. - [ ] **Multi-machine TLS/certificate pinning** -- Add TLS support to bterminal-relay and certificate pinning in RemoteManager for production security. @@ -10,6 +9,9 @@ ## Completed +- [x] **AgentPane onDestroy bug fix** -- Removed onDestroy stopAgent() from AgentPane (fired on layout remounts). Stop-on-close moved to TilingGrid onClose handler. | Done: 2026-03-06 +- [x] **Permission mode passthrough** -- Added permission_mode field flowing Rust -> sidecar -> SDK. Defaults to bypassPermissions, supports default mode. | Done: 2026-03-06 +- [x] **SDK bundling fix** -- Removed --external flag from esbuild build:sidecar. SDK now bundled into agent-runner.mjs. | Done: 2026-03-06 - [x] **Sidecar SDK migration** -- Migrated both sidecar runners from raw `claude` CLI spawning to `@anthropic-ai/claude-agent-sdk` query(). Fixes silent hang bug (CLI #6775). SDK handles subprocess internally. Added ^0.2.70 dependency, build:sidecar script, updated Deno permissions. | Done: 2026-03-06 - [x] **Sidecar CLAUDE* env var leak fix** -- Both sidecar runners now strip ALL CLAUDE-prefixed env vars via SDK `env` option. Prevents nesting detection 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 @@ -17,7 +19,3 @@ - [x] **Multi-machine support (Phases A-D)** -- bterminal-core crate extraction, bterminal-relay WebSocket binary, RemoteManager, frontend integration. | Done: 2026-03-06 - [x] **Agent Teams frontend support** -- Subagent pane spawning, parent/child navigation, message routing by parentId, SUBAGENT_TOOL_NAMES detection in dispatcher. | Done: 2026-03-06 - [x] **Subagent cost aggregation** -- `getTotalCost()` recursive helper in agents store, total cost shown in parent pane done-bar when children present. | Done: 2026-03-06 -- [x] **Dispatcher tests for subagent routing** -- 10 new tests covering spawn, dedup, child message routing, init/cost forwarding, fallbacks. Total: 28 dispatcher tests. | Done: 2026-03-06 -- [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