---
title: Foundry (AI-powered app builder)
---

# Foundry (AI-powered app builder)

## What it is

**Foundry** is a Marketplace plugin (id `prdstack`, currently **v1.2.2**) that takes you from a
one-paragraph idea to a planned, built, and optionally deployed app — without you writing the
plan or the code. Its manifest tagline is literally *"from idea to deployed project in one
sitting."*

It works in four stages:

1. **Plan** — a thirteen-step AI interview turns your idea into a Product Requirements Document.
2. **Decompose** — the PRD is chopped into focused 100–400-line files an AI can build from, plus a
   `tasks.json` build manifest.
3. **Build** — Foundry's own execution engine spawns real coding sessions, one per task, in
   dependency order.
4. **Deploy** *(optional)* — a Firebase setup checklist plus generated deploy tasks put the result
   live.

Stages 1–2 run in either of two modes: the **manual interview** (you answer each step, the AI
drafts the section) or **Autopilot** (you describe the idea once and the AI drives every step
itself). Stages 3–4 are always opt-in — see [Consent and cost](#consent-and-cost).

Progress saves continuously, so a half-finished PRD — or a half-finished *build* — survives
across launches.

## Where to find it

**On by default.** Foundry ships enabled — a one-time backfill (`bundledPluginsDefaultOnBackfilled`)
adds it to `enabledPlugins` for new AND existing installs, so the **Foundry** entry (hammer icon)
is there out of the box in the sidebar's **Plugins** section — expanded by default. (Until
2026-09-04 it nested under **Developer Tools**, which ships collapsed, so the entry was hidden and
Foundry could not be reached at all. Settings → Plugins now also carries an **Open** button.) It stays a Marketplace-managed plugin with no Settings → Features toggle: turn it
off from the plugin Marketplace like any plugin (its id leaves `enabledPlugins` and the entry
hides), and re-enable to bring it back. The default-on backfill runs only once, so a later off/on
choice sticks.

Users who had the old built-in Foundry are migrated to the Marketplace copy automatically on first
launch of the version that dropped the built-in — no reinstall, no data loss. Full detail of that
migration and of how plugin updates work (you always click; nothing installs silently):
[foundry-marketplace-only-autoupdate.md](foundry-marketplace-only-autoupdate.md).

Uninstalling never deletes your work — the `prds` / `steps` / `messages` / `prd_files` /
`build_runs` / `build_tasks` data persists, and re-installing restores the sidebar entry (the
plugin-enable path undeletes the soft-deleted row). The startup seeder enforces this via
`isRegistryEntrySeedable` so the entry can never be force-shown for an uninstalled plugin (see
[plugin-shim-seeding-contract.md](/.claude/memory/contracts/plugin-shim-seeding-contract.md)).

## How it behaves

### The thirteen steps

Every PRD runs the same v3 flow, grouped into four phases. Each step caps at its own `maxRounds`
of back-and-forth before the AI is forced to converge and move on:

| # | Step | Phase | Max rounds |
|---|------|-------|-----------|
| 1 | Product Vision | Discovery | 6 |
| 2 | Feature List | Discovery | 5 |
| 3 | User Journey | Discovery | 4 |
| 4 | Technical Hurdles | Architecture | 4 |
| 5 | Design Language | Architecture | 5 |
| 6 | Tech Stack | Architecture | 5 |
| 7 | Data Flow | Architecture | 4 |
| 8 | User Red Team | Red Team | 3 |
| 9 | Developer Red Team | Red Team | 3 |
| 10 | Designer Red Team | Red Team | 3 |
| 11 | Manual Work | Implementation | 3 |
| 12 | Final Improvement | Implementation | 3 |
| 13 | Decomposer | Implementation | 3 |

Steps 8–10 are the adversarial passes — three reviewers attacking the plan from a user's, a
developer's, and a designer's perspective. They can be switched off (see below).

### How to use it (manual mode)

1. **Open Foundry.** Click **Foundry** in the left sidebar. The dashboard lists every PRD you've
   started, with status and a progress percentage.
