@pleri/olam-cli 0.1.206 → 0.1.207

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.
@@ -445,8 +445,8 @@ var init_parseUtil = __esm({
445
445
  init_errors();
446
446
  init_en();
447
447
  makeIssue = (params) => {
448
- const { data, path: path60, errorMaps, issueData } = params;
449
- const fullPath = [...path60, ...issueData.path || []];
448
+ const { data, path: path62, errorMaps, issueData } = params;
449
+ const fullPath = [...path62, ...issueData.path || []];
450
450
  const fullIssue = {
451
451
  ...issueData,
452
452
  path: fullPath
@@ -754,11 +754,11 @@ var init_types = __esm({
754
754
  init_parseUtil();
755
755
  init_util();
756
756
  ParseInputLazyPath = class {
757
- constructor(parent, value, path60, key) {
757
+ constructor(parent, value, path62, key) {
758
758
  this._cachedPath = [];
759
759
  this.parent = parent;
760
760
  this.data = value;
761
- this._path = path60;
761
+ this._path = path62;
762
762
  this._key = key;
763
763
  }
764
764
  get path() {
@@ -7332,8 +7332,8 @@ var require_utils = __commonJS({
7332
7332
  }
7333
7333
  return ind;
7334
7334
  }
7335
- function removeDotSegments(path60) {
7336
- let input = path60;
7335
+ function removeDotSegments(path62) {
7336
+ let input = path62;
7337
7337
  const output = [];
7338
7338
  let nextSlash = -1;
7339
7339
  let len = 0;
@@ -7532,8 +7532,8 @@ var require_schemes = __commonJS({
7532
7532
  wsComponent.secure = void 0;
7533
7533
  }
7534
7534
  if (wsComponent.resourceName) {
7535
- const [path60, query] = wsComponent.resourceName.split("?");
7536
- wsComponent.path = path60 && path60 !== "/" ? path60 : void 0;
7535
+ const [path62, query] = wsComponent.resourceName.split("?");
7536
+ wsComponent.path = path62 && path62 !== "/" ? path62 : void 0;
7537
7537
  wsComponent.query = query;
7538
7538
  wsComponent.resourceName = void 0;
7539
7539
  }
@@ -10895,12 +10895,12 @@ var require_dist = __commonJS({
10895
10895
  throw new Error(`Unknown format "${name}"`);
10896
10896
  return f;
10897
10897
  };
10898
- function addFormats(ajv, list, fs60, exportName) {
10898
+ function addFormats(ajv, list, fs62, exportName) {
10899
10899
  var _a3;
10900
10900
  var _b;
10901
10901
  (_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
10902
10902
  for (const f of list)
10903
- ajv.addFormat(f, fs60[f]);
10903
+ ajv.addFormat(f, fs62[f]);
10904
10904
  }
10905
10905
  module.exports = exports = formatsPlugin;
10906
10906
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -11053,7 +11053,7 @@ import YAML from "yaml";
11053
11053
  function bootstrapStepCmd(entry) {
11054
11054
  return typeof entry === "string" ? entry : entry.cmd;
11055
11055
  }
11056
- function refineForbiddenKeys(value, path60, ctx, rejectSource) {
11056
+ function refineForbiddenKeys(value, path62, ctx, rejectSource) {
11057
11057
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
11058
11058
  return;
11059
11059
  }
@@ -11061,12 +11061,12 @@ function refineForbiddenKeys(value, path60, ctx, rejectSource) {
11061
11061
  if (FORBIDDEN_KEYS.has(key)) {
11062
11062
  ctx.addIssue({
11063
11063
  code: external_exports2.ZodIssueCode.custom,
11064
- path: [...path60, key],
11064
+ path: [...path62, key],
11065
11065
  message: `forbidden key "${key}" (prototype-pollution surface)`
11066
11066
  });
11067
11067
  continue;
11068
11068
  }
11069
- if (rejectSource && path60.length === 0 && key === "source") {
11069
+ if (rejectSource && path62.length === 0 && key === "source") {
11070
11070
  ctx.addIssue({
11071
11071
  code: external_exports2.ZodIssueCode.custom,
11072
11072
  path: ["source"],
@@ -11074,21 +11074,21 @@ function refineForbiddenKeys(value, path60, ctx, rejectSource) {
11074
11074
  });
11075
11075
  continue;
11076
11076
  }
11077
- refineForbiddenKeys(value[key], [...path60, key], ctx, false);
11077
+ refineForbiddenKeys(value[key], [...path62, key], ctx, false);
11078
11078
  }
11079
11079
  }
11080
- function rejectForbiddenKeys(value, path60, rejectSource) {
11080
+ function rejectForbiddenKeys(value, path62, rejectSource) {
11081
11081
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
11082
11082
  return;
11083
11083
  }
11084
11084
  for (const key of Object.keys(value)) {
11085
11085
  if (FORBIDDEN_KEYS.has(key)) {
11086
- throw new Error(`[manifest] ${path60}: forbidden key "${key}" (prototype-pollution surface)`);
11086
+ throw new Error(`[manifest] ${path62}: forbidden key "${key}" (prototype-pollution surface)`);
11087
11087
  }
11088
11088
  if (rejectSource && key === "source") {
11089
- throw new Error(`[manifest] ${path60}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
11089
+ throw new Error(`[manifest] ${path62}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
11090
11090
  }
11091
- rejectForbiddenKeys(value[key], `${path60}.${key}`, false);
11091
+ rejectForbiddenKeys(value[key], `${path62}.${key}`, false);
11092
11092
  }
11093
11093
  }
11094
11094
  function unknownTopLevelKeys(parsed) {
@@ -13873,8 +13873,8 @@ var init_provider3 = __esm({
13873
13873
  // -----------------------------------------------------------------------
13874
13874
  // Internal fetch helper
13875
13875
  // -----------------------------------------------------------------------
13876
- async request(path60, method, body) {
13877
- const url3 = `${this.config.workerUrl}${path60}`;
13876
+ async request(path62, method, body) {
13877
+ const url3 = `${this.config.workerUrl}${path62}`;
13878
13878
  const bearer = await this.config.mintToken();
13879
13879
  const headers = {
13880
13880
  Authorization: `Bearer ${bearer}`
@@ -14283,10 +14283,81 @@ function readGlobalConfig() {
14283
14283
  }
14284
14284
  }
14285
14285
  return validated;
14286
- } catch (err) {
14287
- throw new GlobalConfigReadError(configPath, err);
14286
+ } catch (strictErr) {
14287
+ const salvaged = quarantineGlobalConfig(migrated.value);
14288
+ if (salvaged !== null) {
14289
+ let backupPath = null;
14290
+ try {
14291
+ backupPath = `${configPath}.quarantine-${Date.now()}`;
14292
+ fs13.copyFileSync(configPath, backupPath);
14293
+ } catch {
14294
+ backupPath = null;
14295
+ }
14296
+ try {
14297
+ writeGlobalConfig(salvaged.value);
14298
+ } catch {
14299
+ }
14300
+ quarantineSink(configPath, { drops: salvaged.drops, backupPath });
14301
+ return salvaged.value;
14302
+ }
14303
+ throw new GlobalConfigReadError(configPath, strictErr);
14288
14304
  }
14289
14305
  }
14306
+ function quarantineGlobalConfig(migratedValue) {
14307
+ if (migratedValue === null || typeof migratedValue !== "object" || Array.isArray(migratedValue)) {
14308
+ return null;
14309
+ }
14310
+ const obj = migratedValue;
14311
+ const drops = [];
14312
+ const filterField = (field, schema, dedupeKeys) => {
14313
+ const v = obj[field];
14314
+ if (v === void 0)
14315
+ return [];
14316
+ if (!Array.isArray(v)) {
14317
+ drops.push({ field, entry: v, reason: `${field} is not an array` });
14318
+ return [];
14319
+ }
14320
+ const out = [];
14321
+ const seen = dedupeKeys.map(() => /* @__PURE__ */ new Set());
14322
+ for (const e of v) {
14323
+ const r = schema.safeParse(e);
14324
+ if (!r.success || r.data === void 0) {
14325
+ drops.push({ field, entry: e, reason: r.error?.issues[0]?.message ?? "invalid entry" });
14326
+ continue;
14327
+ }
14328
+ let dupeKey = null;
14329
+ for (let i = 0; i < dedupeKeys.length; i++) {
14330
+ const k = dedupeKeys[i](r.data);
14331
+ if (seen[i].has(k)) {
14332
+ dupeKey = k;
14333
+ break;
14334
+ }
14335
+ }
14336
+ if (dupeKey !== null) {
14337
+ drops.push({ field, entry: e, reason: `duplicate key "${dupeKey}"` });
14338
+ continue;
14339
+ }
14340
+ for (let i = 0; i < dedupeKeys.length; i++)
14341
+ seen[i].add(dedupeKeys[i](r.data));
14342
+ out.push(r.data);
14343
+ }
14344
+ return out;
14345
+ };
14346
+ const repos = filterField("repos", RepoEntrySchema, [(r) => r.name]);
14347
+ const runbooks = filterField("runbooks", RunbookSchema, [(r) => r.name]);
14348
+ const skillSources = filterField("skillSources", SkillSourceSchema, [
14349
+ (s) => s.id,
14350
+ (s) => s.name
14351
+ ]);
14352
+ const metaHooksDisabled = filterField("metaHooksDisabled", MetaHookBlockKindSchema, [
14353
+ (m) => m
14354
+ ]);
14355
+ const candidate = { schemaVersion: 1, repos, runbooks, skillSources, metaHooksDisabled };
14356
+ const final = GlobalConfigSchema.safeParse(candidate);
14357
+ if (!final.success)
14358
+ return null;
14359
+ return { value: final.data, drops };
14360
+ }
14290
14361
  function migrateSchemaVersion(parsed) {
14291
14362
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
14292
14363
  return { value: parsed, changed: false };
@@ -14306,11 +14377,26 @@ function writeGlobalConfig(config2) {
14306
14377
  fs13.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
14307
14378
  fs13.renameSync(tmp, configPath);
14308
14379
  }
14309
- var GlobalConfigReadError;
14380
+ var quarantineSink, GlobalConfigReadError;
14310
14381
  var init_store2 = __esm({
14311
14382
  "../core/dist/global-config/store.js"() {
14312
14383
  "use strict";
14313
14384
  init_schema4();
14385
+ init_schema3();
14386
+ quarantineSink = (configPath, report) => {
14387
+ if (report.drops.length === 0)
14388
+ return;
14389
+ process.stderr.write(`\x1B[33m\u26A0 global config at ${configPath} had ${report.drops.length} invalid entr${report.drops.length === 1 ? "y" : "ies"} \u2014 quarantined (kept the rest):\x1B[0m
14390
+ `);
14391
+ for (const d of report.drops) {
14392
+ process.stderr.write(` \xB7 ${d.field}: ${d.reason}
14393
+ `);
14394
+ }
14395
+ if (report.backupPath) {
14396
+ process.stderr.write(` \u2192 original backed up to ${report.backupPath}
14397
+ `);
14398
+ }
14399
+ };
14314
14400
  GlobalConfigReadError = class extends Error {
14315
14401
  constructor(configPath, cause) {
14316
14402
  const msg = cause instanceof Error ? cause.message : String(cause);
@@ -14684,6 +14770,145 @@ var init_trust_audit_log = __esm({
14684
14770
  }
14685
14771
  });
14686
14772
 
14773
+ // ../core/dist/skill-sources/clone.js
14774
+ import { execFileSync as execFileSync2 } from "node:child_process";
14775
+ import * as fs17 from "node:fs";
14776
+ import * as os12 from "node:os";
14777
+ import * as path19 from "node:path";
14778
+ function skillSourcesRootDir() {
14779
+ const override = process.env["OLAM_SKILL_SOURCES_DIR"];
14780
+ if (override && override.length > 0)
14781
+ return override;
14782
+ return path19.join(os12.homedir(), ".olam", "state", "skill-sources");
14783
+ }
14784
+ function skillSourceClonePath(id) {
14785
+ return path19.join(skillSourcesRootDir(), id);
14786
+ }
14787
+ function runGit(args, cwd) {
14788
+ try {
14789
+ return execFileSync2("git", args, {
14790
+ cwd,
14791
+ encoding: "utf-8",
14792
+ stdio: ["ignore", "pipe", "pipe"]
14793
+ });
14794
+ } catch (err) {
14795
+ throw err;
14796
+ }
14797
+ }
14798
+ function cloneSkillSource(opts) {
14799
+ const clonePath = skillSourceClonePath(opts.id);
14800
+ if (fs17.existsSync(clonePath)) {
14801
+ throw new Error(`clone path "${clonePath}" already exists. Remove the existing skill-source first.`);
14802
+ }
14803
+ fs17.mkdirSync(skillSourcesRootDir(), { recursive: true });
14804
+ try {
14805
+ runGit(["clone", "--depth", "1", "--branch", opts.branch, opts.gitUrl, clonePath]);
14806
+ } catch (err) {
14807
+ if (fs17.existsSync(clonePath)) {
14808
+ fs17.rmSync(clonePath, { recursive: true, force: true });
14809
+ }
14810
+ throw new SkillSourceGitError("clone", opts.gitUrl, err);
14811
+ }
14812
+ let headSha;
14813
+ try {
14814
+ headSha = runGit(["rev-parse", "HEAD"], clonePath).trim();
14815
+ } catch (err) {
14816
+ throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
14817
+ }
14818
+ return { clonePath, headSha };
14819
+ }
14820
+ function pullSkillSource(opts) {
14821
+ const clonePath = skillSourceClonePath(opts.id);
14822
+ if (!fs17.existsSync(clonePath)) {
14823
+ throw new Error(`clone path "${clonePath}" does not exist. Run "olam skills source add" first.`);
14824
+ }
14825
+ try {
14826
+ runGit(["fetch", "origin", opts.branch], clonePath);
14827
+ runGit(["reset", "--hard", `origin/${opts.branch}`], clonePath);
14828
+ } catch (err) {
14829
+ throw new SkillSourceGitError("fetch/reset", opts.gitUrl, err);
14830
+ }
14831
+ try {
14832
+ const headSha = runGit(["rev-parse", "HEAD"], clonePath).trim();
14833
+ return { headSha };
14834
+ } catch (err) {
14835
+ throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
14836
+ }
14837
+ }
14838
+ function removeSkillSourceClone(id) {
14839
+ const clonePath = skillSourceClonePath(id);
14840
+ if (fs17.existsSync(clonePath)) {
14841
+ fs17.rmSync(clonePath, { recursive: true, force: true });
14842
+ }
14843
+ }
14844
+ var SkillSourceGitError;
14845
+ var init_clone = __esm({
14846
+ "../core/dist/skill-sources/clone.js"() {
14847
+ "use strict";
14848
+ SkillSourceGitError = class extends Error {
14849
+ op;
14850
+ gitUrl;
14851
+ constructor(op, gitUrl, cause) {
14852
+ const msg = cause instanceof Error ? cause.message : String(cause);
14853
+ super(`git ${op} failed for "${gitUrl}": ${msg}`);
14854
+ this.op = op;
14855
+ this.gitUrl = gitUrl;
14856
+ this.name = "SkillSourceGitError";
14857
+ this.cause = cause;
14858
+ }
14859
+ };
14860
+ }
14861
+ });
14862
+
14863
+ // ../core/dist/skill-sources/source-file.js
14864
+ import * as fs18 from "node:fs";
14865
+ import * as path20 from "node:path";
14866
+ function sourceSidecarPath(id) {
14867
+ return path20.join(skillSourceClonePath(id), SOURCE_SIDECAR_FILENAME);
14868
+ }
14869
+ function writeSourceSidecar(entry) {
14870
+ const clonePath = skillSourceClonePath(entry.id);
14871
+ if (!fs18.existsSync(clonePath))
14872
+ return false;
14873
+ try {
14874
+ const validated = SourceSidecarSchema.parse(entry);
14875
+ const target = sourceSidecarPath(entry.id);
14876
+ const tmp = `${target}.tmp-${process.pid}`;
14877
+ fs18.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
14878
+ fs18.renameSync(tmp, target);
14879
+ return true;
14880
+ } catch {
14881
+ return false;
14882
+ }
14883
+ }
14884
+ function readSourceSidecar(id) {
14885
+ const target = sourceSidecarPath(id);
14886
+ let raw;
14887
+ try {
14888
+ raw = fs18.readFileSync(target, "utf-8");
14889
+ } catch {
14890
+ return null;
14891
+ }
14892
+ let parsed;
14893
+ try {
14894
+ parsed = JSON.parse(raw);
14895
+ } catch {
14896
+ return null;
14897
+ }
14898
+ const result = SourceSidecarSchema.safeParse(parsed);
14899
+ return result.success ? result.data : null;
14900
+ }
14901
+ var SOURCE_SIDECAR_FILENAME, SourceSidecarSchema;
14902
+ var init_source_file = __esm({
14903
+ "../core/dist/skill-sources/source-file.js"() {
14904
+ "use strict";
14905
+ init_schema3();
14906
+ init_clone();
14907
+ SOURCE_SIDECAR_FILENAME = ".olam-source.json";
14908
+ SourceSidecarSchema = SkillSourceSchema;
14909
+ }
14910
+ });
14911
+
14687
14912
  // ../core/dist/skill-sources/store.js
14688
14913
  import * as crypto3 from "node:crypto";
14689
14914
  function deriveSkillSourceId(gitUrl) {
@@ -14716,6 +14941,7 @@ function addSkillSource(entry) {
14716
14941
  addedAt: now
14717
14942
  };
14718
14943
  writeGlobalConfig({ ...config2, skillSources: [...config2.skillSources, newEntry] });
14944
+ writeSourceSidecar(newEntry);
14719
14945
  try {
14720
14946
  appendTrustAudit({
14721
14947
  gitUrl: redactUrl2(entry.gitUrl),
@@ -14833,6 +15059,7 @@ function updateSkillSource(id, patch) {
14833
15059
  const next = [...config2.skillSources];
14834
15060
  next[idx] = updated;
14835
15061
  writeGlobalConfig({ ...config2, skillSources: next });
15062
+ writeSourceSidecar(updated);
14836
15063
  return updated;
14837
15064
  }
14838
15065
  var PREFIX_PATTERN3;
@@ -14843,102 +15070,141 @@ var init_store3 = __esm({
14843
15070
  init_schema3();
14844
15071
  init_trust_audit_log();
14845
15072
  init_source_config_schema();
15073
+ init_source_file();
14846
15074
  PREFIX_PATTERN3 = /^[a-z0-9][a-z0-9_-]{0,38}$/;
14847
15075
  }
14848
15076
  });
14849
15077
 
14850
- // ../core/dist/skill-sources/clone.js
14851
- import { execFileSync as execFileSync2 } from "node:child_process";
14852
- import * as fs17 from "node:fs";
14853
- import * as os12 from "node:os";
14854
- import * as path19 from "node:path";
14855
- function skillSourcesRootDir() {
14856
- const override = process.env["OLAM_SKILL_SOURCES_DIR"];
14857
- if (override && override.length > 0)
14858
- return override;
14859
- return path19.join(os12.homedir(), ".olam", "state", "skill-sources");
14860
- }
14861
- function skillSourceClonePath(id) {
14862
- return path19.join(skillSourcesRootDir(), id);
14863
- }
14864
- function runGit(args, cwd) {
15078
+ // ../core/dist/skill-sources/reconcile.js
15079
+ import { execFileSync as execFileSync3 } from "node:child_process";
15080
+ import * as fs19 from "node:fs";
15081
+ import * as path21 from "node:path";
15082
+ function gitRead(args, cwd) {
14865
15083
  try {
14866
- return execFileSync2("git", args, {
15084
+ return execFileSync3("git", args, {
14867
15085
  cwd,
14868
15086
  encoding: "utf-8",
14869
- stdio: ["ignore", "pipe", "pipe"]
14870
- });
14871
- } catch (err) {
14872
- throw err;
15087
+ stdio: ["ignore", "pipe", "ignore"]
15088
+ }).trim();
15089
+ } catch {
15090
+ return null;
14873
15091
  }
14874
15092
  }
14875
- function cloneSkillSource(opts) {
14876
- const clonePath = skillSourceClonePath(opts.id);
14877
- if (fs17.existsSync(clonePath)) {
14878
- throw new Error(`clone path "${clonePath}" already exists. Remove the existing skill-source first.`);
14879
- }
14880
- fs17.mkdirSync(skillSourcesRootDir(), { recursive: true });
15093
+ function nameFromGitUrl(gitUrl) {
15094
+ const tail = gitUrl.replace(/\.git$/, "").replace(/\/+$/, "").split(/[/:]/).filter((s) => s.length > 0).pop();
15095
+ if (!tail)
15096
+ return null;
15097
+ const sanitized = tail.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
15098
+ return NAME_PATTERN2.test(sanitized) ? sanitized : null;
15099
+ }
15100
+ function recoverFromGit(id, clonePath) {
15101
+ const gitUrl = gitRead(["remote", "get-url", "origin"], clonePath);
15102
+ if (!gitUrl)
15103
+ return null;
15104
+ const branch = gitRead(["symbolic-ref", "--short", "HEAD"], clonePath) ?? gitRead(["rev-parse", "--abbrev-ref", "HEAD"], clonePath) ?? "main";
15105
+ const headSha = gitRead(["rev-parse", "HEAD"], clonePath);
15106
+ let addedAt = 0;
14881
15107
  try {
14882
- runGit(["clone", "--depth", "1", "--branch", opts.branch, opts.gitUrl, clonePath]);
14883
- } catch (err) {
14884
- if (fs17.existsSync(clonePath)) {
14885
- fs17.rmSync(clonePath, { recursive: true, force: true });
14886
- }
14887
- throw new SkillSourceGitError("clone", opts.gitUrl, err);
15108
+ addedAt = Math.floor(fs19.statSync(clonePath).ctimeMs);
15109
+ } catch {
15110
+ addedAt = 0;
14888
15111
  }
14889
- let headSha;
15112
+ const entry = {
15113
+ id,
15114
+ name: nameFromGitUrl(gitUrl) ?? `source-${id}`,
15115
+ gitUrl,
15116
+ branch,
15117
+ addedAt,
15118
+ ...headSha && SHA_PATTERN.test(headSha) ? { lastPulledSha: headSha } : {}
15119
+ };
15120
+ return entry;
15121
+ }
15122
+ function listCloneIds() {
15123
+ const root = skillSourcesRootDir();
15124
+ let dirents;
14890
15125
  try {
14891
- headSha = runGit(["rev-parse", "HEAD"], clonePath).trim();
14892
- } catch (err) {
14893
- throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
15126
+ dirents = fs19.readdirSync(root, { withFileTypes: true });
15127
+ } catch {
15128
+ return [];
14894
15129
  }
14895
- return { clonePath, headSha };
15130
+ return dirents.filter((d) => d.isDirectory() && fs19.existsSync(path21.join(root, d.name, ".git"))).map((d) => d.name);
14896
15131
  }
14897
- function pullSkillSource(opts) {
14898
- const clonePath = skillSourceClonePath(opts.id);
14899
- if (!fs17.existsSync(clonePath)) {
14900
- throw new Error(`clone path "${clonePath}" does not exist. Run "olam skills source add" first.`);
15132
+ function reconcileSkillSources(opts = {}) {
15133
+ const config2 = readGlobalConfig();
15134
+ const existingById = new Map(config2.skillSources.map((s) => [s.id, s]));
15135
+ const diskIds = new Set(listCloneIds());
15136
+ const added = [];
15137
+ const registryOnly = [];
15138
+ const sidecarsBackfilled = [];
15139
+ const usedNames = /* @__PURE__ */ new Set();
15140
+ const ensureUniqueName = (entry) => {
15141
+ if (!usedNames.has(entry.name)) {
15142
+ usedNames.add(entry.name);
15143
+ return entry;
15144
+ }
15145
+ const suffixed = `${entry.name}-${entry.id.slice(0, 6)}`.slice(0, 64).replace(/-+$/g, "");
15146
+ usedNames.add(suffixed);
15147
+ return { ...entry, name: suffixed };
15148
+ };
15149
+ const next = [];
15150
+ for (const entry of config2.skillSources) {
15151
+ if (diskIds.has(entry.id)) {
15152
+ usedNames.add(entry.name);
15153
+ next.push(entry);
15154
+ } else {
15155
+ registryOnly.push(entry);
15156
+ if (!opts.prune) {
15157
+ usedNames.add(entry.name);
15158
+ next.push(entry);
15159
+ }
15160
+ }
14901
15161
  }
14902
- try {
14903
- runGit(["fetch", "origin", opts.branch], clonePath);
14904
- runGit(["reset", "--hard", `origin/${opts.branch}`], clonePath);
14905
- } catch (err) {
14906
- throw new SkillSourceGitError("fetch/reset", opts.gitUrl, err);
15162
+ for (const id of diskIds) {
15163
+ if (existingById.has(id)) {
15164
+ if (readSourceSidecar(id) === null && writeSourceSidecar(existingById.get(id))) {
15165
+ sidecarsBackfilled.push(id);
15166
+ }
15167
+ continue;
15168
+ }
15169
+ const sidecar = readSourceSidecar(id);
15170
+ const recovered = sidecar ? { ...sidecar, id } : recoverFromGit(id, skillSourceClonePath(id));
15171
+ if (recovered === null)
15172
+ continue;
15173
+ const unique = ensureUniqueName(recovered);
15174
+ next.push(unique);
15175
+ added.push(unique);
15176
+ if (sidecar === null && writeSourceSidecar(unique))
15177
+ sidecarsBackfilled.push(id);
14907
15178
  }
14908
- try {
14909
- const headSha = runGit(["rev-parse", "HEAD"], clonePath).trim();
14910
- return { headSha };
14911
- } catch (err) {
14912
- throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
15179
+ const pruned = opts.prune ? registryOnly : [];
15180
+ const changed = next.length !== config2.skillSources.length || next.some((e, i) => e !== config2.skillSources[i]);
15181
+ if (changed) {
15182
+ writeGlobalConfig({ ...config2, skillSources: next });
14913
15183
  }
15184
+ return { added, registryOnly, pruned, sidecarsBackfilled, changed };
14914
15185
  }
14915
- function removeSkillSourceClone(id) {
14916
- const clonePath = skillSourceClonePath(id);
14917
- if (fs17.existsSync(clonePath)) {
14918
- fs17.rmSync(clonePath, { recursive: true, force: true });
14919
- }
15186
+ function reconcileIfRegistryEmpty() {
15187
+ if (readGlobalConfig().skillSources.length > 0)
15188
+ return null;
15189
+ if (listCloneIds().length === 0)
15190
+ return null;
15191
+ return reconcileSkillSources();
14920
15192
  }
14921
- var SkillSourceGitError;
14922
- var init_clone = __esm({
14923
- "../core/dist/skill-sources/clone.js"() {
15193
+ var NAME_PATTERN2, SHA_PATTERN;
15194
+ var init_reconcile = __esm({
15195
+ "../core/dist/skill-sources/reconcile.js"() {
14924
15196
  "use strict";
14925
- SkillSourceGitError = class extends Error {
14926
- op;
14927
- gitUrl;
14928
- constructor(op, gitUrl, cause) {
14929
- const msg = cause instanceof Error ? cause.message : String(cause);
14930
- super(`git ${op} failed for "${gitUrl}": ${msg}`);
14931
- this.op = op;
14932
- this.gitUrl = gitUrl;
14933
- this.name = "SkillSourceGitError";
14934
- this.cause = cause;
14935
- }
14936
- };
15197
+ init_store2();
15198
+ init_schema3();
15199
+ init_clone();
15200
+ init_source_file();
15201
+ NAME_PATTERN2 = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
15202
+ SHA_PATTERN = /^[a-f0-9]{40}$/;
14937
15203
  }
14938
15204
  });
14939
15205
 
14940
15206
  // ../core/dist/skill-sources/hook-template.js
14941
- import * as fs18 from "node:fs";
15207
+ import * as fs20 from "node:fs";
14942
15208
  function buildSkillsHookEntry() {
14943
15209
  return {
14944
15210
  matcher: "",
@@ -14997,14 +15263,14 @@ function computeUninstall(settings) {
14997
15263
  return { status: "removed", settingsAfter: next };
14998
15264
  }
14999
15265
  function uninstallSkillsHookFromFile(filePath) {
15000
- if (!fs18.existsSync(filePath)) {
15266
+ if (!fs20.existsSync(filePath)) {
15001
15267
  return { status: "no-settings" };
15002
15268
  }
15003
- const raw = fs18.readFileSync(filePath, "utf-8");
15269
+ const raw = fs20.readFileSync(filePath, "utf-8");
15004
15270
  const settings = raw.trim() ? JSON.parse(raw) : {};
15005
15271
  const result = computeUninstall(settings);
15006
15272
  if (result.status === "removed" && result.settingsAfter) {
15007
- fs18.writeFileSync(filePath, JSON.stringify(result.settingsAfter, null, 2) + "\n");
15273
+ fs20.writeFileSync(filePath, JSON.stringify(result.settingsAfter, null, 2) + "\n");
15008
15274
  }
15009
15275
  return result;
15010
15276
  }
@@ -15020,8 +15286,8 @@ var init_hook_template = __esm({
15020
15286
  });
15021
15287
 
15022
15288
  // ../core/dist/world/merge-settings.js
15023
- import * as fs19 from "node:fs";
15024
- import * as path20 from "node:path";
15289
+ import * as fs21 from "node:fs";
15290
+ import * as path22 from "node:path";
15025
15291
  import * as crypto4 from "node:crypto";
15026
15292
  function mergeHomeSettingsJson(filePath, options) {
15027
15293
  let settings;
@@ -15082,10 +15348,10 @@ function mergeHomeSettingsJson(filePath, options) {
15082
15348
  return { status: "installed", message: `settings.json updated at ${filePath}` };
15083
15349
  }
15084
15350
  function readSettings(filePath) {
15085
- if (!fs19.existsSync(filePath)) {
15351
+ if (!fs21.existsSync(filePath)) {
15086
15352
  return {};
15087
15353
  }
15088
- const raw = fs19.readFileSync(filePath, "utf-8");
15354
+ const raw = fs21.readFileSync(filePath, "utf-8");
15089
15355
  if (!raw.trim())
15090
15356
  return {};
15091
15357
  return JSON.parse(raw);
@@ -15124,13 +15390,13 @@ function isHookSentinelPresent(matchers, sentinel) {
15124
15390
  return false;
15125
15391
  }
15126
15392
  function atomicWriteJson(filePath, data) {
15127
- const dir = path20.dirname(filePath);
15128
- fs19.mkdirSync(dir, { recursive: true });
15393
+ const dir = path22.dirname(filePath);
15394
+ fs21.mkdirSync(dir, { recursive: true });
15129
15395
  const rand = crypto4.randomBytes(6).toString("hex");
15130
15396
  const tmp = `${filePath}.tmp.${process.pid}.${rand}`;
15131
15397
  const json2 = JSON.stringify(data, null, 2) + "\n";
15132
- fs19.writeFileSync(tmp, json2, { mode: 420 });
15133
- fs19.renameSync(tmp, filePath);
15398
+ fs21.writeFileSync(tmp, json2, { mode: 420 });
15399
+ fs21.renameSync(tmp, filePath);
15134
15400
  }
15135
15401
  var init_merge_settings = __esm({
15136
15402
  "../core/dist/world/merge-settings.js"() {
@@ -15139,25 +15405,25 @@ var init_merge_settings = __esm({
15139
15405
  });
15140
15406
 
15141
15407
  // ../core/dist/skill-sources/hook-install.js
15142
- import * as fs20 from "node:fs";
15143
- import * as path21 from "node:path";
15408
+ import * as fs22 from "node:fs";
15409
+ import * as path23 from "node:path";
15144
15410
  import * as os13 from "node:os";
15145
15411
  function settingsPathFor(scope, cwd) {
15146
15412
  if (scope === "user") {
15147
- return path21.join(os13.homedir(), ".claude", "settings.json");
15413
+ return path23.join(os13.homedir(), ".claude", "settings.json");
15148
15414
  }
15149
- return path21.join(cwd ?? process.cwd(), ".claude", "settings.json");
15415
+ return path23.join(cwd ?? process.cwd(), ".claude", "settings.json");
15150
15416
  }
15151
15417
  function backupFile(filePath) {
15152
- if (!fs20.existsSync(filePath))
15418
+ if (!fs22.existsSync(filePath))
15153
15419
  return null;
15154
15420
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
15155
15421
  const backupPath = `${filePath}.olam-bak.${ts}`;
15156
- fs20.copyFileSync(filePath, backupPath);
15422
+ fs22.copyFileSync(filePath, backupPath);
15157
15423
  return backupPath;
15158
15424
  }
15159
15425
  function installSkillsHookToFile(filePath) {
15160
- fs20.mkdirSync(path21.dirname(filePath), { recursive: true });
15426
+ fs22.mkdirSync(path23.dirname(filePath), { recursive: true });
15161
15427
  const backupPath = backupFile(filePath);
15162
15428
  const result = mergeHomeSettingsJson(filePath, {
15163
15429
  ensureHook: {
@@ -15168,7 +15434,7 @@ function installSkillsHookToFile(filePath) {
15168
15434
  });
15169
15435
  if (result.status === "already-present" && backupPath) {
15170
15436
  try {
15171
- fs20.unlinkSync(backupPath);
15437
+ fs22.unlinkSync(backupPath);
15172
15438
  } catch {
15173
15439
  }
15174
15440
  return { status: "already-present", filePath, backupPath: null };
@@ -15176,11 +15442,11 @@ function installSkillsHookToFile(filePath) {
15176
15442
  return { status: result.status, filePath, backupPath };
15177
15443
  }
15178
15444
  function isSkillsHookInstalled(filePath) {
15179
- if (!fs20.existsSync(filePath))
15445
+ if (!fs22.existsSync(filePath))
15180
15446
  return false;
15181
15447
  let parsed;
15182
15448
  try {
15183
- parsed = JSON.parse(fs20.readFileSync(filePath, "utf-8"));
15449
+ parsed = JSON.parse(fs22.readFileSync(filePath, "utf-8"));
15184
15450
  } catch {
15185
15451
  return false;
15186
15452
  }
@@ -15218,36 +15484,36 @@ var init_hook_install = __esm({
15218
15484
  });
15219
15485
 
15220
15486
  // ../core/dist/skill-sources/migration-snapshot.js
15221
- import * as fs21 from "node:fs";
15487
+ import * as fs23 from "node:fs";
15222
15488
  import * as os14 from "node:os";
15223
- import * as path22 from "node:path";
15489
+ import * as path24 from "node:path";
15224
15490
  function claudeDirInternal() {
15225
15491
  const override = process.env["OLAM_CLAUDE_DIR"];
15226
15492
  if (override && override.length > 0)
15227
15493
  return override;
15228
- return path22.join(os14.homedir(), ".claude");
15494
+ return path24.join(os14.homedir(), ".claude");
15229
15495
  }
15230
15496
  function migrationSnapshotsDir() {
15231
15497
  const override = process.env["OLAM_MIGRATION_SNAPSHOTS_DIR"];
15232
15498
  if (override && override.length > 0)
15233
15499
  return override;
15234
- return path22.join(os14.homedir(), ".olam", "state", "migration-snapshots");
15500
+ return path24.join(os14.homedir(), ".olam", "state", "migration-snapshots");
15235
15501
  }
15236
15502
  function listToolboxManagedSymlinks(toolboxPath) {
15237
15503
  const claude = claudeDirInternal();
15238
15504
  const out = [];
15239
15505
  const BUCKETS2 = ["skills", "agents", "scripts", "rules", "commands"];
15240
15506
  for (const bucket of BUCKETS2) {
15241
- const dir = path22.join(claude, bucket);
15242
- if (!fs21.existsSync(dir))
15507
+ const dir = path24.join(claude, bucket);
15508
+ if (!fs23.existsSync(dir))
15243
15509
  continue;
15244
- for (const name of fs21.readdirSync(dir)) {
15245
- const link = path22.join(dir, name);
15510
+ for (const name of fs23.readdirSync(dir)) {
15511
+ const link = path24.join(dir, name);
15246
15512
  try {
15247
- const stat2 = fs21.lstatSync(link);
15513
+ const stat2 = fs23.lstatSync(link);
15248
15514
  if (!stat2.isSymbolicLink())
15249
15515
  continue;
15250
- const target = fs21.readlinkSync(link);
15516
+ const target = fs23.readlinkSync(link);
15251
15517
  if (target.startsWith(toolboxPath)) {
15252
15518
  out.push({ link, target });
15253
15519
  }
@@ -15260,25 +15526,25 @@ function listToolboxManagedSymlinks(toolboxPath) {
15260
15526
  function detectToolboxState(opts) {
15261
15527
  const claude = claudeDirInternal();
15262
15528
  const toolboxPath = opts.toolboxPath;
15263
- const namespace = opts.namespace ?? path22.basename(toolboxPath);
15264
- const atlasUserFile = path22.join(claude, ".atlas-user");
15265
- const atlasUser = fs21.existsSync(atlasUserFile) ? fs21.readFileSync(atlasUserFile, "utf-8").trim() || void 0 : void 0;
15529
+ const namespace = opts.namespace ?? path24.basename(toolboxPath);
15530
+ const atlasUserFile = path24.join(claude, ".atlas-user");
15531
+ const atlasUser = fs23.existsSync(atlasUserFile) ? fs23.readFileSync(atlasUserFile, "utf-8").trim() || void 0 : void 0;
15266
15532
  let subscriptionsJson;
15267
15533
  if (atlasUser) {
15268
- const sp = path22.join(toolboxPath, "members", atlasUser, "subscriptions.json");
15269
- if (fs21.existsSync(sp)) {
15534
+ const sp = path24.join(toolboxPath, "members", atlasUser, "subscriptions.json");
15535
+ if (fs23.existsSync(sp)) {
15270
15536
  try {
15271
- subscriptionsJson = JSON.parse(fs21.readFileSync(sp, "utf-8"));
15537
+ subscriptionsJson = JSON.parse(fs23.readFileSync(sp, "utf-8"));
15272
15538
  } catch {
15273
15539
  }
15274
15540
  }
15275
15541
  }
15276
15542
  const atlasManagedSymlinks = listToolboxManagedSymlinks(toolboxPath);
15277
15543
  let originalSessionStartHook;
15278
- const settingsPath = path22.join(claude, "settings.json");
15279
- if (fs21.existsSync(settingsPath)) {
15544
+ const settingsPath = path24.join(claude, "settings.json");
15545
+ if (fs23.existsSync(settingsPath)) {
15280
15546
  try {
15281
- const settings = JSON.parse(fs21.readFileSync(settingsPath, "utf-8"));
15547
+ const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
15282
15548
  const ss = settings?.hooks?.SessionStart;
15283
15549
  if (Array.isArray(ss))
15284
15550
  originalSessionStartHook = ss;
@@ -15301,21 +15567,21 @@ function detectToolboxState(opts) {
15301
15567
  }
15302
15568
  function writeMigrationSnapshot(snapshot) {
15303
15569
  const dir = migrationSnapshotsDir();
15304
- fs21.mkdirSync(dir, { recursive: true });
15570
+ fs23.mkdirSync(dir, { recursive: true });
15305
15571
  const stamp = snapshot.takenAt.replace(/[:.]/g, "-");
15306
- const file2 = path22.join(dir, `${snapshot.namespace}-${stamp}.json`);
15307
- fs21.writeFileSync(file2, JSON.stringify(snapshot, null, 2) + "\n", { mode: 420 });
15572
+ const file2 = path24.join(dir, `${snapshot.namespace}-${stamp}.json`);
15573
+ fs23.writeFileSync(file2, JSON.stringify(snapshot, null, 2) + "\n", { mode: 420 });
15308
15574
  return file2;
15309
15575
  }
15310
15576
  function readLatestMigrationSnapshot(opts = {}) {
15311
15577
  const dir = migrationSnapshotsDir();
15312
- if (!fs21.existsSync(dir))
15578
+ if (!fs23.existsSync(dir))
15313
15579
  return void 0;
15314
- const files = fs21.readdirSync(dir).filter((f) => f.endsWith(".json")).sort().reverse();
15580
+ const files = fs23.readdirSync(dir).filter((f) => f.endsWith(".json")).sort().reverse();
15315
15581
  for (const f of files) {
15316
- const full = path22.join(dir, f);
15582
+ const full = path24.join(dir, f);
15317
15583
  try {
15318
- const snapshot = JSON.parse(fs21.readFileSync(full, "utf-8"));
15584
+ const snapshot = JSON.parse(fs23.readFileSync(full, "utf-8"));
15319
15585
  if (snapshot.schemaVersion !== MIGRATION_SNAPSHOT_SCHEMA_VERSION)
15320
15586
  continue;
15321
15587
  if (typeof snapshot.atlasToolboxRepoPath !== "string")
@@ -15332,7 +15598,7 @@ function readLatestMigrationSnapshot(opts = {}) {
15332
15598
  return void 0;
15333
15599
  }
15334
15600
  function readMigrationSnapshotFromPath(p) {
15335
- return JSON.parse(fs21.readFileSync(p, "utf-8"));
15601
+ return JSON.parse(fs23.readFileSync(p, "utf-8"));
15336
15602
  }
15337
15603
  var MIGRATION_SNAPSHOT_SCHEMA_VERSION;
15338
15604
  var init_migration_snapshot = __esm({
@@ -15343,15 +15609,15 @@ var init_migration_snapshot = __esm({
15343
15609
  });
15344
15610
 
15345
15611
  // ../core/dist/skill-sync/artifact-resolver.js
15346
- import * as fs22 from "node:fs";
15347
- import * as path23 from "node:path";
15612
+ import * as fs24 from "node:fs";
15613
+ import * as path25 from "node:path";
15348
15614
  function resolveSubscriptions(opts) {
15349
15615
  const { clonePath, atlasUser } = opts;
15350
15616
  if (atlasUser) {
15351
- const subsPath = path23.join(clonePath, "members", atlasUser, "subscriptions.json");
15352
- if (fs22.existsSync(subsPath)) {
15617
+ const subsPath = path25.join(clonePath, "members", atlasUser, "subscriptions.json");
15618
+ if (fs24.existsSync(subsPath)) {
15353
15619
  try {
15354
- const parsed = JSON.parse(fs22.readFileSync(subsPath, "utf-8"));
15620
+ const parsed = JSON.parse(fs24.readFileSync(subsPath, "utf-8"));
15355
15621
  if (Array.isArray(parsed?.categories)) {
15356
15622
  return {
15357
15623
  categories: parsed.categories.filter((c) => typeof c === "string"),
@@ -15363,10 +15629,10 @@ function resolveSubscriptions(opts) {
15363
15629
  }
15364
15630
  }
15365
15631
  }
15366
- const catsPath = path23.join(clonePath, "shared", "categories.json");
15367
- if (fs22.existsSync(catsPath)) {
15632
+ const catsPath = path25.join(clonePath, "shared", "categories.json");
15633
+ if (fs24.existsSync(catsPath)) {
15368
15634
  try {
15369
- const parsed = JSON.parse(fs22.readFileSync(catsPath, "utf-8"));
15635
+ const parsed = JSON.parse(fs24.readFileSync(catsPath, "utf-8"));
15370
15636
  if (Array.isArray(parsed?.categories)) {
15371
15637
  return {
15372
15638
  categories: parsed.categories.map((c) => c.id).filter((id) => typeof id === "string"),
@@ -15377,14 +15643,14 @@ function resolveSubscriptions(opts) {
15377
15643
  } catch {
15378
15644
  }
15379
15645
  }
15380
- const sharedDir = path23.join(clonePath, "shared");
15646
+ const sharedDir = path25.join(clonePath, "shared");
15381
15647
  const cats = [];
15382
- if (fs22.existsSync(sharedDir)) {
15383
- for (const name of fs22.readdirSync(sharedDir)) {
15384
- const dir = path23.join(sharedDir, name);
15385
- if (!fs22.statSync(dir).isDirectory())
15648
+ if (fs24.existsSync(sharedDir)) {
15649
+ for (const name of fs24.readdirSync(sharedDir)) {
15650
+ const dir = path25.join(sharedDir, name);
15651
+ if (!fs24.statSync(dir).isDirectory())
15386
15652
  continue;
15387
- if (fs22.existsSync(path23.join(dir, "skills")) || fs22.existsSync(path23.join(dir, "agents"))) {
15653
+ if (fs24.existsSync(path25.join(dir, "skills")) || fs24.existsSync(path25.join(dir, "agents"))) {
15388
15654
  cats.push(name);
15389
15655
  }
15390
15656
  }
@@ -15392,29 +15658,29 @@ function resolveSubscriptions(opts) {
15392
15658
  return { categories: cats, fromSubscriptionsFile: false, atlasUser };
15393
15659
  }
15394
15660
  function listDirSafe(dir) {
15395
- if (!fs22.existsSync(dir))
15661
+ if (!fs24.existsSync(dir))
15396
15662
  return [];
15397
- return fs22.readdirSync(dir);
15663
+ return fs24.readdirSync(dir);
15398
15664
  }
15399
15665
  function resolveSkillsDir(opts) {
15400
15666
  const { sourceId, baseDir } = opts;
15401
15667
  const out = [];
15402
15668
  for (const name of listDirSafe(baseDir)) {
15403
- const subdir = path23.join(baseDir, name);
15404
- if (!fs22.statSync(subdir).isDirectory())
15669
+ const subdir = path25.join(baseDir, name);
15670
+ if (!fs24.statSync(subdir).isDirectory())
15405
15671
  continue;
15406
- if (!fs22.existsSync(path23.join(subdir, "SKILL.md")))
15672
+ if (!fs24.existsSync(path25.join(subdir, "SKILL.md")))
15407
15673
  continue;
15408
15674
  out.push({ kind: "skill", sourceId, sourcePath: subdir, deployBasename: name });
15409
- const subagentsDir = path23.join(subdir, "references", "agents");
15410
- if (fs22.existsSync(subagentsDir) && fs22.statSync(subagentsDir).isDirectory()) {
15675
+ const subagentsDir = path25.join(subdir, "references", "agents");
15676
+ if (fs24.existsSync(subagentsDir) && fs24.statSync(subagentsDir).isDirectory()) {
15411
15677
  for (const f of listDirSafe(subagentsDir)) {
15412
15678
  if (!f.endsWith(".md"))
15413
15679
  continue;
15414
15680
  out.push({
15415
15681
  kind: "subagent",
15416
15682
  sourceId,
15417
- sourcePath: path23.join(subagentsDir, f),
15683
+ sourcePath: path25.join(subagentsDir, f),
15418
15684
  deployBasename: f,
15419
15685
  parentSkill: name
15420
15686
  });
@@ -15427,8 +15693,8 @@ function resolveAgentsDir(opts) {
15427
15693
  const { sourceId, baseDir } = opts;
15428
15694
  const out = [];
15429
15695
  for (const name of listDirSafe(baseDir)) {
15430
- const full = path23.join(baseDir, name);
15431
- const stat2 = fs22.statSync(full);
15696
+ const full = path25.join(baseDir, name);
15697
+ const stat2 = fs24.statSync(full);
15432
15698
  if (stat2.isFile() && name.endsWith(".md")) {
15433
15699
  out.push({ kind: "agent", sourceId, sourcePath: full, deployBasename: name });
15434
15700
  } else if (stat2.isDirectory()) {
@@ -15438,7 +15704,7 @@ function resolveAgentsDir(opts) {
15438
15704
  out.push({
15439
15705
  kind: "agent",
15440
15706
  sourceId,
15441
- sourcePath: path23.join(full, f),
15707
+ sourcePath: path25.join(full, f),
15442
15708
  deployBasename: `${name}-${f}`
15443
15709
  });
15444
15710
  }
@@ -15450,8 +15716,8 @@ function resolveScriptsDir(opts) {
15450
15716
  const { sourceId, baseDir } = opts;
15451
15717
  const out = [];
15452
15718
  for (const name of listDirSafe(baseDir)) {
15453
- const full = path23.join(baseDir, name);
15454
- const stat2 = fs22.statSync(full);
15719
+ const full = path25.join(baseDir, name);
15720
+ const stat2 = fs24.statSync(full);
15455
15721
  if (stat2.isFile() && name.endsWith(".sh")) {
15456
15722
  out.push({ kind: "script", sourceId, sourcePath: full, deployBasename: name });
15457
15723
  } else if (stat2.isDirectory()) {
@@ -15466,8 +15732,8 @@ function resolveRulesDir(opts) {
15466
15732
  for (const name of listDirSafe(baseDir)) {
15467
15733
  if (!name.endsWith(".md"))
15468
15734
  continue;
15469
- const full = path23.join(baseDir, name);
15470
- if (!fs22.statSync(full).isFile())
15735
+ const full = path25.join(baseDir, name);
15736
+ if (!fs24.statSync(full).isFile())
15471
15737
  continue;
15472
15738
  out.push({ kind: "rule", sourceId, sourcePath: full, deployBasename: name });
15473
15739
  }
@@ -15479,8 +15745,8 @@ function resolveJsonDir(opts) {
15479
15745
  for (const name of listDirSafe(baseDir)) {
15480
15746
  if (!name.endsWith(".json"))
15481
15747
  continue;
15482
- const full = path23.join(baseDir, name);
15483
- if (!fs22.statSync(full).isFile())
15748
+ const full = path25.join(baseDir, name);
15749
+ if (!fs24.statSync(full).isFile())
15484
15750
  continue;
15485
15751
  out.push({ kind, sourceId, sourcePath: full, deployBasename: name });
15486
15752
  }
@@ -15492,8 +15758,8 @@ function resolveOverlaysDir(opts) {
15492
15758
  for (const name of listDirSafe(baseDir)) {
15493
15759
  if (!name.endsWith(".md"))
15494
15760
  continue;
15495
- const full = path23.join(baseDir, name);
15496
- if (!fs22.statSync(full).isFile())
15761
+ const full = path25.join(baseDir, name);
15762
+ if (!fs24.statSync(full).isFile())
15497
15763
  continue;
15498
15764
  const deployBasename = name.replace(/\.md$/, "");
15499
15765
  out.push({
@@ -15511,33 +15777,33 @@ function resolveSourceArtifacts(opts) {
15511
15777
  const subscription = resolveSubscriptions({ clonePath, atlasUser });
15512
15778
  const artifacts = [];
15513
15779
  for (const cat of subscription.categories) {
15514
- const catDir = path23.join(clonePath, "shared", cat);
15515
- if (!fs22.existsSync(catDir))
15780
+ const catDir = path25.join(clonePath, "shared", cat);
15781
+ if (!fs24.existsSync(catDir))
15516
15782
  continue;
15517
- artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path23.join(catDir, "skills") }));
15518
- artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path23.join(catDir, "agents") }));
15519
- artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path23.join(catDir, "scripts") }));
15520
- artifacts.push(...resolveRulesDir({ sourceId, baseDir: path23.join(catDir, "rules") }));
15521
- artifacts.push(...resolveJsonDir({ sourceId, baseDir: path23.join(catDir, "hooks"), kind: "hook" }));
15522
- artifacts.push(...resolveJsonDir({ sourceId, baseDir: path23.join(catDir, "permissions"), kind: "permission" }));
15783
+ artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path25.join(catDir, "skills") }));
15784
+ artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path25.join(catDir, "agents") }));
15785
+ artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path25.join(catDir, "scripts") }));
15786
+ artifacts.push(...resolveRulesDir({ sourceId, baseDir: path25.join(catDir, "rules") }));
15787
+ artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(catDir, "hooks"), kind: "hook" }));
15788
+ artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(catDir, "permissions"), kind: "permission" }));
15523
15789
  }
15524
15790
  if (atlasUser) {
15525
- const memberRoot = path23.join(clonePath, "members", atlasUser);
15526
- if (fs22.existsSync(memberRoot)) {
15527
- artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path23.join(memberRoot, "skills") }));
15528
- artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path23.join(memberRoot, "agents") }));
15529
- artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path23.join(memberRoot, "scripts") }));
15530
- artifacts.push(...resolveRulesDir({ sourceId, baseDir: path23.join(memberRoot, "rules") }));
15531
- artifacts.push(...resolveJsonDir({ sourceId, baseDir: path23.join(memberRoot, "hooks"), kind: "hook" }));
15532
- artifacts.push(...resolveJsonDir({ sourceId, baseDir: path23.join(memberRoot, "permissions"), kind: "permission" }));
15791
+ const memberRoot = path25.join(clonePath, "members", atlasUser);
15792
+ if (fs24.existsSync(memberRoot)) {
15793
+ artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path25.join(memberRoot, "skills") }));
15794
+ artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path25.join(memberRoot, "agents") }));
15795
+ artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path25.join(memberRoot, "scripts") }));
15796
+ artifacts.push(...resolveRulesDir({ sourceId, baseDir: path25.join(memberRoot, "rules") }));
15797
+ artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(memberRoot, "hooks"), kind: "hook" }));
15798
+ artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(memberRoot, "permissions"), kind: "permission" }));
15533
15799
  artifacts.push(...resolveOverlaysDir({
15534
15800
  sourceId,
15535
- baseDir: path23.join(memberRoot, "skills.overrides"),
15801
+ baseDir: path25.join(memberRoot, "skills.overrides"),
15536
15802
  targetKind: "skill"
15537
15803
  }));
15538
15804
  artifacts.push(...resolveOverlaysDir({
15539
15805
  sourceId,
15540
- baseDir: path23.join(memberRoot, "agents.overrides"),
15806
+ baseDir: path25.join(memberRoot, "agents.overrides"),
15541
15807
  targetKind: "agent"
15542
15808
  }));
15543
15809
  }
@@ -15603,14 +15869,14 @@ var init_shim_targets = __esm({
15603
15869
  });
15604
15870
 
15605
15871
  // ../core/dist/skill-sync/symlink-deployer.js
15606
- import * as fs23 from "node:fs";
15872
+ import * as fs25 from "node:fs";
15607
15873
  import * as os15 from "node:os";
15608
- import * as path24 from "node:path";
15874
+ import * as path26 from "node:path";
15609
15875
  function claudeDir() {
15610
15876
  const override = process.env["OLAM_CLAUDE_DIR"];
15611
15877
  if (override && override.length > 0)
15612
15878
  return override;
15613
- return path24.join(os15.homedir(), ".claude");
15879
+ return path26.join(os15.homedir(), ".claude");
15614
15880
  }
15615
15881
  function bucketFor(kind) {
15616
15882
  switch (kind) {
@@ -15670,15 +15936,15 @@ function detectCollisions(artifacts) {
15670
15936
  function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, expectedAgentWinnerNames) {
15671
15937
  const shadowBackups = [];
15672
15938
  for (const bucket of BUCKETS) {
15673
- const dir = path24.join(claude, bucket);
15674
- if (!fs23.existsSync(dir))
15939
+ const dir = path26.join(claude, bucket);
15940
+ if (!fs25.existsSync(dir))
15675
15941
  continue;
15676
- for (const name of fs23.readdirSync(dir)) {
15942
+ for (const name of fs25.readdirSync(dir)) {
15677
15943
  if (name === ".olam-merged")
15678
15944
  continue;
15679
- const p = path24.join(dir, name);
15945
+ const p = path26.join(dir, name);
15680
15946
  try {
15681
- const stat2 = fs23.lstatSync(p);
15947
+ const stat2 = fs25.lstatSync(p);
15682
15948
  if (stat2.isSymbolicLink()) {
15683
15949
  if (bucket === "scripts" && overlayReferences !== void 0) {
15684
15950
  const refs = overlayReferences.get(name);
@@ -15699,7 +15965,7 @@ function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, e
15699
15965
  `);
15700
15966
  }
15701
15967
  }
15702
- fs23.unlinkSync(p);
15968
+ fs25.unlinkSync(p);
15703
15969
  } else if (bucket === "agents" && stat2.isFile() && !name.includes(".shadow-backup-")) {
15704
15970
  const hasWinner = expectedAgentWinnerNames !== void 0 ? expectedAgentWinnerNames.has(name) : true;
15705
15971
  if (hasWinner) {
@@ -15716,34 +15982,34 @@ function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, e
15716
15982
  function shadowBackup(link) {
15717
15983
  const epoch = Math.floor(Date.now() / 1e3);
15718
15984
  const backup = `${link}.shadow-backup-${epoch}`;
15719
- fs23.renameSync(link, backup);
15985
+ fs25.renameSync(link, backup);
15720
15986
  return backup;
15721
15987
  }
15722
15988
  function linkIfNeeded(target, link) {
15723
15989
  try {
15724
- const existing = fs23.readlinkSync(link);
15990
+ const existing = fs25.readlinkSync(link);
15725
15991
  if (existing === target)
15726
15992
  return { created: false };
15727
15993
  } catch {
15728
15994
  }
15729
15995
  let isLink = false;
15730
15996
  try {
15731
- isLink = fs23.lstatSync(link).isSymbolicLink();
15997
+ isLink = fs25.lstatSync(link).isSymbolicLink();
15732
15998
  } catch {
15733
15999
  }
15734
16000
  let backup;
15735
16001
  if (isLink) {
15736
- fs23.unlinkSync(link);
15737
- } else if (fs23.existsSync(link)) {
16002
+ fs25.unlinkSync(link);
16003
+ } else if (fs25.existsSync(link)) {
15738
16004
  backup = shadowBackup(link);
15739
16005
  }
15740
- fs23.symlinkSync(target, link);
16006
+ fs25.symlinkSync(target, link);
15741
16007
  return { created: true, shadowBackup: backup };
15742
16008
  }
15743
16009
  function deployArtifacts(artifacts, opts) {
15744
16010
  const claude = claudeDir();
15745
16011
  for (const bucket of BUCKETS) {
15746
- fs23.mkdirSync(path24.join(claude, bucket), { recursive: true });
16012
+ fs25.mkdirSync(path26.join(claude, bucket), { recursive: true });
15747
16013
  }
15748
16014
  const { winners, collisions } = detectCollisions(artifacts);
15749
16015
  const expectedAgentWinnerNames = new Set(winners.filter((a) => a.kind === "agent").map((a) => a.deployBasename));
@@ -15753,11 +16019,11 @@ function deployArtifacts(artifacts, opts) {
15753
16019
  const bucket = bucketFor(artifact.kind);
15754
16020
  if (!bucket)
15755
16021
  continue;
15756
- const linkPath = path24.join(claude, bucket, artifact.deployBasename);
16022
+ const linkPath = path26.join(claude, bucket, artifact.deployBasename);
15757
16023
  if (artifact.kind === "agent" && artifact.resolvedContent !== void 0) {
15758
16024
  const tmpPath = `${linkPath}.tmp-${process.pid}-${Date.now()}`;
15759
- fs23.writeFileSync(tmpPath, artifact.resolvedContent);
15760
- fs23.renameSync(tmpPath, linkPath);
16025
+ fs25.writeFileSync(tmpPath, artifact.resolvedContent);
16026
+ fs25.renameSync(tmpPath, linkPath);
15761
16027
  result.linked += 1;
15762
16028
  continue;
15763
16029
  }
@@ -15779,7 +16045,7 @@ var init_symlink_deployer = __esm({
15779
16045
  });
15780
16046
 
15781
16047
  // ../core/dist/meta-hooks/memory-recall.js
15782
- import * as fs24 from "node:fs";
16048
+ import * as fs26 from "node:fs";
15783
16049
  function buildMemoryRecallHookEntry() {
15784
16050
  return {
15785
16051
  matcher: OLAM_META_MEMORY_RECALL_MATCHER,
@@ -15854,7 +16120,7 @@ var init_memory_recall = __esm({
15854
16120
  });
15855
16121
 
15856
16122
  // ../core/dist/meta-hooks/memory-classify.js
15857
- import * as fs25 from "node:fs";
16123
+ import * as fs27 from "node:fs";
15858
16124
  function buildMemoryClassifyHookEntry() {
15859
16125
  return {
15860
16126
  matcher: OLAM_META_MEMORY_CLASSIFY_MATCHER,
@@ -15929,7 +16195,7 @@ var init_memory_classify = __esm({
15929
16195
  });
15930
16196
 
15931
16197
  // ../core/dist/meta-hooks/model-router.js
15932
- import * as fs26 from "node:fs";
16198
+ import * as fs28 from "node:fs";
15933
16199
  function buildModelRouterHookEntry() {
15934
16200
  return {
15935
16201
  hooks: [
@@ -16003,9 +16269,9 @@ var init_model_router = __esm({
16003
16269
  });
16004
16270
 
16005
16271
  // ../core/dist/meta-hooks/model-router-deploy.js
16006
- import { existsSync as existsSync30, mkdirSync as mkdirSync16, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "node:fs";
16272
+ import { existsSync as existsSync32, mkdirSync as mkdirSync16, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
16007
16273
  import { homedir as homedir18 } from "node:os";
16008
- import { dirname as dirname13, join as join27, resolve as resolve7 } from "node:path";
16274
+ import { dirname as dirname13, join as join29, resolve as resolve7 } from "node:path";
16009
16275
  import { fileURLToPath as fileURLToPath3 } from "node:url";
16010
16276
  function resolveModelRouterSourcePath() {
16011
16277
  const here = dirname13(fileURLToPath3(import.meta.url));
@@ -16019,28 +16285,28 @@ function resolveModelRouterSourcePath() {
16019
16285
  resolve7(here, "..", "..", "hooks", MODEL_ROUTER_SCRIPT_BASENAME)
16020
16286
  ];
16021
16287
  for (const candidate of candidates) {
16022
- if (existsSync30(candidate))
16288
+ if (existsSync32(candidate))
16023
16289
  return candidate;
16024
16290
  }
16025
16291
  return candidates[0];
16026
16292
  }
16027
16293
  function deployModelRouterScript(opts = {}) {
16028
- const targetDir = opts.targetDir ?? join27(homedir18(), ".claude", "hooks");
16029
- const targetPath = join27(targetDir, MODEL_ROUTER_SCRIPT_BASENAME);
16294
+ const targetDir = opts.targetDir ?? join29(homedir18(), ".claude", "hooks");
16295
+ const targetPath = join29(targetDir, MODEL_ROUTER_SCRIPT_BASENAME);
16030
16296
  const sourcePath = opts.sourcePath ?? resolveModelRouterSourcePath();
16031
- if (!existsSync30(sourcePath)) {
16297
+ if (!existsSync32(sourcePath)) {
16032
16298
  return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "source-missing", targetPath };
16033
16299
  }
16034
- const newContent = readFileSync22(sourcePath, "utf8");
16035
- if (existsSync30(targetPath)) {
16036
- const existing = readFileSync22(targetPath, "utf8");
16300
+ const newContent = readFileSync23(sourcePath, "utf8");
16301
+ if (existsSync32(targetPath)) {
16302
+ const existing = readFileSync23(targetPath, "utf8");
16037
16303
  if (existing === newContent) {
16038
16304
  return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "unchanged", targetPath };
16039
16305
  }
16040
16306
  }
16041
16307
  if (opts.dryRun !== true) {
16042
16308
  mkdirSync16(dirname13(targetPath), { recursive: true });
16043
- writeFileSync14(targetPath, newContent, { mode: 493 });
16309
+ writeFileSync15(targetPath, newContent, { mode: 493 });
16044
16310
  }
16045
16311
  return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "written", targetPath };
16046
16312
  }
@@ -16064,26 +16330,26 @@ var init_meta_hooks = __esm({
16064
16330
  });
16065
16331
 
16066
16332
  // ../core/dist/skill-sync/settings-merger.js
16067
- import * as fs27 from "node:fs";
16333
+ import * as fs29 from "node:fs";
16068
16334
  import * as os16 from "node:os";
16069
- import * as path25 from "node:path";
16335
+ import * as path27 from "node:path";
16070
16336
  function claudeSettingsPath() {
16071
16337
  const override = process.env["OLAM_CLAUDE_SETTINGS_PATH"];
16072
16338
  if (override && override.length > 0)
16073
16339
  return override;
16074
- return path25.join(claudeDirInternal2(), "settings.json");
16340
+ return path27.join(claudeDirInternal2(), "settings.json");
16075
16341
  }
16076
16342
  function claudeDirInternal2() {
16077
16343
  const override = process.env["OLAM_CLAUDE_DIR"];
16078
16344
  if (override && override.length > 0)
16079
16345
  return override;
16080
- return path25.join(os16.homedir(), ".claude");
16346
+ return path27.join(os16.homedir(), ".claude");
16081
16347
  }
16082
16348
  function settingsBackupDir() {
16083
16349
  const override = process.env["OLAM_SETTINGS_BACKUP_DIR"];
16084
16350
  if (override && override.length > 0)
16085
16351
  return override;
16086
- return path25.join(os16.homedir(), ".olam", "state", "settings-backups");
16352
+ return path27.join(os16.homedir(), ".olam", "state", "settings-backups");
16087
16353
  }
16088
16354
  function dedupeByMatcher(entries) {
16089
16355
  const map2 = /* @__PURE__ */ new Map();
@@ -16133,28 +16399,28 @@ function tagOlam(entry) {
16133
16399
  return { ...entry, [OLAM_SKILLS_MARKER]: true };
16134
16400
  }
16135
16401
  function readJson(file2) {
16136
- return JSON.parse(fs27.readFileSync(file2, "utf-8"));
16402
+ return JSON.parse(fs29.readFileSync(file2, "utf-8"));
16137
16403
  }
16138
16404
  function rotateBackups(backupDir) {
16139
- if (!fs27.existsSync(backupDir))
16405
+ if (!fs29.existsSync(backupDir))
16140
16406
  return;
16141
- const files = fs27.readdirSync(backupDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, full: path25.join(backupDir, f), mtime: fs27.statSync(path25.join(backupDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
16407
+ const files = fs29.readdirSync(backupDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, full: path27.join(backupDir, f), mtime: fs29.statSync(path27.join(backupDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
16142
16408
  for (const f of files.slice(BACKUP_RETENTION)) {
16143
16409
  try {
16144
- fs27.unlinkSync(f.full);
16410
+ fs29.unlinkSync(f.full);
16145
16411
  } catch {
16146
16412
  }
16147
16413
  }
16148
16414
  }
16149
16415
  function backupSettings() {
16150
16416
  const src = claudeSettingsPath();
16151
- if (!fs27.existsSync(src))
16417
+ if (!fs29.existsSync(src))
16152
16418
  return void 0;
16153
16419
  const dir = settingsBackupDir();
16154
- fs27.mkdirSync(dir, { recursive: true });
16420
+ fs29.mkdirSync(dir, { recursive: true });
16155
16421
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
16156
- const dest = path25.join(dir, `settings-${stamp}.json`);
16157
- fs27.copyFileSync(src, dest);
16422
+ const dest = path27.join(dir, `settings-${stamp}.json`);
16423
+ fs29.copyFileSync(src, dest);
16158
16424
  rotateBackups(dir);
16159
16425
  return dest;
16160
16426
  }
@@ -16162,7 +16428,7 @@ function mergeSettings(input) {
16162
16428
  const settingsPath = claudeSettingsPath();
16163
16429
  const backupPath = backupSettings();
16164
16430
  let base = {};
16165
- if (fs27.existsSync(settingsPath)) {
16431
+ if (fs29.existsSync(settingsPath)) {
16166
16432
  try {
16167
16433
  base = readJson(settingsPath);
16168
16434
  } catch {
@@ -16230,10 +16496,10 @@ function mergeSettings(input) {
16230
16496
  ...input.permissionFiles.length > 0 ? { allow: [...permSet] } : {}
16231
16497
  }
16232
16498
  };
16233
- fs27.mkdirSync(path25.dirname(settingsPath), { recursive: true });
16499
+ fs29.mkdirSync(path27.dirname(settingsPath), { recursive: true });
16234
16500
  const tmp = `${settingsPath}.tmp-${process.pid}`;
16235
- fs27.writeFileSync(tmp, JSON.stringify(next, null, 2) + "\n", { mode: 420 });
16236
- fs27.renameSync(tmp, settingsPath);
16501
+ fs29.writeFileSync(tmp, JSON.stringify(next, null, 2) + "\n", { mode: 420 });
16502
+ fs29.renameSync(tmp, settingsPath);
16237
16503
  return { backupPath, hooksAdded, permissionsCount: permSet.size, dualWriteDeduped, dualWriteDroppedCommands };
16238
16504
  }
16239
16505
  var OLAM_SKILLS_MARKER, BACKUP_RETENTION, DUAL_WRITE_DEDUP_RULES;
@@ -16289,17 +16555,17 @@ var init_schema5 = __esm({
16289
16555
  });
16290
16556
 
16291
16557
  // ../core/dist/skill-sync/per-project-override.js
16292
- import { execFileSync as execFileSync3 } from "node:child_process";
16293
- import * as fs28 from "node:fs";
16294
- import * as path26 from "node:path";
16558
+ import { execFileSync as execFileSync4 } from "node:child_process";
16559
+ import * as fs30 from "node:fs";
16560
+ import * as path28 from "node:path";
16295
16561
  import { parse as parseYaml3 } from "yaml";
16296
16562
  function findProjectOverride(startDir) {
16297
- let dir = path26.resolve(startDir);
16298
- const root = path26.parse(dir).root;
16563
+ let dir = path28.resolve(startDir);
16564
+ const root = path28.parse(dir).root;
16299
16565
  while (true) {
16300
- const candidate = path26.join(dir, PROJECT_OVERRIDE_RELATIVE_PATH);
16301
- if (fs28.existsSync(candidate) && fs28.statSync(candidate).isFile()) {
16302
- const raw = fs28.readFileSync(candidate, "utf-8");
16566
+ const candidate = path28.join(dir, PROJECT_OVERRIDE_RELATIVE_PATH);
16567
+ if (fs30.existsSync(candidate) && fs30.statSync(candidate).isFile()) {
16568
+ const raw = fs30.readFileSync(candidate, "utf-8");
16303
16569
  let parsed;
16304
16570
  try {
16305
16571
  parsed = parseYaml3(raw);
@@ -16312,7 +16578,7 @@ function findProjectOverride(startDir) {
16312
16578
  }
16313
16579
  if (dir === root)
16314
16580
  return void 0;
16315
- dir = path26.dirname(dir);
16581
+ dir = path28.dirname(dir);
16316
16582
  }
16317
16583
  }
16318
16584
  function applyOverrideToArtifacts(artifacts, override) {
@@ -16332,7 +16598,7 @@ function applyPinToClone(opts) {
16332
16598
  if (ref.startsWith("-")) {
16333
16599
  throw new Error(`refuses ref "${ref}" \u2014 must not start with "-" (would be parsed as a git option)`);
16334
16600
  }
16335
- execFileSync3("git", ["-C", clonePath, "checkout", "-q", ref], {
16601
+ execFileSync4("git", ["-C", clonePath, "checkout", "-q", ref], {
16336
16602
  stdio: ["ignore", "ignore", "pipe"]
16337
16603
  });
16338
16604
  }
@@ -16342,7 +16608,7 @@ function restoreCloneToBranchHead(opts) {
16342
16608
  return;
16343
16609
  }
16344
16610
  try {
16345
- execFileSync3("git", ["-C", clonePath, "checkout", "-q", branch], {
16611
+ execFileSync4("git", ["-C", clonePath, "checkout", "-q", branch], {
16346
16612
  stdio: ["ignore", "ignore", "pipe"]
16347
16613
  });
16348
16614
  } catch {
@@ -16353,14 +16619,14 @@ var init_per_project_override = __esm({
16353
16619
  "../core/dist/skill-sync/per-project-override.js"() {
16354
16620
  "use strict";
16355
16621
  init_schema5();
16356
- PROJECT_OVERRIDE_RELATIVE_PATH = path26.join(".olam", "skill-overrides.yaml");
16622
+ PROJECT_OVERRIDE_RELATIVE_PATH = path28.join(".olam", "skill-overrides.yaml");
16357
16623
  }
16358
16624
  });
16359
16625
 
16360
16626
  // ../core/dist/lib/file-lock.js
16361
- import * as fs29 from "node:fs";
16627
+ import * as fs31 from "node:fs";
16362
16628
  import * as os17 from "node:os";
16363
- import * as path27 from "node:path";
16629
+ import * as path29 from "node:path";
16364
16630
  function defaultIsPidAlive(pid) {
16365
16631
  try {
16366
16632
  process.kill(pid, 0);
@@ -16375,7 +16641,7 @@ function sleep3(ms) {
16375
16641
  }
16376
16642
  function readLockMeta(lockPath) {
16377
16643
  try {
16378
- const raw = fs29.readFileSync(lockPath, "utf-8");
16644
+ const raw = fs31.readFileSync(lockPath, "utf-8");
16379
16645
  const parsed = JSON.parse(raw);
16380
16646
  if (typeof parsed?.pid === "number" && typeof parsed?.hostname === "string" && typeof parsed?.timestamp === "number") {
16381
16647
  return parsed;
@@ -16394,12 +16660,12 @@ function isLockStale(meta3, opts) {
16394
16660
  }
16395
16661
  function tryAcquireOnce(lockPath, meta3, opts) {
16396
16662
  try {
16397
- fs29.mkdirSync(path27.dirname(lockPath), { recursive: true });
16398
- const fd = fs29.openSync(lockPath, "wx", 384);
16663
+ fs31.mkdirSync(path29.dirname(lockPath), { recursive: true });
16664
+ const fd = fs31.openSync(lockPath, "wx", 384);
16399
16665
  try {
16400
- fs29.writeSync(fd, JSON.stringify(meta3));
16666
+ fs31.writeSync(fd, JSON.stringify(meta3));
16401
16667
  } finally {
16402
- fs29.closeSync(fd);
16668
+ fs31.closeSync(fd);
16403
16669
  }
16404
16670
  return true;
16405
16671
  } catch (err) {
@@ -16409,14 +16675,14 @@ function tryAcquireOnce(lockPath, meta3, opts) {
16409
16675
  const existing = readLockMeta(lockPath);
16410
16676
  if (existing === void 0) {
16411
16677
  try {
16412
- fs29.unlinkSync(lockPath);
16678
+ fs31.unlinkSync(lockPath);
16413
16679
  } catch {
16414
16680
  }
16415
16681
  return tryAcquireOnce(lockPath, meta3, opts);
16416
16682
  }
16417
16683
  if (isLockStale(existing, opts)) {
16418
16684
  try {
16419
- fs29.unlinkSync(lockPath);
16685
+ fs31.unlinkSync(lockPath);
16420
16686
  } catch {
16421
16687
  }
16422
16688
  return tryAcquireOnce(lockPath, meta3, opts);
@@ -16426,7 +16692,7 @@ function tryAcquireOnce(lockPath, meta3, opts) {
16426
16692
  }
16427
16693
  async function acquireFileLock(lockDir, options = {}) {
16428
16694
  const lockFilename = options.lockFilename ?? DEFAULT_LOCK_FILENAME;
16429
- const lockPath = path27.join(lockDir, lockFilename);
16695
+ const lockPath = path29.join(lockDir, lockFilename);
16430
16696
  const acquireTimeoutMs = options.acquireTimeoutMs ?? DEFAULT_ACQUIRE_TIMEOUT_MS;
16431
16697
  const staleLockMs = options.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
16432
16698
  const now = options.now ?? Date.now;
@@ -16446,7 +16712,7 @@ async function acquireFileLock(lockDir, options = {}) {
16446
16712
  lockPath,
16447
16713
  release: () => {
16448
16714
  try {
16449
- fs29.unlinkSync(lockPath);
16715
+ fs31.unlinkSync(lockPath);
16450
16716
  } catch {
16451
16717
  }
16452
16718
  }
@@ -16486,13 +16752,13 @@ var init_file_lock = __esm({
16486
16752
  });
16487
16753
 
16488
16754
  // ../core/dist/lib/min-version-filter.js
16489
- import { existsSync as existsSync33, readFileSync as readFileSync26 } from "node:fs";
16755
+ import { existsSync as existsSync35, readFileSync as readFileSync27 } from "node:fs";
16490
16756
  function readOlamMinVersion(filepath) {
16491
- if (!existsSync33(filepath))
16757
+ if (!existsSync35(filepath))
16492
16758
  return void 0;
16493
16759
  let text;
16494
16760
  try {
16495
- text = readFileSync26(filepath, "utf8");
16761
+ text = readFileSync27(filepath, "utf8");
16496
16762
  } catch {
16497
16763
  return void 0;
16498
16764
  }
@@ -16550,11 +16816,11 @@ var init_min_version_filter = __esm({
16550
16816
  });
16551
16817
 
16552
16818
  // ../core/dist/skill-sync/overlay-scan.js
16553
- import * as fs30 from "node:fs";
16554
- import * as path28 from "node:path";
16819
+ import * as fs32 from "node:fs";
16820
+ import * as path30 from "node:path";
16555
16821
  function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
16556
16822
  const result = /* @__PURE__ */ new Map();
16557
- if (!fs30.existsSync(overlayRoot)) {
16823
+ if (!fs32.existsSync(overlayRoot)) {
16558
16824
  return result;
16559
16825
  }
16560
16826
  if (basenames.length === 0) {
@@ -16563,13 +16829,13 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
16563
16829
  const mdFiles = [];
16564
16830
  let overlayRootReal;
16565
16831
  try {
16566
- overlayRootReal = fs30.realpathSync(overlayRoot);
16832
+ overlayRootReal = fs32.realpathSync(overlayRoot);
16567
16833
  } catch {
16568
16834
  return result;
16569
16835
  }
16570
16836
  for (const subdir of OVERRIDE_SUBDIRS) {
16571
- const dir = path28.join(overlayRoot, subdir);
16572
- if (!fs30.existsSync(dir))
16837
+ const dir = path30.join(overlayRoot, subdir);
16838
+ if (!fs32.existsSync(dir))
16573
16839
  continue;
16574
16840
  walkMarkdown(dir, mdFiles, caps.maxFiles);
16575
16841
  }
@@ -16577,25 +16843,25 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
16577
16843
  for (const filepath of mdFiles) {
16578
16844
  let realFile;
16579
16845
  try {
16580
- realFile = fs30.realpathSync(filepath);
16846
+ realFile = fs32.realpathSync(filepath);
16581
16847
  } catch (err) {
16582
16848
  const code = err.code;
16583
16849
  if (code === "ENOENT" || code === "EACCES")
16584
16850
  continue;
16585
16851
  throw err;
16586
16852
  }
16587
- const rel = path28.relative(overlayRootReal, realFile);
16588
- if (rel.startsWith("..") || path28.isAbsolute(rel)) {
16853
+ const rel = path30.relative(overlayRootReal, realFile);
16854
+ if (rel.startsWith("..") || path30.isAbsolute(rel)) {
16589
16855
  continue;
16590
16856
  }
16591
16857
  let content;
16592
16858
  try {
16593
- const stat2 = fs30.statSync(filepath);
16859
+ const stat2 = fs32.statSync(filepath);
16594
16860
  totalBytes += stat2.size;
16595
16861
  if (totalBytes > caps.maxTotalBytes) {
16596
16862
  throw new Error(`[overlay-scan] aborted: overlay tree exceeds ${caps.maxTotalBytes} total bytes. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
16597
16863
  }
16598
- content = fs30.readFileSync(filepath, "utf8");
16864
+ content = fs32.readFileSync(filepath, "utf8");
16599
16865
  } catch (err) {
16600
16866
  const code = err.code;
16601
16867
  if (code === "ENOENT" || code === "EACCES") {
@@ -16603,7 +16869,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
16603
16869
  }
16604
16870
  throw err;
16605
16871
  }
16606
- const relpath = path28.relative(overlayRoot, filepath).split(path28.sep).join("/");
16872
+ const relpath = path30.relative(overlayRoot, filepath).split(path30.sep).join("/");
16607
16873
  for (const basename6 of basenames) {
16608
16874
  if (content.includes(basename6)) {
16609
16875
  const list = result.get(basename6) ?? [];
@@ -16617,7 +16883,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
16617
16883
  function walkMarkdown(dir, out, cap) {
16618
16884
  let entries;
16619
16885
  try {
16620
- entries = fs30.readdirSync(dir, { withFileTypes: true });
16886
+ entries = fs32.readdirSync(dir, { withFileTypes: true });
16621
16887
  } catch (err) {
16622
16888
  if (err.code === "ENOENT")
16623
16889
  return;
@@ -16627,7 +16893,7 @@ function walkMarkdown(dir, out, cap) {
16627
16893
  if (out.length >= cap) {
16628
16894
  throw new Error(`[overlay-scan] aborted: overlay tree contains > ${cap} markdown files. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
16629
16895
  }
16630
- const full = path28.join(dir, entry.name);
16896
+ const full = path30.join(dir, entry.name);
16631
16897
  if (entry.isSymbolicLink())
16632
16898
  continue;
16633
16899
  if (entry.isDirectory()) {
@@ -16652,12 +16918,12 @@ var init_overlay_scan = __esm({
16652
16918
  });
16653
16919
 
16654
16920
  // ../core/dist/skill-sync/settings-json-lock.js
16655
- import * as fs31 from "node:fs";
16921
+ import * as fs33 from "node:fs";
16656
16922
  import * as os18 from "node:os";
16657
- import * as path29 from "node:path";
16923
+ import * as path31 from "node:path";
16658
16924
  function defaultSettingsJsonLockPath() {
16659
- const stateDir = process.env["OLAM_STATE_DIR"] ?? path29.join(os18.homedir(), ".olam", "state");
16660
- return path29.join(stateDir, SETTINGS_JSON_LOCK_FILENAME);
16925
+ const stateDir = process.env["OLAM_STATE_DIR"] ?? path31.join(os18.homedir(), ".olam", "state");
16926
+ return path31.join(stateDir, SETTINGS_JSON_LOCK_FILENAME);
16661
16927
  }
16662
16928
  function defaultIsPidAlive2(pid) {
16663
16929
  try {
@@ -16673,7 +16939,7 @@ function sleep4(ms) {
16673
16939
  }
16674
16940
  function readLockMeta2(lockPath) {
16675
16941
  try {
16676
- const raw = fs31.readFileSync(lockPath, "utf-8");
16942
+ const raw = fs33.readFileSync(lockPath, "utf-8");
16677
16943
  const parsed = JSON.parse(raw);
16678
16944
  if (typeof parsed?.pid === "number" && typeof parsed?.hostname === "string" && typeof parsed?.timestamp === "number") {
16679
16945
  return parsed;
@@ -16696,12 +16962,12 @@ function isLockStale2(meta3, opts) {
16696
16962
  function tryAcquireOnce2(lockPath, meta3, opts) {
16697
16963
  for (let attempt = 0; attempt <= MAX_STEAL_ATTEMPTS; attempt += 1) {
16698
16964
  try {
16699
- fs31.mkdirSync(path29.dirname(lockPath), { recursive: true });
16700
- const fd = fs31.openSync(lockPath, "wx", 384);
16965
+ fs33.mkdirSync(path31.dirname(lockPath), { recursive: true });
16966
+ const fd = fs33.openSync(lockPath, "wx", 384);
16701
16967
  try {
16702
- fs31.writeSync(fd, JSON.stringify(meta3));
16968
+ fs33.writeSync(fd, JSON.stringify(meta3));
16703
16969
  } finally {
16704
- fs31.closeSync(fd);
16970
+ fs33.closeSync(fd);
16705
16971
  }
16706
16972
  return true;
16707
16973
  } catch (err) {
@@ -16719,9 +16985,9 @@ function tryAcquireOnce2(lockPath, meta3, opts) {
16719
16985
  }
16720
16986
  const victimPath = `${lockPath}.victim-${process.pid}-${attempt}-${Date.now()}`;
16721
16987
  try {
16722
- fs31.renameSync(lockPath, victimPath);
16988
+ fs33.renameSync(lockPath, victimPath);
16723
16989
  try {
16724
- fs31.unlinkSync(victimPath);
16990
+ fs33.unlinkSync(victimPath);
16725
16991
  } catch {
16726
16992
  }
16727
16993
  } catch (err) {
@@ -16753,7 +17019,7 @@ async function acquireSettingsJsonLock(options = {}) {
16753
17019
  lockPath,
16754
17020
  release: () => {
16755
17021
  try {
16756
- fs31.unlinkSync(lockPath);
17022
+ fs33.unlinkSync(lockPath);
16757
17023
  } catch {
16758
17024
  }
16759
17025
  }
@@ -16856,14 +17122,14 @@ var init_services_status = __esm({
16856
17122
 
16857
17123
  // ../core/dist/skill-sources/meta-hooks-migration-snapshot.js
16858
17124
  import * as crypto5 from "node:crypto";
16859
- import * as fs32 from "node:fs";
17125
+ import * as fs34 from "node:fs";
16860
17126
  import * as os19 from "node:os";
16861
- import * as path30 from "node:path";
17127
+ import * as path32 from "node:path";
16862
17128
  function migrationSnapshotsDir2() {
16863
17129
  const override = process.env["OLAM_MIGRATION_SNAPSHOTS_DIR"];
16864
17130
  if (override && override.length > 0)
16865
17131
  return override;
16866
- return path30.join(os19.homedir(), ".olam", "state", "migration-snapshots");
17132
+ return path32.join(os19.homedir(), ".olam", "state", "migration-snapshots");
16867
17133
  }
16868
17134
  function writeMetaHooksSnapshot(originalSettings) {
16869
17135
  const snapshot = {
@@ -16874,11 +17140,11 @@ function writeMetaHooksSnapshot(originalSettings) {
16874
17140
  };
16875
17141
  const validated = MetaHooksMigrationSnapshotSchema.parse(snapshot);
16876
17142
  const dir = migrationSnapshotsDir2();
16877
- fs32.mkdirSync(dir, { recursive: true });
17143
+ fs34.mkdirSync(dir, { recursive: true });
16878
17144
  const stamp = validated.takenAt.replace(/[:.]/g, "-");
16879
17145
  const rand = crypto5.randomBytes(3).toString("hex");
16880
- const file2 = path30.join(dir, `${META_HOOKS_SNAPSHOT_PREFIX}${stamp}-${process.pid}-${rand}.json`);
16881
- fs32.writeFileSync(file2, JSON.stringify(validated, null, 2) + "\n", { mode: 384 });
17146
+ const file2 = path32.join(dir, `${META_HOOKS_SNAPSHOT_PREFIX}${stamp}-${process.pid}-${rand}.json`);
17147
+ fs34.writeFileSync(file2, JSON.stringify(validated, null, 2) + "\n", { mode: 384 });
16882
17148
  return file2;
16883
17149
  }
16884
17150
  var META_HOOKS_SNAPSHOT_SCHEMA_VERSION, META_HOOKS_SNAPSHOT_PREFIX, SettingsLooseSchema, MetaHooksMigrationSnapshotSchema;
@@ -17168,7 +17434,7 @@ var init_meta_hook_injector = __esm({
17168
17434
 
17169
17435
  // ../core/dist/lib/markdown-merger.js
17170
17436
  import { createHash as createHash5 } from "node:crypto";
17171
- import { readFileSync as readFileSync30, existsSync as existsSync36, statSync as statSync8 } from "node:fs";
17437
+ import { readFileSync as readFileSync31, existsSync as existsSync38, statSync as statSync9 } from "node:fs";
17172
17438
  function parseFrontmatter(text) {
17173
17439
  const match = FM_RE2.exec(text);
17174
17440
  if (match === null)
@@ -17297,9 +17563,9 @@ function mergeMarkdown(upstreamText, overlayText, labelForError, upstreamPath, o
17297
17563
  return { merged: fmBlock !== "" ? fmBlock + mergedBody : mergedBody };
17298
17564
  }
17299
17565
  function sha256OfPath(p) {
17300
- if (!existsSync36(p) || !statSync8(p).isFile())
17566
+ if (!existsSync38(p) || !statSync9(p).isFile())
17301
17567
  return "MISSING";
17302
- return createHash5("sha256").update(readFileSync30(p)).digest("hex");
17568
+ return createHash5("sha256").update(readFileSync31(p)).digest("hex");
17303
17569
  }
17304
17570
  var FM_RE2, H2_RE;
17305
17571
  var init_markdown_merger = __esm({
@@ -17311,44 +17577,44 @@ var init_markdown_merger = __esm({
17311
17577
  });
17312
17578
 
17313
17579
  // ../core/dist/skill-sync/managed-merge.js
17314
- import * as fs33 from "node:fs";
17315
- import * as path31 from "node:path";
17580
+ import * as fs35 from "node:fs";
17581
+ import * as path33 from "node:path";
17316
17582
  function materializeMergedSkill(opts) {
17317
17583
  const { sourceId, sourcePath, deployBasename, mergedContent, claudeDir: claudeDir2 } = opts;
17318
- const managedDir = path31.join(claudeDir2, ".olam-merged", sourceId, deployBasename);
17319
- const sourceRoot = path31.resolve(path31.join(claudeDir2, ".olam-merged", sourceId));
17320
- const managedResolved = path31.resolve(managedDir);
17321
- if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot + path31.sep))) {
17584
+ const managedDir = path33.join(claudeDir2, ".olam-merged", sourceId, deployBasename);
17585
+ const sourceRoot = path33.resolve(path33.join(claudeDir2, ".olam-merged", sourceId));
17586
+ const managedResolved = path33.resolve(managedDir);
17587
+ if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot + path33.sep))) {
17322
17588
  throw new Error(`[managed-merge] refusing to materialize: deployBasename "${deployBasename}" escapes managed root "${sourceRoot}" (resolved to "${managedResolved}")`);
17323
17589
  }
17324
- fs33.mkdirSync(managedDir, { recursive: true });
17325
- const skillMdPath = path31.join(managedDir, "SKILL.md");
17590
+ fs35.mkdirSync(managedDir, { recursive: true });
17591
+ const skillMdPath = path33.join(managedDir, "SKILL.md");
17326
17592
  const tmpPath = `${skillMdPath}.tmp-${process.pid}-${Date.now()}`;
17327
- fs33.writeFileSync(tmpPath, mergedContent);
17328
- fs33.renameSync(tmpPath, skillMdPath);
17329
- const baseEntries = fs33.readdirSync(sourcePath);
17593
+ fs35.writeFileSync(tmpPath, mergedContent);
17594
+ fs35.renameSync(tmpPath, skillMdPath);
17595
+ const baseEntries = fs35.readdirSync(sourcePath);
17330
17596
  for (const entry of baseEntries) {
17331
17597
  if (entry === "SKILL.md")
17332
17598
  continue;
17333
- const linkPath = path31.join(managedDir, entry);
17334
- const targetAbsolute = path31.join(sourcePath, entry);
17335
- const targetRelative = path31.relative(managedDir, targetAbsolute);
17599
+ const linkPath = path33.join(managedDir, entry);
17600
+ const targetAbsolute = path33.join(sourcePath, entry);
17601
+ const targetRelative = path33.relative(managedDir, targetAbsolute);
17336
17602
  try {
17337
- fs33.lstatSync(linkPath);
17338
- fs33.rmSync(linkPath, { recursive: true, force: true });
17603
+ fs35.lstatSync(linkPath);
17604
+ fs35.rmSync(linkPath, { recursive: true, force: true });
17339
17605
  } catch {
17340
17606
  }
17341
- fs33.symlinkSync(targetRelative, linkPath);
17607
+ fs35.symlinkSync(targetRelative, linkPath);
17342
17608
  }
17343
- const managedEntries = fs33.readdirSync(managedDir);
17609
+ const managedEntries = fs35.readdirSync(managedDir);
17344
17610
  const baseEntrySet = new Set(baseEntries);
17345
17611
  for (const entry of managedEntries) {
17346
17612
  if (entry === "SKILL.md")
17347
17613
  continue;
17348
17614
  if (!baseEntrySet.has(entry)) {
17349
- const stalePath = path31.join(managedDir, entry);
17615
+ const stalePath = path33.join(managedDir, entry);
17350
17616
  try {
17351
- fs33.rmSync(stalePath, { recursive: true, force: true });
17617
+ fs35.rmSync(stalePath, { recursive: true, force: true });
17352
17618
  } catch {
17353
17619
  }
17354
17620
  }
@@ -17356,7 +17622,7 @@ function materializeMergedSkill(opts) {
17356
17622
  return managedDir;
17357
17623
  }
17358
17624
  function cleanMergedDir(claudeDir2) {
17359
- fs33.rmSync(path31.join(claudeDir2, ".olam-merged"), { recursive: true, force: true });
17625
+ fs35.rmSync(path33.join(claudeDir2, ".olam-merged"), { recursive: true, force: true });
17360
17626
  }
17361
17627
  var init_managed_merge = __esm({
17362
17628
  "../core/dist/skill-sync/managed-merge.js"() {
@@ -17454,8 +17720,8 @@ var init_prefix_rules = __esm({
17454
17720
  });
17455
17721
 
17456
17722
  // ../core/dist/skill-sync/prefix-deploy.js
17457
- import * as fs34 from "node:fs";
17458
- import * as path32 from "node:path";
17723
+ import * as fs36 from "node:fs";
17724
+ import * as path34 from "node:path";
17459
17725
  function buildSourcePrefixMap(sources) {
17460
17726
  const byId = /* @__PURE__ */ new Map();
17461
17727
  const scopeById = /* @__PURE__ */ new Map();
@@ -17509,8 +17775,8 @@ function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir2, dryRun) {
17509
17775
  continue;
17510
17776
  }
17511
17777
  if (artifact.kind === "skill") {
17512
- const skillMdPath = path32.join(artifact.sourcePath, "SKILL.md");
17513
- const content = fs34.readFileSync(skillMdPath);
17778
+ const skillMdPath = path34.join(artifact.sourcePath, "SKILL.md");
17779
+ const content = fs36.readFileSync(skillMdPath);
17514
17780
  const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
17515
17781
  const managedDir = materializeMergedSkill({
17516
17782
  sourceId: artifact.sourceId,
@@ -17522,7 +17788,7 @@ function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir2, dryRun) {
17522
17788
  artifact.sourcePath = managedDir;
17523
17789
  artifact.deployBasename = renamed;
17524
17790
  } else {
17525
- const content = artifact.resolvedContent !== void 0 ? artifact.resolvedContent : fs34.readFileSync(artifact.sourcePath);
17791
+ const content = artifact.resolvedContent !== void 0 ? artifact.resolvedContent : fs36.readFileSync(artifact.sourcePath);
17526
17792
  const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
17527
17793
  artifact.resolvedContent = rewritten;
17528
17794
  artifact.deployBasename = renamed;
@@ -17567,19 +17833,19 @@ var init_prefix_deploy = __esm({
17567
17833
  });
17568
17834
 
17569
17835
  // ../core/dist/skill-sync/resolve-source-config.js
17570
- import { readFileSync as readFileSync32, existsSync as existsSync37 } from "node:fs";
17571
- import { join as join36 } from "node:path";
17836
+ import { readFileSync as readFileSync33, existsSync as existsSync39 } from "node:fs";
17837
+ import { join as join38 } from "node:path";
17572
17838
  import { parse as parseYaml4 } from "yaml";
17573
17839
  function sourceConfigPath(clonePath) {
17574
- return join36(clonePath, "shared", "source-config.yaml");
17840
+ return join38(clonePath, "shared", "source-config.yaml");
17575
17841
  }
17576
17842
  function readSourceConfig(clonePath, sourceId) {
17577
- const path60 = sourceConfigPath(clonePath);
17578
- if (!existsSync37(path60))
17843
+ const path62 = sourceConfigPath(clonePath);
17844
+ if (!existsSync39(path62))
17579
17845
  return void 0;
17580
17846
  let raw;
17581
17847
  try {
17582
- raw = readFileSync32(path60, "utf-8");
17848
+ raw = readFileSync33(path62, "utf-8");
17583
17849
  } catch (err) {
17584
17850
  emitMalformedWarning(sourceId, `read failed: ${errToMsg(err)}`);
17585
17851
  return void 0;
@@ -17674,16 +17940,16 @@ var init_resolve_source_config = __esm({
17674
17940
  });
17675
17941
 
17676
17942
  // ../core/dist/skill-sync/engine.js
17677
- import * as fs35 from "node:fs";
17943
+ import * as fs37 from "node:fs";
17678
17944
  import * as os20 from "node:os";
17679
- import * as path33 from "node:path";
17945
+ import * as path35 from "node:path";
17680
17946
  function resolveAtlasUser(override) {
17681
17947
  if (override)
17682
17948
  return override;
17683
- const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] || path33.join(os20.homedir(), ".claude");
17684
- const f = path33.join(claudeDir2, ".atlas-user");
17685
- if (fs35.existsSync(f)) {
17686
- return fs35.readFileSync(f, "utf-8").trim() || void 0;
17949
+ const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] || path35.join(os20.homedir(), ".claude");
17950
+ const f = path35.join(claudeDir2, ".atlas-user");
17951
+ if (fs37.existsSync(f)) {
17952
+ return fs37.readFileSync(f, "utf-8").trim() || void 0;
17687
17953
  }
17688
17954
  return void 0;
17689
17955
  }
@@ -17695,7 +17961,7 @@ async function syncSkills(opts = {}) {
17695
17961
  const perSource = [];
17696
17962
  for (const source of sources) {
17697
17963
  const clonePath = skillSourceClonePath(source.id);
17698
- if (!fs35.existsSync(clonePath))
17964
+ if (!fs37.existsSync(clonePath))
17699
17965
  continue;
17700
17966
  const { artifacts, subscription } = await withFileLock(clonePath, () => {
17701
17967
  const pinRef = projectOverride?.override.pin?.[source.id];
@@ -17735,7 +18001,7 @@ async function syncSkills(opts = {}) {
17735
18001
  const overlayArtifacts = memberOverlaysEnabled ? projectFilteredArtifacts.filter((a) => a.kind === "overlay") : [];
17736
18002
  const effectiveSources = sources.map((s) => {
17737
18003
  const clonePath = skillSourceClonePath(s.id);
17738
- const sourceConfig = fs35.existsSync(clonePath) ? readSourceConfig(clonePath, s.id) : void 0;
18004
+ const sourceConfig = fs37.existsSync(clonePath) ? readSourceConfig(clonePath, s.id) : void 0;
17739
18005
  const eff = resolveEffectivePrefix(s, sourceConfig);
17740
18006
  const entry = {
17741
18007
  id: s.id,
@@ -17841,13 +18107,13 @@ async function syncSkills(opts = {}) {
17841
18107
  let baseContent;
17842
18108
  let basePath;
17843
18109
  if (overlay.targetKind === "skill") {
17844
- basePath = path33.join(base.sourcePath, "SKILL.md");
17845
- baseContent = fs35.readFileSync(basePath, "utf-8");
18110
+ basePath = path35.join(base.sourcePath, "SKILL.md");
18111
+ baseContent = fs37.readFileSync(basePath, "utf-8");
17846
18112
  } else {
17847
18113
  basePath = base.sourcePath;
17848
- baseContent = fs35.readFileSync(basePath, "utf-8");
18114
+ baseContent = fs37.readFileSync(basePath, "utf-8");
17849
18115
  }
17850
- const overlayContent = fs35.readFileSync(overlay.sourcePath, "utf-8");
18116
+ const overlayContent = fs37.readFileSync(overlay.sourcePath, "utf-8");
17851
18117
  const label = `${overlay.sourceId}/${overlay.deployBasename}`;
17852
18118
  const mergeResult = mergeMarkdown(baseContent, overlayContent, label, basePath, overlay.sourcePath);
17853
18119
  if ("error" in mergeResult) {
@@ -17908,7 +18174,7 @@ async function syncSkills(opts = {}) {
17908
18174
  summary.collisions = detectCollisions(baseArtifacts).collisions;
17909
18175
  return summary;
17910
18176
  }
17911
- const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] || path33.join(os20.homedir(), ".claude");
18177
+ const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] || path35.join(os20.homedir(), ".claude");
17912
18178
  const overlayReferences = scanOverlayReferences(claudeDirPath, SHIM_TARGETS.map((t) => t.basename));
17913
18179
  summary.deploy = deployArtifacts(baseArtifacts, {
17914
18180
  installedOlamVersion,
@@ -17944,19 +18210,19 @@ async function injectMetaHooksIntoSettings(opts) {
17944
18210
  const result = await withSettingsJsonLock(() => {
17945
18211
  let currentSettings = {};
17946
18212
  let settingsExisted = false;
17947
- if (fs35.existsSync(settingsFile)) {
18213
+ if (fs37.existsSync(settingsFile)) {
17948
18214
  settingsExisted = true;
17949
18215
  try {
17950
- const raw = fs35.readFileSync(settingsFile, "utf-8");
18216
+ const raw = fs37.readFileSync(settingsFile, "utf-8");
17951
18217
  currentSettings = raw.trim() ? JSON.parse(raw) : {};
17952
18218
  } catch {
17953
18219
  try {
17954
- const raw = fs35.readFileSync(settingsFile);
17955
- const bakDir = path33.join(path33.dirname(settingsFile), ".malformed-backups");
17956
- fs35.mkdirSync(bakDir, { recursive: true });
18220
+ const raw = fs37.readFileSync(settingsFile);
18221
+ const bakDir = path35.join(path35.dirname(settingsFile), ".malformed-backups");
18222
+ fs37.mkdirSync(bakDir, { recursive: true });
17957
18223
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
17958
- const bakFile = path33.join(bakDir, `settings.json.malformed.${stamp}.bak`);
17959
- fs35.writeFileSync(bakFile, raw, { mode: 384 });
18224
+ const bakFile = path35.join(bakDir, `settings.json.malformed.${stamp}.bak`);
18225
+ fs37.writeFileSync(bakFile, raw, { mode: 384 });
17960
18226
  snapshotError = `settings.json was malformed; original bytes preserved at ${bakFile}`;
17961
18227
  } catch (bakErr) {
17962
18228
  snapshotError = `settings.json malformed AND .bak write failed: ${bakErr instanceof Error ? bakErr.message : String(bakErr)}`;
@@ -17996,10 +18262,10 @@ async function injectMetaHooksIntoSettings(opts) {
17996
18262
  } catch {
17997
18263
  }
17998
18264
  }
17999
- fs35.mkdirSync(path33.dirname(settingsFile), { recursive: true });
18265
+ fs37.mkdirSync(path35.dirname(settingsFile), { recursive: true });
18000
18266
  const tmpPath = `${settingsFile}.tmp-${process.pid}-${Date.now()}`;
18001
- fs35.writeFileSync(tmpPath, JSON.stringify(inject.nextSettings, null, 2) + "\n");
18002
- fs35.renameSync(tmpPath, settingsFile);
18267
+ fs37.writeFileSync(tmpPath, JSON.stringify(inject.nextSettings, null, 2) + "\n");
18268
+ fs37.renameSync(tmpPath, settingsFile);
18003
18269
  return inject;
18004
18270
  }, { reason: `syncSkills meta-hook injection (mode=${mode})` });
18005
18271
  let scriptDeploy;
@@ -18007,7 +18273,7 @@ async function injectMetaHooksIntoSettings(opts) {
18007
18273
  if (modelRouterTargeted) {
18008
18274
  try {
18009
18275
  scriptDeploy = deployModelRouterScript({
18010
- targetDir: path33.join(claudeDir(), "hooks")
18276
+ targetDir: path35.join(claudeDir(), "hooks")
18011
18277
  });
18012
18278
  } catch (err) {
18013
18279
  scriptDeploy = {
@@ -18058,19 +18324,19 @@ var init_engine = __esm({
18058
18324
  });
18059
18325
 
18060
18326
  // ../core/dist/skill-sync/shadow-backup-manager.js
18061
- import * as fs36 from "node:fs";
18062
- import * as path34 from "node:path";
18327
+ import * as fs38 from "node:fs";
18328
+ import * as path36 from "node:path";
18063
18329
  function listShadowBackups(opts = {}) {
18064
18330
  const claude = opts.claudeDirOverride ?? claudeDir();
18065
18331
  const now = opts.now ?? Date.now();
18066
18332
  const out = [];
18067
18333
  for (const bucket of SHADOW_BACKUP_BUCKETS) {
18068
- const bucketDir = path34.join(claude, bucket);
18069
- if (!fs36.existsSync(bucketDir))
18334
+ const bucketDir = path36.join(claude, bucket);
18335
+ if (!fs38.existsSync(bucketDir))
18070
18336
  continue;
18071
18337
  let entries;
18072
18338
  try {
18073
- entries = fs36.readdirSync(bucketDir);
18339
+ entries = fs38.readdirSync(bucketDir);
18074
18340
  } catch {
18075
18341
  continue;
18076
18342
  }
@@ -18081,11 +18347,11 @@ function listShadowBackups(opts = {}) {
18081
18347
  const epochSeconds = Number.parseInt(match[1], 10);
18082
18348
  if (!Number.isFinite(epochSeconds) || epochSeconds < 0)
18083
18349
  continue;
18084
- const full = path34.join(bucketDir, name);
18350
+ const full = path36.join(bucketDir, name);
18085
18351
  let sizeBytes = 0;
18086
18352
  let isDir = false;
18087
18353
  try {
18088
- const st = fs36.statSync(full);
18354
+ const st = fs38.statSync(full);
18089
18355
  isDir = st.isDirectory();
18090
18356
  if (!isDir)
18091
18357
  sizeBytes = st.size;
@@ -18098,7 +18364,7 @@ function listShadowBackups(opts = {}) {
18098
18364
  bucket,
18099
18365
  basename: name,
18100
18366
  originalBasename,
18101
- originalPath: path34.join(bucketDir, originalBasename),
18367
+ originalPath: path36.join(bucketDir, originalBasename),
18102
18368
  epochSeconds,
18103
18369
  ageMs: now - epochSeconds * 1e3,
18104
18370
  sizeBytes,
@@ -18143,9 +18409,9 @@ function pruneShadowBackups(opts) {
18143
18409
  if (!opts.dryRun) {
18144
18410
  try {
18145
18411
  if (b.isDir) {
18146
- fs36.rmSync(b.path, { recursive: true, force: true });
18412
+ fs38.rmSync(b.path, { recursive: true, force: true });
18147
18413
  } else {
18148
- fs36.unlinkSync(b.path);
18414
+ fs38.unlinkSync(b.path);
18149
18415
  }
18150
18416
  } catch {
18151
18417
  skipped.push(b);
@@ -18157,29 +18423,29 @@ function pruneShadowBackups(opts) {
18157
18423
  return { deleted, skipped };
18158
18424
  }
18159
18425
  function restoreShadowBackup(opts) {
18160
- const abs = path34.resolve(opts.backupPath);
18161
- if (!fs36.existsSync(abs)) {
18426
+ const abs = path36.resolve(opts.backupPath);
18427
+ if (!fs38.existsSync(abs)) {
18162
18428
  throw new Error(`backup file not found: ${abs}`);
18163
18429
  }
18164
- const basename6 = path34.basename(abs);
18430
+ const basename6 = path36.basename(abs);
18165
18431
  const match = SHADOW_BACKUP_SUFFIX_RE.exec(basename6);
18166
18432
  if (!match) {
18167
18433
  throw new Error(`not a shadow-backup file (basename "${basename6}" does not match \`.shadow-backup-<epoch>\`): ${abs}`);
18168
18434
  }
18169
18435
  const originalBasename = basename6.slice(0, basename6.length - match[0].length);
18170
- const originalPath = path34.join(path34.dirname(abs), originalBasename);
18171
- if (fs36.existsSync(originalPath) && !opts.force) {
18436
+ const originalPath = path36.join(path36.dirname(abs), originalBasename);
18437
+ if (fs38.existsSync(originalPath) && !opts.force) {
18172
18438
  throw new Error(`original path already occupied: ${originalPath}. Move/rename it first OR re-run with --force.`);
18173
18439
  }
18174
- if (opts.force && fs36.existsSync(originalPath)) {
18175
- const existingStat = fs36.statSync(originalPath);
18440
+ if (opts.force && fs38.existsSync(originalPath)) {
18441
+ const existingStat = fs38.statSync(originalPath);
18176
18442
  if (existingStat.isDirectory()) {
18177
- fs36.rmSync(originalPath, { recursive: true, force: true });
18443
+ fs38.rmSync(originalPath, { recursive: true, force: true });
18178
18444
  } else {
18179
- fs36.unlinkSync(originalPath);
18445
+ fs38.unlinkSync(originalPath);
18180
18446
  }
18181
18447
  }
18182
- fs36.renameSync(abs, originalPath);
18448
+ fs38.renameSync(abs, originalPath);
18183
18449
  return { restoredTo: originalPath };
18184
18450
  }
18185
18451
  var SHADOW_BACKUP_BUCKETS, SHADOW_BACKUP_SUFFIX_RE;
@@ -18193,14 +18459,14 @@ var init_shadow_backup_manager = __esm({
18193
18459
  });
18194
18460
 
18195
18461
  // ../core/dist/skill-sources/doctor-checks.js
18196
- import * as fs37 from "node:fs";
18197
- import * as path35 from "node:path";
18462
+ import * as fs39 from "node:fs";
18463
+ import * as path37 from "node:path";
18198
18464
  import * as os21 from "node:os";
18199
18465
  function claudeDirInternal3() {
18200
18466
  const override = process.env["OLAM_CLAUDE_DIR"];
18201
18467
  if (override && override.length > 0)
18202
18468
  return override;
18203
- return path35.join(os21.homedir(), ".claude");
18469
+ return path37.join(os21.homedir(), ".claude");
18204
18470
  }
18205
18471
  function checkStateFileParse() {
18206
18472
  const filePath = globalConfigPath();
@@ -18209,11 +18475,11 @@ function checkStateFileParse() {
18209
18475
  healthy: true,
18210
18476
  description: `~/.olam state file (${filePath})`
18211
18477
  };
18212
- if (!fs37.existsSync(filePath)) {
18478
+ if (!fs39.existsSync(filePath)) {
18213
18479
  result.details = ["(file does not yet exist \u2014 will be created on first write)"];
18214
18480
  return result;
18215
18481
  }
18216
- const raw = fs37.readFileSync(filePath, "utf-8");
18482
+ const raw = fs39.readFileSync(filePath, "utf-8");
18217
18483
  let parsed;
18218
18484
  try {
18219
18485
  parsed = JSON.parse(raw);
@@ -18223,8 +18489,8 @@ function checkStateFileParse() {
18223
18489
  result.details = [err instanceof Error ? err.message : String(err)];
18224
18490
  result.repair = () => {
18225
18491
  const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
18226
- fs37.renameSync(filePath, aside);
18227
- fs37.writeFileSync(filePath, JSON.stringify({ schemaVersion: 1, repos: [], runbooks: [], skillSources: [] }, null, 2));
18492
+ fs39.renameSync(filePath, aside);
18493
+ fs39.writeFileSync(filePath, JSON.stringify({ schemaVersion: 1, repos: [], runbooks: [], skillSources: [] }, null, 2));
18228
18494
  };
18229
18495
  return result;
18230
18496
  }
@@ -18233,18 +18499,20 @@ function checkStateFileParse() {
18233
18499
  result.healthy = false;
18234
18500
  result.issue = "state file does not match GlobalConfigSchema";
18235
18501
  result.details = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
18502
+ const salvaged = quarantineGlobalConfig(parsed);
18503
+ const droppedCount = salvaged?.drops.length ?? 0;
18504
+ if (salvaged !== null) {
18505
+ result.details.push(`auto-fix will keep ${salvaged.value.skillSources.length} skill-source(s), ${salvaged.value.repos.length} repo(s), ${salvaged.value.runbooks.length} runbook(s); dropping ${droppedCount} invalid entr${droppedCount === 1 ? "y" : "ies"}.`);
18506
+ } else {
18507
+ result.details.push("auto-fix cannot salvage any entries (top-level corruption) \u2014 will reset to empty.");
18508
+ }
18236
18509
  result.repair = () => {
18237
18510
  const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
18238
- fs37.copyFileSync(filePath, aside);
18511
+ fs39.copyFileSync(filePath, aside);
18239
18512
  const base = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
18240
- const next = {
18241
- ...base,
18242
- schemaVersion: 1,
18243
- repos: [],
18244
- runbooks: [],
18245
- skillSources: []
18246
- };
18247
- fs37.writeFileSync(filePath, JSON.stringify(next, null, 2));
18513
+ const recovered = quarantineGlobalConfig(parsed);
18514
+ const next = recovered !== null ? { ...base, ...recovered.value } : { ...base, schemaVersion: 1, repos: [], runbooks: [], skillSources: [] };
18515
+ fs39.writeFileSync(filePath, JSON.stringify(next, null, 2));
18248
18516
  };
18249
18517
  return result;
18250
18518
  }
@@ -18255,16 +18523,16 @@ function checkDanglingSymlinks() {
18255
18523
  const buckets = ["commands", "agents", "skills", "scripts", "rules"];
18256
18524
  const dangling = [];
18257
18525
  for (const bucket of buckets) {
18258
- const dir = path35.join(claude, bucket);
18259
- if (!fs37.existsSync(dir))
18526
+ const dir = path37.join(claude, bucket);
18527
+ if (!fs39.existsSync(dir))
18260
18528
  continue;
18261
- for (const name of fs37.readdirSync(dir)) {
18262
- const linkPath = path35.join(dir, name);
18529
+ for (const name of fs39.readdirSync(dir)) {
18530
+ const linkPath = path37.join(dir, name);
18263
18531
  try {
18264
- const lst = fs37.lstatSync(linkPath);
18532
+ const lst = fs39.lstatSync(linkPath);
18265
18533
  if (!lst.isSymbolicLink())
18266
18534
  continue;
18267
- if (!fs37.existsSync(linkPath)) {
18535
+ if (!fs39.existsSync(linkPath)) {
18268
18536
  dangling.push(linkPath);
18269
18537
  }
18270
18538
  } catch {
@@ -18282,7 +18550,7 @@ function checkDanglingSymlinks() {
18282
18550
  result.repair = () => {
18283
18551
  for (const p of dangling) {
18284
18552
  try {
18285
- fs37.unlinkSync(p);
18553
+ fs39.unlinkSync(p);
18286
18554
  } catch {
18287
18555
  }
18288
18556
  }
@@ -18297,19 +18565,19 @@ function checkOrphanedSnapshots() {
18297
18565
  healthy: true,
18298
18566
  description: `orphaned migration snapshots under ${dir}`
18299
18567
  };
18300
- if (!fs37.existsSync(dir)) {
18568
+ if (!fs39.existsSync(dir)) {
18301
18569
  return result;
18302
18570
  }
18303
18571
  const orphans = [];
18304
- for (const name of fs37.readdirSync(dir)) {
18572
+ for (const name of fs39.readdirSync(dir)) {
18305
18573
  if (!name.endsWith(".json"))
18306
18574
  continue;
18307
- const full = path35.join(dir, name);
18575
+ const full = path37.join(dir, name);
18308
18576
  try {
18309
- const stat2 = fs37.statSync(full);
18577
+ const stat2 = fs39.statSync(full);
18310
18578
  if (!stat2.isFile())
18311
18579
  continue;
18312
- const raw = fs37.readFileSync(full, "utf-8");
18580
+ const raw = fs39.readFileSync(full, "utf-8");
18313
18581
  let parsed;
18314
18582
  try {
18315
18583
  parsed = JSON.parse(raw);
@@ -18334,7 +18602,7 @@ function checkOrphanedSnapshots() {
18334
18602
  result.repair = () => {
18335
18603
  for (const o of orphans) {
18336
18604
  try {
18337
- fs37.unlinkSync(o.path);
18605
+ fs39.unlinkSync(o.path);
18338
18606
  } catch {
18339
18607
  }
18340
18608
  }
@@ -18349,12 +18617,12 @@ function checkSentinelDrift() {
18349
18617
  healthy: true,
18350
18618
  description: `olam-skills sentinel block in ${filePath}`
18351
18619
  };
18352
- if (!fs37.existsSync(filePath)) {
18620
+ if (!fs39.existsSync(filePath)) {
18353
18621
  return result;
18354
18622
  }
18355
18623
  let parsed;
18356
18624
  try {
18357
- parsed = JSON.parse(fs37.readFileSync(filePath, "utf-8"));
18625
+ parsed = JSON.parse(fs39.readFileSync(filePath, "utf-8"));
18358
18626
  } catch {
18359
18627
  return result;
18360
18628
  }
@@ -18395,7 +18663,7 @@ function checkSentinelDrift() {
18395
18663
  backupSettings();
18396
18664
  } catch {
18397
18665
  }
18398
- const next = JSON.parse(fs37.readFileSync(filePath, "utf-8"));
18666
+ const next = JSON.parse(fs39.readFileSync(filePath, "utf-8"));
18399
18667
  if (!next.hooks)
18400
18668
  return;
18401
18669
  for (const stage of Object.keys(next.hooks)) {
@@ -18418,7 +18686,7 @@ function checkSentinelDrift() {
18418
18686
  return bad === void 0;
18419
18687
  });
18420
18688
  }
18421
- fs37.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
18689
+ fs39.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
18422
18690
  };
18423
18691
  }
18424
18692
  return result;
@@ -18442,8 +18710,8 @@ function checkMemberNameMissing() {
18442
18710
  return result;
18443
18711
  }
18444
18712
  const claudeDir2 = claudeDirInternal3();
18445
- const atlasUserPath = path35.join(claudeDir2, ".atlas-user");
18446
- const value = fs37.existsSync(atlasUserPath) ? fs37.readFileSync(atlasUserPath, "utf-8").trim() : "";
18713
+ const atlasUserPath = path37.join(claudeDir2, ".atlas-user");
18714
+ const value = fs39.existsSync(atlasUserPath) ? fs39.readFileSync(atlasUserPath, "utf-8").trim() : "";
18447
18715
  if (value.length > 0) {
18448
18716
  result.details = [`atlas-user: ${value}`];
18449
18717
  return result;
@@ -18451,10 +18719,10 @@ function checkMemberNameMissing() {
18451
18719
  result.healthy = false;
18452
18720
  result.issue = "atlas-toolbox source registered but ~/.claude/.atlas-user not set";
18453
18721
  const clonePath = skillSourceClonePath(atlasSource.id);
18454
- const membersDir = path35.join(clonePath, "members");
18455
- const existing = fs37.existsSync(membersDir) ? fs37.readdirSync(membersDir).filter((e) => {
18722
+ const membersDir = path37.join(clonePath, "members");
18723
+ const existing = fs39.existsSync(membersDir) ? fs39.readdirSync(membersDir).filter((e) => {
18456
18724
  try {
18457
- return fs37.statSync(path35.join(membersDir, e)).isDirectory();
18725
+ return fs39.statSync(path37.join(membersDir, e)).isDirectory();
18458
18726
  } catch {
18459
18727
  return false;
18460
18728
  }
@@ -18468,8 +18736,8 @@ function checkMemberNameMissing() {
18468
18736
  }
18469
18737
  function checkMemberOverlayDrift() {
18470
18738
  const claudeDir2 = claudeDirInternal3();
18471
- const atlasUserPath = path35.join(claudeDir2, ".atlas-user");
18472
- const atlasUser = fs37.existsSync(atlasUserPath) ? fs37.readFileSync(atlasUserPath, "utf-8").trim() : "";
18739
+ const atlasUserPath = path37.join(claudeDir2, ".atlas-user");
18740
+ const atlasUser = fs39.existsSync(atlasUserPath) ? fs39.readFileSync(atlasUserPath, "utf-8").trim() : "";
18473
18741
  if (atlasUser.length === 0) {
18474
18742
  return [];
18475
18743
  }
@@ -18485,26 +18753,26 @@ function checkMemberOverlayDrift() {
18485
18753
  const clonePath = skillSourceClonePath(atlasSource.id);
18486
18754
  const results = [];
18487
18755
  for (const kind of ["skills", "agents"]) {
18488
- const localRoot = path35.join(claudeDir2, `${kind}.overrides`);
18489
- if (!fs37.existsSync(localRoot))
18756
+ const localRoot = path37.join(claudeDir2, `${kind}.overrides`);
18757
+ if (!fs39.existsSync(localRoot))
18490
18758
  continue;
18491
18759
  let entries;
18492
18760
  try {
18493
- entries = fs37.readdirSync(localRoot);
18761
+ entries = fs39.readdirSync(localRoot);
18494
18762
  } catch {
18495
18763
  continue;
18496
18764
  }
18497
18765
  for (const entry of entries) {
18498
- const localFile = path35.join(localRoot, entry);
18766
+ const localFile = path37.join(localRoot, entry);
18499
18767
  let stat2;
18500
18768
  try {
18501
- stat2 = fs37.statSync(localFile);
18769
+ stat2 = fs39.statSync(localFile);
18502
18770
  } catch {
18503
18771
  continue;
18504
18772
  }
18505
18773
  if (!stat2.isFile())
18506
18774
  continue;
18507
- const cloneFile = path35.join(clonePath, "members", atlasUser, `${kind}.overrides`, entry);
18775
+ const cloneFile = path37.join(clonePath, "members", atlasUser, `${kind}.overrides`, entry);
18508
18776
  const localSha = sha256OfPath(localFile);
18509
18777
  const cloneSha = sha256OfPath(cloneFile);
18510
18778
  if (localSha === cloneSha) {
@@ -18559,16 +18827,16 @@ var init_doctor_checks = __esm({
18559
18827
  });
18560
18828
 
18561
18829
  // ../core/dist/skill-sync/detect-pull-deploy-drift.js
18562
- import * as fs38 from "node:fs";
18563
- import * as path36 from "node:path";
18830
+ import * as fs40 from "node:fs";
18831
+ import * as path38 from "node:path";
18564
18832
  function deployedSymlinkBasenames(bucketDir) {
18565
18833
  const result = /* @__PURE__ */ new Set();
18566
- if (!fs38.existsSync(bucketDir))
18834
+ if (!fs40.existsSync(bucketDir))
18567
18835
  return result;
18568
- for (const name of fs38.readdirSync(bucketDir)) {
18569
- const p = path36.join(bucketDir, name);
18836
+ for (const name of fs40.readdirSync(bucketDir)) {
18837
+ const p = path38.join(bucketDir, name);
18570
18838
  try {
18571
- if (fs38.lstatSync(p).isSymbolicLink()) {
18839
+ if (fs40.lstatSync(p).isSymbolicLink()) {
18572
18840
  result.add(name);
18573
18841
  }
18574
18842
  } catch {
@@ -18579,7 +18847,7 @@ function deployedSymlinkBasenames(bucketDir) {
18579
18847
  function detectPullDeployDrift(opts) {
18580
18848
  const { clonePath, sourceId, atlasUser } = opts;
18581
18849
  const { artifacts } = resolveSourceArtifacts({ sourceId, clonePath, atlasUser });
18582
- const sourceConfig = fs38.existsSync(clonePath) ? readSourceConfig(clonePath, sourceId) : void 0;
18850
+ const sourceConfig = fs40.existsSync(clonePath) ? readSourceConfig(clonePath, sourceId) : void 0;
18583
18851
  const eff = resolveEffectivePrefix(opts.operatorSource ?? {}, sourceConfig);
18584
18852
  const prefixEntry = { id: sourceId };
18585
18853
  if (eff.prefix !== void 0)
@@ -18616,7 +18884,7 @@ function detectPullDeployDrift(opts) {
18616
18884
  let total = 0;
18617
18885
  for (const kind of Object.keys(KIND_TO_BUCKET)) {
18618
18886
  const bucket = KIND_TO_BUCKET[kind];
18619
- const bucketDir = path36.join(claude, bucket);
18887
+ const bucketDir = path38.join(claude, bucket);
18620
18888
  const deployed = deployedSymlinkBasenames(bucketDir);
18621
18889
  const cloneBasenames = cloneByKind[kind];
18622
18890
  const added = [];
@@ -18667,11 +18935,13 @@ __export(skill_sources_exports, {
18667
18935
  PROJECT_OVERRIDE_RELATIVE_PATH: () => PROJECT_OVERRIDE_RELATIVE_PATH,
18668
18936
  SKILL_SOURCES_AUDIT_LOG_FILENAME: () => SKILL_SOURCES_AUDIT_LOG_FILENAME,
18669
18937
  SKILL_SOURCE_ID_LENGTH: () => SKILL_SOURCE_ID_LENGTH,
18938
+ SOURCE_SIDECAR_FILENAME: () => SOURCE_SIDECAR_FILENAME,
18670
18939
  SkillOverrideSchema: () => SkillOverrideSchema,
18671
18940
  SkillSourceGitError: () => SkillSourceGitError,
18672
18941
  SkillSourceSchema: () => SkillSourceSchema,
18673
18942
  SourceConfigSchema: () => SourceConfigSchema,
18674
18943
  SourceConfigSnapshotSchema: () => SourceConfigSnapshotSchema,
18944
+ SourceSidecarSchema: () => SourceSidecarSchema,
18675
18945
  TrustActionSchema: () => TrustActionSchema,
18676
18946
  TrustAuditEntrySchema: () => TrustAuditEntrySchema,
18677
18947
  TrustMethodSchema: () => TrustMethodSchema,
@@ -18713,7 +18983,10 @@ __export(skill_sources_exports, {
18713
18983
  readLatestMigrationSnapshot: () => readLatestMigrationSnapshot,
18714
18984
  readMigrationSnapshotFromPath: () => readMigrationSnapshotFromPath,
18715
18985
  readSourceConfig: () => readSourceConfig,
18986
+ readSourceSidecar: () => readSourceSidecar,
18716
18987
  readTrustAuditLog: () => readTrustAuditLog,
18988
+ reconcileIfRegistryEmpty: () => reconcileIfRegistryEmpty,
18989
+ reconcileSkillSources: () => reconcileSkillSources,
18717
18990
  redactUrl: () => redactUrl2,
18718
18991
  removeSkillSource: () => removeSkillSource,
18719
18992
  removeSkillSourceClone: () => removeSkillSourceClone,
@@ -18732,11 +19005,13 @@ __export(skill_sources_exports, {
18732
19005
  skillsHookSettingsPathFor: () => settingsPathFor,
18733
19006
  sourceConfigPath: () => sourceConfigPath,
18734
19007
  sourceConfigsEqual: () => sourceConfigsEqual,
19008
+ sourceSidecarPath: () => sourceSidecarPath,
18735
19009
  syncSkills: () => syncSkills,
18736
19010
  uninstallSkillsHookFromFile: () => uninstallSkillsHookFromFile,
18737
19011
  updateSkillSource: () => updateSkillSource,
18738
19012
  withFileLock: () => withFileLock,
18739
- writeMigrationSnapshot: () => writeMigrationSnapshot
19013
+ writeMigrationSnapshot: () => writeMigrationSnapshot,
19014
+ writeSourceSidecar: () => writeSourceSidecar
18740
19015
  });
18741
19016
  var init_skill_sources = __esm({
18742
19017
  "../core/dist/skill-sources/index.js"() {
@@ -18744,6 +19019,8 @@ var init_skill_sources = __esm({
18744
19019
  init_schema3();
18745
19020
  init_store3();
18746
19021
  init_clone();
19022
+ init_source_file();
19023
+ init_reconcile();
18747
19024
  init_hook_template();
18748
19025
  init_hook_install();
18749
19026
  init_migration_snapshot();
@@ -19549,10 +19826,10 @@ function mergeDefs(...defs) {
19549
19826
  function cloneDef(schema) {
19550
19827
  return mergeDefs(schema._zod.def);
19551
19828
  }
19552
- function getElementAtPath(obj, path60) {
19553
- if (!path60)
19829
+ function getElementAtPath(obj, path62) {
19830
+ if (!path62)
19554
19831
  return obj;
19555
- return path60.reduce((acc, key) => acc?.[key], obj);
19832
+ return path62.reduce((acc, key) => acc?.[key], obj);
19556
19833
  }
19557
19834
  function promiseAllObject(promisesObj) {
19558
19835
  const keys = Object.keys(promisesObj);
@@ -19961,11 +20238,11 @@ function explicitlyAborted(x, startIndex = 0) {
19961
20238
  }
19962
20239
  return false;
19963
20240
  }
19964
- function prefixIssues(path60, issues) {
20241
+ function prefixIssues(path62, issues) {
19965
20242
  return issues.map((iss) => {
19966
20243
  var _a3;
19967
20244
  (_a3 = iss).path ?? (_a3.path = []);
19968
- iss.path.unshift(path60);
20245
+ iss.path.unshift(path62);
19969
20246
  return iss;
19970
20247
  });
19971
20248
  }
@@ -20112,16 +20389,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
20112
20389
  }
20113
20390
  function formatError(error51, mapper = (issue2) => issue2.message) {
20114
20391
  const fieldErrors = { _errors: [] };
20115
- const processError = (error52, path60 = []) => {
20392
+ const processError = (error52, path62 = []) => {
20116
20393
  for (const issue2 of error52.issues) {
20117
20394
  if (issue2.code === "invalid_union" && issue2.errors.length) {
20118
- issue2.errors.map((issues) => processError({ issues }, [...path60, ...issue2.path]));
20395
+ issue2.errors.map((issues) => processError({ issues }, [...path62, ...issue2.path]));
20119
20396
  } else if (issue2.code === "invalid_key") {
20120
- processError({ issues: issue2.issues }, [...path60, ...issue2.path]);
20397
+ processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
20121
20398
  } else if (issue2.code === "invalid_element") {
20122
- processError({ issues: issue2.issues }, [...path60, ...issue2.path]);
20399
+ processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
20123
20400
  } else {
20124
- const fullpath = [...path60, ...issue2.path];
20401
+ const fullpath = [...path62, ...issue2.path];
20125
20402
  if (fullpath.length === 0) {
20126
20403
  fieldErrors._errors.push(mapper(issue2));
20127
20404
  } else {
@@ -20148,17 +20425,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
20148
20425
  }
20149
20426
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
20150
20427
  const result = { errors: [] };
20151
- const processError = (error52, path60 = []) => {
20428
+ const processError = (error52, path62 = []) => {
20152
20429
  var _a3, _b;
20153
20430
  for (const issue2 of error52.issues) {
20154
20431
  if (issue2.code === "invalid_union" && issue2.errors.length) {
20155
- issue2.errors.map((issues) => processError({ issues }, [...path60, ...issue2.path]));
20432
+ issue2.errors.map((issues) => processError({ issues }, [...path62, ...issue2.path]));
20156
20433
  } else if (issue2.code === "invalid_key") {
20157
- processError({ issues: issue2.issues }, [...path60, ...issue2.path]);
20434
+ processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
20158
20435
  } else if (issue2.code === "invalid_element") {
20159
- processError({ issues: issue2.issues }, [...path60, ...issue2.path]);
20436
+ processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
20160
20437
  } else {
20161
- const fullpath = [...path60, ...issue2.path];
20438
+ const fullpath = [...path62, ...issue2.path];
20162
20439
  if (fullpath.length === 0) {
20163
20440
  result.errors.push(mapper(issue2));
20164
20441
  continue;
@@ -20190,8 +20467,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
20190
20467
  }
20191
20468
  function toDotPath(_path) {
20192
20469
  const segs = [];
20193
- const path60 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
20194
- for (const seg of path60) {
20470
+ const path62 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
20471
+ for (const seg of path62) {
20195
20472
  if (typeof seg === "number")
20196
20473
  segs.push(`[${seg}]`);
20197
20474
  else if (typeof seg === "symbol")
@@ -32883,13 +33160,13 @@ function resolveRef(ref, ctx) {
32883
33160
  if (!ref.startsWith("#")) {
32884
33161
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
32885
33162
  }
32886
- const path60 = ref.slice(1).split("/").filter(Boolean);
32887
- if (path60.length === 0) {
33163
+ const path62 = ref.slice(1).split("/").filter(Boolean);
33164
+ if (path62.length === 0) {
32888
33165
  return ctx.rootSchema;
32889
33166
  }
32890
33167
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
32891
- if (path60[0] === defsKey) {
32892
- const key = path60[1];
33168
+ if (path62[0] === defsKey) {
33169
+ const key = path62[1];
32893
33170
  if (!key || !ctx.defs[key]) {
32894
33171
  throw new Error(`Reference not found: ${ref}`);
32895
33172
  }
@@ -39389,8 +39666,8 @@ var initSkill = defineSkill({
39389
39666
  // ../mcp-server/src/lib/validated-tool.ts
39390
39667
  function formatIssues(issues) {
39391
39668
  return issues.map((issue2) => {
39392
- const path60 = issue2.path.length > 0 ? issue2.path.join(".") : "<root>";
39393
- return `${path60}: ${issue2.message}`;
39669
+ const path62 = issue2.path.length > 0 ? issue2.path.join(".") : "<root>";
39670
+ return `${path62}: ${issue2.message}`;
39394
39671
  }).join("; ");
39395
39672
  }
39396
39673
  function validatedTool(server, skill, name, handler) {
@@ -39741,8 +40018,8 @@ var AuthClient = class {
39741
40018
  throw new Error(`failed to report rate-limit for ${accountId} (HTTP ${res.status})`);
39742
40019
  }
39743
40020
  }
39744
- async request(method, path60, body, attempt = 0) {
39745
- const url3 = `${this.baseUrl}${path60}`;
40021
+ async request(method, path62, body, attempt = 0) {
40022
+ const url3 = `${this.baseUrl}${path62}`;
39746
40023
  const controller = new AbortController();
39747
40024
  const timer = setTimeout(() => controller.abort(), this.timeoutMs);
39748
40025
  const headers = {};
@@ -39760,7 +40037,7 @@ var AuthClient = class {
39760
40037
  } catch (err) {
39761
40038
  if (attempt < RETRY_COUNT && isTransient(err)) {
39762
40039
  await sleep(RETRY_BACKOFF_MS * (attempt + 1));
39763
- return this.request(method, path60, body, attempt + 1);
40040
+ return this.request(method, path62, body, attempt + 1);
39764
40041
  }
39765
40042
  throw err;
39766
40043
  } finally {
@@ -40759,12 +41036,12 @@ function register3(server, _ctx, _initError) {
40759
41036
  registry2.close();
40760
41037
  }
40761
41038
  try {
40762
- const { default: fs60 } = await import("node:fs");
41039
+ const { default: fs62 } = await import("node:fs");
40763
41040
  const { default: os36 } = await import("node:os");
40764
- const { default: path60 } = await import("node:path");
40765
- const tokenPath = path60.join(os36.homedir(), ".olam", "host-cp.token");
40766
- if (fs60.existsSync(tokenPath)) {
40767
- const token = fs60.readFileSync(tokenPath, "utf-8").trim();
41041
+ const { default: path62 } = await import("node:path");
41042
+ const tokenPath = path62.join(os36.homedir(), ".olam", "host-cp.token");
41043
+ if (fs62.existsSync(tokenPath)) {
41044
+ const token = fs62.readFileSync(tokenPath, "utf-8").trim();
40768
41045
  await fetch("http://127.0.0.1:19000/api/admin/world-pr", {
40769
41046
  method: "POST",
40770
41047
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
@@ -41069,10 +41346,10 @@ function extractMcpConfig(claudeJsonPath) {
41069
41346
  }
41070
41347
  return { mcpServers, secrets };
41071
41348
  }
41072
- function readOptional(path60) {
41073
- if (!existsSync7(path60)) return null;
41349
+ function readOptional(path62) {
41350
+ if (!existsSync7(path62)) return null;
41074
41351
  try {
41075
- return readFileSync5(path60, "utf8");
41352
+ return readFileSync5(path62, "utf8");
41076
41353
  } catch {
41077
41354
  return null;
41078
41355
  }
@@ -44251,10 +44528,10 @@ async function writeManifest(args) {
44251
44528
  capturedAt: args.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
44252
44529
  shots: entries
44253
44530
  };
44254
- const path60 = join14(args.outDir, "manifest.json");
44255
- await writeFile(path60, `${JSON.stringify(manifest, null, 2)}
44531
+ const path62 = join14(args.outDir, "manifest.json");
44532
+ await writeFile(path62, `${JSON.stringify(manifest, null, 2)}
44256
44533
  `, "utf8");
44257
- return { path: path60, manifest };
44534
+ return { path: path62, manifest };
44258
44535
  }
44259
44536
 
44260
44537
  // ../mcp-server/src/tools/_capture/proxy.ts
@@ -44508,9 +44785,9 @@ async function startProxy(opts) {
44508
44785
  const liveCompiled = verified.allowedPaths.map(compileGlob);
44509
44786
  const target = parseRequestTarget(req);
44510
44787
  if (!target) return httpReject(400, "invalid_target");
44511
- const path60 = target.pathname;
44512
- if (!liveCompiled.some((re) => re.test(path60))) {
44513
- return httpReject(403, "outside_allow_list", { path: path60 });
44788
+ const path62 = target.pathname;
44789
+ if (!liveCompiled.some((re) => re.test(path62))) {
44790
+ return httpReject(403, "outside_allow_list", { path: path62 });
44514
44791
  }
44515
44792
  const headerWorld = req.headers[WORLD_ASSERT_HEADER];
44516
44793
  const headerWorldStr = typeof headerWorld === "string" ? headerWorld : Array.isArray(headerWorld) && headerWorld.length > 0 ? headerWorld[0] : void 0;
@@ -45350,14 +45627,14 @@ async function runShot(browser, shot, outDir, format, jpegQuality, allowEval, as
45350
45627
  await page.waitForTimeout(shot.afterLoadMs);
45351
45628
  }
45352
45629
  const ext = format === "jpeg" ? "jpg" : "png";
45353
- const path60 = join15(outDir, `${shot.name}.${ext}`);
45630
+ const path62 = join15(outDir, `${shot.name}.${ext}`);
45354
45631
  await page.screenshot({
45355
- path: path60,
45632
+ path: path62,
45356
45633
  type: format,
45357
45634
  ...format === "jpeg" ? { quality: jpegQuality } : {},
45358
45635
  fullPage: false
45359
45636
  });
45360
- return { name: shot.name, path: path60, urlRedacted: redactUrl(shot.url), viewport };
45637
+ return { name: shot.name, path: path62, urlRedacted: redactUrl(shot.url), viewport };
45361
45638
  } finally {
45362
45639
  await context.close();
45363
45640
  }
@@ -45789,9 +46066,9 @@ import { join as join17 } from "node:path";
45789
46066
  var PLACEHOLDER_ANTHROPIC_API_KEY = "olam-vault-routed-placeholder-stripped-by-proxy";
45790
46067
  var DEFAULT_WEB_TASK_MODEL = "claude-opus-4-7";
45791
46068
  var AnthropicBaseUrlMissingError = class extends Error {
45792
- constructor(path60, cause) {
46069
+ constructor(path62, cause) {
45793
46070
  super(
45794
- `vault base URL is not resolvable from "${path60}" (${cause}). The web-task model call routes through olam's auth-worker vault, not a raw API key \u2014 this host has no vault base URL configured. Run \`olam auth login\` (or set OLAM_ANTHROPIC_BASE_URL) so the path-encoded /auth/<sub>/<secret> base exists.`
46071
+ `vault base URL is not resolvable from "${path62}" (${cause}). The web-task model call routes through olam's auth-worker vault, not a raw API key \u2014 this host has no vault base URL configured. Run \`olam auth login\` (or set OLAM_ANTHROPIC_BASE_URL) so the path-encoded /auth/<sub>/<secret> base exists.`
45795
46072
  );
45796
46073
  this.name = "AnthropicBaseUrlMissingError";
45797
46074
  }
@@ -46690,12 +46967,12 @@ function openUrl(url3) {
46690
46967
  var HOST_CP_URL = "http://127.0.0.1:19000";
46691
46968
  async function readHostCpToken2() {
46692
46969
  try {
46693
- const { default: fs60 } = await import("node:fs");
46970
+ const { default: fs62 } = await import("node:fs");
46694
46971
  const { default: os36 } = await import("node:os");
46695
- const { default: path60 } = await import("node:path");
46696
- const tp = path60.join(os36.homedir(), ".olam", "host-cp.token");
46697
- if (!fs60.existsSync(tp)) return { token: null };
46698
- return { token: fs60.readFileSync(tp, "utf-8").trim() };
46972
+ const { default: path62 } = await import("node:path");
46973
+ const tp = path62.join(os36.homedir(), ".olam", "host-cp.token");
46974
+ if (!fs62.existsSync(tp)) return { token: null };
46975
+ return { token: fs62.readFileSync(tp, "utf-8").trim() };
46699
46976
  } catch {
46700
46977
  return { token: null };
46701
46978
  }
@@ -46989,9 +47266,9 @@ function register22(server, _ctx, _initError) {
46989
47266
  }]
46990
47267
  };
46991
47268
  });
46992
- validatedTool(server, repoAddSkill, "olam_repo_add", async ({ name, path: path60, description, defaultBranch }) => {
47269
+ validatedTool(server, repoAddSkill, "olam_repo_add", async ({ name, path: path62, description, defaultBranch }) => {
46993
47270
  try {
46994
- const entry = addRepo({ name, path: path60, description, defaultBranch });
47271
+ const entry = addRepo({ name, path: path62, description, defaultBranch });
46995
47272
  return {
46996
47273
  content: [{
46997
47274
  type: "text",
@@ -47027,9 +47304,9 @@ function register22(server, _ctx, _initError) {
47027
47304
  };
47028
47305
  }
47029
47306
  });
47030
- validatedTool(server, repoUpdateSkill, "olam_repo_update", async ({ name, path: path60, description, defaultBranch }) => {
47307
+ validatedTool(server, repoUpdateSkill, "olam_repo_update", async ({ name, path: path62, description, defaultBranch }) => {
47031
47308
  try {
47032
- const entry = updateRepo(name, { path: path60, description, defaultBranch });
47309
+ const entry = updateRepo(name, { path: path62, description, defaultBranch });
47033
47310
  return {
47034
47311
  content: [{
47035
47312
  type: "text",
@@ -47054,9 +47331,9 @@ __export(process_port_exports, {
47054
47331
  register: () => register23,
47055
47332
  resolveHostCpToken: () => resolveHostCpToken
47056
47333
  });
47057
- import fs39 from "node:fs";
47334
+ import fs41 from "node:fs";
47058
47335
  import os22 from "node:os";
47059
- import path37 from "node:path";
47336
+ import path39 from "node:path";
47060
47337
 
47061
47338
  // ../skill-runtime/dist/skills/process-list.js
47062
47339
  init_v3();
@@ -47101,8 +47378,8 @@ var HOST_CP_BASE = "http://127.0.0.1:19000";
47101
47378
  function resolveHostCpToken() {
47102
47379
  const envToken = process.env["OLAM_HOST_CP_TOKEN"];
47103
47380
  if (envToken) return envToken;
47104
- const tokenPath = path37.join(os22.homedir(), ".olam", "host-cp.token");
47105
- if (fs39.existsSync(tokenPath)) return fs39.readFileSync(tokenPath, "utf-8").trim();
47381
+ const tokenPath = path39.join(os22.homedir(), ".olam", "host-cp.token");
47382
+ if (fs41.existsSync(tokenPath)) return fs41.readFileSync(tokenPath, "utf-8").trim();
47106
47383
  return null;
47107
47384
  }
47108
47385
  function tokenMissingError() {
@@ -47625,8 +47902,8 @@ __export(skills_exports, {
47625
47902
  register: () => register26
47626
47903
  });
47627
47904
  init_skill_sources();
47628
- import * as fs40 from "node:fs";
47629
- import * as path38 from "node:path";
47905
+ import * as fs42 from "node:fs";
47906
+ import * as path40 from "node:path";
47630
47907
 
47631
47908
  // ../skill-runtime/dist/skills/skills-sync.js
47632
47909
  init_v3();
@@ -47707,14 +47984,14 @@ function listDeployed() {
47707
47984
  );
47708
47985
  const entries = [];
47709
47986
  for (const bucket of ["skills", "agents", "scripts", "rules", "commands"]) {
47710
- const bucketDir = path38.join(dir, bucket);
47711
- if (!fs40.existsSync(bucketDir)) continue;
47712
- for (const name of fs40.readdirSync(bucketDir)) {
47713
- const full = path38.join(bucketDir, name);
47987
+ const bucketDir = path40.join(dir, bucket);
47988
+ if (!fs42.existsSync(bucketDir)) continue;
47989
+ for (const name of fs42.readdirSync(bucketDir)) {
47990
+ const full = path40.join(bucketDir, name);
47714
47991
  try {
47715
- const stat2 = fs40.lstatSync(full);
47992
+ const stat2 = fs42.lstatSync(full);
47716
47993
  if (!stat2.isSymbolicLink()) continue;
47717
- const target = fs40.readlinkSync(full);
47994
+ const target = fs42.readlinkSync(full);
47718
47995
  let sourceId;
47719
47996
  for (const [clonePath, id] of sourcePaths.entries()) {
47720
47997
  if (target.startsWith(clonePath)) {
@@ -47802,15 +48079,15 @@ function deriveModeId(name, taken) {
47802
48079
 
47803
48080
  // ../core/dist/ree-modes/store.js
47804
48081
  init_skill_sources();
47805
- import * as fs42 from "node:fs";
48082
+ import * as fs44 from "node:fs";
47806
48083
  import * as os24 from "node:os";
47807
- import * as path40 from "node:path";
48084
+ import * as path42 from "node:path";
47808
48085
 
47809
48086
  // ../core/dist/ree-modes/registry.js
47810
48087
  init_v3();
47811
- import * as fs41 from "node:fs";
48088
+ import * as fs43 from "node:fs";
47812
48089
  import * as os23 from "node:os";
47813
- import * as path39 from "node:path";
48090
+ import * as path41 from "node:path";
47814
48091
  var CadenceStatusSchema = external_exports2.enum(["running", "stopped"]);
47815
48092
  var CadenceEntrySchema = external_exports2.object({
47816
48093
  /** Unique cadence id (modeId + short timestamp). */
@@ -47832,18 +48109,18 @@ function olamRootDir() {
47832
48109
  const override = process.env["OLAM_STATE_DIR"];
47833
48110
  if (override && override.length > 0)
47834
48111
  return override;
47835
- return path39.join(os23.homedir(), ".olam");
48112
+ return path41.join(os23.homedir(), ".olam");
47836
48113
  }
47837
48114
  function cadenceRegistryPath() {
47838
- return path39.join(olamRootDir(), "ree-cadences.json");
48115
+ return path41.join(olamRootDir(), "ree-cadences.json");
47839
48116
  }
47840
48117
  function readCadenceRegistry() {
47841
48118
  const file2 = cadenceRegistryPath();
47842
- if (!fs41.existsSync(file2))
48119
+ if (!fs43.existsSync(file2))
47843
48120
  return { cadences: [] };
47844
48121
  let raw;
47845
48122
  try {
47846
- raw = JSON.parse(fs41.readFileSync(file2, "utf-8"));
48123
+ raw = JSON.parse(fs43.readFileSync(file2, "utf-8"));
47847
48124
  } catch {
47848
48125
  return { cadences: [] };
47849
48126
  }
@@ -47852,10 +48129,10 @@ function readCadenceRegistry() {
47852
48129
  }
47853
48130
  function writeCadenceRegistry(registry2) {
47854
48131
  const file2 = cadenceRegistryPath();
47855
- fs41.mkdirSync(path39.dirname(file2), { recursive: true });
48132
+ fs43.mkdirSync(path41.dirname(file2), { recursive: true });
47856
48133
  const tmp = `${file2}.tmp-${process.pid}`;
47857
- fs41.writeFileSync(tmp, JSON.stringify(registry2, null, 2) + "\n", "utf-8");
47858
- fs41.renameSync(tmp, file2);
48134
+ fs43.writeFileSync(tmp, JSON.stringify(registry2, null, 2) + "\n", "utf-8");
48135
+ fs43.renameSync(tmp, file2);
47859
48136
  }
47860
48137
  function startCadence(input) {
47861
48138
  const now = input.now ?? /* @__PURE__ */ new Date();
@@ -47899,18 +48176,18 @@ function claudeRootDir() {
47899
48176
  const override = process.env["OLAM_CLAUDE_DIR"];
47900
48177
  if (override && override.length > 0)
47901
48178
  return override;
47902
- return path40.join(os24.homedir(), ".claude");
48179
+ return path42.join(os24.homedir(), ".claude");
47903
48180
  }
47904
48181
  function localModesDir() {
47905
- return path40.join(claudeRootDir(), "ree-modes.local");
48182
+ return path42.join(claudeRootDir(), "ree-modes.local");
47906
48183
  }
47907
48184
  var SOURCE_CATALOG_RELATIVE_PATH = "shared/engineering/skills/ree-cadence/references/modes.md";
47908
48185
  function findSourceCatalogPath(opts) {
47909
48186
  if (opts && "_testCatalogPath" in opts)
47910
48187
  return opts._testCatalogPath ?? null;
47911
48188
  for (const source of listSkillSources()) {
47912
- const candidate = path40.join(skillSourceClonePath(source.id), SOURCE_CATALOG_RELATIVE_PATH);
47913
- if (fs42.existsSync(candidate))
48189
+ const candidate = path42.join(skillSourceClonePath(source.id), SOURCE_CATALOG_RELATIVE_PATH);
48190
+ if (fs44.existsSync(candidate))
47914
48191
  return candidate;
47915
48192
  }
47916
48193
  return null;
@@ -47960,16 +48237,16 @@ function parseModeCatalog(content, origin) {
47960
48237
  }
47961
48238
  function loadLocalModes() {
47962
48239
  const dir = localModesDir();
47963
- if (!fs42.existsSync(dir))
48240
+ if (!fs44.existsSync(dir))
47964
48241
  return [];
47965
48242
  const out = [];
47966
- for (const entry of fs42.readdirSync(dir).sort()) {
48243
+ for (const entry of fs44.readdirSync(dir).sort()) {
47967
48244
  if (!entry.endsWith(".md"))
47968
48245
  continue;
47969
- const full = path40.join(dir, entry);
48246
+ const full = path42.join(dir, entry);
47970
48247
  let content;
47971
48248
  try {
47972
- content = fs42.readFileSync(full, "utf-8");
48249
+ content = fs44.readFileSync(full, "utf-8");
47973
48250
  } catch {
47974
48251
  continue;
47975
48252
  }
@@ -47985,7 +48262,7 @@ function loadSourceModes(opts) {
47985
48262
  return [];
47986
48263
  let content;
47987
48264
  try {
47988
- content = fs42.readFileSync(catalogPath, "utf-8");
48265
+ content = fs44.readFileSync(catalogPath, "utf-8");
47989
48266
  } catch {
47990
48267
  return [];
47991
48268
  }
@@ -48052,12 +48329,12 @@ function createLocalMode(input) {
48052
48329
  id = deriveModeId(name, taken);
48053
48330
  }
48054
48331
  const dir = localModesDir();
48055
- fs42.mkdirSync(dir, { recursive: true });
48056
- const file2 = path40.join(dir, `${id}.md`);
48057
- if (fs42.existsSync(file2)) {
48332
+ fs44.mkdirSync(dir, { recursive: true });
48333
+ const file2 = path42.join(dir, `${id}.md`);
48334
+ if (fs44.existsSync(file2)) {
48058
48335
  throw new Error(`local mode file already exists: ${file2}`);
48059
48336
  }
48060
- fs42.writeFileSync(file2, scaffoldModeBlock({ id, name, instruction }), "utf-8");
48337
+ fs44.writeFileSync(file2, scaffoldModeBlock({ id, name, instruction }), "utf-8");
48061
48338
  return { id, name, origin: "local", path: file2 };
48062
48339
  }
48063
48340
  function renameLocalMode(oldId, newId) {
@@ -48068,8 +48345,8 @@ function renameLocalMode(oldId, newId) {
48068
48345
  throw new Error(`invalid new id "${newId}" \u2014 must match ${MODE_ID_RE}.`);
48069
48346
  }
48070
48347
  const dir = localModesDir();
48071
- const oldFile = path40.join(dir, `${oldId}.md`);
48072
- if (!fs42.existsSync(oldFile)) {
48348
+ const oldFile = path42.join(dir, `${oldId}.md`);
48349
+ if (!fs44.existsSync(oldFile)) {
48073
48350
  const isSource = loadSourceModes().some((m) => m.id === oldId);
48074
48351
  if (isSource) {
48075
48352
  throw new Error(`"${oldId}" is a source built-in mode, not a local one \u2014 it can't be renamed directly. Create a local override (olam skills ree-modes add) and promote it instead.`);
@@ -48079,11 +48356,11 @@ function renameLocalMode(oldId, newId) {
48079
48356
  if (takenModeIds().has(newId)) {
48080
48357
  throw new Error(`target id "${newId}" already exists (source or local).`);
48081
48358
  }
48082
- const content = fs42.readFileSync(oldFile, "utf-8");
48359
+ const content = fs44.readFileSync(oldFile, "utf-8");
48083
48360
  const rewritten = content.replace(new RegExp(`^## ${escapeRegex2(oldId)} \u2014 `, "m"), `## ${newId} \u2014 `);
48084
- const newFile = path40.join(dir, `${newId}.md`);
48085
- fs42.writeFileSync(newFile, rewritten, "utf-8");
48086
- fs42.rmSync(oldFile);
48361
+ const newFile = path42.join(dir, `${newId}.md`);
48362
+ fs44.writeFileSync(newFile, rewritten, "utf-8");
48363
+ fs44.rmSync(oldFile);
48087
48364
  const danglingCadences = listCadences({ runningOnly: true }).filter((c) => c.modeId === oldId).map((c) => c.id);
48088
48365
  return { from: oldId, to: newId, origin: "local", path: newFile, danglingCadences };
48089
48366
  }
@@ -48103,8 +48380,8 @@ function deriveNameFromInstruction(instruction) {
48103
48380
  }
48104
48381
 
48105
48382
  // ../core/dist/ree-modes/promote.js
48106
- import * as fs43 from "node:fs";
48107
- import * as path41 from "node:path";
48383
+ import * as fs45 from "node:fs";
48384
+ import * as path43 from "node:path";
48108
48385
 
48109
48386
  // ../core/dist/ree-modes/disambiguation.js
48110
48387
  var PICKER_THRESHOLD = 4;
@@ -48279,13 +48556,13 @@ var skills_search_exports = {};
48279
48556
  __export(skills_search_exports, {
48280
48557
  register: () => register28
48281
48558
  });
48282
- import * as path43 from "node:path";
48559
+ import * as path45 from "node:path";
48283
48560
  import * as os26 from "node:os";
48284
48561
 
48285
48562
  // ../mcp-server/src/lib/skills-index.mjs
48286
48563
  import { createRequire as createRequire5 } from "node:module";
48287
- import * as fs44 from "node:fs";
48288
- import * as path42 from "node:path";
48564
+ import * as fs46 from "node:fs";
48565
+ import * as path44 from "node:path";
48289
48566
  import * as os25 from "node:os";
48290
48567
  var VECTOR_DIM = 256;
48291
48568
  var SCHEMA_VERSION3 = "1";
@@ -48375,7 +48652,7 @@ function bufferToVector(buf) {
48375
48652
  return vec;
48376
48653
  }
48377
48654
  function openIndex(dbPath) {
48378
- if (!fs44.existsSync(dbPath)) {
48655
+ if (!fs46.existsSync(dbPath)) {
48379
48656
  throw new Error(
48380
48657
  `skills index not found at ${dbPath}. Run \`node scripts/skills-index-build.mjs --out ${dbPath}\` first.`
48381
48658
  );
@@ -48417,8 +48694,8 @@ function searchIndex(dbPath, query, k = 5) {
48417
48694
  db.close();
48418
48695
  }
48419
48696
  }
48420
- var DEFAULT_DB_PATH = path42.join(os25.homedir(), ".olam", "skills.vec.db");
48421
- var DEFAULT_SOURCE_DIR = path42.join(os25.homedir(), ".claude", "skills");
48697
+ var DEFAULT_DB_PATH = path44.join(os25.homedir(), ".olam", "skills.vec.db");
48698
+ var DEFAULT_SOURCE_DIR = path44.join(os25.homedir(), ".claude", "skills");
48422
48699
 
48423
48700
  // ../skill-runtime/dist/skills/skills-search.js
48424
48701
  init_v3();
@@ -48437,7 +48714,7 @@ var skillsSearchSkill = defineSkill({
48437
48714
  function defaultDbPath() {
48438
48715
  const override = process.env["SKILLS_INDEX_PATH"];
48439
48716
  if (override) return override;
48440
- return path43.join(os26.homedir(), ".olam", "skills.vec.db");
48717
+ return path45.join(os26.homedir(), ".olam", "skills.vec.db");
48441
48718
  }
48442
48719
  function asMessage10(err) {
48443
48720
  return err instanceof Error ? err.message : String(err);
@@ -48481,8 +48758,8 @@ function port() {
48481
48758
  const n = Number.parseInt(env, 10);
48482
48759
  return Number.isFinite(n) && n > 0 ? n : KG_SERVICE_PORT_DEFAULT;
48483
48760
  }
48484
- function url2(path60) {
48485
- return `http://127.0.0.1:${port()}${path60}`;
48761
+ function url2(path62) {
48762
+ return `http://127.0.0.1:${port()}${path62}`;
48486
48763
  }
48487
48764
  function kgServiceHealthUrl() {
48488
48765
  return url2("/health");
@@ -48711,8 +48988,8 @@ __export(kg_install_hook_exports, {
48711
48988
  register: () => register31
48712
48989
  });
48713
48990
  init_merge_settings();
48714
- import * as fs45 from "node:fs";
48715
- import * as path44 from "node:path";
48991
+ import * as fs47 from "node:fs";
48992
+ import * as path46 from "node:path";
48716
48993
  import * as os27 from "node:os";
48717
48994
 
48718
48995
  // ../core/dist/kg/hook-template.js
@@ -48809,22 +49086,22 @@ var kgInstallHookSkill = defineSkill({
48809
49086
  // ../mcp-server/src/tools/kg-install-hook.ts
48810
49087
  function settingsPathFor2(scope, projectPath) {
48811
49088
  if (scope === "user") {
48812
- return path44.join(os27.homedir(), ".claude", "settings.json");
49089
+ return path46.join(os27.homedir(), ".claude", "settings.json");
48813
49090
  }
48814
49091
  const root = projectPath ?? process.cwd();
48815
- return path44.join(root, ".claude", "settings.json");
49092
+ return path46.join(root, ".claude", "settings.json");
48816
49093
  }
48817
49094
  function register31(server, _ctx, _initError) {
48818
49095
  validatedTool(server, kgInstallHookSkill, "olam_kg_install_hook", async (params) => {
48819
49096
  const scope = params.scope === "user" ? "user" : "project";
48820
49097
  const filePath = settingsPathFor2(scope, params.projectPath);
48821
49098
  try {
48822
- fs45.mkdirSync(path44.dirname(filePath), { recursive: true });
49099
+ fs47.mkdirSync(path46.dirname(filePath), { recursive: true });
48823
49100
  let backupPath = null;
48824
- if (fs45.existsSync(filePath)) {
49101
+ if (fs47.existsSync(filePath)) {
48825
49102
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
48826
49103
  backupPath = `${filePath}.olam-bak.${ts}`;
48827
- fs45.copyFileSync(filePath, backupPath);
49104
+ fs47.copyFileSync(filePath, backupPath);
48828
49105
  }
48829
49106
  const result = mergeHomeSettingsJson(filePath, {
48830
49107
  ensureHook: {
@@ -48835,7 +49112,7 @@ function register31(server, _ctx, _initError) {
48835
49112
  });
48836
49113
  if (result.status === "already-present" && backupPath) {
48837
49114
  try {
48838
- fs45.unlinkSync(backupPath);
49115
+ fs47.unlinkSync(backupPath);
48839
49116
  } catch {
48840
49117
  }
48841
49118
  }
@@ -48877,8 +49154,8 @@ var kg_uninstall_hook_exports = {};
48877
49154
  __export(kg_uninstall_hook_exports, {
48878
49155
  register: () => register32
48879
49156
  });
48880
- import * as fs46 from "node:fs";
48881
- import * as path45 from "node:path";
49157
+ import * as fs48 from "node:fs";
49158
+ import * as path47 from "node:path";
48882
49159
  import * as os28 from "node:os";
48883
49160
 
48884
49161
  // ../skill-runtime/dist/skills/kg-uninstall-hook.js
@@ -48901,10 +49178,10 @@ var kgUninstallHookSkill = defineSkill({
48901
49178
  // ../mcp-server/src/tools/kg-uninstall-hook.ts
48902
49179
  function settingsPathFor3(scope, projectPath) {
48903
49180
  if (scope === "user") {
48904
- return path45.join(os28.homedir(), ".claude", "settings.json");
49181
+ return path47.join(os28.homedir(), ".claude", "settings.json");
48905
49182
  }
48906
49183
  const root = projectPath ?? process.cwd();
48907
- return path45.join(root, ".claude", "settings.json");
49184
+ return path47.join(root, ".claude", "settings.json");
48908
49185
  }
48909
49186
  function dropSentinel(matchers) {
48910
49187
  let changed = false;
@@ -48931,7 +49208,7 @@ function register32(server, _ctx, _initError) {
48931
49208
  const scope = params.scope === "user" ? "user" : "project";
48932
49209
  const filePath = settingsPathFor3(scope, params.projectPath);
48933
49210
  try {
48934
- if (!fs46.existsSync(filePath)) {
49211
+ if (!fs48.existsSync(filePath)) {
48935
49212
  return {
48936
49213
  content: [
48937
49214
  {
@@ -48945,7 +49222,7 @@ function register32(server, _ctx, _initError) {
48945
49222
  ]
48946
49223
  };
48947
49224
  }
48948
- const raw = fs46.readFileSync(filePath, "utf-8");
49225
+ const raw = fs48.readFileSync(filePath, "utf-8");
48949
49226
  const settings = raw.trim() ? JSON.parse(raw) : {};
48950
49227
  const preToolUse = settings.hooks?.PreToolUse;
48951
49228
  if (!Array.isArray(preToolUse) || preToolUse.length === 0) {
@@ -48980,7 +49257,7 @@ function register32(server, _ctx, _initError) {
48980
49257
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
48981
49258
  const backupPath = `${filePath}.olam-bak.${ts}`;
48982
49259
  try {
48983
- fs46.copyFileSync(filePath, backupPath);
49260
+ fs48.copyFileSync(filePath, backupPath);
48984
49261
  } catch {
48985
49262
  }
48986
49263
  const next = {
@@ -48992,7 +49269,7 @@ function register32(server, _ctx, _initError) {
48992
49269
  if (otherStages.length === 0) delete next.hooks;
48993
49270
  else delete next.hooks.PreToolUse;
48994
49271
  }
48995
- fs46.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
49272
+ fs48.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
48996
49273
  return {
48997
49274
  content: [
48998
49275
  {
@@ -49730,11 +50007,11 @@ function registerAllTools(server, ctx, initError) {
49730
50007
  }
49731
50008
 
49732
50009
  // ../mcp-server/src/resources/chunks.ts
49733
- import fs47 from "node:fs";
50010
+ import fs49 from "node:fs";
49734
50011
  import os29 from "node:os";
49735
- import path46 from "node:path";
50012
+ import path48 from "node:path";
49736
50013
  var DEFAULT_HOST_CP_URL = "http://127.0.0.1:19000";
49737
- var DEFAULT_PLAN_CHAT_SECRET_PATH = path46.join(
50014
+ var DEFAULT_PLAN_CHAT_SECRET_PATH = path48.join(
49738
50015
  os29.homedir(),
49739
50016
  ".olam",
49740
50017
  "plan-chat-secret"
@@ -49749,7 +50026,7 @@ function loadBearer(bearerOpt, secretPath) {
49749
50026
  const envBearer = process.env.OLAM_PLAN_CHAT_BEARER?.trim();
49750
50027
  if (envBearer && envBearer.length > 0) return envBearer;
49751
50028
  try {
49752
- const onDisk = fs47.readFileSync(secretPath, "utf8").trim();
50029
+ const onDisk = fs49.readFileSync(secretPath, "utf8").trim();
49753
50030
  return onDisk.length > 0 ? onDisk : null;
49754
50031
  } catch (err) {
49755
50032
  if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
@@ -51523,9 +51800,9 @@ init_loader();
51523
51800
  // ../core/dist/world/manager.js
51524
51801
  import * as crypto8 from "node:crypto";
51525
51802
  import { execSync as execSync6, spawnSync as spawnSync4 } from "node:child_process";
51526
- import * as fs57 from "node:fs";
51803
+ import * as fs59 from "node:fs";
51527
51804
  import * as os34 from "node:os";
51528
- import * as path57 from "node:path";
51805
+ import * as path59 from "node:path";
51529
51806
 
51530
51807
  // ../core/dist/world/state.js
51531
51808
  var VALID_TRANSITIONS = {
@@ -51620,9 +51897,9 @@ function resolveDevboxImage(config2, tag) {
51620
51897
  }
51621
51898
 
51622
51899
  // ../core/dist/world/worktree.js
51623
- import { execFileSync as execFileSync4 } from "node:child_process";
51624
- import * as fs48 from "node:fs";
51625
- import * as path47 from "node:path";
51900
+ import { execFileSync as execFileSync5 } from "node:child_process";
51901
+ import * as fs50 from "node:fs";
51902
+ import * as path49 from "node:path";
51626
51903
  function resolveGitDir(repo) {
51627
51904
  if (repo.path) {
51628
51905
  return repo.path;
@@ -51632,18 +51909,18 @@ function resolveGitDir(repo) {
51632
51909
  async function createWorktrees(repos, worldId, workspacePath, branch) {
51633
51910
  const created = [];
51634
51911
  for (const repo of repos) {
51635
- const worktreePath = path47.join(workspacePath, repo.name);
51912
+ const worktreePath = path49.join(workspacePath, repo.name);
51636
51913
  const gitDir = resolveGitDir(repo);
51637
51914
  const branchName = branch || `olam/${worldId}`;
51638
51915
  try {
51639
- fs48.mkdirSync(path47.dirname(worktreePath), { recursive: true });
51640
- execFileSync4("git", ["worktree", "add", worktreePath, "-b", branchName], {
51916
+ fs50.mkdirSync(path49.dirname(worktreePath), { recursive: true });
51917
+ execFileSync5("git", ["worktree", "add", worktreePath, "-b", branchName], {
51641
51918
  cwd: gitDir,
51642
51919
  stdio: "pipe"
51643
51920
  });
51644
51921
  if (repo.submodules) {
51645
51922
  try {
51646
- execFileSync4("git", ["submodule", "update", "--init", "--recursive"], {
51923
+ execFileSync5("git", ["submodule", "update", "--init", "--recursive"], {
51647
51924
  cwd: worktreePath,
51648
51925
  stdio: "pipe"
51649
51926
  });
@@ -51655,7 +51932,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
51655
51932
  for (const entry of created) {
51656
51933
  try {
51657
51934
  const entryGitDir = resolveGitDir(entry.repo);
51658
- execFileSync4("git", ["worktree", "remove", entry.worktreePath, "--force"], {
51935
+ execFileSync5("git", ["worktree", "remove", entry.worktreePath, "--force"], {
51659
51936
  cwd: entryGitDir,
51660
51937
  stdio: "pipe"
51661
51938
  });
@@ -51669,7 +51946,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
51669
51946
  }
51670
51947
  async function removeWorktrees(repos, workspacePath) {
51671
51948
  for (const repo of repos) {
51672
- const worktreePath = path47.join(workspacePath, repo.name);
51949
+ const worktreePath = path49.join(workspacePath, repo.name);
51673
51950
  let gitDir;
51674
51951
  try {
51675
51952
  gitDir = resolveGitDir(repo);
@@ -51678,7 +51955,7 @@ async function removeWorktrees(repos, workspacePath) {
51678
51955
  }
51679
51956
  let removed = false;
51680
51957
  try {
51681
- execFileSync4("git", ["worktree", "remove", "--force", worktreePath], {
51958
+ execFileSync5("git", ["worktree", "remove", "--force", worktreePath], {
51682
51959
  cwd: gitDir,
51683
51960
  stdio: "pipe"
51684
51961
  });
@@ -51687,7 +51964,7 @@ async function removeWorktrees(repos, workspacePath) {
51687
51964
  }
51688
51965
  if (!removed) {
51689
51966
  try {
51690
- execFileSync4("git", ["worktree", "prune"], {
51967
+ execFileSync5("git", ["worktree", "prune"], {
51691
51968
  cwd: gitDir,
51692
51969
  stdio: "pipe"
51693
51970
  });
@@ -51704,7 +51981,7 @@ function removeBranch(repo, branch) {
51704
51981
  return { branch, action: "not-found" };
51705
51982
  }
51706
51983
  try {
51707
- execFileSync4("git", ["show-ref", "--quiet", `refs/heads/${branch}`], {
51984
+ execFileSync5("git", ["show-ref", "--quiet", `refs/heads/${branch}`], {
51708
51985
  cwd: gitDir,
51709
51986
  stdio: "pipe"
51710
51987
  });
@@ -51713,7 +51990,7 @@ function removeBranch(repo, branch) {
51713
51990
  }
51714
51991
  let hasUpstream = false;
51715
51992
  try {
51716
- execFileSync4("git", ["rev-parse", "--abbrev-ref", `${branch}@{upstream}`], { cwd: gitDir, stdio: "pipe" });
51993
+ execFileSync5("git", ["rev-parse", "--abbrev-ref", `${branch}@{upstream}`], { cwd: gitDir, stdio: "pipe" });
51717
51994
  hasUpstream = true;
51718
51995
  } catch {
51719
51996
  }
@@ -51722,14 +51999,14 @@ function removeBranch(repo, branch) {
51722
51999
  }
51723
52000
  let localCommitCount = 0;
51724
52001
  try {
51725
- const output = execFileSync4("git", ["rev-list", "--count", branch, "--not", "--remotes"], { cwd: gitDir, stdio: "pipe" }).toString().trim();
52002
+ const output = execFileSync5("git", ["rev-list", "--count", branch, "--not", "--remotes"], { cwd: gitDir, stdio: "pipe" }).toString().trim();
51726
52003
  localCommitCount = parseInt(output, 10) || 0;
51727
52004
  } catch {
51728
52005
  localCommitCount = 1;
51729
52006
  }
51730
52007
  if (localCommitCount === 0) {
51731
52008
  try {
51732
- execFileSync4("git", ["branch", "-D", branch], {
52009
+ execFileSync5("git", ["branch", "-D", branch], {
51733
52010
  cwd: gitDir,
51734
52011
  stdio: "pipe"
51735
52012
  });
@@ -51743,13 +52020,13 @@ function removeBranch(repo, branch) {
51743
52020
  }
51744
52021
 
51745
52022
  // ../core/dist/world/kg-overlay.js
51746
- import { execFileSync as execFileSync5 } from "node:child_process";
51747
- import * as fs49 from "node:fs";
51748
- import * as path48 from "node:path";
52023
+ import { execFileSync as execFileSync6 } from "node:child_process";
52024
+ import * as fs51 from "node:fs";
52025
+ import * as path50 from "node:path";
51749
52026
 
51750
52027
  // ../core/dist/kg/storage-paths.js
51751
52028
  import { homedir as homedir30 } from "node:os";
51752
- import { join as join50, resolve as resolve11 } from "node:path";
52029
+ import { join as join52, resolve as resolve11 } from "node:path";
51753
52030
 
51754
52031
  // ../core/dist/world/workspace-name.js
51755
52032
  var InvalidWorkspaceNameError = class extends Error {
@@ -51770,25 +52047,25 @@ function validateWorkspaceName(name) {
51770
52047
 
51771
52048
  // ../core/dist/kg/storage-paths.js
51772
52049
  function olamHome2() {
51773
- return process.env.OLAM_HOME ?? join50(homedir30(), ".olam");
52050
+ return process.env.OLAM_HOME ?? join52(homedir30(), ".olam");
51774
52051
  }
51775
52052
  function kgRoot() {
51776
- return join50(olamHome2(), "kg");
52053
+ return join52(olamHome2(), "kg");
51777
52054
  }
51778
52055
  function worldsRoot() {
51779
- return join50(olamHome2(), "worlds");
52056
+ return join52(olamHome2(), "worlds");
51780
52057
  }
51781
- function assertWithinPrefix(path60, prefix, label) {
51782
- if (!path60.startsWith(prefix + "/")) {
51783
- throw new Error(`${label} escape: ${path60} not under ${prefix}/`);
52058
+ function assertWithinPrefix(path62, prefix, label) {
52059
+ if (!path62.startsWith(prefix + "/")) {
52060
+ throw new Error(`${label} escape: ${path62} not under ${prefix}/`);
51784
52061
  }
51785
52062
  }
51786
52063
  function kgPristinePath(workspace) {
51787
52064
  validateWorkspaceName(workspace);
51788
52065
  const root = kgRoot();
51789
- const path60 = resolve11(join50(root, workspace));
51790
- assertWithinPrefix(path60, root, "kgPristinePath");
51791
- return path60;
52066
+ const path62 = resolve11(join52(root, workspace));
52067
+ assertWithinPrefix(path62, root, "kgPristinePath");
52068
+ return path62;
51792
52069
  }
51793
52070
  var KG_PATHS_INTERNALS = Object.freeze({
51794
52071
  olamHome: olamHome2,
@@ -51804,10 +52081,10 @@ var KgOverlayError = class extends Error {
51804
52081
  }
51805
52082
  };
51806
52083
  function ensureGitignoreEntry(worldClonePath) {
51807
- const gitignorePath = path48.join(worldClonePath, ".gitignore");
51808
- if (!fs49.existsSync(gitignorePath))
52084
+ const gitignorePath = path50.join(worldClonePath, ".gitignore");
52085
+ if (!fs51.existsSync(gitignorePath))
51809
52086
  return "no-gitignore";
51810
- const content = fs49.readFileSync(gitignorePath, "utf-8");
52087
+ const content = fs51.readFileSync(gitignorePath, "utf-8");
51811
52088
  const lines = content.split("\n").map((l) => l.trim());
51812
52089
  const recognised = /* @__PURE__ */ new Set([
51813
52090
  "graphify-out",
@@ -51822,31 +52099,31 @@ function ensureGitignoreEntry(worldClonePath) {
51822
52099
  const eol = content.includes("\r\n") ? "\r\n" : "\n";
51823
52100
  const needsLeadingNewline = content.length > 0 && !content.endsWith(eol);
51824
52101
  const block = `${needsLeadingNewline ? eol : ""}${eol}# olam-kg-service: per-world KG overlay (Phase B1)${eol}graphify-out/${eol}`;
51825
- fs49.appendFileSync(gitignorePath, block, "utf-8");
52102
+ fs51.appendFileSync(gitignorePath, block, "utf-8");
51826
52103
  return "appended";
51827
52104
  }
51828
52105
  function createWorldOverlay(opts) {
51829
52106
  const pristineRoot = kgPristinePath(opts.workspace);
51830
- const pristinePath = path48.join(pristineRoot, "graphify-out");
51831
- if (!fs49.existsSync(pristinePath)) {
52107
+ const pristinePath = path50.join(pristineRoot, "graphify-out");
52108
+ if (!fs51.existsSync(pristinePath)) {
51832
52109
  throw new KgOverlayError(`Pristine KG for workspace ${JSON.stringify(opts.workspace)} not found at ${pristinePath}. Run \`olam kg build ${opts.workspace}\` first.`);
51833
52110
  }
51834
- if (!path48.isAbsolute(opts.worldClonePath)) {
52111
+ if (!path50.isAbsolute(opts.worldClonePath)) {
51835
52112
  throw new KgOverlayError(`worldClonePath must be absolute (got ${opts.worldClonePath})`);
51836
52113
  }
51837
- if (!fs49.existsSync(opts.worldClonePath)) {
52114
+ if (!fs51.existsSync(opts.worldClonePath)) {
51838
52115
  throw new KgOverlayError(`worldClonePath does not exist: ${opts.worldClonePath}. Create the clone before reflinking.`);
51839
52116
  }
51840
- const overlayPath = path48.join(opts.worldClonePath, "graphify-out");
51841
- if (fs49.existsSync(overlayPath)) {
51842
- fs49.rmSync(overlayPath, { recursive: true, force: true });
52117
+ const overlayPath = path50.join(opts.worldClonePath, "graphify-out");
52118
+ if (fs51.existsSync(overlayPath)) {
52119
+ fs51.rmSync(overlayPath, { recursive: true, force: true });
51843
52120
  }
51844
52121
  const useReflink = process.platform === "darwin";
51845
52122
  let strategy;
51846
52123
  let reflinkError;
51847
52124
  if (useReflink) {
51848
52125
  try {
51849
- execFileSync5("cp", ["-c", "-r", pristinePath, opts.worldClonePath], {
52126
+ execFileSync6("cp", ["-c", "-r", pristinePath, opts.worldClonePath], {
51850
52127
  stdio: ["ignore", "ignore", "pipe"]
51851
52128
  });
51852
52129
  strategy = "cp-c-r-reflink";
@@ -51857,9 +52134,9 @@ function createWorldOverlay(opts) {
51857
52134
  } else {
51858
52135
  strategy = "cp-r";
51859
52136
  }
51860
- if (strategy === "cp-r" || !fs49.existsSync(overlayPath)) {
52137
+ if (strategy === "cp-r" || !fs51.existsSync(overlayPath)) {
51861
52138
  try {
51862
- execFileSync5("cp", ["-r", pristinePath, opts.worldClonePath], {
52139
+ execFileSync6("cp", ["-r", pristinePath, opts.worldClonePath], {
51863
52140
  stdio: ["ignore", "ignore", "pipe"]
51864
52141
  });
51865
52142
  strategy = "cp-r";
@@ -51869,7 +52146,7 @@ function createWorldOverlay(opts) {
51869
52146
  throw new KgOverlayError(`cp -r failed: ${msg}${reflinkMsg}`);
51870
52147
  }
51871
52148
  }
51872
- if (!fs49.existsSync(overlayPath)) {
52149
+ if (!fs51.existsSync(overlayPath)) {
51873
52150
  throw new KgOverlayError(`Overlay creation produced no ${overlayPath} after cp \u2014 filesystem returned without error?`);
51874
52151
  }
51875
52152
  const gitignoreAction = ensureGitignoreEntry(opts.worldClonePath);
@@ -51882,10 +52159,10 @@ function createWorldOverlay(opts) {
51882
52159
  }
51883
52160
 
51884
52161
  // ../core/dist/world/baseline-diff.js
51885
- import { execFileSync as execFileSync6 } from "node:child_process";
51886
- import * as fs50 from "node:fs";
52162
+ import { execFileSync as execFileSync7 } from "node:child_process";
52163
+ import * as fs52 from "node:fs";
51887
52164
  import * as os30 from "node:os";
51888
- import * as path49 from "node:path";
52165
+ import * as path51 from "node:path";
51889
52166
  var DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
51890
52167
  function expandHome2(p, homedir37) {
51891
52168
  return p.replace(/^~(?=$|\/|\\)/, homedir37());
@@ -51910,11 +52187,11 @@ ${stderr}`;
51910
52187
  return /unknown revision|bad revision|does not have any commits|HEAD'?: ambiguous|Needed a single revision/.test(blob);
51911
52188
  }
51912
52189
  function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
51913
- const exec = deps.exec ?? ((cmd, args, opts) => execFileSync6(cmd, args, opts));
52190
+ const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
51914
52191
  const homedir37 = deps.homedir ?? (() => os30.homedir());
51915
- const baselineDir = path49.join(workspacePath, ".olam", "baseline");
52192
+ const baselineDir = path51.join(workspacePath, ".olam", "baseline");
51916
52193
  try {
51917
- fs50.mkdirSync(baselineDir, { recursive: true });
52194
+ fs52.mkdirSync(baselineDir, { recursive: true });
51918
52195
  } catch (err) {
51919
52196
  const msg = err instanceof Error ? err.message : String(err);
51920
52197
  console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
@@ -51926,9 +52203,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
51926
52203
  if (!repo.path)
51927
52204
  continue;
51928
52205
  const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
51929
- const outPath = path49.join(baselineDir, filename);
52206
+ const outPath = path51.join(baselineDir, filename);
51930
52207
  const repoPath = expandHome2(repo.path, homedir37);
51931
- if (!fs50.existsSync(repoPath)) {
52208
+ if (!fs52.existsSync(repoPath)) {
51932
52209
  writeBaselineFile(outPath, `# repo: ${repo.name}
51933
52210
  # (skipped: path ${repoPath} does not exist)
51934
52211
  `);
@@ -51995,7 +52272,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
51995
52272
  }
51996
52273
  function writeBaselineFile(outPath, content) {
51997
52274
  try {
51998
- fs50.writeFileSync(outPath, content);
52275
+ fs52.writeFileSync(outPath, content);
51999
52276
  } catch (err) {
52000
52277
  const msg = err instanceof Error ? err.message : String(err);
52001
52278
  console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
@@ -52003,11 +52280,11 @@ function writeBaselineFile(outPath, content) {
52003
52280
  }
52004
52281
  function stripWorktreeEdits(repos, workspacePath) {
52005
52282
  for (const repo of repos) {
52006
- const worktreePath = path49.join(workspacePath, repo.name);
52007
- if (!fs50.existsSync(worktreePath))
52283
+ const worktreePath = path51.join(workspacePath, repo.name);
52284
+ if (!fs52.existsSync(worktreePath))
52008
52285
  continue;
52009
52286
  try {
52010
- execFileSync6("git", ["checkout", "--", "."], {
52287
+ execFileSync7("git", ["checkout", "--", "."], {
52011
52288
  cwd: worktreePath,
52012
52289
  stdio: "pipe"
52013
52290
  });
@@ -52034,7 +52311,7 @@ ${stderr.trim()}` : "";
52034
52311
  }
52035
52312
  };
52036
52313
  function captureOperatorDiff(repoPath, deps = {}) {
52037
- const exec = deps.exec ?? ((cmd, args, opts) => execFileSync6(cmd, args, opts));
52314
+ const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
52038
52315
  const unstaged = exec("git", ["diff"], {
52039
52316
  cwd: repoPath,
52040
52317
  encoding: "utf-8",
@@ -52062,22 +52339,22 @@ function extractStderr(err) {
52062
52339
  return typeof raw === "string" ? raw : raw.toString("utf-8");
52063
52340
  }
52064
52341
  function carryUncommittedEdits(repos, workspacePath, deps = {}) {
52065
- const exec = deps.exec ?? ((cmd, args, opts) => execFileSync6(cmd, args, opts));
52342
+ const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
52066
52343
  const homedir37 = deps.homedir ?? (() => os30.homedir());
52067
- const existsSync59 = deps.existsSync ?? ((p) => fs50.existsSync(p));
52068
- const copyFileSync9 = deps.copyFileSync ?? ((src, dest) => fs50.copyFileSync(src, dest));
52344
+ const existsSync61 = deps.existsSync ?? ((p) => fs52.existsSync(p));
52345
+ const copyFileSync10 = deps.copyFileSync ?? ((src, dest) => fs52.copyFileSync(src, dest));
52069
52346
  const mkdirSync34 = deps.mkdirSync ?? ((dirPath, opts) => {
52070
- fs50.mkdirSync(dirPath, opts);
52347
+ fs52.mkdirSync(dirPath, opts);
52071
52348
  });
52072
52349
  const plans = [];
52073
52350
  for (const repo of repos) {
52074
52351
  if (!repo.path)
52075
52352
  continue;
52076
52353
  const repoPath = expandHome2(repo.path, homedir37);
52077
- const worktreePath = path49.join(workspacePath, repo.name);
52078
- if (!existsSync59(repoPath))
52354
+ const worktreePath = path51.join(workspacePath, repo.name);
52355
+ if (!existsSync61(repoPath))
52079
52356
  continue;
52080
- if (!existsSync59(worktreePath)) {
52357
+ if (!existsSync61(worktreePath)) {
52081
52358
  console.warn(`[carry] ${repo.name}: world worktree ${worktreePath} missing; skipping carry for this repo`);
52082
52359
  continue;
52083
52360
  }
@@ -52135,13 +52412,13 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
52135
52412
  }
52136
52413
  }
52137
52414
  for (const rel of plan.diff.untracked) {
52138
- const src = path49.join(plan.repoPath, rel);
52139
- const dest = path49.join(plan.worktreePath, rel);
52140
- if (!existsSync59(src))
52415
+ const src = path51.join(plan.repoPath, rel);
52416
+ const dest = path51.join(plan.worktreePath, rel);
52417
+ if (!existsSync61(src))
52141
52418
  continue;
52142
52419
  try {
52143
- mkdirSync34(path49.dirname(dest), { recursive: true });
52144
- copyFileSync9(src, dest);
52420
+ mkdirSync34(path51.dirname(dest), { recursive: true });
52421
+ copyFileSync10(src, dest);
52145
52422
  } catch (err) {
52146
52423
  const msg = err instanceof Error ? err.message : String(err);
52147
52424
  console.warn(`[carry] ${plan.name}: copy untracked ${rel} failed: ${msg}`);
@@ -52166,8 +52443,8 @@ function formatBaselineSummary(result) {
52166
52443
  }
52167
52444
 
52168
52445
  // ../core/dist/world/context-injection.js
52169
- import * as fs51 from "node:fs";
52170
- import * as path50 from "node:path";
52446
+ import * as fs53 from "node:fs";
52447
+ import * as path52 from "node:path";
52171
52448
 
52172
52449
  // ../core/dist/world/templates/_generated.js
52173
52450
  var GH_PR_CREATE = '# Creating PRs from inside an Olam world\n\n## The problem\n\nCalling `gh pr create` directly inside an Olam container **hangs forever** on a\nTTY confirmation prompt that the agent cannot answer. This is a known, reproduced issue.\n\n## The fix\n\nAlways use this exact pattern:\n\n```bash\necho y | timeout 30 gh pr create \\\n --base main \\\n --head <branch> \\\n --title "<title>" \\\n --body-file /tmp/pr-body.md\n```\n\n## Why each part matters\n\n- **`echo y |`** \u2014 answers the "Submit?" confirmation prompt up front so `gh` never pauses.\n- **`timeout 30`** \u2014 hard deadline. If `gh` hangs anyway, the command exits non-zero so the\n agent can react instead of stalling the world indefinitely.\n- **`--body-file /tmp/pr-body.md`** \u2014 write the PR body to a temp file first. Avoids\n shell-escaping bugs that occur with `--body "..."` for long or multi-line bodies.\n- **`--head` and `--base` explicitly** \u2014 removes all interactive prompts; `gh` has nothing to ask.\n\n## Troubleshooting\n\n**"no commits" or "branch not found" error:**\n\n```bash\ngit push -u origin <branch>\n# then retry:\necho y | timeout 30 gh pr create --base main --head <branch> --title "..." --body-file /tmp/pr-body.md\n```\n\n**Timeout exceeded (command exits 124):**\n\n- Check if the branch was pushed: `git log origin/<branch> --oneline -1`\n- Check GitHub CLI auth: `gh auth status`\n- Retry once; if it hangs again, open the PR via the GitHub web UI.\n';
@@ -52177,10 +52454,10 @@ var WORLD_CLAUDE_MD = '# Olam World: {{worldName}}\n\n{{taskBlock}}\n\n## Enviro
52177
52454
  // ../core/dist/world/context-injection.js
52178
52455
  function injectWorldContext(opts) {
52179
52456
  const { world } = opts;
52180
- const claudeDir2 = path50.join(world.workspacePath, ".claude");
52181
- fs51.mkdirSync(claudeDir2, { recursive: true });
52457
+ const claudeDir2 = path52.join(world.workspacePath, ".claude");
52458
+ fs53.mkdirSync(claudeDir2, { recursive: true });
52182
52459
  const content = WORLD_CLAUDE_MD.replace("{{worldName}}", world.name).replace("{{worldId}}", world.id).replace("{{branch}}", world.branch).replace("{{taskBlock}}", buildTaskBlock(opts)).replace("{{reposList}}", buildReposList(world)).replace("{{servicesLine}}", buildServicesLine(opts.services)).replace("{{pleriPlaneLine}}", buildPleriPlaneLine(opts.pleriPlaneUrl)).replace("{{planFileBlock}}", buildPlanFileBlock(world)).replace("{{extraContextBlock}}", buildExtraContextBlock(opts.claudeMdExtra));
52183
- fs51.writeFileSync(path50.join(claudeDir2, "CLAUDE.md"), content);
52460
+ fs53.writeFileSync(path52.join(claudeDir2, "CLAUDE.md"), content);
52184
52461
  writeOlamDocs(world.workspacePath);
52185
52462
  }
52186
52463
  function buildTaskBlock(opts) {
@@ -52254,10 +52531,10 @@ function buildExtraContextBlock(extra) {
52254
52531
  ${extra}`;
52255
52532
  }
52256
52533
  function writeOlamDocs(workspacePath) {
52257
- const docsDir = path50.join(workspacePath, ".olam", "docs");
52258
- fs51.mkdirSync(docsDir, { recursive: true });
52259
- fs51.writeFileSync(path50.join(docsDir, "gh-pr-create.md"), GH_PR_CREATE);
52260
- fs51.writeFileSync(path50.join(docsDir, "lane-orchestration.md"), LANE_ORCHESTRATION);
52534
+ const docsDir = path52.join(workspacePath, ".olam", "docs");
52535
+ fs53.mkdirSync(docsDir, { recursive: true });
52536
+ fs53.writeFileSync(path52.join(docsDir, "gh-pr-create.md"), GH_PR_CREATE);
52537
+ fs53.writeFileSync(path52.join(docsDir, "lane-orchestration.md"), LANE_ORCHESTRATION);
52261
52538
  }
52262
52539
  function formatTaskSource(ctx) {
52263
52540
  if (ctx.source === "linear" && ctx.ticketId) {
@@ -52271,9 +52548,9 @@ function formatTaskSource(ctx) {
52271
52548
  function hasPlanFile(world) {
52272
52549
  if (world.repos.length === 0)
52273
52550
  return false;
52274
- const plansDir = path50.join(world.workspacePath, world.repos[0], "docs", "plans");
52551
+ const plansDir = path52.join(world.workspacePath, world.repos[0], "docs", "plans");
52275
52552
  try {
52276
- return fs51.existsSync(plansDir) && fs51.readdirSync(plansDir).length > 0;
52553
+ return fs53.existsSync(plansDir) && fs53.readdirSync(plansDir).length > 0;
52277
52554
  } catch {
52278
52555
  return false;
52279
52556
  }
@@ -52842,25 +53119,25 @@ init_repo_manifest();
52842
53119
 
52843
53120
  // ../core/dist/world/snapshot.js
52844
53121
  import * as crypto7 from "node:crypto";
52845
- import * as fs52 from "node:fs";
53122
+ import * as fs54 from "node:fs";
52846
53123
  import * as os31 from "node:os";
52847
- import * as path51 from "node:path";
52848
- import { execFileSync as execFileSync7, spawn as spawn5 } from "node:child_process";
53124
+ import * as path53 from "node:path";
53125
+ import { execFileSync as execFileSync8, spawn as spawn5 } from "node:child_process";
52849
53126
  import { gunzipSync } from "node:zlib";
52850
53127
  function snapshotsDir() {
52851
- return process.env["OLAM_SNAPSHOTS_DIR"] ?? path51.join(os31.homedir(), ".olam", "snapshots");
53128
+ return process.env["OLAM_SNAPSHOTS_DIR"] ?? path53.join(os31.homedir(), ".olam", "snapshots");
52852
53129
  }
52853
53130
  function snapshotKindDirByWorkspace(workspace, arch, kind) {
52854
- return path51.join(snapshotsDir(), "by-workspace", workspace, arch, kind);
53131
+ return path53.join(snapshotsDir(), "by-workspace", workspace, arch, kind);
52855
53132
  }
52856
53133
  function cleanupLegacyByWorldDir(worldId) {
52857
- const legacyDir = path51.join(snapshotsDir(), worldId);
53134
+ const legacyDir = path53.join(snapshotsDir(), worldId);
52858
53135
  if (worldId === "by-workspace")
52859
53136
  return;
52860
- if (!fs52.existsSync(legacyDir))
53137
+ if (!fs54.existsSync(legacyDir))
52861
53138
  return;
52862
53139
  try {
52863
- fs52.rmSync(legacyDir, { recursive: true, force: true });
53140
+ fs54.rmSync(legacyDir, { recursive: true, force: true });
52864
53141
  } catch {
52865
53142
  }
52866
53143
  }
@@ -52879,11 +53156,11 @@ function hashBuffers(entries) {
52879
53156
  return hash2.digest("hex").slice(0, 12);
52880
53157
  }
52881
53158
  function computeGemsFingerprint(repoDir, imageDigest) {
52882
- const lockfile = path51.join(repoDir, "Gemfile.lock");
52883
- if (!fs52.existsSync(lockfile))
53159
+ const lockfile = path53.join(repoDir, "Gemfile.lock");
53160
+ if (!fs54.existsSync(lockfile))
52884
53161
  return null;
52885
53162
  const entries = [
52886
- { path: "Gemfile.lock", content: fs52.readFileSync(lockfile) }
53163
+ { path: "Gemfile.lock", content: fs54.readFileSync(lockfile) }
52887
53164
  ];
52888
53165
  if (imageDigest) {
52889
53166
  entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
@@ -52893,10 +53170,10 @@ function computeGemsFingerprint(repoDir, imageDigest) {
52893
53170
  function computeNodeFingerprint(repoDir, imageDigest) {
52894
53171
  const candidates = ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"];
52895
53172
  for (const name of candidates) {
52896
- const lockfile = path51.join(repoDir, name);
52897
- if (fs52.existsSync(lockfile)) {
53173
+ const lockfile = path53.join(repoDir, name);
53174
+ if (fs54.existsSync(lockfile)) {
52898
53175
  const entries = [
52899
- { path: name, content: fs52.readFileSync(lockfile) }
53176
+ { path: name, content: fs54.readFileSync(lockfile) }
52900
53177
  ];
52901
53178
  if (imageDigest) {
52902
53179
  entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
@@ -52915,18 +53192,18 @@ function unpackTarballAtomic(srcPath, destDir) {
52915
53192
  detail: validation.detail ?? `unsafe entry: ${validation.unsafePath}`
52916
53193
  };
52917
53194
  }
52918
- const parent = path51.dirname(destDir);
52919
- fs52.mkdirSync(parent, { recursive: true });
53195
+ const parent = path53.dirname(destDir);
53196
+ fs54.mkdirSync(parent, { recursive: true });
52920
53197
  const tmpSuffix = `.tmp-${process.pid}-${crypto7.randomBytes(4).toString("hex")}`;
52921
53198
  const tmpDir = `${destDir}${tmpSuffix}`;
52922
53199
  try {
52923
- fs52.mkdirSync(tmpDir, { recursive: true });
52924
- execFileSync7("tar", ["-xzf", srcPath, "-C", tmpDir], { stdio: "pipe" });
52925
- fs52.renameSync(tmpDir, destDir);
53200
+ fs54.mkdirSync(tmpDir, { recursive: true });
53201
+ execFileSync8("tar", ["-xzf", srcPath, "-C", tmpDir], { stdio: "pipe" });
53202
+ fs54.renameSync(tmpDir, destDir);
52926
53203
  return { ok: true, entryCount: validation.entries.length };
52927
53204
  } catch (err) {
52928
53205
  try {
52929
- fs52.rmSync(tmpDir, { recursive: true, force: true });
53206
+ fs54.rmSync(tmpDir, { recursive: true, force: true });
52930
53207
  } catch {
52931
53208
  }
52932
53209
  return {
@@ -52937,12 +53214,12 @@ function unpackTarballAtomic(srcPath, destDir) {
52937
53214
  }
52938
53215
  }
52939
53216
  function resolvesWithin(base, target) {
52940
- const resolved = path51.resolve(base, target);
52941
- const baseResolved = path51.resolve(base);
52942
- const rel = path51.relative(baseResolved, resolved);
53217
+ const resolved = path53.resolve(base, target);
53218
+ const baseResolved = path53.resolve(base);
53219
+ const rel = path53.relative(baseResolved, resolved);
52943
53220
  if (rel === "")
52944
53221
  return true;
52945
- return !rel.startsWith("..") && !path51.isAbsolute(rel);
53222
+ return !rel.startsWith("..") && !path53.isAbsolute(rel);
52946
53223
  }
52947
53224
  var TYPE_CHAR_TO_TYPE = {
52948
53225
  "-": "file",
@@ -52992,7 +53269,7 @@ function parseTarListLine(line) {
52992
53269
  function validateHardlinksBinary(tarPath, targetDir) {
52993
53270
  let raw;
52994
53271
  try {
52995
- raw = gunzipSync(fs52.readFileSync(tarPath));
53272
+ raw = gunzipSync(fs54.readFileSync(tarPath));
52996
53273
  } catch {
52997
53274
  return null;
52998
53275
  }
@@ -53007,7 +53284,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
53007
53284
  const name = block.subarray(0, nameNull >= 0 && nameNull <= 99 ? nameNull : 100).toString("utf-8");
53008
53285
  const linkNull = block.indexOf(0, 157);
53009
53286
  const linkname = block.subarray(157, linkNull >= 157 && linkNull <= 256 ? linkNull : 257).toString("utf-8");
53010
- if (linkname && (path51.isAbsolute(linkname) || !resolvesWithin(targetDir, linkname))) {
53287
+ if (linkname && (path53.isAbsolute(linkname) || !resolvesWithin(targetDir, linkname))) {
53011
53288
  return {
53012
53289
  valid: false,
53013
53290
  reason: "hardlink-escape",
@@ -53025,7 +53302,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
53025
53302
  function enumerateAndValidateTarballEntries(tarPath, targetDir) {
53026
53303
  let raw;
53027
53304
  try {
53028
- raw = execFileSync7("tar", ["-tvf", tarPath], {
53305
+ raw = execFileSync8("tar", ["-tvf", tarPath], {
53029
53306
  stdio: ["ignore", "pipe", "pipe"],
53030
53307
  env: { ...process.env, LC_ALL: "C", TZ: "UTC" },
53031
53308
  encoding: "utf-8",
@@ -53045,7 +53322,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
53045
53322
  const entry = parseTarListLine(line);
53046
53323
  if (!entry)
53047
53324
  continue;
53048
- if (path51.isAbsolute(entry.name) || !resolvesWithin(targetDir, entry.name)) {
53325
+ if (path53.isAbsolute(entry.name) || !resolvesWithin(targetDir, entry.name)) {
53049
53326
  return {
53050
53327
  valid: false,
53051
53328
  reason: "path-traversal",
@@ -53053,8 +53330,8 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
53053
53330
  };
53054
53331
  }
53055
53332
  if (entry.type === "symlink" && entry.linkname !== void 0) {
53056
- const symlinkParent = path51.join(targetDir, path51.dirname(entry.name));
53057
- if (path51.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, path51.join(path51.dirname(entry.name), entry.linkname))) {
53333
+ const symlinkParent = path53.join(targetDir, path53.dirname(entry.name));
53334
+ if (path53.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, path53.join(path53.dirname(entry.name), entry.linkname))) {
53058
53335
  return {
53059
53336
  valid: false,
53060
53337
  reason: "symlink-escape",
@@ -53064,7 +53341,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
53064
53341
  }
53065
53342
  }
53066
53343
  if (entry.type === "hardlink" && entry.linkname !== void 0) {
53067
- if (path51.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, entry.linkname)) {
53344
+ if (path53.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, entry.linkname)) {
53068
53345
  return {
53069
53346
  valid: false,
53070
53347
  reason: "hardlink-escape",
@@ -53097,8 +53374,8 @@ function restoreSnapshotsForRepos(input) {
53097
53374
  }
53098
53375
  const archDir = snapshotKindDirByWorkspace(input.workspace, input.arch, kind);
53099
53376
  const tarFilename = `${repo.name}-${input.arch}-${fingerprint}.tar.gz`;
53100
- const tarPath = path51.join(archDir, tarFilename);
53101
- if (!fs52.existsSync(tarPath)) {
53377
+ const tarPath = path53.join(archDir, tarFilename);
53378
+ if (!fs54.existsSync(tarPath)) {
53102
53379
  outcomes.push({ repo: repo.name, kind, outcome: "miss", reason: "no-tarball", fingerprint });
53103
53380
  continue;
53104
53381
  }
@@ -53113,9 +53390,9 @@ function restoreSnapshotsForRepos(input) {
53113
53390
  });
53114
53391
  continue;
53115
53392
  }
53116
- const targetDir = path51.join(repo.worktreeDir, targetSubpath);
53393
+ const targetDir = path53.join(repo.worktreeDir, targetSubpath);
53117
53394
  try {
53118
- fs52.rmSync(targetDir, { recursive: true, force: true });
53395
+ fs54.rmSync(targetDir, { recursive: true, force: true });
53119
53396
  } catch {
53120
53397
  }
53121
53398
  const result = unpackTarballAtomic(tarPath, targetDir);
@@ -53128,8 +53405,8 @@ function restoreSnapshotsForRepos(input) {
53128
53405
  fingerprint
53129
53406
  });
53130
53407
  try {
53131
- fs52.rmSync(tarPath, { force: true });
53132
- fs52.rmSync(manifestPath(tarPath), { force: true });
53408
+ fs54.rmSync(tarPath, { force: true });
53409
+ fs54.rmSync(manifestPath(tarPath), { force: true });
53133
53410
  } catch {
53134
53411
  }
53135
53412
  continue;
@@ -53145,10 +53422,10 @@ function restoreSnapshotsForRepos(input) {
53145
53422
  }
53146
53423
  function readManifest(tarPath) {
53147
53424
  const mPath = manifestPath(tarPath);
53148
- if (!fs52.existsSync(mPath))
53425
+ if (!fs54.existsSync(mPath))
53149
53426
  return null;
53150
53427
  try {
53151
- return JSON.parse(fs52.readFileSync(mPath, "utf-8"));
53428
+ return JSON.parse(fs54.readFileSync(mPath, "utf-8"));
53152
53429
  } catch {
53153
53430
  return null;
53154
53431
  }
@@ -53163,17 +53440,17 @@ function isPidAlive(pid) {
53163
53440
  }
53164
53441
  }
53165
53442
  function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
53166
- fs52.mkdirSync(dir, { recursive: true });
53167
- const lockPath = path51.join(dir, EVICT_LOCK_FILENAME);
53443
+ fs54.mkdirSync(dir, { recursive: true });
53444
+ const lockPath = path53.join(dir, EVICT_LOCK_FILENAME);
53168
53445
  let fd;
53169
53446
  try {
53170
- fd = fs52.openSync(lockPath, fs52.constants.O_WRONLY | fs52.constants.O_CREAT | fs52.constants.O_EXCL, 384);
53447
+ fd = fs54.openSync(lockPath, fs54.constants.O_WRONLY | fs54.constants.O_CREAT | fs54.constants.O_EXCL, 384);
53171
53448
  } catch (err) {
53172
53449
  if (err.code !== "EEXIST")
53173
53450
  return 0;
53174
53451
  let holderPid = null;
53175
53452
  try {
53176
- holderPid = parseInt(fs52.readFileSync(lockPath, "utf-8").trim(), 10);
53453
+ holderPid = parseInt(fs54.readFileSync(lockPath, "utf-8").trim(), 10);
53177
53454
  } catch {
53178
53455
  holderPid = null;
53179
53456
  }
@@ -53181,23 +53458,23 @@ function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
53181
53458
  return 0;
53182
53459
  }
53183
53460
  try {
53184
- fs52.unlinkSync(lockPath);
53185
- fd = fs52.openSync(lockPath, fs52.constants.O_WRONLY | fs52.constants.O_CREAT | fs52.constants.O_EXCL, 384);
53461
+ fs54.unlinkSync(lockPath);
53462
+ fd = fs54.openSync(lockPath, fs54.constants.O_WRONLY | fs54.constants.O_CREAT | fs54.constants.O_EXCL, 384);
53186
53463
  } catch {
53187
53464
  return 0;
53188
53465
  }
53189
53466
  }
53190
53467
  try {
53191
- fs52.writeSync(fd, `${process.pid}
53468
+ fs54.writeSync(fd, `${process.pid}
53192
53469
  `);
53193
53470
  } finally {
53194
- fs52.closeSync(fd);
53471
+ fs54.closeSync(fd);
53195
53472
  }
53196
53473
  try {
53197
53474
  return evictOldSnapshots(maxBytes, dir);
53198
53475
  } finally {
53199
53476
  try {
53200
- fs52.unlinkSync(lockPath);
53477
+ fs54.unlinkSync(lockPath);
53201
53478
  } catch {
53202
53479
  }
53203
53480
  }
@@ -53230,16 +53507,16 @@ function spawnAutoCapture(worldId, olamBin = "olam") {
53230
53507
  }
53231
53508
  }
53232
53509
  function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
53233
- if (!fs52.existsSync(dir))
53510
+ if (!fs54.existsSync(dir))
53234
53511
  return 0;
53235
53512
  const allTars = [];
53236
53513
  const walk = (d) => {
53237
- for (const entry of fs52.readdirSync(d, { withFileTypes: true })) {
53238
- const full = path51.join(d, entry.name);
53514
+ for (const entry of fs54.readdirSync(d, { withFileTypes: true })) {
53515
+ const full = path53.join(d, entry.name);
53239
53516
  if (entry.isDirectory()) {
53240
53517
  walk(full);
53241
53518
  } else if (entry.name.endsWith(".tar.gz")) {
53242
- const stat2 = fs52.statSync(full);
53519
+ const stat2 = fs54.statSync(full);
53243
53520
  allTars.push({ path: full, size: stat2.size, mtime: stat2.mtimeMs });
53244
53521
  }
53245
53522
  }
@@ -53254,8 +53531,8 @@ function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
53254
53531
  for (const tar of allTars) {
53255
53532
  if (remaining <= maxBytes)
53256
53533
  break;
53257
- fs52.rmSync(tar.path, { force: true });
53258
- fs52.rmSync(manifestPath(tar.path), { force: true });
53534
+ fs54.rmSync(tar.path, { force: true });
53535
+ fs54.rmSync(manifestPath(tar.path), { force: true });
53259
53536
  freed += tar.size;
53260
53537
  remaining -= tar.size;
53261
53538
  }
@@ -53372,14 +53649,14 @@ function gcloudAvailable(execFn = defaultExecFn) {
53372
53649
 
53373
53650
  // ../core/dist/world/olam-yaml.js
53374
53651
  init_repo_manifest();
53375
- import * as path52 from "node:path";
53652
+ import * as path54 from "node:path";
53376
53653
  import YAML2 from "yaml";
53377
53654
  function enrichReposWithManifests(repos, workspacePath) {
53378
53655
  return repos.map((repo) => {
53379
53656
  if (repo.manifest !== void 0 && repo.manifest !== null) {
53380
53657
  return repo;
53381
53658
  }
53382
- const repoDir = path52.join(workspacePath, repo.name);
53659
+ const repoDir = path54.join(workspacePath, repo.name);
53383
53660
  let manifest = null;
53384
53661
  try {
53385
53662
  manifest = loadRepoManifest(repoDir);
@@ -53394,8 +53671,8 @@ function enrichReposWithManifests(repos, workspacePath) {
53394
53671
  }
53395
53672
 
53396
53673
  // ../core/dist/policies/loader.js
53397
- import * as fs53 from "node:fs";
53398
- import * as path53 from "node:path";
53674
+ import * as fs55 from "node:fs";
53675
+ import * as path55 from "node:path";
53399
53676
  import { parse as parseYaml5 } from "yaml";
53400
53677
  function parseFrontmatter2(content) {
53401
53678
  const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
@@ -53415,20 +53692,20 @@ function toStringArray(v) {
53415
53692
  return v.filter((x) => typeof x === "string");
53416
53693
  }
53417
53694
  function loadPolicies(workspaceRoot) {
53418
- const policiesDir = path53.join(workspaceRoot, ".olam", "policies");
53419
- if (!fs53.existsSync(policiesDir))
53695
+ const policiesDir = path55.join(workspaceRoot, ".olam", "policies");
53696
+ if (!fs55.existsSync(policiesDir))
53420
53697
  return [];
53421
53698
  let files;
53422
53699
  try {
53423
- files = fs53.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
53700
+ files = fs55.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
53424
53701
  } catch {
53425
53702
  return [];
53426
53703
  }
53427
53704
  const policies = [];
53428
53705
  for (const file2 of files) {
53429
- const filePath = path53.join(policiesDir, file2);
53706
+ const filePath = path55.join(policiesDir, file2);
53430
53707
  try {
53431
- const content = fs53.readFileSync(filePath, "utf8");
53708
+ const content = fs55.readFileSync(filePath, "utf8");
53432
53709
  const parsed = parseFrontmatter2(content);
53433
53710
  if (!parsed) {
53434
53711
  console.warn(`[policies] skipping ${file2}: no valid frontmatter block`);
@@ -53572,9 +53849,9 @@ async function autoDispatchTask(opts) {
53572
53849
  }
53573
53850
 
53574
53851
  // ../core/dist/world/wiki-injection-loader.js
53575
- import * as fs54 from "node:fs";
53852
+ import * as fs56 from "node:fs";
53576
53853
  import * as os32 from "node:os";
53577
- import * as path54 from "node:path";
53854
+ import * as path56 from "node:path";
53578
53855
  var WIKI_INJECTION_FLAG = "OLAM_WIKI_INJECTION";
53579
53856
  var WIKI_PATH_ENV = "OLAM_WIKI_PATH";
53580
53857
  function flagEnabled(value) {
@@ -53587,14 +53864,14 @@ function wikiBlobPath() {
53587
53864
  const override = process.env[WIKI_PATH_ENV];
53588
53865
  if (override && override.length > 0)
53589
53866
  return override;
53590
- return path54.join(os32.homedir(), ".olam", "wiki.json");
53867
+ return path56.join(os32.homedir(), ".olam", "wiki.json");
53591
53868
  }
53592
53869
  function defaultReadBlob() {
53593
53870
  const p = wikiBlobPath();
53594
53871
  try {
53595
- if (!fs54.existsSync(p))
53872
+ if (!fs56.existsSync(p))
53596
53873
  return null;
53597
- return fs54.readFileSync(p, "utf8");
53874
+ return fs56.readFileSync(p, "utf8");
53598
53875
  } catch {
53599
53876
  return null;
53600
53877
  }
@@ -53633,12 +53910,12 @@ init_store2();
53633
53910
  init_bridge();
53634
53911
 
53635
53912
  // ../core/dist/global-config/runbook-resolver.js
53636
- import * as fs55 from "node:fs";
53913
+ import * as fs57 from "node:fs";
53637
53914
  import * as os33 from "node:os";
53638
- import * as path55 from "node:path";
53915
+ import * as path57 from "node:path";
53639
53916
  function expandTilde(p) {
53640
53917
  if (p === "~" || p.startsWith("~/")) {
53641
- return path55.join(os33.homedir(), p.slice(1));
53918
+ return path57.join(os33.homedir(), p.slice(1));
53642
53919
  }
53643
53920
  return p;
53644
53921
  }
@@ -53650,7 +53927,7 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
53650
53927
  throw new Error(`repo "${repoName}" is referenced by runbook "${runbook.name}" but is not in the registry. Run "olam repos add ${repoName} --path <path>" to register it.`);
53651
53928
  }
53652
53929
  const resolvedPath = expandTilde(entry.path);
53653
- if (!fs55.existsSync(resolvedPath)) {
53930
+ if (!fs57.existsSync(resolvedPath)) {
53654
53931
  throw new Error(`repo "${repoName}" path "${resolvedPath}" no longer exists. Run "olam repos update ${repoName} --path <new-path>" to fix.`);
53655
53932
  }
53656
53933
  }
@@ -53666,19 +53943,19 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
53666
53943
  init_port_validator();
53667
53944
 
53668
53945
  // ../core/dist/world/bootstrap-hooks.js
53669
- import * as fs56 from "node:fs";
53670
- import * as path56 from "node:path";
53946
+ import * as fs58 from "node:fs";
53947
+ import * as path58 from "node:path";
53671
53948
  function runFixtureCopySeeds(seeds, workspacePath) {
53672
53949
  if (!seeds)
53673
53950
  return;
53674
53951
  for (const seed of seeds) {
53675
53952
  if (seed.type !== "fixture-copy")
53676
53953
  continue;
53677
- const srcAbs = path56.resolve(workspacePath, seed.repo, seed.src);
53678
- const destAbs = path56.resolve(workspacePath, seed.repo, seed.dest);
53679
- const destDir = path56.dirname(destAbs);
53680
- fs56.mkdirSync(destDir, { recursive: true });
53681
- fs56.cpSync(srcAbs, destAbs, { recursive: true, force: true });
53954
+ const srcAbs = path58.resolve(workspacePath, seed.repo, seed.src);
53955
+ const destAbs = path58.resolve(workspacePath, seed.repo, seed.dest);
53956
+ const destDir = path58.dirname(destAbs);
53957
+ fs58.mkdirSync(destDir, { recursive: true });
53958
+ fs58.cpSync(srcAbs, destAbs, { recursive: true, force: true });
53682
53959
  }
53683
53960
  }
53684
53961
  async function runSeedHooks(seeds, containerName, servicePortMap, exec) {
@@ -54381,7 +54658,7 @@ ${detail}`);
54381
54658
  runbookSeeds = resolved.seeds;
54382
54659
  }
54383
54660
  const worldId = generateWorldId();
54384
- const workspacePath = path57.join(os34.homedir(), ".olam", "worlds", worldId);
54661
+ const workspacePath = path59.join(os34.homedir(), ".olam", "worlds", worldId);
54385
54662
  const portOffset = this.registry.getNextPortOffset();
54386
54663
  const branch = opts.branchName ?? `olam/${worldId}`;
54387
54664
  const repos = await this.resolveReposWithWorkspace(opts);
@@ -54464,37 +54741,37 @@ ${detail}`);
54464
54741
  if (!repo.path)
54465
54742
  continue;
54466
54743
  const sourceRoot = repo.path.replace(/^~/, os34.homedir());
54467
- const worktreeRoot = path57.join(workspacePath, repo.name);
54468
- if (!fs57.existsSync(sourceRoot) || !fs57.existsSync(worktreeRoot))
54744
+ const worktreeRoot = path59.join(workspacePath, repo.name);
54745
+ if (!fs59.existsSync(sourceRoot) || !fs59.existsSync(worktreeRoot))
54469
54746
  continue;
54470
54747
  let copied = 0;
54471
54748
  for (const pattern of RUNTIME_FILE_PATTERNS) {
54472
54749
  const matches2 = [];
54473
54750
  if (pattern.includes("*")) {
54474
- const [dir, glob] = [path57.dirname(pattern), path57.basename(pattern)];
54475
- const sourceDir = path57.join(sourceRoot, dir);
54476
- if (fs57.existsSync(sourceDir)) {
54751
+ const [dir, glob] = [path59.dirname(pattern), path59.basename(pattern)];
54752
+ const sourceDir = path59.join(sourceRoot, dir);
54753
+ if (fs59.existsSync(sourceDir)) {
54477
54754
  const ext = glob.replace(/^\*+/, "");
54478
54755
  try {
54479
- for (const entry of fs57.readdirSync(sourceDir)) {
54756
+ for (const entry of fs59.readdirSync(sourceDir)) {
54480
54757
  if (ext === "" || entry.endsWith(ext))
54481
- matches2.push(path57.join(dir, entry));
54758
+ matches2.push(path59.join(dir, entry));
54482
54759
  }
54483
54760
  } catch {
54484
54761
  }
54485
54762
  }
54486
- } else if (fs57.existsSync(path57.join(sourceRoot, pattern))) {
54763
+ } else if (fs59.existsSync(path59.join(sourceRoot, pattern))) {
54487
54764
  matches2.push(pattern);
54488
54765
  }
54489
54766
  for (const rel of matches2) {
54490
- const src = path57.join(sourceRoot, rel);
54491
- const dst = path57.join(worktreeRoot, rel);
54767
+ const src = path59.join(sourceRoot, rel);
54768
+ const dst = path59.join(worktreeRoot, rel);
54492
54769
  try {
54493
- const st = fs57.statSync(src);
54770
+ const st = fs59.statSync(src);
54494
54771
  if (!st.isFile())
54495
54772
  continue;
54496
- fs57.mkdirSync(path57.dirname(dst), { recursive: true });
54497
- fs57.copyFileSync(src, dst);
54773
+ fs59.mkdirSync(path59.dirname(dst), { recursive: true });
54774
+ fs59.copyFileSync(src, dst);
54498
54775
  copied++;
54499
54776
  } catch {
54500
54777
  }
@@ -54580,7 +54857,7 @@ ${detail}`);
54580
54857
  }
54581
54858
  const overlayAttachments = [];
54582
54859
  for (const repo of repos) {
54583
- const worldClonePath = path57.join(workspacePath, repo.name);
54860
+ const worldClonePath = path59.join(workspacePath, repo.name);
54584
54861
  try {
54585
54862
  const result = createWorldOverlay({
54586
54863
  workspace: repo.name,
@@ -54635,7 +54912,7 @@ ${detail}`);
54635
54912
  try {
54636
54913
  const hostExec = makeHostExecFn();
54637
54914
  for (const repo of repos) {
54638
- const repoDir = path57.join(workspacePath, repo.name);
54915
+ const repoDir = path59.join(workspacePath, repo.name);
54639
54916
  if (repo.stack && Object.keys(repo.stack).length > 0) {
54640
54917
  preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
54641
54918
  } else {
@@ -54679,10 +54956,10 @@ ${detail}`);
54679
54956
  const worldEnv = {};
54680
54957
  if (opts.task)
54681
54958
  worldEnv.OLAM_TASK = opts.task;
54682
- const r2CredsPath = path57.join(os34.homedir(), ".olam", "r2-credentials.json");
54683
- if (fs57.existsSync(r2CredsPath)) {
54959
+ const r2CredsPath = path59.join(os34.homedir(), ".olam", "r2-credentials.json");
54960
+ if (fs59.existsSync(r2CredsPath)) {
54684
54961
  try {
54685
- const r2Raw = fs57.readFileSync(r2CredsPath, "utf-8").trim();
54962
+ const r2Raw = fs59.readFileSync(r2CredsPath, "utf-8").trim();
54686
54963
  if (r2Raw.length > 0) {
54687
54964
  const r2 = JSON.parse(r2Raw);
54688
54965
  if (typeof r2.account_id === "string")
@@ -54699,10 +54976,10 @@ ${detail}`);
54699
54976
  } catch {
54700
54977
  }
54701
54978
  }
54702
- const keysYamlPath = path57.join(os34.homedir(), ".olam", "keys.yaml");
54703
- if (fs57.existsSync(keysYamlPath)) {
54979
+ const keysYamlPath = path59.join(os34.homedir(), ".olam", "keys.yaml");
54980
+ if (fs59.existsSync(keysYamlPath)) {
54704
54981
  try {
54705
- const keysRaw = fs57.readFileSync(keysYamlPath, "utf-8").trim();
54982
+ const keysRaw = fs59.readFileSync(keysYamlPath, "utf-8").trim();
54706
54983
  if (keysRaw.length > 0) {
54707
54984
  const { default: YAML3 } = await import("yaml");
54708
54985
  const parsed = YAML3.parse(keysRaw);
@@ -54762,10 +55039,10 @@ ${detail}`);
54762
55039
  worldEnv[k] = v;
54763
55040
  }
54764
55041
  for (const { repoName, relativePath, content } of fileWrites) {
54765
- const absPath = path57.join(workspacePath, repoName, relativePath);
55042
+ const absPath = path59.join(workspacePath, repoName, relativePath);
54766
55043
  try {
54767
- fs57.mkdirSync(path57.dirname(absPath), { recursive: true });
54768
- fs57.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
55044
+ fs59.mkdirSync(path59.dirname(absPath), { recursive: true });
55045
+ fs59.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
54769
55046
  mode: 384
54770
55047
  });
54771
55048
  console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
@@ -54942,7 +55219,7 @@ ${detail}`);
54942
55219
  imageDigest: void 0,
54943
55220
  repos: enrichedRepos.map((r) => ({
54944
55221
  name: r.name,
54945
- worktreeDir: path57.join(workspacePath, r.name)
55222
+ worktreeDir: path59.join(workspacePath, r.name)
54946
55223
  }))
54947
55224
  });
54948
55225
  for (const out of restoreResult.outcomes) {
@@ -55048,7 +55325,7 @@ ${detail}`);
55048
55325
  }
55049
55326
  if (opts.task) {
55050
55327
  const allPolicies = repos.flatMap((repo) => {
55051
- const repoWorktree = path57.join(workspacePath, repo.name);
55328
+ const repoWorktree = path59.join(workspacePath, repo.name);
55052
55329
  try {
55053
55330
  return loadPolicies(repoWorktree);
55054
55331
  } catch (err) {
@@ -55061,8 +55338,8 @@ ${detail}`);
55061
55338
  try {
55062
55339
  execSync6(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
55063
55340
  for (const repo of repos) {
55064
- const policiesDir = path57.join(workspacePath, repo.name, ".olam", "policies");
55065
- if (fs57.existsSync(policiesDir)) {
55341
+ const policiesDir = path59.join(workspacePath, repo.name, ".olam", "policies");
55342
+ if (fs59.existsSync(policiesDir)) {
55066
55343
  execSync6(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
55067
55344
  }
55068
55345
  }
@@ -55172,8 +55449,8 @@ ${detail}`);
55172
55449
  } catch {
55173
55450
  }
55174
55451
  try {
55175
- fs57.rmSync(world.workspacePath, { recursive: true, force: true });
55176
- if (fs57.existsSync(world.workspacePath)) {
55452
+ fs59.rmSync(world.workspacePath, { recursive: true, force: true });
55453
+ if (fs59.existsSync(world.workspacePath)) {
55177
55454
  console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
55178
55455
  }
55179
55456
  } catch (err) {
@@ -55283,14 +55560,14 @@ ${detail}`);
55283
55560
  }).filter((r) => r !== void 0);
55284
55561
  }
55285
55562
  transportPlanFile(planFilePath, workspacePath, repoNames) {
55286
- const planContent = fs57.readFileSync(planFilePath, "utf-8");
55287
- const planFileName = path57.basename(planFilePath);
55563
+ const planContent = fs59.readFileSync(planFilePath, "utf-8");
55564
+ const planFileName = path59.basename(planFilePath);
55288
55565
  const targetRepo = repoNames[0];
55289
55566
  if (!targetRepo)
55290
55567
  return;
55291
- const plansDir = path57.join(workspacePath, targetRepo, "docs", "plans");
55292
- fs57.mkdirSync(plansDir, { recursive: true });
55293
- fs57.writeFileSync(path57.join(plansDir, planFileName), planContent);
55568
+ const plansDir = path59.join(workspacePath, targetRepo, "docs", "plans");
55569
+ fs59.mkdirSync(plansDir, { recursive: true });
55570
+ fs59.writeFileSync(path59.join(plansDir, planFileName), planContent);
55294
55571
  }
55295
55572
  resolveServices(repos) {
55296
55573
  const services = [];
@@ -55754,8 +56031,8 @@ import * as http2 from "node:http";
55754
56031
 
55755
56032
  // ../core/dist/dashboard/server.js
55756
56033
  import * as http from "node:http";
55757
- import * as fs58 from "node:fs";
55758
- import * as path58 from "node:path";
56034
+ import * as fs60 from "node:fs";
56035
+ import * as path60 from "node:path";
55759
56036
  import { fileURLToPath as fileURLToPath4 } from "node:url";
55760
56037
 
55761
56038
  // ../core/dist/dashboard/serialize.js
@@ -56090,7 +56367,7 @@ function notFound(res) {
56090
56367
  }
56091
56368
  function openThoughtStore(workspacePath) {
56092
56369
  const dbPath = getWorldDbPath(workspacePath);
56093
- if (!fs58.existsSync(dbPath))
56370
+ if (!fs60.existsSync(dbPath))
56094
56371
  return null;
56095
56372
  return new ThoughtLocalStore(dbPath);
56096
56373
  }
@@ -56261,13 +56538,13 @@ function findSessionInWorld(registry2, sessionId) {
56261
56538
  }
56262
56539
  function createDashboardServer(opts) {
56263
56540
  const { port: port2, registry: registry2 } = opts;
56264
- const thisDir = path58.dirname(fileURLToPath4(import.meta.url));
56265
- const defaultPublicDir = path58.resolve(thisDir, "../../../control-plane/public");
56541
+ const thisDir = path60.dirname(fileURLToPath4(import.meta.url));
56542
+ const defaultPublicDir = path60.resolve(thisDir, "../../../control-plane/public");
56266
56543
  const publicDir = opts.publicDir ?? defaultPublicDir;
56267
- let hasPublicDir = fs58.existsSync(publicDir);
56544
+ let hasPublicDir = fs60.existsSync(publicDir);
56268
56545
  const server = http.createServer((req, res) => {
56269
56546
  if (!hasPublicDir) {
56270
- hasPublicDir = fs58.existsSync(publicDir);
56547
+ hasPublicDir = fs60.existsSync(publicDir);
56271
56548
  }
56272
56549
  const host = req.headers.host ?? `localhost:${port2}`;
56273
56550
  const url3 = new URL(req.url ?? "/", `http://${host}`);
@@ -56541,22 +56818,22 @@ function createDashboardServer(opts) {
56541
56818
  res.end(`<html><body style="font-family:system-ui;padding:2rem"><h1>Olam Dashboard</h1><p>The React app has not been built yet.</p><p>Run <code>npm run build:app</code> in <code>packages/control-plane</code> to build it.</p><p>API routes are available at <code>/api/*</code>.</p></body></html>`);
56542
56819
  return;
56543
56820
  }
56544
- let filePath = path58.join(publicDir, pathname === "/" ? "index.html" : pathname);
56821
+ let filePath = path60.join(publicDir, pathname === "/" ? "index.html" : pathname);
56545
56822
  if (!filePath.startsWith(publicDir)) {
56546
56823
  notFound(res);
56547
56824
  return;
56548
56825
  }
56549
- if (fs58.existsSync(filePath) && fs58.statSync(filePath).isFile()) {
56550
- const ext = path58.extname(filePath);
56826
+ if (fs60.existsSync(filePath) && fs60.statSync(filePath).isFile()) {
56827
+ const ext = path60.extname(filePath);
56551
56828
  const contentType = MIME[ext] ?? "application/octet-stream";
56552
56829
  res.writeHead(200, { "Content-Type": contentType });
56553
- fs58.createReadStream(filePath).pipe(res);
56830
+ fs60.createReadStream(filePath).pipe(res);
56554
56831
  return;
56555
56832
  }
56556
- filePath = path58.join(publicDir, "index.html");
56557
- if (fs58.existsSync(filePath)) {
56833
+ filePath = path60.join(publicDir, "index.html");
56834
+ if (fs60.existsSync(filePath)) {
56558
56835
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
56559
- fs58.createReadStream(filePath).pipe(res);
56836
+ fs60.createReadStream(filePath).pipe(res);
56560
56837
  return;
56561
56838
  }
56562
56839
  notFound(res);
@@ -56566,17 +56843,17 @@ function createDashboardServer(opts) {
56566
56843
  }
56567
56844
 
56568
56845
  // ../core/dist/dashboard/state.js
56569
- import * as fs59 from "node:fs";
56846
+ import * as fs61 from "node:fs";
56570
56847
  import * as os35 from "node:os";
56571
- import * as path59 from "node:path";
56572
- var STATE_PATH = path59.join(os35.homedir(), ".olam", "dashboard.json");
56848
+ import * as path61 from "node:path";
56849
+ var STATE_PATH = path61.join(os35.homedir(), ".olam", "dashboard.json");
56573
56850
  function saveDashboardState(state) {
56574
- fs59.mkdirSync(path59.dirname(STATE_PATH), { recursive: true });
56575
- fs59.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
56851
+ fs61.mkdirSync(path61.dirname(STATE_PATH), { recursive: true });
56852
+ fs61.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
56576
56853
  }
56577
56854
  function loadDashboardState() {
56578
56855
  try {
56579
- const raw = fs59.readFileSync(STATE_PATH, "utf-8");
56856
+ const raw = fs61.readFileSync(STATE_PATH, "utf-8");
56580
56857
  return JSON.parse(raw);
56581
56858
  } catch {
56582
56859
  return null;
@@ -56584,7 +56861,7 @@ function loadDashboardState() {
56584
56861
  }
56585
56862
  function clearDashboardState() {
56586
56863
  try {
56587
- fs59.unlinkSync(STATE_PATH);
56864
+ fs61.unlinkSync(STATE_PATH);
56588
56865
  } catch {
56589
56866
  }
56590
56867
  }
@@ -56864,8 +57141,8 @@ var PleriClient = class {
56864
57141
  };
56865
57142
 
56866
57143
  // ../mcp-server/src/env-loader.ts
56867
- import { readFileSync as readFileSync46, existsSync as existsSync58, statSync as statSync14 } from "node:fs";
56868
- import { join as join62, dirname as dirname31, resolve as resolve15 } from "node:path";
57144
+ import { readFileSync as readFileSync47, existsSync as existsSync60, statSync as statSync15 } from "node:fs";
57145
+ import { join as join64, dirname as dirname31, resolve as resolve15 } from "node:path";
56869
57146
  var PROJECT_MARKERS = [
56870
57147
  ".olam/config.yaml",
56871
57148
  ".olam/config.yml",
@@ -56877,12 +57154,12 @@ function findProjectRoot2(startDir) {
56877
57154
  const root = resolve15("/");
56878
57155
  while (true) {
56879
57156
  for (const marker of PROJECT_MARKERS) {
56880
- if (existsSync58(join62(dir, marker))) return dir;
57157
+ if (existsSync60(join64(dir, marker))) return dir;
56881
57158
  }
56882
- const pkg = join62(dir, "package.json");
56883
- if (existsSync58(pkg)) {
57159
+ const pkg = join64(dir, "package.json");
57160
+ if (existsSync60(pkg)) {
56884
57161
  try {
56885
- const json2 = JSON.parse(readFileSync46(pkg, "utf8"));
57162
+ const json2 = JSON.parse(readFileSync47(pkg, "utf8"));
56886
57163
  const isOlamWorkspace = typeof json2.name === "string" && json2.name.startsWith("@olam/");
56887
57164
  const hasOlamDep = json2.dependencies && Object.keys(json2.dependencies).some((k) => k.startsWith("@olam/")) || json2.devDependencies && Object.keys(json2.devDependencies).some((k) => k.startsWith("@olam/"));
56888
57165
  if (isOlamWorkspace || hasOlamDep) return dir;
@@ -56894,9 +57171,9 @@ function findProjectRoot2(startDir) {
56894
57171
  dir = parent;
56895
57172
  }
56896
57173
  }
56897
- function parseEnvFile(path60) {
57174
+ function parseEnvFile(path62) {
56898
57175
  const out = {};
56899
- const raw = readFileSync46(path60, "utf8");
57176
+ const raw = readFileSync47(path62, "utf8");
56900
57177
  for (const line of raw.split(/\r?\n/)) {
56901
57178
  const trimmed = line.trim();
56902
57179
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -56919,8 +57196,8 @@ function loadProjectEnv(startDir = process.cwd()) {
56919
57196
  const filesRead = [];
56920
57197
  const merged = {};
56921
57198
  for (const name of [".env", ".env.local"]) {
56922
- const p = join62(root, name);
56923
- if (existsSync58(p) && statSync14(p).isFile()) {
57199
+ const p = join64(root, name);
57200
+ if (existsSync60(p) && statSync15(p).isFile()) {
56924
57201
  Object.assign(merged, parseEnvFile(p));
56925
57202
  filesRead.push(p);
56926
57203
  }