minimal-agent 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +4 -5
  2. package/package.json +1 -1
  3. package/plugins/workflow-runner/plugin.js +1 -0
  4. package/plugins/workflow-runner/src/agentCommon.js +82 -47
  5. package/plugins/workflow-runner/src/expressions.js +48 -2
  6. package/plugins/workflow-runner/src/index.js +1 -0
  7. package/plugins/workflow-runner/src/jsonPayload.js +1 -1
  8. package/plugins/workflow-runner/src/loader.js +70 -8
  9. package/plugins/workflow-runner/src/recovery.js +43 -35
  10. package/plugins/workflow-runner/src/runner.js +143 -34
  11. package/plugins/workflow-runner/src/stepExecutors/agent.js +64 -35
  12. package/plugins/workflow-runner/src/stepExecutors/assert.js +14 -2
  13. package/plugins/workflow-runner/src/stepExecutors/llm.js +48 -107
  14. package/plugins/workflow-runner/src/stepExecutors/skill.js +50 -39
  15. package/plugins/workflow-runner/src/stepExecutors/tool.js +20 -7
  16. package/plugins/workflow-runner/src/stepExecutors/verify.js +11 -3
  17. package/plugins/workflow-runner/src/taskIdentity.js +141 -0
  18. package/plugins/workflow-runner/src/types.js +1 -2
  19. package/plugins/workflow-runner/src/workflowState.js +211 -28
  20. package/skills/adversarial-review/SKILL.md +0 -1
  21. package/skills/pptx/scripts/office/__pycache__/soffice.cpython-314.pyc +0 -0
  22. package/src/askBridge.js +10 -0
  23. package/src/context/archive.js +4 -0
  24. package/src/infra/verification.js +25 -13
  25. package/src/llm/client.js +160 -12
  26. package/src/loop.js +15 -12
  27. package/src/plugins/pluginLoader.js +2 -1
  28. package/src/plugins/pluginRunner.js +9 -21
  29. package/src/prompts/pluginList.js +5 -5
  30. package/src/prompts/promptAssembly.js +3 -38
  31. package/src/prompts/skillList.js +1 -1
  32. package/src/prompts/system.js +0 -1
  33. package/src/ui/AskQuestion.js +20 -3
  34. package/src/ui/InputBox.js +70 -3
  35. package/src/ui/hooks/useChat.js +13 -0
  36. package/workflows/adaptive-research.yaml +4 -3
  37. package/workflows/book-review-short.yaml +5 -3
  38. package/workflows/e2e-write-greet.yaml +3 -2
  39. package/workflows/plan.yaml +219 -168
  40. package/workflows/ralph-loop.yaml +169 -0
  41. package/workflows/youtube-shorts.yaml +8 -5
  42. package/plugins/HOW-TO-WRITE-A-PLUGIN.md +0 -186
  43. package/plugins/ralph-wiggum/.claude-plugin/plugin.json +0 -9
  44. package/plugins/ralph-wiggum/README.md +0 -197
  45. package/plugins/ralph-wiggum/commands/cancel-ralph.md +0 -18
  46. package/plugins/ralph-wiggum/commands/help.md +0 -137
  47. package/plugins/ralph-wiggum/commands/ralph-loop.md +0 -85
  48. package/plugins/ralph-wiggum/hooks/hooks.json +0 -15
  49. package/plugins/ralph-wiggum/hooks/stop-hook.sh +0 -191
  50. package/plugins/ralph-wiggum/plugin.js +0 -280
  51. package/plugins/ralph-wiggum/src/goalState.js +0 -258
  52. package/plugins/ralph-wiggum/src/sentinels.js +0 -76
  53. package/plugins/ralph-wiggum/src/stopHookRunner.js +0 -104
  54. package/plugins/ralph-wiggum/src/verificationGate.js +0 -202
  55. package/plugins/workflow-runner/src/miniReAct.js +0 -223
