shipwright-cli 1.10.0 → 2.0.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.
Files changed (108) hide show
  1. package/README.md +114 -36
  2. package/completions/_shipwright +212 -32
  3. package/completions/shipwright.bash +97 -25
  4. package/docs/strategy/01-market-research.md +619 -0
  5. package/docs/strategy/02-mission-and-brand.md +587 -0
  6. package/docs/strategy/03-gtm-and-roadmap.md +759 -0
  7. package/docs/strategy/QUICK-START.txt +289 -0
  8. package/docs/strategy/README.md +172 -0
  9. package/package.json +4 -2
  10. package/scripts/sw +208 -1
  11. package/scripts/sw-activity.sh +500 -0
  12. package/scripts/sw-adaptive.sh +925 -0
  13. package/scripts/sw-adversarial.sh +1 -1
  14. package/scripts/sw-architecture-enforcer.sh +1 -1
  15. package/scripts/sw-auth.sh +613 -0
  16. package/scripts/sw-autonomous.sh +664 -0
  17. package/scripts/sw-changelog.sh +704 -0
  18. package/scripts/sw-checkpoint.sh +1 -1
  19. package/scripts/sw-ci.sh +602 -0
  20. package/scripts/sw-cleanup.sh +1 -1
  21. package/scripts/sw-code-review.sh +637 -0
  22. package/scripts/sw-connect.sh +1 -1
  23. package/scripts/sw-context.sh +605 -0
  24. package/scripts/sw-cost.sh +1 -1
  25. package/scripts/sw-daemon.sh +432 -130
  26. package/scripts/sw-dashboard.sh +1 -1
  27. package/scripts/sw-db.sh +540 -0
  28. package/scripts/sw-decompose.sh +539 -0
  29. package/scripts/sw-deps.sh +551 -0
  30. package/scripts/sw-developer-simulation.sh +1 -1
  31. package/scripts/sw-discovery.sh +412 -0
  32. package/scripts/sw-docs-agent.sh +539 -0
  33. package/scripts/sw-docs.sh +1 -1
  34. package/scripts/sw-doctor.sh +59 -1
  35. package/scripts/sw-dora.sh +615 -0
  36. package/scripts/sw-durable.sh +710 -0
  37. package/scripts/sw-e2e-orchestrator.sh +535 -0
  38. package/scripts/sw-eventbus.sh +393 -0
  39. package/scripts/sw-feedback.sh +471 -0
  40. package/scripts/sw-fix.sh +1 -1
  41. package/scripts/sw-fleet-discover.sh +567 -0
  42. package/scripts/sw-fleet-viz.sh +404 -0
  43. package/scripts/sw-fleet.sh +8 -1
  44. package/scripts/sw-github-app.sh +596 -0
  45. package/scripts/sw-github-checks.sh +1 -1
  46. package/scripts/sw-github-deploy.sh +1 -1
  47. package/scripts/sw-github-graphql.sh +1 -1
  48. package/scripts/sw-guild.sh +569 -0
  49. package/scripts/sw-heartbeat.sh +1 -1
  50. package/scripts/sw-hygiene.sh +559 -0
  51. package/scripts/sw-incident.sh +617 -0
  52. package/scripts/sw-init.sh +88 -1
  53. package/scripts/sw-instrument.sh +699 -0
  54. package/scripts/sw-intelligence.sh +1 -1
  55. package/scripts/sw-jira.sh +1 -1
  56. package/scripts/sw-launchd.sh +363 -28
  57. package/scripts/sw-linear.sh +1 -1
  58. package/scripts/sw-logs.sh +1 -1
  59. package/scripts/sw-loop.sh +64 -3
  60. package/scripts/sw-memory.sh +1 -1
  61. package/scripts/sw-mission-control.sh +487 -0
  62. package/scripts/sw-model-router.sh +545 -0
  63. package/scripts/sw-otel.sh +596 -0
  64. package/scripts/sw-oversight.sh +689 -0
  65. package/scripts/sw-pipeline-composer.sh +1 -1
  66. package/scripts/sw-pipeline-vitals.sh +1 -1
  67. package/scripts/sw-pipeline.sh +687 -24
  68. package/scripts/sw-pm.sh +693 -0
  69. package/scripts/sw-pr-lifecycle.sh +522 -0
  70. package/scripts/sw-predictive.sh +1 -1
  71. package/scripts/sw-prep.sh +1 -1
  72. package/scripts/sw-ps.sh +1 -1
  73. package/scripts/sw-public-dashboard.sh +798 -0
  74. package/scripts/sw-quality.sh +595 -0
  75. package/scripts/sw-reaper.sh +1 -1
  76. package/scripts/sw-recruit.sh +573 -0
  77. package/scripts/sw-regression.sh +642 -0
  78. package/scripts/sw-release-manager.sh +736 -0
  79. package/scripts/sw-release.sh +706 -0
  80. package/scripts/sw-remote.sh +1 -1
  81. package/scripts/sw-replay.sh +520 -0
  82. package/scripts/sw-retro.sh +691 -0
  83. package/scripts/sw-scale.sh +444 -0
  84. package/scripts/sw-security-audit.sh +505 -0
  85. package/scripts/sw-self-optimize.sh +1 -1
  86. package/scripts/sw-session.sh +1 -1
  87. package/scripts/sw-setup.sh +1 -1
  88. package/scripts/sw-standup.sh +712 -0
  89. package/scripts/sw-status.sh +1 -1
  90. package/scripts/sw-strategic.sh +658 -0
  91. package/scripts/sw-stream.sh +450 -0
  92. package/scripts/sw-swarm.sh +583 -0
  93. package/scripts/sw-team-stages.sh +511 -0
  94. package/scripts/sw-templates.sh +1 -1
  95. package/scripts/sw-testgen.sh +515 -0
  96. package/scripts/sw-tmux-pipeline.sh +554 -0
  97. package/scripts/sw-tmux.sh +1 -1
  98. package/scripts/sw-trace.sh +485 -0
  99. package/scripts/sw-tracker-github.sh +188 -0
  100. package/scripts/sw-tracker-jira.sh +172 -0
  101. package/scripts/sw-tracker-linear.sh +251 -0
  102. package/scripts/sw-tracker.sh +117 -2
  103. package/scripts/sw-triage.sh +603 -0
  104. package/scripts/sw-upgrade.sh +1 -1
  105. package/scripts/sw-ux.sh +677 -0
  106. package/scripts/sw-webhook.sh +627 -0
  107. package/scripts/sw-widgets.sh +530 -0
  108. package/scripts/sw-worktree.sh +1 -1
