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 +1 -1
- package/template/.agent/skills/entry-boundary/SKILL.md +22 -3
- package/template/.agent/skills/start/SKILL.md +11 -4
- package/template/.agent/skills/writing-plans/SKILL.md +8 -0
- package/template/.codex/hooks/inject-workflow-state.py +30 -1
- package/template/.cowork-flow/.version +1 -1
- package/template/.cowork-flow/config.yaml +5 -0
- package/template/.cowork-flow/scripts/common/config.py +17 -0
- package/template/.cowork-flow/scripts/doctor.py +14 -0
- package/template/.cowork-flow/workflow.md +10 -1
package/package.json
CHANGED
|
@@ -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.
|
|
17
|
-
4.
|
|
18
|
-
5. Read
|
|
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
|
-
|
|
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(
|
|
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.
|
|
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 汇报的文件、命令和结果;不只信“已完成”文本。
|