shipwright-cli 3.2.0 → 3.3.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 (279) hide show
  1. package/.claude/agents/code-reviewer.md +2 -0
  2. package/.claude/agents/devops-engineer.md +2 -0
  3. package/.claude/agents/doc-fleet-agent.md +2 -0
  4. package/.claude/agents/pipeline-agent.md +2 -0
  5. package/.claude/agents/shell-script-specialist.md +2 -0
  6. package/.claude/agents/test-specialist.md +2 -0
  7. package/.claude/hooks/agent-crash-capture.sh +32 -0
  8. package/.claude/hooks/post-tool-use.sh +3 -2
  9. package/.claude/hooks/pre-tool-use.sh +35 -3
  10. package/README.md +4 -4
  11. package/claude-code/hooks/config-change.sh +18 -0
  12. package/claude-code/hooks/instructions-reloaded.sh +7 -0
  13. package/claude-code/hooks/worktree-create.sh +25 -0
  14. package/claude-code/hooks/worktree-remove.sh +20 -0
  15. package/config/code-constitution.json +130 -0
  16. package/dashboard/middleware/auth.ts +134 -0
  17. package/dashboard/middleware/constants.ts +21 -0
  18. package/dashboard/public/index.html +2 -6
  19. package/dashboard/public/styles.css +100 -97
  20. package/dashboard/routes/auth.ts +38 -0
  21. package/dashboard/server.ts +66 -25
  22. package/dashboard/services/config.ts +26 -0
  23. package/dashboard/services/db.ts +118 -0
  24. package/dashboard/src/canvas/pixel-agent.ts +298 -0
  25. package/dashboard/src/canvas/pixel-sprites.ts +440 -0
  26. package/dashboard/src/canvas/shipyard-effects.ts +367 -0
  27. package/dashboard/src/canvas/shipyard-scene.ts +616 -0
  28. package/dashboard/src/canvas/submarine-layout.ts +267 -0
  29. package/dashboard/src/components/header.ts +8 -7
  30. package/dashboard/src/core/router.ts +1 -0
  31. package/dashboard/src/design/submarine-theme.ts +253 -0
  32. package/dashboard/src/main.ts +2 -0
  33. package/dashboard/src/types/api.ts +2 -1
  34. package/dashboard/src/views/activity.ts +2 -1
  35. package/dashboard/src/views/shipyard.ts +39 -0
  36. package/dashboard/types/index.ts +166 -0
  37. package/docs/plans/2026-02-28-compound-audit-and-shipyard-design.md +186 -0
  38. package/docs/plans/2026-02-28-skipper-shipwright-implementation-plan.md +1182 -0
  39. package/docs/plans/2026-02-28-skipper-shipwright-integration-design.md +531 -0
  40. package/docs/plans/2026-03-01-ai-powered-skill-injection-design.md +298 -0
  41. package/docs/plans/2026-03-01-ai-powered-skill-injection-plan.md +1109 -0
  42. package/docs/plans/2026-03-01-capabilities-cleanup-plan.md +658 -0
  43. package/docs/plans/2026-03-01-clean-architecture-plan.md +924 -0
  44. package/docs/plans/2026-03-01-compound-audit-cascade-design.md +191 -0
  45. package/docs/plans/2026-03-01-compound-audit-cascade-plan.md +921 -0
  46. package/docs/plans/2026-03-01-deep-integration-plan.md +851 -0
  47. package/docs/plans/2026-03-01-pipeline-audit-trail-design.md +145 -0
  48. package/docs/plans/2026-03-01-pipeline-audit-trail-plan.md +770 -0
  49. package/docs/plans/2026-03-01-refined-depths-brand-design.md +382 -0
  50. package/docs/plans/2026-03-01-refined-depths-implementation.md +599 -0
  51. package/docs/plans/2026-03-01-skipper-kernel-integration-design.md +203 -0
  52. package/docs/plans/2026-03-01-unified-platform-design.md +272 -0
  53. package/docs/plans/2026-03-07-claude-code-feature-integration-design.md +189 -0
  54. package/docs/plans/2026-03-07-claude-code-feature-integration-plan.md +1165 -0
  55. package/docs/research/BACKLOG_QUICK_REFERENCE.md +352 -0
  56. package/docs/research/CUTTING_EDGE_RESEARCH_2026.md +546 -0
  57. package/docs/research/RESEARCH_INDEX.md +439 -0
  58. package/docs/research/RESEARCH_SOURCES.md +440 -0
  59. package/docs/research/RESEARCH_SUMMARY.txt +275 -0
  60. package/docs/superpowers/specs/2026-03-10-pipeline-quality-revolution-design.md +341 -0
  61. package/package.json +2 -2
  62. package/scripts/lib/adaptive-model.sh +427 -0
  63. package/scripts/lib/adaptive-timeout.sh +316 -0
  64. package/scripts/lib/audit-trail.sh +309 -0
  65. package/scripts/lib/auto-recovery.sh +471 -0
  66. package/scripts/lib/bandit-selector.sh +431 -0
  67. package/scripts/lib/bootstrap.sh +104 -2
  68. package/scripts/lib/causal-graph.sh +455 -0
  69. package/scripts/lib/compat.sh +126 -0
  70. package/scripts/lib/compound-audit.sh +337 -0
  71. package/scripts/lib/constitutional.sh +454 -0
  72. package/scripts/lib/context-budget.sh +359 -0
  73. package/scripts/lib/convergence.sh +594 -0
  74. package/scripts/lib/cost-optimizer.sh +634 -0
  75. package/scripts/lib/daemon-adaptive.sh +10 -0
  76. package/scripts/lib/daemon-dispatch.sh +106 -17
  77. package/scripts/lib/daemon-failure.sh +34 -4
  78. package/scripts/lib/daemon-patrol.sh +23 -2
  79. package/scripts/lib/daemon-poll-github.sh +361 -0
  80. package/scripts/lib/daemon-poll-health.sh +299 -0
  81. package/scripts/lib/daemon-poll.sh +27 -611
  82. package/scripts/lib/daemon-state.sh +112 -66
  83. package/scripts/lib/daemon-triage.sh +10 -0
  84. package/scripts/lib/dod-scorecard.sh +442 -0
  85. package/scripts/lib/error-actionability.sh +300 -0
  86. package/scripts/lib/formal-spec.sh +461 -0
  87. package/scripts/lib/helpers.sh +177 -4
  88. package/scripts/lib/intent-analysis.sh +409 -0
  89. package/scripts/lib/loop-convergence.sh +350 -0
  90. package/scripts/lib/loop-iteration.sh +682 -0
  91. package/scripts/lib/loop-progress.sh +48 -0
  92. package/scripts/lib/loop-restart.sh +185 -0
  93. package/scripts/lib/memory-effectiveness.sh +506 -0
  94. package/scripts/lib/mutation-executor.sh +352 -0
  95. package/scripts/lib/outcome-feedback.sh +521 -0
  96. package/scripts/lib/pipeline-cli.sh +336 -0
  97. package/scripts/lib/pipeline-commands.sh +1216 -0
  98. package/scripts/lib/pipeline-detection.sh +100 -2
  99. package/scripts/lib/pipeline-execution.sh +897 -0
  100. package/scripts/lib/pipeline-github.sh +28 -3
  101. package/scripts/lib/pipeline-intelligence-compound.sh +431 -0
  102. package/scripts/lib/pipeline-intelligence-scoring.sh +407 -0
  103. package/scripts/lib/pipeline-intelligence-skip.sh +181 -0
  104. package/scripts/lib/pipeline-intelligence.sh +100 -1136
  105. package/scripts/lib/pipeline-quality-bash-compat.sh +182 -0
  106. package/scripts/lib/pipeline-quality-checks.sh +17 -715
  107. package/scripts/lib/pipeline-quality-gates.sh +563 -0
  108. package/scripts/lib/pipeline-stages-build.sh +730 -0
  109. package/scripts/lib/pipeline-stages-delivery.sh +965 -0
  110. package/scripts/lib/pipeline-stages-intake.sh +1133 -0
  111. package/scripts/lib/pipeline-stages-monitor.sh +407 -0
  112. package/scripts/lib/pipeline-stages-review.sh +1022 -0
  113. package/scripts/lib/pipeline-stages.sh +59 -2929
  114. package/scripts/lib/pipeline-state.sh +36 -5
  115. package/scripts/lib/pipeline-util.sh +487 -0
  116. package/scripts/lib/policy-learner.sh +438 -0
  117. package/scripts/lib/process-reward.sh +493 -0
  118. package/scripts/lib/project-detect.sh +649 -0
  119. package/scripts/lib/quality-profile.sh +334 -0
  120. package/scripts/lib/recruit-commands.sh +885 -0
  121. package/scripts/lib/recruit-learning.sh +739 -0
  122. package/scripts/lib/recruit-roles.sh +648 -0
  123. package/scripts/lib/reward-aggregator.sh +458 -0
  124. package/scripts/lib/rl-optimizer.sh +362 -0
  125. package/scripts/lib/root-cause.sh +427 -0
  126. package/scripts/lib/scope-enforcement.sh +445 -0
  127. package/scripts/lib/session-restart.sh +493 -0
  128. package/scripts/lib/skill-memory.sh +300 -0
  129. package/scripts/lib/skill-registry.sh +775 -0
  130. package/scripts/lib/spec-driven.sh +476 -0
  131. package/scripts/lib/test-helpers.sh +18 -7
  132. package/scripts/lib/test-holdout.sh +429 -0
  133. package/scripts/lib/test-optimizer.sh +511 -0
  134. package/scripts/shipwright-file-suggest.sh +45 -0
  135. package/scripts/skills/adversarial-quality.md +61 -0
  136. package/scripts/skills/api-design.md +44 -0
  137. package/scripts/skills/architecture-design.md +50 -0
  138. package/scripts/skills/brainstorming.md +43 -0
  139. package/scripts/skills/data-pipeline.md +44 -0
  140. package/scripts/skills/deploy-safety.md +64 -0
  141. package/scripts/skills/documentation.md +38 -0
  142. package/scripts/skills/frontend-design.md +45 -0
  143. package/scripts/skills/generated/.gitkeep +0 -0
  144. package/scripts/skills/generated/_refinements/.gitkeep +0 -0
  145. package/scripts/skills/generated/_refinements/adversarial-quality.patch.md +3 -0
  146. package/scripts/skills/generated/_refinements/architecture-design.patch.md +3 -0
  147. package/scripts/skills/generated/_refinements/brainstorming.patch.md +3 -0
  148. package/scripts/skills/generated/cli-version-management.md +29 -0
  149. package/scripts/skills/generated/collection-system-validation.md +99 -0
  150. package/scripts/skills/generated/large-scale-c-refactoring-coordination.md +97 -0
  151. package/scripts/skills/generated/pattern-matching-similarity-scoring.md +195 -0
  152. package/scripts/skills/generated/test-parallelization-detection.md +65 -0
  153. package/scripts/skills/observability.md +79 -0
  154. package/scripts/skills/performance.md +48 -0
  155. package/scripts/skills/pr-quality.md +49 -0
  156. package/scripts/skills/product-thinking.md +43 -0
  157. package/scripts/skills/security-audit.md +49 -0
  158. package/scripts/skills/systematic-debugging.md +40 -0
  159. package/scripts/skills/testing-strategy.md +47 -0
  160. package/scripts/skills/two-stage-review.md +52 -0
  161. package/scripts/skills/validation-thoroughness.md +55 -0
  162. package/scripts/sw +9 -3
  163. package/scripts/sw-activity.sh +9 -2
  164. package/scripts/sw-adaptive.sh +2 -1
  165. package/scripts/sw-adversarial.sh +2 -1
  166. package/scripts/sw-architecture-enforcer.sh +3 -1
  167. package/scripts/sw-auth.sh +12 -2
  168. package/scripts/sw-autonomous.sh +5 -1
  169. package/scripts/sw-changelog.sh +4 -1
  170. package/scripts/sw-checkpoint.sh +2 -1
  171. package/scripts/sw-ci.sh +5 -1
  172. package/scripts/sw-cleanup.sh +4 -26
  173. package/scripts/sw-code-review.sh +10 -4
  174. package/scripts/sw-connect.sh +2 -1
  175. package/scripts/sw-context.sh +2 -1
  176. package/scripts/sw-cost.sh +48 -3
  177. package/scripts/sw-daemon.sh +66 -9
  178. package/scripts/sw-dashboard.sh +3 -1
  179. package/scripts/sw-db.sh +59 -16
  180. package/scripts/sw-decide.sh +8 -2
  181. package/scripts/sw-decompose.sh +360 -17
  182. package/scripts/sw-deps.sh +4 -1
  183. package/scripts/sw-developer-simulation.sh +4 -1
  184. package/scripts/sw-discovery.sh +325 -2
  185. package/scripts/sw-doc-fleet.sh +4 -1
  186. package/scripts/sw-docs-agent.sh +3 -1
  187. package/scripts/sw-docs.sh +2 -1
  188. package/scripts/sw-doctor.sh +453 -2
  189. package/scripts/sw-dora.sh +4 -1
  190. package/scripts/sw-durable.sh +4 -3
  191. package/scripts/sw-e2e-orchestrator.sh +17 -16
  192. package/scripts/sw-eventbus.sh +7 -1
  193. package/scripts/sw-evidence.sh +364 -12
  194. package/scripts/sw-feedback.sh +550 -9
  195. package/scripts/sw-fix.sh +20 -1
  196. package/scripts/sw-fleet-discover.sh +6 -2
  197. package/scripts/sw-fleet-viz.sh +4 -1
  198. package/scripts/sw-fleet.sh +5 -1
  199. package/scripts/sw-github-app.sh +16 -3
  200. package/scripts/sw-github-checks.sh +3 -2
  201. package/scripts/sw-github-deploy.sh +3 -2
  202. package/scripts/sw-github-graphql.sh +18 -7
  203. package/scripts/sw-guild.sh +5 -1
  204. package/scripts/sw-heartbeat.sh +5 -30
  205. package/scripts/sw-hello.sh +67 -0
  206. package/scripts/sw-hygiene.sh +6 -1
  207. package/scripts/sw-incident.sh +265 -1
  208. package/scripts/sw-init.sh +18 -2
  209. package/scripts/sw-instrument.sh +10 -2
  210. package/scripts/sw-intelligence.sh +42 -6
  211. package/scripts/sw-jira.sh +5 -1
  212. package/scripts/sw-launchd.sh +2 -1
  213. package/scripts/sw-linear.sh +4 -1
  214. package/scripts/sw-logs.sh +4 -1
  215. package/scripts/sw-loop.sh +432 -1128
  216. package/scripts/sw-memory.sh +356 -2
  217. package/scripts/sw-mission-control.sh +6 -1
  218. package/scripts/sw-model-router.sh +481 -26
  219. package/scripts/sw-otel.sh +13 -4
  220. package/scripts/sw-oversight.sh +14 -5
  221. package/scripts/sw-patrol-meta.sh +334 -0
  222. package/scripts/sw-pipeline-composer.sh +5 -1
  223. package/scripts/sw-pipeline-vitals.sh +2 -1
  224. package/scripts/sw-pipeline.sh +53 -2664
  225. package/scripts/sw-pm.sh +12 -5
  226. package/scripts/sw-pr-lifecycle.sh +2 -1
  227. package/scripts/sw-predictive.sh +7 -1
  228. package/scripts/sw-prep.sh +185 -2
  229. package/scripts/sw-ps.sh +5 -25
  230. package/scripts/sw-public-dashboard.sh +15 -3
  231. package/scripts/sw-quality.sh +2 -1
  232. package/scripts/sw-reaper.sh +8 -25
  233. package/scripts/sw-recruit.sh +156 -2303
  234. package/scripts/sw-regression.sh +19 -12
  235. package/scripts/sw-release-manager.sh +3 -1
  236. package/scripts/sw-release.sh +4 -1
  237. package/scripts/sw-remote.sh +3 -1
  238. package/scripts/sw-replay.sh +7 -1
  239. package/scripts/sw-retro.sh +158 -1
  240. package/scripts/sw-review-rerun.sh +3 -1
  241. package/scripts/sw-scale.sh +10 -3
  242. package/scripts/sw-security-audit.sh +6 -1
  243. package/scripts/sw-self-optimize.sh +6 -3
  244. package/scripts/sw-session.sh +9 -3
  245. package/scripts/sw-setup.sh +3 -1
  246. package/scripts/sw-stall-detector.sh +406 -0
  247. package/scripts/sw-standup.sh +15 -7
  248. package/scripts/sw-status.sh +3 -1
  249. package/scripts/sw-strategic.sh +4 -1
  250. package/scripts/sw-stream.sh +7 -1
  251. package/scripts/sw-swarm.sh +18 -6
  252. package/scripts/sw-team-stages.sh +13 -6
  253. package/scripts/sw-templates.sh +5 -29
  254. package/scripts/sw-testgen.sh +7 -1
  255. package/scripts/sw-tmux-pipeline.sh +4 -1
  256. package/scripts/sw-tmux-role-color.sh +2 -0
  257. package/scripts/sw-tmux-status.sh +1 -1
  258. package/scripts/sw-tmux.sh +3 -1
  259. package/scripts/sw-trace.sh +3 -1
  260. package/scripts/sw-tracker-github.sh +3 -0
  261. package/scripts/sw-tracker-jira.sh +3 -0
  262. package/scripts/sw-tracker-linear.sh +3 -0
  263. package/scripts/sw-tracker.sh +3 -1
  264. package/scripts/sw-triage.sh +2 -1
  265. package/scripts/sw-upgrade.sh +3 -1
  266. package/scripts/sw-ux.sh +5 -2
  267. package/scripts/sw-webhook.sh +3 -1
  268. package/scripts/sw-widgets.sh +3 -1
  269. package/scripts/sw-worktree.sh +15 -3
  270. package/scripts/test-skill-injection.sh +1233 -0
  271. package/templates/pipelines/autonomous.json +27 -3
  272. package/templates/pipelines/cost-aware.json +34 -8
  273. package/templates/pipelines/deployed.json +12 -0
  274. package/templates/pipelines/enterprise.json +12 -0
  275. package/templates/pipelines/fast.json +6 -0
  276. package/templates/pipelines/full.json +27 -3
  277. package/templates/pipelines/hotfix.json +6 -0
  278. package/templates/pipelines/standard.json +12 -0
  279. package/templates/pipelines/tdd.json +12 -0
