cowork-flow 0.0.16 → 0.0.17

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.
Files changed (98) hide show
  1. package/README.md +34 -20
  2. package/package.json +1 -1
  3. package/src/cli.js +18 -2
  4. package/src/commands/init.js +155 -35
  5. package/src/lib/copy-template.js +3 -26
  6. package/template/.agent/skills/before-dev/SKILL.md +31 -0
  7. package/template/.agent/skills/brainstorming/SKILL.md +17 -156
  8. package/template/.agent/skills/break-loop/SKILL.md +16 -121
  9. package/template/.agent/skills/check/SKILL.md +29 -0
  10. package/template/.agent/skills/continue/SKILL.md +29 -0
  11. package/template/.agent/skills/entry-boundary/SKILL.md +49 -0
  12. package/template/.agent/skills/finish-work/SKILL.md +21 -152
  13. package/template/.agent/skills/meta/SKILL.md +30 -0
  14. package/template/.agent/skills/python-design/SKILL.md +27 -0
  15. package/template/.agent/skills/start/SKILL.md +33 -67
  16. package/template/.agent/skills/update-spec/SKILL.md +24 -320
  17. package/template/.agent/skills/writing-plans/SKILL.md +37 -127
  18. package/template/.codex/agents/cowork-check.toml +49 -0
  19. package/template/.codex/agents/cowork-implement.toml +51 -0
  20. package/template/.codex/agents/cowork-research.toml +45 -0
  21. package/template/.codex/config.toml +10 -0
  22. package/template/.codex/hooks/inject-workflow-state.py +140 -0
  23. package/template/.codex/hooks.json +15 -0
  24. package/template/.cowork-flow/.version +1 -1
  25. package/template/.cowork-flow/config.yaml +14 -26
  26. package/template/.cowork-flow/scripts/add_session.py +2 -2
  27. package/template/.cowork-flow/scripts/change.py +8 -1
  28. package/template/.cowork-flow/scripts/common/__init__.py +0 -6
  29. package/template/.cowork-flow/scripts/common/active_task.py +167 -0
  30. package/template/.cowork-flow/scripts/common/config.py +13 -18
  31. package/template/.cowork-flow/scripts/common/execution_context.py +151 -12
  32. package/template/.cowork-flow/scripts/common/git_context.py +53 -70
  33. package/template/.cowork-flow/scripts/common/paths.py +0 -119
  34. package/template/.cowork-flow/scripts/doctor.py +118 -0
  35. package/template/.cowork-flow/scripts/resume.py +14 -1
  36. package/template/.cowork-flow/scripts/run.py +6 -5
  37. package/template/.cowork-flow/scripts/subagent.py +379 -0
  38. package/template/.cowork-flow/scripts/task.py +92 -135
  39. package/template/.cowork-flow/spec/backend/database-guidelines.md +15 -18
  40. package/template/.cowork-flow/spec/backend/index.md +16 -13
  41. package/template/.cowork-flow/spec/backend/quality-guidelines.md +14 -13
  42. package/template/.cowork-flow/spec/frontend/index.md +20 -9
  43. package/template/.cowork-flow/spec/frontend/quality-guidelines.md +14 -12
  44. package/template/.cowork-flow/workflow.md +172 -284
  45. package/template/.cowork-flow/workspace/index.md +12 -5
  46. package/template/AGENTS.md +9 -16
  47. package/template/.agent/skills/agent-team-execution/SKILL.md +0 -79
  48. package/template/.agent/skills/brainstorming/scripts/frame-template.html +0 -214
  49. package/template/.agent/skills/brainstorming/scripts/helper.js +0 -88
  50. package/template/.agent/skills/brainstorming/scripts/server.cjs +0 -354
  51. package/template/.agent/skills/brainstorming/scripts/start-server.sh +0 -148
  52. package/template/.agent/skills/brainstorming/scripts/stop-server.sh +0 -56
  53. package/template/.agent/skills/brainstorming/spec-document-reviewer-prompt.md +0 -49
  54. package/template/.agent/skills/brainstorming/visual-companion.md +0 -287
  55. package/template/.agent/skills/check-cross-layer/SKILL.md +0 -158
  56. package/template/.agent/skills/record-session/SKILL.md +0 -78
  57. package/template/.agent/skills/requesting-code-review/SKILL.md +0 -103
  58. package/template/.agent/skills/requesting-code-review/code-reviewer.md +0 -168
  59. package/template/.agent/skills/subagent-driven-development/SKILL.md +0 -279
  60. package/template/.agent/skills/subagent-driven-development/code-quality-reviewer-prompt.md +0 -25
  61. package/template/.agent/skills/subagent-driven-development/implementer-prompt.md +0 -113
  62. package/template/.agent/skills/subagent-driven-development/spec-reviewer-prompt.md +0 -61
  63. package/template/.agent/skills/writing-plans/plan-document-reviewer-prompt.md +0 -49
  64. package/template/.cowork-flow/agent-team/adapters.yaml +0 -15
  65. package/template/.cowork-flow/agent-team/agents.yaml +0 -120
  66. package/template/.cowork-flow/agent-team/policy.yaml +0 -23
  67. package/template/.cowork-flow/scripts/agent_team.py +0 -681
  68. package/template/.cowork-flow/scripts/common/agent_team.py +0 -626
  69. package/template/.superpowers/dispatching-parallel-agents/SKILL.md +0 -182
  70. package/template/.superpowers/executing-plans/SKILL.md +0 -72
  71. package/template/.superpowers/finishing-a-development-branch/SKILL.md +0 -251
  72. package/template/.superpowers/receiving-code-review/SKILL.md +0 -213
  73. package/template/.superpowers/systematic-debugging/CREATION-LOG.md +0 -119
  74. package/template/.superpowers/systematic-debugging/SKILL.md +0 -296
  75. package/template/.superpowers/systematic-debugging/condition-based-waiting-example.ts +0 -158
  76. package/template/.superpowers/systematic-debugging/condition-based-waiting.md +0 -115
  77. package/template/.superpowers/systematic-debugging/defense-in-depth.md +0 -122
  78. package/template/.superpowers/systematic-debugging/find-polluter.sh +0 -63
  79. package/template/.superpowers/systematic-debugging/root-cause-tracing.md +0 -169
  80. package/template/.superpowers/systematic-debugging/test-academic.md +0 -14
  81. package/template/.superpowers/systematic-debugging/test-pressure-1.md +0 -58
  82. package/template/.superpowers/systematic-debugging/test-pressure-2.md +0 -68
  83. package/template/.superpowers/systematic-debugging/test-pressure-3.md +0 -69
  84. package/template/.superpowers/test-driven-development/SKILL.md +0 -371
  85. package/template/.superpowers/test-driven-development/testing-anti-patterns.md +0 -299
  86. package/template/.superpowers/using-git-worktrees/SKILL.md +0 -215
  87. package/template/.superpowers/using-superpowers/SKILL.md +0 -117
  88. package/template/.superpowers/using-superpowers/references/codex-tools.md +0 -59
  89. package/template/.superpowers/using-superpowers/references/copilot-tools.md +0 -42
  90. package/template/.superpowers/using-superpowers/references/gemini-tools.md +0 -51
  91. package/template/.superpowers/verification-before-completion/SKILL.md +0 -139
  92. package/template/.superpowers/writing-skills/SKILL.md +0 -655
  93. package/template/.superpowers/writing-skills/anthropic-best-practices.md +0 -1150
  94. package/template/.superpowers/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
  95. package/template/.superpowers/writing-skills/graphviz-conventions.dot +0 -172
  96. package/template/.superpowers/writing-skills/persuasion-principles.md +0 -187
  97. package/template/.superpowers/writing-skills/render-graphs.js +0 -168
  98. package/template/.superpowers/writing-skills/testing-skills-with-subagents.md +0 -384
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  cowork-flow 是一个用于新项目初始化协作流程的模板仓库。它把项目说明、任务流转、规格治理、开发计划和会话记录放在一套可复制的目录结构里,帮助团队在项目早期就建立清晰的工作闭环。
4
4
 
