acpx 0.1.16 → 0.2.0

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.
@@ -99,6 +99,150 @@ var PermissionPromptUnavailableError = class extends AcpxOperationalError {
99
99
  }
100
100
  };
101
101
 
102
+ //#endregion
103
+ //#region src/prompt-content.ts
104
+ function asRecord$3(value) {
105
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
106
+ return value;
107
+ }
108
+ function isTextBlock(value) {
109
+ const record = asRecord$3(value);
110
+ return record?.type === "text" && typeof record.text === "string";
111
+ }
112
+ function isImageBlock(value) {
113
+ const record = asRecord$3(value);
114
+ return record?.type === "image" && typeof record.mimeType === "string" && typeof record.data === "string";
115
+ }
116
+ function isResourceLinkBlock(value) {
117
+ const record = asRecord$3(value);
118
+ return record?.type === "resource_link" && typeof record.uri === "string" && (record.title === void 0 || typeof record.title === "string") && (record.name === void 0 || typeof record.name === "string");
119
+ }
120
+ function isResourcePayload(value) {
121
+ const record = asRecord$3(value);
122
+ if (!record || typeof record.uri !== "string") return false;
123
+ return record.text === void 0 || typeof record.text === "string";
124
+ }
125
+ function isResourceBlock(value) {
126
+ const record = asRecord$3(value);
127
+ return record?.type === "resource" && isResourcePayload(record.resource);
128
+ }
129
+ function isContentBlock(value) {
130
+ return isTextBlock(value) || isImageBlock(value) || isResourceLinkBlock(value) || isResourceBlock(value);
131
+ }
132
+ function isPromptInput(value) {
133
+ return Array.isArray(value) && value.every((entry) => isContentBlock(entry));
134
+ }
135
+ function textPrompt(text) {
136
+ return [{
137
+ type: "text",
138
+ text
139
+ }];
140
+ }
141
+ function parseStructuredPrompt(source) {
142
+ if (!source.startsWith("[")) return;
143
+ try {
144
+ const parsed = JSON.parse(source);
145
+ return isPromptInput(parsed) ? parsed : void 0;
146
+ } catch {
147
+ return;
148
+ }
149
+ }
150
+ function parsePromptSource(source) {
151
+ const trimmed = source.trim();
152
+ const structured = parseStructuredPrompt(trimmed);
153
+ if (structured) return structured;
154
+ if (!trimmed) return [];
155
+ return textPrompt(trimmed);
156
+ }
157
+ function mergePromptSourceWithText(source, suffixText) {
158
+ const prompt = parsePromptSource(source);
159
+ const appended = suffixText.trim();
160
+ if (!appended) return prompt;
161
+ if (prompt.length === 0) return textPrompt(appended);
162
+ return [...prompt, ...textPrompt(appended)];
163
+ }
164
+ function promptToDisplayText(prompt) {
165
+ return prompt.map((block) => {
166
+ switch (block.type) {
167
+ case "text": return block.text;
168
+ case "resource_link": return block.title ?? block.name ?? block.uri;
169
+ case "resource": return "text" in block.resource && typeof block.resource.text === "string" ? block.resource.text : block.resource.uri;
170
+ case "image": return `[image] ${block.mimeType}`;
171
+ default: return "";
172
+ }
173
+ }).filter((entry) => entry.trim().length > 0).join("\n\n").trim();
174
+ }
175
+
176
+ //#endregion
177
+ //#region src/acp-error-shapes.ts
178
+ const RESOURCE_NOT_FOUND_ACP_CODES = new Set([-32001, -32002]);
179
+ function asRecord$2(value) {
180
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
181
+ return value;
182
+ }
183
+ function toAcpErrorPayload(value) {
184
+ const record = asRecord$2(value);
185
+ if (!record) return;
186
+ if (typeof record.code !== "number" || !Number.isFinite(record.code)) return;
187
+ if (typeof record.message !== "string" || record.message.length === 0) return;
188
+ return {
189
+ code: record.code,
190
+ message: record.message,
191
+ data: record.data
192
+ };
193
+ }
194
+ function extractAcpErrorInternal(value, depth) {
195
+ if (depth > 5) return;
196
+ const direct = toAcpErrorPayload(value);
197
+ if (direct) return direct;
198
+ const record = asRecord$2(value);
199
+ if (!record) return;
200
+ if ("error" in record) {
201
+ const nested = extractAcpErrorInternal(record.error, depth + 1);
202
+ if (nested) return nested;
203
+ }
204
+ if ("cause" in record) {
205
+ const nested = extractAcpErrorInternal(record.cause, depth + 1);
206
+ if (nested) return nested;
207
+ }
208
+ }
209
+ function formatUnknownErrorMessage(error) {
210
+ if (error instanceof Error) return error.message;
211
+ if (error && typeof error === "object") {
212
+ const maybeMessage = error.message;
213
+ if (typeof maybeMessage === "string" && maybeMessage.length > 0) return maybeMessage;
214
+ try {
215
+ return JSON.stringify(error);
216
+ } catch {}
217
+ }
218
+ return String(error);
219
+ }
220
+ function isSessionNotFoundText(value) {
221
+ if (typeof value !== "string") return false;
222
+ const normalized = value.toLowerCase();
223
+ 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");
224
+ }
225
+ function hasSessionNotFoundHint(value, depth = 0) {
226
+ if (depth > 4) return false;
227
+ if (isSessionNotFoundText(value)) return true;
228
+ if (Array.isArray(value)) return value.some((entry) => hasSessionNotFoundHint(entry, depth + 1));
229
+ const record = asRecord$2(value);
230
+ if (!record) return false;
231
+ return Object.values(record).some((entry) => hasSessionNotFoundHint(entry, depth + 1));
232
+ }
233
+ function extractAcpError(error) {
234
+ return extractAcpErrorInternal(error, 0);
235
+ }
236
+ function isAcpResourceNotFoundError(error) {
237
+ const acp = extractAcpError(error);
238
+ if (acp && RESOURCE_NOT_FOUND_ACP_CODES.has(acp.code)) return true;
239
+ if (acp) {
240
+ if (isSessionNotFoundText(acp.message)) return true;
241
+ if (hasSessionNotFoundHint(acp.data)) return true;
242
+ }
243
+ return isSessionNotFoundText(formatUnknownErrorMessage(error));
244
+ }
245
+
102
246
  //#endregion
