chore: generate

This commit is contained in:
opencode-agent[bot]
2026-05-31 01:09:55 +00:00
parent 7f571d36ea
commit 102c8353e0
71 changed files with 11252 additions and 8889 deletions

View File

@@ -48,17 +48,9 @@ export const layer = Layer.effect(
effect.pipe(Effect.mapError((cause) => new AccountRepoError({ message: "Database operation failed", cause })))
const current = Effect.fnUntraced(function* () {
const state = yield* db
.select()
.from(AccountStateTable)
.where(eq(AccountStateTable.id, ACCOUNT_STATE_ID))
.get()
const state = yield* db.select().from(AccountStateTable).where(eq(AccountStateTable.id, ACCOUNT_STATE_ID)).get()
if (!state?.active_account_id) return
const account = yield* db
.select()
.from(AccountTable)
.where(eq(AccountTable.id, state.active_account_id))
.get()
const account = yield* db.select().from(AccountTable).where(eq(AccountTable.id, state.active_account_id)).get()
if (!account) return
return { ...account, active_org_id: state.active_org_id ?? null }
})

View File

@@ -148,7 +148,12 @@ export const layer = Layer.effect(
const { db } = yield* Database.Service
const state = yield* InstanceState.make<State>(
Effect.fn("Permission.state")(function* (ctx) {
const row = yield* db.select().from(PermissionTable).where(eq(PermissionTable.project_id, ctx.project.id)).get().pipe(Effect.orDie)
const row = yield* db
.select()
.from(PermissionTable)
.where(eq(PermissionTable.project_id, ctx.project.id))
.get()
.pipe(Effect.orDie)
const state = {
pending: new Map<PermissionID, PendingEntry>(),
approved: [...(row?.data ?? [])],

View File

@@ -190,41 +190,57 @@ export const layer = Layer.effect(
Effect.gen(function* () {
const oldProject = yield* d.select().from(ProjectTable).where(eq(ProjectTable.id, oldID)).get()
const newProject = yield* d.select().from(ProjectTable).where(eq(ProjectTable.id, newID)).get()
if (oldProject && !newProject) {
yield* d
.insert(ProjectTable)
.values({
...oldProject,
id: newID,
time_updated: Date.now(),
})
.run()
}
if (oldProject && !newProject) {
yield* d
.insert(ProjectTable)
.values({
...oldProject,
id: newID,
time_updated: Date.now(),
})
.run()
}
const oldPermission = yield* d.select().from(PermissionTable).where(eq(PermissionTable.project_id, oldID)).get()
const newPermission = yield* d.select().from(PermissionTable).where(eq(PermissionTable.project_id, newID)).get()
if (oldPermission && newPermission) {
yield* d
.update(PermissionTable)
.set({
data: mergePermissionRules(oldPermission.data, newPermission.data),
time_created: Math.min(oldPermission.time_created, newPermission.time_created),
time_updated: Date.now(),
})
const oldPermission = yield* d
.select()
.from(PermissionTable)
.where(eq(PermissionTable.project_id, oldID))
.get()
const newPermission = yield* d
.select()
.from(PermissionTable)
.where(eq(PermissionTable.project_id, newID))
.run()
.get()
if (oldPermission && newPermission) {
yield* d
.update(PermissionTable)
.set({
data: mergePermissionRules(oldPermission.data, newPermission.data),
time_created: Math.min(oldPermission.time_created, newPermission.time_created),
time_updated: Date.now(),
})
.where(eq(PermissionTable.project_id, newID))
.run()
yield* d.delete(PermissionTable).where(eq(PermissionTable.project_id, oldID)).run()
}
if (oldPermission && !newPermission) {
yield* d.update(PermissionTable).set({ project_id: newID }).where(eq(PermissionTable.project_id, oldID)).run()
}
}
if (oldPermission && !newPermission) {
yield* d
.update(PermissionTable)
.set({ project_id: newID })
.where(eq(PermissionTable.project_id, oldID))
.run()
}
yield* d
.update(SessionTable)
.set({ project_id: newID, time_updated: sql`${SessionTable.time_updated}` })
.where(eq(SessionTable.project_id, oldID))
.run()
yield* d.update(WorkspaceTable).set({ project_id: newID }).where(eq(WorkspaceTable.project_id, oldID)).run()
.set({ project_id: newID, time_updated: sql`${SessionTable.time_updated}` })
.where(eq(SessionTable.project_id, oldID))
.run()
yield* d
.update(WorkspaceTable)
.set({ project_id: newID })
.where(eq(WorkspaceTable.project_id, oldID))
.run()
if (oldProject) yield* d.delete(ProjectTable).where(eq(ProjectTable.id, oldID)).run()
}),
@@ -278,46 +294,46 @@ export const layer = Layer.effect(
).pipe(Effect.map((arr) => arr.filter((x): x is string => x !== undefined)))
yield* db
.insert(ProjectTable)
.values({
id: result.id,
.insert(ProjectTable)
.values({
id: result.id,
worktree: result.worktree,
vcs: result.vcs ?? null,
name: result.name,
icon_url: result.icon?.url,
icon_url_override: result.icon?.override,
icon_color: result.icon?.color,
time_created: result.time.created,
time_updated: result.time.updated,
time_initialized: result.time.initialized,
sandboxes: result.sandboxes,
commands: result.commands,
})
.onConflictDoUpdate({
target: ProjectTable.id,
set: {
worktree: result.worktree,
vcs: result.vcs ?? null,
name: result.name,
icon_url: result.icon?.url,
icon_url_override: result.icon?.override,
icon_color: result.icon?.color,
time_created: result.time.created,
time_updated: result.time.updated,
time_initialized: result.time.initialized,
sandboxes: result.sandboxes,
commands: result.commands,
})
.onConflictDoUpdate({
target: ProjectTable.id,
set: {
worktree: result.worktree,
vcs: result.vcs ?? null,
name: result.name,
icon_url: result.icon?.url,
icon_url_override: result.icon?.override,
icon_color: result.icon?.color,
time_updated: result.time.updated,
time_initialized: result.time.initialized,
sandboxes: result.sandboxes,
commands: result.commands,
},
})
.run()
.pipe(Effect.orDie)
},
})
.run()
.pipe(Effect.orDie)
if (projectID !== ProjectV2.ID.global) {
yield* db
.update(SessionTable)
.set({ project_id: projectID })
.where(and(eq(SessionTable.project_id, ProjectV2.ID.global), eq(SessionTable.directory, data.directory)))
.run()
.pipe(Effect.orDie)
.update(SessionTable)
.set({ project_id: projectID })
.where(and(eq(SessionTable.project_id, ProjectV2.ID.global), eq(SessionTable.directory, data.directory)))
.run()
.pipe(Effect.orDie)
}
yield* emitUpdated(result)
@@ -362,19 +378,19 @@ export const layer = Layer.effect(
const update = Effect.fn("Project.update")(function* (input: UpdateInput) {
const result = yield* db
.update(ProjectTable)
.set({
name: input.name,
icon_url: input.icon?.url,
icon_url_override: input.icon?.override,
icon_color: input.icon?.color,
commands: input.commands,
time_updated: Date.now(),
})
.where(eq(ProjectTable.id, input.projectID))
.returning()
.get()
.pipe(Effect.orDie)
.update(ProjectTable)
.set({
name: input.name,
icon_url: input.icon?.url,
icon_url_override: input.icon?.override,
icon_color: input.icon?.color,
commands: input.commands,
time_updated: Date.now(),
})
.where(eq(ProjectTable.id, input.projectID))
.returning()
.get()
.pipe(Effect.orDie)
if (!result) return yield* new NotFoundError({ projectID: input.projectID })
const data = fromRow(result)
yield* emitUpdated(data)
@@ -393,13 +409,19 @@ export const layer = Layer.effect(
})
const setInitialized = Effect.fn("Project.setInitialized")(function* (id: ProjectV2.ID) {
yield* db.update(ProjectTable).set({ time_initialized: Date.now() }).where(eq(ProjectTable.id, id)).run().pipe(Effect.orDie)
yield* db
.update(ProjectTable)
.set({ time_initialized: Date.now() })
.where(eq(ProjectTable.id, id))
.run()
.pipe(Effect.orDie)
})
const initState = yield* InstanceState.make(
Effect.fn("Project.initState")(function* (ctx) {
const unsubscribe = yield* events.listen((event) => {
if (event.type !== Command.Event.Executed.type || event.location?.directory !== ctx.directory) return Effect.void
if (event.type !== Command.Event.Executed.type || event.location?.directory !== ctx.directory)
return Effect.void
const data = event.data as EventV2.Data<typeof Command.Event.Executed>
return data.name === Command.Default.INIT ? setInitialized(ctx.project.id) : Effect.void
})
@@ -432,12 +454,12 @@ export const layer = Layer.effect(
const sboxes = [...row.sandboxes]
if (!sboxes.includes(directory)) sboxes.push(directory)
const result = yield* db
.update(ProjectTable)
.set({ sandboxes: sboxes, time_updated: Date.now() })
.where(eq(ProjectTable.id, id))
.returning()
.get()
.pipe(Effect.orDie)
.update(ProjectTable)
.set({ sandboxes: sboxes, time_updated: Date.now() })
.where(eq(ProjectTable.id, id))
.returning()
.get()
.pipe(Effect.orDie)
if (!result) throw new Error(`Project not found: ${id}`)
yield* emitUpdated(fromRow(result))
})
@@ -447,12 +469,12 @@ export const layer = Layer.effect(
if (!row) throw new Error(`Project not found: ${id}`)
const sboxes = row.sandboxes.filter((s) => s !== directory)
const result = yield* db
.update(ProjectTable)
.set({ sandboxes: sboxes, time_updated: Date.now() })
.where(eq(ProjectTable.id, id))
.returning()
.get()
.pipe(Effect.orDie)
.update(ProjectTable)
.set({ sandboxes: sboxes, time_updated: Date.now() })
.where(eq(ProjectTable.id, id))
.returning()
.get()
.pipe(Effect.orDie)
if (!result) throw new Error(`Project not found: ${id}`)
yield* emitUpdated(fromRow(result))
})

View File

@@ -328,7 +328,8 @@ export const layer: Layer.Layer<Service, never, Git.Service | EventV2Bridge.Serv
log.info("initialized", { branch: value.current, default_branch: value.root?.name })
const unsubscribe = yield* events.listen((event) => {
if (event.type !== FileWatcher.Event.Updated.type || event.location?.directory !== ctx.directory) return Effect.void
if (event.type !== FileWatcher.Event.Updated.type || event.location?.directory !== ctx.directory)
return Effect.void
const data = event.data as EventV2.Data<typeof FileWatcher.Event.Updated>
if (!data.file.endsWith("HEAD")) return Effect.void
return Effect.gen(function* () {
@@ -429,9 +430,6 @@ export const layer: Layer.Layer<Service, never, Git.Service | EventV2Bridge.Serv
}),
)
export const defaultLayer = layer.pipe(
Layer.provide(Git.defaultLayer),
Layer.provide(EventV2Bridge.defaultLayer),
)
export const defaultLayer = layer.pipe(Layer.provide(Git.defaultLayer), Layer.provide(EventV2Bridge.defaultLayer))
export * as Vcs from "./vcs"

View File

@@ -184,7 +184,9 @@ export const layer: Layer.Layer<Service, never, Auth.Service | Plugin.Service> =
}
})
const callback = Effect.fn("ProviderAuth.callback")(function* (input: { providerID: ProviderV2.ID } & CallbackInput) {
const callback = Effect.fn("ProviderAuth.callback")(function* (
input: { providerID: ProviderV2.ID } & CallbackInput,
) {
const pending = (yield* InstanceState.get(state)).pending
const match = pending.get(input.providerID)
if (!match) return yield* new OauthMissing({ providerID: input.providerID })

View File

@@ -1024,14 +1024,20 @@ export type Error = ModelNotFoundError | InitError | NoProvidersError | NoModels
export interface Interface {
readonly list: () => Effect.Effect<Record<ProviderV2.ID, Info>>
readonly getProvider: (providerID: ProviderV2.ID) => Effect.Effect<Info>
readonly getModel: (providerID: ProviderV2.ID, modelID: ProviderV2.ModelID) => Effect.Effect<Model, ModelNotFoundError>
readonly getModel: (
providerID: ProviderV2.ID,
modelID: ProviderV2.ModelID,
) => Effect.Effect<Model, ModelNotFoundError>
readonly getLanguage: (model: Model) => Effect.Effect<LanguageModelV3, ModelNotFoundError>
readonly closest: (
providerID: ProviderV2.ID,
query: string[],
) => Effect.Effect<{ providerID: ProviderV2.ID; modelID: string } | undefined>
readonly getSmallModel: (providerID: ProviderV2.ID) => Effect.Effect<Model | undefined>
readonly defaultModel: () => Effect.Effect<{ providerID: ProviderV2.ID; modelID: ProviderV2.ModelID }, DefaultModelError>
readonly defaultModel: () => Effect.Effect<
{ providerID: ProviderV2.ID; modelID: ProviderV2.ModelID },
DefaultModelError
>
}
interface State {

View File

@@ -1,2 +1 @@
export function initProjectors() {
}
export function initProjectors() {}

View File

@@ -19,7 +19,9 @@ export const controlHandlers = HttpApiBuilder.group(RootHttpApi, "control", (han
return true
})
const authRemove = Effect.fn("ControlHttpApi.authRemove")(function* (ctx: { params: { providerID: ProviderV2.ID } }) {
const authRemove = Effect.fn("ControlHttpApi.authRemove")(function* (ctx: {
params: { providerID: ProviderV2.ID }
}) {
yield* auth.remove(ctx.params.providerID).pipe(Effect.orDie)
return true
})

View File

@@ -43,7 +43,10 @@ function eventResponse(events: EventV2.Interface) {
Stream.map((event) => ({ id: event.id, type: event.type, properties: event.data })),
)
const disposed = Stream.callback<{ id: string; type: string; properties: unknown }>((queue) => {
const listener = (event: { directory?: string; payload: { id?: string; type?: string; properties?: unknown } }) => {
const listener = (event: {
directory?: string
payload: { id?: string; type?: string; properties?: unknown }
}) => {
if (event.directory !== instance.directory || event.payload.type !== "server.instance.disposed") return
Queue.offerUnsafe(queue, {
id: event.payload.id ?? eventID(),
@@ -56,7 +59,10 @@ function eventResponse(events: EventV2.Interface) {
() => Effect.sync(() => GlobalBus.off("event", listener)),
)
})
const output = stream.pipe(Stream.merge(disposed, { haltStrategy: "left" }), Stream.takeUntil((event) => event.type === "server.instance.disposed"))
const output = stream.pipe(
Stream.merge(disposed, { haltStrategy: "left" }),
Stream.takeUntil((event) => event.type === "server.instance.disposed"),
)
const heartbeat = Stream.tick("10 seconds").pipe(
Stream.drop(1),
Stream.map(() => ({ id: eventID(), type: "server.heartbeat", properties: {} })),

View File

@@ -88,7 +88,8 @@ export const tuiHandlers = HttpApiBuilder.group(InstanceHttpApi, "tui", (handler
yield* events.publish(TuiEvent.PromptAppend, ctx.payload.properties)
if (ctx.payload.type === TuiEvent.CommandExecute.type)
yield* events.publish(TuiEvent.CommandExecute, ctx.payload.properties)
if (ctx.payload.type === TuiEvent.ToastShow.type) yield* events.publish(TuiEvent.ToastShow, ctx.payload.properties)
if (ctx.payload.type === TuiEvent.ToastShow.type)
yield* events.publish(TuiEvent.ToastShow, ctx.payload.properties)
if (ctx.payload.type === TuiEvent.SessionSelect.type)
yield* events.publish(TuiEvent.SessionSelect, ctx.payload.properties)
return true

View File

@@ -353,7 +353,9 @@ export const layer = Layer.effect(
throw new Error(`Compaction parent must be a user message: ${input.parentID}`)
}
const userMessage = parent.info
const compactionPart = parent.parts.find((part): part is SessionLegacy.CompactionPart => part.type === "compaction")
const compactionPart = parent.parts.find(
(part): part is SessionLegacy.CompactionPart => part.type === "compaction",
)
let messages = input.messages
let replay:

View File

@@ -168,13 +168,15 @@ const live: Layer.Layer<
const id = PermissionID.ascending()
let unsub: EventV2.Unsubscribe | undefined
try {
unsub = await bridge.promise(events.listen((event) => {
if (event.type !== Permission.Event.Replied.type) return Effect.void
const data = event.data as EventV2.Data<typeof Permission.Event.Replied>
if (data.requestID !== id) return Effect.void
void data.reply
return Effect.void
}))
unsub = await bridge.promise(
events.listen((event) => {
if (event.type !== Permission.Event.Replied.type) return Effect.void
const data = event.data as EventV2.Data<typeof Permission.Event.Replied>
if (data.requestID !== id) return Effect.void
void data.reply
return Effect.void
}),
)
const toolPatterns = approvalTools.map((t: { name: string; args: string }) => {
try {
const parsed = JSON.parse(t.args) as Record<string, unknown>

View File

@@ -503,14 +503,14 @@ export function stream(sessionID: SessionID) {
export function parts(messageID: MessageID) {
return Effect.gen(function* () {
const { db } = yield* Database.Service
const rows = yield* db
.select()
.from(PartTable)
.where(eq(PartTable.message_id, messageID))
.orderBy(PartTable.id)
.all()
.pipe(Effect.orDie)
return rows.map(part)
const rows = yield* db
.select()
.from(PartTable)
.where(eq(PartTable.message_id, messageID))
.orderBy(PartTable.id)
.all()
.pipe(Effect.orDie)
return rows.map(part)
})
}

View File

@@ -1502,11 +1502,11 @@ export const layer = Layer.effect(
},
)
const loop: (input: LoopInput) => Effect.Effect<SessionLegacy.WithParts> = Effect.fn("SessionPrompt.loop")(function* (
input: LoopInput,
) {
return yield* state.ensureRunning(input.sessionID, lastAssistant(input.sessionID), runLoop(input.sessionID))
})
const loop: (input: LoopInput) => Effect.Effect<SessionLegacy.WithParts> = Effect.fn("SessionPrompt.loop")(
function* (input: LoopInput) {
return yield* state.ensureRunning(input.sessionID, lastAssistant(input.sessionID), runLoop(input.sessionID))
},
)
const shell: (input: ShellInput) => Effect.Effect<SessionLegacy.WithParts, Session.BusyError> = Effect.fn(
"SessionPrompt.shell",

View File

@@ -536,11 +536,7 @@ export type Patch = Omit<Partial<Info>, "time" | "share" | "summary" | "revert"
export const layer: Layer.Layer<
Service,
never,
| BackgroundJob.Service
| Storage.Service
| RuntimeFlags.Service
| Database.Service
| EventV2Bridge.Service
BackgroundJob.Service | Storage.Service | RuntimeFlags.Service | Database.Service | EventV2Bridge.Service
> = Layer.effect(
Service,
Effect.gen(function* () {

View File

@@ -79,7 +79,9 @@ export const layer = Layer.effect(
const storage = yield* Storage.Service
const events = yield* EventV2Bridge.Service
const computeDiff = Effect.fn("SessionSummary.computeDiff")(function* (input: { messages: SessionLegacy.WithParts[] }) {
const computeDiff = Effect.fn("SessionSummary.computeDiff")(function* (input: {
messages: SessionLegacy.WithParts[]
}) {
let from: string | undefined
let to: string | undefined
for (const item of input.messages) {

View File

@@ -173,7 +173,9 @@ export const layer = Layer.effect(
events.listen((event) => {
if (event.type !== def.type || event.location?.directory !== _ctx.directory) return Effect.void
return fn(event.data as EventV2.Data<D>).pipe(
Effect.catchCause((cause) => Effect.sync(() => log.error("share subscriber failed", { type: def.type, cause }))),
Effect.catchCause((cause) =>
Effect.sync(() => log.error("share subscriber failed", { type: def.type, cause })),
),
)
})

View File

@@ -232,7 +232,11 @@ const discoverSkills = Effect.fnUntraced(function* (
}
})
const loadSkills = Effect.fnUntraced(function* (state: State, discovered: DiscoveryState, events: EventV2Bridge.Service["Service"]) {
const loadSkills = Effect.fnUntraced(function* (
state: State,
discovered: DiscoveryState,
events: EventV2Bridge.Service["Service"],
) {
yield* Effect.forEach(discovered.matches, (match) => add(state, match, events), {
concurrency: "unbounded",
discard: true,

View File

@@ -76,7 +76,11 @@ export interface Interface {
readonly ids: () => Effect.Effect<string[]>
readonly all: () => Effect.Effect<Tool.Def[]>
readonly named: () => Effect.Effect<{ task: TaskDef; read: ReadDef }>
readonly tools: (model: { providerID: ProviderV2.ID; modelID: ProviderV2.ModelID; agent: Agent.Info }) => Effect.Effect<Tool.Def[]>
readonly tools: (model: {
providerID: ProviderV2.ID
modelID: ProviderV2.ModelID
agent: Agent.Info
}) => Effect.Effect<Tool.Def[]>
}
export class Service extends Context.Service<Service, Interface>()("@opencode/ToolRegistry") {}

View File

@@ -149,7 +149,13 @@ type GitResult = { code: number; text: string; stderr: string }
export const layer: Layer.Layer<
Service,
never,
AppFileSystem.Service | Path.Path | AppProcess.Service | Git.Service | Project.Service | InstanceStore.Service | Database.Service
| AppFileSystem.Service
| Path.Path
| AppProcess.Service
| Git.Service
| Project.Service
| InstanceStore.Service
| Database.Service
> = Layer.effect(
Service,
Effect.gen(function* () {
@@ -484,7 +490,12 @@ export const layer: Layer.Layer<
directory: string,
input: { projectID: ProjectV2.ID; extra?: string },
) {
const row = yield* db.select().from(ProjectTable).where(eq(ProjectTable.id, input.projectID)).get().pipe(Effect.orDie)
const row = yield* db
.select()
.from(ProjectTable)
.where(eq(ProjectTable.id, input.projectID))
.get()
.pipe(Effect.orDie)
const project = row ? Project.fromRow(row) : undefined
const startup = project?.commands?.start?.trim() ?? ""
const ok = yield* runStartScript(directory, startup, "project")