@@ -0,0 +1,511 @@
1
+ #!/usr/bin/env bash
2
+ # ╔═══════════════════════════════════════════════════════════════════════════╗
3
+ # ║ shipwright team-stages — Multi-agent execution with leader/specialist roles ║
4
+ # ║ Decompose stages into parallel tasks · Consensus voting · Result aggregation║
5
+ # ╚═══════════════════════════════════════════════════════════════════════════╝
6
+ set -euo pipefail
7
+ trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
+
9
+ VERSION="2.0.0"
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
+
13
+ # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
14
+ CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
15
+ PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
16
+ BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
17
+ GREEN='\033[38;2;74;222;128m' # success
18
+ YELLOW='\033[38;2;250;204;21m' # warning
19
+ RED='\033[38;2;248;113;113m' # error
20
+ DIM='\033[2m'
21
+ BOLD='\033[1m'
22
+ RESET='\033[0m'
23
+
24
+ # ─── Cross-platform compatibility ──────────────────────────────────────────
25
+ # shellcheck source=lib/compat.sh
26
+ [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
27
+
28
+ # ─── Output Helpers ─────────────────────────────────────────────────────────
29
+ info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
30
+ success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
31
+ warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
32
+ error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
33
+
34
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
35
+ now_epoch() { date +%s; }
36
+
37
+ # ─── Structured Event Log ──────────────────────────────────────────────────
38
+ EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
39
+
40
+ emit_event() {
41
+ local event_type="$1"
42
+ shift
43
+ local json_fields=""
44
+ for kv in "$@"; do
45
+ local key="${kv%%=*}"
46
+ local val="${kv#*=}"
47
+ if [[ "$val" =~ ^-?[0-9]+\.?[0-9]*$ ]]; then
48
+ json_fields="${json_fields},\"${key}\":${val}"
49
+ else
50
+ val="${val//\"/\\\"}"
51
+ json_fields="${json_fields},\"${key}\":\"${val}\""
52
+ fi
53
+ done
54
+ mkdir -p "${HOME}/.shipwright"
55
+ echo "{\"ts\":\"$(now_iso)\",\"ts_epoch\":$(now_epoch),\"type\":\"${event_type}\"${json_fields}}" >> "$EVENTS_FILE"
56
+ }
57
+
58
+ # ─── Team Configuration ─────────────────────────────────────────────────────
59
+ TEAM_STATE_DIR="${HOME}/.shipwright/team-state"
60
+ INTELLIGENCE_CACHE="${REPO_DIR}/.claude/intelligence-cache.json"
61
+
62
+ ensure_team_dir() {
63
+ mkdir -p "$TEAM_STATE_DIR"
64
+ }
65
+
66
+ # ─── Role Definitions ───────────────────────────────────────────────────────
67
+ # Each role has a prompt injection template that guides the agent's focus
68
+
69
+ declare_role() {
70
+ local role="$1"
71
+ case "$role" in
72
+ builder)
73
+ echo "Implementation specialist — focuses on code quality, architecture, patterns"
74
+ ;;
75
+ reviewer)
76
+ echo "Code reviewer — validates correctness, design, performance, security"
77
+ ;;
78
+ tester)
79
+ echo "Test specialist — writes tests, validates coverage, detects edge cases"
80
+ ;;
81
+ security)
82
+ echo "Security engineer — scans for vulns, auth issues, injection risks"
83
+ ;;
84
+ docs)
85
+ echo "Documentation specialist — API docs, examples, type definitions"
86
+ ;;
87
+ *)
88
+ echo "$role — specialist agent"
89
+ ;;
90
+ esac
91
+ }
92
+
93
+ # ─── Compose: Generate team for a stage ─────────────────────────────────────
94
+ cmd_compose() {
95
+ local stage="${1:-build}"
96
+ local complexity="${2:-medium}"
97
+
98
+ ensure_team_dir
99
+
100
+ local team_json
101
+ local leader="lead-agent"
102
+ local specialists=""
103
+
104
+ case "$stage" in
105
+ build)
106
+ specialists="builder builder reviewer"
107
+ ;;
108
+ test)
109
+ specialists="tester tester security"
110
+ ;;
111
+ review)
112
+ specialists="reviewer reviewer security"
113
+ ;;
114
+ *)
115
+ specialists="builder reviewer tester"
116
+ ;;
117
+ esac
118
+
119
+ # Count specialists
120
+ local spec_count
121
+ spec_count=$(echo "$specialists" | wc -w)
122
+
123
+ team_json=$(jq -n \
124
+ --arg stage "$stage" \
125
+ --arg complexity "$complexity" \
126
+ --arg leader "$leader" \
127
+ --argjson spec_count "$spec_count" \
128
+ --arg specialists "$specialists" \
129
+ '{
130
+ stage: $stage,
131
+ complexity: $complexity,
132
+ created_at: "'$(now_iso)'",
133
+ leader: $leader,
134
+ specialists: ($specialists | split(" ")),
135
+ specialist_count: $spec_count,
136
+ status: "pending"
137
+ }')
138
+
139
+ echo "$team_json"
140
+
141
+ emit_event "team_composed" \
142
+ "stage=$stage" \
143
+ "complexity=$complexity" \
144
+ "specialist_count=$spec_count"
145
+ }
146
+
147
+ # ─── Delegate: Break stage into agent tasks with file assignments ───────────
148
+ cmd_delegate() {
149
+ local stage="${1:-build}"
150
+ local complexity="${2:-medium}"
151
+
152
+ ensure_team_dir
153
+
154
+ local team_json
155
+ team_json=$(cmd_compose "$stage" "$complexity")
156
+
157
+ # Read hotspots from intelligence cache if available
158
+ local hotspots=""
159
+ if [[ -f "$INTELLIGENCE_CACHE" ]]; then
160
+ hotspots=$(jq -r '.hotspots[]? // empty' "$INTELLIGENCE_CACHE" 2>/dev/null | head -10 || true)
161
+ fi
162
+
163
+ # Collect changed files for this stage
164
+ local changed_files=""
165
+ if git rev-parse HEAD >/dev/null 2>&1; then
166
+ changed_files=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git ls-files || true)
167
+ fi
168
+
169
+ # Distribute files across specialists
170
+ local specialist_count
171
+ specialist_count=$(echo "$team_json" | jq -r '.specialist_count // 1')
172
+
173
+ local tasks="[]"
174
+ local file_count=0
175
+
176
+ # Assign files round-robin to specialists
177
+ while IFS= read -r file; do
178
+ [[ -z "$file" ]] && continue
179
+ local spec_idx=$((file_count % specialist_count))
180
+ local task_json
181
+ task_json=$(jq -n \
182
+ --arg file "$file" \
183
+ --arg spec_idx "$spec_idx" \
184
+ --arg status "pending" \
185
+ '{
186
+ file: $file,
187
+ specialist_idx: ($spec_idx | tonumber),
188
+ status: $status,
189
+ assigned_at: "'$(now_iso)'",
190
+ result: null
191
+ }')
192
+ tasks=$(echo "$tasks" | jq ". += [$task_json]")
193
+ ((file_count++))
194
+ done < <(echo "$changed_files")
195
+
196
+ # Output delegation result
197
+ local result
198
+ result=$(echo "$team_json" | jq \
199
+ --argjson tasks "$tasks" \
200
+ --argjson file_count "$file_count" \
201
+ '.tasks = $tasks | .file_count = $file_count')
202
+
203
+ echo "$result"
204
+
205
+ emit_event "stage_delegated" \
206
+ "stage=$stage" \
207
+ "specialist_count=$specialist_count" \
208
+ "file_count=$file_count"
209
+ }
210
+
211
+ # ─── Status: Show team member status for active stage ───────────────────────
212
+ cmd_status() {
213
+ local stage="${1:-}"
214
+
215
+ ensure_team_dir
216
+
217
+ if [[ -z "$stage" ]]; then
218
+ # List all active teams
219
+ if [[ ! -d "$TEAM_STATE_DIR" ]] || [[ -z "$(ls -A "$TEAM_STATE_DIR" 2>/dev/null)" ]]; then
220
+ info "No active teams"
221
+ return 0
222
+ fi
223
+
224
+ for team_file in "$TEAM_STATE_DIR"/*.json; do
225
+ [[ -f "$team_file" ]] || continue
226
+ local ts
227
+ ts=$(stat -f %Bm "$team_file" 2>/dev/null || stat -c %Y "$team_file" 2>/dev/null || echo 0)
228
+ local name
229
+ name=$(basename "$team_file" .json)
230
+ local status
231
+ status=$(jq -r '.status // "unknown"' "$team_file" 2>/dev/null || echo "error")
232
+ printf " %-30s %-15s %-20s\n" "$name" "$status" "$(date -r "$ts" +'%Y-%m-%d %H:%M:%S' 2>/dev/null || echo 'unknown')"
233
+ done
234
+ return 0
235
+ fi
236
+
237
+ # Show details for specific stage
238
+ local team_file="$TEAM_STATE_DIR/${stage}.json"
239
+ if [[ ! -f "$team_file" ]]; then
240
+ error "No team state for stage: $stage"
241
+ exit 1
242
+ fi
243
+
244
+ local team_json
245
+ team_json=$(cat "$team_file")
246
+
247
+ # Display leader
248
+ local leader
249
+ leader=$(echo "$team_json" | jq -r '.leader // "unknown"')
250
+ echo ""
251
+ echo -e " ${BOLD}${CYAN}Stage:${RESET} $(echo "$team_json" | jq -r '.stage')"
252
+ echo -e " ${BOLD}${CYAN}Leader:${RESET} $leader"
253
+ echo -e " ${BOLD}${CYAN}Status:${RESET} $(echo "$team_json" | jq -r '.status // "unknown"')"
254
+ echo ""
255
+
256
+ # Display specialists
257
+ echo -e " ${BOLD}Specialists${RESET}"
258
+ local specs
259
+ specs=$(echo "$team_json" | jq -r '.specialists[]? // empty')
260
+ local spec_idx=0
261
+ while IFS= read -r spec; do
262
+ [[ -z "$spec" ]] && continue
263
+ local spec_status
264
+ spec_status=$(echo "$team_json" | jq -r ".specialist_status[$spec_idx] // \"pending\"" 2>/dev/null || echo "pending")
265
+ printf " ${DIM}%-3d${RESET} %-20s %-15s\n" "$((spec_idx + 1))" "$spec" "$spec_status"
266
+ ((spec_idx++))
267
+ done < <(echo "$specs")
268
+ echo ""
269
+ }
270
+
271
+ # ─── Vote: Collect and tally review votes ──────────────────────────────────
272
+ cmd_vote() {
273
+ local stage="${1:-}"
274
+ local team_file="$TEAM_STATE_DIR/${stage}.json"
275
+
276
+ if [[ -z "$stage" ]]; then
277
+ error "Usage: shipwright team-stages vote <stage>"
278
+ exit 1
279
+ fi
280
+
281
+ if [[ ! -f "$team_file" ]]; then
282
+ error "No team state for stage: $stage"
283
+ exit 1
284
+ fi
285
+
286
+ local team_json
287
+ team_json=$(cat "$team_file")
288
+
289
+ # Collect verdicts from all specialists
290
+ local approve_count=0
291
+ local reject_count=0
292
+ local neutral_count=0
293
+ local total=0
294
+
295
+ local specs
296
+ specs=$(echo "$team_json" | jq -r '.specialists[]? // empty')
297
+
298
+ while IFS= read -r spec; do
299
+ [[ -z "$spec" ]] && continue
300
+ local verdict
301
+ verdict=$(echo "$team_json" | jq -r ".verdicts[\"$spec\"]? // \"neutral\"" 2>/dev/null || echo "neutral")
302
+ case "$verdict" in
303
+ approve) ((approve_count++)) ;;
304
+ reject) ((reject_count++)) ;;
305
+ *) ((neutral_count++)) ;;
306
+ esac
307
+ ((total++))
308
+ done < <(echo "$specs")
309
+
310
+ # Consensus: majority vote with leader tiebreak
311
+ local consensus="neutral"
312
+ if [[ $approve_count -gt $reject_count ]]; then
313
+ consensus="approve"
314
+ elif [[ $reject_count -gt $approve_count ]]; then
315
+ consensus="reject"
316
+ elif [[ $approve_count -eq $reject_count ]] && [[ $approve_count -gt 0 ]]; then
317
+ # Tiebreak: check leader verdict
318
+ local leader_verdict
319
+ leader_verdict=$(echo "$team_json" | jq -r '.verdicts.leader? // "neutral"' 2>/dev/null || echo "neutral")
320
+ consensus="$leader_verdict"
321
+ fi
322
+
323
+ local result
324
+ result=$(jq -n \
325
+ --argjson approve_count "$approve_count" \
326
+ --argjson reject_count "$reject_count" \
327
+ --argjson neutral_count "$neutral_count" \
328
+ --argjson total "$total" \
329
+ --arg consensus "$consensus" \
330
+ '{
331
+ approve: $approve_count,
332
+ reject: $reject_count,
333
+ neutral: $neutral_count,
334
+ total: $total,
335
+ consensus: $consensus,
336
+ decided_at: "'$(now_iso)'"
337
+ }')
338
+
339
+ echo "$result"
340
+
341
+ emit_event "vote_tallied" \
342
+ "stage=$stage" \
343
+ "consensus=$consensus" \
344
+ "approve=$approve_count" \
345
+ "reject=$reject_count"
346
+ }
347
+
348
+ # ─── Aggregate: Combine outputs from all agents ──────────────────────────────
349
+ cmd_aggregate() {
350
+ local stage="${1:-}"
351
+ local team_file="$TEAM_STATE_DIR/${stage}.json"
352
+
353
+ if [[ -z "$stage" ]]; then
354
+ error "Usage: shipwright team-stages aggregate <stage>"
355
+ exit 1
356
+ fi
357
+
358
+ if [[ ! -f "$team_file" ]]; then
359
+ error "No team state for stage: $stage"
360
+ exit 1
361
+ fi
362
+
363
+ local team_json
364
+ team_json=$(cat "$team_file")
365
+
366
+ # Collect task results from all specialists
367
+ local results="[]"
368
+ local success_count=0
369
+ local failure_count=0
370
+
371
+ local tasks
372
+ tasks=$(echo "$team_json" | jq -r '.tasks[]? // empty' 2>/dev/null)
373
+
374
+ while IFS= read -r task_line; do
375
+ [[ -z "$task_line" ]] && continue
376
+ local result
377
+ result=$(echo "$task_line" | jq -r '.result? // empty' 2>/dev/null)
378
+
379
+ if [[ -n "$result" ]]; then
380
+ if echo "$result" | jq -e '.success' >/dev/null 2>&1; then
381
+ ((success_count++))
382
+ else
383
+ ((failure_count++))
384
+ fi
385
+ results=$(echo "$results" | jq ". += [$result]")
386
+ fi
387
+ done < <(echo "$tasks" | jq -c '.[]')
388
+
389
+ # Build aggregated output
390
+ local aggregated
391
+ aggregated=$(jq -n \
392
+ --arg stage "$stage" \
393
+ --argjson results "$results" \
394
+ --argjson success_count "$success_count" \
395
+ --argjson failure_count "$failure_count" \
396
+ '{
397
+ stage: $stage,
398
+ task_count: ($results | length),
399
+ success_count: $success_count,
400
+ failure_count: $failure_count,
401
+ success_rate: (if ($results | length) > 0 then ($success_count / ($results | length) * 100) | floor else 0 end),
402
+ results: $results,
403
+ aggregated_at: "'$(now_iso)'"
404
+ }')
405
+
406
+ echo "$aggregated"
407
+
408
+ emit_event "results_aggregated" \
409
+ "stage=$stage" \
410
+ "task_count=$(echo "$aggregated" | jq -r '.task_count')" \
411
+ "success_rate=$(echo "$aggregated" | jq -r '.success_rate')"
412
+ }
413
+
414
+ # ─── Roles: List available roles and their descriptions ──────────────────────
415
+ cmd_roles() {
416
+ echo ""
417
+ echo -e " ${BOLD}${CYAN}Available Roles${RESET}"
418
+ echo -e " ${DIM}═══════════════════════════════════════════════════════════${RESET}"
419
+ echo ""
420
+ echo -e " ${CYAN}builder${RESET}"
421
+ echo " $(declare_role builder)"
422
+ echo ""
423
+ echo -e " ${CYAN}reviewer${RESET}"
424
+ echo " $(declare_role reviewer)"
425
+ echo ""
426
+ echo -e " ${CYAN}tester${RESET}"
427
+ echo " $(declare_role tester)"
428
+ echo ""
429
+ echo -e " ${CYAN}security${RESET}"
430
+ echo " $(declare_role security)"
431
+ echo ""
432
+ echo -e " ${CYAN}docs${RESET}"
433
+ echo " $(declare_role docs)"
434
+ echo ""
435
+ }
436
+
437
+ # ─── Help ───────────────────────────────────────────────────────────────────
438
+ show_help() {
439
+ echo ""
440
+ echo -e " ${CYAN}${BOLD}Shipwright Team Stages${RESET} ${DIM}v${VERSION}${RESET}"
441
+ echo -e " ${DIM}════════════════════════════════════════════════${RESET}"
442
+ echo ""
443
+ echo -e " ${BOLD}USAGE${RESET}"
444
+ echo -e " shipwright team-stages <command> [options]"
445
+ echo ""
446
+ echo -e " ${BOLD}COMMANDS${RESET}"
447
+ echo -e " ${CYAN}compose${RESET} <stage> [complexity] Generate team for a stage"
448
+ echo -e " ${CYAN}delegate${RESET} <stage> [complexity] Break stage into agent tasks"
449
+ echo -e " ${CYAN}status${RESET} [stage] Show team member status"
450
+ echo -e " ${CYAN}vote${RESET} <stage> Collect and tally review votes"
451
+ echo -e " ${CYAN}aggregate${RESET} <stage> Combine agent outputs into stage result"
452
+ echo -e " ${CYAN}roles${RESET} List available roles and descriptions"
453
+ echo -e " ${CYAN}help${RESET} Show this help message"
454
+ echo ""
455
+ echo -e " ${BOLD}EXAMPLES${RESET}"
456
+ echo -e " ${DIM}# Compose a team for the build stage${RESET}"
457
+ echo -e " shipwright team-stages compose build medium"
458
+ echo ""
459
+ echo -e " ${DIM}# Delegate build stage into parallel tasks${RESET}"
460
+ echo -e " shipwright team-stages delegate build medium"
461
+ echo ""
462
+ echo -e " ${DIM}# Show status of all active teams${RESET}"
463
+ echo -e " shipwright team-stages status"
464
+ echo ""
465
+ echo -e " ${DIM}# Tally votes from review team${RESET}"
466
+ echo -e " shipwright team-stages vote review"
467
+ echo ""
468
+ echo -e " ${DIM}# Combine results from all agents${RESET}"
469
+ echo -e " shipwright team-stages aggregate build"
470
+ echo ""
471
+ }
472
+
473
+ # ─── Main ───────────────────────────────────────────────────────────────────
474
+ main() {
475
+ local cmd="${1:-help}"
476
+ shift 2>/dev/null || true
477
+
478
+ case "$cmd" in
479
+ compose)
480
+ cmd_compose "$@"
481
+ ;;
482
+ delegate)
483
+ cmd_delegate "$@"
484
+ ;;
485
+ status)
486
+ cmd_status "$@"
487
+ ;;
488
+ vote)
489
+ cmd_vote "$@"
490
+ ;;
491
+ aggregate)
492
+ cmd_aggregate "$@"
493
+ ;;
494
+ roles)
495
+ cmd_roles
496
+ ;;
497
+ help|--help|-h)
498
+ show_help
499
+ ;;
500
+ *)
501
+ error "Unknown command: $cmd"
502
+ echo ""
503
+ show_help
504
+ exit 1
505
+ ;;
506
+ esac
507
+ }
508
+
509
+ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
510
+ main "$@"
511
+ fi
@@ -5,7 +5,7 @@
5
5
  # ║ Templates define reusable agent team configurations (roles, layout, ║
6
6
  # ║ focus areas) that shipwright session --template can use to scaffold teams. ║
7
7
  # ╚═══════════════════════════════════════════════════════════════════════════╝
8
- VERSION="1.10.0"
8
+ VERSION="2.0.0"
9
9
  set -euo pipefail
10
10
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
11
11