5
- 这个仓库本身不绑定具体技术栈,也不提供业务代码脚手架。它提供的是协作与治理基础设施:你可以把 `template/` 复制到目标项目中,再按目标项目的真实情况补充技术栈、验证命令、目录规范和提交策略。
5
+ 这个仓库本身不绑定具体技术栈,也不提供业务代码脚手架。它提供的是协作与治理基础设施:你可以把 `template/` 复制到目标项目中,再按目标项目的真实情况补充技术栈、质量门禁、目录规范和提交策略。
6
6
 
7
7
  ## 适用场景
8
8
 
@@ -23,12 +23,13 @@ cowork-flow 是一个用于新项目初始化协作流程的模板仓库。它
23
23
  ├── README.md
24
24
  └── template/
25
25
  ├── AGENTS.md
26
+ ├── .codex/
27
+ │ └── agents/
26
28
  ├── .agent/
27
29
  │ └── skills/
28
30
  └── .cowork-flow/
29
31
  ├── config.yaml
30
32
  ├── workflow.md
31
- ├── agent-team/
32
33
  ├── scripts/
33
34
  ├── spec/
34
35
  ├── changes/
@@ -43,10 +44,16 @@ cowork-flow 是一个用于新项目初始化协作流程的模板仓库。它
43
44
  项目级协作入口,包含编码前思考、简单优先、外科手术式改动、验证优先等基础原则。接入项目后,应把项目名称、技术栈、运行命令、测试命令和提交策略补齐。