@@ -0,0 +1,169 @@
1
+ name: ralph-loop
2
+ description: |
3
+ Ralph Wiggum 迭代开发循环——通过重复执行同一目标直到完成。
4
+
5
+ 等价于原 ralph-wiggum 插件的 /ralph-loop 命令,完全用声明式工作流实现。
6
+ 核心机制:while 循环 + fresh context(每轮重置 history)+ 哨兵协议 + 验证门。
7
+
8
+ 用法:/workflow ralph-loop "你的目标" --max-iterations 50 --verify "shell:bun test"
9
+ inputs:
10
+ - name: goal
11
+ type: string
12
+ required: true
13
+ description: "不可变目标描述(如'实现用户认证模块并确保测试通过')"
14
+ - name: max_iterations
15
+ type: number
16
+ default: 50
17
+ description: "最大迭代次数(安全阀,默认 50,硬上限 200)"
18
+ - name: verify_checks
19
+ type: string
20
+ default: ""
21
+ description: "验证门检查项(逗号分隔,如 'shell:bun test,file_exists:src/index.ts')。空则跳过验证门。"
22
+
23
+ steps:
24
+ # === 初始化阶段变量 ===
25
+ - id: init_phase
26
+ llm: "PLAN"
27
+ capture:
28
+ result: phase
29
+
30
+ # === 初始化教训记录文件(fresh context 下跨轮存活) ===
31
+ - id: init_learnings
32
+ tool: "Write(file_path='.minimal-agent-workflow/learnings.md', content='')"
33
+ onError: continue
34
+
35
+ # ============================================================
36
+ # 主迭代循环(while 模式 + fresh_context)
37
+ # 每轮:构造 prompt → agent 工作 → 哨兵检测 → 阶段推进
38
+ # ============================================================
39
+ - type: loop
40
+ id: main_loop
41
+ max_iterations: "${max_iterations}"
42
+ fresh_context: true
43
+ do:
44
+ # --- 1. 读取上轮教训 ---
45
+ - id: read_learnings
46
+ tool: "Read(file_path='.minimal-agent-workflow/learnings.md')"
47
+ capture:
48
+ text: learnings_text
49
+ onError: continue
50
+
51
+ # --- 2. 构造本轮 prompt(含目标、阶段、通信协议、教训) ---
52
+ - id: build_prompt
53
+ llm: |
54
+ # 不可变目标 (IMMUTABLE GOAL)
55
+ ${goal}
56
+ ⚠️ 你不能修改或扩大上述目标。
57
+
58
+ # 当前阶段: ${phase.toUpperCase()}
59
+ ${phase == 'PLAN' ? '分析任务、拆解步骤、识别风险与未知项;先想清楚再动手。' :
60
+ phase == 'BUILD' ? '按计划实现,一次只聚焦一个子任务,落到具体文件改动。' :
61
+ phase == 'VERIFY' ? '运行测试/检查输出/核对验收标准,用证据确认,别凭感觉。' :
62
+ phase == 'HEAL' ? '已多次验证失败:停止猜测,定位根因再修,避免回归。' :
63
+ '目标已达成。'}
64
+
65
+ # 与循环驱动的通信协议(务必遵守)
66
+ - 任务**真正完成**时输出 `<promise>DONE</promise>`(驱动会运行验证门)
67
+ - 当前方案走不通、要换打法时输出 `<PROMISE>NEED_REPLAN</PROMISE>`(回 PLAN)
68
+ - **目标本身**有问题时输出 `<PROMISE>NEED_GOAL_REVISION</PROMISE>`(干净终止)
69
+ - 踩到的坑用 `<learning>一句话</learning>` 标记(驱动自动存档供后续参考)
70
+ ⚠️ 切勿为逃出循环而谎报完成——只有陈述完全为真时才输出完成哨兵。
71
+
72
+ ${learnings_text && learnings_text != '' ? '# 关键教训(必须遵守,避免重复踩坑)\n' + learnings_text : ''}
73
+
74
+ ---
75
+ 本轮任务 (迭代 ${_iter})
76
+ capture:
77
+ result: prompt_text
78
+
79
+ # --- 3. 执行 agent 工作(TAOR 引擎,有工具能力) ---
80
+ - id: work
81
+ agent: "${prompt_text}"
82
+ maxTurns: 15
83
+ capture:
84
+ text: output
85
+
86
+ # --- 4. 提取 learning 并持久化 ---
87
+ - id: extract_learning
88
+ llm: |
89
+ 从以下文本中提取所有 <learning>...</learning> 内容,每行一条原样输出。
90
+ 如果没有 learning 标签,输出空字符串。
91
+
92
+ 文本:
93
+ ${output}
94
+ capture:
95
+ text: extracted_learning
96
+
97
+ - id: save_learning
98
+ tool: "Bash(command='cat >> .minimal-agent-workflow/learnings.md << EOF\n${extracted_learning}\nEOF')"
99
+ when: "extracted_learning != ''"
100
+ onError: continue
101
+
102
+ # --- 5. 哵兵检测与分支处理 ---
103
+
104
+ # 5a. 是否包含任何哨兵标签?
105
+ - id: has_sentinel
106
+ type: branch
107
+ condition: "includes(output, '<promise>') || includes(output, '<PROMISE>') || includes(output, '<learning>')"
108
+ then:
109
+ # 有哨兵标签 → 判断具体类型
110
+
111
+ # 5a-i. 完成哨兵?
112
+ - id: check_complete
113
+ type: branch
114
+ condition: |
115
+ includes(lower(output), '<promise>') &&
116
+ (includes(lower(output), 'done') ||
117
+ includes(lower(output), 'complete') ||
118
+ includes(lower(output), 'goal_complete'))
119
+ then:
120
+ # === DONE 哨兵 → 验证门 ===
121
+ - id: run_verify
122
+ type: verify
123
+ checks: "${verify_checks}"
124
+ when: "verify_checks != ''"
125
+ onFail: "验证未通过,回到 BUILD 继续"
126
+ onError: continue
127
+ # 验证通过或无验证门 → 设置完成阶段并跳出循环
128
+ - id: set_done
129
+ llm: "DONE"
130
+ capture:
131
+ result: phase
132
+ - id: exit_success
133
+ type: break
134
+ else:
135
+ # 非 DONE 哨兵 → NEED_REPLAN 或 NEED_GOAL_REVISION
136
+ - id: check_replan
137
+ type: branch
138
+ condition: "includes(output, 'NEED_REPLAN')"
139
+ then:
140
+ # 回到 PLAN
141
+ - id: replan
142
+ llm: "PLAN"
143
+ capture:
144
+ result: phase
145
+ else:
146
+ # NEED_GOAL_REVISION → 终止循环
147
+ - id: goal_revision_exit
148
+ llm: "DONE"
149
+ capture:
150
+ result: phase
151
+ - id: exit_goal_revision
152
+ type: break
153
+
154
+ # 5b. 无哨兵 → 自动阶段推进
155
+ - id: auto_advance
156
+ type: branch
157
+ condition: "phase == 'PLAN' && _iter >= 1"
158
+ then:
159
+ - id: to_build
160
+ llm: "BUILD"
161
+ capture:
162
+ result: phase
163
+
164
+ # === 循环结束后的收尾 ===
165
+ - id: final_summary
166
+ llm: |
167
+ 总结本轮 ralph-loop 的执行结果。如果目标是完成的,列出关键产出物。
168
+ 如果是因达到迭代上限而退出,说明当前进度和下一步建议。
169
+ maxTurns: 1
@@ -69,8 +69,10 @@ steps:
69
69
  content: parse_log
