mirror of
https://fastgit.cc/https://github.com/anomalyco/opencode
synced 2026-04-21 05:10:58 +08:00
refactor(core): move server routes around to clarify workspacing (#23031)
This commit is contained in:
@@ -2,13 +2,13 @@ import { LocalContext } from "../util"
|
||||
import type { WorkspaceID } from "../control-plane/schema"
|
||||
|
||||
export interface WorkspaceContext {
|
||||
workspaceID: WorkspaceID
|
||||
workspaceID: WorkspaceID | undefined
|
||||
}
|
||||
|
||||
const context = LocalContext.create<WorkspaceContext>("instance")
|
||||
|
||||
export const WorkspaceContext = {
|
||||
async provide<R>(input: { workspaceID: WorkspaceID; fn: () => R }): Promise<R> {
|
||||
async provide<R>(input: { workspaceID?: WorkspaceID; fn: () => R }): Promise<R> {
|
||||
return context.provide({ workspaceID: input.workspaceID }, () => input.fn())
|
||||
},
|
||||
|
||||
|
||||
@@ -6,13 +6,12 @@ import { ProviderID } from "@/provider/schema"
|
||||
import { Hono } from "hono"
|
||||
import { describeRoute, resolver, validator, openAPIRouteHandler } from "hono-openapi"
|
||||
import z from "zod"
|
||||
import { errors } from "../error"
|
||||
import { GlobalRoutes } from "../instance/global"
|
||||
import { errors } from "../../error"
|
||||
import { WorkspaceRoutes } from "./workspace"
|
||||
|
||||
export function ControlPlaneRoutes(): Hono {
|
||||
const app = new Hono()
|
||||
return app
|
||||
.route("/global", GlobalRoutes())
|
||||
.put(
|
||||
"/auth/:providerID",
|
||||
describeRoute({
|
||||
@@ -159,4 +158,5 @@ export function ControlPlaneRoutes(): Hono {
|
||||
return c.json(true)
|
||||
},
|
||||
)
|
||||
.route("/experimental/workspace", WorkspaceRoutes())
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Hono } from "hono"
|
||||
import { describeRoute, resolver, validator } from "hono-openapi"
|
||||
import z from "zod"
|
||||
import { listAdaptors } from "../../control-plane/adaptors"
|
||||
import { Workspace } from "../../control-plane/workspace"
|
||||
import { Instance } from "../../project/instance"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { listAdaptors } from "@/control-plane/adaptors"
|
||||
import { Workspace } from "@/control-plane/workspace"
|
||||
import { Instance } from "@/project/instance"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { Log } from "@/util"
|
||||
import { errorData } from "@/util/error"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Hono } from "hono"
|
||||
import { describeRoute, validator, resolver } from "hono-openapi"
|
||||
import z from "zod"
|
||||
import { Config } from "../../config"
|
||||
import { Provider } from "../../provider"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { AppRuntime } from "../../effect/app-runtime"
|
||||
import { Config } from "@/config"
|
||||
import { Provider } from "@/provider"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { jsonRequest } from "./trace"
|
||||
|
||||
export const ConfigRoutes = lazy(() =>
|
||||
@@ -5,7 +5,7 @@ import { streamSSE } from "hono/streaming"
|
||||
import { Log } from "@/util"
|
||||
import { BusEvent } from "@/bus/bus-event"
|
||||
import { Bus } from "@/bus"
|
||||
import { AsyncQueue } from "../../util/queue"
|
||||
import { AsyncQueue } from "@/util/queue"
|
||||
|
||||
const log = Log.create({ service: "server" })
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
import { Hono } from "hono"
|
||||
import { describeRoute, validator, resolver } from "hono-openapi"
|
||||
import z from "zod"
|
||||
import { ProviderID, ModelID } from "../../provider/schema"
|
||||
import { ToolRegistry } from "../../tool"
|
||||
import { Worktree } from "../../worktree"
|
||||
import { Instance } from "../../project/instance"
|
||||
import { Project } from "../../project"
|
||||
import { MCP } from "../../mcp"
|
||||
import { Session } from "../../session"
|
||||
import { Config } from "../../config"
|
||||
import { ConsoleState } from "../../config/console-state"
|
||||
import { Account } from "../../account/account"
|
||||
import { AccountID, OrgID } from "../../account/schema"
|
||||
import { AppRuntime } from "../../effect/app-runtime"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { ProviderID, ModelID } from "@/provider/schema"
|
||||
import { ToolRegistry } from "@/tool"
|
||||
import { Worktree } from "@/worktree"
|
||||
import { Instance } from "@/project/instance"
|
||||
import { Project } from "@/project"
|
||||
import { MCP } from "@/mcp"
|
||||
import { Session } from "@/session"
|
||||
import { Config } from "@/config"
|
||||
import { ConsoleState } from "@/config/console-state"
|
||||
import { Account } from "@/account/account"
|
||||
import { AccountID, OrgID } from "@/account/schema"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { Effect, Option } from "effect"
|
||||
import { WorkspaceRoutes } from "./workspace"
|
||||
import { Agent } from "@/agent/agent"
|
||||
|
||||
const ConsoleOrgOption = z.object({
|
||||
@@ -231,7 +230,6 @@ export const ExperimentalRoutes = lazy(() =>
|
||||
)
|
||||
},
|
||||
)
|
||||
.route("/workspace", WorkspaceRoutes())
|
||||
.post(
|
||||
"/worktree",
|
||||
describeRoute({
|
||||
@@ -2,12 +2,12 @@ import { Hono } from "hono"
|
||||
import { describeRoute, validator, resolver } from "hono-openapi"
|
||||
import { Effect } from "effect"
|
||||
import z from "zod"
|
||||
import { AppRuntime } from "../../effect/app-runtime"
|
||||
import { File } from "../../file"
|
||||
import { Ripgrep } from "../../file/ripgrep"
|
||||
import { LSP } from "../../lsp"
|
||||
import { Instance } from "../../project/instance"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { File } from "@/file"
|
||||
import { Ripgrep } from "@/file/ripgrep"
|
||||
import { LSP } from "@/lsp"
|
||||
import { Instance } from "@/project/instance"
|
||||
import { lazy } from "@/util/lazy"
|
||||
|
||||
export const FileRoutes = lazy(() =>
|
||||
new Hono()
|
||||
@@ -3,15 +3,15 @@ import { Hono } from "hono"
|
||||
import type { UpgradeWebSocket } from "hono/ws"
|
||||
import { Context, Effect } from "effect"
|
||||
import z from "zod"
|
||||
import { Format } from "../../format"
|
||||
import { Format } from "@/format"
|
||||
import { TuiRoutes } from "./tui"
|
||||
import { Instance } from "../../project/instance"
|
||||
import { Vcs } from "../../project"
|
||||
import { Agent } from "../../agent/agent"
|
||||
import { Skill } from "../../skill"
|
||||
import { Global } from "../../global"
|
||||
import { LSP } from "../../lsp"
|
||||
import { Command } from "../../command"
|
||||
import { Instance } from "@/project/instance"
|
||||
import { Vcs } from "@/project"
|
||||
import { Agent } from "@/agent/agent"
|
||||
import { Skill } from "@/skill"
|
||||
import { Global } from "@/global"
|
||||
import { LSP } from "@/lsp"
|
||||
import { Command } from "@/command"
|
||||
import { QuestionRoutes } from "./question"
|
||||
import { PermissionRoutes } from "./permission"
|
||||
import { Flag } from "@/flag/flag"
|
||||
@@ -26,11 +26,10 @@ import { ExperimentalRoutes } from "./experimental"
|
||||
import { ProviderRoutes } from "./provider"
|
||||
import { EventRoutes } from "./event"
|
||||
import { SyncRoutes } from "./sync"
|
||||
import { WorkspaceRouterMiddleware } from "./middleware"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
|
||||
export const InstanceRoutes = (upgrade: UpgradeWebSocket): Hono => {
|
||||
const app = new Hono().use(WorkspaceRouterMiddleware(upgrade))
|
||||
const app = new Hono()
|
||||
|
||||
if (Flag.OPENCODE_EXPERIMENTAL_HTTPAPI) {
|
||||
const handler = ExperimentalHttpApiServer.webHandler().handler
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Hono } from "hono"
|
||||
import { describeRoute, validator, resolver } from "hono-openapi"
|
||||
import z from "zod"
|
||||
import { MCP } from "../../mcp"
|
||||
import { Config } from "../../config"
|
||||
import { ConfigMCP } from "../../config/mcp"
|
||||
import { AppRuntime } from "../../effect/app-runtime"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { MCP } from "@/mcp"
|
||||
import { Config } from "@/config"
|
||||
import { ConfigMCP } from "@/config/mcp"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { Effect } from "effect"
|
||||
|
||||
export const McpRoutes = lazy(() =>
|
||||
@@ -4,8 +4,8 @@ import z from "zod"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { Permission } from "@/permission"
|
||||
import { PermissionID } from "@/permission/schema"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
|
||||
export const PermissionRoutes = lazy(() =>
|
||||
new Hono()
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Hono } from "hono"
|
||||
import { describeRoute, validator } from "hono-openapi"
|
||||
import { resolver } from "hono-openapi"
|
||||
import { Instance } from "../../project/instance"
|
||||
import { Project } from "../../project"
|
||||
import { Instance } from "@/project/instance"
|
||||
import { Project } from "@/project"
|
||||
import z from "zod"
|
||||
import { ProjectID } from "../../project/schema"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { InstanceBootstrap } from "../../project/bootstrap"
|
||||
import { ProjectID } from "@/project/schema"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { InstanceBootstrap } from "@/project/bootstrap"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
|
||||
export const ProjectRoutes = lazy(() =>
|
||||
@@ -1,15 +1,15 @@
|
||||
import { Hono } from "hono"
|
||||
import { describeRoute, validator, resolver } from "hono-openapi"
|
||||
import z from "zod"
|
||||
import { Config } from "../../config"
|
||||
import { Provider } from "../../provider"
|
||||
import { ModelsDev } from "../../provider"
|
||||
import { ProviderAuth } from "../../provider"
|
||||
import { ProviderID } from "../../provider/schema"
|
||||
import { AppRuntime } from "../../effect/app-runtime"
|
||||
import { Config } from "@/config"
|
||||
import { Provider } from "@/provider"
|
||||
import { ModelsDev } from "@/provider"
|
||||
import { ProviderAuth } from "@/provider"
|
||||
import { ProviderID } from "@/provider/schema"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { mapValues } from "remeda"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { Effect } from "effect"
|
||||
|
||||
export const ProviderRoutes = lazy(() =>
|
||||
@@ -6,8 +6,8 @@ import z from "zod"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { Pty } from "@/pty"
|
||||
import { PtyID } from "@/pty/schema"
|
||||
import { NotFoundError } from "../../storage"
|
||||
import { errors } from "../error"
|
||||
import { NotFoundError } from "@/storage"
|
||||
import { errors } from "../../error"
|
||||
|
||||
export function PtyRoutes(upgradeWebSocket: UpgradeWebSocket) {
|
||||
return new Hono()
|
||||
@@ -2,11 +2,11 @@ import { Hono } from "hono"
|
||||
import { describeRoute, validator } from "hono-openapi"
|
||||
import { resolver } from "hono-openapi"
|
||||
import { QuestionID } from "@/question/schema"
|
||||
import { Question } from "../../question"
|
||||
import { Question } from "@/question"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import z from "zod"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
|
||||
const Reply = z.object({
|
||||
answers: Question.Answer.zod
|
||||
@@ -3,28 +3,28 @@ import { stream } from "hono/streaming"
|
||||
import { describeRoute, validator, resolver } from "hono-openapi"
|
||||
import { SessionID, MessageID, PartID } from "@/session/schema"
|
||||
import z from "zod"
|
||||
import { Session } from "../../session"
|
||||
import { MessageV2 } from "../../session/message-v2"
|
||||
import { SessionPrompt } from "../../session/prompt"
|
||||
import { Session } from "@/session"
|
||||
import { MessageV2 } from "@/session/message-v2"
|
||||
import { SessionPrompt } from "@/session/prompt"
|
||||
import { SessionRunState } from "@/session/run-state"
|
||||
import { SessionCompaction } from "../../session/compaction"
|
||||
import { SessionRevert } from "../../session/revert"
|
||||
import { SessionCompaction } from "@/session/compaction"
|
||||
import { SessionRevert } from "@/session/revert"
|
||||
import { SessionShare } from "@/share"
|
||||
import { SessionStatus } from "@/session/status"
|
||||
import { SessionSummary } from "@/session/summary"
|
||||
import { Todo } from "../../session/todo"
|
||||
import { Todo } from "@/session/todo"
|
||||
import { Effect } from "effect"
|
||||
import { AppRuntime } from "../../effect/app-runtime"
|
||||
import { Agent } from "../../agent/agent"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { Agent } from "@/agent/agent"
|
||||
import { Snapshot } from "@/snapshot"
|
||||
import { Command } from "../../command"
|
||||
import { Log } from "../../util"
|
||||
import { Command } from "@/command"
|
||||
import { Log } from "@/util"
|
||||
import { Permission } from "@/permission"
|
||||
import { PermissionID } from "@/permission/schema"
|
||||
import { ModelID, ProviderID } from "@/provider/schema"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { Bus } from "../../bus"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { Bus } from "@/bus"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import { jsonRequest } from "./trace"
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Database, asc, and, not, or, lte, eq } from "@/storage"
|
||||
import { EventTable } from "@/sync/event.sql"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { Log } from "@/util"
|
||||
import { errors } from "../error"
|
||||
import { errors } from "../../error"
|
||||
|
||||
const ReplayEvent = z.object({
|
||||
id: z.string(),
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Context } from "hono"
|
||||
import { Effect } from "effect"
|
||||
import { AppRuntime } from "../../effect/app-runtime"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
|
||||
type AppEnv = Parameters<typeof AppRuntime.runPromise>[0] extends Effect.Effect<any, any, infer R> ? R : never
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Hono, type Context } from "hono"
|
||||
import { describeRoute, validator, resolver } from "hono-openapi"
|
||||
import z from "zod"
|
||||
import { Bus } from "../../bus"
|
||||
import { Session } from "../../session"
|
||||
import { Bus } from "@/bus"
|
||||
import { Session } from "@/session"
|
||||
import { TuiEvent } from "@/cli/cmd/tui/event"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { AsyncQueue } from "../../util/queue"
|
||||
import { errors } from "../error"
|
||||
import { lazy } from "../../util/lazy"
|
||||
import { AsyncQueue } from "@/util/queue"
|
||||
import { errors } from "../../error"
|
||||
import { lazy } from "@/util/lazy"
|
||||
|
||||
const TuiRequest = z.object({
|
||||
path: z.string(),
|
||||
@@ -1,16 +1,25 @@
|
||||
import { generateSpecs } from "hono-openapi"
|
||||
import { Hono } from "hono"
|
||||
import type { MiddlewareHandler } from "hono"
|
||||
import { adapter } from "#hono"
|
||||
import { MDNS } from "./mdns"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { AuthMiddleware, CompressionMiddleware, CorsMiddleware, ErrorMiddleware, LoggerMiddleware } from "./middleware"
|
||||
import { FenceMiddleware } from "./fence"
|
||||
import { InstanceRoutes } from "./instance"
|
||||
import { initProjectors } from "./projectors"
|
||||
import { Log } from "@/util"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { ControlPlaneRoutes } from "./control"
|
||||
import { UIRoutes } from "./ui"
|
||||
import { Instance } from "@/project/instance"
|
||||
import { InstanceBootstrap } from "@/project/bootstrap"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import { WorkspaceID } from "@/control-plane/schema"
|
||||
import { WorkspaceContext } from "@/control-plane/workspace-context"
|
||||
import { MDNS } from "./mdns"
|
||||
import { AuthMiddleware, CompressionMiddleware, CorsMiddleware, ErrorMiddleware, LoggerMiddleware } from "./middleware"
|
||||
import { FenceMiddleware } from "./fence"
|
||||
import { initProjectors } from "./projectors"
|
||||
import { InstanceRoutes } from "./routes/instance"
|
||||
import { ControlPlaneRoutes } from "./routes/control"
|
||||
import { UIRoutes } from "./routes/ui"
|
||||
import { GlobalRoutes } from "./routes/global"
|
||||
import { WorkspaceRouterMiddleware } from "./workspace"
|
||||
|
||||
// @ts-ignore This global is needed to prevent ai-sdk from logging warnings to stdout https://github.com/vercel/ai/blob/2dc67e0ef538307f21368db32d5a12345d98831b/packages/ai/src/logger/log-warnings.ts#L85
|
||||
globalThis.AI_SDK_LOG_WARNINGS = false
|
||||
@@ -30,18 +39,48 @@ export const Default = lazy(() => create({}))
|
||||
|
||||
function create(opts: { cors?: string[] }) {
|
||||
const app = new Hono()
|
||||
.onError(ErrorMiddleware)
|
||||
.use(AuthMiddleware)
|
||||
.use(LoggerMiddleware)
|
||||
.use(CompressionMiddleware)
|
||||
.use(CorsMiddleware(opts))
|
||||
.route("/global", GlobalRoutes())
|
||||
|
||||
const runtime = adapter.create(app)
|
||||
|
||||
function InstanceMiddleware(workspaceID?: WorkspaceID): MiddlewareHandler {
|
||||
return async (c, next) => {
|
||||
const raw = c.req.query("directory") || c.req.header("x-opencode-directory") || process.cwd()
|
||||
const directory = AppFileSystem.resolve(
|
||||
(() => {
|
||||
try {
|
||||
return decodeURIComponent(raw)
|
||||
} catch {
|
||||
return raw
|
||||
}
|
||||
})(),
|
||||
)
|
||||
|
||||
return WorkspaceContext.provide({
|
||||
workspaceID,
|
||||
async fn() {
|
||||
return Instance.provide({
|
||||
directory,
|
||||
init: () => AppRuntime.runPromise(InstanceBootstrap),
|
||||
async fn() {
|
||||
return next()
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (Flag.OPENCODE_WORKSPACE_ID) {
|
||||
return {
|
||||
app: app
|
||||
.onError(ErrorMiddleware)
|
||||
.use(AuthMiddleware)
|
||||
.use(LoggerMiddleware)
|
||||
.use(CompressionMiddleware)
|
||||
.use(CorsMiddleware(opts))
|
||||
.use(InstanceMiddleware(Flag.OPENCODE_WORKSPACE_ID ? WorkspaceID.make(Flag.OPENCODE_WORKSPACE_ID) : undefined))
|
||||
.use(FenceMiddleware)
|
||||
.route("/", ControlPlaneRoutes())
|
||||
.route("/", InstanceRoutes(runtime.upgradeWebSocket)),
|
||||
runtime,
|
||||
}
|
||||
@@ -49,12 +88,9 @@ function create(opts: { cors?: string[] }) {
|
||||
|
||||
return {
|
||||
app: app
|
||||
.onError(ErrorMiddleware)
|
||||
.use(AuthMiddleware)
|
||||
.use(LoggerMiddleware)
|
||||
.use(CompressionMiddleware)
|
||||
.use(CorsMiddleware(opts))
|
||||
.use(InstanceMiddleware())
|
||||
.route("/", ControlPlaneRoutes())
|
||||
.use(WorkspaceRouterMiddleware(runtime.upgradeWebSocket))
|
||||
.route("/", InstanceRoutes(runtime.upgradeWebSocket))
|
||||
.route("/", UIRoutes()),
|
||||
runtime,
|
||||
|
||||
@@ -2,17 +2,16 @@ import type { MiddlewareHandler } from "hono"
|
||||
import type { UpgradeWebSocket } from "hono/ws"
|
||||
import { getAdaptor } from "@/control-plane/adaptors"
|
||||
import { WorkspaceID } from "@/control-plane/schema"
|
||||
import { WorkspaceContext } from "@/control-plane/workspace-context"
|
||||
import { Workspace } from "@/control-plane/workspace"
|
||||
import { ServerProxy } from "../proxy"
|
||||
import { Instance } from "@/project/instance"
|
||||
import { InstanceBootstrap } from "@/project/bootstrap"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { InstanceBootstrap } from "@/project/bootstrap"
|
||||
import { Instance } from "@/project/instance"
|
||||
import { Session } from "@/session"
|
||||
import { SessionID } from "@/session/schema"
|
||||
import { WorkspaceContext } from "@/control-plane/workspace-context"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { Log } from "@/util"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import { ServerProxy } from "./proxy"
|
||||
|
||||
type Rule = { method?: string; path: string; exact?: boolean; action: "local" | "forward" }
|
||||
|
||||
@@ -51,45 +50,13 @@ export function WorkspaceRouterMiddleware(upgrade: UpgradeWebSocket): Middleware
|
||||
const log = Log.create({ service: "workspace-router" })
|
||||
|
||||
return async (c, next) => {
|
||||
const raw = c.req.query("directory") || c.req.header("x-opencode-directory") || process.cwd()
|
||||
const directory = AppFileSystem.resolve(
|
||||
(() => {
|
||||
try {
|
||||
return decodeURIComponent(raw)
|
||||
} catch {
|
||||
return raw
|
||||
}
|
||||
})(),
|
||||
)
|
||||
|
||||
const url = new URL(c.req.url)
|
||||
|
||||
const sessionWorkspaceID = await getSessionWorkspace(url)
|
||||
const workspaceID = sessionWorkspaceID || url.searchParams.get("workspace")
|
||||
|
||||
if (!workspaceID || url.pathname.startsWith("/console") || Flag.OPENCODE_WORKSPACE_ID) {
|
||||
if (Flag.OPENCODE_WORKSPACE_ID) {
|
||||
return WorkspaceContext.provide({
|
||||
workspaceID: WorkspaceID.make(Flag.OPENCODE_WORKSPACE_ID),
|
||||
async fn() {
|
||||
return Instance.provide({
|
||||
directory,
|
||||
init: () => AppRuntime.runPromise(InstanceBootstrap),
|
||||
async fn() {
|
||||
return next()
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return Instance.provide({
|
||||
directory,
|
||||
init: () => AppRuntime.runPromise(InstanceBootstrap),
|
||||
async fn() {
|
||||
return next()
|
||||
},
|
||||
})
|
||||
return next()
|
||||
}
|
||||
|
||||
const workspace = await Workspace.get(WorkspaceID.make(workspaceID))
|
||||
@@ -165,16 +165,3 @@ describe("session messages endpoint", () => {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("session.prompt_async error handling", () => {
|
||||
test("prompt_async route has error handler for detached prompt call", async () => {
|
||||
const src = await Bun.file(new URL("../../src/server/instance/session.ts", import.meta.url)).text()
|
||||
const start = src.indexOf('"/:sessionID/prompt_async"')
|
||||
const end = src.indexOf('"/:sessionID/command"', start)
|
||||
expect(start).toBeGreaterThan(-1)
|
||||
expect(end).toBeGreaterThan(start)
|
||||
const route = src.slice(start, end)
|
||||
expect(route).toContain(".catch(")
|
||||
expect(route).toContain("Bus.publish(Session.Event.Error")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -510,6 +510,430 @@ export class App extends HeyApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
export class Adaptor extends HeyApiClient {
|
||||
/**
|
||||
* List workspace adaptors
|
||||
*
|
||||
* List all available workspace adaptors for the current project.
|
||||
*/
|
||||
public list<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalWorkspaceAdaptorListResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/workspace/adaptor",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Workspace extends HeyApiClient {
|
||||
/**
|
||||
* List workspaces
|
||||
*
|
||||
* List all workspaces.
|
||||
*/
|
||||
public list<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalWorkspaceListResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/workspace",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Create workspace
|
||||
*
|
||||
* Create a workspace for the current project.
|
||||
*/
|
||||
public create<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
id?: string
|
||||
type?: string
|
||||
branch?: string | null
|
||||
extra?: unknown | null
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "id" },
|
||||
{ in: "body", key: "type" },
|
||||
{ in: "body", key: "branch" },
|
||||
{ in: "body", key: "extra" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<
|
||||
ExperimentalWorkspaceCreateResponses,
|
||||
ExperimentalWorkspaceCreateErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
url: "/experimental/workspace",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Workspace status
|
||||
*
|
||||
* Get connection status for workspaces in the current project.
|
||||
*/
|
||||
public status<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalWorkspaceStatusResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/workspace/status",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove workspace
|
||||
*
|
||||
* Remove an existing workspace.
|
||||
*/
|
||||
public remove<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
id: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "id" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).delete<
|
||||
ExperimentalWorkspaceRemoveResponses,
|
||||
ExperimentalWorkspaceRemoveErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
url: "/experimental/workspace/{id}",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore session into workspace
|
||||
*
|
||||
* Replay a session's sync events into the target workspace in batches.
|
||||
*/
|
||||
public sessionRestore<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
id: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
sessionID?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "id" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "sessionID" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<
|
||||
ExperimentalWorkspaceSessionRestoreResponses,
|
||||
ExperimentalWorkspaceSessionRestoreErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
url: "/experimental/workspace/{id}/session-restore",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
private _adaptor?: Adaptor
|
||||
get adaptor(): Adaptor {
|
||||
return (this._adaptor ??= new Adaptor({ client: this.client }))
|
||||
}
|
||||
}
|
||||
|
||||
export class Console extends HeyApiClient {
|
||||
/**
|
||||
* Get active Console provider metadata
|
||||
*
|
||||
* Get the active Console org name and the set of provider IDs managed by that Console org.
|
||||
*/
|
||||
public get<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalConsoleGetResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/console",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* List switchable Console orgs
|
||||
*
|
||||
* Get the available Console orgs across logged-in accounts, including the current active org.
|
||||
*/
|
||||
public listOrgs<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalConsoleListOrgsResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/console/orgs",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch active Console org
|
||||
*
|
||||
* Persist a new active Console account/org selection for the current local OpenCode state.
|
||||
*/
|
||||
public switchOrg<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
accountID?: string
|
||||
orgID?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "accountID" },
|
||||
{ in: "body", key: "orgID" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<ExperimentalConsoleSwitchOrgResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/console/switch",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Session extends HeyApiClient {
|
||||
/**
|
||||
* List sessions
|
||||
*
|
||||
* Get a list of all OpenCode sessions across projects, sorted by most recently updated. Archived sessions are excluded by default.
|
||||
*/
|
||||
public list<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
roots?: boolean
|
||||
start?: number
|
||||
cursor?: number
|
||||
search?: string
|
||||
limit?: number
|
||||
archived?: boolean
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "query", key: "roots" },
|
||||
{ in: "query", key: "start" },
|
||||
{ in: "query", key: "cursor" },
|
||||
{ in: "query", key: "search" },
|
||||
{ in: "query", key: "limit" },
|
||||
{ in: "query", key: "archived" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalSessionListResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/session",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Resource extends HeyApiClient {
|
||||
/**
|
||||
* Get MCP resources
|
||||
*
|
||||
* Get all available MCP resources from connected servers. Optionally filter by name.
|
||||
*/
|
||||
public list<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalResourceListResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/resource",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Experimental extends HeyApiClient {
|
||||
private _workspace?: Workspace
|
||||
get workspace(): Workspace {
|
||||
return (this._workspace ??= new Workspace({ client: this.client }))
|
||||
}
|
||||
|
||||
private _console?: Console
|
||||
get console(): Console {
|
||||
return (this._console ??= new Console({ client: this.client }))
|
||||
}
|
||||
|
||||
private _session?: Session
|
||||
get session(): Session {
|
||||
return (this._session ??= new Session({ client: this.client }))
|
||||
}
|
||||
|
||||
private _resource?: Resource
|
||||
get resource(): Resource {
|
||||
return (this._resource ??= new Resource({ client: this.client }))
|
||||
}
|
||||
}
|
||||
|
||||
export class Project extends HeyApiClient {
|
||||
/**
|
||||
* List all projects
|
||||
@@ -972,430 +1396,6 @@ export class Config2 extends HeyApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
export class Console extends HeyApiClient {
|
||||
/**
|
||||
* Get active Console provider metadata
|
||||
*
|
||||
* Get the active Console org name and the set of provider IDs managed by that Console org.
|
||||
*/
|
||||
public get<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalConsoleGetResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/console",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* List switchable Console orgs
|
||||
*
|
||||
* Get the available Console orgs across logged-in accounts, including the current active org.
|
||||
*/
|
||||
public listOrgs<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalConsoleListOrgsResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/console/orgs",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch active Console org
|
||||
*
|
||||
* Persist a new active Console account/org selection for the current local OpenCode state.
|
||||
*/
|
||||
public switchOrg<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
accountID?: string
|
||||
orgID?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "accountID" },
|
||||
{ in: "body", key: "orgID" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<ExperimentalConsoleSwitchOrgResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/console/switch",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Adaptor extends HeyApiClient {
|
||||
/**
|
||||
* List workspace adaptors
|
||||
*
|
||||
* List all available workspace adaptors for the current project.
|
||||
*/
|
||||
public list<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalWorkspaceAdaptorListResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/workspace/adaptor",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Workspace extends HeyApiClient {
|
||||
/**
|
||||
* List workspaces
|
||||
*
|
||||
* List all workspaces.
|
||||
*/
|
||||
public list<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalWorkspaceListResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/workspace",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Create workspace
|
||||
*
|
||||
* Create a workspace for the current project.
|
||||
*/
|
||||
public create<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
id?: string
|
||||
type?: string
|
||||
branch?: string | null
|
||||
extra?: unknown | null
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "id" },
|
||||
{ in: "body", key: "type" },
|
||||
{ in: "body", key: "branch" },
|
||||
{ in: "body", key: "extra" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<
|
||||
ExperimentalWorkspaceCreateResponses,
|
||||
ExperimentalWorkspaceCreateErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
url: "/experimental/workspace",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Workspace status
|
||||
*
|
||||
* Get connection status for workspaces in the current project.
|
||||
*/
|
||||
public status<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalWorkspaceStatusResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/workspace/status",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove workspace
|
||||
*
|
||||
* Remove an existing workspace.
|
||||
*/
|
||||
public remove<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
id: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "id" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).delete<
|
||||
ExperimentalWorkspaceRemoveResponses,
|
||||
ExperimentalWorkspaceRemoveErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
url: "/experimental/workspace/{id}",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore session into workspace
|
||||
*
|
||||
* Replay a session's sync events into the target workspace in batches.
|
||||
*/
|
||||
public sessionRestore<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
id: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
sessionID?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "id" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "sessionID" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<
|
||||
ExperimentalWorkspaceSessionRestoreResponses,
|
||||
ExperimentalWorkspaceSessionRestoreErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
url: "/experimental/workspace/{id}/session-restore",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
private _adaptor?: Adaptor
|
||||
get adaptor(): Adaptor {
|
||||
return (this._adaptor ??= new Adaptor({ client: this.client }))
|
||||
}
|
||||
}
|
||||
|
||||
export class Session extends HeyApiClient {
|
||||
/**
|
||||
* List sessions
|
||||
*
|
||||
* Get a list of all OpenCode sessions across projects, sorted by most recently updated. Archived sessions are excluded by default.
|
||||
*/
|
||||
public list<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
roots?: boolean
|
||||
start?: number
|
||||
cursor?: number
|
||||
search?: string
|
||||
limit?: number
|
||||
archived?: boolean
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "query", key: "roots" },
|
||||
{ in: "query", key: "start" },
|
||||
{ in: "query", key: "cursor" },
|
||||
{ in: "query", key: "search" },
|
||||
{ in: "query", key: "limit" },
|
||||
{ in: "query", key: "archived" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalSessionListResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/session",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Resource extends HeyApiClient {
|
||||
/**
|
||||
* Get MCP resources
|
||||
*
|
||||
* Get all available MCP resources from connected servers. Optionally filter by name.
|
||||
*/
|
||||
public list<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ExperimentalResourceListResponses, unknown, ThrowOnError>({
|
||||
url: "/experimental/resource",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Experimental extends HeyApiClient {
|
||||
private _console?: Console
|
||||
get console(): Console {
|
||||
return (this._console ??= new Console({ client: this.client }))
|
||||
}
|
||||
|
||||
private _workspace?: Workspace
|
||||
get workspace(): Workspace {
|
||||
return (this._workspace ??= new Workspace({ client: this.client }))
|
||||
}
|
||||
|
||||
private _session?: Session
|
||||
get session(): Session {
|
||||
return (this._session ??= new Session({ client: this.client }))
|
||||
}
|
||||
|
||||
private _resource?: Resource
|
||||
get resource(): Resource {
|
||||
return (this._resource ??= new Resource({ client: this.client }))
|
||||
}
|
||||
}
|
||||
|
||||
export class Tool extends HeyApiClient {
|
||||
/**
|
||||
* List tool IDs
|
||||
@@ -4314,6 +4314,11 @@ export class OpencodeClient extends HeyApiClient {
|
||||
return (this._app ??= new App({ client: this.client }))
|
||||
}
|
||||
|
||||
private _experimental?: Experimental
|
||||
get experimental(): Experimental {
|
||||
return (this._experimental ??= new Experimental({ client: this.client }))
|
||||
}
|
||||
|
||||
private _project?: Project
|
||||
get project(): Project {
|
||||
return (this._project ??= new Project({ client: this.client }))
|
||||
@@ -4329,11 +4334,6 @@ export class OpencodeClient extends HeyApiClient {
|
||||
return (this._config ??= new Config2({ client: this.client }))
|
||||
}
|
||||
|
||||
private _experimental?: Experimental
|
||||
get experimental(): Experimental {
|
||||
return (this._experimental ??= new Experimental({ client: this.client }))
|
||||
}
|
||||
|
||||
private _tool?: Tool
|
||||
get tool(): Tool {
|
||||
return (this._tool ??= new Tool({ client: this.client }))
|
||||
|
||||
@@ -1706,6 +1706,16 @@ export type WellKnownAuth = {
|
||||
|
||||
export type Auth = OAuth | ApiAuth | WellKnownAuth
|
||||
|
||||
export type Workspace = {
|
||||
id: string
|
||||
type: string
|
||||
name: string
|
||||
branch: string | null
|
||||
directory: string | null
|
||||
extra: unknown | null
|
||||
projectID: string
|
||||
}
|
||||
|
||||
export type NotFoundError = {
|
||||
name: "NotFoundError"
|
||||
data: {
|
||||
@@ -1808,16 +1818,6 @@ export type ToolListItem = {
|
||||
|
||||
export type ToolList = Array<ToolListItem>
|
||||
|
||||
export type Workspace = {
|
||||
id: string
|
||||
type: string
|
||||
name: string
|
||||
branch: string | null
|
||||
directory: string | null
|
||||
extra: unknown | null
|
||||
projectID: string
|
||||
}
|
||||
|
||||
export type Worktree = {
|
||||
name: string
|
||||
branch: string
|
||||
@@ -2394,6 +2394,177 @@ export type AppLogResponses = {
|
||||
|
||||
export type AppLogResponse = AppLogResponses[keyof AppLogResponses]
|
||||
|
||||
export type ExperimentalWorkspaceAdaptorListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace/adaptor"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceAdaptorListResponses = {
|
||||
/**
|
||||
* Workspace adaptors
|
||||
*/
|
||||
200: Array<{
|
||||
type: string
|
||||
name: string
|
||||
description: string
|
||||
}>
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceAdaptorListResponse =
|
||||
ExperimentalWorkspaceAdaptorListResponses[keyof ExperimentalWorkspaceAdaptorListResponses]
|
||||
|
||||
export type ExperimentalWorkspaceListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceListResponses = {
|
||||
/**
|
||||
* Workspaces
|
||||
*/
|
||||
200: Array<Workspace>
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceListResponse =
|
||||
ExperimentalWorkspaceListResponses[keyof ExperimentalWorkspaceListResponses]
|
||||
|
||||
export type ExperimentalWorkspaceCreateData = {
|
||||
body?: {
|
||||
id?: string
|
||||
type: string
|
||||
branch: string | null
|
||||
extra: unknown | null
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceCreateErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceCreateError =
|
||||
ExperimentalWorkspaceCreateErrors[keyof ExperimentalWorkspaceCreateErrors]
|
||||
|
||||
export type ExperimentalWorkspaceCreateResponses = {
|
||||
/**
|
||||
* Workspace created
|
||||
*/
|
||||
200: Workspace
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceCreateResponse =
|
||||
ExperimentalWorkspaceCreateResponses[keyof ExperimentalWorkspaceCreateResponses]
|
||||
|
||||
export type ExperimentalWorkspaceStatusData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace/status"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceStatusResponses = {
|
||||
/**
|
||||
* Workspace status
|
||||
*/
|
||||
200: Array<{
|
||||
workspaceID: string
|
||||
status: "connected" | "connecting" | "disconnected" | "error"
|
||||
error?: string
|
||||
}>
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceStatusResponse =
|
||||
ExperimentalWorkspaceStatusResponses[keyof ExperimentalWorkspaceStatusResponses]
|
||||
|
||||
export type ExperimentalWorkspaceRemoveData = {
|
||||
body?: never
|
||||
path: {
|
||||
id: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace/{id}"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceRemoveErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceRemoveError =
|
||||
ExperimentalWorkspaceRemoveErrors[keyof ExperimentalWorkspaceRemoveErrors]
|
||||
|
||||
export type ExperimentalWorkspaceRemoveResponses = {
|
||||
/**
|
||||
* Workspace removed
|
||||
*/
|
||||
200: Workspace
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceRemoveResponse =
|
||||
ExperimentalWorkspaceRemoveResponses[keyof ExperimentalWorkspaceRemoveResponses]
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreData = {
|
||||
body?: {
|
||||
sessionID: string
|
||||
}
|
||||
path: {
|
||||
id: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace/{id}/session-restore"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreError =
|
||||
ExperimentalWorkspaceSessionRestoreErrors[keyof ExperimentalWorkspaceSessionRestoreErrors]
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreResponses = {
|
||||
/**
|
||||
* Session replay started
|
||||
*/
|
||||
200: {
|
||||
total: number
|
||||
}
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreResponse =
|
||||
ExperimentalWorkspaceSessionRestoreResponses[keyof ExperimentalWorkspaceSessionRestoreResponses]
|
||||
|
||||
export type ProjectListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
@@ -2883,177 +3054,6 @@ export type ToolListResponses = {
|
||||
|
||||
export type ToolListResponse = ToolListResponses[keyof ToolListResponses]
|
||||
|
||||
export type ExperimentalWorkspaceAdaptorListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace/adaptor"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceAdaptorListResponses = {
|
||||
/**
|
||||
* Workspace adaptors
|
||||
*/
|
||||
200: Array<{
|
||||
type: string
|
||||
name: string
|
||||
description: string
|
||||
}>
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceAdaptorListResponse =
|
||||
ExperimentalWorkspaceAdaptorListResponses[keyof ExperimentalWorkspaceAdaptorListResponses]
|
||||
|
||||
export type ExperimentalWorkspaceListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceListResponses = {
|
||||
/**
|
||||
* Workspaces
|
||||
*/
|
||||
200: Array<Workspace>
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceListResponse =
|
||||
ExperimentalWorkspaceListResponses[keyof ExperimentalWorkspaceListResponses]
|
||||
|
||||
export type ExperimentalWorkspaceCreateData = {
|
||||
body?: {
|
||||
id?: string
|
||||
type: string
|
||||
branch: string | null
|
||||
extra: unknown | null
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceCreateErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceCreateError =
|
||||
ExperimentalWorkspaceCreateErrors[keyof ExperimentalWorkspaceCreateErrors]
|
||||
|
||||
export type ExperimentalWorkspaceCreateResponses = {
|
||||
/**
|
||||
* Workspace created
|
||||
*/
|
||||
200: Workspace
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceCreateResponse =
|
||||
ExperimentalWorkspaceCreateResponses[keyof ExperimentalWorkspaceCreateResponses]
|
||||
|
||||
export type ExperimentalWorkspaceStatusData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace/status"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceStatusResponses = {
|
||||
/**
|
||||
* Workspace status
|
||||
*/
|
||||
200: Array<{
|
||||
workspaceID: string
|
||||
status: "connected" | "connecting" | "disconnected" | "error"
|
||||
error?: string
|
||||
}>
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceStatusResponse =
|
||||
ExperimentalWorkspaceStatusResponses[keyof ExperimentalWorkspaceStatusResponses]
|
||||
|
||||
export type ExperimentalWorkspaceRemoveData = {
|
||||
body?: never
|
||||
path: {
|
||||
id: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace/{id}"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceRemoveErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceRemoveError =
|
||||
ExperimentalWorkspaceRemoveErrors[keyof ExperimentalWorkspaceRemoveErrors]
|
||||
|
||||
export type ExperimentalWorkspaceRemoveResponses = {
|
||||
/**
|
||||
* Workspace removed
|
||||
*/
|
||||
200: Workspace
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceRemoveResponse =
|
||||
ExperimentalWorkspaceRemoveResponses[keyof ExperimentalWorkspaceRemoveResponses]
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreData = {
|
||||
body?: {
|
||||
sessionID: string
|
||||
}
|
||||
path: {
|
||||
id: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/experimental/workspace/{id}/session-restore"
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreError =
|
||||
ExperimentalWorkspaceSessionRestoreErrors[keyof ExperimentalWorkspaceSessionRestoreErrors]
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreResponses = {
|
||||
/**
|
||||
* Session replay started
|
||||
*/
|
||||
200: {
|
||||
total: number
|
||||
}
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceSessionRestoreResponse =
|
||||
ExperimentalWorkspaceSessionRestoreResponses[keyof ExperimentalWorkspaceSessionRestoreResponses]
|
||||
|
||||
export type WorktreeRemoveData = {
|
||||
body?: WorktreeRemoveInput
|
||||
path?: never
|
||||
|
||||
@@ -415,6 +415,394 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace/adaptor": {
|
||||
"get": {
|
||||
"operationId": "experimental.workspace.adaptor.list",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "List workspace adaptors",
|
||||
"description": "List all available workspace adaptors for the current project.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspace adaptors",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["type", "name", "description"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.adaptor.list({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace": {
|
||||
"post": {
|
||||
"operationId": "experimental.workspace.create",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "Create workspace",
|
||||
"description": "Create a workspace for the current project.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspace created",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Workspace"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"branch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"anyOf": [
|
||||
{},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["type", "branch", "extra"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.create({\n ...\n})"
|
||||
}
|
||||
]
|
||||
},
|
||||
"get": {
|
||||
"operationId": "experimental.workspace.list",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "List workspaces",
|
||||
"description": "List all workspaces.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspaces",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Workspace"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.list({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace/status": {
|
||||
"get": {
|
||||
"operationId": "experimental.workspace.status",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "Workspace status",
|
||||
"description": "Get connection status for workspaces in the current project.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspace status",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"workspaceID": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["connected", "connecting", "disconnected", "error"]
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["workspaceID", "status"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.status({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace/{id}": {
|
||||
"delete": {
|
||||
"operationId": "experimental.workspace.remove",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "path",
|
||||
"name": "id",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"summary": "Remove workspace",
|
||||
"description": "Remove an existing workspace.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspace removed",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Workspace"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.remove({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace/{id}/session-restore": {
|
||||
"post": {
|
||||
"operationId": "experimental.workspace.sessionRestore",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "path",
|
||||
"name": "id",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"summary": "Restore session into workspace",
|
||||
"description": "Replay a session's sync events into the target workspace in batches.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Session replay started",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 9007199254740991
|
||||
}
|
||||
},
|
||||
"required": ["total"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"sessionID": {
|
||||
"type": "string",
|
||||
"pattern": "^ses.*"
|
||||
}
|
||||
},
|
||||
"required": ["sessionID"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.sessionRestore({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/project": {
|
||||
"get": {
|
||||
"operationId": "project.list",
|
||||
@@ -1501,394 +1889,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace/adaptor": {
|
||||
"get": {
|
||||
"operationId": "experimental.workspace.adaptor.list",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "List workspace adaptors",
|
||||
"description": "List all available workspace adaptors for the current project.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspace adaptors",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["type", "name", "description"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.adaptor.list({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace": {
|
||||
"post": {
|
||||
"operationId": "experimental.workspace.create",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "Create workspace",
|
||||
"description": "Create a workspace for the current project.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspace created",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Workspace"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"branch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"anyOf": [
|
||||
{},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["type", "branch", "extra"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.create({\n ...\n})"
|
||||
}
|
||||
]
|
||||
},
|
||||
"get": {
|
||||
"operationId": "experimental.workspace.list",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "List workspaces",
|
||||
"description": "List all workspaces.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspaces",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Workspace"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.list({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace/status": {
|
||||
"get": {
|
||||
"operationId": "experimental.workspace.status",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "Workspace status",
|
||||
"description": "Get connection status for workspaces in the current project.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspace status",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"workspaceID": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["connected", "connecting", "disconnected", "error"]
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["workspaceID", "status"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.status({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace/{id}": {
|
||||
"delete": {
|
||||
"operationId": "experimental.workspace.remove",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "path",
|
||||
"name": "id",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"summary": "Remove workspace",
|
||||
"description": "Remove an existing workspace.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Workspace removed",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Workspace"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.remove({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/workspace/{id}/session-restore": {
|
||||
"post": {
|
||||
"operationId": "experimental.workspace.sessionRestore",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "directory",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "workspace",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "path",
|
||||
"name": "id",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"summary": "Restore session into workspace",
|
||||
"description": "Replay a session's sync events into the target workspace in batches.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Session replay started",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 9007199254740991
|
||||
}
|
||||
},
|
||||
"required": ["total"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"sessionID": {
|
||||
"type": "string",
|
||||
"pattern": "^ses.*"
|
||||
}
|
||||
},
|
||||
"required": ["sessionID"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.sessionRestore({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/worktree": {
|
||||
"post": {
|
||||
"operationId": "worktree.create",
|
||||
@@ -12003,6 +12003,53 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"Workspace": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"branch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"directory": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"anyOf": [
|
||||
{},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"projectID": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["id", "type", "name", "branch", "directory", "extra", "projectID"]
|
||||
},
|
||||
"NotFoundError": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -12309,53 +12356,6 @@
|
||||
"$ref": "#/components/schemas/ToolListItem"
|
||||
}
|
||||
},
|
||||
"Workspace": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^wrk.*"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"branch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"directory": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"anyOf": [
|
||||
{},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"projectID": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["id", "type", "name", "branch", "directory", "extra", "projectID"]
|
||||
},
|
||||
"Worktree": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
Reference in New Issue
Block a user