cowork-flow 0.0.19 → 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.19",
3
+ "version": "0.0.20",
4
4
  "description": "CLI for installing and maintaining cowork-flow collaboration templates.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,9 +13,10 @@ 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
 
@@ -51,4 +52,8 @@ Every dispatch prompt starts with:
51
52
  Active task: <task-dir>
52
53
  ```
53
54
 
54
- 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`.
@@ -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.19
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 = [
@@ -45,6 +49,12 @@ REQUIRED_WORKFLOW_DISPATCH_SNIPPETS = [
45
49
  "COWORK_DISPATCH_V1",
46
50
  "COWORK_ACK",
47
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.",
48
58
  "Formal execution uses `cowork-research`, `cowork-implement`, or `cowork-check`.",
49
59
  "Generic `worker` dispatch is best-effort only.",
50
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 汇报的文件、命令和结果;不只信“已完成”文本。