cowork-flow 0.0.24 → 0.0.26

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.24",
3
+ "version": "0.0.26",
4
4
  "description": "CLI for installing and maintaining cowork-flow collaboration templates.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,7 +20,7 @@ Use this skill as a manual advisory roundtable. Coordinate true child agents, no
20
20
  Built-in defaults:
21
21
 
22
22
  - `max_agents=3`
23
- - `max_rounds=3`
23
+ - `max_rounds=5`
24
24
 
25
25
  These defaults are configurable values, not hard-coded constants. Effective config order:
26
26
 
@@ -35,7 +35,7 @@ Configurable fields:
35
35
  - agent roster or review lenses
36
36
  - report enabled
37
37
  - report path
38
- - whether round 2 or round 3 is allowed
38
+ - round phase policy, including when challenge may continue and when convergence must begin
39
39
 
40
40
  Safety gates:
41
41
 
@@ -47,10 +47,14 @@ Safety gates:
47
47
  ## Round Model
48
48
 
49
49
  1. Frame the question, decision needed, scope, and evidence packet.
50
- 2. Round 1 uses fresh child contexts. Send each child the same packet and one lens. Child agents cannot see each other.
51
- 3. Synthesize only evidence-backed positions, disagreements, rejected options, and acceptance signals.
52
- 4. Continue only when a continue condition is met. Send narrow follow-up prompts to the smallest useful set of children.
53
- 5. Stop when any stop condition is met. Close all live children through the Host Adapter close primitive.
50
+ 2. Select the smallest useful agent roster or review lenses within effective `max_agents`. Record why each selected voice is useful and why omitted voices are not needed.
51
+ 3. Round 1 uses fresh child contexts. Send each child the same packet and one lens. Child agents cannot see each other.
52
+ 4. Synthesize evidence-backed positions into a compact claim table: `claim_id`, owner, claim, evidence, counterclaim, evidence gap, and decision impact.
53
+ 5. Continue only when a continue condition is met. Send narrow follow-up prompts to the smallest useful set of children, and bind each prompt to one `claim_id`.
54
+ 6. Follow-up rounds should prefer the same live child that produced or challenged the relevant position. Send only the target claim, counterclaim, evidence gap, and ask the child to `agree`, `reject`, or `revise`.
55
+ 7. For Challenge rounds, the default stance is scrutiny. Test the opposing claim first; choose `agree` only after naming the evidence that compels agreement.
56
+ 8. Spawn an extra child only when the effective roster or lens config allows it, a live child failed, or the user approves expansion.
57
+ 9. Stop when any stop condition is met and no dispatched child is still running. Then close live children through the Host Adapter close primitive.
54
58
 
55
59
  Round intent:
56
60
 
@@ -61,10 +65,10 @@ Round intent:
61
65
  Default mapping:
62
66
 
63
67
  - Round 1 = Opening.
64
- - Round 2 = Challenge.
65
- - Round 3+ = Convergence.
68
+ - Round 2+ = Challenge while continue conditions still expose material disagreement, material risk, missing evidence, or untestable acceptance criteria.
69
+ - Convergence begins when the coordinator can write one recommended direction and no material challenge condition remains.
66
70
 
67
- Only the user can restart exploration after convergence begins.
71
+ After convergence begins, do not reopen exploration unless the user approves or new concrete evidence appears.
68
72
 
69
73
  ## Continue Conditions
70
74
 
@@ -86,6 +90,13 @@ Stop when any condition holds:
86
90
  - Effective `max_rounds` is reached.
87
91
  - Output fails schema, and one repair prompt does not fix it.
88
92
 
93
+ ## Waiting Children
94
+
95
+ - A wait timeout is not a child timeout.
96
+ - If a child remains live after a wait timeout, wait again or report it in `pending_children`.
97
+ - Do not close, cancel, omit, or synthesize around a live child unless the user explicitly asks to close it.
98
+ - When the discussion has converged or the user ends it, close live children after their final output is recorded.
99
+
89
100
  ## Child Output Schema
90
101
 
91
102
  Each child must return these core fields. Extra fields are allowed only after them.
@@ -100,6 +111,18 @@ acceptance_signal:
100
111
  what_would_change_my_mind:
