acpx 0.10.0 → 0.11.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 (34) hide show
  1. package/README.md +25 -19
  2. package/dist/{cli-8dP_TqBp.js → cli-D4XUKXcD.js} +5 -5
  3. package/dist/{cli-8dP_TqBp.js.map → cli-D4XUKXcD.js.map} +1 -1
  4. package/dist/cli.d.ts +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +429 -88
  7. package/dist/cli.js.map +1 -1
  8. package/dist/{client-C4iJBO0j.d.ts → client-DIlpCkHw.d.ts} +38 -5
  9. package/dist/client-DIlpCkHw.d.ts.map +1 -0
  10. package/dist/{flags--2oX_ubW.js → flags-Dvgmpq_l.js} +5 -5
  11. package/dist/flags-Dvgmpq_l.js.map +1 -0
  12. package/dist/{flows-e4umXVbY.js → flows-Cvsc-_AW.js} +4 -3
  13. package/dist/flows-Cvsc-_AW.js.map +1 -0
  14. package/dist/flows.d.ts +1 -1
  15. package/dist/flows.d.ts.map +1 -1
  16. package/dist/flows.js +1 -1
  17. package/dist/{live-checkpoint-CuFft_Nd.js → live-checkpoint-BWkYxMeS.js} +848 -207
  18. package/dist/live-checkpoint-BWkYxMeS.js.map +1 -0
  19. package/dist/{output-Di77Yugq.js → output-BEv_BB7T.js} +359 -141
  20. package/dist/output-BEv_BB7T.js.map +1 -0
  21. package/dist/runtime.d.ts +71 -5
  22. package/dist/runtime.d.ts.map +1 -1
  23. package/dist/runtime.js +192 -35
  24. package/dist/runtime.js.map +1 -1
  25. package/dist/{session-options-Bh1bIqQ2.d.ts → session-options-jkYbBxGE.d.ts} +27 -2
  26. package/dist/session-options-jkYbBxGE.d.ts.map +1 -0
  27. package/package.json +21 -20
  28. package/skills/acpx/SKILL.md +58 -3
  29. package/dist/client-C4iJBO0j.d.ts.map +0 -1
  30. package/dist/flags--2oX_ubW.js.map +0 -1
  31. package/dist/flows-e4umXVbY.js.map +0 -1
  32. package/dist/live-checkpoint-CuFft_Nd.js.map +0 -1
  33. package/dist/output-Di77Yugq.js.map +0 -1
  34. package/dist/session-options-Bh1bIqQ2.d.ts.map +0 -1
