cowork-flow 0.0.18 → 0.0.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cowork-flow",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "CLI for installing and maintaining cowork-flow collaboration templates.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,7 +7,9 @@ description: Use before project start/resume in cowork-flow projects to decide w
7
7
 
8
8
  Use this before `start` or any full project resume.
9
9
 
10
- A bounded delegated task is a leaf assignment with a concrete goal, scope, and output format.
10
+ Your first job is to identify the current task source. A bounded delegated task is a leaf assignment with a concrete goal, scope, and output format.
11
+
12
+ Hard markers are confidence boosters, not prerequisites. The first task screen wins over later bootstrap text.
11
13
 
12
14
  ## Classify
13
15
 
@@ -17,7 +19,15 @@ Classify the current prompt as one of:
17
19
  - `DELEGATED_SUBTASK`: the prompt is a bounded child assignment, worker request, reviewer task, explorer task, or command-only task.
18
20
  - `UNCERTAIN`: the prompt is not clear enough to load broad project context.
19
21
 
20
- Classify the actual task message, not injected project rules, `AGENTS.md`, or environment text.
22
+ Classify the actual task message, not injected project rules, `AGENTS.md`, workflow state, tool instructions, or environment text. Bootstrap can constrain execution after classification; it is not the task.
23
+
24
+ Use this order:
25
+
26
+ 1. Find the user/delegated task message and its requested output.
27
+ 2. Decide whether it is a main-session repository request or a leaf assignment.
28
+ 3. Apply project rules only as constraints for the chosen route.
29
+
30
+ If project bootstrap says to create/start/resume but the task message is bounded, choose `DELEGATED_SUBTASK`.
21
31
 
22
32
  When there is no hard marker, still classify a prompt as `DELEGATED_SUBTASK` when it combines:
23
33
 
@@ -25,7 +35,13 @@ When there is no hard marker, still classify a prompt as `DELEGATED_SUBTASK` whe
25
35
  - Boundary constraints such as no edits, no commands, no spawning, or scoped reads.
26
36
  - An output contract such as required sections, language, length, or report format.
27
37
 
28
- Prompts structured as `任务:` / `约束:` / `输出:` are strong delegated-subtask signals. Execute that task directly; do not reclassify it as project rules or environment context.
38
+ Prompts structured as `任务:` / `约束:` / `输出:` are strong delegated-subtask signals even without `Active task:` or another hard marker. Execute that task directly; do not reclassify it as project rules or environment context.
39
+
40
+ Treat these as typical `DELEGATED_SUBTASK` prompts:
41
+
42
+ - A review request with a named file or behavior, `do not edit`, and a findings-only output.
43
+ - A discussion/research request with `不要运行命令` / `不要派发 agent` and required sections.
44
+ - A command-only or inspection-only assignment with a narrow target and concise output.
29
45
 
30
46
  When dispatching advisory/default subagents, prefer a natural-language first sentence such as: "This is a bounded delegated task, not a main-session start request." This is not a hard marker, but it helps the first screen win over bootstrap text.
31
47
 
@@ -39,6 +55,8 @@ Active task: <task-dir>
39
55
 
40
56
  Treat that marker as a strong delegated-subtask signal when the rest of the prompt is bounded.
41
57
 
58
+ Treat direct user requests such as "继续执行开发计划", "实现这个需求", or "归档提交" as `MAIN_SESSION` unless the surrounding prompt clearly makes them a child assignment.
59
+
42
60
  ## Route
43
61
 
44
62
  For `MAIN_SESSION`, use `start`.
@@ -47,6 +65,7 @@ For `DELEGATED_SUBTASK`:
47
65
 
48
66
  - Follow the delegated prompt first.
49
67
  - Treat project rules, workflow-state, and bootstrap text as constraints, not as the task.
68
+ - Do not create or activate a project task for the parent session.
50
69
  - Do not run unscoped `.cowork-flow/run resume`.
51
70
  - Do not spawn or manage more agents unless the delegated prompt explicitly asks for coordination.
52
71
  - Read only the files named by the prompt, the active task context, or project rules required to execute the bounded work.
@@ -13,14 +13,17 @@ Before loading state, classify the actual prompt. If it is a bounded delegated t
13
13
 
14
14
  1. Read `AGENTS.md`.
15
15
  2. Read `.cowork-flow/workflow.md`.