package/scripts/sw-fix.sh CHANGED
@@ -6,7 +6,8 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="3.2.0"
9
+ # shellcheck disable=SC2034
10
+ VERSION="3.3.0"
10
11
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
12
 
12
13
  # ─── Cross-platform compatibility ──────────────────────────────────────────
@@ -43,6 +44,8 @@ REPOS=()
43
44
  REPOS_FROM=""
44
45
  TEMPLATE="fast"
45
46
  MODEL=""
47
+ EFFORT_LEVEL=""
48
+ FALLBACK_MODEL=""
46
49
  MAX_PARALLEL=3
47
50
  DRY_RUN=false
48
51
  BRANCH_PREFIX="fix/"
@@ -60,6 +63,8 @@ show_help() {
60
63
  echo -e " ${DIM}--repos-from file${RESET} Read repo paths from file (one per line)"
61
64
  echo -e " ${DIM}--pipeline template${RESET} Pipeline template (default: fast)"
62
65
  echo -e " ${DIM}--model model${RESET} Model to use (default: auto)"
66
+ echo -e " ${DIM}--effort level${RESET} Effort level: low, medium, high"
67
+ echo -e " ${DIM}--fallback-model model${RESET} Fallback model on rate limits (default: sonnet)"
63
68
  echo -e " ${DIM}--max-parallel N${RESET} Max concurrent pipelines (default: 3)"
64
69
  echo -e " ${DIM}--branch-prefix prefix${RESET} Branch name prefix (default: \"fix/\")"
65
70
  echo -e " ${DIM}--dry-run${RESET} Show what would happen without executing"
@@ -94,6 +99,14 @@ parse_args() {
94
99
  MODEL="$2"
95
100
  shift 2
96
101
  ;;
102
+ --effort)
103
+ EFFORT_LEVEL="$2"
104
+ shift 2
105
+ ;;
106
+ --fallback-model)
107
+ FALLBACK_MODEL="$2"
108
+ shift 2
109
+ ;;
97
110
  --max-parallel)
