docs: update all docs for session groups, Deno sidecar, signing key, and tests

Update progress log, phases, task_plan decisions, CLAUDE.md files,
README, TODO, and CHANGELOG to reflect session groups, Deno-first
sidecar integration, auto-update signing key, and 104-test suite.
This commit is contained in:
Hibryda 2026-03-06 15:42:44 +01:00
parent 020dc20d4f
commit d021061b8a
8 changed files with 80 additions and 27 deletions

View file

@ -4,7 +4,7 @@
- v1 is a single-file Python app (`bterminal.py`). Changes are localized. - v1 is a single-file Python app (`bterminal.py`). Changes are localized.
- v2 docs are in `docs/`. Architecture decisions are in `docs/task_plan.md`. - v2 docs are in `docs/`. Architecture decisions are in `docs/task_plan.md`.
- All 6 phases complete + extras (SSH, ctx, themes, detached mode, auto-updater, shiki, copy/paste, session resume, drag-resize, testing). - All 6 phases complete + extras (SSH, ctx, themes, detached mode, auto-updater, shiki, copy/paste, session resume, drag-resize, session groups, Deno sidecar, 104 vitest + 29 cargo tests).
- Consult Memora (tag: `bterminal`) before making architectural changes. - Consult Memora (tag: `bterminal`) before making architectural changes.
## Documentation References ## Documentation References
@ -26,12 +26,13 @@
- WebKit2GTK has no WebGL — xterm.js must use Canvas addon explicitly. - 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`). - 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`).
- Node.js sidecar (`sidecar/agent-runner.ts`) spawns claude subprocesses, 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.
- Agent dispatcher (`src/lib/agent-dispatcher.ts`) is a singleton that routes sidecar events to the agent store. - Agent dispatcher (`src/lib/agent-dispatcher.ts`) is a singleton that routes sidecar events to the agent store.
- Maximum 4 active xterm.js instances to avoid WebKit2GTK memory issues. - 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". - 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`. - Session persistence uses rusqlite (bundled) with WAL mode. Data dir: `dirs::data_dir()/bterminal/sessions.db`.
- Layout store persists to SQLite on every addPane/removePane/setPreset change (fire-and-forget). Restores on app startup via `restoreFromDb()`. - Layout store persists to SQLite on every addPane/removePane/setPreset/setPaneGroup change (fire-and-forget). Restores on app startup via `restoreFromDb()`.
- Session groups: Pane.group? field in layout store, group_name column in sessions table, collapsible group headers in sidebar. Right-click pane to set group.
- File watcher uses notify crate v6, watches parent directory (NonRecursive), emits `file-changed` Tauri events. - File watcher uses notify crate v6, watches parent directory (NonRecursive), emits `file-changed` Tauri events.
- Settings use key-value `settings` table in SQLite (session.rs). Frontend: `settings-bridge.ts` adapter, `SettingsDialog.svelte` component. - Settings use key-value `settings` table in SQLite (session.rs). Frontend: `settings-bridge.ts` adapter, `SettingsDialog.svelte` component.
- Notifications use ephemeral toast system: `notifications.svelte.ts` store (max 5, 4s auto-dismiss), `ToastContainer.svelte` display. Agent dispatcher emits toasts on agent complete/error/crash. - Notifications use ephemeral toast system: `notifications.svelte.ts` store (max 5, 4s auto-dismiss), `ToastContainer.svelte` display. Agent dispatcher emits toasts on agent complete/error/crash.

View file

