@getpaseo/server 0.1.12 → 0.1.14
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/dist/server/client/daemon-client.d.ts +84 -87
- package/dist/server/client/daemon-client.d.ts.map +1 -1
- package/dist/server/client/daemon-client.js +253 -299
- package/dist/server/client/daemon-client.js.map +1 -1
- package/dist/server/server/agent/agent-manager.d.ts +2 -1
- package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
- package/dist/server/server/agent/agent-manager.js +23 -0
- package/dist/server/server/agent/agent-manager.js.map +1 -1
- package/dist/server/server/agent/agent-sdk-types.d.ts +0 -15
- package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.js +268 -35
- package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/codex-app-server-agent.js +85 -36
- package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
- package/dist/server/server/bootstrap.d.ts.map +1 -1
- package/dist/server/server/bootstrap.js +3 -1
- package/dist/server/server/bootstrap.js.map +1 -1
- package/dist/server/server/daemon-version.d.ts +5 -0
- package/dist/server/server/daemon-version.d.ts.map +1 -0
- package/dist/server/server/daemon-version.js +22 -0
- package/dist/server/server/daemon-version.js.map +1 -0
- package/dist/server/server/dictation/dictation-stream-manager.d.ts +1 -0
- package/dist/server/server/dictation/dictation-stream-manager.d.ts.map +1 -1
- package/dist/server/server/dictation/dictation-stream-manager.js +32 -1
- package/dist/server/server/dictation/dictation-stream-manager.js.map +1 -1
- package/dist/server/server/package-version.d.ts +13 -0
- package/dist/server/server/package-version.d.ts.map +1 -0
- package/dist/server/server/package-version.js +47 -0
- package/dist/server/server/package-version.js.map +1 -0
- package/dist/server/server/persisted-config.d.ts +2 -2
- package/dist/server/server/pid-lock.d.ts.map +1 -1
- package/dist/server/server/pid-lock.js +16 -2
- package/dist/server/server/pid-lock.js.map +1 -1
- package/dist/server/server/session.d.ts +23 -21
- package/dist/server/server/session.d.ts.map +1 -1
- package/dist/server/server/session.js +975 -850
- package/dist/server/server/session.js.map +1 -1
- package/dist/server/server/websocket-server.d.ts +5 -1
- package/dist/server/server/websocket-server.d.ts.map +1 -1
- package/dist/server/server/websocket-server.js +27 -16
- package/dist/server/server/websocket-server.js.map +1 -1
- package/dist/server/shared/agent-attention-notification.d.ts +40 -0
- package/dist/server/shared/agent-attention-notification.d.ts.map +1 -0
- package/dist/server/shared/agent-attention-notification.js +130 -0
- package/dist/server/shared/agent-attention-notification.js.map +1 -0
- package/dist/server/shared/messages.d.ts +974 -619
- package/dist/server/shared/messages.d.ts.map +1 -1
- package/dist/server/shared/messages.js +285 -296
- package/dist/server/shared/messages.js.map +1 -1
- package/dist/server/utils/checkout-git.d.ts +3 -0
- package/dist/server/utils/checkout-git.d.ts.map +1 -1
- package/dist/server/utils/checkout-git.js +102 -23
- package/dist/server/utils/checkout-git.js.map +1 -1
- package/dist/server/utils/directory-suggestions.d.ts +15 -0
- package/dist/server/utils/directory-suggestions.d.ts.map +1 -1
- package/dist/server/utils/directory-suggestions.js +348 -21
- package/dist/server/utils/directory-suggestions.js.map +1 -1
- package/dist/server/utils/worktree-metadata.d.ts +4 -4
- package/dist/server/utils/worktree.d.ts +1 -0
- package/dist/server/utils/worktree.d.ts.map +1 -1
- package/dist/server/utils/worktree.js +41 -77
- package/dist/server/utils/worktree.js.map +1 -1
- package/package.json +5 -5
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { AgentCreateFailedStatusPayloadSchema, AgentCreatedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, AgentResumedStatusPayloadSchema, RestartRequestedStatusPayloadSchema, SessionInboundMessageSchema, WSOutboundMessageSchema, } from
|
|
2
|
-
import { getAgentProviderDefinition } from
|
|
3
|
-
import { isRelayClientWebSocketUrl } from
|
|
4
|
-
import { asUint8Array, decodeBinaryMuxFrame, encodeBinaryMuxFrame, BinaryMuxChannel, TerminalBinaryFlags, TerminalBinaryMessageType, } from
|
|
5
|
-
import { encodeTerminalKeyInput
|
|
6
|
-
import { TerminalStreamManager, } from
|
|
7
|
-
import { createRelayE2eeTransportFactory, createWebSocketTransportFactory, decodeMessageData, defaultWebSocketFactory, describeTransportClose, describeTransportError, encodeUtf8String, safeRandomId, } from
|
|
1
|
+
import { AgentCreateFailedStatusPayloadSchema, AgentCreatedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, AgentResumedStatusPayloadSchema, RestartRequestedStatusPayloadSchema, SessionInboundMessageSchema, WSOutboundMessageSchema, } from '../shared/messages.js';
|
|
2
|
+
import { getAgentProviderDefinition } from '../server/agent/provider-manifest.js';
|
|
3
|
+
import { isRelayClientWebSocketUrl } from '../shared/daemon-endpoints.js';
|
|
4
|
+
import { asUint8Array, decodeBinaryMuxFrame, encodeBinaryMuxFrame, BinaryMuxChannel, TerminalBinaryFlags, TerminalBinaryMessageType, } from '../shared/binary-mux.js';
|
|
5
|
+
import { encodeTerminalKeyInput } from '../shared/terminal-key-input.js';
|
|
6
|
+
import { TerminalStreamManager, } from './daemon-client-terminal-stream-manager.js';
|
|
7
|
+
import { createRelayE2eeTransportFactory, createWebSocketTransportFactory, decodeMessageData, defaultWebSocketFactory, describeTransportClose, describeTransportError, encodeUtf8String, safeRandomId, } from './daemon-client-transport.js';
|
|
8
8
|
const consoleLogger = {
|
|
9
9
|
debug: (obj, msg) => console.debug(msg, obj),
|
|
10
10
|
info: (obj, msg) => console.info(msg, obj),
|
|
@@ -14,7 +14,7 @@ const consoleLogger = {
|
|
|
14
14
|
class DaemonRpcError extends Error {
|
|
15
15
|
constructor(params) {
|
|
16
16
|
super(params.error);
|
|
17
|
-
this.name =
|
|
17
|
+
this.name = 'DaemonRpcError';
|
|
18
18
|
this.requestId = params.requestId;
|
|
19
19
|
this.requestType = params.requestType;
|
|
20
20
|
this.code = params.code;
|
|
@@ -28,7 +28,7 @@ const DEFAULT_DICTATION_FINISH_ACCEPT_TIMEOUT_MS = 15000;
|
|
|
28
28
|
const DEFAULT_DICTATION_FINISH_FALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
|
|
29
29
|
const DEFAULT_DICTATION_FINISH_TIMEOUT_GRACE_MS = 5000;
|
|
30
30
|
function isWaiterTimeoutError(error) {
|
|
31
|
-
return
|
|
31
|
+
return error instanceof Error && error.message.startsWith('Timeout waiting for message');
|
|
32
32
|
}
|
|
33
33
|
export class DaemonClient {
|
|
34
34
|
constructor(config) {
|
|
@@ -49,8 +49,7 @@ export class DaemonClient {
|
|
|
49
49
|
this.connectResolve = null;
|
|
50
50
|
this.connectReject = null;
|
|
51
51
|
this.lastErrorValue = null;
|
|
52
|
-
this.connectionState = { status:
|
|
53
|
-
this.agentUpdateSubscriptions = new Map();
|
|
52
|
+
this.connectionState = { status: 'idle' };
|
|
54
53
|
this.checkoutDiffSubscriptions = new Map();
|
|
55
54
|
this.terminalDirectorySubscriptions = new Set();
|
|
56
55
|
this.pendingSendQueue = [];
|
|
@@ -73,9 +72,9 @@ export class DaemonClient {
|
|
|
73
72
|
if (isRelayClientWebSocketUrl(this.config.url)) {
|
|
74
73
|
try {
|
|
75
74
|
const parsed = new URL(this.config.url);
|
|
76
|
-
if (!parsed.searchParams.get(
|
|
75
|
+
if (!parsed.searchParams.get('clientId')) {
|
|
77
76
|
this.relayClientId = `clt_${safeRandomId()}`;
|
|
78
|
-
parsed.searchParams.set(
|
|
77
|
+
parsed.searchParams.set('clientId', this.relayClientId);
|
|
79
78
|
this.config.url = parsed.toString();
|
|
80
79
|
}
|
|
81
80
|
}
|
|
@@ -88,7 +87,7 @@ export class DaemonClient {
|
|
|
88
87
|
// Connection
|
|
89
88
|
// ============================================================================
|
|
90
89
|
async connect() {
|
|
91
|
-
if (this.connectionState.status ===
|
|
90
|
+
if (this.connectionState.status === 'connected') {
|
|
92
91
|
return;
|
|
93
92
|
}
|
|
94
93
|
if (this.connectPromise) {
|
|
@@ -104,15 +103,15 @@ export class DaemonClient {
|
|
|
104
103
|
}
|
|
105
104
|
attemptConnect() {
|
|
106
105
|
if (!this.shouldReconnect) {
|
|
107
|
-
this.rejectConnect(new Error(
|
|
106
|
+
this.rejectConnect(new Error('Daemon client is closed'));
|
|
108
107
|
return;
|
|
109
108
|
}
|
|
110
|
-
if (this.connectionState.status ===
|
|
109
|
+
if (this.connectionState.status === 'connecting') {
|
|
111
110
|
return;
|
|
112
111
|
}
|
|
113
112
|
const headers = {};
|
|
114
113
|
if (this.config.authHeader) {
|
|
115
|
-
headers[
|
|
114
|
+
headers['Authorization'] = this.config.authHeader;
|
|
116
115
|
}
|
|
117
116
|
try {
|
|
118
117
|
// If we reconnect while the previous socket is still open (common in browsers
|
|
@@ -122,13 +121,12 @@ export class DaemonClient {
|
|
|
122
121
|
this.disposeTransport();
|
|
123
122
|
const baseTransportFactory = this.config.transportFactory ??
|
|
124
123
|
createWebSocketTransportFactory(this.config.webSocketFactory ?? defaultWebSocketFactory);
|
|
125
|
-
const shouldUseRelayE2ee = this.config.e2ee?.enabled === true &&
|
|
126
|
-
isRelayClientWebSocketUrl(this.config.url);
|
|
124
|
+
const shouldUseRelayE2ee = this.config.e2ee?.enabled === true && isRelayClientWebSocketUrl(this.config.url);
|
|
127
125
|
let transportFactory = baseTransportFactory;
|
|
128
126
|
if (shouldUseRelayE2ee) {
|
|
129
127
|
const daemonPublicKeyB64 = this.config.e2ee?.daemonPublicKeyB64;
|
|
130
128
|
if (!daemonPublicKeyB64) {
|
|
131
|
-
throw new Error(
|
|
129
|
+
throw new Error('daemonPublicKeyB64 is required for relay E2EE');
|
|
132
130
|
}
|
|
133
131
|
transportFactory = createRelayE2eeTransportFactory({
|
|
134
132
|
baseFactory: baseTransportFactory,
|
|
@@ -139,7 +137,7 @@ export class DaemonClient {
|
|
|
139
137
|
const transport = transportFactory({ url: this.config.url, headers });
|
|
140
138
|
this.transport = transport;
|
|
141
139
|
this.updateConnectionState({
|
|
142
|
-
status:
|
|
140
|
+
status: 'connecting',
|
|
143
141
|
attempt: this.reconnectAttempt,
|
|
144
142
|
});
|
|
145
143
|
this.transportCleanup = [
|
|
@@ -150,8 +148,7 @@ export class DaemonClient {
|
|
|
150
148
|
}
|
|
151
149
|
this.lastErrorValue = null;
|
|
152
150
|
this.reconnectAttempt = 0;
|
|
153
|
-
this.updateConnectionState({ status:
|
|
154
|
-
this.resubscribeAgentUpdates();
|
|
151
|
+
this.updateConnectionState({ status: 'connected' });
|
|
155
152
|
this.resubscribeCheckoutDiffSubscriptions();
|
|
156
153
|
this.resubscribeTerminalDirectorySubscriptions();
|
|
157
154
|
this.flushPendingSendQueue();
|
|
@@ -163,10 +160,10 @@ export class DaemonClient {
|
|
|
163
160
|
this.pendingGenericTransportErrorTimeout = null;
|
|
164
161
|
}
|
|
165
162
|
const closeRecord = event;
|
|
166
|
-
const closeCode = closeRecord && typeof closeRecord ===
|
|
163
|
+
const closeCode = closeRecord && typeof closeRecord === 'object' && typeof closeRecord.code === 'number'
|
|
167
164
|
? closeRecord.code
|
|
168
165
|
: null;
|
|
169
|
-
const closeReason = closeRecord && typeof closeRecord ===
|
|
166
|
+
const closeReason = closeRecord && typeof closeRecord === 'object' && typeof closeRecord.reason === 'string'
|
|
170
167
|
? closeRecord.reason
|
|
171
168
|
: null;
|
|
172
169
|
const reason = describeTransportClose(event);
|
|
@@ -174,7 +171,7 @@ export class DaemonClient {
|
|
|
174
171
|
this.lastErrorValue = reason;
|
|
175
172
|
}
|
|
176
173
|
this.updateConnectionState({
|
|
177
|
-
status:
|
|
174
|
+
status: 'disconnected',
|
|
178
175
|
...(reason ? { reason } : {}),
|
|
179
176
|
});
|
|
180
177
|
// When connecting over the relay, only one client connection is allowed at a time.
|
|
@@ -182,18 +179,18 @@ export class DaemonClient {
|
|
|
182
179
|
// connection (which causes flapping where both sides repeatedly replace each other).
|
|
183
180
|
if (isRelayClientWebSocketUrl(this.config.url) &&
|
|
184
181
|
closeCode === 1008 &&
|
|
185
|
-
(closeReason ?? reason) ===
|
|
182
|
+
(closeReason ?? reason) === 'Replaced by new connection') {
|
|
186
183
|
this.shouldReconnect = false;
|
|
187
|
-
this.clearWaiters(new Error(reason ??
|
|
188
|
-
this.rejectPendingSendQueue(new Error(reason ??
|
|
189
|
-
this.rejectConnect(new Error(reason ??
|
|
184
|
+
this.clearWaiters(new Error(reason ?? 'Replaced by new connection'));
|
|
185
|
+
this.rejectPendingSendQueue(new Error(reason ?? 'Replaced by new connection'));
|
|
186
|
+
this.rejectConnect(new Error(reason ?? 'Replaced by new connection'));
|
|
190
187
|
return;
|
|
191
188
|
}
|
|
192
189
|
this.scheduleReconnect(reason);
|
|
193
190
|
}),
|
|
194
191
|
transport.onError((event) => {
|
|
195
192
|
const reason = describeTransportError(event);
|
|
196
|
-
const isGeneric = reason ===
|
|
193
|
+
const isGeneric = reason === 'Transport error';
|
|
197
194
|
// Browser WebSocket.onerror often provides no useful details and is followed
|
|
198
195
|
// by a close event (often with code 1006). Prefer surfacing the close details
|
|
199
196
|
// instead of immediately disconnecting with a generic "Transport error".
|
|
@@ -202,10 +199,10 @@ export class DaemonClient {
|
|
|
202
199
|
if (!this.pendingGenericTransportErrorTimeout) {
|
|
203
200
|
this.pendingGenericTransportErrorTimeout = setTimeout(() => {
|
|
204
201
|
this.pendingGenericTransportErrorTimeout = null;
|
|
205
|
-
if (this.connectionState.status ===
|
|
206
|
-
this.connectionState.status ===
|
|
202
|
+
if (this.connectionState.status === 'connected' ||
|
|
203
|
+
this.connectionState.status === 'connecting') {
|
|
207
204
|
this.lastErrorValue = reason;
|
|
208
|
-
this.updateConnectionState({ status:
|
|
205
|
+
this.updateConnectionState({ status: 'disconnected', reason });
|
|
209
206
|
this.scheduleReconnect(reason);
|
|
210
207
|
}
|
|
211
208
|
}, 250);
|
|
@@ -217,14 +214,14 @@ export class DaemonClient {
|
|
|
217
214
|
this.pendingGenericTransportErrorTimeout = null;
|
|
218
215
|
}
|
|
219
216
|
this.lastErrorValue = reason;
|
|
220
|
-
this.updateConnectionState({ status:
|
|
217
|
+
this.updateConnectionState({ status: 'disconnected', reason });
|
|
221
218
|
this.scheduleReconnect(reason);
|
|
222
219
|
}),
|
|
223
220
|
transport.onMessage((data) => this.handleTransportMessage(data)),
|
|
224
221
|
];
|
|
225
222
|
}
|
|
226
223
|
catch (error) {
|
|
227
|
-
const message = error instanceof Error ? error.message :
|
|
224
|
+
const message = error instanceof Error ? error.message : 'Failed to connect';
|
|
228
225
|
this.lastErrorValue = message;
|
|
229
226
|
this.scheduleReconnect(message);
|
|
230
227
|
this.rejectConnect(error instanceof Error ? error : new Error(message));
|
|
@@ -255,20 +252,20 @@ export class DaemonClient {
|
|
|
255
252
|
clearTimeout(this.reconnectTimeout);
|
|
256
253
|
this.reconnectTimeout = null;
|
|
257
254
|
}
|
|
258
|
-
this.disposeTransport(1000,
|
|
259
|
-
this.clearWaiters(new Error(
|
|
255
|
+
this.disposeTransport(1000, 'Client closed');
|
|
256
|
+
this.clearWaiters(new Error('Daemon client closed'));
|
|
260
257
|
this.terminalStreams.clearAll();
|
|
261
258
|
this.updateConnectionState({
|
|
262
|
-
status:
|
|
263
|
-
reason:
|
|
259
|
+
status: 'disconnected',
|
|
260
|
+
reason: 'client_closed',
|
|
264
261
|
});
|
|
265
262
|
}
|
|
266
263
|
ensureConnected() {
|
|
267
264
|
if (!this.shouldReconnect) {
|
|
268
265
|
this.shouldReconnect = true;
|
|
269
266
|
}
|
|
270
|
-
if (this.connectionState.status ===
|
|
271
|
-
this.connectionState.status ===
|
|
267
|
+
if (this.connectionState.status === 'connected' ||
|
|
268
|
+
this.connectionState.status === 'connecting') {
|
|
272
269
|
return;
|
|
273
270
|
}
|
|
274
271
|
void this.connect();
|
|
@@ -284,10 +281,10 @@ export class DaemonClient {
|
|
|
284
281
|
};
|
|
285
282
|
}
|
|
286
283
|
get isConnected() {
|
|
287
|
-
return this.connectionState.status ===
|
|
284
|
+
return this.connectionState.status === 'connected';
|
|
288
285
|
}
|
|
289
286
|
get isConnecting() {
|
|
290
|
-
return this.connectionState.status ===
|
|
287
|
+
return this.connectionState.status === 'connecting';
|
|
291
288
|
}
|
|
292
289
|
get lastError() {
|
|
293
290
|
return this.lastErrorValue;
|
|
@@ -306,7 +303,7 @@ export class DaemonClient {
|
|
|
306
303
|
};
|
|
307
304
|
}
|
|
308
305
|
on(arg1, arg2) {
|
|
309
|
-
if (typeof arg1 ===
|
|
306
|
+
if (typeof arg1 === 'function') {
|
|
310
307
|
return this.subscribe(arg1);
|
|
311
308
|
}
|
|
312
309
|
const type = arg1;
|
|
@@ -335,7 +332,7 @@ export class DaemonClient {
|
|
|
335
332
|
* For RPC methods that wait for responses, use `sendSessionMessageOrThrow` instead.
|
|
336
333
|
*/
|
|
337
334
|
sendSessionMessage(message) {
|
|
338
|
-
if (!this.transport || this.connectionState.status !==
|
|
335
|
+
if (!this.transport || this.connectionState.status !== 'connected') {
|
|
339
336
|
if (this.config.suppressSendErrors) {
|
|
340
337
|
return;
|
|
341
338
|
}
|
|
@@ -343,7 +340,7 @@ export class DaemonClient {
|
|
|
343
340
|
}
|
|
344
341
|
const payload = SessionInboundMessageSchema.parse(message);
|
|
345
342
|
try {
|
|
346
|
-
this.transport.send(JSON.stringify({ type:
|
|
343
|
+
this.transport.send(JSON.stringify({ type: 'session', message: payload }));
|
|
347
344
|
}
|
|
348
345
|
catch (error) {
|
|
349
346
|
if (this.config.suppressSendErrors) {
|
|
@@ -353,7 +350,7 @@ export class DaemonClient {
|
|
|
353
350
|
}
|
|
354
351
|
}
|
|
355
352
|
sendBinaryFrame(frame) {
|
|
356
|
-
if (!this.transport || this.connectionState.status !==
|
|
353
|
+
if (!this.transport || this.connectionState.status !== 'connected') {
|
|
357
354
|
if (this.config.suppressSendErrors) {
|
|
358
355
|
return;
|
|
359
356
|
}
|
|
@@ -378,13 +375,13 @@ export class DaemonClient {
|
|
|
378
375
|
sendSessionMessageOrThrow(message) {
|
|
379
376
|
const status = this.connectionState.status;
|
|
380
377
|
// If connected, send immediately
|
|
381
|
-
if (this.transport && status ===
|
|
378
|
+
if (this.transport && status === 'connected') {
|
|
382
379
|
const payload = SessionInboundMessageSchema.parse(message);
|
|
383
|
-
this.transport.send(JSON.stringify({ type:
|
|
380
|
+
this.transport.send(JSON.stringify({ type: 'session', message: payload }));
|
|
384
381
|
return Promise.resolve();
|
|
385
382
|
}
|
|
386
383
|
// If connecting, queue the message to be sent once connected
|
|
387
|
-
if (status ===
|
|
384
|
+
if (status === 'connecting') {
|
|
388
385
|
return new Promise((resolve, reject) => {
|
|
389
386
|
const timeoutHandle = setTimeout(() => {
|
|
390
387
|
// Remove from queue
|
|
@@ -409,13 +406,13 @@ export class DaemonClient {
|
|
|
409
406
|
for (const pending of queue) {
|
|
410
407
|
clearTimeout(pending.timeoutHandle);
|
|
411
408
|
try {
|
|
412
|
-
if (this.transport && this.connectionState.status ===
|
|
409
|
+
if (this.transport && this.connectionState.status === 'connected') {
|
|
413
410
|
const payload = SessionInboundMessageSchema.parse(pending.message);
|
|
414
|
-
this.transport.send(JSON.stringify({ type:
|
|
411
|
+
this.transport.send(JSON.stringify({ type: 'session', message: payload }));
|
|
415
412
|
pending.resolve();
|
|
416
413
|
}
|
|
417
414
|
else {
|
|
418
|
-
pending.reject(new Error(
|
|
415
|
+
pending.reject(new Error('Connection lost before message could be sent'));
|
|
419
416
|
}
|
|
420
417
|
}
|
|
421
418
|
catch (error) {
|
|
@@ -436,9 +433,9 @@ export class DaemonClient {
|
|
|
436
433
|
}
|
|
437
434
|
async sendRequest(params) {
|
|
438
435
|
const { promise, cancel } = this.waitForWithCancel((msg) => {
|
|
439
|
-
if (msg.type ===
|
|
436
|
+
if (msg.type === 'rpc_error' && msg.payload.requestId === params.requestId) {
|
|
440
437
|
return {
|
|
441
|
-
kind:
|
|
438
|
+
kind: 'error',
|
|
442
439
|
error: new DaemonRpcError({
|
|
443
440
|
requestId: msg.payload.requestId,
|
|
444
441
|
error: msg.payload.error,
|
|
@@ -451,7 +448,7 @@ export class DaemonClient {
|
|
|
451
448
|
if (value === null) {
|
|
452
449
|
return null;
|
|
453
450
|
}
|
|
454
|
-
return { kind:
|
|
451
|
+
return { kind: 'ok', value };
|
|
455
452
|
}, params.timeout, params.options);
|
|
456
453
|
try {
|
|
457
454
|
await this.sendSessionMessageOrThrow(params.message);
|
|
@@ -463,7 +460,7 @@ export class DaemonClient {
|
|
|
463
460
|
throw err;
|
|
464
461
|
}
|
|
465
462
|
const result = await promise;
|
|
466
|
-
if (result.kind ===
|
|
463
|
+
if (result.kind === 'error') {
|
|
467
464
|
throw result.error;
|
|
468
465
|
}
|
|
469
466
|
return result.value;
|
|
@@ -506,23 +503,23 @@ export class DaemonClient {
|
|
|
506
503
|
});
|
|
507
504
|
}
|
|
508
505
|
sendSessionMessageStrict(message) {
|
|
509
|
-
if (!this.transport || this.connectionState.status !==
|
|
510
|
-
throw new Error(
|
|
506
|
+
if (!this.transport || this.connectionState.status !== 'connected') {
|
|
507
|
+
throw new Error('Transport not connected');
|
|
511
508
|
}
|
|
512
509
|
const payload = SessionInboundMessageSchema.parse(message);
|
|
513
510
|
try {
|
|
514
|
-
this.transport.send(JSON.stringify({ type:
|
|
511
|
+
this.transport.send(JSON.stringify({ type: 'session', message: payload }));
|
|
515
512
|
}
|
|
516
513
|
catch (error) {
|
|
517
514
|
throw error instanceof Error ? error : new Error(String(error));
|
|
518
515
|
}
|
|
519
516
|
}
|
|
520
517
|
clearAgentAttention(agentId) {
|
|
521
|
-
this.sendSessionMessage({ type:
|
|
518
|
+
this.sendSessionMessage({ type: 'clear_agent_attention', agentId });
|
|
522
519
|
}
|
|
523
520
|
sendHeartbeat(params) {
|
|
524
521
|
this.sendSessionMessage({
|
|
525
|
-
type:
|
|
522
|
+
type: 'client_heartbeat',
|
|
526
523
|
deviceType: params.deviceType,
|
|
527
524
|
focusedAgentId: params.focusedAgentId,
|
|
528
525
|
lastActivityAt: params.lastActivityAt,
|
|
@@ -532,26 +529,25 @@ export class DaemonClient {
|
|
|
532
529
|
}
|
|
533
530
|
registerPushToken(token) {
|
|
534
531
|
this.sendSessionMessage({
|
|
535
|
-
type:
|
|
532
|
+
type: 'register_push_token',
|
|
536
533
|
token,
|
|
537
534
|
});
|
|
538
535
|
}
|
|
539
536
|
async ping(params) {
|
|
540
|
-
const requestId = params?.requestId ??
|
|
541
|
-
`ping-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
537
|
+
const requestId = params?.requestId ?? `ping-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
542
538
|
const clientSentAt = Date.now();
|
|
543
539
|
const payload = await this.sendRequest({
|
|
544
540
|
requestId,
|
|
545
|
-
message: { type:
|
|
541
|
+
message: { type: 'ping', requestId, clientSentAt },
|
|
546
542
|
timeout: params?.timeoutMs ?? 5000,
|
|
547
543
|
select: (msg) => {
|
|
548
|
-
if (msg.type !==
|
|
544
|
+
if (msg.type !== 'pong')
|
|
549
545
|
return null;
|
|
550
546
|
if (msg.payload.requestId !== requestId)
|
|
551
547
|
return null;
|
|
552
|
-
if (typeof msg.payload.serverReceivedAt !==
|
|
548
|
+
if (typeof msg.payload.serverReceivedAt !== 'number')
|
|
553
549
|
return null;
|
|
554
|
-
if (typeof msg.payload.serverSentAt !==
|
|
550
|
+
if (typeof msg.payload.serverSentAt !== 'number')
|
|
555
551
|
return null;
|
|
556
552
|
return msg.payload;
|
|
557
553
|
},
|
|
@@ -570,11 +566,12 @@ export class DaemonClient {
|
|
|
570
566
|
async fetchAgents(options) {
|
|
571
567
|
const resolvedRequestId = this.createRequestId(options?.requestId);
|
|
572
568
|
const message = SessionInboundMessageSchema.parse({
|
|
573
|
-
type:
|
|
569
|
+
type: 'fetch_agents_request',
|
|
574
570
|
requestId: resolvedRequestId,
|
|
575
571
|
...(options?.filter ? { filter: options.filter } : {}),
|
|
576
572
|
...(options?.sort ? { sort: options.sort } : {}),
|
|
577
573
|
...(options?.page ? { page: options.page } : {}),
|
|
574
|
+
...(options?.subscribe ? { subscribe: options.subscribe } : {}),
|
|
578
575
|
});
|
|
579
576
|
return this.sendRequest({
|
|
580
577
|
requestId: resolvedRequestId,
|
|
@@ -582,7 +579,7 @@ export class DaemonClient {
|
|
|
582
579
|
timeout: 10000,
|
|
583
580
|
options: { skipQueue: true },
|
|
584
581
|
select: (msg) => {
|
|
585
|
-
if (msg.type !==
|
|
582
|
+
if (msg.type !== 'fetch_agents_response') {
|
|
586
583
|
return null;
|
|
587
584
|
}
|
|
588
585
|
if (msg.payload.requestId !== resolvedRequestId) {
|
|
@@ -595,7 +592,7 @@ export class DaemonClient {
|
|
|
595
592
|
async fetchAgent(agentId, requestId) {
|
|
596
593
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
597
594
|
const message = SessionInboundMessageSchema.parse({
|
|
598
|
-
type:
|
|
595
|
+
type: 'fetch_agent_request',
|
|
599
596
|
requestId: resolvedRequestId,
|
|
600
597
|
agentId,
|
|
601
598
|
});
|
|
@@ -605,7 +602,7 @@ export class DaemonClient {
|
|
|
605
602
|
timeout: 10000,
|
|
606
603
|
options: { skipQueue: true },
|
|
607
604
|
select: (msg) => {
|
|
608
|
-
if (msg.type !==
|
|
605
|
+
if (msg.type !== 'fetch_agent_response') {
|
|
609
606
|
return null;
|
|
610
607
|
}
|
|
611
608
|
if (msg.payload.requestId !== resolvedRequestId) {
|
|
@@ -619,45 +616,13 @@ export class DaemonClient {
|
|
|
619
616
|
}
|
|
620
617
|
return payload.agent;
|
|
621
618
|
}
|
|
622
|
-
subscribeAgentUpdates(options) {
|
|
623
|
-
const subscriptionId = options?.subscriptionId ?? crypto.randomUUID();
|
|
624
|
-
this.agentUpdateSubscriptions.set(subscriptionId, options?.filter);
|
|
625
|
-
const message = SessionInboundMessageSchema.parse({
|
|
626
|
-
type: "subscribe_agent_updates",
|
|
627
|
-
subscriptionId,
|
|
628
|
-
...(options?.filter ? { filter: options.filter } : {}),
|
|
629
|
-
});
|
|
630
|
-
this.sendSessionMessage(message);
|
|
631
|
-
return subscriptionId;
|
|
632
|
-
}
|
|
633
|
-
unsubscribeAgentUpdates(subscriptionId) {
|
|
634
|
-
this.agentUpdateSubscriptions.delete(subscriptionId);
|
|
635
|
-
const message = SessionInboundMessageSchema.parse({
|
|
636
|
-
type: "unsubscribe_agent_updates",
|
|
637
|
-
subscriptionId,
|
|
638
|
-
});
|
|
639
|
-
this.sendSessionMessage(message);
|
|
640
|
-
}
|
|
641
|
-
resubscribeAgentUpdates() {
|
|
642
|
-
if (this.agentUpdateSubscriptions.size === 0) {
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
for (const [subscriptionId, filter] of this.agentUpdateSubscriptions) {
|
|
646
|
-
const message = SessionInboundMessageSchema.parse({
|
|
647
|
-
type: "subscribe_agent_updates",
|
|
648
|
-
subscriptionId,
|
|
649
|
-
...(filter ? { filter } : {}),
|
|
650
|
-
});
|
|
651
|
-
this.sendSessionMessage(message);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
619
|
resubscribeCheckoutDiffSubscriptions() {
|
|
655
620
|
if (this.checkoutDiffSubscriptions.size === 0) {
|
|
656
621
|
return;
|
|
657
622
|
}
|
|
658
623
|
for (const [subscriptionId, subscription] of this.checkoutDiffSubscriptions) {
|
|
659
624
|
const message = SessionInboundMessageSchema.parse({
|
|
660
|
-
type:
|
|
625
|
+
type: 'subscribe_checkout_diff_request',
|
|
661
626
|
subscriptionId,
|
|
662
627
|
cwd: subscription.cwd,
|
|
663
628
|
compare: subscription.compare,
|
|
@@ -672,7 +637,7 @@ export class DaemonClient {
|
|
|
672
637
|
}
|
|
673
638
|
for (const cwd of this.terminalDirectorySubscriptions) {
|
|
674
639
|
this.sendSessionMessage({
|
|
675
|
-
type:
|
|
640
|
+
type: 'subscribe_terminals_request',
|
|
676
641
|
cwd,
|
|
677
642
|
});
|
|
678
643
|
}
|
|
@@ -684,14 +649,12 @@ export class DaemonClient {
|
|
|
684
649
|
const requestId = this.createRequestId(options.requestId);
|
|
685
650
|
const config = resolveAgentConfig(options);
|
|
686
651
|
const message = SessionInboundMessageSchema.parse({
|
|
687
|
-
type:
|
|
652
|
+
type: 'create_agent_request',
|
|
688
653
|
requestId,
|
|
689
654
|
config,
|
|
690
655
|
...(options.initialPrompt ? { initialPrompt: options.initialPrompt } : {}),
|
|
691
656
|
...(options.outputSchema ? { outputSchema: options.outputSchema } : {}),
|
|
692
|
-
...(options.images && options.images.length > 0
|
|
693
|
-
? { images: options.images }
|
|
694
|
-
: {}),
|
|
657
|
+
...(options.images && options.images.length > 0 ? { images: options.images } : {}),
|
|
695
658
|
...(options.git ? { git: options.git } : {}),
|
|
696
659
|
...(options.worktreeName ? { worktreeName: options.worktreeName } : {}),
|
|
697
660
|
...(options.labels && Object.keys(options.labels).length > 0
|
|
@@ -704,7 +667,7 @@ export class DaemonClient {
|
|
|
704
667
|
timeout: 15000,
|
|
705
668
|
options: { skipQueue: true },
|
|
706
669
|
select: (msg) => {
|
|
707
|
-
if (msg.type !==
|
|
670
|
+
if (msg.type !== 'status') {
|
|
708
671
|
return null;
|
|
709
672
|
}
|
|
710
673
|
const created = AgentCreatedStatusPayloadSchema.safeParse(msg.payload);
|
|
@@ -718,7 +681,7 @@ export class DaemonClient {
|
|
|
718
681
|
return null;
|
|
719
682
|
},
|
|
720
683
|
});
|
|
721
|
-
if (status.status ===
|
|
684
|
+
if (status.status === 'agent_create_failed') {
|
|
722
685
|
throw new Error(status.error);
|
|
723
686
|
}
|
|
724
687
|
return status.agent;
|
|
@@ -726,7 +689,7 @@ export class DaemonClient {
|
|
|
726
689
|
async deleteAgent(agentId) {
|
|
727
690
|
const requestId = this.createRequestId();
|
|
728
691
|
const message = SessionInboundMessageSchema.parse({
|
|
729
|
-
type:
|
|
692
|
+
type: 'delete_agent_request',
|
|
730
693
|
agentId,
|
|
731
694
|
requestId,
|
|
732
695
|
});
|
|
@@ -736,7 +699,7 @@ export class DaemonClient {
|
|
|
736
699
|
timeout: 10000,
|
|
737
700
|
options: { skipQueue: true },
|
|
738
701
|
select: (msg) => {
|
|
739
|
-
if (msg.type !==
|
|
702
|
+
if (msg.type !== 'agent_deleted') {
|
|
740
703
|
return null;
|
|
741
704
|
}
|
|
742
705
|
if (msg.payload.requestId !== requestId) {
|
|
@@ -749,7 +712,7 @@ export class DaemonClient {
|
|
|
749
712
|
async archiveAgent(agentId) {
|
|
750
713
|
const requestId = this.createRequestId();
|
|
751
714
|
const message = SessionInboundMessageSchema.parse({
|
|
752
|
-
type:
|
|
715
|
+
type: 'archive_agent_request',
|
|
753
716
|
agentId,
|
|
754
717
|
requestId,
|
|
755
718
|
});
|
|
@@ -759,7 +722,7 @@ export class DaemonClient {
|
|
|
759
722
|
timeout: 10000,
|
|
760
723
|
options: { skipQueue: true },
|
|
761
724
|
select: (msg) => {
|
|
762
|
-
if (msg.type !==
|
|
725
|
+
if (msg.type !== 'agent_archived') {
|
|
763
726
|
return null;
|
|
764
727
|
}
|
|
765
728
|
if (msg.payload.requestId !== requestId) {
|
|
@@ -773,7 +736,7 @@ export class DaemonClient {
|
|
|
773
736
|
async updateAgent(agentId, updates) {
|
|
774
737
|
const requestId = this.createRequestId();
|
|
775
738
|
const message = SessionInboundMessageSchema.parse({
|
|
776
|
-
type:
|
|
739
|
+
type: 'update_agent_request',
|
|
777
740
|
agentId,
|
|
778
741
|
...(updates.name !== undefined ? { name: updates.name } : {}),
|
|
779
742
|
...(updates.labels && Object.keys(updates.labels).length > 0
|
|
@@ -787,7 +750,7 @@ export class DaemonClient {
|
|
|
787
750
|
timeout: 10000,
|
|
788
751
|
options: { skipQueue: true },
|
|
789
752
|
select: (msg) => {
|
|
790
|
-
if (msg.type !==
|
|
753
|
+
if (msg.type !== 'update_agent_response') {
|
|
791
754
|
return null;
|
|
792
755
|
}
|
|
793
756
|
if (msg.payload.requestId !== requestId) {
|
|
@@ -797,13 +760,13 @@ export class DaemonClient {
|
|
|
797
760
|
},
|
|
798
761
|
});
|
|
799
762
|
if (!payload.accepted) {
|
|
800
|
-
throw new Error(payload.error ??
|
|
763
|
+
throw new Error(payload.error ?? 'updateAgent rejected');
|
|
801
764
|
}
|
|
802
765
|
}
|
|
803
766
|
async resumeAgent(handle, overrides) {
|
|
804
767
|
const requestId = this.createRequestId();
|
|
805
768
|
const message = SessionInboundMessageSchema.parse({
|
|
806
|
-
type:
|
|
769
|
+
type: 'resume_agent_request',
|
|
807
770
|
requestId,
|
|
808
771
|
handle,
|
|
809
772
|
...(overrides ? { overrides } : {}),
|
|
@@ -814,7 +777,7 @@ export class DaemonClient {
|
|
|
814
777
|
timeout: 15000,
|
|
815
778
|
options: { skipQueue: true },
|
|
816
779
|
select: (msg) => {
|
|
817
|
-
if (msg.type !==
|
|
780
|
+
if (msg.type !== 'status') {
|
|
818
781
|
return null;
|
|
819
782
|
}
|
|
820
783
|
const resumed = AgentResumedStatusPayloadSchema.safeParse(msg.payload);
|
|
@@ -829,7 +792,7 @@ export class DaemonClient {
|
|
|
829
792
|
async refreshAgent(agentId, requestId) {
|
|
830
793
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
831
794
|
const message = SessionInboundMessageSchema.parse({
|
|
832
|
-
type:
|
|
795
|
+
type: 'refresh_agent_request',
|
|
833
796
|
agentId,
|
|
834
797
|
requestId: resolvedRequestId,
|
|
835
798
|
});
|
|
@@ -839,7 +802,7 @@ export class DaemonClient {
|
|
|
839
802
|
timeout: 15000,
|
|
840
803
|
options: { skipQueue: true },
|
|
841
804
|
select: (msg) => {
|
|
842
|
-
if (msg.type !==
|
|
805
|
+
if (msg.type !== 'status') {
|
|
843
806
|
return null;
|
|
844
807
|
}
|
|
845
808
|
const refreshed = AgentRefreshedStatusPayloadSchema.safeParse(msg.payload);
|
|
@@ -853,12 +816,12 @@ export class DaemonClient {
|
|
|
853
816
|
async fetchAgentTimeline(agentId, options = {}) {
|
|
854
817
|
const resolvedRequestId = this.createRequestId(options.requestId);
|
|
855
818
|
const message = SessionInboundMessageSchema.parse({
|
|
856
|
-
type:
|
|
819
|
+
type: 'fetch_agent_timeline_request',
|
|
857
820
|
agentId,
|
|
858
821
|
requestId: resolvedRequestId,
|
|
859
822
|
...(options.direction ? { direction: options.direction } : {}),
|
|
860
823
|
...(options.cursor ? { cursor: options.cursor } : {}),
|
|
861
|
-
...(typeof options.limit ===
|
|
824
|
+
...(typeof options.limit === 'number' ? { limit: options.limit } : {}),
|
|
862
825
|
...(options.projection ? { projection: options.projection } : {}),
|
|
863
826
|
});
|
|
864
827
|
const payload = await this.sendRequest({
|
|
@@ -867,7 +830,7 @@ export class DaemonClient {
|
|
|
867
830
|
timeout: 15000,
|
|
868
831
|
options: { skipQueue: true },
|
|
869
832
|
select: (msg) => {
|
|
870
|
-
if (msg.type !==
|
|
833
|
+
if (msg.type !== 'fetch_agent_timeline_response') {
|
|
871
834
|
return null;
|
|
872
835
|
}
|
|
873
836
|
if (msg.payload.requestId !== resolvedRequestId) {
|
|
@@ -888,7 +851,7 @@ export class DaemonClient {
|
|
|
888
851
|
const requestId = this.createRequestId();
|
|
889
852
|
const messageId = options?.messageId ?? crypto.randomUUID();
|
|
890
853
|
const message = SessionInboundMessageSchema.parse({
|
|
891
|
-
type:
|
|
854
|
+
type: 'send_agent_message_request',
|
|
892
855
|
requestId,
|
|
893
856
|
agentId,
|
|
894
857
|
text,
|
|
@@ -901,7 +864,7 @@ export class DaemonClient {
|
|
|
901
864
|
timeout: 15000,
|
|
902
865
|
options: { skipQueue: true },
|
|
903
866
|
select: (msg) => {
|
|
904
|
-
if (msg.type !==
|
|
867
|
+
if (msg.type !== 'send_agent_message_response') {
|
|
905
868
|
return null;
|
|
906
869
|
}
|
|
907
870
|
if (msg.payload.requestId !== requestId) {
|
|
@@ -911,19 +874,19 @@ export class DaemonClient {
|
|
|
911
874
|
},
|
|
912
875
|
});
|
|
913
876
|
if (!payload.accepted) {
|
|
914
|
-
throw new Error(payload.error ??
|
|
877
|
+
throw new Error(payload.error ?? 'sendAgentMessage rejected');
|
|
915
878
|
}
|
|
916
879
|
}
|
|
917
880
|
async sendMessage(agentId, text, options) {
|
|
918
881
|
await this.sendAgentMessage(agentId, text, options);
|
|
919
882
|
}
|
|
920
883
|
async cancelAgent(agentId) {
|
|
921
|
-
this.sendSessionMessage({ type:
|
|
884
|
+
this.sendSessionMessage({ type: 'cancel_agent_request', agentId });
|
|
922
885
|
}
|
|
923
886
|
async setAgentMode(agentId, modeId) {
|
|
924
887
|
const requestId = this.createRequestId();
|
|
925
888
|
const message = SessionInboundMessageSchema.parse({
|
|
926
|
-
type:
|
|
889
|
+
type: 'set_agent_mode_request',
|
|
927
890
|
agentId,
|
|
928
891
|
modeId,
|
|
929
892
|
requestId,
|
|
@@ -934,7 +897,7 @@ export class DaemonClient {
|
|
|
934
897
|
timeout: 15000,
|
|
935
898
|
options: { skipQueue: true },
|
|
936
899
|
select: (msg) => {
|
|
937
|
-
if (msg.type !==
|
|
900
|
+
if (msg.type !== 'set_agent_mode_response') {
|
|
938
901
|
return null;
|
|
939
902
|
}
|
|
940
903
|
if (msg.payload.requestId !== requestId) {
|
|
@@ -944,13 +907,13 @@ export class DaemonClient {
|
|
|
944
907
|
},
|
|
945
908
|
});
|
|
946
909
|
if (!payload.accepted) {
|
|
947
|
-
throw new Error(payload.error ??
|
|
910
|
+
throw new Error(payload.error ?? 'setAgentMode rejected');
|
|
948
911
|
}
|
|
949
912
|
}
|
|
950
913
|
async setAgentModel(agentId, modelId) {
|
|
951
914
|
const requestId = this.createRequestId();
|
|
952
915
|
const message = SessionInboundMessageSchema.parse({
|
|
953
|
-
type:
|
|
916
|
+
type: 'set_agent_model_request',
|
|
954
917
|
agentId,
|
|
955
918
|
modelId,
|
|
956
919
|
requestId,
|
|
@@ -961,7 +924,7 @@ export class DaemonClient {
|
|
|
961
924
|
timeout: 15000,
|
|
962
925
|
options: { skipQueue: true },
|
|
963
926
|
select: (msg) => {
|
|
964
|
-
if (msg.type !==
|
|
927
|
+
if (msg.type !== 'set_agent_model_response') {
|
|
965
928
|
return null;
|
|
966
929
|
}
|
|
967
930
|
if (msg.payload.requestId !== requestId) {
|
|
@@ -971,13 +934,13 @@ export class DaemonClient {
|
|
|
971
934
|
},
|
|
972
935
|
});
|
|
973
936
|
if (!payload.accepted) {
|
|
974
|
-
throw new Error(payload.error ??
|
|
937
|
+
throw new Error(payload.error ?? 'setAgentModel rejected');
|
|
975
938
|
}
|
|
976
939
|
}
|
|
977
940
|
async setAgentThinkingOption(agentId, thinkingOptionId) {
|
|
978
941
|
const requestId = this.createRequestId();
|
|
979
942
|
const message = SessionInboundMessageSchema.parse({
|
|
980
|
-
type:
|
|
943
|
+
type: 'set_agent_thinking_request',
|
|
981
944
|
agentId,
|
|
982
945
|
thinkingOptionId,
|
|
983
946
|
requestId,
|
|
@@ -988,7 +951,7 @@ export class DaemonClient {
|
|
|
988
951
|
timeout: 15000,
|
|
989
952
|
options: { skipQueue: true },
|
|
990
953
|
select: (msg) => {
|
|
991
|
-
if (msg.type !==
|
|
954
|
+
if (msg.type !== 'set_agent_thinking_response') {
|
|
992
955
|
return null;
|
|
993
956
|
}
|
|
994
957
|
if (msg.payload.requestId !== requestId) {
|
|
@@ -998,13 +961,13 @@ export class DaemonClient {
|
|
|
998
961
|
},
|
|
999
962
|
});
|
|
1000
963
|
if (!payload.accepted) {
|
|
1001
|
-
throw new Error(payload.error ??
|
|
964
|
+
throw new Error(payload.error ?? 'setAgentThinkingOption rejected');
|
|
1002
965
|
}
|
|
1003
966
|
}
|
|
1004
967
|
async restartServer(reason, requestId) {
|
|
1005
968
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
1006
969
|
const message = SessionInboundMessageSchema.parse({
|
|
1007
|
-
type:
|
|
970
|
+
type: 'restart_server_request',
|
|
1008
971
|
...(reason && reason.trim().length > 0 ? { reason } : {}),
|
|
1009
972
|
requestId: resolvedRequestId,
|
|
1010
973
|
});
|
|
@@ -1014,7 +977,7 @@ export class DaemonClient {
|
|
|
1014
977
|
timeout: 10000,
|
|
1015
978
|
options: { skipQueue: true },
|
|
1016
979
|
select: (msg) => {
|
|
1017
|
-
if (msg.type !==
|
|
980
|
+
if (msg.type !== 'status') {
|
|
1018
981
|
return null;
|
|
1019
982
|
}
|
|
1020
983
|
const restarted = RestartRequestedStatusPayloadSchema.safeParse(msg.payload);
|
|
@@ -1034,7 +997,7 @@ export class DaemonClient {
|
|
|
1034
997
|
async setVoiceMode(enabled, agentId) {
|
|
1035
998
|
const requestId = this.createRequestId();
|
|
1036
999
|
const message = SessionInboundMessageSchema.parse({
|
|
1037
|
-
type:
|
|
1000
|
+
type: 'set_voice_mode',
|
|
1038
1001
|
enabled,
|
|
1039
1002
|
...(agentId ? { agentId } : {}),
|
|
1040
1003
|
requestId,
|
|
@@ -1044,7 +1007,7 @@ export class DaemonClient {
|
|
|
1044
1007
|
message,
|
|
1045
1008
|
timeout: 10000,
|
|
1046
1009
|
select: (msg) => {
|
|
1047
|
-
if (msg.type !==
|
|
1010
|
+
if (msg.type !== 'set_voice_mode_response') {
|
|
1048
1011
|
return null;
|
|
1049
1012
|
}
|
|
1050
1013
|
if (msg.payload.requestId !== requestId) {
|
|
@@ -1054,19 +1017,19 @@ export class DaemonClient {
|
|
|
1054
1017
|
},
|
|
1055
1018
|
});
|
|
1056
1019
|
if (!response.accepted) {
|
|
1057
|
-
const codeSuffix = typeof response.reasonCode ===
|
|
1020
|
+
const codeSuffix = typeof response.reasonCode === 'string' && response.reasonCode.trim().length > 0
|
|
1058
1021
|
? ` (${response.reasonCode})`
|
|
1059
|
-
:
|
|
1060
|
-
throw new Error((response.error ??
|
|
1022
|
+
: '';
|
|
1023
|
+
throw new Error((response.error ?? 'Failed to set voice mode') + codeSuffix);
|
|
1061
1024
|
}
|
|
1062
1025
|
return response;
|
|
1063
1026
|
}
|
|
1064
1027
|
async sendVoiceAudioChunk(audio, format, isLast) {
|
|
1065
|
-
this.sendSessionMessage({ type:
|
|
1028
|
+
this.sendSessionMessage({ type: 'voice_audio_chunk', audio, format, isLast });
|
|
1066
1029
|
}
|
|
1067
1030
|
async startDictationStream(dictationId, format) {
|
|
1068
1031
|
const ack = this.waitForWithCancel((msg) => {
|
|
1069
|
-
if (msg.type !==
|
|
1032
|
+
if (msg.type !== 'dictation_stream_ack') {
|
|
1070
1033
|
return null;
|
|
1071
1034
|
}
|
|
1072
1035
|
if (msg.payload.dictationId !== dictationId) {
|
|
@@ -1079,7 +1042,7 @@ export class DaemonClient {
|
|
|
1079
1042
|
}, 30000, { skipQueue: true });
|
|
1080
1043
|
const ackPromise = ack.promise.then(() => undefined);
|
|
1081
1044
|
const streamError = this.waitForWithCancel((msg) => {
|
|
1082
|
-
if (msg.type !==
|
|
1045
|
+
if (msg.type !== 'dictation_stream_error') {
|
|
1083
1046
|
return null;
|
|
1084
1047
|
}
|
|
1085
1048
|
if (msg.payload.dictationId !== dictationId) {
|
|
@@ -1090,9 +1053,9 @@ export class DaemonClient {
|
|
|
1090
1053
|
const errorPromise = streamError.promise.then((payload) => {
|
|
1091
1054
|
throw new Error(payload.error);
|
|
1092
1055
|
});
|
|
1093
|
-
const cleanupError = new Error(
|
|
1056
|
+
const cleanupError = new Error('Cancelled dictation start waiter');
|
|
1094
1057
|
try {
|
|
1095
|
-
this.sendSessionMessageStrict({ type:
|
|
1058
|
+
this.sendSessionMessageStrict({ type: 'dictation_stream_start', dictationId, format });
|
|
1096
1059
|
await Promise.race([ackPromise, errorPromise]);
|
|
1097
1060
|
}
|
|
1098
1061
|
finally {
|
|
@@ -1103,11 +1066,17 @@ export class DaemonClient {
|
|
|
1103
1066
|
}
|
|
1104
1067
|
}
|
|
1105
1068
|
sendDictationStreamChunk(dictationId, seq, audio, format) {
|
|
1106
|
-
this.sendSessionMessageStrict({
|
|
1069
|
+
this.sendSessionMessageStrict({
|
|
1070
|
+
type: 'dictation_stream_chunk',
|
|
1071
|
+
dictationId,
|
|
1072
|
+
seq,
|
|
1073
|
+
audio,
|
|
1074
|
+
format,
|
|
1075
|
+
});
|
|
1107
1076
|
}
|
|
1108
1077
|
async finishDictationStream(dictationId, finalSeq) {
|
|
1109
1078
|
const final = this.waitForWithCancel((msg) => {
|
|
1110
|
-
if (msg.type !==
|
|
1079
|
+
if (msg.type !== 'dictation_stream_final') {
|
|
1111
1080
|
return null;
|
|
1112
1081
|
}
|
|
1113
1082
|
if (msg.payload.dictationId !== dictationId) {
|
|
@@ -1116,7 +1085,7 @@ export class DaemonClient {
|
|
|
1116
1085
|
return msg.payload;
|
|
1117
1086
|
}, 0, { skipQueue: true });
|
|
1118
1087
|
const streamError = this.waitForWithCancel((msg) => {
|
|
1119
|
-
if (msg.type !==
|
|
1088
|
+
if (msg.type !== 'dictation_stream_error') {
|
|
1120
1089
|
return null;
|
|
1121
1090
|
}
|
|
1122
1091
|
if (msg.payload.dictationId !== dictationId) {
|
|
@@ -1125,7 +1094,7 @@ export class DaemonClient {
|
|
|
1125
1094
|
return msg.payload;
|
|
1126
1095
|
}, 0, { skipQueue: true });
|
|
1127
1096
|
const finishAccepted = this.waitForWithCancel((msg) => {
|
|
1128
|
-
if (msg.type !==
|
|
1097
|
+
if (msg.type !== 'dictation_stream_finish_accepted') {
|
|
1129
1098
|
return null;
|
|
1130
1099
|
}
|
|
1131
1100
|
if (msg.payload.dictationId !== dictationId) {
|
|
@@ -1139,68 +1108,64 @@ export class DaemonClient {
|
|
|
1139
1108
|
});
|
|
1140
1109
|
const finishAcceptedPromise = finishAccepted.promise;
|
|
1141
1110
|
const finalOutcomePromise = finalPromise.then((payload) => ({
|
|
1142
|
-
kind:
|
|
1111
|
+
kind: 'final',
|
|
1143
1112
|
payload,
|
|
1144
1113
|
}));
|
|
1145
1114
|
const errorOutcomePromise = errorPromise.then(() => ({
|
|
1146
|
-
kind:
|
|
1147
|
-
error: new Error(
|
|
1115
|
+
kind: 'error',
|
|
1116
|
+
error: new Error('Unexpected dictation stream error state'),
|
|
1148
1117
|
}), (error) => ({
|
|
1149
|
-
kind:
|
|
1118
|
+
kind: 'error',
|
|
1150
1119
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
1151
1120
|
}));
|
|
1152
|
-
const finishAcceptedOutcomePromise = finishAcceptedPromise.then((payload) => ({ kind:
|
|
1121
|
+
const finishAcceptedOutcomePromise = finishAcceptedPromise.then((payload) => ({ kind: 'accepted', payload }), (error) => {
|
|
1153
1122
|
if (isWaiterTimeoutError(error)) {
|
|
1154
|
-
return { kind:
|
|
1123
|
+
return { kind: 'accepted_timeout' };
|
|
1155
1124
|
}
|
|
1156
1125
|
return {
|
|
1157
|
-
kind:
|
|
1126
|
+
kind: 'accepted_error',
|
|
1158
1127
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
1159
1128
|
};
|
|
1160
1129
|
});
|
|
1161
1130
|
const waitForFinalResult = async (timeoutMs) => {
|
|
1162
1131
|
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
1163
1132
|
const outcome = await Promise.race([finalOutcomePromise, errorOutcomePromise]);
|
|
1164
|
-
if (outcome.kind ===
|
|
1133
|
+
if (outcome.kind === 'error') {
|
|
1165
1134
|
throw outcome.error;
|
|
1166
1135
|
}
|
|
1167
1136
|
return outcome.payload;
|
|
1168
1137
|
}
|
|
1169
1138
|
let timeoutHandle = null;
|
|
1170
1139
|
const timeoutPromise = new Promise((resolve) => {
|
|
1171
|
-
timeoutHandle = setTimeout(() => resolve({ kind:
|
|
1140
|
+
timeoutHandle = setTimeout(() => resolve({ kind: 'timeout' }), timeoutMs);
|
|
1172
1141
|
});
|
|
1173
|
-
const outcome = await Promise.race([
|
|
1174
|
-
finalOutcomePromise,
|
|
1175
|
-
errorOutcomePromise,
|
|
1176
|
-
timeoutPromise,
|
|
1177
|
-
]);
|
|
1142
|
+
const outcome = await Promise.race([finalOutcomePromise, errorOutcomePromise, timeoutPromise]);
|
|
1178
1143
|
if (timeoutHandle) {
|
|
1179
1144
|
clearTimeout(timeoutHandle);
|
|
1180
1145
|
}
|
|
1181
|
-
if (outcome.kind ===
|
|
1146
|
+
if (outcome.kind === 'timeout') {
|
|
1182
1147
|
throw new Error(`Timeout waiting for dictation finalization (${timeoutMs}ms)`);
|
|
1183
1148
|
}
|
|
1184
|
-
if (outcome.kind ===
|
|
1149
|
+
if (outcome.kind === 'error') {
|
|
1185
1150
|
throw outcome.error;
|
|
1186
1151
|
}
|
|
1187
1152
|
return outcome.payload;
|
|
1188
1153
|
};
|
|
1189
|
-
const cleanupError = new Error(
|
|
1154
|
+
const cleanupError = new Error('Cancelled dictation finish waiter');
|
|
1190
1155
|
try {
|
|
1191
|
-
this.sendSessionMessageStrict({ type:
|
|
1156
|
+
this.sendSessionMessageStrict({ type: 'dictation_stream_finish', dictationId, finalSeq });
|
|
1192
1157
|
const firstOutcome = await Promise.race([
|
|
1193
1158
|
finalOutcomePromise,
|
|
1194
1159
|
errorOutcomePromise,
|
|
1195
1160
|
finishAcceptedOutcomePromise,
|
|
1196
1161
|
]);
|
|
1197
|
-
if (firstOutcome.kind ===
|
|
1162
|
+
if (firstOutcome.kind === 'final') {
|
|
1198
1163
|
return firstOutcome.payload;
|
|
1199
1164
|
}
|
|
1200
|
-
if (firstOutcome.kind ===
|
|
1165
|
+
if (firstOutcome.kind === 'error') {
|
|
1201
1166
|
throw firstOutcome.error;
|
|
1202
1167
|
}
|
|
1203
|
-
if (firstOutcome.kind ===
|
|
1168
|
+
if (firstOutcome.kind === 'accepted') {
|
|
1204
1169
|
return await waitForFinalResult(firstOutcome.payload.timeoutMs + DEFAULT_DICTATION_FINISH_TIMEOUT_GRACE_MS);
|
|
1205
1170
|
}
|
|
1206
1171
|
return await waitForFinalResult(DEFAULT_DICTATION_FINISH_FALLBACK_TIMEOUT_MS);
|
|
@@ -1215,13 +1180,13 @@ export class DaemonClient {
|
|
|
1215
1180
|
}
|
|
1216
1181
|
}
|
|
1217
1182
|
cancelDictationStream(dictationId) {
|
|
1218
|
-
this.sendSessionMessageStrict({ type:
|
|
1183
|
+
this.sendSessionMessageStrict({ type: 'dictation_stream_cancel', dictationId });
|
|
1219
1184
|
}
|
|
1220
1185
|
async abortRequest() {
|
|
1221
|
-
this.sendSessionMessage({ type:
|
|
1186
|
+
this.sendSessionMessage({ type: 'abort_request' });
|
|
1222
1187
|
}
|
|
1223
1188
|
async audioPlayed(id) {
|
|
1224
|
-
this.sendSessionMessage({ type:
|
|
1189
|
+
this.sendSessionMessage({ type: 'audio_played', id });
|
|
1225
1190
|
}
|
|
1226
1191
|
// ============================================================================
|
|
1227
1192
|
// Git Operations
|
|
@@ -1236,7 +1201,7 @@ export class DaemonClient {
|
|
|
1236
1201
|
}
|
|
1237
1202
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
1238
1203
|
const message = SessionInboundMessageSchema.parse({
|
|
1239
|
-
type:
|
|
1204
|
+
type: 'checkout_status_request',
|
|
1240
1205
|
cwd,
|
|
1241
1206
|
requestId: resolvedRequestId,
|
|
1242
1207
|
});
|
|
@@ -1246,7 +1211,7 @@ export class DaemonClient {
|
|
|
1246
1211
|
timeout: 60000,
|
|
1247
1212
|
options: { skipQueue: true },
|
|
1248
1213
|
select: (msg) => {
|
|
1249
|
-
if (msg.type !==
|
|
1214
|
+
if (msg.type !== 'checkout_status_response') {
|
|
1250
1215
|
return null;
|
|
1251
1216
|
}
|
|
1252
1217
|
if (msg.payload.requestId !== resolvedRequestId) {
|
|
@@ -1268,14 +1233,14 @@ export class DaemonClient {
|
|
|
1268
1233
|
return responsePromise;
|
|
1269
1234
|
}
|
|
1270
1235
|
normalizeCheckoutDiffCompare(compare) {
|
|
1271
|
-
if (compare.mode ===
|
|
1272
|
-
return { mode:
|
|
1236
|
+
if (compare.mode === 'uncommitted') {
|
|
1237
|
+
return { mode: 'uncommitted' };
|
|
1273
1238
|
}
|
|
1274
1239
|
const trimmedBaseRef = compare.baseRef?.trim();
|
|
1275
1240
|
if (!trimmedBaseRef) {
|
|
1276
|
-
return { mode:
|
|
1241
|
+
return { mode: 'base' };
|
|
1277
1242
|
}
|
|
1278
|
-
return { mode:
|
|
1243
|
+
return { mode: 'base', baseRef: trimmedBaseRef };
|
|
1279
1244
|
}
|
|
1280
1245
|
async getCheckoutDiff(cwd, compare, requestId) {
|
|
1281
1246
|
const oneShotSubscriptionId = `oneshot-checkout-diff:${crypto.randomUUID()}`;
|
|
@@ -1310,7 +1275,7 @@ export class DaemonClient {
|
|
|
1310
1275
|
});
|
|
1311
1276
|
const resolvedRequestId = this.createRequestId(options?.requestId);
|
|
1312
1277
|
const message = SessionInboundMessageSchema.parse({
|
|
1313
|
-
type:
|
|
1278
|
+
type: 'subscribe_checkout_diff_request',
|
|
1314
1279
|
subscriptionId,
|
|
1315
1280
|
cwd,
|
|
1316
1281
|
compare: normalizedCompare,
|
|
@@ -1320,7 +1285,7 @@ export class DaemonClient {
|
|
|
1320
1285
|
return await this.sendCorrelatedRequest({
|
|
1321
1286
|
requestId: resolvedRequestId,
|
|
1322
1287
|
message,
|
|
1323
|
-
responseType:
|
|
1288
|
+
responseType: 'subscribe_checkout_diff_response',
|
|
1324
1289
|
timeout: 60000,
|
|
1325
1290
|
options: { skipQueue: true },
|
|
1326
1291
|
selectPayload: (payload) => {
|
|
@@ -1344,7 +1309,7 @@ export class DaemonClient {
|
|
|
1344
1309
|
unsubscribeCheckoutDiff(subscriptionId) {
|
|
1345
1310
|
this.checkoutDiffSubscriptions.delete(subscriptionId);
|
|
1346
1311
|
this.sendSessionMessage({
|
|
1347
|
-
type:
|
|
1312
|
+
type: 'unsubscribe_checkout_diff_request',
|
|
1348
1313
|
subscriptionId,
|
|
1349
1314
|
});
|
|
1350
1315
|
}
|
|
@@ -1352,12 +1317,12 @@ export class DaemonClient {
|
|
|
1352
1317
|
return this.sendCorrelatedSessionRequest({
|
|
1353
1318
|
requestId,
|
|
1354
1319
|
message: {
|
|
1355
|
-
type:
|
|
1320
|
+
type: 'checkout_commit_request',
|
|
1356
1321
|
cwd,
|
|
1357
1322
|
message: input.message,
|
|
1358
1323
|
addAll: input.addAll,
|
|
1359
1324
|
},
|
|
1360
|
-
responseType:
|
|
1325
|
+
responseType: 'checkout_commit_response',
|
|
1361
1326
|
timeout: 60000,
|
|
1362
1327
|
});
|
|
1363
1328
|
}
|
|
@@ -1365,13 +1330,13 @@ export class DaemonClient {
|
|
|
1365
1330
|
return this.sendCorrelatedSessionRequest({
|
|
1366
1331
|
requestId,
|
|
1367
1332
|
message: {
|
|
1368
|
-
type:
|
|
1333
|
+
type: 'checkout_merge_request',
|
|
1369
1334
|
cwd,
|
|
1370
1335
|
baseRef: input.baseRef,
|
|
1371
1336
|
strategy: input.strategy,
|
|
1372
1337
|
requireCleanTarget: input.requireCleanTarget,
|
|
1373
1338
|
},
|
|
1374
|
-
responseType:
|
|
1339
|
+
responseType: 'checkout_merge_response',
|
|
1375
1340
|
timeout: 60000,
|
|
1376
1341
|
});
|
|
1377
1342
|
}
|
|
@@ -1379,12 +1344,12 @@ export class DaemonClient {
|
|
|
1379
1344
|
return this.sendCorrelatedSessionRequest({
|
|
1380
1345
|
requestId,
|
|
1381
1346
|
message: {
|
|
1382
|
-
type:
|
|
1347
|
+
type: 'checkout_merge_from_base_request',
|
|
1383
1348
|
cwd,
|
|
1384
1349
|
baseRef: input.baseRef,
|
|
1385
1350
|
requireCleanTarget: input.requireCleanTarget,
|
|
1386
1351
|
},
|
|
1387
|
-
responseType:
|
|
1352
|
+
responseType: 'checkout_merge_from_base_response',
|
|
1388
1353
|
timeout: 60000,
|
|
1389
1354
|
});
|
|
1390
1355
|
}
|
|
@@ -1392,10 +1357,10 @@ export class DaemonClient {
|
|
|
1392
1357
|
return this.sendCorrelatedSessionRequest({
|
|
1393
1358
|
requestId,
|
|
1394
1359
|
message: {
|
|
1395
|
-
type:
|
|
1360
|
+
type: 'checkout_push_request',
|
|
1396
1361
|
cwd,
|
|
1397
1362
|
},
|
|
1398
|
-
responseType:
|
|
1363
|
+
responseType: 'checkout_push_response',
|
|
1399
1364
|
timeout: 60000,
|
|
1400
1365
|
});
|
|
1401
1366
|
}
|
|
@@ -1403,13 +1368,13 @@ export class DaemonClient {
|
|
|
1403
1368
|
return this.sendCorrelatedSessionRequest({
|
|
1404
1369
|
requestId,
|
|
1405
1370
|
message: {
|
|
1406
|
-
type:
|
|
1371
|
+
type: 'checkout_pr_create_request',
|
|
1407
1372
|
cwd,
|
|
1408
1373
|
title: input.title,
|
|
1409
1374
|
body: input.body,
|
|
1410
1375
|
baseRef: input.baseRef,
|
|
1411
1376
|
},
|
|
1412
|
-
responseType:
|
|
1377
|
+
responseType: 'checkout_pr_create_response',
|
|
1413
1378
|
timeout: 60000,
|
|
1414
1379
|
});
|
|
1415
1380
|
}
|
|
@@ -1417,10 +1382,10 @@ export class DaemonClient {
|
|
|
1417
1382
|
return this.sendCorrelatedSessionRequest({
|
|
1418
1383
|
requestId,
|
|
1419
1384
|
message: {
|
|
1420
|
-
type:
|
|
1385
|
+
type: 'checkout_pr_status_request',
|
|
1421
1386
|
cwd,
|
|
1422
1387
|
},
|
|
1423
|
-
responseType:
|
|
1388
|
+
responseType: 'checkout_pr_status_response',
|
|
1424
1389
|
timeout: 60000,
|
|
1425
1390
|
});
|
|
1426
1391
|
}
|
|
@@ -1428,11 +1393,11 @@ export class DaemonClient {
|
|
|
1428
1393
|
return this.sendCorrelatedSessionRequest({
|
|
1429
1394
|
requestId,
|
|
1430
1395
|
message: {
|
|
1431
|
-
type:
|
|
1396
|
+
type: 'paseo_worktree_list_request',
|
|
1432
1397
|
cwd: input.cwd,
|
|
1433
1398
|
repoRoot: input.repoRoot,
|
|
1434
1399
|
},
|
|
1435
|
-
responseType:
|
|
1400
|
+
responseType: 'paseo_worktree_list_response',
|
|
1436
1401
|
timeout: 60000,
|
|
1437
1402
|
});
|
|
1438
1403
|
}
|
|
@@ -1440,12 +1405,12 @@ export class DaemonClient {
|
|
|
1440
1405
|
return this.sendCorrelatedSessionRequest({
|
|
1441
1406
|
requestId,
|
|
1442
1407
|
message: {
|
|
1443
|
-
type:
|
|
1408
|
+
type: 'paseo_worktree_archive_request',
|
|
1444
1409
|
worktreePath: input.worktreePath,
|
|
1445
1410
|
repoRoot: input.repoRoot,
|
|
1446
1411
|
branchName: input.branchName,
|
|
1447
1412
|
},
|
|
1448
|
-
responseType:
|
|
1413
|
+
responseType: 'paseo_worktree_archive_response',
|
|
1449
1414
|
timeout: 20000,
|
|
1450
1415
|
});
|
|
1451
1416
|
}
|
|
@@ -1453,11 +1418,11 @@ export class DaemonClient {
|
|
|
1453
1418
|
return this.sendCorrelatedSessionRequest({
|
|
1454
1419
|
requestId,
|
|
1455
1420
|
message: {
|
|
1456
|
-
type:
|
|
1421
|
+
type: 'validate_branch_request',
|
|
1457
1422
|
cwd: options.cwd,
|
|
1458
1423
|
branchName: options.branchName,
|
|
1459
1424
|
},
|
|
1460
|
-
responseType:
|
|
1425
|
+
responseType: 'validate_branch_response',
|
|
1461
1426
|
timeout: 10000,
|
|
1462
1427
|
});
|
|
1463
1428
|
}
|
|
@@ -1465,12 +1430,12 @@ export class DaemonClient {
|
|
|
1465
1430
|
return this.sendCorrelatedSessionRequest({
|
|
1466
1431
|
requestId,
|
|
1467
1432
|
message: {
|
|
1468
|
-
type:
|
|
1433
|
+
type: 'branch_suggestions_request',
|
|
1469
1434
|
cwd: options.cwd,
|
|
1470
1435
|
query: options.query,
|
|
1471
1436
|
limit: options.limit,
|
|
1472
1437
|
},
|
|
1473
|
-
responseType:
|
|
1438
|
+
responseType: 'branch_suggestions_response',
|
|
1474
1439
|
timeout: 10000,
|
|
1475
1440
|
});
|
|
1476
1441
|
}
|
|
@@ -1478,27 +1443,30 @@ export class DaemonClient {
|
|
|
1478
1443
|
return this.sendCorrelatedSessionRequest({
|
|
1479
1444
|
requestId,
|
|
1480
1445
|
message: {
|
|
1481
|
-
type:
|
|
1446
|
+
type: 'directory_suggestions_request',
|
|
1482
1447
|
query: options.query,
|
|
1448
|
+
cwd: options.cwd,
|
|
1449
|
+
includeFiles: options.includeFiles,
|
|
1450
|
+
includeDirectories: options.includeDirectories,
|
|
1483
1451
|
limit: options.limit,
|
|
1484
1452
|
},
|
|
1485
|
-
responseType:
|
|
1453
|
+
responseType: 'directory_suggestions_response',
|
|
1486
1454
|
timeout: 10000,
|
|
1487
1455
|
});
|
|
1488
1456
|
}
|
|
1489
1457
|
// ============================================================================
|
|
1490
1458
|
// File Explorer
|
|
1491
1459
|
// ============================================================================
|
|
1492
|
-
async exploreFileSystem(agentId, path, mode =
|
|
1460
|
+
async exploreFileSystem(agentId, path, mode = 'list', requestId) {
|
|
1493
1461
|
return this.sendCorrelatedSessionRequest({
|
|
1494
1462
|
requestId,
|
|
1495
1463
|
message: {
|
|
1496
|
-
type:
|
|
1464
|
+
type: 'file_explorer_request',
|
|
1497
1465
|
agentId,
|
|
1498
1466
|
path,
|
|
1499
1467
|
mode,
|
|
1500
1468
|
},
|
|
1501
|
-
responseType:
|
|
1469
|
+
responseType: 'file_explorer_response',
|
|
1502
1470
|
timeout: 10000,
|
|
1503
1471
|
});
|
|
1504
1472
|
}
|
|
@@ -1506,11 +1474,11 @@ export class DaemonClient {
|
|
|
1506
1474
|
return this.sendCorrelatedSessionRequest({
|
|
1507
1475
|
requestId,
|
|
1508
1476
|
message: {
|
|
1509
|
-
type:
|
|
1477
|
+
type: 'file_download_token_request',
|
|
1510
1478
|
agentId,
|
|
1511
1479
|
path,
|
|
1512
1480
|
},
|
|
1513
|
-
responseType:
|
|
1481
|
+
responseType: 'file_download_token_response',
|
|
1514
1482
|
timeout: 10000,
|
|
1515
1483
|
});
|
|
1516
1484
|
}
|
|
@@ -1518,10 +1486,10 @@ export class DaemonClient {
|
|
|
1518
1486
|
return this.sendCorrelatedSessionRequest({
|
|
1519
1487
|
requestId,
|
|
1520
1488
|
message: {
|
|
1521
|
-
type:
|
|
1489
|
+
type: 'project_icon_request',
|
|
1522
1490
|
cwd,
|
|
1523
1491
|
},
|
|
1524
|
-
responseType:
|
|
1492
|
+
responseType: 'project_icon_response',
|
|
1525
1493
|
timeout: 10000,
|
|
1526
1494
|
});
|
|
1527
1495
|
}
|
|
@@ -1532,11 +1500,11 @@ export class DaemonClient {
|
|
|
1532
1500
|
return this.sendCorrelatedSessionRequest({
|
|
1533
1501
|
requestId: options?.requestId,
|
|
1534
1502
|
message: {
|
|
1535
|
-
type:
|
|
1503
|
+
type: 'list_provider_models_request',
|
|
1536
1504
|
provider,
|
|
1537
1505
|
cwd: options?.cwd,
|
|
1538
1506
|
},
|
|
1539
|
-
responseType:
|
|
1507
|
+
responseType: 'list_provider_models_response',
|
|
1540
1508
|
timeout: 30000,
|
|
1541
1509
|
});
|
|
1542
1510
|
}
|
|
@@ -1544,9 +1512,9 @@ export class DaemonClient {
|
|
|
1544
1512
|
return this.sendCorrelatedSessionRequest({
|
|
1545
1513
|
requestId: options?.requestId,
|
|
1546
1514
|
message: {
|
|
1547
|
-
type:
|
|
1515
|
+
type: 'list_available_providers_request',
|
|
1548
1516
|
},
|
|
1549
|
-
responseType:
|
|
1517
|
+
responseType: 'list_available_providers_response',
|
|
1550
1518
|
timeout: 30000,
|
|
1551
1519
|
});
|
|
1552
1520
|
}
|
|
@@ -1554,9 +1522,9 @@ export class DaemonClient {
|
|
|
1554
1522
|
return this.sendCorrelatedSessionRequest({
|
|
1555
1523
|
requestId,
|
|
1556
1524
|
message: {
|
|
1557
|
-
type:
|
|
1525
|
+
type: 'speech_models_list_request',
|
|
1558
1526
|
},
|
|
1559
|
-
responseType:
|
|
1527
|
+
responseType: 'speech_models_list_response',
|
|
1560
1528
|
timeout: 30000,
|
|
1561
1529
|
});
|
|
1562
1530
|
}
|
|
@@ -1564,34 +1532,24 @@ export class DaemonClient {
|
|
|
1564
1532
|
return this.sendCorrelatedSessionRequest({
|
|
1565
1533
|
requestId: options?.requestId,
|
|
1566
1534
|
message: {
|
|
1567
|
-
type:
|
|
1535
|
+
type: 'speech_models_download_request',
|
|
1568
1536
|
modelIds: options?.modelIds,
|
|
1569
1537
|
},
|
|
1570
|
-
responseType:
|
|
1538
|
+
responseType: 'speech_models_download_response',
|
|
1571
1539
|
timeout: 30 * 60 * 1000,
|
|
1572
1540
|
});
|
|
1573
1541
|
}
|
|
1574
|
-
async listCommands(agentId,
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
message: {
|
|
1578
|
-
type: "list_commands_request",
|
|
1579
|
-
agentId,
|
|
1580
|
-
},
|
|
1581
|
-
responseType: "list_commands_response",
|
|
1582
|
-
timeout: 30000,
|
|
1583
|
-
});
|
|
1584
|
-
}
|
|
1585
|
-
async executeCommand(agentId, commandName, args, requestId) {
|
|
1542
|
+
async listCommands(agentId, requestIdOrOptions) {
|
|
1543
|
+
const requestId = typeof requestIdOrOptions === 'string' ? requestIdOrOptions : requestIdOrOptions?.requestId;
|
|
1544
|
+
const draftConfig = typeof requestIdOrOptions === 'string' ? undefined : requestIdOrOptions?.draftConfig;
|
|
1586
1545
|
return this.sendCorrelatedSessionRequest({
|
|
1587
1546
|
requestId,
|
|
1588
1547
|
message: {
|
|
1589
|
-
type:
|
|
1548
|
+
type: 'list_commands_request',
|
|
1590
1549
|
agentId,
|
|
1591
|
-
|
|
1592
|
-
args,
|
|
1550
|
+
...(draftConfig ? { draftConfig } : {}),
|
|
1593
1551
|
},
|
|
1594
|
-
responseType:
|
|
1552
|
+
responseType: 'list_commands_response',
|
|
1595
1553
|
timeout: 30000,
|
|
1596
1554
|
});
|
|
1597
1555
|
}
|
|
@@ -1600,7 +1558,7 @@ export class DaemonClient {
|
|
|
1600
1558
|
// ============================================================================
|
|
1601
1559
|
async respondToPermission(agentId, requestId, response) {
|
|
1602
1560
|
this.sendSessionMessage({
|
|
1603
|
-
type:
|
|
1561
|
+
type: 'agent_permission_response',
|
|
1604
1562
|
agentId,
|
|
1605
1563
|
requestId,
|
|
1606
1564
|
response,
|
|
@@ -1608,7 +1566,7 @@ export class DaemonClient {
|
|
|
1608
1566
|
}
|
|
1609
1567
|
async respondToPermissionAndWait(agentId, requestId, response, timeout = 15000) {
|
|
1610
1568
|
const message = SessionInboundMessageSchema.parse({
|
|
1611
|
-
type:
|
|
1569
|
+
type: 'agent_permission_response',
|
|
1612
1570
|
agentId,
|
|
1613
1571
|
requestId,
|
|
1614
1572
|
response,
|
|
@@ -1619,7 +1577,7 @@ export class DaemonClient {
|
|
|
1619
1577
|
timeout,
|
|
1620
1578
|
options: { skipQueue: true },
|
|
1621
1579
|
select: (msg) => {
|
|
1622
|
-
if (msg.type !==
|
|
1580
|
+
if (msg.type !== 'agent_permission_resolved') {
|
|
1623
1581
|
return null;
|
|
1624
1582
|
}
|
|
1625
1583
|
if (msg.payload.requestId !== requestId) {
|
|
@@ -1649,7 +1607,7 @@ export class DaemonClient {
|
|
|
1649
1607
|
async waitForFinish(agentId, timeout = 60000) {
|
|
1650
1608
|
const requestId = this.createRequestId();
|
|
1651
1609
|
const message = SessionInboundMessageSchema.parse({
|
|
1652
|
-
type:
|
|
1610
|
+
type: 'wait_for_finish_request',
|
|
1653
1611
|
requestId,
|
|
1654
1612
|
agentId,
|
|
1655
1613
|
timeoutMs: timeout,
|
|
@@ -1657,7 +1615,7 @@ export class DaemonClient {
|
|
|
1657
1615
|
const payload = await this.sendCorrelatedRequest({
|
|
1658
1616
|
requestId,
|
|
1659
1617
|
message,
|
|
1660
|
-
responseType:
|
|
1618
|
+
responseType: 'wait_for_finish_response',
|
|
1661
1619
|
timeout: timeout + 5000,
|
|
1662
1620
|
options: { skipQueue: true },
|
|
1663
1621
|
});
|
|
@@ -1673,35 +1631,35 @@ export class DaemonClient {
|
|
|
1673
1631
|
// ============================================================================
|
|
1674
1632
|
subscribeTerminals(input) {
|
|
1675
1633
|
this.terminalDirectorySubscriptions.add(input.cwd);
|
|
1676
|
-
if (!this.transport || this.connectionState.status !==
|
|
1634
|
+
if (!this.transport || this.connectionState.status !== 'connected') {
|
|
1677
1635
|
return;
|
|
1678
1636
|
}
|
|
1679
1637
|
this.sendSessionMessage({
|
|
1680
|
-
type:
|
|
1638
|
+
type: 'subscribe_terminals_request',
|
|
1681
1639
|
cwd: input.cwd,
|
|
1682
1640
|
});
|
|
1683
1641
|
}
|
|
1684
1642
|
unsubscribeTerminals(input) {
|
|
1685
1643
|
this.terminalDirectorySubscriptions.delete(input.cwd);
|
|
1686
|
-
if (!this.transport || this.connectionState.status !==
|
|
1644
|
+
if (!this.transport || this.connectionState.status !== 'connected') {
|
|
1687
1645
|
return;
|
|
1688
1646
|
}
|
|
1689
1647
|
this.sendSessionMessage({
|
|
1690
|
-
type:
|
|
1648
|
+
type: 'unsubscribe_terminals_request',
|
|
1691
1649
|
cwd: input.cwd,
|
|
1692
1650
|
});
|
|
1693
1651
|
}
|
|
1694
1652
|
async listTerminals(cwd, requestId) {
|
|
1695
1653
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
1696
1654
|
const message = SessionInboundMessageSchema.parse({
|
|
1697
|
-
type:
|
|
1655
|
+
type: 'list_terminals_request',
|
|
1698
1656
|
cwd,
|
|
1699
1657
|
requestId: resolvedRequestId,
|
|
1700
1658
|
});
|
|
1701
1659
|
return this.sendCorrelatedRequest({
|
|
1702
1660
|
requestId: resolvedRequestId,
|
|
1703
1661
|
message,
|
|
1704
|
-
responseType:
|
|
1662
|
+
responseType: 'list_terminals_response',
|
|
1705
1663
|
timeout: 10000,
|
|
1706
1664
|
options: { skipQueue: true },
|
|
1707
1665
|
});
|
|
@@ -1709,7 +1667,7 @@ export class DaemonClient {
|
|
|
1709
1667
|
async createTerminal(cwd, name, requestId) {
|
|
1710
1668
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
1711
1669
|
const message = SessionInboundMessageSchema.parse({
|
|
1712
|
-
type:
|
|
1670
|
+
type: 'create_terminal_request',
|
|
1713
1671
|
cwd,
|
|
1714
1672
|
name,
|
|
1715
1673
|
requestId: resolvedRequestId,
|
|
@@ -1717,7 +1675,7 @@ export class DaemonClient {
|
|
|
1717
1675
|
return this.sendCorrelatedRequest({
|
|
1718
1676
|
requestId: resolvedRequestId,
|
|
1719
1677
|
message,
|
|
1720
|
-
responseType:
|
|
1678
|
+
responseType: 'create_terminal_response',
|
|
1721
1679
|
timeout: 10000,
|
|
1722
1680
|
options: { skipQueue: true },
|
|
1723
1681
|
});
|
|
@@ -1725,27 +1683,27 @@ export class DaemonClient {
|
|
|
1725
1683
|
async subscribeTerminal(terminalId, requestId) {
|
|
1726
1684
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
1727
1685
|
const message = SessionInboundMessageSchema.parse({
|
|
1728
|
-
type:
|
|
1686
|
+
type: 'subscribe_terminal_request',
|
|
1729
1687
|
terminalId,
|
|
1730
1688
|
requestId: resolvedRequestId,
|
|
1731
1689
|
});
|
|
1732
1690
|
return this.sendCorrelatedRequest({
|
|
1733
1691
|
requestId: resolvedRequestId,
|
|
1734
1692
|
message,
|
|
1735
|
-
responseType:
|
|
1693
|
+
responseType: 'subscribe_terminal_response',
|
|
1736
1694
|
timeout: 10000,
|
|
1737
1695
|
options: { skipQueue: true },
|
|
1738
1696
|
});
|
|
1739
1697
|
}
|
|
1740
1698
|
unsubscribeTerminal(terminalId) {
|
|
1741
1699
|
this.sendSessionMessage({
|
|
1742
|
-
type:
|
|
1700
|
+
type: 'unsubscribe_terminal_request',
|
|
1743
1701
|
terminalId,
|
|
1744
1702
|
});
|
|
1745
1703
|
}
|
|
1746
1704
|
sendTerminalInput(terminalId, message) {
|
|
1747
1705
|
this.sendSessionMessage({
|
|
1748
|
-
type:
|
|
1706
|
+
type: 'terminal_input',
|
|
1749
1707
|
terminalId,
|
|
1750
1708
|
message,
|
|
1751
1709
|
});
|
|
@@ -1753,14 +1711,14 @@ export class DaemonClient {
|
|
|
1753
1711
|
async killTerminal(terminalId, requestId) {
|
|
1754
1712
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
1755
1713
|
const message = SessionInboundMessageSchema.parse({
|
|
1756
|
-
type:
|
|
1714
|
+
type: 'kill_terminal_request',
|
|
1757
1715
|
terminalId,
|
|
1758
1716
|
requestId: resolvedRequestId,
|
|
1759
1717
|
});
|
|
1760
1718
|
return this.sendCorrelatedRequest({
|
|
1761
1719
|
requestId: resolvedRequestId,
|
|
1762
1720
|
message,
|
|
1763
|
-
responseType:
|
|
1721
|
+
responseType: 'kill_terminal_response',
|
|
1764
1722
|
timeout: 10000,
|
|
1765
1723
|
options: { skipQueue: true },
|
|
1766
1724
|
});
|
|
@@ -1768,7 +1726,7 @@ export class DaemonClient {
|
|
|
1768
1726
|
async attachTerminalStream(terminalId, options, requestId) {
|
|
1769
1727
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
1770
1728
|
const message = SessionInboundMessageSchema.parse({
|
|
1771
|
-
type:
|
|
1729
|
+
type: 'attach_terminal_stream_request',
|
|
1772
1730
|
terminalId,
|
|
1773
1731
|
requestId: resolvedRequestId,
|
|
1774
1732
|
...(options?.resumeOffset !== undefined ? { resumeOffset: options.resumeOffset } : {}),
|
|
@@ -1778,7 +1736,7 @@ export class DaemonClient {
|
|
|
1778
1736
|
return this.sendCorrelatedRequest({
|
|
1779
1737
|
requestId: resolvedRequestId,
|
|
1780
1738
|
message,
|
|
1781
|
-
responseType:
|
|
1739
|
+
responseType: 'attach_terminal_stream_response',
|
|
1782
1740
|
timeout: 10000,
|
|
1783
1741
|
options: { skipQueue: true },
|
|
1784
1742
|
});
|
|
@@ -1786,14 +1744,14 @@ export class DaemonClient {
|
|
|
1786
1744
|
async detachTerminalStream(streamId, requestId) {
|
|
1787
1745
|
const resolvedRequestId = this.createRequestId(requestId);
|
|
1788
1746
|
const message = SessionInboundMessageSchema.parse({
|
|
1789
|
-
type:
|
|
1747
|
+
type: 'detach_terminal_stream_request',
|
|
1790
1748
|
streamId,
|
|
1791
1749
|
requestId: resolvedRequestId,
|
|
1792
1750
|
});
|
|
1793
1751
|
const payload = await this.sendCorrelatedRequest({
|
|
1794
1752
|
requestId: resolvedRequestId,
|
|
1795
1753
|
message,
|
|
1796
|
-
responseType:
|
|
1754
|
+
responseType: 'detach_terminal_stream_response',
|
|
1797
1755
|
timeout: 10000,
|
|
1798
1756
|
options: { skipQueue: true },
|
|
1799
1757
|
});
|
|
@@ -1820,7 +1778,7 @@ export class DaemonClient {
|
|
|
1820
1778
|
});
|
|
1821
1779
|
}
|
|
1822
1780
|
sendTerminalStreamInput(streamId, data) {
|
|
1823
|
-
const payload = typeof data ===
|
|
1781
|
+
const payload = typeof data === 'string' ? encodeUtf8String(data) : data;
|
|
1824
1782
|
this.sendBinaryFrame({
|
|
1825
1783
|
channel: BinaryMuxChannel.Terminal,
|
|
1826
1784
|
messageType: TerminalBinaryMessageType.InputUtf8,
|
|
@@ -1849,7 +1807,7 @@ export class DaemonClient {
|
|
|
1849
1807
|
}
|
|
1850
1808
|
async waitForTerminalOutput(terminalId, timeout = 5000) {
|
|
1851
1809
|
return this.waitFor((msg) => {
|
|
1852
|
-
if (msg.type !==
|
|
1810
|
+
if (msg.type !== 'terminal_output') {
|
|
1853
1811
|
return null;
|
|
1854
1812
|
}
|
|
1855
1813
|
if (msg.payload.terminalId !== terminalId) {
|
|
@@ -1864,7 +1822,7 @@ export class DaemonClient {
|
|
|
1864
1822
|
createRequestId(requestId) {
|
|
1865
1823
|
return requestId ?? crypto.randomUUID();
|
|
1866
1824
|
}
|
|
1867
|
-
disposeTransport(code = 1001, reason =
|
|
1825
|
+
disposeTransport(code = 1001, reason = 'Reconnecting') {
|
|
1868
1826
|
this.cleanupTransport();
|
|
1869
1827
|
if (this.transport) {
|
|
1870
1828
|
try {
|
|
@@ -1892,9 +1850,7 @@ export class DaemonClient {
|
|
|
1892
1850
|
this.transportCleanup = [];
|
|
1893
1851
|
}
|
|
1894
1852
|
handleTransportMessage(data) {
|
|
1895
|
-
const rawData = data && typeof data ===
|
|
1896
|
-
? data.data
|
|
1897
|
-
: data;
|
|
1853
|
+
const rawData = data && typeof data === 'object' && 'data' in data ? data.data : data;
|
|
1898
1854
|
const rawBytes = asUint8Array(rawData);
|
|
1899
1855
|
if (rawBytes) {
|
|
1900
1856
|
const frame = decodeBinaryMuxFrame(rawBytes);
|
|
@@ -1916,11 +1872,11 @@ export class DaemonClient {
|
|
|
1916
1872
|
}
|
|
1917
1873
|
const parsed = WSOutboundMessageSchema.safeParse(parsedJson);
|
|
1918
1874
|
if (!parsed.success) {
|
|
1919
|
-
const msgType = parsedJson?.message?.type ??
|
|
1920
|
-
this.logger.warn({ msgType, error: parsed.error.message },
|
|
1875
|
+
const msgType = parsedJson?.message?.type ?? 'unknown';
|
|
1876
|
+
this.logger.warn({ msgType, error: parsed.error.message }, 'Message validation failed');
|
|
1921
1877
|
return;
|
|
1922
1878
|
}
|
|
1923
|
-
if (parsed.data.type ===
|
|
1879
|
+
if (parsed.data.type === 'pong') {
|
|
1924
1880
|
return;
|
|
1925
1881
|
}
|
|
1926
1882
|
this.handleSessionMessage(parsed.data.message);
|
|
@@ -1956,7 +1912,7 @@ export class DaemonClient {
|
|
|
1956
1912
|
this.reconnectTimeout = null;
|
|
1957
1913
|
}
|
|
1958
1914
|
if (!this.shouldReconnect || this.config.reconnect?.enabled === false) {
|
|
1959
|
-
this.rejectConnect(new Error(reason ??
|
|
1915
|
+
this.rejectConnect(new Error(reason ?? 'Transport disconnected before connect'));
|
|
1960
1916
|
return;
|
|
1961
1917
|
}
|
|
1962
1918
|
const attempt = this.reconnectAttempt;
|
|
@@ -1964,16 +1920,16 @@ export class DaemonClient {
|
|
|
1964
1920
|
const maxDelay = this.config.reconnect?.maxDelayMs ?? DEFAULT_RECONNECT_MAX_DELAY_MS;
|
|
1965
1921
|
const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
|
|
1966
1922
|
this.reconnectAttempt = attempt + 1;
|
|
1967
|
-
if (typeof reason ===
|
|
1923
|
+
if (typeof reason === 'string' && reason.trim().length > 0) {
|
|
1968
1924
|
this.lastErrorValue = reason.trim();
|
|
1969
1925
|
}
|
|
1970
1926
|
// Clear all pending waiters and queued sends since the connection was lost
|
|
1971
1927
|
// and responses from the previous connection will never arrive.
|
|
1972
|
-
this.clearWaiters(new Error(reason ??
|
|
1973
|
-
this.rejectPendingSendQueue(new Error(reason ??
|
|
1928
|
+
this.clearWaiters(new Error(reason ?? 'Connection lost'));
|
|
1929
|
+
this.rejectPendingSendQueue(new Error(reason ?? 'Connection lost'));
|
|
1974
1930
|
this.terminalStreams.clearAll();
|
|
1975
1931
|
this.updateConnectionState({
|
|
1976
|
-
status:
|
|
1932
|
+
status: 'disconnected',
|
|
1977
1933
|
...(reason ? { reason } : {}),
|
|
1978
1934
|
});
|
|
1979
1935
|
this.reconnectTimeout = setTimeout(() => {
|
|
@@ -1985,7 +1941,7 @@ export class DaemonClient {
|
|
|
1985
1941
|
}, delay);
|
|
1986
1942
|
}
|
|
1987
1943
|
handleSessionMessage(msg) {
|
|
1988
|
-
if (msg.type ===
|
|
1944
|
+
if (msg.type === 'terminal_stream_exit') {
|
|
1989
1945
|
this.terminalStreams.clearStream({ streamId: msg.payload.streamId });
|
|
1990
1946
|
}
|
|
1991
1947
|
if (this.rawMessageListeners.size > 0) {
|
|
@@ -2040,36 +1996,34 @@ export class DaemonClient {
|
|
|
2040
1996
|
}
|
|
2041
1997
|
toEvent(msg) {
|
|
2042
1998
|
switch (msg.type) {
|
|
2043
|
-
case
|
|
1999
|
+
case 'agent_update':
|
|
2044
2000
|
return {
|
|
2045
|
-
type:
|
|
2046
|
-
agentId: msg.payload.kind ===
|
|
2047
|
-
? msg.payload.agent.id
|
|
2048
|
-
: msg.payload.agentId,
|
|
2001
|
+
type: 'agent_update',
|
|
2002
|
+
agentId: msg.payload.kind === 'upsert' ? msg.payload.agent.id : msg.payload.agentId,
|
|
2049
2003
|
payload: msg.payload,
|
|
2050
2004
|
};
|
|
2051
|
-
case
|
|
2005
|
+
case 'agent_stream':
|
|
2052
2006
|
return {
|
|
2053
|
-
type:
|
|
2007
|
+
type: 'agent_stream',
|
|
2054
2008
|
agentId: msg.payload.agentId,
|
|
2055
2009
|
event: msg.payload.event,
|
|
2056
2010
|
timestamp: msg.payload.timestamp,
|
|
2057
|
-
...(typeof msg.payload.seq ===
|
|
2058
|
-
...(typeof msg.payload.epoch ===
|
|
2011
|
+
...(typeof msg.payload.seq === 'number' ? { seq: msg.payload.seq } : {}),
|
|
2012
|
+
...(typeof msg.payload.epoch === 'string' ? { epoch: msg.payload.epoch } : {}),
|
|
2059
2013
|
};
|
|
2060
|
-
case
|
|
2061
|
-
return { type:
|
|
2062
|
-
case
|
|
2063
|
-
return { type:
|
|
2064
|
-
case
|
|
2014
|
+
case 'status':
|
|
2015
|
+
return { type: 'status', payload: msg.payload };
|
|
2016
|
+
case 'agent_deleted':
|
|
2017
|
+
return { type: 'agent_deleted', agentId: msg.payload.agentId };
|
|
2018
|
+
case 'agent_permission_request':
|
|
2065
2019
|
return {
|
|
2066
|
-
type:
|
|
2020
|
+
type: 'agent_permission_request',
|
|
2067
2021
|
agentId: msg.payload.agentId,
|
|
2068
2022
|
request: msg.payload.request,
|
|
2069
2023
|
};
|
|
2070
|
-
case
|
|
2024
|
+
case 'agent_permission_resolved':
|
|
2071
2025
|
return {
|
|
2072
|
-
type:
|
|
2026
|
+
type: 'agent_permission_resolved',
|
|
2073
2027
|
agentId: msg.payload.agentId,
|
|
2074
2028
|
requestId: msg.payload.requestId,
|
|
2075
2029
|
resolution: msg.payload.resolution,
|
|
@@ -2150,7 +2104,7 @@ function resolveAgentConfig(options) {
|
|
|
2150
2104
|
};
|
|
2151
2105
|
const merged = config ? { ...baseConfig, ...config } : baseConfig;
|
|
2152
2106
|
if (!merged.provider || !merged.cwd) {
|
|
2153
|
-
throw new Error(
|
|
2107
|
+
throw new Error('createAgent requires provider and cwd');
|
|
2154
2108
|
}
|
|
2155
2109
|
if (!merged.modeId) {
|
|
2156
2110
|
merged.modeId = getAgentProviderDefinition(merged.provider).defaultModeId ?? undefined;
|