Idea Builder VSCode Extension
Idea Builder turns VSCode into a control panel for building software with
Claude Code. Its one-click buttons launch, isolate, and resume Claude Code
sessions right inside the editor — and it runs an issue board that spawns a
Claude Code session for every issue you move to todo. It works fully
offline by default, and can optionally sync the board with Linear.
Licensing
Idea Builder is a paid extension. On a fresh install it is locked — the
sidebar shows an Enter License Key button and a $(lock) Activate Idea Builder item in the status bar. Paste the license key from your Dodo
Payments purchase email (Command Palette → Idea Builder: Enter License Key,
or click the status-bar item) to unlock it.
- Activation binds the key to this machine. The proof is cached encrypted in
VS Code SecretStorage and re-checked with Dodo at most once a week, with a long
offline grace window — so once activated you can work offline.
- Manage or move a license with Idea Builder: Manage License (replace the key,
or remove it from this machine to free an activation for another device).
- Dodo's activate/validate endpoints are public, so no secret/API key ships in
the extension — only the public Dodo API base URL.
The shipped bundle is obfuscated as a deterrent, but it is JavaScript on disk
and therefore not tamper-proof. The license gate is designed to stop casual
copying and cross-machine key-sharing, not to be unbreakable DRM.
Develop with Claude Code — one click
The heart of the extension is a set of launcher buttons that drive the Claude
Code CLI for you, no terminal commands to memorize. They live in the Idea
Builder view in the activity bar, with a terminal toggle pinned to the status
bar:
| Button |
What it does |
| Claude |
Open a Claude Code session as an editor tab — it sits next to your files and can be split and dragged like any editor. |
| Claude (Worktree) |
Prompt for a name, then open Claude Code in a fresh, isolated git worktree. |
| Claude (Resume) |
Reopen a previous Claude Code session and pick up where you left off. |
| Terminal |
Open a plain terminal as an editor tab. |
| Terminal (status bar) |
Toggle the integrated terminal panel from the bottom bar. |
Because every session opens as an editor tab, you can run several Claude Code
agents side by side — one per worktree — and arrange them like panes.
The issue board
Idea Builder shows an issue board in the sidebar and can launch a Claude session
per issue automatically. It runs in one of two modes, chosen per-workspace:
- Local (default, offline): issues live in a plain JSON file in the
workspace,
.idea-builder/issues.json. No account, no network. The Claude agent
reads and writes this same file directly (the generated CLAUDE.md documents
the format), so the board, you, and the agent all share one source of truth.
- Linear (optional): issues live in Linear, in a Team/Project you pick.
The board mirrors Linear, and agents manage issues through Linear's own MCP
server. Linear is authoritative; the local file becomes a read-only cache.
When Start Polling is on, any issue assigned to agent that enters the
todo state launches a Claude Code session in an isolated worktree. When the
agent finishes, it moves the issue to in review for a human to mark done
(which closes the session).
Getting started (offline)
- Open a project folder in VSCode.
- Initialize → the extension writes a
.project_idea marker and opens
Claude, which first asks you about your idea, then scaffolds the project
(framework, CLAUDE.md, README, and the initial issues).
- Start Polling → issues moved to todo spin up Claude sessions.
Each workspace is one idea — there is no cross-project idea list. The
.project_idea marker is the idea's only home, holding its id and details:
{ "ideaId": "<idea id>", "title": "<name>", "description": "<one-liner>" }
Syncing with Linear
- Connect Linear → a browser tab opens for OAuth consent (Authorization
Code + PKCE). Approve, then pick a Team and a Project.
- The board now reflects that Linear project. Create/move issues here or in
Linear's own app — Linear wins on conflict.
- Add Linear MCP → registers Linear's MCP with the Claude CLI
(
claude mcp add --transport http linear https://mcp.linear.app/mcp) so
agents manage issues directly in Linear. Run /mcp in a Claude session the
first time to authorize it.
Switch back anytime with Use Local; disconnect entirely with Disconnect
Linear.
How issues map to Linear (labels)
An issue's status maps to a Linear workflow state (backlog / unstarted /
started / "In Review" / completed / canceled). Its type, mode, and
assigned_to fields are stored as labels — but only the non-default
value of each field carries a label. The default value carries no label, which
keeps a typical feature / agent issue label-free.
| Field |
Default (no label) |
Override label |
type |
feature |
Bug — Linear's own seeded label, reused for bug-type issues. |
assigned_to |
agent |
Human — marks the issue as human-assigned (agents skip it). |
mode |
whatever ideaBuilder.defaultMode is set to (ships as auto) |
mode:auto / mode:plan — added only when the mode differs from your default. |
Using the labels correctly:
- Set a field from Linear's app by adding or removing the matching label. Add
Bug to make an issue a bug; remove it to make it a feature. Add Human to
take an issue off the agents; remove it to hand it back. Add mode:plan (or
mode:auto) to override the run mode.
- The extension creates the labels it needs.
Human and mode:* are created
on first use; Bug is Linear's built-in label. You don't have to pre-create
any of them.
mode: labels are relative to your default. Because the unlabeled mode is
ideaBuilder.defaultMode, changing that setting flips which issues need a
mode: label. If you want every issue's mode to be explicit in Linear, that's
expected — the extension writes a mode: label only when it has to.
- Don't hand-edit a
mode: label to a value other than auto or plan — an
unrecognized mode: label is ignored and the issue falls back to your default.
- Legacy labels still work. Older paired labels (
type:bug, type:feature,
assignee:agent, assignee:human) are still read correctly and are cleaned up
automatically the next time you edit the issue from the extension.
- Other labels are left alone. Any labels you add for your own organization
are preserved on every edit; the extension only manages the ones above.
Settings
| Setting |
Purpose |
ideaBuilder.showTerminalButton |
Show the Terminal toggle in the status bar (bottom bar). Default true; set false to remove it. Works regardless of license. |
ideaBuilder.stateFilter |
Comma-separated issue statuses that trigger a session. Default "todo". |
ideaBuilder.pollIntervalMs |
Poll interval in ms (Linear mode). Default 20000. |
ideaBuilder.autoStart |
Start polling automatically on VSCode launch. |
ideaBuilder.claudeCommand |
Path to the claude binary. Default claude. |
ideaBuilder.terminalLocation |
editor (default) or panel. |
Mode and the Linear Team/Project mapping are stored per-workspace and set via the
Connect Linear / Use Local commands, not settings.
Commands
| Command |
What it does |
Enter License Key |
Activate Idea Builder on this machine with your Dodo Payments key. |
Manage License |
Replace the key, or remove the license from this machine. |
New Idea |
Create a new local idea to build. |
Initialize |
Scaffold this workspace; Claude asks about your idea, then sets it up. |
New Issue |
Add an issue (a title is generated from the description). |
Connect Linear |
OAuth to Linear and pick a Team/Project to sync with. |
Use Local (Offline) Mode |
Switch the board back to the local file. |
Add Linear MCP |
Register Linear's MCP server with the Claude CLI. |
Disconnect Linear |
Clear the Linear token and mapping; revert to local. |
Start Polling / Stop Polling |
Begin/stop launching sessions for todo issues. |
Poll Now |
One-shot poll cycle. |
List Sessions |
Quick-pick of open Claude terminals. |
Open Claude / (Worktree) / (Resume) / Terminal |
The one-click launchers above. |
Show Output |
Reveal the Idea Builder output channel. |
Development
cd vscode-extension
npm install
LINEAR_CLIENT_ID=<your-linear-oauth-client-id> npm run build # bundles to dist/extension.cjs
npm run typecheck # tsc --noEmit
Build-time vars (LINEAR_CLIENT_ID, LINEAR_MCP_URL, DODO_BASE_URL) can be
set inline or kept in a gitignored vscode-extension/.env — copy
.env.example to .env and fill it in. Inline env vars still override the file.
LINEAR_CLIENT_ID is the client id of a registered Linear OAuth
application; register
the loopback redirect URIs http://127.0.0.1:54322/callback …54325/callback.
Without it the offline board works fully, but Connect Linear will report that
the client id is missing. Press F5 to launch an Extension Development Host.
Dev builds (npm run build / watch / F5) are not obfuscated and target
Dodo's test environment (https://test.dodopayments.com) automatically;
production builds (npm run build:prod, and thus package-and-install.ps1) are
obfuscated and target live (https://live.dodopayments.com). Override either
with the DODO_BASE_URL env var. The chosen Dodo base is printed in the esbuild
build log.
Selling it — Dodo Payments setup (one-time)
- In the Dodo dashboard, create the product for the extension and enable
License Keys, setting the activations-per-key limit (e.g. 2 machines).
- That's all the extension needs — the activate/validate/deactivate endpoints
are public, so there is no API key to embed. The build only needs the API
base URL, which defaults to
https://live.dodopayments.com.
- Sell the product via a Dodo checkout/payment link; buyers receive a license
key by email and paste it into Enter License Key.
Caveats
- The OAuth callback binds one of ports 54322–54325 on
127.0.0.1. If all four
are in use, Connect Linear fails — free one and retry.
claude must be on PATH (or set ideaBuilder.claudeCommand).
- In Linear mode, a team needs the usual workflow states (backlog / unstarted /
started / completed / canceled); an "In Review" state is used when present,
otherwise the started state is reused.