mirror of
https://github.com/anomalyco/opencode.git
synced 2026-04-26 11:40:49 +00:00
feat(httpapi): bridge worktree read endpoint (#24366)
This commit is contained in:
parent
60fa708f0b
commit
b749866f0b
4 changed files with 29 additions and 2 deletions
|
|
@ -164,7 +164,7 @@ Use raw Effect HTTP routes where `HttpApi` does not fit. The goal is deleting Ho
|
|||
| `mcp` | `bridged` partial | status only |
|
||||
| `workspace` | `bridged` | list, get, enter |
|
||||
| top-level instance reads | `bridged` | path, vcs, command, agent, skill, lsp, formatter |
|
||||
| experimental JSON routes | `bridged` partial | console reads, tool ids, resource list; worktree and global session list remain later |
|
||||
| experimental JSON routes | `bridged` partial | console reads, tool ids, worktree list, resource list; global session list remains later |
|
||||
| `session` | `later/special` | large stateful surface plus streaming |
|
||||
| `sync` | `later` | process/control side effects |
|
||||
| `event` | `special` | SSE |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { Account } from "@/account/account"
|
||||
import { Config } from "@/config"
|
||||
import { InstanceState } from "@/effect"
|
||||
import { MCP } from "@/mcp"
|
||||
import { Project } from "@/project"
|
||||
import { ToolRegistry } from "@/tool"
|
||||
import { Effect, Layer, Option, Schema } from "effect"
|
||||
import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
|
||||
|
|
@ -27,10 +29,13 @@ const ConsoleOrgList = Schema.Struct({
|
|||
|
||||
const ToolIDs = Schema.Array(Schema.String).annotate({ identifier: "ToolIDs" })
|
||||
|
||||
const WorktreeList = Schema.Array(Schema.String).annotate({ identifier: "WorktreeList" })
|
||||
|
||||
export const ExperimentalPaths = {
|
||||
console: "/experimental/console",
|
||||
consoleOrgs: "/experimental/console/orgs",
|
||||
toolIDs: "/experimental/tool/ids",
|
||||
worktree: "/experimental/worktree",
|
||||
resource: "/experimental/resource",
|
||||
} as const
|
||||
|
||||
|
|
@ -66,6 +71,15 @@ export const ExperimentalApi = HttpApi.make("experimental")
|
|||
"Get a list of all available tool IDs, including both built-in tools and dynamically registered tools.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("worktree", ExperimentalPaths.worktree, {
|
||||
success: WorktreeList,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "worktree.list",
|
||||
summary: "List worktrees",
|
||||
description: "List all sandbox worktrees for the current project.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("resource", ExperimentalPaths.resource, {
|
||||
success: Schema.Record(Schema.String, MCP.Resource),
|
||||
}).annotateMerge(
|
||||
|
|
@ -97,6 +111,7 @@ export const experimentalHandlers = Layer.unwrap(
|
|||
const account = yield* Account.Service
|
||||
const config = yield* Config.Service
|
||||
const mcp = yield* MCP.Service
|
||||
const project = yield* Project.Service
|
||||
const registry = yield* ToolRegistry.Service
|
||||
|
||||
const getConsole = Effect.fn("ExperimentalHttpApi.console")(function* () {
|
||||
|
|
@ -139,6 +154,11 @@ export const experimentalHandlers = Layer.unwrap(
|
|||
return yield* registry.ids()
|
||||
})
|
||||
|
||||
const worktree = Effect.fn("ExperimentalHttpApi.worktree")(function* () {
|
||||
const ctx = yield* InstanceState.context
|
||||
return yield* project.sandboxes(ctx.project.id)
|
||||
})
|
||||
|
||||
const resource = Effect.fn("ExperimentalHttpApi.resource")(function* () {
|
||||
return yield* mcp.resources()
|
||||
})
|
||||
|
|
@ -148,6 +168,7 @@ export const experimentalHandlers = Layer.unwrap(
|
|||
.handle("console", getConsole)
|
||||
.handle("consoleOrgs", listConsoleOrgs)
|
||||
.handle("toolIDs", toolIDs)
|
||||
.handle("worktree", worktree)
|
||||
.handle("resource", resource),
|
||||
)
|
||||
}),
|
||||
|
|
@ -155,5 +176,6 @@ export const experimentalHandlers = Layer.unwrap(
|
|||
Layer.provide(Account.defaultLayer),
|
||||
Layer.provide(Config.defaultLayer),
|
||||
Layer.provide(MCP.defaultLayer),
|
||||
Layer.provide(Project.defaultLayer),
|
||||
Layer.provide(ToolRegistry.defaultLayer),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export const InstanceRoutes = (upgrade: UpgradeWebSocket): Hono => {
|
|||
app.get(ExperimentalPaths.console, (c) => handler(c.req.raw, context))
|
||||
app.get(ExperimentalPaths.consoleOrgs, (c) => handler(c.req.raw, context))
|
||||
app.get(ExperimentalPaths.toolIDs, (c) => handler(c.req.raw, context))
|
||||
app.get(ExperimentalPaths.worktree, (c) => handler(c.req.raw, context))
|
||||
app.get(ExperimentalPaths.resource, (c) => handler(c.req.raw, context))
|
||||
app.get("/provider", (c) => handler(c.req.raw, context))
|
||||
app.get("/provider/auth", (c) => handler(c.req.raw, context))
|
||||
|
|
|
|||
|
|
@ -41,10 +41,11 @@ describe("experimental HttpApi", () => {
|
|||
})
|
||||
|
||||
const headers = { "x-opencode-directory": tmp.path }
|
||||
const [consoleState, consoleOrgs, toolIDs, resources] = await Promise.all([
|
||||
const [consoleState, consoleOrgs, toolIDs, worktrees, resources] = await Promise.all([
|
||||
app().request(ExperimentalPaths.console, { headers }),
|
||||
app().request(ExperimentalPaths.consoleOrgs, { headers }),
|
||||
app().request(ExperimentalPaths.toolIDs, { headers }),
|
||||
app().request(ExperimentalPaths.worktree, { headers }),
|
||||
app().request(ExperimentalPaths.resource, { headers }),
|
||||
])
|
||||
|
||||
|
|
@ -60,6 +61,9 @@ describe("experimental HttpApi", () => {
|
|||
expect(toolIDs.status).toBe(200)
|
||||
expect(await toolIDs.json()).toContain("bash")
|
||||
|
||||
expect(worktrees.status).toBe(200)
|
||||
expect(await worktrees.json()).toEqual([])
|
||||
|
||||
expect(resources.status).toBe(200)
|
||||
expect(await resources.json()).toEqual({})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue