Snapshot of where opencode + Qwen3-Coder + MCPs + Kimi-Linear + voice + Phoenix tracing land today, plus in-flight (oc-tree, kimi-linear context ramp) and next (ComfyUI) items with pointers to per-project NEXT_STEPS.md guides.
121 lines
4.7 KiB
Markdown
121 lines
4.7 KiB
Markdown
# oc-tree — resumption guide
|
|
|
|
Open this file first when picking the work back up.
|
|
|
|
## What this project is
|
|
|
|
A Python TUI sidecar that subscribes to `opencode serve`'s SSE event
|
|
stream and renders a live tree of sessions → messages → tool calls in a
|
|
terminal pane next to the opencode TUI. Subagents nest under their
|
|
parent via `session.created.info.parentID`.
|
|
|
|
Roadmap entry: `localgenai/Roadmap.md` → "Layer 0: Cross-cutting
|
|
capabilities" → "Observability — partial" + prioritized step #12.
|
|
|
|
Phoenix (`opencode/.opencode/plugin/phoenix-bridge.js`) already handles
|
|
the *external* deep-trace store. oc-tree is the glanceable "what's it
|
|
doing right now" pane that lives in-harness (well, in tmux next to it).
|
|
|
|
## Where we are
|
|
|
|
- Plan agreed: Python + textual, lives at `localgenai/oc-tree/`.
|
|
- Phases: M0 → M1 → M2 → M3 → M4. See descriptions in this repo's task
|
|
list (`TaskList`) or the roadmap entry.
|
|
- **M0 — DONE** (skeleton). `uv sync` installs cleanly; `oc-tree` and
|
|
`oc-tree-probe` entry points resolve. Imports verified.
|
|
- **M0 — AWAITING USER ACTION** (schema verification). Probe is built
|
|
but hasn't been run against a live `opencode serve`. Three open
|
|
schema questions still unanswered.
|
|
|
|
## What blocks progress
|
|
|
|
User needs to run the probe against a real opencode session and report
|
|
back. Without these answers, M2's reducer design is guesswork.
|
|
|
|
Run in a tmux pane while `opencode serve` is up:
|
|
|
|
```sh
|
|
cd ~/Documents/obsidian/localgenai/oc-tree
|
|
uv run oc-tree-probe
|
|
```
|
|
|
|
Drive opencode through a session that hits **all three** triggers:
|
|
- Spawn a Task-tool subagent
|
|
- Trigger at least one permission prompt
|
|
- Make at least one regular tool call (Read/Bash/etc.)
|
|
|
|
Ctrl-C the probe. Then run:
|
|
|
|
```sh
|
|
# Q1: does session.created.info.parentID populate for subagents?
|
|
jq -r 'select(.type=="session.created") | .raw.properties.info.parentID' \
|
|
/tmp/oc-tree-probe.jsonl
|
|
|
|
# Q2: does message.part.updated carry full part or delta?
|
|
jq -c 'select(.type=="message.part.updated") | .raw.properties.part' \
|
|
/tmp/oc-tree-probe.jsonl | head
|
|
|
|
# Q3: what permission.* events actually fire?
|
|
jq -r '.type' /tmp/oc-tree-probe.jsonl | grep -i permission | sort -u
|
|
```
|
|
|
|
Paste the output (or the JSONL file path) into the next session.
|
|
|
|
## What happens next
|
|
|
|
Once probe answers are in:
|
|
|
|
1. Mark M0 complete, start **M1 (flat session list)** — textual app,
|
|
live-updating list of sessions with status, no nesting yet. Proves
|
|
the reducer + render loop. Independent of the schema answers, so
|
|
could start in parallel.
|
|
2. **M2 (tree view)** — needs probe answers to know:
|
|
- Whether to nest by `parentID` directly (Q1 yes) or fall back to
|
|
inferring subagents from `Task` tool-part response payloads.
|
|
- Whether the part-update reducer replaces by `partID` (Q2 = full
|
|
part) or merges a delta (Q2 = delta).
|
|
- What permission events to render (Q3).
|
|
3. **M3 (reconnect + state rebuild)** — heartbeat watchdog, REST replay
|
|
on disconnect. Driven by sst/opencode#15149/#22198 known leaks.
|
|
4. **M4 (polish)** — keybindings, theme, tmux layout doc.
|
|
|
|
## File layout
|
|
|
|
```
|
|
localgenai/oc-tree/
|
|
├── pyproject.toml uv project (textual, httpx, httpx-sse)
|
|
├── README.md user-facing readme
|
|
├── NEXT_STEPS.md this file
|
|
├── .python-version 3.11
|
|
└── src/oc_tree/
|
|
├── client.py OpenCodeClient: REST + SSE
|
|
├── probe.py schema-verification CLI
|
|
├── __main__.py stub for `oc-tree` (real TUI in M1)
|
|
└── widgets/ empty (populated in M1+)
|
|
```
|
|
|
|
## Key references
|
|
|
|
- opencode server docs: <https://opencode.ai/docs/server/>
|
|
- Authoritative schema: `GET /doc` on a running `opencode serve` (do
|
|
not hardcode — fetch per-version).
|
|
- sst/opencode#7451 — no per-session SSE endpoint; we filter `/event`
|
|
client-side.
|
|
- sst/opencode#6573 — Task subagent over `opencode serve` may have
|
|
bugs; this is what Q1 verifies.
|
|
- sst/opencode#11424 — `message.part.updated` sometimes replays full
|
|
state; this is what Q2 verifies.
|
|
- sst/opencode#15149, #22198 — SSE disconnect leaks; informs M3
|
|
shutdown discipline.
|
|
|
|
## Decisions worth not relitigating
|
|
|
|
- **Python + textual** chosen over Go+Bubbletea (faster iteration,
|
|
matches stack — uvx already in use) and Node+ink (worse SSE/UI
|
|
ergonomics; phoenix-bridge.js doesn't justify matching).
|
|
- **Read-only v1.** No sending messages, no editing. Just visibility.
|
|
- **Lives in `localgenai/oc-tree/`** rather than its own repo; can be
|
|
extracted later if it warrants a standalone release.
|
|
- **State rebuild via REST on every (re)connect** rather than trusting
|
|
SSE catchup or `Last-Event-ID` (server doesn't honor it).
|