@alan-ai-hq/agent-manager 0.1.123 → 0.1.124

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 (2) hide show
  1. package/dist/index.cjs +1028 -653
  2. package/package.json +3 -3
package/dist/index.cjs CHANGED
@@ -14312,7 +14312,7 @@ var require_extract = __commonJS({
14312
14312
  var require_constants2 = __commonJS({
14313
14313
  "../../node_modules/tar-stream/constants.js"(exports2, module2) {
14314
14314
  "use strict";
14315
- var constants5 = {
14315
+ var constants6 = {
14316
14316
  // just for envs without fs
14317
14317
  S_IFMT: 61440,
14318
14318
  S_IFDIR: 16384,
@@ -14322,9 +14322,9 @@ var require_constants2 = __commonJS({
14322
14322
  S_IFLNK: 40960
14323
14323
  };
14324
14324
  try {
14325
- module2.exports = require("fs").constants || constants5;
14325
+ module2.exports = require("fs").constants || constants6;
14326
14326
  } catch {
14327
- module2.exports = constants5;
14327
+ module2.exports = constants6;
14328
14328
  }
14329
14329
  }
14330
14330
  });
@@ -14335,7 +14335,7 @@ var require_pack = __commonJS({
14335
14335
  "use strict";
14336
14336
  var { Readable: Readable2, Writable, getStreamError } = require_streamx();
14337
14337
  var b4a = require_b4a();
14338
- var constants5 = require_constants2();
14338
+ var constants6 = require_constants2();
14339
14339
  var headers = require_headers();
14340
14340
  var DMODE = 493;
14341
14341
  var FMODE = 420;
@@ -14538,16 +14538,16 @@ var require_pack = __commonJS({
14538
14538
  return new Pack(opts);
14539
14539
  };
14540
14540
  function modeToType(mode) {
14541
- switch (mode & constants5.S_IFMT) {
14542
- case constants5.S_IFBLK:
14541
+ switch (mode & constants6.S_IFMT) {
14542
+ case constants6.S_IFBLK:
14543
14543
  return "block-device";
14544
- case constants5.S_IFCHR:
14544
+ case constants6.S_IFCHR:
14545
14545
  return "character-device";
14546
- case constants5.S_IFDIR:
14546
+ case constants6.S_IFDIR:
14547
14547
  return "directory";
14548
- case constants5.S_IFIFO:
14548
+ case constants6.S_IFIFO:
14549
14549
  return "fifo";
14550
- case constants5.S_IFLNK:
14550
+ case constants6.S_IFLNK:
14551
14551
  return "symlink";
14552
14552
  }
14553
14553
  return "file";
@@ -14643,12 +14643,12 @@ function resolveCommand(args, env) {
14643
14643
  // src/cli/hook.ts
14644
14644
  var import_node_fs9 = require("fs");
14645
14645
  var import_node_http = require("http");
14646
- var import_node_path10 = require("path");
14646
+ var import_node_path12 = require("path");
14647
14647
 
14648
14648
  // src/daemon/control.ts
14649
- var import_node_crypto = require("crypto");
14649
+ var import_node_crypto2 = require("crypto");
14650
14650
  var import_node_fs8 = require("fs");
14651
- var import_node_path7 = require("path");
14651
+ var import_node_path9 = require("path");
14652
14652
 
14653
14653
  // src/runtime-config.ts
14654
14654
  var import_node_fs = require("fs");
@@ -33437,9 +33437,9 @@ var transcriptSyncPendingRunSchema = external_exports.object({
33437
33437
  problemPermanent: external_exports.boolean().optional()
33438
33438
  });
33439
33439
  var RUNNER_CAPACITY_SOURCES = ["default", "config", "provider_limit"];
33440
- var DEFAULT_MAX_ACTIVE_RUNS = 4;
33441
33440
  var MIN_MAX_ACTIVE_RUNS = 1;
33442
33441
  var MAX_MAX_ACTIVE_RUNS = 32;
33442
+ var DEFAULT_MAX_ACTIVE_RUNS = MAX_MAX_ACTIVE_RUNS;
33443
33443
  var runnerCapacitySourceSchema = external_exports.enum(RUNNER_CAPACITY_SOURCES);
33444
33444
  var runtimeRunnerStatusSchema = external_exports.object({
33445
33445
  daemonSessionId: external_exports.uuid(),
@@ -33707,14 +33707,153 @@ function bindAgentConfigPathFromArgs(args) {
33707
33707
 
33708
33708
  // src/daemon/status.ts
33709
33709
  var import_node_fs7 = require("fs");
33710
- var import_node_os5 = require("os");
33711
- var import_node_path6 = require("path");
33710
+ var import_node_os6 = require("os");
33711
+ var import_node_path8 = require("path");
33712
33712
 
33713
33713
  // ../shared/dist/node/provider-limits.js
33714
33714
  var import_node_child_process = require("child_process");
33715
- var import_node_fs2 = require("fs");
33715
+ var import_node_fs3 = require("fs");
33716
+ var import_node_os3 = require("os");
33717
+ var import_node_path4 = require("path");
33718
+
33719
+ // ../shared/dist/node/shell-path.js
33716
33720
  var import_node_os2 = require("os");
33721
+ var import_node_path3 = require("path");
33722
+
33723
+ // ../shared/dist/node/version-manager-paths.js
33724
+ var import_node_fs2 = require("fs");
33717
33725
  var import_node_path2 = require("path");
33726
+ function compareNodeVersionsDesc(a, b) {
33727
+ const parse8 = (value2) => value2.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10) || 0);
33728
+ const left = parse8(a);
33729
+ const right = parse8(b);
33730
+ for (let i = 0; i < 3; i += 1) {
33731
+ const diff = (right[i] ?? 0) - (left[i] ?? 0);
33732
+ if (diff !== 0)
33733
+ return diff;
33734
+ }
33735
+ return 0;
33736
+ }
33737
+ function resolveNvmDefaultBin(home) {
33738
+ const versionsDir = (0, import_node_path2.join)(home, ".nvm", "versions", "node");
33739
+ if (!(0, import_node_fs2.existsSync)(versionsDir))
33740
+ return null;
33741
+ let alias = null;
33742
+ try {
33743
+ const aliasFile = (0, import_node_path2.join)(home, ".nvm", "alias", "default");
33744
+ if ((0, import_node_fs2.existsSync)(aliasFile))
33745
+ alias = (0, import_node_fs2.readFileSync)(aliasFile, "utf8").trim();
33746
+ } catch {
33747
+ alias = null;
33748
+ }
33749
+ let installed;
33750
+ try {
33751
+ installed = (0, import_node_fs2.readdirSync)(versionsDir).filter((entry) => entry.startsWith("v"));
33752
+ } catch {
33753
+ return null;
33754
+ }
33755
+ if (installed.length === 0)
33756
+ return null;
33757
+ const matching = alias ? installed.filter((entry) => entry === alias || entry === `v${alias}` || entry.startsWith(`v${alias}.`)) : [];
33758
+ const chosen = (matching.length > 0 ? matching : installed).sort(compareNodeVersionsDesc)[0];
33759
+ if (!chosen)
33760
+ return null;
33761
+ const bin = (0, import_node_path2.join)(versionsDir, chosen, "bin");
33762
+ return (0, import_node_fs2.existsSync)(bin) ? bin : null;
33763
+ }
33764
+ function resolveVersionManagerBinDirs(home, platform7 = process.platform) {
33765
+ if (platform7 === "win32")
33766
+ return [];
33767
+ const candidates = [
33768
+ resolveNvmDefaultBin(home),
33769
+ (0, import_node_path2.join)(home, ".volta", "bin"),
33770
+ (0, import_node_path2.join)(home, ".fnm", "aliases", "default", "bin"),
33771
+ (0, import_node_path2.join)(home, "Library", "Application Support", "fnm", "aliases", "default", "bin"),
33772
+ (0, import_node_path2.join)(home, ".asdf", "shims"),
33773
+ (0, import_node_path2.join)(home, ".local", "share", "mise", "shims")
33774
+ ];
33775
+ const seen = /* @__PURE__ */ new Set();
33776
+ const resolved = [];
33777
+ for (const dir of candidates) {
33778
+ if (!dir || seen.has(dir))
33779
+ continue;
33780
+ seen.add(dir);
33781
+ if ((0, import_node_fs2.existsSync)(dir))
33782
+ resolved.push(dir);
33783
+ }
33784
+ return resolved;
33785
+ }
33786
+
33787
+ // ../shared/dist/node/shell-path.js
33788
+ function splitPath(value2) {
33789
+ const separator = (0, import_node_os2.platform)() === "win32" ? ";" : ":";
33790
+ return (value2 ?? "").split(separator).filter(Boolean);
33791
+ }
33792
+ function joinPath(segments) {
33793
+ return segments.join((0, import_node_os2.platform)() === "win32" ? ";" : ":");
33794
+ }
33795
+ function dedupePath(value2) {
33796
+ const seen = /* @__PURE__ */ new Set();
33797
+ const kept2 = [];
33798
+ for (const dir of splitPath(value2)) {
33799
+ if (seen.has(dir))
33800
+ continue;
33801
+ seen.add(dir);
33802
+ kept2.push(dir);
33803
+ }
33804
+ return joinPath(kept2);
33805
+ }
33806
+ function promoteAheadOfVersionManagers(path2, promoted, versionManagerDirs) {
33807
+ const managed = new Set(versionManagerDirs);
33808
+ const firstManaged = path2.findIndex((dir) => managed.has(dir));
33809
+ if (firstManaged === -1)
33810
+ return path2;
33811
+ const before = path2.slice(0, firstManaged);
33812
+ const tail = path2.slice(firstManaged);
33813
+ const moved = tail.filter((dir) => promoted.has(dir));
33814
+ if (moved.length === 0)
33815
+ return path2;
33816
+ return [...before, ...moved, ...tail.filter((dir) => !promoted.has(dir))];
33817
+ }
33818
+ function promotedUserBinDirs(home) {
33819
+ return /* @__PURE__ */ new Set([
33820
+ (0, import_node_path3.join)(home, ".local", "bin"),
33821
+ (0, import_node_path3.join)(home, ".bun", "bin"),
33822
+ (0, import_node_path3.join)(home, ".cargo", "bin")
33823
+ ]);
33824
+ }
33825
+ function augmentCliPath(env, includeSystemPaths = true) {
33826
+ const source2 = {};
33827
+ for (const [key, value2] of Object.entries(env)) {
33828
+ if (value2 !== void 0)
33829
+ source2[key] = value2;
33830
+ }
33831
+ const home = source2.HOME || source2.USERPROFILE || (0, import_node_os2.homedir)();
33832
+ const isWin = (0, import_node_os2.platform)() === "win32";
33833
+ const windowsLocalAppData = source2.LOCALAPPDATA || (0, import_node_path3.join)(home, "AppData", "Local");
33834
+ const versionManagerDirs = isWin ? [] : resolveVersionManagerBinDirs(home);
33835
+ const userPaths = isWin ? [
33836
+ (0, import_node_path3.join)(home, "AppData", "Roaming", "npm"),
33837
+ (0, import_node_path3.join)(windowsLocalAppData, "Programs", "OpenAI", "Codex", "bin"),
33838
+ (0, import_node_path3.join)(windowsLocalAppData, "Programs", "Microsoft", "WindowsApps"),
33839
+ (0, import_node_path3.join)(home, ".local", "bin")
33840
+ ] : [
33841
+ (0, import_node_path3.join)(home, ".local", "bin"),
33842
+ (0, import_node_path3.join)(home, ".local", "node", "bin"),
33843
+ (0, import_node_path3.join)(home, ".bun", "bin"),
33844
+ (0, import_node_path3.join)(home, ".cargo", "bin"),
33845
+ ...versionManagerDirs
33846
+ ];
33847
+ const systemPaths = isWin ? ["C:\\Program Files\\nodejs", "C:\\Program Files\\Git\\cmd"] : ["/opt/homebrew/bin", "/usr/local/bin"];
33848
+ const extraPaths = includeSystemPaths ? [...userPaths, ...systemPaths] : userPaths;
33849
+ const existing = new Set(splitPath(source2.PATH));
33850
+ const missing = extraPaths.filter((dir) => !existing.has(dir));
33851
+ const combined = [...missing, ...splitPath(source2.PATH)];
33852
+ const ordered = isWin ? combined : promoteAheadOfVersionManagers(combined, promotedUserBinDirs(home), versionManagerDirs);
33853
+ return { ...source2, PATH: dedupePath(joinPath(ordered)) };
33854
+ }
33855
+
33856
+ // ../shared/dist/node/provider-limits.js
33718
33857
  var CACHE_TTL_MS = 6e4;
33719
33858
  var cachedLimits = null;
33720
33859
  function numericValue(value2) {
@@ -33725,42 +33864,23 @@ function numericValue(value2) {
33725
33864
  }
33726
33865
  return null;
33727
33866
  }
33728
- function splitPath(value2) {
33729
- return (value2 ?? "").split(import_node_path2.delimiter).filter(Boolean);
33867
+ function splitPath2(value2) {
33868
+ return (value2 ?? "").split(import_node_path4.delimiter).filter(Boolean);
33730
33869
  }
33731
33870
  function isExecutableFile(path2) {
33732
33871
  try {
33733
- (0, import_node_fs2.accessSync)(path2, import_node_fs2.constants.X_OK);
33872
+ (0, import_node_fs3.accessSync)(path2, import_node_fs3.constants.X_OK);
33734
33873
  return true;
33735
33874
  } catch {
33736
33875
  return false;
33737
33876
  }
33738
33877
  }
33739
- function augmentCliPath(env) {
33740
- const home = env.HOME || (0, import_node_os2.homedir)();
33741
- const extraPaths = [
33742
- (0, import_node_path2.join)(home, ".local", "bin"),
33743
- (0, import_node_path2.join)(home, ".local", "node", "bin"),
33744
- (0, import_node_path2.join)(home, ".bun", "bin"),
33745
- (0, import_node_path2.join)(home, ".cargo", "bin"),
33746
- "/opt/homebrew/bin",
33747
- "/usr/local/bin"
33748
- ];
33749
- const existing = new Set(splitPath(env.PATH));
33750
- const missing = extraPaths.filter((path2) => !existing.has(path2));
33751
- if (missing.length === 0)
33752
- return env;
33753
- return {
33754
- ...env,
33755
- PATH: `${missing.join(import_node_path2.delimiter)}${import_node_path2.delimiter}${env.PATH ?? ""}`
33756
- };
33757
- }
33758
33878
  function resolveExecutable(command, env, overrideEnvVar) {
33759
33879
  const override = env[overrideEnvVar]?.trim();
33760
33880
  if (override && isExecutableFile(override))
33761
33881
  return override;
33762
- for (const dir of splitPath(env.PATH)) {
33763
- const candidate = (0, import_node_path2.join)(dir, command);
33882
+ for (const dir of splitPath2(env.PATH)) {
33883
+ const candidate = (0, import_node_path4.join)(dir, command);
33764
33884
  if (isExecutableFile(candidate))
33765
33885
  return candidate;
33766
33886
  }
@@ -33904,10 +34024,10 @@ async function collectCodexLimits(env) {
33904
34024
  }), 4e3, []);
33905
34025
  }
33906
34026
  function readClaudeCredentialsPayload() {
33907
- const path2 = (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".claude", ".credentials.json");
33908
- if ((0, import_node_fs2.existsSync)(path2)) {
34027
+ const path2 = (0, import_node_path4.join)((0, import_node_os3.homedir)(), ".claude", ".credentials.json");
34028
+ if ((0, import_node_fs3.existsSync)(path2)) {
33909
34029
  try {
33910
- return JSON.parse((0, import_node_fs2.readFileSync)(path2, "utf8"));
34030
+ return JSON.parse((0, import_node_fs3.readFileSync)(path2, "utf8"));
33911
34031
  } catch {
33912
34032
  return null;
33913
34033
  }
@@ -34043,11 +34163,11 @@ async function collectAntigravityLimits(env) {
34043
34163
  var CURSOR_USAGE_URL = "https://api2.cursor.sh/aiserver.v1.DashboardService/GetCurrentPeriodUsage";
34044
34164
  function cursorAuthFilePath(platform7, env, home) {
34045
34165
  if (platform7 === "win32") {
34046
- return (0, import_node_path2.join)(env.APPDATA || (0, import_node_path2.join)(home, "AppData", "Roaming"), "Cursor", "auth.json");
34166
+ return (0, import_node_path4.join)(env.APPDATA || (0, import_node_path4.join)(home, "AppData", "Roaming"), "Cursor", "auth.json");
34047
34167
  }
34048
34168
  if (platform7 === "darwin")
34049
- return (0, import_node_path2.join)(home, ".cursor", "auth.json");
34050
- return (0, import_node_path2.join)(env.XDG_CONFIG_HOME || (0, import_node_path2.join)(home, ".config"), "cursor", "auth.json");
34169
+ return (0, import_node_path4.join)(home, ".cursor", "auth.json");
34170
+ return (0, import_node_path4.join)(env.XDG_CONFIG_HOME || (0, import_node_path4.join)(home, ".config"), "cursor", "auth.json");
34051
34171
  }
34052
34172
  function readCursorKeychainToken() {
34053
34173
  if (process.platform !== "darwin")
@@ -34061,8 +34181,8 @@ function readCursorKeychainToken() {
34061
34181
  }
34062
34182
  function readCursorAuthFileToken() {
34063
34183
  try {
34064
- const path2 = cursorAuthFilePath(process.platform, process.env, (0, import_node_os2.homedir)());
34065
- const parsed = JSON.parse((0, import_node_fs2.readFileSync)(path2, "utf8"));
34184
+ const path2 = cursorAuthFilePath(process.platform, process.env, (0, import_node_os3.homedir)());
34185
+ const parsed = JSON.parse((0, import_node_fs3.readFileSync)(path2, "utf8"));
34066
34186
  return typeof parsed.accessToken === "string" && parsed.accessToken.trim() ? parsed.accessToken.trim() : null;
34067
34187
  } catch {
34068
34188
  return null;
@@ -34168,8 +34288,8 @@ async function collectLocalAgentProviderLimits(env = process.env) {
34168
34288
  var import_node_child_process3 = require("child_process");
34169
34289
  var import_node_fs5 = require("fs");
34170
34290
  var import_node_module = require("module");
34171
- var import_node_os4 = require("os");
34172
- var import_node_path5 = require("path");
34291
+ var import_node_os5 = require("os");
34292
+ var import_node_path7 = require("path");
34173
34293
 
34174
34294
  // ../sandbox-runtime-spec/dist/index.js
34175
34295
  function quote(value2) {
@@ -34569,141 +34689,208 @@ function canRepairSandboxRuntime(runtime, platform7, sandboxProvider) {
34569
34689
  }
34570
34690
 
34571
34691
  // src/shell-environment.ts
34692
+ var import_node_path6 = require("path");
34693
+
34694
+ // ../shared/dist/node/shell-environment.js
34572
34695
  var import_node_child_process2 = require("child_process");
34696
+ var import_node_crypto = require("crypto");
34573
34697
  var import_node_fs4 = require("fs");
34574
- var import_node_os3 = require("os");
34575
- var import_node_path4 = require("path");
34576
-
34577
- // src/version-manager-paths.ts
34578
- var import_node_fs3 = require("fs");
34579
- var import_node_path3 = require("path");
34580
- function compareNodeVersionsDesc(a, b) {
34581
- const parse8 = (value2) => value2.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10) || 0);
34582
- const left = parse8(a);
34583
- const right = parse8(b);
34584
- for (let i = 0; i < 3; i += 1) {
34585
- const diff = (right[i] ?? 0) - (left[i] ?? 0);
34586
- if (diff !== 0) return diff;
34587
- }
34588
- return 0;
34698
+ var import_node_os4 = require("os");
34699
+ var import_node_path5 = require("path");
34700
+ var PROBE_TIMEOUT_MS = 2e4;
34701
+ var DEGRADED_RETRY_BACKOFF_MS = 3e4;
34702
+ var SNAPSHOT_FILE_VERSION = 1;
34703
+ var SELF_GUARD_ENV = "ALAN_RESOLVING_ENVIRONMENT";
34704
+ var config2 = { snapshotFile: null, timeoutMs: PROBE_TIMEOUT_MS };
34705
+ var cachedState = null;
34706
+ var nextRetryAtMs = 0;
34707
+ var lastProbeError = null;
34708
+ function configureShellEnvironment(next) {
34709
+ if (next.snapshotFile !== void 0)
34710
+ config2.snapshotFile = next.snapshotFile;
34711
+ if (next.timeoutMs !== void 0)
34712
+ config2.timeoutMs = next.timeoutMs;
34589
34713
  }
34590
- function resolveNvmDefaultBin(home) {
34591
- const versionsDir = (0, import_node_path3.join)(home, ".nvm", "versions", "node");
34592
- if (!(0, import_node_fs3.existsSync)(versionsDir)) return null;
34593
- let alias = null;
34714
+ function isExecutableFile2(path2) {
34594
34715
  try {
34595
- const aliasFile = (0, import_node_path3.join)(home, ".nvm", "alias", "default");
34596
- if ((0, import_node_fs3.existsSync)(aliasFile)) alias = (0, import_node_fs3.readFileSync)(aliasFile, "utf8").trim();
34716
+ (0, import_node_fs4.accessSync)(path2, import_node_fs4.constants.X_OK);
34717
+ return true;
34597
34718
  } catch {
34598
- alias = null;
34719
+ return false;
34599
34720
  }
34600
- let installed;
34721
+ }
34722
+ function resolveLoginShell(env = process.env) {
34723
+ if ((0, import_node_os4.platform)() === "win32")
34724
+ return null;
34725
+ const explicit = env.SHELL?.trim();
34726
+ if (explicit && (0, import_node_path5.isAbsolute)(explicit) && isExecutableFile2(explicit))
34727
+ return explicit;
34601
34728
  try {
34602
- installed = (0, import_node_fs3.readdirSync)(versionsDir).filter((entry) => entry.startsWith("v"));
34729
+ const accountShell = (0, import_node_os4.userInfo)().shell?.trim();
34730
+ if (accountShell && (0, import_node_path5.isAbsolute)(accountShell) && isExecutableFile2(accountShell)) {
34731
+ return accountShell;
34732
+ }
34603
34733
  } catch {
34604
- return null;
34605
34734
  }
34606
- if (installed.length === 0) return null;
34607
- const matching = alias ? installed.filter(
34608
- (entry) => entry === alias || entry === `v${alias}` || entry.startsWith(`v${alias}.`)
34609
- ) : [];
34610
- const chosen = (matching.length > 0 ? matching : installed).sort(compareNodeVersionsDesc)[0];
34611
- if (!chosen) return null;
34612
- const bin = (0, import_node_path3.join)(versionsDir, chosen, "bin");
34613
- return (0, import_node_fs3.existsSync)(bin) ? bin : null;
34735
+ const fallback = (0, import_node_os4.platform)() === "darwin" ? "/bin/zsh" : "/bin/bash";
34736
+ return isExecutableFile2(fallback) ? fallback : null;
34614
34737
  }
34615
- function resolveVersionManagerBinDirs(home, platform7 = process.platform) {
34616
- if (platform7 === "win32") return [];
34617
- const candidates = [
34618
- resolveNvmDefaultBin(home),
34619
- (0, import_node_path3.join)(home, ".volta", "bin"),
34620
- (0, import_node_path3.join)(home, ".fnm", "aliases", "default", "bin"),
34621
- (0, import_node_path3.join)(home, "Library", "Application Support", "fnm", "aliases", "default", "bin"),
34622
- (0, import_node_path3.join)(home, ".asdf", "shims"),
34623
- (0, import_node_path3.join)(home, ".local", "share", "mise", "shims")
34624
- ];
34625
- const seen = /* @__PURE__ */ new Set();
34626
- const resolved = [];
34627
- for (const dir of candidates) {
34628
- if (!dir || seen.has(dir)) continue;
34629
- seen.add(dir);
34630
- if ((0, import_node_fs3.existsSync)(dir)) resolved.push(dir);
34738
+ function buildProbeEnvironment() {
34739
+ const env = {};
34740
+ for (const [key, value2] of Object.entries(process.env)) {
34741
+ if (value2 !== void 0)
34742
+ env[key] = value2;
34743
+ }
34744
+ if (!env.HOME || !(0, import_node_fs4.existsSync)(env.HOME))
34745
+ env.HOME = (0, import_node_os4.homedir)();
34746
+ env[SELF_GUARD_ENV] = "1";
34747
+ if (process.versions.electron)
34748
+ env.ELECTRON_RUN_AS_NODE = "1";
34749
+ return env;
34750
+ }
34751
+ function escapeForSingleQuotes(value2) {
34752
+ return value2.replace(/'/g, "'\\''");
34753
+ }
34754
+ function buildProbeCommand(execPath, mark) {
34755
+ return `'${escapeForSingleQuotes(execPath)}' -p '"${mark}" + JSON.stringify(process.env) + "${mark}"'`;
34756
+ }
34757
+ function extractProbePayload(stdout, mark) {
34758
+ const first = stdout.indexOf(mark);
34759
+ if (first === -1)
34760
+ return null;
34761
+ const second = stdout.indexOf(mark, first + mark.length);
34762
+ if (second === -1)
34763
+ return null;
34764
+ try {
34765
+ const parsed = JSON.parse(stdout.slice(first + mark.length, second).trim());
34766
+ if (!parsed || typeof parsed !== "object")
34767
+ return null;
34768
+ const env = {};
34769
+ for (const [key, value2] of Object.entries(parsed)) {
34770
+ if (typeof value2 === "string")
34771
+ env[key] = value2;
34772
+ }
34773
+ return env;
34774
+ } catch {
34775
+ return null;
34631
34776
  }
34632
- return resolved;
34633
34777
  }
34634
-
34635
- // src/shell-environment.ts
34636
- var LOGIN_SHELL_PROBE_TIMEOUT_MS = 2e4;
34637
- var DEGRADED_RETRY_BACKOFF_MS = 3e4;
34638
- var SHELL_PATH_SNAPSHOT_FILE = "shell-path.json";
34639
- var SHELL_PATH_SNAPSHOT_VERSION = 1;
34640
- var cachedState = null;
34641
- var nextRetryAtMs = 0;
34642
- var lastProbeError = null;
34643
- function parseEnvOutput(output2) {
34644
- const loginEnv = {};
34778
+ function parseShellEnvLines(output2) {
34779
+ const env = {};
34645
34780
  for (const line of output2.split("\n")) {
34646
- if (!line.trim()) continue;
34781
+ if (!line.trim())
34782
+ continue;
34647
34783
  const eqIdx = line.indexOf("=");
34648
- if (eqIdx <= 0) continue;
34784
+ if (eqIdx <= 0)
34785
+ continue;
34649
34786
  const key = line.slice(0, eqIdx);
34650
- if (/\s/.test(key)) continue;
34651
- loginEnv[key] = line.slice(eqIdx + 1);
34787
+ if (/\s/.test(key) || key.endsWith("%%"))
34788
+ continue;
34789
+ env[key] = line.slice(eqIdx + 1);
34790
+ }
34791
+ return env;
34792
+ }
34793
+ function newMark() {
34794
+ return (0, import_node_crypto.randomUUID)().replace(/-/g, "").slice(0, 12);
34795
+ }
34796
+ function isTimeout(error61) {
34797
+ if (!error61 || typeof error61 !== "object")
34798
+ return false;
34799
+ const candidate = error61;
34800
+ return candidate.killed === true || candidate.signal === "SIGTERM" || candidate.code === "ETIMEDOUT";
34801
+ }
34802
+ function isUsableProbe(env) {
34803
+ return env !== null && Boolean(env.PATH?.trim());
34804
+ }
34805
+ function probeArgs(shell, execPath, mark) {
34806
+ const name = (0, import_node_path5.basename)(shell);
34807
+ if (name === "csh" || name === "tcsh") {
34808
+ return ["-ic", buildProbeCommand(execPath, mark)];
34652
34809
  }
34653
- if (!loginEnv.HOME) loginEnv.HOME = process.env.HOME ?? (0, import_node_os3.homedir)();
34654
- if (!loginEnv.SHELL) loginEnv.SHELL = process.env.SHELL ?? "/bin/zsh";
34655
- return loginEnv;
34810
+ return ["-i", "-l", "-c", buildProbeCommand(execPath, mark)];
34656
34811
  }
34657
- function probeLoginShell() {
34658
- const shell = process.env.SHELL || "/bin/bash";
34812
+ function probeLoginShellBlocking() {
34813
+ const shell = resolveLoginShell();
34814
+ if (!shell) {
34815
+ lastProbeError = "no executable login shell found";
34816
+ return null;
34817
+ }
34818
+ const env = buildProbeEnvironment();
34819
+ const mark = newMark();
34659
34820
  try {
34660
- const envOutput = (0, import_node_child_process2.execFileSync)(shell, ["-lc", "env"], {
34821
+ const stdout = (0, import_node_child_process2.execFileSync)(shell, probeArgs(shell, process.execPath, mark), {
34822
+ env,
34823
+ timeout: config2.timeoutMs,
34661
34824
  encoding: "utf8",
34662
- stdio: ["pipe", "pipe", "pipe"],
34663
- timeout: LOGIN_SHELL_PROBE_TIMEOUT_MS
34825
+ stdio: ["ignore", "pipe", "pipe"],
34826
+ maxBuffer: 8 * 1024 * 1024
34664
34827
  });
34665
- const parsed = parseEnvOutput(envOutput);
34666
- if (!parsed.PATH?.trim()) {
34667
- lastProbeError = "login shell returned no PATH";
34828
+ const payload = extractProbePayload(stdout, mark);
34829
+ if (isUsableProbe(payload))
34830
+ return payload;
34831
+ lastProbeError = "interactive probe returned no PATH";
34832
+ } catch (error61) {
34833
+ if (isTimeout(error61)) {
34834
+ lastProbeError = "interactive probe timed out";
34668
34835
  return null;
34669
34836
  }
34670
- lastProbeError = null;
34671
- return parsed;
34837
+ lastProbeError = error61 instanceof Error ? error61.message : String(error61);
34838
+ }
34839
+ try {
34840
+ const stdout = (0, import_node_child_process2.execFileSync)(shell, ["-lc", "env"], {
34841
+ env,
34842
+ timeout: config2.timeoutMs,
34843
+ encoding: "utf8",
34844
+ stdio: ["ignore", "pipe", "pipe"],
34845
+ maxBuffer: 8 * 1024 * 1024
34846
+ });
34847
+ const parsed = parseShellEnvLines(stdout);
34848
+ if (isUsableProbe(parsed))
34849
+ return parsed;
34850
+ lastProbeError = "login shell returned no PATH";
34672
34851
  } catch (error61) {
34673
34852
  lastProbeError = error61 instanceof Error ? error61.message : String(error61);
34674
- return null;
34675
34853
  }
34854
+ return null;
34676
34855
  }
34677
- function shellPathSnapshotFile() {
34678
- const explicit = process.env.ALAN_AGENT_CONFIG_PATH?.trim();
34679
- const dir = explicit ? (0, import_node_path4.dirname)(explicit) : resolveAgentConfigDirectory();
34680
- return (0, import_node_path4.join)(dir, SHELL_PATH_SNAPSHOT_FILE);
34856
+ function normalizeHydratedEnv(env) {
34857
+ const normalized2 = augmentCliPath(env);
34858
+ if (!normalized2.HOME)
34859
+ normalized2.HOME = (0, import_node_os4.homedir)();
34860
+ if (!normalized2.SHELL)
34861
+ normalized2.SHELL = resolveLoginShell() ?? "";
34862
+ return normalized2;
34863
+ }
34864
+ function snapshotFile() {
34865
+ const configured = config2.snapshotFile;
34866
+ if (!configured)
34867
+ return null;
34868
+ return typeof configured === "function" ? configured() ?? null : configured;
34681
34869
  }
34682
34870
  function persistLastKnownGoodPath(path2) {
34871
+ const file2 = snapshotFile();
34872
+ if (!file2)
34873
+ return;
34683
34874
  try {
34684
- const file2 = shellPathSnapshotFile();
34685
- (0, import_node_fs4.mkdirSync)((0, import_node_path4.dirname)(file2), { recursive: true });
34686
- (0, import_node_fs4.writeFileSync)(
34687
- file2,
34688
- `${JSON.stringify(
34689
- { version: SHELL_PATH_SNAPSHOT_VERSION, path: path2, capturedAt: (/* @__PURE__ */ new Date()).toISOString() },
34690
- null,
34691
- 2
34692
- )}
34693
- `,
34694
- { mode: 384 }
34695
- );
34875
+ (0, import_node_fs4.mkdirSync)((0, import_node_path5.dirname)(file2), { recursive: true });
34876
+ (0, import_node_fs4.writeFileSync)(file2, `${JSON.stringify({ version: SNAPSHOT_FILE_VERSION, path: path2, capturedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)}
34877
+ `, { mode: 384 });
34696
34878
  } catch {
34697
34879
  }
34698
34880
  }
34699
34881
  function readLastKnownGoodPath() {
34882
+ const file2 = snapshotFile();
34883
+ if (!file2)
34884
+ return null;
34700
34885
  try {
34701
- const file2 = shellPathSnapshotFile();
34702
- if (!(0, import_node_fs4.existsSync)(file2)) return null;
34886
+ if (!(0, import_node_fs4.existsSync)(file2))
34887
+ return null;
34703
34888
  const parsed = JSON.parse((0, import_node_fs4.readFileSync)(file2, "utf8"));
34704
- if (!parsed || typeof parsed !== "object") return null;
34889
+ if (!parsed || typeof parsed !== "object")
34890
+ return null;
34705
34891
  const record4 = parsed;
34706
- if (record4.version !== SHELL_PATH_SNAPSHOT_VERSION) return null;
34892
+ if (record4.version !== SNAPSHOT_FILE_VERSION)
34893
+ return null;
34707
34894
  return typeof record4.path === "string" && record4.path.trim() ? record4.path : null;
34708
34895
  } catch {
34709
34896
  return null;
@@ -34712,38 +34899,60 @@ function readLastKnownGoodPath() {
34712
34899
  function buildDegradedState() {
34713
34900
  const base = { ...process.env };
34714
34901
  const lastKnownGood = readLastKnownGoodPath();
34715
- if (!lastKnownGood) return { env: base, source: "process_env" };
34716
- const existing = new Set(splitPath2(base.PATH ?? ""));
34717
- const restored = splitPath2(lastKnownGood).filter((dir) => !existing.has(dir));
34718
- if (restored.length === 0) return { env: base, source: "process_env" };
34719
- return {
34720
- env: { ...base, PATH: [...restored, ...splitPath2(base.PATH ?? "")].join(":") },
34721
- source: "last_known_good_path"
34722
- };
34902
+ if (lastKnownGood) {
34903
+ const existing = new Set(splitPath(base.PATH));
34904
+ const restored = splitPath(lastKnownGood).filter((dir) => !existing.has(dir));
34905
+ if (restored.length > 0) {
34906
+ return {
34907
+ env: { ...base, PATH: dedupePath(joinPath2([...restored, ...splitPath(base.PATH)])) },
34908
+ source: "last_known_good_path"
34909
+ };
34910
+ }
34911
+ }
34912
+ return { env: normalizeHydratedEnv(base), source: "process_env" };
34723
34913
  }
34724
- function splitPath2(value2) {
34725
- const separator = (0, import_node_os3.platform)() === "win32" ? ";" : ":";
34726
- return value2.split(separator).filter(Boolean);
34914
+ function joinPath2(segments) {
34915
+ return segments.join((0, import_node_os4.platform)() === "win32" ? ";" : ":");
34727
34916
  }
34728
- function loadLoginShellEnvironment() {
34729
- if ((0, import_node_os3.platform)() === "win32") {
34917
+ function acceptProbedEnv(probed) {
34918
+ const env = normalizeHydratedEnv(probed);
34919
+ nextRetryAtMs = 0;
34920
+ persistLastKnownGoodPath(env.PATH ?? "");
34921
+ return { env, source: "login_shell" };
34922
+ }
34923
+ function degrade() {
34924
+ if (!lastProbeError)
34925
+ lastProbeError = "login shell probe failed";
34926
+ nextRetryAtMs = Date.now() + DEGRADED_RETRY_BACKOFF_MS;
34927
+ return buildDegradedState();
34928
+ }
34929
+ function loadShellEnvironmentSync() {
34930
+ if ((0, import_node_os4.platform)() === "win32") {
34730
34931
  cachedState ??= { env: process.env, source: "process_env" };
34731
34932
  return cachedState.env;
34732
34933
  }
34733
- if (cachedState?.source === "login_shell") return cachedState.env;
34734
- if (cachedState && Date.now() < nextRetryAtMs) return cachedState.env;
34735
- const probed = probeLoginShell();
34736
- if (probed) {
34737
- cachedState = { env: probed, source: "login_shell" };
34738
- nextRetryAtMs = 0;
34739
- persistLastKnownGoodPath(probed.PATH ?? "");
34740
- return probed;
34741
- }
34742
- nextRetryAtMs = Date.now() + DEGRADED_RETRY_BACKOFF_MS;
34743
- cachedState = buildDegradedState();
34934
+ if (cachedState?.source === "login_shell")
34935
+ return cachedState.env;
34936
+ if (cachedState && Date.now() < nextRetryAtMs)
34937
+ return cachedState.env;
34938
+ const probed = probeLoginShellBlocking();
34939
+ cachedState = isUsableProbe(probed) ? acceptProbedEnv(probed) : degrade();
34744
34940
  return cachedState.env;
34745
34941
  }
34746
34942
 
34943
+ // src/shell-environment.ts
34944
+ var SNAPSHOT_FILE = "shell-path.json";
34945
+ configureShellEnvironment({
34946
+ snapshotFile: () => {
34947
+ const explicit = process.env.ALAN_AGENT_CONFIG_PATH?.trim();
34948
+ const dir = explicit ? (0, import_node_path6.dirname)(explicit) : resolveAgentConfigDirectory();
34949
+ return (0, import_node_path6.join)(dir, SNAPSHOT_FILE);
34950
+ }
34951
+ });
34952
+ function loadLoginShellEnvironment() {
34953
+ return loadShellEnvironmentSync();
34954
+ }
34955
+
34747
34956
  // src/cli-executable.ts
34748
34957
  var ALAN_CODE_PROVIDER_KIND = "alan_code";
34749
34958
  var DISCOVERABLE_PROVIDER_KINDS = [
@@ -34764,8 +34973,8 @@ function appendCliProbeOutput(current, chunk, limit) {
34764
34973
  return current + chunk.slice(0, limit - current.length);
34765
34974
  }
34766
34975
  function getDaemonCliEnvironment() {
34767
- const base = (0, import_node_os4.platform)() === "win32" ? process.env : loadLoginShellEnvironment();
34768
- return augmentCliPath2(base);
34976
+ const base = (0, import_node_os5.platform)() === "win32" ? process.env : loadLoginShellEnvironment();
34977
+ return augmentCliPath(base);
34769
34978
  }
34770
34979
  function cacheResolvedCli(command, resolvedPath) {
34771
34980
  resolvedCliCache.set(command, resolvedPath);
@@ -34791,8 +35000,8 @@ function getCachedResolvedCli(command) {
34791
35000
  return cached2;
34792
35001
  }
34793
35002
  function resolveViaWhere(command, env) {
34794
- if ((0, import_node_os4.platform)() !== "win32") return null;
34795
- const whereExe = (0, import_node_path5.join)(
35003
+ if ((0, import_node_os5.platform)() !== "win32") return null;
35004
+ const whereExe = (0, import_node_path7.join)(
34796
35005
  env.SystemRoot ?? process.env.SystemRoot ?? "C:\\Windows",
34797
35006
  "System32",
34798
35007
  "where.exe"
@@ -34814,7 +35023,7 @@ function resolveViaWhere(command, env) {
34814
35023
  }
34815
35024
  function runCliProbeAsync(executable, env, args = ["--version"], timeoutMs = 3e3, spawnOptions) {
34816
35025
  return new Promise((resolve16) => {
34817
- const isWin = (0, import_node_os4.platform)() === "win32";
35026
+ const isWin = (0, import_node_os5.platform)() === "win32";
34818
35027
  let command = executable;
34819
35028
  let commandArgs = args;
34820
35029
  if (isWin && /\.(cmd|bat)$/i.test(executable)) {
@@ -34859,7 +35068,7 @@ function runCliVersionProbeAsync(executable, env, args = ["--version"], timeoutM
34859
35068
  return runCliProbeAsync(executable, env, args, timeoutMs);
34860
35069
  }
34861
35070
  function pathSeparator() {
34862
- return (0, import_node_os4.platform)() === "win32" ? ";" : ":";
35071
+ return (0, import_node_os5.platform)() === "win32" ? ";" : ":";
34863
35072
  }
34864
35073
  function splitPath3(pathValue) {
34865
35074
  if (!pathValue) return [];
@@ -34867,7 +35076,7 @@ function splitPath3(pathValue) {
34867
35076
  }
34868
35077
  function isRunnableFile(path2) {
34869
35078
  if (!(0, import_node_fs5.existsSync)(path2)) return false;
34870
- if ((0, import_node_os4.platform)() === "win32") return true;
35079
+ if ((0, import_node_os5.platform)() === "win32") return true;
34871
35080
  try {
34872
35081
  (0, import_node_fs5.accessSync)(path2, import_node_fs5.constants.X_OK);
34873
35082
  return true;
@@ -34894,15 +35103,15 @@ var WINDOWS_CODEX_NATIVE_TARGETS = {
34894
35103
  }
34895
35104
  };
34896
35105
  function resolveWindowsCodexNativeExecutable(executable) {
34897
- if ((0, import_node_os4.platform)() !== "win32" || /\.exe$/i.test(executable) || (0, import_node_path5.basename)(executable).toLowerCase() !== "codex.cmd") {
35106
+ if ((0, import_node_os5.platform)() !== "win32" || /\.exe$/i.test(executable) || (0, import_node_path7.basename)(executable).toLowerCase() !== "codex.cmd") {
34898
35107
  return executable;
34899
35108
  }
34900
- const target = WINDOWS_CODEX_NATIVE_TARGETS[(0, import_node_os4.arch)()];
35109
+ const target = WINDOWS_CODEX_NATIVE_TARGETS[(0, import_node_os5.arch)()];
34901
35110
  if (!target) return executable;
34902
- const shimDir = (0, import_node_path5.dirname)(executable);
35111
+ const shimDir = (0, import_node_path7.dirname)(executable);
34903
35112
  const entrypoints = [
34904
- (0, import_node_path5.join)(shimDir, "node_modules", "@openai", "codex", "bin", "codex.js"),
34905
- (0, import_node_path5.join)(shimDir, "..", "@openai", "codex", "bin", "codex.js")
35113
+ (0, import_node_path7.join)(shimDir, "node_modules", "@openai", "codex", "bin", "codex.js"),
35114
+ (0, import_node_path7.join)(shimDir, "..", "@openai", "codex", "bin", "codex.js")
34906
35115
  ];
34907
35116
  for (const entrypoint of entrypoints) {
34908
35117
  if (!(0, import_node_fs5.existsSync)(entrypoint)) continue;
@@ -34910,69 +35119,22 @@ function resolveWindowsCodexNativeExecutable(executable) {
34910
35119
  try {
34911
35120
  const packageJson = (0, import_node_module.createRequire)(entrypoint).resolve(`${target.packageName}/package.json`);
34912
35121
  nativeCandidates.push(
34913
- (0, import_node_path5.join)((0, import_node_path5.dirname)(packageJson), "vendor", target.targetTriple, "bin", "codex.exe")
35122
+ (0, import_node_path7.join)((0, import_node_path7.dirname)(packageJson), "vendor", target.targetTriple, "bin", "codex.exe")
34914
35123
  );
34915
35124
  } catch {
34916
35125
  }
34917
35126
  nativeCandidates.push(
34918
- (0, import_node_path5.join)((0, import_node_path5.dirname)(entrypoint), "..", "vendor", target.targetTriple, "bin", "codex.exe")
35127
+ (0, import_node_path7.join)((0, import_node_path7.dirname)(entrypoint), "..", "vendor", target.targetTriple, "bin", "codex.exe")
34919
35128
  );
34920
35129
  const nativeExecutable = nativeCandidates.find(isRunnableFile);
34921
35130
  if (nativeExecutable) return nativeExecutable;
34922
35131
  }
34923
35132
  return executable;
34924
35133
  }
34925
- function promoteAheadOfVersionManagers(path2, promoted, versionManagerDirs) {
34926
- const managed = new Set(versionManagerDirs);
34927
- const firstManaged = path2.findIndex((dir) => managed.has(dir));
34928
- if (firstManaged === -1) return path2;
34929
- const before = path2.slice(0, firstManaged);
34930
- const tail = path2.slice(firstManaged);
34931
- const moved = tail.filter((dir) => promoted.has(dir));
34932
- if (moved.length === 0) return path2;
34933
- return [...before, ...moved, ...tail.filter((dir) => !promoted.has(dir))];
34934
- }
34935
- function promotedUserBinDirs(home) {
34936
- return /* @__PURE__ */ new Set([
34937
- (0, import_node_path5.join)(home, ".local", "bin"),
34938
- (0, import_node_path5.join)(home, ".bun", "bin"),
34939
- (0, import_node_path5.join)(home, ".cargo", "bin")
34940
- ]);
34941
- }
34942
- function augmentCliPath2(env, includeSystemPaths = true) {
34943
- const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
34944
- const isWin = (0, import_node_os4.platform)() === "win32";
34945
- const windowsLocalAppData = env.LOCALAPPDATA || (0, import_node_path5.join)(home, "AppData", "Local");
34946
- const versionManagerDirs = isWin ? [] : resolveVersionManagerBinDirs(home);
34947
- const userPaths = isWin ? [
34948
- (0, import_node_path5.join)(home, "AppData", "Roaming", "npm"),
34949
- (0, import_node_path5.join)(windowsLocalAppData, "Programs", "OpenAI", "Codex", "bin"),
34950
- (0, import_node_path5.join)(windowsLocalAppData, "Programs", "Microsoft", "WindowsApps"),
34951
- (0, import_node_path5.join)(home, ".local", "bin")
34952
- ] : [
34953
- (0, import_node_path5.join)(home, ".local", "bin"),
34954
- (0, import_node_path5.join)(home, ".local", "node", "bin"),
34955
- (0, import_node_path5.join)(home, ".bun", "bin"),
34956
- (0, import_node_path5.join)(home, ".cargo", "bin"),
34957
- // nvm/fnm/volta/asdf/mise live behind shell functions and leave nothing
34958
- // on a non-interactive PATH, so resolve them from disk. Without this a
34959
- // degraded shell probe hides node entirely and `env node` hooks die 127.
34960
- ...versionManagerDirs
34961
- ];
34962
- const systemPaths = isWin ? ["C:\\Program Files\\nodejs", "C:\\Program Files\\Git\\cmd"] : ["/opt/homebrew/bin", "/usr/local/bin"];
34963
- const extraPaths = includeSystemPaths ? [...userPaths, ...systemPaths] : userPaths;
34964
- const basePath = env.PATH ?? "";
34965
- const existing = new Set(splitPath3(basePath));
34966
- const missing = extraPaths.filter((dir) => !existing.has(dir));
34967
- const combined = missing.length > 0 ? [...missing, ...splitPath3(basePath)] : splitPath3(basePath);
34968
- const ordered = isWin ? combined : promoteAheadOfVersionManagers(combined, promotedUserBinDirs(home), versionManagerDirs);
34969
- if (ordered === combined && missing.length === 0) return env;
34970
- return { ...env, PATH: ordered.join(pathSeparator()) };
34971
- }
34972
35134
  function resolveCliExecutable(command, env) {
34973
35135
  const trimmed4 = command.trim();
34974
35136
  if (!trimmed4) return null;
34975
- const enriched = augmentCliPath2(env ?? getDaemonCliEnvironment(), env === void 0);
35137
+ const enriched = augmentCliPath(env ?? getDaemonCliEnvironment(), env === void 0);
34976
35138
  const cacheKey = cliResolutionCacheKey(trimmed4, enriched);
34977
35139
  const cached2 = getCachedResolvedCli(cacheKey);
34978
35140
  if (cached2 === null) return null;
@@ -34981,7 +35143,7 @@ function resolveCliExecutable(command, env) {
34981
35143
  cacheResolvedCli(cacheKey, trimmed4);
34982
35144
  return trimmed4;
34983
35145
  }
34984
- const isWin = (0, import_node_os4.platform)() === "win32";
35146
+ const isWin = (0, import_node_os5.platform)() === "win32";
34985
35147
  const pathExt = enriched.PATHEXT ?? (isWin ? ".EXE;.CMD;.BAT;.COM" : "");
34986
35148
  const commandNames = [trimmed4, ...CLI_COMMAND_ALIASES[trimmed4] ?? []];
34987
35149
  const names = commandNames.flatMap(
@@ -34994,7 +35156,7 @@ function resolveCliExecutable(command, env) {
34994
35156
  continue;
34995
35157
  }
34996
35158
  for (const dir of splitPath3(enriched.PATH)) {
34997
- candidates.push((0, import_node_path5.join)(dir, name));
35159
+ candidates.push((0, import_node_path7.join)(dir, name));
34998
35160
  }
34999
35161
  }
35000
35162
  const seen = /* @__PURE__ */ new Set();
@@ -35014,7 +35176,15 @@ function resolveCliExecutable(command, env) {
35014
35176
  cacheResolvedCli(cacheKey, null);
35015
35177
  return null;
35016
35178
  }
35179
+ var ALAN_CODE_ENGINE_PATH_ENV = "ALAN_CODE_ENGINE_PATH";
35180
+ function bundledAlanCodeEngine(backendKind, env) {
35181
+ if (backendKind !== ALAN_CODE_PROVIDER_KIND) return null;
35182
+ const path2 = env[ALAN_CODE_ENGINE_PATH_ENV]?.trim() || process.env[ALAN_CODE_ENGINE_PATH_ENV]?.trim();
35183
+ return path2 && isRunnableFile(path2) ? path2 : null;
35184
+ }
35017
35185
  function resolveProviderCliCommand(provider, env) {
35186
+ const bundled = bundledAlanCodeEngine(provider, env ?? getDaemonCliEnvironment());
35187
+ if (bundled) return bundled;
35018
35188
  const spec = findSandboxRuntimeDefinition(provider);
35019
35189
  if (!spec) return null;
35020
35190
  const cliEnv = env ?? getDaemonCliEnvironment();
@@ -35031,6 +35201,8 @@ function resolveBackendRuntimeCommand(backendKind, env) {
35031
35201
  const spec = findSandboxRuntimeDefinition(backendKind);
35032
35202
  if (!spec) return void 0;
35033
35203
  const cliEnv = env ?? getDaemonCliEnvironment();
35204
+ const bundled = bundledAlanCodeEngine(backendKind, cliEnv);
35205
+ if (bundled) return bundled;
35034
35206
  const envOverride = spec.envVars.map((name) => cliEnv[name]?.trim()).find(Boolean);
35035
35207
  const resolved = resolveCliExecutable(envOverride?.trim() || spec.command, cliEnv);
35036
35208
  if (!resolved) return void 0;
@@ -35271,7 +35443,7 @@ function buildComputerReadiness(input2) {
35271
35443
  }
35272
35444
 
35273
35445
  // src/version.ts
35274
- var AGENT_VERSION = "0.1.123";
35446
+ var AGENT_VERSION = "0.1.124";
35275
35447
 
35276
35448
  // src/daemon/status.ts
35277
35449
  var PENDING_RUN_START_TTL_MS = 10 * 6e4;
@@ -35329,7 +35501,7 @@ var DurablePendingRunStarts = class extends Map {
35329
35501
  return;
35330
35502
  }
35331
35503
  const pendingPath = `${this.path}.pending`;
35332
- (0, import_node_fs7.mkdirSync)((0, import_node_path6.dirname)(this.path), { recursive: true, mode: 448 });
35504
+ (0, import_node_fs7.mkdirSync)((0, import_node_path8.dirname)(this.path), { recursive: true, mode: 448 });
35333
35505
  try {
35334
35506
  (0, import_node_fs7.writeFileSync)(
35335
35507
  pendingPath,
@@ -35559,21 +35731,21 @@ function reconcileActiveRuns(input2) {
35559
35731
  }
35560
35732
  }
35561
35733
  function collectRuntimeMetadata() {
35562
- const cpuList = (0, import_node_os5.cpus)();
35734
+ const cpuList = (0, import_node_os6.cpus)();
35563
35735
  const metadata = {
35564
- platform: (0, import_node_os5.platform)(),
35565
- arch: (0, import_node_os5.arch)(),
35566
- osVersion: (0, import_node_os5.release)(),
35736
+ platform: (0, import_node_os6.platform)(),
35737
+ arch: (0, import_node_os6.arch)(),
35738
+ osVersion: (0, import_node_os6.release)(),
35567
35739
  agentVersion: AGENT_VERSION,
35568
- memoryBytes: (0, import_node_os5.totalmem)(),
35569
- memoryFreeBytes: (0, import_node_os5.freemem)()
35740
+ memoryBytes: (0, import_node_os6.totalmem)(),
35741
+ memoryFreeBytes: (0, import_node_os6.freemem)()
35570
35742
  };
35571
35743
  if (cpuList.length > 0) {
35572
35744
  metadata.cpuModel = cpuList[0]?.model;
35573
35745
  metadata.cpuCores = cpuList.length;
35574
35746
  }
35575
35747
  try {
35576
- const disk = (0, import_node_fs7.statfsSync)((0, import_node_os5.homedir)());
35748
+ const disk = (0, import_node_fs7.statfsSync)((0, import_node_os6.homedir)());
35577
35749
  metadata.diskFreeBytes = disk.bavail * disk.bsize;
35578
35750
  metadata.diskTotalBytes = disk.blocks * disk.bsize;
35579
35751
  } catch {
@@ -35622,14 +35794,14 @@ function localServiceOwnerPayload(owner) {
35622
35794
  ].join("\0");
35623
35795
  }
35624
35796
  function signLocalServiceOwner(secret, owner) {
35625
- return (0, import_node_crypto.createHmac)("sha256", secret).update(localServiceOwnerPayload(owner)).digest("hex");
35797
+ return (0, import_node_crypto2.createHmac)("sha256", secret).update(localServiceOwnerPayload(owner)).digest("hex");
35626
35798
  }
35627
35799
  function signLocalServiceAdoption(secret, serviceId, challenge) {
35628
- return (0, import_node_crypto.createHmac)("sha256", secret).update(["adopt", serviceId, challenge].join("\0")).digest("hex");
35800
+ return (0, import_node_crypto2.createHmac)("sha256", secret).update(["adopt", serviceId, challenge].join("\0")).digest("hex");
35629
35801
  }
35630
35802
  function equalHexDigest(actual, expected) {
35631
35803
  if (!/^[a-f0-9]{64}$/i.test(actual) || !/^[a-f0-9]{64}$/i.test(expected)) return false;
35632
- return (0, import_node_crypto.timingSafeEqual)(Buffer.from(actual, "hex"), Buffer.from(expected, "hex"));
35804
+ return (0, import_node_crypto2.timingSafeEqual)(Buffer.from(actual, "hex"), Buffer.from(expected, "hex"));
35633
35805
  }
35634
35806
  function parseLocalServiceOwner(value2) {
35635
35807
  if (!value2 || typeof value2 !== "object") return null;
@@ -35791,7 +35963,7 @@ function getConfigPath() {
35791
35963
  return boundAgentConfigPath ?? process.env.ALAN_AGENT_CONFIG_PATH ?? resolveAgentConfigPath({ profile: "production" });
35792
35964
  }
35793
35965
  function getEndpointDefaultsPath() {
35794
- return process.env.ALAN_AGENT_ENDPOINTS_PATH ?? (0, import_node_path7.join)((0, import_node_path7.dirname)(getConfigPath()), "endpoints.json");
35966
+ return process.env.ALAN_AGENT_ENDPOINTS_PATH ?? (0, import_node_path9.join)((0, import_node_path9.dirname)(getConfigPath()), "endpoints.json");
35795
35967
  }
35796
35968
  function readConfig() {
35797
35969
  const configPath = getConfigPath();
@@ -35821,8 +35993,8 @@ function readEndpointDefaults() {
35821
35993
  }
35822
35994
  function writeConfig(config4) {
35823
35995
  const configPath = getConfigPath();
35824
- (0, import_node_fs8.mkdirSync)((0, import_node_path7.dirname)(configPath), { recursive: true, mode: 448 });
35825
- const pendingPath = `${configPath}.pending-${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
35996
+ (0, import_node_fs8.mkdirSync)((0, import_node_path9.dirname)(configPath), { recursive: true, mode: 448 });
35997
+ const pendingPath = `${configPath}.pending-${process.pid}-${(0, import_node_crypto2.randomBytes)(6).toString("hex")}`;
35826
35998
  try {
35827
35999
  (0, import_node_fs8.writeFileSync)(pendingPath, JSON.stringify(sanitizeAgentConfig({ ...config4 }), null, 2), {
35828
36000
  mode: 384
@@ -35869,12 +36041,12 @@ function acquireLocalDaemonMaintenanceLease(configPath, reason, ttlMs = 5e3) {
35869
36041
  if (existing) return { acquired: false, lease: existing };
35870
36042
  const lease = {
35871
36043
  version: 1,
35872
- id: (0, import_node_crypto.randomUUID)(),
36044
+ id: (0, import_node_crypto2.randomUUID)(),
35873
36045
  reason,
35874
36046
  expiresAtMs: reason === "credential_cleanup" ? null : Date.now() + Math.max(1e3, Math.min(ttlMs, 6e4))
35875
36047
  };
35876
36048
  const path2 = maintenanceLeasePath(configPath);
35877
- (0, import_node_fs8.mkdirSync)((0, import_node_path7.dirname)(path2), { recursive: true, mode: 448 });
36049
+ (0, import_node_fs8.mkdirSync)((0, import_node_path9.dirname)(path2), { recursive: true, mode: 448 });
35878
36050
  try {
35879
36051
  (0, import_node_fs8.writeFileSync)(path2, JSON.stringify(lease), { mode: 384, flag: "wx" });
35880
36052
  (0, import_node_fs8.chmodSync)(path2, 384);
@@ -35940,7 +36112,7 @@ async function acquireLocalDaemonOwnerLease(input2) {
35940
36112
  }
35941
36113
  const lease = {
35942
36114
  version: 1,
35943
- id: (0, import_node_crypto.randomUUID)(),
36115
+ id: (0, import_node_crypto2.randomUUID)(),
35944
36116
  daemonSessionId: input2.daemonSessionId,
35945
36117
  pid: process.pid,
35946
36118
  startedAtMs: Date.now(),
@@ -35950,7 +36122,7 @@ async function acquireLocalDaemonOwnerLease(input2) {
35950
36122
  localApiToken: input2.localApiToken
35951
36123
  };
35952
36124
  const path2 = daemonOwnerLeasePath(input2.configPath);
35953
- (0, import_node_fs8.mkdirSync)((0, import_node_path7.dirname)(path2), { recursive: true, mode: 448 });
36125
+ (0, import_node_fs8.mkdirSync)((0, import_node_path9.dirname)(path2), { recursive: true, mode: 448 });
35954
36126
  try {
35955
36127
  (0, import_node_fs8.writeFileSync)(path2, JSON.stringify(lease), { mode: 384, flag: "wx" });
35956
36128
  (0, import_node_fs8.chmodSync)(path2, 384);
@@ -35980,7 +36152,7 @@ function releaseLocalDaemonOwnerLease(configPath, leaseId) {
35980
36152
  releaseOwnedJsonFile(daemonOwnerLeasePath(configPath), leaseId);
35981
36153
  }
35982
36154
  function releaseOwnedJsonFile(path2, ownerId, ownerField = "id") {
35983
- const releasePath = `${path2}.release-${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
36155
+ const releasePath = `${path2}.release-${process.pid}-${(0, import_node_crypto2.randomBytes)(6).toString("hex")}`;
35984
36156
  try {
35985
36157
  (0, import_node_fs8.renameSync)(path2, releasePath);
35986
36158
  } catch (error61) {
@@ -36055,7 +36227,7 @@ function pendingSetupIntentPath() {
36055
36227
  return `${getConfigPath()}.setup-pending`;
36056
36228
  }
36057
36229
  function setupTokenHash(setupToken) {
36058
- return (0, import_node_crypto.createHash)("sha256").update(setupToken).digest("hex");
36230
+ return (0, import_node_crypto2.createHash)("sha256").update(setupToken).digest("hex");
36059
36231
  }
36060
36232
  function getOrCreateSetupAttemptId(setupToken) {
36061
36233
  const intentPath = pendingSetupIntentPath();
@@ -36069,9 +36241,9 @@ function getOrCreateSetupAttemptId(setupToken) {
36069
36241
  } catch {
36070
36242
  }
36071
36243
  }
36072
- const registrationAttemptId = (0, import_node_crypto.randomUUID)();
36073
- (0, import_node_fs8.mkdirSync)((0, import_node_path7.dirname)(intentPath), { recursive: true, mode: 448 });
36074
- const writePath = `${intentPath}.pending-${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
36244
+ const registrationAttemptId = (0, import_node_crypto2.randomUUID)();
36245
+ (0, import_node_fs8.mkdirSync)((0, import_node_path9.dirname)(intentPath), { recursive: true, mode: 448 });
36246
+ const writePath = `${intentPath}.pending-${process.pid}-${(0, import_node_crypto2.randomBytes)(6).toString("hex")}`;
36075
36247
  try {
36076
36248
  (0, import_node_fs8.writeFileSync)(
36077
36249
  writePath,
@@ -36114,7 +36286,7 @@ function restoreCapturedFileUnlessReplaced(path2, content) {
36114
36286
  }
36115
36287
  }
36116
36288
  function quarantineCorruptDeviceAuthorizationOperation(path2) {
36117
- const quarantinePath = `${path2}.corrupt-${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
36289
+ const quarantinePath = `${path2}.corrupt-${process.pid}-${(0, import_node_crypto2.randomBytes)(6).toString("hex")}`;
36118
36290
  try {
36119
36291
  (0, import_node_fs8.renameSync)(path2, quarantinePath);
36120
36292
  } catch (error61) {
@@ -36149,11 +36321,11 @@ function acquireDeviceAuthorizationOperation() {
36149
36321
  if (existing) return null;
36150
36322
  const lease = {
36151
36323
  version: 1,
36152
- id: (0, import_node_crypto.randomUUID)(),
36324
+ id: (0, import_node_crypto2.randomUUID)(),
36153
36325
  expiresAtMs: Date.now() + 6e4
36154
36326
  };
36155
36327
  const path2 = deviceAuthorizationOperationPath();
36156
- (0, import_node_fs8.mkdirSync)((0, import_node_path7.dirname)(path2), { recursive: true, mode: 448 });
36328
+ (0, import_node_fs8.mkdirSync)((0, import_node_path9.dirname)(path2), { recursive: true, mode: 448 });
36157
36329
  try {
36158
36330
  (0, import_node_fs8.writeFileSync)(path2, JSON.stringify(lease), { mode: 384, flag: "wx" });
36159
36331
  (0, import_node_fs8.chmodSync)(path2, 384);
@@ -36169,7 +36341,7 @@ function extendDeviceAuthorizationOperation(operationId, expiresAtMs) {
36169
36341
  throw new Error("browser authorization operation ownership was lost");
36170
36342
  }
36171
36343
  const path2 = deviceAuthorizationOperationPath();
36172
- const pendingPath = `${path2}.pending-${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
36344
+ const pendingPath = `${path2}.pending-${process.pid}-${(0, import_node_crypto2.randomBytes)(6).toString("hex")}`;
36173
36345
  try {
36174
36346
  (0, import_node_fs8.writeFileSync)(
36175
36347
  pendingPath,
@@ -36218,8 +36390,8 @@ function readPendingDeviceAuthorization(apiUrl) {
36218
36390
  }
36219
36391
  function writePendingDeviceAuthorization(pending) {
36220
36392
  const path2 = pendingDeviceAuthorizationPath();
36221
- (0, import_node_fs8.mkdirSync)((0, import_node_path7.dirname)(path2), { recursive: true, mode: 448 });
36222
- const writePath = `${path2}.pending-${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
36393
+ (0, import_node_fs8.mkdirSync)((0, import_node_path9.dirname)(path2), { recursive: true, mode: 448 });
36394
+ const writePath = `${path2}.pending-${process.pid}-${(0, import_node_crypto2.randomBytes)(6).toString("hex")}`;
36223
36395
  try {
36224
36396
  (0, import_node_fs8.writeFileSync)(writePath, JSON.stringify(pending, null, 2), { mode: 384 });
36225
36397
  (0, import_node_fs8.chmodSync)(writePath, 384);
@@ -36230,8 +36402,8 @@ function writePendingDeviceAuthorization(pending) {
36230
36402
  }
36231
36403
  function removeAlanOwnedLocalArtifacts() {
36232
36404
  const configPath = getConfigPath();
36233
- const directory = (0, import_node_path7.dirname)(configPath);
36234
- const configName = (0, import_node_path7.basename)(configPath).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
36405
+ const directory = (0, import_node_path9.dirname)(configPath);
36406
+ const configName = (0, import_node_path9.basename)(configPath).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
36235
36407
  const alanAtomicSidecarPattern = new RegExp(
36236
36408
  `^${configName}(?:|\\.setup-pending|\\.device-auth-pending|\\.device-auth-operation\\.json|\\.maintenance-lease\\.json|\\.event-outbox\\.enc)\\.(?:pending|release|corrupt)-\\d+-[a-f0-9]{12}$`
36237
36409
  );
@@ -36250,14 +36422,14 @@ function removeAlanOwnedLocalArtifacts() {
36250
36422
  ]);
36251
36423
  if ((0, import_node_fs8.existsSync)(directory)) {
36252
36424
  for (const entry of (0, import_node_fs8.readdirSync)(directory)) {
36253
- if (alanAtomicSidecarPattern.test(entry)) artifacts.add((0, import_node_path7.join)(directory, entry));
36425
+ if (alanAtomicSidecarPattern.test(entry)) artifacts.add((0, import_node_path9.join)(directory, entry));
36254
36426
  }
36255
36427
  }
36256
36428
  for (const artifact of artifacts) (0, import_node_fs8.rmSync)(artifact, { force: true });
36257
36429
  for (const staleSpool of [
36258
36430
  `${configPath}.event-outbox.enc.journal`,
36259
36431
  `${configPath}.native-streams`,
36260
- (0, import_node_path7.join)(directory, "native-hook-inbox")
36432
+ (0, import_node_path9.join)(directory, "native-hook-inbox")
36261
36433
  ]) {
36262
36434
  (0, import_node_fs8.rmSync)(staleSpool, { recursive: true, force: true });
36263
36435
  }
@@ -36306,25 +36478,25 @@ function isNativeAssistantFingerprint(value2) {
36306
36478
  }
36307
36479
 
36308
36480
  // src/native/provider-paths.ts
36309
- var import_node_os6 = require("os");
36310
- var import_node_path8 = require("path");
36481
+ var import_node_os7 = require("os");
36482
+ var import_node_path10 = require("path");
36311
36483
  function providerConfigDir(provider, options) {
36312
36484
  const env = options.env ?? process.env;
36313
- const home = options.homeDir ?? (0, import_node_os6.homedir)();
36314
- if (provider === "claude") return env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path8.join)(home, ".claude");
36315
- return env.CODEX_HOME?.trim() || (0, import_node_path8.join)(home, ".codex");
36485
+ const home = options.homeDir ?? (0, import_node_os7.homedir)();
36486
+ if (provider === "claude") return env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path10.join)(home, ".claude");
36487
+ return env.CODEX_HOME?.trim() || (0, import_node_path10.join)(home, ".codex");
36316
36488
  }
36317
36489
  function providerHookSettingsPath(provider, options = {}) {
36318
36490
  const file2 = provider === "claude" ? "settings.json" : "hooks.json";
36319
- return (0, import_node_path8.join)(providerConfigDir(provider, options), file2);
36491
+ return (0, import_node_path10.join)(providerConfigDir(provider, options), file2);
36320
36492
  }
36321
36493
  function providerTranscriptRoot(provider, options = {}) {
36322
36494
  const directory = provider === "claude" ? "projects" : "sessions";
36323
- return (0, import_node_path8.join)(providerConfigDir(provider, options), directory);
36495
+ return (0, import_node_path10.join)(providerConfigDir(provider, options), directory);
36324
36496
  }
36325
36497
 
36326
36498
  // src/native/signal.ts
36327
- var import_node_path9 = require("path");
36499
+ var import_node_path11 = require("path");
36328
36500
 
36329
36501
  // ../shared/dist/types/native-agent-session.js
36330
36502
  var nativeAgentProviderBackendKinds = {
@@ -36386,7 +36558,7 @@ function isNativeIngestionHookSignal(value2) {
36386
36558
  if (keys.length !== SIGNAL_KEYS.size || !keys.every((key) => SIGNAL_KEYS.has(key))) {
36387
36559
  return false;
36388
36560
  }
36389
- return isNativeIngestionProvider(value2.provider) && isNativeIngestionHookEvent(value2.event) && isNonEmptyString(value2.externalSessionId) && isNonEmptyString(value2.transcriptPath) && (0, import_node_path9.isAbsolute)(value2.transcriptPath) && isNullableString(value2.cwd) && isNullableString(value2.providerTurnId) && (value2.assistantFingerprint === null || isNativeAssistantFingerprint(value2.assistantFingerprint)) && isIsoTimestamp(value2.observedAt);
36561
+ return isNativeIngestionProvider(value2.provider) && isNativeIngestionHookEvent(value2.event) && isNonEmptyString(value2.externalSessionId) && isNonEmptyString(value2.transcriptPath) && (0, import_node_path11.isAbsolute)(value2.transcriptPath) && isNullableString(value2.cwd) && isNullableString(value2.providerTurnId) && (value2.assistantFingerprint === null || isNativeAssistantFingerprint(value2.assistantFingerprint)) && isIsoTimestamp(value2.observedAt);
36390
36562
  }
36391
36563
 
36392
36564
  // src/cli/hook.ts
@@ -36420,7 +36592,7 @@ function stringField(payload, ...names) {
36420
36592
  }
36421
36593
  function codexSessionIdFromTranscriptPath(transcriptPath2) {
36422
36594
  const match = /^rollout-.*-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i.exec(
36423
- (0, import_node_path10.basename)(transcriptPath2)
36595
+ (0, import_node_path12.basename)(transcriptPath2)
36424
36596
  );
36425
36597
  return match?.[1] ?? null;
36426
36598
  }
@@ -36489,14 +36661,14 @@ function realpathOrSelf(path2) {
36489
36661
  }
36490
36662
  }
36491
36663
  function isWithinDirectory(path2, directory) {
36492
- const offset2 = (0, import_node_path10.relative)(realpathOrSelf(directory), realpathOrSelf(path2));
36493
- return offset2 !== "" && !offset2.startsWith("..") && !(0, import_node_path10.isAbsolute)(offset2);
36664
+ const offset2 = (0, import_node_path12.relative)(realpathOrSelf(directory), realpathOrSelf(path2));
36665
+ return offset2 !== "" && !offset2.startsWith("..") && !(0, import_node_path12.isAbsolute)(offset2);
36494
36666
  }
36495
36667
  function parseHookSignal(input2) {
36496
36668
  const { payload } = input2;
36497
36669
  const rawTranscriptPath = stringField(payload, "transcript_path", "transcriptPath");
36498
36670
  if (!rawTranscriptPath) return null;
36499
- const transcriptPath2 = (0, import_node_path10.resolve)(rawTranscriptPath);
36671
+ const transcriptPath2 = (0, import_node_path12.resolve)(rawTranscriptPath);
36500
36672
  const externalSessionId = stringField(payload, "session_id", "sessionId") ?? (input2.provider === "codex" ? codexSessionIdFromTranscriptPath(transcriptPath2) : null);
36501
36673
  if (!externalSessionId) return null;
36502
36674
  const cwd = stringField(payload, "cwd");
@@ -36505,7 +36677,7 @@ function parseHookSignal(input2) {
36505
36677
  event: input2.event,
36506
36678
  externalSessionId,
36507
36679
  transcriptPath: transcriptPath2,
36508
- cwd: cwd ? (0, import_node_path10.resolve)(cwd) : null,
36680
+ cwd: cwd ? (0, import_node_path12.resolve)(cwd) : null,
36509
36681
  providerTurnId: stringField(payload, "prompt_id", "turn_id"),
36510
36682
  assistantFingerprint: typeof payload.last_assistant_message === "string" ? assistantFingerprint(payload.last_assistant_message) : null,
36511
36683
  observedAt: input2.observedAt.toISOString()
@@ -36840,21 +37012,21 @@ function describeError(error61) {
36840
37012
  }
36841
37013
 
36842
37014
  // src/cli/login.ts
36843
- var import_node_crypto3 = require("crypto");
36844
- var import_node_os11 = require("os");
37015
+ var import_node_crypto4 = require("crypto");
37016
+ var import_node_os12 = require("os");
36845
37017
 
36846
37018
  // src/cli/setup.ts
36847
- var import_node_crypto2 = require("crypto");
36848
- var import_node_os10 = require("os");
37019
+ var import_node_crypto3 = require("crypto");
37020
+ var import_node_os11 = require("os");
36849
37021
 
36850
37022
  // src/runtime-registration.ts
36851
- var import_node_os9 = require("os");
37023
+ var import_node_os10 = require("os");
36852
37024
 
36853
37025
  // src/cli-ensure-install.ts
36854
37026
  var import_node_child_process5 = require("child_process");
36855
37027
  var import_node_fs10 = require("fs");
36856
- var import_node_os7 = require("os");
36857
- var import_node_path11 = require("path");
37028
+ var import_node_os8 = require("os");
37029
+ var import_node_path13 = require("path");
36858
37030
  var CLI_RUNTIME_VERSIONS_ENV = "ALAN_CLI_RUNTIME_VERSIONS";
36859
37031
  var installOutcomes = /* @__PURE__ */ new Map();
36860
37032
  function canInstallProviderCli(backendKind) {
@@ -36867,23 +37039,23 @@ function canInstallProviderCli(backendKind) {
36867
37039
  function usesStagedSandboxInstall(backendKind) {
36868
37040
  const runtime = findSandboxRuntimeDefinition(backendKind);
36869
37041
  return Boolean(
36870
- runtime?.installer.kind === "npm" && (0, import_node_os7.platform)() === "linux" && process.env.ALAN_SANDBOX_PROVIDER && canInstallProviderCli(backendKind)
37042
+ runtime?.installer.kind === "npm" && (0, import_node_os8.platform)() === "linux" && process.env.ALAN_SANDBOX_PROVIDER && canInstallProviderCli(backendKind)
36871
37043
  );
36872
37044
  }
36873
37045
  function currentRuntimePlatform() {
36874
- const current = (0, import_node_os7.platform)();
37046
+ const current = (0, import_node_os8.platform)();
36875
37047
  if (current === "linux" || current === "darwin" || current === "win32") return current;
36876
37048
  return null;
36877
37049
  }
36878
37050
  function resolveWindowsNpmInvocation(env, npmArgs) {
36879
37051
  const searchPath = env.PATH ?? env.Path ?? "";
36880
- for (const rawDirectory of searchPath.split(import_node_path11.delimiter)) {
37052
+ for (const rawDirectory of searchPath.split(import_node_path13.delimiter)) {
36881
37053
  const directory = rawDirectory.trim().replace(/^"|"$/g, "");
36882
37054
  if (!directory) continue;
36883
- const executable = (0, import_node_path11.join)(directory, "npm.exe");
37055
+ const executable = (0, import_node_path13.join)(directory, "npm.exe");
36884
37056
  if ((0, import_node_fs10.existsSync)(executable)) return { command: executable, args: npmArgs };
36885
- const commandShim = (0, import_node_path11.join)(directory, "npm.cmd");
36886
- const cliScript = (0, import_node_path11.join)(directory, "node_modules", "npm", "bin", "npm-cli.js");
37057
+ const commandShim = (0, import_node_path13.join)(directory, "npm.cmd");
37058
+ const cliScript = (0, import_node_path13.join)(directory, "node_modules", "npm", "bin", "npm-cli.js");
36887
37059
  if ((0, import_node_fs10.existsSync)(commandShim) && (0, import_node_fs10.existsSync)(cliScript)) {
36888
37060
  return { command: process.execPath, args: [cliScript, ...npmArgs] };
36889
37061
  }
@@ -36896,7 +37068,7 @@ function runCliInstallCommand(command, args, env, timeoutMs) {
36896
37068
  try {
36897
37069
  child = (0, import_node_child_process5.spawn)(command, args, {
36898
37070
  env,
36899
- windowsHide: (0, import_node_os7.platform)() === "win32" ? true : void 0,
37071
+ windowsHide: (0, import_node_os8.platform)() === "win32" ? true : void 0,
36900
37072
  timeout: timeoutMs,
36901
37073
  stdio: ["ignore", "pipe", "pipe"]
36902
37074
  });
@@ -36928,7 +37100,7 @@ function runCliInstallCommand(command, args, env, timeoutMs) {
36928
37100
  }
36929
37101
  function runNpmInstall(installSpec, env, timeoutMs) {
36930
37102
  const npmArgs = ["install", "-g", installSpec];
36931
- const invocation = (0, import_node_os7.platform)() === "win32" ? resolveWindowsNpmInvocation(env, npmArgs) : { command: "npm", args: npmArgs };
37103
+ const invocation = (0, import_node_os8.platform)() === "win32" ? resolveWindowsNpmInvocation(env, npmArgs) : { command: "npm", args: npmArgs };
36932
37104
  if (!invocation) {
36933
37105
  return Promise.resolve({
36934
37106
  status: null,
@@ -37086,8 +37258,8 @@ ${result.stderr}`.trim();
37086
37258
 
37087
37259
  // src/provider-model-discovery.ts
37088
37260
  var import_node_fs11 = require("fs");
37089
- var import_node_os8 = require("os");
37090
- var import_node_path12 = require("path");
37261
+ var import_node_os9 = require("os");
37262
+ var import_node_path14 = require("path");
37091
37263
 
37092
37264
  // ../shared/dist/utils/workflow-tools-filter.js
37093
37265
  var WORKFLOW_ALWAYS_ALLOWED_BUILTIN_TOOLS = [
@@ -39831,9 +40003,9 @@ function readOpenCodeZenCredential(env) {
39831
40003
  function readOpenCodeAuthDocument(env) {
39832
40004
  const injected = env.OPENCODE_AUTH_CONTENT?.trim();
39833
40005
  if (injected) return injected;
39834
- const dataHome = env.XDG_DATA_HOME?.trim() || (0, import_node_path12.join)((0, import_node_os8.homedir)(), ".local", "share");
40006
+ const dataHome = env.XDG_DATA_HOME?.trim() || (0, import_node_path14.join)((0, import_node_os9.homedir)(), ".local", "share");
39835
40007
  try {
39836
- return (0, import_node_fs11.readFileSync)((0, import_node_path12.join)(dataHome, "opencode", "auth.json"), "utf8");
40008
+ return (0, import_node_fs11.readFileSync)((0, import_node_path14.join)(dataHome, "opencode", "auth.json"), "utf8");
39837
40009
  } catch {
39838
40010
  return null;
39839
40011
  }
@@ -39891,10 +40063,10 @@ var OPENCODE_CACHE_PROVIDER_KEYS = ["opencode", "opencode-go"];
39891
40063
  var OPENCODE_CATALOGUE_URL = "https://models.dev/api.json";
39892
40064
  var OPENCODE_CATALOGUE_TIMEOUT_MS = 1e4;
39893
40065
  function readOpenCodeCatalogueCache(env) {
39894
- const cacheHome = env.XDG_CACHE_HOME?.trim() || (0, import_node_path12.join)((0, import_node_os8.homedir)(), ".cache");
40066
+ const cacheHome = env.XDG_CACHE_HOME?.trim() || (0, import_node_path14.join)((0, import_node_os9.homedir)(), ".cache");
39895
40067
  try {
39896
40068
  return openCodeMetadataFromCatalogue(
39897
- JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path12.join)(cacheHome, ...OPENCODE_CATALOGUE_CACHE_SEGMENTS), "utf8"))
40069
+ JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path14.join)(cacheHome, ...OPENCODE_CATALOGUE_CACHE_SEGMENTS), "utf8"))
39898
40070
  );
39899
40071
  } catch {
39900
40072
  return null;
@@ -40403,7 +40575,7 @@ async function exchangeRuntimeSetupGrant(input2, setupSignal) {
40403
40575
  setupToken: input2.setupToken,
40404
40576
  registrationAttemptId,
40405
40577
  displayName: input2.displayName,
40406
- hostname: (0, import_node_os9.hostname)(),
40578
+ hostname: (0, import_node_os10.hostname)(),
40407
40579
  runtimeKind: "machine",
40408
40580
  managementKind: "user_managed",
40409
40581
  hostKind: "daemon",
@@ -40491,9 +40663,9 @@ function writeRegisteredRuntimeConfig(args, previousConfig, registered) {
40491
40663
  writeConfig({
40492
40664
  ...registered,
40493
40665
  localApiPort: getLocalApiPort(args, {}),
40494
- localApiToken: previousConfig.localApiToken ?? (0, import_node_crypto2.randomBytes)(24).toString("hex"),
40495
- localServiceId: previousConfig.localServiceId ?? (0, import_node_crypto2.randomUUID)(),
40496
- localServiceSecret: previousConfig.localServiceSecret ?? (0, import_node_crypto2.randomBytes)(32).toString("base64url"),
40666
+ localApiToken: previousConfig.localApiToken ?? (0, import_node_crypto3.randomBytes)(24).toString("hex"),
40667
+ localServiceId: previousConfig.localServiceId ?? (0, import_node_crypto3.randomUUID)(),
40668
+ localServiceSecret: previousConfig.localServiceSecret ?? (0, import_node_crypto3.randomBytes)(32).toString("base64url"),
40497
40669
  daemonEpoch: previousConfig.daemonEpoch,
40498
40670
  nativeIngestion: previousConfig.nativeIngestion
40499
40671
  });
@@ -40507,9 +40679,9 @@ async function setupDaemon(args, options = {}) {
40507
40679
  const teamId = argValue(args, "--team") ?? process.env.ALAN_TEAM_ID;
40508
40680
  const setupToken = argValue(args, "--setup-token") ?? process.env.ALAN_RUNTIME_SETUP_TOKEN;
40509
40681
  const token = argValue(args, "--token") ?? process.env.ALAN_SETUP_TOKEN;
40510
- const displayName = argValue(args, "--name") ?? (0, import_node_os10.hostname)();
40682
+ const displayName = argValue(args, "--name") ?? (0, import_node_os11.hostname)();
40511
40683
  const scope = argValue(args, "--scope") ?? process.env.ALAN_RUNTIME_SCOPE ?? (setupToken ? "team" : "user");
40512
- const installationId = argValue(args, "--installation-id") ?? previousConfig.installationId ?? (0, import_node_crypto2.randomUUID)();
40684
+ const installationId = argValue(args, "--installation-id") ?? previousConfig.installationId ?? (0, import_node_crypto3.randomUUID)();
40513
40685
  if (scope !== "team" && scope !== "user") {
40514
40686
  throw new Error("setup --scope must be either 'team' or 'user'");
40515
40687
  }
@@ -40627,10 +40799,10 @@ async function loginWithDeviceCode(args) {
40627
40799
  }
40628
40800
  const previousConfig = readConfigForRegistration();
40629
40801
  const { apiUrl, wsUrl, endpointProfile } = resolveEndpoints(args);
40630
- const displayName = argValue(args, "--name") ?? (0, import_node_os11.hostname)();
40802
+ const displayName = argValue(args, "--name") ?? (0, import_node_os12.hostname)();
40631
40803
  const maxPolls = Number.parseInt(argValue(args, "--max-polls") ?? "300", 10);
40632
40804
  const resumed = readPendingDeviceAuthorization(apiUrl);
40633
- const installationId = resumed?.installationId ?? previousConfig.installationId ?? (0, import_node_crypto3.randomUUID)();
40805
+ const installationId = resumed?.installationId ?? previousConfig.installationId ?? (0, import_node_crypto4.randomUUID)();
40634
40806
  let authorization = resumed ? { ...resumed, operationId: operation.id } : null;
40635
40807
  if (!authorization) {
40636
40808
  clearPendingDeviceAuthorization();
@@ -40639,7 +40811,7 @@ async function loginWithDeviceCode(args) {
40639
40811
  headers: { "content-type": "application/json" },
40640
40812
  body: JSON.stringify({
40641
40813
  displayName,
40642
- hostname: (0, import_node_os11.hostname)(),
40814
+ hostname: (0, import_node_os12.hostname)(),
40643
40815
  capabilities: discoverCapabilities(),
40644
40816
  metadata: {
40645
40817
  ...await collectRuntimeMetadataWithProviderLimits(),
@@ -41148,15 +41320,15 @@ async function revokeRuntimeToken(args) {
41148
41320
 
41149
41321
  // src/skills/local-skill-source.ts
41150
41322
  var import_node_buffer2 = require("buffer");
41151
- var import_node_crypto5 = require("crypto");
41323
+ var import_node_crypto6 = require("crypto");
41152
41324
  var import_promises2 = require("fs/promises");
41153
- var import_node_path14 = __toESM(require("path"), 1);
41325
+ var import_node_path16 = __toESM(require("path"), 1);
41154
41326
 
41155
41327
  // ../shared/dist/node/skill-package.js
41156
41328
  var import_node_buffer = require("buffer");
41157
- var import_node_crypto4 = require("crypto");
41329
+ var import_node_crypto5 = require("crypto");
41158
41330
  var import_promises = require("fs/promises");
41159
- var import_node_path13 = require("path");
41331
+ var import_node_path15 = require("path");
41160
41332
  var import_yaml = __toESM(require_dist(), 1);
41161
41333
 
41162
41334
  // ../shared/dist/skills/domain.js
@@ -41638,7 +41810,7 @@ async function inspectSkillPackage(packageRoot, options = {}) {
41638
41810
  }
41639
41811
  const inspectedFiles = await Promise.all(files.map(readPackageFile));
41640
41812
  inspectedFiles.sort(comparePackageFiles);
41641
- const parsedMetadata = parseSkillMetadata(inspectedFiles.find((file2) => file2.manifest.path === "SKILL.md")?.bytes, options.expectedName === void 0 ? (0, import_node_path13.basename)(root) : options.expectedName);
41813
+ const parsedMetadata = parseSkillMetadata(inspectedFiles.find((file2) => file2.manifest.path === "SKILL.md")?.bytes, options.expectedName === void 0 ? (0, import_node_path15.basename)(root) : options.expectedName);
41642
41814
  const manifestFiles = inspectedFiles.map((file2) => file2.manifest);
41643
41815
  const diagnostics = [
41644
41816
  ...parsedMetadata.conformance,
@@ -41662,7 +41834,7 @@ async function readSkillPackageFile(packageRoot, path2, expectedSha256) {
41662
41834
  if (!normalizedPath || normalizedPath !== path2 || normalizedPath.includes("\\") || components.some((component) => !component || component === "." || component === "..")) {
41663
41835
  throw new SkillPackageError("INVALID_PATH", `Invalid Skill package path: ${path2}`, path2);
41664
41836
  }
41665
- const absolutePath = await (0, import_promises.realpath)((0, import_node_path13.resolve)(root, ...components)).catch(() => null);
41837
+ const absolutePath = await (0, import_promises.realpath)((0, import_node_path15.resolve)(root, ...components)).catch(() => null);
41666
41838
  if (!absolutePath || normalizeRelativePath(root, absolutePath) !== normalizedPath) {
41667
41839
  throw new SkillPackageError("INVALID_PATH", `Skill package file was not found: ${path2}`, path2);
41668
41840
  }
@@ -41683,7 +41855,7 @@ async function readSkillPackageFile(packageRoot, path2, expectedSha256) {
41683
41855
  return { file: read.manifest, bytes: read.bytes };
41684
41856
  }
41685
41857
  async function requirePackageRoot(packageRoot) {
41686
- const root = await (0, import_promises.realpath)((0, import_node_path13.resolve)(packageRoot)).catch(() => null);
41858
+ const root = await (0, import_promises.realpath)((0, import_node_path15.resolve)(packageRoot)).catch(() => null);
41687
41859
  if (!root) {
41688
41860
  throw new SkillPackageError("INVALID_PACKAGE_ROOT", "Skill package directory does not exist");
41689
41861
  }
@@ -41709,7 +41881,7 @@ async function walkPackage(root, ignoredPaths) {
41709
41881
  async function walkDirectory(directory) {
41710
41882
  const entries = await (0, import_promises.readdir)(directory, { withFileTypes: true });
41711
41883
  for (const entry of entries) {
41712
- const absolutePath = (0, import_node_path13.resolve)(directory, entry.name);
41884
+ const absolutePath = (0, import_node_path15.resolve)(directory, entry.name);
41713
41885
  const normalizedPath = normalizeRelativePath(root, absolutePath);
41714
41886
  if (isIgnored(normalizedPath, entry.name, entry.isDirectory(), ignored2))
41715
41887
  continue;
@@ -41746,10 +41918,10 @@ function createIgnoreMatcher(path2) {
41746
41918
  const expression = globToRegExp(pattern);
41747
41919
  return (candidate) => expression.test(candidate) || expression.test(`${candidate}/`);
41748
41920
  }
41749
- function isIgnored(normalizedPath, basename7, isDirectory2, configured) {
41750
- if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(basename7))
41921
+ function isIgnored(normalizedPath, basename8, isDirectory2, configured) {
41922
+ if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(basename8))
41751
41923
  return true;
41752
- if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(basename7))
41924
+ if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(basename8))
41753
41925
  return true;
41754
41926
  return configured.some((matches) => matches(normalizedPath));
41755
41927
  }
@@ -41776,12 +41948,12 @@ function globToRegExp(pattern) {
41776
41948
  return new RegExp(`${source2}(?:/.*)?$`);
41777
41949
  }
41778
41950
  function normalizeRelativePath(root, absolutePath) {
41779
- const nativeRelativePath = (0, import_node_path13.relative)(root, absolutePath);
41780
- if (!nativeRelativePath || nativeRelativePath.startsWith(`..${import_node_path13.sep}`) || nativeRelativePath === "..") {
41951
+ const nativeRelativePath = (0, import_node_path15.relative)(root, absolutePath);
41952
+ if (!nativeRelativePath || nativeRelativePath.startsWith(`..${import_node_path15.sep}`) || nativeRelativePath === "..") {
41781
41953
  throw new SkillPackageError("INVALID_PATH", "Skill package path escapes its root");
41782
41954
  }
41783
- const normalized2 = nativeRelativePath.split(import_node_path13.sep).join("/").normalize("NFC");
41784
- if (normalized2.includes("\0") || normalized2.includes("\uFFFD") || import_node_path13.posix.isAbsolute(normalized2)) {
41955
+ const normalized2 = nativeRelativePath.split(import_node_path15.sep).join("/").normalize("NFC");
41956
+ if (normalized2.includes("\0") || normalized2.includes("\uFFFD") || import_node_path15.posix.isAbsolute(normalized2)) {
41785
41957
  throw new SkillPackageError("INVALID_PATH", `Invalid Skill package path: ${normalized2}`);
41786
41958
  }
41787
41959
  return normalized2;
@@ -41816,7 +41988,7 @@ function requireSafeFile(path2, size, normalizedPaths) {
41816
41988
  }
41817
41989
  }
41818
41990
  function isSecretPath(path2) {
41819
- const name = import_node_path13.posix.basename(path2).toLowerCase();
41991
+ const name = import_node_path15.posix.basename(path2).toLowerCase();
41820
41992
  if (SECRET_BASENAMES.has(name) || name.startsWith(".env."))
41821
41993
  return true;
41822
41994
  return name.endsWith(".private-key.pem") || name.endsWith(".private-key.key");
@@ -41844,12 +42016,12 @@ function classifyFileKind(path2) {
41844
42016
  return "reference";
41845
42017
  if (path2.startsWith("assets/"))
41846
42018
  return "asset";
41847
- if (/^(?:licen[cs]e|copying|notice)(?:\.|$)/i.test(import_node_path13.posix.basename(path2)))
42019
+ if (/^(?:licen[cs]e|copying|notice)(?:\.|$)/i.test(import_node_path15.posix.basename(path2)))
41848
42020
  return "license";
41849
42021
  return "other";
41850
42022
  }
41851
42023
  function classifyPreview(path2, bytes) {
41852
- const extension = import_node_path13.posix.extname(path2).toLowerCase();
42024
+ const extension = import_node_path15.posix.extname(path2).toLowerCase();
41853
42025
  if (IMAGE_EXTENSIONS.has(extension))
41854
42026
  return "image";
41855
42027
  if (bytes.includes(0))
@@ -41953,7 +42125,7 @@ function normalizePackageReference(value2) {
41953
42125
  const withoutSuffix = trimmed4.split(/[?#]/, 1)[0];
41954
42126
  if (!withoutSuffix)
41955
42127
  return null;
41956
- const normalized2 = import_node_path13.posix.normalize(withoutSuffix).replace(/^\.\//, "").normalize("NFC");
42128
+ const normalized2 = import_node_path15.posix.normalize(withoutSuffix).replace(/^\.\//, "").normalize("NFC");
41957
42129
  if (normalized2 === ".." || normalized2.startsWith("../"))
41958
42130
  return null;
41959
42131
  return normalized2;
@@ -41965,7 +42137,7 @@ function comparePackageFiles(left, right) {
41965
42137
  return import_node_buffer.Buffer.compare(import_node_buffer.Buffer.from(left.manifest.path, "utf8"), import_node_buffer.Buffer.from(right.manifest.path, "utf8"));
41966
42138
  }
41967
42139
  function hashPackageTree(files) {
41968
- const hash2 = (0, import_node_crypto4.createHash)("sha256");
42140
+ const hash2 = (0, import_node_crypto5.createHash)("sha256");
41969
42141
  hash2.update(TREE_HASH_PREFIX);
41970
42142
  for (const file2 of files) {
41971
42143
  const path2 = import_node_buffer.Buffer.from(file2.path, "utf8");
@@ -41978,7 +42150,7 @@ function hashPackageTree(files) {
41978
42150
  return `sha256:${hash2.digest("hex")}`;
41979
42151
  }
41980
42152
  function sha256(bytes) {
41981
- return `sha256:${(0, import_node_crypto4.createHash)("sha256").update(bytes).digest("hex")}`;
42153
+ return `sha256:${(0, import_node_crypto5.createHash)("sha256").update(bytes).digest("hex")}`;
41982
42154
  }
41983
42155
  function uint322(value2) {
41984
42156
  const buffer = import_node_buffer.Buffer.allocUnsafe(4);
@@ -42928,7 +43100,7 @@ var LocalSkillSource = class {
42928
43100
  locations = /* @__PURE__ */ new Map();
42929
43101
  inspectionCache = /* @__PURE__ */ new Map();
42930
43102
  async scan(input2) {
42931
- const attemptId = (0, import_node_crypto5.randomUUID)();
43103
+ const attemptId = (0, import_node_crypto6.randomUUID)();
42932
43104
  const diagnostics = [];
42933
43105
  const candidates = [];
42934
43106
  const visitedDirectories = /* @__PURE__ */ new Set();
@@ -43005,9 +43177,9 @@ var LocalSkillSource = class {
43005
43177
  */
43006
43178
  async scanRootAsPackage(resolvedRoot, ignoredPaths, mode) {
43007
43179
  const directory = resolvedRoot.directory;
43008
- if (!await pathExists((0, import_node_path14.join)(directory, "SKILL.md"))) return null;
43180
+ if (!await pathExists((0, import_node_path16.join)(directory, "SKILL.md"))) return null;
43009
43181
  const canonicalRoot = await (0, import_promises2.realpath)(directory).catch(() => directory);
43010
- const name = import_node_path14.default.basename(canonicalRoot);
43182
+ const name = import_node_path16.default.basename(canonicalRoot);
43011
43183
  try {
43012
43184
  const fingerprint = await fingerprintPackage(canonicalRoot);
43013
43185
  const ignoreSignature = JSON.stringify(ignoredPaths);
@@ -43077,7 +43249,7 @@ var LocalSkillSource = class {
43077
43249
  );
43078
43250
  for (const entry of entries) {
43079
43251
  if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
43080
- const candidatePath = (0, import_node_path14.join)(resolvedRoot.directory, entry.name);
43252
+ const candidatePath = (0, import_node_path16.join)(resolvedRoot.directory, entry.name);
43081
43253
  const canonicalPath = await (0, import_promises2.realpath)(candidatePath).catch(() => null);
43082
43254
  if (!canonicalPath) {
43083
43255
  diagnostics.push({
@@ -43135,7 +43307,7 @@ var LocalSkillSource = class {
43135
43307
  }
43136
43308
  };
43137
43309
  async function fingerprintPackage(root) {
43138
- const hash2 = (0, import_node_crypto5.createHash)("sha256").update("alan-skill-stat-fingerprint-v1\0");
43310
+ const hash2 = (0, import_node_crypto6.createHash)("sha256").update("alan-skill-stat-fingerprint-v1\0");
43139
43311
  await visit2(root, "");
43140
43312
  return `sha256:${hash2.digest("hex")}`;
43141
43313
  async function visit2(directory, relativeDirectory) {
@@ -43143,7 +43315,7 @@ async function fingerprintPackage(root) {
43143
43315
  entries.sort((left, right) => import_node_buffer2.Buffer.compare(import_node_buffer2.Buffer.from(left.name), import_node_buffer2.Buffer.from(right.name)));
43144
43316
  for (const entry of entries) {
43145
43317
  const path2 = relativeDirectory ? `${relativeDirectory}/${entry.name}` : entry.name;
43146
- const absolutePath = (0, import_node_path14.join)(directory, entry.name);
43318
+ const absolutePath = (0, import_node_path16.join)(directory, entry.name);
43147
43319
  const metadata = await (0, import_promises2.lstat)(absolutePath);
43148
43320
  hash2.update(path2.normalize("NFC")).update("\0").update(
43149
43321
  entry.isDirectory() ? "d" : entry.isFile() ? "f" : entry.isSymbolicLink() ? "l" : "o"
@@ -43168,12 +43340,12 @@ async function canonicalDirectories(directories) {
43168
43340
  return [...new Set(canonical)];
43169
43341
  }
43170
43342
  function isWithinDirectory2(parent, candidate) {
43171
- const path2 = (0, import_node_path14.relative)(parent, candidate);
43172
- return path2 !== ".." && !path2.startsWith(`..${import_node_path14.sep}`) && !(0, import_node_path14.isAbsolute)(path2);
43343
+ const path2 = (0, import_node_path16.relative)(parent, candidate);
43344
+ return path2 !== ".." && !path2.startsWith(`..${import_node_path16.sep}`) && !(0, import_node_path16.isAbsolute)(path2);
43173
43345
  }
43174
43346
  async function loadSkillSourceConfig(homeDirectory2) {
43175
- const configDirectory = (0, import_node_path14.join)(homeDirectory2, ".alan");
43176
- const configPath = (0, import_node_path14.join)(configDirectory, "config.toml");
43347
+ const configDirectory = (0, import_node_path16.join)(homeDirectory2, ".alan");
43348
+ const configPath = (0, import_node_path16.join)(configDirectory, "config.toml");
43177
43349
  await (0, import_promises2.mkdir)(configDirectory, { recursive: true, mode: 448 });
43178
43350
  let created = false;
43179
43351
  try {
@@ -43207,7 +43379,7 @@ async function resolveSkillScanInput(homeDirectory2, declared) {
43207
43379
  }
43208
43380
  const { config: config4 } = loaded;
43209
43381
  if (!config4.enabled) return { ...declared, roots: [], ignoredPaths: config4.ignoredPaths };
43210
- const draftsPath = (0, import_node_path14.resolve)((0, import_node_path14.join)(homeDirectory2, ".alan", "skill-sources"));
43382
+ const draftsPath = (0, import_node_path16.resolve)((0, import_node_path16.join)(homeDirectory2, ".alan", "skill-sources"));
43211
43383
  const enabledProviders = new Set(declared.enabledProviderKinds ?? []);
43212
43384
  const configured = [];
43213
43385
  for (const source2 of config4.sources) {
@@ -43215,7 +43387,7 @@ async function resolveSkillScanInput(homeDirectory2, declared) {
43215
43387
  continue;
43216
43388
  }
43217
43389
  configured.push(
43218
- (0, import_node_path14.resolve)(source2.path) === draftsPath ? { kind: "drafts", path: source2.path, label: "Alan drafts" } : {
43390
+ (0, import_node_path16.resolve)(source2.path) === draftsPath ? { kind: "drafts", path: source2.path, label: "Alan drafts" } : {
43219
43391
  kind: "configured",
43220
43392
  declarationId: source2.declarationId,
43221
43393
  path: source2.path,
@@ -43261,7 +43433,7 @@ function parseSkillSourceConfig(content, homeDirectory2) {
43261
43433
  value2.providers,
43262
43434
  `skills.sources[${index}].providers`
43263
43435
  );
43264
- const relativeDirectory = import_node_path14.default.relative(homeDirectory2, sourcePath);
43436
+ const relativeDirectory = import_node_path16.default.relative(homeDirectory2, sourcePath);
43265
43437
  const inferredProviders = providerKindsForUserDirectory(relativeDirectory);
43266
43438
  const declaredProviders = value2.providers === void 0 ? inferredProviders : [...new Set(explicitProviders.map((provider) => provider.trim()).filter(Boolean))];
43267
43439
  const stale = staleCodexDeclaration(relativeDirectory, label, declaredProviders);
@@ -43282,7 +43454,7 @@ function parseSkillSourceConfig(content, homeDirectory2) {
43282
43454
  return { enabled, discoverRepositorySkills, ignoredPaths, sources };
43283
43455
  }
43284
43456
  function stableSourceDeclarationId(sourcePath) {
43285
- const digest = (0, import_node_crypto5.createHash)("sha256").update("alan-skill-source-v1\0").update(sourcePath.normalize("NFC")).digest("hex").slice(0, 24);
43457
+ const digest = (0, import_node_crypto6.createHash)("sha256").update("alan-skill-source-v1\0").update(sourcePath.normalize("NFC")).digest("hex").slice(0, 24);
43286
43458
  return `source-${digest}`;
43287
43459
  }
43288
43460
  function requiredSourceId(value2, field) {
@@ -43291,7 +43463,7 @@ function requiredSourceId(value2, field) {
43291
43463
  }
43292
43464
  return value2;
43293
43465
  }
43294
- function resolveSkillSourcePath(sourcePath, homeDirectory2, pathApi = import_node_path14.default) {
43466
+ function resolveSkillSourcePath(sourcePath, homeDirectory2, pathApi = import_node_path16.default) {
43295
43467
  const trimmed4 = sourcePath.trim();
43296
43468
  if (trimmed4 === "~") return pathApi.resolve(homeDirectory2);
43297
43469
  if (trimmed4.startsWith("~/") || trimmed4.startsWith("~\\")) {
@@ -43321,7 +43493,7 @@ function resolveScanRoots(roots, enabledProviderKinds) {
43321
43493
  ).entries()) {
43322
43494
  resolved.push({
43323
43495
  root,
43324
- directory: (0, import_node_path14.join)(root.path, relativeDirectory),
43496
+ directory: (0, import_node_path16.join)(root.path, relativeDirectory),
43325
43497
  order: `1:${root.repositoryId}:${String(index).padStart(2, "0")}`
43326
43498
  });
43327
43499
  }
@@ -43343,11 +43515,11 @@ function candidateOrigin(root) {
43343
43515
  }
43344
43516
  function createLocalKey(root, skillName) {
43345
43517
  const rootIdentity = root.kind === "configured" ? `configured:${root.declarationId}` : root.kind === "repository" ? `repository:${root.repositoryId}` : "drafts";
43346
- const digest = (0, import_node_crypto5.createHash)("sha256").update("alan-local-skill-v1\0").update(rootIdentity).update("\0").update(skillName.normalize("NFC")).digest("hex");
43518
+ const digest = (0, import_node_crypto6.createHash)("sha256").update("alan-local-skill-v1\0").update(rootIdentity).update("\0").update(skillName.normalize("NFC")).digest("hex");
43347
43519
  return `local:${digest}`;
43348
43520
  }
43349
43521
  function hashInventory(candidates) {
43350
- const hash2 = (0, import_node_crypto5.createHash)("sha256");
43522
+ const hash2 = (0, import_node_crypto6.createHash)("sha256");
43351
43523
  hash2.update("alan-skill-inventory-v1\0");
43352
43524
  for (const candidate of candidates) {
43353
43525
  hash2.update(candidate.localKey);
@@ -43380,7 +43552,7 @@ async function pathExists(candidate) {
43380
43552
  }
43381
43553
  async function hasManagedMarker(directory) {
43382
43554
  try {
43383
- await (0, import_promises2.access)((0, import_node_path14.join)(directory, ".alan-managed.json"));
43555
+ await (0, import_promises2.access)((0, import_node_path16.join)(directory, ".alan-managed.json"));
43384
43556
  return true;
43385
43557
  } catch {
43386
43558
  return false;
@@ -43401,7 +43573,7 @@ function isAlreadyPresent(error61) {
43401
43573
  }
43402
43574
 
43403
43575
  // src/ws/host.ts
43404
- var import_node_crypto6 = require("crypto");
43576
+ var import_node_crypto7 = require("crypto");
43405
43577
 
43406
43578
  // ../agent-core/dist/index.js
43407
43579
  var import_crypto = require("crypto");
@@ -43425,12 +43597,12 @@ var TRANSCRIPT_LIVE_DELIVERY_HEADER = "x-alan-transcript-delivery";
43425
43597
 
43426
43598
  // ../shared/dist/node/local-workspace.js
43427
43599
  var import_node_fs12 = require("fs");
43428
- var import_node_os12 = require("os");
43429
- var import_node_path15 = require("path");
43430
- function resolveAlanDefaultWorkspacePath(homeDirectory2 = (0, import_node_os12.homedir)()) {
43431
- return (0, import_node_path15.join)(homeDirectory2, ".alan", "workspace");
43600
+ var import_node_os13 = require("os");
43601
+ var import_node_path17 = require("path");
43602
+ function resolveAlanDefaultWorkspacePath(homeDirectory2 = (0, import_node_os13.homedir)()) {
43603
+ return (0, import_node_path17.join)(homeDirectory2, ".alan", "workspace");
43432
43604
  }
43433
- function ensureAlanDefaultWorkspace(homeDirectory2 = (0, import_node_os12.homedir)()) {
43605
+ function ensureAlanDefaultWorkspace(homeDirectory2 = (0, import_node_os13.homedir)()) {
43434
43606
  const workspacePath = resolveAlanDefaultWorkspacePath(homeDirectory2);
43435
43607
  (0, import_node_fs12.mkdirSync)(workspacePath, { recursive: true });
43436
43608
  return workspacePath;
@@ -43500,13 +43672,21 @@ var import_path14 = require("path");
43500
43672
  var import_fs15 = require("fs");
43501
43673
  var import_os7 = require("os");
43502
43674
  var import_path15 = require("path");
43675
+ var import_crypto8 = require("crypto");
43503
43676
  var import_fs16 = require("fs");
43504
43677
  var import_os8 = require("os");
43505
43678
  var import_path16 = require("path");
43506
- var import_child_process7 = require("child_process");
43507
43679
  var import_fs17 = require("fs");
43508
43680
  var import_os9 = require("os");
43509
43681
  var import_path17 = require("path");
43682
+ var import_crypto9 = require("crypto");
43683
+ var import_fs18 = require("fs");
43684
+ var import_os10 = require("os");
43685
+ var import_path18 = require("path");
43686
+ var import_child_process7 = require("child_process");
43687
+ var import_fs19 = require("fs");
43688
+ var import_os11 = require("os");
43689
+ var import_path19 = require("path");
43510
43690
  function createGrammarState() {
43511
43691
  return { seenToolCallIds: /* @__PURE__ */ new Set(), counter: 0, scratch: {} };
43512
43692
  }
@@ -43958,6 +44138,7 @@ var CLI_PROBLEM_CODE_BY_ERROR_KIND = {
43958
44138
  provider_error: "cli.unknown",
43959
44139
  subagent_parent_exited: "cli.process.nonzero_exit",
43960
44140
  tool_call_invalid: "cli.tool.failed",
44141
+ turn_limit: "cli.process.nonzero_exit",
43961
44142
  unknown_cli_error: "cli.unknown"
43962
44143
  };
43963
44144
  function createCliProblem(classified, options) {
@@ -44028,15 +44209,15 @@ var ERROR_SPECS = {
44028
44209
  recoveryClass: "user_fixable"
44029
44210
  },
44030
44211
  rate_limited: {
44031
- message: "Rate limited by the provider. Retrying automatically shortly.",
44212
+ message: "Rate limited by the provider. Wait a moment, then send your message again.",
44032
44213
  recoveryClass: "auto_recovering"
44033
44214
  },
44034
44215
  overloaded: {
44035
- message: "The provider is overloaded. Retrying automatically.",
44216
+ message: "The provider is overloaded right now. Wait a moment or pick a different model, then send your message again.",
44036
44217
  recoveryClass: "auto_recovering"
44037
44218
  },
44038
44219
  network: {
44039
- message: "Network connection failed. Check your internet connection \u2014 retrying automatically.",
44220
+ message: "Network connection failed. Check your internet connection, then send your message again.",
44040
44221
  recoveryClass: "auto_recovering"
44041
44222
  },
44042
44223
  provider_timeout: {
@@ -44075,6 +44256,10 @@ var ERROR_SPECS = {
44075
44256
  message: "The agent made an invalid tool call (for example, referencing a file that doesn't exist) and the run stopped. Send your message again \u2014 it usually succeeds on retry.",
44076
44257
  recoveryClass: "retry"
44077
44258
  },
44259
+ turn_limit: {
44260
+ message: "The agent reached its turn limit and stopped before finishing. Send Continue to pick up where it left off.",
44261
+ recoveryClass: "retry"
44262
+ },
44078
44263
  unknown_cli_error: {
44079
44264
  message: "The agent stopped unexpectedly. Send your message again to retry.",
44080
44265
  recoveryClass: "retry"
@@ -44125,6 +44310,13 @@ function normalizeCodexCliErrorMessage(message) {
44125
44310
  }
44126
44311
  return message;
44127
44312
  }
44313
+ function lineContaining(text2, pattern) {
44314
+ return text2.split("\n").map((line) => line.trim()).find((line) => pattern.test(line));
44315
+ }
44316
+ function lastMeaningfulLine(text2) {
44317
+ const lines = text2.split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !/^at\s/.test(line));
44318
+ return lines.at(-1) ?? "";
44319
+ }
44128
44320
  var NAMED_SESSION_NOT_FOUND = /\b(?:session|chat|conversation)\s+(?:"[^"\n]{1,160}"|'[^'\n]{1,160}'|[\w-]{6,})\s+not found\b/;
44129
44321
  function classifyCliErrorDetailed(stderr, exitCode, opts) {
44130
44322
  const normalizedCodexError = normalizeCodexCliErrorMessage(stderr);
@@ -44141,6 +44333,8 @@ function classifyCliErrorDetailed(stderr, exitCode, opts) {
44141
44333
  if (has("codex cli connection expired", "reconnect openai codex"))
44142
44334
  return specForErrorKind("auth_expired");
44143
44335
  if (has("codex connection to openai timed out")) return specForErrorKind("provider_timeout");
44336
+ if (has("reached maximum conversation turns", "reached maximum number of turns", "error_max_turns"))
44337
+ return specForErrorKind("turn_limit");
44144
44338
  if (has("authentication required", "not authenticated"))
44145
44339
  return specForErrorKind("not_authenticated");
44146
44340
  if (has(
@@ -44216,10 +44410,17 @@ function classifyCliErrorDetailed(stderr, exitCode, opts) {
44216
44410
  "requires a paid"
44217
44411
  ))
44218
44412
  return specForErrorKind("subscription_required");
44219
- if (has("quota exceeded", "quota limit", "daily limit", "monthly limit", "usage limit"))
44413
+ if (has("usage limit", "usage_limit_exceeded"))
44414
+ return {
44415
+ ...specForErrorKind("usage_limit"),
44416
+ message: lineContaining(stderr, /usage limit/i) ?? ERROR_SPECS.usage_limit.message
44417
+ };
44418
+ if (has("quota exceeded", "quota limit", "daily limit", "monthly limit"))
44220
44419
  return specForErrorKind("quota_exceeded");
44221
44420
  if (has(
44222
44421
  "overloaded",
44422
+ "at capacity",
44423
+ "server_overloaded",
44223
44424
  "http 500",
44224
44425
  "[500]",
44225
44426
  "status 500",
@@ -44257,7 +44458,7 @@ function classifyCliErrorDetailed(stderr, exitCode, opts) {
44257
44458
  if (has("out of memory", "enomem")) return specForErrorKind("out_of_memory");
44258
44459
  if (has("invalid tool call error", "declaring permissions:"))
44259
44460
  return specForErrorKind("tool_call_invalid");
44260
- const raw = stderr.trim().slice(0, 200);
44461
+ const raw = lastMeaningfulLine(stderr).slice(0, 200);
44261
44462
  if (raw) {
44262
44463
  return { message: raw, errorKind: "unknown_cli_error", recoveryClass: "unknown" };
44263
44464
  }
@@ -44860,15 +45061,19 @@ function timeoutProblem(closing, message, phase) {
44860
45061
  }
44861
45062
  );
44862
45063
  }
45064
+ var FRESH_SESSION_ON_RESUME_MISS = /* @__PURE__ */ new Set([
45065
+ "cursor_agent_cli",
45066
+ "antigravity_cli"
45067
+ ]);
44863
45068
  function detectSilentResumeFork(closing) {
44864
45069
  const { options, context, state } = closing;
44865
45070
  const requestedResumeId = context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim();
44866
45071
  if (!requestedResumeId || !state.runtimeSessionId) return false;
44867
45072
  if (state.runtimeSessionId === requestedResumeId) return false;
44868
45073
  console.warn(
44869
- `[${options.kind}] CLI reported session id ${state.runtimeSessionId} after resume was requested with ${requestedResumeId} \u2014 expected for claude session forks, a failed-resume signal for cursor-agent`
45074
+ `[${options.kind}] CLI reported session id ${state.runtimeSessionId} after resume was requested with ${requestedResumeId} \u2014 expected for claude session forks, a failed-resume signal for cursor-agent and antigravity`
44870
45075
  );
44871
- if (options.kind !== "cursor_agent_cli") return false;
45076
+ if (!FRESH_SESSION_ON_RESUME_MISS.has(options.kind)) return false;
44872
45077
  logResumeObservability("agent_resume_failed", {
44873
45078
  backendKind: options.kind,
44874
45079
  reason: "cli_forked_fresh_session",
@@ -45080,6 +45285,7 @@ function resumeFailedResult(closing) {
45080
45285
  state
45081
45286
  );
45082
45287
  }
45288
+ var SUMMARY_ERROR_SIGNAL_MAX_CHARS = 300;
45083
45289
  function explainFailure(closing, verdict) {
45084
45290
  const { state, observed } = closing;
45085
45291
  if (state.errorKind && state.error?.trim()) {
@@ -45100,10 +45306,15 @@ function explainFailure(closing, verdict) {
45100
45306
  recoveryClass: "retry"
45101
45307
  };
45102
45308
  }
45309
+ const summary = state.summary.trim();
45103
45310
  const detailed = classifyCliErrorDetailed(
45104
45311
  state.error?.trim() || observed.stderrTail.trim() || "",
45105
45312
  observed.exit.exitCode ?? 1,
45106
- { extraSignals: state.summary ? [state.summary] : void 0 }
45313
+ // A provider error echoed as assistant text is one short line; a partial answer that says
45314
+ // "network" or "API key" in passing must not decide the failure kind.
45315
+ {
45316
+ extraSignals: summary && summary.length <= SUMMARY_ERROR_SIGNAL_MAX_CHARS ? [summary] : void 0
45317
+ }
45107
45318
  );
45108
45319
  return {
45109
45320
  error: detailed.message,
@@ -45875,7 +46086,8 @@ function createCliBackend(options) {
45875
46086
  process: null,
45876
46087
  iterations: 0,
45877
46088
  summary: "",
45878
- runStartedAtMs: Date.now()
46089
+ runStartedAtMs: Date.now(),
46090
+ ...options.initialSessionId ? { runtimeSessionId: options.initialSessionId } : {}
45879
46091
  };
45880
46092
  const prompt = resolvePrompt(options, context);
45881
46093
  const supervisor = new CliProcessSupervisor(options, context, state);
@@ -48370,7 +48582,7 @@ function formatResults(results) {
48370
48582
  }
48371
48583
 
48372
48584
  /** Mirrors the harness CLI: say what the agent can do next instead of just failing. */
48373
- function describeRefusal(refusal, status, text) {
48585
+ function describeRefusalAction(refusal, status, text) {
48374
48586
  const code = refusal && typeof refusal.error === "string" ? refusal.error : "";
48375
48587
  const message = refusal && typeof refusal.message === "string" ? refusal.message : truncate(text, 300);
48376
48588
  const reset = refusal && typeof refusal.resetsAt === "string" ? refusal.resetsAt.slice(0, 10) : "";
@@ -48389,12 +48601,26 @@ function describeRefusal(refusal, status, text) {
48389
48601
  return "Web search failed (" + status + "): " + message;
48390
48602
  }
48391
48603
 
48604
+ /** The correlation id turns "something went wrong" into a log line an operator can open. */
48605
+ function describeRefusal(refusal, status, text) {
48606
+ const described = describeRefusalAction(refusal, status, text);
48607
+ const ref =
48608
+ refusal && typeof refusal.requestId === "string" && refusal.requestId
48609
+ ? " [ref: " + refusal.requestId + "]"
48610
+ : "";
48611
+ return described + ref;
48612
+ }
48613
+
48392
48614
  async function callWebSearch(query, signal) {
48393
48615
  const apiKey = process.env[API_KEY_ENV];
48394
48616
  if (!apiKey) {
48395
48617
  return { title: "web_search unavailable", output: "Web search is unavailable: this run has no Alan credential." };
48396
48618
  }
48397
- const headers = { Authorization: "Bearer " + apiKey, "Content-Type": "application/json" };
48619
+ const headers = {
48620
+ Authorization: "Bearer " + apiKey,
48621
+ "Content-Type": "application/json",
48622
+ "x-request-id": crypto.randomUUID(),
48623
+ };
48398
48624
  if (process.env[RUN_ID_ENV]) headers["x-alan-run-id"] = process.env[RUN_ID_ENV];
48399
48625
 
48400
48626
  for (let attempt = 0; ; attempt += 1) {
@@ -49006,15 +49232,15 @@ var antigravityTextGrammar = {
49006
49232
  `)];
49007
49233
  }
49008
49234
  };
49009
- var config2 = (input2) => input2.context.config;
49235
+ var config3 = (input2) => input2.context.config;
49010
49236
  var settings = (input2) => input2.context.config.antigravity;
49011
- var selectedModel = (input2) => trimmedOrUndefined(config2(input2).selectedModel);
49237
+ var selectedModel = (input2) => trimmedOrUndefined(config3(input2).selectedModel);
49012
49238
  var selectedEffort = (input2) => {
49013
- const level = trimmedOrUndefined(config2(input2).selectedEffortLevel)?.toLowerCase();
49239
+ const level = trimmedOrUndefined(config3(input2).selectedEffortLevel)?.toLowerCase();
49014
49240
  if (!selectedModel(input2) || !level || !isEffortLevel(level)) return void 0;
49015
49241
  return level;
49016
49242
  };
49017
- var resumeId = (input2) => trimmedOrUndefined(config2(input2).runtimeSessionId) ?? trimmedOrUndefined(config2(input2).providerSessionId);
49243
+ var resumeId = (input2) => trimmedOrUndefined(config3(input2).runtimeSessionId) ?? trimmedOrUndefined(config3(input2).providerSessionId);
49018
49244
  var workspacePaths = (input2) => [
49019
49245
  ...new Set(
49020
49246
  (settings(input2)?.additionalWorkspacePaths ?? []).map((p) => p.trim()).filter(Boolean)
@@ -52260,7 +52486,9 @@ var turnCompleted = (event) => {
52260
52486
  };
52261
52487
  var taskComplete = (event) => {
52262
52488
  const last = asString(event.last_agent_message);
52489
+ const error61 = asRecord(event.error);
52263
52490
  return [
52491
+ ...errorNotice3(errorMessage(error61?.message)),
52264
52492
  {
52265
52493
  sessionUpdate: "state_update",
52266
52494
  state: "idle",
@@ -52947,8 +53175,8 @@ var CODEX_EVENTS = /* @__PURE__ */ new Map([
52947
53175
  ],
52948
53176
  [
52949
53177
  "task_complete",
52950
- (_event, _context, state) => {
52951
- clearRecoveredCodexError(state);
53178
+ (event, _context, state) => {
53179
+ if (!recordFailedCodexTurn(event, state)) clearRecoveredCodexError(state);
52952
53180
  completeCodexTurnRespectingWorkers(state);
52953
53181
  }
52954
53182
  ],
@@ -53003,6 +53231,24 @@ function beginCodexTurn(state, family) {
53003
53231
  function clearRecoveredCodexError(state) {
53004
53232
  state.error = void 0;
53005
53233
  }
53234
+ var ERROR_KIND_BY_CODEX_ERROR_INFO = /* @__PURE__ */ new Map([
53235
+ ["server_overloaded", "overloaded"],
53236
+ ["usage_limit_exceeded", "usage_limit"],
53237
+ ["context_window_exceeded", "context_length"]
53238
+ ]);
53239
+ function recordFailedCodexTurn(event, state) {
53240
+ const error61 = asRecord(event.error);
53241
+ const message = normalizeCodexCliErrorMessage(asString(error61?.message).trim());
53242
+ if (!error61 || !message) return false;
53243
+ const info = asString(error61.codex_error_info).trim();
53244
+ const knownKind = ERROR_KIND_BY_CODEX_ERROR_INFO.get(info);
53245
+ const classified = knownKind ? { ...specForErrorKind(knownKind), message } : classifyCliErrorDetailed(message, 1);
53246
+ state.error = classified.message;
53247
+ state.errorKind = classified.errorKind;
53248
+ state.recoveryClass = classified.recoveryClass;
53249
+ if (info) state.providerErrorCode = info;
53250
+ return true;
53251
+ }
53006
53252
  function handleCollabToolCall(context, state, item, completed, updates) {
53007
53253
  const itemId = asString(item.id);
53008
53254
  const tool = asString(item.tool);
@@ -53115,11 +53361,11 @@ function buildCodexExternalMcpArgs(servers) {
53115
53361
  ([name, server]) => server.type === "stdio" ? codexStdioServerArgs(`mcp_servers.${name}`, server) : codexRemoteServerArgs(`mcp_servers.${name}`, server)
53116
53362
  );
53117
53363
  }
53118
- var config3 = (input2) => input2.context.config;
53119
- var permissions = (input2) => getCodexPermissionArgs(config3(input2));
53120
- var baseModel2 = (input2) => collapseModelIdToBase(trimmedOrUndefined(config3(input2).selectedModel) ?? "");
53364
+ var config32 = (input2) => input2.context.config;
53365
+ var permissions = (input2) => getCodexPermissionArgs(config32(input2));
53366
+ var baseModel2 = (input2) => collapseModelIdToBase(trimmedOrUndefined(config32(input2).selectedModel) ?? "");
53121
53367
  var model = (input2) => baseModel2(input2) || void 0;
53122
- var effort2 = (input2) => buildCodexEffortArgs(config3(input2).selectedEffortLevel, { modelId: baseModel2(input2) });
53368
+ var effort2 = (input2) => buildCodexEffortArgs(config32(input2).selectedEffortLevel, { modelId: baseModel2(input2) });
53123
53369
  var overrides = (input2) => input2.configOverrides;
53124
53370
  var resuming = (input2) => Boolean(input2.resumeId);
53125
53371
  var resumeTarget = (input2) => input2.resumeId ? [input2.resumeId] : [];
@@ -53689,6 +53935,7 @@ function usageModel(context, state) {
53689
53935
  const selected = context.config.selectedModel;
53690
53936
  return state.activeModel || (typeof selected === "string" && selected.trim() ? selected : "command-code");
53691
53937
  }
53938
+ var COMMAND_CODE_MAX_TURNS = 1e4;
53692
53939
  function commandCodePermissionArgs(config4) {
53693
53940
  if (shouldUseReadOnlyRuntimePermissions(config4)) {
53694
53941
  if (config4.mode === "plan" || config4.mode === "review") return ["--plan"];
@@ -53727,6 +53974,8 @@ function createCommandCodeCliBackend(command = "command-code", defaultArgs = [])
53727
53974
  "--skip-onboarding",
53728
53975
  "--trust",
53729
53976
  "--no-auto-update",
53977
+ "--max-turns",
53978
+ String(COMMAND_CODE_MAX_TURNS),
53730
53979
  ...commandCodePermissionArgs(ctx.config),
53731
53980
  ...defaultArgs
53732
53981
  ];
@@ -54253,6 +54502,55 @@ function writeCopilotMcpConfig(registration) {
54253
54502
  );
54254
54503
  return { path: path2, cleanup: () => (0, import_fs15.rmSync)(dir, { recursive: true, force: true }) };
54255
54504
  }
54505
+ function resolveCopilotHome(env) {
54506
+ return env.COPILOT_HOME || (0, import_path16.join)(env.HOME || (0, import_os8.homedir)(), ".copilot");
54507
+ }
54508
+ function copilotSessionPresence(sessionId, home) {
54509
+ const stateRoot = (0, import_path16.join)(home, "session-state");
54510
+ if (!(0, import_fs16.existsSync)(stateRoot)) return "unknown";
54511
+ return (0, import_fs16.existsSync)((0, import_path16.join)(stateRoot, sessionId, "events.jsonl")) ? "present" : "missing";
54512
+ }
54513
+ function freshSession(contextPrefix) {
54514
+ const sessionId = (0, import_crypto8.randomUUID)();
54515
+ return {
54516
+ sessionId,
54517
+ sessionArgs: [`--session-id=${sessionId}`],
54518
+ resumed: false,
54519
+ ...contextPrefix ? { contextPrefix } : {}
54520
+ };
54521
+ }
54522
+ function planCopilotSession(context) {
54523
+ const requestedResumeId = context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim();
54524
+ if (!requestedResumeId) return freshSession();
54525
+ const presence = copilotSessionPresence(requestedResumeId, resolveCopilotHome(context.env));
54526
+ if (presence !== "missing") {
54527
+ logResumeObservability("agent_resume_requested", {
54528
+ backendKind: "copilot_cli",
54529
+ requestedResumeId
54530
+ });
54531
+ return {
54532
+ sessionId: requestedResumeId,
54533
+ sessionArgs: [`--resume=${requestedResumeId}`],
54534
+ resumed: true
54535
+ };
54536
+ }
54537
+ const contextPrefix = context.config.resumeFallbackContext?.trim() || void 0;
54538
+ logResumeObservability("agent_resume_fallback_used", {
54539
+ backendKind: "copilot_cli",
54540
+ reason: "session_state_missing",
54541
+ requestedResumeId,
54542
+ hadFallbackContext: Boolean(contextPrefix)
54543
+ });
54544
+ emitSessionUpdate(
54545
+ noticeUpdate(
54546
+ "warning",
54547
+ "session_resume_failed",
54548
+ contextPrefix ? "The previous Copilot session was not found on this machine, so a fresh session was started with the recent conversation history re-included." : "The previous Copilot session was not found on this machine, so a fresh session was started. Earlier conversation context may be missing from this reply."
54549
+ ),
54550
+ context
54551
+ );
54552
+ return freshSession(contextPrefix);
54553
+ }
54256
54554
  function buildCopilotCliArgs(context, prompt, defaultArgs = [], options = {}) {
54257
54555
  const args = [
54258
54556
  "--yolo",
@@ -54284,6 +54582,7 @@ function buildCopilotCliArgs(context, prompt, defaultArgs = [], options = {}) {
54284
54582
  if (options.additionalMcpConfigPath) {
54285
54583
  args.push("--additional-mcp-config", `@${options.additionalMcpConfigPath}`);
54286
54584
  }
54585
+ if (options.sessionArgs) args.push(...options.sessionArgs);
54287
54586
  args.push("-p", prompt);
54288
54587
  return [...args, ...defaultArgs];
54289
54588
  }
@@ -54297,20 +54596,36 @@ function createCopilotCliBackend(command = "copilot", defaultArgs = []) {
54297
54596
  context.cwd
54298
54597
  );
54299
54598
  const mcpConfig = writeCopilotMcpConfig(context.config.alanMcp);
54599
+ const session = planCopilotSession(context);
54600
+ const runContext = session.resumed ? context : {
54601
+ ...context,
54602
+ config: {
54603
+ ...context.config,
54604
+ runtimeSessionId: void 0,
54605
+ providerSessionId: void 0
54606
+ }
54607
+ };
54300
54608
  try {
54301
54609
  return await createCliBackend({
54302
54610
  kind: "copilot_cli",
54303
54611
  supportTier: "structured",
54304
54612
  command,
54305
54613
  args: [],
54614
+ initialSessionId: session.sessionId,
54306
54615
  buildArgs: (ctx, prompt) => buildCopilotCliArgs(ctx, prompt, defaultArgs, {
54307
- additionalMcpConfigPath: mcpConfig?.path
54616
+ additionalMcpConfigPath: mcpConfig?.path,
54617
+ sessionArgs: session.sessionArgs
54308
54618
  }),
54309
- augmentPrompt: (ctx) => buildPromptWithImagePathReferences(ctx, imageFiles),
54619
+ augmentPrompt: (ctx) => {
54620
+ const prompt = buildPromptWithImagePathReferences(ctx, imageFiles);
54621
+ return session.contextPrefix ? `${session.contextPrefix}
54622
+
54623
+ ${prompt}` : prompt;
54624
+ },
54310
54625
  parseStructuredLine: grammarAsStructuredLineParser(copilotGrammar, copilotEffects),
54311
54626
  // Held open so a deferred `result` can wait for background work to drain.
54312
54627
  keepStdinOpen: true
54313
- }).run(context);
54628
+ }).run(runContext);
54314
54629
  } finally {
54315
54630
  mcpConfig?.cleanup();
54316
54631
  cleanup();
@@ -54859,11 +55174,11 @@ function cursorConversationStepText(steps) {
54859
55174
  }
54860
55175
  function cursorTranscriptsRoot(context) {
54861
55176
  const projectKey = context.cwd.replace(/^[/\\]+/, "").replace(/[/\\]+/g, "-");
54862
- const home = context.env.HOME || process.env.HOME || (0, import_os8.homedir)();
54863
- return (0, import_path16.join)(home, ".cursor", "projects", projectKey, "agent-transcripts");
55177
+ const home = context.env.HOME || process.env.HOME || (0, import_os9.homedir)();
55178
+ return (0, import_path17.join)(home, ".cursor", "projects", projectKey, "agent-transcripts");
54864
55179
  }
54865
55180
  function cursorTranscriptPathForAgent(context, agentId) {
54866
- return (0, import_path16.join)(cursorTranscriptsRoot(context), agentId, `${agentId}.jsonl`);
55181
+ return (0, import_path17.join)(cursorTranscriptsRoot(context), agentId, `${agentId}.jsonl`);
54867
55182
  }
54868
55183
  function resolveCursorSubagentTranscriptPath(success2, context) {
54869
55184
  const explicit = success2?.transcriptPath ?? success2?.transcript_path;
@@ -54888,13 +55203,13 @@ function cursorTranscriptUserText(transcriptPath2) {
54888
55203
  }
54889
55204
  function discoverCursorSubagentTranscript(context, state, task) {
54890
55205
  const root = cursorTranscriptsRoot(context);
54891
- if (!(0, import_fs16.existsSync)(root)) return void 0;
55206
+ if (!(0, import_fs17.existsSync)(root)) return void 0;
54892
55207
  const prompt = task.prompt?.trim();
54893
55208
  const description = task.description?.trim().toLowerCase();
54894
55209
  const candidates = [];
54895
55210
  let entries;
54896
55211
  try {
54897
- entries = (0, import_fs16.readdirSync)(root, { withFileTypes: true });
55212
+ entries = (0, import_fs17.readdirSync)(root, { withFileTypes: true });
54898
55213
  } catch {
54899
55214
  return void 0;
54900
55215
  }
@@ -54903,7 +55218,7 @@ function discoverCursorSubagentTranscript(context, state, task) {
54903
55218
  const path2 = cursorTranscriptPathForAgent(context, entry.name);
54904
55219
  let mtimeMs;
54905
55220
  try {
54906
- mtimeMs = (0, import_fs16.statSync)(path2).mtimeMs;
55221
+ mtimeMs = (0, import_fs17.statSync)(path2).mtimeMs;
54907
55222
  } catch {
54908
55223
  continue;
54909
55224
  }
@@ -55220,6 +55535,52 @@ function buildCursorAgentModelArg(modelId, options) {
55220
55535
  if (parsed.fast) return `${id}-fast`;
55221
55536
  return id;
55222
55537
  }
55538
+ function realPathOr(cwd) {
55539
+ try {
55540
+ return (0, import_fs18.realpathSync)(cwd);
55541
+ } catch {
55542
+ return cwd;
55543
+ }
55544
+ }
55545
+ function workspaceKeys(cwd) {
55546
+ return [.../* @__PURE__ */ new Set([realPathOr(cwd), cwd])].map(
55547
+ (path2) => (0, import_crypto9.createHash)("md5").update(path2).digest("hex")
55548
+ );
55549
+ }
55550
+ function cursorChatPresence(query) {
55551
+ const chatsRoot = (0, import_path18.join)(query.home, ".cursor", "chats");
55552
+ if (!(0, import_fs18.existsSync)(chatsRoot)) return "unknown";
55553
+ const found = workspaceKeys(query.cwd).some(
55554
+ (key) => (0, import_fs18.existsSync)((0, import_path18.join)(chatsRoot, key, query.chatId, "store.db"))
55555
+ );
55556
+ return found ? "present" : "missing";
55557
+ }
55558
+ function planCursorResume(context) {
55559
+ const requestedResumeId = context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim();
55560
+ if (!requestedResumeId) return {};
55561
+ const presence = cursorChatPresence({
55562
+ chatId: requestedResumeId,
55563
+ cwd: context.cwd,
55564
+ home: context.env.HOME || (0, import_os10.homedir)()
55565
+ });
55566
+ if (presence !== "missing") return { resumeId: requestedResumeId };
55567
+ const contextPrefix = context.config.resumeFallbackContext?.trim() || void 0;
55568
+ logResumeObservability("agent_resume_fallback_used", {
55569
+ backendKind: "cursor_agent_cli",
55570
+ reason: "chat_store_missing",
55571
+ requestedResumeId,
55572
+ hadFallbackContext: Boolean(contextPrefix)
55573
+ });
55574
+ emitSessionUpdate(
55575
+ noticeUpdate(
55576
+ "warning",
55577
+ "session_resume_failed",
55578
+ contextPrefix ? "The previous Cursor chat was not found on this machine, so a fresh chat was started with the recent conversation history re-included." : "The previous Cursor chat was not found on this machine, so a fresh chat was started. Earlier conversation context may be missing from this reply."
55579
+ ),
55580
+ context
55581
+ );
55582
+ return contextPrefix ? { contextPrefix } : {};
55583
+ }
55223
55584
  function isCursorAgentCliModelId(model2) {
55224
55585
  return model2 === "auto" || /^composer-/.test(model2) || /^gpt-/.test(model2) || /^claude-/.test(model2) || /^gemini-/.test(model2) || /^grok-/.test(model2) || /^kimi-/.test(model2);
55225
55586
  }
@@ -55265,14 +55626,23 @@ function createCursorAgentCliBackend(command = "cursor-agent", defaultArgs = [])
55265
55626
  context.config.alanMcp ? cliSupportsFlag(command, "--approve-mcps", context.env) : Promise.resolve(false),
55266
55627
  cliSupportsFlag(command, "--stream-partial-output", context.env)
55267
55628
  ]);
55268
- const runContext = context.config.alanMcp ? {
55629
+ const resume = planCursorResume(context);
55630
+ const resumeContext = resume.resumeId ? context : {
55269
55631
  ...context,
55632
+ config: {
55633
+ ...context.config,
55634
+ runtimeSessionId: void 0,
55635
+ providerSessionId: void 0
55636
+ }
55637
+ };
55638
+ const runContext = context.config.alanMcp ? {
55639
+ ...resumeContext,
55270
55640
  env: {
55271
- ...context.env,
55641
+ ...resumeContext.env,
55272
55642
  [ALAN_MCP_AUTHORIZATION_ENV]: requireManagedAuthorization(context.config.alanMcp),
55273
55643
  [ALAN_RUN_ID_ENV]: requireManagedRunId(context.config.alanMcp)
55274
55644
  }
55275
- } : context;
55645
+ } : resumeContext;
55276
55646
  const runBackend = () => createCliBackend({
55277
55647
  kind: "cursor_agent_cli",
55278
55648
  supportTier: "structured",
@@ -55293,7 +55663,7 @@ function createCursorAgentCliBackend(command = "cursor-agent", defaultArgs = [])
55293
55663
  if (approveMcps) {
55294
55664
  args.push("--approve-mcps");
55295
55665
  }
55296
- const resumeId3 = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
55666
+ const resumeId3 = resume.resumeId;
55297
55667
  if (shouldForceCursorAgent(ctx.config)) args.push("--force");
55298
55668
  if (ctx.config.mode === "plan" || ctx.config.mode === "review") {
55299
55669
  args.push("--mode", "plan");
@@ -55332,10 +55702,12 @@ function createCursorAgentCliBackend(command = "cursor-agent", defaultArgs = [])
55332
55702
  // cursor-agent headless can hang at startup with zero output.
55333
55703
  startupTimeoutMs: 18e4,
55334
55704
  augmentPrompt: (ctx) => {
55335
- const isResume = Boolean(
55336
- ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim()
55337
- );
55338
- const base = buildResumeAwarePrompt(ctx.config, ctx.promptText, { isResume });
55705
+ const promptText = resume.contextPrefix ? `${resume.contextPrefix}
55706
+
55707
+ ${ctx.promptText}` : ctx.promptText;
55708
+ const base = buildResumeAwarePrompt(ctx.config, promptText, {
55709
+ isResume: Boolean(resume.resumeId)
55710
+ });
55339
55711
  const prompt = ctx.config.mode === "plan" ? buildPlanModePrefix(base) : base;
55340
55712
  return appendImagePathReferences(prompt, imageFiles);
55341
55713
  },
@@ -57192,10 +57564,10 @@ function createKimiCliBackend(command = "kimi", defaultArgs = []) {
57192
57564
  async run(context) {
57193
57565
  const dialect = await detectKimiCliDialect(command, context);
57194
57566
  const registration = dialect === "kimi-cli" ? context.config.alanMcp : void 0;
57195
- const mcpDirectory = registration ? (0, import_fs17.mkdtempSync)((0, import_path17.join)((0, import_os9.tmpdir)(), "alan-kimi-mcp-")) : null;
57196
- const mcpConfigPath = mcpDirectory ? (0, import_path17.join)(mcpDirectory, "mcp.json") : null;
57567
+ const mcpDirectory = registration ? (0, import_fs19.mkdtempSync)((0, import_path19.join)((0, import_os11.tmpdir)(), "alan-kimi-mcp-")) : null;
57568
+ const mcpConfigPath = mcpDirectory ? (0, import_path19.join)(mcpDirectory, "mcp.json") : null;
57197
57569
  if (registration && mcpConfigPath) {
57198
- (0, import_fs17.writeFileSync)(
57570
+ (0, import_fs19.writeFileSync)(
57199
57571
  mcpConfigPath,
57200
57572
  JSON.stringify(
57201
57573
  buildKimiMcpConfig(registration, selectExternalMcpServers(context.config))
@@ -57230,7 +57602,7 @@ function createKimiCliBackend(command = "kimi", defaultArgs = []) {
57230
57602
  }).run(context);
57231
57603
  } finally {
57232
57604
  cleanup();
57233
- if (mcpDirectory) (0, import_fs17.rmSync)(mcpDirectory, { recursive: true, force: true });
57605
+ if (mcpDirectory) (0, import_fs19.rmSync)(mcpDirectory, { recursive: true, force: true });
57234
57606
  }
57235
57607
  }
57236
57608
  };
@@ -57465,9 +57837,12 @@ var AgentRunner = class {
57465
57837
  /** Provider attempts and runner commentary share one sequence for the run. */
57466
57838
  agentEventSeq = 0;
57467
57839
  foregroundState = "idle";
57840
+ /** Notice titles already in this run's transcript, so a failure is not reported twice. */
57841
+ noticeTitles = /* @__PURE__ */ new Set();
57468
57842
  publishEvent(event) {
57469
57843
  if (isUpdate(event.update, "state_update") && typeof event.update._meta?.["alan.dev/parentToolCallId"] !== "string")
57470
57844
  this.foregroundState = event.update.state;
57845
+ if (isUpdate(event.update, "notice")) this.noticeTitles.add(event.update.title.trim());
57471
57846
  this.agentEventSeq += 1;
57472
57847
  this.host.onSessionEvent({ ...event, seq: this.agentEventSeq });
57473
57848
  }
@@ -57475,6 +57850,8 @@ var AgentRunner = class {
57475
57850
  this.publishEvent({ at: Date.now(), update });
57476
57851
  }
57477
57852
  complete(result) {
57853
+ const unreported = this.unreportedFailure(result);
57854
+ if (unreported) this.failure(unreported);
57478
57855
  if (this.foregroundState === "running")
57479
57856
  this.emit({
57480
57857
  sessionUpdate: "state_update",
@@ -57511,6 +57888,16 @@ var AgentRunner = class {
57511
57888
  _meta: { "alan.dev/noticeKind": kind }
57512
57889
  });
57513
57890
  }
57891
+ /**
57892
+ * The chat renders only the transcript, and `result.error` never reaches it on its own:
57893
+ * a failed run whose reason was not already narrated would end with no explanation.
57894
+ */
57895
+ unreportedFailure(result) {
57896
+ const error61 = result.error?.trim();
57897
+ if (result.success || !error61) return null;
57898
+ if (this.abortController?.signal.aborted && this.abortReason === "user") return null;
57899
+ return this.noticeTitles.has(error61) ? null : error61;
57900
+ }
57514
57901
  /** A failure the run could not recover from. */
57515
57902
  failure(message) {
57516
57903
  this.emit({
@@ -57775,6 +58162,7 @@ ${runtimeConfig.task}` } : {}
57775
58162
  }
57776
58163
  async run(config4) {
57777
58164
  this.agentEventSeq = 0;
58165
+ this.noticeTitles = /* @__PURE__ */ new Set();
57778
58166
  this.abortReason = "user";
57779
58167
  this.abortController = new AbortController();
57780
58168
  const backendKind = this.resolveBackendKind(config4);
@@ -59193,7 +59581,7 @@ function buildApplicationRunFailure(input2) {
59193
59581
  const problem = createAlanProblem({
59194
59582
  domain: "application",
59195
59583
  code: input2.code,
59196
- id: (0, import_node_crypto6.randomUUID)(),
59584
+ id: (0, import_node_crypto7.randomUUID)(),
59197
59585
  title: "Alan could not complete the agent run",
59198
59586
  detail: input2.detail,
59199
59587
  occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -59398,7 +59786,7 @@ var RuntimeRunHost = class extends BaseRunHost {
59398
59786
  this.applicationProblem = createAlanProblem({
59399
59787
  domain: "application",
59400
59788
  code: /local path no longer exists/i.test(message) ? "app.workspace.missing" : "app.internal",
59401
- id: (0, import_node_crypto6.randomUUID)(),
59789
+ id: (0, import_node_crypto7.randomUUID)(),
59402
59790
  title: "Alan could not start the agent run",
59403
59791
  detail: message,
59404
59792
  occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -59638,10 +60026,10 @@ function scheduleRuntimeModelScan(getBaseMetadata, options) {
59638
60026
  }
59639
60027
 
59640
60028
  // src/daemon/start.ts
59641
- var import_node_crypto16 = require("crypto");
60029
+ var import_node_crypto17 = require("crypto");
59642
60030
  var import_node_http2 = __toESM(require("http"), 1);
59643
60031
  var import_node_os16 = require("os");
59644
- var import_node_path31 = require("path");
60032
+ var import_node_path33 = require("path");
59645
60033
 
59646
60034
  // ../../node_modules/engine.io-client/build/esm-debug/transports/polling-xhr.node.js
59647
60035
  var XMLHttpRequestModule = __toESM(require_XMLHttpRequest(), 1);
@@ -63199,8 +63587,8 @@ Object.assign(lookup, {
63199
63587
 
63200
63588
  // src/cleanup/hooks.ts
63201
63589
  var import_node_fs13 = require("fs");
63202
- var import_node_os13 = require("os");
63203
- var import_node_path16 = require("path");
63590
+ var import_node_os14 = require("os");
63591
+ var import_node_path18 = require("path");
63204
63592
  var ALAN_HOOK_MARKER = "# alan-native-session-hook";
63205
63593
  var ALAN_KIMI_HOOKS_START = "# alan-native-session-hooks:start";
63206
63594
  var ALAN_KIMI_HOOKS_END = "# alan-native-session-hooks:end";
@@ -63229,7 +63617,7 @@ function writeSettings(path2, settings2) {
63229
63617
  const serialized = `${JSON.stringify(settings2, null, 2)}
63230
63618
  `;
63231
63619
  if ((0, import_node_fs13.existsSync)(path2) && (0, import_node_fs13.readFileSync)(path2, "utf8") === serialized) return false;
63232
- (0, import_node_fs13.mkdirSync)((0, import_node_path16.dirname)(path2), { recursive: true, mode: 448 });
63620
+ (0, import_node_fs13.mkdirSync)((0, import_node_path18.dirname)(path2), { recursive: true, mode: 448 });
63233
63621
  const temporary = `${path2}.${process.pid}.tmp`;
63234
63622
  (0, import_node_fs13.writeFileSync)(temporary, serialized, { mode: 384 });
63235
63623
  (0, import_node_fs13.renameSync)(temporary, path2);
@@ -63237,7 +63625,7 @@ function writeSettings(path2, settings2) {
63237
63625
  }
63238
63626
  function writeTextFile(path2, content) {
63239
63627
  if ((0, import_node_fs13.existsSync)(path2) && (0, import_node_fs13.readFileSync)(path2, "utf8") === content) return false;
63240
- (0, import_node_fs13.mkdirSync)((0, import_node_path16.dirname)(path2), { recursive: true, mode: 448 });
63628
+ (0, import_node_fs13.mkdirSync)((0, import_node_path18.dirname)(path2), { recursive: true, mode: 448 });
63241
63629
  const temporary = `${path2}.${process.pid}.tmp`;
63242
63630
  (0, import_node_fs13.writeFileSync)(temporary, content, { mode: 384 });
63243
63631
  (0, import_node_fs13.renameSync)(temporary, path2);
@@ -63291,7 +63679,7 @@ function removeOwnedFile(path2, marker) {
63291
63679
  return true;
63292
63680
  }
63293
63681
  function removeKimiSection(homeDir) {
63294
- const path2 = (0, import_node_path16.join)(homeDir, ".kimi-code", "config.toml");
63682
+ const path2 = (0, import_node_path18.join)(homeDir, ".kimi-code", "config.toml");
63295
63683
  if (!(0, import_node_fs13.existsSync)(path2)) return false;
63296
63684
  const current = (0, import_node_fs13.readFileSync)(path2, "utf8");
63297
63685
  const content = withoutMarkedSection(current, ALAN_KIMI_HOOKS_START, ALAN_KIMI_HOOKS_END);
@@ -63299,50 +63687,50 @@ function removeKimiSection(homeDir) {
63299
63687
  return writeTextFile(path2, content ? `${content.trimEnd()}
63300
63688
  ` : "");
63301
63689
  }
63302
- function removeNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
63690
+ function removeNativeHooks(homeDir = (0, import_node_os14.homedir)()) {
63303
63691
  const targets = [
63304
63692
  {
63305
63693
  provider: "Claude",
63306
- path: (0, import_node_path16.join)(homeDir, ".claude", "settings.json"),
63307
- remove: () => removeNestedCommandHooks((0, import_node_path16.join)(homeDir, ".claude", "settings.json"), "Claude")
63694
+ path: (0, import_node_path18.join)(homeDir, ".claude", "settings.json"),
63695
+ remove: () => removeNestedCommandHooks((0, import_node_path18.join)(homeDir, ".claude", "settings.json"), "Claude")
63308
63696
  },
63309
63697
  {
63310
63698
  provider: "Codex",
63311
- path: (0, import_node_path16.join)(homeDir, ".codex", "hooks.json"),
63312
- remove: () => removeNestedCommandHooks((0, import_node_path16.join)(homeDir, ".codex", "hooks.json"), "Codex")
63699
+ path: (0, import_node_path18.join)(homeDir, ".codex", "hooks.json"),
63700
+ remove: () => removeNestedCommandHooks((0, import_node_path18.join)(homeDir, ".codex", "hooks.json"), "Codex")
63313
63701
  },
63314
63702
  {
63315
63703
  provider: "Cursor",
63316
- path: (0, import_node_path16.join)(homeDir, ".cursor", "hooks.json"),
63317
- remove: () => removeFlatCommandHooks((0, import_node_path16.join)(homeDir, ".cursor", "hooks.json"), "Cursor")
63704
+ path: (0, import_node_path18.join)(homeDir, ".cursor", "hooks.json"),
63705
+ remove: () => removeFlatCommandHooks((0, import_node_path18.join)(homeDir, ".cursor", "hooks.json"), "Cursor")
63318
63706
  },
63319
63707
  {
63320
63708
  provider: "Copilot",
63321
- path: (0, import_node_path16.join)(homeDir, ".copilot", "hooks", "alan-native-session.json"),
63709
+ path: (0, import_node_path18.join)(homeDir, ".copilot", "hooks", "alan-native-session.json"),
63322
63710
  remove: () => removeOwnedFile(
63323
- (0, import_node_path16.join)(homeDir, ".copilot", "hooks", "alan-native-session.json"),
63711
+ (0, import_node_path18.join)(homeDir, ".copilot", "hooks", "alan-native-session.json"),
63324
63712
  ALAN_HOOK_MARKER
63325
63713
  )
63326
63714
  },
63327
63715
  {
63328
63716
  provider: "Grok",
63329
- path: (0, import_node_path16.join)(homeDir, ".grok", "hooks", "alan-native-session.json"),
63717
+ path: (0, import_node_path18.join)(homeDir, ".grok", "hooks", "alan-native-session.json"),
63330
63718
  remove: () => removeOwnedFile(
63331
- (0, import_node_path16.join)(homeDir, ".grok", "hooks", "alan-native-session.json"),
63719
+ (0, import_node_path18.join)(homeDir, ".grok", "hooks", "alan-native-session.json"),
63332
63720
  ALAN_HOOK_MARKER
63333
63721
  )
63334
63722
  },
63335
63723
  {
63336
63724
  provider: "opencode",
63337
- path: (0, import_node_path16.join)(homeDir, ".config", "opencode", "plugins", "alan-native-session.js"),
63725
+ path: (0, import_node_path18.join)(homeDir, ".config", "opencode", "plugins", "alan-native-session.js"),
63338
63726
  remove: () => removeOwnedFile(
63339
- (0, import_node_path16.join)(homeDir, ".config", "opencode", "plugins", "alan-native-session.js"),
63727
+ (0, import_node_path18.join)(homeDir, ".config", "opencode", "plugins", "alan-native-session.js"),
63340
63728
  ALAN_OPENCODE_PLUGIN_MARKER
63341
63729
  )
63342
63730
  },
63343
63731
  {
63344
63732
  provider: "Kimi",
63345
- path: (0, import_node_path16.join)(homeDir, ".kimi-code", "config.toml"),
63733
+ path: (0, import_node_path18.join)(homeDir, ".kimi-code", "config.toml"),
63346
63734
  remove: () => removeKimiSection(homeDir)
63347
63735
  }
63348
63736
  ];
@@ -63400,7 +63788,7 @@ async function publishModelScanReply(reply, credentials) {
63400
63788
  var import_node_fs19 = require("fs");
63401
63789
 
63402
63790
  // src/events/live.ts
63403
- var import_node_crypto8 = require("crypto");
63791
+ var import_node_crypto9 = require("crypto");
63404
63792
  var import_node_fs17 = require("fs");
63405
63793
  var import_promises8 = require("fs/promises");
63406
63794
 
@@ -63461,13 +63849,13 @@ function requestDeadline(timeoutMs, parent) {
63461
63849
  }
63462
63850
 
63463
63851
  // src/events/push.ts
63464
- var import_node_crypto7 = require("crypto");
63852
+ var import_node_crypto8 = require("crypto");
63465
63853
  var import_node_fs16 = require("fs");
63466
63854
  var import_promises7 = require("fs/promises");
63467
63855
 
63468
63856
  // src/events/session.ts
63469
63857
  var import_node_fs15 = require("fs");
63470
- var import_node_path18 = require("path");
63858
+ var import_node_path20 = require("path");
63471
63859
 
63472
63860
  // src/events/journal-notifications.ts
63473
63861
  var listeners2 = /* @__PURE__ */ new Map();
@@ -63493,21 +63881,21 @@ function subscribeJournalChanges(conversationId, listener) {
63493
63881
 
63494
63882
  // src/events/sync-state.ts
63495
63883
  var import_node_fs14 = require("fs");
63496
- var import_node_path17 = require("path");
63884
+ var import_node_path19 = require("path");
63497
63885
  function sessionsDirectory(configPath) {
63498
- return (0, import_node_path17.join)((0, import_node_path17.dirname)(configPath), "sessions");
63886
+ return (0, import_node_path19.join)((0, import_node_path19.dirname)(configPath), "sessions");
63499
63887
  }
63500
63888
  function conversationDirectory(configPath, conversationId) {
63501
63889
  if (!conversationId || conversationId === "." || conversationId === "..") {
63502
63890
  throw new Error("Invalid conversation storage identity");
63503
63891
  }
63504
- return (0, import_node_path17.join)(sessionsDirectory(configPath), encodeURIComponent(conversationId));
63892
+ return (0, import_node_path19.join)(sessionsDirectory(configPath), encodeURIComponent(conversationId));
63505
63893
  }
63506
63894
  function transcriptPath(configPath, conversationId) {
63507
- return (0, import_node_path17.join)(conversationDirectory(configPath, conversationId), "transcript.jsonl");
63895
+ return (0, import_node_path19.join)(conversationDirectory(configPath, conversationId), "transcript.jsonl");
63508
63896
  }
63509
63897
  function syncStatePath(configPath, conversationId) {
63510
- return (0, import_node_path17.join)(conversationDirectory(configPath, conversationId), "state.json");
63898
+ return (0, import_node_path19.join)(conversationDirectory(configPath, conversationId), "state.json");
63511
63899
  }
63512
63900
  function record2(value2) {
63513
63901
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
@@ -63594,16 +63982,16 @@ function contiguousOffset(state) {
63594
63982
  }
63595
63983
  function save(configPath, conversationId, state) {
63596
63984
  const path2 = syncStatePath(configPath, conversationId);
63597
- (0, import_node_fs14.mkdirSync)((0, import_node_path17.dirname)(path2), { recursive: true, mode: 448 });
63985
+ (0, import_node_fs14.mkdirSync)((0, import_node_path19.dirname)(path2), { recursive: true, mode: 448 });
63598
63986
  (0, import_node_fs14.writeFileSync)(`${path2}.pending`, JSON.stringify(state), { mode: 384 });
63599
63987
  (0, import_node_fs14.renameSync)(`${path2}.pending`, path2);
63600
63988
  }
63601
63989
  function migrateConversationStorage(configPath, conversationId) {
63602
63990
  const root = sessionsDirectory(configPath);
63603
63991
  const name = encodeURIComponent(conversationId);
63604
- const oldTranscript = (0, import_node_path17.join)(root, `${name}.jsonl`);
63605
- const oldState = (0, import_node_path17.join)(root, `${name}.state.json`);
63606
- const oldRuns = (0, import_node_path17.join)(root, `${name}.runs`);
63992
+ const oldTranscript = (0, import_node_path19.join)(root, `${name}.jsonl`);
63993
+ const oldState = (0, import_node_path19.join)(root, `${name}.state.json`);
63994
+ const oldRuns = (0, import_node_path19.join)(root, `${name}.runs`);
63607
63995
  if ((0, import_node_fs14.existsSync)(syncStatePath(configPath, conversationId))) {
63608
63996
  if ((0, import_node_fs14.existsSync)(oldTranscript)) {
63609
63997
  throw new Error("Both transcript layouts exist; refusing to overwrite history");
@@ -63621,11 +64009,11 @@ function migrateConversationStorage(configPath, conversationId) {
63621
64009
  if ((0, import_node_fs14.existsSync)(oldRuns)) {
63622
64010
  for (const file2 of (0, import_node_fs14.readdirSync)(oldRuns)) {
63623
64011
  if (!file2.endsWith(".json")) continue;
63624
- state.runs[decodeURIComponent(file2.slice(0, -5))] = runState(readJson((0, import_node_path17.join)(oldRuns, file2)));
64012
+ state.runs[decodeURIComponent(file2.slice(0, -5))] = runState(readJson((0, import_node_path19.join)(oldRuns, file2)));
63625
64013
  }
63626
64014
  }
63627
64015
  const target = transcriptPath(configPath, conversationId);
63628
- (0, import_node_fs14.mkdirSync)((0, import_node_path17.dirname)(target), { recursive: true, mode: 448 });
64016
+ (0, import_node_fs14.mkdirSync)((0, import_node_path19.dirname)(target), { recursive: true, mode: 448 });
63629
64017
  if ((0, import_node_fs14.existsSync)(oldTranscript)) {
63630
64018
  if ((0, import_node_fs14.existsSync)(target))
63631
64019
  throw new Error("Both transcript layouts exist; refusing to overwrite history");
@@ -63803,7 +64191,7 @@ function openSessionTranscript(input2) {
63803
64191
  if (getTranscriptBuffer(path2))
63804
64192
  throw new Error("Conversation has pending transcript bytes from another writer");
63805
64193
  migrateConversationStorage(input2.configPath, input2.conversationId);
63806
- (0, import_node_fs15.mkdirSync)((0, import_node_path18.dirname)(path2), { recursive: true, mode: 448 });
64194
+ (0, import_node_fs15.mkdirSync)((0, import_node_path20.dirname)(path2), { recursive: true, mode: 448 });
63807
64195
  written = sizeOf(path2);
63808
64196
  const sync = readSyncState(input2.configPath, input2.conversationId);
63809
64197
  if (sync.lastRunId && sync.lastRunId !== input2.runId) {
@@ -64012,7 +64400,7 @@ var MAX_RECEIPT_POLL_MS = 15e3;
64012
64400
  var MAX_PUSH_BYTES = 512 * 1024;
64013
64401
  var MIN_PUSH_BYTES = 64 * 1024;
64014
64402
  var adaptivePushBytes = MAX_PUSH_BYTES;
64015
- function isTimeout(error61) {
64403
+ function isTimeout2(error61) {
64016
64404
  return error61 instanceof Error && error61.name === "TimeoutError";
64017
64405
  }
64018
64406
  var REQUEST_TIMEOUT_MS = 1e4;
@@ -64044,7 +64432,7 @@ async function exchange(target, body, offset2, final = false) {
64044
64432
  "content-type": "application/octet-stream",
64045
64433
  "x-alan-offset": String(offset2),
64046
64434
  "x-alan-revision": "0",
64047
- "x-alan-sha256": (0, import_node_crypto7.createHash)("sha256").update(body).digest("hex"),
64435
+ "x-alan-sha256": (0, import_node_crypto8.createHash)("sha256").update(body).digest("hex"),
64048
64436
  ...final ? { "x-alan-final": "1" } : {}
64049
64437
  } : {}
64050
64438
  },
@@ -64182,7 +64570,7 @@ function startTranscriptPush(target, onProblem) {
64182
64570
  }
64183
64571
  }).catch((error61) => {
64184
64572
  if (target.signal?.aborted) return;
64185
- if (isTimeout(error61)) adaptivePushBytes = Math.max(MIN_PUSH_BYTES, adaptivePushBytes / 2);
64573
+ if (isTimeout2(error61)) adaptivePushBytes = Math.max(MIN_PUSH_BYTES, adaptivePushBytes / 2);
64186
64574
  failures += 1;
64187
64575
  pending = true;
64188
64576
  cached2 = void 0;
@@ -64334,7 +64722,7 @@ function startTranscriptLive(target, onProblem) {
64334
64722
  "content-type": "application/octet-stream",
64335
64723
  "x-alan-offset": String(offset2),
64336
64724
  "x-alan-revision": "0",
64337
- "x-alan-sha256": (0, import_node_crypto8.createHash)("sha256").update(body).digest("hex"),
64725
+ "x-alan-sha256": (0, import_node_crypto9.createHash)("sha256").update(body).digest("hex"),
64338
64726
  "x-alan-live-epoch": epoch ?? ""
64339
64727
  } : {}
64340
64728
  },
@@ -64742,6 +65130,7 @@ var TERMINAL_EVENT_TYPES = /* @__PURE__ */ new Set([
64742
65130
  "session_error",
64743
65131
  "agent_run_finished"
64744
65132
  ]);
65133
+ var PROBLEM_EVENT_TYPES = /* @__PURE__ */ new Set(["error", "application_problem", "agent_problem_observed"]);
64745
65134
  var TERMINAL_RETRY_WINDOW_MS = 10 * 6e4;
64746
65135
  var RETRY_BACKOFF_CAP_MS = 3e4;
64747
65136
  function isRetryableStatus(status2) {
@@ -64819,7 +65208,7 @@ function createHttpRunEventSink(input2, url3, binding) {
64819
65208
  }
64820
65209
  }
64821
65210
  async function deliver(conversationId, runId, event) {
64822
- const terminal = TERMINAL_EVENT_TYPES.has(event.type);
65211
+ const mustDeliver = TERMINAL_EVENT_TYPES.has(event.type) || PROBLEM_EVENT_TYPES.has(event.type);
64823
65212
  const giveUpAt = Date.now() + TERMINAL_RETRY_WINDOW_MS;
64824
65213
  for (let attempt = 0; ; attempt++) {
64825
65214
  if (shutdown.signal.aborted) return;
@@ -64848,7 +65237,7 @@ function createHttpRunEventSink(input2, url3, binding) {
64848
65237
  deadline.dispose();
64849
65238
  }
64850
65239
  const backoff = Math.min(1e3 * 2 ** attempt, RETRY_BACKOFF_CAP_MS);
64851
- if (!terminal || !retryable || Date.now() + backoff > giveUpAt) {
65240
+ if (!mustDeliver || !retryable || Date.now() + backoff > giveUpAt) {
64852
65241
  input2.onFailure?.(failure2);
64853
65242
  return;
64854
65243
  }
@@ -65160,9 +65549,9 @@ async function pushNativeTurn(delivery, record4) {
65160
65549
  }
65161
65550
 
65162
65551
  // src/native/session-store.ts
65163
- var import_node_crypto9 = require("crypto");
65552
+ var import_node_crypto10 = require("crypto");
65164
65553
  var import_node_fs20 = require("fs");
65165
- var import_node_path19 = require("path");
65554
+ var import_node_path21 = require("path");
65166
65555
  var MAX_NATIVE_SESSION_ENTRIES = 500;
65167
65556
  var nativeRunFinishEvents = ["agent_run_finished", "query_complete"];
65168
65557
  function nativeSessionStorePath(configPath) {
@@ -65206,8 +65595,8 @@ function loadSessions(path2) {
65206
65595
  return parsed.sessions.filter(isSessionEntry);
65207
65596
  }
65208
65597
  function writeAtomically(path2, contents) {
65209
- (0, import_node_fs20.mkdirSync)((0, import_node_path19.dirname)(path2), { recursive: true, mode: 448 });
65210
- const pending = `${path2}.pending-${process.pid}-${(0, import_node_crypto9.randomBytes)(6).toString("hex")}`;
65598
+ (0, import_node_fs20.mkdirSync)((0, import_node_path21.dirname)(path2), { recursive: true, mode: 448 });
65599
+ const pending = `${path2}.pending-${process.pid}-${(0, import_node_crypto10.randomBytes)(6).toString("hex")}`;
65211
65600
  try {
65212
65601
  (0, import_node_fs20.writeFileSync)(pending, contents, { mode: 384 });
65213
65602
  (0, import_node_fs20.chmodSync)(pending, 384);
@@ -65260,7 +65649,7 @@ function reconcileTranscriptIdentity(entry, transcriptPath2, identity, size) {
65260
65649
  }
65261
65650
 
65262
65651
  // src/native/turns.ts
65263
- var import_node_crypto10 = require("crypto");
65652
+ var import_node_crypto11 = require("crypto");
65264
65653
  var import_promises9 = require("fs/promises");
65265
65654
  var SCAN_BYTES = 1024 * 1024;
65266
65655
  var MIN_READ_BYTES = 64 * 1024;
@@ -65406,7 +65795,7 @@ function lastMatchingTurnIndex(turns, target) {
65406
65795
  function signalDigest(target) {
65407
65796
  const fingerprint = target.assistantFingerprint;
65408
65797
  const basis = target.providerTurnId ?? (fingerprint ? `${fingerprint.length}\0${fingerprint.head}\0${fingerprint.tail}` : null);
65409
- return basis ? (0, import_node_crypto10.createHash)("sha256").update(basis).digest("hex") : null;
65798
+ return basis ? (0, import_node_crypto11.createHash)("sha256").update(basis).digest("hex") : null;
65410
65799
  }
65411
65800
  function lastForegroundStopReason(updates) {
65412
65801
  for (let index = updates.length - 1; index >= 0; index -= 1) {
@@ -66321,14 +66710,14 @@ var RuntimeSkillCoordinator = class {
66321
66710
 
66322
66711
  // src/skills/runtime-skill-manager.ts
66323
66712
  var import_node_buffer5 = require("buffer");
66324
- var import_node_crypto13 = require("crypto");
66713
+ var import_node_crypto14 = require("crypto");
66325
66714
  var import_promises13 = require("fs/promises");
66326
- var import_node_path22 = require("path");
66715
+ var import_node_path24 = require("path");
66327
66716
 
66328
66717
  // src/skills/managed-skill-store.ts
66329
- var import_node_crypto11 = require("crypto");
66718
+ var import_node_crypto12 = require("crypto");
66330
66719
  var import_promises11 = require("fs/promises");
66331
- var import_node_path20 = require("path");
66720
+ var import_node_path22 = require("path");
66332
66721
  var EMPTY_STATE = {
66333
66722
  version: 1,
66334
66723
  sources: {},
@@ -66345,7 +66734,7 @@ var ManagedSkillStore = class _ManagedSkillStore {
66345
66734
  static async open(baseDirectory) {
66346
66735
  await (0, import_promises11.mkdir)(baseDirectory, { recursive: true, mode: 448 });
66347
66736
  try {
66348
- const parsed = JSON.parse(await (0, import_promises11.readFile)((0, import_node_path20.join)(baseDirectory, "state.json"), "utf8"));
66737
+ const parsed = JSON.parse(await (0, import_promises11.readFile)((0, import_node_path22.join)(baseDirectory, "state.json"), "utf8"));
66349
66738
  return new _ManagedSkillStore(baseDirectory, parseState(parsed), "verified");
66350
66739
  } catch (error61) {
66351
66740
  if (isMissingPath(error61)) {
@@ -66403,10 +66792,10 @@ var ManagedSkillStore = class _ManagedSkillStore {
66403
66792
  this.integrity = "verified";
66404
66793
  }
66405
66794
  async persist() {
66406
- const statePath = (0, import_node_path20.join)(this.baseDirectory, "state.json");
66407
- const pendingPath = (0, import_node_path20.join)(
66795
+ const statePath = (0, import_node_path22.join)(this.baseDirectory, "state.json");
66796
+ const pendingPath = (0, import_node_path22.join)(
66408
66797
  this.baseDirectory,
66409
- `.state.json.pending-${process.pid}-${(0, import_node_crypto11.randomBytes)(6).toString("hex")}`
66798
+ `.state.json.pending-${process.pid}-${(0, import_node_crypto12.randomBytes)(6).toString("hex")}`
66410
66799
  );
66411
66800
  try {
66412
66801
  await (0, import_promises11.writeFile)(pendingPath, `${JSON.stringify(this.state, null, 2)}
@@ -66471,9 +66860,9 @@ function isMissingPath(error61) {
66471
66860
 
66472
66861
  // ../shared/dist/node/skill-bundle.js
66473
66862
  var import_node_buffer3 = require("buffer");
66474
- var import_node_crypto12 = require("crypto");
66863
+ var import_node_crypto13 = require("crypto");
66475
66864
  var import_promises12 = require("fs/promises");
66476
- var import_node_path21 = require("path");
66865
+ var import_node_path23 = require("path");
66477
66866
  var import_node_stream = require("stream");
66478
66867
  var import_node_zlib = require("zlib");
66479
66868
  var import_tar_stream = __toESM(require_tar_stream(), 1);
@@ -66482,7 +66871,7 @@ async function createSkillBundle(packageRoot, options = {}) {
66482
66871
  const archive = (0, import_tar_stream.pack)();
66483
66872
  const tarPromise = collectStream(archive);
66484
66873
  for (const file2 of before.files) {
66485
- const bytes2 = await (0, import_promises12.readFile)((0, import_node_path21.join)(packageRoot, ...file2.path.split("/")));
66874
+ const bytes2 = await (0, import_promises12.readFile)((0, import_node_path23.join)(packageRoot, ...file2.path.split("/")));
66486
66875
  await addArchiveEntry(archive, {
66487
66876
  name: file2.path,
66488
66877
  type: "file",
@@ -66597,19 +66986,19 @@ async function extractEntry(header, stream, destination, limits) {
66597
66986
  if (bytes.byteLength !== declaredSize) {
66598
66987
  throw new Error(`Skill archive file size is invalid: ${path2}`);
66599
66988
  }
66600
- const outputPath = (0, import_node_path21.join)(destination, ...path2.split("/"));
66601
- await (0, import_promises12.mkdir)((0, import_node_path21.dirname)(outputPath), { recursive: true, mode: 448 });
66989
+ const outputPath = (0, import_node_path23.join)(destination, ...path2.split("/"));
66990
+ await (0, import_promises12.mkdir)((0, import_node_path23.dirname)(outputPath), { recursive: true, mode: 448 });
66602
66991
  await (0, import_promises12.writeFile)(outputPath, bytes, { mode: (header.mode ?? 420) & 73 ? 493 : 420 });
66603
66992
  }
66604
66993
  function requireSafeArchivePath(value2) {
66605
66994
  const normalized2 = value2.replaceAll("\\", "/").normalize("NFC");
66606
- if (!normalized2 || normalized2.startsWith("/") || normalized2.includes("\0") || import_node_path21.posix.normalize(normalized2) !== normalized2 || normalized2 === ".." || normalized2.startsWith("../")) {
66995
+ if (!normalized2 || normalized2.startsWith("/") || normalized2.includes("\0") || import_node_path23.posix.normalize(normalized2) !== normalized2 || normalized2 === ".." || normalized2.startsWith("../")) {
66607
66996
  throw new Error(`Skill archive contains an unsafe path: ${value2}`);
66608
66997
  }
66609
66998
  return normalized2;
66610
66999
  }
66611
67000
  function sha2562(bytes) {
66612
- return `sha256:${(0, import_node_crypto12.createHash)("sha256").update(bytes).digest("hex")}`;
67001
+ return `sha256:${(0, import_node_crypto13.createHash)("sha256").update(bytes).digest("hex")}`;
66613
67002
  }
66614
67003
 
66615
67004
  // src/skills/skill-control-client.ts
@@ -66687,14 +67076,14 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
66687
67076
  options.endpointProfile,
66688
67077
  options.profileStorageIdentity
66689
67078
  );
66690
- const skillsStateDirectory = storageNamespace ? (0, import_node_path22.join)(options.homeDirectory, ".alan", "skills", "profiles", storageNamespace) : (0, import_node_path22.join)(options.homeDirectory, ".alan", "skills");
66691
- const managedSkillsDirectory = (0, import_node_path22.join)(options.homeDirectory, ".agents", "skills");
67079
+ const skillsStateDirectory = storageNamespace ? (0, import_node_path24.join)(options.homeDirectory, ".alan", "skills", "profiles", storageNamespace) : (0, import_node_path24.join)(options.homeDirectory, ".alan", "skills");
67080
+ const managedSkillsDirectory = (0, import_node_path24.join)(options.homeDirectory, ".agents", "skills");
66692
67081
  const store = await ManagedSkillStore.open(skillsStateDirectory);
66693
67082
  return new _RuntimeSkillManager(
66694
67083
  skillsStateDirectory,
66695
67084
  managedSkillsDirectory,
66696
- (0, import_node_path22.join)(options.homeDirectory, ".claude", "skills"),
66697
- (0, import_node_path22.join)(options.homeDirectory, ".alan", "sync-manifest.json"),
67085
+ (0, import_node_path24.join)(options.homeDirectory, ".claude", "skills"),
67086
+ (0, import_node_path24.join)(options.homeDirectory, ".alan", "sync-manifest.json"),
66698
67087
  storageNamespace,
66699
67088
  store,
66700
67089
  options.downloadBundle ?? downloadBundleWithFetch,
@@ -66860,11 +67249,11 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
66860
67249
  async reconcileUnlocked(manifest) {
66861
67250
  const desired = desiredSkillManifestSchema.parse(manifest);
66862
67251
  await (0, import_promises13.mkdir)(this.managedSkillsDirectory, { recursive: true, mode: 448 });
66863
- await (0, import_promises13.mkdir)((0, import_node_path22.join)(this.skillsStateDirectory, "cache", "sha256"), {
67252
+ await (0, import_promises13.mkdir)((0, import_node_path24.join)(this.skillsStateDirectory, "cache", "sha256"), {
66864
67253
  recursive: true,
66865
67254
  mode: 448
66866
67255
  });
66867
- await (0, import_promises13.mkdir)((0, import_node_path22.join)(this.skillsStateDirectory, "tmp"), { recursive: true, mode: 448 });
67256
+ await (0, import_promises13.mkdir)((0, import_node_path24.join)(this.skillsStateDirectory, "tmp"), { recursive: true, mode: 448 });
66868
67257
  const results = [];
66869
67258
  const nextProjections = {};
66870
67259
  for (const entry of desired.skills) {
@@ -66908,7 +67297,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
66908
67297
  await this.retireLegacySyncManifest();
66909
67298
  }
66910
67299
  return {
66911
- attemptId: (0, import_node_crypto13.randomUUID)(),
67300
+ attemptId: (0, import_node_crypto14.randomUUID)(),
66912
67301
  desiredRevision: desired.revision,
66913
67302
  skills: results
66914
67303
  };
@@ -66967,7 +67356,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
66967
67356
  }
66968
67357
  conflictDirectory(runtimeDirectory, kind) {
66969
67358
  requireSafeRuntimeDirectory(runtimeDirectory);
66970
- return (0, import_node_path22.join)(
67359
+ return (0, import_node_path24.join)(
66971
67360
  kind === "managed_destination" ? this.managedSkillsDirectory : this.compatibilitySkillsDirectory,
66972
67361
  this.projectionDirectoryName(runtimeDirectory)
66973
67362
  );
@@ -66975,13 +67364,13 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
66975
67364
  async renameLocalConflict(entry, conflict, name) {
66976
67365
  requirePortableSkillName(name);
66977
67366
  const source2 = this.conflictDirectory(entry.runtimeDirectory, conflict.kind);
66978
- const destination = (0, import_node_path22.join)((0, import_node_path22.dirname)(source2), name);
67367
+ const destination = (0, import_node_path24.join)((0, import_node_path24.dirname)(source2), name);
66979
67368
  if (await pathExists2(destination)) {
66980
67369
  throw Object.assign(new Error(`A local Skill named ${name} already exists`), {
66981
67370
  code: "SKILL_LOCAL_NAME_CONFLICT"
66982
67371
  });
66983
67372
  }
66984
- const suffix = `${process.pid}-${(0, import_node_crypto13.randomBytes)(8).toString("hex")}`;
67373
+ const suffix = `${process.pid}-${(0, import_node_crypto14.randomBytes)(8).toString("hex")}`;
66985
67374
  const backup = `${source2}.rename-backup-${suffix}`;
66986
67375
  const pending = `${source2}.rename-pending-${suffix}`;
66987
67376
  let sourceMoved = false;
@@ -66990,7 +67379,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
66990
67379
  await (0, import_promises13.rename)(source2, backup);
66991
67380
  sourceMoved = true;
66992
67381
  await (0, import_promises13.cp)(backup, pending, { recursive: true, errorOnExist: true, force: false });
66993
- const skillMarkdown = (0, import_node_path22.join)(pending, "SKILL.md");
67382
+ const skillMarkdown = (0, import_node_path24.join)(pending, "SKILL.md");
66994
67383
  await (0, import_promises13.writeFile)(
66995
67384
  skillMarkdown,
66996
67385
  rewriteSkillMarkdownName(await (0, import_promises13.readFile)(skillMarkdown, "utf8"), name),
@@ -67018,7 +67407,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67018
67407
  }
67019
67408
  async overwriteLocalConflict(input2, entry, conflict, manifest) {
67020
67409
  const source2 = this.conflictDirectory(entry.runtimeDirectory, conflict.kind);
67021
- const backup = `${source2}.overwrite-backup-${process.pid}-${(0, import_node_crypto13.randomBytes)(8).toString("hex")}`;
67410
+ const backup = `${source2}.overwrite-backup-${process.pid}-${(0, import_node_crypto14.randomBytes)(8).toString("hex")}`;
67022
67411
  await (0, import_promises13.rename)(source2, backup);
67023
67412
  try {
67024
67413
  const reconciled = await this.reconcileUnlocked(manifest);
@@ -67070,14 +67459,14 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67070
67459
  const manifest = await readLegacyManifest(this.legacyManifestPath);
67071
67460
  const legacy = manifest?.skills[entry.slug];
67072
67461
  if (!legacy) return;
67073
- const source2 = (0, import_node_path22.join)(this.managedSkillsDirectory, entry.slug);
67462
+ const source2 = (0, import_node_path24.join)(this.managedSkillsDirectory, entry.slug);
67074
67463
  if (!await legacyFileMatches(source2, legacy.hash) || !await packageMatches(source2, entry.contentHash)) {
67075
67464
  return;
67076
67465
  }
67077
67466
  await (0, import_promises13.rename)(source2, destination);
67078
67467
  try {
67079
67468
  await (0, import_promises13.writeFile)(
67080
- (0, import_node_path22.join)(destination, ".alan-managed.json"),
67469
+ (0, import_node_path24.join)(destination, ".alan-managed.json"),
67081
67470
  `${JSON.stringify(markerFor(entry), null, 2)}
67082
67471
  `,
67083
67472
  { encoding: "utf8", flag: "wx", mode: 384 }
@@ -67086,20 +67475,20 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67086
67475
  await (0, import_promises13.rename)(destination, source2).catch(() => void 0);
67087
67476
  throw error61;
67088
67477
  }
67089
- await removeExactLegacySkill((0, import_node_path22.join)(this.compatibilitySkillsDirectory, entry.slug), legacy.hash);
67478
+ await removeExactLegacySkill((0, import_node_path24.join)(this.compatibilitySkillsDirectory, entry.slug), legacy.hash);
67090
67479
  }
67091
67480
  async retireLegacySyncManifest() {
67092
67481
  if (this.storageNamespace) return;
67093
67482
  const manifest = await readLegacyManifest(this.legacyManifestPath);
67094
67483
  if (!manifest) return;
67095
67484
  for (const [command, entry] of Object.entries(manifest.skills)) {
67096
- await removeExactLegacySkill((0, import_node_path22.join)(this.managedSkillsDirectory, command), entry.hash);
67097
- await removeExactLegacySkill((0, import_node_path22.join)(this.compatibilitySkillsDirectory, command), entry.hash);
67485
+ await removeExactLegacySkill((0, import_node_path24.join)(this.managedSkillsDirectory, command), entry.hash);
67486
+ await removeExactLegacySkill((0, import_node_path24.join)(this.compatibilitySkillsDirectory, command), entry.hash);
67098
67487
  }
67099
67488
  await (0, import_promises13.rm)(this.legacyManifestPath, { force: true });
67100
67489
  }
67101
67490
  async ensureCached(entry) {
67102
- const cacheDirectory = (0, import_node_path22.join)(
67491
+ const cacheDirectory = (0, import_node_path24.join)(
67103
67492
  this.skillsStateDirectory,
67104
67493
  "cache",
67105
67494
  "sha256",
@@ -67113,10 +67502,10 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67113
67502
  `Downloaded Skill bundle length ${bytes.byteLength} does not match ${entry.compressedBytes}`
67114
67503
  );
67115
67504
  }
67116
- const pendingDirectory = (0, import_node_path22.join)(
67505
+ const pendingDirectory = (0, import_node_path24.join)(
67117
67506
  this.skillsStateDirectory,
67118
67507
  "tmp",
67119
- `cache-${process.pid}-${(0, import_node_crypto13.randomBytes)(8).toString("hex")}`
67508
+ `cache-${process.pid}-${(0, import_node_crypto14.randomBytes)(8).toString("hex")}`
67120
67509
  );
67121
67510
  try {
67122
67511
  await extractSkillBundle(bytes, pendingDirectory, {
@@ -67140,16 +67529,16 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67140
67529
  await this.ensureCompatibilityProjection(entry, destination);
67141
67530
  return entry.contentHash;
67142
67531
  }
67143
- const suffix = `${process.pid}-${(0, import_node_crypto13.randomBytes)(8).toString("hex")}`;
67144
- const pending = (0, import_node_path22.join)(this.managedSkillsDirectory, `.pending-${suffix}`);
67145
- const backup = (0, import_node_path22.join)(this.managedSkillsDirectory, `.backup-${suffix}`);
67532
+ const suffix = `${process.pid}-${(0, import_node_crypto14.randomBytes)(8).toString("hex")}`;
67533
+ const pending = (0, import_node_path24.join)(this.managedSkillsDirectory, `.pending-${suffix}`);
67534
+ const backup = (0, import_node_path24.join)(this.managedSkillsDirectory, `.backup-${suffix}`);
67146
67535
  let movedExisting = false;
67147
67536
  let installedPending = false;
67148
67537
  let completed = false;
67149
67538
  try {
67150
67539
  await (0, import_promises13.cp)(cacheDirectory, pending, { recursive: true, errorOnExist: true, force: false });
67151
67540
  await (0, import_promises13.writeFile)(
67152
- (0, import_node_path22.join)(pending, ".alan-managed.json"),
67541
+ (0, import_node_path24.join)(pending, ".alan-managed.json"),
67153
67542
  `${JSON.stringify(markerFor(entry), null, 2)}
67154
67543
  `,
67155
67544
  { encoding: "utf8", flag: "wx", mode: 384 }
@@ -67223,7 +67612,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67223
67612
  const owned = splitProjectionName(entry);
67224
67613
  if (owned.namespace !== this.storageNamespace) continue;
67225
67614
  if (desired[owned.runtimeDirectory]) continue;
67226
- const destination = (0, import_node_path22.join)(this.managedSkillsDirectory, entry);
67615
+ const destination = (0, import_node_path24.join)(this.managedSkillsDirectory, entry);
67227
67616
  const marker = await readMarker(destination);
67228
67617
  if (!marker) continue;
67229
67618
  const projection = {
@@ -67240,7 +67629,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67240
67629
  });
67241
67630
  continue;
67242
67631
  }
67243
- const compatibility = (0, import_node_path22.join)(this.compatibilitySkillsDirectory, entry);
67632
+ const compatibility = (0, import_node_path24.join)(this.compatibilitySkillsDirectory, entry);
67244
67633
  if (!await removeCompatibilityProjection(compatibility, destination, projection)) {
67245
67634
  failures.push({
67246
67635
  ...projection,
@@ -67256,7 +67645,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67256
67645
  }
67257
67646
  async ensureCompatibilityProjection(entry, canonicalDirectory) {
67258
67647
  await (0, import_promises13.mkdir)(this.compatibilitySkillsDirectory, { recursive: true, mode: 448 });
67259
- const destination = (0, import_node_path22.join)(
67648
+ const destination = (0, import_node_path24.join)(
67260
67649
  this.compatibilitySkillsDirectory,
67261
67650
  this.projectionDirectoryName(entry.runtimeDirectory)
67262
67651
  );
@@ -67270,11 +67659,11 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67270
67659
  } catch (error61) {
67271
67660
  if (!isSymlinkUnsupported(error61)) throw error61;
67272
67661
  }
67273
- const pending = `${destination}.pending-${process.pid}-${(0, import_node_crypto13.randomBytes)(6).toString("hex")}`;
67662
+ const pending = `${destination}.pending-${process.pid}-${(0, import_node_crypto14.randomBytes)(6).toString("hex")}`;
67274
67663
  try {
67275
67664
  await (0, import_promises13.cp)(canonicalDirectory, pending, { recursive: true, errorOnExist: true, force: false });
67276
67665
  await (0, import_promises13.writeFile)(
67277
- (0, import_node_path22.join)(pending, ".alan-compatibility.json"),
67666
+ (0, import_node_path24.join)(pending, ".alan-compatibility.json"),
67278
67667
  `${JSON.stringify({ ...markerFor(entry), canonicalDirectory }, null, 2)}
67279
67668
  `,
67280
67669
  { encoding: "utf8", flag: "wx", mode: 384 }
@@ -67298,7 +67687,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67298
67687
  }
67299
67688
  }
67300
67689
  projectionDirectory(runtimeDirectory) {
67301
- return (0, import_node_path22.join)(this.managedSkillsDirectory, this.projectionDirectoryName(runtimeDirectory));
67690
+ return (0, import_node_path24.join)(this.managedSkillsDirectory, this.projectionDirectoryName(runtimeDirectory));
67302
67691
  }
67303
67692
  projectionDirectoryName(runtimeDirectory) {
67304
67693
  requireSafeRuntimeDirectory(runtimeDirectory);
@@ -67306,14 +67695,14 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
67306
67695
  }
67307
67696
  async withMachineLock(work) {
67308
67697
  await (0, import_promises13.mkdir)(this.skillsStateDirectory, { recursive: true, mode: 448 });
67309
- const lockDirectory = (0, import_node_path22.join)(this.skillsStateDirectory, "manager.lock");
67698
+ const lockDirectory = (0, import_node_path24.join)(this.skillsStateDirectory, "manager.lock");
67310
67699
  const deadline = Date.now() + 3e4;
67311
67700
  while (true) {
67312
67701
  try {
67313
67702
  await (0, import_promises13.mkdir)(lockDirectory, { mode: 448 });
67314
67703
  try {
67315
67704
  await (0, import_promises13.writeFile)(
67316
- (0, import_node_path22.join)(lockDirectory, "owner.json"),
67705
+ (0, import_node_path24.join)(lockDirectory, "owner.json"),
67317
67706
  `${JSON.stringify({ pid: process.pid, acquiredAt: (/* @__PURE__ */ new Date()).toISOString() })}
67318
67707
  `,
67319
67708
  { encoding: "utf8", flag: "wx", mode: 384 }
@@ -67363,7 +67752,7 @@ async function packageMatches(directory, expectedHash) {
67363
67752
  async function readMarker(directory) {
67364
67753
  try {
67365
67754
  const value2 = JSON.parse(
67366
- await (0, import_promises13.readFile)((0, import_node_path22.join)(directory, ".alan-managed.json"), "utf8")
67755
+ await (0, import_promises13.readFile)((0, import_node_path24.join)(directory, ".alan-managed.json"), "utf8")
67367
67756
  );
67368
67757
  if (typeof value2 !== "object" || value2 === null || !("protocolVersion" in value2) || value2.protocolVersion !== SKILLS_PROTOCOL_VERSION || !("skillId" in value2) || typeof value2.skillId !== "string" || !("versionId" in value2) || typeof value2.versionId !== "string" || !("contentHash" in value2) || typeof value2.contentHash !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value2.contentHash)) {
67369
67758
  return null;
@@ -67377,7 +67766,7 @@ async function compatibilityProjectionMatches(destination, canonicalDirectory, e
67377
67766
  const metadata = await (0, import_promises13.lstat)(destination);
67378
67767
  if (metadata.isSymbolicLink()) {
67379
67768
  const target = await (0, import_promises13.readlink)(destination);
67380
- return (0, import_node_path22.resolve)((0, import_node_path22.dirname)(destination), target) === (0, import_node_path22.resolve)(canonicalDirectory);
67769
+ return (0, import_node_path24.resolve)((0, import_node_path24.dirname)(destination), target) === (0, import_node_path24.resolve)(canonicalDirectory);
67381
67770
  }
67382
67771
  if (!metadata.isDirectory()) return false;
67383
67772
  const marker = await readCompatibilityMarker(destination);
@@ -67388,7 +67777,7 @@ async function removeCompatibilityProjection(destination, canonicalDirectory, pr
67388
67777
  const metadata = await (0, import_promises13.lstat)(destination);
67389
67778
  if (metadata.isSymbolicLink()) {
67390
67779
  const target = await (0, import_promises13.readlink)(destination);
67391
- if ((0, import_node_path22.resolve)((0, import_node_path22.dirname)(destination), target) !== (0, import_node_path22.resolve)(canonicalDirectory)) return false;
67780
+ if ((0, import_node_path24.resolve)((0, import_node_path24.dirname)(destination), target) !== (0, import_node_path24.resolve)(canonicalDirectory)) return false;
67392
67781
  await (0, import_promises13.rm)(destination, { force: true });
67393
67782
  return true;
67394
67783
  }
@@ -67400,7 +67789,7 @@ async function removeCompatibilityProjection(destination, canonicalDirectory, pr
67400
67789
  async function readCompatibilityMarker(directory) {
67401
67790
  try {
67402
67791
  const value2 = JSON.parse(
67403
- await (0, import_promises13.readFile)((0, import_node_path22.join)(directory, ".alan-compatibility.json"), "utf8")
67792
+ await (0, import_promises13.readFile)((0, import_node_path24.join)(directory, ".alan-compatibility.json"), "utf8")
67404
67793
  );
67405
67794
  if (value2.protocolVersion !== SKILLS_PROTOCOL_VERSION || typeof value2.skillId !== "string" || typeof value2.versionId !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value2.contentHash) || typeof value2.canonicalDirectory !== "string") {
67406
67795
  return null;
@@ -67440,15 +67829,15 @@ async function legacyFileMatches(directory, expectedHash) {
67440
67829
  try {
67441
67830
  const metadata = await (0, import_promises13.lstat)(directory);
67442
67831
  if (!metadata.isDirectory() || metadata.isSymbolicLink()) return false;
67443
- const content = await (0, import_promises13.readFile)((0, import_node_path22.join)(directory, "SKILL.md"));
67444
- return (0, import_node_crypto13.createHash)("sha256").update(content).digest("hex").slice(0, 16) === expectedHash;
67832
+ const content = await (0, import_promises13.readFile)((0, import_node_path24.join)(directory, "SKILL.md"));
67833
+ return (0, import_node_crypto14.createHash)("sha256").update(content).digest("hex").slice(0, 16) === expectedHash;
67445
67834
  } catch {
67446
67835
  return false;
67447
67836
  }
67448
67837
  }
67449
67838
  async function removeExactLegacySkill(directory, expectedHash) {
67450
67839
  if (!await legacyFileMatches(directory, expectedHash)) return;
67451
- await (0, import_promises13.rm)((0, import_node_path22.join)(directory, "SKILL.md"), { force: true });
67840
+ await (0, import_promises13.rm)((0, import_node_path24.join)(directory, "SKILL.md"), { force: true });
67452
67841
  const remaining = await (0, import_promises13.readdir)(directory);
67453
67842
  if (remaining.length === 0) await (0, import_promises13.rm)(directory, { recursive: true, force: true });
67454
67843
  }
@@ -67462,7 +67851,7 @@ function resolveStorageNamespace(endpointProfile, profileStorageIdentity) {
67462
67851
  }
67463
67852
  const identity = profileStorageIdentity?.trim();
67464
67853
  if (!identity) return endpointProfile;
67465
- const identityHash = (0, import_node_crypto13.createHash)("sha256").update(identity).digest("hex").slice(0, 12);
67854
+ const identityHash = (0, import_node_crypto14.createHash)("sha256").update(identity).digest("hex").slice(0, 12);
67466
67855
  return `${endpointProfile}-${identityHash}`;
67467
67856
  }
67468
67857
  function splitProjectionName(name) {
@@ -67641,9 +68030,6 @@ var SuspensionDetector = class {
67641
68030
  }
67642
68031
  };
67643
68032
 
67644
- // src/core-agent.ts
67645
- var import_node_os14 = require("os");
67646
-
67647
68033
  // src/prompt-context.ts
67648
68034
  function joinLines(lines) {
67649
68035
  return lines.join("\n");
@@ -67948,17 +68334,6 @@ var CoreAgent = class extends AgentRunner {
67948
68334
  delete augmented.GOOGLE_API_KEY;
67949
68335
  }
67950
68336
  Object.assign(augmented, buildProviderAuthEnv(backendKind, providerApiKey));
67951
- if ((0, import_node_os14.platform)() !== "win32") {
67952
- const home = augmented.HOME ?? "/home/user";
67953
- const extraPaths = [`${home}/.local/node/bin`, `${home}/.local/bin`];
67954
- const separator = ":";
67955
- const basePath = augmented.PATH ?? "";
67956
- const existingSegments = new Set(basePath.split(separator).filter(Boolean));
67957
- const missing = extraPaths.filter((p) => !existingSegments.has(p));
67958
- if (missing.length > 0) {
67959
- augmented.PATH = `${missing.join(separator)}${separator}${basePath}`;
67960
- }
67961
- }
67962
68337
  return augmented;
67963
68338
  }
67964
68339
  buildExtraSystemPromptParts(config4) {
@@ -68050,24 +68425,24 @@ ${input2.userRequest}
68050
68425
 
68051
68426
  // src/workspace-run-lease.ts
68052
68427
  var import_promises14 = require("fs/promises");
68053
- var import_node_path23 = require("path");
68428
+ var import_node_path25 = require("path");
68054
68429
  var WORKSPACE_LEASE_CHECK_INTERVAL_MS = 1e3;
68055
68430
  async function hasGitWorkspaceMarker(workspacePath) {
68056
68431
  let directory;
68057
68432
  try {
68058
- directory = await (0, import_promises14.realpath)((0, import_node_path23.resolve)(workspacePath));
68433
+ directory = await (0, import_promises14.realpath)((0, import_node_path25.resolve)(workspacePath));
68059
68434
  } catch {
68060
68435
  return true;
68061
68436
  }
68062
68437
  while (true) {
68063
68438
  try {
68064
- await (0, import_promises14.stat)((0, import_node_path23.join)(directory, ".git"));
68439
+ await (0, import_promises14.stat)((0, import_node_path25.join)(directory, ".git"));
68065
68440
  return true;
68066
68441
  } catch (error61) {
68067
68442
  const code = error61.code;
68068
68443
  if (code !== "ENOENT" && code !== "ENOTDIR") return true;
68069
68444
  }
68070
- const parent = (0, import_node_path23.dirname)(directory);
68445
+ const parent = (0, import_node_path25.dirname)(directory);
68071
68446
  if (parent === directory) return false;
68072
68447
  directory = parent;
68073
68448
  }
@@ -68078,19 +68453,19 @@ async function filesystemIdentity(path2) {
68078
68453
  return `${canonicalPath}:${metadata.dev}:${metadata.ino}`;
68079
68454
  }
68080
68455
  function resolveGitPath(workspacePath, value2) {
68081
- return (0, import_node_path23.isAbsolute)(value2) ? value2 : (0, import_node_path23.resolve)(workspacePath, value2);
68456
+ return (0, import_node_path25.isAbsolute)(value2) ? value2 : (0, import_node_path25.resolve)(workspacePath, value2);
68082
68457
  }
68083
68458
  async function resolveGitIdentityPaths(canonicalWorkspacePath) {
68084
68459
  let directory = canonicalWorkspacePath;
68085
68460
  while (true) {
68086
- const marker = (0, import_node_path23.join)(directory, ".git");
68461
+ const marker = (0, import_node_path25.join)(directory, ".git");
68087
68462
  let markerStats;
68088
68463
  try {
68089
68464
  markerStats = await (0, import_promises14.stat)(marker);
68090
68465
  } catch (error61) {
68091
68466
  const code = error61.code;
68092
68467
  if (code !== "ENOENT" && code !== "ENOTDIR") return null;
68093
- const parent = (0, import_node_path23.dirname)(directory);
68468
+ const parent = (0, import_node_path25.dirname)(directory);
68094
68469
  if (parent === directory) return null;
68095
68470
  directory = parent;
68096
68471
  continue;
@@ -68109,8 +68484,8 @@ async function resolveGitIdentityPaths(canonicalWorkspacePath) {
68109
68484
  const gitDirectory = resolveGitPath(directory, gitDirMatch[1].trim());
68110
68485
  let commonDirectory = gitDirectory;
68111
68486
  try {
68112
- const commonRaw = (await (0, import_promises14.readFile)((0, import_node_path23.join)(gitDirectory, "commondir"), "utf8")).trim();
68113
- if (commonRaw) commonDirectory = (0, import_node_path23.resolve)(gitDirectory, commonRaw);
68487
+ const commonRaw = (await (0, import_promises14.readFile)((0, import_node_path25.join)(gitDirectory, "commondir"), "utf8")).trim();
68488
+ if (commonRaw) commonDirectory = (0, import_node_path25.resolve)(gitDirectory, commonRaw);
68114
68489
  } catch (error61) {
68115
68490
  const code = error61.code;
68116
68491
  if (code !== "ENOENT" && code !== "ENOTDIR") return null;
@@ -68138,7 +68513,7 @@ function createWorkspaceRunLeaseSnapshotProbe(loadSnapshot) {
68138
68513
  return pending.promise;
68139
68514
  };
68140
68515
  return (workspacePath, options) => {
68141
- const key = process.platform === "win32" ? (0, import_node_path23.resolve)(workspacePath).toLowerCase() : (0, import_node_path23.resolve)(workspacePath);
68516
+ const key = process.platform === "win32" ? (0, import_node_path25.resolve)(workspacePath).toLowerCase() : (0, import_node_path25.resolve)(workspacePath);
68142
68517
  const existing = snapshots.get(key);
68143
68518
  if (!existing) return startSnapshot(key, options?.coalescePending === true);
68144
68519
  if (!options?.fresh) return existing.promise;
@@ -68155,7 +68530,7 @@ var DEFAULT_PROBE = {
68155
68530
  snapshot: createWorkspaceRunLeaseSnapshotProbe(snapshotWorkspace),
68156
68531
  pathExists: async (workspacePath) => {
68157
68532
  try {
68158
- await (0, import_promises14.access)((0, import_node_path23.resolve)(workspacePath));
68533
+ await (0, import_promises14.access)((0, import_node_path25.resolve)(workspacePath));
68159
68534
  return true;
68160
68535
  } catch (error61) {
68161
68536
  return error61.code !== "ENOENT";
@@ -68164,11 +68539,11 @@ var DEFAULT_PROBE = {
68164
68539
  };
68165
68540
  async function snapshotWorkspace(workspacePath) {
68166
68541
  try {
68167
- const canonicalWorkspacePath = await (0, import_promises14.realpath)((0, import_node_path23.resolve)(workspacePath));
68542
+ const canonicalWorkspacePath = await (0, import_promises14.realpath)((0, import_node_path25.resolve)(workspacePath));
68168
68543
  const gitPaths = await resolveGitIdentityPaths(canonicalWorkspacePath);
68169
68544
  if (!gitPaths) return null;
68170
68545
  return {
68171
- workspacePath: (0, import_node_path23.resolve)(workspacePath),
68546
+ workspacePath: (0, import_node_path25.resolve)(workspacePath),
68172
68547
  workspaceIdentity: await filesystemIdentity(canonicalWorkspacePath),
68173
68548
  // The common Git directory identifies the checkout. A coding agent may
68174
68549
  // legitimately add or update origin without replacing that directory;
@@ -68221,7 +68596,7 @@ var WorkspaceRunLease = class _WorkspaceRunLease {
68221
68596
  const retryDelayMs = Math.max(0, options.retryDelayMs ?? DEFAULT_CAPTURE_RETRY_DELAY_MS);
68222
68597
  const captured = [];
68223
68598
  for (const target of targets) {
68224
- const normalizedTarget = { ...target, workspacePath: (0, import_node_path23.resolve)(target.workspacePath) };
68599
+ const normalizedTarget = { ...target, workspacePath: (0, import_node_path25.resolve)(target.workspacePath) };
68225
68600
  const identity = await captureIdentity(
68226
68601
  probe,
68227
68602
  normalizedTarget.workspacePath,
@@ -68324,15 +68699,15 @@ function applyLeaseCheckResult(input2) {
68324
68699
 
68325
68700
  // src/daemon/admission.ts
68326
68701
  var import_node_fs23 = require("fs");
68327
- var import_node_path26 = require("path");
68702
+ var import_node_path28 = require("path");
68328
68703
 
68329
68704
  // src/workspace-relocation.ts
68330
68705
  var import_node_child_process6 = require("child_process");
68331
68706
  var import_node_fs22 = require("fs");
68332
- var import_node_path24 = require("path");
68707
+ var import_node_path26 = require("path");
68333
68708
  var MAX_RELOCATION_CANDIDATES = 200;
68334
68709
  var DEFAULT_PROBE2 = {
68335
- childDirectories: (parentPath, limit) => (0, import_node_fs22.readdirSync)(parentPath, { withFileTypes: true }).filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path24.join)(parentPath, entry.name)),
68710
+ childDirectories: (parentPath, limit) => (0, import_node_fs22.readdirSync)(parentPath, { withFileTypes: true }).filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path26.join)(parentPath, entry.name)),
68336
68711
  gitRemoteUrl: (candidatePath) => {
68337
68712
  const result = (0, import_node_child_process6.spawnSync)("git", ["-C", candidatePath, "config", "--get", "remote.origin.url"], {
68338
68713
  encoding: "utf8",
@@ -68363,7 +68738,7 @@ function workspaceMatchesExpectedRepositories(input2) {
68363
68738
  input2.expectedRepoUrls.map(normalizeRepositoryIdentity).filter((identity2) => Boolean(identity2))
68364
68739
  );
68365
68740
  if (identities.size === 0) return false;
68366
- const remote = (input2.probe ?? DEFAULT_PROBE2).gitRemoteUrl((0, import_node_path24.resolve)(input2.workspacePath));
68741
+ const remote = (input2.probe ?? DEFAULT_PROBE2).gitRemoteUrl((0, import_node_path26.resolve)(input2.workspacePath));
68367
68742
  const identity = remote ? normalizeRepositoryIdentity(remote) : null;
68368
68743
  return Boolean(identity && identities.has(identity));
68369
68744
  }
@@ -68373,8 +68748,8 @@ function discoverRelocatedWorkspace(input2) {
68373
68748
  );
68374
68749
  if (identities.size === 0) return null;
68375
68750
  const searchRoots = [
68376
- (0, import_node_path24.dirname)((0, import_node_path24.resolve)(input2.missingPath)),
68377
- ...(input2.approvedWorkspacePaths ?? []).map((path2) => (0, import_node_path24.dirname)((0, import_node_path24.resolve)(path2)))
68751
+ (0, import_node_path26.dirname)((0, import_node_path26.resolve)(input2.missingPath)),
68752
+ ...(input2.approvedWorkspacePaths ?? []).map((path2) => (0, import_node_path26.dirname)((0, import_node_path26.resolve)(path2)))
68378
68753
  ].filter((path2, index, paths) => paths.indexOf(path2) === index);
68379
68754
  const candidates = [];
68380
68755
  for (const root of searchRoots) {
@@ -68386,10 +68761,10 @@ function discoverRelocatedWorkspace(input2) {
68386
68761
  }
68387
68762
  }
68388
68763
  const matches = [];
68389
- for (const candidate of new Set(candidates.map((path2) => (0, import_node_path24.resolve)(path2)))) {
68764
+ for (const candidate of new Set(candidates.map((path2) => (0, import_node_path26.resolve)(path2)))) {
68390
68765
  const remote = (input2.probe ?? DEFAULT_PROBE2).gitRemoteUrl(candidate);
68391
68766
  const identity = remote ? normalizeRepositoryIdentity(remote) : null;
68392
- if (identity && identities.has(identity)) matches.push((0, import_node_path24.resolve)(candidate));
68767
+ if (identity && identities.has(identity)) matches.push((0, import_node_path26.resolve)(candidate));
68393
68768
  if (matches.length > 1) return null;
68394
68769
  }
68395
68770
  return matches[0] ?? null;
@@ -68397,7 +68772,7 @@ function discoverRelocatedWorkspace(input2) {
68397
68772
 
68398
68773
  // src/daemon/workspace.ts
68399
68774
  var import_node_child_process7 = require("child_process");
68400
- var import_node_path25 = require("path");
68775
+ var import_node_path27 = require("path");
68401
68776
 
68402
68777
  // src/git/tree.ts
68403
68778
  var BRANCH_LABEL_MAX_LENGTH = 256;
@@ -68468,12 +68843,12 @@ function gitSafe(cwd, args) {
68468
68843
  }
68469
68844
  }
68470
68845
  function statusLocalWorkspace(params) {
68471
- const requestedPath = (0, import_node_path25.resolve)(requiredString(params, "workspacePath"));
68846
+ const requestedPath = (0, import_node_path27.resolve)(requiredString(params, "workspacePath"));
68472
68847
  const rootOutput = gitSafe(requestedPath, ["rev-parse", "--show-toplevel"]);
68473
68848
  if (!rootOutput) {
68474
68849
  throw new Error("The selected folder is not inside a Git repository");
68475
68850
  }
68476
- const root = (0, import_node_path25.resolve)(rootOutput);
68851
+ const root = (0, import_node_path27.resolve)(rootOutput);
68477
68852
  const tree = preflightGitTree(root, git);
68478
68853
  const headSha = gitSafe(root, ["rev-parse", "HEAD"]) || null;
68479
68854
  const upstream = gitSafe(root, ["rev-parse", "--abbrev-ref", "@{upstream}"]);
@@ -68594,22 +68969,22 @@ function settleProvider(ctx, backendKind, runtimeCommand) {
68594
68969
  function expectedRepositoryUrls(payload, explicitWorkspacePath) {
68595
68970
  return [
68596
68971
  ...(payload.repoLocalPaths ?? []).filter(
68597
- (repo) => explicitWorkspacePath ? (0, import_node_path26.resolve)(repo.localPath) === (0, import_node_path26.resolve)(explicitWorkspacePath) : false
68972
+ (repo) => explicitWorkspacePath ? (0, import_node_path28.resolve)(repo.localPath) === (0, import_node_path28.resolve)(explicitWorkspacePath) : false
68598
68973
  ).map((repo) => repo.repoUrl),
68599
68974
  ...payload.localRepoUrls ?? []
68600
68975
  ];
68601
68976
  }
68602
68977
  function relocateWorkspace(ctx, payload, explicitWorkspacePath, expectedRepoUrls) {
68603
- const previousPath = (0, import_node_path26.resolve)(explicitWorkspacePath);
68978
+ const previousPath = (0, import_node_path28.resolve)(explicitWorkspacePath);
68604
68979
  const remembered = ctx.workspaceRelocations.get(previousPath);
68605
68980
  const rememberedPath = remembered?.canonicalPath;
68606
- const relocated = rememberedPath && workspaceMatchesExpectedRepositories({ workspacePath: rememberedPath, expectedRepoUrls }) ? (0, import_node_path26.resolve)(rememberedPath) : discoverRelocatedWorkspace({
68981
+ const relocated = rememberedPath && workspaceMatchesExpectedRepositories({ workspacePath: rememberedPath, expectedRepoUrls }) ? (0, import_node_path28.resolve)(rememberedPath) : discoverRelocatedWorkspace({
68607
68982
  missingPath: explicitWorkspacePath,
68608
68983
  approvedWorkspacePaths: payload.approvedWorkspacePaths,
68609
68984
  expectedRepoUrls
68610
68985
  });
68611
68986
  if (!relocated) return null;
68612
- if (!remembered || (0, import_node_path26.resolve)(remembered.canonicalPath) !== relocated) {
68987
+ if (!remembered || (0, import_node_path28.resolve)(remembered.canonicalPath) !== relocated) {
68613
68988
  ctx.workspaceRelocations.set(previousPath, {
68614
68989
  conversationId: payload.conversationId,
68615
68990
  runId: payload.runId,
@@ -69114,7 +69489,7 @@ async function launchRun(ctx, payload, plan) {
69114
69489
 
69115
69490
  // src/daemon/journal.ts
69116
69491
  var import_node_fs24 = require("fs");
69117
- var import_node_path27 = require("path");
69492
+ var import_node_path29 = require("path");
69118
69493
  var JOURNAL_VERSION = 1;
69119
69494
  var INTERRUPTED_ENTRY_TTL_MS = 24 * 60 * 6e4;
69120
69495
  function isEntry(value2) {
@@ -69258,7 +69633,7 @@ var RuntimeRunJournal = class {
69258
69633
  }
69259
69634
  persist() {
69260
69635
  const pendingPath = `${this.path}.pending`;
69261
- (0, import_node_fs24.mkdirSync)((0, import_node_path27.dirname)(this.path), { recursive: true });
69636
+ (0, import_node_fs24.mkdirSync)((0, import_node_path29.dirname)(this.path), { recursive: true });
69262
69637
  try {
69263
69638
  (0, import_node_fs24.writeFileSync)(
69264
69639
  pendingPath,
@@ -69429,13 +69804,13 @@ function bindLocalApi(server, port) {
69429
69804
 
69430
69805
  // src/daemon/log.ts
69431
69806
  var import_node_fs25 = require("fs");
69432
- var import_node_path28 = require("path");
69807
+ var import_node_path30 = require("path");
69433
69808
  var RECENT_LIMIT = 200;
69434
69809
  var MAX_BYTES = 5 * 1024 * 1024;
69435
69810
  var SIZE_CHECK_EVERY = 256;
69436
69811
  function openDaemonLog(configPath) {
69437
- const directory = (0, import_node_path28.join)((0, import_node_path28.dirname)(configPath), "logs");
69438
- const path2 = (0, import_node_path28.join)(directory, "daemon.jsonl");
69812
+ const directory = (0, import_node_path30.join)((0, import_node_path30.dirname)(configPath), "logs");
69813
+ const path2 = (0, import_node_path30.join)(directory, "daemon.jsonl");
69439
69814
  const recent = [];
69440
69815
  let handle = null;
69441
69816
  let written = 0;
@@ -70136,7 +70511,7 @@ async function handleNativeHook(deps, req, res) {
70136
70511
  }
70137
70512
 
70138
70513
  // src/daemon/routes/owner.ts
70139
- var import_node_crypto14 = require("crypto");
70514
+ var import_node_crypto15 = require("crypto");
70140
70515
  var MAX_OUTSTANDING_CHALLENGES = 32;
70141
70516
  function handleOwner(deps, res) {
70142
70517
  const now = Date.now();
@@ -70148,7 +70523,7 @@ function handleOwner(deps, res) {
70148
70523
  if (!oldest) break;
70149
70524
  deps.adoptionChallenges.delete(oldest);
70150
70525
  }
70151
- const challenge = (0, import_node_crypto14.randomBytes)(24).toString("base64url");
70526
+ const challenge = (0, import_node_crypto15.randomBytes)(24).toString("base64url");
70152
70527
  deps.adoptionChallenges.set(challenge, now + LOCAL_SERVICE_CHALLENGE_TTL_MS);
70153
70528
  const unsigned = {
70154
70529
  version: LOCAL_SERVICE_OWNER_VERSION,
@@ -70433,10 +70808,10 @@ var BindingSwitchGitError = class extends Error {
70433
70808
 
70434
70809
  // src/git/repo.ts
70435
70810
  var import_node_child_process8 = require("child_process");
70436
- var import_node_crypto15 = require("crypto");
70811
+ var import_node_crypto16 = require("crypto");
70437
70812
  var import_node_fs27 = require("fs");
70438
70813
  var import_node_os15 = require("os");
70439
- var import_node_path29 = require("path");
70814
+ var import_node_path31 = require("path");
70440
70815
  var import_node_url = require("url");
70441
70816
  var LOCAL_GIT_TIMEOUT_MS = 1e4;
70442
70817
  var NETWORK_GIT_TIMEOUT_MS = 3e4;
@@ -70468,8 +70843,8 @@ async function waitForCheckpointTestBarrier() {
70468
70843
  const barrierDir = process.env.NODE_ENV === "test" ? process.env.ALAN_TEST_GIT_CHECKPOINT_BARRIER_DIR : void 0;
70469
70844
  if (!barrierDir) return;
70470
70845
  (0, import_node_fs27.mkdirSync)(barrierDir, { recursive: true });
70471
- const readyPath = (0, import_node_path29.join)(barrierDir, "ready");
70472
- const releasePath = (0, import_node_path29.join)(barrierDir, "release");
70846
+ const readyPath = (0, import_node_path31.join)(barrierDir, "ready");
70847
+ const releasePath = (0, import_node_path31.join)(barrierDir, "release");
70473
70848
  (0, import_node_fs27.writeFileSync)(readyPath, "ready\n");
70474
70849
  const deadline = Date.now() + 5e3;
70475
70850
  while (!(0, import_node_fs27.existsSync)(releasePath)) {
@@ -70486,8 +70861,8 @@ async function waitForCheckpointFinalizeTestBarrier() {
70486
70861
  const barrierDir = process.env.NODE_ENV === "test" ? process.env.ALAN_TEST_GIT_CHECKPOINT_FINALIZE_BARRIER_DIR : void 0;
70487
70862
  if (!barrierDir) return;
70488
70863
  (0, import_node_fs27.mkdirSync)(barrierDir, { recursive: true });
70489
- const readyPath = (0, import_node_path29.join)(barrierDir, "ready");
70490
- const releasePath = (0, import_node_path29.join)(barrierDir, "release");
70864
+ const readyPath = (0, import_node_path31.join)(barrierDir, "ready");
70865
+ const releasePath = (0, import_node_path31.join)(barrierDir, "release");
70491
70866
  (0, import_node_fs27.writeFileSync)(readyPath, "ready\n");
70492
70867
  const deadline = Date.now() + 5e3;
70493
70868
  while (!(0, import_node_fs27.existsSync)(releasePath)) {
@@ -70628,7 +71003,7 @@ function acquireCheckpointRepositoryLocks(repoRoot) {
70628
71003
  "checkpoint_lock_unavailable"
70629
71004
  );
70630
71005
  const locks = {
70631
- headLockPath: (0, import_node_path29.join)(gitDir, "HEAD.lock"),
71006
+ headLockPath: (0, import_node_path31.join)(gitDir, "HEAD.lock"),
70632
71007
  headLockHeld: false,
70633
71008
  indexLockPath: `${indexPath}.lock`,
70634
71009
  indexLockHeld: false,
@@ -70670,8 +71045,8 @@ function assertCheckpointHead(repoRoot, expectedRef, expectedHeadSha) {
70670
71045
  }
70671
71046
  }
70672
71047
  function createCheckpointIndexBaseline(repoRoot, checkpointSha) {
70673
- const tempDir = (0, import_node_fs27.mkdtempSync)((0, import_node_path29.join)((0, import_node_os15.tmpdir)(), "alan-checkpoint-index-"));
70674
- const indexPath = (0, import_node_path29.join)(tempDir, "index");
71048
+ const tempDir = (0, import_node_fs27.mkdtempSync)((0, import_node_path31.join)((0, import_node_os15.tmpdir)(), "alan-checkpoint-index-"));
71049
+ const indexPath = (0, import_node_path31.join)(tempDir, "index");
70675
71050
  try {
70676
71051
  runGitWithOptions(
70677
71052
  repoRoot,
@@ -70732,7 +71107,7 @@ function commonRequest(params) {
70732
71107
  return {
70733
71108
  switchId: requiredString2(params, "switchId"),
70734
71109
  repoKey: requiredString2(params, "repoKey"),
70735
- repoPath: (0, import_node_path29.resolve)(requiredString2(params, "repoPath"))
71110
+ repoPath: (0, import_node_path31.resolve)(requiredString2(params, "repoPath"))
70736
71111
  };
70737
71112
  }
70738
71113
  function assertCommitSha(sha, key) {
@@ -70771,9 +71146,9 @@ function expandScpSyntax(value2) {
70771
71146
  return scp ? `ssh://${scp[1]}@${scp[2]}/${scp[3]}` : value2;
70772
71147
  }
70773
71148
  function localRemoteUrl(repoRoot, value2) {
70774
- const looksLocal = (0, import_node_path29.isAbsolute)(value2) || value2.startsWith("./") || value2.startsWith("../");
71149
+ const looksLocal = (0, import_node_path31.isAbsolute)(value2) || value2.startsWith("./") || value2.startsWith("../");
70775
71150
  if (!looksLocal) return null;
70776
- const absolute = (0, import_node_path29.isAbsolute)(value2) ? value2 : (0, import_node_path29.resolve)(repoRoot, value2);
71151
+ const absolute = (0, import_node_path31.isAbsolute)(value2) ? value2 : (0, import_node_path31.resolve)(repoRoot, value2);
70777
71152
  return `file://${trimRepoPath(canonicalPathWithMissingTail(absolute))}`;
70778
71153
  }
70779
71154
  function assertRemoteIsAllowed(parsed) {
@@ -70850,19 +71225,19 @@ function inspectedRemoteUrl(repoRoot, params) {
70850
71225
  }
70851
71226
  function canonicalPathWithMissingTail(path2) {
70852
71227
  const missingSegments = [];
70853
- let cursor = (0, import_node_path29.resolve)(path2);
71228
+ let cursor = (0, import_node_path31.resolve)(path2);
70854
71229
  while (!(0, import_node_fs27.existsSync)(cursor)) {
70855
- const parent = (0, import_node_path29.dirname)(cursor);
71230
+ const parent = (0, import_node_path31.dirname)(cursor);
70856
71231
  if (parent === cursor) {
70857
71232
  throw new BindingSwitchGitError(
70858
71233
  "path_canonicalization_failed",
70859
71234
  "The selected path has no existing canonical ancestor"
70860
71235
  );
70861
71236
  }
70862
- missingSegments.unshift((0, import_node_path29.basename)(cursor));
71237
+ missingSegments.unshift((0, import_node_path31.basename)(cursor));
70863
71238
  cursor = parent;
70864
71239
  }
70865
- return (0, import_node_path29.join)(import_node_fs27.realpathSync.native(cursor), ...missingSegments);
71240
+ return (0, import_node_path31.join)(import_node_fs27.realpathSync.native(cursor), ...missingSegments);
70866
71241
  }
70867
71242
  function resolveRepositoryRoot(requestedPath) {
70868
71243
  if (!(0, import_node_fs27.existsSync)(requestedPath)) {
@@ -70878,7 +71253,7 @@ function resolveRepositoryRoot(requestedPath) {
70878
71253
  "The selected folder is not inside a Git repository"
70879
71254
  );
70880
71255
  }
70881
- return import_node_fs27.realpathSync.native((0, import_node_path29.resolve)(root.stdout.trim()));
71256
+ return import_node_fs27.realpathSync.native((0, import_node_path31.resolve)(root.stdout.trim()));
70882
71257
  }
70883
71258
  function listWorktrees(repoRoot) {
70884
71259
  return runGit(repoRoot, ["worktree", "list", "--porcelain"]).split("\n\n").flatMap((entry) => {
@@ -70897,7 +71272,7 @@ function resolveAuthorizedRepository(params, requireTrustedContext = false) {
70897
71272
  const { repoPath } = commonRequest(params);
70898
71273
  const repoRoot = resolveRepositoryRoot(repoPath);
70899
71274
  const expectedRepoRoot = requireTrustedContext ? requiredString2(params, "expectedRepoRoot") : optionalString(params, "expectedRepoRoot");
70900
- if (expectedRepoRoot && resolveRepositoryRoot((0, import_node_path29.resolve)(expectedRepoRoot)) !== repoRoot) {
71275
+ if (expectedRepoRoot && resolveRepositoryRoot((0, import_node_path31.resolve)(expectedRepoRoot)) !== repoRoot) {
70901
71276
  throw new BindingSwitchGitError(
70902
71277
  "repository_path_changed",
70903
71278
  "The selected path now resolves to a different Git repository"
@@ -70905,7 +71280,7 @@ function resolveAuthorizedRepository(params, requireTrustedContext = false) {
70905
71280
  }
70906
71281
  const projectPath = requireTrustedContext ? requiredString2(params, "projectPath") : optionalString(params, "projectPath");
70907
71282
  if (!projectPath) return repoRoot;
70908
- const projectRoot = resolveRepositoryRoot((0, import_node_path29.resolve)(projectPath));
71283
+ const projectRoot = resolveRepositoryRoot((0, import_node_path31.resolve)(projectPath));
70909
71284
  const registrations = listWorktrees(projectRoot);
70910
71285
  const registered = registrations.find(({ path: path2 }) => path2 === repoRoot);
70911
71286
  if (!registered) {
@@ -70934,8 +71309,8 @@ function updateLengthPrefixed(hash2, value2) {
70934
71309
  hash2.update("\0");
70935
71310
  }
70936
71311
  function proposedTreeSha(repoRoot, headSha) {
70937
- const tempDir = (0, import_node_fs27.mkdtempSync)((0, import_node_path29.join)((0, import_node_os15.tmpdir)(), "alan-switch-index-"));
70938
- const indexPath = (0, import_node_path29.join)(tempDir, "index");
71312
+ const tempDir = (0, import_node_fs27.mkdtempSync)((0, import_node_path31.join)((0, import_node_os15.tmpdir)(), "alan-switch-index-"));
71313
+ const indexPath = (0, import_node_path31.join)(tempDir, "index");
70939
71314
  const options = { env: { GIT_INDEX_FILE: indexPath } };
70940
71315
  try {
70941
71316
  if (headSha) {
@@ -70968,7 +71343,7 @@ function statusFingerprint(repoRoot, porcelain, proposedTree) {
70968
71343
  "git_status_unreadable"
70969
71344
  );
70970
71345
  const untrackedPaths = untrackedRaw.split("\0").filter(Boolean);
70971
- const hash2 = (0, import_node_crypto15.createHash)("sha256");
71346
+ const hash2 = (0, import_node_crypto16.createHash)("sha256");
70972
71347
  updateLengthPrefixed(hash2, porcelain);
70973
71348
  updateLengthPrefixed(hash2, proposedTree);
70974
71349
  updateLengthPrefixed(hash2, unstagedPatch);
@@ -71523,9 +71898,9 @@ async function stopBackgroundTaskForRun(deps, payload) {
71523
71898
 
71524
71899
  // src/daemon/sweep.ts
71525
71900
  var import_node_fs29 = require("fs");
71526
- var import_node_path30 = require("path");
71901
+ var import_node_path32 = require("path");
71527
71902
  function retiredPaths(configPath) {
71528
- const directory = (0, import_node_path30.dirname)(configPath);
71903
+ const directory = (0, import_node_path32.dirname)(configPath);
71529
71904
  return [
71530
71905
  // The durable event outbox and its journal.
71531
71906
  `${configPath}.event-outbox.enc`,
@@ -71535,7 +71910,7 @@ function retiredPaths(configPath) {
71535
71910
  `${configPath}.native-transcript-cursors.json`,
71536
71911
  `${configPath}.native-transcript-cursors.json.d`,
71537
71912
  `${configPath}.native-transcript-cursors.json.migrated`,
71538
- (0, import_node_path30.join)(directory, "native-hook-inbox")
71913
+ (0, import_node_path32.join)(directory, "native-hook-inbox")
71539
71914
  ];
71540
71915
  }
71541
71916
  function sweepRetiredArtifacts(configPath) {
@@ -71558,10 +71933,10 @@ var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12
71558
71933
  async function startDaemon(args) {
71559
71934
  bindConfigPath(args);
71560
71935
  const stored = readConfig();
71561
- const installationId = stored.installationId ?? (0, import_node_crypto16.randomUUID)();
71936
+ const installationId = stored.installationId ?? (0, import_node_crypto17.randomUUID)();
71562
71937
  const configPath = getConfigPath();
71563
71938
  const endpointProfile = stored.endpointProfile ?? resolveEndpointProfile(args);
71564
- const daemonSessionId = (0, import_node_crypto16.randomUUID)();
71939
+ const daemonSessionId = (0, import_node_crypto17.randomUUID)();
71565
71940
  let heartbeatSeq = 0;
71566
71941
  const runtimeId = argValue(args, "--runtime-id") ?? process.env.ALAN_RUNTIME_ID ?? stored.runtimeId;
71567
71942
  const runtimeTokenOverride = argValue(args, "--token") ?? process.env.ALAN_RUNTIME_TOKEN;
@@ -71581,9 +71956,9 @@ async function startDaemon(args) {
71581
71956
  wsUrl = endpointMismatch.expectedWsUrl;
71582
71957
  }
71583
71958
  let localApiPort = getLocalApiPort(args, stored);
71584
- const localApiToken = stored.localApiToken ?? (0, import_node_crypto16.randomBytes)(24).toString("hex");
71585
- const localServiceId = stored.localServiceId ?? (0, import_node_crypto16.randomUUID)();
71586
- const localServiceSecret = stored.localServiceSecret ?? (0, import_node_crypto16.randomBytes)(32).toString("base64url");
71959
+ const localApiToken = stored.localApiToken ?? (0, import_node_crypto17.randomBytes)(24).toString("hex");
71960
+ const localServiceId = stored.localServiceId ?? (0, import_node_crypto17.randomUUID)();
71961
+ const localServiceSecret = stored.localServiceSecret ?? (0, import_node_crypto17.randomBytes)(32).toString("base64url");
71587
71962
  const localServiceStartedAtMs = Date.now();
71588
71963
  if (stored.daemonEpoch !== void 0 && (!Number.isSafeInteger(stored.daemonEpoch) || stored.daemonEpoch < 0 || stored.daemonEpoch >= Number.MAX_SAFE_INTEGER)) {
71589
71964
  throw new Error("daemon config contains an invalid durable epoch; repair the runtime config");
@@ -71739,7 +72114,7 @@ async function startDaemon(args) {
71739
72114
  const workspaceRelocations = /* @__PURE__ */ new Map();
71740
72115
  for (const relocation of stored.workspaceRelocations ?? []) {
71741
72116
  if (relocation?.conversationId && relocation.runId && relocation.previousPath && relocation.canonicalPath) {
71742
- workspaceRelocations.set((0, import_node_path31.resolve)(relocation.previousPath), relocation);
72117
+ workspaceRelocations.set((0, import_node_path33.resolve)(relocation.previousPath), relocation);
71743
72118
  }
71744
72119
  }
71745
72120
  if (stored.localApiPort !== localApiPort || stored.localApiToken !== localApiToken || stored.localServiceId !== localServiceId || stored.localServiceSecret !== localServiceSecret || stored.daemonEpoch !== daemonEpoch || stored.installationId !== installationId) {
@@ -72491,10 +72866,10 @@ async function startDaemon(args) {
72491
72866
 
72492
72867
  // src/service-manager.ts
72493
72868
  var import_node_child_process9 = require("child_process");
72494
- var import_node_crypto17 = require("crypto");
72869
+ var import_node_crypto18 = require("crypto");
72495
72870
  var import_node_fs30 = require("fs");
72496
72871
  var import_node_os17 = require("os");
72497
- var import_node_path32 = require("path");
72872
+ var import_node_path34 = require("path");
72498
72873
  var SERVICE_LABEL = "ai.tryalan.agent";
72499
72874
  var SYSTEMD_UNIT = "alan-agent.service";
72500
72875
  var WINDOWS_TASK = "Alan Agent";
@@ -72539,8 +72914,8 @@ function buildDarwinServicePlan(input2, daemonArgs, names) {
72539
72914
  if (userId === void 0) throw new Error("Cannot determine the current macOS user ID");
72540
72915
  const domain2 = `gui/${userId}`;
72541
72916
  const serviceTarget = `${domain2}/${names.launchd}`;
72542
- const manifestPath = (0, import_node_path32.join)(input2.homeDir, "Library", "LaunchAgents", `${names.launchd}.plist`);
72543
- const logDir = (0, import_node_path32.join)(resolveAgentConfigDirectory(input2.profile, input2.homeDir), "logs");
72917
+ const manifestPath = (0, import_node_path34.join)(input2.homeDir, "Library", "LaunchAgents", `${names.launchd}.plist`);
72918
+ const logDir = (0, import_node_path34.join)(resolveAgentConfigDirectory(input2.profile, input2.homeDir), "logs");
72544
72919
  const programArguments = daemonArgs.map((arg) => ` <string>${xml(arg)}</string>`).join("\n");
72545
72920
  const environmentEntries2 = Object.entries(input2.environment ?? {}).map(([key, value2]) => ` <key>${xml(key)}</key>
72546
72921
  <string>${xml(value2)}</string>`).join("\n");
@@ -72569,9 +72944,9 @@ ${environmentBlock} <key>RunAtLoad</key>
72569
72944
  <key>ThrottleInterval</key>
72570
72945
  <integer>5</integer>
72571
72946
  <key>StandardOutPath</key>
72572
- <string>${xml((0, import_node_path32.join)(logDir, "daemon-launcher.log"))}</string>
72947
+ <string>${xml((0, import_node_path34.join)(logDir, "daemon-launcher.log"))}</string>
72573
72948
  <key>StandardErrorPath</key>
72574
- <string>${xml((0, import_node_path32.join)(logDir, "daemon-launcher-error.log"))}</string>
72949
+ <string>${xml((0, import_node_path34.join)(logDir, "daemon-launcher-error.log"))}</string>
72575
72950
  </dict>
72576
72951
  </plist>
72577
72952
  `;
@@ -72647,7 +73022,7 @@ ${environmentBlock} <key>RunAtLoad</key>
72647
73022
  };
72648
73023
  }
72649
73024
  function buildLinuxServicePlan(input2, daemonArgs, names) {
72650
- const manifestPath = (0, import_node_path32.join)(input2.homeDir, ".config", "systemd", "user", names.systemd);
73025
+ const manifestPath = (0, import_node_path34.join)(input2.homeDir, ".config", "systemd", "user", names.systemd);
72651
73026
  const environmentLines = Object.entries(input2.environment ?? {}).map(([key, value2]) => `Environment=${systemdArg(`${key}=${value2}`)}`).join("\n");
72652
73027
  const manifest = `[Unit]
72653
73028
  Description=Alan local agent daemon
@@ -72732,7 +73107,7 @@ WantedBy=default.target
72732
73107
  };
72733
73108
  }
72734
73109
  function buildWindowsServicePlan(input2, names) {
72735
- const logDir = import_node_path32.win32.join(resolveAgentConfigDirectory(input2.profile, input2.homeDir), "logs");
73110
+ const logDir = import_node_path34.win32.join(resolveAgentConfigDirectory(input2.profile, input2.homeDir), "logs");
72736
73111
  const legacyEnvironmentPrefix = Object.entries(input2.environment ?? {}).map(([key, value2]) => `$env:${key} = ${powershellLiteral(value2)}`).join("; ");
72737
73112
  const legacyDirectArguments = [input2.cliEntry, "daemon", "--profile", input2.profile].map((part) => part.includes(" ") ? `"${part}"` : part).join(" ");
72738
73113
  const legacyExecutable = legacyEnvironmentPrefix ? "powershell.exe" : input2.nodeExecutable;
@@ -72746,14 +73121,14 @@ function buildWindowsServicePlan(input2, names) {
72746
73121
  "$startInfo = [System.Diagnostics.ProcessStartInfo]::new()",
72747
73122
  `$startInfo.FileName = ${powershellLiteral(input2.nodeExecutable)}`,
72748
73123
  `$startInfo.Arguments = ${powershellLiteral(daemonArguments)}`,
72749
- `$startInfo.WorkingDirectory = ${powershellLiteral(import_node_path32.win32.dirname(input2.cliEntry))}`,
73124
+ `$startInfo.WorkingDirectory = ${powershellLiteral(import_node_path34.win32.dirname(input2.cliEntry))}`,
72750
73125
  "$startInfo.UseShellExecute = $false",
72751
73126
  "$startInfo.CreateNoWindow = $true",
72752
73127
  "$startInfo.RedirectStandardOutput = $true",
72753
73128
  "$startInfo.RedirectStandardError = $true",
72754
73129
  ...environmentStatements,
72755
- `$stdout = [System.IO.File]::Open(${powershellLiteral(import_node_path32.win32.join(logDir, "daemon-launcher.log"))}, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite)`,
72756
- `$stderr = [System.IO.File]::Open(${powershellLiteral(import_node_path32.win32.join(logDir, "daemon-launcher-error.log"))}, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite)`,
73130
+ `$stdout = [System.IO.File]::Open(${powershellLiteral(import_node_path34.win32.join(logDir, "daemon-launcher.log"))}, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite)`,
73131
+ `$stderr = [System.IO.File]::Open(${powershellLiteral(import_node_path34.win32.join(logDir, "daemon-launcher-error.log"))}, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite)`,
72757
73132
  "$process = [System.Diagnostics.Process]::new()",
72758
73133
  "$process.StartInfo = $startInfo",
72759
73134
  "try { if (-not $process.Start()) { throw 'Alan daemon process did not start' }; $stdoutCopy = $process.StandardOutput.BaseStream.CopyToAsync($stdout); $stderrCopy = $process.StandardError.BaseStream.CopyToAsync($stderr); $process.WaitForExit(); [System.Threading.Tasks.Task]::WaitAll([System.Threading.Tasks.Task[]]@($stdoutCopy, $stderrCopy)); $exitCode = $process.ExitCode } finally { $stdout.Dispose(); $stderr.Dispose(); $process.Dispose() }",
@@ -72762,7 +73137,7 @@ function buildWindowsServicePlan(input2, names) {
72762
73137
  const executable = powershellLiteral("powershell.exe");
72763
73138
  const launcherArguments = `-NoProfile -NonInteractive -WindowStyle Hidden -EncodedCommand ${Buffer.from(launcherScript, "utf16le").toString("base64")}`;
72764
73139
  const settingsScript = "New-ScheduledTaskSettingsSet -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) -ExecutionTimeLimit ([TimeSpan]::Zero) -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries";
72765
- const ownerMarker = `Alan daemon owner v1 ${(0, import_node_crypto17.createHash)("sha256").update(
73140
+ const ownerMarker = `Alan daemon owner v1 ${(0, import_node_crypto18.createHash)("sha256").update(
72766
73141
  JSON.stringify({
72767
73142
  executable: input2.nodeExecutable,
72768
73143
  cliEntry: input2.cliEntry,
@@ -72770,18 +73145,18 @@ function buildWindowsServicePlan(input2, names) {
72770
73145
  taskBaseName: names.windows
72771
73146
  })
72772
73147
  ).digest("hex")}`;
72773
- const definitionMarker = `${ownerMarker}; definition v3 ${(0, import_node_crypto17.createHash)("sha256").update(
73148
+ const definitionMarker = `${ownerMarker}; definition v3 ${(0, import_node_crypto18.createHash)("sha256").update(
72774
73149
  JSON.stringify({
72775
73150
  executable: "powershell.exe",
72776
73151
  launcherArguments,
72777
- workingDirectory: import_node_path32.win32.dirname(input2.cliEntry),
73152
+ workingDirectory: import_node_path34.win32.dirname(input2.cliEntry),
72778
73153
  settingsScript,
72779
73154
  taskBaseName: names.windows
72780
73155
  })
72781
73156
  ).digest("hex")}`;
72782
73157
  const windowsDefinitionContext = [
72783
73158
  `$expectedLauncherArguments = ${powershellLiteral(launcherArguments)}`,
72784
- `$expectedWorkingDirectory = ${powershellLiteral(import_node_path32.win32.dirname(input2.cliEntry))}`,
73159
+ `$expectedWorkingDirectory = ${powershellLiteral(import_node_path34.win32.dirname(input2.cliEntry))}`,
72785
73160
  `$expectedOwnerMarker = ${powershellLiteral(`${ownerMarker};`)}`,
72786
73161
  `$expectedDefinitionMarker = ${powershellLiteral(definitionMarker)}`,
72787
73162
  `$expectedLegacyExecutable = ${powershellLiteral(legacyExecutable)}`,
@@ -72924,13 +73299,13 @@ function currentServicePlan(args, runtime, options = {}) {
72924
73299
  homeDir: options.homeDir ?? (0, import_node_os17.homedir)(),
72925
73300
  userId: options.userId,
72926
73301
  nodeExecutable: runtime?.executable ?? process.execPath,
72927
- cliEntry: currentPlatform === "win32" ? import_node_path32.win32.resolve(cliEntry) : (0, import_node_path32.resolve)(cliEntry),
73302
+ cliEntry: currentPlatform === "win32" ? import_node_path34.win32.resolve(cliEntry) : (0, import_node_path34.resolve)(cliEntry),
72928
73303
  profile,
72929
73304
  environment: runtime?.environment
72930
73305
  });
72931
73306
  }
72932
73307
  function writeManifestAtomic(path2, contents) {
72933
- (0, import_node_fs30.mkdirSync)((0, import_node_path32.dirname)(path2), { recursive: true, mode: 448 });
73308
+ (0, import_node_fs30.mkdirSync)((0, import_node_path34.dirname)(path2), { recursive: true, mode: 448 });
72934
73309
  const pendingPath = `${path2}.pending-${process.pid}`;
72935
73310
  try {
72936
73311
  (0, import_node_fs30.writeFileSync)(pendingPath, contents, { mode: 384 });
@@ -73464,10 +73839,10 @@ ${result.output}
73464
73839
  }
73465
73840
 
73466
73841
  // src/mcp-config-adapters.ts
73467
- var import_node_crypto18 = require("crypto");
73842
+ var import_node_crypto19 = require("crypto");
73468
73843
  var import_node_fs31 = require("fs");
73469
73844
  var import_node_os18 = require("os");
73470
- var import_node_path33 = require("path");
73845
+ var import_node_path35 = require("path");
73471
73846
  var log2 = {
73472
73847
  info: (...args) => console.info("[mcp-config-adapters]", ...args),
73473
73848
  warn: (...args) => console.warn("[mcp-config-adapters]", ...args),
@@ -73495,7 +73870,7 @@ function readFileOr(path2) {
73495
73870
  return (0, import_node_fs31.existsSync)(path2) ? (0, import_node_fs31.readFileSync)(path2, "utf-8") : null;
73496
73871
  }
73497
73872
  function acquireConfigLock(path2) {
73498
- (0, import_node_fs31.mkdirSync)((0, import_node_path33.dirname)(path2), { recursive: true });
73873
+ (0, import_node_fs31.mkdirSync)((0, import_node_path35.dirname)(path2), { recursive: true });
73499
73874
  const lockPath = `${path2}.alan-lock`;
73500
73875
  const startedAt = Date.now();
73501
73876
  while (true) {
@@ -73521,8 +73896,8 @@ function acquireConfigLock(path2) {
73521
73896
  }
73522
73897
  }
73523
73898
  function writeFileSafe(path2, content) {
73524
- (0, import_node_fs31.mkdirSync)((0, import_node_path33.dirname)(path2), { recursive: true });
73525
- const pendingPath = `${path2}.alan-pending-${process.pid}-${(0, import_node_crypto18.randomBytes)(6).toString("hex")}`;
73899
+ (0, import_node_fs31.mkdirSync)((0, import_node_path35.dirname)(path2), { recursive: true });
73900
+ const pendingPath = `${path2}.alan-pending-${process.pid}-${(0, import_node_crypto19.randomBytes)(6).toString("hex")}`;
73526
73901
  try {
73527
73902
  (0, import_node_fs31.writeFileSync)(pendingPath, content, { encoding: "utf8", mode: 384, flag: "wx" });
73528
73903
  (0, import_node_fs31.renameSync)(pendingPath, path2);
@@ -73531,7 +73906,7 @@ function writeFileSafe(path2, content) {
73531
73906
  }
73532
73907
  }
73533
73908
  function saveMalformedBackup(path2, content) {
73534
- const hash2 = (0, import_node_crypto18.createHash)("sha256").update(content).digest("hex").slice(0, 16);
73909
+ const hash2 = (0, import_node_crypto19.createHash)("sha256").update(content).digest("hex").slice(0, 16);
73535
73910
  const backupPath = `${path2}.alan-backup-${hash2}`;
73536
73911
  if (!(0, import_node_fs31.existsSync)(backupPath)) (0, import_node_fs31.copyFileSync)(path2, backupPath);
73537
73912
  return backupPath;
@@ -73539,7 +73914,7 @@ function saveMalformedBackup(path2, content) {
73539
73914
  var claudeAdapter = {
73540
73915
  cli: "Claude Code",
73541
73916
  get configPath() {
73542
- return (0, import_node_path33.join)(homeDirectory(), ".claude.json");
73917
+ return (0, import_node_path35.join)(homeDirectory(), ".claude.json");
73543
73918
  },
73544
73919
  get guardDir() {
73545
73920
  return homeDirectory();
@@ -73572,10 +73947,10 @@ var claudeAdapter = {
73572
73947
  var codexAdapter = {
73573
73948
  cli: "Codex",
73574
73949
  get configPath() {
73575
- return (0, import_node_path33.join)(homeDirectory(), ".codex", "config.toml");
73950
+ return (0, import_node_path35.join)(homeDirectory(), ".codex", "config.toml");
73576
73951
  },
73577
73952
  get guardDir() {
73578
- return (0, import_node_path33.join)(homeDirectory(), ".codex");
73953
+ return (0, import_node_path35.join)(homeDirectory(), ".codex");
73579
73954
  },
73580
73955
  merge(existing, servers) {
73581
73956
  let config4 = {};
@@ -73621,10 +73996,10 @@ var codexAdapter = {
73621
73996
  var cursorAdapter = {
73622
73997
  cli: "Cursor",
73623
73998
  get configPath() {
73624
- return (0, import_node_path33.join)(homeDirectory(), ".cursor", "mcp.json");
73999
+ return (0, import_node_path35.join)(homeDirectory(), ".cursor", "mcp.json");
73625
74000
  },
73626
74001
  get guardDir() {
73627
- return (0, import_node_path33.join)(homeDirectory(), ".cursor");
74002
+ return (0, import_node_path35.join)(homeDirectory(), ".cursor");
73628
74003
  },
73629
74004
  merge(existing, servers) {
73630
74005
  const config4 = parseJsonSafe(existing);
@@ -73659,10 +74034,10 @@ function createAntigravityAdapter() {
73659
74034
  return {
73660
74035
  cli: "Antigravity CLI",
73661
74036
  get configPath() {
73662
- return (0, import_node_path33.join)(homeDirectory(), ".gemini", "config", "mcp_config.json");
74037
+ return (0, import_node_path35.join)(homeDirectory(), ".gemini", "config", "mcp_config.json");
73663
74038
  },
73664
74039
  get guardDir() {
73665
- return (0, import_node_path33.join)(homeDirectory(), ".gemini", "config");
74040
+ return (0, import_node_path35.join)(homeDirectory(), ".gemini", "config");
73666
74041
  },
73667
74042
  // Antigravity sends `initialize` without ever completing OAuth
73668
74043
  // (google-antigravity/antigravity-cli#25), so a credential-free entry only
@@ -73698,10 +74073,10 @@ var antigravityAdapter = createAntigravityAdapter();
73698
74073
  var geminiAdapter = {
73699
74074
  cli: "Gemini CLI",
73700
74075
  get configPath() {
73701
- return (0, import_node_path33.join)(homeDirectory(), ".gemini", "settings.json");
74076
+ return (0, import_node_path35.join)(homeDirectory(), ".gemini", "settings.json");
73702
74077
  },
73703
74078
  get guardDir() {
73704
- return (0, import_node_path33.join)(homeDirectory(), ".gemini");
74079
+ return (0, import_node_path35.join)(homeDirectory(), ".gemini");
73705
74080
  },
73706
74081
  merge(existing, servers) {
73707
74082
  const config4 = parseJsonSafe(existing);
@@ -73731,10 +74106,10 @@ var geminiAdapter = {
73731
74106
  var kimiAdapter = {
73732
74107
  cli: "Kimi CLI",
73733
74108
  get configPath() {
73734
- return (0, import_node_path33.join)(homeDirectory(), ".kimi", "mcp.json");
74109
+ return (0, import_node_path35.join)(homeDirectory(), ".kimi", "mcp.json");
73735
74110
  },
73736
74111
  get guardDir() {
73737
- return (0, import_node_path33.join)(homeDirectory(), ".kimi");
74112
+ return (0, import_node_path35.join)(homeDirectory(), ".kimi");
73738
74113
  },
73739
74114
  merge(existing, servers) {
73740
74115
  const config4 = parseJsonSafe(existing);
@@ -73764,10 +74139,10 @@ var kimiAdapter = {
73764
74139
  var opencodeAdapter = {
73765
74140
  cli: "OpenCode",
73766
74141
  get configPath() {
73767
- return (0, import_node_path33.join)(homeDirectory(), ".config", "opencode", "opencode.json");
74142
+ return (0, import_node_path35.join)(homeDirectory(), ".config", "opencode", "opencode.json");
73768
74143
  },
73769
74144
  get guardDir() {
73770
- return (0, import_node_path33.join)(homeDirectory(), ".config", "opencode");
74145
+ return (0, import_node_path35.join)(homeDirectory(), ".config", "opencode");
73771
74146
  },
73772
74147
  merge(existing, servers) {
73773
74148
  const config4 = parseJsonSafe(existing);
@@ -73797,10 +74172,10 @@ var opencodeAdapter = {
73797
74172
  var factoryAdapter = {
73798
74173
  cli: "Factory Droid",
73799
74174
  get configPath() {
73800
- return (0, import_node_path33.join)(homeDirectory(), ".factory", "mcp.json");
74175
+ return (0, import_node_path35.join)(homeDirectory(), ".factory", "mcp.json");
73801
74176
  },
73802
74177
  get guardDir() {
73803
- return (0, import_node_path33.join)(homeDirectory(), ".factory");
74178
+ return (0, import_node_path35.join)(homeDirectory(), ".factory");
73804
74179
  },
73805
74180
  merge(existing, servers) {
73806
74181
  const config4 = parseJsonSafe(existing);
@@ -73837,10 +74212,10 @@ var factoryAdapter = {
73837
74212
  var ampAdapter = {
73838
74213
  cli: "Amp",
73839
74214
  get configPath() {
73840
- return (0, import_node_path33.join)(homeDirectory(), ".config", "amp", "settings.json");
74215
+ return (0, import_node_path35.join)(homeDirectory(), ".config", "amp", "settings.json");
73841
74216
  },
73842
74217
  get guardDir() {
73843
- return (0, import_node_path33.join)(homeDirectory(), ".config", "amp");
74218
+ return (0, import_node_path35.join)(homeDirectory(), ".config", "amp");
73844
74219
  },
73845
74220
  merge(existing, servers) {
73846
74221
  const config4 = parseJsonSafe(existing);
@@ -73869,10 +74244,10 @@ var ampAdapter = {
73869
74244
  var commandCodeAdapter = {
73870
74245
  cli: "Command Code",
73871
74246
  get configPath() {
73872
- return (0, import_node_path33.join)(homeDirectory(), ".commandcode", "mcp.json");
74247
+ return (0, import_node_path35.join)(homeDirectory(), ".commandcode", "mcp.json");
73873
74248
  },
73874
74249
  get guardDir() {
73875
- return (0, import_node_path33.join)(homeDirectory(), ".commandcode");
74250
+ return (0, import_node_path35.join)(homeDirectory(), ".commandcode");
73876
74251
  },
73877
74252
  merge(existing, servers) {
73878
74253
  const config4 = parseJsonSafe(existing);
@@ -73909,10 +74284,10 @@ var commandCodeAdapter = {
73909
74284
  var copilotAdapter = {
73910
74285
  cli: "GitHub Copilot CLI",
73911
74286
  get configPath() {
73912
- return (0, import_node_path33.join)(homeDirectory(), ".copilot", "mcp-config.json");
74287
+ return (0, import_node_path35.join)(homeDirectory(), ".copilot", "mcp-config.json");
73913
74288
  },
73914
74289
  get guardDir() {
73915
- return (0, import_node_path33.join)(homeDirectory(), ".copilot");
74290
+ return (0, import_node_path35.join)(homeDirectory(), ".copilot");
73916
74291
  },
73917
74292
  merge(existing, servers) {
73918
74293
  const config4 = parseJsonSafe(existing);
@@ -73949,10 +74324,10 @@ var copilotAdapter = {
73949
74324
  var grokAdapter = {
73950
74325
  cli: "Grok CLI",
73951
74326
  get configPath() {
73952
- return (0, import_node_path33.join)(homeDirectory(), ".grok", "config.toml");
74327
+ return (0, import_node_path35.join)(homeDirectory(), ".grok", "config.toml");
73953
74328
  },
73954
74329
  get guardDir() {
73955
- return (0, import_node_path33.join)(homeDirectory(), ".grok");
74330
+ return (0, import_node_path35.join)(homeDirectory(), ".grok");
73956
74331
  },
73957
74332
  merge(existing, servers) {
73958
74333
  let config4 = {};
@@ -74420,12 +74795,12 @@ var McpSyncService = class {
74420
74795
 
74421
74796
  // src/cli/ingestion-hooks.ts
74422
74797
  var import_node_fs33 = require("fs");
74423
- var import_node_path35 = require("path");
74798
+ var import_node_path37 = require("path");
74424
74799
 
74425
74800
  // src/native/hook-config.ts
74426
74801
  var import_node_fs32 = require("fs");
74427
74802
  var import_node_os19 = require("os");
74428
- var import_node_path34 = require("path");
74803
+ var import_node_path36 = require("path");
74429
74804
  var INGESTION_HOOK_MARKER = "# alan-session-ingest";
74430
74805
  var PROVIDER_HOOK_EVENTS = [
74431
74806
  { providerEvent: "Stop", event: "turn_end" },
@@ -74512,7 +74887,7 @@ function hooksOf(settings2) {
74512
74887
  return isRecord7(settings2.hooks) ? settings2.hooks : {};
74513
74888
  }
74514
74889
  function writeSettings2(path2, settings2) {
74515
- (0, import_node_fs32.mkdirSync)((0, import_node_path34.dirname)(path2), { recursive: true, mode: 448 });
74890
+ (0, import_node_fs32.mkdirSync)((0, import_node_path36.dirname)(path2), { recursive: true, mode: 448 });
74516
74891
  const temporary = `${path2}.${process.pid}.tmp`;
74517
74892
  try {
74518
74893
  (0, import_node_fs32.writeFileSync)(temporary, `${JSON.stringify(settings2, null, 2)}
@@ -74603,7 +74978,7 @@ var VERSIONED_NODE_DIR = /\/(?:Cellar\/node(?:@[^/]+)?|\.nvm\/versions\/node|nod
74603
74978
  var STABLE_NODE_PATHS = ["/opt/homebrew/bin/node", "/usr/local/bin/node"];
74604
74979
  function systemNodeProbe(env) {
74605
74980
  return {
74606
- pathEntries: (env.PATH ?? "").split(import_node_path35.delimiter),
74981
+ pathEntries: (env.PATH ?? "").split(import_node_path37.delimiter),
74607
74982
  realpath: (path2) => {
74608
74983
  try {
74609
74984
  return (0, import_node_fs33.realpathSync)(path2);
@@ -74618,7 +74993,7 @@ function stableNodeExecutable(execPath, probe) {
74618
74993
  const binary = probe.realpath(execPath);
74619
74994
  if (!binary) return execPath;
74620
74995
  const candidates = [
74621
- ...probe.pathEntries.filter((entry) => (0, import_node_path35.isAbsolute)(entry)).map((entry) => (0, import_node_path35.join)(entry, "node")),
74996
+ ...probe.pathEntries.filter((entry) => (0, import_node_path37.isAbsolute)(entry)).map((entry) => (0, import_node_path37.join)(entry, "node")),
74622
74997
  ...STABLE_NODE_PATHS
74623
74998
  ];
74624
74999
  return candidates.find(
@@ -74630,7 +75005,7 @@ function currentHookRuntime(env = process.env) {
74630
75005
  if (!cliEntry) throw new Error("Cannot determine the alan-agent CLI entry path");
74631
75006
  return {
74632
75007
  executable: process.versions.electron ? process.execPath : stableNodeExecutable(process.execPath, systemNodeProbe(env)),
74633
- cliEntry: (0, import_node_path35.resolve)(cliEntry),
75008
+ cliEntry: (0, import_node_path37.resolve)(cliEntry),
74634
75009
  environment: process.versions.electron ? { ELECTRON_RUN_AS_NODE: "1" } : void 0
74635
75010
  };
74636
75011
  }
@@ -74934,10 +75309,10 @@ function decodeResumeFallbackContext(encoded) {
74934
75309
 
74935
75310
  // src/sandbox/run.ts
74936
75311
  var import_node_os21 = require("os");
74937
- var import_node_path37 = require("path");
75312
+ var import_node_path39 = require("path");
74938
75313
 
74939
75314
  // src/ws/client.ts
74940
- var import_node_crypto19 = require("crypto");
75315
+ var import_node_crypto20 = require("crypto");
74941
75316
 
74942
75317
  // ../shared/dist/agent-liveness.js
74943
75318
  var AGENT_LIVENESS_PROTOCOL_VERSION = 1;
@@ -74997,7 +75372,7 @@ var agentProbeAckSchema = external_exports.object({
74997
75372
  // src/resource-diagnostics.ts
74998
75373
  var import_node_fs34 = require("fs");
74999
75374
  var import_node_os20 = require("os");
75000
- var import_node_path36 = require("path");
75375
+ var import_node_path38 = require("path");
75001
75376
  var import_node_perf_hooks = require("perf_hooks");
75002
75377
  var MAX_RESOURCE_FILE_BYTES = 16384;
75003
75378
  var RESOURCE_READ_TIMEOUT_MS = 500;
@@ -75037,7 +75412,7 @@ function meminfoBytes(text2, field) {
75037
75412
  function cgroupDirectory(text2) {
75038
75413
  const path2 = text2?.match(/^0::(\/[^\n]*)$/m)?.[1];
75039
75414
  if (!path2 || path2.split("/").includes("..")) return void 0;
75040
- return import_node_path36.posix.join("/sys/fs/cgroup", path2);
75415
+ return import_node_path38.posix.join("/sys/fs/cgroup", path2);
75041
75416
  }
75042
75417
  async function collectAgentResourceDiagnostics(options = {}) {
75043
75418
  const platform7 = options.platform ?? process.platform;
@@ -75188,7 +75563,7 @@ var WSClient = class {
75188
75563
  socket;
75189
75564
  runEvents;
75190
75565
  eventAuthorityReady;
75191
- agentSessionId = (0, import_node_crypto19.randomUUID)();
75566
+ agentSessionId = (0, import_node_crypto20.randomUUID)();
75192
75567
  heartbeatSeq = 0;
75193
75568
  heartbeatTimer = null;
75194
75569
  resourceSampler = new AgentResourceSampler();
@@ -75669,7 +76044,7 @@ function sameRegistration(left, right) {
75669
76044
  }
75670
76045
 
75671
76046
  // src/sandbox/host.ts
75672
- var import_node_crypto20 = require("crypto");
76047
+ var import_node_crypto21 = require("crypto");
75673
76048
  var WebRunHost = class extends BaseRunHost {
75674
76049
  constructor(wsClient, conversationId) {
75675
76050
  super();
@@ -75731,7 +76106,7 @@ var WebRunHost = class extends BaseRunHost {
75731
76106
  this.applicationProblem = createAlanProblem({
75732
76107
  domain: "application",
75733
76108
  code: input2.code,
75734
- id: (0, import_node_crypto20.randomUUID)(),
76109
+ id: (0, import_node_crypto21.randomUUID)(),
75735
76110
  title: APPLICATION_PROBLEM_TITLES[input2.code],
75736
76111
  detail: input2.message,
75737
76112
  // Carries the technical cause without putting an SDK error in front of the person.
@@ -76308,7 +76683,7 @@ function applyUserMessage(turn, patch) {
76308
76683
  // src/sandbox/run.ts
76309
76684
  async function runSandbox(config4) {
76310
76685
  if (!config4.sandboxId) throw new Error("Sandbox lifecycle delivery requires sandboxId");
76311
- const sandboxStatePath = (0, import_node_path37.join)((0, import_node_os21.homedir)(), ".alan", "agent", "config.json");
76686
+ const sandboxStatePath = (0, import_node_path39.join)((0, import_node_os21.homedir)(), ".alan", "agent", "config.json");
76312
76687
  const sandboxApiUrl = config4.apiUrl ?? "https://api.tryalan.ai";
76313
76688
  let stopped = false;
76314
76689
  const transcriptShutdown = new AbortController();
@@ -76749,7 +77124,7 @@ async function runSandbox(config4) {
76749
77124
  // src/skills/skill-cli.ts
76750
77125
  var import_promises16 = require("fs/promises");
76751
77126
  var import_node_os22 = require("os");
76752
- var import_node_path38 = require("path");
77127
+ var import_node_path40 = require("path");
76753
77128
  async function runSkillsCommand(args) {
76754
77129
  const [subcommand, ...options] = args;
76755
77130
  const homeDirectory2 = option2(options, "--home") ?? (0, import_node_os22.homedir)();
@@ -76793,7 +77168,7 @@ async function defaultScanInput(homeDirectory2) {
76793
77168
  });
76794
77169
  }
76795
77170
  async function readProtectedJson(path2) {
76796
- const absolutePath = (0, import_node_path38.resolve)(path2);
77171
+ const absolutePath = (0, import_node_path40.resolve)(path2);
76797
77172
  const stat4 = await (0, import_promises16.lstat)(absolutePath);
76798
77173
  if (!stat4.isFile()) throw new Error(`Skill input is not a regular file: ${absolutePath}`);
76799
77174
  if (process.platform !== "win32" && (stat4.mode & 63) !== 0) {