@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Added ### Added
- Session groups/folders: group_name column in sessions table, setPaneGroup in layout store, collapsible group headers in sidebar with arrow/count, right-click pane to set group
- Auto-update signing key: generated minisign keypair, pubkey configured in tauri.conf.json updater section
- Deno-first sidecar: SidecarCommand struct in sidecar.rs, resolve_sidecar_command() prefers Deno (runs TS directly) with Node.js fallback, both runners bundled via tauri.conf.json resources
- Vitest integration tests: layout.test.ts (30 tests), agent-bridge.test.ts (11 tests), agent-dispatcher.test.ts (18 tests) — total 104 vitest tests passing
- E2E test scaffold: v2/tests/e2e/README.md documenting WebDriver approach
- Terminal copy/paste: Ctrl+Shift+C copies selection, Ctrl+Shift+V pastes from clipboard to PTY (TerminalPane.svelte) - Terminal copy/paste: Ctrl+Shift+C copies selection, Ctrl+Shift+V pastes from clipboard to PTY (TerminalPane.svelte)
- Terminal theme hot-swap: onThemeChange() callback registry in theme.svelte.ts, open terminals update immediately when flavor changes - Terminal theme hot-swap: onThemeChange() callback registry in theme.svelte.ts, open terminals update immediately when flavor changes
- Agent tree node click: clicking a tree node scrolls to the corresponding message in the agent pane (scrollIntoView smooth) - Agent tree node click: clicking a tree node scrolls to the corresponding message in the agent pane (scrollIntoView smooth)
@ -21,6 +26,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- tempfile dev dependency for Rust test isolation - tempfile dev dependency for Rust test isolation
### Changed ### Changed
- Sidecar manager refactored from Node.js-only to Deno-first with Node.js fallback (SidecarCommand abstraction)
- Session struct: added group_name field with serde default
- SessionDb: added update_group method, list/save queries updated for group_name column
- SessionList sidebar: uses Svelte 5 snippets for grouped pane rendering with collapsible headers
- Agent tree NODE_H increased from 32 to 40 to accommodate subtree cost display - Agent tree NODE_H increased from 32 to 40 to accommodate subtree cost display
- release.yml build step now passes TAURI_SIGNING_PRIVATE_KEY and PASSWORD env vars from secrets - release.yml build step now passes TAURI_SIGNING_PRIVATE_KEY and PASSWORD env vars from secrets
- release.yml uploads latest.json alongside .deb and .AppImage artifacts - release.yml uploads latest.json alongside .deb and .AppImage artifacts

View file

