@alan-ai-hq/agent-manager-linux-arm64 0.1.160 → 0.1.161

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/alan-agent.cjs +775 -270
  2. package/alan-holder.cjs +657 -181
  3. package/package.json +1 -1
package/alan-agent.cjs CHANGED
@@ -637,14 +637,14 @@ function codePointLength(str) {
637
637
  const units = str.length;
638
638
  if (!highSurrogate.test(str))
639
639
  return units;
640
- let count = units;
640
+ let count2 = units;
641
641
  for (let i = 0; i < units - 1; i++) {
642
642
  if ((str.charCodeAt(i) & 64512) === 55296 && (str.charCodeAt(i + 1) & 64512) === 56320) {
643
- count--;
643
+ count2--;
644
644
  i++;
645
645
  }
646
646
  }
647
- return count;
647
+ return count2;
648
648
  }
649
649
  function getLengthableOrigin(input2) {
650
650
  if (Array.isArray(input2))
@@ -5147,8 +5147,8 @@ var init_az = __esm({
5147
5147
  });
5148
5148
 
5149
5149
  // ../../node_modules/zod/v4/locales/be.js
5150
- function getBelarusianPlural(count, one, few, many) {
5151
- const absCount = Math.abs(count);
5150
+ function getBelarusianPlural(count2, one, few, many) {
5151
+ const absCount = Math.abs(count2);
5152
5152
  const lastDigit = absCount % 10;
5153
5153
  const lastTwoDigits = absCount % 100;
5154
5154
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
@@ -7942,8 +7942,8 @@ var init_hu = __esm({
7942
7942
  });
7943
7943
 
7944
7944
  // ../../node_modules/zod/v4/locales/hy.js
7945
- function getArmenianPlural(count, one, many) {
7946
- return Math.abs(count) === 1 ? one : many;
7945
+ function getArmenianPlural(count2, one, many) {
7946
+ return Math.abs(count2) === 1 ? one : many;
7947
7947
  }
7948
7948
  function withDefiniteArticle(word) {
7949
7949
  if (!word)
@@ -10841,8 +10841,8 @@ var init_ro = __esm({
10841
10841
  });
10842
10842
 
10843
10843
  // ../../node_modules/zod/v4/locales/ru.js
10844
- function getRussianPlural(count, one, few, many) {
10845
- const absCount = Math.abs(count);
10844
+ function getRussianPlural(count2, one, few, many) {
10845
+ const absCount = Math.abs(count2);
10846
10846
  const lastDigit = absCount % 10;
10847
10847
  const lastTwoDigits = absCount % 100;
10848
10848
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
@@ -25521,8 +25521,8 @@ function diffRows(patch) {
25521
25521
  return { kind: "meta", text: line };
25522
25522
  });
25523
25523
  }
25524
- function patchForPath(text3, path4, count) {
25525
- if (count === 1)
25524
+ function patchForPath(text3, path4, count2) {
25525
+ if (count2 === 1)
25526
25526
  return text3;
25527
25527
  const normalized2 = path4.replace(/^\/+/, "");
25528
25528
  return text3.split(/(?=^diff --git )/m).find((part) => {
@@ -26093,6 +26093,13 @@ function applyUpdate(state, update) {
26093
26093
  index.last = state.entries.at(-1);
26094
26094
  return state;
26095
26095
  }
26096
+ function usageContextTokens(meta3) {
26097
+ const usage = meta3?.["alan.dev/usage"];
26098
+ if (typeof usage !== "object" || usage === null || !("contextTokens" in usage))
26099
+ return void 0;
26100
+ const { contextTokens } = usage;
26101
+ return typeof contextTokens === "number" && Number.isFinite(contextTokens) && contextTokens > 0 ? contextTokens : void 0;
26102
+ }
26096
26103
  function awaitingToolCallIds(meta3) {
26097
26104
  const ids = meta3?.[AWAITING_TOOL_CALLS_META];
26098
26105
  return Array.isArray(ids) ? ids.filter((id) => typeof id === "string") : [];
@@ -26144,9 +26151,11 @@ function applyOne(state, index, update) {
26144
26151
  case "usage_update": {
26145
26152
  if (!isUpdate(update, "usage_update"))
26146
26153
  return;
26154
+ const contextTokens = usageContextTokens(update._meta);
26147
26155
  state.usage = {
26148
26156
  used: update.used,
26149
26157
  size: update.size,
26158
+ ...contextTokens === void 0 ? {} : { contextTokens },
26150
26159
  ...update.cost ? { cost: update.cost } : {}
26151
26160
  };
26152
26161
  delete state.thinkingTokens;
@@ -27047,7 +27056,7 @@ var init_acp = __esm({
27047
27056
  }
27048
27057
  });
27049
27058
 
27050
- // ../agent-core/dist/chunk-OUEMTEUX.js
27059
+ // ../agent-core/dist/chunk-RBQC7XZH.js
27051
27060
  function textBlock(text3) {
27052
27061
  return { type: "text", text: text3 };
27053
27062
  }
@@ -27182,8 +27191,8 @@ function readPatchHunks(value2) {
27182
27191
  return hunk ? [hunk] : [];
27183
27192
  });
27184
27193
  }
27185
- function hunkRange(start, count) {
27186
- return count === 1 ? String(start) : `${start},${count}`;
27194
+ function hunkRange(start, count2) {
27195
+ return count2 === 1 ? String(start) : `${start},${count2}`;
27187
27196
  }
27188
27197
  function hunkHeader(hunk) {
27189
27198
  return `@@ -${hunkRange(hunk.oldStart, hunk.oldLines)} +${hunkRange(hunk.newStart, hunk.newLines)} @@`;
@@ -27194,14 +27203,14 @@ function patchPath(path4) {
27194
27203
  function wholeFileHunk(content, deleted) {
27195
27204
  const lines2 = content === "" ? [] : content.split("\n");
27196
27205
  if (lines2.at(-1) === "") lines2.pop();
27197
- const count = lines2.length;
27206
+ const count2 = lines2.length;
27198
27207
  const marked = lines2.map((line) => `${deleted ? "-" : "+"}${line}`);
27199
27208
  if (content && !content.endsWith("\n")) marked.push("\");
27200
27209
  return {
27201
- oldStart: deleted && count ? 1 : 0,
27202
- oldLines: deleted ? count : 0,
27203
- newStart: !deleted && count ? 1 : 0,
27204
- newLines: deleted ? 0 : count,
27210
+ oldStart: deleted && count2 ? 1 : 0,
27211
+ oldLines: deleted ? count2 : 0,
27212
+ newStart: !deleted && count2 ? 1 : 0,
27213
+ newLines: deleted ? 0 : count2,
27205
27214
  lines: marked
27206
27215
  };
27207
27216
  }
@@ -27296,8 +27305,8 @@ function planEntries(todos) {
27296
27305
  });
27297
27306
  }
27298
27307
  var PROVIDER_PAYLOAD_META, TOOL_RESULT_ONLY_META, PARENT_TOOL_CALL_META, SUBAGENT_LAUNCHER_META, SUBAGENT_TASK_ID_META, SUBAGENT_OUTPUT_FILE_META, USAGE_META, TODOS_META, NOTICE_KIND_META, ASK_USER_QUESTIONS_META, USER_ANSWER_META, AWAITING_TOOL_CALLS_META2, EXIT_PLAN_MODE_INPUT_META, BACKGROUND_TASK_META, TASK_PROGRESS_META, RATE_LIMIT_META, MODEL_META, TOOLS_META, SLASH_COMMANDS_META, TOOL_KIND_RULES, ANSWER_PREFIX, ACCEPT_WORDS, MIN_INLINE_MEDIA_CHARS, DATA_URL_PREFIX, BASE64_BODY, PLAN_ENTRY_STATUSES;
27299
- var init_chunk_OUEMTEUX = __esm({
27300
- "../agent-core/dist/chunk-OUEMTEUX.js"() {
27308
+ var init_chunk_RBQC7XZH = __esm({
27309
+ "../agent-core/dist/chunk-RBQC7XZH.js"() {
27301
27310
  "use strict";
27302
27311
  init_chunk_YXWJW7I5();
27303
27312
  init_constants();
@@ -27353,12 +27362,12 @@ var init_chunk_OUEMTEUX = __esm({
27353
27362
  var init_acp2 = __esm({
27354
27363
  "../agent-core/dist/acp.js"() {
27355
27364
  "use strict";
27356
- init_chunk_OUEMTEUX();
27365
+ init_chunk_RBQC7XZH();
27357
27366
  init_chunk_YXWJW7I5();
27358
27367
  }
27359
27368
  });
27360
27369
 
27361
- // ../agent-core/dist/chunk-D4TIXPWZ.js
27370
+ // ../agent-core/dist/chunk-TFIO37PI.js
27362
27371
  function isRecordValue(value2) {
27363
27372
  return value2 !== null;
27364
27373
  }
@@ -27537,10 +27546,10 @@ function readTranscriptTurns(transcript, chunk, baseOffset, skipped = []) {
27537
27546
  return { turns, consumedBytes: consumedEnd - baseOffset };
27538
27547
  }
27539
27548
  var import_fs4, NEWLINE2, TranscriptCursor, TranscriptLineLookup, CONTENT_UPDATES;
27540
- var init_chunk_D4TIXPWZ = __esm({
27541
- "../agent-core/dist/chunk-D4TIXPWZ.js"() {
27549
+ var init_chunk_TFIO37PI = __esm({
27550
+ "../agent-core/dist/chunk-TFIO37PI.js"() {
27542
27551
  "use strict";
27543
- init_chunk_OUEMTEUX();
27552
+ init_chunk_RBQC7XZH();
27544
27553
  init_chunk_YXWJW7I5();
27545
27554
  import_fs4 = require("fs");
27546
27555
  NEWLINE2 = 10;
@@ -28097,7 +28106,7 @@ var init_chunk_ZCTKXKYY = __esm({
28097
28106
  }
28098
28107
  });
28099
28108
 
28100
- // ../agent-core/dist/chunk-WD7O4DYQ.js
28109
+ // ../agent-core/dist/chunk-N2M5D7RS.js
28101
28110
  function detectImageMimeType(buffer) {
28102
28111
  if (buffer.length >= 8 && buffer.subarray(0, 8).equals(PNG_SIGNATURE)) return "image/png";
28103
28112
  if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) {
@@ -28538,10 +28547,10 @@ function silentStartError(name, timeoutMs) {
28538
28547
  };
28539
28548
  }
28540
28549
  var import_crypto4, import_fs5, import_path4, PNG_SIGNATURE, IMAGE_MIME_BY_EXT, VIDEO_MIME_BY_EXT, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, MAX_TURN_MEDIA_DATA_CHARS, MTIME_SLACK_MS, AGENT_BROWSER_MENTION, AGENT_BROWSER_CAPTURE_COMMAND, LocalMediaReader, SessionOpenRefusal, JsonRpcError, ACP_PROTOCOL_VERSION, ACP_ERROR, STDERR_TAIL_LINES, RESULT_EXIT_GRACE_MS, PerTurnSession;
28541
- var init_chunk_WD7O4DYQ = __esm({
28542
- "../agent-core/dist/chunk-WD7O4DYQ.js"() {
28550
+ var init_chunk_N2M5D7RS = __esm({
28551
+ "../agent-core/dist/chunk-N2M5D7RS.js"() {
28543
28552
  "use strict";
28544
- init_chunk_OUEMTEUX();
28553
+ init_chunk_RBQC7XZH();
28545
28554
  init_chunk_ZCTKXKYY();
28546
28555
  init_chunk_6VWVDJ2A();
28547
28556
  init_chunk_YXWJW7I5();
@@ -30644,9 +30653,29 @@ function backgroundTaskProgress(event, tasks) {
30644
30653
  }
30645
30654
  ];
30646
30655
  }
30656
+ function claudeMessageContextTokens(message2) {
30657
+ if (asString(message2?.model) === "<synthetic>") return void 0;
30658
+ const usage = asRecord(message2?.usage);
30659
+ if (!usage) return void 0;
30660
+ const tokens2 = (asFiniteNumber(usage.input_tokens) ?? 0) + (asFiniteNumber(usage.cache_read_input_tokens) ?? 0) + (asFiniteNumber(usage.cache_creation_input_tokens) ?? 0) + (asFiniteNumber(usage.output_tokens) ?? 0);
30661
+ return tokens2 > 0 ? tokens2 : void 0;
30662
+ }
30663
+ function resultContextWindow(event, model) {
30664
+ const byModel = asRecord(event.modelUsage);
30665
+ if (!byModel) return void 0;
30666
+ const own2 = asFiniteNumber(asRecord(byModel[model])?.contextWindow);
30667
+ if (own2 !== void 0) return own2;
30668
+ let largest;
30669
+ for (const entry of Object.values(byModel)) {
30670
+ const size = asFiniteNumber(asRecord(entry)?.contextWindow);
30671
+ if (size !== void 0 && size > (largest ?? 0)) largest = size;
30672
+ }
30673
+ return largest;
30674
+ }
30647
30675
  function resultUsage(event, context) {
30648
30676
  const usage = asRecord(event.usage);
30649
30677
  const model = asString(event.model).trim() || context.activeModel?.trim() || context.selectedModel?.trim() || "claude";
30678
+ const contextSize = resultContextWindow(event, model);
30650
30679
  return usageUpdate({
30651
30680
  model,
30652
30681
  numTurns: asFiniteNumber(event.num_turns) ?? Math.max(context.iterations, 1),
@@ -30655,7 +30684,9 @@ function resultUsage(event, context) {
30655
30684
  outputTokens: asFiniteNumber(usage?.output_tokens) ?? 0,
30656
30685
  cacheReadTokens: asFiniteNumber(usage?.cache_read_input_tokens) ?? 0,
30657
30686
  cacheCreationTokens: asFiniteNumber(usage?.cache_creation_input_tokens) ?? 0,
30658
- costUsd: asFiniteNumber(event.total_cost_usd) ?? 0
30687
+ costUsd: asFiniteNumber(event.total_cost_usd) ?? 0,
30688
+ ...contextSize === void 0 ? {} : { contextSize },
30689
+ ...context.contextTokens === void 0 ? {} : { contextTokens: context.contextTokens }
30659
30690
  });
30660
30691
  }
30661
30692
  function resultErrorText(event, subtype) {
@@ -31073,7 +31104,8 @@ function scanTurn(records) {
31073
31104
  model: "",
31074
31105
  lastStopReason: "",
31075
31106
  interrupted: false,
31076
- durationMs: void 0
31107
+ durationMs: void 0,
31108
+ contextTokens: void 0
31077
31109
  };
31078
31110
  for (const record2 of records) {
31079
31111
  if (isInterruptMarker(record2)) scan.interrupted = true;
@@ -31086,19 +31118,22 @@ function scanTurn(records) {
31086
31118
  scan.model ||= recordModel;
31087
31119
  const id = asString(message2.id) || asString(record2.uuid);
31088
31120
  scan.usageByMessage.set(id, messageUsage(message2));
31121
+ if (isTopLevel(record2))
31122
+ scan.contextTokens = claudeMessageContextTokens(message2) ?? scan.contextTokens;
31089
31123
  scan.lastStopReason = asString(message2.stop_reason);
31090
31124
  }
31091
31125
  return scan;
31092
31126
  }
31093
31127
  function claudeTurnClosingUpdates(records, state) {
31094
- const { usageByMessage, model, lastStopReason, interrupted, durationMs } = scanTurn(records);
31128
+ const { usageByMessage, model, lastStopReason, interrupted, durationMs, contextTokens } = scanTurn(records);
31095
31129
  const updates = [];
31096
31130
  if (usageByMessage.size > 0) {
31097
31131
  const breakdown = {
31098
31132
  ...totalUsage(usageByMessage.values()),
31099
31133
  model,
31100
31134
  numTurns: usageByMessage.size,
31101
- ...durationMs ? { durationMs } : {}
31135
+ ...durationMs ? { durationMs } : {},
31136
+ ...contextTokens === void 0 ? {} : { contextTokens }
31102
31137
  };
31103
31138
  updates.push(usageUpdate(breakdown, state.model ?? ""));
31104
31139
  }
@@ -31113,9 +31148,9 @@ var import_crypto7, import_fs6, import_path6, import_crypto8, import_promises31,
31113
31148
  var init_claude = __esm({
31114
31149
  "../agent-core/dist/providers/claude.js"() {
31115
31150
  "use strict";
31116
- init_chunk_D4TIXPWZ();
31117
- init_chunk_WD7O4DYQ();
31118
- init_chunk_OUEMTEUX();
31151
+ init_chunk_TFIO37PI();
31152
+ init_chunk_N2M5D7RS();
31153
+ init_chunk_RBQC7XZH();
31119
31154
  init_chunk_ZCTKXKYY();
31120
31155
  init_chunk_6VWVDJ2A();
31121
31156
  init_chunk_DLVRNIY5();
@@ -31413,6 +31448,7 @@ var init_claude = __esm({
31413
31448
  #announced = /* @__PURE__ */ new Set();
31414
31449
  #awaitingAskDenialFallback = false;
31415
31450
  #iterations = 0;
31451
+ #contextTokens;
31416
31452
  #providerErrorCode;
31417
31453
  #deferredOnAnswer = false;
31418
31454
  #deferredOnBackground = false;
@@ -31552,6 +31588,7 @@ var init_claude = __esm({
31552
31588
  #handleSystem(event) {
31553
31589
  const subtype = asString(event.subtype);
31554
31590
  if (subtype === "api_retry") this.#noteRetry(event);
31591
+ if (subtype === "compact_boundary") this.#noteCompaction(event);
31555
31592
  if (subtype === "task_started") {
31556
31593
  this.tasks.registerRecord(event, parentToolUseId(event));
31557
31594
  this.taskRecords.track(event, this.tasks.resolveToolUseId(event));
@@ -31636,13 +31673,25 @@ var init_claude = __esm({
31636
31673
  status
31637
31674
  });
31638
31675
  }
31676
+ /** The window was just rewritten; the pre-compaction figure would overstate it until the next call. */
31677
+ #noteCompaction(event) {
31678
+ if (parentToolUseId(event)) return;
31679
+ const after = asFiniteNumber(asRecord(event.compact_metadata)?.post_tokens);
31680
+ this.#contextTokens = after !== void 0 && after > 0 ? after : void 0;
31681
+ }
31682
+ #noteContext(event, message2) {
31683
+ if (parentToolUseId(event)) return;
31684
+ this.#contextTokens = claudeMessageContextTokens(message2) ?? this.#contextTokens;
31685
+ }
31639
31686
  #handleAssistant(event) {
31640
31687
  if (this.#awaitingAskDenialFallback) {
31641
31688
  this.#awaitingAskDenialFallback = false;
31642
31689
  return;
31643
31690
  }
31644
31691
  this.#iterations += 1;
31645
- for (const raw of asArray(asRecord(event.message)?.content)) {
31692
+ const message2 = asRecord(event.message);
31693
+ this.#noteContext(event, message2);
31694
+ for (const raw of asArray(message2?.content)) {
31646
31695
  const block2 = asRecord(raw);
31647
31696
  if (!block2 || asString(block2.type) !== "tool_use") continue;
31648
31697
  const id = asString(block2.id);
@@ -31662,7 +31711,8 @@ var init_claude = __esm({
31662
31711
  resultUsage(event, {
31663
31712
  activeModel: this.grammar.model,
31664
31713
  selectedModel: this.#options.selectedModel,
31665
- iterations: this.#iterations
31714
+ iterations: this.#iterations,
31715
+ ...this.#contextTokens === void 0 ? {} : { contextTokens: this.#contextTokens }
31666
31716
  })
31667
31717
  ];
31668
31718
  if (typeof event.num_turns === "number") this.#iterations = event.num_turns;
@@ -32900,6 +32950,59 @@ function planEntries2(plan2) {
32900
32950
  ];
32901
32951
  });
32902
32952
  }
32953
+ function count(value2) {
32954
+ return asFiniteNumber(value2) ?? 0;
32955
+ }
32956
+ function withTotal(tokens2, reported) {
32957
+ return { ...tokens2, total: reported || tokens2.input + tokens2.output };
32958
+ }
32959
+ function appServerTokens(record2) {
32960
+ return withTotal(
32961
+ {
32962
+ input: count(record2.inputTokens),
32963
+ cachedInput: count(record2.cachedInputTokens),
32964
+ cacheWrite: count(record2.cacheWriteInputTokens),
32965
+ output: count(record2.outputTokens)
32966
+ },
32967
+ count(record2.totalTokens)
32968
+ );
32969
+ }
32970
+ function rolloutTokens(record2) {
32971
+ return withTotal(
32972
+ {
32973
+ input: count(record2.input_tokens),
32974
+ cachedInput: count(record2.cached_input_tokens),
32975
+ cacheWrite: count(record2.cache_write_input_tokens),
32976
+ output: count(record2.output_tokens)
32977
+ },
32978
+ count(record2.total_tokens)
32979
+ );
32980
+ }
32981
+ function subtractTokens(from, amount2) {
32982
+ const minus = (a, b) => Math.max(a - b, 0);
32983
+ return {
32984
+ input: minus(from.input, amount2.input),
32985
+ cachedInput: minus(from.cachedInput, amount2.cachedInput),
32986
+ cacheWrite: minus(from.cacheWrite, amount2.cacheWrite),
32987
+ output: minus(from.output, amount2.output),
32988
+ total: minus(from.total, amount2.total)
32989
+ };
32990
+ }
32991
+ function codexBreakdown(tokens2) {
32992
+ return {
32993
+ inputTokens: Math.max(tokens2.input - tokens2.cachedInput - tokens2.cacheWrite, 0),
32994
+ outputTokens: tokens2.output,
32995
+ cacheReadTokens: tokens2.cachedInput,
32996
+ cacheCreationTokens: tokens2.cacheWrite
32997
+ };
32998
+ }
32999
+ function codexUsageUpdate(spend, extra, fallbackModel) {
33000
+ const update = usageUpdate({ ...codexBreakdown(spend), ...extra }, fallbackModel);
33001
+ return spend.total > 0 && isUpdate(update, "usage_update") ? { ...update, used: spend.total } : update;
33002
+ }
33003
+ function codexContextTokens(last) {
33004
+ return last.total > 0 ? last.total : void 0;
33005
+ }
32903
33006
  function createCodexSessionMemory() {
32904
33007
  return { shownWarnings: /* @__PURE__ */ new Set(), workers: /* @__PURE__ */ new Map() };
32905
33008
  }
@@ -33285,6 +33388,7 @@ function createCodexRolloutState() {
33285
33388
  return {
33286
33389
  recordTime: 0,
33287
33390
  turnUsageSeen: false,
33391
+ turnTokens: new CodexTurnTokens(),
33288
33392
  shellCallIds: /* @__PURE__ */ new Set(),
33289
33393
  announcedCallIds: /* @__PURE__ */ new Set(),
33290
33394
  failedCallIds: /* @__PURE__ */ new Set(),
@@ -33707,31 +33811,29 @@ function compactionNotice2() {
33707
33811
  function num(value2) {
33708
33812
  return asFiniteNumber(value2) ?? 0;
33709
33813
  }
33710
- function tokenBreakdown(usage) {
33711
- return {
33712
- inputTokens: num(usage.input_tokens),
33713
- outputTokens: num(usage.output_tokens) + num(usage.reasoning_output_tokens),
33714
- cacheReadTokens: num(usage.cached_input_tokens),
33715
- cacheCreationTokens: num(usage.cache_write_input_tokens)
33716
- };
33717
- }
33718
- function reportedUsage(breakdown, totalTokens, state) {
33719
- const update = usageUpdate(breakdown, state.model ?? "");
33720
- return totalTokens && update.sessionUpdate === "usage_update" ? { ...update, used: totalTokens } : update;
33814
+ function reportedUsage(spend, state) {
33815
+ return codexUsageUpdate(spend, state.turnTokens.context, state.model ?? "");
33721
33816
  }
33722
33817
  function turnUsage(payload, state) {
33723
33818
  const turn = asRecord(payload.turn_token_usage);
33724
33819
  if (!turn) return [];
33725
33820
  state.turnUsageSeen = true;
33726
- return [reportedUsage(tokenBreakdown(turn), num(turn.total_tokens), state)];
33821
+ return [reportedUsage(rolloutTokens(turn), state)];
33727
33822
  }
33728
33823
  function tokenCount(payload, state) {
33729
- if (state.turnUsageSeen) return [];
33730
33824
  const info = asRecord(payload.info);
33731
- const total = asRecord(info?.total_token_usage);
33732
- if (!total) return [];
33733
- const breakdown = { ...tokenBreakdown(total), contextSize: num(info?.model_context_window) };
33734
- return [reportedUsage(breakdown, num(total.total_tokens), state)];
33825
+ const totalRecord = asRecord(info?.total_token_usage);
33826
+ if (!totalRecord) return [];
33827
+ const total = rolloutTokens(totalRecord);
33828
+ const lastRecord = asRecord(info?.last_token_usage);
33829
+ if (lastRecord)
33830
+ state.turnTokens.note(rolloutTokens(lastRecord), total, num(info?.model_context_window));
33831
+ if (state.turnUsageSeen) return [];
33832
+ return [reportedUsage(state.turnTokens.spend(total), state)];
33833
+ }
33834
+ function turnStarted(state) {
33835
+ state.turnTokens = new CodexTurnTokens();
33836
+ return [{ sessionUpdate: "state_update", state: "running" }];
33735
33837
  }
33736
33838
  function extensionItem(item, state) {
33737
33839
  switch (asString(item.kind)) {
@@ -33824,7 +33926,7 @@ function parseEventMsg(payload, state) {
33824
33926
  case "task_complete":
33825
33927
  return taskComplete(payload);
33826
33928
  case "task_started":
33827
- return [{ sessionUpdate: "state_update", state: "running" }];
33929
+ return turnStarted(state);
33828
33930
  case "turn_aborted":
33829
33931
  return [{ sessionUpdate: "state_update", state: "idle", stopReason: "cancelled" }];
33830
33932
  case "error":
@@ -33972,13 +34074,13 @@ function codexTurnInput(run2, context) {
33972
34074
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
33973
34075
  };
33974
34076
  }
33975
- var import_fs7, import_path7, import_crypto9, import_crypto10, import_crypto11, import_crypto12, TokenRefresher, MCP_STARTUP_TIMEOUT_SEC, FIELD_TYPES, YES_NO, ACCEPT_DECLINE, MAX_INLINE_GENERATED_IMAGE_BYTES, PNG_SIGNATURE2, JPEG_NON_FRAME_MARKERS, IMAGE_GEN_CALL, PROMPT_LITERAL, RELOCATE_EVERY_MS, CodexImageGenerationFold, CodexRolloutImages, CodexRateLimits, USER_INPUT_METHOD, PERMISSIONS_METHOD, ELICITATION_METHOD, COMMAND_OR_FILE, LEGACY, DECISIONS, COORDINATION_TOOLS, SETTLED_AGENT, STATUS, CHANGE_OPERATIONS, SILENT_ON_START, IGNORED_ITEMS, PLAN_STATUS, CODEX_MCP_STATUS, WORKER_LIFECYCLE, INFO_KINDS, SILENT, CodexTurn, STDERR_TAIL_LINES3, MAX_BETWEEN_UPDATES, UNSUPPORTED_REQUEST, DECLINED_ELICITATION, IMAGE_CATCH_UP_MS, IMAGE_POLL_MS, CodexSession, CODEX_MIN_VERSION, CODEX_REQUIREMENT, CODEX_TESTED_LINE, DEFAULTS2, CLIENT_INFO, STATUS2, EXITED_WITHOUT_RESPONSE, CodexExecTurn, DEFAULTS22, CodexExecSession, INJECTED_USER_PREFIXES, SHELL_TOOL_NAMES, ANNOUNCING_ITEM_TYPES, OUTPUT_MARKER, OPEN_PAGE_ACTIONS, FIND_IN_PAGE_ACTIONS, FILE_OPERATIONS, UNDERSTOOD_ITEM_TYPES, PRELUDE_TYPES2, PRELUDE_EVENTS, codexRolloutFile;
34077
+ var import_fs7, import_path7, import_crypto9, import_crypto10, import_crypto11, import_crypto12, TokenRefresher, MCP_STARTUP_TIMEOUT_SEC, FIELD_TYPES, YES_NO, ACCEPT_DECLINE, MAX_INLINE_GENERATED_IMAGE_BYTES, PNG_SIGNATURE2, JPEG_NON_FRAME_MARKERS, IMAGE_GEN_CALL, PROMPT_LITERAL, RELOCATE_EVERY_MS, CodexImageGenerationFold, CodexRolloutImages, CodexRateLimits, USER_INPUT_METHOD, PERMISSIONS_METHOD, ELICITATION_METHOD, COMMAND_OR_FILE, LEGACY, DECISIONS, COORDINATION_TOOLS, SETTLED_AGENT, STATUS, CHANGE_OPERATIONS, SILENT_ON_START, IGNORED_ITEMS, PLAN_STATUS, CodexTurnTokens, CODEX_MCP_STATUS, WORKER_LIFECYCLE, INFO_KINDS, SILENT, CodexTurn, STDERR_TAIL_LINES3, MAX_BETWEEN_UPDATES, UNSUPPORTED_REQUEST, DECLINED_ELICITATION, IMAGE_CATCH_UP_MS, IMAGE_POLL_MS, CodexSession, CODEX_MIN_VERSION, CODEX_REQUIREMENT, CODEX_TESTED_LINE, DEFAULTS2, CLIENT_INFO, STATUS2, EXITED_WITHOUT_RESPONSE, CodexExecTurn, DEFAULTS22, CodexExecSession, INJECTED_USER_PREFIXES, SHELL_TOOL_NAMES, ANNOUNCING_ITEM_TYPES, OUTPUT_MARKER, OPEN_PAGE_ACTIONS, FIND_IN_PAGE_ACTIONS, FILE_OPERATIONS, UNDERSTOOD_ITEM_TYPES, PRELUDE_TYPES2, PRELUDE_EVENTS, codexRolloutFile;
33976
34078
  var init_codex = __esm({
33977
34079
  "../agent-core/dist/providers/codex.js"() {
33978
34080
  "use strict";
33979
- init_chunk_D4TIXPWZ();
33980
- init_chunk_WD7O4DYQ();
33981
- init_chunk_OUEMTEUX();
34081
+ init_chunk_TFIO37PI();
34082
+ init_chunk_N2M5D7RS();
34083
+ init_chunk_RBQC7XZH();
33982
34084
  init_chunk_ZCTKXKYY();
33983
34085
  init_chunk_6VWVDJ2A();
33984
34086
  init_chunk_DLVRNIY5();
@@ -33990,6 +34092,7 @@ var init_codex = __esm({
33990
34092
  import_crypto9 = require("crypto");
33991
34093
  import_crypto10 = require("crypto");
33992
34094
  init_runtime_v2();
34095
+ init_acp();
33993
34096
  init_agent2();
33994
34097
  import_crypto11 = require("crypto");
33995
34098
  init_agent2();
@@ -34123,10 +34226,13 @@ var init_codex = __esm({
34123
34226
  #reported = /* @__PURE__ */ new Set();
34124
34227
  #cursor;
34125
34228
  #lastMiss;
34126
- constructor(locate2, clock) {
34229
+ #onTokenCount;
34230
+ /** `onTokenCount` also hears each `token_count` the rollout gains, for the turn's usage. */
34231
+ constructor(locate2, clock, onTokenCount) {
34127
34232
  this.#locate = locate2;
34128
34233
  this.#clock = clock;
34129
34234
  this.#fold = new CodexImageGenerationFold(clock);
34235
+ this.#onTokenCount = onTokenCount;
34130
34236
  }
34131
34237
  get waiting() {
34132
34238
  return this.#fold.waiting;
@@ -34147,7 +34253,10 @@ var init_codex = __esm({
34147
34253
  }
34148
34254
  /** What the rollout gained since the last drain. */
34149
34255
  drain() {
34150
- for (const line of this.#open()?.read() ?? []) this.#fold.foldLine(line.text);
34256
+ for (const line of this.#open()?.read() ?? []) {
34257
+ this.#fold.foldLine(line.text);
34258
+ if (this.#onTokenCount) this.#readTokenCount(line.text, this.#onTokenCount);
34259
+ }
34151
34260
  return this.admit(this.#fold.take());
34152
34261
  }
34153
34262
  /** The turn is over: what is left, then every call still pending as failed. */
@@ -34164,6 +34273,16 @@ var init_codex = __esm({
34164
34273
  }
34165
34274
  return updates;
34166
34275
  }
34276
+ #readTokenCount(text3, onTokenCount) {
34277
+ if (!text3.includes('"token_count"')) return;
34278
+ try {
34279
+ const payload = asRecord(asRecord(JSON.parse(text3))?.payload);
34280
+ const info = asRecord(payload?.info);
34281
+ if (asString(payload?.type) === "token_count" && info) onTokenCount(info);
34282
+ } catch {
34283
+ return;
34284
+ }
34285
+ }
34167
34286
  #open() {
34168
34287
  if (this.#cursor) return this.#cursor;
34169
34288
  const now = this.#clock.monotonic();
@@ -34265,6 +34384,31 @@ var init_codex = __esm({
34265
34384
  ["inProgress", "in_progress"],
34266
34385
  ["completed", "completed"]
34267
34386
  ]);
34387
+ CodexTurnTokens = class {
34388
+ #baseline;
34389
+ #last;
34390
+ #window;
34391
+ /** Records one report; `total` absent means `last` is the whole turn so far. */
34392
+ note(last, total, window2) {
34393
+ if (total) this.#baseline ??= subtractTokens(total, last);
34394
+ this.#last = last;
34395
+ if (window2 !== void 0 && window2 > 0) this.#window = window2;
34396
+ }
34397
+ get hasBaseline() {
34398
+ return this.#baseline !== void 0;
34399
+ }
34400
+ spend(total) {
34401
+ return this.#baseline ? subtractTokens(total, this.#baseline) : total;
34402
+ }
34403
+ /** The context the turn's last call left, and the window, as far as they are known. */
34404
+ get context() {
34405
+ const contextTokens = this.#last ? codexContextTokens(this.#last) : void 0;
34406
+ return {
34407
+ ...this.#window === void 0 ? {} : { contextSize: this.#window },
34408
+ ...contextTokens === void 0 ? {} : { contextTokens }
34409
+ };
34410
+ }
34411
+ };
34268
34412
  CODEX_MCP_STATUS = {
34269
34413
  starting: "starting",
34270
34414
  ready: "connected",
@@ -34311,6 +34455,7 @@ var init_codex = __esm({
34311
34455
  #end;
34312
34456
  #failFast;
34313
34457
  #lastError;
34458
+ #tokens = new CodexTurnTokens();
34314
34459
  codexTurnId;
34315
34460
  constructor(memory, clock = systemClock2) {
34316
34461
  this.#memory = memory;
@@ -34405,19 +34550,16 @@ var init_codex = __esm({
34405
34550
  }
34406
34551
  #usage(params) {
34407
34552
  const usage = asRecord(params.tokenUsage);
34408
- const last = asRecord(usage?.last);
34409
- if (!last) return [];
34410
- const number4 = (value2) => asFiniteNumber(value2) ?? 0;
34553
+ const lastRecord = asRecord(usage?.last);
34554
+ if (!lastRecord) return [];
34555
+ const last = appServerTokens(lastRecord);
34556
+ const totalRecord = asRecord(usage?.total);
34557
+ const total = totalRecord ? appServerTokens(totalRecord) : void 0;
34558
+ this.#tokens.note(last, total, asFiniteNumber(usage?.modelContextWindow));
34411
34559
  return [
34412
- usageUpdate(
34413
- {
34414
- inputTokens: number4(last.inputTokens),
34415
- outputTokens: number4(last.outputTokens) + number4(last.reasoningOutputTokens),
34416
- cacheReadTokens: number4(last.cachedInputTokens),
34417
- cacheCreationTokens: number4(last.cacheWriteInputTokens),
34418
- ...asFiniteNumber(usage?.modelContextWindow) === void 0 ? {} : { contextSize: number4(usage?.modelContextWindow) },
34419
- costUsd: 0
34420
- },
34560
+ codexUsageUpdate(
34561
+ total ? this.#tokens.spend(total) : last,
34562
+ { ...this.#tokens.context, costUsd: 0 },
34421
34563
  this.#memory.model ?? "codex"
34422
34564
  )
34423
34565
  ];
@@ -34958,12 +35100,16 @@ var init_codex = __esm({
34958
35100
  #lastError;
34959
35101
  #answered = false;
34960
35102
  #images;
35103
+ #tokens = new CodexTurnTokens();
35104
+ #resumed;
34961
35105
  constructor(resumeId, rollout) {
34962
35106
  this.#threadId = resumeId;
35107
+ this.#resumed = resumeId !== void 0;
34963
35108
  if (!rollout) return;
34964
35109
  this.#images = new CodexRolloutImages(
34965
35110
  () => this.#threadId ? findCodexRollout(rollout.codexHome, this.#threadId) : void 0,
34966
- rollout.clock
35111
+ rollout.clock,
35112
+ (info) => this.#noteTokenCount(info)
34967
35113
  );
34968
35114
  if (resumeId) this.#images.startAtEnd();
34969
35115
  }
@@ -35025,22 +35171,34 @@ var init_codex = __esm({
35025
35171
  if (mapped) return itemUpdates(mapped, completed);
35026
35172
  return [{ sessionUpdate: "_alan/unhandled", kind: `item/${type || "(untyped)"}` }];
35027
35173
  }
35174
+ /** The rollout's per-call counts: exec's own usage is only the thread's running total. */
35175
+ #noteTokenCount(info) {
35176
+ const last = asRecord(info.last_token_usage);
35177
+ const total = asRecord(info.total_token_usage);
35178
+ if (!last) return;
35179
+ this.#tokens.note(
35180
+ rolloutTokens(last),
35181
+ total ? rolloutTokens(total) : void 0,
35182
+ asFiniteNumber(info.model_context_window)
35183
+ );
35184
+ }
35028
35185
  #completed(usage) {
35029
35186
  this.#end = { status: "completed" };
35030
- const number4 = (value2) => asFiniteNumber(value2) ?? 0;
35187
+ const rolloutUpdates = this.#images?.drain() ?? [];
35031
35188
  return [
35032
- ...usage ? [
35033
- usageUpdate({
35034
- inputTokens: number4(usage.input_tokens),
35035
- outputTokens: number4(usage.output_tokens) + number4(usage.reasoning_output_tokens),
35036
- cacheReadTokens: number4(usage.cached_input_tokens),
35037
- cacheCreationTokens: number4(usage.cache_write_input_tokens),
35038
- costUsd: 0
35039
- })
35040
- ] : [],
35189
+ ...rolloutUpdates,
35190
+ ...usage ? this.#usage(rolloutTokens(usage)) : [],
35041
35191
  { sessionUpdate: "state_update", state: "idle", stopReason: "end_turn" }
35042
35192
  ];
35043
35193
  }
35194
+ /** A resumed turn with no rollout counts cannot separate its spend from earlier turns'. */
35195
+ #usage(threadTotal) {
35196
+ const context = { ...this.#tokens.context, costUsd: 0 };
35197
+ if (this.#resumed && !this.#tokens.hasBaseline) {
35198
+ return context.contextTokens === void 0 ? [] : [usageUpdate(context)];
35199
+ }
35200
+ return [codexUsageUpdate(this.#tokens.spend(threadTotal), context, "")];
35201
+ }
35044
35202
  #failed(error62, fallback) {
35045
35203
  const message2 = errorText(error62?.message) || errorText(error62?.detail) || fallback.trim();
35046
35204
  const classified = message2 ? classifyCliError(normalizeCodexCliErrorMessage(message2)) : this.#lastError ?? specForErrorKind("provider_error");
@@ -35175,6 +35333,14 @@ function resolveAlanCodeModelId(selectedModel, models) {
35175
35333
  if (requested && models.some((model) => model.id === requested)) return requested;
35176
35334
  return models.find((model) => model.isDefault)?.id ?? firstModel.id;
35177
35335
  }
35336
+ function disabledInheritedMcp(own2, inherited) {
35337
+ const disabled = {};
35338
+ for (const name of inherited ?? []) {
35339
+ if (name in own2) continue;
35340
+ disabled[name] = { enabled: false };
35341
+ }
35342
+ return disabled;
35343
+ }
35178
35344
  function parseExisting(existing) {
35179
35345
  if (!existing?.trim()) return {};
35180
35346
  try {
@@ -35202,6 +35368,8 @@ function alanCodeConfigContent(existing, input2) {
35202
35368
  const prompt = input2.prompt ?? ALAN_CODE_BASELINE_PROMPT;
35203
35369
  const hiddenSkills = { skill: { "customize-opencode": "deny" } };
35204
35370
  const plugins = Array.isArray(config2.plugin) ? config2.plugin : [];
35371
+ const ownMcp = field(config2, "mcp");
35372
+ const mcp = { ...ownMcp, ...disabledInheritedMcp(ownMcp, input2.inheritedMcpServers) };
35205
35373
  return JSON.stringify({
35206
35374
  $schema: "https://opencode.ai/config.json",
35207
35375
  ...config2,
@@ -35210,6 +35378,7 @@ function alanCodeConfigContent(existing, input2) {
35210
35378
  // 3.4 GB of a dev machine's engine database was these patches, against 82 sessions. Alan
35211
35379
  // does not use the engine's undo/revert, so the tracking stays off.
35212
35380
  snapshot: false,
35381
+ ...Object.keys(mcp).length ? { mcp } : {},
35213
35382
  model: `${ALAN_CODE_ENGINE_PROVIDER_ID}/${input2.modelId}`,
35214
35383
  enabled_providers: [ALAN_CODE_ENGINE_PROVIDER_ID],
35215
35384
  provider: {
@@ -35528,6 +35697,77 @@ function alanCodeEngineEnv(input2) {
35528
35697
  [ALAN_CODE_CONVERSATION_ID_ENV]: input2.conversationId
35529
35698
  };
35530
35699
  }
35700
+ function openCodeGlobalConfigDirectory(env, home) {
35701
+ const configHome = env.XDG_CONFIG_HOME?.trim() || (0, import_path9.join)(home, ".config");
35702
+ return (0, import_path9.join)(configHome, "opencode");
35703
+ }
35704
+ function stripJsonc(text3) {
35705
+ let out = "";
35706
+ let index = 0;
35707
+ while (index < text3.length) {
35708
+ const skipTo = commentEnd(text3, index);
35709
+ if (skipTo !== void 0) {
35710
+ index = skipTo;
35711
+ continue;
35712
+ }
35713
+ const char = text3[index];
35714
+ if (char === "}" || char === "]") out = out.replace(/,\s*$/, "");
35715
+ const end = char === '"' ? stringLiteralEnd(text3, index) : index + 1;
35716
+ out += text3.slice(index, end);
35717
+ index = end;
35718
+ }
35719
+ return out;
35720
+ }
35721
+ function commentEnd(text3, index) {
35722
+ const pair = text3.slice(index, index + 2);
35723
+ if (pair === "//") {
35724
+ const newline = text3.indexOf("\n", index);
35725
+ return newline === -1 ? text3.length : newline;
35726
+ }
35727
+ if (pair === "/*") {
35728
+ const close2 = text3.indexOf("*/", index + 2);
35729
+ return close2 === -1 ? text3.length : close2 + 2;
35730
+ }
35731
+ return void 0;
35732
+ }
35733
+ function stringLiteralEnd(text3, start) {
35734
+ let index = start + 1;
35735
+ while (index < text3.length) {
35736
+ const char = text3[index];
35737
+ if (char === "\\") {
35738
+ index += 2;
35739
+ } else if (char === '"') {
35740
+ return index + 1;
35741
+ } else {
35742
+ index += 1;
35743
+ }
35744
+ }
35745
+ return text3.length;
35746
+ }
35747
+ function parseJsonc(text3) {
35748
+ try {
35749
+ return JSON.parse(text3);
35750
+ } catch {
35751
+ try {
35752
+ return JSON.parse(stripJsonc(text3));
35753
+ } catch {
35754
+ return void 0;
35755
+ }
35756
+ }
35757
+ }
35758
+ async function inheritedMcpServerNames(configDirectory) {
35759
+ const names = /* @__PURE__ */ new Set();
35760
+ for (const file2 of ["config.json", "opencode.json", "opencode.jsonc"]) {
35761
+ const text3 = await (0, import_promises34.readFile)((0, import_path9.join)(configDirectory, file2), "utf8").catch(() => null);
35762
+ if (text3 === null) continue;
35763
+ const parsed = parseJsonc(text3);
35764
+ const mcp = parsed !== null && typeof parsed === "object" ? parsed.mcp : void 0;
35765
+ if (mcp !== null && typeof mcp === "object") {
35766
+ for (const name of Object.keys(mcp)) names.add(name);
35767
+ }
35768
+ }
35769
+ return [...names];
35770
+ }
35531
35771
  async function writePlugin(directory, apiOrigin) {
35532
35772
  const origin = (0, import_crypto13.createHash)("sha256").update(apiOrigin).digest("hex").slice(0, 12);
35533
35773
  const target = (0, import_path9.join)(directory, `engine-plugin-v${ALAN_CODE_ENGINE_PLUGIN_VERSION}-${origin}.mjs`);
@@ -35542,9 +35782,10 @@ async function prepareAlanCodeProfile(input2) {
35542
35782
  await Promise.all(
35543
35783
  directories.map((directory) => (0, import_promises34.mkdir)(directory, { recursive: true, mode: 448 }))
35544
35784
  );
35545
- const [pluginUrl, models] = await Promise.all([
35785
+ const [pluginUrl, models, inheritedMcpServers] = await Promise.all([
35546
35786
  writePlugin((0, import_path9.join)(input2.engineRoot, "plugin"), input2.access.apiOrigin),
35547
- (input2.loadModels ?? fetchAlanCodeModels)(input2.access)
35787
+ (input2.loadModels ?? fetchAlanCodeModels)(input2.access),
35788
+ input2.globalConfigDirectory === void 0 ? Promise.resolve([]) : inheritedMcpServerNames(input2.globalConfigDirectory)
35548
35789
  ]);
35549
35790
  const modelId = resolveAlanCodeModelId(input2.requestedModel, models);
35550
35791
  return {
@@ -35552,7 +35793,8 @@ async function prepareAlanCodeProfile(input2) {
35552
35793
  baseURL: `${input2.access.apiOrigin}${ALAN_CODE_PROXY_PATH}`,
35553
35794
  modelId,
35554
35795
  models,
35555
- pluginUrl
35796
+ pluginUrl,
35797
+ inheritedMcpServers
35556
35798
  }),
35557
35799
  model: { providerID: ALAN_CODE_ENGINE_PROVIDER_ID, modelID: modelId }
35558
35800
  };
@@ -36190,8 +36432,8 @@ var require_Node = __commonJS({
36190
36432
  };
36191
36433
  const res = toJS.toJS(this, "", ctx);
36192
36434
  if (typeof onAnchor === "function")
36193
- for (const { count, res: res2 } of ctx.anchors.values())
36194
- onAnchor(res2, count);
36435
+ for (const { count: count2, res: res2 } of ctx.anchors.values())
36436
+ onAnchor(res2, count2);
36195
36437
  return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res;
36196
36438
  }
36197
36439
  };
@@ -36297,13 +36539,13 @@ var require_Alias = __commonJS({
36297
36539
  const anchor2 = anchors2 && source && anchors2.get(source);
36298
36540
  return anchor2 ? anchor2.count * anchor2.aliasCount : 0;
36299
36541
  } else if (identity.isCollection(node2)) {
36300
- let count = 0;
36542
+ let count2 = 0;
36301
36543
  for (const item of node2.items) {
36302
36544
  const c = getAliasCount(doc, item, anchors2);
36303
- if (c > count)
36304
- count = c;
36545
+ if (c > count2)
36546
+ count2 = c;
36305
36547
  }
36306
- return count;
36548
+ return count2;
36307
36549
  } else if (identity.isPair(node2)) {
36308
36550
  const kc = getAliasCount(doc, node2.key, anchors2);
36309
36551
  const vc = getAliasCount(doc, node2.value, anchors2);
@@ -39256,8 +39498,8 @@ var require_Document = __commonJS({
39256
39498
  };
39257
39499
  const res = toJS.toJS(this.contents, jsonArg ?? "", ctx);
39258
39500
  if (typeof onAnchor === "function")
39259
- for (const { count, res: res2 } of ctx.anchors.values())
39260
- onAnchor(res2, count);
39501
+ for (const { count: count2, res: res2 } of ctx.anchors.values())
39502
+ onAnchor(res2, count2);
39261
39503
  return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res;
39262
39504
  }
39263
39505
  /**
@@ -39334,12 +39576,12 @@ var require_errors = __commonJS({
39334
39576
  lineStr = prev + lineStr;
39335
39577
  }
39336
39578
  if (/[^ ]/.test(lineStr)) {
39337
- let count = 1;
39579
+ let count2 = 1;
39338
39580
  const end = error62.linePos[1];
39339
39581
  if (end?.line === line && end.col > col) {
39340
- count = Math.max(1, Math.min(end.col - col, 80 - ci));
39582
+ count2 = Math.max(1, Math.min(end.col - col, 80 - ci));
39341
39583
  }
39342
- const pointer = " ".repeat(ci) + "^".repeat(count);
39584
+ const pointer = " ".repeat(ci) + "^".repeat(count2);
39343
39585
  error62.message += `:
39344
39586
 
39345
39587
  ${lineStr}
@@ -39581,7 +39823,7 @@ var require_resolve_block_map = __commonJS({
39581
39823
  if (ctx.atRoot)
39582
39824
  ctx.atRoot = false;
39583
39825
  let offset = bm.offset;
39584
- let commentEnd = null;
39826
+ let commentEnd2 = null;
39585
39827
  for (const collItem of bm.items) {
39586
39828
  const { start, key, sep: sep4, value: value2 } = collItem;
39587
39829
  const keyProps = resolveProps.resolveProps(start, {
@@ -39601,7 +39843,7 @@ var require_resolve_block_map = __commonJS({
39601
39843
  onError(offset, "BAD_INDENT", startColMsg);
39602
39844
  }
39603
39845
  if (!keyProps.anchor && !keyProps.tag && !sep4) {
39604
- commentEnd = keyProps.end;
39846
+ commentEnd2 = keyProps.end;
39605
39847
  if (keyProps.comment) {
39606
39848
  if (map2.comment)
39607
39849
  map2.comment += "\n" + keyProps.comment;
@@ -39663,9 +39905,9 @@ var require_resolve_block_map = __commonJS({
39663
39905
  map2.items.push(pair);
39664
39906
  }
39665
39907
  }
39666
- if (commentEnd && commentEnd < offset)
39667
- onError(commentEnd, "IMPOSSIBLE", "Map comment with trailing content");
39668
- map2.range = [bm.offset, offset, commentEnd ?? offset];
39908
+ if (commentEnd2 && commentEnd2 < offset)
39909
+ onError(commentEnd2, "IMPOSSIBLE", "Map comment with trailing content");
39910
+ map2.range = [bm.offset, offset, commentEnd2 ?? offset];
39669
39911
  return map2;
39670
39912
  }
39671
39913
  exports2.resolveBlockMap = resolveBlockMap;
@@ -39687,7 +39929,7 @@ var require_resolve_block_seq = __commonJS({
39687
39929
  if (ctx.atKey)
39688
39930
  ctx.atKey = false;
39689
39931
  let offset = bs.offset;
39690
- let commentEnd = null;
39932
+ let commentEnd2 = null;
39691
39933
  for (const { start, value: value2 } of bs.items) {
39692
39934
  const props = resolveProps.resolveProps(start, {
39693
39935
  indicator: "seq-item-ind",
@@ -39704,7 +39946,7 @@ var require_resolve_block_seq = __commonJS({
39704
39946
  else
39705
39947
  onError(offset, "MISSING_CHAR", "Sequence item without - indicator");
39706
39948
  } else {
39707
- commentEnd = props.end;
39949
+ commentEnd2 = props.end;
39708
39950
  if (props.comment)
39709
39951
  seq.comment = props.comment;
39710
39952
  continue;
@@ -39716,7 +39958,7 @@ var require_resolve_block_seq = __commonJS({
39716
39958
  offset = node2.range[2];
39717
39959
  seq.items.push(node2);
39718
39960
  }
39719
- seq.range = [bs.offset, offset, commentEnd ?? offset];
39961
+ seq.range = [bs.offset, offset, commentEnd2 ?? offset];
39720
39962
  return seq;
39721
39963
  }
39722
39964
  exports2.resolveBlockSeq = resolveBlockSeq;
@@ -45389,8 +45631,8 @@ var require_tar_stream = __commonJS({
45389
45631
  var init_dist = __esm({
45390
45632
  "../agent-core/dist/index.js"() {
45391
45633
  "use strict";
45392
- init_chunk_WD7O4DYQ();
45393
- init_chunk_OUEMTEUX();
45634
+ init_chunk_N2M5D7RS();
45635
+ init_chunk_RBQC7XZH();
45394
45636
  init_chunk_ZCTKXKYY();
45395
45637
  init_chunk_6VWVDJ2A();
45396
45638
  init_chunk_YXWJW7I5();
@@ -45749,24 +45991,30 @@ function tokens(record2, ...keys) {
45749
45991
  }
45750
45992
  return void 0;
45751
45993
  }
45752
- function promptUsage(result, fallbackModel) {
45753
- const usage = asRecord(result.usage) ?? asRecord(result._meta);
45994
+ function contextOf(update) {
45995
+ const used = asFiniteNumber(update.used);
45996
+ const size = asFiniteNumber(update.size);
45997
+ if (used === void 0 || used <= 0) return void 0;
45998
+ return { contextTokens: used, ...size !== void 0 && size > 0 ? { contextSize: size } : {} };
45999
+ }
46000
+ function promptSpend(result, profile) {
46001
+ const meta3 = asRecord(result._meta);
46002
+ const usage = asRecord(result.usage) ?? asRecord(meta3?.usage) ?? meta3;
45754
46003
  const input2 = tokens(usage, "inputTokens", "input_tokens");
45755
46004
  const output2 = tokens(usage, "outputTokens", "output_tokens");
45756
46005
  if (input2 === void 0 && output2 === void 0) return void 0;
45757
46006
  const thoughts = tokens(usage, "thoughtTokens", "reasoningTokens") ?? 0;
45758
- const meta3 = asRecord(result._meta);
45759
- return usageUpdate(
45760
- {
45761
- inputTokens: input2 ?? 0,
45762
- outputTokens: (output2 ?? 0) + thoughts,
45763
- cacheReadTokens: tokens(usage, "cachedReadTokens", "cacheReadTokens") ?? 0,
45764
- cacheCreationTokens: tokens(usage, "cachedWriteTokens", "cacheWriteTokens") ?? 0,
45765
- costUsd: 0,
45766
- ...asString(meta3?.modelId) ? { model: asString(meta3?.modelId) } : {}
45767
- },
45768
- fallbackModel
45769
- );
46007
+ const cacheRead = tokens(usage, "cachedReadTokens", "cacheReadTokens") ?? 0;
46008
+ const cacheWrite = tokens(usage, "cachedWriteTokens", "cacheWriteTokens") ?? 0;
46009
+ const uncached = profile.promptInputIncludesCache ? Math.max((input2 ?? 0) - cacheRead - cacheWrite, 0) : input2 ?? 0;
46010
+ return {
46011
+ inputTokens: uncached,
46012
+ outputTokens: (output2 ?? 0) + thoughts,
46013
+ cacheReadTokens: cacheRead,
46014
+ cacheCreationTokens: cacheWrite,
46015
+ costUsd: 0,
46016
+ ...asString(meta3?.modelId) ? { model: asString(meta3?.modelId) } : {}
46017
+ };
45770
46018
  }
45771
46019
  function pendingAnswer2(pending, answer) {
45772
46020
  switch (pending.kind) {
@@ -46136,8 +46384,8 @@ var import_promises50, import_path10, import_crypto14, import_promises51, CURSOR
46136
46384
  var init_acp3 = __esm({
46137
46385
  "../agent-core/dist/providers/acp.js"() {
46138
46386
  "use strict";
46139
- init_chunk_WD7O4DYQ();
46140
- init_chunk_OUEMTEUX();
46387
+ init_chunk_N2M5D7RS();
46388
+ init_chunk_RBQC7XZH();
46141
46389
  init_chunk_ZCTKXKYY();
46142
46390
  init_chunk_6VWVDJ2A();
46143
46391
  init_chunk_DLVRNIY5();
@@ -46367,9 +46615,52 @@ var init_acp3 = __esm({
46367
46615
  #bursts = /* @__PURE__ */ new Map();
46368
46616
  #counter = 0;
46369
46617
  #failure;
46370
- constructor(prefix, profile) {
46618
+ #context;
46619
+ #spend;
46620
+ #onContext;
46621
+ /** `context` is what the session's last turn left, until this turn reports its own. */
46622
+ constructor(prefix, profile, context) {
46371
46623
  this.#prefix = prefix;
46372
46624
  this.#profile = profile;
46625
+ this.#context = context;
46626
+ }
46627
+ get context() {
46628
+ return this.#context;
46629
+ }
46630
+ /** The prompt's answer: what the turn spent, with the context so far, as one update. */
46631
+ settle(result, fallbackModel) {
46632
+ this.#spend = promptSpend(result, this.#profile);
46633
+ return this.#usage(fallbackModel);
46634
+ }
46635
+ /** Resolves on the next `usage_update`, or after `ms`. */
46636
+ async nextContext(ms, sleep) {
46637
+ await Promise.race([
46638
+ new Promise((resolve13) => {
46639
+ this.#onContext = resolve13;
46640
+ }),
46641
+ sleep(ms)
46642
+ ]);
46643
+ this.#onContext = void 0;
46644
+ }
46645
+ /** Ends a `nextContext` wait at once: the turn is being cancelled. */
46646
+ stopWaiting() {
46647
+ this.#onContext?.();
46648
+ }
46649
+ /**
46650
+ * The chat keeps a turn's last usage update, so each one carries both the spend and the
46651
+ * context. An agent's own `usage_update` is context only and must not read as spend.
46652
+ */
46653
+ #noteContext(update) {
46654
+ const context = contextOf(update);
46655
+ if (!context) return [];
46656
+ this.#context = context;
46657
+ this.#onContext?.();
46658
+ const usage = this.#usage(this.#spend?.model ?? "");
46659
+ return usage ? [usage] : [];
46660
+ }
46661
+ #usage(fallbackModel) {
46662
+ if (!this.#spend && !this.#context) return void 0;
46663
+ return usageUpdate({ ...this.#spend, ...this.#context }, fallbackModel);
46373
46664
  }
46374
46665
  /** The first cause a vendor frame named; the prompt's own error is usually generic. */
46375
46666
  get failure() {
@@ -46399,6 +46690,8 @@ var init_acp3 = __esm({
46399
46690
  entries: Array.isArray(update.entries) ? update.entries : []
46400
46691
  }
46401
46692
  ];
46693
+ case "usage_update":
46694
+ return this.#noteContext(update);
46402
46695
  case "current_mode_update":
46403
46696
  return [
46404
46697
  noticeUpdate("info", "mode_changed", asString(update.currentModeId) || "mode changed")
@@ -46524,7 +46817,13 @@ var init_acp3 = __esm({
46524
46817
  return active.done;
46525
46818
  }
46526
46819
  const prompt = this.#promptBlocks(input2);
46527
- this.#rpc.request("session/prompt", { sessionId, prompt }).then((result) => active.finish(this.#promptOutcome(active, asRecord(result) ?? {}))).catch((error62) => {
46820
+ this.#rpc.request("session/prompt", { sessionId, prompt }).then(async (result) => {
46821
+ const record2 = asRecord(result) ?? {};
46822
+ const trailing = this.#profile.trailingUsageMs;
46823
+ if (trailing && !active.cancelRequested)
46824
+ await active.turn.nextContext(trailing, (ms) => this.#options.clock.sleep(ms));
46825
+ active.finish(this.#promptOutcome(active, record2));
46826
+ }).catch((error62) => {
46528
46827
  if (this.#state === "closed") return;
46529
46828
  active.finish(this.#errorOutcome(active, error62));
46530
46829
  });
@@ -46605,7 +46904,7 @@ var init_acp3 = __esm({
46605
46904
  ];
46606
46905
  }
46607
46906
  #promptOutcome(active, result) {
46608
- const usage = promptUsage(result, this.#config?.model ?? this.#profile.backendKind);
46907
+ const usage = active.turn.settle(result, this.#config?.model ?? this.#profile.backendKind);
46609
46908
  if (usage) this.#emit({ type: "update", turnId: active.id, update: usage });
46610
46909
  const stopReason = asString(result.stopReason);
46611
46910
  const failure22 = active.turn.failure;
@@ -46639,6 +46938,7 @@ var init_acp3 = __esm({
46639
46938
  async #stopTurn(active) {
46640
46939
  if (active.cancelRequested) return active.done.then(() => void 0);
46641
46940
  active.cancelRequested = true;
46941
+ active.turn.stopWaiting();
46642
46942
  const rung = await runCancelLadder({
46643
46943
  clock: this.#options.clock,
46644
46944
  graceMs: this.#options.interruptGraceMs,
@@ -46664,14 +46964,14 @@ var init_acp3 = __esm({
46664
46964
  }
46665
46965
  #startTurn(id) {
46666
46966
  this.#turns += 1;
46667
- const turn = new AcpTurn(`acp-${this.#turns}-${id}`, this.#profile);
46967
+ const turn = new AcpTurn(`acp-${this.#turns}-${id}`, this.#profile, this.#idleTurn.context);
46668
46968
  let finish = () => {
46669
46969
  };
46670
46970
  const done = new Promise((resolve13) => {
46671
46971
  finish = (outcome2) => {
46672
46972
  if (this.#current?.id !== id) return;
46673
46973
  this.#current = void 0;
46674
- this.#idleTurn = new AcpTurn(`acp-between-${this.#turns}`, this.#profile);
46974
+ this.#idleTurn = new AcpTurn(`acp-between-${this.#turns}`, this.#profile, turn.context);
46675
46975
  if (this.#state === "busy") this.#state = "idle";
46676
46976
  this.#host.scanDescendants(true);
46677
46977
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
@@ -46910,6 +47210,8 @@ var init_acp3 = __esm({
46910
47210
  }
46911
47211
  };
46912
47212
  grokAcpProfile = {
47213
+ // Grok's ACP `inputTokens` is the full prompt; its own docs say only headless output subtracts cache.
47214
+ promptInputIncludesCache: true,
46913
47215
  backendKind: "grok_cli",
46914
47216
  displayName: "Grok CLI",
46915
47217
  defaultCommand: "grok",
@@ -46940,7 +47242,9 @@ var init_acp3 = __esm({
46940
47242
  requirement: { cli: "kimi", feature: "`kimi acp`" },
46941
47243
  launchArgs: () => ["acp"],
46942
47244
  modelChannel: "session",
46943
- exitsOnStdinEof: true
47245
+ exitsOnStdinEof: true,
47246
+ // Kimi answers the prompt, then reads its context size and pushes `usage_update`.
47247
+ trailingUsageMs: 1e3
46944
47248
  };
46945
47249
  ACP_PROFILES = {
46946
47250
  cursor_agent_cli: cursorAcpProfile,
@@ -47777,8 +48081,22 @@ function codeModeChildUpdates(tool, metadata) {
47777
48081
  };
47778
48082
  });
47779
48083
  }
48084
+ function stepContextTokens(step, total) {
48085
+ const sum = step.inputTokens + step.outputTokens + step.cacheReadTokens + step.cacheCreationTokens;
48086
+ const tokens2 = total !== void 0 && total > 0 ? total : sum;
48087
+ return tokens2 > 0 ? tokens2 : void 0;
48088
+ }
48089
+ function addStepUsage(turn, step) {
48090
+ return {
48091
+ inputTokens: turn.inputTokens + step.inputTokens,
48092
+ outputTokens: turn.outputTokens + step.outputTokens,
48093
+ cacheReadTokens: turn.cacheReadTokens + step.cacheReadTokens,
48094
+ cacheCreationTokens: turn.cacheCreationTokens + step.cacheCreationTokens,
48095
+ costUsd: turn.costUsd === void 0 && step.costUsd === void 0 ? void 0 : (turn.costUsd ?? 0) + (step.costUsd ?? 0)
48096
+ };
48097
+ }
47780
48098
  function createOpenCodeSessionMemory() {
47781
- return { userMessageIds: /* @__PURE__ */ new Set() };
48099
+ return { userMessageIds: /* @__PURE__ */ new Set(), contextWindows: /* @__PURE__ */ new Map() };
47782
48100
  }
47783
48101
  function only(updates) {
47784
48102
  return { updates, actions: [] };
@@ -48111,12 +48429,12 @@ function openCodeTurnInput(run2, context) {
48111
48429
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
48112
48430
  };
48113
48431
  }
48114
- var import_crypto15, import_http10, import_crypto16, import_promises52, import_path11, import_path12, import_url2, import_crypto17, IDLE_SOCKET_MS3, OpenCodeHttpError, BASE62, messageIdClock, OpenCodeClient, OPENCODE_CONFIG_ENV, OPENCODE_ENGINE, TEXT_PARTS, STEP_PARTS, STOPPED_BY_USER, OpenCodeSubagents, NAMED_KINDS, OPENCODE_ABORTED_ERROR, PROVIDER_EVENT_META, TASK_TOOL_NAME, TASK_RESULT_TAG, TASK_ERROR_TAG, PERMISSION_DENIED, FILE_OPERATIONS2, PartReader, NOTHING, NON_INTERACTIVE_PERMISSIONS, CONTENT_FILTER_FINISHES, TRUNCATED_FINISHES, OUTPUT_PARTS, OpenCodeTurn, LISTENING, OUTPUT_TAIL_LINES, IMAGE_TYPES, OpenCodeSession, OPENCODE_MIN_VERSION, OPENCODE_REQUIREMENT, OPENCODE_TESTED_LINE, OPENCODE_SUPPORTED_MAJOR, DEFAULTS4, STORE_LOCKED, NON_INTERACTIVE_RULES, TITLE_LENGTH, MAX_VARIANT_LENGTH;
48432
+ var import_crypto15, import_http10, import_crypto16, import_promises52, import_path11, import_path12, import_url2, import_crypto17, IDLE_SOCKET_MS3, OpenCodeHttpError, BASE62, messageIdClock, OpenCodeClient, OPENCODE_CONFIG_ENV, OPENCODE_ENGINE, TEXT_PARTS, STEP_PARTS, STOPPED_BY_USER, OpenCodeSubagents, NAMED_KINDS, OPENCODE_ABORTED_ERROR, PROVIDER_EVENT_META, TASK_TOOL_NAME, TASK_RESULT_TAG, TASK_ERROR_TAG, PERMISSION_DENIED, FILE_OPERATIONS2, NO_USAGE, PartReader, NOTHING, NON_INTERACTIVE_PERMISSIONS, CONTENT_FILTER_FINISHES, TRUNCATED_FINISHES, OUTPUT_PARTS, OpenCodeTurn, LISTENING, OUTPUT_TAIL_LINES, IMAGE_TYPES, OpenCodeSession, OPENCODE_MIN_VERSION, OPENCODE_REQUIREMENT, OPENCODE_TESTED_LINE, OPENCODE_SUPPORTED_MAJOR, DEFAULTS4, STORE_LOCKED, NON_INTERACTIVE_RULES, TITLE_LENGTH, MAX_VARIANT_LENGTH;
48115
48433
  var init_opencode = __esm({
48116
48434
  "../agent-core/dist/providers/opencode.js"() {
48117
48435
  "use strict";
48118
- init_chunk_WD7O4DYQ();
48119
- init_chunk_OUEMTEUX();
48436
+ init_chunk_N2M5D7RS();
48437
+ init_chunk_RBQC7XZH();
48120
48438
  init_chunk_ZCTKXKYY();
48121
48439
  init_chunk_6VWVDJ2A();
48122
48440
  init_chunk_DLVRNIY5();
@@ -48298,6 +48616,22 @@ var init_opencode = __esm({
48298
48616
  const providers = Array.isArray(body?.providers) ? body.providers : [];
48299
48617
  return providers.map((provider4) => asString(asRecord(provider4)?.id)).filter(Boolean);
48300
48618
  }
48619
+ /** `provider/model` \u2192 the model's context limit; 0 (a custom model's unknown) is left out. */
48620
+ async modelContextWindows() {
48621
+ const body = asRecord(await this.#call("provider list", "GET", "/config/providers"));
48622
+ const windows = /* @__PURE__ */ new Map();
48623
+ for (const provider4 of Array.isArray(body?.providers) ? body.providers : []) {
48624
+ const record2 = asRecord(provider4);
48625
+ const providerId = asString(record2?.id);
48626
+ for (const [modelId, model] of Object.entries(asRecord(record2?.models) ?? {})) {
48627
+ const limit = asFiniteNumber(asRecord(asRecord(model)?.limit)?.context);
48628
+ if (providerId && limit !== void 0 && limit > 0) {
48629
+ windows.set(`${providerId}/${modelId}`, limit);
48630
+ }
48631
+ }
48632
+ }
48633
+ return windows;
48634
+ }
48301
48635
  /** Asks emitted while disconnected must still get a reply. Older engines may lack these routes. */
48302
48636
  async pendingAsks() {
48303
48637
  const read = async (path4, type) => {
@@ -48529,6 +48863,13 @@ var init_opencode = __esm({
48529
48863
  ["delete", "delete"],
48530
48864
  ["update", "modify"]
48531
48865
  ]);
48866
+ NO_USAGE = {
48867
+ inputTokens: 0,
48868
+ outputTokens: 0,
48869
+ cacheReadTokens: 0,
48870
+ cacheCreationTokens: 0,
48871
+ costUsd: void 0
48872
+ };
48532
48873
  PartReader = class {
48533
48874
  /** messageID \u2192 part ids in arrival order, so a multi-part message keeps its order. */
48534
48875
  #order = /* @__PURE__ */ new Map();
@@ -48538,6 +48879,7 @@ var init_opencode = __esm({
48538
48879
  /** To-do calls already sent as a plan; the running and completed frames repeat the input. */
48539
48880
  #planned = /* @__PURE__ */ new Set();
48540
48881
  #steps = /* @__PURE__ */ new Set();
48882
+ #turnUsage = NO_USAGE;
48541
48883
  #partIds = /* @__PURE__ */ new Set();
48542
48884
  #anonymous = 0;
48543
48885
  #retainedChars = 0;
@@ -48552,6 +48894,9 @@ var init_opencode = __esm({
48552
48894
  }
48553
48895
  /** `provider/model` from the assistant message; step-finish frames do not repeat it. */
48554
48896
  model;
48897
+ /** The model's context limit, when the server listed it. */
48898
+ contextWindow;
48899
+ #contextTokens;
48555
48900
  part(part, parentToolCallId) {
48556
48901
  const id = asString(part.id);
48557
48902
  if (id) this.#partIds.add(id);
@@ -48560,7 +48905,7 @@ var init_opencode = __esm({
48560
48905
  "protocol_violation",
48561
48906
  "Alan Code exceeded the retained event limit. Continue in a new turn."
48562
48907
  );
48563
- return withParent(this.#read(part), parentToolCallId);
48908
+ return withParent(this.#read(part, parentToolCallId !== void 0), parentToolCallId);
48564
48909
  }
48565
48910
  /** A delta names only its part; the role and message come from the part's opening snapshot. */
48566
48911
  delta(partId, field3, delta, parentToolCallId) {
@@ -48572,7 +48917,7 @@ var init_opencode = __esm({
48572
48917
  const update = role === "text" ? { sessionUpdate: "agent_message_chunk", messageId, content } : { sessionUpdate: "agent_thought_chunk", messageId: `${messageId}:reasoning`, content };
48573
48918
  return withParent([update], parentToolCallId);
48574
48919
  }
48575
- #read(part) {
48920
+ #read(part, child) {
48576
48921
  const type = asString(part.type);
48577
48922
  switch (type) {
48578
48923
  case "step-start":
@@ -48588,7 +48933,7 @@ var init_opencode = __esm({
48588
48933
  return this.#tool(part);
48589
48934
  case "step-finish":
48590
48935
  case "step_finish":
48591
- return this.#stepFinish(part);
48936
+ return this.#stepFinish(part, child);
48592
48937
  case "snapshot":
48593
48938
  case "patch":
48594
48939
  return [];
@@ -48654,6 +48999,31 @@ var init_opencode = __esm({
48654
48999
  }
48655
49000
  return updates;
48656
49001
  }
49002
+ #stepUsage(part, tokens2, child) {
49003
+ const cache2 = asRecord(tokens2.cache);
49004
+ const step = {
49005
+ inputTokens: asFiniteNumber(tokens2.input) ?? 0,
49006
+ // OpenCode counts reasoning apart from output, and cache apart from input.
49007
+ outputTokens: (asFiniteNumber(tokens2.output) ?? 0) + (asFiniteNumber(tokens2.reasoning) ?? 0),
49008
+ cacheReadTokens: asFiniteNumber(cache2?.read) ?? 0,
49009
+ cacheCreationTokens: asFiniteNumber(cache2?.write) ?? 0
49010
+ };
49011
+ if (!child) this.#contextTokens = stepContextTokens(step, asFiniteNumber(tokens2.total));
49012
+ this.#turnUsage = addStepUsage(this.#turnUsage, {
49013
+ ...step,
49014
+ costUsd: asFiniteNumber(part.cost)
49015
+ });
49016
+ const { costUsd, ...turnTokens } = this.#turnUsage;
49017
+ return usageUpdate(
49018
+ {
49019
+ ...turnTokens,
49020
+ ...costUsd === void 0 ? {} : { costUsd },
49021
+ ...this.#contextTokens === void 0 ? {} : { contextTokens: this.#contextTokens },
49022
+ ...this.contextWindow === void 0 ? {} : { contextSize: this.contextWindow }
49023
+ },
49024
+ this.model
49025
+ );
49026
+ }
48657
49027
  /** OpenCode's to-do list is the plan, sent once per call although every frame repeats it. */
48658
49028
  #plan(toolCallId, name, toolState) {
48659
49029
  const todos = asRecord(toolState?.input)?.todos;
@@ -48662,28 +49032,12 @@ var init_opencode = __esm({
48662
49032
  this.#planned.add(toolCallId);
48663
49033
  return [todoPlanUpdate(toolCallId, todos)];
48664
49034
  }
48665
- #stepFinish(part) {
49035
+ #stepFinish(part, child) {
48666
49036
  const id = asString(part.id);
48667
49037
  if (id && this.#steps.has(id)) return [];
48668
49038
  if (id) this.#steps.add(id);
48669
- const updates = [];
48670
49039
  const tokens2 = asRecord(part.tokens);
48671
- if (tokens2) {
48672
- const cache2 = asRecord(tokens2.cache);
48673
- const cost = asFiniteNumber(part.cost);
48674
- updates.push(
48675
- usageUpdate(
48676
- {
48677
- inputTokens: asFiniteNumber(tokens2.input) ?? 0,
48678
- outputTokens: asFiniteNumber(tokens2.output) ?? 0,
48679
- cacheReadTokens: asFiniteNumber(cache2?.read) ?? 0,
48680
- cacheCreationTokens: asFiniteNumber(cache2?.write) ?? 0,
48681
- ...cost === void 0 ? {} : { costUsd: cost }
48682
- },
48683
- this.model
48684
- )
48685
- );
48686
- }
49040
+ const updates = tokens2 ? [this.#stepUsage(part, tokens2, child)] : [];
48687
49041
  const reason = asString(part.reason);
48688
49042
  if (reason === "stop") {
48689
49043
  updates.push({ sessionUpdate: "state_update", state: "idle", stopReason: "end_turn" });
@@ -48868,7 +49222,10 @@ var init_opencode = __esm({
48868
49222
  if (finish) this.#finish = finish;
48869
49223
  const provider4 = asString(info.providerID);
48870
49224
  const model = asString(info.modelID);
48871
- if (provider4 && model) this.#parts.model = `${provider4}/${model}`;
49225
+ if (provider4 && model) {
49226
+ this.#parts.model = `${provider4}/${model}`;
49227
+ this.#parts.contextWindow = this.#memory.contextWindows.get(this.#parts.model);
49228
+ }
48872
49229
  const error62 = asRecord(info.error);
48873
49230
  if (!error62 || isAbortError(error62) || this.#error) return [];
48874
49231
  return this.#fail(classifyOpenCodeError(error62, `${this.#engine.label} session error.`));
@@ -49073,6 +49430,9 @@ var init_opencode = __esm({
49073
49430
  /** Subscribes before the session exists, so `session.created` and early asks are seen. */
49074
49431
  async connect(client) {
49075
49432
  this.#client = client;
49433
+ client.modelContextWindows().then((windows) => {
49434
+ this.#memory.contextWindows = windows;
49435
+ }).catch(() => void 0);
49076
49436
  this.#events?.close();
49077
49437
  this.#events = await client.events({
49078
49438
  onEvent: (event) => {
@@ -49481,7 +49841,9 @@ function createAlanCodeHolderDriver(options) {
49481
49841
  });
49482
49842
  const env = options.cliEnvironment;
49483
49843
  const engine = resolveAlanCodeEngine({ env, platform: platform3, packaged: [] });
49484
- const engineRoot = alanCodeEngineRoot(env.HOME?.trim() || (0, import_node_os7.homedir)());
49844
+ const home = env.HOME?.trim() || (0, import_node_os7.homedir)();
49845
+ const engineRoot = alanCodeEngineRoot(home);
49846
+ const globalConfigDirectory = openCodeGlobalConfigDirectory(env, home);
49485
49847
  options.log.info("alan_code.engine", { command: engine.command, source: engine.source });
49486
49848
  const open6 = async (planned) => {
49487
49849
  if (planned.profile === void 0) throw refuseWithoutCredential();
@@ -49519,6 +49881,7 @@ function createAlanCodeHolderDriver(options) {
49519
49881
  conversationId: spec.conversationId
49520
49882
  },
49521
49883
  engineRoot,
49884
+ globalConfigDirectory,
49522
49885
  requestedModel: spec.model
49523
49886
  };
49524
49887
  const skills = options.installedSkills?.() ?? null;
@@ -50166,8 +50529,8 @@ var import_crypto18, import_promises53, FACTORY_API_VERSION, FACTORY_PROTOCOL_VE
50166
50529
  var init_droid = __esm({
50167
50530
  "../agent-core/dist/providers/droid.js"() {
50168
50531
  "use strict";
50169
- init_chunk_WD7O4DYQ();
50170
- init_chunk_OUEMTEUX();
50532
+ init_chunk_N2M5D7RS();
50533
+ init_chunk_RBQC7XZH();
50171
50534
  init_chunk_ZCTKXKYY();
50172
50535
  init_chunk_6VWVDJ2A();
50173
50536
  init_chunk_DLVRNIY5();
@@ -50212,7 +50575,10 @@ var init_droid = __esm({
50212
50575
  const notification = asRecord(params.notification);
50213
50576
  if (!notification) return [];
50214
50577
  const sessionId = asString(params.sessionId);
50215
- if (!sessionId || sessionId === this.#sessionId) return this.#read(notification);
50578
+ if (!sessionId || sessionId === this.#sessionId) {
50579
+ this.#noteContext(notification);
50580
+ return this.#read(notification);
50581
+ }
50216
50582
  const launcher = this.#memory.childLaunchers.get(sessionId);
50217
50583
  if (!launcher) return [];
50218
50584
  return this.#read(notification).map(
@@ -50222,6 +50588,14 @@ var init_droid = __esm({
50222
50588
  })
50223
50589
  );
50224
50590
  }
50591
+ /** Droid's own context figure: the last call's input, cache reads and output. */
50592
+ #noteContext(notification) {
50593
+ if (asString(notification.type) !== "session_token_usage_changed") return;
50594
+ const last = asRecord(notification.lastCallTokenUsage);
50595
+ if (!last) return;
50596
+ const tokens2 = (asFiniteNumber(last.inputTokens) ?? 0) + (asFiniteNumber(last.cacheReadTokens) ?? 0) + (asFiniteNumber(last.outputTokens) ?? 0);
50597
+ if (tokens2 > 0) this.#memory.contextTokens = tokens2;
50598
+ }
50225
50599
  #read(notification) {
50226
50600
  const type = asString(notification.type);
50227
50601
  if (SILENT2.has(type)) return [];
@@ -50296,6 +50670,7 @@ var init_droid = __esm({
50296
50670
  cacheCreationTokens: number4(usage?.cacheCreationTokens),
50297
50671
  numTurns: 1,
50298
50672
  ...duration3 === void 0 ? {} : { durationMs: duration3 },
50673
+ ...this.#memory.contextTokens === void 0 ? {} : { contextTokens: this.#memory.contextTokens },
50299
50674
  costUsd: 0
50300
50675
  },
50301
50676
  this.#memory.model ?? "droid"
@@ -51104,6 +51479,23 @@ function providerError2(_grammar, frame) {
51104
51479
  function spellings(types, handle) {
51105
51480
  return types.map((type) => [type, handle]);
51106
51481
  }
51482
+ function stepTokens(stats) {
51483
+ return {
51484
+ inputTokens: firstNumber2(stats.input_tokens, stats.input),
51485
+ outputTokens: firstNumber2(stats.output_tokens) + firstNumber2(stats.thinking_tokens),
51486
+ cacheReadTokens: firstNumber2(stats.cache_read_tokens, stats.cached_input_tokens, stats.cached),
51487
+ cacheCreationTokens: 0
51488
+ };
51489
+ }
51490
+ function addStepTokens(total, step) {
51491
+ if (!total) return step;
51492
+ return {
51493
+ inputTokens: total.inputTokens + step.inputTokens,
51494
+ outputTokens: total.outputTokens + step.outputTokens,
51495
+ cacheReadTokens: total.cacheReadTokens + step.cacheReadTokens,
51496
+ cacheCreationTokens: total.cacheCreationTokens + step.cacheCreationTokens
51497
+ };
51498
+ }
51107
51499
  function firstNumber2(...values) {
51108
51500
  for (const value2 of values) {
51109
51501
  const number4 = asFiniteNumber(value2);
@@ -51275,9 +51667,9 @@ var import_promises54, import_path13, import_fs9, import_path14, import_path15,
51275
51667
  var init_antigravity = __esm({
51276
51668
  "../agent-core/dist/providers/antigravity.js"() {
51277
51669
  "use strict";
51278
- init_chunk_D4TIXPWZ();
51279
- init_chunk_WD7O4DYQ();
51280
- init_chunk_OUEMTEUX();
51670
+ init_chunk_TFIO37PI();
51671
+ init_chunk_N2M5D7RS();
51672
+ init_chunk_RBQC7XZH();
51281
51673
  init_chunk_ZCTKXKYY();
51282
51674
  init_chunk_6VWVDJ2A();
51283
51675
  init_chunk_DLVRNIY5();
@@ -51635,6 +52027,11 @@ var init_antigravity = __esm({
51635
52027
  /** What `--conversation` takes: a frame's `conversation_id` wins over its `session_id`. */
51636
52028
  #conversationId;
51637
52029
  #forkReported = false;
52030
+ /** The conversation this turn runs in; a subagent's steps come under another id. */
52031
+ #rootConversation;
52032
+ /** The sum of this turn's own steps: the result's usage is the whole conversation's. */
52033
+ #stepSpend;
52034
+ #contextTokens;
51638
52035
  constructor(options) {
51639
52036
  this.#options = options;
51640
52037
  this.#conversationId = options.resumeId;
@@ -51681,7 +52078,9 @@ var init_antigravity = __esm({
51681
52078
  const type = asString(frame.type);
51682
52079
  if (!type) return [];
51683
52080
  this.#conversationId = antigravityString(frame, "conversation_id") ?? antigravityString(frame, "session_id") ?? this.#conversationId;
52081
+ this.#rootConversation ??= this.#conversationId;
51684
52082
  this.#track(type, frame);
52083
+ this.#noteStep(type, frame);
51685
52084
  const forked = this.#silentFork();
51686
52085
  if (SESSION_START_TYPES.has(type)) {
51687
52086
  return [
@@ -51696,6 +52095,29 @@ var init_antigravity = __esm({
51696
52095
  if (RESULT_TYPES.has(type)) return [...forked, ...this.#onResult(type, frame)];
51697
52096
  return [...forked, ...this.#transcripts?.read() ?? []];
51698
52097
  }
52098
+ /** A finished answer step of this conversation: one model call, with its own usage. */
52099
+ #noteStep(type, frame) {
52100
+ if (type !== "assistant_message" || asString(frame.state).toUpperCase() !== "DONE") return;
52101
+ const usage = asRecord(frame.usage);
52102
+ if (!usage) return;
52103
+ const conversation = antigravityString(frame, "conversation_id");
52104
+ if (conversation && this.#rootConversation && conversation !== this.#rootConversation) return;
52105
+ const step = stepTokens(usage);
52106
+ this.#stepSpend = addStepTokens(this.#stepSpend, step);
52107
+ const context = step.inputTokens + step.cacheReadTokens + step.outputTokens;
52108
+ if (context > 0) this.#contextTokens = context;
52109
+ }
52110
+ /**
52111
+ * agy's result usage is cumulative over the conversation, so a resumed turn's spend comes
52112
+ * from its steps; a first turn's result is its own.
52113
+ */
52114
+ #turnSpend(frame) {
52115
+ const steps = this.#stepSpend;
52116
+ this.#stepSpend = void 0;
52117
+ if (steps) return steps;
52118
+ if (this.#options.resumeId) return void 0;
52119
+ return stepTokens(asRecord(frame.usage) ?? asRecord(frame.stats) ?? frame);
52120
+ }
51699
52121
  #track(type, frame) {
51700
52122
  const transcripts = this.#transcripts;
51701
52123
  if (!transcripts) return;
@@ -51713,6 +52135,22 @@ var init_antigravity = __esm({
51713
52135
  this.#forkReported = true;
51714
52136
  return [noticeUpdate("warning", "session_resume_failed", RESUME_FORKED)];
51715
52137
  }
52138
+ #resultUsage(frame) {
52139
+ const spend = this.#turnSpend(frame);
52140
+ const contextTokens = this.#contextTokens;
52141
+ if (!spend && contextTokens === void 0) return [];
52142
+ const stats = asRecord(frame.usage) ?? asRecord(frame.stats) ?? frame;
52143
+ return [
52144
+ usageUpdate({
52145
+ model: formatAntigravityModelName(this.#model()),
52146
+ numTurns: Math.max(this.#iterations, 1),
52147
+ durationMs: asFiniteNumber(stats.duration_ms) ?? 0,
52148
+ ...spend,
52149
+ ...contextTokens === void 0 ? {} : { contextTokens },
52150
+ costUsd: 0
52151
+ })
52152
+ ];
52153
+ }
51716
52154
  #onResult(type, frame) {
51717
52155
  const updates = [];
51718
52156
  this.#iterations = Math.max(this.#iterations, asFiniteNumber(frame.num_turns) ?? 1);
@@ -51721,23 +52159,7 @@ var init_antigravity = __esm({
51721
52159
  updates.push(agentText(`antigravity-${this.#conversationId ?? "run"}-result`, resultText3));
51722
52160
  this.#resultShown = true;
51723
52161
  }
51724
- const stats = asRecord(frame.usage) ?? asRecord(frame.stats) ?? frame;
51725
- updates.push(
51726
- usageUpdate({
51727
- model: formatAntigravityModelName(this.#model()),
51728
- numTurns: Math.max(this.#iterations, 1),
51729
- durationMs: asFiniteNumber(stats.duration_ms) ?? 0,
51730
- inputTokens: firstNumber2(stats.input_tokens, stats.input),
51731
- outputTokens: firstNumber2(stats.output_tokens),
51732
- cacheReadTokens: firstNumber2(
51733
- stats.cache_read_tokens,
51734
- stats.cached_input_tokens,
51735
- stats.cached
51736
- ),
51737
- cacheCreationTokens: 0,
51738
- costUsd: 0
51739
- })
51740
- );
52162
+ updates.push(...this.#resultUsage(frame));
51741
52163
  const status = asString(frame.status).toLowerCase();
51742
52164
  const succeeded = !status || SUCCESSFUL_STATUSES.has(status);
51743
52165
  if (succeeded) {
@@ -51980,8 +52402,8 @@ var import_promises55, import_path16, import_crypto20, COMMAND_CODE_GRAMMAR_NAME
51980
52402
  var init_command_code = __esm({
51981
52403
  "../agent-core/dist/providers/command-code.js"() {
51982
52404
  "use strict";
51983
- init_chunk_WD7O4DYQ();
51984
- init_chunk_OUEMTEUX();
52405
+ init_chunk_N2M5D7RS();
52406
+ init_chunk_RBQC7XZH();
51985
52407
  init_chunk_ZCTKXKYY();
51986
52408
  init_chunk_6VWVDJ2A();
51987
52409
  init_chunk_DLVRNIY5();
@@ -52346,6 +52768,7 @@ var init_command_code = __esm({
52346
52768
  #streamed = false;
52347
52769
  #totals;
52348
52770
  #result;
52771
+ #contextTokens;
52349
52772
  constructor(options) {
52350
52773
  this.#options = options;
52351
52774
  if (options.resumeId) this.#grammar.sessionId = options.resumeId;
@@ -52388,6 +52811,8 @@ var init_command_code = __esm({
52388
52811
  #onEvent(event) {
52389
52812
  switch (commandCodeString(event.type)) {
52390
52813
  case "model_request_end":
52814
+ this.#noteContext(event.usage);
52815
+ return this.#usage(event.usage);
52391
52816
  case "turn_end":
52392
52817
  return this.#usage(event.usage);
52393
52818
  case "run_end": {
@@ -52439,7 +52864,28 @@ var init_command_code = __esm({
52439
52864
  durationMs: durationMs ?? previous?.durationMs ?? 0
52440
52865
  };
52441
52866
  this.#totals = totals;
52442
- return [usageUpdate({ model: this.#model(), numTurns: 1, ...totals, costUsd: 0 })];
52867
+ return [
52868
+ usageUpdate({
52869
+ model: this.#model(),
52870
+ numTurns: 1,
52871
+ ...totals,
52872
+ // Command Code's own cost estimate takes cache out of inputTokens, which counts it.
52873
+ inputTokens: Math.max(
52874
+ totals.inputTokens - totals.cacheReadTokens - totals.cacheCreationTokens,
52875
+ 0
52876
+ ),
52877
+ ...this.#contextTokens === void 0 ? {} : { contextTokens: this.#contextTokens },
52878
+ costUsd: 0
52879
+ })
52880
+ ];
52881
+ }
52882
+ /** One model call's prompt, cache included, plus its reply: what it left in the window. */
52883
+ #noteContext(usage) {
52884
+ const record2 = asRecord(usage);
52885
+ const input2 = asFiniteNumber(record2?.inputTokens) ?? asFiniteNumber(record2?.input_tokens);
52886
+ if (input2 === void 0 || input2 <= 0) return;
52887
+ const output2 = asFiniteNumber(record2?.outputTokens) ?? asFiniteNumber(record2?.output_tokens);
52888
+ this.#contextTokens = input2 + (output2 ?? 0);
52443
52889
  }
52444
52890
  };
52445
52891
  COMMAND_CODE_MAX_TURNS = 1e4;
@@ -57383,7 +57829,7 @@ var require_websocket_server = __commonJS({
57383
57829
  // package.json
57384
57830
  var package_default = {
57385
57831
  name: "@alan-ai-hq/agent-manager",
57386
- version: "0.1.160",
57832
+ version: "0.1.161",
57387
57833
  private: true,
57388
57834
  type: "module",
57389
57835
  description: "Alan machine runtime (alan-agent): identity, link, reconciler, session holders, run log, uploader, local API",
@@ -58890,15 +59336,15 @@ var BRANCH_LABEL_MAX_LENGTH = 256;
58890
59336
  var HASH_OBJECT_BATCH = 128;
58891
59337
  function countPorcelainEntries(output2) {
58892
59338
  const records = output2.split("\0");
58893
- let count = 0;
59339
+ let count2 = 0;
58894
59340
  for (let index = 0; index < records.length; index += 1) {
58895
59341
  const record2 = records[index];
58896
59342
  if (!record2) continue;
58897
- count += 1;
59343
+ count2 += 1;
58898
59344
  const status = record2.slice(0, 2);
58899
59345
  if (status.includes("R") || status.includes("C")) index += 1;
58900
59346
  }
58901
- return count;
59347
+ return count2;
58902
59348
  }
58903
59349
  function sanitizeBranch(value2) {
58904
59350
  const printable = Array.from(value2.trim()).filter((character) => {
@@ -60863,6 +61309,7 @@ function runtimePaths(stateDir) {
60863
61309
 
60864
61310
  // src/platform/process-memory.ts
60865
61311
  var import_node_child_process4 = require("child_process");
61312
+ var import_node_fs7 = require("fs");
60866
61313
  var import_promises16 = require("fs/promises");
60867
61314
  var import_node_os2 = require("os");
60868
61315
  var import_node_util3 = require("util");
@@ -60930,12 +61377,52 @@ function readMemoryPressure() {
60930
61377
  if (process.platform === "linux") return linuxPressure();
60931
61378
  return Promise.resolve("normal");
60932
61379
  }
61380
+ function parseDarwinVmStat(output2) {
61381
+ const pageSize = Number(/page size of (\d+) bytes/.exec(output2)?.[1]);
61382
+ if (!Number.isFinite(pageSize) || pageSize <= 0) return null;
61383
+ const pages = (name) => {
61384
+ const match = new RegExp(`^Pages ${name}:\\s+(\\d+)\\.?$`, "m").exec(output2);
61385
+ return match ? Number(match[1]) : null;
61386
+ };
61387
+ const free = pages("free");
61388
+ if (free === null) return null;
61389
+ return (free + (pages("inactive") ?? 0) + (pages("speculative") ?? 0)) * pageSize;
61390
+ }
61391
+ function parseLinuxMemInfo(output2) {
61392
+ const kilobytes = /^MemAvailable:\s+(\d+)\s+kB$/m.exec(output2)?.[1];
61393
+ return kilobytes === void 0 ? null : Number(kilobytes) * 1024;
61394
+ }
61395
+ var CAPACITY_PROBE_TTL_MS = 2e3;
61396
+ var AvailableMemoryProbe = class {
61397
+ cached = null;
61398
+ read(now) {
61399
+ if (this.cached !== null && now - this.cached.at < CAPACITY_PROBE_TTL_MS) {
61400
+ return this.cached.bytes;
61401
+ }
61402
+ let bytes = null;
61403
+ try {
61404
+ if (process.platform === "darwin") {
61405
+ bytes = parseDarwinVmStat(
61406
+ (0, import_node_child_process4.execFileSync)("vm_stat", { encoding: "utf8", timeout: PROBE_TIMEOUT_MS })
61407
+ );
61408
+ } else if (process.platform === "linux") {
61409
+ bytes = parseLinuxMemInfo((0, import_node_fs7.readFileSync)("/proc/meminfo", "utf8"));
61410
+ }
61411
+ } catch {
61412
+ bytes = null;
61413
+ }
61414
+ this.cached = { at: now, bytes };
61415
+ return bytes;
61416
+ }
61417
+ };
61418
+ var availableMemoryProbe = new AvailableMemoryProbe();
60933
61419
  function readMemoryCapacity() {
60934
61420
  const constrained = process.constrainedMemory();
60935
- return {
60936
- totalBytes: constrained > 0 ? Math.min((0, import_node_os2.totalmem)(), constrained) : (0, import_node_os2.totalmem)(),
60937
- availableBytes: typeof process.availableMemory === "function" ? process.availableMemory() : (0, import_node_os2.freemem)()
60938
- };
61421
+ const totalBytes = constrained > 0 ? Math.min((0, import_node_os2.totalmem)(), constrained) : (0, import_node_os2.totalmem)();
61422
+ const reported = typeof process.availableMemory === "function" ? process.availableMemory() : (0, import_node_os2.freemem)();
61423
+ const probed = constrained > 0 && process.platform === "linux" ? null : availableMemoryProbe.read(Date.now());
61424
+ const availableBytes = Math.min(totalBytes, Math.max(reported, probed ?? reported));
61425
+ return { totalBytes, availableBytes };
60939
61426
  }
60940
61427
  async function processMemoryRows() {
60941
61428
  if (process.platform === "win32") {
@@ -61415,7 +61902,7 @@ var import_promises20 = require("fs/promises");
61415
61902
  var import_node_path17 = require("path");
61416
61903
 
61417
61904
  // src/platform/service/windows-service.ts
61418
- var import_node_fs7 = require("fs");
61905
+ var import_node_fs8 = require("fs");
61419
61906
  var import_promises19 = require("fs/promises");
61420
61907
  var import_node_path16 = require("path");
61421
61908
 
@@ -61645,7 +62132,7 @@ function windowsManager(host, profile) {
61645
62132
  name: files.runValue,
61646
62133
  definitionPath: files.config,
61647
62134
  install: async (spec, { restart }) => {
61648
- if (process.platform === "win32" && !(0, import_node_fs7.existsSync)(files.helper)) {
62135
+ if (process.platform === "win32" && !(0, import_node_fs8.existsSync)(files.helper)) {
61649
62136
  throw new RuntimeFault("io_failed", `Windows helper is missing: ${files.helper}`);
61650
62137
  }
61651
62138
  await (0, import_promises19.mkdir)((0, import_node_path16.dirname)(spec.logPath), { recursive: true });
@@ -62340,7 +62827,7 @@ function systemAssertionSpawner(log) {
62340
62827
  // src/platform/spawn-detached.ts
62341
62828
  var import_node_child_process8 = require("child_process");
62342
62829
  var import_node_crypto12 = require("crypto");
62343
- var import_node_fs8 = require("fs");
62830
+ var import_node_fs9 = require("fs");
62344
62831
  var import_node_path21 = require("path");
62345
62832
  var WINDOWS_UNSAFE_ENV = "NODE_PENDING_PIPE_INSTANCES";
62346
62833
  var SYSTEMD_RUN = "systemd-run";
@@ -62395,8 +62882,8 @@ function isolatedCommand(request2, isolation) {
62395
62882
  };
62396
62883
  }
62397
62884
  function spawnDetached(request2, isolation) {
62398
- (0, import_node_fs8.mkdirSync)((0, import_node_path21.dirname)(request2.outputPath), { recursive: true, mode: 448 });
62399
- const output2 = (0, import_node_fs8.openSync)(request2.outputPath, "a", 384);
62885
+ (0, import_node_fs9.mkdirSync)((0, import_node_path21.dirname)(request2.outputPath), { recursive: true, mode: 448 });
62886
+ const output2 = (0, import_node_fs9.openSync)(request2.outputPath, "a", 384);
62400
62887
  const { command, args } = isolatedCommand(request2, isolation);
62401
62888
  try {
62402
62889
  const child = (0, import_node_child_process8.spawn)(command, args, {
@@ -62412,7 +62899,7 @@ function spawnDetached(request2, isolation) {
62412
62899
  child.unref();
62413
62900
  return { pid: child.pid };
62414
62901
  } finally {
62415
- (0, import_node_fs8.closeSync)(output2);
62902
+ (0, import_node_fs9.closeSync)(output2);
62416
62903
  }
62417
62904
  }
62418
62905
 
@@ -62452,7 +62939,7 @@ function createUpdateGate(deps) {
62452
62939
 
62453
62940
  // src/platform/wake-clock.ts
62454
62941
  var import_node_child_process9 = require("child_process");
62455
- var import_node_fs9 = require("fs");
62942
+ var import_node_fs10 = require("fs");
62456
62943
  var import_node_readline = require("readline");
62457
62944
  var PTP_DEVICE = "/dev/ptp0";
62458
62945
  var RESPAWN_BASE_MS = 1e3;
@@ -62536,7 +63023,7 @@ function systemWakeClockSpawner(log) {
62536
63023
  function startWakeClock(options) {
62537
63024
  const { clock, log } = options;
62538
63025
  const platform3 = options.platform ?? process.platform;
62539
- const hasPtpDevice = options.hasPtpDevice ?? (() => (0, import_node_fs9.existsSync)(PTP_DEVICE));
63026
+ const hasPtpDevice = options.hasPtpDevice ?? (() => (0, import_node_fs10.existsSync)(PTP_DEVICE));
62540
63027
  if (platform3 !== "linux" || !hasPtpDevice()) return { [Symbol.dispose]: () => {
62541
63028
  } };
62542
63029
  const spawner = options.spawner ?? systemWakeClockSpawner(log);
@@ -64670,7 +65157,7 @@ function fingerprintWholeText(fingerprint) {
64670
65157
  }
64671
65158
 
64672
65159
  // src/capabilities/native-ingest/hook-config.ts
64673
- var import_node_fs10 = require("fs");
65160
+ var import_node_fs11 = require("fs");
64674
65161
  var import_node_path28 = require("path");
64675
65162
 
64676
65163
  // src/capabilities/native-ingest/provider-paths.ts
@@ -64748,9 +65235,9 @@ function hookHandler(provider4, event, options) {
64748
65235
  return { type: "command", command: posixCommand(argv, environment), timeout: 5 };
64749
65236
  }
64750
65237
  function readSettings(path4, backupWhenMalformed, now) {
64751
- if (!(0, import_node_fs10.existsSync)(path4)) return {};
65238
+ if (!(0, import_node_fs11.existsSync)(path4)) return {};
64752
65239
  try {
64753
- const value2 = JSON.parse((0, import_node_fs10.readFileSync)(path4, "utf8"));
65240
+ const value2 = JSON.parse((0, import_node_fs11.readFileSync)(path4, "utf8"));
64754
65241
  if (!isRecord4(value2)) throw new Error("settings root must be an object");
64755
65242
  if (value2.hooks !== void 0 && !isRecord4(value2.hooks)) {
64756
65243
  throw new Error("settings `hooks` must be an object");
@@ -64760,7 +65247,7 @@ function readSettings(path4, backupWhenMalformed, now) {
64760
65247
  const reason = error62 instanceof Error ? error62.message : String(error62);
64761
65248
  if (!backupWhenMalformed) throw new Error(`${path4} is malformed: ${reason}`);
64762
65249
  const backup = `${path4}.malformed-${now}.bak`;
64763
- (0, import_node_fs10.copyFileSync)(path4, backup);
65250
+ (0, import_node_fs11.copyFileSync)(path4, backup);
64764
65251
  throw new Error(`${path4} is malformed and was copied to ${backup}: ${reason}`);
64765
65252
  }
64766
65253
  }
@@ -64768,14 +65255,14 @@ function hooksOf(settings2) {
64768
65255
  return isRecord4(settings2.hooks) ? settings2.hooks : {};
64769
65256
  }
64770
65257
  function writeSettings(path4, settings2) {
64771
- (0, import_node_fs10.mkdirSync)((0, import_node_path28.dirname)(path4), { recursive: true, mode: 448 });
65258
+ (0, import_node_fs11.mkdirSync)((0, import_node_path28.dirname)(path4), { recursive: true, mode: 448 });
64772
65259
  const temporary = `${path4}.${process.pid}.tmp`;
64773
65260
  try {
64774
- (0, import_node_fs10.writeFileSync)(temporary, `${JSON.stringify(settings2, null, 2)}
65261
+ (0, import_node_fs11.writeFileSync)(temporary, `${JSON.stringify(settings2, null, 2)}
64775
65262
  `, { mode: 384 });
64776
- (0, import_node_fs10.renameSync)(temporary, path4);
65263
+ (0, import_node_fs11.renameSync)(temporary, path4);
64777
65264
  } finally {
64778
- (0, import_node_fs10.rmSync)(temporary, { force: true });
65265
+ (0, import_node_fs11.rmSync)(temporary, { force: true });
64779
65266
  }
64780
65267
  }
64781
65268
  function isIngestionHandler(handler) {
@@ -64820,7 +65307,7 @@ function installIngestionHooks(provider4, options, now) {
64820
65307
  }
64821
65308
  function removeIngestionHooks(provider4, where, now) {
64822
65309
  const path4 = providerHookSettingsPath(provider4, where);
64823
- if (!(0, import_node_fs10.existsSync)(path4)) return { provider: provider4, path: path4, changed: false };
65310
+ if (!(0, import_node_fs11.existsSync)(path4)) return { provider: provider4, path: path4, changed: false };
64824
65311
  const settings2 = readSettings(path4, true, now);
64825
65312
  const hooks = hooksOf(settings2);
64826
65313
  const nextHooks = {};
@@ -64857,7 +65344,7 @@ function ingestionHookStatus(provider4, options) {
64857
65344
  }
64858
65345
 
64859
65346
  // src/capabilities/native-ingest/hook-input.ts
64860
- var import_node_fs11 = require("fs");
65347
+ var import_node_fs12 = require("fs");
64861
65348
  var import_node_path29 = require("path");
64862
65349
  var ALAN_MANAGED_SESSION_ENV = "ALAN_MANAGED_SESSION";
64863
65350
  var MAX_HOOK_STDIN_BYTES = 256 * 1024 * 1024;
@@ -64887,17 +65374,17 @@ function codexSessionIdFromTranscriptPath(transcriptPath) {
64887
65374
  );
64888
65375
  return match?.[1] ?? null;
64889
65376
  }
64890
- function lastBytes(chunks, count) {
65377
+ function lastBytes(chunks, count2) {
64891
65378
  const kept = [];
64892
65379
  let size = 0;
64893
- for (let index = chunks.length - 1; index >= 0 && size < count; index -= 1) {
65380
+ for (let index = chunks.length - 1; index >= 0 && size < count2; index -= 1) {
64894
65381
  const chunk = chunks[index];
64895
65382
  if (chunk === void 0) continue;
64896
65383
  kept.unshift(chunk);
64897
65384
  size += chunk.length;
64898
65385
  }
64899
65386
  const joined = Buffer.concat(kept);
64900
- return joined.subarray(Math.max(0, joined.length - count));
65387
+ return joined.subarray(Math.max(0, joined.length - count2));
64901
65388
  }
64902
65389
  async function readHookStdin(stream, maxBytes = MAX_HOOK_STDIN_BYTES) {
64903
65390
  const chunks = [];
@@ -64957,10 +65444,10 @@ function hookPayload(input2) {
64957
65444
  }
64958
65445
  function realpathOrSelf(path4) {
64959
65446
  try {
64960
- return (0, import_node_fs11.realpathSync)(path4);
65447
+ return (0, import_node_fs12.realpathSync)(path4);
64961
65448
  } catch {
64962
65449
  try {
64963
- return (0, import_node_path29.join)((0, import_node_fs11.realpathSync)((0, import_node_path29.dirname)(path4)), (0, import_node_path29.basename)(path4));
65450
+ return (0, import_node_path29.join)((0, import_node_fs12.realpathSync)((0, import_node_path29.dirname)(path4)), (0, import_node_path29.basename)(path4));
64964
65451
  } catch {
64965
65452
  return path4;
64966
65453
  }
@@ -64991,7 +65478,7 @@ function parseHookSignal(input2) {
64991
65478
  }
64992
65479
 
64993
65480
  // src/capabilities/native-ingest/ingest.ts
64994
- var import_node_fs12 = require("fs");
65481
+ var import_node_fs13 = require("fs");
64995
65482
 
64996
65483
  // ../shared/dist/types/native-agent-session.js
64997
65484
  var nativeAgentProviderBackendKinds = {
@@ -65761,7 +66248,7 @@ function workerKey(provider4, externalSessionId) {
65761
66248
  return `${provider4}\0${externalSessionId}`;
65762
66249
  }
65763
66250
  function holdFor(entry) {
65764
- const stats = (0, import_node_fs12.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
66251
+ const stats = (0, import_node_fs13.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
65765
66252
  if (!stats) return [];
65766
66253
  return [
65767
66254
  {
@@ -65962,7 +66449,7 @@ async function startNativeIngest(deps) {
65962
66449
  return "accepted";
65963
66450
  };
65964
66451
  const hasUnreadBytes = (entry, now) => {
65965
- const stats = (0, import_node_fs12.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
66452
+ const stats = (0, import_node_fs13.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
65966
66453
  if (!stats || now - Number(stats.mtimeMs) > timing.sweepRecencyMs) return false;
65967
66454
  const replaced = String(stats.dev) !== entry.device || String(stats.ino) !== entry.inode;
65968
66455
  return replaced || Number(stats.size) > entry.cursor.offset;
@@ -66006,7 +66493,7 @@ async function startNativeIngest(deps) {
66006
66493
  const recordAlanRun = async (hold, runId) => {
66007
66494
  const entry = store.get(hold.provider, hold.externalSessionId);
66008
66495
  if (!entry || entry.dead) return;
66009
- const stats = (0, import_node_fs12.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
66496
+ const stats = (0, import_node_fs13.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
66010
66497
  if (!stats) return;
66011
66498
  const identity = { device: String(stats.dev), inode: String(stats.ino) };
66012
66499
  const size = Number(stats.size);
@@ -66080,7 +66567,7 @@ async function startNativeIngest(deps) {
66080
66567
  init_alan_code();
66081
66568
 
66082
66569
  // src/capabilities/providers/commands.ts
66083
- var import_node_fs13 = require("fs");
66570
+ var import_node_fs14 = require("fs");
66084
66571
  var import_promises35 = require("fs/promises");
66085
66572
  var import_node_path32 = require("path");
66086
66573
  var PROVIDER_COMMANDS = [
@@ -66118,7 +66605,7 @@ function pathDelimiter(platform3) {
66118
66605
  async function isRunnable(path4, platform3) {
66119
66606
  try {
66120
66607
  if (!(await (0, import_promises35.stat)(path4)).isFile()) return false;
66121
- if (platform3 !== "win32") await (0, import_promises35.access)(path4, import_node_fs13.constants.X_OK);
66608
+ if (platform3 !== "win32") await (0, import_promises35.access)(path4, import_node_fs14.constants.X_OK);
66122
66609
  return true;
66123
66610
  } catch {
66124
66611
  return false;
@@ -66301,7 +66788,7 @@ init_runtime_v2();
66301
66788
 
66302
66789
  // src/capabilities/providers/account-label.ts
66303
66790
  var import_node_child_process12 = require("child_process");
66304
- var import_node_fs14 = require("fs");
66791
+ var import_node_fs15 = require("fs");
66305
66792
  var import_node_path33 = require("path");
66306
66793
  var import_node_url3 = require("url");
66307
66794
  var ACCOUNT_TIMEOUT_MS = 2e4;
@@ -66404,7 +66891,7 @@ async function claudeLabel(executable, env) {
66404
66891
  const childEnv = { ...env };
66405
66892
  delete childEnv.FORCE_CODE_TERMINAL;
66406
66893
  const bundledSdk = typeof __dirname === "string" ? (0, import_node_path33.join)(__dirname, "claude-sdk.mjs") : "";
66407
- const sdkSpecifier = (0, import_node_fs14.existsSync)(bundledSdk) ? (0, import_node_url3.pathToFileURL)(bundledSdk).href : "@anthropic-ai/claude-agent-sdk";
66894
+ const sdkSpecifier = (0, import_node_fs15.existsSync)(bundledSdk) ? (0, import_node_url3.pathToFileURL)(bundledSdk).href : "@anthropic-ai/claude-agent-sdk";
66408
66895
  const { query } = await import(sdkSpecifier);
66409
66896
  const session = query({
66410
66897
  prompt: idlePrompt(abort.signal),
@@ -66814,7 +67301,7 @@ var import_node_path37 = require("path");
66814
67301
  // ../shared/dist/node/shell-environment.js
66815
67302
  var import_node_child_process13 = require("child_process");
66816
67303
  var import_node_crypto16 = require("crypto");
66817
- var import_node_fs16 = require("fs");
67304
+ var import_node_fs17 = require("fs");
66818
67305
  var import_node_os6 = require("os");
66819
67306
  var import_node_path36 = require("path");
66820
67307
 
@@ -66823,7 +67310,7 @@ var import_node_os5 = require("os");
66823
67310
  var import_node_path35 = require("path");
66824
67311
 
66825
67312
  // ../shared/dist/node/version-manager-paths.js
66826
- var import_node_fs15 = require("fs");
67313
+ var import_node_fs16 = require("fs");
66827
67314
  var import_node_path34 = require("path");
66828
67315
  function compareNodeVersionsDesc(a, b) {
66829
67316
  const parse7 = (value2) => value2.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10) || 0);
@@ -66838,19 +67325,19 @@ function compareNodeVersionsDesc(a, b) {
66838
67325
  }
66839
67326
  function resolveNvmDefaultBin(home) {
66840
67327
  const versionsDir = (0, import_node_path34.join)(home, ".nvm", "versions", "node");
66841
- if (!(0, import_node_fs15.existsSync)(versionsDir))
67328
+ if (!(0, import_node_fs16.existsSync)(versionsDir))
66842
67329
  return null;
66843
67330
  let alias = null;
66844
67331
  try {
66845
67332
  const aliasFile = (0, import_node_path34.join)(home, ".nvm", "alias", "default");
66846
- if ((0, import_node_fs15.existsSync)(aliasFile))
66847
- alias = (0, import_node_fs15.readFileSync)(aliasFile, "utf8").trim();
67333
+ if ((0, import_node_fs16.existsSync)(aliasFile))
67334
+ alias = (0, import_node_fs16.readFileSync)(aliasFile, "utf8").trim();
66848
67335
  } catch {
66849
67336
  alias = null;
66850
67337
  }
66851
67338
  let installed;
66852
67339
  try {
66853
- installed = (0, import_node_fs15.readdirSync)(versionsDir).filter((entry) => entry.startsWith("v"));
67340
+ installed = (0, import_node_fs16.readdirSync)(versionsDir).filter((entry) => entry.startsWith("v"));
66854
67341
  } catch {
66855
67342
  return null;
66856
67343
  }
@@ -66861,7 +67348,7 @@ function resolveNvmDefaultBin(home) {
66861
67348
  if (!chosen)
66862
67349
  return null;
66863
67350
  const bin = (0, import_node_path34.join)(versionsDir, chosen, "bin");
66864
- return (0, import_node_fs15.existsSync)(bin) ? bin : null;
67351
+ return (0, import_node_fs16.existsSync)(bin) ? bin : null;
66865
67352
  }
66866
67353
  function resolveVersionManagerBinDirs(home, platform3 = process.platform) {
66867
67354
  if (platform3 === "win32")
@@ -66880,7 +67367,7 @@ function resolveVersionManagerBinDirs(home, platform3 = process.platform) {
66880
67367
  if (!dir || seen.has(dir))
66881
67368
  continue;
66882
67369
  seen.add(dir);
66883
- if ((0, import_node_fs15.existsSync)(dir))
67370
+ if ((0, import_node_fs16.existsSync)(dir))
66884
67371
  resolved.push(dir);
66885
67372
  }
66886
67373
  return resolved;
@@ -66922,7 +67409,7 @@ function promoteUserBinDirs(path4, home, versionManagerDirs) {
66922
67409
  // ../shared/dist/node/shell-environment.js
66923
67410
  function isExecutableFile(path4) {
66924
67411
  try {
66925
- (0, import_node_fs16.accessSync)(path4, import_node_fs16.constants.X_OK);
67412
+ (0, import_node_fs17.accessSync)(path4, import_node_fs17.constants.X_OK);
66926
67413
  return true;
66927
67414
  } catch {
66928
67415
  return false;
@@ -68832,7 +69319,7 @@ async function publishLocalSkill(options) {
68832
69319
 
68833
69320
  // src/capabilities/skills/native-index.ts
68834
69321
  var import_node_crypto23 = require("crypto");
68835
- var import_node_fs17 = require("fs");
69322
+ var import_node_fs18 = require("fs");
68836
69323
  var import_promises45 = require("fs/promises");
68837
69324
  var import_node_path45 = require("path");
68838
69325
  var ALAN_SKILLS_PLUGIN_NAME = "alan";
@@ -68983,7 +69470,7 @@ async function reconcileNativeIndex(layout, installed, options) {
68983
69470
  };
68984
69471
  }
68985
69472
  function installedSkillFolders(layout) {
68986
- return (0, import_node_fs17.existsSync)((0, import_node_path45.join)(layout.pluginDir, ".claude-plugin", "plugin.json")) ? { pluginDir: layout.pluginDir, skillsDir: layout.pluginSkillsDir } : null;
69473
+ return (0, import_node_fs18.existsSync)((0, import_node_path45.join)(layout.pluginDir, ".claude-plugin", "plugin.json")) ? { pluginDir: layout.pluginDir, skillsDir: layout.pluginSkillsDir } : null;
68987
69474
  }
68988
69475
 
68989
69476
  // src/capabilities/skills/sync.ts
@@ -70872,10 +71359,10 @@ async function reapLeftoverEngines(path4, options) {
70872
71359
  }
70873
71360
 
70874
71361
  // src/holder/launch-command.ts
70875
- var import_node_fs18 = require("fs");
71362
+ var import_node_fs19 = require("fs");
70876
71363
  var import_node_path53 = require("path");
70877
71364
  var HOLDER_BUNDLE = "alan-holder.cjs";
70878
- function holderArguments(runtimeArgs, nodeFlags, exists6 = import_node_fs18.existsSync) {
71365
+ function holderArguments(runtimeArgs, nodeFlags, exists6 = import_node_fs19.existsSync) {
70879
71366
  const bundle = runtimeArgs.at(-1);
70880
71367
  const lean = bundle === void 0 ? void 0 : (0, import_node_path53.join)((0, import_node_path53.dirname)(bundle), HOLDER_BUNDLE);
70881
71368
  const script = lean !== void 0 && exists6(lean) ? [...runtimeArgs.slice(0, -1), lean] : runtimeArgs;
@@ -71014,20 +71501,20 @@ async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
71014
71501
 
71015
71502
  // src/holder/serve.ts
71016
71503
  var import_node_crypto30 = require("crypto");
71017
- var import_node_fs23 = require("fs");
71504
+ var import_node_fs24 = require("fs");
71018
71505
  var import_node_net3 = require("net");
71019
71506
  var import_node_path66 = require("path");
71020
71507
  init_runtime_v2();
71021
71508
 
71022
71509
  // src/holder/admission.ts
71023
- var import_node_fs20 = require("fs");
71510
+ var import_node_fs21 = require("fs");
71024
71511
  var import_promises61 = require("fs/promises");
71025
71512
  var import_node_os10 = require("os");
71026
71513
  var import_node_path60 = require("path");
71027
71514
  init_constants();
71028
71515
 
71029
71516
  // ../shared/dist/node/local-workspace.js
71030
- var import_node_fs19 = require("fs");
71517
+ var import_node_fs20 = require("fs");
71031
71518
  var import_node_os9 = require("os");
71032
71519
  var import_node_path55 = require("path");
71033
71520
  function resolveAlanDefaultWorkspacePath(homeDirectory = (0, import_node_os9.homedir)()) {
@@ -71447,7 +71934,7 @@ async function inspectReadiness(path4) {
71447
71934
  if (!(await (0, import_promises61.stat)(path4)).isDirectory()) {
71448
71935
  return { ready: false, missing: true, message: MESSAGES.missing };
71449
71936
  }
71450
- await (0, import_promises61.access)(path4, import_node_fs20.constants.R_OK | import_node_fs20.constants.W_OK | import_node_fs20.constants.X_OK);
71937
+ await (0, import_promises61.access)(path4, import_node_fs21.constants.R_OK | import_node_fs21.constants.W_OK | import_node_fs21.constants.X_OK);
71451
71938
  return { ready: true };
71452
71939
  } catch (error62) {
71453
71940
  const code = errnoCode(error62) ?? "";
@@ -71492,7 +71979,7 @@ async function admitDefaultWorkspace(spec, context, skills) {
71492
71979
  const path4 = resolveAlanDefaultWorkspacePath(env.HOME || env.USERPROFILE || (0, import_node_os10.homedir)());
71493
71980
  try {
71494
71981
  await (0, import_promises61.mkdir)(path4, { recursive: true, mode: 448 });
71495
- await (0, import_promises61.access)(path4, import_node_fs20.constants.R_OK | import_node_fs20.constants.W_OK | import_node_fs20.constants.X_OK);
71982
+ await (0, import_promises61.access)(path4, import_node_fs21.constants.R_OK | import_node_fs21.constants.W_OK | import_node_fs21.constants.X_OK);
71496
71983
  return { kind: "admitted", spec: { ...spec, projectPath: path4 }, skills };
71497
71984
  } catch (error62) {
71498
71985
  const code = errnoCode(error62);
@@ -71741,7 +72228,7 @@ ${added.join("\n")}
71741
72228
 
71742
72229
  // src/run-log/complete.ts
71743
72230
  var import_node_crypto29 = require("crypto");
71744
- var import_node_fs21 = require("fs");
72231
+ var import_node_fs22 = require("fs");
71745
72232
  var import_node_path63 = require("path");
71746
72233
 
71747
72234
  // src/run-log/directory.ts
@@ -71792,23 +72279,23 @@ async function isRunClaimed(runsDir, runId) {
71792
72279
  // src/run-log/complete.ts
71793
72280
  function writeLogFile(path4, dir, text3) {
71794
72281
  const temp = (0, import_node_path63.join)(dir, `.log.${(0, import_node_crypto29.randomUUID)()}.tmp`);
71795
- const fd = (0, import_node_fs21.openSync)(temp, "wx", 384);
72282
+ const fd = (0, import_node_fs22.openSync)(temp, "wx", 384);
71796
72283
  try {
71797
- (0, import_node_fs21.writeSync)(fd, text3);
71798
- (0, import_node_fs21.fsyncSync)(fd);
72284
+ (0, import_node_fs22.writeSync)(fd, text3);
72285
+ (0, import_node_fs22.fsyncSync)(fd);
71799
72286
  } finally {
71800
- (0, import_node_fs21.closeSync)(fd);
72287
+ (0, import_node_fs22.closeSync)(fd);
71801
72288
  }
71802
72289
  try {
71803
- (0, import_node_fs21.renameSync)(temp, path4);
72290
+ (0, import_node_fs22.renameSync)(temp, path4);
71804
72291
  } finally {
71805
- (0, import_node_fs21.rmSync)(temp, { force: true });
72292
+ (0, import_node_fs22.rmSync)(temp, { force: true });
71806
72293
  }
71807
72294
  }
71808
72295
  async function writeCompleteRunLog(runsDir, meta3, records) {
71809
72296
  const paths = runDirectory(runsDir, meta3.runId);
71810
72297
  if (!await isRunClaimed(runsDir, meta3.runId)) {
71811
- (0, import_node_fs21.mkdirSync)(paths.dir, { recursive: true, mode: 448 });
72298
+ (0, import_node_fs22.mkdirSync)(paths.dir, { recursive: true, mode: 448 });
71812
72299
  const text3 = records.map((record2, index) => {
71813
72300
  const line = { seq: index + 1, at: record2.at, update: record2.update };
71814
72301
  return `${JSON.stringify(line)}
@@ -72065,13 +72552,13 @@ function runEnded(input2) {
72065
72552
  var decoder = new TextDecoder();
72066
72553
 
72067
72554
  // src/run-log/writer.ts
72068
- var import_node_fs22 = require("fs");
72555
+ var import_node_fs23 = require("fs");
72069
72556
  var import_node_path65 = require("path");
72070
72557
  init_runtime_v2();
72071
72558
  function lastSeq(fd, size) {
72072
72559
  for (const length of tailWindows(size)) {
72073
72560
  const buffer = Buffer.alloc(length);
72074
- (0, import_node_fs22.readSync)(fd, buffer, 0, length, size - length);
72561
+ (0, import_node_fs23.readSync)(fd, buffer, 0, length, size - length);
72075
72562
  const last = lastLine(buffer.toString("utf8").trimEnd(), length === size);
72076
72563
  if (last === void 0) continue;
72077
72564
  if (last.length === 0) return 0;
@@ -72082,13 +72569,13 @@ function lastSeq(fd, size) {
72082
72569
  throw new RuntimeFault("record_too_large", "Run log tail record is larger than any record");
72083
72570
  }
72084
72571
  function openRunLog(path4, clock) {
72085
- (0, import_node_fs22.mkdirSync)((0, import_node_path65.dirname)(path4), { recursive: true, mode: 448 });
72086
- const fd = (0, import_node_fs22.openSync)(path4, "a+", 384);
72087
- let size = (0, import_node_fs22.fstatSync)(fd).size;
72572
+ (0, import_node_fs23.mkdirSync)((0, import_node_path65.dirname)(path4), { recursive: true, mode: 448 });
72573
+ const fd = (0, import_node_fs23.openSync)(path4, "a+", 384);
72574
+ let size = (0, import_node_fs23.fstatSync)(fd).size;
72088
72575
  let seq = lastSeq(fd, size);
72089
72576
  let dirty = false;
72090
72577
  const sync = () => {
72091
- (0, import_node_fs22.fsyncSync)(fd);
72578
+ (0, import_node_fs23.fsyncSync)(fd);
72092
72579
  dirty = false;
72093
72580
  };
72094
72581
  return {
@@ -72102,7 +72589,7 @@ function openRunLog(path4, clock) {
72102
72589
  };
72103
72590
  const line = Buffer.from(`${JSON.stringify(record2)}
72104
72591
  `, "utf8");
72105
- (0, import_node_fs22.writeSync)(fd, line);
72592
+ (0, import_node_fs23.writeSync)(fd, line);
72106
72593
  size += line.length;
72107
72594
  dirty = true;
72108
72595
  if (isRunLifecycleKind(update.sessionUpdate)) sync();
@@ -72114,7 +72601,7 @@ function openRunLog(path4, clock) {
72114
72601
  },
72115
72602
  [Symbol.dispose]: () => {
72116
72603
  if (dirty) sync();
72117
- (0, import_node_fs22.closeSync)(fd);
72604
+ (0, import_node_fs23.closeSync)(fd);
72118
72605
  }
72119
72606
  };
72120
72607
  }
@@ -72558,7 +73045,7 @@ async function runHolder({
72558
73045
  for (const client of holder.clients) client.end();
72559
73046
  await new Promise((resolve13) => server.close(() => resolve13()));
72560
73047
  await statusWrites;
72561
- (0, import_node_fs23.rmSync)(launch.statusPath, { force: true });
73048
+ (0, import_node_fs24.rmSync)(launch.statusPath, { force: true });
72562
73049
  log.info("holder.suspended", { conversationId: launch.conversationId });
72563
73050
  } catch (_) {
72564
73051
  var _error = _, _hasError = true;
@@ -72571,6 +73058,7 @@ async function runHolder({
72571
73058
  var GIB = 1024 ** 3;
72572
73059
  var MIN_RUN_BYTES = 1.25 * GIB;
72573
73060
  function memoryAllowsStart(capacity, activeRuns, pendingStarts = 0) {
73061
+ if (activeRuns + pendingStarts === 0) return true;
72574
73062
  const headroom = Math.max(512 * 1024 ** 2, capacity.totalBytes * 0.2);
72575
73063
  const slots = Math.max(1, Math.floor((capacity.totalBytes - headroom) / MIN_RUN_BYTES));
72576
73064
  return activeRuns + pendingStarts < slots && capacity.availableBytes >= MIN_RUN_BYTES * (pendingStarts + 1);
@@ -72588,6 +73076,7 @@ function runOccupancy(held, reserved, exclude = null) {
72588
73076
 
72589
73077
  // src/sessions/suspend-policy.ts
72590
73078
  var GIB2 = 1024 ** 3;
73079
+ var SESSION_MEMORY_CEILING_BYTES = 2.5 * GIB2;
72591
73080
  var MEMORY_BUDGET_SHARE = 0.15;
72592
73081
  var MEMORY_BUDGET_MIN_BYTES = GIB2;
72593
73082
  var MEMORY_BUDGET_MAX_BYTES = 4 * GIB2;
@@ -72621,7 +73110,9 @@ function memoryOf(holder) {
72621
73110
  function ownReason({ holder, idleSinceMs }, policy, nowMs) {
72622
73111
  if (holder.facts.loginFailed) return "login_error";
72623
73112
  if (holder.facts.cliBinaryChanged) return "cli_changed";
72624
- if (memoryOf(holder) > Math.min(policy.memoryBudgetBytes, 1.25 * GIB2)) return "memory_budget";
73113
+ if (memoryOf(holder) > Math.min(policy.memoryBudgetBytes, SESSION_MEMORY_CEILING_BYTES)) {
73114
+ return "memory_budget";
73115
+ }
72625
73116
  if (nowMs - idleSinceMs >= policy.idleMs) return "idle";
72626
73117
  if (nowMs - holder.facts.startedAtMs >= policy.maxAgeMs) return "age";
72627
73118
  return null;
@@ -72636,8 +73127,8 @@ function planSuspends(holders, policy, nowMs, pressure, opened = null) {
72636
73127
  if (reason === null) kept.push(entry);
72637
73128
  else decisions.push({ conversationId: entry.holder.conversationId, reason });
72638
73129
  }
72639
- const suspend = (count, reason) => {
72640
- for (const { holder } of kept.splice(0, Math.max(0, count))) {
73130
+ const suspend = (count2, reason) => {
73131
+ for (const { holder } of kept.splice(0, Math.max(0, count2))) {
72641
73132
  decisions.push({ conversationId: holder.conversationId, reason });
72642
73133
  }
72643
73134
  };
@@ -73010,7 +73501,20 @@ async function openSessions(deps) {
73010
73501
  return "started";
73011
73502
  }
73012
73503
  if (!await claimCapacity(run2.runId)) {
73013
- log.info("sessions.resource_wait", { runId: run2.runId });
73504
+ const capacity = memoryCapacity();
73505
+ const { active, pending } = runOccupancy(
73506
+ await heldRuns(),
73507
+ [...admitted, ...launched.keys()],
73508
+ run2.runId
73509
+ );
73510
+ log.info("sessions.resource_wait", {
73511
+ runId: run2.runId,
73512
+ active,
73513
+ pending,
73514
+ maxActiveRuns,
73515
+ totalMiB: Math.round(capacity.totalBytes / 2 ** 20),
73516
+ availableMiB: Math.round(capacity.availableBytes / 2 ** 20)
73517
+ });
73014
73518
  return "waiting";
73015
73519
  }
73016
73520
  try {
@@ -73133,7 +73637,8 @@ var envSchema = external_exports.object({
73133
73637
  ALAN_RUNTIME_LOG_LEVEL: external_exports.enum(["debug", "info", "warn", "error"]).default("info"),
73134
73638
  ALAN_RUNTIME_SUSPEND_IDLE_MS: external_exports.coerce.number().int().positive().optional(),
73135
73639
  ALAN_RUNTIME_SUSPEND_CHECK_MS: external_exports.coerce.number().int().positive().default(3e4),
73136
- ALAN_RUNTIME_DESIRED_RESYNC_MS: external_exports.coerce.number().int().positive().default(6e5),
73640
+ // A two-minute conditional GET bounds recovery after a lost poke; unchanged state returns 304.
73641
+ ALAN_RUNTIME_DESIRED_RESYNC_MS: external_exports.coerce.number().int().positive().default(12e4),
73137
73642
  ALAN_MAX_ACTIVE_RUNS: external_exports.coerce.number().int().optional(),
73138
73643
  ALAN_RUNTIME_API_URL: external_exports.url().optional(),
73139
73644
  ALAN_RUNTIME_CREDENTIAL_STORE: external_exports.enum(CREDENTIAL_STORE_KINDS).optional(),
@@ -75310,7 +75815,7 @@ async function runLogout(argv, signal) {
75310
75815
  }
75311
75816
 
75312
75817
  // src/cli/commands/run.ts
75313
- var import_node_fs25 = require("fs");
75818
+ var import_node_fs26 = require("fs");
75314
75819
  var import_node_path82 = require("path");
75315
75820
 
75316
75821
  // src/local-api/app-attachments.ts
@@ -75865,7 +76370,7 @@ var machineFeatureRoutes = [
75865
76370
  ];
75866
76371
 
75867
76372
  // src/local-api/run-log-routes.ts
75868
- var import_node_fs24 = require("fs");
76373
+ var import_node_fs25 = require("fs");
75869
76374
  init_runtime_v2();
75870
76375
  var RUN_ENDED = "_alan/run.ended";
75871
76376
  var decoder2 = new TextDecoder();
@@ -75882,7 +76387,7 @@ async function openWhenWritten(deps, runId, res, signal) {
75882
76387
  const path4 = runDirectory(deps.runsDir, runId).log;
75883
76388
  while (!signal.aborted) {
75884
76389
  const appended = deps.appends.nextAppend(runId, signal);
75885
- if ((0, import_node_fs24.existsSync)(path4) || !await deps.isHeld(runId, signal)) return openReader(res, path4);
76390
+ if ((0, import_node_fs25.existsSync)(path4) || !await deps.isHeld(runId, signal)) return openReader(res, path4);
75886
76391
  await appended;
75887
76392
  }
75888
76393
  return null;
@@ -76655,11 +77160,11 @@ var SEPARATOR = String.fromCharCode(30);
76655
77160
  var encodePayload = (packets, callback) => {
76656
77161
  const length = packets.length;
76657
77162
  const encodedPackets = new Array(length);
76658
- let count = 0;
77163
+ let count2 = 0;
76659
77164
  packets.forEach((packet, i) => {
76660
77165
  encodePacket(packet, false, (encodedPacket) => {
76661
77166
  encodedPackets[i] = encodedPacket;
76662
- if (++count === length) {
77167
+ if (++count2 === length) {
76663
77168
  callback(encodedPackets.join(SEPARATOR));
76664
77169
  }
76665
77170
  });
@@ -82230,7 +82735,7 @@ function lockWaitMs(argv) {
82230
82735
  async function openManagedProviders(config2, paths) {
82231
82736
  const providerEnv = readCliEnvironment();
82232
82737
  const bundledNpm = (0, import_node_path82.join)((0, import_node_path82.dirname)(process.execPath), "npm", "bin", "npm-cli.js");
82233
- const providerToolchain = config2.providerToolchain ?? (process.platform === "win32" && (0, import_node_fs25.existsSync)(bundledNpm) ? { node: process.execPath, npmCli: bundledNpm } : null);
82738
+ const providerToolchain = config2.providerToolchain ?? (process.platform === "win32" && (0, import_node_fs26.existsSync)(bundledNpm) ? { node: process.execPath, npmCli: bundledNpm } : null);
82234
82739
  const npmPath = providerToolchain?.node ?? await resolveCommandOnPath("npm", providerEnv, process.platform);
82235
82740
  const npmOptions = npmPath === null || process.platform === "win32" && providerToolchain === null ? null : {
82236
82741
  command: npmPath,