Skip to content

refactor(plugin): return Effect from ToolContext.ask#21986

Merged
kitlangton merged 2 commits intodevfrom
kit/plugin-tool-ask-effect
Apr 11, 2026
Merged

refactor(plugin): return Effect from ToolContext.ask#21986
kitlangton merged 2 commits intodevfrom
kit/plugin-tool-ask-effect

Conversation

@kitlangton
Copy link
Copy Markdown
Contributor

Summary

  • Change ToolContext.ask return type from Promise<void> to Effect.Effect<void> in @opencode-ai/plugin
  • Remove the Effect.runPromise bridge in registry.ts that was converting between the two
  • Add effect as a dependency of the plugin package

Test plan

  • bun run typecheck passes for both packages/plugin and packages/opencode
  • bun run test test/tool/ — all 167 tests pass

@kitlangton kitlangton merged commit d84cc33 into dev Apr 11, 2026
9 of 11 checks passed
@kitlangton kitlangton deleted the kit/plugin-tool-ask-effect branch April 11, 2026 03:50
mrsimpson pushed a commit to mrsimpson/opencode that referenced this pull request Apr 14, 2026
mrsimpson added a commit to codemcp/workflows that referenced this pull request Apr 22, 2026
## Root Cause

OpenCode PR [#21986](anomalyco/opencode#21986) (merged **April 10, 2026**, commit `bfef334b`) deliberately changed `ToolContext.ask` in the plugin SDK from returning `Promise<void>` to `Effect.Effect<void>`:

```diff
-  ask(input: AskInput): Promise<void>
+  ask(input: AskInput): Effect.Effect<void>
```

This broke the previous fix from commit `9e92eb3` (April 1, 2026), which used `await context.ask(...)` and worked correctly at the time. After the opencode change, `await`-ing an Effect object is a no-op — the Effect is never executed, so the permission prompt was silently skipped.

## Fix

Add `effect` as a peer dependency (it is always present in the process since the plugin runs inside opencode) and a dev dependency for local type checking. Use `Effect.runPromise()` to bridge the Effect into the async/await context of the plugin's `execute` functions.

The `ask` call is centralised in the `wrap()` decorator in `plugin.ts` so all five tools get permission enforcement without duplicating the call in each handler.

## Changes

- `package.json`: add `effect >=3.0.0` as peer + dev dependency
- `src/types.ts`: fix local `ToolContext.ask` type to match real SDK (`Effect.Effect<void>`)
- `src/plugin.ts`: use `Effect.runPromise(ctx.ask(...))` in the `wrap()` decorator; import `Effect` from `effect`
- `test/e2e/plugin.test.ts`: update `createMockToolContext()` helper; mock `ask` returns `Effect.void` instead of a resolved Promise
xywsxp pushed a commit to xywsxp/opencode that referenced this pull request Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant