feat(cli): extend the OpenCode plugin to every documented context surface - #1487
Conversation
…face The generated OpenCode adapter covered only the grep/glob graph lookup, so OpenCode sessions missed the read-coverage and lifecycle context other clients get through their hook configuration. Extend the plugin to the surfaces OpenCode documents: - unwrap hook-augment's additionalContext envelope so plain text, not raw JSON, lands in the tool output - post-read index-coverage notes via tool.execute.after, mapping OpenCode's filePath argument to the file_path key the default dialect reads - session-start tier routing injected once per sessionID on the first tool result, since OpenCode documents no context-output lifecycle hook - post-compaction reinjection through the documented experimental session.compacting surface (output.context) Every failure path resolves to the empty string: the adapter can degrade to a no-op but never blocks a tool call. Pin the new surfaces in test_agent_clients (31/31 pass; the DeusData#616 payload guard stays green) and record the wider surface in the README client matrix. Signed-off-by: jc <jcvi007@gmail.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
|
Thank you for extending the OpenCode integration across the documented context surfaces. Because the change touches several event payloads and execution paths, it needs a careful correctness and security-aware integration review. I have routed it to |
Maintainer mechanics on top of the accepted feature: merge current main and format the 24 violations in the edited region of client_adapter.c — the only red CI leg. No content change; the generated plugin is byte-identical apart from whitespace in the C literals' layout. Co-authored-by: jc <jcvi007@gmail.com> Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
|
@JCVIDev — the reserved fit decision is made: accepted, all four surfaces. OpenCode reaches context parity with the first-tier clients, including the What carried it, concretely: the review built your branch, drove all four hooks end-to-end against a real emitted install (plain text appended where main pastes raw JSON today, dedup holding across calls, a second session getting its own note, compaction pushing into I've pushed the two mechanical items to your branch so this doesn't cost you a round-trip: a merge of current main and a clang-format pass over the edited generator block (the 24 violations that were the only red CI leg — no content change; the emitted plugin is unchanged). Your commits and authorship are untouched. CI runs the full matrix now; merge on green, Also noted with appreciation: #1483 and #1484, both real, both filed from your own verification run. That's the diligence standard this queue wishes were normal. One residual worth a comment from you if you know it offhand: whether |
|
Merged as Two things from your work are worth recording rather than leaving in a merged diff: The envelope unwrap fixed a real shipped defect that was independent of the feature you were adding. Main was pasting raw JSON where plain text belonged. You could have added the four hooks and left that alone — noticing it and fixing it while you were in there is the part that does not show up in a line count. The surface inventory held up under checking. "Every documented context-capable surface" was verified against OpenCode's live docs, including the observation that the #616-era chat-transform hook has since disappeared from them. That is exactly the churn class this integration signs up for, and you documented it rather than quietly coding around it — which is what made accepting the The behaviour was checked end-to-end against a real emitted install before merge, not read: all four hooks driven live, dedup holding across calls, a second session getting its own note, compaction pushing into Thank you — a strong first contribution, and the kind that leaves the integration better documented than it found it. |
|
Apologies for the silence. This landed in a stretch of heavy workload and I simply never made it back to the thread — your question of 28 August deserved better than three days of nothing followed by a merge notification. That one is on me. Thank you for taking the PR seriously, and for the pace once it reached the front of the queue: the fit decision on the 28th and merged on the 31st. I'm particularly grateful you pushed the merge of On the residual: yes, yield* i.trigger("tool.execute.after",
{ tool: u.id, sessionID: H.sessionID, callID: H.callID, args: b },
V);
The same call sites also confirm what #1737 reported: Two things about it are mine to own: It widened the defect. Before this PR the only consumer of It is the other half of the conflict on #1933. You took that one as yours on that thread; the file it collides with is mine, so let me carry the part I can. To spare Chewji9875 a re-read of my diff: on current One note, offered tentatively because it rests on a guess about a harness I have not seen: if the payloads in that end-to-end run were constructed rather than captured, they would have been built from the plugin's own assumption — |
Summary
OpenCode is the closest client to Claude-parity for models CBM has no first-party hook dialect for (DeepSeek, etc.): it already gets MCP + the skill + the three read-only agents, but its generated plugin only covered one of the four context surfaces other clients get through hook configuration. This PR extends
cbm_client_adapter_opencode()so the generatedcbm-augment.tscovers every surface OpenCode documents — and nothing it doesn't:hook-augmentand unwrapshookSpecificOutput.additionalContextinstead of pasting the raw Claude JSON envelope into the tool output.readindex-coverage notes:tool.execute.afterforreadmaps OpenCode'sfilePatharg to thePostToolUse/Readeventhook-augmentalready accepts.SessionStartnote is carried on the first tool result of each session (deduped persessionID).experimental.session.compactinghook, appending to the mutableoutput.contextarray.Every path stays fail-open (all failures resolve to
''; context is only ever appended), consistent with the hook-augment contract, and the plugin body remains marker-free socbm_text_upsert_managed_blockowns the lifecycle (regenerated on install/update, per the #616 lesson).Why only these surfaces
Checked against the published OpenCode plugin docs:
tool.execute.before/after, theeventbus, andexperimental.session.compactingare the documented context-capable hooks; there is nochat.message-style hook. Per CBM policy the generator does not invent undocumented vendor surfaces, so session-start context rides on the first tool result rather than a fabricated lifecycle hook.Testing
client_adapter_opencode_covers_lifecycle_read_and_compactionpins the four surfaces (SessionStart lifecycle, PostToolUse/Read withfile_pathmapping, compaction hook,additionalContextunwrap, per-session dedup).client_adapter_opencode_sends_the_required_hook_eventstill passes unchanged (PreToolUse event,tool.execute.after, noregisterTool, no markers in the body).agent_clientssuite: 31/31 inside a fullscripts/test.shrun; the emitted JS also validated standalone withnode --check.mainwithout this change.README's OpenCode matrix row updated to describe the four surfaces.
🤖 Generated with Claude Code