@colinmollenhour/occtl 1.0.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 (53) hide show
  1. package/README.md +290 -0
  2. package/SKILL.md +692 -0
  3. package/dist/client.d.ts +4 -0
  4. package/dist/client.js +64 -0
  5. package/dist/commands/session-abort.d.ts +2 -0
  6. package/dist/commands/session-abort.js +16 -0
  7. package/dist/commands/session-children.d.ts +2 -0
  8. package/dist/commands/session-children.js +30 -0
  9. package/dist/commands/session-create.d.ts +2 -0
  10. package/dist/commands/session-create.js +39 -0
  11. package/dist/commands/session-diff.d.ts +2 -0
  12. package/dist/commands/session-diff.js +35 -0
  13. package/dist/commands/session-get.d.ts +2 -0
  14. package/dist/commands/session-get.js +24 -0
  15. package/dist/commands/session-last.d.ts +2 -0
  16. package/dist/commands/session-last.js +39 -0
  17. package/dist/commands/session-list.d.ts +2 -0
  18. package/dist/commands/session-list.js +91 -0
  19. package/dist/commands/session-messages.d.ts +2 -0
  20. package/dist/commands/session-messages.js +44 -0
  21. package/dist/commands/session-respond.d.ts +2 -0
  22. package/dist/commands/session-respond.js +78 -0
  23. package/dist/commands/session-send.d.ts +2 -0
  24. package/dist/commands/session-send.js +114 -0
  25. package/dist/commands/session-share.d.ts +3 -0
  26. package/dist/commands/session-share.js +53 -0
  27. package/dist/commands/session-status.d.ts +2 -0
  28. package/dist/commands/session-status.js +45 -0
  29. package/dist/commands/session-summary.d.ts +2 -0
  30. package/dist/commands/session-summary.js +87 -0
  31. package/dist/commands/session-todo.d.ts +2 -0
  32. package/dist/commands/session-todo.js +41 -0
  33. package/dist/commands/session-wait-for-text.d.ts +2 -0
  34. package/dist/commands/session-wait-for-text.js +119 -0
  35. package/dist/commands/session-wait.d.ts +4 -0
  36. package/dist/commands/session-wait.js +85 -0
  37. package/dist/commands/session-watch.d.ts +2 -0
  38. package/dist/commands/session-watch.js +101 -0
  39. package/dist/commands/skill.d.ts +3 -0
  40. package/dist/commands/skill.js +55 -0
  41. package/dist/commands/worktree.d.ts +5 -0
  42. package/dist/commands/worktree.js +359 -0
  43. package/dist/format.d.ts +19 -0
  44. package/dist/format.js +115 -0
  45. package/dist/index.d.ts +2 -0
  46. package/dist/index.js +63 -0
  47. package/dist/resolve.d.ts +6 -0
  48. package/dist/resolve.js +47 -0
  49. package/dist/sse.d.ts +40 -0
  50. package/dist/sse.js +128 -0
  51. package/dist/wait-util.d.ts +23 -0
  52. package/dist/wait-util.js +118 -0
  53. package/package.json +49 -0
