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.
- package/LICENSE +21 -0
- package/README.md +428 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +56 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/prompts.d.ts +25 -0
- package/dist/commands/prompts.d.ts.map +1 -0
- package/dist/commands/prompts.js +249 -0
- package/dist/commands/prompts.js.map +1 -0
- package/dist/commands/tools.d.ts +47 -0
- package/dist/commands/tools.d.ts.map +1 -0
- package/dist/commands/tools.js +633 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/engine/check-bash.d.ts +121 -0
- package/dist/engine/check-bash.d.ts.map +1 -0
- package/dist/engine/check-bash.js +373 -0
- package/dist/engine/check-bash.js.map +1 -0
- package/dist/engine/check.d.ts +47 -0
- package/dist/engine/check.d.ts.map +1 -0
- package/dist/engine/check.js +298 -0
- package/dist/engine/check.js.map +1 -0
- package/dist/engine/core.d.ts +153 -0
- package/dist/engine/core.d.ts.map +1 -0
- package/dist/engine/core.js +1984 -0
- package/dist/engine/core.js.map +1 -0
- package/dist/engine/lock.d.ts +27 -0
- package/dist/engine/lock.d.ts.map +1 -0
- package/dist/engine/lock.js +121 -0
- package/dist/engine/lock.js.map +1 -0
- package/dist/engine/runner.d.ts +108 -0
- package/dist/engine/runner.d.ts.map +1 -0
- package/dist/engine/runner.js +510 -0
- package/dist/engine/runner.js.map +1 -0
- package/dist/engine/skills.d.ts +53 -0
- package/dist/engine/skills.d.ts.map +1 -0
- package/dist/engine/skills.js +109 -0
- package/dist/engine/skills.js.map +1 -0
- package/dist/engine/step-tools.d.ts +22 -0
- package/dist/engine/step-tools.d.ts.map +1 -0
- package/dist/engine/step-tools.js +45 -0
- package/dist/engine/step-tools.js.map +1 -0
- package/dist/engine/types.d.ts +136 -0
- package/dist/engine/types.d.ts.map +1 -0
- package/dist/engine/types.js +20 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/headless.d.ts +57 -0
- package/dist/headless.d.ts.map +1 -0
- package/dist/headless.js +318 -0
- package/dist/headless.js.map +1 -0
- package/dist/pi/adapter.d.ts +135 -0
- package/dist/pi/adapter.d.ts.map +1 -0
- package/dist/pi/adapter.js +231 -0
- package/dist/pi/adapter.js.map +1 -0
- package/dist/pi/interactive.d.ts +28 -0
- package/dist/pi/interactive.d.ts.map +1 -0
- package/dist/pi/interactive.js +58 -0
- package/dist/pi/interactive.js.map +1 -0
- package/dist/pi/tui.d.ts +12 -0
- package/dist/pi/tui.d.ts.map +1 -0
- package/dist/pi/tui.js +12 -0
- package/dist/pi/tui.js.map +1 -0
- package/dist/tui/app.d.ts +25 -0
- package/dist/tui/app.d.ts.map +1 -0
- package/dist/tui/app.js +47 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/embed.d.ts +42 -0
- package/dist/tui/embed.d.ts.map +1 -0
- package/dist/tui/embed.js +38 -0
- package/dist/tui/embed.js.map +1 -0
- package/dist/tui/extension.d.ts +88 -0
- package/dist/tui/extension.d.ts.map +1 -0
- package/dist/tui/extension.js +114 -0
- package/dist/tui/extension.js.map +1 -0
- package/dist/tui/history-editor.d.ts +38 -0
- package/dist/tui/history-editor.d.ts.map +1 -0
- package/dist/tui/history-editor.js +55 -0
- package/dist/tui/history-editor.js.map +1 -0
- package/dist/tui/launcher.d.ts +24 -0
- package/dist/tui/launcher.d.ts.map +1 -0
- package/dist/tui/launcher.js +97 -0
- package/dist/tui/launcher.js.map +1 -0
- package/dist/tui/render.d.ts +87 -0
- package/dist/tui/render.d.ts.map +1 -0
- package/dist/tui/render.js +266 -0
- package/dist/tui/render.js.map +1 -0
- package/dist/tui/run-app.d.ts +49 -0
- package/dist/tui/run-app.d.ts.map +1 -0
- package/dist/tui/run-app.js +317 -0
- package/dist/tui/run-app.js.map +1 -0
- package/dist/tui/run-model.d.ts +162 -0
- package/dist/tui/run-model.d.ts.map +1 -0
- package/dist/tui/run-model.js +280 -0
- package/dist/tui/run-model.js.map +1 -0
- package/dist/tui/run-view.d.ts +71 -0
- package/dist/tui/run-view.d.ts.map +1 -0
- package/dist/tui/run-view.js +167 -0
- package/dist/tui/run-view.js.map +1 -0
- package/dist/tui/welcome-header.d.ts +40 -0
- package/dist/tui/welcome-header.d.ts.map +1 -0
- package/dist/tui/welcome-header.js +90 -0
- package/dist/tui/welcome-header.js.map +1 -0
- package/package.json +55 -0
- package/skills/c-to-rust-audit/SKILL.md +67 -0
- package/skills/c-to-rust-implement/SKILL.md +151 -0
- package/skills/c-to-rust-implement/references/c-to-rust-patterns.md +86 -0
- package/skills/c-to-rust-implement/references/conditional-compilation.md +47 -0
- package/skills/c-to-rust-implement/references/crate-reference.md +15 -0
- package/skills/c-to-rust-implement/references/error-strategies.md +80 -0
- package/skills/c-to-rust-implement/references/inline-asm.md +37 -0
- package/skills/c-to-rust-plan/SKILL.md +166 -0
- package/skills/c-to-rust-plan/references/detection-commands.md +66 -0
- package/skills/c-to-rust-test-gen/SKILL.md +130 -0
- package/skills/c-to-rust-test-gen/references/proptest-patterns.md +81 -0
- package/skills/c-to-rust-test-gen/references/test-porting.md +56 -0
- package/skills/c-to-rust-validate/SKILL.md +121 -0
- package/skills/everything2rust-audit/SKILL.md +69 -0
- package/skills/everything2rust-design/SKILL.md +121 -0
- package/skills/everything2rust-design/references/domain-playbooks.md +68 -0
- package/skills/everything2rust-design/references/paradigm-map.md +99 -0
- package/skills/everything2rust-implement/SKILL.md +101 -0
- package/skills/everything2rust-spec/SKILL.md +86 -0
- package/skills/everything2rust-spec/references/oracle-strategies.md +96 -0
- package/skills/everything2rust-survey/SKILL.md +99 -0
- package/skills/everything2rust-test-gen/SKILL.md +68 -0
- package/skills/everything2rust-test-gen/references/harness-patterns.md +186 -0
- package/skills/everything2rust-validate/SKILL.md +85 -0
- package/workflows/c-to-rust.yaml +202 -0
- package/workflows/everything2rust.yaml +259 -0
- package/workflows/loop.yaml +68 -0
- package/workflows/spec.yaml +183 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 534529531
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
# ralph-flow-pi
|
|
2
|
+
|
|
3
|
+
**让 AI 自己把任务做完、自己验证、失败了自己重试 —— 不用你盯着,也不用你反复复制粘贴报错信息。**
|
|
4
|
+
|
|
5
|
+
命令行工具,基于 [Pi SDK](https://github.com/earendil-works/pi) 构建,是 [ralph-flow](https://github.com/534529531/ralph-flow)(opencode 插件版)的独立 CLI 重写。
|
|
6
|
+
|
|
7
|
+
## 特性
|
|
8
|
+
|
|
9
|
+
- **不怕聊天越聊越长** —— 每一步都在一个全新会话里执行,不会因为任务做到第 7 步、聊天记录已经很长了,模型就开始丢三落四、跑偏方向
|
|
10
|
+
- **验证者不会官官相护** —— 验证这一步是独立开的只读会话,看不到你是怎么改的,只看结果说话;甚至可以指定用另一个模型当裁判(比如用 GPT 验证 Claude 写的代码)
|
|
11
|
+
- **崩溃 / 关掉重开不丢进度** —— 每一步的会话记录会落盘,中断后接着原来的会话继续,不用整个重来
|
|
12
|
+
- **界面就是聊天,随时能插话** —— 工作流跑起来时屏幕会自动切到实时视图,但直接打字就是在指挥它;按 `Esc` 随时退回聊天,工作流照常在后台跑,等你回来看
|
|
13
|
+
- **老工作流 YAML 直接能用** —— 迁移自插件版 ralph-flow,工作流定义和 7 个斜杠命令零改动兼容
|
|
14
|
+
|
|
15
|
+
## 快速开始
|
|
16
|
+
|
|
17
|
+
### 前置条件
|
|
18
|
+
|
|
19
|
+
- [Node.js](https://nodejs.org/) 20+
|
|
20
|
+
- 一个 Pi SDK 支持的模型账号或 API key(Anthropic / OpenAI / Gemini 等都行,见下面「配置模型凭据」)
|
|
21
|
+
|
|
22
|
+
### 安装
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g ralph-flow-pi
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
或者不装,直接跑一次:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx ralph-flow-pi
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**从源码构建**(贡献代码,或者还没发布到 npm 时):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone <仓库地址> ralph-flow-pi
|
|
38
|
+
cd ralph-flow-pi
|
|
39
|
+
npm install
|
|
40
|
+
npm run build
|
|
41
|
+
node dist/cli.js
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
想在任意目录用 `ralphflow` 命令,在仓库目录下跑一次 `npm link`。
|
|
45
|
+
|
|
46
|
+
### 验证安装
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
ralphflow doctor
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
看到类似下面的输出说明装好了:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
## 概览
|
|
56
|
+
- 可启动工作流:4 个
|
|
57
|
+
- 有问题的定义文件:0 个
|
|
58
|
+
...
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 配置模型凭据
|
|
62
|
+
|
|
63
|
+
第一次进 `ralphflow` 之后,在聊天里输入 `/login` 按提示登录;或者提前设好环境变量,比如:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
支持的 provider 很多(Anthropic、OpenAI、Gemini、Bedrock、OpenRouter 等),凭据体系是 Pi SDK 自己的,跟本工具无关。
|
|
70
|
+
|
|
71
|
+
## 使用方法
|
|
72
|
+
|
|
73
|
+
### 入口就是聊天
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
ralphflow
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
跟直接用 Claude Code 聊天没有区别——写代码、回答问题、聊需求都行,工作流只是聊天里能让它做的一件事。第一次用建议先跑一个小任务(比如"用 loop 工作流帮我建一个 hello.txt"),确认整条链路通了,再上真任务。
|
|
80
|
+
|
|
81
|
+
### 斜杠命令
|
|
82
|
+
|
|
83
|
+
| 命令 | 作用 | 什么时候用 |
|
|
84
|
+
|------|------|-----------|
|
|
85
|
+
| `/ralphflow-start` | 启动工作流(新实例) | 开始一个新任务,一句话里说清楚工作流名和任务描述 |
|
|
86
|
+
| `/ralphflow-continue` | 通过人工审查门 / 恢复暂停 / 接管中断实例 | 审查通过后 / 工作流暂停后 / 新会话续接 |
|
|
87
|
+
| `/ralphflow-watch` | 重新接管一个还在跑、你之前 `Esc` 退出的实例 | 想回去看看进度 |
|
|
88
|
+
| `/ralphflow-status` | 查看状态 | 想知道进展到哪了 |
|
|
89
|
+
| `/ralphflow-list` | 列出可用工作流 + 活跃实例 | 查看有哪些工作流/实例 |
|
|
90
|
+
| `/ralphflow-cancel` | 取消工作流实例 | 放弃当前任务 |
|
|
91
|
+
| `/ralphflow-create` | 交互式设计并创建自定义工作流 | 想定制自己的流程,不想手写 YAML |
|
|
92
|
+
| `/ralphflow-doctor` | 诊断所有工作流定义和实例状态 | 自定义工作流不生效 / 启动报错 / 例行体检 |
|
|
93
|
+
|
|
94
|
+
这些命令不是严格的位置参数,而是自然语言驱动:`/ralphflow-start` 需要你在同一句话里说清楚**用哪个工作流**和**做什么任务**,比如:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
/ralphflow-start 用 loop 工作流,修复登录页面的表单验证 bug
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
工作流名或任务没说清楚,模型会直接问你,不会自己瞎猜。
|
|
101
|
+
|
|
102
|
+
### headless 子命令(不进交互界面,适合脚本 / CI)
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
ralphflow status [实例ID] # 查看实例(不带 ID 时列出全部,支持 ID 唯一前缀)
|
|
106
|
+
ralphflow list # 列出工作流与活跃实例
|
|
107
|
+
ralphflow doctor # 诊断所有工作流定义与 skill
|
|
108
|
+
ralphflow continue [实例ID] # 恢复暂停/审查门/崩溃的实例,跑到下一个停点再返回
|
|
109
|
+
ralphflow cancel [实例ID] # 取消并归档报告
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`continue` 是唯一"做完事之后还会继续跑一段"的 headless 命令——它恢复实例后驱动到下一次停下来(再次需要人工审查/暂停,或者完成)才退出进程,不会把自己变成一个常驻后台的守护进程。`create` 天生需要一段对话,没有 headless 形式。
|
|
113
|
+
|
|
114
|
+
## 内置工作流
|
|
115
|
+
|
|
116
|
+
| 名称 | 用途 |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `loop` | 检查点驱动:先拆解任务为检查点清单,再循环执行直到全部通过 |
|
|
119
|
+
| `spec` | 需求分析 → 规格 → 设计 → 任务拆解 → 实现 → 验收 → 归档,适合完整功能开发 |
|
|
120
|
+
| `c-to-rust` | C 项目翻译为惯用安全 Rust,逐模块渐进移植 + TDD |
|
|
121
|
+
| `everything2rust` | 任意语言的系统重写为 Rust,行为契约 + 独立审计的方法论,适合大改造 |
|
|
122
|
+
|
|
123
|
+
### loop — 检查点驱动循环
|
|
124
|
+
|
|
125
|
+
适用场景:范围明确的单个任务。
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
帮我用 loop 工作流修复登录页面的表单验证 bug
|
|
129
|
+
帮我用 loop 工作流给 user.py 加单元测试,覆盖率 > 80%
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
checkpoints(拆解需求为可验证的检查点清单)
|
|
134
|
+
↓
|
|
135
|
+
loop(逐项实现并自验,直到全部打勾;最多重试 100 次)
|
|
136
|
+
↓
|
|
137
|
+
完成
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### spec — 规格驱动开发
|
|
141
|
+
|
|
142
|
+
适用场景:需要从需求到实现的完整流程。
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
propose → specs → design → tasks → implement → verify → archive
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
每一步的产出文件都归档在 `.ralph-flow/artifacts/` 下,一路能看到 proposal.md、specs.md、design.md、tasks.md 等。
|
|
149
|
+
|
|
150
|
+
### c-to-rust / everything2rust
|
|
151
|
+
|
|
152
|
+
这两个是这个项目独有、插件版没有的能力:专门把现有代码库重写成 Rust。`c-to-rust` 针对 C 项目;`everything2rust` 更通用,能处理任意语言的项目,走的是"先摸清系统行为契约、再增量实现、再独立审计"的方法论,步骤更多、耗时更长,适合真正的大改造而不是小任务。`everything2rust` 的 `design` 步骤默认是人工审查门(见下)。
|
|
153
|
+
|
|
154
|
+
## 工作流机制详解
|
|
155
|
+
|
|
156
|
+
### 执行(DO)与验证(CHECK)
|
|
157
|
+
|
|
158
|
+
每一步分两段:AI 先执行任务(DO),完成后交给**另一个独立的只读会话**验证(CHECK)——验证者看不到你是怎么改的,只能通过检查实际结果来判断,通过则自动进入下一步,不通过则带着失败原因自动重试。
|
|
159
|
+
|
|
160
|
+
### 失败重试
|
|
161
|
+
|
|
162
|
+
CHECK 不通过时:
|
|
163
|
+
1. 失败次数 +1,若小于该步骤的 `max_fail_count`,自动重试同一步骤
|
|
164
|
+
2. 重试时会把上次失败原因带给 DO,避免重复犯同一个错
|
|
165
|
+
3. 达到 `max_fail_count` 仍不通过,工作流**暂停**,等你介入
|
|
166
|
+
|
|
167
|
+
### 人工审查门(manual_step)
|
|
168
|
+
|
|
169
|
+
某些步骤会在 DO 完成后主动停下来等你看一眼,比如 `everything2rust` 的 `design` 步骤(技术方案定下来了,值得你看一眼再往下走):
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
DO 完成 → 停下来提示你审查
|
|
173
|
+
→ 满意:/ralphflow-continue 通过 → 进入 CHECK → 通过则自动继续
|
|
174
|
+
→ 不满意:直接打字说要改什么 → 模型修改后再次进入审查门
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### 随时插话,随时退出
|
|
178
|
+
|
|
179
|
+
工作流跑的时候屏幕会自动接管成实时运行视图(步骤条 + 当前阶段耗时),但**这不是另一个 App,是同一个聊天会话借用了同一块终端**:
|
|
180
|
+
|
|
181
|
+
- DO 执行中直接打字就是插话,模型会把你说的话接进去接着干
|
|
182
|
+
- `Esc`(输入框为空时)随时退回聊天,工作流**不会停**,继续在后台跑;需要你时(人工审查/暂停/完成)会自动出现在聊天记录里,同时响一声终端提示音
|
|
183
|
+
- 想再看,直接说"带我看看",或者打 `/ralphflow-watch`——模型不会自己主动去查,只有你要求时才会
|
|
184
|
+
|
|
185
|
+
### 多实例并行
|
|
186
|
+
|
|
187
|
+
同一个项目目录可以同时跑多个工作流实例:**每个聊天会话一个实例**。开几个会话就能并行跑几个工作流,互不干扰;`status`/`continue`/`cancel` 都支持用实例 ID 的唯一前缀指定目标。
|
|
188
|
+
|
|
189
|
+
## 实际使用示例
|
|
190
|
+
|
|
191
|
+
### 全自动跑完一个简单任务
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
你: 帮我用 loop 工作流修复 user.py 里的空指针异常
|
|
195
|
+
|
|
196
|
+
[屏幕自动接管为运行视图]
|
|
197
|
+
|
|
198
|
+
✓ ✓ ▶ ○ ○ loop · DO 0:42
|
|
199
|
+
▸ 读取 user.py,定位空指针触发点...
|
|
200
|
+
▸ 编写修复,运行测试...
|
|
201
|
+
|
|
202
|
+
✓ ✓ ✓ ○ ○ loop · CHECK 0:08
|
|
203
|
+
独立会话正在核对修复是否生效...
|
|
204
|
+
|
|
205
|
+
✅ 工作流完成!报告已归档到 .ralph-flow/reports/
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### CHECK 不通过,自动重试一次
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
✓ ✓ ✗(1/5) loop · CHECK 失败
|
|
212
|
+
原因:进度条组件未实现,拖拽区域缺少样式。
|
|
213
|
+
|
|
214
|
+
[自动带着失败原因重新进入 DO]
|
|
215
|
+
|
|
216
|
+
▸ 补充进度条组件,补齐样式...
|
|
217
|
+
|
|
218
|
+
✓ ✓ ✓ ○ ○ CHECK 通过
|
|
219
|
+
|
|
220
|
+
✅ 工作流完成!
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### 人工审查门
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
✓ ✓ ▶(design,等待审查)
|
|
227
|
+
|
|
228
|
+
设计方案已经写好,看看 .ralph-flow/artifacts/.../design.md,
|
|
229
|
+
觉得可以就 /ralphflow-continue,不行就直接说要改哪里。
|
|
230
|
+
|
|
231
|
+
你: 用 trait 而不是 enum 来抽象这层,方便以后加新后端
|
|
232
|
+
|
|
233
|
+
[模型修改设计,再次停在审查门]
|
|
234
|
+
|
|
235
|
+
你: /ralphflow-continue
|
|
236
|
+
|
|
237
|
+
[进入独立验证 → 通过 → 自动继续后续步骤]
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Esc 退出,后台照跑,回来再看
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
你: 帮我跑一下 spec 工作流,实现登录接口
|
|
244
|
+
|
|
245
|
+
[自动接管为运行视图,DO 正在跑...]
|
|
246
|
+
|
|
247
|
+
[按 Esc]
|
|
248
|
+
|
|
249
|
+
引擎: 已切回聊天。工作流在后台继续运行。
|
|
250
|
+
想再看实时进度:直接说"看着它跑",或者输入 /ralphflow-watch。
|
|
251
|
+
|
|
252
|
+
你: 今天北京天气怎么样?
|
|
253
|
+
|
|
254
|
+
引擎: [正常回答天气,不会顺手提起工作流,也不会自己跑去查状态]
|
|
255
|
+
|
|
256
|
+
(几分钟后,CHECK 通过、工作流完成)
|
|
257
|
+
|
|
258
|
+
引擎: 🔔 spec 工作流完成了,报告在 .ralph-flow/reports/。
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## 自定义工作流
|
|
262
|
+
|
|
263
|
+
### 交互式创建(推荐)
|
|
264
|
+
|
|
265
|
+
打 `/ralphflow-create` 或者 `ralphflow create`,描述你想自动化的流程,模型会和你一起设计步骤图、生成 YAML,并自己跑 `doctor` 校验到零问题,写完即可用。
|
|
266
|
+
|
|
267
|
+
### 手写 YAML
|
|
268
|
+
|
|
269
|
+
工作流可以放在两个位置,解析顺序 **项目 → 全局 → 内置**(同名时靠前的遮蔽靠后的):
|
|
270
|
+
|
|
271
|
+
| 位置 | 作用范围 |
|
|
272
|
+
|---|---|
|
|
273
|
+
| `.ralph-flow/workflows/` | 仅本项目 |
|
|
274
|
+
| `~/.config/ralph-flow-pi/workflows/` | 全局,所有项目可用,更新不会覆盖 |
|
|
275
|
+
|
|
276
|
+
```yaml
|
|
277
|
+
description: 先分析再实现
|
|
278
|
+
|
|
279
|
+
steps:
|
|
280
|
+
- id: analyze
|
|
281
|
+
desc: 任务分析
|
|
282
|
+
do: 分析需求,产出设计文档。
|
|
283
|
+
input: 用户需求
|
|
284
|
+
output: "design.md"
|
|
285
|
+
check: 打开 design.md,核对是否完整、技术上合理。
|
|
286
|
+
on_pass: execute
|
|
287
|
+
on_fail: analyze
|
|
288
|
+
max_fail_count: 3
|
|
289
|
+
|
|
290
|
+
- id: execute
|
|
291
|
+
desc: 实现
|
|
292
|
+
do: 按设计实现,跑测试直到全绿。
|
|
293
|
+
input: design.md
|
|
294
|
+
output: 测试通过的可工作代码
|
|
295
|
+
check: 自己跑测试套件,核对实现与 design.md 一致。
|
|
296
|
+
on_pass: done
|
|
297
|
+
on_fail: execute
|
|
298
|
+
max_fail_count: 5
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
写完运行 `ralphflow doctor` 校验。**记住一件事**:每个步骤是全新的上下文窗口,步骤之间**只有** `input`/`output` 里写的话和 artifacts 目录里的文件会传过去——需要上一步的结论,就明确写出它在哪个文件里。
|
|
302
|
+
|
|
303
|
+
### 跨模型对抗验证
|
|
304
|
+
|
|
305
|
+
```yaml
|
|
306
|
+
adversarial_check:
|
|
307
|
+
model: "openai/gpt-5.2" # 用 GPT 验证 Claude 写的代码
|
|
308
|
+
timeout_ms: 1800000
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
检查者与执行者不同源,同源偏见被结构性削弱——这是插件版做不到的,它锁死在单一宿主的模型上。
|
|
312
|
+
|
|
313
|
+
### CHECK 阶段的自定义命令
|
|
314
|
+
|
|
315
|
+
CHECK 阶段默认只放行一份内置的 bash 白名单(`cat`/`grep`/`git diff`/`cargo test`/`npm test`/`pytest` 等)。如果你的项目用自定义 CLI、`just`、`bazel`、`./scripts/check.sh` 这类命令,需要显式声明:
|
|
316
|
+
|
|
317
|
+
```yaml
|
|
318
|
+
adversarial_check:
|
|
319
|
+
extra_allowed_bash:
|
|
320
|
+
- "./scripts/check.sh *"
|
|
321
|
+
- "just test*"
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
`ralphflow doctor` 会报告每条被拒绝的模式及原因;`rm`/`curl`/`sudo`/`git`/`npm` 等约 50 个命令永远无法通过这个字段打开。
|
|
325
|
+
|
|
326
|
+
## 常见问题
|
|
327
|
+
|
|
328
|
+
**loop 还是 spec 怎么选?**
|
|
329
|
+
|
|
330
|
+
任务范围明确、一个人一天能干完的用 `loop`(修 bug、写测试、重构、写文档);需要从需求到实现走完整流程的用 `spec`(新功能开发、架构改造)。拿不准就 `/ralphflow-create` 让它帮你设计。
|
|
331
|
+
|
|
332
|
+
**验证会不会很慢、很贵?**
|
|
333
|
+
|
|
334
|
+
可以给 CHECK 指定更便宜更快的模型:
|
|
335
|
+
|
|
336
|
+
```yaml
|
|
337
|
+
adversarial_check:
|
|
338
|
+
model: "anthropic/claude-haiku-4-5"
|
|
339
|
+
timeout_ms: 600000
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
**验证失败了,但我觉得它判错了?**
|
|
343
|
+
|
|
344
|
+
CHECK 是一次独立、只读的判断,也会看漏东西。趁 DO 重试阶段插一句话说明情况,模型会带着你的说明一起处理;如果已经暂停了,`/ralphflow-continue` 时也可以先留一句话。
|
|
345
|
+
|
|
346
|
+
**能同时跑多个工作流吗?**
|
|
347
|
+
|
|
348
|
+
能。同一项目目录开几个聊天会话,每个会话各自最多带一个实例,互不干扰。
|
|
349
|
+
|
|
350
|
+
**状态存在哪?**
|
|
351
|
+
|
|
352
|
+
`.ralph-flow/instances/<实例ID>/state.json`,完成或取消后实例目录清理,最终报告归档到 `.ralph-flow/reports/`。
|
|
353
|
+
|
|
354
|
+
## 故障排查
|
|
355
|
+
|
|
356
|
+
**`ralphflow` 命令找不到**
|
|
357
|
+
|
|
358
|
+
确认 `npm install -g ralph-flow-pi`(或 `npm link`)成功:
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
npm ls -g --depth=0 | grep ralph-flow-pi
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**`ralphflow list` 里没有我自定义的工作流**
|
|
365
|
+
|
|
366
|
+
跑 `ralphflow doctor`,它会告诉你这份 YAML 生效的是哪个文件、有没有被同名文件遮蔽、以及具体校验错误(不止第一条)。
|
|
367
|
+
|
|
368
|
+
**YAML 解析失败**
|
|
369
|
+
|
|
370
|
+
常见原因:缩进用了 Tab(应该用空格)、特殊字符没加引号、缺少必填字段(`id`/`desc`/`on_pass`/`on_fail`/`max_fail_count`)。
|
|
371
|
+
|
|
372
|
+
**模型没反应 / 提示凭据错误**
|
|
373
|
+
|
|
374
|
+
确认 `/login` 走完了流程,或者对应 provider 的环境变量(如 `ANTHROPIC_API_KEY`)已经设置。
|
|
375
|
+
|
|
376
|
+
**Esc 退出后忘了怎么回去看进度**
|
|
377
|
+
|
|
378
|
+
直接说"帮我看看工作流跑得怎么样了",或者打 `/ralphflow-watch`;忘了实例名先 `/ralphflow-list` 或 `ralphflow list`。
|
|
379
|
+
|
|
380
|
+
## 文件存储结构
|
|
381
|
+
|
|
382
|
+
```
|
|
383
|
+
你的项目/
|
|
384
|
+
└── .ralph-flow/
|
|
385
|
+
├── instances/<实例ID>/ # 运行时状态,完成/取消后清理
|
|
386
|
+
│ ├── state.json
|
|
387
|
+
│ ├── state-stack.json # 子工作流栈
|
|
388
|
+
│ └── sessions/ # 每次 DO/CHECK 尝试的会话记录
|
|
389
|
+
├── artifacts/<任务摘要>/ # 工作流产出的文档,长期保留
|
|
390
|
+
├── reports/ # 完成/取消后的最终报告
|
|
391
|
+
│ └── <实例ID>-final-report.md
|
|
392
|
+
├── workflows/ # 项目自定义工作流(仅本项目,优先级最高)
|
|
393
|
+
└── logs/ # 执行日志
|
|
394
|
+
|
|
395
|
+
~/.config/ralph-flow-pi/
|
|
396
|
+
└── workflows/ # 全局自定义工作流(所有项目可用)
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## 从插件版迁移
|
|
400
|
+
|
|
401
|
+
- **工作流 YAML**:直接可用,零改动
|
|
402
|
+
- **数据目录**:本包用 `.ralph-flow/`,不会自动迁移插件版已有的实例——迁移前先把在跑的工作流跑完或取消
|
|
403
|
+
- **`adversarial_check.agent`**:接受但忽略(本引擎没有 agent 概念,只读沙箱是内置的),`ralphflow doctor` 会提示
|
|
404
|
+
- **裸模型名**(`model: sonnet`):需改成 `"anthropic/claude-sonnet-4-5"` 这种带 provider 前缀的写法,`ralphflow doctor` 会提示
|
|
405
|
+
|
|
406
|
+
## 开发
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
npm install
|
|
410
|
+
npm run build
|
|
411
|
+
npm test # 401 个测试,无需 API key
|
|
412
|
+
ralphflow doctor
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
从上游插件重新同步领域 skill 与工作流:
|
|
416
|
+
|
|
417
|
+
```bash
|
|
418
|
+
node scripts/import-from-claude.mjs <claude-plugin-path>
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
不要手改导入的文件——机械替换规则和三个实现之间必须逐字一致的语义边界见 [SYNC.md](SYNC.md)。
|
|
422
|
+
|
|
423
|
+
## 已知边界
|
|
424
|
+
|
|
425
|
+
- Pi SDK 处于 0.x 且迭代很快,版本精确 pin,所有 SDK 接触收口在 `src/pi/` 一处,升级前先跑 `adapter.test.ts` 这道门。
|
|
426
|
+
- CHECK 阶段的 bash 白名单是黑名单式的逐条排查(拦截命令替换、写重定向、脚本内嵌写语法等),不是形式化证明的沙箱。它管的是命令的**名字和语法**,不管被放行的程序运行时实际做了什么——`cargo test`/`npm test` 一旦放行就会真的执行你的测试代码/构建脚本,拿到进程的完整权限。这跟你自己手动跑一遍项目测试套件时承担的信任边界是一样的,需要更强隔离时应该把整个 `ralphflow` 进程放进容器,而不是指望这份白名单。
|
|
427
|
+
|
|
428
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ralph — entry point.
|
|
4
|
+
*
|
|
5
|
+
* No verb → interactive TUI (the normal way to use this).
|
|
6
|
+
* A verb → headless one-shot for scripts/CI.
|
|
7
|
+
*/
|
|
8
|
+
import { runHeadless } from "./headless.js";
|
|
9
|
+
const HELP = `ralphflow — DO → CHECK 工作流引擎(每个步骤运行在全新、隔离的 AI 会话中)
|
|
10
|
+
|
|
11
|
+
用法:
|
|
12
|
+
ralphflow 通用聊天——可以直接让我跑工作流("用 spec 工作流帮我实现一个登录接口"),
|
|
13
|
+
启动后会接管终端显示实时运行视图,Esc 可随时切回聊天
|
|
14
|
+
ralphflow create [描述] 同一个聊天,预置一句设计新工作流的开场白
|
|
15
|
+
ralphflow status [实例ID] 查看实例状态(不带 ID 时列出全部)
|
|
16
|
+
ralphflow list 列出可用工作流与活跃实例
|
|
17
|
+
ralphflow doctor 诊断所有工作流定义与 skill
|
|
18
|
+
ralphflow continue [实例ID] 不进交互界面,恢复暂停/审查门/崩溃的实例,
|
|
19
|
+
跑到下一个停点(再次暂停或完成)再返回
|
|
20
|
+
ralphflow cancel [实例ID] 取消实例并归档报告
|
|
21
|
+
ralphflow --help 显示本帮助
|
|
22
|
+
|
|
23
|
+
工作流定义(YAML)解析顺序:项目 .ralph-flow/workflows/ → 全局 ~/.config/ralph-flow-pi/workflows/ → 内置。
|
|
24
|
+
`;
|
|
25
|
+
async function main() {
|
|
26
|
+
const argv = process.argv.slice(2);
|
|
27
|
+
if (argv[0] === "--help" || argv[0] === "-h" || argv[0] === "help") {
|
|
28
|
+
process.stdout.write(HELP);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (argv.length === 0) {
|
|
32
|
+
// The default entry: a general chat, same as `create`. Starting a
|
|
33
|
+
// workflow (natural language or /ralphflow-start) takes over the
|
|
34
|
+
// terminal with the dedicated run view for the duration of the run — see
|
|
35
|
+
// tui/embed.ts. The standalone picker-first run view (tui/run-app.ts's
|
|
36
|
+
// runApp) still exists but is no longer wired to any CLI verb.
|
|
37
|
+
const { runChat } = await import("./tui/app.js");
|
|
38
|
+
await runChat(process.cwd());
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (argv[0] === "create") {
|
|
42
|
+
// Designing a NEW workflow is a genuine conversation, so it uses the chat
|
|
43
|
+
// surface (the one place chat fits) rather than the run view.
|
|
44
|
+
const { runCreateMode } = await import("./tui/app.js");
|
|
45
|
+
await runCreateMode(process.cwd(), argv.slice(1).join(" "));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const { text, code } = await runHeadless(argv[0], argv.slice(1), process.cwd());
|
|
49
|
+
(code === 0 ? process.stdout : process.stderr).write(text.endsWith("\n") ? text : text + "\n");
|
|
50
|
+
process.exitCode = code;
|
|
51
|
+
}
|
|
52
|
+
main().catch((e) => {
|
|
53
|
+
process.stderr.write(`ralph: ${e?.stack || e?.message || String(e)}\n`);
|
|
54
|
+
process.exitCode = 1;
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;CAeZ,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;QACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,kEAAkE;QAClE,iEAAiE;QACjE,yEAAyE;QACzE,uEAAuE;QACvE,+DAA+D;QAC/D,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACjD,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QACzB,0EAA0E;QAC1E,8DAA8D;QAC9D,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACvD,MAAM,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAChF,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC/F,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAM,EAAE,EAAE;IACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
export interface CommandTemplate {
|
|
20
|
+
description: string;
|
|
21
|
+
/** $ARGUMENTS is replaced with whatever followed the slash command. */
|
|
22
|
+
render(args: string): string;
|
|
23
|
+
}
|
|
24
|
+
export declare const COMMAND_PROMPTS: Record<string, CommandTemplate>;
|
|
25
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/commands/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CAC9B;AASD,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAsP3D,CAAC"}
|