feat(opencode): transcript ingest via the opencode-events parser#156
Merged
Conversation
added 2 commits
July 18, 2026 13:28
OpenCode's skill tool lists frontmatter names, and staging rewrites the staged skill-under-test's frontmatter name: to the sanitized slug — so the <available_skills> block in dispatch prompts should advertise the slug (as Codex already does), not the natural name that no longer resolves. Closes #65
Wire the third transcript-ingest capability: opencode run --format json emits self-contained envelopes, but tool args nest at part.state.input and timestamps are epoch-ms numbers — beyond the extract tier's primitives, so a named parser normalizes tool_use parts (name, state.input args, output/error result), sums step_finish tokens (cache excluded, matching codex), recovers the final message from the last text part, and measures duration from the envelope timestamps. - opencode.toml declares [transcript] + the verified [tools] vocabulary (bash/edit/write/apply_patch/read/glob/grep); schema, template.toml, byoh.md, and the PR template list the new capability. - The __skill_invoked meta-check generalizes to descriptor-declared skill_tool/skill_arg (defaults Skill/skill keep claude unchanged; opencode declares skill/name — the native skill tool is a deterministic invocation event, so surfaces_skill_invocation = true). - The shared write-boundary policy reads OpenCode's camelCase spellings (filePath in path_arg, patchText in apply_patch_paths). - Transcript-less preflight-warning coverage moves to the byoh integration tests (every built-in is now transcript-wired); next-steps/runbook goldens re-blessed for the ingest-wired handoff. - End-to-end: a staged run ingesting simulated opencode-events.jsonl yields parsed invocations, token/duration backfill, the transcript final-message fallback, and a code-graded skill-invocation meta-check. Remaining enhancement columns are tracked: dispatch recipes + model flag (#153), shadow preflight (#154), write guard (#155).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Two scoped commits advancing OpenCode from staging-only toward full enhancement parity (model in #113):
fix(opencode)— closes Opencode skill name #65. OpenCode's skill tool lists frontmatter names, and staging rewrites the staged skill'sname:to the sanitized slug — so the<available_skills>block in dispatch prompts now advertises the slug (as Codex already does) instead of the natural name that no longer resolves.feat(opencode)— transcript ingest. Wires theopencode-eventsparser capability:opencode run --format jsonenvelopes are self-contained, but tool args nest atpart.state.inputand timestamps are epoch-ms numbers — beyond the extract tier's five primitives, exactly the case the docs reserve for a code capability. The parser normalizestool_useparts (name atpart.tool, args =state.input, result =state.output/state.error), sumsstep_finish.part.tokens(cache reads excluded, matching codex accounting), recovers the final message from the lasttextpart, and measures duration from envelope timestamps.With this, OpenCode flips Transcript ingest to ✅ in the README support table. Remaining columns are filed: dispatch recipes + model flag (#153), shadow preflight (#154), write guard (#155) — each scoped with verified CLI/source evidence.
Details
harnesses/opencode.tomldeclares[transcript]+ the verified[tools]vocabulary (bashis the shell tool id;edit/writetakefilePath;apply_patchtakespatchText— ids and arg shapes checked againstpackages/opencode/src/tool/in the opencode repo).__skill_invokedmeta-check generalizes from hardcodedSkill/skillto descriptor-declaredskill_tool/skill_arg(defaults keep claude-code.toml untouched; OpenCode declaresskill/name— its native skill tool is a deterministic invocation event, sosurfaces_skill_invocation = trueand the meta-check grades from the transcript instead of the LLM-judge fallback).filePathinpath_arg,patchTextinapply_patch_paths) — additive, no effect on claude/codex classification.Schema change:
harness-descriptor.schema.jsongainsopencode-eventsin theparserenum and optionalskill_tool/skill_argstrings on[transcript]. No CLI change.Before / after (generated next-steps)
Verification
cargo test— 657 passed, 0 failed (478 lib / 99 cli / 80 run), including a new end-to-end test: staged run → simulatedopencode-events.jsonl→ingestyields parsed invocations, 125-token / 5s backfill, transcript final-message fallback, and a code-graded__skill_invoked(passed: true,grader: transcript_check).cargo clippy --all-targets -- -D warnings— clean.cargo fmt --check— clean.docs/opencode-notes.md(code map / what's wired / next enhancements),docs/byoh.md,docs/progressive-enhancements.md,harnesses/template.toml, harness-descriptor PR template.Event shapes verified against the opencode SDK types (
ToolPart/StepFinishPart) andrun.tsinanomalyco/opencodev1.18.3, per the don't-guess guardrail; a liveopencode runcapture is part of #153's acceptance (dispatch recipes) and will re-confirm the fixtures then.