Skip to content

[FEATURE]: plugin hook for streamed tool metadata (bash output is persisted before tool.execute.after can redact it) #51937

Closed as not planned

Description

@r-d-w

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Problem: a plugin that redacts secrets in tool.execute.after can't reach the copies of bash output that were already persisted while the command was still running.

While output streams, bash calls ctx.metadata({ metadata: { output } }). Each update is saved as a running-state message.part.updated row in the event table of opencode.db, before tool.execute.after runs. Mutating output.output / output.metadata in the after-hook fixes the final part, the model context and the truncated-output file, but the streamed rows keep the raw value.

Repro (1.18.18, macOS):

export const RedactDemo = async () => ({
  "tool.execute.after": async (_input, output) => {
    const scrub = (s: string) => s.replaceAll("SECRET-1234567890", "<redacted>")
    output.output = scrub(output.output)
    if (typeof output.metadata?.output === "string") output.metadata.output = scrub(output.metadata.output)
  },
})
  1. Load the plugin and have the model run printf SECRET-1234567890.
  2. The tool result shows <redacted>.
  3. sqlite3 ~/.local/share/opencode/opencode.db "select count(*) from event where instr(data, 'SECRET-1234567890') > 0" returns > 0.

Ask: either of these would let plugins close the gap:

  • a hook such as tool.execute.metadata, run on each ctx.metadata() update before it is published or persisted, which can mutate the metadata; or
  • an option not to persist running-state part updates, keeping only the final state.

Built-in redaction was declined in #19425 / #32183. This asks only for the hook, so plugins can do it themselves. We use it to mask 1Password op:// secrets that a plugin resolves for MCP auth.

Activity

  1. github-actions commented on Sep 28, 2026

    @github-actions
    Contributor

    This issue might be related to existing issues. Please check:

  2. r-d-w commented on Oct 6, 2026

    @r-d-w
    Author

    Checked these, none are duplicates:

  3. r-d-w commented on Oct 6, 2026

    @r-d-w
    Author

    @rekram1-node happy to send a PR for this if you'd take it.

    Approach: add a tool.execute.metadata hook that runs where a tool's ctx.metadata() update is published and persisted, with { tool, sessionID, callID } as input and a mutable { title, metadata } output. That way a plugin can rewrite streamed bash output before it's written to the event table. It's a no-op when no plugin registers it. I'd include a test showing that a registered hook's changes land in the persisted part.

    OK to proceed?

  4. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed write-up and repro, @r-d-w!

    This was reported on 1.18.18, which is OpenCode v1. v1 now only gets fixes for critical bugs (data loss, security problems, crashes or breakage with no workaround). New plugin hooks like tool.execute.metadata, or an option not to save running-state part updates, are unlikely to be added to v1.

    OpenCode v2 (the @opencode/cli package, opencode command) is a separate implementation with its own plugin API (execute.before / execute.after tool hooks and streamed progress updates). We'd encourage upgrading. If you find the same gap there (streamed tool progress saved before a plugin can redact it), please open a new issue for v2 or reply here, and maintainers will look at it through the normal flow. Related: #19425 and #32183 (built-in redaction, declined).

  5. opencodejr commented on Oct 29, 2026

    @opencodejr
    Contributor

    Closing this as not planned. The request (a hook to redact streamed ctx.metadata() updates before they're saved, or an option not to save running-state part updates) was reported on v1 (1.18.18). v1 only gets critical fixes, and we haven't heard back.

    Thanks again for the clear repro, @r-d-w. If v2 (@opencode/cli) has the same problem, where streamed tool progress is saved before a plugin's execute.after hook can redact it, please open a new issue with the v2 version and steps, and it will be looked at there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions