chore: generate

This commit is contained in:
opencode-agent[bot] 2026-06-14 10:48:03 +00:00
parent f2cf607376
commit 8cc2276dba
6 changed files with 1358 additions and 43 deletions

View File

@ -278,8 +278,7 @@ export const layer = Layer.effect(
const update = Effect.fn("Pty.update")(function* (id: PtyID, input: UpdateInput) {
const session = yield* requireSession(id)
if (input.title) session.info.title = input.title
if (input.size && session.info.status === "running")
session.process.resize(input.size.cols, input.size.rows)
if (input.size && session.info.status === "running") session.process.resize(input.size.cols, input.size.rows)
yield* events.publish(Event.Updated, { info: session.info })
return session.info
})

View File

@ -164,7 +164,10 @@ describe("v2 pty HttpApi", () => {
expect(yield* takeUntil("ping-v2")).toContain("ping-v2")
yield* write(new Socket.CloseEvent(1000, "done")).pipe(Effect.catch(() => Effect.void))
const removed = yield* HttpClientRequest.delete(`/api/pty/${info.id}`).pipe(directoryHeader(dir), HttpClient.execute)
const removed = yield* HttpClientRequest.delete(`/api/pty/${info.id}`).pipe(
directoryHeader(dir),
HttpClient.execute,
)
expect(removed.status).toBe(204)
}),
)

View File

