|
|
@@ -0,0 +1,103 @@
|
|
|
+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))
|