Add Tokyo Night, Gruvbox Dark, Ayu Dark, Poimandres, Vesper, and
Midnight themes. Now 17 total themes in 3 groups: Catppuccin (4),
Editor (7), Deep Dark (6). Midnight is pure OLED black (#000000).
Generalize theme system from Catppuccin-only (4 flavors) to 11 themes
across 2 groups. New editor themes: VSCode Dark+, Atom One Dark,
Monokai, Dracula, Nord, Solarized Dark, GitHub Dark.
All themes map to the same 26 --ctp-* CSS custom properties, so every
component works unchanged. ThemeId replaces CatppuccinFlavor as primary
type. Theme store uses getCurrentTheme()/setTheme() with deprecated
wrappers. SettingsTab uses optgroup-based theme selector.
Add Global section with theme flavor dropdown, default shell input, and
default CWD input. All settings persisted via settings-bridge. Fix a11y
by using wrapping <label> elements for project fields. Clean up unused
CSS selectors.
- Remove unused SessionDb::update_ssh_session() and its test (SshDialog
was deleted in P10, this method had no callers)
- Fix stale TilingGrid reference in AgentPane comment
- Eliminates the last Rust compiler warning
Without the preset, settingSources loads files but the system prompt has
no slot to inject CLAUDE.md content. The claude_code preset enables the
full Claude Code system prompt including project instructions.
Add switcher-claude multi-account support with profile selector in AgentPane
toolbar, skill autocomplete menu (type / in prompt), and 5 new AgentQueryOptions
fields (setting_sources, system_prompt, model, claude_config_dir,
additional_directories) flowing through full stack from Rust to SDK.
New Tauri commands: claude_list_profiles, claude_list_skills, claude_read_skill,
pick_directory. New frontend adapter: claude-bridge.ts.
Both sidecar runners (agent-runner.ts and agent-runner-deno.ts) now include
findClaudeCli() which checks common paths (~/.local/bin/claude,
~/.claude/local/claude, /usr/local/bin/claude, /usr/bin/claude) and falls
back to `which claude`. The resolved path is passed to the SDK query()
options as pathToClaudeCodeExecutable. If the CLI is not found, an
agent_error is emitted immediately instead of a cryptic SDK failure.
Add env_clear() + envs(clean_env) to Command in SidecarManager to
filter all CLAUDE-prefixed environment variables before spawning the
sidecar process. This provides primary defense against SDK nesting
detection when BTerminal is launched from a Claude Code terminal.
The JS-side stripping via SDK env option is retained as defense-in-depth.
Consolidated from two separate runners (agent-runner-deno.ts +
agent-runner.ts) to a single pre-built agent-runner.mjs that runs
under both Deno and Node.js. resolve_sidecar_command() now checks
runtime availability upfront before path search, with improved
error messages. Removed agent-runner-deno.ts from tauri.conf.json
bundled resources.
- Add permission_mode field to AgentQueryOptions (Rust, sidecar, bridge)
flowing from controller through sidecar to SDK; defaults to
bypassPermissions, supports default mode
- Fix AgentPane onDestroy bug: remove stopAgent() from onDestroy (fires
on layout remounts), move stop-on-close to TilingGrid onClose handler
- Bundle SDK into sidecar via esbuild (remove --external flag)
Claude CLI v2.1.69 hangs silently when spawned via child_process.spawn()
with piped stdio (known bug github.com/anthropics/claude-code/issues/6775).
Replace raw CLI spawning in both sidecar runners with the SDK's query()
function, which handles subprocess management internally. SDK message
format matches CLI stream-json, so the sdk-messages.ts adapter is
unchanged.
- agent-runner.ts: use SDK query() with AbortController for stop
- agent-runner-deno.ts: use npm:@anthropic-ai/claude-agent-sdk import
- sidecar.rs: add --allow-write and --allow-net Deno permissions
- package.json: add @anthropic-ai/claude-agent-sdk ^0.2.70, build:sidecar script
When BTerminal is launched from a Claude Code terminal, ~8 CLAUDE*
env vars leak into the sidecar child processes. The claude CLI detects
these as nesting indicators and silently hangs. Previously only
CLAUDECODE was removed; now all CLAUDE-prefixed vars are stripped
in both Node.js and Deno sidecar runners.
Replace attempt_ws_connect() with attempt_tcp_probe() in RemoteManager to
avoid allocating per-connection resources (PtyManager, SidecarManager) on
the relay during reconnection probes. Add onRemoteMachineReconnecting and
onRemoteMachineReconnectReady event listeners in remote-bridge.ts. Wire
machines store to auto-reconnect when relay becomes reachable.
remote-bridge.ts adapter for machine management IPC. machines.svelte.ts
store for remote machine state. Layout store extended with
remoteMachineId on Pane interface. agent-bridge.ts and pty-bridge.ts
route to remote commands when remoteMachineId is set. SettingsDialog
gains Remote Machines section. Sidebar auto-groups remote panes by
machine label.
New remote.rs module in src-tauri with WebSocket client connections to
bterminal-relay instances. Machine lifecycle: add/remove/connect/
disconnect. 12 new Tauri commands for remote operations. Heartbeat
ping every 15s. lib.rs updated with remote commands and AppState.
Create Cargo workspace at v2/ level with members: src-tauri,
bterminal-core, bterminal-relay. Extract PtyManager and SidecarManager
into shared bterminal-core crate with EventSink trait for abstracting
event emission. TauriEventSink wraps AppHandle. src-tauri pty.rs and
sidecar.rs become thin re-exports. Move Cargo.lock to workspace root.
Add v2/target/ to .gitignore.
getTotalCost() recursively aggregates costUsd, inputTokens, outputTokens
across parent and all child sessions. AgentPane done-bar displays total
cost in yellow when children are present and total exceeds parent cost.
Detect subagent tool_call events (Agent/Task/dispatch_agent), auto-spawn
child agent panes with parent/child navigation. Messages with parentId
are routed to child panes; parent session keeps its own messages.
- agents.svelte.ts: parent/child hierarchy fields, findChildByToolUseId,
getChildSessions, parent-aware createAgentSession/removeAgentSession
- agent-dispatcher.ts: SUBAGENT_TOOL_NAMES detection, toolUseToChildPane
routing map, spawnSubagentPane with auto-grouping under parent title
- AgentPane.svelte: parent link bar (SUB badge), children bar (chips
with status colors), clickable navigation between parent/child
- SessionList.svelte: subagent panes show arrow icon instead of asterisk
Refactor SidecarManager to use SidecarCommand struct abstracting
runtime choice. resolve_sidecar_command() prefers Deno (runs TS
directly, no build step), falls back to Node.js if deno not in PATH.
Both runners bundled in tauri.conf.json resources. Set auto-update
signing pubkey in updater config.
Add group_name column to sessions table with ALTER TABLE migration,
setPaneGroup in layout store, grouped sidebar rendering with Svelte 5
snippets, and right-click to assign group via prompt dialog.
Experimental agent-runner-deno.ts as drop-in replacement for Node.js sidecar.
Uses Deno.Command for claude CLI subprocess, TextLineStream for NDJSON parsing.
Same stdio NDJSON protocol. Compiles to single binary via deno compile.
Not yet integrated with Rust SidecarManager.
Build-from-source installer (install-v2.sh) with dependency checks for
Node.js 20+, Rust 1.77+, and system libraries. Tauri bundle config for
.deb and AppImage targets. GitHub Actions workflow builds and uploads
release artifacts on version tags. Icons regenerated as RGBA PNGs.
Agent tree visualization (SVG) with horizontal layout and bezier edges.
Global status bar with pane counts, active agents pulse, token/cost totals.
Toast notification system with auto-dismiss and agent dispatcher integration.
Settings dialog with SQLite persistence for shell, cwd, and max panes.
Keyboard shortcuts: Ctrl+W close pane, Ctrl+, open settings.
Phase 3 polish: dispatcher listens for sidecar-exited events and marks
running sessions as error. AgentPane shows "Restart Sidecar" button on
error. Auto-scroll disables when user scrolls >50px from bottom with
"Scroll to bottom" button. Added agent_restart Tauri command.
Svelte 5 $state/$derived runes only work in .svelte and .svelte.ts
files. The stores had plain .ts extensions, causing a blank screen with
"rune_outside_svelte" runtime error. Renamed all three store files and
updated import paths across 5 consuming files.
Replace Agent SDK stub with working implementation that spawns
claude CLI with --output-format stream-json, manages multiple
sessions via Map<sessionId, ChildProcess>, and forwards NDJSON
events to Rust backend. Supports query, stop, and graceful shutdown.