98
111
  MAX_PARALLEL="$2"
99
112
  shift 2
@@ -222,6 +235,7 @@ fix_start() {
222
235
  local sanitized
223
236
  sanitized=$(sanitize_branch "$GOAL")
224
237
  local branch_name="${BRANCH_PREFIX}${sanitized}"
238
+ # shellcheck disable=SC2155
225
239
  local session_id="fix-$(date +%s)"
226
240
  local state_file="$FIX_DIR/${session_id}.json"
227
241
  local log_dir="$FIX_DIR/${session_id}-logs"
@@ -242,6 +256,8 @@ fix_start() {
242
256
  echo -e " ${BOLD}Branch:${RESET} $branch_name"
243
257
  echo -e " ${BOLD}Parallel:${RESET} $MAX_PARALLEL"
244
258
  [[ -n "$MODEL" ]] && echo -e " ${BOLD}Model:${RESET} $MODEL"
259
+ [[ -n "$EFFORT_LEVEL" ]] && echo -e " ${BOLD}Effort:${RESET} $EFFORT_LEVEL"
260
+ [[ -n "$FALLBACK_MODEL" ]] && echo -e " ${BOLD}Fallback:${RESET} $FALLBACK_MODEL"
245
261
  echo ""
246
262
 
247
263
  # ─── Dry Run ────────────────────────────────────────────────────────────
@@ -289,6 +305,7 @@ fix_start() {
289
305
 
290
306
  # ─── Parallel Execution ─────────────────────────────────────────────────
291
307
  local pids=()
308
+ # shellcheck disable=SC2034
292
309
  local pid_to_idx=()
293
310
  local idx=0
294
311
 
@@ -335,6 +352,8 @@ fix_start() {
335
352
  # Build pipeline command
336
353
  local cmd=("$SCRIPT_DIR/sw-pipeline.sh" start --goal "$GOAL" --pipeline "$TEMPLATE" --skip-gates)
337
354
  [[ -n "$MODEL" ]] && cmd+=(--model "$MODEL")
355
+ [[ -n "$EFFORT_LEVEL" ]] && cmd+=(--effort "$EFFORT_LEVEL")
356
+ [[ -n "$FALLBACK_MODEL" ]] && cmd+=(--fallback-model "$FALLBACK_MODEL")
338
357
 
339
358
  # Run pipeline
340
359
  "${cmd[@]}"
@@ -6,8 +6,9 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="3.2.0"
9
+ VERSION="3.3.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ # shellcheck disable=SC2034
11
12
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
13
 
13
14
  # ─── Cross-platform compatibility ──────────────────────────────────────────
@@ -29,6 +30,7 @@ fi
29
30
  if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
30
31
  emit_event() {
31
32
  local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
33
+ # shellcheck disable=SC2155
32
34
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
33
35
  while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
34
36
  echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
@@ -118,6 +120,7 @@ discover_repos() {
118
120
 
119
121
  # Paginate through org repos
120
122
  local page=1
123
+ # shellcheck disable=SC2034
121
124
  local per_page=100
122
125
  local total_found=0
123
126
  local has_more=true
@@ -150,6 +153,7 @@ discover_repos() {
150
153
 
151
154
  name=$(echo "$repo_data" | jq -r '.name // ""')
152
155
  full_name=$(echo "$repo_data" | jq -r '.full_name // ""')
156
+ # shellcheck disable=SC2034
153
157
  url=$(echo "$repo_data" | jq -r '.url // ""')
154
158
  archived=$(echo "$repo_data" | jq -r '.archived // false')
155
159
  disabled=$(echo "$repo_data" | jq -r '.disabled // false')
@@ -376,7 +380,7 @@ merge_into_config() {
376
380
 
377
381
  # Merge into config
378
382
  local tmp_config="${config_path}.tmp.$$"
379
- local updated_config=$(cat "$config_path")
383
+ local updated_config; updated_config=$(cat "$config_path")
380
384
 
381
385
  for repo_path in "${repos_to_add[@]}"; do
382
386
  updated_config=$(echo "$updated_config" | jq \
@@ -6,8 +6,9 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="3.2.0"
9
+ VERSION="3.3.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ # shellcheck disable=SC2034
11
12
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
13
 
13
14
  # ─── Cross-platform compatibility ──────────────────────────────────────────
@@ -31,6 +32,7 @@ fi
31
32
  if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
32
33
  emit_event() {
33
34
  local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
35
+ # shellcheck disable=SC2155
34
36
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
35
37
  while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
36
38
  echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
@@ -156,6 +158,7 @@ show_workers() {
156
158
  echo ""
157
159
 
158
160
  # Get per-repo worker counts
161
+ # shellcheck disable=SC2034
159
162
  local total_workers_allocated=0
160
163
  jq -r '.active_jobs[]? | .repo' "$FLEET_STATE" 2>/dev/null | sort -u | while read -r repo; do
161
164
  local worker_count job_count utilization
@@ -6,8 +6,9 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="3.2.0"
9
+ VERSION="3.3.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ # shellcheck disable=SC2034
11
12
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
13
 
13
14
  # ─── Cross-platform compatibility ──────────────────────────────────────────
@@ -29,6 +30,7 @@ fi
29
30
  if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
30
31
  emit_event() {
31
32
  local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
33
+ # shellcheck disable=SC2155
32
34
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
33
35
  while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
34
36
  echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
@@ -357,6 +359,7 @@ fleet_rebalance() {
357
359
  # When intelligence weighting is active, use weighted demand
358
360
  local allocated_total=0
359
361
  local alloc_list=()
362
+ # shellcheck disable=SC2034
360
363
  local use_weight="$total_weight"
361
364
  local effective_total="$total_demand"
362
365
  if [[ "$intel_weighting" == "true" && "$total_weight" -gt 0 ]]; then
@@ -768,6 +771,7 @@ fleet_start() {
768
771
  default_max_parallel=$(jq -r '.defaults.max_parallel // 2' "$config_file")
769
772
  default_model=$(jq -r '.defaults.model // "opus"' "$config_file")
770
773
  local shared_events
774
+ # shellcheck disable=SC2034
771
775
  shared_events=$(jq -r '.shared_events // true' "$config_file")
772
776
 
773
777
  mkdir -p "$FLEET_DIR"
@@ -6,8 +6,10 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="3.2.0"
9
+ # shellcheck disable=SC2034
10
+ VERSION="3.3.0"
10
11
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ # shellcheck disable=SC2034
11
13
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
14
 
13
15
  # ─── Cross-platform compatibility ──────────────────────────────────────────
@@ -29,6 +31,7 @@ fi
29
31
  if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
30
32
  emit_event() {
31
33
  local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
34
+ # shellcheck disable=SC2155
32
35
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
33
36
  while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
34
37
  echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
@@ -80,7 +83,9 @@ cmd_setup() {
80
83
  # Create config atomically
81
84
  local tmp_config
82
85
  tmp_config=$(mktemp)
86
+ # shellcheck disable=SC2064
83
87
  trap "rm -f '$tmp_config'" RETURN
88
+ # shellcheck disable=SC2046
84
89
  jq -n \
85
90
  --arg app_id "$app_id" \
86
91
  --arg key_path "$key_path" \
@@ -185,13 +190,21 @@ _cache_token() {
185
190
 
186
191
  local tmp_tokens
187
192
  tmp_tokens=$(mktemp)
193
+ # shellcheck disable=SC2064
188
194
  trap "rm -f '$tmp_tokens'" RETURN
189
195
 
196
+ local new_entry
197
+ new_entry=$(jq -n \
198
+ --argjson installation_id "$installation_id" \
199
+ --arg token "$token" \
200
+ --arg expires_at "$expires_at" \
201
+ '{installation_id: $installation_id, token: $token, expires_at: $expires_at}')
202
+
190
203
  if [[ -f "$TOKENS_FILE" ]]; then
191
- jq ".tokens += [{\"installation_id\":$installation_id,\"token\":\"$token\",\"expires_at\":\"$expires_at\"}]" \
204
+ jq --argjson entry "$new_entry" '.tokens += [$entry]' \
192
205
  "$TOKENS_FILE" > "$tmp_tokens"
193
206
  else
194
- jq -n ".tokens = [{\"installation_id\":$installation_id,\"token\":\"$token\",\"expires_at\":\"$expires_at\"}]" \
207
+ jq -n --argjson entry "$new_entry" '.tokens = [$entry]' \
195
208
  > "$tmp_tokens"
196
209
  fi
197
210
 
@@ -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="3.2.0"
9
+ VERSION="3.3.0"
10
10
  SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
11
11
  REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
12
12
 
@@ -29,6 +29,7 @@ fi
29
29
  if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
30
30
  emit_event() {
31
31
  local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
32
+ # shellcheck disable=SC2155
32
33
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
33
34
  while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
34
35
  echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
@@ -142,7 +143,7 @@ gh_checks_create_run() {
142
143
  if [[ "$result" -ne 0 ]]; then
143
144
  warn "Failed to create check run '${name}' (API returned ${result})" >&2
144
145
  echo ""
145
- return 0
146
+ return 1
146
147
  fi
147
148
 
148
149
  local run_id
@@ -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="3.2.0"
9
+ VERSION="3.3.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
@@ -29,6 +29,7 @@ fi
29
29
  if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
30
30
  emit_event() {
31
31
  local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
32
+ # shellcheck disable=SC2155
32
33
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
33
34
  while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
34
35
  echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
@@ -95,7 +96,7 @@ gh_deploy_create() {
95
96
  if [[ "$result" -ne 0 ]]; then
96
97
  warn "Failed to create deployment for ref '${ref}' to '${environment}' (API returned ${result})" >&2
97
98
  echo ""
98
- return 0
99
+ return 1
99
100
  fi
100
101
 
101
102
  local deploy_id
@@ -6,8 +6,10 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="3.2.0"
9
+ # shellcheck disable=SC2034
10
+ VERSION="3.3.0"
10
11
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ # shellcheck disable=SC2034
11
13
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
14
 
13
15
  # ─── Cross-platform compatibility ──────────────────────────────────────────
@@ -29,12 +31,14 @@ fi
29
31
  if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
30
32
  emit_event() {
31
33
  local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
32
- local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
34
+ local payload
35
+ payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
33
36
  while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
34
37
  echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
35
38
  }
36
39
  fi
37
40
  # ─── Structured Event Log ──────────────────────────────────────────────────
41
+ # shellcheck disable=SC2034
38
42
  EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
39
43
 
40
44
  # ─── Cache Configuration ───────────────────────────────────────────────────
@@ -116,7 +120,9 @@ _gh_cache_stats() {
116
120
  _gh_cache_init
117
121
  local count=0
118
122
  local total_size=0
123
+ # shellcheck disable=SC2034
119
124
  local oldest=""
125
+ # shellcheck disable=SC2034
120
126
  local newest=""
121
127
 
122
128
  for f in "$GH_CACHE_DIR"/*.json; do
@@ -257,7 +263,8 @@ gh_file_change_frequency() {
257
263
  since=$(date -u -d "${days} days ago" +"%Y-%m-%dT%H:%M:%SZ")
258
264
  fi
259
265
 
260
- local cache_key="freq_${owner}_${repo}_$(echo "$path" | tr '/' '_')_${days}d"
266
+ local cache_key
267
+ cache_key="freq_${owner}_${repo}_$(echo "$path" | tr '/' '_')_${days}d"
261
268
 
262
269
  local query='query($owner: String!, $repo: String!, $since: GitTimestamp!) {
263
270
  repository(owner: $owner, name: $repo) {
@@ -301,7 +308,8 @@ gh_blame_data() {
301
308
  return 0
302
309
  fi
303
310
 
304
- local cache_key="blame_${owner}_${repo}_$(echo "$path" | tr '/' '_')"
311
+ local cache_key
312
+ cache_key="blame_${owner}_${repo}_$(echo "$path" | tr '/' '_')"
305
313
  local cached
306
314
  cached=$(_gh_cache_get "$cache_key" "14400" 2>/dev/null) && {
307
315
  emit_event "github.cache_hit" "key=$cache_key"
@@ -386,7 +394,8 @@ gh_similar_issues() {
386
394
  fi
387
395
 
388
396
  local search_query="repo:${owner}/${repo} is:issue is:closed ${search_text}"
389
- local cache_key="similar_${owner}_${repo}_$(echo "$search_text" | tr ' /' '__' | head -c 50)"
397
+ local cache_key
398
+ cache_key="similar_${owner}_${repo}_$(echo "$search_text" | tr ' /' '__' | head -c 50)"
390
399
 
391
400
  local query='query($q: String!, $limit: Int!) {
392
401
  search(query: $q, type: ISSUE, first: $limit) {
@@ -436,7 +445,8 @@ gh_commit_history() {
436
445
  return 0
437
446
  fi
438
447
 
439
- local cache_key="history_${owner}_${repo}_$(echo "$path" | tr '/' '_')_${limit}"
448
+ local cache_key
449
+ cache_key="history_${owner}_${repo}_$(echo "$path" | tr '/' '_')_${limit}"
440
450
  local cached
441
451
  cached=$(_gh_cache_get "$cache_key" "3600" 2>/dev/null) && {
442
452
  emit_event "github.cache_hit" "key=$cache_key"
@@ -701,7 +711,8 @@ gh_actions_runs() {
701
711
  return 0
702
712
  fi
703
713
 
704
- local cache_key="actions_${owner}_${repo}_$(echo "$workflow" | tr '/' '_')_${limit}"
714
+ local cache_key
715
+ cache_key="actions_${owner}_${repo}_$(echo "$workflow" | tr '/' '_')_${limit}"
705
716
  local cached
706
717
  cached=$(_gh_cache_get "$cache_key" "900" 2>/dev/null) && {
707
718
  emit_event "github.cache_hit" "key=$cache_key"
@@ -6,7 +6,8 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="3.2.0"
9
+ # shellcheck disable=SC2034
10
+ VERSION="3.3.0"
10
11
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
12
 
12
13
  # ─── Cross-platform compatibility ──────────────────────────────────────────
@@ -28,6 +29,7 @@ fi
28
29
  if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
29
30
  emit_event() {
30
31
  local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
32
+ # shellcheck disable=SC2155
31
33
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
32
34
  while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
33
35
  echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
@@ -39,6 +41,7 @@ GUILD_CONFIG="${GUILD_ROOT}/config.json"
39
41
  GUILD_DATA="${GUILD_ROOT}/guilds.json"
40
42
 
41
43
  # ─── Event Logging ────────────────────────────────────────────────────────
44
+ # shellcheck disable=SC2034
42
45
  EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
43
46
 
44
47
  # ─── Initialization ────────────────────────────────────────────────────────
@@ -311,6 +314,7 @@ cmd_learn() {
311
314
  # ─── Inject Knowledge into Prompt ────────────────────────────────────────
312
315
  cmd_inject() {
313
316
  local task_type="${1:-}"
317
+ # shellcheck disable=SC2034
314
318
  local context="${2:-}"
315
319
 
316
320
  if [[ -z "$task_type" ]]; then
@@ -4,39 +4,14 @@
4
4
  # ║ Write · Check · List · Clear heartbeats for autonomous agents ║
5
5
  # ╚═══════════════════════════════════════════════════════════════════════════╝
6
6
  set -euo pipefail
7
- trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
7
 
9
- VERSION="3.2.0"
10
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
-
12
- # ─── Cross-platform compatibility ──────────────────────────────────────────
13
- # shellcheck source=lib/compat.sh
14
- [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
15
-
16
- # Canonical helpers (colors, output, events)
17
- # shellcheck source=lib/helpers.sh
18
- [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
8
+ VERSION="3.3.0"
9
+ # shellcheck source=lib/bootstrap.sh
10
+ source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/bootstrap.sh"
19
11
 
20
12
  # SQLite persistence (DB as primary read path)
21
13
  # shellcheck source=sw-db.sh
22
14
  [[ -f "$SCRIPT_DIR/sw-db.sh" ]] && source "$SCRIPT_DIR/sw-db.sh"
23
- # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
24
- [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
25
- [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
26
- [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
27
- [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
28
- if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
29
- now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
30
- now_epoch() { date +%s; }
31
- fi
32
- if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
33
- emit_event() {
34
- local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
35
- local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
36
- while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
37
- echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
38
- }
39
- fi
40
15
  # ─── Constants ──────────────────────────────────────────────────────────────
41
16
  HEARTBEAT_DIR="$HOME/.shipwright/heartbeats"
42
17
 
@@ -136,7 +111,7 @@ cmd_write() {
136
111
  ensure_dir
137
112
 
138
113
  local tmp_file
139
- tmp_file="$(mktemp "${HEARTBEAT_DIR}/.tmp.XXXXXX")"
114
+ tmp_file="$(mktemp "${HEARTBEAT_DIR}/.tmp.XXXXXX")" || { error "mktemp failed for heartbeat"; return 1; }
140
115
 
141
116
  # Build JSON with jq for proper escaping
142
117
  jq -n \
@@ -160,7 +135,7 @@ cmd_write() {
160
135
  }' > "$tmp_file" || { rm -f "$tmp_file"; return 1; }
161
136
 
162
137
  # Atomic write
163
- mv "$tmp_file" "${HEARTBEAT_DIR}/${job_id}.json"
138
+ mv "$tmp_file" "${HEARTBEAT_DIR}/${job_id}.json" || { rm -f "$tmp_file"; return 1; }
164
139
 
165
140
  # Dual-write to DB when available
166
141
  if type db_record_heartbeat >/dev/null 2>&1 && db_available 2>/dev/null; then
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env bash
2
+ # ╔═══════════════════════════════════════════════════════════════════════════╗
3
+ # ║ sw-hello.sh — Hello World Command ║
4
+ # ║ ║
5
+ # ║ A simple hello world command that demonstrates the CLI structure. ║
6
+ # ╚═══════════════════════════════════════════════════════════════════════════╝
7
+ # shellcheck disable=SC2034
8
+ VERSION="3.3.0"
9
+ set -euo pipefail
10
+ trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
11
+
12
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+
14
+ # Canonical helpers (colors, output, events)
15
+ # shellcheck source=lib/helpers.sh
16
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
17
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
18
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
19
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
20
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
21
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
22
+
23
+ # ─── Help text ──────────────────────────────────────────────────────────────
24
+ show_help() {
25
+ cat <<EOF
26
+ USAGE
27
+ shipwright hello [OPTIONS]
28
+
29
+ DESCRIPTION
30
+ A simple hello world command.
31
+
32
+ OPTIONS
33
+ --help, -h Show this help text
34
+ --version, -v Show version
35
+
36
+ EXAMPLES
37
+ shipwright hello Print "hello world"
38
+ shipwright hello --help Show this help text
39
+
40
+ EOF
41
+ }
42
+
43
+ # ─── Main ───────────────────────────────────────────────────────────────────
44
+ main() {
45
+ case "${1:-}" in
46
+ --help|-h)
47
+ show_help
48
+ exit 0
49
+ ;;
50
+ --version|-v)
51
+ echo "$VERSION"
52
+ exit 0
53
+ ;;
54
+ "")
55
+ # No arguments: output hello world
56
+ echo "hello world"
57
+ exit 0
58
+ ;;
59
+ *)
60
+ error "Unknown option: $1"
61
+ show_help
62
+ exit 1
63
+ ;;
64
+ esac
65
+ }
66
+
67
+ main "$@"
@@ -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="3.2.0"
9
+ VERSION="3.3.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
@@ -27,6 +27,7 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
27
27
  emit_event() {
28
28
  local event_type="$1"; shift
29
29
  mkdir -p "${HOME}/.shipwright"
30
+ # shellcheck disable=SC2155
30
31
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
31
32
  while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
32
33
  echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
@@ -320,6 +321,7 @@ list_stale_branches() {
320
321
 
321
322
  # Find branches not updated in 30 days
322
323
  local old_branches
324
+ # shellcheck disable=SC2046
323
325
  old_branches=$(git branch -r --format="%(refname:short)%09%(committerdate:short)" 2>/dev/null | \
324
326
  awk -v cutoff=$(date -d "30 days ago" +%Y-%m-%d 2>/dev/null || date -v-30d +%Y-%m-%d) \
325
327
  '$2 < cutoff {print $1}' || true)
@@ -342,10 +344,12 @@ list_stale_branches() {
342
344
  analyze_size() {
343
345
  info "Analyzing repository size..."
344
346
 
347
+ # shellcheck disable=SC2034
345
348
  local total_size=0
346
349
 
347
350
  # Find large files
348
351
  info "Largest files:"
352
+ # shellcheck disable=SC2038
349
353
  find "$REPO_DIR" -type f ! -path '*/.git/*' ! -path '*/node_modules/*' 2>/dev/null | \
350
354
  xargs ls -lh 2>/dev/null | \
351
355
  awk '{print $5, $9}' | \
@@ -404,6 +408,7 @@ scan_platform_refactor() {
404
408
  grep -rnE "hardcoded|Hardcoded|Fallback:|fallback:|TODO|FIXME|HACK|KLUDGE" "$scripts_dir" --include="*.sh" 2>/dev/null > "$findings_raw" || true
405
409
  while IFS= read -r line; do
406
410
  [[ -z "$line" ]] && continue
411
+ # shellcheck disable=SC2318
407
412
  local f="${line%%:*}" rest="${line#*:}" ln="${rest%%:*}"
408
413
  ln="${ln:-0}"
409
414
  printf '{"file":"%s","line":%s}\n' "${f#$REPO_DIR/}" "$ln"