shipwright-cli 1.7.0 → 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 (106) 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/sw-init.sh +522 -0
  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 -328
  104. package/scripts/cct-init.sh +0 -282
  105. package/scripts/cct-session.sh +0 -284
  106. package/scripts/cct-status.sh +0 -169
@@ -0,0 +1,390 @@
1
+ #!/usr/bin/env bash
2
+ # ╔═══════════════════════════════════════════════════════════════════════════╗
3
+ # ║ sw-checkpoint.sh — Save and restore agent state mid-stage ║
4
+ # ║ ║
5
+ # ║ Checkpoints capture enough state to resume a pipeline stage without ║
6
+ # ║ restarting from scratch. ║
7
+ # ╚═══════════════════════════════════════════════════════════════════════════╝
8
+ set -euo pipefail
9
+ trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
10
+
11
+ VERSION="1.9.0"
12
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+
14
+ # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
15
+ CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
16
+ PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
17
+ BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
18
+ GREEN='\033[38;2;74;222;128m' # success
19
+ YELLOW='\033[38;2;250;204;21m' # warning
20
+ RED='\033[38;2;248;113;113m' # error
21
+ DIM='\033[2m'
22
+ BOLD='\033[1m'
23
+ RESET='\033[0m'
24
+
25
+ # ─── Cross-platform compatibility ──────────────────────────────────────────
26
+ # shellcheck source=lib/compat.sh
27
+ [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
28
+ # ─── Output Helpers ─────────────────────────────────────────────────────────
29
+ info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
30
+ success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
31
+ warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
32
+ error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
33
+
34
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
35
+
36
+ # ─── Checkpoint Directory ───────────────────────────────────────────────────
37
+ CHECKPOINT_DIR=".claude/pipeline-artifacts/checkpoints"
38
+
39
+ ensure_checkpoint_dir() {
40
+ mkdir -p "$CHECKPOINT_DIR"
41
+ }
42
+
43
+ checkpoint_file() {
44
+ local stage="$1"
45
+ echo "${CHECKPOINT_DIR}/${stage}-checkpoint.json"
46
+ }
47
+
48
+ # ─── Save ────────────────────────────────────────────────────────────────────
49
+
50
+ cmd_save() {
51
+ local stage=""
52
+ local iteration=""
53
+ local git_sha=""
54
+ local files_modified=""
55
+ local tests_passing="false"
56
+ local loop_state=""
57
+
58
+ while [[ $# -gt 0 ]]; do
59
+ case "$1" in
60
+ --stage)
61
+ stage="${2:-}"
62
+ shift 2
63
+ ;;
64
+ --stage=*)
65
+ stage="${1#--stage=}"
66
+ shift
67
+ ;;
68
+ --iteration)
69
+ iteration="${2:-}"
70
+ shift 2
71
+ ;;
72
+ --iteration=*)
73
+ iteration="${1#--iteration=}"
74
+ shift
75
+ ;;
76
+ --git-sha)
77
+ git_sha="${2:-}"
78
+ shift 2
79
+ ;;
80
+ --git-sha=*)
81
+ git_sha="${1#--git-sha=}"
82
+ shift
83
+ ;;
84
+ --files-modified)
85
+ files_modified="${2:-}"
86
+ shift 2
87
+ ;;
88
+ --files-modified=*)
89
+ files_modified="${1#--files-modified=}"
90
+ shift
91
+ ;;
92
+ --tests-passing)
93
+ tests_passing="true"
94
+ shift
95
+ ;;
96
+ --loop-state)
97
+ loop_state="${2:-}"
98
+ shift 2
99
+ ;;
100
+ --loop-state=*)
101
+ loop_state="${1#--loop-state=}"
102
+ shift
103
+ ;;
104
+ --help|-h)
105
+ show_help
106
+ return 0
107
+ ;;
108
+ *)
109
+ error "Unknown option: $1"
110
+ return 1
111
+ ;;
112
+ esac
113
+ done
114
+
115
+ if [[ -z "$stage" ]]; then
116
+ error "Missing required --stage"
117
+ echo ""
118
+ show_help
119
+ return 1
120
+ fi
121
+
122
+ # Default git sha from HEAD if not provided
123
+ if [[ -z "$git_sha" ]]; then
124
+ git_sha="$(git rev-parse HEAD 2>/dev/null || echo "unknown")"
125
+ fi
126
+
127
+ ensure_checkpoint_dir
128
+
129
+ # Build files_modified JSON array from comma-separated string
130
+ local files_json="[]"
131
+ if [[ -n "$files_modified" ]]; then
132
+ files_json="$(echo "$files_modified" | tr ',' '\n' | jq -R . | jq -s .)"
133
+ fi
134
+
135
+ # Build checkpoint JSON with jq for proper escaping
136
+ local tmp_file
137
+ tmp_file="$(mktemp)"
138
+
139
+ jq -n \
140
+ --arg stage "$stage" \
141
+ --arg iteration "${iteration:-0}" \
142
+ --argjson files_modified "$files_json" \
143
+ --arg tests_passing "$tests_passing" \
144
+ --arg git_sha "$git_sha" \
145
+ --arg loop_state "${loop_state:-}" \
146
+ --arg created_at "$(now_iso)" \
147
+ '{
148
+ stage: $stage,
149
+ iteration: ($iteration | tonumber),
150
+ files_modified: $files_modified,
151
+ tests_passing: ($tests_passing == "true"),
152
+ git_sha: $git_sha,
153
+ loop_state: $loop_state,
154
+ created_at: $created_at
155
+ }' > "$tmp_file"
156
+
157
+ # Atomic write
158
+ local target
159
+ target="$(checkpoint_file "$stage")"
160
+ mv "$tmp_file" "$target"
161
+
162
+ success "Checkpoint saved for stage ${BOLD}${stage}${RESET} (iteration ${iteration:-0})"
163
+ }
164
+
165
+ # ─── Restore ─────────────────────────────────────────────────────────────────
166
+
167
+ cmd_restore() {
168
+ local stage=""
169
+
170
+ while [[ $# -gt 0 ]]; do
171
+ case "$1" in
172
+ --stage)
173
+ stage="${2:-}"
174
+ shift 2
175
+ ;;
176
+ --stage=*)
177
+ stage="${1#--stage=}"
178
+ shift
179
+ ;;
180
+ --help|-h)
181
+ show_help
182
+ return 0
183
+ ;;
184
+ *)
185
+ error "Unknown option: $1"
186
+ return 1
187
+ ;;
188
+ esac
189
+ done
190
+
191
+ if [[ -z "$stage" ]]; then
192
+ error "Missing required --stage"
193
+ return 1
194
+ fi
195
+
196
+ local target
197
+ target="$(checkpoint_file "$stage")"
198
+
199
+ if [[ ! -f "$target" ]]; then
200
+ return 1
201
+ fi
202
+
203
+ if ! jq empty "$target" 2>/dev/null; then
204
+ warn "Corrupt checkpoint for stage: $(basename "$target")"
205
+ return 1
206
+ fi
207
+
208
+ cat "$target"
209
+ return 0
210
+ }
211
+
212
+ # ─── List ────────────────────────────────────────────────────────────────────
213
+
214
+ cmd_list() {
215
+ echo ""
216
+ echo -e "${CYAN}${BOLD} Checkpoints${RESET}"
217
+ echo -e "${DIM} ══════════════════════════════════════════${RESET}"
218
+ echo ""
219
+
220
+ if [[ ! -d "$CHECKPOINT_DIR" ]]; then
221
+ echo -e " ${DIM}No checkpoints found.${RESET}"
222
+ echo ""
223
+ return 0
224
+ fi
225
+
226
+ local count=0
227
+ local file
228
+ for file in "${CHECKPOINT_DIR}"/*-checkpoint.json; do
229
+ # Handle no matches (glob returns literal pattern)
230
+ [[ -f "$file" ]] || continue
231
+ count=$((count + 1))
232
+
233
+ local stage iteration git_sha tests_passing loop_state created_at
234
+ stage="$(jq -r '.stage' "$file")"
235
+ iteration="$(jq -r '.iteration' "$file")"
236
+ git_sha="$(jq -r '.git_sha' "$file")"
237
+ tests_passing="$(jq -r '.tests_passing' "$file")"
238
+ loop_state="$(jq -r '.loop_state' "$file")"
239
+ created_at="$(jq -r '.created_at' "$file")"
240
+
241
+ # Format tests indicator
242
+ local tests_icon
243
+ if [[ "$tests_passing" == "true" ]]; then
244
+ tests_icon="${GREEN}✓${RESET}"
245
+ else
246
+ tests_icon="${RED}✗${RESET}"
247
+ fi
248
+
249
+ # Format loop state
250
+ local state_display=""
251
+ if [[ -n "$loop_state" && "$loop_state" != "null" ]]; then
252
+ state_display=" ${DIM}state:${RESET}${loop_state}"
253
+ fi
254
+
255
+ echo -e " ${CYAN}●${RESET} ${BOLD}${stage}${RESET} iter:${iteration} tests:${tests_icon} ${DIM}sha:${git_sha:0:7}${RESET}${state_display}"
256
+ echo -e " ${DIM}${created_at}${RESET}"
257
+ done
258
+
259
+ if [[ "$count" -eq 0 ]]; then
260
+ echo -e " ${DIM}No checkpoints found.${RESET}"
261
+ else
262
+ echo ""
263
+ echo -e " ${DIM}${count} checkpoint(s)${RESET}"
264
+ fi
265
+ echo ""
266
+ }
267
+
268
+ # ─── Clear ───────────────────────────────────────────────────────────────────
269
+
270
+ cmd_clear() {
271
+ local stage=""
272
+ local clear_all=false
273
+
274
+ while [[ $# -gt 0 ]]; do
275
+ case "$1" in
276
+ --stage)
277
+ stage="${2:-}"
278
+ shift 2
279
+ ;;
280
+ --stage=*)
281
+ stage="${1#--stage=}"
282
+ shift
283
+ ;;
284
+ --all)
285
+ clear_all=true
286
+ shift
287
+ ;;
288
+ --help|-h)
289
+ show_help
290
+ return 0
291
+ ;;
292
+ *)
293
+ error "Unknown option: $1"
294
+ return 1
295
+ ;;
296
+ esac
297
+ done
298
+
299
+ if [[ "$clear_all" == "true" ]]; then
300
+ if [[ -d "$CHECKPOINT_DIR" ]]; then
301
+ local count=0
302
+ local file
303
+ for file in "${CHECKPOINT_DIR}"/*-checkpoint.json; do
304
+ [[ -f "$file" ]] || continue
305
+ rm -f "$file"
306
+ count=$((count + 1))
307
+ done
308
+ success "Cleared ${count} checkpoint(s)"
309
+ else
310
+ info "No checkpoints to clear"
311
+ fi
312
+ return 0
313
+ fi
314
+
315
+ if [[ -z "$stage" ]]; then
316
+ error "Missing --stage or --all"
317
+ return 1
318
+ fi
319
+
320
+ local target
321
+ target="$(checkpoint_file "$stage")"
322
+
323
+ if [[ -f "$target" ]]; then
324
+ rm -f "$target"
325
+ success "Cleared checkpoint for stage ${BOLD}${stage}${RESET}"
326
+ else
327
+ warn "No checkpoint found for stage ${BOLD}${stage}${RESET}"
328
+ fi
329
+ }
330
+
331
+ # ─── Help ────────────────────────────────────────────────────────────────────
332
+
333
+ show_help() {
334
+ echo -e "${CYAN}${BOLD}shipwright checkpoint${RESET} ${DIM}v${VERSION}${RESET} — Save and restore agent state mid-stage"
335
+ echo ""
336
+ echo -e "${BOLD}USAGE${RESET}"
337
+ echo -e " ${CYAN}shipwright checkpoint${RESET} <command> [options]"
338
+ echo ""
339
+ echo -e "${BOLD}COMMANDS${RESET}"
340
+ echo -e " ${CYAN}save${RESET} Save a checkpoint for a stage"
341
+ echo -e " ${CYAN}restore${RESET} Restore a checkpoint (prints JSON to stdout)"
342
+ echo -e " ${CYAN}list${RESET} Show all available checkpoints"
343
+ echo -e " ${CYAN}clear${RESET} Remove checkpoint(s)"
344
+ echo ""
345
+ echo -e "${BOLD}SAVE OPTIONS${RESET}"
346
+ echo -e " ${CYAN}--stage${RESET} <name> Stage name (required)"
347
+ echo -e " ${CYAN}--iteration${RESET} <n> Current iteration number"
348
+ echo -e " ${CYAN}--git-sha${RESET} <sha> Git commit SHA (default: HEAD)"
349
+ echo -e " ${CYAN}--files-modified${RESET} \"f1,f2\" Comma-separated list of modified files"
350
+ echo -e " ${CYAN}--tests-passing${RESET} Mark tests as passing"
351
+ echo -e " ${CYAN}--loop-state${RESET} <state> Loop state (running, paused, etc.)"
352
+ echo ""
353
+ echo -e "${BOLD}RESTORE OPTIONS${RESET}"
354
+ echo -e " ${CYAN}--stage${RESET} <name> Stage to restore (required)"
355
+ echo ""
356
+ echo -e "${BOLD}CLEAR OPTIONS${RESET}"
357
+ echo -e " ${CYAN}--stage${RESET} <name> Stage to clear"
358
+ echo -e " ${CYAN}--all${RESET} Clear all checkpoints"
359
+ echo ""
360
+ echo -e "${BOLD}EXAMPLES${RESET}"
361
+ echo -e " ${DIM}shipwright checkpoint save --stage build --iteration 5${RESET}"
362
+ echo -e " ${DIM}shipwright checkpoint save --stage build --iteration 3 --tests-passing --files-modified \"src/auth.ts,src/middleware.ts\"${RESET}"
363
+ echo -e " ${DIM}shipwright checkpoint restore --stage build${RESET}"
364
+ echo -e " ${DIM}shipwright checkpoint list${RESET}"
365
+ echo -e " ${DIM}shipwright checkpoint clear --stage build${RESET}"
366
+ echo -e " ${DIM}shipwright checkpoint clear --all${RESET}"
367
+ }
368
+
369
+ # ─── Command Router ─────────────────────────────────────────────────────────
370
+
371
+ main() {
372
+ local cmd="${1:-help}"
373
+ shift 2>/dev/null || true
374
+
375
+ case "$cmd" in
376
+ save) cmd_save "$@" ;;
377
+ restore) cmd_restore "$@" ;;
378
+ list) cmd_list ;;
379
+ clear) cmd_clear "$@" ;;
380
+ help|--help|-h) show_help ;;
381
+ *)
382
+ error "Unknown command: ${cmd}"
383
+ echo ""
384
+ show_help
385
+ exit 1
386
+ ;;
387
+ esac
388
+ }
389
+
390
+ main "$@"
@@ -1,11 +1,13 @@
1
1
  #!/usr/bin/env bash
2
2
  # ╔═══════════════════════════════════════════════════════════════════════════╗
3
- # ║ cct-cleanup.sh — Clean up orphaned Claude team sessions ║
3
+ # ║ sw-cleanup.sh — Clean up orphaned Claude team sessions ║
4
4
  # ║ ║
5
5
  # ║ Default: dry-run (shows what would be cleaned). ║
6
6
  # ║ Use --force to actually kill sessions and remove files. ║
7
7
  # ╚═══════════════════════════════════════════════════════════════════════════╝
8
+ VERSION="1.9.0"
8
9
  set -euo pipefail
10
+ trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
9
11
 
10
12
  # ─── Colors ──────────────────────────────────────────────────────────────────
11
13
  CYAN='\033[38;2;0;212;255m'