Skip to content

fix(opencode): intercept annotate/review/archive commands before LLM#718

Merged
backnotprop merged 1 commit into
mainfrom
fix/713
May 13, 2026
Merged

fix(opencode): intercept annotate/review/archive commands before LLM#718
backnotprop merged 1 commit into
mainfrom
fix/713

Conversation

@backnotprop
Copy link
Copy Markdown
Owner

Summary

  • Move /plannotator-annotate, /plannotator-review, /plannotator-archive from the post-hoc event handler into command.execute.before — same pattern plannotator-last already used — so the agent never sees the command body or appended args.
  • Empty the bodies of the three .md files; only the frontmatter is needed for OpenCode to register the slash command.
  • Fix output.parts = []output.parts.length = 0: OpenCode's caller (prompt.ts:1944-1979) holds a direct reference to the parts array and ignores any new array assigned to the hook's output.parts, so the previous reassignment was a no-op.

Root cause

When the user runs /plannotator-annotate /path/to/huge.md, OpenCode appends the args to the .md body and runs resolvePromptParts() on the combined string. That function (prompt.ts) walks file references and pushes { type: "file", url, filename, mime } parts. The agent then receives the file as a FilePart in a user message — before the annotation UI even exists. With a large file plus GLM-5, that blows the context and triggers auto-compact.

plannotator-last already used command.execute.before to intercept the prompt before it reached the LLM. The other three commands relied on the event handler, which fires after command.executed is published — i.e. after the agent has already processed the turn.

Test plan

  • bun test apps/opencode-plugin/ — 37 pass
  • bun build apps/opencode-plugin/index.ts — clean
  • Manual: /plannotator-annotate <large markdown file> in OpenCode no longer triggers auto-compact; annotation UI opens immediately; feedback is delivered after submit.
  • Manual: /plannotator-review, /plannotator-archive, /plannotator-last still behave as before.

Fixes #713

…713)

OpenCode's command dispatcher appends `arguments` to the `.md` body and
runs `resolvePromptParts()` over the combined string, which auto-attaches
any file path it finds as a `FilePart`. With `/plannotator-annotate
/path/to/huge.md`, that meant the agent received the file's content as a
user message before the annotation UI even opened — blowing the context
on large files (GLM-5 auto-compact reported in #713).

Move `plannotator-annotate`, `plannotator-review`, and `plannotator-archive`
from the post-hoc `event` handler to `command.execute.before`, matching
the pattern `plannotator-last` already used. The hook clears `output.parts`
in place so the agent never receives the command turn; handlers then run
the UI and inject feedback via `client.session.prompt` as a separate turn.

Empty the bodies of the three `.md` files for defense in depth — only the
frontmatter is needed for OpenCode to register the slash command.

Also fixes a latent bug in the `plannotator-last` path: `output.parts = []`
reassigns the throwaway wrapper object's property but doesn't touch the
`parts` array the caller in `prompt.ts:1944` uses directly. Switched to
`output.parts.length = 0` to mutate in place. `plannotator-last` only
escaped notice because its parts array was always a single benign text
part.
@backnotprop backnotprop merged commit 1c40655 into main May 13, 2026
10 checks passed
@backnotprop backnotprop deleted the fix/713 branch May 13, 2026 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Large files and compacting issues

1 participant