44
45
 
45
46
  `template/.agent/skills/`
46
- 本地技能入口,覆盖开始工作、收尾验证、记录 session、更新规范、跨层检查等常见协作动作。这里的 skill 应保持通用,不承载某个业务项目的一次性细节。
47
+ 本地技能入口,覆盖 start、before-dev、brainstorming、writing-plans、check、finish-work、continue、meta、python-design、update-spec 和 break-loop 等协作动作。这里的 skill 应保持通用,不承载某个业务项目的一次性细节。
48
+
49
+ `template/.codex/agents/`
50
+ 固定角色 agent 定义,包含 `cowork-research`、`cowork-implement` 和 `cowork-check`。主会话负责计划与收口,并用 Codex `spawn_agent` 派发固定 agent;派发必须使用 `fork_turns="none"`,提示词首行使用 `Active task: <task-dir>`。
51
+
52
+ `template/.codex/config.toml`、`template/.codex/hooks.json`、`template/.codex/hooks/`
53
+ Codex 项目级配置与每轮上下文注入入口。hook 会读取当前 session task、`.cowork-flow/workflow.md` 中的 `workflow-state` 片段和 `codex.dispatch_mode`,把流程状态注入到当前轮对话。
47
54
 
48
55
  `template/.cowork-flow/`
49
- 工作流目录,包含流程说明、任务状态、开发者工作区、项目规范、行为变更规格、实现计划和辅助脚本。`.cowork-flow/config.yaml` 用于填写项目自己的 lint、build、test 等验证命令。
56
+ 工作流目录,包含流程说明、任务状态、开发者工作区、项目规范、行为变更规格、实现计划和辅助脚本。`.cowork-flow/config.yaml` 只承载真实接线的 session/journal, Codex hint, and task lifecycle hook settings。
50
57
 
51
58
  `template/.cowork-flow/spec/`
52
59
  项目规范目录,预置了 backend、frontend 和 guides 三类说明。接入时应按项目事实保留、改写或删除对应规范。
@@ -57,9 +64,6 @@ cowork-flow 是一个用于新项目初始化协作流程的模板仓库。它
57
64
  `template/.cowork-flow/plans/`
58
65
  保存可执行步骤、验证方式和执行状态。
59
66
 
60
- `template/.cowork-flow/agent-team/`
61
- 保存 agent team 的项目级 registry、适配器和策略。默认适配器是 `codex`,由主 agent 调度 Codex 子 agent;没有子 agent 能力时可退回 `manual` 提示词模式。
62
-
63
67
  ## 快速开始
64
68
 
65
69
  使用 CLI 把模板内容安装到目标项目根目录:
