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
@@ -1,137 +0,0 @@
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 (default: 50, hard cap: 200)
46
- - `--completion-promise <text>` - Custom phrase to signal completion (now fully active; default phrases DONE/COMPLETE/GOAL_COMPLETE also work)
47
- - `--verify "<CHECK>"` - Completion gate: ALL checks must pass after the promise tag before the loop truly exits. Repeatable. Supported CHECK types:
48
- - `shell:<cmd>` — exit code 0 = pass (Windows: `cmd /c`, others: `bash -c`)
49
- - `file_exists:<path>` — file must exist
50
- - `file_contains:<file>:<regex>` — file content matches regex
51
- - `test_count:<min>` — `bun test` pass count ≥ min
52
-
53
- **How it works:**
54
- 1. Creates `.claude/.ralph-loop.local.md` state file
55
- 2. You work on the task
56
- 3. When you try to exit, stop hook intercepts
57
- 4. Same prompt fed back
58
- 5. You see your previous work
59
- 6. Continues until promise detected or max iterations
60
-
61
- ---
62
-
63
- ### /cancel-ralph
64
-
65
- Cancel an active Ralph loop (removes the loop state file).
66
-
67
- **Usage:**
68
- ```
69
- /cancel-ralph
70
- ```
71
-
72
- **How it works:**
73
- - Checks for active loop state file
74
- - Removes `.claude/.ralph-loop.local.md`
75
- - Reports cancellation with iteration count
76
-
77
- ---
78
-
79
- ## Key Concepts
80
-
81
- ### Completion Promises
82
-
83
- To signal completion, Claude outputs a `<promise>` tag:
84
-
85
- ```
86
- <promise>TASK COMPLETE</promise>
87
- ```
88
-
89
- The driver looks for this tag (or the custom `--completion-promise` phrase). This signals intent to complete — the loop then runs any `--verify` checks before truly exiting.
90
-
91
- **Escape hatches** (output these tags to exit early):
92
- - `<PROMISE>NEED_REPLAN</PROMISE>` — current approach is unworkable, replan with same goal
93
- - `<PROMISE>NEED_GOAL_REVISION</PROMISE>` — the goal itself is unreachable; loop stops cleanly for human review (distinct from NEED_REPLAN: that swaps approach, this flags the goal)
94
-
95
- **Lessons tagging**: wrap insights with `<learning>…</learning>` and the driver auto-archives them to `learnings.md` for reuse in subsequent iterations.
96
-
97
- ### Self-Reference Mechanism
98
-
99
- The "loop" doesn't mean Claude talks to itself. It means:
100
- - Same prompt repeated
101
- - Claude's work persists in files
102
- - Each iteration sees previous attempts
103
- - Builds incrementally toward goal
104
-
105
- ## Example
106
-
107
- ### Interactive Bug Fix
108
-
109
- ```
110
- /ralph-loop "Fix the token refresh logic in auth.ts. Output <promise>FIXED</promise> when all tests pass." --completion-promise "FIXED" --max-iterations 10
111
- ```
112
-
113
- You'll see Ralph:
114
- - Attempt fixes
115
- - Run tests
116
- - See failures
117
- - Iterate on solution
118
- - In your current session
119
-
120
- ## When to Use Ralph
121
-
122
- **Good for:**
123
- - Well-defined tasks with clear success criteria
124
- - Tasks requiring iteration and refinement
125
- - Iterative development with self-correction
126
- - Greenfield projects
127
-
128
- **Not good for:**
129
- - Tasks requiring human judgment or design decisions
130
- - One-shot operations
131
- - Tasks with unclear success criteria
132
- - Debugging production issues (use targeted debugging instead)
133
-
134
- ## Learn More
135
-
136
- - Original technique: https://ghuntley.com/ralph/
137
- - Ralph Orchestrator: https://github.com/mikeyobrien/ralph-orchestrator
@@ -1,85 +0,0 @@
1
- ---
2
- description: "Start Ralph Wiggum loop in current session"
3
- argument-hint: "PROMPT [--max-iterations N] [--completion-promise TEXT] [--verify \"CHECK\" ...]"
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
- 也可使用 `--completion-promise` 指定的自定义短语,驱动同样认可。
52
-
53
- 如果发现**当前方案**根本不可行,需要换方案重新规划(目标不变):
54
- ```
55
- <PROMISE>NEED_REPLAN</PROMISE>
56
- ```
57
-
58
- 如果**目标本身**有问题、无法用任何方案达成,需要人工修订目标时(独立逃生门,循环干净停止):
59
- ```
60
- <PROMISE>NEED_GOAL_REVISION</PROMISE>
61
- ```
62
- > 区别:NEED_REPLAN = 换方案(目标不变);NEED_GOAL_REVISION = 目标本身有问题,请人工介入。
63
-
64
- ## 验证门 --verify
65
-
66
- 命中完成哨兵后,驱动会运行所有 `--verify` CHECK,**全部通过才真正退出**,否则回 BUILD 继续。
67
- 可重复多次,支持 4 种 CHECK 类型:
68
-
69
- - `shell:<命令>` —— 退出码 0 = 通过(Windows 走 `cmd /c`,其余 `bash -c`)
70
- - `file_exists:<路径>` —— 文件存在
71
- - `file_contains:<文件>:<正则>` —— 文件内容匹配正则
72
- - `test_count:<最小数>` —— 跑 `bun test`,统计到的通过数 ≥ 最小数
73
-
74
- 示例:
75
- ```
76
- /ralph-loop "实现并测试缓存层" --verify "shell:bun test" --verify "file_exists:src/cache.ts"
77
- ```
78
-
79
- ## 踩坑记录
80
-
81
- 如果在工作中发现任何值得记录的教训(坑、陷阱、最佳实践),用 `<learning>…</learning>` 标记:
82
- ```
83
- <learning>直接写文件前必须先 Read,否则 Edit 会报错</learning>
84
- ```
85
- 驱动每轮自动把 learning 存档到 `.minimal-agent-ralph-wiggum/learnings.md`,后续迭代会自动读入上下文复用。
@@ -1,15 +0,0 @@
1
- {
2
- "description": "Ralph Wiggum plugin stop hook for self-referential loops",
3
- "hooks": {
4
- "Stop": [
5
- {
6
- "hooks": [
7
- {
8
- "type": "command",
9
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh"
10
- }
11
- ]
12
- }
13
- ]
14
- }
15
- }
@@ -1,191 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Ralph Wiggum Stop Hook
4
- # Prevents session exit when a ralph-loop is active
5
- # Feeds Claude's output back as input to continue the loop
6
- #
7
- # NOTE (minimal-agent):
8
- # This hook is the original Claude Code contract — kept here so the plugin
9
- # stays portable to upstream. In minimal-agent the loop is driven natively
10
- # by src/plugins/pluginRunner.ts; this hook is consulted as an *advisory*
11
- # signal (block → inject reason into next iteration; pass / errors → no
12
- # effect on loop termination). The loop's real exit conditions are:
13
- # - <promise>DONE</promise> sentinel + verification pass
14
- # - --max-iterations reached
15
- # - user abort / NEED_REPLAN
16
- # On Windows minimal-agent skips this hook entirely (bash unavailable).
17
- # The .minimal-agent/ralph-loop.local.md state file referenced below is
18
- # NOT created by minimal-agent — GoalState writes goal.md/phase.md/etc
19
- # instead, so this hook simply exits 0 in minimal-agent runs.
20
-
21
- set -euo pipefail
22
-
23
- # Read hook input from stdin (advanced stop hook API)
24
- HOOK_INPUT=$(cat)
25
-
26
- # Check if ralph-loop is active
27
- RALPH_STATE_FILE=".minimal-agent/ralph-loop.local.md"
28
-
29
- if [[ ! -f "$RALPH_STATE_FILE" ]]; then
30
- # No active loop - allow exit
31
- exit 0
32
- fi
33
-
34
- # Parse markdown frontmatter (YAML between ---) and extract values
35
- FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$RALPH_STATE_FILE")
36
- ITERATION=$(echo "$FRONTMATTER" | grep '^iteration:' | sed 's/iteration: *//')
37
- MAX_ITERATIONS=$(echo "$FRONTMATTER" | grep '^max_iterations:' | sed 's/max_iterations: *//')
38
- # Extract completion_promise and strip surrounding quotes if present
39
- COMPLETION_PROMISE=$(echo "$FRONTMATTER" | grep '^completion_promise:' | sed 's/completion_promise: *//' | sed 's/^"\(.*\)"$/\1/')
40
-
41
- # Validate numeric fields before arithmetic operations
42
- if [[ ! "$ITERATION" =~ ^[0-9]+$ ]]; then
43
- echo "⚠️ Ralph loop: State file corrupted" >&2
44
- echo " File: $RALPH_STATE_FILE" >&2
45
- echo " Problem: 'iteration' field is not a valid number (got: '$ITERATION')" >&2
46
- echo "" >&2
47
- echo " This usually means the state file was manually edited or corrupted." >&2
48
- echo " Ralph loop is stopping. Run /ralph-loop again to start fresh." >&2
49
- rm "$RALPH_STATE_FILE"
50
- exit 0
51
- fi
52
-
53
- if [[ ! "$MAX_ITERATIONS" =~ ^[0-9]+$ ]]; then
54
- echo "⚠️ Ralph loop: State file corrupted" >&2
55
- echo " File: $RALPH_STATE_FILE" >&2
56
- echo " Problem: 'max_iterations' field is not a valid number (got: '$MAX_ITERATIONS')" >&2
57
- echo "" >&2
58
- echo " This usually means the state file was manually edited or corrupted." >&2
59
- echo " Ralph loop is stopping. Run /ralph-loop again to start fresh." >&2
60
- rm "$RALPH_STATE_FILE"
61
- exit 0
62
- fi
63
-
64
- # Check if max iterations reached
65
- if [[ $MAX_ITERATIONS -gt 0 ]] && [[ $ITERATION -ge $MAX_ITERATIONS ]]; then
66
- echo "🛑 Ralph loop: Max iterations ($MAX_ITERATIONS) reached."
67
- rm "$RALPH_STATE_FILE"
68
- exit 0
69
- fi
70
-
71
- # Get transcript path from hook input
72
- TRANSCRIPT_PATH=$(echo "$HOOK_INPUT" | jq -r '.transcript_path')
73
-
74
- if [[ ! -f "$TRANSCRIPT_PATH" ]]; then
75
- echo "⚠️ Ralph loop: Transcript file not found" >&2
76
- echo " Expected: $TRANSCRIPT_PATH" >&2
77
- echo " This is unusual and may indicate a Claude Code internal issue." >&2
78
- echo " Ralph loop is stopping." >&2
79
- rm "$RALPH_STATE_FILE"
80
- exit 0
81
- fi
82
-
83
- # Read last assistant message from transcript (JSONL format - one JSON per line)
84
- # First check if there are any assistant messages
85
- if ! grep -q '"role":"assistant"' "$TRANSCRIPT_PATH"; then
86
- echo "⚠️ Ralph loop: No assistant messages found in transcript" >&2
87
- echo " Transcript: $TRANSCRIPT_PATH" >&2
88
- echo " This is unusual and may indicate a transcript format issue" >&2
89
- echo " Ralph loop is stopping." >&2
90
- rm "$RALPH_STATE_FILE"
91
- exit 0
92
- fi
93
-
94
- # Extract last assistant message with explicit error handling
95
- LAST_LINE=$(grep '"role":"assistant"' "$TRANSCRIPT_PATH" | tail -1)
96
- if [[ -z "$LAST_LINE" ]]; then
97
- echo "⚠️ Ralph loop: Failed to extract last assistant message" >&2
98
- echo " Ralph loop is stopping." >&2
99
- rm "$RALPH_STATE_FILE"
100
- exit 0
101
- fi
102
-
103
- # Parse JSON with error handling
104
- LAST_OUTPUT=$(echo "$LAST_LINE" | jq -r '
105
- .message.content |
106
- map(select(.type == "text")) |
107
- map(.text) |
108
- join("\n")
109
- ' 2>&1)
110
-
111
- # Check if jq succeeded
112
- if [[ $? -ne 0 ]]; then
113
- echo "⚠️ Ralph loop: Failed to parse assistant message JSON" >&2
114
- echo " Error: $LAST_OUTPUT" >&2
115
- echo " This may indicate a transcript format issue" >&2
116
- echo " Ralph loop is stopping." >&2
117
- rm "$RALPH_STATE_FILE"
118
- exit 0
119
- fi
120
-
121
- if [[ -z "$LAST_OUTPUT" ]]; then
122
- echo "⚠️ Ralph loop: Assistant message contained no text content" >&2
123
- echo " Ralph loop is stopping." >&2
124
- rm "$RALPH_STATE_FILE"
125
- exit 0
126
- fi
127
-
128
- # Check for completion promise (only if set)
129
- if [[ "$COMPLETION_PROMISE" != "null" ]] && [[ -n "$COMPLETION_PROMISE" ]]; then
130
- # Extract text from <promise> tags using Perl for multiline support
131
- # -0777 slurps entire input, s flag makes . match newlines
132
- # .*? is non-greedy (takes FIRST tag), whitespace normalized
133
- PROMISE_TEXT=$(echo "$LAST_OUTPUT" | perl -0777 -pe 's/.*?<promise>(.*?)<\/promise>.*/$1/s; s/^\s+|\s+$//g; s/\s+/ /g' 2>/dev/null || echo "")
134
-
135
- # Use = for literal string comparison (not pattern matching)
136
- # == in [[ ]] does glob pattern matching which breaks with *, ?, [ characters
137
- if [[ -n "$PROMISE_TEXT" ]] && [[ "$PROMISE_TEXT" = "$COMPLETION_PROMISE" ]]; then
138
- echo "✅ Ralph loop: Detected <promise>$COMPLETION_PROMISE</promise>"
139
- rm "$RALPH_STATE_FILE"
140
- exit 0
141
- fi
142
- fi
143
-
144
- # Not complete - continue loop with SAME PROMPT
145
- NEXT_ITERATION=$((ITERATION + 1))
146
-
147
- # Extract prompt (everything after the closing ---)
148
- # Skip first --- line, skip until second --- line, then print everything after
149
- # Use i>=2 instead of i==2 to handle --- in prompt content
150
- PROMPT_TEXT=$(awk '/^---$/{i++; next} i>=2' "$RALPH_STATE_FILE")
151
-
152
- if [[ -z "$PROMPT_TEXT" ]]; then
153
- echo "⚠️ Ralph loop: State file corrupted or incomplete" >&2
154
- echo " File: $RALPH_STATE_FILE" >&2
155
- echo " Problem: No prompt text found" >&2
156
- echo "" >&2
157
- echo " This usually means:" >&2
158
- echo " • State file was manually edited" >&2
159
- echo " • File was corrupted during writing" >&2
160
- echo "" >&2
161
- echo " Ralph loop is stopping. Run /ralph-loop again to start fresh." >&2
162
- rm "$RALPH_STATE_FILE"
163
- exit 0
164
- fi
165
-
166
- # Update iteration in frontmatter (portable across macOS and Linux)
167
- # Create temp file, then atomically replace
168
- TEMP_FILE="${RALPH_STATE_FILE}.tmp.$$"
169
- sed "s/^iteration: .*/iteration: $NEXT_ITERATION/" "$RALPH_STATE_FILE" > "$TEMP_FILE"
170
- mv "$TEMP_FILE" "$RALPH_STATE_FILE"
171
-
172
- # Build system message with iteration count and completion promise info
173
- if [[ "$COMPLETION_PROMISE" != "null" ]] && [[ -n "$COMPLETION_PROMISE" ]]; then
174
- SYSTEM_MSG="🔄 Ralph iteration $NEXT_ITERATION | To stop: output <promise>$COMPLETION_PROMISE</promise> (ONLY when statement is TRUE - do not lie to exit!)"
175
- else
176
- SYSTEM_MSG="🔄 Ralph iteration $NEXT_ITERATION | No completion promise set - loop runs infinitely"
177
- fi
178
-
179
- # Output JSON to block the stop and feed prompt back
180
- # The "reason" field contains the prompt that will be sent back to Claude
181
- jq -n \
182
- --arg prompt "$PROMPT_TEXT" \
183
- --arg msg "$SYSTEM_MSG" \
184
- '{
185
- "decision": "block",
186
- "reason": $prompt,
187
- "systemMessage": $msg
188
- }'
189
-
190
- # Exit 0 for successful hook execution
191
- exit 0