chore: generate

This commit is contained in:
opencode-agent[bot]
2026-06-04 06:59:09 +00:00
parent 1ff19103a2
commit 30ec231aaf
19 changed files with 3592 additions and 2882 deletions
+21 -7
View File
@@ -88,8 +88,17 @@ const names = (() => {
return false return false
} }
})() })()
if (musl) return arch === "x64" ? (baseline ? [`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base] : [`${base}-musl`, `${base}-baseline-musl`, base, `${base}-baseline`]) : [`${base}-musl`, base] if (musl)
return arch === "x64" ? (baseline ? [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`] : [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]) : [base, `${base}-musl`] return arch === "x64"
? baseline
? [`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base]
: [`${base}-musl`, `${base}-baseline-musl`, base, `${base}-baseline`]
: [`${base}-musl`, base]
return arch === "x64"
? baseline
? [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
: [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
: [base, `${base}-musl`]
} }
return arch === "x64" ? (baseline ? [`${base}-baseline`, base] : [base, `${base}-baseline`]) : [base] return arch === "x64" ? (baseline ? [`${base}-baseline`, base] : [base, `${base}-baseline`]) : [base]
})() })()
@@ -98,10 +107,11 @@ function findBinary(startDir) {
let current = startDir let current = startDir
for (;;) { for (;;) {
const modules = path.join(current, "node_modules") const modules = path.join(current, "node_modules")
if (fs.existsSync(modules)) for (const name of names) { if (fs.existsSync(modules))
const candidate = path.join(modules, name, "bin", binary) for (const name of names) {
if (fs.existsSync(candidate)) return candidate const candidate = path.join(modules, name, "bin", binary)
} if (fs.existsSync(candidate)) return candidate
}
const parent = path.dirname(current) const parent = path.dirname(current)
if (parent === current) return if (parent === current) return
current = parent current = parent
@@ -110,7 +120,11 @@ function findBinary(startDir) {
const resolved = envPath || (fs.existsSync(cached) ? cached : findBinary(scriptDir)) const resolved = envPath || (fs.existsSync(cached) ? cached : findBinary(scriptDir))
if (!resolved) { if (!resolved) {
console.error("It seems that your package manager failed to install the right lildax CLI package. Try manually installing " + names.map((name) => `"${name}"`).join(" or ") + " package") console.error(
"It seems that your package manager failed to install the right lildax CLI package. Try manually installing " +
names.map((name) => `"${name}"`).join(" or ") +
" package",
)
process.exit(1) process.exit(1)
} }
run(resolved) run(resolved)
+5 -1
View File
@@ -44,5 +44,9 @@ await Bun.file(`./dist/${pkg.name}/package.json`).write(
), ),
) )
await Promise.all(Object.entries(binaries).map(([name, version]) => publish(`./dist/${name.replace("@opencode-ai/", "")}`, name, version))) await Promise.all(
Object.entries(binaries).map(([name, version]) =>
publish(`./dist/${name.replace("@opencode-ai/", "")}`, name, version),
),
)
await publish(`./dist/${pkg.name}`, pkg.name, version) await publish(`./dist/${pkg.name}`, pkg.name, version)
+3 -1
View File
@@ -11,7 +11,9 @@ export type Input<Value> =
: never : never
type RuntimeHandler = (input: unknown) => Effect.Effect<void, unknown, Daemon.Service> type RuntimeHandler = (input: unknown) => Effect.Effect<void, unknown, Daemon.Service>
type Loader<Node extends Spec.Any> = () => Promise<{ default: (input: Input<Node>) => Effect.Effect<void, any, Daemon.Service> }> type Loader<Node extends Spec.Any> = () => Promise<{
default: (input: Input<Node>) => Effect.Effect<void, any, Daemon.Service>
}>
type ProvidedCommand = Command.Command<string, unknown, unknown, unknown, Daemon.Service> type ProvidedCommand = Command.Command<string, unknown, unknown, unknown, Daemon.Service>
export type Handlers<Node extends Spec.Any> = keyof Node["commands"] extends never export type Handlers<Node extends Spec.Any> = keyof Node["commands"] extends never
+3 -5
View File
@@ -125,11 +125,9 @@ export const layer = Layer.effect(
const register = Effect.fn("cli.daemon.register")(function* (address: HttpServer.Address) { const register = Effect.fn("cli.daemon.register")(function* (address: HttpServer.Address) {
const temp = file + ".tmp" const temp = file + ".tmp"
yield* fs.makeDirectory(directory, { recursive: true }) yield* fs.makeDirectory(directory, { recursive: true })
yield* fs.writeFileString( yield* fs.writeFileString(temp, JSON.stringify({ url: HttpServer.formatAddress(address), pid: process.pid }), {
temp, mode: 0o600,
JSON.stringify({ url: HttpServer.formatAddress(address), pid: process.pid }), })
{ mode: 0o600 },
)
yield* fs.rename(temp, file) yield* fs.rename(temp, file)
// The metadata file represents this live listener, not persistent config. // The metadata file represents this live listener, not persistent config.
// Scope shutdown removes it when the server exits normally. // Scope shutdown removes it when the server exits normally.
+3 -1
View File
@@ -22,7 +22,9 @@ export const Plugin = PluginV2.define({
const documents = yield* Effect.forEach(yield* config.entries(), (entry) => { const documents = yield* Effect.forEach(yield* config.entries(), (entry) => {
if (entry.type === "document") return Effect.succeed([{ commands: entry.info.commands }]) if (entry.type === "document") return Effect.succeed([{ commands: entry.info.commands }])
return loadDirectory(fs, entry.path).pipe( return loadDirectory(fs, entry.path).pipe(
Effect.map((commands) => [{ commands: Object.fromEntries(commands.map((command) => [command.name, command.info])) }]), Effect.map((commands) => [
{ commands: Object.fromEntries(commands.map((command) => [command.name, command.info])) },
]),
) )
}).pipe(Effect.map((documents) => documents.flat())) }).pipe(Effect.map((documents) => documents.flat()))
+6 -2
View File
@@ -23,8 +23,12 @@ export const Plugin = PluginV2.define({
yield* transform((editor) => { yield* transform((editor) => {
for (const directory of directories) { for (const directory of directories) {
editor.source(new SkillV2.DirectorySource({ type: "directory", path: AbsolutePath.make(path.join(directory, "skill")) })) editor.source(
editor.source(new SkillV2.DirectorySource({ type: "directory", path: AbsolutePath.make(path.join(directory, "skills")) })) new SkillV2.DirectorySource({ type: "directory", path: AbsolutePath.make(path.join(directory, "skill")) }),
)
editor.source(
new SkillV2.DirectorySource({ type: "directory", path: AbsolutePath.make(path.join(directory, "skills")) }),
)
} }
for (const item of items) { for (const item of items) {
if (URL.canParse(item) && /^(https?:)$/.test(new URL(item).protocol)) { if (URL.canParse(item) && /^(https?:)$/.test(new URL(item).protocol)) {
+3 -1
View File
@@ -10,7 +10,9 @@ export const Plugin = PluginV2.define({
effect: Effect.gen(function* () { effect: Effect.gen(function* () {
const skill = yield* SkillV2.Service const skill = yield* SkillV2.Service
const transform = yield* skill.transform() const transform = yield* skill.transform()
const content = yield* Effect.promise(() => Bun.file(new URL("./skill/customize-opencode.md", import.meta.url)).text()) const content = yield* Effect.promise(() =>
Bun.file(new URL("./skill/customize-opencode.md", import.meta.url)).text(),
)
yield* transform((editor) => { yield* transform((editor) => {
editor.source( editor.source(
+5 -1
View File
@@ -37,7 +37,11 @@ export const Source = Schema.Union([DirectorySource, UrlSource, EmbeddedSource])
return false return false
}, },
key: (source: DirectorySource | UrlSource | EmbeddedSource) => key: (source: DirectorySource | UrlSource | EmbeddedSource) =>
source.type === "directory" ? `directory:${source.path}` : source.type === "url" ? `url:${source.url}` : `embedded:${source.skill.name}`, source.type === "directory"
? `directory:${source.path}`
: source.type === "url"
? `url:${source.url}`
: `embedded:${source.skill.name}`,
})), })),
) )
export type Source = typeof Source.Type export type Source = typeof Source.Type
+5 -5
View File
@@ -12,10 +12,7 @@ const project = AbsolutePath.make("/repo")
const it = testEffect( const it = testEffect(
CommandV2.locationLayer.pipe( CommandV2.locationLayer.pipe(
Layer.provide( Layer.provide(
Layer.succeed( Layer.succeed(Location.Service, Location.Service.of(location({ directory }, { projectDirectory: project }))),
Location.Service,
Location.Service.of(location({ directory }, { projectDirectory: project })),
),
), ),
), ),
) )
@@ -26,7 +23,10 @@ describe("CommandPlugin.Plugin", () => {
const command = yield* CommandV2.Service const command = yield* CommandV2.Service
yield* CommandPlugin.Plugin.effect.pipe( yield* CommandPlugin.Plugin.effect.pipe(
Effect.provideService(CommandV2.Service, command), Effect.provideService(CommandV2.Service, command),
Effect.provideService(Location.Service, Location.Service.of(location({ directory }, { projectDirectory: project }))), Effect.provideService(
Location.Service,
Location.Service.of(location({ directory }, { projectDirectory: project })),
),
) )
expect(yield* command.get("init")).toMatchObject({ expect(yield* command.get("init")).toMatchObject({
+2 -8
View File
@@ -1017,20 +1017,14 @@ export type Error = ModelNotFoundError | InitError | NoProvidersError | NoModels
export interface Interface { export interface Interface {
readonly list: () => Effect.Effect<Record<ProviderV2.ID, Info>> readonly list: () => Effect.Effect<Record<ProviderV2.ID, Info>>
readonly getProvider: (providerID: ProviderV2.ID) => Effect.Effect<Info> readonly getProvider: (providerID: ProviderV2.ID) => Effect.Effect<Info>
readonly getModel: ( readonly getModel: (providerID: ProviderV2.ID, modelID: ModelV2.ID) => Effect.Effect<Model, ModelNotFoundError>
providerID: ProviderV2.ID,
modelID: ModelV2.ID,
) => Effect.Effect<Model, ModelNotFoundError>
readonly getLanguage: (model: Model) => Effect.Effect<LanguageModelV3, ModelNotFoundError> readonly getLanguage: (model: Model) => Effect.Effect<LanguageModelV3, ModelNotFoundError>
readonly closest: ( readonly closest: (
providerID: ProviderV2.ID, providerID: ProviderV2.ID,
query: string[], query: string[],
) => Effect.Effect<{ providerID: ProviderV2.ID; modelID: string } | undefined> ) => Effect.Effect<{ providerID: ProviderV2.ID; modelID: string } | undefined>
readonly getSmallModel: (providerID: ProviderV2.ID) => Effect.Effect<Model | undefined> readonly getSmallModel: (providerID: ProviderV2.ID) => Effect.Effect<Model | undefined>
readonly defaultModel: () => Effect.Effect< readonly defaultModel: () => Effect.Effect<{ providerID: ProviderV2.ID; modelID: ModelV2.ID }, DefaultModelError>
{ providerID: ProviderV2.ID; modelID: ModelV2.ID },
DefaultModelError
>
} }
interface State { interface State {
@@ -192,7 +192,15 @@ type RouteRequirements =
export function createRoutes( export function createRoutes(
corsOptions?: CorsOptions, corsOptions?: CorsOptions,
): Layer.Layer<never, EffectConfig.ConfigError, RouteRequirements> { ): Layer.Layer<never, EffectConfig.ConfigError, RouteRequirements> {
return Layer.mergeAll(rootApiRoutes, eventApiRoutes, ptyConnectApiRoutes, instanceRoutes, v2Routes, docRoute, uiRoute).pipe( return Layer.mergeAll(
rootApiRoutes,
eventApiRoutes,
ptyConnectApiRoutes,
instanceRoutes,
v2Routes,
docRoute,
uiRoute,
).pipe(
Layer.provide([ Layer.provide([
errorLayer, errorLayer,
compressionLayer, compressionLayer,
+16 -31
View File
@@ -574,10 +574,7 @@ export const layer: Layer.Layer<
} }
log.info("created", result) log.info("created", result)
yield* events.publish( yield* events.publish(SessionV1.Event.Created, { sessionID: result.id, info: result })
SessionV1.Event.Created,
{ sessionID: result.id, info: result },
)
return result return result
}) })
@@ -664,10 +661,7 @@ export const layer: Layer.Layer<
yield* remove(child.id) yield* remove(child.id)
} }
yield* events.publish( yield* events.publish(SessionV1.Event.Deleted, { sessionID, info: session })
SessionV1.Event.Deleted,
{ sessionID, info: session },
)
yield* events.remove(sessionID) yield* events.remove(sessionID)
} catch (e) { } catch (e) {
log.error(e) log.error(e)
@@ -682,14 +676,11 @@ export const layer: Layer.Layer<
const updatePart = <T extends SessionV1.Part>(part: T): Effect.Effect<T> => const updatePart = <T extends SessionV1.Part>(part: T): Effect.Effect<T> =>
Effect.gen(function* () { Effect.gen(function* () {
yield* events.publish( yield* events.publish(SessionV1.Event.PartUpdated, {
SessionV1.Event.PartUpdated, sessionID: part.sessionID,
{ part: structuredClone(part),
sessionID: part.sessionID, time: Date.now(),
part: structuredClone(part), })
time: Date.now(),
},
)
return part return part
}).pipe(Effect.withSpan("Session.updatePart")) }).pipe(Effect.withSpan("Session.updatePart"))
@@ -892,13 +883,10 @@ export const layer: Layer.Layer<
sessionID: SessionID sessionID: SessionID
messageID: MessageID messageID: MessageID
}) { }) {
yield* events.publish( yield* events.publish(SessionV1.Event.MessageRemoved, {
SessionV1.Event.MessageRemoved, sessionID: input.sessionID,
{ messageID: input.messageID,
sessionID: input.sessionID, })
messageID: input.messageID,
},
)
return input.messageID return input.messageID
}) })
@@ -907,14 +895,11 @@ export const layer: Layer.Layer<
messageID: MessageID messageID: MessageID
partID: PartID partID: PartID
}) { }) {
yield* events.publish( yield* events.publish(SessionV1.Event.PartRemoved, {
SessionV1.Event.PartRemoved, sessionID: input.sessionID,
{ messageID: input.messageID,
sessionID: input.sessionID, partID: input.partID,
messageID: input.messageID, })
partID: input.partID,
},
)
return input.partID return input.partID
}) })
@@ -980,14 +980,8 @@ it.instance(
it.instance("getModel returns consistent results", () => it.instance("getModel returns consistent results", () =>
Effect.gen(function* () { Effect.gen(function* () {
yield* set("ANTHROPIC_API_KEY", "test-api-key") yield* set("ANTHROPIC_API_KEY", "test-api-key")
const model1 = yield* Provider.use.getModel( const model1 = yield* Provider.use.getModel(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-20250514"))
ProviderV2.ID.anthropic, const model2 = yield* Provider.use.getModel(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-20250514"))
ModelV2.ID.make("claude-sonnet-4-20250514"),
)
const model2 = yield* Provider.use.getModel(
ProviderV2.ID.anthropic,
ModelV2.ID.make("claude-sonnet-4-20250514"),
)
expect(model1.providerID).toEqual(model2.providerID) expect(model1.providerID).toEqual(model2.providerID)
expect(model1.id).toEqual(model2.id) expect(model1.id).toEqual(model2.id)
expect(model1).toEqual(model2) expect(model1).toEqual(model2)
@@ -457,7 +457,8 @@ describe("session HttpApi", () => {
})}`, })}`,
{ headers }, { headers },
) )
const sessionCursor = (yield* json<{ data: Session.Info[]; cursor: { next?: string } }>(sessionPage)).cursor.next const sessionCursor = (yield* json<{ data: Session.Info[]; cursor: { next?: string } }>(sessionPage)).cursor
.next
expect(sessionCursor).toBeTruthy() expect(sessionCursor).toBeTruthy()
expect(JSON.parse(Buffer.from(sessionCursor!, "base64url").toString("utf8"))).toMatchObject({ expect(JSON.parse(Buffer.from(sessionCursor!, "base64url").toString("utf8"))).toMatchObject({
order: "asc", order: "asc",
@@ -57,7 +57,10 @@ describe("v2 location HttpApi", () => {
for (const route of ["/api/command", "/api/skill"]) { for (const route of ["/api/command", "/api/skill"]) {
const response = await request(route, tmp.path) const response = await request(route, tmp.path)
expect(response.status).toBe(200) expect(response.status).toBe(200)
const body = (await response.json()) as { location: { directory: string; project: { id: string } }; data: unknown } const body = (await response.json()) as {
location: { directory: string; project: { id: string } }
data: unknown
}
expect(body.data).toBeArray() expect(body.data).toBeArray()
expect(body.location.directory).toBe(tmp.path) expect(body.location.directory).toBe(tmp.path)
expect(body.location.project.id).toBeTruthy() expect(body.location.project.id).toBeTruthy()
+1 -4
View File
@@ -1671,10 +1671,7 @@ describe("session.llm.stream", () => {
] ]
const request = waitRequest("/messages", createEventResponse(chunks)) const request = waitRequest("/messages", createEventResponse(chunks))
const resolved = yield* Provider.use.getModel( const resolved = yield* Provider.use.getModel(ProviderV2.ID.make("anthropic"), ModelV2.ID.make(model.id))
ProviderV2.ID.make("anthropic"),
ModelV2.ID.make(model.id),
)
const sessionID = SessionID.make("session-test-anthropic-tools") const sessionID = SessionID.make("session-test-anthropic-tools")
const agent = { const agent = {
name: "test", name: "test",
+3478 -2783
View File
File diff suppressed because it is too large Load Diff
+8 -6
View File
@@ -34,13 +34,15 @@ export const eventHandlers = HttpApiBuilder.group(V2Api, "v2.event", (handlers)
return HttpServerResponse.stream( return HttpServerResponse.stream(
Stream.make(connected).pipe( Stream.make(connected).pipe(
Stream.concat( Stream.concat(
events.all().pipe( events
Stream.filter( .all()
(event) => .pipe(
event.location?.directory === location.directory && Stream.filter(
event.location.workspaceID === location.workspaceID, (event) =>
event.location?.directory === location.directory &&
event.location.workspaceID === location.workspaceID,
),
), ),
),
), ),
Stream.map(eventData), Stream.map(eventData),
Stream.pipeThroughChannel(Sse.encode()), Stream.pipeThroughChannel(Sse.encode()),
+16 -15
View File
@@ -14,23 +14,24 @@ import { schemaErrorLayer } from "./middleware/schema-error"
export function createRoutes(password?: string) { export function createRoutes(password?: string) {
return HttpApiBuilder.layer(V2Api).pipe( return HttpApiBuilder.layer(V2Api).pipe(
Layer.provide(v2Handlers), Layer.provide(v2Handlers),
Layer.provide(v2AuthorizationLayer), Layer.provide(v2AuthorizationLayer),
Layer.provide(schemaErrorLayer), Layer.provide(schemaErrorLayer),
Layer.provide( Layer.provide(
password password
? ServerAuth.Config.layer({ username: "opencode", password: Option.some(password) }) ? ServerAuth.Config.layer({ username: "opencode", password: Option.some(password) })
: ServerAuth.Config.defaultLayer, : ServerAuth.Config.defaultLayer,
), ),
Layer.provide(LocationServiceMap.layer), Layer.provide(LocationServiceMap.layer),
Layer.provide(PermissionSaved.layer), Layer.provide(PermissionSaved.layer),
Layer.provide(SessionV2.defaultLayer), Layer.provide(SessionV2.defaultLayer),
Layer.provide(Database.defaultLayer), Layer.provide(Database.defaultLayer),
Layer.provide(EventV2.defaultLayer), Layer.provide(EventV2.defaultLayer),
Layer.provide(FetchHttpClient.layer), Layer.provide(FetchHttpClient.layer),
) )
} }
export const routes = createRoutes() export const routes = createRoutes()
export const webHandler = () => HttpRouter.toWebHandler(routes.pipe(Layer.provide(HttpServer.layerServices)), { disableLogger: true }) export const webHandler = () =>
HttpRouter.toWebHandler(routes.pipe(Layer.provide(HttpServer.layerServices)), { disableLogger: true })