ultra-builder-pro-cli 0.6.0 → 0.7.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/.ultra-template/changes/active/.gitkeep +1 -0
- package/.ultra-template/changes/archive/.gitkeep +1 -0
- package/CHANGELOG.md +62 -11
- package/README.md +26 -18
- package/adapters/_shared/handbook.cjs +7 -7
- package/adapters/_shared/runtime-assets.cjs +2 -0
- package/adapters/_shared/tests/handbook.test.cjs +4 -1
- package/adapters/_shared/tests/runtime-assets.test.cjs +2 -0
- package/adapters/opencode.js +81 -20
- package/adapters/tests/codex.test.cjs +5 -3
- package/adapters/tests/opencode.test.cjs +16 -9
- package/bin/install.js +0 -19
- package/bin/orchestrator.js +1 -26
- package/commands/ultra-change.md +47 -0
- package/commands/ultra-deliver.md +14 -7
- package/commands/ultra-dev.md +6 -3
- package/commands/ultra-doctor.md +36 -0
- package/commands/ultra-init.md +4 -3
- package/commands/ultra-status.md +7 -5
- package/commands/ultra-test.md +2 -1
- package/docs/AGENT-CONTEXT.md +31 -23
- package/docs/ARCHITECTURE.md +46 -17
- package/docs/PLAN.zh-CN.md +35 -29
- package/docs/ROADMAP.md +14 -14
- package/docs/RUNTIME-COMPAT-MATRIX.md +11 -11
- package/hooks/README.md +8 -7
- package/hooks/active_task_context.py +22 -15
- package/hooks/health_check.py +136 -38
- package/hooks/workflow_context.py +120 -30
- package/mcp-server/lib/change-workflow.cjs +556 -0
- package/mcp-server/lib/change-workflow.test.cjs +259 -0
- package/mcp-server/lib/doctor.cjs +112 -0
- package/mcp-server/lib/doctor.test.cjs +86 -0
- package/mcp-server/lib/init-project.cjs +32 -6
- package/mcp-server/lib/runtime-state.cjs +222 -0
- package/mcp-server/lib/runtime-state.test.cjs +92 -0
- package/mcp-server/lib/state-db.cjs +31 -8
- package/mcp-server/lib/state-ops.cjs +17 -3
- package/mcp-server/server.cjs +102 -10
- package/mcp-server/tests/db-ops.test.cjs +5 -1
- package/mcp-server/tests/init-project.test.cjs +45 -0
- package/mcp-server/tests/server-contract.test.cjs +123 -1
- package/mcp-server/tests/state-db.test.cjs +44 -7
- package/mcp-server/tests/state-ops.test.cjs +19 -0
- package/orchestrator/daemon.cjs +39 -0
- package/orchestrator/tests/daemon.test.cjs +50 -0
- package/package.json +3 -3
- package/settings.json +1 -2
- package/skills/ultra-change/SKILL.md +140 -0
- package/skills/ultra-deliver/SKILL.md +81 -15
- package/skills/ultra-dev/SKILL.md +32 -12
- package/skills/ultra-doctor/SKILL.md +90 -0
- package/skills/ultra-init/SKILL.md +8 -5
- package/skills/ultra-review/SKILL.md +16 -0
- package/skills/ultra-status/SKILL.md +30 -7
- package/skills/ultra-test/SKILL.md +14 -2
- package/spec/cli-protocol.md +12 -1
- package/spec/mcp-tools.yaml +337 -1
- package/spec/schemas/mcp-tools.schema.json +1 -1
- package/spec/schemas/state-db.sql +117 -0
- package/ultra-tools/cli.cjs +3 -0
- package/ultra-tools/commands/system.cjs +57 -0
- package/ultra-tools/system-command.test.cjs +53 -0
- package/adapters/_shared/rtk-detect.cjs +0 -86
- package/adapters/_shared/tests/rtk-detect.test.cjs +0 -116
- package/docs/LEGACY-HERMES.md +0 -1099
- package/orchestrator/code-graph-watcher.cjs +0 -121
- package/orchestrator/tests/code-graph-watcher.test.cjs +0 -183
package/docs/PLAN.zh-CN.md
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
# ultra-builder-pro-cli —
|
|
1
|
+
# ultra-builder-pro-cli — 历史执行计划与决策日志
|
|
2
2
|
|
|
3
|
-
> **2026-07-17 当前生效边界(D50-
|
|
3
|
+
> **2026-07-17 当前生效边界(D50-D52,覆盖下文旧 Phase 6/7 的内置图谱、memory 与 runtime 设计)**:
|
|
4
4
|
> Ultra Builder Pro 不再拥有 `memory.*`、recall、prompt/transcript/observation/summary
|
|
5
5
|
> 收集 hook 或私有 agent memory。跨会话记忆全部交给独立安装的 cloud-mem/claude-mem。
|
|
6
|
-
> 插件只保留
|
|
7
|
-
>
|
|
6
|
+
> 插件只保留 12 个 Ultra 公共 workflow(新增 daily `ultra-change` 与诊断
|
|
7
|
+
> `ultra-doctor`)、4 个 agent-only 规则 skill、宿主专属 collab companion、
|
|
8
|
+
> workflow/change hook 与 `.ultra/state.db` 权威。Memory 和代码图谱内容全部由外部
|
|
9
|
+
> provider 所有,Ultra 只保存 provider 元数据引用。Claude Code、Codex、OpenCode
|
|
8
10
|
> 采用各自 native plugin 呈现,其他旧 runtime adapter 已退役。下文所有与此冲突的
|
|
9
11
|
> memory/hindsight 章节仅作为历史实施记录,不再是当前需求或运行时契约。
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
**当前状态**:v0.7.0 发布候选;三宿主 native plugin、29 个 live MCP tool、
|
|
14
|
+
schema 9.0(15 表)、持续 change/context/convergence/doctor 已落地;npm 发布由
|
|
15
|
+
`v*.*.*` tag 触发。以下 Phase 0-9 正文保留为 2026-04 的实施历史,不再作为
|
|
16
|
+
当前 runtime 或发布状态的事实来源。
|
|
17
|
+
**历史版本**:0.3.1-plan · 2026-04-17 Codex 第二轮评审收尾
|
|
13
18
|
**范围**:最终目标 = 可落地的"跨 runtime coding 自动化工厂"。12 个 Phase 渐进交付。
|
|
14
19
|
**整体置信度**:**86%**(同 v0.3;Phase 2 下调被 4.5/8A/8B 上调抵消)
|
|
15
20
|
**关键变更**(vs v0.3,基于 Codex 第二轮 R1-R7):
|
|
@@ -22,14 +27,16 @@
|
|
|
22
27
|
- **Phase 4.6 拆 a/b**(R6 + D35):v0.1 只跑 smoke flow,full conformance 推 v0.2
|
|
23
28
|
- **Codex 第二轮结论**:"小改后开工"(tl;dr);本版已完成小改
|
|
24
29
|
|
|
25
|
-
**总决策数**:D1-
|
|
30
|
+
**总决策数**:D1-D52(当前边界以 D50-D52 为准)
|
|
26
31
|
**总风险数**:R1-R32(v0.3.1 新增 R25-R32 共 8 条)
|
|
27
32
|
|
|
28
33
|
---
|
|
29
34
|
|
|
30
|
-
>
|
|
31
|
-
>
|
|
32
|
-
>
|
|
35
|
+
> **当前事实权威**:live MCP 以 `spec/mcp-tools.yaml` 为准,持久状态以
|
|
36
|
+
> `spec/schemas/state-db.sql` 为准,插件边界以 `docs/AGENT-CONTEXT.md` 与
|
|
37
|
+
> `adapters/_shared/runtime-assets.cjs` 为准,宿主差异以
|
|
38
|
+
> `docs/RUNTIME-COMPAT-MATRIX.md` 为准。本文件只保存历史方案与决策来源;任何
|
|
39
|
+
> 与上述当前契约冲突的旧 Phase 文本均不生效。
|
|
33
40
|
|
|
34
41
|
---
|
|
35
42
|
|
|
@@ -109,7 +116,7 @@ Hermes(Ultra Builder Pro)是一套成熟的 agent 工程系统:
|
|
|
109
116
|
| G4 | 每 task 独立会话(新进程 + 独立 worktree + lease),对话不污染 | 2 并发 session 各独立 worktree;kill -9 后 lease 过期可清理 | **4.5** |
|
|
110
117
|
| G5 | 跨 session 事件可订阅 | MCP `session.subscribe_events` 从 state-db events 表实时推 | **4.5** |
|
|
111
118
|
| G6 | 崩溃自动恢复,失败有熔断 | kill -9 agent 后 orchestrator 重启能续;同 task 重试 ≥3 次自动停 | 5 |
|
|
112
|
-
| G7 |
|
|
119
|
+
| G7 | Memory 与代码图谱由外部 provider 完成,Ultra 只保存可追溯引用 | 三个 runtime 的 context manifest 都只含 provider 元数据,不复制 provider 内容 | 6, 7 |
|
|
113
120
|
| G8 | PRD 自动拆 task + 并行分派(8A + 8B) | 10 task 的 PRD 一键触发,≤3 失败项,其余自动完成并合入 | **8A, 8B** |
|
|
114
121
|
| G9 | 三渠道可装(npm / Homebrew / pip) | 干净 macOS / Ubuntu 60 秒装好 | 9 |
|
|
115
122
|
| G10 | 0 私人数据泄漏 | npm tarball / brew bottle / pip wheel 审计干净 | 9 |
|
|
@@ -252,7 +259,7 @@ v0.2 加执行层进阶(recovery + 监控 + 实时图谱)→ 半自动 → v
|
|
|
252
259
|
│ ▼ TDD RED/GREEN/REFACTOR (调 impact.radius + memory.recall)
|
|
253
260
|
│ ▼ review: MCP review.run → 5 个 subagent 并行
|
|
254
261
|
│ │ │
|
|
255
|
-
│ │ ▼ (Phase 6)
|
|
262
|
+
│ │ ▼ (Phase 6) telemetry
|
|
256
263
|
│ │
|
|
257
264
|
│ ▼ task.update_status completed + commit
|
|
258
265
|
│ ▼ activity-log: task_complete(id=1, commit=abc)
|
|
@@ -308,7 +315,6 @@ ultra-builder-pro-cli/
|
|
|
308
315
|
│ └── recovery.ts # Phase 5 circuit-breaker
|
|
309
316
|
├── telemetry/ # Phase 6
|
|
310
317
|
│ ├── collectors/ # token / tool_call / cost
|
|
311
|
-
│ └── rtk-integration.ts
|
|
312
318
|
├── adapters/ # Phase 4 跨 runtime 分发
|
|
313
319
|
│ ├── claude.ts
|
|
314
320
|
│ ├── opencode.ts
|
|
@@ -341,7 +347,7 @@ ultra-builder-pro-cli/
|
|
|
341
347
|
| A6 | 事件流 = state-db `events` 表(append-only)+ MCP subscribe | 取代 activity-log.json 文件;state-db 统一权威源(D18) |
|
|
342
348
|
| A7 | Python hooks 沿用,Node shell out | 15 hook 重写 Node 要 2-3 周纯折腾;零价值 |
|
|
343
349
|
| A8 | orchestrator 是可选的常驻 Node daemon | 规则层可不依赖执行层独立跑;半自动 → 全自动平滑升级 |
|
|
344
|
-
| A9 |
|
|
350
|
+
| A9 | Memory 与代码图谱全部归外部 provider 所有 | Ultra 只存 provider、project、reference、revision、indexed_head、status 等元数据引用,不内嵌内容或自建等价能力 |
|
|
345
351
|
| **A10** | **v0.1 = 规则层 + execution-lite**(非裸规则层) | Codex Q3:用户核心诉求是"独立会话",无执行层 v0.1 不够用;D19 |
|
|
346
352
|
| **A11** | **Schema v4.4 → v4.5 过渡(不直接 v5 breaking)** | Codex Q5:tasks.json 成 authoritative view,context status 降级派生,停止手写保留兼容;等命令全迁完再 v5;D21 |
|
|
347
353
|
| **A12** | **Runtime capability matrix + conformance tests** 代替纸面 parity | Codex Q8:4 runtime 在 hook / subagent / 权限 / usage 统计不等价;D23 |
|
|
@@ -373,7 +379,6 @@ ultra-builder-pro-cli/
|
|
|
373
379
|
|
|
374
380
|
| 能力 | 来源 | 加到哪 | Phase | 工时 |
|
|
375
381
|
|------|------|-------|-------|-----:|
|
|
376
|
-
| RTK Bash 命令压缩(60-90%) | RTK | `rtk init -g` + hook 注册 | 6 | 0.5d |
|
|
377
382
|
| 爆炸半径分析(8x 减少) | code-review-graph | MCP `impact.*` tool | 7 | 2d |
|
|
378
383
|
| 长期记忆(retain/recall/reflect) | hindsight | MCP `memory.*` tool | 7 | 5d |
|
|
379
384
|
| Skill 自动萃取 + 注入 | OMC | `/learn` 扩展;dev 起步读匹配 skill | 7 | 2d |
|
|
@@ -935,16 +940,16 @@ agent 并行,orchestrator 负责 session 隔离和状态一致。
|
|
|
935
940
|
|
|
936
941
|
**前置**:Phase 5(session 是监控的归属单位)
|
|
937
942
|
|
|
938
|
-
**置信度**:93
|
|
943
|
+
**置信度**:93%(埋点与结构化事件是标准工程)
|
|
939
944
|
|
|
940
945
|
**工时**:3-4 天
|
|
941
946
|
|
|
942
947
|
#### 任务清单
|
|
943
948
|
|
|
944
|
-
**6.1
|
|
945
|
-
-
|
|
946
|
-
-
|
|
947
|
-
- **AC
|
|
949
|
+
**6.1 外部能力边界**(0.5 天)
|
|
950
|
+
- 安装器不检测、不注册、也不代理任何通用 shell 压缩工具。
|
|
951
|
+
- Memory 与代码图谱由独立 provider 安装和运行;Ultra 只消费显式传入的元数据引用。
|
|
952
|
+
- **AC**:干净环境安装不产生第三方命令代理配置,context manifest 不包含外部 provider 的内容正文。
|
|
948
953
|
|
|
949
954
|
**6.2 Telemetry collectors**(1.5 天)
|
|
950
955
|
- `telemetry/collectors/token.ts`:从 activity-log + session log 抽 token
|
|
@@ -977,7 +982,7 @@ agent 并行,orchestrator 负责 session 隔离和状态一致。
|
|
|
977
982
|
**6.5 Runtime stdout 拦截(可选)**(1 天)
|
|
978
983
|
- orchestrator spawn agent 时拦截 stdout,解析 Anthropic/OpenAI
|
|
979
984
|
SDK 的 usage 字段(若可达)。
|
|
980
|
-
- 更精准的 token
|
|
985
|
+
- 更精准的 token 统计(不依赖命令输出压缩推测)。
|
|
981
986
|
- **AC**:对一个已知 token 数的 task 做 E2E,telemetry 与官方 usage 误差 <5%。
|
|
982
987
|
|
|
983
988
|
#### Phase 6 gate
|
|
@@ -985,7 +990,7 @@ agent 并行,orchestrator 负责 session 隔离和状态一致。
|
|
|
985
990
|
- ✅ telemetry 覆盖率:每 MCP tool 调用 100% 有埋点(state.db.telemetry + jsonl 双写)
|
|
986
991
|
- ✅ `/ultra-status --cost` panel 数字可信(token → pricing 表 → cost_usd 推算;SDK usage 精确对账推迟 6.5)
|
|
987
992
|
- ✅ code-review-graph watcher 实时增量测试过(debounce + exclude + large_batch 6 tests)
|
|
988
|
-
- ⤼ 6.5 Runtime stdout 拦截按 PLAN
|
|
993
|
+
- ⤼ 6.5 Runtime stdout 拦截按 PLAN 原文“可选”跳过(YAGNI:宿主 usage 与 pricing 估算已覆盖当前需求)
|
|
989
994
|
- ✅ **Phase 6 完成 — D44**(2026-04-17)
|
|
990
995
|
|
|
991
996
|
---
|
|
@@ -1193,7 +1198,7 @@ files_modified 重叠检测 + 自动合并。这是 "coding 工厂" 的**后端*
|
|
|
1193
1198
|
|
|
1194
1199
|
**9.1 CI 矩阵**(1 天)
|
|
1195
1200
|
- GitHub Actions:`{claude, opencode, codex} × {local, global}`
|
|
1196
|
-
=
|
|
1201
|
+
= 6 jobs + 外部 provider 引用边界测试。
|
|
1197
1202
|
- **AC**:所有矩阵单元绿,每周定时跑一次(catch runtime 上游变更)。
|
|
1198
1203
|
|
|
1199
1204
|
**9.2 README 重写**(0.5 天)
|
|
@@ -1559,7 +1564,7 @@ Week 18 buffer(ship 中任何 Phase 的 25% 滑动吃掉)
|
|
|
1559
1564
|
最终 commit 独立。
|
|
1560
1565
|
4. **事件传播**:agent A 完成 task 1 后,≤1s 内 agent B 通过 MCP 看到。
|
|
1561
1566
|
5. **崩溃恢复**:kill -9 跑 dev 的 agent,重启后能续或熔断。
|
|
1562
|
-
6. **
|
|
1567
|
+
6. **Provider 边界**:Memory 与图谱正文不进入 Ultra state.db 或发布包,只保留可追溯元数据引用。
|
|
1563
1568
|
7. **记忆召回**:跨 session retain → recall 命中率 ≥90%。
|
|
1564
1569
|
8. **PRD 自动拆**:2KB PRD 自动拆与人工 ≥80% 一致。
|
|
1565
1570
|
9. **并行工厂**:10 task PRD 自动完成率 ≥80%。
|
|
@@ -1597,7 +1602,7 @@ Week 18 buffer(ship 中任何 Phase 的 25% 滑动吃掉)
|
|
|
1597
1602
|
| **D12** | **2026-04-17** | **采用 skill + MCP + CLI 三层架构**,skill=说明书、MCP=状态操作主路径、CLI=Bash 兜底 | 参考 CTM(MCP 模式)+ OMC/OMX(skill 模式)+ get-shit-done(CLI 模式);三层分工覆盖 "knowledge / state / hook" 三类需求 |
|
|
1598
1603
|
| **D13** | **2026-04-17** | **规则层 / 执行层双时间线交付**(Phase 1-4 规则层 → v0.1;Phase 5-8 执行层 → v0.2-v0.3) | 用户明确"规则 vs 自动化执行"的维度;降低单次发布复杂度;早让用户拿到可用价值 |
|
|
1599
1604
|
| **D14** | **2026-04-17** | **范围从"分发器"扩展到"自动化 coding 工厂"**,总工时从 4-5 周扩到 11-13 周 | 用户诉求:跨 agent 上下文共享 + 独立对话避污染 + 监控 + 实时代码图 + 记忆系统;不只是 distribution tool |
|
|
1600
|
-
| **D15** | **2026-04-17** |
|
|
1605
|
+
| **D15** | **2026-04-17** | 外部 Memory / 图谱能力采用 provider 引用,不自建等价实现 | 避免复制第三方能力与内容,让 Ultra 聚焦 change workflow 与收敛证据 |
|
|
1601
1606
|
| **D16** | **2026-04-17** | GSD / GSD-2 的 **atomic-write / state-machine / ctx.newSession / DISPATCH_RULES** 直接移植(不自建) | 已在 14 runtime 实战;用户确认"可以先集成,混合" |
|
|
1602
1607
|
| **D17** | **2026-04-17** | Phase 3 消除 **tasks.json 与 context 的 status 双写**(原 v4.4 → v5.0,**后被 D21 覆盖为 v4.5 过渡**) | 用户指痛点"异步效果不好"根因之一 |
|
|
1603
1608
|
| **D18** | **2026-04-17** | **权威状态层 = `.ultra/state.db` SQLite + WAL**,md/json 降级为投影/导出视图 | Codex Q1:多主写入是最大架构风险;SQLite 提供事务 + 并发读;tasks.json/activity-log/sessions/workflow-state 多文件各管一摊易炸 |
|
|
@@ -1626,13 +1631,14 @@ Week 18 buffer(ship 中任何 Phase 的 25% 滑动吃掉)
|
|
|
1626
1631
|
| **D41** | **2026-04-17** | **Phase 4 初始跨 runtime 分发里程碑** — adapter、能力矩阵、smoke flow 与 installer 装配首次闭环;0.6.0 后只保留 Claude Code、OpenCode、Codex 三个 native plugin | 历史里程碑;当前边界由 D51 覆盖 |
|
|
1627
1632
|
| **D46** | **2026-04-17** | **Phase 7 完成 — 智能层落地** — 偏离原 PLAN:**不内嵌 hindsight-server(Python/Docker),改自建 SQLite FTS5 memory store**(理由:PLAN 自己说"避免 Docker"已承认痛点;Node 内嵌 Python 要 subprocess/HTTP 胶水,成本高于直接用 state.db)。**7.1 Memory store**:schema 升 5.2 → 7.1,新增 `memory_entries` 表(task_id/session_id/tag/kind/content/source/ts;kind CHECK `fact/decision/error_fix/pattern/note`)+ `memory_fts` FTS5 虚表 + 3 trigger(ai/ad/au 同步);`mcp-server/lib/memory-store.cjs` retain/recall/reflect 三函数(FTS5 MATCH 构造 escape 用 quote-wrap 防注入;空 query → 近期条目 fallback;bm25 ranking);3 MCP tool `memory.retain/recall/reflect`(spec/mcp-tools.yaml 老 schema 用 scope/ttl_days 方案 → 替换为 kind 方案,更贴事件自动提取);`orchestrator/memory-wrapper.cjs` autoRecallOnSpawn(task.title+trace_to → recall → prefetch.md)+ autoRetainOnClose(event-type heuristic 映射 task_completed→decision / task_circuit_broken→error_fix / session_crashed→pattern / task_stale_marked→fact;**不调 LLM**);session-runner opt-in `autoMemory: true`。**7.2 Tagged task lists**:`deriveBranchTag(cwd)` 用 `spawnSync`(非 throw, 状态码判断) 读 git symbolic-ref + `sanitizeTag`(slash→hyphen, @→dot, 非 `\w.-` 剥离, ≤100 chars);`switchTaskTag` + `task_tag_changed` event;`createTask` 接 `_cwd` 字段自动推导 tag 不覆盖显式传入;MCP `task.switch_tag` + spec/cli-protocol.md 加 33rd mapping;daemon `branchScoped: true` 过滤 pending by current branch tag。**7.3 Skill 萃取(heuristic, 0 LLM cost)**:`orchestrator/skill-miner.cjs` mineSession 扫 session events → 3 signal 触发(`task_completed` → task-completion / `task_circuit_broken` → debug-pattern / `session_crashed` → recovery-pattern)→ 写 `skills/learned/<ts>_<sid>_unverified.md` 含 YAML frontmatter + Problem/Signal/Evidence/Suggested reuse 4 section;idempotent(同 sid 再跑检到已有 draft 则 skip);session-runner opt-in `mineSkill: true` + `skillsRoot`。**聚合**:Phase 7 新增 38 tests(memory-store 11 + memory-wrapper 7 + tagged-tasks 11 + skill-miner 7 + server-contract 1 memory roundtrip + daemon 1 branchScoped),D45 基线 232 → **270 tests 全绿**,0 回归。schema_version 升到 7.1(第三个 seed 行),RequiredTables 加 `memory_entries` | v0.3 准备期:用户现在每 task 起步自动拿到相关历史 prefetch;branch 切换自动过滤任务;debug / crash / 完成自动生成 skill draft;所有 opt-in 默认关,不破坏现有集成 |
|
|
1628
1633
|
| **D45** | **2026-04-17** | **Phase 4 backlog 与 full conformance 完工** — 共享 capability assertions、三宿主 install/MCP/hook/skill/idempotency 覆盖与 `resolveTarget` 合约形成自动化防护网 | 当前三宿主 conformance 继续保留并由退役回归契约补强 |
|
|
1629
|
-
| **D44** | **2026-04-17** | **Phase 6 完成** —
|
|
1634
|
+
| **D44** | **2026-04-17** | **Phase 6 完成** — 三宿主 pricing/telemetry、成本面板与早期 code-graph watcher 落地 | 后续由外部 provider 边界取代内置 watcher |
|
|
1630
1635
|
| **D43** | **2026-04-17** | **Phase 5 完成** — 执行层进阶四件套落地:(5.1) `orchestrator/recovery.cjs` `recoverOnBoot` 扫 orphan 用 `process.kill(pid,0)` 探测 pid 存活,死的 → crashed + `task_failure` event(5 tests 含 kill -9 真实集成);(5.2) `circuit_breaker` 表(schema_version 升 4.5 → 5.2,`ensureSchemaVersion` 从 "latest row" 改 "exact match" 解决同 ms seed 排序不稳)+ `recordTaskFailure` 计数器(连续 ≥3 → `tripped_at` + `task_circuit_broken` 一次性 event)+ `resetCircuitBreaker` + `admissionCheck` 短路 `blocked_by_breaker` + `spawnSession` 抛 `CIRCUIT_TRIPPED`(7 tests,含 takeover 不可越过熔断);(5.3) `markTasksStaleBySpecSections` + `consumeSpecChangedEvents` 游标消费 + projector `⚠️ STALE` banner(只对 pending + 幂等,10 tests);(5.4) `orchestrator/daemon.cjs` 轮询 + `routeTask` 按 complexity_hint(haiku/sonnet/opus) 最简路由 + `bin/orchestrator.js` 四子命令 `run/start/stop/status` + `settings.json` `orchestrator.auto_dispatch` opt-in gate(11 tests + 手测 opt-in 拒启/pidfile 生命周期);Recovery 明确不自动 retry(retry 留给 Phase 8B),仅计失败交给熔断;总计 108 tests 全绿(state 76 + orch 26 + spec 6),原 118 基线 +35 无回归 | v0.2 执行层进阶完工;可起 daemon 自动捡 pending task,熔断+恢复+staleness 闭环 |
|
|
1631
1636
|
| **D42** | **2026-04-17** | **Phase 4.5 完成 — v0.1 发布就绪点** — execution-lite 落地:MCP 新增 7 个 session.* tool(spawn/close/get/list/admission_check/heartbeat/subscribe_events;spec 新增 session.list + meta-schema errors minItems 兼容);state-ops 新增 readSession / heartbeatSession / admissionCheck / reapOrphanSessions(D32/D33);`orchestrator/session-runner.cjs` 真 git worktree + child_process + state.db sessions 表 lease/heartbeat(替代 lease.json 文件 — grep 证代码零出现);`ultra-tools session {list,admission,reap,get,heartbeat,close,subscribe}` 7 verb CLI;skills/ultra-status 升级读 session.list + session.subscribe_events;Phase 4.5 gate 全过(2 并发 session 隔离 / 并发 spawn 单活 / kill -9 → orphan 识别 / event subscribe ≤1s latency / 无文件+表双源);总计 118 tests 全绿(state 59 + orch 8 + spec 6 + adapter/conformance/install 45);0 回归 | v0.1 发布就绪点达成:用户装上即可跨 4 runtime 手动并发跑任务、会话独立、事件订阅、活跃会话可见。真·可用最小单元 |
|
|
1632
1637
|
| **D47** | **2026-04-17** | **Phase 8A 完成 — planner 线就绪** — PRD → task graph → execution-plan 全链 MCP:(8A.0) schema 升 7.1 → 8A.1,tasks.parent_id TEXT REFERENCES tasks(id) ON DELETE SET NULL + `tasks_parent` 部分索引;EXPECTED_VERSION bump。(8A.1) `lib/llm-client.cjs` 官方 SDK 双 provider(`@anthropic-ai/sdk` + `openai`,+2 devDeps,用户选 D)按 model 前缀推(claude|opus|sonnet|haiku → anthropic;gpt|o1|o3 → openai),统一 `completeJson({system, user, maxTokens})`;`lib/prd-parser.cjs` Test Double 注入;`orchestrator/planner/prd-prompt.cjs` 模板;`task.parse_prd` input 加 `dry_run`(默认 false)实现 human-gate preview→approve;server.cjs dispatchTool 改 async。(8A.2) `lib/topo.cjs` Kahn + Tarjan SCC — 外部 dep 视已满足;有环返 CYCLE_DETECTED + `err.details.cycles`;errorResponse 扩展 optional `details`。(8A.3) `lib/task-expander.cjs` LLM prompt(sub_count 默认 3)→ 原子 tx(createTask children with parent_id + patchTask parent.status='expanded' → 自动 emit task_expanded);server 前置 parent 检查避免无谓 LLM client 构造。(8A.4a) `orchestrator/planner/plan-builder.cjs` Functional Core;`listWaveConflicts` pair-wise files_modified 交集;parallel wave 取 max(complexity),serial sum;cost 用 `pricing.computeCost`。(8A.4b) `lib/plan-store.cjs` `writeAtomic` 原子落 `.ultra/execution-plan.json`;`loadPlanArtifact` corrupt→null;`selectSection` 投影 tasks/topo/conflicts/all;emit plan_approved。(8A.5) `skills/ultra-plan` PRD Direct workflow — dry_run=true parse → buildPlan → ask.question → approve 走 dry_run=false + plan.export / reject 0 写入;frontmatter mcp_tools_required +5 tool。**spec 扩展**:task.create input 加 `files_modified` + `parent_id`;task.parse_prd input 加 `dry_run`。D46 基线 270 → **361 tests 全绿**(+91:state +71 / orch +20 / spec +5);0 回归 | v0.3 planner 里程碑就绪;execution-plan.json 是 Phase 8B 的权威输入;dry_run 是 human-gate 最小扩展 |
|
|
1633
1638
|
| **D48** | **2026-04-18** | **Phase 8B 完成 — executor 线就绪,v0.3 coding 工厂可用** — (8B.0) schema 不动(tasks.files_modified/session_id/parent_id 齐备);events 新增 5 type(wave_started / wave_completed / plan_completed / merged_back / merge_conflict),利用 events.type 无 CHECK 约束向后兼容。(8B.1) `orchestrator/dispatch-rules.cjs` 声明式规则数组(GSD-2 模式):`evaluate(ctx, rules)` 按 priority 取首个 match 返 `{rule_id, action, runtime}`;3 action(`spawn_agent`/`defer`/`block`);6 DEFAULT_RULES(breaker-blocked / deps-not-ready / no-runtimes / wave-conflict / by-preference / fallback-first-available);ROUTE_PREFERENCES 从 daemon.cjs 移过来;daemon.routeTask 改为 `evaluate` 的 thin wrapper,Phase 5.4 daemon 6 routeTask 测试 0 回归。(8B.2) `orchestrator/parallel-orchestrator.cjs` 读 plan waves → wave.parallel=true 批 `Promise.all` / parallel=false await 串行;前置 dispatch-rules.evaluate;`STATUS_TRANSITIONS` 约束要求 spawn 后 patchTask(in_progress),exit 后 patchTask(completed|pending);失败 task 不短路同 wave 其他任务;`finalizeSession` 调 `closeSession` 统一 session+worktree+可选 autoMerge 生命周期;runPlan 加 `autoMerge`/`mergeBaseBranch` opt-in(默认关,Phase 4/5/6/7/8A 0 回归)。(8B.3) `orchestrator/worktree-manager.cjs` N 并发 git worktree 注册簿:allocate/release/listActive/releaseAll;`listActive` 用 `git worktree list --porcelain` + realpath 规范化(macOS `/var`↔`/private/var` 符号链接坑)+ `.ultra/worktrees/` 域过滤;`releaseAll` 兼作崩溃恢复(git-tracked 清理 + 文件系统孤儿 sweep);Node 单线程 execFileSync 天然序列化避免 `.git/config.lock` 竞争。(8B.4) `orchestrator/auto-merge.cjs` — autoMerge 三出口(no_changes / merged_back / merge_conflict);冲突路径用 `git diff --name-only --diff-filter=U` 在 abort 之前收集;closeSession 加 `autoMerge`/`mergeBaseBranch` opt-in,conflict 时强制 `remove_worktree=false` 保留 worktree 给人。(8B.5 gate) `orchestrator/tests/phase-8b-gate.test.cjs` 三条 gate 全过:10-task PRD 端到端完成率 100%(要求 ≥80%);5 slice 压力 0 git lock 错误;merge 冲突正确识别 + conflict_paths 准确。**总计 +36 tests**(dispatch-rules +12 / worktree-manager +8 / parallel-orchestrator +7 / auto-merge +6 / gate +3),D47 基线 361 → **397 tests 全绿**(state 182 / orch 103 / spec 6 / rest 106),0 回归 | **v0.3 = 自动化 coding 工厂**:8A plan → 8B 执行 → 冲突人审 全链打通;autoMerge 默认关保留手动控制;worktree 全生命周期可观测可恢复 |
|
|
1634
1639
|
| **D50** | **2026-07-15** | **重划插件与记忆边界**:Claude Code、Codex、OpenCode 改为各自 native plugin;只打包 10 个 Ultra 公共 workflow、4 个 agent-only 规则 skill 与宿主专属 collab companion;删除 6 个外部 skill、recall、Impeccable 残留、Ultra memory MCP/store/wrapper/capture hooks;持久记忆由独立 cloud-mem/claude-mem 负责;用户 handbook 通过可预览、可备份的 managed block 显式同步 | 用户确认最终方案;运行时 allowlist、conformance、hook 与 handbook 回归测试共同锁定边界 |
|
|
1635
1640
|
| **D51** | **2026-07-17** | **runtime 收敛为 Claude Code、OpenCode、Codex**:删除第四 runtime 的 adapter、安装参数、collab skill、prompt、schema、pricing、调度与测试面;`ultra-verify` 改为当前宿主主责加单一只读外部顾问 | 用户确认不再需要第四 runtime;0.6.0 退役契约阻止其重新进入活跃源码或发布包 |
|
|
1641
|
+
| **D52** | **2026-07-17** | **初始交付后进入持续变更闭环**:新增 `ultra-change` / `ultra-doctor`、change/context/artifact/trace/incident/projection/consumer 状态、delta-first spec、确定性 convergence 与 baseline reconciliation;删除内置 code-graph watcher 和通用命令代理,Memory/图谱只保留外部 provider 元数据引用 | 用户确认采用最佳组合落地;解决日常小改导致 spec/context 漂移、投影失败静默和异常无恢复证据的问题 |
|
|
1636
1642
|
|
|
1637
1643
|
---
|
|
1638
1644
|
|
|
@@ -1656,9 +1662,9 @@ Week 18 buffer(ship 中任何 Phase 的 25% 滑动吃掉)
|
|
|
1656
1662
|
- **规则层 / 执行层**:§4.2;Phase 1-4 / Phase 4.5-8。
|
|
1657
1663
|
- **Session**:GSD-2 模式升级版(D20):新进程 + 独立 worktree + lease/
|
|
1658
1664
|
heartbeat(存 sessions 表) + artifact dir;Phase 4.5 实装。
|
|
1659
|
-
- **state.db**:`.ultra/state.db` SQLite + WAL
|
|
1660
|
-
|
|
1661
|
-
|
|
1665
|
+
- **state.db**:`.ultra/state.db` SQLite + WAL 数据库,所有 Ultra workflow
|
|
1666
|
+
状态的权威源;当前 15 表,新增 changes/artifacts/context_snapshots/
|
|
1667
|
+
trace_links/incidents/projection_jobs/event_consumers;Phase 2 建立,D52 扩展。
|
|
1662
1668
|
- **三层架构**:§4.1;skill(知识,只读发现)+ MCP(状态操作主路径)+
|
|
1663
1669
|
CLI(兜底)。
|
|
1664
1670
|
- **staleness**:task 的 spec 被改后,未开工的 pending task 自动标记
|
package/docs/ROADMAP.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# ultra-builder-pro-cli — Roadmap
|
|
2
2
|
|
|
3
|
-
> **
|
|
4
|
-
>
|
|
5
|
-
>
|
|
3
|
+
> **Current roadmap**. [`PLAN.zh-CN.md`](./PLAN.zh-CN.md) preserves the original
|
|
4
|
+
> phase plan and decision history. Current executable contracts live in
|
|
5
|
+
> `spec/`, `AGENT-CONTEXT.md`, and `RUNTIME-COMPAT-MATRIX.md`; those sources win
|
|
6
|
+
> when historical plan text differs.
|
|
6
7
|
|
|
7
8
|
**Goal**: distribute the Ultra Builder Pro engineering loop as native Claude
|
|
8
9
|
Code, OpenCode, and Codex plugins, and run it with isolated sessions sharing one
|
|
@@ -12,9 +13,7 @@ authoritative workflow store.
|
|
|
12
13
|
|
|
13
14
|
**Distribution channels (v1.0)**: npm · Homebrew · pip.
|
|
14
15
|
|
|
15
|
-
**
|
|
16
|
-
|
|
17
|
-
**Timeline**: 14–18 weeks AI-assisted (PLAN §11).
|
|
16
|
+
**Release line**: `0.7.x`; every release is gated by `npm run verify:release`.
|
|
18
17
|
|
|
19
18
|
---
|
|
20
19
|
|
|
@@ -23,7 +22,7 @@ authoritative workflow store.
|
|
|
23
22
|
| Release | Week | Contents |
|
|
24
23
|
|---------|-----:|---------------------------------------------------------------------------|
|
|
25
24
|
| **v0.1**| 8 | Rule layer + execution-lite (session isolation + admission + event subscribe + active-session visibility) — solves the core "independent conversations don't pollute each other" pain |
|
|
26
|
-
| **v0.2**| 11 | Auto-recovery + monitoring +
|
|
25
|
+
| **v0.2**| 11 | Auto-recovery + monitoring + full conformance |
|
|
27
26
|
| **v0.3**| 16 | PRD → execution-plan artifact → parallel dispatch / merge — coding factory |
|
|
28
27
|
| **v1.0**| 17–18| Three-channel publish (npm + Homebrew + pip) |
|
|
29
28
|
|
|
@@ -38,30 +37,31 @@ authoritative workflow store.
|
|
|
38
37
|
| 4 | Cross-runtime distribution + 4.6a smoke flow | ✅ done (D41, `5aa1fd0`) |
|
|
39
38
|
| 4.5 | Execution-lite (session + admission + events) | ✅ done (D42, `0d3e5ed`) — **v0.1 ready** |
|
|
40
39
|
| 5 | Recovery + staleness + auto-routing | ✅ done (D43) → v0.2 |
|
|
41
|
-
| 6 | Monitoring +
|
|
40
|
+
| 6 | Monitoring + telemetry | ✅ done (D44) → v0.2 |
|
|
42
41
|
| 4.6b | Full conformance suite | ✅ done (D45) — 20 conformance + 21 resolveTarget tests |
|
|
43
42
|
| 7 | tagged tasks + skill mining; retired Ultra memory handed to cloud-mem/claude-mem | ✅ superseded by D50 boundary cleanup |
|
|
44
43
|
| 8A | Plan automation (parse / topo / expand + artifact + human gate) | ✅ done (D47, `a932cb8`) → v0.3 |
|
|
45
44
|
| 8B | Execution automation (dispatch / parallel worktree / merge) | ✅ done (D48, `8224159`) — **v0.3 ready** |
|
|
46
|
-
|
|
|
45
|
+
| 8C | Continuous change packets + context compiler + convergence + doctor | ✅ done (D52) |
|
|
46
|
+
| 9 | Release pipeline | npm tag publishing live; Homebrew / pip not implemented |
|
|
47
47
|
|
|
48
48
|
## What is in the repo today
|
|
49
49
|
|
|
50
50
|
```
|
|
51
51
|
spec/ ← Phase 1 single source of truth
|
|
52
|
-
├── mcp-tools.yaml (
|
|
52
|
+
├── mcp-tools.yaml (29 live tools across 5 families)
|
|
53
53
|
├── cli-protocol.md (CLI ↔ MCP mapping table)
|
|
54
54
|
├── schemas/ (state-db.sql + 4 JSON schemas)
|
|
55
55
|
├── fixtures/{valid,invalid}/ (+ v4.4-project for migration)
|
|
56
|
-
└── scripts/test-all.cjs (npm run test:spec —
|
|
56
|
+
└── scripts/test-all.cjs (npm run test:spec — 7 validation stages)
|
|
57
57
|
|
|
58
58
|
mcp-server/ ← Phase 2 authoritative state layer
|
|
59
|
-
├── server.cjs (stdio MCP server,
|
|
59
|
+
├── server.cjs (stdio MCP server, 29 task/session/change/system/plan tools)
|
|
60
60
|
├── lib/
|
|
61
61
|
│ ├── state-db.cjs (SQLite + WAL + pragmas)
|
|
62
62
|
│ ├── state-ops.cjs (full write API, status state machine)
|
|
63
63
|
│ └── projector.cjs (state.db → tasks.json + context md)
|
|
64
|
-
└── tests/ (npm run test:state
|
|
64
|
+
└── tests/ (npm run test:state)
|
|
65
65
|
|
|
66
66
|
ultra-tools/ ← CLI fallback, migration, and diagnostics
|
|
67
67
|
├── cli.cjs
|
|
@@ -76,7 +76,7 @@ adapters/ ← native Claude/OpenCode/Codex plugin builders
|
|
|
76
76
|
skills/ ← allowlisted Ultra workflows, internal rules, and collab companions
|
|
77
77
|
hooks/ ← 7 workflow-only Python hooks; OpenCode uses native JavaScript hooks
|
|
78
78
|
docs/
|
|
79
|
-
├── PLAN.zh-CN.md
|
|
79
|
+
├── PLAN.zh-CN.md historical phase plan + decision log
|
|
80
80
|
├── ARCHITECTURE.md Phase 1 single-page entry point
|
|
81
81
|
├── AGENT-CONTEXT.md Phase 3 canonical runtime context contract
|
|
82
82
|
├── USER-HANDBOOK-CONTRACT.md managed CLAUDE.md / AGENTS.md boundary
|
|
@@ -13,12 +13,12 @@ equivalent lifecycle/control surface, **N/A** = intentionally not installed.
|
|
|
13
13
|
|---|---|---|---|
|
|
14
14
|
| Package form | `.claude-plugin` native plugin | native config bundle + JS plugin | personal `.codex-plugin` |
|
|
15
15
|
| Public entry | `/ultra-*`, `/learn` | `/ultra-*`, `/learn` | `$ultra-builder-pro:<skill>` |
|
|
16
|
-
| Public Ultra workflows |
|
|
16
|
+
| Public Ultra workflows | 12 | 12 | 12 |
|
|
17
17
|
| Internal agent-rule skills | 4, non-user-facing | 4, non-user-facing | 4 with implicit invocation disabled |
|
|
18
18
|
| Collaboration companions | `codex-collab`, `ultra-verify` | `cc-collab`, `codex-collab`, `ultra-verify` | `cc-collab`, `ultra-verify` |
|
|
19
19
|
| External browser/deploy/framework skills | N/A | N/A | N/A |
|
|
20
20
|
|
|
21
|
-
Codex converts the workflows into namespaced skills and records
|
|
21
|
+
Codex converts the workflows into namespaced skills and records eleven legacy
|
|
22
22
|
command mappings in `command-map.json`; `ultra-review` remains directly
|
|
23
23
|
invocable as a skill.
|
|
24
24
|
|
|
@@ -39,14 +39,15 @@ primary verification.
|
|
|
39
39
|
|
|
40
40
|
| Lifecycle | Claude Code | OpenCode | Codex |
|
|
41
41
|
|---|---|---|---|
|
|
42
|
-
| Session context/health | FULL, native `SessionStart` |
|
|
42
|
+
| Session context/health | FULL, native `SessionStart` | DEGRADED, native context; health via `system.doctor` | FULL, native `SessionStart` |
|
|
43
43
|
| Active edit boundary | FULL, `PreToolUse Edit|Write` | FULL, `tool.execute.before` rejects projection writes | FULL, `PreToolUse Edit|Write|apply_patch` |
|
|
44
44
|
| Compaction recovery | FULL, `PreCompact` + resume matcher | FULL, native compacting context | FULL, `PreCompact` + `PostCompact` |
|
|
45
45
|
| Incomplete-stop gate | FULL, native blocking `Stop` | DEGRADED, no equivalent blocking stop hook | FULL, native blocking `Stop` |
|
|
46
46
|
| Subagent lifecycle evidence | FULL | DEGRADED, no equivalent packaged event | FULL |
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
Health/context hooks inspect initialized projects; projection protection also
|
|
49
|
+
applies at baseline, while compact/stop/subagent enforcement remains active-workflow scoped.
|
|
50
|
+
No host receives prompt capture, transcript
|
|
50
51
|
capture, observation journaling, session-summary memory, generic command
|
|
51
52
|
blocking, or generic post-edit policy.
|
|
52
53
|
|
|
@@ -55,15 +56,14 @@ blocking, or generic post-edit policy.
|
|
|
55
56
|
| Capability | Claude Code | OpenCode | Codex |
|
|
56
57
|
|---|---|---|---|
|
|
57
58
|
| stdio MCP registration | plugin `.mcp.json` | `opencode.json` local MCP entry | plugin `.mcp.json` |
|
|
58
|
-
| Live contracts |
|
|
59
|
-
|
|
|
60
|
-
| Nine non-live contracts | host-native review/discovery/ask | host-native review/discovery/ask | `codex-capability-map.json` |
|
|
59
|
+
| Live/declared contracts | 29 | 29 | 29 |
|
|
60
|
+
| Host-native review/discovery/ask | native | native | documented in `codex-capability-map.json` |
|
|
61
61
|
| Durable authority | project `.ultra/state.db` | project `.ultra/state.db` | project `.ultra/state.db` |
|
|
62
62
|
| Ultra memory API | N/A | N/A | N/A |
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
`mcp-server/server.cjs` are
|
|
66
|
-
interaction remain host-native surfaces.
|
|
64
|
+
All 29 `task.*`, `session.*`, `change.*`, `system.*`, and `plan.*` operations
|
|
65
|
+
registered by `mcp-server/server.cjs` are live. Review, impact discovery, skill
|
|
66
|
+
loading, and user interaction remain host-native surfaces.
|
|
67
67
|
|
|
68
68
|
## 5. User handbook presentation
|
|
69
69
|
|
package/hooks/README.md
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
# Ultra Builder Pro workflow hooks
|
|
2
2
|
|
|
3
|
-
These hooks
|
|
4
|
-
|
|
3
|
+
These hooks observe only Ultra-owned state. Session health/context recognizes an initialized
|
|
4
|
+
`.ultra/state.db` and active continuous changes; edit/compact/stop/subagent enforcement remains
|
|
5
|
+
bounded to the relevant Ultra projection or a non-terminal workflow.
|
|
5
6
|
|
|
6
7
|
| Lifecycle | Hook | Purpose |
|
|
7
8
|
|---|---|---|
|
|
8
|
-
| Session start | `health_check.py` |
|
|
9
|
-
| Session start | `workflow_context.py` | Inject
|
|
10
|
-
| Before edit | `active_task_context.py` |
|
|
9
|
+
| Session start | `health_check.py` | Read-only integrity, incident, projection, session, and change-artifact checks |
|
|
10
|
+
| Session start | `workflow_context.py` | Inject baseline/active workflow/change context and filtered provider metadata references |
|
|
11
|
+
| Before edit | `active_task_context.py` | Protect `tasks.json` projection and restate an active task boundary |
|
|
11
12
|
| Before compact | `workflow_checkpoint.py` | Atomically save a minimal workflow checkpoint |
|
|
12
13
|
| After compact/resume | `workflow_resume.py` | Re-inject the current workflow boundary |
|
|
13
14
|
| Stop | `pre_stop_check.py` | Block once when the Ultra workflow is incomplete |
|
|
14
15
|
| Subagent lifecycle | `subagent_tracker.py` | Append lifecycle evidence under `.ultra/runtime/` |
|
|
15
16
|
|
|
16
17
|
The plugin deliberately does not capture prompts, tool observations, transcripts, summaries, or
|
|
17
|
-
cross-session memory. Generic command blocking and post-edit policy are
|
|
18
|
-
|
|
18
|
+
cross-session memory or code-graph content. Generic command blocking and post-edit policy are
|
|
19
|
+
user/repository governance. Persistent Memory/graph content belongs to separately installed providers.
|
|
19
20
|
|
|
20
21
|
Runtime wiring:
|
|
21
22
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
2
|
+
"""Protect Ultra projections and restate an active task boundary before edits."""
|
|
3
3
|
|
|
4
4
|
import json
|
|
5
5
|
import sys
|
|
@@ -33,9 +33,28 @@ def main() -> None:
|
|
|
33
33
|
data = {}
|
|
34
34
|
start = Path(data.get("cwd") or Path.cwd()).resolve()
|
|
35
35
|
for root in (start, *start.parents):
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
ultra = root / ".ultra"
|
|
37
|
+
state_file = ultra / "workflow-state.json"
|
|
38
|
+
initialized = (
|
|
39
|
+
(ultra / "state.db").is_file()
|
|
40
|
+
or state_file.is_file()
|
|
41
|
+
or (ultra / "changes" / "active").is_dir()
|
|
42
|
+
)
|
|
43
|
+
if not initialized:
|
|
38
44
|
continue
|
|
45
|
+
if targets_tasks_projection(data, root):
|
|
46
|
+
print(json.dumps({"hookSpecificOutput": {
|
|
47
|
+
"hookEventName": "PreToolUse",
|
|
48
|
+
"permissionDecision": "deny",
|
|
49
|
+
"permissionDecisionReason": (
|
|
50
|
+
"Refusing a direct write to the .ultra/tasks/tasks.json projection. "
|
|
51
|
+
".ultra/state.db is authoritative; use the Ultra MCP task tools and "
|
|
52
|
+
"run ultra-doctor when state or projection health is degraded."
|
|
53
|
+
),
|
|
54
|
+
}}))
|
|
55
|
+
return
|
|
56
|
+
if not state_file.is_file():
|
|
57
|
+
break
|
|
39
58
|
try:
|
|
40
59
|
state = json.loads(state_file.read_text(encoding="utf-8"))
|
|
41
60
|
except (OSError, json.JSONDecodeError) as exc:
|
|
@@ -45,18 +64,6 @@ def main() -> None:
|
|
|
45
64
|
break
|
|
46
65
|
task = state.get("task_id", state.get("task", "unknown"))
|
|
47
66
|
step = state.get("step", "unknown")
|
|
48
|
-
if targets_tasks_projection(data, root):
|
|
49
|
-
print(json.dumps({"hookSpecificOutput": {
|
|
50
|
-
"hookEventName": "PreToolUse",
|
|
51
|
-
"permissionDecision": "deny",
|
|
52
|
-
"permissionDecisionReason": (
|
|
53
|
-
"Refusing a direct write to .ultra/tasks/tasks.json during an active Ultra "
|
|
54
|
-
"workflow. .ultra/state.db is authoritative; use the Ultra MCP task tools. "
|
|
55
|
-
"If they report LEGACY_STATE_MIGRATION_REQUIRED, run the v4.4 to v4.5 "
|
|
56
|
-
"migration before continuing."
|
|
57
|
-
),
|
|
58
|
-
}}))
|
|
59
|
-
return
|
|
60
67
|
print(json.dumps({"hookSpecificOutput": {
|
|
61
68
|
"hookEventName": "PreToolUse",
|
|
62
69
|
"additionalContext": (
|