@alan-ai-hq/agent-manager-linux-arm64 0.1.145 → 0.1.147

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 +895 -410
  2. package/alan-holder.cjs +894 -396
  3. package/package.json +7 -2
package/alan-holder.cjs CHANGED
@@ -12529,7 +12529,7 @@ function compileValidator(schema, parser) {
12529
12529
  function compile(schema, options) {
12530
12530
  try {
12531
12531
  const parser = compileFn(schema);
12532
- const clone2 = clone(schema);
12532
+ const clone3 = clone(schema);
12533
12533
  const liveRun = schema._zod.run;
12534
12534
  const originalRun = liveRun.__originalRun ?? liveRun;
12535
12535
  const wrapped = (payload, ctx) => {
@@ -12549,12 +12549,12 @@ function compile(schema, options) {
12549
12549
  return originalRun(payload, ctx);
12550
12550
  };
12551
12551
  wrapped.__originalRun = originalRun;
12552
- clone2._zod.bag.fallbackRun = originalRun;
12553
- clone2._zod.bag.validator = compileValidator(schema, parser);
12554
- clone2._zod.run = wrapped;
12552
+ clone3._zod.bag.fallbackRun = originalRun;
12553
+ clone3._zod.bag.validator = compileValidator(schema, parser);
12554
+ clone3._zod.run = wrapped;
12555
12555
  if (!liveRun.__originalRun)
12556
- installCompiledUserMethods(clone2, schema, parser);
12557
- return clone2;
12556
+ installCompiledUserMethods(clone3, schema, parser);
12557
+ return clone3;
12558
12558
  } catch (err) {
12559
12559
  if (options?.strict)
12560
12560
  throw err;
@@ -20309,7 +20309,7 @@ var init_workspace = __esm({
20309
20309
  });
20310
20310
 
20311
20311
  // ../shared/dist/runtime-v2/desired-state.js
20312
- var repoLocalPathSchema, runSpecSchema, desiredRunSchema, desiredStateSchema;
20312
+ var repoLocalPathSchema, requestedCheckoutSchema, runSpecSchema, desiredRunSchema, desiredStateSchema;
20313
20313
  var init_desired_state = __esm({
20314
20314
  "../shared/dist/runtime-v2/desired-state.js"() {
20315
20315
  "use strict";
@@ -20324,6 +20324,11 @@ var init_desired_state = __esm({
20324
20324
  localPath: external_exports.string().min(1),
20325
20325
  branch: external_exports.string().min(1).optional()
20326
20326
  });
20327
+ requestedCheckoutSchema = external_exports.object({
20328
+ path: machinePathSchema,
20329
+ repoUrl: gitRemoteUrlSchema,
20330
+ branch: gitBranchSchema
20331
+ });
20327
20332
  runSpecSchema = external_exports.object({
20328
20333
  runId: runIdSchema,
20329
20334
  conversationId: conversationIdSchema,
@@ -20342,6 +20347,8 @@ var init_desired_state = __esm({
20342
20347
  workspacePathPinned: external_exports.boolean().optional(),
20343
20348
  approvedWorkspacePaths: external_exports.array(external_exports.string().min(1)).optional(),
20344
20349
  repoLocalPaths: external_exports.array(repoLocalPathSchema).optional(),
20350
+ /** Applied once, at the conversation's first turn on a cloud sandbox; never moves local work. */
20351
+ requestedCheckouts: external_exports.array(requestedCheckoutSchema).max(64).optional(),
20345
20352
  workflowId: external_exports.guid().optional(),
20346
20353
  workflowExecutionId: external_exports.guid().optional(),
20347
20354
  agentId: external_exports.string().min(1).optional(),
@@ -20506,7 +20513,9 @@ var init_machine_identity = __esm({
20506
20513
  runCodexCredentialSchema = external_exports.object({
20507
20514
  accessToken: external_exports.string().min(1),
20508
20515
  chatgptAccountId: external_exports.string().min(1),
20509
- chatgptPlanType: external_exports.string().nullable()
20516
+ chatgptPlanType: external_exports.string().nullable(),
20517
+ credentialId: external_exports.uuid().optional(),
20518
+ providerUserId: external_exports.string().min(1).optional()
20510
20519
  });
20511
20520
  runCodexCredentialRefreshRequestSchema = external_exports.object({
20512
20521
  /** sha256 hex of the access token Codex was refused with; a newer stored token is returned instead of rotating. */
@@ -20515,7 +20524,7 @@ var init_machine_identity = __esm({
20515
20524
  runProviderCredentialSchema = external_exports.object({
20516
20525
  /** Environment variables for the agent CLI, e.g. ANTHROPIC_API_KEY; empty when the CLI's own login is used. */
20517
20526
  env: external_exports.record(external_exports.string(), external_exports.string()),
20518
- /** The team's Codex login for a cloud sandbox; absent where the CLI's own login is used. */
20527
+ /** The bound Codex login for a cloud sandbox; absent where the CLI's own login is used. */
20519
20528
  codex: runCodexCredentialSchema.optional()
20520
20529
  });
20521
20530
  }
@@ -20930,16 +20939,84 @@ var init_problem = __esm({
20930
20939
  }
20931
20940
  });
20932
20941
 
20942
+ // ../shared/dist/cli-usage.js
20943
+ var usagePercentSchema, usageTimestampSchema, usageAmountSchema, usageObservationShape, cliUsageWindowPatchSchema, cliUsageWindowSchema, cliUsageSpendPatchSchema, cliUsageSpendSchema, cliUsageCreditsPatchSchema, cliUsageCreditsSchema, cliUsageBucketSchema, cliUsageSnapshotSchema;
20944
+ var init_cli_usage = __esm({
20945
+ "../shared/dist/cli-usage.js"() {
20946
+ "use strict";
20947
+ init_zod();
20948
+ usagePercentSchema = external_exports.number().min(0).max(100);
20949
+ usageTimestampSchema = external_exports.iso.datetime();
20950
+ usageAmountSchema = external_exports.string().min(1);
20951
+ usageObservationShape = {
20952
+ observedAt: usageTimestampSchema,
20953
+ receivedAt: usageTimestampSchema,
20954
+ sourceId: external_exports.string().min(1),
20955
+ sequence: external_exports.number().int().nonnegative()
20956
+ };
20957
+ cliUsageWindowPatchSchema = external_exports.object({
20958
+ usedPercent: usagePercentSchema.nullable().optional(),
20959
+ windowMinutes: external_exports.number().positive().nullable().optional(),
20960
+ resetsAt: usageTimestampSchema.nullable().optional()
20961
+ });
20962
+ cliUsageWindowSchema = external_exports.object({
20963
+ usedPercent: usagePercentSchema.optional(),
20964
+ windowMinutes: external_exports.number().positive().optional(),
20965
+ resetsAt: usageTimestampSchema.optional(),
20966
+ ...usageObservationShape
20967
+ });
20968
+ cliUsageSpendPatchSchema = external_exports.object({
20969
+ reached: external_exports.boolean(),
20970
+ limit: usageAmountSchema.nullable().optional(),
20971
+ used: usageAmountSchema.nullable().optional(),
20972
+ remaining: usageAmountSchema.nullable().optional(),
20973
+ usedPercent: usagePercentSchema.nullable().optional(),
20974
+ resetsAt: usageTimestampSchema.nullable().optional()
20975
+ });
20976
+ cliUsageSpendSchema = external_exports.object({
20977
+ reached: external_exports.boolean(),
20978
+ limit: usageAmountSchema.optional(),
20979
+ used: usageAmountSchema.optional(),
20980
+ remaining: usageAmountSchema.optional(),
20981
+ usedPercent: usagePercentSchema.optional(),
20982
+ resetsAt: usageTimestampSchema.optional(),
20983
+ ...usageObservationShape
20984
+ });
20985
+ cliUsageCreditsPatchSchema = external_exports.object({
20986
+ hasCredits: external_exports.boolean(),
20987
+ unlimited: external_exports.boolean(),
20988
+ balance: usageAmountSchema.nullable().optional()
20989
+ });
20990
+ cliUsageCreditsSchema = external_exports.object({
20991
+ hasCredits: external_exports.boolean(),
20992
+ unlimited: external_exports.boolean(),
20993
+ balance: usageAmountSchema.optional(),
20994
+ ...usageObservationShape
20995
+ });
20996
+ cliUsageBucketSchema = external_exports.object({
20997
+ primary: cliUsageWindowSchema.optional(),
20998
+ secondary: cliUsageWindowSchema.optional(),
20999
+ spend: cliUsageSpendSchema.optional(),
21000
+ credits: cliUsageCreditsSchema.optional(),
21001
+ planType: external_exports.string().min(1).nullable().optional()
21002
+ });
21003
+ cliUsageSnapshotSchema = external_exports.object({
21004
+ buckets: external_exports.record(external_exports.string().min(1), cliUsageBucketSchema)
21005
+ });
21006
+ }
21007
+ });
21008
+
20933
21009
  // ../shared/dist/runtime-v2/run-log.js
20934
21010
  function isRunLifecycleKind(sessionUpdate) {
20935
21011
  return RUN_LIFECYCLE_KINDS.has(sessionUpdate);
20936
21012
  }
20937
- var runAcceptedUpdateSchema, runStartedUpdateSchema, runWorkspaceRelocatedUpdateSchema, runOutcomeSchema, runRejectionCodeSchema, runEndedUpdateSchema, runLifecycleUpdateSchema, RUN_LIFECYCLE_KINDS, runLogRecordSchema;
21013
+ var runAcceptedUpdateSchema, runStartedUpdateSchema, runCodexRateLimitsUpdateSchema, runWorkspaceRelocatedUpdateSchema, runOutcomeSchema, runRejectionCodeSchema, runEndedUpdateSchema, runLifecycleUpdateSchema, RUN_LIFECYCLE_KINDS, runLogRecordSchema;
20938
21014
  var init_run_log = __esm({
20939
21015
  "../shared/dist/runtime-v2/run-log.js"() {
20940
21016
  "use strict";
20941
21017
  init_zod();
20942
21018
  init_problem();
21019
+ init_cli_usage();
20943
21020
  init_ids();
20944
21021
  runAcceptedUpdateSchema = external_exports.object({
20945
21022
  sessionUpdate: external_exports.literal("_alan/run.accepted"),
@@ -20951,6 +21028,18 @@ var init_run_log = __esm({
20951
21028
  providerSessionId: external_exports.string().min(1).optional(),
20952
21029
  pid: external_exports.number().int().positive().optional()
20953
21030
  });
21031
+ runCodexRateLimitsUpdateSchema = external_exports.object({
21032
+ sessionUpdate: external_exports.literal("_alan/codex.rate_limits"),
21033
+ limitId: external_exports.string().min(1),
21034
+ primary: cliUsageWindowPatchSchema.nullable().optional(),
21035
+ secondary: cliUsageWindowPatchSchema.nullable().optional(),
21036
+ spend: cliUsageSpendPatchSchema.nullable().optional(),
21037
+ credits: cliUsageCreditsPatchSchema.nullable().optional(),
21038
+ planType: external_exports.string().min(1).nullable().optional(),
21039
+ observedAt: external_exports.iso.datetime(),
21040
+ sourceId: external_exports.string().min(1),
21041
+ sequence: external_exports.number().int().nonnegative()
21042
+ });
20954
21043
  runWorkspaceRelocatedUpdateSchema = external_exports.object({
20955
21044
  sessionUpdate: external_exports.literal("_alan/run.workspace_relocated"),
20956
21045
  previousPath: external_exports.string().min(1).max(4096),
@@ -21013,7 +21102,7 @@ var init_holder_protocol = __esm({
21013
21102
  init_ids();
21014
21103
  init_link();
21015
21104
  init_run_log();
21016
- HOLDER_PROTOCOL = 1;
21105
+ HOLDER_PROTOCOL = 2;
21017
21106
  holderAbortOutcomeSchema = external_exports.enum(["aborted", "interrupted"]);
21018
21107
  holderRequestSchema = external_exports.discriminatedUnion("type", [
21019
21108
  external_exports.object({ type: external_exports.literal("auth"), token: external_exports.string().min(1) }),
@@ -22179,11 +22268,11 @@ function createListeners() {
22179
22268
  }
22180
22269
  };
22181
22270
  }
22182
- var import_promises4, CoreFault, NANOS_PER_MILLI, systemClock2, silentLog;
22271
+ var import_promises5, CoreFault, NANOS_PER_MILLI, systemClock2, silentLog;
22183
22272
  var init_chunk_YXWJW7I5 = __esm({
22184
22273
  "../agent-core/dist/chunk-YXWJW7I5.js"() {
22185
22274
  "use strict";
22186
- import_promises4 = require("timers/promises");
22275
+ import_promises5 = require("timers/promises");
22187
22276
  CoreFault = class extends Error {
22188
22277
  code;
22189
22278
  constructor(code, message, options) {
@@ -22197,7 +22286,7 @@ var init_chunk_YXWJW7I5 = __esm({
22197
22286
  now: () => Date.now(),
22198
22287
  monotonic: () => Number(process.hrtime.bigint() / NANOS_PER_MILLI),
22199
22288
  sleep: async (ms, signal) => {
22200
- await (0, import_promises4.setTimeout)(ms, void 0, signal ? { signal } : void 0);
22289
+ await (0, import_promises5.setTimeout)(ms, void 0, signal ? { signal } : void 0);
22201
22290
  }
22202
22291
  };
22203
22292
  silentLog = {
@@ -22404,7 +22493,7 @@ function plan(command, args, options) {
22404
22493
  function captureOutput(command, args, options) {
22405
22494
  const launch = plan(command, args, options);
22406
22495
  if (launch === void 0) return Promise.resolve(NEVER_STARTED);
22407
- return new Promise((resolve7) => {
22496
+ return new Promise((resolve9) => {
22408
22497
  (0, import_child_process.execFile)(
22409
22498
  launch.file,
22410
22499
  [...launch.args],
@@ -22418,7 +22507,7 @@ function captureOutput(command, args, options) {
22418
22507
  },
22419
22508
  (error61, stdout, stderr) => {
22420
22509
  const code = error61 && typeof error61.code === "number" ? error61.code : error61 ? void 0 : 0;
22421
- resolve7({ stdout, stderr, exitCode: code });
22510
+ resolve9({ stdout, stderr, exitCode: code });
22422
22511
  }
22423
22512
  );
22424
22513
  });
@@ -22460,18 +22549,18 @@ function decode3(bytes, start, end) {
22460
22549
  }
22461
22550
  async function linuxStartTicks(pid) {
22462
22551
  try {
22463
- const stat15 = await (0, import_promises5.readFile)(`/proc/${pid}/stat`, "utf8");
22464
- const fields = stat15.slice(stat15.lastIndexOf(")") + 2).split(" ");
22552
+ const stat16 = await (0, import_promises6.readFile)(`/proc/${pid}/stat`, "utf8");
22553
+ const fields = stat16.slice(stat16.lastIndexOf(")") + 2).split(" ");
22465
22554
  return fields[19];
22466
22555
  } catch {
22467
22556
  return void 0;
22468
22557
  }
22469
22558
  }
22470
22559
  function psStartTime(pid) {
22471
- return new Promise((resolve7) => {
22560
+ return new Promise((resolve9) => {
22472
22561
  (0, import_child_process2.execFile)("ps", ["-o", "lstart=", "-p", String(pid)], { timeout: 2e3 }, (error61, stdout) => {
22473
22562
  const text2 = stdout.trim();
22474
- resolve7(error61 || !text2 ? void 0 : text2);
22563
+ resolve9(error61 || !text2 ? void 0 : text2);
22475
22564
  });
22476
22565
  });
22477
22566
  }
@@ -22500,12 +22589,12 @@ function parseProcessList(text2) {
22500
22589
  }
22501
22590
  function listProcesses(platform = process.platform) {
22502
22591
  if (platform === "win32") return Promise.resolve([]);
22503
- return new Promise((resolve7) => {
22592
+ return new Promise((resolve9) => {
22504
22593
  (0, import_child_process3.execFile)(
22505
22594
  "ps",
22506
22595
  ["-A", "-o", "pid=,ppid=,pgid=,lstart="],
22507
22596
  { timeout: 5e3, maxBuffer: 8 * 1024 * 1024 },
22508
- (error61, stdout) => resolve7(error61 ? [] : parseProcessList(stdout))
22597
+ (error61, stdout) => resolve9(error61 ? [] : parseProcessList(stdout))
22509
22598
  );
22510
22599
  });
22511
22600
  }
@@ -22545,11 +22634,11 @@ async function taskkill(pid, options) {
22545
22634
  stdio: "ignore",
22546
22635
  windowsHide: true
22547
22636
  });
22548
- const exited = new Promise((resolve7) => {
22549
- killer.once("error", (error210) => resolve7(error210));
22637
+ const exited = new Promise((resolve9) => {
22638
+ killer.once("error", (error210) => resolve9(error210));
22550
22639
  killer.once(
22551
22640
  "exit",
22552
- (code, signal) => resolve7(code === 0 ? void 0 : new Error(`taskkill failed: exit ${code}, signal ${signal}`))
22641
+ (code, signal) => resolve9(code === 0 ? void 0 : new Error(`taskkill failed: exit ${code}, signal ${signal}`))
22553
22642
  );
22554
22643
  });
22555
22644
  const timedOut = clock.sleep(options.timeoutMs ?? DEFAULT_TASKKILL_TIMEOUT_MS, timeout.signal).then(() => new Error("taskkill timed out")).catch(() => void 0);
@@ -22753,7 +22842,7 @@ async function waitForWindowsJob(child, command) {
22753
22842
  const deadline = systemClock2.monotonic() + START_TIMEOUT_MS;
22754
22843
  try {
22755
22844
  while (systemClock2.monotonic() < deadline) {
22756
- const providerPid = await (0, import_promises6.readFile)(status.path, "utf8").catch(() => void 0);
22845
+ const providerPid = await (0, import_promises7.readFile)(status.path, "utf8").catch(() => void 0);
22757
22846
  if (providerPid !== void 0) {
22758
22847
  requireStartedProvider(providerPid, command);
22759
22848
  return;
@@ -22776,7 +22865,7 @@ async function waitForWindowsJob(child, command) {
22776
22865
  throw new CoreFault("spawn_failed", `Could not start ${command} (Windows helper timed out)`);
22777
22866
  } finally {
22778
22867
  statuses.delete(child);
22779
- await (0, import_promises6.rm)(status.directory, { recursive: true, force: true });
22868
+ await (0, import_promises7.rm)(status.directory, { recursive: true, force: true });
22780
22869
  }
22781
22870
  }
22782
22871
  function onCliSpawned(listener) {
@@ -22805,10 +22894,10 @@ function spawnCli(options) {
22805
22894
  function waitForSpawn(child, command) {
22806
22895
  if (isWindowsJob(child)) return waitForWindowsJob(child, command);
22807
22896
  if (child.pid !== void 0) return Promise.resolve();
22808
- return new Promise((resolve7, reject) => {
22897
+ return new Promise((resolve9, reject) => {
22809
22898
  const onSpawn = () => {
22810
22899
  child.off("error", onError);
22811
- resolve7();
22900
+ resolve9();
22812
22901
  };
22813
22902
  const onError = (error61) => {
22814
22903
  child.off("spawn", onSpawn);
@@ -22821,7 +22910,7 @@ function waitForSpawn(child, command) {
22821
22910
  child.once("error", onError);
22822
22911
  });
22823
22912
  }
22824
- var import_child_process, import_fs, import_path, import_child_process2, import_promises5, import_child_process3, import_child_process4, import_child_process5, import_child_process6, import_crypto, import_fs2, import_promises6, import_os, import_path2, SHIM_MAX_BYTES, CMD_MAX_COMMAND_LINE, MAX_COMMAND_LINE, DEFAULT_PATHEXT, LAUNCHABLE_EXTENSIONS, nodeWindowsFiles, NODE_SHIM_ENTRY, NATIVE_SHIM_LINES, NATIVE_SHIM_ENTRY, CMD_META, NEVER_STARTED, HIDDEN_FLAG_PROBE_VALUE, NEWLINE, CARRIAGE_RETURN, EMPTY, MAX_LINE_BYTES, LineSplitter, PS_LINE, POLL_MS, DEFAULT_GRACE_MS, DEFAULT_KILL_WAIT_MS, DEFAULT_TASKKILL_TIMEOUT_MS, statuses, START_TIMEOUT_MS, spawnListeners;
22913
+ var import_child_process, import_fs, import_path, import_child_process2, import_promises6, import_child_process3, import_child_process4, import_child_process5, import_child_process6, import_crypto, import_fs2, import_promises7, import_os, import_path2, SHIM_MAX_BYTES, CMD_MAX_COMMAND_LINE, MAX_COMMAND_LINE, DEFAULT_PATHEXT, LAUNCHABLE_EXTENSIONS, nodeWindowsFiles, NODE_SHIM_ENTRY, NATIVE_SHIM_LINES, NATIVE_SHIM_ENTRY, CMD_META, NEVER_STARTED, HIDDEN_FLAG_PROBE_VALUE, NEWLINE, CARRIAGE_RETURN, EMPTY, MAX_LINE_BYTES, LineSplitter, PS_LINE, POLL_MS, DEFAULT_GRACE_MS, DEFAULT_KILL_WAIT_MS, DEFAULT_TASKKILL_TIMEOUT_MS, statuses, START_TIMEOUT_MS, spawnListeners;
22825
22914
  var init_chunk_M6YHY2EZ = __esm({
22826
22915
  "../agent-core/dist/chunk-M6YHY2EZ.js"() {
22827
22916
  "use strict";
@@ -22830,14 +22919,14 @@ var init_chunk_M6YHY2EZ = __esm({
22830
22919
  import_fs = require("fs");
22831
22920
  import_path = require("path");
22832
22921
  import_child_process2 = require("child_process");
22833
- import_promises5 = require("fs/promises");
22922
+ import_promises6 = require("fs/promises");
22834
22923
  import_child_process3 = require("child_process");
22835
22924
  import_child_process4 = require("child_process");
22836
22925
  import_child_process5 = require("child_process");
22837
22926
  import_child_process6 = require("child_process");
22838
22927
  import_crypto = require("crypto");
22839
22928
  import_fs2 = require("fs");
22840
- import_promises6 = require("fs/promises");
22929
+ import_promises7 = require("fs/promises");
22841
22930
  import_os = require("os");
22842
22931
  import_path2 = require("path");
22843
22932
  SHIM_MAX_BYTES = 64 * 1024;
@@ -24141,7 +24230,18 @@ var init_chunk_SBT5W7L4 = __esm({
24141
24230
  }
24142
24231
  });
24143
24232
 
24144
- // ../agent-core/dist/chunk-54ZRJOQP.js
24233
+ // ../agent-core/dist/chunk-HBIPWAUI.js
24234
+ function readCapReset(text2) {
24235
+ const epoch = EPOCH_RESET.exec(text2);
24236
+ if (epoch) return { resetsAt: new Date(Number(epoch[1]) * 1e3).toISOString() };
24237
+ const codex = CODEX_RESET.exec(text2);
24238
+ if (codex) {
24239
+ const milliseconds = Date.parse(codex[1].replace(/(\d)(?:st|nd|rd|th)\b/gi, "$1"));
24240
+ if (Number.isFinite(milliseconds)) return { resetsAt: new Date(milliseconds).toISOString() };
24241
+ }
24242
+ const worded = WORDED_RESET.exec(text2);
24243
+ return worded ? { resetHint: worded[1].trim() } : {};
24244
+ }
24145
24245
  function specForErrorKind(errorKind) {
24146
24246
  const spec = ERROR_SPECS[errorKind];
24147
24247
  return { message: spec.message, errorKind, recoveryClass: spec.recoveryClass };
@@ -24202,15 +24302,6 @@ function normalizeCodexCliErrorMessage(message) {
24202
24302
  }
24203
24303
  return message;
24204
24304
  }
24205
- function readCapReset(text2) {
24206
- const epoch = EPOCH_RESET.exec(text2);
24207
- if (epoch) {
24208
- const seconds = Number(epoch[1]);
24209
- return { resetsAt: new Date(seconds * 1e3).toISOString() };
24210
- }
24211
- const worded = WORDED_RESET.exec(text2);
24212
- return worded ? { resetHint: worded[1].trim() } : {};
24213
- }
24214
24305
  function lineMatching(text2, pattern) {
24215
24306
  return text2.split("\n").map((line) => line.trim()).find((line) => pattern.test(line));
24216
24307
  }
@@ -24222,10 +24313,11 @@ function withCapReset(classified, text2) {
24222
24313
  if (classified.errorKind !== "usage_limit") return classified;
24223
24314
  const reset = readCapReset(text2);
24224
24315
  if (reset.resetsAt) {
24316
+ const own22 = lineMatching(text2, /\btry again at\b/i);
24225
24317
  return {
24226
24318
  ...classified,
24227
24319
  ...reset,
24228
- message: `Provider usage limit reached. It resets at ${reset.resetsAt}; switch model or wait, then retry.`
24320
+ message: own22 ?? `Provider usage limit reached. It resets at ${reset.resetsAt}; switch model or wait, then retry.`
24229
24321
  };
24230
24322
  }
24231
24323
  const own2 = lineMatching(text2, /usage limit/i);
@@ -24344,13 +24436,16 @@ function createCliProblem(observed, options) {
24344
24436
  ...classified.resetsAt ? { resetsAt: classified.resetsAt } : {}
24345
24437
  });
24346
24438
  }
24347
- var import_crypto2, ERROR_SPECS, AGENT_ERROR_KINDS, AGENT_SIGN_IN_BY_HARNESS, STATUS_PREFIX, TEXT_RULES, CODEX_TIMEOUT_MESSAGE, CODEX_EXPIRED_MESSAGE, EPOCH_RESET, WORDED_RESET, COMMAND_NOT_FOUND, CODE_RULES, TEXT_REFINES, STATUS_LEAD, CLI_PROBLEM_CODE_BY_ERROR_KIND, KEY_REJECTION_KINDS;
24348
- var init_chunk_54ZRJOQP = __esm({
24349
- "../agent-core/dist/chunk-54ZRJOQP.js"() {
24439
+ var import_crypto2, EPOCH_RESET, WORDED_RESET, CODEX_RESET, ERROR_SPECS, AGENT_ERROR_KINDS, AGENT_SIGN_IN_BY_HARNESS, STATUS_PREFIX, TEXT_RULES, CODEX_TIMEOUT_MESSAGE, CODEX_EXPIRED_MESSAGE, COMMAND_NOT_FOUND, CODE_RULES, TEXT_REFINES, STATUS_LEAD, CLI_PROBLEM_CODE_BY_ERROR_KIND, KEY_REJECTION_KINDS;
24440
+ var init_chunk_HBIPWAUI = __esm({
24441
+ "../agent-core/dist/chunk-HBIPWAUI.js"() {
24350
24442
  "use strict";
24351
24443
  init_chunk_YXWJW7I5();
24352
24444
  import_crypto2 = require("crypto");
24353
24445
  init_agent2();
24446
+ EPOCH_RESET = /\|\s*(\d{10})\b/;
24447
+ WORDED_RESET = /\bresets?\s+(?:at\s+)?([^.\n]{1,60}?)\s*(?:$|[.\n])/i;
24448
+ CODEX_RESET = /\btry again at\s+([A-Za-z]{3,9}\s+\d{1,2}(?:st|nd|rd|th)?,?\s+\d{4}\s+\d{1,2}:\d{2}\s*[AP]M(?:\s+(?:UTC|GMT)(?:[+-]\d{1,2}(?::?\d{2})?)?)?)/i;
24354
24449
  ERROR_SPECS = {
24355
24450
  model_mismatch: {
24356
24451
  message: "The selected model isn't available, or you don't have access to it. Pick a different model, then send your message again.",
@@ -24504,7 +24599,7 @@ var init_chunk_54ZRJOQP = __esm({
24504
24599
  // #44604), or a trailing assistant message (opencode #19517).
24505
24600
  {
24506
24601
  kind: "history_rejected",
24507
- pattern: /\btext content blocks must be non-empty\b|\bcontent field in the message object\b|\bids were found without `?tool_result`? blocks\b|\bunexpected `?tool_use_id`?|\btool use concurrency issues\b|\bno tool output found for\b|\bdoes not support assistant message prefill\b/
24602
+ pattern: /\btext content blocks must be non-empty\b|\bcontent field in the message object\b|\bids were found without `?tool_result`? blocks\b|\bunexpected `?tool_use_id`?|\btool use concurrency issues\b|\bno tool output found for\b|\bdoes not support assistant message prefill\b|\binvalid_encrypted_content\b|organization_id did not match the target organization/
24508
24603
  },
24509
24604
  // Claude: "No conversation found with session ID"; Codex: "no rollout found for thread id";
24510
24605
  // Copilot: "No session, task, or name matched"; Kimi/Cursor ACP: `Session "<id>" not found`.
@@ -24553,8 +24648,6 @@ var init_chunk_54ZRJOQP = __esm({
24553
24648
  ];
24554
24649
  CODEX_TIMEOUT_MESSAGE = "Codex connection to OpenAI timed out while waiting for the turn to continue. Retry the message; if it repeats, check network/API latency or reduce slow MCP/tool calls in the turn.";
24555
24650
  CODEX_EXPIRED_MESSAGE = "Codex CLI connection expired. Re-authenticate the Codex CLI on this computer (run `codex login`) or reconnect it in Cloud settings, then retry.";
24556
- EPOCH_RESET = /\|\s*(\d{10})\b/;
24557
- WORDED_RESET = /\bresets?\s+(?:at\s+)?([^.\n]{1,60}?)\s*(?:$|[.\n])/i;
24558
24651
  COMMAND_NOT_FOUND = /\bcommand not found\b|\bno such file or directory\b/i;
24559
24652
  CODE_RULES = [
24560
24653
  { pattern: /model_not_found|model_not_available/, kind: "model_mismatch" },
@@ -24609,7 +24702,7 @@ var init_chunk_54ZRJOQP = __esm({
24609
24702
  }
24610
24703
  });
24611
24704
 
24612
- // ../agent-core/dist/chunk-72NSEYHK.js
24705
+ // ../agent-core/dist/chunk-4G77APXN.js
24613
24706
  function detectImageMimeType(buffer) {
24614
24707
  if (buffer.length >= 8 && buffer.subarray(0, 8).equals(PNG_SIGNATURE)) return "image/png";
24615
24708
  if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) {
@@ -24715,8 +24808,8 @@ function readMediaFiles(candidates2, cwd, mimeByExt, maxBytes) {
24715
24808
  seen.add(path);
24716
24809
  const mimeType = mimeByExt[(0, import_path3.extname)(path).toLowerCase()];
24717
24810
  if (!mimeType) continue;
24718
- const stat15 = (0, import_fs4.statSync)(path);
24719
- if (!stat15.isFile() || stat15.size <= 0 || stat15.size > maxBytes) continue;
24811
+ const stat16 = (0, import_fs4.statSync)(path);
24812
+ if (!stat16.isFile() || stat16.size <= 0 || stat16.size > maxBytes) continue;
24720
24813
  files.push({ path, mimeType, buffer: (0, import_fs4.readFileSync)(path) });
24721
24814
  }
24722
24815
  return files;
@@ -24791,8 +24884,8 @@ function createJsonRpcPeer(writer, handlers) {
24791
24884
  },
24792
24885
  request: (method, params = {}) => {
24793
24886
  const id = counter.next++;
24794
- return new Promise((resolve7, reject) => {
24795
- pending.set(id, { method, resolve: resolve7, reject });
24887
+ return new Promise((resolve9, reject) => {
24888
+ pending.set(id, { method, resolve: resolve9, reject });
24796
24889
  writer.write({ id, method, params }).catch((error61) => {
24797
24890
  pending.delete(id);
24798
24891
  reject(error61 instanceof Error ? error61 : new Error(String(error61)));
@@ -24905,7 +24998,7 @@ function createNdjsonWriter(stream) {
24905
24998
  get writable() {
24906
24999
  return stream.writable && !stream.destroyed && failure5.error === void 0;
24907
25000
  },
24908
- write: (value) => new Promise((resolve7, reject) => {
25001
+ write: (value) => new Promise((resolve9, reject) => {
24909
25002
  if (failure5.error) {
24910
25003
  reject(failure5.error);
24911
25004
  return;
@@ -24917,7 +25010,7 @@ function createNdjsonWriter(stream) {
24917
25010
  stream.write(`${JSON.stringify(value)}
24918
25011
  `, (error61) => {
24919
25012
  if (error61) reject(error61);
24920
- else resolve7();
25013
+ else resolve9();
24921
25014
  });
24922
25015
  }),
24923
25016
  end: () => {
@@ -24933,11 +25026,11 @@ function hostProcess(child, tree, options, handlers) {
24933
25026
  const stderr = new LineSplitter((line) => handlers.onStderrLine(line));
24934
25027
  child.stderr.on("data", (chunk) => stderr.push(chunk));
24935
25028
  child.stderr.once("end", () => stderr.flush());
24936
- const processExit = new Promise((resolve7) => {
24937
- child.once("exit", (code, signal) => resolve7({ code, signal }));
25029
+ const processExit = new Promise((resolve9) => {
25030
+ child.once("exit", (code, signal) => resolve9({ code, signal }));
24938
25031
  });
24939
- const outputEnded = new Promise((resolve7) => {
24940
- child.stdout.once("close", () => resolve7());
25032
+ const outputEnded = new Promise((resolve9) => {
25033
+ child.stdout.once("close", () => resolve9());
24941
25034
  });
24942
25035
  const watch = async () => {
24943
25036
  const { clock, stdoutDrainMs, log, name } = options;
@@ -24993,11 +25086,11 @@ function silentStartError(name, timeoutMs) {
24993
25086
  };
24994
25087
  }
24995
25088
  var import_crypto3, import_fs4, import_path3, PNG_SIGNATURE, IMAGE_MIME_BY_EXT, VIDEO_MIME_BY_EXT, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, AGENT_BROWSER_MENTION, LocalMediaReader, SessionOpenRefusal, JsonRpcError, ACP_PROTOCOL_VERSION, ACP_ERROR, STDERR_TAIL_LINES, RESULT_EXIT_GRACE_MS, PerTurnSession;
24996
- var init_chunk_72NSEYHK = __esm({
24997
- "../agent-core/dist/chunk-72NSEYHK.js"() {
25089
+ var init_chunk_4G77APXN = __esm({
25090
+ "../agent-core/dist/chunk-4G77APXN.js"() {
24998
25091
  "use strict";
24999
25092
  init_chunk_XC5676SG();
25000
- init_chunk_54ZRJOQP();
25093
+ init_chunk_HBIPWAUI();
25001
25094
  init_chunk_M6YHY2EZ();
25002
25095
  init_chunk_YXWJW7I5();
25003
25096
  import_crypto3 = require("crypto");
@@ -25227,13 +25320,13 @@ var init_chunk_72NSEYHK = __esm({
25227
25320
  const turnId = input2.turnId;
25228
25321
  let finish = () => {
25229
25322
  };
25230
- const done = new Promise((resolve7) => {
25323
+ const done = new Promise((resolve9) => {
25231
25324
  finish = (outcome2) => {
25232
25325
  if (this.#current?.id !== turnId) return;
25233
25326
  this.#current = void 0;
25234
25327
  if (this.#state === "busy") this.#state = "idle";
25235
25328
  this.#emit({ type: "turn_ended", turnId, outcome: outcome2 });
25236
- resolve7({ turnId, outcome: outcome2, providerSessionId: this.#sessionId });
25329
+ resolve9({ turnId, outcome: outcome2, providerSessionId: this.#sessionId });
25237
25330
  };
25238
25331
  });
25239
25332
  const pending = {
@@ -25429,20 +25522,20 @@ function canonicalizeManagedMcpToolName(toolName) {
25429
25522
  return flattened ? `mcp__${MANAGED_MCP_SERVER_NAME}__${flattened[1]}` : toolName;
25430
25523
  }
25431
25524
  async function writeSecretFile(name, contents) {
25432
- const dir = await (0, import_promises13.mkdtemp)((0, import_path4.join)((0, import_os2.tmpdir)(), "alan-mcp-"));
25525
+ const dir = await (0, import_promises14.mkdtemp)((0, import_path4.join)((0, import_os2.tmpdir)(), "alan-mcp-"));
25433
25526
  const path = (0, import_path4.join)(dir, name);
25434
25527
  const remove = async () => {
25435
- await (0, import_promises13.rm)(dir, { recursive: true, force: true });
25528
+ await (0, import_promises14.rm)(dir, { recursive: true, force: true });
25436
25529
  };
25437
25530
  try {
25438
- await (0, import_promises13.writeFile)(path, contents, { mode: 384, flag: "wx" });
25531
+ await (0, import_promises14.writeFile)(path, contents, { mode: 384, flag: "wx" });
25439
25532
  } catch (error61) {
25440
25533
  await remove();
25441
25534
  throw error61;
25442
25535
  }
25443
25536
  return { path, remove, [Symbol.asyncDispose]: remove };
25444
25537
  }
25445
- var import_crypto4, import_crypto5, import_promises13, import_os2, import_path4, MANAGED_MCP_SERVER_NAME, RUN_SCOPED_SERVER, NAMESPACED_RUN_TOOL, FLATTENED_RUN_TOOL;
25538
+ var import_crypto4, import_crypto5, import_promises14, import_os2, import_path4, MANAGED_MCP_SERVER_NAME, RUN_SCOPED_SERVER, NAMESPACED_RUN_TOOL, FLATTENED_RUN_TOOL;
25446
25539
  var init_chunk_J2KTV5FP = __esm({
25447
25540
  "../agent-core/dist/chunk-J2KTV5FP.js"() {
25448
25541
  "use strict";
@@ -25451,7 +25544,7 @@ var init_chunk_J2KTV5FP = __esm({
25451
25544
  import_crypto5 = require("crypto");
25452
25545
  init_agent2();
25453
25546
  init_runtime_v2();
25454
- import_promises13 = require("fs/promises");
25547
+ import_promises14 = require("fs/promises");
25455
25548
  import_os2 = require("os");
25456
25549
  import_path4 = require("path");
25457
25550
  MANAGED_MCP_SERVER_NAME = "alan";
@@ -26894,19 +26987,19 @@ async function claudeTurnInput(run, context) {
26894
26987
  const encoded = await Promise.all(
26895
26988
  images.map(async (image) => ({
26896
26989
  mimeType: image.mimeType,
26897
- data: (await (0, import_promises14.readFile)(image.path)).toString("base64")
26990
+ data: (await (0, import_promises15.readFile)(image.path)).toString("base64")
26898
26991
  }))
26899
26992
  );
26900
26993
  return { turnId: run.runId, text: text2, ...encoded.length ? { images: encoded } : {} };
26901
26994
  }
26902
- var import_crypto6, import_fs5, import_path5, import_crypto7, import_promises14, EDIT_TOOLS, ThoughtBlocks, UNDERSTOOD_SYSTEM_SUBTYPES, RATE_LIMIT_WARN_AT, CLAUDE_GRAMMAR_NAME, SUBAGENT_TOOL_NAMES, PLAN_ENTRY_STATUSES, controlResponseSchema, STOPPED_STATUSES, TaskRecords, TERMINAL_BACKGROUND_STATUSES, NON_TERMINAL_BACKGROUND_STATUSES, ASYNC_LAUNCH_ACK, BackgroundTasks, FAILED_STATUSES, STOPPED_BY_USER_TEXT, ClaudeTurn, STDERR_TAIL_LINES2, MAX_EARLY_LINES, UNSUPPORTED_STOP, OUTPUT_CLOSED_REASON, ClaudeSession, DEFAULTS, READ_ONLY_DISALLOWED_TOOLS, DEFAULT_MCP_TIMEOUT_MS;
26995
+ var import_crypto6, import_fs5, import_path5, import_crypto7, import_promises15, EDIT_TOOLS, ThoughtBlocks, UNDERSTOOD_SYSTEM_SUBTYPES, RATE_LIMIT_WARN_AT, CLAUDE_GRAMMAR_NAME, SUBAGENT_TOOL_NAMES, PLAN_ENTRY_STATUSES, controlResponseSchema, STOPPED_STATUSES, TaskRecords, TERMINAL_BACKGROUND_STATUSES, NON_TERMINAL_BACKGROUND_STATUSES, ASYNC_LAUNCH_ACK, BackgroundTasks, FAILED_STATUSES, STOPPED_BY_USER_TEXT, ClaudeTurn, STDERR_TAIL_LINES2, MAX_EARLY_LINES, UNSUPPORTED_STOP, OUTPUT_CLOSED_REASON, ClaudeSession, DEFAULTS, READ_ONLY_DISALLOWED_TOOLS, DEFAULT_MCP_TIMEOUT_MS;
26903
26996
  var init_claude = __esm({
26904
26997
  "../agent-core/dist/providers/claude.js"() {
26905
26998
  "use strict";
26906
26999
  init_chunk_SBT5W7L4();
26907
- init_chunk_72NSEYHK();
27000
+ init_chunk_4G77APXN();
26908
27001
  init_chunk_XC5676SG();
26909
- init_chunk_54ZRJOQP();
27002
+ init_chunk_HBIPWAUI();
26910
27003
  init_chunk_J2KTV5FP();
26911
27004
  init_chunk_M6YHY2EZ();
26912
27005
  init_chunk_FPGAN4XO();
@@ -26922,7 +27015,7 @@ var init_claude = __esm({
26922
27015
  import_fs5 = require("fs");
26923
27016
  import_path5 = require("path");
26924
27017
  import_crypto7 = require("crypto");
26925
- import_promises14 = require("fs/promises");
27018
+ import_promises15 = require("fs/promises");
26926
27019
  init_agent2();
26927
27020
  EDIT_TOOLS = /* @__PURE__ */ new Set([
26928
27021
  "Edit",
@@ -27632,8 +27725,8 @@ var init_claude = __esm({
27632
27725
  }
27633
27726
  async #awaitTaskStop(requestId, taskId) {
27634
27727
  const timer = new AbortController();
27635
- const answered = new Promise((resolve7) => {
27636
- this.#taskStops.set(requestId, resolve7);
27728
+ const answered = new Promise((resolve9) => {
27729
+ this.#taskStops.set(requestId, resolve9);
27637
27730
  });
27638
27731
  const timeoutMs = this.#options.stopTaskTimeoutMs;
27639
27732
  const timedOut = this.#options.clock.sleep(timeoutMs, timer.signal).then(
@@ -27706,17 +27799,17 @@ var init_claude = __esm({
27706
27799
  };
27707
27800
  let markStarted = () => {
27708
27801
  };
27709
- const whenStarted = new Promise((resolve7) => {
27710
- markStarted = resolve7;
27802
+ const whenStarted = new Promise((resolve9) => {
27803
+ markStarted = resolve9;
27711
27804
  });
27712
- const done = new Promise((resolve7) => {
27805
+ const done = new Promise((resolve9) => {
27713
27806
  finish = (outcome2) => {
27714
27807
  if (this.#current?.id !== id) return;
27715
27808
  this.#current = void 0;
27716
27809
  this.#lastTurn = turn;
27717
27810
  if (this.#state === "busy") this.#state = "idle";
27718
27811
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
27719
- resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#providerSessionId });
27812
+ resolve9({ turnId: id, outcome: outcome2, providerSessionId: this.#providerSessionId });
27720
27813
  };
27721
27814
  });
27722
27815
  const active = {
@@ -27834,8 +27927,8 @@ var init_claude = __esm({
27834
27927
  void removeLaunchFiles(this.#launchFiles).catch((error61) => {
27835
27928
  this.#options.log.warn("claude.launch_files_cleanup_failed", { error: error61 });
27836
27929
  });
27837
- for (const resolve7 of this.#taskStops.values()) {
27838
- resolve7({ ok: false, reason: "runtime_unavailable", message: "Claude Code exited." });
27930
+ for (const resolve9 of this.#taskStops.values()) {
27931
+ resolve9({ ok: false, reason: "runtime_unavailable", message: "Claude Code exited." });
27839
27932
  }
27840
27933
  const active = this.#current;
27841
27934
  if (active) {
@@ -28208,6 +28301,67 @@ function imageKey(update) {
28208
28301
  const image = asRecord(update.image);
28209
28302
  return asString(image?.sourceHash) || asString(image?.id) || void 0;
28210
28303
  }
28304
+ function windowPatch(value) {
28305
+ if (value === null) return null;
28306
+ const record2 = asRecord(value);
28307
+ if (!record2) return void 0;
28308
+ const patch = {};
28309
+ const usedPercent = asFiniteNumber(record2.usedPercent);
28310
+ if (usedPercent !== void 0 && usedPercent >= 0 && usedPercent <= 100) {
28311
+ patch.usedPercent = usedPercent;
28312
+ } else if (record2.usedPercent === null) {
28313
+ patch.usedPercent = null;
28314
+ }
28315
+ const duration3 = asFiniteNumber(record2.windowDurationMins);
28316
+ if (duration3 !== void 0 && duration3 > 0) patch.windowMinutes = duration3;
28317
+ else if (record2.windowDurationMins === null) patch.windowMinutes = null;
28318
+ const seconds = asFiniteNumber(record2.resetsAt);
28319
+ if (seconds !== void 0 && seconds >= 0) {
28320
+ const reset = new Date(seconds * 1e3);
28321
+ if (Number.isFinite(reset.getTime())) patch.resetsAt = reset.toISOString();
28322
+ } else if (record2.resetsAt === null) {
28323
+ patch.resetsAt = null;
28324
+ }
28325
+ return patch;
28326
+ }
28327
+ function amount(value) {
28328
+ const text2 = asString(value).trim();
28329
+ return text2.length > 0 ? text2 : void 0;
28330
+ }
28331
+ function spendPatch(limit, reached) {
28332
+ const record2 = asRecord(limit);
28333
+ const reachedFlag = reached === true;
28334
+ if (!record2)
28335
+ return limit === null && !reachedFlag ? null : reachedFlag ? { reached: true } : void 0;
28336
+ const patch = { reached: reachedFlag };
28337
+ const limitAmount = amount(record2.limit);
28338
+ const usedAmount = amount(record2.used);
28339
+ if (limitAmount) patch.limit = limitAmount;
28340
+ if (usedAmount) patch.used = usedAmount;
28341
+ const remainingPercent = asFiniteNumber(record2.remainingPercent);
28342
+ if (remainingPercent !== void 0) {
28343
+ patch.usedPercent = Math.min(100, Math.max(0, 100 - remainingPercent));
28344
+ }
28345
+ const seconds = asFiniteNumber(record2.resetsAt);
28346
+ if (seconds !== void 0 && seconds >= 0) {
28347
+ const reset = new Date(seconds * 1e3);
28348
+ if (Number.isFinite(reset.getTime())) patch.resetsAt = reset.toISOString();
28349
+ }
28350
+ return patch;
28351
+ }
28352
+ function creditsPatch(value) {
28353
+ if (value === null) return null;
28354
+ const record2 = asRecord(value);
28355
+ if (!record2 || typeof record2.hasCredits !== "boolean" || typeof record2.unlimited !== "boolean") {
28356
+ return void 0;
28357
+ }
28358
+ const balance = amount(record2.balance);
28359
+ return {
28360
+ hasCredits: record2.hasCredits,
28361
+ unlimited: record2.unlimited,
28362
+ ...balance ? { balance } : {}
28363
+ };
28364
+ }
28211
28365
  function isApprovalRequest(method) {
28212
28366
  return COMMAND_OR_FILE.has(method) || LEGACY.has(method);
28213
28367
  }
@@ -28619,7 +28773,10 @@ function classifyCodexError(error61) {
28619
28773
  const message = asString(error61?.message);
28620
28774
  const known = typeof info === "string" ? INFO_KINDS.get(info) : void 0;
28621
28775
  const own2 = normalizeCodexCliErrorMessage(message.trim());
28622
- if (known) return own2 ? { ...specForErrorKind(known), message: own2 } : specForErrorKind(known);
28776
+ if (known) {
28777
+ const classified = own2 ? { ...specForErrorKind(known), message: own2 } : specForErrorKind(known);
28778
+ return known === "usage_limit" ? { ...classified, ...readCapReset(message) } : classified;
28779
+ }
28623
28780
  const status = httpStatusOf(info);
28624
28781
  return classifyProviderError(message, status === void 0 ? {} : { status });
28625
28782
  }
@@ -28703,7 +28860,7 @@ async function handshake(session, spec, log) {
28703
28860
  }
28704
28861
  await session.rpc.notify("initialized");
28705
28862
  }
28706
- async function preflight(session, spec) {
28863
+ async function preflight(session, spec, log) {
28707
28864
  if (spec.externalAuth) {
28708
28865
  const tokens2 = await spec.externalAuth.current();
28709
28866
  await session.rpc.request("account/login/start", {
@@ -28721,6 +28878,13 @@ async function preflight(session, spec) {
28721
28878
  specForErrorKind("not_logged_in")
28722
28879
  );
28723
28880
  }
28881
+ if (spec.externalAuth) {
28882
+ try {
28883
+ session.observeRateLimits(await session.rpc.request("account/rateLimits/read", {}));
28884
+ } catch {
28885
+ log.warn("codex.rate_limits_unavailable", {});
28886
+ }
28887
+ }
28724
28888
  }
28725
28889
  function threadOf(result) {
28726
28890
  const thread = asRecord(asRecord(result)?.thread);
@@ -28782,7 +28946,7 @@ function createCodexDriver(options = {}) {
28782
28946
  try {
28783
28947
  const opening = (async () => {
28784
28948
  await handshake(session, spec, resolved.log);
28785
- await preflight(session, spec);
28949
+ await preflight(session, spec, resolved.log);
28786
28950
  return openThread(session, spec, resolved.log);
28787
28951
  })();
28788
28952
  const thread = await withDeadline(
@@ -28933,7 +29097,7 @@ function createCodexExecDriver(options = {}) {
28933
29097
  };
28934
29098
  }
28935
29099
  function envDigest2(env) {
28936
- const hash2 = (0, import_crypto9.createHash)("sha256");
29100
+ const hash2 = (0, import_crypto10.createHash)("sha256");
28937
29101
  for (const key of Object.keys(env).sort()) hash2.update(`${key}\0${env[key]}\0`);
28938
29102
  return hash2.digest("hex");
28939
29103
  }
@@ -28974,7 +29138,7 @@ function planCodexExecSession(run, context) {
28974
29138
  };
28975
29139
  }
28976
29140
  function envDigest22(env) {
28977
- const hash2 = (0, import_crypto10.createHash)("sha256");
29141
+ const hash2 = (0, import_crypto11.createHash)("sha256");
28978
29142
  for (const key of Object.keys(env).sort()) hash2.update(`${key}\0${env[key]}\0`);
28979
29143
  return hash2.digest("hex");
28980
29144
  }
@@ -29043,14 +29207,14 @@ function codexTurnInput(run, context) {
29043
29207
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
29044
29208
  };
29045
29209
  }
29046
- var import_fs6, import_path6, import_crypto8, import_crypto9, import_crypto10, 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, 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, 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;
29210
+ var import_fs6, import_path6, import_crypto8, import_crypto9, import_crypto10, import_crypto11, 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, 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;
29047
29211
  var init_codex = __esm({
29048
29212
  "../agent-core/dist/providers/codex.js"() {
29049
29213
  "use strict";
29050
29214
  init_chunk_SBT5W7L4();
29051
- init_chunk_72NSEYHK();
29215
+ init_chunk_4G77APXN();
29052
29216
  init_chunk_XC5676SG();
29053
- init_chunk_54ZRJOQP();
29217
+ init_chunk_HBIPWAUI();
29054
29218
  init_chunk_J2KTV5FP();
29055
29219
  init_chunk_M6YHY2EZ();
29056
29220
  init_chunk_FPGAN4XO();
@@ -29059,10 +29223,12 @@ var init_codex = __esm({
29059
29223
  import_path6 = require("path");
29060
29224
  init_effort();
29061
29225
  import_crypto8 = require("crypto");
29062
- init_agent2();
29063
29226
  import_crypto9 = require("crypto");
29227
+ init_runtime_v2();
29064
29228
  init_agent2();
29065
29229
  import_crypto10 = require("crypto");
29230
+ init_agent2();
29231
+ import_crypto11 = require("crypto");
29066
29232
  init_effort();
29067
29233
  TokenRefresher = class {
29068
29234
  #auth;
@@ -29246,6 +29412,50 @@ var init_codex = __esm({
29246
29412
  return this.#cursor;
29247
29413
  }
29248
29414
  };
29415
+ CodexRateLimits = class {
29416
+ #clock;
29417
+ #sourceId;
29418
+ #sequence = 0;
29419
+ constructor(clock, sourceId = (0, import_crypto9.randomUUID)()) {
29420
+ this.#clock = clock;
29421
+ this.#sourceId = sourceId;
29422
+ }
29423
+ read(value) {
29424
+ const response = asRecord(value);
29425
+ const buckets = asRecord(response?.rateLimitsByLimitId);
29426
+ if (buckets) {
29427
+ return Object.entries(buckets).flatMap(
29428
+ ([limitId, snapshot2]) => this.#update(snapshot2, limitId)
29429
+ );
29430
+ }
29431
+ return this.#update(response?.rateLimits);
29432
+ }
29433
+ notification(params) {
29434
+ return this.#update(params.rateLimits);
29435
+ }
29436
+ #update(value, bucketId) {
29437
+ const snapshot2 = asRecord(value);
29438
+ if (!snapshot2) return [];
29439
+ const primary = windowPatch(snapshot2.primary);
29440
+ const secondary = windowPatch(snapshot2.secondary);
29441
+ const spend = spendPatch(snapshot2.individualLimit, snapshot2.spendControlReached);
29442
+ const credits = creditsPatch(snapshot2.credits);
29443
+ const planType = snapshot2.planType === null ? null : asString(snapshot2.planType) || void 0;
29444
+ const parsed = runCodexRateLimitsUpdateSchema.safeParse({
29445
+ sessionUpdate: "_alan/codex.rate_limits",
29446
+ limitId: bucketId ?? (asString(snapshot2.limitId) || "codex"),
29447
+ ...primary === void 0 ? {} : { primary },
29448
+ ...secondary === void 0 ? {} : { secondary },
29449
+ ...spend === void 0 ? {} : { spend },
29450
+ ...credits === void 0 ? {} : { credits },
29451
+ ...planType === void 0 ? {} : { planType },
29452
+ observedAt: new Date(this.#clock.now()).toISOString(),
29453
+ sourceId: this.#sourceId,
29454
+ sequence: this.#sequence++
29455
+ });
29456
+ return parsed.success ? [parsed.data] : [];
29457
+ }
29458
+ };
29249
29459
  USER_INPUT_METHOD = "item/tool/requestUserInput";
29250
29460
  PERMISSIONS_METHOD = "item/permissions/requestApproval";
29251
29461
  ELICITATION_METHOD = "mcpServer/elicitation/request";
@@ -29315,7 +29525,6 @@ var init_codex = __esm({
29315
29525
  "thread/closed",
29316
29526
  "hook/started",
29317
29527
  "hook/completed",
29318
- "account/rateLimits/updated",
29319
29528
  "account/updated",
29320
29529
  "account/login/completed",
29321
29530
  "remoteControl/status/changed",
@@ -29510,6 +29719,7 @@ var init_codex = __esm({
29510
29719
  #listeners = createListeners();
29511
29720
  #options;
29512
29721
  #memory;
29722
+ #rateLimits;
29513
29723
  #stderr = [];
29514
29724
  #approvals = /* @__PURE__ */ new Map();
29515
29725
  /** Session-level updates (thread start warnings, MCP startup) that open the next turn's log. */
@@ -29526,6 +29736,7 @@ var init_codex = __esm({
29526
29736
  constructor(child, tree, memory, options) {
29527
29737
  this.#options = options;
29528
29738
  this.#memory = memory;
29739
+ this.#rateLimits = new CodexRateLimits(options.clock);
29529
29740
  this.#lastTurn = new CodexTurn(memory, options.clock);
29530
29741
  this.#host = hostProcess(
29531
29742
  child,
@@ -29560,6 +29771,9 @@ var init_codex = __esm({
29560
29771
  configure(config2) {
29561
29772
  this.#config = config2;
29562
29773
  }
29774
+ observeRateLimits(response) {
29775
+ this.#recordRateLimits(this.#rateLimits.read(response));
29776
+ }
29563
29777
  attachThread(threadId, rolloutPath) {
29564
29778
  if (threadId === this.#threadId) return;
29565
29779
  this.#threadId = threadId;
@@ -29672,10 +29886,10 @@ var init_codex = __esm({
29672
29886
  };
29673
29887
  let identify = () => {
29674
29888
  };
29675
- const identified = new Promise((resolve7) => {
29676
- identify = resolve7;
29889
+ const identified = new Promise((resolve9) => {
29890
+ identify = resolve9;
29677
29891
  });
29678
- const done = new Promise((resolve7) => {
29892
+ const done = new Promise((resolve9) => {
29679
29893
  finish = (outcome2) => {
29680
29894
  if (this.#current?.id !== id) return;
29681
29895
  this.#current = void 0;
@@ -29683,7 +29897,7 @@ var init_codex = __esm({
29683
29897
  if (this.#state === "busy") this.#state = "idle";
29684
29898
  this.#host.scanDescendants(true);
29685
29899
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
29686
- resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#threadId });
29900
+ resolve9({ turnId: id, outcome: outcome2, providerSessionId: this.#threadId });
29687
29901
  };
29688
29902
  });
29689
29903
  const active = {
@@ -29726,6 +29940,10 @@ var init_codex = __esm({
29726
29940
  return known === void 0 || known === turnId ? active : void 0;
29727
29941
  }
29728
29942
  #onNotification(notification) {
29943
+ if (notification.method === "account/rateLimits/updated") {
29944
+ this.#recordRateLimits(this.#rateLimits.notification(notification.params));
29945
+ return;
29946
+ }
29729
29947
  if (notification.method === "serverRequest/resolved") this.#dropResolved(notification);
29730
29948
  const active = this.#ownerOf(notification);
29731
29949
  const reader = active?.turn ?? this.#lastTurn;
@@ -29752,6 +29970,14 @@ var init_codex = __esm({
29752
29970
  void this.#stopTurn(active);
29753
29971
  }
29754
29972
  }
29973
+ #recordRateLimits(updates) {
29974
+ const active = this.#current;
29975
+ if (active) this.#emitUpdates(active, updates);
29976
+ else {
29977
+ this.#between.push(...updates);
29978
+ this.#between.splice(0, Math.max(0, this.#between.length - MAX_BETWEEN_UPDATES));
29979
+ }
29980
+ }
29755
29981
  #emitUpdates(active, updates) {
29756
29982
  for (const update of updates) this.#emit({ type: "update", turnId: active.id, update });
29757
29983
  }
@@ -30161,7 +30387,7 @@ function alanCodeConfigContent(existing, input2) {
30161
30387
  });
30162
30388
  }
30163
30389
  function readBody2(response) {
30164
- return new Promise((resolve7, reject) => {
30390
+ return new Promise((resolve9, reject) => {
30165
30391
  const chunks = [];
30166
30392
  let size = 0;
30167
30393
  response.on("data", (chunk) => {
@@ -30169,7 +30395,7 @@ function readBody2(response) {
30169
30395
  if (size > MAX_CATALOG_BYTES) response.destroy(new Error("catalog too large"));
30170
30396
  else chunks.push(chunk);
30171
30397
  });
30172
- response.on("end", () => resolve7(Buffer.concat(chunks).toString("utf8")));
30398
+ response.on("end", () => resolve9(Buffer.concat(chunks).toString("utf8")));
30173
30399
  response.on("error", reject);
30174
30400
  });
30175
30401
  }
@@ -30185,13 +30411,13 @@ function parseResponseBody(text2, status) {
30185
30411
  }
30186
30412
  function getJson(url2, headers, timeout, signal) {
30187
30413
  const request2 = url2.protocol === "https:" ? import_https.request : import_http3.request;
30188
- return new Promise((resolve7, reject) => {
30414
+ return new Promise((resolve9, reject) => {
30189
30415
  const outgoing = request2(url2, { method: "GET", headers, timeout, signal }, (response) => {
30190
30416
  const status = response.statusCode ?? 0;
30191
30417
  readBody2(response).then((text2) => {
30192
30418
  const body = parseResponseBody(text2, status);
30193
30419
  if (status < 200 || status >= 300) reject(new CatalogResponseError(status, body));
30194
- else resolve7(body);
30420
+ else resolve9(body);
30195
30421
  }).catch(reject);
30196
30422
  });
30197
30423
  outgoing.on("timeout", () => outgoing.destroy(new Error("catalog timed out")));
@@ -30405,18 +30631,18 @@ function alanCodeEngineEnv(input2) {
30405
30631
  };
30406
30632
  }
30407
30633
  async function writePlugin(directory, apiOrigin) {
30408
- const origin = (0, import_crypto11.createHash)("sha256").update(apiOrigin).digest("hex").slice(0, 12);
30634
+ const origin = (0, import_crypto12.createHash)("sha256").update(apiOrigin).digest("hex").slice(0, 12);
30409
30635
  const target = (0, import_path8.join)(directory, `engine-plugin-v${ALAN_CODE_ENGINE_PLUGIN_VERSION}-${origin}.mjs`);
30410
- const temporary = `${target}.${(0, import_crypto11.randomUUID)()}.tmp`;
30411
- await (0, import_promises15.mkdir)(directory, { recursive: true, mode: 448 });
30412
- await (0, import_promises15.writeFile)(temporary, alanCodeEnginePluginSource(apiOrigin), { mode: 384 });
30413
- await (0, import_promises15.rename)(temporary, target);
30636
+ const temporary = `${target}.${(0, import_crypto12.randomUUID)()}.tmp`;
30637
+ await (0, import_promises16.mkdir)(directory, { recursive: true, mode: 448 });
30638
+ await (0, import_promises16.writeFile)(temporary, alanCodeEnginePluginSource(apiOrigin), { mode: 384 });
30639
+ await (0, import_promises16.rename)(temporary, target);
30414
30640
  return (0, import_url.pathToFileURL)(target).href;
30415
30641
  }
30416
30642
  async function prepareAlanCodeProfile(input2) {
30417
30643
  const directories = Object.values(alanCodeEngineDirectories(input2.engineRoot));
30418
30644
  await Promise.all(
30419
- directories.map((directory) => (0, import_promises15.mkdir)(directory, { recursive: true, mode: 448 }))
30645
+ directories.map((directory) => (0, import_promises16.mkdir)(directory, { recursive: true, mode: 448 }))
30420
30646
  );
30421
30647
  const [pluginUrl, models] = await Promise.all([
30422
30648
  writePlugin((0, import_path8.join)(input2.engineRoot, "plugin"), input2.access.apiOrigin),
@@ -30439,7 +30665,7 @@ function alanCodeSystemPrompt(alanSystemPrompt) {
30439
30665
 
30440
30666
  ${instructions}` : ALAN_CODE_TOOL_NAMING_PROMPT;
30441
30667
  }
30442
- var import_http3, import_https, import_fs7, import_path7, import_crypto11, import_promises15, import_path8, import_url, ALAN_CODE_BASELINE_PROMPT, ALAN_CODE_ENGINE_PROVIDER_ID, DEFAULT_CONTEXT_WINDOW, DEFAULT_MAX_OUTPUT_TOKENS, ALAN_CODE_API_KEY_ENV, ALAN_CODE_CONVERSATION_ID_ENV, ALAN_CODE_PROXY_PATH, ALAN_CODE_WEBSEARCH_PATH, ALAN_CODE_CATALOG_PATH, CATALOG_TIMEOUT_MS, MAX_CATALOG_BYTES, ACTIVATION_WAIT_MS, ACTIVATION_POLL_MS, CatalogResponseError, ALAN_CODE_ENGINE_PATH_ENV, ALAN_CODE_ENGINE_COMMAND, ALAN_CODE_ENGINE_NAME, WINDOWS_RUNNABLE_EXTENSION, ALAN_CODE_ENGINE_PLUGIN_VERSION, ALAN_CODE_TOOL_NAMING_PROMPT;
30668
+ var import_http3, import_https, import_fs7, import_path7, import_crypto12, import_promises16, import_path8, import_url, ALAN_CODE_BASELINE_PROMPT, ALAN_CODE_ENGINE_PROVIDER_ID, DEFAULT_CONTEXT_WINDOW, DEFAULT_MAX_OUTPUT_TOKENS, ALAN_CODE_API_KEY_ENV, ALAN_CODE_CONVERSATION_ID_ENV, ALAN_CODE_PROXY_PATH, ALAN_CODE_WEBSEARCH_PATH, ALAN_CODE_CATALOG_PATH, CATALOG_TIMEOUT_MS, MAX_CATALOG_BYTES, ACTIVATION_WAIT_MS, ACTIVATION_POLL_MS, CatalogResponseError, ALAN_CODE_ENGINE_PATH_ENV, ALAN_CODE_ENGINE_COMMAND, ALAN_CODE_ENGINE_NAME, WINDOWS_RUNNABLE_EXTENSION, ALAN_CODE_ENGINE_PLUGIN_VERSION, ALAN_CODE_TOOL_NAMING_PROMPT;
30443
30669
  var init_alan_code = __esm({
30444
30670
  "../agent-core/dist/providers/alan-code.js"() {
30445
30671
  "use strict";
@@ -30452,8 +30678,8 @@ var init_alan_code = __esm({
30452
30678
  import_fs7 = require("fs");
30453
30679
  import_path7 = require("path");
30454
30680
  init_runtime_v2();
30455
- import_crypto11 = require("crypto");
30456
- import_promises15 = require("fs/promises");
30681
+ import_crypto12 = require("crypto");
30682
+ import_promises16 = require("fs/promises");
30457
30683
  import_path8 = require("path");
30458
30684
  import_url = require("url");
30459
30685
  ALAN_CODE_BASELINE_PROMPT = "You are alan-code, an interactive CLI coding agent that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.\n\nDo not invent URLs. Use verified URLs or ones supplied by the user or project.\n\nIf the user asks for help or wants to give feedback, inform them of the following:\n- `--harness-help` / harness help: learn how to run alan-code\n- For product feedback or bugs, report through the Alan / Supatest issue channels used by this repository\n\nWhen the user directly asks about alan-code capabilities (for example \"can alan-code\u2026\", \"does the harness have\u2026\") or asks in second person about your abilities, answer from the tools and instructions available in this session. If a docs/fetch tool is available and project docs URLs are known, use them; otherwise inspect local README / AGENTS.md rather than inventing product claims.\n\n# Personality\n\nYour default personality and tone is concise, direct, and friendly. You communicate efficiently, always keeping the user clearly informed about ongoing actions without unnecessary detail. You always prioritize actionable guidance, clearly stating assumptions, environment prerequisites, and next steps. Unless explicitly asked, you avoid excessively verbose explanations about your work.\n\n# Tone and style\n\nYou should be concise, direct, and to the point. When you run a non-trivial bash command, you should explain what the command does and why you are running it, so the user understands what you are doing (especially important for commands that change their system).\nRemember that your output will be displayed on a command line interface. Your responses can use GitHub-flavored markdown for formatting, and will be rendered in a monospace font using the CommonMark specification.\nOutput text to communicate with the user; all text you output outside of tool use is displayed to the user. Only use tools to complete tasks. Never use tools like Bash or code comments as means to communicate with the user during the session.\nIf you cannot or will not help the user with something, do not lecture about why. Offer helpful alternatives if possible; otherwise keep the response to 1-2 sentences.\nOnly use emojis if the user explicitly requests it. Avoid emojis in all communication unless asked.\nIMPORTANT: Minimize output tokens while staying helpful, correct, and accurate. Only address the specific query or task. Avoid tangential information unless it is critical to completing the request. If you can answer in 1-3 sentences or a short paragraph, do that.\nAnswer the user's question directly. One-word answers are best when they suffice. Avoid text before/after your response such as \"The answer is <answer>.\", \"Here is the content of the file\u2026\", \"Based on the information provided\u2026\", or \"Here is what I will do next\u2026\". Examples of appropriate verbosity:\n<example>\nuser: what is 2+2?\nassistant: 4\n</example>\n\n<example>\nuser: is 11 a prime number?\nassistant: Yes\n</example>\n\n<example>\nuser: what command should I run to list files in the current directory?\nassistant: ls\n</example>\n\n<example>\nuser: what command should I run to watch files in the current directory?\nassistant: [use tools to inspect the project, then answer]\nnpm run dev\n</example>\n\n<example>\nuser: what files are in the directory src/?\nassistant: [lists files and sees foo.c, bar.c, baz.c]\nuser: which file contains the implementation of foo?\nassistant: src/foo.c\n</example>\n\n<example>\nuser: write tests for new feature\nassistant: [searches for similar tests, reads relevant files concurrently, edits/writes tests]\n</example>\n\n# Responsiveness\n\n## Preamble messages\n\nBefore making tool calls, send a brief preamble to the user explaining what you're about to do. When sending preamble messages, follow these principles and examples:\n\n- **Logically group related actions**: if you're about to run several related commands, describe them together in one preamble rather than sending a separate note for each.\n- **Keep it concise**: be no more than 1-2 sentences, focused on immediate, tangible next steps. (8\u201312 words for quick updates).\n- **Build on prior context**: if this is not your first tool call, use the preamble message to connect the dots with what's been done so far and create a sense of momentum and clarity for the user to understand your next actions.\n- **Keep your tone light, friendly and curious**: add small touches of personality in preambles feel collaborative and engaging.\n- **Exception**: Avoid adding a preamble for every trivial read (e.g., `cat` a single file) unless it's part of a larger grouped action.\n\nExamples:\n\n- \"I've explored the repo; now checking the API route definitions.\"\n- \"Next, I'll patch the config and update the related tests.\"\n- \"I'm about to scaffold the CLI commands and helper functions.\"\n- \"Ok cool, so I've wrapped my head around the repo. Now digging into the API routes.\"\n- \"Config's looking tidy. Next up is patching helpers to keep things in sync.\"\n- \"Finished poking at the DB gateway. I will now chase down error handling.\"\n- \"Alright, build pipeline order is interesting. Checking how it reports failures.\"\n- \"Spotted a clever caching util; now hunting where it gets used.\"\n\n# Planning\n\nIf a planning tool is available, use it when it helps track complex work. Keep the plan brief and update it as work progresses.\n\nNote that plans are not for padding out simple work with filler steps or stating the obvious. The content of your plan should not involve doing anything that you aren't capable of doing (i.e. don't try to test things that you can't test). Do not use plans for simple or single-step queries that you can just do or answer immediately.\n\nWhen a planning tool displays the plan, summarize only what changed or what comes next.\n\nKeep any active plan aligned with the work completed and remaining.\n\nUse a plan when:\n\n- The task is non-trivial and will require multiple actions over a long time horizon.\n- There are logical phases or dependencies where sequencing matters.\n- The work has ambiguity that benefits from outlining high-level goals.\n- You want intermediate checkpoints for feedback and validation.\n- When the user asked you to do more than one thing in a single prompt\n- The user has asked you to use the plan tool (aka \"TODOs\")\n- You generate additional steps while working, and plan to do them before yielding to the user\n\n## Examples\n\n**High-quality plans**\n\nExample 1:\n\n1. Add CLI entry with file args\n2. Parse Markdown via CommonMark library\n3. Apply semantic HTML template\n4. Handle code blocks, images, links\n5. Add error handling for invalid files\n\nExample 2:\n\n1. Define CSS variables for colors\n2. Add toggle with localStorage state\n3. Refactor components to use variables\n4. Verify all views for readability\n5. Add smooth theme-change transition\n\nExample 3:\n\n1. Set up Node.js + WebSocket server\n2. Add join/leave broadcast events\n3. Implement messaging with timestamps\n4. Add usernames + mention highlighting\n5. Persist messages in lightweight DB\n6. Add typing indicators + unread count\n\n**Low-quality plans**\n\nExample 1:\n\n1. Create CLI tool\n2. Add Markdown parser\n3. Convert to HTML\n\nExample 2:\n\n1. Add dark mode toggle\n2. Save preference\n3. Make styles look good\n\nExample 3:\n\n1. Create single-file HTML game\n2. Run quick sanity check\n3. Summarize usage instructions\n\nIf you need to write a plan, only write high quality plans, not low quality ones.\n\n## Plan mode and clarification (harness specifics)\n\n- When the session is in plan mode, inspect without making changes and produce a concrete plan. Outside plan mode, proceed with authorized work and ask for approval only when the action requires it.\n- Prefer the durable plan file path over relying on chat memory after compaction.\n- When requirements are ambiguous, ask a targeted question using an available user-input tool instead of guessing.\n- An execution checklist is not a substitute for a durable plan when the task requires one.\n\n# Task execution\n\nYou are a coding agent. Please keep going until the query is completely resolved, before ending your turn and yielding back to the user. Only terminate your turn when you are sure that the problem is solved. Autonomously resolve the query to the best of your ability, using the tools available to you, before coming back to the user. Do NOT guess or make up an answer.\n\nYou MUST adhere to the following criteria when solving queries:\n\n- Working on the repo(s) in the current environment is allowed, even if they are proprietary.\n- Analyzing code for vulnerabilities is allowed.\n- Showing user code and tool call details is allowed.\n- Use the editing tools available in the current host to modify files. Do not assume a particular tool name.\n\nIf completing the user's task requires writing or modifying files, your code and final answer should follow these coding guidelines, though user instructions (i.e. AGENTS.md) may override these guidelines:\n\n- Fix the problem at the root cause rather than applying surface-level patches, when possible.\n- Avoid unneeded complexity in your solution.\n- Do not attempt to fix unrelated bugs or broken tests. It is not your responsibility to fix them. (You may mention them to the user in your final message though.)\n- Update documentation as necessary.\n- Keep changes consistent with the style of the existing codebase. Changes should be minimal and focused on the task.\n- Use `git log` and `git blame` to search the history of the codebase if additional context is required.\n- NEVER add copyright or license headers unless specifically requested.\n- Do not waste tokens by re-reading files after editing them. The tool call will fail if it didn't work. The same goes for making folders, deleting folders, etc.\n- Do not `git commit` your changes or create new git branches unless explicitly requested.\n- Add comments when they explain a non-obvious invariant or reason for a decision.\n- Do not use one-letter variable names unless explicitly requested.\n- NEVER output inline citations like \"\u3010F:README.md\u2020L5-L14\u3011\" in your outputs. The CLI is not able to render these so they will just be broken in the UI. Instead, if you output valid filepaths, users will be able to click on them to open the files in their editor.\n\n# Validating your work\n\nIf the codebase has tests or the ability to build or run, consider using them to verify that your work is complete.\n\nWhen testing, your philosophy should be to start as specific as possible to the code you changed so that you can catch issues efficiently, then make your way to broader tests as you build confidence. If there's no test for the code you changed, and if the adjacent patterns in the codebases show that there's a logical place for you to add a test, you may do so. However, do not add tests to codebases with no tests.\n\nSimilarly, once you're confident in correctness, you can suggest or use formatting commands to ensure that your code is well formatted. If there are issues you can iterate up to 3 times to get formatting right, but if you still can't manage it's better to save the user time and present them a correct solution where you call out the formatting in your final message. If the codebase does not have a formatter configured, do not add one.\n\nFor all of testing, running, building, and formatting, do not attempt to fix unrelated bugs. It is not your responsibility to fix them. (You may mention them to the user in your final message though.)\n\nBe mindful of whether to run validation commands proactively. In the absence of behavioral guidance:\n\n- When running in a non-interactive mode where edits are auto-approved (print/headless, or the `allow edits` permission mode), proactively run tests, lint and do whatever you need to ensure you've completed the task.\n- In plan mode, stay read-only. Otherwise, run focused checks after changes when the host permits them.\n- When working on test-related tasks, such as adding tests, fixing tests, or reproducing a bug to verify behavior, you may proactively run tests regardless of permission mode. Use your judgement to decide whether this is a test-related task.\n\n# Ambition vs. precision\n\nFor tasks that have no prior context (i.e. the user is starting something brand new), you should feel free to be ambitious and demonstrate creativity with your implementation.\n\nIf you're operating in an existing codebase, you should make sure you do exactly what the user asks with surgical precision. Treat the surrounding codebase with respect, and don't overstep (i.e. changing filenames or variables unnecessarily). You should balance being sufficiently ambitious and proactive when completing tasks of this nature.\n\nYou should use judicious initiative to decide on the right level of detail and complexity to deliver based on the user's needs. This means showing good judgment that you're capable of doing the right extras without gold-plating. This might be demonstrated by high-value, creative touches when scope of the task is vague; while being surgical and targeted when scope is tightly specified.\n\n# Sharing progress updates\n\nFor especially longer tasks that you work on (i.e. requiring many tool calls, or a plan with multiple steps), you should provide progress updates back to the user at reasonable intervals. These updates should be structured as a concise sentence or two (no more than 8-10 words long) recapping progress so far in plain language: this update demonstrates your understanding of what needs to be done, progress so far (i.e. files explores, subtasks complete), and where you're going next.\n\nBefore doing large chunks of work that may incur latency as experienced by the user (i.e. writing a new file), you should send a concise message to the user with an update indicating what you're about to do to ensure they know what you're spending time on. Don't start editing or writing large files before informing the user what you are doing and why.\n\nThe messages you send before tool calls should describe what is immediately about to be done next in very concise language. If there was previous work done, this preamble message should also include a note about the work done so far to bring the user along.\n\n# Presenting your work and final message\n\nYour final message should read naturally, like an update from a concise teammate. For casual conversation, brainstorming tasks, or quick questions from the user, respond in a friendly, conversational tone. You should ask questions, suggest ideas, and adapt to the user's style. If you've finished a large amount of work, when describing what you've done to the user, you should follow the final answer formatting guidelines to communicate substantive changes. You don't need to add structured formatting for one-word answers, greetings, or purely conversational exchanges.\n\nYou can skip heavy formatting for single, simple actions or confirmations. In these cases, respond in plain sentences with any relevant next step or quick option. Reserve multi-section structured responses for results that need grouping or explanation.\n\nThe user is working on the same computer as you, and has access to your work. As such there's no need to show the full contents of large files you have already written unless the user explicitly asks for them. Similarly, if you've created or modified files, there's no need to tell users to \"save the file\" or \"copy the code into a file\"\u2014just reference the file path.\n\nComplete authorized next steps, including relevant tests. Ask before a consequential action that needs approval, and briefly report anything you could not verify.\n\nBrevity is very important as a default. You should be very concise (i.e. no more than 10 lines), but can relax this requirement for tasks where additional detail and comprehensiveness is important for the user's understanding.\n\n## Final answer structure and style guidelines\n\nYou are producing plain text that will later be styled by the CLI. Follow these rules exactly. Formatting should make results easy to scan, but not feel mechanical. Use judgment to decide how much structure adds value.\n\n**Section Headers**\n\n- Use only when they improve clarity \u2014 they are not mandatory for every answer.\n- Choose descriptive names that fit the content\n- Keep headers short (1\u20133 words) and in `**Title Case**`. Always start headers with `**` and end with `**`\n- Use the blank lines required by the renderer for headings and lists.\n- Section headers should only be used where they genuinely improve scanability; avoid fragmenting the answer.\n\n**Bullets**\n\n- Use `-` followed by a space for every bullet.\n- Merge related points when possible; avoid a bullet for every trivial detail.\n- Keep bullets to one line unless breaking for clarity is unavoidable.\n- Group into short lists (4\u20136 bullets) ordered by importance.\n- Use consistent keyword phrasing and formatting across sections.\n\n**Monospace**\n\n- Wrap all commands, file paths, env vars, and code identifiers in backticks (`` `...` ``).\n- Apply to inline examples and to bullet keywords if the keyword itself is a literal file/command.\n- Never mix monospace and bold markers; choose one based on whether it's a keyword (`**`) or inline code/path (`` ` ``).\n\n**File References**\n\nWhen referencing files in your response, make sure to include the relevant start line and always follow the below rules:\n\n- Use inline code to make file paths clickable.\n- Each reference should have a stand alone path. Even if it's the same file.\n- Accepted: absolute, workspace\u2011relative, a/ or b/ diff prefixes, or bare filename/suffix.\n- Line/column (1\u2011based, optional): :line[:column] or #Lline[Ccolumn] (column defaults to 1).\n- Do not use URIs like file://, vscode://, or https://.\n- Do not provide range of lines\n- Examples: src/app.ts, src/app.ts:42, b/server/index.js#L10, C:\\repo\\project\\main.rs:12:5\n\n**Structure**\n\n- Place related bullets together; don't mix unrelated concepts in the same section.\n- Order sections from general \u2192 specific \u2192 supporting info.\n- For subsections (e.g., \"Binaries\" under \"Rust Workspace\"), introduce with a bolded keyword bullet, then list items under it.\n- Match structure to complexity:\n - Multi-part or detailed results \u2192 use clear headers and grouped bullets.\n - Simple results \u2192 minimal headers, possibly just a short list or paragraph.\n\n**Tone**\n\n- Keep the voice collaborative and natural, like a coding partner handing off work.\n- Be concise and factual \u2014 no filler or conversational commentary and avoid unnecessary repetition\n- Use present tense and active voice (e.g., \"Runs tests\" not \"This will run tests\").\n- Keep descriptions self-contained; don't refer to \"above\" or \"below\".\n- Use parallel structure in lists for consistency.\n\n**Don't**\n\n- Don't use literal words \"bold\" or \"monospace\" in the content.\n- Don't nest bullets or create deep hierarchies.\n- Don't output ANSI escape codes directly \u2014 the CLI renderer applies them.\n- Don't cram unrelated keywords into a single bullet; split for clarity.\n- Don't let keyword lists run long \u2014 wrap or reformat for scanability.\n\nGenerally, ensure your final answers adapt their shape and depth to the request. For example, answers to code explanations should have a precise, structured explanation with code references that answer the question directly. For tasks with a simple implementation, lead with the outcome and supplement only with what's needed for clarity. Larger changes can be presented as a logical walkthrough of your approach, grouping related steps, explaining rationale where it adds value, and highlighting next actions to accelerate the user. Your answers should provide the right level of detail while being easily scannable.\n\nFor casual greetings, acknowledgements, or other one-off conversational messages that are not delivering substantive information or structured results, respond naturally without section headers or bullet formatting.\n\n# Professional objectivity\n\nPrioritize technical accuracy and truthfulness over validating the user's beliefs. Focus on facts and problem-solving. Be direct and objective without unnecessary praise or emotional validation. Disagree when needed. When uncertain, investigate before confirming the user's assumptions.\n\n# Proactiveness\n\nProactively complete work that follows from the user's request. Avoid unrelated actions that would surprise the user. Strike a balance between:\n\n1. Doing the right thing when asked, including follow-up actions\n2. Not surprising the user with unrequested actions\n For example, if the user asks how to approach something, answer first; do not immediately jump into edits.\n\n# Following conventions\n\nWhen changing files, first understand the file's conventions. Mimic code style, use existing libraries and utilities, and follow existing patterns.\n\n- NEVER assume a library is available, even if it is well known. Whenever you write code that uses a library or framework, first check that this codebase already uses it (neighboring files, package.json, cargo.toml, go.mod, etc.).\n- When creating a new component, first look at existing components for framework choice, naming, typing, and other conventions.\n- When editing code, first look at surrounding context (especially imports) to understand chosen frameworks/libraries, then make the change idiomatically.\n- Always follow security best practices. Never introduce code that exposes or logs secrets and keys. Never commit secrets or keys to the repository.\n\n# Doing tasks\n\nThe user will primarily request software engineering tasks: bugs, features, refactors, explanations, and more. Recommended steps:\n\n- Use available search/read tools extensively to understand the codebase and the query (in parallel when independent).\n- Implement the solution with the tools available to you.\n- Prefer editing existing files. Create documentation when the task or project instructions require it.\n- Verify when possible with tests. NEVER assume a specific test framework or script \u2014 check README / AGENTS.md or search the repo.\n- Run lint and typecheck commands (for example npm run lint, npm run typecheck, ruff, pnpm lint) if they were provided to you \u2014 see Validating your work for when to run them proactively vs. when to hold off. If you cannot find the correct command, ask the user, and if they supply it, proactively suggest writing it to AGENTS.md so you know next time.\n\n- Tool results and user messages may include <system-reminder> tags. Those tags contain useful reminders. They are NOT part of the user's provided input or the tool result.\n\n# Tool usage policy\n\n- Prefer specialized file tools over shell for reading, editing, writing, listing, and searching when those tools are available. Use the `grep`, `glob`, and `list` tools instead of bash for search and listing \u2014 they are ripgrep-backed and return structured, length-capped results. Use shell for real system commands (git, package managers, builds, tests, process control).\n- When doing broad codebase exploration, use the available search tools and delegate only when the task benefits from independent work.\n- You can call multiple tools in one response. When multiple independent pieces of information are needed, batch tool calls for performance. When making multiple bash tool calls, send a single message with multiple tool calls so they can run in parallel (for example git status and git diff together).\n- Match edit old-text exactly, including whitespace.\n- If a tool call is denied by policy, adapt: use an allowed approach or ask the user. Do not retry the same blocked call in a loop.\n\n## Shell commands\n\nWhen using the shell, you must adhere to the following guidelines:\n\n- When searching for text or files, prefer using `rg` or `rg --files` respectively because `rg` is much faster than alternatives like `grep` and `find`. (If the `rg` command is not found, then use alternatives.) Reach for the shell only when the `grep`/`glob` tools cannot express the query \u2014 for example counting matches, or piping results into another command.\n- Search narrow first: use `rg -l` or `rg -c` to find which files match, then read only those files. Do not dump full match bodies across a repo into context.\n- Never pipe a large file into your context. Do not `cat` a big file; use the `read` tool with an offset/limit, or `sed -n 'START,ENDp'` for a specific range.\n- Do not use python scripts to attempt to output larger chunks of a file.\n\nIMPORTANT: Before you begin work, think about what the code you're editing is supposed to do based on the filenames and directory structure.\n\n# AGENTS.md spec\n\n- Repos often contain AGENTS.md files. These files can appear anywhere within the repository.\n- These files are a way for humans to give you (the agent) instructions or tips for working within the container.\n- Some examples might be: coding conventions, info about how code is organized, or instructions for how to run or test code.\n- Instructions in AGENTS.md files:\n - The scope of an AGENTS.md file is the entire directory tree rooted at the folder that contains it.\n - For every file you touch in the final change, you must obey instructions in any AGENTS.md file whose scope includes that file.\n - Instructions about code style, structure, naming, etc. apply only to code within the AGENTS.md file's scope, unless the file states otherwise.\n - More-deeply-nested AGENTS.md files take precedence in the case of conflicting instructions.\n - Direct system/developer/user instructions (as part of a prompt) take precedence over AGENTS.md instructions.\n- The contents of the AGENTS.md file at the root of the repo and the project directory are loaded into your context automatically and don't need to be re-read. AGENTS.md files in subdirectories are NOT loaded automatically: when working in a subdirectory, or a directory outside the CWD, check for any AGENTS.md files that may be applicable.\n\n# Permissions and safety\n\n- Never commit secrets or keys.\n- Never create a git commit unless the user explicitly asks.\n- Do not run destructive commands (mass delete, force-push, hard reset) unless the user clearly requested them.\n";
@@ -37822,9 +38048,9 @@ var require_dist = __commonJS({
37822
38048
  var init_dist = __esm({
37823
38049
  "../agent-core/dist/index.js"() {
37824
38050
  "use strict";
37825
- init_chunk_72NSEYHK();
38051
+ init_chunk_4G77APXN();
37826
38052
  init_chunk_XC5676SG();
37827
- init_chunk_54ZRJOQP();
38053
+ init_chunk_HBIPWAUI();
37828
38054
  init_chunk_M6YHY2EZ();
37829
38055
  init_chunk_YXWJW7I5();
37830
38056
  }
@@ -37917,7 +38143,7 @@ function within(root, path) {
37917
38143
  }
37918
38144
  async function resolveReal(path) {
37919
38145
  try {
37920
- return await (0, import_promises23.realpath)(path);
38146
+ return await (0, import_promises24.realpath)(path);
37921
38147
  } catch {
37922
38148
  const parent = (0, import_path9.dirname)(path);
37923
38149
  if (parent === path) return path;
@@ -37946,14 +38172,14 @@ function createWorkspaceFs(roots, writable) {
37946
38172
  return {
37947
38173
  read: async (params) => {
37948
38174
  const path = await confined(params);
37949
- const bytes = await (0, import_promises23.readFile)(path);
38175
+ const bytes = await (0, import_promises24.readFile)(path);
37950
38176
  if (bytes.byteLength > MAX_READ_BYTES) throw new FsDenied(`${path} is too large to read`);
37951
38177
  return { content: sliceLines(bytes.toString("utf8"), params) };
37952
38178
  },
37953
38179
  write: async (params) => {
37954
38180
  if (!writable) throw new FsDenied("This session is read-only");
37955
38181
  const path = await confined(params);
37956
- await (0, import_promises23.writeFile)(path, asString(params.content));
38182
+ await (0, import_promises24.writeFile)(path, asString(params.content));
37957
38183
  return {};
37958
38184
  }
37959
38185
  };
@@ -38498,7 +38724,7 @@ function isAcpBackendKind(value) {
38498
38724
  return Object.hasOwn(ACP_PROFILES, value);
38499
38725
  }
38500
38726
  function envDigest3(env) {
38501
- const hash2 = (0, import_crypto12.createHash)("sha256");
38727
+ const hash2 = (0, import_crypto13.createHash)("sha256");
38502
38728
  for (const key of Object.keys(env).sort()) hash2.update(`${key}\0${env[key]}\0`);
38503
38729
  return hash2.digest("hex");
38504
38730
  }
@@ -38556,7 +38782,7 @@ async function acpTurnInput(run, context) {
38556
38782
  const encoded = await Promise.all(
38557
38783
  images.map(async (image) => ({
38558
38784
  mimeType: image.mimeType,
38559
- data: (await (0, import_promises24.readFile)(image.path)).toString("base64")
38785
+ data: (await (0, import_promises25.readFile)(image.path)).toString("base64")
38560
38786
  }))
38561
38787
  );
38562
38788
  return {
@@ -38565,23 +38791,23 @@ async function acpTurnInput(run, context) {
38565
38791
  ...encoded.length ? { images: encoded, imagePaths: images.map((image) => image.path) } : {}
38566
38792
  };
38567
38793
  }
38568
- var import_promises23, import_path9, import_crypto12, import_promises24, CURSOR_ASK_QUESTION, copilotAcpProfile, cursorAcpProfile, MODEL_REJECTED, MAX_READ_BYTES, FsDenied, ENV_REFERENCE, AcpBackgroundTasks, CURSOR_CREATE_PLAN, STATUSES, READ_KINDS, ALLOW_KINDS, REJECT_KINDS, CANCELLED_PERMISSION, STOP_REASONS, CHUNKS, ECHOES, AcpTurn, STDERR_TAIL_LINES4, MAX_BETWEEN_UPDATES2, AcpSession, DEFAULTS3, CLIENT_INFO2, TASK_BACKGROUNDED, TASK_COMPLETED, SESSION_NOTIFICATION, KILLED_STATUSES, SUCCESS_STATUSES, SUBAGENT_ID, grokTaskDialect, grokAcpProfile, kimiAcpProfile, ACP_PROFILES, ACP_MODES;
38794
+ var import_promises24, import_path9, import_crypto13, import_promises25, CURSOR_ASK_QUESTION, copilotAcpProfile, cursorAcpProfile, MODEL_REJECTED, MAX_READ_BYTES, FsDenied, ENV_REFERENCE, AcpBackgroundTasks, CURSOR_CREATE_PLAN, STATUSES, READ_KINDS, ALLOW_KINDS, REJECT_KINDS, CANCELLED_PERMISSION, STOP_REASONS, CHUNKS, ECHOES, AcpTurn, STDERR_TAIL_LINES4, MAX_BETWEEN_UPDATES2, AcpSession, DEFAULTS3, CLIENT_INFO2, TASK_BACKGROUNDED, TASK_COMPLETED, SESSION_NOTIFICATION, KILLED_STATUSES, SUCCESS_STATUSES, SUBAGENT_ID, grokTaskDialect, grokAcpProfile, kimiAcpProfile, ACP_PROFILES, ACP_MODES;
38569
38795
  var init_acp3 = __esm({
38570
38796
  "../agent-core/dist/providers/acp.js"() {
38571
38797
  "use strict";
38572
- init_chunk_72NSEYHK();
38798
+ init_chunk_4G77APXN();
38573
38799
  init_chunk_XC5676SG();
38574
- init_chunk_54ZRJOQP();
38800
+ init_chunk_HBIPWAUI();
38575
38801
  init_chunk_J2KTV5FP();
38576
38802
  init_chunk_M6YHY2EZ();
38577
38803
  init_chunk_FPGAN4XO();
38578
38804
  init_chunk_YXWJW7I5();
38579
- import_promises23 = require("fs/promises");
38805
+ import_promises24 = require("fs/promises");
38580
38806
  import_path9 = require("path");
38581
38807
  init_effort();
38582
38808
  init_acp();
38583
- import_crypto12 = require("crypto");
38584
- import_promises24 = require("fs/promises");
38809
+ import_crypto13 = require("crypto");
38810
+ import_promises25 = require("fs/promises");
38585
38811
  init_agent2();
38586
38812
  CURSOR_ASK_QUESTION = "cursor/ask_question";
38587
38813
  copilotAcpProfile = {
@@ -39097,7 +39323,7 @@ var init_acp3 = __esm({
39097
39323
  const turn = new AcpTurn(`acp-${this.#turns}-${id}`, this.#profile);
39098
39324
  let finish = () => {
39099
39325
  };
39100
- const done = new Promise((resolve7) => {
39326
+ const done = new Promise((resolve9) => {
39101
39327
  finish = (outcome2) => {
39102
39328
  if (this.#current?.id !== id) return;
39103
39329
  this.#current = void 0;
@@ -39105,7 +39331,7 @@ var init_acp3 = __esm({
39105
39331
  if (this.#state === "busy") this.#state = "idle";
39106
39332
  this.#host.scanDescendants(true);
39107
39333
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
39108
- resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
39334
+ resolve9({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
39109
39335
  };
39110
39336
  });
39111
39337
  const active = { id, turn, done, finish, cancelRequested: false };
@@ -39386,7 +39612,7 @@ var init_acp3 = __esm({
39386
39612
  var init_classify = __esm({
39387
39613
  "../agent-core/dist/classify.js"() {
39388
39614
  "use strict";
39389
- init_chunk_54ZRJOQP();
39615
+ init_chunk_HBIPWAUI();
39390
39616
  init_chunk_YXWJW7I5();
39391
39617
  }
39392
39618
  });
@@ -39596,7 +39822,10 @@ function createPersistentDriver(provider4, options) {
39596
39822
  return "delivered";
39597
39823
  };
39598
39824
  const openFailed = (error61, spec, sink, signal, inputs) => {
39599
- if (error61 instanceof SessionOpenRefusal && error61.reason === "unsupported_version" && options.fallback) {
39825
+ if (error61 instanceof SessionOpenRefusal && error61.reason === "unsupported_version" && inputs.codex !== void 0) {
39826
+ return { outcome: "failed", message: error61.message };
39827
+ }
39828
+ if (error61 instanceof SessionOpenRefusal && error61.reason === "unsupported_version" && options.fallback && inputs.codex === void 0) {
39600
39829
  log.warn("holder.persistent_unsupported", {
39601
39830
  harness: provider4.harness,
39602
39831
  message: error61.message
@@ -39613,7 +39842,7 @@ function createPersistentDriver(provider4, options) {
39613
39842
  };
39614
39843
  return {
39615
39844
  runTurn: async (spec, sink, signal, inputs) => {
39616
- if (live.fallbackOnly && options.fallback)
39845
+ if (live.fallbackOnly && options.fallback && inputs.codex === void 0)
39617
39846
  return options.fallback.runTurn(spec, sink, signal, inputs);
39618
39847
  if (signal.aborted) return { outcome: "aborted" };
39619
39848
  const managedMcp = await managedMcpAccess(signal);
@@ -40103,7 +40332,7 @@ async function sameDirectory(left, right) {
40103
40332
  }
40104
40333
  async function canonicalDirectory(directory) {
40105
40334
  try {
40106
- return await (0, import_promises25.realpath)(directory);
40335
+ return await (0, import_promises26.realpath)(directory);
40107
40336
  } catch {
40108
40337
  return (0, import_path10.resolve)(directory);
40109
40338
  }
@@ -40203,7 +40432,7 @@ function createOpenCodeDriver(options = {}) {
40203
40432
  await authorization?.remove();
40204
40433
  };
40205
40434
  const spec = { ...planned, env: launchEnv(planned, authorization) };
40206
- const password = options.password?.() ?? (0, import_crypto13.randomBytes)(24).toString("base64url");
40435
+ const password = options.password?.() ?? (0, import_crypto14.randomBytes)(24).toString("base64url");
40207
40436
  try {
40208
40437
  const session = await openWithRetries(spec, password, resolved);
40209
40438
  void session.exited.then(removeAuthorization).catch((error61) => {
@@ -40218,7 +40447,7 @@ function createOpenCodeDriver(options = {}) {
40218
40447
  };
40219
40448
  }
40220
40449
  function envDigest4(env) {
40221
- const hash2 = (0, import_crypto14.createHash)("sha256");
40450
+ const hash2 = (0, import_crypto15.createHash)("sha256");
40222
40451
  for (const key of Object.keys(env).sort()) hash2.update(`${key}\0${env[key]}\0`);
40223
40452
  return hash2.digest("hex");
40224
40453
  }
@@ -40299,28 +40528,28 @@ function openCodeTurnInput(run, context) {
40299
40528
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
40300
40529
  };
40301
40530
  }
40302
- var import_http4, import_crypto13, import_promises25, import_path10, import_path11, import_url2, import_crypto14, IDLE_SOCKET_MS2, OpenCodeHttpError, 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_OPERATIONS, PartReader, NOTHING, NON_INTERACTIVE_PERMISSIONS, CONTENT_FILTER_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;
40531
+ var import_http4, import_crypto14, import_promises26, import_path10, import_path11, import_url2, import_crypto15, IDLE_SOCKET_MS2, OpenCodeHttpError, 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_OPERATIONS, PartReader, NOTHING, NON_INTERACTIVE_PERMISSIONS, CONTENT_FILTER_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;
40303
40532
  var init_opencode = __esm({
40304
40533
  "../agent-core/dist/providers/opencode.js"() {
40305
40534
  "use strict";
40306
- init_chunk_72NSEYHK();
40535
+ init_chunk_4G77APXN();
40307
40536
  init_chunk_XC5676SG();
40308
- init_chunk_54ZRJOQP();
40537
+ init_chunk_HBIPWAUI();
40309
40538
  init_chunk_J2KTV5FP();
40310
40539
  init_chunk_M6YHY2EZ();
40311
40540
  init_chunk_FPGAN4XO();
40312
40541
  init_chunk_YXWJW7I5();
40313
40542
  import_http4 = require("http");
40314
40543
  init_runtime_v2();
40315
- import_crypto13 = require("crypto");
40316
- import_promises25 = require("fs/promises");
40544
+ import_crypto14 = require("crypto");
40545
+ import_promises26 = require("fs/promises");
40317
40546
  import_path10 = require("path");
40318
40547
  init_agent2();
40319
40548
  import_path11 = require("path");
40320
40549
  import_url2 = require("url");
40321
40550
  init_acp();
40322
40551
  init_acp();
40323
- import_crypto14 = require("crypto");
40552
+ import_crypto15 = require("crypto");
40324
40553
  init_agent2();
40325
40554
  IDLE_SOCKET_MS2 = 4e3;
40326
40555
  OpenCodeHttpError = class extends Error {
@@ -41616,11 +41845,11 @@ function createCodexLogin(broker) {
41616
41845
  }
41617
41846
  };
41618
41847
  }
41619
- function withLogin(planned, externalAuth, accountId) {
41848
+ function withLogin(planned, externalAuth, credentialKey) {
41620
41849
  return {
41621
41850
  ...planned,
41622
41851
  spec: { ...planned.spec, externalAuth },
41623
- key: JSON.stringify([planned.key, accountId])
41852
+ key: JSON.stringify([planned.key, credentialKey])
41624
41853
  };
41625
41854
  }
41626
41855
  function createCodexHolderDriver(options) {
@@ -41642,7 +41871,11 @@ function createCodexHolderDriver(options) {
41642
41871
  });
41643
41872
  if (inputs.codex === void 0) return planned;
41644
41873
  login.forTurn(spec.runId, inputs.codex);
41645
- return withLogin(planned, login.externalAuth, inputs.codex.chatgptAccountId);
41874
+ return withLogin(
41875
+ planned,
41876
+ login.externalAuth,
41877
+ inputs.codex.credentialId ?? inputs.codex.chatgptAccountId
41878
+ );
41646
41879
  },
41647
41880
  canResume: () => true,
41648
41881
  open: async (spec) => {
@@ -41774,8 +42007,8 @@ function createDroidPeer(writer, handlers) {
41774
42007
  },
41775
42008
  request: (method, params = {}) => {
41776
42009
  const id = `alan-${counter.next++}`;
41777
- return new Promise((resolve7, reject) => {
41778
- pending.set(id, { method, resolve: resolve7, reject });
42010
+ return new Promise((resolve9, reject) => {
42011
+ pending.set(id, { method, resolve: resolve9, reject });
41779
42012
  writer.write(envelope("request", { id, method, params })).catch((error61) => {
41780
42013
  pending.delete(id);
41781
42014
  reject(error61 instanceof Error ? error61 : new Error(String(error61)));
@@ -42055,7 +42288,7 @@ function createDroidDriver(options = {}) {
42055
42288
  };
42056
42289
  }
42057
42290
  function envDigest5(env) {
42058
- const hash2 = (0, import_crypto15.createHash)("sha256");
42291
+ const hash2 = (0, import_crypto16.createHash)("sha256");
42059
42292
  for (const key of Object.keys(env).sort()) hash2.update(`${key}\0${env[key]}\0`);
42060
42293
  return hash2.digest("hex");
42061
42294
  }
@@ -42110,25 +42343,25 @@ async function droidTurnInput(run, context) {
42110
42343
  const encoded = await Promise.all(
42111
42344
  images.map(async (image) => ({
42112
42345
  mimeType: image.mimeType,
42113
- data: (await (0, import_promises26.readFile)(image.path)).toString("base64")
42346
+ data: (await (0, import_promises27.readFile)(image.path)).toString("base64")
42114
42347
  }))
42115
42348
  );
42116
42349
  return { turnId: run.runId, text: text2, ...encoded.length ? { images: encoded } : {} };
42117
42350
  }
42118
- var import_crypto15, import_promises26, FACTORY_API_VERSION, FACTORY_PROTOCOL_VERSION, SUBAGENT_TOOLS, TASK_OUTPUT_TOOLS, TASK_STOP_TOOLS, SILENT2, DroidTurn, STDERR_TAIL_LINES5, UNSUPPORTED_REQUEST2, DroidSession, DEFAULTS5, DROID_REQUIREMENT, DROID_JSONRPC_ARGS;
42351
+ var import_crypto16, import_promises27, FACTORY_API_VERSION, FACTORY_PROTOCOL_VERSION, SUBAGENT_TOOLS, TASK_OUTPUT_TOOLS, TASK_STOP_TOOLS, SILENT2, DroidTurn, STDERR_TAIL_LINES5, UNSUPPORTED_REQUEST2, DroidSession, DEFAULTS5, DROID_REQUIREMENT, DROID_JSONRPC_ARGS;
42119
42352
  var init_droid = __esm({
42120
42353
  "../agent-core/dist/providers/droid.js"() {
42121
42354
  "use strict";
42122
- init_chunk_72NSEYHK();
42355
+ init_chunk_4G77APXN();
42123
42356
  init_chunk_XC5676SG();
42124
- init_chunk_54ZRJOQP();
42357
+ init_chunk_HBIPWAUI();
42125
42358
  init_chunk_J2KTV5FP();
42126
42359
  init_chunk_M6YHY2EZ();
42127
42360
  init_chunk_FPGAN4XO();
42128
42361
  init_chunk_YXWJW7I5();
42129
42362
  init_runtime_v2();
42130
- import_crypto15 = require("crypto");
42131
- import_promises26 = require("fs/promises");
42363
+ import_crypto16 = require("crypto");
42364
+ import_promises27 = require("fs/promises");
42132
42365
  init_agent2();
42133
42366
  FACTORY_API_VERSION = "1.0.0";
42134
42367
  FACTORY_PROTOCOL_VERSION = "1.187.0";
@@ -42400,14 +42633,14 @@ var init_droid = __esm({
42400
42633
  const turn = new DroidTurn(sessionId, this.#memory);
42401
42634
  let finish = () => {
42402
42635
  };
42403
- const done = new Promise((resolve7) => {
42636
+ const done = new Promise((resolve9) => {
42404
42637
  finish = (outcome2) => {
42405
42638
  if (this.#current?.id !== id) return;
42406
42639
  this.#current = void 0;
42407
42640
  if (this.#state === "busy") this.#state = "idle";
42408
42641
  this.#host.scanDescendants(true);
42409
42642
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
42410
- resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
42643
+ resolve9({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
42411
42644
  };
42412
42645
  });
42413
42646
  const active = { id, turn, done, finish, cancelRequested: false };
@@ -42603,7 +42836,7 @@ function settingsPath(env) {
42603
42836
  async function readSettings(path) {
42604
42837
  let raw;
42605
42838
  try {
42606
- raw = (await (0, import_promises27.readFile)(path, "utf8")).trim();
42839
+ raw = (await (0, import_promises28.readFile)(path, "utf8")).trim();
42607
42840
  } catch {
42608
42841
  return {};
42609
42842
  }
@@ -42621,8 +42854,8 @@ async function selectAntigravityApiKeyMode(env) {
42621
42854
  const settings2 = await readSettings(path);
42622
42855
  if (settings2 === "malformed") return "malformed";
42623
42856
  if (settings2.modelProvider === "gemini") return "already_selected";
42624
- await (0, import_promises27.mkdir)((0, import_path12.dirname)(path), { recursive: true });
42625
- await (0, import_promises27.writeFile)(path, JSON.stringify({ ...settings2, modelProvider: "gemini" }), { mode: 384 });
42857
+ await (0, import_promises28.mkdir)((0, import_path12.dirname)(path), { recursive: true });
42858
+ await (0, import_promises28.writeFile)(path, JSON.stringify({ ...settings2, modelProvider: "gemini" }), { mode: 384 });
42626
42859
  return "selected";
42627
42860
  }
42628
42861
  function readAntigravityCapabilities(version2, help) {
@@ -43175,7 +43408,7 @@ ${output2.stderr}`).join("\n")
43175
43408
  };
43176
43409
  }
43177
43410
  function envDigest6(env) {
43178
- const hash2 = (0, import_crypto16.createHash)("sha256");
43411
+ const hash2 = (0, import_crypto17.createHash)("sha256");
43179
43412
  for (const key of Object.keys(env).sort()) hash2.update(`${key}\0${env[key]}\0`);
43180
43413
  return hash2.digest("hex");
43181
43414
  }
@@ -43221,18 +43454,18 @@ function antigravityTurnInput(run, context) {
43221
43454
  });
43222
43455
  return { turnId: run.runId, text: appendImagePathReferences(text2, images) };
43223
43456
  }
43224
- var import_promises27, import_path12, import_fs8, import_path13, import_path14, import_url3, import_crypto16, NO_ANTIGRAVITY_CAPABILITIES, INSTRUCTIONS_FILE, MAX_INSTRUCTION_CHARS, SHORTENED_NOTE, DIFF_BLOCK_START, DIFF_BLOCK_END, HUNK_HEADER, TRANSCRIPT_FILE, FULL_TRANSCRIPT_FILE, LOG_DIRS, TOOL_RESULT_TYPES, BrainTranscript, AntigravityTranscripts, ANTIGRAVITY_GRAMMAR_NAME, AntigravityGrammar, ignored, HANDLERS, SUCCESSFUL_STATUSES, SESSION_START_TYPES, RESULT_TYPES, SUBAGENT_START_TYPES, RESUME_FORKED, EXITED_WITHOUT_RESULT, AntigravityTurn, DEFAULTS6, AntigravitySession, WINDOWS_LINE_MARGIN;
43457
+ var import_promises28, import_path12, import_fs8, import_path13, import_path14, import_url3, import_crypto17, NO_ANTIGRAVITY_CAPABILITIES, INSTRUCTIONS_FILE, MAX_INSTRUCTION_CHARS, SHORTENED_NOTE, DIFF_BLOCK_START, DIFF_BLOCK_END, HUNK_HEADER, TRANSCRIPT_FILE, FULL_TRANSCRIPT_FILE, LOG_DIRS, TOOL_RESULT_TYPES, BrainTranscript, AntigravityTranscripts, ANTIGRAVITY_GRAMMAR_NAME, AntigravityGrammar, ignored, HANDLERS, SUCCESSFUL_STATUSES, SESSION_START_TYPES, RESULT_TYPES, SUBAGENT_START_TYPES, RESUME_FORKED, EXITED_WITHOUT_RESULT, AntigravityTurn, DEFAULTS6, AntigravitySession, WINDOWS_LINE_MARGIN;
43225
43458
  var init_antigravity = __esm({
43226
43459
  "../agent-core/dist/providers/antigravity.js"() {
43227
43460
  "use strict";
43228
43461
  init_chunk_SBT5W7L4();
43229
- init_chunk_72NSEYHK();
43462
+ init_chunk_4G77APXN();
43230
43463
  init_chunk_XC5676SG();
43231
- init_chunk_54ZRJOQP();
43464
+ init_chunk_HBIPWAUI();
43232
43465
  init_chunk_M6YHY2EZ();
43233
43466
  init_chunk_FPGAN4XO();
43234
43467
  init_chunk_YXWJW7I5();
43235
- import_promises27 = require("fs/promises");
43468
+ import_promises28 = require("fs/promises");
43236
43469
  import_path12 = require("path");
43237
43470
  init_type_guards();
43238
43471
  import_fs8 = require("fs");
@@ -43240,7 +43473,7 @@ var init_antigravity = __esm({
43240
43473
  init_effort();
43241
43474
  import_path14 = require("path");
43242
43475
  import_url3 = require("url");
43243
- import_crypto16 = require("crypto");
43476
+ import_crypto17 = require("crypto");
43244
43477
  init_agent2();
43245
43478
  NO_ANTIGRAVITY_CAPABILITIES = {
43246
43479
  structuredPrint: false,
@@ -43732,7 +43965,7 @@ function parseConfig(raw) {
43732
43965
  }
43733
43966
  async function writeCommandCodeProjectMcp(cwd, mcp) {
43734
43967
  const path = (0, import_path15.join)(cwd, ".mcp.json");
43735
- const original = await (0, import_promises28.readFile)(path, "utf8").catch(() => null);
43968
+ const original = await (0, import_promises29.readFile)(path, "utf8").catch(() => null);
43736
43969
  const config2 = parseConfig(original);
43737
43970
  const next = {
43738
43971
  ...config2,
@@ -43749,12 +43982,12 @@ async function writeCommandCodeProjectMcp(cwd, mcp) {
43749
43982
  }
43750
43983
  }
43751
43984
  };
43752
- await (0, import_promises28.mkdir)(cwd, { recursive: true });
43753
- await (0, import_promises28.writeFile)(path, `${JSON.stringify(next, null, 2)}
43985
+ await (0, import_promises29.mkdir)(cwd, { recursive: true });
43986
+ await (0, import_promises29.writeFile)(path, `${JSON.stringify(next, null, 2)}
43754
43987
  `);
43755
43988
  return async () => {
43756
- if (original === null) await (0, import_promises28.rm)(path, { force: true });
43757
- else await (0, import_promises28.writeFile)(path, original);
43989
+ if (original === null) await (0, import_promises29.rm)(path, { force: true });
43990
+ else await (0, import_promises29.writeFile)(path, original);
43758
43991
  };
43759
43992
  }
43760
43993
  function commandCodeString(value) {
@@ -43874,7 +44107,7 @@ function createCommandCodeDriver(options = {}) {
43874
44107
  };
43875
44108
  }
43876
44109
  function envDigest7(env) {
43877
- const hash2 = (0, import_crypto17.createHash)("sha256");
44110
+ const hash2 = (0, import_crypto18.createHash)("sha256");
43878
44111
  for (const key of Object.keys(env).sort()) hash2.update(`${key}\0${env[key]}\0`);
43879
44112
  return hash2.digest("hex");
43880
44113
  }
@@ -43926,23 +44159,23 @@ function commandCodeTurnInput(run, context) {
43926
44159
  });
43927
44160
  return { turnId: run.runId, text: appendImagePathReferences(text2, images) };
43928
44161
  }
43929
- var import_promises28, import_path15, import_crypto17, COMMAND_CODE_GRAMMAR_NAME, SILENT3, CommandCodeGrammar, SHELL_TOOL, STOP_TOOLS, REPORTED_STATUS, SHELL_STATUS, SWEEP_INTERVAL_MS, CommandCodeBackgroundTasks, EXITED_WITHOUT_RESULT2, CommandCodeTurn, COMMAND_CODE_MAX_TURNS, DEFAULTS7, CommandCodeSession;
44162
+ var import_promises29, import_path15, import_crypto18, COMMAND_CODE_GRAMMAR_NAME, SILENT3, CommandCodeGrammar, SHELL_TOOL, STOP_TOOLS, REPORTED_STATUS, SHELL_STATUS, SWEEP_INTERVAL_MS, CommandCodeBackgroundTasks, EXITED_WITHOUT_RESULT2, CommandCodeTurn, COMMAND_CODE_MAX_TURNS, DEFAULTS7, CommandCodeSession;
43930
44163
  var init_command_code = __esm({
43931
44164
  "../agent-core/dist/providers/command-code.js"() {
43932
44165
  "use strict";
43933
- init_chunk_72NSEYHK();
44166
+ init_chunk_4G77APXN();
43934
44167
  init_chunk_XC5676SG();
43935
- init_chunk_54ZRJOQP();
44168
+ init_chunk_HBIPWAUI();
43936
44169
  init_chunk_J2KTV5FP();
43937
44170
  init_chunk_M6YHY2EZ();
43938
44171
  init_chunk_FPGAN4XO();
43939
44172
  init_chunk_YXWJW7I5();
43940
- import_promises28 = require("fs/promises");
44173
+ import_promises29 = require("fs/promises");
43941
44174
  import_path15 = require("path");
43942
44175
  init_agent2();
43943
44176
  init_runtime_v2();
43944
44177
  init_acp();
43945
- import_crypto17 = require("crypto");
44178
+ import_crypto18 = require("crypto");
43946
44179
  init_agent2();
43947
44180
  COMMAND_CODE_GRAMMAR_NAME = "command_code_cli";
43948
44181
  SILENT3 = /* @__PURE__ */ new Set([
@@ -44799,7 +45032,7 @@ function transportFailure(request2, error61) {
44799
45032
  });
44800
45033
  }
44801
45034
  function readBody(incoming, url2, maxBytes) {
44802
- return new Promise((resolve7, reject) => {
45035
+ return new Promise((resolve9, reject) => {
44803
45036
  const declared = Number(incoming.headers["content-length"] ?? "0");
44804
45037
  if (maxBytes !== void 0 && declared > maxBytes) {
44805
45038
  incoming.destroy();
@@ -44818,7 +45051,7 @@ function readBody(incoming, url2, maxBytes) {
44818
45051
  chunks.push(chunk);
44819
45052
  });
44820
45053
  incoming.on("error", reject);
44821
- incoming.on("end", () => resolve7(Buffer.concat(chunks)));
45054
+ incoming.on("end", () => resolve9(Buffer.concat(chunks)));
44822
45055
  });
44823
45056
  }
44824
45057
  function isConnectionReset(error61) {
@@ -44826,7 +45059,7 @@ function isConnectionReset(error61) {
44826
45059
  }
44827
45060
  function exchange(request2, agents, attempt = 0) {
44828
45061
  const { signal, url: url2 } = request2;
44829
- return new Promise((resolve7, reject) => {
45062
+ return new Promise((resolve9, reject) => {
44830
45063
  if (signal.aborted) {
44831
45064
  reject(signal.reason);
44832
45065
  return;
@@ -44853,7 +45086,7 @@ function exchange(request2, agents, attempt = 0) {
44853
45086
  const stale = outgoing.reusedSocket && !responded && isConnectionReset(error61);
44854
45087
  if (stale && attempt < STALE_SOCKET_RETRIES && !signal.aborted) {
44855
45088
  settle();
44856
- resolve7(exchange(request2, agents, attempt + 1));
45089
+ resolve9(exchange(request2, agents, attempt + 1));
44857
45090
  return;
44858
45091
  }
44859
45092
  fail(error61);
@@ -44866,7 +45099,7 @@ function exchange(request2, agents, attempt = 0) {
44866
45099
  readBody(incoming, url2, isRedirect(status) ? void 0 : request2.maxBodyBytes).then(
44867
45100
  (body) => {
44868
45101
  settle();
44869
- resolve7({ status, headers: incoming.headers, body });
45102
+ resolve9({ status, headers: incoming.headers, body });
44870
45103
  },
44871
45104
  fail
44872
45105
  );
@@ -44933,7 +45166,18 @@ function createHttpTransport() {
44933
45166
 
44934
45167
  // src/api-client/holder-client.ts
44935
45168
  init_runtime_v2();
45169
+ init_zod();
44936
45170
  var REQUEST_TIMEOUT_MS = 3e4;
45171
+ var credentialRefusalSchema = external_exports.object({ message: external_exports.string().trim().min(1) });
45172
+ function credentialFailureMessage(response, fallback) {
45173
+ if (response.status !== 409) return fallback;
45174
+ try {
45175
+ const parsed = credentialRefusalSchema.safeParse(jsonBody(response));
45176
+ return parsed.success ? parsed.data.message : fallback;
45177
+ } catch {
45178
+ return fallback;
45179
+ }
45180
+ }
44937
45181
  function createHolderApiClient({
44938
45182
  apiUrl,
44939
45183
  accessToken,
@@ -44966,7 +45210,10 @@ function createHolderApiClient({
44966
45210
  if (!isOk(response)) {
44967
45211
  throw new RuntimeFault(
44968
45212
  "io_failed",
44969
- `Provider credential request failed: ${response.status}`
45213
+ credentialFailureMessage(
45214
+ response,
45215
+ `Provider credential request failed: ${response.status}`
45216
+ )
44970
45217
  );
44971
45218
  }
44972
45219
  return runProviderCredentialSchema.parse(jsonBody(response));
@@ -44974,7 +45221,10 @@ function createHolderApiClient({
44974
45221
  refreshCodexCredential: async (runId, body, signal) => {
44975
45222
  const response = await request2("POST", runCodexCredentialRefreshPath(runId), signal, body);
44976
45223
  if (!isOk(response)) {
44977
- throw new RuntimeFault("io_failed", `Codex sign-in refresh failed: ${response.status}`);
45224
+ throw new RuntimeFault(
45225
+ "io_failed",
45226
+ credentialFailureMessage(response, `Codex sign-in refresh failed: ${response.status}`)
45227
+ );
44978
45228
  }
44979
45229
  return runCodexCredentialSchema.parse(jsonBody(response));
44980
45230
  },
@@ -45019,6 +45269,19 @@ var GitFault = class extends Error {
45019
45269
  }
45020
45270
  };
45021
45271
 
45272
+ // src/capabilities/git/repository.ts
45273
+ var import_promises4 = require("fs/promises");
45274
+ var import_node_path3 = require("path");
45275
+ async function assertValidBranch(git, repoRoot, branch, signal) {
45276
+ const output2 = await git.run(
45277
+ { cwd: repoRoot, args: ["check-ref-format", "--branch", branch], readOnly: true },
45278
+ signal
45279
+ );
45280
+ if (branch.startsWith("-") || output2.exitCode !== 0) {
45281
+ throw new GitFault("invalid_git_request", "branch is not a valid Git ref");
45282
+ }
45283
+ }
45284
+
45022
45285
  // src/capabilities/git/run-git.ts
45023
45286
  var import_node_child_process = require("child_process");
45024
45287
 
@@ -45155,7 +45418,7 @@ function createGitRunner(options) {
45155
45418
  }
45156
45419
  await killProcessTree(child.pid, { signal: "SIGKILL", child, platform });
45157
45420
  };
45158
- return new Promise((resolve7, reject) => {
45421
+ return new Promise((resolve9, reject) => {
45159
45422
  let ending = null;
45160
45423
  const stop = (next) => {
45161
45424
  if (ending !== null) return;
@@ -45180,7 +45443,7 @@ function createGitRunner(options) {
45180
45443
  signal.removeEventListener("abort", onAbort);
45181
45444
  const final = ending ?? last;
45182
45445
  if (final.kind === "exited") {
45183
- resolve7({ exitCode: final.exitCode, stdout: stdout.text(), stderr: stderr.text() });
45446
+ resolve9({ exitCode: final.exitCode, stdout: stdout.text(), stderr: stderr.text() });
45184
45447
  } else {
45185
45448
  reject(faultFor(final, command));
45186
45449
  }
@@ -45204,8 +45467,8 @@ function createGitRunner(options) {
45204
45467
 
45205
45468
  // src/capabilities/git/checkout-freshness.ts
45206
45469
  var import_node_crypto3 = require("crypto");
45207
- var import_promises7 = require("fs/promises");
45208
- var import_node_path3 = require("path");
45470
+ var import_promises8 = require("fs/promises");
45471
+ var import_node_path4 = require("path");
45209
45472
  init_zod();
45210
45473
  var REMOTE = "origin";
45211
45474
  var snapshotSchema = external_exports.object({
@@ -45235,7 +45498,7 @@ var freshnessSchema = external_exports.discriminatedUnion("state", [
45235
45498
  })
45236
45499
  ]);
45237
45500
  function freshnessFile(dir, path) {
45238
- return (0, import_node_path3.join)(dir, `${(0, import_node_crypto3.createHash)("sha256").update(path).digest("hex").slice(0, 32)}.json`);
45501
+ return (0, import_node_path4.join)(dir, `${(0, import_node_crypto3.createHash)("sha256").update(path).digest("hex").slice(0, 32)}.json`);
45239
45502
  }
45240
45503
  function parseStatus(stdout) {
45241
45504
  const lines = stdout.split("\n").filter((line) => line.length > 0);
@@ -45267,32 +45530,35 @@ async function readCheckoutStatus(git, cwd, signal) {
45267
45530
  return output2.exitCode === 0 ? parseStatus(output2.stdout) : null;
45268
45531
  }
45269
45532
  async function isCheckout(path) {
45270
- return (0, import_promises7.stat)((0, import_node_path3.join)(path, ".git")).then(
45533
+ return (0, import_promises8.stat)((0, import_node_path4.join)(path, ".git")).then(
45271
45534
  () => true,
45272
45535
  () => false
45273
45536
  );
45274
45537
  }
45275
45538
  async function checkoutsUnder(root) {
45276
45539
  if (await isCheckout(root)) return [root];
45277
- const entries = await (0, import_promises7.readdir)(root, { withFileTypes: true }).catch(() => []);
45540
+ const entries = await (0, import_promises8.readdir)(root, { withFileTypes: true }).catch(() => []);
45278
45541
  const found = await Promise.all(
45279
45542
  entries.filter((entry) => entry.isDirectory()).map(
45280
- async (entry) => await isCheckout((0, import_node_path3.join)(root, entry.name)) ? (0, import_node_path3.join)(root, entry.name) : null
45543
+ async (entry) => await isCheckout((0, import_node_path4.join)(root, entry.name)) ? (0, import_node_path4.join)(root, entry.name) : null
45281
45544
  )
45282
45545
  );
45283
45546
  return found.filter((path) => path !== null);
45284
45547
  }
45548
+ async function recordCheckoutKept(dir, path, reason) {
45549
+ await writeJsonFileAtomic(freshnessFile(dir, path), { state: "kept", path, reason });
45550
+ }
45285
45551
  async function readCheckoutFreshness(dir, path) {
45286
- for (let current = path; ; current = (0, import_node_path3.dirname)(current)) {
45552
+ for (let current = path; ; current = (0, import_node_path4.dirname)(current)) {
45287
45553
  const read = await readJsonFile(freshnessFile(dir, current), freshnessSchema);
45288
45554
  if (read.kind === "ok") return read.value;
45289
- if ((0, import_node_path3.dirname)(current) === current) return null;
45555
+ if ((0, import_node_path4.dirname)(current) === current) return null;
45290
45556
  }
45291
45557
  }
45292
45558
 
45293
45559
  // src/platform/credential-store/credential-store.ts
45294
45560
  var import_node_crypto4 = require("crypto");
45295
- var import_promises8 = require("fs/promises");
45561
+ var import_promises9 = require("fs/promises");
45296
45562
 
45297
45563
  // src/platform/credential-store/parse.ts
45298
45564
  function parseStoredJson(text2, schema) {
@@ -45308,16 +45574,16 @@ function parseStoredJson(text2, schema) {
45308
45574
 
45309
45575
  // src/platform/windows-helper.ts
45310
45576
  var import_node_fs3 = require("fs");
45311
- var import_node_path4 = require("path");
45577
+ var import_node_path5 = require("path");
45312
45578
  var import_node_url = require("url");
45313
45579
  var import_meta = {};
45314
45580
  function windowsHelperPath(entry = process.argv[1]) {
45315
- const packaged = entry === void 0 ? null : (0, import_node_path4.join)((0, import_node_path4.dirname)((0, import_node_path4.resolve)(entry)), "alan-winhelper.exe");
45581
+ const packaged = entry === void 0 ? null : (0, import_node_path5.join)((0, import_node_path5.dirname)((0, import_node_path5.resolve)(entry)), "alan-winhelper.exe");
45316
45582
  if (entry !== void 0) {
45317
45583
  if (packaged !== null && (0, import_node_fs3.existsSync)(packaged)) return packaged;
45318
45584
  }
45319
45585
  try {
45320
- const local = (0, import_node_path4.resolve)((0, import_node_path4.dirname)((0, import_node_url.fileURLToPath)(import_meta.url)), "../../dist/alan-winhelper.exe");
45586
+ const local = (0, import_node_path5.resolve)((0, import_node_path5.dirname)((0, import_node_url.fileURLToPath)(import_meta.url)), "../../dist/alan-winhelper.exe");
45321
45587
  return (0, import_node_fs3.existsSync)(local) ? local : packaged;
45322
45588
  } catch {
45323
45589
  return packaged;
@@ -45385,7 +45651,7 @@ function createFileCredentialStore(path) {
45385
45651
  kind: "file",
45386
45652
  read: (schema) => readJsonFile(path, schema),
45387
45653
  write: (value) => writeJsonFileAtomic(path, value),
45388
- clear: () => (0, import_promises8.rm)(path, { force: true })
45654
+ clear: () => (0, import_promises9.rm)(path, { force: true })
45389
45655
  };
45390
45656
  }
45391
45657
  var KEYCHAIN_SERVICE = "ai.tryalan.runtime";
@@ -45480,14 +45746,14 @@ function defaultCredentialStoreKind(platform) {
45480
45746
  var import_node_child_process3 = require("child_process");
45481
45747
  var import_node_crypto5 = require("crypto");
45482
45748
  var import_node_fs4 = require("fs");
45483
- var import_promises10 = require("fs/promises");
45484
- var import_node_path5 = require("path");
45749
+ var import_promises11 = require("fs/promises");
45750
+ var import_node_path6 = require("path");
45485
45751
  var import_node_util2 = require("util");
45486
45752
  init_zod();
45487
45753
 
45488
45754
  // src/platform/process-identity.ts
45489
45755
  var import_node_child_process2 = require("child_process");
45490
- var import_promises9 = require("fs/promises");
45756
+ var import_promises10 = require("fs/promises");
45491
45757
  var import_node_util = require("util");
45492
45758
  var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
45493
45759
  function isProcessAlive(pid) {
@@ -45499,13 +45765,13 @@ function isProcessAlive(pid) {
45499
45765
  }
45500
45766
  }
45501
45767
  async function linuxStartTime(pid) {
45502
- const stat15 = await (0, import_promises9.readFile)(`/proc/${pid}/stat`, "utf8").catch(() => null);
45503
- if (stat15 === null) return null;
45504
- const fields = stat15.slice(stat15.lastIndexOf(")") + 2).split(" ");
45768
+ const stat16 = await (0, import_promises10.readFile)(`/proc/${pid}/stat`, "utf8").catch(() => null);
45769
+ if (stat16 === null) return null;
45770
+ const fields = stat16.slice(stat16.lastIndexOf(")") + 2).split(" ");
45505
45771
  return fields[19] ?? null;
45506
45772
  }
45507
45773
  async function linuxCommand(pid) {
45508
- const raw = await (0, import_promises9.readFile)(`/proc/${pid}/cmdline`, "utf8").catch(() => null);
45774
+ const raw = await (0, import_promises10.readFile)(`/proc/${pid}/cmdline`, "utf8").catch(() => null);
45509
45775
  return raw === null ? null : normalizeCommand(raw.replaceAll("\0", " "));
45510
45776
  }
45511
45777
  async function darwinCommand(pid) {
@@ -45599,11 +45865,11 @@ async function mayBeSameProcess(expected, probe = systemProcessProbe) {
45599
45865
  var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process3.execFile);
45600
45866
  var packageJsonSchema = external_exports.object({ version: external_exports.string().min(1) });
45601
45867
  function markVersionInUse(bundlePath) {
45602
- const versionDir = (0, import_node_path5.dirname)(bundlePath);
45603
- if ((0, import_node_path5.basename)((0, import_node_path5.dirname)(versionDir)) !== "versions") return { [Symbol.dispose]: () => {
45868
+ const versionDir = (0, import_node_path6.dirname)(bundlePath);
45869
+ if ((0, import_node_path6.basename)((0, import_node_path6.dirname)(versionDir)) !== "versions") return { [Symbol.dispose]: () => {
45604
45870
  } };
45605
- const marker = (0, import_node_path5.join)(versionDir, ".running", String(process.pid));
45606
- (0, import_node_fs4.mkdirSync)((0, import_node_path5.dirname)(marker), { recursive: true, mode: 448 });
45871
+ const marker = (0, import_node_path6.join)(versionDir, ".running", String(process.pid));
45872
+ (0, import_node_fs4.mkdirSync)((0, import_node_path6.dirname)(marker), { recursive: true, mode: 448 });
45607
45873
  (0, import_node_fs4.writeFileSync)(marker, "");
45608
45874
  const remove = () => (0, import_node_fs4.rmSync)(marker, { force: true });
45609
45875
  process.once("exit", remove);
@@ -45619,36 +45885,36 @@ function markVersionInUse(bundlePath) {
45619
45885
  var import_node_crypto6 = require("crypto");
45620
45886
  var import_node_fs5 = require("fs");
45621
45887
  var import_node_os = require("os");
45622
- var import_node_path6 = require("path");
45888
+ var import_node_path7 = require("path");
45623
45889
  function removeStaleEndpoint(endpoint) {
45624
45890
  if (!endpoint.startsWith("\\\\.\\pipe\\")) (0, import_node_fs5.rmSync)(endpoint, { force: true });
45625
45891
  }
45626
45892
 
45627
45893
  // src/platform/paths.ts
45628
- var import_node_path7 = require("path");
45894
+ var import_node_path8 = require("path");
45629
45895
  function runtimePaths(stateDir) {
45630
45896
  return {
45631
45897
  stateDir,
45632
- lock: (0, import_node_path7.join)(stateDir, "runtime.lock"),
45633
- machine: (0, import_node_path7.join)(stateDir, "machine.json"),
45634
- credential: (0, import_node_path7.join)(stateDir, "credential.json"),
45635
- runs: (0, import_node_path7.join)(stateDir, "runs"),
45636
- sessions: (0, import_node_path7.join)(stateDir, "sessions"),
45637
- sockets: (0, import_node_path7.join)(stateDir, "s"),
45638
- logs: (0, import_node_path7.join)(stateDir, "logs"),
45639
- tmp: (0, import_node_path7.join)(stateDir, "tmp")
45898
+ lock: (0, import_node_path8.join)(stateDir, "runtime.lock"),
45899
+ machine: (0, import_node_path8.join)(stateDir, "machine.json"),
45900
+ credential: (0, import_node_path8.join)(stateDir, "credential.json"),
45901
+ runs: (0, import_node_path8.join)(stateDir, "runs"),
45902
+ sessions: (0, import_node_path8.join)(stateDir, "sessions"),
45903
+ sockets: (0, import_node_path8.join)(stateDir, "s"),
45904
+ logs: (0, import_node_path8.join)(stateDir, "logs"),
45905
+ tmp: (0, import_node_path8.join)(stateDir, "tmp")
45640
45906
  };
45641
45907
  }
45642
45908
 
45643
45909
  // src/platform/process-memory.ts
45644
45910
  var import_node_child_process4 = require("child_process");
45645
- var import_promises11 = require("fs/promises");
45911
+ var import_promises12 = require("fs/promises");
45646
45912
  var import_node_util3 = require("util");
45647
45913
  var execFileAsync3 = (0, import_node_util3.promisify)(import_node_child_process4.execFile);
45648
45914
  var PROBE_TIMEOUT_MS = 2e3;
45649
45915
  async function readProcessRss(pid) {
45650
45916
  if (process.platform === "linux") {
45651
- const status = await (0, import_promises11.readFile)(`/proc/${pid}/status`, "utf8").catch(() => null);
45917
+ const status = await (0, import_promises12.readFile)(`/proc/${pid}/status`, "utf8").catch(() => null);
45652
45918
  const kilobytes = status === null ? void 0 : /^VmRSS:\s+(\d+)\s+kB$/m.exec(status)?.[1];
45653
45919
  return kilobytes === void 0 ? null : Number(kilobytes) * 1024;
45654
45920
  }
@@ -45665,7 +45931,7 @@ async function readProcessRss(pid) {
45665
45931
  }
45666
45932
 
45667
45933
  // src/platform/runtime-host.ts
45668
- var import_promises12 = require("fs/promises");
45934
+ var import_promises13 = require("fs/promises");
45669
45935
  var RUNTIME_HOST_KINDS = ["app", "standalone"];
45670
45936
 
45671
45937
  // src/platform/service/exec.ts
@@ -45680,7 +45946,7 @@ function statusOf(error61) {
45680
45946
  }
45681
45947
  return 1;
45682
45948
  }
45683
- var systemExec = (request2) => new Promise((resolve7) => {
45949
+ var systemExec = (request2) => new Promise((resolve9) => {
45684
45950
  const child = (0, import_node_child_process5.execFile)(
45685
45951
  request2.command,
45686
45952
  [...request2.args],
@@ -45691,7 +45957,7 @@ var systemExec = (request2) => new Promise((resolve7) => {
45691
45957
  windowsHide: true
45692
45958
  },
45693
45959
  (error61, stdout, stderr) => {
45694
- resolve7({ status: statusOf(error61), stdout, stderr });
45960
+ resolve9({ status: statusOf(error61), stdout, stderr });
45695
45961
  }
45696
45962
  );
45697
45963
  child.stdin?.on("error", () => {
@@ -45704,8 +45970,8 @@ init_alan_code();
45704
45970
 
45705
45971
  // src/capabilities/providers/commands.ts
45706
45972
  var import_node_fs6 = require("fs");
45707
- var import_promises16 = require("fs/promises");
45708
- var import_node_path8 = require("path");
45973
+ var import_promises17 = require("fs/promises");
45974
+ var import_node_path9 = require("path");
45709
45975
  var PROVIDER_COMMANDS = [
45710
45976
  // The engine, not a CLI of its own: `resolveProviderExecutable` finds the bundled one first.
45711
45977
  { backendKind: "alan_code", command: "opencode", name: "Alan Code" },
@@ -45740,8 +46006,8 @@ function pathDelimiter(platform) {
45740
46006
  }
45741
46007
  async function isRunnable(path, platform) {
45742
46008
  try {
45743
- if (!(await (0, import_promises16.stat)(path)).isFile()) return false;
45744
- if (platform !== "win32") await (0, import_promises16.access)(path, import_node_fs6.constants.X_OK);
46009
+ if (!(await (0, import_promises17.stat)(path)).isFile()) return false;
46010
+ if (platform !== "win32") await (0, import_promises17.access)(path, import_node_fs6.constants.X_OK);
45745
46011
  return true;
45746
46012
  } catch {
45747
46013
  return false;
@@ -45758,12 +46024,12 @@ async function resolveCommandOnPath(command, env, platform) {
45758
46024
  const directories = envValue(env, "PATH").split(pathDelimiter(platform)).map(
45759
46025
  (directory) => platform === "win32" ? directory.trim().replace(/^"(.*)"$/, "$1") : directory
45760
46026
  ).filter(
45761
- (directory) => platform === "win32" ? import_node_path8.win32.isAbsolute(directory) : directory.length > 0
46027
+ (directory) => platform === "win32" ? import_node_path9.win32.isAbsolute(directory) : directory.length > 0
45762
46028
  );
45763
46029
  const extensions = platform === "win32" ? windowsExtensions(command, env) : [""];
45764
46030
  for (const directory of directories) {
45765
46031
  for (const extension of extensions) {
45766
- const candidate = (0, import_node_path8.join)(directory, `${command}${extension}`);
46032
+ const candidate = (0, import_node_path9.join)(directory, `${command}${extension}`);
45767
46033
  if (await isRunnable(candidate, platform)) return candidate;
45768
46034
  }
45769
46035
  }
@@ -45798,14 +46064,14 @@ function resolveProviderExecutable(provider4, env, platform) {
45798
46064
 
45799
46065
  // src/capabilities/providers/managed.ts
45800
46066
  var import_node_crypto7 = require("crypto");
45801
- var import_promises17 = require("fs/promises");
45802
- var import_node_path9 = require("path");
46067
+ var import_promises18 = require("fs/promises");
46068
+ var import_node_path10 = require("path");
45803
46069
  init_zod();
45804
46070
  var VERSION = /^[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?$/;
45805
46071
  var selectedSchema = external_exports.record(external_exports.string(), external_exports.string());
45806
46072
  async function readManagedProviderVersion(file2, backendKind) {
45807
46073
  try {
45808
- const selected = selectedSchema.parse(JSON.parse(await (0, import_promises17.readFile)(file2, "utf8")));
46074
+ const selected = selectedSchema.parse(JSON.parse(await (0, import_promises18.readFile)(file2, "utf8")));
45809
46075
  const version2 = selected[backendKind];
45810
46076
  return version2 !== void 0 && VERSION.test(version2) ? version2 : null;
45811
46077
  } catch {
@@ -45816,8 +46082,8 @@ async function readManagedProviderVersion(file2, backendKind) {
45816
46082
  // ../shared/dist/node/skill-package.js
45817
46083
  var import_node_buffer = require("buffer");
45818
46084
  var import_node_crypto8 = require("crypto");
45819
- var import_promises18 = require("fs/promises");
45820
- var import_node_path10 = require("path");
46085
+ var import_promises19 = require("fs/promises");
46086
+ var import_node_path11 = require("path");
45821
46087
  var import_yaml = __toESM(require_dist(), 1);
45822
46088
  init_contracts();
45823
46089
  init_domain();
@@ -45888,7 +46154,7 @@ async function inspectSkillPackage(packageRoot, options = {}) {
45888
46154
  }
45889
46155
  const inspectedFiles = await Promise.all(files.map(readPackageFile));
45890
46156
  inspectedFiles.sort(comparePackageFiles);
45891
- const parsedMetadata = parseSkillMetadata(inspectedFiles.find((file2) => file2.manifest.path === "SKILL.md")?.bytes, options.expectedName === void 0 ? (0, import_node_path10.basename)(root) : options.expectedName);
46157
+ const parsedMetadata = parseSkillMetadata(inspectedFiles.find((file2) => file2.manifest.path === "SKILL.md")?.bytes, options.expectedName === void 0 ? (0, import_node_path11.basename)(root) : options.expectedName);
45892
46158
  const manifestFiles = inspectedFiles.map((file2) => file2.manifest);
45893
46159
  const diagnostics = [
45894
46160
  ...parsedMetadata.conformance,
@@ -45906,11 +46172,11 @@ async function inspectSkillPackage(packageRoot, options = {}) {
45906
46172
  };
45907
46173
  }
45908
46174
  async function requirePackageRoot(packageRoot) {
45909
- const root = await (0, import_promises18.realpath)((0, import_node_path10.resolve)(packageRoot)).catch(() => null);
46175
+ const root = await (0, import_promises19.realpath)((0, import_node_path11.resolve)(packageRoot)).catch(() => null);
45910
46176
  if (!root) {
45911
46177
  throw new SkillPackageError("INVALID_PACKAGE_ROOT", "Skill package directory does not exist");
45912
46178
  }
45913
- const rootStat = await (0, import_promises18.lstat)(root);
46179
+ const rootStat = await (0, import_promises19.lstat)(root);
45914
46180
  if (!rootStat.isDirectory()) {
45915
46181
  throw new SkillPackageError("INVALID_PACKAGE_ROOT", "Skill package root must be a directory");
45916
46182
  }
@@ -45930,13 +46196,13 @@ async function walkPackage(root, ignoredPaths) {
45930
46196
  }
45931
46197
  return files;
45932
46198
  async function walkDirectory(directory) {
45933
- const entries = await (0, import_promises18.readdir)(directory, { withFileTypes: true });
46199
+ const entries = await (0, import_promises19.readdir)(directory, { withFileTypes: true });
45934
46200
  for (const entry of entries) {
45935
- const absolutePath = (0, import_node_path10.resolve)(directory, entry.name);
46201
+ const absolutePath = (0, import_node_path11.resolve)(directory, entry.name);
45936
46202
  const normalizedPath = normalizeRelativePath(root, absolutePath);
45937
46203
  if (isIgnored(normalizedPath, entry.name, entry.isDirectory(), ignored2))
45938
46204
  continue;
45939
- const entryStat = await (0, import_promises18.lstat)(absolutePath);
46205
+ const entryStat = await (0, import_promises19.lstat)(absolutePath);
45940
46206
  if (entryStat.isSymbolicLink()) {
45941
46207
  throw new SkillPackageError("SYMLINK_BLOCKED", `Nested symbolic links are not allowed in Skill packages: ${normalizedPath}`, normalizedPath);
45942
46208
  }
@@ -45999,12 +46265,12 @@ function globToRegExp(pattern) {
45999
46265
  return new RegExp(`${source}(?:/.*)?$`);
46000
46266
  }
46001
46267
  function normalizeRelativePath(root, absolutePath) {
46002
- const nativeRelativePath = (0, import_node_path10.relative)(root, absolutePath);
46003
- if (!nativeRelativePath || nativeRelativePath.startsWith(`..${import_node_path10.sep}`) || nativeRelativePath === "..") {
46268
+ const nativeRelativePath = (0, import_node_path11.relative)(root, absolutePath);
46269
+ if (!nativeRelativePath || nativeRelativePath.startsWith(`..${import_node_path11.sep}`) || nativeRelativePath === "..") {
46004
46270
  throw new SkillPackageError("INVALID_PATH", "Skill package path escapes its root");
46005
46271
  }
46006
- const normalized2 = nativeRelativePath.split(import_node_path10.sep).join("/").normalize("NFC");
46007
- if (normalized2.includes("\0") || normalized2.includes("\uFFFD") || import_node_path10.posix.isAbsolute(normalized2)) {
46272
+ const normalized2 = nativeRelativePath.split(import_node_path11.sep).join("/").normalize("NFC");
46273
+ if (normalized2.includes("\0") || normalized2.includes("\uFFFD") || import_node_path11.posix.isAbsolute(normalized2)) {
46008
46274
  throw new SkillPackageError("INVALID_PATH", `Invalid Skill package path: ${normalized2}`);
46009
46275
  }
46010
46276
  return normalized2;
@@ -46039,13 +46305,13 @@ function requireSafeFile(path, size, normalizedPaths) {
46039
46305
  }
46040
46306
  }
46041
46307
  function isSecretPath(path) {
46042
- const name = import_node_path10.posix.basename(path).toLowerCase();
46308
+ const name = import_node_path11.posix.basename(path).toLowerCase();
46043
46309
  if (SECRET_BASENAMES.has(name) || name.startsWith(".env."))
46044
46310
  return true;
46045
46311
  return name.endsWith(".private-key.pem") || name.endsWith(".private-key.key");
46046
46312
  }
46047
46313
  async function readPackageFile(file2) {
46048
- const bytes = await (0, import_promises18.readFile)(file2.absolutePath);
46314
+ const bytes = await (0, import_promises19.readFile)(file2.absolutePath);
46049
46315
  return {
46050
46316
  bytes,
46051
46317
  manifest: {
@@ -46067,12 +46333,12 @@ function classifyFileKind(path) {
46067
46333
  return "reference";
46068
46334
  if (path.startsWith("assets/"))
46069
46335
  return "asset";
46070
- if (/^(?:licen[cs]e|copying|notice)(?:\.|$)/i.test(import_node_path10.posix.basename(path)))
46336
+ if (/^(?:licen[cs]e|copying|notice)(?:\.|$)/i.test(import_node_path11.posix.basename(path)))
46071
46337
  return "license";
46072
46338
  return "other";
46073
46339
  }
46074
46340
  function classifyPreview(path, bytes) {
46075
- const extension = import_node_path10.posix.extname(path).toLowerCase();
46341
+ const extension = import_node_path11.posix.extname(path).toLowerCase();
46076
46342
  if (IMAGE_EXTENSIONS2.has(extension))
46077
46343
  return "image";
46078
46344
  if (bytes.includes(0))
@@ -46176,7 +46442,7 @@ function normalizePackageReference(value) {
46176
46442
  const withoutSuffix = trimmed4.split(/[?#]/, 1)[0];
46177
46443
  if (!withoutSuffix)
46178
46444
  return null;
46179
- const normalized2 = import_node_path10.posix.normalize(withoutSuffix).replace(/^\.\//, "").normalize("NFC");
46445
+ const normalized2 = import_node_path11.posix.normalize(withoutSuffix).replace(/^\.\//, "").normalize("NFC");
46180
46446
  if (normalized2 === ".." || normalized2.startsWith("../"))
46181
46447
  return null;
46182
46448
  return normalized2;
@@ -46215,8 +46481,8 @@ function uint642(value) {
46215
46481
  }
46216
46482
 
46217
46483
  // src/capabilities/skills/store.ts
46218
- var import_promises19 = require("fs/promises");
46219
- var import_node_path11 = require("path");
46484
+ var import_promises20 = require("fs/promises");
46485
+ var import_node_path12 = require("path");
46220
46486
 
46221
46487
  // ../shared/dist/node/alan-skill-identity.js
46222
46488
  var import_node_crypto9 = require("crypto");
@@ -46239,21 +46505,21 @@ function alanSkillVersionId(slug, contentHash) {
46239
46505
  init_runtime_v2();
46240
46506
  init_zod();
46241
46507
  function skillsLayout(stateDir, home) {
46242
- const root = (0, import_node_path11.join)(stateDir, "skills");
46508
+ const root = (0, import_node_path12.join)(stateDir, "skills");
46243
46509
  return {
46244
46510
  root,
46245
- installedFile: (0, import_node_path11.join)(root, "installed.json"),
46246
- retiredFile: (0, import_node_path11.join)(root, "retired.json"),
46247
- localFile: (0, import_node_path11.join)(root, "local.json"),
46248
- versionsDir: (0, import_node_path11.join)(root, "versions"),
46249
- tmpDir: (0, import_node_path11.join)(root, "tmp"),
46250
- pluginDir: (0, import_node_path11.join)(root, "alan-plugin"),
46251
- pluginSkillsDir: (0, import_node_path11.join)(root, "alan-plugin", "skills"),
46252
- nativeDir: home === void 0 || home === "" ? null : (0, import_node_path11.join)(home, ".agents", "skills")
46511
+ installedFile: (0, import_node_path12.join)(root, "installed.json"),
46512
+ retiredFile: (0, import_node_path12.join)(root, "retired.json"),
46513
+ localFile: (0, import_node_path12.join)(root, "local.json"),
46514
+ versionsDir: (0, import_node_path12.join)(root, "versions"),
46515
+ tmpDir: (0, import_node_path12.join)(root, "tmp"),
46516
+ pluginDir: (0, import_node_path12.join)(root, "alan-plugin"),
46517
+ pluginSkillsDir: (0, import_node_path12.join)(root, "alan-plugin", "skills"),
46518
+ nativeDir: home === void 0 || home === "" ? null : (0, import_node_path12.join)(home, ".agents", "skills")
46253
46519
  };
46254
46520
  }
46255
46521
  function packageDirectory(layout, versionId) {
46256
- return (0, import_node_path11.join)(layout.versionsDir, versionId);
46522
+ return (0, import_node_path12.join)(layout.versionsDir, versionId);
46257
46523
  }
46258
46524
  var installedFileSchema = external_exports.object({ skills: external_exports.array(desiredMachineSkillSchema) });
46259
46525
  async function readInstalledSkills(layout) {
@@ -46280,7 +46546,7 @@ async function readLocalSkills(layout) {
46280
46546
  async function isLocalSkillCurrent(entry, contentHash, ignoredPaths) {
46281
46547
  if (entry.contentHash !== contentHash) return false;
46282
46548
  try {
46283
- if (await (0, import_promises19.realpath)(entry.path) !== entry.path) return false;
46549
+ if (await (0, import_promises20.realpath)(entry.path) !== entry.path) return false;
46284
46550
  const inspected = await inspectSkillPackage(entry.path, { expectedName: null, ignoredPaths });
46285
46551
  return inspected.contentHash === contentHash;
46286
46552
  } catch {
@@ -46295,7 +46561,7 @@ async function resolveLocalSkill(local, invocation) {
46295
46561
  }
46296
46562
  async function hasSkillFile(directory) {
46297
46563
  try {
46298
- return (await (0, import_promises19.stat)((0, import_node_path11.join)(directory, "SKILL.md"))).isFile();
46564
+ return (await (0, import_promises20.stat)((0, import_node_path12.join)(directory, "SKILL.md"))).isFile();
46299
46565
  } catch {
46300
46566
  return false;
46301
46567
  }
@@ -46313,7 +46579,7 @@ async function isIntact(layout, skill) {
46313
46579
  async function resolveNativeBuiltIn(layout, invocation, baked) {
46314
46580
  const slug = invocation.displayName;
46315
46581
  if (layout.nativeDir === null || invocation.skillId !== alanSkillId(slug)) return null;
46316
- const directory = (0, import_node_path11.join)(layout.nativeDir, slug);
46582
+ const directory = (0, import_node_path12.join)(layout.nativeDir, slug);
46317
46583
  try {
46318
46584
  const inspected = await inspectSkillPackage(directory, { expectedName: slug });
46319
46585
  if (baked === "exact" && alanSkillVersionId(slug, inspected.contentHash) !== invocation.versionId)
@@ -46359,10 +46625,10 @@ async function availableSkillIndex(layout) {
46359
46625
  });
46360
46626
  }
46361
46627
  if (layout.nativeDir !== null) {
46362
- const entries = await (0, import_promises19.readdir)(layout.nativeDir, { withFileTypes: true }).catch(() => []);
46628
+ const entries = await (0, import_promises20.readdir)(layout.nativeDir, { withFileTypes: true }).catch(() => []);
46363
46629
  for (const entry of entries) {
46364
46630
  if (entry.isDirectory() || entry.isSymbolicLink())
46365
- candidates2.push({ directory: (0, import_node_path11.join)(layout.nativeDir, entry.name) });
46631
+ candidates2.push({ directory: (0, import_node_path12.join)(layout.nativeDir, entry.name) });
46366
46632
  }
46367
46633
  }
46368
46634
  const bounded = candidates2.slice(0, 2e3);
@@ -46392,8 +46658,8 @@ async function inspectIndexedSkill(directory, contentHash) {
46392
46658
  // src/capabilities/skills/native-index.ts
46393
46659
  var import_node_crypto10 = require("crypto");
46394
46660
  var import_node_fs7 = require("fs");
46395
- var import_promises20 = require("fs/promises");
46396
- var import_node_path12 = require("path");
46661
+ var import_promises21 = require("fs/promises");
46662
+ var import_node_path13 = require("path");
46397
46663
  var ALAN_SKILLS_PLUGIN_NAME = "alan";
46398
46664
  var PLUGIN_MANIFEST = `${JSON.stringify(
46399
46665
  {
@@ -46405,18 +46671,18 @@ var PLUGIN_MANIFEST = `${JSON.stringify(
46405
46671
  )}
46406
46672
  `;
46407
46673
  function installedSkillFolders(layout) {
46408
- return (0, import_node_fs7.existsSync)((0, import_node_path12.join)(layout.pluginDir, ".claude-plugin", "plugin.json")) ? { pluginDir: layout.pluginDir, skillsDir: layout.pluginSkillsDir } : null;
46674
+ return (0, import_node_fs7.existsSync)((0, import_node_path13.join)(layout.pluginDir, ".claude-plugin", "plugin.json")) ? { pluginDir: layout.pluginDir, skillsDir: layout.pluginSkillsDir } : null;
46409
46675
  }
46410
46676
 
46411
46677
  // src/capabilities/workspace/index.ts
46412
- var import_node_path15 = require("path");
46678
+ var import_node_path16 = require("path");
46413
46679
 
46414
46680
  // src/capabilities/workspace/approved-paths.ts
46415
- var import_promises21 = require("fs/promises");
46681
+ var import_promises22 = require("fs/promises");
46416
46682
  init_zod();
46417
46683
 
46418
46684
  // src/capabilities/workspace/paths.ts
46419
- var import_node_path13 = require("path");
46685
+ var import_node_path14 = require("path");
46420
46686
  function stripWin32Namespace(path) {
46421
46687
  if (/^\\\\\?\\UNC\\/i.test(path)) return `\\\\${path.slice(8)}`;
46422
46688
  if (path.startsWith("\\\\?\\")) return path.slice(4);
@@ -46424,15 +46690,15 @@ function stripWin32Namespace(path) {
46424
46690
  }
46425
46691
  function comparablePath(path, platform) {
46426
46692
  if (platform === "win32") {
46427
- const normalized3 = import_node_path13.win32.normalize(stripWin32Namespace(path).replaceAll("/", "\\"));
46693
+ const normalized3 = import_node_path14.win32.normalize(stripWin32Namespace(path).replaceAll("/", "\\"));
46428
46694
  const trimmed4 = normalized3.length > 3 || !/^[a-z]:\\$/i.test(normalized3) ? normalized3.replace(/\\+$/, "") : normalized3;
46429
46695
  return trimmed4.toLowerCase();
46430
46696
  }
46431
- const normalized2 = import_node_path13.posix.normalize(path);
46697
+ const normalized2 = import_node_path14.posix.normalize(path);
46432
46698
  return normalized2.length > 1 ? normalized2.replace(/\/+$/, "") : normalized2;
46433
46699
  }
46434
46700
  function isAbsoluteFor(path, platform) {
46435
- return platform === "win32" ? import_node_path13.win32.isAbsolute(path) : import_node_path13.posix.isAbsolute(path);
46701
+ return platform === "win32" ? import_node_path14.win32.isAbsolute(path) : import_node_path14.posix.isAbsolute(path);
46436
46702
  }
46437
46703
  function isWithin(root, candidate, platform) {
46438
46704
  const separator = platform === "win32" ? "\\" : "/";
@@ -46450,7 +46716,7 @@ var storeSchema = external_exports.object({
46450
46716
  });
46451
46717
  async function realpathOrNull(path) {
46452
46718
  try {
46453
- return await (0, import_promises21.realpath)(path);
46719
+ return await (0, import_promises22.realpath)(path);
46454
46720
  } catch (error61) {
46455
46721
  const code = errnoCode(error61);
46456
46722
  if (code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "EPERM") {
@@ -46510,8 +46776,8 @@ async function openApprovedPaths(options) {
46510
46776
 
46511
46777
  // src/capabilities/workspace/locks.ts
46512
46778
  var import_node_crypto11 = require("crypto");
46513
- var import_promises22 = require("fs/promises");
46514
- var import_node_path14 = require("path");
46779
+ var import_promises23 = require("fs/promises");
46780
+ var import_node_path15 = require("path");
46515
46781
  init_zod();
46516
46782
  var LOCK_FORMAT = 1;
46517
46783
  var EXCLUSIVE_FILE = "exclusive.json";
@@ -46531,7 +46797,7 @@ function repositoryLockKey(commonDir, platform) {
46531
46797
  async function readOwner(path) {
46532
46798
  let text2;
46533
46799
  try {
46534
- text2 = await (0, import_promises22.readFile)(path, "utf8");
46800
+ text2 = await (0, import_promises23.readFile)(path, "utf8");
46535
46801
  } catch (error61) {
46536
46802
  if (errnoCode(error61) === "ENOENT") return { kind: "missing" };
46537
46803
  return { kind: "unreadable" };
@@ -46552,7 +46818,7 @@ async function removeIfSame(path, expected) {
46552
46818
  if (current.kind !== "owner" || current.owner.since !== expected.since) return;
46553
46819
  if (current.owner.pid !== expected.pid || current.owner.holder !== expected.holder) return;
46554
46820
  }
46555
- await (0, import_promises22.unlink)(path).catch((error61) => {
46821
+ await (0, import_promises23.unlink)(path).catch((error61) => {
46556
46822
  if (errnoCode(error61) !== "ENOENT") throw error61;
46557
46823
  });
46558
46824
  }
@@ -46577,7 +46843,7 @@ function openRepositoryLocks(options) {
46577
46843
  await removeIfSame(path, read.owner);
46578
46844
  return null;
46579
46845
  }
46580
- const age = await (0, import_promises22.stat)(path).then(
46846
+ const age = await (0, import_promises23.stat)(path).then(
46581
46847
  (info) => clock.now() - info.mtimeMs,
46582
46848
  () => 0
46583
46849
  );
@@ -46591,13 +46857,13 @@ function openRepositoryLocks(options) {
46591
46857
  });
46592
46858
  const folder = async (commonDir) => {
46593
46859
  const key = repositoryLockKey(commonDir, platform);
46594
- const dir = (0, import_node_path14.join)(options.dir, key);
46595
- await (0, import_promises22.mkdir)(dir, { recursive: true, mode: 448 });
46860
+ const dir = (0, import_node_path15.join)(options.dir, key);
46861
+ await (0, import_promises23.mkdir)(dir, { recursive: true, mode: 448 });
46596
46862
  return { key, dir };
46597
46863
  };
46598
46864
  const createExclusive = async (path, owner) => {
46599
46865
  try {
46600
- const handle = await (0, import_promises22.open)(path, "wx", 384);
46866
+ const handle = await (0, import_promises23.open)(path, "wx", 384);
46601
46867
  try {
46602
46868
  await handle.writeFile(JSON.stringify(owner));
46603
46869
  } finally {
@@ -46610,10 +46876,10 @@ function openRepositoryLocks(options) {
46610
46876
  }
46611
46877
  };
46612
46878
  const liveRun = async (dir) => {
46613
- const entries = await (0, import_promises22.readdir)(dir);
46879
+ const entries = await (0, import_promises23.readdir)(dir);
46614
46880
  for (const entry of entries) {
46615
46881
  if (!entry.startsWith(RUN_FILE_PREFIX)) continue;
46616
- const holder = await heldBy((0, import_node_path14.join)(dir, entry));
46882
+ const holder = await heldBy((0, import_node_path15.join)(dir, entry));
46617
46883
  if (holder !== null) return holder;
46618
46884
  }
46619
46885
  return null;
@@ -46621,7 +46887,7 @@ function openRepositoryLocks(options) {
46621
46887
  return {
46622
46888
  tryExclusive: async (commonDir, operationId) => {
46623
46889
  const { key, dir } = await folder(commonDir);
46624
- const path = (0, import_node_path14.join)(dir, EXCLUSIVE_FILE);
46890
+ const path = (0, import_node_path15.join)(dir, EXCLUSIVE_FILE);
46625
46891
  const owner = await self(operationId);
46626
46892
  if (!await createExclusive(path, owner)) {
46627
46893
  const holder = await heldBy(path);
@@ -46640,10 +46906,10 @@ function openRepositoryLocks(options) {
46640
46906
  tryShared: async (commonDir, runId) => {
46641
46907
  const { key, dir } = await folder(commonDir);
46642
46908
  const file2 = `${RUN_FILE_PREFIX}${(0, import_node_crypto11.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}.json`;
46643
- const path = (0, import_node_path14.join)(dir, file2);
46909
+ const path = (0, import_node_path15.join)(dir, file2);
46644
46910
  const owner = await self(runId);
46645
46911
  await writeJsonFileAtomic(path, owner);
46646
- const operation = await heldBy((0, import_node_path14.join)(dir, EXCLUSIVE_FILE));
46912
+ const operation = await heldBy((0, import_node_path15.join)(dir, EXCLUSIVE_FILE));
46647
46913
  if (operation !== null) {
46648
46914
  await removeIfSame(path, owner);
46649
46915
  return { kind: "busy", holder: operation };
@@ -46655,30 +46921,30 @@ function openRepositoryLocks(options) {
46655
46921
 
46656
46922
  // src/cli/config.ts
46657
46923
  var import_node_os7 = require("os");
46658
- var import_node_path29 = require("path");
46924
+ var import_node_path32 = require("path");
46659
46925
  init_zod();
46660
46926
 
46661
46927
  // src/client/locate.ts
46662
- var import_node_path16 = require("path");
46928
+ var import_node_path17 = require("path");
46663
46929
  var RUNTIME_PROFILES = ["production", "staging", "development", "local"];
46664
46930
  function defaultStateDir({ profile, platform, home, env }) {
46665
46931
  if (platform === "win32") {
46666
- return (0, import_node_path16.join)(env.LOCALAPPDATA ?? (0, import_node_path16.join)(home, "AppData", "Local"), "Alan", profile);
46932
+ return (0, import_node_path17.join)(env.LOCALAPPDATA ?? (0, import_node_path17.join)(home, "AppData", "Local"), "Alan", profile);
46667
46933
  }
46668
- return (0, import_node_path16.join)(env.XDG_STATE_HOME ?? (0, import_node_path16.join)(home, ".local", "state"), "alan", profile);
46934
+ return (0, import_node_path17.join)(env.XDG_STATE_HOME ?? (0, import_node_path17.join)(home, ".local", "state"), "alan", profile);
46669
46935
  }
46670
46936
  function defaultInstallDir({ platform, home, env }) {
46671
46937
  if (platform === "win32") {
46672
- return (0, import_node_path16.join)(env.LOCALAPPDATA ?? (0, import_node_path16.join)(home, "AppData", "Local"), "Alan", "runtime");
46938
+ return (0, import_node_path17.join)(env.LOCALAPPDATA ?? (0, import_node_path17.join)(home, "AppData", "Local"), "Alan", "runtime");
46673
46939
  }
46674
- return (0, import_node_path16.join)(env.XDG_DATA_HOME ?? (0, import_node_path16.join)(home, ".local", "share"), "alan", "runtime");
46940
+ return (0, import_node_path17.join)(env.XDG_DATA_HOME ?? (0, import_node_path17.join)(home, ".local", "share"), "alan", "runtime");
46675
46941
  }
46676
46942
 
46677
46943
  // src/sessions/index.ts
46678
46944
  var import_node_crypto16 = require("crypto");
46679
- var import_promises38 = require("fs/promises");
46945
+ var import_promises40 = require("fs/promises");
46680
46946
  var import_node_os6 = require("os");
46681
- var import_node_path28 = require("path");
46947
+ var import_node_path31 = require("path");
46682
46948
 
46683
46949
  // src/holder/control-client.ts
46684
46950
  var import_node_crypto12 = require("crypto");
@@ -46845,7 +47111,7 @@ function createProviderDrivers(options) {
46845
47111
  }
46846
47112
 
46847
47113
  // src/holder/engine-records.ts
46848
- var import_node_path17 = require("path");
47114
+ var import_node_path18 = require("path");
46849
47115
  init_zod();
46850
47116
  var ENGINES_FILE = "engines.json";
46851
47117
  var engineRecordSchema = external_exports.object({
@@ -46855,7 +47121,7 @@ var engineRecordSchema = external_exports.object({
46855
47121
  });
46856
47122
  var engineRecordsSchema = external_exports.object({ engines: external_exports.array(engineRecordSchema) });
46857
47123
  function engineRecordsPath(sessionDir) {
46858
- return (0, import_node_path17.join)(sessionDir, ENGINES_FILE);
47124
+ return (0, import_node_path18.join)(sessionDir, ENGINES_FILE);
46859
47125
  }
46860
47126
  function recordSpawnedEngines(path, clock, log) {
46861
47127
  const live = /* @__PURE__ */ new Map();
@@ -46910,17 +47176,17 @@ function createConversationMcpAuthorization(options) {
46910
47176
  }
46911
47177
 
46912
47178
  // src/holder/mcp-helper-access.ts
46913
- var import_promises29 = require("fs/promises");
47179
+ var import_promises30 = require("fs/promises");
46914
47180
  function createHelperMcpAccess(options) {
46915
47181
  return {
46916
47182
  [Symbol.asyncDispose]: async () => {
46917
- await (0, import_promises29.rm)(options.credentialPath, { force: true });
47183
+ await (0, import_promises30.rm)(options.credentialPath, { force: true });
46918
47184
  },
46919
47185
  url: options.managedMcp.url,
46920
47186
  authorization: async (signal) => {
46921
47187
  const authorization = await options.managedMcp.authorization(signal);
46922
47188
  if (authorization === void 0 || signal.aborted) {
46923
- await (0, import_promises29.rm)(options.credentialPath, { force: true });
47189
+ await (0, import_promises30.rm)(options.credentialPath, { force: true });
46924
47190
  return void 0;
46925
47191
  }
46926
47192
  const credential = {
@@ -46935,8 +47201,8 @@ function createHelperMcpAccess(options) {
46935
47201
  }
46936
47202
 
46937
47203
  // src/holder/run-inputs.ts
46938
- var import_promises30 = require("fs/promises");
46939
- var import_node_path18 = require("path");
47204
+ var import_promises31 = require("fs/promises");
47205
+ var import_node_path19 = require("path");
46940
47206
  init_dist();
46941
47207
  var NO_RUN_INPUTS = {
46942
47208
  attachments: [],
@@ -46950,18 +47216,18 @@ function safeFilename(filename) {
46950
47216
  return safe || "attachment";
46951
47217
  }
46952
47218
  async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
46953
- const dir = (0, import_node_path18.join)(tmpDir, "runs", spec.runId);
47219
+ const dir = (0, import_node_path19.join)(tmpDir, "runs", spec.runId);
46954
47220
  const cleanup = async () => {
46955
- await (0, import_promises30.rm)(dir, { recursive: true, force: true });
47221
+ await (0, import_promises31.rm)(dir, { recursive: true, force: true });
46956
47222
  };
46957
47223
  try {
46958
47224
  const credential = await source.fetchProviderCredential(spec.runId, signal);
46959
47225
  const attachments = [];
46960
- if (spec.attachments?.length) await (0, import_promises30.mkdir)(dir, { recursive: true, mode: 448 });
47226
+ if (spec.attachments?.length) await (0, import_promises31.mkdir)(dir, { recursive: true, mode: 448 });
46961
47227
  for (const [index, attachment] of (spec.attachments ?? []).entries()) {
46962
47228
  const bytes = await source.downloadAttachment(spec.runId, attachment.id, signal);
46963
- const path = (0, import_node_path18.join)(dir, `${index}-${safeFilename(attachment.filename)}`);
46964
- await (0, import_promises30.writeFile)(path, bytes, { mode: 384 });
47229
+ const path = (0, import_node_path19.join)(dir, `${index}-${safeFilename(attachment.filename)}`);
47230
+ await (0, import_promises31.writeFile)(path, bytes, { mode: 384 });
46965
47231
  const imageMimeType = attachment.kind === "image" ? detectImageMimeType(Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)) : null;
46966
47232
  attachments.push({
46967
47233
  id: attachment.id,
@@ -46992,27 +47258,27 @@ async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
46992
47258
  var import_node_crypto15 = require("crypto");
46993
47259
  var import_node_fs11 = require("fs");
46994
47260
  var import_node_net2 = require("net");
46995
- var import_node_path27 = require("path");
47261
+ var import_node_path30 = require("path");
46996
47262
  init_runtime_v2();
46997
47263
 
46998
47264
  // src/holder/admission.ts
46999
47265
  var import_node_fs9 = require("fs");
47000
- var import_promises34 = require("fs/promises");
47266
+ var import_promises36 = require("fs/promises");
47001
47267
  var import_node_os5 = require("os");
47002
- var import_node_path23 = require("path");
47268
+ var import_node_path26 = require("path");
47003
47269
  init_constants();
47004
47270
 
47005
47271
  // ../shared/dist/node/local-workspace.js
47006
47272
  var import_node_fs8 = require("fs");
47007
47273
  var import_node_os4 = require("os");
47008
- var import_node_path19 = require("path");
47274
+ var import_node_path20 = require("path");
47009
47275
  function resolveAlanDefaultWorkspacePath(homeDirectory = (0, import_node_os4.homedir)()) {
47010
- return (0, import_node_path19.join)(homeDirectory, ".alan", "workspace");
47276
+ return (0, import_node_path20.join)(homeDirectory, ".alan", "workspace");
47011
47277
  }
47012
47278
 
47013
47279
  // src/holder/admission-relocation.ts
47014
- var import_promises31 = require("fs/promises");
47015
- var import_node_path20 = require("path");
47280
+ var import_promises32 = require("fs/promises");
47281
+ var import_node_path21 = require("path");
47016
47282
  var MAX_RELOCATION_CANDIDATES = 200;
47017
47283
  var RELOCATION_BUDGET_MS = 2e4;
47018
47284
  function repositoryIdentity(url2) {
@@ -47047,8 +47313,8 @@ async function originIdentity(git, path, signal) {
47047
47313
  }
47048
47314
  async function childDirectories(parent, limit) {
47049
47315
  try {
47050
- const entries = await (0, import_promises31.readdir)(parent, { withFileTypes: true });
47051
- return entries.filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path20.join)(parent, entry.name));
47316
+ const entries = await (0, import_promises32.readdir)(parent, { withFileTypes: true });
47317
+ return entries.filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path21.join)(parent, entry.name));
47052
47318
  } catch {
47053
47319
  return [];
47054
47320
  }
@@ -47056,7 +47322,7 @@ async function childDirectories(parent, limit) {
47056
47322
  async function candidateFolders(search) {
47057
47323
  const roots = /* @__PURE__ */ new Map();
47058
47324
  for (const path of [search.missingPath, ...search.approvedWorkspacePaths]) {
47059
- const parent = (0, import_node_path20.dirname)((0, import_node_path20.resolve)(path));
47325
+ const parent = (0, import_node_path21.dirname)((0, import_node_path21.resolve)(path));
47060
47326
  roots.set(comparablePath(parent, search.platform), parent);
47061
47327
  }
47062
47328
  const candidates2 = /* @__PURE__ */ new Map();
@@ -47083,9 +47349,205 @@ async function discoverRelocatedWorkspace(search) {
47083
47349
  }
47084
47350
 
47085
47351
  // src/holder/checkout-refresh.ts
47352
+ var import_node_path24 = require("path");
47353
+
47354
+ // src/holder/claim-once.ts
47086
47355
  var import_node_crypto14 = require("crypto");
47087
- var import_promises32 = require("fs/promises");
47088
- var import_node_path21 = require("path");
47356
+ var import_promises33 = require("fs/promises");
47357
+ var import_node_path22 = require("path");
47358
+ async function claimOnce(dir, name) {
47359
+ try {
47360
+ await (0, import_promises33.mkdir)(dir, { recursive: true, mode: 448 });
47361
+ await (await (0, import_promises33.open)((0, import_node_path22.join)(dir, name), "wx")).close();
47362
+ return true;
47363
+ } catch {
47364
+ return false;
47365
+ }
47366
+ }
47367
+ function claimFirstLease(freshnessDir, path) {
47368
+ return claimOnce((0, import_node_path22.join)(freshnessDir, "leased"), (0, import_node_crypto14.createHash)("sha256").update(path).digest("hex"));
47369
+ }
47370
+
47371
+ // src/holder/requested-checkout.ts
47372
+ var import_promises34 = require("fs/promises");
47373
+ var import_node_path23 = require("path");
47374
+ var REMOTE2 = "origin";
47375
+ var REASON_MAX_CHARS = 200;
47376
+ function firstLine2(text2) {
47377
+ return (text2.trim().split("\n")[0] ?? "").slice(0, REASON_MAX_CHARS);
47378
+ }
47379
+ function reasonOf(output2, command) {
47380
+ return firstLine2(output2.stderr) || `git ${command} exited ${output2.exitCode}`;
47381
+ }
47382
+ function noted(checkout, situation, reason, action) {
47383
+ return {
47384
+ kind: "noted",
47385
+ line: `Note: ${checkout.path} ${situation}: ${reason}. ${action} before relying on its files.`
47386
+ };
47387
+ }
47388
+ function notSwitched(checkout, current, reason) {
47389
+ const on = current ?? "a detached HEAD";
47390
+ return noted(
47391
+ checkout,
47392
+ `is on ${on}, not ${checkout.branch}, the branch picked for this chat`,
47393
+ reason,
47394
+ `Switch it to ${checkout.branch}`
47395
+ );
47396
+ }
47397
+ async function clone2(checkout, deps, signal) {
47398
+ const parent = (0, import_node_path23.dirname)(checkout.path);
47399
+ await (0, import_promises34.mkdir)(parent, { recursive: true });
47400
+ await assertValidBranch(deps.git, parent, checkout.branch, signal);
47401
+ const output2 = await deps.git.run(
47402
+ {
47403
+ cwd: parent,
47404
+ args: [
47405
+ "clone",
47406
+ "--quiet",
47407
+ "--no-tags",
47408
+ "--depth=1",
47409
+ "--branch",
47410
+ checkout.branch,
47411
+ "--",
47412
+ checkout.repoUrl,
47413
+ checkout.path
47414
+ ],
47415
+ network: true
47416
+ },
47417
+ signal
47418
+ );
47419
+ if (output2.exitCode === 0) return { kind: "moved", how: "cloned" };
47420
+ return noted(
47421
+ checkout,
47422
+ `is missing, and cloning it on ${checkout.branch}, the branch picked for this chat, failed`,
47423
+ reasonOf(output2, "clone"),
47424
+ `Clone ${checkout.repoUrl} there`
47425
+ );
47426
+ }
47427
+ var SWITCHED = { kind: "moved", how: "switched" };
47428
+ function coversBranch(fetchConfig, branch) {
47429
+ return fetchConfig.split("\n").some(
47430
+ (refspec) => refspec === `+refs/heads/*:refs/remotes/${REMOTE2}/*` || refspec === `+refs/heads/${branch}:refs/remotes/${REMOTE2}/${branch}`
47431
+ );
47432
+ }
47433
+ async function fetchBranch(checkout, git, shallow, current) {
47434
+ const { branch } = checkout;
47435
+ const tracking = `refs/remotes/${REMOTE2}/${branch}`;
47436
+ const fetchConfig = await git(["config", "--get-all", `remote.${REMOTE2}.fetch`], {
47437
+ readOnly: true
47438
+ });
47439
+ if (!coversBranch(fetchConfig.stdout, branch)) {
47440
+ const added = await git(["remote", "set-branches", "--add", REMOTE2, branch]);
47441
+ if (added.exitCode !== 0) return notSwitched(checkout, current, reasonOf(added, "remote"));
47442
+ }
47443
+ const depth = shallow ? ["--depth=1"] : [];
47444
+ const fetched = await git(
47445
+ ["fetch", "--no-tags", "--quiet", ...depth, REMOTE2, `refs/heads/${branch}:${tracking}`],
47446
+ { network: true }
47447
+ );
47448
+ if (fetched.exitCode !== 0) return notSwitched(checkout, current, reasonOf(fetched, "fetch"));
47449
+ const tip = await git(["rev-parse", "--verify", tracking], { readOnly: true });
47450
+ if (tip.exitCode !== 0) return notSwitched(checkout, current, reasonOf(tip, "rev-parse"));
47451
+ return { kind: "fetched", tip: tip.stdout.trim() };
47452
+ }
47453
+ async function moveOnto(checkout, git, tip, current) {
47454
+ const { branch } = checkout;
47455
+ const local = await git(["rev-parse", "--verify", "-q", `refs/heads/${branch}`], {
47456
+ readOnly: true
47457
+ });
47458
+ if (local.exitCode !== 0) {
47459
+ const created = await git([
47460
+ "switch",
47461
+ "--quiet",
47462
+ "-c",
47463
+ branch,
47464
+ "--track",
47465
+ `${REMOTE2}/${branch}`
47466
+ ]);
47467
+ return created.exitCode === 0 ? SWITCHED : notSwitched(checkout, current, reasonOf(created, "switch"));
47468
+ }
47469
+ const localHead = local.stdout.trim();
47470
+ const ancestor = localHead === tip || (await git(["merge-base", "--is-ancestor", localHead, tip], { readOnly: true })).exitCode === 0;
47471
+ if (!ancestor) {
47472
+ return notSwitched(
47473
+ checkout,
47474
+ current,
47475
+ `its local ${branch} has diverged from ${REMOTE2}/${branch}`
47476
+ );
47477
+ }
47478
+ const switched = await git(["switch", "--quiet", branch]);
47479
+ if (switched.exitCode !== 0) return notSwitched(checkout, current, reasonOf(switched, "switch"));
47480
+ if (localHead === tip) return SWITCHED;
47481
+ const merged = await git(["merge", "--quiet", "--ff-only", tip]);
47482
+ return merged.exitCode === 0 ? SWITCHED : noted(
47483
+ checkout,
47484
+ `is on ${branch} but behind ${REMOTE2}/${branch}`,
47485
+ reasonOf(merged, "merge"),
47486
+ "Run `git pull --ff-only` there"
47487
+ );
47488
+ }
47489
+ async function switchTo(checkout, current, operationId, deps, signal) {
47490
+ var _stack = [];
47491
+ try {
47492
+ const cwd = checkout.path;
47493
+ const git = (args, invocation = {}) => deps.git.run({ cwd, args, ...invocation }, signal);
47494
+ await assertValidBranch(deps.git, cwd, checkout.branch, signal);
47495
+ const refs = await git(
47496
+ ["rev-parse", "--path-format=absolute", "--git-common-dir", "--is-shallow-repository"],
47497
+ { readOnly: true }
47498
+ );
47499
+ if (refs.exitCode !== 0) return notSwitched(checkout, current, reasonOf(refs, "rev-parse"));
47500
+ const [commonDir = "", shallow] = refs.stdout.trim().split("\n");
47501
+ const attempt = await deps.locks.tryExclusive(commonDir, operationId);
47502
+ if (attempt.kind === "busy") {
47503
+ return notSwitched(checkout, current, "another git operation holds the checkout");
47504
+ }
47505
+ const _lock = __using(_stack, attempt.lock, true);
47506
+ const now = await readCheckoutStatus(deps.git, cwd, signal);
47507
+ if (now === null || now.dirty) {
47508
+ return notSwitched(checkout, now?.branch ?? current, "it has uncommitted changes");
47509
+ }
47510
+ const fetched = await fetchBranch(checkout, git, shallow === "true", now.branch);
47511
+ if (fetched.kind !== "fetched") return fetched;
47512
+ const outcome2 = await moveOnto(checkout, git, fetched.tip, now.branch);
47513
+ const after = await readCheckoutStatus(deps.git, cwd, signal);
47514
+ if (after?.branch === checkout.branch) {
47515
+ await recordCheckoutKept(deps.dir, cwd, "requested_branch");
47516
+ }
47517
+ return outcome2;
47518
+ } catch (_) {
47519
+ var _error = _, _hasError = true;
47520
+ } finally {
47521
+ var _promise2 = __callDispose(_stack, _error, _hasError);
47522
+ _promise2 && await _promise2;
47523
+ }
47524
+ }
47525
+ async function applyRequestedCheckout(checkout, spec, deps, signal) {
47526
+ try {
47527
+ if (!await isCheckout(checkout.path)) return await clone2(checkout, deps, signal);
47528
+ const status = await readCheckoutStatus(deps.git, checkout.path, signal);
47529
+ if (status === null) return notSwitched(checkout, null, "git status failed");
47530
+ if (status.branch === checkout.branch) return { kind: "on_branch" };
47531
+ if (status.dirty) return notSwitched(checkout, status.branch, "it has uncommitted changes");
47532
+ if (!await claimFirstLease(deps.dir, checkout.path)) {
47533
+ return notSwitched(
47534
+ checkout,
47535
+ status.branch,
47536
+ "an earlier conversation on this machine already uses it"
47537
+ );
47538
+ }
47539
+ return await switchTo(checkout, status.branch, `checkout-${spec.runId}`, deps, signal);
47540
+ } catch (error61) {
47541
+ return noted(
47542
+ checkout,
47543
+ `could not be put on ${checkout.branch}, the branch picked for this chat`,
47544
+ firstLine2(error61 instanceof Error ? error61.message : String(error61)) || "unknown error",
47545
+ "Check it"
47546
+ );
47547
+ }
47548
+ }
47549
+
47550
+ // src/holder/checkout-refresh.ts
47089
47551
  function short(sha) {
47090
47552
  return sha.slice(0, 12);
47091
47553
  }
@@ -47095,15 +47557,6 @@ function staleLine(path, snapshot2, tip) {
47095
47557
  const remote = tip === void 0 ? "may be ahead" : `is ahead at ${short(tip)}`;
47096
47558
  return `Note: ${path} ${checkout}; ${base} ${remote}. Run \`git pull --ff-only\` there before relying on its files.`;
47097
47559
  }
47098
- async function claimOnce(dir, name) {
47099
- try {
47100
- await (0, import_promises32.mkdir)(dir, { recursive: true, mode: 448 });
47101
- await (await (0, import_promises32.open)((0, import_node_path21.join)(dir, name), "wx")).close();
47102
- return true;
47103
- } catch {
47104
- return false;
47105
- }
47106
- }
47107
47560
  async function fastForward(freshness, operationId, deps, signal) {
47108
47561
  var _stack = [];
47109
47562
  try {
@@ -47128,10 +47581,7 @@ async function fastForward(freshness, operationId, deps, signal) {
47128
47581
  }
47129
47582
  }
47130
47583
  async function atFirstLease(freshness, spec, deps, signal) {
47131
- const first = await claimOnce(
47132
- (0, import_node_path21.join)(deps.dir, "leased"),
47133
- (0, import_node_crypto14.createHash)("sha256").update(freshness.path).digest("hex")
47134
- );
47584
+ const first = await claimFirstLease(deps.dir, freshness.path);
47135
47585
  switch (freshness.state) {
47136
47586
  case "current":
47137
47587
  case "kept":
@@ -47157,32 +47607,73 @@ async function checkoutsOf(spec, leaseTargets) {
47157
47607
  if (leaseTargets.length > 0 || spec.projectPath === void 0) return [...leaseTargets];
47158
47608
  return checkoutsUnder(spec.projectPath);
47159
47609
  }
47160
- function createCheckoutRefresh(deps) {
47161
- return async (spec, leaseTargets, signal) => {
47162
- if (spec.providerSessionId !== void 0) return void 0;
47163
- if (!await claimOnce((0, import_node_path21.join)(deps.dir, "conversations"), spec.conversationId)) return void 0;
47164
- const lines = [];
47165
- for (const target of await checkoutsOf(spec, leaseTargets)) {
47166
- const freshness = await readCheckoutFreshness(deps.dir, target);
47167
- if (freshness === null) continue;
47168
- const outcome2 = await atFirstLease(freshness, spec, deps, signal).catch(
47169
- () => "noted"
47170
- );
47171
- if (outcome2 === "noted") lines.push(lineFor(freshness));
47172
- deps.log.info("workspace.refresh", {
47610
+ function requestedCheckoutsOf(spec, log) {
47611
+ const roots = spec.approvedWorkspacePaths ?? [];
47612
+ return (spec.requestedCheckouts ?? []).filter((checkout) => {
47613
+ const approved = roots.some((root) => isWithin(root, checkout.path, process.platform));
47614
+ if (!approved) {
47615
+ log.warn("workspace.requested_checkout_outside_workspace", {
47173
47616
  runId: spec.runId,
47174
- path: freshness.path,
47175
- state: freshness.state,
47176
- outcome: outcome2
47617
+ path: checkout.path
47177
47618
  });
47178
47619
  }
47620
+ return approved;
47621
+ });
47622
+ }
47623
+ async function applyRequestedCheckouts(spec, deps, signal) {
47624
+ const settled2 = /* @__PURE__ */ new Set();
47625
+ const lines = [];
47626
+ for (const checkout of requestedCheckoutsOf(spec, deps.log)) {
47627
+ const outcome2 = await applyRequestedCheckout(checkout, spec, deps, signal);
47628
+ deps.log.info("workspace.requested_checkout", {
47629
+ runId: spec.runId,
47630
+ path: checkout.path,
47631
+ branch: checkout.branch,
47632
+ outcome: outcome2.kind,
47633
+ ...outcome2.kind === "moved" ? { how: outcome2.how } : {}
47634
+ });
47635
+ if (outcome2.kind === "on_branch") continue;
47636
+ settled2.add((0, import_node_path24.resolve)(checkout.path));
47637
+ if (outcome2.kind === "noted") lines.push(outcome2.line);
47638
+ }
47639
+ return { settled: settled2, lines };
47640
+ }
47641
+ async function refreshSnapshotCheckouts(spec, targets, settled2, deps, signal) {
47642
+ const lines = [];
47643
+ for (const target of targets) {
47644
+ if (settled2.has((0, import_node_path24.resolve)(target))) continue;
47645
+ const freshness = await readCheckoutFreshness(deps.dir, target);
47646
+ if (freshness === null) continue;
47647
+ const outcome2 = await atFirstLease(freshness, spec, deps, signal).catch(
47648
+ () => "noted"
47649
+ );
47650
+ if (outcome2 === "noted") lines.push(lineFor(freshness));
47651
+ deps.log.info("workspace.refresh", {
47652
+ runId: spec.runId,
47653
+ path: freshness.path,
47654
+ state: freshness.state,
47655
+ outcome: outcome2
47656
+ });
47657
+ }
47658
+ return lines;
47659
+ }
47660
+ function createCheckoutRefresh(deps) {
47661
+ return async (spec, leaseTargets, signal) => {
47662
+ if (spec.providerSessionId !== void 0) return void 0;
47663
+ if (!await claimOnce((0, import_node_path24.join)(deps.dir, "conversations"), spec.conversationId)) return void 0;
47664
+ const requested = await applyRequestedCheckouts(spec, deps, signal);
47665
+ const targets = await checkoutsOf(spec, leaseTargets);
47666
+ const lines = [
47667
+ ...requested.lines,
47668
+ ...await refreshSnapshotCheckouts(spec, targets, requested.settled, deps, signal)
47669
+ ];
47179
47670
  return lines.length === 0 ? void 0 : lines.join("\n");
47180
47671
  };
47181
47672
  }
47182
47673
 
47183
47674
  // src/holder/lease.ts
47184
- var import_promises33 = require("fs/promises");
47185
- var import_node_path22 = require("path");
47675
+ var import_promises35 = require("fs/promises");
47676
+ var import_node_path25 = require("path");
47186
47677
  var LEASE_CHECK_EVERY_MS = 5e3;
47187
47678
  var MAX_TRANSIENT_FAILURES = 3;
47188
47679
  var BACKOFF_BASE_MS = 1e3;
@@ -47196,8 +47687,8 @@ function identityFailure(code, workspacePath) {
47196
47687
  return { code, problemCode: "app.workspace.missing", message: MESSAGES[code], workspacePath };
47197
47688
  }
47198
47689
  async function fileIdentity(path) {
47199
- const canonical = await (0, import_promises33.realpath)(path);
47200
- const info = await (0, import_promises33.stat)(canonical, { bigint: true });
47690
+ const canonical = await (0, import_promises35.realpath)(path);
47691
+ const info = await (0, import_promises35.stat)(canonical, { bigint: true });
47201
47692
  return `${canonical}:${info.dev}:${info.ino}`;
47202
47693
  }
47203
47694
  async function snapshot(git, path, signal) {
@@ -47216,7 +47707,7 @@ async function snapshot(git, path, signal) {
47216
47707
  workspace: await fileIdentity(path),
47217
47708
  repository: await fileIdentity(commonDir),
47218
47709
  worktree: await fileIdentity(gitDir),
47219
- commonDir: await (0, import_promises33.realpath)(commonDir)
47710
+ commonDir: await (0, import_promises35.realpath)(commonDir)
47220
47711
  };
47221
47712
  } catch {
47222
47713
  return null;
@@ -47229,7 +47720,7 @@ async function gitValue(git, path, args, signal) {
47229
47720
  }
47230
47721
  async function pathExists(path) {
47231
47722
  try {
47232
- await (0, import_promises33.stat)(path);
47723
+ await (0, import_promises35.stat)(path);
47233
47724
  return true;
47234
47725
  } catch (error61) {
47235
47726
  return errnoCode(error61) !== "ENOENT" && errnoCode(error61) !== "ENOTDIR";
@@ -47238,19 +47729,19 @@ async function pathExists(path) {
47238
47729
  async function hasGitMarker(path) {
47239
47730
  let directory;
47240
47731
  try {
47241
- directory = await (0, import_promises33.realpath)(path);
47732
+ directory = await (0, import_promises35.realpath)(path);
47242
47733
  } catch {
47243
47734
  return true;
47244
47735
  }
47245
47736
  for (; ; ) {
47246
47737
  try {
47247
- await (0, import_promises33.stat)((0, import_node_path22.join)(directory, ".git"));
47738
+ await (0, import_promises35.stat)((0, import_node_path25.join)(directory, ".git"));
47248
47739
  return true;
47249
47740
  } catch (error61) {
47250
47741
  const code = errnoCode(error61);
47251
47742
  if (code !== "ENOENT" && code !== "ENOTDIR") return true;
47252
47743
  }
47253
- const parent = (0, import_node_path22.dirname)(directory);
47744
+ const parent = (0, import_node_path25.dirname)(directory);
47254
47745
  if (parent === directory) return false;
47255
47746
  directory = parent;
47256
47747
  }
@@ -47414,7 +47905,7 @@ function volumeRoot(path) {
47414
47905
  }
47415
47906
  async function exists(path) {
47416
47907
  try {
47417
- await (0, import_promises34.stat)(path);
47908
+ await (0, import_promises36.stat)(path);
47418
47909
  return true;
47419
47910
  } catch {
47420
47911
  return false;
@@ -47422,10 +47913,10 @@ async function exists(path) {
47422
47913
  }
47423
47914
  async function inspectReadiness(path) {
47424
47915
  try {
47425
- if (!(await (0, import_promises34.stat)(path)).isDirectory()) {
47916
+ if (!(await (0, import_promises36.stat)(path)).isDirectory()) {
47426
47917
  return { ready: false, missing: true, message: MESSAGES2.missing };
47427
47918
  }
47428
- await (0, import_promises34.access)(path, import_node_fs9.constants.R_OK | import_node_fs9.constants.W_OK | import_node_fs9.constants.X_OK);
47919
+ await (0, import_promises36.access)(path, import_node_fs9.constants.R_OK | import_node_fs9.constants.W_OK | import_node_fs9.constants.X_OK);
47429
47920
  return { ready: true };
47430
47921
  } catch (error61) {
47431
47922
  const code = errnoCode(error61) ?? "";
@@ -47503,8 +47994,8 @@ async function admitDefaultWorkspace(spec, context, skills) {
47503
47994
  const { env } = context;
47504
47995
  const path = resolveAlanDefaultWorkspacePath(env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)());
47505
47996
  try {
47506
- await (0, import_promises34.mkdir)(path, { recursive: true, mode: 448 });
47507
- await (0, import_promises34.access)(path, import_node_fs9.constants.R_OK | import_node_fs9.constants.W_OK | import_node_fs9.constants.X_OK);
47997
+ await (0, import_promises36.mkdir)(path, { recursive: true, mode: 448 });
47998
+ await (0, import_promises36.access)(path, import_node_fs9.constants.R_OK | import_node_fs9.constants.W_OK | import_node_fs9.constants.X_OK);
47508
47999
  return {
47509
48000
  kind: "admitted",
47510
48001
  spec: { ...spec, projectPath: path },
@@ -47577,10 +48068,12 @@ async function admitRun(spec, context, signal) {
47577
48068
  };
47578
48069
  }
47579
48070
  var PROBE_TIMEOUT_MS2 = 5e3;
48071
+ var CHECKOUT_LOCAL_TIMEOUT_MS = 6e4;
48072
+ var CHECKOUT_NETWORK_TIMEOUT_MS = 12e4;
47580
48073
  function createHolderWorkspace(machine, clock, log) {
47581
48074
  const platform = machine.platform ?? process.platform;
47582
48075
  const git = createGitRunner({ env: machine.env, platform, localTimeoutMs: PROBE_TIMEOUT_MS2 });
47583
- const locks = openRepositoryLocks({ dir: (0, import_node_path23.join)(machine.stateDir, "locks"), clock, platform });
48076
+ const locks = openRepositoryLocks({ dir: (0, import_node_path26.join)(machine.stateDir, "locks"), clock, platform });
47584
48077
  return {
47585
48078
  admission: {
47586
48079
  env: machine.env,
@@ -47592,7 +48085,7 @@ function createHolderWorkspace(machine, clock, log) {
47592
48085
  ),
47593
48086
  approvedRoots: async () => {
47594
48087
  const approved = await openApprovedPaths({
47595
- file: (0, import_node_path23.join)(machine.stateDir, "workspaces.json"),
48088
+ file: (0, import_node_path26.join)(machine.stateDir, "workspaces.json"),
47596
48089
  log,
47597
48090
  platform
47598
48091
  });
@@ -47602,10 +48095,15 @@ function createHolderWorkspace(machine, clock, log) {
47602
48095
  lease: { git, locks, clock, log, platform },
47603
48096
  ...machine.refreshesFirstCheckout === true ? {
47604
48097
  refreshFirstCheckout: createCheckoutRefresh({
47605
- git,
48098
+ git: createGitRunner({
48099
+ env: machine.env,
48100
+ platform,
48101
+ localTimeoutMs: CHECKOUT_LOCAL_TIMEOUT_MS,
48102
+ networkTimeoutMs: CHECKOUT_NETWORK_TIMEOUT_MS
48103
+ }),
47606
48104
  locks,
47607
48105
  log,
47608
- dir: (0, import_node_path23.join)(machine.stateDir, "checkout-freshness")
48106
+ dir: (0, import_node_path26.join)(machine.stateDir, "checkout-freshness")
47609
48107
  })
47610
48108
  } : {}
47611
48109
  };
@@ -47633,7 +48131,7 @@ async function respondToTurn(runningRunId, gate, driver, request2) {
47633
48131
  }
47634
48132
 
47635
48133
  // src/holder/session-facts.ts
47636
- var import_promises35 = require("fs/promises");
48134
+ var import_promises37 = require("fs/promises");
47637
48135
  var CLI_RSS_CACHE_MS = 1e4;
47638
48136
  var LOGIN_PROBLEM_PREFIX = "cli.auth.";
47639
48137
  function isLoginFailure(result) {
@@ -47659,8 +48157,8 @@ function createSessionFacts(options) {
47659
48157
  const path = await resolveCommandOnPath(command, env, platform);
47660
48158
  if (path === null) return null;
47661
48159
  try {
47662
- const real = await (0, import_promises35.realpath)(path);
47663
- const info = await (0, import_promises35.stat)(real);
48160
+ const real = await (0, import_promises37.realpath)(path);
48161
+ const info = await (0, import_promises37.stat)(real);
47664
48162
  return { command, key: `${real}:${info.ino}:${info.size}:${info.mtimeMs}` };
47665
48163
  } catch {
47666
48164
  return null;
@@ -47747,8 +48245,8 @@ function createSessionFacts(options) {
47747
48245
  init_acp2();
47748
48246
 
47749
48247
  // src/run-log/directory.ts
47750
- var import_promises36 = require("fs/promises");
47751
- var import_node_path24 = require("path");
48248
+ var import_promises38 = require("fs/promises");
48249
+ var import_node_path27 = require("path");
47752
48250
  init_runtime_v2();
47753
48251
  init_zod();
47754
48252
  var runMetaSchema = external_exports.object({
@@ -47770,17 +48268,17 @@ var runMetaSchema = external_exports.object({
47770
48268
  }).optional()
47771
48269
  });
47772
48270
  function runDirectory(runsDir, runId) {
47773
- const dir = (0, import_node_path24.join)(runsDir, runId);
48271
+ const dir = (0, import_node_path27.join)(runsDir, runId);
47774
48272
  return {
47775
48273
  dir,
47776
- log: (0, import_node_path24.join)(dir, "log.jsonl"),
47777
- upload: (0, import_node_path24.join)(dir, "upload.json"),
47778
- meta: (0, import_node_path24.join)(dir, "run.json")
48274
+ log: (0, import_node_path27.join)(dir, "log.jsonl"),
48275
+ upload: (0, import_node_path27.join)(dir, "upload.json"),
48276
+ meta: (0, import_node_path27.join)(dir, "run.json")
47779
48277
  };
47780
48278
  }
47781
48279
  async function isRunClaimed(runsDir, runId) {
47782
48280
  try {
47783
- return (await (0, import_promises36.stat)(runDirectory(runsDir, runId).log)).size > 0;
48281
+ return (await (0, import_promises38.stat)(runDirectory(runsDir, runId).log)).size > 0;
47784
48282
  } catch (error61) {
47785
48283
  if (errnoCode(error61) === "ENOENT") return false;
47786
48284
  throw error61;
@@ -47788,8 +48286,8 @@ async function isRunClaimed(runsDir, runId) {
47788
48286
  }
47789
48287
 
47790
48288
  // src/run-log/conversation-index.ts
47791
- var import_promises37 = require("fs/promises");
47792
- var import_node_path25 = require("path");
48289
+ var import_promises39 = require("fs/promises");
48290
+ var import_node_path28 = require("path");
47793
48291
  init_runtime_v2();
47794
48292
  init_zod();
47795
48293
  var ORDINALS_PER_SHARD = 1e3;
@@ -47805,13 +48303,13 @@ var coverageSchema = external_exports.object({
47805
48303
  nextExpectedOrdinal: external_exports.number().int().positive()
47806
48304
  });
47807
48305
  function conversationsDirectory(runsDir) {
47808
- return (0, import_node_path25.join)((0, import_node_path25.dirname)(runsDir), "conversations");
48306
+ return (0, import_node_path28.join)((0, import_node_path28.dirname)(runsDir), "conversations");
47809
48307
  }
47810
48308
  function indexDirectory(runsDir, conversationId) {
47811
- return (0, import_node_path25.join)(conversationsDirectory(runsDir), conversationId, "turn-index");
48309
+ return (0, import_node_path28.join)(conversationsDirectory(runsDir), conversationId, "turn-index");
47812
48310
  }
47813
48311
  function shardPath(runsDir, conversationId, ordinal) {
47814
- return (0, import_node_path25.join)(
48312
+ return (0, import_node_path28.join)(
47815
48313
  indexDirectory(runsDir, conversationId),
47816
48314
  `${Math.floor(ordinal / ORDINALS_PER_SHARD)}.jsonl`
47817
48315
  );
@@ -47820,10 +48318,10 @@ async function indexConversationRun(runsDir, conversationId, ordinal, assistantO
47820
48318
  const nextOrdinal = assistantOrdinal + 1;
47821
48319
  if (nextOrdinal <= ordinal) throw new Error("Assistant order must follow the prompt");
47822
48320
  const path = shardPath(runsDir, conversationId, ordinal);
47823
- await (0, import_promises37.mkdir)((0, import_node_path25.dirname)(path), { recursive: true, mode: 448 });
47824
- await (0, import_promises37.appendFile)(path, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
48321
+ await (0, import_promises39.mkdir)((0, import_node_path28.dirname)(path), { recursive: true, mode: 448 });
48322
+ await (0, import_promises39.appendFile)(path, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
47825
48323
  `, { mode: 384 });
47826
- const coveragePath = (0, import_node_path25.join)((0, import_node_path25.dirname)((0, import_node_path25.dirname)(path)), "coverage.json");
48324
+ const coveragePath = (0, import_node_path28.join)((0, import_node_path28.dirname)((0, import_node_path28.dirname)(path)), "coverage.json");
47827
48325
  const coverage = await readJsonFile(coveragePath, coverageSchema);
47828
48326
  const current = coverage.kind === "ok" ? coverage.value : null;
47829
48327
  const next = nextCoverage(current, ordinal, nextOrdinal);
@@ -47867,7 +48365,7 @@ var decoder = new TextDecoder();
47867
48365
 
47868
48366
  // src/run-log/writer.ts
47869
48367
  var import_node_fs10 = require("fs");
47870
- var import_node_path26 = require("path");
48368
+ var import_node_path29 = require("path");
47871
48369
  init_runtime_v2();
47872
48370
  function lastSeq(fd, size) {
47873
48371
  for (const length of tailWindows(size)) {
@@ -47883,7 +48381,7 @@ function lastSeq(fd, size) {
47883
48381
  throw new RuntimeFault("record_too_large", "Run log tail record is larger than any record");
47884
48382
  }
47885
48383
  function openRunLog(path, clock) {
47886
- (0, import_node_fs10.mkdirSync)((0, import_node_path26.dirname)(path), { recursive: true, mode: 448 });
48384
+ (0, import_node_fs10.mkdirSync)((0, import_node_path29.dirname)(path), { recursive: true, mode: 448 });
47887
48385
  const fd = (0, import_node_fs10.openSync)(path, "a+", 384);
47888
48386
  let size = (0, import_node_fs10.fstatSync)(fd).size;
47889
48387
  let seq = lastSeq(fd, size);
@@ -48219,7 +48717,7 @@ async function runHolder({
48219
48717
  try {
48220
48718
  const identity = await readProcessIdentity(process.pid);
48221
48719
  if (identity === null) throw new RuntimeFault("internal", "Cannot read own process identity");
48222
- const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path27.dirname)(launch.statusPath)), clock, log));
48720
+ const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path30.dirname)(launch.statusPath)), clock, log));
48223
48721
  const holder = {
48224
48722
  state: "idle",
48225
48723
  runId: null,
@@ -48415,16 +48913,16 @@ async function runHolder({
48415
48913
  client.on("error", () => holder.clients.delete(client));
48416
48914
  });
48417
48915
  removeStaleEndpoint(launch.endpoint);
48418
- await new Promise((resolve7, reject) => {
48916
+ await new Promise((resolve9, reject) => {
48419
48917
  server.once("error", reject);
48420
- server.listen(launch.endpoint, () => resolve7());
48918
+ server.listen(launch.endpoint, () => resolve9());
48421
48919
  });
48422
48920
  await writeStatus();
48423
48921
  log.info("holder.ready", { conversationId: launch.conversationId, pid: identity.pid });
48424
- await new Promise((resolve7) => exit.signal.addEventListener("abort", () => resolve7()));
48922
+ await new Promise((resolve9) => exit.signal.addEventListener("abort", () => resolve9()));
48425
48923
  await driver.suspend?.().catch((error61) => log.warn("holder.driver_suspend_failed", { error: error61 }));
48426
48924
  for (const client of holder.clients) client.end();
48427
- await new Promise((resolve7) => server.close(() => resolve7()));
48925
+ await new Promise((resolve9) => server.close(() => resolve9()));
48428
48926
  (0, import_node_fs11.rmSync)(launch.statusPath, { force: true });
48429
48927
  log.info("holder.suspended", { conversationId: launch.conversationId });
48430
48928
  } catch (_) {
@@ -48564,7 +49062,7 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
48564
49062
  providerProbes: ALAN_RUNTIME_PROVIDER_PROBES === "on",
48565
49063
  providerToolchain: ALAN_RUNTIME_PROVIDER_NODE !== void 0 && ALAN_RUNTIME_PROVIDER_NPM_CLI !== void 0 ? { node: ALAN_RUNTIME_PROVIDER_NODE, npmCli: ALAN_RUNTIME_PROVIDER_NPM_CLI } : null,
48566
49064
  home,
48567
- configHome: XDG_CONFIG_HOME ?? (0, import_node_path29.join)(home, ".config"),
49065
+ configHome: XDG_CONFIG_HOME ?? (0, import_node_path32.join)(home, ".config"),
48568
49066
  codexHome: resolveCodexHome(CODEX_HOME, home),
48569
49067
  ...githubProxyConfig({ ALAN_RUNTIME_GITHUB_PROXY, XDG_CONFIG_HOME, GH_CONFIG_DIR }, home),
48570
49068
  gitGatewayUrl: ALAN_RUNTIME_GIT_GATEWAY_URL ?? null,
@@ -48574,13 +49072,13 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
48574
49072
  };
48575
49073
  }
48576
49074
  function resolveCodexHome(configuredHome, home) {
48577
- return configuredHome ?? (0, import_node_path29.join)(home, ".codex");
49075
+ return configuredHome ?? (0, import_node_path32.join)(home, ".codex");
48578
49076
  }
48579
49077
  function githubProxyConfig(env, home) {
48580
- const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path29.join)(home, ".config");
49078
+ const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path32.join)(home, ".config");
48581
49079
  return {
48582
49080
  githubProxy: env.ALAN_RUNTIME_GITHUB_PROXY === "on",
48583
- ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path29.join)(configHome, "gh")
49081
+ ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path32.join)(configHome, "gh")
48584
49082
  };
48585
49083
  }
48586
49084
  function serviceEnvironment(env, profile) {
@@ -48679,7 +49177,7 @@ async function loadStoredAccess(paths, access3 = { exec: systemExec }) {
48679
49177
  }
48680
49178
 
48681
49179
  // src/cli/commands/hold.ts
48682
- var import_node_path30 = require("path");
49180
+ var import_node_path33 = require("path");
48683
49181
  init_agent2();
48684
49182
  init_runtime_v2();
48685
49183
  async function machineAccess(paths, log, conversationId, transport) {
@@ -48737,7 +49235,7 @@ async function runHold(argv) {
48737
49235
  const config2 = loadRuntimeConfig();
48738
49236
  const paths = runtimePaths(config2.stateDir);
48739
49237
  const log = __using(_stack, openFileLog(
48740
- (0, import_node_path30.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
49238
+ (0, import_node_path33.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
48741
49239
  config2.logLevel,
48742
49240
  systemClock
48743
49241
  ));
@@ -48748,7 +49246,7 @@ async function runHold(argv) {
48748
49246
  );
48749
49247
  const transport = __using(_stack, createHttpTransport());
48750
49248
  const access3 = await machineAccess(paths, log, launch.value.conversationId, transport);
48751
- const credentialPath = (0, import_node_path30.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
49249
+ const credentialPath = (0, import_node_path33.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
48752
49250
  const managedMcp = __using(_stack, access3.managedMcp === void 0 ? void 0 : createHelperMcpAccess({
48753
49251
  managedMcp: access3.managedMcp,
48754
49252
  conversationId: launch.value.conversationId,