73 lines
2.4 KiB
Markdown
73 lines
2.4 KiB
Markdown
|
|
# oc-tree
|
||
|
|
|
||
|
|
Live tree-view sidecar for [opencode](https://opencode.ai). Subscribes
|
||
|
|
to the `opencode serve` SSE event stream and renders a live hierarchy of
|
||
|
|
sessions → messages → tool calls in a terminal pane next to the opencode
|
||
|
|
TUI.
|
||
|
|
|
||
|
|
Phoenix (`opencode/.opencode/plugin/phoenix-bridge.js`) handles
|
||
|
|
after-the-fact deep traces; oc-tree is the glanceable "what's it doing
|
||
|
|
right now" pane.
|
||
|
|
|
||
|
|
## Status
|
||
|
|
|
||
|
|
- **M0** — skeleton + schema probe (current).
|
||
|
|
- M1 — flat session list (textual).
|
||
|
|
- M2 — tree view with subagent nesting via `parentID`.
|
||
|
|
- M3 — heartbeat watchdog + REST replay on reconnect.
|
||
|
|
- M4 — polish (keybindings, theme, tmux layout doc).
|
||
|
|
|
||
|
|
Picking the work back up: read [`NEXT_STEPS.md`](./NEXT_STEPS.md) first.
|
||
|
|
|
||
|
|
## Requirements
|
||
|
|
|
||
|
|
- Python 3.11+
|
||
|
|
- `uv`
|
||
|
|
- A running `opencode serve` (default `127.0.0.1:4096`)
|
||
|
|
|
||
|
|
## Quickstart
|
||
|
|
|
||
|
|
```sh
|
||
|
|
cd ~/Documents/obsidian/localgenai/oc-tree
|
||
|
|
uv sync
|
||
|
|
uv run oc-tree-probe
|
||
|
|
```
|
||
|
|
|
||
|
|
Drive opencode in another terminal. Probe writes JSONL frames to
|
||
|
|
`/tmp/oc-tree-probe.jsonl` and a live counter to stdout. Ctrl-C to stop;
|
||
|
|
event-type counts print on exit.
|
||
|
|
|
||
|
|
### M0 verification queries
|
||
|
|
|
||
|
|
After driving a session that includes a Task subagent, a permission
|
||
|
|
prompt, and a tool call:
|
||
|
|
|
||
|
|
```sh
|
||
|
|
# 1. Does session.created.info.parentID populate for subagents?
|
||
|
|
jq -r 'select(.type=="session.created") | .raw.properties.info.parentID' \
|
||
|
|
/tmp/oc-tree-probe.jsonl
|
||
|
|
|
||
|
|
# 2. Does message.part.updated carry full parts or deltas?
|
||
|
|
jq -c 'select(.type=="message.part.updated") | .raw.properties.part' \
|
||
|
|
/tmp/oc-tree-probe.jsonl | head
|
||
|
|
|
||
|
|
# 3. Which permission.* events actually fire?
|
||
|
|
jq -r '.type' /tmp/oc-tree-probe.jsonl | grep -i permission | sort -u
|
||
|
|
```
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
| Env var | Default |
|
||
|
|
| --------------------------- | ------------------------ |
|
||
|
|
| `OPENCODE_URL` | `http://127.0.0.1:4096` |
|
||
|
|
| `OPENCODE_SERVER_USERNAME` | `opencode` (if pw set) |
|
||
|
|
| `OPENCODE_SERVER_PASSWORD` | _(unset → no auth)_ |
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
- [opencode server docs](https://opencode.ai/docs/server/)
|
||
|
|
- [sst/opencode#7451](https://github.com/sst/opencode/issues/7451) — no per-session SSE endpoint
|
||
|
|
- [sst/opencode#6573](https://github.com/sst/opencode/issues/6573) — Task subagent over `opencode serve`
|
||
|
|
- [sst/opencode#11424](https://github.com/sst/opencode/issues/11424) — replayed message.part.updated frames
|
||
|
|
- [sst/opencode#15149](https://github.com/sst/opencode/issues/15149) — SSE disconnect leaves server hung
|