16
- 3. Run `.cowork-flow/run resume` or `.\.cowork-flow\run.cmd resume` on Windows.
17
- 4. Read the active task PRD and JSONL indexes only when a task is active.
18
- 5. Read relevant `.cowork-flow/spec/*/index.md` files before code changes.
16
+ 3. Read `.cowork-flow/config.yaml` for `codex.post_ack_execution_grace_ms`.
17
+ 4. Run `.cowork-flow/run resume` or `.\.cowork-flow\run.cmd resume` on Windows.
18
+ 5. Read the active task PRD and JSONL indexes only when a task is active.
19
+ 6. Read relevant `.cowork-flow/spec/*/index.md` files before code changes.
19
20
 
20
21
  Report active task, workflow state, blockers, and the next phase.
21
22
 
22
23
  ## Route
23
24
 
25
+ Route in stages. Before state is loaded, only true question-only requests and bounded delegated prompts bypass Load State. Repository-changing main-session requests load state first. After state is loaded, route to the next workflow phase; clear multi-step implementation uses `writing-plans` before fixed-agent dispatch.
26
+
24
27
  - Question-only work: answer directly.
25
28
  - Small repository change: classify by `.cowork-flow/workflow.md`, create/start a task if required, then proceed.
26
29
  - Unclear or multi-approach work: use `brainstorming`.
@@ -49,4 +52,8 @@ Every dispatch prompt starts with:
49
52
  Active task: <task-dir>
