minimal-agent 0.1.8 → 0.2.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.
- package/README.md +405 -122
- package/dist/main.js +423 -941
- package/package.json +5 -2
- package/plugins/HOW-TO-WRITE-A-PLUGIN.md +186 -0
- package/plugins/ralph-wiggum/.claude-plugin/plugin.json +9 -0
- package/plugins/ralph-wiggum/README.md +179 -0
- package/plugins/ralph-wiggum/commands/cancel-ralph.md +18 -0
- package/plugins/ralph-wiggum/commands/help.md +126 -0
- package/plugins/ralph-wiggum/commands/ralph-loop.md +59 -0
- package/plugins/ralph-wiggum/hooks/hooks.json +15 -0
- package/plugins/ralph-wiggum/hooks/stop-hook.sh +191 -0
- package/plugins/ralph-wiggum/plugin.ts +275 -0
- package/plugins/ralph-wiggum/scripts/setup-ralph-loop.sh +203 -0
- package/plugins/ralph-wiggum/src/goalState.ts +310 -0
- package/plugins/ralph-wiggum/src/sentinels.ts +24 -0
- package/plugins/ralph-wiggum/src/stopHookRunner.ts +136 -0
- package/plugins/ralph-wiggum/src/verificationGate.ts +252 -0
- package/plugins/ralph-wiggum/test/goalState.test.ts +410 -0
- package/plugins/ralph-wiggum/test/verificationGate.test.ts +122 -0
- package/plugins/workflow-runner/.claude-plugin/plugin.json +5 -0
- package/plugins/workflow-runner/commands/workflow.md +15 -0
- package/plugins/workflow-runner/commands/workflows.md +8 -0
- package/plugins/workflow-runner/plugin.ts +42 -0
- package/plugins/workflow-runner/src/expressions.ts +371 -0
- package/plugins/workflow-runner/src/index.ts +194 -0
- package/plugins/workflow-runner/src/loader.ts +193 -0
- package/plugins/workflow-runner/src/runner.ts +313 -0
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +30 -0
- package/plugins/workflow-runner/src/stepExecutors/llm.ts +54 -0
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +115 -0
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +41 -0
- package/plugins/workflow-runner/src/types.ts +183 -0
- package/plugins/workflow-runner/src/workflowState.ts +65 -0
- package/plugins/workflow-runner/test/cli.e2e.test.ts +114 -0
- package/plugins/workflow-runner/test/e2e.test.ts +268 -0
- package/plugins/workflow-runner/test/expressions.test.ts +140 -0
- package/plugins/workflow-runner/test/fixtures/cli-e2e.yaml +27 -0
- package/plugins/workflow-runner/test/fixtures/hello-workflow.yaml +49 -0
- package/plugins/workflow-runner/test/graceful.test.ts +139 -0
- package/plugins/workflow-runner/test/loader.test.ts +216 -0
- package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +230 -0
- package/plugins/workflow-runner/test/runner.test.ts +511 -0
- package/skills/config/SKILL.md +27 -1
- package/skills/image-gen-openrouter/SKILL.md +121 -0
- package/skills/subtitle-srt/SKILL.md +134 -0
- package/skills/tts-zh/SKILL.md +137 -0
- package/skills/video-compose/SKILL.md +139 -0
- package/workflows/book-review-short.yaml +99 -0
- package/workflows/e2e-write-greet.yaml +27 -0
- package/workflows/schema.json +74 -0
- package/workflows/youtube-shorts.yaml +171 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minimal-agent",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "最小化 Agent 系统 —— 单对话 + 10 工具 +
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "最小化 Agent 系统 —— 单对话 + 10 工具 + 插件系统 + workflow DSL + 自动压缩 + OpenAI 兼容 + Ink TUI(学习/教学用)",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Bill Wang <leiwang0359@gmail.com>",
|
|
7
7
|
"repository": {
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
"dist",
|
|
38
38
|
"vendor/ripgrep",
|
|
39
39
|
"skills",
|
|
40
|
+
"plugins",
|
|
41
|
+
"workflows",
|
|
40
42
|
"README.md",
|
|
41
43
|
"LICENSE"
|
|
42
44
|
],
|
|
@@ -53,6 +55,7 @@
|
|
|
53
55
|
"ink": "^5.0.1",
|
|
54
56
|
"react": "^18.3.1",
|
|
55
57
|
"turndown": "^7.2.4",
|
|
58
|
+
"yaml": "^2.9.0",
|
|
56
59
|
"zod": "^3.23.8",
|
|
57
60
|
"zod-to-json-schema": "^3.25.2"
|
|
58
61
|
},
|
|
@@ -0,0 +1,186 @@
|
|
|
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 中存在不会报错,但被忽略。
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
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: unlimited)
|
|
61
|
+
- `--completion-promise <text>` - Phrase that signals completion
|
|
62
|
+
|
|
63
|
+
### /cancel-ralph
|
|
64
|
+
|
|
65
|
+
Cancel the active Ralph loop.
|
|
66
|
+
|
|
67
|
+
**Usage:**
|
|
68
|
+
```bash
|
|
69
|
+
/cancel-ralph
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Prompt Writing Best Practices
|
|
73
|
+
|
|
74
|
+
### 1. Clear Completion Criteria
|
|
75
|
+
|
|
76
|
+
❌ Bad: "Build a todo API and make it good."
|
|
77
|
+
|
|
78
|
+
✅ Good:
|
|
79
|
+
```markdown
|
|
80
|
+
Build a REST API for todos.
|
|
81
|
+
|
|
82
|
+
When complete:
|
|
83
|
+
- All CRUD endpoints working
|
|
84
|
+
- Input validation in place
|
|
85
|
+
- Tests passing (coverage > 80%)
|
|
86
|
+
- README with API docs
|
|
87
|
+
- Output: <promise>COMPLETE</promise>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. Incremental Goals
|
|
91
|
+
|
|
92
|
+
❌ Bad: "Create a complete e-commerce platform."
|
|
93
|
+
|
|
94
|
+
✅ Good:
|
|
95
|
+
```markdown
|
|
96
|
+
Phase 1: User authentication (JWT, tests)
|
|
97
|
+
Phase 2: Product catalog (list/search, tests)
|
|
98
|
+
Phase 3: Shopping cart (add/remove, tests)
|
|
99
|
+
|
|
100
|
+
Output <promise>COMPLETE</promise> when all phases done.
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. Self-Correction
|
|
104
|
+
|
|
105
|
+
❌ Bad: "Write code for feature X."
|
|
106
|
+
|
|
107
|
+
✅ Good:
|
|
108
|
+
```markdown
|
|
109
|
+
Implement feature X following TDD:
|
|
110
|
+
1. Write failing tests
|
|
111
|
+
2. Implement feature
|
|
112
|
+
3. Run tests
|
|
113
|
+
4. If any fail, debug and fix
|
|
114
|
+
5. Refactor if needed
|
|
115
|
+
6. Repeat until all green
|
|
116
|
+
7. Output: <promise>COMPLETE</promise>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 4. Escape Hatches
|
|
120
|
+
|
|
121
|
+
Always use `--max-iterations` as a safety net to prevent infinite loops on impossible tasks:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Recommended: Always set a reasonable iteration limit
|
|
125
|
+
/ralph-loop "Try to implement feature X" --max-iterations 20
|
|
126
|
+
|
|
127
|
+
# In your prompt, include what to do if stuck:
|
|
128
|
+
# "After 15 iterations, if not complete:
|
|
129
|
+
# - Document what's blocking progress
|
|
130
|
+
# - List what was attempted
|
|
131
|
+
# - Suggest alternative approaches"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Note**: The `--completion-promise` uses exact string matching, so you cannot use it for multiple completion conditions (like "SUCCESS" vs "BLOCKED"). Always rely on `--max-iterations` as your primary safety mechanism.
|
|
135
|
+
|
|
136
|
+
## Philosophy
|
|
137
|
+
|
|
138
|
+
Ralph embodies several key principles:
|
|
139
|
+
|
|
140
|
+
### 1. Iteration > Perfection
|
|
141
|
+
Don't aim for perfect on first try. Let the loop refine the work.
|
|
142
|
+
|
|
143
|
+
### 2. Failures Are Data
|
|
144
|
+
"Deterministically bad" means failures are predictable and informative. Use them to tune prompts.
|
|
145
|
+
|
|
146
|
+
### 3. Operator Skill Matters
|
|
147
|
+
Success depends on writing good prompts, not just having a good model.
|
|
148
|
+
|
|
149
|
+
### 4. Persistence Wins
|
|
150
|
+
Keep trying until success. The loop handles retry logic automatically.
|
|
151
|
+
|
|
152
|
+
## When to Use Ralph
|
|
153
|
+
|
|
154
|
+
**Good for:**
|
|
155
|
+
- Well-defined tasks with clear success criteria
|
|
156
|
+
- Tasks requiring iteration and refinement (e.g., getting tests to pass)
|
|
157
|
+
- Greenfield projects where you can walk away
|
|
158
|
+
- Tasks with automatic verification (tests, linters)
|
|
159
|
+
|
|
160
|
+
**Not good for:**
|
|
161
|
+
- Tasks requiring human judgment or design decisions
|
|
162
|
+
- One-shot operations
|
|
163
|
+
- Tasks with unclear success criteria
|
|
164
|
+
- Production debugging (use targeted debugging instead)
|
|
165
|
+
|
|
166
|
+
## Real-World Results
|
|
167
|
+
|
|
168
|
+
- Successfully generated 6 repositories overnight in Y Combinator hackathon testing
|
|
169
|
+
- One $50k contract completed for $297 in API costs
|
|
170
|
+
- Created entire programming language ("cursed") over 3 months using this approach
|
|
171
|
+
|
|
172
|
+
## Learn More
|
|
173
|
+
|
|
174
|
+
- Original technique: https://ghuntley.com/ralph/
|
|
175
|
+
- Ralph Orchestrator: https://github.com/mikeyobrien/ralph-orchestrator
|
|
176
|
+
|
|
177
|
+
## For Help
|
|
178
|
+
|
|
179
|
+
Run `/help` in Claude Code for detailed command reference and examples.
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Explain Ralph Wiggum technique and available commands"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Ralph Wiggum Plugin Help
|
|
6
|
+
|
|
7
|
+
Please explain the following to the user:
|
|
8
|
+
|
|
9
|
+
## What is the Ralph Wiggum Technique?
|
|
10
|
+
|
|
11
|
+
The Ralph Wiggum technique is an iterative development methodology based on continuous AI loops, pioneered by Geoffrey Huntley.
|
|
12
|
+
|
|
13
|
+
**Core concept:**
|
|
14
|
+
```bash
|
|
15
|
+
while :; do
|
|
16
|
+
cat PROMPT.md | claude-code --continue
|
|
17
|
+
done
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The same prompt is fed to Claude repeatedly. The "self-referential" aspect comes from Claude seeing its own previous work in the files and git history, not from feeding output back as input.
|
|
21
|
+
|
|
22
|
+
**Each iteration:**
|
|
23
|
+
1. Claude receives the SAME prompt
|
|
24
|
+
2. Works on the task, modifying files
|
|
25
|
+
3. Tries to exit
|
|
26
|
+
4. Stop hook intercepts and feeds the same prompt again
|
|
27
|
+
5. Claude sees its previous work in the files
|
|
28
|
+
6. Iteratively improves until completion
|
|
29
|
+
|
|
30
|
+
The technique is described as "deterministically bad in an undeterministic world" - failures are predictable, enabling systematic improvement through prompt tuning.
|
|
31
|
+
|
|
32
|
+
## Available Commands
|
|
33
|
+
|
|
34
|
+
### /ralph-loop <PROMPT> [OPTIONS]
|
|
35
|
+
|
|
36
|
+
Start a Ralph loop in your current session.
|
|
37
|
+
|
|
38
|
+
**Usage:**
|
|
39
|
+
```
|
|
40
|
+
/ralph-loop "Refactor the cache layer" --max-iterations 20
|
|
41
|
+
/ralph-loop "Add tests" --completion-promise "TESTS COMPLETE"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Options:**
|
|
45
|
+
- `--max-iterations <n>` - Max iterations before auto-stop
|
|
46
|
+
- `--completion-promise <text>` - Promise phrase to signal completion
|
|
47
|
+
|
|
48
|
+
**How it works:**
|
|
49
|
+
1. Creates `.claude/.ralph-loop.local.md` state file
|
|
50
|
+
2. You work on the task
|
|
51
|
+
3. When you try to exit, stop hook intercepts
|
|
52
|
+
4. Same prompt fed back
|
|
53
|
+
5. You see your previous work
|
|
54
|
+
6. Continues until promise detected or max iterations
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### /cancel-ralph
|
|
59
|
+
|
|
60
|
+
Cancel an active Ralph loop (removes the loop state file).
|
|
61
|
+
|
|
62
|
+
**Usage:**
|
|
63
|
+
```
|
|
64
|
+
/cancel-ralph
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**How it works:**
|
|
68
|
+
- Checks for active loop state file
|
|
69
|
+
- Removes `.claude/.ralph-loop.local.md`
|
|
70
|
+
- Reports cancellation with iteration count
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Key Concepts
|
|
75
|
+
|
|
76
|
+
### Completion Promises
|
|
77
|
+
|
|
78
|
+
To signal completion, Claude must output a `<promise>` tag:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
<promise>TASK COMPLETE</promise>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The stop hook looks for this specific tag. Without it (or `--max-iterations`), Ralph runs infinitely.
|
|
85
|
+
|
|
86
|
+
### Self-Reference Mechanism
|
|
87
|
+
|
|
88
|
+
The "loop" doesn't mean Claude talks to itself. It means:
|
|
89
|
+
- Same prompt repeated
|
|
90
|
+
- Claude's work persists in files
|
|
91
|
+
- Each iteration sees previous attempts
|
|
92
|
+
- Builds incrementally toward goal
|
|
93
|
+
|
|
94
|
+
## Example
|
|
95
|
+
|
|
96
|
+
### Interactive Bug Fix
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
/ralph-loop "Fix the token refresh logic in auth.ts. Output <promise>FIXED</promise> when all tests pass." --completion-promise "FIXED" --max-iterations 10
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
You'll see Ralph:
|
|
103
|
+
- Attempt fixes
|
|
104
|
+
- Run tests
|
|
105
|
+
- See failures
|
|
106
|
+
- Iterate on solution
|
|
107
|
+
- In your current session
|
|
108
|
+
|
|
109
|
+
## When to Use Ralph
|
|
110
|
+
|
|
111
|
+
**Good for:**
|
|
112
|
+
- Well-defined tasks with clear success criteria
|
|
113
|
+
- Tasks requiring iteration and refinement
|
|
114
|
+
- Iterative development with self-correction
|
|
115
|
+
- Greenfield projects
|
|
116
|
+
|
|
117
|
+
**Not good for:**
|
|
118
|
+
- Tasks requiring human judgment or design decisions
|
|
119
|
+
- One-shot operations
|
|
120
|
+
- Tasks with unclear success criteria
|
|
121
|
+
- Debugging production issues (use targeted debugging instead)
|
|
122
|
+
|
|
123
|
+
## Learn More
|
|
124
|
+
|
|
125
|
+
- Original technique: https://ghuntley.com/ralph/
|
|
126
|
+
- Ralph Orchestrator: https://github.com/mikeyobrien/ralph-orchestrator
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Start Ralph Wiggum loop in current session"
|
|
3
|
+
argument-hint: "PROMPT [--max-iterations N] [--completion-promise TEXT]"
|
|
4
|
+
allowed-tools: ["Bash(${CLAUDE_PLUGIN_ROOT}/scripts/setup-ralph-loop.sh:*)"]
|
|
5
|
+
hide-from-slash-command-tool: "true"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Ralph Loop Command
|
|
9
|
+
|
|
10
|
+
<!--
|
|
11
|
+
minimal-agent 注意:以下 ```! ``` 块是 Claude Code 专有的 shell-on-command
|
|
12
|
+
语法,minimal-agent **不会执行**它。GoalState 的初始化(goal.md / phase.md
|
|
13
|
+
/ completion.md 等)由本插件的 plugin.ts 在进循环前自动完成,
|
|
14
|
+
不需要 setup 脚本。该块保留在这里只是为了与原版 Claude Code 兼容。
|
|
15
|
+
-->
|
|
16
|
+
|
|
17
|
+
Execute the setup script to initialize the Ralph loop:
|
|
18
|
+
|
|
19
|
+
```!
|
|
20
|
+
"${CLAUDE_PLUGIN_ROOT}/scripts/setup-ralph-loop.sh" $ARGUMENTS
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Please work on the task. When you try to exit, the Ralph loop will feed the SAME PROMPT back to you for the next iteration. You'll see your previous work in files and git history, allowing you to iterate and improve.
|
|
24
|
+
|
|
25
|
+
CRITICAL RULE: If a completion promise is set, you may ONLY output it when the statement is completely and unequivocally TRUE. Do not output false promises to escape the loop, even if you think you're stuck or should exit for other reasons. The loop is designed to continue until genuine completion.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 本插件管理的状态文件
|
|
30
|
+
|
|
31
|
+
`.minimal-agent-ralph-wiggum/` 目录下的所有文件(goal.md / phase.md / completion.md /
|
|
32
|
+
progress.md / learnings.md / decisions.md)**由本插件自动创建并维护**,你不需要主动
|
|
33
|
+
读写它们。每轮迭代开始时,插件会把当前目标、阶段、最近进度、关键决策、教训自动拼接到
|
|
34
|
+
你的 prompt 头部(freshContext),你**专注按头部信息行动**即可。
|
|
35
|
+
|
|
36
|
+
## 阶段工作流
|
|
37
|
+
|
|
38
|
+
循环会自动管理阶段转换(PLAN → BUILD → VERIFY → HEAL → DONE),但你应主动配合当前阶段:
|
|
39
|
+
|
|
40
|
+
- **PLAN 阶段**:分析任务、拆解步骤、识别风险
|
|
41
|
+
- **BUILD 阶段**:按计划实现代码,每次聚焦一个子任务
|
|
42
|
+
- **VERIFY 阶段**:运行测试、检查输出、验证功能
|
|
43
|
+
- **HEAL 阶段**:定位问题根因、修复 bug、避免回归
|
|
44
|
+
|
|
45
|
+
## 完成哨兵
|
|
46
|
+
|
|
47
|
+
当且仅当任务真正完成时,输出:
|
|
48
|
+
```
|
|
49
|
+
<promise>DONE</promise>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
如果发现方案根本不可行需要重新规划:
|
|
53
|
+
```
|
|
54
|
+
<PROMISE>NEED_REPLAN</PROMISE>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 踩坑记录
|
|
58
|
+
|
|
59
|
+
如果在工作中发现任何值得记录的教训(坑、陷阱、最佳实践),请明确说明,系统会自动记录到 `.minimal-agent/learnings.md` 供后续迭代参考。
|