ralph-flow-pi 0.1.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 (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +428 -0
  3. package/dist/cli.d.ts +9 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +56 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/prompts.d.ts +25 -0
  8. package/dist/commands/prompts.d.ts.map +1 -0
  9. package/dist/commands/prompts.js +249 -0
  10. package/dist/commands/prompts.js.map +1 -0
  11. package/dist/commands/tools.d.ts +47 -0
  12. package/dist/commands/tools.d.ts.map +1 -0
  13. package/dist/commands/tools.js +633 -0
  14. package/dist/commands/tools.js.map +1 -0
  15. package/dist/engine/check-bash.d.ts +121 -0
  16. package/dist/engine/check-bash.d.ts.map +1 -0
  17. package/dist/engine/check-bash.js +373 -0
  18. package/dist/engine/check-bash.js.map +1 -0
  19. package/dist/engine/check.d.ts +47 -0
  20. package/dist/engine/check.d.ts.map +1 -0
  21. package/dist/engine/check.js +298 -0
  22. package/dist/engine/check.js.map +1 -0
  23. package/dist/engine/core.d.ts +153 -0
  24. package/dist/engine/core.d.ts.map +1 -0
  25. package/dist/engine/core.js +1984 -0
  26. package/dist/engine/core.js.map +1 -0
  27. package/dist/engine/lock.d.ts +27 -0
  28. package/dist/engine/lock.d.ts.map +1 -0
  29. package/dist/engine/lock.js +121 -0
  30. package/dist/engine/lock.js.map +1 -0
  31. package/dist/engine/runner.d.ts +108 -0
  32. package/dist/engine/runner.d.ts.map +1 -0
  33. package/dist/engine/runner.js +510 -0
  34. package/dist/engine/runner.js.map +1 -0
  35. package/dist/engine/skills.d.ts +53 -0
  36. package/dist/engine/skills.d.ts.map +1 -0
  37. package/dist/engine/skills.js +109 -0
  38. package/dist/engine/skills.js.map +1 -0
  39. package/dist/engine/step-tools.d.ts +22 -0
  40. package/dist/engine/step-tools.d.ts.map +1 -0
  41. package/dist/engine/step-tools.js +45 -0
  42. package/dist/engine/step-tools.js.map +1 -0
  43. package/dist/engine/types.d.ts +136 -0
  44. package/dist/engine/types.d.ts.map +1 -0
  45. package/dist/engine/types.js +20 -0
  46. package/dist/engine/types.js.map +1 -0
  47. package/dist/headless.d.ts +57 -0
  48. package/dist/headless.d.ts.map +1 -0
  49. package/dist/headless.js +318 -0
  50. package/dist/headless.js.map +1 -0
  51. package/dist/pi/adapter.d.ts +135 -0
  52. package/dist/pi/adapter.d.ts.map +1 -0
  53. package/dist/pi/adapter.js +231 -0
  54. package/dist/pi/adapter.js.map +1 -0
  55. package/dist/pi/interactive.d.ts +28 -0
  56. package/dist/pi/interactive.d.ts.map +1 -0
  57. package/dist/pi/interactive.js +58 -0
  58. package/dist/pi/interactive.js.map +1 -0
  59. package/dist/pi/tui.d.ts +12 -0
  60. package/dist/pi/tui.d.ts.map +1 -0
  61. package/dist/pi/tui.js +12 -0
  62. package/dist/pi/tui.js.map +1 -0
  63. package/dist/tui/app.d.ts +25 -0
  64. package/dist/tui/app.d.ts.map +1 -0
  65. package/dist/tui/app.js +47 -0
  66. package/dist/tui/app.js.map +1 -0
  67. package/dist/tui/embed.d.ts +42 -0
  68. package/dist/tui/embed.d.ts.map +1 -0
  69. package/dist/tui/embed.js +38 -0
  70. package/dist/tui/embed.js.map +1 -0
  71. package/dist/tui/extension.d.ts +88 -0
  72. package/dist/tui/extension.d.ts.map +1 -0
  73. package/dist/tui/extension.js +114 -0
  74. package/dist/tui/extension.js.map +1 -0
  75. package/dist/tui/history-editor.d.ts +38 -0
  76. package/dist/tui/history-editor.d.ts.map +1 -0
  77. package/dist/tui/history-editor.js +55 -0
  78. package/dist/tui/history-editor.js.map +1 -0
  79. package/dist/tui/launcher.d.ts +24 -0
  80. package/dist/tui/launcher.d.ts.map +1 -0
  81. package/dist/tui/launcher.js +97 -0
  82. package/dist/tui/launcher.js.map +1 -0
  83. package/dist/tui/render.d.ts +87 -0
  84. package/dist/tui/render.d.ts.map +1 -0
  85. package/dist/tui/render.js +266 -0
  86. package/dist/tui/render.js.map +1 -0
  87. package/dist/tui/run-app.d.ts +49 -0
  88. package/dist/tui/run-app.d.ts.map +1 -0
  89. package/dist/tui/run-app.js +317 -0
  90. package/dist/tui/run-app.js.map +1 -0
  91. package/dist/tui/run-model.d.ts +162 -0
  92. package/dist/tui/run-model.d.ts.map +1 -0
  93. package/dist/tui/run-model.js +280 -0
  94. package/dist/tui/run-model.js.map +1 -0
  95. package/dist/tui/run-view.d.ts +71 -0
  96. package/dist/tui/run-view.d.ts.map +1 -0
  97. package/dist/tui/run-view.js +167 -0
  98. package/dist/tui/run-view.js.map +1 -0
  99. package/dist/tui/welcome-header.d.ts +40 -0
  100. package/dist/tui/welcome-header.d.ts.map +1 -0
  101. package/dist/tui/welcome-header.js +90 -0
  102. package/dist/tui/welcome-header.js.map +1 -0
  103. package/package.json +55 -0
  104. package/skills/c-to-rust-audit/SKILL.md +67 -0
  105. package/skills/c-to-rust-implement/SKILL.md +151 -0
  106. package/skills/c-to-rust-implement/references/c-to-rust-patterns.md +86 -0
  107. package/skills/c-to-rust-implement/references/conditional-compilation.md +47 -0
  108. package/skills/c-to-rust-implement/references/crate-reference.md +15 -0
  109. package/skills/c-to-rust-implement/references/error-strategies.md +80 -0
  110. package/skills/c-to-rust-implement/references/inline-asm.md +37 -0
  111. package/skills/c-to-rust-plan/SKILL.md +166 -0
  112. package/skills/c-to-rust-plan/references/detection-commands.md +66 -0
  113. package/skills/c-to-rust-test-gen/SKILL.md +130 -0
  114. package/skills/c-to-rust-test-gen/references/proptest-patterns.md +81 -0
  115. package/skills/c-to-rust-test-gen/references/test-porting.md +56 -0
  116. package/skills/c-to-rust-validate/SKILL.md +121 -0
  117. package/skills/everything2rust-audit/SKILL.md +69 -0
  118. package/skills/everything2rust-design/SKILL.md +121 -0
  119. package/skills/everything2rust-design/references/domain-playbooks.md +68 -0
  120. package/skills/everything2rust-design/references/paradigm-map.md +99 -0
  121. package/skills/everything2rust-implement/SKILL.md +101 -0
  122. package/skills/everything2rust-spec/SKILL.md +86 -0
  123. package/skills/everything2rust-spec/references/oracle-strategies.md +96 -0
  124. package/skills/everything2rust-survey/SKILL.md +99 -0
  125. package/skills/everything2rust-test-gen/SKILL.md +68 -0
  126. package/skills/everything2rust-test-gen/references/harness-patterns.md +186 -0
  127. package/skills/everything2rust-validate/SKILL.md +85 -0
  128. package/workflows/c-to-rust.yaml +202 -0
  129. package/workflows/everything2rust.yaml +259 -0
  130. package/workflows/loop.yaml +68 -0
  131. package/workflows/spec.yaml +183 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * The eight slash-command prompt templates.
3
+ *
4
+ * Command names and most prose are a verbatim port of the plugin versions, so
5
+ * the docs and the user's habits carry over. One section had to go, and it is
6
+ * worth being explicit about which:
7
+ *
8
+ * The plugins' /ralphflow-start template spent half its length teaching the
9
+ * model how to BE the working session — "execute the DO prompt you receive",
10
+ * "output <promise>done</promise> on the last line", "acknowledge phase
11
+ * transitions". None of that is true here. The main chat session is a control
12
+ * surface; DO runs in its own session with its own context and its own
13
+ * report_done tool. Leaving those instructions in would invite the chat model to
14
+ * start doing the work itself, in the one context window we are trying to keep
15
+ * clean.
16
+ *
17
+ * What replaced it is short: start the workflow, watch it, help when it stops.
18
+ */
19
+ function template(description, body) {
20
+ return {
21
+ description,
22
+ render: (args) => body.replace(/\$ARGUMENTS/g, args?.trim() ? args.trim() : "(未提供)"),
23
+ };
24
+ }
25
+ export const COMMAND_PROMPTS = {
26
+ "ralphflow-start": template("Start a ralph-flow workflow", `Start a Ralph Flow workflow execution.
27
+
28
+ User input: $ARGUMENTS
29
+
30
+ User needs to specify both the workflow name and task description. If information is incomplete, ask the user:
31
+
32
+ - Only task, no workflow → ask which workflow to use
33
+ - Only workflow, no task → ask what to do
34
+ - Neither → ask for both
35
+
36
+ Do NOT guess which workflow to use - let the user choose.
37
+
38
+ Available workflows: use \`ralphflow_list\` tool to see.
39
+
40
+ Once information is complete, call the \`ralphflow_start\` tool to start the workflow.
41
+
42
+ **extra_dirs**: If the task's source material lives OUTSIDE the current project directory (e.g. migrating \`~/some-c-lib\` into this project), pass those directories in the optional \`extra_dirs\` parameter — the independent CHECK verifier works from the project directory and must be able to read the source material it verifies against. Each directory is validated at start; a nonexistent path refuses the start immediately. Do not guess: only pass paths the user actually mentioned.
43
+
44
+ Each start creates a new **workflow instance** (the response carries its instance id). One session runs at most one instance; multiple sessions in the same project can each run their own instance in parallel. If the tool says this session already has an active instance, finish or cancel it first.
45
+
46
+ ## How execution works
47
+
48
+ **You do not execute the steps.** After \`ralphflow_start\` returns, the engine runs the workflow on its own:
49
+
50
+ - Each **DO** step runs in a **separate, fresh AI session** — its own context window, its own tools. It ends by calling \`report_done\`.
51
+ - Each **CHECK** runs in another independent, read-only session that verifies the work against the step's check criteria and submits a \`verdict\`.
52
+ - Passing advances to the next step; failing retries it with the reason; too many failures pauses the workflow.
53
+
54
+ ## After you call ralphflow_start, STOP. Your turn is over.
55
+
56
+ The engine drives everything on its own, and its progress renders into this conversation **automatically** — you do not display it and do not need to fetch it.
57
+
58
+ **Do NOT poll.** After starting a workflow, do NOT call \`ralphflow_status\` in a loop, do NOT read/tail/cat anything under \`.ralph-flow/\` (instances, sessions, logs) to track progress, and do NOT \`sleep\` and re-check. All of that is wasted work — the engine is autonomous and the user can already see what is happening. Even one \`ralphflow_status\` call here is unnecessary; a loop of them is a bug in your behavior, not progress.
59
+
60
+ **Only speak up again when there is something for a human to decide:**
61
+
62
+ - **Manual review** (📋): the workflow paused for the USER to review. Wait for them. Their \`/ralphflow-continue\` is the approval. If they want changes, relay them — do not approve on their behalf.
63
+ - **Paused** (max failures / config error / verification failure): explain why and what to do next.
64
+ - **Stopped driving**: a DO step went several turns without finishing. Help the user work out what it is stuck on.
65
+ - The **user asks** you something.
66
+
67
+ Until one of those happens, reply with one short sentence that the workflow has started, then wait silently. Do NOT call \`ralphflow_continue\` for normal steps — verification is automatic. It is only for: approving a manual review, resuming a paused workflow, or attaching to an interrupted instance.`),
68
+ "ralphflow-continue": template("Approve a manual review / resume or attach to a ralph-flow workflow", `Call the \`ralphflow_continue\` tool. It covers four situations:
69
+
70
+ User input: $ARGUMENTS
71
+
72
+ **Normal steps are automatic**: the engine runs DO and the independent verification on its own, and advances without help — you do NOT call this tool for them. \`ralphflow_continue\` is only for the cases below.
73
+
74
+ **Manual review approval**: When the user runs this command after a 📋 manual-step review, calling \`ralphflow_continue\` is their approval — it starts the independent verification. (Never call it on your own initiative during a manual review.)
75
+
76
+ **Paused workflow**: If the workflow was paused due to max failures:
77
+ 1. Review the failure reason shown in \`/ralphflow-status\`
78
+ 2. Fix the issues that caused the failure
79
+ 3. Call \`ralphflow_continue\` — it resets the fail counter and retries the step
80
+
81
+ **Verification infrastructure failure** (⚠️ 验证未能运行): the verifier itself failed (quota/API/timeout), not the work. Nothing needs redoing and no failure was counted — once the underlying problem is fixed, \`ralphflow_continue\` re-runs the verification directly.
82
+
83
+ **Attach to an interrupted instance (new session)**: If the user provided an instance id with this command, pass it as the \`instance\` argument (unique prefix allowed). Without an id:
84
+ - a single instance in the project → auto-attached
85
+ - multiple instances exist → the tool returns an instance list; show it to the user and ask which one to attach, then call again with \`instance\`
86
+ - attaching to an instance interrupted mid-DO restarts that step; if it was interrupted after the step reported done, verification starts directly
87
+
88
+ After the tool returns, the engine resumes driving on its own. Briefly tell the user what happened, then STOP. Do NOT poll ralphflow_status or read anything under .ralph-flow/ to watch progress — it renders automatically. Speak up again only for a manual review, a pause, or a user question.`),
89
+ "ralphflow-watch": template("Re-attach the live run view to a workflow that's already running in the background", `Call the \`ralphflow_watch\` tool to re-attach to a workflow instance that is running in the background — one the user detached from earlier (Esc on the run view), or one adopted when this session started.
90
+
91
+ User input: $ARGUMENTS
92
+
93
+ - Without arguments it attaches to this session's instance (or the single active instance in the project).
94
+ - If the user named an instance, pass it as the \`instance\` argument (unique prefix allowed).
95
+ - This does NOT approve, resume, or cancel anything by itself — it only opens the view onto whatever is already happening. If what's actually needed is approving a review or resuming a pause, use \`/ralphflow-continue\` instead.
96
+
97
+ After the tool returns, briefly tell the user what happened (attached and detached again / workflow completed / cancelled), then STOP. Do NOT call this again on your own initiative just because a workflow is still running in the background — the user asked to look this one time; you'll be told automatically (in this same conversation) when it actually needs a human.`),
98
+ "ralphflow-status": template("Show ralph-flow workflow status (this session's instance or all instances)", `Show Ralph Flow workflow status.
99
+
100
+ User input: $ARGUMENTS
101
+
102
+ Call the \`ralphflow_status\` tool:
103
+ - Without arguments it shows this session's instance, or an overview of ALL active instances in the project when this session has none (id, workflow, step, state, owner session, last activity).
104
+ - If the user names an instance, pass it as the \`instance\` argument (unique prefix allowed) to inspect that instance.
105
+
106
+ Displayed per instance:
107
+ - Workflow name, current step and phase (do/check)
108
+ - State: running / verifying / waiting for manual review / paused (with reason)
109
+ - Failure count and last failure reason (if any)
110
+ - Owner session — an instance owned by another (or a since-closed) session can be taken over via \`ralphflow_continue\`
111
+ - Driving process — when another \`ralph\` process is running the instance, operate it there`),
112
+ "ralphflow-list": template("List available ralph-flow workflows and active instances", `List all available Ralph Flow workflows and active workflow instances.
113
+
114
+ Call the \`ralphflow_list\` tool to show:
115
+ - All workflow names with a brief description of each
116
+ - All active workflow instances in this project (id, workflow, step, state, owner session)
117
+
118
+ Workflows are resolved in order (a same-named workflow at an earlier tier shadows the later ones):
119
+ 1. Project custom (.ralph-flow/workflows/) — this project only
120
+ 2. Global custom (~/.config/ralph-flow-pi/workflows/) — all projects, survives updates
121
+ 3. Built-in (bundled with ralph-flow-pi)`),
122
+ "ralphflow-cancel": template("Cancel a ralph-flow workflow instance", `Cancel a Ralph Flow workflow instance.
123
+
124
+ User input: $ARGUMENTS
125
+
126
+ Call the \`ralphflow_cancel\` tool to properly cancel the workflow: it aborts the running step and verification sessions, archives the final report to \`.ralph-flow/reports/\`, and removes the instance directory (including the sub-workflow state stack).
127
+
128
+ - Without arguments it cancels this session's instance (or the single instance in the project).
129
+ - To cancel a specific instance (e.g. one owned by another/closed session), pass the \`instance\` argument (unique prefix allowed). If the tool returns an instance list instead, show it to the user and confirm which one to cancel.
130
+
131
+ Do NOT manually delete files — use the tool to ensure proper cleanup. Artifacts produced by the workflow are kept.`),
132
+ "ralphflow-doctor": template("Diagnose ralph-flow workflow definitions and instance state, explain problems, and offer fixes", `Diagnose the health of all Ralph Flow workflow definitions (project + global + built-in), skills, and instance state.
133
+
134
+ ## Procedure
135
+
136
+ 1. Call the \`ralphflow_doctor\` tool. It is read-only and returns a full diagnosis report:
137
+ - Per-workflow verdict (launchable / broken) with the **complete** list of validation problems, not just the first one
138
+ - Warnings on launchable workflows: silently skipped steps, unreachable steps, unresolvable \`{{...}}\` tokens, broken sub-workflow references, sub-workflow cycles, clamped/ignored \`adversarial_check\` fields
139
+ - Shadowing: which file actually runs when several tiers define the same name, and when an invalid project file silently falls back to a built-in
140
+ - YAML files ignored because they aren't workflow-shaped
141
+ - Instance directories with missing/corrupt state.json
142
+ - Available skills and which ones shadow which
143
+
144
+ 2. Present the report to the user. For each problem, explain the root cause in plain language and what its consequence is (e.g. "this step was silently dropped — the workflow runs, but without it").
145
+
146
+ 3. **Offer to fix.** If the user agrees (or asked for fixes up front), edit the offending YAML files directly, then call \`ralphflow_doctor\` again to confirm the report is clean. Repeat until no problems remain. Never edit built-in workflow files — if a built-in needs different behavior, copy it into \`.ralph-flow/workflows/\` and edit the copy (it shadows the built-in by name).
147
+
148
+ ## Common problems → fixes
149
+
150
+ | Symptom in report | Fix |
151
+ |---|---|
152
+ | missing/invalid \`input\` / \`output\` / \`do\` / \`check\` / \`desc\` / \`on_pass\` / \`on_fail\` / \`max_fail_count\` | Add the missing field to that step. Every non-sub-workflow step needs all of: \`id\`, \`desc\`, \`do\`, \`check\`, \`input\`, \`output\`, \`on_pass\`, \`on_fail\`, \`max_fail_count\` (number ≥ 1) |
153
+ | step skipped silently | Same as above — the step is missing a required field; the rest of the workflow still validated, so it runs WITHOUT this step |
154
+ | \`on_pass\`/\`on_fail\` references unknown step | Fix the typo, or use \`done\` (valid for \`on_pass\` only, marks workflow completion) |
155
+ | \`manual_step\` references unknown step | Fix the step id in the top-level \`manual_step\` list (hard error by design: a typo'd review gate must never run gateless) |
156
+ | unreachable step | Wire it into the graph via some step's \`on_pass\`/\`on_fail\`, or delete it. Execution starts at the FIRST element of \`steps\` |
157
+ | no reachable step has \`on_pass: done\` | Point the final step's \`on_pass\` at \`done\` |
158
+ | unresolvable template token | Remove it. The engine resolves exactly one token, \`{{artifacts_dir}}\` (no spaces inside braces), and normally you don't need even that — every DO/CHECK prompt automatically carries a 产出目录 section |
159
+ | \`adversarial_check.model\` is a bare name | Use \`"provider/model"\` (e.g. \`"anthropic/claude-sonnet-4-5"\`, optionally \`:high\` for a thinking level). A bare name cannot be resolved and falls back to the default model |
160
+ | \`adversarial_check.agent\` is ignored | Delete it. ralph-flow-pi has no agent concept — the verifier's read-only sandbox is built in (read-only tools + a bash whitelist) |
161
+ | sub-workflow won't load | Fix the \`workflow:\` name or create the referenced workflow file |
162
+ | sub-workflow cycle | Break the cycle; nesting is capped at depth 5 and errors at runtime |
163
+ | invalid project file falling back to a built-in | Fix the project file — right now starting that name runs the BUILT-IN, not the user's version |
164
+ | corrupt instance state.json | The instance is unrecoverable; after the user confirms it's not needed, delete \`.ralph-flow/instances/<id>/\` |
165
+
166
+ To create a brand-new workflow instead of fixing one, suggest \`/ralphflow-create\`.`),
167
+ "ralphflow-create": template("Interactively design and create a custom ralph-flow workflow, validated and ready to run", `Interactively design a custom Ralph Flow workflow with the user, write it to \`.ralph-flow/workflows/<name>.yaml\`, and validate it with the \`ralphflow_doctor\` tool until it is clean and launchable.
168
+
169
+ User input: $ARGUMENTS
170
+
171
+ ## Procedure
172
+
173
+ 1. **Understand the process to automate.** Ask the user (in one round, don't interrogate):
174
+ - What repeating process should the workflow run? What are its phases?
175
+ - Where do they want a human review gate (workflow stops for their approval before verification)?
176
+ - Should any phase reuse an existing workflow as a sub-workflow? (\`ralphflow_list\` shows what exists.)
177
+ If the user already described all this, skip the questions and design directly.
178
+
179
+ 2. **Design the step graph and present it** as a compact overview (step id → what it does → on_pass/on_fail targets) before writing the file. Adjust per feedback.
180
+
181
+ 3. **Write the YAML** (kebab-case name). Ask the user for the scope, or default to project:
182
+ - project-only → \`.ralph-flow/workflows/<name>.yaml\`
183
+ - available in all projects → \`~/.config/ralph-flow-pi/workflows/<name>.yaml\` (global; survives updates)
184
+
185
+ Create the directory if needed. If the name matches a built-in (\`loop\`, \`spec\`, \`c-to-rust\`, \`everything2rust\`), tell the user it will shadow the built-in and confirm that's intended.
186
+
187
+ 4. **Validate**: call the \`ralphflow_doctor\` tool and check the new workflow's section. Fix every problem AND warning it reports for this workflow, re-run doctor, repeat until its verdict is "可启动" with no warnings.
188
+
189
+ 5. **Hand off**: show the user the final step overview and tell them how to run it: \`/ralphflow-start\` with workflow \`<name>\` and their task description.
190
+
191
+ ## YAML schema (exact — the engine validates all of this)
192
+
193
+ \`\`\`yaml
194
+ description: One-line description shown in ralphflow_list # optional but recommended
195
+
196
+ manual_step: # optional: step ids that pause for HUMAN review after DO, before verification
197
+ - design
198
+
199
+ adversarial_check: # optional: config for the independent CHECK session
200
+ model: "anthropic/claude-sonnet-4-5" # optional: verifier model, "provider/model"[:thinking].
201
+ # Any provider works — verifying with a DIFFERENT model
202
+ # than the one doing the work is the point of the design.
203
+ timeout_ms: 3600000 # capped at 3600000 (1 hour)
204
+ # system_prompt: ... # optional extra system prompt for the checker
205
+ \`\`\`
206
+
207
+ \`\`\`yaml
208
+ steps: # required, non-empty; execution starts at the FIRST element
209
+ - id: step-id # required, unique string
210
+ desc: 一句话说明 # required
211
+ do: | # required (unless this is a sub-workflow step)
212
+ DO-phase instructions, executed by a fresh session with its own context.
213
+ check: | # required (unless sub-workflow step)
214
+ CHECK-phase instructions, executed by an INDEPENDENT read-only verifier session.
215
+ input: 上一步的产物或用户输入 # required: what this step consumes
216
+ output: "result.md" # required: what this step must produce
217
+ on_pass: next-step-id # required: step id, or "done" to finish the workflow
218
+ on_fail: step-id # required: step id to retry/fall back to ("done" NOT allowed)
219
+ max_fail_count: 3 # required, number ≥ 1: pauses for the user after this many CHECK failures
220
+
221
+ - id: delegate # sub-workflow step: replaces do/check with:
222
+ workflow: loop # name of another workflow (nesting capped at depth 5, no cycles)
223
+ desc: ...
224
+ input: ...
225
+ output: ...
226
+ on_pass: done
227
+ on_fail: delegate
228
+ max_fail_count: 3
229
+ \`\`\`
230
+
231
+ Hard rules the engine enforces (violations make the file unlaunchable or silently drop steps):
232
+
233
+ - Every field above marked required is required **per step** — a step missing one is **silently skipped** while the rest of the workflow still runs. Never omit \`input\`/\`output\`.
234
+ - \`on_pass\`/\`on_fail\` must reference an existing step id (\`done\` valid only for \`on_pass\`).
235
+ - \`manual_step\` entries must match existing step ids — a typo is a hard error by design.
236
+ - **No template variables.** The engine resolves nothing except the internal \`{{artifacts_dir}}\` escape hatch, and you don't need it: every DO/CHECK prompt automatically carries a 产出目录 (artifacts directory) section. Write bare filenames in \`output\` (e.g. \`"plan.md"\`); the session knows to put them in the artifacts dir.
237
+
238
+ ## Design best practices (apply these unless the user objects)
239
+
240
+ - **Every step gets a fresh context window.** Steps do NOT share conversation history — the ONLY things carried between them are the files in the artifacts dir and what \`input\`/\`output\` name. Write each step so it stands alone: if a step needs an earlier decision, say which file holds it.
241
+ - **\`do\` must demand real work**, not analysis: create files, run commands, produce the named output. The session ends DO by calling the \`report_done\` tool.
242
+ - **\`check\` is executed by an independent session that saw none of the DO conversation.** Write it as a self-contained verification recipe: which files to open, which commands to run, and concrete pass/fail criteria. Vague criteria ("代码质量好") make CHECK useless.
243
+ - **Checkpoint-list pattern** for open-ended tasks: first step decomposes the request into a \`checkpoints.md\` of objectively verifiable items each annotated with its verification method; later steps execute and tick them; their \`check\` re-verifies each item independently instead of trusting the ticks.
244
+ - **Light persona nudge in \`check\`** sharpens verification, e.g. opening with 「你是一个挑剔的测试工程师:你的目标不是确认任务完成,而是想办法证明它没完成。」 Keep it one line — no heavyweight role setups.
245
+ - **Retry loops**: \`on_fail\` usually points at the step itself; point it at an earlier step only when a failure genuinely invalidates earlier output. \`max_fail_count\` 3–5 for bounded steps, large (e.g. 100) for grind-until-green loops.
246
+ - **Manual gates** where a wrong direction is expensive (plans, designs, destructive actions) — list those step ids in \`manual_step\`.
247
+ - **Language**: write \`do\`/\`check\` prose in the user's language.`),
248
+ };
249
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/commands/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAQH,SAAS,QAAQ,CAAC,WAAmB,EAAE,IAAY;IACjD,OAAO;QACL,WAAW;QACX,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;KAC7F,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAoC;IAC9D,iBAAiB,EAAE,QAAQ,CACzB,6BAA6B,EAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8SAyC0S,CAAC;IAE7S,oBAAoB,EAAE,QAAQ,CAC5B,qEAAqE,EACrE;;;;;;;;;;;;;;;;;;;;oSAoBgS,CAAC;IAEnS,iBAAiB,EAAE,QAAQ,CACzB,oFAAoF,EACpF;;;;;;;;iXAQ6W,CAAC;IAEhX,kBAAkB,EAAE,QAAQ,CAC1B,4EAA4E,EAC5E;;;;;;;;;;;;;6FAayF,CAAC;IAE5F,gBAAgB,EAAE,QAAQ,CACxB,0DAA0D,EAC1D;;;;;;;;;yCASqC,CAAC;IAExC,kBAAkB,EAAE,QAAQ,CAC1B,uCAAuC,EACvC;;;;;;;;;mHAS+G,CAAC;IAElH,kBAAkB,EAAE,QAAQ,CAC1B,gGAAgG,EAChG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qFAkCiF,CAAC;IAEpF,kBAAkB,EAAE,QAAQ,CAC1B,0FAA0F,EAC1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qEAgFiE,CAAC;CACrE,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The six ralphflow_* tools, exposed to the main chat session.
3
+ *
4
+ * Names and response texts are a verbatim port of the plugin versions' tools, so
5
+ * the workflow YAML, the docs and the user's muscle memory all carry over.
6
+ *
7
+ * Two runtime differences (SYNC.md has the full list):
8
+ *
9
+ * - The plugins ran the CHECK from an idle event, so ralphflow_continue was
10
+ * "pure state management" that promised verification would happen "when you
11
+ * go idle". Here the runner owns execution: continue mutates the state and
12
+ * then calls ensureRunning, and the loop does the rest. The user-facing texts
13
+ * say "自动" either way; only the mechanism moved.
14
+ * - opencode needed no lock (one plugin process per project). A `ralph` CLI is
15
+ * an ordinary process, so every state mutation takes the cross-process
16
+ * instance lock, and start/continue refuse an instance another live process
17
+ * is already driving.
18
+ */
19
+ import type { Engine } from "../engine/core.js";
20
+ import type { Runner } from "../engine/runner.js";
21
+ import { type ToolDefinition } from "../pi/adapter.js";
22
+ export interface ToolsContext {
23
+ engine: Engine;
24
+ runner: Runner;
25
+ /** Id of the main chat session — the ownership token in state.session_id. */
26
+ getSessionId(): string;
27
+ }
28
+ /**
29
+ * The state-machine core of "continue": approve a manual review / resume a
30
+ * paused workflow / recover from a crash / attach to an instance interrupted
31
+ * mid-DO. Pulled out of the `ralphflow_continue` tool so `ralphflow continue`
32
+ * (the headless CLI verb in headless.ts) can drive the exact same six
33
+ * branches without a chat session or a run-view attach — headless has no
34
+ * `ctx.ui.custom()` to borrow a terminal from, and doesn't need one: this
35
+ * function only mutates state and returns what happened, it never touches
36
+ * the runner or the UI. Caller is responsible for the instance lock (both
37
+ * call sites already need `withInstanceLock` for other reasons) and for
38
+ * calling `runner.ensureRunning(instId)` afterward.
39
+ *
40
+ * `attached`: true when the caller does NOT already own this instance's
41
+ * session — this is what makes branch 5 (crash-recovery re-attach) reachable.
42
+ * Headless callers always pass true: a one-shot CLI invocation has no
43
+ * standing session identity to already "be" the owner of anything.
44
+ */
45
+ export declare function resolveContinueAction(engine: Engine, instId: string, sessionId: string, attached: boolean): string;
46
+ export declare function createTools(ctx: ToolsContext): ToolDefinition[];
47
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/commands/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAIhD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAInE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,YAAY,IAAI,MAAM,CAAC;CACxB;AAkED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAuKlH;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,cAAc,EAAE,CAsX/D"}