fix(permission): fire permission.ask hook for first-encounter commands#20634
fix(permission): fire permission.ask hook for first-encounter commands#20634YumaKakuya wants to merge 5 commits intoanomalyco:devfrom
Conversation
The permission.ask plugin hook was inside an if (!needsAsk) guard, preventing it from firing for first-encounter commands. Plugins could not participate in permission decisions for new commands. This moves the hook trigger before the early return so it fires regardless of needsAsk, allowing plugins to override the permission status (ask/allow/deny) for all commands. Existing tests updated to account for the async plugin hook trigger. Closes anomalyco#19927
|
The following comment was made by an LLM, it may be inaccurate: Found potential related PRs:
These PRs should be reviewed to ensure they're not duplicates or if they conflict with the changes in PR #20634. |
|
I noticed #19453 and #19470 also address this issue. This PR was based on the latest dev branch and includes regression tests for the hook behavior. Happy to close this if either of the existing PRs is preferred — just wanted to make sure the test coverage was available regardless of which approach is merged. |
Prevent Plugin.trigger from hanging the permission flow in environments where the plugin runtime initializes slowly. Falls back to the original permission status if the hook does not respond within 5 seconds.
|
Windows unit runner lost connection during post-test cleanup (tests completed: 300 pass / 0 fail before disconnect). All other checks are green. Re-running the Windows job. |
The permission.ask hook trigger has a 5s timeout, but waitForPending() polls with Bun.sleep(0) — in slow CI environments, the pending entry isn't created before polling ends, causing the test to hang until the 30s test timeout.
ec330e3 to
8f42e6f
Compare
Issue for this PR
Closes #19927
Type of change
What does this PR do?
The
permission.askplugin hook is defined in@opencode-ai/pluginand other
hooks (
shell.env,chat.system.transform, etc.) are triggeredcorrectly via
Plugin.trigger()— butpermission.askis never called.The root cause is the early return
if (!needsAsk) returnon L183 ofpackages/opencode/src/permission/index.ts. WhenneedsAskistrue(first-encounter command), execution skips past this guard into the
permission dialog — but there is no
Plugin.trigger("permission.ask", ...)call anywhere in the function, so the hook never fires regardless of
needsAsk.This PR adds the missing
Plugin.trigger("permission.ask")call beforethe
early-return guard. The hook receives the current status (
"ask","allow",or
"deny") and plugins can override it — e.g. a security plugin candeny
a command that rules would otherwise allow.
Three existing tests that assumed synchronous pending-list population
are
updated to use the existing
waitForPending()helper, since the asyncPlugin.triggercall now precedes the deferred creation.How did you verify your code works?
bun test test/permission/— 84 tests pass (0 fail)bun typecheck— 0 errorstest/permission/permission-hook.test.ts:Screenshots / recordings
N/A (no UI change)
Checklist