cowork-flow 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +22 -10
- package/package.json +2 -2
- package/src/lib/copy-template.js +6 -2
- package/template/.agent/skills/record-session/SKILL.md +8 -8
- package/template/.agent/skills/start/SKILL.md +28 -24
- package/template/.cowork-flow/.version +1 -1
- package/template/.cowork-flow/run +162 -0
- package/template/.cowork-flow/run.cmd +191 -0
- package/template/.cowork-flow/scripts/add_session.py +2 -2
- package/template/.cowork-flow/scripts/change.py +5 -11
- package/template/.cowork-flow/scripts/common/developer.py +1 -1
- package/template/.cowork-flow/scripts/common/git_context.py +4 -4
- package/template/.cowork-flow/scripts/get_context.py +2 -2
- package/template/.cowork-flow/scripts/init_developer.py +1 -1
- package/template/.cowork-flow/scripts/task.py +44 -44
- package/template/.cowork-flow/workflow.md +20 -18
- package/template/.cowork-flow/workspace/index.md +3 -3
- package/template/.superpowers/brainstorming/SKILL.md +1 -1
- package/template/AGENTS.md +4 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 fisklikewater
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -132,39 +132,51 @@ cowork-flow sync . --dry-run
|
|
|
132
132
|
|
|
133
133
|
## 常用入口
|
|
134
134
|
|
|
135
|
+
模板内置统一入口来运行 Python 工作流脚本:
|
|
136
|
+
|
|
137
|
+
- macOS / Linux / Git Bash / WSL:`./.cowork-flow/run`
|
|
138
|
+
- Windows cmd / PowerShell:`.\.cowork-flow\run.cmd`
|
|
139
|
+
|
|
140
|
+
入口会按 `COWORK_FLOW_PYTHON`、`PYTHON`、`python3`、`python`、`py -3`
|
|
141
|
+
的顺序查找 Python 3.8+ 解释器,避免不同环境中 `python` / `python3`
|
|
142
|
+
命令不一致的问题。
|
|
143
|
+
|
|
144
|
+
下面示例使用 macOS / Linux 写法;Windows 原生命令行中把
|
|
145
|
+
`./.cowork-flow/run` 替换为 `.\.cowork-flow\run.cmd`。
|
|
146
|
+
|
|
135
147
|
初始化或查看开发者身份:
|
|
136
148
|
|
|
137
149
|
```bash
|
|
138
|
-
|
|
139
|
-
|
|
150
|
+
./.cowork-flow/run get-developer
|
|
151
|
+
./.cowork-flow/run init-developer <developer-name>
|
|
140
152
|
```
|
|
141
153
|
|
|
142
154
|
查看当前上下文:
|
|
143
155
|
|
|
144
156
|
```bash
|
|
145
|
-
|
|
146
|
-
|
|
157
|
+
./.cowork-flow/run get-context
|
|
158
|
+
./.cowork-flow/run task list
|
|
147
159
|
```
|
|
148
160
|
|
|
149
161
|
创建并验证行为变更:
|
|
150
162
|
|
|
151
163
|
```bash
|
|
152
|
-
|
|
153
|
-
|
|
164
|
+
./.cowork-flow/run change create <slug>
|
|
165
|
+
./.cowork-flow/run change validate <slug>
|
|
154
166
|
```
|
|
155
167
|
|
|
156
168
|
创建并启动任务:
|
|
157
169
|
|
|
158
170
|
```bash
|
|
159
|
-
|
|
160
|
-
|
|
171
|
+
./.cowork-flow/run task create "<title>" --slug <task-name>
|
|
172
|
+
./.cowork-flow/run task start <task-dir>
|
|
161
173
|
```
|
|
162
174
|
|
|
163
175
|
记录 session:
|
|
164
176
|
|
|
165
177
|
```bash
|
|
166
|
-
|
|
167
|
-
|
|
178
|
+
./.cowork-flow/run get-context --mode record
|
|
179
|
+
./.cowork-flow/run add-session \
|
|
168
180
|
--title "<session-title>" \
|
|
169
181
|
--commit "<commit-or-handoff-ref>" \
|
|
170
182
|
--summary "<summary>"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cowork-flow",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "CLI for installing and maintaining cowork-flow collaboration templates.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
16
|
"test": "node --test",
|
|
17
|
-
"test:template": "
|
|
17
|
+
"test:template": "./template/.cowork-flow/run python -m unittest discover tests -v",
|
|
18
18
|
"pack:check": "npm_config_cache=/tmp/cowork-flow-npm-cache npm pack --dry-run --json",
|
|
19
19
|
"test:all": "npm test && npm run test:template && npm run pack:check"
|
|
20
20
|
},
|
package/src/lib/copy-template.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { constants } from 'node:fs';
|
|
2
|
-
import { access, copyFile, mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { access, chmod, copyFile, mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { dirname, join, relative } from 'node:path';
|
|
4
4
|
|
|
5
5
|
import { templateRoot } from './paths.js';
|
|
@@ -110,7 +110,9 @@ const SAFE_SYNC_PREFIXES = [
|
|
|
110
110
|
|
|
111
111
|
const SAFE_SYNC_FILES = new Set([
|
|
112
112
|
'.cowork-flow/.gitignore',
|
|
113
|
-
'.cowork-flow/.version'
|
|
113
|
+
'.cowork-flow/.version',
|
|
114
|
+
'.cowork-flow/run',
|
|
115
|
+
'.cowork-flow/run.cmd'
|
|
114
116
|
]);
|
|
115
117
|
|
|
116
118
|
const COWORK_FLOW_START = '<!-- COWORK-FLOW:START -->';
|
|
@@ -242,6 +244,8 @@ export async function applyPlan(actions, options = {}) {
|
|
|
242
244
|
await writeFile(item.destination, item.content, 'utf8');
|
|
243
245
|
} else {
|
|
244
246
|
await copyFile(item.source, item.destination);
|
|
247
|
+
const sourceStats = await stat(item.source);
|
|
248
|
+
await chmod(item.destination, sourceStats.mode & 0o777);
|
|
245
249
|
}
|
|
246
250
|
}
|
|
247
251
|
}
|
|
@@ -24,7 +24,7 @@ Do not archive a task while the plan file still shows stale progress.
|
|
|
24
24
|
### Step 1: Get Context & Check Tasks
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
27
|
+
./.cowork-flow/run get-context --mode record
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
[!] Archive tasks whose work is **actually done** — judge by work status, not the `status` field in task.json:
|
|
@@ -33,20 +33,20 @@ python3 ./.cowork-flow/scripts/get_context.py --mode record
|
|
|
33
33
|
- Don't skip archiving just because `status` still says `planning` or `in_progress`
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
|
|
36
|
+
./.cowork-flow/run task archive <task-name>
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
### Step 2: One-Click Add Session
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
42
|
# Method 1: Simple parameters
|
|
43
|
-
|
|
43
|
+
./.cowork-flow/run add-session \
|
|
44
44
|
--title "Session Title" \
|
|
45
45
|
--commit "hash1,hash2" \
|
|
46
46
|
--summary "Brief summary of what was done"
|
|
47
47
|
|
|
48
48
|
# Method 2: Pass detailed content via stdin
|
|
49
|
-
cat << 'EOF' |
|
|
49
|
+
cat << 'EOF' | ./.cowork-flow/run add-session --title "Title" --commit "hash"
|
|
50
50
|
| Feature | Description |
|
|
51
51
|
|---------|-------------|
|
|
52
52
|
| Change | Description |
|
|
@@ -72,7 +72,7 @@ EOF
|
|
|
72
72
|
|
|
73
73
|
| Command | Purpose |
|
|
74
74
|
|---------|---------|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
77
|
-
|
|
|
78
|
-
|
|
|
75
|
+
| `./.cowork-flow/run get-context --mode record` | Get context for record-session |
|
|
76
|
+
| `./.cowork-flow/run add-session --title "..." --commit "..."` | **One-click add session (recommended)** |
|
|
77
|
+
| `./.cowork-flow/run task archive <name>` | Archive completed task (auto-commits) |
|
|
78
|
+
| `./.cowork-flow/run task list` | List active tasks |
|
|
@@ -44,13 +44,17 @@ cat AGENTS.md
|
|
|
44
44
|
- Best practices
|
|
45
45
|
- Project-specific collaboration and documentation rules
|
|
46
46
|
|
|
47
|
+
Command examples use macOS / Linux / Git Bash / WSL syntax. In native Windows
|
|
48
|
+
cmd or PowerShell, replace `./.cowork-flow/run <command>` with
|
|
49
|
+
`.\.cowork-flow\run.cmd <command>`.
|
|
50
|
+
|
|
47
51
|
> **Important**:
|
|
48
52
|
> Reusable skills are already part of the template. During project onboarding, put project-specific facts in `AGENTS.md`, `.cowork-flow/workflow.md`, `.cowork-flow/config.yaml`, and `.cowork-flow/spec/` rather than editing `SKILL.md`.
|
|
49
53
|
|
|
50
54
|
### Step 2: Get Current Context
|
|
51
55
|
|
|
52
56
|
```bash
|
|
53
|
-
|
|
57
|
+
./.cowork-flow/run resume
|
|
54
58
|
```
|
|
55
59
|
|
|
56
60
|
This shows: developer identity, git status, current task (if any), active tasks, and
|
|
@@ -108,9 +112,9 @@ Before entering Task Workflow, classify the change as `L0` / `L1` / `L2` using `
|
|
|
108
112
|
|
|
109
113
|
- `L0`: No external behavior change. Continue with the existing Task Workflow.
|
|
110
114
|
- `L1`: Behavior change in a bounded module. Do **not** go straight to PRD/Research. First run:
|
|
111
|
-
1.
|
|
115
|
+
1. `./.cowork-flow/run change create <slug>`
|
|
112
116
|
2. `superpowers:brainstorming` to create or complete `proposal/spec`
|
|
113
|
-
3.
|
|
117
|
+
3. `./.cowork-flow/run change validate <slug>`
|
|
114
118
|
4. `superpowers:writing-plans` to produce the implementation plan
|
|
115
119
|
- `L2`: Same as `L1`, plus required `design.md`. Multi-perspective review happens after implementation in the review gate.
|
|
116
120
|
|
|
@@ -217,7 +221,7 @@ If unclear, ask clarifying questions.
|
|
|
217
221
|
**Step 2: Create Task Directory** `[AI]`
|
|
218
222
|
|
|
219
223
|
```bash
|
|
220
|
-
TASK_DIR=$(
|
|
224
|
+
TASK_DIR=$(./.cowork-flow/run task create "<title>" --slug <name>)
|
|
221
225
|
```
|
|
222
226
|
|
|
223
227
|
**Step 3: Write PRD** `[AI]`
|
|
@@ -290,7 +294,7 @@ Use this output format:
|
|
|
290
294
|
Initialize default context:
|
|
291
295
|
|
|
292
296
|
```bash
|
|
293
|
-
|
|
297
|
+
./.cowork-flow/run task init-context "$TASK_DIR" <type>
|
|
294
298
|
# type: backend | frontend | fullstack
|
|
295
299
|
```
|
|
296
300
|
|
|
@@ -298,25 +302,25 @@ Add specs found in your research pass:
|
|
|
298
302
|
|
|
299
303
|
```bash
|
|
300
304
|
# For each relevant spec and code pattern:
|
|
301
|
-
|
|
302
|
-
|
|
305
|
+
./.cowork-flow/run task add-context "$TASK_DIR" implement "<path>" "<reason>"
|
|
306
|
+
./.cowork-flow/run task add-context "$TASK_DIR" check "<path>" "<reason>"
|
|
303
307
|
```
|
|
304
308
|
|
|
305
309
|
If this task came through the Behavior Change Gate, add the approved artifacts before coding:
|
|
306
310
|
|
|
307
311
|
```bash
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
312
|
+
./.cowork-flow/run task add-context "$TASK_DIR" implement ".cowork-flow/changes/<slug>/proposal.md" "Approved change proposal"
|
|
313
|
+
./.cowork-flow/run task add-context "$TASK_DIR" implement ".cowork-flow/changes/<slug>/spec.md" "Approved behavior spec"
|
|
314
|
+
./.cowork-flow/run task add-context "$TASK_DIR" implement ".cowork-flow/changes/<slug>/design.md" "Approved design for L2 changes"
|
|
315
|
+
./.cowork-flow/run task add-context "$TASK_DIR" implement ".cowork-flow/plans/YYYY-MM-DD-<slug>.md" "Approved implementation plan"
|
|
316
|
+
./.cowork-flow/run task add-context "$TASK_DIR" check ".cowork-flow/changes/<slug>/spec.md" "Check implementation against approved spec"
|
|
317
|
+
./.cowork-flow/run task add-context "$TASK_DIR" check ".cowork-flow/plans/YYYY-MM-DD-<slug>.md" "Check implementation against approved plan"
|
|
314
318
|
```
|
|
315
319
|
|
|
316
320
|
**Step 7: Activate Task** `[AI]`
|
|
317
321
|
|
|
318
322
|
```bash
|
|
319
|
-
|
|
323
|
+
./.cowork-flow/run task start "$TASK_DIR"
|
|
320
324
|
```
|
|
321
325
|
|
|
322
326
|
This sets `.current-task` so hooks can inject context.
|
|
@@ -369,10 +373,10 @@ If yes, resume from the appropriate step (usually Step 7 or 8).
|
|
|
369
373
|
When a conversation has many rounds, a task runs for a long time, or context was
|
|
370
374
|
compressed, resume with the smallest useful context:
|
|
371
375
|
|
|
372
|
-
1. Run
|
|
376
|
+
1. Run `./.cowork-flow/run resume`.
|
|
373
377
|
2. Follow the `RESUME CHECKLIST` section.
|
|
374
378
|
3. Read the current task `prd.md`.
|
|
375
|
-
4. Run
|
|
379
|
+
4. Run `./.cowork-flow/run task list-context <task-dir>` and read only the jsonl references needed for the current phase.
|
|
376
380
|
5. If a plan is listed, read its current execution status before continuing implementation.
|
|
377
381
|
|
|
378
382
|
Do not bulk-read `.cowork-flow/spec/`, all plans, all tasks, or workspace journals
|
|
@@ -395,14 +399,14 @@ anchor, then load details on demand.
|
|
|
395
399
|
|
|
396
400
|
| Script | Purpose |
|
|
397
401
|
|--------|---------|
|
|
398
|
-
|
|
|
399
|
-
|
|
|
400
|
-
|
|
|
401
|
-
|
|
|
402
|
-
|
|
|
403
|
-
|
|
|
404
|
-
|
|
|
405
|
-
|
|
|
402
|
+
| `./.cowork-flow/run resume` | Resume session with minimal context checklist |
|
|
403
|
+
| `./.cowork-flow/run get-context` | Get session context |
|
|
404
|
+
| `./.cowork-flow/run task create` | Create task directory |
|
|
405
|
+
| `./.cowork-flow/run task init-context` | Initialize jsonl files |
|
|
406
|
+
| `./.cowork-flow/run task add-context` | Add spec to jsonl |
|
|
407
|
+
| `./.cowork-flow/run task start` | Set current task |
|
|
408
|
+
| `./.cowork-flow/run task finish` | Clear current task |
|
|
409
|
+
| `./.cowork-flow/run task archive` | Archive completed task |
|
|
406
410
|
|
|
407
411
|
### Workflow Phases `[AI]`
|
|
408
412
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.4
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -u
|
|
3
|
+
|
|
4
|
+
MIN_PYTHON_LABEL="Python 3.8+"
|
|
5
|
+
VERSION_CHECK='import sys; raise SystemExit(0 if sys.version_info >= (3, 8) else 1)'
|
|
6
|
+
|
|
7
|
+
WORKFLOW_DIR=$(CDPATH= cd "$(dirname "$0")" && pwd) || exit 1
|
|
8
|
+
SCRIPTS_DIR="$WORKFLOW_DIR/scripts"
|
|
9
|
+
|
|
10
|
+
print_usage() {
|
|
11
|
+
cat <<'EOF'
|
|
12
|
+
用法:
|
|
13
|
+
./.cowork-flow/run <command> [args...]
|
|
14
|
+
./.cowork-flow/run python [python-args...]
|
|
15
|
+
|
|
16
|
+
常用 command:
|
|
17
|
+
resume
|
|
18
|
+
task
|
|
19
|
+
change
|
|
20
|
+
get-context
|
|
21
|
+
get-developer
|
|
22
|
+
init-developer
|
|
23
|
+
add-session
|
|
24
|
+
|
|
25
|
+
解释器选择顺序:
|
|
26
|
+
COWORK_FLOW_PYTHON -> PYTHON -> python3 -> python -> py -3
|
|
27
|
+
EOF
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
candidate_is_valid() {
|
|
31
|
+
candidate_cmd=$1
|
|
32
|
+
candidate_arg=${2:-}
|
|
33
|
+
|
|
34
|
+
command -v "$candidate_cmd" >/dev/null 2>&1 || return 1
|
|
35
|
+
|
|
36
|
+
if [ -n "$candidate_arg" ]; then
|
|
37
|
+
"$candidate_cmd" "$candidate_arg" -c "$VERSION_CHECK" >/dev/null 2>&1
|
|
38
|
+
else
|
|
39
|
+
"$candidate_cmd" -c "$VERSION_CHECK" >/dev/null 2>&1
|
|
40
|
+
fi
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
select_explicit_python() {
|
|
44
|
+
env_name=$1
|
|
45
|
+
env_value=$2
|
|
46
|
+
|
|
47
|
+
if candidate_is_valid "$env_value"; then
|
|
48
|
+
SELECTED_PYTHON=$env_value
|
|
49
|
+
SELECTED_PYTHON_ARG=
|
|
50
|
+
return 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
echo "错误:$env_name 指向的解释器不可用或版本低于 ${MIN_PYTHON_LABEL}:$env_value" >&2
|
|
54
|
+
echo "请设置 $env_name 为可执行的 Python 3.8+ 解释器路径。" >&2
|
|
55
|
+
exit 127
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
select_python() {
|
|
59
|
+
SELECTED_PYTHON=
|
|
60
|
+
SELECTED_PYTHON_ARG=
|
|
61
|
+
|
|
62
|
+
if [ -n "${COWORK_FLOW_PYTHON:-}" ]; then
|
|
63
|
+
select_explicit_python "COWORK_FLOW_PYTHON" "$COWORK_FLOW_PYTHON"
|
|
64
|
+
return 0
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
if [ -n "${PYTHON:-}" ]; then
|
|
68
|
+
select_explicit_python "PYTHON" "$PYTHON"
|
|
69
|
+
return 0
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
if candidate_is_valid "python3"; then
|
|
73
|
+
SELECTED_PYTHON=python3
|
|
74
|
+
return 0
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
if candidate_is_valid "python"; then
|
|
78
|
+
SELECTED_PYTHON=python
|
|
79
|
+
return 0
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
if candidate_is_valid "py" "-3"; then
|
|
83
|
+
SELECTED_PYTHON=py
|
|
84
|
+
SELECTED_PYTHON_ARG=-3
|
|
85
|
+
return 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
echo "错误:需要 ${MIN_PYTHON_LABEL},但未找到可用解释器。" >&2
|
|
89
|
+
echo "已尝试:COWORK_FLOW_PYTHON、PYTHON、python3、python、py -3。" >&2
|
|
90
|
+
echo "可设置 COWORK_FLOW_PYTHON=/path/to/python3 后重试。" >&2
|
|
91
|
+
exit 127
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
exec_python() {
|
|
95
|
+
select_python
|
|
96
|
+
|
|
97
|
+
if [ -n "$SELECTED_PYTHON_ARG" ]; then
|
|
98
|
+
exec "$SELECTED_PYTHON" "$SELECTED_PYTHON_ARG" "$@"
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
exec "$SELECTED_PYTHON" "$@"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
run_script() {
|
|
105
|
+
script_path=$1
|
|
106
|
+
shift
|
|
107
|
+
|
|
108
|
+
if [ ! -f "$script_path" ]; then
|
|
109
|
+
echo "错误:找不到脚本:$script_path" >&2
|
|
110
|
+
exit 2
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
exec_python "$script_path" "$@"
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if [ "$#" -eq 0 ]; then
|
|
117
|
+
print_usage >&2
|
|
118
|
+
exit 2
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
command_name=$1
|
|
122
|
+
shift
|
|
123
|
+
|
|
124
|
+
case "$command_name" in
|
|
125
|
+
-h|--help|help)
|
|
126
|
+
print_usage
|
|
127
|
+
exit 0
|
|
128
|
+
;;
|
|
129
|
+
python)
|
|
130
|
+
exec_python "$@"
|
|
131
|
+
;;
|
|
132
|
+
resume)
|
|
133
|
+
run_script "$SCRIPTS_DIR/resume.py" "$@"
|
|
134
|
+
;;
|
|
135
|
+
task)
|
|
136
|
+
run_script "$SCRIPTS_DIR/task.py" "$@"
|
|
137
|
+
;;
|
|
138
|
+
change)
|
|
139
|
+
run_script "$SCRIPTS_DIR/change.py" "$@"
|
|
140
|
+
;;
|
|
141
|
+
get-context|get_context)
|
|
142
|
+
run_script "$SCRIPTS_DIR/get_context.py" "$@"
|
|
143
|
+
;;
|
|
144
|
+
get-developer|get_developer)
|
|
145
|
+
run_script "$SCRIPTS_DIR/get_developer.py" "$@"
|
|
146
|
+
;;
|
|
147
|
+
init-developer|init_developer)
|
|
148
|
+
run_script "$SCRIPTS_DIR/init_developer.py" "$@"
|
|
149
|
+
;;
|
|
150
|
+
add-session|add_session)
|
|
151
|
+
run_script "$SCRIPTS_DIR/add_session.py" "$@"
|
|
152
|
+
;;
|
|
153
|
+
*)
|
|
154
|
+
if [ -f "$SCRIPTS_DIR/$command_name.py" ]; then
|
|
155
|
+
run_script "$SCRIPTS_DIR/$command_name.py" "$@"
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
echo "错误:未知 cowork-flow 命令:$command_name" >&2
|
|
159
|
+
print_usage >&2
|
|
160
|
+
exit 2
|
|
161
|
+
;;
|
|
162
|
+
esac
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
setlocal EnableExtensions
|
|
3
|
+
|
|
4
|
+
set "MIN_PYTHON_LABEL=Python 3.8+"
|
|
5
|
+
set "VERSION_CHECK=import sys; raise SystemExit(0 if sys.version_info >= (3, 8) else 1)"
|
|
6
|
+
set "WORKFLOW_DIR=%~dp0"
|
|
7
|
+
set "SCRIPTS_DIR=%WORKFLOW_DIR%scripts"
|
|
8
|
+
set "SELECTED_PYTHON="
|
|
9
|
+
set "SELECTED_PYTHON_ARG="
|
|
10
|
+
set "REST_ARGS="
|
|
11
|
+
|
|
12
|
+
if "%~1"=="" goto usage_error
|
|
13
|
+
|
|
14
|
+
set "COMMAND_NAME=%~1"
|
|
15
|
+
if not "%~2"=="" (
|
|
16
|
+
for /F "tokens=1,* delims= " %%A in ("%*") do set "REST_ARGS=%%B"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
if /I "%COMMAND_NAME%"=="-h" goto usage
|
|
20
|
+
if /I "%COMMAND_NAME%"=="--help" goto usage
|
|
21
|
+
if /I "%COMMAND_NAME%"=="help" goto usage
|
|
22
|
+
if /I "%COMMAND_NAME%"=="python" goto run_python_passthrough
|
|
23
|
+
if /I "%COMMAND_NAME%"=="resume" goto run_resume
|
|
24
|
+
if /I "%COMMAND_NAME%"=="task" goto run_task
|
|
25
|
+
if /I "%COMMAND_NAME%"=="change" goto run_change
|
|
26
|
+
if /I "%COMMAND_NAME%"=="get-context" goto run_get_context
|
|
27
|
+
if /I "%COMMAND_NAME%"=="get_context" goto run_get_context
|
|
28
|
+
if /I "%COMMAND_NAME%"=="get-developer" goto run_get_developer
|
|
29
|
+
if /I "%COMMAND_NAME%"=="get_developer" goto run_get_developer
|
|
30
|
+
if /I "%COMMAND_NAME%"=="init-developer" goto run_init_developer
|
|
31
|
+
if /I "%COMMAND_NAME%"=="init_developer" goto run_init_developer
|
|
32
|
+
if /I "%COMMAND_NAME%"=="add-session" goto run_add_session
|
|
33
|
+
if /I "%COMMAND_NAME%"=="add_session" goto run_add_session
|
|
34
|
+
|
|
35
|
+
if exist "%SCRIPTS_DIR%\%COMMAND_NAME%.py" (
|
|
36
|
+
call :run_script "%SCRIPTS_DIR%\%COMMAND_NAME%.py"
|
|
37
|
+
exit /b %ERRORLEVEL%
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
echo 错误:未知 cowork-flow 命令:%COMMAND_NAME% 1>&2
|
|
41
|
+
call :print_usage 1>&2
|
|
42
|
+
exit /b 2
|
|
43
|
+
|
|
44
|
+
:usage
|
|
45
|
+
call :print_usage
|
|
46
|
+
exit /b 0
|
|
47
|
+
|
|
48
|
+
:usage_error
|
|
49
|
+
call :print_usage 1>&2
|
|
50
|
+
exit /b 2
|
|
51
|
+
|
|
52
|
+
:run_python_passthrough
|
|
53
|
+
call :exec_python %REST_ARGS%
|
|
54
|
+
exit /b %ERRORLEVEL%
|
|
55
|
+
|
|
56
|
+
:run_resume
|
|
57
|
+
call :run_script "%SCRIPTS_DIR%\resume.py"
|
|
58
|
+
exit /b %ERRORLEVEL%
|
|
59
|
+
|
|
60
|
+
:run_task
|
|
61
|
+
call :run_script "%SCRIPTS_DIR%\task.py"
|
|
62
|
+
exit /b %ERRORLEVEL%
|
|
63
|
+
|
|
64
|
+
:run_change
|
|
65
|
+
call :run_script "%SCRIPTS_DIR%\change.py"
|
|
66
|
+
exit /b %ERRORLEVEL%
|
|
67
|
+
|
|
68
|
+
:run_get_context
|
|
69
|
+
call :run_script "%SCRIPTS_DIR%\get_context.py"
|
|
70
|
+
exit /b %ERRORLEVEL%
|
|
71
|
+
|
|
72
|
+
:run_get_developer
|
|
73
|
+
call :run_script "%SCRIPTS_DIR%\get_developer.py"
|
|
74
|
+
exit /b %ERRORLEVEL%
|
|
75
|
+
|
|
76
|
+
:run_init_developer
|
|
77
|
+
call :run_script "%SCRIPTS_DIR%\init_developer.py"
|
|
78
|
+
exit /b %ERRORLEVEL%
|
|
79
|
+
|
|
80
|
+
:run_add_session
|
|
81
|
+
call :run_script "%SCRIPTS_DIR%\add_session.py"
|
|
82
|
+
exit /b %ERRORLEVEL%
|
|
83
|
+
|
|
84
|
+
:print_usage
|
|
85
|
+
echo 用法:
|
|
86
|
+
echo .\.cowork-flow\run.cmd ^<command^> [args...]
|
|
87
|
+
echo .\.cowork-flow\run.cmd python [python-args...]
|
|
88
|
+
echo.
|
|
89
|
+
echo 常用 command:
|
|
90
|
+
echo resume
|
|
91
|
+
echo task
|
|
92
|
+
echo change
|
|
93
|
+
echo get-context
|
|
94
|
+
echo get-developer
|
|
95
|
+
echo init-developer
|
|
96
|
+
echo add-session
|
|
97
|
+
echo.
|
|
98
|
+
echo 解释器选择顺序:
|
|
99
|
+
echo COWORK_FLOW_PYTHON -^> PYTHON -^> python3 -^> python -^> py -3
|
|
100
|
+
exit /b 0
|
|
101
|
+
|
|
102
|
+
:candidate_is_valid
|
|
103
|
+
set "CANDIDATE_CMD=%~1"
|
|
104
|
+
set "CANDIDATE_ARG=%~2"
|
|
105
|
+
|
|
106
|
+
where "%CANDIDATE_CMD%" >nul 2>nul
|
|
107
|
+
if errorlevel 1 (
|
|
108
|
+
if not exist "%CANDIDATE_CMD%" exit /b 1
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if not "%CANDIDATE_ARG%"=="" (
|
|
112
|
+
"%CANDIDATE_CMD%" "%CANDIDATE_ARG%" -c "%VERSION_CHECK%" >nul 2>nul
|
|
113
|
+
) else (
|
|
114
|
+
"%CANDIDATE_CMD%" -c "%VERSION_CHECK%" >nul 2>nul
|
|
115
|
+
)
|
|
116
|
+
exit /b %ERRORLEVEL%
|
|
117
|
+
|
|
118
|
+
:select_explicit_python
|
|
119
|
+
set "ENV_NAME=%~1"
|
|
120
|
+
set "ENV_VALUE=%~2"
|
|
121
|
+
|
|
122
|
+
call :candidate_is_valid "%ENV_VALUE%" ""
|
|
123
|
+
if not errorlevel 1 (
|
|
124
|
+
set "SELECTED_PYTHON=%ENV_VALUE%"
|
|
125
|
+
set "SELECTED_PYTHON_ARG="
|
|
126
|
+
exit /b 0
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
echo 错误:%ENV_NAME% 指向的解释器不可用或版本低于 %MIN_PYTHON_LABEL%:%ENV_VALUE% 1>&2
|
|
130
|
+
echo 请设置 %ENV_NAME% 为可执行的 Python 3.8+ 解释器路径。 1>&2
|
|
131
|
+
exit /b 127
|
|
132
|
+
|
|
133
|
+
:select_python
|
|
134
|
+
set "SELECTED_PYTHON="
|
|
135
|
+
set "SELECTED_PYTHON_ARG="
|
|
136
|
+
|
|
137
|
+
if not "%COWORK_FLOW_PYTHON%"=="" (
|
|
138
|
+
call :select_explicit_python "COWORK_FLOW_PYTHON" "%COWORK_FLOW_PYTHON%"
|
|
139
|
+
exit /b %ERRORLEVEL%
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
if not "%PYTHON%"=="" (
|
|
143
|
+
call :select_explicit_python "PYTHON" "%PYTHON%"
|
|
144
|
+
exit /b %ERRORLEVEL%
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
call :candidate_is_valid "python3" ""
|
|
148
|
+
if not errorlevel 1 (
|
|
149
|
+
set "SELECTED_PYTHON=python3"
|
|
150
|
+
exit /b 0
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
call :candidate_is_valid "python" ""
|
|
154
|
+
if not errorlevel 1 (
|
|
155
|
+
set "SELECTED_PYTHON=python"
|
|
156
|
+
exit /b 0
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
call :candidate_is_valid "py" "-3"
|
|
160
|
+
if not errorlevel 1 (
|
|
161
|
+
set "SELECTED_PYTHON=py"
|
|
162
|
+
set "SELECTED_PYTHON_ARG=-3"
|
|
163
|
+
exit /b 0
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
echo 错误:需要 %MIN_PYTHON_LABEL%,但未找到可用解释器。 1>&2
|
|
167
|
+
echo 已尝试:COWORK_FLOW_PYTHON、PYTHON、python3、python、py -3。 1>&2
|
|
168
|
+
echo 可设置 COWORK_FLOW_PYTHON=C:\Path\To\python.exe 后重试。 1>&2
|
|
169
|
+
exit /b 127
|
|
170
|
+
|
|
171
|
+
:exec_python
|
|
172
|
+
call :select_python
|
|
173
|
+
if errorlevel 1 exit /b %ERRORLEVEL%
|
|
174
|
+
|
|
175
|
+
if not "%SELECTED_PYTHON_ARG%"=="" (
|
|
176
|
+
"%SELECTED_PYTHON%" "%SELECTED_PYTHON_ARG%" %*
|
|
177
|
+
) else (
|
|
178
|
+
"%SELECTED_PYTHON%" %*
|
|
179
|
+
)
|
|
180
|
+
exit /b %ERRORLEVEL%
|
|
181
|
+
|
|
182
|
+
:run_script
|
|
183
|
+
set "SCRIPT_PATH=%~1"
|
|
184
|
+
|
|
185
|
+
if not exist "%SCRIPT_PATH%" (
|
|
186
|
+
echo 错误:找不到脚本:%SCRIPT_PATH% 1>&2
|
|
187
|
+
exit /b 2
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
call :exec_python "%SCRIPT_PATH%" %REST_ARGS%
|
|
191
|
+
exit /b %ERRORLEVEL%
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
Add a new session to journal file and update index.md.
|
|
5
5
|
|
|
6
6
|
Usage:
|
|
7
|
-
|
|
8
|
-
echo "content" |
|
|
7
|
+
./.cowork-flow/run add-session --title "Title" --commit "hash" --summary "Summary"
|
|
8
|
+
echo "content" | ./.cowork-flow/run add-session --title "Title" --commit "hash"
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
@@ -92,11 +92,8 @@ def _has_text(path: Path) -> bool:
|
|
|
92
92
|
return path.is_file() and bool(path.read_text(encoding="utf-8").strip())
|
|
93
93
|
|
|
94
94
|
|
|
95
|
-
def
|
|
96
|
-
|
|
97
|
-
if not specs_dir.is_dir():
|
|
98
|
-
return []
|
|
99
|
-
return sorted(path for path in specs_dir.rglob("spec.md") if path.is_file())
|
|
95
|
+
def _spec_file(change_dir: Path) -> Path:
|
|
96
|
+
return change_dir / "spec.md"
|
|
100
97
|
|
|
101
98
|
|
|
102
99
|
def _resolve_link(repo_root: Path, base_dir: str, value: object) -> Path | None:
|
|
@@ -151,10 +148,8 @@ def validate_change(repo_root: Path, slug: str, quiet: bool = False) -> bool:
|
|
|
151
148
|
errors.append("proposal.md is missing or empty")
|
|
152
149
|
|
|
153
150
|
documentation_only = metadata.get("documentation_only") is True
|
|
154
|
-
if not documentation_only:
|
|
155
|
-
|
|
156
|
-
if not specs or not any(_has_text(spec) for spec in specs):
|
|
157
|
-
errors.append("specs must include at least one non-empty behavior spec")
|
|
151
|
+
if not documentation_only and not _has_text(_spec_file(change_dir)):
|
|
152
|
+
errors.append("spec.md is missing or empty")
|
|
158
153
|
|
|
159
154
|
if level == "L2" and not _has_text(change_dir / "design.md"):
|
|
160
155
|
errors.append("design.md is required for L2 changes")
|
|
@@ -189,13 +184,12 @@ def create_change(args: argparse.Namespace) -> int:
|
|
|
189
184
|
return 1
|
|
190
185
|
|
|
191
186
|
change_dir.mkdir(parents=True)
|
|
192
|
-
(change_dir / "specs").mkdir()
|
|
193
187
|
(change_dir / "proposal.md").write_text(
|
|
194
188
|
f"# {slug}\n\nDescribe the proposed behavior change.\n",
|
|
195
189
|
encoding="utf-8",
|
|
196
190
|
)
|
|
197
191
|
(change_dir / "design.md").write_text("", encoding="utf-8")
|
|
198
|
-
(change_dir
|
|
192
|
+
_spec_file(change_dir).write_text("", encoding="utf-8")
|
|
199
193
|
_write_metadata(
|
|
200
194
|
change_dir,
|
|
201
195
|
{
|
|
@@ -174,7 +174,7 @@ def ensure_developer(repo_root: Path | None = None) -> None:
|
|
|
174
174
|
|
|
175
175
|
if not check_developer(repo_root):
|
|
176
176
|
print("Error: developer identity has not been initialized.", file=sys.stderr)
|
|
177
|
-
print(f"Run:
|
|
177
|
+
print(f"Run: ./{DIR_WORKFLOW}/run init-developer <your-name>", file=sys.stderr)
|
|
178
178
|
sys.exit(1)
|
|
179
179
|
|
|
180
180
|
|
|
@@ -258,7 +258,7 @@ def _build_resume_checklist(
|
|
|
258
258
|
snapshot: CurrentTaskSnapshot,
|
|
259
259
|
) -> dict[str, list[str]]:
|
|
260
260
|
"""构建最小恢复清单,只返回路径和命令,不展开文件内容。"""
|
|
261
|
-
commands = [f"
|
|
261
|
+
commands = [f"./{DIR_WORKFLOW}/run resume"]
|
|
262
262
|
read_files: list[str] = []
|
|
263
263
|
notes: list[str] = []
|
|
264
264
|
|
|
@@ -268,7 +268,7 @@ def _build_resume_checklist(
|
|
|
268
268
|
return {"commands": commands, "readFiles": read_files, "notes": notes}
|
|
269
269
|
|
|
270
270
|
current_task = snapshot.path
|
|
271
|
-
commands.append(f"
|
|
271
|
+
commands.append(f"./{DIR_WORKFLOW}/run task list-context {current_task}")
|
|
272
272
|
|
|
273
273
|
if snapshot.has_prd:
|
|
274
274
|
read_files.append(f"{current_task}/prd.md")
|
|
@@ -503,7 +503,7 @@ def get_context_text(repo_root: Path | None = None) -> str:
|
|
|
503
503
|
lines.append("## DEVELOPER")
|
|
504
504
|
if not developer:
|
|
505
505
|
lines.append(
|
|
506
|
-
f"ERROR: Not initialized. Run:
|
|
506
|
+
f"ERROR: Not initialized. Run: ./{DIR_WORKFLOW}/run init-developer <name>"
|
|
507
507
|
)
|
|
508
508
|
return "\n".join(lines)
|
|
509
509
|
|
|
@@ -670,7 +670,7 @@ def get_context_text_record(repo_root: Path | None = None) -> str:
|
|
|
670
670
|
developer = get_developer(repo_root)
|
|
671
671
|
if not developer:
|
|
672
672
|
lines.append(
|
|
673
|
-
f"ERROR: Not initialized. Run:
|
|
673
|
+
f"ERROR: Not initialized. Run: ./{DIR_WORKFLOW}/run init-developer <name>"
|
|
674
674
|
)
|
|
675
675
|
return "\n".join(lines)
|
|
676
676
|
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Get Session Context for AI Agent.
|
|
4
4
|
|
|
5
5
|
Usage:
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
./.cowork-flow/run get-context Output context in text format
|
|
7
|
+
./.cowork-flow/run get-context --json Output context in JSON format
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
from __future__ import annotations
|
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
Task Management Script for cowork-flow workflow.
|
|
5
5
|
|
|
6
6
|
Usage:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
./.cowork-flow/run task create "<title>" [--slug <name>] [--assignee <dev>] [--priority P0|P1|P2|P3] [--parent <dir>]
|
|
8
|
+
./.cowork-flow/run task init-context <dir> <type> # Initialize jsonl files
|
|
9
|
+
./.cowork-flow/run task add-context <dir> <file> <path> [reason] # Add jsonl entry
|
|
10
|
+
./.cowork-flow/run task validate <dir> # Validate jsonl files
|
|
11
|
+
./.cowork-flow/run task list-context <dir> # List jsonl entries
|
|
12
|
+
./.cowork-flow/run task start <dir> # Set as current task
|
|
13
|
+
./.cowork-flow/run task finish # Clear current task
|
|
14
|
+
./.cowork-flow/run task archive <task-name> # Archive completed task
|
|
15
|
+
./.cowork-flow/run task list # List active tasks
|
|
16
|
+
./.cowork-flow/run task list-archive [month] # List archived tasks
|
|
17
|
+
./.cowork-flow/run task add-subtask <parent-dir> <child-dir> # Link child to parent
|
|
18
|
+
./.cowork-flow/run task remove-subtask <parent-dir> <child-dir> # Unlink child from parent
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
21
|
from __future__ import annotations
|
|
@@ -630,8 +630,8 @@ def cmd_create(args: argparse.Namespace) -> int:
|
|
|
630
630
|
print("", file=sys.stderr)
|
|
631
631
|
print(colored("Next steps:", Colors.BLUE), file=sys.stderr)
|
|
632
632
|
print(" 1. Create prd.md with requirements", file=sys.stderr)
|
|
633
|
-
print(" 2. Run:
|
|
634
|
-
print(" 3. Run:
|
|
633
|
+
print(" 2. Run: ./.cowork-flow/run task init-context <dir> <dev_type>", file=sys.stderr)
|
|
634
|
+
print(" 3. Run: ./.cowork-flow/run task start <dir>", file=sys.stderr)
|
|
635
635
|
print("", file=sys.stderr)
|
|
636
636
|
|
|
637
637
|
# Output relative path for script chaining
|
|
@@ -653,7 +653,7 @@ def cmd_init_context(args: argparse.Namespace) -> int:
|
|
|
653
653
|
|
|
654
654
|
if not dev_type:
|
|
655
655
|
print(colored("Error: Missing arguments", Colors.RED))
|
|
656
|
-
print("Usage:
|
|
656
|
+
print("Usage: ./.cowork-flow/run task init-context <task-dir> <dev_type>")
|
|
657
657
|
print(" dev_type: backend | frontend | fullstack | test | docs")
|
|
658
658
|
return 1
|
|
659
659
|
|
|
@@ -699,8 +699,8 @@ def cmd_init_context(args: argparse.Namespace) -> int:
|
|
|
699
699
|
print(colored("[OK] All context files created", Colors.GREEN))
|
|
700
700
|
print()
|
|
701
701
|
print(colored("Next steps:", Colors.BLUE))
|
|
702
|
-
print(" 1. Add task-specific specs:
|
|
703
|
-
print(" 2. Set as current:
|
|
702
|
+
print(" 1. Add task-specific specs: ./.cowork-flow/run task add-context <dir> <jsonl> <path>")
|
|
703
|
+
print(" 2. Set as current: ./.cowork-flow/run task start <dir>")
|
|
704
704
|
|
|
705
705
|
return 0
|
|
706
706
|
|
|
@@ -914,7 +914,7 @@ def cmd_start(args: argparse.Namespace) -> int:
|
|
|
914
914
|
for blocker in blockers:
|
|
915
915
|
print(f" - {blocker}", file=sys.stderr)
|
|
916
916
|
print(
|
|
917
|
-
"Hint: write prd.md, run
|
|
917
|
+
"Hint: write prd.md, run ./.cowork-flow/run task init-context <dir> <dev_type>, then retry",
|
|
918
918
|
file=sys.stderr,
|
|
919
919
|
)
|
|
920
920
|
return 1
|
|
@@ -925,7 +925,7 @@ def cmd_start(args: argparse.Namespace) -> int:
|
|
|
925
925
|
for issue in validation_issues:
|
|
926
926
|
print(f" - {issue}", file=sys.stderr)
|
|
927
927
|
print(
|
|
928
|
-
"Hint: run
|
|
928
|
+
"Hint: run ./.cowork-flow/run task validate <dir> and fix the reported issues",
|
|
929
929
|
file=sys.stderr,
|
|
930
930
|
)
|
|
931
931
|
return 1
|
|
@@ -1311,19 +1311,19 @@ def show_usage() -> None:
|
|
|
1311
1311
|
print("""Task Management Script for cowork-flow workflow
|
|
1312
1312
|
|
|
1313
1313
|
Usage:
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1314
|
+
./.cowork-flow/run task create <title> Create new task directory
|
|
1315
|
+
./.cowork-flow/run task create <title> --parent <dir> Create task as child of parent
|
|
1316
|
+
./.cowork-flow/run task init-context <dir> <dev_type> Initialize jsonl files
|
|
1317
|
+
./.cowork-flow/run task add-context <dir> <jsonl> <path> [reason] Add entry to jsonl
|
|
1318
|
+
./.cowork-flow/run task validate <dir> Validate jsonl files
|
|
1319
|
+
./.cowork-flow/run task list-context <dir> List jsonl entries
|
|
1320
|
+
./.cowork-flow/run task start <dir> Set as current task
|
|
1321
|
+
./.cowork-flow/run task finish Clear current task
|
|
1322
|
+
./.cowork-flow/run task archive <task-name> Archive completed task
|
|
1323
|
+
./.cowork-flow/run task add-subtask <parent> <child> Link child task to parent
|
|
1324
|
+
./.cowork-flow/run task remove-subtask <parent> <child> Unlink child from parent
|
|
1325
|
+
./.cowork-flow/run task list [--mine] [--status <status>] List tasks
|
|
1326
|
+
./.cowork-flow/run task list-archive [YYYY-MM] List archived tasks
|
|
1327
1327
|
|
|
1328
1328
|
Arguments:
|
|
1329
1329
|
dev_type: backend | frontend | fullstack | test | docs
|
|
@@ -1333,18 +1333,18 @@ List options:
|
|
|
1333
1333
|
--status, -s <s> Filter by status (planning, in_progress, review, completed)
|
|
1334
1334
|
|
|
1335
1335
|
Examples:
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1336
|
+
./.cowork-flow/run task create "Add login feature" --slug add-login
|
|
1337
|
+
./.cowork-flow/run task create "Child task" --slug child --parent .cowork-flow/tasks/01-21-parent
|
|
1338
|
+
./.cowork-flow/run task init-context .cowork-flow/tasks/01-21-add-login backend
|
|
1339
|
+
./.cowork-flow/run task add-context <dir> implement .cowork-flow/spec/backend/auth.md "Auth guidelines"
|
|
1340
|
+
./.cowork-flow/run task start .cowork-flow/tasks/01-21-add-login
|
|
1341
|
+
./.cowork-flow/run task finish
|
|
1342
|
+
./.cowork-flow/run task archive add-login
|
|
1343
|
+
./.cowork-flow/run task add-subtask parent-task child-task # Link existing tasks
|
|
1344
|
+
./.cowork-flow/run task remove-subtask parent-task child-task
|
|
1345
|
+
./.cowork-flow/run task list # List all active tasks
|
|
1346
|
+
./.cowork-flow/run task list --mine # List my tasks only
|
|
1347
|
+
./.cowork-flow/run task list --mine --status in_progress # List my in-progress tasks
|
|
1348
1348
|
""")
|
|
1349
1349
|
|
|
1350
1350
|
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
所有任务都应先明确目标和验收标准,再进入实现;所有完成结论都必须有验证证据支撑。
|
|
12
12
|
|
|
13
|
+
命令示例默认使用 macOS / Linux / Git Bash / WSL 写法;Windows cmd / PowerShell 中使用 `.\.cowork-flow\run.cmd <command>` 替代 `./.cowork-flow/run <command>`。
|
|
14
|
+
|
|
13
15
|
---
|
|
14
16
|
|
|
15
17
|
## 2. 职责边界
|
|
@@ -70,8 +72,8 @@
|
|
|
70
72
|
首次进入项目时执行:
|
|
71
73
|
|
|
72
74
|
```bash
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
./.cowork-flow/run get-developer
|
|
76
|
+
./.cowork-flow/run init-developer <developer-name>
|
|
75
77
|
```
|
|
76
78
|
|
|
77
79
|
如果已经存在开发者身份,只需读取当前身份。
|
|
@@ -81,8 +83,8 @@ python3 ./.cowork-flow/scripts/init_developer.py <developer-name>
|
|
|
81
83
|
每次开始工作先执行:
|
|
82
84
|
|
|
83
85
|
```bash
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
./.cowork-flow/run resume
|
|
87
|
+
./.cowork-flow/run task list
|
|
86
88
|
git status
|
|
87
89
|
git log --oneline -10
|
|
88
90
|
```
|
|
@@ -167,8 +169,8 @@ cowork-flow change -> brainstorming -> design.md -> writing-plans -> 任务上
|
|
|
167
169
|
### 6.1 创建或选择任务
|
|
168
170
|
|
|
169
171
|
```bash
|
|
170
|
-
|
|
171
|
-
|
|
172
|
+
./.cowork-flow/run task list
|
|
173
|
+
./.cowork-flow/run task create "<title>" --slug <task-name>
|
|
172
174
|
```
|
|
173
175
|
|
|
174
176
|
### 6.2 写入任务 PRD
|
|
@@ -184,7 +186,7 @@ python3 ./.cowork-flow/scripts/task.py create "<title>" --slug <task-name>
|
|
|
184
186
|
### 6.3 初始化任务上下文
|
|
185
187
|
|
|
186
188
|
```bash
|
|
187
|
-
|
|
189
|
+
./.cowork-flow/run task init-context <task-dir> <type>
|
|
188
190
|
```
|
|
189
191
|
|
|
190
192
|
`<type>` 按任务选择:
|
|
@@ -200,14 +202,14 @@ python3 ./.cowork-flow/scripts/task.py init-context <task-dir> <type>
|
|
|
200
202
|
把任务相关规范、代码模式、计划文件加入上下文:
|
|
201
203
|
|
|
202
204
|
```bash
|
|
203
|
-
|
|
204
|
-
|
|
205
|
+
./.cowork-flow/run task add-context <task-dir> implement <path> "<reason>"
|
|
206
|
+
./.cowork-flow/run task add-context <task-dir> check <path> "<reason>"
|
|
205
207
|
```
|
|
206
208
|
|
|
207
209
|
### 6.5 激活任务并执行
|
|
208
210
|
|
|
209
211
|
```bash
|
|
210
|
-
|
|
212
|
+
./.cowork-flow/run task start <task-dir>
|
|
211
213
|
```
|
|
212
214
|
|
|
213
215
|
执行要求:
|
|
@@ -225,7 +227,7 @@ python3 ./.cowork-flow/scripts/task.py start <task-dir>
|
|
|
225
227
|
### 7.1 创建 cowork-flow change
|
|
226
228
|
|
|
227
229
|
```bash
|
|
228
|
-
|
|
230
|
+
./.cowork-flow/run change create <slug>
|
|
229
231
|
```
|
|
230
232
|
|
|
231
233
|
### 7.2 使用 brainstorming 形成方案
|
|
@@ -233,13 +235,13 @@ python3 ./.cowork-flow/scripts/change.py create <slug>
|
|
|
233
235
|
使用 `superpowers:brainstorming` 澄清需求、比较方案,并补齐:
|
|
234
236
|
|
|
235
237
|
- `.cowork-flow/changes/<slug>/proposal.md`
|
|
236
|
-
- `.cowork-flow/changes/<slug>/
|
|
238
|
+
- `.cowork-flow/changes/<slug>/spec.md`
|
|
237
239
|
- L2 任务需要 `.cowork-flow/changes/<slug>/design.md`
|
|
238
240
|
|
|
239
241
|
### 7.3 校验 cowork-flow change
|
|
240
242
|
|
|
241
243
|
```bash
|
|
242
|
-
|
|
244
|
+
./.cowork-flow/run change validate <slug>
|
|
243
245
|
```
|
|
244
246
|
|
|
245
247
|
### 7.4 使用 writing-plans 形成计划
|
|
@@ -345,8 +347,8 @@ L2 任务完成前需要多视角审阅:
|
|
|
345
347
|
### 9.2 记录 session
|
|
346
348
|
|
|
347
349
|
```bash
|
|
348
|
-
|
|
349
|
-
|
|
350
|
+
./.cowork-flow/run get-context --mode record
|
|
351
|
+
./.cowork-flow/run add-session \
|
|
350
352
|
--title "<session-title>" \
|
|
351
353
|
--commit "<commit-or-handoff-ref>" \
|
|
352
354
|
--summary "<summary>"
|
|
@@ -357,13 +359,13 @@ python3 ./.cowork-flow/scripts/add_session.py \
|
|
|
357
359
|
仅在任务真实完成后归档:
|
|
358
360
|
|
|
359
361
|
```bash
|
|
360
|
-
|
|
362
|
+
./.cowork-flow/run task archive <task-name>
|
|
361
363
|
```
|
|
362
364
|
|
|
363
365
|
行为变更任务还需要归档 cowork-flow change:
|
|
364
366
|
|
|
365
367
|
```bash
|
|
366
|
-
|
|
368
|
+
./.cowork-flow/run change archive <slug>
|
|
367
369
|
```
|
|
368
370
|
|
|
369
371
|
---
|
|
@@ -399,7 +401,7 @@ python3 ./.cowork-flow/scripts/change.py archive <slug>
|
|
|
399
401
|
|
|
400
402
|
恢复规则:
|
|
401
403
|
|
|
402
|
-
- 先执行
|
|
404
|
+
- 先执行 `./.cowork-flow/run resume`。
|
|
403
405
|
- 按 `RESUME CHECKLIST` 读取当前 PRD、当前 plan 和 `list-context` 输出。
|
|
404
406
|
- 不要全量重读 `.cowork-flow/spec/`、所有 plan、所有 task 或 workspace journal。
|
|
405
407
|
- 如果 plan 有 `Current Execution Status`,先读该段以确定下一步。
|
|
@@ -33,14 +33,14 @@ workspace/
|
|
|
33
33
|
### 新开发者
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
|
|
36
|
+
./.cowork-flow/run init-developer <your-name>
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
### 已初始化开发者
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
|
|
43
|
-
cat .cowork-flow/workspace/$(
|
|
42
|
+
./.cowork-flow/run get-developer
|
|
43
|
+
cat .cowork-flow/workspace/$(./.cowork-flow/run get-developer)/index.md
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
---
|
|
@@ -110,7 +110,7 @@ digraph brainstorming {
|
|
|
110
110
|
|
|
111
111
|
- Write the validated change artifacts under `.cowork-flow/changes/<slug>/`
|
|
112
112
|
- `proposal.md` explains why the behavior should change
|
|
113
|
-
- `
|
|
113
|
+
- `spec.md` defines external behavior and acceptance criteria
|
|
114
114
|
- `design.md` records important design trade-offs for L2 work
|
|
115
115
|
- (User preferences for spec location override this default)
|
|
116
116
|
- Use elements-of-style:writing-clearly-and-concisely skill if available
|
package/template/AGENTS.md
CHANGED
|
@@ -99,13 +99,15 @@
|
|
|
99
99
|
|
|
100
100
|
若与项目自定义说明冲突,以项目说明和用户明确指令为准。
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
命令示例默认使用 macOS / Linux / Git Bash / WSL 写法;Windows cmd / PowerShell 中使用 `.\.cowork-flow\run.cmd <command>` 替代 `./.cowork-flow/run <command>`。
|
|
103
|
+
|
|
104
|
+
1. 每次新会话、重新接手任务、或上下文明显丢失时,先执行 `./.cowork-flow/run resume`,再进入 `.agent/skills/start`。
|
|
103
105
|
2. 执行 `start` 时,先读 `AGENTS.md`、`.cowork-flow/workflow.md` 和 `resume.py` 的输出,不要直接编码。
|
|
104
106
|
3. 任何会修改仓库文件的请求,都必须先分级为 `L0` / `L1` / `L2`,再进入对应流程;不要把“很小”当成可以绕过流程的理由。
|
|
105
107
|
4. `L1` / `L2` 行为变更必须先有 `change -> spec -> plan`;`L2` 还必须有 `design.md`,然后才能进入实现。
|
|
106
108
|
5. 实现前必须把任务上下文写入 `.cowork-flow/tasks/<task>/implement.jsonl`、`check.jsonl`、`debug.jsonl`,并在 `start` 之后再改代码。
|
|
107
109
|
6. 收尾前必须跑验证、同步 plan / task / change 状态,完成 `finish-work` 检查,再按项目策略记录 session。
|
|
108
|
-
7. 多轮对话、长任务恢复或上下文压缩后,先运行
|
|
110
|
+
7. 多轮对话、长任务恢复或上下文压缩后,先运行 `./.cowork-flow/run resume` 并查看 `RESUME CHECKLIST`;只读取清单列出的 PRD、当前 plan 和 jsonl 引用,不要全量重读 `.cowork-flow/spec/` 或历史 journal。
|
|
109
111
|
|
|
110
112
|
Use the `.agent/skills/start` skill when starting a new session to:
|
|
111
113
|
- Initialize your developer identity
|