@pleri/olam-cli 0.1.49 → 0.1.52

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.
@@ -5,7 +5,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJS = (cb, mod) => function __require() {
8
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
9
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
10
+ }) : x)(function(x) {
11
+ if (typeof require !== "undefined") return require.apply(this, arguments);
12
+ throw Error('Dynamic require of "' + x + '" is not supported');
13
+ });
14
+ var __commonJS = (cb, mod) => function __require2() {
9
15
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
16
  };
11
17
  var __export = (target, all) => {
@@ -3222,8 +3228,8 @@ var require_utils = __commonJS({
3222
3228
  }
3223
3229
  return ind;
3224
3230
  }
3225
- function removeDotSegments(path21) {
3226
- let input = path21;
3231
+ function removeDotSegments(path22) {
3232
+ let input = path22;
3227
3233
  const output = [];
3228
3234
  let nextSlash = -1;
3229
3235
  let len = 0;
@@ -3422,8 +3428,8 @@ var require_schemes = __commonJS({
3422
3428
  wsComponent.secure = void 0;
3423
3429
  }
3424
3430
  if (wsComponent.resourceName) {
3425
- const [path21, query] = wsComponent.resourceName.split("?");
3426
- wsComponent.path = path21 && path21 !== "/" ? path21 : void 0;
3431
+ const [path22, query] = wsComponent.resourceName.split("?");
3432
+ wsComponent.path = path22 && path22 !== "/" ? path22 : void 0;
3427
3433
  wsComponent.query = query;
3428
3434
  wsComponent.resourceName = void 0;
3429
3435
  }
@@ -6785,12 +6791,12 @@ var require_dist = __commonJS({
6785
6791
  throw new Error(`Unknown format "${name}"`);
6786
6792
  return f;
6787
6793
  };
6788
- function addFormats(ajv, list, fs17, exportName) {
6794
+ function addFormats(ajv, list, fs18, exportName) {
6789
6795
  var _a;
6790
6796
  var _b;
6791
6797
  (_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6792
6798
  for (const f of list)
6793
- ajv.addFormat(f, fs17[f]);
6799
+ ajv.addFormat(f, fs18[f]);
6794
6800
  }
6795
6801
  module.exports = exports = formatsPlugin;
6796
6802
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -6996,10 +7002,10 @@ function assignProp(target, prop, value) {
6996
7002
  configurable: true
6997
7003
  });
6998
7004
  }
6999
- function getElementAtPath(obj, path21) {
7000
- if (!path21)
7005
+ function getElementAtPath(obj, path22) {
7006
+ if (!path22)
7001
7007
  return obj;
7002
- return path21.reduce((acc, key) => acc?.[key], obj);
7008
+ return path22.reduce((acc, key) => acc?.[key], obj);
7003
7009
  }
7004
7010
  function promiseAllObject(promisesObj) {
7005
7011
  const keys = Object.keys(promisesObj);
@@ -7319,11 +7325,11 @@ function aborted(x, startIndex = 0) {
7319
7325
  }
7320
7326
  return false;
7321
7327
  }
7322
- function prefixIssues(path21, issues) {
7328
+ function prefixIssues(path22, issues) {
7323
7329
  return issues.map((iss) => {
7324
7330
  var _a;
7325
7331
  (_a = iss).path ?? (_a.path = []);
7326
- iss.path.unshift(path21);
7332
+ iss.path.unshift(path22);
7327
7333
  return iss;
7328
7334
  });
7329
7335
  }
@@ -13397,8 +13403,8 @@ function getErrorMap() {
13397
13403
 
13398
13404
  // ../../node_modules/zod/v3/helpers/parseUtil.js
13399
13405
  var makeIssue = (params) => {
13400
- const { data, path: path21, errorMaps, issueData } = params;
13401
- const fullPath = [...path21, ...issueData.path || []];
13406
+ const { data, path: path22, errorMaps, issueData } = params;
13407
+ const fullPath = [...path22, ...issueData.path || []];
13402
13408
  const fullIssue = {
13403
13409
  ...issueData,
13404
13410
  path: fullPath
@@ -13514,11 +13520,11 @@ var errorUtil;
13514
13520
 
13515
13521
  // ../../node_modules/zod/v3/types.js
13516
13522
  var ParseInputLazyPath = class {
13517
- constructor(parent, value, path21, key) {
13523
+ constructor(parent, value, path22, key) {
13518
13524
  this._cachedPath = [];
13519
13525
  this.parent = parent;
13520
13526
  this.data = value;
13521
- this._path = path21;
13527
+ this._path = path22;
13522
13528
  this._key = key;
13523
13529
  }
13524
13530
  get path() {
@@ -21359,8 +21365,8 @@ var AuthClient = class {
21359
21365
  throw new Error(`failed to report rate-limit for ${accountId} (HTTP ${res.status})`);
21360
21366
  }
21361
21367
  }
21362
- async request(method, path21, body, attempt = 0) {
21363
- const url = `${this.baseUrl}${path21}`;
21368
+ async request(method, path22, body, attempt = 0) {
21369
+ const url = `${this.baseUrl}${path22}`;
21364
21370
  const controller = new AbortController();
21365
21371
  const timer = setTimeout(() => controller.abort(), this.timeoutMs);
21366
21372
  const headers = {};
@@ -21378,7 +21384,7 @@ var AuthClient = class {
21378
21384
  } catch (err) {
21379
21385
  if (attempt < RETRY_COUNT && isTransient(err)) {
21380
21386
  await sleep(RETRY_BACKOFF_MS * (attempt + 1));
21381
- return this.request(method, path21, body, attempt + 1);
21387
+ return this.request(method, path22, body, attempt + 1);
21382
21388
  }
21383
21389
  throw err;
21384
21390
  } finally {
@@ -22185,12 +22191,12 @@ function register3(server, _ctx, _initError) {
22185
22191
  registry2.close();
22186
22192
  }
22187
22193
  try {
22188
- const { default: fs17 } = await import("node:fs");
22194
+ const { default: fs18 } = await import("node:fs");
22189
22195
  const { default: os10 } = await import("node:os");
22190
- const { default: path21 } = await import("node:path");
22191
- const tokenPath = path21.join(os10.homedir(), ".olam", "host-cp.token");
22192
- if (fs17.existsSync(tokenPath)) {
22193
- const token = fs17.readFileSync(tokenPath, "utf-8").trim();
22196
+ const { default: path22 } = await import("node:path");
22197
+ const tokenPath = path22.join(os10.homedir(), ".olam", "host-cp.token");
22198
+ if (fs18.existsSync(tokenPath)) {
22199
+ const token = fs18.readFileSync(tokenPath, "utf-8").trim();
22194
22200
  await fetch("http://127.0.0.1:19000/api/admin/world-pr", {
22195
22201
  method: "POST",
22196
22202
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
@@ -22383,7 +22389,7 @@ var KNOWN_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
22383
22389
  "deploy"
22384
22390
  ]);
22385
22391
  var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
22386
- function refineForbiddenKeys(value, path21, ctx, rejectSource) {
22392
+ function refineForbiddenKeys(value, path22, ctx, rejectSource) {
22387
22393
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
22388
22394
  return;
22389
22395
  }
@@ -22391,12 +22397,12 @@ function refineForbiddenKeys(value, path21, ctx, rejectSource) {
22391
22397
  if (FORBIDDEN_KEYS.has(key)) {
22392
22398
  ctx.addIssue({
22393
22399
  code: external_exports.ZodIssueCode.custom,
22394
- path: [...path21, key],
22400
+ path: [...path22, key],
22395
22401
  message: `forbidden key "${key}" (prototype-pollution surface)`
22396
22402
  });
22397
22403
  continue;
22398
22404
  }
22399
- if (rejectSource && path21.length === 0 && key === "source") {
22405
+ if (rejectSource && path22.length === 0 && key === "source") {
22400
22406
  ctx.addIssue({
22401
22407
  code: external_exports.ZodIssueCode.custom,
22402
22408
  path: ["source"],
@@ -22404,21 +22410,21 @@ function refineForbiddenKeys(value, path21, ctx, rejectSource) {
22404
22410
  });
22405
22411
  continue;
22406
22412
  }
22407
- refineForbiddenKeys(value[key], [...path21, key], ctx, false);
22413
+ refineForbiddenKeys(value[key], [...path22, key], ctx, false);
22408
22414
  }
22409
22415
  }
22410
- function rejectForbiddenKeys(value, path21, rejectSource) {
22416
+ function rejectForbiddenKeys(value, path22, rejectSource) {
22411
22417
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
22412
22418
  return;
22413
22419
  }
22414
22420
  for (const key of Object.keys(value)) {
22415
22421
  if (FORBIDDEN_KEYS.has(key)) {
22416
- throw new Error(`[manifest] ${path21}: forbidden key "${key}" (prototype-pollution surface)`);
22422
+ throw new Error(`[manifest] ${path22}: forbidden key "${key}" (prototype-pollution surface)`);
22417
22423
  }
22418
22424
  if (rejectSource && key === "source") {
22419
- throw new Error(`[manifest] ${path21}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
22425
+ throw new Error(`[manifest] ${path22}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
22420
22426
  }
22421
- rejectForbiddenKeys(value[key], `${path21}.${key}`, false);
22427
+ rejectForbiddenKeys(value[key], `${path22}.${key}`, false);
22422
22428
  }
22423
22429
  }
22424
22430
  function unknownTopLevelKeys(parsed) {
@@ -22856,10 +22862,10 @@ function extractMcpConfig(claudeJsonPath) {
22856
22862
  }
22857
22863
  return { mcpServers, secrets };
22858
22864
  }
22859
- function readOptional(path21) {
22860
- if (!existsSync6(path21)) return null;
22865
+ function readOptional(path22) {
22866
+ if (!existsSync6(path22)) return null;
22861
22867
  try {
22862
- return readFileSync5(path21, "utf8");
22868
+ return readFileSync5(path22, "utf8");
22863
22869
  } catch {
22864
22870
  return null;
22865
22871
  }
@@ -24002,8 +24008,8 @@ var CloudflareProvider = class extends ComputeProvider {
24002
24008
  // -----------------------------------------------------------------------
24003
24009
  // Internal fetch helper
24004
24010
  // -----------------------------------------------------------------------
24005
- async request(path21, method, body) {
24006
- const url = `${this.config.workerUrl}${path21}`;
24011
+ async request(path22, method, body) {
24012
+ const url = `${this.config.workerUrl}${path22}`;
24007
24013
  const bearer = await this.config.mintToken();
24008
24014
  const headers = {
24009
24015
  Authorization: `Bearer ${bearer}`
@@ -24983,10 +24989,10 @@ var ThoughtLocalStore = class {
24983
24989
  };
24984
24990
 
24985
24991
  // ../core/dist/world/env-setup.js
24986
- import * as crypto2 from "node:crypto";
24987
- import * as fs6 from "node:fs";
24992
+ import * as crypto3 from "node:crypto";
24993
+ import * as fs7 from "node:fs";
24988
24994
  import * as os6 from "node:os";
24989
- import * as path9 from "node:path";
24995
+ import * as path10 from "node:path";
24990
24996
  import { globSync } from "node:fs";
24991
24997
 
24992
24998
  // ../core/dist/thought/hooks-config.js
@@ -25003,14 +25009,25 @@ function generateHooksConfig(hookServerUrl = DEFAULT_HOOK_SERVER_URL) {
25003
25009
  hooks: {
25004
25010
  // Codex adversarial review — fires on every user prompt in-world
25005
25011
  // Uses $HOME so sanitizeContainerClaudeHooks does not strip it
25006
- UserPromptSubmit: [{
25007
- matcher: "",
25008
- hooks: [{
25009
- type: "command",
25010
- command: "$HOME/.claude/scripts/codex-on-prompt.sh",
25011
- timeout: 15
25012
- }]
25013
- }],
25012
+ UserPromptSubmit: [
25013
+ {
25014
+ matcher: "",
25015
+ hooks: [{
25016
+ type: "command",
25017
+ command: "$HOME/.claude/scripts/codex-on-prompt.sh",
25018
+ timeout: 15
25019
+ }]
25020
+ },
25021
+ // C02: surface first-call hint when MCP creds are missing
25022
+ {
25023
+ matcher: "",
25024
+ hooks: [{
25025
+ type: "command",
25026
+ command: "node /opt/olam/scripts/mcp-status-hint.mjs",
25027
+ timeout: 2
25028
+ }]
25029
+ }
25030
+ ],
25014
25031
  // Tool execution events → high-frequency thought capture
25015
25032
  // Layer 1: Upstream Codex review (PreToolUse) — runs after thought capture
25016
25033
  PreToolUse: [
@@ -25061,82 +25078,182 @@ function generateHooksConfig(hookServerUrl = DEFAULT_HOOK_SERVER_URL) {
25061
25078
  };
25062
25079
  }
25063
25080
 
25081
+ // ../core/dist/world/merge-settings.js
25082
+ import * as fs6 from "node:fs";
25083
+ import * as path9 from "node:path";
25084
+ import * as crypto2 from "node:crypto";
25085
+ function mergeHomeSettingsJson(filePath, options) {
25086
+ let settings;
25087
+ try {
25088
+ settings = readSettings(filePath);
25089
+ } catch (err) {
25090
+ throw new Error(`merge-settings: failed to parse existing settings.json: ${err?.message ?? err}`);
25091
+ }
25092
+ let changed = false;
25093
+ if (options.ensureHook) {
25094
+ const { stage, sentinel, entry } = options.ensureHook;
25095
+ if (!settings.hooks || typeof settings.hooks !== "object") {
25096
+ settings = { ...settings, hooks: {} };
25097
+ changed = true;
25098
+ }
25099
+ const hooks = settings.hooks;
25100
+ if (!Array.isArray(hooks[stage])) {
25101
+ settings = {
25102
+ ...settings,
25103
+ hooks: { ...hooks, [stage]: [] }
25104
+ };
25105
+ changed = true;
25106
+ }
25107
+ const stageArr = settings.hooks[stage];
25108
+ if (isHookSentinelPresent(stageArr, sentinel)) {
25109
+ if (!changed) {
25110
+ return { status: "already-present", message: `hook already present at ${filePath}` };
25111
+ }
25112
+ } else {
25113
+ settings = {
25114
+ ...settings,
25115
+ hooks: {
25116
+ ...settings.hooks,
25117
+ [stage]: [...stageArr, entry]
25118
+ }
25119
+ };
25120
+ changed = true;
25121
+ }
25122
+ }
25123
+ if (options.env) {
25124
+ const existingEnv = settings.env && typeof settings.env === "object" ? settings.env : {};
25125
+ const mergedEnv = { ...existingEnv, ...options.env };
25126
+ const sameKeys = Object.keys(mergedEnv).length === Object.keys(existingEnv).length && Object.keys(mergedEnv).every((k) => existingEnv[k] === mergedEnv[k]);
25127
+ if (!sameKeys) {
25128
+ settings = { ...settings, env: mergedEnv };
25129
+ changed = true;
25130
+ }
25131
+ }
25132
+ if (!changed) {
25133
+ return { status: "no-op", message: `no change needed at ${filePath}` };
25134
+ }
25135
+ try {
25136
+ atomicWriteJson(filePath, settings);
25137
+ } catch (err) {
25138
+ throw new Error(`merge-settings: failed to write settings.json: ${err?.message ?? err}`);
25139
+ }
25140
+ return { status: "installed", message: `settings.json updated at ${filePath}` };
25141
+ }
25142
+ function readSettings(filePath) {
25143
+ if (!fs6.existsSync(filePath)) {
25144
+ return {};
25145
+ }
25146
+ const raw = fs6.readFileSync(filePath, "utf-8");
25147
+ if (!raw.trim())
25148
+ return {};
25149
+ return JSON.parse(raw);
25150
+ }
25151
+ function isHookSentinelPresent(matchers, sentinel) {
25152
+ for (const matcher of matchers) {
25153
+ if (typeof matcher?.command === "string" && matcher.command.includes(sentinel)) {
25154
+ return true;
25155
+ }
25156
+ if (Array.isArray(matcher?.hooks)) {
25157
+ for (const h of matcher.hooks) {
25158
+ if (typeof h?.command === "string" && h.command.includes(sentinel)) {
25159
+ return true;
25160
+ }
25161
+ }
25162
+ }
25163
+ }
25164
+ return false;
25165
+ }
25166
+ function atomicWriteJson(filePath, data) {
25167
+ const dir = path9.dirname(filePath);
25168
+ fs6.mkdirSync(dir, { recursive: true });
25169
+ const rand = crypto2.randomBytes(6).toString("hex");
25170
+ const tmp = `${filePath}.tmp.${process.pid}.${rand}`;
25171
+ const json = JSON.stringify(data, null, 2) + "\n";
25172
+ fs6.writeFileSync(tmp, json, { mode: 420 });
25173
+ fs6.renameSync(tmp, filePath);
25174
+ }
25175
+
25064
25176
  // ../core/dist/world/env-setup.js
25065
25177
  function copyClaudeConfig(workspacePath, homeDir, configCtx) {
25066
- const sourceClaudeDir = path9.join(homeDir ?? os6.homedir(), ".claude");
25067
- const destClaudeDir = path9.join(workspacePath, ".claude-host-config");
25178
+ const sourceClaudeDir = path10.join(homeDir ?? os6.homedir(), ".claude");
25179
+ const destClaudeDir = path10.join(workspacePath, ".claude-host-config");
25068
25180
  void configCtx;
25069
- if (!fs6.existsSync(sourceClaudeDir))
25181
+ if (!fs7.existsSync(sourceClaudeDir))
25070
25182
  return;
25071
- fs6.mkdirSync(destClaudeDir, { recursive: true });
25072
- const settingsPath = path9.join(sourceClaudeDir, "settings.json");
25183
+ fs7.mkdirSync(destClaudeDir, { recursive: true });
25184
+ const settingsPath = path10.join(sourceClaudeDir, "settings.json");
25073
25185
  let settings = {};
25074
- if (fs6.existsSync(settingsPath)) {
25186
+ if (fs7.existsSync(settingsPath)) {
25075
25187
  try {
25076
- settings = JSON.parse(fs6.readFileSync(settingsPath, "utf-8"));
25188
+ settings = JSON.parse(fs7.readFileSync(settingsPath, "utf-8"));
25077
25189
  delete settings["hooks"];
25078
25190
  } catch {
25079
25191
  }
25080
25192
  }
25081
25193
  const hooksConfig = generateHooksConfig(DEFAULT_HOOK_SERVER_URL);
25082
25194
  settings["hooks"] = hooksConfig["hooks"];
25083
- fs6.writeFileSync(path9.join(destClaudeDir, "settings.json"), JSON.stringify(settings, null, 2));
25084
- const claudeMdPath = path9.join(sourceClaudeDir, "CLAUDE.md");
25085
- if (fs6.existsSync(claudeMdPath)) {
25086
- fs6.copyFileSync(claudeMdPath, path9.join(destClaudeDir, "CLAUDE.md"));
25195
+ fs7.writeFileSync(path10.join(destClaudeDir, "settings.json"), JSON.stringify(settings, null, 2));
25196
+ const claudeMdPath = path10.join(sourceClaudeDir, "CLAUDE.md");
25197
+ if (fs7.existsSync(claudeMdPath)) {
25198
+ fs7.copyFileSync(claudeMdPath, path10.join(destClaudeDir, "CLAUDE.md"));
25087
25199
  }
25088
- const rulesDir = path9.join(sourceClaudeDir, "rules");
25089
- if (fs6.existsSync(rulesDir)) {
25090
- copyDirRecursive(rulesDir, path9.join(destClaudeDir, "rules"));
25200
+ const rulesDir = path10.join(sourceClaudeDir, "rules");
25201
+ if (fs7.existsSync(rulesDir)) {
25202
+ copyDirRecursive(rulesDir, path10.join(destClaudeDir, "rules"));
25091
25203
  }
25092
- const agentsDir = path9.join(sourceClaudeDir, "agents");
25093
- if (fs6.existsSync(agentsDir)) {
25094
- copyDirRecursive(agentsDir, path9.join(destClaudeDir, "agents"));
25204
+ const agentsDir = path10.join(sourceClaudeDir, "agents");
25205
+ if (fs7.existsSync(agentsDir)) {
25206
+ copyDirRecursive(agentsDir, path10.join(destClaudeDir, "agents"));
25095
25207
  }
25096
- const pluginsDir = path9.join(sourceClaudeDir, "plugins");
25097
- if (fs6.existsSync(pluginsDir)) {
25098
- copyDirRecursive(pluginsDir, path9.join(destClaudeDir, "plugins"), 0, SKIP_FILES);
25208
+ const pluginsDir = path10.join(sourceClaudeDir, "plugins");
25209
+ if (fs7.existsSync(pluginsDir)) {
25210
+ copyDirRecursive(pluginsDir, path10.join(destClaudeDir, "plugins"), 0, SKIP_FILES);
25099
25211
  }
25100
- const skillsDir = path9.join(sourceClaudeDir, "skills");
25101
- if (fs6.existsSync(skillsDir)) {
25102
- copyDirRecursive(skillsDir, path9.join(destClaudeDir, "skills"));
25212
+ const skillsDir = path10.join(sourceClaudeDir, "skills");
25213
+ if (fs7.existsSync(skillsDir)) {
25214
+ copyDirRecursive(skillsDir, path10.join(destClaudeDir, "skills"));
25103
25215
  }
25104
- const scriptsDir = path9.join(sourceClaudeDir, "scripts");
25105
- if (fs6.existsSync(scriptsDir)) {
25106
- copyDirRecursive(scriptsDir, path9.join(destClaudeDir, "scripts"));
25216
+ const scriptsDir = path10.join(sourceClaudeDir, "scripts");
25217
+ if (fs7.existsSync(scriptsDir)) {
25218
+ copyDirRecursive(scriptsDir, path10.join(destClaudeDir, "scripts"));
25107
25219
  }
25108
25220
  applyProjectClaudeOverlay(workspacePath, destClaudeDir);
25109
25221
  writeStrippedMcpServersSnapshot(homeDir ?? os6.homedir(), workspacePath, destClaudeDir);
25222
+ if (configCtx != null && configCtx.worlds_default?.agent_teams_enabled !== false) {
25223
+ mergeHomeSettingsJson(path10.join(destClaudeDir, "settings.json"), {
25224
+ env: { CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1" }
25225
+ });
25226
+ }
25110
25227
  }
25111
25228
  function applyProjectClaudeOverlay(workspacePath, destClaudeDir) {
25112
- const projectClaudeDir = path9.join(workspacePath, ".claude");
25113
- if (!fs6.existsSync(projectClaudeDir))
25229
+ const projectClaudeDir = path10.join(workspacePath, ".claude");
25230
+ if (!fs7.existsSync(projectClaudeDir))
25114
25231
  return;
25115
- const projectSettingsPath = path9.join(projectClaudeDir, "settings.json");
25116
- const destSettingsPath = path9.join(destClaudeDir, "settings.json");
25117
- if (fs6.existsSync(projectSettingsPath)) {
25232
+ const projectSettingsPath = path10.join(projectClaudeDir, "settings.json");
25233
+ const destSettingsPath = path10.join(destClaudeDir, "settings.json");
25234
+ if (fs7.existsSync(projectSettingsPath)) {
25118
25235
  try {
25119
- const projectSettings = JSON.parse(fs6.readFileSync(projectSettingsPath, "utf-8"));
25236
+ const projectSettings = JSON.parse(fs7.readFileSync(projectSettingsPath, "utf-8"));
25120
25237
  delete projectSettings["hooks"];
25121
- const existing = fs6.existsSync(destSettingsPath) ? JSON.parse(fs6.readFileSync(destSettingsPath, "utf-8")) : {};
25238
+ const existing = fs7.existsSync(destSettingsPath) ? JSON.parse(fs7.readFileSync(destSettingsPath, "utf-8")) : {};
25122
25239
  const merged = { ...existing, ...projectSettings, hooks: existing["hooks"] };
25123
- fs6.writeFileSync(destSettingsPath, JSON.stringify(merged, null, 2));
25240
+ fs7.writeFileSync(destSettingsPath, JSON.stringify(merged, null, 2));
25124
25241
  } catch {
25125
25242
  }
25126
25243
  }
25127
- const projectClaudeMd = path9.join(projectClaudeDir, "CLAUDE.md");
25128
- if (fs6.existsSync(projectClaudeMd)) {
25129
- fs6.copyFileSync(projectClaudeMd, path9.join(destClaudeDir, "CLAUDE.md"));
25244
+ const projectClaudeMd = path10.join(projectClaudeDir, "CLAUDE.md");
25245
+ if (fs7.existsSync(projectClaudeMd)) {
25246
+ fs7.copyFileSync(projectClaudeMd, path10.join(destClaudeDir, "CLAUDE.md"));
25130
25247
  }
25131
- const projectAgentsMd = path9.join(projectClaudeDir, "AGENTS.md");
25132
- if (fs6.existsSync(projectAgentsMd)) {
25133
- fs6.copyFileSync(projectAgentsMd, path9.join(destClaudeDir, "AGENTS.md"));
25248
+ const projectAgentsMd = path10.join(projectClaudeDir, "AGENTS.md");
25249
+ if (fs7.existsSync(projectAgentsMd)) {
25250
+ fs7.copyFileSync(projectAgentsMd, path10.join(destClaudeDir, "AGENTS.md"));
25134
25251
  }
25135
25252
  for (const subdir of ["rules", "agents", "plugins", "skills", "scripts"]) {
25136
- const projectSubdir = path9.join(projectClaudeDir, subdir);
25137
- if (fs6.existsSync(projectSubdir)) {
25253
+ const projectSubdir = path10.join(projectClaudeDir, subdir);
25254
+ if (fs7.existsSync(projectSubdir)) {
25138
25255
  const skip = subdir === "plugins" ? SKIP_FILES : /* @__PURE__ */ new Set();
25139
- copyDirRecursive(projectSubdir, path9.join(destClaudeDir, subdir), 0, skip);
25256
+ copyDirRecursive(projectSubdir, path10.join(destClaudeDir, subdir), 0, skip);
25140
25257
  }
25141
25258
  }
25142
25259
  }
@@ -25172,8 +25289,8 @@ function stripMcpServers(mcpServers) {
25172
25289
  return out;
25173
25290
  }
25174
25291
  function writeStrippedMcpServersSnapshot(homeDir, workspacePath, destClaudeDir) {
25175
- const hostMcpServers = readMcpServersFromFile(path9.join(homeDir, ".claude.json"));
25176
- const projectMcpServers = readMcpServersFromFile(path9.join(workspacePath, ".mcp.json"));
25292
+ const hostMcpServers = readMcpServersFromFile(path10.join(homeDir, ".claude.json"));
25293
+ const projectMcpServers = readMcpServersFromFile(path10.join(workspacePath, ".mcp.json"));
25177
25294
  if (Object.keys(hostMcpServers).length === 0 && Object.keys(projectMcpServers).length === 0) {
25178
25295
  return;
25179
25296
  }
@@ -25182,11 +25299,11 @@ function writeStrippedMcpServersSnapshot(homeDir, workspacePath, destClaudeDir)
25182
25299
  ...stripMcpServers(projectMcpServers)
25183
25300
  };
25184
25301
  const output = { mcpServers: stripped };
25185
- fs6.writeFileSync(path9.join(destClaudeDir, ".claude.json"), JSON.stringify(output, null, 2), { mode: 384 });
25302
+ fs7.writeFileSync(path10.join(destClaudeDir, ".claude.json"), JSON.stringify(output, null, 2), { mode: 384 });
25186
25303
  }
25187
25304
  function writeWorldEntitlementsJson(workspacePath, configCtx) {
25188
- const olamDir = path9.join(workspacePath, ".olam");
25189
- fs6.mkdirSync(olamDir, { recursive: true });
25305
+ const olamDir = path10.join(workspacePath, ".olam");
25306
+ fs7.mkdirSync(olamDir, { recursive: true });
25190
25307
  const resolvedRepos = configCtx.repos.map((repo) => {
25191
25308
  const repoEntitlement = repo;
25192
25309
  return {
@@ -25200,14 +25317,14 @@ function writeWorldEntitlementsJson(workspacePath, configCtx) {
25200
25317
  worlds_default: configCtx.worlds_default,
25201
25318
  repos: resolvedRepos
25202
25319
  };
25203
- const filePath = path9.join(olamDir, "world-entitlements.json");
25204
- fs6.writeFileSync(filePath, JSON.stringify(resolved, null, 2), { mode: 420 });
25320
+ const filePath = path10.join(olamDir, "world-entitlements.json");
25321
+ fs7.writeFileSync(filePath, JSON.stringify(resolved, null, 2), { mode: 420 });
25205
25322
  }
25206
25323
  function readMcpServersFromFile(filePath) {
25207
- if (!fs6.existsSync(filePath))
25324
+ if (!fs7.existsSync(filePath))
25208
25325
  return {};
25209
25326
  try {
25210
- const raw = fs6.readFileSync(filePath, "utf-8");
25327
+ const raw = fs7.readFileSync(filePath, "utf-8");
25211
25328
  if (!raw.trim())
25212
25329
  return {};
25213
25330
  const parsed = JSON.parse(raw);
@@ -25243,8 +25360,8 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
25243
25360
  function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new Set()) {
25244
25361
  if (depth > 10)
25245
25362
  return;
25246
- fs6.mkdirSync(dest, { recursive: true });
25247
- for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
25363
+ fs7.mkdirSync(dest, { recursive: true });
25364
+ for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
25248
25365
  const { name } = entry;
25249
25366
  if (skipFiles.has(name))
25250
25367
  continue;
@@ -25254,12 +25371,12 @@ function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new
25254
25371
  continue;
25255
25372
  if (entry.isDirectory() && SKIP_DIRS.has(name))
25256
25373
  continue;
25257
- const srcPath = path9.join(src, name);
25258
- const destPath = path9.join(dest, name);
25374
+ const srcPath = path10.join(src, name);
25375
+ const destPath = path10.join(dest, name);
25259
25376
  if (entry.isSymbolicLink()) {
25260
25377
  let stat;
25261
25378
  try {
25262
- stat = fs6.statSync(srcPath);
25379
+ stat = fs7.statSync(srcPath);
25263
25380
  } catch {
25264
25381
  continue;
25265
25382
  }
@@ -25268,12 +25385,12 @@ function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new
25268
25385
  continue;
25269
25386
  copyDirRecursive(srcPath, destPath, depth + 1, skipFiles);
25270
25387
  } else if (stat.isFile()) {
25271
- fs6.copyFileSync(srcPath, destPath);
25388
+ fs7.copyFileSync(srcPath, destPath);
25272
25389
  }
25273
25390
  } else if (entry.isDirectory()) {
25274
25391
  copyDirRecursive(srcPath, destPath, depth + 1, skipFiles);
25275
25392
  } else {
25276
- fs6.copyFileSync(srcPath, destPath);
25393
+ fs7.copyFileSync(srcPath, destPath);
25277
25394
  }
25278
25395
  }
25279
25396
  }
@@ -25442,9 +25559,9 @@ function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, conf
25442
25559
  }
25443
25560
  }
25444
25561
  for (const repo of repos) {
25445
- const worktreePath = path9.join(workspacePath, repo.name);
25562
+ const worktreePath = path10.join(workspacePath, repo.name);
25446
25563
  const sourcePath = repo.path;
25447
- if (!sourcePath || !fs6.existsSync(worktreePath))
25564
+ if (!sourcePath || !fs7.existsSync(worktreePath))
25448
25565
  continue;
25449
25566
  const envSetup = repo.env_setup;
25450
25567
  if (!envSetup)
@@ -25463,23 +25580,23 @@ function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, conf
25463
25580
  }
25464
25581
  }
25465
25582
  function copyMatchingFiles(sourcePath, destPath, pattern) {
25466
- const fullPattern = path9.join(sourcePath, pattern);
25583
+ const fullPattern = path10.join(sourcePath, pattern);
25467
25584
  if (!pattern.includes("*")) {
25468
- const sourceFile = path9.join(sourcePath, pattern);
25469
- const destFile = path9.join(destPath, pattern);
25470
- if (fs6.existsSync(sourceFile)) {
25471
- fs6.mkdirSync(path9.dirname(destFile), { recursive: true });
25472
- fs6.copyFileSync(sourceFile, destFile);
25585
+ const sourceFile = path10.join(sourcePath, pattern);
25586
+ const destFile = path10.join(destPath, pattern);
25587
+ if (fs7.existsSync(sourceFile)) {
25588
+ fs7.mkdirSync(path10.dirname(destFile), { recursive: true });
25589
+ fs7.copyFileSync(sourceFile, destFile);
25473
25590
  }
25474
25591
  return;
25475
25592
  }
25476
25593
  try {
25477
25594
  const matches2 = globSync(fullPattern);
25478
25595
  for (const match of matches2) {
25479
- const relative2 = path9.relative(sourcePath, match);
25480
- const dest = path9.join(destPath, relative2);
25481
- fs6.mkdirSync(path9.dirname(dest), { recursive: true });
25482
- fs6.copyFileSync(match, dest);
25596
+ const relative2 = path10.relative(sourcePath, match);
25597
+ const dest = path10.join(destPath, relative2);
25598
+ fs7.mkdirSync(path10.dirname(dest), { recursive: true });
25599
+ fs7.copyFileSync(match, dest);
25483
25600
  }
25484
25601
  } catch {
25485
25602
  }
@@ -25487,14 +25604,14 @@ function copyMatchingFiles(sourcePath, destPath, pattern) {
25487
25604
  function generateEnvFromExample(repoPath, overrides) {
25488
25605
  const exampleFiles = [".env.example", ".env.sample", ".env.local.example"];
25489
25606
  for (const exampleName of exampleFiles) {
25490
- const examplePath = path9.join(repoPath, exampleName);
25491
- if (!fs6.existsSync(examplePath))
25607
+ const examplePath = path10.join(repoPath, exampleName);
25608
+ if (!fs7.existsSync(examplePath))
25492
25609
  continue;
25493
25610
  const targetName = exampleName.replace(".example", "").replace(".sample", "");
25494
- const targetPath = path9.join(repoPath, targetName);
25495
- if (fs6.existsSync(targetPath))
25611
+ const targetPath = path10.join(repoPath, targetName);
25612
+ if (fs7.existsSync(targetPath))
25496
25613
  continue;
25497
- const template = fs6.readFileSync(examplePath, "utf-8");
25614
+ const template = fs7.readFileSync(examplePath, "utf-8");
25498
25615
  const generated = template.split("\n").map((line) => {
25499
25616
  const match = /^([A-Z_][A-Z0-9_]*)=(.*)$/.exec(line);
25500
25617
  if (match) {
@@ -25505,13 +25622,13 @@ function generateEnvFromExample(repoPath, overrides) {
25505
25622
  }
25506
25623
  return line;
25507
25624
  }).join("\n");
25508
- fs6.writeFileSync(targetPath, generated);
25625
+ fs7.writeFileSync(targetPath, generated);
25509
25626
  }
25510
25627
  }
25511
25628
  function applyEnvOverrides(repoPath, overrides) {
25512
- const envPath = path9.join(repoPath, ".env");
25513
- if (fs6.existsSync(envPath)) {
25514
- const existing = fs6.readFileSync(envPath, "utf-8");
25629
+ const envPath = path10.join(repoPath, ".env");
25630
+ if (fs7.existsSync(envPath)) {
25631
+ const existing = fs7.readFileSync(envPath, "utf-8");
25515
25632
  const existingKeys = new Set(existing.split("\n").map((l) => l.split("=")[0]?.trim()).filter(Boolean));
25516
25633
  const additions = [];
25517
25634
  for (const [key, value] of Object.entries(overrides)) {
@@ -25520,7 +25637,7 @@ function applyEnvOverrides(repoPath, overrides) {
25520
25637
  }
25521
25638
  }
25522
25639
  if (additions.length > 0) {
25523
- fs6.appendFileSync(envPath, "\n# Olam injected\n" + additions.join("\n") + "\n");
25640
+ fs7.appendFileSync(envPath, "\n# Olam injected\n" + additions.join("\n") + "\n");
25524
25641
  }
25525
25642
  }
25526
25643
  }
@@ -25777,7 +25894,7 @@ __export(world_crystallize_exports, {
25777
25894
  register: () => register12
25778
25895
  });
25779
25896
  import "node:path";
25780
- import * as fs7 from "node:fs";
25897
+ import * as fs8 from "node:fs";
25781
25898
 
25782
25899
  // ../core/dist/crystallize/checksum.js
25783
25900
  import { createHash as createHash2 } from "node:crypto";
@@ -25833,7 +25950,7 @@ function register12(server, ctx, initError) {
25833
25950
  }
25834
25951
  try {
25835
25952
  const thoughtDbPath = getWorldDbPath(world.workspacePath);
25836
- if (!fs7.existsSync(thoughtDbPath)) {
25953
+ if (!fs8.existsSync(thoughtDbPath)) {
25837
25954
  return {
25838
25955
  content: [{
25839
25956
  type: "text",
@@ -26419,23 +26536,23 @@ async function writeManifest(args) {
26419
26536
  capturedAt: args.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
26420
26537
  shots: entries
26421
26538
  };
26422
- const path21 = join12(args.outDir, "manifest.json");
26423
- await writeFile(path21, `${JSON.stringify(manifest, null, 2)}
26539
+ const path22 = join12(args.outDir, "manifest.json");
26540
+ await writeFile(path22, `${JSON.stringify(manifest, null, 2)}
26424
26541
  `, "utf8");
26425
- return { path: path21, manifest };
26542
+ return { path: path22, manifest };
26426
26543
  }
26427
26544
 
26428
26545
  // ../mcp-server/src/tools/_capture/proxy.ts
26429
- import { chmodSync as chmodSync3, mkdirSync as mkdirSync7, statSync as statSync3, unlinkSync as unlinkSync2 } from "node:fs";
26546
+ import { chmodSync as chmodSync3, mkdirSync as mkdirSync8, statSync as statSync3, unlinkSync as unlinkSync2 } from "node:fs";
26430
26547
  import { createServer as createServer2 } from "node:http";
26431
26548
  import { request as httpRequest } from "node:http";
26432
26549
  import { request as httpsRequest } from "node:https";
26433
26550
  import { connect as netConnect } from "node:net";
26434
- import { dirname as dirname6 } from "node:path";
26551
+ import { dirname as dirname7 } from "node:path";
26435
26552
  import { userInfo } from "node:os";
26436
26553
 
26437
26554
  // ../mcp-server/src/tools/_capture/token.ts
26438
- import { createHmac, randomBytes as randomBytes3, timingSafeEqual } from "node:crypto";
26555
+ import { createHmac, randomBytes as randomBytes4, timingSafeEqual } from "node:crypto";
26439
26556
  var HOST_TTL_MAX_SEC = 600;
26440
26557
  var WORLD_TTL_MAX_SEC = 60;
26441
26558
  var WORLD_HOURLY_QUOTA = 50;
@@ -26477,7 +26594,7 @@ function loadHmacKey() {
26477
26594
  );
26478
26595
  _autoKeyWarned = true;
26479
26596
  }
26480
- _hmacKey = randomBytes3(32);
26597
+ _hmacKey = randomBytes4(32);
26481
26598
  return _hmacKey;
26482
26599
  }
26483
26600
  function base64url2(buf) {
@@ -26545,7 +26662,7 @@ function mintToken(input) {
26545
26662
  window2.count++;
26546
26663
  }
26547
26664
  }
26548
- const correlationId = base32Crockford(randomBytes3(16));
26665
+ const correlationId = base32Crockford(randomBytes4(16));
26549
26666
  const exp = Math.floor(_now() / 1e3) + ttlClamped;
26550
26667
  const scope = {
26551
26668
  allowedPaths: input.allowedPaths,
@@ -26676,9 +26793,9 @@ async function startProxy(opts) {
26676
26793
  const liveCompiled = verified.allowedPaths.map(compileGlob);
26677
26794
  const target = parseRequestTarget(req);
26678
26795
  if (!target) return httpReject(400, "invalid_target");
26679
- const path21 = target.pathname;
26680
- if (!liveCompiled.some((re) => re.test(path21))) {
26681
- return httpReject(403, "outside_allow_list", { path: path21 });
26796
+ const path22 = target.pathname;
26797
+ if (!liveCompiled.some((re) => re.test(path22))) {
26798
+ return httpReject(403, "outside_allow_list", { path: path22 });
26682
26799
  }
26683
26800
  const headerWorld = req.headers[WORLD_ASSERT_HEADER];
26684
26801
  const headerWorldStr = typeof headerWorld === "string" ? headerWorld : Array.isArray(headerWorld) && headerWorld.length > 0 ? headerWorld[0] : void 0;
@@ -26833,7 +26950,7 @@ ${JSON.stringify({ error: reason })}`
26833
26950
  };
26834
26951
  }
26835
26952
  function ensureUdsParentDirSafe(udsPath) {
26836
- const parent = dirname6(udsPath);
26953
+ const parent = dirname7(udsPath);
26837
26954
  if (!parent || parent === udsPath || parent === ".") {
26838
26955
  throw new Error(
26839
26956
  `uds_parent_path_invalid: bindUdsPath "${udsPath}" has no manageable parent directory`
@@ -26850,7 +26967,7 @@ function ensureUdsParentDirSafe(udsPath) {
26850
26967
  }
26851
26968
  }
26852
26969
  if (!stat) {
26853
- mkdirSync7(parent, { recursive: true, mode: 448 });
26970
+ mkdirSync8(parent, { recursive: true, mode: 448 });
26854
26971
  return;
26855
26972
  }
26856
26973
  if (!stat.isDirectory()) {
@@ -27457,14 +27574,14 @@ async function runShot(browser, shot, outDir, format, jpegQuality, allowEval, as
27457
27574
  await page.waitForTimeout(shot.afterLoadMs);
27458
27575
  }
27459
27576
  const ext = format === "jpeg" ? "jpg" : "png";
27460
- const path21 = join13(outDir, `${shot.name}.${ext}`);
27577
+ const path22 = join13(outDir, `${shot.name}.${ext}`);
27461
27578
  await page.screenshot({
27462
- path: path21,
27579
+ path: path22,
27463
27580
  type: format,
27464
27581
  ...format === "jpeg" ? { quality: jpegQuality } : {},
27465
27582
  fullPage: false
27466
27583
  });
27467
- return { name: shot.name, path: path21, urlRedacted: redactUrl(shot.url), viewport };
27584
+ return { name: shot.name, path: path22, urlRedacted: redactUrl(shot.url), viewport };
27468
27585
  } finally {
27469
27586
  await context.close();
27470
27587
  }
@@ -27907,12 +28024,12 @@ function openUrl(url) {
27907
28024
  var HOST_CP_URL = "http://127.0.0.1:19000";
27908
28025
  async function readHostCpToken2() {
27909
28026
  try {
27910
- const { default: fs17 } = await import("node:fs");
28027
+ const { default: fs18 } = await import("node:fs");
27911
28028
  const { default: os10 } = await import("node:os");
27912
- const { default: path21 } = await import("node:path");
27913
- const tp = path21.join(os10.homedir(), ".olam", "host-cp.token");
27914
- if (!fs17.existsSync(tp)) return { token: null };
27915
- return { token: fs17.readFileSync(tp, "utf-8").trim() };
28029
+ const { default: path22 } = await import("node:path");
28030
+ const tp = path22.join(os10.homedir(), ".olam", "host-cp.token");
28031
+ if (!fs18.existsSync(tp)) return { token: null };
28032
+ return { token: fs18.readFileSync(tp, "utf-8").trim() };
27916
28033
  } catch {
27917
28034
  return { token: null };
27918
28035
  }
@@ -28192,8 +28309,8 @@ function createServer3(ctx, initError) {
28192
28309
  }
28193
28310
 
28194
28311
  // ../core/dist/config/loader.js
28195
- import * as fs9 from "node:fs";
28196
- import * as path12 from "node:path";
28312
+ import * as fs10 from "node:fs";
28313
+ import * as path13 from "node:path";
28197
28314
  import { parse as parseYaml2 } from "yaml";
28198
28315
 
28199
28316
  // ../core/dist/config/schema.js
@@ -28523,11 +28640,11 @@ function substituteEnvVars(obj) {
28523
28640
  }
28524
28641
 
28525
28642
  // ../core/dist/config/dotenv.js
28526
- import * as fs8 from "node:fs";
28643
+ import * as fs9 from "node:fs";
28527
28644
  function loadDotEnv(envPath) {
28528
- if (!fs8.existsSync(envPath))
28645
+ if (!fs9.existsSync(envPath))
28529
28646
  return;
28530
- const content = fs8.readFileSync(envPath, "utf-8");
28647
+ const content = fs9.readFileSync(envPath, "utf-8");
28531
28648
  for (const line of content.split("\n")) {
28532
28649
  const trimmed = line.trim();
28533
28650
  if (!trimmed || trimmed.startsWith("#"))
@@ -28546,18 +28663,18 @@ function loadDotEnv(envPath) {
28546
28663
  // ../core/dist/config/loader.js
28547
28664
  function findConfigFile(startDir) {
28548
28665
  const searched = [];
28549
- let current = path12.resolve(startDir);
28666
+ let current = path13.resolve(startDir);
28550
28667
  while (true) {
28551
- const newLayout = path12.join(current, CONFIG_DIR_NAME, CONFIG_FILENAME);
28552
- const legacyLayout = path12.join(current, LEGACY_CONFIG_FILENAME);
28668
+ const newLayout = path13.join(current, CONFIG_DIR_NAME, CONFIG_FILENAME);
28669
+ const legacyLayout = path13.join(current, LEGACY_CONFIG_FILENAME);
28553
28670
  searched.push(newLayout, legacyLayout);
28554
- if (fs9.existsSync(newLayout)) {
28671
+ if (fs10.existsSync(newLayout)) {
28555
28672
  return { path: newLayout, isLegacy: false };
28556
28673
  }
28557
- if (fs9.existsSync(legacyLayout)) {
28674
+ if (fs10.existsSync(legacyLayout)) {
28558
28675
  return { path: legacyLayout, isLegacy: true };
28559
28676
  }
28560
- const parent = path12.dirname(current);
28677
+ const parent = path13.dirname(current);
28561
28678
  if (parent === current)
28562
28679
  break;
28563
28680
  current = parent;
@@ -28572,12 +28689,12 @@ function loadConfig(startDir) {
28572
28689
  Run /olam:init to migrate to .olam/config.yaml
28573
28690
  `);
28574
28691
  } else {
28575
- const envPath = path12.join(path12.dirname(found.path), ".env");
28692
+ const envPath = path13.join(path13.dirname(found.path), ".env");
28576
28693
  loadDotEnv(envPath);
28577
28694
  }
28578
28695
  let rawContent;
28579
28696
  try {
28580
- rawContent = fs9.readFileSync(found.path, "utf-8");
28697
+ rawContent = fs10.readFileSync(found.path, "utf-8");
28581
28698
  } catch (err) {
28582
28699
  throw new Error(`Failed to read ${found.path}: ${err instanceof Error ? err.message : String(err)}`);
28583
28700
  }
@@ -28607,11 +28724,11 @@ function loadConfig(startDir) {
28607
28724
  }
28608
28725
 
28609
28726
  // ../core/dist/world/manager.js
28610
- import * as crypto4 from "node:crypto";
28727
+ import * as crypto5 from "node:crypto";
28611
28728
  import { execSync as execSync4 } from "node:child_process";
28612
- import * as fs14 from "node:fs";
28729
+ import * as fs15 from "node:fs";
28613
28730
  import * as os8 from "node:os";
28614
- import * as path18 from "node:path";
28731
+ import * as path19 from "node:path";
28615
28732
 
28616
28733
  // ../core/dist/world/state.js
28617
28734
  var VALID_TRANSITIONS = {
@@ -28693,8 +28810,8 @@ function resolveDevboxImage(config2, tag) {
28693
28810
 
28694
28811
  // ../core/dist/world/worktree.js
28695
28812
  import { execFileSync as execFileSync2 } from "node:child_process";
28696
- import * as fs10 from "node:fs";
28697
- import * as path13 from "node:path";
28813
+ import * as fs11 from "node:fs";
28814
+ import * as path14 from "node:path";
28698
28815
  function resolveGitDir(repo) {
28699
28816
  if (repo.path) {
28700
28817
  return repo.path;
@@ -28704,11 +28821,11 @@ function resolveGitDir(repo) {
28704
28821
  async function createWorktrees(repos, worldId, workspacePath, branch) {
28705
28822
  const created = [];
28706
28823
  for (const repo of repos) {
28707
- const worktreePath = path13.join(workspacePath, repo.name);
28824
+ const worktreePath = path14.join(workspacePath, repo.name);
28708
28825
  const gitDir = resolveGitDir(repo);
28709
28826
  const branchName = branch || `olam/${worldId}`;
28710
28827
  try {
28711
- fs10.mkdirSync(path13.dirname(worktreePath), { recursive: true });
28828
+ fs11.mkdirSync(path14.dirname(worktreePath), { recursive: true });
28712
28829
  execFileSync2("git", ["worktree", "add", worktreePath, "-b", branchName], {
28713
28830
  cwd: gitDir,
28714
28831
  stdio: "pipe"
@@ -28741,7 +28858,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
28741
28858
  }
28742
28859
  async function removeWorktrees(repos, workspacePath) {
28743
28860
  for (const repo of repos) {
28744
- const worktreePath = path13.join(workspacePath, repo.name);
28861
+ const worktreePath = path14.join(workspacePath, repo.name);
28745
28862
  let gitDir;
28746
28863
  try {
28747
28864
  gitDir = resolveGitDir(repo);
@@ -28816,9 +28933,9 @@ function removeBranch(repo, branch) {
28816
28933
 
28817
28934
  // ../core/dist/world/baseline-diff.js
28818
28935
  import { execFileSync as execFileSync3 } from "node:child_process";
28819
- import * as fs11 from "node:fs";
28936
+ import * as fs12 from "node:fs";
28820
28937
  import * as os7 from "node:os";
28821
- import * as path14 from "node:path";
28938
+ import * as path15 from "node:path";
28822
28939
  var DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
28823
28940
  function expandHome(p, homedir11) {
28824
28941
  return p.replace(/^~(?=$|\/|\\)/, homedir11());
@@ -28845,9 +28962,9 @@ ${stderr}`;
28845
28962
  function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
28846
28963
  const exec = deps.exec ?? ((cmd, args, opts) => execFileSync3(cmd, args, opts));
28847
28964
  const homedir11 = deps.homedir ?? (() => os7.homedir());
28848
- const baselineDir = path14.join(workspacePath, ".olam", "baseline");
28965
+ const baselineDir = path15.join(workspacePath, ".olam", "baseline");
28849
28966
  try {
28850
- fs11.mkdirSync(baselineDir, { recursive: true });
28967
+ fs12.mkdirSync(baselineDir, { recursive: true });
28851
28968
  } catch (err) {
28852
28969
  const msg = err instanceof Error ? err.message : String(err);
28853
28970
  console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
@@ -28859,9 +28976,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
28859
28976
  if (!repo.path)
28860
28977
  continue;
28861
28978
  const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
28862
- const outPath = path14.join(baselineDir, filename);
28979
+ const outPath = path15.join(baselineDir, filename);
28863
28980
  const repoPath = expandHome(repo.path, homedir11);
28864
- if (!fs11.existsSync(repoPath)) {
28981
+ if (!fs12.existsSync(repoPath)) {
28865
28982
  writeBaselineFile(outPath, `# repo: ${repo.name}
28866
28983
  # (skipped: path ${repoPath} does not exist)
28867
28984
  `);
@@ -28928,7 +29045,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
28928
29045
  }
28929
29046
  function writeBaselineFile(outPath, content) {
28930
29047
  try {
28931
- fs11.writeFileSync(outPath, content);
29048
+ fs12.writeFileSync(outPath, content);
28932
29049
  } catch (err) {
28933
29050
  const msg = err instanceof Error ? err.message : String(err);
28934
29051
  console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
@@ -28936,8 +29053,8 @@ function writeBaselineFile(outPath, content) {
28936
29053
  }
28937
29054
  function stripWorktreeEdits(repos, workspacePath) {
28938
29055
  for (const repo of repos) {
28939
- const worktreePath = path14.join(workspacePath, repo.name);
28940
- if (!fs11.existsSync(worktreePath))
29056
+ const worktreePath = path15.join(workspacePath, repo.name);
29057
+ if (!fs12.existsSync(worktreePath))
28941
29058
  continue;
28942
29059
  try {
28943
29060
  execFileSync3("git", ["checkout", "--", "."], {
@@ -28967,12 +29084,12 @@ function formatBaselineSummary(result) {
28967
29084
  }
28968
29085
 
28969
29086
  // ../core/dist/world/context-injection.js
28970
- import * as fs12 from "node:fs";
28971
- import * as path15 from "node:path";
29087
+ import * as fs13 from "node:fs";
29088
+ import * as path16 from "node:path";
28972
29089
  function injectWorldContext(opts) {
28973
29090
  const { world, task, linearTicketId, claudeMdExtra, taskContext, services, pleriPlaneUrl } = opts;
28974
- const claudeDir = path15.join(world.workspacePath, ".claude");
28975
- fs12.mkdirSync(claudeDir, { recursive: true });
29091
+ const claudeDir = path16.join(world.workspacePath, ".claude");
29092
+ fs13.mkdirSync(claudeDir, { recursive: true });
28976
29093
  const sections = [];
28977
29094
  sections.push(`# Olam World: ${world.name}`);
28978
29095
  sections.push("");
@@ -29133,7 +29250,7 @@ function injectWorldContext(opts) {
29133
29250
  sections.push("");
29134
29251
  }
29135
29252
  const content = sections.join("\n");
29136
- fs12.writeFileSync(path15.join(claudeDir, "CLAUDE.md"), content);
29253
+ fs13.writeFileSync(path16.join(claudeDir, "CLAUDE.md"), content);
29137
29254
  }
29138
29255
  function formatTaskSource(ctx) {
29139
29256
  if (ctx.source === "linear" && ctx.ticketId) {
@@ -29147,9 +29264,9 @@ function formatTaskSource(ctx) {
29147
29264
  function hasPlanFile(world) {
29148
29265
  if (world.repos.length === 0)
29149
29266
  return false;
29150
- const plansDir = path15.join(world.workspacePath, world.repos[0], "docs", "plans");
29267
+ const plansDir = path16.join(world.workspacePath, world.repos[0], "docs", "plans");
29151
29268
  try {
29152
- return fs12.existsSync(plansDir) && fs12.readdirSync(plansDir).length > 0;
29269
+ return fs13.existsSync(plansDir) && fs13.readdirSync(plansDir).length > 0;
29153
29270
  } catch {
29154
29271
  return false;
29155
29272
  }
@@ -29376,7 +29493,7 @@ async function installStack(exec, repos, stacks) {
29376
29493
 
29377
29494
  // ../core/dist/world/stack-image.js
29378
29495
  import { execSync as execSync2 } from "node:child_process";
29379
- import * as crypto3 from "node:crypto";
29496
+ import * as crypto4 from "node:crypto";
29380
29497
  var BASE_IMAGE = "olam-devbox";
29381
29498
  var LABEL_PREFIX = "olam.stack-image";
29382
29499
  var MAX_TAG_LENGTH = 128;
@@ -29430,14 +29547,14 @@ function getBaseImageDigest() {
29430
29547
  cachedBaseDigest = digest.replace("sha256:", "").slice(0, 16);
29431
29548
  return cachedBaseDigest;
29432
29549
  } catch {
29433
- cachedBaseDigest = crypto3.createHash("sha256").update("unknown").digest("hex").slice(0, 16);
29550
+ cachedBaseDigest = crypto4.createHash("sha256").update("unknown").digest("hex").slice(0, 16);
29434
29551
  return cachedBaseDigest;
29435
29552
  }
29436
29553
  }
29437
29554
  function sanitizeTag(raw) {
29438
29555
  let tag = raw.toLowerCase().replace(/[^a-z0-9._-]/g, "-");
29439
29556
  if (tag.length > MAX_TAG_LENGTH) {
29440
- const hash = crypto3.createHash("sha256").update(raw).digest("hex").slice(0, 12);
29557
+ const hash = crypto4.createHash("sha256").update(raw).digest("hex").slice(0, 12);
29441
29558
  tag = tag.slice(0, MAX_TAG_LENGTH - 13) + "_" + hash;
29442
29559
  }
29443
29560
  return tag;
@@ -29815,14 +29932,14 @@ function gcloudAvailable(execFn = defaultExecFn) {
29815
29932
  }
29816
29933
 
29817
29934
  // ../core/dist/world/olam-yaml.js
29818
- import * as path16 from "node:path";
29935
+ import * as path17 from "node:path";
29819
29936
  import YAML2 from "yaml";
29820
29937
  function enrichReposWithManifests(repos, workspacePath) {
29821
29938
  return repos.map((repo) => {
29822
29939
  if (repo.manifest !== void 0 && repo.manifest !== null) {
29823
29940
  return repo;
29824
29941
  }
29825
- const repoDir = path16.join(workspacePath, repo.name);
29942
+ const repoDir = path17.join(workspacePath, repo.name);
29826
29943
  let manifest = null;
29827
29944
  try {
29828
29945
  manifest = loadRepoManifest(repoDir);
@@ -29837,8 +29954,8 @@ function enrichReposWithManifests(repos, workspacePath) {
29837
29954
  }
29838
29955
 
29839
29956
  // ../core/dist/policies/loader.js
29840
- import * as fs13 from "node:fs";
29841
- import * as path17 from "node:path";
29957
+ import * as fs14 from "node:fs";
29958
+ import * as path18 from "node:path";
29842
29959
  import { parse as parseYaml3 } from "yaml";
29843
29960
  function parseFrontmatter(content) {
29844
29961
  const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
@@ -29858,20 +29975,20 @@ function toStringArray(v) {
29858
29975
  return v.filter((x) => typeof x === "string");
29859
29976
  }
29860
29977
  function loadPolicies(workspaceRoot) {
29861
- const policiesDir = path17.join(workspaceRoot, ".olam", "policies");
29862
- if (!fs13.existsSync(policiesDir))
29978
+ const policiesDir = path18.join(workspaceRoot, ".olam", "policies");
29979
+ if (!fs14.existsSync(policiesDir))
29863
29980
  return [];
29864
29981
  let files;
29865
29982
  try {
29866
- files = fs13.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
29983
+ files = fs14.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
29867
29984
  } catch {
29868
29985
  return [];
29869
29986
  }
29870
29987
  const policies = [];
29871
29988
  for (const file of files) {
29872
- const filePath = path17.join(policiesDir, file);
29989
+ const filePath = path18.join(policiesDir, file);
29873
29990
  try {
29874
- const content = fs13.readFileSync(filePath, "utf8");
29991
+ const content = fs14.readFileSync(filePath, "utf8");
29875
29992
  const parsed = parseFrontmatter(content);
29876
29993
  if (!parsed) {
29877
29994
  console.warn(`[policies] skipping ${file}: no valid frontmatter block`);
@@ -30106,12 +30223,42 @@ ${stderr.split("\n").slice(0, 3).join(" ")}`);
30106
30223
  dockerExec(`cd ${repoDir} && git checkout -b ${branch}`);
30107
30224
  }
30108
30225
  if (ghToken) {
30226
+ const olamUserPresent = (() => {
30227
+ try {
30228
+ dockerExec(`id olam`);
30229
+ return true;
30230
+ } catch {
30231
+ return false;
30232
+ }
30233
+ })();
30234
+ if (!olamUserPresent) {
30235
+ const imageName = (() => {
30236
+ try {
30237
+ const { execSync: execSync6 } = __require("node:child_process");
30238
+ return execSync6(`docker inspect ${containerName} --format '{{.Config.Image}}'`, {
30239
+ encoding: "utf8",
30240
+ timeout: 5e3
30241
+ }).trim() || "(unknown)";
30242
+ } catch {
30243
+ return "(unknown)";
30244
+ }
30245
+ })();
30246
+ console.warn(`[world] gh auth setup skipped for ${containerName}: container has no \`olam\` user.
30247
+ Image: ${imageName}
30248
+ Likely cause: corrupt local image, a custom devbox image without
30249
+ the olam user (line 10 of devbox.Dockerfile), or NSS resolver
30250
+ failure under cross-arch QEMU emulation.
30251
+ Remedy: docker rmi olam-devbox:latest && olam upgrade -y
30252
+ (or set OLAM_DEVBOX_IMAGE to a known-good ref before \`olam create\`).
30253
+ PR push from inside the world will not work until this is resolved.`);
30254
+ return;
30255
+ }
30109
30256
  let tokenWritten = false;
30110
30257
  try {
30111
30258
  dockerExec(`which gh || (sudo apt-get update -qq && sudo apt-get install -y -qq gh) 2>/dev/null`);
30112
30259
  dockerExec(`printf '%s' '${ghToken.replace(/'/g, "'\\''")}' > /tmp/.gh-token && chmod 600 /tmp/.gh-token`);
30113
30260
  tokenWritten = true;
30114
- dockerExec(`sudo chown olam:olam /home/olam/.config`);
30261
+ dockerExec(`sudo chown olam:olam /home/olam/.config 2>/dev/null || true`);
30115
30262
  dockerExec(`gh auth login --with-token < /tmp/.gh-token`);
30116
30263
  dockerExec(`gh auth setup-git`);
30117
30264
  } catch (err) {
@@ -30328,6 +30475,15 @@ var WorkspaceNotFoundError = class extends Error {
30328
30475
  this.name = "WorkspaceNotFoundError";
30329
30476
  }
30330
30477
  };
30478
+ var RepoSelectionRequiredError = class extends Error {
30479
+ availableRepos;
30480
+ constructor(availableRepos) {
30481
+ const list = availableRepos.length > 0 ? availableRepos.join(", ") : "(none configured)";
30482
+ super(`--repos or --workspace is required. Available repos: ${list}. Pick the subset you actually want \u2014 implicit "all repos" was removed to prevent accidental multi-repo bootstraps.`);
30483
+ this.availableRepos = availableRepos;
30484
+ this.name = "RepoSelectionRequiredError";
30485
+ }
30486
+ };
30331
30487
  function buildManifestRuntime(worldId, repos) {
30332
30488
  const runtimeRepos = [];
30333
30489
  for (const repo of repos) {
@@ -30380,7 +30536,7 @@ var WorldManager = class {
30380
30536
  }
30381
30537
  }
30382
30538
  const worldId = generateWorldId();
30383
- const workspacePath = path18.join(os8.homedir(), ".olam", "worlds", worldId);
30539
+ const workspacePath = path19.join(os8.homedir(), ".olam", "worlds", worldId);
30384
30540
  const portOffset = this.registry.getNextPortOffset();
30385
30541
  const branch = opts.branchName ?? `olam/${worldId}`;
30386
30542
  const repos = this.resolveReposWithWorkspace(opts);
@@ -30437,37 +30593,37 @@ var WorldManager = class {
30437
30593
  if (!repo.path)
30438
30594
  continue;
30439
30595
  const sourceRoot = repo.path.replace(/^~/, os8.homedir());
30440
- const worktreeRoot = path18.join(workspacePath, repo.name);
30441
- if (!fs14.existsSync(sourceRoot) || !fs14.existsSync(worktreeRoot))
30596
+ const worktreeRoot = path19.join(workspacePath, repo.name);
30597
+ if (!fs15.existsSync(sourceRoot) || !fs15.existsSync(worktreeRoot))
30442
30598
  continue;
30443
30599
  let copied = 0;
30444
30600
  for (const pattern of RUNTIME_FILE_PATTERNS) {
30445
30601
  const matches2 = [];
30446
30602
  if (pattern.includes("*")) {
30447
- const [dir, glob] = [path18.dirname(pattern), path18.basename(pattern)];
30448
- const sourceDir = path18.join(sourceRoot, dir);
30449
- if (fs14.existsSync(sourceDir)) {
30603
+ const [dir, glob] = [path19.dirname(pattern), path19.basename(pattern)];
30604
+ const sourceDir = path19.join(sourceRoot, dir);
30605
+ if (fs15.existsSync(sourceDir)) {
30450
30606
  const ext = glob.replace(/^\*+/, "");
30451
30607
  try {
30452
- for (const entry of fs14.readdirSync(sourceDir)) {
30608
+ for (const entry of fs15.readdirSync(sourceDir)) {
30453
30609
  if (ext === "" || entry.endsWith(ext))
30454
- matches2.push(path18.join(dir, entry));
30610
+ matches2.push(path19.join(dir, entry));
30455
30611
  }
30456
30612
  } catch {
30457
30613
  }
30458
30614
  }
30459
- } else if (fs14.existsSync(path18.join(sourceRoot, pattern))) {
30615
+ } else if (fs15.existsSync(path19.join(sourceRoot, pattern))) {
30460
30616
  matches2.push(pattern);
30461
30617
  }
30462
30618
  for (const rel of matches2) {
30463
- const src = path18.join(sourceRoot, rel);
30464
- const dst = path18.join(worktreeRoot, rel);
30619
+ const src = path19.join(sourceRoot, rel);
30620
+ const dst = path19.join(worktreeRoot, rel);
30465
30621
  try {
30466
- const st = fs14.statSync(src);
30622
+ const st = fs15.statSync(src);
30467
30623
  if (!st.isFile())
30468
30624
  continue;
30469
- fs14.mkdirSync(path18.dirname(dst), { recursive: true });
30470
- fs14.copyFileSync(src, dst);
30625
+ fs15.mkdirSync(path19.dirname(dst), { recursive: true });
30626
+ fs15.copyFileSync(src, dst);
30471
30627
  copied++;
30472
30628
  } catch {
30473
30629
  }
@@ -30567,7 +30723,7 @@ var WorldManager = class {
30567
30723
  try {
30568
30724
  const hostExec = makeHostExecFn();
30569
30725
  for (const repo of repos) {
30570
- const repoDir = path18.join(workspacePath, repo.name);
30726
+ const repoDir = path19.join(workspacePath, repo.name);
30571
30727
  if (repo.stack && Object.keys(repo.stack).length > 0) {
30572
30728
  preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
30573
30729
  } else {
@@ -30624,10 +30780,10 @@ var WorldManager = class {
30624
30780
  const worldEnv = {};
30625
30781
  if (opts.task)
30626
30782
  worldEnv.OLAM_TASK = opts.task;
30627
- const r2CredsPath = path18.join(os8.homedir(), ".olam", "r2-credentials.json");
30628
- if (fs14.existsSync(r2CredsPath)) {
30783
+ const r2CredsPath = path19.join(os8.homedir(), ".olam", "r2-credentials.json");
30784
+ if (fs15.existsSync(r2CredsPath)) {
30629
30785
  try {
30630
- const r2Raw = fs14.readFileSync(r2CredsPath, "utf-8").trim();
30786
+ const r2Raw = fs15.readFileSync(r2CredsPath, "utf-8").trim();
30631
30787
  if (r2Raw.length > 0) {
30632
30788
  const r2 = JSON.parse(r2Raw);
30633
30789
  if (typeof r2.account_id === "string")
@@ -30644,10 +30800,10 @@ var WorldManager = class {
30644
30800
  } catch {
30645
30801
  }
30646
30802
  }
30647
- const keysYamlPath = path18.join(os8.homedir(), ".olam", "keys.yaml");
30648
- if (fs14.existsSync(keysYamlPath)) {
30803
+ const keysYamlPath = path19.join(os8.homedir(), ".olam", "keys.yaml");
30804
+ if (fs15.existsSync(keysYamlPath)) {
30649
30805
  try {
30650
- const keysRaw = fs14.readFileSync(keysYamlPath, "utf-8").trim();
30806
+ const keysRaw = fs15.readFileSync(keysYamlPath, "utf-8").trim();
30651
30807
  if (keysRaw.length > 0) {
30652
30808
  const parsed = YAML3.parse(keysRaw);
30653
30809
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
@@ -30694,10 +30850,10 @@ var WorldManager = class {
30694
30850
  worldEnv[k] = v;
30695
30851
  }
30696
30852
  for (const { repoName, relativePath, content } of fileWrites) {
30697
- const absPath = path18.join(workspacePath, repoName, relativePath);
30853
+ const absPath = path19.join(workspacePath, repoName, relativePath);
30698
30854
  try {
30699
- fs14.mkdirSync(path18.dirname(absPath), { recursive: true });
30700
- fs14.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
30855
+ fs15.mkdirSync(path19.dirname(absPath), { recursive: true });
30856
+ fs15.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
30701
30857
  mode: 384
30702
30858
  });
30703
30859
  console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
@@ -30849,7 +31005,7 @@ var WorldManager = class {
30849
31005
  let taskWithPolicies = opts.task;
30850
31006
  try {
30851
31007
  const allPolicies = repos.flatMap((repo) => {
30852
- const repoWorktree = path18.join(workspacePath, repo.name);
31008
+ const repoWorktree = path19.join(workspacePath, repo.name);
30853
31009
  return loadPolicies(repoWorktree);
30854
31010
  });
30855
31011
  const seen = /* @__PURE__ */ new Set();
@@ -30865,8 +31021,8 @@ var WorldManager = class {
30865
31021
  ${opts.task}`;
30866
31022
  execSync4(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
30867
31023
  for (const repo of repos) {
30868
- const policiesDir = path18.join(workspacePath, repo.name, ".olam", "policies");
30869
- if (fs14.existsSync(policiesDir)) {
31024
+ const policiesDir = path19.join(workspacePath, repo.name, ".olam", "policies");
31025
+ if (fs15.existsSync(policiesDir)) {
30870
31026
  execSync4(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
30871
31027
  }
30872
31028
  }
@@ -30945,8 +31101,8 @@ ${opts.task}`;
30945
31101
  } catch {
30946
31102
  }
30947
31103
  try {
30948
- fs14.rmSync(world.workspacePath, { recursive: true, force: true });
30949
- if (fs14.existsSync(world.workspacePath)) {
31104
+ fs15.rmSync(world.workspacePath, { recursive: true, force: true });
31105
+ if (fs15.existsSync(world.workspacePath)) {
30950
31106
  console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
30951
31107
  }
30952
31108
  } catch (err) {
@@ -31001,7 +31157,10 @@ ${opts.task}`;
31001
31157
  * Resolution precedence (matches the CF worker exactly):
31002
31158
  * 1. inline `opts.repos` names → look up in `config.repos`
31003
31159
  * 2. named `opts.workspace` → load catalog YAML, map via workspaceToRepoConfigs
31004
- * 3. fallbackevery repo declared in the project's config.yaml
31160
+ * 3. neitherthrow `RepoSelectionRequiredError`. The historical
31161
+ * "include every repo in config.yaml" fallback silently fanned a
31162
+ * single-repo audit into 7-repo bootstraps and steered
31163
+ * `image_selectors` to a wider tag than intended.
31005
31164
  */
31006
31165
  resolveReposWithWorkspace(opts) {
31007
31166
  if (opts.repos && opts.repos.length > 0) {
@@ -31013,7 +31172,7 @@ ${opts.task}`;
31013
31172
  throw new WorkspaceNotFoundError(opts.workspace);
31014
31173
  return workspaceToRepoConfigs(ws);
31015
31174
  }
31016
- return this.resolveRepos(void 0);
31175
+ throw new RepoSelectionRequiredError(this.config.repos.map((r) => r.name));
31017
31176
  }
31018
31177
  resolveRepos(repoNames) {
31019
31178
  if (!repoNames || repoNames.length === 0) {
@@ -31031,14 +31190,14 @@ ${opts.task}`;
31031
31190
  return names.map((name) => this.config.repos.find((r) => r.name === name)).filter((r) => r !== void 0);
31032
31191
  }
31033
31192
  transportPlanFile(planFilePath, workspacePath, repoNames) {
31034
- const planContent = fs14.readFileSync(planFilePath, "utf-8");
31035
- const planFileName = path18.basename(planFilePath);
31193
+ const planContent = fs15.readFileSync(planFilePath, "utf-8");
31194
+ const planFileName = path19.basename(planFilePath);
31036
31195
  const targetRepo = repoNames[0];
31037
31196
  if (!targetRepo)
31038
31197
  return;
31039
- const plansDir = path18.join(workspacePath, targetRepo, "docs", "plans");
31040
- fs14.mkdirSync(plansDir, { recursive: true });
31041
- fs14.writeFileSync(path18.join(plansDir, planFileName), planContent);
31198
+ const plansDir = path19.join(workspacePath, targetRepo, "docs", "plans");
31199
+ fs15.mkdirSync(plansDir, { recursive: true });
31200
+ fs15.writeFileSync(path19.join(plansDir, planFileName), planContent);
31042
31201
  }
31043
31202
  resolveServices(repos) {
31044
31203
  const services = [];
@@ -31123,8 +31282,8 @@ import * as http2 from "node:http";
31123
31282
 
31124
31283
  // ../core/dist/dashboard/server.js
31125
31284
  import * as http from "node:http";
31126
- import * as fs15 from "node:fs";
31127
- import * as path19 from "node:path";
31285
+ import * as fs16 from "node:fs";
31286
+ import * as path20 from "node:path";
31128
31287
  import { fileURLToPath as fileURLToPath2 } from "node:url";
31129
31288
 
31130
31289
  // ../core/dist/dashboard/serialize.js
@@ -31459,7 +31618,7 @@ function notFound(res) {
31459
31618
  }
31460
31619
  function openThoughtStore(workspacePath) {
31461
31620
  const dbPath = getWorldDbPath(workspacePath);
31462
- if (!fs15.existsSync(dbPath))
31621
+ if (!fs16.existsSync(dbPath))
31463
31622
  return null;
31464
31623
  return new ThoughtLocalStore(dbPath);
31465
31624
  }
@@ -31630,13 +31789,13 @@ function findSessionInWorld(registry2, sessionId) {
31630
31789
  }
31631
31790
  function createDashboardServer(opts) {
31632
31791
  const { port, registry: registry2 } = opts;
31633
- const thisDir = path19.dirname(fileURLToPath2(import.meta.url));
31634
- const defaultPublicDir = path19.resolve(thisDir, "../../../control-plane/public");
31792
+ const thisDir = path20.dirname(fileURLToPath2(import.meta.url));
31793
+ const defaultPublicDir = path20.resolve(thisDir, "../../../control-plane/public");
31635
31794
  const publicDir = opts.publicDir ?? defaultPublicDir;
31636
- let hasPublicDir = fs15.existsSync(publicDir);
31795
+ let hasPublicDir = fs16.existsSync(publicDir);
31637
31796
  const server = http.createServer((req, res) => {
31638
31797
  if (!hasPublicDir) {
31639
- hasPublicDir = fs15.existsSync(publicDir);
31798
+ hasPublicDir = fs16.existsSync(publicDir);
31640
31799
  }
31641
31800
  const host = req.headers.host ?? `localhost:${port}`;
31642
31801
  const url = new URL(req.url ?? "/", `http://${host}`);
@@ -31910,22 +32069,22 @@ function createDashboardServer(opts) {
31910
32069
  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>`);
31911
32070
  return;
31912
32071
  }
31913
- let filePath = path19.join(publicDir, pathname === "/" ? "index.html" : pathname);
32072
+ let filePath = path20.join(publicDir, pathname === "/" ? "index.html" : pathname);
31914
32073
  if (!filePath.startsWith(publicDir)) {
31915
32074
  notFound(res);
31916
32075
  return;
31917
32076
  }
31918
- if (fs15.existsSync(filePath) && fs15.statSync(filePath).isFile()) {
31919
- const ext = path19.extname(filePath);
32077
+ if (fs16.existsSync(filePath) && fs16.statSync(filePath).isFile()) {
32078
+ const ext = path20.extname(filePath);
31920
32079
  const contentType = MIME[ext] ?? "application/octet-stream";
31921
32080
  res.writeHead(200, { "Content-Type": contentType });
31922
- fs15.createReadStream(filePath).pipe(res);
32081
+ fs16.createReadStream(filePath).pipe(res);
31923
32082
  return;
31924
32083
  }
31925
- filePath = path19.join(publicDir, "index.html");
31926
- if (fs15.existsSync(filePath)) {
32084
+ filePath = path20.join(publicDir, "index.html");
32085
+ if (fs16.existsSync(filePath)) {
31927
32086
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
31928
- fs15.createReadStream(filePath).pipe(res);
32087
+ fs16.createReadStream(filePath).pipe(res);
31929
32088
  return;
31930
32089
  }
31931
32090
  notFound(res);
@@ -31935,17 +32094,17 @@ function createDashboardServer(opts) {
31935
32094
  }
31936
32095
 
31937
32096
  // ../core/dist/dashboard/state.js
31938
- import * as fs16 from "node:fs";
32097
+ import * as fs17 from "node:fs";
31939
32098
  import * as os9 from "node:os";
31940
- import * as path20 from "node:path";
31941
- var STATE_PATH = path20.join(os9.homedir(), ".olam", "dashboard.json");
32099
+ import * as path21 from "node:path";
32100
+ var STATE_PATH = path21.join(os9.homedir(), ".olam", "dashboard.json");
31942
32101
  function saveDashboardState(state) {
31943
- fs16.mkdirSync(path20.dirname(STATE_PATH), { recursive: true });
31944
- fs16.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
32102
+ fs17.mkdirSync(path21.dirname(STATE_PATH), { recursive: true });
32103
+ fs17.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
31945
32104
  }
31946
32105
  function loadDashboardState() {
31947
32106
  try {
31948
- const raw = fs16.readFileSync(STATE_PATH, "utf-8");
32107
+ const raw = fs17.readFileSync(STATE_PATH, "utf-8");
31949
32108
  return JSON.parse(raw);
31950
32109
  } catch {
31951
32110
  return null;
@@ -31953,7 +32112,7 @@ function loadDashboardState() {
31953
32112
  }
31954
32113
  function clearDashboardState() {
31955
32114
  try {
31956
- fs16.unlinkSync(STATE_PATH);
32115
+ fs17.unlinkSync(STATE_PATH);
31957
32116
  } catch {
31958
32117
  }
31959
32118
  }
@@ -32233,8 +32392,8 @@ var PleriClient = class {
32233
32392
  };
32234
32393
 
32235
32394
  // ../mcp-server/src/env-loader.ts
32236
- import { readFileSync as readFileSync14, existsSync as existsSync17, statSync as statSync6 } from "node:fs";
32237
- import { join as join23, dirname as dirname12, resolve as resolve5 } from "node:path";
32395
+ import { readFileSync as readFileSync15, existsSync as existsSync18, statSync as statSync6 } from "node:fs";
32396
+ import { join as join23, dirname as dirname13, resolve as resolve5 } from "node:path";
32238
32397
  var PROJECT_MARKERS = [
32239
32398
  ".olam/config.yaml",
32240
32399
  ".olam/config.yml",
@@ -32246,26 +32405,26 @@ function findProjectRoot2(startDir) {
32246
32405
  const root = resolve5("/");
32247
32406
  while (true) {
32248
32407
  for (const marker of PROJECT_MARKERS) {
32249
- if (existsSync17(join23(dir, marker))) return dir;
32408
+ if (existsSync18(join23(dir, marker))) return dir;
32250
32409
  }
32251
32410
  const pkg = join23(dir, "package.json");
32252
- if (existsSync17(pkg)) {
32411
+ if (existsSync18(pkg)) {
32253
32412
  try {
32254
- const json = JSON.parse(readFileSync14(pkg, "utf8"));
32413
+ const json = JSON.parse(readFileSync15(pkg, "utf8"));
32255
32414
  const isOlamWorkspace = typeof json.name === "string" && json.name.startsWith("@olam/");
32256
32415
  const hasOlamDep = json.dependencies && Object.keys(json.dependencies).some((k) => k.startsWith("@olam/")) || json.devDependencies && Object.keys(json.devDependencies).some((k) => k.startsWith("@olam/"));
32257
32416
  if (isOlamWorkspace || hasOlamDep) return dir;
32258
32417
  } catch {
32259
32418
  }
32260
32419
  }
32261
- const parent = dirname12(dir);
32420
+ const parent = dirname13(dir);
32262
32421
  if (parent === dir || parent === root) return null;
32263
32422
  dir = parent;
32264
32423
  }
32265
32424
  }
32266
- function parseEnvFile(path21) {
32425
+ function parseEnvFile(path22) {
32267
32426
  const out = {};
32268
- const raw = readFileSync14(path21, "utf8");
32427
+ const raw = readFileSync15(path22, "utf8");
32269
32428
  for (const line of raw.split(/\r?\n/)) {
32270
32429
  const trimmed = line.trim();
32271
32430
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -32289,7 +32448,7 @@ function loadProjectEnv(startDir = process.cwd()) {
32289
32448
  const merged = {};
32290
32449
  for (const name of [".env", ".env.local"]) {
32291
32450
  const p = join23(root, name);
32292
- if (existsSync17(p) && statSync6(p).isFile()) {
32451
+ if (existsSync18(p) && statSync6(p).isFile()) {
32293
32452
  Object.assign(merged, parseEnvFile(p));
32294
32453
  filesRead.push(p);
32295
32454
  }