summaryrefslogtreecommitdiffhomepage
path: root/packages/sdk
diff options
context:
space:
mode:
authorJames Long <[email protected]>2026-04-15 10:18:48 -0400
committerGitHub <[email protected]>2026-04-15 10:18:48 -0400
commitaf20191d1cd60a7f4a421ad81eca5053f7deace1 (patch)
tree4faa83e938c61311f67a189220d427b9f0ed3017 /packages/sdk
parent47af00b2452ef7374cdda8769910799938d1303c (diff)
downloadopencode-af20191d1cd60a7f4a421ad81eca5053f7deace1.tar.gz
opencode-af20191d1cd60a7f4a421ad81eca5053f7deace1.zip
feat(core): sync routes, refactor proxy, session restore, and more syncing (#22518)
Diffstat (limited to 'packages/sdk')
-rw-r--r--packages/sdk/js/src/v2/gen/sdk.gen.ts157
-rw-r--r--packages/sdk/js/src/v2/gen/types.gen.ts127
-rw-r--r--packages/sdk/openapi.json320
3 files changed, 604 insertions, 0 deletions
diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts
index b5fc976bb..d7bf43f50 100644
--- a/packages/sdk/js/src/v2/gen/sdk.gen.ts
+++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts
@@ -35,6 +35,8 @@ import type {
ExperimentalWorkspaceListResponses,
ExperimentalWorkspaceRemoveErrors,
ExperimentalWorkspaceRemoveResponses,
+ ExperimentalWorkspaceSessionRestoreErrors,
+ ExperimentalWorkspaceSessionRestoreResponses,
ExperimentalWorkspaceStatusResponses,
FileListResponses,
FilePartInput,
@@ -157,6 +159,10 @@ import type {
SessionUpdateErrors,
SessionUpdateResponses,
SubtaskPartInput,
+ SyncHistoryListErrors,
+ SyncHistoryListResponses,
+ SyncReplayErrors,
+ SyncReplayResponses,
TextPartInput,
ToolIdsErrors,
ToolIdsResponses,
@@ -1243,6 +1249,49 @@ export class Workspace extends HeyApiClient {
})
}
+ /**
+ * 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 }))
@@ -2961,6 +3010,109 @@ export class Provider extends HeyApiClient {
}
}
+export class History extends HeyApiClient {
+ /**
+ * List sync events
+ *
+ * List sync events for all aggregates. Keys are aggregate IDs the client already knows about, values are the last known sequence ID. Events with seq > value are returned for those aggregates. Aggregates not listed in the input get their full history.
+ */
+ public list<ThrowOnError extends boolean = false>(
+ parameters?: {
+ directory?: string
+ workspace?: string
+ body?: {
+ [key: string]: number
+ }
+ },
+ options?: Options<never, ThrowOnError>,
+ ) {
+ const params = buildClientParams(
+ [parameters],
+ [
+ {
+ args: [
+ { in: "query", key: "directory" },
+ { in: "query", key: "workspace" },
+ { key: "body", map: "body" },
+ ],
+ },
+ ],
+ )
+ return (options?.client ?? this.client).get<SyncHistoryListResponses, SyncHistoryListErrors, ThrowOnError>({
+ url: "/sync/history",
+ ...options,
+ ...params,
+ headers: {
+ "Content-Type": "application/json",
+ ...options?.headers,
+ ...params.headers,
+ },
+ })
+ }
+}
+
+export class Sync extends HeyApiClient {
+ /**
+ * Replay sync events
+ *
+ * Validate and replay a complete sync event history.
+ */
+ public replay<ThrowOnError extends boolean = false>(
+ parameters?: {
+ query_directory?: string
+ workspace?: string
+ body_directory?: string
+ events?: Array<{
+ id: string
+ aggregateID: string
+ seq: number
+ type: string
+ data: {
+ [key: string]: unknown
+ }
+ }>
+ },
+ options?: Options<never, ThrowOnError>,
+ ) {
+ const params = buildClientParams(
+ [parameters],
+ [
+ {
+ args: [
+ {
+ in: "query",
+ key: "query_directory",
+ map: "directory",
+ },
+ { in: "query", key: "workspace" },
+ {
+ in: "body",
+ key: "body_directory",
+ map: "directory",
+ },
+ { in: "body", key: "events" },
+ ],
+ },
+ ],
+ )
+ return (options?.client ?? this.client).post<SyncReplayResponses, SyncReplayErrors, ThrowOnError>({
+ url: "/sync/replay",
+ ...options,
+ ...params,
+ headers: {
+ "Content-Type": "application/json",
+ ...options?.headers,
+ ...params.headers,
+ },
+ })
+ }
+
+ private _history?: History
+ get history(): History {
+ return (this._history ??= new History({ client: this.client }))
+ }
+}
+
export class Find extends HeyApiClient {
/**
* Find text
@@ -4217,6 +4369,11 @@ export class OpencodeClient extends HeyApiClient {
return (this._provider ??= new Provider({ client: this.client }))
}
+ private _sync?: Sync
+ get sync(): Sync {
+ return (this._sync ??= new Sync({ client: this.client }))
+ }
+
private _find?: Find
get find(): Find {
return (this._find ??= new Find({ client: this.client }))
diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts
index 8f4c16c5b..24c1d53bf 100644
--- a/packages/sdk/js/src/v2/gen/types.gen.ts
+++ b/packages/sdk/js/src/v2/gen/types.gen.ts
@@ -520,6 +520,16 @@ export type EventWorkspaceFailed = {
}
}
+export type EventWorkspaceRestore = {
+ type: "workspace.restore"
+ properties: {
+ workspaceID: string
+ sessionID: string
+ total: number
+ step: number
+ }
+}
+
export type EventWorkspaceStatus = {
type: "workspace.status"
properties: {
@@ -1137,6 +1147,7 @@ export type GlobalEvent = {
| EventPtyDeleted
| EventWorkspaceReady
| EventWorkspaceFailed
+ | EventWorkspaceRestore
| EventWorkspaceStatus
| EventMessageUpdated
| EventMessageRemoved
@@ -2049,6 +2060,7 @@ export type Event =
| EventPtyDeleted
| EventWorkspaceReady
| EventWorkspaceFailed
+ | EventWorkspaceRestore
| EventWorkspaceStatus
| EventMessageUpdated
| EventMessageRemoved
@@ -3006,6 +3018,42 @@ export type ExperimentalWorkspaceRemoveResponses = {
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
@@ -4456,6 +4504,85 @@ export type ProviderOauthCallbackResponses = {
export type ProviderOauthCallbackResponse = ProviderOauthCallbackResponses[keyof ProviderOauthCallbackResponses]
+export type SyncReplayData = {
+ body?: {
+ directory: string
+ events: Array<{
+ id: string
+ aggregateID: string
+ seq: number
+ type: string
+ data: {
+ [key: string]: unknown
+ }
+ }>
+ }
+ path?: never
+ query?: {
+ directory?: string
+ workspace?: string
+ }
+ url: "/sync/replay"
+}
+
+export type SyncReplayErrors = {
+ /**
+ * Bad request
+ */
+ 400: BadRequestError
+}
+
+export type SyncReplayError = SyncReplayErrors[keyof SyncReplayErrors]
+
+export type SyncReplayResponses = {
+ /**
+ * Replayed sync events
+ */
+ 200: {
+ sessionID: string
+ }
+}
+
+export type SyncReplayResponse = SyncReplayResponses[keyof SyncReplayResponses]
+
+export type SyncHistoryListData = {
+ body?: {
+ [key: string]: number
+ }
+ path?: never
+ query?: {
+ directory?: string
+ workspace?: string
+ }
+ url: "/sync/history"
+}
+
+export type SyncHistoryListErrors = {
+ /**
+ * Bad request
+ */
+ 400: BadRequestError
+}
+
+export type SyncHistoryListError = SyncHistoryListErrors[keyof SyncHistoryListErrors]
+
+export type SyncHistoryListResponses = {
+ /**
+ * Sync events
+ */
+ 200: Array<{
+ id: string
+ aggregate_id: string
+ seq: number
+ type: string
+ data: {
+ [key: string]: unknown
+ }
+ }>
+}
+
+export type SyncHistoryListResponse = SyncHistoryListResponses[keyof SyncHistoryListResponses]
+
export type FindTextData = {
body?: never
path?: never
diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json
index 6000e6604..ee3538d55 100644
--- a/packages/sdk/openapi.json
+++ b/packages/sdk/openapi.json
@@ -1805,6 +1805,90 @@
]
}
},
+ "/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",
@@ -5143,6 +5227,202 @@
]
}
},
+ "/sync/replay": {
+ "post": {
+ "operationId": "sync.replay",
+ "parameters": [
+ {
+ "in": "query",
+ "name": "directory",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "in": "query",
+ "name": "workspace",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "summary": "Replay sync events",
+ "description": "Validate and replay a complete sync event history.",
+ "responses": {
+ "200": {
+ "description": "Replayed sync events",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "sessionID": {
+ "type": "string"
+ }
+ },
+ "required": ["sessionID"]
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BadRequestError"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "directory": {
+ "type": "string"
+ },
+ "events": {
+ "minItems": 1,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "aggregateID": {
+ "type": "string"
+ },
+ "seq": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 9007199254740991
+ },
+ "type": {
+ "type": "string"
+ },
+ "data": {
+ "type": "object",
+ "propertyNames": {
+ "type": "string"
+ },
+ "additionalProperties": {}
+ }
+ },
+ "required": ["id", "aggregateID", "seq", "type", "data"]
+ }
+ }
+ },
+ "required": ["directory", "events"]
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "js",
+ "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.sync.replay({\n ...\n})"
+ }
+ ]
+ }
+ },
+ "/sync/history": {
+ "get": {
+ "operationId": "sync.history.list",
+ "parameters": [
+ {
+ "in": "query",
+ "name": "directory",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "in": "query",
+ "name": "workspace",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "summary": "List sync events",
+ "description": "List sync events for all aggregates. Keys are aggregate IDs the client already knows about, values are the last known sequence ID. Events with seq > value are returned for those aggregates. Aggregates not listed in the input get their full history.",
+ "responses": {
+ "200": {
+ "description": "Sync events",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "aggregate_id": {
+ "type": "string"
+ },
+ "seq": {
+ "type": "number"
+ },
+ "type": {
+ "type": "string"
+ },
+ "data": {
+ "type": "object",
+ "propertyNames": {
+ "type": "string"
+ },
+ "additionalProperties": {}
+ }
+ },
+ "required": ["id", "aggregate_id", "seq", "type", "data"]
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BadRequestError"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "propertyNames": {
+ "type": "string"
+ },
+ "additionalProperties": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 9007199254740991
+ }
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "js",
+ "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.sync.history.list({\n ...\n})"
+ }
+ ]
+ }
+ },
"/find": {
"get": {
"operationId": "find.text",
@@ -8514,6 +8794,40 @@
},
"required": ["type", "properties"]
},
+ "Event.workspace.restore": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "const": "workspace.restore"
+ },
+ "properties": {
+ "type": "object",
+ "properties": {
+ "workspaceID": {
+ "type": "string",
+ "pattern": "^wrk.*"
+ },
+ "sessionID": {
+ "type": "string",
+ "pattern": "^ses.*"
+ },
+ "total": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 9007199254740991
+ },
+ "step": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 9007199254740991
+ }
+ },
+ "required": ["workspaceID", "sessionID", "total", "step"]
+ }
+ },
+ "required": ["type", "properties"]
+ },
"Event.workspace.status": {
"type": "object",
"properties": {
@@ -10524,6 +10838,9 @@
"$ref": "#/components/schemas/Event.workspace.failed"
},
{
+ "$ref": "#/components/schemas/Event.workspace.restore"
+ },
+ {
"$ref": "#/components/schemas/Event.workspace.status"
},
{
@@ -12781,6 +13098,9 @@
"$ref": "#/components/schemas/Event.workspace.failed"
},
{
+ "$ref": "#/components/schemas/Event.workspace.restore"
+ },
+ {
"$ref": "#/components/schemas/Event.workspace.status"
},
{