2. **Create a new PRD.** Click **New PRD** in the dashboard header. The Builder view opens at
   step 1 with the AI asking the first interview question.
3. **Work through the steps.** Each step has an AI-generated prompt, a textarea for your answer,
   and a **Generate** button that drafts the section from what you've said so far. Edit the draft,
   then click **Next Step**. Earlier steps stay visible — scroll back and rework any answer.
4. **Configure the flow.** Settings → **Foundry** → **Prompt Flow Version** (default `v3` — Modern
   13-Step) and **Include Red Team Reviews** (default on). Turning red-team off skips steps 8–10.
5. **Export when done.** Once all steps are complete the dashboard marks the PRD `complete`.
   **Export PRD Files** writes the decomposed file set to a folder you pick.

### Autopilot (automated mode)

**Autopilot** lets you describe a project idea once and have the AI drive every PRD step from
start to finish — no per-step typing, no Generate/Next clicks. You watch decisions stream into a
feed and can pause or abort at any time.

#### How to run it

1. **Start from the dashboard.** Open Foundry and click **New PRD**. The Builder view's intake
   screen shows a large textarea labelled "Describe your idea" with an **Analyze Idea** button
   beneath it, disabled until you type something.
2. **Click Analyze Idea.** Autopilot sends your description to a fresh session, which produces a
   short intake summary plus a suggested project name and parent folder. Confirm or edit both,
   then start the run. (If Firebase isn't set up, a notice offers **Set up Firebase** or
   **Continue Anyway** first.)
3. **Watch it run.** A status strip pins to the top showing the current step name, **"Step 4 of
   13"** with an overall progress bar, a round counter, an elapsed timer, a **"Spent $X.XX"** chip,
   and **Pause** / **Abort**. Below it, the **decision feed** streams a card per AI choice, grouped
   under step headers with a count badge. Cards collapse by default; click to expand and see the
   full question and the options the AI chose from.
4. **Intervene on a decision.** Each decision card runs a **20-second** countdown before
   auto-selecting the option badged **Recommended**. Every option shows its description. A **"Let
   me decide"** button cancels that one card's timer without pausing the whole run. The countdown
   is announced via `aria-live`.
5. **Pause / resume / abort.** Pause halts the loop and freezes the timer; resume picks up at the
   same step and round. Abort tears down the session and marks the run `aborted`. If you close the
   view or the app restarts mid-run, reopening the PRD restores it **paused** — the in-flight
   session is dead after navigation, so you click Resume to re-spawn one.
6. **Completion.** When all steps converge, Autopilot runs the **decomposer** phase: it plans the
   PRD's output files (`01_VISION.md`, `02_FEATURES.md`, …), generates each in turn, writes them to
   `docs/planning/`, and updates the planned-files list as it goes. The dashboard then flips the
   PRD to `complete` and offers to build it.

#### What's automatic vs. what you control

- **Automatic**: every per-step question, the AI's choice between options, advancing rounds and
  steps, the convergence decision, the file-generation order during decompose.
- **You control**: the idea description, the project name + parent folder, any individual decision
  (via "Let me decide"), Pause / Resume / Abort, and **every paid stage after the PRD**.
- **Safety rails**: each step caps at its `maxRounds` (3–6) and then force-converges; if a step
  produces no actionable options a 15s auto-continue timer fires so the run can't hang; a 20s
  countdown precedes each auto-pick.

#### State persistence

Autopilot writes its full state into `prds.project_context.autopilot` after every meaningful event
— current step index, round count, decision log, intake summary, project + folder names, elapsed
seconds, accrued cost, and the decomposer's planned-files / completed-files arrays. Reopening a PRD
whose autopilot state is non-terminal (anything other than `done` / `aborted` / `idle`) restores
the run as `paused`, replays the decision cards, and shows Resume. The decomposer resumes the same
way — a crash mid-decompose picks up at the next planned file, and existing files on disk are
reused rather than regenerated.

### The build pipeline

