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
@@ -1,414 +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. Agent Teams
162
- # ═════════════════════════════════════════════════════════════════════════════
163
- echo ""
164
- echo -e "${PURPLE}${BOLD} AGENT TEAMS${RESET}"
165
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
166
-
167
- # Agent teams env var in settings.json
168
- SETTINGS_FILE="$HOME/.claude/settings.json"
169
- if [[ -f "$SETTINGS_FILE" ]]; then
170
- if grep -q 'CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS' "$SETTINGS_FILE" 2>/dev/null; then
171
- check_pass "Agent teams enabled in settings.json"
172
- else
173
- check_fail "Agent teams NOT enabled in settings.json"
174
- echo -e " ${DIM}Run: shipwright init${RESET}"
175
- echo -e " ${DIM}Or add to ~/.claude/settings.json:${RESET}"
176
- echo -e " ${DIM}\"env\": { \"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS\": \"1\" }${RESET}"
177
- fi
178
- else
179
- check_fail "No ~/.claude/settings.json — agent teams not configured"
180
- echo -e " ${DIM}Run: shipwright init${RESET}"
181
- fi
182
-
183
- # CLAUDE.md with Shipwright instructions
184
- GLOBAL_CLAUDE_MD="$HOME/.claude/CLAUDE.md"
185
- if [[ -f "$GLOBAL_CLAUDE_MD" ]]; then
186
- if grep -q "Shipwright" "$GLOBAL_CLAUDE_MD" 2>/dev/null; then
187
- check_pass "CLAUDE.md contains Shipwright instructions"
188
- else
189
- check_warn "CLAUDE.md exists but missing Shipwright instructions"
190
- echo -e " ${DIM}Run: shipwright init${RESET}"
191
- fi
192
- else
193
- check_warn "No ~/.claude/CLAUDE.md — agents won't know Shipwright commands"
194
- echo -e " ${DIM}Run: shipwright init${RESET}"
195
- fi
196
-
197
- # Team templates
198
- TEMPLATES_DIR="$HOME/.shipwright/templates"
199
- if [[ -d "$TEMPLATES_DIR" ]]; then
200
- tpl_count=0
201
- while IFS= read -r f; do
202
- [[ -n "$f" ]] && tpl_count=$((tpl_count + 1))
203
- done < <(find "$TEMPLATES_DIR" -maxdepth 1 -name '*.json' -type f 2>/dev/null)
204
- if [[ $tpl_count -gt 0 ]]; then
205
- check_pass "Team templates: ${tpl_count} installed"
206
- else
207
- check_warn "Template dir exists but no .json files found"
208
- fi
209
- else
210
- check_warn "No team templates at ~/.shipwright/templates/"
211
- echo -e " ${DIM}Run: shipwright init${RESET}"
212
- fi
213
-
214
- # Pipeline templates
215
- PIPELINES_DIR="$HOME/.shipwright/pipelines"
216
- if [[ -d "$PIPELINES_DIR" ]]; then
217
- pip_count=0
218
- while IFS= read -r f; do
219
- [[ -n "$f" ]] && pip_count=$((pip_count + 1))
220
- done < <(find "$PIPELINES_DIR" -maxdepth 1 -name '*.json' -type f 2>/dev/null)
221
- if [[ $pip_count -gt 0 ]]; then
222
- check_pass "Pipeline templates: ${pip_count} installed"
223
- else
224
- check_warn "Pipeline dir exists but no .json files found"
225
- fi
226
- else
227
- check_warn "No pipeline templates at ~/.shipwright/pipelines/"
228
- echo -e " ${DIM}Run: shipwright init${RESET}"
229
- fi
230
-
231
- # GitHub CLI
232
- if command -v gh &>/dev/null; then
233
- if gh auth status &>/dev/null; then
234
- GH_USER="$(gh api user -q .login 2>/dev/null || echo "authenticated")"
235
- check_pass "GitHub CLI: ${GH_USER}"
236
- else
237
- check_warn "GitHub CLI installed but not authenticated"
238
- echo -e " ${DIM}gh auth login${RESET}"
239
- fi
240
- else
241
- check_warn "GitHub CLI (gh) not installed — daemon/pipeline need it for PRs and issues"
242
- echo -e " ${DIM}brew install gh${RESET} (macOS)"
243
- echo -e " ${DIM}sudo apt install gh${RESET} (Ubuntu/Debian)"
244
- fi
245
-
246
- # ═════════════════════════════════════════════════════════════════════════════
247
- # 4. PATH & CLI
248
- # ═════════════════════════════════════════════════════════════════════════════
249
- echo ""
250
- echo -e "${PURPLE}${BOLD} PATH & CLI${RESET}"
251
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
252
-
253
- BIN_DIR="$HOME/.local/bin"
254
-
255
- if echo "$PATH" | tr ':' '\n' | grep -q "$BIN_DIR"; then
256
- check_pass "${BIN_DIR} is in PATH"
257
- else
258
- check_warn "${BIN_DIR} is NOT in PATH"
259
- echo -e " ${DIM}Add to ~/.zshrc or ~/.bashrc:${RESET}"
260
- echo -e " ${DIM}export PATH=\"\$HOME/.local/bin:\$PATH\"${RESET}"
261
- fi
262
-
263
- # Check cct subcommands are installed alongside the router
264
- if command -v cct &>/dev/null; then
265
- CCT_DIR="$(dirname "$(command -v cct)")"
266
- check_pass "shipwright router found at ${CCT_DIR}/cct"
267
-
268
- missing_subs=()
269
- for sub in cct-session.sh cct-status.sh cct-cleanup.sh; do
270
- if [[ ! -x "${CCT_DIR}/${sub}" ]]; then
271
- missing_subs+=("$sub")
272
- fi
273
- done
274
-
275
- if [[ ${#missing_subs[@]} -eq 0 ]]; then
276
- check_pass "All core subcommands installed"
277
- else
278
- check_warn "Missing subcommands: ${missing_subs[*]}"
279
- echo -e " ${DIM}Re-run install.sh or shipwright upgrade --apply${RESET}"
280
- fi
281
- else
282
- check_fail "shipwright command not found in PATH"
283
- echo -e " ${DIM}Re-run install.sh to install the CLI${RESET}"
284
- fi
285
-
286
- # ═════════════════════════════════════════════════════════════════════════════
287
- # 5. Pane Display
288
- # ═════════════════════════════════════════════════════════════════════════════
289
- echo ""
290
- echo -e "${PURPLE}${BOLD} PANE DISPLAY${RESET}"
291
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
292
-
293
- # Check overlay file exists
294
- if [[ -f "$HOME/.tmux/claude-teams-overlay.conf" ]]; then
295
- # Check for set-hook color enforcement
296
- if grep -q "set-hook.*after-split-window" "$HOME/.tmux/claude-teams-overlay.conf" 2>/dev/null; then
297
- check_pass "Overlay has color hooks (set-hook)"
298
- else
299
- check_warn "Overlay missing color hooks — new panes may flash white"
300
- echo -e " ${DIM}Run: shipwright upgrade --apply or shipwright init${RESET}"
301
- fi
302
- else
303
- check_fail "Overlay not found — pane display features unavailable"
304
- fi
305
-
306
- # Check if set-hook commands are active in tmux
307
- if [[ -n "${TMUX:-}" ]]; then
308
- if tmux show-hooks -g 2>/dev/null | grep -q "after-split-window"; then
309
- check_pass "set-hook commands active in tmux"
310
- else
311
- check_warn "set-hook commands not active — reload config: prefix + r"
312
- fi
313
-
314
- # Check default-terminal
315
- TMUX_TERM="$(tmux show-option -gv default-terminal 2>/dev/null || echo "unknown")"
316
- if [[ "$TMUX_TERM" == *"256color"* ]]; then
317
- check_pass "default-terminal: $TMUX_TERM"
318
- else
319
- check_warn "default-terminal: $TMUX_TERM — 256color variant recommended"
320
- echo -e " ${DIM}set -g default-terminal 'tmux-256color'${RESET}"
321
- fi
322
-
323
- # Check pane border includes cyan accent
324
- BORDER_FMT="$(tmux show-option -gv pane-border-format 2>/dev/null || echo "")"
325
- if echo "$BORDER_FMT" | grep -q "#00d4ff"; then
326
- check_pass "Pane border format includes cyan accent"
327
- else
328
- check_warn "Pane border format missing cyan accent — overlay may not be loaded"
329
- fi
330
- else
331
- info "Not in tmux session — skipping runtime display checks"
332
- fi
333
-
334
- # ═════════════════════════════════════════════════════════════════════════════
335
- # 6. Orphaned Sessions
336
- # ═════════════════════════════════════════════════════════════════════════════
337
- echo ""
338
- echo -e "${PURPLE}${BOLD} ORPHAN CHECK${RESET}"
339
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
340
-
341
- orphaned_teams=0
342
- TEAMS_DIR="$HOME/.claude/teams"
343
- if [[ -d "$TEAMS_DIR" ]]; then
344
- while IFS= read -r team_dir; do
345
- [[ -z "$team_dir" ]] && continue
346
- team_name="$(basename "$team_dir")"
347
- config_file="${team_dir}/config.json"
348
- if [[ ! -f "$config_file" ]]; then
349
- orphaned_teams=$((orphaned_teams + 1))
350
- check_warn "Orphaned team dir: ${team_name} (no config.json)"
351
- fi
352
- done < <(find "$TEAMS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null)
353
- fi
354
-
355
- if [[ $orphaned_teams -eq 0 ]]; then
356
- check_pass "No orphaned team sessions"
357
- fi
358
-
359
- # ═════════════════════════════════════════════════════════════════════════════
360
- # 7. Terminal Compatibility
361
- # ═════════════════════════════════════════════════════════════════════════════
362
- echo ""
363
- echo -e "${PURPLE}${BOLD} TERMINAL${RESET}"
364
- echo -e "${DIM} ──────────────────────────────────────────${RESET}"
365
-
366
- TERM_PROGRAM="${TERM_PROGRAM:-unknown}"
367
-
368
- case "$TERM_PROGRAM" in
369
- iTerm.app|iTerm2)
370
- check_pass "iTerm2 — full support"
371
- ;;
372
- Apple_Terminal)
373
- check_pass "Terminal.app — supported"
374
- ;;
375
- WezTerm)
376
- check_pass "WezTerm — full support"
377
- ;;
378
- tmux)
379
- check_pass "Running inside tmux (nested)"
380
- ;;
381
- vscode)
382
- check_warn "VS Code integrated terminal"
383
- echo -e " ${DIM}Some pane border features may not render correctly.${RESET}"
384
- echo -e " ${DIM}Consider running tmux in an external terminal.${RESET}"
385
- ;;
386
- Ghostty)
387
- check_warn "Ghostty — may have tmux rendering quirks"
388
- echo -e " ${DIM}If pane borders look wrong, try: set -g default-terminal 'xterm-256color'${RESET}"
389
- ;;
390
- *)
391
- info "Terminal: ${TERM_PROGRAM}"
392
- ;;
393
- esac
394
-
395
- # ═════════════════════════════════════════════════════════════════════════════
396
- # Summary
397
- # ═════════════════════════════════════════════════════════════════════════════
398
- echo ""
399
- echo -e "${DIM} ══════════════════════════════════════════${RESET}"
400
- echo ""
401
-
402
- TOTAL=$((PASS + WARN + FAIL))
403
-
404
- echo -e " ${GREEN}${BOLD}${PASS}${RESET} passed ${YELLOW}${BOLD}${WARN}${RESET} warnings ${RED}${BOLD}${FAIL}${RESET} failed ${DIM}(${TOTAL} checks)${RESET}"
405
- echo ""
406
-
407
- if [[ $FAIL -gt 0 ]]; then
408
- error "Some checks failed. Fix the issues above and re-run ${CYAN}shipwright doctor${RESET}"
409
- elif [[ $WARN -gt 0 ]]; then
410
- warn "Setup mostly OK, but there are warnings above"
411
- else
412
- success "Everything looks good!"
413
- fi
414
- echo ""