101
112
  ```
102
113
 
114
+ Follow-up rounds may add these fields after the core fields:
115
+
116
+ ```text
117
+ claim_id:
118
+ responding_to:
119
+ opposing_claim:
120
+ position_delta:
121
+ evidence_delta:
122
+ still_disagree:
123
+ ```
124
+
125
+ Use `position_delta` to say whether the child maintained, narrowed, or changed its position.
103
126
  Reject unsupported opinion. Evidence should name files, commands, rules, observed behavior, user scenarios, or concrete assumptions.
104
127
 
105
128
  ## Coordinator Output Schema
@@ -107,6 +130,13 @@ Reject unsupported opinion. Evidence should name files, commands, rules, observe
107
130
  Final synthesis must return these core fields. Extra fields are allowed only after them.
108
131
 
109
132
  ```text
133
+ effective_max_agents:
134
+ effective_max_rounds:
135
+ rounds_used:
136
+ selected_agents:
137
+ claim_table:
138
+ agent_turns:
139
+ pending_children:
110
140
  consensus:
111
141
  disagreements:
112
142
  evidence:
@@ -114,7 +144,8 @@ decision:
114
144
  rejected_options:
115
145
  acceptance_criteria:
116
146
  open_questions:
147
+ early_stop_reason:
117
148
  stop_reason:
118
149
  ```
119
150
 
120
- Keep the final decision traceable to child evidence. Do not count votes as validation.
151
+ `selected_agents` must include the selected agent or lens names and selection reasons. `agent_turns` should preserve a compact transcript with round, agent or lens, `claim_id`, position, and `position_delta`. Keep the final decision traceable to child evidence. Do not count votes as validation.
@@ -20,7 +20,7 @@ Use this skill as a manual advisory roundtable. Coordinate true child agents, no
20
20
  Built-in defaults:
21
21
 
22
22
  - `max_agents=3`
23
- - `max_rounds=3`
23
+ - `max_rounds=5`
24
24
 
25
25
  These defaults are configurable values, not hard-coded constants. Effective config order:
26
26
 
@@ -35,7 +35,7 @@ Configurable fields:
35
35
  - agent roster or review lenses
36
36
  - report enabled
37
37
  - report path
38
- - whether round 2 or round 3 is allowed
38
+ - round phase policy, including when challenge may continue and when convergence must begin
39
39
 
40
40
  Safety gates:
41
41
 
@@ -47,10 +47,14 @@ Safety gates:
47
47
  ## Round Model
48
48
 
49
49
  1. Frame the question, decision needed, scope, and evidence packet.
50
- 2. Round 1 uses fresh child contexts. Send each child the same packet and one lens. Child agents cannot see each other.
51
- 3. Synthesize only evidence-backed positions, disagreements, rejected options, and acceptance signals.
52
- 4. Continue only when a continue condition is met. Send narrow follow-up prompts to the smallest useful set of children.
53
- 5. Stop when any stop condition is met. Close all live children through the Host Adapter close primitive.
50
+ 2. Select the smallest useful agent roster or review lenses within effective `max_agents`. Record why each selected voice is useful and why omitted voices are not needed.
51
+ 3. Round 1 uses fresh child contexts. Send each child the same packet and one lens. Child agents cannot see each other.
52
+ 4. Synthesize evidence-backed positions into a compact claim table: `claim_id`, owner, claim, evidence, counterclaim, evidence gap, and decision impact.
53
+ 5. Continue only when a continue condition is met. Send narrow follow-up prompts to the smallest useful set of children, and bind each prompt to one `claim_id`.
54
+ 6. Follow-up rounds should prefer the same live child that produced or challenged the relevant position. Send only the target claim, counterclaim, evidence gap, and ask the child to `agree`, `reject`, or `revise`.
55
+ 7. For Challenge rounds, the default stance is scrutiny. Test the opposing claim first; choose `agree` only after naming the evidence that compels agreement.
56
+ 8. Spawn an extra child only when the effective roster or lens config allows it, a live child failed, or the user approves expansion.
57
+ 9. Stop when any stop condition is met and no dispatched child is still running. Then close live children through the Host Adapter close primitive.
54
58
 
55
59
  Round intent:
56
60
 
@@ -61,10 +65,10 @@ Round intent:
61
65
  Default mapping:
62
66
 
63
67
  - Round 1 = Opening.
64
- - Round 2 = Challenge.
65
- - Round 3+ = Convergence.
68
+ - Round 2+ = Challenge while continue conditions still expose material disagreement, material risk, missing evidence, or untestable acceptance criteria.
69
+ - Convergence begins when the coordinator can write one recommended direction and no material challenge condition remains.
66
70
 
67
- Only the user can restart exploration after convergence begins.
71
+ After convergence begins, do not reopen exploration unless the user approves or new concrete evidence appears.
68
72
 
69
73
  ## Continue Conditions
70
74
 
@@ -86,6 +90,13 @@ Stop when any condition holds:
86
90
  - Effective `max_rounds` is reached.
87
91
  - Output fails schema, and one repair prompt does not fix it.
88
92
 
93
+ ## Waiting Children
94
+
95
+ - A wait timeout is not a child timeout.
96
+ - If a child remains live after a wait timeout, wait again or report it in `pending_children`.
97
+ - Do not close, cancel, omit, or synthesize around a live child unless the user explicitly asks to close it.
98
+ - When the discussion has converged or the user ends it, close live children after their final output is recorded.
99
+
89
100
  ## Child Output Schema
90
101
 
91
102
  Each child must return these core fields. Extra fields are allowed only after them.
@@ -100,6 +111,18 @@ acceptance_signal:
100
111
  what_would_change_my_mind:
101
112
  ```
