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
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "refactor",
3
3
  "description": "Refactoring with one agent for changes and one for consumers/tests",
4
+ "keywords": ["refactor", "cleanup", "simplify", "reorganize", "optimize"],
4
5
  "agents": [
5
6
  {
6
7
  "name": "refactor",
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "release",
3
+ "description": "Release management with preparation, validation, and announcement agents",
4
+ "keywords": [
5
+ "release",
6
+ "version",
7
+ "publish",
8
+ "changelog",
9
+ "tag",
10
+ "package",
11
+ "ship",
12
+ "launch",
13
+ "npm publish"
14
+ ],
15
+ "agents": [
16
+ {
17
+ "name": "preparer",
18
+ "role": "Changelog generation, version bumps, dependency audit, license check, breaking change detection",
19
+ "focus": "package.json, CHANGELOG.md, Cargo.toml, go.mod, *.lock, version.*"
20
+ },
21
+ {
22
+ "name": "validator",
23
+ "role": "Full test suite, smoke tests, canary checks, rollback verification, binary/package size check",
24
+ "focus": "*.test.*, scripts/, e2e/, *.spec.*"
25
+ },
26
+ {
27
+ "name": "announcer",
28
+ "role": "Release notes, migration guide, deprecation notices, upgrade instructions, API diff summary",
29
+ "focus": "docs/, *.md, CHANGELOG.md, MIGRATION.md, UPGRADING.md"
30
+ }
31
+ ],
32
+ "layout": "tiled",
33
+ "layout_style": "main-horizontal",
34
+ "main_pane_percent": 65
35
+ }
@@ -1,6 +1,14 @@
1
1
  {
2
2
  "name": "security-audit",
3
3
  "description": "Security audit with code analysis, dependency scanning, and config review agents",
4
+ "keywords": [
5
+ "security",
6
+ "vulnerability",
7
+ "xss",
8
+ "injection",
9
+ "auth",
10
+ "patch"
11
+ ],
4
12
  "agents": [
5
13
  {
6
14
  "name": "code-analysis",
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "spike",
3
+ "description": "Proof of concept and technical spike with researcher, prototyper, and evaluator agents",
4
+ "keywords": [
5
+ "spike",
6
+ "poc",
7
+ "proof of concept",
8
+ "prototype",
9
+ "experiment",
10
+ "evaluate",
11
+ "feasibility",
12
+ "compare"
13
+ ],
14
+ "agents": [
15
+ {
16
+ "name": "researcher",
17
+ "role": "Evaluate libraries, APIs, and approaches. Compare trade-offs, licensing, maintenance status, community support.",
18
+ "focus": "docs/, package.json, go.mod, Cargo.toml, requirements.txt"
19
+ },
20
+ {
21
+ "name": "prototyper",
22
+ "role": "Build minimal working prototype. Throwaway code is fine — optimize for speed of learning, not production quality.",
23
+ "focus": "spike/, prototype/, src/"
24
+ },
25
+ {
26
+ "name": "evaluator",
27
+ "role": "Write decision document with recommendation, risks, migration path, and effort estimate. Zero attachment to the prototype.",
28
+ "focus": "docs/, *.md, spike/"
29
+ }
30
+ ],
31
+ "layout": "tiled",
32
+ "layout_style": "main-horizontal",
33
+ "main_pane_percent": 65
34
+ }
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "testing",
3
3
  "description": "Comprehensive testing with unit, integration, and e2e agents",
4
+ "keywords": ["test", "coverage", "unit", "integration", "e2e", "spec"],
4
5
  "agents": [
5
6
  {
6
7
  "name": "unit-tests",
package/tmux/tmux.conf CHANGED
@@ -1,6 +1,6 @@
1
1
  # ╔═══════════════════════════════════════════════════════════════════════════╗
2
2
  # ║ TMUX CONFIGURATION ║
3
- # ║ Premium Developer Theme
3
+ # ║ Shipwright Optimized for Claude Code
4
4
  # ╚═══════════════════════════════════════════════════════════════════════════╝
5
5
 
6
6
  # ═══════════════════════════════════════════════════════════════════════════
@@ -8,16 +8,63 @@
8
8
  # ═══════════════════════════════════════════════════════════════════════════
9
9
 
10
10
  set -g default-terminal "tmux-256color"
11
+
12
+ # ─── Terminal-specific overrides ────────────────────────────────────────
13
+ # True color + italics for modern terminals
11
14
  set -ag terminal-overrides ",xterm-256color:RGB"
15
+ set -ag terminal-overrides ",xterm-256color:Tc"
16
+ set -ag terminal-overrides ",iTerm2*:RGB:Tc"
17
+ # Ghostty, kitty, WezTerm, Alacritty true color
18
+ set -ag terminal-overrides ",xterm-ghostty:RGB:Tc"
19
+ set -ag terminal-overrides ",xterm-kitty:RGB:Tc"
20
+ set -ag terminal-overrides ",wezterm:RGB:Tc"
21
+ set -ag terminal-overrides ",alacritty:RGB:Tc"
22
+ # Styled underline (curly, dotted, dashed)
23
+ set -ag terminal-overrides ",*:Smulx=\\E[4::%p1%dm"
24
+ set -ag terminal-overrides ",*:Setulc=\\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m"
25
+ # Terminal.app: 256 color only, basic mouse
26
+ set -ag terminal-overrides ",Apple_Terminal*:colors=256"
27
+
28
+ # ─── Claude Code TUI Compatibility ────────────────────────────────────
29
+ # Passthrough: enables DEC 2026 synchronized output (eliminates flicker),
30
+ # OSC 52 clipboard, OSC notifications, and image protocols.
31
+ # Critical for Claude Code's rapid TUI updates inside tmux.
32
+ set -g allow-passthrough on
33
+
34
+ # Extended keys: lets TUI apps (Claude Code, vim, etc.) receive modifier
35
+ # key combos that plain terminals would swallow (Ctrl+Shift+key, etc.)
36
+ set -g extended-keys on
37
+ set -as terminal-features 'xterm*:extkeys'
38
+
39
+ # ─── Mouse ──────────────────────────────────────────────────────────────
12
40
  set -g mouse on
41
+ # Fix: tmux 3.4+ defaults MouseDown1Status to switch-client (sessions),
42
+ # but we want select-window so clicking status bar windows actually works
43
+ bind -T root MouseDown1Status select-window -t =
44
+ # Double-click on status bar word to rename window
45
+ bind -T root DoubleClick1Status command-prompt -I "#W" "rename-window -- '%%'"
46
+
47
+ # ─── Core Behavior ─────────────────────────────────────────────────────
13
48
  set -g base-index 1
14
49
  setw -g pane-base-index 1
15
50
  set -g renumber-windows on
16
- set -g history-limit 50000
17
51
  set -sg escape-time 0
18
52
  set -g focus-events on
19
53
  setw -g monitor-activity on
20
54
  set -g visual-activity off
55
+ # Display messages for 3 seconds (default 750ms is too fast)
56
+ set -g display-time 3000
57
+ # Display pane indicators for 2 seconds
58
+ set -g display-panes-time 2000
59
+ # Smoother repeated key operations (600ms window)
60
+ set -g repeat-time 600
61
+ # Clipboard: native OSC 52 — copies work across SSH + tmux nesting
62
+ set -g set-clipboard on
63
+
64
+ # ─── History ───────────────────────────────────────────────────────────
65
+ # Claude Code generates 4,000-6,700 scroll events/sec during streaming.
66
+ # 250k lines prevents buffer exhaustion during long agent runs.
67
+ set -g history-limit 250000
21
68
 
22
69
  # ═══════════════════════════════════════════════════════════════════════════
23
70
  # STATUS BAR CONFIGURATION
@@ -35,14 +82,12 @@ set -g status-left "#[fg=#1e1e32,bg=#00d4ff,bold] #S #[fg=#00d4ff,bg=#0066ff]#[
35
82
 
36
83
  setw -g window-status-separator " "
37
84
  # Inactive windows; team windows (claude-*) get a λ icon
38
- # NOTE: use separate #[fg=]#[bg=] blocks — commas inside #{?} branches break parsing
39
85
  setw -g window-status-format "#{?#{m:claude-*,#W},#[fg=#7c3aed]#[bg=#252538] λ #I:#W ,#[fg=#71717a]#[bg=#252538] #I:#W }#[fg=#252538]#[bg=#1a1a2e]"
40
86
  # Active window; team windows get λ icon in cyan
41
87
  setw -g window-status-current-format "#{?#{m:claude-*,#W},#[fg=#1e1e32]#[bg=#00d4ff]#[bold] λ #I:#W ,#[fg=#1e1e32]#[bg=#00d4ff]#[bold] #I:#W }#[fg=#00d4ff]#[bg=#1a1a2e]"
42
88
 
43
- # Right side: normal info OR key hints when prefix is active
44
- # NOTE: use separate #[fg=]#[bg=] blocks commas inside #{?} branches break parsing
45
- set -g status-right "#{?client_prefix,#[fg=#1e1e32]#[bg=#0066ff]#[bold] T team | split - split hjkl nav G zoom S sync x kill #[fg=#1e1e32]#[bg=#00d4ff]#[bold] ^a ,#[fg=#71717a]#[bg=#252538] #(whoami)@#h #[fg=#1e1e32]#[bg=#7c3aed]#[bold] %H:%M #[fg=#e4e4e7]#[bg=#0066ff]#[bold] %b %d #[fg=#1e1e32]#[bg=#00d4ff]#[bold] %a }"
89
+ # Right side: key hints when prefix is active, otherwise clock + date
90
+ set -g status-right "#{?client_prefix,#[fg=#1e1e32]#[bg=#0066ff]#[bold] T team | split - split hjkl nav G zoom S sync x kill F fzf #[fg=#1e1e32]#[bg=#00d4ff]#[bold] ^a ,#[fg=#71717a]#[bg=#252538] #(whoami)@#h #[fg=#1e1e32]#[bg=#7c3aed]#[bold] %H:%M #[fg=#e4e4e7]#[bg=#0066ff]#[bold] %b %d #[fg=#1e1e32]#[bg=#00d4ff]#[bold] %a }"
46
91
 
47
92
  # ═══════════════════════════════════════════════════════════════════════════
48
93
  # PANE STYLING
@@ -52,9 +97,16 @@ set -g window-style 'bg=#1a1a2e,fg=#e4e4e7'
52
97
  set -g window-active-style 'bg=#1a1a2e,fg=#e4e4e7'
53
98
  set -g pane-border-style "fg=#333355,bg=#1a1a2e"
54
99
  set -g pane-active-border-style "fg=#00d4ff,bg=#1a1a2e"
100
+ # Heavy pane border lines for better visibility (tmux 3.2+)
101
+ set -g pane-border-lines heavy
55
102
  set -g display-panes-colour "#333355"
56
103
  set -g display-panes-active-colour "#00d4ff"
57
104
 
105
+ # ─── Popup Styling (tmux 3.3+) ─────────────────────────────────────────
106
+ set -gq popup-style 'bg=#252538'
107
+ set -gq popup-border-style 'fg=#00d4ff'
108
+ set -gq popup-border-lines rounded
109
+
58
110
  # ═══════════════════════════════════════════════════════════════════════════
59
111
  # MESSAGE STYLING
60
112
  # ═══════════════════════════════════════════════════════════════════════════
@@ -139,23 +191,54 @@ bind s choose-tree -sZ -O name
139
191
  bind N new-session
140
192
 
141
193
  # ═══════════════════════════════════════════════════════════════════════════
142
- # PLUGINS (via TPM - optional)
194
+ # FLOATING POPUP TERMINALS (tmux 3.2+)
195
+ # ═══════════════════════════════════════════════════════════════════════════
196
+
197
+ # prefix + F → floating popup terminal in current directory
198
+ bind F display-popup -E -w 80% -h 75% -d "#{pane_current_path}"
199
+
200
+ # prefix + C-f → FZF session/window switcher in a popup
201
+ bind C-f display-popup -E -w 60% -h 50% "\
202
+ tmux list-sessions -F '#{session_name}' | \
203
+ fzf --reverse --header='Switch session' | \
204
+ xargs -I{} tmux switch-client -t {}"
205
+
206
+ # ═══════════════════════════════════════════════════════════════════════════
207
+ # PLUGINS (via TPM)
143
208
  # ═══════════════════════════════════════════════════════════════════════════
144
209
 
145
210
  set -g @plugin 'tmux-plugins/tpm'
146
211
  set -g @plugin 'tmux-plugins/tmux-sensible'
147
212
  set -g @plugin 'tmux-plugins/tmux-resurrect'
148
213
  set -g @plugin 'tmux-plugins/tmux-continuum'
214
+ set -g @plugin 'tmux-plugins/tmux-yank'
215
+ set -g @plugin 'sainnhe/tmux-fzf'
216
+
217
+ # ─── Plugin Configuration ──────────────────────────────────────────────
149
218
 
219
+ # Resurrect: persist full pane content + programs
150
220
  set -g @resurrect-capture-pane-contents 'on'
221
+ set -g @resurrect-strategy-nvim 'session'
222
+
223
+ # Continuum: auto-save every 15 min, auto-restore on tmux start
151
224
  set -g @continuum-restore 'on'
225
+ set -g @continuum-save-interval '15'
226
+
227
+ # Yank: use system clipboard, stay in copy mode after yanking
228
+ set -g @yank_selection_mouse 'clipboard'
229
+ set -g @yank_action 'copy-pipe'
230
+
231
+ # FZF: use popup window (tmux 3.2+), Shipwright color scheme
232
+ set -g @tmux-fzf-launch-key 'C-f'
233
+ TMUX_FZF_OPTIONS="-p -w 60% -h 50%"
234
+ TMUX_FZF_PREVIEW=0
152
235
 
153
236
  # ═══════════════════════════════════════════════════════════════════════════
154
- # CLAUDE CODE TEAMS INTEGRATION
237
+ # SHIPWRIGHT INTEGRATION
155
238
  # ═══════════════════════════════════════════════════════════════════════════
156
239
 
157
240
  # Source teams overlay (agent pane styling, keybindings)
158
- source-file -q ~/.tmux/claude-teams-overlay.conf
241
+ source-file -q ~/.tmux/shipwright-overlay.conf
159
242
 
160
243
  # Quick launch: prefix + T → start a Claude team session
161
244
  bind T run-shell "shipwright session"
@@ -163,5 +246,11 @@ bind T run-shell "shipwright session"
163
246
  # Quick status: prefix + C-t → show team dashboard in floating popup
164
247
  bind C-t display-popup -w 80% -h 70% -E "shipwright status; echo ''; echo 'Press ENTER to close'; read"
165
248
 
249
+ # Quick logs: prefix + C-l → tail agent logs in popup
250
+ bind M-L display-popup -w 85% -h 80% -E "shipwright logs --follow 2>/dev/null || echo 'No active logs'; echo ''; echo 'Press ENTER to close'; read"
251
+
252
+ # Quick cost: prefix + C-c → cost dashboard in popup
253
+ bind M-C display-popup -w 70% -h 60% -E "shipwright cost show 2>/dev/null || echo 'Cost tracking not configured'; echo ''; echo 'Press ENTER to close'; read"
254
+
166
255
  # Initialize TPM (keep at very bottom)
167
256
  run-shell '~/.tmux/plugins/tpm/tpm'
@@ -1,328 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ╔═══════════════════════════════════════════════════════════════════════════╗
3
- # ║ cct-doctor.sh — Validate Claude Code Teams setup ║
4
- # ║ ║
5
- # ║ Checks prerequisites, installed files, PATH, and common issues. ║
6
- # ╚═══════════════════════════════════════════════════════════════════════════╝
7
- set -euo pipefail
8
-
9
- # ─── Colors ──────────────────────────────────────────────────────────────────
10
- CYAN='\033[38;2;0;212;255m'
11
- PURPLE='\033[38;2;124;58;237m'
12
- BLUE='\033[38;2;0;102;255m'
13
- GREEN='\033[38;2;74;222;128m'
14
- YELLOW='\033[38;2;250;204;21m'
15
- RED='\033[38;2;248;113;113m'
16
- DIM='\033[2m'
17
- BOLD='\033[1m'
18
- RESET='\033[0m'
19
-
20
- # ─── Helpers ─────────────────────────────────────────────────────────────────
21
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
22
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
23
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
24
- error() { echo -e "${RED}${BOLD}✗${RESET} $*"; }
25
-
26
- PASS=0
27
- WARN=0
28
- FAIL=0
29
-
30
- check_pass() { success "$*"; PASS=$((PASS + 1)); }
31
- check_warn() { warn "$*"; WARN=$((WARN + 1)); }
32
- check_fail() { error "$*"; FAIL=$((FAIL + 1)); }
33
-
34
- # ─── Header ─────────────────────────────────────────────────────────────────
35
- echo ""
36
- echo -e "${CYAN}${BOLD} Claude Code Teams — Doctor${RESET}"
37
- echo -e "${DIM} $(date '+%Y-%m-%d %H:%M:%S')${RESET}"
38
- echo -e "${DIM} ══════════════════════════════════════════${RESET}"
39
- echo ""
40
-
41
- # ═════════════════════════════════════════════════════════════════════════════
42
- # 1. Prerequisites
43
- # ═════════════════════════════════════════════════════════════════════════════
44
- echo -e "${PURPLE}${BOLD} PREREQUISITES${RESET}"
45
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
46
-
47
- # tmux
48
- if command -v tmux &>/dev/null; then
49
- TMUX_VERSION="$(tmux -V | grep -oE '[0-9]+\.[0-9a-z]+')"
50
- TMUX_MAJOR="$(echo "$TMUX_VERSION" | cut -d. -f1)"
51
- TMUX_MINOR="$(echo "$TMUX_VERSION" | cut -d. -f2 | tr -dc '0-9')"
52
- if [[ "$TMUX_MAJOR" -ge 3 && "$TMUX_MINOR" -ge 2 ]] || [[ "$TMUX_MAJOR" -ge 4 ]]; then
53
- check_pass "tmux ${TMUX_VERSION}"
54
- else
55
- check_warn "tmux ${TMUX_VERSION} — 3.2+ recommended for pane-border-format"
56
- fi
57
- else
58
- check_fail "tmux not installed"
59
- echo -e " ${DIM}brew install tmux (macOS)${RESET}"
60
- echo -e " ${DIM}sudo apt install tmux (Ubuntu/Debian)${RESET}"
61
- fi
62
-
63
- # jq
64
- if command -v jq &>/dev/null; then
65
- check_pass "jq $(jq --version 2>&1 | tr -d 'jq-')"
66
- else
67
- check_fail "jq not installed — required for template parsing"
68
- echo -e " ${DIM}brew install jq${RESET} (macOS)"
69
- echo -e " ${DIM}sudo apt install jq${RESET} (Ubuntu/Debian)"
70
- fi
71
-
72
- # Claude Code CLI
73
- if command -v claude &>/dev/null; then
74
- check_pass "Claude Code CLI found"
75
- else
76
- check_fail "Claude Code CLI not found"
77
- echo -e " ${DIM}npm install -g @anthropic-ai/claude-code${RESET}"
78
- fi
79
-
80
- # Node.js
81
- if command -v node &>/dev/null; then
82
- NODE_VERSION="$(node -v | tr -d 'v')"
83
- NODE_MAJOR="$(echo "$NODE_VERSION" | cut -d. -f1)"
84
- if [[ "$NODE_MAJOR" -ge 20 ]]; then
85
- check_pass "Node.js ${NODE_VERSION}"
86
- else
87
- check_warn "Node.js ${NODE_VERSION} — 20+ recommended"
88
- fi
89
- else
90
- check_fail "Node.js not found"
91
- fi
92
-
93
- # Git
94
- if command -v git &>/dev/null; then
95
- check_pass "git $(git --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')"
96
- else
97
- check_fail "git not found"
98
- fi
99
-
100
- # ═════════════════════════════════════════════════════════════════════════════
101
- # 2. Installed Files
102
- # ═════════════════════════════════════════════════════════════════════════════
103
- echo ""
104
- echo -e "${PURPLE}${BOLD} INSTALLED FILES${RESET}"
105
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
106
-
107
- # tmux overlay
108
- if [[ -f "$HOME/.tmux/claude-teams-overlay.conf" ]]; then
109
- check_pass "Overlay: ~/.tmux/claude-teams-overlay.conf"
110
- else
111
- check_fail "Overlay not found: ~/.tmux/claude-teams-overlay.conf"
112
- echo -e " ${DIM}Re-run install.sh to install it${RESET}"
113
- fi
114
-
115
- # Overlay sourced in tmux.conf
116
- if [[ -f "$HOME/.tmux.conf" ]]; then
117
- if grep -q "claude-teams-overlay" "$HOME/.tmux.conf" 2>/dev/null; then
118
- check_pass "Overlay sourced in ~/.tmux.conf"
119
- else
120
- check_warn "Overlay not sourced in ~/.tmux.conf"
121
- echo -e " ${DIM}Add: source-file -q ~/.tmux/claude-teams-overlay.conf${RESET}"
122
- fi
123
- else
124
- check_warn "No ~/.tmux.conf found"
125
- fi
126
-
127
- # Claude settings
128
- if [[ -f "$HOME/.claude/settings.json" ]]; then
129
- check_pass "Settings: ~/.claude/settings.json"
130
- else
131
- check_warn "No ~/.claude/settings.json"
132
- echo -e " ${DIM}Copy from settings.json.template${RESET}"
133
- fi
134
-
135
- # Hooks directory
136
- HOOKS_DIR="$HOME/.claude/hooks"
137
- if [[ -d "$HOOKS_DIR" ]]; then
138
- hook_count=0
139
- non_exec=0
140
- while IFS= read -r hook; do
141
- [[ -z "$hook" ]] && continue
142
- hook_count=$((hook_count + 1))
143
- if [[ ! -x "$hook" ]]; then
144
- non_exec=$((non_exec + 1))
145
- fi
146
- done < <(find "$HOOKS_DIR" -maxdepth 1 -name '*.sh' -type f 2>/dev/null)
147
-
148
- if [[ $hook_count -gt 0 && $non_exec -eq 0 ]]; then
149
- check_pass "Hooks: ${hook_count} scripts, all executable"
150
- elif [[ $hook_count -gt 0 && $non_exec -gt 0 ]]; then
151
- check_warn "Hooks: ${non_exec}/${hook_count} scripts not executable"
152
- echo -e " ${DIM}chmod +x ~/.claude/hooks/*.sh${RESET}"
153
- else
154
- check_warn "Hooks dir exists but no .sh scripts found"
155
- fi
156
- else
157
- check_warn "No hooks directory at ~/.claude/hooks/"
158
- fi
159
-
160
- # ═════════════════════════════════════════════════════════════════════════════
161
- # 3. PATH & CLI
162
- # ═════════════════════════════════════════════════════════════════════════════
163
- echo ""
164
- echo -e "${PURPLE}${BOLD} PATH & CLI${RESET}"
165
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
166
-
167
- BIN_DIR="$HOME/.local/bin"
168
-
169
- if echo "$PATH" | tr ':' '\n' | grep -q "$BIN_DIR"; then
170
- check_pass "${BIN_DIR} is in PATH"
171
- else
172
- check_warn "${BIN_DIR} is NOT in PATH"
173
- echo -e " ${DIM}Add to ~/.zshrc or ~/.bashrc:${RESET}"
174
- echo -e " ${DIM}export PATH=\"\$HOME/.local/bin:\$PATH\"${RESET}"
175
- fi
176
-
177
- # Check cct subcommands are installed alongside the router
178
- if command -v cct &>/dev/null; then
179
- CCT_DIR="$(dirname "$(command -v cct)")"
180
- check_pass "shipwright router found at ${CCT_DIR}/cct"
181
-
182
- missing_subs=()
183
- for sub in cct-session.sh cct-status.sh cct-cleanup.sh; do
184
- if [[ ! -x "${CCT_DIR}/${sub}" ]]; then
185
- missing_subs+=("$sub")
186
- fi
187
- done
188
-
189
- if [[ ${#missing_subs[@]} -eq 0 ]]; then
190
- check_pass "All core subcommands installed"
191
- else
192
- check_warn "Missing subcommands: ${missing_subs[*]}"
193
- echo -e " ${DIM}Re-run install.sh or shipwright upgrade --apply${RESET}"
194
- fi
195
- else
196
- check_fail "shipwright command not found in PATH"
197
- echo -e " ${DIM}Re-run install.sh to install the CLI${RESET}"
198
- fi
199
-
200
- # ═════════════════════════════════════════════════════════════════════════════
201
- # 4. Pane Display
202
- # ═════════════════════════════════════════════════════════════════════════════
203
- echo ""
204
- echo -e "${PURPLE}${BOLD} PANE DISPLAY${RESET}"
205
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
206
-
207
- # Check overlay file exists
208
- if [[ -f "$HOME/.tmux/claude-teams-overlay.conf" ]]; then
209
- # Check for set-hook color enforcement
210
- if grep -q "set-hook.*after-split-window" "$HOME/.tmux/claude-teams-overlay.conf" 2>/dev/null; then
211
- check_pass "Overlay has color hooks (set-hook)"
212
- else
213
- check_warn "Overlay missing color hooks — new panes may flash white"
214
- echo -e " ${DIM}Run: shipwright upgrade --apply or shipwright init${RESET}"
215
- fi
216
- else
217
- check_fail "Overlay not found — pane display features unavailable"
218
- fi
219
-
220
- # Check if set-hook commands are active in tmux
221
- if [[ -n "${TMUX:-}" ]]; then
222
- if tmux show-hooks -g 2>/dev/null | grep -q "after-split-window"; then
223
- check_pass "set-hook commands active in tmux"
224
- else
225
- check_warn "set-hook commands not active — reload config: prefix + r"
226
- fi
227
-
228
- # Check default-terminal
229
- TMUX_TERM="$(tmux show-option -gv default-terminal 2>/dev/null || echo "unknown")"
230
- if [[ "$TMUX_TERM" == *"256color"* ]]; then
231
- check_pass "default-terminal: $TMUX_TERM"
232
- else
233
- check_warn "default-terminal: $TMUX_TERM — 256color variant recommended"
234
- echo -e " ${DIM}set -g default-terminal 'tmux-256color'${RESET}"
235
- fi
236
-
237
- # Check pane border includes cyan accent
238
- BORDER_FMT="$(tmux show-option -gv pane-border-format 2>/dev/null || echo "")"
239
- if echo "$BORDER_FMT" | grep -q "#00d4ff"; then
240
- check_pass "Pane border format includes cyan accent"
241
- else
242
- check_warn "Pane border format missing cyan accent — overlay may not be loaded"
243
- fi
244
- else
245
- info "Not in tmux session — skipping runtime display checks"
246
- fi
247
-
248
- # ═════════════════════════════════════════════════════════════════════════════
249
- # 5. Orphaned Sessions
250
- # ═════════════════════════════════════════════════════════════════════════════
251
- echo ""
252
- echo -e "${PURPLE}${BOLD} ORPHAN CHECK${RESET}"
253
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
254
-
255
- orphaned_teams=0
256
- TEAMS_DIR="$HOME/.claude/teams"
257
- if [[ -d "$TEAMS_DIR" ]]; then
258
- while IFS= read -r team_dir; do
259
- [[ -z "$team_dir" ]] && continue
260
- team_name="$(basename "$team_dir")"
261
- config_file="${team_dir}/config.json"
262
- if [[ ! -f "$config_file" ]]; then
263
- orphaned_teams=$((orphaned_teams + 1))
264
- check_warn "Orphaned team dir: ${team_name} (no config.json)"
265
- fi
266
- done < <(find "$TEAMS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null)
267
- fi
268
-
269
- if [[ $orphaned_teams -eq 0 ]]; then
270
- check_pass "No orphaned team sessions"
271
- fi
272
-
273
- # ═════════════════════════════════════════════════════════════════════════════
274
- # 6. Terminal Compatibility
275
- # ═════════════════════════════════════════════════════════════════════════════
276
- echo ""
277
- echo -e "${PURPLE}${BOLD} TERMINAL${RESET}"
278
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
279
-
280
- TERM_PROGRAM="${TERM_PROGRAM:-unknown}"
281
-
282
- case "$TERM_PROGRAM" in
283
- iTerm.app|iTerm2)
284
- check_pass "iTerm2 — full support"
285
- ;;
286
- Apple_Terminal)
287
- check_pass "Terminal.app — supported"
288
- ;;
289
- WezTerm)
290
- check_pass "WezTerm — full support"
291
- ;;
292
- tmux)
293
- check_pass "Running inside tmux (nested)"
294
- ;;
295
- vscode)
296
- check_warn "VS Code integrated terminal"
297
- echo -e " ${DIM}Some pane border features may not render correctly.${RESET}"
298
- echo -e " ${DIM}Consider running tmux in an external terminal.${RESET}"
299
- ;;
300
- Ghostty)
301
- check_warn "Ghostty — may have tmux rendering quirks"
302
- echo -e " ${DIM}If pane borders look wrong, try: set -g default-terminal 'xterm-256color'${RESET}"
303
- ;;
304
- *)
305
- info "Terminal: ${TERM_PROGRAM}"
306
- ;;
307
- esac
308
-
309
- # ═════════════════════════════════════════════════════════════════════════════
310
- # Summary
311
- # ═════════════════════════════════════════════════════════════════════════════
312
- echo ""
313
- echo -e "${DIM} ══════════════════════════════════════════${RESET}"
314
- echo ""
315
-
316
- TOTAL=$((PASS + WARN + FAIL))
317
-
318
- echo -e " ${GREEN}${BOLD}${PASS}${RESET} passed ${YELLOW}${BOLD}${WARN}${RESET} warnings ${RED}${BOLD}${FAIL}${RESET} failed ${DIM}(${TOTAL} checks)${RESET}"
319
- echo ""
320
-
321
- if [[ $FAIL -gt 0 ]]; then
322
- error "Some checks failed. Fix the issues above and re-run ${CYAN}shipwright doctor${RESET}"
323
- elif [[ $WARN -gt 0 ]]; then
324
- warn "Setup mostly OK, but there are warnings above"
325
- else
326
- success "Everything looks good!"
327
- fi
328
- echo ""