103
247
  //#region src/types.ts
104
248
  const EXIT_CODES = {
@@ -135,7 +279,6 @@ const SESSION_RECORD_SCHEMA = "acpx.session.v1";
135
279
 
136
280
  //#endregion
137
281
  //#region src/error-normalization.ts
138
- const RESOURCE_NOT_FOUND_ACP_CODES = new Set([-32002]);
139
282
  const AUTH_REQUIRED_ACP_CODES = new Set([-32e3]);
140
283
  const QUERY_CLOSED_BEFORE_RESPONSE_DETAIL = "query closed before response received";
141
284
  function asRecord$1(value) {
@@ -174,35 +317,9 @@ function readOutputErrorMeta(error) {
174
317
  detailCode: typeof record.detailCode === "string" && record.detailCode.trim().length > 0 ? record.detailCode : void 0,
175
318
  origin: isOutputErrorOrigin$1(record.origin) ? record.origin : void 0,
176
319
  retryable: typeof record.retryable === "boolean" ? record.retryable : void 0,
177
- acp: toAcpErrorPayload(record.acp)
178
- };
179
- }
180
- function toAcpErrorPayload(value) {
181
- const record = asRecord$1(value);
182
- if (!record) return;
183
- if (typeof record.code !== "number" || !Number.isFinite(record.code)) return;
184
- if (typeof record.message !== "string" || record.message.length === 0) return;
185
- return {
186
- code: record.code,
187
- message: record.message,
188
- data: record.data
320
+ acp: extractAcpError(record.acp)
189
321
  };
190
322
  }
191
- function extractAcpErrorInternal(value, depth) {
192
- if (depth > 5) return;
193
- const direct = toAcpErrorPayload(value);
194
- if (direct) return direct;
195
- const record = asRecord$1(value);
196
- if (!record) return;
197
- if ("error" in record) {
198
- const nested = extractAcpErrorInternal(record.error, depth + 1);
199
- if (nested) return nested;
200
- }
201
- if ("cause" in record) {
202
- const nested = extractAcpErrorInternal(record.cause, depth + 1);
203
- if (nested) return nested;
204
- }
205
- }
206
323
  function isTimeoutLike(error) {
207
324
  return error instanceof Error && error.name === "TimeoutError";
208
325
  }
@@ -214,22 +331,7 @@ function isUsageLike(error) {
214
331
  return error.name === "CommanderError" || error.name === "InvalidArgumentError" || asRecord$1(error)?.code === "commander.invalidArgument";
215
332
  }
216
333
  function formatErrorMessage(error) {
217
- if (error instanceof Error) return error.message;
218
- if (error && typeof error === "object") {
219
- const maybeMessage = error.message;
220
- if (typeof maybeMessage === "string" && maybeMessage.length > 0) return maybeMessage;
221
- try {
222
- return JSON.stringify(error);
223
- } catch {}
224
- }
225
- return String(error);
226
- }
227
- function extractAcpError(error) {
228
- return extractAcpErrorInternal(error, 0);
229
- }
230
- function isAcpResourceNotFoundError(error) {
231
- const acp = extractAcpError(error);
232
- return Boolean(acp && RESOURCE_NOT_FOUND_ACP_CODES.has(acp.code));
334
+ return formatUnknownErrorMessage(error);
233
335
  }
234
336
  function isAcpQueryClosedBeforeResponseError(error) {
235
337
  const acp = extractAcpError(error);
@@ -595,12 +697,14 @@ function parseQueueRequest(raw) {
595
697
  if (request.type === "submit_prompt") {
596
698
  const nonInteractivePermissions = request.nonInteractivePermissions == null ? void 0 : isNonInteractivePermissionPolicy(request.nonInteractivePermissions) ? request.nonInteractivePermissions : null;
597
699
  const suppressSdkConsoleErrors = request.suppressSdkConsoleErrors == null ? void 0 : typeof request.suppressSdkConsoleErrors === "boolean" ? request.suppressSdkConsoleErrors : null;
598
- if (typeof request.message !== "string" || !isPermissionMode(request.permissionMode) || nonInteractivePermissions === null || suppressSdkConsoleErrors === null || typeof request.waitForCompletion !== "boolean") return null;
700
+ const prompt = request.prompt == null ? void 0 : isPromptInput(request.prompt) ? request.prompt : null;
701
+ if (typeof request.message !== "string" || !isPermissionMode(request.permissionMode) || prompt === null || nonInteractivePermissions === null || suppressSdkConsoleErrors === null || typeof request.waitForCompletion !== "boolean") return null;
599
702
  return {
600
703
  type: "submit_prompt",
601
704
  requestId: request.requestId,
602
705
  ownerGeneration,
603
706
  message: request.message,
707
+ prompt: prompt ?? textPrompt(request.message),
604
708
  permissionMode: request.permissionMode,
605
709
  nonInteractivePermissions,
606
710
  timeoutMs,
@@ -862,6 +966,26 @@ var SessionQueueOwner = class SessionQueueOwner {
862
966
  this.pending.push(task);
863
967
  this.emitQueueDepth();
864
968
  }
969
+ handleControlRequest(options) {
970
+ writeQueueMessage(options.socket, {
971
+ type: "accepted",
972
+ requestId: options.requestId,
973
+ ownerGeneration: this.ownerGeneration
974
+ });
975
+ options.run().then((message) => {
976
+ writeQueueMessage(options.socket, {
977
+ ...message,
978
+ ownerGeneration: this.ownerGeneration
979
+ });
980
+ }).catch((error) => {
981
+ writeQueueMessage(options.socket, {
982
+ ...makeQueueOwnerErrorFromUnknown(options.requestId, error, "QUEUE_CONTROL_REQUEST_FAILED"),
983
+ ownerGeneration: this.ownerGeneration
984
+ });
985
+ }).finally(() => {
986
+ if (!options.socket.destroyed) options.socket.end();
987
+ });
988
+ }
865
989
  handleConnection(socket) {
866
990
  socket.setEncoding("utf8");
867
991
  if (this.closed) {
@@ -898,77 +1022,48 @@ var SessionQueueOwner = class SessionQueueOwner {
898
1022
  return;
899
1023
  }
900
1024
  if (request.type === "cancel_prompt") {
901
- writeQueueMessage(socket, {
902
- type: "accepted",
1025
+ this.handleControlRequest({
1026
+ socket,
903
1027
  requestId: request.requestId,
904
- ownerGeneration: this.ownerGeneration
905
- });
906
- this.controlHandlers.cancelPrompt().then((cancelled) => {
907
- writeQueueMessage(socket, {
1028
+ run: async () => ({
908
1029
  type: "cancel_result",
909
1030
  requestId: request.requestId,
910
- ownerGeneration: this.ownerGeneration,
911
- cancelled
912
- });
913
- }).catch((error) => {
914
- writeQueueMessage(socket, {
915
- ...makeQueueOwnerErrorFromUnknown(request.requestId, error, "QUEUE_CONTROL_REQUEST_FAILED"),
916
- ownerGeneration: this.ownerGeneration
917
- });
918
- }).finally(() => {
919
- if (!socket.destroyed) socket.end();
1031
+ cancelled: await this.controlHandlers.cancelPrompt()
1032
+ })
920
1033
  });
921
1034
  return;
922
1035
  }
923
1036
  if (request.type === "set_mode") {
924
- writeQueueMessage(socket, {
925
- type: "accepted",
1037
+ this.handleControlRequest({
1038
+ socket,
926
1039
  requestId: request.requestId,
927
- ownerGeneration: this.ownerGeneration
928
- });
929
- this.controlHandlers.setSessionMode(request.modeId, request.timeoutMs).then(() => {
930
- writeQueueMessage(socket, {
931
- type: "set_mode_result",
932
- requestId: request.requestId,
933
- ownerGeneration: this.ownerGeneration,
934
- modeId: request.modeId
935
- });
936
- }).catch((error) => {
937
- writeQueueMessage(socket, {
938
- ...makeQueueOwnerErrorFromUnknown(request.requestId, error, "QUEUE_CONTROL_REQUEST_FAILED"),
939
- ownerGeneration: this.ownerGeneration
940
- });
941
- }).finally(() => {
942
- if (!socket.destroyed) socket.end();
1040
+ run: async () => {
1041
+ await this.controlHandlers.setSessionMode(request.modeId, request.timeoutMs);
1042
+ return {
1043
+ type: "set_mode_result",
1044
+ requestId: request.requestId,
1045
+ modeId: request.modeId
1046
+ };
1047
+ }
943
1048
  });
944
1049
  return;
945
1050
  }
946
1051
  if (request.type === "set_config_option") {
947
- writeQueueMessage(socket, {
948
- type: "accepted",
1052
+ this.handleControlRequest({
1053
+ socket,
949
1054
  requestId: request.requestId,
950
- ownerGeneration: this.ownerGeneration
951
- });
952
- this.controlHandlers.setSessionConfigOption(request.configId, request.value, request.timeoutMs).then((response) => {
953
- writeQueueMessage(socket, {
1055
+ run: async () => ({
954
1056
  type: "set_config_option_result",
955
1057
  requestId: request.requestId,
956
- ownerGeneration: this.ownerGeneration,
957
- response
958
- });
959
- }).catch((error) => {
960
- writeQueueMessage(socket, {
961
- ...makeQueueOwnerErrorFromUnknown(request.requestId, error, "QUEUE_CONTROL_REQUEST_FAILED"),
962
- ownerGeneration: this.ownerGeneration
963
- });
964
- }).finally(() => {
965
- if (!socket.destroyed) socket.end();
1058
+ response: await this.controlHandlers.setSessionConfigOption(request.configId, request.value, request.timeoutMs)
1059
+ })
966
1060
  });
967
1061
  return;
968
1062
  }
969
1063
  const task = {
970
1064
  requestId: request.requestId,
971
1065
  message: request.message,
1066
+ prompt: request.prompt ?? textPrompt(request.message),
972
1067
  permissionMode: request.permissionMode,
973
1068
  nonInteractivePermissions: request.nonInteractivePermissions,
974
1069
  timeoutMs: request.timeoutMs,
@@ -1115,27 +1210,38 @@ function assertOwnerGeneration(owner, message) {
1115
1210
  });
1116
1211
  return message;
1117
1212
  }
1118
- async function submitToQueueOwner(owner, options) {
1119
- const socket = await connectToQueueOwner(owner);
1213
+ function makeMalformedQueueMessageError() {
1214
+ return new QueueProtocolError("Queue owner sent malformed message", {
1215
+ detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
1216
+ origin: "queue",
1217
+ retryable: true
1218
+ });
1219
+ }
1220
+ function parseQueueOwnerResponseLine(owner, requestId, line) {
1221
+ let parsed;
1222
+ try {
1223
+ parsed = JSON.parse(line);
1224
+ } catch {
1225
+ throw new QueueProtocolError("Queue owner sent invalid JSON payload", {
1226
+ detailCode: "QUEUE_PROTOCOL_INVALID_JSON",
1227
+ origin: "queue",
1228
+ retryable: true
1229
+ });
1230
+ }
1231
+ const parsedMessage = parseQueueOwnerMessage(parsed);
1232
+ if (!parsedMessage) throw makeMalformedQueueMessageError();
1233
+ const message = assertOwnerGeneration(owner, parsedMessage);
1234
+ if (message.requestId !== requestId) throw makeMalformedQueueMessageError();
1235
+ return message;
1236
+ }
1237
+ async function runQueueOwnerRequest(options) {
1238
+ const socket = await connectToQueueOwner(options.owner);
1120
1239
  if (!socket) return;
1121
1240
  socket.setEncoding("utf8");
1122
- const requestId = randomUUID();
1123
- const request = {
1124
- type: "submit_prompt",
1125
- requestId,
1126
- ownerGeneration: owner.ownerGeneration,
1127
- message: options.message,
1128
- permissionMode: options.permissionMode,
1129
- nonInteractivePermissions: options.nonInteractivePermissions,
1130
- timeoutMs: options.timeoutMs,
1131
- suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,
1132
- waitForCompletion: options.waitForCompletion
1133
- };
1134
- options.outputFormatter.setContext({ sessionId: options.sessionId });
1135
1241
  return await new Promise((resolve, reject) => {
1136
1242
  let settled = false;
1137
- let acknowledged = false;
1138
1243
  let buffer = "";
1244
+ const state = { acknowledged: false };
1139
1245
  const finishResolve = (result) => {
1140
1246
  if (settled) return;
1141
1247
  settled = true;
@@ -1150,46 +1256,73 @@ async function submitToQueueOwner(owner, options) {
1150
1256
  if (!socket.destroyed) socket.destroy();
1151
1257
  reject(error);
1152
1258
  };
1259
+ const controls = {
1260
+ state,
1261
+ resolve: finishResolve,
1262
+ reject: finishReject
1263
+ };
1153
1264
  const processLine = (line) => {
1154
- let parsed;
1265
+ let message;
1155
1266
  try {
1156
- parsed = JSON.parse(line);
1157
- } catch {
1158
- finishReject(new QueueProtocolError("Queue owner sent invalid JSON payload", {
1159
- detailCode: "QUEUE_PROTOCOL_INVALID_JSON",
1160
- origin: "queue",
1161
- retryable: true
1162
- }));
1163
- return;
1164
- }
1165
- const parsedMessage = parseQueueOwnerMessage(parsed);
1166
- if (!parsedMessage) {
1167
- finishReject(new QueueProtocolError("Queue owner sent malformed message", {
1168
- detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
1169
- origin: "queue",
1170
- retryable: true
1171
- }));
1172
- return;
1173
- }
1174
- const message = assertOwnerGeneration(owner, parsedMessage);
1175
- if (message.requestId !== requestId) {
1176
- finishReject(new QueueProtocolError("Queue owner sent malformed message", {
1177
- detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
1178
- origin: "queue",
1179
- retryable: true
1180
- }));
1267
+ message = parseQueueOwnerResponseLine(options.owner, options.request.requestId, line);
1268
+ } catch (error) {
1269
+ finishReject(error);
1181
1270
  return;
1182
1271
  }
1183
1272
  if (message.type === "accepted") {
1184
- acknowledged = true;
1185
- options.outputFormatter.setContext({ sessionId: options.sessionId });
1186
- if (!options.waitForCompletion) finishResolve({
1187
- queued: true,
1188
- sessionId: options.sessionId,
1189
- requestId
1190
- });
1273
+ state.acknowledged = true;
1274
+ options.onAccepted?.(controls);
1191
1275
  return;
1192
1276
  }
1277
+ options.onMessage(message, controls);
1278
+ };
1279
+ socket.on("data", (chunk) => {
1280
+ buffer += chunk;
1281
+ let index = buffer.indexOf("\n");
1282
+ while (index >= 0) {
1283
+ const line = buffer.slice(0, index).trim();
1284
+ buffer = buffer.slice(index + 1);
1285
+ if (line.length > 0) processLine(line);
1286
+ index = buffer.indexOf("\n");
1287
+ }
1288
+ });
1289
+ socket.once("error", (error) => {
1290
+ finishReject(error);
1291
+ });
1292
+ socket.once("close", () => {
1293
+ if (settled) return;
1294
+ options.onClose(controls);
1295
+ });
1296
+ socket.write(`${JSON.stringify(options.request)}\n`);
1297
+ });
1298
+ }
1299
+ async function submitToQueueOwner(owner, options) {
1300
+ const requestId = randomUUID();
1301
+ const request = {
1302
+ type: "submit_prompt",
1303
+ requestId,
1304
+ ownerGeneration: owner.ownerGeneration,
1305
+ message: options.message,
1306
+ prompt: options.prompt,
1307
+ permissionMode: options.permissionMode,
1308
+ nonInteractivePermissions: options.nonInteractivePermissions,
1309
+ timeoutMs: options.timeoutMs,
1310
+ suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,
1311
+ waitForCompletion: options.waitForCompletion
1312
+ };
1313
+ options.outputFormatter.setContext({ sessionId: options.sessionId });
1314
+ return await runQueueOwnerRequest({
1315
+ owner,
1316
+ request,
1317
+ onAccepted: ({ resolve }) => {
1318
+ options.outputFormatter.setContext({ sessionId: options.sessionId });
1319
+ if (!options.waitForCompletion) resolve({
1320
+ queued: true,
1321
+ sessionId: options.sessionId,
1322
+ requestId
1323
+ });
1324
+ },
1325
+ onMessage: (message, { state, resolve, reject }) => {
1193
1326
  if (message.type === "error") {
1194
1327
  options.outputFormatter.setContext({ sessionId: options.sessionId });
1195
1328
  const queueErrorAlreadyEmitted = options.errorEmissionPolicy?.queueErrorAlreadyEmitted ?? true;
@@ -1204,7 +1337,7 @@ async function submitToQueueOwner(owner, options) {
1204
1337
  });
1205
1338
  options.outputFormatter.flush();
1206
1339
  }
1207
- finishReject(new QueueConnectionError(message.message, {
1340
+ reject(new QueueConnectionError(message.message, {
1208
1341
  outputCode: message.code,
1209
1342
  detailCode: message.detailCode,
1210
1343
  origin: message.origin ?? "queue",
@@ -1214,8 +1347,8 @@ async function submitToQueueOwner(owner, options) {
1214
1347
  }));
1215
1348
  return;
1216
1349
  }
1217
- if (!acknowledged) {
1218
- finishReject(new QueueConnectionError("Queue owner did not acknowledge request", {
1350
+ if (!state.acknowledged) {
1351
+ reject(new QueueConnectionError("Queue owner did not acknowledge request", {
1219
1352
  detailCode: "QUEUE_ACK_MISSING",
1220
1353
  origin: "queue",
1221
1354
  retryable: true
@@ -1228,32 +1361,18 @@ async function submitToQueueOwner(owner, options) {
1228
1361
  }
1229
1362
  if (message.type === "result") {
1230
1363
  options.outputFormatter.flush();
1231
- finishResolve(message.result);
1364
+ resolve(message.result);
1232
1365
  return;
1233
1366
  }
1234
- finishReject(new QueueProtocolError("Queue owner returned unexpected response", {
1367
+ reject(new QueueProtocolError("Queue owner returned unexpected response", {
1235
1368
  detailCode: "QUEUE_PROTOCOL_UNEXPECTED_RESPONSE",
1236
1369
  origin: "queue",
1237
1370
  retryable: true
1238
1371
  }));
1239
- };
1240
- socket.on("data", (chunk) => {
1241
- buffer += chunk;
1242
- let index = buffer.indexOf("\n");
1243
- while (index >= 0) {
1244
- const line = buffer.slice(0, index).trim();
1245
- buffer = buffer.slice(index + 1);
1246
- if (line.length > 0) processLine(line);
1247
- index = buffer.indexOf("\n");
1248
- }
1249
- });
1250
- socket.once("error", (error) => {
1251
- finishReject(error);
1252
- });
1253
- socket.once("close", () => {
1254
- if (settled) return;
1255
- if (!acknowledged) {
1256
- finishReject(new QueueConnectionError("Queue owner disconnected before acknowledging request", {
1372
+ },
1373
+ onClose: ({ state, resolve, reject }) => {
1374
+ if (!state.acknowledged) {
1375
+ reject(new QueueConnectionError("Queue owner disconnected before acknowledging request", {
1257
1376
  detailCode: "QUEUE_DISCONNECTED_BEFORE_ACK",
1258
1377
  origin: "queue",
1259
1378
  retryable: true
@@ -1261,80 +1380,28 @@ async function submitToQueueOwner(owner, options) {
1261
1380
  return;
1262
1381
  }
1263
1382
  if (!options.waitForCompletion) {
1264
- finishResolve({
1383
+ resolve({
1265
1384
  queued: true,
1266
1385
  sessionId: options.sessionId,
1267
1386
  requestId
1268
1387
  });
1269
1388
  return;
1270
1389
  }
1271
- finishReject(new QueueConnectionError("Queue owner disconnected before prompt completion", {
1390
+ reject(new QueueConnectionError("Queue owner disconnected before prompt completion", {
1272
1391
  detailCode: "QUEUE_DISCONNECTED_BEFORE_COMPLETION",
1273
1392
  origin: "queue",
1274
1393
  retryable: true
1275
1394
  }));
1276
- });
1277
- socket.write(`${JSON.stringify(request)}\n`);
1395
+ }
1278
1396
  });
1279
1397
  }
1280
1398
  async function submitControlToQueueOwner(owner, request, isExpectedResponse) {
1281
- const socket = await connectToQueueOwner(owner);
1282
- if (!socket) return;
1283
- socket.setEncoding("utf8");
1284
- return await new Promise((resolve, reject) => {
1285
- let settled = false;
1286
- let acknowledged = false;
1287
- let buffer = "";
1288
- const finishResolve = (result) => {
1289
- if (settled) return;
1290
- settled = true;
1291
- socket.removeAllListeners();
1292
- if (!socket.destroyed) socket.end();
1293
- resolve(result);
1294
- };
1295
- const finishReject = (error) => {
1296
- if (settled) return;
1297
- settled = true;
1298
- socket.removeAllListeners();
1299
- if (!socket.destroyed) socket.destroy();
1300
- reject(error);
1301
- };
1302
- const processLine = (line) => {
1303
- let parsed;
1304
- try {
1305
- parsed = JSON.parse(line);
1306
- } catch {
1307
- finishReject(new QueueProtocolError("Queue owner sent invalid JSON payload", {
1308
- detailCode: "QUEUE_PROTOCOL_INVALID_JSON",
1309
- origin: "queue",
1310
- retryable: true
1311
- }));
1312
- return;
1313
- }
1314
- const parsedMessage = parseQueueOwnerMessage(parsed);
1315
- if (!parsedMessage) {
1316
- finishReject(new QueueProtocolError("Queue owner sent malformed message", {
1317
- detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
1318
- origin: "queue",
1319
- retryable: true
1320
- }));
1321
- return;
1322
- }
1323
- const message = assertOwnerGeneration(owner, parsedMessage);
1324
- if (message.requestId !== request.requestId) {
1325
- finishReject(new QueueProtocolError("Queue owner sent malformed message", {
1326
- detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
1327
- origin: "queue",
1328
- retryable: true
1329
- }));
1330
- return;
1331
- }
1332
- if (message.type === "accepted") {
1333
- acknowledged = true;
1334
- return;
1335
- }
1399
+ return await runQueueOwnerRequest({
1400
+ owner,
1401
+ request,
1402
+ onMessage: (message, { state, resolve, reject }) => {
1336
1403
  if (message.type === "error") {
1337
- finishReject(new QueueConnectionError(message.message, {
1404
+ reject(new QueueConnectionError(message.message, {
1338
1405
  outputCode: message.code,
1339
1406
  detailCode: message.detailCode,
1340
1407
  origin: message.origin ?? "queue",
@@ -1343,8 +1410,8 @@ async function submitControlToQueueOwner(owner, request, isExpectedResponse) {
1343
1410
  }));
1344
1411
  return;
1345
1412
  }
1346
- if (!acknowledged) {
1347
- finishReject(new QueueConnectionError("Queue owner did not acknowledge request", {
1413
+ if (!state.acknowledged) {
1414
+ reject(new QueueConnectionError("Queue owner did not acknowledge request", {
1348
1415
  detailCode: "QUEUE_ACK_MISSING",
1349
1416
  origin: "queue",
1350
1417
  retryable: true
@@ -1352,45 +1419,30 @@ async function submitControlToQueueOwner(owner, request, isExpectedResponse) {
1352
1419
  return;
1353
1420
  }
1354
1421
  if (!isExpectedResponse(message)) {
1355
- finishReject(new QueueProtocolError("Queue owner returned unexpected response", {
1422
+ reject(new QueueProtocolError("Queue owner returned unexpected response", {
1356
1423
  detailCode: "QUEUE_PROTOCOL_UNEXPECTED_RESPONSE",
1357
1424
  origin: "queue",
1358
1425
  retryable: true
1359
1426
  }));
1360
1427
  return;
1361
1428
  }
1362
- finishResolve(message);
1363
- };
1364
- socket.on("data", (chunk) => {
1365
- buffer += chunk;
1366
- let index = buffer.indexOf("\n");
1367
- while (index >= 0) {
1368
- const line = buffer.slice(0, index).trim();
1369
- buffer = buffer.slice(index + 1);
1370
- if (line.length > 0) processLine(line);
1371
- index = buffer.indexOf("\n");
1372
- }
1373
- });
1374
- socket.once("error", (error) => {
1375
- finishReject(error);
1376
- });
1377
- socket.once("close", () => {
1378
- if (settled) return;
1379
- if (!acknowledged) {
1380
- finishReject(new QueueConnectionError("Queue owner disconnected before acknowledging request", {
1429
+ resolve(message);
1430
+ },
1431
+ onClose: ({ state, reject }) => {
1432
+ if (!state.acknowledged) {
1433
+ reject(new QueueConnectionError("Queue owner disconnected before acknowledging request", {
1381
1434
  detailCode: "QUEUE_DISCONNECTED_BEFORE_ACK",
1382
1435
  origin: "queue",
1383
1436
  retryable: true
1384
1437
  }));
1385
1438
  return;
1386
1439
  }
1387
- finishReject(new QueueConnectionError("Queue owner disconnected before responding", {
1440
+ reject(new QueueConnectionError("Queue owner disconnected before responding", {
1388
1441
  detailCode: "QUEUE_DISCONNECTED_BEFORE_COMPLETION",
1389
1442
  origin: "queue",
1390
1443
  retryable: true
1391
1444
  }));
1392
- });
1393
- socket.write(`${JSON.stringify(request)}\n`);
1445
+ }
1394
1446
  });
1395
1447
  }
1396
1448
  async function submitCancelToQueueOwner(owner) {
@@ -1515,5 +1567,5 @@ async function trySetConfigOptionOnRunningOwner(sessionId, configId, value, time
1515
1567
  }
1516
1568
 
1517
1569
  //#endregion
1518
- export { EXIT_CODES as A, PermissionPromptUnavailableError as B, exitCodeForOutputErrorCode as C, isAcpResourceNotFoundError as D, isAcpQueryClosedBeforeResponseError as E, AuthPolicyError as F, SessionModeReplayError as H, ClaudeAcpSessionCreateTimeoutError as I, CopilotAcpUnsupportedError as L, OUTPUT_FORMATS as M, SESSION_RECORD_SCHEMA as N, normalizeOutputError as O, AgentSpawnError as P, GeminiAcpStartupTimeoutError as R, startPerfTimer as S, formatErrorMessage as T, SessionNotFoundError as U, QueueConnectionError as V, SessionResolutionError as W, getPerfMetricsSnapshot as _, trySetConfigOptionOnRunningOwner as a, resetPerfMetrics as b, SessionQueueOwner as c, releaseQueueOwnerLease as d, terminateProcess as f, formatPerfMetric as g, waitMs as h, tryCancelOnRunningOwner as i, NON_INTERACTIVE_PERMISSION_POLICIES as j, AUTH_POLICIES as k, isProcessAlive as l, tryAcquireQueueOwnerLease as m, probeQueueOwnerHealth as n, trySetModeOnRunningOwner as o, terminateQueueOwnerForSession as p, queue_ipc_exports as r, trySubmitToRunningOwner as s, QUEUE_CONNECT_RETRY_MS as t, refreshQueueOwnerLease as u, incrementPerfCounter as v, extractAcpError as w, setPerfGauge as x, measurePerf as y, PermissionDeniedError as z };
1519
- //# sourceMappingURL=queue-ipc-CEetz4_7.js.map
1570
+ export { OUTPUT_FORMATS as A, ClaudeAcpSessionCreateTimeoutError as B, exitCodeForOutputErrorCode as C, AUTH_POLICIES as D, normalizeOutputError as E, parsePromptSource as F, QueueConnectionError as G, GeminiAcpStartupTimeoutError as H, promptToDisplayText as I, SessionResolutionError as J, SessionModeReplayError as K, textPrompt as L, extractAcpError as M, isAcpResourceNotFoundError as N, EXIT_CODES as O, mergePromptSourceWithText as P, AgentSpawnError as R, startPerfTimer as S, isAcpQueryClosedBeforeResponseError as T, PermissionDeniedError as U, CopilotAcpUnsupportedError as V, PermissionPromptUnavailableError as W, getPerfMetricsSnapshot as _, trySetConfigOptionOnRunningOwner as a, resetPerfMetrics as b, SessionQueueOwner as c, releaseQueueOwnerLease as d, terminateProcess as f, formatPerfMetric as g, waitMs as h, tryCancelOnRunningOwner as i, SESSION_RECORD_SCHEMA as j, NON_INTERACTIVE_PERMISSION_POLICIES as k, isProcessAlive as l, tryAcquireQueueOwnerLease as m, probeQueueOwnerHealth as n, trySetModeOnRunningOwner as o, terminateQueueOwnerForSession as p, SessionNotFoundError as q, queue_ipc_exports as r, trySubmitToRunningOwner as s, QUEUE_CONNECT_RETRY_MS as t, refreshQueueOwnerLease as u, incrementPerfCounter as v, formatErrorMessage as w, setPerfGauge as x, measurePerf as y, AuthPolicyError as z };
1571
+ //# sourceMappingURL=queue-ipc-C8StWiZt.js.map