VividKit Desktop is a GUI companion that makes Claude Code CLI + CCS accessible to everyone — developers who avoid the terminal and non-developers alike.
Core mechanic: Rust backend spawns a PTY process running ccs [profile] [args], streamed to the user via xterm.js. The UI abstracts away CLI complexity behind visual workflows.
MVP scope: 5 modules — Onboarding, Project Deck, Brainstorm, Tasks, Cook + Worktree. Target: single-user, local-first. No cloud sync. API keys stay on device.
External CLI dependencies (must be installed by user):
- CCS CLI —
npm install -g @kaitranntt/ccs - Claude Code CLI
Frontend: React 18, TypeScript, Tailwind v4, shadcn/ui, Zustand
Desktop: Tauri v2, Rust
Libraries: xterm.js, Monaco Editor, dnd-kit, react-markdown, git2, rusqlite, tokio
All UI rules (tokens, typography, spacing, components, status mapping, terminal, theme, checklist) are centralized in:
docs/design-system.md
When implementing/reviewing UI in src/components/**, src/pages/**, src/App.css:
- Always read and follow
docs/design-system.md - Do not duplicate or override UI rules in
CLAUDE.md/AGENTS.md - If a guideline needs updates, edit
docs/design-system.mddirectly
REMINDER: VividKit targets macOS, Linux, AND Windows. Every file path, shell command, and env var must work on ALL three platforms. Never assume a single OS. Review every path operation for platform bias before committing.
Rust:
- Always use
std::path::PathBufand.join()— never concat paths with/or\ - Use
dirscrate for home/config dirs — never hardcode~/,/home/,C:\Users\ - Use
std::path::MAIN_SEPARATORorPathBufmethods when building display paths std::process::Command: avoid bash-only syntax (pipes|,&&,||) — use Rust logic instead- Platform-specific behavior: use
#[cfg(target_os = "windows")]/"macos"/"linux"guards - Use
std::env::var()for env paths — never hardcode platform-specific env vars - Line endings: use
\ninternally; let OS handle display. Never hardcode\r\n - Executable extensions: use
which/dirscrate to locate binaries — never hardcode.exeor assume no extension
Frontend (React/TS):
- No platform detection in frontend — let Rust handle platform logic and return normalized data
- Path display only — actual path resolution always done in Rust via IPC
- Never construct file paths in TypeScript — always receive resolved paths from Rust
- NO hardcoded user-facing strings in JSX — all text via
t('key')fromreact-i18next - Locale files:
src/locales/{lang}/*.json(vi as default, en as secondary) - Date/time: store UTC internally, format at display layer via
Intl.DateTimeFormat - Numbers: use
Intl.NumberFormatfor locale-aware formatting - CSS: prefer logical props (
margin-inline-startovermargin-left) for RTL readiness - Error strings from Rust (returned as
String): map to i18n key on frontend before displaying
File size: Max 200 lines per file. Split into focused modules if exceeded.
No mocks: Never use fake data, mocked implementations, or simulated responses in any context.
AI via CCS — Rust PTY only: All AI sessions are spawned as ccs [profile] PTY processes in Rust (src-tauri/src/commands/ai.rs). Never call AI provider APIs directly from React/TypeScript or via fetch().
CCS profile selection: UI lets user pick profile (claude, gemini, glm, kimi, etc.) — Rust maps selection to ccs <profile> spawn args.
React pattern: Component → Custom Hook → Zustand action → invoke()
- State lives in Zustand stores (
src/stores/) - Tauri IPC wrapped in
src/lib/tauri.tshelper functions - Logic > 10 lines extracted into custom hooks (
src/hooks/)
xterm.js rules:
- Always call
terminal.dispose()on component unmount - Lazy mount: do not initialize terminal when tab is hidden
- Stream output via buffer — never inject large strings at once
Rust commands:
- Every
#[tauri::command]returnsResult<T, String>— no exceptions - Never use
.unwrap()in command files — usemap_err(|e| e.to_string()) - Use
tokiofor async I/O operations
Tauri IPC: invoke() argument names and types must exactly match #[tauri::command] parameter signatures.
| Module | Directory | Purpose |
|---|---|---|
| Layout | src/components/layout/ |
App shell, sidebar, header, theme provider |
| Dashboard | src/components/dashboard/ |
Stats cards, quick actions, overview |
| Onboarding | src/components/onboarding/ |
Welcome wizard, CCS profile setup, project creation |
| Decks | src/components/decks/ |
Deck cards, deck list, create deck dialog |
| New Project | src/components/new-project/ |
Project creation flow |
| Brainstorm | src/components/brainstorm/ |
Idea generation, AI-assisted ideation, report preview |
| Plans | src/components/plans/ |
Plan cards, plan list, phase checklist, markdown preview |
| Generate Plan | src/components/generate-plan/ |
AI plan generation, phase indicator |
| Tasks | src/components/tasks/ |
Kanban board, list view, task CRUD |
| Cook | src/components/cook/ |
Cook terminal, controls, progress, steps |
| Worktrees | src/components/worktrees/ |
Git worktree cards (active/ready/merged), merge dialog |
| CCS Stream | src/components/ccs-stream/ |
JSONL stream view, AI/user messages, tool calls, thinking |
| Settings | src/components/settings/ |
General, editor, git, AI commands, CCS account |
src/
components/{module}/ # UI components (functional, no class components)
stores/ # Zustand stores — one file per domain
hooks/ # Custom hooks — one hook per concern
lib/tauri.ts # invoke() wrappers with typed args/returns
types/ # Shared TypeScript interfaces
src-tauri/src/
commands/{module}.rs # #[tauri::command] functions
models/{entity}.rs # Serde structs for IPC and DB
lib.rs # Plugin registration, invoke_handler
Error pattern: fn foo(arg: String) -> Result<MyStruct, String>
Async pattern: async fn bar() -> Result<T, String> with tokio::spawn for blocking I/O
When working on this project, activate these skills:
tauri-v2-desktop— Tauri IPC, plugins, capabilities, Rust commandsrusqlite-sqlite— SQLite schema, queries, migrations in Rustreact-best-practices— React 18 patterns, performance, Suspensefrontend-development— React/TypeScript components, hooks, Zustandtailwind-v4-styling— Tailwind v4 utility classes, shadcn/ui components
- Architecture:
docs/system-architecture.md - Code standards:
docs/code-standards.md - Design system:
docs/design-system.md - Plans:
plans/— active implementation plans with phase files