IdeaClyst
Catalyze rough ideas into buildable SaaS plans — by sitting Claude and Codex on the same council.
★Step-by-step guide
The fastest path from a fresh clone to a finished planning packet. Mock mode is the default, so you need no CLIs to try it end to end.
Install dependencies
From the project root:
npm installCreate your config
Copy the example env file. It defaults to mock mode — no CLIs required.
cp .env.example .env.localStart an idea session
On the homepage, click “Start an Idea Session” to open the idea form (/new).
Describe your idea
Give it a title, write the idea (at least a sentence, 10+ chars), and pick a goal — validate · plan · build · pitch · refine. Optionally add a target customer, constraints, or a preferred stack. Then submit.
Watch the council deliberate
You land on the run page, which polls every 1.5s. The five steps light up as they run — ✓ done, ▸ active, ○ pending — and each output appears the moment it completes.
Read your packet
When the run completes, the result tabs fill in: Summary, MVP Backlog, Risks, Validation Tests, Next Prompts. All past sessions live under /runs.
(Optional) Switch to the real CLIs
For real model output, set IDEACLYST_AGENT_MODE=cli in .env.local, make sure both CLIs are installed and logged in, then restart the server and run a new session. A real council takes ~5–7 min (five live model calls), versus instant in mock mode.
Find the files
Every run is saved to disk under .ideaclyst/runs/<runId>/ as run.json plus Markdown artifacts you can read or share outside the app.
Heads up in dev: editing a file mid-run can interrupt an in-flight council (the orchestrator runs in-process). If that happens, restart npm run dev and start a fresh session.
01What it is
IdeaClyst is a local-first Next.js app that turns one rough product idea into a complete founder planning packet. It does this not with a single prompt, but by orchestrating a structured council — a five-step deliberation between two AI command-line tools that take opposing roles and critique each other before reaching a verdict.
Think of it as a tiny boardroom: a skeptical SaaS founder (Claude) and a pragmatic CTO (Codex) argue your idea into shape. The output is split into Summary, MVP Backlog, Risks, Validation Tests, and ready-to-paste Next Prompts.
The whole app is built around one idea: two different models, taking adversarial roles and reading each other's work, produce a sharper plan than either alone. Everything else — the disk store, the polling UI, the mode switch — exists to serve that deliberation.
New: a web-research Step 0 (vendored from surfagent) headlessly scouts the market/competitors and grounds every council step in real data — plus an Idea Discovery mode (/discover) that proposes ideas to promote into a run. Research now writes a structured dossier, competitor matrix, opportunity map, validation experiments, distribution plan, kill criteria, MVP scope notes, landing-page critique, watch baseline, and founder brief. Discovery candidates also get full idea reports with scorecards, offer ladders, proof signals, execution plans, founder fit, roasts, keyword source/freshness labels, copyable exports, Claude/Codex handoff prompts, a saved library, founder profile personalization, a trend radar, and a side-by-side compare view. Research is best-effort and mode-gated (mock/offline by default), so a run never fails when Chrome is missing. See the README for details.
02Features at a glance
Dual-agent council
Five alternating steps between Claude and Codex, each agent reading prior outputs and critiquing the other.
Mock mode by default
Realistic, idea-aware output with zero CLIs installed. Flip one env var for the real thing.
Progressive results
Each step's output appears the instant it completes — the run page polls disk every 1.5s.
Disk is the truth
Every run persists as run.json + Markdown files. A server restart never loses a result.
Tabbed packet
The final plan auto-splits into Summary, MVP Backlog, Risks, Validation Tests & Next Prompts.
No-shell, sandboxed
CLIs spawn with array args + stdin (no injection); Codex runs read-only in a throwaway temp dir.
Graceful failure
A missing or failing CLI marks the run failed with a clear message — completed steps survive.
Markdown artifacts
Each run also writes human-readable .md files you can read or share outside the app.
No secrets handled
IdeaClyst never touches API keys — both CLIs authenticate via their own local sessions.
Evidence toolkit
Surfagent research writes RESEARCH_DOSSIER.json, a toolkit tab, a founder brief, and standalone market artifacts.
Full idea reports
Every candidate has a report page with business fit, offer ladder, why-now, proof, market gap, framework, keyword, founder-fit, and roast sections.
Compare and export
Candidate reports can be added to /compare and copied as Markdown, JSON, a one-pager, or Claude/Codex implementation and review prompts.
Founder profile
/profile stores skills, capacity, risk, sales comfort, capital, market access, and unfair advantages locally.
My Stuff
Save candidate ideas and reports into /library, backed by local JSON and Markdown files under .ideaclyst.
Market signal library
/trends, /insights, and /monitors turn local discoveries into trend cards, market insight reports, and rerunnable competitor/trend diffs.
Source-aware intelligence
Report keyword sections label source and freshness, with optional snapshot data layered over deterministic offline estimates.
Lean product areas
The header stays compact: Explore has Discover, Today, and Trends; Workspace has Sessions, Library, and Validation. Deeper tools are linked from those pages.
Source audit
/evidence indexes run, discovery, and report sources with confidence, freshness, claims, and weak-evidence warnings.
Sprint workspaces
/validation, /validation/import, /validation/analytics, and /interviews turn reports, pricing tests, pasted results, and buyer personas into an audit trail.
PRD, landing, and packets
Candidate reports now open funnel, landing-page, persona, advisor, report-version, export-packet, and build-this-idea workspaces grounded in the saved report.
Decisions and memory
Report decisions write to .ideaclyst/decisions, feed compact council memory, and keep promoted, parked, killed, and validated calls inspectable.
Source lanes and cache
/settings/research edits source lane templates and shows the TTL/size-capped cache used by search, recon, and readable-page extraction.
03Architecture
IdeaClyst has four layers, and the design discipline is that only one of them knows whether you're in mock or real-CLI mode.
App Router pages
Home, idea form (/new), sessions list (/runs), and a live run detail page that polls. Pure client rendering + fetch.
Route handlers
/api/runs creates a run and fires the council; /api/runs/[id] returns one run for polling; /api/runs/[id]/research queues a research-only refresh and returns immediately.
The 5-step pipeline
orchestrator.ts sequences the council and persists after every step, including the structured research toolkit files created during Step 0.
The mode seam & disk
agents/ is the only mode-aware code; runs/store.ts reads & writes the on-disk source of truth.
// the only branch that knows the mode — agents/index.ts export async function runAgent(agent, prompt, ctx) { if (agentMode() === "mock") return runMock(ctx.run, ctx.stepKey); // ignores prompt, uses structured run return agent === "claude" ? runClaude(prompt, runDir) // real `claude` (no -p), in run dir : runCodex(prompt); // real `codex exec` }
04The 5-step council
This is the heart of the app. The two agents alternate, and the crucial detail is in the "sees" line of each step — every agent reads specific prior outputs, which is what makes it a deliberation rather than five isolated prompts.
Market research
Before the council deliberates, headless Chrome scouts the web for the idea's market and competitors and writes a research memo plus a structured toolkit that grounds every later step. Best-effort: if Chrome is missing or a search is blocked it falls back to offline synthesis — the run never fails. Can be toggled off per run in the idea form or queued later as a background refresh without rerunning the council.
Product strategy
Pressure-tests the idea into a credible strategy: the core problem & who feels it most, the sharpest wedge, target customer & willingness to pay, differentiation, go-to-market, and the riskiest assumptions.
Technical architecture
Designs a lean, buildable MVP architecture: recommended stack & why, data model, key services, third-party APIs, build risks, and a rough build order. Flags anything technically naive in the strategy.
Critiques the architecture
Back as the skeptical founder — attacks the CTO's plan from a product/shipping lens: Is it over-engineered for an MVP? Does it serve the wedge? What gets cut to ship in weeks, not months?
Critiques the strategy
The CTO returns fire on the strategy from an engineering-reality lens: which assumptions are technically expensive or infeasible for an MVP? Where does go-to-market imply scope the team can't deliver fast?
Final synthesis
Reconciles everything into one decisive packet, resolving disagreements with a clear recommendation. Outputs exact ## headings: Summary, MVP Backlog, Risks, Validation Tests, Next Prompts.
The cross-exchange is the point. Codex builds on Claude's strategy (step 2), then each critiques the other's domain (steps 3 & 4), and Claude reconciles all four into a verdict (step 5). After every step the orchestrator rewrites run.json and a Markdown file, so the UI reveals outputs one at a time.
◆Idea Discovery
Most of IdeaClyst evaluates an idea you bring. Idea Discovery (the /discover route) does the opposite — it finds ideas for you, grounded in what people are actually struggling with on the web. The blank page is the hardest part of building; Discovery replaces it with real demand signals.
Tell it who is building
Optionally fill /profile once so discovery can account for skills, buyer access, capital, time, risk, and sales comfort.
You frame the hunt
A market or space — “visionOS apps,” “AI for accountants” — plus your goal and build capacity. Founder-profile context is prefilled into notes and can be edited per scout.
Surfagent sweeps the web
Headless Chrome scouts source-specific lanes — Hacker News, Reddit, Product Hunt, GitHub, commercial review/pricing pages, and general web — for problems, “I wish there was…”, launches, and implementation ecosystems.
An honest landscape first
Claude writes a sourced read of the space — a one-line verdict, demand signals, competition, who actually pays, and a realistic outlook for your goal. It leads with the bad news when the market is hard.
Find the wedge zone
The scout creates a high-pain/competition map so you can see sharp wedges, crowded-but-validated ideas, exploratory bets, and likely skips before choosing a candidate.
Concrete, comparable ideas
Then 5–7 candidates, ranked best-fit-first, each with a wedge, who pays, build effort, commercial strength, biggest risk, fit, signal + source, confidence score, and kill criteria.
Inspect before committing
Each candidate opens into a full report: opportunity scorecard, business fit, offer ladder, why-now, proof signals, market gap, execution plan, framework fit, community and keyword intelligence, founder fit, profile lens, and roast.
Watch signals accumulate
/trends collects market terms, keyword growth notes, related communities, sources, and candidate links from local discoveries.
Make a sharper call
Save reports to /library, add them to /compare, sort by scores, and copy Markdown, JSON, one-pagers, build prompts, or review-only prompts.
One click to the council
“Promote to council” turns a candidate into a normal run and carries the report thesis, founder fit, core offer, and roast verdict into the council brief.
A first-class feature. Like research, Discovery is mode-gated (deterministic offline candidates in mock; live scouting + synthesis in CLI mode) and best-effort — it always returns candidates, even offline or when a source is blocked.
Discoveries persist on disk under .ideaclyst/discoveries/<id>/ (a discovery.json, MARKET_READ.md, OPPORTUNITY_MAP.md, CANDIDATES.md, and report/version artifacts), and the discovery page polls live, just like a run. Trend radar writes .ideaclyst/trends; insights, monitors, decisions, exports, source lanes, validation imports, and interviews write to their own local folders under .ideaclyst/. The app header stays lean: Explore opens /discover, /today, and /trends; Workspace opens sessions, library, and validation. Compare, evidence, decisions, insights, monitors, interviews, clusters, and research settings are linked contextually from those pages.
◆Roadmap Intelligence
IdeaClyst can read the roadmap of a Threlmark project — a separate local-first roadmap manager — and turn it into grounded growth suggestions. Point it at a project (the /roadmap route) and it proposes new features, spin-off products, and services, each scored like a roadmap card and backed by real web evidence. Review them, then send the best ones back into Threlmark's Inbox.
Point at Threlmark
Reads each project's roadmap straight off disk (~/.threlmark) — read-only — or via Threlmark's REST API. Configure it on the new /settings page; environment variables always win.
Know the roadmap first
A deterministic coverage read — which categories are strong, which are thin or entirely absent, what's done vs. still open — frames the analysis before any model runs.
Features · spin-offs · services
Three independent research lanes sweep the web: gaps→features, adjacency→spin-offs, productize→services. You choose how many suggestions per lane.
Always real, never mock
Live + strict only. Each suggestion cites real, actually-fetched source links plus a why-now. No sources means no fabrication — just a clear notice.
Score, sources, select
The review page shows impact/evidence/fit/effort, computed priority, the why-now, and source links per card. Tick the ones worth keeping.
Round-trip to the Inbox
“Send to Threlmark” writes flat suggestion files into the project's suggestions/ folder; Threlmark's Inbox accepts them into the roadmap. Pick a different target project to cross-promote.
Read-only except one folder. IdeaClyst only ever writes into a Threlmark project's suggestions/ directory — never its items, board, or metadata. Suggestions carry provenance (kind, why-now, sources) that round-trips intact through Threlmark's Inbox.
Analyses persist under .ideaclyst/roadmap/<id>/ and the page polls live, just like a run. The data source and any REST base URL are set at /settings; see the new variables in Configuration. Roadmap intelligence is mode-gated like the rest of research — it runs live + strict and shows real data only.
05Request lifecycle
From the moment you hit submit, here is the exact path — note that the server responds before the council finishes:
| # | Stage | What happens |
|---|---|---|
| 1 | Submit | The /new form POSTs the idea brief to /api/runs. |
| 2 | Validate & create | Title required, idea ≥ 10 chars, goal must be valid. A queued run is written to disk (run.json + IDEA.md). |
| 3 | Fire & forget | Server calls void startRun(id) without awaiting and returns { runId } with a 201 immediately. |
| 4 | Redirect | Client navigates to /runs/[runId]. |
| 5 | Poll | The run page fetches GET /api/runs/[runId] every 1.5s, re-rendering as outputs fill in. |
| 6 | Deliberate | In the background, the orchestrator runs steps 1→5, rewriting run.json after each. |
| 7 | Complete | Step 5 is split into tabs, status becomes completed (or failed), and polling stops. |
// api/runs/route.ts — the fire-and-forget hand-off const run = await createRun(input); void startRun(run.id); // NOT awaited — runs in background return NextResponse.json({ runId: run.id }, { status: 201 });
06Mock vs. CLI mode
One environment variable, IDEACLYST_AGENT_MODE, selects the backend. The orchestrator and UI are identical in both modes — only agents/ behaves differently.
| Aspect | Mock (default) | CLI |
|---|---|---|
| Set with | IDEACLYST_AGENT_MODE=mock | IDEACLYST_AGENT_MODE=cli |
| Needs CLIs? | No — runs instantly offline | Yes — claude & codex installed + logged in |
| Driven by | Structured run + step key (prompt ignored) | The generated prompt (run/step ignored) |
| Output | Deterministic, idea-aware Markdown | Real model output |
| Use for | Demos, UI work, offline dev | Real planning packets |
CLI mode prerequisites. Both binaries must be on PATH and authenticated: claude --version and codex login status. IdeaClyst never handles credentials — it relies entirely on each CLI's own local session.
Expect minutes, not seconds. A full council in CLI mode is five real model calls — roughly 50–80s per step, ~5–7 min end to end. Mock mode finishes instantly. Env vars are read at server start, so restart the dev server after changing the mode, and note that switching modes does not recompute existing runs — start a fresh session.
Did a run actually use the real CLIs? Open its PRODUCT_STRATEGY.md — real output is specific to your idea and references your preferred stack / constraints, whereas mock output reuses a fixed template (it splices your idea text into generic phrasing like “…points at a workflow that is currently manual, fragmented, or simply tolerated”).
07How CLI calls work
In CLI mode each council step spawns a real process. Both backends use array args + stdin (never a shell string), so a prompt can't break escaping or inject shell syntax, and both enforce a per-call timeout (default 180s).
Claude backend
No -p / --print. When claude's stdout is not a TTY (here it's a pipe), the CLI runs non-interactively and prints a single response, then exits. So IdeaClyst just pipes the prompt on stdin and reads stdout — no print flag needed. --tools "" keeps it a pure text completion (no agentic file actions), and it runs inside the idea's own run directory (spawn cwd):
// agents/claude.ts — runs in the run's own directory claude --tools "" // prompt on stdin, stdout piped (non-TTY) [--model <model>] // optional IDEACLYST_CLAUDE_MODEL
Returns trimmed stdout. A missing binary (ENOENT), non-zero exit with no output, or empty output each reject with a clear "fall back to mock mode" message.
Why no -p? The CLI's clean non-interactive behavior is triggered by a non-TTY stdout, not solely by the print flag — so dropping -p (and the -p-only --output-format) still yields a one-shot completion. Each idea runs in its own directory, mirroring how Codex is isolated.
Codex backend
Runs Codex non-interactively, read-only, inside a throwaway temp working directory so it can't touch your filesystem — we only want the text completion:
// agents/codex.ts codex exec --json --skip-git-repo-check --ephemeral \ -s read-only --color never \ -C <temp-dir> -o last-message.txt - // prompt on stdin
The clean final message is read from the -o output file; the --json event stream is parsed as a fallback (and to surface a clean API error). The temp dir is always removed afterward. An optional IDEACLYST_CODEX_MODEL adds -m <model>, otherwise it defers to ~/.codex/config.toml.
08Data model & storage
IdeaClyst is local-first: there is no database and no in-memory state. Each run is a directory, and run.json is the single source of truth — the orchestrator rewrites it after each step, the polling API just reads it back.
On-disk layout
The run record
A run carries the brief (title, idea, goal, optional target customer / constraints / preferred stack), a status of queued → running → completed | failed, a human-readable currentStep label for the UI, and an outputs object that starts empty and fills in. Run IDs are timestamp-prefixed slugs, so a reverse string-sort yields newest-first for free.
| Status | Meaning |
|---|---|
queued | Created, council not yet started. |
running | Council in progress; currentStep tracks where. |
completed | All 5 steps done; tabs populated. |
failed | A step errored; error holds the message, prior steps preserved. |
Forgiving section splitting. Step 5 asks for exact ## headings, but markdown.ts matches them case-insensitively by keyword (e.g. "mvp" / "backlog" / "scope") and tolerates ###. If a section can't be found, the full plan falls back into the Summary tab — so a tab is never blank.
09API reference
/api/runsLists all runs, newest first. Returns { runs: Run[] }.
/api/runsValidates the brief, creates a queued run, fires the council in the background, and returns { runId } (201). Validation: title required; idea ≥ 10 chars; goal ∈ validate · plan · build · pitch · refine.
// request body { "title": "...", // required "idea": "...", // required, 10+ chars "goal": "validate", // required, one of the five "targetCustomer": "...", // optional "constraints": "...", // optional "preferredStack": "..." // optional }
/api/runs/[runId]Returns a single run as { run: Run } — this is what the detail page polls every 1.5s.
Drive a run from the terminal
The UI is just a client of this API — anything you can do in the browser you can do from a script. Create a run, poll until it completes, then read the packet off disk:
# 1. Create a run → returns { "runId": "..." } curl -s -X POST http://localhost:5417/api/runs \ -H 'Content-Type: application/json' \ -d '{"title":"StandupScribe","idea":"A Slack bot that posts a daily standup digest.","goal":"plan"}' # 2. Poll status until completed (every few seconds) curl -s http://localhost:5417/api/runs/<runId> | jq '.run.status, .run.currentStep' # 3. Read the finished packet cat .ideaclyst/runs/<runId>/FINAL_PLAN.md
10File map
11Configuration
All configuration lives in .env.local (copy from .env.example). No secrets are required.
| Variable | Default | Purpose |
|---|---|---|
IDEACLYST_AGENT_MODE | mock | mock or cli |
IDEACLYST_CLAUDE_BIN | claude | Claude CLI binary / path |
IDEACLYST_CLAUDE_MODEL | empty | Concrete Claude model (e.g. opus), or defer to the CLI default |
IDEACLYST_CODEX_BIN | codex | Codex CLI binary / path |
IDEACLYST_CODEX_MODEL | empty | Concrete Codex model, or defer to ~/.codex/config.toml |
IDEACLYST_AGENT_TIMEOUT_MS | 180000 | Per-agent-call timeout |
IDEACLYST_DATA_DIR | .ideaclyst | Where runs are stored |
Research & discovery
All best-effort; the live path needs a Chrome/Chromium install. Research follows the agent mode unless overridden.
| Variable | Default | Purpose |
|---|---|---|
IDEACLYST_RESEARCH_MODE | follows agent mode | mock or live override |
IDEACLYST_RESEARCH_STRICT | off | 1 = never show mock/offline content; show a clear notice if live data is unavailable (pair with live) |
IDEACLYST_RESEARCH_ENGINE | duckduckgo | duckduckgo · bing · google |
IDEACLYST_CHROME_BIN | auto-detected | Chrome/Chromium path override |
IDEACLYST_RESEARCH_USER_AGENT | desktop Chrome UA | UA override (avoids headless bot challenges) |
IDEACLYST_RESEARCH_CDP_PORT | 9222 | Headless Chrome debug port |
IDEACLYST_RESEARCH_TIMEOUT_MS | 20000 | Per-page recon timeout |
IDEACLYST_RESEARCH_BUDGET_MS | 60000 | Whole research / scout step budget |
IDEACLYST_RESEARCH_MAX_RESULTS | 6 | Search results parsed per query |
IDEACLYST_RESEARCH_MAX_SOURCES | 3 | Pages deep-reconned |
IDEACLYST_RESEARCH_IDLE_MS | 120000 | Reap idle headless Chrome after |
Roadmap intelligence (Threlmark)
Where IdeaClyst reads Threlmark projects from. The /settings page edits these too; environment variables take precedence.
| Variable | Default | Purpose |
|---|---|---|
IDEACLYST_ROADMAP_SOURCE | settings / disk | disk or rest |
THRELMARK_DATA_DIR | ~/.threlmark | Threlmark data root (disk source) |
IDEACLYST_ROADMAP_DIR | = THRELMARK_DATA_DIR | Explicit path override |
IDEACLYST_THRELMARK_API | none | Base URL for the REST source (e.g. http://localhost:5418) |
12Running it
# quick start — mock mode, no CLIs needed npm install cp .env.example .env.local npm run dev # → http://localhost:5417 # then: open the app → "Start an Idea Session" → submit → watch it assemble
| Script | Does |
|---|---|
npm run dev | Dev server on :5417 (Turbopack) |
npm run build | Production build |
npm run start | Serve the production build on :5417 |
npm run lint | ESLint |
npm run typecheck | tsc --noEmit |
13Limits & troubleshooting
Hot reload interrupts in-flight runs. The orchestrator runs in-process. In dev, editing a file mid-run can kill an active council. Restart dev and start a fresh session. Completed steps already on disk are kept.
"The council run failed" in CLI mode. Almost always a CLI that isn't installed or logged in. Check claude --version and codex login status, or set IDEACLYST_AGENT_MODE=mock to fall back to mock outputs.
v0 scope. No auth, billing, teams, database, or Docker. Runs are local files. This is intentional — IdeaClyst is a local-first planning instrument, not a hosted product.