@@ -68,17 +72,23 @@ cowork-flow 是一个用于新项目初始化协作流程的模板仓库。它
68
72
  npx cowork-flow init ./my-project
69
73
  ```
70
74
 
75
+ `init` 会显式要求开发者身份。交互式终端会提示输入;脚本或 CI 请传入:
76
+
77
+ ```bash
78
+ npx cowork-flow init ./my-project --developer <your-name>
79
+ ```
80
+
71
81
  也可以先全局安装:
72
82
 
73
83
  ```bash
74
84
  npm install -g cowork-flow
75
- cowork-flow init ./my-project
85
+ cowork-flow init ./my-project --developer <your-name>
76
86
  ```
77
87
 
78
88
  初始化后优先完成这些配置:
79
89
 
80
90
  1. 更新 `AGENTS.md` 中的项目名称、技术栈、命令和提交策略。
81
- 2. 更新 `.cowork-flow/config.yaml` 中的验证命令。
91
+ 2. 按需调整 `.cowork-flow/config.yaml` 中的 session/journal, Codex hint, and task lifecycle hook settings。
82
92
  3. 更新 `.cowork-flow/workflow.md` 中与项目流程不一致的门禁、分级和完成定义。
83
93
  4. 按项目实际情况调整 `.cowork-flow/spec/`,删除不存在的 frontend、backend 或行为变更场景。
84
94
  5. 按团队实践使用 `.cowork-flow/changes/` 管理规格变更,使用 `.cowork-flow/plans/` 管理实现计划和验证状态。
@@ -97,8 +107,7 @@ npx cowork-flow --help
97
107
  cowork-flow init ./my-project
98
108
  ```
99
109
 
100
- `init` 会询问你是否已经安装了 Superpowers skills。选择未安装时,会把内置的 `.superpowers/` 技能复制到目标项目的 `.agent/skills/` 下。
101
- 在非交互环境里,这一步会自动跳过询问并默认视为已安装。
110
+ `init` 会直接复制模板中的 `.agent/skills/`、`.codex/` 和 `.cowork-flow/`,并初始化 `.cowork-flow/.developer` 与 `.cowork-flow/workspace/<developer>/`。交互式终端会提示输入开发者名称;非交互式环境必须传入 `--developer <name>`。`init` 不会复制额外技能包。
102
111
 
103
112
  初始化到当前项目:
104
113
 
@@ -115,9 +124,11 @@ cowork-flow init ./my-project --dry-run
115
124
  需要明确覆盖已有文件时使用:
116
125
 
117
126
  ```bash
118
- cowork-flow init ./my-project --force
127
+ cowork-flow init ./my-project --force --developer <your-name>
119
128
  ```
120
129
 
130
+ `--force` 不会静默覆盖既有 `.cowork-flow/.developer`;如需重设身份,请先显式处理旧身份文件。
131
+
121
132
  升级 CLI 本身:
122
133
 
123
134
  ```bash
@@ -176,18 +187,21 @@ cowork-flow sync . --dry-run
176
187
  ./.cowork-flow/run task start <task-dir>
177
188
  ```
178
189
 
179
- 执行 plan 时准备 agent team:
190
+ 执行 plan 时使用固定 cowork agents:
180
191
 
181
- 默认 `agent_team.enabled: false`。运行 `agent-team prepare/status/next/record-result/record-review/retry/complete` 前,先在 `.cowork-flow/config.yaml` 中设置 `agent_team.enabled: true`。
192
+ 主会话负责创建/启动任务、维护计划与收口验证;可并行的实现或检查工作通过 Codex subagent 交给固定角色 agent。
182
193
 