@ -27,11 +27,11 @@ Terminal emulator with SSH and Claude Code session management. v1 (GTK3+VTE Pyth
| `docs/progress.md` | Session progress log | | `docs/progress.md` | Session progress log |
| `v2/src-tauri/src/pty.rs` | PTY backend (portable-pty, PtyManager) | | `v2/src-tauri/src/pty.rs` | PTY backend (portable-pty, PtyManager) |
| `v2/src-tauri/src/lib.rs` | Tauri commands (pty + agent + session + file + settings) | | `v2/src-tauri/src/lib.rs` | Tauri commands (pty + agent + session + file + settings) |
| `v2/src-tauri/src/sidecar.rs` | SidecarManager (Node.js lifecycle, NDJSON) | | `v2/src-tauri/src/sidecar.rs` | SidecarManager (Deno-first + Node.js fallback, SidecarCommand, NDJSON) |
| `v2/src-tauri/src/session.rs` | SessionDb (rusqlite, sessions + layout + settings + ssh_sessions) | | `v2/src-tauri/src/session.rs` | SessionDb (rusqlite, sessions + layout + settings + ssh_sessions) |
| `v2/src-tauri/src/watcher.rs` | FileWatcherManager (notify crate, file change events) | | `v2/src-tauri/src/watcher.rs` | FileWatcherManager (notify crate, file change events) |
| `v2/src-tauri/src/ctx.rs` | CtxDb (read-only access to ~/.claude-context/context.db) | | `v2/src-tauri/src/ctx.rs` | CtxDb (read-only access to ~/.claude-context/context.db) |
| `v2/src/lib/stores/layout.svelte.ts` | Layout store (panes, presets, persistence, Svelte 5 runes) | | `v2/src/lib/stores/layout.svelte.ts` | Layout store (panes, presets, groups, persistence, Svelte 5 runes) |
| `v2/src/lib/stores/agents.svelte.ts` | Agent session store (messages, cost) | | `v2/src/lib/stores/agents.svelte.ts` | Agent session store (messages, cost) |
| `v2/src/lib/components/Terminal/TerminalPane.svelte` | xterm.js terminal pane | | `v2/src/lib/components/Terminal/TerminalPane.svelte` | xterm.js terminal pane |
| `v2/src/lib/components/Agent/AgentPane.svelte` | Agent session pane (prompt, messages, cost) | | `v2/src/lib/components/Agent/AgentPane.svelte` | Agent session pane (prompt, messages, cost) |
@ -57,12 +57,15 @@ Terminal emulator with SSH and Claude Code session management. v1 (GTK3+VTE Pyth
| `v2/src/lib/components/StatusBar/StatusBar.svelte` | Global status bar (pane counts, cost) | | `v2/src/lib/components/StatusBar/StatusBar.svelte` | Global status bar (pane counts, cost) |
| `v2/src/lib/components/Notifications/ToastContainer.svelte` | Toast notification display | | `v2/src/lib/components/Notifications/ToastContainer.svelte` | Toast notification display |
| `v2/src/lib/components/Settings/SettingsDialog.svelte` | Settings modal (shell, cwd, max panes, theme) | | `v2/src/lib/components/Settings/SettingsDialog.svelte` | Settings modal (shell, cwd, max panes, theme) |
| `v2/src/lib/adapters/session-bridge.ts` | Session/layout persistence IPC wrapper | | `v2/src/lib/adapters/session-bridge.ts` | Session/layout/group persistence IPC wrapper |
| `v2/src/lib/components/Markdown/MarkdownPane.svelte` | Markdown file viewer (marked.js + shiki, live reload) | | `v2/src/lib/components/Markdown/MarkdownPane.svelte` | Markdown file viewer (marked.js + shiki, live reload) |
| `v2/sidecar/agent-runner.ts` | Node.js sidecar (spawns claude CLI) | | `v2/sidecar/agent-runner.ts` | Node.js sidecar (spawns claude CLI) |
| `v2/sidecar/agent-runner-deno.ts` | Deno sidecar proof-of-concept (experimental) | | `v2/sidecar/agent-runner-deno.ts` | Deno sidecar (preferred when deno available) |
| `v2/src/lib/adapters/sdk-messages.test.ts` | Vitest tests for SDK message adapter | | `v2/src/lib/adapters/sdk-messages.test.ts` | Vitest tests for SDK message adapter (25 tests) |
| `v2/src/lib/utils/agent-tree.test.ts` | Vitest tests for agent tree builder | | `v2/src/lib/adapters/agent-bridge.test.ts` | Vitest tests for agent IPC bridge (11 tests) |
| `v2/src/lib/agent-dispatcher.test.ts` | Vitest tests for agent dispatcher (18 tests) |
| `v2/src/lib/stores/layout.test.ts` | Vitest tests for layout store (30 tests) |
| `v2/src/lib/utils/agent-tree.test.ts` | Vitest tests for agent tree builder (20 tests) |
## v1 Stack ## v1 Stack
@ -76,7 +79,7 @@ Terminal emulator with SSH and Claude Code session management. v1 (GTK3+VTE Pyth
- Tauri 2.x (Rust backend) + Svelte 5 (frontend) - Tauri 2.x (Rust backend) + Svelte 5 (frontend)
- xterm.js with Canvas addon (no WebGL on WebKit2GTK) - xterm.js with Canvas addon (no WebGL on WebKit2GTK)
- Agent sessions via `claude` CLI subprocess with `--output-format stream-json` - Agent sessions via `claude` CLI subprocess with `--output-format stream-json`
- Node.js sidecar manages claude processes (stdio NDJSON to Rust) - Sidecar manages claude processes (Deno-first + Node.js fallback, stdio NDJSON to Rust)
- portable-pty for terminal management - portable-pty for terminal management
- SQLite session persistence (rusqlite, WAL mode) + layout restore on startup - SQLite session persistence (rusqlite, WAL mode) + layout restore on startup
- File watcher (notify crate) for live markdown viewer - File watcher (notify crate) for live markdown viewer

View file

@ -2,7 +2,7 @@
Terminal with session panel (MobaXterm-style), built with GTK 3 + VTE. Catppuccin Mocha theme. Terminal with session panel (MobaXterm-style), built with GTK 3 + VTE. Catppuccin Mocha theme.
> **v2 all phases complete + extras:** Multi-session Claude agent dashboard using Tauri 2.x + Svelte 5. Features: multi-pane terminal with PTY backend and copy/paste, agent panes with structured output, tree visualization with subtree cost, and session resume, SSH session management, ctx context database viewer, SQLite session persistence with layout restore, live markdown file viewer with Shiki syntax highlighting, global status bar with cost tracking, toast notifications, settings dialog with theme flavors (Catppuccin Latte/Frappe/Macchiato/Mocha) and live hot-swap, detached pane mode (pop-out windows), pane drag-resize handles, auto-updater plugin with CI signing support, CSS Grid tiling, .deb + AppImage packaging, GitHub Actions CI, vitest + cargo test suites. Branch `v2-mission-control`. See [docs/task_plan.md](docs/task_plan.md) for architecture and [docs/phases.md](docs/phases.md) for implementation plan. > **v2 all phases complete + extras:** Multi-session Claude agent dashboard using Tauri 2.x + Svelte 5. Features: multi-pane terminal with PTY backend and copy/paste, agent panes with structured output, tree visualization with subtree cost and session resume, session groups/folders with collapsible sidebar headers, SSH session management, ctx context database viewer, SQLite session persistence with layout restore, live markdown file viewer with Shiki syntax highlighting, global status bar with cost tracking, toast notifications, settings dialog with theme flavors (Catppuccin Latte/Frappe/Macchiato/Mocha) and live hot-swap, detached pane mode (pop-out windows), pane drag-resize handles, auto-updater plugin with signing key configured, Deno-first sidecar with Node.js fallback, CSS Grid tiling, .deb + AppImage packaging, GitHub Actions CI, 104 vitest + 29 cargo tests. Branch `v2-mission-control`. See [docs/task_plan.md](docs/task_plan.md) for architecture and [docs/phases.md](docs/phases.md) for implementation plan.
![BTerminal](screenshot.png) ![BTerminal](screenshot.png)

17
TODO.md
View file

@ -2,20 +2,21 @@
## Active ## Active
- [ ] **Auto-update signing key** -- Generate TAURI_SIGNING_PRIVATE_KEY, set as GitHub repo secret. CI workflow ready (latest.json + signing). - [ ] **Set TAURI_SIGNING_PRIVATE_KEY secret** -- Private key generated; must be added to GitHub repo settings for auto-update signing to work in CI.
- [ ] **Deno sidecar integration** -- Proof-of-concept done (agent-runner-deno.ts). Needs real claude CLI testing, benchmark vs Node.js, sidecar.rs integration. - [ ] **Deno sidecar real-world testing** -- Integrated into sidecar.rs (Deno-first + Node.js fallback). Needs testing with real claude CLI and startup time benchmark vs Node.js.
- [ ] **E2E testing (Playwright)** -- No e2e tests yet. Test: open terminal, run command, open agent, verify output. - [ ] **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.
- [ ] **Session groups/folders** -- Organize sessions in sidebar by folder (deferred from Phase 4). - [ ] **Multi-machine support** -- Remote agents via WebSocket (Phase 7+ feature).
- [ ] **Agent Teams integration** -- Experimental Anthropic feature. Each teammate gets its own pane (Phase 7+ feature).
## Completed ## Completed
- [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] **Auto-update signing key** -- Generated minisign keypair, pubkey set in tauri.conf.json. | 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** -- 104 vitest tests (layout 30, agent-bridge 11, agent-dispatcher 18, sdk-messages 25, agent-tree 20) + 29 cargo tests. | Done: 2026-03-06
- [x] **Copy/paste (Ctrl+Shift+C/V)** -- TerminalPane attachCustomKeyEventHandler, C copies selection, V writes clipboard to PTY. | Done: 2026-03-06 - [x] **Copy/paste (Ctrl+Shift+C/V)** -- TerminalPane attachCustomKeyEventHandler, C copies selection, V writes clipboard to PTY. | Done: 2026-03-06
- [x] **Terminal theme hot-swap** -- onThemeChange callback registry in theme.svelte.ts, TerminalPane subscribes. All open terminals update. | Done: 2026-03-06 - [x] **Terminal theme hot-swap** -- onThemeChange callback registry in theme.svelte.ts, TerminalPane subscribes. All open terminals update. | Done: 2026-03-06
- [x] **Tree node click -> scroll to message** -- handleTreeNodeClick in AgentPane, scrollIntoView smooth. | Done: 2026-03-06 - [x] **Tree node click -> scroll to message** -- handleTreeNodeClick in AgentPane, scrollIntoView smooth. | Done: 2026-03-06
- [x] **Subtree cost display** -- Yellow cost text below each tree node (subtreeCost util, NODE_H 32->40). | Done: 2026-03-06 - [x] **Subtree cost display** -- Yellow cost text below each tree node (subtreeCost util, NODE_H 32->40). | Done: 2026-03-06
- [x] **Session resume** -- Follow-up prompt in AgentPane, resume_session_id passed to SDK. | Done: 2026-03-06 - [x] **Session resume** -- Follow-up prompt in AgentPane, resume_session_id passed to SDK. | Done: 2026-03-06
- [x] **Pane drag-resize handles** -- Splitter overlays in TilingGrid with mouse drag, 10-90% clamping. | Done: 2026-03-06 - [x] **Pane drag-resize handles** -- Splitter overlays in TilingGrid with mouse drag, 10-90% clamping. | Done: 2026-03-06
- [x] **Vitest + cargo tests** -- sdk-messages.test.ts, agent-tree.test.ts, session.rs tests, ctx.rs tests. | Done: 2026-03-06
- [x] **Auto-update CI workflow** -- latest.json generation, signing env vars, artifact upload. | Done: 2026-03-06
- [x] **Deno sidecar PoC** -- agent-runner-deno.ts proof-of-concept with same NDJSON protocol. | Done: 2026-03-06
- [x] **Phase 6: Packaging + Distribution** -- install-v2.sh, bundle config, GitHub Actions release. | Done: 2026-03-06

View file

@ -20,7 +20,7 @@ bterminal-v2/
src/ src/
main.rs # Tauri app entry main.rs # Tauri app entry
pty.rs # PTY management (portable-pty, not plugin) pty.rs # PTY management (portable-pty, not plugin)
sidecar.rs # Node.js sidecar lifecycle (spawn, restart, health) sidecar.rs # Sidecar lifecycle (Deno-first + Node.js fallback, SidecarCommand)
watcher.rs # File watcher for markdown viewer watcher.rs # File watcher for markdown viewer
session.rs # Session + SSH session persistence (SQLite via rusqlite) session.rs # Session + SSH session persistence (SQLite via rusqlite)
ctx.rs # Read-only ctx context DB access ctx.rs # Read-only ctx context DB access
@ -75,6 +75,7 @@ bterminal-v2/
app.css app.css
sidecar/ sidecar/
agent-runner.ts # Node.js sidecar entry point agent-runner.ts # Node.js sidecar entry point
agent-runner-deno.ts # Deno sidecar (preferred when deno available)
package.json # Agent SDK dependency package.json # Agent SDK dependency
esbuild.config.ts # Bundle to single file esbuild.config.ts # Bundle to single file
package.json package.json
@ -168,7 +169,7 @@ bterminal-v2/
- [x] SQLite persistence for sessions (rusqlite with bundled feature) - [x] SQLite persistence for sessions (rusqlite with bundled feature)
- [x] Session types: terminal, agent, markdown (SSH via terminal args) - [x] Session types: terminal, agent, markdown (SSH via terminal args)
- [x] Session CRUD: save, delete, update_title, touch (last_used_at) - [x] Session CRUD: save, delete, update_title, touch (last_used_at)
- [ ] Session groups/folders (deferred — not needed for MVP) - [x] Session groups/folders — group_name column, setPaneGroup, grouped sidebar with collapsible headers
- [x] Remember last layout on restart (preset + pane_ids in layout_state table) - [x] Remember last layout on restart (preset + pane_ids in layout_state table)
- [x] Auto-restore panes on app startup (restoreFromDb in layout store) - [x] Auto-restore panes on app startup (restoreFromDb in layout store)
@ -226,7 +227,8 @@ bterminal-v2/
- [x] Auto-updater plugin integrated (tauri-plugin-updater Rust + @tauri-apps/plugin-updater npm + updater.ts) - [x] Auto-updater plugin integrated (tauri-plugin-updater Rust + @tauri-apps/plugin-updater npm + updater.ts)
- [x] Auto-update latest.json generation in CI (version, platform URL, signature from .sig file) - [x] Auto-update latest.json generation in CI (version, platform URL, signature from .sig file)
- [x] release.yml: TAURI_SIGNING_PRIVATE_KEY env vars passed to build step - [x] release.yml: TAURI_SIGNING_PRIVATE_KEY env vars passed to build step
- [ ] Auto-update signing key generation + TAURI_SIGNING_PRIVATE_KEY secret in GitHub repo - [x] Auto-update signing key generated, pubkey set in tauri.conf.json
- [ ] TAURI_SIGNING_PRIVATE_KEY secret must be set in GitHub repo settings
### System Requirements ### System Requirements
- Node.js 20+ (for Agent SDK sidecar) - Node.js 20+ (for Agent SDK sidecar)

View file

@ -178,8 +178,42 @@ Architecture decision: Uses `claude` CLI with `--output-format stream-json` inst
- [x] session.rs tests: SessionDb CRUD (sessions, SSH sessions, settings, layout), uses tempfile::tempdir() - [x] session.rs tests: SessionDb CRUD (sessions, SSH sessions, settings, layout), uses tempfile::tempdir()
- [x] ctx.rs tests: CtxDb error handling with missing database (conn=None) - [x] ctx.rs tests: CtxDb error handling with missing database (conn=None)
### Session: 2026-03-06 (continued) — Session Groups, Auto-Update Key, Deno Sidecar, Tests
#### Auto-Update Signing Key
- [x] Generated Tauri signing keypair (minisign)
- [x] Set pubkey in tauri.conf.json updater.pubkey field (base64 encoded)
- [x] Private key to be stored as TAURI_SIGNING_PRIVATE_KEY GitHub secret by user
#### Session Groups/Folders
- [x] Added group_name column to sessions table (session.rs, ALTER TABLE migration with pragma_table_info check)
- [x] Session struct: added group_name field with #[serde(default)]
- [x] SessionDb: update_group(id, group_name) method + save/list queries updated
- [x] Tauri command: session_update_group registered in lib.rs
- [x] Frontend: updateSessionGroup() in session-bridge.ts
- [x] Layout store: Pane.group? field, setPaneGroup(id, group) function in layout.svelte.ts
- [x] SessionList.svelte: grouped sidebar with collapsible headers (arrow + count), right-click to set group via prompt()
- [x] Svelte 5 snippet pattern used for paneItem to avoid duplication across grouped/ungrouped rendering
#### Deno Sidecar Integration (upgraded from PoC)
- [x] SidecarCommand struct in sidecar.rs: { program, args } abstracts runtime choice
- [x] resolve_sidecar_command(): Deno-first resolution (checks agent-runner-deno.ts + deno availability), Node.js fallback
- [x] Both sidecar runners bundled in tauri.conf.json resources array
- [x] Graceful fallback: if Deno binary not found in PATH, falls back to Node.js with log warning
#### E2E/Integration Tests
- [x] layout.test.ts (30 tests): addPane, removePane, focusPane, setPreset, autoPreset, getGridTemplate, getPaneGridArea, renamePaneTitle, setPaneGroup
- [x] agent-bridge.test.ts (11 tests): Tauri IPC mock pattern with vi.hoisted(), invoke/listen wrappers
- [x] agent-dispatcher.test.ts (18 tests): sidecar event routing, crash detection, vi.useFakeTimers() for async setTimeout
- [x] sdk-messages.test.ts rewrite (25 tests): removed unused ErrorContent import
- [x] E2E scaffold: v2/tests/e2e/README.md documenting WebDriver approach
- [x] Total: 104 vitest tests + 29 cargo tests, all passing
Build status: TypeScript 0 errors, Rust 0 errors (1 pre-existing warning), all tests green.
### Next Steps ### Next Steps
- [ ] Auto-update signing key generation + TAURI_SIGNING_PRIVATE_KEY secret in GitHub repo - [ ] Set TAURI_SIGNING_PRIVATE_KEY secret in GitHub repo settings
- [ ] Deno sidecar: test with real claude CLI, benchmark vs Node.js, integrate with sidecar.rs - [ ] Deno sidecar: test with real claude CLI, benchmark startup time vs Node.js
- [ ] E2E testing with Playwright - [ ] E2E testing with Playwright/WebDriver (when display server available)
- [ ] Session groups/folders in sidebar - [ ] Multi-machine support (remote agents via WebSocket)
- [ ] Agent Teams integration

View file

@ -136,10 +136,13 @@ See [phases.md](phases.md) for the full phased implementation plan (Phases 1-6).
| Vitest for frontend tests | Vitest over Jest — zero-config with Vite, same transform pipeline, faster. Test config in vite.config.ts. | 2026-03-06 | | Vitest for frontend tests | Vitest over Jest — zero-config with Vite, same transform pipeline, faster. Test config in vite.config.ts. | 2026-03-06 |
| Deno sidecar evaluation | Proof-of-concept agent-runner-deno.ts created. Deno compiles to single binary (better packaging). Same NDJSON protocol. Not yet integrated. | 2026-03-06 | | Deno sidecar evaluation | Proof-of-concept agent-runner-deno.ts created. Deno compiles to single binary (better packaging). Same NDJSON protocol. Not yet integrated. | 2026-03-06 |
| Splitter overlays for pane resize | Fixed-position divs outside CSS Grid (avoids layout interference). Mouse drag updates customColumns/customRows state. Resets on preset change. | 2026-03-06 | | Splitter overlays for pane resize | Fixed-position divs outside CSS Grid (avoids layout interference). Mouse drag updates customColumns/customRows state. Resets on preset change. | 2026-03-06 |
| Deno-first sidecar with Node.js fallback | SidecarCommand struct abstracts runtime. resolve_sidecar_command() checks Deno first (runs TS directly, no build step), falls back to Node.js. Both bundled in tauri.conf.json resources. | 2026-03-06 |
| Session groups/folders | group_name column in sessions table with ALTER TABLE migration. Pane.group field in layout store. Collapsible group headers in sidebar. Right-click to set group. | 2026-03-06 |
| Auto-update signing key | Generated minisign keypair. Pubkey set in tauri.conf.json. Private key for TAURI_SIGNING_PRIVATE_KEY GitHub secret. | 2026-03-06 |
## Open Questions ## Open Questions
1. **Node.js or Deno for sidecar?** Node.js has the SDK package. Deno would be a single binary (better packaging) but needs SDK compatibility testing. → Start Node.js, evaluate Deno later. 1. **Node.js or Deno for sidecar?** Resolved: Deno-first with Node.js fallback. SidecarCommand struct in sidecar.rs abstracts the choice. Deno preferred (runs TS directly, compiles to single binary). Falls back to Node.js if Deno not in PATH.
2. **Multi-machine support?** Remote agents via WebSocket. Phase 7+ feature. 2. **Multi-machine support?** Remote agents via WebSocket. Phase 7+ feature.
3. **Agent Teams integration?** Experimental Anthropic feature. Natural fit but adds complexity. Phase 7+. 3. **Agent Teams integration?** Experimental Anthropic feature. Natural fit but adds complexity. Phase 7+.
4. **Electron escape hatch threshold?** If Canvas xterm.js proves >50ms latency on target system with 4 panes, switch to Electron. Benchmark in Phase 2. 4. **Electron escape hatch threshold?** If Canvas xterm.js proves >50ms latency on target system with 4 panes, switch to Electron. Benchmark in Phase 2.