cowork-flow 0.0.37 → 0.0.39
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/README.md +27 -14
- package/package.json +1 -1
- package/src/commands/init.js +39 -28
- package/src/commands/sync.js +2 -2
- package/src/lib/asset-plan.js +127 -0
- package/src/lib/copy-template.js +101 -141
- package/src/lib/host-assets.js +231 -0
- package/src/lib/plan-applier.js +329 -0
- package/src/lib/platforms.js +15 -76
- package/src/lib/skill-registry.js +503 -0
- package/template/.claude/agents/cowork-check.md +10 -1
- package/template/.claude/agents/cowork-implement.md +11 -2
- package/template/.claude/hooks/inject-workflow-state.py +51 -254
- package/template/.codex/agents/cowork-check.toml +12 -3
- package/template/.codex/agents/cowork-implement.toml +11 -2
- package/template/.codex/agents/default.toml +3 -2
- package/template/.codex/agents/explorer.toml +3 -2
- package/template/.codex/agents/worker.toml +2 -1
- package/template/.codex/hooks/inject-workflow-state.py +46 -265
- package/template/.cowork-flow/.version +1 -1
- package/template/.cowork-flow/scripts/application/__init__.py +1 -0
- package/template/.cowork-flow/scripts/application/batch_execution.py +743 -0
- package/template/.cowork-flow/scripts/application/runtime_context_service.py +365 -0
- package/template/.cowork-flow/scripts/application/task_archive.py +220 -0
- package/template/.cowork-flow/scripts/application/task_context.py +765 -0
- package/template/.cowork-flow/scripts/application/task_creation.py +201 -0
- package/template/.cowork-flow/scripts/application/task_lifecycle.py +532 -0
- package/template/.cowork-flow/scripts/application/task_tree.py +179 -0
- package/template/.cowork-flow/scripts/commands/doctor.py +78 -57
- package/template/.cowork-flow/scripts/commands/party_mode_v2.py +671 -425
- package/template/.cowork-flow/scripts/commands/subagent.py +38 -26
- package/template/.cowork-flow/scripts/commands/task.py +535 -1953
- package/template/.cowork-flow/scripts/commands/task_archive_commands.py +195 -0
- package/template/.cowork-flow/scripts/commands/task_context_commands.py +240 -0
- package/template/.cowork-flow/scripts/commands/task_create_command.py +164 -0
- package/template/.cowork-flow/scripts/commands/task_navigation.py +407 -0
- package/template/.cowork-flow/scripts/commands/task_parser.py +364 -0
- package/template/.cowork-flow/scripts/commands/task_support.py +76 -0
- package/template/.cowork-flow/scripts/commands/task_tree_commands.py +160 -0
- package/template/.cowork-flow/scripts/common/core/execution_context.py +161 -85
- package/template/.cowork-flow/scripts/common/core/host_manifest.py +393 -0
- package/template/.cowork-flow/scripts/common/core/skill_registry.py +568 -0
- package/template/.cowork-flow/scripts/common/gates/coding_standards.py +58 -7
- package/template/.cowork-flow/scripts/common/gates/gates.py +323 -46
- package/template/.cowork-flow/scripts/common/gates/models.py +196 -0
- package/template/.cowork-flow/scripts/common/gates/registry.py +79 -0
- package/template/.cowork-flow/scripts/common/gates/tdd_evidence.py +13 -13
- package/template/.cowork-flow/scripts/common/gates/validate_coding_standards.py +104 -62
- package/template/.cowork-flow/scripts/common/gates/validate_implementation.py +39 -22
- package/template/.cowork-flow/scripts/common/gates/validate_rules.py +223 -40
- package/template/.cowork-flow/scripts/common/git/git_context.py +216 -182
- package/template/.cowork-flow/scripts/common/host/__init__.py +1 -0
- package/template/.cowork-flow/scripts/common/host/workflow_state_hook.py +303 -0
- package/template/.cowork-flow/scripts/common/storage/__init__.py +1 -0
- package/template/.cowork-flow/scripts/common/storage/operation_log.py +72 -0
- package/template/.cowork-flow/scripts/common/storage/state_store.py +279 -0
- package/template/.cowork-flow/scripts/common/storage/unit_of_work.py +214 -0
- package/template/.cowork-flow/scripts/common/task/active_task.py +93 -135
- package/template/.cowork-flow/scripts/common/task/batch_mode.py +33 -120
- package/template/.cowork-flow/scripts/common/task/decision_review.py +85 -0
- package/template/.cowork-flow/scripts/common/task/readiness.py +9 -15
- package/template/.cowork-flow/scripts/common/task/task_repository.py +156 -0
- package/template/.cowork-flow/scripts/run.py +24 -0
- package/template/.cowork-flow/spec/contracts/decision-anchor.md +8 -2
- package/template/.cowork-flow/spec/contracts/subagent-dispatch.md +2 -4
- package/template/.cowork-flow/spec/contracts/workflow-state-templates.md +1 -1
- package/template/.cowork-flow/spec/protocols/decision-review.md +28 -0
- package/template/.cowork-flow/spec/protocols/review.md +34 -0
- package/template/.cowork-flow/spec/protocols/spec-maintenance.md +16 -0
- package/template/.cowork-flow/spec/protocols/tdd.md +30 -0
- package/template/.cowork-flow/spec/references/definition-of-done.md +4 -4
- package/template/.cowork-flow/spec/references/orchestration-patterns.md +1 -1
- package/template/.cowork-flow/spec/runtime/contract-registry.json +25 -0
- package/template/.cowork-flow/spec/runtime/host-assets.json +214 -0
- package/template/.cowork-flow/spec/runtime/index.md +8 -0
- package/template/.cowork-flow/spec/runtime/rules.json +61 -10
- package/template/.cowork-flow/spec/runtime/skill-registry.json +397 -0
- package/template/.cowork-flow/spec/schemas/host-assets.schema.json +173 -0
- package/template/.cowork-flow/spec/schemas/rules.schema.json +10 -1
- package/template/.cowork-flow/spec/schemas/skill-registry.schema.json +202 -0
- package/template/.cowork-flow/workflow.md +18 -13
- package/template/.opencode/agents/cowork-check.md +11 -0
- package/template/.opencode/agents/cowork-implement.md +16 -1
- package/template/.zcode/.zcode-plugin/plugin.json +1 -1
- package/template/.zcode/hooks/inject-context.js +3 -85
- package/template/.zcode/hooks/inject-context.selfcheck.mjs +6 -6
- package/template/.zcode/scaffold/.cowork-flow/spec/contracts/decision-anchor.md +8 -2
- package/template/.zcode/scaffold/.cowork-flow/spec/contracts/subagent-dispatch.md +2 -4
- package/template/.zcode/scaffold/.cowork-flow/spec/runtime/rules.json +61 -10
- package/template/.zcode/scaffold/.cowork-flow/spec/schemas/rules.schema.json +10 -1
- package/template/.zcode/scaffold/.cowork-flow/workflow.md +18 -13
- package/template/.zcode/scaffold/AGENTS.md +18 -8
- package/template/AGENTS.md +1 -1
- package/template/skills/batch-mode/SKILL.md +140 -76
- package/template/skills/brainstorming/SKILL.md +2 -2
- package/template/skills/cowork-flow/SKILL.md +42 -0
- package/template/skills/party-mode/SHARED-BOUNDARIES.md +1 -1
- package/template/skills/party-mode/SKILL.md +48 -119
- package/template/.cowork-flow/scripts/common/gates/spec_validator.py +0 -53
- package/template/.cowork-flow/scripts/common/gates/validate_jsonl.py +0 -32
- package/template/skills/before-dev/SKILL.md +0 -41
- package/template/skills/check/SKILL.md +0 -53
- package/template/skills/check/simplification-guide.md +0 -47
- package/template/skills/continue/SKILL.md +0 -29
- package/template/skills/doubt-review/SKILL.md +0 -118
- package/template/skills/finish-work/SKILL.md +0 -32
- package/template/skills/party-mode-v2/SKILL.md +0 -75
- package/template/skills/start/SKILL.md +0 -78
- package/template/skills/tdd/SKILL.md +0 -74
- package/template/skills/update-spec/SKILL.md +0 -39
- package/template/skills/using-cowork-flow/SKILL.md +0 -80
|
@@ -1,36 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Emit cowork-flow workflow context for Codex
|
|
2
|
+
"""Emit cowork-flow workflow context for Codex hooks."""
|
|
3
3
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
import json
|
|
7
|
-
import hashlib
|
|
8
7
|
import os
|
|
9
|
-
import re
|
|
10
8
|
import sys
|
|
11
9
|
from pathlib import Path
|
|
12
10
|
from typing import Any
|
|
13
11
|
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"Formal subagent work is keyed by cowork_runtime_context_id.",
|
|
26
|
-
"Explicit shim bind records bound_context_key before formal output is accepted.",
|
|
27
|
-
],
|
|
28
|
-
"readWhen": ["before formal subagent dispatch", "when checking subagent health"],
|
|
29
|
-
},
|
|
30
|
-
]
|
|
31
|
-
}
|
|
13
|
+
def _read_input() -> dict[str, Any]:
|
|
14
|
+
raw = sys.stdin.buffer.read()
|
|
15
|
+
if not raw.strip():
|
|
16
|
+
return {}
|
|
17
|
+
try:
|
|
18
|
+
data = json.loads(raw.decode("utf-8-sig"))
|
|
19
|
+
except (UnicodeDecodeError, json.JSONDecodeError, ValueError):
|
|
20
|
+
return {}
|
|
21
|
+
return data if isinstance(data, dict) else {}
|
|
22
|
+
|
|
32
23
|
|
|
33
|
-
def
|
|
24
|
+
def _find_root(start: Path) -> Path | None:
|
|
34
25
|
current = start.resolve()
|
|
35
26
|
while True:
|
|
36
27
|
if (current / ".cowork-flow").is_dir():
|
|
@@ -40,263 +31,53 @@ def _find_repo_root(start: Path) -> Path | None:
|
|
|
40
31
|
current = current.parent
|
|
41
32
|
|
|
42
33
|
|
|
43
|
-
def _read_hook_input() -> dict[str, Any]:
|
|
44
|
-
try:
|
|
45
|
-
raw = sys.stdin.buffer.read()
|
|
46
|
-
except AttributeError:
|
|
47
|
-
text = sys.stdin.read()
|
|
48
|
-
else:
|
|
49
|
-
if not raw.strip():
|
|
50
|
-
return {}
|
|
51
|
-
try:
|
|
52
|
-
text = raw.decode("utf-8-sig")
|
|
53
|
-
except UnicodeDecodeError:
|
|
54
|
-
encoding = getattr(sys.stdin, "encoding", None) or "utf-8"
|
|
55
|
-
text = raw.decode(encoding, errors="replace")
|
|
56
|
-
if not text.strip():
|
|
57
|
-
return {}
|
|
58
|
-
try:
|
|
59
|
-
data = json.loads(text)
|
|
60
|
-
except (json.JSONDecodeError, ValueError):
|
|
61
|
-
return {}
|
|
62
|
-
return data if isinstance(data, dict) else {}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def _load_breadcrumbs(root: Path) -> dict[str, str]:
|
|
66
|
-
workflow = root / ".cowork-flow" / "spec" / "contracts" / "workflow-state-templates.md"
|
|
67
|
-
try:
|
|
68
|
-
text = workflow.read_text(encoding="utf-8")
|
|
69
|
-
except OSError:
|
|
70
|
-
return {}
|
|
71
|
-
return {match.group(1): match.group(2).strip() for match in TAG_RE.finditer(text)}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def _as_string_list(value: Any) -> list[str]:
|
|
75
|
-
if not isinstance(value, list):
|
|
76
|
-
return []
|
|
77
|
-
return [item for item in value if isinstance(item, str) and item.strip()]
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def _load_contract_registry(root: Path) -> tuple[list[dict[str, Any]], str | None]:
|
|
81
|
-
registry_file = root / ".cowork-flow" / "spec" / "runtime" / "contract-registry.json"
|
|
82
|
-
try:
|
|
83
|
-
data = json.loads(registry_file.read_text(encoding="utf-8"))
|
|
84
|
-
except OSError:
|
|
85
|
-
data = DEFAULT_CONTRACT_REGISTRY
|
|
86
|
-
warning = f"contract registry unavailable at {registry_file}; using fallback digest"
|
|
87
|
-
except json.JSONDecodeError:
|
|
88
|
-
data = DEFAULT_CONTRACT_REGISTRY
|
|
89
|
-
warning = f"contract registry invalid at {registry_file}; using fallback digest"
|
|
90
|
-
else:
|
|
91
|
-
warning = None
|
|
92
|
-
contracts = data.get("contracts") if isinstance(data, dict) else None
|
|
93
|
-
if not isinstance(contracts, list):
|
|
94
|
-
contracts = DEFAULT_CONTRACT_REGISTRY["contracts"]
|
|
95
|
-
warning = warning or f"contract registry has no contracts array at {registry_file}; using fallback digest"
|
|
96
|
-
return [contract for contract in contracts if isinstance(contract, dict)], warning
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def _contract_fingerprint(root: Path, contracts: list[dict[str, Any]]) -> str:
|
|
100
|
-
digest = hashlib.sha256()
|
|
101
|
-
digest.update(json.dumps(contracts, ensure_ascii=False, sort_keys=True).encode("utf-8"))
|
|
102
|
-
for contract in contracts:
|
|
103
|
-
path = contract.get("path")
|
|
104
|
-
if not isinstance(path, str) or not path.strip():
|
|
105
|
-
continue
|
|
106
|
-
try:
|
|
107
|
-
digest.update((root / path).read_bytes())
|
|
108
|
-
except OSError:
|
|
109
|
-
digest.update(f"missing:{path}".encode("utf-8"))
|
|
110
|
-
return digest.hexdigest()[:16]
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def _build_contract_digest(root: Path) -> str:
|
|
114
|
-
contracts, warning = _load_contract_registry(root)
|
|
115
|
-
fingerprint = _contract_fingerprint(root, contracts)
|
|
116
|
-
lines = [
|
|
117
|
-
'<cowork-runtime host="codex" adapter="codex.spawn_agent">',
|
|
118
|
-
f'<contract-digest fingerprint="{fingerprint}">',
|
|
119
|
-
"policy: repeat this short digest every hook; read full spec files only before listed actions.",
|
|
120
|
-
]
|
|
121
|
-
if warning:
|
|
122
|
-
lines.append(f"warning: {warning}")
|
|
123
|
-
for contract in contracts:
|
|
124
|
-
contract_id = contract.get("id")
|
|
125
|
-
path = contract.get("path")
|
|
126
|
-
if not isinstance(contract_id, str) or not contract_id.strip():
|
|
127
|
-
continue
|
|
128
|
-
path_text = path if isinstance(path, str) and path.strip() else "<missing-path>"
|
|
129
|
-
lines.append(f"- {contract_id}: {path_text}")
|
|
130
|
-
for item in _as_string_list(contract.get("digest"))[:2]:
|
|
131
|
-
lines.append(f" digest: {item}")
|
|
132
|
-
read_when = _as_string_list(contract.get("readWhen"))
|
|
133
|
-
if read_when:
|
|
134
|
-
lines.append(f" read_before: {'; '.join(read_when)}")
|
|
135
|
-
lines.extend(["</contract-digest>", "</cowork-runtime>"])
|
|
136
|
-
return "\n".join(lines)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def _load_common(root: Path) -> None:
|
|
140
|
-
scripts_dir = root / ".cowork-flow" / "scripts"
|
|
141
|
-
if str(scripts_dir) not in sys.path:
|
|
142
|
-
sys.path.insert(0, str(scripts_dir))
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def _get_dispatch_mode(root: Path) -> str:
|
|
146
|
-
_load_common(root)
|
|
147
|
-
try:
|
|
148
|
-
from common.core.config import get_codex_dispatch_mode # type: ignore[import-not-found]
|
|
149
|
-
except Exception:
|
|
150
|
-
return "sub-agent"
|
|
151
|
-
try:
|
|
152
|
-
return get_codex_dispatch_mode(root)
|
|
153
|
-
except Exception:
|
|
154
|
-
return "sub-agent"
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def _get_active_task(root: Path, hook_input: dict[str, Any]) -> tuple[str | None, str, str]:
|
|
158
|
-
_load_common(root)
|
|
159
|
-
try:
|
|
160
|
-
from common.task.active_task import get_active_task # type: ignore[import-not-found]
|
|
161
|
-
except Exception:
|
|
162
|
-
return None, "no_task", "unavailable"
|
|
163
|
-
|
|
164
|
-
active = get_active_task(root, hook_input)
|
|
165
|
-
if not active.task_path:
|
|
166
|
-
return None, "no_task", active.source
|
|
167
|
-
|
|
168
|
-
task_dir = root / active.task_path
|
|
169
|
-
task_json = task_dir / "task.json"
|
|
170
|
-
try:
|
|
171
|
-
data = json.loads(task_json.read_text(encoding="utf-8"))
|
|
172
|
-
except (OSError, json.JSONDecodeError):
|
|
173
|
-
return active.task_path, "stale", active.source
|
|
174
|
-
|
|
175
|
-
status = data.get("status")
|
|
176
|
-
if not isinstance(status, str) or not status.strip():
|
|
177
|
-
status = "unknown"
|
|
178
|
-
return active.task_path, status.strip(), active.source
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
def _resolve_runtime_context(root: Path, hook_input: dict[str, Any]) -> tuple[dict[str, Any] | None, str | None]:
|
|
182
|
-
_load_common(root)
|
|
183
|
-
try:
|
|
184
|
-
from common.task.active_task import ( # type: ignore[import-not-found]
|
|
185
|
-
bind_runtime_context,
|
|
186
|
-
read_runtime_context,
|
|
187
|
-
resolve_runtime_context_id,
|
|
188
|
-
)
|
|
189
|
-
except Exception:
|
|
190
|
-
return None, None
|
|
191
|
-
|
|
192
|
-
runtime_context_id = resolve_runtime_context_id(hook_input)
|
|
193
|
-
if not runtime_context_id:
|
|
194
|
-
return None, None
|
|
195
|
-
|
|
196
|
-
context = read_runtime_context(root, runtime_context_id)
|
|
197
|
-
if not context or context.get("scope") != "subagent" or context.get("status") == "closed":
|
|
198
|
-
return None, runtime_context_id
|
|
199
|
-
|
|
200
|
-
bound = bind_runtime_context(root, runtime_context_id, values=hook_input)
|
|
201
|
-
return bound or context, runtime_context_id
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def _subagent_runtime_lines(context: dict[str, Any]) -> list[str]:
|
|
205
|
-
assignment = context.get("assignment") if isinstance(context.get("assignment"), dict) else {}
|
|
206
|
-
lines = [
|
|
207
|
-
f"Runtime context: {context.get('runtime_context_id')}",
|
|
208
|
-
f"Agent: {context.get('agent_type') or 'unknown'}",
|
|
209
|
-
"Scope: subagent",
|
|
210
|
-
"Do not run start/resume/task start/archive/commit/spawn.",
|
|
211
|
-
]
|
|
212
|
-
goal = assignment.get("goal") if isinstance(assignment, dict) else None
|
|
213
|
-
if isinstance(goal, str) and goal.strip():
|
|
214
|
-
lines.append(f"Goal: {goal.strip()}")
|
|
215
|
-
return lines
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
def _build_context(
|
|
219
|
-
root: Path,
|
|
220
|
-
task_path: str | None,
|
|
221
|
-
status: str,
|
|
222
|
-
source: str,
|
|
223
|
-
breadcrumbs: dict[str, str],
|
|
224
|
-
dispatch_mode: str,
|
|
225
|
-
extra_lines: list[str] | None = None,
|
|
226
|
-
) -> str:
|
|
227
|
-
body = breadcrumbs.get(status) or "Refer to .cowork-flow/workflow.md for the current step."
|
|
228
|
-
if extra_lines:
|
|
229
|
-
body = "\n".join([body, *extra_lines])
|
|
230
|
-
if task_path is None:
|
|
231
|
-
header = f"Status: {status}\nSource: {source}"
|
|
232
|
-
else:
|
|
233
|
-
header = f"Task: {task_path}\nStatus: {status}\nSource: {source}"
|
|
234
|
-
|
|
235
|
-
return "\n\n".join(
|
|
236
|
-
[
|
|
237
|
-
f"<codex-dispatch-mode>{dispatch_mode}</codex-dispatch-mode>",
|
|
238
|
-
(
|
|
239
|
-
"<codex-runtime>\n"
|
|
240
|
-
"dispatch_mode_meaning: workflow dispatch hint, not current thread role\n"
|
|
241
|
-
"runtime_context_identity: formal subagent sessions bind before workflow-state injection\n"
|
|
242
|
-
"</codex-runtime>"
|
|
243
|
-
),
|
|
244
|
-
(
|
|
245
|
-
_build_contract_digest(root)
|
|
246
|
-
),
|
|
247
|
-
f"<workflow-state>\n{header}\n{body}\n</workflow-state>",
|
|
248
|
-
]
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
|
|
252
34
|
def main() -> int:
|
|
253
|
-
if
|
|
35
|
+
if (
|
|
36
|
+
os.environ.get("COWORK_FLOW_HOOKS") == "0"
|
|
37
|
+
or os.environ.get("COWORK_FLOW_DISABLE_HOOKS") == "1"
|
|
38
|
+
):
|
|
254
39
|
return 0
|
|
255
|
-
|
|
256
|
-
hook_input = _read_hook_input()
|
|
40
|
+
hook_input = _read_input()
|
|
257
41
|
cwd_value = hook_input.get("cwd")
|
|
258
|
-
cwd =
|
|
259
|
-
|
|
42
|
+
cwd = (
|
|
43
|
+
Path(cwd_value)
|
|
44
|
+
if isinstance(cwd_value, str) and cwd_value.strip()
|
|
45
|
+
else Path.cwd()
|
|
46
|
+
)
|
|
47
|
+
root = _find_root(cwd)
|
|
260
48
|
if root is None:
|
|
261
49
|
return 0
|
|
50
|
+
scripts_dir = root / ".cowork-flow" / "scripts"
|
|
51
|
+
sys.path.insert(0, str(scripts_dir))
|
|
52
|
+
from common.host.workflow_state_hook import (
|
|
53
|
+
build_hook_context,
|
|
54
|
+
codex_dispatch_mode,
|
|
55
|
+
)
|
|
262
56
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
runtime_context, runtime_context_id = _resolve_runtime_context(root, hook_input)
|
|
266
|
-
extra_lines: list[str] | None = None
|
|
267
|
-
if runtime_context is not None:
|
|
268
|
-
task_dir = runtime_context.get("task_dir")
|
|
269
|
-
task_path = task_dir.strip() if isinstance(task_dir, str) and task_dir.strip() else None
|
|
270
|
-
status = "delegated_subtask"
|
|
271
|
-
source = f"runtime-context:{runtime_context.get('runtime_context_id')}"
|
|
272
|
-
extra_lines = _subagent_runtime_lines(runtime_context)
|
|
273
|
-
elif runtime_context_id:
|
|
274
|
-
task_path = None
|
|
275
|
-
status = "delegated_subtask"
|
|
276
|
-
source = f"runtime-context-invalid:{runtime_context_id}"
|
|
277
|
-
extra_lines = [
|
|
278
|
-
f"Runtime context: {runtime_context_id}",
|
|
279
|
-
"Scope: subagent",
|
|
280
|
-
"Runtime context is missing, closed, or invalid. Do not run start/resume/task start/archive/commit/spawn.",
|
|
281
|
-
]
|
|
282
|
-
else:
|
|
283
|
-
task_path, status, source = _get_active_task(root, hook_input)
|
|
284
|
-
additional_context = _build_context(
|
|
57
|
+
dispatch_mode = codex_dispatch_mode(root)
|
|
58
|
+
context = build_hook_context(
|
|
285
59
|
root,
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
60
|
+
hook_input,
|
|
61
|
+
host="codex",
|
|
62
|
+
adapter="codex.spawn_agent",
|
|
63
|
+
preamble=(
|
|
64
|
+
f"<codex-dispatch-mode>{dispatch_mode}</codex-dispatch-mode>",
|
|
65
|
+
(
|
|
66
|
+
"<codex-runtime>\n"
|
|
67
|
+
"dispatch_mode_meaning: workflow dispatch hint, not current "
|
|
68
|
+
"thread role\n"
|
|
69
|
+
"runtime_context_identity: formal subagent sessions bind "
|
|
70
|
+
"before workflow-state injection\n"
|
|
71
|
+
"</codex-runtime>"
|
|
72
|
+
),
|
|
73
|
+
),
|
|
292
74
|
)
|
|
293
|
-
|
|
294
75
|
print(
|
|
295
76
|
json.dumps(
|
|
296
77
|
{
|
|
297
78
|
"hookSpecificOutput": {
|
|
298
79
|
"hookEventName": "UserPromptSubmit",
|
|
299
|
-
"additionalContext":
|
|
80
|
+
"additionalContext": context,
|
|
300
81
|
}
|
|
301
82
|
},
|
|
302
83
|
ensure_ascii=False,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.39
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Application services for cowork-flow commands."""
|