@alan-ai-hq/agent-manager-linux-x64 0.1.160 → 0.1.162

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 +788 -285
  2. package/alan-holder.cjs +670 -196
  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,
@@ -46971,8 +47275,9 @@ var init_driver = __esm({
46971
47275
  });
46972
47276
 
46973
47277
  // src/holder/drivers/persistent.ts
46974
- function sessionContextFor(opened, inputs) {
46975
- return opened.fresh ? inputs.agentContext?.full : inputs.agentContext?.update;
47278
+ async function sessionContextFor(opened, inputs) {
47279
+ const text3 = await inputs.agentContext;
47280
+ return opened.fresh ? text3?.full : text3?.update;
46976
47281
  }
46977
47282
  function steerEcho(request2) {
46978
47283
  return {
@@ -47221,7 +47526,7 @@ function createPersistentDriver(provider4, options) {
47221
47526
  };
47222
47527
  signal.addEventListener("abort", onAbort, { once: true });
47223
47528
  try {
47224
- const contextPrefix = [sessionContextFor(opened, inputs), opened.contextPrefix].filter((part) => part !== void 0).join("\n\n");
47529
+ const contextPrefix = [await sessionContextFor(opened, inputs), opened.contextPrefix].filter((part) => part !== void 0).join("\n\n");
47225
47530
  const input2 = await provider4.turnInput(spec, inputs, contextPrefix || void 0);
47226
47531
  if (signal.aborted) return { outcome: "aborted" };
47227
47532
  const timeoutMs = options.firstOutputTimeoutMs ?? FIRST_OUTPUT_TIMEOUT_MS;
@@ -47777,8 +48082,22 @@ function codeModeChildUpdates(tool, metadata) {
47777
48082
  };
47778
48083
  });
47779
48084
  }
48085
+ function stepContextTokens(step, total) {
48086
+ const sum = step.inputTokens + step.outputTokens + step.cacheReadTokens + step.cacheCreationTokens;
48087
+ const tokens2 = total !== void 0 && total > 0 ? total : sum;
48088
+ return tokens2 > 0 ? tokens2 : void 0;
48089
+ }
48090
+ function addStepUsage(turn, step) {
48091
+ return {
48092
+ inputTokens: turn.inputTokens + step.inputTokens,
48093
+ outputTokens: turn.outputTokens + step.outputTokens,
48094
+ cacheReadTokens: turn.cacheReadTokens + step.cacheReadTokens,
48095
+ cacheCreationTokens: turn.cacheCreationTokens + step.cacheCreationTokens,
48096
+ costUsd: turn.costUsd === void 0 && step.costUsd === void 0 ? void 0 : (turn.costUsd ?? 0) + (step.costUsd ?? 0)
48097
+ };
48098
+ }
47780
48099
  function createOpenCodeSessionMemory() {
47781
- return { userMessageIds: /* @__PURE__ */ new Set() };
48100
+ return { userMessageIds: /* @__PURE__ */ new Set(), contextWindows: /* @__PURE__ */ new Map() };
47782
48101
  }
47783
48102
  function only(updates) {
47784
48103
  return { updates, actions: [] };
@@ -48111,12 +48430,12 @@ function openCodeTurnInput(run2, context) {
48111
48430
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
48112
48431
  };
48113
48432
  }
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;
48433
+ 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
48434
  var init_opencode = __esm({
48116
48435
  "../agent-core/dist/providers/opencode.js"() {
48117
48436
  "use strict";
48118
- init_chunk_WD7O4DYQ();
48119
- init_chunk_OUEMTEUX();
48437
+ init_chunk_N2M5D7RS();
48438
+ init_chunk_RBQC7XZH();
48120
48439
  init_chunk_ZCTKXKYY();
48121
48440
  init_chunk_6VWVDJ2A();
48122
48441
  init_chunk_DLVRNIY5();
@@ -48298,6 +48617,22 @@ var init_opencode = __esm({
48298
48617
  const providers = Array.isArray(body?.providers) ? body.providers : [];
48299
48618
  return providers.map((provider4) => asString(asRecord(provider4)?.id)).filter(Boolean);
48300
48619
  }
48620
+ /** `provider/model` \u2192 the model's context limit; 0 (a custom model's unknown) is left out. */
48621
+ async modelContextWindows() {
48622
+ const body = asRecord(await this.#call("provider list", "GET", "/config/providers"));
48623
+ const windows = /* @__PURE__ */ new Map();
48624
+ for (const provider4 of Array.isArray(body?.providers) ? body.providers : []) {
48625
+ const record2 = asRecord(provider4);
48626
+ const providerId = asString(record2?.id);
48627
+ for (const [modelId, model] of Object.entries(asRecord(record2?.models) ?? {})) {
48628
+ const limit = asFiniteNumber(asRecord(asRecord(model)?.limit)?.context);
48629
+ if (providerId && limit !== void 0 && limit > 0) {
48630
+ windows.set(`${providerId}/${modelId}`, limit);
48631
+ }
48632
+ }
48633
+ }
48634
+ return windows;
48635
+ }
48301
48636
  /** Asks emitted while disconnected must still get a reply. Older engines may lack these routes. */
48302
48637
  async pendingAsks() {
48303
48638
  const read = async (path4, type) => {
@@ -48529,6 +48864,13 @@ var init_opencode = __esm({
48529
48864
  ["delete", "delete"],
48530
48865
  ["update", "modify"]
48531
48866
  ]);
48867
+ NO_USAGE = {
48868
+ inputTokens: 0,
48869
+ outputTokens: 0,
48870
+ cacheReadTokens: 0,
48871
+ cacheCreationTokens: 0,
48872
+ costUsd: void 0
48873
+ };
48532
48874
  PartReader = class {
48533
48875
  /** messageID \u2192 part ids in arrival order, so a multi-part message keeps its order. */
48534
48876
  #order = /* @__PURE__ */ new Map();
@@ -48538,6 +48880,7 @@ var init_opencode = __esm({
48538
48880
  /** To-do calls already sent as a plan; the running and completed frames repeat the input. */
48539
48881
  #planned = /* @__PURE__ */ new Set();
48540
48882
  #steps = /* @__PURE__ */ new Set();
48883
+ #turnUsage = NO_USAGE;
48541
48884
  #partIds = /* @__PURE__ */ new Set();
48542
48885
  #anonymous = 0;
48543
48886
  #retainedChars = 0;
@@ -48552,6 +48895,9 @@ var init_opencode = __esm({
48552
48895
  }
48553
48896
  /** `provider/model` from the assistant message; step-finish frames do not repeat it. */
48554
48897
  model;
48898
+ /** The model's context limit, when the server listed it. */
48899
+ contextWindow;
48900
+ #contextTokens;
48555
48901
  part(part, parentToolCallId) {
48556
48902
  const id = asString(part.id);
48557
48903
  if (id) this.#partIds.add(id);
@@ -48560,7 +48906,7 @@ var init_opencode = __esm({
48560
48906
  "protocol_violation",
48561
48907
  "Alan Code exceeded the retained event limit. Continue in a new turn."
48562
48908
  );
48563
- return withParent(this.#read(part), parentToolCallId);
48909
+ return withParent(this.#read(part, parentToolCallId !== void 0), parentToolCallId);
48564
48910
  }
48565
48911
  /** A delta names only its part; the role and message come from the part's opening snapshot. */
48566
48912
  delta(partId, field3, delta, parentToolCallId) {
@@ -48572,7 +48918,7 @@ var init_opencode = __esm({
48572
48918
  const update = role === "text" ? { sessionUpdate: "agent_message_chunk", messageId, content } : { sessionUpdate: "agent_thought_chunk", messageId: `${messageId}:reasoning`, content };
48573
48919
  return withParent([update], parentToolCallId);
48574
48920
  }
48575
- #read(part) {
48921
+ #read(part, child) {
48576
48922
  const type = asString(part.type);
48577
48923
  switch (type) {
48578
48924
  case "step-start":
@@ -48588,7 +48934,7 @@ var init_opencode = __esm({
48588
48934
  return this.#tool(part);
48589
48935
  case "step-finish":
48590
48936
  case "step_finish":
48591
- return this.#stepFinish(part);
48937
+ return this.#stepFinish(part, child);
48592
48938
  case "snapshot":
48593
48939
  case "patch":
48594
48940
  return [];
@@ -48654,6 +49000,31 @@ var init_opencode = __esm({
48654
49000
  }
48655
49001
  return updates;
48656
49002
  }
49003
+ #stepUsage(part, tokens2, child) {
49004
+ const cache2 = asRecord(tokens2.cache);
49005
+ const step = {
49006
+ inputTokens: asFiniteNumber(tokens2.input) ?? 0,
49007
+ // OpenCode counts reasoning apart from output, and cache apart from input.
49008
+ outputTokens: (asFiniteNumber(tokens2.output) ?? 0) + (asFiniteNumber(tokens2.reasoning) ?? 0),
49009
+ cacheReadTokens: asFiniteNumber(cache2?.read) ?? 0,
49010
+ cacheCreationTokens: asFiniteNumber(cache2?.write) ?? 0
49011
+ };
49012
+ if (!child) this.#contextTokens = stepContextTokens(step, asFiniteNumber(tokens2.total));
49013
+ this.#turnUsage = addStepUsage(this.#turnUsage, {
49014
+ ...step,
49015
+ costUsd: asFiniteNumber(part.cost)
49016
+ });
49017
+ const { costUsd, ...turnTokens } = this.#turnUsage;
49018
+ return usageUpdate(
49019
+ {
49020
+ ...turnTokens,
49021
+ ...costUsd === void 0 ? {} : { costUsd },
49022
+ ...this.#contextTokens === void 0 ? {} : { contextTokens: this.#contextTokens },
49023
+ ...this.contextWindow === void 0 ? {} : { contextSize: this.contextWindow }
49024
+ },
49025
+ this.model
49026
+ );
49027
+ }
48657
49028
  /** OpenCode's to-do list is the plan, sent once per call although every frame repeats it. */
48658
49029
  #plan(toolCallId, name, toolState) {
48659
49030
  const todos = asRecord(toolState?.input)?.todos;
@@ -48662,28 +49033,12 @@ var init_opencode = __esm({
48662
49033
  this.#planned.add(toolCallId);
48663
49034
  return [todoPlanUpdate(toolCallId, todos)];
48664
49035
  }
48665
- #stepFinish(part) {
49036
+ #stepFinish(part, child) {
48666
49037
  const id = asString(part.id);
48667
49038
  if (id && this.#steps.has(id)) return [];
48668
49039
  if (id) this.#steps.add(id);
48669
- const updates = [];
48670
49040
  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
- }
49041
+ const updates = tokens2 ? [this.#stepUsage(part, tokens2, child)] : [];
48687
49042
  const reason = asString(part.reason);
48688
49043
  if (reason === "stop") {
48689
49044
  updates.push({ sessionUpdate: "state_update", state: "idle", stopReason: "end_turn" });
@@ -48868,7 +49223,10 @@ var init_opencode = __esm({
48868
49223
  if (finish) this.#finish = finish;
48869
49224
  const provider4 = asString(info.providerID);
48870
49225
  const model = asString(info.modelID);
48871
- if (provider4 && model) this.#parts.model = `${provider4}/${model}`;
49226
+ if (provider4 && model) {
49227
+ this.#parts.model = `${provider4}/${model}`;
49228
+ this.#parts.contextWindow = this.#memory.contextWindows.get(this.#parts.model);
49229
+ }
48872
49230
  const error62 = asRecord(info.error);
48873
49231
  if (!error62 || isAbortError(error62) || this.#error) return [];
48874
49232
  return this.#fail(classifyOpenCodeError(error62, `${this.#engine.label} session error.`));
@@ -49073,6 +49431,9 @@ var init_opencode = __esm({
49073
49431
  /** Subscribes before the session exists, so `session.created` and early asks are seen. */
49074
49432
  async connect(client) {
49075
49433
  this.#client = client;
49434
+ client.modelContextWindows().then((windows) => {
49435
+ this.#memory.contextWindows = windows;
49436
+ }).catch(() => void 0);
49076
49437
  this.#events?.close();
49077
49438
  this.#events = await client.events({
49078
49439
  onEvent: (event) => {
@@ -49481,7 +49842,9 @@ function createAlanCodeHolderDriver(options) {
49481
49842
  });
49482
49843
  const env = options.cliEnvironment;
49483
49844
  const engine = resolveAlanCodeEngine({ env, platform: platform3, packaged: [] });
49484
- const engineRoot = alanCodeEngineRoot(env.HOME?.trim() || (0, import_node_os7.homedir)());
49845
+ const home = env.HOME?.trim() || (0, import_node_os7.homedir)();
49846
+ const engineRoot = alanCodeEngineRoot(home);
49847
+ const globalConfigDirectory = openCodeGlobalConfigDirectory(env, home);
49485
49848
  options.log.info("alan_code.engine", { command: engine.command, source: engine.source });
49486
49849
  const open6 = async (planned) => {
49487
49850
  if (planned.profile === void 0) throw refuseWithoutCredential();
@@ -49519,6 +49882,7 @@ function createAlanCodeHolderDriver(options) {
49519
49882
  conversationId: spec.conversationId
49520
49883
  },
49521
49884
  engineRoot,
49885
+ globalConfigDirectory,
49522
49886
  requestedModel: spec.model
49523
49887
  };
49524
49888
  const skills = options.installedSkills?.() ?? null;
@@ -50166,8 +50530,8 @@ var import_crypto18, import_promises53, FACTORY_API_VERSION, FACTORY_PROTOCOL_VE
50166
50530
  var init_droid = __esm({
50167
50531
  "../agent-core/dist/providers/droid.js"() {
50168
50532
  "use strict";
50169
- init_chunk_WD7O4DYQ();
50170
- init_chunk_OUEMTEUX();
50533
+ init_chunk_N2M5D7RS();
50534
+ init_chunk_RBQC7XZH();
50171
50535
  init_chunk_ZCTKXKYY();
50172
50536
  init_chunk_6VWVDJ2A();
50173
50537
  init_chunk_DLVRNIY5();
@@ -50212,7 +50576,10 @@ var init_droid = __esm({
50212
50576
  const notification = asRecord(params.notification);
50213
50577
  if (!notification) return [];
50214
50578
  const sessionId = asString(params.sessionId);
50215
- if (!sessionId || sessionId === this.#sessionId) return this.#read(notification);
50579
+ if (!sessionId || sessionId === this.#sessionId) {
50580
+ this.#noteContext(notification);
50581
+ return this.#read(notification);
50582
+ }
50216
50583
  const launcher = this.#memory.childLaunchers.get(sessionId);
50217
50584
  if (!launcher) return [];
50218
50585
  return this.#read(notification).map(
@@ -50222,6 +50589,14 @@ var init_droid = __esm({
50222
50589
  })
50223
50590
  );
50224
50591
  }
50592
+ /** Droid's own context figure: the last call's input, cache reads and output. */
50593
+ #noteContext(notification) {
50594
+ if (asString(notification.type) !== "session_token_usage_changed") return;
50595
+ const last = asRecord(notification.lastCallTokenUsage);
50596
+ if (!last) return;
50597
+ const tokens2 = (asFiniteNumber(last.inputTokens) ?? 0) + (asFiniteNumber(last.cacheReadTokens) ?? 0) + (asFiniteNumber(last.outputTokens) ?? 0);
50598
+ if (tokens2 > 0) this.#memory.contextTokens = tokens2;
50599
+ }
50225
50600
  #read(notification) {
50226
50601
  const type = asString(notification.type);
50227
50602
  if (SILENT2.has(type)) return [];
@@ -50296,6 +50671,7 @@ var init_droid = __esm({
50296
50671
  cacheCreationTokens: number4(usage?.cacheCreationTokens),
50297
50672
  numTurns: 1,
50298
50673
  ...duration3 === void 0 ? {} : { durationMs: duration3 },
50674
+ ...this.#memory.contextTokens === void 0 ? {} : { contextTokens: this.#memory.contextTokens },
50299
50675
  costUsd: 0
50300
50676
  },
50301
50677
  this.#memory.model ?? "droid"
@@ -51104,6 +51480,23 @@ function providerError2(_grammar, frame) {
51104
51480
  function spellings(types, handle) {
51105
51481
  return types.map((type) => [type, handle]);
51106
51482
  }
51483
+ function stepTokens(stats) {
51484
+ return {
51485
+ inputTokens: firstNumber2(stats.input_tokens, stats.input),
51486
+ outputTokens: firstNumber2(stats.output_tokens) + firstNumber2(stats.thinking_tokens),
51487
+ cacheReadTokens: firstNumber2(stats.cache_read_tokens, stats.cached_input_tokens, stats.cached),
51488
+ cacheCreationTokens: 0
51489
+ };
51490
+ }
51491
+ function addStepTokens(total, step) {
51492
+ if (!total) return step;
51493
+ return {
51494
+ inputTokens: total.inputTokens + step.inputTokens,
51495
+ outputTokens: total.outputTokens + step.outputTokens,
51496
+ cacheReadTokens: total.cacheReadTokens + step.cacheReadTokens,
51497
+ cacheCreationTokens: total.cacheCreationTokens + step.cacheCreationTokens
51498
+ };
51499
+ }
51107
51500
  function firstNumber2(...values) {
51108
51501
  for (const value2 of values) {
51109
51502
  const number4 = asFiniteNumber(value2);
@@ -51275,9 +51668,9 @@ var import_promises54, import_path13, import_fs9, import_path14, import_path15,
51275
51668
  var init_antigravity = __esm({
51276
51669
  "../agent-core/dist/providers/antigravity.js"() {
51277
51670
  "use strict";
51278
- init_chunk_D4TIXPWZ();
51279
- init_chunk_WD7O4DYQ();
51280
- init_chunk_OUEMTEUX();
51671
+ init_chunk_TFIO37PI();
51672
+ init_chunk_N2M5D7RS();
51673
+ init_chunk_RBQC7XZH();
51281
51674
  init_chunk_ZCTKXKYY();
51282
51675
  init_chunk_6VWVDJ2A();
51283
51676
  init_chunk_DLVRNIY5();
@@ -51635,6 +52028,11 @@ var init_antigravity = __esm({
51635
52028
  /** What `--conversation` takes: a frame's `conversation_id` wins over its `session_id`. */
51636
52029
  #conversationId;
51637
52030
  #forkReported = false;
52031
+ /** The conversation this turn runs in; a subagent's steps come under another id. */
52032
+ #rootConversation;
52033
+ /** The sum of this turn's own steps: the result's usage is the whole conversation's. */
52034
+ #stepSpend;
52035
+ #contextTokens;
51638
52036
  constructor(options) {
51639
52037
  this.#options = options;
51640
52038
  this.#conversationId = options.resumeId;
@@ -51681,7 +52079,9 @@ var init_antigravity = __esm({
51681
52079
  const type = asString(frame.type);
51682
52080
  if (!type) return [];
51683
52081
  this.#conversationId = antigravityString(frame, "conversation_id") ?? antigravityString(frame, "session_id") ?? this.#conversationId;
52082
+ this.#rootConversation ??= this.#conversationId;
51684
52083
  this.#track(type, frame);
52084
+ this.#noteStep(type, frame);
51685
52085
  const forked = this.#silentFork();
51686
52086
  if (SESSION_START_TYPES.has(type)) {
51687
52087
  return [
@@ -51696,6 +52096,29 @@ var init_antigravity = __esm({
51696
52096
  if (RESULT_TYPES.has(type)) return [...forked, ...this.#onResult(type, frame)];
51697
52097
  return [...forked, ...this.#transcripts?.read() ?? []];
51698
52098
  }
52099
+ /** A finished answer step of this conversation: one model call, with its own usage. */
52100
+ #noteStep(type, frame) {
52101
+ if (type !== "assistant_message" || asString(frame.state).toUpperCase() !== "DONE") return;
52102
+ const usage = asRecord(frame.usage);
52103
+ if (!usage) return;
52104
+ const conversation = antigravityString(frame, "conversation_id");
52105
+ if (conversation && this.#rootConversation && conversation !== this.#rootConversation) return;
52106
+ const step = stepTokens(usage);
52107
+ this.#stepSpend = addStepTokens(this.#stepSpend, step);
52108
+ const context = step.inputTokens + step.cacheReadTokens + step.outputTokens;
52109
+ if (context > 0) this.#contextTokens = context;
52110
+ }
52111
+ /**
52112
+ * agy's result usage is cumulative over the conversation, so a resumed turn's spend comes
52113
+ * from its steps; a first turn's result is its own.
52114
+ */
52115
+ #turnSpend(frame) {
52116
+ const steps = this.#stepSpend;
52117
+ this.#stepSpend = void 0;
52118
+ if (steps) return steps;
52119
+ if (this.#options.resumeId) return void 0;
52120
+ return stepTokens(asRecord(frame.usage) ?? asRecord(frame.stats) ?? frame);
52121
+ }
51699
52122
  #track(type, frame) {
51700
52123
  const transcripts = this.#transcripts;
51701
52124
  if (!transcripts) return;
@@ -51713,6 +52136,22 @@ var init_antigravity = __esm({
51713
52136
  this.#forkReported = true;
51714
52137
  return [noticeUpdate("warning", "session_resume_failed", RESUME_FORKED)];
51715
52138
  }
52139
+ #resultUsage(frame) {
52140
+ const spend = this.#turnSpend(frame);
52141
+ const contextTokens = this.#contextTokens;
52142
+ if (!spend && contextTokens === void 0) return [];
52143
+ const stats = asRecord(frame.usage) ?? asRecord(frame.stats) ?? frame;
52144
+ return [
52145
+ usageUpdate({
52146
+ model: formatAntigravityModelName(this.#model()),
52147
+ numTurns: Math.max(this.#iterations, 1),
52148
+ durationMs: asFiniteNumber(stats.duration_ms) ?? 0,
52149
+ ...spend,
52150
+ ...contextTokens === void 0 ? {} : { contextTokens },
52151
+ costUsd: 0
52152
+ })
52153
+ ];
52154
+ }
51716
52155
  #onResult(type, frame) {
51717
52156
  const updates = [];
51718
52157
  this.#iterations = Math.max(this.#iterations, asFiniteNumber(frame.num_turns) ?? 1);
@@ -51721,23 +52160,7 @@ var init_antigravity = __esm({
51721
52160
  updates.push(agentText(`antigravity-${this.#conversationId ?? "run"}-result`, resultText3));
51722
52161
  this.#resultShown = true;
51723
52162
  }
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
- );
52163
+ updates.push(...this.#resultUsage(frame));
51741
52164
  const status = asString(frame.status).toLowerCase();
51742
52165
  const succeeded = !status || SUCCESSFUL_STATUSES.has(status);
51743
52166
  if (succeeded) {
@@ -51980,8 +52403,8 @@ var import_promises55, import_path16, import_crypto20, COMMAND_CODE_GRAMMAR_NAME
51980
52403
  var init_command_code = __esm({
51981
52404
  "../agent-core/dist/providers/command-code.js"() {
51982
52405
  "use strict";
51983
- init_chunk_WD7O4DYQ();
51984
- init_chunk_OUEMTEUX();
52406
+ init_chunk_N2M5D7RS();
52407
+ init_chunk_RBQC7XZH();
51985
52408
  init_chunk_ZCTKXKYY();
51986
52409
  init_chunk_6VWVDJ2A();
51987
52410
  init_chunk_DLVRNIY5();
@@ -52346,6 +52769,7 @@ var init_command_code = __esm({
52346
52769
  #streamed = false;
52347
52770
  #totals;
52348
52771
  #result;
52772
+ #contextTokens;
52349
52773
  constructor(options) {
52350
52774
  this.#options = options;
52351
52775
  if (options.resumeId) this.#grammar.sessionId = options.resumeId;
@@ -52388,6 +52812,8 @@ var init_command_code = __esm({
52388
52812
  #onEvent(event) {
52389
52813
  switch (commandCodeString(event.type)) {
52390
52814
  case "model_request_end":
52815
+ this.#noteContext(event.usage);
52816
+ return this.#usage(event.usage);
52391
52817
  case "turn_end":
52392
52818
  return this.#usage(event.usage);
52393
52819
  case "run_end": {
@@ -52439,7 +52865,28 @@ var init_command_code = __esm({
52439
52865
  durationMs: durationMs ?? previous?.durationMs ?? 0
52440
52866
  };
52441
52867
  this.#totals = totals;
52442
- return [usageUpdate({ model: this.#model(), numTurns: 1, ...totals, costUsd: 0 })];
52868
+ return [
52869
+ usageUpdate({
52870
+ model: this.#model(),
52871
+ numTurns: 1,
52872
+ ...totals,
52873
+ // Command Code's own cost estimate takes cache out of inputTokens, which counts it.
52874
+ inputTokens: Math.max(
52875
+ totals.inputTokens - totals.cacheReadTokens - totals.cacheCreationTokens,
52876
+ 0
52877
+ ),
52878
+ ...this.#contextTokens === void 0 ? {} : { contextTokens: this.#contextTokens },
52879
+ costUsd: 0
52880
+ })
52881
+ ];
52882
+ }
52883
+ /** One model call's prompt, cache included, plus its reply: what it left in the window. */
52884
+ #noteContext(usage) {
52885
+ const record2 = asRecord(usage);
52886
+ const input2 = asFiniteNumber(record2?.inputTokens) ?? asFiniteNumber(record2?.input_tokens);
52887
+ if (input2 === void 0 || input2 <= 0) return;
52888
+ const output2 = asFiniteNumber(record2?.outputTokens) ?? asFiniteNumber(record2?.output_tokens);
52889
+ this.#contextTokens = input2 + (output2 ?? 0);
52443
52890
  }
52444
52891
  };
52445
52892
  COMMAND_CODE_MAX_TURNS = 1e4;
@@ -57383,7 +57830,7 @@ var require_websocket_server = __commonJS({
57383
57830
  // package.json
57384
57831
  var package_default = {
57385
57832
  name: "@alan-ai-hq/agent-manager",
57386
- version: "0.1.160",
57833
+ version: "0.1.162",
57387
57834
  private: true,
57388
57835
  type: "module",
57389
57836
  description: "Alan machine runtime (alan-agent): identity, link, reconciler, session holders, run log, uploader, local API",
@@ -58890,15 +59337,15 @@ var BRANCH_LABEL_MAX_LENGTH = 256;
58890
59337
  var HASH_OBJECT_BATCH = 128;
58891
59338
  function countPorcelainEntries(output2) {
58892
59339
  const records = output2.split("\0");
58893
- let count = 0;
59340
+ let count2 = 0;
58894
59341
  for (let index = 0; index < records.length; index += 1) {
58895
59342
  const record2 = records[index];
58896
59343
  if (!record2) continue;
58897
- count += 1;
59344
+ count2 += 1;
58898
59345
  const status = record2.slice(0, 2);
58899
59346
  if (status.includes("R") || status.includes("C")) index += 1;
58900
59347
  }
58901
- return count;
59348
+ return count2;
58902
59349
  }
58903
59350
  function sanitizeBranch(value2) {
58904
59351
  const printable = Array.from(value2.trim()).filter((character) => {
@@ -60863,6 +61310,7 @@ function runtimePaths(stateDir) {
60863
61310
 
60864
61311
  // src/platform/process-memory.ts
60865
61312
  var import_node_child_process4 = require("child_process");
61313
+ var import_node_fs7 = require("fs");
60866
61314
  var import_promises16 = require("fs/promises");
60867
61315
  var import_node_os2 = require("os");
60868
61316
  var import_node_util3 = require("util");
@@ -60930,12 +61378,52 @@ function readMemoryPressure() {
60930
61378
  if (process.platform === "linux") return linuxPressure();
60931
61379
  return Promise.resolve("normal");
60932
61380
  }
61381
+ function parseDarwinVmStat(output2) {
61382
+ const pageSize = Number(/page size of (\d+) bytes/.exec(output2)?.[1]);
61383
+ if (!Number.isFinite(pageSize) || pageSize <= 0) return null;
61384
+ const pages = (name) => {
61385
+ const match = new RegExp(`^Pages ${name}:\\s+(\\d+)\\.?$`, "m").exec(output2);
61386
+ return match ? Number(match[1]) : null;
61387
+ };
61388
+ const free = pages("free");
61389
+ if (free === null) return null;
61390
+ return (free + (pages("inactive") ?? 0) + (pages("speculative") ?? 0)) * pageSize;
61391
+ }
61392
+ function parseLinuxMemInfo(output2) {
61393
+ const kilobytes = /^MemAvailable:\s+(\d+)\s+kB$/m.exec(output2)?.[1];
61394
+ return kilobytes === void 0 ? null : Number(kilobytes) * 1024;
61395
+ }
61396
+ var CAPACITY_PROBE_TTL_MS = 2e3;
61397
+ var AvailableMemoryProbe = class {
61398
+ cached = null;
61399
+ read(now) {
61400
+ if (this.cached !== null && now - this.cached.at < CAPACITY_PROBE_TTL_MS) {
61401
+ return this.cached.bytes;
61402
+ }
61403
+ let bytes = null;
61404
+ try {
61405
+ if (process.platform === "darwin") {
61406
+ bytes = parseDarwinVmStat(
61407
+ (0, import_node_child_process4.execFileSync)("vm_stat", { encoding: "utf8", timeout: PROBE_TIMEOUT_MS })
61408
+ );
61409
+ } else if (process.platform === "linux") {
61410
+ bytes = parseLinuxMemInfo((0, import_node_fs7.readFileSync)("/proc/meminfo", "utf8"));
61411
+ }
61412
+ } catch {
61413
+ bytes = null;
61414
+ }
61415
+ this.cached = { at: now, bytes };
61416
+ return bytes;
61417
+ }
61418
+ };
61419
+ var availableMemoryProbe = new AvailableMemoryProbe();
60933
61420
  function readMemoryCapacity() {
60934
61421
  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
- };
61422
+ const totalBytes = constrained > 0 ? Math.min((0, import_node_os2.totalmem)(), constrained) : (0, import_node_os2.totalmem)();
61423
+ const reported = typeof process.availableMemory === "function" ? process.availableMemory() : (0, import_node_os2.freemem)();
61424
+ const probed = constrained > 0 && process.platform === "linux" ? null : availableMemoryProbe.read(Date.now());
61425
+ const availableBytes = Math.min(totalBytes, Math.max(reported, probed ?? reported));
61426
+ return { totalBytes, availableBytes };
60939
61427
  }
60940
61428
  async function processMemoryRows() {
60941
61429
  if (process.platform === "win32") {
@@ -61415,7 +61903,7 @@ var import_promises20 = require("fs/promises");
61415
61903
  var import_node_path17 = require("path");
61416
61904
 
61417
61905
  // src/platform/service/windows-service.ts
61418
- var import_node_fs7 = require("fs");
61906
+ var import_node_fs8 = require("fs");
61419
61907
  var import_promises19 = require("fs/promises");
61420
61908
  var import_node_path16 = require("path");
61421
61909
 
@@ -61645,7 +62133,7 @@ function windowsManager(host, profile) {
61645
62133
  name: files.runValue,
61646
62134
  definitionPath: files.config,
61647
62135
  install: async (spec, { restart }) => {
61648
- if (process.platform === "win32" && !(0, import_node_fs7.existsSync)(files.helper)) {
62136
+ if (process.platform === "win32" && !(0, import_node_fs8.existsSync)(files.helper)) {
61649
62137
  throw new RuntimeFault("io_failed", `Windows helper is missing: ${files.helper}`);
61650
62138
  }
61651
62139
  await (0, import_promises19.mkdir)((0, import_node_path16.dirname)(spec.logPath), { recursive: true });
@@ -62340,7 +62828,7 @@ function systemAssertionSpawner(log) {
62340
62828
  // src/platform/spawn-detached.ts
62341
62829
  var import_node_child_process8 = require("child_process");
62342
62830
  var import_node_crypto12 = require("crypto");
62343
- var import_node_fs8 = require("fs");
62831
+ var import_node_fs9 = require("fs");
62344
62832
  var import_node_path21 = require("path");
62345
62833
  var WINDOWS_UNSAFE_ENV = "NODE_PENDING_PIPE_INSTANCES";
62346
62834
  var SYSTEMD_RUN = "systemd-run";
@@ -62395,8 +62883,8 @@ function isolatedCommand(request2, isolation) {
62395
62883
  };
62396
62884
  }
62397
62885
  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);
62886
+ (0, import_node_fs9.mkdirSync)((0, import_node_path21.dirname)(request2.outputPath), { recursive: true, mode: 448 });
62887
+ const output2 = (0, import_node_fs9.openSync)(request2.outputPath, "a", 384);
62400
62888
  const { command, args } = isolatedCommand(request2, isolation);
62401
62889
  try {
62402
62890
  const child = (0, import_node_child_process8.spawn)(command, args, {
@@ -62412,7 +62900,7 @@ function spawnDetached(request2, isolation) {
62412
62900
  child.unref();
62413
62901
  return { pid: child.pid };
62414
62902
  } finally {
62415
- (0, import_node_fs8.closeSync)(output2);
62903
+ (0, import_node_fs9.closeSync)(output2);
62416
62904
  }
62417
62905
  }
62418
62906
 
@@ -62452,7 +62940,7 @@ function createUpdateGate(deps) {
62452
62940
 
62453
62941
  // src/platform/wake-clock.ts
62454
62942
  var import_node_child_process9 = require("child_process");
62455
- var import_node_fs9 = require("fs");
62943
+ var import_node_fs10 = require("fs");
62456
62944
  var import_node_readline = require("readline");
62457
62945
  var PTP_DEVICE = "/dev/ptp0";
62458
62946
  var RESPAWN_BASE_MS = 1e3;
@@ -62536,7 +63024,7 @@ function systemWakeClockSpawner(log) {
62536
63024
  function startWakeClock(options) {
62537
63025
  const { clock, log } = options;
62538
63026
  const platform3 = options.platform ?? process.platform;
62539
- const hasPtpDevice = options.hasPtpDevice ?? (() => (0, import_node_fs9.existsSync)(PTP_DEVICE));
63027
+ const hasPtpDevice = options.hasPtpDevice ?? (() => (0, import_node_fs10.existsSync)(PTP_DEVICE));
62540
63028
  if (platform3 !== "linux" || !hasPtpDevice()) return { [Symbol.dispose]: () => {
62541
63029
  } };
62542
63030
  const spawner = options.spawner ?? systemWakeClockSpawner(log);
@@ -64670,7 +65158,7 @@ function fingerprintWholeText(fingerprint) {
64670
65158
  }
64671
65159
 
64672
65160
  // src/capabilities/native-ingest/hook-config.ts
64673
- var import_node_fs10 = require("fs");
65161
+ var import_node_fs11 = require("fs");
64674
65162
  var import_node_path28 = require("path");
64675
65163
 
64676
65164
  // src/capabilities/native-ingest/provider-paths.ts
@@ -64748,9 +65236,9 @@ function hookHandler(provider4, event, options) {
64748
65236
  return { type: "command", command: posixCommand(argv, environment), timeout: 5 };
64749
65237
  }
64750
65238
  function readSettings(path4, backupWhenMalformed, now) {
64751
- if (!(0, import_node_fs10.existsSync)(path4)) return {};
65239
+ if (!(0, import_node_fs11.existsSync)(path4)) return {};
64752
65240
  try {
64753
- const value2 = JSON.parse((0, import_node_fs10.readFileSync)(path4, "utf8"));
65241
+ const value2 = JSON.parse((0, import_node_fs11.readFileSync)(path4, "utf8"));
64754
65242
  if (!isRecord4(value2)) throw new Error("settings root must be an object");
64755
65243
  if (value2.hooks !== void 0 && !isRecord4(value2.hooks)) {
64756
65244
  throw new Error("settings `hooks` must be an object");
@@ -64760,7 +65248,7 @@ function readSettings(path4, backupWhenMalformed, now) {
64760
65248
  const reason = error62 instanceof Error ? error62.message : String(error62);
64761
65249
  if (!backupWhenMalformed) throw new Error(`${path4} is malformed: ${reason}`);
64762
65250
  const backup = `${path4}.malformed-${now}.bak`;
64763
- (0, import_node_fs10.copyFileSync)(path4, backup);
65251
+ (0, import_node_fs11.copyFileSync)(path4, backup);
64764
65252
  throw new Error(`${path4} is malformed and was copied to ${backup}: ${reason}`);
64765
65253
  }
64766
65254
  }
@@ -64768,14 +65256,14 @@ function hooksOf(settings2) {
64768
65256
  return isRecord4(settings2.hooks) ? settings2.hooks : {};
64769
65257
  }
64770
65258
  function writeSettings(path4, settings2) {
64771
- (0, import_node_fs10.mkdirSync)((0, import_node_path28.dirname)(path4), { recursive: true, mode: 448 });
65259
+ (0, import_node_fs11.mkdirSync)((0, import_node_path28.dirname)(path4), { recursive: true, mode: 448 });
64772
65260
  const temporary = `${path4}.${process.pid}.tmp`;
64773
65261
  try {
64774
- (0, import_node_fs10.writeFileSync)(temporary, `${JSON.stringify(settings2, null, 2)}
65262
+ (0, import_node_fs11.writeFileSync)(temporary, `${JSON.stringify(settings2, null, 2)}
64775
65263
  `, { mode: 384 });
64776
- (0, import_node_fs10.renameSync)(temporary, path4);
65264
+ (0, import_node_fs11.renameSync)(temporary, path4);
64777
65265
  } finally {
64778
- (0, import_node_fs10.rmSync)(temporary, { force: true });
65266
+ (0, import_node_fs11.rmSync)(temporary, { force: true });
64779
65267
  }
64780
65268
  }
64781
65269
  function isIngestionHandler(handler) {
@@ -64820,7 +65308,7 @@ function installIngestionHooks(provider4, options, now) {
64820
65308
  }
64821
65309
  function removeIngestionHooks(provider4, where, now) {
64822
65310
  const path4 = providerHookSettingsPath(provider4, where);
64823
- if (!(0, import_node_fs10.existsSync)(path4)) return { provider: provider4, path: path4, changed: false };
65311
+ if (!(0, import_node_fs11.existsSync)(path4)) return { provider: provider4, path: path4, changed: false };
64824
65312
  const settings2 = readSettings(path4, true, now);
64825
65313
  const hooks = hooksOf(settings2);
64826
65314
  const nextHooks = {};
@@ -64857,7 +65345,7 @@ function ingestionHookStatus(provider4, options) {
64857
65345
  }
64858
65346
 
64859
65347
  // src/capabilities/native-ingest/hook-input.ts
64860
- var import_node_fs11 = require("fs");
65348
+ var import_node_fs12 = require("fs");
64861
65349
  var import_node_path29 = require("path");
64862
65350
  var ALAN_MANAGED_SESSION_ENV = "ALAN_MANAGED_SESSION";
64863
65351
  var MAX_HOOK_STDIN_BYTES = 256 * 1024 * 1024;
@@ -64887,17 +65375,17 @@ function codexSessionIdFromTranscriptPath(transcriptPath) {
64887
65375
  );
64888
65376
  return match?.[1] ?? null;
64889
65377
  }
64890
- function lastBytes(chunks, count) {
65378
+ function lastBytes(chunks, count2) {
64891
65379
  const kept = [];
64892
65380
  let size = 0;
64893
- for (let index = chunks.length - 1; index >= 0 && size < count; index -= 1) {
65381
+ for (let index = chunks.length - 1; index >= 0 && size < count2; index -= 1) {
64894
65382
  const chunk = chunks[index];
64895
65383
  if (chunk === void 0) continue;
64896
65384
  kept.unshift(chunk);
64897
65385
  size += chunk.length;
64898
65386
  }
64899
65387
  const joined = Buffer.concat(kept);
64900
- return joined.subarray(Math.max(0, joined.length - count));
65388
+ return joined.subarray(Math.max(0, joined.length - count2));
64901
65389
  }
64902
65390
  async function readHookStdin(stream, maxBytes = MAX_HOOK_STDIN_BYTES) {
64903
65391
  const chunks = [];
@@ -64957,10 +65445,10 @@ function hookPayload(input2) {
64957
65445
  }
64958
65446
  function realpathOrSelf(path4) {
64959
65447
  try {
64960
- return (0, import_node_fs11.realpathSync)(path4);
65448
+ return (0, import_node_fs12.realpathSync)(path4);
64961
65449
  } catch {
64962
65450
  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));
65451
+ return (0, import_node_path29.join)((0, import_node_fs12.realpathSync)((0, import_node_path29.dirname)(path4)), (0, import_node_path29.basename)(path4));
64964
65452
  } catch {
64965
65453
  return path4;
64966
65454
  }
@@ -64991,7 +65479,7 @@ function parseHookSignal(input2) {
64991
65479
  }
64992
65480
 
64993
65481
  // src/capabilities/native-ingest/ingest.ts
64994
- var import_node_fs12 = require("fs");
65482
+ var import_node_fs13 = require("fs");
64995
65483
 
64996
65484
  // ../shared/dist/types/native-agent-session.js
64997
65485
  var nativeAgentProviderBackendKinds = {
@@ -65761,7 +66249,7 @@ function workerKey(provider4, externalSessionId) {
65761
66249
  return `${provider4}\0${externalSessionId}`;
65762
66250
  }
65763
66251
  function holdFor(entry) {
65764
- const stats = (0, import_node_fs12.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
66252
+ const stats = (0, import_node_fs13.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
65765
66253
  if (!stats) return [];
65766
66254
  return [
65767
66255
  {
@@ -65962,7 +66450,7 @@ async function startNativeIngest(deps) {
65962
66450
  return "accepted";
65963
66451
  };
65964
66452
  const hasUnreadBytes = (entry, now) => {
65965
- const stats = (0, import_node_fs12.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
66453
+ const stats = (0, import_node_fs13.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
65966
66454
  if (!stats || now - Number(stats.mtimeMs) > timing.sweepRecencyMs) return false;
65967
66455
  const replaced = String(stats.dev) !== entry.device || String(stats.ino) !== entry.inode;
65968
66456
  return replaced || Number(stats.size) > entry.cursor.offset;
@@ -66006,7 +66494,7 @@ async function startNativeIngest(deps) {
66006
66494
  const recordAlanRun = async (hold, runId) => {
66007
66495
  const entry = store.get(hold.provider, hold.externalSessionId);
66008
66496
  if (!entry || entry.dead) return;
66009
- const stats = (0, import_node_fs12.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
66497
+ const stats = (0, import_node_fs13.statSync)(entry.transcriptPath, { bigint: true, throwIfNoEntry: false });
66010
66498
  if (!stats) return;
66011
66499
  const identity = { device: String(stats.dev), inode: String(stats.ino) };
66012
66500
  const size = Number(stats.size);
@@ -66080,7 +66568,7 @@ async function startNativeIngest(deps) {
66080
66568
  init_alan_code();
66081
66569
 
66082
66570
  // src/capabilities/providers/commands.ts
66083
- var import_node_fs13 = require("fs");
66571
+ var import_node_fs14 = require("fs");
66084
66572
  var import_promises35 = require("fs/promises");
66085
66573
  var import_node_path32 = require("path");
66086
66574
  var PROVIDER_COMMANDS = [
@@ -66118,7 +66606,7 @@ function pathDelimiter(platform3) {
66118
66606
  async function isRunnable(path4, platform3) {
66119
66607
  try {
66120
66608
  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);
66609
+ if (platform3 !== "win32") await (0, import_promises35.access)(path4, import_node_fs14.constants.X_OK);
66122
66610
  return true;
66123
66611
  } catch {
66124
66612
  return false;
@@ -66301,7 +66789,7 @@ init_runtime_v2();
66301
66789
 
66302
66790
  // src/capabilities/providers/account-label.ts
66303
66791
  var import_node_child_process12 = require("child_process");
66304
- var import_node_fs14 = require("fs");
66792
+ var import_node_fs15 = require("fs");
66305
66793
  var import_node_path33 = require("path");
66306
66794
  var import_node_url3 = require("url");
66307
66795
  var ACCOUNT_TIMEOUT_MS = 2e4;
@@ -66404,7 +66892,7 @@ async function claudeLabel(executable, env) {
66404
66892
  const childEnv = { ...env };
66405
66893
  delete childEnv.FORCE_CODE_TERMINAL;
66406
66894
  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";
66895
+ const sdkSpecifier = (0, import_node_fs15.existsSync)(bundledSdk) ? (0, import_node_url3.pathToFileURL)(bundledSdk).href : "@anthropic-ai/claude-agent-sdk";
66408
66896
  const { query } = await import(sdkSpecifier);
66409
66897
  const session = query({
66410
66898
  prompt: idlePrompt(abort.signal),
@@ -66814,7 +67302,7 @@ var import_node_path37 = require("path");
66814
67302
  // ../shared/dist/node/shell-environment.js
66815
67303
  var import_node_child_process13 = require("child_process");
66816
67304
  var import_node_crypto16 = require("crypto");
66817
- var import_node_fs16 = require("fs");
67305
+ var import_node_fs17 = require("fs");
66818
67306
  var import_node_os6 = require("os");
66819
67307
  var import_node_path36 = require("path");
66820
67308
 
@@ -66823,7 +67311,7 @@ var import_node_os5 = require("os");
66823
67311
  var import_node_path35 = require("path");
66824
67312
 
66825
67313
  // ../shared/dist/node/version-manager-paths.js
66826
- var import_node_fs15 = require("fs");
67314
+ var import_node_fs16 = require("fs");
66827
67315
  var import_node_path34 = require("path");
66828
67316
  function compareNodeVersionsDesc(a, b) {
66829
67317
  const parse7 = (value2) => value2.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10) || 0);
@@ -66838,19 +67326,19 @@ function compareNodeVersionsDesc(a, b) {
66838
67326
  }
66839
67327
  function resolveNvmDefaultBin(home) {
66840
67328
  const versionsDir = (0, import_node_path34.join)(home, ".nvm", "versions", "node");
66841
- if (!(0, import_node_fs15.existsSync)(versionsDir))
67329
+ if (!(0, import_node_fs16.existsSync)(versionsDir))
66842
67330
  return null;
66843
67331
  let alias = null;
66844
67332
  try {
66845
67333
  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();
67334
+ if ((0, import_node_fs16.existsSync)(aliasFile))
67335
+ alias = (0, import_node_fs16.readFileSync)(aliasFile, "utf8").trim();
66848
67336
  } catch {
66849
67337
  alias = null;
66850
67338
  }
66851
67339
  let installed;
66852
67340
  try {
66853
- installed = (0, import_node_fs15.readdirSync)(versionsDir).filter((entry) => entry.startsWith("v"));
67341
+ installed = (0, import_node_fs16.readdirSync)(versionsDir).filter((entry) => entry.startsWith("v"));
66854
67342
  } catch {
66855
67343
  return null;
66856
67344
  }
@@ -66861,7 +67349,7 @@ function resolveNvmDefaultBin(home) {
66861
67349
  if (!chosen)
66862
67350
  return null;
66863
67351
  const bin = (0, import_node_path34.join)(versionsDir, chosen, "bin");
66864
- return (0, import_node_fs15.existsSync)(bin) ? bin : null;
67352
+ return (0, import_node_fs16.existsSync)(bin) ? bin : null;
66865
67353
  }
66866
67354
  function resolveVersionManagerBinDirs(home, platform3 = process.platform) {
66867
67355
  if (platform3 === "win32")
@@ -66880,7 +67368,7 @@ function resolveVersionManagerBinDirs(home, platform3 = process.platform) {
66880
67368
  if (!dir || seen.has(dir))
66881
67369
  continue;
66882
67370
  seen.add(dir);
66883
- if ((0, import_node_fs15.existsSync)(dir))
67371
+ if ((0, import_node_fs16.existsSync)(dir))
66884
67372
  resolved.push(dir);
66885
67373
  }
66886
67374
  return resolved;
@@ -66922,7 +67410,7 @@ function promoteUserBinDirs(path4, home, versionManagerDirs) {
66922
67410
  // ../shared/dist/node/shell-environment.js
66923
67411
  function isExecutableFile(path4) {
66924
67412
  try {
66925
- (0, import_node_fs16.accessSync)(path4, import_node_fs16.constants.X_OK);
67413
+ (0, import_node_fs17.accessSync)(path4, import_node_fs17.constants.X_OK);
66926
67414
  return true;
66927
67415
  } catch {
66928
67416
  return false;
@@ -68832,7 +69320,7 @@ async function publishLocalSkill(options) {
68832
69320
 
68833
69321
  // src/capabilities/skills/native-index.ts
68834
69322
  var import_node_crypto23 = require("crypto");
68835
- var import_node_fs17 = require("fs");
69323
+ var import_node_fs18 = require("fs");
68836
69324
  var import_promises45 = require("fs/promises");
68837
69325
  var import_node_path45 = require("path");
68838
69326
  var ALAN_SKILLS_PLUGIN_NAME = "alan";
@@ -68983,7 +69471,7 @@ async function reconcileNativeIndex(layout, installed, options) {
68983
69471
  };
68984
69472
  }
68985
69473
  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;
69474
+ 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
69475
  }
68988
69476
 
68989
69477
  // src/capabilities/skills/sync.ts
@@ -70872,10 +71360,10 @@ async function reapLeftoverEngines(path4, options) {
70872
71360
  }
70873
71361
 
70874
71362
  // src/holder/launch-command.ts
70875
- var import_node_fs18 = require("fs");
71363
+ var import_node_fs19 = require("fs");
70876
71364
  var import_node_path53 = require("path");
70877
71365
  var HOLDER_BUNDLE = "alan-holder.cjs";
70878
- function holderArguments(runtimeArgs, nodeFlags, exists6 = import_node_fs18.existsSync) {
71366
+ function holderArguments(runtimeArgs, nodeFlags, exists6 = import_node_fs19.existsSync) {
70879
71367
  const bundle = runtimeArgs.at(-1);
70880
71368
  const lean = bundle === void 0 ? void 0 : (0, import_node_path53.join)((0, import_node_path53.dirname)(bundle), HOLDER_BUNDLE);
70881
71369
  const script = lean !== void 0 && exists6(lean) ? [...runtimeArgs.slice(0, -1), lean] : runtimeArgs;
@@ -71014,20 +71502,20 @@ async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
71014
71502
 
71015
71503
  // src/holder/serve.ts
71016
71504
  var import_node_crypto30 = require("crypto");
71017
- var import_node_fs23 = require("fs");
71505
+ var import_node_fs24 = require("fs");
71018
71506
  var import_node_net3 = require("net");
71019
71507
  var import_node_path66 = require("path");
71020
71508
  init_runtime_v2();
71021
71509
 
71022
71510
  // src/holder/admission.ts
71023
- var import_node_fs20 = require("fs");
71511
+ var import_node_fs21 = require("fs");
71024
71512
  var import_promises61 = require("fs/promises");
71025
71513
  var import_node_os10 = require("os");
71026
71514
  var import_node_path60 = require("path");
71027
71515
  init_constants();
71028
71516
 
71029
71517
  // ../shared/dist/node/local-workspace.js
71030
- var import_node_fs19 = require("fs");
71518
+ var import_node_fs20 = require("fs");
71031
71519
  var import_node_os9 = require("os");
71032
71520
  var import_node_path55 = require("path");
71033
71521
  function resolveAlanDefaultWorkspacePath(homeDirectory = (0, import_node_os9.homedir)()) {
@@ -71447,7 +71935,7 @@ async function inspectReadiness(path4) {
71447
71935
  if (!(await (0, import_promises61.stat)(path4)).isDirectory()) {
71448
71936
  return { ready: false, missing: true, message: MESSAGES.missing };
71449
71937
  }
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);
71938
+ 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
71939
  return { ready: true };
71452
71940
  } catch (error62) {
71453
71941
  const code = errnoCode(error62) ?? "";
@@ -71492,7 +71980,7 @@ async function admitDefaultWorkspace(spec, context, skills) {
71492
71980
  const path4 = resolveAlanDefaultWorkspacePath(env.HOME || env.USERPROFILE || (0, import_node_os10.homedir)());
71493
71981
  try {
71494
71982
  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);
71983
+ 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
71984
  return { kind: "admitted", spec: { ...spec, projectPath: path4 }, skills };
71497
71985
  } catch (error62) {
71498
71986
  const code = errnoCode(error62);
@@ -71741,7 +72229,7 @@ ${added.join("\n")}
71741
72229
 
71742
72230
  // src/run-log/complete.ts
71743
72231
  var import_node_crypto29 = require("crypto");
71744
- var import_node_fs21 = require("fs");
72232
+ var import_node_fs22 = require("fs");
71745
72233
  var import_node_path63 = require("path");
71746
72234
 
71747
72235
  // src/run-log/directory.ts
@@ -71792,23 +72280,23 @@ async function isRunClaimed(runsDir, runId) {
71792
72280
  // src/run-log/complete.ts
71793
72281
  function writeLogFile(path4, dir, text3) {
71794
72282
  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);
72283
+ const fd = (0, import_node_fs22.openSync)(temp, "wx", 384);
71796
72284
  try {
71797
- (0, import_node_fs21.writeSync)(fd, text3);
71798
- (0, import_node_fs21.fsyncSync)(fd);
72285
+ (0, import_node_fs22.writeSync)(fd, text3);
72286
+ (0, import_node_fs22.fsyncSync)(fd);
71799
72287
  } finally {
71800
- (0, import_node_fs21.closeSync)(fd);
72288
+ (0, import_node_fs22.closeSync)(fd);
71801
72289
  }
71802
72290
  try {
71803
- (0, import_node_fs21.renameSync)(temp, path4);
72291
+ (0, import_node_fs22.renameSync)(temp, path4);
71804
72292
  } finally {
71805
- (0, import_node_fs21.rmSync)(temp, { force: true });
72293
+ (0, import_node_fs22.rmSync)(temp, { force: true });
71806
72294
  }
71807
72295
  }
71808
72296
  async function writeCompleteRunLog(runsDir, meta3, records) {
71809
72297
  const paths = runDirectory(runsDir, meta3.runId);
71810
72298
  if (!await isRunClaimed(runsDir, meta3.runId)) {
71811
- (0, import_node_fs21.mkdirSync)(paths.dir, { recursive: true, mode: 448 });
72299
+ (0, import_node_fs22.mkdirSync)(paths.dir, { recursive: true, mode: 448 });
71812
72300
  const text3 = records.map((record2, index) => {
71813
72301
  const line = { seq: index + 1, at: record2.at, update: record2.update };
71814
72302
  return `${JSON.stringify(line)}
@@ -72065,13 +72553,13 @@ function runEnded(input2) {
72065
72553
  var decoder = new TextDecoder();
72066
72554
 
72067
72555
  // src/run-log/writer.ts
72068
- var import_node_fs22 = require("fs");
72556
+ var import_node_fs23 = require("fs");
72069
72557
  var import_node_path65 = require("path");
72070
72558
  init_runtime_v2();
72071
72559
  function lastSeq(fd, size) {
72072
72560
  for (const length of tailWindows(size)) {
72073
72561
  const buffer = Buffer.alloc(length);
72074
- (0, import_node_fs22.readSync)(fd, buffer, 0, length, size - length);
72562
+ (0, import_node_fs23.readSync)(fd, buffer, 0, length, size - length);
72075
72563
  const last = lastLine(buffer.toString("utf8").trimEnd(), length === size);
72076
72564
  if (last === void 0) continue;
72077
72565
  if (last.length === 0) return 0;
@@ -72082,13 +72570,13 @@ function lastSeq(fd, size) {
72082
72570
  throw new RuntimeFault("record_too_large", "Run log tail record is larger than any record");
72083
72571
  }
72084
72572
  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;
72573
+ (0, import_node_fs23.mkdirSync)((0, import_node_path65.dirname)(path4), { recursive: true, mode: 448 });
72574
+ const fd = (0, import_node_fs23.openSync)(path4, "a+", 384);
72575
+ let size = (0, import_node_fs23.fstatSync)(fd).size;
72088
72576
  let seq = lastSeq(fd, size);
72089
72577
  let dirty = false;
72090
72578
  const sync = () => {
72091
- (0, import_node_fs22.fsyncSync)(fd);
72579
+ (0, import_node_fs23.fsyncSync)(fd);
72092
72580
  dirty = false;
72093
72581
  };
72094
72582
  return {
@@ -72102,7 +72590,7 @@ function openRunLog(path4, clock) {
72102
72590
  };
72103
72591
  const line = Buffer.from(`${JSON.stringify(record2)}
72104
72592
  `, "utf8");
72105
- (0, import_node_fs22.writeSync)(fd, line);
72593
+ (0, import_node_fs23.writeSync)(fd, line);
72106
72594
  size += line.length;
72107
72595
  dirty = true;
72108
72596
  if (isRunLifecycleKind(update.sessionUpdate)) sync();
@@ -72114,7 +72602,7 @@ function openRunLog(path4, clock) {
72114
72602
  },
72115
72603
  [Symbol.dispose]: () => {
72116
72604
  if (dirty) sync();
72117
- (0, import_node_fs22.closeSync)(fd);
72605
+ (0, import_node_fs23.closeSync)(fd);
72118
72606
  }
72119
72607
  };
72120
72608
  }
@@ -72177,20 +72665,17 @@ async function runWithInputs({ spec, skills }, context, sink, signal) {
72177
72665
  message: `Could not fetch this run's attachments or provider credential: ${error62 instanceof Error ? error62.message : String(error62)}`
72178
72666
  };
72179
72667
  }
72180
- const agentContext = await sessionContext;
72181
72668
  const prepared = __using(_stack, inputs, true);
72182
- const result = await context.driver.runTurn(
72183
- spec,
72184
- sink,
72185
- signal,
72186
- agentContext === void 0 ? prepared : {
72187
- ...prepared,
72188
- agentContext: {
72189
- full: agentContext.full,
72190
- ...agentContext.update ? { update: agentContext.update } : {}
72669
+ const result = await context.driver.runTurn(spec, sink, signal, {
72670
+ ...prepared,
72671
+ agentContext: sessionContext.then(
72672
+ (agentContext2) => agentContext2 === void 0 ? void 0 : {
72673
+ full: agentContext2.full,
72674
+ ...agentContext2.update ? { update: agentContext2.update } : {}
72191
72675
  }
72192
- }
72193
- );
72676
+ )
72677
+ });
72678
+ const agentContext = await sessionContext;
72194
72679
  if (agentContext !== void 0 && result.outcome !== "rejected") {
72195
72680
  await agentContext.save().catch((error62) => {
72196
72681
  context.log.warn("holder.agent_context_save_failed", { runId: spec.runId, error: error62 });
@@ -72558,7 +73043,7 @@ async function runHolder({
72558
73043
  for (const client of holder.clients) client.end();
72559
73044
  await new Promise((resolve13) => server.close(() => resolve13()));
72560
73045
  await statusWrites;
72561
- (0, import_node_fs23.rmSync)(launch.statusPath, { force: true });
73046
+ (0, import_node_fs24.rmSync)(launch.statusPath, { force: true });
72562
73047
  log.info("holder.suspended", { conversationId: launch.conversationId });
72563
73048
  } catch (_) {
72564
73049
  var _error = _, _hasError = true;
@@ -72571,6 +73056,7 @@ async function runHolder({
72571
73056
  var GIB = 1024 ** 3;
72572
73057
  var MIN_RUN_BYTES = 1.25 * GIB;
72573
73058
  function memoryAllowsStart(capacity, activeRuns, pendingStarts = 0) {
73059
+ if (activeRuns + pendingStarts === 0) return true;
72574
73060
  const headroom = Math.max(512 * 1024 ** 2, capacity.totalBytes * 0.2);
72575
73061
  const slots = Math.max(1, Math.floor((capacity.totalBytes - headroom) / MIN_RUN_BYTES));
72576
73062
  return activeRuns + pendingStarts < slots && capacity.availableBytes >= MIN_RUN_BYTES * (pendingStarts + 1);
@@ -72588,6 +73074,7 @@ function runOccupancy(held, reserved, exclude = null) {
72588
73074
 
72589
73075
  // src/sessions/suspend-policy.ts
72590
73076
  var GIB2 = 1024 ** 3;
73077
+ var SESSION_MEMORY_CEILING_BYTES = 2.5 * GIB2;
72591
73078
  var MEMORY_BUDGET_SHARE = 0.15;
72592
73079
  var MEMORY_BUDGET_MIN_BYTES = GIB2;
72593
73080
  var MEMORY_BUDGET_MAX_BYTES = 4 * GIB2;
@@ -72621,7 +73108,9 @@ function memoryOf(holder) {
72621
73108
  function ownReason({ holder, idleSinceMs }, policy, nowMs) {
72622
73109
  if (holder.facts.loginFailed) return "login_error";
72623
73110
  if (holder.facts.cliBinaryChanged) return "cli_changed";
72624
- if (memoryOf(holder) > Math.min(policy.memoryBudgetBytes, 1.25 * GIB2)) return "memory_budget";
73111
+ if (memoryOf(holder) > Math.min(policy.memoryBudgetBytes, SESSION_MEMORY_CEILING_BYTES)) {
73112
+ return "memory_budget";
73113
+ }
72625
73114
  if (nowMs - idleSinceMs >= policy.idleMs) return "idle";
72626
73115
  if (nowMs - holder.facts.startedAtMs >= policy.maxAgeMs) return "age";
72627
73116
  return null;
@@ -72636,8 +73125,8 @@ function planSuspends(holders, policy, nowMs, pressure, opened = null) {
72636
73125
  if (reason === null) kept.push(entry);
72637
73126
  else decisions.push({ conversationId: entry.holder.conversationId, reason });
72638
73127
  }
72639
- const suspend = (count, reason) => {
72640
- for (const { holder } of kept.splice(0, Math.max(0, count))) {
73128
+ const suspend = (count2, reason) => {
73129
+ for (const { holder } of kept.splice(0, Math.max(0, count2))) {
72641
73130
  decisions.push({ conversationId: holder.conversationId, reason });
72642
73131
  }
72643
73132
  };
@@ -73010,7 +73499,20 @@ async function openSessions(deps) {
73010
73499
  return "started";
73011
73500
  }
73012
73501
  if (!await claimCapacity(run2.runId)) {
73013
- log.info("sessions.resource_wait", { runId: run2.runId });
73502
+ const capacity = memoryCapacity();
73503
+ const { active, pending } = runOccupancy(
73504
+ await heldRuns(),
73505
+ [...admitted, ...launched.keys()],
73506
+ run2.runId
73507
+ );
73508
+ log.info("sessions.resource_wait", {
73509
+ runId: run2.runId,
73510
+ active,
73511
+ pending,
73512
+ maxActiveRuns,
73513
+ totalMiB: Math.round(capacity.totalBytes / 2 ** 20),
73514
+ availableMiB: Math.round(capacity.availableBytes / 2 ** 20)
73515
+ });
73014
73516
  return "waiting";
73015
73517
  }
73016
73518
  try {
@@ -73133,7 +73635,8 @@ var envSchema = external_exports.object({
73133
73635
  ALAN_RUNTIME_LOG_LEVEL: external_exports.enum(["debug", "info", "warn", "error"]).default("info"),
73134
73636
  ALAN_RUNTIME_SUSPEND_IDLE_MS: external_exports.coerce.number().int().positive().optional(),
73135
73637
  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),
73638
+ // A two-minute conditional GET bounds recovery after a lost poke; unchanged state returns 304.
73639
+ ALAN_RUNTIME_DESIRED_RESYNC_MS: external_exports.coerce.number().int().positive().default(12e4),
73137
73640
  ALAN_MAX_ACTIVE_RUNS: external_exports.coerce.number().int().optional(),
73138
73641
  ALAN_RUNTIME_API_URL: external_exports.url().optional(),
73139
73642
  ALAN_RUNTIME_CREDENTIAL_STORE: external_exports.enum(CREDENTIAL_STORE_KINDS).optional(),
@@ -75310,7 +75813,7 @@ async function runLogout(argv, signal) {
75310
75813
  }
75311
75814
 
75312
75815
  // src/cli/commands/run.ts
75313
- var import_node_fs25 = require("fs");
75816
+ var import_node_fs26 = require("fs");
75314
75817
  var import_node_path82 = require("path");
75315
75818
 
75316
75819
  // src/local-api/app-attachments.ts
@@ -75865,7 +76368,7 @@ var machineFeatureRoutes = [
75865
76368
  ];
75866
76369
 
75867
76370
  // src/local-api/run-log-routes.ts
75868
- var import_node_fs24 = require("fs");
76371
+ var import_node_fs25 = require("fs");
75869
76372
  init_runtime_v2();
75870
76373
  var RUN_ENDED = "_alan/run.ended";
75871
76374
  var decoder2 = new TextDecoder();
@@ -75882,7 +76385,7 @@ async function openWhenWritten(deps, runId, res, signal) {
75882
76385
  const path4 = runDirectory(deps.runsDir, runId).log;
75883
76386
  while (!signal.aborted) {
75884
76387
  const appended = deps.appends.nextAppend(runId, signal);
75885
- if ((0, import_node_fs24.existsSync)(path4) || !await deps.isHeld(runId, signal)) return openReader(res, path4);
76388
+ if ((0, import_node_fs25.existsSync)(path4) || !await deps.isHeld(runId, signal)) return openReader(res, path4);
75886
76389
  await appended;
75887
76390
  }
75888
76391
  return null;
@@ -76655,11 +77158,11 @@ var SEPARATOR = String.fromCharCode(30);
76655
77158
  var encodePayload = (packets, callback) => {
76656
77159
  const length = packets.length;
76657
77160
  const encodedPackets = new Array(length);
76658
- let count = 0;
77161
+ let count2 = 0;
76659
77162
  packets.forEach((packet, i) => {
76660
77163
  encodePacket(packet, false, (encodedPacket) => {
76661
77164
  encodedPackets[i] = encodedPacket;
76662
- if (++count === length) {
77165
+ if (++count2 === length) {
76663
77166
  callback(encodedPackets.join(SEPARATOR));
76664
77167
  }
76665
77168
  });
@@ -82230,7 +82733,7 @@ function lockWaitMs(argv) {
82230
82733
  async function openManagedProviders(config2, paths) {
82231
82734
  const providerEnv = readCliEnvironment();
82232
82735
  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);
82736
+ const providerToolchain = config2.providerToolchain ?? (process.platform === "win32" && (0, import_node_fs26.existsSync)(bundledNpm) ? { node: process.execPath, npmCli: bundledNpm } : null);
82234
82737
  const npmPath = providerToolchain?.node ?? await resolveCommandOnPath("npm", providerEnv, process.platform);
82235
82738
  const npmOptions = npmPath === null || process.platform === "win32" && providerToolchain === null ? null : {
82236
82739
  command: npmPath,