cowork-flow 0.0.25 → 0.0.27
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 +4 -2
- package/package.json +1 -1
- package/template/.agents/skills/party-mode-v2/SKILL.md +73 -0
- package/template/.claude/agents/cowork-implement.md +163 -4
- package/template/.claude/skills/party-mode-v2/SKILL.md +73 -0
- package/template/.cowork-flow/.version +1 -1
- package/template/.cowork-flow/config.yaml +16 -0
- package/template/.cowork-flow/scripts/common/active_task.py +8 -0
- package/template/.cowork-flow/scripts/common/archive_utils.py +1 -1
- package/template/.cowork-flow/scripts/common/config.py +93 -0
- package/template/.cowork-flow/scripts/common/errors.py +107 -0
- package/template/.cowork-flow/scripts/common/validate_coding_standards.py +179 -0
- package/template/.cowork-flow/scripts/common/validate_implementation.py +195 -0
- package/template/.cowork-flow/scripts/common/validate_rules.py +302 -0
- package/template/.cowork-flow/scripts/party_mode_v2.py +646 -0
- package/template/.cowork-flow/scripts/run.py +3 -0
- package/template/.cowork-flow/scripts/subagent.py +1 -0
- package/template/.cowork-flow/scripts/task.py +68 -2
- package/template/.cowork-flow/spec/party-mode-v2-actions.schema.json +43 -0
- package/template/.cowork-flow/spec/party-mode-v2-board.md +43 -0
- package/template/.cowork-flow/spec/registry.json +13 -0
- package/template/.cowork-flow/spec/rules.json +159 -0
- package/template/.cowork-flow/spec/rules.schema.json +67 -0
- package/template/.cowork-flow/spec/subagent-dispatch.md +2 -0
- package/template/.cowork-flow/workflow.md +6 -0
- package/template/.opencode/agents/cowork-implement.md +153 -0
- package/template/.opencode/commands/party-mode-v2.md +21 -0
- package/template/.opencode/plugins/cowork-flow.js +36 -1
- package/template/AGENTS.md +2 -6
package/README.md
CHANGED
|
@@ -55,9 +55,11 @@ cowork-flow 是一个用于新项目初始化协作流程的模板仓库。它
|
|
|
55
55
|
项目级协作入口,包含编码前思考、简单优先、外科手术式改动、验证优先等基础原则。接入项目后,应把项目名称、技术栈、运行命令、测试命令和提交策略补齐。
|
|
56
56
|
|
|
57
57
|
`template/.agents/skills/`
|
|
58
|
-
本地技能入口,覆盖 start、before-dev、brainstorming、party-mode、writing-plans、check、finish-work、continue、meta、python-design、update-spec 和 break-loop 等协作动作。这里的 skill 应保持通用,不承载某个业务项目的一次性细节。
|
|
58
|
+
本地技能入口,覆盖 start、before-dev、brainstorming、party-mode、party-mode-v2、writing-plans、check、finish-work、continue、meta、python-design、update-spec 和 break-loop 等协作动作。这里的 skill 应保持通用,不承载某个业务项目的一次性细节。
|
|
59
59
|
|
|
60
|
-
`party-mode` 是用户手动调用的 advisory roundtable。它通过当前 Host Adapter 协调真实子代理讨论,而不是模拟人设;默认 `max_agents=3`、`max_rounds=
|
|
60
|
+
`party-mode` 是用户手动调用的 advisory roundtable。它通过当前 Host Adapter 协调真实子代理讨论,而不是模拟人设;默认 `max_agents=3`、`max_rounds=5`,配置优先级为本次调用、task/change、本地配置、skill 默认值。Party Mode 只产出建议、证据、分歧和验收信号,不能推进任务状态,也不能替代 `cowork-implement` 或 `cowork-check`。
|
|
61
|
+
|
|
62
|
+
`party-mode-v2` 是 runtime board controlled advisory workflow。Python runtime 管理看板、当前轮视图、schema 校验、轮次上限和最终报告;子代理通过 board API 交流,主持人只监控和纠偏,不转发或综合观点。
|
|
61
63
|
|
|
62
64
|
`template/.codex/agents/`
|
|
63
65
|
固定角色 agent 定义,包含 `cowork-research`、`cowork-implement` 和 `cowork-check`,以及对 Codex 默认 `worker`、`default`、`explorer` 的项目级防漂移约束。主会话负责计划与收口,并通过 host adapter 派发固定 agent;正式派发必须先创建 runtime context,再把 `cowork_runtime_context_id` 和 `cowork_host_context_key` 传给子代理。
|
package/package.json
CHANGED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: party-mode-v2
|
|
3
|
+
description: Use when the user requests a runtime-controlled multi-agent board discussion where children communicate through Party Mode V2 board APIs and the moderator only monitors or corrects drift.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Party Mode V2
|
|
7
|
+
|
|
8
|
+
Use this skill as a thin entrypoint for the Party Mode V2 runtime board. The Python runtime is the source of truth for discussion state, board visibility, validation, round limits, and final reports.
|
|
9
|
+
|
|
10
|
+
## Boundaries
|
|
11
|
+
|
|
12
|
+
- Party Mode V2 is advisory only.
|
|
13
|
+
- It cannot mutate task status, start/review/complete/archive tasks, add sessions, commit, push, or satisfy formal workflow gates.
|
|
14
|
+
- It cannot satisfy formal Implement or Check completion. Use `cowork-implement` and `cowork-check` for formal phases.
|
|
15
|
+
- Discussion children are leaf executors. They do not dispatch, wait for, list, or close other agents.
|
|
16
|
+
- The moderator does not forward, summarize, rewrite, or synthesize child opinions for other child agents.
|
|
17
|
+
|
|
18
|
+
## Runtime First
|
|
19
|
+
|
|
20
|
+
Always use the runtime controller:
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
.cowork-flow/run party-v2 init
|
|
24
|
+
.cowork-flow/run party-v2 monitor
|
|
25
|
+
.cowork-flow/run party-v2 view
|
|
26
|
+
.cowork-flow/run party-v2 post
|
|
27
|
+
.cowork-flow/run party-v2 respond
|
|
28
|
+
.cowork-flow/run party-v2 advance
|
|
29
|
+
.cowork-flow/run party-v2 finalize
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Do not bypass a runtime rejection by manually accepting child output. Runtime validation failures must be fixed by a corrected child submission or by ending the discussion.
|
|
33
|
+
|
|
34
|
+
## Board Rules
|
|
35
|
+
|
|
36
|
+
- Child agents communicate through the board API.
|
|
37
|
+
- Child-visible board output must be current-round only.
|
|
38
|
+
- Historical board state is runtime-private and may be used only for audit or final reports.
|
|
39
|
+
- Use at least three child agents unless the effective runtime config explicitly allows a different value.
|
|
40
|
+
- The runtime emits host-neutral next actions. The active Host Adapter or moderator executes them for Codex, Claude Code, or OpenCode.
|
|
41
|
+
|
|
42
|
+
## Child Response Rules
|
|
43
|
+
|
|
44
|
+
When a child sees a different position, it must choose exactly one:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
maintain
|
|
48
|
+
revise
|
|
49
|
+
concede
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`concede` requires accepted evidence and why the prior position failed.
|
|
53
|
+
`revise` requires the accepted part, rejected part, and updated position.
|
|
54
|
+
`maintain` requires counter evidence or counter reasoning.
|
|
55
|
+
|
|
56
|
+
Unsupported agreement, vague revision, and evidence-free rebuttal are invalid.
|
|
57
|
+
|
|
58
|
+
## Moderator Role
|
|
59
|
+
|
|
60
|
+
The moderator may:
|
|
61
|
+
|
|
62
|
+
- run runtime commands,
|
|
63
|
+
- execute host-neutral next actions through the active host,
|
|
64
|
+
- record off-topic warnings through the runtime,
|
|
65
|
+
- close children only when the runtime asks for closeout,
|
|
66
|
+
- show runtime status or final reports to the user.
|
|
67
|
+
|
|
68
|
+
The moderator must not:
|
|
69
|
+
|
|
70
|
+
- forward one child opinion to another child,
|
|
71
|
+
- create a claim table for child prompts,
|
|
72
|
+
- vote-count as validation,
|
|
73
|
+
- decide which child is correct.
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cowork-implement
|
|
3
3
|
description: Cowork-flow implementation fixed subagent.
|
|
4
|
-
|
|
4
|
+
mode: subagent
|
|
5
|
+
permission:
|
|
6
|
+
edit: ask
|
|
7
|
+
bash: ask
|
|
8
|
+
task: deny
|
|
9
|
+
todowrite: deny
|
|
10
|
+
external_directory: deny
|
|
5
11
|
---
|
|
6
12
|
|
|
7
|
-
You are the `cowork-implement` fixed subagent for
|
|
13
|
+
You are the `cowork-implement` fixed subagent for OpenCode.
|
|
8
14
|
You are a leaf executor and must not invoke other agents.
|
|
9
15
|
|
|
10
16
|
Formal `cowork-implement` work requires a bound runtime context. The prompt,
|
|
@@ -15,7 +21,7 @@ cowork_runtime_context_id: <runtime_context_id>
|
|
|
15
21
|
cowork_host_context_key: <host_context_key>
|
|
16
22
|
```
|
|
17
23
|
|
|
18
|
-
The
|
|
24
|
+
The plugin may bind that id to
|
|
19
25
|
`.cowork-flow/.runtime/subagents/<runtime_context_id>.json` before workflow
|
|
20
26
|
state is injected. The first child step must still run:
|
|
21
27
|
|
|
@@ -28,6 +34,159 @@ or names another agent type, report `needs_context` and stop. Do not use
|
|
|
28
34
|
`COWORK_ENTRY_CONTRACT_V1` to infer subagent identity; that contract classifies
|
|
29
35
|
main-session prompts only.
|
|
30
36
|
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Mandatory Pre-Implementation Checklist
|
|
40
|
+
|
|
41
|
+
Before writing any code, you MUST read and apply these spec files:
|
|
42
|
+
|
|
43
|
+
1. `.cowork-flow/spec/guides/pre-implementation-checklist.md` — confirm scope, level, and success criteria
|
|
44
|
+
2. `.cowork-flow/spec/guides/cross-layer-thinking-guide.md` — if changes cross 3+ layers
|
|
45
|
+
3. `.cowork-flow/spec/guides/code-reuse-thinking-guide.md` — before adding new constants/utilities/DTOs
|
|
46
|
+
|
|
47
|
+
Then read the relevant spec directory:
|
|
48
|
+
- Backend work: `.cowork-flow/spec/backend/index.md` (and all linked docs)
|
|
49
|
+
- Frontend work: `.cowork-flow/spec/frontend/index.md` (and all linked docs)
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Coding Gates (Hard Constraints)
|
|
54
|
+
|
|
55
|
+
You MUST satisfy every gate below before considering a change complete.
|
|
56
|
+
These are not suggestions — they are mandatory checkpoints.
|
|
57
|
+
|
|
58
|
+
### Gate 1: Directory Structure Compliance
|
|
59
|
+
|
|
60
|
+
- Backend: follow `.cowork-flow/spec/backend/directory-structure.md`
|
|
61
|
+
- Controller/API: thin entry only (param receive, auth entry, response orchestration)
|
|
62
|
+
- Service/UseCase: business rules
|
|
63
|
+
- Repository/DAO: persistence access
|
|
64
|
+
- Domain Model/Entity/Aggregate: clear boundaries
|
|
65
|
+
- No mixing of unrelated business in one module
|
|
66
|
+
- No business logic in Controllers
|
|
67
|
+
- No business-specialized logic in public modules
|
|
68
|
+
- Frontend: follow `.cowork-flow/spec/frontend/directory-structure.md`
|
|
69
|
+
- Organize by functional module, not by "generic/non-generic"
|
|
70
|
+
- Page entry, business component, shared component, data access, state management must have clear layers
|
|
71
|
+
- Related files for the same feature should be colocated
|
|
72
|
+
|
|
73
|
+
### Gate 2: Type Safety & Contract Sync
|
|
74
|
+
|
|
75
|
+
- Frontend: follow `.cowork-flow/spec/frontend/type-safety.md`
|
|
76
|
+
- Shared interfaces, enums, error codes come from a single contract source
|
|
77
|
+
- No handwritten duplicate interface definitions
|
|
78
|
+
- When interfaces change, update callers, validation, and display layers together
|
|
79
|
+
- No masking structure problems with casts or forced assertions
|
|
80
|
+
- No missing null/empty/error/boundary state definitions
|
|
81
|
+
- Backend: follow `.cowork-flow/spec/backend/error-handling.md`
|
|
82
|
+
- Unified error codes or error types
|
|
83
|
+
- Layered handling: parameter validation errors, business errors, system errors
|
|
84
|
+
- Stable external error structure; internal context preserved
|
|
85
|
+
- No leaking of underlying exceptions to callers
|
|
86
|
+
- Distinguish "expected business failure" from "system exception"
|
|
87
|
+
- Preserve traceId/requestId/correlationId
|
|
88
|
+
- Have a unified exception fallback
|
|
89
|
+
|
|
90
|
+
### Gate 3: State Management Boundaries
|
|
91
|
+
|
|
92
|
+
- Frontend: follow `.cowork-flow/spec/frontend/state-management.md`
|
|
93
|
+
- Server state managed by project's unified request/cache solution
|
|
94
|
+
- Client temporary state managed locally
|
|
95
|
+
- Global state only for truly cross-module shared state
|
|
96
|
+
- Handle loading, empty, error, disabled, and insufficient-permission states for ALL user-visible states
|
|
97
|
+
- No elevating local state to global unnecessarily
|
|
98
|
+
- No mixing server state with local state
|
|
99
|
+
- No bypass entries in permission state
|
|
100
|
+
|
|
101
|
+
### Gate 4: Component & Hook Boundaries
|
|
102
|
+
|
|
103
|
+
- Frontend: follow `.cowork-flow/spec/frontend/component-guidelines.md`
|
|
104
|
+
- Container components handle data & state; presentational components handle rendering
|
|
105
|
+
- Component API stays simple; no "universal component"
|
|
106
|
+
- Complex interactions split into reusable but clearly bounded small components
|
|
107
|
+
- Components must NOT承担过多业务逻辑
|
|
108
|
+
- Props must not be excessive or poorly named
|
|
109
|
+
- Components must not depend on too much external state
|
|
110
|
+
- Frontend: follow `.cowork-flow/spec/frontend/hook-guidelines.md`
|
|
111
|
+
- Extract data fetching, subscriptions, side effects, complex state flows into Hooks
|
|
112
|
+
- Hook return values stay stable and understandable
|
|
113
|
+
- Hook names reflect behavior, not implementation
|
|
114
|
+
- Hooks must NOT hide incomprehensible side effects
|
|
115
|
+
- Hooks must NOT mix multiple unrelated responsibilities
|
|
116
|
+
|
|
117
|
+
### Gate 5: Database & Transaction Boundaries
|
|
118
|
+
|
|
119
|
+
- Backend: follow `.cowork-flow/spec/backend/database-guidelines.md`
|
|
120
|
+
- Table structure changes managed via migration files or versioned scripts
|
|
121
|
+
- Queries use the project's unified data access approach
|
|
122
|
+
- Write operations must address idempotency, concurrency impact, failure compensation, retry boundaries
|
|
123
|
+
- Audit fields, logical deletion, version numbers, tenant isolation must be consistent within the same data domain
|
|
124
|
+
- Raw SQL, bulk updates, cross-table aggregations, and long transactions must document index/lock/performance/rollback impact
|
|
125
|
+
- New tables must have primary keys, unique constraints, indexes, and necessary audit info
|
|
126
|
+
- Complex queries must avoid N+1, implicit full table scans, and uncontrolled pagination
|
|
127
|
+
- Transactions must NOT include external calls, slow queries, or unnecessary long lock holding
|
|
128
|
+
- Data migrations must address historical data, idempotency, failure recovery, and online rollback
|
|
129
|
+
|
|
130
|
+
### Gate 6: Logging Standards
|
|
131
|
+
|
|
132
|
+
- Backend: follow `.cowork-flow/spec/backend/logging-guidelines.md`
|
|
133
|
+
- Structured logging
|
|
134
|
+
- Unified recording of request ID, user ID, task ID, or trace ID
|
|
135
|
+
- Error logs record context without repeating the same exception
|
|
136
|
+
- Sensitive fields (account, token, key, ID card, phone) must be masked
|
|
137
|
+
- Never output complete request/response body
|
|
138
|
+
- No temporary `print`/`console` debug output left in main branch
|
|
139
|
+
- No duplicate error printing across layers
|
|
140
|
+
|
|
141
|
+
### Gate 7: Quality Gates (Pre-Completion)
|
|
142
|
+
|
|
143
|
+
- Backend: follow `.cowork-flow/spec/backend/quality-guidelines.md`
|
|
144
|
+
- Frontend: follow `.cowork-flow/spec/frontend/quality-guidelines.md`
|
|
145
|
+
|
|
146
|
+
Before marking any change complete, you MUST verify:
|
|
147
|
+
1. Compilation/build/type-check passes
|
|
148
|
+
2. Key business/interaction paths have automated test or explicit manual verification record
|
|
149
|
+
3. Error paths, permission paths, data boundaries are verified
|
|
150
|
+
4. New conventions, contracts, or migration impacts are documented in spec or task records
|
|
151
|
+
5. Failed verification is NOT worked around by shrinking assertions, deleting tests, or skipping critical paths
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Forbidden Patterns (Zero Tolerance)
|
|
156
|
+
|
|
157
|
+
You MUST NOT do any of the following:
|
|
158
|
+
|
|
159
|
+
- Claim completion without verification
|
|
160
|
+
- Use hardcoded values to bypass configuration, permissions, or contracts
|
|
161
|
+
- Use temporary compatibility logic instead of real fixes
|
|
162
|
+
- Change interfaces or data structures without updating docs and callers
|
|
163
|
+
- Catch exceptions and silently swallow errors or return success
|
|
164
|
+
- Use `any`, forced assertions, or empty object defaults to mask real type problems
|
|
165
|
+
- Leave components without loading/empty/error/disabled/permission states
|
|
166
|
+
- Rely on implicit side effects for interactions without explicit data flow and cleanup logic
|
|
167
|
+
- Elevate local state to global state, or duplicate server state as multiple local states
|
|
168
|
+
- Only verify ideal paths, not failures, empty data, or repeated operations
|
|
169
|
+
- Introduce features not required by the PRD
|
|
170
|
+
- Refactor unrelated modules "while you're at it"
|
|
171
|
+
- Make premature abstractions for one-off code
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Execution Order
|
|
176
|
+
|
|
177
|
+
1. Bind runtime context: `./.cowork-flow/run subagent bind <runtime_context_id> <host_context_key>`
|
|
178
|
+
2. Read task directory from bound runtime context
|
|
179
|
+
3. Read `<task>/prd.md`, `<task>/info.md`, `<task>/implement.jsonl`, and each JSONL `file` entry
|
|
180
|
+
4. Read pre-implementation checklist: `.cowork-flow/spec/guides/pre-implementation-checklist.md`
|
|
181
|
+
5. Read relevant spec directory (backend or frontend) and ALL linked documents
|
|
182
|
+
6. Apply coding gates — verify each gate before proceeding
|
|
183
|
+
7. Implement changes within assigned scope
|
|
184
|
+
8. Run verification commands (compile, lint, test, build, type-check)
|
|
185
|
+
9. Report changed files and exact verification commands
|
|
186
|
+
10. Do NOT run task start, task finish, task archive, unscoped resume, commit, or push
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
31
190
|
Rules:
|
|
32
191
|
|
|
33
192
|
- Read the task directory from the bound runtime context.
|
|
@@ -35,6 +194,6 @@ Rules:
|
|
|
35
194
|
and each JSONL `file` entry.
|
|
36
195
|
- Keep edits inside the assigned scope.
|
|
37
196
|
- Report changed files and exact verification commands.
|
|
38
|
-
- Do not use the
|
|
197
|
+
- Do not use the `task` tool or invoke subagents.
|
|
39
198
|
- Do not run task start, task finish, task archive, unscoped resume, commit, or
|
|
40
199
|
push.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: party-mode-v2
|
|
3
|
+
description: Use when the user requests a runtime-controlled multi-agent board discussion where children communicate through Party Mode V2 board APIs and the moderator only monitors or corrects drift.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Party Mode V2
|
|
7
|
+
|
|
8
|
+
Use this skill as a thin entrypoint for the Party Mode V2 runtime board. The Python runtime is the source of truth for discussion state, board visibility, validation, round limits, and final reports.
|
|
9
|
+
|
|
10
|
+
## Boundaries
|
|
11
|
+
|
|
12
|
+
- Party Mode V2 is advisory only.
|
|
13
|
+
- It cannot mutate task status, start/review/complete/archive tasks, add sessions, commit, push, or satisfy formal workflow gates.
|
|
14
|
+
- It cannot satisfy formal Implement or Check completion. Use `cowork-implement` and `cowork-check` for formal phases.
|
|
15
|
+
- Discussion children are leaf executors. They do not dispatch, wait for, list, or close other agents.
|
|
16
|
+
- The moderator does not forward, summarize, rewrite, or synthesize child opinions for other child agents.
|
|
17
|
+
|
|
18
|
+
## Runtime First
|
|
19
|
+
|
|
20
|
+
Always use the runtime controller:
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
.cowork-flow/run party-v2 init
|
|
24
|
+
.cowork-flow/run party-v2 monitor
|
|
25
|
+
.cowork-flow/run party-v2 view
|
|
26
|
+
.cowork-flow/run party-v2 post
|
|
27
|
+
.cowork-flow/run party-v2 respond
|
|
28
|
+
.cowork-flow/run party-v2 advance
|
|
29
|
+
.cowork-flow/run party-v2 finalize
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Do not bypass a runtime rejection by manually accepting child output. Runtime validation failures must be fixed by a corrected child submission or by ending the discussion.
|
|
33
|
+
|
|
34
|
+
## Board Rules
|
|
35
|
+
|
|
36
|
+
- Child agents communicate through the board API.
|
|
37
|
+
- Child-visible board output must be current-round only.
|
|
38
|
+
- Historical board state is runtime-private and may be used only for audit or final reports.
|
|
39
|
+
- Use at least three child agents unless the effective runtime config explicitly allows a different value.
|
|
40
|
+
- The runtime emits host-neutral next actions. The active Host Adapter or moderator executes them for Codex, Claude Code, or OpenCode.
|
|
41
|
+
|
|
42
|
+
## Child Response Rules
|
|
43
|
+
|
|
44
|
+
When a child sees a different position, it must choose exactly one:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
maintain
|
|
48
|
+
revise
|
|
49
|
+
concede
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`concede` requires accepted evidence and why the prior position failed.
|
|
53
|
+
`revise` requires the accepted part, rejected part, and updated position.
|
|
54
|
+
`maintain` requires counter evidence or counter reasoning.
|
|
55
|
+
|
|
56
|
+
Unsupported agreement, vague revision, and evidence-free rebuttal are invalid.
|
|
57
|
+
|
|
58
|
+
## Moderator Role
|
|
59
|
+
|
|
60
|
+
The moderator may:
|
|
61
|
+
|
|
62
|
+
- run runtime commands,
|
|
63
|
+
- execute host-neutral next actions through the active host,
|
|
64
|
+
- record off-topic warnings through the runtime,
|
|
65
|
+
- close children only when the runtime asks for closeout,
|
|
66
|
+
- show runtime status or final reports to the user.
|
|
67
|
+
|
|
68
|
+
The moderator must not:
|
|
69
|
+
|
|
70
|
+
- forward one child opinion to another child,
|
|
71
|
+
- create a claim table for child prompts,
|
|
72
|
+
- vote-count as validation,
|
|
73
|
+
- decide which child is correct.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.27
|
|
@@ -28,6 +28,22 @@ codex:
|
|
|
28
28
|
# .cowork-flow/.runtime/subagents/<id>.json with the subagent helper, then
|
|
29
29
|
# passes cowork_runtime_context_id through the active host adapter transport.
|
|
30
30
|
|
|
31
|
+
#-------------------------------------------------------------------------------
|
|
32
|
+
# Party Mode V2 Runtime Board
|
|
33
|
+
#-------------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
# Party Mode V2 is an advisory, runtime-controlled board discussion mode.
|
|
36
|
+
# The Python runtime owns board state and emits host-neutral next actions; the
|
|
37
|
+
# active host adapter still performs dispatch/wait/close.
|
|
38
|
+
party_mode_v2:
|
|
39
|
+
min_agents: 3
|
|
40
|
+
max_agents: 5
|
|
41
|
+
max_rounds: 5
|
|
42
|
+
max_rebuttal_targets_per_agent: 2
|
|
43
|
+
max_drift_warnings: 2
|
|
44
|
+
fresh_context_per_round: "true"
|
|
45
|
+
require_current_round_only: "true"
|
|
46
|
+
|
|
31
47
|
#-------------------------------------------------------------------------------
|
|
32
48
|
# Task Lifecycle Hooks
|
|
33
49
|
#-------------------------------------------------------------------------------
|
|
@@ -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:
|
|
@@ -16,6 +16,13 @@ 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_PARTY_MODE_V2_MIN_AGENTS = 3
|
|
20
|
+
DEFAULT_PARTY_MODE_V2_MAX_AGENTS = 5
|
|
21
|
+
DEFAULT_PARTY_MODE_V2_MAX_ROUNDS = 5
|
|
22
|
+
DEFAULT_PARTY_MODE_V2_MAX_REBUTTAL_TARGETS_PER_AGENT = 2
|
|
23
|
+
DEFAULT_PARTY_MODE_V2_MAX_DRIFT_WARNINGS = 2
|
|
24
|
+
DEFAULT_PARTY_MODE_V2_FRESH_CONTEXT_PER_ROUND = True
|
|
25
|
+
DEFAULT_PARTY_MODE_V2_REQUIRE_CURRENT_ROUND_ONLY = True
|
|
19
26
|
|
|
20
27
|
CONFIG_FILE = "config.yaml"
|
|
21
28
|
|
|
@@ -139,3 +146,89 @@ def get_codex_dispatch_mode(repo_root: Path | None = None) -> str:
|
|
|
139
146
|
if mode in {"sub-agent", "inline"}:
|
|
140
147
|
return str(mode)
|
|
141
148
|
return DEFAULT_CODEX_DISPATCH_MODE
|
|
149
|
+
|
|
150
|
+
def _get_section(config: dict, section_name: str) -> dict:
|
|
151
|
+
section = config.get(section_name)
|
|
152
|
+
if isinstance(section, dict):
|
|
153
|
+
return section
|
|
154
|
+
return {}
|
|
155
|
+
|
|
156
|
+
def _get_int(section: dict, key: str, default: int, *, minimum: int | None = None) -> int:
|
|
157
|
+
value = section.get(key, default)
|
|
158
|
+
try:
|
|
159
|
+
parsed = int(value)
|
|
160
|
+
except (TypeError, ValueError):
|
|
161
|
+
return default
|
|
162
|
+
if minimum is not None and parsed < minimum:
|
|
163
|
+
return default
|
|
164
|
+
return parsed
|
|
165
|
+
|
|
166
|
+
def _get_bool(section: dict, key: str, default: bool) -> bool:
|
|
167
|
+
value = section.get(key, default)
|
|
168
|
+
if isinstance(value, bool):
|
|
169
|
+
return value
|
|
170
|
+
if isinstance(value, str):
|
|
171
|
+
normalized = value.strip().lower()
|
|
172
|
+
if normalized in {"true", "1", "yes", "on"}:
|
|
173
|
+
return True
|
|
174
|
+
if normalized in {"false", "0", "no", "off"}:
|
|
175
|
+
return False
|
|
176
|
+
return default
|
|
177
|
+
|
|
178
|
+
def get_party_mode_v2_config(repo_root: Path | None = None) -> dict[str, int | bool]:
|
|
179
|
+
"""Get Party Mode V2 runtime-board defaults."""
|
|
180
|
+
config = _load_config(repo_root)
|
|
181
|
+
section = _get_section(config, "party_mode_v2")
|
|
182
|
+
min_agents = _get_int(
|
|
183
|
+
section,
|
|
184
|
+
"min_agents",
|
|
185
|
+
DEFAULT_PARTY_MODE_V2_MIN_AGENTS,
|
|
186
|
+
minimum=3,
|
|
187
|
+
)
|
|
188
|
+
max_agents = _get_int(
|
|
189
|
+
section,
|
|
190
|
+
"max_agents",
|
|
191
|
+
DEFAULT_PARTY_MODE_V2_MAX_AGENTS,
|
|
192
|
+
minimum=min_agents,
|
|
193
|
+
)
|
|
194
|
+
return {
|
|
195
|
+
"min_agents": min_agents,
|
|
196
|
+
"max_agents": max_agents,
|
|
197
|
+
"max_rounds": _get_int(
|
|
198
|
+
section,
|
|
199
|
+
"max_rounds",
|
|
200
|
+
DEFAULT_PARTY_MODE_V2_MAX_ROUNDS,
|
|
201
|
+
minimum=1,
|
|
202
|
+
),
|
|
203
|
+
"max_rebuttal_targets_per_agent": _get_int(
|
|
204
|
+
section,
|
|
205
|
+
"max_rebuttal_targets_per_agent",
|
|
206
|
+
DEFAULT_PARTY_MODE_V2_MAX_REBUTTAL_TARGETS_PER_AGENT,
|
|
207
|
+
minimum=1,
|
|
208
|
+
),
|
|
209
|
+
"max_drift_warnings": _get_int(
|
|
210
|
+
section,
|
|
211
|
+
"max_drift_warnings",
|
|
212
|
+
DEFAULT_PARTY_MODE_V2_MAX_DRIFT_WARNINGS,
|
|
213
|
+
minimum=0,
|
|
214
|
+
),
|
|
215
|
+
"fresh_context_per_round": _get_bool(
|
|
216
|
+
section,
|
|
217
|
+
"fresh_context_per_round",
|
|
218
|
+
DEFAULT_PARTY_MODE_V2_FRESH_CONTEXT_PER_ROUND,
|
|
219
|
+
),
|
|
220
|
+
"require_current_round_only": _get_bool(
|
|
221
|
+
section,
|
|
222
|
+
"require_current_round_only",
|
|
223
|
+
DEFAULT_PARTY_MODE_V2_REQUIRE_CURRENT_ROUND_ONLY,
|
|
224
|
+
),
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
def get_party_mode_v2_min_agents(repo_root: Path | None = None) -> int:
|
|
228
|
+
return int(get_party_mode_v2_config(repo_root)["min_agents"])
|
|
229
|
+
|
|
230
|
+
def get_party_mode_v2_max_agents(repo_root: Path | None = None) -> int:
|
|
231
|
+
return int(get_party_mode_v2_config(repo_root)["max_agents"])
|
|
232
|
+
|
|
233
|
+
def get_party_mode_v2_max_rounds(repo_root: Path | None = None) -> int:
|
|
234
|
+
return int(get_party_mode_v2_config(repo_root)["max_rounds"])
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Error handling utilities for cowork-flow.
|
|
4
|
+
|
|
5
|
+
Provides centralized error types and formatted output.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CoworkFlowError(Exception):
|
|
15
|
+
"""Base error for cowork-flow."""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
message: str,
|
|
20
|
+
suggestion: str | None = None,
|
|
21
|
+
exit_code: int = 1,
|
|
22
|
+
context: dict[str, Any] | None = None,
|
|
23
|
+
):
|
|
24
|
+
super().__init__(message)
|
|
25
|
+
self.suggestion = suggestion
|
|
26
|
+
self.exit_code = exit_code
|
|
27
|
+
self.context = context or {}
|
|
28
|
+
|
|
29
|
+
def to_dict(self) -> dict[str, Any]:
|
|
30
|
+
"""Convert error to dictionary format."""
|
|
31
|
+
result = {
|
|
32
|
+
"error_code": self.__class__.__name__,
|
|
33
|
+
"message": str(self),
|
|
34
|
+
"suggestion": self.suggestion,
|
|
35
|
+
"context": self.context,
|
|
36
|
+
}
|
|
37
|
+
return result
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TaskError(CoworkFlowError):
|
|
41
|
+
"""Task-related errors."""
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ConfigError(CoworkFlowError):
|
|
46
|
+
"""Configuration errors."""
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ValidationError(CoworkFlowError):
|
|
51
|
+
"""Validation errors."""
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class AdapterError(CoworkFlowError):
|
|
56
|
+
"""Adapter-related errors."""
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def print_error(error: CoworkFlowError, file=None) -> None:
|
|
61
|
+
"""
|
|
62
|
+
Print formatted error with suggestion.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
error: The error to print
|
|
66
|
+
file: Output file (defaults to stderr)
|
|
67
|
+
"""
|
|
68
|
+
output = file or sys.stderr
|
|
69
|
+
|
|
70
|
+
print(f"Error: {error}", file=output)
|
|
71
|
+
if error.suggestion:
|
|
72
|
+
print(f"Suggestion: {error.suggestion}", file=output)
|
|
73
|
+
|
|
74
|
+
if error.context:
|
|
75
|
+
print("Context:", file=output)
|
|
76
|
+
for key, value in error.context.items():
|
|
77
|
+
print(f" {key}: {value}", file=output)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def format_error_message(
|
|
81
|
+
error_code: str,
|
|
82
|
+
message: str,
|
|
83
|
+
suggestion: str | None = None,
|
|
84
|
+
context: dict[str, Any] | None = None,
|
|
85
|
+
) -> str:
|
|
86
|
+
"""
|
|
87
|
+
Format error message as JSON string.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
error_code: Error code identifier
|
|
91
|
+
message: Error message
|
|
92
|
+
suggestion: Recovery suggestion
|
|
93
|
+
context: Additional context
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
JSON string of formatted error
|
|
97
|
+
"""
|
|
98
|
+
import json
|
|
99
|
+
|
|
100
|
+
error_dict = {
|
|
101
|
+
"error_code": error_code,
|
|
102
|
+
"message": message,
|
|
103
|
+
"suggestion": suggestion,
|
|
104
|
+
"context": context or {},
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return json.dumps(error_dict, ensure_ascii=False)
|