acpx 0.4.1 → 0.5.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.
Files changed (45) hide show
  1. package/dist/{cli-idpWyCOs.js → cli-DZjj5kij.js} +8 -12
  2. package/dist/cli-DZjj5kij.js.map +1 -0
  3. package/dist/cli.d.ts +2 -2
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +1017 -1009
  6. package/dist/cli.js.map +1 -1
  7. package/dist/client-S8QicFBT.d.ts +119 -0
  8. package/dist/client-S8QicFBT.d.ts.map +1 -0
  9. package/dist/{flags-CCcX9fZj.js → flags-W3vEVSiS.js} +5 -55
  10. package/dist/flags-W3vEVSiS.js.map +1 -0
  11. package/dist/{flows-BL1tSvZT.js → flows-CLQYpPh7.js} +471 -281
  12. package/dist/flows-CLQYpPh7.js.map +1 -0
  13. package/dist/flows.d.ts +5 -9
  14. package/dist/flows.d.ts.map +1 -1
  15. package/dist/flows.js +1 -1
  16. package/dist/{queue-ipc-CE8_QGX3.js → ipc-BM335WFg.js} +12 -571
  17. package/dist/ipc-BM335WFg.js.map +1 -0
  18. package/dist/{acp-jsonrpc-BbBgC5gO.js → jsonrpc-DSxh2w5R.js} +2 -2
  19. package/dist/jsonrpc-DSxh2w5R.js.map +1 -0
  20. package/dist/{output-Du3m6oPQ.js → output-C4QhjpM6.js} +6 -6
  21. package/dist/output-C4QhjpM6.js.map +1 -0
  22. package/dist/perf-metrics-D0um6IR6.js +588 -0
  23. package/dist/perf-metrics-D0um6IR6.js.map +1 -0
  24. package/dist/{session-RO_LZUnv.js → prompt-turn-CbSSNHjk.js} +2568 -3667
  25. package/dist/prompt-turn-CbSSNHjk.js.map +1 -0
  26. package/dist/{output-render-Bz58qaQn.js → render-Br-kVPK_.js} +7 -6
  27. package/dist/render-Br-kVPK_.js.map +1 -0
  28. package/dist/runtime.d.ts +267 -0
  29. package/dist/runtime.d.ts.map +1 -0
  30. package/dist/runtime.js +983 -0
  31. package/dist/runtime.js.map +1 -0
  32. package/dist/session-BiBN0BvM.js +1488 -0
  33. package/dist/session-BiBN0BvM.js.map +1 -0
  34. package/dist/{types-CeRKmEQ1.d.ts → types-Cgigsj1X.d.ts} +40 -3
  35. package/dist/types-Cgigsj1X.d.ts.map +1 -0
  36. package/package.json +5 -3
  37. package/dist/acp-jsonrpc-BbBgC5gO.js.map +0 -1
  38. package/dist/cli-idpWyCOs.js.map +0 -1
  39. package/dist/flags-CCcX9fZj.js.map +0 -1
  40. package/dist/flows-BL1tSvZT.js.map +0 -1
  41. package/dist/output-Du3m6oPQ.js.map +0 -1
  42. package/dist/output-render-Bz58qaQn.js.map +0 -1
  43. package/dist/queue-ipc-CE8_QGX3.js.map +0 -1
  44. package/dist/session-RO_LZUnv.js.map +0 -1
  45. package/dist/types-CeRKmEQ1.d.ts.map +0 -1
