Files
localgenai/oc-tree/NEXT_STEPS.md
noisedestroyers a29793032d Document current coding-workflow stack state
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.
2026-05-10 21:14:43 -04:00

4.7 KiB

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:

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:

# 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#11424message.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).