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
@@ -11,6 +11,7 @@ Tracked bugs and limitations in Claude Code Agent Teams + tmux integration, with
11
11
  **Problem:** When Claude Code spawns 4+ agent panes simultaneously using `split-window` + `send-keys`, tmux can deliver keystrokes to the wrong pane. This happens because tmux processes `split-window` and `send-keys` asynchronously — the new pane may not be the active pane by the time `send-keys` fires.
12
12
 
13
13
  **Symptoms:**
14
+
14
15
  - Agent commands appear in the wrong pane
15
16
  - Panes start with garbled or partial commands
16
17
  - Some panes sit empty while others received duplicate input
@@ -38,6 +39,7 @@ tmux send-keys -t "$session" "claude" Enter
38
39
  **Problem:** Agent teams can silently fall back to in-process mode if tmux isn't detected properly. No error is shown — agents just spawn in the same process instead of separate panes.
39
40
 
40
41
  **Symptoms:**
42
+
41
43
  - You're inside tmux but agents don't get their own panes
42
44
  - All agent output appears in a single terminal
43
45
  - No tmux split-windows are created
@@ -68,25 +70,27 @@ If only one pane is listed while agents are active, the fallback occurred.
68
70
  **Severity:** Medium — affects users of these terminals
69
71
 
70
72
  **Problem:** Claude Code's tmux-based agent pane spawning does not work in:
73
+
71
74
  - **VS Code's integrated terminal** — VS Code's terminal emulator doesn't support the tmux control mode and pane management that Claude Code uses for agent teams.
72
75
  - **Ghostty** — As of current versions, Ghostty lacks the tmux integration hooks needed for split-pane agent spawning.
73
76
 
74
77
  **Symptoms:**
78
+
75
79
  - Agent teams silently fall back to in-process mode
76
80
  - No tmux split panes are created
77
81
  - Everything works, but you lose the visual multi-pane experience
78
82
 
79
83
  **Workaround:** Use a supported terminal emulator:
80
84
 
81
- | Terminal | Status | Notes |
82
- |----------|--------|-------|
83
- | **iTerm2** (macOS) | Supported | Recommended for macOS |
84
- | **Alacritty** | Supported | Fast, cross-platform |
85
- | **Kitty** | Supported | Feature-rich, cross-platform |
86
- | **WezTerm** | Supported | Cross-platform, GPU-accelerated |
87
- | **macOS Terminal.app** | Supported | Built-in, basic but works |
88
- | VS Code terminal | Not supported | Use an external terminal |
89
- | Ghostty | Not supported | May be supported in future versions |
85
+ | Terminal | Status | Notes |
86
+ | ---------------------- | ------------- | ----------------------------------- |
87
+ | **iTerm2** (macOS) | Supported | Recommended for macOS |
88
+ | **Alacritty** | Supported | Fast, cross-platform |
89
+ | **Kitty** | Supported | Feature-rich, cross-platform |
90
+ | **WezTerm** | Supported | Cross-platform, GPU-accelerated |
91
+ | **macOS Terminal.app** | Supported | Built-in, basic but works |
92
+ | VS Code terminal | Not supported | Use an external terminal |
93
+ | Ghostty | Not supported | May be supported in future versions |
90
94
 
91
95
  **Tip:** You can run tmux in an external terminal while keeping VS Code open for editing. Claude Code doesn't need to run inside VS Code to work with your project.
92
96
 
@@ -101,6 +105,7 @@ If only one pane is listed while agents are active, the fallback occurred.
101
105
  **Problem:** Each agent in a team uses its own context window. With 3+ agents running complex tasks, individual agents can hit context limits faster than expected, especially if tasks are too broad.
102
106
 
103
107
  **Symptoms:**
108
+
104
109
  - Agent output becomes less coherent toward the end of long tasks
105
110
  - Agents start losing track of earlier context
106
111
  - Auto-compact kicks in frequently
@@ -112,6 +117,7 @@ If only one pane is listed while agents are active, the fallback occurred.
112
117
  2. **Keep tasks focused.** 5-6 specific tasks per agent is the sweet spot. Avoid vague tasks like "improve the codebase."
113
118
 
114
119
  3. **Set aggressive auto-compact:**
120
+
115
121
  ```json
116
122
  {
117
123
  "env": {
@@ -121,6 +127,7 @@ If only one pane is listed while agents are active, the fallback occurred.
121
127
  ```
122
128
 
123
129
  4. **Use haiku for subagent lookups** to save context budget for the main agent:
130
+
124
131
  ```json
125
132
  {
126
133
  "env": {
@@ -143,7 +150,7 @@ If only one pane is listed while agents are active, the fallback occurred.
143
150
 
144
151
  **Root Cause:** tmux's `window-style` applies at the window level but newly spawned panes from external processes (like Claude Code) don't always inherit it.
145
152
 
146
- **Fix:** As of v1.3.0, `claude-teams-overlay.conf` uses `set-hook` to force the dark theme on every new pane:
153
+ **Fix:** As of v1.3.0, `shipwright-overlay.conf` uses `set-hook` to force the dark theme on every new pane:
147
154
 
148
155
  ```conf