70
70
 
71
71
  - id: assert_script_parsed
72
- type: assert
73
- condition: 'fileExists("./assets/prompts.txt") && fileExists("./assets/narrations.txt")'
72
+ type: verify
73
+ checks:
74
+ - 'file_exists:./assets/prompts.txt'
75
+ - 'file_exists:./assets/narrations.txt'
74
76
  onFail: "脚本解析失败:./assets/prompts.txt 或 ./assets/narrations.txt 不存在"
75
77
 
76
78
  # ---------- 4. 生成 5 张配图(loop 静态数组 + 每轮先读对应一行 prompt) ----------
@@ -149,10 +151,11 @@ steps:
149
151
  skill: video-compose
150
152
  input: 'images_glob=./assets/img_*.png audio=./assets/audio.mp3 srt=./assets/subs.srt output=./out/shorts.mp4 width=${inputs.width} height=${inputs.height}'
151
153
 
152
- # ---------- 11. 守门 assert ----------
154
+ # ---------- 11. 守门 verify(升级自 assert) ----------
153
155
  - id: verify_output
154
- type: assert
155
- condition: 'fileExists("./out/shorts.mp4")'
156
+ type: verify
157
+ checks:
158
+ - 'file_exists:./out/shorts.mp4'
156
159
  onFail: "最终视频 ./out/shorts.mp4 未生成,请检查 video-compose 日志"
