Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
"name": "How do I start a loop from an idea?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Type an idea, freeze a loop. agent-loop-prompt is an Ink TUI: you describe the goal; the judge (not the worker) drafts GOAL.md and verify.sh; freeze lint rejects gameable greps; you confirm; then the watch TUI grinds. Resume lines keep Doppler when the shell was started that way. Optional preview after green is trust-gated and is not executed by agent-loop run."
"text": "Two paths: (1) If you see your coding agent's logo on this page — type your idea as a normal prompt, and ask it to implement the feature with Agent Looper. It sets up the loop and keeps grinding until the check is green. (2) If you like the terminal — set worker and judge with pnpm exec agent-loop-setup, then use pnpm exec agent-loop-prompt to type your idea and start the run. The check stays the finish line."
}
},
{
Expand Down Expand Up @@ -190,19 +190,19 @@
"@type": "HowToStep",
"position": 2,
"name": "Set credentials",
"text": "Export an API key for that agent, or run under Doppler."
"text": "Export an API key for your coding agent."
},
{
"@type": "HowToStep",
"position": 3,
"name": "Freeze a goal and check",
"text": "Prefer pnpm exec agent-loop-prompt --out .cursor/loops/my-task — describe your idea; the judge drafts GOAL.md and verify.sh; confirm freeze. Or run pnpm exec agent-loop-init and edit GOAL.md and verify.sh until bash verify.sh is an honest pass/fail."
"name": "Start from an idea",
"text": "Agent path: type your idea and ask it to implement the feature with Agent Looper. Terminal path: pnpm exec agent-loop-setup, then pnpm exec agent-loop-prompt --out .cursor/loops/my-task to type your idea and start."
},
{
"@type": "HowToStep",
"position": 4,
"name": "Run until green",
"text": "Run pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate."
"text": "Let your agent keep grinding, or run pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate until the check is green."
}
]
}
Expand Down Expand Up @@ -370,9 +370,12 @@ <h2>What do I get when a loop finishes?</h2>
</article>
<article class="tui-answer tui-answer--prompt">
<h2>How do I start a loop from an idea?</h2>
<p>
Type an idea, freeze a loop. <code>agent-loop-prompt</code> is an Ink TUI: you describe the goal; the <strong>judge</strong> (not the worker) drafts <code>GOAL.md</code> and <code>verify.sh</code>; freeze lint rejects gameable greps; you confirm; then the watch TUI grinds. Resume lines keep Doppler when the shell was started that way. Optional <code>preview</code> after green is trust-gated and is <strong>not</strong> executed by <code>agent-loop run</code>.
</p>
<p>Two paths:</p>
<ol>
<li><strong>If you see your coding agent's logo on this page</strong> — type your idea as a normal prompt, and ask it to implement the feature <strong>with Agent Looper</strong>. It sets up the loop and keeps grinding until the check is green.</li>
<li><strong>If you like the terminal</strong> — set worker and judge with <code>pnpm exec agent-loop-setup</code>, then use <code>pnpm exec agent-loop-prompt</code> to type your idea and start the run.</li>
</ol>
<p>The check stays the finish line.</p>
</article>
<article class="tui-answer tui-answer--spend">
<h2>What do the spend numbers mean?</h2>
Expand Down Expand Up @@ -469,9 +472,9 @@ <h2>Install Agent Looper</h2>
</p>
<ol class="howto-steps">
<li>Add <code>@dancingteeth/agent-looper</code> and the SDK for your coding agent (Cursor: <code>@cursor/sdk</code>).</li>
<li>Export an API key, or run under Doppler.</li>
<li>Prefer <code>pnpm exec agent-loop-prompt --out .cursor/loops/my-task</code> — describe your idea; the judge drafts <code>GOAL.md</code> and <code>verify.sh</code>; confirm freeze. Or <code>pnpm exec agent-loop-init</code> and edit the goal and check yourself.</li>
<li>Run <code>pnpm exec agent-loop run</code> until that check is green.</li>
<li>Export an API key for your coding agent.</li>
<li><strong>Agent path:</strong> type your idea and ask it to implement the feature with Agent Looper. <strong>Terminal path:</strong> <code>pnpm exec agent-loop-setup</code>, then <code>pnpm exec agent-loop-prompt --out .cursor/loops/my-task</code> to type your idea and start.</li>
<li>Run until the check is green — or let your agent keep grinding.</li>
</ol>
<div class="install-switcher">
<input type="radio" name="install-view" id="install-view-agent" class="install-switcher__input" checked>
Expand All @@ -492,22 +495,23 @@ <h2>Install Agent Looper</h2>