@@ -1,4 +1,4 @@
1
- import fs, { statSync } from "node:fs";
1
+ import fs, { readFileSync, statSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import path from "node:path";
4
4
  import fs$1 from "node:fs/promises";
@@ -6,7 +6,7 @@ import os from "node:os";
6
6
  import { randomUUID } from "node:crypto";
7
7
  import { execFile, spawn } from "node:child_process";
8
8
  import { Readable, Writable } from "node:stream";
9
- import { ClientSideConnection, PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
9
+ import { ClientSideConnection, PROTOCOL_VERSION, RequestError } from "@agentclientprotocol/sdk";
10
10
  import readline from "node:readline/promises";
11
11
  import { promisify } from "node:util";
12
12
  //#region src/errors.ts
@@ -222,13 +222,13 @@ const OUTPUT_ERROR_ORIGINS = [
222
222
  const SESSION_RECORD_SCHEMA = "acpx.session.v1";
223
223
  //#endregion
224
224
  //#region src/acp/error-shapes.ts
225
- const RESOURCE_NOT_FOUND_ACP_CODES = new Set([-32001, -32002]);
226
- function asRecord$7(value) {
225
+ const RESOURCE_NOT_FOUND_ACP_CODES = /* @__PURE__ */ new Set([-32001, -32002]);
226
+ function asRecord$8(value) {
227
227
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
228
228
  return value;
229
229
  }
230
230
  function toAcpErrorPayload(value) {
231
- const record = asRecord$7(value);
231
+ const record = asRecord$8(value);
232
232
  if (!record) return;
233
233
  if (typeof record.code !== "number" || !Number.isFinite(record.code)) return;
234
234
  if (typeof record.message !== "string" || record.message.length === 0) return;
@@ -242,7 +242,7 @@ function extractAcpErrorInternal(value, depth) {
242
242
  if (depth > 5) return;
243
243
  const direct = toAcpErrorPayload(value);
244
244
  if (direct) return direct;
245
- const record = asRecord$7(value);
245
+ const record = asRecord$8(value);
246
246
  if (!record) return;
247
247
  return extractNestedAcpError(record, depth);
248
248
  }
@@ -277,7 +277,7 @@ function hasSessionNotFoundHint(value, depth = 0) {
277
277
  if (depth > 4) return false;
278
278
  if (isSessionNotFoundText(value)) return true;
279
279
  if (Array.isArray(value)) return value.some((entry) => hasSessionNotFoundHint(entry, depth + 1));
280
- const record = asRecord$7(value);
280
+ const record = asRecord$8(value);
281
281
  if (!record) return false;
282
282
  return Object.values(record).some((entry) => hasSessionNotFoundHint(entry, depth + 1));
283
283
  }
@@ -295,9 +295,9 @@ function isAcpResourceNotFoundError(error) {
295
295
  }
296
296
  //#endregion
297
297
  //#region src/acp/error-normalization.ts
298
- const AUTH_REQUIRED_ACP_CODES = new Set([-32e3]);
298
+ const AUTH_REQUIRED_ACP_CODES = /* @__PURE__ */ new Set([-32e3]);
299
299
  const QUERY_CLOSED_BEFORE_RESPONSE_DETAIL = "query closed before response received";
300
- function asRecord$6(value) {
300
+ function asRecord$7(value) {
301
301
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
302
302
  return value;
303
303
  }
@@ -318,7 +318,7 @@ function isAcpAuthRequiredPayload(acp) {
318
318
  if (!acp) return false;
319
319
  if (!AUTH_REQUIRED_ACP_CODES.has(acp.code)) return false;
320
320
  if (isAuthRequiredMessage(acp.message)) return true;
321
- const data = asRecord$6(acp.data);
321
+ const data = asRecord$7(acp.data);
322
322
  if (!data) return false;
323
323
  return hasAuthRequiredData(data);
324
324
  }
@@ -338,7 +338,7 @@ function isOutputErrorOrigin(value) {
338
338
  return typeof value === "string" && OUTPUT_ERROR_ORIGINS.includes(value);
339
339
  }
340
340
  function readOutputErrorMeta(error) {
341
- const record = asRecord$6(error);
341
+ const record = asRecord$7(error);
342
342
  if (!record) return {};
343
343
  return {
344
344
  outputCode: isOutputErrorCode(record.outputCode) ? record.outputCode : void 0,
@@ -356,7 +356,7 @@ function isNoSessionLike(error) {
356
356
  }
357
357
  function isUsageLike(error) {
358
358
  if (!(error instanceof Error)) return false;
359
- return error.name === "CommanderError" || error.name === "InvalidArgumentError" || asRecord$6(error)?.code === "commander.invalidArgument";
359
+ return error.name === "CommanderError" || error.name === "InvalidArgumentError" || asRecord$7(error)?.code === "commander.invalidArgument";
360
360
  }
361
361
  function formatErrorMessage(error) {
362
362
  return formatUnknownErrorMessage(error);
@@ -364,7 +364,7 @@ function formatErrorMessage(error) {
364
364
  function isAcpQueryClosedBeforeResponseError(error) {
365
365
  const acp = extractAcpError(error);
366
366
  if (!acp || acp.code !== -32603) return false;
367
- const details = asRecord$6(acp.data)?.details;
367
+ const details = asRecord$7(acp.data)?.details;
368
368
  if (typeof details !== "string") return false;
369
369
  return details.toLowerCase().includes(QUERY_CLOSED_BEFORE_RESPONSE_DETAIL);
370
370
  }
@@ -432,7 +432,8 @@ function exitCodeForOutputErrorCode(code) {
432
432
  const ACP_ADAPTER_PACKAGE_RANGES = {
433
433
  pi: "^0.0.26",
434
434
  codex: "^0.0.44",
435
- claude: "^0.36.1"
435
+ claude: "^0.37.0",
436
+ mux: "^0.27.0"
436
437
  };
437
438
  const AGENT_REGISTRY = {
438
439
  pi: `npx pi-acp@${ACP_ADAPTER_PACKAGE_RANGES.pi}`,
@@ -443,10 +444,12 @@ const AGENT_REGISTRY = {
443
444
  cursor: "cursor-agent acp",
444
445
  copilot: "copilot --acp --stdio",
445
446
  droid: "droid exec --output-format acp",
447
+ "fast-agent": "uvx fast-agent-mcp acp",
446
448
  iflow: "iflow --experimental-acp",
447
449
  kilocode: "npx -y @kilocode/cli acp",
448
450
  kimi: "kimi acp",
449
451
  kiro: "kiro-cli-chat acp",
452
+ mux: `npx -y mux@${ACP_ADAPTER_PACKAGE_RANGES.mux} acp`,
450
453
  opencode: "npx -y opencode-ai acp",
451
454
  qoder: "qodercli --acp",
452
455
  qwen: "qwen --acp",
@@ -658,7 +661,7 @@ var PromptInputValidationError = class extends Error {
658
661
  this.name = "PromptInputValidationError";
659
662
  }
660
663
  };
661
- function asRecord$5(value) {
664
+ function asRecord$6(value) {
662
665
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
663
666
  return value;
664
667
  }
@@ -676,28 +679,28 @@ function isAudioMimeType(value) {
676
679
  return /^audio\/[A-Za-z0-9.+-]+$/i.test(value);
677
680
  }
678
681
  function isTextBlock(value) {
679
- const record = asRecord$5(value);
682
+ const record = asRecord$6(value);
680
683
  return record?.type === "text" && typeof record.text === "string";
681
684
  }
682
685
  function isImageBlock(value) {
683
- const record = asRecord$5(value);
686
+ const record = asRecord$6(value);
684
687
  return record?.type === "image" && isNonEmptyString(record.mimeType) && isImageMimeType(record.mimeType) && typeof record.data === "string" && isBase64Data(record.data);
685
688
  }
686
689
  function isAudioBlock(value) {
687
- const record = asRecord$5(value);
690
+ const record = asRecord$6(value);
688
691
  return record?.type === "audio" && isNonEmptyString(record.mimeType) && isAudioMimeType(record.mimeType) && typeof record.data === "string" && isBase64Data(record.data);
689
692
  }
690
693
  function isResourceLinkBlock(value) {
691
- const record = asRecord$5(value);
694
+ const record = asRecord$6(value);
692
695
  return record?.type === "resource_link" && isNonEmptyString(record.uri) && (record.title === void 0 || typeof record.title === "string") && (record.name === void 0 || typeof record.name === "string");
693
696
  }
694
697
  function isResourcePayload(value) {
695
- const record = asRecord$5(value);
698
+ const record = asRecord$6(value);
696
699
  if (!record || !isNonEmptyString(record.uri)) return false;
697
700
  return record.text === void 0 || typeof record.text === "string";
698
701
  }
699
702
  function isResourceBlock(value) {
700
- const record = asRecord$5(value);
703
+ const record = asRecord$6(value);
701
704
  return record?.type === "resource" && isResourcePayload(record.resource);
702
705
  }
703
706
  const CONTENT_BLOCK_VALIDATORS = [
@@ -741,11 +744,11 @@ function validateResourceLinkContentBlock(record, index) {
741
744
  if (record.name !== void 0 && typeof record.name !== "string") return `prompt[${index}] resource_link block name must be a string when present`;
742
745
  }
743
746
  function validateResourceContentBlock(record, index) {
744
- if (!asRecord$5(record.resource)) return `prompt[${index}] resource block must include a resource object`;
747
+ if (!asRecord$6(record.resource)) return `prompt[${index}] resource block must include a resource object`;
745
748
  return isResourcePayload(record.resource) ? void 0 : `prompt[${index}] resource block resource must include a non-empty uri and optional text`;
746
749
  }
747
750
  function getContentBlockValidationError(value, index) {
748
- const record = asRecord$5(value);
751
+ const record = asRecord$6(value);
749
752
  if (!record || typeof record.type !== "string") return `prompt[${index}] must be an ACP content block object`;
750
753
  const validator = contentBlockErrorValidator(record.type);
751
754
  return validator ? validator(record, index) : `prompt[${index}] has unsupported content block type ${JSON.stringify(record.type)}`;
@@ -828,15 +831,18 @@ function resourceBlockDisplayText(block) {
828
831
  }
829
832
  //#endregion
830
833
  //#region src/acp/jsonrpc.ts
831
- function asRecord$4(value) {
834
+ function asRecord$5(value) {
832
835
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
833
836
  return value;
834
837
  }
838
+ function isAcpMessageObject(value) {
839
+ return asRecord$5(value) !== null;
840
+ }
835
841
  function hasValidId(value) {
836
842
  return value === null || typeof value === "string" || typeof value === "number" && Number.isFinite(value);
837
843
  }
838
844
  function isErrorObject(value) {
839
- const record = asRecord$4(value);
845
+ const record = asRecord$5(value);
840
846
  return !!record && typeof record.code === "number" && Number.isFinite(record.code) && typeof record.message === "string";
841
847
  }
842
848
  function hasResultOrError(value) {
@@ -861,7 +867,7 @@ function isJsonRpcResponse(value) {
861
867
  return hasResultOrError(value);
862
868
  }
863
869
  function isAcpJsonRpcMessage(value) {
864
- const record = asRecord$4(value);
870
+ const record = asRecord$5(value);
865
871
  if (!record || record.jsonrpc !== "2.0") return false;
866
872
  return isJsonRpcNotificationRecord(record) || isJsonRpcRequest(record) || isJsonRpcResponse(record);
867
873
  }
@@ -873,11 +879,11 @@ function isSessionUpdateNotification(message) {
873
879
  }
874
880
  function extractSessionUpdateNotification(message) {
875
881
  if (!isSessionUpdateNotification(message)) return;
876
- const params = asRecord$4(message.params);
882
+ const params = asRecord$5(message.params);
877
883
  if (!params) return;
878
884
  const sessionId = typeof params.sessionId === "string" ? params.sessionId : null;
879
885
  if (!sessionId) return;
880
- const update = asRecord$4(params.update);
886
+ const update = asRecord$5(params.update);
881
887
  if (!update || typeof update.sessionUpdate !== "string") return;
882
888
  return {
883
889
  sessionId,
@@ -886,13 +892,13 @@ function extractSessionUpdateNotification(message) {
886
892
  }
887
893
  function parsePromptStopReason(message) {
888
894
  if (!Object.hasOwn(message, "id") || !Object.hasOwn(message, "result")) return;
889
- const record = asRecord$4(message.result);
895
+ const record = asRecord$5(message.result);
890
896
  if (!record) return;
891
897
  return typeof record.stopReason === "string" ? record.stopReason : void 0;
892
898
  }
893
899
  function parseJsonRpcErrorMessage(message) {
894
900
  if (!Object.hasOwn(message, "error")) return;
895
- const errorRecord = asRecord$4(message.error);
901
+ const errorRecord = asRecord$5(message.error);
896
902
  if (!errorRecord || typeof errorRecord.message !== "string") return;
897
903
  return errorRecord.message;
898
904
  }
@@ -987,6 +993,7 @@ function serializeSessionRecordForDisk(record) {
987
993
  messages: canonical.messages,
988
994
  updated_at: canonical.updated_at,
989
995
  cumulative_token_usage: canonical.cumulative_token_usage,
996
+ cumulative_cost: canonical.cumulative_cost,
990
997
  request_token_usage: canonical.request_token_usage,
991
998
  acpx: canonical.acpx,
992
999
  imported_from: canonical.importedFrom ? {
@@ -999,7 +1006,7 @@ function serializeSessionRecordForDisk(record) {
999
1006
  }
1000
1007
  //#endregion
1001
1008
  //#region src/session/persistence/parse.ts
1002
- function asRecord$3(value) {
1009
+ function asRecord$4(value) {
1003
1010
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
1004
1011
  return value;
1005
1012
  }
@@ -1009,16 +1016,55 @@ function hasOwn$1(source, key) {
1009
1016
  function isStringArray(value) {
1010
1017
  return Array.isArray(value) && value.every((entry) => typeof entry === "string");
1011
1018
  }
1019
+ function hasModelConfigOption(options) {
1020
+ if (!Array.isArray(options)) return false;
1021
+ return options.some((entry) => {
1022
+ const option = asRecord$4(entry);
1023
+ return option?.category === "model" || option?.id === "model";
1024
+ });
1025
+ }
1026
+ function parseConfigOptions(raw) {
1027
+ if (!Array.isArray(raw) || !raw.every((entry) => asRecord$4(entry) !== void 0)) return;
1028
+ return raw;
1029
+ }
1030
+ function parseAvailableCommand(raw) {
1031
+ if (typeof raw === "string") {
1032
+ const name = raw.trim();
1033
+ return name ? { name } : void 0;
1034
+ }
1035
+ const record = asRecord$4(raw);
1036
+ if (!record) return;
1037
+ const name = parseNonEmptyString(record.name);
1038
+ if (!name) return;
1039
+ const description = parseNonEmptyString(record.description);
1040
+ return {
1041
+ name,
1042
+ ...description ? { description } : {},
1043
+ ...typeof record.has_input === "boolean" ? { has_input: record.has_input } : {}
1044
+ };
1045
+ }
1046
+ function parseAvailableCommands(raw) {
1047
+ if (!Array.isArray(raw)) return;
1048
+ const commands = raw.map((entry) => parseAvailableCommand(entry)).filter((entry) => entry !== void 0);
1049
+ return commands.length > 0 ? commands : void 0;
1050
+ }
1051
+ function parseNonEmptyString(value) {
1052
+ if (typeof value !== "string") return;
1053
+ const trimmed = value.trim();
1054
+ return trimmed ? trimmed : void 0;
1055
+ }
1012
1056
  function parseTokenUsage(raw) {
1013
1057
  if (raw === void 0 || raw === null) return;
1014
- const record = asRecord$3(raw);
1058
+ const record = asRecord$4(raw);
1015
1059
  if (!record) return null;
1016
1060
  const usage = {};
1017
1061
  for (const field of [
1018
1062
  "input_tokens",
1019
1063
  "output_tokens",
1020
1064
  "cache_creation_input_tokens",
1021
- "cache_read_input_tokens"
1065
+ "cache_read_input_tokens",
1066
+ "thought_tokens",
1067
+ "total_tokens"
1022
1068
  ]) {
1023
1069
  const value = record[field];
1024
1070
  if (value === void 0) continue;
@@ -1030,9 +1076,35 @@ function parseTokenUsage(raw) {
1030
1076
  function isNonNegativeFiniteNumber(value) {
1031
1077
  return typeof value === "number" && Number.isFinite(value) && value >= 0;
1032
1078
  }
1079
+ function parseUsageCost(raw) {
1080
+ if (raw === void 0 || raw === null) return;
1081
+ const record = asRecord$4(raw);
1082
+ if (!record) return null;
1083
+ return parseUsageCostRecord(record);
1084
+ }
1085
+ function parseUsageCostRecord(record) {
1086
+ const amount = parseCostAmount(record.amount);
1087
+ const currency = parseCostCurrency(record.currency);
1088
+ if (amount === null || currency === null) return null;
1089
+ const cost = {
1090
+ ...amount !== void 0 ? { amount } : {},
1091
+ ...currency !== void 0 ? { currency } : {}
1092
+ };
1093
+ return Object.keys(cost).length > 0 ? cost : void 0;
1094
+ }
1095
+ function parseCostAmount(value) {
1096
+ if (value === void 0) return;
1097
+ return isNonNegativeFiniteNumber(value) ? value : null;
1098
+ }
1099
+ function parseCostCurrency(value) {
1100
+ if (value === void 0) return;
1101
+ if (typeof value !== "string") return null;
1102
+ const currency = value.trim();
1103
+ return currency.length > 0 ? currency : void 0;
1104
+ }
1033
1105
  function parseRequestTokenUsage(raw) {
1034
1106
  if (raw === void 0 || raw === null) return;
1035
- const record = asRecord$3(raw);
1107
+ const record = asRecord$4(raw);
1036
1108
  if (!record) return null;
1037
1109
  const usage = {};
1038
1110
  for (const [key, value] of Object.entries(record)) {
@@ -1043,25 +1115,25 @@ function parseRequestTokenUsage(raw) {
1043
1115
  return usage;
1044
1116
  }
1045
1117
  function isSessionMessageImage(raw) {
1046
- const record = asRecord$3(raw);
1118
+ const record = asRecord$4(raw);
1047
1119
  if (!record || typeof record.source !== "string") return false;
1048
1120
  if (record.size === void 0 || record.size === null) return true;
1049
- const size = asRecord$3(record.size);
1121
+ const size = asRecord$4(record.size);
1050
1122
  return !!size && isFiniteNumber(size.width) && isFiniteNumber(size.height);
1051
1123
  }
1052
1124
  function isSessionMessageAudio(raw) {
1053
- const record = asRecord$3(raw);
1125
+ const record = asRecord$4(raw);
1054
1126
  return !!record && typeof record.source === "string" && typeof record.mime_type === "string";
1055
1127
  }
1056
1128
  function isFiniteNumber(value) {
1057
1129
  return typeof value === "number" && Number.isFinite(value);
1058
1130
  }
1059
1131
  function isUserContent(raw) {
1060
- const record = asRecord$3(raw);
1132
+ const record = asRecord$4(raw);
1061
1133
  if (!record) return false;
1062
1134
  if (typeof record.Text === "string") return true;
1063
1135
  if (record.Mention !== void 0) {
1064
- const mention = asRecord$3(record.Mention);
1136
+ const mention = asRecord$4(record.Mention);
1065
1137
  return !!mention && typeof mention.uri === "string" && typeof mention.content === "string";
1066
1138
  }
1067
1139
  if (record.Image !== void 0) return isSessionMessageImage(record.Image);
@@ -1069,7 +1141,7 @@ function isUserContent(raw) {
1069
1141
  return false;
1070
1142
  }
1071
1143
  function isToolUse(raw) {
1072
- const record = asRecord$3(raw);
1144
+ const record = asRecord$4(raw);
1073
1145
  return !!record && hasStringFields(record, [
1074
1146
  "id",
1075
1147
  "name",
@@ -1083,18 +1155,18 @@ function isOptionalString(value) {
1083
1155
  return value === void 0 || value === null || typeof value === "string";
1084
1156
  }
1085
1157
  function isToolResultContent(raw) {
1086
- const record = asRecord$3(raw);
1158
+ const record = asRecord$4(raw);
1087
1159
  if (!record) return false;
1088
1160
  if (typeof record.Text === "string") return true;
1089
1161
  if (record.Image !== void 0) return isSessionMessageImage(record.Image);
1090
1162
  return false;
1091
1163
  }
1092
1164
  function isToolResult(raw) {
1093
- const record = asRecord$3(raw);
1165
+ const record = asRecord$4(raw);
1094
1166
  return !!record && typeof record.tool_use_id === "string" && typeof record.tool_name === "string" && typeof record.is_error === "boolean" && isToolResultContent(record.content);
1095
1167
  }
1096
1168
  function isAgentContent(raw) {
1097
- const record = asRecord$3(raw);
1169
+ const record = asRecord$4(raw);
1098
1170
  if (!record) return false;
1099
1171
  if (typeof record.Text === "string") return true;
1100
1172
  if (record.Thinking !== void 0) return isThinkingContent(record.Thinking);
@@ -1103,21 +1175,21 @@ function isAgentContent(raw) {
1103
1175
  return false;
1104
1176
  }
1105
1177
  function isThinkingContent(raw) {
1106
- const thinking = asRecord$3(raw);
1178
+ const thinking = asRecord$4(raw);
1107
1179
  return !!thinking && typeof thinking.text === "string" && isOptionalString(thinking.signature);
1108
1180
  }
1109
1181
  function isUserMessage$1(raw) {
1110
- const record = asRecord$3(raw);
1182
+ const record = asRecord$4(raw);
1111
1183
  if (!record || record.User === void 0) return false;
1112
- const user = asRecord$3(record.User);
1184
+ const user = asRecord$4(record.User);
1113
1185
  return !!user && typeof user.id === "string" && Array.isArray(user.content) && user.content.every((entry) => isUserContent(entry));
1114
1186
  }
1115
1187
  function isAgentMessage$1(raw) {
1116
- const record = asRecord$3(raw);
1188
+ const record = asRecord$4(raw);
1117
1189
  if (!record || record.Agent === void 0) return false;
1118
- const agent = asRecord$3(record.Agent);
1190
+ const agent = asRecord$4(record.Agent);
1119
1191
  if (!agent || !Array.isArray(agent.content) || !agent.content.every(isAgentContent)) return false;
1120
- const toolResults = asRecord$3(agent.tool_results);
1192
+ const toolResults = asRecord$4(agent.tool_results);
1121
1193
  if (!toolResults) return false;
1122
1194
  return Object.values(toolResults).every(isToolResult);
1123
1195
  }
@@ -1129,13 +1201,15 @@ function parseConversationRecord(record) {
1129
1201
  const title = parseConversationTitle(record.title);
1130
1202
  if (title === INVALID_VALUE) return;
1131
1203
  const cumulativeTokenUsage = parseTokenUsage(record.cumulative_token_usage);
1204
+ const cumulativeCost = parseUsageCost(record.cumulative_cost);
1132
1205
  const requestTokenUsage = parseRequestTokenUsage(record.request_token_usage);
1133
- if (cumulativeTokenUsage === null || requestTokenUsage === null) return;
1206
+ if (cumulativeTokenUsage === null || cumulativeCost === null || requestTokenUsage === null) return;
1134
1207
  return {
1135
1208
  title,
1136
1209
  messages: record.messages,
1137
1210
  updated_at: record.updated_at,
1138
1211
  cumulative_token_usage: cumulativeTokenUsage ?? {},
1212
+ cumulative_cost: cumulativeCost,
1139
1213
  request_token_usage: requestTokenUsage ?? {}
1140
1214
  };
1141
1215
  }
@@ -1148,20 +1222,27 @@ function hasValidConversationCore(record) {
1148
1222
  return Array.isArray(record.messages) && record.messages.every(isConversationMessage) && typeof record.updated_at === "string";
1149
1223
  }
1150
1224
  function parseAcpxState(raw) {
1151
- const record = asRecord$3(raw);
1225
+ const record = asRecord$4(raw);
1152
1226
  if (!record) return;
1153
1227
  const state = {};
1154
1228
  assignBooleanTrue(state, "reset_on_next_ensure", record.reset_on_next_ensure);
1155
1229
  assignStringState(state, "current_mode_id", record.current_mode_id);
1156
1230
  assignStringState(state, "desired_mode_id", record.desired_mode_id);
1157
1231
  assignDesiredConfigOptions(state, record.desired_config_options);
1158
- assignStringState(state, "current_model_id", record.current_model_id);
1159
- if (isStringArray(record.available_models)) state.available_models = [...record.available_models];
1160
- if (isStringArray(record.available_commands)) state.available_commands = [...record.available_commands];
1161
- if (Array.isArray(record.config_options)) state.config_options = record.config_options;
1232
+ assignParsedModelState(state, record);
1233
+ const availableCommands = parseAvailableCommands(record.available_commands);
1234
+ if (availableCommands) state.available_commands = availableCommands;
1162
1235
  assignParsedSessionOptions(state, record.session_options);
1163
1236
  return state;
1164
1237
  }
1238
+ function assignParsedModelState(state, record) {
1239
+ assignStringState(state, "current_model_id", record.current_model_id);
1240
+ if (isStringArray(record.available_models)) state.available_models = [...record.available_models];
1241
+ if (record.model_control === "config_option" || record.model_control === "legacy_set_model") state.model_control = record.model_control;
1242
+ const configOptions = parseConfigOptions(record.config_options);
1243
+ if (configOptions) state.config_options = configOptions;
1244
+ if (state.model_control === void 0 && state.available_models !== void 0) state.model_control = hasModelConfigOption(state.config_options) ? "config_option" : "legacy_set_model";
1245
+ }
1165
1246
  function assignBooleanTrue(state, key, value) {
1166
1247
  if (value === true) state[key] = true;
1167
1248
  }
@@ -1169,7 +1250,7 @@ function assignStringState(state, key, value) {
1169
1250
  if (typeof value === "string") state[key] = value;
1170
1251
  }
1171
1252
  function assignDesiredConfigOptions(state, raw) {
1172
- const desiredConfigOptions = asRecord$3(raw);
1253
+ const desiredConfigOptions = asRecord$4(raw);
1173
1254
  if (!desiredConfigOptions) return;
1174
1255
  const parsed = Object.fromEntries(Object.entries(desiredConfigOptions).filter((entry) => {
1175
1256
  const [, value] = entry;
@@ -1178,13 +1259,14 @@ function assignDesiredConfigOptions(state, raw) {
1178
1259
  if (Object.keys(parsed).length > 0) state.desired_config_options = parsed;
1179
1260
  }
1180
1261
  function assignParsedSessionOptions(state, raw) {
1181
- const sessionOptions = asRecord$3(raw);
1262
+ const sessionOptions = asRecord$4(raw);
1182
1263
  if (!sessionOptions) return;
1183
1264
  const parsedSessionOptions = {};
1184
1265
  assignSessionOptionModel(parsedSessionOptions, sessionOptions.model);
1185
1266
  assignSessionOptionAllowedTools(parsedSessionOptions, sessionOptions.allowed_tools);
1186
1267
  assignSessionOptionMaxTurns(parsedSessionOptions, sessionOptions.max_turns);
1187
1268
  assignSessionOptionSystemPrompt(parsedSessionOptions, sessionOptions.system_prompt);
1269
+ assignSessionOptionEnv(parsedSessionOptions, sessionOptions.env);
1188
1270
  if (Object.keys(parsedSessionOptions).length > 0) state.session_options = parsedSessionOptions;
1189
1271
  }
1190
1272
  function assignSessionOptionModel(options, value) {
@@ -1201,11 +1283,20 @@ function assignSessionOptionSystemPrompt(options, value) {
1201
1283
  options.system_prompt = value;
1202
1284
  return;
1203
1285
  }
1204
- const appendRecord = asRecord$3(value);
1286
+ const appendRecord = asRecord$4(value);
1205
1287
  if (appendRecord && typeof appendRecord.append === "string" && appendRecord.append.length > 0) options.system_prompt = { append: appendRecord.append };
1206
1288
  }
1289
+ function assignSessionOptionEnv(options, value) {
1290
+ const env = asRecord$4(value);
1291
+ if (!env) return;
1292
+ const parsed = Object.fromEntries(Object.entries(env).filter((entry) => {
1293
+ const [, raw] = entry;
1294
+ return typeof raw === "string";
1295
+ }));
1296
+ if (Object.keys(parsed).length > 0) options.env = parsed;
1297
+ }
1207
1298
  function parseEventLog(raw, sessionId) {
1208
- const record = asRecord$3(raw);
1299
+ const record = asRecord$4(raw);
1209
1300
  if (!record || !hasValidEventLogCore(record)) return defaultSessionEventLog(sessionId);
1210
1301
  return {
1211
1302
  active_path: record.active_path,
@@ -1224,7 +1315,7 @@ function isPositiveInteger(value) {
1224
1315
  }
1225
1316
  function parseImportedFrom(raw) {
1226
1317
  if (raw == null) return;
1227
- const record = asRecord$3(raw);
1318
+ const record = asRecord$4(raw);
1228
1319
  if (!record || typeof record.record_id !== "string" || typeof record.cwd_original !== "string" || typeof record.exported_by !== "string" || typeof record.exported_at !== "string") return null;
1229
1320
  return {
1230
1321
  recordId: record.record_id,
@@ -1275,7 +1366,7 @@ function normalizeOptionalSignal(value) {
1275
1366
  return Symbol("invalid");
1276
1367
  }
1277
1368
  function parseSessionRecord(raw) {
1278
- const record = asRecord$3(raw);
1369
+ const record = asRecord$4(raw);
1279
1370
  if (!record) return null;
1280
1371
  if (record.schema !== "acpx.session.v1") return null;
1281
1372
  const optionals = validSessionOptionals({
@@ -1319,11 +1410,12 @@ function parseSessionRecord(raw) {
1319
1410
  lastAgentExitAt: optionals.lastAgentExitAt,
1320
1411
  lastAgentDisconnectReason: optionals.lastAgentDisconnectReason,
1321
1412
  protocolVersion: typeof record.protocol_version === "number" ? record.protocol_version : void 0,
1322
- agentCapabilities: asRecord$3(record.agent_capabilities),
1413
+ agentCapabilities: asRecord$4(record.agent_capabilities),
1323
1414
  title: conversation.title,
1324
1415
  messages: conversation.messages,
1325
1416
  updated_at: conversation.updated_at,
1326
1417
  cumulative_token_usage: conversation.cumulative_token_usage,
1418
+ cumulative_cost: conversation.cumulative_cost,
1327
1419
  request_token_usage: conversation.request_token_usage,
1328
1420
  acpx: parseAcpxState(record.acpx),
1329
1421
  importedFrom: metadata.importedFrom
@@ -1427,7 +1519,7 @@ function formatPerfMetric(name, durationMsValue) {
1427
1519
  //#endregion
1428
1520
  //#region src/persisted-key-policy.ts
1429
1521
  const SNAKE_CASE_KEY = /^[a-z][a-z0-9_]*$/;
1430
- const ZED_TAG_KEYS = new Set([
1522
+ const ZED_TAG_KEYS = /* @__PURE__ */ new Set([
1431
1523
  "User",
1432
1524
  "Agent",
1433
1525
  "Resume",
@@ -1439,8 +1531,8 @@ const ZED_TAG_KEYS = new Set([
1439
1531
  "RedactedThinking",
1440
1532
  "ToolUse"
1441
1533
  ]);
1442
- const MAP_OBJECT_PATHS = new Set(["request_token_usage", "messages.Agent.tool_results"]);
1443
- const OPAQUE_VALUE_PATHS = new Set([
1534
+ const MAP_OBJECT_PATHS = /* @__PURE__ */ new Set(["request_token_usage", "messages.Agent.tool_results"]);
1535
+ const OPAQUE_VALUE_PATHS = /* @__PURE__ */ new Set([
1444
1536
  "agent_capabilities",
1445
1537
  "messages.Agent.content.ToolUse.input",
1446
1538
  "acpx.desired_config_options",
@@ -1498,12 +1590,12 @@ function assertPersistedKeyPolicy(value) {
1498
1590
  //#endregion
1499
1591
  //#region src/session/persistence/index.ts
1500
1592
  const SESSION_INDEX_SCHEMA = "acpx.session-index.v1";
1501
- function asRecord$2(value) {
1593
+ function asRecord$3(value) {
1502
1594
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
1503
1595
  return value;
1504
1596
  }
1505
1597
  function parseIndexEntry(raw) {
1506
- const record = asRecord$2(raw);
1598
+ const record = asRecord$3(raw);
1507
1599
  if (!record) return;
1508
1600
  if (!hasRequiredIndexEntryFields(record)) return;
1509
1601
  if (record.name !== void 0 && typeof record.name !== "string") return;
@@ -1547,7 +1639,7 @@ async function readSessionIndex(sessionDir) {
1547
1639
  const filePath = sessionIndexPath(sessionDir);
1548
1640
  try {
1549
1641
  const payload = await fs$1.readFile(filePath, "utf8");
1550
- const record = asRecord$2(JSON.parse(payload));
1642
+ const record = asRecord$3(JSON.parse(payload));
1551
1643
  if (!record || record.schema !== SESSION_INDEX_SCHEMA || !Array.isArray(record.files)) return;
1552
1644
  const files = record.files.filter((entry) => typeof entry === "string");
1553
1645
  if (files.length !== record.files.length || !Array.isArray(record.entries)) return;
@@ -1645,7 +1737,7 @@ async function writeSessionRecord(record) {
1645
1737
  const entries = index.entries.filter((entry) => entry.file !== fileName);
1646
1738
  entries.push(toSessionIndexEntry(record, fileName));
1647
1739
  await writeSessionIndex(sessionDir, {
1648
- files: [...new Set([...index.files.filter((entry) => entry !== fileName), fileName])],
1740
+ files: [.../* @__PURE__ */ new Set([...index.files.filter((entry) => entry !== fileName), fileName])],
1649
1741
  entries
1650
1742
  });
1651
1743
  });
@@ -2259,11 +2351,42 @@ function findExistingCommandInDirectory(directory, candidates) {
2259
2351
  if (trimmedDirectory.length === 0) return;
2260
2352
  return candidates.map((candidate) => path.join(trimmedDirectory, candidate)).find((resolved) => fs.existsSync(resolved));
2261
2353
  }
2354
+ function resolveWindowsWrapperToken(token, wrapperPath) {
2355
+ const relative = token.match(/%~?dp0%?\s*[\\/]*(.*)$/i)?.[1]?.trim();
2356
+ if (!relative) return;
2357
+ const candidate = path.resolve(path.dirname(wrapperPath), relative.replace(/[\\/]+/g, path.sep).replace(/^[\\/]+/, ""));
2358
+ return path.extname(candidate).toLowerCase() === ".exe" && fs.existsSync(candidate) ? candidate : void 0;
2359
+ }
2360
+ function resolveWindowsWrapperExecutable(wrapperPath) {
2361
+ if (!fs.existsSync(wrapperPath)) return;
2362
+ try {
2363
+ return [...fs.readFileSync(wrapperPath, "utf8").matchAll(/"([^"\r\n]*)"/g)].map((match) => resolveWindowsWrapperToken(match[1] ?? "", wrapperPath)).find((candidate) => candidate !== void 0);
2364
+ } catch {
2365
+ return;
2366
+ }
2367
+ }
2262
2368
  function resolveWindowsCommand(command, env = process.env) {
2263
2369
  const candidates = commandCandidates(command, env);
2264
2370
  if (commandHasPath(command)) return candidates.find((candidate) => fs.existsSync(candidate));
2265
2371
  return resolveWindowsPathCommand(command, env);
2266
2372
  }
2373
+ /**
2374
+ * Resolve a Windows command to a native executable suitable for direct spawn.
2375
+ *
2376
+ * Batch and PowerShell shims are intentionally rejected unless they point at a
2377
+ * real `.exe` entrypoint. Callers that need shell execution should use the
2378
+ * command-specific shell policy instead.
2379
+ */
2380
+ function resolveWindowsExecutablePath(command, env = process.env) {
2381
+ const resolved = resolveWindowsCommand(command, env);
2382
+ if (!resolved) return;
2383
+ const absolute = path.resolve(resolved);
2384
+ const extension = path.extname(absolute).toLowerCase();
2385
+ if (extension === ".exe") return absolute;
2386
+ if (extension !== ".cmd" && extension !== ".bat" && extension !== ".ps1") return;
2387
+ const siblingExecutable = `${absolute.slice(0, -extension.length)}.exe`;
2388
+ return fs.existsSync(siblingExecutable) ? siblingExecutable : resolveWindowsWrapperExecutable(absolute);
2389
+ }
2267
2390
  function shouldUseWindowsBatchShell(command, platform = process.platform, env = process.env) {
2268
2391
  if (platform !== "win32") return false;
2269
2392
  const resolvedCommand = resolveWindowsCommand(command, env) ?? command;
@@ -2302,6 +2425,49 @@ function buildTerminalShellSpawnCommand(command, platform = process.platform) {
2302
2425
  };
2303
2426
  }
2304
2427
  //#endregion
2428
+ //#region src/version.ts
2429
+ const UNKNOWN_VERSION = "0.0.0-unknown";
2430
+ const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
2431
+ let cachedVersion = null;
2432
+ function parseVersion(value) {
2433
+ if (typeof value !== "string") return null;
2434
+ const trimmed = value.trim();
2435
+ return trimmed.length > 0 ? trimmed : null;
2436
+ }
2437
+ function readPackageVersion(packageJsonPath) {
2438
+ try {
2439
+ return parseVersion(JSON.parse(readFileSync(packageJsonPath, "utf8")).version);
2440
+ } catch {
2441
+ return null;
2442
+ }
2443
+ }
2444
+ function resolveVersionFromAncestors(startDir) {
2445
+ let current = startDir;
2446
+ while (true) {
2447
+ const packageVersion = readPackageVersion(path.join(current, "package.json"));
2448
+ if (packageVersion) return packageVersion;
2449
+ const parent = path.dirname(current);
2450
+ if (parent === current) return null;
2451
+ current = parent;
2452
+ }
2453
+ }
2454
+ function resolveAcpxVersion(params) {
2455
+ const envVersion = resolvePackageEnvVersion(params?.env ?? process.env);
2456
+ if (envVersion) return envVersion;
2457
+ if (params?.packageJsonPath) return readPackageVersion(params.packageJsonPath) ?? UNKNOWN_VERSION;
2458
+ return resolveVersionFromAncestors(MODULE_DIR) ?? UNKNOWN_VERSION;
2459
+ }
2460
+ function resolvePackageEnvVersion(env) {
2461
+ const envPackageName = parseVersion(env.npm_package_name);
2462
+ const envVersion = parseVersion(env.npm_package_version);
2463
+ return envPackageName === "acpx" ? envVersion : null;
2464
+ }
2465
+ function getAcpxVersion() {
2466
+ if (cachedVersion) return cachedVersion;
2467
+ cachedVersion = resolveAcpxVersion();
2468
+ return cachedVersion;
2469
+ }
2470
+ //#endregion
2305
2471
  //#region src/acp/client-process.ts
2306
2472
  const execFileAsync = promisify(execFile);
2307
2473
  function isoNow$1() {
@@ -2355,22 +2521,29 @@ function splitCommandLine(value) {
2355
2521
  let current = "";
2356
2522
  let quote = null;
2357
2523
  let escaping = false;
2524
+ let hasPart = false;
2358
2525
  for (const ch of value) {
2359
2526
  const next = readCommandLineChar({
2360
2527
  ch,
2361
2528
  current,
2362
2529
  quote,
2363
2530
  escaping,
2364
- parts
2531
+ parts,
2532
+ hasPart
2365
2533
  });
2366
2534
  current = next.current;
2367
2535
  quote = next.quote;
2368
2536
  escaping = next.escaping;
2537
+ hasPart = next.hasPart;
2538
+ }
2539
+ if (escaping) {
2540
+ current += "\\";
2541
+ hasPart = true;
2369
2542
  }
2370
- if (escaping) current += "\\";
2371
2543
  if (quote) throw new Error("Invalid --agent command: unterminated quote");
2372
- if (current.length > 0) parts.push(current);
2544
+ if (hasPart) parts.push(current);
2373
2545
  if (parts.length === 0) throw new Error("Invalid --agent command: empty command");
2546
+ if (parts[0] === "") throw new Error("Invalid --agent command: empty command");
2374
2547
  return {
2375
2548
  command: parts[0],
2376
2549
  args: parts.slice(1)
@@ -2380,17 +2553,20 @@ function readCommandLineChar(state) {
2380
2553
  if (state.escaping) return {
2381
2554
  current: state.current + state.ch,
2382
2555
  quote: state.quote,
2383
- escaping: false
2556
+ escaping: false,
2557
+ hasPart: true
2384
2558
  };
2385
2559
  if (state.ch === "\\" && state.quote !== "'") return {
2386
2560
  current: state.current,
2387
2561
  quote: state.quote,
2388
- escaping: true
2562
+ escaping: true,
2563
+ hasPart: state.hasPart
2389
2564
  };
2390
2565
  if (state.quote) return readQuotedCommandLineChar({
2391
2566
  ch: state.ch,
2392
2567
  current: state.current,
2393
- quote: state.quote
2568
+ quote: state.quote,
2569
+ hasPart: state.hasPart
2394
2570
  });
2395
2571
  return readUnquotedCommandLineChar(state);
2396
2572
  }
@@ -2398,36 +2574,41 @@ function readQuotedCommandLineChar(state) {
2398
2574
  if (state.ch === state.quote) return {
2399
2575
  current: state.current,
2400
2576
  quote: null,
2401
- escaping: false
2577
+ escaping: false,
2578
+ hasPart: true
2402
2579
  };
2403
2580
  return {
2404
2581
  current: state.current + state.ch,
2405
2582
  quote: state.quote,
2406
- escaping: false
2583
+ escaping: false,
2584
+ hasPart: true
2407
2585
  };
2408
2586
  }
2409
2587
  function readUnquotedCommandLineChar(state) {
2410
2588
  if (state.ch === "'" || state.ch === "\"") return {
2411
2589
  current: state.current,
2412
2590
  quote: state.ch,
2413
- escaping: false
2591
+ escaping: false,
2592
+ hasPart: true
2414
2593
  };
2415
2594
  if (/\s/.test(state.ch)) {
2416
- flushCommandLinePart(state.parts, state.current);
2595
+ flushCommandLinePart(state.parts, state.current, state.hasPart);
2417
2596
  return {
2418
2597
  current: "",
2419
2598
  quote: null,
2420
- escaping: false
2599
+ escaping: false,
2600
+ hasPart: false
2421
2601
  };
2422
2602
  }
2423
2603
  return {
2424
2604
  current: state.current + state.ch,
2425
2605
  quote: null,
2426
- escaping: false
2606
+ escaping: false,
2607
+ hasPart: true
2427
2608
  };
2428
2609
  }
2429
- function flushCommandLinePart(parts, current) {
2430
- if (current.length > 0) parts.push(current);
2610
+ function flushCommandLinePart(parts, current, hasPart) {
2611
+ if (hasPart) parts.push(current);
2431
2612
  }
2432
2613
  function asAbsoluteCwd(cwd) {
2433
2614
  return path.resolve(cwd);
@@ -2477,7 +2658,8 @@ const GEMINI_ACP_FLAG_VERSION = [
2477
2658
  0
2478
2659
  ];
2479
2660
  const COPILOT_HELP_TIMEOUT_MS = 2e3;
2480
- const QODER_BENIGN_STDOUT_LINES = new Set(["Received interrupt signal. Cleaning up resources...", "Cleanup completed. Exiting..."]);
2661
+ const CLAUDE_CODE_DEFAULT_SETTING_SOURCES = ["project", "local"];
2662
+ const QODER_BENIGN_STDOUT_LINES = /* @__PURE__ */ new Set(["Received interrupt signal. Cleaning up resources...", "Cleanup completed. Exiting..."]);
2481
2663
  function resolveAgentCloseAfterStdinEndMs(agentCommand) {
2482
2664
  const { command } = splitCommandLine(agentCommand);
2483
2665
  return basenameToken(command) === "qodercli" ? QODER_AGENT_CLOSE_AFTER_STDIN_END_MS : DEFAULT_AGENT_CLOSE_AFTER_STDIN_END_MS;
@@ -2499,6 +2681,13 @@ function isCopilotAcpCommand(command, args) {
2499
2681
  function isQoderAcpCommand(command, args) {
2500
2682
  return basenameToken(command) === "qodercli" && args.includes("--acp");
2501
2683
  }
2684
+ function isCursorAcpCommand(command, args) {
2685
+ const commandToken = basenameToken(command);
2686
+ return commandToken === "cursor-agent" || commandToken === "agent" && args.includes("acp");
2687
+ }
2688
+ function isDevinAcpCommand(command, args) {
2689
+ return basenameToken(command) === "devin" && (args.includes("acp") || args.includes("--acp") || args.includes("--experimental-acp"));
2690
+ }
2502
2691
  function hasCommandFlag(args, flagName) {
2503
2692
  return args.some((arg) => arg === flagName || arg.startsWith(`${flagName}=`));
2504
2693
  }
@@ -2639,16 +2828,20 @@ async function ensureCopilotAcpSupport(command) {
2639
2828
  const helpOutput = await readCommandOutput(command, ["--help"], COPILOT_HELP_TIMEOUT_MS);
2640
2829
  if (typeof helpOutput === "string" && !helpOutput.includes("--acp")) throw new CopilotAcpUnsupportedError(await buildCopilotAcpUnsupportedMessage(command), { retryable: false });
2641
2830
  }
2642
- function buildClaudeCodeOptionsMeta(options) {
2643
- if (!options) return;
2831
+ function buildClaudeCodeOptionsMeta(options, isolateUserSettings = false) {
2644
2832
  const claudeCodeOptions = {};
2645
- assignClaudeCodeOptions(claudeCodeOptions, options);
2833
+ if (isolateUserSettings) claudeCodeOptions.settingSources = resolveClaudeCodeSettingSources();
2834
+ if (options) assignClaudeCodeOptions(claudeCodeOptions, options);
2646
2835
  const meta = {};
2647
2836
  if (Object.keys(claudeCodeOptions).length > 0) meta.claudeCode = { options: claudeCodeOptions };
2648
- assignClaudeCodeSystemPrompt(meta, options.systemPrompt);
2837
+ assignClaudeCodeSystemPrompt(meta, options?.systemPrompt);
2649
2838
  if (Object.keys(meta).length === 0) return;
2650
2839
  return meta;
2651
2840
  }
2841
+ function resolveClaudeCodeSettingSources(env = process.env) {
2842
+ if (env.ACPX_CLAUDE_INCLUDE_USER_SETTINGS?.trim() === "1") return ["user", ...CLAUDE_CODE_DEFAULT_SETTING_SOURCES];
2843
+ return [...CLAUDE_CODE_DEFAULT_SETTING_SOURCES];
2844
+ }
2652
2845
  function assignClaudeCodeOptions(target, options) {
2653
2846
  if (typeof options.model === "string" && options.model.trim().length > 0) target.model = options.model;
2654
2847
  if (Array.isArray(options.allowedTools)) target.allowedTools = [...options.allowedTools];
@@ -2667,9 +2860,7 @@ function isAppendSystemPrompt(value) {
2667
2860
  function resolveClaudeCodeExecutable(platform = process.platform, env = process.env) {
2668
2861
  if (platform !== "win32") return;
2669
2862
  if (readWindowsEnvValue(env, "CLAUDE_CODE_EXECUTABLE")) return;
2670
- const resolved = resolveWindowsCommand("claude", env);
2671
- if (!resolved) return;
2672
- return path.resolve(resolved);
2863
+ return resolveWindowsExecutablePath("claude", env);
2673
2864
  }
2674
2865
  //#endregion
2675
2866
  //#region src/acp/auth-env.ts
@@ -2695,22 +2886,58 @@ function readEnvCredential(methodId) {
2695
2886
  const value = process.env[key];
2696
2887
  if (typeof value === "string" && value.trim().length > 0) return value;
2697
2888
  }
2889
+ function protectedEnvKey(key) {
2890
+ return process.platform === "win32" ? key.toUpperCase() : key;
2891
+ }
2892
+ function isAuthEnvKey(key) {
2893
+ return protectedEnvKey(key).startsWith(AUTH_ENV_PREFIX);
2894
+ }
2895
+ function authEnvSuffix(key) {
2896
+ return key.slice(10);
2897
+ }
2898
+ function protectEnvKey(protectedKeys, key) {
2899
+ protectedKeys.add(protectedEnvKey(key));
2900
+ }
2698
2901
  function promotePrefixedAuthEnvironment(env) {
2902
+ const protectedKeys = /* @__PURE__ */ new Set();
2699
2903
  for (const [key, value] of Object.entries(env)) {
2700
- if (!key.startsWith(AUTH_ENV_PREFIX)) continue;
2904
+ if (!isAuthEnvKey(key)) continue;
2701
2905
  if (typeof value !== "string" || value.trim().length === 0) continue;
2702
- const normalized = key.slice(10);
2703
- if (!normalized || env[normalized] != null) continue;
2704
- env[normalized] = value;
2906
+ const normalized = toEnvToken(authEnvSuffix(key));
2907
+ if (!normalized) continue;
2908
+ protectEnvKey(protectedKeys, key);
2909
+ protectEnvKey(protectedKeys, normalized);
2910
+ if (env[normalized] == null) env[normalized] = value;
2705
2911
  }
2912
+ return protectedKeys;
2706
2913
  }
2707
- function buildAgentEnvironment(authCredentials) {
2914
+ function buildAgentEnvironment(authCredentials, sessionEnv) {
2708
2915
  const env = { ...process.env };
2709
- promotePrefixedAuthEnvironment(env);
2710
- if (!authCredentials) return env;
2711
- for (const [methodId, credential] of Object.entries(authCredentials)) assignAuthCredentialEnv(env, methodId, credential);
2916
+ const protectedAuthEnvKeys = promotePrefixedAuthEnvironment(env);
2917
+ if (authCredentials) for (const [methodId, credential] of Object.entries(authCredentials)) {
2918
+ addAuthCredentialEnvKeys(protectedAuthEnvKeys, methodId, credential);
2919
+ assignAuthCredentialEnv(env, methodId, credential);
2920
+ }
2921
+ if (sessionEnv) for (const [key, value] of Object.entries(sessionEnv)) {
2922
+ if (typeof value !== "string" || protectedAuthEnvKeys.has(protectedEnvKey(key))) continue;
2923
+ assignSessionEnv(env, key, value);
2924
+ }
2712
2925
  return env;
2713
2926
  }
2927
+ function assignSessionEnv(env, key, value) {
2928
+ const normalizedKey = protectedEnvKey(key);
2929
+ for (const existingKey of Object.keys(env)) if (protectedEnvKey(existingKey) === normalizedKey) delete env[existingKey];
2930
+ env[key] = value;
2931
+ }
2932
+ function addAuthCredentialEnvKeys(protectedKeys, methodId, credential) {
2933
+ if (typeof credential !== "string" || credential.trim().length === 0) return;
2934
+ if (!methodId.includes("=") && !methodId.includes("\0")) protectEnvKey(protectedKeys, methodId);
2935
+ const normalized = toEnvToken(methodId);
2936
+ if (normalized) {
2937
+ protectEnvKey(protectedKeys, `${AUTH_ENV_PREFIX}${normalized}`);
2938
+ protectEnvKey(protectedKeys, normalized);
2939
+ }
2940
+ }
2714
2941
  function assignAuthCredentialEnv(env, methodId, credential) {
2715
2942
  if (typeof credential !== "string" || credential.trim().length === 0) return;
2716
2943
  if (!methodId.includes("=") && !methodId.includes("\0") && env[methodId] == null) env[methodId] = credential;
@@ -2727,10 +2954,10 @@ function resolveConfiguredAuthCredential(methodId, authCredentials) {
2727
2954
  const configCredentials = authCredentials ?? {};
2728
2955
  return configCredentials[methodId] ?? configCredentials[toEnvToken(methodId)];
2729
2956
  }
2730
- function buildAgentSpawnOptions(cwd, authCredentials) {
2957
+ function buildAgentSpawnOptions(cwd, authCredentials, sessionEnv) {
2731
2958
  return {
2732
2959
  cwd,
2733
- env: buildAgentEnvironment(authCredentials),
2960
+ env: buildAgentEnvironment(authCredentials, sessionEnv),
2734
2961
  stdio: [
2735
2962
  "pipe",
2736
2963
  "pipe",
@@ -2740,8 +2967,127 @@ function buildAgentSpawnOptions(cwd, authCredentials) {
2740
2967
  };
2741
2968
  }
2742
2969
  //#endregion
2970
+ //#region src/acp/model-support.ts
2971
+ const REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE = "ACP_MODEL_UNSUPPORTED";
2972
+ const REQUESTED_MODEL_UNSUPPORTED_REASONS = ["missing-capability", "unadvertised-model"];
2973
+ var RequestedModelUnsupportedError = class extends Error {
2974
+ code = REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE;
2975
+ reason;
2976
+ constructor(message, reason) {
2977
+ super(message);
2978
+ this.name = "RequestedModelUnsupportedError";
2979
+ this.reason = reason;
2980
+ }
2981
+ };
2982
+ function isRequestedModelUnsupportedReason(value) {
2983
+ return typeof value === "string" && REQUESTED_MODEL_UNSUPPORTED_REASONS.includes(value);
2984
+ }
2985
+ function isRequestedModelUnsupportedError(value) {
2986
+ if (value instanceof RequestedModelUnsupportedError) return true;
2987
+ if (!value || typeof value !== "object") return false;
2988
+ const candidate = value;
2989
+ return candidate.name === "RequestedModelUnsupportedError" && candidate.code === "ACP_MODEL_UNSUPPORTED" && isRequestedModelUnsupportedReason(candidate.reason);
2990
+ }
2991
+ function supportsLegacyClaudeCodeModelMetadata(agentCommand) {
2992
+ if (!agentCommand) return false;
2993
+ const { command, args } = splitCommandLine(agentCommand);
2994
+ return isClaudeAcpCommand(command, args);
2995
+ }
2996
+ function asRecord$2(value) {
2997
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
2998
+ return value;
2999
+ }
3000
+ function parseAvailableModel(value) {
3001
+ const option = asRecord$2(value);
3002
+ if (!option || typeof option.value !== "string" || typeof option.name !== "string") return;
3003
+ return {
3004
+ modelId: option.value,
3005
+ name: option.name
3006
+ };
3007
+ }
3008
+ function parseAvailableModelGroup(value) {
3009
+ const group = asRecord$2(value);
3010
+ if (!group || typeof group.group !== "string" || typeof group.name !== "string" || !Array.isArray(group.options)) return;
3011
+ const models = group.options.map((option) => parseAvailableModel(option));
3012
+ return models.every((model) => model !== void 0) ? models : void 0;
3013
+ }
3014
+ function parseAvailableModels(value) {
3015
+ if (!Array.isArray(value)) return;
3016
+ const directModels = value.map((option) => parseAvailableModel(option));
3017
+ if (directModels.every((model) => model !== void 0)) return directModels;
3018
+ const groupedModels = value.map((group) => parseAvailableModelGroup(group));
3019
+ return groupedModels.every((models) => models !== void 0) ? groupedModels.flat() : void 0;
3020
+ }
3021
+ function isModelSelectOption(option) {
3022
+ return option.type === "select" && (option.category === "model" || option.id === "model");
3023
+ }
3024
+ function parseModelConfigOption(value) {
3025
+ const option = asRecord$2(value);
3026
+ if (!option || !isModelSelectOption(option) || typeof option.id !== "string" || typeof option.currentValue !== "string") return;
3027
+ const availableModels = parseAvailableModels(option.options);
3028
+ return availableModels ? {
3029
+ configId: option.id,
3030
+ currentModelId: option.currentValue,
3031
+ availableModels
3032
+ } : void 0;
3033
+ }
3034
+ function modelStateFromConfigOptions(configOptions) {
3035
+ if (!Array.isArray(configOptions)) return;
3036
+ for (const value of configOptions) {
3037
+ const models = parseModelConfigOption(value);
3038
+ if (models) return models;
3039
+ }
3040
+ }
3041
+ function modelStateFromLegacyResponse(response) {
3042
+ if (!response || typeof response !== "object") return;
3043
+ const models = response.models;
3044
+ if (!models || typeof models.currentModelId !== "string" || !Array.isArray(models.availableModels)) return;
3045
+ const availableModels = models.availableModels.flatMap((entry) => {
3046
+ if (!entry || typeof entry !== "object") return [];
3047
+ const candidate = entry;
3048
+ return typeof candidate.modelId === "string" && typeof candidate.name === "string" ? [{
3049
+ modelId: candidate.modelId,
3050
+ name: candidate.name
3051
+ }] : [];
3052
+ });
3053
+ return {
3054
+ currentModelId: models.currentModelId,
3055
+ availableModels
3056
+ };
3057
+ }
3058
+ function modelStateFromSessionResponse(params) {
3059
+ return modelStateFromConfigOptions(params.configOptions) ?? modelStateFromLegacyResponse(params.response);
3060
+ }
3061
+ function formatAvailableModelIds(models) {
3062
+ const ids = models?.availableModels.map((model) => model.modelId.trim()).filter((modelId) => modelId.length > 0) ?? [];
3063
+ return ids.length > 0 ? ids.join(", ") : "none advertised";
3064
+ }
3065
+ function resolveRequestedModelId(params) {
3066
+ if (!params.models || !isCursorAcpCommandForModelAlias(params.agentCommand)) return params.requestedModel;
3067
+ if (params.models.availableModels.some((model) => model.modelId === params.requestedModel)) return params.requestedModel;
3068
+ const candidates = params.models.availableModels.map((model) => model.modelId).filter((modelId) => modelId.startsWith(`${params.requestedModel}[`));
3069
+ return candidates.length === 1 ? candidates[0] : params.requestedModel;
3070
+ }
3071
+ function isCursorAcpCommandForModelAlias(agentCommand) {
3072
+ if (!agentCommand) return false;
3073
+ const { command, args } = splitCommandLine(agentCommand);
3074
+ return isCursorAcpCommand(command, args);
3075
+ }
3076
+ function assertRequestedModelSupported(params) {
3077
+ if (!params.models) {
3078
+ if (supportsLegacyClaudeCodeModelMetadata(params.agentCommand)) return;
3079
+ throw new RequestedModelUnsupportedError(`Cannot ${params.context === "replay" ? "replay saved model" : "apply --model"} "${params.requestedModel}": the ACP agent did not advertise model support through a session config option or legacy models metadata, and the adapter does not support a startup model flag.`, "missing-capability");
3080
+ }
3081
+ if (!new Set(params.models.availableModels.map((model) => model.modelId)).has(params.requestedModel)) {
3082
+ const resolvedModel = resolveRequestedModelId(params);
3083
+ if (resolvedModel !== params.requestedModel) return `Cursor ACP advertised "${resolvedModel}" for requested model "${params.requestedModel}"; using the advertised id.`;
3084
+ if (supportsLegacyClaudeCodeModelMetadata(params.agentCommand)) return `requested model "${params.requestedModel}" was not in the Claude ACP advertised model list (${formatAvailableModelIds(params.models)}); forwarding it to Claude Code so the adapter can accept or reject it.`;
3085
+ throw new RequestedModelUnsupportedError(`Cannot ${params.context === "replay" ? "replay saved model" : "apply --model"} "${params.requestedModel}": the ACP agent did not advertise that model. Available models: ${formatAvailableModelIds(params.models)}.`, "unadvertised-model");
3086
+ }
3087
+ }
3088
+ //#endregion
2743
3089
  //#region src/acp/session-control-errors.ts
2744
- const SESSION_CONTROL_UNSUPPORTED_ACP_CODES = new Set([-32601, -32602]);
3090
+ const SESSION_CONTROL_UNSUPPORTED_ACP_CODES = /* @__PURE__ */ new Set([-32601, -32602]);
2745
3091
  function asRecord$1(value) {
2746
3092
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
2747
3093
  return value;
@@ -3356,11 +3702,54 @@ const DRAIN_POLL_INTERVAL_MS = 20;
3356
3702
  const AGENT_CLOSE_TERM_GRACE_MS = 1500;
3357
3703
  const AGENT_CLOSE_KILL_GRACE_MS = 1e3;
3358
3704
  const STARTUP_STDERR_MAX_CHARS = 8192;
3705
+ const DEVIN_COMPATIBILITY_CLIENT_CAPABILITIES_META = Object.freeze({ "cognition.ai/requestDiagnostics": true });
3706
+ const DEVIN_COMPATIBILITY_CLIENT_NAME = "windsurf";
3707
+ const DEFAULT_DEVIN_COMPATIBILITY_CLIENT_VERSION = "1.110.1";
3708
+ function resolveClientInfo(devinAcp) {
3709
+ if (!devinAcp) return {
3710
+ name: "acpx",
3711
+ version: getAcpxVersion()
3712
+ };
3713
+ return {
3714
+ name: DEVIN_COMPATIBILITY_CLIENT_NAME,
3715
+ version: process.env.ACPX_DEVIN_WINDSURF_VERSION ?? DEFAULT_DEVIN_COMPATIBILITY_CLIENT_VERSION
3716
+ };
3717
+ }
3718
+ function resolveClientCapabilities(params) {
3719
+ const baseCapabilities = {
3720
+ fs: {
3721
+ readTextFile: true,
3722
+ writeTextFile: true
3723
+ },
3724
+ terminal: params.terminal
3725
+ };
3726
+ if (!params.devinAcp) return baseCapabilities;
3727
+ return {
3728
+ ...baseCapabilities,
3729
+ _meta: DEVIN_COMPATIBILITY_CLIENT_CAPABILITIES_META
3730
+ };
3731
+ }
3732
+ function isDevinRequestDiagnosticsMethod(method) {
3733
+ return method === "_cognition.ai/request_diagnostics";
3734
+ }
3735
+ function hasResponseField(response, field) {
3736
+ return !!response && typeof response === "object" && field in response;
3737
+ }
3738
+ function normalizeResponseConfigOptions(response) {
3739
+ if (!response || !("configOptions" in response)) return;
3740
+ return response.configOptions ?? [];
3741
+ }
3359
3742
  function toReconnectedSessionResult(response) {
3743
+ const configOptions = normalizeResponseConfigOptions(response);
3360
3744
  return {
3361
3745
  agentSessionId: extractRuntimeSessionId(response?._meta),
3362
- configOptions: response?.configOptions ?? void 0,
3363
- models: response?.models ?? void 0
3746
+ configOptions,
3747
+ models: modelStateFromSessionResponse({
3748
+ configOptions,
3749
+ response
3750
+ }),
3751
+ configOptionsPresent: hasResponseField(response, "configOptions"),
3752
+ legacyModelMetadataPresent: hasResponseField(response, "models")
3364
3753
  };
3365
3754
  }
3366
3755
  function childProcessIsRunning(agent) {
@@ -3388,12 +3777,16 @@ function enqueueNdJsonLine(agentCommand, line, controller) {
3388
3777
  const trimmedLine = line.trim();
3389
3778
  if (!trimmedLine || shouldIgnoreNonJsonAgentOutputLine(agentCommand, trimmedLine)) return;
3390
3779
  try {
3391
- const message = JSON.parse(trimmedLine);
3392
- controller.enqueue(message);
3780
+ const message = parseAcpJsonMessageLine(trimmedLine);
3781
+ if (message) controller.enqueue(message);
3393
3782
  } catch (err) {
3394
3783
  console.error("Failed to parse JSON message:", trimmedLine, err);
3395
3784
  }
3396
3785
  }
3786
+ function parseAcpJsonMessageLine(line) {
3787
+ const message = JSON.parse(line);
3788
+ return isAcpMessageObject(message) ? message : void 0;
3789
+ }
3397
3790
  function enqueueNdJsonLines(agentCommand, lines, controller) {
3398
3791
  for (const line of lines) enqueueNdJsonLine(agentCommand, line, controller);
3399
3792
  }
@@ -3459,6 +3852,8 @@ var AcpClient = class {
3459
3852
  lastKnownPid;
3460
3853
  promptPermissionFailures = /* @__PURE__ */ new Map();
3461
3854
  pendingConnectionRequests = /* @__PURE__ */ new Set();
3855
+ modelConfigIds = /* @__PURE__ */ new Map();
3856
+ legacyModelSessionIds = /* @__PURE__ */ new Set();
3462
3857
  constructor(options) {
3463
3858
  this.options = {
3464
3859
  ...options,
@@ -3570,7 +3965,7 @@ var AcpClient = class {
3570
3965
  const input = Writable.toWeb(child.stdin);
3571
3966
  const output = Readable.toWeb(child.stdout);
3572
3967
  const stream = this.createTappedStream(createNdJsonMessageStream(this.options.agentCommand, input, output));
3573
- const connection = this.createConnection(stream);
3968
+ const connection = this.createConnection(stream, launch);
3574
3969
  connection.signal.addEventListener("abort", () => {
3575
3970
  this.recordAgentExit("connection_close", child.exitCode ?? null, child.signalCode ?? null);
3576
3971
  }, { once: true });
@@ -3594,10 +3989,11 @@ var AcpClient = class {
3594
3989
  spawnCommand,
3595
3990
  args,
3596
3991
  resolvedBuiltInLaunch,
3992
+ devinAcp: isDevinAcpCommand(spawnCommand, args),
3597
3993
  geminiAcp: isGeminiAcpCommand(spawnCommand, args),
3598
3994
  copilotAcp: isCopilotAcpCommand(spawnCommand, args),
3599
3995
  claudeAcp: isClaudeAcpCommand(spawnCommand, args),
3600
- spawnOptions: buildAgentSpawnOptions(this.options.cwd, this.options.authCredentials)
3996
+ spawnOptions: buildAgentSpawnOptions(this.options.cwd, this.options.authCredentials, this.options.sessionOptions?.env)
3601
3997
  };
3602
3998
  }
3603
3999
  logAgentLaunch(plan) {
@@ -3630,7 +4026,7 @@ var AcpClient = class {
3630
4026
  }
3631
4027
  return requireAgentStdio(spawnedChild);
3632
4028
  }
3633
- createConnection(stream) {
4029
+ createConnection(stream, launch) {
3634
4030
  return new ClientSideConnection(() => ({
3635
4031
  sessionUpdate: async (params) => {
3636
4032
  await this.handleSessionUpdate(params);
@@ -3638,6 +4034,12 @@ var AcpClient = class {
3638
4034
  requestPermission: async (params) => {
3639
4035
  return this.handlePermissionRequest(params);
3640
4036
  },
4037
+ extMethod: async (method) => {
4038
+ if (launch.devinAcp && isDevinRequestDiagnosticsMethod(method)) return {};
4039
+ const error = RequestError.methodNotFound(method);
4040
+ if (!this.options.suppressSdkConsoleErrors) console.error(error.message);
4041
+ throw error;
4042
+ },
3641
4043
  readTextFile: async (params) => {
3642
4044
  return this.handleReadTextFile(params);
3643
4045
  },
@@ -3658,12 +4060,13 @@ var AcpClient = class {
3658
4060
  },
3659
4061
  releaseTerminal: async (params) => {
3660
4062
  return this.handleReleaseTerminal(params);
3661
- }
4063
+ },
4064
+ extNotification: async () => {}
3662
4065
  }), stream);
3663
4066
  }
3664
4067
  async initializeAgentConnection(params) {
3665
4068
  try {
3666
- const initResult = await Promise.race([this.initializeProtocolConnection(params.connection, params.launch.geminiAcp), params.startupFailure.promise]);
4069
+ const initResult = await Promise.race([this.initializeProtocolConnection(params.connection, params.launch), params.startupFailure.promise]);
3667
4070
  params.startupFailure.dispose();
3668
4071
  this.connection = params.connection;
3669
4072
  this.agent = params.child;
@@ -3673,22 +4076,16 @@ var AcpClient = class {
3673
4076
  await this.handleInitializeFailure(params, error);
3674
4077
  }
3675
4078
  }
3676
- async initializeProtocolConnection(connection, geminiAcp) {
4079
+ async initializeProtocolConnection(connection, launch) {
3677
4080
  const initializePromise = connection.initialize({
3678
4081
  protocolVersion: PROTOCOL_VERSION,
3679
- clientCapabilities: {
3680
- fs: {
3681
- readTextFile: true,
3682
- writeTextFile: true
3683
- },
4082
+ clientCapabilities: resolveClientCapabilities({
4083
+ devinAcp: launch.devinAcp,
3684
4084
  terminal: this.options.terminal !== false
3685
- },
3686
- clientInfo: {
3687
- name: "acpx",
3688
- version: "0.1.0"
3689
- }
4085
+ }),
4086
+ clientInfo: resolveClientInfo(launch.devinAcp)
3690
4087
  });
3691
- const initialized = geminiAcp ? await withTimeout(initializePromise, resolveGeminiAcpStartupTimeoutMs()) : await initializePromise;
4088
+ const initialized = launch.geminiAcp ? await withTimeout(initializePromise, resolveGeminiAcpStartupTimeoutMs()) : await initializePromise;
3692
4089
  await this.authenticateIfRequired(connection, initialized.authMethods ?? []);
3693
4090
  return initialized;
3694
4091
  }
@@ -3751,7 +4148,7 @@ var AcpClient = class {
3751
4148
  const createPromise = this.runConnectionRequest(() => connection.newSession({
3752
4149
  cwd: sessionCwd,
3753
4150
  mcpServers: this.options.mcpServers ?? [],
3754
- _meta: buildClaudeCodeOptionsMeta(this.options.sessionOptions)
4151
+ _meta: buildClaudeCodeOptionsMeta(this.options.sessionOptions, claudeAcp)
3755
4152
  }));
3756
4153
  result = claudeAcp ? await withTimeout(createPromise, resolveClaudeAcpSessionCreateTimeoutMs()) : await createPromise;
3757
4154
  } catch (error) {
@@ -3762,11 +4159,19 @@ var AcpClient = class {
3762
4159
  throw error;
3763
4160
  }
3764
4161
  this.loadedSessionId = result.sessionId;
4162
+ const configOptions = normalizeResponseConfigOptions(result);
4163
+ const models = modelStateFromSessionResponse({
4164
+ configOptions,
4165
+ response: result
4166
+ });
4167
+ this.rememberSessionModels(result.sessionId, models);
3765
4168
  return {
3766
4169
  sessionId: result.sessionId,
3767
4170
  agentSessionId: extractRuntimeSessionId(result._meta),
3768
- configOptions: result.configOptions ?? void 0,
3769
- models: result.models ?? void 0
4171
+ configOptions,
4172
+ models,
4173
+ configOptionsPresent: hasResponseField(result, "configOptions"),
4174
+ legacyModelMetadataPresent: hasResponseField(result, "models")
3770
4175
  };
3771
4176
  }
3772
4177
  async loadSession(sessionId, cwd = this.options.cwd) {
@@ -3789,7 +4194,9 @@ var AcpClient = class {
3789
4194
  this.restoreSessionUpdateSuppression(previousSuppression);
3790
4195
  }
3791
4196
  this.loadedSessionId = sessionId;
3792
- return toReconnectedSessionResult(response);
4197
+ const result = toReconnectedSessionResult(response);
4198
+ this.updateRememberedSessionModels(sessionId, result);
4199
+ return result;
3793
4200
  }
3794
4201
  async resumeSession(sessionId, cwd = this.options.cwd) {
3795
4202
  const connection = this.getConnection();
@@ -3800,7 +4207,9 @@ var AcpClient = class {
3800
4207
  mcpServers: this.options.mcpServers ?? []
3801
4208
  }));
3802
4209
  this.loadedSessionId = sessionId;
3803
- return toReconnectedSessionResult(response);
4210
+ const result = toReconnectedSessionResult(response);
4211
+ this.updateRememberedSessionModels(sessionId, result);
4212
+ return result;
3804
4213
  }
3805
4214
  applySessionUpdateSuppression(enabled) {
3806
4215
  const previous = {
@@ -3883,21 +4292,78 @@ var AcpClient = class {
3883
4292
  throw maybeWrapSessionControlError("session/set_config_option", error, `for "${configId}"="${value}"`);
3884
4293
  }
3885
4294
  }
3886
- async setSessionModel(sessionId, modelId) {
4295
+ async setSessionModel(sessionId, modelId, controlOverride) {
4296
+ const control = this.resolveModelControl(sessionId, controlOverride);
4297
+ if (!control) throw new RequestedModelUnsupportedError(`Cannot set model "${modelId}": the ACP session did not advertise a model config option or legacy session/set_model support.`, "missing-capability");
4298
+ const resolvedModelId = resolveRequestedModelId({
4299
+ requestedModel: modelId,
4300
+ models: controlOverride?.availableModels ? { availableModels: controlOverride.availableModels } : void 0,
4301
+ agentCommand: this.options.agentCommand
4302
+ });
4303
+ return control.kind === "config_option" ? await this.setSessionModelThroughConfig(sessionId, resolvedModelId, control.configId) : await this.setSessionModelThroughLegacyMethod(sessionId, resolvedModelId);
4304
+ }
4305
+ async setSessionModelThroughConfig(sessionId, modelId, configId) {
3887
4306
  const connection = this.getConnection();
3888
4307
  try {
3889
- await this.runConnectionRequest(() => connection.unstable_setSessionModel({
4308
+ const response = await this.runConnectionRequest(() => connection.setSessionConfigOption({
4309
+ sessionId,
4310
+ configId,
4311
+ value: modelId
4312
+ }));
4313
+ this.rememberSessionModels(sessionId, modelStateFromConfigOptions(response.configOptions));
4314
+ return response;
4315
+ } catch (error) {
4316
+ return this.throwSessionModelError("session/set_config_option", modelId, error);
4317
+ }
4318
+ }
4319
+ async setSessionModelThroughLegacyMethod(sessionId, modelId) {
4320
+ const connection = this.getConnection();
4321
+ try {
4322
+ await this.runConnectionRequest(() => connection.extMethod("session/set_model", {
3890
4323
  sessionId,
3891
4324
  modelId
3892
4325
  }));
4326
+ return;
3893
4327
  } catch (error) {
3894
- const wrapped = maybeWrapSessionControlError("session/set_model", error, `for model "${modelId}"`);
3895
- if (wrapped !== error) throw wrapped;
3896
- const acp = extractAcpError(error);
3897
- const summary = acp ? formatSessionControlAcpSummary(acp) : error instanceof Error ? error.message : String(error);
3898
- if (error instanceof Error) throw new Error(`Failed session/set_model for model "${modelId}": ${summary}`, { cause: error });
3899
- throw new Error(`Failed session/set_model for model "${modelId}": ${summary}`, { cause: error });
4328
+ return this.throwSessionModelError("session/set_model", modelId, error);
4329
+ }
4330
+ }
4331
+ throwSessionModelError(method, modelId, error) {
4332
+ const wrapped = maybeWrapSessionControlError(method, error, `for model "${modelId}"`);
4333
+ if (wrapped !== error) throw wrapped;
4334
+ const acp = extractAcpError(error);
4335
+ const summary = acp ? formatSessionControlAcpSummary(acp) : error instanceof Error ? error.message : String(error);
4336
+ throw new Error(`Failed ${method} for model "${modelId}": ${summary}`, { cause: error });
4337
+ }
4338
+ resolveModelControl(sessionId, controlOverride) {
4339
+ if (controlOverride) return controlOverride.configId ? {
4340
+ kind: "config_option",
4341
+ configId: controlOverride.configId
4342
+ } : { kind: "legacy_set_model" };
4343
+ const configId = this.modelConfigIds.get(sessionId);
4344
+ if (configId) return {
4345
+ kind: "config_option",
4346
+ configId
4347
+ };
4348
+ return this.legacyModelSessionIds.has(sessionId) ? { kind: "legacy_set_model" } : void 0;
4349
+ }
4350
+ rememberSessionModels(sessionId, models) {
4351
+ if (!models) {
4352
+ this.modelConfigIds.delete(sessionId);
4353
+ this.legacyModelSessionIds.delete(sessionId);
4354
+ return;
4355
+ }
4356
+ if (models.configId) {
4357
+ this.modelConfigIds.set(sessionId, models.configId);
4358
+ this.legacyModelSessionIds.delete(sessionId);
4359
+ return;
3900
4360
  }
4361
+ this.modelConfigIds.delete(sessionId);
4362
+ this.legacyModelSessionIds.add(sessionId);
4363
+ }
4364
+ updateRememberedSessionModels(sessionId, result) {
4365
+ const explicitConfigRemoval = result.configOptionsPresent && this.modelConfigIds.has(sessionId);
4366
+ if (result.models || result.legacyModelMetadataPresent || explicitConfigRemoval) this.rememberSessionModels(sessionId, result.models);
3901
4367
  }
3902
4368
  async cancel(sessionId) {
3903
4369
  const connection = this.getConnection();
@@ -3909,6 +4375,8 @@ var AcpClient = class {
3909
4375
  const connection = this.getConnection();
3910
4376
  await this.runConnectionRequest(() => connection.closeSession({ sessionId }));
3911
4377
  if (this.loadedSessionId === sessionId) this.loadedSessionId = void 0;
4378
+ this.modelConfigIds.delete(sessionId);
4379
+ this.legacyModelSessionIds.delete(sessionId);
3912
4380
  }
3913
4381
  async listSessions(params = {}) {
3914
4382
  const connection = this.getConnection();
@@ -3957,6 +4425,8 @@ var AcpClient = class {
3957
4425
  this.permissionAbortControllers.clear();
3958
4426
  this.promptPermissionFailures.clear();
3959
4427
  this.loadedSessionId = void 0;
4428
+ this.modelConfigIds.clear();
4429
+ this.legacyModelSessionIds.clear();
3960
4430
  this.initResult = void 0;
3961
4431
  this.connection = void 0;
3962
4432
  this.agent = void 0;
@@ -4010,7 +4480,7 @@ var AcpClient = class {
4010
4480
  target.push(text);
4011
4481
  if (target.join("").length - STARTUP_STDERR_MAX_CHARS <= 0) return;
4012
4482
  const joined = target.join("");
4013
- target.splice(0, target.length, joined.slice(-STARTUP_STDERR_MAX_CHARS));
4483
+ target.splice(0, target.length, joined.slice(-8192));
4014
4484
  }
4015
4485
  summarizeStartupStderr(target) {
4016
4486
  const joined = target.join("").trim();
@@ -4369,6 +4839,7 @@ function applyConversation(record, conversation) {
4369
4839
  record.updated_at = conversation.updated_at;
4370
4840
  record.messages = conversation.messages;
4371
4841
  record.cumulative_token_usage = conversation.cumulative_token_usage;
4842
+ record.cumulative_cost = conversation.cumulative_cost;
4372
4843
  record.request_token_usage = conversation.request_token_usage;
4373
4844
  }
4374
4845
  //#endregion
@@ -4379,8 +4850,16 @@ function mergeSessionOptions(preferred, fallback) {
4379
4850
  assignDefinedOption(merged, "allowedTools", preferred?.allowedTools);
4380
4851
  assignDefinedOption(merged, "maxTurns", preferred?.maxTurns);
4381
4852
  assignDefinedOption(merged, "systemPrompt", preferred?.systemPrompt);
4853
+ assignDefinedOption(merged, "env", mergeEnvRecords(fallback?.env, preferred?.env));
4382
4854
  return Object.keys(merged).length > 0 ? merged : void 0;
4383
4855
  }
4856
+ function mergeEnvRecords(fallback, preferred) {
4857
+ if (!fallback && !preferred) return;
4858
+ return {
4859
+ ...fallback,
4860
+ ...preferred
4861
+ };
4862
+ }
4384
4863
  function assignDefinedOption(target, key, value) {
4385
4864
  if (value !== void 0) target[key] = value;
4386
4865
  }
@@ -4404,6 +4883,7 @@ function sessionOptionsFromRecord(record) {
4404
4883
  assignStoredOption(sessionOptions, "allowedTools", storedAllowedTools(stored.allowed_tools));
4405
4884
  assignStoredOption(sessionOptions, "maxTurns", storedMaxTurns(stored.max_turns));
4406
4885
  assignStoredOption(sessionOptions, "systemPrompt", storedSystemPromptOption(stored.system_prompt));
4886
+ assignStoredOption(sessionOptions, "env", storedEnvRecord(stored.env));
4407
4887
  return Object.keys(sessionOptions).length > 0 ? sessionOptions : void 0;
4408
4888
  }
4409
4889
  function persistedSessionOptions(options) {
@@ -4411,12 +4891,23 @@ function persistedSessionOptions(options) {
4411
4891
  model: nonEmptyString(options.model),
4412
4892
  allowed_tools: Array.isArray(options.allowedTools) ? [...options.allowedTools] : void 0,
4413
4893
  max_turns: typeof options.maxTurns === "number" ? options.maxTurns : void 0,
4414
- system_prompt: normalizeSystemPromptOption(options.systemPrompt)
4894
+ system_prompt: normalizeSystemPromptOption(options.systemPrompt),
4895
+ env: storedEnvRecord(options.env)
4415
4896
  };
4416
4897
  return hasPersistedSessionOptions(next) ? next : void 0;
4417
4898
  }
4418
4899
  function hasPersistedSessionOptions(options) {
4419
- return options.model !== void 0 || options.allowed_tools !== void 0 || options.max_turns !== void 0 || options.system_prompt !== void 0;
4900
+ return options.model !== void 0 || options.allowed_tools !== void 0 || options.max_turns !== void 0 || options.system_prompt !== void 0 || options.env !== void 0;
4901
+ }
4902
+ function storedEnvRecord(value) {
4903
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return;
4904
+ const entries = Object.entries(value);
4905
+ const result = {};
4906
+ for (const [key, raw] of entries) {
4907
+ if (typeof raw !== "string") continue;
4908
+ result[key] = raw;
4909
+ }
4910
+ return Object.keys(result).length > 0 ? result : void 0;
4420
4911
  }
4421
4912
  function normalizeSystemPromptOption(value) {
4422
4913
  const prompt = nonEmptyString(value);
@@ -4444,6 +4935,51 @@ function nonEmptyString(value) {
4444
4935
  return typeof value === "string" && value.trim().length > 0 ? value : void 0;
4445
4936
  }
4446
4937
  //#endregion
4938
+ //#region src/session/model-state.ts
4939
+ function configOptionsAreAuthoritative(state) {
4940
+ return state.model_control === "config_option";
4941
+ }
4942
+ function legacyModelState(state) {
4943
+ if (!Array.isArray(state.available_models)) return;
4944
+ return {
4945
+ currentModelId: state.current_model_id ?? "",
4946
+ availableModels: state.available_models.map((modelId) => ({
4947
+ modelId,
4948
+ name: modelId
4949
+ }))
4950
+ };
4951
+ }
4952
+ function advertisedModelState(state) {
4953
+ if (!state) return;
4954
+ const configModels = modelStateFromConfigOptions(state?.config_options);
4955
+ if (configModels) return configModels;
4956
+ if (configOptionsAreAuthoritative(state)) return;
4957
+ return legacyModelState(state);
4958
+ }
4959
+ function applyAdvertisedModelState(state, models) {
4960
+ state.current_model_id = models.currentModelId;
4961
+ state.available_models = models.availableModels.map((model) => model.modelId);
4962
+ state.model_control = models.configId ? "config_option" : "legacy_set_model";
4963
+ }
4964
+ function clearAdvertisedModelState(state) {
4965
+ delete state.current_model_id;
4966
+ delete state.available_models;
4967
+ delete state.model_control;
4968
+ }
4969
+ function removeModelConfigOptions(state) {
4970
+ if (!state.config_options) return;
4971
+ state.config_options = state.config_options.filter((option) => option.category !== "model" && option.id !== "model");
4972
+ }
4973
+ function applyConfigOptionsModelState(state, configOptions) {
4974
+ const previousConfigModels = modelStateFromConfigOptions(state.config_options);
4975
+ const preservesLegacyControl = state.model_control === "legacy_set_model" || state.model_control === void 0 && previousConfigModels === void 0 && legacyModelState(state) !== void 0;
4976
+ state.config_options = structuredClone(configOptions);
4977
+ const models = modelStateFromConfigOptions(configOptions);
4978
+ if (models) applyAdvertisedModelState(state, models);
4979
+ else if (preservesLegacyControl) state.model_control = "legacy_set_model";
4980
+ else clearAdvertisedModelState(state);
4981
+ }
4982
+ //#endregion
4447
4983
  //#region src/session/conversation-model.ts
4448
4984
  const MAX_RUNTIME_MESSAGES = 200;
4449
4985
  const MAX_RUNTIME_AGENT_TEXT_CHARS = 8e3;
@@ -4464,10 +5000,25 @@ function hasOwn(source, key) {
4464
5000
  return Object.prototype.hasOwnProperty.call(source, key);
4465
5001
  }
4466
5002
  function normalizeAgentName(value) {
5003
+ return trimmedString(value);
5004
+ }
5005
+ function trimmedString(value) {
4467
5006
  if (typeof value !== "string") return;
4468
5007
  const trimmed = value.trim();
4469
5008
  return trimmed.length > 0 ? trimmed : void 0;
4470
5009
  }
5010
+ function normalizeAvailableCommand(value) {
5011
+ const record = asRecord(value);
5012
+ if (!record) return;
5013
+ const name = trimmedString(record.name);
5014
+ if (!name) return;
5015
+ const description = trimmedString(record.description);
5016
+ return {
5017
+ name,
5018
+ ...description ? { description } : {},
5019
+ has_input: record.input != null
5020
+ };
5021
+ }
4471
5022
  function extractText(content) {
4472
5023
  switch (content.type) {
4473
5024
  case "text": return content.text;
@@ -4695,7 +5246,9 @@ function usageToTokenUsage(update) {
4695
5246
  "cache_read_input_tokens",
4696
5247
  "cacheReadInputTokens",
4697
5248
  "cachedReadTokens"
4698
- ])
5249
+ ]),
5250
+ thought_tokens: numberField(source, ["thought_tokens", "thoughtTokens"]),
5251
+ total_tokens: numberField(source, ["total_tokens", "totalTokens"])
4699
5252
  };
4700
5253
  if (!hasTokenUsageValue(normalized)) return;
4701
5254
  return normalized;
@@ -4703,6 +5256,21 @@ function usageToTokenUsage(update) {
4703
5256
  function hasTokenUsageValue(usage) {
4704
5257
  return Object.values(usage).some((value) => value !== void 0);
4705
5258
  }
5259
+ function usageCost(update) {
5260
+ const cost = asRecord(asRecord(update)?.cost);
5261
+ if (!cost) return;
5262
+ return buildUsageCost(numberField(cost, ["amount"]), stringField(cost.currency));
5263
+ }
5264
+ function stringField(value) {
5265
+ return typeof value === "string" && value.trim() ? value : void 0;
5266
+ }
5267
+ function buildUsageCost(amount, currency) {
5268
+ const cost = {
5269
+ ...amount !== void 0 ? { amount } : {},
5270
+ ...currency !== void 0 ? { currency } : {}
5271
+ };
5272
+ return Object.keys(cost).length > 0 ? cost : void 0;
5273
+ }
4706
5274
  function ensureAcpxState$1(state) {
4707
5275
  return state ?? {};
4708
5276
  }
@@ -4718,6 +5286,7 @@ function createSessionConversation(timestamp = isoNow()) {
4718
5286
  messages: [],
4719
5287
  updated_at: timestamp,
4720
5288
  cumulative_token_usage: {},
5289
+ cumulative_cost: void 0,
4721
5290
  request_token_usage: {}
4722
5291
  };
4723
5292
  }
@@ -4728,9 +5297,13 @@ function cloneSessionConversation(conversation) {
4728
5297
  messages: deepClone(conversation.messages ?? []),
4729
5298
  updated_at: conversation.updated_at,
4730
5299
  cumulative_token_usage: deepClone(conversation.cumulative_token_usage ?? {}),
5300
+ cumulative_cost: cloneUsageCost(conversation.cumulative_cost),
4731
5301
  request_token_usage: deepClone(conversation.request_token_usage ?? {})
4732
5302
  };
4733
5303
  }
5304
+ function cloneUsageCost(cost) {
5305
+ return cost ? { ...cost } : void 0;
5306
+ }
4734
5307
  function cloneSessionAcpxState(state) {
4735
5308
  if (!state) return;
4736
5309
  return {
@@ -4739,7 +5312,8 @@ function cloneSessionAcpxState(state) {
4739
5312
  desired_config_options: state.desired_config_options ? { ...state.desired_config_options } : void 0,
4740
5313
  current_model_id: state.current_model_id,
4741
5314
  available_models: state.available_models ? [...state.available_models] : void 0,
4742
- available_commands: state.available_commands ? [...state.available_commands] : void 0,
5315
+ model_control: state.model_control,
5316
+ available_commands: state.available_commands ? state.available_commands.map((command) => ({ ...command })) : void 0,
4743
5317
  config_options: state.config_options ? deepClone(state.config_options) : void 0,
4744
5318
  session_options: cloneSessionOptions(state.session_options)
4745
5319
  };
@@ -4750,7 +5324,8 @@ function cloneSessionOptions(options) {
4750
5324
  model: options.model,
4751
5325
  allowed_tools: options.allowed_tools ? [...options.allowed_tools] : void 0,
4752
5326
  max_turns: options.max_turns,
4753
- ...options.system_prompt !== void 0 ? { system_prompt: cloneSystemPromptOption(options.system_prompt) } : {}
5327
+ ...options.system_prompt !== void 0 ? { system_prompt: cloneSystemPromptOption(options.system_prompt) } : {},
5328
+ ...options.env !== void 0 ? { env: { ...options.env } } : {}
4754
5329
  };
4755
5330
  }
4756
5331
  function cloneSystemPromptOption(option) {
@@ -4820,13 +5395,13 @@ const SESSION_UPDATE_HANDLERS = {
4820
5395
  if (update.sessionUpdate === "session_info_update") applySessionInfoUpdate(conversation, update);
4821
5396
  },
4822
5397
  available_commands_update: (_conversation, acpx, update) => {
4823
- if (update.sessionUpdate === "available_commands_update") acpx.available_commands = update.availableCommands.map((entry) => entry.name).filter((entry) => typeof entry === "string" && entry.trim().length > 0);
5398
+ if (update.sessionUpdate === "available_commands_update") acpx.available_commands = update.availableCommands.map((entry) => normalizeAvailableCommand(entry)).filter((entry) => entry !== void 0);
4824
5399
  },
4825
5400
  current_mode_update: (_conversation, acpx, update) => {
4826
5401
  if (update.sessionUpdate === "current_mode_update") acpx.current_mode_id = update.currentModeId;
4827
5402
  },
4828
5403
  config_option_update: (_conversation, acpx, update) => {
4829
- if (update.sessionUpdate === "config_option_update") acpx.config_options = deepClone(update.configOptions);
5404
+ if (update.sessionUpdate === "config_option_update") applyConfigOptionsModelState(acpx, deepClone(update.configOptions));
4830
5405
  }
4831
5406
  };
4832
5407
  function appendUserMessageChunk(conversation, content) {
@@ -4843,10 +5418,14 @@ function appendAgentMessageChunk(conversation, content, append) {
4843
5418
  }
4844
5419
  function applyUsageUpdate(conversation, update) {
4845
5420
  const usage = usageToTokenUsage(update);
4846
- if (!usage) return;
4847
- conversation.cumulative_token_usage = usage;
4848
- const userId = lastUserMessageId(conversation);
4849
- if (userId) conversation.request_token_usage[userId] = usage;
5421
+ const cost = usageCost(update);
5422
+ if (!usage && !cost) return;
5423
+ if (usage) {
5424
+ conversation.cumulative_token_usage = usage;
5425
+ const userId = lastUserMessageId(conversation);
5426
+ if (userId) conversation.request_token_usage[userId] = usage;
5427
+ }
5428
+ if (cost) conversation.cumulative_cost = cost;
4850
5429
  }
4851
5430
  function applySessionInfoUpdate(conversation, update) {
4852
5431
  if (hasOwn(update, "title")) conversation.title = update.title ?? null;
@@ -4859,10 +5438,10 @@ function recordClientOperation(conversation, state, operation, timestamp = isoNo
4859
5438
  return acpx;
4860
5439
  }
4861
5440
  function trimConversationForRuntime(conversation) {
4862
- if (conversation.messages.length > MAX_RUNTIME_MESSAGES) conversation.messages = conversation.messages.slice(-MAX_RUNTIME_MESSAGES);
5441
+ if (conversation.messages.length > MAX_RUNTIME_MESSAGES) conversation.messages = conversation.messages.slice(-200);
4863
5442
  for (const message of conversation.messages) trimRuntimeMessage(message);
4864
5443
  const requestUsageEntries = Object.entries(conversation.request_token_usage);
4865
- if (requestUsageEntries.length > MAX_RUNTIME_REQUEST_TOKEN_USAGE) conversation.request_token_usage = Object.fromEntries(requestUsageEntries.slice(-MAX_RUNTIME_REQUEST_TOKEN_USAGE));
5444
+ if (requestUsageEntries.length > MAX_RUNTIME_REQUEST_TOKEN_USAGE) conversation.request_token_usage = Object.fromEntries(requestUsageEntries.slice(-100));
4866
5445
  }
4867
5446
  function trimRuntimeMessage(message) {
4868
5447
  if (isUserMessage(message)) {
@@ -4892,12 +5471,15 @@ function trimRuntimeToolResult(result) {
4892
5471
  }
4893
5472
  //#endregion
4894
5473
  //#region src/session/config-options.ts
5474
+ function applyConfigOptionsToState(state, configOptions) {
5475
+ const acpxState = cloneSessionAcpxState(state) ?? {};
5476
+ applyConfigOptionsModelState(acpxState, configOptions);
5477
+ return acpxState;
5478
+ }
4895
5479
  function applyConfigOptionsToRecord(record, result) {
4896
5480
  const configOptions = result?.configOptions;
4897
5481
  if (!configOptions) return;
4898
- const acpxState = cloneSessionAcpxState(record.acpx) ?? {};
4899
- acpxState.config_options = structuredClone(configOptions);
4900
- record.acpx = acpxState;
5482
+ record.acpx = applyConfigOptionsToState(record.acpx, configOptions);
4901
5483
  }
4902
5484
  //#endregion
4903
5485
  //#region src/session/mode-preference.ts
@@ -4943,17 +5525,29 @@ function setDesiredConfigOption(record, configId, value) {
4943
5525
  else delete acpx.desired_config_options;
4944
5526
  record.acpx = acpx;
4945
5527
  }
5528
+ function clearDesiredConfigOption(state, configId) {
5529
+ const normalizedConfigId = normalizeModeId(configId);
5530
+ if (!normalizedConfigId || !state.desired_config_options) return;
5531
+ const desired = { ...state.desired_config_options };
5532
+ delete desired[normalizedConfigId];
5533
+ if (Object.keys(desired).length > 0) state.desired_config_options = desired;
5534
+ else delete state.desired_config_options;
5535
+ }
4946
5536
  function getDesiredModelId(state) {
4947
5537
  return normalizeModelId(state?.session_options?.model);
4948
5538
  }
4949
- function setDesiredModelId(record, modelId) {
5539
+ function hasStoredSessionOptions(options) {
5540
+ return typeof options.model === "string" || Array.isArray(options.allowed_tools) || typeof options.max_turns === "number" || options.system_prompt !== void 0 || options.env !== void 0;
5541
+ }
5542
+ function setDesiredModelId(record, modelId, modelConfigId) {
4950
5543
  const acpx = ensureAcpxState(record.acpx);
4951
5544
  const normalized = normalizeModelId(modelId);
4952
5545
  const sessionOptions = { ...acpx.session_options };
4953
5546
  if (normalized) sessionOptions.model = normalized;
4954
5547
  else delete sessionOptions.model;
4955
- if (typeof sessionOptions.model === "string" || Array.isArray(sessionOptions.allowed_tools) || typeof sessionOptions.max_turns === "number" || sessionOptions.system_prompt !== void 0) acpx.session_options = sessionOptions;
5548
+ if (hasStoredSessionOptions(sessionOptions)) acpx.session_options = sessionOptions;
4956
5549
  else delete acpx.session_options;
5550
+ clearDesiredConfigOption(acpx, modelConfigId ?? modelStateFromConfigOptions(acpx.config_options)?.configId);
4957
5551
  record.acpx = acpx;
4958
5552
  }
4959
5553
  function setCurrentModelId(record, modelId) {
@@ -4966,49 +5560,30 @@ function setCurrentModelId(record, modelId) {
4966
5560
  function syncAdvertisedModelState(record, models) {
4967
5561
  if (!models) return;
4968
5562
  const acpx = ensureAcpxState(record.acpx);
4969
- acpx.current_model_id = models.currentModelId;
4970
- acpx.available_models = models.availableModels.map((model) => model.modelId);
5563
+ applyAdvertisedModelState(acpx, models);
4971
5564
  record.acpx = acpx;
4972
5565
  }
4973
5566
  //#endregion
4974
- //#region src/acp/model-support.ts
4975
- var RequestedModelUnsupportedError = class extends Error {
4976
- constructor(message) {
4977
- super(message);
4978
- this.name = "RequestedModelUnsupportedError";
4979
- }
4980
- };
4981
- function supportsLegacyClaudeCodeModelMetadata(agentCommand) {
4982
- if (!agentCommand) return false;
4983
- const { command, args } = splitCommandLine(agentCommand);
4984
- return isClaudeAcpCommand(command, args);
4985
- }
4986
- function formatAvailableModelIds(models) {
4987
- const ids = models?.availableModels.map((model) => model.modelId.trim()).filter((modelId) => modelId.length > 0) ?? [];
4988
- return ids.length > 0 ? ids.join(", ") : "none advertised";
4989
- }
4990
- function assertRequestedModelSupported(params) {
4991
- if (!params.models) {
4992
- if (supportsLegacyClaudeCodeModelMetadata(params.agentCommand)) return;
4993
- throw new RequestedModelUnsupportedError(`Cannot ${params.context === "replay" ? "replay saved model" : "apply --model"} "${params.requestedModel}": the ACP agent did not advertise model support. Generic model selection requires ACP models plus session/set_model support, or an adapter-specific startup model flag.`);
4994
- }
4995
- if (!new Set(params.models.availableModels.map((model) => model.modelId)).has(params.requestedModel)) throw new RequestedModelUnsupportedError(`Cannot ${params.context === "replay" ? "replay saved model" : "apply --model"} "${params.requestedModel}": the ACP agent did not advertise that model. Available models: ${formatAvailableModelIds(params.models)}.`);
4996
- }
4997
- //#endregion
4998
5567
  //#region src/session/model-application.ts
5568
+ function currentModelIdFromSetModelResponse(response, fallbackModelId) {
5569
+ return modelStateFromConfigOptions(response?.configOptions)?.currentModelId ?? fallbackModelId;
5570
+ }
4999
5571
  async function applyRequestedModelIfAdvertised(params) {
5000
5572
  const requestedModel = typeof params.requestedModel === "string" ? params.requestedModel.trim() : "";
5001
- if (!requestedModel) return false;
5002
- assertRequestedModelSupported({
5573
+ if (!requestedModel) return { applied: false };
5574
+ const warning = assertRequestedModelSupported({
5003
5575
  requestedModel,
5004
5576
  models: params.models,
5005
5577
  agentCommand: params.agentCommand,
5006
5578
  context: "apply"
5007
5579
  });
5008
- if (!params.models) return false;
5009
- if (params.models.currentModelId === requestedModel) return true;
5010
- await withTimeout(params.client.setSessionModel(params.sessionId, requestedModel), params.timeoutMs);
5011
- return true;
5580
+ if (warning) params.onWarning?.(warning);
5581
+ if (!params.models) return { applied: false };
5582
+ if (params.models.currentModelId === requestedModel) return { applied: true };
5583
+ return {
5584
+ applied: true,
5585
+ response: await withTimeout(params.client.setSessionModel(params.sessionId, requestedModel, params.models), params.timeoutMs)
5586
+ };
5012
5587
  }
5013
5588
  //#endregion
5014
5589
  //#region src/runtime/engine/reconnect.ts
@@ -5021,7 +5596,7 @@ function isProcessAlive(pid) {
5021
5596
  return false;
5022
5597
  }
5023
5598
  }
5024
- const SESSION_LOAD_UNSUPPORTED_CODES = new Set([-32601, -32602]);
5599
+ const SESSION_LOAD_UNSUPPORTED_CODES = /* @__PURE__ */ new Set([-32601, -32602]);
5025
5600
  function shouldFallbackToNewSession(error, record) {
5026
5601
  if (isHardReconnectFailure(error)) return false;
5027
5602
  const acp = extractAcpError(error);
@@ -5056,17 +5631,27 @@ async function replayDesiredMode(params) {
5056
5631
  }
5057
5632
  }
5058
5633
  async function replayDesiredModel(params) {
5059
- if (!params.desiredModelId) return;
5634
+ if (!params.desiredModelId) return { replayed: false };
5060
5635
  try {
5061
- assertRequestedModelSupported({
5636
+ emitModelSupportWarning(assertRequestedModelSupported({
5062
5637
  requestedModel: params.desiredModelId,
5063
5638
  models: params.models,
5064
5639
  agentCommand: params.record.agentCommand,
5065
5640
  context: "replay"
5066
- });
5067
- if (!params.models || params.models.currentModelId === params.desiredModelId) return;
5068
- await withTimeout(params.client.setSessionModel(params.sessionId, params.desiredModelId), params.timeoutMs);
5641
+ }), params.suppressWarnings);
5642
+ if (!params.models || params.models.currentModelId === params.desiredModelId) return { replayed: false };
5643
+ const response = await withTimeout(params.client.setSessionModel(params.sessionId, params.desiredModelId, params.models), params.timeoutMs);
5644
+ applyConfigOptionsToRecord(params.record, response);
5645
+ const models = response ? modelStateFromConfigOptions(response.configOptions) : {
5646
+ ...params.models,
5647
+ currentModelId: params.desiredModelId
5648
+ };
5069
5649
  if (params.verbose) process.stderr.write(`[acpx] replayed desired model ${params.desiredModelId} on fresh ACP session ${params.sessionId} (previous ${params.previousSessionId})\n`);
5650
+ return {
5651
+ replayed: true,
5652
+ models,
5653
+ configOptionsPresent: response !== void 0
5654
+ };
5070
5655
  } catch (error) {
5071
5656
  throw new SessionModelReplayError(`Failed to replay saved session model ${params.desiredModelId} on fresh ACP session ${params.sessionId}: ${formatErrorMessage(error)}`, {
5072
5657
  cause: error instanceof Error ? error : void 0,
@@ -5074,9 +5659,18 @@ async function replayDesiredModel(params) {
5074
5659
  });
5075
5660
  }
5076
5661
  }
5662
+ function emitModelSupportWarning(warning, suppressWarnings) {
5663
+ if (warning && !suppressWarnings) process.stderr.write(`[acpx] warning: ${warning}\n`);
5664
+ }
5077
5665
  async function replayDesiredConfigOptions(params) {
5666
+ let result = { replayed: false };
5078
5667
  for (const [configId, value] of Object.entries(params.desiredConfigOptions)) try {
5079
- await withTimeout(params.client.setSessionConfigOption(params.sessionId, configId, value), params.timeoutMs);
5668
+ const response = await withTimeout(params.client.setSessionConfigOption(params.sessionId, configId, value), params.timeoutMs);
5669
+ applyConfigOptionsToRecord(params.record, response);
5670
+ result = {
5671
+ replayed: true,
5672
+ models: modelStateFromConfigOptions(response.configOptions)
5673
+ };
5080
5674
  if (params.verbose) process.stderr.write(`[acpx] replayed desired config option ${configId} on fresh ACP session ${params.sessionId} (previous ${params.previousSessionId})\n`);
5081
5675
  } catch (error) {
5082
5676
  throw new SessionConfigOptionReplayError(`Failed to replay saved session config option ${configId} on fresh ACP session ${params.sessionId}: ${formatErrorMessage(error)}`, {
@@ -5084,6 +5678,7 @@ async function replayDesiredConfigOptions(params) {
5084
5678
  retryable: true
5085
5679
  });
5086
5680
  }
5681
+ return result;
5087
5682
  }
5088
5683
  function restoreOriginalSessionState(params) {
5089
5684
  params.record.acpSessionId = params.sessionId;
@@ -5095,6 +5690,7 @@ async function connectAndLoadSession(options) {
5095
5690
  const sameSessionOnly = requiresSameSession(options.resumePolicy) || Boolean(record.importedFrom);
5096
5691
  const originalSessionId = record.acpSessionId;
5097
5692
  const originalAgentSessionId = record.agentSessionId;
5693
+ const originalAcpx = cloneSessionAcpxState(record.acpx);
5098
5694
  const desiredModeId = getDesiredModeId(record.acpx);
5099
5695
  const desiredModelId = getDesiredModelId(record.acpx);
5100
5696
  const desiredConfigOptions = getDesiredConfigOptions(record.acpx);
@@ -5127,7 +5723,7 @@ async function connectAndLoadSession(options) {
5127
5723
  createdFreshSession = loadState.createdFreshSession;
5128
5724
  pendingAgentSessionId = loadState.pendingAgentSessionId;
5129
5725
  sessionModels = loadState.sessionModels;
5130
- await replayFreshSessionPreferences({
5726
+ const preferenceReplay = await replayFreshSessionPreferences({
5131
5727
  client,
5132
5728
  record,
5133
5729
  createdFreshSession,
@@ -5135,14 +5731,16 @@ async function connectAndLoadSession(options) {
5135
5731
  pendingAgentSessionId,
5136
5732
  originalSessionId,
5137
5733
  originalAgentSessionId,
5734
+ originalAcpx,
5138
5735
  desiredModeId,
5139
5736
  desiredModelId,
5140
5737
  desiredConfigOptions,
5141
5738
  sessionModels,
5142
5739
  timeoutMs: options.timeoutMs,
5143
- verbose: options.verbose
5740
+ verbose: options.verbose,
5741
+ suppressWarnings: options.suppressWarnings
5144
5742
  });
5145
- applyReconnectedModelState(record, sessionModels, createdFreshSession, desiredModelId);
5743
+ applyReconnectedModelState(record, resolveModelsAfterReplay(preferenceReplay, sessionModels), resolveConfigOptionsPresenceAfterReplay(preferenceReplay, loadState.configOptionsPresent), loadState.legacyModelMetadataPresent, createdFreshSession);
5146
5744
  options.onSessionIdResolved?.(sessionId);
5147
5745
  return {
5148
5746
  sessionId,
@@ -5151,9 +5749,28 @@ async function connectAndLoadSession(options) {
5151
5749
  loadError
5152
5750
  };
5153
5751
  }
5154
- function applyReconnectedModelState(record, sessionModels, createdFreshSession, desiredModelId) {
5155
- syncAdvertisedModelState(record, sessionModels);
5156
- if (createdFreshSession && desiredModelId && sessionModels) setCurrentModelId(record, desiredModelId);
5752
+ function resolveModelsAfterReplay(replay, initialModels) {
5753
+ if (replay.configReplay.replayed) return replay.configReplay.models ?? preserveLegacyModels(replay.modelReplay.replayed ? replay.modelReplay.models : initialModels);
5754
+ return replay.modelReplay.replayed ? replay.modelReplay.models : initialModels;
5755
+ }
5756
+ function preserveLegacyModels(models) {
5757
+ return models && !models.configId ? models : void 0;
5758
+ }
5759
+ function resolveConfigOptionsPresenceAfterReplay(replay, initiallyPresent) {
5760
+ return initiallyPresent || replay.configReplay.replayed || replay.modelReplay.replayed && replay.modelReplay.configOptionsPresent;
5761
+ }
5762
+ function applyReconnectedModelState(record, sessionModels, configOptionsPresent, legacyModelMetadataPresent, createdFreshSession) {
5763
+ clearOmittedFreshSessionConfigOptions(record, createdFreshSession, configOptionsPresent);
5764
+ if (sessionModels) {
5765
+ if (legacyModelMetadataPresent && !sessionModels.configId && record.acpx) removeModelConfigOptions(record.acpx);
5766
+ syncAdvertisedModelState(record, sessionModels);
5767
+ } else clearRemovedModelState(record, legacyModelMetadataPresent || createdFreshSession);
5768
+ }
5769
+ function clearOmittedFreshSessionConfigOptions(record, createdFreshSession, configOptionsPresent) {
5770
+ if (createdFreshSession && !configOptionsPresent && record.acpx) delete record.acpx.config_options;
5771
+ }
5772
+ function clearRemovedModelState(record, shouldClear) {
5773
+ if (shouldClear && record.acpx) clearAdvertisedModelState(record.acpx);
5157
5774
  }
5158
5775
  function logReconnectAttempt(record, storedProcessAlive, shouldReconnect, verbose) {
5159
5776
  if (!verbose) return;
@@ -5164,7 +5781,12 @@ function logReconnectAttempt(record, storedProcessAlive, shouldReconnect, verbos
5164
5781
  if (shouldReconnect) process.stderr.write(`[acpx] saved session pid ${record.pid} is dead; respawning agent and attempting session reconnect\n`);
5165
5782
  }
5166
5783
  async function replayFreshSessionPreferences(params) {
5167
- if (!params.createdFreshSession) return;
5784
+ if (!params.createdFreshSession) return {
5785
+ modelReplay: { replayed: false },
5786
+ configReplay: { replayed: false }
5787
+ };
5788
+ let modelReplay = { replayed: false };
5789
+ let configReplay = { replayed: false };
5168
5790
  try {
5169
5791
  await replayDesiredMode({
5170
5792
  client: params.client,
@@ -5174,7 +5796,7 @@ async function replayFreshSessionPreferences(params) {
5174
5796
  timeoutMs: params.timeoutMs,
5175
5797
  verbose: params.verbose
5176
5798
  });
5177
- await replayDesiredModel({
5799
+ modelReplay = await replayDesiredModel({
5178
5800
  client: params.client,
5179
5801
  sessionId: params.sessionId,
5180
5802
  desiredModelId: params.desiredModelId,
@@ -5182,10 +5804,12 @@ async function replayFreshSessionPreferences(params) {
5182
5804
  record: params.record,
5183
5805
  models: params.sessionModels,
5184
5806
  timeoutMs: params.timeoutMs,
5185
- verbose: params.verbose
5807
+ verbose: params.verbose,
5808
+ suppressWarnings: params.suppressWarnings
5186
5809
  });
5187
- await replayDesiredConfigOptions({
5810
+ configReplay = await replayDesiredConfigOptions({
5188
5811
  client: params.client,
5812
+ record: params.record,
5189
5813
  sessionId: params.sessionId,
5190
5814
  desiredConfigOptions: params.desiredConfigOptions,
5191
5815
  previousSessionId: params.originalSessionId,
@@ -5198,17 +5822,24 @@ async function replayFreshSessionPreferences(params) {
5198
5822
  sessionId: params.originalSessionId,
5199
5823
  agentSessionId: params.originalAgentSessionId
5200
5824
  });
5825
+ params.record.acpx = cloneSessionAcpxState(params.originalAcpx);
5201
5826
  if (params.verbose) process.stderr.write(`[acpx] ${formatErrorMessage(error)}\n`);
5202
5827
  throw error;
5203
5828
  }
5204
5829
  params.record.acpSessionId = params.sessionId;
5205
5830
  reconcileAgentSessionId(params.record, params.pendingAgentSessionId);
5831
+ return {
5832
+ modelReplay,
5833
+ configReplay
5834
+ };
5206
5835
  }
5207
5836
  async function loadOrCreateRuntimeSession(params) {
5208
5837
  if (params.reusingLoadedSession) return {
5209
5838
  sessionId: params.record.acpSessionId,
5210
5839
  pendingAgentSessionId: params.record.agentSessionId,
5211
5840
  sessionModels: void 0,
5841
+ configOptionsPresent: false,
5842
+ legacyModelMetadataPresent: false,
5212
5843
  resumed: true,
5213
5844
  createdFreshSession: false
5214
5845
  };
@@ -5229,6 +5860,8 @@ async function resumeRuntimeSession(params) {
5229
5860
  sessionId: params.record.acpSessionId,
5230
5861
  pendingAgentSessionId: params.record.agentSessionId,
5231
5862
  sessionModels: resumeResult.models,
5863
+ configOptionsPresent: resumeResult.configOptionsPresent,
5864
+ legacyModelMetadataPresent: resumeResult.legacyModelMetadataPresent,
5232
5865
  resumed: true,
5233
5866
  createdFreshSession: false
5234
5867
  };
@@ -5245,6 +5878,8 @@ async function loadRuntimeSession(params) {
5245
5878
  sessionId: params.record.acpSessionId,
5246
5879
  pendingAgentSessionId: params.record.agentSessionId,
5247
5880
  sessionModels: loadResult.models,
5881
+ configOptionsPresent: loadResult.configOptionsPresent,
5882
+ legacyModelMetadataPresent: loadResult.legacyModelMetadataPresent,
5248
5883
  resumed: true,
5249
5884
  createdFreshSession: false
5250
5885
  };
@@ -5272,6 +5907,8 @@ async function createFreshRuntimeSession(client, record, timeoutMs) {
5272
5907
  sessionId: createdSession.sessionId,
5273
5908
  pendingAgentSessionId: createdSession.agentSessionId,
5274
5909
  sessionModels: createdSession.models,
5910
+ configOptionsPresent: createdSession.configOptionsPresent,
5911
+ legacyModelMetadataPresent: createdSession.legacyModelMetadataPresent,
5275
5912
  resumed: false,
5276
5913
  createdFreshSession: true
5277
5914
  };
@@ -5287,7 +5924,10 @@ function createActiveSessionController(params) {
5287
5924
  await params.client.setSessionMode(getActiveSessionId(), modeId);
5288
5925
  },
5289
5926
  setSessionModel: async (modelId) => {
5290
- await params.client.setSessionModel(getActiveSessionId(), modelId);
5927
+ const models = advertisedModelState(params.record.acpx);
5928
+ const response = await params.client.setSessionModel(getActiveSessionId(), modelId, models);
5929
+ applyConfigOptionsToRecord(params.record, response);
5930
+ return response;
5291
5931
  },
5292
5932
  setSessionConfigOption: async (configId, value) => {
5293
5933
  return await params.client.setSessionConfigOption(getActiveSessionId(), configId, value);
@@ -5325,6 +5965,7 @@ async function withConnectedSession(options) {
5325
5965
  let notifiedClientAvailable = false;
5326
5966
  const activeController = createActiveSessionController({
5327
5967
  client,
5968
+ record,
5328
5969
  getActiveSessionId: () => activeSessionIdForControl
5329
5970
  });
5330
5971
  try {
@@ -5468,6 +6109,6 @@ var LiveSessionCheckpoint = class {
5468
6109
  }
5469
6110
  };
5470
6111
  //#endregion
5471
- export { defaultSessionEventLog as $, findGitRepositoryRoot as A, EXIT_CODES as At, assertPersistedKeyPolicy as B, QueueConnectionError as Bt, applyConversation as C, formatErrorMessage as Ct, permissionModeSatisfies as D, isAcpResourceNotFoundError as Dt, AcpClient as E, extractAcpError as Et, listSessionsForAgent as F, PERMISSION_MODES as Ft, recordPerfDuration as G, getPerfMetricsSnapshot as H, normalizeName as I, PERMISSION_POLICY_ACTIONS as It, startPerfTimer as J, resetPerfMetrics as K, pruneSessions as L, SESSION_RECORD_SCHEMA as Lt, findSessionByDirectoryWalk as M, OUTPUT_ERROR_CODES as Mt, isoNow$2 as N, OUTPUT_ERROR_ORIGINS as Nt, DEFAULT_HISTORY_LIMIT as O, toAcpErrorPayload as Ot, listSessions as P, OUTPUT_FORMATS as Pt, DEFAULT_EVENT_SEGMENT_MAX_BYTES as Q, resolveSessionRecord as R, AcpxOperationalError as Rt, sessionOptionsFromRecord as S, exitCodeForOutputErrorCode as St, reconcileAgentSessionId as T, normalizeOutputError as Tt, incrementPerfCounter as U, formatPerfMetric as V, QueueProtocolError as Vt, measurePerf as W, serializeSessionRecordForDisk as X, parseSessionRecord as Y, normalizeRuntimeSessionId as Z, recordPromptSubmission as _, withTimeout as _t, applyRequestedModelIfAdvertised as a, isAcpJsonRpcMessage as at, mergeSessionOptions as b, normalizeAgentName$1 as bt, setDesiredConfigOption as c, PromptInputValidationError as ct, syncAdvertisedModelState as d, parsePromptSource as dt, sessionBaseDir$1 as et, applyConfigOptionsToRecord as f, promptToDisplayText as ft, recordClientOperation as g, withInterrupt as gt, createSessionConversation as h, TimeoutError as ht, connectAndLoadSession as i, extractSessionUpdateNotification as it, findSession as j, NON_INTERACTIVE_PERMISSION_POLICIES as jt, absolutePath as k, AUTH_POLICIES as kt, setDesiredModeId as l, isPromptInput as lt, cloneSessionConversation as m, InterruptedError as mt, runPromptTurn as n, sessionEventLockPath as nt, assertRequestedModelSupported as o, parseJsonRpcErrorMessage as ot, cloneSessionAcpxState as p, textPrompt as pt, setPerfGauge as q, withConnectedSession as r, sessionEventSegmentPath as rt, setCurrentModelId as s, parsePromptStopReason as st, LiveSessionCheckpoint as t, sessionEventActivePath as tt, setDesiredModelId as u, mergePromptSourceWithText as ut, recordSessionUpdate as v, DEFAULT_AGENT_NAME as vt, applyLifecycleSnapshotToRecord as w, isRetryablePromptError as wt, persistSessionOptions as x, resolveAgentCommand as xt, trimConversationForRuntime as y, listBuiltInAgents as yt, writeSessionRecord as z, AgentSpawnError as zt };
6112
+ export { getPerfMetricsSnapshot as $, REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE as A, listBuiltInAgents as At, absolutePath as B, AUTH_POLICIES as Bt, mergeSessionOptions as C, promptToDisplayText as Ct, applyLifecycleSnapshotToRecord as D, withInterrupt as Dt, applyConversation as E, TimeoutError as Et, modelStateFromConfigOptions as F, isRetryablePromptError as Ft, listSessions as G, OUTPUT_FORMATS as Gt, findSession as H, NON_INTERACTIVE_PERMISSION_POLICIES as Ht, splitCommandLine as I, normalizeOutputError as It, pruneSessions as J, SESSION_RECORD_SCHEMA as Jt, listSessionsForAgent as K, PERMISSION_MODES as Kt, getAcpxVersion as L, extractAcpError as Lt, RequestedModelUnsupportedError as M, resolveAgentCommand as Mt, assertRequestedModelSupported as N, exitCodeForOutputErrorCode as Nt, reconcileAgentSessionId as O, withTimeout as Ot, isRequestedModelUnsupportedError as P, formatErrorMessage as Pt, formatPerfMetric as Q, QueueProtocolError as Qt, permissionModeSatisfies as R, isAcpResourceNotFoundError as Rt, advertisedModelState as S, parsePromptSource as St, sessionOptionsFromRecord as T, InterruptedError as Tt, findSessionByDirectoryWalk as U, OUTPUT_ERROR_CODES as Ut, findGitRepositoryRoot as V, EXIT_CODES as Vt, isoNow$2 as W, OUTPUT_ERROR_ORIGINS as Wt, writeSessionRecord as X, AgentSpawnError as Xt, resolveSessionRecord as Y, AcpxOperationalError as Yt, assertPersistedKeyPolicy as Z, QueueConnectionError as Zt, createSessionConversation as _, parseJsonRpcErrorMessage as _t, applyRequestedModelIfAdvertised as a, startPerfTimer as at, recordSessionUpdate as b, isPromptInput as bt, setCurrentModelId as c, normalizeRuntimeSessionId as ct, setDesiredModelId as d, sessionBaseDir$1 as dt, incrementPerfCounter as et, syncAdvertisedModelState as f, sessionEventActivePath as ft, cloneSessionConversation as g, isAcpJsonRpcMessage as gt, cloneSessionAcpxState as h, extractSessionUpdateNotification as ht, connectAndLoadSession as i, setPerfGauge as it, REQUESTED_MODEL_UNSUPPORTED_REASONS as j, normalizeAgentName$1 as jt, AcpClient as k, DEFAULT_AGENT_NAME as kt, setDesiredConfigOption as l, DEFAULT_EVENT_SEGMENT_MAX_BYTES as lt, applyConfigOptionsToState as m, sessionEventSegmentPath as mt, runPromptTurn as n, recordPerfDuration as nt, currentModelIdFromSetModelResponse as o, parseSessionRecord as ot, applyConfigOptionsToRecord as p, sessionEventLockPath as pt, normalizeName as q, PERMISSION_POLICY_ACTIONS as qt, withConnectedSession as r, resetPerfMetrics as rt, clearDesiredConfigOption as s, serializeSessionRecordForDisk as st, LiveSessionCheckpoint as t, measurePerf as tt, setDesiredModeId as u, defaultSessionEventLog as ut, recordClientOperation as v, parsePromptStopReason as vt, persistSessionOptions as w, textPrompt as wt, trimConversationForRuntime as x, mergePromptSourceWithText as xt, recordPromptSubmission as y, PromptInputValidationError as yt, DEFAULT_HISTORY_LIMIT as z, toAcpErrorPayload as zt };
5472
6113
 
5473
- //# sourceMappingURL=live-checkpoint-CuFft_Nd.js.map
6114
+ //# sourceMappingURL=live-checkpoint-BWkYxMeS.js.map