Skip to content

feat(scaffold): OpenCode commit-nudge plugin#17

Merged
vivek7405 merged 2 commits into
mainfrom
feat/opencode-commit-nudge-plugin
May 19, 2026
Merged

feat(scaffold): OpenCode commit-nudge plugin#17
vivek7405 merged 2 commits into
mainfrom
feat/opencode-commit-nudge-plugin

Conversation

@vivek7405
Copy link
Copy Markdown
Collaborator

Summary

Closes the last gap in cross-agent commit-frequency enforcement. OpenCode users now get the same nudge that Claude Code, Gemini CLI, and Cursor users got in PR #13.

Mechanism

OpenCode doesn't use shell-script hooks. It uses TS plugin modules loaded by Bun at runtime, registered automatically when dropped into .opencode/plugins/. The plugin exports an async function that returns a Hooks object whose handlers fire on lifecycle events.

The plugin in this PR:

  1. Hooks tool.execute.after
  2. Filters to input.tool === "edit" || input.tool === "write"
  3. Runs git status --porcelain via the injected Bun shell ($)
  4. If uncommitted file count crosses WEBJS_COMMIT_NUDGE_THRESHOLD (default 4), appends a reminder to output.output so the agent sees it on the next turn

Same threshold and same message text as the Claude / Gemini / Cursor hooks. Skipped on main/master and outside a git work tree.

Updated enforcement matrix

Agent Mechanism
Claude Code .claude/hooks/nudge-uncommitted.sh (PostToolUse)
Gemini CLI .gemini/hooks/nudge-uncommitted.sh (AfterTool)
Cursor 1.7+ .cursor/hooks/nudge-uncommitted.sh (afterFileEdit)
OpenCode (new) .opencode/plugins/nudge-uncommitted.ts (tool.execute.after)
Windsurf text rule only (post-write hooks can't inject context)
GitHub Copilot text rule only (no hooks API)
Google Antigravity text rule only (no hooks API)

Plus the tool-agnostic .hooks/pre-commit that runs webjs test + webjs check for everyone.

Commits

Two. First adds the plugin file plus the create.js copy-list entry. Second updates the enforcement matrix in framework AGENTS.md and scaffold templates/AGENTS.md.

Test plan

  • Framework npm test passes on every commit (pre-commit gate)
  • Plugin signature matches @opencode-ai/plugin types per https://opencode.ai/docs/plugins/
  • End-to-end test by running OpenCode against a scaffolded webjs app with 4+ uncommitted files would require an OpenCode install. Not done in this PR. The plugin logic mirrors the Claude / Gemini / Cursor hooks which are all known-good.

References

vivek7405 added 2 commits May 19, 2026 16:30
OpenCode does not have shell-script hooks; it uses TS plugin
modules loaded as-is by Bun. This plugin is the counterpart of
the .claude/, .gemini/, .cursor/ hooks already in the scaffold.

The plugin hooks tool.execute.after, filters to edit/write tools,
runs 'git status --porcelain' via the injected Bun shell, and
when uncommitted file count crosses WEBJS_COMMIT_NUDGE_THRESHOLD
(default 4), appends a nudge to output.output so the agent sees
it on its next turn. Same threshold and same message text as the
other agents' hooks.

Skipped on main/master (different guards cover that) and outside
a git work tree.

Auto-discovered by OpenCode from .opencode/plugins/ at startup.
No opencode.json registration needed.

lib/create.js scaffold copy list extended so new apps ship the
plugin file alongside the other hook configs.

Doc reference: https://opencode.ai/docs/plugins/
Updates the enforcement matrix in both framework AGENTS.md and
scaffold templates/AGENTS.md. OpenCode moves from 'text rule
only (TS plugin support planned)' to a real programmatic entry
that fires on tool.execute.after at threshold 4, matching the
Claude Code / Gemini CLI / Cursor coverage.

Only Windsurf, Copilot, and Antigravity remain text-rule-only.
Windsurf because its post-write hooks cannot inject context
back to the agent; Copilot and Antigravity because they have
no hooks API.
@vivek7405 vivek7405 merged commit c9ba4b3 into main May 19, 2026
@vivek7405 vivek7405 deleted the feat/opencode-commit-nudge-plugin branch May 19, 2026 11:39
vivek7405 added a commit that referenced this pull request May 21, 2026
feat(scaffold): OpenCode commit-nudge plugin
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.

1 participant