Once a PRD is complete and exported, **Build This Now** hands it to Foundry's own build engine —
this is not a single coding session, it's a managed multi-session run.

- **Task manifest.** The decomposer generates a `tasks.json` describing phases and tasks, each with
  a name, description, complexity, the PRD files it needs, a `depends_on` list, and a prompt. A
  malformed manifest is retried once with a forgiving parse before it's treated as a failure.
- **Dependency-ordered execution.** `build-graph.js` computes which tasks are runnable (pending,
  with all dependencies `completed` or `skipped`). Cycles and dangling dependencies are guarded
  against, and a malformed `depends_on` degrades to "no dependencies" rather than crashing.
- **Concurrency and retries.** Up to **3** tasks run at once by default; each task retries up to
  **2** times. A failed task marks everything transitively depending on it `blocked`.
- **Live dashboard.** A poll every 5s updates stat cards for Tasks, Elapsed, Active, and
  **Spent** (every task session's real cost — banked whether it succeeded, failed, was
  retried, was skipped, or was halted), plus a progress ring and per-phase accordions.
- **Pause and resume.** **Pause build** asks for confirmation, then rewinds in-flight tasks to
  pending. A **Resume Build** banner restarts the engine from DB state — it reconciles crash
  orphans by re-adopting still-live sessions, recording finished ones, and settling lost ones to
  `failed` without re-spawning them, so resuming never double-charges you.
- **Needs-your-answer ≠ failure.** A task whose session asks a question is shown amber with
  **"Answer in session"**, not as an error. It also keeps its concurrency slot, so once every
  slot is parked that way the build can no longer advance on its own: it says so once, and the
  status badge reads **"Waiting for you"** until you answer. Nothing is nudged or auto-answered
  — the question is yours, and a build that guesses at it is how one gets called finished
  when it is not.

### Deploying to Firebase

Foundry can carry the project all the way to a live URL. The **Firebase Setup** view is a
step-by-step checklist — install Node, install the Firebase CLI, sign in (with a re-show if the
browser flow stalls), pick a billing-enabled project, choose services. When deployment is opted
into, the decomposer appends a final build phase: *Configure Firebase* (init, enable services, set
security rules — depends on every feature task) then *Deploy to Firebase* (deploy, verify the live
URL). Autopilot checks `isFirebaseReady()` before it starts and lets you set it up first or
continue anyway.

### Consent and cost

Foundry spends real money, and every paid stage past the PRD is explicitly opt-in:

- Finishing the PRD does **not** auto-launch a build. You get a **"PRD ready — build it now?
  (uses AI credits)"** call to action.
- Finishing the build does **not** auto-chain the polish steps. You get **"Polish your app?"** with
  Design Overhaul, UX Intuitiveness, and Legal Pages as separate opt-in cards, each labelled as
  using AI credits.
- Running cost is visible while it accrues — a **"Spent $X.XX"** chip on the Autopilot status strip
  and a **Spent** stat card on the build dashboard. Autopilot records cost per session through its
  heartbeat poll so re-polling never double-counts. The build engine banks each session's cost once,
  at whichever end its task reaches — completed, failed, retried, skipped, or halted by Pause
  — so a build full of retries reports what it really spent rather than only what succeeded.
- A replayed launch is never charged twice. Both build launches carry a request key, so if the
  app dies between starting a session and recording which one it was, the retry gets that same
  session back instead of a second billed one. A deliberate rebuild still starts a fresh one.

#### When a spend cap stops a run

Foundry's sessions are ordinary AMC sessions, so they obey the app's spend caps
(`api-key-spend-cap-contract.md`) —
including the per-account **daily** cap, which ships armed (warn $10 / stop $25) and applies to
pay-per-use API-key accounts only (a Claude subscription is exempt).

Three behaviours matter when that cap is reached:

- **The spawn is refused, not killed after the fact.** `createPluginSession` and
  `launchBuildSession` call the shared daily gate before creating the session row. Until
  2026-08-07 they bypassed it — only the running-session monitor applied, so each session
  spawned, billed ~$1, and was then killed. Measured result: **$70.30 spent in one day against a
  $25 cap.**
