mirror of
https://github.com/anomalyco/opencode.git
synced 2026-06-01 22:10:06 +02:00
add endpoints
This commit is contained in:
@@ -12,6 +12,7 @@ import { InstanceApi } from "./groups/instance"
|
||||
import { McpApi } from "./groups/mcp"
|
||||
import { PermissionApi } from "./groups/permission"
|
||||
import { ProjectApi } from "./groups/project"
|
||||
import { ProjectCopyApi } from "./groups/project-copy"
|
||||
import { ProviderApi } from "./groups/provider"
|
||||
import { PtyApi, PtyConnectApi } from "./groups/pty"
|
||||
import { QuestionApi } from "./groups/question"
|
||||
@@ -52,6 +53,7 @@ export const InstanceHttpApi = HttpApi.make("opencode-instance")
|
||||
.addHttpApi(InstanceApi)
|
||||
.addHttpApi(McpApi)
|
||||
.addHttpApi(ProjectApi)
|
||||
.addHttpApi(ProjectCopyApi)
|
||||
.addHttpApi(PtyApi)
|
||||
.addHttpApi(QuestionApi)
|
||||
.addHttpApi(PermissionApi)
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import { ProjectCopy } from "@opencode-ai/core/project/copy"
|
||||
import { ProjectV2 } from "@opencode-ai/core/project"
|
||||
import { Schema } from "effect"
|
||||
import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/unstable/httpapi"
|
||||
import { Authorization } from "../middleware/authorization"
|
||||
import { InstanceContextMiddleware } from "../middleware/instance-context"
|
||||
import { WorkspaceRoutingMiddleware, WorkspaceRoutingQuery } from "../middleware/workspace-routing"
|
||||
import { described } from "./metadata"
|
||||
|
||||
const root = "/project/:projectID/copy"
|
||||
|
||||
export const CreatePayload = Schema.Struct({
|
||||
strategy: ProjectCopy.StrategyID,
|
||||
path: ProjectCopy.CreateInput.fields.path,
|
||||
})
|
||||
export const RemovePayload = Schema.Struct({
|
||||
strategy: ProjectCopy.StrategyID,
|
||||
path: ProjectCopy.RemoveInput.fields.path,
|
||||
})
|
||||
export const RefreshPayload = Schema.Struct({
|
||||
strategy: Schema.optional(ProjectCopy.StrategyID),
|
||||
})
|
||||
|
||||
export const ProjectCopyApi = HttpApi.make("projectCopy")
|
||||
.add(
|
||||
HttpApiGroup.make("projectCopy")
|
||||
.add(
|
||||
HttpApiEndpoint.get("strategies", `${root}/strategy`, {
|
||||
params: { projectID: ProjectV2.ID },
|
||||
query: WorkspaceRoutingQuery,
|
||||
success: described(Schema.Array(ProjectCopy.StrategyInfo), "Project copy strategies"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "projectCopy.strategies",
|
||||
summary: "List project copy strategies",
|
||||
description: "List mechanisms available for managing local copies of a project.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.post("create", root, {
|
||||
params: { projectID: ProjectV2.ID },
|
||||
query: WorkspaceRoutingQuery,
|
||||
payload: CreatePayload,
|
||||
success: described(ProjectCopy.Copy, "Project copy created"),
|
||||
error: HttpApiError.BadRequest,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "projectCopy.create",
|
||||
summary: "Create project copy",
|
||||
description: "Create a local physical copy of a project using the selected strategy.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.delete("remove", root, {
|
||||
params: { projectID: ProjectV2.ID },
|
||||
query: WorkspaceRoutingQuery,
|
||||
payload: RemovePayload,
|
||||
success: described(HttpApiSchema.NoContent, "Project copy removed"),
|
||||
error: HttpApiError.BadRequest,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "projectCopy.remove",
|
||||
summary: "Remove project copy",
|
||||
description: "Remove a local physical copy of a project using the selected strategy.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.post("refresh", `${root}/refresh`, {
|
||||
params: { projectID: ProjectV2.ID },
|
||||
query: WorkspaceRoutingQuery,
|
||||
payload: RefreshPayload,
|
||||
success: described(HttpApiSchema.NoContent, "Project copies refreshed"),
|
||||
error: HttpApiError.BadRequest,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "projectCopy.refresh",
|
||||
summary: "Refresh project copies",
|
||||
description: "Discover local project copies using one or all configured strategies.",
|
||||
}),
|
||||
),
|
||||
)
|
||||
.annotateMerge(OpenApi.annotations({ title: "projectCopy", description: "Project copy management routes." }))
|
||||
.middleware(InstanceContextMiddleware)
|
||||
.middleware(WorkspaceRoutingMiddleware)
|
||||
.middleware(Authorization),
|
||||
)
|
||||
@@ -62,6 +62,17 @@ export const ProjectApi = HttpApi.make("project")
|
||||
description: "Update project properties such as name, icon, and commands.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("paths", `${root}/:projectID/paths`, {
|
||||
params: { projectID: ProjectV2.ID },
|
||||
query: WorkspaceRoutingQuery,
|
||||
success: described(ProjectV2.Paths, "Project paths"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "project.paths",
|
||||
summary: "List project paths",
|
||||
description: "List known local absolute paths for a project.",
|
||||
}),
|
||||
),
|
||||
)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { ProjectCopy } from "@opencode-ai/core/project/copy"
|
||||
import { ProjectV2 } from "@opencode-ai/core/project"
|
||||
import { Effect } from "effect"
|
||||
import { HttpApiBuilder, HttpApiError } from "effect/unstable/httpapi"
|
||||
import { InstanceHttpApi } from "../api"
|
||||
import { CreatePayload, RefreshPayload, RemovePayload } from "../groups/project-copy"
|
||||
|
||||
function badRequest<A, R>(effect: Effect.Effect<A, ProjectCopy.Error, R>) {
|
||||
return effect.pipe(Effect.mapError(() => new HttpApiError.BadRequest({})))
|
||||
}
|
||||
|
||||
export const projectCopyHandlers = HttpApiBuilder.group(InstanceHttpApi, "projectCopy", (handlers) =>
|
||||
Effect.gen(function* () {
|
||||
const service = yield* ProjectCopy.Service
|
||||
|
||||
const strategies = Effect.fn("ProjectCopyHttpApi.strategies")((ctx: { params: { projectID: ProjectV2.ID } }) =>
|
||||
service.strategies({ projectID: ctx.params.projectID }),
|
||||
)
|
||||
|
||||
const create = Effect.fn("ProjectCopyHttpApi.create")(function* (ctx: {
|
||||
params: { projectID: ProjectV2.ID }
|
||||
payload: typeof CreatePayload.Type
|
||||
}) {
|
||||
return yield* badRequest(service.create({ ...ctx.payload, projectID: ctx.params.projectID }))
|
||||
})
|
||||
|
||||
const remove = Effect.fn("ProjectCopyHttpApi.remove")(function* (ctx: {
|
||||
params: { projectID: ProjectV2.ID }
|
||||
payload: typeof RemovePayload.Type
|
||||
}) {
|
||||
yield* badRequest(service.remove({ ...ctx.payload, projectID: ctx.params.projectID }))
|
||||
})
|
||||
|
||||
const refresh = Effect.fn("ProjectCopyHttpApi.refresh")(function* (ctx: {
|
||||
params: { projectID: ProjectV2.ID }
|
||||
payload: typeof RefreshPayload.Type
|
||||
}) {
|
||||
yield* badRequest(service.refresh({ ...ctx.payload, projectID: ctx.params.projectID }))
|
||||
})
|
||||
|
||||
return handlers
|
||||
.handle("strategies", strategies)
|
||||
.handle("create", create)
|
||||
.handle("remove", remove)
|
||||
.handle("refresh", refresh)
|
||||
}),
|
||||
)
|
||||
@@ -10,6 +10,7 @@ import { markInstanceForReload } from "../lifecycle"
|
||||
export const projectHandlers = HttpApiBuilder.group(InstanceHttpApi, "project", (handlers) =>
|
||||
Effect.gen(function* () {
|
||||
const svc = yield* Project.Service
|
||||
const project = yield* ProjectV2.Service
|
||||
|
||||
const list = Effect.fn("ProjectHttpApi.list")(function* () {
|
||||
return yield* svc.list()
|
||||
@@ -48,6 +49,15 @@ export const projectHandlers = HttpApiBuilder.group(InstanceHttpApi, "project",
|
||||
)
|
||||
})
|
||||
|
||||
return handlers.handle("list", list).handle("current", current).handle("initGit", initGit).handle("update", update)
|
||||
const paths = Effect.fn("ProjectHttpApi.paths")((ctx: { params: { projectID: ProjectV2.ID } }) =>
|
||||
project.paths({ projectID: ctx.params.projectID }),
|
||||
)
|
||||
|
||||
return handlers
|
||||
.handle("list", list)
|
||||
.handle("current", current)
|
||||
.handle("initGit", initGit)
|
||||
.handle("update", update)
|
||||
.handle("paths", paths)
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -28,6 +28,8 @@ import { Installation } from "@/installation"
|
||||
import { InstanceLayer } from "@/project/instance-layer"
|
||||
import { Plugin } from "@/plugin"
|
||||
import { Project } from "@/project/project"
|
||||
import { ProjectV2 } from "@opencode-ai/core/project"
|
||||
import { ProjectCopy } from "@opencode-ai/core/project/copy"
|
||||
import { ProviderAuth } from "@/provider/auth"
|
||||
import { ModelsDev } from "@opencode-ai/core/models-dev"
|
||||
import { Provider } from "@/provider/provider"
|
||||
@@ -76,6 +78,7 @@ import { instanceHandlers } from "./handlers/instance"
|
||||
import { mcpHandlers } from "./handlers/mcp"
|
||||
import { permissionHandlers } from "./handlers/permission"
|
||||
import { projectHandlers } from "./handlers/project"
|
||||
import { projectCopyHandlers } from "./handlers/project-copy"
|
||||
import { providerHandlers } from "./handlers/provider"
|
||||
import { ptyConnectHandlers, ptyHandlers } from "./handlers/pty"
|
||||
import { questionHandlers } from "./handlers/question"
|
||||
@@ -137,6 +140,7 @@ const instanceApiRoutes = HttpApiBuilder.layer(InstanceHttpApi).pipe(
|
||||
instanceHandlers,
|
||||
mcpHandlers,
|
||||
projectHandlers,
|
||||
projectCopyHandlers,
|
||||
ptyHandlers,
|
||||
questionHandlers,
|
||||
permissionHandlers,
|
||||
@@ -208,6 +212,8 @@ export function createRoutes(
|
||||
Permission.defaultLayer,
|
||||
Plugin.defaultLayer,
|
||||
Project.defaultLayer,
|
||||
ProjectV2.defaultLayer,
|
||||
ProjectCopy.defaultLayer,
|
||||
ProviderAuth.defaultLayer,
|
||||
Provider.defaultLayer,
|
||||
Pty.defaultLayer,
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
import { afterEach, describe, expect } from "bun:test"
|
||||
import { $ } from "bun"
|
||||
import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { HttpClientResponse } from "effect/unstable/http"
|
||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { Snapshot } from "@/snapshot"
|
||||
import { InstanceBootstrap } from "@/project/bootstrap-service"
|
||||
import { InstanceStore } from "@/project/instance-store"
|
||||
import { resetDatabase } from "../fixture/db"
|
||||
import { disposeAllInstances, TestInstance } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import { httpApiLayer, requestInDirectory } from "./httpapi-layer"
|
||||
|
||||
afterEach(async () => {
|
||||
await disposeAllInstances()
|
||||
await resetDatabase()
|
||||
})
|
||||
|
||||
const noopBootstrap = Layer.succeed(InstanceBootstrap.Service, InstanceBootstrap.Service.of({ run: Effect.void }))
|
||||
const testInstanceStore = InstanceStore.defaultLayer.pipe(Layer.provide(noopBootstrap))
|
||||
const it = testEffect(Layer.mergeAll(AppFileSystem.defaultLayer, Snapshot.defaultLayer, testInstanceStore, httpApiLayer))
|
||||
|
||||
function request(directory: string, url: string, init: RequestInit = {}) {
|
||||
return requestInDirectory(url, directory, init)
|
||||
}
|
||||
|
||||
function json<T>(response: HttpClientResponse.HttpClientResponse) {
|
||||
return response.json.pipe(Effect.map((value) => value as T))
|
||||
}
|
||||
|
||||
describe("project paths and copies endpoints", () => {
|
||||
it.instance(
|
||||
"lists paths and manages git worktree copies",
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const test = yield* TestInstance
|
||||
const current = yield* request(test.directory, "/project/current")
|
||||
const base = `/project/${(yield* json<{ id: string }>(current)).id}`
|
||||
const createdPath = path.join(test.directory, "..", path.basename(test.directory) + "-http-copy")
|
||||
yield* Effect.addFinalizer(() =>
|
||||
Effect.promise(() => fs.rm(createdPath, { recursive: true, force: true })).pipe(Effect.ignore),
|
||||
)
|
||||
|
||||
const strategies = yield* request(test.directory, `${base}/copy/strategy`)
|
||||
expect(strategies.status).toBe(200)
|
||||
expect(yield* json(strategies)).toEqual([{ id: "git_worktree", name: "Git worktree" }])
|
||||
|
||||
const initial = yield* request(test.directory, `${base}/paths`)
|
||||
expect(initial.status).toBe(200)
|
||||
expect(yield* json<Array<{ path: string; primary: boolean }>>(initial)).toEqual([
|
||||
{ path: test.directory, primary: true },
|
||||
])
|
||||
|
||||
const create = yield* request(test.directory, `${base}/copy`, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({ strategy: "git_worktree", path: createdPath }),
|
||||
})
|
||||
expect(create.status).toBe(200)
|
||||
const created = yield* json<{ path: string }>(create)
|
||||
expect(created.path).toContain("-http-copy")
|
||||
|
||||
const listed = yield* request(test.directory, `${base}/paths`)
|
||||
expect((yield* json<Array<{ path: string; primary: boolean }>>(listed)).map((item) => item.path)).toContain(
|
||||
created.path,
|
||||
)
|
||||
|
||||
const remove = yield* request(test.directory, `${base}/copy`, {
|
||||
method: "DELETE",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({ strategy: "git_worktree", path: created.path }),
|
||||
})
|
||||
expect(remove.status).toBe(204)
|
||||
|
||||
const externalPath = path.join(test.directory, "..", path.basename(test.directory) + "-http-refresh")
|
||||
yield* Effect.addFinalizer(() =>
|
||||
Effect.promise(() => fs.rm(externalPath, { recursive: true, force: true })).pipe(Effect.ignore),
|
||||
)
|
||||
yield* Effect.promise(() => $`git worktree add --detach ${externalPath} HEAD`.cwd(test.directory).quiet())
|
||||
const refresh = yield* request(test.directory, `${base}/copy/refresh`, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({ strategy: "git_worktree" }),
|
||||
})
|
||||
expect(refresh.status).toBe(204)
|
||||
const refreshed = yield* request(test.directory, `${base}/paths`)
|
||||
expect((yield* json<Array<{ path: string; primary: boolean }>>(refreshed)).length).toBe(2)
|
||||
}),
|
||||
{ git: true },
|
||||
)
|
||||
})
|
||||
@@ -117,12 +117,22 @@ import type {
|
||||
PermissionRespondErrors,
|
||||
PermissionRespondResponses,
|
||||
PermissionRuleset,
|
||||
ProjectCopyCreateErrors,
|
||||
ProjectCopyCreateResponses,
|
||||
ProjectCopyRefreshErrors,
|
||||
ProjectCopyRefreshResponses,
|
||||
ProjectCopyRemoveErrors,
|
||||
ProjectCopyRemoveResponses,
|
||||
ProjectCopyStrategiesErrors,
|
||||
ProjectCopyStrategiesResponses,
|
||||
ProjectCurrentErrors,
|
||||
ProjectCurrentResponses,
|
||||
ProjectInitGitErrors,
|
||||
ProjectInitGitResponses,
|
||||
ProjectListErrors,
|
||||
ProjectListResponses,
|
||||
ProjectPathsErrors,
|
||||
ProjectPathsResponses,
|
||||
ProjectUpdateErrors,
|
||||
ProjectUpdateResponses,
|
||||
Prompt,
|
||||
@@ -2373,6 +2383,197 @@ export class Project extends HeyApiClient {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* List project paths
|
||||
*
|
||||
* List known local absolute paths for a project.
|
||||
*/
|
||||
public paths<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
projectID: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "projectID" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ProjectPathsResponses, ProjectPathsErrors, ThrowOnError>({
|
||||
url: "/project/{projectID}/paths",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class ProjectCopy extends HeyApiClient {
|
||||
/**
|
||||
* List project copy strategies
|
||||
*
|
||||
* List mechanisms available for managing local copies of a project.
|
||||
*/
|
||||
public strategies<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
projectID: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "projectID" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<
|
||||
ProjectCopyStrategiesResponses,
|
||||
ProjectCopyStrategiesErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
url: "/project/{projectID}/copy/strategy",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove project copy
|
||||
*
|
||||
* Remove a local physical copy of a project using the selected strategy.
|
||||
*/
|
||||
public remove<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
projectID: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
strategy?: "git_worktree"
|
||||
path?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "projectID" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "strategy" },
|
||||
{ in: "body", key: "path" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).delete<ProjectCopyRemoveResponses, ProjectCopyRemoveErrors, ThrowOnError>({
|
||||
url: "/project/{projectID}/copy",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Create project copy
|
||||
*
|
||||
* Create a local physical copy of a project using the selected strategy.
|
||||
*/
|
||||
public create<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
projectID: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
strategy?: "git_worktree"
|
||||
path?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "projectID" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "strategy" },
|
||||
{ in: "body", key: "path" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<ProjectCopyCreateResponses, ProjectCopyCreateErrors, ThrowOnError>({
|
||||
url: "/project/{projectID}/copy",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh project copies
|
||||
*
|
||||
* Discover local project copies using one or all configured strategies.
|
||||
*/
|
||||
public refresh<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
projectID: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
strategy?: "git_worktree"
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "projectID" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "strategy" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<ProjectCopyRefreshResponses, ProjectCopyRefreshErrors, ThrowOnError>({
|
||||
url: "/project/{projectID}/copy/refresh",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Pty extends HeyApiClient {
|
||||
@@ -5119,6 +5320,11 @@ export class OpencodeClient extends HeyApiClient {
|
||||
return (this._project ??= new Project({ client: this.client }))
|
||||
}
|
||||
|
||||
private _projectCopy?: ProjectCopy
|
||||
get projectCopy(): ProjectCopy {
|
||||
return (this._projectCopy ??= new ProjectCopy({ client: this.client }))
|
||||
}
|
||||
|
||||
private _pty?: Pty
|
||||
get pty(): Pty {
|
||||
return (this._pty ??= new Pty({ client: this.client }))
|
||||
|
||||
@@ -76,6 +76,7 @@ export type Event =
|
||||
| EventPtyDeleted
|
||||
| EventInstallationUpdated
|
||||
| EventInstallationUpdateAvailable
|
||||
| EventProjectPathsUpdated
|
||||
| EventServerConnected
|
||||
| EventGlobalDisposed
|
||||
| EventAccountAdded
|
||||
@@ -1401,6 +1402,13 @@ export type GlobalEvent = {
|
||||
version: string
|
||||
}
|
||||
}
|
||||
| {
|
||||
id: string
|
||||
type: "project.paths.updated"
|
||||
properties: {
|
||||
projectID: string
|
||||
}
|
||||
}
|
||||
| {
|
||||
id: string
|
||||
type: "server.connected"
|
||||
@@ -3335,6 +3343,20 @@ export type ConfigV2ExperimentalPolicy = {
|
||||
resource: string
|
||||
}
|
||||
|
||||
export type ProjectPaths = Array<{
|
||||
path: string
|
||||
primary: boolean
|
||||
}>
|
||||
|
||||
export type ProjectCopyStrategyInfo = {
|
||||
id: "git_worktree"
|
||||
name: string
|
||||
}
|
||||
|
||||
export type ProjectCopyCopy = {
|
||||
path: string
|
||||
}
|
||||
|
||||
export type SessionInfo = {
|
||||
id: string
|
||||
parentID?: string
|
||||
@@ -4457,6 +4479,14 @@ export type EventInstallationUpdateAvailable = {
|
||||
}
|
||||
}
|
||||
|
||||
export type EventProjectPathsUpdated = {
|
||||
id: string
|
||||
type: "project.paths.updated"
|
||||
properties: {
|
||||
projectID: string
|
||||
}
|
||||
}
|
||||
|
||||
export type EventServerConnected = {
|
||||
id: string
|
||||
type: "server.connected"
|
||||
@@ -6153,6 +6183,164 @@ export type ProjectUpdateResponses = {
|
||||
|
||||
export type ProjectUpdateResponse = ProjectUpdateResponses[keyof ProjectUpdateResponses]
|
||||
|
||||
export type ProjectPathsData = {
|
||||
body?: never
|
||||
path: {
|
||||
projectID: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/project/{projectID}/paths"
|
||||
}
|
||||
|
||||
export type ProjectPathsErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type ProjectPathsError = ProjectPathsErrors[keyof ProjectPathsErrors]
|
||||
|
||||
export type ProjectPathsResponses = {
|
||||
/**
|
||||
* Project paths
|
||||
*/
|
||||
200: ProjectPaths
|
||||
}
|
||||
|
||||
export type ProjectPathsResponse = ProjectPathsResponses[keyof ProjectPathsResponses]
|
||||
|
||||
export type ProjectCopyStrategiesData = {
|
||||
body?: never
|
||||
path: {
|
||||
projectID: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/project/{projectID}/copy/strategy"
|
||||
}
|
||||
|
||||
export type ProjectCopyStrategiesErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type ProjectCopyStrategiesError = ProjectCopyStrategiesErrors[keyof ProjectCopyStrategiesErrors]
|
||||
|
||||
export type ProjectCopyStrategiesResponses = {
|
||||
/**
|
||||
* Project copy strategies
|
||||
*/
|
||||
200: Array<ProjectCopyStrategyInfo>
|
||||
}
|
||||
|
||||
export type ProjectCopyStrategiesResponse = ProjectCopyStrategiesResponses[keyof ProjectCopyStrategiesResponses]
|
||||
|
||||
export type ProjectCopyRemoveData = {
|
||||
body?: {
|
||||
strategy: "git_worktree"
|
||||
path: string
|
||||
}
|
||||
path: {
|
||||
projectID: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/project/{projectID}/copy"
|
||||
}
|
||||
|
||||
export type ProjectCopyRemoveErrors = {
|
||||
/**
|
||||
* BadRequest | InvalidRequestError
|
||||
*/
|
||||
400: EffectHttpApiErrorBadRequest | InvalidRequestError
|
||||
}
|
||||
|
||||
export type ProjectCopyRemoveError = ProjectCopyRemoveErrors[keyof ProjectCopyRemoveErrors]
|
||||
|
||||
export type ProjectCopyRemoveResponses = {
|
||||
/**
|
||||
* Project copy removed
|
||||
*/
|
||||
204: void
|
||||
}
|
||||
|
||||
export type ProjectCopyRemoveResponse = ProjectCopyRemoveResponses[keyof ProjectCopyRemoveResponses]
|
||||
|
||||
export type ProjectCopyCreateData = {
|
||||
body?: {
|
||||
strategy: "git_worktree"
|
||||
path: string
|
||||
}
|
||||
path: {
|
||||
projectID: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/project/{projectID}/copy"
|
||||
}
|
||||
|
||||
export type ProjectCopyCreateErrors = {
|
||||
/**
|
||||
* BadRequest | InvalidRequestError
|
||||
*/
|
||||
400: EffectHttpApiErrorBadRequest | InvalidRequestError
|
||||
}
|
||||
|
||||
export type ProjectCopyCreateError = ProjectCopyCreateErrors[keyof ProjectCopyCreateErrors]
|
||||
|
||||
export type ProjectCopyCreateResponses = {
|
||||
/**
|
||||
* Project copy created
|
||||
*/
|
||||
200: ProjectCopyCopy
|
||||
}
|
||||
|
||||
export type ProjectCopyCreateResponse = ProjectCopyCreateResponses[keyof ProjectCopyCreateResponses]
|
||||
|
||||
export type ProjectCopyRefreshData = {
|
||||
body?: {
|
||||
strategy?: "git_worktree"
|
||||
}
|
||||
path: {
|
||||
projectID: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/project/{projectID}/copy/refresh"
|
||||
}
|
||||
|
||||
export type ProjectCopyRefreshErrors = {
|
||||
/**
|
||||
* BadRequest | InvalidRequestError
|
||||
*/
|
||||
400: EffectHttpApiErrorBadRequest | InvalidRequestError
|
||||
}
|
||||
|
||||
export type ProjectCopyRefreshError = ProjectCopyRefreshErrors[keyof ProjectCopyRefreshErrors]
|
||||
|
||||
export type ProjectCopyRefreshResponses = {
|
||||
/**
|
||||
* Project copies refreshed
|
||||
*/
|
||||
204: void
|
||||
}
|
||||
|
||||
export type ProjectCopyRefreshResponse = ProjectCopyRefreshResponses[keyof ProjectCopyRefreshResponses]
|
||||
|
||||
export type PtyShellsData = {
|
||||
body?: never
|
||||
path?: never
|
||||
|
||||
Reference in New Issue
Block a user