Skip to content

vouchdev/vouch-desktop

Repository files navigation

vouch-desktop

A cross-platform Electron desktop app that puts a GUI on the entire vouch command surface — the review-gated, local-first decision-memory knowledge base.

image

vouch is an unmodified dependency: vouch-desktop spawns the vouch CLI's machine transports and never patches its Python source. It talks to vouch two ways, and never writes durable KB state except through vouch's own propose → approve review gate.

  • JSONL stdio (vouch serve --transport jsonl) — the workhorse. All 54 kb.* methods (read, search, list, propose, review, lifecycle, sessions, graph, maintenance, export/import, audit) flow over one newline-delimited JSON pipe.
  • HTTP + WebSocket (vouch review-ui --allow-dual-solve) — spawned lazily, only when you open the Dual-Solve view, for the one thing JSONL can't do: the long-running, sandboxed two-engine dual-solve runner with streamed progress.

What you get

  • One window over every command. A left-rail of ten task-shaped views plus a bespoke Dual-Solve runner. Data-entry methods get forms generated from a verified parameter catalog (typed controls, enum dropdowns, sliders, tag inputs, native file pickers, and search-backed id typeaheads) — so the UI stays in step with vouch instead of hand-coding 54 forms.
  • The gate, made visible. Propose anything; it lands in the review queue. Approve / reject from the Review view. Nothing is ever auto-approved.
  • Capability-aware. Methods the connected vouch doesn't advertise are shown disabled, and light up automatically when you upgrade vouch.
  • A companion, not just a window. Tray icon with a pending-count badge and KB switcher, native notifications (a dual-solve run is ready to judge; new proposals arrived; the process went down), and no terminal required — the app finds, launches, and supervises vouch for you.

A look around

The gate, made visible Forms from the catalog
Review & Lifecycle — the pending queue with approve/reject controls Browse — read methods rendered as generated forms
Propose anything and it lands in the review queue. Approve or reject it here — nothing is ever auto-approved. Every method gets a typed form generated from the verified parameter catalog, with id typeaheads and result cards.

The bespoke Dual-Solve runner is the one thing JSONL can't do — it drives vouch's sandboxed two-engine runner over HTTP, streams progress, then proposes the winning diff into the same review queue:

Dual-Solve — run claude and codex on one issue, compare diffs, pick a winner

Requirements

  • Node 18+ and npm to build/run from source (Node 20+ recommended).
  • vouch on your PATH (pipx install vouch), or set its path in the app.

Dual-Solve prerequisites

The Dual-Solve view is the only feature with extra setup. It drives two coding agents — the claude and codex CLIs — over an issue, then proposes the winner's diff into the review queue. vouch-desktop has no API-key fields: it never calls the Anthropic or OpenAI APIs itself. Instead it runs the two CLIs, and each CLI brings its own credentials. You authenticate them once, the normal way, and dual-solve reuses that.

Before opening the Dual-Solve view, set up all of the following:

  1. The two engine CLIs, installed and authenticated.

    # Claude
    npm install -g @anthropic-ai/claude-code
    claude login                 # or: export ANTHROPIC_API_KEY=sk-ant-...
    
    # Codex
    npm install -g @openai/codex
    codex login                  # or: export OPENAI_API_KEY=sk-...

    Either auth method works for each engine — an interactive login (subscription / OAuth), or the matching API-key environment variable exported in the shell that launches vouch-desktop. If you launch the app from a desktop icon rather than a terminal, prefer login so the credential is persisted to disk where the sandbox can find it.

  2. vouch's [web] extra (the dual-solve server): pipx install 'vouch[web]'.

  3. git, gh, and docker on your PATH. Run gh auth login so vouch can fetch the issue, and start Docker.

  4. The sandbox image vouch/coder:latest pulled locally (docker pull vouch/coder:latest). By default dual-solve runs each engine in this container; it mounts a temporary copy of your claude / codex credential files (~/.claude*, ~/.codex/auth.json) and forwards ANTHROPIC_API_KEY / OPENAI_API_KEY if they're set — so the same login from step 1 works inside the sandbox without exposing your real config.

  5. The KB inside a git repository — dual-solve commits each candidate to a worktree, so the KB root must be a git working tree.

The other ten views (read, search, propose, review, sessions, graph, maintenance, export/import, audit) need none of this — only vouch itself.

Quick start

npm install
npm start

On first launch, Open existing… a folder containing a .vouch/ directory, or Initialize new… to create one. The app spawns and supervises the vouch process; you never touch a shell.

Tech stack

React 18 + TypeScript 5 renderer, built with electron-vite (three-target build: main → CJS, preload → CJS, renderer → React/ESM). Vitest 2 + @testing-library/react for unit tests. Typed IPC contract shared between main, preload, and renderer via src/shared/ipc.ts; typed parameter catalog in src/shared/methods.gen.ts (generated from src/catalog/methods.json).

Develop

npm run dev           # electron-vite dev — launches Electron with HMR
npm run build         # electron-vite build → out/main, out/preload, out/renderer
npm test              # vitest run — catalog, gen-methods, form, controls (85 tests)
npm run typecheck     # tsc -b --noEmit across main + preload + renderer
npm run gen:methods   # regenerate src/shared/methods.gen.ts from src/catalog/methods.json
npm run dist          # electron-vite build + electron-builder → dmg / nsis / AppImage

src/catalog/methods.json is the verified surface catalog (method names, parameters, types, enum sets) extracted from vouch's source. scripts/gen-methods.ts enriches it and writes src/shared/methods.gen.ts, which drives the form generator. Regenerate it when vouch's surface changes.

To ship a zero-Python install, freeze vouch with PyInstaller into resources/vouch/ (see scripts/freeze-vouch.sh); the locator prefers it.

Architecture

 renderer (sandboxed, no node)
   │  window.vouch.call(method, params)   ← one frozen preload bridge
   ▼  IPC
 main process
   ├─ JsonlClient   → vouch serve --transport jsonl   (all 54 kb.* methods)
   ├─ HttpClient    → vouch review-ui --allow-dual-solve --dual-solve-sandbox
   ├─ Supervisor    → health poll, restart, shutdown
   ├─ Tray/Notifier → companion + OS notifications
   └─ KbStore       → recent KBs, prefs

See docs/architecture.md for the full design, including the method-by-method coverage table.

Status

v0.1.0 covers the entire kb.* surface plus dual-solve. The CLI-only orchestration commands (auto-pr, migrate, schema, sync-*) are not yet surfaced — see the CHANGELOG.

License

MIT.