102
113
 
114
+ Follow-up rounds may add these fields after the core fields:
115
+
116
+ ```text
117
+ claim_id:
118
+ responding_to:
119
+ opposing_claim:
120
+ position_delta:
121
+ evidence_delta:
122
+ still_disagree:
123
+ ```
124
+
125
+ Use `position_delta` to say whether the child maintained, narrowed, or changed its position.
103
126
  Reject unsupported opinion. Evidence should name files, commands, rules, observed behavior, user scenarios, or concrete assumptions.
104
127
 
105
128
  ## Coordinator Output Schema
@@ -107,6 +130,13 @@ Reject unsupported opinion. Evidence should name files, commands, rules, observe
107
130
  Final synthesis must return these core fields. Extra fields are allowed only after them.
108
131
 
109
132
  ```text
133
+ effective_max_agents:
134
+ effective_max_rounds:
135
+ rounds_used:
136
+ selected_agents:
137
+ claim_table:
138
+ agent_turns:
139
+ pending_children:
110
140
  consensus:
111
141
  disagreements:
112
142
  evidence:
@@ -114,7 +144,8 @@ decision:
114
144
  rejected_options:
115
145
  acceptance_criteria:
116
146
  open_questions:
147
+ early_stop_reason:
117
148
  stop_reason:
118
149
  ```
119
150
 
120
- Keep the final decision traceable to child evidence. Do not count votes as validation.
151
+ `selected_agents` must include the selected agent or lens names and selection reasons. `agent_turns` should preserve a compact transcript with round, agent or lens, `claim_id`, position, and `position_delta`. Keep the final decision traceable to child evidence. Do not count votes as validation.
@@ -1 +1 @@
1
- 0.0.24
1
+ 0.0.26
@@ -66,6 +66,10 @@ def resolve_context_key(values: Mapping[str, object] | None = None) -> str | Non
66
66
  if claude_session and claude_session.strip():
67
67
  return f"claude_{_sanitize(claude_session)}"
68
68
 
69
+ claude_code_session = os.environ.get("CLAUDE_CODE_SESSION_ID")
70
+ if claude_code_session and claude_code_session.strip():
71
+ return f"claude_{_sanitize(claude_code_session)}"
72
+
69
73
  codex_session = os.environ.get("CODEX_SESSION_ID")
70
74
  if codex_session and codex_session.strip():
71
75
  return f"codex_{_sanitize(codex_session)}"
@@ -90,6 +94,8 @@ def resolve_context_key(values: Mapping[str, object] | None = None) -> str | Non
90
94
  (
91
95
  "OPENCODE_SESSION_ID",
92
96
  "opencode_session_id",
97
+ "sessionID",
98
+ "sessionId",
93
99
  ),
94
100
  )
95
101
  if input_opencode_session:
@@ -100,6 +106,8 @@ def resolve_context_key(values: Mapping[str, object] | None = None) -> str | Non
100
106
  (
101
107
  "CLAUDE_SESSION_ID",
102
108
  "claude_session_id",
109
+ "CLAUDE_CODE_SESSION_ID",
110
+ "claude_code_session_id",
103
111
  ),
104
112
  )
105
113
  if input_claude_session:
