You have an idea – a bird house camera, a podcast, a home server. Getting from "I'd like to…" to "it works" usually means juggling chats, notes, half-finished plans and forgotten next steps.
I built Vibewright to take that part off my plate: a free, open-source desktop app for Windows and macOS. You type one sentence, it plans the project with you, and then Claude Code builds it step by step – right inside the app.
The flow
Idea ──► Interview ──► Needs analysis ──► Plan ──► Tool check ──► Build
(clicks) approve approve approve Claude Code in the app
- Interview – one multiple-choice question per screen, with your own answer always possible. Two short rounds, follow-ups only where something is missing.
- Needs analysis – goal, scope, must-haves, non-goals, risks and a feasibility traffic light.
- Plan – 3–6 phases, each with a "done when" criterion and concrete steps in plain language.
- Tool check – which tools, plugins or MCP servers each phase actually needs. Nothing gets installed without your OK.
- Build – Claude Code runs in an embedded terminal, knows the current phase and ticks off finished steps.
You approve every gate. Claude does the heavy lifting.
Below are the technical decisions that made this work – and a few things I learned along the way.
1. Planning calls: headless, tool-less and cheap
Every planning step is a single headless call to the Claude Code CLI:
claude -p --output-format json --model <haiku|sonnet|opus> \
--system-prompt "<short system prompt>" \
--tools "" \
--setting-sources project --strict-mcp-config \
--json-schema '<schema>' \
[--resume <session-id>]
A few details that matter:
-
--tools ""– planning doesn't need file access, so Claude gets no tools at all. No permission prompts, nothing touches the disk. -
--setting-sources project --strict-mcp-config– the user's global hooks, skills and MCP servers are ignored, so their setup can't change or bloat the planning calls. - Short system prompt + no tools – a call costs about 1,000 input tokens instead of 15,000–20,000. That keeps a Pro/Max subscription's limits for the actual building.
-
--json-schema– every step returns structured output (questions, analysis, plan, tool needs), so the UI never has to parse free text. -
--resume– all steps of a project share one session, so Claude remembers the interview when it writes the plan.
One trap: --bare would be even leaner, but it doesn't work with a subscription login – it requires an API key.
2. A state machine that is safe to retry
Each project keeps its state in a JSON file. The important rule: state only changes after a successful Claude call. If a call fails or times out, "Try again" simply repeats it – there's no half-written step to clean up.
null → questions → (round 2) → needs analysis gate → plan gate → tool check → done
3. Plain Markdown is the source of truth
Plans, phases and checklists are written as Markdown files – into an Obsidian vault (with Dataview tables and a Kanban board if those plugins are installed) or into a normal folder with an HTML dashboard.
Progress is never stored separately. The app parses the ## Checklist section of each task file and derives everything else from it: phase status, progress percentage, next step, dashboard.
That has a nice side effect: ticking a box works everywhere. In the app, in Obsidian, or by Claude Code editing the file – an fs.watch on the task folder picks it up and the UI updates live.
4. The real Claude Code, embedded
I didn't want to re-implement an agent. The build phase runs the actual interactive Claude Code inside the app, using xterm.js and node-pty:
- Before starting, Vibewright writes a marked block into the project's
CLAUDE.md(<!-- projekthelper:start --> … <!-- projekthelper:ende -->) with the current phase, its goal and the next step. Anything the user wrote inCLAUDE.mdstays untouched. - Claude ticks off steps in the task files – and the watcher from section 3 does the rest.
- New ideas can be typed in at any time. Claude sorts them into the right phase; if Claude is busy, the idea waits until the current step is done.
- Several projects can run their own Claude Code session at the same time.
Two gotchas from this part:
-
Nested sessions: if the app is started from inside another Claude Code session, inherited
CLAUDECODE/CLAUDE_CODE_*environment variables change Claude's behaviour. The app strips them before spawning. -
Windows and
.cmdshims: an npm install of Claude Code puts aclaude.cmdon the PATH. Windows can't start.cmdfiles without a shell – and going through a shell mangles JSON-schema arguments. Vibewright prefersclaude.exe(native installer) and otherwise reads the shim to run its target directly.
5. Claude never runs commands on your PC during planning
For the tool check, Claude receives an inventory (OS version, installed plugins, skills, MCP servers) and returns what each phase needs. For system tools it only names the executable and typical install paths – the app checks them itself. Planning stays read-only.
Stack
- Electron with plain HTML/CSS/JS – no framework, no bundler
- Claude Code CLI (headless for planning, interactive for building)
-
xterm.js+@lydell/node-pty(prebuilt binaries, no build tools needed on Windows) - Three runtime dependencies plus Electron
Try it
- Website & demo: https://neodk2004.github.io/vibewright/
- Source (MIT): https://github.com/neodk2004/vibewright
- Requirements: Windows 10/11 or macOS 11+, Claude Code installed and signed in, a Claude subscription (Pro or Max recommended). Obsidian and Git are optional.
The Mac build is signed and notarized. The Windows installer isn't code-signed yet, so SmartScreen may warn you – every release is scanned on VirusTotal and ships with SHA-256 checksums.
Feedback, bug reports and ideas are very welcome – either here in the comments or as a GitHub issue.

Top comments (2)
Stripping
CLAUDECODEand pairing--tools ""with--strict-mcp-configis a clean way to keep planning calls down near 1,000 tokens. Two failure modes usually show up once the interactive session starts editing those shared Markdown task files. Editors like Obsidian and many CLI tools save atomically by writing a temp file and renaming over the target, so watching only the file path drops events after the first rename while watching the parent directory catches the replacement. Letting the coding session tick off its own## Checklistboxes also turns the agent into its own grader unless a test exit code or file check backs each step.Thanks, good points!
On the first one: Vibewright already watches the parent Tasks/ folder rather than the individual files (with a short debounce), so atomic saves from Obsidian that rename over the target come through fine.
The second one was fair, and I just shipped a change for it. The session is now told to tick a box only after it has checked the step: for code, run the tests or the program; otherwise, confirm the file or result actually exists. It also has to tell the user what the proof was, and if the check fails, the box stays open. The app itself doesn't verify this yet, so it's still the agent checking its own work, but with a stated proof the user can see. Since most of my users aren't developers, many of their projects have nothing a machine could check anyway. That's why the user stays the final judge rather than an exit code. Appreciate the input!