cowork-flow 0.0.2 → 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 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
@@ -128,43 +128,55 @@ cowork-flow sync .
128
128
  cowork-flow sync . --dry-run
129
129
  ```
130
130
 
131
- `sync` 默认保护 `AGENTS.md`、`.cowork-flow/config.yaml`、`.cowork-flow/workflow.md`、`.cowork-flow/spec/`、任务、计划、变更和 workspace 记录。只有明确传入 `--force` 时才覆盖保护文件。
131
+ `sync` 默认刷新 `.agent/skills/`、`.cowork-flow/scripts/` 和 `AGENTS.md` 中的 `<!-- COWORK-FLOW:START --> ... <!-- COWORK-FLOW:END -->` 托管块,保留 `AGENTS.md` 托管块之外的项目自定义内容。`.cowork-flow/config.yaml`、`.cowork-flow/workflow.md`、`.cowork-flow/spec/`、任务、计划、变更和 workspace 记录默认受保护。只有明确传入 `--force` 时才整文件覆盖保护文件。
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
- python3 ./.cowork-flow/scripts/get_developer.py
139
- python3 ./.cowork-flow/scripts/init_developer.py <developer-name>
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
- python3 ./.cowork-flow/scripts/get_context.py
146
- python3 ./.cowork-flow/scripts/task.py list
157
+ ./.cowork-flow/run get-context
158
+ ./.cowork-flow/run task list
147
159
  ```
148
160
 
149
161
  创建并验证行为变更:
150
162
 
151
163
  ```bash
152
- python3 ./.cowork-flow/scripts/change.py create <slug>
153
- python3 ./.cowork-flow/scripts/change.py validate <slug>
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
- python3 ./.cowork-flow/scripts/task.py create "<title>" --slug <task-name>
160
- python3 ./.cowork-flow/scripts/task.py start <task-dir>
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
- python3 ./.cowork-flow/scripts/get_context.py --mode record
167
- python3 ./.cowork-flow/scripts/add_session.py \
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.2",
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": "python3 -m unittest discover tests -v",
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
  },
@@ -1,5 +1,5 @@
1
1
  import { constants } from 'node:fs';
2
- import { access, copyFile, mkdir, 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,9 +110,14 @@ 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
 
118
+ const COWORK_FLOW_START = '<!-- COWORK-FLOW:START -->';
119
+ const COWORK_FLOW_END = '<!-- COWORK-FLOW:END -->';
120
+
116
121
  function isProtectedSyncFile(relativePath) {
117
122
  return PROTECTED_SYNC_FILES.has(relativePath)
118
123
  || PROTECTED_SYNC_PREFIXES.some((prefix) => relativePath.startsWith(prefix));
@@ -124,6 +129,48 @@ function isSafeSyncFile(relativePath) {
124
129
  || relativePath.endsWith('/.gitkeep');
125
130
  }
126
131
 
132
+ function replaceManagedBlock(targetContent, templateContent) {
133
+ const targetStart = targetContent.indexOf(COWORK_FLOW_START);
134
+ const targetEnd = targetContent.indexOf(COWORK_FLOW_END, targetStart + COWORK_FLOW_START.length);
135
+ const templateStart = templateContent.indexOf(COWORK_FLOW_START);
136
+ const templateEnd = templateContent.indexOf(COWORK_FLOW_END, templateStart + COWORK_FLOW_START.length);
137
+
138
+ if (targetStart === -1 || targetEnd === -1 || templateStart === -1 || templateEnd === -1) {
139
+ return null;
140
+ }
141
+
142
+ const targetBlockEnd = targetEnd + COWORK_FLOW_END.length;
143
+ const templateBlockEnd = templateEnd + COWORK_FLOW_END.length;
144
+ return [
145
+ targetContent.slice(0, targetStart),
146
+ templateContent.slice(templateStart, templateBlockEnd),
147
+ targetContent.slice(targetBlockEnd)
148
+ ].join('');
149
+ }
150
+
151
+ async function buildAgentsSyncAction({ source, destination, exists, options }) {
152
+ if (!exists || options.force) {
153
+ return {
154
+ action: exists ? 'update' : 'create',
155
+ source,
156
+ destination,
157
+ relativePath: 'AGENTS.md'
158
+ };
159
+ }
160
+
161
+ const [templateContent, targetContent] = await Promise.all([
162
+ readFile(source, 'utf8'),
163
+ readFile(destination, 'utf8')
164
+ ]);
165
+ const content = replaceManagedBlock(targetContent, templateContent);
166
+
167
+ if (content === null) {
168
+ return { action: 'protected', source, destination, relativePath: 'AGENTS.md' };
169
+ }
170
+
171
+ return { action: 'update', source, destination, relativePath: 'AGENTS.md', content };
172
+ }
173
+
127
174
  export async function buildSyncPlan(targetDir, options = {}) {
128
175
  if (!await pathExists(join(targetDir, '.cowork-flow'))) {
129
176
  throw new Error(`Target is not initialized: ${targetDir}`);
@@ -140,6 +187,11 @@ export async function buildSyncPlan(targetDir, options = {}) {
140
187
  const source = join(templateRoot, file);
141
188
  const destination = join(targetDir, file);
142
189
  const exists = await pathExists(destination);
190
+ if (file === 'AGENTS.md') {
191
+ actions.push(await buildAgentsSyncAction({ source, destination, exists, options }));
192
+ continue;
193
+ }
194
+
143
195
  const protectedFile = isProtectedSyncFile(file) && !options.force && exists;
144
196
  const safeFile = isSafeSyncFile(file);
145
197
 
@@ -192,6 +244,8 @@ export async function applyPlan(actions, options = {}) {
192
244
  await writeFile(item.destination, item.content, 'utf8');
193
245
  } else {
194
246
  await copyFile(item.source, item.destination);
247
+ const sourceStats = await stat(item.source);
248
+ await chmod(item.destination, sourceStats.mode & 0o777);
195
249
  }
196
250
  }
197
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
- python3 ./.cowork-flow/scripts/get_context.py --mode record
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
- python3 ./.cowork-flow/scripts/task.py archive <task-name>
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
- python3 ./.cowork-flow/scripts/add_session.py \
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' | python3 ./.cowork-flow/scripts/add_session.py --title "Title" --commit "hash"
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
- | `python3 ./.cowork-flow/scripts/get_context.py --mode record` | Get context for record-session |
76
- | `python3 ./.cowork-flow/scripts/add_session.py --title "..." --commit "..."` | **One-click add session (recommended)** |
77
- | `python3 ./.cowork-flow/scripts/task.py archive <name>` | Archive completed task (auto-commits) |
78
- | `python3 ./.cowork-flow/scripts/task.py list` | List active tasks |
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 |
@@ -7,6 +7,14 @@ description: Use when beginning a development session in a project that uses the
7
7
 
8
8
  Initialize your AI development session and begin working on tasks.
9
9
 
10
+ <HARD-GATE>
11
+ Any request that changes repository files MUST go through this skill's task workflow.
12
+ Questions may be answered directly, but file edits are at least `L0` and require a task,
13
+ PRD, context initialization, task activation, verification, and session recording.
14
+ Do not use a direct-edit shortcut unless the user explicitly tells you not to use
15
+ cowork-flow for this task.
16
+ </HARD-GATE>
17
+
10
18
  ---
11
19
 
12
20
  ## Operation Types
@@ -36,16 +44,21 @@ cat AGENTS.md
36
44
  - Best practices
37
45
  - Project-specific collaboration and documentation rules
38
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
+
39
51
  > **Important**:
40
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`.
41
53
 
