Add .claude/rules/18-relative-units.md enforcing rem/em for layout CSS
(px only for icons/borders). Convert GlobalTabBar.svelte and App.svelte
sidebar styles from px to rem. Change rail-btn color to --ctp-subtext0.
Settings is now a right-side drawer (32em width, semi-transparent
backdrop) instead of a full-page tab. GlobalTabBar has 3 tabs
(Sessions/Docs/Context) + gear icon toggle. WorkspaceTab type
reduced to 'sessions' | 'docs' | 'context'. Close via Escape,
click-outside, or close button. Alt+1..3 for tabs, Ctrl+, toggles
drawer.
Split single font setting into separate UI font (sans-serif options)
and Terminal font (monospace options), each with custom themed dropdown
and size stepper (8-24px). Single-column layout with Appearance and
Defaults subsections. All native <select> replaced with custom themed
dropdowns. Font previews render in their own typeface. New CSS vars:
--term-font-family, --term-font-size. Setting keys changed from
font_family/font_size to ui_font_family/ui_font_size +
term_font_family/term_font_size.
Add font family select (9 monospace fonts) and font size +/- stepper
(8-24px) to SettingsTab global settings. Both controls apply live
preview via CSS custom properties (--ui-font-family, --ui-font-size)
and persist to SQLite. Restructure global settings from inline rows
to 2-column grid with labels above controls. initTheme() now restores
saved font settings on startup.
Custom dropdown in SettingsTab uses --ctp-* CSS vars for full theming.
Shows color swatches (base color) and accent dot previews (red/green/
blue/yellow) per theme. Grouped sections (Catppuccin/Editor/Deep Dark)
with styled headers. Click-outside and Escape to close. Uses getPalette()
from themes.ts for live color rendering.
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
v3 architecture planning: task plan with core concept, user requirements,
and architecture questions for adversarial review. Findings doc with
codebase reuse analysis (keep/replace/drop). Progress log for v3 sessions.
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.
- Added pathToClaudeCodeExecutable and findClaudeCli() docs to CLAUDE.md,
.claude/CLAUDE.md, task_plan.md decisions log, and CHANGELOG.md
- Split docs/progress.md (425 lines) into progress.md (153 lines) +
progress-archive.md (180 lines) to stay under 300-line threshold
- Updated docs/README.md, README.md with archive file reference
- Updated TODO.md with completed items from this session
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.
Updated all docs, CLAUDE.md files, README, and CHANGELOG to reflect
the consolidated sidecar approach (single agent-runner.mjs for both
Deno and Node.js). Removed references to agent-runner-deno.ts as
active runner. Added progress log entry for 2026-03-07 session.
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 stale attempt_ws_connect() references with attempt_tcp_probe()
across all docs. Add progress entry for reconnection hardening session.
Update CHANGELOG with new entries and probe refactor change.
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.