@pleri/olam-cli 0.1.160 → 0.1.162

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +11 -0
  2. package/dist/agent-stream/agent-sdk-to-chunks.js +20 -2
  3. package/dist/commands/bootstrap.d.ts +15 -0
  4. package/dist/commands/bootstrap.d.ts.map +1 -1
  5. package/dist/commands/bootstrap.js +58 -5
  6. package/dist/commands/bootstrap.js.map +1 -1
  7. package/dist/commands/flywheel/migrate-overlays.d.ts +1 -0
  8. package/dist/commands/flywheel/migrate-overlays.d.ts.map +1 -1
  9. package/dist/commands/flywheel/migrate-overlays.js +29 -3
  10. package/dist/commands/flywheel/migrate-overlays.js.map +1 -1
  11. package/dist/commands/skills-source.d.ts.map +1 -1
  12. package/dist/commands/skills-source.js +57 -2
  13. package/dist/commands/skills-source.js.map +1 -1
  14. package/dist/commands/skills.d.ts.map +1 -1
  15. package/dist/commands/skills.js +14 -0
  16. package/dist/commands/skills.js.map +1 -1
  17. package/dist/image-digests.json +7 -7
  18. package/dist/index.js +2424 -1781
  19. package/dist/lib/bootstrap-kubernetes.d.ts +42 -0
  20. package/dist/lib/bootstrap-kubernetes.d.ts.map +1 -0
  21. package/dist/lib/bootstrap-kubernetes.js +367 -0
  22. package/dist/lib/bootstrap-kubernetes.js.map +1 -0
  23. package/dist/lib/config.d.ts.map +1 -1
  24. package/dist/lib/config.js +6 -1
  25. package/dist/lib/config.js.map +1 -1
  26. package/dist/mcp-server.js +568 -368
  27. package/hermes-bundle/version.json +1 -1
  28. package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
  29. package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
  30. package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
  31. package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
  32. package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
  33. package/host-cp/observability/grafana-port-forward.sh +283 -0
  34. package/host-cp/observability/kyverno-cardinality-mutate.sh +462 -0
  35. package/host-cp/observability/loki-ingest.sh +253 -0
  36. package/host-cp/observability/prom-no-double-grafana.sh +311 -0
  37. package/host-cp/peripheral-services/helm-values/grafana-values.yaml +159 -0
  38. package/host-cp/peripheral-services/helm-values/kube-prom-stack-values.yaml +229 -0
  39. package/host-cp/peripheral-services/helm-values/kyverno-values.yaml +85 -0
  40. package/host-cp/peripheral-services/helm-values/loki-values.yaml +166 -0
  41. package/host-cp/peripheral-services/helm-values/promtail-staging.yaml +92 -0
  42. package/host-cp/peripheral-services/helm-values/promtail-values.yaml +102 -0
  43. package/host-cp/peripheral-services/helm-values/traefik-values.yaml +73 -0
  44. package/host-cp/peripheral-services/manifests/20-namespace.yaml +6 -0
  45. package/host-cp/peripheral-services/manifests/24-deploy-kg-service.yaml +245 -0
  46. package/host-cp/peripheral-services/manifests/30-traefik-ingressroute-host-cp.yaml +22 -0
  47. package/host-cp/peripheral-services/manifests/40-traefik-ingressroute-kg.yaml +29 -0
  48. package/host-cp/peripheral-services/manifests/50-traefik-ingressroute-agent-memory.yaml +29 -0
  49. package/host-cp/peripheral-services/manifests/60-networkpolicy-ingress.yaml +80 -0
  50. package/host-cp/peripheral-services/manifests/65-networkpolicy-loki-prom-deny.yaml +67 -0
  51. package/host-cp/peripheral-services/manifests/80-grafana-dashboard-configmap.yaml +1349 -0
  52. package/host-cp/peripheral-services/manifests/90-prom-alert-cardinality.yaml +50 -0
  53. package/host-cp/peripheral-services/manifests/91-servicemonitor-host-cp.yaml +70 -0
  54. package/host-cp/peripheral-services/manifests/92-servicemonitor-kg-service.yaml +70 -0
  55. package/host-cp/peripheral-services/manifests/93-servicemonitor-memory-service.yaml +87 -0
  56. package/host-cp/peripheral-services/manifests/95-prom-recording-rules.yaml +108 -0
  57. package/host-cp/peripheral-services/manifests/96-kyverno-cardinality-mutate.yaml +195 -0
  58. package/host-cp/src/plan-chat-service.mjs +147 -1
  59. package/package.json +1 -1
