claude-tempo 0.19.0-beta.4 → 0.19.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/README.md CHANGED
@@ -16,8 +16,6 @@
16
16
 
17
17
  Multiple Claude Code sessions discover each other, exchange messages in real time, and coordinate work — across machines, not just localhost.
18
18
 
19
- Each Claude Code session registers as a **player** in Temporal. Players discover each other with `ensemble`, exchange messages with `cue`, and coordinate work across machines. An optional **conductor** orchestrates the group and connects to external interfaces like Discord, Telegram, or a dashboard.
20
-
21
19
  ## Why claude-tempo?
22
20
 
23
21
  - **Crash-safe durability** — Sessions are Temporal workflows. Crashes, restarts, and network blips don't lose messages or drop coordination state. Dead sessions are detected automatically and the conductor is notified.
@@ -25,28 +23,15 @@ Each Claude Code session registers as a **player** in Temporal. Players discover
25
23
  - **Built-in scheduling** — Set up one-shot or recurring message schedules without any external infrastructure. Fan-out to all players at once for periodic status checks.
26
24
  - **Extensible agent types** — Define reusable player roles as `.md` files. Ship lineups that assemble entire teams in one command. Mix Claude Code and Copilot CLI sessions in the same ensemble.
27
25
 
28
- ## Features
29
-
30
- | | |
31
- |---|---|
32
- | 🔁 **Ensemble Lineups** | YAML configs that define a full team — players, instructions, schedules — and recruit them all in one command |
33
- | ⏰ **Scheduling** | One-shot and recurring message schedules with fan-out, bounds, and failure notifications |
34
- | 🎭 **Player Types** | Reusable agent definitions (composer, soloist, critic, etc.) with shipped examples and three-tier lookup |
35
- | 🌐 **Cross-machine** | Any session that can reach your Temporal server can join the ensemble |
36
-
37
26
  ## Installation
38
27
 
39
28
  ```bash
40
29
  npm install -g claude-tempo
41
30
  ```
42
31
 
