cowork-flow 0.0.37 → 0.0.39
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 +27 -14
- package/package.json +1 -1
- package/src/commands/init.js +39 -28
- package/src/commands/sync.js +2 -2
- package/src/lib/asset-plan.js +127 -0
- package/src/lib/copy-template.js +101 -141
- package/src/lib/host-assets.js +231 -0
- package/src/lib/plan-applier.js +329 -0
- package/src/lib/platforms.js +15 -76
- package/src/lib/skill-registry.js +503 -0
- package/template/.claude/agents/cowork-check.md +10 -1
- package/template/.claude/agents/cowork-implement.md +11 -2
- package/template/.claude/hooks/inject-workflow-state.py +51 -254
- package/template/.codex/agents/cowork-check.toml +12 -3
- package/template/.codex/agents/cowork-implement.toml +11 -2
- package/template/.codex/agents/default.toml +3 -2
- package/template/.codex/agents/explorer.toml +3 -2
- package/template/.codex/agents/worker.toml +2 -1
- package/template/.codex/hooks/inject-workflow-state.py +46 -265
- package/template/.cowork-flow/.version +1 -1
- package/template/.cowork-flow/scripts/application/__init__.py +1 -0
- package/template/.cowork-flow/scripts/application/batch_execution.py +743 -0
- package/template/.cowork-flow/scripts/application/runtime_context_service.py +365 -0
- package/template/.cowork-flow/scripts/application/task_archive.py +220 -0
- package/template/.cowork-flow/scripts/application/task_context.py +765 -0
- package/template/.cowork-flow/scripts/application/task_creation.py +201 -0
- package/template/.cowork-flow/scripts/application/task_lifecycle.py +532 -0
- package/template/.cowork-flow/scripts/application/task_tree.py +179 -0
- package/template/.cowork-flow/scripts/commands/doctor.py +78 -57
- package/template/.cowork-flow/scripts/commands/party_mode_v2.py +671 -425
- package/template/.cowork-flow/scripts/commands/subagent.py +38 -26
- package/template/.cowork-flow/scripts/commands/task.py +535 -1953
- package/template/.cowork-flow/scripts/commands/task_archive_commands.py +195 -0
- package/template/.cowork-flow/scripts/commands/task_context_commands.py +240 -0
- package/template/.cowork-flow/scripts/commands/task_create_command.py +164 -0
- package/template/.cowork-flow/scripts/commands/task_navigation.py +407 -0
- package/template/.cowork-flow/scripts/commands/task_parser.py +364 -0
- package/template/.cowork-flow/scripts/commands/task_support.py +76 -0
- package/template/.cowork-flow/scripts/commands/task_tree_commands.py +160 -0
- package/template/.cowork-flow/scripts/common/core/execution_context.py +161 -85
- package/template/.cowork-flow/scripts/common/core/host_manifest.py +393 -0
- package/template/.cowork-flow/scripts/common/core/skill_registry.py +568 -0
- package/template/.cowork-flow/scripts/common/gates/coding_standards.py +58 -7
- package/template/.cowork-flow/scripts/common/gates/gates.py +323 -46
- package/template/.cowork-flow/scripts/common/gates/models.py +196 -0
- package/template/.cowork-flow/scripts/common/gates/registry.py +79 -0
- package/template/.cowork-flow/scripts/common/gates/tdd_evidence.py +13 -13
- package/template/.cowork-flow/scripts/common/gates/validate_coding_standards.py +104 -62
- package/template/.cowork-flow/scripts/common/gates/validate_implementation.py +39 -22
- package/template/.cowork-flow/scripts/common/gates/validate_rules.py +223 -40
- package/template/.cowork-flow/scripts/common/git/git_context.py +216 -182
- package/template/.cowork-flow/scripts/common/host/__init__.py +1 -0
- package/template/.cowork-flow/scripts/common/host/workflow_state_hook.py +303 -0
- package/template/.cowork-flow/scripts/common/storage/__init__.py +1 -0
- package/template/.cowork-flow/scripts/common/storage/operation_log.py +72 -0
- package/template/.cowork-flow/scripts/common/storage/state_store.py +279 -0
- package/template/.cowork-flow/scripts/common/storage/unit_of_work.py +214 -0
- package/template/.cowork-flow/scripts/common/task/active_task.py +93 -135
- package/template/.cowork-flow/scripts/common/task/batch_mode.py +33 -120
- package/template/.cowork-flow/scripts/common/task/decision_review.py +85 -0
- package/template/.cowork-flow/scripts/common/task/readiness.py +9 -15
- package/template/.cowork-flow/scripts/common/task/task_repository.py +156 -0
- package/template/.cowork-flow/scripts/run.py +24 -0
- package/template/.cowork-flow/spec/contracts/decision-anchor.md +8 -2
- package/template/.cowork-flow/spec/contracts/subagent-dispatch.md +2 -4
- package/template/.cowork-flow/spec/contracts/workflow-state-templates.md +1 -1
- package/template/.cowork-flow/spec/protocols/decision-review.md +28 -0
- package/template/.cowork-flow/spec/protocols/review.md +34 -0
- package/template/.cowork-flow/spec/protocols/spec-maintenance.md +16 -0
- package/template/.cowork-flow/spec/protocols/tdd.md +30 -0
- package/template/.cowork-flow/spec/references/definition-of-done.md +4 -4
- package/template/.cowork-flow/spec/references/orchestration-patterns.md +1 -1
- package/template/.cowork-flow/spec/runtime/contract-registry.json +25 -0
- package/template/.cowork-flow/spec/runtime/host-assets.json +214 -0
- package/template/.cowork-flow/spec/runtime/index.md +8 -0
- package/template/.cowork-flow/spec/runtime/rules.json +61 -10
- package/template/.cowork-flow/spec/runtime/skill-registry.json +397 -0
- package/template/.cowork-flow/spec/schemas/host-assets.schema.json +173 -0
- package/template/.cowork-flow/spec/schemas/rules.schema.json +10 -1
- package/template/.cowork-flow/spec/schemas/skill-registry.schema.json +202 -0
- package/template/.cowork-flow/workflow.md +18 -13
- package/template/.opencode/agents/cowork-check.md +11 -0
- package/template/.opencode/agents/cowork-implement.md +16 -1
- package/template/.zcode/.zcode-plugin/plugin.json +1 -1
- package/template/.zcode/hooks/inject-context.js +3 -85
- package/template/.zcode/hooks/inject-context.selfcheck.mjs +6 -6
- package/template/.zcode/scaffold/.cowork-flow/spec/contracts/decision-anchor.md +8 -2
- package/template/.zcode/scaffold/.cowork-flow/spec/contracts/subagent-dispatch.md +2 -4
- package/template/.zcode/scaffold/.cowork-flow/spec/runtime/rules.json +61 -10
- package/template/.zcode/scaffold/.cowork-flow/spec/schemas/rules.schema.json +10 -1
- package/template/.zcode/scaffold/.cowork-flow/workflow.md +18 -13
- package/template/.zcode/scaffold/AGENTS.md +18 -8
- package/template/AGENTS.md +1 -1
- package/template/skills/batch-mode/SKILL.md +140 -76
- package/template/skills/brainstorming/SKILL.md +2 -2
- package/template/skills/cowork-flow/SKILL.md +42 -0
- package/template/skills/party-mode/SHARED-BOUNDARIES.md +1 -1
- package/template/skills/party-mode/SKILL.md +48 -119
- package/template/.cowork-flow/scripts/common/gates/spec_validator.py +0 -53
- package/template/.cowork-flow/scripts/common/gates/validate_jsonl.py +0 -32
- package/template/skills/before-dev/SKILL.md +0 -41
- package/template/skills/check/SKILL.md +0 -53
- package/template/skills/check/simplification-guide.md +0 -47
- package/template/skills/continue/SKILL.md +0 -29
- package/template/skills/doubt-review/SKILL.md +0 -118
- package/template/skills/finish-work/SKILL.md +0 -32
- package/template/skills/party-mode-v2/SKILL.md +0 -75
- package/template/skills/start/SKILL.md +0 -78
- package/template/skills/tdd/SKILL.md +0 -74
- package/template/skills/update-spec/SKILL.md +0 -39
- package/template/skills/using-cowork-flow/SKILL.md +0 -80
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://cowork-flow.dev/schemas/skill-registry.schema.json",
|
|
4
|
+
"title": "cowork-flow Skill Registry",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schemaVersion",
|
|
9
|
+
"entries"
|
|
10
|
+
],
|
|
11
|
+
"properties": {
|
|
12
|
+
"schemaVersion": {
|
|
13
|
+
"const": 1
|
|
14
|
+
},
|
|
15
|
+
"entries": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"minItems": 1,
|
|
18
|
+
"items": {
|
|
19
|
+
"$ref": "#/$defs/entry"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"$defs": {
|
|
24
|
+
"entry": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"additionalProperties": false,
|
|
27
|
+
"required": [
|
|
28
|
+
"id",
|
|
29
|
+
"displayName",
|
|
30
|
+
"aliases",
|
|
31
|
+
"kind",
|
|
32
|
+
"visibility",
|
|
33
|
+
"status",
|
|
34
|
+
"statuses",
|
|
35
|
+
"intents",
|
|
36
|
+
"enforcement",
|
|
37
|
+
"runtimeGate",
|
|
38
|
+
"runtimeCommand",
|
|
39
|
+
"evidenceArtifact",
|
|
40
|
+
"source",
|
|
41
|
+
"managedPaths"
|
|
42
|
+
],
|
|
43
|
+
"properties": {
|
|
44
|
+
"id": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
47
|
+
},
|
|
48
|
+
"displayName": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"minLength": 1
|
|
51
|
+
},
|
|
52
|
+
"aliases": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"uniqueItems": true,
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"kind": {
|
|
61
|
+
"enum": [
|
|
62
|
+
"phase",
|
|
63
|
+
"protocol",
|
|
64
|
+
"domain",
|
|
65
|
+
"mode",
|
|
66
|
+
"runtime"
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
"visibility": {
|
|
70
|
+
"enum": [
|
|
71
|
+
"public",
|
|
72
|
+
"internal"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"status": {
|
|
76
|
+
"enum": [
|
|
77
|
+
"active",
|
|
78
|
+
"disabled"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
"statuses": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"uniqueItems": true,
|
|
84
|
+
"items": {
|
|
85
|
+
"enum": [
|
|
86
|
+
"no_task",
|
|
87
|
+
"planning",
|
|
88
|
+
"in_progress",
|
|
89
|
+
"review",
|
|
90
|
+
"completed",
|
|
91
|
+
"delegated_subtask"
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"intents": {
|
|
96
|
+
"type": "array",
|
|
97
|
+
"uniqueItems": true,
|
|
98
|
+
"items": {
|
|
99
|
+
"type": "string",
|
|
100
|
+
"pattern": "^[a-z][a-z0-9_]*$"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"enforcement": {
|
|
104
|
+
"enum": [
|
|
105
|
+
"advisory",
|
|
106
|
+
"mandatory",
|
|
107
|
+
"runtime"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
"runtimeGate": {
|
|
111
|
+
"type": [
|
|
112
|
+
"string",
|
|
113
|
+
"null"
|
|
114
|
+
],
|
|
115
|
+
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
116
|
+
},
|
|
117
|
+
"runtimeCommand": {
|
|
118
|
+
"type": [
|
|
119
|
+
"string",
|
|
120
|
+
"null"
|
|
121
|
+
],
|
|
122
|
+
"minLength": 1
|
|
123
|
+
},
|
|
124
|
+
"evidenceArtifact": {
|
|
125
|
+
"type": [
|
|
126
|
+
"string",
|
|
127
|
+
"null"
|
|
128
|
+
],
|
|
129
|
+
"minLength": 1
|
|
130
|
+
},
|
|
131
|
+
"source": {
|
|
132
|
+
"type": "string",
|
|
133
|
+
"pattern": "^[A-Za-z0-9._/-]+$"
|
|
134
|
+
},
|
|
135
|
+
"managedPaths": {
|
|
136
|
+
"type": "array",
|
|
137
|
+
"uniqueItems": true,
|
|
138
|
+
"items": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"pattern": "^[A-Za-z0-9._/-]+/$"
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"readWhen": {
|
|
144
|
+
"type": [
|
|
145
|
+
"object",
|
|
146
|
+
"null"
|
|
147
|
+
],
|
|
148
|
+
"additionalProperties": false,
|
|
149
|
+
"properties": {
|
|
150
|
+
"devTypes": {
|
|
151
|
+
"type": "array",
|
|
152
|
+
"uniqueItems": true,
|
|
153
|
+
"items": {
|
|
154
|
+
"type": "string",
|
|
155
|
+
"minLength": 1
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"pathPatterns": {
|
|
159
|
+
"type": "array",
|
|
160
|
+
"uniqueItems": true,
|
|
161
|
+
"items": {
|
|
162
|
+
"type": "string",
|
|
163
|
+
"minLength": 1
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"anyOf": [
|
|
168
|
+
{
|
|
169
|
+
"required": [
|
|
170
|
+
"devTypes"
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"required": [
|
|
175
|
+
"pathPatterns"
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
"allOf": [
|
|
182
|
+
{
|
|
183
|
+
"if": {
|
|
184
|
+
"properties": {
|
|
185
|
+
"enforcement": {
|
|
186
|
+
"const": "mandatory"
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
"then": {
|
|
191
|
+
"properties": {
|
|
192
|
+
"runtimeGate": {
|
|
193
|
+
"type": "string",
|
|
194
|
+
"minLength": 1
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -14,7 +14,7 @@ changes -> brainstorming -> read spec -> plan -> tasks -> implement -> check ->
|
|
|
14
14
|
2. brainstorming:对changes需求做头脑风暴,确定目标、范围、验收标准、范围边界、被拒方案、实现方案、检查方案。
|
|
15
15
|
3. read spec: 读取项目规范
|
|
16
16
|
4. plan:构建开发计划。
|
|
17
|
-
5. tasks:根据plan拆分具体执行任务、明确
|
|
17
|
+
5. tasks:根据plan拆分具体执行任务、明确 `decision-anchor.md`、整理 `implement.jsonl` / `check.jsonl`。
|
|
18
18
|
6. implement:主会话通过当前宿主适配器派发 `cowork-implement`,按 `.cowork-flow/spec/contracts/subagent-dispatch.md` 执行固定代理派发协议。
|
|
19
19
|
7. check:主会话通过当前宿主适配器派发 `cowork-check`,按 `.cowork-flow/spec/contracts/subagent-dispatch.md` 执行固定代理派发协议。
|
|
20
20
|
8. complete:主会话做最终验证、同步规格、归档、记录会话、提交。
|
|
@@ -31,7 +31,7 @@ changes -> brainstorming -> read spec -> plan -> tasks -> implement -> check ->
|
|
|
31
31
|
|
|
32
32
|
## 1.2 需求澄清与头脑风暴门禁
|
|
33
33
|
|
|
34
|
-
1. 新需求先判断清晰度。只读问题、单步且目标/范围/验收标准都清楚的小改可以绕过;否则必须先进入 `brainstorming
|
|
34
|
+
1. 新需求先判断清晰度。只读问题、单步且目标/范围/验收标准都清楚的小改可以绕过;否则必须先进入 `brainstorming`,在写决策锚点、计划或固定代理派发前收束方向。
|
|
35
35
|
2. 以下情况触发头脑风暴:
|
|
36
36
|
- 目标、用户价值或期望行为不清楚。
|
|
37
37
|
- 范围边界、非目标或影响面不清楚。
|
|
@@ -39,7 +39,7 @@ changes -> brainstorming -> read spec -> plan -> tasks -> implement -> check ->
|
|
|
39
39
|
- 涉及 L1/L2 行为变化,或影响架构、接口、数据、权限、发布迁移。
|
|
40
40
|
- 验收标准缺失、风险未知,或关键假设需要暴露。
|
|
41
41
|
|
|
42
|
-
3. `brainstorming`
|
|
42
|
+
3. `brainstorming` 输出至少包括:目标、非目标、关键假设、范围边界、推荐方向、被拒方案、验收标准、开放问题/阻塞。只有方向和验收标准清楚后,才进入决策锚点、计划或固定代理派发。
|
|
43
43
|
|
|
44
44
|
## 2. 状态文件
|
|
45
45
|
|
|
@@ -70,6 +70,15 @@ changes -> brainstorming -> read spec -> plan -> tasks -> implement -> check ->
|
|
|
70
70
|
|
|
71
71
|
`task finish` 只清理当前会话任务指针,不改变 `task.json.status`。
|
|
72
72
|
|
|
73
|
+
## 2.1 运行时权威边界与旧资产清理
|
|
74
|
+
|
|
75
|
+
1. `scripts/commands/` 只负责参数解析和输出;任务、上下文、归档和 runtime context 业务流程由 `scripts/application/` 编排。
|
|
76
|
+
2. JSON 状态写入统一经过 `scripts/common/storage/`,显式使用 UTF-8、修订检查和可恢复 Unit of Work。
|
|
77
|
+
3. 宿主资产、平台识别、同步保护和 obsolete cleanup 清单以 `spec/runtime/host-assets.json` 为权威来源;禁止在命令层维护第二套平台集合。
|
|
78
|
+
4. init/sync 必须先构建和验证 Asset Plan,再通过 staging、备份和 rollback 提交;`.cowork-flow/.version` 最后更新。
|
|
79
|
+
5. 旧 task/session/runtime-context 只允许在带保护测试的读取边界保留;旧受管资产只允许由 sync 的 obsolete cleanup 删除。新写入必须使用当前 schema、当前目录和共享 Hook 核心。
|
|
80
|
+
6. 未完成事务、损坏状态或未知 schema 不能静默继续写入;无法安全恢复时 fail-closed 并保留诊断现场。
|
|
81
|
+
|
|
73
82
|
## 3. 固定代理
|
|
74
83
|
|
|
75
84
|
固定代理只执行主会话派发的叶子任务。子代理是执行者,子任务是工作单元。
|
|
@@ -91,17 +100,13 @@ changes -> brainstorming -> read spec -> plan -> tasks -> implement -> check ->
|
|
|
91
100
|
- 固定 `cowork-*` 代理是叶子执行者;不得再派发、等待、列出或取消其他代理。
|
|
92
101
|
- 通用 `worker`、`default` 或 `explorer` 只能作为 advisory work,不能满足正式实现或检查完成条件。
|
|
93
102
|
|
|
94
|
-
## 3.2
|
|
95
|
-
|
|
96
|
-
Party Mode 是用户手动触发的 advisory roundtable。主会话可通过当前宿主适配器创建 fresh child contexts,收集真实讨论子代理的证据、分歧、风险和可测验收信号,再由主会话综合结论。
|
|
97
|
-
|
|
98
|
-
Party Mode 不能推进任务状态,不能满足正式实现或检查完成条件,也不能替代 `cowork-implement` 或 `cowork-check`。轮次上限、继续/停止条件、输出 schema 和可配置默认值由 party-mode skill 定义;正式子代理协议仍以 `.cowork-flow/spec/contracts/subagent-dispatch.md` 为准。
|
|
103
|
+
## 3.2 Party Mode
|
|
99
104
|
|
|
100
|
-
|
|
105
|
+
Party Mode 是用户手动触发的 runtime board advisory workflow。主会话通过 `party-mode` 入口启动 `party-v2` runtime;Python runtime 控制看板、当前轮视图、schema 校验、轮次上限、纠偏事件和最终报告。
|
|
101
106
|
|
|
102
|
-
Party Mode
|
|
107
|
+
Party Mode 子代理通过 board API 交流,主持人只监控 runtime status、执行宿主适配器动作和记录偏题纠正。Party Mode 不能推进任务状态,不能满足正式实现或检查完成条件,也不能替代 `cowork-implement` 或 `cowork-check`。
|
|
103
108
|
|
|
104
|
-
Party Mode
|
|
109
|
+
Party Mode runtime 只输出 host-neutral next actions,宿主专属原语仍只在 `.cowork-flow/adapters/<host>/adapter.yaml` 和宿主资产中声明。正式子代理协议仍以 `.cowork-flow/spec/contracts/subagent-dispatch.md` 为准。
|
|
105
110
|
|
|
106
111
|
## 3.3 并行会话
|
|
107
112
|
|
|
@@ -195,7 +200,7 @@ L2 任务在 `task start` 前必须通过 readiness gate;同一 blocker 列表
|
|
|
195
200
|
1. 先运行 `task next` 确认任务处于 `review` 检查阶段。
|
|
196
201
|
2. 默认通过宿主适配器派发 `cowork-check`。派发必须使用新鲜子上下文,并遵守 `.cowork-flow/spec/contracts/subagent-dispatch.md`。
|
|
197
202
|
3. 检查内容:
|
|
198
|
-
-
|
|
203
|
+
- decision-anchor 验收标准是否满足。
|
|
199
204
|
- `git diff` 是否只包含预期范围。
|
|
200
205
|
- 测试是否覆盖关键行为。
|
|
201
206
|
- `.cowork-flow/spec/` 是否需要更新。
|
|
@@ -233,7 +238,7 @@ L2 任务在 `task start` 前必须通过 readiness gate;同一 blocker 列表
|
|
|
233
238
|
|
|
234
239
|
恢复时只读取最小上下文:
|
|
235
240
|
1. 运行 `./.cowork-flow/run resume`。
|
|
236
|
-
2. 按 `RESUME CHECKLIST` 读取当前任务
|
|
241
|
+
2. 按 `RESUME CHECKLIST` 读取当前任务 decision-anchor、计划状态和 JSONL 指向文件。
|
|
237
242
|
3. 不批量读取所有规格、计划、任务或工作区日志。
|
|
238
243
|
4. 不存在当前会话任务时,先创建或启动任务。
|
|
239
244
|
|
|
@@ -33,6 +33,17 @@ or names another agent type, report `needs_context` and stop. Do not infer
|
|
|
33
33
|
subagent identity from prompt shape; runtime context binding is the only formal
|
|
34
34
|
signal.
|
|
35
35
|
|
|
36
|
+
Authoritative internal protocols:
|
|
37
|
+
|
|
38
|
+
- `.cowork-flow/spec/protocols/review.md`
|
|
39
|
+
- `.cowork-flow/spec/protocols/decision-review.md`
|
|
40
|
+
- `.cowork-flow/spec/protocols/spec-maintenance.md`
|
|
41
|
+
|
|
42
|
+
Apply their Host-neutral output contract. Review output must preserve
|
|
43
|
+
`acceptanceId`, `findings`, `test_intent_review`, `resolution`, and
|
|
44
|
+
`specUpdates`; reject shallow tests that do not cover meaningful behavior
|
|
45
|
+
breaks or map to decision-anchor acceptance.
|
|
46
|
+
|
|
36
47
|
Rules:
|
|
37
48
|
|
|
38
49
|
- Read the task directory from the bound runtime context.
|
|
@@ -35,6 +35,21 @@ signal.
|
|
|
35
35
|
|
|
36
36
|
---
|
|
37
37
|
|
|
38
|
+
## Authoritative Internal Protocols
|
|
39
|
+
|
|
40
|
+
Read and apply:
|
|
41
|
+
|
|
42
|
+
- `.cowork-flow/spec/protocols/tdd.md`
|
|
43
|
+
- `.cowork-flow/spec/protocols/decision-review.md`
|
|
44
|
+
- `.cowork-flow/spec/protocols/spec-maintenance.md`
|
|
45
|
+
|
|
46
|
+
Their contracts are Host-neutral. Implementation reports and `tdd.jsonl` must
|
|
47
|
+
preserve `acceptanceId`, `redCommand`, `redExitCode`, `greenCommand`,
|
|
48
|
+
`greenExitCode`, and `specUpdates`. A behavior change requires
|
|
49
|
+
red-green-refactor evidence or a valid documented exemption.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
38
53
|
## Mandatory Pre-Implementation Checklist
|
|
39
54
|
|
|
40
55
|
Before writing any code, you MUST read and apply these spec files:
|
|
@@ -165,7 +180,7 @@ You MUST NOT do any of the following:
|
|
|
165
180
|
- Rely on implicit side effects for interactions without explicit data flow and cleanup logic
|
|
166
181
|
- Elevate local state to global state, or duplicate server state as multiple local states
|
|
167
182
|
- Only verify ideal paths, not failures, empty data, or repeated operations
|
|
168
|
-
- Introduce features not required by the
|
|
183
|
+
- Introduce features not required by the decision-anchor
|
|
169
184
|
- Refactor unrelated modules "while you're at it"
|
|
170
185
|
- Make premature abstractions for one-off code
|
|
171
186
|
|
|
@@ -5,39 +5,13 @@
|
|
|
5
5
|
* Output: ZCode/Claude Code hook format (stdout JSON).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { readFileSync,
|
|
9
|
-
import { join, dirname
|
|
8
|
+
import { readFileSync, existsSync, readdirSync } from "fs";
|
|
9
|
+
import { join, dirname } from "path";
|
|
10
10
|
import { createHash } from "crypto";
|
|
11
11
|
|
|
12
|
-
const SCAFFOLD_DIR = join(import.meta.dirname, "..", "scaffold");
|
|
13
12
|
const DIR_WORKFLOW = ".cowork-flow";
|
|
14
13
|
const FILE_TASK_JSON = "task.json";
|
|
15
14
|
|
|
16
|
-
// Derive the installed plugin version from this hook's location in the cache.
|
|
17
|
-
// Path: hooks/inject-context.js -> .. = <cache>/<version>/
|
|
18
|
-
const PLUGIN_VERSION = basename(dirname(import.meta.dirname));
|
|
19
|
-
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
// Version sync
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
function syncPluginVersion(targetDir) {
|
|
24
|
-
if (!PLUGIN_VERSION) return;
|
|
25
|
-
const versionFile = join(targetDir, DIR_WORKFLOW, ".version");
|
|
26
|
-
let current = "";
|
|
27
|
-
try {
|
|
28
|
-
current = readFileSync(versionFile, "utf8").trim();
|
|
29
|
-
} catch {
|
|
30
|
-
current = "";
|
|
31
|
-
}
|
|
32
|
-
if (current === PLUGIN_VERSION) return;
|
|
33
|
-
try {
|
|
34
|
-
mkdirSync(dirname(versionFile), { recursive: true });
|
|
35
|
-
writeFileSync(versionFile, `${PLUGIN_VERSION}\n`, "utf8");
|
|
36
|
-
} catch {
|
|
37
|
-
/* skip — non-fatal */
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
15
|
const TAG_RE = /\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n(.*?)\n\s*\[\/workflow-state:\1\]/gs;
|
|
42
16
|
const RUNTIME_CONTEXT_PROMPT_RE = /^\s*cowork_runtime_context_id\s*:\s*([A-Za-z0-9._-]+)\s*$/gim;
|
|
43
17
|
const DEFAULT_CONTRACT_REGISTRY = {
|
|
@@ -224,41 +198,6 @@ function checkEssentialFiles(repoRoot) {
|
|
|
224
198
|
return missing;
|
|
225
199
|
}
|
|
226
200
|
|
|
227
|
-
// ---------------------------------------------------------------------------
|
|
228
|
-
// Scaffold missing template files
|
|
229
|
-
// ---------------------------------------------------------------------------
|
|
230
|
-
function scaffoldProject(repoRoot) {
|
|
231
|
-
const copied = [];
|
|
232
|
-
function copyRecursive(srcDir, destDir, prefix) {
|
|
233
|
-
let entries;
|
|
234
|
-
try {
|
|
235
|
-
entries = readdirSync(srcDir, { withFileTypes: true });
|
|
236
|
-
} catch {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
for (const entry of entries) {
|
|
240
|
-
if (entry.name === "__pycache__" || entry.name.endsWith(".pyc")) continue;
|
|
241
|
-
const srcPath = join(srcDir, entry.name);
|
|
242
|
-
const destPath = join(destDir, entry.name);
|
|
243
|
-
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
244
|
-
if (entry.isDirectory()) {
|
|
245
|
-
copyRecursive(srcPath, destPath, relPath);
|
|
246
|
-
} else {
|
|
247
|
-
if (existsSync(destPath)) continue;
|
|
248
|
-
try {
|
|
249
|
-
mkdirSync(dirname(destPath), { recursive: true });
|
|
250
|
-
copyFileSync(srcPath, destPath);
|
|
251
|
-
copied.push(relPath);
|
|
252
|
-
} catch {
|
|
253
|
-
// skip
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
copyRecursive(SCAFFOLD_DIR, repoRoot, "");
|
|
259
|
-
return copied;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
201
|
// ---------------------------------------------------------------------------
|
|
263
202
|
// Runtime context detection
|
|
264
203
|
// ---------------------------------------------------------------------------
|
|
@@ -354,30 +293,16 @@ function main() {
|
|
|
354
293
|
|
|
355
294
|
let context;
|
|
356
295
|
|
|
357
|
-
// Ensure .cowork-flow/ exists and scaffold missing template files
|
|
358
296
|
const envDir = process.env.ZCODE_PROJECT_DIR;
|
|
359
|
-
if (envDir && !existsSync(join(envDir, DIR_WORKFLOW))) {
|
|
360
|
-
mkdirSync(join(envDir, DIR_WORKFLOW), { recursive: true });
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const copied = envDir ? scaffoldProject(envDir) : [];
|
|
364
297
|
const effectiveRoot = repoRoot || (envDir && existsSync(join(envDir, DIR_WORKFLOW)) ? envDir : null);
|
|
365
298
|
|
|
366
|
-
// Always refresh .version so plugin upgrades propagate to existing projects
|
|
367
|
-
if (effectiveRoot) {
|
|
368
|
-
syncPluginVersion(effectiveRoot);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
299
|
if (!effectiveRoot) {
|
|
372
300
|
context = `<workflow-state>
|
|
373
301
|
Status: not_initialized
|
|
374
302
|
Source: cowork-flow-plugin
|
|
375
303
|
⚠️ 项目未初始化 cowork-flow 工作流。
|
|
376
304
|
|
|
377
|
-
|
|
378
|
-
./.cowork-flow/run init-developer <询问用户的名字>
|
|
379
|
-
|
|
380
|
-
初始化完成后,继续按工作流引导用户创建任务。
|
|
305
|
+
请通过显式 init/sync 安装 cowork-flow 模板后再继续;hook 不会在注入阶段创建或复制项目文件。
|
|
381
306
|
</workflow-state>`;
|
|
382
307
|
} else {
|
|
383
308
|
// PRIORITY 1: Detect delegated_subtask from runtime context
|
|
@@ -406,13 +331,6 @@ Source: cowork-flow-plugin
|
|
|
406
331
|
|
|
407
332
|
⚠️ 缺少必要文件:${missingFiles.join(", ")}。
|
|
408
333
|
请立即创建这些文件以保障工作流正常运行。`;
|
|
409
|
-
} else if (copied.length > 0) {
|
|
410
|
-
const summary = copied.length <= 5
|
|
411
|
-
? copied.join(", ")
|
|
412
|
-
: `${copied.slice(0, 5).join(", ")} 等 ${copied.length} 个文件`;
|
|
413
|
-
context += `
|
|
414
|
-
|
|
415
|
-
已自动补充模板文件:${summary}。`;
|
|
416
334
|
}
|
|
417
335
|
|
|
418
336
|
const payload =
|
|
@@ -36,7 +36,7 @@ function runHook(env = {}, stdin) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
function copyScaffoldTemplate(repoRoot) {
|
|
39
|
-
const src = join(import.meta.dirname, "..", "scaffold", "spec", "contracts", "workflow-state-templates.md");
|
|
39
|
+
const src = join(import.meta.dirname, "..", "scaffold", ".cowork-flow", "spec", "contracts", "workflow-state-templates.md");
|
|
40
40
|
const dest = join(repoRoot, ".cowork-flow", "spec", "contracts", "workflow-state-templates.md");
|
|
41
41
|
if (existsSync(src)) {
|
|
42
42
|
mkdirSync(dirname(dest), { recursive: true });
|
|
@@ -85,7 +85,7 @@ try {
|
|
|
85
85
|
assert.match(ctx, /Status: in_progress/);
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
test("
|
|
88
|
+
test("reports not_initialized without scaffolding when ZCODE_PROJECT_DIR has none", () => {
|
|
89
89
|
const scaffoldTmp = join(import.meta.dirname, ".scaffold-test");
|
|
90
90
|
if (existsSync(scaffoldTmp)) rmSync(scaffoldTmp, { recursive: true, force: true });
|
|
91
91
|
const emptyDir = join(scaffoldTmp, "fresh-proj");
|
|
@@ -93,10 +93,10 @@ try {
|
|
|
93
93
|
const result = runHook({ ZCODE_PROJECT_DIR: emptyDir });
|
|
94
94
|
const parsed = JSON.parse(result);
|
|
95
95
|
const ctx = parsed.hookSpecificOutput.additionalContext;
|
|
96
|
-
assert.match(ctx, /
|
|
97
|
-
assert.
|
|
98
|
-
assert.ok(existsSync(join(emptyDir, ".cowork-flow"
|
|
99
|
-
assert.ok(existsSync(join(emptyDir, "AGENTS.md")), "AGENTS.md should be created");
|
|
96
|
+
assert.match(ctx, /not_initialized/);
|
|
97
|
+
assert.match(ctx, /hook 不会在注入阶段创建或复制项目文件/);
|
|
98
|
+
assert.ok(!existsSync(join(emptyDir, ".cowork-flow")), ".cowork-flow should not be created");
|
|
99
|
+
assert.ok(!existsSync(join(emptyDir, "AGENTS.md")), "AGENTS.md should not be created");
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
test("workflow-state block is well-formed XML", () => {
|
|
@@ -63,6 +63,12 @@
|
|
|
63
63
|
- `cowork-check` 读取:同上
|
|
64
64
|
- `debug.jsonl` 引用:可选,偏差诊断时写入 anchor 锚点差异
|
|
65
65
|
|
|
66
|
-
##
|
|
66
|
+
## 正式版行为
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
正式版不自动迁移旧 `prd.md`。任务启动时只认可 `decision-anchor.md`
|
|
69
|
+
作为权威决策来源;如果任务目录只有 `prd.md` 而缺少
|
|
70
|
+
`decision-anchor.md`,`task start` 必须 fail-closed 并报告
|
|
71
|
+
`decision-anchor.md is missing or empty`。
|
|
72
|
+
|
|
73
|
+
已有旧任务需要人工把 `prd.md` 内容转换为 `decision-anchor.md`,并补齐
|
|
74
|
+
`## 目标` 与 `## 验收标准` 后再启动。
|
|
@@ -14,11 +14,9 @@ classification or a prompt handshake.
|
|
|
14
14
|
|
|
15
15
|
## Advisory Party Mode
|
|
16
16
|
|
|
17
|
-
Party Mode discussion children are advisory leaf executors. They
|
|
17
|
+
Party Mode discussion children are advisory leaf executors. They communicate through the `party-v2` runtime board for evidence gathering, disagreement surfacing, risk review, and acceptance-signal review. They cannot mutate task status, write code, archive, commit, or coordinate other agents. Their output cannot satisfy formal Implement or Check completion.
|
|
18
18
|
|
|
19
|
-
The `party-mode` skill
|
|
20
|
-
|
|
21
|
-
Party Mode V2 discussion children are also advisory leaf executors. The `party-mode-v2` entrypoint delegates discussion state, current-round board visibility, schema validation, drift warnings, round limits, and final reports to the Party Mode V2 runtime board controller. The runtime emits host-neutral next actions; it does not change the formal `cowork-*` dispatch protocol and does not satisfy Implement or Check completion.
|
|
19
|
+
The public `party-mode` skill delegates discussion state, current-round board visibility, schema validation, drift warnings, round limits, and final reports to the `party-v2` runtime board controller. The runtime emits host-neutral next actions; it does not change the formal `cowork-*` dispatch protocol and does not satisfy Implement or Check completion. This document remains the formal `cowork-*` dispatch protocol source.
|
|
22
20
|
|
|
23
21
|
## Runtime Context
|
|
24
22
|
|