shipwright-cli 1.7.1 → 1.9.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 (105) hide show
  1. package/.claude/agents/code-reviewer.md +90 -0
  2. package/.claude/agents/devops-engineer.md +142 -0
  3. package/.claude/agents/pipeline-agent.md +80 -0
  4. package/.claude/agents/shell-script-specialist.md +150 -0
  5. package/.claude/agents/test-specialist.md +196 -0
  6. package/.claude/hooks/post-tool-use.sh +38 -0
  7. package/.claude/hooks/pre-tool-use.sh +25 -0
  8. package/.claude/hooks/session-started.sh +37 -0
  9. package/README.md +212 -814
  10. package/claude-code/CLAUDE.md.shipwright +54 -0
  11. package/claude-code/hooks/notify-idle.sh +2 -2
  12. package/claude-code/hooks/session-start.sh +24 -0
  13. package/claude-code/hooks/task-completed.sh +6 -2
  14. package/claude-code/settings.json.template +12 -0
  15. package/dashboard/public/app.js +4422 -0
  16. package/dashboard/public/index.html +816 -0
  17. package/dashboard/public/styles.css +4755 -0
  18. package/dashboard/server.ts +4315 -0
  19. package/docs/KNOWN-ISSUES.md +18 -10
  20. package/docs/TIPS.md +38 -26
  21. package/docs/patterns/README.md +33 -23
  22. package/package.json +9 -5
  23. package/scripts/adapters/iterm2-adapter.sh +1 -1
  24. package/scripts/adapters/tmux-adapter.sh +52 -23
  25. package/scripts/adapters/wezterm-adapter.sh +26 -14
  26. package/scripts/lib/compat.sh +200 -0
  27. package/scripts/lib/helpers.sh +72 -0
  28. package/scripts/postinstall.mjs +72 -13
  29. package/scripts/{cct → sw} +109 -21
  30. package/scripts/sw-adversarial.sh +274 -0
  31. package/scripts/sw-architecture-enforcer.sh +330 -0
  32. package/scripts/sw-checkpoint.sh +390 -0
  33. package/scripts/{cct-cleanup.sh → sw-cleanup.sh} +3 -1
  34. package/scripts/sw-connect.sh +619 -0
  35. package/scripts/{cct-cost.sh → sw-cost.sh} +368 -34
  36. package/scripts/{cct-daemon.sh → sw-daemon.sh} +2217 -204
  37. package/scripts/sw-dashboard.sh +477 -0
  38. package/scripts/sw-developer-simulation.sh +252 -0
  39. package/scripts/sw-docs.sh +635 -0
  40. package/scripts/sw-doctor.sh +907 -0
  41. package/scripts/{cct-fix.sh → sw-fix.sh} +10 -6
  42. package/scripts/{cct-fleet.sh → sw-fleet.sh} +498 -22
  43. package/scripts/sw-github-checks.sh +521 -0
  44. package/scripts/sw-github-deploy.sh +533 -0
  45. package/scripts/sw-github-graphql.sh +972 -0
  46. package/scripts/sw-heartbeat.sh +293 -0
  47. package/scripts/{cct-init.sh → sw-init.sh} +144 -11
  48. package/scripts/sw-intelligence.sh +1196 -0
  49. package/scripts/sw-jira.sh +643 -0
  50. package/scripts/sw-launchd.sh +364 -0
  51. package/scripts/sw-linear.sh +648 -0
  52. package/scripts/{cct-logs.sh → sw-logs.sh} +72 -2
  53. package/scripts/{cct-loop.sh → sw-loop.sh} +534 -44
  54. package/scripts/{cct-memory.sh → sw-memory.sh} +321 -38
  55. package/scripts/sw-patrol-meta.sh +417 -0
  56. package/scripts/sw-pipeline-composer.sh +455 -0
  57. package/scripts/{cct-pipeline.sh → sw-pipeline.sh} +2319 -178
  58. package/scripts/sw-predictive.sh +820 -0
  59. package/scripts/{cct-prep.sh → sw-prep.sh} +339 -49
  60. package/scripts/{cct-ps.sh → sw-ps.sh} +6 -4
  61. package/scripts/{cct-reaper.sh → sw-reaper.sh} +6 -4
  62. package/scripts/sw-remote.sh +687 -0
  63. package/scripts/sw-self-optimize.sh +947 -0
  64. package/scripts/sw-session.sh +519 -0
  65. package/scripts/sw-setup.sh +234 -0
  66. package/scripts/sw-status.sh +605 -0
  67. package/scripts/{cct-templates.sh → sw-templates.sh} +9 -4
  68. package/scripts/sw-tmux.sh +591 -0
  69. package/scripts/sw-tracker-jira.sh +277 -0
  70. package/scripts/sw-tracker-linear.sh +292 -0
  71. package/scripts/sw-tracker.sh +409 -0
  72. package/scripts/{cct-upgrade.sh → sw-upgrade.sh} +103 -46
  73. package/scripts/{cct-worktree.sh → sw-worktree.sh} +3 -0
  74. package/templates/pipelines/autonomous.json +27 -5
  75. package/templates/pipelines/full.json +12 -0
  76. package/templates/pipelines/standard.json +12 -0
  77. package/tmux/{claude-teams-overlay.conf → shipwright-overlay.conf} +27 -9
  78. package/tmux/templates/accessibility.json +34 -0
  79. package/tmux/templates/api-design.json +35 -0
  80. package/tmux/templates/architecture.json +1 -0
  81. package/tmux/templates/bug-fix.json +9 -0
  82. package/tmux/templates/code-review.json +1 -0
  83. package/tmux/templates/compliance.json +36 -0
  84. package/tmux/templates/data-pipeline.json +36 -0
  85. package/tmux/templates/debt-paydown.json +34 -0
  86. package/tmux/templates/devops.json +1 -0
  87. package/tmux/templates/documentation.json +1 -0
  88. package/tmux/templates/exploration.json +1 -0
  89. package/tmux/templates/feature-dev.json +1 -0
  90. package/tmux/templates/full-stack.json +8 -0
  91. package/tmux/templates/i18n.json +34 -0
  92. package/tmux/templates/incident-response.json +36 -0
  93. package/tmux/templates/migration.json +1 -0
  94. package/tmux/templates/observability.json +35 -0
  95. package/tmux/templates/onboarding.json +33 -0
  96. package/tmux/templates/performance.json +35 -0
  97. package/tmux/templates/refactor.json +1 -0
  98. package/tmux/templates/release.json +35 -0
  99. package/tmux/templates/security-audit.json +8 -0
  100. package/tmux/templates/spike.json +34 -0
  101. package/tmux/templates/testing.json +1 -0
  102. package/tmux/tmux.conf +98 -9
  103. package/scripts/cct-doctor.sh +0 -414
  104. package/scripts/cct-session.sh +0 -284
  105. package/scripts/cct-status.sh +0 -169
