shipwright-cli 2.2.2 → 2.3.1

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 (151) hide show
  1. package/README.md +12 -11
  2. package/dashboard/public/index.html +224 -8
  3. package/dashboard/public/styles.css +1078 -4
  4. package/dashboard/server.ts +1100 -15
  5. package/dashboard/src/canvas/interactions.ts +74 -0
  6. package/dashboard/src/canvas/layout.ts +85 -0
  7. package/dashboard/src/canvas/overlays.ts +117 -0
  8. package/dashboard/src/canvas/particles.ts +105 -0
  9. package/dashboard/src/canvas/renderer.ts +191 -0
  10. package/dashboard/src/components/charts/bar.ts +54 -0
  11. package/dashboard/src/components/charts/donut.ts +25 -0
  12. package/dashboard/src/components/charts/pipeline-rail.ts +105 -0
  13. package/dashboard/src/components/charts/sparkline.ts +82 -0
  14. package/dashboard/src/components/header.ts +616 -0
  15. package/dashboard/src/components/modal.ts +413 -0
  16. package/dashboard/src/components/terminal.ts +144 -0
  17. package/dashboard/src/core/api.test.ts +362 -0
  18. package/dashboard/src/core/api.ts +381 -0
  19. package/dashboard/src/core/helpers.ts +118 -0
  20. package/dashboard/src/core/router.test.ts +266 -0
  21. package/dashboard/src/core/router.ts +190 -0
  22. package/dashboard/src/core/sse.ts +38 -0
  23. package/dashboard/src/core/state.test.ts +235 -0
  24. package/dashboard/src/core/state.ts +150 -0
  25. package/dashboard/src/core/ws.test.ts +216 -0
  26. package/dashboard/src/core/ws.ts +143 -0
  27. package/dashboard/src/design/icons.test.ts +105 -0
  28. package/dashboard/src/design/icons.ts +131 -0
  29. package/dashboard/src/design/tokens.test.ts +204 -0
  30. package/dashboard/src/design/tokens.ts +160 -0
  31. package/dashboard/src/main.ts +68 -0
  32. package/dashboard/src/types/api.ts +337 -0
  33. package/dashboard/src/views/activity.ts +185 -0
  34. package/dashboard/src/views/agent-cockpit.ts +236 -0
  35. package/dashboard/src/views/agents.ts +72 -0
  36. package/dashboard/src/views/fleet-map.ts +299 -0
  37. package/dashboard/src/views/insights.ts +298 -0
  38. package/dashboard/src/views/machines.ts +162 -0
  39. package/dashboard/src/views/metrics.ts +420 -0
  40. package/dashboard/src/views/overview.ts +409 -0
  41. package/dashboard/src/views/pipeline-theater.ts +219 -0
  42. package/dashboard/src/views/pipelines.ts +595 -0
  43. package/dashboard/src/views/team.ts +362 -0
  44. package/dashboard/src/views/timeline.ts +389 -0
  45. package/dashboard/tsconfig.json +21 -0
  46. package/dashboard/vitest.config.ts +27 -0
  47. package/docs/AGI-WHATS-NEXT.md +15 -15
  48. package/package.json +16 -2
  49. package/scripts/lib/helpers.sh +30 -0
  50. package/scripts/lib/pipeline-quality-checks.sh +1 -1
  51. package/scripts/lib/pipeline-stages.sh +59 -0
  52. package/scripts/sw +86 -167
  53. package/scripts/sw-activity.sh +1 -1
  54. package/scripts/sw-adaptive.sh +1 -1
  55. package/scripts/sw-adversarial.sh +1 -1
  56. package/scripts/sw-architecture-enforcer.sh +1 -1
  57. package/scripts/sw-auth.sh +14 -6
  58. package/scripts/sw-autonomous.sh +230 -13
  59. package/scripts/sw-changelog.sh +2 -2
  60. package/scripts/sw-checkpoint.sh +1 -1
  61. package/scripts/sw-ci.sh +1 -1
  62. package/scripts/sw-cleanup.sh +1 -1
  63. package/scripts/sw-code-review.sh +1 -1
  64. package/scripts/sw-connect.sh +1 -1
  65. package/scripts/sw-context.sh +1 -1
  66. package/scripts/sw-cost.sh +1 -1
  67. package/scripts/sw-daemon.sh +2 -2
  68. package/scripts/sw-dashboard.sh +1 -1
  69. package/scripts/sw-db.sh +1 -1
  70. package/scripts/sw-decompose.sh +1 -1
  71. package/scripts/sw-deps.sh +1 -1
  72. package/scripts/sw-developer-simulation.sh +1 -1
  73. package/scripts/sw-discovery.sh +1 -1
  74. package/scripts/sw-doc-fleet.sh +1 -1
  75. package/scripts/sw-docs-agent.sh +1 -1
  76. package/scripts/sw-docs.sh +1 -1
  77. package/scripts/sw-doctor.sh +8 -1
  78. package/scripts/sw-dora.sh +1 -1
  79. package/scripts/sw-durable.sh +1 -1
  80. package/scripts/sw-e2e-orchestrator.sh +1 -1
  81. package/scripts/sw-eventbus.sh +1 -1
  82. package/scripts/sw-feedback.sh +1 -1
  83. package/scripts/sw-fix.sh +6 -5
  84. package/scripts/sw-fleet-discover.sh +1 -1
  85. package/scripts/sw-fleet-viz.sh +1 -1
  86. package/scripts/sw-fleet.sh +1 -1
  87. package/scripts/sw-github-app.sh +5 -2
  88. package/scripts/sw-github-checks.sh +1 -1
  89. package/scripts/sw-github-deploy.sh +1 -1
  90. package/scripts/sw-github-graphql.sh +1 -1
  91. package/scripts/sw-guild.sh +1 -1
  92. package/scripts/sw-heartbeat.sh +1 -1
  93. package/scripts/sw-hygiene.sh +1 -1
  94. package/scripts/sw-incident.sh +1 -1
  95. package/scripts/sw-init.sh +112 -9
  96. package/scripts/sw-instrument.sh +6 -1
  97. package/scripts/sw-intelligence.sh +5 -1
  98. package/scripts/sw-jira.sh +1 -1
  99. package/scripts/sw-launchd.sh +1 -1
  100. package/scripts/sw-linear.sh +20 -9
  101. package/scripts/sw-logs.sh +1 -1
  102. package/scripts/sw-loop.sh +2 -1
  103. package/scripts/sw-memory.sh +10 -1
  104. package/scripts/sw-mission-control.sh +1 -1
  105. package/scripts/sw-model-router.sh +4 -1
  106. package/scripts/sw-otel.sh +1 -1
  107. package/scripts/sw-oversight.sh +1 -1
  108. package/scripts/sw-pipeline-composer.sh +3 -1
  109. package/scripts/sw-pipeline-vitals.sh +4 -6
  110. package/scripts/sw-pipeline.sh +4 -1
  111. package/scripts/sw-pm.sh +5 -2
  112. package/scripts/sw-pr-lifecycle.sh +1 -1
  113. package/scripts/sw-predictive.sh +4 -1
  114. package/scripts/sw-prep.sh +3 -2
  115. package/scripts/sw-ps.sh +1 -1
  116. package/scripts/sw-public-dashboard.sh +10 -4
  117. package/scripts/sw-quality.sh +1 -1
  118. package/scripts/sw-reaper.sh +1 -1
  119. package/scripts/sw-recruit.sh +16 -0
  120. package/scripts/sw-regression.sh +2 -1
  121. package/scripts/sw-release-manager.sh +1 -1
  122. package/scripts/sw-release.sh +7 -5
  123. package/scripts/sw-remote.sh +1 -1
  124. package/scripts/sw-replay.sh +1 -1
  125. package/scripts/sw-retro.sh +4 -1
  126. package/scripts/sw-scale.sh +4 -1
  127. package/scripts/sw-security-audit.sh +1 -1
  128. package/scripts/sw-self-optimize.sh +113 -1
  129. package/scripts/sw-session.sh +1 -1
  130. package/scripts/sw-setup.sh +1 -1
  131. package/scripts/sw-standup.sh +2 -1
  132. package/scripts/sw-status.sh +1 -1
  133. package/scripts/sw-strategic.sh +2 -1
  134. package/scripts/sw-stream.sh +1 -1
  135. package/scripts/sw-swarm.sh +6 -1
  136. package/scripts/sw-team-stages.sh +1 -1
  137. package/scripts/sw-templates.sh +1 -1
  138. package/scripts/sw-testgen.sh +3 -2
  139. package/scripts/sw-tmux-pipeline.sh +2 -1
  140. package/scripts/sw-tmux.sh +1 -1
  141. package/scripts/sw-trace.sh +1 -1
  142. package/scripts/sw-tracker-jira.sh +1 -0
  143. package/scripts/sw-tracker-linear.sh +1 -0
  144. package/scripts/sw-tracker.sh +1 -1
  145. package/scripts/sw-triage.sh +198 -11
  146. package/scripts/sw-upgrade.sh +1 -1
  147. package/scripts/sw-ux.sh +1 -1
  148. package/scripts/sw-webhook.sh +1 -1
  149. package/scripts/sw-widgets.sh +2 -2
  150. package/scripts/sw-worktree.sh +1 -1
  151. package/dashboard/public/app.js +0 -4422