43
- ### Prerequisites
44
-
45
- - [Node.js](https://nodejs.org/) 18+
46
- - [Temporal CLI](https://docs.temporal.io/cli) (for local dev server)
47
- - [Claude Code](https://claude.ai/code)
32
+ **Prerequisites:** [Node.js](https://nodejs.org/) 18+, [Temporal CLI](https://docs.temporal.io/cli), [Claude Code](https://claude.ai/code)
48
33
 
49
- ## Quick start
34
+ ## Quick Start
50
35
 
51
36
  One command handles everything:
52
37
 
@@ -55,14 +40,7 @@ cd your-project
55
40
  claude-tempo up
56
41
  ```
57
42
 
58
- This will:
59
-
60
- 1. Check that Temporal CLI is installed
61
- 2. Start the Temporal dev server (data persists in `~/.claude-tempo/`)
62
- 3. Register required search attributes
63
- 4. Register the claude-tempo MCP server (globally by default)
64
- 5. Start the worker daemon in the background
65
- 6. Launch a conductor session in a new terminal window
43
+ This starts the Temporal dev server, registers the MCP server globally, starts the worker daemon, and launches a conductor session in a new terminal.
66
44
 
67
45
  Then add players:
68
46
 
@@ -78,765 +56,123 @@ Or ask the conductor to `recruit` players for you from inside Claude Code.
78
56
  For more control, run each step individually:
79
57
 
80
58
  ```bash
81
- # Start Temporal dev server (keep running)
82
- claude-tempo server
83
-
84
- # Register claude-tempo MCP server (globally by default)
85
- cd your-project
86
- claude-tempo init
87
-
88
- # Verify everything is ready
89
- claude-tempo preflight
90
-
91
- # Start a conductor
92
- claude-tempo conduct
93
-
94
- # Add players
95
- claude-tempo start
59
+ claude-tempo server # start Temporal dev server (keep running)
60
+ claude-tempo init # register MCP server globally
61
+ claude-tempo preflight # verify environment
62
+ claude-tempo conduct # start a conductor
63
+ claude-tempo start # add players
96
64
  ```
97
65
 
98
- ## Upgrading
99
-
100
- ### Upgrading to 0.19.0
101
-
102
- v0.19.0 introduces the **worker daemon** — a single background process that runs all Temporal workers instead of each session running its own. Old sessions running in-process workers will compete on the same task queue as the daemon, causing errors. A clean restart is required.
103
-
104
- 1. **Stop everything:**
105
-
106
- ```bash
107
- claude-tempo down --all
108
- ```
109
-
110
- 2. **Install the new version:**
111
-
112
- ```bash
113
- npm install -g claude-tempo@latest
114
- ```
115
-
116
- 3. **Fix MCP registration (if you previously used `npx`):**
117
-
118
- If you registered with `npx` (e.g. via `claude-tempo init` before v0.19.0):
119
-
120
- ```bash
121
- # Remove old registration
122
- claude mcp remove claude-tempo -s user
123
-
124
- # Re-register with the direct binary
125
- claude mcp add claude-tempo -s user -- claude-tempo-server
126
- ```
127
-
128
- If you have a project-level `.mcp.json` with `"command": "npx"`, either delete it or change the entry:
129
-
130
- ```json
131
- { "command": "claude-tempo-server", "args": [] }
132
- ```
133
-
134
- 4. **Start fresh:**
135
-
136
- ```bash
137
- claude-tempo up <ensemble>
138
- ```
139
-
140
- The daemon starts automatically — no manual daemon management needed.
141
-
142
- ### Troubleshooting
66
+ ### Basic MCP usage
143
67
 
144
- | Symptom | Fix |
145
- |---------|-----|
146
- | `workflow execution not found` errors | Restart the daemon: `claude-tempo daemon stop && claude-tempo daemon start` |
147
- | Sessions not responding to messages | Run `claude-tempo daemon status` — ensure the daemon is running |
148
- | `.mcp.json` keeps being recreated with `npx` | Delete `.mcp.json` and use user-level registration: `claude-tempo init` |
68
+ Inside any Claude Code session connected to claude-tempo:
149
69
 
150
- ---
70
+ - "Show me the ensemble" — discover other sessions
71
+ - "Set your name to 'frontend'" — set a human-readable name
72
+ - "Cue backend: what are you working on?" — send a message to another player
73
+ - "Recruit a soloist in /repos/api" — spawn a new player session
151
74
 
152
- ## Core concepts
75
+ 📖 **[Full documentation](docs/README.md)**
153
76
 
154
- - **Player** — A Claude Code session registered as a Temporal workflow
155
- - **Conductor** — An optional orchestration hub connected to external interfaces (one per ensemble)
156
- - **Ensemble** — A named group of players that can see and message each other, isolated from other ensembles
157
- - **Cue** — A message sent to a player by name via Temporal signal
77
+ ## Core Concepts
158
78
 
159
- Players in one ensemble cannot see or message players in another. By default, sessions join the `default` ensemble:
79
+ Each Claude Code session registers as a **player** in Temporal. Players discover each other with `ensemble`, exchange messages with `cue`, and coordinate work across machines. An optional **conductor** orchestrates the group and connects to external interfaces. All players in the same **ensemble** can see and message each other; ensembles are isolated from each other.
160
80
 
161
81
  ```bash
162
- claude-tempo conduct frontend # conduct the "frontend" ensemble
163
- claude-tempo start backend # join the "backend" ensemble
164
- claude-tempo conduct # conduct the "default" ensemble
82
+ claude-tempo conduct frontend # conduct the "frontend" ensemble
83
+ claude-tempo start backend # join the "backend" ensemble
165
84
  ```
166
85
 
167
- ## MCP tools
86
+ ## What You Can Do
168
87
 
169
- These tools are available inside Claude Code sessions connected to claude-tempo:
88
+ ### Terminal UI
170
89
 
171
- | Tool | Description |
172
- |------|-------------|
173
- | `ensemble` | Discover active sessions. Scope: `machine`, `repo`, or `all`. |
174
- | `cue` | Send a message to a player by name. Delivered instantly via Temporal signal. |
175
- | `set_name` | Set a human-readable name for this session. |
176
- | `set_part` | Describe what you're working on. Visible to others via `ensemble`. |
177
- | `listen` | Manually check for pending messages. |
178
- | `recruit` | Spawn a new Claude Code session in a directory. Can recruit a conductor with `conductor: true`. |
179
- | `report` | Send updates to the conductor. No-op if no conductor exists. |
180
- | `stop` | Stop a player session by name. |
181
- | `schedule` | Create a one-shot or recurring schedule to cue a player. |
182
- | `unschedule` | Cancel a named schedule. |
183
- | `schedules` | List all active schedules. |
184
- | `who_am_i` | Get your identity, role, player type, and session details. |
185
- | `agent_types` | List available player types with name, description, and source. |
186
- | `save_lineup` | Save the current ensemble as a YAML lineup (conductor only). |
187
- | `load_lineup` | Load a lineup to recruit players and create schedules. |
188
- | `broadcast` | Send a message to all active players. Optional `type` filter limits to a specific player type. |
189
- | `encore` | Revive a stale player session — restarts the process and reconnects to the existing workflow with context restored. |
190
- | `recall` | Read your own message history. Shows received messages by default; pass `includeSent: true` for the full timeline. |
191
- | `worktree` | Manage git worktrees for player isolation. Actions: `create`, `remove`, `list`. Conductor only. |
192
- | `quality_gate` | Define or replace a quality gate for a task — a named checklist of criteria that must pass. Conductor only. |
193
- | `evaluate_gate` | Mark one or more criteria on a quality gate as passed or failed. Conductor only. |
194
- | `gates` | List quality gates and their status. Filter by task name or status (`open`, `passed`, `failed`). Conductor only. |
195
- | `stage` | Define a stage — tracks a set of players doing parallel work and auto-notifies when all report. Conductor only. |
196
- | `stages` | List stages and their status. Conductor only. |
197
- | `cancel_stage` | Cancel an active stage by name. Conductor only. |
90
+ Run `claude-tempo` (no arguments) to launch the built-in TUI — a chat-focused shell for managing your ensemble without leaving the terminal.
198
91
 
199
- ## Scheduling
200
-
201
- Players can set up schedules to send messages on timers — useful for periodic checks, reminders, and recurring coordination.
202
-
203
- Three tools are available:
204
- - **`schedule`** — Create a named schedule (one-shot or recurring)
205
- - **`unschedule`** — Remove a schedule by name
206
- - **`schedules`** — List all active schedules
207
-
208
- ### Examples
209
-
210
- Tell your session things like:
211
-
212
- - *"Schedule a check every hour called 'deploy-watch' — cue ops to check deployment status"*
213
- - *"Remind me in 30 minutes to review PR #42"*
214
- - *"Every 5 minutes for the next hour, ping frontend to check their progress"*
215
- - *"Set up a daily standup at 9am New York time, weekdays only"*
216
- - *"Cancel the deploy-watch schedule"*
217
- - *"Show me all active schedules"*
218
-
219
- Schedules support four timing modes — all accept optional bounds (`count` max fires, `until` end time):
220
-
221
- | Mode | Parameter | Example |
222
- |------|-----------|---------|
223
- | One-shot delay | `delay` | `"10m"`, `"2h"`, `"1d"` |
224
- | Fixed time | `at` | `"2026-04-03T20:00:00Z"` |
225
- | Recurring interval | `every` | `"5m"`, `"1h"` |
226
- | Cron expression | `cron` + optional `timezone` | `"0 9 * * 1-5"` (weekdays 9am) |
227
-
228
- The `timezone` parameter accepts any IANA timezone (e.g. `"America/New_York"`, `"Europe/London"`). Defaults to UTC when omitted.
229
-
230
- ### How it works
231
-
232
- - Scheduled messages arrive with a `[scheduled: name]` prefix so recipients can distinguish them from direct cues
233
- - The `from` field is set to the schedule creator, so replies go to the right person
234
- - If the target player is gone when a schedule fires, the creator is notified so they can re-recruit if needed. Falls back to notifying the conductor if the creator is also unavailable
235
- - Messages include `isScheduled` metadata for dashboard integrations
236
- - `claude-tempo status` shows active schedules alongside sessions
237
- - A single durable scheduler workflow per ensemble manages all schedules using Temporal timers
238
-
239
- ## Quality Gates
240
-
241
- Conductors can define named checklists of criteria to verify task completion. Three conductor-only tools are available: `quality_gate` (create or replace a gate), `evaluate_gate` (mark criteria as passed or failed), and `gates` (list all gates with optional filters).
242
-
243
- ### Examples
244
-
245
- Tell your conductor things like:
246
-
247
- - *"Set a quality gate 'pr-ready' with criteria: tests pass, no lint errors, code reviewed"*
248
- - *"Mark criteria 0 and 1 on 'pr-ready' as passed"*
249
- - *"Show me all open quality gates"*
250
- - *"Check whether 'deploy-staging' has passed"*
251
-
252
- ### How it works
253
-
254
- - Gate status is derived from criteria: all passed → `passed`; any failed → `failed`; otherwise `open`
255
- - Gates survive `continueAsNew` for the conductor workflow's lifetime
256
-
257
- ## Pipeline Stages
258
-
259
- Conductors can track fan-out/fan-in of parallel work using stages. Define a stage with a set of players, cue them to work, and the conductor is automatically notified when all players have reported — without polling.
260
-
261
- Three conductor-only tools: `stage` (create a stage), `stages` (list all stages), `cancel_stage` (cancel an active stage).
262
-
263
- ### Examples
264
-
265
- Tell your conductor things like:
266
-
267
- - *"Create a stage called 'review' with players: critic-1, critic-2, critic-3"*
268
- - *"Show me the status of all pipeline stages"*
269
- - *"Cancel the 'deploy' stage"*
270
-
271
- ### How it works
272
-
273
- - When a tracked player sends a `report`, their status updates automatically (`waiting` → `reported` or `blocked`)
274
- - When all players have reported, the conductor is notified that the stage is complete
275
- - Two failure policies: `halt` (default — fail the stage on first blocker) and `continue` (keep the stage active until all players report)
276
- - Stages survive `continueAsNew` for the conductor workflow's lifetime
277
-
278
- ## Ensemble Lineups
279
-
280
- Define reusable ensemble configurations as YAML files. A lineup specifies which players to recruit, what instructions to give them, what schedules to create, and optionally which custom agent files to use.
281
-
282
- ### Example lineup
283
-
284
- ```yaml
285
- name: my-project
286
- conductor:
287
- instructions: "Coordinate the frontend and backend teams"
288
- players:
289
- - name: frontend
290
- workDir: /repos/my-app
291
- instructions: "Build the React dashboard in src/components"
292
- - name: backend
293
- workDir: /repos/my-api
294
- instructions: "Implement the REST endpoints in src/routes"
295
- - name: ops
296
- workDir: /repos/infra
297
- agent: agents/ops-agent.md
298
- instructions: "Monitor deployments and run health checks"
299
- schedules:
300
- - name: status-check
301
- message: "Report your current progress and any blockers"
302
- target: all
303
- every: 30m
304
- - name: deploy-reminder
305
- message: "Check if the staging deploy succeeded"
306
- target: ops
307
- delay: 10m
308
- ```
309
-
310
- ### Three ways to use lineups
311
-
312
- 1. **From the CLI** — load a lineup when starting an ensemble:
313
-
314
- ```bash
315
- claude-tempo up --lineup my-lineup.yaml
316
- ```
317
-
318
- 2. **From inside a session** — use the `load_lineup` tool:
319
-
320
- *"Load the lineup from ~/.claude-tempo/ensembles/my-project.yaml"*
321
-
322
- 3. **Save the current state** — snapshot a running ensemble as a lineup (conductor only):
323
-
324
- *"Save this ensemble as a lineup called my-project"*
325
-
326
- ### Natural language examples
327
-
328
- Tell your session things like:
329
-
330
- - *"Load the my-project lineup"*
331
- - *"Save this ensemble as a lineup"*
332
- - *"Load the lineup from /repos/configs/team.yaml"*
333
-
334
- ### Fan-out schedules
335
-
336
- Use `target: "all"` in a schedule to deliver a message to every active player (excluding the conductor). This is useful for periodic status checks or broadcast announcements:
337
-
338
- - *"Schedule a message every 30 minutes to all players asking for a progress update"*
339
-
340
- ### Custom agents
341
-
342
- The `agent` field on a player can be a path to a `.md` file that will be used as the session's system prompt via `--system-prompt`. This lets you create specialized agents with domain-specific instructions:
343
-
344
- ```yaml
345
- players:
346
- - name: security-reviewer
347
- workDir: /repos/my-app
348
- agent: agents/security-review.md
349
- instructions: "Review the latest PR for security issues"
350
- ```
351
-
352
- ## Player Types
353
-
354
- Player types are reusable agent definitions in Claude Code's standard subagent format — `.md` files with YAML frontmatter specifying name, description, optional model, and optional tool restrictions. They let you define specialized roles once and reuse them across lineups.
355
-
356
- ### How player types work
357
-
358
- Reference a type by name in a lineup's `type` field:
359
-
360
- ```yaml
361
- players:
362
- - name: arch
363
- type: tempo-composer
364
- - name: eng
365
- type: tempo-soloist
366
- ```
367
-
368
- When a player is recruited with a type, the agent definition is resolved and passed to the session. Players know their type via the `who_am_i` tool.
369
-
370
- ### Tool restrictions (`allowedTools`)
371
-
372
- Agent type frontmatter may include an `allowedTools` array to restrict which tools the spawned session can use. When present, it is passed to the Claude Code session via `--allowedTools` and overrides any lineup-level setting.
373
-
374
- ```yaml
375
- ---
376
- name: tempo-reviewer
377
- description: Read-only code reviewer
378
- allowedTools:
379
- - Read
380
- - Glob
381
- - Grep
382
- ---
92
+ ```bash
93
+ claude-tempo # launch TUI (multi-ensemble view)
94
+ claude-tempo tui --ensemble myteam # connect directly to an ensemble
383
95
  ```
384
96
 
385
- This is useful for security-sensitive roles (read-only reviewers, auditors) or to prevent specific players from making changes outside their scope. Sessions launched without a type, or with a type that omits `allowedTools`, receive no tool restrictions.
386
-
387
- ### Three-tier lookup
388
-
389
- Player types are resolved in order (first match wins):
390
-
391
- 1. **Project** — `.claude/agents/` in the project directory
392
- 2. **User** — `~/.claude/agents/` in the user's home directory
393
- 3. **Shipped** — `examples/agents/` bundled with claude-tempo
394
-
395
- Project and user types are resolved natively by Claude Code via `--agent <name>`. Shipped types fall back to `--system-prompt <path>`.
396
-
397
- ### Shipped player types
398
-
399
- | Type | Description |
400
- |------|-------------|
401
- | `tempo-conductor` | Orchestrates the ensemble — breaks down tasks, delegates to players, tracks progress |
402
- | `tempo-composer` | Software architect — designs system structure, defines interfaces, makes technology decisions |
403
- | `tempo-soloist` | Senior engineer — implements features, fixes bugs, writes tests, delivers working code |
404
- | `tempo-tuner` | QA engineer — designs test strategies, finds bugs, validates edge cases |
405
- | `tempo-critic` | Code reviewer — evaluates changes for correctness, security, performance, maintainability |
406
- | `tempo-roadie` | DevOps engineer — manages CI/CD, deployments, infrastructure, environment configuration |
407
- | `tempo-improv` | Researcher and explorer — investigates unknowns, runs spikes, evaluates options |
408
- | `tempo-liner` | Documentation specialist — owns README, CHANGELOG, CLAUDE.md, and PR descriptions |
409
-
410
- ### Shipped lineups
411
-
412
- | Lineup | Description |
413
- |--------|-------------|
414
- | `tempo-big-band` | Full-lifecycle ensemble with all 8 player types — design, implement, test, review, and ship |
415
- | `tempo-dev-team` | Feature development — conductor, composer, two soloists, and a tuner |
416
- | `tempo-review-squad` | Three critics with different focus areas for thorough parallel code review |
417
- | `tempo-jam-session` | Exploratory ensemble for spikes, research, and problems where the path is unclear |
97
+ Inside the TUI, type `/help` to see all available slash commands: `/cue`, `/broadcast`, `/recruit`, `/stop`, `/encore`, `/recall`, `/search`, `/players`, `/schedule`, `/gates`, `/stages`, `/worktree`, and more. See [docs/dashboard.md](docs/dashboard.md) for the full TUI reference.
418
98
 
419
- ### Discovery
99
+ ### Scheduling
420
100
 
421
- Use the `agent_types` MCP tool inside a session or the CLI:
101
+ Send messages on a delay, at a fixed time, on a recurring interval, or via cron expression:
422
102
 
423
103
  ```bash
424
- claude-tempo agent-types list # show available types
425
- claude-tempo agent-types show <name> # print full definition
426
- claude-tempo agent-types init # copy shipped examples to ~/.claude/agents/
104
+ # From inside Claude Code (via MCP tools)
105
+ schedule: { name: "standup", cron: "0 9 * * 1-5", target: "conductor", message: "Daily standup" }
427
106
  ```
428
107
 
429
- ## Conductors
108
+ Supports `delay`, `at`, `every`, and `cron` with optional IANA timezone. See [docs/scheduling.md](docs/scheduling.md).
430
109
 
431
- A **conductor** is an optional special player that acts as an orchestration hub. Use one when you want:
110
+ ### Lineups
432
111
 
433
- - A single session coordinating work across multiple players
434
- - External access to the ensemble via Discord, Telegram, or any Temporal client
435
- - A central point for players to `report` progress, blockers, and questions
436
-
437
- Without a conductor, players work fine peer-to-peer — they discover each other via `ensemble` and communicate via `cue`.
112
+ Define your entire ensemble as a YAML file and bootstrap it in one command:
438
113
 
439
114
  ```bash
440
- claude-tempo conduct # default ensemble
441
- claude-tempo conduct my-project # named ensemble
115
+ claude-tempo up --lineup lineups/dev-team.yml
442
116
  ```
443
117
 
444
- ### External access
445
-
446
- The conductor's Temporal workflow exposes a signal/query API:
447
-
448
- ```typescript
449
- import { Client } from '@temporalio/client';
118
+ Shipped lineups: `tempo-big-band` (full lifecycle), `tempo-dev-team` (feature work), `tempo-review-squad` (parallel review), `tempo-jam-session` (exploration). See [docs/ensembles.md](docs/ensembles.md).
450
119
 
451
- const client = new Client();
452
- const conductor = client.workflow.getHandle('claude-session-default-conductor');
453
-
454
- // Send a command
455
- await conductor.signal('command', {
456
- text: 'recruit /repos/api and run tests',
457
- source: 'cli',
458
- });
459
-
460
- // Check history
461
- const history = await conductor.query('history');
462
- ```
120
+ ### Orchestration
463
121
 
464
- Connect external channel plugins (e.g., Discord):
122
+ Conductors can track parallel work with **Quality Gates**, **Pipeline Stages**, and **Git Worktrees**:
465
123
 
466
- ```bash
467
- CLAUDE_TEMPO_CONDUCTOR=true claude \
468
- --channels plugin:discord@claude-plugins-official \
469
- --dangerously-skip-permissions --dangerously-load-development-channels server:claude-tempo
470
- ```
124
+ - **Quality Gates** — named checklists of criteria; auto-aggregate to `passed`/`failed`/`open`
125
+ - **Pipeline Stages** — fan-out/fan-in tracking; conductor is notified when all players report
126
+ - **Git Worktrees** — provision isolated branches for players; clean up when done
471
127
 
472
- ## Players
128
+ See [docs/orchestration.md](docs/orchestration.md).
473
129
 
474
- ### Starting players
130
+ ## Command Discovery
475
131
 
476
132
  ```bash
477
- # Terminal 1 — conductor
478
- claude-tempo conduct my-project
479
-
480
- # Terminal 2 — frontend
481
- claude-tempo start my-project -n frontend
482
-
483
- # Terminal 3 — backend
484
- claude-tempo start my-project -n backend
133
+ claude-tempo --help # all CLI commands
134
+ claude-tempo <command> --help # flags for a specific command
485
135
  ```
486
136
 
487
- Or let the conductor `recruit` players this spawns new terminal windows automatically.
488
-
489
- Inside a session, try:
490
- - "Show me the ensemble" — discovers other sessions
491
- - "Set your name to 'frontend'" — human-readable name
492
- - "Cue frontend: what are you working on?" — sends a message
493
-
494
- ### Session naming
137
+ Inside the TUI, type `/help` for slash commands. Inside Claude Code, use the `ensemble` tool to see who's active and explore from there.
495
138
 
496
- Sessions start with a random 8-character hex ID. Set a name at launch with `-n` or use `set_name` inside a session.
497
-
498
- - Names are stored in workflow metadata and discoverable via metadata queries. Search attributes are also set for Temporal UI visibility.
499
- - Other players use names to send messages via `cue`
500
- - `recruit` automatically tells new sessions to set their name
501
- - Names must be unique within an ensemble
502
- - Names must contain only letters, numbers, hyphens, and underscores
503
- - The name "conductor" is reserved for conductor sessions
504
-
505
- ### Session status lifecycle
506
-
507
- Each session has a status that tracks its connection state:
508
-
509
- | Status | Meaning |
510
- |--------|---------|
511
- | `pending` | Workflow created by `recruit`, but the Claude Code process hasn't connected yet |
512
- | `active` | Session is running and responsive |
513
- | `stale` | Messages have gone undelivered for 3+ minutes — the session is likely disconnected |
514
- | `blocked` | Messages are being delivered but the session has produced no outbound activity for 5+ minutes — it may be stuck or spinning |
515
-
516
- Status transitions:
517
- - **`pending` → `active`** — when the spawned session connects and sends its `updateMetadata` signal
518
- - **`active` → `stale`** — when undelivered messages exceed the stale threshold (3 minutes)
519
- - **`active` → `blocked`** — when delivered messages produce no outbound response for 5+ minutes; auto-recovers to `active` on next outbound activity
520
- - Any status → **terminated** — on graceful shutdown or `stop`
521
-
522
- `claude-tempo status` shows `(pending)` and `(stale)` indicators next to player names. The `ClaudeTempoStatus` search attribute is also set, so you can filter sessions by status in the Temporal UI (e.g., `ClaudeTempoStatus = "stale"`).
523
-
524
- ### Terminal support
525
-
526
- `recruit` and the CLI detect your terminal automatically:
527
-
528
- | Terminal | macOS | Linux | Windows |
529
- |----------|-------|-------|---------|
530
- | Ghostty | ✓ | — | — |
531
- | iTerm2 | ✓ | — | — |
532
- | Terminal.app | ✓ | — | — |
533
- | gnome-terminal | — | ✓ | — |
534
- | konsole / xterm | — | ✓ | — |
535
- | Windows Terminal | — | — | ✓ (tabs) |
536
- | cmd.exe / PowerShell | — | — | ✓ |
537
-
538
- macOS terminals preserve the full shell environment (fish, zsh, bash) including node version managers (fnm, nvm).
539
-
540
- Windows Terminal is detected automatically via the `WT_SESSION` environment variable. When running inside Windows Terminal, recruited sessions open as new tabs (with the player name as the tab title) instead of separate cmd.exe windows.
541
-
542
- ## CLI reference
543
-
544
- ```
545
- claude-tempo <command> [options]
546
- ```
547
-
548
- ### Commands
139
+ ### Key commands
549
140
 
141
+ **Session management**
550
142
  | Command | Description |
551
143
  |---------|-------------|
552
- | `up [ensemble]` | First-time setup: start Temporal, configure MCP, launch conductor. Use `--lineup` to load a lineup. |
553
- | `down` | Stop Temporal, terminate sessions, remove MCP config. Use `--keep-mcp` to preserve MCP config. |
554
- | `server` | Start the Temporal dev server and register search attributes |
555
- | `conduct [ensemble]` | Start a conductor session (one per ensemble). Use `--resume` or `--replace` if one exists. |
556
- | `start [ensemble]` | Start a player session |
557
- | `status [ensemble]` | Show active sessions and Temporal health |
558
- | `config` | Configure Temporal connection settings (interactive or `set`/`show`) |
559
- | `stop [ensemble]` | Stop sessions (`-n <name>` for one, `--all` for everything) |
560
- | `init` | Register claude-tempo MCP server globally (`--project` for per-directory) |
561
- | `preflight` | Run environment checks |
562
- | `broadcast <msg>` | Send a message to all active players. Use `--type` to filter by player type, `--include-stale` to include stale sessions. |
563
- | `encore <name>` | Revive a stale player session by name. Use `--host` to target a remote machine. |
564
- | `ensemble <sub>` | Manage saved lineups (`save`, `list`, `show`) |
565
- | `agent-types <sub>` | Manage player types (`list`, `show <name>`, `init`) |
566
- | `daemon <sub>` | Manage the worker daemon (`start`, `stop`, `status`, `logs`) |
567
- | `tui [ensemble]` | Launch the terminal UI dashboard — shows players, status, and recent activity (experimental) |
568
- | `version` | Print the installed version |
569
- | `help` | Show usage info |
570
-
571
- ### Global options
572
-
573
- ```
574
- --temporal-address <addr> Temporal server address (default: localhost:7233)
575
- --temporal-namespace <ns> Temporal namespace (default: default)
576
- --temporal-api-key <key> Temporal Cloud API key
577
- --temporal-tls-cert <path> mTLS client certificate path
578
- --temporal-tls-key <path> mTLS client key path
579
- -n, --name <name> Set the player name (start/conduct/up)
580
- --agent <claude|copilot> Agent backend to use (default: claude)
581
- --skip-preflight Skip preflight checks (start/conduct)
582
- -d, --dir <path> Target directory (default: cwd)
583
- --background Run Temporal in background (server only)
584
- --keep-mcp Preserve MCP config when tearing down (down only)
585
- --lineup <name|file> Load an ensemble lineup by name or file path (up only)
586
- --resume Resume an existing conductor session (conduct only)
587
- --replace Stop existing conductor and start fresh (conduct only)
588
- -v, --version Print version and exit
589
- ```
590
-
591
- ### `claude-tempo up`
592
-
593
- The recommended way to get started:
594
-
595
- ```
596
- $ claude-tempo up myband
597
-
598
- claude-tempo setup
599
- ✓ temporal CLI installed
600
- … Starting Temporal dev server...
601
- ✓ Temporal started (pid 12345, data in ~/.claude-tempo/)
602
- ✓ Registered search attributes
603
- ✓ .mcp.json created
604
-
605
- Launching conductor in ensemble myband...
144
+ | `claude-tempo up` | Start everything (Temporal + daemon + conductor) |
145
+ | `claude-tempo start [ensemble]` | Open a player session |
146
+ | `claude-tempo conduct [ensemble]` | Start a conductor session |
147
+ | `claude-tempo status` | Show active sessions |
148
+ | `claude-tempo down` | Stop everything |
606
149
 
607
- ✓ You're all set!
608
- Conductor launched (pid 12346)
609
- Ensemble: myband
610
-
611
- What next?
612
- claude-tempo start myband Add a player session
613
- claude-tempo status myband See who's active
614
- Or ask the conductor to recruit players for you
615
- ```
616
-
617
- ### `claude-tempo server`
618
-
619
- Starts the Temporal dev server with automatic search attribute registration:
620
-
621
- ```bash
622
- claude-tempo server # foreground (Ctrl+C to stop)
623
- claude-tempo server --background # daemonize
624
- ```
625
-
626
- Data persists in `~/.claude-tempo/temporal-data.db`. If Temporal is already running, registers attributes and exits.
627
-
628
- ### `claude-tempo status`
629
-
630
- Shows all active sessions:
631
-
632
- ```
633
- Ensemble: myband
634
- 3 active sessions
635
-
636
- conductor (conductor)
637
- Orchestrating the team
638
- /Users/me/projects/app main my-machine.local
639
-
640
- alice
641
- Building the REST endpoints
642
- /Users/me/projects/app feat/api my-machine.local
643
-
644
- bob (pending)
645
- Working on the dashboard
646
- /Users/me/projects/app feat/ui my-machine.local
647
-
648
- 1 active schedule
649
- deploy-watch → ops | every 1h | next: 3:00:00 PM
650
- ```
651
-
652
- ### `claude-tempo preflight`
653
-
654
- Verifies your environment: Node.js >= 18, Temporal reachable, `claude` on PATH, `claude-tempo-server` on PATH, `.mcp.json` configured.
655
-
656
- ### `claude-tempo init`
657
-
658
- Registers the claude-tempo MCP server globally so it's available in every Claude Code session:
659
-
660
- ```bash
661
- claude-tempo init # global install (recommended)
662
- claude-tempo init --project # per-directory .mcp.json instead
663
- ```
664
-
665
- If the `claude` CLI is not available, falls back to creating `.mcp.json` in the current directory.
666
-
667
- ### `claude-tempo down`
668
-
669
- Stops Temporal, terminates all sessions, and removes MCP config:
670
-
671
- ```bash
672
- claude-tempo down # full teardown
673
- claude-tempo down --keep-mcp # stop Temporal and sessions, but preserve MCP config
674
- ```
675
-
676
- ## Configuration
677
-
678
- Run `claude-tempo config` to save Temporal connection settings so you don't need flags or env vars every time:
679
-
680
- ```
681
- $ claude-tempo config
682
-
683
- ? Temporal address (localhost:7233): my-ns.tmprl.cloud:7233
684
- ? Temporal namespace (default): my-ns.abc123
685
- ? Auth method: (None / API key / mTLS)
686
- ? API key: ****
687
- Saved to ~/.claude-tempo/config.json
688
- ✓ Connected successfully
689
- ```
690
-
691
- Settings are stored in `~/.claude-tempo/config.json`. You can also set values non-interactively:
692
-
693
- ```bash
694
- claude-tempo config set temporalAddress my-ns.tmprl.cloud:7233
695
- claude-tempo config set temporalNamespace my-ns.abc123
696
- claude-tempo config set temporalApiKey tcl_...
697
- claude-tempo config show
698
- ```
699
-
700
- ### Resolution order
701
-
702
- Settings are resolved in this order (first match wins):
703
-
704
- 1. CLI flags (`--temporal-address`, `--temporal-namespace`, etc.)
705
- 2. Environment variables (`TEMPORAL_ADDRESS`, `TEMPORAL_NAMESPACE`, etc.)
706
- 3. claude-tempo config file (`~/.claude-tempo/config.json`)
707
- 4. Temporal CLI config (`~/.config/temporalio/temporal.yaml`) — if you've already configured the Temporal CLI, claude-tempo reads it automatically
708
- 5. Defaults (`localhost:7233`, `default` namespace)
709
-
710
- ### Temporal Cloud
711
-
712
- For Temporal Cloud, run `claude-tempo config` and provide your cloud address, namespace, and API key. Or set them as environment variables in CI:
713
-
714
- ```bash
715
- export TEMPORAL_ADDRESS=my-ns.abc123.tmprl.cloud:7233
716
- export TEMPORAL_NAMESPACE=my-ns.abc123
717
- export TEMPORAL_API_KEY=tcl_...
718
- ```
719
-
720
- ## Environment variables
721
-
722
- | Variable | Default | Description |
723
- |----------|---------|-------------|
724
- | `TEMPORAL_ADDRESS` | `localhost:7233` | Temporal server address |
725
- | `TEMPORAL_NAMESPACE` | `default` | Temporal namespace |
726
- | `TEMPORAL_API_KEY` | *(none)* | Temporal Cloud API key |
727
- | `TEMPORAL_TLS_CERT_PATH` | *(none)* | mTLS client certificate path |
728
- | `TEMPORAL_TLS_KEY_PATH` | *(none)* | mTLS client key path |
729
- | `CLAUDE_TEMPO_TASK_QUEUE` | `claude-tempo` | Task queue name |
730
- | `CLAUDE_TEMPO_ENSEMBLE` | `default` | Ensemble name |
731
- | `CLAUDE_TEMPO_CONDUCTOR` | `false` | Enable conductor mode |
732
- | `CLAUDE_TEMPO_PLAYER_NAME` | *(random hex)* | Player name on startup |
733
- | `CLAUDE_TEMPO_DEFAULT_AGENT` | `claude` | Default agent type (`claude` or `copilot`) |
734
-
735
- ## Stale session cleanup
736
-
737
- When a session crashes or closes without graceful shutdown, Temporal detects it automatically:
738
-
739
- - If a message to a dead session remains undelivered for **3 minutes**, the workflow self-completes
740
- - Before exiting, it notifies the conductor with the undelivered message so work can be reassigned
741
- - Idle sessions with no pending messages are probed after 1 hour of inactivity via a heartbeat ping; if the ping goes undelivered, the session self-completes
742
-
743
- No manual cleanup needed — `cue` a dead player and the system handles the rest.
744
-
745
- ## Copilot CLI integration (experimental)
746
-
747
- > **Warning:** Copilot bridge support is experimental and subject to breaking changes.
748
-
749
- GitHub Copilot CLI sessions can join an ensemble via the Copilot bridge. Bridge sessions are headless — they require a conductor or another player to receive work via `cue`.
750
-
751
- <details>
752
- <summary>Setup and usage</summary>
753
-
754
- ### Prerequisites
755
-
756
- - [GitHub Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli) installed and authenticated
757
- - An active GitHub Copilot subscription
758
- - Node.js 20+
759
- - Install the Copilot SDK: `npm install @github/copilot-sdk`
760
-
761
- ### Starting Copilot sessions
762
-
763
- Use `--agent copilot` with any session-launching command:
764
-
765
- ```bash
766
- claude-tempo start myband --agent copilot -n copilot-1 # start a player
767
- claude-tempo conduct myband --agent copilot # start a conductor
768
- claude-tempo up myband --agent copilot # full setup
769
- ```
770
-
771
- Or recruit from within any active session:
772
-
773
- > "Recruit a copilot session named 'copilot-dev' in /repos/my-project with agent copilot"
774
-
775
- ### Setting a default agent
776
-
777
- To avoid passing `--agent copilot` every time:
778
-
779
- ```bash
780
- claude-tempo config set default-agent copilot
781
- ```
782
-
783
- Or via environment variable:
784
-
785
- ```bash
786
- export CLAUDE_TEMPO_DEFAULT_AGENT=copilot
787
- ```
788
-
789
- Resolution order: `--agent` flag → `CLAUDE_TEMPO_DEFAULT_AGENT` env → config file → `claude`.
790
-
791
- ### Model override
792
-
793
- Set `COPILOT_BRIDGE_MODEL` to use a specific model for Copilot sessions:
794
-
795
- ```bash
796
- COPILOT_BRIDGE_MODEL=gpt-4o claude-tempo start myband --agent copilot
797
- ```
150
+ **Lineups**
151
+ | Command | Description |
152
+ |---------|-------------|
153
+ | `claude-tempo up --lineup <file>` | Bootstrap from a lineup YAML |
154
+ | `claude-tempo ensemble save <name>` | Save current ensemble as a lineup |
155
+ | `claude-tempo ensemble list` | List saved lineups |
798
156
 
799
- ### Limitations
157
+ **Player types**
158
+ | Command | Description |
159
+ |---------|-------------|
160
+ | `claude-tempo agent-types list` | List available player types |
161
+ | `claude-tempo agent-types show <name>` | Show a player type definition |
162
+ | `claude-tempo agent-types init <name>` | Create a new player type |
800
163
 
801
- - Headless only — bridge sessions respond to cues, no interactive terminal
802
- - ~2-second polling latency (vs instant for Claude Code sessions)
803
- - `@github/copilot-sdk` adds ~243MB to node_modules
804
- - Node 20+ required (rest of claude-tempo works on Node 18+)
164
+ **Infrastructure**
165
+ | Command | Description |
166
+ |---------|-------------|
167
+ | `claude-tempo daemon start\|stop\|status\|logs` | Manage the worker daemon |
168
+ | `claude-tempo config` | Configure env vars interactively |
169
+ | `claude-tempo preflight` | Verify environment |
805
170
 
806
- </details>
171
+ See [docs/cli.md](docs/cli.md) for the full CLI reference including all flags and examples.
807
172
 
808
173
  ## Maestro Dashboard
809
174
 
810
- The **Maestro** workflow runs alongside the conductor, monitoring ensemble state in real time tracking player joins/leaves, status changes, and part updates. It also accepts commands from external sources for relay to the conductor.
811
-
812
- The [Maestro dashboard](https://github.com/vinceblank/maestro) is a web UI that connects to this workflow and provides a live view of your ensemble:
813
-
814
- - Player list with status, part, host, and git branch
815
- - Event log of recent ensemble activity
816
- - Command input to interact with the conductor
817
-
818
- The Maestro workflow starts automatically with the conductor and requires no additional setup. Connect the dashboard to your Temporal server's address and namespace to get started.
819
-
820
- ## Worker Daemon
821
-
822
- The **worker daemon** is a standalone background process that runs Temporal workers — it replaces the per-session workers from earlier versions. Sessions are now pure MCP clients.
823
-
824
- The daemon auto-starts the first time any claude-tempo command needs it. You can also manage it explicitly:
825
-
826
- ```bash
827
- claude-tempo daemon start # start the daemon (no-op if already running)
828
- claude-tempo daemon stop # stop the daemon
829
- claude-tempo daemon status # show running state and PID
830
- claude-tempo daemon logs # tail daemon logs
831
- ```
832
-
833
- ### How it works
834
-
835
- - On first use, any claude-tempo command calls `startDaemon()` and waits up to 10 seconds for it to confirm startup (by writing `~/.claude-tempo/daemon.pid`)
836
- - The daemon runs detached — it survives terminal closes and session restarts
837
- - All Temporal worker duties (workflow execution, activity dispatch) run in the daemon
838
- - Logs are written to `~/.claude-tempo/daemon.log`
839
- - On Linux/macOS, the daemon is stopped via `SIGTERM`; on Windows, the process is killed directly
175
+ The [Maestro dashboard](https://github.com/vinceblank/maestro) is a web UI that connects to your Temporal server and provides a live view of your ensemble player status, event log, and command input. See [docs/dashboard.md](docs/dashboard.md).
840
176
 
841
177
  ## Development
842
178
 
@@ -855,10 +191,6 @@ npm link # link CLI for local testing
855
191
 
856
192
  See [CLAUDE.md](CLAUDE.md) for project structure, key concepts, and development setup. Pull requests are welcome — please run `npm test` before submitting.
857
193
 
858
- ## Known limitations
859
-
860
- - **`recruit` requires manual acknowledgment** — Recruited sessions use `--dangerously-load-development-channels`. Claude Code shows a confirmation prompt that must be manually acknowledged in the spawned terminal. This will be resolved once claude-tempo is published as an approved channel plugin. Copilot bridge sessions do not have this limitation.
861
-
862
194
  ## License
863
195
 
864
196
  MIT