opencode/packages/opencode/src/server/routes/instance/httpapi/instance.ts

104 lines
3.3 KiB
TypeScript

import { Global } from "@/global"
import { Vcs } from "@/project"
import * as InstanceState from "@/effect/instance-state"
import { Effect, Layer, Schema } from "effect"
import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
import { Authorization } from "./auth"
const PathInfo = Schema.Struct({
home: Schema.String,
state: Schema.String,
config: Schema.String,
worktree: Schema.String,
directory: Schema.String,
}).annotate({ identifier: "Path" })
const VcsDiffQuery = Schema.Struct({
mode: Vcs.Mode,
})
export const InstancePaths = {
path: "/path",
vcs: "/vcs",
vcsDiff: "/vcs/diff",
} as const
export const InstanceApi = HttpApi.make("instance")
.add(
HttpApiGroup.make("instance")
.add(
HttpApiEndpoint.get("path", InstancePaths.path, {
success: PathInfo,
}).annotateMerge(
OpenApi.annotations({
identifier: "path.get",
summary: "Get paths",
description: "Retrieve the current working directory and related path information for the OpenCode instance.",
}),
),
HttpApiEndpoint.get("vcs", InstancePaths.vcs, {
success: Vcs.Info,
}).annotateMerge(
OpenApi.annotations({
identifier: "vcs.get",
summary: "Get VCS info",
description: "Retrieve version control system (VCS) information for the current project, such as git branch.",
}),
),
HttpApiEndpoint.get("vcsDiff", InstancePaths.vcsDiff, {
query: VcsDiffQuery,
success: Schema.Array(Vcs.FileDiff),
}).annotateMerge(
OpenApi.annotations({
identifier: "vcs.diff",
summary: "Get VCS diff",
description: "Retrieve the current git diff for the working tree or against the default branch.",
}),
),
)
.annotateMerge(
OpenApi.annotations({
title: "instance",
description: "Experimental HttpApi instance read routes.",
}),
)
.middleware(Authorization),
)
.annotateMerge(
OpenApi.annotations({
title: "opencode experimental HttpApi",
version: "0.0.1",
description: "Experimental HttpApi surface for selected instance routes.",
}),
)
export const instanceHandlers = Layer.unwrap(
Effect.gen(function* () {
const vcs = yield* Vcs.Service
const getPath = Effect.fn("InstanceHttpApi.path")(function* () {
const ctx = yield* InstanceState.context
return {
home: Global.Path.home,
state: Global.Path.state,
config: Global.Path.config,
worktree: ctx.worktree,
directory: ctx.directory,
}
})
const getVcs = Effect.fn("InstanceHttpApi.vcs")(function* () {
const [branch, default_branch] = yield* Effect.all([vcs.branch(), vcs.defaultBranch()], { concurrency: 2 })
return { branch, default_branch }
})
const getVcsDiff = Effect.fn("InstanceHttpApi.vcsDiff")(function* (ctx: { query: { mode: Vcs.Mode } }) {
return yield* vcs.diff(ctx.query.mode)
})
return HttpApiBuilder.group(InstanceApi, "instance", (handlers) =>
handlers.handle("path", getPath).handle("vcs", getVcs).handle("vcsDiff", getVcsDiff),
)
}),
).pipe(Layer.provide(Vcs.defaultLayer))