Dashboard › opencode › Distillation
3ea40760-a0b5-41a9-9529-8a21cf466d46["lore_tm_v1_aNpj4_Sx6b9sFc_YwQSeNXZo7bNzmmXOcg2xJXaAZzk","lore_tm_v1_yrEE_2x0iIl4lGKwix3QCx5_T13ECnQCubnWKXBWCt0","lore_tm_v1_AnTnJA5h3nigfMmp3AnpMd8iHqeeSZqYp1k_jkaH_2w","lore_tm_v1_yAH6iwaS4XdDRflncW8l2bxMFeta4qPBgBSDaXximxo","lore_tm_v1_TuyO-kBut_-6O3NIXRUz6DvhfdLNNlk5OydvORH1zb0","lore_tm_v1_J8WYkAbRsca73BPtUhMT9kVhzdoV3IG3ERonVG9eqa4"]
Date: Sep 14, 2026
/home/byk/Code/opencode/packages/opencode/src/effect/instance-registry.ts maintains disposers as Set<(directory: string) => Promise<void>>; registerDisposer() adds a disposer and returns a callback that removes it, while disposeInstance(directory) invokes every registered disposer concurrently through Promise.allSettled(...), so individual rejections do not reject the aggregate disposal call./home/byk/Code/opencode/packages/opencode/src/control-plane/workspace.ts:589 claims session events with events.claim(input.sessionID, input.workspaceID ?? previous.projectID), preferring input.workspaceID and falling back to previous.projectID./home/byk/Code/opencode/packages/opencode/src/permission/index.ts defines permission Interface operations ask(input: PermissionV1.AskInput), reply(input: PermissionV1.ReplyInput), and list(), exposed by Service with identifier "@opencode/Permission"./home/byk/Code/opencode/packages/opencode/src/permission/index.ts is instance-scoped through InstanceState.make<State> and contains pending: Map<PermissionV1.ID, PendingEntry> plus approved: PermissionV1.Rule[]; its finalizer fails every pending deferred with PermissionV1.RejectedError and clears the map.evaluate(permission, pattern, ...rulesets) in /home/byk/Code/opencode/packages/opencode/src/permission/index.ts flattens rules and uses findLast() with Wildcard.match() for both permission and pattern, making the last matching rule authoritative; if none matches, it returns { action: "ask", permission, pattern: "*" }.Permission.ask evaluates each requested pattern against the supplied ruleset followed by instance-approved rules. A "deny" immediately produces PermissionV1.DeniedError containing supplied rules whose permission wildcard matches; all-"allow" requests return immediately, while any "ask" result creates a pending request.request.id ?? PermissionV1.ID.ascending(), preserve sessionID, permission, patterns, metadata, always, and tool, publish PermissionV1.Event.Asked, and await a Deferred<void, PermissionV1.RejectedError | PermissionV1.CorrectedError> whose pending-map entry is removed with Effect.ensuring(...).Permission.reply returns PermissionV1.NotFoundError({ requestID }) for an unknown pending request and otherwise removes the request before publishing PermissionV1.Event.Replied with its sessionID, requestID, and reply."reject" permission reply fails the selected deferred with PermissionV1.CorrectedError({ feedback: input.message }) when a message exists, otherwise PermissionV1.RejectedError; it also rejects every other pending request in the same session, publishes a "reject" reply event for each, and removes each from pending."once" adds no lasting approval, while other successful replies add "allow" rules for every pattern in existing.info.always, then automatically resolve same-session pending requests whose patterns all evaluate to "allow", publishing reply "always" for each.Permission.list returns the info objects for all current pending entries via Array.from(pending.values(), (item) => item.info).expand(pattern) in /home/byk/Code/opencode/packages/opencode/src/permission/index.ts expands "~", "~/", "$HOME", and "$HOME/" prefixes using os.homedir(); other patterns are unchanged.fromConfig(permission: ConfigPermissionV1.Info) converts string-valued entries into { permission: key, action: value, pattern: "*" }; object-valued entries become one rule per pattern after expand(pattern). merge(...rulesets) simply returns rulesets.flat().disabled(tools, ruleset) in /home/byk/Code/opencode/packages/opencode/src/permission/index.ts maps tools "edit", "write", and "apply_patch" to permission "edit"; maps "list_mcp_resources", "list_mcp_resource_templates", and "read_mcp_resource" to "read"; and otherwise uses the tool name. A tool is disabled only when the last permission-matching rule has pattern === "*" and action === "deny".visibleTools<T>(tools, ruleset) removes entries named by disabled(...); the permission layer node is LayerNode.make({ service: Service, layer: layer, deps: [EventV2Bridge.node] })./home/byk/Code/opencode/packages/schema/src/v1/permission.ts and /home/byk/Code/opencode/packages/core/src/v1/permission.ts.