- **The reason reaches the user.** A refusal is humanized by `FoundryStatus.humanizeFoundryError`
  into copy that names the cap and points at Settings → Session → Spending limits. It previously
  showed "Couldn't send your message. Please try again" — advice that could not work, since a
  retry is refused identically until the cap resets.
- **A batch aborts instead of retrying.** File generation spawns one session per file; on a cap
  refusal both generation loops stop via `FoundryStatus.isPermanentRefusal` rather than trying the
  remaining files and then retrying the failures. Blind retrying cost ~$22 for zero files.

#### The prompt-size ceiling

`session.create` rejects a prompt over **200,000 characters**. Foundry assembles
`<project_context>` from every completed step's `context_summary`, which is unbounded at write
time — a real PRD reached **213,012 characters** across ten steps (the Data Flow + three Red Team
steps alone were 168k, since those produce long critiques the summary keeps nearly whole) and
wedged permanently at step 11 of 13: instant failure, no retry or setting could clear it.

`FoundryStatus.boundProjectContext` now bounds the assembly at READ time — 8k per step, 60k
total, oldest steps dropped first and named in-band so the model knows its view is partial — with
`clampSpawnPrompt` as a final guard that keeps the head (instructions) and tail (the user's
message). Read-time bounding repairs a PRD that is already over the line without rewriting stored
data.

### Where your files are stored

Foundry is a "virtual" project — there is no folder you picked for it. The app gives it a
**stable, app-managed working directory** at `<userData>/plugins/prdstack` (on Windows
`%APPDATA%\Omniscio\plugins\prdstack`; on macOS under `~/Library/Application Support/`). Every
Foundry session — including each Autopilot run — spawns with that folder as its working directory,
so anything the agent writes with a relative path lands inside it.

Two things make this reliable:

- **The folder is created automatically before the session starts.** You will never see a "Project
  folder not found — Recreate Folder" banner for Foundry. The Marketplace installer creates the
  directory as a side effect of installing, and the spawn path calls `ensurePluginProjectDir()` as
  a belt-and-braces check regardless.
- **It persists across restarts.** It lives in your permanent user-data directory, not a temporary
  one, so deliverables and the chat links pointing at them survive quitting the app.

**Finding the files.** Because the folder lives under your user-data / AppData directory rather
than Documents, it's easy to overlook. The simplest way in is the project's built-in **File
Explorer** (`Ctrl+E` with a Foundry session active) or clicking a file link surfaced in chat. If
you want the finished PRD somewhere more visible, export it — at Autopilot intake you choose a
parent folder, and the build creates a normal project there so the real coding sessions run
somewhere you picked.

> **Re-exporting after a restart.** Omniscio's permission to write into the project folder you pick for **Export PRD Files** / **Build This Now** is granted when you choose it and — by design — resets when Omniscio restarts. So an export after a restart re-opens the folder picker (pre-filled with your last choice) to re-confirm; pick it and the export continues. It no longer fails with a silent "Export failed — try again" toast (Sentry 7658204379).

> **History:** before v0.1.47 the `__plugin_prdstack__` sentinel could resolve to a per-launch temporary folder that Windows wiped on restart — a long Autopilot run's deliverables would vanish and their chat links break. The sentinel now always resolves to the stable `<userData>/plugins/prdstack` path above, and Omniscio ensures the directory exists before spawning.

## For agents

### How it works

Foundry's source lives at [/src/plugins/prdstack/](/src/plugins/prdstack/), declared by
[manifest.json](/src/plugins/prdstack/manifest.json) — `id: 'prdstack'`, `category: 'planning'`,
sidebar entry "Foundry", icon `hammer`. **The in-repo copy is the build source for the Marketplace
package, not a plugin the app loads**: the loader's
`BUILTIN_EXCLUDE = new Set(['prdstack', 'reading-queue', 'repoguard', 'writer'])` in
[plugin-loader.ts](/src/main/services/plugin/plugin-loader.ts) skips it during the built-in scan, so
the copy that runs is always the installed Marketplace one.