package/SKILL.md ADDED
@@ -0,0 +1,692 @@
1
+ ---
2
+ name: occtl
3
+ description: Manage OpenCode sessions from the CLI using occtl. Use when the user wants to list sessions, read session messages, get the last message, watch a session for updates, send messages to sessions, respond to permission requests, check session status, view todos, abort sessions, view diffs, or automate session management. Triggers include "check session", "read messages", "last message", "watch session", "send prompt", "approve permissions", "session status", "session todo", "abort session", or any programmatic OpenCode session interaction.
4
+ ---
5
+
6
+ # occtl - Extended CLI for OpenCode Sessions
7
+
8
+ `occtl` extends the `opencode` CLI with session management commands that are missing from the official tool: reading messages, watching sessions in real-time, responding to permission requests, and more.
9
+
10
+ ## Prerequisites
11
+
12
+ - OpenCode must be running (the server is auto-detected from running processes)
13
+ - If auto-detection fails, set `OPENCODE_SERVER_HOST` and `OPENCODE_SERVER_PORT`
14
+
15
+ ## Quick Reference
16
+
17
+ ```bash
18
+ occtl create -q # create a new session, print its ID
19
+ occtl list # list all sessions
20
+ occtl last # last message from most recent session
21
+ occtl messages <id> # all messages in a session
22
+ occtl watch <id> --text-only # stream text in real-time
23
+ occtl send "fix the bug" # send a message
24
+ occtl respond --auto-approve -w # auto-approve permissions
25
+ occtl todo # view session todo list
26
+ occtl status # check if sessions are busy/idle
27
+ occtl share # share session, get public URL
28
+ ```
29
+
30
+ ## Commands
31
+
32
+ ### List Sessions
33
+
34
+ ```bash
35
+ occtl list # sessions for current directory only (default)
36
+ occtl list --all # sessions for ALL directories
37
+ occtl list /path/to/project # sessions for a specific directory
38
+ occtl list --children # include child sessions (sub-agents)
39
+ occtl list --json # JSON output for scripting
40
+ occtl list --detailed # show full details per session
41
+ occtl list --limit 5 # limit results
42
+ occtl list --sort created # sort by: updated (default), created, title
43
+ occtl list --sort title --asc # sort ascending
44
+ ```
45
+
46
+ ### Create a Session
47
+
48
+ ```bash
49
+ occtl create # create a new session in the current directory
50
+ occtl create -t "my feature work" # with a title
51
+ occtl create -d /path/to/project # create in a specific project directory
52
+ occtl create -q # quiet mode: only output the session ID
53
+ occtl create --json # full JSON output
54
+ occtl create -p <parent-id> # create a child session
55
+ ```
56
+
57
+ The `-q` flag is useful in scripts: `SID=$(occtl create -q)`
58
+
59
+ The `-d` flag enables cross-project orchestration: `SID=$(occtl create -q -d /path/to/other/project)`
60
+
61
+ ### Get Session Details
62
+
63
+ ```bash
64
+ occtl get <session-id> # detailed info about a session
65
+ occtl get <session-id> --json
66
+ ```
67
+
68
+ ### Read Messages
69
+
70
+ ```bash
71
+ occtl messages # all messages from most recent session
72
+ occtl messages <session-id> # all messages from specific session
73
+ occtl messages <id> --role user # only user messages
74
+ occtl messages <id> --role assistant # only assistant messages
75
+ occtl messages <id> --limit 5 # last 5 messages
76
+ occtl messages <id> --text-only # text content only
77
+ occtl messages <id> --verbose # include tool call details
78
+ occtl messages <id> --json # full JSON output
79
+ ```
80
+
81
+ ### Get Last Message
82
+
83
+ ```bash
84
+ occtl last # last message (text-only by default)
85
+ occtl last <session-id> # from specific session
86
+ occtl last --role user # last user message
87
+ occtl last --role assistant # last assistant message
88
+ occtl last --verbose # include tool calls and metadata
89
+ occtl last --json # full JSON output
90
+ ```
91
+
92
+ ### Watch Session (Real-Time)
93
+
94
+ Connects to the SSE event stream and displays events for a session:
95
+
96
+ ```bash
97
+ occtl watch # watch most recent session
98
+ occtl watch <session-id> # watch specific session
99
+ occtl watch --text-only # stream only text content as it arrives
100
+ occtl watch --json # output each event as JSON line
101
+ occtl watch --events message.updated,session.idle # filter event types
102
+ ```
103
+
104
+ Event types shown: `message.updated`, `message.part.updated` (text deltas, tool calls), `session.status`, `session.idle`, `permission.updated`, `todo.updated`, `session.error`.
105
+
106
+ Press Ctrl+C to stop watching.
107
+
108
+ ### Send Messages
109
+
110
+ ```bash
111
+ occtl send "your message here" # send to most recent session
112
+ occtl send -s <session-id> "your message" # send to specific session
113
+ occtl send --async "do this in background" # send and return immediately
114
+ occtl send -w "fix the tests" # send, block until idle, show result
115
+ occtl send --model anthropic/claude-opus-4-6 "hi" # specify model
116
+ occtl send --agent plan "analyze this code" # specify agent
117
+ occtl send --no-reply "context info" # inject context without AI response
118
+ occtl send --stdin < prompt.txt # read message from stdin
119
+ occtl send "message" --json # JSON response output
120
+ ```
121
+
122
+ The three send modes:
123
+ - **(default)** — synchronous: blocks on the HTTP request until the agent responds, returns the response.
124
+ - **`--async`** — fire-and-forget: sends and exits immediately. Use with `watch` or `wait-for-text` separately.
125
+ - **`--wait` / `-w`** — hybrid: sends async, blocks until `session.idle` via SSE, then fetches and displays the last assistant message. Best for scripts that need the result but want event-driven waiting.
126
+
127
+ ### Respond to Permission Requests
128
+
129
+ ```bash
130
+ # Respond to a specific permission
131
+ occtl respond <session-id> -p <permission-id> -r once
132
+
133
+ # Wait for and respond to the next permission request
134
+ occtl respond <session-id> --wait -r always
135
+
136
+ # Auto-approve all permissions continuously (for automation)
137
+ occtl respond <session-id> --auto-approve --wait
138
+
139
+ # Response options: once, always, reject
140
+ occtl respond -r reject -p <permission-id>
141
+ ```
142
+
143
+ ### View Todos
144
+
145
+ ```bash
146
+ occtl todo # todos from most recent session
147
+ occtl todo <session-id> # todos from specific session
148
+ occtl todo --json # JSON output
149
+ ```
150
+
151
+ Output format:
152
+ ```
153
+ [x]! Completed high-priority task
154
+ [>] In-progress task
155
+ [ ] Pending task
156
+ [-] Cancelled task
157
+ ```
158
+
159
+ ### Check Session Status
160
+
161
+ ```bash
162
+ occtl status # all session statuses
163
+ occtl status <session-id> # specific session status
164
+ occtl status --json # JSON output
165
+ ```
166
+
167
+ Status types: `idle`, `busy`, `retry`.
168
+
169
+ ### Abort a Session
170
+
171
+ ```bash
172
+ occtl abort # abort most recent session
173
+ occtl abort <session-id> # abort specific session
174
+ ```
175
+
176
+ ### View Diffs
177
+
178
+ ```bash
179
+ occtl diff # file changes from most recent session
180
+ occtl diff <session-id> # file changes from specific session
181
+ occtl diff --json # JSON output
182
+ ```
183
+
184
+ ### Wait for Text
185
+
186
+ ```bash
187
+ occtl wait-for-text "SOME_TEXT" # wait on most recent session
188
+ occtl wait-for-text "SOME_TEXT" <session-id> # wait on specific session
189
+ occtl wait-for-text "DONE" --timeout 300 # timeout after 5 minutes (exit 1)
190
+ occtl wait-for-text "DONE" --no-check-existing # skip checking existing messages
191
+ ```
192
+
193
+ Checks existing messages first (by default), then watches the SSE stream for new ones. Outputs everything after the matched text and exits 0. Exits 1 on timeout.
194
+
195
+ The default check-existing behavior prevents a race condition where the text appears between `send --async` and `wait-for-text` starting. Use `--no-check-existing` only if you specifically want to wait for a *new* occurrence.
196
+
197
+ ### Wait for Idle
198
+
199
+ ```bash
200
+ occtl wait-for-idle # block until most recent session is idle
201
+ occtl wait-for-idle <session-id> # block until specific session is idle
202
+ occtl wait-for-idle --timeout 300 # timeout after 5 minutes (exit 1)
203
+ ```
204
+
205
+ Blocks until the session goes idle. Does a quick status check first — if already idle, exits immediately. Otherwise watches the SSE stream. Exit 0 = idle, exit 1 = timeout.
206
+
207
+ ### Wait Any (Multiple Sessions)
208
+
209
+ ```bash
210
+ occtl wait-any <id1> <id2> <id3> # wait for FIRST to go idle, output its ID
211
+ occtl wait-any <id1> <id2> --timeout 600
212
+ occtl wait-any <id1> <id2> --json # {"sessionID": "...", "reason": "idle"}
213
+ ```
214
+
215
+ Watches multiple sessions simultaneously. Outputs the session ID of the first one to go idle and exits. Essential for orchestrating parallel workloads.
216
+
217
+ ### Is Idle (Non-Blocking Check)
218
+
219
+ ```bash
220
+ occtl is-idle # exit 0 if idle, exit 1 if busy
221
+ occtl is-idle <session-id>
222
+ occtl is-idle --json # {"sessionID": "...", "idle": true, "status": "idle"}
223
+ ```
224
+
225
+ Non-blocking check. Useful for conditional logic in agent orchestration.
226
+
227
+ ### Session Summary
228
+
229
+ ```bash
230
+ occtl summary # compact summary of most recent session
231
+ occtl summary <session-id>
232
+ occtl summary --json # machine-readable summary
233
+ occtl summary -n 500 # longer last-message snippet (default: 200 chars)
234
+ ```
235
+
236
+ Shows status, todo progress, total cost, file changes, and a snippet of the last assistant message — all in one call. Designed for orchestration agents that need a quick overview without reading full message history.
237
+
238
+ ### Share / Unshare
239
+
240
+ ```bash
241
+ occtl share # share most recent session, print URL
242
+ occtl share <session-id> # share a specific session
243
+ occtl share --json # full JSON output
244
+ occtl unshare <session-id> # remove sharing
245
+ ```
246
+
247
+ ### List Child Sessions
248
+
249
+ ```bash
250
+ occtl children # children of most recent session
251
+ occtl children <session-id> # children of specific session
252
+ occtl children --json # JSON output
253
+ ```
254
+
255
+ ## Session ID Resolution
256
+
257
+ All commands that accept a session ID support:
258
+
259
+ 1. **No ID** - defaults to most recent session
260
+ 2. **Full ID** - exact match (e.g., `ses_2e1451cf8ffe7cBLbjmQS8Ogsc`)
261
+ 3. **Partial ID** - prefix or substring match (e.g., `ses_2e14` or just `2e14`)
262
+ 4. **Title search** - case-insensitive match against session title
263
+
264
+ ## Worktrees
265
+
266
+ `occtl worktree` (alias `occtl wt`) manages git worktrees for running parallel, isolated sessions. Each worktree gets its own branch and working directory under `.occtl/worktrees/`, so multiple agents can work on different features simultaneously without file conflicts.
267
+
268
+ ### List Worktrees
269
+
270
+ ```bash
271
+ occtl wt list # list all git worktrees
272
+ occtl wt list --json # JSON output
273
+ ```
274
+
275
+ ### Create a Worktree
276
+
277
+ ```bash
278
+ occtl wt create auth-feature # creates worktree + branch + session
279
+ occtl wt create auth-feature -b my-branch # custom branch name
280
+ occtl wt create auth-feature --base main # branch from a specific ref
281
+ occtl wt create auth-feature --no-session # just create the worktree, no session
282
+ occtl wt create auth-feature -q # only output the worktree path
283
+ occtl wt create auth-feature --json # JSON output with path, branch, sessionID
284
+ ```
285
+
286
+ By default, `create` also creates an OpenCode session scoped to the worktree directory.
287
+
288
+ Worktrees are created under `.occtl/worktrees/<name>` with branch `worktree-<name>`.
289
+
290
+ ### Remove a Worktree
291
+
292
+ ```bash
293
+ occtl wt rm auth-feature # remove by name
294
+ occtl wt rm auth-feature --force # force remove even if dirty
295
+ ```
296
+
297
+ ### Run a Prompt in a New Worktree
298
+
299
+ The `run` command is a one-liner that creates a worktree, starts a session, and sends a prompt:
300
+
301
+ ```bash
302
+ # Fire-and-forget: create worktree + session, send prompt, exit immediately
303
+ occtl wt run auth-feature "implement JWT authentication"
304
+
305
+ # Wait for completion: block until the session goes idle, show result
306
+ occtl wt run auth-feature -w "implement JWT authentication"
307
+
308
+ # With auto-approve and a specific model
309
+ occtl wt run auth-feature -w --auto-approve \
310
+ --model anthropic/claude-sonnet-4-6 \
311
+ "implement JWT authentication"
312
+
313
+ # Read prompt from a file
314
+ occtl wt run auth-feature -w --stdin < prompts/auth.md
315
+ ```
316
+
317
+ ### Parallel Features
318
+
319
+ Launch multiple features in parallel, each in its own worktree:
320
+
321
+ ```bash
322
+ # Start 3 features simultaneously
323
+ occtl wt run auth "implement JWT auth" &
324
+ occtl wt run payments "add Stripe checkout" &
325
+ occtl wt run dashboard "build analytics dashboard" &
326
+ wait
327
+
328
+ # Check status of each
329
+ occtl ls /path/to/repo/.occtl/worktrees/auth
330
+ occtl ls /path/to/repo/.occtl/worktrees/payments
331
+ occtl ls /path/to/repo/.occtl/worktrees/dashboard
332
+
333
+ # When done, review diffs and merge
334
+ for wt in auth payments dashboard; do
335
+ echo "=== $wt ==="
336
+ cd .occtl/worktrees/$wt && git log --oneline main..HEAD && cd -
337
+ done
338
+ ```
339
+
340
+ ### Parallel Ralph Loop
341
+
342
+ Combine worktrees with the Ralph Loop to run multiple autonomous task lists in parallel:
343
+
344
+ ```bash
345
+ #!/usr/bin/env bash
346
+ set -e
347
+
348
+ # Each feature gets its own worktree and Ralph loop
349
+ FEATURES=("auth" "payments" "dashboard")
350
+
351
+ for feature in "${FEATURES[@]}"; do
352
+ (
353
+ # Create worktree
354
+ WT_PATH=$(occtl wt create "$feature" -q)
355
+
356
+ for i in $(seq 1 10); do
357
+ SID=$(occtl create -q -t "ralph-${feature}-$i")
358
+
359
+ PROMPT="$(cat "prompts/${feature}.md")
360
+
361
+ ## Progress
362
+ $(cat "${WT_PATH}/progress.txt" 2>/dev/null || echo 'Starting fresh.')
363
+
364
+ When done, output RALPH_DONE. If ALL tasks are complete, output ALL_TASKS_COMPLETE."
365
+
366
+ occtl send --async "$PROMPT" -s "$SID"
367
+ occtl respond "$SID" --auto-approve --wait &
368
+ APID=$!
369
+
370
+ occtl wait-for-text "RALPH_DONE" "$SID" --timeout 600 || true
371
+ kill $APID 2>/dev/null || true
372
+
373
+ occtl last "$SID" >> "${WT_PATH}/progress.txt"
374
+
375
+ if occtl wait-for-text "ALL_TASKS_COMPLETE" "$SID" \
376
+ --check-existing --timeout 1; then
377
+ echo "=== $feature complete ==="
378
+ break
379
+ fi
380
+ done
381
+ ) &
382
+ done
383
+
384
+ wait
385
+ echo "All features complete. Review worktrees and merge."
386
+ ```
387
+
388
+ ## Automation Patterns
389
+
390
+ ### Continuous permission approval
391
+
392
+ ```bash
393
+ # Run in background to auto-approve all permission requests
394
+ occtl respond --auto-approve --wait &
395
+ ```
396
+
397
+ ### Poll session until idle
398
+
399
+ ```bash
400
+ while [ "$(occtl status <id> --json | jq -r '.type')" = "busy" ]; do
401
+ sleep 2
402
+ done
403
+ echo "Session is idle"
404
+ ```
405
+
406
+ ### Send message and capture response
407
+
408
+ ```bash
409
+ response=$(occtl send "what files were changed?" --json)
410
+ echo "$response" | jq -r '.parts[] | select(.type == "text") | .text'
411
+ ```
412
+
413
+ ### Watch for text output and pipe it
414
+
415
+ ```bash
416
+ occtl watch <id> --text-only | tee session-output.txt
417
+ ```
418
+
419
+ ### Chain send + watch for async workflows
420
+
421
+ ```bash
422
+ occtl send --async "refactor the auth module"
423
+ occtl watch --text-only
424
+ ```
425
+
426
+ ## JSON Output
427
+
428
+ All commands support `--json` for machine-readable output. The JSON structure matches the OpenCode SDK types directly (`Session`, `Message`, `Part`, `Todo`, etc.).
429
+
430
+ ## Ralph Mode
431
+
432
+ Ralph Mode turns YOU (the agent reading this skill) into an autonomous project
433
+ orchestrator. Instead of a bash script driving the loop, you ARE the loop. You
434
+ create sessions, send prompts, monitor progress, handle failures, and keep
435
+ iterating until the project is done — all by running `occtl` commands.
436
+
437
+ The user kicks it off with something like:
438
+ > "Use the occtl skill to complete project X using Ralph Mode."
439
+
440
+ And you take it from there.
441
+
442
+ ### How It Works
443
+
444
+ The Ralph pattern: break work into atomic tasks, execute each in a fresh session
445
+ (fresh context window), persist progress in the filesystem, repeat until done.
446
+
447
+ You are smarter than a bash loop because you can:
448
+ - Read the worker session's output and decide what to do next
449
+ - Adjust the prompt based on what actually happened
450
+ - Run multiple sessions in parallel on independent tasks
451
+ - Use worktrees to isolate parallel work that would conflict
452
+ - Handle errors, retries, and stuck sessions intelligently
453
+ - Make strategic decisions about task ordering and dependencies
454
+
455
+ ### Step-by-Step Procedure
456
+
457
+ When asked to use Ralph Mode, follow this procedure:
458
+
459
+ **1. Assess the project.** Read the codebase, requirements, and any existing
460
+ task files. Understand what needs to be done.
461
+
462
+ **2. Create a task list.** Write a `tasks.md` file (or similar) in the project
463
+ root. Each task should be:
464
+ - Atomic: completable in a single session/context window
465
+ - Verifiable: has clear done criteria (tests pass, file exists, etc.)
466
+ - Independent: minimizes dependencies on other tasks
467
+
468
+ **3. Create a `PROMPT.md` file.** This is the base prompt sent to each worker
469
+ session. It should tell the worker to:
470
+ - Read `tasks.md` and `progress.txt` to understand current state
471
+ - Pick one incomplete task and implement it
472
+ - Run tests/verification before marking done
473
+ - Update `tasks.md` (mark task done) and `progress.txt` (append summary)
474
+ - Commit changes
475
+
476
+ **4. Execute the loop.** For each iteration:
477
+
478
+ ```bash
479
+ # Create a fresh session
480
+ occtl create -q -t "ralph-iteration-N"
481
+ # Returns: ses_xxxxx
482
+
483
+ # Send the prompt (async so you don't block)
484
+ occtl send --async "$(cat PROMPT.md)" -s ses_xxxxx
485
+
486
+ # Auto-approve permissions for this session
487
+ occtl respond ses_xxxxx --auto-approve --wait
488
+ # (this runs in background via the shell — use & in bash)
489
+
490
+ # Wait for the session to finish
491
+ occtl wait-for-idle ses_xxxxx --timeout 600
492
+
493
+ # Check what happened
494
+ occtl summary ses_xxxxx
495
+ occtl last ses_xxxxx
496
+ occtl todo ses_xxxxx
497
+ ```
498
+
499
+ **5. Evaluate and decide.** After each iteration:
500
+ - Read the worker's output with `occtl last ses_xxxxx`
501
+ - Check `tasks.md` to see what was marked done
502
+ - Check `progress.txt` for the worker's notes
503
+ - If the task failed or was only partially done, adjust the next prompt
504
+ - If the worker got stuck, break the task into smaller pieces
505
+ - If all tasks are done, stop
506
+
507
+ **6. Repeat** until `tasks.md` shows all tasks complete.
508
+
509
+ ### Cross-Project Orchestration
510
+
511
+ You can coordinate work across completely separate codebases. Use `--dir`
512
+ when creating sessions to target different project directories:
513
+
514
+ ```bash
515
+ # Create sessions in different projects
516
+ API_SID=$(occtl create -q -d /path/to/backend -t "implement API endpoints")
517
+ CLIENT_SID=$(occtl create -q -d /path/to/frontend -t "implement API client")
518
+
519
+ # Send prompts to both
520
+ occtl send --async "Add the /users REST endpoints per the spec in docs/api.md" -s $API_SID
521
+ occtl send --async "Add API client methods for the /users endpoints" -s $CLIENT_SID
522
+
523
+ # Wait for both, checking whichever finishes first
524
+ DONE=$(occtl wait-any $API_SID $CLIENT_SID)
525
+ occtl summary $DONE
526
+ # ... continue coordinating
527
+ ```
528
+
529
+ This works because one OpenCode server can manage sessions across different
530
+ directories. Each session operates in its own project context.
531
+
532
+ Use cases:
533
+ - **API + client**: Implement a backend API and its frontend client simultaneously
534
+ - **Library + consumers**: Make a library change and update all downstream repos
535
+ - **Monorepo coordination**: Work across packages that have separate contexts
536
+ - **Migration**: Change a shared schema in one project and update all dependents
537
+
538
+ ### Key Commands for Orchestration
539
+
540
+ | What you need to do | Command |
541
+ |---|---|
542
+ | Create a fresh session | `occtl create -q -t "ralph-N"` |
543
+ | Create session in another project | `occtl create -q -d /path/to/project` |
544
+ | Send prompt to a session | `occtl send --async "prompt text" -s <id>` |
545
+ | Auto-approve permissions | `occtl respond <id> --auto-approve --wait` |
546
+ | Wait for session to finish | `occtl wait-for-idle <id> --timeout 600` |
547
+ | Quick status check | `occtl is-idle <id>` (exit 0=idle, 1=busy) |
548
+ | Get session overview | `occtl summary <id>` |
549
+ | Read last assistant message | `occtl last <id>` |
550
+ | Read full message history | `occtl messages <id> --text-only` |
551
+ | Check todo progress | `occtl todo <id>` |
552
+ | Check file changes | `occtl diff <id>` |
553
+ | Wait for first of N to finish | `occtl wait-any <id1> <id2> <id3>` |
554
+ | Abort a stuck session | `occtl abort <id>` |
555
+
556
+ ### Parallel Execution
557
+
558
+ For independent tasks, run multiple sessions simultaneously:
559
+
560
+ ```bash
561
+ # Create sessions for independent tasks
562
+ SID1=$(occtl create -q -t "task-auth")
563
+ SID2=$(occtl create -q -t "task-payments")
564
+ SID3=$(occtl create -q -t "task-dashboard")
565
+
566
+ # Send prompts to all three
567
+ occtl send --async "implement JWT auth. Read tasks.md..." -s $SID1
568
+ occtl send --async "add Stripe checkout. Read tasks.md..." -s $SID2
569
+ occtl send --async "build analytics dashboard. Read tasks.md..." -s $SID3
570
+
571
+ # Wait for the first one to finish
572
+ FINISHED=$(occtl wait-any $SID1 $SID2 $SID3 --timeout 600)
573
+ # $FINISHED contains the session ID that went idle first
574
+
575
+ # Check its result
576
+ occtl summary $FINISHED
577
+ ```
578
+
579
+ When tasks would modify the same files, use worktrees for isolation:
580
+
581
+ ```bash
582
+ # Create isolated worktrees for conflicting work
583
+ WT1=$(occtl wt create auth -q)
584
+ WT2=$(occtl wt create payments -q)
585
+
586
+ # Sessions are auto-created in worktree directories
587
+ # Send prompts, wait, then merge branches when done
588
+ ```
589
+
590
+ ### Handling Failures
591
+
592
+ When a worker session fails or produces bad output:
593
+
594
+ 1. **Read the output**: `occtl last <id>` — understand what went wrong
595
+ 2. **Check for errors**: `occtl summary <id> --json` — look at the error field
596
+ 3. **Decide**:
597
+ - If the task is too big, break it into subtasks in `tasks.md`
598
+ - If the worker misunderstood, refine the prompt and retry
599
+ - If there's a dependency, reorder tasks
600
+ - If it's a transient error, simply retry with a new session
601
+ 4. **Create a new session and try again** — never reuse a failed session
602
+
603
+ ### Example: Full Ralph Mode Session
604
+
605
+ Here is how you (the agent) would orchestrate a project. You are talking to
606
+ yourself — these are the bash commands you would execute:
607
+
608
+ ```
609
+ # 1. Read the project
610
+ cat tasks.md # understand what needs doing
611
+ cat progress.txt # see what's done so far
612
+
613
+ # 2. Iteration 1: first task
614
+ SID=$(occtl create -q -t "ralph-1-add-user-model")
615
+ occtl send --async "You are working on a project. Read tasks.md and progress.txt.
616
+ Pick the first incomplete task and implement it. Run tests. Update tasks.md and
617
+ progress.txt when done. Commit your changes." -s $SID
618
+ occtl respond $SID --auto-approve --wait &
619
+ occtl wait-for-idle $SID --timeout 600
620
+ occtl summary $SID
621
+ # Read output to see what happened
622
+ occtl last $SID
623
+
624
+ # 3. Check progress
625
+ cat tasks.md # was the task marked done?
626
+ cat progress.txt # what did the worker report?
627
+
628
+ # 4. Iteration 2: next task
629
+ SID=$(occtl create -q -t "ralph-2-add-api-endpoints")
630
+ occtl send --async "..." -s $SID
631
+ # ... repeat
632
+
633
+ # 5. When tasks.md shows all tasks done: stop and report to the user.
634
+ ```
635
+
636
+ ### Guidelines
637
+
638
+ - **One task per session.** This is the core principle. Fresh context = better quality.
639
+ - **You are the brains, workers are the hands.** Workers implement. You plan,
640
+ evaluate, and adapt. Don't expect workers to make strategic decisions.
641
+ - **Read worker output between iterations.** Use `occtl last` and
642
+ `occtl summary` to understand what actually happened before deciding
643
+ what to do next.
644
+ - **Adjust prompts based on results.** If a worker misunderstood, clarify.
645
+ If a task was too big, break it down. This is where you add intelligence
646
+ that a bash loop cannot.
647
+ - **Use parallel sessions for independent work.** Use `wait-any` to react
648
+ to whichever finishes first, then dispatch the next task.
649
+ - **Use worktrees when parallel tasks touch the same files.** Merge after.
650
+ - **Keep `progress.txt` lean.** Workers append to it, you may edit it to
651
+ keep it useful. Trim old entries if it gets too long.
652
+ - **Commit early, commit often.** Tell workers to commit after each task.
653
+ Git history is the real memory.
654
+ - **Report progress to the user.** Periodically summarize what's been done
655
+ and what remains. The user should be able to check in and see status.
656
+
657
+ ### Handling Timeouts
658
+
659
+ When a `wait-for-idle` or `wait-for-text` times out, do NOT blindly
660
+ start a new session. That wastes the work the current session may still
661
+ be doing. Instead:
662
+
663
+ 1. **Check if the session is still working:** `occtl is-idle <id>`
664
+ 2. **If still busy:** the task is taking longer than expected. Either:
665
+ - Increase the timeout and wait again: `occtl wait-for-idle <id> --timeout 1200`
666
+ - Check what it's doing: `occtl summary <id>` — it may be stuck in a loop
667
+ - Abort and retry with a clearer prompt: `occtl abort <id>`, then create a new session
668
+ 3. **If idle:** the timeout was a false alarm (the session finished between the
669
+ timeout firing and your check). Read the output: `occtl last <id>`
670
+ 4. **Never re-send the same prompt to the same session** — that adds to its
671
+ context window. Always create a fresh session for retries.
672
+
673
+ ### Model Recommendations
674
+
675
+ As the orchestrator, you don't write code — you run `occtl` commands and make
676
+ decisions. This is lightweight work that doesn't require a frontier model.
677
+
678
+ - **Orchestrator (you):** Use a fast, cheap model like **Sonnet**, **Flash**,
679
+ or **GPT-4o-mini**. You're just reading summaries, comparing outputs, and
680
+ running shell commands. Speed and cost matter more than raw capability.
681
+ - **Worker sessions:** Use a capable model like **Opus**, **Pro**, or **o3**
682
+ for the actual implementation work. Workers need deep reasoning to write
683
+ code, debug tests, and handle complexity.
684
+
685
+ You can specify the worker model when sending prompts:
686
+ ```bash
687
+ occtl send --async --model anthropic/claude-opus-4-6 "implement feature X" -s $SID
688
+ ```
689
+
690
+ This keeps orchestration cheap while letting workers use the best model for
691
+ the job. A typical Ralph Mode run might cost $0.50 in orchestration and
692
+ $15 in worker tokens.
@@ -0,0 +1,4 @@
1
+ import { type OpencodeClient } from "@opencode-ai/sdk";
2
+ export declare function getBaseUrl(): string;
3
+ export declare function getClient(): OpencodeClient;
4
+ export declare function ensureServer(): Promise<OpencodeClient>;