cowork-flow 0.0.42 → 0.0.44
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 +39 -23
- package/package.json +8 -4
- package/src/commands/install-zcode-plugin.js +3 -15
- package/src/lib/copy-template.js +119 -66
- package/template/.claude/agents/cowork-check.md +14 -58
- package/template/.claude/agents/cowork-implement.md +15 -62
- package/template/.claude/agents/cowork-research.md +9 -31
- package/template/.claude/hooks/inject-workflow-state.py +1 -1
- package/template/.codex/agents/cowork-check.toml +14 -51
- package/template/.codex/agents/cowork-implement.toml +15 -54
- package/template/.codex/agents/cowork-research.toml +8 -22
- package/template/.codex/hooks/inject-workflow-state.py +1 -1
- package/template/.cowork-flow/.version +1 -1
- package/template/.cowork-flow/scripts/adapters/__init__.py +1 -0
- package/template/.cowork-flow/scripts/adapters/cli/_bootstrap.py +14 -0
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/add_session.py +3 -3
- package/template/.cowork-flow/scripts/adapters/cli/batch_mode.py +90 -0
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/change.py +2 -2
- package/template/.cowork-flow/scripts/adapters/cli/encoding.py +28 -0
- package/template/.cowork-flow/scripts/adapters/cli/execution_context_args.py +121 -0
- package/template/.cowork-flow/scripts/{common/core/execution_context.py → adapters/cli/execution_resume.py} +9 -216
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/get_context.py +1 -1
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/get_developer.py +2 -2
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/init_developer.py +2 -2
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/resume.py +5 -3
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/subagent.py +4 -4
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/task.py +259 -179
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/task_archive_commands.py +12 -12
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/task_context_commands.py +5 -5
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/task_create_command.py +26 -8
- package/template/.cowork-flow/scripts/adapters/cli/task_navigation.py +226 -0
- package/template/.cowork-flow/scripts/adapters/cli/task_parser.py +167 -0
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/task_support.py +2 -2
- package/template/.cowork-flow/scripts/{commands → adapters/cli}/task_tree_commands.py +4 -4
- package/template/.cowork-flow/scripts/{common → adapters}/git/git_context.py +6 -6
- package/template/.cowork-flow/scripts/{common/core → adapters/host}/host_manifest.py +28 -1
- package/template/.cowork-flow/scripts/{common → adapters}/host/workflow_state_hook.py +7 -7
- package/template/.cowork-flow/scripts/adapters/review/__init__.py +1 -0
- package/template/.cowork-flow/scripts/adapters/review/test_intent.py +172 -0
- package/template/.cowork-flow/scripts/infra/__init__.py +0 -0
- package/template/.cowork-flow/scripts/{common/core → infra}/config.py +1 -1
- package/template/.cowork-flow/scripts/{common/core/developer.py → infra/developer_profile.py} +1 -1
- package/template/.cowork-flow/scripts/{common/git → infra}/git_snapshot.py +15 -2
- package/template/.cowork-flow/scripts/{common/core → infra}/paths.py +0 -0
- package/template/.cowork-flow/scripts/{common/core → infra}/quality_sources.py +0 -17
- package/template/.cowork-flow/scripts/infra/skill_manifest.py +427 -0
- package/template/.cowork-flow/scripts/{common → infra}/storage/operation_log.py +1 -1
- package/template/.cowork-flow/scripts/{common → infra}/storage/unit_of_work.py +2 -2
- package/template/.cowork-flow/scripts/kernel/__init__.py +1 -0
- package/template/.cowork-flow/scripts/{common/task/state_machine.py → kernel/task_state.py} +2 -2
- package/template/.cowork-flow/scripts/kernel/workflow_route.py +199 -0
- package/template/.cowork-flow/scripts/run.py +65 -42
- package/template/.cowork-flow/scripts/runtime/__init__.py +0 -0
- package/template/.cowork-flow/scripts/runtime/execution_context.py +121 -0
- package/template/.cowork-flow/scripts/{common/task/active_task.py → runtime/session_state.py} +2 -47
- package/template/.cowork-flow/scripts/services/__init__.py +1 -0
- package/template/.cowork-flow/scripts/services/lifecycle_checks.py +194 -0
- package/template/.cowork-flow/scripts/{common/task → services}/readiness.py +8 -90
- package/template/.cowork-flow/scripts/{application → services}/task_archive.py +7 -7
- package/template/.cowork-flow/scripts/{application → services}/task_context.py +50 -88
- package/template/.cowork-flow/scripts/{application → services}/task_creation.py +3 -3
- package/template/.cowork-flow/scripts/{application → services}/task_lifecycle.py +52 -84
- package/template/.cowork-flow/scripts/{common/task → services}/task_repository.py +3 -3
- package/template/.cowork-flow/scripts/services/task_routing.py +148 -0
- package/template/.cowork-flow/scripts/{application → services}/task_tree.py +3 -3
- package/template/.cowork-flow/scripts/{common/task → services}/task_utils.py +3 -3
- package/template/.cowork-flow/scripts/{application/runtime_context_service.py → services/workflow_runtime.py} +38 -3
- package/template/.cowork-flow/spec/backend/index.md +1 -1
- package/template/.cowork-flow/spec/backend/quality-guidelines.md +1 -3
- package/template/.cowork-flow/spec/contracts/decision-anchor.md +4 -4
- package/template/.cowork-flow/spec/contracts/error-output-as-data.md +1 -1
- package/template/.cowork-flow/spec/contracts/index.md +1 -0
- package/template/.cowork-flow/spec/contracts/skill-owned-actions.md +46 -0
- package/template/.cowork-flow/spec/contracts/workflow-state-templates.md +22 -39
- package/template/.cowork-flow/spec/frontend/index.md +1 -1
- package/template/.cowork-flow/spec/frontend/quality-guidelines.md +1 -3
- package/template/.cowork-flow/spec/index.md +8 -5
- package/template/.cowork-flow/spec/references/definition-of-done.md +4 -4
- package/template/.cowork-flow/spec/references/orchestration-patterns.md +2 -2
- package/template/.cowork-flow/spec/references/security-checklist.md +1 -1
- package/template/.cowork-flow/spec/references/testing-checklist.md +2 -2
- package/template/.cowork-flow/spec/runtime/contract-registry.json +4 -17
- package/template/.cowork-flow/spec/runtime/host-assets.json +81 -34
- package/template/.cowork-flow/spec/runtime/index.md +7 -6
- package/template/.cowork-flow/spec/schemas/index.md +1 -3
- package/template/.opencode/agents/cowork-check.md +13 -43
- package/template/.opencode/agents/cowork-implement.md +14 -207
- package/template/.opencode/agents/cowork-research.md +8 -25
- package/template/.zcode/.zcode-plugin/plugin.json +1 -1
- package/template/.zcode/hooks/inject-context.js +9 -7
- package/template/.zcode/hooks/inject-context.selfcheck.mjs +49 -10
- package/template/.zcode/scaffold/AGENTS.md +19 -10
- package/template/AGENTS.md +3 -3
- package/template/skills/adversarial-review/SKILL.md +35 -0
- package/template/skills/adversarial-review/manifest.json +18 -0
- package/template/skills/agent-dispatch/SKILL.md +37 -0
- package/template/skills/batch-execution/SKILL.md +189 -0
- package/template/skills/batch-execution/manifest.json +20 -0
- package/template/skills/batch-execution/scripts/batch_action.py +48 -0
- package/template/{.cowork-flow/scripts/application → skills/batch-execution/scripts}/batch_execution.py +24 -3
- package/template/skills/brainstorming/SKILL.md +3 -3
- package/template/skills/brainstorming/manifest.json +12 -0
- package/template/skills/cowork-flow/SKILL.md +10 -7
- package/template/skills/cowork-flow/manifest.json +43 -0
- package/template/skills/{meta → cowork-flow-maintenance}/SKILL.md +3 -3
- package/template/skills/cowork-flow-maintenance/manifest.json +12 -0
- package/template/skills/decision-audit/SKILL.md +23 -0
- package/template/skills/decision-audit/manifest.json +11 -0
- package/template/skills/{break-loop → failure-analysis}/SKILL.md +4 -4
- package/template/skills/failure-analysis/manifest.json +18 -0
- package/template/skills/game-design/manifest.json +11 -0
- package/template/skills/party-mode/SKILL.md +3 -2
- package/template/skills/party-mode/manifest.json +13 -0
- package/template/{.cowork-flow/scripts/commands → skills/party-mode/scripts}/party_mode_v2.py +13 -6
- package/template/skills/{python-design → python-runtime-design}/SKILL.md +2 -2
- package/template/skills/python-runtime-design/manifest.json +12 -0
- package/template/skills/runtime-health/SKILL.md +27 -0
- package/template/skills/runtime-health/manifest.json +11 -0
- package/template/skills/runtime-health/scripts/doctor.py +195 -0
- package/template/{.cowork-flow/spec/protocols/spec-maintenance.md → skills/spec-sync/SKILL.md} +14 -5
- package/template/skills/spec-sync/manifest.json +11 -0
- package/template/skills/{writing-plans → task-planning}/SKILL.md +49 -22
- package/template/skills/task-planning/manifest.json +12 -0
- package/template/skills/task-review/SKILL.md +63 -0
- package/template/skills/task-review/manifest.json +34 -0
- package/template/skills/task-review/scripts/review_check.py +357 -0
- package/template/skills/test-first/SKILL.md +37 -0
- package/template/skills/test-first/manifest.json +12 -0
- package/src/lib/skill-registry.js +0 -503
- package/template/.cowork-flow/scripts/application/__init__.py +0 -1
- package/template/.cowork-flow/scripts/commands/_bootstrap.py +0 -10
- package/template/.cowork-flow/scripts/commands/doctor.py +0 -455
- package/template/.cowork-flow/scripts/commands/task_navigation.py +0 -471
- package/template/.cowork-flow/scripts/commands/task_parser.py +0 -365
- package/template/.cowork-flow/scripts/common/__init__.py +0 -79
- package/template/.cowork-flow/scripts/common/core/__init__.py +0 -1
- package/template/.cowork-flow/scripts/common/core/skill_registry.py +0 -568
- package/template/.cowork-flow/scripts/common/gates/__init__.py +0 -1
- package/template/.cowork-flow/scripts/common/gates/anti_rationalization.py +0 -55
- package/template/.cowork-flow/scripts/common/gates/coding_standards.py +0 -261
- package/template/.cowork-flow/scripts/common/gates/gates.py +0 -406
- package/template/.cowork-flow/scripts/common/gates/models.py +0 -196
- package/template/.cowork-flow/scripts/common/gates/quality_review.py +0 -332
- package/template/.cowork-flow/scripts/common/gates/registry.py +0 -79
- package/template/.cowork-flow/scripts/common/gates/tdd_evidence.py +0 -378
- package/template/.cowork-flow/scripts/common/gates/test_intent.py +0 -262
- package/template/.cowork-flow/scripts/common/gates/validate_coding_standards.py +0 -392
- package/template/.cowork-flow/scripts/common/gates/validate_implementation.py +0 -312
- package/template/.cowork-flow/scripts/common/gates/validate_rules.py +0 -645
- package/template/.cowork-flow/scripts/common/task/__init__.py +0 -1
- package/template/.cowork-flow/scripts/common/task/batch_mode.py +0 -58
- package/template/.cowork-flow/scripts/common/task/decision_review.py +0 -85
- package/template/.cowork-flow/spec/protocols/decision-review.md +0 -55
- package/template/.cowork-flow/spec/protocols/review.md +0 -53
- package/template/.cowork-flow/spec/protocols/tdd.md +0 -43
- package/template/.cowork-flow/spec/runtime/rules.json +0 -176
- package/template/.cowork-flow/spec/runtime/skill-registry.json +0 -425
- package/template/.cowork-flow/spec/schemas/rules.schema.json +0 -89
- package/template/.cowork-flow/spec/schemas/skill-registry.schema.json +0 -202
- package/template/.cowork-flow/workflow.md +0 -261
- package/template/.zcode/scaffold/.cowork-flow/.version +0 -1
- package/template/.zcode/scaffold/.cowork-flow/config.yaml +0 -65
- package/template/.zcode/scaffold/.cowork-flow/run +0 -98
- package/template/.zcode/scaffold/.cowork-flow/run.cmd +0 -111
- package/template/.zcode/scaffold/.cowork-flow/workflow.md +0 -261
- package/template/skills/batch-mode/SKILL.md +0 -181
- package/template/skills/doubt-review/SKILL.md +0 -125
- /package/template/.cowork-flow/scripts/{commands → adapters/cli}/__init__.py +0 -0
- /package/template/.cowork-flow/scripts/{common → adapters}/git/__init__.py +0 -0
- /package/template/.cowork-flow/scripts/{common → adapters}/host/__init__.py +0 -0
- /package/template/.cowork-flow/scripts/{common/task → infra}/archive_utils.py +0 -0
- /package/template/.cowork-flow/scripts/{common/core → infra}/files.py +0 -0
- /package/template/.cowork-flow/scripts/{common → infra}/storage/__init__.py +0 -0
- /package/template/.cowork-flow/scripts/{common → infra}/storage/state_store.py +0 -0
package/README.md
CHANGED
|
@@ -39,10 +39,9 @@ template/
|
|
|
39
39
|
├── .codex/ # Codex agents / hooks / config
|
|
40
40
|
├── .claude/ # Claude Code settings / agents / hooks
|
|
41
41
|
├── .opencode/ # OpenCode agents / commands / plugins
|
|
42
|
-
├── .zcode/ # ⭐ ZCode 插件(hooks +
|
|
42
|
+
├── .zcode/ # ⭐ ZCode 插件(hooks + skills + scaffold instructions)
|
|
43
43
|
└── .cowork-flow/
|
|
44
44
|
├── config.yaml # 项目配置
|
|
45
|
-
├── workflow.md # 主流程定义
|
|
46
45
|
├── scripts/ # Python 运行时
|
|
47
46
|
├── spec/ # 规范文档(contracts / schemas / guides)
|
|
48
47
|
├── changes/ # 行为变更管理
|
|
@@ -58,17 +57,19 @@ template/
|
|
|
58
57
|
- **Host Asset Manifest**:`spec/runtime/host-assets.json` 是宿主资产、平台识别、同步策略和 obsolete 迁移清单的权威来源。新增平台或资产时更新 Manifest 与 schema,不在 CLI 中新增硬编码集合。
|
|
59
58
|
- **事务式 init/sync**:CLI 先构建不可变 Asset Plan,在同文件系统 staging 中校验 hash/权限,再按备份清单提交;失败时逆序回滚,`.cowork-flow/.version` 最后更新。
|
|
60
59
|
- **共享 Hook 核心**:Codex 与 Claude Code Hook 只做宿主输入适配,工作流状态解析由 `scripts/common/host/workflow_state_hook.py` 统一实现。
|
|
60
|
+
- **流程内核**:公开任务入口只有 `task next`;阶段动作由内核动作表推荐对应 Skill,硬门禁由 runtime gate 执行,不再分发独立流程中枢文件或 Skill 注册控制面。
|
|
61
|
+
- **Skill 自带脚本**:只服务单个 Skill 的控制器或辅助脚本放在 `template/skills/<skill-id>/scripts/`,由 `.cowork-flow/run` 薄分发;`scripts/` 内核只保留任务导航、生命周期、gate、host/runtime、存储和分发所需代码。
|
|
61
62
|
|
|
62
63
|
## Skills 分发机制
|
|
63
64
|
|
|
64
|
-
Skills 维护在 `template/skills/` 唯一源码,`init`
|
|
65
|
+
Skills 维护在 `template/skills/` 唯一源码,`init` / `sync` 时按目录分发到对应平台;`SKILL.md`、可选的 command `manifest.json` 和 `scripts/` 一起归属该 Skill:
|
|
65
66
|
|
|
66
67
|
| 平台 | 目标目录 |
|
|
67
68
|
|---|---|
|
|
68
69
|
| `codex` / `opencode` | `.agents/skills/` |
|
|
69
70
|
| `claude-code` | `.claude/skills/` |
|
|
70
71
|
|
|
71
|
-
分发动作:`batch-
|
|
72
|
+
分发动作:`adversarial-review`、`agent-dispatch`、`batch-execution`、`brainstorming`、`cowork-flow`、`cowork-flow-maintenance`、`decision-audit`、`failure-analysis`、`game-design`、`party-mode`、`python-runtime-design`、`runtime-health`、`spec-sync`、`task-planning`、`task-review`、`test-first`
|
|
72
73
|
|
|
73
74
|
## CLI 命令
|
|
74
75
|
|
|
@@ -92,7 +93,7 @@ Skills 维护在 `template/skills/` 唯一源码,`init` 时按平台分发到
|
|
|
92
93
|
|
|
93
94
|
- **自动识别**已安装 host 目录,只同步对应平台资产
|
|
94
95
|
- **Skills** 从 `template/skills/` 按平台分发
|
|
95
|
-
- **保护文件**:`config.yaml`、`
|
|
96
|
+
- **保护文件**:`config.yaml`、`spec/`(除 `workflow-state-templates.md`)、任务、计划、变更、workspace
|
|
96
97
|
- **正式版旧资产清理**:旧脚本位置、旧 adapter 资产和已废弃文件按 Host Asset Manifest 的 `obsoleteFiles` 清理;用户保护文件保持不变
|
|
97
98
|
- **事务恢复**:上次未完成事务会在新一轮 sync 前恢复;事务元数据缺失或损坏时 fail-closed,不在未知状态上继续写入
|
|
98
99
|
- `--force` 整文件覆盖保护文件
|
|
@@ -106,6 +107,8 @@ cowork-flow install-zcode-plugin --force # 覆盖已安装
|
|
|
106
107
|
|
|
107
108
|
安装到 `~/.zcode/cli/plugins/cache/zcode-plugins-official/cowork-flow/<version>/`
|
|
108
109
|
|
|
110
|
+
ZCode 插件只安装 hook、skills 和轻量说明文件;`.cowork-flow/` 流程文件仍由显式 `cowork-flow init` / `cowork-flow sync` 在项目根目录管理。插件不会通过 scaffold 创建 `.cowork-flow/`,因此不会在多模块项目的模块目录重复落盘流程文件。
|
|
111
|
+
|
|
109
112
|
**Hook 注入内容:**
|
|
110
113
|
- `workflow-state` — 当前任务状态
|
|
111
114
|
- `contract-digest` — 合同摘要(SHA256 fingerprint)
|
|
@@ -117,19 +120,17 @@ cowork-flow install-zcode-plugin --force # 覆盖已安装
|
|
|
117
120
|
changes → brainstorming → read spec → plan → tasks → implement → check → complete
|
|
118
121
|
```
|
|
119
122
|
|
|
120
|
-
|
|
123
|
+
`./.cowork-flow/run task next` 是唯一公开任务流程入口。它读取当前状态,输出下一步 action、激活 Skill、runtime gate、blocker,以及可执行时的 `task next --run` 命令。
|
|
124
|
+
|
|
125
|
+
| action | 入口 | status 结果 |
|
|
121
126
|
|---|---|---|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
> Batch 使用任务图和持久化 Host action:运行
|
|
130
|
-
> `task start <parent-task> --auto --approved` 获取 `next_action`,
|
|
131
|
-
> Host 完成真实生命周期动作后用 `task batch-record-result <batch-id> --file <result.json>`
|
|
132
|
-
> 回写结果;失败会暂停,可用 `task batch-resume <batch-id>` 生成新的重试动作。
|
|
127
|
+
| `create_task` | `task next --run --title "<title>" --slug <name> --assignee <name>` | `planning` |
|
|
128
|
+
| `start_task` | `task next <dir> --run` | `in_progress` |
|
|
129
|
+
| `request_review` | `task next <dir> --run --intent review` | `review` |
|
|
130
|
+
| `complete_task` | `task next <dir> --run --intent review` | `completed` |
|
|
131
|
+
| `archive_task` | `task next <dir> --run --intent archive` | 归档副本保持 `completed` |
|
|
132
|
+
|
|
133
|
+
Batch 使用任务图和持久化 Host action:运行 `task next <parent-task> --run --intent batch --auto --approved` 获取 `next_action`;Host 完成真实生命周期动作后继续通过 `task next` 导航,不暴露独立 batch 子命令。
|
|
133
134
|
|
|
134
135
|
## 常用命令
|
|
135
136
|
|
|
@@ -140,16 +141,20 @@ changes → brainstorming → read spec → plan → tasks → implement → che
|
|
|
140
141
|
|
|
141
142
|
# 上下文
|
|
142
143
|
./.cowork-flow/run get-context
|
|
143
|
-
./.cowork-flow/run task list
|
|
144
144
|
./.cowork-flow/run task next
|
|
145
|
+
./.cowork-flow/run task next --json
|
|
146
|
+
./.cowork-flow/run task next --list
|
|
147
|
+
./.cowork-flow/run task next <dir> --validate
|
|
145
148
|
|
|
146
149
|
# 变更
|
|
147
150
|
./.cowork-flow/run change create <slug>
|
|
148
151
|
./.cowork-flow/run change validate <slug>
|
|
149
152
|
|
|
150
153
|
# 任务
|
|
151
|
-
./.cowork-flow/run task
|
|
152
|
-
./.cowork-flow/run task
|
|
154
|
+
./.cowork-flow/run task next --run --title "<title>" --slug <name> --assignee <name>
|
|
155
|
+
./.cowork-flow/run task next <dir> --run
|
|
156
|
+
./.cowork-flow/run task next <dir> --run --intent review
|
|
157
|
+
./.cowork-flow/run task next <dir> --run --intent archive
|
|
153
158
|
|
|
154
159
|
# 子代理
|
|
155
160
|
./.cowork-flow/run subagent init --role implement --agent-type cowork-implement --execution-task-dir <dir> --title "<title>"
|
|
@@ -170,14 +175,25 @@ runtime 发出的 host-neutral action、记录执行结果并纠偏漂移。
|
|
|
170
175
|
|
|
171
176
|
## 发布
|
|
172
177
|
|
|
178
|
+
测试按反馈速度和覆盖范围分层:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
npm run test:fast # 快速 Node 测试,等价于 npm test
|
|
182
|
+
npm run test:integration # init/sync 关键集成路径
|
|
183
|
+
npm run test:node:full # 完整 Node 测试
|
|
184
|
+
npm run test:template # 核心模板集成测试
|
|
185
|
+
npm run test:template:full # 完整模板 Python discovery
|
|
186
|
+
npm run test:all # 发布前全量测试与打包检查
|
|
187
|
+
```
|
|
188
|
+
|
|
173
189
|
```bash
|
|
174
190
|
npm run release # patch
|
|
175
191
|
npm run release -- minor # minor
|
|
176
192
|
```
|
|
177
193
|
|
|
178
194
|
**发布流程:**
|
|
179
|
-
1. `npm
|
|
180
|
-
2. 稳定性变更使用 `COWORK_TEMPLATE_TEST_REPEAT=3` 和固定 `COWORK_TEMPLATE_TEST_SEED`
|
|
195
|
+
1. `npm run test:all`、`git diff --check`
|
|
196
|
+
2. 稳定性变更使用 `COWORK_TEMPLATE_TEST_REPEAT=3` 和固定 `COWORK_TEMPLATE_TEST_SEED` 重复运行 `npm run test:template:full`
|
|
181
197
|
3. `npm version` 升级版本
|
|
182
198
|
4. 同步版本到 `template/.cowork-flow/.version` 和 `template/.zcode/.zcode-plugin/plugin.json`
|
|
183
199
|
5. `git commit` + `git tag`
|
|
@@ -191,5 +207,5 @@ Windows 上发布前使用 `run.cmd` 入口验证;POSIX shell 专属 release
|
|
|
191
207
|
|
|
192
208
|
- 以目标项目事实为准,不把模板内容当成项目事实
|
|
193
209
|
- 保留有价值的流程骨架,删除不存在的场景
|
|
194
|
-
- 项目差异写入 `AGENTS.md`、`
|
|
210
|
+
- 项目差异写入 `AGENTS.md`、`config.yaml`、`spec/` 或项目自有 Skill;不要恢复第二套流程中枢文档
|
|
195
211
|
- 不为了替换项目命令而改写通用 skill
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cowork-flow",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.44",
|
|
4
4
|
"description": "CLI for installing and maintaining cowork-flow collaboration templates.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,10 +16,14 @@
|
|
|
16
16
|
"!template/**/*.pyc"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
-
"test": "
|
|
20
|
-
"test:
|
|
19
|
+
"test": "npm run test:fast",
|
|
20
|
+
"test:fast": "node --test test/asset-plan.test.js test/cli.test.js test/host-assets.test.js test/opencode-plugin.test.js test/template-runner.test.js test/update.test.js test/zcode-plugin.test.js",
|
|
21
|
+
"test:integration": "node --test --test-name-pattern=\"^(init copies the template into a new target directory|sync updates safe template files and preserves protected files)$\" test/init.test.js test/sync.test.js",
|
|
22
|
+
"test:node:full": "node --test",
|
|
23
|
+
"test:template": "node scripts/run-template-tests.js --suite core",
|
|
24
|
+
"test:template:full": "node scripts/run-template-tests.js --suite full",
|
|
21
25
|
"pack:check": "node scripts/pack-check.js",
|
|
22
|
-
"test:all": "npm test && npm run test:template && npm run pack:check",
|
|
26
|
+
"test:all": "npm run test:node:full && npm run test:template:full && npm run pack:check",
|
|
23
27
|
"release": "sh scripts/release.sh"
|
|
24
28
|
},
|
|
25
29
|
"engines": {
|
|
@@ -72,7 +72,6 @@ export async function runInstallZCodePlugin(args = []) {
|
|
|
72
72
|
const { dryRun, force } = parseArgs(args);
|
|
73
73
|
const pluginSrc = join(templateRoot, ".zcode");
|
|
74
74
|
const skillsSrc = join(templateRoot, "skills");
|
|
75
|
-
const specSrc = join(templateRoot, ".cowork-flow", "spec");
|
|
76
75
|
const { version } = await readPackageInfo();
|
|
77
76
|
|
|
78
77
|
if (!(await pathExists(pluginSrc))) {
|
|
@@ -81,9 +80,6 @@ export async function runInstallZCodePlugin(args = []) {
|
|
|
81
80
|
if (!(await pathExists(skillsSrc))) {
|
|
82
81
|
throw new Error(`Skills source missing at ${skillsSrc}. Reinstall cowork-flow.`);
|
|
83
82
|
}
|
|
84
|
-
if (!(await pathExists(specSrc))) {
|
|
85
|
-
throw new Error(`Spec source missing at ${specSrc}. Reinstall cowork-flow.`);
|
|
86
|
-
}
|
|
87
83
|
|
|
88
84
|
const cacheRoot = await getZCodeCacheDir();
|
|
89
85
|
const destDir = join(cacheRoot, version);
|
|
@@ -98,7 +94,6 @@ export async function runInstallZCodePlugin(args = []) {
|
|
|
98
94
|
console.log(`[dry-run] Would install ZCode plugin:`);
|
|
99
95
|
console.log(` Plugin: ${pluginSrc} -> ${destDir}`);
|
|
100
96
|
console.log(` Skills: ${skillsSrc} -> ${join(destDir, 'skills')}`);
|
|
101
|
-
console.log(` Spec: ${specSrc} -> ${join(destDir, 'scaffold', '.cowork-flow', 'spec')}`);
|
|
102
97
|
return;
|
|
103
98
|
}
|
|
104
99
|
|
|
@@ -110,16 +105,9 @@ export async function runInstallZCodePlugin(args = []) {
|
|
|
110
105
|
// Copy plugin runtime (.zcode-plugin/, hooks/, runtime/, scaffold/) from .zcode/
|
|
111
106
|
await cp(pluginSrc, destDir, { recursive: true });
|
|
112
107
|
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
await writeFile(scaffoldVersionPath, `${version}\n`, "utf8");
|
|
117
|
-
|
|
118
|
-
// Materialize scaffold specs from the main template instead of maintaining
|
|
119
|
-
// a second static copy under template/.zcode/scaffold/.
|
|
120
|
-
const scaffoldSpecDest = join(destDir, "scaffold", ".cowork-flow", "spec");
|
|
121
|
-
await rm(scaffoldSpecDest, { recursive: true, force: true });
|
|
122
|
-
await cp(specSrc, scaffoldSpecDest, { recursive: true, force: true });
|
|
108
|
+
// ZCode may apply plugin scaffold files to each workspace folder. Keep
|
|
109
|
+
// workflow runtime files out of scaffold; explicit init/sync owns .cowork-flow.
|
|
110
|
+
await rm(join(destDir, "scaffold", ".cowork-flow"), { recursive: true, force: true });
|
|
123
111
|
|
|
124
112
|
// Sync canonical scripts from main template (single source of truth).
|
|
125
113
|
// The .zcode/hooks/runtime/scripts/ copy is stale; overwrite with the
|
package/src/lib/copy-template.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { constants } from 'node:fs';
|
|
2
|
-
import { access, readFile, readdir } from 'node:fs/promises';
|
|
2
|
+
import { access, readFile, readdir, stat } from 'node:fs/promises';
|
|
3
3
|
import { join, relative } from 'node:path';
|
|
4
4
|
|
|
5
5
|
import { createAssetPlan, planActions } from './asset-plan.js';
|
|
@@ -7,7 +7,6 @@ import { hostRegistry } from './host-assets.js';
|
|
|
7
7
|
import { applyAssetPlan } from './plan-applier.js';
|
|
8
8
|
import { templateRoot } from './paths.js';
|
|
9
9
|
import { shouldIncludeForPlatforms, skillDestinationForPlatform } from './platforms.js';
|
|
10
|
-
import { skillRegistry } from './skill-registry.js';
|
|
11
10
|
|
|
12
11
|
async function pathExists(path) {
|
|
13
12
|
try {
|
|
@@ -41,6 +40,83 @@ function toTemplatePath(relativePath) {
|
|
|
41
40
|
return relativePath.replaceAll('\\', '/');
|
|
42
41
|
}
|
|
43
42
|
|
|
43
|
+
async function listSkillDirs() {
|
|
44
|
+
const skillsRoot = join(templateRoot, 'skills');
|
|
45
|
+
const entries = await readdir(skillsRoot, { withFileTypes: true });
|
|
46
|
+
const skills = [];
|
|
47
|
+
for (const entry of entries) {
|
|
48
|
+
if (!entry.isDirectory()) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const skillRoot = join(skillsRoot, entry.name);
|
|
52
|
+
if (await pathExists(join(skillRoot, 'SKILL.md'))) {
|
|
53
|
+
skills.push({ id: entry.name, sourceRoot: skillRoot });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return skills.sort((left, right) => left.id.localeCompare(right.id));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function listSkillFiles(skill) {
|
|
60
|
+
const sourceRoot = skill.sourceRoot;
|
|
61
|
+
return (await listFiles(sourceRoot)).map((file) => ({
|
|
62
|
+
source: join(sourceRoot, file),
|
|
63
|
+
skillRelativePath: file
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function sourceMatchesDestination(source, destination) {
|
|
68
|
+
try {
|
|
69
|
+
const [sourceContent, targetContent, sourceStats, targetStats] = await Promise.all([
|
|
70
|
+
readFile(source),
|
|
71
|
+
readFile(destination),
|
|
72
|
+
stat(source),
|
|
73
|
+
stat(destination)
|
|
74
|
+
]);
|
|
75
|
+
return sourceContent.equals(targetContent)
|
|
76
|
+
&& (sourceStats.mode & 0o777) === (targetStats.mode & 0o777);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (error && error.code === 'ENOENT') {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function appendSkillFileActions(actions, {
|
|
86
|
+
targetDir,
|
|
87
|
+
platforms,
|
|
88
|
+
seen,
|
|
89
|
+
sync = false
|
|
90
|
+
}) {
|
|
91
|
+
for (const skill of await listSkillDirs()) {
|
|
92
|
+
const skillFiles = await listSkillFiles(skill);
|
|
93
|
+
for (const platform of platforms) {
|
|
94
|
+
const destBase = skillDestinationForPlatform(platform);
|
|
95
|
+
if (!destBase) continue;
|
|
96
|
+
for (const skillFile of skillFiles) {
|
|
97
|
+
const destination = join(
|
|
98
|
+
targetDir,
|
|
99
|
+
destBase,
|
|
100
|
+
skill.id,
|
|
101
|
+
skillFile.skillRelativePath
|
|
102
|
+
);
|
|
103
|
+
if (seen.has(destination)) continue;
|
|
104
|
+
seen.add(destination);
|
|
105
|
+
const exists = await pathExists(destination);
|
|
106
|
+
const unchanged = sync && exists
|
|
107
|
+
? await sourceMatchesDestination(skillFile.source, destination)
|
|
108
|
+
: false;
|
|
109
|
+
actions.push({
|
|
110
|
+
action: exists ? (sync ? (unchanged ? 'skip' : 'update') : 'skip') : 'create',
|
|
111
|
+
source: skillFile.source,
|
|
112
|
+
destination,
|
|
113
|
+
relativePath: join(destBase, skill.id, skillFile.skillRelativePath)
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
44
120
|
export async function buildInitPlan(targetDir, options = {}) {
|
|
45
121
|
const files = await listFiles(templateRoot);
|
|
46
122
|
const actions = [];
|
|
@@ -67,21 +143,7 @@ export async function buildInitPlan(targetDir, options = {}) {
|
|
|
67
143
|
actions.push({ action, source, destination, relativePath: file });
|
|
68
144
|
}
|
|
69
145
|
|
|
70
|
-
|
|
71
|
-
for (const platform of platforms) {
|
|
72
|
-
const destBase = skillDestinationForPlatform(platform);
|
|
73
|
-
if (!destBase) continue;
|
|
74
|
-
const dest = join(targetDir, destBase, entry.id, 'SKILL.md');
|
|
75
|
-
if (seen.has(dest)) continue;
|
|
76
|
-
seen.add(dest);
|
|
77
|
-
actions.push({
|
|
78
|
-
action: (await pathExists(dest)) ? 'skip' : 'create',
|
|
79
|
-
source: join(templateRoot, entry.source),
|
|
80
|
-
destination: dest,
|
|
81
|
-
relativePath: join(destBase, entry.id, 'SKILL.md')
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|
|
146
|
+
await appendSkillFileActions(actions, { targetDir, platforms, seen });
|
|
85
147
|
|
|
86
148
|
const versionDestination = join(targetDir, '.cowork-flow', '.version');
|
|
87
149
|
const versionExists = await pathExists(versionDestination);
|
|
@@ -144,6 +206,10 @@ function isSafeSyncFile(relativePath) {
|
|
|
144
206
|
|| templatePath.endsWith('/.gitkeep');
|
|
145
207
|
}
|
|
146
208
|
|
|
209
|
+
function isCoveredByDeletedParent(relativePath, deletedParents) {
|
|
210
|
+
return deletedParents.some((parent) => relativePath.startsWith(`${parent}/`));
|
|
211
|
+
}
|
|
212
|
+
|
|
147
213
|
function replaceManagedBlock(targetContent, templateContent) {
|
|
148
214
|
const targetStart = targetContent.indexOf(COWORK_FLOW_START);
|
|
149
215
|
const targetEnd = targetContent.indexOf(COWORK_FLOW_END, targetStart + COWORK_FLOW_START.length);
|
|
@@ -183,9 +249,22 @@ async function buildManagedBlockSyncAction({ source, destination, exists, option
|
|
|
183
249
|
return { action: 'protected', source, destination, relativePath };
|
|
184
250
|
}
|
|
185
251
|
|
|
252
|
+
if (content === targetContent) {
|
|
253
|
+
return { action: 'skip', source, destination, relativePath };
|
|
254
|
+
}
|
|
255
|
+
|
|
186
256
|
return { action: 'update', source, destination, relativePath, content };
|
|
187
257
|
}
|
|
188
258
|
|
|
259
|
+
async function buildFileSyncAction({ source, destination, relativePath }) {
|
|
260
|
+
return {
|
|
261
|
+
action: await sourceMatchesDestination(source, destination) ? 'skip' : 'update',
|
|
262
|
+
source,
|
|
263
|
+
destination,
|
|
264
|
+
relativePath
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
189
268
|
export async function buildSyncPlan(targetDir, options = {}) {
|
|
190
269
|
if (!await pathExists(join(targetDir, '.cowork-flow'))) {
|
|
191
270
|
throw new Error(`Target is not initialized: ${targetDir}`);
|
|
@@ -221,7 +300,11 @@ export async function buildSyncPlan(targetDir, options = {}) {
|
|
|
221
300
|
if (protectedFile) {
|
|
222
301
|
actions.push({ action: 'protected', source, destination, relativePath: file });
|
|
223
302
|
} else if (exists && (safeFile || options.force)) {
|
|
224
|
-
actions.push({
|
|
303
|
+
actions.push(await buildFileSyncAction({
|
|
304
|
+
source,
|
|
305
|
+
destination,
|
|
306
|
+
relativePath: file
|
|
307
|
+
}));
|
|
225
308
|
} else if (!exists) {
|
|
226
309
|
actions.push({ action: 'create', source, destination, relativePath: file });
|
|
227
310
|
} else {
|
|
@@ -229,66 +312,36 @@ export async function buildSyncPlan(targetDir, options = {}) {
|
|
|
229
312
|
}
|
|
230
313
|
}
|
|
231
314
|
|
|
232
|
-
|
|
233
|
-
for (const platform of platforms) {
|
|
234
|
-
const destBase = skillDestinationForPlatform(platform);
|
|
235
|
-
if (!destBase) continue;
|
|
236
|
-
const dest = join(targetDir, destBase, entry.id, 'SKILL.md');
|
|
237
|
-
if (seen.has(dest)) continue;
|
|
238
|
-
seen.add(dest);
|
|
239
|
-
const destExists = await pathExists(dest);
|
|
240
|
-
const safe = hostRegistry.skillTargets.some(
|
|
241
|
-
(target) => dest.startsWith(join(targetDir, target))
|
|
242
|
-
);
|
|
243
|
-
if (destExists && (safe || options.force)) {
|
|
244
|
-
actions.push({
|
|
245
|
-
action: 'update',
|
|
246
|
-
source: join(templateRoot, entry.source),
|
|
247
|
-
destination: dest,
|
|
248
|
-
relativePath: join(destBase, entry.id, 'SKILL.md')
|
|
249
|
-
});
|
|
250
|
-
} else if (!destExists) {
|
|
251
|
-
actions.push({
|
|
252
|
-
action: 'create',
|
|
253
|
-
source: join(templateRoot, entry.source),
|
|
254
|
-
destination: dest,
|
|
255
|
-
relativePath: join(destBase, entry.id, 'SKILL.md')
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
315
|
+
await appendSkillFileActions(actions, { targetDir, platforms, seen, sync: true });
|
|
260
316
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
317
|
+
const deletedObsoleteParents = [];
|
|
318
|
+
const obsoleteFiles = [...OBSOLETE_SYNC_FILES].sort((left, right) => {
|
|
319
|
+
if (left.length !== right.length) {
|
|
320
|
+
return left.length - right.length;
|
|
264
321
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
action: 'delete',
|
|
271
|
-
source: null,
|
|
272
|
-
destination,
|
|
273
|
-
relativePath
|
|
274
|
-
});
|
|
275
|
-
}
|
|
322
|
+
return left.localeCompare(right);
|
|
323
|
+
});
|
|
324
|
+
for (const file of obsoleteFiles) {
|
|
325
|
+
if (isCoveredByDeletedParent(file, deletedObsoleteParents)) {
|
|
326
|
+
continue;
|
|
276
327
|
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
for (const file of OBSOLETE_SYNC_FILES) {
|
|
280
328
|
const destination = join(targetDir, file);
|
|
281
329
|
if (await pathExists(destination)) {
|
|
330
|
+
deletedObsoleteParents.push(file);
|
|
282
331
|
actions.push({ action: 'delete', source: null, destination, relativePath: file });
|
|
283
332
|
}
|
|
284
333
|
}
|
|
285
334
|
|
|
335
|
+
const versionDestination = join(targetDir, '.cowork-flow', '.version');
|
|
336
|
+
const versionContent = `${options.version}\n`;
|
|
337
|
+
const versionUnchanged = await pathExists(versionDestination)
|
|
338
|
+
&& (await readFile(versionDestination, 'utf8')) === versionContent;
|
|
286
339
|
actions.push({
|
|
287
|
-
action: 'update',
|
|
340
|
+
action: versionUnchanged ? 'skip' : 'update',
|
|
288
341
|
source: null,
|
|
289
|
-
destination:
|
|
342
|
+
destination: versionDestination,
|
|
290
343
|
relativePath: '.cowork-flow/.version',
|
|
291
|
-
content:
|
|
344
|
+
content: versionContent
|
|
292
345
|
});
|
|
293
346
|
|
|
294
347
|
return createAssetPlan({
|
|
@@ -6,67 +6,23 @@ tools: Read, Write, Edit, Grep, Glob, LS, Bash, Skill
|
|
|
6
6
|
|
|
7
7
|
You are the `cowork-check` subagent.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Read and apply these Skills before review work:
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
- `.claude/skills/agent-dispatch/SKILL.md`
|
|
12
|
+
- `.claude/skills/task-review/SKILL.md`
|
|
13
|
+
- `.claude/skills/decision-audit/SKILL.md`
|
|
14
|
+
- `.claude/skills/spec-sync/SKILL.md`
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
cowork_runtime_context_id: <runtime_context_id>
|
|
16
|
-
cowork_host_context_key: <host_context_key>
|
|
17
|
-
```
|
|
16
|
+
Execution:
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
./.cowork-flow/run subagent bind <runtime_context_id> <host_context_key>
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
On Windows (cmd/PowerShell), use:
|
|
27
|
-
|
|
28
|
-
```cmd
|
|
29
|
-
.\.cowork-flow\run.cmd subagent bind <runtime_context_id> <host_context_key>
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
If the explicit bind fails, or if the bound runtime context is missing, closed,
|
|
33
|
-
invalid, or names another agent type, report `needs_context` and do not execute
|
|
34
|
-
the task.
|
|
35
|
-
|
|
36
|
-
Load context before checking:
|
|
37
|
-
1. Read the task directory from the bound runtime context.
|
|
38
|
-
2. Read `<task>/decision-anchor.md`.
|
|
39
|
-
3. Read the plan file linked from this task (check `<task>/task.json` `relatedFiles` for a plan path, or search `.cowork-flow/plans/` for a plan file referencing this task directory). Use the plan's Verify commands and Expected results as the checklist for each step.
|
|
40
|
-
4. Read `<task>/check.jsonl`.
|
|
41
|
-
5. Read each JSONL `file` entry from `<task>/check.jsonl`.
|
|
42
|
-
6. Read `<task>/quality-review.jsonl` if present and verify machine warning,
|
|
43
|
-
checklist, and Definition of Done evidence.
|
|
44
|
-
7. Read `git diff`.
|
|
45
|
-
8. Include `test_intent_review` in the review output for meaningful behavior
|
|
46
|
-
breaks coverage and shallow tests rejection.
|
|
47
|
-
|
|
48
|
-
Authoritative internal protocols:
|
|
49
|
-
- `.cowork-flow/spec/protocols/review.md`
|
|
50
|
-
- `.cowork-flow/spec/protocols/decision-review.md`
|
|
51
|
-
- `.cowork-flow/spec/protocols/spec-maintenance.md`
|
|
52
|
-
|
|
53
|
-
Apply their output contracts exactly. Review output must preserve
|
|
54
|
-
`acceptanceId`, `findings`, `test_intent_review`, `resolution`, and
|
|
55
|
-
`specUpdates`.
|
|
18
|
+
1. Follow `agent-dispatch` to bind runtime context. If binding fails, report `needs_context` and stop.
|
|
19
|
+
2. Read the task directory, `decision-anchor.md`, linked plan, the `check.jsonl` context index, every referenced `file` entry, and current `git diff`; do not write review conclusions to JSONL.
|
|
20
|
+
3. Apply `task-review` to verify scope, tests, specs, advisory facts, lifecycle facts, and Definition of Done coverage.
|
|
21
|
+
4. Fix only clearly in-scope issues; otherwise report findings with acceptance IDs, resolutions, `test_intent_review` (test intent review), and verification commands.
|
|
56
22
|
|
|
57
23
|
Rules:
|
|
58
|
-
|
|
24
|
+
|
|
59
25
|
- Do not use the Task tool or invoke subagents.
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
- Include test intent findings that map tests back to decision-anchor acceptance or
|
|
64
|
-
regression behavior.
|
|
65
|
-
- Run the deterministic coding gate before accepting quality:
|
|
66
|
-
`./.cowork-flow/run python .cowork-flow/scripts/common/gates/validate_coding_standards.py --validate --repo-root .`.
|
|
67
|
-
This gate enforces machine-decidable UTF-8/IO checks; backend/frontend
|
|
68
|
-
natural-language markdown remains checklist context, not dynamic hard validators.
|
|
69
|
-
- Treat machine warning output as review evidence: fix real issues or require
|
|
70
|
-
acknowledged warning records in `<task>/quality-review.jsonl`.
|
|
71
|
-
- Verify `<task>/quality-review.jsonl` covers Definition of Done, checklist
|
|
72
|
-
sources, affected files, and exact verification commands before acceptance.
|
|
26
|
+
- Do not run task start, finish, archive, unscoped resume, commit, or push.
|
|
27
|
+
- Treat backend/frontend natural-language specs as checklist context, not dynamic hard validators.
|
|
28
|
+
- Do not accept shallow tests that would still pass when target behavior breaks.
|
|
@@ -6,71 +6,24 @@ tools: Read, Write, Edit, Grep, Glob, LS, Bash, Skill
|
|
|
6
6
|
|
|
7
7
|
You are the `cowork-implement` subagent.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Read and apply these Skills before task work:
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
- `.claude/skills/agent-dispatch/SKILL.md`
|
|
12
|
+
- `.claude/skills/decision-audit/SKILL.md`
|
|
13
|
+
- `.claude/skills/spec-sync/SKILL.md`
|
|
14
|
+
- `.claude/skills/test-first/SKILL.md` for behavior changes
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
cowork_runtime_context_id: <runtime_context_id>
|
|
16
|
-
cowork_host_context_key: <host_context_key>
|
|
17
|
-
```
|
|
16
|
+
Execution:
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
On Windows (cmd/PowerShell), use:
|
|
27
|
-
|
|
28
|
-
```cmd
|
|
29
|
-
.\.cowork-flow\run.cmd subagent bind <runtime_context_id> <host_context_key>
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
If the explicit bind fails, or if the bound runtime context is missing, closed,
|
|
33
|
-
invalid, or names another agent type, report `needs_context` and do not execute
|
|
34
|
-
the task.
|
|
35
|
-
|
|
36
|
-
Load context before editing:
|
|
37
|
-
1. Read the task directory from the bound runtime context.
|
|
38
|
-
2. Read `<task>/decision-anchor.md`.
|
|
39
|
-
3. Read `<task>/info.md` if present.
|
|
40
|
-
4. Read `<task>/implement.jsonl`.
|
|
41
|
-
5. Read each JSONL `file` entry.
|
|
42
|
-
6. Read the plan file linked from this task (check `<task>/task.json` `relatedFiles` for a plan path, or search `.cowork-flow/plans/` for a plan file referencing this task directory). Follow the plan steps in order — each step has Files, Action, Verify, and Expected fields.
|
|
43
|
-
7. Read quality source entries from context; backend/frontend natural-language
|
|
44
|
-
specs are review checklists, not dynamic hard validators.
|
|
45
|
-
8. For behavior-change tasks, create or verify `<task>/tdd.jsonl` before
|
|
46
|
-
implementation or record a documented exemption.
|
|
47
|
-
9. Before reporting completion, write `<task>/quality-review.jsonl` with
|
|
48
|
-
checklist, machine warning, and Definition of Done evidence.
|
|
49
|
-
|
|
50
|
-
Authoritative internal protocols:
|
|
51
|
-
- `.cowork-flow/spec/protocols/tdd.md`
|
|
52
|
-
- `.cowork-flow/spec/protocols/decision-review.md`
|
|
53
|
-
- `.cowork-flow/spec/protocols/spec-maintenance.md`
|
|
54
|
-
|
|
55
|
-
Apply their output contracts exactly. Implementation reports and `tdd.jsonl`
|
|
56
|
-
must preserve `acceptanceId`, `redCommand`, `redExitCode`, `greenCommand`,
|
|
57
|
-
`greenExitCode`, and `specUpdates`.
|
|
18
|
+
1. Follow `agent-dispatch` to bind runtime context. If binding fails, report `needs_context` and stop.
|
|
19
|
+
2. Read the task directory, `decision-anchor.md`, optional `info.md`, `implement.jsonl`, every JSONL `file` entry, and the linked plan.
|
|
20
|
+
3. Follow the plan in order, keeping edits inside assigned scope.
|
|
21
|
+
4. Use project specs and quality sources as checklist context; runtime gates remain kernel-owned commands.
|
|
22
|
+
5. Run planned verification and report changed files, acceptance IDs, verification commands, and spec updates or why none were needed.
|
|
58
23
|
|
|
59
24
|
Rules:
|
|
25
|
+
|
|
60
26
|
- Do not use the Task tool or invoke subagents.
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
- Keep edits inside requested scope.
|
|
65
|
-
- Do not treat shallow tests as TDD evidence; red-green-refactor proof must
|
|
66
|
-
include redCommand, redExitCode, greenCommand, greenExitCode, and
|
|
67
|
-
decision-anchor acceptance ID mapping.
|
|
68
|
-
- Report changed files and exact verification commands.
|
|
69
|
-
- Before editing source files, run the deterministic coding gate:
|
|
70
|
-
`./.cowork-flow/run python .cowork-flow/scripts/common/gates/validate_coding_standards.py --validate --repo-root .`.
|
|
71
|
-
This gate enforces machine-decidable UTF-8/IO checks; backend/frontend
|
|
72
|
-
natural-language markdown remains checklist context, not dynamic hard validators.
|
|
73
|
-
- Fix machine warning findings or record acknowledged warning evidence in
|
|
74
|
-
`<task>/quality-review.jsonl`.
|
|
75
|
-
- Record Definition of Done and quality checklist evidence in
|
|
76
|
-
`<task>/quality-review.jsonl`.
|
|
27
|
+
- Do not run task start, finish, archive, unscoped resume, commit, or push.
|
|
28
|
+
- Do not create task-local review artifacts, `tdd.jsonl`, or TDD evidence records in `check.jsonl`.
|
|
29
|
+
- Do not claim completion without current verification.
|