fix(server): show OpenCode task progress in the composer - #178
Conversation
OpenCode threads never populated the Tasks tab, the turn plan summary, or the sidebar working line. The adapter dropped OpenCode's `todo.updated` event off the end of its event switch, so no `turn.plan.updated` was ever emitted -- OpenCode was the only provider without plan parity. Separately, `todowrite` matched the `write` branch of tool classification and was filed as a file change, inflating the work log's edit count. Handle `todo.updated` from the v2 SDK, which already reaches the adapter and already passes the parent-session gate, and classify todo tools ahead of the write branch. Cancelled todos are dropped rather than reported completed, and a fingerprint suppresses the duplicate emissions OpenCode sends on every mutation.
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
Also note in WATCH-1 that Pylon's own OpenCode task-progress fix is open as #178, so the row stays listed only because upstream #5760 is still open.
|
Completed by #283, which merged with green CI. That PR includes the recovered OpenCode approval/Stop series and the task-progress behavior from this PR: native parent-session todos, cancelled-step omission, unknown-status fallback, correct todo tool classification, and duplicate suppression. It also rejects late task updates after a turn ends and preserves Pylon's current incarnation/admission guards. Closing this older overlapping implementation as superseded; its branch remains available. |
Problem
OpenCode threads never showed task progress. The composer Tasks tab, the turn plan summary, and the sidebar working line were all permanently empty — OpenCode was the only provider in Pylon without plan parity:
turn/plan/updated✅TodoWriteinput + Claude Tasks ✅cursor/update_todos✅PlanUpdated✅Two causes, both in
OpenCodeAdapter.ts:todo.updatedevent that was already arriving at the adapter and already passing the parent-session gate — it just fell off the end of the event switch, which has nodefault. Noturn.plan.updatedwas ever emitted.toToolLifecycleItemTypematchedtodowriteon itswritebranch and classified it asfile_change, so every todo update was filed into the edit tool group and counted toward the edit total. OpenCode threads over-reported file edits.Found while reviewing upstream pingdotgg/t3code#5760, which diagnoses the same bug in T3. That issue is still open with no upstream fix, so this is Pylon's own.
Fix
Handle
todo.updatedand classify todo tools ahead of the write branch. Entirely within the adapter boundary — no contract, decider, projector, or migration changes, sinceturn.plan.updatedalready flows end to end for five other providers.Notes on the choices:
todo.updatedevent, not the tool-call input the upstream issue suggests sniffing. The event is structured, already in the subscribedEventunion, and survives OpenCode changing its tool internals.completed. Pylon's plan contract has no cancelled state, and claiming finished work that was abandoned is worse than omitting it.pending— the SDK typesTodo.statusas a barestring.todo.updatedon every mutation; without this each step transition would write a redundant plan activity. Same approach Grok and Prime already use.Verification
vp test run apps/server/src/provider/Layers/OpenCodeAdapter.test.ts— 84 passed, including 4 new.Each new test was mutation-tested rather than trusted for going green:
todo.updatedcase → the 3 plan tests fail.vp run -F t3 typecheck— 0 errors.vp lintclean on both changed files, verified live with adebuggerprobe rather than inferred from a silent exit 0.Claude Opus 5 in Pylon.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.