@@ -253,6 +253,7 @@ def build_parser() -> argparse.ArgumentParser:
253
253
  init.add_argument("--title", required=True)
254
254
  init.add_argument("--role", default="subagent")
255
255
  init.add_argument("--agent-type")
256
+ init.add_argument("--execution-task-dir", default=argparse.SUPPRESS)
256
257
  init.add_argument("--source", default="auto")
257
258
  init.add_argument("--goal")
258
259
  init.add_argument("--expected-output", default="Files changed, validation commands, and blockers.")
@@ -931,7 +931,7 @@ def cmd_start(args: argparse.Namespace) -> int:
931
931
  if active is None:
932
932
  print(
933
933
  colored(
934
- "Error: Missing session context. Set COWORK_FLOW_CONTEXT_ID or run inside Codex session.",
934
+ "Error: Missing session context. Set COWORK_FLOW_CONTEXT_ID or run inside a supported host session.",
935
935
  Colors.RED,
936
936
  ),
937
937
  file=sys.stderr,
@@ -1011,7 +1011,7 @@ def cmd_current(args: argparse.Namespace) -> int:
1011
1011
  if not active.context_key:
1012
1012
  print(
1013
1013
  colored(
1014
- "Error: Missing session context. Set COWORK_FLOW_CONTEXT_ID or run inside Codex session.",
1014
+ "Error: Missing session context. Set COWORK_FLOW_CONTEXT_ID or run inside a supported host session.",
1015
1015
  Colors.RED,
1016
1016
  ),
1017
1017
  file=sys.stderr,
@@ -202,15 +202,47 @@ function resolveRuntimeContextId(input) {
202
202
  return match ? sanitize(match[1]) : null
203
203
  }
204
204
 
205
+ function resolveOpenCodeSessionId(input) {
206
+ const direct = firstString(input, [
207
+ "OPENCODE_SESSION_ID",
208
+ "opencode_session_id",
209
+ "sessionID",
210
+ "sessionId",
211
+ "session_id",
212
+ ])
213
+ if (direct) {
214
+ return sanitize(direct)
215
+ }
216
+ const nested = firstString(input?.session, ["id", "sessionID", "sessionId", "session_id"])
217
+ return nested ? sanitize(nested) : null
218
+ }
219
+
205
220
  function resolveContextKey(input) {
206
221
  const explicit = firstString(input, ["COWORK_FLOW_CONTEXT_ID", "cowork_flow_context_id", "context_id"])
207
222
  if (explicit) {
208
223
  return sanitize(explicit)
209
224
  }
210
- const opencodeSession = firstString(input, ["OPENCODE_SESSION_ID", "opencode_session_id", "session_id"])
225
+ const opencodeSession = resolveOpenCodeSessionId(input)
211
226
  return opencodeSession ? `opencode_${sanitize(opencodeSession)}` : null
212
227
  }
213
228
 
229
+ function injectShellEnv(input, output) {
230
+ const contextKey = resolveContextKey(input)
231
+ if (!contextKey) {
232
+ return
233
+ }
234
+ if (!output.env || typeof output.env !== "object") {
235
+ output.env = {}
236
+ }
237
+ if (!output.env.COWORK_FLOW_CONTEXT_ID) {
238
+ output.env.COWORK_FLOW_CONTEXT_ID = contextKey
239
+ }
240
+ const opencodeSession = resolveOpenCodeSessionId(input)
241
+ if (opencodeSession && !output.env.OPENCODE_SESSION_ID) {
242
+ output.env.OPENCODE_SESSION_ID = opencodeSession
243
+ }
244
+ }
245
+
214
246
  function resolveHostContextKey(input) {
215
247
  const direct = firstString(input, ["cowork_host_context_key", "host_context_key", "COWORK_FLOW_HOST_CONTEXT_KEY"])
216
248
  if (direct) {
@@ -310,6 +342,9 @@ function buildRuntimeWorkflowState(input) {
310
342
 
311
343
  export const CoworkFlowPlugin = async () => {
312
344
  return {
345
+ "shell.env": async (input, output) => {
346
+ injectShellEnv(input, output)
347
+ },
313
348
  "experimental.chat.system.transform": async (input, output) => {
314
349
  output.system.push([buildContractDigest(input), buildRuntimeWorkflowState(input)].filter(Boolean).join("\n\n"))
315
350
  },