| Library | Version | Why chosen |
|---|---|---|
| React | 19.x | Concurrent features, mature ecosystem |
| TypeScript | ~5.8 | Required for maintainability at this scale |
| Vite | 6.x | Fast HMR, native ESM, Tauri integration |
| Tailwind v4 | 4.x | CSS-first config (no JS file), CSS variables as design tokens |
| react-resizable-panels | ^2.1 | Handles IDE split layout with persistence |
| @xterm/xterm | ^5.5 | De-facto terminal emulator for web; handles ANSI natively |
| @xterm/addon-fit | ^0.10 | Auto-resize terminal to container |
| @xterm/addon-search | ^0.15 | Terminal text search |
| @xterm/addon-web-links | ^0.11 | Clickable URLs in terminal output |
| @monaco-editor/react | ^4.7 | Monaco editor for plan/readme/file editing tabs |
| Zustand | 5.x | Minimal boilerplate, works outside React components |
| TanStack Query | 5.x | Async data fetching, caching, invalidation |
| @tanstack/react-virtual | ^3.13 | Virtualized lists for large data sets (git log, sessions) |
| cmdk | 1.x | Accessible command palette with fuzzy search |
| lucide-react | latest | Consistent icon set, tree-shakeable |
| react-markdown | ^10.1 | Render markdown content (README preview, context panel) |
| class-variance-authority | ^0.7 | Utility for composing variant-based class names |
| clsx + tailwind-merge | latest | Conditional class name merging |
| Crate | Version | Why chosen |
|---|---|---|
| tauri | 2.x | WebView2 + Rust backend; native Windows app without Electron overhead |
| portable-pty | 0.8.x | Windows ConPTY support; real PTY so Claude sees a real terminal |
| notify | 8.x | Cross-platform file watching; uses ReadDirectoryChangesW on Windows |
| git2 | 0.20.x | Rust-native libgit2 bindings; no git CLI required for basic ops |
| keyring | 3.x | Windows Credential Manager; OS-level secret storage |
| reqwest | 0.12.x | Async HTTP for GitHub/Linear/Jira API calls |
| open | 5.x | Opens URLs in default browser (OAuth verification URI) |
| serde + serde_json | 1.x | JSON serialization for all data models |
| tokio | 1.x | Async runtime (already pulled in by Tauri) |
| chrono | 0.4.x | Timestamp parsing; handles both ms-epoch and ISO8601 formats |
| uuid | 1.x | Session ID generation |
| anyhow | 1.x | Ergonomic error handling in Tauri commands |
| rfd | 0.14.x | Native file dialog (folder picker for project selection) |
| Plugin | Purpose |
|---|---|
| tauri-plugin-store | Persistent JSON settings (non-sensitive config only) |
| tauri-plugin-shell | Shell command execution (gh CLI for PRs/Issues, claude CLI for init/readme) |
| tauri-plugin-fs | File system access from frontend |
| tauri-plugin-opener | Opens files/URLs in OS default handler |
Tauri uses the OS WebView (WebView2 on Windows) and a Rust backend instead of bundling Chromium + Node.js. The result is a ~10MB binary vs ~200MB for Electron, lower RAM usage, and direct access to native Windows APIs without npm packages.
MSVC requires Visual Studio Build Tools (~5GB install). The GNU toolchain (via MSYS2 + MinGW) is ~500MB and scriptable. The stable-x86_64-pc-windows-gnu Rust target works without any Microsoft tooling.
Windows DLL exports are limited to 65,535 ordinals. A large Rust library with many symbols hits this limit. Removing cdylib from crate-type avoids the linker error "export ordinal too large". Tauri's build system works fine with staticlib + rlib.
std::process::Command with Stdio::piped() creates non-TTY stdin/stdout. Claude Code CLI detects this (via isatty()) and switches to --print mode, which requires a prompt argument and exits immediately. portable-pty creates a real Windows ConPTY so Claude sees an interactive terminal.
React 18 Strict Mode double-invokes effects in development to surface bugs. For this app, effects spawn real OS processes (PTY sessions) and register OS-level event listeners. Double-invocation creates two Claude processes writing to the same xterm.js terminal. StrictMode is disabled in src/main.tsx.
UI state (which panel is open, which tab is active) changes synchronously and never needs to be fetched from a backend -- Zustand (7 stores). Data that comes from the Rust backend (sessions list, git status, inbox) is async, can fail, and benefits from caching and invalidation -- TanStack Query. Mixing both into one store creates unnecessary complexity.
The GitHub REST/GraphQL API for PRs and Issues is complex and requires token scopes, pagination handling, and type-safe response parsing. The gh CLI handles all of this and is already installed as a dependency for the GitHub auth flow. std::process::Command::new("gh").args([...]) is a simpler integration surface.
Tailwind v4 moves configuration from tailwind.config.js to a CSS file with @theme directives. This means design tokens (colors, spacing) are emitted as CSS custom properties, which can be referenced directly in inline styles and component logic without importing a JS config object.
Claude Code CLI sets CLAUDECODE=1 in its own process environment to detect nested invocations. When the IDE (which runs inside Claude Code) spawns a new claude process, it inherits this env var, and Claude refuses to start. Calling cmd.env_remove("CLAUDECODE") before spawning removes this marker.
API tokens and OAuth tokens are sensitive. Storing them in settings.json (a plain JSON file in %APPDATA%) exposes them to any process that can read the file. Windows Credential Manager (accessed via the keyring crate) uses DPAPI to encrypt credentials, tied to the user's Windows login. This is the same store used by Git Credential Manager and VS Code.
The @monaco-editor/react package provides the same editor used in VS Code. It's used for plan files, README editing, and arbitrary file editing tabs. This gives syntax highlighting, search/replace, and familiar keybindings without building a custom editor.
The rfd (Rusty File Dialogs) crate provides native OS file/folder picker dialogs. Used for the project folder selection flow (cmd_pick_folder). This gives a native Windows dialog rather than a web-based file picker.
The IDE uses a nested panel layout: a vertical PanelGroup splits top content from the bottom panel (full-width), and a horizontal PanelGroup inside the top section splits sidebar, main area, and right panel. This ensures the bottom panel spans the full window width.
Git log, session lists, and other potentially large data sets use virtualized rendering to maintain smooth performance regardless of list size.