The manifest declares **six** plugin-storage collections that the plugin runtime materializes as
SQLite tables — `prds`, `steps`, `messages`, `prd_files`, `build_runs`, `build_tasks` — six
permissions (`notifications`, `navigation`, `storage`, `sessions`, `ai`, `firebase`), and two
settings (`promptVersion`, `includeRedTeam`) surfaced in Settings → Foundry.

The UI is a self-contained HTML/JS app at [ui/index.html](/src/plugins/prdstack/ui/index.html)
loaded through the plugin shell, under a strict CSP (`script-src 'self'` — no inline handlers, no
inline `<script>`, locked by
[prdstack-csp.test.ts](/tests/unit/plugins/prdstack-csp.test.ts)). It loads ~18 scripts in a fixed
order:

- **Shared** — `status-meta.js` (the single source of truth for status icon/colour/label via
  `window.FoundryStatus`, the money/time formatters, and the `ACTION_CARDS` list), `marked.min.js`
  + `dompurify.min.js` for sanitized markdown.
- **Core** — `plugin.js` (dashboard, builder, viewer, `V3_STEPS`, `openPrd`, Build This Now),
  `prompt-constants.js`, `wizard.js`, `export.js`, `setup.js` (Firebase).
- **Autopilot** — `autopilot.js` plus `autopilot-intake.js`, `autopilot-persist.js`,
  `autopilot-phase-watchers.js`, `autopilot-decomposer-render.js`, and the two decomposers
  (`prdstack-decomposer.js`, `prdstack-autopilot-decomposer.js`, `decomposer-file-browser.js`).
- **Build** — `build-db.js`, `build-graph.js` (pure dependency functions), `build-engine.js` (the
  run loop), `build-dashboard.js`.

Prompt templates live under [prompts/v3/](/src/plugins/prdstack/prompts/v3/) — one per step, plus
`master_system_prompt.md`, `intake_validation.md`, and `autopilot_addendum.md`.

The sidebar entry is special-cased via `PRDSTACK_PROJECT_PATH = '__plugin_prdstack__'` in
[/src/shared/types.ts](/src/shared/types.ts), which is also how the integration registry records
it. `resolveProjectWorkDir()` in
[claude-project.ts](/src/main/services/claude-project.ts) maps any `__plugin_<id>__` sentinel to
`<userData>/plugins/<id>`, and the spawn path calls `ensurePluginProjectDir(folderPath)` just before
its pre-spawn `existsSync` check. That ensure step is non-fatal — a creation failure is logged and
falls through to `existsSync` rather than aborting the spawn.

Autopilot's state machine has **seven** values — `idle | intake | running | paused | completing |
done | aborted` — with `restoreAutopilot(prd)` always rehydrating non-terminal runs as `paused`.
Decomposer state (`plannedFiles`, `completedFiles`) persists alongside the run state in the same
`project_context.autopilot` JSON blob.

**Navigation between PRDs** is contract-locked — a single command-channel path, a re-entrancy guard
in `openPrd()`, and a state-reset-before-load invariant that stops one PRD's state leaking into
another. Long-running operations must capture `prdId` at entry rather than reading `currentPrd.id`
after an `await`. See
[prdstack-navigation-contract.md](/.claude/memory/contracts/prdstack-navigation-contract.md).

## Related

[INDEX.md](INDEX.md) is the full library index. [foundry-marketplace-only-autoupdate.md](foundry-marketplace-only-autoupdate.md) explains why Foundry is Marketplace-only, and how plugin updates work. [plugin-marketplace.md](plugin-marketplace.md) covers installing and updating plugins generally. [use-recipes.md](use-recipes.md) is for multi-step agent workflows that aren't PRD-shaped, and [projects-sidebar.md](projects-sidebar.md) covers how the sidebar lists Foundry in the Plugins section.