1. Add @dancingteeth/agent-looper and the SDK for the coding agent on this machine. Cursor uses @cursor/sdk. If you're not sure, detect what's installed (Cursor, Cline, OpenCode, Pi, Codex, DSH, Muse, Claude).
2. Keep @dancingteeth/agent-looper in package.json even if you gitignore `.cursor/loops`. Don't only npx it.
3. Use an API key already on this machine, or run under Doppler. Don't invent keys.
4. Prefer: pnpm exec agent-loop-prompt --out .cursor/loops/&lt;task&gt;
— describe the idea; the judge (not the worker) drafts GOAL.md and verify.sh; freeze lint rejects gameable greps; confirm; then the watch TUI grinds.
Or manually: pnpm exec agent-loop-init, write GOAL.md, and a determined check until `bash verify.sh` is an honest pass/fail. Don't rewrite the goal mid-loop.
5. Start the loop:
3. Use an API key already on this machine. Don't invent keys.
4. Ask me what I want, then implement it with Agent Looper — set up the loop, write GOAL.md and verify.sh, and keep grinding until the check is green.
Or if I'm in the terminal: pnpm exec agent-loop-setup then pnpm exec agent-loop-prompt --out .cursor/loops/&lt;task&gt;.
Manual fallback: pnpm exec agent-loop-init and edit GOAL.md + verify.sh yourself.
5. Start or resume the loop:
pnpm exec agent-loop run .cursor/loops/&lt;task&gt; --runtime &lt;cursor|cline|opencode|pi|codex|dsh|muse|claude&gt; --review-gate
6. Review skill: blockers come back for the next iteration. Advisory is my call. Don't loop on subjective taste.