149
156
  set-hook -g after-split-window "select-pane -P 'bg=#1a1a2e,fg=#e4e4e7'"
@@ -182,6 +189,7 @@ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
182
189
  **Problem:** When Claude Code teammates shut down (via `shutdown_request` → `shutdown_response`), the Claude process exits but the tmux pane remains open with an idle shell. There is no Claude Code hook event for teammate shutdown — the available hooks (`TeammateIdle`, `TaskCompleted`, `Notification`, `Stop`, etc.) do not fire on agent exit.
183
190
 
184
191
  **Symptoms:**
192
+
185
193
  - After a team finishes work, panes remain with idle shell prompts
186
194
  - `shipwright ps` shows panes as "idle" with increasing idle time
187
195
  - `~/.claude/teams/` and `~/.claude/tasks/` directories accumulate
package/docs/TIPS.md CHANGED
@@ -9,36 +9,43 @@ Patterns and tricks for getting the most out of Claude Code Agent Teams with tmu
9
9
  Based on [Addy Osmani's research](https://addyosmani.com/blog/claude-code-agent-teams/) and community experience:
10
10
 
11
11
  ### When Teams Add Value
12
+
12
13
  - **Competing hypotheses** — Multiple agents investigating different theories for a bug
13
14
  - **Parallel review** — Security, performance, and test coverage by dedicated reviewers
14
15
  - **Cross-layer features** — Frontend, backend, and tests developed simultaneously
15
16
 
16
17
  ### When to Stay Single-Agent
18
+
17
19
  - Sequential, tightly-coupled work where each step depends on the last
18
20
  - Simple bugs or single-file changes
19
21
  - Tasks where coordination overhead exceeds the parallel benefit
20
22
 
21
23
  ### The Task Sizing Sweet Spot
24
+
22
25
  Too small and coordination overhead dominates. Too large and agents work too long without check-ins. Aim for **5-6 focused tasks per agent** with clear deliverables.
23
26
 
24
27
  ### Specification Quality = Output Quality
25
- Detailed spawn prompts with technical constraints, acceptance criteria, and domain context produce dramatically better results. Don't just say "fix the tests" — say "fix the auth tests in src/auth/__tests__/, ensuring all edge cases for expired tokens are covered, using the existing MockAuthProvider pattern."
28
+
29
+ Detailed spawn prompts with technical constraints, acceptance criteria, and domain context produce dramatically better results. Don't just say "fix the tests" — say "fix the auth tests in src/auth/**tests**/, ensuring all edge cases for expired tokens are covered, using the existing MockAuthProvider pattern."
26
30
 
27
31
  ---
28
32
 
29
33
  ## Hook Patterns for Teams
30
34
 
31
35
  ### Quality Gates (Most Valuable)
36
+
32
37
  - **TeammateIdle** — Run typecheck before letting agents idle. Catches errors early.
33
38
  - **TaskCompleted** — Run lint + related tests before allowing task completion.
34
39
  - **Stop** — Verify all work is complete before Claude stops responding.
35
40
 
36
41
  ### Observability
42
+
37
43
  - **Notification** — Desktop alerts so you can work on other things.
38
44
  - **PostToolUse** on `Bash` — Log all commands agents run to a file.
39
45
  - **SubagentStart/SubagentStop** — Track when agents spawn and finish.
40
46
 
41
47
  ### Context Preservation
48
+
42
49
  - **PreCompact** — Save git status, recent commits, and project reminders before compaction.
43
50
  - **SessionStart** on `compact` — Re-inject critical context after compaction.
44
51
 
@@ -124,7 +131,7 @@ This compacts the conversation when it hits 70% of the context window (default i
124
131
 
125
132
  ### Watch all agents at once
126
133
 
127
- Use `shipwright status` (alias: `cct`, `sw`) to see a dashboard of running team sessions:
134
+ Use `shipwright status` (alias: `sw`, `cct`) to see a dashboard of running team sessions:
128
135
 
129
136
  ```bash
130
137
  shipwright status
@@ -139,6 +146,7 @@ Press `prefix + G` to toggle zoom on the current pane. This makes one agent fill
139
146
  ### Synchronized input
140
147
 
141
148
  Press `prefix + Alt-t` to toggle synchronized panes. When enabled, anything you type goes to ALL panes simultaneously. Useful for:
149
+
142
150
  - Stopping all agents at once (`Ctrl-C` in all panes)
143
151
  - Running the same command in all agent directories
144
152
 
@@ -246,17 +254,17 @@ shipwright cleanup --force # Actually kills orphaned sessions
246
254
 
247
255
  ## Environment Variables Reference
248
256
 
249
- | Variable | Default | What it does |
250
- |----------|---------|--------------|
251
- | `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` | — | **Required.** Enables agent teams feature |
252
- | `CLAUDE_CODE_SUBAGENT_MODEL` | (parent model) | Model for subagent lookups. Set to `"haiku"` to save money |
253
- | `CLAUDE_CODE_AUTOCOMPACT_PCT_OVERRIDE` | `"80"` | Context compaction threshold. Lower = more aggressive |
254
- | `CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY` | `"3"` | Parallel tool calls per agent. Higher = faster but more API usage |
255
- | `CLAUDE_CODE_GLOB_HIDDEN` | — | Include dotfiles in glob searches |
256
- | `CLAUDE_CODE_BASH_MAINTAIN_PROJECT_WORKING_DIR` | — | Keep bash cwd consistent across tool calls |
257
- | `CLAUDE_CODE_EMIT_TOOL_USE_SUMMARIES` | — | Show tool use summaries in output |
258
- | `CLAUDE_CODE_TST_NAMES_IN_MESSAGES` | — | Show teammate names in messages |
259
- | `CLAUDE_CODE_EAGER_FLUSH` | — | Flush output eagerly (reduces perceived latency) |
257
+ | Variable | Default | What it does |
258
+ | ----------------------------------------------- | -------------- | ----------------------------------------------------------------- |
259
+ | `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` | — | **Required.** Enables agent teams feature |
260
+ | `CLAUDE_CODE_SUBAGENT_MODEL` | (parent model) | Model for subagent lookups. Set to `"haiku"` to save money |
261
+ | `CLAUDE_CODE_AUTOCOMPACT_PCT_OVERRIDE` | `"80"` | Context compaction threshold. Lower = more aggressive |
262
+ | `CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY` | `"3"` | Parallel tool calls per agent. Higher = faster but more API usage |
263
+ | `CLAUDE_CODE_GLOB_HIDDEN` | — | Include dotfiles in glob searches |
264
+ | `CLAUDE_CODE_BASH_MAINTAIN_PROJECT_WORKING_DIR` | — | Keep bash cwd consistent across tool calls |
265
+ | `CLAUDE_CODE_EMIT_TOOL_USE_SUMMARIES` | — | Show tool use summaries in output |
266
+ | `CLAUDE_CODE_TST_NAMES_IN_MESSAGES` | — | Show teammate names in messages |
267
+ | `CLAUDE_CODE_EAGER_FLUSH` | — | Flush output eagerly (reduces perceived latency) |
260
268
 
261
269
  ---
262
270
 
@@ -290,14 +298,17 @@ started_at: 2026-02-07T10:00:00Z
290
298
  ---
291
299
 
292
300
  ## Completed
301
+
293
302
  - [x] Scanned existing auth patterns
294
303
  - [x] Built User model
295
304
 
296
305
  ## In Progress
306
+
297
307
  - [ ] JWT route handlers
298
308
  - [ ] React login components
299
309
 
300
310
  ## Blocked
311
+
301
312
  - Integration tests blocked on route completion
302
313
  ```
303
314
 
@@ -306,6 +317,7 @@ started_at: 2026-02-07T10:00:00Z
306
317
  Each agent writes findings/results to a file in this directory. The team lead reads all outputs between waves.
307
318
 
308
319
  **Add to `.gitignore`:**
320
+
309
321
  ```
310
322
  .claude/team-state.local.md
311
323
  .claude/team-outputs/
@@ -313,19 +325,19 @@ Each agent writes findings/results to a file in this directory. The team lead re
313
325
 
314
326
  ### When to Use Waves vs. Single-Pass Teams
315
327
 
316
- | Situation | Approach |
317
- |-----------|----------|
318
- | Independent tasks with clear file ownership | Single-pass team — spawn agents, collect results |
319
- | Tasks that require iteration (tests must pass, errors must be fixed) | Wave pattern — iterate until completion criteria met |
320
- | Exploratory work that builds on previous findings | Wave pattern — each wave goes deeper based on last wave's results |
321
- | Simple parallel review (code quality + security + tests) | Single-pass team — each reviewer works independently |
328
+ | Situation | Approach |
329
+ | -------------------------------------------------------------------- | ----------------------------------------------------------------- |
330
+ | Independent tasks with clear file ownership | Single-pass team — spawn agents, collect results |
331
+ | Tasks that require iteration (tests must pass, errors must be fixed) | Wave pattern — iterate until completion criteria met |
332
+ | Exploratory work that builds on previous findings | Wave pattern — each wave goes deeper based on last wave's results |
333
+ | Simple parallel review (code quality + security + tests) | Single-pass team — each reviewer works independently |
322
334
 
323
335
  ### Quick Reference: Five Wave Patterns
324
336
 
325
- | Pattern | Waves | Agents | Best For |
326
- |---------|-------|--------|----------|
327
- | [Feature Implementation](patterns/feature-implementation.md) | 3-4 | 2-3 | Multi-component features |
328
- | [Research & Exploration](patterns/research-exploration.md) | 2-3 | 2-3 | Understanding codebases |
329
- | [Test Generation](patterns/test-generation.md) | 3-4+ | 2-3 | Coverage campaigns |
330
- | [Refactoring](patterns/refactoring.md) | 3-4 | 2 | Large-scale transformations |
331
- | [Bug Hunt](patterns/bug-hunt.md) | 3-4 | 2-3 | Complex, elusive bugs |
337
+ | Pattern | Waves | Agents | Best For |
338
+ | ------------------------------------------------------------ | ----- | ------ | --------------------------- |
339
+ | [Feature Implementation](patterns/feature-implementation.md) | 3-4 | 2-3 | Multi-component features |
340
+ | [Research & Exploration](patterns/research-exploration.md) | 2-3 | 2-3 | Understanding codebases |
341
+ | [Test Generation](patterns/test-generation.md) | 3-4+ | 2-3 | Coverage campaigns |
342
+ | [Refactoring](patterns/refactoring.md) | 3-4 | 2 | Large-scale transformations |
343
+ | [Bug Hunt](patterns/bug-hunt.md) | 3-4 | 2-3 | Complex, elusive bugs |
@@ -18,6 +18,7 @@ Wave 1: Research Wave 2: Build Wave 3: Integrate
18
18
  ```
19
19
 
20
20
  Each wave:
21
+
21
22
  1. **Assess** — What did the previous wave accomplish? What failed?
22
23
  2. **Decompose** — What can be done in parallel now?
23
24
  3. **Spawn** — Launch agents in tmux panes for each independent task
@@ -27,13 +28,13 @@ Each wave:
27
28
 
28
29
  ## Available Patterns
29
30
 
30
- | Pattern | When to Use | Typical Waves | Team Size |
31
- |---------|-------------|---------------|-----------|
32
- | [Feature Implementation](feature-implementation.md) | Building multi-component features | 3-4 | 2-3 agents |
33
- | [Research & Exploration](research-exploration.md) | Understanding a codebase or problem space | 2-3 | 2-3 agents |
34
- | [Test Generation](test-generation.md) | Comprehensive test coverage campaigns | 3-4+ | 2-3 agents |
35
- | [Refactoring](refactoring.md) | Large-scale code transformations | 3-4 | 2 agents |
36
- | [Bug Hunt](bug-hunt.md) | Tracking down complex, elusive bugs | 3-4 | 2-3 agents |
31
+ | Pattern | When to Use | Typical Waves | Team Size |
32
+ | --------------------------------------------------- | ----------------------------------------- | ------------- | ---------- |
33
+ | [Feature Implementation](feature-implementation.md) | Building multi-component features | 3-4 | 2-3 agents |
34
+ | [Research & Exploration](research-exploration.md) | Understanding a codebase or problem space | 2-3 | 2-3 agents |
35
+ | [Test Generation](test-generation.md) | Comprehensive test coverage campaigns | 3-4+ | 2-3 agents |
36
+ | [Refactoring](refactoring.md) | Large-scale code transformations | 3-4 | 2 agents |
37
+ | [Bug Hunt](bug-hunt.md) | Tracking down complex, elusive bugs | 3-4 | 2-3 agents |
37
38
 
38
39
  ---
39
40
 
@@ -52,18 +53,22 @@ started_at: 2026-02-07T10:00:00Z
52
53
  ---
53
54
 
54
55
  ## Completed
56
+
55
57
  - [x] Scanned existing auth patterns
56
58
  - [x] Identified middleware structure
57
59
  - [x] Built User model
58
60
 
59
61
  ## In Progress
62
+
60
63
  - [ ] JWT route handlers
61
64
  - [ ] Login/signup React components
62
65
 
63
66
  ## Blocked
67
+
64
68
  - None
65
69
 
66
70
  ## Agent Outputs
71
+
67
72
  - wave-1-scan-auth.md — Existing auth analysis
68
73
  - wave-1-scan-deps.md — Dependency audit
69
74
  - wave-2-model.md — User model implementation notes
@@ -79,7 +84,7 @@ Each agent writes its results to a markdown file in this directory. The team lea
79
84
 
80
85
  ## Quick Start
81
86
 
82
- Pick a pattern, then use `shipwright` (alias: `cct`, `sw`) to set up the team:
87
+ Pick a pattern, then use `shipwright` (alias: `sw`, `cct`) to set up the team:
83
88
 
84
89
  ```bash
85
90
  # Start a tmux session
@@ -97,32 +102,37 @@ shipwright session my-feature
97
102
  ## Key Principles
98
103
 
99
104
  ### 1. Parallel Everything
105
+
100
106
  If two tasks don't depend on each other, run them at the same time in separate panes. The whole point of waves is maximizing parallel throughput.
101
107
 
102
108
  ### 2. Synthesize Between Waves
109
+
103
110
  Don't just fire-and-forget. After each wave, the team lead reads all agent outputs, identifies gaps, and adjusts the plan. This is where the real value happens.
104
111
 
105
112
  ### 3. Iterate Until Done
113
+
106
114
  Waves repeat until the goal is met. Failed tasks get retried with better instructions. Each wave builds on the last. Set a reasonable max (5-10 waves for most tasks).
107
115
 
108
116
  ### 4. File-Based State Is the Source of Truth
117
+
109
118
  The `.claude/team-state.local.md` file tracks what's done, what's pending, and what's blocked. Agents update their output files; the team lead updates the state file.
110
119
 
111
120
  ### 5. Keep Teams Small
121
+
112
122
  2-3 agents per team. More agents means more tmux panes, more coordination overhead, and more risk of file conflicts. The sweet spot is 2-3 focused agents.
113
123
 
114
124
  ---
115
125
 
116
126
  ## Anti-Patterns
117
127
 
118
- | Don't | Why | Instead |
119
- |-------|-----|---------|
120
- | Spawn 5+ agents per wave | Coordination overhead, race conditions | 2-3 agents per wave |
121
- | Skip synthesis between waves | You'll lose track of progress and duplicate work | Always read outputs and update state |
122
- | Give vague task descriptions | Agents waste context figuring out what to do | Be specific: files, functions, acceptance criteria |
123
- | Let agents touch overlapping files | One will overwrite the other's changes | Partition files by agent |
124
- | Keep iterating when stuck | Wastes tokens and your time | After 3 failed attempts, rethink the approach |
125
- | Use waves for trivial tasks | Overhead exceeds benefit | Just do it in a single agent |
128
+ | Don't | Why | Instead |
129
+ | ---------------------------------- | ------------------------------------------------ | -------------------------------------------------- |
130
+ | Spawn 5+ agents per wave | Coordination overhead, race conditions | 2-3 agents per wave |
131
+ | Skip synthesis between waves | You'll lose track of progress and duplicate work | Always read outputs and update state |
132
+ | Give vague task descriptions | Agents waste context figuring out what to do | Be specific: files, functions, acceptance criteria |
133
+ | Let agents touch overlapping files | One will overwrite the other's changes | Partition files by agent |
134
+ | Keep iterating when stuck | Wastes tokens and your time | After 3 failed attempts, rethink the approach |
135
+ | Use waves for trivial tasks | Overhead exceeds benefit | Just do it in a single agent |
126
136
 
127
137
  ---
128
138
 
@@ -130,10 +140,10 @@ The `.claude/team-state.local.md` file tracks what's done, what's pending, and w
130
140
 
131
141
  Choose the right model for each agent's task:
132
142
 
133
- | Task Type | Model | Why |
134
- |-----------|-------|-----|
135
- | File search, simple lookups | `haiku` | Fast, cheap |
136
- | Implementation, clear requirements | `sonnet` | Balanced speed/quality |
137
- | Architecture decisions, complex debugging | `opus` | Best reasoning |
138
- | Test generation | `sonnet` | Good pattern matching |
139
- | Documentation, reports | `sonnet` | Clear writing |
143
+ | Task Type | Model | Why |
144
+ | ----------------------------------------- | -------- | ---------------------- |
145
+ | File search, simple lookups | `haiku` | Fast, cheap |
146
+ | Implementation, clear requirements | `sonnet` | Balanced speed/quality |
147
+ | Architecture decisions, complex debugging | `opus` | Best reasoning |
148
+ | Test generation | `sonnet` | Good pattern matching |
149
+ | Documentation, reports | `sonnet` | Clear writing |
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "shipwright-cli",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "description": "Orchestrate autonomous Claude Code agent teams in tmux",
5
5
  "bin": {
6
- "shipwright": "./scripts/cct",
7
- "sw": "./scripts/cct"
6
+ "shipwright": "./scripts/sw",
7
+ "sw": "./scripts/sw",
8
+ "cct": "./scripts/sw"
8
9
  },
9
10
  "files": [
10
11
  "scripts/",
@@ -16,8 +17,11 @@
16
17
  "templates/",
17
18
  "tmux/templates/",
18
19
  "tmux/tmux.conf",
19
- "tmux/claude-teams-overlay.conf",
20
+ "tmux/shipwright-overlay.conf",
21
+ "dashboard/",
20
22
  "claude-code/",
23
+ ".claude/agents/",
24
+ ".claude/hooks/",
21
25
  "completions/",
22
26
  "docs/",
23
27
  "LICENSE",
@@ -25,7 +29,7 @@
25
29
  ],
26
30
  "scripts": {
27
31
  "postinstall": "node scripts/postinstall.mjs",
28
- "test": "bash scripts/cct-pipeline-test.sh && bash scripts/cct-daemon-test.sh && bash scripts/cct-prep-test.sh && bash scripts/cct-fleet-test.sh && bash scripts/cct-fix-test.sh && bash scripts/cct-memory-test.sh"
32
+ "test": "bash scripts/sw-pipeline-test.sh && bash scripts/sw-daemon-test.sh && bash scripts/sw-prep-test.sh && bash scripts/sw-fleet-test.sh && bash scripts/sw-fix-test.sh && bash scripts/sw-memory-test.sh && bash scripts/sw-session-test.sh && bash scripts/sw-init-test.sh && bash scripts/sw-tracker-test.sh && bash scripts/sw-heartbeat-test.sh && bash scripts/sw-remote-test.sh && bash scripts/sw-intelligence-test.sh && bash scripts/sw-pipeline-composer-test.sh && bash scripts/sw-self-optimize-test.sh && bash scripts/sw-predictive-test.sh && bash scripts/sw-frontier-test.sh && bash scripts/sw-connect-test.sh && bash scripts/sw-github-graphql-test.sh && bash scripts/sw-github-checks-test.sh && bash scripts/sw-github-deploy-test.sh && bash scripts/sw-docs-test.sh && bash scripts/sw-tmux-test.sh"
29
33
  },
30
34
  "keywords": [
31
35
  "claude",
@@ -4,7 +4,7 @@
4
4
  # ║ ║
5
5
  # ║ Uses AppleScript (osascript) to create iTerm2 tabs with named titles ║
6
6
  # ║ and working directories. macOS only. ║
7
- # ║ Sourced by cct-session.sh — exports: spawn_agent, list_agents, ║
7
+ # ║ Sourced by sw-session.sh — exports: spawn_agent, list_agents, ║
8
8
  # ║ kill_agent, focus_agent. ║
9
9
  # ╚═══════════════════════════════════════════════════════════════════════════╝
10
10
 
@@ -3,37 +3,52 @@
3
3
  # ║ tmux-adapter.sh — Terminal adapter for tmux pane management ║
4
4
  # ║ ║
5
5
  # ║ Default adapter. Creates tmux panes within a named window. ║
6
- # ║ Sourced by cct-session.sh — exports: spawn_agent, list_agents, ║
6
+ # ║ Sourced by sw-session.sh — exports: spawn_agent, list_agents, ║
7
7
  # ║ kill_agent, focus_agent. ║
8
+ # ║ ║
9
+ # ║ Uses pane IDs (%N) instead of indices to avoid the pane-base-index ║
10
+ # ║ bug where teammate instructions are sent to wrong panes when ║
11
+ # ║ pane-base-index != 0. See: claude-code#23527 ║
8
12
  # ╚═══════════════════════════════════════════════════════════════════════════╝
9
13
 
10
- # Track spawned panes by agent name
11
- declare -A _TMUX_AGENT_PANES
14
+ # Track spawned panes by agent name → pane ID (file-based for bash 3.2 compat)
15
+ _TMUX_PANE_MAP="${TMPDIR:-/tmp}/shipwright-tmux-pane-map.$$"
16
+ : > "$_TMUX_PANE_MAP"
17
+ trap 'rm -f "$_TMUX_PANE_MAP"' EXIT
12
18
 
13
19
  spawn_agent() {
14
20
  local name="$1"
15
21
  local working_dir="${2:-#{pane_current_path}}"
16
22
  local command="${3:-}"
17
23
 
18
- # If no window exists yet, create one
24
+ local new_pane_id=""
25
+
26
+ # If no window exists yet, create one and capture the pane ID
19
27
  if ! tmux list-windows -F '#W' 2>/dev/null | grep -qx "$WINDOW_NAME"; then
20
- tmux new-window -n "$WINDOW_NAME" -c "$working_dir"
28
+ # -P prints the new pane's ID (e.g. %5)
29
+ new_pane_id=$(tmux new-window -n "$WINDOW_NAME" -c "$working_dir" -P -F '#{pane_id}')
21
30
  else
22
- # Split the current window to add a pane
23
- tmux split-window -t "$WINDOW_NAME" -c "$working_dir"
31
+ # Split the current window and capture the new pane ID
32
+ new_pane_id=$(tmux split-window -t "$WINDOW_NAME" -c "$working_dir" -P -F '#{pane_id}')
24
33
  fi
25
34
 
35
+ # Record the mapping: name → pane_id
36
+ echo "${name}=${new_pane_id}" >> "$_TMUX_PANE_MAP"
37
+
26
38
  sleep 0.1
27
39
 
28
- # Set the pane title
29
- tmux send-keys -t "$WINDOW_NAME" "printf '\\033]2;${name}\\033\\\\'" Enter
40
+ # Set the pane title using the stable pane ID (not index)
41
+ tmux send-keys -t "$new_pane_id" "printf '\\033]2;${name}\\033\\\\'" Enter
30
42
  sleep 0.1
31
- tmux send-keys -t "$WINDOW_NAME" "clear" Enter
43
+ tmux send-keys -t "$new_pane_id" "clear" Enter
44
+
45
+ # Apply dark theme to the new pane
46
+ tmux select-pane -t "$new_pane_id" -P 'bg=#1a1a2e,fg=#e4e4e7' 2>/dev/null || true
32
47
 
33
48
  # Run the command if provided
34
49
  if [[ -n "$command" ]]; then
35
50
  sleep 0.1
36
- tmux send-keys -t "$WINDOW_NAME" "$command" Enter
51
+ tmux send-keys -t "$new_pane_id" "$command" Enter
37
52
  fi
38
53
 
39
54
  # Re-tile after adding each pane
@@ -41,9 +56,9 @@ spawn_agent() {
41
56
  }
42
57
 
43
58
  list_agents() {
44
- # List all panes in the window with their titles
59
+ # List all panes in the window with their titles and IDs
45
60
  if tmux list-windows -F '#W' 2>/dev/null | grep -qx "$WINDOW_NAME"; then
46
- tmux list-panes -t "$WINDOW_NAME" -F '#{pane_index}: #{pane_title} (#{pane_current_command})' 2>/dev/null
61
+ tmux list-panes -t "$WINDOW_NAME" -F '#{pane_id}: #{pane_title} (#{pane_current_command})' 2>/dev/null
47
62
  fi
48
63
  }
49
64
 
@@ -54,10 +69,17 @@ kill_agent() {
54
69
  return 1
55
70
  fi
56
71
 
57
- # Find the pane with the matching title
58
- local pane_id
59
- pane_id=$(tmux list-panes -t "$WINDOW_NAME" -F '#{pane_id} #{pane_title}' 2>/dev/null \
60
- | grep " ${name}$" | head -1 | cut -d' ' -f1)
72
+ # First try: look up from our pane map
73
+ local pane_id=""
74
+ if [[ -f "$_TMUX_PANE_MAP" ]]; then
75
+ pane_id=$(grep "^${name}=" "$_TMUX_PANE_MAP" 2>/dev/null | tail -1 | cut -d= -f2) || true
76
+ fi
77
+
78
+ # Fallback: find the pane with the matching title (handles external spawns)
79
+ if [[ -z "$pane_id" ]]; then
80
+ pane_id=$(tmux list-panes -t "$WINDOW_NAME" -F '#{pane_id} #{pane_title}' 2>/dev/null \
81
+ | grep " ${name}$" | head -1 | cut -d' ' -f1) || true
82
+ fi
61
83
 
62
84
  if [[ -n "$pane_id" ]]; then
63
85
  tmux kill-pane -t "$pane_id"
@@ -73,14 +95,21 @@ focus_agent() {
73
95
  return 1
74
96
  fi
75
97
 
76
- # Find the pane with the matching title
77
- local pane_index
78
- pane_index=$(tmux list-panes -t "$WINDOW_NAME" -F '#{pane_index} #{pane_title}' 2>/dev/null \
79
- | grep " ${name}$" | head -1 | cut -d' ' -f1)
98
+ # First try: look up from our pane map
99
+ local pane_id=""
100
+ if [[ -f "$_TMUX_PANE_MAP" ]]; then
101
+ pane_id=$(grep "^${name}=" "$_TMUX_PANE_MAP" 2>/dev/null | tail -1 | cut -d= -f2) || true
102
+ fi
80
103
 
81
- if [[ -n "$pane_index" ]]; then
104
+ # Fallback: find the pane by title
105
+ if [[ -z "$pane_id" ]]; then
106
+ pane_id=$(tmux list-panes -t "$WINDOW_NAME" -F '#{pane_id} #{pane_title}' 2>/dev/null \
107
+ | grep " ${name}$" | head -1 | cut -d' ' -f1) || true
108
+ fi
109
+
110
+ if [[ -n "$pane_id" ]]; then
82
111
  tmux select-window -t "$WINDOW_NAME"
83
- tmux select-pane -t "$WINDOW_NAME.$pane_index"
112
+ tmux select-pane -t "$pane_id"
84
113
  return 0
85
114
  fi
86
115
  return 1
@@ -4,7 +4,7 @@
4
4
  # ║ ║
5
5
  # ║ Uses `wezterm cli` to spawn panes/tabs with named titles and working ║
6
6
  # ║ directories. Cross-platform. ║
7
- # ║ Sourced by cct-session.sh — exports: spawn_agent, list_agents, ║
7
+ # ║ Sourced by sw-session.sh — exports: spawn_agent, list_agents, ║
8
8
  # ║ kill_agent, focus_agent. ║
9
9
  # ╚═══════════════════════════════════════════════════════════════════════════╝
10
10
 
@@ -14,8 +14,10 @@ if ! command -v wezterm &>/dev/null; then
14
14
  exit 1
15
15
  fi
16
16
 
17
- # Track spawned pane IDs for agent management
18
- declare -A _WEZTERM_AGENT_PANES
17
+ # Track spawned pane IDs for agent management (file-based for bash 3.2 compat)
18
+ _WEZTERM_PANE_MAP="${TMPDIR:-/tmp}/shipwright-wezterm-pane-map.$$"
19
+ : > "$_WEZTERM_PANE_MAP"
20
+ trap 'rm -f "$_WEZTERM_PANE_MAP"' EXIT
19
21
 
20
22
  spawn_agent() {
21
23
  local name="$1"
@@ -30,12 +32,16 @@ spawn_agent() {
30
32
  local pane_id
31
33
 
32
34
  # Spawn a new pane in the current tab (split right by default)
33
- if [[ ${#_WEZTERM_AGENT_PANES[@]} -eq 0 ]]; then
35
+ local pane_count
36
+ pane_count=$(wc -l < "$_WEZTERM_PANE_MAP" 2>/dev/null | tr -d ' ')
37
+ pane_count="${pane_count:-0}"
38
+ if [[ "$pane_count" -eq 0 ]]; then
34
39
  # First agent: create a new tab
35
40
  pane_id=$(wezterm cli spawn --cwd "$working_dir" 2>/dev/null)
36
41
  else
37
42
  # Subsequent agents: split from the first pane
38
- local first_pane="${_WEZTERM_AGENT_PANES[${!_WEZTERM_AGENT_PANES[*]}]}"
43
+ local first_pane
44
+ first_pane=$(head -1 "$_WEZTERM_PANE_MAP" 2>/dev/null | cut -d= -f2-)
39
45
  pane_id=$(wezterm cli split-pane --cwd "$working_dir" --right --pane-id "${first_pane:-0}" 2>/dev/null) || \
40
46
  pane_id=$(wezterm cli split-pane --cwd "$working_dir" --bottom 2>/dev/null)
41
47
  fi
@@ -45,8 +51,8 @@ spawn_agent() {
45
51
  return 1
46
52
  fi
47
53
 
48
- # Store mapping
49
- _WEZTERM_AGENT_PANES["$name"]="$pane_id"
54
+ # Store mapping (file-based)
55
+ echo "${name}=${pane_id}" >> "$_WEZTERM_PANE_MAP"
50
56
 
51
57
  # Set the pane title
52
58
  wezterm cli set-tab-title --pane-id "$pane_id" "$name" 2>/dev/null || true
@@ -70,30 +76,36 @@ list_agents() {
70
76
  done
71
77
 
72
78
  # Also show our tracked agents
73
- if [[ ${#_WEZTERM_AGENT_PANES[@]} -gt 0 ]]; then
79
+ if [[ -s "$_WEZTERM_PANE_MAP" ]]; then
74
80
  echo ""
75
81
  echo "Tracked agents:"
76
- for name in "${!_WEZTERM_AGENT_PANES[@]}"; do
77
- echo " ${name} → pane ${_WEZTERM_AGENT_PANES[$name]}"
78
- done
82
+ while IFS='=' read -r _name _pid; do
83
+ echo " ${_name} → pane ${_pid}"
84
+ done < "$_WEZTERM_PANE_MAP"
79
85
  fi
80
86
  }
81
87
 
82
88
  kill_agent() {
83
89
  local name="$1"
84
- local pane_id="${_WEZTERM_AGENT_PANES[$name]:-}"
90
+ local pane_id
91
+ pane_id=$(grep "^${name}=" "$_WEZTERM_PANE_MAP" 2>/dev/null | head -1 | cut -d= -f2-)
85
92
 
86
93
  if [[ -z "$pane_id" ]]; then
87
94
  return 1
88
95
  fi
89
96
 
90
97
  wezterm cli kill-pane --pane-id "$pane_id" 2>/dev/null
91
- unset '_WEZTERM_AGENT_PANES[$name]'
98
+ # Remove entry from pane map
99
+ local _tmp
100
+ _tmp=$(mktemp)
101
+ grep -v "^${name}=" "$_WEZTERM_PANE_MAP" > "$_tmp" 2>/dev/null || true
102
+ mv "$_tmp" "$_WEZTERM_PANE_MAP"
92
103
  }
93
104
 
94
105
  focus_agent() {
95
106
  local name="$1"
96
- local pane_id="${_WEZTERM_AGENT_PANES[$name]:-}"
107
+ local pane_id
108
+ pane_id=$(grep "^${name}=" "$_WEZTERM_PANE_MAP" 2>/dev/null | head -1 | cut -d= -f2-)
97
109
 
98
110
  if [[ -z "$pane_id" ]]; then
99
111
  return 1