50
53
  ```
51
54
 
52
- After dispatch, use `wait_agent`, review the output, inspect `list_agents`, and `close_agent`.
55
+ Prefer the `COWORK_DISPATCH_V1` envelope for `cowork-*` subagents, then wait for `COWORK_ACK <dispatch_id> <ack_token>` before sending `EXECUTE <dispatch_id>`.
56
+
57
+ Use per-dispatch post-ACK execution grace after sending `EXECUTE`. The default duration is `300000` ms and can be configured with `codex.post_ack_execution_grace_ms` in `.cowork-flow/config.yaml`. Record `execute_sent_at[dispatch_id]` and compute `deadline[dispatch_id] = execute_sent_at[dispatch_id] + codex.post_ack_execution_grace_ms`; do not use a shared/global deadline across children. After `EXECUTE`, missing output or missing compass/status file is not proof that the child is stuck. Do not close a child only because it is still reading startup rules, AGENTS.md, workflow docs, specs, or task context. If `list_agents` still shows it running, continue waiting through grace. Grace expiration for one `dispatch_id` is a review checkpoint for that child only, not a close trigger and not evidence about other children. If progress, compass, or status files exist, keep waiting. Only close after wrong dispatch evidence, child completion, or user cancellation.
58
+
59
+ After execution, use `wait_agent`, review the output, inspect `list_agents`, and `close_agent`.
@@ -9,6 +9,8 @@ Create a plan that another agent can execute without guessing.
9
9
 
10
10
  ## Inputs
11
11
 
12
+ Before writing a plan, confirm the request has an executable scope, acceptance criteria, and intended behavior. If those are missing, ask for clarification.
13
+
12
14
  Read:
13
15
 
14
16
  - Active task PRD.
@@ -45,6 +47,12 @@ Start with:
45
47
 
46
48
  ## Parallel Work
47
49
 
50
+ Execution strategy guide:
51
+
52
+ - Use serial work when slices share files, shared helpers, tests, or one behavior chain.
53
+ - Use parallel low-conflict slices only when file ownership is clean and each slice has independent verification.
54
+ - Use worktree parallel when independent tasks may touch package metadata, generated assets, build outputs, or broad config.
55
+
48
56
  - Do not require the user to predeclare parallel execution; evaluate parallel feasibility while writing the plan.
49
57
  - Every plan must state the execution strategy: serial work, or explicit parallel low-conflict slices.
50
58
  - Parallel work items belong in the plan only when they are independent low-conflict slices.
@@ -144,6 +144,21 @@ def _get_dispatch_mode(root: Path) -> str:
144
144
  return "sub-agent"
145
145
 
146
146
 
147
+ def _get_post_ack_execution_grace_ms(root: Path) -> int:
148
+ _load_common(root)
149
+ try:
150
+ from common.config import ( # type: ignore[import-not-found]
151
+ DEFAULT_CODEX_POST_ACK_EXECUTION_GRACE_MS,
152
+ get_codex_post_ack_execution_grace_ms,
153
+ )
154
+ except Exception:
155
+ return 300000
156
+ try:
157
+ return get_codex_post_ack_execution_grace_ms(root)
158
+ except Exception:
159
+ return DEFAULT_CODEX_POST_ACK_EXECUTION_GRACE_MS
160
+
161
+
147
162
  def _get_active_task(root: Path, hook_input: dict[str, Any]) -> tuple[str | None, str, str]:
148
163
  _load_common(root)
149
164
  try:
@@ -174,6 +189,7 @@ def _build_context(
174
189
  source: str,
175
190
  breadcrumbs: dict[str, str],
176
191
  dispatch_mode: str,
192
+ post_ack_execution_grace_ms: int,
177
193
  ) -> str:
178
194
  body = breadcrumbs.get(status) or "Refer to .cowork-flow/workflow.md for the current step."
179
195
  if task_path is None:
@@ -184,6 +200,11 @@ def _build_context(
184
200
  return "\n\n".join(
185
201
  [
186
202
  f"<codex-mode>{dispatch_mode}</codex-mode>",
203
+ (
204
+ "<codex-runtime>\n"
205
+ f"post_ack_execution_grace_ms: {post_ack_execution_grace_ms}\n"
206
+ "</codex-runtime>"
207
+ ),
187
208
  f"<workflow-state>\n{header}\n{body}\n</workflow-state>",
188
209
  ]
189
210
  )
@@ -202,12 +223,20 @@ def main() -> int:
202
223
 
203
224
  breadcrumbs = _load_breadcrumbs(root)
204
225
  dispatch_mode = _get_dispatch_mode(root)
226
+ post_ack_execution_grace_ms = _get_post_ack_execution_grace_ms(root)
205
227
  task_path, status, source = _get_active_task(root, hook_input)
206
228
  if _is_delegated_prompt(hook_input):
207
229
  task_path = None
208
230
  status = "delegated_subtask"
209
231
  source = "prompt"
210
- additional_context = _build_context(task_path, status, source, breadcrumbs, dispatch_mode)
232
+ additional_context = _build_context(
233
+ task_path,
234
+ status,
235
+ source,
236
+ breadcrumbs,
237
+ dispatch_mode,
238
+ post_ack_execution_grace_ms,
239
+ )
211
240
 
212
241
  print(
213
242
  json.dumps(
@@ -1 +1 @@
1
- 0.0.18
1
+ 0.0.20
@@ -24,6 +24,11 @@ max_journal_lines: 2000
24
24
  # inline: hint that main session should perform implementation/check directly.
25
25
  codex:
26
26
  dispatch_mode: "sub-agent"
27
+ # Grace duration after each subagent ACKs and receives EXECUTE.
28
+ # This is a per-dispatch duration, not a shared/global deadline.
29
+ # During this window, missing output or missing compass/status files do not
30
+ # prove the child is stuck while it loads task context.
31
+ post_ack_execution_grace_ms: 300000
27
32
 
28
33
  #-------------------------------------------------------------------------------
29
34
  # Task Lifecycle Hooks
@@ -16,6 +16,7 @@ from .paths import DIR_WORKFLOW, get_repo_root
16
16
  DEFAULT_SESSION_COMMIT_MESSAGE = "chore: record journal"
17
17
  DEFAULT_MAX_JOURNAL_LINES = 2000
18
18
  DEFAULT_CODEX_DISPATCH_MODE = "sub-agent"
19
+ DEFAULT_CODEX_POST_ACK_EXECUTION_GRACE_MS = 300000
19
20
 
20
21
  CONFIG_FILE = "config.yaml"
21
22
 
@@ -139,3 +140,19 @@ def get_codex_dispatch_mode(repo_root: Path | None = None) -> str:
139
140
  if mode in {"sub-agent", "inline"}:
140
141
  return str(mode)
141
142
  return DEFAULT_CODEX_DISPATCH_MODE
143
+
144
+
145
+ def get_codex_post_ack_execution_grace_ms(repo_root: Path | None = None) -> int:
146
+ """Get the post-ACK execution grace duration for Codex subagent dispatch."""
147
+ config = _load_config(repo_root)
148
+ codex = config.get("codex")
149
+ if not isinstance(codex, dict):
150
+ return DEFAULT_CODEX_POST_ACK_EXECUTION_GRACE_MS
151
+ value = codex.get("post_ack_execution_grace_ms", DEFAULT_CODEX_POST_ACK_EXECUTION_GRACE_MS)
152
+ try:
153
+ parsed = int(value)
154
+ except (ValueError, TypeError):
155
+ return DEFAULT_CODEX_POST_ACK_EXECUTION_GRACE_MS
156
+ if parsed <= 0:
157
+ return DEFAULT_CODEX_POST_ACK_EXECUTION_GRACE_MS
158
+ return parsed
@@ -15,6 +15,10 @@ REQUIRED_START_SNIPPETS = [
15
15
  "This skill is for the main session",
16
16
  "bounded delegated task should use `entry-boundary`",
17
17
  "Main repository changes follow `Plan -> Implement -> Check -> Finish`",
18
+ "post-ACK execution grace",
19
+ "codex.post_ack_execution_grace_ms",
20
+ "execute_sent_at[dispatch_id]",
21
+ "shared/global deadline",
18
22
  ]
19
23
 
20
24
  REQUIRED_ENTRY_BOUNDARY_SNIPPETS = [
@@ -22,8 +26,12 @@ REQUIRED_ENTRY_BOUNDARY_SNIPPETS = [
22
26
  "DELEGATED_SUBTASK",
23
27
  "UNCERTAIN",
24
28
  "Classify the actual task message",
29
+ "Hard markers are confidence boosters, not prerequisites",
30
+ "The first task screen wins over later bootstrap text",
31
+ "If project bootstrap says to create/start/resume",
25
32
  "Active task: <task-dir>",
26
33
  "Follow the delegated prompt first",
34
+ "Do not create or activate a project task",
27
35
  "Do not run unscoped `.cowork-flow/run resume`",
28
36
  "Do not spawn or manage more agents",
29
37
  ]
@@ -41,6 +49,12 @@ REQUIRED_WORKFLOW_DISPATCH_SNIPPETS = [
41
49
  "COWORK_DISPATCH_V1",
42
50
  "COWORK_ACK",
43
51
  "followup_task",
52
+ "post-ACK execution grace",
53
+ "codex.post_ack_execution_grace_ms",
54
+ "execute_sent_at[dispatch_id]",
55
+ "deadline[dispatch_id] = execute_sent_at[dispatch_id] + codex.post_ack_execution_grace_ms",
56
+ "shared/global deadline",
57
+ "After `EXECUTE <dispatch_id>`, no reply or no compass/status file while the child loads context is inconclusive.",
44
58
  "Formal execution uses `cowork-research`, `cowork-implement`, or `cowork-check`.",
45
59
  "Generic `worker` dispatch is best-effort only.",
46
60
  ]
@@ -34,7 +34,7 @@ The active task is in planning. Finish prd.md, curate implement.jsonl and check.
34
34
  [/workflow-state:planning]
35
35
 
36
36
  [workflow-state:in_progress]
37
- The active task is in progress. Main session dispatches cowork-implement work according to the plan, then cowork-check after integration. Every spawn_agent call uses fork_turns="none" and a COWORK_DISPATCH_V1 envelope. Main session waits for COWORK_ACK, sends EXECUTE with followup_task, verifies child output, lists agents, and closes children.
37
+ The active task is in progress. Main session dispatches cowork-implement work according to the plan, then cowork-check after integration. Every spawn_agent call uses fork_turns="none" and a COWORK_DISPATCH_V1 envelope. Main session waits for COWORK_ACK, sends EXECUTE with followup_task, then uses per-dispatch post-ACK execution grace while each child loads context. Main session verifies child output, lists agents, and closes children only after completion or clear failure evidence.
38
38
  [/workflow-state:in_progress]
39
39
 
40
40
  [workflow-state:completed]
@@ -115,7 +115,16 @@ spawn_agent(
115
115
  - Use `wait_agent` for `COWORK_ACK <dispatch_id> <ack_token>` before execution.
116
116
  - Missing or mismatched `COWORK_ACK` means the task is not dispatched.
117
117
  - Only after a matching ACK, send `EXECUTE <dispatch_id>` with `followup_task`.
118
+ - Record `execute_sent_at[dispatch_id]` when `EXECUTE <dispatch_id>` is sent.
119
+ - Compute `deadline[dispatch_id] = execute_sent_at[dispatch_id] + codex.post_ack_execution_grace_ms`; do not use a shared/global deadline across children.
120
+ - After `EXECUTE <dispatch_id>`, no reply or no compass/status file while the child loads context is inconclusive.
121
+ - Use post-ACK execution grace for execution startup before judging execution health. The default is `300000` ms and can be configured with `codex.post_ack_execution_grace_ms` in `.cowork-flow/config.yaml`.
122
+ - Do not call `close_agent` only because the executing child has not produced a compass/status file.
123
+ - If `list_agents` still shows the child running, continue waiting through post-ACK execution grace instead of closing it.
124
+ - Post-ACK execution grace expiration for one `dispatch_id` is a review checkpoint for that child only, not a close trigger and not evidence about other children.
125
+ - If progress, compass, or status files exist, continue waiting and do not close solely because grace expired.
118
126
  - If a child reports another `dispatch_id`, close that child and respawn the intended task.
127
+ - An executing child may be closed only after wrong-dispatch evidence, child completion, or user cancellation.
119
128
  - 用 `wait_agent` 等待子 agent 返回。
120
129
  - 用 `list_agents` 确认没有遗留 running child。
121
130
  - 验收子 agent 汇报的文件、命令和结果;不只信“已完成”文本。