42
54
  ### Step 2: Get Current Context
43
55
 
44
56
  ```bash
45
- python3 ./.cowork-flow/scripts/get_context.py
57
+ ./.cowork-flow/run resume
46
58
  ```
47
59
 
48
- This shows: developer identity, git status, current task (if any), active tasks.
60
+ This shows: developer identity, git status, current task (if any), active tasks, and
61
+ the minimal `RESUME CHECKLIST` for loading task details on demand.
49
62
 
50
63
  ### Step 3: Read Guidelines Index
51
64
 
@@ -71,13 +84,19 @@ When user describes a task, classify it:
71
84
 
72
85
  | Type | Criteria | Workflow |
73
86
  |------|----------|----------|
74
- | **Question** | User asks about code, architecture, or how something works | Answer directly |
75
- | **Trivial Fix** | Typo fix, comment update, single-line change, < 5 minutes | Direct Edit |
76
- | **Simple Task** | Clear goal, 1-2 files, well-defined scope | Quick confirm → Task Workflow |
77
- | **Complex Task** | Vague goal, multiple files, architectural decisions | **Brainstorm → Task Workflow** |
87
+ | **Question** | User asks about code, architecture, or how something works, and no repository files need to change | Answer directly after session context is loaded |
88
+ | **L0 Change** | Docs, tests, comments, config, small refactors, or any file change without external behavior change | Task Workflow, no Behavior Change Gate |
89
+ | **L1 Change** | Bounded behavior change in one module or one interface | Behavior Change Gate → Task Workflow |
90
+ | **L2 Change** | Cross-layer, architectural, migration, permission, compatibility, release, or security-impacting change | Behavior Change Gate + `design.md` → Task Workflow |
91
+ | **Unclear / Complex** | Vague goal, multiple possible interpretations, or architectural decisions | **Brainstorm → classify L0/L1/L2 → gated workflow** |
78
92
 
