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.
- package/.claude/agents/code-reviewer.md +90 -0
- package/.claude/agents/devops-engineer.md +142 -0
- package/.claude/agents/pipeline-agent.md +80 -0
- package/.claude/agents/shell-script-specialist.md +150 -0
- package/.claude/agents/test-specialist.md +196 -0
- package/.claude/hooks/post-tool-use.sh +38 -0
- package/.claude/hooks/pre-tool-use.sh +25 -0
- package/.claude/hooks/session-started.sh +37 -0
- package/README.md +212 -814
- package/claude-code/CLAUDE.md.shipwright +54 -0
- package/claude-code/hooks/notify-idle.sh +2 -2
- package/claude-code/hooks/session-start.sh +24 -0
- package/claude-code/hooks/task-completed.sh +6 -2
- package/claude-code/settings.json.template +12 -0
- package/dashboard/public/app.js +4422 -0
- package/dashboard/public/index.html +816 -0
- package/dashboard/public/styles.css +4755 -0
- package/dashboard/server.ts +4315 -0
- package/docs/KNOWN-ISSUES.md +18 -10
- package/docs/TIPS.md +38 -26
- package/docs/patterns/README.md +33 -23
- package/package.json +9 -5
- package/scripts/adapters/iterm2-adapter.sh +1 -1
- package/scripts/adapters/tmux-adapter.sh +52 -23
- package/scripts/adapters/wezterm-adapter.sh +26 -14
- package/scripts/lib/compat.sh +200 -0
- package/scripts/lib/helpers.sh +72 -0
- package/scripts/postinstall.mjs +72 -13
- package/scripts/{cct → sw} +109 -21
- package/scripts/sw-adversarial.sh +274 -0
- package/scripts/sw-architecture-enforcer.sh +330 -0
- package/scripts/sw-checkpoint.sh +390 -0
- package/scripts/{cct-cleanup.sh → sw-cleanup.sh} +3 -1
- package/scripts/sw-connect.sh +619 -0
- package/scripts/{cct-cost.sh → sw-cost.sh} +368 -34
- package/scripts/{cct-daemon.sh → sw-daemon.sh} +2217 -204
- package/scripts/sw-dashboard.sh +477 -0
- package/scripts/sw-developer-simulation.sh +252 -0
- package/scripts/sw-docs.sh +635 -0
- package/scripts/sw-doctor.sh +907 -0
- package/scripts/{cct-fix.sh → sw-fix.sh} +10 -6
- package/scripts/{cct-fleet.sh → sw-fleet.sh} +498 -22
- package/scripts/sw-github-checks.sh +521 -0
- package/scripts/sw-github-deploy.sh +533 -0
- package/scripts/sw-github-graphql.sh +972 -0
- package/scripts/sw-heartbeat.sh +293 -0
- package/scripts/{cct-init.sh → sw-init.sh} +144 -11
- package/scripts/sw-intelligence.sh +1196 -0
- package/scripts/sw-jira.sh +643 -0
- package/scripts/sw-launchd.sh +364 -0
- package/scripts/sw-linear.sh +648 -0
- package/scripts/{cct-logs.sh → sw-logs.sh} +72 -2
- package/scripts/{cct-loop.sh → sw-loop.sh} +534 -44
- package/scripts/{cct-memory.sh → sw-memory.sh} +321 -38
- package/scripts/sw-patrol-meta.sh +417 -0
- package/scripts/sw-pipeline-composer.sh +455 -0
- package/scripts/{cct-pipeline.sh → sw-pipeline.sh} +2319 -178
- package/scripts/sw-predictive.sh +820 -0
- package/scripts/{cct-prep.sh → sw-prep.sh} +339 -49
- package/scripts/{cct-ps.sh → sw-ps.sh} +6 -4
- package/scripts/{cct-reaper.sh → sw-reaper.sh} +6 -4
- package/scripts/sw-remote.sh +687 -0
- package/scripts/sw-self-optimize.sh +947 -0
- package/scripts/sw-session.sh +519 -0
- package/scripts/sw-setup.sh +234 -0
- package/scripts/sw-status.sh +605 -0
- package/scripts/{cct-templates.sh → sw-templates.sh} +9 -4
- package/scripts/sw-tmux.sh +591 -0
- package/scripts/sw-tracker-jira.sh +277 -0
- package/scripts/sw-tracker-linear.sh +292 -0
- package/scripts/sw-tracker.sh +409 -0
- package/scripts/{cct-upgrade.sh → sw-upgrade.sh} +103 -46
- package/scripts/{cct-worktree.sh → sw-worktree.sh} +3 -0
- package/templates/pipelines/autonomous.json +27 -5
- package/templates/pipelines/full.json +12 -0
- package/templates/pipelines/standard.json +12 -0
- package/tmux/{claude-teams-overlay.conf → shipwright-overlay.conf} +27 -9
- package/tmux/templates/accessibility.json +34 -0
- package/tmux/templates/api-design.json +35 -0
- package/tmux/templates/architecture.json +1 -0
- package/tmux/templates/bug-fix.json +9 -0
- package/tmux/templates/code-review.json +1 -0
- package/tmux/templates/compliance.json +36 -0
- package/tmux/templates/data-pipeline.json +36 -0
- package/tmux/templates/debt-paydown.json +34 -0
- package/tmux/templates/devops.json +1 -0
- package/tmux/templates/documentation.json +1 -0
- package/tmux/templates/exploration.json +1 -0
- package/tmux/templates/feature-dev.json +1 -0
- package/tmux/templates/full-stack.json +8 -0
- package/tmux/templates/i18n.json +34 -0
- package/tmux/templates/incident-response.json +36 -0
- package/tmux/templates/migration.json +1 -0
- package/tmux/templates/observability.json +35 -0
- package/tmux/templates/onboarding.json +33 -0
- package/tmux/templates/performance.json +35 -0
- package/tmux/templates/refactor.json +1 -0
- package/tmux/templates/release.json +35 -0
- package/tmux/templates/security-audit.json +8 -0
- package/tmux/templates/spike.json +34 -0
- package/tmux/templates/testing.json +1 -0
- package/tmux/tmux.conf +98 -9
- package/scripts/cct-doctor.sh +0 -414
- package/scripts/cct-session.sh +0 -284
- package/scripts/cct-status.sh +0 -169
package/docs/KNOWN-ISSUES.md
CHANGED
|
@@ -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
|
|
82
|
-
|
|
83
|
-
| **iTerm2** (macOS)
|
|
84
|
-
| **Alacritty**
|
|
85
|
-
| **Kitty**
|
|
86
|
-
| **WezTerm**
|
|
87
|
-
| **macOS Terminal.app** | Supported
|
|
88
|
-
| VS Code terminal
|
|
89
|
-
| Ghostty
|
|
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, `
|
|
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
|
-
|
|
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: `
|
|
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
|
|
250
|
-
|
|
251
|
-
| `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`
|
|
252
|
-
| `CLAUDE_CODE_SUBAGENT_MODEL`
|
|
253
|
-
| `CLAUDE_CODE_AUTOCOMPACT_PCT_OVERRIDE`
|
|
254
|
-
| `CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY`
|
|
255
|
-
| `CLAUDE_CODE_GLOB_HIDDEN`
|
|
256
|
-
| `CLAUDE_CODE_BASH_MAINTAIN_PROJECT_WORKING_DIR` | —
|
|
257
|
-
| `CLAUDE_CODE_EMIT_TOOL_USE_SUMMARIES`
|
|
258
|
-
| `CLAUDE_CODE_TST_NAMES_IN_MESSAGES`
|
|
259
|
-
| `CLAUDE_CODE_EAGER_FLUSH`
|
|
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
|
|
317
|
-
|
|
318
|
-
| Independent tasks with clear file ownership
|
|
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
|
|
321
|
-
| Simple parallel review (code quality + security + tests)
|
|
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
|
|
326
|
-
|
|
327
|
-
| [Feature Implementation](patterns/feature-implementation.md) | 3-4
|
|
328
|
-
| [Research & Exploration](patterns/research-exploration.md)
|
|
329
|
-
| [Test Generation](patterns/test-generation.md)
|
|
330
|
-
| [Refactoring](patterns/refactoring.md)
|
|
331
|
-
| [Bug Hunt](patterns/bug-hunt.md)
|
|
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 |
|
package/docs/patterns/README.md
CHANGED
|
@@ -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
|
|
31
|
-
|
|
32
|
-
| [Feature Implementation](feature-implementation.md) | Building multi-component features
|
|
33
|
-
| [Research & Exploration](research-exploration.md)
|
|
34
|
-
| [Test Generation](test-generation.md)
|
|
35
|
-
| [Refactoring](refactoring.md)
|
|
36
|
-
| [Bug Hunt](bug-hunt.md)
|
|
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: `
|
|
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
|
|
119
|
-
|
|
120
|
-
| Spawn 5+ agents per wave
|
|
121
|
-
| Skip synthesis between waves
|
|
122
|
-
| Give vague task descriptions
|
|
123
|
-
| Let agents touch overlapping files | One will overwrite the other's changes
|
|
124
|
-
| Keep iterating when stuck
|
|
125
|
-
| Use waves for trivial tasks
|
|
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
|
|
134
|
-
|
|
135
|
-
| File search, simple lookups
|
|
136
|
-
| Implementation, clear requirements
|
|
137
|
-
| Architecture decisions, complex debugging | `opus`
|
|
138
|
-
| Test generation
|
|
139
|
-
| Documentation, reports
|
|
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.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Orchestrate autonomous Claude Code agent teams in tmux",
|
|
5
5
|
"bin": {
|
|
6
|
-
"shipwright": "./scripts/
|
|
7
|
-
"sw": "./scripts/
|
|
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/
|
|
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/
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 "$
|
|
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 "$
|
|
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 "$
|
|
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 '#{
|
|
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
|
-
#
|
|
58
|
-
local pane_id
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
#
|
|
77
|
-
local
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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 "$
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 [[
|
|
79
|
+
if [[ -s "$_WEZTERM_PANE_MAP" ]]; then
|
|
74
80
|
echo ""
|
|
75
81
|
echo "Tracked agents:"
|
|
76
|
-
|
|
77
|
-
echo " ${
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|