pi-ultracode 0.1.0 → 0.1.2

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 CHANGED
@@ -1,225 +1,478 @@
1
- # pi-ultracode
1
+ # Ultracode
2
2
 
3
- > Claude-Code-style **ultracode** for [Pi](https://github.com/earendil-works/pi).
3
+ **Ultracode** [Pi](https://github.com/badlogic/pi-mono) 的“全力执行”模式。它把 Pi 的 Agentic Loop 从单线程编码助手升级为能够运行子代理团队的编排器。
4
4
 
5
- `ultracode` is an effort mode that turns Pi into a relentless, multi-agent
6
- orchestrator. While it's on, Pi raises its thinking to **xhigh** and treats
7
- "author and run a workflow" as the **default** for every substantive task —
8
- decomposing work, fanning it out across isolated subagents, and adversarially
9
- verifying findings before committing to an answer. Token cost is not the
10
- constraint; correctness and coverage are.
5
+ 启用 Ultracode 后,主代理会获得一条 `workflow` 工具,以及一段要求它主动使用该工具处理复杂任务的系统提示词。扩展加载时会先注册该工具,并在模型请求前的 input `before_agent_start` 边界按模式校准 active tools;未启用或已暂停时,残留调用会被拒绝。每个子代理都运行在独立的内存 Pi 会话中,拥有标准编码工具、独立上下文,并可选择结构化输出、模型覆盖、Agent Type 和隔离的 git worktree。
11
6
 
12
- This single extension implements the full ultracode surface:
7
+ Ultracode 保留 Pi 自身的核心循环、内存模型、工具系统、扩展 API 与会话格式。它是在 Pi 之上增加编排能力,而不是替换 Pi。
13
8
 
14
- | Pillar | What you get |
9
+ ## 功能
10
+
11
+ | 能力 | 说明 |
15
12
  | --- | --- |
16
- | **Ultracode mode** | `/ultracode on` raises thinking to xhigh, keeps the `workflow` tool active, and injects a standing "orchestrate + verify by default" system block on every turn. Survives reload / resume / fork via session entries. Optional token budget. |
17
- | **The `workflow` tool** | A deterministic JavaScript orchestrator: `agent()`, `parallel()`, `pipeline()`, `phase()`, `log()`, `workflow()` (nesting), `args`, `budget`. Plus per-agent **model overrides**, **custom agent types**, **git-worktree isolation**, a real **token budget**, **resumable runs**, and **script persistence**. |
18
- | **`/workflows` manager** | List recent and in-flight runs with live progress; inspect or abort runs. |
13
+ | `workflow` 工具 | 模型请求前按 Ultracode 状态校准;运行确定性的 JavaScript 编排脚本,并调用 `agent()`、`parallel()`、`pipeline()` `workflow()`。 |
14
+ | 独立子代理 | 每次 `agent()` 调用都会创建一条带标准编码工具的新 Pi 会话。 |
15
+ | 并行执行 | `parallel()` 并发运行任务,且保留输入顺序。 |
16
+ | 流水线 | `pipeline()` 让任务独立流经多个阶段,无需全局屏障。 |
17
+ | 结构化输出 | 传入 JSON Schema,即可通过终止型 `structured_output` 工具获得经校验的对象。 |
18
+ | Agent Type | 通过 `.pi/ultracode/agents/*.md` 定义角色提示词、工具白名单、模型和思考强度。 |
19
+ | 模型覆盖 | 每次 `agent()` 调用都可指定模型模式,例如 `anthropic/claude-sonnet-4`。 |
20
+ | Worktree 隔离 | 让写入型并行代理在临时 git worktree 中运行,并把改动安全合并回共享工作树。 |
21
+ | 进度与详情 | 实时状态、实际模型/effort、turn/工具/token 统计,以及可流式展开的 TUI 任务详情浮层。 |
22
+ | Ultracode 模式 | `/ultracode on` 启用主动编排提示词,并请求当前模型支持的最高思考强度。 |
23
+ | 配额执行 | 可选 token 预算、代理数量限制、并发限制、脚本超时与嵌套深度限制。 |
24
+
25
+ ## 为什么使用工作流
26
+
27
+ 普通的多代理提示通常依赖模型临场决定如何分解与组合任务。Ultracode 采用另一种方式:**模型编写确定性的编排脚本,运行时执行该脚本**。
19
28
 
20
- Inspired by Anthropic's [dynamic workflows in Claude Code](https://claude.com/blog/introducing-dynamic-workflows-in-claude-code),
21
- and a superset of the `pi-dynamic-workflows` prototype.
29
+ 这样可以清晰表达:
22
30
 
23
- ## Install
31
+ - 哪些任务可以并行;
32
+ - 哪些阶段依赖前一阶段的结果;
33
+ - 哪些代理应返回结构化数据;
34
+ - 何时需要共享上下文,何时需要隔离;
35
+ - 预算如何限制额外探索;
36
+ - 失败分支应如何降级。
37
+
38
+ ## 安装
24
39
 
25
40
  ```bash
26
41
  pi install npm:pi-ultracode # or: pi install /path/to/pi-ultracode
27
42
  ```
28
43
 
29
- > **Conflict note:** pi-ultracode registers a tool named `workflow`, the same name
30
- > used by `pi-dynamic-workflows`. pi-ultracode is a strict superset, so remove the
31
- > prototype first: `pi remove npm:pi-dynamic-workflows`.
44
+ > **工具冲突:** pi-ultracode 注册名为 `workflow` 的工具,与 `pi-dynamic-workflows` 相同。pi-ultracode 是后者的严格超集,请先执行 `pi remove npm:pi-dynamic-workflows` 移除原型扩展。
45
+
46
+ 安装后在 Pi 中运行 `/reload`。
47
+
48
+ 开发仓库也可直接加载:
49
+
50
+ ```bash
51
+ pi -e ./extensions/ultracode.ts
52
+ ```
32
53
 
33
- Then in Pi: `/reload`.
54
+ 仓库中提供两个兼容入口:
34
55
 
35
- ## Usage
56
+ - `extensions/ultracode.ts`:推荐的 Pi 扩展入口;
57
+ - `src/index.ts`:兼容入口,重新导出同一个扩展。
36
58
 
37
- ### Turn ultracode on
59
+ ## 快速开始
60
+
61
+ 在 Pi 中启用模式:
62
+
63
+ ```text
64
+ /ultracode on
65
+ ```
66
+
67
+ 随后给出复杂任务,例如:
38
68
 
39
69
  ```text
40
- /ultracode # TOGGLE on/off
41
- /ultracode on # xhigh thinking + default workflow orchestration
42
- /ultracode on 500k # also cap the per-session output-token budget at ~500k
43
- /ultracode budget 1m # change the budget later
44
- /ultracode status # show current mode
45
- /ultracode off # restore the previous thinking level
70
+ Review the current branch, identify correctness and compatibility risks,
71
+ fix the justified issues, and verify the result.
46
72
  ```
47
73
 
48
- > **Models without `xhigh`:** pi clamps the requested level down to the model's
49
- > maximum (e.g. glm-5.2 tops out at `high`; non-reasoning models fall to `off`) —
50
- > it never errors. `/ultracode status` shows the level that actually applied
51
- > (e.g. `ultracode: on · thinking high`). The **workflow orchestration** half of
52
- > ultracode doesn't depend on the thinking level at all, so it's unaffected by
53
- > the model you run.
74
+ 启用后,主代理会被要求在并行检视、迁移、审计或大范围修改明显有益时编写并运行工作流,而不是把所有工作塞进一个上下文。
54
75
 
55
- You can also start a session in ultracode mode with the CLI flag:
76
+ 也可以在启动时启用:
56
77
 
57
78
  ```bash
58
79
  pi --ultracode
59
80
  ```
60
81
 
61
- While on, just describe the task. Pi will write a workflow script and call the
62
- `workflow` tool, with live progress shown inline:
82
+ 工作流运行时会内联显示实时进度,例如:
63
83
 
64
84
  ```text
65
- ◆ ▶ audit_repo (4/7 done, 2 running) · 3 cached · 41.2k/500k tok
85
+ ◆ ▶ audit_repo (4/7 done, 2 running) · 3 cached · 203k token (141k new, 62k replayed) · 41.2k/500k out
66
86
  ✓ Survey 1/1
67
87
  #1 ✓ repo inventory
88
+ gpt-5.6-sol • max · 15 turns · 42 tool uses · 141k token
68
89
  ▶ Review 3/4 · 1 running
69
90
  #2 ✓ auth module
70
91
  #3 ✓ db layer
71
92
  #4 ● payments module
93
+ claude-sonnet-4 • high · 6 turns · 18 tool uses · 52.3k+ token · partial
72
94
  ▶ Verify 0/2 · 2 running
73
95
  ```
74
96
 
75
- Press `Esc` to cancel; running subagents are aborted and surfaced as skipped.
97
+ 紧凑 token 数始终是 input + output;cache read/write 与成本只出现在任务详情中。主对话会折叠较早任务并明确显示省略数量,按 `Ctrl+O` 可展开全部,或用 `F6` 打开详情。按 `Esc` 可取消;运行中的子代理会被终止并显示为 cancelled,同时保留已有输出和部分用量。
76
98
 
77
- ### Manage runs
99
+ ## 命令
78
100
 
79
101
  ```text
80
- /workflows # toggle the run panel above the editor (run again to hide)
81
- /workflows wf_ab12-3 # show one run's detail
82
- /workflows clear # hide the panel
83
- /workflows abort # abort all active runs (and hide the panel)
102
+ /ultracode # toggle on/off
103
+ /ultracode on # enable orchestration mode
104
+ /ultracode on 500k # enable it with an output-token budget
105
+ /ultracode off # disable the tool and restore the previous thinking level
106
+ /ultracode status # show status and the configured budget
107
+ /ultracode budget 500k # set a token budget
108
+ /ultracode budget off # remove the budget
109
+ /workflows # open the interactive workflow detail overlay
110
+ /workflows <runId> # open one run directly (prefix accepted)
111
+ /workflows abort # abort active runs
112
+ F6 # open the workflow detail overlay
84
113
  ```
85
114
 
86
- The panel is a static snapshot taken when you run the command, so re-run
87
- `/workflows` to refresh it, or `/workflows clear` to dismiss it. Live progress
88
- while a workflow runs is shown inline in the tool result, not in this panel.
115
+ `/workflows` `F6` 打开实时浮层。只有一个活动运行时会直接进入;多个活动运行会先显示选择器;没有活动运行时会打开最近完成的运行。宽终端使用任务/详情双栏,窄终端在列表与详情间切换。键盘操作:
116
+
117
+ - `↑` / `↓` 选择运行或任务;`Enter` 打开;`Tab` 切换双栏焦点;`Esc` 返回或关闭;
118
+ - `PageUp` / `PageDown` 滚动;`End` 恢复尾随;
119
+ - `/` 搜索任务,`r` 只看运行中的任务,`a` 恢复全部,`p` 展开或收起任务 prompt。
89
120
 
90
- ## Workflow script shape
121
+ 每次 `agent()` 调用都是一个可独立展开的任务。详情按时间交错显示 turn、assistant 正文、工具调用、重试、上下文压缩、错误与 thinking 持续时间;thinking 正文不会被捕获。正文 delta 只保存在有界内存中并以不超过每 100ms 一次的频率刷新,消息完成后改用 Markdown 渲染。
91
122
 
92
- A workflow is plain JavaScript whose first statement is a **pure literal**
93
- `export const meta`:
123
+ 所有可视化和落盘内容都会移除终端控制序列并脱敏凭据。内存上限为每任务 1MiB / 5000 行、每工作流 32MiB;最终 transcript 上限为每任务 10MB(约 1MB 头部 + 9MB 尾部)、每工作流 128MB。最终清理后的 timeline 与 manifest 保存在 session 的 `ultracode-runs/` 目录,因而 `/reload` 后仍可浏览;不会复制系统 prompt、注入 skill、AGENTS 内容或父会话上下文。
124
+
125
+ 状态行会显示实际生效的思考强度,例如:
126
+
127
+ ```text
128
+ ultracode: on · max
129
+ ultracode: on · xhigh
130
+ ultracode: on · high
131
+ ultracode: on · off
132
+ ```
133
+
134
+ Ultracode 请求的是**当前模型支持的最高强度**,不是固定标签。对支持 `max` 的模型(包括 GPT-5.6 Sol)使用 `max`;能力较低的模型由 Pi 正常钳制。对不认识 `max` 的旧版 Pi,Ultracode 会自动回退到 `xhigh`。
135
+
136
+ 显式覆盖始终优先:
137
+
138
+ - 每次调用的模型后缀,例如 `model: "openai/gpt-5.6-sol:high"`;
139
+ - Agent Type frontmatter 中的 `thinking:`;
140
+ - 显式 `:off`、`:high`、`:xhigh` 或 `:max`。
141
+
142
+ 模型切换或手动降低强度时,只要 Ultracode 仍启用,它就会重新请求该模型的最高可用强度。关闭或退出时,会恢复启用前的会话强度与原始默认偏好。若当前模型暂时无法表示原始强度,恢复意图会保留到后续兼容模型;中间模型的钳制结果不会覆盖原始意图。
143
+
144
+ ## 工作原理
145
+
146
+ 扩展注册单个 `workflow` 工具,并在 input preflight 与 `before_agent_start` 边界按 Ultracode 状态校准 active tools,同时保留其他 active tools。关闭或暂停时,`tool_call` 与实际执行入口会双重 fail-closed 拒绝残留调用。工具输入是 JavaScript 源码,其中必须包含纯字面量 `meta` 导出:
94
147
 
95
148
  ```js
96
149
  export const meta = {
97
- name: 'review_changes',
98
- description: 'Review changed files across dimensions, verify each finding',
99
- phases: [{ title: 'Review' }, { title: 'Verify' }],
100
- }
150
+ name: "review_and_fix",
151
+ description: "Review independent areas, then verify the combined result",
152
+ };
153
+ ```
154
+
155
+ 脚本可使用下列全局变量:
156
+
157
+ - `agent(prompt, options)`
158
+ - `parallel(thunks)`
159
+ - `pipeline(items, ...stages)`
160
+ - `phase(title)`
161
+ - `log(message)`
162
+ - `workflow(nameOrRef, args)`
163
+ - `args`
164
+ - `cwd`
165
+ - `budget`
166
+
167
+ `agent()` 的主要选项:
168
+
169
+ | 选项 | 作用 |
170
+ | --- | --- |
171
+ | `label` | 进度中显示的 2–5 个词短名称。 |
172
+ | `phase` | 显式指定进度阶段。 |
173
+ | `schema` | 普通 JSON Schema;成功时返回经 `structured_output` 校验的对象。 |
174
+ | `model` | 按模式覆盖模型,也可带 `:off`、`:high`、`:xhigh` 或 `:max`。 |
175
+ | `agentType` | 使用内置或自定义角色。 |
176
+ | `isolation: "worktree"` | 在临时 git worktree 中运行写入型代理。 |
177
+
178
+ 为保证可恢复和确定性,脚本不提供 Node.js 模块加载能力,也不允许直接使用 `fs`、网络、`Date.now()`、`new Date()` 或 `Math.random()`。
101
179
 
102
- const DIMENSIONS = [
103
- { key: 'bugs', prompt: 'Find correctness bugs in the diff.' },
104
- { key: 'perf', prompt: 'Find performance regressions in the diff.' },
105
- ]
180
+ ### 取消与清理
181
+
182
+ `Esc` 取消工作流时,取消信号会覆盖子代理初始化、异步 preflight 和流式执行窗口。运行器会等待进行中的 `abort()` 完成后再释放会话;清理失败不会覆盖原始 prompt 或取消错误。兼容旧版 Pi 时创建的临时 fallback 会话也遵循同一清理规则。
183
+
184
+ ### 直接调用
185
+
186
+ ```js
187
+ export const meta = {
188
+ name: "single_review",
189
+ description: "Run one focused reviewer",
190
+ };
191
+
192
+ const result = await agent(
193
+ "Inspect src/mode.ts for lifecycle bugs. Return concise findings.",
194
+ { label: "mode review" },
195
+ );
196
+
197
+ export default result;
198
+ ```
199
+
200
+ ### 并行检视
201
+
202
+ `parallel()` 接收 thunk,而不是已经启动的 Promise:
203
+
204
+ ```js
205
+ export const meta = {
206
+ name: "parallel_review",
207
+ description: "Review independent concerns concurrently",
208
+ };
209
+
210
+ const tasks = [
211
+ ["correctness", "Review correctness and lifecycle behavior."],
212
+ ["tests", "Review test coverage and missing regressions."],
213
+ ["docs", "Review README and parity documentation."],
214
+ ];
215
+
216
+ const results = await parallel(
217
+ tasks.map(([label, prompt]) => () => agent(prompt, { label })),
218
+ );
219
+
220
+ export default results.filter(Boolean);
221
+ ```
222
+
223
+ ### 流水线
224
+
225
+ 除非后续阶段确实需要所有前置结果,否则优先使用 `pipeline()`。不同条目可独立推进:
226
+
227
+ ```js
228
+ export const meta = {
229
+ name: "review_pipeline",
230
+ description: "Inspect and verify several modules independently",
231
+ };
232
+
233
+ const files = ["src/mode.ts", "src/workflow/agent-runner.ts"];
106
234
 
107
- // pipeline: each dimension verifies as soon as its review completes (no barrier).
108
235
  const results = await pipeline(
109
- DIMENSIONS,
110
- (d) => agent(d.prompt, { label: 'review:' + d.key, phase: 'Review', schema: FINDINGS }),
111
- (review) => parallel((review.findings ?? []).map((f) => () =>
112
- agent('Adversarially verify, default to refuted: ' + f.title,
113
- { label: 'verify:' + f.file, phase: 'Verify', agentType: 'code-reviewer', schema: VERDICT })
114
- .then((v) => ({ ...f, verdict: v }))
115
- )),
116
- )
236
+ files,
237
+ async (file) => agent(
238
+ `Inspect ${file} and report concrete risks.`,
239
+ { label: `inspect ${file}` },
240
+ ),
241
+ async (finding, file) => agent(
242
+ `Verify this finding against ${file}:\n\n${finding}`,
243
+ { label: `verify ${file}` },
244
+ ),
245
+ );
246
+
247
+ export default results.filter(Boolean);
248
+ ```
249
+
250
+ ### 结构化输出
117
251
 
118
- const confirmed = results.flat().filter(Boolean).filter((f) => f.verdict?.isReal)
119
- return { confirmed }
252
+ 不传 `schema` 时,`agent()` 返回子代理最后一段非空 assistant 文本;传入普通 JSON Schema 时,则返回经校验的对象:
120
253
 
121
- const FINDINGS = { type: 'object', properties: { findings: { type: 'array', items: { type: 'object' } } } }
122
- const VERDICT = { type: 'object', properties: { isReal: { type: 'boolean' }, why: { type: 'string' } }, required: ['isReal'] }
254
+ ```js
255
+ export const meta = {
256
+ name: "structured_audit",
257
+ description: "Collect machine-readable findings",
258
+ };
259
+
260
+ const finding = await agent(
261
+ "Audit the mode lifecycle and return one finding.",
262
+ {
263
+ label: "lifecycle audit",
264
+ schema: {
265
+ type: "object",
266
+ properties: {
267
+ severity: { enum: ["low", "medium", "high"] },
268
+ summary: { type: "string" },
269
+ },
270
+ required: ["severity", "summary"],
271
+ additionalProperties: false,
272
+ },
273
+ },
274
+ );
275
+
276
+ export default finding;
123
277
  ```
124
278
 
125
- ### Globals
279
+ 使用 schema 的代理必须调用 `structured_output`。否则该 `agent()` 分支会失败并返回 `null`;工作流本身仍可继续,因此脚本应过滤或显式处理失败分支,而不会把自由文本伪装成结构化结果。
126
280
 
127
- | Global | Description |
128
- | --- | --- |
129
- | `agent(prompt, opts)` | Spawn an isolated subagent. Returns its final text, or a validated object when `opts.schema` is set. |
130
- | `parallel(thunks)` | Run `() => agent(...)` thunks concurrently. **A barrier.** Failures become `null`. |
131
- | `pipeline(items, ...stages)` | Run each item through stages independently (no barrier). Stages get `(prev, original, index)`. **The default** for multi-stage work. |
132
- | `workflow(nameOrRef, args)` | Run a saved workflow (by name) or `{ scriptPath }` inline, sharing the run's concurrency cap, agent counter, and budget. One level of nesting. |
133
- | `phase(title)` | Mark the current progress group. |
134
- | `log(message)` | Append a workflow-level log line. |
135
- | `args`, `cwd` | The tool's `args` value; the working directory. |
136
- | `budget` | `{ total, spent(), remaining() }` — real output-token budget. |
137
-
138
- ### `agent()` options
139
-
140
- | Option | Effect |
141
- | --- | --- |
142
- | `label` | Short (2-5 word) name shown in live progress. |
143
- | `phase` | Assign this agent to a progress group explicitly (use inside `parallel`/`pipeline`). |
144
- | `schema` | Plain JSON Schema; the subagent returns a validated object via a terminating `structured_output` tool. |
145
- | `model` | Override the subagent model by pattern, e.g. `'sonnet'` or `'provider/id:high'`. |
146
- | `agentType` | Use a custom role: built-ins `claude`, `general-purpose`, `Explore`, `Plan`, `code-reviewer`, or your own (below). |
147
- | `isolation: 'worktree'` | Run the agent in a throwaway git worktree (for parallel file mutation). Changes are applied back to the working tree under a lock; an unchanged worktree is auto-removed. |
281
+ ## Agent Type
148
282
 
149
- ### Determinism
283
+ 项目级角色定义放在:
150
284
 
151
- Scripts run in a `vm` sandbox. `Date.now()`, `new Date()`, `Math.random()`,
152
- `require`/`import`, `fs`, and network APIs are unavailable — this keeps `meta`
153
- parseable and runs **reproducible and resumable**. Pass timestamps via `args`;
154
- vary randomness by agent index.
285
+ ```text
286
+ .pi/ultracode/agents/*.md
287
+ ```
155
288
 
156
- ## Custom agent types
289
+ 用户级角色定义放在:
157
290
 
158
- Drop a Markdown file with frontmatter under
159
- `.pi/ultracode/agents/<name>.md` (project) or `~/.pi/ultracode/agents/<name>.md`
160
- (user):
291
+ ```text
292
+ ~/.pi/ultracode/agents/*.md
293
+ ```
161
294
 
162
- ```markdown
295
+ 同时兼容旧的用户级目录 `~/.pi/agent/agents/*.md`。
296
+
297
+ 示例:
298
+
299
+ ```md
163
300
  ---
164
- name: security
165
- description: Security-focused reviewer
166
- tools: read, grep, find, bash
167
- model: sonnet
301
+ name: reviewer
302
+ description: Read-only reviewer focused on correctness and regressions
303
+ tools: read, bash
304
+ model: anthropic/claude-sonnet-4
168
305
  thinking: high
169
306
  ---
170
- You are a security reviewer. Hunt for injection, authz gaps, and unsafe deserialization.
171
- Cite exact file:line evidence and prefer false negatives over invented findings.
307
+
308
+ Inspect the requested area. Do not modify files. Report only evidence-backed findings.
172
309
  ```
173
310
 
174
- Then `agent('Audit auth.ts', { agentType: 'security' })`.
311
+ 工作流中的用法:
175
312
 
176
- ## Saved & resumable runs
313
+ ```js
314
+ await agent("Review the current diff.", {
315
+ label: "diff review",
316
+ agentType: "reviewer",
317
+ });
318
+ ```
177
319
 
178
- Every run persists its script and a JSONL journal under
179
- `<sessionDir>/ultracode-runs/<runId>.{workflow.js,jsonl}`. To resume after a
180
- pause, kill, or script edit, call the tool again with `resumeFromRunId`: the
181
- longest unchanged prefix of `agent()` calls returns cached results instantly;
182
- the first changed/new call and everything after it run live.
320
+ 内置类型包括 `claude`、`general-purpose`、`Explore`、`Plan` `code-reviewer`。
183
321
 
184
- Save reusable workflows under `.pi/ultracode/workflows/<name>.workflow.js` and
185
- run them with the tool's `name` parameter or `workflow('<name>')`.
322
+ Agent Type 可控制:
186
323
 
187
- ## Library modules
324
+ - 角色提示词;
325
+ - 工具白名单;
326
+ - 默认模型;
327
+ - 默认思考强度。
188
328
 
189
- | File | Purpose |
190
- | --- | --- |
191
- | `src/prompts.ts` | Ultracode system block + workflow tool guidelines. |
192
- | `src/mode.ts` | The ultracode mode controller (toggle, thinking, persistence, injection). |
193
- | `src/commands.ts` | `/ultracode` and `/workflows` commands. |
194
- | `src/workflow/parser.ts` | AST-validated, deterministic script parser. |
195
- | `src/workflow/runtime.ts` | The sandboxed runtime (agent/parallel/pipeline/phase/log/workflow/budget). |
196
- | `src/workflow/agent-runner.ts` | In-memory subagent runner (model, agent type, worktree, usage). |
197
- | `src/workflow/worktree.ts` | Git worktree isolation. |
198
- | `src/workflow/agent-types.ts` | Custom agent-type discovery. |
199
- | `src/workflow/journal.ts` | Run journal + resume. |
200
- | `src/workflow/registry.ts` | In-process run registry for `/workflows`. |
201
- | `src/workflow/display.ts` | Live progress snapshots and renderers. |
202
- | `src/workflow/structured-output.ts` / `json-schema.ts` | Terminating structured output + JSON-Schema TypeBox. |
203
- | `src/workflow/tool.ts` | The Pi `workflow` tool. |
204
- | `extensions/ultracode.ts` | Extension entrypoint. |
205
-
206
- ## Development
329
+ 每次调用的选项优先于 Agent Type 默认值。
330
+
331
+ ## 模型选择
332
+
333
+ `model` 接受 provider/model 模式,并可带思考强度后缀:
334
+
335
+ ```js
336
+ await agent("Analyze this failure.", {
337
+ label: "failure analysis",
338
+ model: "openai/gpt-5.6-sol:max",
339
+ });
340
+ ```
341
+
342
+ 若未指定 model,则子代理继承工作流工具创建时的 Pi 当前模型。Ultracode 启用时,默认子代理强度同样请求 `max`,并按每个代理实际选择的模型独立钳制。Ultracode 不会自动启用 GPT-5.6 `pro` 模式,也不会隐式设置 token 预算。
343
+
344
+ ## Worktree 隔离
345
+
346
+ 并行写入同一工作树容易产生竞态。对会修改文件的代理使用:
347
+
348
+ ```js
349
+ await agent("Implement the requested change and run focused tests.", {
350
+ label: "implementation",
351
+ isolation: "worktree",
352
+ });
353
+ ```
354
+
355
+ 运行器会:
356
+
357
+ 1. 创建临时 git worktree;
358
+ 2. 在隔离目录运行代理;
359
+ 3. 捕获 worktree diff;
360
+ 4. 检查共享工作树是否漂移;
361
+ 5. 通过 `git apply --3way` 应用补丁;
362
+ 6. 在失败时保存 rescue patch;
363
+ 7. 成功且安全时清理临时 worktree。
364
+
365
+ 如果 diff 捕获、rescue 保存或补丁集成异常,运行器会故障安全地保留 worktree,并在日志中给出路径,避免丢失代理改动。确认内容后可手动恢复或删除;超过保留阈值的 Ultracode worktree 会由后续运行回收。
366
+
367
+ 使用隔离前,共享仓库必须处于干净状态。
368
+
369
+ ## 已保存的工作流与可恢复运行
370
+
371
+ 可复用工作流可放在:
372
+
373
+ ```text
374
+ .pi/ultracode/workflows/<name>.workflow.js
375
+ ~/.pi/ultracode/workflows/<name>.workflow.js
376
+ ```
377
+
378
+ 可通过工具的 `name`、`scriptPath`,或脚本内调用来运行:
379
+
380
+ ```js
381
+ await workflow("saved_workflow_name", { target: "src" });
382
+ ```
383
+
384
+ 嵌套限制为一层,且共享父运行的并发上限、代理计数与 token 预算。
385
+
386
+ 每次运行都会把脚本和 JSONL journal 保存到:
387
+
388
+ ```text
389
+ <sessionDir>/ultracode-runs/<runId>.workflow.js
390
+ <sessionDir>/ultracode-runs/<runId>.jsonl
391
+ ```
392
+
393
+ 暂停、终止或修改脚本后,可再次调用 `workflow` 工具并传入 `resumeFromRunId`。最长的未变 `agent()` 调用前缀会立即返回缓存结果;第一个变化或新增的调用及其后续调用会实时执行。
394
+
395
+ ## 预算与限制
396
+
397
+ 默认 token 预算为无限。只有显式配置后,`budget.total` 才是有限值。
398
+
399
+ 动态探索必须同时检查预算是否存在:
400
+
401
+ ```js
402
+ while (budget.total && budget.remaining() > 50_000) {
403
+ // additional bounded exploration
404
+ break;
405
+ }
406
+ ```
407
+
408
+ 若不检查 `budget.total`,无限预算下的 `remaining()` 是 `Infinity`,循环可能一直运行到代理数量上限。
409
+
410
+ 其他限制:
411
+
412
+ - 最大代理数;
413
+ - 最大并发数;
414
+ - 工作流脚本超时;
415
+ - 嵌套深度;
416
+ - 结构化输出校验;
417
+ - 静态禁止不确定性与危险全局变量。
418
+
419
+ ## 会话与兼容性
420
+
421
+ Ultracode 模式状态通过自定义 session entry 持久化。恢复、reload、fork 和 `/tree` 导航都会按当前 branch 重新读取状态;被丢弃分支中的 entry 不会错误启用模式。旧版 Pi 或旧模型会把 `max` 兼容回退为 `xhigh`,而不会把未知值静默变成 `off`。
422
+
423
+ 扩展清理只管理自己的详情浮层、status 与运行状态,不会调用 Pi 的全局 `ui.clear()`,因此不会清除其他扩展的 UI。
424
+
425
+ ## 开发
426
+
427
+ ```bash
428
+ npm ci
429
+ npm run typecheck
430
+ npm test
431
+ npm pack --dry-run
432
+ ```
433
+
434
+ 项目源码位于:
435
+
436
+ - `extensions/ultracode.ts`:扩展入口和 Pi 生命周期接线;
437
+ - `src/mode.ts`:Ultracode 模式状态、恢复与强度管理;
438
+ - `src/thinking.ts`:共享思考强度词汇与兼容性检测;
439
+ - `src/workflow/`:脚本验证、运行时、子代理执行、worktree 和进度显示;
440
+ - `test/`:单元、扩展和回归测试;
441
+ - `docs/parity.md`:与原生 Pi 能力边界的说明。
442
+
443
+ 开发依赖会安装 TypeScript 和用于测试的 Pi peer 包;通过 `pi install` 加载正式包时,Pi 仍会提供这些 peer 依赖。
444
+
445
+ ## 发布
446
+
447
+ npm 发布由 [`.github/workflows/publish-npm.yml`](.github/workflows/publish-npm.yml) 完成,使用 npm Trusted Publishing(OIDC),无需保存长期 `NPM_TOKEN`。
448
+
449
+ 首次使用前,在 npm 的 `pi-ultracode` 包设置中添加 GitHub Actions Trusted Publisher:
450
+
451
+ - Organization or user:`ekil1100`
452
+ - Repository:`pi-ultracode`
453
+ - Workflow filename:`publish-npm.yml`
454
+ - Environment name:`npm`
455
+ - Allowed action:`npm publish`
456
+
457
+ 同时在 GitHub 仓库中创建名为 `npm` 的 Environment;可以按需增加审批人。正常发布无需打开 Actions 页面:
207
458
 
208
459
  ```bash
209
- npm test # node --test over the parser, runtime, journal, agent types, mode, and extension
210
- npm run typecheck # tsc --noEmit (requires a local TypeScript)
460
+ npm version patch # or: minor / major / 0.2.0-beta.1
461
+ git push origin main --follow-tags
211
462
  ```
212
463
 
213
- The test suite injects a mock subagent runner, so it runs without a model. A
214
- faithful end-to-end check (real subagents) just calls `runWorkflow` with the
215
- default runner.
464
+ `npm version` 会同步更新 `package.json` `package-lock.json`,创建版本提交与 `v<version>` Tag;推送 Tag CI 自动发布。稳定版本发布到 `latest`,预发布版本发布到 `next`。
465
+
466
+ 需要重试或指定其他 npm dist-tag 时,也可以在 Actions 中手动运行工作流;填写完全匹配 `package.json` 的版本,且只允许从 `main` 运行。
467
+
468
+ 工作流会校验 Tag 与包版本完全一致、确认版本尚未发布,并在正式发布前执行干净安装、测试和类型检查。
469
+
470
+ ## 设计原则
471
+
472
+ Ultracode 的目标不是“尽可能多地启动代理”,而是:
216
473
 
217
- **Dependencies.** The only hard runtime dependency is `acorn`; Pi provides
218
- `typebox` and `@earendil-works/*` to extensions at load time. When running the
219
- node test runner directly (which has no Pi loader), link those peers into
220
- `node_modules/` — e.g. symlink them from your Pi install — alongside the
221
- real `acorn` that `pi install` / `npm install` provides.
474
+ > 在任务确实适合拆分、并行、独立验证或跨上下文扩展时,使用确定性编排获得更高置信度;否则继续使用 Pi 简洁直接的单代理循环。
222
475
 
223
- ## License
476
+ ## 许可证
224
477
 
225
478
  MIT