79
93
  ### Decision Rule
80
94
 
95
+ > **Any file change must enter L0 / L1 / L2 workflow.**
96
+ >
97
+ > A typo, comment, one-line fix, or "quick" change is still a repository change.
98
+ > Do not treat small size as permission to skip PRD, context, verification, or session recording.
99
+ >
81
100
  > **If in doubt, use Brainstorm + Task Workflow.**
82
101
  >
83
102
  > Task Workflow ensures code-specs are injected to the right context, resulting in higher quality code.
@@ -93,9 +112,9 @@ Before entering Task Workflow, classify the change as `L0` / `L1` / `L2` using `
93
112
 
94
113
  - `L0`: No external behavior change. Continue with the existing Task Workflow.
95
114
  - `L1`: Behavior change in a bounded module. Do **not** go straight to PRD/Research. First run:
96
- 1. `python3 ./.cowork-flow/scripts/change.py create <slug>`
115
+ 1. `./.cowork-flow/run change create <slug>`
97
116
  2. `superpowers:brainstorming` to create or complete `proposal/spec`
98
- 3. `python3 ./.cowork-flow/scripts/change.py validate <slug>`
117
+ 3. `./.cowork-flow/run change validate <slug>`
99
118
  4. `superpowers:writing-plans` to produce the implementation plan
100
119
  - `L2`: Same as `L1`, plus required `design.md`. Multi-perspective review happens after implementation in the review gate.
101
120
 
@@ -114,24 +133,24 @@ Before Phase 2, always complete this task handoff:
114
133
 
115
134
  ---
116
135
 
117
- ## Question / Trivial Fix
136
+ ## Question Only
118
137
 
119
- For questions or trivial fixes, work directly:
138
+ For questions that do not modify repository files, work directly:
120
139
 
121
- 1. Answer question or make the fix
122
- 2. If code was changed, follow the current session convention for verification, business-code commit or handoff, and `$record-session`
140
+ 1. Answer the question.
141
+ 2. If the answer reveals that files should change, stop and re-enter Task Classification.
142
+ 3. Do not modify files from this section.
123
143
 
124
144
  ---
125
145
 
126
- ## Simple Task
146
+ ## L0 / Simple Task
127
147
 
128
- For simple, well-defined tasks:
148
+ For simple, well-defined tasks that modify files without external behavior change:
129
149
 
130
- 1. Quick confirm: "I understand you want to [goal]. Shall I proceed?"
131
- 2. If no, clarify and confirm again
132
- 3. Determine whether the task is `L0`, `L1`, or `L2`.
133
- 4. **If it is `L1/L2`, complete the Behavior Change Gate first. After that, execute Path B Step 2 and Step 3, complete the task handoff, then continue with Phase 2.**
134
- 5. **If it is `L0`, execute ALL steps below without stopping. Do NOT ask for additional confirmation between steps.**
150
+ 1. Clarify only if the goal, scope, or verification method is unclear.
151
+ 2. Determine whether the task is `L0`, `L1`, or `L2`.
152
+ 3. **If it is `L1/L2`, complete the Behavior Change Gate first. After that, execute Path B Step 2 and Step 3, complete the task handoff, then continue with Phase 2.**
153
+ 4. **If it is `L0`, execute ALL steps below without stopping. Do NOT ask for additional confirmation between steps. Do NOT switch to ad hoc direct editing.**
135
154
  - Create task directory (Phase 1 Path B, Step 2)
136
155
  - Write PRD (Step 3)
137
156
  - Research codebase (Phase 2, Step 5)
@@ -202,7 +221,7 @@ If unclear, ask clarifying questions.
202
221
  **Step 2: Create Task Directory** `[AI]`
203
222
 
204
223
  ```bash
205
- TASK_DIR=$(python3 ./.cowork-flow/scripts/task.py create "<title>" --slug <name>)
224
+ TASK_DIR=$(./.cowork-flow/run task create "<title>" --slug <name>)
206
225
  ```
207
226
 
208
227
  **Step 3: Write PRD** `[AI]`
@@ -275,7 +294,7 @@ Use this output format:
275
294
  Initialize default context:
276
295
 
277
296
  ```bash
278
- python3 ./.cowork-flow/scripts/task.py init-context "$TASK_DIR" <type>
297
+ ./.cowork-flow/run task init-context "$TASK_DIR" <type>
279
298
  # type: backend | frontend | fullstack
280
299
  ```
281
300
 
@@ -283,25 +302,25 @@ Add specs found in your research pass:
283
302
 
284
303
  ```bash