@ -309,6 +309,20 @@ import type {
V2ProviderGetResponses,
V2ProviderListErrors,
V2ProviderListResponses,
V2PtyConnectErrors,
V2PtyConnectResponses,
V2PtyConnectTokenErrors,
V2PtyConnectTokenResponses,
V2PtyCreateErrors,
V2PtyCreateResponses,
V2PtyGetErrors,
V2PtyGetResponses,
V2PtyListErrors,
V2PtyListResponses,
V2PtyRemoveErrors,
V2PtyRemoveResponses,
V2PtyUpdateErrors,
V2PtyUpdateResponses,
V2QuestionRequestListErrors,
V2QuestionRequestListResponses,
V2ReferenceListErrors,
@ -6101,6 +6115,258 @@ export class Event2 extends HeyApiClient {
}
}
export class Pty2 extends HeyApiClient {
/**
* List PTY sessions
*
* List PTY sessions for a location, including exited sessions retained until removal.
*/
public list<ThrowOnError extends boolean = false>(
parameters?: {
location?: {
directory?: string
workspace?: string
}
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams([parameters], [{ args: [{ in: "query", key: "location" }] }])
return (options?.client ?? this.client).get<V2PtyListResponses, V2PtyListErrors, ThrowOnError>({
url: "/api/pty",
...options,
...params,
})
}
/**
* Create PTY session
*
* Create a pseudo-terminal session for a location.
*/
public create<ThrowOnError extends boolean = false>(
parameters?: {
location?: {
directory?: string
workspace?: string
}
command?: string
args?: Array<string>
cwd?: string
title?: string
env?: {
[key: string]: string
}
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "query", key: "location" },
{ in: "body", key: "command" },
{ in: "body", key: "args" },
{ in: "body", key: "cwd" },
{ in: "body", key: "title" },
{ in: "body", key: "env" },
],
},
],
)
return (options?.client ?? this.client).post<V2PtyCreateResponses, V2PtyCreateErrors, ThrowOnError>({
url: "/api/pty",
...options,
...params,
headers: {
"Content-Type": "application/json",
...options?.headers,
...params.headers,
},
})
}
/**
* Remove PTY session
*
* Terminate and remove one PTY session.
*/
public remove<ThrowOnError extends boolean = false>(
parameters: {
ptyID: string
location?: {
directory?: string
workspace?: string
}
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "ptyID" },
{ in: "query", key: "location" },
],
},
],
)
return (options?.client ?? this.client).delete<V2PtyRemoveResponses, V2PtyRemoveErrors, ThrowOnError>({
url: "/api/pty/{ptyID}",
...options,
...params,
})
}
/**
* Get PTY session
*
* Get one PTY session, including its exit code once exited.
*/
public get<ThrowOnError extends boolean = false>(
parameters: {
ptyID: string
location?: {
directory?: string
workspace?: string
}
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "ptyID" },
{ in: "query", key: "location" },
],
},
],
)
return (options?.client ?? this.client).get<V2PtyGetResponses, V2PtyGetErrors, ThrowOnError>({
url: "/api/pty/{ptyID}",
...options,
...params,
})
}
/**
* Update PTY session
*
* Update the title or viewport size of one PTY session.
*/
public update<ThrowOnError extends boolean = false>(
parameters: {
ptyID: string
location?: {
directory?: string
workspace?: string
}
title?: string
size?: {
rows: number
cols: number
}
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "ptyID" },
{ in: "query", key: "location" },
{ in: "body", key: "title" },
{ in: "body", key: "size" },
],
},
],
)
return (options?.client ?? this.client).put<V2PtyUpdateResponses, V2PtyUpdateErrors, ThrowOnError>({
url: "/api/pty/{ptyID}",
...options,
...params,
headers: {
"Content-Type": "application/json",
...options?.headers,
...params.headers,
},
})
}
/**
* Create PTY WebSocket token
*
* Create a short-lived single-use ticket for opening a PTY WebSocket connection.
*/
public connectToken<ThrowOnError extends boolean = false>(
parameters: {
ptyID: string
location?: {
directory?: string
workspace?: string
}
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "ptyID" },
{ in: "query", key: "location" },
],
},
],
)
return (options?.client ?? this.client).post<V2PtyConnectTokenResponses, V2PtyConnectTokenErrors, ThrowOnError>({
url: "/api/pty/{ptyID}/connect-token",
...options,
...params,
})
}
/**
* Connect to PTY session
*
* Establish a WebSocket connection streaming PTY output and accepting terminal input.
*/
public connect<ThrowOnError extends boolean = false>(
parameters: {
ptyID: string
"location[directory]"?: string
"location[workspace]"?: string
cursor?: string
ticket?: string
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "ptyID" },
{ in: "query", key: "location[directory]" },
{ in: "query", key: "location[workspace]" },
{ in: "query", key: "cursor" },
{ in: "query", key: "ticket" },
],
},
],
)
return (options?.client ?? this.client).get<V2PtyConnectResponses, V2PtyConnectErrors, ThrowOnError>({
url: "/api/pty/{ptyID}/connect",
...options,
...params,
})
}
}
export class Request2 extends HeyApiClient {
/**
* List pending question requests
@ -6342,6 +6608,11 @@ export class V2 extends HeyApiClient {
return (this._event ??= new Event2({ client: this.client }))
}
private _pty?: Pty2
get pty(): Pty2 {
return (this._pty ??= new Pty2({ client: this.client }))
}
private _question?: Question3
get question(): Question3 {
return (this._question ??= new Question3({ client: this.client }))

View File

@ -650,6 +650,7 @@ export type Pty = {
cwd: string
status: "running" | "exited"
pid: number
exitCode?: number
}
export type Todo = {
@ -2759,6 +2760,11 @@ export type ProviderNotFoundError = {
message: string
}
export type ForbiddenError = {
_tag: "ForbiddenError"
message: string
}
export type ProjectCopyError = {
name: "ProjectCopyError"
data: {
@ -10702,6 +10708,314 @@ export type V2EventSubscribeResponses = {
export type V2EventSubscribeResponse = V2EventSubscribeResponses[keyof V2EventSubscribeResponses]
export type V2PtyListData = {
body?: never
path?: never
query?: {
location?: {
directory?: string
workspace?: string
}
}
url: "/api/pty"
}
export type V2PtyListErrors = {
/**
* InvalidRequestError
*/
400: InvalidRequestError
/**
* UnauthorizedError
*/
401: UnauthorizedError
}
export type V2PtyListError = V2PtyListErrors[keyof V2PtyListErrors]
export type V2PtyListResponses = {
/**
* Success
*/
200: {
location: LocationInfo
data: Array<Pty>
}
}
export type V2PtyListResponse = V2PtyListResponses[keyof V2PtyListResponses]
export type V2PtyCreateData = {
body: {
command?: string
args?: Array<string>
cwd?: string
title?: string
env?: {
[key: string]: string
}
}
path?: never
query?: {
location?: {
directory?: string
workspace?: string
}
}
url: "/api/pty"
}
export type V2PtyCreateErrors = {
/**
* InvalidRequestError
*/
400: InvalidRequestError
/**
* UnauthorizedError
*/
401: UnauthorizedError
}
export type V2PtyCreateError = V2PtyCreateErrors[keyof V2PtyCreateErrors]
export type V2PtyCreateResponses = {
/**
* Success
*/
200: {
location: LocationInfo
data: Pty
}
}
export type V2PtyCreateResponse = V2PtyCreateResponses[keyof V2PtyCreateResponses]
export type V2PtyRemoveData = {
body?: never
path: {
ptyID: string
}
query?: {
location?: {
directory?: string
workspace?: string
}
}
url: "/api/pty/{ptyID}"
}
export type V2PtyRemoveErrors = {
/**
* InvalidRequestError
*/
400: InvalidRequestError
/**
* UnauthorizedError
*/
401: UnauthorizedError
/**
* PtyNotFoundError
*/
404: PtyNotFoundError
}
export type V2PtyRemoveError = V2PtyRemoveErrors[keyof V2PtyRemoveErrors]
export type V2PtyRemoveResponses = {
/**
* <No Content>
*/
204: void
}
export type V2PtyRemoveResponse = V2PtyRemoveResponses[keyof V2PtyRemoveResponses]
export type V2PtyGetData = {
body?: never
path: {
ptyID: string
}
query?: {
location?: {
directory?: string
workspace?: string
}
}
url: "/api/pty/{ptyID}"
}
export type V2PtyGetErrors = {
/**
* InvalidRequestError
*/
400: InvalidRequestError
/**
* UnauthorizedError
*/
401: UnauthorizedError
/**
* PtyNotFoundError
*/
404: PtyNotFoundError
}
export type V2PtyGetError = V2PtyGetErrors[keyof V2PtyGetErrors]
export type V2PtyGetResponses = {
/**
* Success
*/
200: {
location: LocationInfo
data: Pty
}
}
export type V2PtyGetResponse = V2PtyGetResponses[keyof V2PtyGetResponses]
export type V2PtyUpdateData = {
body: {
title?: string
size?: {
rows: number
cols: number
}
}
path: {
ptyID: string
}
query?: {
location?: {
directory?: string
workspace?: string
}
}
url: "/api/pty/{ptyID}"
}
export type V2PtyUpdateErrors = {
/**
* InvalidRequestError
*/
400: InvalidRequestError
/**
* UnauthorizedError
*/
401: UnauthorizedError
/**
* PtyNotFoundError
*/
404: PtyNotFoundError
}
export type V2PtyUpdateError = V2PtyUpdateErrors[keyof V2PtyUpdateErrors]
export type V2PtyUpdateResponses = {
/**
* Success
*/
200: {
location: LocationInfo
data: Pty
}
}
export type V2PtyUpdateResponse = V2PtyUpdateResponses[keyof V2PtyUpdateResponses]
export type V2PtyConnectTokenData = {
body?: never
path: {
ptyID: string
}
query?: {
location?: {
directory?: string
workspace?: string
}
}
url: "/api/pty/{ptyID}/connect-token"
}
export type V2PtyConnectTokenErrors = {
/**
* InvalidRequestError
*/
400: InvalidRequestError
/**
* UnauthorizedError
*/
401: UnauthorizedError
/**
* ForbiddenError
*/
403: ForbiddenError
/**
* PtyNotFoundError
*/
404: PtyNotFoundError
}
export type V2PtyConnectTokenError = V2PtyConnectTokenErrors[keyof V2PtyConnectTokenErrors]
export type V2PtyConnectTokenResponses = {
/**
* Success
*/
200: {
location: LocationInfo
data: {
ticket: string
expires_in: number
}
}
}
export type V2PtyConnectTokenResponse = V2PtyConnectTokenResponses[keyof V2PtyConnectTokenResponses]
export type V2PtyConnectData = {
body?: never
path: {
ptyID: string
}
query?: {
"location[directory]"?: string
"location[workspace]"?: string
cursor?: string
ticket?: string
}
url: "/api/pty/{ptyID}/connect"
}
export type V2PtyConnectErrors = {
/**
* InvalidRequestError
*/
400: InvalidRequestError
/**
* UnauthorizedError
*/
401: UnauthorizedError
/**
* ForbiddenError
*/
403: ForbiddenError
/**
* PtyNotFoundError
*/
404: PtyNotFoundError
}
export type V2PtyConnectError = V2PtyConnectErrors[keyof V2PtyConnectErrors]
export type V2PtyConnectResponses = {
/**
* Success
*/
200: boolean
}
export type V2PtyConnectResponse = V2PtyConnectResponses[keyof V2PtyConnectResponses]
export type V2QuestionRequestListData = {
body?: never
path?: never

View File

@ -12927,6 +12927,722 @@
]
}
},
"/api/pty": {
"get": {
"tags": ["pty"],
"operationId": "v2.pty.list",
"parameters": [
{
"name": "location",
"in": "query",
"schema": {
"type": "object",
"properties": {
"directory": {
"type": "string"
},
"workspace": {
"type": "string"
}
},
"additionalProperties": false
},
"required": false,
"style": "deepObject",
"explode": true
}
],
"security": [],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"location": {
"$ref": "#/components/schemas/LocationInfo"
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Pty"
}
}
},
"required": ["location", "data"],
"additionalProperties": false
}
}
}
},
"400": {
"description": "InvalidRequestError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvalidRequestError"
}
}
}
},
"401": {
"description": "UnauthorizedError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UnauthorizedError"
}
}
}
}
},
"description": "List PTY sessions for a location, including exited sessions retained until removal.",
"summary": "List PTY sessions",
"x-codeSamples": [
{
"lang": "js",
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.v2.pty.list({\n ...\n})"
}
]
},
"post": {
"tags": ["pty"],
"operationId": "v2.pty.create",
"parameters": [
{
"name": "location",
"in": "query",
"schema": {
"type": "object",
"properties": {
"directory": {
"type": "string"
},
"workspace": {
"type": "string"
}
},
"additionalProperties": false
},
"required": false,
"style": "deepObject",
"explode": true
}
],
"security": [],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"location": {
"$ref": "#/components/schemas/LocationInfo"
},
"data": {
"$ref": "#/components/schemas/Pty"
}
},
"required": ["location", "data"],
"additionalProperties": false
}
}
}
},
"400": {
"description": "InvalidRequestError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvalidRequestError"
}
}
}
},
"401": {
"description": "UnauthorizedError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UnauthorizedError"
}
}
}
}
},
"description": "Create a pseudo-terminal session for a location.",
"summary": "Create PTY session",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"command": {
"type": "string"
},
"args": {
"type": "array",
"items": {
"type": "string"
}
},
"cwd": {
"type": "string"
},
"title": {
"type": "string"
},
"env": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"additionalProperties": false
}
}
},
"required": true
},
"x-codeSamples": [
{
"lang": "js",
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.v2.pty.create({\n ...\n})"
}
]
}
},
"/api/pty/{ptyID}": {
"get": {
"tags": ["pty"],
"operationId": "v2.pty.get",
"parameters": [
{
"name": "ptyID",
"in": "path",
"schema": {
"type": "string",
"pattern": "^pty"
},
"required": true
},
{
"name": "location",
"in": "query",
"schema": {
"type": "object",
"properties": {
"directory": {
"type": "string"
},
"workspace": {
"type": "string"
}
},
"additionalProperties": false
},
"required": false,
"style": "deepObject",
"explode": true
}
],
"security": [],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"location": {
"$ref": "#/components/schemas/LocationInfo"
},
"data": {
"$ref": "#/components/schemas/Pty"
}
},
"required": ["location", "data"],
"additionalProperties": false
}
}
}
},
"400": {
"description": "InvalidRequestError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvalidRequestError"
}
}
}
},
"401": {
"description": "UnauthorizedError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UnauthorizedError"
}
}
}
},
"404": {
"description": "PtyNotFoundError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PtyNotFoundError"
}
}
}
}
},
"description": "Get one PTY session, including its exit code once exited.",
"summary": "Get PTY session",
"x-codeSamples": [
{
"lang": "js",
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.v2.pty.get({\n ...\n})"
}
]
},
"put": {
"tags": ["pty"],
"operationId": "v2.pty.update",
"parameters": [
{
"name": "ptyID",
"in": "path",
"schema": {
"type": "string",
"pattern": "^pty"
},
"required": true
},
{
"name": "location",
"in": "query",
"schema": {
"type": "object",
"properties": {
"directory": {
"type": "string"
},
"workspace": {
"type": "string"
}
},
"additionalProperties": false
},
"required": false,
"style": "deepObject",
"explode": true
}
],
"security": [],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"location": {
"$ref": "#/components/schemas/LocationInfo"
},
"data": {
"$ref": "#/components/schemas/Pty"
}
},
"required": ["location", "data"],
"additionalProperties": false
}
}
}
},
"400": {
"description": "InvalidRequestError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvalidRequestError"
}
}
}
},
"401": {
"description": "UnauthorizedError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UnauthorizedError"
}
}
}
},
"404": {
"description": "PtyNotFoundError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PtyNotFoundError"
}
}
}
}
},
"description": "Update the title or viewport size of one PTY session.",
"summary": "Update PTY session",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"size": {
"type": "object",
"properties": {
"rows": {
"type": "integer",
"exclusiveMinimum": 0
},
"cols": {
"type": "integer",
"exclusiveMinimum": 0
}
},
"required": ["rows", "cols"],
"additionalProperties": false
}
},
"additionalProperties": false
}
}
},
"required": true
},
"x-codeSamples": [
{
"lang": "js",
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.v2.pty.update({\n ...\n})"
}
]
},
"delete": {
"tags": ["pty"],
"operationId": "v2.pty.remove",
"parameters": [
{
"name": "ptyID",
"in": "path",
"schema": {
"type": "string",
"pattern": "^pty"
},
"required": true
},
{
"name": "location",
"in": "query",
"schema": {
"type": "object",
"properties": {
"directory": {
"type": "string"
},
"workspace": {
"type": "string"
}
},
"additionalProperties": false
},
"required": false,
"style": "deepObject",
"explode": true
}
],
"security": [],
"responses": {
"204": {
"description": "<No Content>"
},
"400": {
"description": "InvalidRequestError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvalidRequestError"
}
}
}
},
"401": {
"description": "UnauthorizedError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UnauthorizedError"
}
}
}
},
"404": {
"description": "PtyNotFoundError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PtyNotFoundError"
}
}
}
}
},
"description": "Terminate and remove one PTY session.",
"summary": "Remove PTY session",
"x-codeSamples": [
{
"lang": "js",
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.v2.pty.remove({\n ...\n})"
}
]
}
},
"/api/pty/{ptyID}/connect-token": {
"post": {
"tags": ["pty"],
"operationId": "v2.pty.connectToken",
"parameters": [
{
"name": "ptyID",
"in": "path",
"schema": {
"type": "string",
"pattern": "^pty"
},
"required": true
},
{
"name": "location",
"in": "query",
"schema": {
"type": "object",
"properties": {
"directory": {
"type": "string"
},
"workspace": {
"type": "string"
}
},
"additionalProperties": false
},
"required": false,
"style": "deepObject",
"explode": true
}
],
"security": [],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"location": {
"$ref": "#/components/schemas/LocationInfo"
},
"data": {
"type": "object",
"properties": {
"ticket": {
"type": "string"
},
"expires_in": {
"type": "integer",
"exclusiveMinimum": 0
}
},
"required": ["ticket", "expires_in"],
"additionalProperties": false
}
},
"required": ["location", "data"],
"additionalProperties": false
}
}
}
},
"400": {
"description": "InvalidRequestError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvalidRequestError"
}
}
}
},
"401": {
"description": "UnauthorizedError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UnauthorizedError"
}
}
}
},
"403": {
"description": "ForbiddenError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ForbiddenError"
}
}
}
},
"404": {
"description": "PtyNotFoundError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PtyNotFoundError"
}
}
}
}
},
"description": "Create a short-lived single-use ticket for opening a PTY WebSocket connection.",
"summary": "Create PTY WebSocket token",
"x-codeSamples": [
{
"lang": "js",
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.v2.pty.connectToken({\n ...\n})"
}
]
}
},
"/api/pty/{ptyID}/connect": {
"get": {
"tags": ["pty"],
"operationId": "v2.pty.connect",
"parameters": [
{
"name": "ptyID",
"in": "path",
"schema": {
"type": "string",
"pattern": "^pty"
},
"required": true
},
{
"in": "query",
"name": "location[directory]",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "location[workspace]",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "ticket",
"schema": {
"type": "string"
}
}
],
"security": [],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "boolean"
}
}
}
},
"400": {
"description": "InvalidRequestError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvalidRequestError"
}
}
}
},
"401": {
"description": "UnauthorizedError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UnauthorizedError"
}
}
}
},
"403": {
"description": "ForbiddenError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ForbiddenError"
}
}
}
},
"404": {
"description": "PtyNotFoundError",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PtyNotFoundError"
}
}
}
}
},
"description": "Establish a WebSocket connection streaming PTY output and accepting terminal input.",
"summary": "Connect to PTY session",
"x-codeSamples": [
{
"lang": "js",
"source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.v2.pty.connect({\n ...\n})"
}
]
}
},
"/api/question/request": {
"get": {
"tags": ["session questions"],
@ -15640,6 +16356,10 @@
"pid": {
"type": "integer",
"minimum": 0
},
"exitCode": {
"type": "integer",
"minimum": 0
}
},
"required": ["id", "title", "command", "args", "cwd", "status", "pid"],
@ -22082,6 +22802,20 @@
"required": ["_tag", "providerID", "message"],
"additionalProperties": false
},
"ForbiddenError": {
"type": "object",
"properties": {
"_tag": {
"type": "string",
"enum": ["ForbiddenError"]
},
"message": {
"type": "string"
}
},
"required": ["_tag", "message"],
"additionalProperties": false
},
"ProjectCopyError": {
"type": "object",
"properties": {
@ -30432,6 +31166,10 @@
"name": "events",
"description": "Experimental event stream route."
},
{
"name": "pty",
"description": "Experimental location-scoped PTY routes."
},
{
"name": "session questions",
"description": "Experimental session question routes."

View File

@ -9,11 +9,7 @@ import * as Socket from "effect/unstable/socket/Socket"
import { Api } from "../api"
import { CorsConfig, isAllowedRequestOrigin } from "../cors"
import { ForbiddenError, PtyNotFoundError } from "../errors"
import {
PTY_CONNECT_TICKET_QUERY,
PTY_CONNECT_TOKEN_HEADER,
PTY_CONNECT_TOKEN_HEADER_VALUE,
} from "../groups/pty"
import { PTY_CONNECT_TICKET_QUERY, PTY_CONNECT_TOKEN_HEADER, PTY_CONNECT_TOKEN_HEADER_VALUE } from "../groups/pty"
import { response } from "../groups/location"
const ticketScope = Effect.gen(function* () {
@ -51,18 +47,16 @@ export const PtyHandler = HttpApiBuilder.group(Api, "server.pty", (handlers) =>
Effect.fn(function* (ctx) {
const pty = yield* Pty.Service
return yield* response(
pty
.get(ctx.params.ptyID)
.pipe(
Effect.catchTag(
"Pty.NotFoundError",
() =>
new PtyNotFoundError({
ptyID: ctx.params.ptyID,
message: `PTY session not found: ${ctx.params.ptyID}`,
}),
),
pty.get(ctx.params.ptyID).pipe(
Effect.catchTag(
"Pty.NotFoundError",
() =>
new PtyNotFoundError({
ptyID: ctx.params.ptyID,
message: `PTY session not found: ${ctx.params.ptyID}`,
}),
),
),
)
}),
)
@ -93,18 +87,16 @@ export const PtyHandler = HttpApiBuilder.group(Api, "server.pty", (handlers) =>
"pty.remove",
Effect.fn(function* (ctx) {
const pty = yield* Pty.Service
yield* pty
.remove(ctx.params.ptyID)
.pipe(
Effect.catchTag(
"Pty.NotFoundError",
() =>
new PtyNotFoundError({
ptyID: ctx.params.ptyID,
message: `PTY session not found: ${ctx.params.ptyID}`,
}),
),
)
yield* pty.remove(ctx.params.ptyID).pipe(
Effect.catchTag(
"Pty.NotFoundError",
() =>
new PtyNotFoundError({
ptyID: ctx.params.ptyID,
message: `PTY session not found: ${ctx.params.ptyID}`,
}),
),
)
return HttpApiSchema.NoContent.make()
}),
)
@ -120,18 +112,16 @@ export const PtyHandler = HttpApiBuilder.group(Api, "server.pty", (handlers) =>
)
return yield* new ForbiddenError({ message: "Invalid PTY connect token request" })
const pty = yield* Pty.Service
yield* pty
.get(ctx.params.ptyID)
.pipe(
Effect.catchTag(
"Pty.NotFoundError",
() =>
new PtyNotFoundError({
ptyID: ctx.params.ptyID,
message: `PTY session not found: ${ctx.params.ptyID}`,
}),
),
)
yield* pty.get(ctx.params.ptyID).pipe(
Effect.catchTag(
"Pty.NotFoundError",
() =>
new PtyNotFoundError({
ptyID: ctx.params.ptyID,
message: `PTY session not found: ${ctx.params.ptyID}`,
}),
),
)
return yield* response(tickets.issue({ ptyID: ctx.params.ptyID, ...(yield* ticketScope) }))
}),
)