@@ -0,0 +1,588 @@
1
+ //#region src/errors.ts
2
+ var AcpxOperationalError = class extends Error {
3
+ outputCode;
4
+ detailCode;
5
+ origin;
6
+ retryable;
7
+ acp;
8
+ outputAlreadyEmitted;
9
+ constructor(message, options) {
10
+ super(message, options);
11
+ this.name = new.target.name;
12
+ this.outputCode = options?.outputCode;
13
+ this.detailCode = options?.detailCode;
14
+ this.origin = options?.origin;
15
+ this.retryable = options?.retryable;
16
+ this.acp = options?.acp;
17
+ this.outputAlreadyEmitted = options?.outputAlreadyEmitted;
18
+ }
19
+ };
20
+ var SessionNotFoundError = class extends AcpxOperationalError {
21
+ sessionId;
22
+ constructor(sessionId) {
23
+ super(`Session not found: ${sessionId}`);
24
+ this.sessionId = sessionId;
25
+ }
26
+ };
27
+ var SessionResolutionError = class extends AcpxOperationalError {};
28
+ var AgentSpawnError = class extends AcpxOperationalError {
29
+ agentCommand;
30
+ constructor(agentCommand, cause) {
31
+ super(`Failed to spawn agent command: ${agentCommand}`, { cause: cause instanceof Error ? cause : void 0 });
32
+ this.agentCommand = agentCommand;
33
+ }
34
+ };
35
+ var AgentStartupError = class extends AcpxOperationalError {
36
+ agentCommand;
37
+ exitCode;
38
+ signal;
39
+ stderrSummary;
40
+ constructor(params) {
41
+ const exitSummary = `exit=${params.exitCode ?? "null"}, signal=${params.signal ?? "null"}`;
42
+ const stderrSuffix = typeof params.stderrSummary === "string" && params.stderrSummary.trim().length > 0 ? `: ${params.stderrSummary.trim()}` : "";
43
+ super(`ACP agent exited before initialize completed (${exitSummary})${stderrSuffix}`, {
44
+ cause: params.cause instanceof Error ? params.cause : void 0,
45
+ outputCode: "RUNTIME",
46
+ detailCode: "AGENT_STARTUP_FAILED",
47
+ origin: "acp"
48
+ });
49
+ this.agentCommand = params.agentCommand;
50
+ this.exitCode = params.exitCode;
51
+ this.signal = params.signal;
52
+ this.stderrSummary = params.stderrSummary?.trim() || void 0;
53
+ }
54
+ };
55
+ var AgentDisconnectedError = class extends AcpxOperationalError {
56
+ reason;
57
+ exitCode;
58
+ signal;
59
+ constructor(reason, exitCode, signal, options) {
60
+ super(`ACP agent disconnected during request (${reason}, exit=${exitCode ?? "null"}, signal=${signal ?? "null"})`, {
61
+ outputCode: "RUNTIME",
62
+ detailCode: "AGENT_DISCONNECTED",
63
+ origin: "acp",
64
+ ...options
65
+ });
66
+ this.reason = reason;
67
+ this.exitCode = exitCode;
68
+ this.signal = signal;
69
+ }
70
+ };
71
+ var SessionResumeRequiredError = class extends AcpxOperationalError {
72
+ constructor(message, options) {
73
+ super(message, {
74
+ outputCode: "RUNTIME",
75
+ detailCode: "SESSION_RESUME_REQUIRED",
76
+ origin: "acp",
77
+ retryable: true,
78
+ ...options
79
+ });
80
+ }
81
+ };
82
+ var GeminiAcpStartupTimeoutError = class extends AcpxOperationalError {
83
+ constructor(message, options) {
84
+ super(message, {
85
+ outputCode: "TIMEOUT",
86
+ detailCode: "GEMINI_ACP_STARTUP_TIMEOUT",
87
+ origin: "acp",
88
+ ...options
89
+ });
90
+ }
91
+ };
92
+ var SessionModeReplayError = class extends AcpxOperationalError {
93
+ constructor(message, options) {
94
+ super(message, {
95
+ outputCode: "RUNTIME",
96
+ detailCode: "SESSION_MODE_REPLAY_FAILED",
97
+ origin: "acp",
98
+ ...options
99
+ });
100
+ }
101
+ };
102
+ var SessionModelReplayError = class extends AcpxOperationalError {
103
+ constructor(message, options) {
104
+ super(message, {
105
+ outputCode: "RUNTIME",
106
+ detailCode: "SESSION_MODEL_REPLAY_FAILED",
107
+ origin: "acp",
108
+ ...options
109
+ });
110
+ }
111
+ };
112
+ var ClaudeAcpSessionCreateTimeoutError = class extends AcpxOperationalError {
113
+ constructor(message, options) {
114
+ super(message, {
115
+ outputCode: "TIMEOUT",
116
+ detailCode: "CLAUDE_ACP_SESSION_CREATE_TIMEOUT",
117
+ origin: "acp",
118
+ ...options
119
+ });
120
+ }
121
+ };
122
+ var CopilotAcpUnsupportedError = class extends AcpxOperationalError {
123
+ constructor(message, options) {
124
+ super(message, {
125
+ outputCode: "RUNTIME",
126
+ detailCode: "COPILOT_ACP_UNSUPPORTED",
127
+ origin: "acp",
128
+ ...options
129
+ });
130
+ }
131
+ };
132
+ var AuthPolicyError = class extends AcpxOperationalError {
133
+ constructor(message, options) {
134
+ super(message, {
135
+ outputCode: "RUNTIME",
136
+ detailCode: "AUTH_REQUIRED",
137
+ origin: "acp",
138
+ ...options
139
+ });
140
+ }
141
+ };
142
+ var QueueConnectionError = class extends AcpxOperationalError {};
143
+ var QueueProtocolError = class extends AcpxOperationalError {};
144
+ var PermissionDeniedError = class extends AcpxOperationalError {};
145
+ var PermissionPromptUnavailableError = class extends AcpxOperationalError {
146
+ constructor() {
147
+ super("Permission prompt unavailable in non-interactive mode");
148
+ }
149
+ };
150
+ //#endregion
151
+ //#region src/types.ts
152
+ const EXIT_CODES = {
153
+ SUCCESS: 0,
154
+ ERROR: 1,
155
+ USAGE: 2,
156
+ TIMEOUT: 3,
157
+ NO_SESSION: 4,
158
+ PERMISSION_DENIED: 5,
159
+ INTERRUPTED: 130
160
+ };
161
+ const OUTPUT_FORMATS = [
162
+ "text",
163
+ "json",
164
+ "quiet"
165
+ ];
166
+ const PERMISSION_MODES = [
167
+ "approve-all",
168
+ "approve-reads",
169
+ "deny-all"
170
+ ];
171
+ const AUTH_POLICIES = ["skip", "fail"];
172
+ const NON_INTERACTIVE_PERMISSION_POLICIES = ["deny", "fail"];
173
+ const OUTPUT_ERROR_CODES = [
174
+ "NO_SESSION",
175
+ "TIMEOUT",
176
+ "PERMISSION_DENIED",
177
+ "PERMISSION_PROMPT_UNAVAILABLE",
178
+ "RUNTIME",
179
+ "USAGE"
180
+ ];
181
+ const OUTPUT_ERROR_ORIGINS = [
182
+ "cli",
183
+ "runtime",
184
+ "queue",
185
+ "acp"
186
+ ];
187
+ const SESSION_RECORD_SCHEMA = "acpx.session.v1";
188
+ //#endregion
189
+ //#region src/acp/error-shapes.ts
190
+ const RESOURCE_NOT_FOUND_ACP_CODES = new Set([-32001, -32002]);
191
+ function asRecord$2(value) {
192
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
193
+ return value;
194
+ }
195
+ function toAcpErrorPayload(value) {
196
+ const record = asRecord$2(value);
197
+ if (!record) return;
198
+ if (typeof record.code !== "number" || !Number.isFinite(record.code)) return;
199
+ if (typeof record.message !== "string" || record.message.length === 0) return;
200
+ return {
201
+ code: record.code,
202
+ message: record.message,
203
+ data: record.data
204
+ };
205
+ }
206
+ function extractAcpErrorInternal(value, depth) {
207
+ if (depth > 5) return;
208
+ const direct = toAcpErrorPayload(value);
209
+ if (direct) return direct;
210
+ const record = asRecord$2(value);
211
+ if (!record) return;
212
+ if ("error" in record) {
213
+ const nested = extractAcpErrorInternal(record.error, depth + 1);
214
+ if (nested) return nested;
215
+ }
216
+ if ("acp" in record) {
217
+ const nested = extractAcpErrorInternal(record.acp, depth + 1);
218
+ if (nested) return nested;
219
+ }
220
+ if ("cause" in record) {
221
+ const nested = extractAcpErrorInternal(record.cause, depth + 1);
222
+ if (nested) return nested;
223
+ }
224
+ }
225
+ function formatUnknownErrorMessage(error) {
226
+ if (error instanceof Error) return error.message;
227
+ if (error && typeof error === "object") {
228
+ const maybeMessage = error.message;
229
+ if (typeof maybeMessage === "string" && maybeMessage.length > 0) return maybeMessage;
230
+ try {
231
+ return JSON.stringify(error);
232
+ } catch {}
233
+ }
234
+ return String(error);
235
+ }
236
+ const SESSION_NOT_FOUND_PATTERN = /session\s+["'\w-]+\s+not found/i;
237
+ function isSessionNotFoundText(value) {
238
+ if (typeof value !== "string") return false;
239
+ const normalized = value.toLowerCase();
240
+ return normalized.includes("resource_not_found") || normalized.includes("resource not found") || normalized.includes("session not found") || normalized.includes("unknown session") || normalized.includes("invalid session identifier") || SESSION_NOT_FOUND_PATTERN.test(value);
241
+ }
242
+ function hasSessionNotFoundHint(value, depth = 0) {
243
+ if (depth > 4) return false;
244
+ if (isSessionNotFoundText(value)) return true;
245
+ if (Array.isArray(value)) return value.some((entry) => hasSessionNotFoundHint(entry, depth + 1));
246
+ const record = asRecord$2(value);
247
+ if (!record) return false;
248
+ return Object.values(record).some((entry) => hasSessionNotFoundHint(entry, depth + 1));
249
+ }
250
+ function extractAcpError(error) {
251
+ return extractAcpErrorInternal(error, 0);
252
+ }
253
+ function isAcpResourceNotFoundError(error) {
254
+ const acp = extractAcpError(error);
255
+ if (acp && RESOURCE_NOT_FOUND_ACP_CODES.has(acp.code)) return true;
256
+ if (acp) {
257
+ if (isSessionNotFoundText(acp.message)) return true;
258
+ if (hasSessionNotFoundHint(acp.data)) return true;
259
+ }
260
+ return isSessionNotFoundText(formatUnknownErrorMessage(error));
261
+ }
262
+ //#endregion
263
+ //#region src/acp/error-normalization.ts
264
+ const AUTH_REQUIRED_ACP_CODES = new Set([-32e3]);
265
+ const QUERY_CLOSED_BEFORE_RESPONSE_DETAIL = "query closed before response received";
266
+ function asRecord$1(value) {
267
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
268
+ return value;
269
+ }
270
+ function isAuthRequiredMessage(value) {
271
+ if (!value) return false;
272
+ const normalized = value.toLowerCase();
273
+ return normalized.includes("auth required") || normalized.includes("authentication required") || normalized.includes("authorization required") || normalized.includes("credential required") || normalized.includes("credentials required") || normalized.includes("token required") || normalized.includes("login required");
274
+ }
275
+ function isAcpAuthRequiredPayload(acp) {
276
+ if (!acp) return false;
277
+ if (!AUTH_REQUIRED_ACP_CODES.has(acp.code)) return false;
278
+ if (isAuthRequiredMessage(acp.message)) return true;
279
+ const data = asRecord$1(acp.data);
280
+ if (!data) return false;
281
+ if (data.authRequired === true) return true;
282
+ const methodId = data.methodId;
283
+ if (typeof methodId === "string" && methodId.trim().length > 0) return true;
284
+ const methods = data.methods;
285
+ if (Array.isArray(methods) && methods.length > 0) return true;
286
+ return false;
287
+ }
288
+ function isOutputErrorCode(value) {
289
+ return typeof value === "string" && OUTPUT_ERROR_CODES.includes(value);
290
+ }
291
+ function isOutputErrorOrigin(value) {
292
+ return typeof value === "string" && OUTPUT_ERROR_ORIGINS.includes(value);
293
+ }
294
+ function readOutputErrorMeta(error) {
295
+ const record = asRecord$1(error);
296
+ if (!record) return {};
297
+ return {
298
+ outputCode: isOutputErrorCode(record.outputCode) ? record.outputCode : void 0,
299
+ detailCode: typeof record.detailCode === "string" && record.detailCode.trim().length > 0 ? record.detailCode : void 0,
300
+ origin: isOutputErrorOrigin(record.origin) ? record.origin : void 0,
301
+ retryable: typeof record.retryable === "boolean" ? record.retryable : void 0,
302
+ acp: extractAcpError(record.acp)
303
+ };
304
+ }
305
+ function isTimeoutLike(error) {
306
+ return error instanceof Error && error.name === "TimeoutError";
307
+ }
308
+ function isNoSessionLike(error) {
309
+ return error instanceof Error && error.name === "NoSessionError";
310
+ }
311
+ function isUsageLike(error) {
312
+ if (!(error instanceof Error)) return false;
313
+ return error.name === "CommanderError" || error.name === "InvalidArgumentError" || asRecord$1(error)?.code === "commander.invalidArgument";
314
+ }
315
+ function formatErrorMessage(error) {
316
+ return formatUnknownErrorMessage(error);
317
+ }
318
+ function isAcpQueryClosedBeforeResponseError(error) {
319
+ const acp = extractAcpError(error);
320
+ if (!acp || acp.code !== -32603) return false;
321
+ const details = asRecord$1(acp.data)?.details;
322
+ if (typeof details !== "string") return false;
323
+ return details.toLowerCase().includes(QUERY_CLOSED_BEFORE_RESPONSE_DETAIL);
324
+ }
325
+ function mapErrorCode(error) {
326
+ if (error instanceof PermissionPromptUnavailableError) return "PERMISSION_PROMPT_UNAVAILABLE";
327
+ if (error instanceof PermissionDeniedError) return "PERMISSION_DENIED";
328
+ if (isTimeoutLike(error)) return "TIMEOUT";
329
+ if (isNoSessionLike(error) || isAcpResourceNotFoundError(error)) return "NO_SESSION";
330
+ if (isUsageLike(error)) return "USAGE";
331
+ }
332
+ function normalizeOutputError(error, options = {}) {
333
+ const meta = readOutputErrorMeta(error);
334
+ let code = mapErrorCode(error) ?? options.defaultCode ?? "RUNTIME";
335
+ if (meta.outputCode) code = meta.outputCode;
336
+ if (code === "RUNTIME" && isAcpResourceNotFoundError(error)) code = "NO_SESSION";
337
+ const acp = options.acp ?? meta.acp ?? extractAcpError(error);
338
+ const detailCode = meta.detailCode ?? options.detailCode ?? (error instanceof AuthPolicyError || isAcpAuthRequiredPayload(acp) ? "AUTH_REQUIRED" : void 0);
339
+ return {
340
+ code,
341
+ message: formatErrorMessage(error),
342
+ detailCode,
343
+ origin: meta.origin ?? options.origin,
344
+ retryable: meta.retryable ?? options.retryable,
345
+ acp
346
+ };
347
+ }
348
+ /**
349
+ * Returns true when an error from `client.prompt()` looks transient and
350
+ * can reasonably be retried (e.g. model-API 400/500, network hiccups that
351
+ * surface as ACP internal errors).
352
+ *
353
+ * Errors that are definitively non-recoverable (auth, missing session,
354
+ * invalid params, timeout, permission) return false.
355
+ */
356
+ function isRetryablePromptError(error) {
357
+ if (error instanceof PermissionDeniedError || error instanceof PermissionPromptUnavailableError) return false;
358
+ if (isTimeoutLike(error) || isNoSessionLike(error) || isUsageLike(error)) return false;
359
+ const acp = extractAcpError(error);
360
+ if (!acp) return false;
361
+ if (acp.code === -32001 || acp.code === -32002) return false;
362
+ if (isAcpAuthRequiredPayload(acp)) return false;
363
+ if (acp.code === -32601 || acp.code === -32602) return false;
364
+ return acp.code === -32603 || acp.code === -32700;
365
+ }
366
+ function exitCodeForOutputErrorCode(code) {
367
+ switch (code) {
368
+ case "USAGE": return EXIT_CODES.USAGE;
369
+ case "TIMEOUT": return EXIT_CODES.TIMEOUT;
370
+ case "NO_SESSION": return EXIT_CODES.NO_SESSION;
371
+ case "PERMISSION_DENIED":
372
+ case "PERMISSION_PROMPT_UNAVAILABLE": return EXIT_CODES.PERMISSION_DENIED;
373
+ default: return EXIT_CODES.ERROR;
374
+ }
375
+ }
376
+ //#endregion
377
+ //#region src/prompt-content.ts
378
+ var PromptInputValidationError = class extends Error {
379
+ constructor(message) {
380
+ super(message);
381
+ this.name = "PromptInputValidationError";
382
+ }
383
+ };
384
+ function asRecord(value) {
385
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
386
+ return value;
387
+ }
388
+ function isNonEmptyString(value) {
389
+ return typeof value === "string" && value.trim().length > 0;
390
+ }
391
+ function isBase64Data(value) {
392
+ if (value.length === 0 || value.length % 4 !== 0) return false;
393
+ return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value);
394
+ }
395
+ function isImageMimeType(value) {
396
+ return /^image\/[A-Za-z0-9.+-]+$/i.test(value);
397
+ }
398
+ function isTextBlock(value) {
399
+ const record = asRecord(value);
400
+ return record?.type === "text" && typeof record.text === "string";
401
+ }
402
+ function isImageBlock(value) {
403
+ const record = asRecord(value);
404
+ return record?.type === "image" && isNonEmptyString(record.mimeType) && isImageMimeType(record.mimeType) && typeof record.data === "string" && isBase64Data(record.data);
405
+ }
406
+ function isResourceLinkBlock(value) {
407
+ const record = asRecord(value);
408
+ return record?.type === "resource_link" && isNonEmptyString(record.uri) && (record.title === void 0 || typeof record.title === "string") && (record.name === void 0 || typeof record.name === "string");
409
+ }
410
+ function isResourcePayload(value) {
411
+ const record = asRecord(value);
412
+ if (!record || !isNonEmptyString(record.uri)) return false;
413
+ return record.text === void 0 || typeof record.text === "string";
414
+ }
415
+ function isResourceBlock(value) {
416
+ const record = asRecord(value);
417
+ return record?.type === "resource" && isResourcePayload(record.resource);
418
+ }
419
+ function isContentBlock(value) {
420
+ return isTextBlock(value) || isImageBlock(value) || isResourceLinkBlock(value) || isResourceBlock(value);
421
+ }
422
+ function getContentBlockValidationError(value, index) {
423
+ const record = asRecord(value);
424
+ if (!record || typeof record.type !== "string") return `prompt[${index}] must be an ACP content block object`;
425
+ switch (record.type) {
426
+ case "text": return typeof record.text === "string" ? void 0 : `prompt[${index}] text block must include a string text field`;
427
+ case "image":
428
+ if (!isNonEmptyString(record.mimeType)) return `prompt[${index}] image block must include a non-empty mimeType`;
429
+ if (!isImageMimeType(record.mimeType)) return `prompt[${index}] image block mimeType must start with image/`;
430
+ if (typeof record.data !== "string" || record.data.length === 0) return `prompt[${index}] image block must include non-empty base64 data`;
431
+ if (!isBase64Data(record.data)) return `prompt[${index}] image block data must be valid base64`;
432
+ return;
433
+ case "resource_link":
434
+ if (!isNonEmptyString(record.uri)) return `prompt[${index}] resource_link block must include a non-empty uri`;
435
+ if (record.title !== void 0 && typeof record.title !== "string") return `prompt[${index}] resource_link block title must be a string when present`;
436
+ if (record.name !== void 0 && typeof record.name !== "string") return `prompt[${index}] resource_link block name must be a string when present`;
437
+ return;
438
+ case "resource":
439
+ if (!asRecord(record.resource)) return `prompt[${index}] resource block must include a resource object`;
440
+ if (!isResourcePayload(record.resource)) return `prompt[${index}] resource block resource must include a non-empty uri and optional text`;
441
+ return;
442
+ default: return `prompt[${index}] has unsupported content block type ${JSON.stringify(record.type)}`;
443
+ }
444
+ }
445
+ function isPromptInput(value) {
446
+ return Array.isArray(value) && value.every((entry) => isContentBlock(entry));
447
+ }
448
+ function textPrompt(text) {
449
+ return [{
450
+ type: "text",
451
+ text
452
+ }];
453
+ }
454
+ function parseStructuredPrompt(source) {
455
+ if (!source.startsWith("[")) return;
456
+ try {
457
+ const parsed = JSON.parse(source);
458
+ if (isPromptInput(parsed)) return parsed;
459
+ if (Array.isArray(parsed)) throw new PromptInputValidationError(parsed.map((entry, index) => getContentBlockValidationError(entry, index)).find((message) => message !== void 0) ?? "Structured prompt JSON must be an array of valid ACP content blocks");
460
+ return;
461
+ } catch (error) {
462
+ if (error instanceof PromptInputValidationError) throw error;
463
+ return;
464
+ }
465
+ }
466
+ function parsePromptSource(source) {
467
+ const trimmed = source.trim();
468
+ const structured = parseStructuredPrompt(trimmed);
469
+ if (structured) return structured;
470
+ if (!trimmed) return [];
471
+ return textPrompt(trimmed);
472
+ }
473
+ function mergePromptSourceWithText(source, suffixText) {
474
+ const prompt = parsePromptSource(source);
475
+ const appended = suffixText.trim();
476
+ if (!appended) return prompt;
477
+ if (prompt.length === 0) return textPrompt(appended);
478
+ return [...prompt, ...textPrompt(appended)];
479
+ }
480
+ function promptToDisplayText(prompt) {
481
+ return prompt.map((block) => {
482
+ switch (block.type) {
483
+ case "text": return block.text;
484
+ case "resource_link": return block.title ?? block.name ?? block.uri;
485
+ case "resource": return "text" in block.resource && typeof block.resource.text === "string" ? block.resource.text : block.resource.uri;
486
+ case "image": return `[image] ${block.mimeType}`;
487
+ default: return "";
488
+ }
489
+ }).filter((entry) => entry.trim().length > 0).join("\n\n").trim();
490
+ }
491
+ //#endregion
492
+ //#region src/acp/agent-session-id.ts
493
+ const AGENT_SESSION_ID_META_KEYS = ["agentSessionId", "sessionId"];
494
+ function normalizeAgentSessionId(value) {
495
+ if (typeof value !== "string") return;
496
+ const trimmed = value.trim();
497
+ return trimmed.length > 0 ? trimmed : void 0;
498
+ }
499
+ function asMetaRecord(meta) {
500
+ if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
501
+ return meta;
502
+ }
503
+ function extractAgentSessionId(meta) {
504
+ const record = asMetaRecord(meta);
505
+ if (!record) return;
506
+ for (const key of AGENT_SESSION_ID_META_KEYS) {
507
+ const normalized = normalizeAgentSessionId(record[key]);
508
+ if (normalized) return normalized;
509
+ }
510
+ }
511
+ //#endregion
512
+ //#region src/session/runtime-session-id.ts
513
+ function normalizeRuntimeSessionId(value) {
514
+ return normalizeAgentSessionId(value);
515
+ }
516
+ function extractRuntimeSessionId(meta) {
517
+ return extractAgentSessionId(meta);
518
+ }
519
+ //#endregion
520
+ //#region src/perf-metrics.ts
521
+ const counters = /* @__PURE__ */ new Map();
522
+ const gauges = /* @__PURE__ */ new Map();
523
+ const timings = /* @__PURE__ */ new Map();
524
+ function hrNow() {
525
+ return process.hrtime.bigint();
526
+ }
527
+ function durationMs(start) {
528
+ return Number(process.hrtime.bigint() - start) / 1e6;
529
+ }
530
+ function roundMetric(value) {
531
+ return Number(value.toFixed(3));
532
+ }
533
+ function incrementPerfCounter(name, delta = 1) {
534
+ counters.set(name, (counters.get(name) ?? 0) + delta);
535
+ }
536
+ function setPerfGauge(name, value) {
537
+ gauges.set(name, value);
538
+ }
539
+ function recordPerfDuration(name, durationMsValue) {
540
+ const next = timings.get(name) ?? {
541
+ count: 0,
542
+ totalMs: 0,
543
+ maxMs: 0
544
+ };
545
+ next.count += 1;
546
+ next.totalMs += durationMsValue;
547
+ next.maxMs = Math.max(next.maxMs, durationMsValue);
548
+ timings.set(name, next);
549
+ }
550
+ async function measurePerf(name, run) {
551
+ const startedAt = hrNow();
552
+ try {
553
+ return await run();
554
+ } finally {
555
+ recordPerfDuration(name, durationMs(startedAt));
556
+ }
557
+ }
558
+ function startPerfTimer(name) {
559
+ const startedAt = hrNow();
560
+ return () => {
561
+ const elapsedMs = durationMs(startedAt);
562
+ recordPerfDuration(name, elapsedMs);
563
+ return elapsedMs;
564
+ };
565
+ }
566
+ function getPerfMetricsSnapshot() {
567
+ return {
568
+ counters: Object.fromEntries(counters.entries()),
569
+ gauges: Object.fromEntries(gauges.entries()),
570
+ timings: Object.fromEntries([...timings.entries()].map(([name, bucket]) => [name, {
571
+ count: bucket.count,
572
+ totalMs: roundMetric(bucket.totalMs),
573
+ maxMs: roundMetric(bucket.maxMs)
574
+ }]))
575
+ };
576
+ }
577
+ function resetPerfMetrics() {
578
+ counters.clear();
579
+ gauges.clear();
580
+ timings.clear();
581
+ }
582
+ function formatPerfMetric(name, durationMsValue) {
583
+ return `${name}=${roundMetric(durationMsValue)}ms`;
584
+ }
585
+ //#endregion
586
+ export { PERMISSION_MODES as A, PermissionPromptUnavailableError as B, isAcpResourceNotFoundError as C, OUTPUT_ERROR_CODES as D, NON_INTERACTIVE_PERMISSION_POLICIES as E, AuthPolicyError as F, SessionNotFoundError as G, QueueProtocolError as H, ClaudeAcpSessionCreateTimeoutError as I, SessionResolutionError as K, CopilotAcpUnsupportedError as L, AgentDisconnectedError as M, AgentSpawnError as N, OUTPUT_ERROR_ORIGINS as O, AgentStartupError as P, GeminiAcpStartupTimeoutError as R, extractAcpError as S, EXIT_CODES as T, SessionModeReplayError as U, QueueConnectionError as V, SessionModelReplayError as W, exitCodeForOutputErrorCode as _, recordPerfDuration as a, isRetryablePromptError as b, startPerfTimer as c, PromptInputValidationError as d, isPromptInput as f, textPrompt as g, promptToDisplayText as h, measurePerf as i, SESSION_RECORD_SCHEMA as j, OUTPUT_FORMATS as k, extractRuntimeSessionId as l, parsePromptSource as m, getPerfMetricsSnapshot as n, resetPerfMetrics as o, mergePromptSourceWithText as p, SessionResumeRequiredError as q, incrementPerfCounter as r, setPerfGauge as s, formatPerfMetric as t, normalizeRuntimeSessionId as u, formatErrorMessage as v, AUTH_POLICIES as w, normalizeOutputError as x, isAcpQueryClosedBeforeResponseError as y, PermissionDeniedError as z };
587
+
588
+ //# sourceMappingURL=perf-metrics-D0um6IR6.js.map