A human-in-the-loop starter for the Fountain API. The user asks for an outcome, an agent returns a typed proposal, the user approves or revises it, and only then does the agent act.
This is the right starting point for change management, infrastructure, research plans, content pipelines, audits, purchasing, and other products where a review gate matters more than a blank chat box.
After clicking Use this template:
-
Edit
src/config.ts: give the app a unique OAuth client ID and storage key. -
Replace
Proposal,Result, andPROTOCOL_INSTRUCTIONSinsrc/protocol.tswith domain-specific objects. Keep the validator and agent instructions together. -
Replace
ProposalCardinsrc/App.tsxwith the review surface your object deserves: a diff, itinerary, checklist, table, or preview. -
Register the dev origin and OAuth redirect in Fountain:
API_CORS_ORIGINS=http://localhost:5174 OAUTH_CLIENTS='[{"id":"fountain-template-workflow","name":"Fountain Workflow Starter","redirect_uris":["http://localhost:5174/"]}]' -
Delete this checklist and document the actual workflow.
bun install
bun run dev
bun test
bun run typecheck
bun run buildSet FOUNTAIN_PROXY=http://localhost:4000 for Vite to proxy /api and
/oauth during local development.
The Fountain conversation is the system of record. The initial prompt embeds the protocol, plans have stable IDs, approval names the exact ID, and revised plans get new IDs. On reload, the UI folds the current proposal, approval, and result back out of the transcript. Browser storage contains only credentials and the current conversation ID.
This avoids a second application database for many focused workflows and prevents a stale approval from applying to a revised proposal.
| Concern | File |
|---|---|
| product-specific protocol | src/protocol.ts |
| review and result UI | src/App.tsx |
| API, auth, SSE, local IDs | src/fountain.ts |
| app identity | src/config.ts |
| visual system | src/styles.css |
fountain.ts is intentionally one visible file in this template. Split it
into api/ and lib/ as the application grows; do not publish it as a hidden
client framework before the API surface has earned one.
MIT