flower-trellis 0.6.0-beta.2 → 0.6.0-beta.4
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 +17 -6
- package/enhancements/0.6/.agents/skills/trellis-check-all/references/document-drift-auto-remediation.md +7 -3
- package/enhancements/0.6/.agents/skills/trellis-worktree/SKILL.md +56 -0
- package/enhancements/0.6/.claude/skills/trellis-check-all/references/document-drift-auto-remediation.md +7 -3
- package/enhancements/0.6/.claude/skills/trellis-worktree/SKILL.md +56 -0
- package/enhancements/0.6/overrides/conflicts.json +7 -1
- package/enhancements/0.6/overrides/patches/hooks/inject-workflow-state/shared-runtime/patch.json +19 -0
- package/enhancements/0.6/overrides/patches/hooks/inject-workflow-state/shared-runtime/worktree-root-content.py +70 -0
- package/enhancements/0.6/overrides/patches/hooks/inject-workflow-state/shared-runtime/worktree-root-selector.py +12 -0
- package/enhancements/0.6/overrides/patches/workflow/intent-routing/request-triage/content.md +1 -0
- package/enhancements/0.6/overrides/patches/workflow/state-no-task/content.md +2 -1
- package/enhancements/0.6/overrides/patches/workflow/state-untracked/content.md +1 -1
- package/enhancements/0.6/scripts/untracked_flow.py +154 -6
- package/enhancements/0.6/scripts/worktree_setup.py +422 -0
- package/enhancements/MANIFEST.json +10 -5
- package/enhancements/common/.common/.claude/skills/humanize-writing/SKILL.md +140 -16
- package/enhancements/common/.common/.codex/skills/humanize-writing/SKILL.md +140 -16
- package/package.json +3 -3
- package/src/assets/flower_update_hook.py +13 -4
- package/src/cli.js +4 -2
- package/src/commands/self-check.js +1 -0
- package/src/commands/update-check.js +87 -1
- package/src/lib/manifest.js +24 -2
- package/src/lib/self-check.js +209 -7
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ flower-trellis -v
|
|
|
86
86
|
| `update` | 升级 Trellis,并按新版本重新叠加强化包 |
|
|
87
87
|
| `self-check` | 输出启动更新检查 JSON,供 Codex / Claude Code hook 和 AI 自动化读取 |
|
|
88
88
|
| `self-update` | 受控升级 flower-trellis 并对目标项目执行完整 `flower-trellis update` 重叠加 |
|
|
89
|
-
| `update-check` | 管理 `.
|
|
89
|
+
| `update-check` | 管理 `.flower/settings.json` 内的启动更新策略和提示节流 |
|
|
90
90
|
| `telemetry` | 查询、启用或停用用户级匿名安装遥测 |
|
|
91
91
|
| `plugin` | 管理 Flower Plugin、Marketplace 来源、GitLab 授权和作者校验 |
|
|
92
92
|
| `uninstall` | 移除 Trellis 本体并清理强化包残留(支持 `-y` / `--dry-run`) |
|
|
@@ -204,16 +204,17 @@ flower-trellis plugin add flower/flower-plugin-author --platform codex --json
|
|
|
204
204
|
flower-trellis self-check --json --target .
|
|
205
205
|
```
|
|
206
206
|
|
|
207
|
-
发现可更新或项目已铺版本不一致时,向 AI 注入 `<flower-update>` 上下文。无更新、离线、关闭检查、npx
|
|
207
|
+
发现可更新或项目已铺版本不一致时,向 AI 注入 `<flower-update>` 上下文。无更新、离线、关闭检查、npx 临时运行时默认不打扰;同一更新提示会按本机提示节流状态降噪。
|
|
208
208
|
|
|
209
209
|
检查分两层:
|
|
210
210
|
|
|
211
|
-
- **本地一致性检查**:每次启动都会比对当前安装的 `flower-trellis` / 捆绑 Trellis 版本与项目 `.trellis/.flower-manifest.json` / `.trellis/.version`;不受 `intervalHours` 限制。
|
|
211
|
+
- **本地一致性检查**:每次启动都会比对当前安装的 `flower-trellis` / 捆绑 Trellis 版本与项目 `.flower/plugin-lock.json` / `.trellis/.flower-manifest.json` / `.trellis/.version`;不受 `intervalHours` 限制。
|
|
212
212
|
- **远程版本探测**:访问 npm registry 读取 `flower-trellis` dist-tags;受 `intervalHours` 节流,带超时,失败静默。
|
|
213
|
+
- **提示节流**:同一更新提示默认 24 小时内只注入一次;用户选择稍后时默认 7 天不再提示,选择跳过时同一版本不再提示。
|
|
213
214
|
|
|
214
|
-
策略保存在 `.
|
|
215
|
+
策略保存在 `.flower/settings.json` 的 `updateCheck`;运行缓存保存在 gitignored 的 `.flower/update-check.tmp`,避免 `lastCheckedAt` / `lastPromptedAt` 等字段反复污染 git。旧 `.trellis/.flower-manifest.json` 和 `.trellis/.flower-update-check.tmp` 只作为兼容 fallback 读取。
|
|
215
216
|
|
|
216
|
-
|
|
217
|
+
settings 中只保留用户策略:
|
|
217
218
|
|
|
218
219
|
```json
|
|
219
220
|
{
|
|
@@ -231,8 +232,14 @@ tmp 中保存本地运行缓存:
|
|
|
231
232
|
{
|
|
232
233
|
"lastCheckedAt": "2026-07-07T00:00:00.000Z",
|
|
233
234
|
"lastRemote": { "latest": "0.4.2", "beta": null },
|
|
235
|
+
"lastReleaseNotes": null,
|
|
234
236
|
"lastStatus": "update_available",
|
|
235
|
-
"lastErrorCode": null
|
|
237
|
+
"lastErrorCode": null,
|
|
238
|
+
"lastPromptedAt": "2026-07-07T00:05:00.000Z",
|
|
239
|
+
"lastPromptedKey": "update:latest:0.4.2",
|
|
240
|
+
"promptSuppressedUntil": null,
|
|
241
|
+
"promptSuppressedKey": null,
|
|
242
|
+
"promptSuppressionReason": null
|
|
236
243
|
}
|
|
237
244
|
```
|
|
238
245
|
|
|
@@ -254,6 +261,10 @@ flower-trellis update-check get --target .
|
|
|
254
261
|
flower-trellis update-check set --policy auto --interval-hours 12 --target .
|
|
255
262
|
flower-trellis update-check disable --target . # 只设置 enabled=false,不改 policy
|
|
256
263
|
flower-trellis update-check enable --target . # 只设置 enabled=true,沿用原 policy
|
|
264
|
+
flower-trellis update-check snooze --target . # 延后当前提示,默认 7 天
|
|
265
|
+
flower-trellis update-check snooze --days 3 --target .
|
|
266
|
+
flower-trellis update-check skip --target . # 跳过当前提示 key
|
|
267
|
+
flower-trellis update-check reset --target . # 清空提示节流状态
|
|
257
268
|
```
|
|
258
269
|
|
|
259
270
|
执行更新:
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
| 字段 | 规则 |
|
|
12
12
|
| --- | --- |
|
|
13
13
|
| ID | 首次记录时依次分配 `DOC-001`、`DOC-002` |
|
|
14
|
-
| 类型 | `task-status`、`brief-stale`、`implementation-note`、`check-record`、`mechanical-link` |
|
|
15
|
-
| 文件 |
|
|
14
|
+
| 类型 | `task-status`、`brief-stale`、`implementation-note`、`check-record`、`mechanical-link`、`fact-status` |
|
|
15
|
+
| 文件 | 需要修改的任务、规范、项目文档或本地上下文摘要路径 |
|
|
16
16
|
| 漂移 | 当前文档与实际 diff / 任务状态不一致的事实 |
|
|
17
17
|
| 证据 | `file:line`、命令输出或实际 diff 摘要 |
|
|
18
18
|
| 修复 | 精确说明要写入、更新或删除的内容 |
|
|
@@ -26,10 +26,12 @@
|
|
|
26
26
|
|
|
27
27
|
满足以下全部条件才可自动修复:
|
|
28
28
|
|
|
29
|
-
- 目标是任务执行文档、brief、check
|
|
29
|
+
- 目标是任务执行文档、brief、check 记录、实现进度记录、机械链接、明显过期的本地上下文摘要,或项目文档中仅记录已验证事实状态的片段;
|
|
30
30
|
- 修复内容可由实际 diff、任务状态、命令输出或已存在任务材料唯一推出;
|
|
31
31
|
- 不新增需求、不改变验收标准、不改变设计取舍、不替用户选择产品语义;
|
|
32
32
|
- 不修改源码、配置、测试、迁移、生产数据或外部系统;
|
|
33
|
+
- 可自动修复性由具体片段语义决定,不由文档类别决定;同一文档中只有可由证据唯一推出的事实状态片段可改;
|
|
34
|
+
- 事实状态修复只允许同步状态、URL、版本号、配置键、命令结果、验证结论或时间点,不改操作步骤、责任边界、安全提示、协议字段或对外承诺;
|
|
33
35
|
- 改动小且可通过重读文件或简单静态检查验证;
|
|
34
36
|
- 用户没有明确要求本轮绝对只读。
|
|
35
37
|
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
- `implement.md` 中机械状态仍写“待完成”,但对应步骤已经落地且无语义争议;
|
|
40
42
|
- `check.jsonl` 或任务记录中的文件路径、命令名、链接因重命名出现机械漂移;
|
|
41
43
|
- 文档写的检查深度、route 或状态与 runner / task.py 的确定性状态不一致。
|
|
44
|
+
- 任意 Markdown / HTML / 运行手册 / 接入说明仍写“待发布 / 待回读 / 旧版本 / 旧地址”,但已读取的发布记录、环境回读、测试输出或实际 diff 唯一证明目标状态已经变化。
|
|
42
45
|
|
|
43
46
|
---
|
|
44
47
|
|
|
@@ -51,6 +54,7 @@
|
|
|
51
54
|
- 实现与规划冲突,无法判断是代码错还是文档错;
|
|
52
55
|
- 需要新增测试、改代码、改配置、改迁移或调用外部系统;
|
|
53
56
|
- 证据来自推测、聊天摘要或未读取的文件;
|
|
57
|
+
- 文档修复需要改写用户可见操作路径、接口协议、权限/安全边界、上线承诺、责任归属或验收口径;
|
|
54
58
|
- 修改会扩大任务范围或影响发布、权限、数据安全、生产行为。
|
|
55
59
|
|
|
56
60
|
---
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: trellis-worktree
|
|
3
|
+
description: "Prepare and diagnose Trellis usage inside linked Git worktrees. Use when the user mentions worktree, linked worktree, worktree development, missing .trellis in a worktree, or asks to make .claude/.codex/.agents/Trellis files work from a worktree."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Trellis Worktree
|
|
7
|
+
|
|
8
|
+
Use this skill before normal Trellis routing when the user's current request is about using Trellis from a linked Git worktree.
|
|
9
|
+
|
|
10
|
+
The problem is usually not task or untracked routing itself: linked worktrees often do not contain the untracked `.trellis`, `.agents`, `.codex`, or `.claude` directories that AI tools need before any Trellis hook or skill can run.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Identify the target worktree. Use the user's explicit path if present; otherwise use the current working directory.
|
|
15
|
+
2. Locate a source worktree in the same Git worktree set that contains `.trellis/scripts/worktree_setup.py`.
|
|
16
|
+
3. Run read-only diagnosis first:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
python3 <source-worktree>/.trellis/scripts/worktree_setup.py status --target <target-worktree> --json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
4. If status is `needs-prepare`, run:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
python3 <source-worktree>/.trellis/scripts/worktree_setup.py prepare --target <target-worktree> --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
5. If status is `blocked` or `error`, stop and report the reason and conflict paths. Do not overwrite or delete user files.
|
|
29
|
+
6. After `ready` or `prepared`, return to the user's original Trellis intent and follow the normal workflow state.
|
|
30
|
+
|
|
31
|
+
## Source Worktree Discovery
|
|
32
|
+
|
|
33
|
+
If `<source-worktree>` is not obvious, inspect Git worktrees:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git -C <target-worktree> worktree list --porcelain
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Choose a listed worktree that contains `.trellis/scripts/worktree_setup.py`. If none exists, report that this project has not been updated with `trellis-worktree` support yet.
|
|
40
|
+
|
|
41
|
+
## Safety Rules
|
|
42
|
+
|
|
43
|
+
- The helper only projects source paths that already exist.
|
|
44
|
+
- MVP projection paths are `.trellis`, `.agents`, `.codex`, and `.claude`.
|
|
45
|
+
- Projection uses symlinks and records `<target-worktree>/.trellis-worktree.json`.
|
|
46
|
+
- Existing non-managed `.codex`, `.claude`, `.agents`, or `.trellis` paths are conflicts.
|
|
47
|
+
- Do not hand-copy platform directories. Copying creates drift between worktrees.
|
|
48
|
+
- Do not treat successful setup as task approval, check approval, or push approval.
|
|
49
|
+
|
|
50
|
+
## Expected Results
|
|
51
|
+
|
|
52
|
+
- `ready`: target worktree already has valid Trellis entry points.
|
|
53
|
+
- `needs-prepare`: target worktree is safe to prepare; run `prepare`.
|
|
54
|
+
- `prepared`: symlinks and manifest were created or repaired.
|
|
55
|
+
- `blocked`: user-owned paths would be overwritten; stop and report `conflicts`.
|
|
56
|
+
- `error`: Git or source-root resolution failed; stop and report `reason`.
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
| 字段 | 规则 |
|
|
12
12
|
| --- | --- |
|
|
13
13
|
| ID | 首次记录时依次分配 `DOC-001`、`DOC-002` |
|
|
14
|
-
| 类型 | `task-status`、`brief-stale`、`implementation-note`、`check-record`、`mechanical-link` |
|
|
15
|
-
| 文件 |
|
|
14
|
+
| 类型 | `task-status`、`brief-stale`、`implementation-note`、`check-record`、`mechanical-link`、`fact-status` |
|
|
15
|
+
| 文件 | 需要修改的任务、规范、项目文档或本地上下文摘要路径 |
|
|
16
16
|
| 漂移 | 当前文档与实际 diff / 任务状态不一致的事实 |
|
|
17
17
|
| 证据 | `file:line`、命令输出或实际 diff 摘要 |
|
|
18
18
|
| 修复 | 精确说明要写入、更新或删除的内容 |
|
|
@@ -26,10 +26,12 @@
|
|
|
26
26
|
|
|
27
27
|
满足以下全部条件才可自动修复:
|
|
28
28
|
|
|
29
|
-
- 目标是任务执行文档、brief、check
|
|
29
|
+
- 目标是任务执行文档、brief、check 记录、实现进度记录、机械链接、明显过期的本地上下文摘要,或项目文档中仅记录已验证事实状态的片段;
|
|
30
30
|
- 修复内容可由实际 diff、任务状态、命令输出或已存在任务材料唯一推出;
|
|
31
31
|
- 不新增需求、不改变验收标准、不改变设计取舍、不替用户选择产品语义;
|
|
32
32
|
- 不修改源码、配置、测试、迁移、生产数据或外部系统;
|
|
33
|
+
- 可自动修复性由具体片段语义决定,不由文档类别决定;同一文档中只有可由证据唯一推出的事实状态片段可改;
|
|
34
|
+
- 事实状态修复只允许同步状态、URL、版本号、配置键、命令结果、验证结论或时间点,不改操作步骤、责任边界、安全提示、协议字段或对外承诺;
|
|
33
35
|
- 改动小且可通过重读文件或简单静态检查验证;
|
|
34
36
|
- 用户没有明确要求本轮绝对只读。
|
|
35
37
|
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
- `implement.md` 中机械状态仍写“待完成”,但对应步骤已经落地且无语义争议;
|
|
40
42
|
- `check.jsonl` 或任务记录中的文件路径、命令名、链接因重命名出现机械漂移;
|
|
41
43
|
- 文档写的检查深度、route 或状态与 runner / task.py 的确定性状态不一致。
|
|
44
|
+
- 任意 Markdown / HTML / 运行手册 / 接入说明仍写“待发布 / 待回读 / 旧版本 / 旧地址”,但已读取的发布记录、环境回读、测试输出或实际 diff 唯一证明目标状态已经变化。
|
|
42
45
|
|
|
43
46
|
---
|
|
44
47
|
|
|
@@ -51,6 +54,7 @@
|
|
|
51
54
|
- 实现与规划冲突,无法判断是代码错还是文档错;
|
|
52
55
|
- 需要新增测试、改代码、改配置、改迁移或调用外部系统;
|
|
53
56
|
- 证据来自推测、聊天摘要或未读取的文件;
|
|
57
|
+
- 文档修复需要改写用户可见操作路径、接口协议、权限/安全边界、上线承诺、责任归属或验收口径;
|
|
54
58
|
- 修改会扩大任务范围或影响发布、权限、数据安全、生产行为。
|
|
55
59
|
|
|
56
60
|
---
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: trellis-worktree
|
|
3
|
+
description: "Prepare and diagnose Trellis usage inside linked Git worktrees. Use when the user mentions worktree, linked worktree, worktree development, missing .trellis in a worktree, or asks to make .claude/.codex/.agents/Trellis files work from a worktree."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Trellis Worktree
|
|
7
|
+
|
|
8
|
+
Use this skill before normal Trellis routing when the user's current request is about using Trellis from a linked Git worktree.
|
|
9
|
+
|
|
10
|
+
The problem is usually not task or untracked routing itself: linked worktrees often do not contain the untracked `.trellis`, `.agents`, `.codex`, or `.claude` directories that AI tools need before any Trellis hook or skill can run.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Identify the target worktree. Use the user's explicit path if present; otherwise use the current working directory.
|
|
15
|
+
2. Locate a source worktree in the same Git worktree set that contains `.trellis/scripts/worktree_setup.py`.
|
|
16
|
+
3. Run read-only diagnosis first:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
python3 <source-worktree>/.trellis/scripts/worktree_setup.py status --target <target-worktree> --json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
4. If status is `needs-prepare`, run:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
python3 <source-worktree>/.trellis/scripts/worktree_setup.py prepare --target <target-worktree> --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
5. If status is `blocked` or `error`, stop and report the reason and conflict paths. Do not overwrite or delete user files.
|
|
29
|
+
6. After `ready` or `prepared`, return to the user's original Trellis intent and follow the normal workflow state.
|
|
30
|
+
|
|
31
|
+
## Source Worktree Discovery
|
|
32
|
+
|
|
33
|
+
If `<source-worktree>` is not obvious, inspect Git worktrees:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git -C <target-worktree> worktree list --porcelain
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Choose a listed worktree that contains `.trellis/scripts/worktree_setup.py`. If none exists, report that this project has not been updated with `trellis-worktree` support yet.
|
|
40
|
+
|
|
41
|
+
## Safety Rules
|
|
42
|
+
|
|
43
|
+
- The helper only projects source paths that already exist.
|
|
44
|
+
- MVP projection paths are `.trellis`, `.agents`, `.codex`, and `.claude`.
|
|
45
|
+
- Projection uses symlinks and records `<target-worktree>/.trellis-worktree.json`.
|
|
46
|
+
- Existing non-managed `.codex`, `.claude`, `.agents`, or `.trellis` paths are conflicts.
|
|
47
|
+
- Do not hand-copy platform directories. Copying creates drift between worktrees.
|
|
48
|
+
- Do not treat successful setup as task approval, check approval, or push approval.
|
|
49
|
+
|
|
50
|
+
## Expected Results
|
|
51
|
+
|
|
52
|
+
- `ready`: target worktree already has valid Trellis entry points.
|
|
53
|
+
- `needs-prepare`: target worktree is safe to prepare; run `prepare`.
|
|
54
|
+
- `prepared`: symlinks and manifest were created or repaired.
|
|
55
|
+
- `blocked`: user-owned paths would be overwritten; stop and report `conflicts`.
|
|
56
|
+
- `error`: Git or source-root resolution failed; stop and report `reason`.
|
|
@@ -303,6 +303,7 @@
|
|
|
303
303
|
"severity": "error",
|
|
304
304
|
"target": ".codex/hooks/inject-workflow-state.py",
|
|
305
305
|
"whenOperations": [
|
|
306
|
+
"workflow-state-worktree-root-fallback",
|
|
306
307
|
"workflow-state-codex-session-start-guard",
|
|
307
308
|
"workflow-state-stale-task-status",
|
|
308
309
|
"workflow-state-untracked-helper",
|
|
@@ -312,11 +313,13 @@
|
|
|
312
313
|
"assertion": {
|
|
313
314
|
"type": "required-literal",
|
|
314
315
|
"values": [
|
|
316
|
+
"# BEGIN skill-garden patch workflow-state-worktree-root-fallback v0.6",
|
|
315
317
|
"# BEGIN skill-garden patch workflow-state-codex-session-start-guard v0.6",
|
|
316
318
|
"# BEGIN skill-garden patch workflow-state-stale-task-status v0.6",
|
|
317
319
|
"# BEGIN skill-garden patch workflow-state-untracked-helper v0.6",
|
|
318
320
|
"# BEGIN skill-garden patch workflow-state-breadcrumb-subject v0.6",
|
|
319
321
|
"# BEGIN skill-garden patch workflow-state-main-subject-routing v0.6",
|
|
322
|
+
"_find_trellis_root_from_git",
|
|
320
323
|
"DEFAULT_PROMPT_INJECTION_SKIP_KEYWORD = \"no-trellis\"",
|
|
321
324
|
"\"ZCODE_PROJECT_DIR\": \"zcode\"",
|
|
322
325
|
"Normalize `codex.dispatch_mode` from .trellis/config.yaml to \"auto\" or \"inline\"."
|
|
@@ -476,7 +479,10 @@
|
|
|
476
479
|
"type": "required-literal",
|
|
477
480
|
"values": [
|
|
478
481
|
"Only an explicit current-request workflow instruction such as `直接做` / `不要任务` may override automatic `task_plan`.",
|
|
479
|
-
"
|
|
482
|
+
"Use quick direct edit for one-turn small fixes",
|
|
483
|
+
"Use tracked direct edit only when the user explicitly wants no task but still wants later turns to remember the current phase",
|
|
484
|
+
"python3 ./.trellis/scripts/untracked_flow.py begin --summary \"<bounded work summary>\" --source <inferred|user-explicit> --mode tracked-direct-edit",
|
|
485
|
+
"Never create `untracked_flow` for `workflow_action` itself",
|
|
480
486
|
"A same-item hit resumes the existing state",
|
|
481
487
|
"`active-work-conflict` blocks unrelated code writes until the current item is completed, explicitly abandoned, or adopted into a task",
|
|
482
488
|
"Unrelated read-only requests may continue without mutating the state.",
|
package/enhancements/0.6/overrides/patches/hooks/inject-workflow-state/shared-runtime/patch.json
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
"id": "inject-workflow-state-shared-runtime",
|
|
4
4
|
"purpose": "hook_override",
|
|
5
5
|
"operations": [
|
|
6
|
+
{
|
|
7
|
+
"id": "workflow-state-worktree-root-fallback",
|
|
8
|
+
"operation": "replace",
|
|
9
|
+
"targetPolicy": "each-existing",
|
|
10
|
+
"targets": [
|
|
11
|
+
{ "kind": "file", "path": ".codex/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" },
|
|
12
|
+
{ "kind": "file", "path": ".claude/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" },
|
|
13
|
+
{ "kind": "file", "path": ".gemini/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" },
|
|
14
|
+
{ "kind": "file", "path": ".qoder/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" },
|
|
15
|
+
{ "kind": "file", "path": ".github/copilot/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" },
|
|
16
|
+
{ "kind": "file", "path": ".codebuddy/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" },
|
|
17
|
+
{ "kind": "file", "path": ".factory/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" },
|
|
18
|
+
{ "kind": "file", "path": ".kiro/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" },
|
|
19
|
+
{ "kind": "file", "path": ".trae/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" },
|
|
20
|
+
{ "kind": "file", "path": ".zcode/hooks/inject-workflow-state.py", "missing": "skip", "markerStyle": "hash" }
|
|
21
|
+
],
|
|
22
|
+
"selector": { "type": "literal", "source": "worktree-root-selector.py" },
|
|
23
|
+
"content": { "source": "worktree-root-content.py" }
|
|
24
|
+
},
|
|
6
25
|
{
|
|
7
26
|
"id": "workflow-state-codex-session-start-guard",
|
|
8
27
|
"operation": "insert",
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
def _git_output(start: Path, *args: str) -> Optional[str]:
|
|
2
|
+
"""Run a read-only git command for best-effort Trellis root fallback."""
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
result = subprocess.run(
|
|
7
|
+
["git", "-C", str(start), *args],
|
|
8
|
+
check=False,
|
|
9
|
+
stdout=subprocess.PIPE,
|
|
10
|
+
stderr=subprocess.DEVNULL,
|
|
11
|
+
text=True,
|
|
12
|
+
timeout=2,
|
|
13
|
+
)
|
|
14
|
+
except (OSError, subprocess.SubprocessError):
|
|
15
|
+
return None
|
|
16
|
+
if result.returncode != 0:
|
|
17
|
+
return None
|
|
18
|
+
output = result.stdout.strip()
|
|
19
|
+
return output or None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _resolve_git_common_dir(start: Path) -> Optional[Path]:
|
|
23
|
+
"""Return the current repository's common git dir."""
|
|
24
|
+
output = _git_output(start, "rev-parse", "--path-format=absolute", "--git-common-dir")
|
|
25
|
+
if output is None:
|
|
26
|
+
output = _git_output(start, "rev-parse", "--git-common-dir")
|
|
27
|
+
if output is None:
|
|
28
|
+
return None
|
|
29
|
+
common_dir = Path(output)
|
|
30
|
+
if common_dir.is_absolute():
|
|
31
|
+
return common_dir.resolve()
|
|
32
|
+
top_level = _git_output(start, "rev-parse", "--show-toplevel")
|
|
33
|
+
if top_level is None:
|
|
34
|
+
return None
|
|
35
|
+
return (Path(top_level) / common_dir).resolve()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _find_trellis_root_from_git(start: Path) -> Optional[Path]:
|
|
39
|
+
"""Find a sibling worktree that carries .trellis/ for this Git repository."""
|
|
40
|
+
common_dir = _resolve_git_common_dir(start)
|
|
41
|
+
if common_dir is not None:
|
|
42
|
+
candidate = common_dir.parent
|
|
43
|
+
if (candidate / ".trellis").is_dir():
|
|
44
|
+
return candidate
|
|
45
|
+
|
|
46
|
+
output = _git_output(start, "worktree", "list", "--porcelain")
|
|
47
|
+
if output is None:
|
|
48
|
+
return None
|
|
49
|
+
for line in output.splitlines():
|
|
50
|
+
if not line.startswith("worktree "):
|
|
51
|
+
continue
|
|
52
|
+
candidate = Path(line.split(" ", 1)[1]).expanduser().resolve()
|
|
53
|
+
if (candidate / ".trellis").is_dir():
|
|
54
|
+
return candidate
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def find_trellis_root(start: Path) -> Optional[Path]:
|
|
59
|
+
"""Walk up from start, then fall back to the Git worktree carrying .trellis/.
|
|
60
|
+
|
|
61
|
+
Linked worktrees often do not contain the untracked .trellis/ runtime. The
|
|
62
|
+
hook still needs the main worktree's runtime state so direct-edit cursors can
|
|
63
|
+
be resumed from the linked worktree without copying .trellis/.
|
|
64
|
+
"""
|
|
65
|
+
cur = start.resolve()
|
|
66
|
+
while cur != cur.parent:
|
|
67
|
+
if (cur / ".trellis").is_dir():
|
|
68
|
+
return cur
|
|
69
|
+
cur = cur.parent
|
|
70
|
+
return _find_trellis_root_from_git(start.resolve())
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
def find_trellis_root(start: Path) -> Optional[Path]:
|
|
2
|
+
"""Walk up from start to find directory containing .trellis/.
|
|
3
|
+
|
|
4
|
+
Handles CWD drift: subdirectory launches, monorepo packages, etc.
|
|
5
|
+
Returns None if no .trellis/ found (silent no-op).
|
|
6
|
+
"""
|
|
7
|
+
cur = start.resolve()
|
|
8
|
+
while cur != cur.parent:
|
|
9
|
+
if (cur / ".trellis").is_dir():
|
|
10
|
+
return cur
|
|
11
|
+
cur = cur.parent
|
|
12
|
+
return None
|
package/enhancements/0.6/overrides/patches/workflow/intent-routing/request-triage/content.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
- Infer `discuss`, `inspect`, `direct_edit`, `task_plan`, or `workflow_action` from the whole current request, scope, risk, side effects, active-task state, and latest explicit switch. Do not classify from one keyword alone.
|
|
2
2
|
- Treat requests for an opinion, expressions of discomfort, rejected proposals, or questions about how something should change as `discuss`; treat requests to inspect, explain, verify, or locate a cause as `inspect`. Both are read-only unless the current request explicitly authorizes a concrete edit. Selecting a repair does not authorize editing while scope is unknown or permission to skip task planning; inspect first and reclassify from evidence.
|
|
3
3
|
- `direct_edit` requires known, bounded, low-risk, reversible scope, no unresolved design choice, and simple validation. Permission/authentication/data-scope/security, database/migration/release/external effects, or unknown scope remain strong `task_plan` boundaries. Shared contracts, cross-package/layer or multi-entry behavior, configuration, historical regressions, and systematic validation raise the evidence and validation bar, but do not automatically require `task_plan`. An exact rollback or mechanically synchronized known change may remain `direct_edit` or `workflow_action` when its behavior, scope, side effects, and validation are already determined.
|
|
4
|
+
- `direct_edit` has two execution shapes. Use quick direct edit for one-turn small fixes, wording/config tweaks, focused release-note corrections, or other changes that can be edited, validated, and reported without remembering a later phase; do not create `untracked_flow` for those. Use tracked direct edit only when the user explicitly wants no task but still wants later turns to remember the current phase, or when the work is likely to continue across turns with `下一步` / `继续` / check / push handoff.
|
|
4
5
|
- When project-local SOPs or conventions may change the correct action for non-trivial work, build a short query from the request, intended commands, affected files or systems, package/layer, and domain terms; run `python3 ./.trellis/scripts/spec_router.py "<short query describing the intended action>"` once per user intent, workflow phase, or decision boundary and follow its returned `load_strategy` and `action`. Skip discovery for pure Q&A, simple read-only inspection, opening local tools, or trivial edits unless project rules may alter the approach.
|
|
5
6
|
- When an active task exists, apply the Active Task Scope Guard before artifact ownership, task routing, or file edits. New implementation outside the active task title/brief requires a new task, an artifact update before continuing, or an explicit untracked path that does not reuse current progress. `task_intent.py` executes the already-decided safety boundary; it does not decide semantic ownership.
|
|
6
7
|
- High-confidence reversible steps proceed without a mechanical task-creation question. Clear complex implementation intent may create a planning task and enter `trellis-brainstorm`, but never authorizes `task.py start` or implementation. Ask one focused question only when ambiguity changes material side effects or crosses an independent destructive, production, database, credential, external-system, permission, or safety boundary.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
No active task. Infer the current request intent before acting.
|
|
2
2
|
Repair intent alone is not a no-task switch; inspect unknown scope and reclassify before edits. Only an explicit current-request workflow instruction such as `直接做` / `不要任务` may override automatic `task_plan`.
|
|
3
3
|
For non-trivial project work, follow the `Request Triage` Project Knowledge Discovery contract before routing the action. Load a Trellis capability directly only when the user explicitly names it or the request exactly matches that capability; route project-specific workflow actions through the matched SOP instead of keyword-mapping a general release/publish request to `trellis-release`.
|
|
4
|
-
Handle `discuss` and `inspect` silently. For
|
|
4
|
+
Handle `discuss` and `inspect` silently. For quick direct edit, make the bounded edit, run focused validation, and report without creating `untracked_flow`; small wording/config tweaks, release dry-runs, version checks, local SOP steps, and other one-turn fixes stay in this path unless the current request explicitly asks future `下一步` / `继续` / check / push handoff to remember this no-task work. For tracked direct edit, state once that work will use the session-scoped untracked flow, then run `python3 ./.trellis/scripts/untracked_flow.py begin --summary "<bounded work summary>" --source <inferred|user-explicit> --mode tracked-direct-edit`.
|
|
5
|
+
Never create `untracked_flow` for `workflow_action` itself, including release/publish, commit, push, finish-work, task operations, snapshot sync, auto-loop control, or read-only inspection. If a workflow action reveals a separate code/config fix, pause that workflow action, explain the separate fix, and only create tracked direct edit when the user wants later turns to remember that fix's check/spec/push handoff; otherwise keep it as quick direct edit.
|
|
5
6
|
A same-item hit resumes the existing state; `active-work-conflict` blocks unrelated code writes until the current item is completed, explicitly abandoned, or adopted into a task. Unrelated read-only requests may continue without mutating the state. A successful `begin` starts at `stage=implement`; the helper is a workflow cursor and does not gate edits on file scope, Git state, or owner evidence.
|
|
6
7
|
For high-confidence complex implementation, create an auto-routed planning task through `task_intent.py create`, show one non-blocking switch hint, and enter `trellis-brainstorm`. Ask only for material ambiguity or independent safety gates.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[workflow-state:untracked]
|
|
2
2
|
The current-session untracked work item is at `implement`. Run `python3 ./.trellis/scripts/untracked_flow.py status`, then enter Phase 2.1 through `trellis-route(target=implement)` without creating task artifacts or task-scoped route decisions.
|
|
3
|
-
The helper is only a workflow cursor: it does not validate file scope, Git state, focused validation, or owner evidence. After focused validation is complete, run `python3 ./.trellis/scripts/untracked_flow.py advance --stage check` and continue through the normal Phase 2.1 completion contract.
|
|
3
|
+
The helper is only a workflow cursor: it does not validate file scope, Git state, focused validation, or owner evidence. Its `owner` / `remainingOwners` fields are route reminders for `trellis-check-all` -> `trellis-update-spec` -> `trellis-push`, not proof that any owner already ran. After focused validation is complete, run `python3 ./.trellis/scripts/untracked_flow.py advance --stage check` and continue through the normal Phase 2.1 completion contract.
|
|
4
4
|
A different implementation request remains blocked by the single-active-work guard until this item is completed, explicitly abandoned, or adopted through `python3 ./.trellis/scripts/task_intent.py adopt "<title>" --slug <slug>`; adoption continues through planning artifacts, Brief review, and `task.py start`, and never authorizes immediate implementation. Unrelated read-only requests may continue without changing state.
|
|
5
5
|
[/workflow-state:untracked]
|
|
6
6
|
|