183
- ```bash
184
- ./.cowork-flow/run agent-team init
185
- ./.cowork-flow/run agent-team prepare <task-dir> --plan <plan-file>
186
- ./.cowork-flow/run agent-team next <task-dir>
187
- ./.cowork-flow/run agent-team complete <task-dir>
194
+ ```python
195
+ spawn_agent(
196
+ agent_type="cowork-implement",
197
+ fork_turns="none",
198
+ message="Active task: <task-dir>\n\n<assignment>",
199
+ )
188
200
  ```
189
201
 
190
- `agent-team` 命令会生成任务目录内的 dispatch plan、assignments、状态、审阅和 metrics 工件。默认 `codex` 适配器采用主 agent 调度型:脚本生成 Codex-ready 分派文件,主 agent 负责调用子 agent、协调并回写结果。
202
+ 默认角色为 `cowork-research`、`cowork-implement`、`cowork-check`,任务上下文由 agent 根据 active task 自行加载。主会话必须用 `wait_agent` 等待结果,验收输出,再用 `list_agents` / `close_agent` 收口。
203
+
204
+ Codex hook 启用后,每轮会自动注入 `<workflow-state>`,其中包含当前任务、状态来源和下一步流程提示。hook 不替代主会话验收;它只负责把 task 状态和 workflow gate 放进上下文。
191
205
 
192
206
  记录 session:
193
207
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cowork-flow",
3
- "version": "0.0.16",
3
+ "version": "0.0.17",
4
4
  "description": "CLI for installing and maintaining cowork-flow collaboration templates.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -1,3 +1,6 @@
1
+ import { stdin as input, stdout as output } from 'node:process';
2
+ import { createInterface } from 'node:readline/promises';
3
+
1
4
  import { runInit } from './commands/init.js';
2
5
  import { runSync } from './commands/sync.js';
3
6
  import { runUpdate } from './commands/update.js';
@@ -6,7 +9,7 @@ import { readPackageInfo } from './lib/package-info.js';
6
9
  const HELP = `cowork-flow
7
10
 
8
11
  Usage:
9
- cowork-flow init [target] [--dry-run] [--force]
12
+ cowork-flow init [target] [--developer <name>] [--dry-run] [--force]
10
13
  cowork-flow update [--global] [--yes]
11
14
  cowork-flow sync [target] [--dry-run] [--force]
12
15
  cowork-flow --version
@@ -24,8 +27,21 @@ function defaultIo() {
24
27
  };
25
28
  }
26
29
 
