@codexhost/cli-darwin-x64 0.2.0 → 0.2.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.
@@ -773,10 +773,10 @@ function mergeDefs(...defs) {
773
773
  function cloneDef(schema) {
774
774
  return mergeDefs(schema._zod.def);
775
775
  }
776
- function getElementAtPath(obj, path17) {
777
- if (!path17)
776
+ function getElementAtPath(obj, path18) {
777
+ if (!path18)
778
778
  return obj;
779
- return path17.reduce((acc, key) => acc?.[key], obj);
779
+ return path18.reduce((acc, key) => acc?.[key], obj);
780
780
  }
781
781
  function promiseAllObject(promisesObj) {
782
782
  const keys = Object.keys(promisesObj);
@@ -1185,11 +1185,11 @@ function explicitlyAborted(x2, startIndex = 0) {
1185
1185
  }
1186
1186
  return false;
1187
1187
  }
1188
- function prefixIssues(path17, issues) {
1188
+ function prefixIssues(path18, issues) {
1189
1189
  return issues.map((iss) => {
1190
1190
  var _a4;
1191
1191
  (_a4 = iss).path ?? (_a4.path = []);
1192
- iss.path.unshift(path17);
1192
+ iss.path.unshift(path18);
1193
1193
  return iss;
1194
1194
  });
1195
1195
  }
@@ -1336,16 +1336,16 @@ function flattenError(error52, mapper = (issue2) => issue2.message) {
1336
1336
  }
1337
1337
  function formatError(error52, mapper = (issue2) => issue2.message) {
1338
1338
  const fieldErrors = { _errors: [] };
1339
- const processError = (error53, path17 = []) => {
1339
+ const processError = (error53, path18 = []) => {
1340
1340
  for (const issue2 of error53.issues) {
1341
1341
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1342
- issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
1342
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
1343
1343
  } else if (issue2.code === "invalid_key") {
1344
- processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1344
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1345
1345
  } else if (issue2.code === "invalid_element") {
1346
- processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1346
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1347
1347
  } else {
1348
- const fullpath = [...path17, ...issue2.path];
1348
+ const fullpath = [...path18, ...issue2.path];
1349
1349
  if (fullpath.length === 0) {
1350
1350
  fieldErrors._errors.push(mapper(issue2));
1351
1351
  } else {
@@ -1372,17 +1372,17 @@ function formatError(error52, mapper = (issue2) => issue2.message) {
1372
1372
  }
1373
1373
  function treeifyError(error52, mapper = (issue2) => issue2.message) {
1374
1374
  const result = { errors: [] };
1375
- const processError = (error53, path17 = []) => {
1375
+ const processError = (error53, path18 = []) => {
1376
1376
  var _a4, _b2;
1377
1377
  for (const issue2 of error53.issues) {
1378
1378
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1379
- issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
1379
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
1380
1380
  } else if (issue2.code === "invalid_key") {
1381
- processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1381
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1382
1382
  } else if (issue2.code === "invalid_element") {
1383
- processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1383
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1384
1384
  } else {
1385
- const fullpath = [...path17, ...issue2.path];
1385
+ const fullpath = [...path18, ...issue2.path];
1386
1386
  if (fullpath.length === 0) {
1387
1387
  result.errors.push(mapper(issue2));
1388
1388
  continue;
@@ -1414,8 +1414,8 @@ function treeifyError(error52, mapper = (issue2) => issue2.message) {
1414
1414
  }
1415
1415
  function toDotPath(_path) {
1416
1416
  const segs = [];
1417
- const path17 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1418
- for (const seg of path17) {
1417
+ const path18 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1418
+ for (const seg of path18) {
1419
1419
  if (typeof seg === "number")
1420
1420
  segs.push(`[${seg}]`);
1421
1421
  else if (typeof seg === "symbol")
@@ -14107,13 +14107,13 @@ function resolveRef(ref, ctx) {
14107
14107
  if (!ref.startsWith("#")) {
14108
14108
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14109
14109
  }
14110
- const path17 = ref.slice(1).split("/").filter(Boolean);
14111
- if (path17.length === 0) {
14110
+ const path18 = ref.slice(1).split("/").filter(Boolean);
14111
+ if (path18.length === 0) {
14112
14112
  return ctx.rootSchema;
14113
14113
  }
14114
14114
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14115
- if (path17[0] === defsKey) {
14116
- const key = path17[1];
14115
+ if (path18[0] === defsKey) {
14116
+ const key = path18[1];
14117
14117
  if (!key || !ctx.defs[key]) {
14118
14118
  throw new Error(`Reference not found: ${ref}`);
14119
14119
  }
@@ -14690,12 +14690,24 @@ var threadUsageSnapshotSchema = external_exports.object({
14690
14690
  });
14691
14691
  }
14692
14692
  });
14693
+ var usagePercentSchema = external_exports.number().finite().min(0).max(100);
14694
+ var accountCreditsProductUsageSchema = external_exports.object({
14695
+ product: external_exports.string().min(1),
14696
+ usagePercent: usagePercentSchema
14697
+ }).strict();
14698
+ var accountCreditsSnapshotSchema = external_exports.object({
14699
+ usedPercent: usagePercentSchema,
14700
+ resetsAt: external_exports.string().min(1).optional(),
14701
+ periodType: external_exports.enum(["weekly", "monthly", "unknown"]),
14702
+ productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional()
14703
+ }).strict();
14693
14704
  var threadUsageInspectionParamsSchema = external_exports.object({
14694
14705
  threadId: hostThreadIdSchema
14695
14706
  }).strict();
14696
14707
  var threadUsageInspectionSchema = external_exports.object({
14697
14708
  threadId: hostThreadIdSchema,
14698
- usage: threadUsageSnapshotSchema.nullable()
14709
+ usage: threadUsageSnapshotSchema.nullable(),
14710
+ accountCredits: accountCreditsSnapshotSchema.optional()
14699
14711
  }).strict();
14700
14712
 
14701
14713
  // packages/shared-contracts/dist/harness-models.js
@@ -19116,8 +19128,8 @@ var qU = v(function(BU) {
19116
19128
  BU._globalThis = void 0;
19117
19129
  BU._globalThis = typeof globalThis === "object" ? globalThis : global;
19118
19130
  });
19119
- var GU = v(function(os6) {
19120
- var Axe = os6 && os6.__createBinding || (Object.create ? function(e, t, r, n) {
19131
+ var GU = v(function(os7) {
19132
+ var Axe = os7 && os7.__createBinding || (Object.create ? function(e, t, r, n) {
19121
19133
  if (n === void 0) n = r;
19122
19134
  Object.defineProperty(e, n, { enumerable: true, get: function() {
19123
19135
  return t[r];
@@ -19125,11 +19137,11 @@ var GU = v(function(os6) {
19125
19137
  } : function(e, t, r, n) {
19126
19138
  if (n === void 0) n = r;
19127
19139
  e[n] = t[r];
19128
- }), kxe = os6 && os6.__exportStar || function(e, t) {
19140
+ }), kxe = os7 && os7.__exportStar || function(e, t) {
19129
19141
  for (var r in e) if (r !== "default" && !Object.prototype.hasOwnProperty.call(t, r)) Axe(t, e, r);
19130
19142
  };
19131
- Object.defineProperty(os6, "__esModule", { value: true });
19132
- kxe(qU(), os6);
19143
+ Object.defineProperty(os7, "__esModule", { value: true });
19144
+ kxe(qU(), os7);
19133
19145
  });
19134
19146
  var WU = v(function(is) {
19135
19147
  var Oxe = is && is.__createBinding || (Object.create ? function(e, t, r, n) {
@@ -44826,16 +44838,16 @@ var AbstractApiClient = class {
44826
44838
  * Shared POST leg of both C→S carriers (callUnary/respond): JSON body,
44827
44839
  * optional default timeout merged with the caller's external signal, non-2xx → transport throw.
44828
44840
  */
44829
- async postJson(path17, body, signal, timeoutPolicy = "default") {
44841
+ async postJson(path18, body, signal, timeoutPolicy = "default") {
44830
44842
  const requestSignal = timeoutPolicy === "default" ? signal === void 0 ? AbortSignal.timeout(this.timeoutMs) : AbortSignal.any([AbortSignal.timeout(this.timeoutMs), signal]) : signal;
44831
- const response = await this.doFetch(new URL(path17, this.resolveBase()), {
44843
+ const response = await this.doFetch(new URL(path18, this.resolveBase()), {
44832
44844
  method: "POST",
44833
44845
  headers: { "content-type": "application/json" },
44834
44846
  body: JSON.stringify(body),
44835
44847
  ...requestSignal === void 0 ? {} : { signal: requestSignal }
44836
44848
  });
44837
44849
  if (!response.ok)
44838
- throw new Error(`transport failure for ${path17}: HTTP ${response.status}`);
44850
+ throw new Error(`transport failure for ${path18}: HTTP ${response.status}`);
44839
44851
  return response;
44840
44852
  }
44841
44853
  /**
@@ -44871,10 +44883,10 @@ var AbstractApiClient = class {
44871
44883
  * either parse level is reported and skipped (one corrupt frame must not kill the stream; the
44872
44884
  * client's gap detection covers whatever the frame carried).
44873
44885
  */
44874
- async *readSse(path17, signal, frameSchema, onOpen) {
44875
- const response = await this.doFetch(new URL(path17, this.resolveBase()), { signal });
44886
+ async *readSse(path18, signal, frameSchema, onOpen) {
44887
+ const response = await this.doFetch(new URL(path18, this.resolveBase()), { signal });
44876
44888
  if (!response.ok || response.body === null)
44877
- throw new Error(`transport failure for ${path17}: HTTP ${response.status}`);
44889
+ throw new Error(`transport failure for ${path18}: HTTP ${response.status}`);
44878
44890
  onOpen?.();
44879
44891
  const reader = response.body.getReader();
44880
44892
  const decoder2 = new TextDecoder();
@@ -44898,7 +44910,7 @@ var AbstractApiClient = class {
44898
44910
  full = serverRequestSchema.parse(JSON.parse(data));
44899
44911
  frame = frameSchema.parse(full.payload);
44900
44912
  } catch (error52) {
44901
- console.error(`[apiproxy] dropping malformed SSE frame on ${path17}:`, error52);
44913
+ console.error(`[apiproxy] dropping malformed SSE frame on ${path18}:`, error52);
44902
44914
  continue;
44903
44915
  }
44904
44916
  this.onEnvelope(full);
@@ -45473,16 +45485,16 @@ var Diff = class {
45473
45485
  }
45474
45486
  }
45475
45487
  }
45476
- addToPath(path17, added, removed, oldPosInc, options) {
45477
- const last = path17.lastComponent;
45488
+ addToPath(path18, added, removed, oldPosInc, options) {
45489
+ const last = path18.lastComponent;
45478
45490
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
45479
45491
  return {
45480
- oldPos: path17.oldPos + oldPosInc,
45492
+ oldPos: path18.oldPos + oldPosInc,
45481
45493
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
45482
45494
  };
45483
45495
  } else {
45484
45496
  return {
45485
- oldPos: path17.oldPos + oldPosInc,
45497
+ oldPos: path18.oldPos + oldPosInc,
45486
45498
  lastComponent: { count: 1, added, removed, previousComponent: last }
45487
45499
  };
45488
45500
  }
@@ -46657,13 +46669,7 @@ var DeepSeekHarnessSession = class {
46657
46669
  error: invalidState2(`DeepSeek Harness rejected Interaction: ${receipt.reason}`)
46658
46670
  };
46659
46671
  }
46660
- active.interactions.delete(command.interactionId);
46661
- this.#emit({
46662
- type: "interaction.closed",
46663
- interactionId: command.interactionId,
46664
- turnId: active.command.turnId,
46665
- reason: "responded"
46666
- });
46672
+ this.#closeHostInteraction(active, command.interactionId, "responded");
46667
46673
  return { ok: true, value: { accepted: true } };
46668
46674
  } catch (error52) {
46669
46675
  return { ok: false, error: normalizedError(error52, "nativeFailure") };
@@ -46945,15 +46951,19 @@ var DeepSeekHarnessSession = class {
46945
46951
  const matches = type === "approval" ? pending.type === "approval" && pending.approvalId === nativeId : pending.type === "question" && pending.rpcId === nativeId;
46946
46952
  if (!matches)
46947
46953
  continue;
46948
- active.interactions.delete(interactionId);
46949
- this.#emit({
46950
- type: "interaction.closed",
46951
- interactionId,
46952
- turnId: active.command.turnId,
46953
- reason: "responded"
46954
- });
46954
+ this.#closeHostInteraction(active, interactionId, "responded");
46955
46955
  }
46956
46956
  }
46957
+ #closeHostInteraction(active, interactionId, reason) {
46958
+ if (!active.interactions.delete(interactionId))
46959
+ return;
46960
+ this.#emit({
46961
+ type: "interaction.closed",
46962
+ interactionId,
46963
+ turnId: active.command.turnId,
46964
+ reason
46965
+ });
46966
+ }
46957
46967
  #finishTurn(active, reason) {
46958
46968
  const terminal = projectTurnReason(reason);
46959
46969
  const itemOutcome3 = terminal.outcome.status === "succeeded" ? { status: "succeeded" } : terminal.outcome.status === "cancelled" ? {
@@ -46965,15 +46975,9 @@ var DeepSeekHarnessSession = class {
46965
46975
  for (const tool of active.tools.values())
46966
46976
  this.#completeItem(active, tool.item, itemOutcome3);
46967
46977
  active.tools.clear();
46968
- for (const [interactionId] of active.interactions) {
46969
- this.#emit({
46970
- type: "interaction.closed",
46971
- interactionId,
46972
- turnId: active.command.turnId,
46973
- reason: "cancelled"
46974
- });
46978
+ for (const interactionId of [...active.interactions.keys()]) {
46979
+ this.#closeHostInteraction(active, interactionId, "cancelled");
46975
46980
  }
46976
- active.interactions.clear();
46977
46981
  const nativeTurnRef2 = this.#nativeTurnRef(active.nativeTurn);
46978
46982
  this.#turns.push({
46979
46983
  nativeTurnRef: nativeTurnRef2,
@@ -47046,15 +47050,9 @@ var DeepSeekHarnessSession = class {
47046
47050
  for (const tool of active.tools.values())
47047
47051
  this.#completeItem(active, tool.item, outcome);
47048
47052
  active.tools.clear();
47049
- for (const [interactionId] of active.interactions) {
47050
- this.#emit({
47051
- type: "interaction.closed",
47052
- interactionId,
47053
- turnId: active.command.turnId,
47054
- reason: "cancelled"
47055
- });
47053
+ for (const interactionId of [...active.interactions.keys()]) {
47054
+ this.#closeHostInteraction(active, interactionId, "cancelled");
47056
47055
  }
47057
- active.interactions.clear();
47058
47056
  this.#emit({
47059
47057
  type: "turn.completed",
47060
47058
  turnId: active.command.turnId,
@@ -47248,7 +47246,7 @@ var packageMetadata3 = {
47248
47246
 
47249
47247
  // packages/adapters/grok/dist/grok-adapter.js
47250
47248
  import { randomUUID as randomUUID3 } from "node:crypto";
47251
- import path9 from "node:path";
47249
+ import path10 from "node:path";
47252
47250
 
47253
47251
  // packages/adapters/grok/dist/acp-transport.js
47254
47252
  import { spawn as spawn3, spawnSync } from "node:child_process";
@@ -51605,8 +51603,8 @@ function transportEvent(update, metadata) {
51605
51603
  function nativeSessionFile(options, sessionId, fileName) {
51606
51604
  const environment = { ...process.env, ...options.environment };
51607
51605
  const home = environment.HOME ?? environment.USERPROFILE ?? os3.homedir();
51608
- const grokHome = environment.GROK_HOME ?? path8.join(home, ".grok");
51609
- return path8.join(grokHome, "sessions", encodeURIComponent(path8.resolve(options.cwd)), sessionId, fileName);
51606
+ const grokHome2 = environment.GROK_HOME ?? path8.join(home, ".grok");
51607
+ return path8.join(grokHome2, "sessions", encodeURIComponent(path8.resolve(options.cwd)), sessionId, fileName);
51610
51608
  }
51611
51609
  function nativeHistoryPath(options, sessionId) {
51612
51610
  return nativeSessionFile(options, sessionId, "updates.jsonl");
@@ -51904,6 +51902,14 @@ function terminalOutcome(stopReason) {
51904
51902
  }
51905
51903
  };
51906
51904
  }
51905
+ var systemReminderPattern = /^\s*<system-reminder>[\s\S]*$/u;
51906
+ var taskCompletedTurnKeyPattern = /^task-completed-/u;
51907
+ function isSyntheticGrokUserText(text) {
51908
+ return systemReminderPattern.test(text);
51909
+ }
51910
+ function isSyntheticGrokTurnKey(nativeTurnKey3) {
51911
+ return taskCompletedTurnKeyPattern.test(nativeTurnKey3);
51912
+ }
51907
51913
  function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
51908
51914
  const turns = [];
51909
51915
  let input = "";
@@ -51964,6 +51970,8 @@ function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
51964
51970
  };
51965
51971
  for (const event of replay) {
51966
51972
  if (event.type === "user.text") {
51973
+ if (isSyntheticGrokUserText(event.text))
51974
+ continue;
51967
51975
  if (input.length > 0) {
51968
51976
  completeTurn({
51969
51977
  status: "unknown",
@@ -51982,6 +51990,8 @@ function mapGrokReplay(replay, harnessId, sessionId, knownTurnRefs = []) {
51982
51990
  if (input.length === 0)
51983
51991
  continue;
51984
51992
  if (event.type === "turn.completed") {
51993
+ if (isSyntheticGrokTurnKey(event.nativeTurnKey))
51994
+ continue;
51985
51995
  completeTurn(terminalOutcome(event.stopReason), event.nativeTurnKey);
51986
51996
  } else if (event.type === "agent.text") {
51987
51997
  if (!agent) {
@@ -52124,9 +52134,115 @@ function stateForGrokModel(modelState, nativeState, model = modelState.currentMo
52124
52134
  };
52125
52135
  }
52126
52136
 
52137
+ // packages/adapters/grok/dist/grok-credits.js
52138
+ import { readFile as readFile2 } from "node:fs/promises";
52139
+ import os4 from "node:os";
52140
+ import path9 from "node:path";
52141
+ var GROK_CREDITS_ENDPOINT = "https://cli-chat-proxy.grok.com/v1/billing?format=credits";
52142
+ var REQUEST_TIMEOUT_MS = 15e3;
52143
+ function isRecord11(value) {
52144
+ return typeof value === "object" && value !== null && !Array.isArray(value);
52145
+ }
52146
+ function finitePercent(value) {
52147
+ if (typeof value !== "number" || !Number.isFinite(value))
52148
+ return void 0;
52149
+ return Math.min(100, Math.max(0, value));
52150
+ }
52151
+ function nonNegativeNumber(value) {
52152
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
52153
+ return void 0;
52154
+ return value;
52155
+ }
52156
+ function grokHome(environment) {
52157
+ return environment.GROK_HOME ?? path9.join(environment.HOME ?? environment.USERPROFILE ?? os4.homedir(), ".grok");
52158
+ }
52159
+ function periodTypeFrom(value) {
52160
+ if (typeof value !== "string")
52161
+ return "unknown";
52162
+ const normalized = value.toUpperCase();
52163
+ if (normalized.includes("WEEKLY"))
52164
+ return "weekly";
52165
+ if (normalized.includes("MONTHLY"))
52166
+ return "monthly";
52167
+ return "unknown";
52168
+ }
52169
+ function productUsageFrom(value) {
52170
+ if (!Array.isArray(value))
52171
+ return void 0;
52172
+ const products = value.flatMap((entry) => {
52173
+ if (!isRecord11(entry) || typeof entry.product !== "string")
52174
+ return [];
52175
+ const usagePercent = finitePercent(entry.usagePercent);
52176
+ return usagePercent === void 0 ? [] : [{ product: entry.product, usagePercent }];
52177
+ });
52178
+ return products.length > 0 ? products : void 0;
52179
+ }
52180
+ function parseGrokCreditsResponse(value, fetchedAt = (/* @__PURE__ */ new Date()).toISOString()) {
52181
+ if (!isRecord11(value) || !isRecord11(value.config))
52182
+ return null;
52183
+ const config2 = value.config;
52184
+ const period = isRecord11(config2.currentPeriod) ? config2.currentPeriod : void 0;
52185
+ const resetsAt = (typeof period?.end === "string" && period.end.length > 0 ? period.end : void 0) ?? (typeof config2.billingPeriodEnd === "string" && config2.billingPeriodEnd.length > 0 ? config2.billingPeriodEnd : void 0);
52186
+ const onDemandCap = isRecord11(config2.onDemandCap) ? nonNegativeNumber(config2.onDemandCap.val) : void 0;
52187
+ const onDemandUsed = isRecord11(config2.onDemandUsed) ? nonNegativeNumber(config2.onDemandUsed.val) : void 0;
52188
+ const usedPercent = finitePercent(config2.creditUsagePercent) ?? (onDemandCap !== void 0 && onDemandCap > 0 && onDemandUsed !== void 0 ? Math.min(100, Math.max(0, onDemandUsed / onDemandCap * 100)) : resetsAt ? 0 : void 0);
52189
+ if (usedPercent === void 0)
52190
+ return null;
52191
+ const productUsage = productUsageFrom(config2.productUsage);
52192
+ return {
52193
+ usedPercent,
52194
+ periodType: periodTypeFrom(period?.type),
52195
+ fetchedAt,
52196
+ ...resetsAt ? { resetsAt } : {},
52197
+ ...productUsage ? { productUsage } : {}
52198
+ };
52199
+ }
52200
+ function selectAccessToken(auth, now) {
52201
+ if (!isRecord11(auth))
52202
+ return null;
52203
+ const entries = Object.entries(auth).filter(([, value]) => isRecord11(value) && typeof value.key === "string" && value.key.length > 0).sort(([left], [right]) => Number(right.startsWith("https://auth.x.ai")) - Number(left.startsWith("https://auth.x.ai")));
52204
+ for (const [, value] of entries) {
52205
+ if (!isRecord11(value) || typeof value.key !== "string")
52206
+ continue;
52207
+ if (typeof value.expires_at === "string") {
52208
+ const expiresAt = Date.parse(value.expires_at);
52209
+ if (Number.isFinite(expiresAt) && expiresAt <= now.getTime())
52210
+ continue;
52211
+ }
52212
+ return value.key;
52213
+ }
52214
+ return null;
52215
+ }
52216
+ async function fetchGrokCredits(input = {}) {
52217
+ try {
52218
+ const environment = input.environment ?? process.env;
52219
+ const now = input.now ?? /* @__PURE__ */ new Date();
52220
+ const authPath = path9.join(grokHome(environment), "auth.json");
52221
+ const raw = input.readAuthFile ? await input.readAuthFile(authPath) : await readFile2(authPath, "utf8");
52222
+ const token = selectAccessToken(JSON.parse(raw), now);
52223
+ if (!token)
52224
+ return null;
52225
+ const fetchImpl = input.fetch ?? fetch;
52226
+ const response = await fetchImpl(GROK_CREDITS_ENDPOINT, {
52227
+ method: "GET",
52228
+ headers: {
52229
+ Authorization: `Bearer ${token}`,
52230
+ "x-xai-token-auth": "xai-grok-cli",
52231
+ Accept: "application/json"
52232
+ },
52233
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
52234
+ });
52235
+ if (!response.ok)
52236
+ return null;
52237
+ return parseGrokCreditsResponse(await response.json(), now.toISOString());
52238
+ } catch {
52239
+ return null;
52240
+ }
52241
+ }
52242
+
52127
52243
  // packages/adapters/grok/dist/grok-usage.js
52128
52244
  var USD_TICKS_PER_DOLLAR = 1e10;
52129
- function isRecord11(value) {
52245
+ function isRecord12(value) {
52130
52246
  return typeof value === "object" && value !== null && !Array.isArray(value);
52131
52247
  }
52132
52248
  function optionalToken(value) {
@@ -52143,7 +52259,7 @@ function combineUsage(base, next) {
52143
52259
  return base === null ? next : parseHostUsage({ ...base, ...next });
52144
52260
  }
52145
52261
  function usageFromNative(value) {
52146
- if (!isRecord11(value))
52262
+ if (!isRecord12(value))
52147
52263
  return null;
52148
52264
  const inputTokens = optionalToken(value.inputTokens);
52149
52265
  const cachedRead = optionalToken(value.cachedReadTokens);
@@ -52170,7 +52286,7 @@ function usageFromPrompt(response) {
52170
52286
  return response.usage ? usageFromNative(response.usage) : null;
52171
52287
  }
52172
52288
  function usageFromSignals(value) {
52173
- if (!isRecord11(value))
52289
+ if (!isRecord12(value))
52174
52290
  return null;
52175
52291
  try {
52176
52292
  return parseHostUsage({
@@ -52195,7 +52311,7 @@ function lastTurnUsage(events) {
52195
52311
  function usageFromUpdate(update, metadata, contextWindowTokens) {
52196
52312
  try {
52197
52313
  if (update?.sessionUpdate === "usage_update") {
52198
- const cost = isRecord11(update.cost) ? update.cost : null;
52314
+ const cost = isRecord12(update.cost) ? update.cost : null;
52199
52315
  return parseHostUsage({
52200
52316
  contextUsedTokens: update.used,
52201
52317
  contextWindowTokens: update.size,
@@ -52229,7 +52345,7 @@ function capabilitiesForModels(modelState) {
52229
52345
  }
52230
52346
  var DEFAULT_CLOSE_TIMEOUT_MS3 = 2e3;
52231
52347
  var DEFAULT_TOOL_OUTPUT_LIMIT3 = 64e3;
52232
- function isRecord12(value) {
52348
+ function isRecord13(value) {
52233
52349
  return typeof value === "object" && value !== null && !Array.isArray(value);
52234
52350
  }
52235
52351
  function invalidState3(message3) {
@@ -52264,7 +52380,7 @@ function contentText2(content) {
52264
52380
  if (!content)
52265
52381
  return "";
52266
52382
  return content.flatMap((entry) => {
52267
- if (!isRecord12(entry) || entry.type !== "content" || !isRecord12(entry.content))
52383
+ if (!isRecord13(entry) || entry.type !== "content" || !isRecord13(entry.content))
52268
52384
  return [];
52269
52385
  return entry.content.type === "text" && typeof entry.content.text === "string" ? [entry.content.text] : [];
52270
52386
  }).join("\n");
@@ -52827,22 +52943,53 @@ var GrokAdapter = class {
52827
52943
  harnessId = grokHarnessId;
52828
52944
  #closeTimeoutMs;
52829
52945
  #dependencies;
52946
+ #environment;
52947
+ #fetchCredits;
52830
52948
  #inspectionCache = /* @__PURE__ */ new Map();
52831
52949
  #sessions = /* @__PURE__ */ new Set();
52832
52950
  #toolOutputLimit;
52833
52951
  #closePromise = null;
52952
+ #credits = null;
52953
+ #creditsRefresh = null;
52834
52954
  constructor(options = {}, dependencies) {
52835
52955
  this.#closeTimeoutMs = options.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS3;
52956
+ this.#environment = options.environment;
52836
52957
  this.#toolOutputLimit = options.toolOutputLimit ?? DEFAULT_TOOL_OUTPUT_LIMIT3;
52837
52958
  this.#dependencies = dependencies ?? {
52838
52959
  randomUUID: randomUUID3,
52839
52960
  createTransport: (transportOptions) => new GrokAcpTransport({ ...options, ...transportOptions })
52840
52961
  };
52962
+ this.#fetchCredits = this.#dependencies.fetchCredits ?? ((input) => fetchGrokCredits(input.environment ? { environment: input.environment } : this.#environment ? { environment: this.#environment } : {}));
52963
+ }
52964
+ credits() {
52965
+ return this.#credits;
52966
+ }
52967
+ refreshCredits() {
52968
+ if (this.#closePromise)
52969
+ return Promise.resolve(this.#credits);
52970
+ if (this.#creditsRefresh)
52971
+ return this.#creditsRefresh;
52972
+ this.#creditsRefresh = this.#loadCredits().finally(() => {
52973
+ this.#creditsRefresh = null;
52974
+ });
52975
+ return this.#creditsRefresh;
52976
+ }
52977
+ #scheduleCreditsRefresh() {
52978
+ void this.refreshCredits();
52979
+ }
52980
+ async #loadCredits() {
52981
+ try {
52982
+ const snapshot = await this.#fetchCredits(this.#environment ? { environment: this.#environment } : {});
52983
+ if (snapshot)
52984
+ this.#credits = snapshot;
52985
+ } catch {
52986
+ }
52987
+ return this.#credits;
52841
52988
  }
52842
52989
  async inspect(input = {}) {
52843
52990
  if (this.#closePromise)
52844
52991
  return { status: "unavailable", error: invalidState3("Grok Adapter is closed") };
52845
- const cwd = path9.resolve(input.cwd ?? process.cwd());
52992
+ const cwd = path10.resolve(input.cwd ?? process.cwd());
52846
52993
  if (!input.refresh) {
52847
52994
  const cached2 = this.#inspectionCache.get(cwd);
52848
52995
  if (cached2)
@@ -52862,6 +53009,7 @@ var GrokAdapter = class {
52862
53009
  capabilities: capabilitiesForModels(modelState)
52863
53010
  };
52864
53011
  this.#inspectionCache.set(cwd, ready);
53012
+ this.#scheduleCreditsRefresh();
52865
53013
  return ready;
52866
53014
  } catch (error52) {
52867
53015
  await transport?.close().catch(() => void 0);
@@ -52900,7 +53048,7 @@ var GrokAdapter = class {
52900
53048
  }
52901
53049
  };
52902
53050
  }
52903
- const cwd = path9.resolve(input.cwd);
53051
+ const cwd = path10.resolve(input.cwd);
52904
53052
  const parsedRef = input.kind === "resume" ? nativeSessionRefSchema.safeParse(input.nativeRef) : null;
52905
53053
  if (parsedRef && (!parsedRef.success || parsedRef.data.harnessId !== this.harnessId)) {
52906
53054
  return {
@@ -52949,6 +53097,7 @@ var GrokAdapter = class {
52949
53097
  });
52950
53098
  session = openedSession;
52951
53099
  this.#sessions.add(openedSession);
53100
+ this.#scheduleCreditsRefresh();
52952
53101
  return { ok: true, value: openedSession };
52953
53102
  } catch (error52) {
52954
53103
  await transport.close().catch(() => void 0);
@@ -53086,7 +53235,7 @@ function normalizePiModelCatalog(nativeModels, effectiveModel, thinkingLevels, e
53086
53235
 
53087
53236
  // packages/adapters/pi/dist/pi-history.js
53088
53237
  var piHarnessId = harnessIdSchema.parse("pi");
53089
- function isRecord13(value) {
53238
+ function isRecord14(value) {
53090
53239
  return typeof value === "object" && value !== null && !Array.isArray(value);
53091
53240
  }
53092
53241
  function textContent(value) {
@@ -53094,12 +53243,12 @@ function textContent(value) {
53094
53243
  return value;
53095
53244
  if (!Array.isArray(value))
53096
53245
  return "";
53097
- return value.filter((part) => isRecord13(part) && part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
53246
+ return value.filter((part) => isRecord14(part) && part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
53098
53247
  }
53099
53248
  function thinkingContent(value) {
53100
53249
  if (!Array.isArray(value))
53101
53250
  return "";
53102
- return value.filter((part) => isRecord13(part) && part.type === "thinking" && typeof part.thinking === "string").map((part) => part.thinking).join("");
53251
+ return value.filter((part) => isRecord14(part) && part.type === "thinking" && typeof part.thinking === "string").map((part) => part.thinking).join("");
53103
53252
  }
53104
53253
  function validatedEntry(value) {
53105
53254
  if (typeof value.id !== "string" || value.id.length === 0 || value.parentId !== null && typeof value.parentId !== "string" || typeof value.type !== "string") {
@@ -53130,7 +53279,7 @@ function activePiEntries(history) {
53130
53279
  return reversed.reverse();
53131
53280
  }
53132
53281
  function message(entry) {
53133
- return entry.type === "message" && isRecord13(entry.message) ? entry.message : null;
53282
+ return entry.type === "message" && isRecord14(entry.message) ? entry.message : null;
53134
53283
  }
53135
53284
  function messageRole(entry) {
53136
53285
  const value = message(entry)?.role;
@@ -53192,7 +53341,7 @@ function snapshotItems(entries, outcome) {
53192
53341
  let projectedText = false;
53193
53342
  let projectedReasoning = false;
53194
53343
  for (const [ordinal, part] of content.entries()) {
53195
- if (!isRecord13(part))
53344
+ if (!isRecord14(part))
53196
53345
  continue;
53197
53346
  if (part.type === "thinking" && !projectedReasoning && reasoning.length > 0) {
53198
53347
  const item2 = {
@@ -53384,12 +53533,12 @@ async function rollbackPiLastTurn(transport, sourceSessionId, cwd) {
53384
53533
  // packages/adapters/pi/dist/pi-rpc-session.js
53385
53534
  import { spawn as spawn4, spawnSync as spawnSync2 } from "node:child_process";
53386
53535
  import { randomUUID as randomUUID4 } from "node:crypto";
53387
- import path11 from "node:path";
53536
+ import path12 from "node:path";
53388
53537
 
53389
53538
  // packages/adapters/pi/dist/command.js
53390
53539
  import { accessSync as accessSync2, constants as constants2, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
53391
- import os4 from "node:os";
53392
- import path10 from "node:path";
53540
+ import os5 from "node:os";
53541
+ import path11 from "node:path";
53393
53542
  function environmentValue2(environment, name) {
53394
53543
  return Object.entries(environment).find(([key]) => key.toLowerCase() === name.toLowerCase())?.[1];
53395
53544
  }
@@ -53402,7 +53551,7 @@ function isExecutable3(filePath, platform) {
53402
53551
  }
53403
53552
  }
53404
53553
  function pathCandidates(command, platform, environment) {
53405
- const targetPath = platform === "win32" ? path10.win32 : path10.posix;
53554
+ const targetPath = platform === "win32" ? path11.win32 : path11.posix;
53406
53555
  if (targetPath.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
53407
53556
  return [command];
53408
53557
  }
@@ -53410,25 +53559,25 @@ function pathCandidates(command, platform, environment) {
53410
53559
  return (environmentValue2(environment, "PATH") ?? "").split(targetPath.delimiter).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean).flatMap((directory) => extensions.map((extension) => targetPath.join(directory, command + extension)));
53411
53560
  }
53412
53561
  function nvmCandidates2(homeDirectory, executableName) {
53413
- const versionsDirectory = path10.join(homeDirectory, ".nvm", "versions", "node");
53562
+ const versionsDirectory = path11.join(homeDirectory, ".nvm", "versions", "node");
53414
53563
  try {
53415
- return readdirSync2(versionsDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left, void 0, { numeric: true })).map((version2) => path10.join(versionsDirectory, version2, "bin", executableName));
53564
+ return readdirSync2(versionsDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left, void 0, { numeric: true })).map((version2) => path11.join(versionsDirectory, version2, "bin", executableName));
53416
53565
  } catch {
53417
53566
  return [];
53418
53567
  }
53419
53568
  }
53420
53569
  function userInstallCandidates2(platform, environment, homeDirectory) {
53421
53570
  if (platform === "win32") {
53422
- const appData = environment.APPDATA ?? path10.join(homeDirectory, "AppData", "Roaming");
53571
+ const appData = environment.APPDATA ?? path11.join(homeDirectory, "AppData", "Roaming");
53423
53572
  return [
53424
- path10.join(appData, "npm", "pi.cmd"),
53425
- path10.join(homeDirectory, ".local", "bin", "pi.exe"),
53426
- path10.join(homeDirectory, ".local", "bin", "pi.cmd")
53573
+ path11.join(appData, "npm", "pi.cmd"),
53574
+ path11.join(homeDirectory, ".local", "bin", "pi.exe"),
53575
+ path11.join(homeDirectory, ".local", "bin", "pi.cmd")
53427
53576
  ];
53428
53577
  }
53429
53578
  return [
53430
- path10.join(homeDirectory, ".npm-global", "bin", "pi"),
53431
- path10.join(homeDirectory, ".local", "bin", "pi"),
53579
+ path11.join(homeDirectory, ".npm-global", "bin", "pi"),
53580
+ path11.join(homeDirectory, ".local", "bin", "pi"),
53432
53581
  ...nvmCandidates2(homeDirectory, "pi"),
53433
53582
  "/opt/homebrew/bin/pi",
53434
53583
  "/usr/local/bin/pi"
@@ -53438,7 +53587,7 @@ function resolvePiExecutable(input, dependencies = {}) {
53438
53587
  const platform = dependencies.platform ?? process.platform;
53439
53588
  const configuredCommand = input.command ?? input.environment.PI_COMMAND;
53440
53589
  const command = configuredCommand ?? "pi";
53441
- const homeDirectory = dependencies.homeDirectory ?? input.environment.HOME ?? input.environment.USERPROFILE ?? os4.homedir();
53590
+ const homeDirectory = dependencies.homeDirectory ?? input.environment.HOME ?? input.environment.USERPROFILE ?? os5.homedir();
53442
53591
  const candidates2 = [
53443
53592
  ...pathCandidates(command, platform, input.environment),
53444
53593
  ...configuredCommand ? [] : userInstallCandidates2(platform, input.environment, homeDirectory)
@@ -53449,7 +53598,7 @@ function resolvePiExecutable(input, dependencies = {}) {
53449
53598
  function withNodeRuntimeOnPath2(environment, runtimeExecutable = process.execPath, platform = process.platform) {
53450
53599
  const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
53451
53600
  const delimiter = platform === "win32" ? ";" : ":";
53452
- const runtimeDirectory = path10.dirname(runtimeExecutable);
53601
+ const runtimeDirectory = path11.dirname(runtimeExecutable);
53453
53602
  const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
53454
53603
  const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
53455
53604
  if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
@@ -53459,14 +53608,14 @@ function withNodeRuntimeOnPath2(environment, runtimeExecutable = process.execPat
53459
53608
  }
53460
53609
 
53461
53610
  // packages/adapters/pi/dist/pi-usage.js
53462
- function isRecord14(value) {
53611
+ function isRecord15(value) {
53463
53612
  return typeof value === "object" && value !== null && !Array.isArray(value);
53464
53613
  }
53465
53614
  function nonNegativeSafeInteger2(value) {
53466
53615
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
53467
53616
  }
53468
53617
  function optionalPiCacheHitRatePercent(value) {
53469
- if (!isRecord14(value) || value.role !== "assistant" || !isRecord14(value.usage))
53618
+ if (!isRecord15(value) || value.role !== "assistant" || !isRecord15(value.usage))
53470
53619
  return null;
53471
53620
  const input = nonNegativeSafeInteger2(value.usage.input);
53472
53621
  const cacheRead = nonNegativeSafeInteger2(value.usage.cacheRead);
@@ -53479,20 +53628,20 @@ function optionalPiCacheHitRatePercent(value) {
53479
53628
  function latestPiCacheHitRatePercent(history) {
53480
53629
  let latest = null;
53481
53630
  for (const entry of activePiEntries(history)) {
53482
- if (entry.type === "message" && isRecord14(entry.message) && entry.message.role === "assistant") {
53631
+ if (entry.type === "message" && isRecord15(entry.message) && entry.message.role === "assistant") {
53483
53632
  latest = optionalPiCacheHitRatePercent(entry.message);
53484
53633
  }
53485
53634
  }
53486
53635
  return latest;
53487
53636
  }
53488
53637
  function responseData(response, operation) {
53489
- if (!isRecord14(response.data)) {
53638
+ if (!isRecord15(response.data)) {
53490
53639
  throw new Error(`Pi RPC ${operation} response has no data`);
53491
53640
  }
53492
53641
  return response.data;
53493
53642
  }
53494
53643
  function contextUsage(value) {
53495
- if (!isRecord14(value))
53644
+ if (!isRecord15(value))
53496
53645
  throw new Error("Pi RPC context Usage is invalid");
53497
53646
  return parseHostUsage({
53498
53647
  contextUsedTokens: value.tokens,
@@ -53502,15 +53651,15 @@ function contextUsage(value) {
53502
53651
  function parsePiSessionUsage(response) {
53503
53652
  const data = responseData(response, "Session stats");
53504
53653
  const tokens = data.tokens;
53505
- if (tokens !== void 0 && !isRecord14(tokens)) {
53654
+ if (tokens !== void 0 && !isRecord15(tokens)) {
53506
53655
  throw new Error("Pi RPC Session stats tokens are invalid");
53507
53656
  }
53508
53657
  return parseHostUsage({
53509
- ...isRecord14(tokens) && tokens.input !== void 0 ? { inputTokens: tokens.input } : {},
53510
- ...isRecord14(tokens) && tokens.cacheRead !== void 0 ? { cachedInputTokens: tokens.cacheRead } : {},
53511
- ...isRecord14(tokens) && tokens.cacheWrite !== void 0 ? { cacheWriteInputTokens: tokens.cacheWrite } : {},
53512
- ...isRecord14(tokens) && tokens.output !== void 0 ? { outputTokens: tokens.output } : {},
53513
- ...isRecord14(tokens) && tokens.total !== void 0 ? { totalTokens: tokens.total } : {},
53658
+ ...isRecord15(tokens) && tokens.input !== void 0 ? { inputTokens: tokens.input } : {},
53659
+ ...isRecord15(tokens) && tokens.cacheRead !== void 0 ? { cachedInputTokens: tokens.cacheRead } : {},
53660
+ ...isRecord15(tokens) && tokens.cacheWrite !== void 0 ? { cacheWriteInputTokens: tokens.cacheWrite } : {},
53661
+ ...isRecord15(tokens) && tokens.output !== void 0 ? { outputTokens: tokens.output } : {},
53662
+ ...isRecord15(tokens) && tokens.total !== void 0 ? { totalTokens: tokens.total } : {},
53514
53663
  ...data.cost !== void 0 ? { totalCostUsd: data.cost } : {},
53515
53664
  ...data.contextUsage !== void 0 ? contextUsage(data.contextUsage) : {}
53516
53665
  });
@@ -53533,7 +53682,7 @@ function optionalPiStateContextUsage(value) {
53533
53682
  import { open, realpath } from "node:fs/promises";
53534
53683
  var MAX_SESSION_HEADER_BYTES = 64 * 1024;
53535
53684
  var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
53536
- function isRecord15(value) {
53685
+ function isRecord16(value) {
53537
53686
  return typeof value === "object" && value !== null && !Array.isArray(value);
53538
53687
  }
53539
53688
  async function readPiSessionHeader(sessionFile) {
@@ -53553,7 +53702,7 @@ async function readPiSessionHeader(sessionFile) {
53553
53702
  } catch {
53554
53703
  throw new Error("Pi Session header is not valid JSON");
53555
53704
  }
53556
- if (!isRecord15(parsed) || parsed.type !== "session" || typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
53705
+ if (!isRecord16(parsed) || parsed.type !== "session" || typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
53557
53706
  throw new Error("Pi Session header is invalid");
53558
53707
  }
53559
53708
  return { type: "session", id: parsed.id, cwd: parsed.cwd };
@@ -53595,7 +53744,7 @@ var PiRpcUnsupportedCommandError = class extends Error {
53595
53744
  }
53596
53745
  };
53597
53746
  var textDecoder = new TextDecoder("utf-8", { fatal: true });
53598
- function isRecord16(value) {
53747
+ function isRecord17(value) {
53599
53748
  return typeof value === "object" && value !== null && !Array.isArray(value);
53600
53749
  }
53601
53750
  function message2(value) {
@@ -53607,13 +53756,13 @@ function nonBlankString2(value) {
53607
53756
  function parseNativeModel(value, context) {
53608
53757
  if (value === null || value === void 0)
53609
53758
  return null;
53610
- if (!isRecord16(value) || !nonBlankString2(value.provider) || !nonBlankString2(value.id)) {
53759
+ if (!isRecord17(value) || !nonBlankString2(value.provider) || !nonBlankString2(value.id)) {
53611
53760
  throw new PiRpcFaultError("protocolError", `Pi RPC returned an invalid ${context} Model`);
53612
53761
  }
53613
53762
  return { provider: value.provider, id: value.id };
53614
53763
  }
53615
53764
  function sessionStateData(response) {
53616
- const data = isRecord16(response.data) ? response.data : null;
53765
+ const data = isRecord17(response.data) ? response.data : null;
53617
53766
  if (!data)
53618
53767
  throw new PiRpcFaultError("protocolError", "Pi RPC state response has no data");
53619
53768
  return data;
@@ -53645,13 +53794,13 @@ function parseSessionStreaming(response) {
53645
53794
  return isStreaming;
53646
53795
  }
53647
53796
  function parseSessionHistory(response) {
53648
- const data = isRecord16(response.data) ? response.data : null;
53797
+ const data = isRecord17(response.data) ? response.data : null;
53649
53798
  if (!data || !Array.isArray(data.entries)) {
53650
53799
  throw new PiRpcFaultError("protocolError", "Pi RPC entries response has no Entries");
53651
53800
  }
53652
53801
  const entries = data.entries.map((entry) => {
53653
53802
  const parsed = jsonValueSchema.safeParse(entry);
53654
- if (!parsed.success || !isRecord16(parsed.data)) {
53803
+ if (!parsed.success || !isRecord17(parsed.data)) {
53655
53804
  throw new PiRpcFaultError("protocolError", "Pi RPC entries response contains an invalid Entry");
53656
53805
  }
53657
53806
  return parsed.data;
@@ -53662,7 +53811,7 @@ function parseSessionHistory(response) {
53662
53811
  return { entries, leafId: data.leafId };
53663
53812
  }
53664
53813
  function parseAvailableThinkingLevels(response) {
53665
- const data = isRecord16(response.data) ? response.data : null;
53814
+ const data = isRecord17(response.data) ? response.data : null;
53666
53815
  if (!data || !Array.isArray(data.levels) || data.levels.length === 0) {
53667
53816
  throw new PiRpcFaultError("protocolError", "Pi RPC Thinking catalog response has no levels");
53668
53817
  }
@@ -53679,35 +53828,35 @@ function parseAvailableThinkingLevels(response) {
53679
53828
  return levels;
53680
53829
  }
53681
53830
  function parseAvailableModels(response) {
53682
- const data = isRecord16(response.data) ? response.data : null;
53831
+ const data = isRecord17(response.data) ? response.data : null;
53683
53832
  if (!data || !Array.isArray(data.models)) {
53684
53833
  throw new PiRpcFaultError("protocolError", "Pi RPC Model catalog response has no models");
53685
53834
  }
53686
53835
  return data.models.map((model) => {
53687
53836
  const parsed = parseNativeModel(model, "catalog");
53688
- if (!parsed || !isRecord16(model) || typeof model.reasoning !== "boolean") {
53837
+ if (!parsed || !isRecord17(model) || typeof model.reasoning !== "boolean") {
53689
53838
  throw new PiRpcFaultError("protocolError", "Pi RPC catalog contains a Model without reasoning capability");
53690
53839
  }
53691
53840
  return { ...parsed, reasoning: model.reasoning };
53692
53841
  });
53693
53842
  }
53694
53843
  function assistantText2(value) {
53695
- if (!isRecord16(value) || value.role !== "assistant" || !Array.isArray(value.content))
53844
+ if (!isRecord17(value) || value.role !== "assistant" || !Array.isArray(value.content))
53696
53845
  return null;
53697
- return value.content.filter((content) => isRecord16(content) && content.type === "text" && typeof content.text === "string").map((content) => content.text).join("");
53846
+ return value.content.filter((content) => isRecord17(content) && content.type === "text" && typeof content.text === "string").map((content) => content.text).join("");
53698
53847
  }
53699
53848
  function assistantMessageId(value) {
53700
- if (!isRecord16(value) || value.role !== "assistant")
53849
+ if (!isRecord17(value) || value.role !== "assistant")
53701
53850
  return null;
53702
53851
  return nonBlankString2(value.responseId) ? value.responseId : null;
53703
53852
  }
53704
53853
  function assistantReasoning(value) {
53705
- if (!isRecord16(value) || value.role !== "assistant" || !Array.isArray(value.content))
53854
+ if (!isRecord17(value) || value.role !== "assistant" || !Array.isArray(value.content))
53706
53855
  return null;
53707
- return value.content.filter((content) => isRecord16(content) && content.type === "thinking" && typeof content.thinking === "string").map((content) => content.thinking).join("");
53856
+ return value.content.filter((content) => isRecord17(content) && content.type === "thinking" && typeof content.thinking === "string").map((content) => content.thinking).join("");
53708
53857
  }
53709
53858
  function assistantFailure(value) {
53710
- if (!isRecord16(value) || value.role !== "assistant")
53859
+ if (!isRecord17(value) || value.role !== "assistant")
53711
53860
  return void 0;
53712
53861
  if (value.stopReason !== "error" && value.stopReason !== "aborted")
53713
53862
  return null;
@@ -53727,7 +53876,7 @@ function signalProcessTree2(child, signal) {
53727
53876
  try {
53728
53877
  process.kill(-child.pid, signal);
53729
53878
  } catch (error52) {
53730
- if (!isRecord16(error52) || error52.code !== "ESRCH")
53879
+ if (!isRecord17(error52) || error52.code !== "ESRCH")
53731
53880
  throw error52;
53732
53881
  }
53733
53882
  }
@@ -53758,7 +53907,7 @@ function piRpcProcessCommand(options, dependencies = {}) {
53758
53907
  const sessionArguments = options.forkSessionFile ? ["--fork", options.forkSessionFile] : options.sessionFile ? ["--session", options.sessionFile] : [];
53759
53908
  const modelArguments = options.model ? ["--provider", options.model.provider, "--model", options.model.id] : [];
53760
53909
  const arguments_2 = ["--mode", "rpc", ...modelArguments, ...sessionArguments];
53761
- const extension = path11.win32.extname(command).toLowerCase();
53910
+ const extension = path12.win32.extname(command).toLowerCase();
53762
53911
  if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
53763
53912
  return { command, arguments: arguments_2, windowsVerbatimArguments: false };
53764
53913
  }
@@ -53841,7 +53990,7 @@ var PiRpcSession = class {
53841
53990
  });
53842
53991
  child.stderr.resume();
53843
53992
  child.once("error", (error52) => {
53844
- const kind = isRecord16(error52) && error52.code === "ENOENT" ? "notInstalled" : "unavailable";
53993
+ const kind = isRecord17(error52) && error52.code === "ENOENT" ? "notInstalled" : "unavailable";
53845
53994
  this.#fail(new PiRpcFaultError(kind, `Pi RPC failed to start: ${error52.message}`));
53846
53995
  });
53847
53996
  child.once("exit", (code, signal) => {
@@ -54093,7 +54242,7 @@ var PiRpcSession = class {
54093
54242
  this.#buffer = this.#buffer.subarray(newline3 + 1);
54094
54243
  try {
54095
54244
  const value = JSON.parse(textDecoder.decode(frame));
54096
- if (!isRecord16(value) || typeof value.type !== "string") {
54245
+ if (!isRecord17(value) || typeof value.type !== "string") {
54097
54246
  throw new PiRpcFaultError("protocolError", "Pi RPC returned an invalid envelope");
54098
54247
  }
54099
54248
  this.#handle(value);
@@ -54132,7 +54281,7 @@ var PiRpcSession = class {
54132
54281
  }
54133
54282
  compactionTurn?.onEvent({
54134
54283
  type: "compaction.completed",
54135
- outcome: value.aborted === true ? "cancelled" : isRecord16(value.result) ? "succeeded" : "failed",
54284
+ outcome: value.aborted === true ? "cancelled" : isRecord17(value.result) ? "succeeded" : "failed",
54136
54285
  ...nonBlankString2(value.errorMessage) ? { errorMessage: value.errorMessage } : {}
54137
54286
  });
54138
54287
  return;
@@ -54152,7 +54301,7 @@ var PiRpcSession = class {
54152
54301
  this.#startAssistantMessage(active, value.message);
54153
54302
  return;
54154
54303
  }
54155
- if (value.type === "message_update" && isRecord16(value.assistantMessageEvent)) {
54304
+ if (value.type === "message_update" && isRecord17(value.assistantMessageEvent)) {
54156
54305
  const event = value.assistantMessageEvent;
54157
54306
  if (event.type === "text_delta" && typeof event.delta === "string") {
54158
54307
  const messageId = this.#ensureAssistantMessage(active, value.message);
@@ -54546,7 +54695,7 @@ var PiRpcSession = class {
54546
54695
  // packages/adapters/pi/dist/pi-adapter.js
54547
54696
  var piHarnessId2 = harnessIdSchema.parse("pi");
54548
54697
  var DEFAULT_TOOL_OUTPUT_LIMIT4 = 64e3;
54549
- function isRecord17(value) {
54698
+ function isRecord18(value) {
54550
54699
  return typeof value === "object" && value !== null && !Array.isArray(value);
54551
54700
  }
54552
54701
  function errorMessage(error52) {
@@ -54620,7 +54769,7 @@ function nativeModelForHistory(state) {
54620
54769
  return nativeModelFromState(state);
54621
54770
  }
54622
54771
  function sessionFileFromRef(ref) {
54623
- if (ref.harnessId !== piHarnessId2 || !isRecord17(ref.locator) || typeof ref.locator.sessionFile !== "string" || ref.locator.sessionFile.length === 0) {
54772
+ if (ref.harnessId !== piHarnessId2 || !isRecord18(ref.locator) || typeof ref.locator.sessionFile !== "string" || ref.locator.sessionFile.length === 0) {
54624
54773
  throw new Error("Pi Native Session Ref has no resumable Session file");
54625
54774
  }
54626
54775
  return ref.locator.sessionFile;
@@ -54635,9 +54784,9 @@ function toolFailure2(toolName) {
54635
54784
  function nativeText(value) {
54636
54785
  if (typeof value === "string")
54637
54786
  return value;
54638
- if (!isRecord17(value) || !Array.isArray(value.content))
54787
+ if (!isRecord18(value) || !Array.isArray(value.content))
54639
54788
  return "";
54640
- return value.content.filter((content) => isRecord17(content) && content.type === "text" && typeof content.text === "string").map(({ text }) => text).join("");
54789
+ return value.content.filter((content) => isRecord18(content) && content.type === "text" && typeof content.text === "string").map(({ text }) => text).join("");
54641
54790
  }
54642
54791
  function boundedOutput(value, limit) {
54643
54792
  const text = nativeText(value);
@@ -54653,19 +54802,19 @@ function outputText2(output) {
54653
54802
  return output?.content.filter((content) => content.type === "text").map(({ text }) => text).join("") ?? "";
54654
54803
  }
54655
54804
  function stringField2(value, key) {
54656
- return isRecord17(value) && typeof value[key] === "string" ? value[key] : void 0;
54805
+ return isRecord18(value) && typeof value[key] === "string" ? value[key] : void 0;
54657
54806
  }
54658
54807
  function numberField(value, key) {
54659
- if (!isRecord17(value))
54808
+ if (!isRecord18(value))
54660
54809
  return void 0;
54661
54810
  const field = value[key];
54662
54811
  return typeof field === "number" || field === null ? field : void 0;
54663
54812
  }
54664
- function stripDiffPrefix(path17) {
54665
- return path17.startsWith("a/") || path17.startsWith("b/") ? path17.slice(2) : path17;
54813
+ function stripDiffPrefix(path18) {
54814
+ return path18.startsWith("a/") || path18.startsWith("b/") ? path18.slice(2) : path18;
54666
54815
  }
54667
54816
  function reliableFileChange(result) {
54668
- if (!isRecord17(result) || !isRecord17(result.details) || typeof result.details.patch !== "string") {
54817
+ if (!isRecord18(result) || !isRecord18(result.details) || typeof result.details.patch !== "string") {
54669
54818
  return null;
54670
54819
  }
54671
54820
  const patch = result.details.patch;
@@ -54681,10 +54830,10 @@ function reliableFileChange(result) {
54681
54830
  const oldFile = file2.oldFileName;
54682
54831
  const newFile = file2.newFileName;
54683
54832
  const kind = oldFile === "/dev/null" ? "add" : newFile === "/dev/null" ? "delete" : "update";
54684
- const path17 = stripDiffPrefix(kind === "delete" ? oldFile : newFile);
54685
- if (!path17 || path17 === "/dev/null")
54833
+ const path18 = stripDiffPrefix(kind === "delete" ? oldFile : newFile);
54834
+ if (!path18 || path18 === "/dev/null")
54686
54835
  return null;
54687
- return [{ path: path17, kind, unifiedDiff: patch }];
54836
+ return [{ path: path18, kind, unifiedDiff: patch }];
54688
54837
  }
54689
54838
  function delay3(milliseconds) {
54690
54839
  return new Promise((resolve2) => setTimeout(resolve2, milliseconds));
@@ -55927,8 +56076,8 @@ import nodePath from "node:path";
55927
56076
  import { execFileSync } from "node:child_process";
55928
56077
  import { randomUUID as randomUUID6 } from "node:crypto";
55929
56078
  import { constants as constants3 } from "node:fs";
55930
- import { copyFile, mkdir, open as open2, readFile as readFile2, readdir, rename, rm as rm2, stat } from "node:fs/promises";
55931
- import path12 from "node:path";
56079
+ import { copyFile, mkdir, open as open2, readFile as readFile3, readdir, rename, rm as rm2, stat } from "node:fs/promises";
56080
+ import path13 from "node:path";
55932
56081
 
55933
56082
  // packages/mapping-store/dist/records.js
55934
56083
  var nonBlankTextSchema3 = external_exports.string().refine((value) => value.trim().length > 0, {
@@ -56133,11 +56282,11 @@ var MappingStore = class {
56133
56282
  #initialized = false;
56134
56283
  #lockHandle = null;
56135
56284
  constructor(options) {
56136
- this.#directory = path12.resolve(options.directory);
56137
- this.#threadsDirectory = path12.join(this.#directory, "threads");
56138
- this.#backupsDirectory = path12.join(this.#directory, "backups");
56139
- this.#quarantineDirectory = path12.join(this.#directory, "quarantine");
56140
- this.#lockPath = path12.join(this.#directory, "store.lock");
56285
+ this.#directory = path13.resolve(options.directory);
56286
+ this.#threadsDirectory = path13.join(this.#directory, "threads");
56287
+ this.#backupsDirectory = path13.join(this.#directory, "backups");
56288
+ this.#quarantineDirectory = path13.join(this.#directory, "quarantine");
56289
+ this.#lockPath = path13.join(this.#directory, "store.lock");
56141
56290
  this.#instanceId = options.instanceId ?? randomUUID6();
56142
56291
  this.#now = options.now ?? (() => /* @__PURE__ */ new Date());
56143
56292
  this.#beforeReplace = options.beforeReplace;
@@ -56155,8 +56304,8 @@ var MappingStore = class {
56155
56304
  await this.#cleanupTemps();
56156
56305
  const names = (await readdir(this.#threadsDirectory)).filter((name) => name.endsWith(".json"));
56157
56306
  for (const name of names) {
56158
- const primary = path12.join(this.#threadsDirectory, name);
56159
- const backup = path12.join(this.#backupsDirectory, name);
56307
+ const primary = path13.join(this.#threadsDirectory, name);
56308
+ const backup = path13.join(this.#backupsDirectory, name);
56160
56309
  let record3 = null;
56161
56310
  try {
56162
56311
  record3 = await this.#readRecord(primary, name);
@@ -56165,7 +56314,7 @@ var MappingStore = class {
56165
56314
  record3 = await this.#readRecord(backup, name);
56166
56315
  await this.#replaceFile(primary, record3, false);
56167
56316
  } catch (backupError) {
56168
- const quarantine = path12.join(this.#quarantineDirectory, `${name}.${this.#now().getTime()}.invalid`);
56317
+ const quarantine = path13.join(this.#quarantineDirectory, `${name}.${this.#now().getTime()}.invalid`);
56169
56318
  await rename(primary, quarantine).catch(() => void 0);
56170
56319
  void primaryError;
56171
56320
  void backupError;
@@ -56339,7 +56488,7 @@ var MappingStore = class {
56339
56488
  if (handle)
56340
56489
  await handle.close().catch(() => void 0);
56341
56490
  try {
56342
- const current = JSON.parse(await readFile2(this.#lockPath, "utf8"));
56491
+ const current = JSON.parse(await readFile3(this.#lockPath, "utf8"));
56343
56492
  if (current.instanceId === this.#instanceId)
56344
56493
  await rm2(this.#lockPath, { force: true });
56345
56494
  } catch {
@@ -56433,7 +56582,7 @@ var MappingStore = class {
56433
56582
  }
56434
56583
  }
56435
56584
  async #readRecord(file2, expectedName) {
56436
- const parsed = storedThreadRecordV1Schema.safeParse(JSON.parse(await readFile2(file2, "utf8")));
56585
+ const parsed = storedThreadRecordV1Schema.safeParse(JSON.parse(await readFile3(file2, "utf8")));
56437
56586
  if (!parsed.success) {
56438
56587
  throw new MappingStoreError("INVALID_RECORD", "Mapping Store record is invalid", {
56439
56588
  cause: parsed.error
@@ -56446,7 +56595,7 @@ var MappingStore = class {
56446
56595
  }
56447
56596
  async #cleanupTemps() {
56448
56597
  const names = await readdir(this.#threadsDirectory);
56449
- await Promise.all(names.filter((name) => name.includes(".tmp-")).map((name) => rm2(path12.join(this.#threadsDirectory, name), { force: true })));
56598
+ await Promise.all(names.filter((name) => name.includes(".tmp-")).map((name) => rm2(path13.join(this.#threadsDirectory, name), { force: true })));
56450
56599
  }
56451
56600
  async #acquireLock() {
56452
56601
  const attempt = async () => {
@@ -56472,7 +56621,7 @@ var MappingStore = class {
56472
56621
  }
56473
56622
  let existing = {};
56474
56623
  try {
56475
- existing = JSON.parse(await readFile2(this.#lockPath, "utf8"));
56624
+ existing = JSON.parse(await readFile3(this.#lockPath, "utf8"));
56476
56625
  } catch {
56477
56626
  }
56478
56627
  if (typeof existing.pid === "number" && lockOwnerIsLive(existing)) {
@@ -56539,10 +56688,10 @@ var MappingStore = class {
56539
56688
  }
56540
56689
  }
56541
56690
  #recordPath(hostThreadId) {
56542
- return path12.join(this.#threadsDirectory, `${hostThreadId}.json`);
56691
+ return path13.join(this.#threadsDirectory, `${hostThreadId}.json`);
56543
56692
  }
56544
56693
  #backupPath(hostThreadId) {
56545
- return path12.join(this.#backupsDirectory, `${hostThreadId}.json`);
56694
+ return path13.join(this.#backupsDirectory, `${hostThreadId}.json`);
56546
56695
  }
56547
56696
  #requireInitialized() {
56548
56697
  if (!this.#initialized) {
@@ -56561,7 +56710,7 @@ var packageMetadata5 = {
56561
56710
  var TITLE_MAX_LENGTH = 120;
56562
56711
  var DESCRIPTION_MAX_LENGTH = 500;
56563
56712
  var SERVER_NAME_MAX_LENGTH = 80;
56564
- function isRecord18(value) {
56713
+ function isRecord19(value) {
56565
56714
  return typeof value === "object" && value !== null && !Array.isArray(value);
56566
56715
  }
56567
56716
  function boundedText(value, field, maxLength) {
@@ -56605,7 +56754,7 @@ function responseError(message3) {
56605
56754
  function responsePersist(value) {
56606
56755
  if (value === void 0 || value === null)
56607
56756
  return null;
56608
- if (!isRecord18(value) || Object.keys(value).length !== 1 || value.persist !== "session" && value.persist !== "always") {
56757
+ if (!isRecord19(value) || Object.keys(value).length !== 1 || value.persist !== "session" && value.persist !== "always") {
56609
56758
  throw responseError("contains malformed persist metadata");
56610
56759
  }
56611
56760
  return value.persist;
@@ -56648,7 +56797,7 @@ function projectCodexApprovalRequest(input) {
56648
56797
  },
56649
56798
  denyResponse,
56650
56799
  parseResponse(result) {
56651
- if (!isRecord18(result) || typeof result.action !== "string") {
56800
+ if (!isRecord19(result) || typeof result.action !== "string") {
56652
56801
  throw responseError("missing action");
56653
56802
  }
56654
56803
  if (Object.keys(result).some((key) => key !== "action" && key !== "content" && key !== "_meta")) {
@@ -56656,7 +56805,7 @@ function projectCodexApprovalRequest(input) {
56656
56805
  }
56657
56806
  const selectedPersist = responsePersist(result._meta);
56658
56807
  if (result.action === "accept") {
56659
- if ("content" in result && (!isRecord18(result.content) || Object.keys(result.content).length !== 0)) {
56808
+ if ("content" in result && (!isRecord19(result.content) || Object.keys(result.content).length !== 0)) {
56660
56809
  throw responseError("contains non-empty accepted content");
56661
56810
  }
56662
56811
  if (selectedPersist === "session") {
@@ -56683,7 +56832,7 @@ function projectCodexApprovalRequest(input) {
56683
56832
  }
56684
56833
 
56685
56834
  // packages/protocol-core/dist/codex-question.js
56686
- function isRecord19(value) {
56835
+ function isRecord20(value) {
56687
56836
  return typeof value === "object" && value !== null && !Array.isArray(value);
56688
56837
  }
56689
56838
  function responseError2(message3) {
@@ -56752,7 +56901,7 @@ function projectCodexQuestionRequest(input) {
56752
56901
  }
56753
56902
  },
56754
56903
  parseResponse(result) {
56755
- if (!isRecord19(result) || !isRecord19(result.answers)) {
56904
+ if (!isRecord20(result) || !isRecord20(result.answers)) {
56756
56905
  throw responseError2("missing answers object");
56757
56906
  }
56758
56907
  const rawAnswers = result.answers;
@@ -56765,7 +56914,7 @@ function projectCodexQuestionRequest(input) {
56765
56914
  const question = interaction.questions.find(({ id: id2 }) => id2 === questionId);
56766
56915
  if (!question)
56767
56916
  throw responseError2("contains an unknown Question ID");
56768
- if (!isRecord19(answerValue) || !Array.isArray(answerValue.answers)) {
56917
+ if (!isRecord20(answerValue) || !Array.isArray(answerValue.answers)) {
56769
56918
  throw responseError2("answer entry has no answers array");
56770
56919
  }
56771
56920
  const values = answerValue.answers;
@@ -56911,8 +57060,8 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true) {
56911
57060
  return {
56912
57061
  id: item.itemId,
56913
57062
  type: "fileChange",
56914
- changes: item.changes.map(({ path: path17, kind, unifiedDiff }) => ({
56915
- path: path17,
57063
+ changes: item.changes.map(({ path: path18, kind, unifiedDiff }) => ({
57064
+ path: path18,
56916
57065
  kind,
56917
57066
  diff: unifiedDiff
56918
57067
  })),
@@ -57329,8 +57478,8 @@ var CodexTurnProjector = class {
57329
57478
  return messages;
57330
57479
  }
57331
57480
  #fileChangeUpdates(itemId3, changes) {
57332
- const projectedChanges = changes.map(({ path: path17, kind, unifiedDiff }) => ({
57333
- path: path17,
57481
+ const projectedChanges = changes.map(({ path: path18, kind, unifiedDiff }) => ({
57482
+ path: path18,
57334
57483
  kind,
57335
57484
  diff: unifiedDiff
57336
57485
  }));
@@ -57375,7 +57524,7 @@ var CodexTurnProjector = class {
57375
57524
  };
57376
57525
 
57377
57526
  // packages/protocol-core/dist/thread-fork.js
57378
- function isRecord20(value) {
57527
+ function isRecord21(value) {
57379
57528
  return typeof value === "object" && value !== null && !Array.isArray(value);
57380
57529
  }
57381
57530
  function optionalText(params, name, options = {}) {
@@ -57398,7 +57547,7 @@ function optionalBoolean(params, name) {
57398
57547
  function decodeThreadForkRequest(request) {
57399
57548
  if (request.method !== "thread/fork")
57400
57549
  return null;
57401
- if (!isRecord20(request.params))
57550
+ if (!isRecord21(request.params))
57402
57551
  throw new Error("thread/fork params must be an object");
57403
57552
  const params = request.params;
57404
57553
  const threadId2 = optionalText(params, "threadId");
@@ -57413,13 +57562,13 @@ function decodeThreadForkRequest(request) {
57413
57562
  if (runtimeWorkspaceRoots !== void 0 && runtimeWorkspaceRoots !== null && (!Array.isArray(runtimeWorkspaceRoots) || runtimeWorkspaceRoots.some((root) => typeof root !== "string" || root.length === 0))) {
57414
57563
  throw new Error("thread/fork params.runtimeWorkspaceRoots must be text paths or null");
57415
57564
  }
57416
- const path17 = optionalText(params, "path", { allowEmpty: true });
57565
+ const path18 = optionalText(params, "path", { allowEmpty: true });
57417
57566
  const ephemeral = optionalBoolean(params, "ephemeral");
57418
57567
  return {
57419
57568
  threadId: threadId2,
57420
57569
  ...lastTurnText ? { lastTurnId: hostTurnIdSchema.parse(lastTurnText) } : {},
57421
57570
  ...beforeTurnText ? { beforeTurnId: hostTurnIdSchema.parse(beforeTurnText) } : {},
57422
- ...path17 ? { path: path17 } : {},
57571
+ ...path18 ? { path: path18 } : {},
57423
57572
  ...optionalField(params, "model"),
57424
57573
  ...optionalField(params, "modelProvider"),
57425
57574
  ...optionalField(params, "cwd"),
@@ -57434,7 +57583,7 @@ function decodeThreadForkRequest(request) {
57434
57583
  function decodeThreadRollbackRequest(request) {
57435
57584
  if (request.method !== "thread/rollback")
57436
57585
  return null;
57437
- if (!isRecord20(request.params))
57586
+ if (!isRecord21(request.params))
57438
57587
  throw new Error("thread/rollback params must be an object");
57439
57588
  const { threadId: threadId2, numTurns } = request.params;
57440
57589
  if (typeof threadId2 !== "string" || threadId2.length === 0) {
@@ -57528,13 +57677,13 @@ var THREAD_SOURCE_KINDS = /* @__PURE__ */ new Set([
57528
57677
  "subAgentOther",
57529
57678
  "unknown"
57530
57679
  ]);
57531
- function isRecord21(value) {
57680
+ function isRecord22(value) {
57532
57681
  return typeof value === "object" && value !== null && !Array.isArray(value);
57533
57682
  }
57534
57683
  function paramsObject(request, method) {
57535
57684
  if (request.params === void 0 && method === "thread/list")
57536
57685
  return {};
57537
- if (!isRecord21(request.params))
57686
+ if (!isRecord22(request.params))
57538
57687
  throw new Error(`${method} params must be an object`);
57539
57688
  return request.params;
57540
57689
  }
@@ -57606,7 +57755,7 @@ function cursorPayload(value) {
57606
57755
  };
57607
57756
  }
57608
57757
  function parseCursorPayload(value) {
57609
- if (!isRecord21(value) || value.formatVersion !== 1)
57758
+ if (!isRecord22(value) || value.formatVersion !== 1)
57610
57759
  throw new Error("Host cursor is invalid");
57611
57760
  const { queryFingerprint: fingerprint, sortDirection: sortDirection2, officialCursor, officialDone } = value;
57612
57761
  const { externalAnchor: externalAnchor2, externalDone } = value;
@@ -57615,7 +57764,7 @@ function parseCursorPayload(value) {
57615
57764
  }
57616
57765
  let anchor = null;
57617
57766
  if (externalAnchor2 !== null) {
57618
- if (!isRecord21(externalAnchor2) || !Number.isSafeInteger(externalAnchor2.timestamp) || typeof externalAnchor2.threadId !== "string" || externalAnchor2.threadId.length === 0) {
57767
+ if (!isRecord22(externalAnchor2) || !Number.isSafeInteger(externalAnchor2.timestamp) || typeof externalAnchor2.threadId !== "string" || externalAnchor2.threadId.length === 0) {
57619
57768
  throw new Error("Host cursor is invalid");
57620
57769
  }
57621
57770
  anchor = {
@@ -57735,7 +57884,7 @@ function decodeThreadMetadataUpdateRequest(request) {
57735
57884
  if (params.gitInfo === null) {
57736
57885
  gitInfo = null;
57737
57886
  } else if (params.gitInfo !== void 0) {
57738
- if (!isRecord21(params.gitInfo)) {
57887
+ if (!isRecord22(params.gitInfo)) {
57739
57888
  throw new Error("thread/metadata/update params.gitInfo must be an object or null");
57740
57889
  }
57741
57890
  gitInfo = {};
@@ -57763,7 +57912,7 @@ function optionalCursor(value, name) {
57763
57912
  return value;
57764
57913
  }
57765
57914
  function decodeOfficialThreadListPage(value) {
57766
- if (!isRecord21(value) || !Array.isArray(value.data) || value.data.some((row) => !isRecord21(row))) {
57915
+ if (!isRecord22(value) || !Array.isArray(value.data) || value.data.some((row) => !isRecord22(row))) {
57767
57916
  throw new Error("Official thread/list response is invalid");
57768
57917
  }
57769
57918
  return {
@@ -58084,8 +58233,8 @@ var packageMetadata6 = {
58084
58233
 
58085
58234
  // packages/host-runtime/src/external-thread-repository.ts
58086
58235
  import { randomUUID as randomUUID7 } from "node:crypto";
58087
- import os5 from "node:os";
58088
- import path13 from "node:path";
58236
+ import os6 from "node:os";
58237
+ import path14 from "node:path";
58089
58238
  function nativeTurnKey2(ref) {
58090
58239
  return `${ref.harnessId}\0${ref.nativeSessionId}\0${ref.nativeTurnKey}\0${ref.formatVersion}`;
58091
58240
  }
@@ -58094,8 +58243,8 @@ function sameMapping(left, right) {
58094
58243
  }
58095
58244
  function defaultMappingStoreDirectory(environment) {
58096
58245
  const dataDirectory = environment.CODEXHOST_DATA_DIR;
58097
- return path13.join(
58098
- dataDirectory ? path13.resolve(dataDirectory) : path13.join(os5.homedir(), ".codexhost"),
58246
+ return path14.join(
58247
+ dataDirectory ? path14.resolve(dataDirectory) : path14.join(os6.homedir(), ".codexhost"),
58099
58248
  "mapping-store"
58100
58249
  );
58101
58250
  }
@@ -59180,7 +59329,7 @@ var ExternalThreadRuntime = class {
59180
59329
  import { randomUUID as randomUUID8 } from "node:crypto";
59181
59330
  var INTERNAL_REQUEST_PREFIX = "codexhost:official:";
59182
59331
  var MAX_RETIRED_IDS = 1024;
59183
- function isRecord22(value) {
59332
+ function isRecord23(value) {
59184
59333
  return typeof value === "object" && value !== null && !Array.isArray(value);
59185
59334
  }
59186
59335
  var OfficialRequestBroker = class {
@@ -59223,7 +59372,7 @@ var OfficialRequestBroker = class {
59223
59372
  });
59224
59373
  }
59225
59374
  handle(value) {
59226
- if (!isRecord22(value) || typeof value.id !== "string") return false;
59375
+ if (!isRecord23(value) || typeof value.id !== "string") return false;
59227
59376
  const pending = this.#pending.get(value.id);
59228
59377
  if (!pending) return this.#retired.has(value.id);
59229
59378
  clearTimeout(pending.timeout);
@@ -59252,11 +59401,11 @@ var OfficialRequestBroker = class {
59252
59401
  };
59253
59402
 
59254
59403
  // packages/host-runtime/src/route-observation.ts
59255
- function isRecord23(value) {
59404
+ function isRecord24(value) {
59256
59405
  return typeof value === "object" && value !== null && !Array.isArray(value);
59257
59406
  }
59258
59407
  function classifyThreadPurpose(request) {
59259
- return isRecord23(request.params) && request.params.ephemeral === true ? "ephemeral" : "conversation";
59408
+ return isRecord24(request.params) && request.params.ephemeral === true ? "ephemeral" : "conversation";
59260
59409
  }
59261
59410
  var RequestRouteObservationTracker = class {
59262
59411
  #nextCreateOrdinal = 0;
@@ -59281,13 +59430,13 @@ var RequestRouteObservationTracker = class {
59281
59430
  this.#createByThreadId.set(threadId2, tracked);
59282
59431
  }
59283
59432
  bindOfficialResponse(response) {
59284
- if (!isRecord23(response) || !("id" in response)) return;
59433
+ if (!isRecord24(response) || !("id" in response)) return;
59285
59434
  const tracked = this.#pendingByRequestId.get(response.id);
59286
59435
  if (!tracked) return;
59287
59436
  this.#pendingByRequestId.delete(response.id);
59288
59437
  const result = response.result;
59289
- const thread = isRecord23(result) ? result.thread : null;
59290
- if (isRecord23(thread) && typeof thread.id === "string") {
59438
+ const thread = isRecord24(result) ? result.thread : null;
59439
+ if (isRecord24(thread) && typeof thread.id === "string") {
59291
59440
  this.#createByThreadId.set(thread.id, tracked);
59292
59441
  }
59293
59442
  }
@@ -59384,25 +59533,25 @@ function resolveExternalSessionTreeIds(records) {
59384
59533
  const resolve2 = (start) => {
59385
59534
  const cached2 = resolved.get(start.hostThreadId);
59386
59535
  if (cached2) return cached2;
59387
- const path17 = [];
59536
+ const path18 = [];
59388
59537
  const visited = /* @__PURE__ */ new Set();
59389
59538
  let current = start;
59390
59539
  while (true) {
59391
59540
  const known = resolved.get(current.hostThreadId);
59392
59541
  if (known) {
59393
- for (const record3 of path17) resolved.set(record3.hostThreadId, known);
59542
+ for (const record3 of path18) resolved.set(record3.hostThreadId, known);
59394
59543
  return known;
59395
59544
  }
59396
59545
  if (visited.has(current.hostThreadId)) {
59397
59546
  throw new Error("External Thread Fork tree contains a cycle");
59398
59547
  }
59399
59548
  visited.add(current.hostThreadId);
59400
- path17.push(current);
59549
+ path18.push(current);
59401
59550
  const sourceId = current.forkSource?.hostThreadId;
59402
59551
  const source = sourceId ? byId.get(sourceId) : void 0;
59403
59552
  if (!source) {
59404
59553
  const root = current.hostThreadId;
59405
- for (const record3 of path17) resolved.set(record3.hostThreadId, root);
59554
+ for (const record3 of path18) resolved.set(record3.hostThreadId, root);
59406
59555
  return root;
59407
59556
  }
59408
59557
  current = source;
@@ -59453,11 +59602,11 @@ var OfficialThreadListError = class extends Error {
59453
59602
  }
59454
59603
  rpcError;
59455
59604
  };
59456
- function isRecord24(value) {
59605
+ function isRecord25(value) {
59457
59606
  return typeof value === "object" && value !== null && !Array.isArray(value);
59458
59607
  }
59459
59608
  function officialThreadListPageFromResponse(response) {
59460
- if (isRecord24(response.error)) {
59609
+ if (isRecord25(response.error)) {
59461
59610
  if (!Number.isSafeInteger(response.error.code) || typeof response.error.message !== "string") {
59462
59611
  throw new Error("Official thread/list error response is invalid");
59463
59612
  }
@@ -59617,9 +59766,19 @@ async function aggregateThreadList(input) {
59617
59766
  }
59618
59767
 
59619
59768
  // packages/host-runtime/src/app-server-host.ts
59620
- function isRecord25(value) {
59769
+ function isRecord26(value) {
59621
59770
  return typeof value === "object" && value !== null && !Array.isArray(value);
59622
59771
  }
59772
+ function isCreditsAdapter(adapter) {
59773
+ return typeof adapter.credits === "function" && typeof adapter.refreshCredits === "function";
59774
+ }
59775
+ function projectAccountCredits(value) {
59776
+ if (!isRecord26(value)) return null;
59777
+ const rest = { ...value };
59778
+ delete rest.fetchedAt;
59779
+ const parsed = accountCreditsSnapshotSchema.safeParse(rest);
59780
+ return parsed.success ? parsed.data : null;
59781
+ }
59623
59782
  function errorMessage3(error52) {
59624
59783
  return error52 instanceof Error ? error52.message : String(error52);
59625
59784
  }
@@ -59713,12 +59872,12 @@ function classifyCreateRequestRoute(request, defaultAgent2) {
59713
59872
  };
59714
59873
  }
59715
59874
  function requestObject(request) {
59716
- if (!isRecord25(request.params)) throw new Error(`${request.method} params must be an object`);
59875
+ if (!isRecord26(request.params)) throw new Error(`${request.method} params must be an object`);
59717
59876
  return request.params;
59718
59877
  }
59719
59878
  function requestText(params) {
59720
59879
  if (!Array.isArray(params.input)) throw new Error("turn/start input must be an array");
59721
- const text = params.input.filter((item) => isRecord25(item) && item.type === "text").map((item) => item.text).filter((value) => typeof value === "string").join("\n");
59880
+ const text = params.input.filter((item) => isRecord26(item) && item.type === "text").map((item) => item.text).filter((value) => typeof value === "string").join("\n");
59722
59881
  if (!text) throw new Error("turn/start must contain text input");
59723
59882
  return text;
59724
59883
  }
@@ -59872,11 +60031,11 @@ var AppServerHost = class {
59872
60031
  }
59873
60032
  const request = requestResult.data;
59874
60033
  if (request.method === "codexhost/update/check" || request.method === "codexhost/update/start" || request.method === "codexhost/update/status") {
59875
- await this.#handleUpdateRequest(request);
60034
+ this.#dispatchDesktopRequest(() => this.#handleUpdateRequest(request));
59876
60035
  continue;
59877
60036
  }
59878
60037
  if (request.method === "codexhost/harness/inspect") {
59879
- await this.#inspectHarness(request);
60038
+ this.#dispatchDesktopRequest(() => this.#inspectHarness(request));
59880
60039
  continue;
59881
60040
  }
59882
60041
  if (request.method === "codexhost/thread/fork") {
@@ -59921,7 +60080,7 @@ var AppServerHost = class {
59921
60080
  await writeFrame(official.stdin, frame);
59922
60081
  continue;
59923
60082
  }
59924
- await this.#listThreads(request, listRequest);
60083
+ this.#dispatchDesktopRequest(() => this.#listThreads(request, listRequest));
59925
60084
  continue;
59926
60085
  }
59927
60086
  if (request.method === "thread/archive" || request.method === "thread/unarchive") {
@@ -59992,7 +60151,7 @@ var AppServerHost = class {
59992
60151
  continue;
59993
60152
  }
59994
60153
  if (request.method === "thread/fork") {
59995
- const params = isRecord25(request.params) ? request.params : {};
60154
+ const params = isRecord26(request.params) ? request.params : {};
59996
60155
  const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
59997
60156
  if (resolution.kind === "error") {
59998
60157
  await this.#writer.json(
@@ -60015,7 +60174,7 @@ var AppServerHost = class {
60015
60174
  }
60016
60175
  }
60017
60176
  if (request.method === "thread/rollback") {
60018
- const params = isRecord25(request.params) ? request.params : {};
60177
+ const params = isRecord26(request.params) ? request.params : {};
60019
60178
  const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
60020
60179
  if (resolution.kind === "error") {
60021
60180
  await this.#writer.json(
@@ -60155,7 +60314,7 @@ var AppServerHost = class {
60155
60314
  continue;
60156
60315
  }
60157
60316
  }
60158
- if (request.method.startsWith("thread/") && !EXPLICIT_EXTERNAL_THREAD_METHODS.has(request.method) && isRecord25(request.params) && typeof request.params.threadId === "string") {
60317
+ if (request.method.startsWith("thread/") && !EXPLICIT_EXTERNAL_THREAD_METHODS.has(request.method) && isRecord26(request.params) && typeof request.params.threadId === "string") {
60159
60318
  const location = await this.#locateExternalThread(request.params.threadId);
60160
60319
  if (await this.#writeResolutionError(request, location)) continue;
60161
60320
  if (location.kind === "external") {
@@ -60276,7 +60435,6 @@ var AppServerHost = class {
60276
60435
  }
60277
60436
  const result = updateStartResultSchema.parse(await coordinator.start());
60278
60437
  await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
60279
- coordinator.requestShutdown();
60280
60438
  } catch (error52) {
60281
60439
  await this.#writer.json(rpcError(request, -32091, errorMessage3(error52).slice(0, 500)));
60282
60440
  }
@@ -60371,9 +60529,13 @@ var AppServerHost = class {
60371
60529
  );
60372
60530
  return;
60373
60531
  }
60532
+ const adapter = this.#externalAdapters.get(resolution.thread.harnessId);
60533
+ if (adapter && isCreditsAdapter(adapter)) void adapter.refreshCredits();
60534
+ const credits = adapter && isCreditsAdapter(adapter) ? projectAccountCredits(adapter.credits()) : null;
60374
60535
  const result = threadUsageInspectionSchema.parse({
60375
60536
  threadId: params.data.threadId,
60376
- usage: resolution.thread.latestUsage
60537
+ usage: resolution.thread.latestUsage,
60538
+ ...credits ? { accountCredits: credits } : {}
60377
60539
  });
60378
60540
  await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
60379
60541
  }
@@ -60975,10 +61137,10 @@ var AppServerHost = class {
60975
61137
  ...typeof params.serviceTier === "string" ? { serviceTier: params.serviceTier } : {}
60976
61138
  });
60977
61139
  try {
60978
- if (params.initialTurnsPage !== void 0 && params.initialTurnsPage !== null && !isRecord25(params.initialTurnsPage)) {
61140
+ if (params.initialTurnsPage !== void 0 && params.initialTurnsPage !== null && !isRecord26(params.initialTurnsPage)) {
60979
61141
  throw new ExternalHistoryRequestError("initialTurnsPage must be an object");
60980
61142
  }
60981
- const initialPageParams = isRecord25(params.initialTurnsPage) ? params.initialTurnsPage : null;
61143
+ const initialPageParams = isRecord26(params.initialTurnsPage) ? params.initialTurnsPage : null;
60982
61144
  const initialTurnsPage = initialPageParams ? listExternalTurns(turns, initialPageParams) : null;
60983
61145
  const paginated = thread.record.historyMode === "paginated";
60984
61146
  const turnsBackwardsCursor = paginated ? listExternalTurns(turns, { limit: 1, itemsView: "notLoaded" }).backwardsCursor : null;
@@ -61230,7 +61392,7 @@ var AppServerHost = class {
61230
61392
  }
61231
61393
  }
61232
61394
  async #handleDesktopApprovalResponse(value) {
61233
- if (!isRecord25(value) || !isHostApprovalRequestId(value.id)) return false;
61395
+ if (!isRecord26(value) || !isHostApprovalRequestId(value.id)) return false;
61234
61396
  const pending = this.#pendingDesktopApprovals.get(value.id);
61235
61397
  if (!pending) return true;
61236
61398
  this.#pendingDesktopApprovals.delete(value.id);
@@ -61352,7 +61514,7 @@ var AppServerHost = class {
61352
61514
  }
61353
61515
  }
61354
61516
  async #handleDesktopQuestionResponse(value) {
61355
- if (!isRecord25(value) || !isHostQuestionRequestId(value.id)) return false;
61517
+ if (!isRecord26(value) || !isHostQuestionRequestId(value.id)) return false;
61356
61518
  const pending = this.#pendingDesktopQuestions.get(value.id);
61357
61519
  if (!pending) return true;
61358
61520
  this.#pendingDesktopQuestions.delete(value.id);
@@ -61453,18 +61615,18 @@ var AppServerHost = class {
61453
61615
  }
61454
61616
  await this.#writer.json(projection);
61455
61617
  }
61618
+ #dispatchDesktopRequest(run) {
61619
+ void run().catch((error52) => this.#diagnose(error52));
61620
+ }
61456
61621
  #diagnose(error52) {
61457
61622
  this.#options.diagnosticOutput.write(`codexhost Host Runtime: ${errorMessage3(error52)}
61458
61623
  `);
61459
61624
  }
61460
61625
  };
61461
61626
 
61462
- // packages/host-runtime/src/update-coordinator.ts
61463
- import { createConnection } from "node:net";
61464
-
61465
61627
  // packages/update-manager/dist/distribution.js
61466
- import { lstat, readFile as readFile3 } from "node:fs/promises";
61467
- import path14 from "node:path";
61628
+ import { lstat, readFile as readFile4 } from "node:fs/promises";
61629
+ import path15 from "node:path";
61468
61630
 
61469
61631
  // packages/update-manager/dist/status.js
61470
61632
  var STATUS_SCHEMA_VERSION = 1;
@@ -61550,9 +61712,9 @@ function parseDistributionMetadata(value) {
61550
61712
  }
61551
61713
  function absoluteEnvironmentPath(environment, name) {
61552
61714
  const value = environment[name];
61553
- if (!value || !path14.isAbsolute(value))
61715
+ if (!value || !path15.isAbsolute(value))
61554
61716
  throw new Error(`${name} must be an absolute path`);
61555
- return path14.normalize(value);
61717
+ return path15.normalize(value);
61556
61718
  }
61557
61719
  function positiveEnvironmentInteger(environment, name) {
61558
61720
  const value = Number(environment[name]);
@@ -61574,39 +61736,39 @@ function expectedTarget(platform, architecture) {
61574
61736
  function defaultUpdateStateDirectory(platform = process.platform, environment = process.env) {
61575
61737
  if (platform === "win32") {
61576
61738
  const root = environment.LOCALAPPDATA;
61577
- if (!root || !path14.isAbsolute(root))
61739
+ if (!root || !path15.isAbsolute(root))
61578
61740
  throw new Error("LOCALAPPDATA is unavailable");
61579
- return path14.join(root, "codexhost", "updates");
61741
+ return path15.join(root, "codexhost", "updates");
61580
61742
  }
61581
61743
  const home = environment.HOME;
61582
- if (!home || !path14.isAbsolute(home))
61744
+ if (!home || !path15.isAbsolute(home))
61583
61745
  throw new Error("HOME is unavailable");
61584
- return platform === "darwin" ? path14.join(home, "Library", "Application Support", "codexhost", "updates") : path14.join(home, ".codexhost", "updates");
61746
+ return platform === "darwin" ? path15.join(home, "Library", "Application Support", "codexhost", "updates") : path15.join(home, ".codexhost", "updates");
61585
61747
  }
61586
61748
  async function resolveInstalledUpdateContext(options) {
61587
61749
  const environment = options.environment ?? process.env;
61588
61750
  const platform = options.platform ?? process.platform;
61589
61751
  const architecture = options.architecture ?? process.arch;
61590
- if (!path14.isAbsolute(options.hostRuntimePath)) {
61752
+ if (!path15.isAbsolute(options.hostRuntimePath)) {
61591
61753
  throw new Error("Host Runtime path must be absolute");
61592
61754
  }
61593
- const hostRuntimePath = path14.normalize(options.hostRuntimePath);
61755
+ const hostRuntimePath = path15.normalize(options.hostRuntimePath);
61594
61756
  const runtimeMetadata = await lstat(hostRuntimePath);
61595
61757
  if (!runtimeMetadata.isFile() || runtimeMetadata.isSymbolicLink()) {
61596
61758
  throw new Error("Host Runtime must be a regular file");
61597
61759
  }
61598
- const appDirectory = path14.dirname(hostRuntimePath);
61599
- const metadata = parseDistributionMetadata(JSON.parse(await readFile3(path14.join(appDirectory, "codexhost-distribution.json"), "utf8")));
61760
+ const appDirectory = path15.dirname(hostRuntimePath);
61761
+ const metadata = parseDistributionMetadata(JSON.parse(await readFile4(path15.join(appDirectory, "codexhost-distribution.json"), "utf8")));
61600
61762
  const target = expectedTarget(platform, architecture);
61601
61763
  if (metadata.target !== target) {
61602
61764
  throw new Error(`installed target ${metadata.target} does not match ${target}`);
61603
61765
  }
61604
61766
  const launcherPid = positiveEnvironmentInteger(environment, UPDATE_RUNTIME_ENV.launcherPid);
61605
61767
  const launcherExecutable = absoluteEnvironmentPath(environment, UPDATE_RUNTIME_ENV.launcherExecutable);
61606
- const stateDirectory = path14.normalize(options.stateDirectory ?? defaultUpdateStateDirectory(platform, environment));
61607
- const resourcesRoot = path14.dirname(appDirectory);
61608
- const installationRoot = platform === "darwin" ? path14.dirname(path14.dirname(resourcesRoot)) : resourcesRoot;
61609
- const updaterExecutable = path14.join(resourcesRoot, "libexec", platform === "win32" ? "codexhost-updater.exe" : "codexhost-updater");
61768
+ const stateDirectory = path15.normalize(options.stateDirectory ?? defaultUpdateStateDirectory(platform, environment));
61769
+ const resourcesRoot = path15.dirname(appDirectory);
61770
+ const installationRoot = platform === "darwin" ? path15.dirname(path15.dirname(resourcesRoot)) : resourcesRoot;
61771
+ const updaterExecutable = path15.join(resourcesRoot, "libexec", platform === "win32" ? "codexhost-updater.exe" : "codexhost-updater");
61610
61772
  const common = {
61611
61773
  version: metadata.version,
61612
61774
  launcherPid,
@@ -61629,7 +61791,7 @@ async function resolveInstalledUpdateContext(options) {
61629
61791
  npmLauncherPath: absoluteEnvironmentPath(environment, UPDATE_RUNTIME_ENV.npmLauncherPath),
61630
61792
  packageRoot: absoluteEnvironmentPath(environment, UPDATE_RUNTIME_ENV.npmPackageRoot)
61631
61793
  };
61632
- if (path14.normalize(npmOptions.packageRoot) !== resourcesRoot) {
61794
+ if (path15.normalize(npmOptions.packageRoot) !== resourcesRoot) {
61633
61795
  throw new Error("npm platform package root does not own the Host Runtime");
61634
61796
  }
61635
61797
  return { metadata, common, controller, installation: { kind: "npm", options: npmOptions } };
@@ -61791,8 +61953,8 @@ function selectInstallerReleaseArtifact(release, target) {
61791
61953
  }
61792
61954
 
61793
61955
  // packages/update-manager/dist/operation-state.js
61794
- import { lstat as lstat2, mkdir as mkdir2, open as open3, readFile as readFile4, readdir as readdir2, rm as rm3, writeFile } from "node:fs/promises";
61795
- import path15 from "node:path";
61956
+ import { lstat as lstat2, mkdir as mkdir2, open as open3, readFile as readFile5, readdir as readdir2, rm as rm3, writeFile } from "node:fs/promises";
61957
+ import path16 from "node:path";
61796
61958
  var LOCK_FILE = "active-update-v1.lock";
61797
61959
  var STATUS_FILE = "status-v1.json";
61798
61960
  var TERMINAL_PHASES = /* @__PURE__ */ new Set(["succeeded", "failed"]);
@@ -61807,12 +61969,12 @@ async function regularFile(filePath) {
61807
61969
  }
61808
61970
  }
61809
61971
  async function isUpdateOperationActive(stateDirectory) {
61810
- if (!path15.isAbsolute(stateDirectory))
61972
+ if (!path16.isAbsolute(stateDirectory))
61811
61973
  throw new Error("update state directory must be absolute");
61812
- return regularFile(path15.join(stateDirectory, LOCK_FILE));
61974
+ return regularFile(path16.join(stateDirectory, LOCK_FILE));
61813
61975
  }
61814
61976
  async function discoverLatestUpdateStatus(stateDirectory) {
61815
- if (!path15.isAbsolute(stateDirectory))
61977
+ if (!path16.isAbsolute(stateDirectory))
61816
61978
  throw new Error("update state directory must be absolute");
61817
61979
  let entries;
61818
61980
  try {
@@ -61826,13 +61988,13 @@ async function discoverLatestUpdateStatus(stateDirectory) {
61826
61988
  for (const entry of entries) {
61827
61989
  if (!entry.isDirectory() || entry.isSymbolicLink() || !entry.name.startsWith("update-"))
61828
61990
  continue;
61829
- const statusPath = path15.join(stateDirectory, entry.name, STATUS_FILE);
61991
+ const statusPath = path16.join(stateDirectory, entry.name, STATUS_FILE);
61830
61992
  if (!await regularFile(statusPath))
61831
61993
  continue;
61832
61994
  try {
61833
61995
  candidates2.push({
61834
61996
  statusPath,
61835
- status: parseUpdateStatus(JSON.parse(await readFile4(statusPath, "utf8")))
61997
+ status: parseUpdateStatus(JSON.parse(await readFile5(statusPath, "utf8")))
61836
61998
  });
61837
61999
  } catch {
61838
62000
  }
@@ -61854,10 +62016,10 @@ async function cleanupTerminalUpdateState(stateDirectory, options = {}) {
61854
62016
  for (const entry of entries) {
61855
62017
  if (!entry.isDirectory() || entry.isSymbolicLink() || !entry.name.startsWith("update-"))
61856
62018
  continue;
61857
- const directory = path15.join(stateDirectory, entry.name);
61858
- const statusPath = path15.join(directory, STATUS_FILE);
62019
+ const directory = path16.join(stateDirectory, entry.name);
62020
+ const statusPath = path16.join(directory, STATUS_FILE);
61859
62021
  try {
61860
- const status = parseUpdateStatus(JSON.parse(await readFile4(statusPath, "utf8")));
62022
+ const status = parseUpdateStatus(JSON.parse(await readFile5(statusPath, "utf8")));
61861
62023
  if (TERMINAL_PHASES.has(status.phase) && now - status.updatedAt > retentionSeconds) {
61862
62024
  await rm3(directory, { recursive: true, force: true });
61863
62025
  }
@@ -61866,10 +62028,10 @@ async function cleanupTerminalUpdateState(stateDirectory, options = {}) {
61866
62028
  }
61867
62029
  }
61868
62030
  async function acquireUpdateOperationLock(stateDirectory) {
61869
- if (!path15.isAbsolute(stateDirectory))
62031
+ if (!path16.isAbsolute(stateDirectory))
61870
62032
  throw new Error("update state directory must be absolute");
61871
62033
  await mkdir2(stateDirectory, { recursive: true, mode: 448 });
61872
- const lockPath = path15.join(stateDirectory, LOCK_FILE);
62034
+ const lockPath = path16.join(stateDirectory, LOCK_FILE);
61873
62035
  let handle;
61874
62036
  try {
61875
62037
  handle = await open3(lockPath, "wx", 384);
@@ -61888,9 +62050,9 @@ async function acquireUpdateOperationLock(stateDirectory) {
61888
62050
  async setStatusPath(statusPath) {
61889
62051
  if (released)
61890
62052
  throw new Error("update operation lock is released");
61891
- if (!path15.isAbsolute(statusPath))
62053
+ if (!path16.isAbsolute(statusPath))
61892
62054
  throw new Error("update status path must be absolute");
61893
- await writeFile(lockPath, `${JSON.stringify({ ownerPid: process.pid, statusPath: path15.normalize(statusPath) })}
62055
+ await writeFile(lockPath, `${JSON.stringify({ ownerPid: process.pid, statusPath: path16.normalize(statusPath) })}
61894
62056
  `, { encoding: "utf8", mode: 384 });
61895
62057
  },
61896
62058
  async release() {
@@ -61912,22 +62074,22 @@ function processIsAlive(processId) {
61912
62074
  }
61913
62075
  }
61914
62076
  async function recoverUpdateOperationLock(stateDirectory) {
61915
- const lockPath = path15.join(stateDirectory, LOCK_FILE);
62077
+ const lockPath = path16.join(stateDirectory, LOCK_FILE);
61916
62078
  if (!await regularFile(lockPath))
61917
62079
  return;
61918
62080
  let ownerPid;
61919
62081
  let statusPath;
61920
62082
  try {
61921
- const value = JSON.parse(await readFile4(lockPath, "utf8"));
62083
+ const value = JSON.parse(await readFile5(lockPath, "utf8"));
61922
62084
  ownerPid = value.ownerPid;
61923
62085
  statusPath = value.statusPath;
61924
62086
  } catch {
61925
62087
  return;
61926
62088
  }
61927
- if (typeof statusPath !== "string" || !path15.isAbsolute(statusPath))
62089
+ if (typeof statusPath !== "string" || !path16.isAbsolute(statusPath))
61928
62090
  return;
61929
62091
  try {
61930
- const status = parseUpdateStatus(JSON.parse(await readFile4(statusPath, "utf8")));
62092
+ const status = parseUpdateStatus(JSON.parse(await readFile5(statusPath, "utf8")));
61931
62093
  if (TERMINAL_PHASES.has(status.phase) || typeof ownerPid !== "number" || !processIsAlive(ownerPid)) {
61932
62094
  await rm3(lockPath, { force: true });
61933
62095
  }
@@ -61938,8 +62100,8 @@ async function recoverUpdateOperationLock(stateDirectory) {
61938
62100
  // packages/update-manager/dist/update-manager.js
61939
62101
  import { spawn as spawn6 } from "node:child_process";
61940
62102
  import { randomUUID as randomUUID10 } from "node:crypto";
61941
- import { chmod, copyFile as copyFile2, lstat as lstat4, mkdir as mkdir3, readFile as readFile5, rename as rename2, rm as rm4, writeFile as writeFile2 } from "node:fs/promises";
61942
- import path16 from "node:path";
62103
+ import { chmod, copyFile as copyFile2, lstat as lstat4, mkdir as mkdir3, readFile as readFile6, rename as rename2, rm as rm4, writeFile as writeFile2 } from "node:fs/promises";
62104
+ import path17 from "node:path";
61943
62105
 
61944
62106
  // packages/update-manager/dist/artifact.js
61945
62107
  import { createHash as createHash2 } from "node:crypto";
@@ -62036,9 +62198,9 @@ function errorMessage4(error52) {
62036
62198
  return error52 instanceof Error ? error52.message : String(error52);
62037
62199
  }
62038
62200
  function requireAbsolutePath(value, label) {
62039
- if (!path16.isAbsolute(value))
62201
+ if (!path17.isAbsolute(value))
62040
62202
  throw new Error(`${label} must be an absolute path`);
62041
- return path16.normalize(value);
62203
+ return path17.normalize(value);
62042
62204
  }
62043
62205
  async function requireRegularFile(value, label) {
62044
62206
  const filePath = requireAbsolutePath(value, label);
@@ -62081,7 +62243,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
62081
62243
  const now = dependencies.now ?? Date.now;
62082
62244
  const preparedRequests = /* @__PURE__ */ new Set();
62083
62245
  async function writeStatusSnapshot(statusPath, status) {
62084
- const temporaryPath = path16.join(path16.dirname(statusPath), `.update-status-${randomId()}.tmp`);
62246
+ const temporaryPath = path17.join(path17.dirname(statusPath), `.update-status-${randomId()}.tmp`);
62085
62247
  try {
62086
62248
  await writeFile2(temporaryPath, `${JSON.stringify(status)}
62087
62249
  `, {
@@ -62140,15 +62302,15 @@ function createBackgroundUpdateManager(dependencies = {}) {
62140
62302
  const updaterExecutable = await requireRegularFile(options.updaterExecutable, "Updater executable");
62141
62303
  const stateDirectory = requireAbsolutePath(options.stateDirectory, "update state directory");
62142
62304
  await mkdir3(stateDirectory, { recursive: true, mode: 448 });
62143
- const workDirectory = path16.join(stateDirectory, `update-${version2}-${randomId()}`);
62305
+ const workDirectory = path17.join(stateDirectory, `update-${version2}-${randomId()}`);
62144
62306
  await mkdir3(workDirectory, { recursive: false, mode: 448 });
62145
62307
  const executableSuffix = platform === "win32" ? ".exe" : "";
62146
- const helperPath = path16.join(workDirectory, `codexhost-updater${executableSuffix}`);
62308
+ const helperPath = path17.join(workDirectory, `codexhost-updater${executableSuffix}`);
62147
62309
  await copyFile2(updaterExecutable, helperPath);
62148
62310
  if (platform !== "win32")
62149
62311
  await chmod(helperPath, 448);
62150
- const requestPath = path16.join(workDirectory, "request-v1.json");
62151
- const statusPath = path16.join(workDirectory, "status-v1.json");
62312
+ const requestPath = path17.join(workDirectory, "request-v1.json");
62313
+ const statusPath = path17.join(workDirectory, "status-v1.json");
62152
62314
  await writePrivateJson(statusPath, preparedStatus(version2, installation, now()));
62153
62315
  await options.onPrepared?.({ version: version2, installation, statusPath });
62154
62316
  return {
@@ -62163,8 +62325,8 @@ function createBackgroundUpdateManager(dependencies = {}) {
62163
62325
  }
62164
62326
  async function prepareArtifact(common, installation, sourceValue, fileName) {
62165
62327
  const source = validateArtifact(sourceValue);
62166
- const temporaryPath = path16.join(common.workDirectory, `.${fileName}.download`);
62167
- const artifactPath = path16.join(common.workDirectory, fileName);
62328
+ const temporaryPath = path17.join(common.workDirectory, `.${fileName}.download`);
62329
+ const artifactPath = path17.join(common.workDirectory, fileName);
62168
62330
  const progress = progressReporter(common.statusPath, common.version, installation, source.size);
62169
62331
  try {
62170
62332
  const result = await download(source, temporaryPath, progress.update);
@@ -62237,7 +62399,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
62237
62399
  throw new Error("macOS DMG updates require macOS");
62238
62400
  const common = await prepareCommon(options, "macos-dmg");
62239
62401
  const appPath = requireAbsolutePath(options.appPath, "macOS application path");
62240
- if (path16.extname(appPath) !== ".app") {
62402
+ if (path17.extname(appPath) !== ".app") {
62241
62403
  throw new Error("macOS application path must end in .app");
62242
62404
  }
62243
62405
  const artifact = await prepareArtifact(common, "macos-dmg", options.artifact, "update.dmg");
@@ -62260,7 +62422,7 @@ function createBackgroundUpdateManager(dependencies = {}) {
62260
62422
  async readStatus(statusPathValue) {
62261
62423
  const statusPath = requireAbsolutePath(statusPathValue, "update status path");
62262
62424
  try {
62263
- return parseUpdateStatus(JSON.parse(await readFile5(statusPath, "utf8")));
62425
+ return parseUpdateStatus(JSON.parse(await readFile6(statusPath, "utf8")));
62264
62426
  } catch (error52) {
62265
62427
  if (error52.code === "ENOENT")
62266
62428
  return null;
@@ -62272,37 +62434,10 @@ function createBackgroundUpdateManager(dependencies = {}) {
62272
62434
 
62273
62435
  // packages/host-runtime/src/update-coordinator.ts
62274
62436
  var ERROR_MAX_LENGTH = 500;
62275
- var CONTROLLER_TIMEOUT_MS = 5e3;
62276
- var UPDATER_READY_TIMEOUT_MS = 1e4;
62277
- var UPDATER_READY_POLL_MS = 20;
62278
62437
  function boundedError(error52) {
62279
62438
  const message3 = error52 instanceof Error ? error52.message : String(error52);
62280
62439
  return message3.slice(0, ERROR_MAX_LENGTH) || "Update operation failed";
62281
62440
  }
62282
- function delay4(milliseconds) {
62283
- return new Promise((resolve2) => setTimeout(resolve2, milliseconds));
62284
- }
62285
- async function waitForUpdaterReady(manager, statusPath) {
62286
- const deadline = Date.now() + UPDATER_READY_TIMEOUT_MS;
62287
- while (Date.now() < deadline) {
62288
- const status = await manager.readStatus(statusPath);
62289
- switch (status?.phase) {
62290
- case "waiting-for-exit":
62291
- case "installing":
62292
- case "restarting":
62293
- case "succeeded":
62294
- return;
62295
- case "failed":
62296
- throw new Error(status.error ?? "Background Updater failed before Desktop shutdown");
62297
- case "prepared":
62298
- break;
62299
- default:
62300
- throw new Error("Background Updater reported an unexpected startup phase");
62301
- }
62302
- await delay4(UPDATER_READY_POLL_MS);
62303
- }
62304
- throw new Error("Background Updater did not become ready before Desktop shutdown");
62305
- }
62306
62441
  function publicStatus(status) {
62307
62442
  return {
62308
62443
  version: status.version,
@@ -62314,34 +62449,6 @@ function publicStatus(status) {
62314
62449
  error: status.error?.slice(0, ERROR_MAX_LENGTH) ?? null
62315
62450
  };
62316
62451
  }
62317
- function requestControllerShutdown(controller) {
62318
- return new Promise((resolve2, reject) => {
62319
- const socket = createConnection({ host: "127.0.0.1", port: controller.port });
62320
- let response = "";
62321
- const timeout = setTimeout(
62322
- () => socket.destroy(new Error("Controller shutdown timed out")),
62323
- CONTROLLER_TIMEOUT_MS
62324
- );
62325
- const settle = (operation) => {
62326
- clearTimeout(timeout);
62327
- operation();
62328
- };
62329
- socket.setEncoding("utf8");
62330
- socket.once("error", (error52) => settle(() => reject(error52)));
62331
- socket.on("data", (chunk) => {
62332
- response += chunk;
62333
- });
62334
- socket.once(
62335
- "end",
62336
- () => settle(() => {
62337
- if (response === "ready\n") resolve2();
62338
- else reject(new Error("Desktop Controller rejected the shutdown request"));
62339
- })
62340
- );
62341
- socket.once("connect", () => socket.write(`SHUTDOWN ${controller.nonce}
62342
- `));
62343
- });
62344
- }
62345
62452
  function createHostUpdateCoordinator(options) {
62346
62453
  const platform = options.platform ?? process.platform;
62347
62454
  const manager = options.manager ?? createBackgroundUpdateManager({ platform });
@@ -62352,16 +62459,7 @@ function createHostUpdateCoordinator(options) {
62352
62459
  ...options.architecture ? { architecture: options.architecture } : {}
62353
62460
  });
62354
62461
  const fetchLatest = options.fetchLatest ?? ((signal) => fetchLatestGitHubRelease({ signal: signal ?? AbortSignal.timeout(15e3) }));
62355
- const shutdown = options.shutdown ?? requestControllerShutdown;
62356
62462
  let candidate = null;
62357
- let shutdownPending = null;
62358
- let shutdownRequested = false;
62359
- const scheduleShutdown = () => {
62360
- if (!shutdownRequested || !shutdownPending) return;
62361
- const controller = shutdownPending;
62362
- shutdownPending = null;
62363
- setTimeout(() => void shutdown(controller).catch(() => void 0), 50).unref();
62364
- };
62365
62463
  async function latestStatus(context) {
62366
62464
  const discovered = await discoverLatestUpdateStatus(context.common.stateDirectory);
62367
62465
  if (!discovered) return null;
@@ -62488,9 +62586,6 @@ function createHostUpdateCoordinator(options) {
62488
62586
  });
62489
62587
  }
62490
62588
  if (platform !== "darwin") manager.start(prepared2);
62491
- await waitForUpdaterReady(manager, prepared2.statusPath);
62492
- shutdownPending = context.controller;
62493
- scheduleShutdown();
62494
62589
  } catch (error52) {
62495
62590
  await lock.release();
62496
62591
  rejectPrepared(error52);
@@ -62514,10 +62609,6 @@ function createHostUpdateCoordinator(options) {
62514
62609
  } catch {
62515
62610
  return { status: null };
62516
62611
  }
62517
- },
62518
- requestShutdown() {
62519
- shutdownRequested = true;
62520
- scheduleShutdown();
62521
62612
  }
62522
62613
  });
62523
62614
  }