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.
@@ -0,0 +1,339 @@
1
+ #!/usr/bin/env bash
2
+ # roles.sh — Dynamic role management for acpx council
3
+ # Supports builtin, community, and custom roles with auto-inference from task descriptions
4
+ # Compatible with Bash 3.2+ (no associative arrays)
5
+
6
+ set -euo pipefail
7
+
8
+ ACPX_ROOT="${ACPX_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
9
+ ROLE_TEMPLATES_DIR="${ACPX_ROOT}/config/role-templates"
10
+ CUSTOM_ROLES_DIR="${ACPX_CUSTOM_ROLES:-$HOME/.acpx/roles}"
11
+
12
+ # ─── Builtin Role Definitions ──────────────────────────────────
13
+ # Using functions instead of associative arrays for Bash 3.2 compat
14
+
15
+ _role_r1_security() { cat <<'PROMPT'
16
+ [ROLE: Security Expert]
17
+ Analyze this from a security perspective. Focus on:
18
+ - Injection vulnerabilities (SQL, XSS, command injection)
19
+ - Authentication and authorization flaws
20
+ - Data exposure and PII handling
21
+ - Dependency vulnerabilities
22
+ - Secure configuration defaults
23
+ Rate each finding: CRITICAL / HIGH / MEDIUM / LOW.
24
+ PROMPT
25
+ }
26
+
27
+ _role_r2_security() { cat <<'PROMPT'
28
+ [ROLE: Security Expert — Deliberation]
29
+ Other reviewers provided their analysis below. Maintain your security perspective.
30
+ Identify security implications they may have missed. Update your findings if other arguments convince you.
31
+ Do not soften your assessment to align with others — escalate disagreements.
32
+ PROMPT
33
+ }
34
+
35
+ _role_r1_architect() { cat <<'PROMPT'
36
+ [ROLE: Software Architect]
37
+ Analyze this from an architectural perspective. Focus on:
38
+ - System design and component boundaries
39
+ - Scalability and performance characteristics
40
+ - Coupling, cohesion, and separation of concerns
41
+ - Design pattern appropriateness
42
+ - Migration path and backward compatibility
43
+ Provide concrete alternatives where you see problems.
44
+ PROMPT
45
+ }
46
+
47
+ _role_r2_architect() { cat <<'PROMPT'
48
+ [ROLE: Software Architect — Deliberation]
49
+ Other reviewers provided their analysis below. Maintain your architectural perspective.
50
+ Evaluate their proposals against scalability and maintainability criteria. If their approach has hidden architectural costs, say so.
51
+ PROMPT
52
+ }
53
+
54
+ _role_r1_skeptic() { cat <<'PROMPT'
55
+ [ROLE: Skeptic / Devil's Advocate]
56
+ Your job is to find problems. Assume the proposal will fail and explain why:
57
+ - What assumptions does this design make that could be wrong?
58
+ - What are the failure modes?
59
+ - What happens under edge cases, high load, or adversarial input?
60
+ - What would you need to see to be convinced this will work?
61
+ Be specific. "This might not scale" is not enough — explain how and why it would break.
62
+ PROMPT
63
+ }
64
+
65
+ _role_r2_skeptic() { cat <<'PROMPT'
66
+ [ROLE: Skeptic — Deliberation]
67
+ Other reviewers responded to your concerns below. For each of your original objections:
68
+ - Was it adequately addressed? (YES / PARTIALLY / NO)
69
+ - If partially or no, restate the concern with additional evidence.
70
+ - If yes, acknowledge the resolution.
71
+ Do NOT concede just to reach consensus. Persist where evidence supports your position.
72
+ PROMPT
73
+ }
74
+
75
+ _role_r1_perf() { cat <<'PROMPT'
76
+ [ROLE: Performance Expert]
77
+ Analyze this from a performance perspective. Focus on:
78
+ - Time complexity and algorithmic efficiency
79
+ - Memory allocation patterns and GC pressure
80
+ - I/O patterns (database queries, network calls, file operations)
81
+ - Caching opportunities and cache invalidation
82
+ - Bottleneck identification
83
+ Quantify where possible (O(n), expected latency, memory bounds).
84
+ PROMPT
85
+ }
86
+
87
+ _role_r2_perf() { cat <<'PROMPT'
88
+ [ROLE: Performance Expert — Deliberation]
89
+ Other reviewers provided their analysis below. Maintain your performance perspective.
90
+ Check if their proposals introduce performance regressions you can identify.
91
+ PROMPT
92
+ }
93
+
94
+ _role_r1_testing() { cat <<'PROMPT'
95
+ [ROLE: Testing Expert]
96
+ Analyze this from a testing perspective. Focus on:
97
+ - Test coverage gaps (what is NOT tested)
98
+ - Edge cases and boundary conditions
99
+ - Integration vs unit test coverage
100
+ - Regression risk areas
101
+ - Testability of the proposed design
102
+ List specific test cases that should exist.
103
+ PROMPT
104
+ }
105
+
106
+ _role_r2_testing() { cat <<'PROMPT'
107
+ [ROLE: Testing Expert — Deliberation]
108
+ Other reviewers provided their analysis below. Maintain your testing perspective.
109
+ Identify testing implications of their proposals that they may have missed.
110
+ PROMPT
111
+ }
112
+
113
+ _role_r1_maintainer() { cat <<'PROMPT'
114
+ [ROLE: Maintainer]
115
+ Analyze this from a maintenance perspective. Focus on:
116
+ - Code clarity and readability
117
+ - Documentation adequacy
118
+ - Naming conventions and consistency
119
+ - Error handling patterns
120
+ - How easy it is for a new team member to understand and modify
121
+ Flag anything that would cause confusion in a PR review.
122
+ PROMPT
123
+ }
124
+
125
+ _role_r2_maintainer() { cat <<'PROMPT'
126
+ [ROLE: Maintainer — Deliberation]
127
+ Other reviewers provided their analysis below. Maintain your maintenance perspective.
128
+ Assess whether their proposals improve or degrade overall code health.
129
+ PROMPT
130
+ }
131
+
132
+ _role_r1_dx() { cat <<'PROMPT'
133
+ [ROLE: DX Expert]
134
+ Analyze this from a developer experience perspective. Focus on:
135
+ - API ergonomics and discoverability
136
+ - Error messages and debugging experience
137
+ - Configuration complexity
138
+ - Developer workflow integration
139
+ - Breaking changes and migration burden
140
+ Suggest concrete DX improvements.
141
+ PROMPT
142
+ }
143
+
144
+ _role_r2_dx() { cat <<'PROMPT'
145
+ [ROLE: DX Expert — Deliberation]
146
+ Other reviewers provided their analysis below. Maintain your DX perspective.
147
+ Ensure their proposals don't introduce unnecessary complexity for developers.
148
+ PROMPT
149
+ }
150
+
151
+ _role_r1_neutral() { cat <<'PROMPT'
152
+ [ROLE: Neutral Analyst]
153
+ Provide a thorough, balanced analysis. Consider multiple perspectives and state your reasoning clearly.
154
+ PROMPT
155
+ }
156
+
157
+ _role_r2_neutral() { cat <<'PROMPT'
158
+ [ROLE: Neutral Analyst — Deliberation]
159
+ Other reviewers provided their analysis below. Consider their points fairly. Update your analysis where you find their arguments convincing. Note any remaining disagreements.
160
+ PROMPT
161
+ }
162
+
163
+ # ─── Role Prompt Access ────────────────────────────────────────
164
+
165
+ role_get_r1() {
166
+ local role="${1:?Usage: role_get_r1 <role_name>}"
167
+ # Check builtin via function dispatch
168
+ if type "_role_r1_${role}" &>/dev/null; then
169
+ "_role_r1_${role}"
170
+ return
171
+ fi
172
+ # Check template file
173
+ if [[ -f "$ROLE_TEMPLATES_DIR/${role}.md" ]]; then
174
+ head -50 "$ROLE_TEMPLATES_DIR/${role}.md"
175
+ return
176
+ fi
177
+ # Check custom role
178
+ if [[ -f "$CUSTOM_ROLES_DIR/${role}.md" ]]; then
179
+ cat "$CUSTOM_ROLES_DIR/${role}.md"
180
+ return
181
+ fi
182
+ # Fallback to neutral
183
+ _role_r1_neutral
184
+ }
185
+
186
+ role_get_r2() {
187
+ local role="${1:?Usage: role_get_r2 <role_name>}"
188
+ if type "_role_r2_${role}" &>/dev/null; then
189
+ "_role_r2_${role}"
190
+ return
191
+ fi
192
+ if [[ -f "$CUSTOM_ROLES_DIR/${role}-deliberation.md" ]]; then
193
+ cat "$CUSTOM_ROLES_DIR/${role}-deliberation.md"
194
+ return
195
+ fi
196
+ if [[ -f "$ROLE_TEMPLATES_DIR/${role}-deliberation.md" ]]; then
197
+ cat "$ROLE_TEMPLATES_DIR/${role}-deliberation.md"
198
+ return
199
+ fi
200
+ _role_r2_neutral
201
+ }
202
+
203
+ # ─── List Available Roles ──────────────────────────────────────
204
+
205
+ role_list() {
206
+ echo "=== Builtin Roles ==="
207
+ for role in security architect skeptic perf testing maintainer dx neutral; do
208
+ echo " ${role}"
209
+ done
210
+
211
+ echo ""
212
+ echo "=== Template Roles ==="
213
+ if [[ -d "$ROLE_TEMPLATES_DIR" ]]; then
214
+ for f in "$ROLE_TEMPLATES_DIR"/*.md; do
215
+ [[ -f "$f" ]] || continue
216
+ local name
217
+ name=$(basename "$f" .md)
218
+ [[ "$name" == *"-deliberation" ]] && continue
219
+ [[ "$name" == _* ]] && continue
220
+ echo " ${name}"
221
+ done
222
+ fi
223
+
224
+ echo ""
225
+ echo "=== Custom Roles ==="
226
+ if [[ -d "$CUSTOM_ROLES_DIR" ]]; then
227
+ local found=0
228
+ for f in "$CUSTOM_ROLES_DIR"/*.md; do
229
+ [[ -f "$f" ]] || continue
230
+ found=1
231
+ echo " $(basename "$f" .md)"
232
+ done
233
+ if [[ "$found" -eq 0 ]]; then
234
+ echo " (none — create with: acpx-council roles create <name>)"
235
+ fi
236
+ else
237
+ echo " (none — create with: acpx-council roles create <name>)"
238
+ fi
239
+ }
240
+
241
+ # ─── Create Custom Role ────────────────────────────────────────
242
+
243
+ role_create() {
244
+ local name="${1:?Usage: role_create <name> [focus] [technologies]}"
245
+ local focus="${2:-General analysis}"
246
+ local tech="${3:-}"
247
+
248
+ mkdir -p "$CUSTOM_ROLES_DIR"
249
+
250
+ cat > "$CUSTOM_ROLES_DIR/${name}.md" <<ROLE
251
+ [ROLE: ${name}]
252
+ Analyze this from a ${focus} perspective. Focus on:
253
+ - ${focus} best practices and patterns
254
+ - Common pitfalls and anti-patterns
255
+ ${tech:+- Technology-specific considerations: ${tech}}
256
+ - Impact on overall system quality
257
+ Provide specific, actionable findings.
258
+ ROLE
259
+
260
+ cat > "$CUSTOM_ROLES_DIR/${name}-deliberation.md" <<ROLE2
261
+ [ROLE: ${name} — Deliberation]
262
+ Other reviewers provided their analysis below. Maintain your ${focus} perspective.
263
+ Identify ${focus} implications they may have missed.
264
+ Do not soften your assessment to align with others.
265
+ ROLE2
266
+
267
+ echo "Created custom role: ${name}"
268
+ echo " Prompt: $CUSTOM_ROLES_DIR/${name}.md"
269
+ echo " Deliberation: $CUSTOM_ROLES_DIR/${name}-deliberation.md"
270
+ }
271
+
272
+ # ─── Auto-Infer Roles from Task ────────────────────────────────
273
+
274
+ role_infer_from_task() {
275
+ local task="${1:?Usage: role_infer_from_task <task_description>}"
276
+ local task_lower
277
+ task_lower=$(echo "$task" | tr '[:upper:]' '[:lower:]')
278
+
279
+ local -a inferred=()
280
+ local inferred_str=""
281
+
282
+ # Keyword→role matching (Bash 3.2 safe)
283
+ _match_role() {
284
+ local role="$1"
285
+ shift
286
+ for kw in "$@"; do
287
+ if [[ "$task_lower" == *"$kw"* ]]; then
288
+ # Deduplicate
289
+ if [[ "$inferred_str" != *":${role}:"* ]]; then
290
+ inferred+=("$role")
291
+ inferred_str="${inferred_str}:${role}:"
292
+ fi
293
+ return
294
+ fi
295
+ done
296
+ }
297
+
298
+ _match_role security "security" "vulnerability" "auth" "authentication" "authorization" "xss" "injection" "owasp" "encryption" "token"
299
+ _match_role architect "architecture" "system design" "scalability" "migration" "refactor" "microservice" "monorepo"
300
+ _match_role perf "performance" "latency" "throughput" "optimization" "bottleneck" "caching" "memory" "slow"
301
+ _match_role testing "test" "coverage" "edge case" "regression" "integration test" "unit test" "e2e"
302
+ _match_role database "database" "sql" "query" "index" "migration" "schema" "postgresql" "redis" "mongodb" "prisma" "drizzle"
303
+ _match_role frontend "ui" "frontend" "react" "next.js" "css" "component" "accessibility" "a11y"
304
+ _match_role payments "payment" "stripe" "billing" "checkout" "subscription"
305
+ _match_role devops "deploy" "ci/cd" "docker" "kubernetes" "infrastructure" "pipeline"
306
+ _match_role dx "developer experience" "dx" "api design" "ergonomics" "error message" "usability"
307
+ _match_role i18n "internationalization" "i18n" "localization" "locale" "translation"
308
+
309
+ # Always add skeptic if fewer than 2 roles matched
310
+ if [[ ${#inferred[@]} -lt 2 ]]; then
311
+ if [[ "$inferred_str" != *":skeptic:"* ]]; then
312
+ inferred+=("skeptic")
313
+ fi
314
+ fi
315
+
316
+ # Output one per line
317
+ for role in "${inferred[@]}"; do
318
+ echo "$role"
319
+ done
320
+ }
321
+
322
+ # ─── Assign Roles to Agents ────────────────────────────────────
323
+
324
+ role_assign_to_agents() {
325
+ local agents_str="${1:?Usage: role_assign_to_agents <agents,comma,sep> <roles,comma,sep>}"
326
+ local roles_str="${2:?missing roles}"
327
+
328
+ local IFS=','
329
+ local -a agents_arr=($agents_str)
330
+ local -a roles_arr=($roles_str)
331
+ unset IFS
332
+
333
+ local i=0
334
+ for agent in "${agents_arr[@]}"; do
335
+ local role="${roles_arr[$((i % ${#roles_arr[@]}))]:-neutral}"
336
+ echo "${agent}:${role}"
337
+ ((i++))
338
+ done
339
+ }
@@ -0,0 +1,187 @@
1
+ #!/usr/bin/env bash
2
+ # synthesize.sh — Auto consensus detection and synthesis for acpx council
3
+ # Analyzes multi-agent outputs, detects agreements/divergences, produces structured synthesis
4
+ # Compatible with Bash 3.2+, cross-platform (macOS/Linux/Windows Git Bash)
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 workspace functions ─────────────────────────────────
12
+ source "${ACPX_ROOT}/lib/workspace.sh"
13
+
14
+ # ─── Gather All Outputs for a Round ────────────────────────────
15
+
16
+ _gather_all_outputs() {
17
+ local round="${1:?Usage: _gather_all_outputs <round>}"
18
+ local ws="${2:-$ACPX_WORKSPACE}"
19
+
20
+ for agent_dir in "${ws}/agents"/*/; do
21
+ [[ -d "$agent_dir" ]] || continue
22
+ local agent_name
23
+ agent_name=$(basename "$agent_dir")
24
+ local file="${agent_dir}round-${round}.md"
25
+ if [[ -f "$file" ]]; then
26
+ echo "---"
27
+ echo "## Agent: ${agent_name}"
28
+ echo ""
29
+ cat "$file"
30
+ echo ""
31
+ echo ""
32
+ fi
33
+ done
34
+ }
35
+
36
+ # ─── Synthesize Round ──────────────────────────────────────────
37
+ # Analyzes all agent outputs for a round and produces structured synthesis
38
+
39
+ synthesize_round() {
40
+ local round="${1:?Usage: synthesize_round <round> [orchestrator] [output_file]}"
41
+ local orchestrator="${2:-claude}"
42
+ local output_file="${3:-$ACPX_WORKSPACE/synthesis.md}"
43
+
44
+ local all_outputs
45
+ all_outputs=$(_gather_all_outputs "$round")
46
+
47
+ if [[ -z "$all_outputs" ]]; then
48
+ echo "Error: no agent outputs found for round ${round}" >&2
49
+ return 1
50
+ fi
51
+
52
+ # Build synthesis prompt using heredoc (avoids quoting issues)
53
+ local prompt
54
+ prompt=$(cat <<SYNPROMPT
55
+ You are a synthesis analyst. Review the following multi-agent deliberation outputs and produce a structured consensus report.
56
+
57
+ ## Agent Outputs
58
+
59
+ ${all_outputs}
60
+
61
+ ## Instructions
62
+
63
+ Analyze the above outputs and produce a structured report with EXACTLY these sections:
64
+
65
+ ### CONSENSUS
66
+ Points where ALL or MOST agents agree. Format as bullet points.
67
+
68
+ ### DIVERGENCES
69
+ Points where agents DISAGREE. For each:
70
+ - State the point of disagreement
71
+ - Quote each opposing position
72
+ - Assess which position has stronger evidence
73
+
74
+ ### ACTION ITEMS
75
+ Concrete next steps derived from the discussion. Format as numbered list.
76
+
77
+ ### HUMAN DECISIONS NEEDED
78
+ Questions or tradeoffs that require human judgment. For each:
79
+ - State the question
80
+ - Summarize the options
81
+ - Note any time/cost/quality implications
82
+
83
+ ### CONFIDENCE
84
+ Overall confidence in the consensus (HIGH / MEDIUM / LOW) with brief justification.
85
+
86
+ ### RECOMMENDATION
87
+ One clear recommended path forward based on the analysis above.
88
+ SYNPROMPT
89
+ )
90
+
91
+ # Run orchestrator agent to synthesize
92
+ acpx --format quiet "$orchestrator" exec "$prompt" > "$output_file"
93
+
94
+ echo "Synthesis written to $output_file"
95
+ }
96
+
97
+ # ─── Quick Consensus Check ─────────────────────────────────────
98
+ # Lightweight check: do agents broadly agree? Returns HIGH/MEDIUM/LOW
99
+
100
+ consensus_check() {
101
+ local round="${1:?Usage: consensus_check <round> [orchestrator]}"
102
+ local orchestrator="${2:-claude}"
103
+
104
+ local all_outputs=""
105
+ for agent_dir in "$ACPX_WORKSPACE/agents"/*/; do
106
+ [[ -d "$agent_dir" ]] || continue
107
+ local agent_name
108
+ agent_name=$(basename "$agent_dir")
109
+ local file="${agent_dir}round-${round}.md"
110
+ if [[ -f "$file" ]]; then
111
+ all_outputs="${all_outputs}[${agent_name}]: $(head -100 "$file")"$'\n\n'
112
+ fi
113
+ done
114
+
115
+ if [[ -z "$all_outputs" ]]; then
116
+ echo "LOW"
117
+ return
118
+ fi
119
+
120
+ local result
121
+ result=$(acpx --format quiet "$orchestrator" exec "$(cat <<CHKPROMPT
122
+ Analyze these agent responses and rate their agreement level.
123
+ Respond with EXACTLY one word: HIGH (mostly agree), MEDIUM (some disagreements), or LOW (fundamentally different views).
124
+
125
+ ${all_outputs}
126
+ CHKPROMPT
127
+ )" 2>/dev/null | head -1)
128
+
129
+ # Normalize
130
+ case "${result:-LOW}" in
131
+ *HIGH*) echo "HIGH" ;;
132
+ *MEDIUM*) echo "MEDIUM" ;;
133
+ *LOW*) echo "LOW" ;;
134
+ *) echo "MEDIUM" ;;
135
+ esac
136
+ }
137
+
138
+ # ─── Plan Synthesis ────────────────────────────────────────────
139
+ # Synthesize plan-phase outputs into an actionable plan document
140
+
141
+ synthesize_plan() {
142
+ local orchestrator="${1:-claude}"
143
+ local output_file="${2:-$ACPX_WORKSPACE/plan.md}"
144
+ local task=""
145
+ if [[ -f "$ACPX_WORKSPACE/context.md" ]]; then
146
+ task=$(grep -A1 "^## Task$" "$ACPX_WORKSPACE/context.md" 2>/dev/null | tail -1 | xargs || true)
147
+ fi
148
+
149
+ local all_outputs=""
150
+ for agent_dir in "$ACPX_WORKSPACE/agents"/*/; do
151
+ [[ -d "$agent_dir" ]] || continue
152
+ local agent_name
153
+ agent_name=$(basename "$agent_dir")
154
+ local file="${agent_dir}round-1.md"
155
+ if [[ -f "$file" ]]; then
156
+ all_outputs="${all_outputs}---"$'\n'"## ${agent_name}"$'\n\n'"$(cat "$file")"$'\n\n'
157
+ fi
158
+ done
159
+
160
+ local prompt
161
+ prompt=$(cat <<PLANPROMPT
162
+ You are a technical lead synthesizing a plan from multiple expert opinions.
163
+
164
+ ## Original Task
165
+ ${task}
166
+
167
+ ## Expert Opinions
168
+ ${all_outputs}
169
+
170
+ ## Instructions
171
+ Produce a clear, actionable implementation plan that:
172
+ 1. Incorporates the strongest points from each expert
173
+ 2. Resolves any contradictions (explain why you chose one approach over another)
174
+ 3. Is ordered by dependency (what to do first, second, etc.)
175
+ 4. Includes verification steps
176
+
177
+ Format as a numbered plan with:
178
+ - Step description
179
+ - Rationale (brief)
180
+ - Files/modules affected
181
+ - Verification criteria
182
+ PLANPROMPT
183
+ )
184
+
185
+ acpx --format quiet "$orchestrator" exec "$prompt" > "$output_file"
186
+ echo "Plan written to $output_file"
187
+ }