Rust groups.rs ProjectConfig was missing provider, model, and other optional
fields — serde silently dropped them on save, causing all projects to fall
back to claude/Opus on reload. Added all missing fields to both ProjectConfig
and GroupAgentConfig structs.
Rewrote aider-runner from one-shot --message mode to interactive stdin/stdout:
- Persistent aider process with multi-turn conversation support
- Pre-fetches btmsg inbox and bttask board before sending prompt to LLM
- Autonomous agent override prompt so LLM acts instead of asking for files
- Line-buffered output (no token-by-token fragments)
- Thinking block classification for DeepSeek R1
- Graceful /exit shutdown
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add aider-runner.ts sidecar that spawns aider CLI in non-interactive mode
- Add Aider provider metadata with OpenRouter model presets
- Add aider-messages.ts adapter for Aider event format
- Refactor SidecarManager from single-process to per-provider process management
with lazy startup on first query and session→provider routing
- Add openrouter_api_key to secrets system (keyring storage)
- Inject OPENROUTER_API_KEY from secrets into Aider agent environment
- Register Aider in provider registry, build pipeline, and resource bundle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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 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.
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.
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.