acpx-team 0.2.0
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 +119 -0
- package/acpx/SKILL.md +546 -0
- package/acpx/bin/acpx-council +374 -0
- package/acpx/config/agent-profiles.yaml +245 -0
- package/acpx/config/role-templates/_README.md +41 -0
- package/acpx/lib/protocols.sh +521 -0
- package/acpx/lib/roles.sh +339 -0
- package/acpx/lib/synthesize.sh +187 -0
- package/acpx/lib/workspace.sh +274 -0
- package/acpx/references/protocols.md +273 -0
- package/acpx/references/roles.md +286 -0
- package/acpx-council.js +10 -0
- package/package.json +47 -0
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# protocols.sh — Protocol implementations with Plan-First flow
|
|
3
|
+
# Each protocol: Phase 1 (Plan) → consensus check → Phase 2 (Execute)
|
|
4
|
+
# Compatible with Bash 3.2+ (no mapfile, no associative arrays)
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
ACPX_ROOT="${ACPX_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
|
9
|
+
ACPX_WORKSPACE="${ACPX_WORKSPACE:-.acpx-workspace}"
|
|
10
|
+
|
|
11
|
+
source "${ACPX_ROOT}/lib/workspace.sh"
|
|
12
|
+
source "${ACPX_ROOT}/lib/roles.sh"
|
|
13
|
+
source "${ACPX_ROOT}/lib/synthesize.sh"
|
|
14
|
+
|
|
15
|
+
# ─── Portable Helpers ──────────────────────────────────────────
|
|
16
|
+
# read_into_array VARNAME < input (replaces mapfile for Bash 3.2)
|
|
17
|
+
|
|
18
|
+
read_into_array() {
|
|
19
|
+
local _varname="$1"
|
|
20
|
+
eval "${_varname}=()"
|
|
21
|
+
while IFS= read -r _line; do
|
|
22
|
+
[[ -n "$_line" ]] && eval "${_varname}+=(\"\$_line\")"
|
|
23
|
+
done
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
# ─── Agent Detection ───────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
_detect_available_agents() {
|
|
29
|
+
local found=""
|
|
30
|
+
for cmd in claude codex gemini opencode cursor copilot pi qwen openclaw; do
|
|
31
|
+
if command -v "acpx-${cmd}" &>/dev/null 2>&1 || acpx "${cmd}" exec "echo ok" &>/dev/null 2>&1; then
|
|
32
|
+
found="${found}${cmd}"$'\n'
|
|
33
|
+
fi
|
|
34
|
+
done
|
|
35
|
+
printf '%s' "$found"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
_get_agents_or_default() {
|
|
39
|
+
local agents_spec="${1:-auto}"
|
|
40
|
+
if [[ "$agents_spec" == "auto" ]]; then
|
|
41
|
+
local detected
|
|
42
|
+
detected=$(_detect_available_agents)
|
|
43
|
+
if [[ -z "$detected" ]]; then
|
|
44
|
+
echo "claude"
|
|
45
|
+
else
|
|
46
|
+
printf '%s' "$detected"
|
|
47
|
+
fi
|
|
48
|
+
else
|
|
49
|
+
echo "$agents_spec" | tr ',' '\n'
|
|
50
|
+
fi
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_run_agent_plan() {
|
|
54
|
+
local agent="$1"
|
|
55
|
+
local session="$2"
|
|
56
|
+
local prompt="$3"
|
|
57
|
+
|
|
58
|
+
acpx "$agent" -s "$session" set-mode plan 2>/dev/null || true
|
|
59
|
+
acpx --format quiet "$agent" -s "$session" "$prompt"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
_run_agent_execute() {
|
|
63
|
+
local agent="$1"
|
|
64
|
+
local session="$2"
|
|
65
|
+
local prompt="$3"
|
|
66
|
+
local mode="${4:-acceptEdits}"
|
|
67
|
+
|
|
68
|
+
acpx "$agent" -s "$session" set-mode "$mode" 2>/dev/null || true
|
|
69
|
+
acpx --format quiet "$agent" -s "$session" "$prompt"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# ─── Protocol 1: Parallel Fan-Out ──────────────────────────────
|
|
73
|
+
|
|
74
|
+
protocol_fanout() {
|
|
75
|
+
local task="${1:?Usage: protocol_fanout <task> [agents] [orchestrator]}"
|
|
76
|
+
local agents_spec="${2:-auto}"
|
|
77
|
+
local orchestrator="${3:-claude}"
|
|
78
|
+
|
|
79
|
+
local -a agents=()
|
|
80
|
+
while IFS= read -r line; do
|
|
81
|
+
[[ -n "$line" ]] && agents+=("$line")
|
|
82
|
+
done < <(_get_agents_or_default "$agents_spec")
|
|
83
|
+
|
|
84
|
+
workspace_init "$task" "fanout"
|
|
85
|
+
|
|
86
|
+
# ── Phase 1: Plan (parallel fan-out) ──
|
|
87
|
+
workspace_set_phase "plan"
|
|
88
|
+
workspace_set_round 1
|
|
89
|
+
|
|
90
|
+
echo "==> Protocol 1: Fan-Out | ${#agents[@]} agent(s) | Plan phase"
|
|
91
|
+
|
|
92
|
+
local pids=()
|
|
93
|
+
for agent in "${agents[@]}"; do
|
|
94
|
+
local session="fanout-${agent}"
|
|
95
|
+
acpx "${agent}" sessions new --name "$session" 2>/dev/null || true
|
|
96
|
+
|
|
97
|
+
_run_agent_plan "$agent" "$session" "$task" \
|
|
98
|
+
| workspace_write_agent_output "$agent" 1 &
|
|
99
|
+
pids+=($!)
|
|
100
|
+
done
|
|
101
|
+
|
|
102
|
+
for pid in "${pids[@]}"; do
|
|
103
|
+
wait "$pid" 2>/dev/null || true
|
|
104
|
+
done
|
|
105
|
+
|
|
106
|
+
# ── Synthesize ──
|
|
107
|
+
echo "==> Synthesizing..."
|
|
108
|
+
synthesize_round 1 "$orchestrator"
|
|
109
|
+
|
|
110
|
+
workspace_set_phase "done"
|
|
111
|
+
echo "==> Fan-Out complete. See $ACPX_WORKSPACE/synthesis.md"
|
|
112
|
+
|
|
113
|
+
for agent in "${agents[@]}"; do
|
|
114
|
+
acpx "${agent}" sessions close "fanout-${agent}" 2>/dev/null || true
|
|
115
|
+
done
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# ─── Protocol 2: Round-Robin Deliberation ──────────────────────
|
|
119
|
+
|
|
120
|
+
protocol_deliberation() {
|
|
121
|
+
local task="${1:?Usage: protocol_deliberation <task> [agents] [orchestrator]}"
|
|
122
|
+
local agents_spec="${2:-auto}"
|
|
123
|
+
local orchestrator="${3:-claude}"
|
|
124
|
+
|
|
125
|
+
local -a agents=()
|
|
126
|
+
while IFS= read -r line; do
|
|
127
|
+
[[ -n "$line" ]] && agents+=("$line")
|
|
128
|
+
done < <(_get_agents_or_default "$agents_spec")
|
|
129
|
+
|
|
130
|
+
workspace_init "$task" "deliberation"
|
|
131
|
+
|
|
132
|
+
# ── Phase 1: Plan - Round 1 ──
|
|
133
|
+
workspace_set_phase "plan"
|
|
134
|
+
workspace_set_round 1
|
|
135
|
+
|
|
136
|
+
echo "==> Protocol 2: Deliberation | ${#agents[@]} agent(s) | Round 1 (Plan)"
|
|
137
|
+
|
|
138
|
+
local pids=()
|
|
139
|
+
for agent in "${agents[@]}"; do
|
|
140
|
+
local session="delib-${agent}"
|
|
141
|
+
acpx "${agent}" sessions new --name "$session" 2>/dev/null || true
|
|
142
|
+
|
|
143
|
+
_run_agent_plan "$agent" "$session" "$task" \
|
|
144
|
+
| workspace_write_agent_output "$agent" 1 &
|
|
145
|
+
pids+=($!)
|
|
146
|
+
done
|
|
147
|
+
for pid in "${pids[@]}"; do wait "$pid" 2>/dev/null || true; done
|
|
148
|
+
|
|
149
|
+
# ── Consensus check ──
|
|
150
|
+
local consensus
|
|
151
|
+
consensus=$(consensus_check 1 "$orchestrator")
|
|
152
|
+
echo "==> Round 1 consensus: ${consensus}"
|
|
153
|
+
|
|
154
|
+
if [[ "$consensus" == "HIGH" ]]; then
|
|
155
|
+
echo "==> High consensus after Round 1 — skipping Round 2"
|
|
156
|
+
synthesize_round 1 "$orchestrator"
|
|
157
|
+
synthesize_plan "$orchestrator"
|
|
158
|
+
workspace_set_phase "done"
|
|
159
|
+
echo "==> Deliberation complete. See $ACPX_WORKSPACE/synthesis.md"
|
|
160
|
+
return
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
# ── Round 2: Deliberation ──
|
|
164
|
+
workspace_set_round 2
|
|
165
|
+
echo "==> Round 2 (Deliberation)"
|
|
166
|
+
|
|
167
|
+
local all_r1
|
|
168
|
+
all_r1=$(workspace_gather_round 1)
|
|
169
|
+
|
|
170
|
+
pids=()
|
|
171
|
+
for agent in "${agents[@]}"; do
|
|
172
|
+
local session="delib-${agent}"
|
|
173
|
+
local r2_prompt="[Round 2: Deliberation]
|
|
174
|
+
Other reviewers provided their analysis below. Consider their points fairly.
|
|
175
|
+
Update your analysis where you find their arguments convincing. Note any remaining disagreements.
|
|
176
|
+
|
|
177
|
+
${all_r1}"
|
|
178
|
+
|
|
179
|
+
_run_agent_plan "$agent" "$session" "$r2_prompt" \
|
|
180
|
+
| workspace_write_agent_output "$agent" 2 &
|
|
181
|
+
pids+=($!)
|
|
182
|
+
done
|
|
183
|
+
for pid in "${pids[@]}"; do wait "$pid" 2>/dev/null || true; done
|
|
184
|
+
|
|
185
|
+
# ── Synthesize ──
|
|
186
|
+
echo "==> Synthesizing..."
|
|
187
|
+
synthesize_round 2 "$orchestrator"
|
|
188
|
+
synthesize_plan "$orchestrator"
|
|
189
|
+
|
|
190
|
+
workspace_set_phase "execute"
|
|
191
|
+
echo "==> Plan phase complete. Ready to execute."
|
|
192
|
+
echo "==> Run: acpx-council execute --from-workspace"
|
|
193
|
+
|
|
194
|
+
for agent in "${agents[@]}"; do
|
|
195
|
+
acpx "${agent}" sessions close "delib-${agent}" 2>/dev/null || true
|
|
196
|
+
done
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# ─── Protocol 3: Role-Specialized Council (Recommended) ────────
|
|
200
|
+
|
|
201
|
+
protocol_role_council() {
|
|
202
|
+
local task="${1:?Usage: protocol_role_council <task> [agents] [roles] [orchestrator]}"
|
|
203
|
+
local agents_spec="${2:-auto}"
|
|
204
|
+
local roles_spec="${3:-auto}"
|
|
205
|
+
local orchestrator="${4:-claude}"
|
|
206
|
+
|
|
207
|
+
local -a agents=()
|
|
208
|
+
while IFS= read -r line; do
|
|
209
|
+
[[ -n "$line" ]] && agents+=("$line")
|
|
210
|
+
done < <(_get_agents_or_default "$agents_spec")
|
|
211
|
+
|
|
212
|
+
# Infer roles if auto
|
|
213
|
+
local -a roles=()
|
|
214
|
+
if [[ "$roles_spec" == "auto" ]]; then
|
|
215
|
+
while IFS= read -r line; do
|
|
216
|
+
[[ -n "$line" ]] && roles+=("$line")
|
|
217
|
+
done < <(role_infer_from_task "$task")
|
|
218
|
+
# Ensure at least as many roles as agents
|
|
219
|
+
while [[ ${#roles[@]} -lt ${#agents[@]} ]]; do
|
|
220
|
+
roles+=("neutral")
|
|
221
|
+
done
|
|
222
|
+
else
|
|
223
|
+
while IFS= read -r line; do
|
|
224
|
+
[[ -n "$line" ]] && roles+=("$line")
|
|
225
|
+
done < <(echo "$roles_spec" | tr ',' '\n')
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
workspace_init "$task" "role-council"
|
|
229
|
+
|
|
230
|
+
# ── Phase 1: Plan - Round 1 with roles ──
|
|
231
|
+
workspace_set_phase "plan"
|
|
232
|
+
workspace_set_round 1
|
|
233
|
+
|
|
234
|
+
echo "==> Protocol 3: Role Council | ${#agents[@]} agent(s)"
|
|
235
|
+
echo " Agents: ${agents[*]}"
|
|
236
|
+
echo " Roles: ${roles[*]}"
|
|
237
|
+
|
|
238
|
+
local pids=()
|
|
239
|
+
local i=0
|
|
240
|
+
for agent in "${agents[@]}"; do
|
|
241
|
+
local role="${roles[$i]:-neutral}"
|
|
242
|
+
local session="council-${agent}"
|
|
243
|
+
|
|
244
|
+
acpx "${agent}" sessions new --name "$session" 2>/dev/null || true
|
|
245
|
+
|
|
246
|
+
local r1_prompt
|
|
247
|
+
r1_prompt="$(role_get_r1 "$role")
|
|
248
|
+
|
|
249
|
+
${task}"
|
|
250
|
+
|
|
251
|
+
_run_agent_plan "$agent" "$session" "$r1_prompt" \
|
|
252
|
+
| workspace_write_agent_output "$agent" 1 &
|
|
253
|
+
pids+=($!)
|
|
254
|
+
i=$((i + 1))
|
|
255
|
+
done
|
|
256
|
+
for pid in "${pids[@]}"; do wait "$pid" 2>/dev/null || true; done
|
|
257
|
+
|
|
258
|
+
# ── Consensus check ──
|
|
259
|
+
local consensus
|
|
260
|
+
consensus=$(consensus_check 1 "$orchestrator")
|
|
261
|
+
echo "==> Round 1 consensus: ${consensus}"
|
|
262
|
+
|
|
263
|
+
if [[ "$consensus" == "HIGH" ]]; then
|
|
264
|
+
echo "==> High consensus — synthesizing plan"
|
|
265
|
+
synthesize_round 1 "$orchestrator"
|
|
266
|
+
synthesize_plan "$orchestrator"
|
|
267
|
+
workspace_set_phase "execute"
|
|
268
|
+
echo "==> Plan ready. See $ACPX_WORKSPACE/plan.md"
|
|
269
|
+
return
|
|
270
|
+
fi
|
|
271
|
+
|
|
272
|
+
# ── Round 2: Role-persistent deliberation ──
|
|
273
|
+
workspace_set_round 2
|
|
274
|
+
echo "==> Round 2 (Role Deliberation)"
|
|
275
|
+
|
|
276
|
+
local all_r1
|
|
277
|
+
all_r1=$(workspace_gather_round 1)
|
|
278
|
+
|
|
279
|
+
pids=()
|
|
280
|
+
i=0
|
|
281
|
+
for agent in "${agents[@]}"; do
|
|
282
|
+
local role="${roles[$i]:-neutral}"
|
|
283
|
+
local session="council-${agent}"
|
|
284
|
+
|
|
285
|
+
local r2_prompt
|
|
286
|
+
r2_prompt="$(role_get_r2 "$role")
|
|
287
|
+
|
|
288
|
+
Other experts' analysis:
|
|
289
|
+
${all_r1}"
|
|
290
|
+
|
|
291
|
+
_run_agent_plan "$agent" "$session" "$r2_prompt" \
|
|
292
|
+
| workspace_write_agent_output "$agent" 2 &
|
|
293
|
+
pids+=($!)
|
|
294
|
+
i=$((i + 1))
|
|
295
|
+
done
|
|
296
|
+
for pid in "${pids[@]}"; do wait "$pid" 2>/dev/null || true; done
|
|
297
|
+
|
|
298
|
+
# ── Synthesize ──
|
|
299
|
+
echo "==> Synthesizing..."
|
|
300
|
+
synthesize_round 2 "$orchestrator"
|
|
301
|
+
synthesize_plan "$orchestrator"
|
|
302
|
+
|
|
303
|
+
workspace_set_phase "execute"
|
|
304
|
+
echo "==> Plan ready. See $ACPX_WORKSPACE/plan.md"
|
|
305
|
+
|
|
306
|
+
for agent in "${agents[@]}"; do
|
|
307
|
+
acpx "${agent}" sessions close "council-${agent}" 2>/dev/null || true
|
|
308
|
+
done
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
# ─── Protocol 4: Adversarial Debate ────────────────────────────
|
|
312
|
+
|
|
313
|
+
protocol_adversarial() {
|
|
314
|
+
local task="${1:?Usage: protocol_adversarial <task> [agents] [orchestrator]}"
|
|
315
|
+
local agents_spec="${2:-claude,codex}"
|
|
316
|
+
local orchestrator="${3:-gemini}"
|
|
317
|
+
|
|
318
|
+
local -a agents=()
|
|
319
|
+
while IFS= read -r line; do
|
|
320
|
+
[[ -n "$line" ]] && agents+=("$line")
|
|
321
|
+
done < <(_get_agents_or_default "$agents_spec")
|
|
322
|
+
|
|
323
|
+
local advocate="${agents[0]:-claude}"
|
|
324
|
+
local critic="${agents[1]:-codex}"
|
|
325
|
+
local judge="${agents[2]:-$orchestrator}"
|
|
326
|
+
|
|
327
|
+
workspace_init "$task" "adversarial"
|
|
328
|
+
workspace_set_phase "plan"
|
|
329
|
+
workspace_set_round 1
|
|
330
|
+
|
|
331
|
+
echo "==> Protocol 4: Adversarial Debate"
|
|
332
|
+
echo " Advocate: ${advocate} | Critic: ${critic} | Judge: ${judge}"
|
|
333
|
+
|
|
334
|
+
acpx "$advocate" sessions new --name "bull" 2>/dev/null || true
|
|
335
|
+
acpx "$critic" sessions new --name "bear" 2>/dev/null || true
|
|
336
|
+
acpx "$judge" sessions new --name "judge" 2>/dev/null || true
|
|
337
|
+
|
|
338
|
+
# Round 1: Opening arguments
|
|
339
|
+
echo "==> Opening arguments..."
|
|
340
|
+
|
|
341
|
+
_run_agent_plan "$advocate" "bull" "Argue FOR the following proposal. Provide specific technical benefits and evidence.
|
|
342
|
+
${task}" | workspace_write_agent_output "advocate" 1 &
|
|
343
|
+
local pid1=$!
|
|
344
|
+
|
|
345
|
+
_run_agent_plan "$critic" "bear" "Argue AGAINST the following proposal. Provide specific technical risks and counter-evidence.
|
|
346
|
+
${task}" | workspace_write_agent_output "critic" 1 &
|
|
347
|
+
local pid2=$!
|
|
348
|
+
|
|
349
|
+
wait "$pid1" 2>/dev/null || true
|
|
350
|
+
wait "$pid2" 2>/dev/null || true
|
|
351
|
+
|
|
352
|
+
# Round 2: Cross-arguments
|
|
353
|
+
workspace_set_round 2
|
|
354
|
+
echo "==> Cross-arguments..."
|
|
355
|
+
|
|
356
|
+
local bull_r1 critic_r1
|
|
357
|
+
bull_r1=$(workspace_read_agent_output "advocate" 1)
|
|
358
|
+
critic_r1=$(workspace_read_agent_output "critic" 1)
|
|
359
|
+
|
|
360
|
+
_run_agent_plan "$advocate" "bull" "The critic argues:
|
|
361
|
+
${critic_r1}
|
|
362
|
+
|
|
363
|
+
Counter-argue. Address each concern specifically." | workspace_write_agent_output "advocate" 2 &
|
|
364
|
+
pid1=$!
|
|
365
|
+
|
|
366
|
+
_run_agent_plan "$critic" "bear" "The advocate argues:
|
|
367
|
+
${bull_r1}
|
|
368
|
+
|
|
369
|
+
Counter-argue. Address each claim specifically." | workspace_write_agent_output "critic" 2 &
|
|
370
|
+
pid2=$!
|
|
371
|
+
|
|
372
|
+
wait "$pid1" 2>/dev/null || true
|
|
373
|
+
wait "$pid2" 2>/dev/null || true
|
|
374
|
+
|
|
375
|
+
# Judge synthesis
|
|
376
|
+
echo "==> Judge synthesizing..."
|
|
377
|
+
|
|
378
|
+
local bull_r2 critic_r2
|
|
379
|
+
bull_r2=$(workspace_read_agent_output "advocate" 2)
|
|
380
|
+
critic_r2=$(workspace_read_agent_output "critic" 2)
|
|
381
|
+
|
|
382
|
+
acpx --format quiet "$judge" -s judge "You are the judge. Synthesize this debate into a final recommendation.
|
|
383
|
+
|
|
384
|
+
[FOR]:
|
|
385
|
+
${bull_r2}
|
|
386
|
+
|
|
387
|
+
[AGAINST]:
|
|
388
|
+
${critic_r2}
|
|
389
|
+
|
|
390
|
+
Provide:
|
|
391
|
+
1. Summary of key arguments on each side
|
|
392
|
+
2. Points of agreement
|
|
393
|
+
3. Unresolved tensions
|
|
394
|
+
4. Your final recommendation with confidence level (HIGH/MEDIUM/LOW)" \
|
|
395
|
+
| workspace_write_agent_output "judge" 1
|
|
396
|
+
|
|
397
|
+
cp "$ACPX_WORKSPACE/agents/judge/round-1.md" "$ACPX_WORKSPACE/synthesis.md"
|
|
398
|
+
|
|
399
|
+
synthesize_plan "$orchestrator"
|
|
400
|
+
workspace_set_phase "execute"
|
|
401
|
+
echo "==> Debate complete. See $ACPX_WORKSPACE/synthesis.md"
|
|
402
|
+
|
|
403
|
+
acpx "$advocate" sessions close "bull" 2>/dev/null || true
|
|
404
|
+
acpx "$critic" sessions close "bear" 2>/dev/null || true
|
|
405
|
+
acpx "$judge" sessions close "judge" 2>/dev/null || true
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
# ─── Protocol 5: Sequential Pipeline ───────────────────────────
|
|
409
|
+
|
|
410
|
+
protocol_pipeline() {
|
|
411
|
+
local task="${1:?Usage: protocol_pipeline <task> [agents] [orchestrator]}"
|
|
412
|
+
local agents_spec="${2:-claude,codex,claude}"
|
|
413
|
+
local orchestrator="${3:-claude}"
|
|
414
|
+
|
|
415
|
+
local -a agents=()
|
|
416
|
+
while IFS= read -r line; do
|
|
417
|
+
[[ -n "$line" ]] && agents+=("$line")
|
|
418
|
+
done < <(_get_agents_or_default "$agents_spec")
|
|
419
|
+
|
|
420
|
+
local writer="${agents[0]:-claude}"
|
|
421
|
+
local reviewer="${agents[1]:-codex}"
|
|
422
|
+
local editor="${agents[2]:-$writer}"
|
|
423
|
+
|
|
424
|
+
workspace_init "$task" "pipeline"
|
|
425
|
+
workspace_set_phase "plan"
|
|
426
|
+
|
|
427
|
+
echo "==> Protocol 5: Pipeline"
|
|
428
|
+
echo " Writer: ${writer} → Reviewer: ${reviewer} → Editor: ${editor}"
|
|
429
|
+
|
|
430
|
+
# Step 1: Plan (writer)
|
|
431
|
+
echo "==> [Plan] Writer analyzing..."
|
|
432
|
+
acpx "$writer" sessions new --name "pipe-writer" 2>/dev/null || true
|
|
433
|
+
_run_agent_plan "$writer" "pipe-writer" "$task" \
|
|
434
|
+
| workspace_write_agent_output "writer" 1
|
|
435
|
+
|
|
436
|
+
# Step 2: Review
|
|
437
|
+
echo "==> [Plan] Reviewer checking..."
|
|
438
|
+
acpx "$reviewer" sessions new --name "pipe-reviewer" 2>/dev/null || true
|
|
439
|
+
local writer_output
|
|
440
|
+
writer_output=$(workspace_read_agent_output "writer" 1)
|
|
441
|
+
|
|
442
|
+
_run_agent_plan "$reviewer" "pipe-reviewer" "Review this analysis for gaps, errors, and edge cases:
|
|
443
|
+
${writer_output}
|
|
444
|
+
|
|
445
|
+
Rate each finding: CRITICAL/HIGH/MEDIUM/LOW." | workspace_write_agent_output "reviewer" 1
|
|
446
|
+
|
|
447
|
+
# Step 3: Edit
|
|
448
|
+
echo "==> [Plan] Editor revising..."
|
|
449
|
+
local review_output
|
|
450
|
+
review_output=$(workspace_read_agent_output "reviewer" 1)
|
|
451
|
+
|
|
452
|
+
_run_agent_plan "$writer" "pipe-writer" "Incorporate this review feedback into your original analysis:
|
|
453
|
+
${review_output}
|
|
454
|
+
|
|
455
|
+
Original output:
|
|
456
|
+
${writer_output}" | workspace_write_agent_output "editor" 1
|
|
457
|
+
|
|
458
|
+
synthesize_round 1 "$orchestrator"
|
|
459
|
+
synthesize_plan "$orchestrator"
|
|
460
|
+
|
|
461
|
+
workspace_set_phase "execute"
|
|
462
|
+
echo "==> Pipeline complete. See $ACPX_WORKSPACE/synthesis.md"
|
|
463
|
+
|
|
464
|
+
acpx "$writer" sessions close "pipe-writer" 2>/dev/null || true
|
|
465
|
+
acpx "$reviewer" sessions close "pipe-reviewer" 2>/dev/null || true
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
# ─── Protocol Auto-Select ──────────────────────────────────────
|
|
469
|
+
|
|
470
|
+
protocol_auto_select() {
|
|
471
|
+
local task="${1:?Usage: protocol_auto_select <task>}"
|
|
472
|
+
local task_lower
|
|
473
|
+
task_lower=$(echo "$task" | tr '[:upper:]' '[:lower:]')
|
|
474
|
+
|
|
475
|
+
case "$task_lower" in
|
|
476
|
+
*review*|*audit*|*assess*) echo "role-council" ;;
|
|
477
|
+
*should*|*decide*|*choose*|*whether*) echo "adversarial" ;;
|
|
478
|
+
*implement*|*build*|*create*|*add*) echo "role-council" ;;
|
|
479
|
+
*quick*|*opinion*|*think*) echo "fanout" ;;
|
|
480
|
+
*design*|*architect*|*plan*) echo "role-council" ;;
|
|
481
|
+
*debug*|*fix*|*investigate*) echo "pipeline" ;;
|
|
482
|
+
*) echo "role-council" ;;
|
|
483
|
+
esac
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
# ─── Execute Phase ─────────────────────────────────────────────
|
|
487
|
+
|
|
488
|
+
protocol_execute() {
|
|
489
|
+
local plan_file="${1:-$ACPX_WORKSPACE/plan.md}"
|
|
490
|
+
local agents_spec="${2:-auto}"
|
|
491
|
+
local orchestrator="${3:-claude}"
|
|
492
|
+
|
|
493
|
+
if [[ ! -f "$plan_file" ]]; then
|
|
494
|
+
echo "Error: No plan found at $plan_file. Run plan phase first." >&2
|
|
495
|
+
return 1
|
|
496
|
+
fi
|
|
497
|
+
|
|
498
|
+
local plan
|
|
499
|
+
plan=$(cat "$plan_file")
|
|
500
|
+
|
|
501
|
+
local -a agents=()
|
|
502
|
+
while IFS= read -r line; do
|
|
503
|
+
[[ -n "$line" ]] && agents+=("$line")
|
|
504
|
+
done < <(_get_agents_or_default "$agents_spec")
|
|
505
|
+
|
|
506
|
+
workspace_set_phase "execute"
|
|
507
|
+
echo "==> Executing plan with ${#agents[@]} agent(s)"
|
|
508
|
+
|
|
509
|
+
local primary="${agents[0]}"
|
|
510
|
+
local session="exec-${primary}"
|
|
511
|
+
|
|
512
|
+
acpx "$primary" sessions new --name "$session" 2>/dev/null || true
|
|
513
|
+
|
|
514
|
+
_run_agent_execute "$primary" "$session" "Execute this plan. Follow each step in order:
|
|
515
|
+
${plan}" "acceptEdits" | workspace_write_agent_output "executor" 1
|
|
516
|
+
|
|
517
|
+
echo "==> Execution complete. See $ACPX_WORKSPACE/agents/executor/round-1.md"
|
|
518
|
+
|
|
519
|
+
acpx "$primary" sessions close "$session" 2>/dev/null || true
|
|
520
|
+
workspace_set_phase "review"
|
|
521
|
+
}
|