Desktop project cockpit built with Electron, React, and TypeScript.
Manage local projects, run per-project AI terminal sessions (Codex/Claude/OpenCode), and keep a secure localhost live preview in one place.
ShipDeck is a desktop workspace for juggling multiple projects quickly:
- Track and switch projects from a single sidebar
- Launch server + shell terminals per project
- Open and resume Codex/Claude/OpenCode sessions
- Keep a secure embedded localhost preview synced to the active project/session
- Electron (main + preload + renderer split)
- React 19 + TypeScript
- Vite (renderer)
node-pty(terminal sessions)better-sqlite3(local metadata state)zod(IPC payload validation)
- Node.js 20+
- pnpm 9+
- Windows/macOS/Linux (scripts are currently Windows-friendly but not Windows-only)
pnpm install
pnpm devpnpm dev starts:
- Vite renderer dev server
tsupwatch for maintsupwatch for preload- Electron app process
| Command | Purpose |
|---|---|
pnpm dev |
Start full development environment |
pnpm build |
Build renderer + main + preload into dist/ |
pnpm typecheck |
Run TypeScript type checks |
pnpm lint |
Run ESLint |
pnpm test |
Run Vitest |
pnpm rebuild:native |
Rebuild native modules (better-sqlite3) |
pnpm rebuild:pty |
Rebuild node-pty |
src/
main/ Electron main process, IPC handlers, DB, PTY, webview manager
preload/ Secure bridge (`window.api`) exposed to renderer
renderer/ React UI (App + components + styles + utilities)
shared/ Shared IPC channels, schemas, and common types
tests/ Vitest tests for core logic
- Main process owns:
- SQLite repository (
src/main/db) - PTY lifecycle/streaming (
src/main/pty/manager.ts) - Webview bounds, visibility, and target loading (
src/main/webview/manager.ts)
- SQLite repository (
- Renderer owns:
- Project/session UI state and interactions
- Terminal tab selection and modal flows
- All main-process access via
window.apionly
- Validate IPC payloads in main process with Zod before side effects.
- Do not access Node APIs directly in renderer; always use preload bridge.
- Session title changes are user-driven via rename flow.
- On first load, ShipDeck auto-opens the first project’s first session (when available).
- Add channel in
src/shared/ipc.ts - Add schema in
src/shared/schemas.ts(if needed) - Implement handler in
src/main/index.ts - Expose function in
src/preload/index.ts - Add typing in
src/renderer/global.d.ts
- Terminal not starting:
- Verify shell availability
- Run
pnpm rebuild:pty
- Electron launch issues after dependency changes:
- Run
pnpm rebuild:nativeand retry
- Run
- No localhost preview:
- Confirm project dev command starts and binds a local port
Ignored artifacts include:
node_modules/,dist/,.vite/,.pnpm-store/- logs and coverage output
- local trace/heap captures (
Trace-*.json,Heap-*.heaptimeline)
Before pushing:
pnpm typecheck && pnpm lint && pnpm test && pnpm build