Dashboard › opencode › Distillation
3644ddec-a9fa-403d-bb6e-60f52885e1d0["lore_tm_v1_GAjwwq18BV9OCY7CA9BdAx_HXFGkW-XQck75BxGiAAw","lore_tm_v1_8I1jb-neue5WTWxPwweSLbqEXb-TMBg34ftS4J2qEJ0","lore_tm_v1_5_awMTpwxIRNcSSCZAI71GUgzwOq3OyxRGNXVV_qaJQ","lore_tm_v1_-LqM4OlKc7G3xIBu1ZB18FqlZgKoF5LC5h3KQHbSXaM","lore_tm_v1_qGS_NkRG04-YOZ7aUbSfT6Vn7KfZOwSIfuqZUh_QcAo","lore_tm_v1_Tk4NKXRwqYtHh40617ZXOGgrb4FkiVTTlmVCTjilC7c","lore_tm_v1_kudMwofh88_oJ_UVAQRQBT0Eua57XiHRpMGEskY8snc","lore_tm_v1_JuQrzJ75naQSy5IO69iiyxYwB2tUuiTCmBqHS1UvHaQ","lore_tm_v1_VtQk1W68et6DC0RGOh7pTz5E5lk99iMRNbAaVV-MZ0w"]
Date: Sep 8, 2026
/home/byk/Code/opencode-v2-pilot/packages/core/src/permission.ts, /home/byk/Code/opencode-v2-pilot/packages/core/src/plugin/promise.ts, and /home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/adapter.ts; the broader search also covered Core tool/plugin implementations under /home/byk/Code/opencode-v2-pilot/packages/core/src/tool/ and /home/byk/Code/opencode-v2-pilot/packages/core/src/plugin/.packages/core/src/permission.ts defines Permission.DeclinedError with no fields, Permission.CorrectedError with feedback: Schema.String, and Permission.BlockedError with rules, permission, resources, and optional reason; BlockedError.message returns reason ?? \Permission denied: ${this.permission}``.Permission.Interface.assert in packages/core/src/permission.ts:105 returns Effect.Effect<void, Error | SessionErrors.NotFoundError>, where Permission.Error is BlockedError | CorrectedError; DeclinedError is deliberately absent from the public typed error union.Permission.assert in packages/core/src/permission.ts:221-252 evaluates configured/saved permission rules: "deny" fails with BlockedError, "allow" succeeds immediately, and "ask" creates a pending request and awaits its Deferred.Permission.assert deliberately tunnels Permission.DeclinedError as a defect via Effect.catchTag("Permission.DeclinedError", (error) => Effect.die(error)) at packages/core/src/permission.ts:242, while CorrectedError remains a typed failure so a leaf can turn it into a tool failure and allow the model to continue; pending requests are deleted in Effect.ensuring.Permission.reply in packages/core/src/permission.ts:254-309 handles "reject" by failing the selected pending request with CorrectedError({ feedback: input.message }) when a message exists, otherwise DeclinedError; it then rejects every other pending request for the same session with DeclinedError. Non-reject replies succeed the deferred, and "always" persists save rules and automatically resolves other now-allowed pending requests.Permission.evaluate in packages/core/src/permission.ts:87-97 selects the last matching wildcard rule and defaults to { action, resource: "*", effect: "ask" }; missing agent permissions default to [{ action: "*", resource: "*", effect: "deny" }].packages/core/src/plugin/promise.ts is a 3-line re-export surface: it exports the PluginPromise namespace from ./promise.js and exports fromPromise from @opencode/plugin/promise/adapter.fromPromise(plugin) implementation is located at packages/plugin/src/promise/adapter.ts:218; its permission bridge is at lines 434-446 and its Promise-tool error conversion is in executePromiseTool at lines 612-639.packages/plugin/src/promise/adapter.ts:34-36 defines a private TypedFailure wrapper carrying readonly error: unknown.packages/plugin/src/promise/adapter.ts:437-442 runs host.permission.assert(input) through the captured Effect context and converts every typed Effect failure into a defect using Effect.catch((error) => Effect.die(new TypedFailure(error))).context2.tool.transform are wrapped with executePromiseTool(tool, input, context) at packages/plugin/src/promise/adapter.ts:479-483; updated tools receive the same wrapper at lines 484-496, while existing Effect tools exposed through list() and get() use promiseExecutor.executePromiseTool in packages/plugin/src/promise/adapter.ts:612-639 runs the Promise tool with Effect.tryPromise; if the rejection is a TypedFailure, it becomes a typed Tool.Error, while every other rejection becomes a defect through Effect.die(error).executePromiseTool derives the model-facing Tool.Error.message in this precedence order: 1. a non-null object with string feedback uses feedback; 2. an Error uses .message; 3. all other values use String(error.error). The resulting Tool.Error also preserves the original wrapped value in its error field.ctx.permission.assert resolves normally; Permission.CorrectedError({ feedback }) is wrapped as a TypedFailure defect across the Promise boundary and then converted by executePromiseTool into Tool.Error with message exactly equal to feedback; ordinary Promise-tool defects do not use TypedFailure and remain defects; Permission.DeclinedError is already converted to a defect inside Core before the adapter’s typed-error catch, so it retains its established defect tunnel./home/byk/Code/opencode-v2-pilot/packages/plugin/AGENTS.md: the package has Effect and Promise versions; every Effect plugin domain must extend its corresponding Effect API client interface from @opencode/client/effect/api; functions already present on the Effect API client interface must not be redefined; plugin domains should add only functions meaningful in plugin context.