@@ -0,0 +1,364 @@
1
+ #!/usr/bin/env bash
2
+ # ╔═══════════════════════════════════════════════════════════════════════════╗
3
+ # ║ shipwright launchd — Process supervision on macOS ║
4
+ # ║ Auto-start daemon + dashboard on boot via launchd ║
5
+ # ╚═══════════════════════════════════════════════════════════════════════════╝
6
+ set -euo pipefail
7
+ trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
+
9
+ VERSION="1.9.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
+ # ─── Constants ──────────────────────────────────────────────────────────────
35
+ PLIST_DIR="$HOME/Library/LaunchAgents"
36
+ DAEMON_PLIST="$PLIST_DIR/com.shipwright.daemon.plist"
37
+ DASHBOARD_PLIST="$PLIST_DIR/com.shipwright.dashboard.plist"
38
+ CONNECT_PLIST="$PLIST_DIR/com.shipwright.connect.plist"
39
+ LOG_DIR="$HOME/.shipwright/logs"
40
+ TEAM_CONFIG="$HOME/.shipwright/team-config.json"
41
+
42
+ # ─── Check macOS ─────────────────────────────────────────────────────────────
43
+ check_macos() {
44
+ if [[ "$OSTYPE" != "darwin"* ]]; then
45
+ error "launchd is only available on macOS"
46
+ exit 1
47
+ fi
48
+ }
49
+
50
+ # ─── Help ───────────────────────────────────────────────────────────────────
51
+ show_help() {
52
+ echo ""
53
+ echo -e "${CYAN}${BOLD} Shipwright launchd${RESET} ${DIM}v${VERSION}${RESET}"
54
+ echo -e "${DIM} ════════════════════════════════════════════${RESET}"
55
+ echo ""
56
+ echo -e " ${BOLD}USAGE${RESET}"
57
+ echo -e " shipwright launchd <command>"
58
+ echo ""
59
+ echo -e " ${BOLD}COMMANDS${RESET}"
60
+ echo -e " ${CYAN}install${RESET} Install launchd agents for daemon and dashboard (auto-start on boot)"
61
+ echo -e " ${CYAN}uninstall${RESET} Remove launchd agents and stop services"
62
+ echo -e " ${CYAN}status${RESET} Check status of launchd services"
63
+ echo -e " ${CYAN}help${RESET} Show this help message"
64
+ echo ""
65
+ echo -e " ${BOLD}EXAMPLES${RESET}"
66
+ echo -e " ${DIM}shipwright launchd install${RESET} # Set up auto-start on boot"
67
+ echo -e " ${DIM}shipwright launchd status${RESET} # Check if services are running"
68
+ echo -e " ${DIM}shipwright launchd uninstall${RESET} # Remove auto-start"
69
+ echo ""
70
+ }
71
+
72
+ # ─── Install Command ─────────────────────────────────────────────────────────
73
+ cmd_install() {
74
+ check_macos
75
+
76
+ info "Installing launchd agents..."
77
+
78
+ # Create directories
79
+ mkdir -p "$PLIST_DIR" "$LOG_DIR"
80
+
81
+ # Find the full path to the sw CLI
82
+ local sw_bin
83
+ if [[ -x "$SCRIPT_DIR/sw" ]]; then
84
+ sw_bin="$SCRIPT_DIR/sw"
85
+ else
86
+ # Try to find it via PATH
87
+ sw_bin=$(command -v sw 2>/dev/null || echo "")
88
+ if [[ -z "$sw_bin" ]]; then
89
+ error "Could not find 'sw' binary — make sure Shipwright is installed"
90
+ exit 1
91
+ fi
92
+ fi
93
+
94
+ # Resolve symlinks in case sw is symlinked
95
+ sw_bin=$(cd "$(dirname "$sw_bin")" && pwd)/$(basename "$sw_bin")
96
+
97
+ # ─── Create Daemon Plist ───────────────────────────────────────────────────
98
+ cat > "$DAEMON_PLIST" <<EOF
99
+ <?xml version="1.0" encoding="UTF-8"?>
100
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
101
+ <plist version="1.0">
102
+ <dict>
103
+ <key>Label</key>
104
+ <string>com.shipwright.daemon</string>
105
+ <key>ProgramArguments</key>
106
+ <array>
107
+ <string>${sw_bin}</string>
108
+ <string>daemon</string>
109
+ <string>start</string>
110
+ </array>
111
+ <key>WorkingDirectory</key>
112
+ <string>${REPO_DIR}</string>
113
+ <key>KeepAlive</key>
114
+ <true/>
115
+ <key>RunAtLoad</key>
116
+ <true/>
117
+ <key>StandardOutPath</key>
118
+ <string>${LOG_DIR}/daemon.stdout.log</string>
119
+ <key>StandardErrorPath</key>
120
+ <string>${LOG_DIR}/daemon.stderr.log</string>
121
+ <key>EnvironmentVariables</key>
122
+ <dict>
123
+ <key>PATH</key>
124
+ <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
125
+ <key>HOME</key>
126
+ <string>\$HOME</string>
127
+ </dict>
128
+ </dict>
129
+ </plist>
130
+ EOF
131
+
132
+ chmod 644 "$DAEMON_PLIST"
133
+ success "Created daemon plist: ${DAEMON_PLIST}"
134
+
135
+ # ─── Create Dashboard Plist ────────────────────────────────────────────────
136
+ # Get full path to bun and server.ts
137
+ local bun_bin
138
+ bun_bin=$(command -v bun 2>/dev/null || echo "bun")
139
+
140
+ local server_file="$REPO_DIR/dashboard/server.ts"
141
+ if [[ ! -f "$server_file" ]]; then
142
+ warn "server.ts not found at $server_file — dashboard plist will reference a missing file"
143
+ fi
144
+
145
+ cat > "$DASHBOARD_PLIST" <<EOF
146
+ <?xml version="1.0" encoding="UTF-8"?>
147
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
148
+ <plist version="1.0">
149
+ <dict>
150
+ <key>Label</key>
151
+ <string>com.shipwright.dashboard</string>
152
+ <key>ProgramArguments</key>
153
+ <array>
154
+ <string>${bun_bin}</string>
155
+ <string>run</string>
156
+ <string>${server_file}</string>
157
+ </array>
158
+ <key>WorkingDirectory</key>
159
+ <string>${REPO_DIR}/dashboard</string>
160
+ <key>KeepAlive</key>
161
+ <true/>
162
+ <key>RunAtLoad</key>
163
+ <true/>
164
+ <key>StandardOutPath</key>
165
+ <string>${LOG_DIR}/dashboard.stdout.log</string>
166
+ <key>StandardErrorPath</key>
167
+ <string>${LOG_DIR}/dashboard.stderr.log</string>
168
+ <key>EnvironmentVariables</key>
169
+ <dict>
170
+ <key>PATH</key>
171
+ <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
172
+ <key>HOME</key>
173
+ <string>\$HOME</string>
174
+ </dict>
175
+ </dict>
176
+ </plist>
177
+ EOF
178
+
179
+ chmod 644 "$DASHBOARD_PLIST"
180
+ success "Created dashboard plist: ${DASHBOARD_PLIST}"
181
+
182
+ # ─── Create Connect Plist (only if team-config.json exists) ────────────────
183
+ if [[ -f "$TEAM_CONFIG" ]]; then
184
+ cat > "$CONNECT_PLIST" <<EOF
185
+ <?xml version="1.0" encoding="UTF-8"?>
186
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
187
+ <plist version="1.0">
188
+ <dict>
189
+ <key>Label</key>
190
+ <string>com.shipwright.connect</string>
191
+ <key>ProgramArguments</key>
192
+ <array>
193
+ <string>${sw_bin}</string>
194
+ <string>connect</string>
195
+ <string>start</string>
196
+ </array>
197
+ <key>WorkingDirectory</key>
198
+ <string>${REPO_DIR}</string>
199
+ <key>KeepAlive</key>
200
+ <true/>
201
+ <key>RunAtLoad</key>
202
+ <true/>
203
+ <key>StandardOutPath</key>
204
+ <string>${LOG_DIR}/connect.log</string>
205
+ <key>StandardErrorPath</key>
206
+ <string>${LOG_DIR}/connect.err</string>
207
+ <key>EnvironmentVariables</key>
208
+ <dict>
209
+ <key>PATH</key>
210
+ <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
211
+ <key>HOME</key>
212
+ <string>\$HOME</string>
213
+ </dict>
214
+ </dict>
215
+ </plist>
216
+ EOF
217
+
218
+ chmod 644 "$CONNECT_PLIST"
219
+ success "Created connect plist: ${CONNECT_PLIST}"
220
+ else
221
+ info "Skipping connect plist — ${TEAM_CONFIG} not found"
222
+ fi
223
+
224
+ # ─── Load Services ─────────────────────────────────────────────────────────
225
+ info "Loading launchd services..."
226
+
227
+ if launchctl load "$DAEMON_PLIST" 2>/dev/null; then
228
+ success "Loaded daemon service"
229
+ else
230
+ warn "Could not load daemon service — it may already be loaded"
231
+ fi
232
+
233
+ if launchctl load "$DASHBOARD_PLIST" 2>/dev/null; then
234
+ success "Loaded dashboard service"
235
+ else
236
+ warn "Could not load dashboard service — it may already be loaded"
237
+ fi
238
+
239
+ if [[ -f "$CONNECT_PLIST" ]]; then
240
+ if launchctl load "$CONNECT_PLIST" 2>/dev/null; then
241
+ success "Loaded connect service"
242
+ else
243
+ warn "Could not load connect service — it may already be loaded"
244
+ fi
245
+ fi
246
+
247
+ echo ""
248
+ info "Services will auto-start on next login"
249
+ info "View logs: ${DIM}tail -f ${LOG_DIR}/*.log${RESET}"
250
+ info "Uninstall: ${DIM}shipwright launchd uninstall${RESET}"
251
+ }
252
+
253
+ # ─── Uninstall Command ──────────────────────────────────────────────────────
254
+ cmd_uninstall() {
255
+ check_macos
256
+
257
+ info "Uninstalling launchd agents..."
258
+
259
+ # Unload daemon
260
+ if [[ -f "$DAEMON_PLIST" ]]; then
261
+ if launchctl unload "$DAEMON_PLIST" 2>/dev/null; then
262
+ success "Unloaded daemon service"
263
+ else
264
+ warn "Could not unload daemon service — it may not be loaded"
265
+ fi
266
+ rm -f "$DAEMON_PLIST"
267
+ success "Removed daemon plist"
268
+ fi
269
+
270
+ # Unload dashboard
271
+ if [[ -f "$DASHBOARD_PLIST" ]]; then
272
+ if launchctl unload "$DASHBOARD_PLIST" 2>/dev/null; then
273
+ success "Unloaded dashboard service"
274
+ else
275
+ warn "Could not unload dashboard service — it may not be loaded"
276
+ fi
277
+ rm -f "$DASHBOARD_PLIST"
278
+ success "Removed dashboard plist"
279
+ fi
280
+
281
+ # Unload connect
282
+ if [[ -f "$CONNECT_PLIST" ]]; then
283
+ if launchctl unload "$CONNECT_PLIST" 2>/dev/null; then
284
+ success "Unloaded connect service"
285
+ else
286
+ warn "Could not unload connect service — it may not be loaded"
287
+ fi
288
+ rm -f "$CONNECT_PLIST"
289
+ success "Removed connect plist"
290
+ fi
291
+
292
+ echo ""
293
+ success "Uninstalled all launchd agents"
294
+ }
295
+
296
+ # ─── Status Command ─────────────────────────────────────────────────────────
297
+ cmd_status() {
298
+ check_macos
299
+
300
+ echo ""
301
+ echo -e "${CYAN}${BOLD}Launchd Services${RESET}"
302
+ echo -e "${DIM}════════════════════════════════════════════${RESET}"
303
+ echo ""
304
+
305
+ # Check daemon
306
+ if launchctl list | grep -q "com.shipwright.daemon" 2>/dev/null; then
307
+ echo -e " ${GREEN}●${RESET} Daemon service is ${GREEN}loaded${RESET}"
308
+ else
309
+ echo -e " ${RED}○${RESET} Daemon service is ${RED}not loaded${RESET}"
310
+ fi
311
+
312
+ # Check dashboard
313
+ if launchctl list | grep -q "com.shipwright.dashboard" 2>/dev/null; then
314
+ echo -e " ${GREEN}●${RESET} Dashboard service is ${GREEN}loaded${RESET}"
315
+ else
316
+ echo -e " ${RED}○${RESET} Dashboard service is ${RED}not loaded${RESET}"
317
+ fi
318
+
319
+ # Check connect
320
+ if launchctl list | grep -q "com.shipwright.connect" 2>/dev/null; then
321
+ echo -e " ${GREEN}●${RESET} Connect service is ${GREEN}loaded${RESET}"
322
+ else
323
+ echo -e " ${RED}○${RESET} Connect service is ${RED}not loaded${RESET}"
324
+ fi
325
+
326
+ echo ""
327
+ echo -e " Logs: ${DIM}${LOG_DIR}${RESET}"
328
+ echo ""
329
+
330
+ # Show recent log entries
331
+ if [[ -f "$LOG_DIR/daemon.stdout.log" ]]; then
332
+ echo -e "${DIM}Recent daemon logs:${RESET}"
333
+ tail -3 "$LOG_DIR/daemon.stdout.log" | sed 's/^/ /'
334
+ echo ""
335
+ fi
336
+ }
337
+
338
+ # ─── Main ───────────────────────────────────────────────────────────────────
339
+ main() {
340
+ local cmd="${1:-help}"
341
+
342
+ case "$cmd" in
343
+ install)
344
+ cmd_install
345
+ ;;
346
+ uninstall)
347
+ cmd_uninstall
348
+ ;;
349
+ status)
350
+ cmd_status
351
+ ;;
352
+ help|--help|-h)
353
+ show_help
354
+ ;;
355
+ *)
356
+ error "Unknown command: ${cmd}"
357
+ echo ""
358
+ show_help
359
+ exit 1
360
+ ;;
361
+ esac
362
+ }
363
+
364
+ main "$@"