feat(core): add location-based permission service (#30287)

This commit is contained in:
Dax
2026-06-01 21:32:50 -04:00
committed by GitHub
parent acd620f411
commit 9b815bcbd2
65 changed files with 4970 additions and 552 deletions

View File

@@ -1,3 +1,4 @@
import { PermissionLegacy } from "@opencode-ai/core/permission/legacy"
import { Provider } from "@/provider/provider"
import { SessionLegacy } from "@opencode-ai/core/session/legacy"
import { serviceUse } from "@opencode-ai/core/effect/service-use"
@@ -15,7 +16,6 @@ import type { Agent } from "@/agent/agent"
import type { MessageV2 } from "./message-v2"
import { Plugin } from "@/plugin"
import { Permission } from "@/permission"
import { PermissionID } from "@/permission/schema"
import { EventV2Bridge } from "@/event-v2-bridge"
import { EventV2 } from "@opencode-ai/core/event"
import { Wildcard } from "@/util/wildcard"
@@ -38,7 +38,7 @@ export type StreamInput = {
parentSessionID?: string
model: Provider.Model
agent: Agent.Info
permission?: Permission.Ruleset
permission?: PermissionLegacy.Ruleset
system: string[]
messages: ModelMessage[]
small?: boolean
@@ -165,7 +165,7 @@ const live: Layer.Layer<
return { approved: true }
}
const id = PermissionID.ascending()
const id = PermissionLegacy.ID.ascending()
let unsub: EventV2.Unsubscribe | undefined
try {
unsub = await bridge.promise(

View File

@@ -1,3 +1,4 @@
import { PermissionLegacy } from "@opencode-ai/core/permission/legacy"
import type { Auth } from "@/auth"
import { SessionLegacy } from "@opencode-ai/core/session/legacy"
import type { RuntimeFlags } from "@/effect/runtime-flags"
@@ -22,7 +23,7 @@ type PrepareInput = {
readonly parentSessionID?: string
readonly model: Provider.Model
readonly agent: Agent.Info
readonly permission?: Permission.Ruleset
readonly permission?: PermissionLegacy.Ruleset
readonly system: string[]
readonly messages: ModelMessage[]
readonly small?: boolean

View File

@@ -1,3 +1,4 @@
import { PermissionLegacy } from "@opencode-ai/core/permission/legacy"
import { Image } from "@/image/image"
import { SessionLegacy } from "@opencode-ai/core/session/legacy"
import { Cause, Deferred, Effect, Exit, Layer, Context, Scope, Schema } from "effect"
@@ -204,7 +205,7 @@ export const layer = Layer.effect(
time: { start: match.part.state.time.start, end: Date.now() },
},
})
if (error instanceof Permission.RejectedError || error instanceof Question.RejectedError) {
if (error instanceof PermissionLegacy.RejectedError || error instanceof Question.RejectedError) {
ctx.blocked = ctx.shouldBreak
}
yield* settleToolCall(toolCallID)

View File

@@ -1,3 +1,4 @@
import { PermissionLegacy } from "@opencode-ai/core/permission/legacy"
import path from "path"
import { SessionLegacy } from "@opencode-ai/core/session/legacy"
import os from "os"
@@ -1220,7 +1221,7 @@ export const layer = Layer.effect(
const message = yield* createUserMessage(input)
yield* sessions.touch(input.sessionID)
const permissions: Permission.Rule[] = []
const permissions: PermissionLegacy.Rule[] = []
for (const [t, enabled] of Object.entries(input.tools ?? {})) {
permissions.push({ permission: t, action: enabled ? "allow" : "deny", pattern: "*" })
}

View File

@@ -1,3 +1,4 @@
import { PermissionLegacy } from "@opencode-ai/core/permission/legacy"
import { Slug } from "@opencode-ai/core/util/slug"
import { SessionLegacy } from "@opencode-ai/core/session/legacy"
import { serviceUse } from "@opencode-ai/core/effect/service-use"
@@ -233,7 +234,7 @@ export const Info = Schema.Struct({
version: Schema.String,
metadata: optionalOmitUndefined(Metadata),
time: Time,
permission: optionalOmitUndefined(Permission.Ruleset),
permission: optionalOmitUndefined(PermissionLegacy.Ruleset),
revert: optionalOmitUndefined(Revert),
}).annotate({ identifier: "Session" })
export type Info = Types.DeepMutable<Schema.Schema.Type<typeof Info>>
@@ -258,7 +259,7 @@ export const CreateInput = Schema.optional(
agent: Schema.optional(Schema.String),
model: Schema.optional(Model),
metadata: Schema.optional(Metadata),
permission: Schema.optional(Permission.Ruleset),
permission: Schema.optional(PermissionLegacy.Ruleset),
workspaceID: Schema.optional(WorkspaceV2.ID),
}),
)
@@ -282,7 +283,7 @@ export const SetMetadataInput = Schema.Struct({
})
export const SetPermissionInput = Schema.Struct({
sessionID: SessionID,
permission: Permission.Ruleset,
permission: PermissionLegacy.Ruleset,
})
export const SetRevertInput = Schema.Struct({
sessionID: SessionID,
@@ -348,7 +349,7 @@ const UpdatedInfo = Schema.Struct({
version: Schema.optional(Schema.NullOr(Schema.String)),
metadata: Schema.optional(Schema.NullOr(Metadata)),
time: Schema.optional(UpdatedTime),
permission: Schema.optional(Schema.NullOr(Permission.Ruleset)),
permission: Schema.optional(Schema.NullOr(PermissionLegacy.Ruleset)),
revert: Schema.optional(Schema.NullOr(Revert)),
})
@@ -472,7 +473,7 @@ export interface Interface {
agent?: string
model?: Schema.Schema.Type<typeof Model>
metadata?: typeof Metadata.Type
permission?: Permission.Ruleset
permission?: PermissionLegacy.Ruleset
workspaceID?: WorkspaceV2.ID
}) => Effect.Effect<Info>
readonly fork: (input: { sessionID: SessionID; messageID?: MessageID }) => Effect.Effect<Info, NotFound>
@@ -481,7 +482,7 @@ export interface Interface {
readonly setTitle: (input: { sessionID: SessionID; title: string }) => Effect.Effect<void>
readonly setArchived: (input: { sessionID: SessionID; time?: number }) => Effect.Effect<void>
readonly setMetadata: (input: typeof SetMetadataInput.Type) => Effect.Effect<void>
readonly setPermission: (input: { sessionID: SessionID; permission: Permission.Ruleset }) => Effect.Effect<void>
readonly setPermission: (input: { sessionID: SessionID; permission: PermissionLegacy.Ruleset }) => Effect.Effect<void>
readonly setRevert: (input: {
sessionID: SessionID
revert: Info["revert"]
@@ -570,7 +571,7 @@ export const layer: Layer.Layer<
directory: string
path?: string
metadata?: typeof Metadata.Type
permission?: Permission.Ruleset
permission?: PermissionLegacy.Ruleset
}) {
const ctx = yield* InstanceState.context
const result: Info = {
@@ -748,7 +749,7 @@ export const layer: Layer.Layer<
agent?: string
model?: Schema.Schema.Type<typeof Model>
metadata?: typeof Metadata.Type
permission?: Permission.Ruleset
permission?: PermissionLegacy.Ruleset
workspaceID?: WorkspaceV2.ID
}) {
const ctx = yield* InstanceState.context
@@ -842,7 +843,7 @@ export const layer: Layer.Layer<
const setPermission = Effect.fn("Session.setPermission")(function* (input: {
sessionID: SessionID
permission: Permission.Ruleset
permission: PermissionLegacy.Ruleset
}) {
yield* patch(input.sessionID, { permission: [...input.permission], time: { updated: Date.now() } }).pipe(
Effect.orDie,