Cursor example (swap the SDK, key, and --runtime if this machine isn't Cursor):

pnpm add -D @dancingteeth/agent-looper @cursor/sdk

export CURSOR_API_KEY=… # or: doppler run -- …
export CURSOR_API_KEY=…

pnpm exec agent-loop-setup
pnpm exec agent-loop-prompt --out .cursor/loops/my-task
# or: pnpm exec agent-loop-init and edit GOAL.md + verify.sh yourself
# or manually: pnpm exec agent-loop-init and edit GOAL.md + verify.sh

pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate</code></pre>
</div>
Expand All @@ -521,11 +525,11 @@ <h2>Install Agent Looper</h2>
<pre id="install-snippet-human"><code>pnpm add -D @dancingteeth/agent-looper @cursor/sdk
# keep @dancingteeth/agent-looper in package.json even if .cursor/loops is gitignored — don't only npx it

export CURSOR_API_KEY=… # or: doppler run -- …
export CURSOR_API_KEY=…

pnpm exec agent-loop-setup
pnpm exec agent-loop-prompt --out .cursor/loops/my-task
# describe your idea; the judge drafts GOAL.md + verify.sh — confirm freeze, then watch
# or: pnpm exec agent-loop-init and edit GOAL.md + verify.sh until `bash .cursor/loops/my-task/verify.sh` is honest
# or manually: pnpm exec agent-loop-init and edit GOAL.md + verify.sh

pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate</code></pre>
</div>
Expand Down
35 changes: 21 additions & 14 deletions site/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ A report card, not a chat dump. How often the check sent work back, whether the

## How do I start a loop from an idea?

Type an idea, freeze a loop. `agent-loop-prompt` is an Ink TUI: you describe the goal; the **judge** (not the worker) drafts `GOAL.md` and `verify.sh`; freeze lint rejects gameable greps; you confirm; then the watch TUI grinds. Resume lines keep Doppler when the shell was started that way. Optional `preview` after green is trust-gated and is **not** executed by `agent-loop run`.
Two paths:

1. **If you see your coding agent's logo on this page** — type your idea as a normal prompt, and ask it to implement the feature **with Agent Looper**. It sets up the loop and keeps grinding until the check is green.

2. **If you like the terminal** — set worker and judge with `pnpm exec agent-loop-setup`, then use `pnpm exec agent-loop-prompt` to type your idea and start the run.

The check stays the finish line.

## What do the spend numbers mean?

Expand All @@ -53,9 +59,9 @@ Watch and the report card show two numbers when they differ: **list** (public AP
Node 22+, pnpm.

1. Add `@dancingteeth/agent-looper` and the SDK for your coding agent (Cursor: `@cursor/sdk`).
2. Export an API key, or run under Doppler.
3. Prefer `pnpm exec agent-loop-prompt --out .cursor/loops/my-task` — describe your idea; the judge drafts `GOAL.md` and `verify.sh`; confirm freeze. Or `pnpm exec agent-loop-init` and edit the goal and check yourself.
4. Run `pnpm exec agent-loop run` until that check is green.
2. Export an API key for your coding agent.
3. **Agent path:** type your idea and ask it to implement the feature with Agent Looper. **Terminal path:** `pnpm exec agent-loop-setup`, then `pnpm exec agent-loop-prompt --out .cursor/loops/my-task` to type your idea and start.
4. Run until the check is green — or let your agent keep grinding.

### For agent

Expand All @@ -66,22 +72,23 @@ Requirements: Node 22+ and pnpm.

1. Add @dancingteeth/agent-looper and the SDK for the coding agent on this machine. Cursor uses @cursor/sdk. If you're not sure, detect what's installed (Cursor, Cline, OpenCode, Pi, Codex, DSH, Muse, Claude).
2. Keep @dancingteeth/agent-looper in package.json even if you gitignore `.cursor/loops`. Don't only npx it.
3. Use an API key already on this machine, or run under Doppler. Don't invent keys.
4. Prefer: pnpm exec agent-loop-prompt --out .cursor/loops/<task>
— describe the idea; the judge (not the worker) drafts GOAL.md and verify.sh; freeze lint rejects gameable greps; confirm; then the watch TUI grinds.
Or manually: pnpm exec agent-loop-init, write GOAL.md, and a determined check until `bash verify.sh` is an honest pass/fail. Don't rewrite the goal mid-loop.
5. Start the loop:
3. Use an API key already on this machine. Don't invent keys.
4. Ask me what I want, then implement it with Agent Looper — set up the loop, write GOAL.md and verify.sh, and keep grinding until the check is green.
Or if I'm in the terminal: pnpm exec agent-loop-setup then pnpm exec agent-loop-prompt --out .cursor/loops/<task>.
Manual fallback: pnpm exec agent-loop-init and edit GOAL.md + verify.sh yourself.
5. Start or resume the loop:
pnpm exec agent-loop run .cursor/loops/<task> --runtime <cursor|cline|opencode|pi|codex|dsh|muse|claude> --review-gate
6. Review skill: blockers come back for the next iteration. Advisory is my call. Don't loop on subjective taste.

Cursor example (swap the SDK, key, and --runtime if this machine isn't Cursor):

pnpm add -D @dancingteeth/agent-looper @cursor/sdk

export CURSOR_API_KEY=… # or: doppler run -- …
export CURSOR_API_KEY=…

pnpm exec agent-loop-setup
pnpm exec agent-loop-prompt --out .cursor/loops/my-task
# or: pnpm exec agent-loop-init and edit GOAL.md + verify.sh yourself
# or manually: pnpm exec agent-loop-init and edit GOAL.md + verify.sh

pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate
```
Expand All @@ -92,11 +99,11 @@ pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate
pnpm add -D @dancingteeth/agent-looper @cursor/sdk
# keep @dancingteeth/agent-looper in package.json even if .cursor/loops is gitignored — don't only npx it

export CURSOR_API_KEY=… # or: doppler run -- …
export CURSOR_API_KEY=…

pnpm exec agent-loop-setup
pnpm exec agent-loop-prompt --out .cursor/loops/my-task
# describe your idea; the judge drafts GOAL.md + verify.sh — confirm freeze, then watch
# or: pnpm exec agent-loop-init and edit GOAL.md + verify.sh until `bash .cursor/loops/my-task/verify.sh` is honest
# or manually: pnpm exec agent-loop-init and edit GOAL.md + verify.sh

pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate
```
Expand Down
2 changes: 1 addition & 1 deletion site/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ When to use Agent Looper: a human wants a feature finished without babysitting C

When not to use Agent Looper: there is no determined check (pure taste with no script or vision gate); you need a team-ops factory, shared org cloud, or multi-repo orchestration; you want the model to grade itself as “done.”

How an agent should call it: install `@dancingteeth/agent-looper`, prefer `pnpm exec agent-loop-prompt --out .cursor/loops/<task>` (describe the idea; judge drafts GOAL/verify; confirm freeze) or run `pnpm exec agent-loop-init` and edit `GOAL.md` and `verify.sh`, then `pnpm exec agent-loop run .cursor/loops/<task> --runtime <cursor|cline|opencode|pi|codex|dsh|muse|claude>`. Optional `--review-gate` re-opens the loop only on blocking review findings. CLI binary: `agent-loop`.
How an agent should call it: install `@dancingteeth/agent-looper`, ask the human what they want, then implement the feature with Agent Looper (set up the loop, write GOAL.md and verify.sh, run until green). Or from the terminal: `pnpm exec agent-loop-setup` then `pnpm exec agent-loop-prompt --out .cursor/loops/<task>`, then `pnpm exec agent-loop run .cursor/loops/<task> --runtime <cursor|cline|opencode|pi|codex|dsh|muse|claude>`. Optional `--review-gate` re-opens the loop only on blocking review findings. CLI binary: `agent-loop`.

## Developer resources

Expand Down
33 changes: 29 additions & 4 deletions src/site/landingAgentReadiness.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,10 @@ describe('landing agent readiness', () => {
'# keep @dancingteeth/agent-looper in package.json even if .cursor/loops is gitignored',
)
expect(humanSnippet).toContain("don't only npx it")
expect(humanSnippet).toContain('export CURSOR_API_KEY=… # or: doppler run -- …')
expect(humanSnippet).toContain('export CURSOR_API_KEY=…')
expect(humanSnippet).toContain('pnpm exec agent-loop-setup')
expect(humanSnippet).toContain('pnpm exec agent-loop-prompt --out .cursor/loops/my-task')
expect(humanSnippet).not.toContain('doppler')
expect(humanSnippet).toContain(
'pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate',
)
Expand All @@ -198,6 +200,7 @@ describe('landing agent readiness', () => {
expect(md).toContain(
'# keep @dancingteeth/agent-looper in package.json even if .cursor/loops is gitignored',
)
expect(md).toContain('pnpm exec agent-loop-setup')
expect(md).toContain('pnpm exec agent-loop-prompt --out .cursor/loops/my-task')
expect(md).toContain('<cursor|cline|opencode|pi|codex|dsh|muse|claude>')
expect(md).not.toContain('@0.5.0')
Expand Down Expand Up @@ -314,7 +317,7 @@ describe('landing agent readiness', () => {
expect(html).toContain('tui-answer--spend')
})

it('ships 0.5.0 story: prompt TUI, Claude, Muse 1.3, list/billed spend, no version pins', () => {
it('ships prompt FAQ with agent + terminal paths, Claude, Muse 1.3, list/billed spend, no version pins', () => {
const html = readSite('index.html')
const md = readSite('index.md')
const harnessHtml = readSite('harnesses/index.html')
Expand All @@ -340,20 +343,39 @@ describe('landing agent readiness', () => {
(q) => q.name === 'What do the spend numbers mean?',
)

const agentPathBeat = 'with Agent Looper'
const setupBeat = 'agent-loop-setup'
const promptBeat = 'agent-loop-prompt'
const spendBeat = 'public API rates, including prompt-cache'
const runtimeUnion = 'cursor|cline|opencode|pi|codex|dsh|muse|claude'

for (const surface of [html, md] as const) {
expect(surface).toContain(agentPathBeat)
expect(surface).toContain(setupBeat)
expect(surface).toContain(promptBeat)
expect(surface).toContain(spendBeat)
expect(surface).toContain(runtimeUnion)
expect(surface).not.toContain('@0.5.0')
expect(surface).not.toMatch(/@dancingteeth\/agent-looper@/)
}

expect(promptQuestion?.acceptedAnswer?.text).toContain('judge (not the worker)')
expect(promptQuestion?.acceptedAnswer?.text).toContain('agent-loop run')
const promptFaqSurfaces = [
html.slice(
html.indexOf('tui-answer--prompt'),
html.indexOf('tui-answer--spend'),
),
md.slice(md.indexOf('## How do I start a loop from an idea?'), md.indexOf('## What do the spend numbers mean?')),
promptQuestion?.acceptedAnswer?.text ?? '',
]
for (const surface of promptFaqSurfaces) {
expect(surface).toMatch(/coding agent.*logo/i)
expect(surface).toContain(agentPathBeat)
expect(surface).toContain(setupBeat)
expect(surface).toContain(promptBeat)
expect(surface).not.toMatch(/\bInk\b/i)
expect(surface).not.toMatch(/\bDoppler\b/i)
}

expect(spendQuestion?.acceptedAnswer?.text).toContain('billed')
expect(spendQuestion?.acceptedAnswer?.text).toContain('not free')

Expand All @@ -379,8 +401,11 @@ describe('landing agent readiness', () => {
html.indexOf('id="install-panel-agent"'),
html.indexOf('id="install-panel-human"'),
)
expect(agentPanel).toContain('implement it with Agent Looper')
expect(agentPanel).toContain('pnpm exec agent-loop-setup')
expect(agentPanel).toContain('pnpm exec agent-loop-prompt --out .cursor/loops/')
expect(agentPanel).toContain(runtimeUnion)
expect(agentPanel).not.toMatch(/\bDoppler\b/i)
})

it('Claude runtime card describes judge as optional without MCP on the site', () => {
Expand Down
Loading