@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.
- package/README.md +290 -0
- package/SKILL.md +692 -0
- package/dist/client.d.ts +4 -0
- package/dist/client.js +64 -0
- package/dist/commands/session-abort.d.ts +2 -0
- package/dist/commands/session-abort.js +16 -0
- package/dist/commands/session-children.d.ts +2 -0
- package/dist/commands/session-children.js +30 -0
- package/dist/commands/session-create.d.ts +2 -0
- package/dist/commands/session-create.js +39 -0
- package/dist/commands/session-diff.d.ts +2 -0
- package/dist/commands/session-diff.js +35 -0
- package/dist/commands/session-get.d.ts +2 -0
- package/dist/commands/session-get.js +24 -0
- package/dist/commands/session-last.d.ts +2 -0
- package/dist/commands/session-last.js +39 -0
- package/dist/commands/session-list.d.ts +2 -0
- package/dist/commands/session-list.js +91 -0
- package/dist/commands/session-messages.d.ts +2 -0
- package/dist/commands/session-messages.js +44 -0
- package/dist/commands/session-respond.d.ts +2 -0
- package/dist/commands/session-respond.js +78 -0
- package/dist/commands/session-send.d.ts +2 -0
- package/dist/commands/session-send.js +114 -0
- package/dist/commands/session-share.d.ts +3 -0
- package/dist/commands/session-share.js +53 -0
- package/dist/commands/session-status.d.ts +2 -0
- package/dist/commands/session-status.js +45 -0
- package/dist/commands/session-summary.d.ts +2 -0
- package/dist/commands/session-summary.js +87 -0
- package/dist/commands/session-todo.d.ts +2 -0
- package/dist/commands/session-todo.js +41 -0
- package/dist/commands/session-wait-for-text.d.ts +2 -0
- package/dist/commands/session-wait-for-text.js +119 -0
- package/dist/commands/session-wait.d.ts +4 -0
- package/dist/commands/session-wait.js +85 -0
- package/dist/commands/session-watch.d.ts +2 -0
- package/dist/commands/session-watch.js +101 -0
- package/dist/commands/skill.d.ts +3 -0
- package/dist/commands/skill.js +55 -0
- package/dist/commands/worktree.d.ts +5 -0
- package/dist/commands/worktree.js +359 -0
- package/dist/format.d.ts +19 -0
- package/dist/format.js +115 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +63 -0
- package/dist/resolve.d.ts +6 -0
- package/dist/resolve.js +47 -0
- package/dist/sse.d.ts +40 -0
- package/dist/sse.js +128 -0
- package/dist/wait-util.d.ts +23 -0
- package/dist/wait-util.js +118 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# occtl
|
|
2
|
+
|
|
3
|
+
Extended CLI for managing [OpenCode](https://opencode.ai) sessions. Adds the commands missing from the `opencode` CLI: reading messages, watching sessions in real-time, sending prompts, responding to permission requests, managing worktrees, and more.
|
|
4
|
+
|
|
5
|
+
Built for automating and orchestrating OpenCode sessions externally -- including [Ralph Mode](#ralph-mode), [session handoff](#use-cases), and [parallel worktree](#worktrees) workflows.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g occtl
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# List sessions for the current directory
|
|
17
|
+
occtl list
|
|
18
|
+
|
|
19
|
+
# Get the last assistant message
|
|
20
|
+
occtl last
|
|
21
|
+
|
|
22
|
+
# Watch a session stream in real-time
|
|
23
|
+
occtl watch --text-only
|
|
24
|
+
|
|
25
|
+
# Send a prompt and wait for the response
|
|
26
|
+
occtl send "fix the failing tests"
|
|
27
|
+
|
|
28
|
+
# Auto-approve all permission requests
|
|
29
|
+
occtl respond --auto-approve --wait
|
|
30
|
+
|
|
31
|
+
# Run a task in an isolated worktree
|
|
32
|
+
occtl worktree run auth -w "implement JWT authentication"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`worktree` can be shortened to `wt`:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
occtl wt run payments -w "add Stripe checkout"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Server Detection
|
|
42
|
+
|
|
43
|
+
`occtl` auto-detects a running OpenCode server by inspecting processes. Override with environment variables:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export OPENCODE_SERVER_HOST=127.0.0.1
|
|
47
|
+
export OPENCODE_SERVER_PORT=4096
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Commands
|
|
51
|
+
|
|
52
|
+
| Command | Description |
|
|
53
|
+
|---------|-------------|
|
|
54
|
+
| `list` | List sessions (filters by cwd, supports `--all`, path arg, `--sort`, `--asc`) |
|
|
55
|
+
| `create` | Create a new session (`-q` for ID, `-t` for title, `-d` for directory) |
|
|
56
|
+
| `get` | Get detailed session info |
|
|
57
|
+
| `messages` | List messages (`--role`, `--limit`, `--text-only`, `--verbose`) |
|
|
58
|
+
| `last` | Get the last message (text-only by default) |
|
|
59
|
+
| `status` | Check session status (idle/busy/retry) |
|
|
60
|
+
| `watch` | Watch session events via SSE (`--text-only`, `--json`, `--events`) |
|
|
61
|
+
| `send` | Send a message (`--async`, `--wait`, `--model`, `--agent`, `--stdin`) |
|
|
62
|
+
| `respond` | Respond to permission requests (`--auto-approve`, `--wait`) |
|
|
63
|
+
| `todo` | View the session's todo list |
|
|
64
|
+
| `abort` | Abort a running session |
|
|
65
|
+
| `diff` | Show file changes in a session |
|
|
66
|
+
| `children` | List child sessions (sub-agents) |
|
|
67
|
+
| `share` | Share a session and get a public URL |
|
|
68
|
+
| `unshare` | Remove sharing from a session |
|
|
69
|
+
| `wait-for-text` | Block until a message contains given text, then exit 0 |
|
|
70
|
+
| `wait-for-idle` | Block until a session goes idle |
|
|
71
|
+
| `wait-any` | Wait for first of N sessions to go idle, output its ID |
|
|
72
|
+
| `is-idle` | Non-blocking idle check (exit 0=idle, 1=busy) |
|
|
73
|
+
| `summary` | Compact overview: status, todos, cost, last message snippet |
|
|
74
|
+
| `worktree list` | List git worktrees |
|
|
75
|
+
| `worktree create` | Create a worktree with branch and optional session |
|
|
76
|
+
| `worktree remove` | Remove a worktree |
|
|
77
|
+
| `worktree run` | Create worktree + session + send prompt (one-liner) |
|
|
78
|
+
| `install-skill` | Install the occtl skill as an OpenCode user-level skill |
|
|
79
|
+
| `view-skill` | Display the bundled SKILL.md |
|
|
80
|
+
|
|
81
|
+
All commands that accept a session ID support partial matching and title search. When no ID is given, the most recent session is used.
|
|
82
|
+
|
|
83
|
+
All commands support `--json` for machine-readable output.
|
|
84
|
+
|
|
85
|
+
### Send Modes
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Default: synchronous, blocks until the agent responds
|
|
89
|
+
occtl send "fix the bug"
|
|
90
|
+
|
|
91
|
+
# Async: fire and forget
|
|
92
|
+
occtl send --async "fix the bug"
|
|
93
|
+
|
|
94
|
+
# Wait: send async, block until session idle, show result
|
|
95
|
+
occtl send --wait "fix the bug"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Worktrees
|
|
99
|
+
|
|
100
|
+
`occtl worktree` manages git worktrees for parallel, isolated sessions. Each worktree gets its own branch and directory under `.occtl/worktrees/`, so multiple agents can work on different features without conflicts.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Create a worktree with a session
|
|
104
|
+
occtl wt create auth-feature
|
|
105
|
+
|
|
106
|
+
# Run a prompt in a new worktree (one-liner)
|
|
107
|
+
occtl wt run auth-feature -w "implement JWT authentication"
|
|
108
|
+
|
|
109
|
+
# Run 3 features in parallel
|
|
110
|
+
occtl wt run auth "implement JWT auth" &
|
|
111
|
+
occtl wt run payments "add Stripe checkout" &
|
|
112
|
+
occtl wt run dashboard "build analytics dashboard" &
|
|
113
|
+
wait
|
|
114
|
+
|
|
115
|
+
# List worktrees
|
|
116
|
+
occtl wt ls
|
|
117
|
+
|
|
118
|
+
# Clean up
|
|
119
|
+
occtl wt rm auth-feature
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## OpenCode Skill
|
|
123
|
+
|
|
124
|
+
`occtl` ships with a SKILL.md that teaches OpenCode agents how to use `occtl`. Install it as a user-level skill:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
occtl install-skill
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This copies the skill to `~/.config/opencode/skills/occtl/`. Restart OpenCode to pick it up. The skill includes full command reference, Ralph Loop templates, and worktree patterns.
|
|
131
|
+
|
|
132
|
+
To view the skill without installing:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
occtl view-skill
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Ralph Mode
|
|
139
|
+
|
|
140
|
+
The [Ralph Loop](https://ghuntley.com/ralph/) is an autonomous coding pattern where an AI agent works through tasks in a loop with fresh context each iteration. Traditionally this requires a bash script to drive the loop.
|
|
141
|
+
|
|
142
|
+
`occtl` eliminates the bash script entirely. With Ralph Mode, **the agent IS the orchestrator**. It creates sessions, sends prompts, monitors progress, handles failures, and keeps iterating — all through `occtl` commands. No bash wrapper needed.
|
|
143
|
+
|
|
144
|
+
To start: tell your agent "Use the occtl skill to complete project X using Ralph Mode." The skill teaches the agent to:
|
|
145
|
+
|
|
146
|
+
1. Break work into atomic tasks (`tasks.md`)
|
|
147
|
+
2. Create a fresh session per task (`occtl create`)
|
|
148
|
+
3. Send the worker a prompt with context (`occtl send --async`)
|
|
149
|
+
4. Wait for completion (`occtl wait-for-idle`)
|
|
150
|
+
5. Evaluate output (`occtl summary`, `occtl last`)
|
|
151
|
+
6. Repeat until all tasks are done
|
|
152
|
+
|
|
153
|
+
### Parallel Execution
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Agent creates 3 sessions for independent tasks
|
|
157
|
+
SID1=$(occtl create -q -t "task-auth")
|
|
158
|
+
SID2=$(occtl create -q -t "task-payments")
|
|
159
|
+
SID3=$(occtl create -q -t "task-dashboard")
|
|
160
|
+
|
|
161
|
+
# Sends prompts to all three
|
|
162
|
+
occtl send --async "implement JWT auth..." -s $SID1
|
|
163
|
+
occtl send --async "add Stripe checkout..." -s $SID2
|
|
164
|
+
occtl send --async "build dashboard..." -s $SID3
|
|
165
|
+
|
|
166
|
+
# Waits for first to finish, evaluates, dispatches next
|
|
167
|
+
DONE=$(occtl wait-any $SID1 $SID2 $SID3)
|
|
168
|
+
occtl summary $DONE
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
For conflicting work, use worktrees:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
occtl wt run auth -w "implement JWT auth"
|
|
175
|
+
occtl wt run payments -w "add Stripe checkout"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
See `occtl view-skill` for the full Ralph Mode guide.
|
|
179
|
+
|
|
180
|
+
### Model Recommendations
|
|
181
|
+
|
|
182
|
+
The orchestrating agent doesn't write code — it just runs `occtl` commands and makes decisions. Use a cheap, fast model for the orchestrator and a capable model for the workers:
|
|
183
|
+
|
|
184
|
+
- **Orchestrator:** Sonnet, Flash, GPT-4o-mini (cheap, fast)
|
|
185
|
+
- **Workers:** Opus, Pro, o3 (capable, thorough)
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Specify the worker model when sending prompts
|
|
189
|
+
occtl send --async --model anthropic/claude-opus-4-6 "implement feature X" -s $SID
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Use Cases
|
|
193
|
+
|
|
194
|
+
### Handoff: "Watch my session while I sleep"
|
|
195
|
+
|
|
196
|
+
You're working in a normal OpenCode session — maybe a big refactor that's halfway done. You want to go to bed but keep things moving. Start a second session and tell it to babysit the first:
|
|
197
|
+
|
|
198
|
+
> "The session ses_abc123 is working on a refactor. When it finishes, use occtl to have it create a pull request, then monitor the CI pipeline. If the pipeline fails, read the failure logs and send the session a prompt to fix the issues. Keep going until the pipeline passes."
|
|
199
|
+
|
|
200
|
+
The supervisory agent uses:
|
|
201
|
+
- `occtl wait-for-idle ses_abc123` — block until the worker finishes
|
|
202
|
+
- `occtl send -w "create a PR for this work" -s ses_abc123` — tell it to make a PR
|
|
203
|
+
- `occtl last ses_abc123` — read the PR URL from its output
|
|
204
|
+
- `occtl send -w "the CI pipeline failed with: ... fix it" -s ses_abc123` — feed it failures
|
|
205
|
+
- Loop until the pipeline is green
|
|
206
|
+
|
|
207
|
+
You come back in the morning to a merged PR.
|
|
208
|
+
|
|
209
|
+
### PR Review Bot
|
|
210
|
+
|
|
211
|
+
A session can review another session's work:
|
|
212
|
+
|
|
213
|
+
> "Use occtl to watch for any session in this project that goes idle. When one does, read its diff and last message. If it made code changes, create a new session to review the changes and post review comments."
|
|
214
|
+
|
|
215
|
+
- `occtl list --json` — find active sessions
|
|
216
|
+
- `occtl wait-any <ids...>` — wait for any to finish
|
|
217
|
+
- `occtl diff <id>` — see what files changed
|
|
218
|
+
- `occtl create` + `occtl send` — start a review session with the diff as context
|
|
219
|
+
|
|
220
|
+
### Parallel Test Matrix
|
|
221
|
+
|
|
222
|
+
Run the same change against different test configurations:
|
|
223
|
+
|
|
224
|
+
> "Create 3 worktrees. In each one, send a session to run the test suite with a different Node version (18, 20, 22). Wait for all three to finish and report which ones passed."
|
|
225
|
+
|
|
226
|
+
- `occtl wt create node18` / `node20` / `node22`
|
|
227
|
+
- `occtl send --async` to each with the appropriate test command
|
|
228
|
+
- `occtl wait-any` repeatedly until all three are idle
|
|
229
|
+
- `occtl summary` each to check results
|
|
230
|
+
|
|
231
|
+
### Continuous Integration Helper
|
|
232
|
+
|
|
233
|
+
Wire `occtl` into your CI pipeline to have an agent fix failures:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# In CI, after a failure:
|
|
237
|
+
SID=$(occtl create -q -t "ci-fix-$(date +%s)")
|
|
238
|
+
occtl send -w "The CI build failed. Here's the log: $(cat ci-output.log)
|
|
239
|
+
Fix the issues and commit." -s $SID
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Cross-Project Coordination
|
|
243
|
+
|
|
244
|
+
Orchestrate work across separate codebases from a single agent:
|
|
245
|
+
|
|
246
|
+
> "Implement the new /users API in the backend, and simultaneously build the API client in the frontend. When both are done, verify they work together."
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# Sessions in different projects
|
|
250
|
+
API=$(occtl create -q -d /path/to/backend -t "users API")
|
|
251
|
+
CLIENT=$(occtl create -q -d /path/to/frontend -t "users client")
|
|
252
|
+
|
|
253
|
+
# Work in parallel
|
|
254
|
+
occtl send --async "implement /users endpoints" -s $API
|
|
255
|
+
occtl send --async "implement users API client" -s $CLIENT
|
|
256
|
+
|
|
257
|
+
# Wait for both, react to whichever finishes first
|
|
258
|
+
DONE=$(occtl wait-any $API $CLIENT)
|
|
259
|
+
occtl summary $DONE
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Works because one OpenCode server manages sessions across directories. Useful for API + client, library + consumers, or monorepo coordination.
|
|
263
|
+
|
|
264
|
+
### Session Migration
|
|
265
|
+
|
|
266
|
+
Move context from one session to another when a session gets too large:
|
|
267
|
+
|
|
268
|
+
> "Read the last 5 messages from ses_old using occtl, create a fresh session, and send it a summary of the prior work so it can continue."
|
|
269
|
+
|
|
270
|
+
- `occtl messages ses_old --limit 5 --text-only` — extract recent context
|
|
271
|
+
- `occtl create -q` — fresh session
|
|
272
|
+
- `occtl send --async "Continue the work. Here's what was done: ..."` — seed the new session
|
|
273
|
+
|
|
274
|
+
## Why Not Just Use opencode CLI?
|
|
275
|
+
|
|
276
|
+
The `opencode` CLI provides `session list` and `session delete`. Everything else in `occtl` is additive:
|
|
277
|
+
|
|
278
|
+
- **Read messages** from any session
|
|
279
|
+
- **Watch** sessions in real-time via SSE
|
|
280
|
+
- **Send prompts** programmatically (sync, async, or wait-for-idle)
|
|
281
|
+
- **Respond** to permission requests (including continuous auto-approve)
|
|
282
|
+
- **Wait for text** in agent output (event-driven, not polling)
|
|
283
|
+
- **Create** sessions for fresh-context workflows
|
|
284
|
+
- **Worktrees** for parallel, isolated agent execution
|
|
285
|
+
- **Share/unshare** sessions
|
|
286
|
+
- **Inspect** todos, diffs, children, and status
|
|
287
|
+
|
|
288
|
+
## License
|
|
289
|
+
|
|
290
|
+
MIT
|