157
160
 
158
161
  __meta:
@@ -1,186 +0,0 @@
1
- # How to Write a minimal-agent Plugin
2
-
3
- minimal-agent 的插件系统遵循 **drop-in** 原则:把目录扔进 `plugins/`,命令立即可用,**`src/` 一行不改**。
4
-
5
- ## 两种契约
6
-
7
- ### 1. 纯声明式(Anthropic 兼容,零 TS)
8
-
9
- 最小可用插件 = 一个 frontmatter 模板。框架替你拼 prompt 喂给 LLM。
10
-
11
- ```
12
- plugins/hello-bot/
13
- ├── .claude-plugin/
14
- │ └── plugin.json
15
- └── commands/
16
- └── hi.md
17
- ```
18
-
19
- **`.claude-plugin/plugin.json`**
20
-
21
- ```json
22
- {
23
- "name": "hello-bot",
24
- "version": "0.1.0",
25
- "description": "Greets the user"
26
- }
27
- ```
28
-
29
- **`commands/hi.md`**
30
-
31
- ```markdown
32
- ---
33
- description: "Greet the user"
34
- argument-hint: "<name>"
35
- ---
36
-
37
- 你好 $ARGUMENTS!欢迎使用 minimal-agent。
38
- ```
39
-
40
- **效果**:用户输入 `/hi 世界` → LLM 收到 `你好 世界!欢迎使用 minimal-agent。\n\n用户参数: 世界`。
41
-
42
- 支持的占位符:
43
- - `$ARGUMENTS` / `${ARGUMENTS}` —— 用户在命令名后的全部文本
44
- - `${CLAUDE_PLUGIN_ROOT}` —— 该插件目录的绝对路径(用于引用插件资源)
45
-
46
- ### 2. 声明式 + `plugin.ts`(富插件)
47
-
48
- 当模板不够(要跑循环 / 做 TS 校验 / 启动子进程 / 状态机),加一个 `plugin.ts`:
49
-
50
- ```
51
- plugins/echo-bot/
52
- ├── .claude-plugin/plugin.json
53
- ├── commands/echo.md # 仍要存在!frontmatter 用于 listAvailableCommands
54
- └── plugin.ts # PluginApi default export
55
- ```
56
-
57
- **`plugin.ts`**
58
-
59
- ```typescript
60
- import {
61
- runQuery,
62
- type PluginApi,
63
- type LoopEvent,
64
- } from '../../src/plugin-sdk.ts';
65
-
66
- const api: PluginApi = {
67
- async *runCommand(commandName, args, ctx): AsyncGenerator<LoopEvent> {
68
- if (commandName === 'echo') {
69
- // 直接 yield 自定义事件
70
- yield { type: 'text', delta: `你输入了:${args}` };
71
- yield { type: 'turn_done' };
72
- return;
73
- }
74
-
75
- // 或者改写 prompt 后丢给 LLM
76
- yield* runQuery(`请把以下内容重复 3 遍:${args}`, {
77
- provider: ctx.provider,
78
- history: ctx.history,
79
- signal: ctx.signal,
80
- });
81
- },
82
- };
83
-
84
- export default api;
85
- ```
86
-
87
- **框架行为**:命中 `/echo abc` 时,`pluginRunner` 优先调用 `runCommand('echo', 'abc', ctx)`,不再走声明式 fallback。你完全接管事件流。
88
-
89
- ## `plugin-sdk.ts` 暴露的全部 API
90
-
91
- **唯一稳定 import 路径**:`from '../../src/plugin-sdk.ts'`(相对你的 `plugin.ts`)。
92
-
93
- | 名称 | 类型 | 用途 |
94
- |------|------|------|
95
- | `runQuery(input, opts)` | function | 标准 T-A-O-R 循环,AsyncGenerator |
96
- | `chat(messages, provider, opts)` | function | 单次非流式 LLM 调用 |
97
- | `executeTool(name, argsJson, ctx)` | function | 框架级工具调用入口 |
98
- | `getToolByName(name)` | function | 取 Tool 定义 |
99
- | `ALL_TOOLS` | const | 所有内置工具数组 |
100
- | `getWorkingDir()` | function | 当前锁定的工作目录 |
101
- | `getResourceSearchPaths(name, importMetaUrl)` | function | 双源资源路径(cwd + packageRoot) |
102
- | `triggerHook(event, payload)` | function | 触发框架级 hook |
103
- | `createSessionState()` | function | 新建 SessionState |
104
- | `Message` / `Provider` / `LoopEvent` / `LlmStreamEvent` | type | 协议类型 |
105
- | `Tool` / `ToolCall` / `ToolResult` | type | 工具协议类型 |
106
- | `PluginApi` / `PluginContext` | type | 你的 plugin.ts 契约 |
107
- | `ResourceName` / `HookEventName` / `HookDecision` / `SessionState` | type | 杂项 |
108
-
109
- **不要**绕开 `plugin-sdk.ts` 直接 import `src/loop.ts` / `src/llm/client.ts` 等内部路径 —— 那些路径不是稳定 API,框架重构时会破坏你的插件。
110
-
111
- ## `PluginContext`
112
-
113
- `runCommand` 收到的 ctx:
114
-
115
- ```typescript
116
- interface PluginContext {
117
- provider: Provider; // 当前 LLM provider 配置
118
- history: Message[]; // 对话历史(你可以读 / 修改 / 替换)
119
- signal?: AbortSignal; // 用户 ESC / Ctrl+C 时触发
120
- sessionState?: SessionState; // 可选共享 session 状态
121
- maxTurns?: number; // 工具循环最大轮数(runQuery 透传用)
122
- }
123
- ```
124
-
125
- ## 事件 (`LoopEvent`)
126
-
127
- 你的 `runCommand` 必须 yield `LoopEvent`,UI 据此渲染。常用的有:
128
-
129
- | type | 字段 | 用途 |
130
- |------|------|------|
131
- | `text` | `delta: string` | 流式文本片段 |
132
- | `assistant_message` | (无) | 一次完整 assistant 消息已 push 进 history |
133
- | `tool_start` | `toolName`, `argsPreview` | 工具开始执行 |
134
- | `tool_end` | (无) | 工具结束 |
135
- | `turn_done` | (无) | 整轮交互结束 |
136
- | `interrupted` | (无) | 用户中断 |
137
- | `error` | `error: string` | 红色错误提示 |
138
- | `plugin_progress` | `pluginId`, `current`, `max?`, `message?` | 循环进度条(替代旧的 plugin_start / plugin_iteration) |
139
-
140
- 通常做法:复杂插件直接 `yield* runQuery(...)` 透传所有事件,自己额外 yield `plugin_progress` 做进度展示。
141
-
142
- ## 工作目录与持久化
143
-
144
- - 状态写到 `getWorkingDir()/.minimal-agent-<your-plugin-id>/` 下,避免污染主 context 目录
145
- - `/new` 命令会自动清这些 `.minimal-agent*` 目录,你不用管 cleanup
146
- - 跨平台:Windows 没 bash,hooks/*.sh 静默跳过;其它 .ts 代码完全平台无关
147
-
148
- ## 命令默认值
149
-
150
- 框架**不再**注入命令默认参数(旧版 `COMMAND_DEFAULTS` 已删除)。如果你的命令需要默认值(如 `--max-iterations 50`),自己在 `plugin.ts` 里解析 args 时兜底。这样默认值的语义属于插件契约,不属于框架。
151
-
152
- ## 测试
153
-
154
- - 把测试放在 `plugins/<id>/test/*.test.ts`
155
- - `bunfig.toml` 的 `[test].root = ["./test", "./plugins"]` 让 `bun test` 自动发现
156
- - 测试里 mock LLM / 工具时,用 `mock.module('../../../src/loop.ts', ...)` 等绝对到 src 的相对路径
157
-
158
- ## 参考实现
159
-
160
- - **声明式 + plugin.ts 简单例**:`plugins/workflow-runner/plugin.ts`(~25 行接管 `/workflow` 与 `/workflows`)
161
- - **重型循环例**:`plugins/ralph-wiggum/plugin.ts`(~270 行 do-while loop + FSM + sentinel + verification + stop-hook)
162
-
163
- ## Transcript 与 Hook:当前状态
164
-
165
- 框架提供了两套基础设施 —— 都**就绪、有测试、可独立调用**,但**主循环 `src/loop.ts` 不自动触发**:
166
-
167
- | 模块 | 暴露 | 当前主循环触发? |
168
- |------|------|------|
169
- | `src/plugins/transcript.ts` | `initTranscript / appendUserMessage / appendAssistantMessage / appendToolResult` | 否 |
170
- | `src/plugins/hookEngine.ts` | `loadHooks / triggerHook('UserPromptSubmit' \| 'PreToolUse' \| 'PostToolUse' \| 'SessionStart' \| 'SessionEnd', payload)` | 否 |
171
-
172
- **插件如何使用**:
173
- - 想写自己的 JSONL transcript → 在 `runCommand` 内 `import { initTranscript, appendUserMessage } from '../../src/plugin-sdk.ts'` 自己调
174
- - 想响应 hook 事件 → 在 `runCommand` 内 `triggerHook('PreToolUse', { tool_name, ... })` 自己调;ralph-wiggum 走的就是这条路(vendored stop-hook 执行器在 `plugins/ralph-wiggum/src/stopHookRunner.ts`)
175
-
176
- **为什么不在主循环自动触发**:当前没有 Anthropic 风格 `hooks/*.sh` 的真实用例驱动;自动触发会改主循环热路径但不解决实际问题。等真有跨插件的全局 hook 需求时再接也不迟。届时只需在 `src/loop.ts` 的 user/assistant/tool 三处 push 点加 `appendXxx` 与 `triggerHook` 调用即可,**不影响插件契约**。
177
-
178
- ## 不支持的 Anthropic 字段
179
-
180
- minimal-agent 的插件契约是 Anthropic 上游的**子集**。当前未实现的字段:
181
-
182
- - `mcp-servers/` —— MCP 服务器配置
183
- - `agents/` —— 子 agent 定义
184
- - `skills/` 在插件目录下 —— minimal-agent 的 skill 系统是独立顶层目录
185
-
186
- 未实现字段在 plugin.json 中存在不会报错,但被忽略。
@@ -1,9 +0,0 @@
1
- {
2
- "name": "ralph-wiggum",
3
- "version": "1.0.0",
4
- "description": "Implementation of the Ralph Wiggum technique - continuous self-referential AI loops for interactive iterative development. Run Claude in a while-true loop with the same prompt until task completion.",
5
- "author": {
6
- "name": "Daisy Hollman",
7
- "email": "daisy@anthropic.com"
8
- }
9
- }
@@ -1,197 +0,0 @@
1
- # Ralph Wiggum Plugin
2
-
3
- Implementation of the Ralph Wiggum technique for iterative, self-referential AI development loops in Minimal Agent.
4
-
5
- ## What is Ralph?
6
-
7
- Ralph is a development methodology based on continuous AI agent loops. As Geoffrey Huntley describes it: **"Ralph is a Bash loop"** - a simple `while true` that repeatedly feeds an AI agent a prompt file, allowing it to iteratively improve its work until completion.
8
-
9
- The technique is named after Ralph Wiggum from The Simpsons, embodying the philosophy of persistent iteration despite setbacks.
10
-
11
- ### Core Concept
12
-
13
- This plugin implements Ralph using a **Stop hook** that intercepts Minimal Agent's exit attempts:
14
-
15
- ```bash
16
- # You run ONCE:
17
- /ralph-loop "Your task description" --completion-promise "DONE"
18
-
19
- # Then Claude Code automatically:
20
- # 1. Works on the task
21
- # 2. Tries to exit
22
- # 3. Stop hook blocks exit
23
- # 4. Stop hook feeds the SAME prompt back
24
- # 5. Repeat until completion
25
- ```
26
-
27
- The loop happens **inside your current session** - you don't need external bash loops. The Stop hook in `hooks/stop-hook.sh` creates the self-referential feedback loop by blocking normal session exit.
28
-
29
- This creates a **self-referential feedback loop** where:
30
- - The prompt never changes between iterations
31
- - Claude's previous work persists in files
32
- - Each iteration sees modified files and git history
33
- - Claude autonomously improves by reading its own past work in files
34
-
35
- ## Quick Start
36
-
37
- ```bash
38
- /ralph-loop "Build a REST API for todos. Requirements: CRUD operations, input validation, tests. Output <promise>COMPLETE</promise> when done." --completion-promise "COMPLETE" --max-iterations 50
39
- ```
40
-
41
- Claude will:
42
- - Implement the API iteratively
43
- - Run tests and see failures
44
- - Fix bugs based on test output
45
- - Iterate until all requirements met
46
- - Output the completion promise when done
47
-
48
- ## Commands
49
-
50
- ### /ralph-loop
51
-
52
- Start a Ralph loop in your current session.
53
-
54
- **Usage:**
55
- ```bash
56
- /ralph-loop "<prompt>" --max-iterations <n> --completion-promise "<text>"
57
- ```
58
-
59
- **Options:**
60
- - `--max-iterations <n>` - Stop after N iterations (default: 50, hard cap: 200)
61
- - `--completion-promise <text>` - Phrase that signals completion (natively active; default: DONE / COMPLETE / GOAL_COMPLETE)
62
- - `--verify "<CHECK>"` - Completion gate run after the promise tag. All checks must pass before the loop exits. Repeatable.
63
- - `shell:<cmd>` — exit code 0 = pass (Windows: `cmd /c`, others: `bash -c`)
64
- - `file_exists:<path>` — file must exist
65
- - `file_contains:<file>:<regex>` — file content matches regex
66
- - `test_count:<min>` — `bun test` pass count ≥ min
67
-
68
- Example:
69
- ```bash
70
- /ralph-loop "Implement and test cache layer" \
71
- --verify "shell:bun test" \
72
- --verify "file_exists:dist/index.js"
73
- ```
74
-
75
- ### /cancel-ralph
76
-
77
- Cancel the active Ralph loop.
78
-
79
- **Usage:**
80
- ```bash
81
- /cancel-ralph
82
- ```
83
-
84
- ## Prompt Writing Best Practices
85
-
86
- ### 1. Clear Completion Criteria
87
-
88
- ❌ Bad: "Build a todo API and make it good."
89
-
90
- ✅ Good:
91
- ```markdown
92
- Build a REST API for todos.
93
-
94
- When complete:
95
- - All CRUD endpoints working
96
- - Input validation in place
97
- - Tests passing (coverage > 80%)
98
- - README with API docs
99
- - Output: <promise>COMPLETE</promise>
100
- ```
101
-
102
- ### 2. Incremental Goals
103
-
104
- ❌ Bad: "Create a complete e-commerce platform."
105
-
106
- ✅ Good:
107
- ```markdown
108
- Phase 1: User authentication (JWT, tests)
109
- Phase 2: Product catalog (list/search, tests)
110
- Phase 3: Shopping cart (add/remove, tests)
111
-
112
- Output <promise>COMPLETE</promise> when all phases done.
113
- ```
114
-
115
- ### 3. Self-Correction
116
-
117
- ❌ Bad: "Write code for feature X."
118
-
119
- ✅ Good:
120
- ```markdown
121
- Implement feature X following TDD:
122
- 1. Write failing tests
123
- 2. Implement feature
124
- 3. Run tests
125
- 4. If any fail, debug and fix
126
- 5. Refactor if needed
127
- 6. Repeat until all green
128
- 7. Output: <promise>COMPLETE</promise>
129
- ```
130
-
131
- Tag lessons inline with `<learning>…</learning>` — the driver archives them to `learnings.md` automatically, so subsequent iterations inherit the hard-won knowledge without repeating mistakes.
132
-
133
- ### 4. Escape Hatches
134
-
135
- Always use `--max-iterations` as a safety net to prevent infinite loops on impossible tasks:
136
-
137
- ```bash
138
- # Recommended: Always set a reasonable iteration limit
139
- /ralph-loop "Try to implement feature X" --max-iterations 20
140
-
141
- # In your prompt, include what to do if stuck:
142
- # "After 15 iterations, if not complete:
143
- # - Document what's blocking progress
144
- # - List what was attempted
145
- # - Suggest alternative approaches"
146
- ```
147
-
148
- Claude can also signal early exit using two distinct tags:
149
- - `<PROMISE>NEED_REPLAN</PROMISE>` — current approach is unworkable; loop returns to PLAN with the same goal
150
- - `<PROMISE>NEED_GOAL_REVISION</PROMISE>` — the goal itself is unreachable; loop stops cleanly for human review. Use this when no approach can work, not just the current one.
151
-
152
- **Note**: The `--completion-promise` uses exact string matching and is natively active (no external stop-hook required). It signals Claude's intent to complete; use `--verify` checks for objective verification of that intent.
153
-
154
- ## Philosophy
155
-
156
- Ralph embodies several key principles:
157
-
158
- ### 1. Iteration > Perfection
159
- Don't aim for perfect on first try. Let the loop refine the work.
160
-
161
- ### 2. Failures Are Data
162
- "Deterministically bad" means failures are predictable and informative. Use them to tune prompts.
163
-
164
- ### 3. Operator Skill Matters
165
- Success depends on writing good prompts, not just having a good model.
166
-
167
- ### 4. Persistence Wins
168
- Keep trying until success. The loop handles retry logic automatically.
169
-
170
- ## When to Use Ralph
171
-
172
- **Good for:**
173
- - Well-defined tasks with clear success criteria
174
- - Tasks requiring iteration and refinement (e.g., getting tests to pass)
175
- - Greenfield projects where you can walk away
176
- - Tasks with automatic verification (tests, linters)
177
-
178
- **Not good for:**
179
- - Tasks requiring human judgment or design decisions
180
- - One-shot operations
181
- - Tasks with unclear success criteria
182
- - Production debugging (use targeted debugging instead)
183
-
184
- ## Real-World Results
185
-
186
- - Successfully generated 6 repositories overnight in Y Combinator hackathon testing
187
- - One $50k contract completed for $297 in API costs
188
- - Created entire programming language ("cursed") over 3 months using this approach
189
-
190
- ## Learn More
191
-
192
- - Original technique: https://ghuntley.com/ralph/
193
- - Ralph Orchestrator: https://github.com/mikeyobrien/ralph-orchestrator
194
-
195
- ## For Help
196
-
197
- Run `/help` in Claude Code for detailed command reference and examples.
@@ -1,18 +0,0 @@
1
- ---
2
- description: "Cancel active Ralph Wiggum loop"
3
- allowed-tools: ["Bash(test -f .minimal-agent/ralph-loop.local.md:*)", "Bash(rm .minimal-agent/ralph-loop.local.md)", "Read(.minimal-agent/ralph-loop.local.md)"]
4
- hide-from-slash-command-tool: "true"
5
- ---
6
-
7
- # Cancel Ralph
8
-
9
- To cancel the Ralph loop:
10
-
11
- 1. Check if `.minimal-agent/ralph-loop.local.md` exists using Bash: `test -f .minimal-agent/ralph-loop.local.md && echo "EXISTS" || echo "NOT_FOUND"`
12
-
13
- 2. **If NOT_FOUND**: Say "No active Ralph loop found."
14
-
15
- 3. **If EXISTS**:
16
- - Read `.minimal-agent/ralph-loop.local.md` to get the current iteration number from the `iteration:` field
17
- - Remove the file using Bash: `rm .minimal-agent/ralph-loop.local.md`
18
- - Report: "Cancelled Ralph loop (was at iteration N)" where N is the iteration value