Skip to content

Enforce per-state allowed_commands in the opencode plugin - #6

Merged
azurewraith merged 1 commit into
statewright:mainfrom
costajohnt:opencode-allowed-commands
Jul 18, 2026
Merged

Enforce per-state allowed_commands in the opencode plugin#6
azurewraith merged 1 commit into
statewright:mainfrom
costajohnt:opencode-allowed-commands

Conversation

@costajohnt

Copy link
Copy Markdown
Contributor

Fixes #5.

The opencode plugin sent only tool_name to the hook server, so once bash was allowed in a state, any command ran — allowed_commands was advisory. The claude-code hook, OMX, and Pi plugins all classify bash commands client-side; this ports that same classification to opencode:

  • classifyBashCommand (exported, pure): destructive ops always blocked, redirect/interpreter heuristics when Write/Edit aren't in allowed tools, allowed_commands prefix matching (same semantics as OMX/Pi). Wired into tool.execute.before after the gateway's tool-level decision; fail-open when no state is available so plain opencode sessions are unaffected.
  • /hooks/state now includes allowed_commands (the MCP statewright_get_state already returned it; the HTTP endpoint didn't), giving the plugin the list to match against.
  • The destructive pattern treats newline as a command separator and tests the trimmed command — closes two bypasses the ^-anchored patterns elsewhere miss (echo hi\nrm -rf / riding an allowed echo prefix, and leading whitespace). The OMX/claude-code classifiers may want the same hardening; happy to follow up if there's interest.
  • Tool-id casing: opencode uses lowercase (write/edit), so the Write/Edit heuristics accept both spellings.

Tests: 18 vitest cases for the pure classifier (plugins/opencode/src/index.spec.ts, wired as npm test matching the OMX plugin's setup); cargo test --workspace passes; warning count unchanged vs main.

The opencode plugin only sent tool_name to the hook server, so a state's
allowed_commands had no effect once bash itself was allowed - unlike the
claude-code hook, OMX, and Pi plugins, which all classify bash commands
client-side. Port that classification into the opencode plugin (destructive
ops always blocked, redirect/interpreter heuristics without Write/Edit,
allowed_commands prefix matching) and expose allowed_commands on the
/hooks/state response so the plugin has the list to match against.

The destructive pattern also treats newline as a command separator and
tests the trimmed command, closing two bypasses the anchored patterns
elsewhere miss (newline chaining and leading whitespace).

Fixes statewright#5
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.

opencode plugin: per-state allowed_commands are not enforced (parity gap with claude-code/omx/pi)

2 participants