@@ -1761,6 +1761,60 @@ stage_merge() {
1761
1761
  return 0
1762
1762
  fi
1763
1763
 
1764
+ # ── Oversight gate: merge block on verdict (diff + review criticals + goal) ──
1765
+ if [[ -x "$SCRIPT_DIR/sw-oversight.sh" ]] && [[ "${SKIP_GATES:-false}" != "true" ]]; then
1766
+ local merge_diff_file="${ARTIFACTS_DIR}/review-diff.patch"
1767
+ local merge_review_file="${ARTIFACTS_DIR}/review.md"
1768
+ if [[ ! -s "$merge_diff_file" ]]; then
1769
+ git diff "${BASE_BRANCH}...${GIT_BRANCH}" > "$merge_diff_file" 2>/dev/null || \
1770
+ git diff HEAD~5 > "$merge_diff_file" 2>/dev/null || true
1771
+ fi
1772
+ if [[ -s "$merge_diff_file" ]]; then
1773
+ local _merge_critical _merge_sec _merge_blocking _merge_reject
1774
+ _merge_critical=$(grep -ciE '\*\*\[?Critical\]?\*\*' "$merge_review_file" 2>/dev/null || echo "0")
1775
+ _merge_sec=$(grep -ciE '\*\*\[?Security\]?\*\*' "$merge_review_file" 2>/dev/null || echo "0")
1776
+ _merge_blocking=$((${_merge_critical:-0} + ${_merge_sec:-0}))
1777
+ [[ "$_merge_blocking" -gt 0 ]] && _merge_reject="Review found ${_merge_blocking} critical/security issue(s)"
1778
+ if ! bash "$SCRIPT_DIR/sw-oversight.sh" gate --diff "$merge_diff_file" --description "${GOAL:-Pipeline merge}" --reject-if "${_merge_reject:-}" >/dev/null 2>&1; then
1779
+ error "Oversight gate rejected — blocking merge"
1780
+ emit_event "merge.oversight_blocked" "issue=${ISSUE_NUMBER:-0}"
1781
+ log_stage "merge" "BLOCKED: oversight gate rejected"
1782
+ return 1
1783
+ fi
1784
+ fi
1785
+ fi
1786
+
1787
+ # ── Approval gates: block if merge requires approval and pending for this issue ──
1788
+ local ag_file="${HOME}/.shipwright/approval-gates.json"
1789
+ if [[ -f "$ag_file" ]] && [[ "${SKIP_GATES:-false}" != "true" ]]; then
1790
+ local ag_enabled ag_stages ag_pending_merge ag_issue_num
1791
+ ag_enabled=$(jq -r '.enabled // false' "$ag_file" 2>/dev/null || echo "false")
1792
+ ag_stages=$(jq -r '.stages // [] | if type == "array" then .[] else empty end' "$ag_file" 2>/dev/null || true)
1793
+ ag_issue_num=$(echo "${ISSUE_NUMBER:-0}" | awk '{print $1+0}')
1794
+ if [[ "$ag_enabled" == "true" ]] && echo "$ag_stages" | grep -qx "merge" 2>/dev/null; then
1795
+ local ha_file="${ARTIFACTS_DIR}/human-approval.txt"
1796
+ local ha_approved="false"
1797
+ if [[ -f "$ha_file" ]]; then
1798
+ ha_approved=$(jq -r --arg stage "merge" 'select(.stage == $stage) | .approved // false' "$ha_file" 2>/dev/null || echo "false")
1799
+ fi
1800
+ if [[ "$ha_approved" != "true" ]]; then
1801
+ ag_pending_merge=$(jq -r --argjson issue "$ag_issue_num" --arg stage "merge" \
1802
+ '[.pending[]? | select(.issue == $issue and .stage == $stage)] | length' "$ag_file" 2>/dev/null || echo "0")
1803
+ if [[ "${ag_pending_merge:-0}" -eq 0 ]]; then
1804
+ local req_at tmp_ag
1805
+ req_at=$(date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || true)
1806
+ tmp_ag=$(mktemp "${HOME}/.shipwright/approval-gates.json.XXXXXX" 2>/dev/null || mktemp)
1807
+ jq --argjson issue "$ag_issue_num" --arg stage "merge" --arg requested "${req_at}" \
1808
+ '.pending += [{"issue": $issue, "stage": $stage, "requested_at": $requested}]' "$ag_file" > "$tmp_ag" 2>/dev/null && mv "$tmp_ag" "$ag_file" || rm -f "$tmp_ag"
1809
+ fi
1810
+ info "Merge requires approval — awaiting human approval via dashboard"
1811
+ emit_event "merge.approval_pending" "issue=${ISSUE_NUMBER:-0}"
1812
+ log_stage "merge" "BLOCKED: approval gate pending"
1813
+ return 1
1814
+ fi
1815
+ fi
1816
+ fi
1817
+
1764
1818
  # ── Branch Protection Check ──
1765
1819
  if type gh_branch_protection &>/dev/null 2>&1 && [[ -n "$REPO_OWNER" && -n "$REPO_NAME" ]]; then
1766
1820
  local protection_json
@@ -2472,6 +2526,11 @@ _Created automatically by \`shipwright pipeline\` monitor stage_" 2>/dev/null ||
2472
2526
 
2473
2527
  success "Post-deploy monitoring clean (${total_errors} errors in ${duration_minutes}m)"
2474
2528
 
2529
+ # Proactive feedback collection: always collect deploy logs for trend analysis
2530
+ if [[ -f "$deploy_log_file" ]] && [[ -s "$deploy_log_file" ]] && [[ -x "$SCRIPT_DIR/sw-feedback.sh" ]]; then
2531
+ (cd "$PROJECT_ROOT" && ARTIFACTS_DIR="$ARTIFACTS_DIR" bash "$SCRIPT_DIR/sw-feedback.sh" collect "$deploy_log_file" 2>/dev/null) || true
2532
+ fi
2533
+
2475
2534
  if [[ -n "$ISSUE_NUMBER" ]]; then
2476
2535
  gh_comment_issue "$ISSUE_NUMBER" "✅ **Post-deploy monitoring passed** — ${duration_minutes}m, ${total_errors} errors" 2>/dev/null || true
2477
2536
  fi
package/scripts/sw CHANGED
@@ -5,7 +5,7 @@
5
5
  # ╚═══════════════════════════════════════════════════════════════════════════╝
6
6
  set -euo pipefail
7
7
 
8
- VERSION="2.2.2"
8
+ VERSION="2.3.1"
9
9
 
10
10
  # Resolve symlinks (required for npm global install where bin/ symlinks to node_modules/)
11
11
  SOURCE="${BASH_SOURCE[0]}"
@@ -27,6 +27,19 @@ DIM='\033[2m'
27
27
  BOLD='\033[1m'
28
28
  RESET='\033[0m'
29
29
 
30
+ # ─── Project identity (auto-detect from git remote) ───────────────────────
31
+ _sw_github_repo() {
32
+ local url; url="$(git remote get-url origin 2>/dev/null || echo "")"
33
+ if [[ "$url" =~ github\.com[:/]([^/]+)/([^/.]+) ]]; then
34
+ echo "${BASH_REMATCH[1]}/${BASH_REMATCH[2]}"
35
+ else
36
+ echo "${SHIPWRIGHT_GITHUB_REPO:-sethdford/shipwright}"
37
+ fi
38
+ }
39
+ _sw_github_owner() { local r="$(_sw_github_repo)"; echo "${r%%/*}"; }
40
+ _sw_docs_url() { echo "${SHIPWRIGHT_DOCS_URL:-https://$(_sw_github_owner).github.io/shipwright}"; }
41
+ _sw_github_url() { echo "https://github.com/$(_sw_github_repo)"; }
42
+
30
43
  # ─── Cross-platform compatibility ──────────────────────────────────────────
31
44
  # shellcheck source=lib/compat.sh
32
45
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
@@ -76,183 +89,85 @@ show_help() {
76
89
  echo ""
77
90
  echo -e "${BOLD}USAGE${RESET}"
78
91
  echo -e " ${CYAN}shipwright${RESET} <command> [options] ${DIM}(also: sw, cct)${RESET}"
79
- echo -e " ${CYAN}shipwright${RESET} <group> <subcommand> [options]"
80
92
  echo ""
81
- echo -e "${BOLD}COMMAND GROUPS${RESET} ${DIM}(new grouped syntax)${RESET}"
82
- echo -e " ${CYAN}agent${RESET} <subcmd> ${DIM}Agent management: recruit, swarm, standup, guild, oversight${RESET}"
83
- echo -e " ${CYAN}quality${RESET} <subcmd> ${DIM}Quality & review: code-review, security-audit, testgen, hygiene${RESET}"
84
- echo -e " ${CYAN}observe${RESET} <subcmd> ${DIM}Observability: vitals, dora, retro, stream, activity, replay${RESET}"
85
- echo -e " ${CYAN}release${RESET} <subcmd> ${DIM}Release & deploy: release, release-manager, changelog, deploy${RESET}"
86
- echo -e " ${CYAN}intel${RESET} <subcmd> ${DIM}Intelligence: predict, intelligence, strategic, optimize${RESET}"
87
- echo ""
88
- echo -e "${BOLD}CORE COMMANDS${RESET} ${DIM}(flat aliases for backwards compat)${RESET}"
89
- echo -e " ${CYAN}session${RESET} [name] Create a new tmux window for a Claude team"
90
- echo -e " ${CYAN}status${RESET} [--json] Show dashboard of running teams and agents"
91
- echo -e " ${CYAN}mission-control|mc${RESET} Terminal-based pipeline mission control (drill-down, team tree, orchestration)"
92
- echo -e " ${CYAN}ps${RESET} Show running agent processes and status"
93
- echo -e " ${CYAN}logs${RESET} [team] [opts] View and search agent pane logs"
94
- echo -e " ${CYAN}activity${RESET} [cmd] [opts] Live agent activity stream — watch Claude think"
95
- echo -e " ${CYAN}templates${RESET} [list|show] Manage team composition templates"
93
+ echo -e "${BOLD}GETTING STARTED${RESET}"
94
+ echo -e " ${CYAN}init${RESET} One-command setup tmux, CLI, templates, hooks"
95
+ echo -e " ${CYAN}setup${RESET} Guided interactive setup"
96
96
  echo -e " ${CYAN}doctor${RESET} Validate your setup and check for issues"
97
- echo -e " ${CYAN}cleanup${RESET} [--force] Clean up orphaned team sessions"
98
- echo -e " ${CYAN}reaper${RESET} [--watch] Automatic pane cleanup when agents exit"
99
- echo -e " ${CYAN}upgrade${RESET} [--apply] Check for updates from the repo (dry-run by default)"
100
- echo -e " ${CYAN}loop${RESET} \"goal\" [opts] ${BOLD}Continuous agent loop${RESET} — run until goal is achieved"
101
- echo -e " ${CYAN}pipeline${RESET} <cmd> ${BOLD}Full delivery pipeline${RESET} — idea to production"
102
- echo -e " ${CYAN}worktree${RESET} <cmd> Manage git worktrees for agent isolation"
103
- echo -e " ${CYAN}prep${RESET} [options] ${BOLD}Repo preparation${RESET} — generate .claude/ configs for agents"
104
- echo -e " ${CYAN}hygiene${RESET} <cmd> ${BOLD}Repo hygiene${RESET} — dead code, structure, deps, cleanup"
105
- echo -e " ${CYAN}daemon${RESET} <cmd> ${BOLD}Issue watcher${RESET} — auto-process GitHub issues"
106
- echo -e " ${CYAN}autonomous|auto${RESET} <cmd> ${BOLD}Autonomous loop${RESET} — AI-building-AI: analyze, create, build, learn"
107
- echo -e " ${CYAN}memory${RESET} <cmd> ${BOLD}Persistent memory${RESET} — learn from every pipeline run"
108
- echo -e " ${CYAN}guild${RESET} <cmd> ${BOLD}Knowledge guilds${RESET} — cross-team learning, shared patterns"
109
- echo -e " ${CYAN}instrument${RESET} <cmd> ${BOLD}Pipeline instrumentation${RESET} — record predicted vs actual metrics"
110
- echo -e " ${CYAN}cost${RESET} <cmd> ${BOLD}Cost intelligence${RESET} — track tokens, budgets, model routing"
111
- echo -e " ${CYAN}adaptive${RESET} <cmd> ${BOLD}Adaptive tuning${RESET} — data-driven pipeline defaults from historical runs"
112
- echo -e " ${CYAN}regression${RESET} <cmd> ${BOLD}Regression detection${RESET} — detect regressions after merge"
113
- echo -e " ${CYAN}incident${RESET} <cmd> ${BOLD}Incident commander${RESET} — detect failures, triage, remediate"
114
- echo -e " ${CYAN}db${RESET} <cmd> ${BOLD}SQLite persistence${RESET} — events, runs, developers, metrics"
115
- echo -e " ${CYAN}deps${RESET} <cmd> ${BOLD}Dependency updates${RESET} — scan, classify, test, merge Dependabot/Renovate PRs"
116
- echo -e " ${CYAN}fleet${RESET} <cmd> ${BOLD}Multi-repo fleet${RESET} — orchestrate daemons across repos"
117
- echo -e " ${CYAN}fleet-viz${RESET} <cmd> ${BOLD}Fleet visualization${RESET} — cross-repo insights and queue"
118
- echo -e " ${CYAN}fix${RESET} \"goal\" [opts] ${BOLD}Bulk fix${RESET} — apply a fix across multiple repos"
119
- echo -e " ${CYAN}dashboard${RESET} <cmd> ${BOLD}Fleet Command${RESET} — real-time WebSocket dashboard"
120
- echo -e " ${CYAN}public-dashboard${RESET} <cmd> ${BOLD}Public dashboard${RESET} — shareable pipeline progress (static HTML)"
121
- echo -e " ${CYAN}share${RESET} [...] ${BOLD}Share pipeline${RESET} — alias for ${DIM}public-dashboard share${RESET}"
122
- echo -e " ${CYAN}jira${RESET} <cmd> ${BOLD}Jira sync${RESET} — bidirectional issue sync with Jira"
123
- echo -e " ${CYAN}linear${RESET} <cmd> ${BOLD}Linear sync${RESET} — bidirectional issue sync with Linear"
124
- echo -e " ${CYAN}model${RESET} <cmd> ${BOLD}Model router${RESET} — intelligent model routing and cost optimization"
125
- echo -e " ${CYAN}tracker${RESET} <cmd> ${BOLD}Issue tracker${RESET} — configure Linear/Jira integration"
126
- echo -e " ${CYAN}heartbeat${RESET} <cmd> ${BOLD}Agent heartbeat${RESET} — write/check/list/clear heartbeats"
127
- echo -e " ${CYAN}standup${RESET} <cmd> ${BOLD}Daily standups${RESET} — gather status, summarize work, report blockers"
128
- echo -e " ${CYAN}checkpoint${RESET} <cmd> ${BOLD}Checkpoints${RESET} — save/restore agent state mid-stage"
129
- echo -e " ${CYAN}durable${RESET} <cmd> ${BOLD}Durable workflow${RESET} — event log, checkpoints, locks, exactly-once"
130
- echo -e " ${CYAN}webhook${RESET} <cmd> ${BOLD}GitHub webhooks${RESET} — instant issue processing, no polling"
131
- echo -e " ${CYAN}decompose${RESET} <cmd> ${BOLD}Issue decomposer${RESET} — analyze complexity, auto-create subtasks"
132
- echo -e " ${CYAN}discovery${RESET} <cmd> ${BOLD}Cross-pipeline learning${RESET} — real-time knowledge sharing"
133
- echo -e " ${CYAN}connect${RESET} <cmd> ${BOLD}Team connect${RESET} — sync local state to team dashboard"
134
- echo -e " ${CYAN}remote${RESET} <cmd> ${BOLD}Remote machines${RESET} — register and manage distributed workers"
135
- echo -e " ${CYAN}launchd${RESET} <cmd> ${BOLD}Process supervision${RESET} — auto-start daemon + dashboard on boot"
136
- echo -e " ${CYAN}auth${RESET} <cmd> ${BOLD}GitHub authentication${RESET} — OAuth login, token management, multi-user"
137
- echo -e " ${CYAN}docs${RESET} <cmd> ${BOLD}Documentation keeper${RESET} — auto-sync docs from source"
138
- echo -e " ${CYAN}changelog${RESET} <cmd> ${BOLD}Changelog engine${RESET} — auto-generate release notes and migration guides"
139
- echo -e " ${CYAN}docs-agent${RESET} <cmd> ${BOLD}Autonomous docs agent${RESET} — scan gaps, sync, coverage, API ref"
140
- echo -e " ${CYAN}doc-fleet${RESET} <cmd> ${BOLD}Documentation fleet${RESET} — 5 specialized agents: audit, refactor, enhance docs"
141
- echo -e " ${CYAN}release${RESET} <cmd> ${BOLD}Release automation${RESET} — bump versions, changelog, tags, releases"
142
- echo -e " ${CYAN}release-manager|rm${RESET} ${BOLD}Autonomous release pipeline${RESET} — readiness checks, RC flow, rollback"
143
- echo -e " ${CYAN}replay${RESET} <cmd> ${BOLD}Pipeline DVR${RESET} — list, show, narrative, diff, export, compare runs"
144
- echo -e " ${CYAN}scale${RESET} <cmd> ${BOLD}Dynamic team scaling${RESET} — scale agents up/down during pipeline"
145
- echo -e " ${CYAN}swarm${RESET} <cmd> ${BOLD}Agent swarm manager${RESET} — registry, spawning, scaling, health, topology"
146
- echo -e " ${CYAN}dora${RESET} <cmd> ${BOLD}DORA metrics${RESET} — deploy frequency, lead time, CFR, MTTR dashboard"
147
- echo -e " ${CYAN}retro${RESET} <cmd> ${BOLD}Sprint retrospective${RESET} — analyze sprints, identify improvements, create actions"
148
- echo -e " ${CYAN}tmux${RESET} <cmd> ${BOLD}tmux health${RESET} — doctor, install plugins, fix issues"
149
- echo -e " ${CYAN}vitals${RESET} ${BOLD}Pipeline vitals${RESET} — real-time health scoring and dashboard"
150
- echo -e " ${CYAN}stream${RESET} ${BOLD}Terminal streaming${RESET} — live agent output to dashboard or CLI"
151
- echo -e " ${CYAN}github${RESET} ${BOLD}GitHub context${RESET} — repo metadata, security, blame"
152
- echo -e " ${CYAN}checks${RESET} ${BOLD}GitHub checks${RESET} — CI check runs and status"
153
- echo -e " ${CYAN}ci${RESET} ${BOLD}CI/CD orchestration${RESET} — workflow generation, matrix, caching, secrets"
154
- echo -e " ${CYAN}deploys${RESET} ${BOLD}Deployments${RESET} — deployment history and environments"
155
- echo -e " ${CYAN}github-app${RESET} ${BOLD}GitHub App management${RESET} — JWT, tokens, webhooks, manifest"
156
- echo -e " ${CYAN}pr${RESET} ${BOLD}PR lifecycle${RESET} — auto-review, merge, cleanup, feedback"
157
- echo -e " ${CYAN}context${RESET} ${BOLD}Context engine${RESET} — gather context for pipeline stages"
158
- echo -e " ${CYAN}trace${RESET} ${BOLD}E2E traceability${RESET} — issue to commit to PR to deploy"
159
- echo -e " ${CYAN}widgets${RESET} ${BOLD}Status widgets${RESET} — embeddable badges, Slack messages, markdown"
160
- echo -e " ${CYAN}eventbus${RESET} ${BOLD}Event bus${RESET} — real-time inter-component communication"
161
- echo -e " ${CYAN}otel${RESET} ${BOLD}OpenTelemetry observability${RESET} — Prometheus metrics, traces, OTLP export"
162
- echo -e " ${CYAN}triage${RESET} ${BOLD}Issue labeling & prioritization${RESET} — auto-analyze, label, score, team sizing"
163
- echo -e " ${CYAN}quality${RESET} ${BOLD}Quality validation${RESET} — ruthless gates, adversarial audits, completion detection"
164
- echo -e " ${CYAN}oversight${RESET} ${BOLD}Quality oversight board${RESET} — multi-agent review council, voting, architecture governance"
165
- echo -e " ${CYAN}code-review${RESET} ${BOLD}Autonomous code review${RESET} — clean code, SOLID, architecture boundaries, complexity"
166
- echo -e " ${CYAN}pm${RESET} ${BOLD}Autonomous PM agent${RESET} — intelligent team sizing, composition, orchestration"
167
- echo -e " ${CYAN}strategic${RESET} ${BOLD}Strategic intelligence${RESET} — analyze strategy, metrics, create improvement issues"
168
- echo -e " ${CYAN}team-stages${RESET} ${BOLD}Multi-agent stage execution${RESET} — compose teams, delegate tasks, tally votes"
169
- echo -e " ${CYAN}ux${RESET} ${BOLD}Premium UX layer${RESET} — themes, animations, shortcuts, accessibility"
170
- echo -e " ${CYAN}recruit${RESET} ${BOLD}Agent recruitment${RESET} — skill matching, role definitions, performance evaluation"
171
- echo -e " ${CYAN}testgen${RESET} ${BOLD}Test generation${RESET} — analyze coverage, generate tests, maintain thresholds"
172
- echo -e " ${CYAN}security-audit|audit${RESET} ${BOLD}Security auditing${RESET} — secrets, licenses, vulnerabilities, SBOM, compliance"
173
- echo -e " ${CYAN}init${RESET} ${BOLD}Quick tmux setup${RESET} — one command, no prompts"
174
- echo -e " ${CYAN}setup${RESET} ${BOLD}Guided setup${RESET} — prerequisites, init, doctor, quick start"
175
- echo -e " ${CYAN}help${RESET} Show this help message"
176
- echo -e " ${CYAN}version${RESET} [show] Show version"
177
- echo -e " ${CYAN}version bump${RESET} <x.y.z> Bump version everywhere (scripts, README, package.json)"
178
- echo -e " ${CYAN}version check${RESET} Verify version consistency (CI / before release)"
179
- echo -e " ${CYAN}hello${RESET} Say hello world"
180
- echo ""
181
- echo -e "${BOLD}CONTINUOUS LOOP${RESET} ${DIM}(autonomous agent operation)${RESET}"
182
- echo -e " ${DIM}shipwright loop \"Build auth\" --test-cmd \"npm test\"${RESET}"
183
- echo -e " ${DIM}shipwright loop \"Fix bugs\" --max-iterations 10 --model sonnet${RESET}"
184
- echo -e " ${DIM}shipwright loop \"Build API\" --agents 3 --skip-permissions${RESET}"
185
- echo -e " ${DIM}shipwright loop --resume${RESET} # Resume interrupted loop"
186
97
  echo ""
187
- echo -e "${BOLD}DELIVERY PIPELINE${RESET} ${DIM}(idea to production)${RESET}"
188
- echo -e " ${DIM}shipwright pipeline start --goal \"Add auth\" --pipeline standard${RESET}"
189
- echo -e " ${DIM}shipwright pipeline start --issue 123 --skip-gates${RESET}"
190
- echo -e " ${DIM}shipwright pipeline resume${RESET} # Resume from last stage"
191
- echo -e " ${DIM}shipwright pipeline status${RESET} # Show progress dashboard"
98
+ echo -e "${BOLD}EVERYDAY COMMANDS${RESET}"
99
+ echo -e " ${CYAN}session${RESET} [name] Create a tmux window for a Claude agent team"
100
+ echo -e " ${CYAN}loop${RESET} \"goal\" [opts] Continuous agent loop — run until goal achieved"
101
+ echo -e " ${CYAN}pipeline${RESET} <cmd> Full delivery pipeline — issue to merged PR"
102
+ echo -e " ${CYAN}daemon${RESET} <cmd> Issue watcher — auto-process GitHub issues"
103
+ echo -e " ${CYAN}status${RESET} [--json] Show running teams and agents"
104
+ echo -e " ${CYAN}ps${RESET} Show agent processes"
105
+ echo -e " ${CYAN}logs${RESET} [team] [opts] View and search agent pane logs"
106
+ echo -e " ${CYAN}prep${RESET} [options] Generate .claude/ configs for any repo"
192
107
  echo ""
193
- echo -e "${BOLD}AUTONOMOUS DAEMON${RESET} ${DIM}(watch GitHub, auto-deliver)${RESET}"
194
- echo -e " ${DIM}shipwright daemon start${RESET} # Start issue watcher (foreground)"
195
- echo -e " ${DIM}shipwright daemon start --detach${RESET} # Start in background tmux session"
196
- echo -e " ${DIM}shipwright daemon status${RESET} # Show active pipelines and queue"
197
- echo -e " ${DIM}shipwright daemon metrics${RESET} # DORA/DX metrics dashboard"
198
- echo -e " ${DIM}shipwright daemon stop${RESET} # Graceful shutdown"
108
+ echo -e "${BOLD}COMMAND GROUPS${RESET} ${DIM}(use: shipwright <group> help)${RESET}"
109
+ echo -e " ${CYAN}agent${RESET} ${DIM}recruit, swarm, standup, guild, oversight${RESET}"
110
+ echo -e " ${CYAN}quality${RESET} ${DIM}code-review, security-audit, testgen, hygiene${RESET}"
111
+ echo -e " ${CYAN}observe${RESET} ${DIM}vitals, dora, retro, stream, activity, replay${RESET}"
112
+ echo -e " ${CYAN}release${RESET} ${DIM}release, release-manager, changelog, deploy${RESET}"
113
+ echo -e " ${CYAN}intel${RESET} ${DIM}predict, intelligence, strategic, optimize${RESET}"
199
114
  echo ""
200
- echo -e "${BOLD}MEMORY & COST${RESET} ${DIM}(intelligence layer)${RESET}"
201
- echo -e " ${DIM}shipwright memory show${RESET} # Show learned patterns for this repo"
202
- echo -e " ${DIM}shipwright memory search \"auth\"${RESET} # Search across all memories"
203
- echo -e " ${DIM}shipwright memory stats${RESET} # Memory usage and coverage"
204
- echo -e " ${DIM}shipwright cost show${RESET} # Token usage and spend overview"
205
- echo -e " ${DIM}shipwright cost budget set 10.00${RESET} # Set daily budget"
206
- echo -e " ${DIM}shipwright cost show --period 30 --by-stage${RESET} # Detailed cost report"
115
+ echo -e "${BOLD}OPERATIONS${RESET}"
116
+ echo -e " ${CYAN}fleet${RESET} <cmd> Multi-repo orchestration"
117
+ echo -e " ${CYAN}fix${RESET} \"goal\" [opts] Bulk fix across multiple repos"
118
+ echo -e " ${CYAN}dashboard${RESET} <cmd> Real-time WebSocket dashboard"
119
+ echo -e " ${CYAN}cost${RESET} <cmd> Token usage, budgets, model routing"
120
+ echo -e " ${CYAN}memory${RESET} <cmd> Persistent learning from pipeline runs"
207
121
  echo ""
208
- echo -e "${BOLD}FLEET OPERATIONS${RESET} ${DIM}(multi-repo management)${RESET}"
209
- echo -e " ${DIM}shipwright fleet start${RESET} # Start daemons for all configured repos"
210
- echo -e " ${DIM}shipwright fleet status${RESET} # Show fleet-wide status"
211
- echo -e " ${DIM}shipwright fleet metrics${RESET} # Cross-repo DORA metrics"
212
- echo -e " ${DIM}shipwright fix \"Bump deps\" --repos ~/api,~/web${RESET} # Bulk fix"
122
+ echo -e "${BOLD}INTEGRATIONS${RESET}"
123
+ echo -e " ${CYAN}github${RESET} Repo context, security, blame"
124
+ echo -e " ${CYAN}jira${RESET} <cmd> Bidirectional Jira sync"
125
+ echo -e " ${CYAN}linear${RESET} <cmd> Bidirectional Linear sync"
126
+ echo -e " ${CYAN}ci${RESET} <cmd> CI/CD workflow generation"
213
127
  echo ""
214
- echo -e "${BOLD}REPO PREPARATION${RESET} ${DIM}(prep repo for agents)${RESET}"
215
- echo -e " ${DIM}shipwright prep${RESET} # Analyze repo, generate .claude/ configs"
216
- echo -e " ${DIM}shipwright prep --check${RESET} # Audit existing prep quality"
217
- echo -e " ${DIM}shipwright prep --with-claude${RESET} # Deep analysis using Claude Code"
128
+ echo -e "${BOLD}MAINTENANCE${RESET}"
129
+ echo -e " ${CYAN}cleanup${RESET} [--force] Clean up orphaned sessions"
130
+ echo -e " ${CYAN}upgrade${RESET} [--apply] Check for and apply updates"
131
+ echo -e " ${CYAN}templates${RESET} [list|show] Manage team composition templates"
132
+ echo -e " ${CYAN}version${RESET} Show/bump/check version"
218
133
  echo ""
219
- echo -e "${BOLD}GITHUB INTEGRATION${RESET} ${DIM}(repo context, checks, deployments)${RESET}"
220
- echo -e " ${DIM}shipwright github context${RESET} # Show repo GitHub context"
221
- echo -e " ${DIM}shipwright github security${RESET} # Show security alerts"
222
- echo -e " ${DIM}shipwright github blame <path>${RESET} # Show file ownership"
223
- echo -e " ${DIM}shipwright checks list${RESET} # Show check runs"
224
- echo -e " ${DIM}shipwright deploys list${RESET} # Show deployment history"
225
- echo ""
226
- echo -e "${BOLD}TEST SUITES${RESET} ${DIM}(validate shipwright components)${RESET}"
227
- echo -e " ${DIM}shipwright daemon test${RESET} # Run daemon test suite"
228
- echo -e " ${DIM}shipwright prep test${RESET} # Run prep test suite"
229
- echo -e " ${DIM}shipwright pipeline test${RESET} # Run pipeline test suite"
230
- echo -e " ${DIM}shipwright e2e${RESET} <cmd> ${BOLD}Test orchestration${RESET} — smoke/integration/regression"
134
+ echo -e "${BOLD}QUICK START${RESET}"
135
+ echo -e " ${DIM}shipwright loop \"Build auth\" --test-cmd \"npm test\"${RESET}"
136
+ echo -e " ${DIM}shipwright pipeline start --issue 123${RESET}"
137
+ echo -e " ${DIM}shipwright daemon start --detach${RESET}"
231
138
  echo ""
232
- echo -e "${BOLD}AUDIT & QUALITY${RESET} ${DIM}(loop guardrails)${RESET}"
233
- echo -e " ${DIM}shipwright loop \"goal\" --audit${RESET} # Self-reflection each iteration"
234
- echo -e " ${DIM}shipwright loop \"goal\" --audit-agent${RESET} # Separate auditor reviews work"
235
- echo -e " ${DIM}shipwright loop \"goal\" --quality-gates${RESET} # Automated quality checks"
236
- echo -e " ${DIM}shipwright loop \"goal\" --definition-of-done dod.md${RESET} # Custom completion checklist"
139
+ echo -e "${BOLD}TMUX KEYBINDINGS${RESET}"
140
+ echo -e " ${PURPLE}prefix + T${RESET} Launch a team session"
141
+ echo -e " ${PURPLE}prefix + Ctrl-t${RESET} Show team dashboard"
237
142
  echo ""
238
- echo -e "${BOLD}TMUX KEYBINDINGS${RESET} ${DIM}(with the bundled tmux.conf)${RESET}"
239
- echo -e " ${PURPLE}prefix + T${RESET} Launch a team session (runs ${DIM}shipwright session${RESET})"
240
- echo -e " ${PURPLE}prefix + Ctrl-t${RESET} Show team dashboard (runs ${DIM}shipwright status${RESET})"
143
+ echo -e "${DIM}Run ${RESET}${CYAN}shipwright help --all${RESET}${DIM} for the full command list (80+ commands)${RESET}"
144
+ echo -e "${DIM}Docs: $(_sw_docs_url) | GitHub: $(_sw_github_url)${RESET}"
145
+ }
146
+
147
+ show_help_all() {
148
+ show_help
241
149
  echo ""
242
- echo -e "${BOLD}EXAMPLES${RESET}"
243
- echo -e " ${DIM}shipwright session refactor${RESET} # New window named 'claude-refactor'"
244
- echo -e " ${DIM}shipwright session${RESET} # New window with timestamp name"
245
- echo -e " ${DIM}shipwright status${RESET} # See all active teams"
246
- echo -e " ${DIM}shipwright ps${RESET} # Show agent processes"
247
- echo -e " ${DIM}shipwright logs myteam${RESET} # View logs for a team"
248
- echo -e " ${DIM}shipwright logs myteam --follow${RESET} # Tail agent logs"
249
- echo -e " ${DIM}shipwright doctor${RESET} # Check setup health"
250
- echo -e " ${DIM}shipwright cleanup${RESET} # Dry-run: show what would be cleaned"
251
- echo -e " ${DIM}shipwright cleanup --force${RESET} # Actually kill orphaned sessions"
252
- echo -e " ${DIM}shipwright upgrade${RESET} # Check what's changed since install"
253
- echo -e " ${DIM}shipwright upgrade --apply${RESET} # Apply available updates"
150
+ echo -e "${BOLD}ALL COMMANDS${RESET} ${DIM}(complete reference)${RESET}"
151
+ echo -e " ${CYAN}session${RESET} ${CYAN}status${RESET} ${CYAN}ps${RESET} ${CYAN}logs${RESET} ${CYAN}activity${RESET}"
152
+ echo -e " ${CYAN}loop${RESET} ${CYAN}pipeline${RESET} ${CYAN}daemon${RESET} ${CYAN}prep${RESET} ${CYAN}worktree${RESET}"
153
+ echo -e " ${CYAN}fleet${RESET} ${CYAN}fleet-viz${RESET} ${CYAN}fix${RESET} ${CYAN}dashboard${RESET} ${CYAN}public-dashboard${RESET}"
154
+ echo -e " ${CYAN}memory${RESET} ${CYAN}cost${RESET} ${CYAN}model${RESET} ${CYAN}adaptive${RESET} ${CYAN}regression${RESET}"
155
+ echo -e " ${CYAN}incident${RESET} ${CYAN}db${RESET} ${CYAN}deps${RESET} ${CYAN}instrument${RESET} ${CYAN}scale${RESET}"
156
+ echo -e " ${CYAN}swarm${RESET} ${CYAN}recruit${RESET} ${CYAN}standup${RESET} ${CYAN}guild${RESET} ${CYAN}oversight${RESET}"
157
+ echo -e " ${CYAN}code-review${RESET} ${CYAN}testgen${RESET} ${CYAN}security-audit${RESET} ${CYAN}hygiene${RESET} ${CYAN}quality${RESET}"
158
+ echo -e " ${CYAN}vitals${RESET} ${CYAN}dora${RESET} ${CYAN}retro${RESET} ${CYAN}stream${RESET} ${CYAN}replay${RESET}"
159
+ echo -e " ${CYAN}release${RESET} ${CYAN}release-manager${RESET} ${CYAN}changelog${RESET} ${CYAN}docs${RESET} ${CYAN}docs-agent${RESET}"
160
+ echo -e " ${CYAN}doc-fleet${RESET} ${CYAN}pr${RESET} ${CYAN}triage${RESET} ${CYAN}decompose${RESET} ${CYAN}discovery${RESET}"
161
+ echo -e " ${CYAN}github${RESET} ${CYAN}github-app${RESET} ${CYAN}checks${RESET} ${CYAN}ci${RESET} ${CYAN}deploys${RESET}"
162
+ echo -e " ${CYAN}auth${RESET} ${CYAN}webhook${RESET} ${CYAN}eventbus${RESET} ${CYAN}otel${RESET} ${CYAN}context${RESET}"
163
+ echo -e " ${CYAN}trace${RESET} ${CYAN}widgets${RESET} ${CYAN}connect${RESET} ${CYAN}remote${RESET} ${CYAN}launchd${RESET}"
164
+ echo -e " ${CYAN}jira${RESET} ${CYAN}linear${RESET} ${CYAN}tracker${RESET} ${CYAN}heartbeat${RESET} ${CYAN}checkpoint${RESET}"
165
+ echo -e " ${CYAN}durable${RESET} ${CYAN}autonomous${RESET} ${CYAN}pm${RESET} ${CYAN}strategic${RESET} ${CYAN}team-stages${RESET}"
166
+ echo -e " ${CYAN}ux${RESET} ${CYAN}mission-control${RESET} ${CYAN}tmux${RESET} ${CYAN}reaper${RESET} ${CYAN}e2e${RESET}"
167
+ echo -e " ${CYAN}init${RESET} ${CYAN}setup${RESET} ${CYAN}doctor${RESET} ${CYAN}cleanup${RESET} ${CYAN}upgrade${RESET}"
168
+ echo -e " ${CYAN}templates${RESET} ${CYAN}version${RESET}"
254
169
  echo ""
255
- echo -e "${DIM}Docs: https://sethdford.github.io/shipwright | GitHub: https://github.com/sethdford/shipwright${RESET}"
170
+ echo -e "${DIM}Run ${RESET}${CYAN}shipwright <command> --help${RESET}${DIM} for details on any command${RESET}"
256
171
  }
257
172
 
258
173
  # ─── Command Group Routers ───────────────────────────────────────────────────
@@ -646,7 +561,11 @@ main() {
646
561
  exec "$SCRIPT_DIR/sw-security-audit.sh" "$@"
647
562
  ;;
648
563
  help|--help|-h)
649
- show_help
564
+ if [[ "${1:-}" == "--all" || "${1:-}" == "-a" ]]; then
565
+ show_help_all
566
+ else
567
+ show_help
568
+ fi
650
569
  ;;
651
570
  version)
652
571
  case "${1:-show}" in
@@ -6,7 +6,7 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.2.2"
9
+ VERSION="2.3.1"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
12
12
  # ─── Cross-platform compatibility ──────────────────────────────────────────
@@ -6,7 +6,7 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.2.2"
9
+ VERSION="2.3.1"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
12
12
  # ─── Cross-platform compatibility ──────────────────────────────────────────
@@ -6,7 +6,7 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.2.2"
9
+ VERSION="2.3.1"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
@@ -6,7 +6,7 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.2.2"
9
+ VERSION="2.3.1"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
@@ -6,7 +6,7 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.2.2"
9
+ VERSION="2.3.1"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
@@ -348,11 +348,19 @@ cmd_login() {
348
348
  info "Starting GitHub OAuth device flow..."
349
349
 
350
350
  # Initiate device flow
351
- local device_flow_vars
352
- device_flow_vars=$(initiate_device_flow) || return 1
353
-
354
- # Source the variables
355
- eval "$device_flow_vars"
351
+ local device_flow_response
352
+ device_flow_response=$(initiate_device_flow) || return 1
353
+
354
+ # Extract variables without eval (initiate_device_flow outputs key=value pairs)
355
+ local DEVICE_CODE USER_CODE INTERVAL EXPIRES_IN
356
+ while IFS='=' read -r key value; do
357
+ case "$key" in
358
+ DEVICE_CODE) DEVICE_CODE="$value" ;;
359
+ USER_CODE) USER_CODE="$value" ;;
360
+ INTERVAL) INTERVAL="$value" ;;
361
+ EXPIRES_IN) EXPIRES_IN="$value" ;;
362
+ esac
363
+ done <<< "$device_flow_response"
356
364
 
357
365
  info "Visit: ${CYAN}${DEVICE_FLOW_ENDPOINT}${RESET}"
358
366
  info "Enter code: ${BOLD}${USER_CODE}${RESET}"