@@ -445,8 +445,8 @@ var init_parseUtil = __esm({
445
445
  init_errors();
446
446
  init_en();
447
447
  makeIssue = (params) => {
448
- const { data, path: path48, errorMaps, issueData } = params;
449
- const fullPath = [...path48, ...issueData.path || []];
448
+ const { data, path: path49, errorMaps, issueData } = params;
449
+ const fullPath = [...path49, ...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, path48, key) {
757
+ constructor(parent, value, path49, key) {
758
758
  this._cachedPath = [];
759
759
  this.parent = parent;
760
760
  this.data = value;
761
- this._path = path48;
761
+ this._path = path49;
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(path48) {
7336
- let input = path48;
7335
+ function removeDotSegments(path49) {
7336
+ let input = path49;
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 [path48, query] = wsComponent.resourceName.split("?");
7536
- wsComponent.path = path48 && path48 !== "/" ? path48 : void 0;
7535
+ const [path49, query] = wsComponent.resourceName.split("?");
7536
+ wsComponent.path = path49 && path49 !== "/" ? path49 : 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, fs48, exportName) {
10898
+ function addFormats(ajv, list, fs49, 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, fs48[f]);
10903
+ ajv.addFormat(f, fs49[f]);
10904
10904
  }
10905
10905
  module.exports = exports = formatsPlugin;
10906
10906
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -11008,7 +11008,7 @@ import YAML from "yaml";
11008
11008
  function bootstrapStepCmd(entry) {
11009
11009
  return typeof entry === "string" ? entry : entry.cmd;
11010
11010
  }
11011
- function refineForbiddenKeys(value, path48, ctx, rejectSource) {
11011
+ function refineForbiddenKeys(value, path49, ctx, rejectSource) {
11012
11012
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
11013
11013
  return;
11014
11014
  }
@@ -11016,12 +11016,12 @@ function refineForbiddenKeys(value, path48, ctx, rejectSource) {
11016
11016
  if (FORBIDDEN_KEYS.has(key)) {
11017
11017
  ctx.addIssue({
11018
11018
  code: external_exports.ZodIssueCode.custom,
11019
- path: [...path48, key],
11019
+ path: [...path49, key],
11020
11020
  message: `forbidden key "${key}" (prototype-pollution surface)`
11021
11021
  });
11022
11022
  continue;
11023
11023
  }
11024
- if (rejectSource && path48.length === 0 && key === "source") {
11024
+ if (rejectSource && path49.length === 0 && key === "source") {
11025
11025
  ctx.addIssue({
11026
11026
  code: external_exports.ZodIssueCode.custom,
11027
11027
  path: ["source"],
@@ -11029,21 +11029,21 @@ function refineForbiddenKeys(value, path48, ctx, rejectSource) {
11029
11029
  });
11030
11030
  continue;
11031
11031
  }
11032
- refineForbiddenKeys(value[key], [...path48, key], ctx, false);
11032
+ refineForbiddenKeys(value[key], [...path49, key], ctx, false);
11033
11033
  }
11034
11034
  }
11035
- function rejectForbiddenKeys(value, path48, rejectSource) {
11035
+ function rejectForbiddenKeys(value, path49, rejectSource) {
11036
11036
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
11037
11037
  return;
11038
11038
  }
11039
11039
  for (const key of Object.keys(value)) {
11040
11040
  if (FORBIDDEN_KEYS.has(key)) {
11041
- throw new Error(`[manifest] ${path48}: forbidden key "${key}" (prototype-pollution surface)`);
11041
+ throw new Error(`[manifest] ${path49}: forbidden key "${key}" (prototype-pollution surface)`);
11042
11042
  }
11043
11043
  if (rejectSource && key === "source") {
11044
- throw new Error(`[manifest] ${path48}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
11044
+ throw new Error(`[manifest] ${path49}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
11045
11045
  }
11046
- rejectForbiddenKeys(value[key], `${path48}.${key}`, false);
11046
+ rejectForbiddenKeys(value[key], `${path49}.${key}`, false);
11047
11047
  }
11048
11048
  }
11049
11049
  function unknownTopLevelKeys(parsed) {
@@ -11895,7 +11895,7 @@ var init_loader = __esm({
11895
11895
  });
11896
11896
 
11897
11897
  // ../core/dist/skill-sources/schema.js
11898
- var SKILL_SOURCE_ID_LENGTH, NAME_PATTERN, URL_PATTERN, SkillSourceSchema;
11898
+ var SKILL_SOURCE_ID_LENGTH, NAME_PATTERN, URL_PATTERN, PREFIX_PATTERN, SkillSourceSchema;
11899
11899
  var init_schema3 = __esm({
11900
11900
  "../core/dist/skill-sources/schema.js"() {
11901
11901
  "use strict";
@@ -11903,13 +11903,24 @@ var init_schema3 = __esm({
11903
11903
  SKILL_SOURCE_ID_LENGTH = 12;
11904
11904
  NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
11905
11905
  URL_PATTERN = /^(?:https?:\/\/|git@|ssh:\/\/|file:\/\/|\/).+/;
11906
+ PREFIX_PATTERN = /^[a-z0-9][a-z0-9_-]{0,38}$/;
11906
11907
  SkillSourceSchema = external_exports.object({
11907
11908
  id: external_exports.string().length(SKILL_SOURCE_ID_LENGTH, `skill-source id must be exactly ${SKILL_SOURCE_ID_LENGTH} chars (sha256-of-url prefix)`).regex(/^[a-f0-9]+$/, "skill-source id must be lowercase hex"),
11908
11909
  name: external_exports.string().regex(NAME_PATTERN, "skill-source name must be ASCII lowercase + digits + dash (1-64 chars, no leading/trailing dash)"),
11909
11910
  gitUrl: external_exports.string().min(1, "gitUrl must not be empty").regex(URL_PATTERN, "gitUrl must look like a git URL (https://, git@, ssh://, file://, or absolute path)"),
11910
11911
  branch: external_exports.string().min(1, "branch must not be empty").default("main"),
11911
11912
  addedAt: external_exports.number().int().nonnegative(),
11912
- lastPulledSha: external_exports.string().regex(/^[a-f0-9]{40}$/, "lastPulledSha must be a 40-char lowercase hex git SHA").optional()
11913
+ lastPulledSha: external_exports.string().regex(/^[a-f0-9]{40}$/, "lastPulledSha must be a 40-char lowercase hex git SHA").optional(),
11914
+ /**
11915
+ * Optional rename prefix. When set, skills+agents from this source are
11916
+ * deployed under `<prefix>:<canonical-name>` (both filename + frontmatter
11917
+ * `name:` rewritten). Source clone + atlas-toolbox member overlays remain
11918
+ * canonical-named on disk; the rename is purely a deploy-time view.
11919
+ * Operator overlay files (`~/.claude/{skills,agents}.overrides/`) MUST
11920
+ * use canonical names; `olam flywheel migrate-overlays --push` enforces
11921
+ * this via the reverse validator.
11922
+ */
11923
+ prefix: external_exports.string().regex(PREFIX_PATTERN, "skill-source prefix must be ASCII lowercase + digits + dash/underscore (1-39 chars, no leading/trailing dash)").optional()
11913
11924
  });
11914
11925
  }
11915
11926
  });
@@ -12437,7 +12448,8 @@ var init_trust_audit_log = __esm({
12437
12448
  "removed",
12438
12449
  "meta-hook-stripped",
12439
12450
  "setup-skill-source-picked",
12440
- "setup-project-sweep-completed"
12451
+ "setup-project-sweep-completed",
12452
+ "prefix-collision"
12441
12453
  ]);
12442
12454
  TrustMethodSchema = external_exports.enum(["flag", "interactive", "auto-reject-tty", "none"]);
12443
12455
  TrustAuditEntrySchema = external_exports.object({
@@ -12550,24 +12562,49 @@ function updateSkillSource(id, patch) {
12550
12562
  throw new Error(`skill-source name "${patch.name}" already in use by id "${collision.id}".`);
12551
12563
  }
12552
12564
  }
12565
+ if (patch.prefix !== void 0 && patch.prefix !== null) {
12566
+ if (!PREFIX_PATTERN2.test(patch.prefix)) {
12567
+ throw new Error(`prefix must match /^[a-z0-9][a-z0-9_-]{0,38}$/ \u2014 got "${patch.prefix}"`);
12568
+ }
12569
+ }
12553
12570
  const existing = config2.skillSources[idx];
12571
+ let prefixUpdate = {};
12572
+ if (patch.prefix === null) {
12573
+ const { prefix: _dropped, ...rest } = existing;
12574
+ void _dropped;
12575
+ const updated2 = {
12576
+ ...rest,
12577
+ ...patch.name !== void 0 ? { name: patch.name } : {},
12578
+ ...patch.branch !== void 0 ? { branch: patch.branch } : {},
12579
+ ...patch.lastPulledSha !== void 0 ? { lastPulledSha: patch.lastPulledSha } : {}
12580
+ };
12581
+ const next2 = [...config2.skillSources];
12582
+ next2[idx] = updated2;
12583
+ writeGlobalConfig({ ...config2, skillSources: next2 });
12584
+ return updated2;
12585
+ } else if (patch.prefix !== void 0) {
12586
+ prefixUpdate = { prefix: patch.prefix };
12587
+ }
12554
12588
  const updated = {
12555
12589
  ...existing,
12556
12590
  ...patch.name !== void 0 ? { name: patch.name } : {},
12557
12591
  ...patch.branch !== void 0 ? { branch: patch.branch } : {},
12558
- ...patch.lastPulledSha !== void 0 ? { lastPulledSha: patch.lastPulledSha } : {}
12592
+ ...patch.lastPulledSha !== void 0 ? { lastPulledSha: patch.lastPulledSha } : {},
12593
+ ...prefixUpdate
12559
12594
  };
12560
12595
  const next = [...config2.skillSources];
12561
12596
  next[idx] = updated;
12562
12597
  writeGlobalConfig({ ...config2, skillSources: next });
12563
12598
  return updated;
12564
12599
  }
12600
+ var PREFIX_PATTERN2;
12565
12601
  var init_store2 = __esm({
12566
12602
  "../core/dist/skill-sources/store.js"() {
12567
12603
  "use strict";
12568
12604
  init_store();
12569
12605
  init_schema3();
12570
12606
  init_trust_audit_log();
12607
+ PREFIX_PATTERN2 = /^[a-z0-9][a-z0-9_-]{0,38}$/;
12571
12608
  }
12572
12609
  });
12573
12610
 
@@ -14865,17 +14902,154 @@ var init_managed_merge = __esm({
14865
14902
  }
14866
14903
  });
14867
14904
 
14868
- // ../core/dist/skill-sync/engine.js
14905
+ // ../core/dist/skill-sync/prefix-rules.js
14906
+ function applyPrefix(name, prefix, otherKnownPrefixes = []) {
14907
+ if (prefix.length === 0) {
14908
+ throw new Error("applyPrefix: prefix must be non-empty");
14909
+ }
14910
+ if (prefix.includes(":")) {
14911
+ throw new Error(`applyPrefix: prefix must not contain ':' (got "${prefix}")`);
14912
+ }
14913
+ if (name.startsWith(`${prefix}:`))
14914
+ return name;
14915
+ for (const other of otherKnownPrefixes) {
14916
+ if (other.length > 0 && name.startsWith(`${other}:`))
14917
+ return name;
14918
+ }
14919
+ return `${prefix}:${name}`;
14920
+ }
14921
+ function rewriteFrontmatterName(content, rewriter) {
14922
+ const text = content.toString("utf-8");
14923
+ const parsed = parseFrontmatter(text);
14924
+ if (Object.keys(parsed.fm).length === 0)
14925
+ return content;
14926
+ const currentName = parsed.fm["name"];
14927
+ if (currentName === void 0)
14928
+ return content;
14929
+ const newName = rewriter(currentName);
14930
+ if (newName === currentName)
14931
+ return content;
14932
+ const nextFm = { ...parsed.fm, name: newName };
14933
+ const rebuilt = serializeFrontmatter(nextFm) + parsed.body;
14934
+ return Buffer.from(rebuilt, "utf-8");
14935
+ }
14936
+ var init_prefix_rules = __esm({
14937
+ "../core/dist/skill-sync/prefix-rules.js"() {
14938
+ "use strict";
14939
+ init_markdown_merger();
14940
+ }
14941
+ });
14942
+
14943
+ // ../core/dist/skill-sync/prefix-deploy.js
14869
14944
  import * as fs30 from "node:fs";
14870
- import * as os18 from "node:os";
14871
14945
  import * as path29 from "node:path";
14946
+ function buildSourcePrefixMap(sources) {
14947
+ const byId = /* @__PURE__ */ new Map();
14948
+ const prefixes = /* @__PURE__ */ new Set();
14949
+ for (const s of sources) {
14950
+ if (s.prefix !== void 0 && s.prefix.length > 0) {
14951
+ byId.set(s.id, s.prefix);
14952
+ prefixes.add(s.prefix);
14953
+ }
14954
+ }
14955
+ return {
14956
+ get: (sourceId) => byId.get(sourceId),
14957
+ registeredPrefixes: Array.from(prefixes)
14958
+ };
14959
+ }
14960
+ function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir2, dryRun) {
14961
+ const result = { rewrittenCount: 0, entries: [] };
14962
+ for (const artifact of baseArtifacts) {
14963
+ if (artifact.kind !== "skill" && artifact.kind !== "agent")
14964
+ continue;
14965
+ const prefix = sourceMap.get(artifact.sourceId);
14966
+ if (prefix === void 0)
14967
+ continue;
14968
+ const canonical = artifact.deployBasename;
14969
+ const otherPrefixes = sourceMap.registeredPrefixes.filter((p) => p !== prefix);
14970
+ const renamed = applyPrefix(canonical, prefix, otherPrefixes);
14971
+ if (renamed === canonical)
14972
+ continue;
14973
+ const renamedFrontmatterName = renamed.replace(/\.md$/, "");
14974
+ if (dryRun) {
14975
+ artifact.deployBasename = renamed;
14976
+ result.rewrittenCount += 1;
14977
+ result.entries.push({
14978
+ sourceId: artifact.sourceId,
14979
+ kind: artifact.kind,
14980
+ canonicalBasename: canonical,
14981
+ renamedBasename: renamed,
14982
+ prefix
14983
+ });
14984
+ continue;
14985
+ }
14986
+ if (artifact.kind === "skill") {
14987
+ const skillMdPath = path29.join(artifact.sourcePath, "SKILL.md");
14988
+ const content = fs30.readFileSync(skillMdPath);
14989
+ const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
14990
+ const managedDir = materializeMergedSkill({
14991
+ sourceId: artifact.sourceId,
14992
+ sourcePath: artifact.sourcePath,
14993
+ deployBasename: renamed,
14994
+ mergedContent: rewritten,
14995
+ claudeDir: claudeDir2
14996
+ });
14997
+ artifact.sourcePath = managedDir;
14998
+ artifact.deployBasename = renamed;
14999
+ } else {
15000
+ const content = artifact.resolvedContent !== void 0 ? artifact.resolvedContent : fs30.readFileSync(artifact.sourcePath);
15001
+ const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
15002
+ artifact.resolvedContent = rewritten;
15003
+ artifact.deployBasename = renamed;
15004
+ }
15005
+ result.rewrittenCount += 1;
15006
+ result.entries.push({
15007
+ sourceId: artifact.sourceId,
15008
+ kind: artifact.kind,
15009
+ canonicalBasename: canonical,
15010
+ renamedBasename: renamed,
15011
+ prefix
15012
+ });
15013
+ }
15014
+ return result;
15015
+ }
15016
+ function detectPrefixCollisions(sources) {
15017
+ const byPrefix = /* @__PURE__ */ new Map();
15018
+ for (const s of sources) {
15019
+ if (s.prefix === void 0 || s.prefix.length === 0)
15020
+ continue;
15021
+ const ids = byPrefix.get(s.prefix) ?? [];
15022
+ ids.push(s.id);
15023
+ byPrefix.set(s.prefix, ids);
15024
+ }
15025
+ const collisions = [];
15026
+ for (const [prefix, ids] of byPrefix.entries()) {
15027
+ if (ids.length < 2)
15028
+ continue;
15029
+ const [winner, ...losers] = ids;
15030
+ collisions.push({ prefix, winnerSourceId: winner, loserSourceIds: losers });
15031
+ }
15032
+ return collisions;
15033
+ }
15034
+ var init_prefix_deploy = __esm({
15035
+ "../core/dist/skill-sync/prefix-deploy.js"() {
15036
+ "use strict";
15037
+ init_prefix_rules();
15038
+ init_managed_merge();
15039
+ }
15040
+ });
15041
+
15042
+ // ../core/dist/skill-sync/engine.js
15043
+ import * as fs31 from "node:fs";
15044
+ import * as os18 from "node:os";
15045
+ import * as path30 from "node:path";
14872
15046
  function resolveAtlasUser(override) {
14873
15047
  if (override)
14874
15048
  return override;
14875
- const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] || path29.join(os18.homedir(), ".claude");
14876
- const f = path29.join(claudeDir2, ".atlas-user");
14877
- if (fs30.existsSync(f)) {
14878
- return fs30.readFileSync(f, "utf-8").trim() || void 0;
15049
+ const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] || path30.join(os18.homedir(), ".claude");
15050
+ const f = path30.join(claudeDir2, ".atlas-user");
15051
+ if (fs31.existsSync(f)) {
15052
+ return fs31.readFileSync(f, "utf-8").trim() || void 0;
14879
15053
  }
14880
15054
  return void 0;
14881
15055
  }
@@ -14887,7 +15061,7 @@ async function syncSkills(opts = {}) {
14887
15061
  const perSource = [];
14888
15062
  for (const source of sources) {
14889
15063
  const clonePath = skillSourceClonePath(source.id);
14890
- if (!fs30.existsSync(clonePath))
15064
+ if (!fs31.existsSync(clonePath))
14891
15065
  continue;
14892
15066
  const { artifacts, subscription } = await withFileLock(clonePath, () => {
14893
15067
  const pinRef = projectOverride?.override.pin?.[source.id];
@@ -14925,9 +15099,15 @@ async function syncSkills(opts = {}) {
14925
15099
  const memberOverlaysEnabled = process.env["OLAM_MEMBER_OVERLAYS"] === "1";
14926
15100
  const baseArtifacts = projectFilteredArtifacts.filter((a) => a.kind !== "overlay");
14927
15101
  const overlayArtifacts = memberOverlaysEnabled ? projectFilteredArtifacts.filter((a) => a.kind === "overlay") : [];
14928
- if (memberOverlaysEnabled && overlayArtifacts.length > 0 && !opts.dryRun) {
15102
+ const sourcePrefixMap = buildSourcePrefixMap(sources);
15103
+ const hasPrefixRewrites = sources.some((s) => s.prefix !== void 0 && s.prefix.length > 0);
15104
+ const willMutateManagedDir = !opts.dryRun && (memberOverlaysEnabled && overlayArtifacts.length > 0 || hasPrefixRewrites);
15105
+ if (willMutateManagedDir) {
14929
15106
  const claude = claudeDir();
14930
15107
  cleanMergedDir(claude);
15108
+ }
15109
+ if (memberOverlaysEnabled && overlayArtifacts.length > 0 && !opts.dryRun) {
15110
+ const claude = claudeDir();
14931
15111
  for (const overlay of overlayArtifacts) {
14932
15112
  if (!overlay.targetKind)
14933
15113
  continue;
@@ -14937,13 +15117,13 @@ async function syncSkills(opts = {}) {
14937
15117
  let baseContent;
14938
15118
  let basePath;
14939
15119
  if (overlay.targetKind === "skill") {
14940
- basePath = path29.join(base.sourcePath, "SKILL.md");
14941
- baseContent = fs30.readFileSync(basePath, "utf-8");
15120
+ basePath = path30.join(base.sourcePath, "SKILL.md");
15121
+ baseContent = fs31.readFileSync(basePath, "utf-8");
14942
15122
  } else {
14943
15123
  basePath = base.sourcePath;
14944
- baseContent = fs30.readFileSync(basePath, "utf-8");
15124
+ baseContent = fs31.readFileSync(basePath, "utf-8");
14945
15125
  }
14946
- const overlayContent = fs30.readFileSync(overlay.sourcePath, "utf-8");
15126
+ const overlayContent = fs31.readFileSync(overlay.sourcePath, "utf-8");
14947
15127
  const label = `${overlay.sourceId}/${overlay.deployBasename}`;
14948
15128
  const mergeResult = mergeMarkdown(baseContent, overlayContent, label, basePath, overlay.sourcePath);
14949
15129
  if ("error" in mergeResult) {
@@ -14967,6 +15147,23 @@ async function syncSkills(opts = {}) {
14967
15147
  }
14968
15148
  const hookFiles = projectFilteredArtifacts.filter((a) => a.kind === "hook").map((a) => a.sourcePath);
14969
15149
  const permissionFiles = projectFilteredArtifacts.filter((a) => a.kind === "permission").map((a) => a.sourcePath);
15150
+ const claudeDirForRewrites = claudeDir();
15151
+ const prefixRewriteResult = applyPrefixRewrites(baseArtifacts, sourcePrefixMap, claudeDirForRewrites, opts.dryRun === true);
15152
+ const prefixCollisions = detectPrefixCollisions(sources);
15153
+ if (!opts.dryRun) {
15154
+ for (const collision of prefixCollisions) {
15155
+ try {
15156
+ appendTrustAudit({
15157
+ gitUrl: "internal:prefix-collision",
15158
+ action: "prefix-collision",
15159
+ trustMethod: "none",
15160
+ sourceId: collision.winnerSourceId,
15161
+ note: `prefix="${collision.prefix}"; winner=${collision.winnerSourceId}; losers=${collision.loserSourceIds.join(",")}`
15162
+ });
15163
+ } catch {
15164
+ }
15165
+ }
15166
+ }
14970
15167
  const summary = {
14971
15168
  sourceCount: sources.length,
14972
15169
  artifactCount: projectFilteredArtifacts.length,
@@ -14977,13 +15174,15 @@ async function syncSkills(opts = {}) {
14977
15174
  deploy: void 0,
14978
15175
  merge: void 0,
14979
15176
  metaHooks: void 0,
14980
- perSource
15177
+ perSource,
15178
+ prefixRewrites: prefixRewriteResult.entries,
15179
+ prefixCollisions
14981
15180
  };
14982
15181
  if (opts.dryRun) {
14983
15182
  summary.collisions = detectCollisions(baseArtifacts).collisions;
14984
15183
  return summary;
14985
15184
  }
14986
- const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] || path29.join(os18.homedir(), ".claude");
15185
+ const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] || path30.join(os18.homedir(), ".claude");
14987
15186
  const overlayReferences = scanOverlayReferences(claudeDirPath, SHIM_TARGETS.map((t) => t.basename));
14988
15187
  summary.deploy = deployArtifacts(baseArtifacts, {
14989
15188
  installedOlamVersion,
@@ -15009,19 +15208,19 @@ async function injectMetaHooksIntoSettings(opts) {
15009
15208
  const result = await withSettingsJsonLock(() => {
15010
15209
  let currentSettings = {};
15011
15210
  let settingsExisted = false;
15012
- if (fs30.existsSync(settingsFile)) {
15211
+ if (fs31.existsSync(settingsFile)) {
15013
15212
  settingsExisted = true;
15014
15213
  try {
15015
- const raw = fs30.readFileSync(settingsFile, "utf-8");
15214
+ const raw = fs31.readFileSync(settingsFile, "utf-8");
15016
15215
  currentSettings = raw.trim() ? JSON.parse(raw) : {};
15017
15216
  } catch {
15018
15217
  try {
15019
- const raw = fs30.readFileSync(settingsFile);
15020
- const bakDir = path29.join(path29.dirname(settingsFile), ".malformed-backups");
15021
- fs30.mkdirSync(bakDir, { recursive: true });
15218
+ const raw = fs31.readFileSync(settingsFile);
15219
+ const bakDir = path30.join(path30.dirname(settingsFile), ".malformed-backups");
15220
+ fs31.mkdirSync(bakDir, { recursive: true });
15022
15221
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
15023
- const bakFile = path29.join(bakDir, `settings.json.malformed.${stamp}.bak`);
15024
- fs30.writeFileSync(bakFile, raw, { mode: 384 });
15222
+ const bakFile = path30.join(bakDir, `settings.json.malformed.${stamp}.bak`);
15223
+ fs31.writeFileSync(bakFile, raw, { mode: 384 });
15025
15224
  snapshotError = `settings.json was malformed; original bytes preserved at ${bakFile}`;
15026
15225
  } catch (bakErr) {
15027
15226
  snapshotError = `settings.json malformed AND .bak write failed: ${bakErr instanceof Error ? bakErr.message : String(bakErr)}`;
@@ -15071,10 +15270,10 @@ async function injectMetaHooksIntoSettings(opts) {
15071
15270
  } catch {
15072
15271
  }
15073
15272
  }
15074
- fs30.mkdirSync(path29.dirname(settingsFile), { recursive: true });
15273
+ fs31.mkdirSync(path30.dirname(settingsFile), { recursive: true });
15075
15274
  const tmpPath = `${settingsFile}.tmp-${process.pid}-${Date.now()}`;
15076
- fs30.writeFileSync(tmpPath, JSON.stringify(inject.nextSettings, null, 2) + "\n");
15077
- fs30.renameSync(tmpPath, settingsFile);
15275
+ fs31.writeFileSync(tmpPath, JSON.stringify(inject.nextSettings, null, 2) + "\n");
15276
+ fs31.renameSync(tmpPath, settingsFile);
15078
15277
  return inject;
15079
15278
  }, { reason: `syncSkills meta-hook injection (mode=${mode})` });
15080
15279
  return {
@@ -15108,23 +15307,24 @@ var init_engine = __esm({
15108
15307
  init_meta_hook_injector();
15109
15308
  init_markdown_merger();
15110
15309
  init_managed_merge();
15310
+ init_prefix_deploy();
15111
15311
  }
15112
15312
  });
15113
15313
 
15114
15314
  // ../core/dist/skill-sync/shadow-backup-manager.js
15115
- import * as fs31 from "node:fs";
15116
- import * as path30 from "node:path";
15315
+ import * as fs32 from "node:fs";
15316
+ import * as path31 from "node:path";
15117
15317
  function listShadowBackups(opts = {}) {
15118
15318
  const claude = opts.claudeDirOverride ?? claudeDir();
15119
15319
  const now = opts.now ?? Date.now();
15120
15320
  const out = [];
15121
15321
  for (const bucket of SHADOW_BACKUP_BUCKETS) {
15122
- const bucketDir = path30.join(claude, bucket);
15123
- if (!fs31.existsSync(bucketDir))
15322
+ const bucketDir = path31.join(claude, bucket);
15323
+ if (!fs32.existsSync(bucketDir))
15124
15324
  continue;
15125
15325
  let entries;
15126
15326
  try {
15127
- entries = fs31.readdirSync(bucketDir);
15327
+ entries = fs32.readdirSync(bucketDir);
15128
15328
  } catch {
15129
15329
  continue;
15130
15330
  }
@@ -15135,10 +15335,10 @@ function listShadowBackups(opts = {}) {
15135
15335
  const epochSeconds = Number.parseInt(match[1], 10);
15136
15336
  if (!Number.isFinite(epochSeconds) || epochSeconds < 0)
15137
15337
  continue;
15138
- const full = path30.join(bucketDir, name);
15338
+ const full = path31.join(bucketDir, name);
15139
15339
  let sizeBytes = 0;
15140
15340
  try {
15141
- const st = fs31.statSync(full);
15341
+ const st = fs32.statSync(full);
15142
15342
  if (st.isDirectory())
15143
15343
  continue;
15144
15344
  sizeBytes = st.size;
@@ -15151,7 +15351,7 @@ function listShadowBackups(opts = {}) {
15151
15351
  bucket,
15152
15352
  basename: name,
15153
15353
  originalBasename,
15154
- originalPath: path30.join(bucketDir, originalBasename),
15354
+ originalPath: path31.join(bucketDir, originalBasename),
15155
15355
  epochSeconds,
15156
15356
  ageMs: now - epochSeconds * 1e3,
15157
15357
  sizeBytes
@@ -15194,7 +15394,7 @@ function pruneShadowBackups(opts) {
15194
15394
  }
15195
15395
  if (!opts.dryRun) {
15196
15396
  try {
15197
- fs31.unlinkSync(b.path);
15397
+ fs32.unlinkSync(b.path);
15198
15398
  } catch {
15199
15399
  skipped.push(b);
15200
15400
  continue;
@@ -15205,24 +15405,24 @@ function pruneShadowBackups(opts) {
15205
15405
  return { deleted, skipped };
15206
15406
  }
15207
15407
  function restoreShadowBackup(opts) {
15208
- const abs = path30.resolve(opts.backupPath);
15209
- if (!fs31.existsSync(abs)) {
15408
+ const abs = path31.resolve(opts.backupPath);
15409
+ if (!fs32.existsSync(abs)) {
15210
15410
  throw new Error(`backup file not found: ${abs}`);
15211
15411
  }
15212
- const basename6 = path30.basename(abs);
15412
+ const basename6 = path31.basename(abs);
15213
15413
  const match = SHADOW_BACKUP_SUFFIX_RE.exec(basename6);
15214
15414
  if (!match) {
15215
15415
  throw new Error(`not a shadow-backup file (basename "${basename6}" does not match \`.shadow-backup-<epoch>\`): ${abs}`);
15216
15416
  }
15217
15417
  const originalBasename = basename6.slice(0, basename6.length - match[0].length);
15218
- const originalPath = path30.join(path30.dirname(abs), originalBasename);
15219
- if (fs31.existsSync(originalPath) && !opts.force) {
15418
+ const originalPath = path31.join(path31.dirname(abs), originalBasename);
15419
+ if (fs32.existsSync(originalPath) && !opts.force) {
15220
15420
  throw new Error(`original path already occupied: ${originalPath}. Move/rename it first OR re-run with --force.`);
15221
15421
  }
15222
- if (opts.force && fs31.existsSync(originalPath)) {
15223
- fs31.unlinkSync(originalPath);
15422
+ if (opts.force && fs32.existsSync(originalPath)) {
15423
+ fs32.unlinkSync(originalPath);
15224
15424
  }
15225
- fs31.renameSync(abs, originalPath);
15425
+ fs32.renameSync(abs, originalPath);
15226
15426
  return { restoredTo: originalPath };
15227
15427
  }
15228
15428
  var SHADOW_BACKUP_BUCKETS, SHADOW_BACKUP_SUFFIX_RE;
@@ -15236,14 +15436,14 @@ var init_shadow_backup_manager = __esm({
15236
15436
  });
15237
15437
 
15238
15438
  // ../core/dist/skill-sources/doctor-checks.js
15239
- import * as fs32 from "node:fs";
15240
- import * as path31 from "node:path";
15439
+ import * as fs33 from "node:fs";
15440
+ import * as path32 from "node:path";
15241
15441
  import * as os19 from "node:os";
15242
15442
  function claudeDirInternal3() {
15243
15443
  const override = process.env["OLAM_CLAUDE_DIR"];
15244
15444
  if (override && override.length > 0)
15245
15445
  return override;
15246
- return path31.join(os19.homedir(), ".claude");
15446
+ return path32.join(os19.homedir(), ".claude");
15247
15447
  }
15248
15448
  function checkStateFileParse() {
15249
15449
  const filePath = globalConfigPath();
@@ -15252,11 +15452,11 @@ function checkStateFileParse() {
15252
15452
  healthy: true,
15253
15453
  description: `~/.olam state file (${filePath})`
15254
15454
  };
15255
- if (!fs32.existsSync(filePath)) {
15455
+ if (!fs33.existsSync(filePath)) {
15256
15456
  result.details = ["(file does not yet exist \u2014 will be created on first write)"];
15257
15457
  return result;
15258
15458
  }
15259
- const raw = fs32.readFileSync(filePath, "utf-8");
15459
+ const raw = fs33.readFileSync(filePath, "utf-8");
15260
15460
  let parsed;
15261
15461
  try {
15262
15462
  parsed = JSON.parse(raw);
@@ -15266,8 +15466,8 @@ function checkStateFileParse() {
15266
15466
  result.details = [err instanceof Error ? err.message : String(err)];
15267
15467
  result.repair = () => {
15268
15468
  const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
15269
- fs32.renameSync(filePath, aside);
15270
- fs32.writeFileSync(filePath, JSON.stringify({ schemaVersion: 1, repos: [], runbooks: [], skillSources: [] }, null, 2));
15469
+ fs33.renameSync(filePath, aside);
15470
+ fs33.writeFileSync(filePath, JSON.stringify({ schemaVersion: 1, repos: [], runbooks: [], skillSources: [] }, null, 2));
15271
15471
  };
15272
15472
  return result;
15273
15473
  }
@@ -15278,7 +15478,7 @@ function checkStateFileParse() {
15278
15478
  result.details = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
15279
15479
  result.repair = () => {
15280
15480
  const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
15281
- fs32.copyFileSync(filePath, aside);
15481
+ fs33.copyFileSync(filePath, aside);
15282
15482
  const base = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
15283
15483
  const next = {
15284
15484
  ...base,
@@ -15287,7 +15487,7 @@ function checkStateFileParse() {
15287
15487
  runbooks: [],
15288
15488
  skillSources: []
15289
15489
  };
15290
- fs32.writeFileSync(filePath, JSON.stringify(next, null, 2));
15490
+ fs33.writeFileSync(filePath, JSON.stringify(next, null, 2));
15291
15491
  };
15292
15492
  return result;
15293
15493
  }
@@ -15298,16 +15498,16 @@ function checkDanglingSymlinks() {
15298
15498
  const buckets = ["commands", "agents", "skills", "scripts", "rules"];
15299
15499
  const dangling = [];
15300
15500
  for (const bucket of buckets) {
15301
- const dir = path31.join(claude, bucket);
15302
- if (!fs32.existsSync(dir))
15501
+ const dir = path32.join(claude, bucket);
15502
+ if (!fs33.existsSync(dir))
15303
15503
  continue;
15304
- for (const name of fs32.readdirSync(dir)) {
15305
- const linkPath = path31.join(dir, name);
15504
+ for (const name of fs33.readdirSync(dir)) {
15505
+ const linkPath = path32.join(dir, name);
15306
15506
  try {
15307
- const lst = fs32.lstatSync(linkPath);
15507
+ const lst = fs33.lstatSync(linkPath);
15308
15508
  if (!lst.isSymbolicLink())
15309
15509
  continue;
15310
- if (!fs32.existsSync(linkPath)) {
15510
+ if (!fs33.existsSync(linkPath)) {
15311
15511
  dangling.push(linkPath);
15312
15512
  }
15313
15513
  } catch {
@@ -15325,7 +15525,7 @@ function checkDanglingSymlinks() {
15325
15525
  result.repair = () => {
15326
15526
  for (const p of dangling) {
15327
15527
  try {
15328
- fs32.unlinkSync(p);
15528
+ fs33.unlinkSync(p);
15329
15529
  } catch {
15330
15530
  }
15331
15531
  }
@@ -15340,19 +15540,19 @@ function checkOrphanedSnapshots() {
15340
15540
  healthy: true,
15341
15541
  description: `orphaned migration snapshots under ${dir}`
15342
15542
  };
15343
- if (!fs32.existsSync(dir)) {
15543
+ if (!fs33.existsSync(dir)) {
15344
15544
  return result;
15345
15545
  }
15346
15546
  const orphans = [];
15347
- for (const name of fs32.readdirSync(dir)) {
15547
+ for (const name of fs33.readdirSync(dir)) {
15348
15548
  if (!name.endsWith(".json"))
15349
15549
  continue;
15350
- const full = path31.join(dir, name);
15550
+ const full = path32.join(dir, name);
15351
15551
  try {
15352
- const stat = fs32.statSync(full);
15552
+ const stat = fs33.statSync(full);
15353
15553
  if (!stat.isFile())
15354
15554
  continue;
15355
- const raw = fs32.readFileSync(full, "utf-8");
15555
+ const raw = fs33.readFileSync(full, "utf-8");
15356
15556
  let parsed;
15357
15557
  try {
15358
15558
  parsed = JSON.parse(raw);
@@ -15377,7 +15577,7 @@ function checkOrphanedSnapshots() {
15377
15577
  result.repair = () => {
15378
15578
  for (const o of orphans) {
15379
15579
  try {
15380
- fs32.unlinkSync(o.path);
15580
+ fs33.unlinkSync(o.path);
15381
15581
  } catch {
15382
15582
  }
15383
15583
  }
@@ -15392,12 +15592,12 @@ function checkSentinelDrift() {
15392
15592
  healthy: true,
15393
15593
  description: `olam-skills sentinel block in ${filePath}`
15394
15594
  };
15395
- if (!fs32.existsSync(filePath)) {
15595
+ if (!fs33.existsSync(filePath)) {
15396
15596
  return result;
15397
15597
  }
15398
15598
  let parsed;
15399
15599
  try {
15400
- parsed = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
15600
+ parsed = JSON.parse(fs33.readFileSync(filePath, "utf-8"));
15401
15601
  } catch {
15402
15602
  return result;
15403
15603
  }
@@ -15438,7 +15638,7 @@ function checkSentinelDrift() {
15438
15638
  backupSettings();
15439
15639
  } catch {
15440
15640
  }
15441
- const next = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
15641
+ const next = JSON.parse(fs33.readFileSync(filePath, "utf-8"));
15442
15642
  if (!next.hooks)
15443
15643
  return;
15444
15644
  for (const stage of Object.keys(next.hooks)) {
@@ -15461,7 +15661,7 @@ function checkSentinelDrift() {
15461
15661
  return bad === void 0;
15462
15662
  });
15463
15663
  }
15464
- fs32.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
15664
+ fs33.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
15465
15665
  };
15466
15666
  }
15467
15667
  return result;
@@ -15485,8 +15685,8 @@ function checkMemberNameMissing() {
15485
15685
  return result;
15486
15686
  }
15487
15687
  const claudeDir2 = claudeDirInternal3();
15488
- const atlasUserPath = path31.join(claudeDir2, ".atlas-user");
15489
- const value = fs32.existsSync(atlasUserPath) ? fs32.readFileSync(atlasUserPath, "utf-8").trim() : "";
15688
+ const atlasUserPath = path32.join(claudeDir2, ".atlas-user");
15689
+ const value = fs33.existsSync(atlasUserPath) ? fs33.readFileSync(atlasUserPath, "utf-8").trim() : "";
15490
15690
  if (value.length > 0) {
15491
15691
  result.details = [`atlas-user: ${value}`];
15492
15692
  return result;
@@ -15494,10 +15694,10 @@ function checkMemberNameMissing() {
15494
15694
  result.healthy = false;
15495
15695
  result.issue = "atlas-toolbox source registered but ~/.claude/.atlas-user not set";
15496
15696
  const clonePath = skillSourceClonePath(atlasSource.id);
15497
- const membersDir = path31.join(clonePath, "members");
15498
- const existing = fs32.existsSync(membersDir) ? fs32.readdirSync(membersDir).filter((e) => {
15697
+ const membersDir = path32.join(clonePath, "members");
15698
+ const existing = fs33.existsSync(membersDir) ? fs33.readdirSync(membersDir).filter((e) => {
15499
15699
  try {
15500
- return fs32.statSync(path31.join(membersDir, e)).isDirectory();
15700
+ return fs33.statSync(path32.join(membersDir, e)).isDirectory();
15501
15701
  } catch {
15502
15702
  return false;
15503
15703
  }
@@ -15511,8 +15711,8 @@ function checkMemberNameMissing() {
15511
15711
  }
15512
15712
  function checkMemberOverlayDrift() {
15513
15713
  const claudeDir2 = claudeDirInternal3();
15514
- const atlasUserPath = path31.join(claudeDir2, ".atlas-user");
15515
- const atlasUser = fs32.existsSync(atlasUserPath) ? fs32.readFileSync(atlasUserPath, "utf-8").trim() : "";
15714
+ const atlasUserPath = path32.join(claudeDir2, ".atlas-user");
15715
+ const atlasUser = fs33.existsSync(atlasUserPath) ? fs33.readFileSync(atlasUserPath, "utf-8").trim() : "";
15516
15716
  if (atlasUser.length === 0) {
15517
15717
  return [];
15518
15718
  }
@@ -15528,26 +15728,26 @@ function checkMemberOverlayDrift() {
15528
15728
  const clonePath = skillSourceClonePath(atlasSource.id);
15529
15729
  const results = [];
15530
15730
  for (const kind of ["skills", "agents"]) {
15531
- const localRoot = path31.join(claudeDir2, `${kind}.overrides`);
15532
- if (!fs32.existsSync(localRoot))
15731
+ const localRoot = path32.join(claudeDir2, `${kind}.overrides`);
15732
+ if (!fs33.existsSync(localRoot))
15533
15733
  continue;
15534
15734
  let entries;
15535
15735
  try {
15536
- entries = fs32.readdirSync(localRoot);
15736
+ entries = fs33.readdirSync(localRoot);
15537
15737
  } catch {
15538
15738
  continue;
15539
15739
  }
15540
15740
  for (const entry of entries) {
15541
- const localFile = path31.join(localRoot, entry);
15741
+ const localFile = path32.join(localRoot, entry);
15542
15742
  let stat;
15543
15743
  try {
15544
- stat = fs32.statSync(localFile);
15744
+ stat = fs33.statSync(localFile);
15545
15745
  } catch {
15546
15746
  continue;
15547
15747
  }
15548
15748
  if (!stat.isFile())
15549
15749
  continue;
15550
- const cloneFile = path31.join(clonePath, "members", atlasUser, `${kind}.overrides`, entry);
15750
+ const cloneFile = path32.join(clonePath, "members", atlasUser, `${kind}.overrides`, entry);
15551
15751
  const localSha = sha256OfPath(localFile);
15552
15752
  const cloneSha = sha256OfPath(cloneFile);
15553
15753
  if (localSha === cloneSha) {
@@ -15960,10 +16160,10 @@ function mergeDefs(...defs) {
15960
16160
  function cloneDef(schema) {
15961
16161
  return mergeDefs(schema._zod.def);
15962
16162
  }
15963
- function getElementAtPath(obj, path48) {
15964
- if (!path48)
16163
+ function getElementAtPath(obj, path49) {
16164
+ if (!path49)
15965
16165
  return obj;
15966
- return path48.reduce((acc, key) => acc?.[key], obj);
16166
+ return path49.reduce((acc, key) => acc?.[key], obj);
15967
16167
  }
15968
16168
  function promiseAllObject(promisesObj) {
15969
16169
  const keys = Object.keys(promisesObj);
@@ -16372,11 +16572,11 @@ function explicitlyAborted(x, startIndex = 0) {
16372
16572
  }
16373
16573
  return false;
16374
16574
  }
16375
- function prefixIssues(path48, issues) {
16575
+ function prefixIssues(path49, issues) {
16376
16576
  return issues.map((iss) => {
16377
16577
  var _a3;
16378
16578
  (_a3 = iss).path ?? (_a3.path = []);
16379
- iss.path.unshift(path48);
16579
+ iss.path.unshift(path49);
16380
16580
  return iss;
16381
16581
  });
16382
16582
  }
@@ -16523,16 +16723,16 @@ function flattenError(error2, mapper = (issue2) => issue2.message) {
16523
16723
  }
16524
16724
  function formatError(error2, mapper = (issue2) => issue2.message) {
16525
16725
  const fieldErrors = { _errors: [] };
16526
- const processError = (error3, path48 = []) => {
16726
+ const processError = (error3, path49 = []) => {
16527
16727
  for (const issue2 of error3.issues) {
16528
16728
  if (issue2.code === "invalid_union" && issue2.errors.length) {
16529
- issue2.errors.map((issues) => processError({ issues }, [...path48, ...issue2.path]));
16729
+ issue2.errors.map((issues) => processError({ issues }, [...path49, ...issue2.path]));
16530
16730
  } else if (issue2.code === "invalid_key") {
16531
- processError({ issues: issue2.issues }, [...path48, ...issue2.path]);
16731
+ processError({ issues: issue2.issues }, [...path49, ...issue2.path]);
16532
16732
  } else if (issue2.code === "invalid_element") {
16533
- processError({ issues: issue2.issues }, [...path48, ...issue2.path]);
16733
+ processError({ issues: issue2.issues }, [...path49, ...issue2.path]);
16534
16734
  } else {
16535
- const fullpath = [...path48, ...issue2.path];
16735
+ const fullpath = [...path49, ...issue2.path];
16536
16736
  if (fullpath.length === 0) {
16537
16737
  fieldErrors._errors.push(mapper(issue2));
16538
16738
  } else {
@@ -27171,8 +27371,8 @@ var AuthClient = class {
27171
27371
  throw new Error(`failed to report rate-limit for ${accountId} (HTTP ${res.status})`);
27172
27372
  }
27173
27373
  }
27174
- async request(method, path48, body, attempt = 0) {
27175
- const url2 = `${this.baseUrl}${path48}`;
27374
+ async request(method, path49, body, attempt = 0) {
27375
+ const url2 = `${this.baseUrl}${path49}`;
27176
27376
  const controller = new AbortController();
27177
27377
  const timer = setTimeout(() => controller.abort(), this.timeoutMs);
27178
27378
  const headers = {};
@@ -27190,7 +27390,7 @@ var AuthClient = class {
27190
27390
  } catch (err) {
27191
27391
  if (attempt < RETRY_COUNT && isTransient(err)) {
27192
27392
  await sleep(RETRY_BACKOFF_MS * (attempt + 1));
27193
- return this.request(method, path48, body, attempt + 1);
27393
+ return this.request(method, path49, body, attempt + 1);
27194
27394
  }
27195
27395
  throw err;
27196
27396
  } finally {
@@ -28044,12 +28244,12 @@ function register3(server, _ctx, _initError) {
28044
28244
  registry2.close();
28045
28245
  }
28046
28246
  try {
28047
- const { default: fs48 } = await import("node:fs");
28247
+ const { default: fs49 } = await import("node:fs");
28048
28248
  const { default: os28 } = await import("node:os");
28049
- const { default: path48 } = await import("node:path");
28050
- const tokenPath = path48.join(os28.homedir(), ".olam", "host-cp.token");
28051
- if (fs48.existsSync(tokenPath)) {
28052
- const token = fs48.readFileSync(tokenPath, "utf-8").trim();
28249
+ const { default: path49 } = await import("node:path");
28250
+ const tokenPath = path49.join(os28.homedir(), ".olam", "host-cp.token");
28251
+ if (fs49.existsSync(tokenPath)) {
28252
+ const token = fs49.readFileSync(tokenPath, "utf-8").trim();
28053
28253
  await fetch("http://127.0.0.1:19000/api/admin/world-pr", {
28054
28254
  method: "POST",
28055
28255
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
@@ -28469,10 +28669,10 @@ function extractMcpConfig(claudeJsonPath) {
28469
28669
  }
28470
28670
  return { mcpServers, secrets };
28471
28671
  }
28472
- function readOptional(path48) {
28473
- if (!existsSync6(path48)) return null;
28672
+ function readOptional(path49) {
28673
+ if (!existsSync6(path49)) return null;
28474
28674
  try {
28475
- return readFileSync5(path48, "utf8");
28675
+ return readFileSync5(path49, "utf8");
28476
28676
  } catch {
28477
28677
  return null;
28478
28678
  }
@@ -29918,8 +30118,8 @@ var CloudflareProvider = class extends ComputeProvider {
29918
30118
  // -----------------------------------------------------------------------
29919
30119
  // Internal fetch helper
29920
30120
  // -----------------------------------------------------------------------
29921
- async request(path48, method, body) {
29922
- const url2 = `${this.config.workerUrl}${path48}`;
30121
+ async request(path49, method, body) {
30122
+ const url2 = `${this.config.workerUrl}${path49}`;
29923
30123
  const bearer = await this.config.mintToken();
29924
30124
  const headers = {
29925
30125
  Authorization: `Bearer ${bearer}`
@@ -32370,10 +32570,10 @@ async function writeManifest(args) {
32370
32570
  capturedAt: args.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
32371
32571
  shots: entries
32372
32572
  };
32373
- const path48 = join13(args.outDir, "manifest.json");
32374
- await writeFile(path48, `${JSON.stringify(manifest, null, 2)}
32573
+ const path49 = join13(args.outDir, "manifest.json");
32574
+ await writeFile(path49, `${JSON.stringify(manifest, null, 2)}
32375
32575
  `, "utf8");
32376
- return { path: path48, manifest };
32576
+ return { path: path49, manifest };
32377
32577
  }
32378
32578
 
32379
32579
  // ../mcp-server/src/tools/_capture/proxy.ts
@@ -32627,9 +32827,9 @@ async function startProxy(opts) {
32627
32827
  const liveCompiled = verified.allowedPaths.map(compileGlob);
32628
32828
  const target = parseRequestTarget(req);
32629
32829
  if (!target) return httpReject(400, "invalid_target");
32630
- const path48 = target.pathname;
32631
- if (!liveCompiled.some((re) => re.test(path48))) {
32632
- return httpReject(403, "outside_allow_list", { path: path48 });
32830
+ const path49 = target.pathname;
32831
+ if (!liveCompiled.some((re) => re.test(path49))) {
32832
+ return httpReject(403, "outside_allow_list", { path: path49 });
32633
32833
  }
32634
32834
  const headerWorld = req.headers[WORLD_ASSERT_HEADER];
32635
32835
  const headerWorldStr = typeof headerWorld === "string" ? headerWorld : Array.isArray(headerWorld) && headerWorld.length > 0 ? headerWorld[0] : void 0;
@@ -33408,14 +33608,14 @@ async function runShot(browser, shot, outDir, format, jpegQuality, allowEval, as
33408
33608
  await page.waitForTimeout(shot.afterLoadMs);
33409
33609
  }
33410
33610
  const ext = format === "jpeg" ? "jpg" : "png";
33411
- const path48 = join14(outDir, `${shot.name}.${ext}`);
33611
+ const path49 = join14(outDir, `${shot.name}.${ext}`);
33412
33612
  await page.screenshot({
33413
- path: path48,
33613
+ path: path49,
33414
33614
  type: format,
33415
33615
  ...format === "jpeg" ? { quality: jpegQuality } : {},
33416
33616
  fullPage: false
33417
33617
  });
33418
- return { name: shot.name, path: path48, urlRedacted: redactUrl(shot.url), viewport };
33618
+ return { name: shot.name, path: path49, urlRedacted: redactUrl(shot.url), viewport };
33419
33619
  } finally {
33420
33620
  await context.close();
33421
33621
  }
@@ -33859,12 +34059,12 @@ function openUrl(url2) {
33859
34059
  var HOST_CP_URL = "http://127.0.0.1:19000";
33860
34060
  async function readHostCpToken2() {
33861
34061
  try {
33862
- const { default: fs48 } = await import("node:fs");
34062
+ const { default: fs49 } = await import("node:fs");
33863
34063
  const { default: os28 } = await import("node:os");
33864
- const { default: path48 } = await import("node:path");
33865
- const tp = path48.join(os28.homedir(), ".olam", "host-cp.token");
33866
- if (!fs48.existsSync(tp)) return { token: null };
33867
- return { token: fs48.readFileSync(tp, "utf-8").trim() };
34064
+ const { default: path49 } = await import("node:path");
34065
+ const tp = path49.join(os28.homedir(), ".olam", "host-cp.token");
34066
+ if (!fs49.existsSync(tp)) return { token: null };
34067
+ return { token: fs49.readFileSync(tp, "utf-8").trim() };
33868
34068
  } catch {
33869
34069
  return { token: null };
33870
34070
  }
@@ -34124,9 +34324,9 @@ function register22(server, _ctx, _initError) {
34124
34324
  description: external_exports.string().optional().describe("Optional human-readable description."),
34125
34325
  defaultBranch: external_exports.string().optional().describe("Default branch name (e.g. main).")
34126
34326
  },
34127
- async ({ name, path: path48, description, defaultBranch }) => {
34327
+ async ({ name, path: path49, description, defaultBranch }) => {
34128
34328
  try {
34129
- const entry = addRepo({ name, path: path48, description, defaultBranch });
34329
+ const entry = addRepo({ name, path: path49, description, defaultBranch });
34130
34330
  return {
34131
34331
  content: [{
34132
34332
  type: "text",
@@ -34167,9 +34367,9 @@ function register22(server, _ctx, _initError) {
34167
34367
  description: external_exports.string().optional().describe("New description."),
34168
34368
  defaultBranch: external_exports.string().optional().describe("New default branch.")
34169
34369
  },
34170
- async ({ name, path: path48, description, defaultBranch }) => {
34370
+ async ({ name, path: path49, description, defaultBranch }) => {
34171
34371
  try {
34172
- const entry = updateRepo(name, { path: path48, description, defaultBranch });
34372
+ const entry = updateRepo(name, { path: path49, description, defaultBranch });
34173
34373
  return {
34174
34374
  content: [{
34175
34375
  type: "text",
@@ -34190,15 +34390,15 @@ __export(process_port_exports, {
34190
34390
  resolveHostCpToken: () => resolveHostCpToken
34191
34391
  });
34192
34392
  init_v3();
34193
- import fs33 from "node:fs";
34393
+ import fs34 from "node:fs";
34194
34394
  import os20 from "node:os";
34195
- import path32 from "node:path";
34395
+ import path33 from "node:path";
34196
34396
  var HOST_CP_BASE = "http://127.0.0.1:19000";
34197
34397
  function resolveHostCpToken() {
34198
34398
  const envToken = process.env["OLAM_HOST_CP_TOKEN"];
34199
34399
  if (envToken) return envToken;
34200
- const tokenPath = path32.join(os20.homedir(), ".olam", "host-cp.token");
34201
- if (fs33.existsSync(tokenPath)) return fs33.readFileSync(tokenPath, "utf-8").trim();
34400
+ const tokenPath = path33.join(os20.homedir(), ".olam", "host-cp.token");
34401
+ if (fs34.existsSync(tokenPath)) return fs34.readFileSync(tokenPath, "utf-8").trim();
34202
34402
  return null;
34203
34403
  }
34204
34404
  function tokenMissingError() {
@@ -34630,8 +34830,8 @@ __export(skills_exports, {
34630
34830
  });
34631
34831
  init_v3();
34632
34832
  init_skill_sources();
34633
- import * as fs34 from "node:fs";
34634
- import * as path33 from "node:path";
34833
+ import * as fs35 from "node:fs";
34834
+ import * as path34 from "node:path";
34635
34835
  function asMessage8(err) {
34636
34836
  return err instanceof Error ? err.message : String(err);
34637
34837
  }
@@ -34654,14 +34854,14 @@ function listDeployed() {
34654
34854
  );
34655
34855
  const entries = [];
34656
34856
  for (const bucket of ["skills", "agents", "scripts", "rules", "commands"]) {
34657
- const bucketDir = path33.join(dir, bucket);
34658
- if (!fs34.existsSync(bucketDir)) continue;
34659
- for (const name of fs34.readdirSync(bucketDir)) {
34660
- const full = path33.join(bucketDir, name);
34857
+ const bucketDir = path34.join(dir, bucket);
34858
+ if (!fs35.existsSync(bucketDir)) continue;
34859
+ for (const name of fs35.readdirSync(bucketDir)) {
34860
+ const full = path34.join(bucketDir, name);
34661
34861
  try {
34662
- const stat = fs34.lstatSync(full);
34862
+ const stat = fs35.lstatSync(full);
34663
34863
  if (!stat.isSymbolicLink()) continue;
34664
- const target = fs34.readlinkSync(full);
34864
+ const target = fs35.readlinkSync(full);
34665
34865
  let sourceId;
34666
34866
  for (const [clonePath, id] of sourcePaths.entries()) {
34667
34867
  if (target.startsWith(clonePath)) {
@@ -34757,8 +34957,8 @@ function port() {
34757
34957
  const n = Number.parseInt(env, 10);
34758
34958
  return Number.isFinite(n) && n > 0 ? n : KG_SERVICE_PORT_DEFAULT;
34759
34959
  }
34760
- function url(path48) {
34761
- return `http://127.0.0.1:${port()}${path48}`;
34960
+ function url(path49) {
34961
+ return `http://127.0.0.1:${port()}${path49}`;
34762
34962
  }
34763
34963
  function kgServiceHealthUrl() {
34764
34964
  return url("/health");
@@ -34957,8 +35157,8 @@ __export(kg_install_hook_exports, {
34957
35157
  });
34958
35158
  init_v3();
34959
35159
  init_merge_settings();
34960
- import * as fs35 from "node:fs";
34961
- import * as path34 from "node:path";
35160
+ import * as fs36 from "node:fs";
35161
+ import * as path35 from "node:path";
34962
35162
  import * as os21 from "node:os";
34963
35163
 
34964
35164
  // ../core/dist/kg/hook-template.js
@@ -35009,10 +35209,10 @@ function buildHookMatcherEntry(opts) {
35009
35209
  // ../mcp-server/src/tools/kg-install-hook.ts
35010
35210
  function settingsPathFor2(scope, projectPath) {
35011
35211
  if (scope === "user") {
35012
- return path34.join(os21.homedir(), ".claude", "settings.json");
35212
+ return path35.join(os21.homedir(), ".claude", "settings.json");
35013
35213
  }
35014
35214
  const root = projectPath ?? process.cwd();
35015
- return path34.join(root, ".claude", "settings.json");
35215
+ return path35.join(root, ".claude", "settings.json");
35016
35216
  }
35017
35217
  function register29(server, _ctx, _initError) {
35018
35218
  server.tool(
@@ -35026,12 +35226,12 @@ function register29(server, _ctx, _initError) {
35026
35226
  const scope = params.scope === "user" ? "user" : "project";
35027
35227
  const filePath = settingsPathFor2(scope, params.projectPath);
35028
35228
  try {
35029
- fs35.mkdirSync(path34.dirname(filePath), { recursive: true });
35229
+ fs36.mkdirSync(path35.dirname(filePath), { recursive: true });
35030
35230
  let backupPath = null;
35031
- if (fs35.existsSync(filePath)) {
35231
+ if (fs36.existsSync(filePath)) {
35032
35232
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
35033
35233
  backupPath = `${filePath}.olam-bak.${ts}`;
35034
- fs35.copyFileSync(filePath, backupPath);
35234
+ fs36.copyFileSync(filePath, backupPath);
35035
35235
  }
35036
35236
  const result = mergeHomeSettingsJson(filePath, {
35037
35237
  ensureHook: {
@@ -35042,7 +35242,7 @@ function register29(server, _ctx, _initError) {
35042
35242
  });
35043
35243
  if (result.status === "already-present" && backupPath) {
35044
35244
  try {
35045
- fs35.unlinkSync(backupPath);
35245
+ fs36.unlinkSync(backupPath);
35046
35246
  } catch {
35047
35247
  }
35048
35248
  }
@@ -35086,15 +35286,15 @@ __export(kg_uninstall_hook_exports, {
35086
35286
  register: () => register30
35087
35287
  });
35088
35288
  init_v3();
35089
- import * as fs36 from "node:fs";
35090
- import * as path35 from "node:path";
35289
+ import * as fs37 from "node:fs";
35290
+ import * as path36 from "node:path";
35091
35291
  import * as os22 from "node:os";
35092
35292
  function settingsPathFor3(scope, projectPath) {
35093
35293
  if (scope === "user") {
35094
- return path35.join(os22.homedir(), ".claude", "settings.json");
35294
+ return path36.join(os22.homedir(), ".claude", "settings.json");
35095
35295
  }
35096
35296
  const root = projectPath ?? process.cwd();
35097
- return path35.join(root, ".claude", "settings.json");
35297
+ return path36.join(root, ".claude", "settings.json");
35098
35298
  }
35099
35299
  function dropSentinel(matchers) {
35100
35300
  let changed = false;
@@ -35128,7 +35328,7 @@ function register30(server, _ctx, _initError) {
35128
35328
  const scope = params.scope === "user" ? "user" : "project";
35129
35329
  const filePath = settingsPathFor3(scope, params.projectPath);
35130
35330
  try {
35131
- if (!fs36.existsSync(filePath)) {
35331
+ if (!fs37.existsSync(filePath)) {
35132
35332
  return {
35133
35333
  content: [
35134
35334
  {
@@ -35142,7 +35342,7 @@ function register30(server, _ctx, _initError) {
35142
35342
  ]
35143
35343
  };
35144
35344
  }
35145
- const raw = fs36.readFileSync(filePath, "utf-8");
35345
+ const raw = fs37.readFileSync(filePath, "utf-8");
35146
35346
  const settings = raw.trim() ? JSON.parse(raw) : {};
35147
35347
  const preToolUse = settings.hooks?.PreToolUse;
35148
35348
  if (!Array.isArray(preToolUse) || preToolUse.length === 0) {
@@ -35177,7 +35377,7 @@ function register30(server, _ctx, _initError) {
35177
35377
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
35178
35378
  const backupPath = `${filePath}.olam-bak.${ts}`;
35179
35379
  try {
35180
- fs36.copyFileSync(filePath, backupPath);
35380
+ fs37.copyFileSync(filePath, backupPath);
35181
35381
  } catch {
35182
35382
  }
35183
35383
  const next = {
@@ -35189,7 +35389,7 @@ function register30(server, _ctx, _initError) {
35189
35389
  if (otherStages.length === 0) delete next.hooks;
35190
35390
  else delete next.hooks.PreToolUse;
35191
35391
  }
35192
- fs36.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
35392
+ fs37.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
35193
35393
  return {
35194
35394
  content: [
35195
35395
  {
@@ -35404,9 +35604,9 @@ init_loader();
35404
35604
  // ../core/dist/world/manager.js
35405
35605
  import * as crypto8 from "node:crypto";
35406
35606
  import { execSync as execSync5, spawnSync as spawnSync4 } from "node:child_process";
35407
- import * as fs45 from "node:fs";
35607
+ import * as fs46 from "node:fs";
35408
35608
  import * as os26 from "node:os";
35409
- import * as path45 from "node:path";
35609
+ import * as path46 from "node:path";
35410
35610
 
35411
35611
  // ../core/dist/world/state.js
35412
35612
  var VALID_TRANSITIONS = {
@@ -35502,8 +35702,8 @@ function resolveDevboxImage(config2, tag) {
35502
35702
 
35503
35703
  // ../core/dist/world/worktree.js
35504
35704
  import { execFileSync as execFileSync4 } from "node:child_process";
35505
- import * as fs37 from "node:fs";
35506
- import * as path36 from "node:path";
35705
+ import * as fs38 from "node:fs";
35706
+ import * as path37 from "node:path";
35507
35707
  function resolveGitDir(repo) {
35508
35708
  if (repo.path) {
35509
35709
  return repo.path;
@@ -35513,11 +35713,11 @@ function resolveGitDir(repo) {
35513
35713
  async function createWorktrees(repos, worldId, workspacePath, branch) {
35514
35714
  const created = [];
35515
35715
  for (const repo of repos) {
35516
- const worktreePath = path36.join(workspacePath, repo.name);
35716
+ const worktreePath = path37.join(workspacePath, repo.name);
35517
35717
  const gitDir = resolveGitDir(repo);
35518
35718
  const branchName = branch || `olam/${worldId}`;
35519
35719
  try {
35520
- fs37.mkdirSync(path36.dirname(worktreePath), { recursive: true });
35720
+ fs38.mkdirSync(path37.dirname(worktreePath), { recursive: true });
35521
35721
  execFileSync4("git", ["worktree", "add", worktreePath, "-b", branchName], {
35522
35722
  cwd: gitDir,
35523
35723
  stdio: "pipe"
@@ -35550,7 +35750,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
35550
35750
  }
35551
35751
  async function removeWorktrees(repos, workspacePath) {
35552
35752
  for (const repo of repos) {
35553
- const worktreePath = path36.join(workspacePath, repo.name);
35753
+ const worktreePath = path37.join(workspacePath, repo.name);
35554
35754
  let gitDir;
35555
35755
  try {
35556
35756
  gitDir = resolveGitDir(repo);
@@ -35625,12 +35825,12 @@ function removeBranch(repo, branch) {
35625
35825
 
35626
35826
  // ../core/dist/world/kg-overlay.js
35627
35827
  import { execFileSync as execFileSync5 } from "node:child_process";
35628
- import * as fs38 from "node:fs";
35629
- import * as path37 from "node:path";
35828
+ import * as fs39 from "node:fs";
35829
+ import * as path38 from "node:path";
35630
35830
 
35631
35831
  // ../core/dist/kg/storage-paths.js
35632
35832
  import { homedir as homedir22 } from "node:os";
35633
- import { join as join37, resolve as resolve9 } from "node:path";
35833
+ import { join as join38, resolve as resolve9 } from "node:path";
35634
35834
 
35635
35835
  // ../core/dist/world/workspace-name.js
35636
35836
  var InvalidWorkspaceNameError = class extends Error {
@@ -35651,25 +35851,25 @@ function validateWorkspaceName(name) {
35651
35851
 
35652
35852
  // ../core/dist/kg/storage-paths.js
35653
35853
  function olamHome() {
35654
- return process.env.OLAM_HOME ?? join37(homedir22(), ".olam");
35854
+ return process.env.OLAM_HOME ?? join38(homedir22(), ".olam");
35655
35855
  }
35656
35856
  function kgRoot() {
35657
- return join37(olamHome(), "kg");
35857
+ return join38(olamHome(), "kg");
35658
35858
  }
35659
35859
  function worldsRoot() {
35660
- return join37(olamHome(), "worlds");
35860
+ return join38(olamHome(), "worlds");
35661
35861
  }
35662
- function assertWithinPrefix(path48, prefix, label) {
35663
- if (!path48.startsWith(prefix + "/")) {
35664
- throw new Error(`${label} escape: ${path48} not under ${prefix}/`);
35862
+ function assertWithinPrefix(path49, prefix, label) {
35863
+ if (!path49.startsWith(prefix + "/")) {
35864
+ throw new Error(`${label} escape: ${path49} not under ${prefix}/`);
35665
35865
  }
35666
35866
  }
35667
35867
  function kgPristinePath(workspace) {
35668
35868
  validateWorkspaceName(workspace);
35669
35869
  const root = kgRoot();
35670
- const path48 = resolve9(join37(root, workspace));
35671
- assertWithinPrefix(path48, root, "kgPristinePath");
35672
- return path48;
35870
+ const path49 = resolve9(join38(root, workspace));
35871
+ assertWithinPrefix(path49, root, "kgPristinePath");
35872
+ return path49;
35673
35873
  }
35674
35874
  var KG_PATHS_INTERNALS = Object.freeze({
35675
35875
  olamHome,
@@ -35685,10 +35885,10 @@ var KgOverlayError = class extends Error {
35685
35885
  }
35686
35886
  };
35687
35887
  function ensureGitignoreEntry(worldClonePath) {
35688
- const gitignorePath = path37.join(worldClonePath, ".gitignore");
35689
- if (!fs38.existsSync(gitignorePath))
35888
+ const gitignorePath = path38.join(worldClonePath, ".gitignore");
35889
+ if (!fs39.existsSync(gitignorePath))
35690
35890
  return "no-gitignore";
35691
- const content = fs38.readFileSync(gitignorePath, "utf-8");
35891
+ const content = fs39.readFileSync(gitignorePath, "utf-8");
35692
35892
  const lines = content.split("\n").map((l) => l.trim());
35693
35893
  const recognised = /* @__PURE__ */ new Set([
35694
35894
  "graphify-out",
@@ -35703,24 +35903,24 @@ function ensureGitignoreEntry(worldClonePath) {
35703
35903
  const eol = content.includes("\r\n") ? "\r\n" : "\n";
35704
35904
  const needsLeadingNewline = content.length > 0 && !content.endsWith(eol);
35705
35905
  const block = `${needsLeadingNewline ? eol : ""}${eol}# olam-kg-service: per-world KG overlay (Phase B1)${eol}graphify-out/${eol}`;
35706
- fs38.appendFileSync(gitignorePath, block, "utf-8");
35906
+ fs39.appendFileSync(gitignorePath, block, "utf-8");
35707
35907
  return "appended";
35708
35908
  }
35709
35909
  function createWorldOverlay(opts) {
35710
35910
  const pristineRoot = kgPristinePath(opts.workspace);
35711
- const pristinePath = path37.join(pristineRoot, "graphify-out");
35712
- if (!fs38.existsSync(pristinePath)) {
35911
+ const pristinePath = path38.join(pristineRoot, "graphify-out");
35912
+ if (!fs39.existsSync(pristinePath)) {
35713
35913
  throw new KgOverlayError(`Pristine KG for workspace ${JSON.stringify(opts.workspace)} not found at ${pristinePath}. Run \`olam kg build ${opts.workspace}\` first.`);
35714
35914
  }
35715
- if (!path37.isAbsolute(opts.worldClonePath)) {
35915
+ if (!path38.isAbsolute(opts.worldClonePath)) {
35716
35916
  throw new KgOverlayError(`worldClonePath must be absolute (got ${opts.worldClonePath})`);
35717
35917
  }
35718
- if (!fs38.existsSync(opts.worldClonePath)) {
35918
+ if (!fs39.existsSync(opts.worldClonePath)) {
35719
35919
  throw new KgOverlayError(`worldClonePath does not exist: ${opts.worldClonePath}. Create the clone before reflinking.`);
35720
35920
  }
35721
- const overlayPath = path37.join(opts.worldClonePath, "graphify-out");
35722
- if (fs38.existsSync(overlayPath)) {
35723
- fs38.rmSync(overlayPath, { recursive: true, force: true });
35921
+ const overlayPath = path38.join(opts.worldClonePath, "graphify-out");
35922
+ if (fs39.existsSync(overlayPath)) {
35923
+ fs39.rmSync(overlayPath, { recursive: true, force: true });
35724
35924
  }
35725
35925
  const useReflink = process.platform === "darwin";
35726
35926
  let strategy;
@@ -35738,7 +35938,7 @@ function createWorldOverlay(opts) {
35738
35938
  } else {
35739
35939
  strategy = "cp-r";
35740
35940
  }
35741
- if (strategy === "cp-r" || !fs38.existsSync(overlayPath)) {
35941
+ if (strategy === "cp-r" || !fs39.existsSync(overlayPath)) {
35742
35942
  try {
35743
35943
  execFileSync5("cp", ["-r", pristinePath, opts.worldClonePath], {
35744
35944
  stdio: ["ignore", "ignore", "pipe"]
@@ -35750,7 +35950,7 @@ function createWorldOverlay(opts) {
35750
35950
  throw new KgOverlayError(`cp -r failed: ${msg}${reflinkMsg}`);
35751
35951
  }
35752
35952
  }
35753
- if (!fs38.existsSync(overlayPath)) {
35953
+ if (!fs39.existsSync(overlayPath)) {
35754
35954
  throw new KgOverlayError(`Overlay creation produced no ${overlayPath} after cp \u2014 filesystem returned without error?`);
35755
35955
  }
35756
35956
  const gitignoreAction = ensureGitignoreEntry(opts.worldClonePath);
@@ -35764,9 +35964,9 @@ function createWorldOverlay(opts) {
35764
35964
 
35765
35965
  // ../core/dist/world/baseline-diff.js
35766
35966
  import { execFileSync as execFileSync6 } from "node:child_process";
35767
- import * as fs39 from "node:fs";
35967
+ import * as fs40 from "node:fs";
35768
35968
  import * as os23 from "node:os";
35769
- import * as path38 from "node:path";
35969
+ import * as path39 from "node:path";
35770
35970
  var DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
35771
35971
  function expandHome2(p, homedir28) {
35772
35972
  return p.replace(/^~(?=$|\/|\\)/, homedir28());
@@ -35793,9 +35993,9 @@ ${stderr}`;
35793
35993
  function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
35794
35994
  const exec = deps.exec ?? ((cmd, args, opts) => execFileSync6(cmd, args, opts));
35795
35995
  const homedir28 = deps.homedir ?? (() => os23.homedir());
35796
- const baselineDir = path38.join(workspacePath, ".olam", "baseline");
35996
+ const baselineDir = path39.join(workspacePath, ".olam", "baseline");
35797
35997
  try {
35798
- fs39.mkdirSync(baselineDir, { recursive: true });
35998
+ fs40.mkdirSync(baselineDir, { recursive: true });
35799
35999
  } catch (err) {
35800
36000
  const msg = err instanceof Error ? err.message : String(err);
35801
36001
  console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
@@ -35807,9 +36007,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
35807
36007
  if (!repo.path)
35808
36008
  continue;
35809
36009
  const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
35810
- const outPath = path38.join(baselineDir, filename);
36010
+ const outPath = path39.join(baselineDir, filename);
35811
36011
  const repoPath = expandHome2(repo.path, homedir28);
35812
- if (!fs39.existsSync(repoPath)) {
36012
+ if (!fs40.existsSync(repoPath)) {
35813
36013
  writeBaselineFile(outPath, `# repo: ${repo.name}
35814
36014
  # (skipped: path ${repoPath} does not exist)
35815
36015
  `);
@@ -35876,7 +36076,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
35876
36076
  }
35877
36077
  function writeBaselineFile(outPath, content) {
35878
36078
  try {
35879
- fs39.writeFileSync(outPath, content);
36079
+ fs40.writeFileSync(outPath, content);
35880
36080
  } catch (err) {
35881
36081
  const msg = err instanceof Error ? err.message : String(err);
35882
36082
  console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
@@ -35884,8 +36084,8 @@ function writeBaselineFile(outPath, content) {
35884
36084
  }
35885
36085
  function stripWorktreeEdits(repos, workspacePath) {
35886
36086
  for (const repo of repos) {
35887
- const worktreePath = path38.join(workspacePath, repo.name);
35888
- if (!fs39.existsSync(worktreePath))
36087
+ const worktreePath = path39.join(workspacePath, repo.name);
36088
+ if (!fs40.existsSync(worktreePath))
35889
36089
  continue;
35890
36090
  try {
35891
36091
  execFileSync6("git", ["checkout", "--", "."], {
@@ -35945,17 +36145,17 @@ function extractStderr(err) {
35945
36145
  function carryUncommittedEdits(repos, workspacePath, deps = {}) {
35946
36146
  const exec = deps.exec ?? ((cmd, args, opts) => execFileSync6(cmd, args, opts));
35947
36147
  const homedir28 = deps.homedir ?? (() => os23.homedir());
35948
- const existsSync46 = deps.existsSync ?? ((p) => fs39.existsSync(p));
35949
- const copyFileSync9 = deps.copyFileSync ?? ((src, dest) => fs39.copyFileSync(src, dest));
36148
+ const existsSync46 = deps.existsSync ?? ((p) => fs40.existsSync(p));
36149
+ const copyFileSync9 = deps.copyFileSync ?? ((src, dest) => fs40.copyFileSync(src, dest));
35950
36150
  const mkdirSync29 = deps.mkdirSync ?? ((dirPath, opts) => {
35951
- fs39.mkdirSync(dirPath, opts);
36151
+ fs40.mkdirSync(dirPath, opts);
35952
36152
  });
35953
36153
  const plans = [];
35954
36154
  for (const repo of repos) {
35955
36155
  if (!repo.path)
35956
36156
  continue;
35957
36157
  const repoPath = expandHome2(repo.path, homedir28);
35958
- const worktreePath = path38.join(workspacePath, repo.name);
36158
+ const worktreePath = path39.join(workspacePath, repo.name);
35959
36159
  if (!existsSync46(repoPath))
35960
36160
  continue;
35961
36161
  if (!existsSync46(worktreePath)) {
@@ -36016,12 +36216,12 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
36016
36216
  }
36017
36217
  }
36018
36218
  for (const rel of plan.diff.untracked) {
36019
- const src = path38.join(plan.repoPath, rel);
36020
- const dest = path38.join(plan.worktreePath, rel);
36219
+ const src = path39.join(plan.repoPath, rel);
36220
+ const dest = path39.join(plan.worktreePath, rel);
36021
36221
  if (!existsSync46(src))
36022
36222
  continue;
36023
36223
  try {
36024
- mkdirSync29(path38.dirname(dest), { recursive: true });
36224
+ mkdirSync29(path39.dirname(dest), { recursive: true });
36025
36225
  copyFileSync9(src, dest);
36026
36226
  } catch (err) {
36027
36227
  const msg = err instanceof Error ? err.message : String(err);
@@ -36047,8 +36247,8 @@ function formatBaselineSummary(result) {
36047
36247
  }
36048
36248
 
36049
36249
  // ../core/dist/world/context-injection.js
36050
- import * as fs40 from "node:fs";
36051
- import * as path39 from "node:path";
36250
+ import * as fs41 from "node:fs";
36251
+ import * as path40 from "node:path";
36052
36252
 
36053
36253
  // ../core/dist/world/templates/_generated.js
36054
36254
  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';
@@ -36058,10 +36258,10 @@ var WORLD_CLAUDE_MD = '# Olam World: {{worldName}}\n\n{{taskBlock}}\n\n## Enviro
36058
36258
  // ../core/dist/world/context-injection.js
36059
36259
  function injectWorldContext(opts) {
36060
36260
  const { world } = opts;
36061
- const claudeDir2 = path39.join(world.workspacePath, ".claude");
36062
- fs40.mkdirSync(claudeDir2, { recursive: true });
36261
+ const claudeDir2 = path40.join(world.workspacePath, ".claude");
36262
+ fs41.mkdirSync(claudeDir2, { recursive: true });
36063
36263
  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));
36064
- fs40.writeFileSync(path39.join(claudeDir2, "CLAUDE.md"), content);
36264
+ fs41.writeFileSync(path40.join(claudeDir2, "CLAUDE.md"), content);
36065
36265
  writeOlamDocs(world.workspacePath);
36066
36266
  }
36067
36267
  function buildTaskBlock(opts) {
@@ -36135,10 +36335,10 @@ function buildExtraContextBlock(extra) {
36135
36335
  ${extra}`;
36136
36336
  }
36137
36337
  function writeOlamDocs(workspacePath) {
36138
- const docsDir = path39.join(workspacePath, ".olam", "docs");
36139
- fs40.mkdirSync(docsDir, { recursive: true });
36140
- fs40.writeFileSync(path39.join(docsDir, "gh-pr-create.md"), GH_PR_CREATE);
36141
- fs40.writeFileSync(path39.join(docsDir, "lane-orchestration.md"), LANE_ORCHESTRATION);
36338
+ const docsDir = path40.join(workspacePath, ".olam", "docs");
36339
+ fs41.mkdirSync(docsDir, { recursive: true });
36340
+ fs41.writeFileSync(path40.join(docsDir, "gh-pr-create.md"), GH_PR_CREATE);
36341
+ fs41.writeFileSync(path40.join(docsDir, "lane-orchestration.md"), LANE_ORCHESTRATION);
36142
36342
  }
36143
36343
  function formatTaskSource(ctx) {
36144
36344
  if (ctx.source === "linear" && ctx.ticketId) {
@@ -36152,9 +36352,9 @@ function formatTaskSource(ctx) {
36152
36352
  function hasPlanFile(world) {
36153
36353
  if (world.repos.length === 0)
36154
36354
  return false;
36155
- const plansDir = path39.join(world.workspacePath, world.repos[0], "docs", "plans");
36355
+ const plansDir = path40.join(world.workspacePath, world.repos[0], "docs", "plans");
36156
36356
  try {
36157
- return fs40.existsSync(plansDir) && fs40.readdirSync(plansDir).length > 0;
36357
+ return fs41.existsSync(plansDir) && fs41.readdirSync(plansDir).length > 0;
36158
36358
  } catch {
36159
36359
  return false;
36160
36360
  }
@@ -36726,25 +36926,25 @@ init_repo_manifest();
36726
36926
 
36727
36927
  // ../core/dist/world/snapshot.js
36728
36928
  import * as crypto7 from "node:crypto";
36729
- import * as fs41 from "node:fs";
36929
+ import * as fs42 from "node:fs";
36730
36930
  import * as os24 from "node:os";
36731
- import * as path40 from "node:path";
36931
+ import * as path41 from "node:path";
36732
36932
  import { execFileSync as execFileSync7, spawn as spawn2 } from "node:child_process";
36733
36933
  import { gunzipSync } from "node:zlib";
36734
36934
  function snapshotsDir() {
36735
- return process.env["OLAM_SNAPSHOTS_DIR"] ?? path40.join(os24.homedir(), ".olam", "snapshots");
36935
+ return process.env["OLAM_SNAPSHOTS_DIR"] ?? path41.join(os24.homedir(), ".olam", "snapshots");
36736
36936
  }
36737
36937
  function snapshotKindDirByWorkspace(workspace, arch, kind) {
36738
- return path40.join(snapshotsDir(), "by-workspace", workspace, arch, kind);
36938
+ return path41.join(snapshotsDir(), "by-workspace", workspace, arch, kind);
36739
36939
  }
36740
36940
  function cleanupLegacyByWorldDir(worldId) {
36741
- const legacyDir = path40.join(snapshotsDir(), worldId);
36941
+ const legacyDir = path41.join(snapshotsDir(), worldId);
36742
36942
  if (worldId === "by-workspace")
36743
36943
  return;
36744
- if (!fs41.existsSync(legacyDir))
36944
+ if (!fs42.existsSync(legacyDir))
36745
36945
  return;
36746
36946
  try {
36747
- fs41.rmSync(legacyDir, { recursive: true, force: true });
36947
+ fs42.rmSync(legacyDir, { recursive: true, force: true });
36748
36948
  } catch {
36749
36949
  }
36750
36950
  }
@@ -36763,11 +36963,11 @@ function hashBuffers(entries) {
36763
36963
  return hash.digest("hex").slice(0, 12);
36764
36964
  }
36765
36965
  function computeGemsFingerprint(repoDir, imageDigest) {
36766
- const lockfile = path40.join(repoDir, "Gemfile.lock");
36767
- if (!fs41.existsSync(lockfile))
36966
+ const lockfile = path41.join(repoDir, "Gemfile.lock");
36967
+ if (!fs42.existsSync(lockfile))
36768
36968
  return null;
36769
36969
  const entries = [
36770
- { path: "Gemfile.lock", content: fs41.readFileSync(lockfile) }
36970
+ { path: "Gemfile.lock", content: fs42.readFileSync(lockfile) }
36771
36971
  ];
36772
36972
  if (imageDigest) {
36773
36973
  entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
@@ -36777,10 +36977,10 @@ function computeGemsFingerprint(repoDir, imageDigest) {
36777
36977
  function computeNodeFingerprint(repoDir, imageDigest) {
36778
36978
  const candidates = ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"];
36779
36979
  for (const name of candidates) {
36780
- const lockfile = path40.join(repoDir, name);
36781
- if (fs41.existsSync(lockfile)) {
36980
+ const lockfile = path41.join(repoDir, name);
36981
+ if (fs42.existsSync(lockfile)) {
36782
36982
  const entries = [
36783
- { path: name, content: fs41.readFileSync(lockfile) }
36983
+ { path: name, content: fs42.readFileSync(lockfile) }
36784
36984
  ];
36785
36985
  if (imageDigest) {
36786
36986
  entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
@@ -36799,18 +36999,18 @@ function unpackTarballAtomic(srcPath, destDir) {
36799
36999
  detail: validation.detail ?? `unsafe entry: ${validation.unsafePath}`
36800
37000
  };
36801
37001
  }
36802
- const parent = path40.dirname(destDir);
36803
- fs41.mkdirSync(parent, { recursive: true });
37002
+ const parent = path41.dirname(destDir);
37003
+ fs42.mkdirSync(parent, { recursive: true });
36804
37004
  const tmpSuffix = `.tmp-${process.pid}-${crypto7.randomBytes(4).toString("hex")}`;
36805
37005
  const tmpDir = `${destDir}${tmpSuffix}`;
36806
37006
  try {
36807
- fs41.mkdirSync(tmpDir, { recursive: true });
37007
+ fs42.mkdirSync(tmpDir, { recursive: true });
36808
37008
  execFileSync7("tar", ["-xzf", srcPath, "-C", tmpDir], { stdio: "pipe" });
36809
- fs41.renameSync(tmpDir, destDir);
37009
+ fs42.renameSync(tmpDir, destDir);
36810
37010
  return { ok: true, entryCount: validation.entries.length };
36811
37011
  } catch (err) {
36812
37012
  try {
36813
- fs41.rmSync(tmpDir, { recursive: true, force: true });
37013
+ fs42.rmSync(tmpDir, { recursive: true, force: true });
36814
37014
  } catch {
36815
37015
  }
36816
37016
  return {
@@ -36821,12 +37021,12 @@ function unpackTarballAtomic(srcPath, destDir) {
36821
37021
  }
36822
37022
  }
36823
37023
  function resolvesWithin(base, target) {
36824
- const resolved = path40.resolve(base, target);
36825
- const baseResolved = path40.resolve(base);
36826
- const rel = path40.relative(baseResolved, resolved);
37024
+ const resolved = path41.resolve(base, target);
37025
+ const baseResolved = path41.resolve(base);
37026
+ const rel = path41.relative(baseResolved, resolved);
36827
37027
  if (rel === "")
36828
37028
  return true;
36829
- return !rel.startsWith("..") && !path40.isAbsolute(rel);
37029
+ return !rel.startsWith("..") && !path41.isAbsolute(rel);
36830
37030
  }
36831
37031
  var TYPE_CHAR_TO_TYPE = {
36832
37032
  "-": "file",
@@ -36876,7 +37076,7 @@ function parseTarListLine(line) {
36876
37076
  function validateHardlinksBinary(tarPath, targetDir) {
36877
37077
  let raw;
36878
37078
  try {
36879
- raw = gunzipSync(fs41.readFileSync(tarPath));
37079
+ raw = gunzipSync(fs42.readFileSync(tarPath));
36880
37080
  } catch {
36881
37081
  return null;
36882
37082
  }
@@ -36891,7 +37091,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
36891
37091
  const name = block.subarray(0, nameNull >= 0 && nameNull <= 99 ? nameNull : 100).toString("utf-8");
36892
37092
  const linkNull = block.indexOf(0, 157);
36893
37093
  const linkname = block.subarray(157, linkNull >= 157 && linkNull <= 256 ? linkNull : 257).toString("utf-8");
36894
- if (linkname && (path40.isAbsolute(linkname) || !resolvesWithin(targetDir, linkname))) {
37094
+ if (linkname && (path41.isAbsolute(linkname) || !resolvesWithin(targetDir, linkname))) {
36895
37095
  return {
36896
37096
  valid: false,
36897
37097
  reason: "hardlink-escape",
@@ -36929,7 +37129,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
36929
37129
  const entry = parseTarListLine(line);
36930
37130
  if (!entry)
36931
37131
  continue;
36932
- if (path40.isAbsolute(entry.name) || !resolvesWithin(targetDir, entry.name)) {
37132
+ if (path41.isAbsolute(entry.name) || !resolvesWithin(targetDir, entry.name)) {
36933
37133
  return {
36934
37134
  valid: false,
36935
37135
  reason: "path-traversal",
@@ -36937,8 +37137,8 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
36937
37137
  };
36938
37138
  }
36939
37139
  if (entry.type === "symlink" && entry.linkname !== void 0) {
36940
- const symlinkParent = path40.join(targetDir, path40.dirname(entry.name));
36941
- if (path40.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, path40.join(path40.dirname(entry.name), entry.linkname))) {
37140
+ const symlinkParent = path41.join(targetDir, path41.dirname(entry.name));
37141
+ if (path41.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, path41.join(path41.dirname(entry.name), entry.linkname))) {
36942
37142
  return {
36943
37143
  valid: false,
36944
37144
  reason: "symlink-escape",
@@ -36948,7 +37148,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
36948
37148
  }
36949
37149
  }
36950
37150
  if (entry.type === "hardlink" && entry.linkname !== void 0) {
36951
- if (path40.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, entry.linkname)) {
37151
+ if (path41.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, entry.linkname)) {
36952
37152
  return {
36953
37153
  valid: false,
36954
37154
  reason: "hardlink-escape",
@@ -36981,8 +37181,8 @@ function restoreSnapshotsForRepos(input) {
36981
37181
  }
36982
37182
  const archDir = snapshotKindDirByWorkspace(input.workspace, input.arch, kind);
36983
37183
  const tarFilename = `${repo.name}-${input.arch}-${fingerprint}.tar.gz`;
36984
- const tarPath = path40.join(archDir, tarFilename);
36985
- if (!fs41.existsSync(tarPath)) {
37184
+ const tarPath = path41.join(archDir, tarFilename);
37185
+ if (!fs42.existsSync(tarPath)) {
36986
37186
  outcomes.push({ repo: repo.name, kind, outcome: "miss", reason: "no-tarball", fingerprint });
36987
37187
  continue;
36988
37188
  }
@@ -36997,9 +37197,9 @@ function restoreSnapshotsForRepos(input) {
36997
37197
  });
36998
37198
  continue;
36999
37199
  }
37000
- const targetDir = path40.join(repo.worktreeDir, targetSubpath);
37200
+ const targetDir = path41.join(repo.worktreeDir, targetSubpath);
37001
37201
  try {
37002
- fs41.rmSync(targetDir, { recursive: true, force: true });
37202
+ fs42.rmSync(targetDir, { recursive: true, force: true });
37003
37203
  } catch {
37004
37204
  }
37005
37205
  const result = unpackTarballAtomic(tarPath, targetDir);
@@ -37012,8 +37212,8 @@ function restoreSnapshotsForRepos(input) {
37012
37212
  fingerprint
37013
37213
  });
37014
37214
  try {
37015
- fs41.rmSync(tarPath, { force: true });
37016
- fs41.rmSync(manifestPath(tarPath), { force: true });
37215
+ fs42.rmSync(tarPath, { force: true });
37216
+ fs42.rmSync(manifestPath(tarPath), { force: true });
37017
37217
  } catch {
37018
37218
  }
37019
37219
  continue;
@@ -37029,10 +37229,10 @@ function restoreSnapshotsForRepos(input) {
37029
37229
  }
37030
37230
  function readManifest(tarPath) {
37031
37231
  const mPath = manifestPath(tarPath);
37032
- if (!fs41.existsSync(mPath))
37232
+ if (!fs42.existsSync(mPath))
37033
37233
  return null;
37034
37234
  try {
37035
- return JSON.parse(fs41.readFileSync(mPath, "utf-8"));
37235
+ return JSON.parse(fs42.readFileSync(mPath, "utf-8"));
37036
37236
  } catch {
37037
37237
  return null;
37038
37238
  }
@@ -37047,17 +37247,17 @@ function isPidAlive(pid) {
37047
37247
  }
37048
37248
  }
37049
37249
  function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
37050
- fs41.mkdirSync(dir, { recursive: true });
37051
- const lockPath = path40.join(dir, EVICT_LOCK_FILENAME);
37250
+ fs42.mkdirSync(dir, { recursive: true });
37251
+ const lockPath = path41.join(dir, EVICT_LOCK_FILENAME);
37052
37252
  let fd;
37053
37253
  try {
37054
- fd = fs41.openSync(lockPath, fs41.constants.O_WRONLY | fs41.constants.O_CREAT | fs41.constants.O_EXCL, 384);
37254
+ fd = fs42.openSync(lockPath, fs42.constants.O_WRONLY | fs42.constants.O_CREAT | fs42.constants.O_EXCL, 384);
37055
37255
  } catch (err) {
37056
37256
  if (err.code !== "EEXIST")
37057
37257
  return 0;
37058
37258
  let holderPid = null;
37059
37259
  try {
37060
- holderPid = parseInt(fs41.readFileSync(lockPath, "utf-8").trim(), 10);
37260
+ holderPid = parseInt(fs42.readFileSync(lockPath, "utf-8").trim(), 10);
37061
37261
  } catch {
37062
37262
  holderPid = null;
37063
37263
  }
@@ -37065,23 +37265,23 @@ function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
37065
37265
  return 0;
37066
37266
  }
37067
37267
  try {
37068
- fs41.unlinkSync(lockPath);
37069
- fd = fs41.openSync(lockPath, fs41.constants.O_WRONLY | fs41.constants.O_CREAT | fs41.constants.O_EXCL, 384);
37268
+ fs42.unlinkSync(lockPath);
37269
+ fd = fs42.openSync(lockPath, fs42.constants.O_WRONLY | fs42.constants.O_CREAT | fs42.constants.O_EXCL, 384);
37070
37270
  } catch {
37071
37271
  return 0;
37072
37272
  }
37073
37273
  }
37074
37274
  try {
37075
- fs41.writeSync(fd, `${process.pid}
37275
+ fs42.writeSync(fd, `${process.pid}
37076
37276
  `);
37077
37277
  } finally {
37078
- fs41.closeSync(fd);
37278
+ fs42.closeSync(fd);
37079
37279
  }
37080
37280
  try {
37081
37281
  return evictOldSnapshots(maxBytes, dir);
37082
37282
  } finally {
37083
37283
  try {
37084
- fs41.unlinkSync(lockPath);
37284
+ fs42.unlinkSync(lockPath);
37085
37285
  } catch {
37086
37286
  }
37087
37287
  }
@@ -37114,16 +37314,16 @@ function spawnAutoCapture(worldId, olamBin = "olam") {
37114
37314
  }
37115
37315
  }
37116
37316
  function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
37117
- if (!fs41.existsSync(dir))
37317
+ if (!fs42.existsSync(dir))
37118
37318
  return 0;
37119
37319
  const allTars = [];
37120
37320
  const walk = (d) => {
37121
- for (const entry of fs41.readdirSync(d, { withFileTypes: true })) {
37122
- const full = path40.join(d, entry.name);
37321
+ for (const entry of fs42.readdirSync(d, { withFileTypes: true })) {
37322
+ const full = path41.join(d, entry.name);
37123
37323
  if (entry.isDirectory()) {
37124
37324
  walk(full);
37125
37325
  } else if (entry.name.endsWith(".tar.gz")) {
37126
- const stat = fs41.statSync(full);
37326
+ const stat = fs42.statSync(full);
37127
37327
  allTars.push({ path: full, size: stat.size, mtime: stat.mtimeMs });
37128
37328
  }
37129
37329
  }
@@ -37138,8 +37338,8 @@ function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
37138
37338
  for (const tar of allTars) {
37139
37339
  if (remaining <= maxBytes)
37140
37340
  break;
37141
- fs41.rmSync(tar.path, { force: true });
37142
- fs41.rmSync(manifestPath(tar.path), { force: true });
37341
+ fs42.rmSync(tar.path, { force: true });
37342
+ fs42.rmSync(manifestPath(tar.path), { force: true });
37143
37343
  freed += tar.size;
37144
37344
  remaining -= tar.size;
37145
37345
  }
@@ -37256,14 +37456,14 @@ function gcloudAvailable(execFn = defaultExecFn) {
37256
37456
 
37257
37457
  // ../core/dist/world/olam-yaml.js
37258
37458
  init_repo_manifest();
37259
- import * as path41 from "node:path";
37459
+ import * as path42 from "node:path";
37260
37460
  import YAML2 from "yaml";
37261
37461
  function enrichReposWithManifests(repos, workspacePath) {
37262
37462
  return repos.map((repo) => {
37263
37463
  if (repo.manifest !== void 0 && repo.manifest !== null) {
37264
37464
  return repo;
37265
37465
  }
37266
- const repoDir = path41.join(workspacePath, repo.name);
37466
+ const repoDir = path42.join(workspacePath, repo.name);
37267
37467
  let manifest = null;
37268
37468
  try {
37269
37469
  manifest = loadRepoManifest(repoDir);
@@ -37278,8 +37478,8 @@ function enrichReposWithManifests(repos, workspacePath) {
37278
37478
  }
37279
37479
 
37280
37480
  // ../core/dist/policies/loader.js
37281
- import * as fs42 from "node:fs";
37282
- import * as path42 from "node:path";
37481
+ import * as fs43 from "node:fs";
37482
+ import * as path43 from "node:path";
37283
37483
  import { parse as parseYaml4 } from "yaml";
37284
37484
  function parseFrontmatter2(content) {
37285
37485
  const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
@@ -37299,20 +37499,20 @@ function toStringArray(v) {
37299
37499
  return v.filter((x) => typeof x === "string");
37300
37500
  }
37301
37501
  function loadPolicies(workspaceRoot) {
37302
- const policiesDir = path42.join(workspaceRoot, ".olam", "policies");
37303
- if (!fs42.existsSync(policiesDir))
37502
+ const policiesDir = path43.join(workspaceRoot, ".olam", "policies");
37503
+ if (!fs43.existsSync(policiesDir))
37304
37504
  return [];
37305
37505
  let files;
37306
37506
  try {
37307
- files = fs42.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
37507
+ files = fs43.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
37308
37508
  } catch {
37309
37509
  return [];
37310
37510
  }
37311
37511
  const policies = [];
37312
37512
  for (const file of files) {
37313
- const filePath = path42.join(policiesDir, file);
37513
+ const filePath = path43.join(policiesDir, file);
37314
37514
  try {
37315
- const content = fs42.readFileSync(filePath, "utf8");
37515
+ const content = fs43.readFileSync(filePath, "utf8");
37316
37516
  const parsed = parseFrontmatter2(content);
37317
37517
  if (!parsed) {
37318
37518
  console.warn(`[policies] skipping ${file}: no valid frontmatter block`);
@@ -37459,12 +37659,12 @@ init_store();
37459
37659
  init_bridge();
37460
37660
 
37461
37661
  // ../core/dist/global-config/runbook-resolver.js
37462
- import * as fs43 from "node:fs";
37662
+ import * as fs44 from "node:fs";
37463
37663
  import * as os25 from "node:os";
37464
- import * as path43 from "node:path";
37664
+ import * as path44 from "node:path";
37465
37665
  function expandTilde(p) {
37466
37666
  if (p === "~" || p.startsWith("~/")) {
37467
- return path43.join(os25.homedir(), p.slice(1));
37667
+ return path44.join(os25.homedir(), p.slice(1));
37468
37668
  }
37469
37669
  return p;
37470
37670
  }
@@ -37476,7 +37676,7 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
37476
37676
  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.`);
37477
37677
  }
37478
37678
  const resolvedPath = expandTilde(entry.path);
37479
- if (!fs43.existsSync(resolvedPath)) {
37679
+ if (!fs44.existsSync(resolvedPath)) {
37480
37680
  throw new Error(`repo "${repoName}" path "${resolvedPath}" no longer exists. Run "olam repos update ${repoName} --path <new-path>" to fix.`);
37481
37681
  }
37482
37682
  }
@@ -37492,19 +37692,19 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
37492
37692
  init_port_validator();
37493
37693
 
37494
37694
  // ../core/dist/world/bootstrap-hooks.js
37495
- import * as fs44 from "node:fs";
37496
- import * as path44 from "node:path";
37695
+ import * as fs45 from "node:fs";
37696
+ import * as path45 from "node:path";
37497
37697
  function runFixtureCopySeeds(seeds, workspacePath) {
37498
37698
  if (!seeds)
37499
37699
  return;
37500
37700
  for (const seed of seeds) {
37501
37701
  if (seed.type !== "fixture-copy")
37502
37702
  continue;
37503
- const srcAbs = path44.resolve(workspacePath, seed.repo, seed.src);
37504
- const destAbs = path44.resolve(workspacePath, seed.repo, seed.dest);
37505
- const destDir = path44.dirname(destAbs);
37506
- fs44.mkdirSync(destDir, { recursive: true });
37507
- fs44.cpSync(srcAbs, destAbs, { recursive: true, force: true });
37703
+ const srcAbs = path45.resolve(workspacePath, seed.repo, seed.src);
37704
+ const destAbs = path45.resolve(workspacePath, seed.repo, seed.dest);
37705
+ const destDir = path45.dirname(destAbs);
37706
+ fs45.mkdirSync(destDir, { recursive: true });
37707
+ fs45.cpSync(srcAbs, destAbs, { recursive: true, force: true });
37508
37708
  }
37509
37709
  }
37510
37710
  async function runSeedHooks(seeds, containerName, servicePortMap, exec) {
@@ -38140,7 +38340,7 @@ ${detail}`);
38140
38340
  runbookSeeds = resolved.seeds;
38141
38341
  }
38142
38342
  const worldId = generateWorldId();
38143
- const workspacePath = path45.join(os26.homedir(), ".olam", "worlds", worldId);
38343
+ const workspacePath = path46.join(os26.homedir(), ".olam", "worlds", worldId);
38144
38344
  const portOffset = this.registry.getNextPortOffset();
38145
38345
  const branch = opts.branchName ?? `olam/${worldId}`;
38146
38346
  const repos = this.resolveReposWithWorkspace(opts);
@@ -38222,37 +38422,37 @@ ${detail}`);
38222
38422
  if (!repo.path)
38223
38423
  continue;
38224
38424
  const sourceRoot = repo.path.replace(/^~/, os26.homedir());
38225
- const worktreeRoot = path45.join(workspacePath, repo.name);
38226
- if (!fs45.existsSync(sourceRoot) || !fs45.existsSync(worktreeRoot))
38425
+ const worktreeRoot = path46.join(workspacePath, repo.name);
38426
+ if (!fs46.existsSync(sourceRoot) || !fs46.existsSync(worktreeRoot))
38227
38427
  continue;
38228
38428
  let copied = 0;
38229
38429
  for (const pattern of RUNTIME_FILE_PATTERNS) {
38230
38430
  const matches2 = [];
38231
38431
  if (pattern.includes("*")) {
38232
- const [dir, glob] = [path45.dirname(pattern), path45.basename(pattern)];
38233
- const sourceDir = path45.join(sourceRoot, dir);
38234
- if (fs45.existsSync(sourceDir)) {
38432
+ const [dir, glob] = [path46.dirname(pattern), path46.basename(pattern)];
38433
+ const sourceDir = path46.join(sourceRoot, dir);
38434
+ if (fs46.existsSync(sourceDir)) {
38235
38435
  const ext = glob.replace(/^\*+/, "");
38236
38436
  try {
38237
- for (const entry of fs45.readdirSync(sourceDir)) {
38437
+ for (const entry of fs46.readdirSync(sourceDir)) {
38238
38438
  if (ext === "" || entry.endsWith(ext))
38239
- matches2.push(path45.join(dir, entry));
38439
+ matches2.push(path46.join(dir, entry));
38240
38440
  }
38241
38441
  } catch {
38242
38442
  }
38243
38443
  }
38244
- } else if (fs45.existsSync(path45.join(sourceRoot, pattern))) {
38444
+ } else if (fs46.existsSync(path46.join(sourceRoot, pattern))) {
38245
38445
  matches2.push(pattern);
38246
38446
  }
38247
38447
  for (const rel of matches2) {
38248
- const src = path45.join(sourceRoot, rel);
38249
- const dst = path45.join(worktreeRoot, rel);
38448
+ const src = path46.join(sourceRoot, rel);
38449
+ const dst = path46.join(worktreeRoot, rel);
38250
38450
  try {
38251
- const st = fs45.statSync(src);
38451
+ const st = fs46.statSync(src);
38252
38452
  if (!st.isFile())
38253
38453
  continue;
38254
- fs45.mkdirSync(path45.dirname(dst), { recursive: true });
38255
- fs45.copyFileSync(src, dst);
38454
+ fs46.mkdirSync(path46.dirname(dst), { recursive: true });
38455
+ fs46.copyFileSync(src, dst);
38256
38456
  copied++;
38257
38457
  } catch {
38258
38458
  }
@@ -38338,7 +38538,7 @@ ${detail}`);
38338
38538
  }
38339
38539
  const overlayAttachments = [];
38340
38540
  for (const repo of repos) {
38341
- const worldClonePath = path45.join(workspacePath, repo.name);
38541
+ const worldClonePath = path46.join(workspacePath, repo.name);
38342
38542
  try {
38343
38543
  const result = createWorldOverlay({
38344
38544
  workspace: repo.name,
@@ -38393,7 +38593,7 @@ ${detail}`);
38393
38593
  try {
38394
38594
  const hostExec = makeHostExecFn();
38395
38595
  for (const repo of repos) {
38396
- const repoDir = path45.join(workspacePath, repo.name);
38596
+ const repoDir = path46.join(workspacePath, repo.name);
38397
38597
  if (repo.stack && Object.keys(repo.stack).length > 0) {
38398
38598
  preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
38399
38599
  } else {
@@ -38437,10 +38637,10 @@ ${detail}`);
38437
38637
  const worldEnv = {};
38438
38638
  if (opts.task)
38439
38639
  worldEnv.OLAM_TASK = opts.task;
38440
- const r2CredsPath = path45.join(os26.homedir(), ".olam", "r2-credentials.json");
38441
- if (fs45.existsSync(r2CredsPath)) {
38640
+ const r2CredsPath = path46.join(os26.homedir(), ".olam", "r2-credentials.json");
38641
+ if (fs46.existsSync(r2CredsPath)) {
38442
38642
  try {
38443
- const r2Raw = fs45.readFileSync(r2CredsPath, "utf-8").trim();
38643
+ const r2Raw = fs46.readFileSync(r2CredsPath, "utf-8").trim();
38444
38644
  if (r2Raw.length > 0) {
38445
38645
  const r2 = JSON.parse(r2Raw);
38446
38646
  if (typeof r2.account_id === "string")
@@ -38457,10 +38657,10 @@ ${detail}`);
38457
38657
  } catch {
38458
38658
  }
38459
38659
  }
38460
- const keysYamlPath = path45.join(os26.homedir(), ".olam", "keys.yaml");
38461
- if (fs45.existsSync(keysYamlPath)) {
38660
+ const keysYamlPath = path46.join(os26.homedir(), ".olam", "keys.yaml");
38661
+ if (fs46.existsSync(keysYamlPath)) {
38462
38662
  try {
38463
- const keysRaw = fs45.readFileSync(keysYamlPath, "utf-8").trim();
38663
+ const keysRaw = fs46.readFileSync(keysYamlPath, "utf-8").trim();
38464
38664
  if (keysRaw.length > 0) {
38465
38665
  const parsed = YAML3.parse(keysRaw);
38466
38666
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
@@ -38519,10 +38719,10 @@ ${detail}`);
38519
38719
  worldEnv[k] = v;
38520
38720
  }
38521
38721
  for (const { repoName, relativePath, content } of fileWrites) {
38522
- const absPath = path45.join(workspacePath, repoName, relativePath);
38722
+ const absPath = path46.join(workspacePath, repoName, relativePath);
38523
38723
  try {
38524
- fs45.mkdirSync(path45.dirname(absPath), { recursive: true });
38525
- fs45.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
38724
+ fs46.mkdirSync(path46.dirname(absPath), { recursive: true });
38725
+ fs46.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
38526
38726
  mode: 384
38527
38727
  });
38528
38728
  console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
@@ -38699,7 +38899,7 @@ ${detail}`);
38699
38899
  imageDigest: void 0,
38700
38900
  repos: enrichedRepos.map((r) => ({
38701
38901
  name: r.name,
38702
- worktreeDir: path45.join(workspacePath, r.name)
38902
+ worktreeDir: path46.join(workspacePath, r.name)
38703
38903
  }))
38704
38904
  });
38705
38905
  for (const out of restoreResult.outcomes) {
@@ -38805,7 +39005,7 @@ ${detail}`);
38805
39005
  }
38806
39006
  if (opts.task) {
38807
39007
  const allPolicies = repos.flatMap((repo) => {
38808
- const repoWorktree = path45.join(workspacePath, repo.name);
39008
+ const repoWorktree = path46.join(workspacePath, repo.name);
38809
39009
  try {
38810
39010
  return loadPolicies(repoWorktree);
38811
39011
  } catch (err) {
@@ -38818,8 +39018,8 @@ ${detail}`);
38818
39018
  try {
38819
39019
  execSync5(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
38820
39020
  for (const repo of repos) {
38821
- const policiesDir = path45.join(workspacePath, repo.name, ".olam", "policies");
38822
- if (fs45.existsSync(policiesDir)) {
39021
+ const policiesDir = path46.join(workspacePath, repo.name, ".olam", "policies");
39022
+ if (fs46.existsSync(policiesDir)) {
38823
39023
  execSync5(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
38824
39024
  }
38825
39025
  }
@@ -38927,8 +39127,8 @@ ${detail}`);
38927
39127
  } catch {
38928
39128
  }
38929
39129
  try {
38930
- fs45.rmSync(world.workspacePath, { recursive: true, force: true });
38931
- if (fs45.existsSync(world.workspacePath)) {
39130
+ fs46.rmSync(world.workspacePath, { recursive: true, force: true });
39131
+ if (fs46.existsSync(world.workspacePath)) {
38932
39132
  console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
38933
39133
  }
38934
39134
  } catch (err) {
@@ -39037,14 +39237,14 @@ ${detail}`);
39037
39237
  }).filter((r) => r !== void 0);
39038
39238
  }
39039
39239
  transportPlanFile(planFilePath, workspacePath, repoNames) {
39040
- const planContent = fs45.readFileSync(planFilePath, "utf-8");
39041
- const planFileName = path45.basename(planFilePath);
39240
+ const planContent = fs46.readFileSync(planFilePath, "utf-8");
39241
+ const planFileName = path46.basename(planFilePath);
39042
39242
  const targetRepo = repoNames[0];
39043
39243
  if (!targetRepo)
39044
39244
  return;
39045
- const plansDir = path45.join(workspacePath, targetRepo, "docs", "plans");
39046
- fs45.mkdirSync(plansDir, { recursive: true });
39047
- fs45.writeFileSync(path45.join(plansDir, planFileName), planContent);
39245
+ const plansDir = path46.join(workspacePath, targetRepo, "docs", "plans");
39246
+ fs46.mkdirSync(plansDir, { recursive: true });
39247
+ fs46.writeFileSync(path46.join(plansDir, planFileName), planContent);
39048
39248
  }
39049
39249
  resolveServices(repos) {
39050
39250
  const services = [];
@@ -39478,8 +39678,8 @@ import * as http2 from "node:http";
39478
39678
 
39479
39679
  // ../core/dist/dashboard/server.js
39480
39680
  import * as http from "node:http";
39481
- import * as fs46 from "node:fs";
39482
- import * as path46 from "node:path";
39681
+ import * as fs47 from "node:fs";
39682
+ import * as path47 from "node:path";
39483
39683
  import { fileURLToPath as fileURLToPath3 } from "node:url";
39484
39684
 
39485
39685
  // ../core/dist/dashboard/serialize.js
@@ -39814,7 +40014,7 @@ function notFound(res) {
39814
40014
  }
39815
40015
  function openThoughtStore(workspacePath) {
39816
40016
  const dbPath = getWorldDbPath(workspacePath);
39817
- if (!fs46.existsSync(dbPath))
40017
+ if (!fs47.existsSync(dbPath))
39818
40018
  return null;
39819
40019
  return new ThoughtLocalStore(dbPath);
39820
40020
  }
@@ -39985,13 +40185,13 @@ function findSessionInWorld(registry2, sessionId) {
39985
40185
  }
39986
40186
  function createDashboardServer(opts) {
39987
40187
  const { port: port2, registry: registry2 } = opts;
39988
- const thisDir = path46.dirname(fileURLToPath3(import.meta.url));
39989
- const defaultPublicDir = path46.resolve(thisDir, "../../../control-plane/public");
40188
+ const thisDir = path47.dirname(fileURLToPath3(import.meta.url));
40189
+ const defaultPublicDir = path47.resolve(thisDir, "../../../control-plane/public");
39990
40190
  const publicDir = opts.publicDir ?? defaultPublicDir;
39991
- let hasPublicDir = fs46.existsSync(publicDir);
40191
+ let hasPublicDir = fs47.existsSync(publicDir);
39992
40192
  const server = http.createServer((req, res) => {
39993
40193
  if (!hasPublicDir) {
39994
- hasPublicDir = fs46.existsSync(publicDir);
40194
+ hasPublicDir = fs47.existsSync(publicDir);
39995
40195
  }
39996
40196
  const host = req.headers.host ?? `localhost:${port2}`;
39997
40197
  const url2 = new URL(req.url ?? "/", `http://${host}`);
@@ -40265,22 +40465,22 @@ function createDashboardServer(opts) {
40265
40465
  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>`);
40266
40466
  return;
40267
40467
  }
40268
- let filePath = path46.join(publicDir, pathname === "/" ? "index.html" : pathname);
40468
+ let filePath = path47.join(publicDir, pathname === "/" ? "index.html" : pathname);
40269
40469
  if (!filePath.startsWith(publicDir)) {
40270
40470
  notFound(res);
40271
40471
  return;
40272
40472
  }
40273
- if (fs46.existsSync(filePath) && fs46.statSync(filePath).isFile()) {
40274
- const ext = path46.extname(filePath);
40473
+ if (fs47.existsSync(filePath) && fs47.statSync(filePath).isFile()) {
40474
+ const ext = path47.extname(filePath);
40275
40475
  const contentType = MIME[ext] ?? "application/octet-stream";
40276
40476
  res.writeHead(200, { "Content-Type": contentType });
40277
- fs46.createReadStream(filePath).pipe(res);
40477
+ fs47.createReadStream(filePath).pipe(res);
40278
40478
  return;
40279
40479
  }
40280
- filePath = path46.join(publicDir, "index.html");
40281
- if (fs46.existsSync(filePath)) {
40480
+ filePath = path47.join(publicDir, "index.html");
40481
+ if (fs47.existsSync(filePath)) {
40282
40482
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
40283
- fs46.createReadStream(filePath).pipe(res);
40483
+ fs47.createReadStream(filePath).pipe(res);
40284
40484
  return;
40285
40485
  }
40286
40486
  notFound(res);
@@ -40290,17 +40490,17 @@ function createDashboardServer(opts) {
40290
40490
  }
40291
40491
 
40292
40492
  // ../core/dist/dashboard/state.js
40293
- import * as fs47 from "node:fs";
40493
+ import * as fs48 from "node:fs";
40294
40494
  import * as os27 from "node:os";
40295
- import * as path47 from "node:path";
40296
- var STATE_PATH = path47.join(os27.homedir(), ".olam", "dashboard.json");
40495
+ import * as path48 from "node:path";
40496
+ var STATE_PATH = path48.join(os27.homedir(), ".olam", "dashboard.json");
40297
40497
  function saveDashboardState(state) {
40298
- fs47.mkdirSync(path47.dirname(STATE_PATH), { recursive: true });
40299
- fs47.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
40498
+ fs48.mkdirSync(path48.dirname(STATE_PATH), { recursive: true });
40499
+ fs48.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
40300
40500
  }
40301
40501
  function loadDashboardState() {
40302
40502
  try {
40303
- const raw = fs47.readFileSync(STATE_PATH, "utf-8");
40503
+ const raw = fs48.readFileSync(STATE_PATH, "utf-8");
40304
40504
  return JSON.parse(raw);
40305
40505
  } catch {
40306
40506
  return null;
@@ -40308,7 +40508,7 @@ function loadDashboardState() {
40308
40508
  }
40309
40509
  function clearDashboardState() {
40310
40510
  try {
40311
- fs47.unlinkSync(STATE_PATH);
40511
+ fs48.unlinkSync(STATE_PATH);
40312
40512
  } catch {
40313
40513
  }
40314
40514
  }
@@ -40588,8 +40788,8 @@ var PleriClient = class {
40588
40788
  };
40589
40789
 
40590
40790
  // ../mcp-server/src/env-loader.ts
40591
- import { readFileSync as readFileSync36, existsSync as existsSync45, statSync as statSync14 } from "node:fs";
40592
- import { join as join48, dirname as dirname28, resolve as resolve13 } from "node:path";
40791
+ import { readFileSync as readFileSync37, existsSync as existsSync45, statSync as statSync14 } from "node:fs";
40792
+ import { join as join49, dirname as dirname28, resolve as resolve13 } from "node:path";
40593
40793
  var PROJECT_MARKERS = [
40594
40794
  ".olam/config.yaml",
40595
40795
  ".olam/config.yml",
@@ -40601,12 +40801,12 @@ function findProjectRoot2(startDir) {
40601
40801
  const root = resolve13("/");
40602
40802
  while (true) {
40603
40803
  for (const marker of PROJECT_MARKERS) {
40604
- if (existsSync45(join48(dir, marker))) return dir;
40804
+ if (existsSync45(join49(dir, marker))) return dir;
40605
40805
  }
40606
- const pkg = join48(dir, "package.json");
40806
+ const pkg = join49(dir, "package.json");
40607
40807
  if (existsSync45(pkg)) {
40608
40808
  try {
40609
- const json = JSON.parse(readFileSync36(pkg, "utf8"));
40809
+ const json = JSON.parse(readFileSync37(pkg, "utf8"));
40610
40810
  const isOlamWorkspace = typeof json.name === "string" && json.name.startsWith("@olam/");
40611
40811
  const hasOlamDep = json.dependencies && Object.keys(json.dependencies).some((k) => k.startsWith("@olam/")) || json.devDependencies && Object.keys(json.devDependencies).some((k) => k.startsWith("@olam/"));
40612
40812
  if (isOlamWorkspace || hasOlamDep) return dir;
@@ -40618,9 +40818,9 @@ function findProjectRoot2(startDir) {
40618
40818
  dir = parent;
40619
40819
  }
40620
40820
  }
40621
- function parseEnvFile(path48) {
40821
+ function parseEnvFile(path49) {
40622
40822
  const out = {};
40623
- const raw = readFileSync36(path48, "utf8");
40823
+ const raw = readFileSync37(path49, "utf8");
40624
40824
  for (const line of raw.split(/\r?\n/)) {
40625
40825
  const trimmed = line.trim();
40626
40826
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -40643,7 +40843,7 @@ function loadProjectEnv(startDir = process.cwd()) {
40643
40843
  const filesRead = [];
40644
40844
  const merged = {};
40645
40845
  for (const name of [".env", ".env.local"]) {
40646
- const p = join48(root, name);
40846
+ const p = join49(root, name);
40647
40847
  if (existsSync45(p) && statSync14(p).isFile()) {
40648
40848
  Object.assign(merged, parseEnvFile(p));
40649
40849
  filesRead.push(p);