refactor(core): move v1 schemas into core (#30473)

This commit is contained in:
Dax
2026-06-03 02:42:13 +00:00
committed by GitHub
parent 0543fd29c8
commit 83452558f7
129 changed files with 1578 additions and 1227 deletions
+31 -31
View File
@@ -1,48 +1,48 @@
import { ConfigPermission } from "@/config/permission"
import { ConfigPermissionV1 } from "@opencode-ai/core/v1/config/permission"
import { InstanceState } from "@/effect/instance-state"
import * as Log from "@opencode-ai/core/util/log"
import { Wildcard } from "@opencode-ai/core/util/wildcard"
import { Deferred, Effect, Layer, Context } from "effect"
import os from "os"
import { PermissionLegacy } from "@opencode-ai/core/permission/legacy"
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
import { EventV2Bridge } from "@/event-v2-bridge"
import { EventV2 } from "@opencode-ai/core/event"
const log = Log.create({ service: "permission" })
export const Event = {
Asked: EventV2.define({ type: "permission.asked", schema: PermissionLegacy.Request.fields }),
Asked: EventV2.define({ type: "permission.asked", schema: PermissionV1.Request.fields }),
Replied: EventV2.define({
type: "permission.replied",
schema: {
sessionID: PermissionLegacy.Request.fields.sessionID,
requestID: PermissionLegacy.ID,
reply: PermissionLegacy.Reply,
sessionID: PermissionV1.Request.fields.sessionID,
requestID: PermissionV1.ID,
reply: PermissionV1.Reply,
},
}),
}
export interface Interface {
readonly ask: (input: PermissionLegacy.AskInput) => Effect.Effect<void, PermissionLegacy.Error>
readonly reply: (input: PermissionLegacy.ReplyInput) => Effect.Effect<void, PermissionLegacy.NotFoundError>
readonly list: () => Effect.Effect<ReadonlyArray<PermissionLegacy.Request>>
readonly ask: (input: PermissionV1.AskInput) => Effect.Effect<void, PermissionV1.Error>
readonly reply: (input: PermissionV1.ReplyInput) => Effect.Effect<void, PermissionV1.NotFoundError>
readonly list: () => Effect.Effect<ReadonlyArray<PermissionV1.Request>>
}
interface PendingEntry {
info: PermissionLegacy.Request
deferred: Deferred.Deferred<void, PermissionLegacy.RejectedError | PermissionLegacy.CorrectedError>
info: PermissionV1.Request
deferred: Deferred.Deferred<void, PermissionV1.RejectedError | PermissionV1.CorrectedError>
}
interface State {
pending: Map<PermissionLegacy.ID, PendingEntry>
approved: PermissionLegacy.Rule[]
pending: Map<PermissionV1.ID, PendingEntry>
approved: PermissionV1.Rule[]
}
export function evaluate(
permission: string,
pattern: string,
...rulesets: PermissionLegacy.Ruleset[]
): PermissionLegacy.Rule {
...rulesets: PermissionV1.Ruleset[]
): PermissionV1.Rule {
return (
rulesets
.flat()
@@ -64,14 +64,14 @@ export const layer = Layer.effect(
Effect.fn("Permission.state")(function* (ctx) {
void ctx
const state = {
pending: new Map<PermissionLegacy.ID, PendingEntry>(),
pending: new Map<PermissionV1.ID, PendingEntry>(),
approved: [],
}
yield* Effect.addFinalizer(() =>
Effect.gen(function* () {
for (const item of state.pending.values()) {
yield* Deferred.fail(item.deferred, new PermissionLegacy.RejectedError())
yield* Deferred.fail(item.deferred, new PermissionV1.RejectedError())
}
state.pending.clear()
}),
@@ -81,7 +81,7 @@ export const layer = Layer.effect(
}),
)
const ask = Effect.fn("Permission.ask")(function* (input: PermissionLegacy.AskInput) {
const ask = Effect.fn("Permission.ask")(function* (input: PermissionV1.AskInput) {
const { approved, pending } = yield* InstanceState.get(state)
const { ruleset, ...request } = input
let needsAsk = false
@@ -90,7 +90,7 @@ export const layer = Layer.effect(
const rule = evaluate(request.permission, pattern, ruleset, approved)
log.info("evaluated", { permission: request.permission, pattern, action: rule })
if (rule.action === "deny") {
return yield* new PermissionLegacy.DeniedError({
return yield* new PermissionV1.DeniedError({
ruleset: ruleset.filter((rule) => Wildcard.match(request.permission, rule.permission)),
})
}
@@ -100,8 +100,8 @@ export const layer = Layer.effect(
if (!needsAsk) return
const id = request.id ?? PermissionLegacy.ID.ascending()
const info: PermissionLegacy.Request = {
const id = request.id ?? PermissionV1.ID.ascending()
const info: PermissionV1.Request = {
id,
sessionID: request.sessionID,
permission: request.permission,
@@ -112,7 +112,7 @@ export const layer = Layer.effect(
}
log.info("asking", { id, permission: info.permission, patterns: info.patterns })
const deferred = yield* Deferred.make<void, PermissionLegacy.RejectedError | PermissionLegacy.CorrectedError>()
const deferred = yield* Deferred.make<void, PermissionV1.RejectedError | PermissionV1.CorrectedError>()
pending.set(id, { info, deferred })
yield* events.publish(Event.Asked, info)
return yield* Effect.ensuring(
@@ -123,10 +123,10 @@ export const layer = Layer.effect(
)
})
const reply = Effect.fn("Permission.reply")(function* (input: PermissionLegacy.ReplyInput) {
const reply = Effect.fn("Permission.reply")(function* (input: PermissionV1.ReplyInput) {
const { approved, pending } = yield* InstanceState.get(state)
const existing = pending.get(input.requestID)
if (!existing) return yield* new PermissionLegacy.NotFoundError({ requestID: input.requestID })
if (!existing) return yield* new PermissionV1.NotFoundError({ requestID: input.requestID })
pending.delete(input.requestID)
yield* events.publish(Event.Replied, {
@@ -139,8 +139,8 @@ export const layer = Layer.effect(
yield* Deferred.fail(
existing.deferred,
input.message
? new PermissionLegacy.CorrectedError({ feedback: input.message })
: new PermissionLegacy.RejectedError(),
? new PermissionV1.CorrectedError({ feedback: input.message })
: new PermissionV1.RejectedError(),
)
for (const [id, item] of pending.entries()) {
@@ -151,7 +151,7 @@ export const layer = Layer.effect(
requestID: item.info.id,
reply: "reject",
})
yield* Deferred.fail(item.deferred, new PermissionLegacy.RejectedError())
yield* Deferred.fail(item.deferred, new PermissionV1.RejectedError())
}
return
}
@@ -200,8 +200,8 @@ function expand(pattern: string): string {
return pattern
}
export function fromConfig(permission: ConfigPermission.Info) {
const ruleset: PermissionLegacy.Rule[] = []
export function fromConfig(permission: ConfigPermissionV1.Info) {
const ruleset: PermissionV1.Rule[] = []
for (const [key, value] of Object.entries(permission)) {
if (typeof value === "string") {
ruleset.push({ permission: key, action: value, pattern: "*" })
@@ -214,11 +214,11 @@ export function fromConfig(permission: ConfigPermission.Info) {
return ruleset
}
export function merge(...rulesets: PermissionLegacy.Ruleset[]): PermissionLegacy.Rule[] {
export function merge(...rulesets: PermissionV1.Ruleset[]): PermissionV1.Rule[] {
return rulesets.flat()
}
export function disabled(tools: string[], ruleset: PermissionLegacy.Ruleset): Set<string> {
export function disabled(tools: string[], ruleset: PermissionV1.Ruleset): Set<string> {
const edits = ["edit", "write", "apply_patch"]
return new Set(
tools.filter((tool) => {