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.
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 54kb.*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.
- 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.
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:
- 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.
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:
-
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, preferloginso the credential is persisted to disk where the sandbox can find it. -
vouch's
[web]extra (the dual-solve server):pipx install 'vouch[web]'. -
git,gh, anddockeron yourPATH. Rungh auth loginso vouch can fetch the issue, and start Docker. -
The sandbox image
vouch/coder:latestpulled locally (docker pull vouch/coder:latest). By default dual-solve runs each engine in this container; it mounts a temporary copy of yourclaude/codexcredential files (~/.claude*,~/.codex/auth.json) and forwardsANTHROPIC_API_KEY/OPENAI_API_KEYif they're set — so the same login from step 1 works inside the sandbox without exposing your real config. -
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.
npm install
npm startOn 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.
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).
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 / AppImagesrc/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.
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.
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.
MIT.