285
304
  # For each relevant spec and code pattern:
286
- python3 ./.cowork-flow/scripts/task.py add-context "$TASK_DIR" implement "<path>" "<reason>"
287
- python3 ./.cowork-flow/scripts/task.py add-context "$TASK_DIR" check "<path>" "<reason>"
305
+ ./.cowork-flow/run task add-context "$TASK_DIR" implement "<path>" "<reason>"
306
+ ./.cowork-flow/run task add-context "$TASK_DIR" check "<path>" "<reason>"
288
307
  ```
289
308
 
290
309
  If this task came through the Behavior Change Gate, add the approved artifacts before coding:
291
310
 
292
311
  ```bash
293
- python3 ./.cowork-flow/scripts/task.py add-context "$TASK_DIR" implement ".cowork-flow/changes/<slug>/proposal.md" "Approved change proposal"
294
- python3 ./.cowork-flow/scripts/task.py add-context "$TASK_DIR" implement ".cowork-flow/changes/<slug>/specs/.../spec.md" "Approved behavior spec"
295
- python3 ./.cowork-flow/scripts/task.py add-context "$TASK_DIR" implement ".cowork-flow/changes/<slug>/design.md" "Approved design for L2 changes"
296
- python3 ./.cowork-flow/scripts/task.py add-context "$TASK_DIR" implement ".cowork-flow/plans/YYYY-MM-DD-<slug>.md" "Approved implementation plan"
297
- python3 ./.cowork-flow/scripts/task.py add-context "$TASK_DIR" check ".cowork-flow/changes/<slug>/specs/.../spec.md" "Check implementation against approved spec"
298
- python3 ./.cowork-flow/scripts/task.py add-context "$TASK_DIR" check ".cowork-flow/plans/YYYY-MM-DD-<slug>.md" "Check implementation against approved plan"
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"
299
318
  ```
300
319
 
301
320
  **Step 7: Activate Task** `[AI]`
302
321
 
303
322
  ```bash
304
- python3 ./.cowork-flow/scripts/task.py start "$TASK_DIR"
323
+ ./.cowork-flow/run task start "$TASK_DIR"
305
324
  ```
306
325
 
307
326
  This sets `.current-task` so hooks can inject context.
@@ -339,7 +358,7 @@ Run a quality pass against check context:
339
358
 
340
359
  ## Continuing Existing Task
341
360
 
342
- If `get_context.py` shows a current task:
361
+ If `resume.py` shows a current task:
343
362
 
344
363
  1. Read the task's `prd.md` to understand the goal
345
364
  2. Check `task.json` for current status
@@ -349,6 +368,23 @@ If yes, resume from the appropriate step (usually Step 7 or 8).
349
368
 
350
369
  ---
351
370
 
371
+ ## Resume / Context Compression
372
+
373
+ When a conversation has many rounds, a task runs for a long time, or context was
374
+ compressed, resume with the smallest useful context:
375
+
376
+ 1. Run `./.cowork-flow/run resume`.
377
+ 2. Follow the `RESUME CHECKLIST` section.
378
+ 3. Read the current task `prd.md`.
379
+ 4. Run `./.cowork-flow/run task list-context <task-dir>` and read only the jsonl references needed for the current phase.
380
+ 5. If a plan is listed, read its current execution status before continuing implementation.
381
+
382
+ Do not bulk-read `.cowork-flow/spec/`, all plans, all tasks, or workspace journals
383
+ just because context was compressed. Use the checklist as the minimal recovery
384
+ anchor, then load details on demand.
385
+
386
+ ---
387
+
352
388
  ## Skills Reference
353
389
 
354
390
  ### User Skills `[USER]`
@@ -363,13 +399,14 @@ If yes, resume from the appropriate step (usually Step 7 or 8).
363
399
 
364
400
  | Script | Purpose |
365
401
  |--------|---------|
366
- | `python3 ./.cowork-flow/scripts/get_context.py` | Get session context |
367
- | `python3 ./.cowork-flow/scripts/task.py create` | Create task directory |
368
- | `python3 ./.cowork-flow/scripts/task.py init-context` | Initialize jsonl files |
369
- | `python3 ./.cowork-flow/scripts/task.py add-context` | Add spec to jsonl |
370
- | `python3 ./.cowork-flow/scripts/task.py start` | Set current task |
371
- | `python3 ./.cowork-flow/scripts/task.py finish` | Clear current task |
372
- | `python3 ./.cowork-flow/scripts/task.py archive` | Archive completed task |
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 |
373
410
 
374
411
  ### Workflow Phases `[AI]`
375
412
 
@@ -1 +1 @@
1
- 0.0.2
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