30
+ async function defaultPrompt(message) {
31
+ if (!input.isTTY || !output.isTTY) {
32
+ return null;
33
+ }
34
+ const readline = createInterface({ input, output });
35
+ try {
36
+ return await readline.question(message);
37
+ } finally {
38
+ readline.close();
39
+ }
40
+ }
41
+
27
42
  export async function main(argv = process.argv.slice(2), options = {}) {
28
43
  const io = options.io ?? defaultIo();
44
+ const prompt = Object.hasOwn(options, 'prompt') ? options.prompt : defaultPrompt;
29
45
  const [command, ...args] = argv;
30
46
 
31
47
  try {
@@ -41,7 +57,7 @@ export async function main(argv = process.argv.slice(2), options = {}) {
41
57
  }
42
58
 
43
59
  if (command === 'init') {
44
- return await runInit(args, { io, prompt: options.prompt });
60
+ return await runInit(args, { io, prompt });
45
61
  }
46
62
 
47
63
  if (command === 'sync') {
@@ -1,21 +1,30 @@
1
- import { resolve } from 'node:path';
2
- import { createInterface } from 'node:readline/promises';
1
+ import { access, mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { join, resolve } from 'node:path';
3
3
 
4
4
  import {
5
5
  applyPlan,
6
6
  buildInitPlan,
7
- buildSuperpowersPlan,
8
7
  summarizePlan
9
8
  } from '../lib/copy-template.js';
10
9
  import { readPackageInfo } from '../lib/package-info.js';
11
10
 
12
11
  function parseInitArgs(args) {
13
- const options = { dryRun: false, force: false, target: process.cwd() };
14
- for (const arg of args) {
12
+ const options = { developer: null, dryRun: false, force: false, target: process.cwd() };
13
+ for (let index = 0; index < args.length; index += 1) {
14
+ const arg = args[index];
15
15
  if (arg === '--dry-run') {
16
16
  options.dryRun = true;
17
17
  } else if (arg === '--force') {
18
18
  options.force = true;
19
+ } else if (arg === '--developer') {
20
+ const value = args[index + 1];
21
+ if (!value || value.startsWith('--')) {
22
+ throw new Error('Missing value for --developer');
23
+ }
24
+ options.developer = value;
25
+ index += 1;
26
+ } else if (arg.startsWith('--developer=')) {
27
+ options.developer = arg.slice('--developer='.length);
19
28
  } else if (arg.startsWith('--')) {
20
29
  throw new Error(`Unknown init option: ${arg}`);
21
30
  } else {
@@ -25,27 +34,139 @@ function parseInitArgs(args) {
25
34
  return options;
26
35
  }
27
36
 
28
- function isAffirmative(answer) {
29
- const normalized = answer.trim().toLowerCase();
30
- return normalized === 'y' || normalized === 'yes' || normalized === 'true' || normalized === '1';
37
+ async function pathExists(path) {
38
+ try {
39
+ await access(path);
40
+ return true;
41
+ } catch (error) {
42
+ if (error && error.code === 'ENOENT') {
43
+ return false;
44
+ }
45
+ throw error;
46
+ }
31
47
  }
32
48
 
33
- async function defaultSuperpowersPrompt(io) {
34
- if (!process.stdin.isTTY || !process.stdout.isTTY) {
35
- io.writeOut('Superpowers prompt skipped because stdin is not interactive.\n');
36
- return true;
49
+ function normalizeDeveloperName(value) {
50
+ const name = String(value ?? '').trim();
51
+ if (!name) {
52
+ throw new Error('Developer name required. Run: cowork-flow init <target> --developer <name>');
53
+ }
54
+ if (/[\\/]/.test(name)) {
55
+ throw new Error('Developer name must not contain path separators');
37
56
  }
57
+ return name;
58
+ }
38
59
 
39
- const rl = createInterface({
40
- input: process.stdin,
41
- output: process.stdout
42
- });
60
+ async function readExistingDeveloper(target) {
61
+ const developerFile = join(target, '.cowork-flow', '.developer');
62
+ if (!await pathExists(developerFile)) {
63
+ return null;
64
+ }
65
+ const content = await readFile(developerFile, 'utf8');
66
+ const match = content.match(/^name=(.+)$/m);
67
+ return match ? match[1].trim() : null;
68
+ }
43
69
 
44
- try {
45
- const answer = await rl.question('Have you already installed Superpowers skills? [y/N] ');
46
- return isAffirmative(answer);
47
- } finally {
48
- rl.close();
70
+ async function resolveDeveloperName(options, prompt) {
71
+ const existing = await readExistingDeveloper(options.target);
72
+ if (existing) {
73
+ return { existing: true, name: existing };
74
+ }
75
+
76
+ if (options.dryRun && !options.developer) {
77
+ return { existing: false, name: null };
78
+ }
79
+
80
+ let name = options.developer;
81
+ if (!name && typeof prompt === 'function') {
82
+ name = await prompt('Developer name: ');
83
+ }
84
+
85
+ return { existing: false, name: normalizeDeveloperName(name) };
86
+ }
87
+
88
+ function todayIsoDate() {
89
+ return new Date().toISOString().slice(0, 10);
90
+ }
91
+
92
+ function initialJournalContent(name) {
93
+ return `# Development Journal - ${name} (Part 1)
94
+
95
+ > AI development session journal
96
+ > Start date: ${todayIsoDate()}
97
+
98
+ ---
99
+
100
+ `;
101
+ }
102
+
103
+ function initialIndexContent(name) {
104
+ return `# Workspace Index - ${name}
105
+
106
+ > Tracks AI development session records.
107
+
108
+ ---
109
+
110
+ ## Current Status
111
+
112
+ <!-- @@@auto:current-status -->
113
+ - **Current file**: \`journal-1.md\`
114
+ - **Total Sessions**: 0
115
+ - **Last Active**: -
116
+ <!-- @@@/auto:current-status -->
117
+
118
+ ---
119
+
120
+ ## Active Documents
121
+
122
+ <!-- @@@auto:active-documents -->
123
+ | File | Lines | Status |
124
+ |------|------|------|
125
+ | \`journal-1.md\` | ~0 | Current |
126
+ <!-- @@@/auto:active-documents -->
127
+
128
+ ---
129
+
130
+ ## Session History
131
+
132
+ <!-- @@@auto:session-history -->
133
+ | # | Date | Title | Commit |
134
+ |---|------|------|------|
135
+ <!-- @@@/auto:session-history -->
136
+
137
+ ---
138
+
139
+ ## Notes
140
+
141
+ - Sessions are appended to the journal file
142
+ - A new journal file is created automatically after the current file exceeds 2000 lines
143
+ - Use \`add_session.py\` to record sessions
144
+ - New records use English text; legacy records can remain as they are
145
+ `;
146
+ }
147
+
148
+ async function initializeDeveloper(target, developer) {
149
+ const workflowDir = join(target, '.cowork-flow');
150
+ const developerFile = join(workflowDir, '.developer');
151
+ const workspaceDir = join(workflowDir, 'workspace', developer.name);
152
+ const journalFile = join(workspaceDir, 'journal-1.md');
153
+ const indexFile = join(workspaceDir, 'index.md');
154
+
155
+ await mkdir(workflowDir, { recursive: true });
156
+ if (!developer.existing) {
157
+ await writeFile(
158
+ developerFile,
159
+ `name=${developer.name}\ninitialized_at=${new Date().toISOString()}\n`,
160
+ 'utf8'
161
+ );
162
+ }
163
+
164
+ await mkdir(workspaceDir, { recursive: true });
165
+ if (!await pathExists(journalFile)) {
166
+ await writeFile(journalFile, initialJournalContent(developer.name), 'utf8');
167
+ }
168
+ if (!await pathExists(indexFile)) {
169
+ await writeFile(indexFile, initialIndexContent(developer.name), 'utf8');
49
170
  }
50
171
  }
51
172
 
@@ -53,8 +174,9 @@ export async function runInit(args, { io, prompt }) {
53
174
  return runInitWithOptions(args, { io, prompt });
54
175
  }
55
176
 
56
- export async function runInitWithOptions(args, { io, prompt = defaultSuperpowersPrompt }) {
177
+ export async function runInitWithOptions(args, { io, prompt }) {
57
178
  const options = parseInitArgs(args);
179
+ const developer = await resolveDeveloperName(options, prompt);
58
180
  const packageInfo = await readPackageInfo();
59
181
  const plan = await buildInitPlan(options.target, {
60
182
  force: options.force,
@@ -65,24 +187,22 @@ export async function runInitWithOptions(args, { io, prompt = defaultSuperpowers
65
187
  io.writeOut(summarizePlan(plan, options.dryRun));
66
188
 
67
189
  if (options.dryRun) {
68
- io.writeOut('Superpowers prompt skipped in dry-run.\n');
190
+ if (developer.existing) {
191
+ io.writeOut(`dry-run preserve-existing=.cowork-flow/.developer for developer ${developer.name}\n`);
192
+ } else if (developer.name) {
193
+ io.writeOut(`dry-run would-create=.cowork-flow/.developer for developer ${developer.name}\n`);
194
+ io.writeOut(`dry-run would-create=.cowork-flow/workspace/${developer.name}/\n`);
195
+ }
69
196
  io.writeOut('Next: update AGENTS.md and .cowork-flow/config.yaml for this project.\n');
70
197
  return 0;
71
198
  }
72
199
 
73
- const alreadyInstalled = await prompt(io);
74
- if (alreadyInstalled) {
75
- io.writeOut('Superpowers skills already installed; skipping bundled skills.\n');
76
- io.writeOut('Next: update AGENTS.md and .cowork-flow/config.yaml for this project.\n');
77
- return 0;
200
+ await initializeDeveloper(options.target, developer);
201
+ if (developer.existing) {
202
+ io.writeOut(`Developer already initialized: ${developer.name}\n`);
203
+ } else {
204
+ io.writeOut(`Developer initialized: ${developer.name}\n`);
78
205
  }
79
-
80
- const superpowersPlan = await buildSuperpowersPlan(options.target, {
81
- force: options.force
82
- });
83
- await applyPlan(superpowersPlan, { dryRun: false });
84
- io.writeOut(summarizePlan(superpowersPlan, false));
85
- io.writeOut('Superpowers skills were bundled into .agent/skills.\n');
86
206
  io.writeOut('Next: update AGENTS.md and .cowork-flow/config.yaml for this project.\n');
87
207
  return 0;
88
208
  }
@@ -36,16 +36,12 @@ function toTemplatePath(relativePath) {
36
36
  return relativePath.replaceAll('\\', '/');
37
37
  }
38
38
 
39
- export function isInternalTemplateFile(relativePath) {
40
- return toTemplatePath(relativePath).startsWith('.superpowers/');
41
- }
42
-
43
39
  export async function buildInitPlan(targetDir, options = {}) {
44
40
  const files = await listFiles(templateRoot);
45
41
  const actions = [];
46
42
 
47
43
  for (const file of files) {
48
- if (toTemplatePath(file) === '.cowork-flow/.version' || isInternalTemplateFile(file)) {
44
+ if (toTemplatePath(file) === '.cowork-flow/.version') {
49
45
  continue;
50
46
  }
51
47
 
@@ -69,26 +65,6 @@ export async function buildInitPlan(targetDir, options = {}) {
69
65
  return actions;
70
66
  }
71
67
 
72
- export async function buildSuperpowersPlan(targetDir, options = {}) {
73
- const sourceRoot = join(templateRoot, '.superpowers');
74
- if (!await pathExists(sourceRoot)) {
75
- return [];
76
- }
77
-
78
- const files = await listFiles(sourceRoot);
79
- const actions = [];
80
-
81
- for (const file of files) {
82
- const source = join(sourceRoot, file);
83
- const destination = join(targetDir, '.agent', 'skills', file);
84
- const exists = await pathExists(destination);
85
- const action = exists ? (options.force ? 'update' : 'skip') : 'create';
86
- actions.push({ action, source, destination, relativePath: `.agent/skills/${file}` });
87
- }
88
-
89
- return actions;
90
- }
91
-
92
68
  const PROTECTED_SYNC_FILES = new Set([
93
69
  '.cowork-flow/config.yaml'
94
70
  ]);
@@ -102,6 +78,7 @@ const PROTECTED_SYNC_PREFIXES = [
102
78
  ];
103
79
 
104
80
  const SAFE_SYNC_PREFIXES = [
81
+ '.codex/',
105
82
  '.agent/skills/',
106
83
  '.cowork-flow/'
107
84
  ];
@@ -180,7 +157,7 @@ export async function buildSyncPlan(targetDir, options = {}) {
180
157
  const actions = [];
181
158
 
182
159
  for (const file of files) {
183
- if (toTemplatePath(file) === '.cowork-flow/.version' || isInternalTemplateFile(file)) {
160
+ if (toTemplatePath(file) === '.cowork-flow/.version') {
184
161
  continue;
185
162
  }
186
163
 
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: before-dev
3
+ description: Use before writing code in a cowork-flow project to load project-specific guidelines, active task context, and verification expectations.
4
+ ---
5
+
6
+ # Before Dev
7
+
8
+ Use this immediately before code edits.
9
+
10
+ ## Read
11
+
12
+ 1. `AGENTS.md`
13
+ 2. `.cowork-flow/workflow.md`
14
+ 3. Active task `prd.md`
15
+ 4. Active task `implement.jsonl`
16
+ 5. Relevant `.cowork-flow/spec/*/index.md`
17
+ 6. Any exact files named by the task, plan, or user
18
+
19
+ Do not bulk-load unrelated tasks, archived sessions, or every spec file.
20
+
21
+ ## Confirm
22
+
23
+ State briefly:
24
+
25
+ - Assumptions.
26
+ - Success criteria.
27
+ - Files or modules likely to change.
28
+ - Verification command you expect to run.
29
+ - Whether fixed agents or inline work are appropriate.
30
+
31
+ If the task is a bounded subagent prompt, do not convert it into main-session planning.