@hypercli.com/sdk 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +629 -0
- package/dist/acp-driver.d.ts +72 -0
- package/dist/acp-driver.d.ts.map +1 -0
- package/dist/acp-driver.js +147 -0
- package/dist/acp-driver.js.map +1 -0
- package/dist/acp-pool.d.ts +70 -0
- package/dist/acp-pool.d.ts.map +1 -0
- package/dist/acp-pool.js +181 -0
- package/dist/acp-pool.js.map +1 -0
- package/dist/acp.d.ts +179 -0
- package/dist/acp.d.ts.map +1 -0
- package/dist/acp.js +487 -0
- package/dist/acp.js.map +1 -0
- package/dist/agent-persona.d.ts +68 -0
- package/dist/agent-persona.d.ts.map +1 -0
- package/dist/agent-persona.js +78 -0
- package/dist/agent-persona.js.map +1 -0
- package/dist/agent-slots.d.ts +18 -0
- package/dist/agent-slots.d.ts.map +1 -0
- package/dist/agent-slots.js +24 -0
- package/dist/agent-slots.js.map +1 -0
- package/dist/agent-urls.d.ts +47 -0
- package/dist/agent-urls.d.ts.map +1 -0
- package/dist/agent-urls.js +178 -0
- package/dist/agent-urls.js.map +1 -0
- package/dist/agent.d.ts +482 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +926 -0
- package/dist/agent.js.map +1 -0
- package/dist/agents.d.ts +1452 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +4022 -0
- package/dist/agents.js.map +1 -0
- package/dist/billing.d.ts +72 -0
- package/dist/billing.d.ts.map +1 -0
- package/dist/billing.js +93 -0
- package/dist/billing.js.map +1 -0
- package/dist/browser-jobs.d.ts +24 -0
- package/dist/browser-jobs.d.ts.map +1 -0
- package/dist/browser-jobs.js +209 -0
- package/dist/browser-jobs.js.map +1 -0
- package/dist/browser.d.ts +41 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +57 -0
- package/dist/browser.js.map +1 -0
- package/dist/buzz-activity.d.ts +169 -0
- package/dist/buzz-activity.d.ts.map +1 -0
- package/dist/buzz-activity.js +844 -0
- package/dist/buzz-activity.js.map +1 -0
- package/dist/channels.d.ts +99 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +27 -0
- package/dist/channels.js.map +1 -0
- package/dist/chat-integrations.d.ts +44 -0
- package/dist/chat-integrations.d.ts.map +1 -0
- package/dist/chat-integrations.js +138 -0
- package/dist/chat-integrations.js.map +1 -0
- package/dist/client.d.ts +88 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +144 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +192 -0
- package/dist/config.js.map +1 -0
- package/dist/connectors.d.ts +80 -0
- package/dist/connectors.d.ts.map +1 -0
- package/dist/connectors.js +2 -0
- package/dist/connectors.js.map +1 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +26 -0
- package/dist/errors.js.map +1 -0
- package/dist/files.d.ts +60 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +128 -0
- package/dist/files.js.map +1 -0
- package/dist/http.d.ts +56 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +362 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/instances.d.ts +94 -0
- package/dist/instances.d.ts.map +1 -0
- package/dist/instances.js +197 -0
- package/dist/instances.js.map +1 -0
- package/dist/integrations.d.ts +111 -0
- package/dist/integrations.d.ts.map +1 -0
- package/dist/integrations.js +206 -0
- package/dist/integrations.js.map +1 -0
- package/dist/job/base.d.ts +86 -0
- package/dist/job/base.d.ts.map +1 -0
- package/dist/job/base.js +206 -0
- package/dist/job/base.js.map +1 -0
- package/dist/job/comfyui.d.ts +259 -0
- package/dist/job/comfyui.d.ts.map +1 -0
- package/dist/job/comfyui.js +1563 -0
- package/dist/job/comfyui.js.map +1 -0
- package/dist/job/gradio.d.ts +48 -0
- package/dist/job/gradio.d.ts.map +1 -0
- package/dist/job/gradio.js +90 -0
- package/dist/job/gradio.js.map +1 -0
- package/dist/job-codecs.d.ts +66 -0
- package/dist/job-codecs.d.ts.map +1 -0
- package/dist/job-codecs.js +132 -0
- package/dist/job-codecs.js.map +1 -0
- package/dist/jobs.d.ts +148 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +480 -0
- package/dist/jobs.js.map +1 -0
- package/dist/keys.d.ts +99 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +145 -0
- package/dist/keys.js.map +1 -0
- package/dist/logs.d.ts +54 -0
- package/dist/logs.d.ts.map +1 -0
- package/dist/logs.js +256 -0
- package/dist/logs.js.map +1 -0
- package/dist/managed-context.d.ts +20 -0
- package/dist/managed-context.d.ts.map +1 -0
- package/dist/managed-context.js +95 -0
- package/dist/managed-context.js.map +1 -0
- package/dist/mcp.d.ts +7 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +8 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory.d.ts +87 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +79 -0
- package/dist/memory.js.map +1 -0
- package/dist/models.d.ts +15 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +19 -0
- package/dist/models.js.map +1 -0
- package/dist/openclaw-control-ui-origin.d.ts +23 -0
- package/dist/openclaw-control-ui-origin.d.ts.map +1 -0
- package/dist/openclaw-control-ui-origin.js +53 -0
- package/dist/openclaw-control-ui-origin.js.map +1 -0
- package/dist/renders.d.ts +187 -0
- package/dist/renders.d.ts.map +1 -0
- package/dist/renders.js +360 -0
- package/dist/renders.js.map +1 -0
- package/dist/routines.d.ts +59 -0
- package/dist/routines.d.ts.map +1 -0
- package/dist/routines.js +135 -0
- package/dist/routines.js.map +1 -0
- package/dist/runners.d.ts +61 -0
- package/dist/runners.d.ts.map +1 -0
- package/dist/runners.js +127 -0
- package/dist/runners.js.map +1 -0
- package/dist/sessions.d.ts +280 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +292 -0
- package/dist/sessions.js.map +1 -0
- package/dist/skills.d.ts +170 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +2 -0
- package/dist/skills.js.map +1 -0
- package/dist/user.d.ts +78 -0
- package/dist/user.d.ts.map +1 -0
- package/dist/user.js +143 -0
- package/dist/user.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/voice-session.d.ts +66 -0
- package/dist/voice-session.d.ts.map +1 -0
- package/dist/voice-session.js +366 -0
- package/dist/voice-session.js.map +1 -0
- package/dist/voice-transcription-session.d.ts +64 -0
- package/dist/voice-transcription-session.d.ts.map +1 -0
- package/dist/voice-transcription-session.js +228 -0
- package/dist/voice-transcription-session.js.map +1 -0
- package/dist/voice.d.ts +62 -0
- package/dist/voice.d.ts.map +1 -0
- package/dist/voice.js +134 -0
- package/dist/voice.js.map +1 -0
- package/dist/workspace-tomd.d.ts +61 -0
- package/dist/workspace-tomd.d.ts.map +1 -0
- package/dist/workspace-tomd.js +177 -0
- package/dist/workspace-tomd.js.map +1 -0
- package/dist/workspaces.d.ts +255 -0
- package/dist/workspaces.d.ts.map +1 -0
- package/dist/workspaces.js +653 -0
- package/dist/workspaces.js.map +1 -0
- package/package.json +115 -0
- package/runtime/config-require.browser.js +4 -0
- package/runtime/config-require.d.ts +2 -0
- package/runtime/config-require.node.js +8 -0
package/dist/acp.d.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import * as acp from '@agentclientprotocol/sdk';
|
|
2
|
+
export type { ContentBlock, SessionNotification, RequestPermissionRequest } from '@agentclientprotocol/sdk';
|
|
3
|
+
export type CodingAgentAcpProtocolVersion = 1;
|
|
4
|
+
export type CodingAgentAcpPromptResult = acp.PromptResponse;
|
|
5
|
+
export type CodingAgentAcpTransport = 'proxy' | 'direct';
|
|
6
|
+
export declare const ACP_RECONNECT_DELAYS_MS: readonly number[];
|
|
7
|
+
export declare const ACP_PROXY_UNKNOWN_SESSION_CLOSE_CODE = 4404;
|
|
8
|
+
export declare class CodingAgentAcpUnavailableError extends Error {
|
|
9
|
+
readonly capability: string;
|
|
10
|
+
constructor(capability: string, detail: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class CodingAgentAcpConnectionError extends Error {
|
|
13
|
+
readonly code: number | null;
|
|
14
|
+
constructor(message: string, options?: {
|
|
15
|
+
code?: number | null;
|
|
16
|
+
cause?: unknown;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export declare class CodingAgentAcpRequestError extends Error {
|
|
20
|
+
readonly method: string;
|
|
21
|
+
readonly code: number;
|
|
22
|
+
readonly data?: unknown | undefined;
|
|
23
|
+
constructor(method: string, code: number, message: string, data?: unknown | undefined, cause?: unknown);
|
|
24
|
+
}
|
|
25
|
+
export declare class CodingAgentAcpAttachmentError extends Error {
|
|
26
|
+
readonly sessionId: string;
|
|
27
|
+
constructor(sessionId: string, detail: string, options?: {
|
|
28
|
+
cause?: unknown;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export type CodingAgentAcpStage = 'connect' | 'initialize' | 'cwd' | 'new' | 'list' | 'resume' | 'prompt';
|
|
32
|
+
export interface CodingAgentAcpDiagnosticError {
|
|
33
|
+
name: string;
|
|
34
|
+
code?: number | string;
|
|
35
|
+
statusCode?: number;
|
|
36
|
+
cause?: CodingAgentAcpDiagnosticError;
|
|
37
|
+
}
|
|
38
|
+
export type CodingAgentAcpDiagnostic = {
|
|
39
|
+
stage: CodingAgentAcpStage;
|
|
40
|
+
operationId: number;
|
|
41
|
+
timestamp: number;
|
|
42
|
+
elapsedMs: number;
|
|
43
|
+
phase: 'started' | 'succeeded' | 'failed';
|
|
44
|
+
error?: CodingAgentAcpDiagnosticError;
|
|
45
|
+
} | {
|
|
46
|
+
stage: 'transport';
|
|
47
|
+
phase: 'closed';
|
|
48
|
+
timestamp: number;
|
|
49
|
+
code: number | null;
|
|
50
|
+
reasonPresent: boolean;
|
|
51
|
+
};
|
|
52
|
+
type PermissionHandler = (params: acp.RequestPermissionRequest, signal?: AbortSignal) => acp.MaybePromise<acp.RequestPermissionResponse>;
|
|
53
|
+
export interface CodingAgentAcpConnectOptions {
|
|
54
|
+
onDiagnostic?: (event: CodingAgentAcpDiagnostic) => void;
|
|
55
|
+
resolveDefaultCwd?: () => Promise<string>;
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
token?: string;
|
|
58
|
+
cwd?: string;
|
|
59
|
+
clientInfo?: {
|
|
60
|
+
name?: string;
|
|
61
|
+
version?: string;
|
|
62
|
+
};
|
|
63
|
+
mcpServers?: acp.McpServer[];
|
|
64
|
+
transport?: CodingAgentAcpTransport;
|
|
65
|
+
sessionId?: string;
|
|
66
|
+
source?: string | null;
|
|
67
|
+
onUpdate?: (notification: acp.SessionNotification) => void;
|
|
68
|
+
onPermissionRequest?: PermissionHandler;
|
|
69
|
+
onError?: (error: Error) => void;
|
|
70
|
+
onClose?: (event: {
|
|
71
|
+
code: number;
|
|
72
|
+
reason: string;
|
|
73
|
+
}) => void;
|
|
74
|
+
/** Refresh platform history before reconnect resumes the tracked sessions. */
|
|
75
|
+
onReconnect?: () => void | Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
export interface CodingAgentAcpTarget {
|
|
78
|
+
url: string;
|
|
79
|
+
token: string;
|
|
80
|
+
}
|
|
81
|
+
/** Retained product publication, independent of native ACP. */
|
|
82
|
+
export interface SessionAttachment {
|
|
83
|
+
type: 'attachment';
|
|
84
|
+
id: string;
|
|
85
|
+
sessionId: string;
|
|
86
|
+
agentId: string;
|
|
87
|
+
nativeSessionId: string;
|
|
88
|
+
file: {
|
|
89
|
+
type: 'resource_link';
|
|
90
|
+
uri: string;
|
|
91
|
+
name: string;
|
|
92
|
+
mimeType: string;
|
|
93
|
+
size: number;
|
|
94
|
+
sha256: string;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export declare class CodingAgentAcpClient {
|
|
98
|
+
private readonly options;
|
|
99
|
+
private readonly target;
|
|
100
|
+
private readonly cookieStore;
|
|
101
|
+
private connection;
|
|
102
|
+
private pendingConnection;
|
|
103
|
+
private initializeValue;
|
|
104
|
+
private readonly sessions;
|
|
105
|
+
private readonly sessionConfig;
|
|
106
|
+
private ready;
|
|
107
|
+
private readonly connectedWaiters;
|
|
108
|
+
private readonly pendingPrompts;
|
|
109
|
+
private readonly updateListeners;
|
|
110
|
+
private readonly attachmentListeners;
|
|
111
|
+
private readonly errorListeners;
|
|
112
|
+
private readonly closeListeners;
|
|
113
|
+
private permissionHandler;
|
|
114
|
+
private closedFlag;
|
|
115
|
+
private terminalError;
|
|
116
|
+
private failures;
|
|
117
|
+
private generation;
|
|
118
|
+
private reconnectTimer;
|
|
119
|
+
private nextDiagnosticOperation;
|
|
120
|
+
private readonly onAbort;
|
|
121
|
+
private constructor();
|
|
122
|
+
static connect(target: CodingAgentAcpTarget, options?: CodingAgentAcpConnectOptions): Promise<CodingAgentAcpClient>;
|
|
123
|
+
get connected(): boolean;
|
|
124
|
+
get closed(): boolean;
|
|
125
|
+
get negotiatedProtocolVersion(): CodingAgentAcpProtocolVersion | null;
|
|
126
|
+
get initializeResponse(): acp.InitializeResponse | null;
|
|
127
|
+
get sessionIds(): string[];
|
|
128
|
+
/** Latest native configuration advertised for an attached session. */
|
|
129
|
+
sessionConfigOptions(sessionId: string): readonly acp.SessionConfigOption[];
|
|
130
|
+
addUpdateListener(listener: (notification: acp.SessionNotification) => void): () => void;
|
|
131
|
+
addAttachmentListener(listener: (attachment: SessionAttachment) => void): () => void;
|
|
132
|
+
addErrorListener(listener: (error: Error) => void): () => void;
|
|
133
|
+
addCloseListener(listener: (event: {
|
|
134
|
+
code: number;
|
|
135
|
+
reason: string;
|
|
136
|
+
}) => void): () => void;
|
|
137
|
+
setPermissionHandler(handler: PermissionHandler | null): void;
|
|
138
|
+
waitConnected(signal?: AbortSignal): Promise<void>;
|
|
139
|
+
private diagnostic;
|
|
140
|
+
private observe;
|
|
141
|
+
newSession(options?: {
|
|
142
|
+
cwd?: string;
|
|
143
|
+
mcpServers?: acp.McpServer[];
|
|
144
|
+
}): Promise<acp.NewSessionResponse>;
|
|
145
|
+
listSessions(options?: {
|
|
146
|
+
cwd?: string | null;
|
|
147
|
+
cursor?: string | null;
|
|
148
|
+
}): Promise<acp.ListSessionsResponse>;
|
|
149
|
+
private originalSessionCwd;
|
|
150
|
+
/** Exact tracked/catalog session cwd, without a launch/connection default fallback. */
|
|
151
|
+
sessionCwd(sessionId: string): Promise<string>;
|
|
152
|
+
resumeSession(sessionId: string, options?: {
|
|
153
|
+
cwd?: string;
|
|
154
|
+
mcpServers?: acp.McpServer[];
|
|
155
|
+
}): Promise<acp.ResumeSessionResponse>;
|
|
156
|
+
prompt(sessionId: string, prompt: string | acp.ContentBlock | acp.ContentBlock[]): Promise<acp.PromptResponse>;
|
|
157
|
+
cancel(sessionId: string): Promise<void>;
|
|
158
|
+
closeSession(sessionId: string): Promise<void>;
|
|
159
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
160
|
+
unstableForkSession(sessionId: string, options?: {
|
|
161
|
+
cwd?: string;
|
|
162
|
+
mcpServers?: acp.McpServer[];
|
|
163
|
+
}): Promise<acp.ForkSessionResponse>;
|
|
164
|
+
setMode(sessionId: string, modeId: string): Promise<void>;
|
|
165
|
+
setConfigOption(params: acp.SetSessionConfigOptionRequest): Promise<acp.SetSessionConfigOptionResponse>;
|
|
166
|
+
setConfigOption(sessionId: string, configId: string, value: string | boolean): Promise<acp.SetSessionConfigOptionResponse>;
|
|
167
|
+
setModel(sessionId: string, modelId: string): Promise<acp.SetSessionConfigOptionResponse>;
|
|
168
|
+
unstableListProviders(): Promise<unknown>;
|
|
169
|
+
unstableSetProvider(params: acp.SetProviderRequest): Promise<unknown>;
|
|
170
|
+
unstableDisableProvider(params: acp.DisableProviderRequest): Promise<unknown>;
|
|
171
|
+
request<T = unknown>(method: string, params?: unknown): Promise<T>;
|
|
172
|
+
notify(method: string, params?: unknown): Promise<void>;
|
|
173
|
+
private context;
|
|
174
|
+
close(): void;
|
|
175
|
+
private open;
|
|
176
|
+
private markReady;
|
|
177
|
+
private scheduleReconnect;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=acp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acp.d.ts","sourceRoot":"","sources":["../src/acp.ts"],"names":[],"mappings":"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"}
|
package/dist/acp.js
ADDED
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
/** Vanilla ACP v1. Platform history/receipts are separate from native turns. */
|
|
2
|
+
import NodeWebSocket from 'ws';
|
|
3
|
+
import * as acp from '@agentclientprotocol/sdk';
|
|
4
|
+
import { createWebSocketStream, MemoryAcpCookieStore } from '@agentclientprotocol/sdk/experimental/ws-client';
|
|
5
|
+
export const ACP_RECONNECT_DELAYS_MS = [1_000, 2_000, 4_000];
|
|
6
|
+
export const ACP_PROXY_UNKNOWN_SESSION_CLOSE_CODE = 4404;
|
|
7
|
+
const TERMINAL_CODES = new Set([4401, 4403, 4404, 4408]);
|
|
8
|
+
export class CodingAgentAcpUnavailableError extends Error {
|
|
9
|
+
capability;
|
|
10
|
+
constructor(capability, detail) {
|
|
11
|
+
super(`${capability} is not available: ${detail}`);
|
|
12
|
+
this.capability = capability;
|
|
13
|
+
this.name = 'CodingAgentAcpUnavailableError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class CodingAgentAcpConnectionError extends Error {
|
|
17
|
+
code;
|
|
18
|
+
constructor(message, options = {}) {
|
|
19
|
+
super(message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
20
|
+
this.name = 'CodingAgentAcpConnectionError';
|
|
21
|
+
this.code = options.code ?? null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export class CodingAgentAcpRequestError extends Error {
|
|
25
|
+
method;
|
|
26
|
+
code;
|
|
27
|
+
data;
|
|
28
|
+
constructor(method, code, message, data, cause) {
|
|
29
|
+
super(message, cause === undefined ? undefined : { cause });
|
|
30
|
+
this.method = method;
|
|
31
|
+
this.code = code;
|
|
32
|
+
this.data = data;
|
|
33
|
+
this.name = 'CodingAgentAcpRequestError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class CodingAgentAcpAttachmentError extends Error {
|
|
37
|
+
sessionId;
|
|
38
|
+
constructor(sessionId, detail, options = {}) {
|
|
39
|
+
super(`ACP session ${sessionId} could not be reattached: ${detail}`, options);
|
|
40
|
+
this.sessionId = sessionId;
|
|
41
|
+
this.name = 'CodingAgentAcpAttachmentError';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function diagnosticError(error, depth = 0) {
|
|
45
|
+
const value = error;
|
|
46
|
+
const name = value?.constructor?.name;
|
|
47
|
+
return {
|
|
48
|
+
name: typeof name === 'string' && /^[A-Za-z][A-Za-z0-9_]{0,79}$/.test(name) ? name : 'Error',
|
|
49
|
+
...(typeof value?.code === 'number' || (typeof value?.code === 'string' && /^(?:E[A-Z]+|UND_ERR_[A-Z_]+)$/.test(value.code)) ? { code: value.code } : {}),
|
|
50
|
+
...(typeof value?.statusCode === 'number' ? { statusCode: value.statusCode } : {}),
|
|
51
|
+
...(value?.cause !== undefined && depth < 3 ? { cause: diagnosticError(value.cause, depth + 1) } : {}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Observers never own protocol settlement, including accidentally async observers. */
|
|
55
|
+
function callObserver(observer, value) {
|
|
56
|
+
try {
|
|
57
|
+
void Promise.resolve(observer?.(value)).catch(() => { });
|
|
58
|
+
}
|
|
59
|
+
catch { /* Isolate consumer observers. */ }
|
|
60
|
+
}
|
|
61
|
+
export class CodingAgentAcpClient {
|
|
62
|
+
options;
|
|
63
|
+
target;
|
|
64
|
+
cookieStore = new MemoryAcpCookieStore();
|
|
65
|
+
connection = null;
|
|
66
|
+
pendingConnection = null;
|
|
67
|
+
initializeValue = null;
|
|
68
|
+
sessions = new Map();
|
|
69
|
+
sessionConfig = new Map();
|
|
70
|
+
ready = false;
|
|
71
|
+
connectedWaiters = new Set();
|
|
72
|
+
pendingPrompts = new Set();
|
|
73
|
+
updateListeners = new Set();
|
|
74
|
+
attachmentListeners = new Set();
|
|
75
|
+
errorListeners = new Set();
|
|
76
|
+
closeListeners = new Set();
|
|
77
|
+
permissionHandler = null;
|
|
78
|
+
closedFlag = false;
|
|
79
|
+
terminalError = null;
|
|
80
|
+
failures = 0;
|
|
81
|
+
generation = 0;
|
|
82
|
+
reconnectTimer = null;
|
|
83
|
+
nextDiagnosticOperation = 0;
|
|
84
|
+
onAbort = () => this.close();
|
|
85
|
+
constructor(target, options) {
|
|
86
|
+
this.options = options;
|
|
87
|
+
const url = new URL(target.url);
|
|
88
|
+
if (options.source !== undefined && options.source !== null) {
|
|
89
|
+
if (options.transport === 'direct')
|
|
90
|
+
throw new Error('source requires the ACP proxy transport');
|
|
91
|
+
url.searchParams.set('source', options.source);
|
|
92
|
+
}
|
|
93
|
+
this.target = { ...target, url: url.toString() };
|
|
94
|
+
}
|
|
95
|
+
static async connect(target, options = {}) {
|
|
96
|
+
const client = new CodingAgentAcpClient(target, options);
|
|
97
|
+
try {
|
|
98
|
+
if (options.signal?.aborted)
|
|
99
|
+
throw new CodingAgentAcpConnectionError('ACP connect aborted');
|
|
100
|
+
options.signal?.addEventListener('abort', client.onAbort, { once: true });
|
|
101
|
+
await client.open();
|
|
102
|
+
return client;
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
client.close();
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
get connected() { return this.ready && this.connection !== null && !this.closedFlag; }
|
|
110
|
+
get closed() { return this.closedFlag; }
|
|
111
|
+
get negotiatedProtocolVersion() { return this.initializeValue ? 1 : null; }
|
|
112
|
+
get initializeResponse() { return this.initializeValue; }
|
|
113
|
+
get sessionIds() { return [...this.sessions.keys()]; }
|
|
114
|
+
/** Latest native configuration advertised for an attached session. */
|
|
115
|
+
sessionConfigOptions(sessionId) {
|
|
116
|
+
return this.sessionConfig.get(sessionId) ?? [];
|
|
117
|
+
}
|
|
118
|
+
addUpdateListener(listener) {
|
|
119
|
+
this.updateListeners.add(listener);
|
|
120
|
+
return () => { this.updateListeners.delete(listener); };
|
|
121
|
+
}
|
|
122
|
+
addAttachmentListener(listener) {
|
|
123
|
+
this.attachmentListeners.add(listener);
|
|
124
|
+
return () => { this.attachmentListeners.delete(listener); };
|
|
125
|
+
}
|
|
126
|
+
addErrorListener(listener) {
|
|
127
|
+
this.errorListeners.add(listener);
|
|
128
|
+
return () => { this.errorListeners.delete(listener); };
|
|
129
|
+
}
|
|
130
|
+
addCloseListener(listener) {
|
|
131
|
+
this.closeListeners.add(listener);
|
|
132
|
+
return () => { this.closeListeners.delete(listener); };
|
|
133
|
+
}
|
|
134
|
+
setPermissionHandler(handler) { this.permissionHandler = handler; }
|
|
135
|
+
waitConnected(signal) {
|
|
136
|
+
if (signal?.aborted)
|
|
137
|
+
return Promise.reject(signal.reason);
|
|
138
|
+
if (this.connected)
|
|
139
|
+
return Promise.resolve();
|
|
140
|
+
if (this.closedFlag)
|
|
141
|
+
return Promise.reject(this.terminalError ?? new CodingAgentAcpConnectionError('ACP client closed'));
|
|
142
|
+
return new Promise((resolve, reject) => {
|
|
143
|
+
const cleanup = () => { this.connectedWaiters.delete(waiter); signal?.removeEventListener('abort', abort); };
|
|
144
|
+
const waiter = { resolve: () => { cleanup(); resolve(); }, reject: (error) => { cleanup(); reject(error); } };
|
|
145
|
+
const abort = () => waiter.reject(signal.reason);
|
|
146
|
+
this.connectedWaiters.add(waiter);
|
|
147
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
diagnostic(event) {
|
|
151
|
+
callObserver(this.options.onDiagnostic, event);
|
|
152
|
+
}
|
|
153
|
+
async observe(stage, run) {
|
|
154
|
+
const operationId = ++this.nextDiagnosticOperation;
|
|
155
|
+
const started = globalThis.performance.now();
|
|
156
|
+
this.diagnostic({ stage, operationId, timestamp: Date.now(), elapsedMs: 0, phase: 'started' });
|
|
157
|
+
try {
|
|
158
|
+
const result = await run();
|
|
159
|
+
this.diagnostic({ stage, operationId, timestamp: Date.now(), elapsedMs: Math.round(globalThis.performance.now() - started), phase: 'succeeded' });
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
this.diagnostic({ stage, operationId, timestamp: Date.now(), elapsedMs: Math.round(globalThis.performance.now() - started), phase: 'failed', error: diagnosticError(error) });
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async newSession(options = {}) {
|
|
168
|
+
const cwd = await this.observe('cwd', async () => {
|
|
169
|
+
const supplied = options.cwd ?? this.options.cwd;
|
|
170
|
+
if (supplied !== undefined)
|
|
171
|
+
return supplied;
|
|
172
|
+
if (!this.options.resolveDefaultCwd)
|
|
173
|
+
throw new CodingAgentAcpUnavailableError('session/new', 'supply cwd or a runtime path resolver');
|
|
174
|
+
return this.options.resolveDefaultCwd();
|
|
175
|
+
});
|
|
176
|
+
const mcpServers = structuredClone(options.mcpServers ?? this.options.mcpServers ?? []);
|
|
177
|
+
const result = await this.observe('new', () => this.request('session/new', { cwd, mcpServers }));
|
|
178
|
+
this.sessions.set(result.sessionId, { cwd, mcpServers });
|
|
179
|
+
if (result.configOptions)
|
|
180
|
+
this.sessionConfig.set(result.sessionId, result.configOptions);
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
async listSessions(options = {}) {
|
|
184
|
+
return this.observe('list', () => this.request('session/list', options));
|
|
185
|
+
}
|
|
186
|
+
async originalSessionCwd(sessionId) {
|
|
187
|
+
return this.sessions.get(sessionId)?.cwd ?? this.options.cwd ?? this.sessionCwd(sessionId);
|
|
188
|
+
}
|
|
189
|
+
/** Exact tracked/catalog session cwd, without a launch/connection default fallback. */
|
|
190
|
+
async sessionCwd(sessionId) {
|
|
191
|
+
const tracked = this.sessions.get(sessionId);
|
|
192
|
+
if (tracked)
|
|
193
|
+
return tracked.cwd;
|
|
194
|
+
let cursor;
|
|
195
|
+
const seen = new Set();
|
|
196
|
+
do {
|
|
197
|
+
const page = await this.listSessions({ cursor });
|
|
198
|
+
const entry = page.sessions.find(s => s.sessionId === sessionId);
|
|
199
|
+
if (entry)
|
|
200
|
+
return entry.cwd;
|
|
201
|
+
cursor = page.nextCursor ?? undefined;
|
|
202
|
+
if (cursor && seen.has(cursor))
|
|
203
|
+
throw new Error('session/list repeated a cursor');
|
|
204
|
+
if (cursor)
|
|
205
|
+
seen.add(cursor);
|
|
206
|
+
} while (cursor);
|
|
207
|
+
throw new CodingAgentAcpUnavailableError('session/list', 'original session cwd is unavailable');
|
|
208
|
+
}
|
|
209
|
+
async resumeSession(sessionId, options = {}) {
|
|
210
|
+
const previous = this.sessions.get(sessionId);
|
|
211
|
+
const cwd = await this.observe('cwd', () => options.cwd !== undefined ? Promise.resolve(options.cwd) : this.originalSessionCwd(sessionId));
|
|
212
|
+
const mcpServers = structuredClone(options.mcpServers ?? previous?.mcpServers ?? this.options.mcpServers ?? []);
|
|
213
|
+
const connection = this.connection, generation = this.generation;
|
|
214
|
+
const result = await this.observe('resume', () => this.request('session/resume', { sessionId, cwd, mcpServers }));
|
|
215
|
+
if (connection !== this.connection || generation !== this.generation || this.closedFlag)
|
|
216
|
+
throw new CodingAgentAcpConnectionError('ACP attachment interrupted');
|
|
217
|
+
this.sessions.set(sessionId, { cwd, mcpServers });
|
|
218
|
+
if (result.configOptions)
|
|
219
|
+
this.sessionConfig.set(sessionId, result.configOptions);
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
async prompt(sessionId, prompt) {
|
|
223
|
+
const pending = { sessionId, controller: new AbortController() };
|
|
224
|
+
this.pendingPrompts.add(pending);
|
|
225
|
+
try {
|
|
226
|
+
await this.waitConnected(pending.controller.signal);
|
|
227
|
+
pending.controller.signal.throwIfAborted();
|
|
228
|
+
}
|
|
229
|
+
finally {
|
|
230
|
+
this.pendingPrompts.delete(pending);
|
|
231
|
+
}
|
|
232
|
+
const blocks = typeof prompt === 'string' ? [{ type: 'text', text: prompt }] : Array.isArray(prompt) ? prompt : [prompt];
|
|
233
|
+
return this.observe('prompt', () => this.request('session/prompt', { sessionId, prompt: blocks }));
|
|
234
|
+
}
|
|
235
|
+
async cancel(sessionId) {
|
|
236
|
+
for (const pending of this.pendingPrompts) {
|
|
237
|
+
if (pending.sessionId === sessionId)
|
|
238
|
+
pending.controller.abort(new Error('ACP prompt cancelled before delivery'));
|
|
239
|
+
}
|
|
240
|
+
await this.notify('session/cancel', { sessionId });
|
|
241
|
+
}
|
|
242
|
+
async closeSession(sessionId) { await this.request('session/close', { sessionId }); this.sessions.delete(sessionId); this.sessionConfig.delete(sessionId); }
|
|
243
|
+
async deleteSession(sessionId) { await this.request('session/delete', { sessionId }); this.sessions.delete(sessionId); this.sessionConfig.delete(sessionId); }
|
|
244
|
+
async unstableForkSession(sessionId, options = {}) {
|
|
245
|
+
const cwd = options.cwd ?? await this.originalSessionCwd(sessionId);
|
|
246
|
+
const mcpServers = structuredClone(options.mcpServers ?? this.sessions.get(sessionId)?.mcpServers ?? this.options.mcpServers ?? []);
|
|
247
|
+
const result = await this.request('session/fork', { sessionId, cwd, mcpServers });
|
|
248
|
+
this.sessions.set(result.sessionId, { cwd, mcpServers });
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
async setMode(sessionId, modeId) { await this.request('session/set_mode', { sessionId, modeId }); }
|
|
252
|
+
async setConfigOption(...args) {
|
|
253
|
+
const params = args.length === 1 ? args[0] : {
|
|
254
|
+
sessionId: args[0], configId: args[1], value: args[2],
|
|
255
|
+
...(typeof args[2] === 'boolean' ? { type: 'boolean' } : {}),
|
|
256
|
+
};
|
|
257
|
+
const result = await this.request('session/set_config_option', params);
|
|
258
|
+
this.sessionConfig.set(params.sessionId, result.configOptions);
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
async setModel(sessionId, modelId) {
|
|
262
|
+
const option = this.sessionConfig.get(sessionId)?.find(o => o.category === 'model');
|
|
263
|
+
if (!option)
|
|
264
|
+
throw new CodingAgentAcpUnavailableError('session/set_config_option', 'no model configuration advertised');
|
|
265
|
+
return this.setConfigOption(sessionId, option.id, modelId);
|
|
266
|
+
}
|
|
267
|
+
async unstableListProviders() { return this.request('providers/list', {}); }
|
|
268
|
+
async unstableSetProvider(params) { return this.request('providers/set', params); }
|
|
269
|
+
async unstableDisableProvider(params) { return this.request('providers/disable', params); }
|
|
270
|
+
async request(method, params) {
|
|
271
|
+
try {
|
|
272
|
+
return await this.context().request(method, params);
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
if (error instanceof acp.RequestError)
|
|
276
|
+
throw new CodingAgentAcpRequestError(method, error.code, error.message, error.data, error);
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
notify(method, params) { return this.context().notify(method, params); }
|
|
281
|
+
context() {
|
|
282
|
+
if (!this.connection || this.closedFlag)
|
|
283
|
+
throw this.terminalError ?? new CodingAgentAcpConnectionError('ACP connection unavailable');
|
|
284
|
+
return this.connection.agent;
|
|
285
|
+
}
|
|
286
|
+
close() {
|
|
287
|
+
if (this.closedFlag)
|
|
288
|
+
return;
|
|
289
|
+
this.closedFlag = true;
|
|
290
|
+
++this.generation;
|
|
291
|
+
this.options.signal?.removeEventListener('abort', this.onAbort);
|
|
292
|
+
if (this.reconnectTimer !== null)
|
|
293
|
+
clearTimeout(this.reconnectTimer);
|
|
294
|
+
const error = this.terminalError ?? new CodingAgentAcpConnectionError('ACP client closed; pending delivery is unresolved');
|
|
295
|
+
this.pendingConnection?.close(error);
|
|
296
|
+
this.connection?.close(error);
|
|
297
|
+
this.connection = this.pendingConnection = null;
|
|
298
|
+
for (const waiter of this.connectedWaiters)
|
|
299
|
+
waiter.reject(error);
|
|
300
|
+
this.connectedWaiters.clear();
|
|
301
|
+
this.updateListeners.clear();
|
|
302
|
+
this.errorListeners.clear();
|
|
303
|
+
this.closeListeners.clear();
|
|
304
|
+
this.sessionConfig.clear();
|
|
305
|
+
this.permissionHandler = null;
|
|
306
|
+
}
|
|
307
|
+
async open(reconnecting = false) {
|
|
308
|
+
const generation = this.generation;
|
|
309
|
+
const closeInfo = { reason: '' };
|
|
310
|
+
let socketOpened;
|
|
311
|
+
let socketFailed;
|
|
312
|
+
const opened = new Promise((resolve, reject) => { socketOpened = resolve; socketFailed = reject; });
|
|
313
|
+
void opened.catch(() => { });
|
|
314
|
+
const WebSocketImpl = (NodeWebSocket ?? globalThis.WebSocket);
|
|
315
|
+
const diagnostic = (event) => this.diagnostic(event);
|
|
316
|
+
const TrackedSocket = class {
|
|
317
|
+
constructor(url, protocols, options) {
|
|
318
|
+
const ws = new WebSocketImpl(url, protocols, options);
|
|
319
|
+
const closed = (code, reason = '') => {
|
|
320
|
+
closeInfo.code = code;
|
|
321
|
+
closeInfo.reason = reason;
|
|
322
|
+
socketFailed(new CodingAgentAcpConnectionError('ACP socket closed before opening', { code }));
|
|
323
|
+
diagnostic({ stage: 'transport', phase: 'closed', timestamp: Date.now(), code: code ?? null, reasonPresent: reason.length > 0 });
|
|
324
|
+
};
|
|
325
|
+
if (typeof ws.on === 'function') {
|
|
326
|
+
ws.on('open', socketOpened);
|
|
327
|
+
ws.on('error', (error) => socketFailed(new CodingAgentAcpConnectionError('ACP socket failed before opening', { cause: error })));
|
|
328
|
+
ws.on('close', (...args) => closed(typeof args[0] === 'number' ? args[0] : undefined, String(args[1] ?? '')));
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
ws.addEventListener?.('open', socketOpened);
|
|
332
|
+
ws.addEventListener?.('error', (error) => socketFailed(new CodingAgentAcpConnectionError('ACP socket failed before opening', { cause: error })));
|
|
333
|
+
ws.addEventListener?.('close', (event) => { const e = event; closed(e.code, e.reason); });
|
|
334
|
+
}
|
|
335
|
+
return ws;
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
const app = acp.client({ name: this.options.clientInfo?.name ?? 'hypercli-ts-sdk' });
|
|
339
|
+
app.onRequest('session/request_permission', context => {
|
|
340
|
+
const handler = this.permissionHandler ?? this.options.onPermissionRequest;
|
|
341
|
+
return handler ? handler(context.params, context.signal) : { outcome: { outcome: 'cancelled' } };
|
|
342
|
+
});
|
|
343
|
+
const sessionUpdate = (notification) => {
|
|
344
|
+
if (this.closedFlag || generation !== this.generation)
|
|
345
|
+
return;
|
|
346
|
+
if (notification.update.sessionUpdate === 'config_option_update') {
|
|
347
|
+
this.sessionConfig.set(notification.sessionId, notification.update.configOptions);
|
|
348
|
+
}
|
|
349
|
+
for (const listener of [this.options.onUpdate, ...this.updateListeners]) {
|
|
350
|
+
callObserver(listener, notification);
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
const productAttachment = (attachment) => {
|
|
354
|
+
if (this.closedFlag || generation !== this.generation)
|
|
355
|
+
return;
|
|
356
|
+
for (const listener of this.attachmentListeners)
|
|
357
|
+
callObserver(listener, attachment);
|
|
358
|
+
};
|
|
359
|
+
const connection = await this.observe('connect', async () => {
|
|
360
|
+
const stream = createWebSocketStream(this.target.url, {
|
|
361
|
+
WebSocket: TrackedSocket, cookieStore: this.cookieStore,
|
|
362
|
+
headers: this.target.token ? { Authorization: `Bearer ${this.target.token}` } : undefined,
|
|
363
|
+
});
|
|
364
|
+
const pending = app.connect({ ...stream,
|
|
365
|
+
// Upstream's active-session router validates an exhaustive update union.
|
|
366
|
+
// Forward notifications untouched; RPCs/callbacks remain SDK-owned.
|
|
367
|
+
readable: stream.readable.pipeThrough(new globalThis.TransformStream({ transform(frame, controller) {
|
|
368
|
+
if (frame && typeof frame === 'object' && 'type' in frame && frame.type === 'attachment') {
|
|
369
|
+
const attachment = frame;
|
|
370
|
+
if (typeof attachment.sessionId === 'string' && typeof attachment.id === 'string'
|
|
371
|
+
&& typeof attachment.agentId === 'string' && typeof attachment.file?.name === 'string'
|
|
372
|
+
&& typeof attachment.file.mimeType === 'string'
|
|
373
|
+
&& typeof attachment.file.uri === 'string' && typeof attachment.file.sha256 === 'string') {
|
|
374
|
+
productAttachment(attachment);
|
|
375
|
+
}
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
if (frame && typeof frame === 'object' && 'method' in frame && frame.method === 'session/update' && !('id' in frame)) {
|
|
379
|
+
sessionUpdate(frame.params);
|
|
380
|
+
}
|
|
381
|
+
else
|
|
382
|
+
controller.enqueue(frame);
|
|
383
|
+
} })),
|
|
384
|
+
});
|
|
385
|
+
this.pendingConnection = pending;
|
|
386
|
+
void pending.closed.then(() => socketFailed(new CodingAgentAcpConnectionError('ACP connection closed before opening')));
|
|
387
|
+
try {
|
|
388
|
+
await opened;
|
|
389
|
+
return pending;
|
|
390
|
+
}
|
|
391
|
+
catch (error) {
|
|
392
|
+
pending.close(error instanceof Error ? error : undefined);
|
|
393
|
+
throw error;
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
this.pendingConnection = connection;
|
|
397
|
+
void connection.closed.then(() => {
|
|
398
|
+
if (this.closedFlag || this.connection !== connection)
|
|
399
|
+
return;
|
|
400
|
+
this.connection = null;
|
|
401
|
+
this.ready = false;
|
|
402
|
+
++this.generation;
|
|
403
|
+
this.scheduleReconnect(closeInfo.code ?? 1006, closeInfo.reason);
|
|
404
|
+
});
|
|
405
|
+
try {
|
|
406
|
+
const response = await this.observe('initialize', () => connection.agent.request('initialize', {
|
|
407
|
+
protocolVersion: 1, clientCapabilities: {}, clientInfo: { name: this.options.clientInfo?.name ?? 'hypercli-ts-sdk', version: this.options.clientInfo?.version ?? '' },
|
|
408
|
+
}));
|
|
409
|
+
if (response.protocolVersion !== 1)
|
|
410
|
+
throw new CodingAgentAcpConnectionError('ACP peer did not select v1');
|
|
411
|
+
if (this.closedFlag || generation !== this.generation)
|
|
412
|
+
throw new CodingAgentAcpConnectionError('ACP connect aborted');
|
|
413
|
+
this.initializeValue = response;
|
|
414
|
+
this.connection = connection;
|
|
415
|
+
if (!reconnecting)
|
|
416
|
+
this.markReady();
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
connection.close(error instanceof Error ? error : undefined);
|
|
420
|
+
throw error;
|
|
421
|
+
}
|
|
422
|
+
finally {
|
|
423
|
+
if (this.pendingConnection === connection)
|
|
424
|
+
this.pendingConnection = null;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
markReady() {
|
|
428
|
+
this.ready = true;
|
|
429
|
+
for (const waiter of this.connectedWaiters)
|
|
430
|
+
waiter.resolve();
|
|
431
|
+
this.connectedWaiters.clear();
|
|
432
|
+
}
|
|
433
|
+
scheduleReconnect(code, reason) {
|
|
434
|
+
if (this.closedFlag)
|
|
435
|
+
return;
|
|
436
|
+
if (TERMINAL_CODES.has(code) || this.failures >= ACP_RECONNECT_DELAYS_MS.length) {
|
|
437
|
+
this.terminalError = new CodingAgentAcpConnectionError('ACP connection closed', { code });
|
|
438
|
+
const listeners = [...this.closeListeners];
|
|
439
|
+
this.close();
|
|
440
|
+
for (const listener of [this.options.onClose, ...listeners])
|
|
441
|
+
callObserver(listener, { code, reason });
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
this.reconnectTimer = setTimeout(() => {
|
|
445
|
+
this.reconnectTimer = null;
|
|
446
|
+
void this.open(true).then(async () => {
|
|
447
|
+
const connection = this.connection, generation = this.generation;
|
|
448
|
+
const ownsConnection = () => !this.closedFlag && connection === this.connection && generation === this.generation;
|
|
449
|
+
this.failures = 0;
|
|
450
|
+
try {
|
|
451
|
+
await this.options.onReconnect?.();
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
const failure = error instanceof Error ? error : new CodingAgentAcpConnectionError('ACP reconnect callback failed', { cause: error });
|
|
455
|
+
if (ownsConnection())
|
|
456
|
+
for (const listener of [this.options.onError, ...this.errorListeners])
|
|
457
|
+
callObserver(listener, failure);
|
|
458
|
+
}
|
|
459
|
+
for (const [sid, setup] of this.sessions) {
|
|
460
|
+
if (!ownsConnection())
|
|
461
|
+
return;
|
|
462
|
+
try {
|
|
463
|
+
await this.resumeSession(sid, { cwd: setup.cwd });
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
if (!ownsConnection())
|
|
467
|
+
return;
|
|
468
|
+
if (!(error instanceof CodingAgentAcpRequestError)) {
|
|
469
|
+
connection?.close(error instanceof Error ? error : undefined);
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
this.sessions.delete(sid);
|
|
473
|
+
const gap = new CodingAgentAcpAttachmentError(sid, error.message, { cause: error });
|
|
474
|
+
for (const waiter of this.connectedWaiters)
|
|
475
|
+
waiter.reject(gap);
|
|
476
|
+
this.connectedWaiters.clear();
|
|
477
|
+
for (const listener of [this.options.onError, ...this.errorListeners])
|
|
478
|
+
callObserver(listener, gap);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
if (ownsConnection())
|
|
482
|
+
this.markReady();
|
|
483
|
+
}, () => this.scheduleReconnect(code, reason));
|
|
484
|
+
}, ACP_RECONNECT_DELAYS_MS[this.failures++]);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
//# sourceMappingURL=acp.js.map
|