flower-trellis 0.5.5 → 0.5.6-beta.1
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 +8 -0
- package/enhancements/0.6/.agents/skills/trellis-auto-loop/SKILL.md +11 -7
- package/enhancements/0.6/.agents/skills/trellis-check-all/SKILL.md +3 -2
- package/enhancements/0.6/.agents/skills/trellis-check-all/references/depth-routing.md +10 -2
- package/enhancements/0.6/.agents/skills/trellis-check-all/references/full-profile.md +2 -0
- package/enhancements/0.6/.agents/skills/trellis-check-all/references/light-profile.md +2 -0
- package/enhancements/0.6/.agents/skills/trellis-check-all/references/reporting-and-disposition.md +4 -2
- package/enhancements/0.6/.agents/skills/trellis-push/SKILL.md +38 -14
- package/enhancements/0.6/.agents/skills/trellis-route/SKILL.md +36 -9
- package/enhancements/0.6/.agents/skills/trellis-route/scripts/route_state.py +93 -1
- package/enhancements/0.6/.claude/skills/trellis-auto-loop/SKILL.md +11 -7
- package/enhancements/0.6/.claude/skills/trellis-check-all/SKILL.md +3 -2
- package/enhancements/0.6/.claude/skills/trellis-check-all/references/depth-routing.md +10 -2
- package/enhancements/0.6/.claude/skills/trellis-check-all/references/full-profile.md +2 -0
- package/enhancements/0.6/.claude/skills/trellis-check-all/references/light-profile.md +2 -0
- package/enhancements/0.6/.claude/skills/trellis-check-all/references/reporting-and-disposition.md +4 -2
- package/enhancements/0.6/.claude/skills/trellis-push/SKILL.md +38 -14
- package/enhancements/0.6/.claude/skills/trellis-route/SKILL.md +36 -9
- package/enhancements/0.6/.claude/skills/trellis-route/scripts/route_state.py +93 -1
- package/enhancements/0.6/overrides/bundles/intent-routing.json +3 -1
- package/enhancements/0.6/overrides/bundles/untracked-execution.json +16 -0
- package/enhancements/0.6/overrides/conflicts.json +4 -2
- package/enhancements/0.6/overrides/patches/agents/untracked-context/codex-content.md +2 -0
- package/enhancements/0.6/overrides/patches/agents/untracked-context/codex-selector.md +1 -0
- package/enhancements/0.6/overrides/patches/agents/untracked-context/kiro-content.txt +1 -0
- package/enhancements/0.6/overrides/patches/agents/untracked-context/kiro-selector.txt +1 -0
- package/enhancements/0.6/overrides/patches/agents/untracked-context/markdown-check-selector.md +1 -0
- package/enhancements/0.6/overrides/patches/agents/untracked-context/markdown-content.md +8 -0
- package/enhancements/0.6/overrides/patches/agents/untracked-context/markdown-implement-selector.md +1 -0
- package/enhancements/0.6/overrides/patches/agents/untracked-context/patch.json +83 -0
- package/enhancements/0.6/overrides/patches/hooks/inject-workflow-state/shared-runtime/baseline-flower-pre-untracked.py +443 -0
- package/enhancements/0.6/overrides/patches/hooks/inject-workflow-state/shared-runtime/content.py +53 -7
- package/enhancements/0.6/overrides/patches/hooks/inject-workflow-state/shared-runtime/patch.json +6 -1
- package/enhancements/0.6/overrides/patches/hooks/session-start/pre-check-hold/claude-content.py +13 -0
- package/enhancements/0.6/overrides/patches/hooks/session-start/pre-check-hold/codex-content.py +13 -0
- package/enhancements/0.6/overrides/patches/skills/trellis-meta/managed-workflow-owners/owner-routing-content.md +2 -0
- package/enhancements/0.6/overrides/patches/skills/trellis-meta/managed-workflow-owners/workflow-change-map-content.md +1 -0
- package/enhancements/0.6/overrides/patches/skills/trellis-start/no-task-routing/content.md +1 -1
- package/enhancements/0.6/overrides/patches/skills/trellis-update-spec/autonomous-evaluation/content.md +8 -6
- package/enhancements/0.6/overrides/patches/workflow/hub/content.md +3 -1
- package/enhancements/0.6/overrides/patches/workflow/intent-routing/request-triage/content.md +3 -0
- package/enhancements/0.6/overrides/patches/workflow/phase-ownership/phase-2-check-content.md +3 -1
- package/enhancements/0.6/overrides/patches/workflow/phase-ownership/phase-2-implement-content.md +5 -1
- package/enhancements/0.6/overrides/patches/workflow/phase-ownership/phase-3-commit-content.md +2 -0
- package/enhancements/0.6/overrides/patches/workflow/phase-ownership/phase-3-update-spec-content.md +2 -0
- package/enhancements/0.6/overrides/patches/workflow/runtime-contract-reference/runtime-reference-content.md +1 -1
- package/enhancements/0.6/overrides/patches/workflow/runtime-contract-reference/state-contract-comment-content.md +2 -1
- package/enhancements/0.6/overrides/patches/workflow/state-no-task/content.md +1 -1
- package/enhancements/0.6/overrides/patches/workflow/state-untracked/content.md +8 -0
- package/enhancements/0.6/overrides/patches/workflow/state-untracked/patch.json +13 -0
- package/enhancements/0.6/overrides/patches/workflow/state-untracked/selector.md +1 -0
- package/enhancements/0.6/scripts/auto_loop.py +317 -49
- package/enhancements/0.6/scripts/git_evidence.py +343 -0
- package/enhancements/0.6/scripts/pre_check_state.py +108 -30
- package/enhancements/0.6/scripts/task_intent.py +190 -55
- package/enhancements/0.6/scripts/untracked_flow.py +800 -0
- package/enhancements/MANIFEST.json +20 -3
- package/enhancements/common/.common/.claude/skills/aliyun-sls-query/SKILL.md +164 -0
- package/enhancements/common/.common/.claude/skills/aliyun-sls-query/assets/env.example +6 -0
- package/enhancements/common/.common/.claude/skills/aliyun-sls-query/scripts/sls_get_logs.py +259 -0
- package/enhancements/common/.common/.codex/skills/aliyun-sls-query/SKILL.md +164 -0
- package/enhancements/common/.common/.codex/skills/aliyun-sls-query/assets/env.example +6 -0
- package/enhancements/common/.common/.codex/skills/aliyun-sls-query/scripts/sls_get_logs.py +259 -0
- package/package.json +3 -3
- package/src/builtin-plugins/skill-garden/content-adapter.js +12 -0
- package/src/cli.js +4 -0
- package/src/commands/init.js +3 -0
- package/src/commands/self-check.js +5 -1
- package/src/commands/telemetry.js +56 -0
- package/src/commands/update.js +5 -0
- package/src/lib/copy-scripts.js +35 -0
- package/src/lib/patch-engine.js +15 -0
- package/src/lib/self-check.js +8 -2
- package/src/lib/telemetry.js +322 -0
- package/src/lib/update-check.js +11 -2
package/README.md
CHANGED
|
@@ -64,6 +64,9 @@ flower-trellis self-update --target . --yes
|
|
|
64
64
|
# 管理启动更新检查策略
|
|
65
65
|
flower-trellis update-check get --target .
|
|
66
66
|
|
|
67
|
+
# 查看或修改匿名安装遥测开关
|
|
68
|
+
flower-trellis telemetry status
|
|
69
|
+
|
|
67
70
|
# 卸载:移除 Trellis 本体并清理强化包残留
|
|
68
71
|
flower-trellis uninstall
|
|
69
72
|
|
|
@@ -73,6 +76,8 @@ flower-trellis -v
|
|
|
73
76
|
|
|
74
77
|
> 已全局安装时可直接写 `flower-trellis`、`ftl` 或 `ft`(三者等价);未安装则在命令前加 `npx`。
|
|
75
78
|
|
|
79
|
+
为统计安装活跃度和版本分布,CLI 默认在远程版本检查及 `init` / `update` 成功后上报随机设备 ID、Flower/Trellis 版本、项目 `.trellis/.developer` 名称和运行平台;不采集 MAC、主机名、系统用户名、项目路径或仓库地址。可用 `flower-trellis telemetry disable` 持久停用,或用 `FLOWER_NO_TELEMETRY=1` 临时停用。
|
|
80
|
+
|
|
76
81
|
### 命令
|
|
77
82
|
|
|
78
83
|
| 命令 | 说明 |
|
|
@@ -82,6 +87,7 @@ flower-trellis -v
|
|
|
82
87
|
| `self-check` | 输出启动更新检查 JSON,供 Codex / Claude Code hook 和 AI 自动化读取 |
|
|
83
88
|
| `self-update` | 受控升级 flower-trellis 并对目标项目执行完整 `flower-trellis update` 重叠加 |
|
|
84
89
|
| `update-check` | 管理 `.trellis/.flower-manifest.json` 内的启动更新检查策略 |
|
|
90
|
+
| `telemetry` | 查询、启用或停用用户级匿名安装遥测 |
|
|
85
91
|
| `plugin` | 管理 Flower Plugin、Marketplace 来源、GitLab 授权和作者校验 |
|
|
86
92
|
| `uninstall` | 移除 Trellis 本体并清理强化包残留(支持 `-y` / `--dry-run`) |
|
|
87
93
|
| `<其它命令>` | 原样透传给 Trellis,覆盖其现有及未来子命令 |
|
|
@@ -113,6 +119,8 @@ flower-trellis plugin
|
|
|
113
119
|
|
|
114
120
|
交互管理器采用 `发现 / 已安装 / 来源 / 问题` 四个页签。Trellis 项目的 `发现` 页会展示 `flower/skill-garden` 内置入口,按 Enter 直接管理工作流强化与可选通用技能;原 `flower-trellis skill` 命令继续保留为高级兼容入口。`发现` 同时合并全部已启用来源的 Plugin,并保留来源标签和即时搜索;未登录 GitLab 来源会直接进入 Device Flow,GitHub 公共来源无需登录。`来源` 页的“新增来源”可选择 GitHub 公共仓库或 GitLab Marketplace;GitHub 会先在临时缓存中下载固定快照、检测格式、展示可导入与忽略组件,确认后才保存。ref 留空时使用仓库默认分支;出现多个格式入口时会要求选择,公开 GitHub 跨仓 Marketplace 条目和 `plugins/*` 多 Plugin 仓库也可识别。
|
|
115
121
|
|
|
122
|
+
可选通用技能包含 `aliyun-sls-query`,可为 Codex / Claude 项目安装零第三方依赖的阿里云 SLS 查询脚本与排障知识;默认不安装,也不会复制用户私有 AK/SK 配置。
|
|
123
|
+
|
|
116
124
|
安装、更新和卸载都会先展示 dry-run、依赖、capability 和目标文件变化,确认后才写入项目。Plugin 作者使用的 `plugin init`、`plugin validate` 继续保留在高级命令中,不占用普通用户的管理器首页。
|
|
117
125
|
|
|
118
126
|
独立的 `plugin add` 只建立最小 Plugin Runtime,安装目标 Plugin 及其显式依赖,不会隐式安装 `skill-garden`,因此交互管理器也可以在没有 `.trellis/` 的普通项目中使用。
|
|
@@ -16,7 +16,7 @@ description: "启动、恢复和推进 Trellis 自动任务循环。用于用户
|
|
|
16
16
|
- `record` 返回 `status=retryable` 时保留的是同一个 outstanding Check action:不得运行 `next`,必须先按返回指令消解漂移并重录。
|
|
17
17
|
- 本地提交是自动终点。不得 push、merge、release、deploy、finish-work 或 archive;queue item 完成后 Trellis task 仍保持 `in_progress`。
|
|
18
18
|
- 任务顺序只决定稳定调度顺序,不隐含依赖。依赖必须通过 `--depends-on dependent=dependency` 明确传入或由 planning artifacts 明确声明。
|
|
19
|
-
- 任务级失败只阻塞自身及显式依赖项;独立任务继续。fix/recheck
|
|
19
|
+
- 任务级失败只阻塞自身及显式依赖项;独立任务继续。fix/recheck、planning repair 与安全的 commit-only repair 各最多 3 轮,队列结束后不自动执行第二遍恢复扫描。
|
|
20
20
|
- schema 1 runtime 继续按 runner 返回的旧 action 恢复,包括 outstanding `confirm_brief`;不要把旧 run 改写成 schema 2。
|
|
21
21
|
|
|
22
22
|
启动或恢复前静默清除交互式 pre-check hold;miss、task mismatch 或损坏诊断不阻断 runner:
|
|
@@ -105,7 +105,7 @@ python3 ./.trellis/scripts/auto_loop.py decide \
|
|
|
105
105
|
| `run_fix` | 根据 `last_failure` 修复并复用 implement route | `record --action run_fix --result ok --route-mode <mode> --route-source <source>` |
|
|
106
106
|
| `run_recheck` | 复用 check route,且不得低于 `minimum_check_depth` | 同 `run_check_all`,action 改为 `run_recheck` |
|
|
107
107
|
| `run_spec_update` | 执行 `trellis-update-spec` | `no-op|written` 用 ok;`needs-review` 用 blocked + `spec-needs-review` |
|
|
108
|
-
| `commit_only` | 复用 `trellis-push`
|
|
108
|
+
| `commit_only` | 复用 `trellis-push` 内部多仓精确本地提交能力,不 push | `record --action commit_only --result ok --commit <primary-or-last-hash> [--repo-commit <repository>::<hash> ...] --files <exact...> --commit-message "..."` |
|
|
109
109
|
|
|
110
110
|
失败或越权时必须回写,runner 决定重试、blocked 或继续队列:
|
|
111
111
|
|
|
@@ -113,6 +113,7 @@ python3 ./.trellis/scripts/auto_loop.py decide \
|
|
|
113
113
|
python3 ./.trellis/scripts/auto_loop.py record \
|
|
114
114
|
--action <action> --result failed|blocked \
|
|
115
115
|
--failure-type <type> --summary "<摘要>" \
|
|
116
|
+
[--repo-commit <repository>::<hash> ...] \
|
|
116
117
|
[--files <repository>::<path> ...]
|
|
117
118
|
python3 ./.trellis/scripts/auto_loop.py next
|
|
118
119
|
```
|
|
@@ -128,17 +129,20 @@ Check-All 自动修复当前任务 `implement.md` 或 `brief.md` 时,每个实
|
|
|
128
129
|
3. 若是合法 `implement.md` / `brief.md` DOC 修复,补齐精确 `--doc-remediation-file` 后重录。
|
|
129
130
|
4. 若无法安全归因,使用原 action、`--result blocked --failure-type artifact-drift` 重录并停止。
|
|
130
131
|
|
|
131
|
-
同一 Check action 最多允许 3 次 retryable 自纠,第 4 次进入 terminal blocked。实现、spec update、commit-only 等其它 action 的 artifact drift
|
|
132
|
+
同一 Check action 最多允许 3 次 retryable 自纠,第 4 次进入 terminal blocked。实现、spec update、commit-only 等其它 action 的 artifact drift 不使用该预算;commit-only 只有下方明确的 `commit-repairable` 本地失败可以使用独立三轮预算。
|
|
132
133
|
|
|
133
134
|
## Commit-Only
|
|
134
135
|
|
|
135
136
|
收到 `commit_only` 后:
|
|
136
137
|
|
|
137
138
|
1. 用 `status` 确认 active run、profile、outstanding action 和 task 一致。
|
|
138
|
-
2.
|
|
139
|
-
3.
|
|
140
|
-
4.
|
|
141
|
-
5.
|
|
139
|
+
2. 调用 `trellis-push` 内部 `commit-only`,由它根据任务 artifacts、项目 SOP/spec、受版本控制脚本和可验证 Git/submodule 关系,从当前真实 Git 状态生成有序 `commit -> generate -> commit` 链。不得仅因多个仓库、submodule pin 或证据充分的本地生成命令返回 `multi-repo-commit-boundary`。
|
|
140
|
+
3. 仓库发现、证据冲突处理、生成入口校验、exact/retained 归属和逐步 Git 预检都由 `trellis-push` 负责;本 skill 不另行猜测依赖、拼接命令或绕过其计划。只有本地生成入口确定性、可重复、受版本控制且无外部副作用,并且计划外 dirty、retained、staged、分支和 HEAD 都满足其安全契约时才继续。
|
|
141
|
+
4. 按 `trellis-push` 的计划精确提交和运行生成入口。不得裸 `git add .`、`git add -A`、push、按时间差猜归属或撤销已经成功的本地 commit。
|
|
142
|
+
5. 确定性生成失败、生成结果尚未收敛或可重新规划的本地预检失败时,用 `--result failed --failure-type commit-repairable` 回写全部已完成 `--repo-commit`,然后立即 `next`。runner 前 3 次会重新发出同一个 action;每次都从真实 Git 状态重建计划,验证并跳过已完成提交,安全重跑生成,后续仓 clean 时跳过空提交。第 4 次失败进入 `commit-repair-budget-exhausted`。
|
|
143
|
+
6. 全部完成后,用主仓或最后提交传 `--commit`,并为每个已完成仓库重复传入 `--repo-commit <repositories[].root>::<hash>`;同时传 `--files`、`--retained-files` 和 `--commit-message`,record 成功后立即 next。
|
|
144
|
+
|
|
145
|
+
`commit-repairable` 只用于继续执行仍然安全的本地确定性链。外部副作用风险或任何 Git 安全边界问题必须用 `blocked` 或非 repairable `failed` 立即结束当前项。部分成功提交跨 retry/resume 保留,不回滚、不 amend、不重复创建。
|
|
142
146
|
|
|
143
147
|
`decisions.jsonl` 属于当前任务文件,发生决策时应进入该任务最终精确提交。任务 `task.json.status` 不因 queue item completed 而改写。
|
|
144
148
|
|
|
@@ -12,12 +12,13 @@ description: "统一 Check-All 入口:确认范围与运行上下文,按 req
|
|
|
12
12
|
|
|
13
13
|
## 入口职责
|
|
14
14
|
|
|
15
|
-
1.
|
|
15
|
+
1. 确认本轮检查范围、task artifacts 或 untracked state、项目规范和运行上下文。
|
|
16
16
|
2. 解析 `requested_depth`,生成 `check_profile`,决定 `effective_depth=light|full`。
|
|
17
17
|
3. 按有效深度读取并执行对应 profile。
|
|
18
18
|
4. 全程收集普通问题到 `CHK-*`,收集低风险文档漂移到 `DOC-*`。
|
|
19
19
|
5. 在最终报告前处理允许自动修复的文档漂移,并把修复内容展示在报告里。
|
|
20
20
|
6. 根据 interactive / validated auto-loop 边界输出下一步或完成 runner `record + next`。
|
|
21
|
+
7. untracked 上下文在最终 diff 稳定后调用 `untracked_flow.py record-check`;只有严格通过且 disposition 确认继续时才 `advance --stage spec`。
|
|
21
22
|
|
|
22
23
|
---
|
|
23
24
|
|
|
@@ -62,7 +63,7 @@ description: "统一 Check-All 入口:确认范围与运行上下文,按 req
|
|
|
62
63
|
|
|
63
64
|
| 顺序 | 维度 | 检查内容 | 对照物 |
|
|
64
65
|
| --- | --- | --- | --- |
|
|
65
|
-
| 1 | 三件套实现 | 规划是否正确落地 | `prd.md` + 可选 `design.md` / `implement.md` |
|
|
66
|
+
| 1 | 三件套实现 | 规划是否正确落地 | task 的 `prd.md` + 可选 `design.md` / `implement.md`;untracked 为 `N/A` |
|
|
66
67
|
| 2 | 实现假设 | API、组件、历史数据、数据流和测试假设是否成立 | 源码、真实契约、可用验证证据 |
|
|
67
68
|
| 3 | 完整性与规范 | 影响面是否同步、代码是否符合 spec、验证是否通过 | 实际变更范围 + 项目 spec |
|
|
68
69
|
|
|
@@ -23,9 +23,9 @@ git log --oneline -10
|
|
|
23
23
|
|
|
24
24
|
如果确认范围内确实无变更,提示用户并终止。
|
|
25
25
|
|
|
26
|
-
### 0.2
|
|
26
|
+
### 0.2 读取工作上下文与规范
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
存在当前 task 时读取:
|
|
29
29
|
|
|
30
30
|
- `prd.md`;没有时三件套实现维度标记 `N/A`。
|
|
31
31
|
- `design.md`(若存在)。
|
|
@@ -35,6 +35,14 @@ git log --oneline -10
|
|
|
35
35
|
|
|
36
36
|
不得只依赖 session 摘要推断规划内容,必须读取实际文件。
|
|
37
37
|
|
|
38
|
+
没有当前 task 时运行 `python3 ./.trellis/scripts/untracked_flow.py status --verbose`:
|
|
39
|
+
|
|
40
|
+
- `hit`:读取 work id、summary、stage、scope、baseline/current fingerprint 和已有验证证据;三件套实现维度标记 `N/A`,其余维度仍对实际 diff 与相关 spec 负责。
|
|
41
|
+
- `miss`:仅当用户明确要求检查一个无状态的已知 diff 时继续,并把工作上下文缺失列为风险;否则停止并回到 Request Triage。
|
|
42
|
+
- `error` 或 workspace drift:按阻塞报告,禁止用聊天摘要恢复或覆盖状态。
|
|
43
|
+
|
|
44
|
+
untracked 检查必须处于 `stage=check`,且只读取个人 check 偏好,不创建 task-scoped route decision。
|
|
45
|
+
|
|
38
46
|
### 0.3 验证运行上下文
|
|
39
47
|
|
|
40
48
|
默认 `context=interactive`。只有调用方声称来自 auto-loop 时,才通过 runner 的 `status` / `next` 验证以下事实:
|
|
@@ -6,6 +6,8 @@ Full 是完整验收映射和全影响面审查。只有 `check_profile.effectiv
|
|
|
6
6
|
|
|
7
7
|
## Step 1:对照规划三件套检查实现
|
|
8
8
|
|
|
9
|
+
untracked 上下文没有 task artifacts,本 Step 标记 `N/A`;不得把 summary、scope 或聊天记录当成 PRD。仍须完整执行 Step 2 与 Step 3,并对实际 diff、相关 spec、状态机证据和多仓分发边界负责。
|
|
10
|
+
|
|
9
11
|
### 1.1 验收依据
|
|
10
12
|
|
|
11
13
|
- PRD Requirement / Acceptance Criteria:行为基线。
|
package/enhancements/0.6/.agents/skills/trellis-check-all/references/reporting-and-disposition.md
CHANGED
|
@@ -33,7 +33,7 @@ interactive 模式完成所有可继续检查和允许的 `DOC-*` 自动修复
|
|
|
33
33
|
|
|
34
34
|
[<通过/未通过/阻塞>] <N> 个维度 · CHK <N> · 自动修复 DOC <N> · P0 <N> / P1 <N> / P2 <N> · 验证 <通过>/<总数>
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
工作:<任务名称 | Untracked work: work-id | 无活动工作>
|
|
37
37
|
范围:<文件数与层级摘要;包含自动修复产生的文档 diff>
|
|
38
38
|
画像:requested=<auto/light/full> · effective=<light/full> · confidence=<high/fallback-full/escalated> · <原因摘要>
|
|
39
39
|
结论:<一句话结论>
|
|
@@ -94,7 +94,7 @@ interactive 模式完成所有可继续检查和允许的 `DOC-*` 自动修复
|
|
|
94
94
|
|
|
95
95
|
用户选择修复范围后:
|
|
96
96
|
|
|
97
|
-
1.
|
|
97
|
+
1. 主会话复用当前 task 已有的合法 implement route;untracked 则重新直接读取个人 pref。不存在合法 route 时进入 `trellis-route(target=implement)`,不得自行默认 inline/subagent。
|
|
98
98
|
2. 修复过程中不对每个问题重复确认。
|
|
99
99
|
3. 新增业务歧义、破坏性风险或范围扩张时才暂停,并一次性说明受影响问题。
|
|
100
100
|
4. 完成定向验证后复用当前 check route 重新执行 Check-All。
|
|
@@ -125,6 +125,8 @@ interactive 模式完成所有可继续检查和允许的 `DOC-*` 自动修复
|
|
|
125
125
|
|
|
126
126
|
检查通过后的动作由下方 `Interactive Post-Check Stop Gate` 判断:普通交互停止等待,符合 direct Git 严格通过条件时同轮进入 Phase 3.3 `trellis-update-spec`,再到 Phase 3.4 `trellis-push`。仍有 `CHK-*` 时停留在修复/重检循环。
|
|
127
127
|
|
|
128
|
+
untracked 在最终报告前调用 `untracked_flow.py record-check`:严格通过记录 `pass`,有问题记录 `findings`,部分验证记录 `partial`,真正阻塞记录 `blocked`。普通严格通过但尚未继续时保持 `stage=check`;只有 direct Git 同轮继续或用户后续明确继续时才 `advance --stage spec`。任何报告后的新编辑先回到 `prepare-edit`,旧检查证据随 fingerprint 失效。
|
|
129
|
+
|
|
128
130
|
---
|
|
129
131
|
|
|
130
132
|
## Auto-Loop Return Gate
|
|
@@ -5,7 +5,7 @@ description: "按确认的精确文件范围提交普通变更或完成已就绪
|
|
|
5
5
|
|
|
6
6
|
# Trellis Push
|
|
7
7
|
|
|
8
|
-
`trellis-push` 是 Phase 3.4
|
|
8
|
+
`trellis-push` 是 Phase 3.4 唯一的代码提交入口。它只负责生成最小计划、精确提交、普通推送,以及在 task 上触发进度同步或在 untracked 上完成状态清理。
|
|
9
9
|
|
|
10
10
|
## 职责边界
|
|
11
11
|
|
|
@@ -13,10 +13,11 @@ description: "按确认的精确文件范围提交普通变更或完成已就绪
|
|
|
13
13
|
- 普通多仓计划可以包含本地确定性生成命令;生成后没有新增计划外文件时沿用同一次确认。
|
|
14
14
|
- 普通模式把当前任务产物与更新后的 `task.json` 纳入同一次确认下的独立任务记录提交。
|
|
15
15
|
- 用户明确要求“只提交不推送”时使用 `commit-only`。
|
|
16
|
-
- auto-loop 可调用内部 `commit-only
|
|
16
|
+
- auto-loop 可调用内部 `commit-only`,复用本 skill 的仓库发现、动态多仓计划、确定性本地生成、精确提交和失败保留能力;不再次确认、不 push,也不执行 Step 5 的任务进度写入、进度 commit 或 progress push。Auto-Loop runner 仍按自己的状态契约写入本地 `task.json.progress`。
|
|
17
17
|
- 不发起、终止或解决分支合并;只允许普通模式完成已经开始、冲突已清零且索引完全可归属的 merge commit。
|
|
18
18
|
- 不处理上线核对、任务归档、会话日志或自动任务队列状态。
|
|
19
19
|
- 不使用 `git add .`、`git add -A`,不要求工作区整体干净,也不提交计划外文件。
|
|
20
|
+
- untracked 上下文只接受 `stage=push` 且 Check-All / Update-Spec 证据与当前 workspace fingerprint 一致;不生成任务进度提交。
|
|
20
21
|
|
|
21
22
|
## 模式
|
|
22
23
|
|
|
@@ -24,9 +25,9 @@ description: "按确认的精确文件范围提交普通变更或完成已就绪
|
|
|
24
25
|
| --- | --- | --- | --- |
|
|
25
26
|
| 普通 | 展示最小计划并确认一次 | exact commit;已有 merge 就绪时完成双父提交;然后 push | 有活动任务时立即同步 |
|
|
26
27
|
| 用户 `commit-only` | 展示最小计划并确认一次 | exact local commit | 跳过 |
|
|
27
|
-
| auto-loop 内部 `commit-only` | 复用 auto-loop 预授权 | exact local commit | 跳过 |
|
|
28
|
+
| auto-loop 内部 `commit-only` | 复用 auto-loop 预授权 | exact local commit chain | 由 Auto-Loop runner 写本地 progress;本 skill 跳过 Step 5 |
|
|
28
29
|
|
|
29
|
-
内部 `commit-only`
|
|
30
|
+
内部 `commit-only` 不接受超出当前任务证据、runner owned dirty 和 protected-retained 边界的文件,不执行远端推送或其他附加动作。安全条件不满足时返回失败,由调用方决定后续状态。
|
|
30
31
|
|
|
31
32
|
## Step 0:记录完成链证据
|
|
32
33
|
|
|
@@ -39,6 +40,8 @@ description: "按确认的精确文件范围提交普通变更或完成已就绪
|
|
|
39
40
|
|
|
40
41
|
auto-loop 内部 `commit-only` 已由 runner 的 `run_check_all -> run_spec_update -> commit_only` 状态机和预授权保证顺序,因此不重复记录或判断本交互证据。
|
|
41
42
|
|
|
43
|
+
没有活动 task 时运行 `python3 ./.trellis/scripts/untracked_flow.py status --verbose`。命中 untracked 后,以 helper 返回的 stage、scope、baseline、current fingerprint、Check-All 和 Update-Spec 证据填写上述完成链;必须为 `stage=push` 且证据仍有效。`miss` 才按既有“无活动任务”普通 Git 路径处理;`error` 或 workspace drift 停止,不从摘要猜测。
|
|
44
|
+
|
|
42
45
|
## Step 1:发现仓库与任务
|
|
43
46
|
|
|
44
47
|
候选仓库包括:
|
|
@@ -51,7 +54,7 @@ auto-loop 内部 `commit-only` 已由 runner 的 `run_check_all -> run_spec_upda
|
|
|
51
54
|
|
|
52
55
|
为每个候选仓库生成用户可见名称:优先使用 `.trellis/config.yaml` 中匹配的 package 名;没有配置时使用 Git top-level 目录名。`root`、`parent`、`main repo` 只允许作为输入别名,禁止直接显示在计划或结果中。
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
活动 task 或 untracked work 都是可选上下文:
|
|
55
58
|
|
|
56
59
|
```bash
|
|
57
60
|
python3 ./.trellis/scripts/task.py current --source || true
|
|
@@ -64,7 +67,7 @@ python3 ./.trellis/scripts/task_progress.py status --json || true
|
|
|
64
67
|
git status --short --untracked-files=all -- <task-dir>
|
|
65
68
|
```
|
|
66
69
|
|
|
67
|
-
不得把默认 `git status --short` 可能返回的 `?? <task-dir>/` 折叠目录当成 exact file、展示条目或 pathspec
|
|
70
|
+
不得把默认 `git status --short` 可能返回的 `?? <task-dir>/` 折叠目录当成 exact file、展示条目或 pathspec。无活动 task 时仍可提交相关代码,但不生成任务进度。untracked 命中时,所有业务 `planned` 文件必须能由当前 state scope 与实际 diff 归属,计划同时显示 work id;scope 外文件只能保留或作为归属风险。存在活动 task 时,结合 `brief.md`、`implement.md`、当前 diff 与本轮执行范围生成一行语义进度;同时识别当前任务目录中已存在且可归属的 dirty/untracked 产物,供 Step 5 生成任务记录 exact files。不得从旧进度推断 Git 动作。
|
|
68
71
|
|
|
69
72
|
## Step 2:预检与文件归属
|
|
70
73
|
|
|
@@ -100,12 +103,25 @@ git log @{u}..HEAD --oneline 2>/dev/null || true
|
|
|
100
103
|
|
|
101
104
|
普通模式存在活动任务时,当前任务目录中已存在且可归属的 dirty/untracked 产物不进入业务 `planned`,也不进入 `retained`;它们与预计由 helper 更新的 `<task-dir>/task.json` 组成 Step 5 的任务记录 exact files。其他任务目录和无法归属当前任务的文件仍属于 `retained` 或风险,不得顺带提交。
|
|
102
105
|
|
|
103
|
-
普通 `PUSH`
|
|
106
|
+
普通 `PUSH` 或 auto-loop 内部 `commit-only` 需要在仓库间运行本地生成命令时,计划必须包含命令、工作目录、依赖顺序和后续仓预计 exact files。执行链可包含任意数量的仓库和生成步骤,不硬编码具体仓库、两仓三阶段或命令名称。
|
|
107
|
+
|
|
108
|
+
动态执行链按以下证据优先级生成:
|
|
109
|
+
|
|
110
|
+
1. 当前任务 `design.md` / `implement.md` 明确记录的顺序、命令和路径。
|
|
111
|
+
2. 项目 SOP/spec 中的 canonical、生成和分发约定。
|
|
112
|
+
3. 受版本控制的 `package.json`、Makefile 或仓库脚本入口,以及可确认的输入输出路径。
|
|
113
|
+
4. 可验证的 Git/submodule 父子关系。
|
|
114
|
+
|
|
115
|
+
上述优先级用于发现意图和执行顺序,不允许用文档覆盖当前仓库事实。命令入口、工作目录和输出路径必须由受版本控制内容验证;任务 artifacts、SOP/spec、脚本实际行为或 Git 关系互相冲突时失败关闭。
|
|
116
|
+
|
|
117
|
+
命令必须是受版本控制的稳定入口,并且本地、确定性、可重复、无外部副作用。工作目录和预期影响路径必须可审计;只有名称相似、mtime、目录邻近或惯例不足以执行。禁止任意 shell 字符串、管道、重定向、命令替换、push、release、deploy、archive、凭证和生产数据操作;证据不足时失败关闭。
|
|
104
118
|
|
|
105
119
|
`retained` 只是内部集合名。用户可见输出统一写“保留未提交的变更(dirty)”,并逐项标注 `[untracked]`、`[unstaged]`、`[staged]`。unknown ahead、branch/upstream 异常、归属不确定等真正需要处理的事项单独进入“风险”区;普通 retained dirty 不默认视为阻塞。
|
|
106
120
|
|
|
107
121
|
普通模式允许 `retained` 存在。执行前记录计划外 staged set,提交后确认这些 staged 文件仍保持原状。用户明确要求新增文件时,重新生成计划并确认,不能在执行中静默扩大范围。
|
|
108
122
|
|
|
123
|
+
auto-loop 内部 `commit-only` 也允许 retained dirty 存在,但每个生成/提交步骤前后都必须验证 retained exact paths 的内容摘要不变,并确认它们与 planned/generated paths 不冲突。内部模式仍要求 staged 区为空;计划外 dirty、retained 漂移、未知 staged、无法由当前计划或已记录提交解释的分支/HEAD 漂移,或归属歧义立即停止后续副作用。
|
|
124
|
+
|
|
109
125
|
已有 merge 会提交整个索引,因此 planned 必须覆盖全部 staged paths,`retained` 中不得存在 `[staged]`;未跟踪或未暂存 retained 仍可保留。
|
|
110
126
|
|
|
111
127
|
## Step 3:展示最小计划
|
|
@@ -116,7 +132,7 @@ git log @{u}..HEAD --oneline 2>/dev/null || true
|
|
|
116
132
|
## Trellis Push 计划
|
|
117
133
|
|
|
118
134
|
[<PUSH / PUSH · MERGE / COMMIT-ONLY>] <N> 个仓库 · <N> 个 commit · <N> 个文件 · 保留未提交 <N> · 风险 <N>
|
|
119
|
-
[
|
|
135
|
+
[无活动 task 时追加:无活动任务;untracked 命中时改为 `Untracked work: <work-id>`]
|
|
120
136
|
顺序:<repo-a> [-> `<local generation command>`] -> <repo-b> [-> task progress]
|
|
121
137
|
|
|
122
138
|
### 完成链证据
|
|
@@ -135,7 +151,7 @@ git log @{u}..HEAD --oneline 2>/dev/null || true
|
|
|
135
151
|
|
|
136
152
|
Push:<执行 / 跳过(commit-only)>
|
|
137
153
|
|
|
138
|
-
[
|
|
154
|
+
[生成(多仓需要时显示):前置仓成功后,在 `<working-directory>` 运行 `<exact local command>`;预计只影响 <后续仓 exact files 或分组摘要>]
|
|
139
155
|
|
|
140
156
|
### 保留未提交的变更(dirty,仅数量大于 0 时显示)
|
|
141
157
|
- [untracked] <path>
|
|
@@ -161,19 +177,21 @@ Push:<执行 / 跳过(commit-only)>
|
|
|
161
177
|
- 顶部仓库/commit/file 总数包含独立任务记录提交所在 Git root、该提交及其 exact files;任务记录文件使用相同的 8 文件展示阈值和展开规则。
|
|
162
178
|
- 保留未提交的变更始终逐项标注 Git 状态;真正风险在独立“风险”区逐项展示。
|
|
163
179
|
- 完成链证据始终显示当前状态,但不重复 Check-All 报告或 Spec review 正文;`未运行`、`已失效`、findings、blocked、部分验证或 `needs-review` 同时计入风险区。
|
|
164
|
-
-
|
|
180
|
+
- 无活动 task、untracked 或 `commit-only` 时省略进度动作。
|
|
165
181
|
- 不重复展示检查结果、规范复核、归档或其他阶段的详细信息。
|
|
166
182
|
- 生成前无法确定的内容和增删行写“生成后计算”,不得填预测值。
|
|
167
183
|
|
|
168
184
|
普通多仓只确认一次。计划已展示生成命令和预计 exact files 时,命令成功且没有出现预计列表外的新 dirty path 就沿用原确认;内容、hash 或统计变化不重问。其它计划边界变化仍按 Step 4 重新规划。
|
|
169
185
|
|
|
170
|
-
auto-loop 内部 `commit-only`
|
|
186
|
+
auto-loop 内部 `commit-only` 仍生成同样的逐仓执行数据用于自检和结果记录,但不再次询问用户;它只能在当前任务 artifacts、runner owned dirty 和 protected-retained 边界内形成 exact files/message。
|
|
171
187
|
|
|
172
188
|
## Step 4:精确提交与推送
|
|
173
189
|
|
|
174
|
-
每个仓库按计划顺序执行。执行前重新检查 planned files、当前分支、upstream
|
|
190
|
+
每个仓库按计划顺序执行。执行前重新检查 planned files、当前分支、HEAD、upstream、冲突状态、staged、全部 dirty paths 和 retained 摘要;任一关键条件变化都停止当前执行并重新规划。普通模式仅 `retained` 内容变化时可更新说明;auto-loop 内部模式的 retained 内容必须保持不变。
|
|
191
|
+
|
|
192
|
+
计划包含本地生成命令时,前置仓成功后按计划执行命令,再复用本节现有预检。命令成功、后续仓全部 dirty paths 都在预计 exact files 内且 retained 摘要未漂移时直接继续;否则停止并重新生成计划。预计文件最终 clean 时不强行提交。
|
|
175
193
|
|
|
176
|
-
|
|
194
|
+
auto-loop retry/resume 时,读取调用方提供的已完成仓库提交,逐个验证 repository、commit object、message 和文件集合仍符合当前任务证据,并确认当前分支/HEAD 变化可由这些提交解释。验证通过的提交直接跳过;验证失败立即 blocked,不重复提交。确定性生成入口可以安全重跑,以当前 Git 状态重新规划后续步骤。
|
|
177
195
|
|
|
178
196
|
普通精确提交:
|
|
179
197
|
|
|
@@ -223,9 +241,11 @@ git push origin <current-branch>
|
|
|
223
241
|
|
|
224
242
|
多仓执行失败时停止后续未开始仓库,保留已经成功的提交/推送,不做回滚。
|
|
225
243
|
|
|
244
|
+
auto-loop 内部链失败时向调用方返回全部已完成仓库提交和失败位置。只有确定性生成未收敛或仍可安全重新规划的本地预检使用 `commit-repairable`;计划外 dirty、retained 漂移、未知 staged、无法由当前计划或已记录提交解释的分支/HEAD 漂移、归属歧义和外部副作用风险必须立即 blocked。不得 reset、rebase、revert、amend 或撤销成功提交。
|
|
245
|
+
|
|
226
246
|
## Step 5:同步任务进度
|
|
227
247
|
|
|
228
|
-
|
|
248
|
+
仅普通模式且存在活动 task 时由本 skill 执行。untracked、用户 `commit-only` 与 auto-loop 内部 `commit-only` 都跳过本 Step;Auto-Loop runner 在 action record/next 后按自身契约写入本地 `task.json.progress`,不属于这里的任务进度提交或推送。全部业务仓库成功后写完整进度;已有仓库成功而后续仓库失败时写 partial 进度,明确 completed、失败位置、next 和 notes。尚未发生成功 Git 动作就失败时,不记录虚假的 completed steps;只有父仓仍可安全提交并推送时才允许记录 failure notes。
|
|
229
249
|
|
|
230
250
|
新进度固定为:
|
|
231
251
|
|
|
@@ -268,6 +288,8 @@ git push origin <current-branch>
|
|
|
268
288
|
|
|
269
289
|
## Step 6:结果
|
|
270
290
|
|
|
291
|
+
untracked 的全部已确认 Git 动作成功后,最后运行 `python3 ./.trellis/scripts/untracked_flow.py clear --reason completed --work-id <work-id>`。清理成功才报告完成链已结束;任一仓库、push 或清理失败都保留状态并报告恢复位置,禁止因部分成功伪造完成。用户 `commit-only` 的已确认动作全部成功时同样可以完成并清理。
|
|
292
|
+
|
|
271
293
|
结果复用计划的视觉顺序,先给总览,再逐仓报告实际 commit/push,最后报告任务进度与保留 dirty:
|
|
272
294
|
|
|
273
295
|
```markdown
|
|
@@ -296,6 +318,8 @@ git push origin <current-branch>
|
|
|
296
318
|
- [staged] <path>
|
|
297
319
|
```
|
|
298
320
|
|
|
321
|
+
untracked 结果用“无任务状态”替代“任务进度”,展示 work id 与 `<已清理/保留待恢复>`;不生成或暗示 task progress commit。
|
|
322
|
+
|
|
299
323
|
部分完成时必须明确列出已成功仓库、失败仓库/步骤、当前分支和下一恢复动作。业务结果与 progress sync 状态不得合并成一个模糊结论。
|
|
300
324
|
|
|
301
325
|
## 禁止事项
|
|
@@ -13,7 +13,7 @@ description: |
|
|
|
13
13
|
|
|
14
14
|
# Trellis 路由器:implement / check 执行模式选择
|
|
15
15
|
|
|
16
|
-
主 agent 进入 Phase 2.1 实现路由或 Phase 2.2 检查路由时调用本 skill
|
|
16
|
+
主 agent 进入 Phase 2.1 实现路由或 Phase 2.2 检查路由时调用本 skill。task 上下文继续使用 task-scoped session route decision;untracked 上下文只读取个人 `.trellis/.route-prefs.tmp`,不读取或写入 `route_decisions`。提交前确实需要最终复查时,回到 Phase 2.2 并按当前 subject 的同一规则解析 route。
|
|
17
17
|
|
|
18
18
|
个人配置只写入 `.trellis/.route-prefs.tmp`。该文件匹配 `.trellis/.gitignore` 的 `*.tmp` 规则,属于开发者本地偏好,不纳入 git,也不影响其他开发者。auto-loop 可在 `.trellis/.runtime/auto-loop/<run-id>.json` 写入临时 route 授权;它不是个人偏好,优先级低于 `.route-prefs.tmp`,只用于减少 auto 模式下的交互打断。
|
|
19
19
|
|
|
@@ -23,9 +23,15 @@ description: |
|
|
|
23
23
|
|
|
24
24
|
## Step 0: 识别目标与用户意图
|
|
25
25
|
|
|
26
|
-
个人 route 配置只决定“已获准执行后的模式”,不是开工授权。调用 helper 前,必须确认当前 workflow 已允许进入对应 target:implement 需要任务已完成规划确认并处于 `in_progress`;
|
|
26
|
+
个人 route 配置只决定“已获准执行后的模式”,不是开工授权。调用 helper 前,必须确认当前 workflow 已允许进入对应 target:task implement 需要任务已完成规划确认并处于 `in_progress`;untracked implement 需要 `untracked_flow.py status` 命中当前 session;check 需要 Phase 2.2 或 untracked `stage=check`。如果仍在 planning、等待用户确认,或用户表达“等一下 / 我再想想”,停止,不读取 runtime/prefs。
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
先用 `task.py current --source` 与 `untracked_flow.py status` 确认 subject,二者只能命中一个:
|
|
29
|
+
|
|
30
|
+
- task 命中:`scope=task`,继续使用本 skill 既有 runtime -> prefs -> auto-loop 顺序。
|
|
31
|
+
- 无 task 且 untracked 命中:`scope=untracked`,只使用 pref-only CLI;不得伪造 task 路径或 task artifacts。
|
|
32
|
+
- 二者都未命中:返回 workflow Request Triage,不展示执行 route。
|
|
33
|
+
|
|
34
|
+
task 的合法 route 决策必须能追溯到 `trellis-route`、同编号 fallback 选项、有效 `.trellis/.route-prefs.tmp`,或 route helper 校验过的 auto-loop 临时授权,并且 `task` 字段等于当前任务路径。untracked 的合法 route 只来自本次紧邻选择或 `read-pref` 命中;不写 runtime,也不接受 auto-loop 授权。用户自然语言、摘要、SessionStart 提示、`codex-mode`、空偏好或历史裸数字都不能单独作为有效 route 决策。
|
|
29
35
|
|
|
30
36
|
当前上下文内已有 target 匹配、task 等于当前任务路径、且来源合法的 route 决策时,后续实现、check 发现问题、用户指出刚检查过的实现有问题、修复后重检、提交前复查均默认复用最近 implement/check 路由;除非用户明确要求重选/临时改/清除默认,不再调用本 skill。当前上下文没有 route 决策但 runtime state 命中时,本 skill 恢复该决策并输出同样的结构化 `route_decision`。如果上下文里只有上一个任务的 `route_decision`,必须忽略并重新解析当前任务。
|
|
31
37
|
|
|
@@ -49,7 +55,7 @@ Codex inline mode 只表示主会话默认直接执行,不是 route 选项过
|
|
|
49
55
|
|
|
50
56
|
## Step 0.5: 解析已有 route state
|
|
51
57
|
|
|
52
|
-
仅在没有覆盖意图、当前上下文没有 target + 当前 task 匹配的合法 `route_decision` 时调用
|
|
58
|
+
task 仅在没有覆盖意图、当前上下文没有 target + 当前 task 匹配的合法 `route_decision` 时调用 `resolve`,解析顺序固定为 runtime -> prefs -> auto-loop。untracked 不调用 `resolve`,每次直接调用 `read-pref`;命中即可执行,miss 才进入 Step 2。
|
|
53
59
|
|
|
54
60
|
调用随本 skill 分发的 helper;不要在对话中内嵌或改写 helper 逻辑:
|
|
55
61
|
|
|
@@ -59,6 +65,14 @@ python3 .agents/skills/trellis-route/scripts/route_state.py resolve --target <im
|
|
|
59
65
|
python3 .claude/skills/trellis-route/scripts/route_state.py resolve --target <implement|check>
|
|
60
66
|
```
|
|
61
67
|
|
|
68
|
+
untracked 调用:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
python3 .agents/skills/trellis-route/scripts/route_state.py read-pref --target <implement|check>
|
|
72
|
+
# Claude 平台若只有 .claude skill 副本,则使用:
|
|
73
|
+
python3 .claude/skills/trellis-route/scripts/route_state.py read-pref --target <implement|check>
|
|
74
|
+
```
|
|
75
|
+
|
|
62
76
|
helper 只接受当前 session 或唯一 session fallback 的 `.trellis/.runtime/sessions/<context-key>.json`,并只从 `route_decisions.<target>` 恢复当前任务的决策。命中时输出 `{"status":"hit", ...}`,其中默认输出里的 `task` / `mode` / `source` 已经过 task/target/source/mode/scope 校验,可跳过 Step 2 并进入 Step 3 输出决策。`origin=route-prefs` 表示来自个人 route 配置,并且 helper 已写回 session runtime state;`origin=auto-loop` 表示来自 auto-loop 临时授权且 helper 已写回 session runtime state;`origin=runtime` 表示来自 session runtime state。
|
|
63
77
|
|
|
64
78
|
helper 默认输出为精简 JSON,只包含 route 执行必需的 `status`、`origin`、`mode`、`source`/`reason` 等字段。需要排查完整 `decision`、session 文件、context key、任务路径、个人配置路径或写回标记时,在同一命令末尾加 `--verbose`;不要为了诊断信息额外读取 runtime 文件。
|
|
@@ -137,7 +151,7 @@ fi
|
|
|
137
151
|
|
|
138
152
|
## Step 2.6: 写入 route state / 默认配置
|
|
139
153
|
|
|
140
|
-
用户选择本次模式后,调用 helper 写入当前 session runtime。选项含“保存默认”或“更新默认”时,加 `--save-pref
|
|
154
|
+
task 用户选择本次模式后,调用 helper 写入当前 session runtime。选项含“保存默认”或“更新默认”时,加 `--save-pref`。untracked 的“仅本次”只用于当前调用,不写任何 runtime 或偏好;“保存默认/更新默认”只调用 `write-pref`。
|
|
141
155
|
|
|
142
156
|
只影响本次:
|
|
143
157
|
|
|
@@ -155,6 +169,14 @@ python3 .agents/skills/trellis-route/scripts/route_state.py write --target <impl
|
|
|
155
169
|
python3 .claude/skills/trellis-route/scripts/route_state.py write --target <implement|check> --mode <mode> --source <trellis-route|numbered-fallback> --save-pref
|
|
156
170
|
```
|
|
157
171
|
|
|
172
|
+
untracked 保存 / 更新默认:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
python3 .agents/skills/trellis-route/scripts/route_state.py write-pref --target <implement|check> --mode <mode>
|
|
176
|
+
# Claude 平台若只有 .claude skill 副本,则使用:
|
|
177
|
+
python3 .claude/skills/trellis-route/scripts/route_state.py write-pref --target <implement|check> --mode <mode>
|
|
178
|
+
```
|
|
179
|
+
|
|
158
180
|
清除默认:
|
|
159
181
|
|
|
160
182
|
```bash
|
|
@@ -177,13 +199,17 @@ helper 写入规则:保留另一个 target 的 runtime 决策和偏好;覆
|
|
|
177
199
|
|
|
178
200
|
| 路由决定 | 主 agent 应执行 |
|
|
179
201
|
|---------|----------------|
|
|
180
|
-
| `inline implement` | `Skill({skill: "trellis-before-dev"})` 加载 spec
|
|
181
|
-
| `subagent implement` | `Agent({subagent_type: "trellis-implement"})
|
|
202
|
+
| `inline implement` | `Skill({skill: "trellis-before-dev"})` 加载 spec;task 再读任务文档,untracked 读取 helper 状态与实际 scope → 主线程实施 → 跑必要验证 → 回到 Phase 2.1 completion contract |
|
|
203
|
+
| `subagent implement` | `Agent({subagent_type: "trellis-implement"})`;task 使用 `Active task:`,untracked 使用下方自包含 `Untracked work:` 契约;主 agent 收到结果后回到 Phase 2.1 completion contract |
|
|
182
204
|
| `inline check-all` | `Skill({skill: "trellis-check-all"})` |
|
|
183
205
|
| `subagent check-all` | 优先使用明确 audit-only 的 `trellis-check-all` agent;不存在时使用平台通用 subagent,并用下方 dispatch 契约执行本地 `trellis-check-all`。subagent 只返回 `DOC-*` 文档漂移候选,不写文件;主会话负责允许的文档自修。禁止 fallback 到会直接修改工作区的 `trellis-check` agent;无兼容 subagent 时停止并请用户改选 inline |
|
|
184
206
|
|
|
185
207
|
implement 路由只决定执行位置,不拥有实现后的停止策略。无论 inline 或 subagent,focused validation 完成后都必须返回 workflow Phase 2.1 的 completion contract;由该 owner 处理 auto-loop、用户显式继续/暂缓、已有 hold 和默认立即 Check-All 的优先级。
|
|
186
208
|
|
|
209
|
+
### Untracked Subagent Dispatch 契约
|
|
210
|
+
|
|
211
|
+
untracked 的 implement/check subagent prompt 第一行固定为 `Untracked work: <work-id>`,并包含事项摘要、stage、scope、baseline 仓库摘要、current fingerprint、已有验证证据、相关 spec 路径和本轮明确职责。不得写 `Active task:`,不得要求 `prd.md`、`implement.jsonl` 或 `check.jsonl`。agent 必须直接执行,不得递归 dispatch implement/check agent。
|
|
212
|
+
|
|
187
213
|
### Subagent Check-All Dispatch 契约
|
|
188
214
|
|
|
189
215
|
使用专用或通用 subagent 时,dispatch prompt 第一行必须是当前任务路径,并包含以下完整边界:
|
|
@@ -219,8 +245,9 @@ route_decision:
|
|
|
219
245
|
target: <implement | check>
|
|
220
246
|
mode: <inline | subagent | check-all-inline | check-all-subagent>
|
|
221
247
|
source: <trellis-route | route-prefs | auto-loop | numbered-fallback>
|
|
222
|
-
scope: task
|
|
223
|
-
task: <current task path>
|
|
248
|
+
scope: <task | untracked>
|
|
249
|
+
task: <current task path; task only>
|
|
250
|
+
work_id: <current untracked work id; untracked only>
|
|
224
251
|
|
|
225
252
|
接下来主 agent 应当:
|
|
226
253
|
- <路由表里对应的工具调用形式>
|
|
@@ -317,7 +317,20 @@ def _write_prefs(repo_root: Path, prefs: dict[str, str]) -> None:
|
|
|
317
317
|
if value:
|
|
318
318
|
lines.append(f"{target}={value}")
|
|
319
319
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
320
|
-
|
|
320
|
+
fd, temp_name = tempfile.mkstemp(prefix=f".{path.name}.", suffix=".tmp", dir=path.parent)
|
|
321
|
+
temp_path = Path(temp_name)
|
|
322
|
+
try:
|
|
323
|
+
with os.fdopen(fd, "w", encoding="utf-8") as handle:
|
|
324
|
+
handle.write("\n".join(lines) + "\n")
|
|
325
|
+
handle.flush()
|
|
326
|
+
os.fsync(handle.fileno())
|
|
327
|
+
os.replace(temp_path, path)
|
|
328
|
+
except Exception:
|
|
329
|
+
try:
|
|
330
|
+
temp_path.unlink()
|
|
331
|
+
except FileNotFoundError:
|
|
332
|
+
pass
|
|
333
|
+
raise
|
|
321
334
|
|
|
322
335
|
|
|
323
336
|
def _normalized_decision(decision: Any, target: str, current_task: str) -> dict[str, Any] | None:
|
|
@@ -643,6 +656,74 @@ def write_route(args: argparse.Namespace) -> int:
|
|
|
643
656
|
)
|
|
644
657
|
|
|
645
658
|
|
|
659
|
+
def read_pref(args: argparse.Namespace) -> int:
|
|
660
|
+
"""读取不依赖任务或 session 的个人 route 偏好。
|
|
661
|
+
|
|
662
|
+
Args:
|
|
663
|
+
args: 包含 target 和 verbose 的命令行参数。
|
|
664
|
+
|
|
665
|
+
Returns:
|
|
666
|
+
命令退出码。
|
|
667
|
+
"""
|
|
668
|
+
repo_root = _repo_root()
|
|
669
|
+
if repo_root is None:
|
|
670
|
+
return _print({"status": "miss", "reason": "not-trellis-project"})
|
|
671
|
+
mode = _read_prefs(repo_root).get(args.target)
|
|
672
|
+
if mode not in PREF_MODES[args.target]:
|
|
673
|
+
return _output(
|
|
674
|
+
args,
|
|
675
|
+
{"status": "miss", "reason": "no-valid-pref", "target": args.target},
|
|
676
|
+
{"pref_path": _rel_path(repo_root, _pref_path(repo_root))},
|
|
677
|
+
)
|
|
678
|
+
return _output(
|
|
679
|
+
args,
|
|
680
|
+
{
|
|
681
|
+
"status": "hit",
|
|
682
|
+
"target": args.target,
|
|
683
|
+
"mode": mode,
|
|
684
|
+
"source": "route-prefs",
|
|
685
|
+
},
|
|
686
|
+
{"pref_path": _rel_path(repo_root, _pref_path(repo_root))},
|
|
687
|
+
)
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
def write_pref(args: argparse.Namespace) -> int:
|
|
691
|
+
"""写入不依赖任务或 session 的个人 route 偏好。
|
|
692
|
+
|
|
693
|
+
Args:
|
|
694
|
+
args: 包含 target、mode 和 verbose 的命令行参数。
|
|
695
|
+
|
|
696
|
+
Returns:
|
|
697
|
+
命令退出码。
|
|
698
|
+
"""
|
|
699
|
+
mode = _normalize_mode(args.target, args.mode)
|
|
700
|
+
if mode not in PREF_MODES[args.target]:
|
|
701
|
+
return _print(
|
|
702
|
+
{
|
|
703
|
+
"status": "error",
|
|
704
|
+
"reason": "invalid-mode",
|
|
705
|
+
"target": args.target,
|
|
706
|
+
"mode": args.mode,
|
|
707
|
+
}
|
|
708
|
+
)
|
|
709
|
+
repo_root = _repo_root()
|
|
710
|
+
if repo_root is None:
|
|
711
|
+
return _print({"status": "skipped", "reason": "not-trellis-project"})
|
|
712
|
+
prefs = _read_prefs(repo_root)
|
|
713
|
+
prefs[args.target] = mode
|
|
714
|
+
_write_prefs(repo_root, prefs)
|
|
715
|
+
return _output(
|
|
716
|
+
args,
|
|
717
|
+
{
|
|
718
|
+
"status": "written",
|
|
719
|
+
"target": args.target,
|
|
720
|
+
"mode": mode,
|
|
721
|
+
"source": "route-prefs",
|
|
722
|
+
},
|
|
723
|
+
{"pref_path": _rel_path(repo_root, _pref_path(repo_root))},
|
|
724
|
+
)
|
|
725
|
+
|
|
726
|
+
|
|
646
727
|
def clear_pref(args: argparse.Namespace) -> int:
|
|
647
728
|
"""清除当前 target 的个人默认 route 配置。"""
|
|
648
729
|
repo_root = _repo_root()
|
|
@@ -688,6 +769,17 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
688
769
|
write_parser.add_argument("--verbose", action="store_true", help="include diagnostic paths and session metadata")
|
|
689
770
|
write_parser.set_defaults(func=write_route)
|
|
690
771
|
|
|
772
|
+
read_pref_parser = subparsers.add_parser("read-pref", help="read a personal route preference")
|
|
773
|
+
read_pref_parser.add_argument("--target", choices=sorted(PREF_MODES), required=True)
|
|
774
|
+
read_pref_parser.add_argument("--verbose", action="store_true", help="include preference path metadata")
|
|
775
|
+
read_pref_parser.set_defaults(func=read_pref)
|
|
776
|
+
|
|
777
|
+
write_pref_parser = subparsers.add_parser("write-pref", help="write a personal route preference")
|
|
778
|
+
write_pref_parser.add_argument("--target", choices=sorted(PREF_MODES), required=True)
|
|
779
|
+
write_pref_parser.add_argument("--mode", required=True)
|
|
780
|
+
write_pref_parser.add_argument("--verbose", action="store_true", help="include preference path metadata")
|
|
781
|
+
write_pref_parser.set_defaults(func=write_pref)
|
|
782
|
+
|
|
691
783
|
clear_parser = subparsers.add_parser("clear-pref", help="clear a personal route preference")
|
|
692
784
|
clear_parser.add_argument("--target", choices=sorted(PREF_MODES), required=True)
|
|
693
785
|
clear_parser.add_argument("--verbose", action="store_true", help="include diagnostic paths and preference metadata")
|