@pleri/olam-cli 0.1.69 → 0.1.70

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.
package/dist/index.js CHANGED
@@ -15,6 +15,33 @@ var __export = (target, all) => {
15
15
  __defProp(target, name, { get: all[name], enumerable: true });
16
16
  };
17
17
 
18
+ // src/cli-version.ts
19
+ import * as fs from "node:fs";
20
+ import * as path from "node:path";
21
+ import { fileURLToPath } from "node:url";
22
+ function readCliVersion() {
23
+ try {
24
+ const here = path.dirname(fileURLToPath(import.meta.url));
25
+ for (const candidate of [
26
+ path.join(here, "package.json"),
27
+ path.join(here, "..", "package.json"),
28
+ path.join(here, "..", "..", "package.json")
29
+ ]) {
30
+ if (fs.existsSync(candidate)) {
31
+ const pkg = JSON.parse(fs.readFileSync(candidate, "utf-8"));
32
+ if (typeof pkg.version === "string" && pkg.version.length > 0) return pkg.version;
33
+ }
34
+ }
35
+ } catch {
36
+ }
37
+ return "0.0.0-unknown";
38
+ }
39
+ var init_cli_version = __esm({
40
+ "src/cli-version.ts"() {
41
+ "use strict";
42
+ }
43
+ });
44
+
18
45
  // src/output.ts
19
46
  import pc from "picocolors";
20
47
  function printError(message) {
@@ -4248,8 +4275,8 @@ var init_version2 = __esm({
4248
4275
  });
4249
4276
 
4250
4277
  // ../core/dist/world/repo-manifest.js
4251
- import { existsSync, lstatSync, readFileSync } from "node:fs";
4252
- import { join } from "node:path";
4278
+ import { existsSync as existsSync2, lstatSync, readFileSync as readFileSync2 } from "node:fs";
4279
+ import { join as join2 } from "node:path";
4253
4280
  import YAML from "yaml";
4254
4281
  function bootstrapStepCmd(entry) {
4255
4282
  return typeof entry === "string" ? entry : entry.cmd;
@@ -4296,14 +4323,14 @@ function unknownTopLevelKeys(parsed) {
4296
4323
  return Object.keys(parsed).filter((k) => !KNOWN_TOP_LEVEL_KEYS.has(k));
4297
4324
  }
4298
4325
  function loadRepoManifest(repoDir) {
4299
- const olamPath = join(repoDir, ".olam.yaml");
4300
- const adbPath = join(repoDir, ".adb.yaml");
4326
+ const olamPath = join2(repoDir, ".olam.yaml");
4327
+ const adbPath = join2(repoDir, ".adb.yaml");
4301
4328
  let manifestPath2;
4302
4329
  let source;
4303
- if (existsSync(olamPath)) {
4330
+ if (existsSync2(olamPath)) {
4304
4331
  manifestPath2 = olamPath;
4305
4332
  source = "olam";
4306
- } else if (existsSync(adbPath)) {
4333
+ } else if (existsSync2(adbPath)) {
4307
4334
  manifestPath2 = adbPath;
4308
4335
  source = "adb";
4309
4336
  } else {
@@ -4313,10 +4340,10 @@ function loadRepoManifest(repoDir) {
4313
4340
  if (stat.isSymbolicLink()) {
4314
4341
  throw new Error(`[manifest] ${manifestPath2}: symbolic links are not permitted`);
4315
4342
  }
4316
- const raw = readFileSync(manifestPath2, "utf-8");
4343
+ const raw = readFileSync2(manifestPath2, "utf-8");
4317
4344
  const parsed = YAML.parse(raw, { maxAliasCount: 100 });
4318
4345
  if (parsed === null || parsed === void 0) {
4319
- if (source === "olam" && existsSync(adbPath)) {
4346
+ if (source === "olam" && existsSync2(adbPath)) {
4320
4347
  console.warn(`[manifest] ${manifestPath2}: file is empty; .adb.yaml is NOT consulted (delete .olam.yaml to fall back)`);
4321
4348
  }
4322
4349
  return null;
@@ -4421,12 +4448,12 @@ var init_repo_manifest = __esm({
4421
4448
 
4422
4449
  // ../core/dist/util/path.js
4423
4450
  import * as os from "node:os";
4424
- import * as path from "node:path";
4451
+ import * as path2 from "node:path";
4425
4452
  function resolveTildePath(p) {
4426
4453
  if (p === "~")
4427
4454
  return os.homedir();
4428
4455
  if (p.startsWith("~/"))
4429
- return path.join(os.homedir(), p.slice(2));
4456
+ return path2.join(os.homedir(), p.slice(2));
4430
4457
  if (p.startsWith("~")) {
4431
4458
  throw new Error(`[path] POSIX "~user" syntax is not supported (got "${p}"). Use "~/..." for the operator's home or an absolute path.`);
4432
4459
  }
@@ -4441,15 +4468,15 @@ var init_path = __esm({
4441
4468
  });
4442
4469
 
4443
4470
  // ../core/dist/workspace/store.js
4444
- import * as fs from "node:fs";
4471
+ import * as fs2 from "node:fs";
4445
4472
  import * as os2 from "node:os";
4446
- import * as path2 from "node:path";
4473
+ import * as path3 from "node:path";
4447
4474
  import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
4448
4475
  function workspacesDir() {
4449
4476
  const override = process.env["OLAM_WORKSPACES_DIR"];
4450
4477
  if (override && override.length > 0)
4451
4478
  return override;
4452
- return path2.join(os2.homedir(), ".olam", "workspaces");
4479
+ return path3.join(os2.homedir(), ".olam", "workspaces");
4453
4480
  }
4454
4481
  function validateName(name) {
4455
4482
  if (!WORKSPACE_NAME_PATTERN.test(name)) {
@@ -4457,17 +4484,17 @@ function validateName(name) {
4457
4484
  }
4458
4485
  }
4459
4486
  function filePathFor(name) {
4460
- return path2.join(workspacesDir(), `${name}.yaml`);
4487
+ return path3.join(workspacesDir(), `${name}.yaml`);
4461
4488
  }
4462
4489
  function listWorkspaces() {
4463
4490
  const dir = workspacesDir();
4464
- if (!fs.existsSync(dir))
4491
+ if (!fs2.existsSync(dir))
4465
4492
  return [];
4466
- const entries = fs.readdirSync(dir).filter((f) => f.endsWith(".yaml"));
4493
+ const entries = fs2.readdirSync(dir).filter((f) => f.endsWith(".yaml"));
4467
4494
  const result = [];
4468
4495
  for (const entry of entries) {
4469
4496
  try {
4470
- const raw = fs.readFileSync(path2.join(dir, entry), "utf-8");
4497
+ const raw = fs2.readFileSync(path3.join(dir, entry), "utf-8");
4471
4498
  const parsed = parseYaml(raw);
4472
4499
  const ws = WorkspaceSchema.parse(parsed);
4473
4500
  result.push(ws);
@@ -4483,30 +4510,30 @@ function listWorkspaces() {
4483
4510
  function readWorkspace(name) {
4484
4511
  validateName(name);
4485
4512
  const file = filePathFor(name);
4486
- if (!fs.existsSync(file))
4513
+ if (!fs2.existsSync(file))
4487
4514
  return null;
4488
- const raw = fs.readFileSync(file, "utf-8");
4515
+ const raw = fs2.readFileSync(file, "utf-8");
4489
4516
  return WorkspaceSchema.parse(parseYaml(raw));
4490
4517
  }
4491
4518
  function writeWorkspace(ws, options = {}) {
4492
4519
  validateName(ws.name);
4493
4520
  const parsed = WorkspaceSchema.parse(ws);
4494
4521
  const dir = workspacesDir();
4495
- fs.mkdirSync(dir, { recursive: true });
4522
+ fs2.mkdirSync(dir, { recursive: true });
4496
4523
  const final = filePathFor(parsed.name);
4497
- if (fs.existsSync(final) && options.force !== true) {
4524
+ if (fs2.existsSync(final) && options.force !== true) {
4498
4525
  throw new WorkspaceExistsError(parsed.name);
4499
4526
  }
4500
4527
  const tmp = `${final}.tmp-${process.pid}`;
4501
- fs.writeFileSync(tmp, stringifyYaml(parsed), { mode: 420 });
4502
- fs.renameSync(tmp, final);
4528
+ fs2.writeFileSync(tmp, stringifyYaml(parsed), { mode: 420 });
4529
+ fs2.renameSync(tmp, final);
4503
4530
  }
4504
4531
  function removeWorkspace(name) {
4505
4532
  validateName(name);
4506
4533
  const file = filePathFor(name);
4507
- if (!fs.existsSync(file))
4534
+ if (!fs2.existsSync(file))
4508
4535
  return false;
4509
- fs.unlinkSync(file);
4536
+ fs2.unlinkSync(file);
4510
4537
  return true;
4511
4538
  }
4512
4539
  function workspaceToRepoConfigs(ws) {
@@ -4996,11 +5023,11 @@ var init_substitute = __esm({
4996
5023
  });
4997
5024
 
4998
5025
  // ../core/dist/config/dotenv.js
4999
- import * as fs2 from "node:fs";
5026
+ import * as fs3 from "node:fs";
5000
5027
  function loadDotEnv(envPath) {
5001
- if (!fs2.existsSync(envPath))
5028
+ if (!fs3.existsSync(envPath))
5002
5029
  return;
5003
- const content = fs2.readFileSync(envPath, "utf-8");
5030
+ const content = fs3.readFileSync(envPath, "utf-8");
5004
5031
  for (const line of content.split("\n")) {
5005
5032
  const trimmed = line.trim();
5006
5033
  if (!trimmed || trimmed.startsWith("#"))
@@ -5026,23 +5053,23 @@ var loader_exports = {};
5026
5053
  __export(loader_exports, {
5027
5054
  loadConfig: () => loadConfig
5028
5055
  });
5029
- import * as fs3 from "node:fs";
5030
- import * as path3 from "node:path";
5056
+ import * as fs4 from "node:fs";
5057
+ import * as path4 from "node:path";
5031
5058
  import { parse as parseYaml2 } from "yaml";
5032
5059
  function findConfigFile(startDir) {
5033
5060
  const searched = [];
5034
- let current = path3.resolve(startDir);
5061
+ let current = path4.resolve(startDir);
5035
5062
  while (true) {
5036
- const newLayout = path3.join(current, CONFIG_DIR_NAME, CONFIG_FILENAME);
5037
- const legacyLayout = path3.join(current, LEGACY_CONFIG_FILENAME);
5063
+ const newLayout = path4.join(current, CONFIG_DIR_NAME, CONFIG_FILENAME);
5064
+ const legacyLayout = path4.join(current, LEGACY_CONFIG_FILENAME);
5038
5065
  searched.push(newLayout, legacyLayout);
5039
- if (fs3.existsSync(newLayout)) {
5066
+ if (fs4.existsSync(newLayout)) {
5040
5067
  return { path: newLayout, isLegacy: false };
5041
5068
  }
5042
- if (fs3.existsSync(legacyLayout)) {
5069
+ if (fs4.existsSync(legacyLayout)) {
5043
5070
  return { path: legacyLayout, isLegacy: true };
5044
5071
  }
5045
- const parent = path3.dirname(current);
5072
+ const parent = path4.dirname(current);
5046
5073
  if (parent === current)
5047
5074
  break;
5048
5075
  current = parent;
@@ -5057,12 +5084,12 @@ function loadConfig(startDir) {
5057
5084
  Run /olam:init to migrate to .olam/config.yaml
5058
5085
  `);
5059
5086
  } else {
5060
- const envPath = path3.join(path3.dirname(found.path), ".env");
5087
+ const envPath = path4.join(path4.dirname(found.path), ".env");
5061
5088
  loadDotEnv(envPath);
5062
5089
  }
5063
5090
  let rawContent;
5064
5091
  try {
5065
- rawContent = fs3.readFileSync(found.path, "utf-8");
5092
+ rawContent = fs4.readFileSync(found.path, "utf-8");
5066
5093
  } catch (err) {
5067
5094
  throw new Error(`Failed to read ${found.path}: ${err instanceof Error ? err.message : String(err)}`);
5068
5095
  }
@@ -5104,27 +5131,27 @@ var init_loader = __esm({
5104
5131
 
5105
5132
  // ../core/dist/auth/secret.js
5106
5133
  import * as crypto from "node:crypto";
5107
- import * as fs7 from "node:fs";
5134
+ import * as fs8 from "node:fs";
5108
5135
  import * as os4 from "node:os";
5109
- import * as path7 from "node:path";
5136
+ import * as path8 from "node:path";
5110
5137
  function getSecretFilePath() {
5111
- return path7.join(os4.homedir(), ".olam", SECRET_FILENAME);
5138
+ return path8.join(os4.homedir(), ".olam", SECRET_FILENAME);
5112
5139
  }
5113
5140
  function getOrCreateSecret() {
5114
5141
  const fromEnv = process.env[SECRET_ENV_VAR];
5115
5142
  if (fromEnv && fromEnv.length > 0)
5116
5143
  return fromEnv;
5117
5144
  const file = getSecretFilePath();
5118
- if (fs7.existsSync(file)) {
5119
- const value = fs7.readFileSync(file, "utf-8").trim();
5145
+ if (fs8.existsSync(file)) {
5146
+ const value = fs8.readFileSync(file, "utf-8").trim();
5120
5147
  if (value.length > 0)
5121
5148
  return value;
5122
5149
  }
5123
5150
  const generated = crypto.randomBytes(SECRET_BYTES).toString("base64url");
5124
- fs7.mkdirSync(path7.dirname(file), { recursive: true });
5125
- fs7.writeFileSync(file, generated, { mode: 384 });
5151
+ fs8.mkdirSync(path8.dirname(file), { recursive: true });
5152
+ fs8.writeFileSync(file, generated, { mode: 384 });
5126
5153
  try {
5127
- fs7.chmodSync(file, 384);
5154
+ fs8.chmodSync(file, 384);
5128
5155
  } catch {
5129
5156
  }
5130
5157
  return generated;
@@ -5134,9 +5161,9 @@ function readSecretIfExists() {
5134
5161
  if (fromEnv && fromEnv.length > 0)
5135
5162
  return fromEnv;
5136
5163
  const file = getSecretFilePath();
5137
- if (!fs7.existsSync(file))
5164
+ if (!fs8.existsSync(file))
5138
5165
  return null;
5139
- const value = fs7.readFileSync(file, "utf-8").trim();
5166
+ const value = fs8.readFileSync(file, "utf-8").trim();
5140
5167
  return value.length > 0 ? value : null;
5141
5168
  }
5142
5169
  var SECRET_ENV_VAR, SECRET_FILENAME, SECRET_BYTES;
@@ -5312,13 +5339,13 @@ var init_client = __esm({
5312
5339
 
5313
5340
  // ../core/dist/auth/container.js
5314
5341
  import { execFileSync, spawnSync } from "node:child_process";
5315
- import { existsSync as existsSync8 } from "node:fs";
5316
- import * as path8 from "node:path";
5317
- import { fileURLToPath } from "node:url";
5342
+ import { existsSync as existsSync9 } from "node:fs";
5343
+ import * as path9 from "node:path";
5344
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
5318
5345
  function resolveAuthServicePath() {
5319
- const here = fileURLToPath(import.meta.url);
5320
- const pkgsDir = path8.resolve(path8.dirname(here), "..", "..", "..");
5321
- return path8.join(pkgsDir, "auth-service");
5346
+ const here = fileURLToPath2(import.meta.url);
5347
+ const pkgsDir = path9.resolve(path9.dirname(here), "..", "..", "..");
5348
+ return path9.join(pkgsDir, "auth-service");
5322
5349
  }
5323
5350
  function sleep2(ms) {
5324
5351
  return new Promise((resolve8) => setTimeout(resolve8, ms));
@@ -5394,7 +5421,7 @@ var init_container = __esm({
5394
5421
  */
5395
5422
  buildImage() {
5396
5423
  const dockerfileDir = resolveAuthServicePath();
5397
- if (!existsSync8(path8.join(dockerfileDir, "Dockerfile"))) {
5424
+ if (!existsSync9(path9.join(dockerfileDir, "Dockerfile"))) {
5398
5425
  throw new Error(`auth image '${this.imageTag}' is not present locally and no Dockerfile is available at ${dockerfileDir} to build from. Run \`olam bootstrap\` to pull the published image, or check out the olam source tree.`);
5399
5426
  }
5400
5427
  execFileSync("docker", ["build", "--tag", this.imageTag, dockerfileDir], { stdio: "inherit" });
@@ -5627,16 +5654,16 @@ var init_volume = __esm({
5627
5654
  });
5628
5655
 
5629
5656
  // ../adapters/dist/docker/container.js
5630
- import * as fs9 from "node:fs";
5657
+ import * as fs10 from "node:fs";
5631
5658
  import * as os6 from "node:os";
5632
- import * as path10 from "node:path";
5659
+ import * as path11 from "node:path";
5633
5660
  function readAuthSecret() {
5634
5661
  const fromEnv = process.env["OLAM_AUTH_SECRET"];
5635
5662
  if (fromEnv && fromEnv.length > 0)
5636
5663
  return fromEnv;
5637
- const file = path10.join(os6.homedir(), ".olam", "auth-secret");
5664
+ const file = path11.join(os6.homedir(), ".olam", "auth-secret");
5638
5665
  try {
5639
- return fs9.readFileSync(file, "utf-8").trim();
5666
+ return fs10.readFileSync(file, "utf-8").trim();
5640
5667
  } catch {
5641
5668
  return "";
5642
5669
  }
@@ -5645,9 +5672,9 @@ function readHostCpToken() {
5645
5672
  const fromEnv = process.env["OLAM_HOST_CP_TOKEN"];
5646
5673
  if (fromEnv && fromEnv.length > 0)
5647
5674
  return fromEnv;
5648
- const file = path10.join(os6.homedir(), ".olam", "host-cp.token");
5675
+ const file = path11.join(os6.homedir(), ".olam", "host-cp.token");
5649
5676
  try {
5650
- return fs9.readFileSync(file, "utf-8").trim();
5677
+ return fs10.readFileSync(file, "utf-8").trim();
5651
5678
  } catch {
5652
5679
  return "";
5653
5680
  }
@@ -5658,11 +5685,11 @@ function sanitizeContainerName(name) {
5658
5685
  function buildPackageManagerCacheBinds(homeDir) {
5659
5686
  const result = [];
5660
5687
  for (const entry of PACKAGE_MANAGER_CACHE_DIRS) {
5661
- const hostPath = path10.join(homeDir, entry.hostSubpath);
5688
+ const hostPath = path11.join(homeDir, entry.hostSubpath);
5662
5689
  try {
5663
- fs9.mkdirSync(hostPath, { recursive: true, mode: 448 });
5690
+ fs10.mkdirSync(hostPath, { recursive: true, mode: 448 });
5664
5691
  try {
5665
- fs9.chmodSync(hostPath, 448);
5692
+ fs10.chmodSync(hostPath, 448);
5666
5693
  } catch {
5667
5694
  }
5668
5695
  result.push(`${hostPath}:${entry.containerPath}:rw`);
@@ -5814,12 +5841,12 @@ var init_container2 = __esm({
5814
5841
  if (workspacePath) {
5815
5842
  binds.push(`${workspacePath}:/home/olam/workspace:rw`);
5816
5843
  }
5817
- const r2CredHostPath = path10.join(olamHomeDir, ".olam", "r2-credentials.json");
5818
- if (fs9.existsSync(r2CredHostPath)) {
5844
+ const r2CredHostPath = path11.join(olamHomeDir, ".olam", "r2-credentials.json");
5845
+ if (fs10.existsSync(r2CredHostPath)) {
5819
5846
  binds.push(`${r2CredHostPath}:/etc/olam/r2-credentials.json:ro`);
5820
5847
  }
5821
- const gcloudCredsDir = path10.join(olamHomeDir, ".config", "gcloud");
5822
- if (fs9.existsSync(gcloudCredsDir)) {
5848
+ const gcloudCredsDir = path11.join(olamHomeDir, ".config", "gcloud");
5849
+ if (fs10.existsSync(gcloudCredsDir)) {
5823
5850
  binds.push(`${gcloudCredsDir}:/home/olam/.config/gcloud:ro`);
5824
5851
  }
5825
5852
  const hostControlPlanePort = HOST_CONTROL_PLANE_BASE + (portOffset ?? 0);
@@ -6254,7 +6281,7 @@ var init_cleanup = __esm({
6254
6281
 
6255
6282
  // ../adapters/dist/ssh/connection.js
6256
6283
  import { Client as SSHClient } from "ssh2";
6257
- import { readFileSync as readFileSync9 } from "node:fs";
6284
+ import { readFileSync as readFileSync10 } from "node:fs";
6258
6285
  var SSHConnectionPool;
6259
6286
  var init_connection = __esm({
6260
6287
  "../adapters/dist/ssh/connection.js"() {
@@ -6349,7 +6376,7 @@ var init_connection = __esm({
6349
6376
  host: config.host,
6350
6377
  port: config.port ?? 22,
6351
6378
  username: config.user,
6352
- ...config.key ? { privateKey: readFileSync9(config.key) } : {},
6379
+ ...config.key ? { privateKey: readFileSync10(config.key) } : {},
6353
6380
  ...config.password ? { password: config.password } : {}
6354
6381
  });
6355
6382
  });
@@ -7058,8 +7085,8 @@ __export(registry_exports, {
7058
7085
  import { createRequire } from "node:module";
7059
7086
  import * as net from "node:net";
7060
7087
  import * as os7 from "node:os";
7061
- import * as path11 from "node:path";
7062
- import * as fs10 from "node:fs";
7088
+ import * as path12 from "node:path";
7089
+ import * as fs11 from "node:fs";
7063
7090
  function getDatabase() {
7064
7091
  if (_Database === null) {
7065
7092
  _Database = _require("better-sqlite3");
@@ -7165,9 +7192,9 @@ CREATE TABLE IF NOT EXISTS meta (
7165
7192
  WorldRegistry = class {
7166
7193
  db;
7167
7194
  constructor(dbPath) {
7168
- const resolvedPath = dbPath ?? path11.join(os7.homedir(), ".olam", "worlds.db");
7195
+ const resolvedPath = dbPath ?? path12.join(os7.homedir(), ".olam", "worlds.db");
7169
7196
  if (resolvedPath !== ":memory:") {
7170
- fs10.mkdirSync(path11.dirname(resolvedPath), { recursive: true });
7197
+ fs11.mkdirSync(path12.dirname(resolvedPath), { recursive: true });
7171
7198
  }
7172
7199
  const Database = getDatabase();
7173
7200
  this.db = new Database(resolvedPath);
@@ -7354,8 +7381,8 @@ var init_devbox_image = __esm({
7354
7381
 
7355
7382
  // ../core/dist/world/worktree.js
7356
7383
  import { execFileSync as execFileSync2 } from "node:child_process";
7357
- import * as fs11 from "node:fs";
7358
- import * as path12 from "node:path";
7384
+ import * as fs12 from "node:fs";
7385
+ import * as path13 from "node:path";
7359
7386
  function resolveGitDir(repo) {
7360
7387
  if (repo.path) {
7361
7388
  return repo.path;
@@ -7365,11 +7392,11 @@ function resolveGitDir(repo) {
7365
7392
  async function createWorktrees(repos, worldId, workspacePath, branch) {
7366
7393
  const created = [];
7367
7394
  for (const repo of repos) {
7368
- const worktreePath = path12.join(workspacePath, repo.name);
7395
+ const worktreePath = path13.join(workspacePath, repo.name);
7369
7396
  const gitDir = resolveGitDir(repo);
7370
7397
  const branchName = branch || `olam/${worldId}`;
7371
7398
  try {
7372
- fs11.mkdirSync(path12.dirname(worktreePath), { recursive: true });
7399
+ fs12.mkdirSync(path13.dirname(worktreePath), { recursive: true });
7373
7400
  execFileSync2("git", ["worktree", "add", worktreePath, "-b", branchName], {
7374
7401
  cwd: gitDir,
7375
7402
  stdio: "pipe"
@@ -7402,7 +7429,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
7402
7429
  }
7403
7430
  async function removeWorktrees(repos, workspacePath) {
7404
7431
  for (const repo of repos) {
7405
- const worktreePath = path12.join(workspacePath, repo.name);
7432
+ const worktreePath = path13.join(workspacePath, repo.name);
7406
7433
  let gitDir;
7407
7434
  try {
7408
7435
  gitDir = resolveGitDir(repo);
@@ -7571,85 +7598,85 @@ var init_hooks_config = __esm({
7571
7598
 
7572
7599
  // ../core/dist/world/env-setup.js
7573
7600
  import * as crypto2 from "node:crypto";
7574
- import * as fs12 from "node:fs";
7601
+ import * as fs13 from "node:fs";
7575
7602
  import * as os8 from "node:os";
7576
- import * as path13 from "node:path";
7603
+ import * as path14 from "node:path";
7577
7604
  import { globSync } from "node:fs";
7578
7605
  function copyClaudeConfig(workspacePath, homeDir, configCtx) {
7579
- const sourceClaudeDir = path13.join(homeDir ?? os8.homedir(), ".claude");
7580
- const destClaudeDir = path13.join(workspacePath, ".claude-host-config");
7606
+ const sourceClaudeDir = path14.join(homeDir ?? os8.homedir(), ".claude");
7607
+ const destClaudeDir = path14.join(workspacePath, ".claude-host-config");
7581
7608
  void configCtx;
7582
- if (!fs12.existsSync(sourceClaudeDir))
7609
+ if (!fs13.existsSync(sourceClaudeDir))
7583
7610
  return;
7584
- fs12.mkdirSync(destClaudeDir, { recursive: true });
7585
- const settingsPath = path13.join(sourceClaudeDir, "settings.json");
7611
+ fs13.mkdirSync(destClaudeDir, { recursive: true });
7612
+ const settingsPath = path14.join(sourceClaudeDir, "settings.json");
7586
7613
  let settings = {};
7587
- if (fs12.existsSync(settingsPath)) {
7614
+ if (fs13.existsSync(settingsPath)) {
7588
7615
  try {
7589
- settings = JSON.parse(fs12.readFileSync(settingsPath, "utf-8"));
7616
+ settings = JSON.parse(fs13.readFileSync(settingsPath, "utf-8"));
7590
7617
  delete settings["hooks"];
7591
7618
  } catch {
7592
7619
  }
7593
7620
  }
7594
7621
  const hooksConfig = generateHooksConfig(DEFAULT_HOOK_SERVER_URL);
7595
7622
  settings["hooks"] = hooksConfig["hooks"];
7596
- fs12.writeFileSync(path13.join(destClaudeDir, "settings.json"), JSON.stringify(settings, null, 2));
7597
- const claudeMdPath = path13.join(sourceClaudeDir, "CLAUDE.md");
7598
- if (fs12.existsSync(claudeMdPath)) {
7599
- fs12.copyFileSync(claudeMdPath, path13.join(destClaudeDir, "CLAUDE.md"));
7623
+ fs13.writeFileSync(path14.join(destClaudeDir, "settings.json"), JSON.stringify(settings, null, 2));
7624
+ const claudeMdPath = path14.join(sourceClaudeDir, "CLAUDE.md");
7625
+ if (fs13.existsSync(claudeMdPath)) {
7626
+ fs13.copyFileSync(claudeMdPath, path14.join(destClaudeDir, "CLAUDE.md"));
7600
7627
  }
7601
- const rulesDir = path13.join(sourceClaudeDir, "rules");
7602
- if (fs12.existsSync(rulesDir)) {
7603
- copyDirRecursive(rulesDir, path13.join(destClaudeDir, "rules"));
7628
+ const rulesDir = path14.join(sourceClaudeDir, "rules");
7629
+ if (fs13.existsSync(rulesDir)) {
7630
+ copyDirRecursive(rulesDir, path14.join(destClaudeDir, "rules"));
7604
7631
  }
7605
- const agentsDir = path13.join(sourceClaudeDir, "agents");
7606
- if (fs12.existsSync(agentsDir)) {
7607
- copyDirRecursive(agentsDir, path13.join(destClaudeDir, "agents"));
7632
+ const agentsDir = path14.join(sourceClaudeDir, "agents");
7633
+ if (fs13.existsSync(agentsDir)) {
7634
+ copyDirRecursive(agentsDir, path14.join(destClaudeDir, "agents"));
7608
7635
  }
7609
- const pluginsDir = path13.join(sourceClaudeDir, "plugins");
7610
- if (fs12.existsSync(pluginsDir)) {
7611
- copyDirRecursive(pluginsDir, path13.join(destClaudeDir, "plugins"), 0, SKIP_FILES);
7636
+ const pluginsDir = path14.join(sourceClaudeDir, "plugins");
7637
+ if (fs13.existsSync(pluginsDir)) {
7638
+ copyDirRecursive(pluginsDir, path14.join(destClaudeDir, "plugins"), 0, SKIP_FILES);
7612
7639
  }
7613
- const skillsDir = path13.join(sourceClaudeDir, "skills");
7614
- if (fs12.existsSync(skillsDir)) {
7615
- copyDirRecursive(skillsDir, path13.join(destClaudeDir, "skills"));
7640
+ const skillsDir = path14.join(sourceClaudeDir, "skills");
7641
+ if (fs13.existsSync(skillsDir)) {
7642
+ copyDirRecursive(skillsDir, path14.join(destClaudeDir, "skills"));
7616
7643
  }
7617
- const scriptsDir = path13.join(sourceClaudeDir, "scripts");
7618
- if (fs12.existsSync(scriptsDir)) {
7619
- copyDirRecursive(scriptsDir, path13.join(destClaudeDir, "scripts"));
7644
+ const scriptsDir = path14.join(sourceClaudeDir, "scripts");
7645
+ if (fs13.existsSync(scriptsDir)) {
7646
+ copyDirRecursive(scriptsDir, path14.join(destClaudeDir, "scripts"));
7620
7647
  }
7621
7648
  applyProjectClaudeOverlay(workspacePath, destClaudeDir);
7622
7649
  writeStrippedMcpServersSnapshot(homeDir ?? os8.homedir(), workspacePath, destClaudeDir);
7623
7650
  }
7624
7651
  function applyProjectClaudeOverlay(workspacePath, destClaudeDir) {
7625
- const projectClaudeDir = path13.join(workspacePath, ".claude");
7626
- if (!fs12.existsSync(projectClaudeDir))
7652
+ const projectClaudeDir = path14.join(workspacePath, ".claude");
7653
+ if (!fs13.existsSync(projectClaudeDir))
7627
7654
  return;
7628
- const projectSettingsPath = path13.join(projectClaudeDir, "settings.json");
7629
- const destSettingsPath = path13.join(destClaudeDir, "settings.json");
7630
- if (fs12.existsSync(projectSettingsPath)) {
7655
+ const projectSettingsPath = path14.join(projectClaudeDir, "settings.json");
7656
+ const destSettingsPath = path14.join(destClaudeDir, "settings.json");
7657
+ if (fs13.existsSync(projectSettingsPath)) {
7631
7658
  try {
7632
- const projectSettings = JSON.parse(fs12.readFileSync(projectSettingsPath, "utf-8"));
7659
+ const projectSettings = JSON.parse(fs13.readFileSync(projectSettingsPath, "utf-8"));
7633
7660
  delete projectSettings["hooks"];
7634
- const existing = fs12.existsSync(destSettingsPath) ? JSON.parse(fs12.readFileSync(destSettingsPath, "utf-8")) : {};
7661
+ const existing = fs13.existsSync(destSettingsPath) ? JSON.parse(fs13.readFileSync(destSettingsPath, "utf-8")) : {};
7635
7662
  const merged = { ...existing, ...projectSettings, hooks: existing["hooks"] };
7636
- fs12.writeFileSync(destSettingsPath, JSON.stringify(merged, null, 2));
7663
+ fs13.writeFileSync(destSettingsPath, JSON.stringify(merged, null, 2));
7637
7664
  } catch {
7638
7665
  }
7639
7666
  }
7640
- const projectClaudeMd = path13.join(projectClaudeDir, "CLAUDE.md");
7641
- if (fs12.existsSync(projectClaudeMd)) {
7642
- fs12.copyFileSync(projectClaudeMd, path13.join(destClaudeDir, "CLAUDE.md"));
7667
+ const projectClaudeMd = path14.join(projectClaudeDir, "CLAUDE.md");
7668
+ if (fs13.existsSync(projectClaudeMd)) {
7669
+ fs13.copyFileSync(projectClaudeMd, path14.join(destClaudeDir, "CLAUDE.md"));
7643
7670
  }
7644
- const projectAgentsMd = path13.join(projectClaudeDir, "AGENTS.md");
7645
- if (fs12.existsSync(projectAgentsMd)) {
7646
- fs12.copyFileSync(projectAgentsMd, path13.join(destClaudeDir, "AGENTS.md"));
7671
+ const projectAgentsMd = path14.join(projectClaudeDir, "AGENTS.md");
7672
+ if (fs13.existsSync(projectAgentsMd)) {
7673
+ fs13.copyFileSync(projectAgentsMd, path14.join(destClaudeDir, "AGENTS.md"));
7647
7674
  }
7648
7675
  for (const subdir of ["rules", "agents", "plugins", "skills", "scripts"]) {
7649
- const projectSubdir = path13.join(projectClaudeDir, subdir);
7650
- if (fs12.existsSync(projectSubdir)) {
7676
+ const projectSubdir = path14.join(projectClaudeDir, subdir);
7677
+ if (fs13.existsSync(projectSubdir)) {
7651
7678
  const skip = subdir === "plugins" ? SKIP_FILES : /* @__PURE__ */ new Set();
7652
- copyDirRecursive(projectSubdir, path13.join(destClaudeDir, subdir), 0, skip);
7679
+ copyDirRecursive(projectSubdir, path14.join(destClaudeDir, subdir), 0, skip);
7653
7680
  }
7654
7681
  }
7655
7682
  }
@@ -7679,8 +7706,8 @@ function stripMcpServers(mcpServers) {
7679
7706
  return out;
7680
7707
  }
7681
7708
  function writeStrippedMcpServersSnapshot(homeDir, workspacePath, destClaudeDir) {
7682
- const hostMcpServers = readMcpServersFromFile(path13.join(homeDir, ".claude.json"));
7683
- const projectMcpServers = readMcpServersFromFile(path13.join(workspacePath, ".mcp.json"));
7709
+ const hostMcpServers = readMcpServersFromFile(path14.join(homeDir, ".claude.json"));
7710
+ const projectMcpServers = readMcpServersFromFile(path14.join(workspacePath, ".mcp.json"));
7684
7711
  if (Object.keys(hostMcpServers).length === 0 && Object.keys(projectMcpServers).length === 0) {
7685
7712
  return;
7686
7713
  }
@@ -7689,11 +7716,11 @@ function writeStrippedMcpServersSnapshot(homeDir, workspacePath, destClaudeDir)
7689
7716
  ...stripMcpServers(projectMcpServers)
7690
7717
  };
7691
7718
  const output = { mcpServers: stripped };
7692
- fs12.writeFileSync(path13.join(destClaudeDir, ".claude.json"), JSON.stringify(output, null, 2), { mode: 384 });
7719
+ fs13.writeFileSync(path14.join(destClaudeDir, ".claude.json"), JSON.stringify(output, null, 2), { mode: 384 });
7693
7720
  }
7694
7721
  function writeWorldEntitlementsJson(workspacePath, configCtx) {
7695
- const olamDir = path13.join(workspacePath, ".olam");
7696
- fs12.mkdirSync(olamDir, { recursive: true });
7722
+ const olamDir = path14.join(workspacePath, ".olam");
7723
+ fs13.mkdirSync(olamDir, { recursive: true });
7697
7724
  const resolvedRepos = configCtx.repos.map((repo) => {
7698
7725
  const repoEntitlement = repo;
7699
7726
  return {
@@ -7707,14 +7734,14 @@ function writeWorldEntitlementsJson(workspacePath, configCtx) {
7707
7734
  worlds_default: configCtx.worlds_default,
7708
7735
  repos: resolvedRepos
7709
7736
  };
7710
- const filePath = path13.join(olamDir, "world-entitlements.json");
7711
- fs12.writeFileSync(filePath, JSON.stringify(resolved, null, 2), { mode: 420 });
7737
+ const filePath = path14.join(olamDir, "world-entitlements.json");
7738
+ fs13.writeFileSync(filePath, JSON.stringify(resolved, null, 2), { mode: 420 });
7712
7739
  }
7713
7740
  function readMcpServersFromFile(filePath) {
7714
- if (!fs12.existsSync(filePath))
7741
+ if (!fs13.existsSync(filePath))
7715
7742
  return {};
7716
7743
  try {
7717
- const raw = fs12.readFileSync(filePath, "utf-8");
7744
+ const raw = fs13.readFileSync(filePath, "utf-8");
7718
7745
  if (!raw.trim())
7719
7746
  return {};
7720
7747
  const parsed = JSON.parse(raw);
@@ -7729,8 +7756,8 @@ function readMcpServersFromFile(filePath) {
7729
7756
  function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new Set()) {
7730
7757
  if (depth > 10)
7731
7758
  return;
7732
- fs12.mkdirSync(dest, { recursive: true });
7733
- for (const entry of fs12.readdirSync(src, { withFileTypes: true })) {
7759
+ fs13.mkdirSync(dest, { recursive: true });
7760
+ for (const entry of fs13.readdirSync(src, { withFileTypes: true })) {
7734
7761
  const { name } = entry;
7735
7762
  if (skipFiles.has(name))
7736
7763
  continue;
@@ -7740,12 +7767,12 @@ function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new
7740
7767
  continue;
7741
7768
  if (entry.isDirectory() && SKIP_DIRS_ANYWHERE.has(name))
7742
7769
  continue;
7743
- const srcPath = path13.join(src, name);
7744
- const destPath = path13.join(dest, name);
7770
+ const srcPath = path14.join(src, name);
7771
+ const destPath = path14.join(dest, name);
7745
7772
  if (entry.isSymbolicLink()) {
7746
7773
  let stat;
7747
7774
  try {
7748
- stat = fs12.statSync(srcPath);
7775
+ stat = fs13.statSync(srcPath);
7749
7776
  } catch {
7750
7777
  continue;
7751
7778
  }
@@ -7754,12 +7781,12 @@ function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new
7754
7781
  continue;
7755
7782
  copyDirRecursive(srcPath, destPath, depth + 1, skipFiles);
7756
7783
  } else if (stat.isFile()) {
7757
- fs12.copyFileSync(srcPath, destPath);
7784
+ fs13.copyFileSync(srcPath, destPath);
7758
7785
  }
7759
7786
  } else if (entry.isDirectory()) {
7760
7787
  copyDirRecursive(srcPath, destPath, depth + 1, skipFiles);
7761
7788
  } else {
7762
- fs12.copyFileSync(srcPath, destPath);
7789
+ fs13.copyFileSync(srcPath, destPath);
7763
7790
  }
7764
7791
  }
7765
7792
  }
@@ -7897,9 +7924,9 @@ function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, conf
7897
7924
  }
7898
7925
  }
7899
7926
  for (const repo of repos) {
7900
- const worktreePath = path13.join(workspacePath, repo.name);
7927
+ const worktreePath = path14.join(workspacePath, repo.name);
7901
7928
  const sourcePath = repo.path;
7902
- if (!sourcePath || !fs12.existsSync(worktreePath))
7929
+ if (!sourcePath || !fs13.existsSync(worktreePath))
7903
7930
  continue;
7904
7931
  const envSetup = repo.env_setup;
7905
7932
  if (!envSetup)
@@ -7918,23 +7945,23 @@ function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, conf
7918
7945
  }
7919
7946
  }
7920
7947
  function copyMatchingFiles(sourcePath, destPath, pattern) {
7921
- const fullPattern = path13.join(sourcePath, pattern);
7948
+ const fullPattern = path14.join(sourcePath, pattern);
7922
7949
  if (!pattern.includes("*")) {
7923
- const sourceFile = path13.join(sourcePath, pattern);
7924
- const destFile = path13.join(destPath, pattern);
7925
- if (fs12.existsSync(sourceFile)) {
7926
- fs12.mkdirSync(path13.dirname(destFile), { recursive: true });
7927
- fs12.copyFileSync(sourceFile, destFile);
7950
+ const sourceFile = path14.join(sourcePath, pattern);
7951
+ const destFile = path14.join(destPath, pattern);
7952
+ if (fs13.existsSync(sourceFile)) {
7953
+ fs13.mkdirSync(path14.dirname(destFile), { recursive: true });
7954
+ fs13.copyFileSync(sourceFile, destFile);
7928
7955
  }
7929
7956
  return;
7930
7957
  }
7931
7958
  try {
7932
7959
  const matches2 = globSync(fullPattern);
7933
7960
  for (const match2 of matches2) {
7934
- const relative2 = path13.relative(sourcePath, match2);
7935
- const dest = path13.join(destPath, relative2);
7936
- fs12.mkdirSync(path13.dirname(dest), { recursive: true });
7937
- fs12.copyFileSync(match2, dest);
7961
+ const relative2 = path14.relative(sourcePath, match2);
7962
+ const dest = path14.join(destPath, relative2);
7963
+ fs13.mkdirSync(path14.dirname(dest), { recursive: true });
7964
+ fs13.copyFileSync(match2, dest);
7938
7965
  }
7939
7966
  } catch {
7940
7967
  }
@@ -7942,14 +7969,14 @@ function copyMatchingFiles(sourcePath, destPath, pattern) {
7942
7969
  function generateEnvFromExample(repoPath, overrides) {
7943
7970
  const exampleFiles = [".env.example", ".env.sample", ".env.local.example"];
7944
7971
  for (const exampleName of exampleFiles) {
7945
- const examplePath = path13.join(repoPath, exampleName);
7946
- if (!fs12.existsSync(examplePath))
7972
+ const examplePath = path14.join(repoPath, exampleName);
7973
+ if (!fs13.existsSync(examplePath))
7947
7974
  continue;
7948
7975
  const targetName = exampleName.replace(".example", "").replace(".sample", "");
7949
- const targetPath = path13.join(repoPath, targetName);
7950
- if (fs12.existsSync(targetPath))
7976
+ const targetPath = path14.join(repoPath, targetName);
7977
+ if (fs13.existsSync(targetPath))
7951
7978
  continue;
7952
- const template = fs12.readFileSync(examplePath, "utf-8");
7979
+ const template = fs13.readFileSync(examplePath, "utf-8");
7953
7980
  const generated = template.split("\n").map((line) => {
7954
7981
  const match2 = /^([A-Z_][A-Z0-9_]*)=(.*)$/.exec(line);
7955
7982
  if (match2) {
@@ -7960,13 +7987,13 @@ function generateEnvFromExample(repoPath, overrides) {
7960
7987
  }
7961
7988
  return line;
7962
7989
  }).join("\n");
7963
- fs12.writeFileSync(targetPath, generated);
7990
+ fs13.writeFileSync(targetPath, generated);
7964
7991
  }
7965
7992
  }
7966
7993
  function applyEnvOverrides(repoPath, overrides) {
7967
- const envPath = path13.join(repoPath, ".env");
7968
- if (fs12.existsSync(envPath)) {
7969
- const existing = fs12.readFileSync(envPath, "utf-8");
7994
+ const envPath = path14.join(repoPath, ".env");
7995
+ if (fs13.existsSync(envPath)) {
7996
+ const existing = fs13.readFileSync(envPath, "utf-8");
7970
7997
  const existingKeys = new Set(existing.split("\n").map((l) => l.split("=")[0]?.trim()).filter(Boolean));
7971
7998
  const additions = [];
7972
7999
  for (const [key, value] of Object.entries(overrides)) {
@@ -7975,7 +8002,7 @@ function applyEnvOverrides(repoPath, overrides) {
7975
8002
  }
7976
8003
  }
7977
8004
  if (additions.length > 0) {
7978
- fs12.appendFileSync(envPath, "\n# Olam injected\n" + additions.join("\n") + "\n");
8005
+ fs13.appendFileSync(envPath, "\n# Olam injected\n" + additions.join("\n") + "\n");
7979
8006
  }
7980
8007
  }
7981
8008
  }
@@ -8053,9 +8080,9 @@ var init_env_setup = __esm({
8053
8080
 
8054
8081
  // ../core/dist/world/baseline-diff.js
8055
8082
  import { execFileSync as execFileSync3 } from "node:child_process";
8056
- import * as fs13 from "node:fs";
8083
+ import * as fs14 from "node:fs";
8057
8084
  import * as os9 from "node:os";
8058
- import * as path14 from "node:path";
8085
+ import * as path15 from "node:path";
8059
8086
  function expandHome(p, homedir24) {
8060
8087
  return p.replace(/^~(?=$|\/|\\)/, homedir24());
8061
8088
  }
@@ -8081,9 +8108,9 @@ ${stderr}`;
8081
8108
  function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
8082
8109
  const exec = deps.exec ?? ((cmd, args, opts) => execFileSync3(cmd, args, opts));
8083
8110
  const homedir24 = deps.homedir ?? (() => os9.homedir());
8084
- const baselineDir = path14.join(workspacePath, ".olam", "baseline");
8111
+ const baselineDir = path15.join(workspacePath, ".olam", "baseline");
8085
8112
  try {
8086
- fs13.mkdirSync(baselineDir, { recursive: true });
8113
+ fs14.mkdirSync(baselineDir, { recursive: true });
8087
8114
  } catch (err) {
8088
8115
  const msg = err instanceof Error ? err.message : String(err);
8089
8116
  console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
@@ -8095,9 +8122,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
8095
8122
  if (!repo.path)
8096
8123
  continue;
8097
8124
  const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
8098
- const outPath = path14.join(baselineDir, filename);
8125
+ const outPath = path15.join(baselineDir, filename);
8099
8126
  const repoPath = expandHome(repo.path, homedir24);
8100
- if (!fs13.existsSync(repoPath)) {
8127
+ if (!fs14.existsSync(repoPath)) {
8101
8128
  writeBaselineFile(outPath, `# repo: ${repo.name}
8102
8129
  # (skipped: path ${repoPath} does not exist)
8103
8130
  `);
@@ -8164,7 +8191,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
8164
8191
  }
8165
8192
  function writeBaselineFile(outPath, content) {
8166
8193
  try {
8167
- fs13.writeFileSync(outPath, content);
8194
+ fs14.writeFileSync(outPath, content);
8168
8195
  } catch (err) {
8169
8196
  const msg = err instanceof Error ? err.message : String(err);
8170
8197
  console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
@@ -8172,8 +8199,8 @@ function writeBaselineFile(outPath, content) {
8172
8199
  }
8173
8200
  function stripWorktreeEdits(repos, workspacePath) {
8174
8201
  for (const repo of repos) {
8175
- const worktreePath = path14.join(workspacePath, repo.name);
8176
- if (!fs13.existsSync(worktreePath))
8202
+ const worktreePath = path15.join(workspacePath, repo.name);
8203
+ if (!fs14.existsSync(worktreePath))
8177
8204
  continue;
8178
8205
  try {
8179
8206
  execFileSync3("git", ["checkout", "--", "."], {
@@ -8210,12 +8237,12 @@ var init_baseline_diff = __esm({
8210
8237
  });
8211
8238
 
8212
8239
  // ../core/dist/world/context-injection.js
8213
- import * as fs14 from "node:fs";
8214
- import * as path15 from "node:path";
8240
+ import * as fs15 from "node:fs";
8241
+ import * as path16 from "node:path";
8215
8242
  function injectWorldContext(opts) {
8216
8243
  const { world, task, linearTicketId, claudeMdExtra, taskContext, services, pleriPlaneUrl } = opts;
8217
- const claudeDir = path15.join(world.workspacePath, ".claude");
8218
- fs14.mkdirSync(claudeDir, { recursive: true });
8244
+ const claudeDir = path16.join(world.workspacePath, ".claude");
8245
+ fs15.mkdirSync(claudeDir, { recursive: true });
8219
8246
  const sections = [];
8220
8247
  sections.push(`# Olam World: ${world.name}`);
8221
8248
  sections.push("");
@@ -8376,7 +8403,7 @@ function injectWorldContext(opts) {
8376
8403
  sections.push("");
8377
8404
  }
8378
8405
  const content = sections.join("\n");
8379
- fs14.writeFileSync(path15.join(claudeDir, "CLAUDE.md"), content);
8406
+ fs15.writeFileSync(path16.join(claudeDir, "CLAUDE.md"), content);
8380
8407
  }
8381
8408
  function formatTaskSource(ctx) {
8382
8409
  if (ctx.source === "linear" && ctx.ticketId) {
@@ -8390,9 +8417,9 @@ function formatTaskSource(ctx) {
8390
8417
  function hasPlanFile(world) {
8391
8418
  if (world.repos.length === 0)
8392
8419
  return false;
8393
- const plansDir = path15.join(world.workspacePath, world.repos[0], "docs", "plans");
8420
+ const plansDir = path16.join(world.workspacePath, world.repos[0], "docs", "plans");
8394
8421
  try {
8395
- return fs14.existsSync(plansDir) && fs14.readdirSync(plansDir).length > 0;
8422
+ return fs15.existsSync(plansDir) && fs15.readdirSync(plansDir).length > 0;
8396
8423
  } catch {
8397
8424
  return false;
8398
8425
  }
@@ -9096,14 +9123,14 @@ var init_secrets_fetcher = __esm({
9096
9123
  });
9097
9124
 
9098
9125
  // ../core/dist/world/olam-yaml.js
9099
- import * as path16 from "node:path";
9126
+ import * as path17 from "node:path";
9100
9127
  import YAML2 from "yaml";
9101
9128
  function enrichReposWithManifests(repos, workspacePath) {
9102
9129
  return repos.map((repo) => {
9103
9130
  if (repo.manifest !== void 0 && repo.manifest !== null) {
9104
9131
  return repo;
9105
9132
  }
9106
- const repoDir = path16.join(workspacePath, repo.name);
9133
+ const repoDir = path17.join(workspacePath, repo.name);
9107
9134
  let manifest = null;
9108
9135
  try {
9109
9136
  manifest = loadRepoManifest(repoDir);
@@ -9124,8 +9151,8 @@ var init_olam_yaml = __esm({
9124
9151
  });
9125
9152
 
9126
9153
  // ../core/dist/policies/loader.js
9127
- import * as fs15 from "node:fs";
9128
- import * as path17 from "node:path";
9154
+ import * as fs16 from "node:fs";
9155
+ import * as path18 from "node:path";
9129
9156
  import { parse as parseYaml3 } from "yaml";
9130
9157
  function parseFrontmatter(content) {
9131
9158
  const match2 = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
@@ -9145,20 +9172,20 @@ function toStringArray(v) {
9145
9172
  return v.filter((x) => typeof x === "string");
9146
9173
  }
9147
9174
  function loadPolicies(workspaceRoot) {
9148
- const policiesDir = path17.join(workspaceRoot, ".olam", "policies");
9149
- if (!fs15.existsSync(policiesDir))
9175
+ const policiesDir = path18.join(workspaceRoot, ".olam", "policies");
9176
+ if (!fs16.existsSync(policiesDir))
9150
9177
  return [];
9151
9178
  let files;
9152
9179
  try {
9153
- files = fs15.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
9180
+ files = fs16.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
9154
9181
  } catch {
9155
9182
  return [];
9156
9183
  }
9157
9184
  const policies = [];
9158
9185
  for (const file of files) {
9159
- const filePath = path17.join(policiesDir, file);
9186
+ const filePath = path18.join(policiesDir, file);
9160
9187
  try {
9161
- const content = fs15.readFileSync(filePath, "utf8");
9188
+ const content = fs16.readFileSync(filePath, "utf8");
9162
9189
  const parsed = parseFrontmatter(content);
9163
9190
  if (!parsed) {
9164
9191
  console.warn(`[policies] skipping ${file}: no valid frontmatter block`);
@@ -9332,9 +9359,9 @@ __export(manager_exports, {
9332
9359
  });
9333
9360
  import * as crypto4 from "node:crypto";
9334
9361
  import { execSync as execSync4 } from "node:child_process";
9335
- import * as fs16 from "node:fs";
9362
+ import * as fs17 from "node:fs";
9336
9363
  import * as os10 from "node:os";
9337
- import * as path18 from "node:path";
9364
+ import * as path19 from "node:path";
9338
9365
  import YAML3 from "yaml";
9339
9366
  function getTokenScopes(ghToken, _exec = execSync4) {
9340
9367
  try {
@@ -9749,7 +9776,7 @@ var init_manager = __esm({
9749
9776
  }
9750
9777
  }
9751
9778
  const worldId = generateWorldId();
9752
- const workspacePath = path18.join(os10.homedir(), ".olam", "worlds", worldId);
9779
+ const workspacePath = path19.join(os10.homedir(), ".olam", "worlds", worldId);
9753
9780
  const portOffset = this.registry.getNextPortOffset();
9754
9781
  const branch = opts.branchName ?? `olam/${worldId}`;
9755
9782
  const repos = this.resolveReposWithWorkspace(opts);
@@ -9806,37 +9833,37 @@ var init_manager = __esm({
9806
9833
  if (!repo.path)
9807
9834
  continue;
9808
9835
  const sourceRoot = repo.path.replace(/^~/, os10.homedir());
9809
- const worktreeRoot = path18.join(workspacePath, repo.name);
9810
- if (!fs16.existsSync(sourceRoot) || !fs16.existsSync(worktreeRoot))
9836
+ const worktreeRoot = path19.join(workspacePath, repo.name);
9837
+ if (!fs17.existsSync(sourceRoot) || !fs17.existsSync(worktreeRoot))
9811
9838
  continue;
9812
9839
  let copied = 0;
9813
9840
  for (const pattern of RUNTIME_FILE_PATTERNS) {
9814
9841
  const matches2 = [];
9815
9842
  if (pattern.includes("*")) {
9816
- const [dir, glob] = [path18.dirname(pattern), path18.basename(pattern)];
9817
- const sourceDir = path18.join(sourceRoot, dir);
9818
- if (fs16.existsSync(sourceDir)) {
9843
+ const [dir, glob] = [path19.dirname(pattern), path19.basename(pattern)];
9844
+ const sourceDir = path19.join(sourceRoot, dir);
9845
+ if (fs17.existsSync(sourceDir)) {
9819
9846
  const ext2 = glob.replace(/^\*+/, "");
9820
9847
  try {
9821
- for (const entry of fs16.readdirSync(sourceDir)) {
9848
+ for (const entry of fs17.readdirSync(sourceDir)) {
9822
9849
  if (ext2 === "" || entry.endsWith(ext2))
9823
- matches2.push(path18.join(dir, entry));
9850
+ matches2.push(path19.join(dir, entry));
9824
9851
  }
9825
9852
  } catch {
9826
9853
  }
9827
9854
  }
9828
- } else if (fs16.existsSync(path18.join(sourceRoot, pattern))) {
9855
+ } else if (fs17.existsSync(path19.join(sourceRoot, pattern))) {
9829
9856
  matches2.push(pattern);
9830
9857
  }
9831
9858
  for (const rel of matches2) {
9832
- const src = path18.join(sourceRoot, rel);
9833
- const dst = path18.join(worktreeRoot, rel);
9859
+ const src = path19.join(sourceRoot, rel);
9860
+ const dst = path19.join(worktreeRoot, rel);
9834
9861
  try {
9835
- const st = fs16.statSync(src);
9862
+ const st = fs17.statSync(src);
9836
9863
  if (!st.isFile())
9837
9864
  continue;
9838
- fs16.mkdirSync(path18.dirname(dst), { recursive: true });
9839
- fs16.copyFileSync(src, dst);
9865
+ fs17.mkdirSync(path19.dirname(dst), { recursive: true });
9866
+ fs17.copyFileSync(src, dst);
9840
9867
  copied++;
9841
9868
  } catch {
9842
9869
  }
@@ -9936,7 +9963,7 @@ var init_manager = __esm({
9936
9963
  try {
9937
9964
  const hostExec = makeHostExecFn();
9938
9965
  for (const repo of repos) {
9939
- const repoDir = path18.join(workspacePath, repo.name);
9966
+ const repoDir = path19.join(workspacePath, repo.name);
9940
9967
  if (repo.stack && Object.keys(repo.stack).length > 0) {
9941
9968
  preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
9942
9969
  } else {
@@ -9993,10 +10020,10 @@ var init_manager = __esm({
9993
10020
  const worldEnv = {};
9994
10021
  if (opts.task)
9995
10022
  worldEnv.OLAM_TASK = opts.task;
9996
- const r2CredsPath = path18.join(os10.homedir(), ".olam", "r2-credentials.json");
9997
- if (fs16.existsSync(r2CredsPath)) {
10023
+ const r2CredsPath = path19.join(os10.homedir(), ".olam", "r2-credentials.json");
10024
+ if (fs17.existsSync(r2CredsPath)) {
9998
10025
  try {
9999
- const r2Raw = fs16.readFileSync(r2CredsPath, "utf-8").trim();
10026
+ const r2Raw = fs17.readFileSync(r2CredsPath, "utf-8").trim();
10000
10027
  if (r2Raw.length > 0) {
10001
10028
  const r2 = JSON.parse(r2Raw);
10002
10029
  if (typeof r2.account_id === "string")
@@ -10013,10 +10040,10 @@ var init_manager = __esm({
10013
10040
  } catch {
10014
10041
  }
10015
10042
  }
10016
- const keysYamlPath = path18.join(os10.homedir(), ".olam", "keys.yaml");
10017
- if (fs16.existsSync(keysYamlPath)) {
10043
+ const keysYamlPath = path19.join(os10.homedir(), ".olam", "keys.yaml");
10044
+ if (fs17.existsSync(keysYamlPath)) {
10018
10045
  try {
10019
- const keysRaw = fs16.readFileSync(keysYamlPath, "utf-8").trim();
10046
+ const keysRaw = fs17.readFileSync(keysYamlPath, "utf-8").trim();
10020
10047
  if (keysRaw.length > 0) {
10021
10048
  const parsed = YAML3.parse(keysRaw);
10022
10049
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
@@ -10063,10 +10090,10 @@ var init_manager = __esm({
10063
10090
  worldEnv[k] = v;
10064
10091
  }
10065
10092
  for (const { repoName, relativePath, content } of fileWrites) {
10066
- const absPath = path18.join(workspacePath, repoName, relativePath);
10093
+ const absPath = path19.join(workspacePath, repoName, relativePath);
10067
10094
  try {
10068
- fs16.mkdirSync(path18.dirname(absPath), { recursive: true });
10069
- fs16.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
10095
+ fs17.mkdirSync(path19.dirname(absPath), { recursive: true });
10096
+ fs17.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
10070
10097
  mode: 384
10071
10098
  });
10072
10099
  console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
@@ -10218,7 +10245,7 @@ var init_manager = __esm({
10218
10245
  let taskWithPolicies = opts.task;
10219
10246
  try {
10220
10247
  const allPolicies = repos.flatMap((repo) => {
10221
- const repoWorktree = path18.join(workspacePath, repo.name);
10248
+ const repoWorktree = path19.join(workspacePath, repo.name);
10222
10249
  return loadPolicies(repoWorktree);
10223
10250
  });
10224
10251
  const seen = /* @__PURE__ */ new Set();
@@ -10234,8 +10261,8 @@ var init_manager = __esm({
10234
10261
  ${opts.task}`;
10235
10262
  execSync4(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
10236
10263
  for (const repo of repos) {
10237
- const policiesDir = path18.join(workspacePath, repo.name, ".olam", "policies");
10238
- if (fs16.existsSync(policiesDir)) {
10264
+ const policiesDir = path19.join(workspacePath, repo.name, ".olam", "policies");
10265
+ if (fs17.existsSync(policiesDir)) {
10239
10266
  execSync4(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
10240
10267
  }
10241
10268
  }
@@ -10314,8 +10341,8 @@ ${opts.task}`;
10314
10341
  } catch {
10315
10342
  }
10316
10343
  try {
10317
- fs16.rmSync(world.workspacePath, { recursive: true, force: true });
10318
- if (fs16.existsSync(world.workspacePath)) {
10344
+ fs17.rmSync(world.workspacePath, { recursive: true, force: true });
10345
+ if (fs17.existsSync(world.workspacePath)) {
10319
10346
  console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
10320
10347
  }
10321
10348
  } catch (err) {
@@ -10400,14 +10427,14 @@ ${opts.task}`;
10400
10427
  return names.map((name) => this.config.repos.find((r) => r.name === name)).filter((r) => r !== void 0);
10401
10428
  }
10402
10429
  transportPlanFile(planFilePath, workspacePath, repoNames) {
10403
- const planContent = fs16.readFileSync(planFilePath, "utf-8");
10404
- const planFileName = path18.basename(planFilePath);
10430
+ const planContent = fs17.readFileSync(planFilePath, "utf-8");
10431
+ const planFileName = path19.basename(planFilePath);
10405
10432
  const targetRepo = repoNames[0];
10406
10433
  if (!targetRepo)
10407
10434
  return;
10408
- const plansDir = path18.join(workspacePath, targetRepo, "docs", "plans");
10409
- fs16.mkdirSync(plansDir, { recursive: true });
10410
- fs16.writeFileSync(path18.join(plansDir, planFileName), planContent);
10435
+ const plansDir = path19.join(workspacePath, targetRepo, "docs", "plans");
10436
+ fs17.mkdirSync(plansDir, { recursive: true });
10437
+ fs17.writeFileSync(path19.join(plansDir, planFileName), planContent);
10411
10438
  }
10412
10439
  resolveServices(repos) {
10413
10440
  const services = [];
@@ -10500,9 +10527,9 @@ var init_tracker = __esm({
10500
10527
  });
10501
10528
 
10502
10529
  // ../core/dist/world-paths.js
10503
- import * as path19 from "node:path";
10530
+ import * as path20 from "node:path";
10504
10531
  function getWorldDbPath(workspacePath) {
10505
- return path19.join(workspacePath, WORLD_DB_FILENAME);
10532
+ return path20.join(workspacePath, WORLD_DB_FILENAME);
10506
10533
  }
10507
10534
  var WORLD_DB_FILENAME;
10508
10535
  var init_world_paths = __esm({
@@ -11120,9 +11147,9 @@ var init_session_aggregator = __esm({
11120
11147
 
11121
11148
  // ../core/dist/dashboard/server.js
11122
11149
  import * as http from "node:http";
11123
- import * as fs17 from "node:fs";
11124
- import * as path20 from "node:path";
11125
- import { fileURLToPath as fileURLToPath2 } from "node:url";
11150
+ import * as fs18 from "node:fs";
11151
+ import * as path21 from "node:path";
11152
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
11126
11153
  function jsonResponse(res, data, status = 200) {
11127
11154
  res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
11128
11155
  res.end(JSON.stringify(data));
@@ -11132,7 +11159,7 @@ function notFound(res) {
11132
11159
  }
11133
11160
  function openThoughtStore(workspacePath) {
11134
11161
  const dbPath = getWorldDbPath(workspacePath);
11135
- if (!fs17.existsSync(dbPath))
11162
+ if (!fs18.existsSync(dbPath))
11136
11163
  return null;
11137
11164
  return new ThoughtLocalStore(dbPath);
11138
11165
  }
@@ -11303,13 +11330,13 @@ function findSessionInWorld(registry, sessionId) {
11303
11330
  }
11304
11331
  function createDashboardServer(opts) {
11305
11332
  const { port, registry } = opts;
11306
- const thisDir = path20.dirname(fileURLToPath2(import.meta.url));
11307
- const defaultPublicDir = path20.resolve(thisDir, "../../../control-plane/public");
11333
+ const thisDir = path21.dirname(fileURLToPath3(import.meta.url));
11334
+ const defaultPublicDir = path21.resolve(thisDir, "../../../control-plane/public");
11308
11335
  const publicDir = opts.publicDir ?? defaultPublicDir;
11309
- let hasPublicDir = fs17.existsSync(publicDir);
11336
+ let hasPublicDir = fs18.existsSync(publicDir);
11310
11337
  const server = http.createServer((req, res) => {
11311
11338
  if (!hasPublicDir) {
11312
- hasPublicDir = fs17.existsSync(publicDir);
11339
+ hasPublicDir = fs18.existsSync(publicDir);
11313
11340
  }
11314
11341
  const host = req.headers.host ?? `localhost:${port}`;
11315
11342
  const url = new URL(req.url ?? "/", `http://${host}`);
@@ -11583,22 +11610,22 @@ function createDashboardServer(opts) {
11583
11610
  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>`);
11584
11611
  return;
11585
11612
  }
11586
- let filePath = path20.join(publicDir, pathname === "/" ? "index.html" : pathname);
11613
+ let filePath = path21.join(publicDir, pathname === "/" ? "index.html" : pathname);
11587
11614
  if (!filePath.startsWith(publicDir)) {
11588
11615
  notFound(res);
11589
11616
  return;
11590
11617
  }
11591
- if (fs17.existsSync(filePath) && fs17.statSync(filePath).isFile()) {
11592
- const ext2 = path20.extname(filePath);
11618
+ if (fs18.existsSync(filePath) && fs18.statSync(filePath).isFile()) {
11619
+ const ext2 = path21.extname(filePath);
11593
11620
  const contentType = MIME[ext2] ?? "application/octet-stream";
11594
11621
  res.writeHead(200, { "Content-Type": contentType });
11595
- fs17.createReadStream(filePath).pipe(res);
11622
+ fs18.createReadStream(filePath).pipe(res);
11596
11623
  return;
11597
11624
  }
11598
- filePath = path20.join(publicDir, "index.html");
11599
- if (fs17.existsSync(filePath)) {
11625
+ filePath = path21.join(publicDir, "index.html");
11626
+ if (fs18.existsSync(filePath)) {
11600
11627
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
11601
- fs17.createReadStream(filePath).pipe(res);
11628
+ fs18.createReadStream(filePath).pipe(res);
11602
11629
  return;
11603
11630
  }
11604
11631
  notFound(res);
@@ -11629,16 +11656,16 @@ var init_server = __esm({
11629
11656
  });
11630
11657
 
11631
11658
  // ../core/dist/dashboard/state.js
11632
- import * as fs18 from "node:fs";
11659
+ import * as fs19 from "node:fs";
11633
11660
  import * as os11 from "node:os";
11634
- import * as path21 from "node:path";
11661
+ import * as path22 from "node:path";
11635
11662
  function saveDashboardState(state) {
11636
- fs18.mkdirSync(path21.dirname(STATE_PATH), { recursive: true });
11637
- fs18.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
11663
+ fs19.mkdirSync(path22.dirname(STATE_PATH), { recursive: true });
11664
+ fs19.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
11638
11665
  }
11639
11666
  function loadDashboardState() {
11640
11667
  try {
11641
- const raw = fs18.readFileSync(STATE_PATH, "utf-8");
11668
+ const raw = fs19.readFileSync(STATE_PATH, "utf-8");
11642
11669
  return JSON.parse(raw);
11643
11670
  } catch {
11644
11671
  return null;
@@ -11646,7 +11673,7 @@ function loadDashboardState() {
11646
11673
  }
11647
11674
  function clearDashboardState() {
11648
11675
  try {
11649
- fs18.unlinkSync(STATE_PATH);
11676
+ fs19.unlinkSync(STATE_PATH);
11650
11677
  } catch {
11651
11678
  }
11652
11679
  }
@@ -11666,7 +11693,7 @@ var STATE_PATH;
11666
11693
  var init_state2 = __esm({
11667
11694
  "../core/dist/dashboard/state.js"() {
11668
11695
  "use strict";
11669
- STATE_PATH = path21.join(os11.homedir(), ".olam", "dashboard.json");
11696
+ STATE_PATH = path22.join(os11.homedir(), ".olam", "dashboard.json");
11670
11697
  }
11671
11698
  });
11672
11699
 
@@ -12061,50 +12088,50 @@ __export(host_cp_exports, {
12061
12088
  writeToken: () => writeToken
12062
12089
  });
12063
12090
  import * as crypto5 from "node:crypto";
12064
- import * as fs19 from "node:fs";
12091
+ import * as fs20 from "node:fs";
12065
12092
  import * as os12 from "node:os";
12066
- import * as path22 from "node:path";
12093
+ import * as path23 from "node:path";
12067
12094
  import { spawnSync as spawnSync4 } from "node:child_process";
12068
12095
  import Dockerode2 from "dockerode";
12069
12096
  function findComposeFile() {
12070
12097
  const candidates = [
12071
12098
  // Bundled path: dist/index.js lives at <pkg>/dist/; host-cp/ is a sibling of dist/
12072
- path22.resolve(path22.dirname(new URL(import.meta.url).pathname), "../host-cp/compose.yaml"),
12099
+ path23.resolve(path23.dirname(new URL(import.meta.url).pathname), "../host-cp/compose.yaml"),
12073
12100
  // Source-mode: cwd is monorepo root
12074
- path22.resolve(process.cwd(), "packages/host-cp/compose.yaml"),
12101
+ path23.resolve(process.cwd(), "packages/host-cp/compose.yaml"),
12075
12102
  // Source-mode: cwd is one level inside the monorepo
12076
- path22.resolve(process.cwd(), "../packages/host-cp/compose.yaml")
12103
+ path23.resolve(process.cwd(), "../packages/host-cp/compose.yaml")
12077
12104
  ];
12078
12105
  for (const c of candidates) {
12079
- if (fs19.existsSync(c)) return c;
12106
+ if (fs20.existsSync(c)) return c;
12080
12107
  }
12081
- return path22.resolve(process.cwd(), "packages/host-cp/compose.yaml");
12108
+ return path23.resolve(process.cwd(), "packages/host-cp/compose.yaml");
12082
12109
  }
12083
12110
  function olamHome() {
12084
- return process.env.OLAM_HOME ?? path22.join(os12.homedir(), ".olam");
12111
+ return process.env.OLAM_HOME ?? path23.join(os12.homedir(), ".olam");
12085
12112
  }
12086
12113
  function tokenPath() {
12087
- return path22.join(olamHome(), "host-cp.token");
12114
+ return path23.join(olamHome(), "host-cp.token");
12088
12115
  }
12089
12116
  function pidPath() {
12090
- return path22.join(olamHome(), "host-cp.pid");
12117
+ return path23.join(olamHome(), "host-cp.pid");
12091
12118
  }
12092
12119
  function authSecretPath() {
12093
- return path22.join(olamHome(), "auth-secret");
12120
+ return path23.join(olamHome(), "auth-secret");
12094
12121
  }
12095
12122
  function readAuthSecret2() {
12096
12123
  const filePath = authSecretPath();
12097
- if (!fs19.existsSync(filePath)) return null;
12098
- const raw = fs19.readFileSync(filePath, "utf-8").trim();
12124
+ if (!fs20.existsSync(filePath)) return null;
12125
+ const raw = fs20.readFileSync(filePath, "utf-8").trim();
12099
12126
  return raw.length > 0 ? raw : null;
12100
12127
  }
12101
12128
  function r2CredentialsPath() {
12102
- return path22.join(olamHome(), "r2-credentials.json");
12129
+ return path23.join(olamHome(), "r2-credentials.json");
12103
12130
  }
12104
12131
  function readR2Credentials() {
12105
12132
  const filePath = r2CredentialsPath();
12106
- if (!fs19.existsSync(filePath)) return null;
12107
- const raw = fs19.readFileSync(filePath, "utf-8").trim();
12133
+ if (!fs20.existsSync(filePath)) return null;
12134
+ const raw = fs20.readFileSync(filePath, "utf-8").trim();
12108
12135
  if (raw.length === 0) return null;
12109
12136
  try {
12110
12137
  const parsed = JSON.parse(raw);
@@ -12127,37 +12154,37 @@ function readR2Credentials() {
12127
12154
  function writeToken() {
12128
12155
  const token = crypto5.randomBytes(32).toString("hex");
12129
12156
  const filePath = tokenPath();
12130
- fs19.mkdirSync(path22.dirname(filePath), { recursive: true });
12131
- fs19.writeFileSync(filePath, token, { mode: 384 });
12157
+ fs20.mkdirSync(path23.dirname(filePath), { recursive: true });
12158
+ fs20.writeFileSync(filePath, token, { mode: 384 });
12132
12159
  return token;
12133
12160
  }
12134
12161
  function readToken() {
12135
12162
  const filePath = tokenPath();
12136
- if (!fs19.existsSync(filePath)) return null;
12137
- return fs19.readFileSync(filePath, "utf-8").trim();
12163
+ if (!fs20.existsSync(filePath)) return null;
12164
+ return fs20.readFileSync(filePath, "utf-8").trim();
12138
12165
  }
12139
12166
  function removeToken() {
12140
12167
  const filePath = tokenPath();
12141
- if (!fs19.existsSync(filePath)) return false;
12142
- fs19.unlinkSync(filePath);
12168
+ if (!fs20.existsSync(filePath)) return false;
12169
+ fs20.unlinkSync(filePath);
12143
12170
  return true;
12144
12171
  }
12145
12172
  function writePid(pid) {
12146
12173
  const filePath = pidPath();
12147
- fs19.mkdirSync(path22.dirname(filePath), { recursive: true });
12148
- fs19.writeFileSync(filePath, String(pid), { mode: 420 });
12174
+ fs20.mkdirSync(path23.dirname(filePath), { recursive: true });
12175
+ fs20.writeFileSync(filePath, String(pid), { mode: 420 });
12149
12176
  }
12150
12177
  function readPid() {
12151
12178
  const filePath = pidPath();
12152
- if (!fs19.existsSync(filePath)) return null;
12153
- const raw = fs19.readFileSync(filePath, "utf-8").trim();
12179
+ if (!fs20.existsSync(filePath)) return null;
12180
+ const raw = fs20.readFileSync(filePath, "utf-8").trim();
12154
12181
  const n = parseInt(raw, 10);
12155
12182
  return Number.isFinite(n) ? n : null;
12156
12183
  }
12157
12184
  function removePid() {
12158
12185
  const filePath = pidPath();
12159
- if (!fs19.existsSync(filePath)) return false;
12160
- fs19.unlinkSync(filePath);
12186
+ if (!fs20.existsSync(filePath)) return false;
12187
+ fs20.unlinkSync(filePath);
12161
12188
  return true;
12162
12189
  }
12163
12190
  async function findHostCpContainer() {
@@ -12269,6 +12296,10 @@ function buildComposeEnv(authSecret, ghToken) {
12269
12296
  if (ghToken != null && ghToken.length > 0) {
12270
12297
  env.GH_TOKEN = ghToken;
12271
12298
  }
12299
+ const cliVersion = readCliVersion();
12300
+ if (cliVersion && cliVersion !== "0.0.0-unknown") {
12301
+ env.OLAM_CLI_VERSION = cliVersion;
12302
+ }
12272
12303
  return env;
12273
12304
  }
12274
12305
  function captureGhToken() {
@@ -12316,7 +12347,7 @@ async function handleStart(opts) {
12316
12347
  }
12317
12348
  const token = writeToken();
12318
12349
  const composeFile = findComposeFile();
12319
- if (!fs19.existsSync(composeFile)) {
12350
+ if (!fs20.existsSync(composeFile)) {
12320
12351
  printError(`compose.yaml not found at ${composeFile}. Run from the olam project root.`);
12321
12352
  removeToken();
12322
12353
  process.exitCode = 1;
@@ -12398,7 +12429,7 @@ async function stopHostCp() {
12398
12429
  }
12399
12430
  async function handleStop() {
12400
12431
  const composeFile = findComposeFile();
12401
- if (!fs19.existsSync(composeFile)) {
12432
+ if (!fs20.existsSync(composeFile)) {
12402
12433
  printWarning(`compose.yaml not found at ${composeFile}. Cleaning up token + PID anyway.`);
12403
12434
  removeToken();
12404
12435
  removePid();
@@ -12426,13 +12457,13 @@ async function buildStatusReport() {
12426
12457
  const container = await findHostCpContainer();
12427
12458
  const health = await probeHealth();
12428
12459
  const tokenFile = tokenPath();
12429
- const tokenPresent = fs19.existsSync(tokenFile);
12460
+ const tokenPresent = fs20.existsSync(tokenFile);
12430
12461
  let tokenModeOk = false;
12431
12462
  if (tokenPresent) {
12432
- const mode = fs19.statSync(tokenFile).mode & 511;
12463
+ const mode = fs20.statSync(tokenFile).mode & 511;
12433
12464
  tokenModeOk = mode === 384;
12434
12465
  }
12435
- const pidPresent = fs19.existsSync(pidPath());
12466
+ const pidPresent = fs20.existsSync(pidPath());
12436
12467
  let stack;
12437
12468
  if (!container) {
12438
12469
  stack = "not_started";
@@ -12520,8 +12551,8 @@ async function discoverWorldPort(worldId) {
12520
12551
  }
12521
12552
  async function readHostCpToken2() {
12522
12553
  const tp = tokenPath();
12523
- if (!fs19.existsSync(tp)) return null;
12524
- return fs19.readFileSync(tp, "utf-8").trim();
12554
+ if (!fs20.existsSync(tp)) return null;
12555
+ return fs20.readFileSync(tp, "utf-8").trim();
12525
12556
  }
12526
12557
  async function callHostCpProxy(method, worldId, path46, body) {
12527
12558
  const token = await readHostCpToken2();
@@ -12637,6 +12668,7 @@ var init_host_cp = __esm({
12637
12668
  init_dist();
12638
12669
  init_output();
12639
12670
  init_docker_host();
12671
+ init_cli_version();
12640
12672
  init_open_url();
12641
12673
  HOST_CP_PORT = 19e3;
12642
12674
  SIDECAR_PULL_SERVICE = "docker-socket-proxy";
@@ -12651,17 +12683,17 @@ __export(install_root_exports, {
12651
12683
  isDevMode: () => isDevMode,
12652
12684
  resolveBuildScript: () => resolveBuildScript
12653
12685
  });
12654
- import { existsSync as existsSync18 } from "node:fs";
12655
- import { dirname as dirname13, join as join24, resolve as resolve6 } from "node:path";
12656
- import { fileURLToPath as fileURLToPath3 } from "node:url";
12686
+ import { existsSync as existsSync19 } from "node:fs";
12687
+ import { dirname as dirname14, join as join25, resolve as resolve6 } from "node:path";
12688
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
12657
12689
  function installRoot(metaUrl = import.meta.url) {
12658
- const here = fileURLToPath3(metaUrl);
12659
- return resolve6(dirname13(here), "..");
12690
+ const here = fileURLToPath4(metaUrl);
12691
+ return resolve6(dirname14(here), "..");
12660
12692
  }
12661
12693
  function isDevMode(env = process.env, installRootDir = installRoot()) {
12662
12694
  if (env.OLAM_DEV !== "1") return false;
12663
12695
  const repoRoot = resolve6(installRootDir, "..", "..");
12664
- return existsSync18(join24(repoRoot, "packages")) && existsSync18(join24(repoRoot, "package.json"));
12696
+ return existsSync19(join25(repoRoot, "packages")) && existsSync19(join25(repoRoot, "package.json"));
12665
12697
  }
12666
12698
  function resolveBuildScript(input) {
12667
12699
  const { scriptRelPath, env = process.env, installRootDir = installRoot() } = input;
@@ -12669,7 +12701,7 @@ function resolveBuildScript(input) {
12669
12701
  throw new MissingBuildScriptError(scriptRelPath);
12670
12702
  }
12671
12703
  const repoRoot = resolve6(installRootDir, "..", "..");
12672
- return join24(repoRoot, scriptRelPath);
12704
+ return join25(repoRoot, scriptRelPath);
12673
12705
  }
12674
12706
  var MissingBuildScriptError;
12675
12707
  var init_install_root = __esm({
@@ -12840,20 +12872,20 @@ var init_registry_allowlist = __esm({
12840
12872
  });
12841
12873
 
12842
12874
  // ../core/dist/world/world-yaml.js
12843
- import * as fs21 from "node:fs";
12844
- import * as path24 from "node:path";
12875
+ import * as fs22 from "node:fs";
12876
+ import * as path25 from "node:path";
12845
12877
  import { parse as parseYaml4, stringify as stringifyYaml4 } from "yaml";
12846
12878
  function writeWorldYaml(worldPath, data) {
12847
- const olamDir = path24.join(worldPath, ".olam");
12848
- fs21.mkdirSync(olamDir, { recursive: true });
12849
- fs21.writeFileSync(path24.join(olamDir, "world.yaml"), stringifyYaml4(data), "utf-8");
12879
+ const olamDir = path25.join(worldPath, ".olam");
12880
+ fs22.mkdirSync(olamDir, { recursive: true });
12881
+ fs22.writeFileSync(path25.join(olamDir, "world.yaml"), stringifyYaml4(data), "utf-8");
12850
12882
  }
12851
12883
  function readWorldYaml(worldPath) {
12852
- const yamlPath = path24.join(worldPath, ".olam", "world.yaml");
12853
- if (!fs21.existsSync(yamlPath))
12884
+ const yamlPath = path25.join(worldPath, ".olam", "world.yaml");
12885
+ if (!fs22.existsSync(yamlPath))
12854
12886
  return null;
12855
12887
  try {
12856
- const raw = fs21.readFileSync(yamlPath, "utf-8");
12888
+ const raw = fs22.readFileSync(yamlPath, "utf-8");
12857
12889
  const parsed = parseYaml4(raw);
12858
12890
  return WorldYamlSchema.parse(parsed);
12859
12891
  } catch {
@@ -12984,16 +13016,16 @@ __export(machine_schema_exports, {
12984
13016
  readMachineConfig: () => readMachineConfig,
12985
13017
  writeMachineConfig: () => writeMachineConfig
12986
13018
  });
12987
- import * as fs35 from "node:fs";
12988
- import * as path39 from "node:path";
13019
+ import * as fs36 from "node:fs";
13020
+ import * as path40 from "node:path";
12989
13021
  import * as os21 from "node:os";
12990
13022
  import { parse as parseYaml5, stringify as stringifyYaml5 } from "yaml";
12991
13023
  function readMachineConfig(configPath) {
12992
13024
  const p = configPath ?? DEFAULT_CONFIG_PATH;
12993
- if (!fs35.existsSync(p))
13025
+ if (!fs36.existsSync(p))
12994
13026
  return null;
12995
13027
  try {
12996
- const raw = fs35.readFileSync(p, "utf-8");
13028
+ const raw = fs36.readFileSync(p, "utf-8");
12997
13029
  const parsed = parseYaml5(raw);
12998
13030
  return MachineConfigSchema.parse(parsed);
12999
13031
  } catch {
@@ -13002,8 +13034,8 @@ function readMachineConfig(configPath) {
13002
13034
  }
13003
13035
  function writeMachineConfig(config, configPath) {
13004
13036
  const p = configPath ?? DEFAULT_CONFIG_PATH;
13005
- fs35.mkdirSync(path39.dirname(p), { recursive: true });
13006
- fs35.writeFileSync(p, stringifyYaml5({ ...config }), { mode: 420 });
13037
+ fs36.mkdirSync(path40.dirname(p), { recursive: true });
13038
+ fs36.writeFileSync(p, stringifyYaml5({ ...config }), { mode: 420 });
13007
13039
  }
13008
13040
  function initMachineConfig(opts = {}) {
13009
13041
  const configPath = opts.configPath ?? DEFAULT_CONFIG_PATH;
@@ -13026,22 +13058,20 @@ var init_machine_schema = __esm({
13026
13058
  channel: external_exports.enum(["stable", "beta", "edge"]).default("stable"),
13027
13059
  auto_update: external_exports.boolean().default(true),
13028
13060
  telemetry: external_exports.boolean().default(true),
13029
- worlds_dir: external_exports.string().default(() => path39.join(os21.homedir(), ".olam", "worlds"))
13061
+ worlds_dir: external_exports.string().default(() => path40.join(os21.homedir(), ".olam", "worlds"))
13030
13062
  });
13031
- DEFAULT_CONFIG_PATH = path39.join(os21.homedir(), ".olam", "config.yaml");
13063
+ DEFAULT_CONFIG_PATH = path40.join(os21.homedir(), ".olam", "config.yaml");
13032
13064
  }
13033
13065
  });
13034
13066
 
13035
13067
  // src/index.ts
13068
+ init_cli_version();
13036
13069
  import { Command } from "commander";
13037
- import * as fs42 from "node:fs";
13038
- import * as path45 from "node:path";
13039
- import { fileURLToPath as fileURLToPath4 } from "node:url";
13040
13070
 
13041
13071
  // src/commands/init.ts
13042
13072
  init_output();
13043
- import * as fs5 from "node:fs";
13044
- import * as path5 from "node:path";
13073
+ import * as fs6 from "node:fs";
13074
+ import * as path6 from "node:path";
13045
13075
  import { execSync } from "node:child_process";
13046
13076
  import pc3 from "picocolors";
13047
13077
 
@@ -13049,8 +13079,8 @@ import pc3 from "picocolors";
13049
13079
  init_workspace();
13050
13080
  init_loader();
13051
13081
  init_output();
13052
- import * as fs4 from "node:fs";
13053
- import * as path4 from "node:path";
13082
+ import * as fs5 from "node:fs";
13083
+ import * as path5 from "node:path";
13054
13084
  import pc2 from "picocolors";
13055
13085
  import { stringify as stringifyYaml2 } from "yaml";
13056
13086
  function printWorkspaceNotFound(name) {
@@ -13144,7 +13174,7 @@ function registerWorkspace(program2) {
13144
13174
  updatedAt: Date.now()
13145
13175
  };
13146
13176
  writeWorkspace(ws, { force: opts.force });
13147
- const file = path4.join(workspacesDir(), `${name}.yaml`);
13177
+ const file = path5.join(workspacesDir(), `${name}.yaml`);
13148
13178
  printSuccess(`Created workspace "${name}" (${repos.length} repo${repos.length === 1 ? "" : "s"})`);
13149
13179
  printInfo("File", file);
13150
13180
  printInfo("Next", `olam create --name <world> --workspace ${name} --task "..."`);
@@ -13168,7 +13198,7 @@ function ensureProjectWorkspaceFromConfig(projectRoot, workspaceName) {
13168
13198
  }
13169
13199
  })();
13170
13200
  if (existing) {
13171
- return { created: false, file: path4.join(workspacesDir(), `${workspaceName}.yaml`) };
13201
+ return { created: false, file: path5.join(workspacesDir(), `${workspaceName}.yaml`) };
13172
13202
  }
13173
13203
  const cfg = loadConfig(projectRoot);
13174
13204
  const repos = cfg.repos.map((r) => ({
@@ -13182,15 +13212,15 @@ function ensureProjectWorkspaceFromConfig(projectRoot, workspaceName) {
13182
13212
  updatedAt: Date.now()
13183
13213
  };
13184
13214
  writeWorkspace(ws);
13185
- const file = path4.join(workspacesDir(), `${workspaceName}.yaml`);
13215
+ const file = path5.join(workspacesDir(), `${workspaceName}.yaml`);
13186
13216
  return { created: true, file };
13187
13217
  }
13188
13218
 
13189
13219
  // src/commands/init.ts
13190
13220
  function detectProjectType(root) {
13191
- if (fs5.existsSync(path5.join(root, "Gemfile")) || fs5.existsSync(path5.join(root, "config", "routes.rb"))) return "rails";
13192
- if (fs5.existsSync(path5.join(root, "package.json"))) return "node";
13193
- if (fs5.existsSync(path5.join(root, "pyproject.toml")) || fs5.existsSync(path5.join(root, "requirements.txt"))) return "python";
13221
+ if (fs6.existsSync(path6.join(root, "Gemfile")) || fs6.existsSync(path6.join(root, "config", "routes.rb"))) return "rails";
13222
+ if (fs6.existsSync(path6.join(root, "package.json"))) return "node";
13223
+ if (fs6.existsSync(path6.join(root, "pyproject.toml")) || fs6.existsSync(path6.join(root, "requirements.txt"))) return "python";
13194
13224
  return "generic";
13195
13225
  }
13196
13226
  function getRepoName(root) {
@@ -13203,13 +13233,13 @@ function getRepoName(root) {
13203
13233
  if (match2) return match2[1];
13204
13234
  } catch {
13205
13235
  }
13206
- return path5.basename(root);
13236
+ return path6.basename(root);
13207
13237
  }
13208
13238
  function findProjectRoot(startDir) {
13209
- let current = path5.resolve(startDir);
13239
+ let current = path6.resolve(startDir);
13210
13240
  while (true) {
13211
- if (fs5.existsSync(path5.join(current, ".git"))) return current;
13212
- const parent = path5.dirname(current);
13241
+ if (fs6.existsSync(path6.join(current, ".git"))) return current;
13242
+ const parent = path6.dirname(current);
13213
13243
  if (parent === current) return startDir;
13214
13244
  current = parent;
13215
13245
  }
@@ -13218,8 +13248,8 @@ function registerInit(program2) {
13218
13248
  program2.command("init").description("Initialize olam in the current project").option("--path <path>", "Project root path", process.cwd()).option("--skip-pleri", "Skip Pleri setup").action(async (opts) => {
13219
13249
  try {
13220
13250
  const projectRoot = findProjectRoot(opts.path);
13221
- const olamDir = path5.join(projectRoot, ".olam");
13222
- if (fs5.existsSync(path5.join(olamDir, "config.yaml"))) {
13251
+ const olamDir = path6.join(projectRoot, ".olam");
13252
+ if (fs6.existsSync(path6.join(olamDir, "config.yaml"))) {
13223
13253
  printError(`Already initialized at ${olamDir}/config.yaml`);
13224
13254
  process.exitCode = 1;
13225
13255
  return;
@@ -13235,8 +13265,8 @@ function registerInit(program2) {
13235
13265
  } catch {
13236
13266
  remoteUrl = `git@github.com:your-org/${repoName}.git`;
13237
13267
  }
13238
- fs5.mkdirSync(path5.join(olamDir, "state"), { recursive: true });
13239
- fs5.mkdirSync(path5.join(olamDir, "thoughts"), { recursive: true });
13268
+ fs6.mkdirSync(path6.join(olamDir, "state"), { recursive: true });
13269
+ fs6.mkdirSync(path6.join(olamDir, "thoughts"), { recursive: true });
13240
13270
  const pleriSection = opts.skipPleri ? "# pleri:\n# base_url: ${PLERI_BASE_URL}\n# plane_id: ${PLERI_PLANE_ID}\n# api_key: ${PLERI_API_KEY}\n" : "pleri:\n base_url: ${PLERI_BASE_URL}\n plane_id: ${PLERI_PLANE_ID}\n api_key: ${PLERI_API_KEY}\n";
13241
13271
  const config = [
13242
13272
  "version: 2",
@@ -13264,7 +13294,7 @@ function registerInit(program2) {
13264
13294
  " mode: oauth",
13265
13295
  ""
13266
13296
  ].join("\n");
13267
- fs5.writeFileSync(path5.join(olamDir, "config.yaml"), config);
13297
+ fs6.writeFileSync(path6.join(olamDir, "config.yaml"), config);
13268
13298
  const envExample = [
13269
13299
  "# Pleri credentials",
13270
13300
  "PLERI_BASE_URL=https://pleri.dev/api",
@@ -13272,7 +13302,7 @@ function registerInit(program2) {
13272
13302
  "PLERI_API_KEY=",
13273
13303
  ""
13274
13304
  ].join("\n");
13275
- fs5.writeFileSync(path5.join(olamDir, ".env.example"), envExample);
13305
+ fs6.writeFileSync(path6.join(olamDir, ".env.example"), envExample);
13276
13306
  printHeader("Olam initialized");
13277
13307
  printInfo("Config", `${olamDir}/config.yaml`);
13278
13308
  printInfo("Project", `${projectType} (detected)`);
@@ -13297,9 +13327,9 @@ ${pc3.dim(`Next: olam create --name my-world --workspace ${repoName} --task "...
13297
13327
  }
13298
13328
 
13299
13329
  // src/commands/install.ts
13300
- import * as fs6 from "node:fs";
13330
+ import * as fs7 from "node:fs";
13301
13331
  import * as os3 from "node:os";
13302
- import * as path6 from "node:path";
13332
+ import * as path7 from "node:path";
13303
13333
  import pc4 from "picocolors";
13304
13334
  import { stringify as stringifyYaml3 } from "yaml";
13305
13335
 
@@ -13442,11 +13472,11 @@ function walk(name, acc, stack) {
13442
13472
 
13443
13473
  // src/commands/install.ts
13444
13474
  init_output();
13445
- var ROLE_FILE_PATH = path6.join(os3.homedir(), ".olam", "role.yaml");
13475
+ var ROLE_FILE_PATH = path7.join(os3.homedir(), ".olam", "role.yaml");
13446
13476
  function readRoleFile() {
13447
- if (!fs6.existsSync(ROLE_FILE_PATH)) return null;
13477
+ if (!fs7.existsSync(ROLE_FILE_PATH)) return null;
13448
13478
  try {
13449
- const raw = fs6.readFileSync(ROLE_FILE_PATH, "utf-8");
13479
+ const raw = fs7.readFileSync(ROLE_FILE_PATH, "utf-8");
13450
13480
  const m = /archetype:\s*(\S+)/.exec(raw);
13451
13481
  if (!m) return null;
13452
13482
  const archetype = m[1];
@@ -13466,13 +13496,13 @@ function readRoleFile() {
13466
13496
  }
13467
13497
  }
13468
13498
  function writeRoleFile(role) {
13469
- fs6.mkdirSync(path6.dirname(ROLE_FILE_PATH), { recursive: true });
13499
+ fs7.mkdirSync(path7.dirname(ROLE_FILE_PATH), { recursive: true });
13470
13500
  const yaml = stringifyYaml3({
13471
13501
  archetype: role.archetype,
13472
13502
  customCapabilities: [...role.customCapabilities],
13473
13503
  installedAt: role.installedAt
13474
13504
  });
13475
- fs6.writeFileSync(ROLE_FILE_PATH, yaml, { mode: 420 });
13505
+ fs7.writeFileSync(ROLE_FILE_PATH, yaml, { mode: 420 });
13476
13506
  }
13477
13507
  function nextStepsFor(archetype) {
13478
13508
  switch (archetype) {
@@ -13613,21 +13643,21 @@ import * as readline from "node:readline/promises";
13613
13643
  import { spawn as spawn3 } from "node:child_process";
13614
13644
 
13615
13645
  // src/commands/auth-status.ts
13616
- import * as fs8 from "node:fs";
13646
+ import * as fs9 from "node:fs";
13617
13647
  import * as os5 from "node:os";
13618
- import * as path9 from "node:path";
13648
+ import * as path10 from "node:path";
13619
13649
  import pc5 from "picocolors";
13620
13650
  init_auth();
13621
13651
  init_output();
13622
13652
  init_exit_codes();
13623
- var LOCAL_DATA_DIR = path9.join(os5.homedir(), ".olam", "auth-data");
13653
+ var LOCAL_DATA_DIR = path10.join(os5.homedir(), ".olam", "auth-data");
13624
13654
 
13625
13655
  // src/commands/auth-upgrade.ts
13626
13656
  init_output();
13627
13657
  init_host_cp();
13628
13658
  init_auth();
13629
- import * as fs20 from "node:fs";
13630
- import * as path23 from "node:path";
13659
+ import * as fs21 from "node:fs";
13660
+ import * as path24 from "node:path";
13631
13661
  import { spawnSync as spawnSync7 } from "node:child_process";
13632
13662
  import ora2 from "ora";
13633
13663
  import pc7 from "picocolors";
@@ -13638,20 +13668,20 @@ init_exit_codes();
13638
13668
  init_protocol_version();
13639
13669
  init_output();
13640
13670
  import { spawn as spawn2, spawnSync as spawnSync6 } from "node:child_process";
13641
- import { existsSync as existsSync19, readFileSync as readFileSync15 } from "node:fs";
13642
- import { join as join25 } from "node:path";
13671
+ import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
13672
+ import { join as join26 } from "node:path";
13643
13673
  import ora from "ora";
13644
13674
  import pc6 from "picocolors";
13645
13675
  function loadImageDigests(installRootDir = installRoot()) {
13646
- const digestsPath = join25(installRootDir, "dist", "image-digests.json");
13647
- if (!existsSync19(digestsPath)) {
13676
+ const digestsPath = join26(installRootDir, "dist", "image-digests.json");
13677
+ if (!existsSync20(digestsPath)) {
13648
13678
  throw new Error(
13649
13679
  `image-digests.json missing at ${digestsPath}. Re-run \`npm install -g @pleri/olam-cli@<version>\` to refresh the tarball.`
13650
13680
  );
13651
13681
  }
13652
13682
  let parsed;
13653
13683
  try {
13654
- parsed = JSON.parse(readFileSync15(digestsPath, "utf8"));
13684
+ parsed = JSON.parse(readFileSync16(digestsPath, "utf8"));
13655
13685
  } catch (err) {
13656
13686
  throw new Error(`image-digests.json is not valid JSON: ${err.message}`);
13657
13687
  }
@@ -13968,8 +13998,8 @@ function parseAuthUpgradeOpts(raw) {
13968
13998
  };
13969
13999
  }
13970
14000
  function validateAuthRepoRoot(cwd) {
13971
- const marker = path23.join(cwd, "packages/auth-service/Dockerfile");
13972
- if (!fs20.existsSync(marker)) {
14001
+ const marker = path24.join(cwd, "packages/auth-service/Dockerfile");
14002
+ if (!fs21.existsSync(marker)) {
13973
14003
  return {
13974
14004
  ok: false,
13975
14005
  error: `Not an olam repo root (expected ${marker}).
@@ -14703,15 +14733,15 @@ ${pc9.dim("Next: olam create --name my-world")}`);
14703
14733
  // src/commands/create.ts
14704
14734
  init_manager();
14705
14735
  import { spawnSync as spawnSync9 } from "node:child_process";
14706
- import { existsSync as existsSync22 } from "node:fs";
14707
- import { dirname as dirname14, resolve as resolve7 } from "node:path";
14736
+ import { existsSync as existsSync23 } from "node:fs";
14737
+ import { dirname as dirname15, resolve as resolve7 } from "node:path";
14708
14738
  import ora3 from "ora";
14709
14739
  import pc10 from "picocolors";
14710
14740
 
14711
14741
  // ../core/dist/world/devbox-freshness.js
14712
14742
  import { execSync as execSync6 } from "node:child_process";
14713
- import { existsSync as existsSync21, statSync as statSync5 } from "node:fs";
14714
- import { join as join27 } from "node:path";
14743
+ import { existsSync as existsSync22, statSync as statSync5 } from "node:fs";
14744
+ import { join as join28 } from "node:path";
14715
14745
  var DEFAULT_DEVBOX_IMAGE = "olam-devbox:latest";
14716
14746
  var DEVBOX_BAKED_SOURCES = [
14717
14747
  "packages/adapters/src/docker/devbox.Dockerfile",
@@ -14747,7 +14777,7 @@ function getDevboxFreshness(deps) {
14747
14777
  }
14748
14778
  const newerSources = [];
14749
14779
  for (const relPath of DEVBOX_BAKED_SOURCES) {
14750
- const absPath = join27(deps.repoRoot, relPath);
14780
+ const absPath = join28(deps.repoRoot, relPath);
14751
14781
  const mtimeMs = statMtime(absPath);
14752
14782
  if (mtimeMs === null)
14753
14783
  continue;
@@ -14800,7 +14830,7 @@ function defaultDockerInspect(image) {
14800
14830
  }
14801
14831
  function defaultStatMtime(absPath) {
14802
14832
  try {
14803
- if (!existsSync21(absPath))
14833
+ if (!existsSync22(absPath))
14804
14834
  return null;
14805
14835
  return statSync5(absPath).mtimeMs;
14806
14836
  } catch {
@@ -15296,10 +15326,10 @@ ${pc10.cyan("Host CP UI:")} ${worldUrl}`);
15296
15326
  function resolveRepoRoot(start) {
15297
15327
  let cur = start;
15298
15328
  while (true) {
15299
- if (existsSync22(resolve7(cur, "packages")) && existsSync22(resolve7(cur, "package.json"))) {
15329
+ if (existsSync23(resolve7(cur, "packages")) && existsSync23(resolve7(cur, "package.json"))) {
15300
15330
  return cur;
15301
15331
  }
15302
- const parent = dirname14(cur);
15332
+ const parent = dirname15(cur);
15303
15333
  if (parent === cur) return start;
15304
15334
  cur = parent;
15305
15335
  }
@@ -15527,9 +15557,9 @@ function registerList(program2) {
15527
15557
 
15528
15558
  // src/commands/status.ts
15529
15559
  init_output();
15530
- import * as fs22 from "node:fs";
15560
+ import * as fs23 from "node:fs";
15531
15561
  import * as os13 from "node:os";
15532
- import * as path25 from "node:path";
15562
+ import * as path26 from "node:path";
15533
15563
  var CLI_VERSION2 = process.env["OLAM_CLI_VERSION"] ?? "0.0.0";
15534
15564
  var HOST_CP_PORT2 = 19e3;
15535
15565
  async function getMachineStatus(_probe, _loadCtx, _readToken) {
@@ -15559,14 +15589,14 @@ async function getMachineStatus(_probe, _loadCtx, _readToken) {
15559
15589
  }
15560
15590
  } catch {
15561
15591
  }
15562
- const manifestPath2 = path25.join(os13.homedir(), ".olam", "cache", "manifest.json");
15592
+ const manifestPath2 = path26.join(os13.homedir(), ".olam", "cache", "manifest.json");
15563
15593
  let updateAvailable = null;
15564
15594
  let lastUpdateCheck = null;
15565
- if (fs22.existsSync(manifestPath2)) {
15566
- const mtime = fs22.statSync(manifestPath2).mtime;
15595
+ if (fs23.existsSync(manifestPath2)) {
15596
+ const mtime = fs23.statSync(manifestPath2).mtime;
15567
15597
  lastUpdateCheck = mtime.toISOString();
15568
15598
  try {
15569
- const manifest = JSON.parse(fs22.readFileSync(manifestPath2, "utf-8"));
15599
+ const manifest = JSON.parse(fs23.readFileSync(manifestPath2, "utf-8"));
15570
15600
  const latest = manifest["version"];
15571
15601
  updateAvailable = latest !== void 0 && latest !== CLI_VERSION2;
15572
15602
  } catch {
@@ -15689,9 +15719,9 @@ function registerDestroy(program2) {
15689
15719
  // src/commands/clean.ts
15690
15720
  init_context();
15691
15721
  init_output();
15692
- import fs23 from "node:fs";
15722
+ import fs24 from "node:fs";
15693
15723
  import os14 from "node:os";
15694
- import path26 from "node:path";
15724
+ import path27 from "node:path";
15695
15725
  import { execFileSync as execFileSync5 } from "node:child_process";
15696
15726
  function registerClean(program2) {
15697
15727
  program2.command("clean").description("Reap orphan world filesystem state under ~/.olam/worlds/").option("--apply", "Actually delete the orphans (default is dry-run)", false).option(
@@ -15715,8 +15745,8 @@ async function runClean(opts) {
15715
15745
  printError(error?.message ?? "Olam is not configured. Run `olam init` first.");
15716
15746
  return 1;
15717
15747
  }
15718
- const worldsDir = path26.join(os14.homedir(), ".olam", "worlds");
15719
- if (!fs23.existsSync(worldsDir)) {
15748
+ const worldsDir = path27.join(os14.homedir(), ".olam", "worlds");
15749
+ if (!fs24.existsSync(worldsDir)) {
15720
15750
  if (opts.json) {
15721
15751
  process.stdout.write(`${JSON.stringify({ worldsDir, entries: [] })}
15722
15752
  `);
@@ -15731,8 +15761,8 @@ async function runClean(opts) {
15731
15761
  }
15732
15762
  const worktreeMap = collectWorktrees(worldsDir);
15733
15763
  const entries = [];
15734
- for (const id of fs23.readdirSync(worldsDir).sort()) {
15735
- const fullPath = path26.join(worldsDir, id);
15764
+ for (const id of fs24.readdirSync(worldsDir).sort()) {
15765
+ const fullPath = path27.join(worldsDir, id);
15736
15766
  const stat = safeStat(fullPath);
15737
15767
  if (!stat || !stat.isDirectory()) continue;
15738
15768
  entries.push(classifyWorld({ id, fullPath, liveIds, worktreeMap }));
@@ -15798,7 +15828,7 @@ function classifyWorld(args) {
15798
15828
  if (liveIds.has(id)) {
15799
15829
  return { id, path: fullPath, bytes, category: "active", note: "in registry" };
15800
15830
  }
15801
- const worktreeChild = path26.join(fullPath, "olam");
15831
+ const worktreeChild = path27.join(fullPath, "olam");
15802
15832
  const worktreeInfo = worktreeMap.get(worktreeChild);
15803
15833
  if (worktreeInfo) {
15804
15834
  if (worktreeInfo.dirty > 0 || worktreeInfo.unpushed > 0) {
@@ -15844,20 +15874,20 @@ function reapEntry(entry) {
15844
15874
  }
15845
15875
  }
15846
15876
  try {
15847
- fs23.rmSync(entry.path, { recursive: true, force: true });
15877
+ fs24.rmSync(entry.path, { recursive: true, force: true });
15848
15878
  } catch (err) {
15849
15879
  process.stderr.write(` ! rm ${entry.path}: ${err instanceof Error ? err.message : String(err)}
15850
15880
  `);
15851
15881
  return false;
15852
15882
  }
15853
- return !fs23.existsSync(entry.path);
15883
+ return !fs24.existsSync(entry.path);
15854
15884
  }
15855
15885
  function collectWorktrees(worldsDir) {
15856
15886
  const out = /* @__PURE__ */ new Map();
15857
- for (const id of fs23.readdirSync(worldsDir)) {
15858
- const child = path26.join(worldsDir, id, "olam");
15859
- const gitMarker = path26.join(child, ".git");
15860
- if (!fs23.existsSync(gitMarker)) continue;
15887
+ for (const id of fs24.readdirSync(worldsDir)) {
15888
+ const child = path27.join(worldsDir, id, "olam");
15889
+ const gitMarker = path27.join(child, ".git");
15890
+ if (!fs24.existsSync(gitMarker)) continue;
15861
15891
  const gitDir = resolveGitDirForWorktree(child);
15862
15892
  if (!gitDir) continue;
15863
15893
  const branch = readBranch(child);
@@ -15868,7 +15898,7 @@ function collectWorktrees(worldsDir) {
15868
15898
  return out;
15869
15899
  }
15870
15900
  function resolveGitDirForWorktree(worktreePath) {
15871
- const gitMarker = path26.join(worktreePath, ".git");
15901
+ const gitMarker = path27.join(worktreePath, ".git");
15872
15902
  try {
15873
15903
  const top = execFileSync5("git", ["rev-parse", "--show-toplevel"], {
15874
15904
  cwd: worktreePath,
@@ -15882,7 +15912,7 @@ function resolveGitDirForWorktree(worktreePath) {
15882
15912
  stdio: "pipe"
15883
15913
  }).trim();
15884
15914
  if (!common) return top;
15885
- return path26.dirname(path26.resolve(worktreePath, common));
15915
+ return path27.dirname(path27.resolve(worktreePath, common));
15886
15916
  } catch {
15887
15917
  return null;
15888
15918
  }
@@ -15925,7 +15955,7 @@ function countUnpushed(worktreePath) {
15925
15955
  }
15926
15956
  function safeStat(p) {
15927
15957
  try {
15928
- return fs23.statSync(p);
15958
+ return fs24.statSync(p);
15929
15959
  } catch {
15930
15960
  return null;
15931
15961
  }
@@ -15937,7 +15967,7 @@ function computeBytes(p) {
15937
15967
  const cur = stack.pop();
15938
15968
  let st;
15939
15969
  try {
15940
- st = fs23.lstatSync(cur);
15970
+ st = fs24.lstatSync(cur);
15941
15971
  } catch {
15942
15972
  continue;
15943
15973
  }
@@ -15945,11 +15975,11 @@ function computeBytes(p) {
15945
15975
  if (st.isDirectory()) {
15946
15976
  let entries;
15947
15977
  try {
15948
- entries = fs23.readdirSync(cur);
15978
+ entries = fs24.readdirSync(cur);
15949
15979
  } catch {
15950
15980
  continue;
15951
15981
  }
15952
- for (const name of entries) stack.push(path26.join(cur, name));
15982
+ for (const name of entries) stack.push(path27.join(cur, name));
15953
15983
  } else {
15954
15984
  total += st.size;
15955
15985
  }
@@ -16157,7 +16187,7 @@ init_context();
16157
16187
  init_output();
16158
16188
  init_exit_codes();
16159
16189
  init_world_paths();
16160
- import * as fs24 from "node:fs";
16190
+ import * as fs25 from "node:fs";
16161
16191
  import "node:path";
16162
16192
  import ora6 from "ora";
16163
16193
  function registerCrystallize(program2, options = {}) {
@@ -16189,7 +16219,7 @@ function registerCrystallize(program2, options = {}) {
16189
16219
  return;
16190
16220
  }
16191
16221
  const thoughtDbPath = getWorldDbPath(world.workspacePath);
16192
- if (!fs24.existsSync(thoughtDbPath)) {
16222
+ if (!fs25.existsSync(thoughtDbPath)) {
16193
16223
  printError(`No thoughts captured yet for "${worldId}". Run a dispatch first.`);
16194
16224
  process.exitCode = EXIT_GENERIC_ERROR;
16195
16225
  return;
@@ -17563,11 +17593,11 @@ var qmarksTestNoExtDot = ([$0]) => {
17563
17593
  return (f) => f.length === len && f !== "." && f !== "..";
17564
17594
  };
17565
17595
  var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
17566
- var path28 = {
17596
+ var path29 = {
17567
17597
  win32: { sep: "\\" },
17568
17598
  posix: { sep: "/" }
17569
17599
  };
17570
- var sep = defaultPlatform === "win32" ? path28.win32.sep : path28.posix.sep;
17600
+ var sep = defaultPlatform === "win32" ? path29.win32.sep : path29.posix.sep;
17571
17601
  minimatch.sep = sep;
17572
17602
  var GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
17573
17603
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -18395,23 +18425,23 @@ function registerPolicyCheck(program2) {
18395
18425
  // src/commands/upgrade.ts
18396
18426
  init_output();
18397
18427
  init_host_cp();
18398
- import * as fs27 from "node:fs";
18399
- import * as path31 from "node:path";
18428
+ import * as fs28 from "node:fs";
18429
+ import * as path32 from "node:path";
18400
18430
  import { spawnSync as spawnSync11 } from "node:child_process";
18401
18431
  import ora7 from "ora";
18402
18432
  import pc17 from "picocolors";
18403
18433
 
18404
18434
  // src/commands/upgrade-lock.ts
18405
- import * as fs25 from "node:fs";
18435
+ import * as fs26 from "node:fs";
18406
18436
  import * as os15 from "node:os";
18407
- import * as path29 from "node:path";
18437
+ import * as path30 from "node:path";
18408
18438
  import { spawnSync as spawnSync10 } from "node:child_process";
18409
- var LOCK_FILE_PATH = path29.join(os15.homedir(), ".olam", ".upgrade.lock");
18439
+ var LOCK_FILE_PATH = path30.join(os15.homedir(), ".olam", ".upgrade.lock");
18410
18440
  var STALE_LOCK_TIMEOUT_MS = 5 * 60 * 1e3;
18411
18441
  function readLockFile(lockPath) {
18412
18442
  try {
18413
- if (!fs25.existsSync(lockPath)) return null;
18414
- const raw = fs25.readFileSync(lockPath, "utf-8").trim();
18443
+ if (!fs26.existsSync(lockPath)) return null;
18444
+ const raw = fs26.readFileSync(lockPath, "utf-8").trim();
18415
18445
  if (raw.length === 0) return null;
18416
18446
  const parsed = JSON.parse(raw);
18417
18447
  if (typeof parsed.pid !== "number" || typeof parsed.startTs !== "number") return null;
@@ -18456,16 +18486,16 @@ function isStaleLock(content, nowMs = Date.now()) {
18456
18486
  return false;
18457
18487
  }
18458
18488
  function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
18459
- const dir = path29.dirname(lockPath);
18460
- fs25.mkdirSync(dir, { recursive: true });
18489
+ const dir = path30.dirname(lockPath);
18490
+ fs26.mkdirSync(dir, { recursive: true });
18461
18491
  for (let attempt = 0; attempt < 2; attempt++) {
18462
18492
  try {
18463
- const fd = fs25.openSync(lockPath, "wx", 420);
18493
+ const fd = fs26.openSync(lockPath, "wx", 420);
18464
18494
  try {
18465
18495
  const content = { pid: process.pid, startTs: nowMs };
18466
- fs25.writeSync(fd, JSON.stringify(content));
18496
+ fs26.writeSync(fd, JSON.stringify(content));
18467
18497
  } finally {
18468
- fs25.closeSync(fd);
18498
+ fs26.closeSync(fd);
18469
18499
  }
18470
18500
  return { acquired: true, lockPath };
18471
18501
  } catch (err) {
@@ -18474,7 +18504,7 @@ function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
18474
18504
  const existing2 = readLockFile(lockPath);
18475
18505
  if (isStaleLock(existing2, nowMs)) {
18476
18506
  try {
18477
- fs25.unlinkSync(lockPath);
18507
+ fs26.unlinkSync(lockPath);
18478
18508
  } catch (unlinkErr) {
18479
18509
  const ucode = unlinkErr.code;
18480
18510
  if (ucode !== "ENOENT") throw unlinkErr;
@@ -18499,7 +18529,7 @@ function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
18499
18529
  }
18500
18530
  function releaseLock(lockPath = LOCK_FILE_PATH) {
18501
18531
  try {
18502
- fs25.unlinkSync(lockPath);
18532
+ fs26.unlinkSync(lockPath);
18503
18533
  } catch (err) {
18504
18534
  const code = err.code;
18505
18535
  if (code !== "ENOENT") throw err;
@@ -18517,19 +18547,19 @@ function formatRefusalMessage(result, lockPath = LOCK_FILE_PATH) {
18517
18547
  }
18518
18548
 
18519
18549
  // src/commands/upgrade-log.ts
18520
- import * as fs26 from "node:fs";
18550
+ import * as fs27 from "node:fs";
18521
18551
  import * as os16 from "node:os";
18522
- import * as path30 from "node:path";
18552
+ import * as path31 from "node:path";
18523
18553
  function getUpgradeLogPath() {
18524
18554
  const home = process.env["HOME"] ?? os16.homedir();
18525
- return path30.join(home, ".olam", "upgrade.log");
18555
+ return path31.join(home, ".olam", "upgrade.log");
18526
18556
  }
18527
18557
  var UPGRADE_LOG_PATH = getUpgradeLogPath();
18528
18558
  function appendUpgradeLog(row, logPath = getUpgradeLogPath()) {
18529
18559
  try {
18530
- fs26.mkdirSync(path30.dirname(logPath), { recursive: true });
18560
+ fs27.mkdirSync(path31.dirname(logPath), { recursive: true });
18531
18561
  const line = JSON.stringify(row) + "\n";
18532
- fs26.appendFileSync(logPath, line, { mode: 420 });
18562
+ fs27.appendFileSync(logPath, line, { mode: 420 });
18533
18563
  } catch (err) {
18534
18564
  process.stderr.write(
18535
18565
  `[upgrade-log] failed to append: ${err instanceof Error ? err.message : String(err)}
@@ -18538,10 +18568,10 @@ function appendUpgradeLog(row, logPath = getUpgradeLogPath()) {
18538
18568
  }
18539
18569
  }
18540
18570
  function readUpgradeLog(limit = 10, logPath = getUpgradeLogPath()) {
18541
- if (!fs26.existsSync(logPath)) return [];
18571
+ if (!fs27.existsSync(logPath)) return [];
18542
18572
  let raw;
18543
18573
  try {
18544
- raw = fs26.readFileSync(logPath, "utf-8");
18574
+ raw = fs27.readFileSync(logPath, "utf-8");
18545
18575
  } catch (err) {
18546
18576
  process.stderr.write(
18547
18577
  `[upgrade-log] failed to read: ${err instanceof Error ? err.message : String(err)}
@@ -18634,12 +18664,12 @@ init_protocol_version();
18634
18664
  init_install_root();
18635
18665
  var AUTH_HEALTH_URL2 = "http://127.0.0.1:9999/health";
18636
18666
  function isNodeModulesInSync(cwd) {
18637
- const lockPath = path31.join(cwd, "package-lock.json");
18638
- const markerPath = path31.join(cwd, "node_modules", ".package-lock.json");
18639
- if (!fs27.existsSync(lockPath) || !fs27.existsSync(markerPath)) return false;
18667
+ const lockPath = path32.join(cwd, "package-lock.json");
18668
+ const markerPath = path32.join(cwd, "node_modules", ".package-lock.json");
18669
+ if (!fs28.existsSync(lockPath) || !fs28.existsSync(markerPath)) return false;
18640
18670
  try {
18641
- const lockStat = fs27.statSync(lockPath);
18642
- const markerStat = fs27.statSync(markerPath);
18671
+ const lockStat = fs28.statSync(lockPath);
18672
+ const markerStat = fs28.statSync(markerPath);
18643
18673
  return markerStat.mtimeMs >= lockStat.mtimeMs;
18644
18674
  } catch {
18645
18675
  return false;
@@ -18655,8 +18685,8 @@ function shouldSkipInstall(opts, cwd) {
18655
18685
  return { skip: false };
18656
18686
  }
18657
18687
  function validateRepoRoot(cwd) {
18658
- const marker = path31.join(cwd, "packages/host-cp/compose.yaml");
18659
- if (!fs27.existsSync(marker)) {
18688
+ const marker = path32.join(cwd, "packages/host-cp/compose.yaml");
18689
+ if (!fs28.existsSync(marker)) {
18660
18690
  return {
18661
18691
  ok: false,
18662
18692
  error: `Not an olam repo root (expected ${marker}).
@@ -19012,9 +19042,9 @@ async function recreateAuthService() {
19012
19042
  }
19013
19043
  }
19014
19044
  function readBundleHash(cwd) {
19015
- const indexPath = path31.join(cwd, "packages/control-plane/public/index.html");
19016
- if (!fs27.existsSync(indexPath)) return null;
19017
- return extractBundleHash(fs27.readFileSync(indexPath, "utf-8"));
19045
+ const indexPath = path32.join(cwd, "packages/control-plane/public/index.html");
19046
+ if (!fs28.existsSync(indexPath)) return null;
19047
+ return extractBundleHash(fs28.readFileSync(indexPath, "utf-8"));
19018
19048
  }
19019
19049
  async function runUpgradePullByDigest(deps = {}) {
19020
19050
  const docker2 = deps.docker ?? realDocker;
@@ -19514,7 +19544,7 @@ ${buildResult.stderr}`);
19514
19544
  return;
19515
19545
  }
19516
19546
  const authSecret = readAuthSecret2();
19517
- const spaDir = path31.join(cwd, "packages/control-plane/app");
19547
+ const spaDir = path32.join(cwd, "packages/control-plane/app");
19518
19548
  const spaResult = runStep2(
19519
19549
  "vite build (SPA)",
19520
19550
  "npx",
@@ -20048,20 +20078,20 @@ ${pc19.dim(`world: ${worldId} sort: ${sortKey} refresh: 5s Ctrl-C to exit`)}
20048
20078
 
20049
20079
  // src/commands/keys.ts
20050
20080
  init_output();
20051
- import * as fs28 from "node:fs";
20081
+ import * as fs29 from "node:fs";
20052
20082
  import * as os17 from "node:os";
20053
- import * as path32 from "node:path";
20083
+ import * as path33 from "node:path";
20054
20084
  import YAML4 from "yaml";
20055
20085
  function olamHome2() {
20056
- return process.env.OLAM_HOME ?? path32.join(os17.homedir(), ".olam");
20086
+ return process.env.OLAM_HOME ?? path33.join(os17.homedir(), ".olam");
20057
20087
  }
20058
20088
  function keysFilePath() {
20059
- return path32.join(olamHome2(), "keys.yaml");
20089
+ return path33.join(olamHome2(), "keys.yaml");
20060
20090
  }
20061
20091
  function readKeysFile() {
20062
20092
  const filePath = keysFilePath();
20063
- if (!fs28.existsSync(filePath)) return null;
20064
- const raw = fs28.readFileSync(filePath, "utf-8").trim();
20093
+ if (!fs29.existsSync(filePath)) return null;
20094
+ const raw = fs29.readFileSync(filePath, "utf-8").trim();
20065
20095
  if (raw.length === 0) return null;
20066
20096
  try {
20067
20097
  const parsed = YAML4.parse(raw);
@@ -20077,13 +20107,13 @@ function readKeysFile() {
20077
20107
  }
20078
20108
  function writeKeysFile(keys) {
20079
20109
  const dir = olamHome2();
20080
- if (!fs28.existsSync(dir)) {
20081
- fs28.mkdirSync(dir, { recursive: true });
20110
+ if (!fs29.existsSync(dir)) {
20111
+ fs29.mkdirSync(dir, { recursive: true });
20082
20112
  }
20083
20113
  const filePath = keysFilePath();
20084
20114
  const content = YAML4.stringify(keys);
20085
- fs28.writeFileSync(filePath, content, { encoding: "utf-8", mode: 384 });
20086
- fs28.chmodSync(filePath, 384);
20115
+ fs29.writeFileSync(filePath, content, { encoding: "utf-8", mode: 384 });
20116
+ fs29.chmodSync(filePath, 384);
20087
20117
  }
20088
20118
  function redact(value) {
20089
20119
  if (value.length <= 8) return value + "...";
@@ -20126,7 +20156,7 @@ function registerKeys(program2) {
20126
20156
  }
20127
20157
  const { [key]: _removed, ...rest } = existing;
20128
20158
  if (Object.keys(rest).length === 0) {
20129
- fs28.unlinkSync(keysFilePath());
20159
+ fs29.unlinkSync(keysFilePath());
20130
20160
  } else {
20131
20161
  writeKeysFile(rest);
20132
20162
  }
@@ -20149,26 +20179,26 @@ function registerKeys(program2) {
20149
20179
  }
20150
20180
 
20151
20181
  // src/commands/world-snapshot.ts
20152
- import * as fs30 from "node:fs";
20153
- import * as path34 from "node:path";
20182
+ import * as fs31 from "node:fs";
20183
+ import * as path35 from "node:path";
20154
20184
  import { execSync as execSync9 } from "node:child_process";
20155
20185
  import pc20 from "picocolors";
20156
20186
 
20157
20187
  // ../core/dist/world/snapshot.js
20158
20188
  import * as crypto6 from "node:crypto";
20159
- import * as fs29 from "node:fs";
20189
+ import * as fs30 from "node:fs";
20160
20190
  import * as os18 from "node:os";
20161
- import * as path33 from "node:path";
20191
+ import * as path34 from "node:path";
20162
20192
  import { execFileSync as execFileSync6 } from "node:child_process";
20163
20193
  function snapshotsDir() {
20164
- return process.env["OLAM_SNAPSHOTS_DIR"] ?? path33.join(os18.homedir(), ".olam", "snapshots");
20194
+ return process.env["OLAM_SNAPSHOTS_DIR"] ?? path34.join(os18.homedir(), ".olam", "snapshots");
20165
20195
  }
20166
20196
  function snapshotKindDir(worldId, kind) {
20167
- return path33.join(snapshotsDir(), worldId, kind);
20197
+ return path34.join(snapshotsDir(), worldId, kind);
20168
20198
  }
20169
20199
  function snapshotTarPath(worldId, kind, repoName, hash) {
20170
20200
  const base = repoName ? `${repoName}-${hash}` : hash;
20171
- return path33.join(snapshotKindDir(worldId, kind), `${base}.tar.gz`);
20201
+ return path34.join(snapshotKindDir(worldId, kind), `${base}.tar.gz`);
20172
20202
  }
20173
20203
  function manifestPath(tarPath) {
20174
20204
  return tarPath.replace(/\.tar\.gz$/, ".manifest.json");
@@ -20185,17 +20215,17 @@ function hashBuffers(entries) {
20185
20215
  return hash.digest("hex").slice(0, 12);
20186
20216
  }
20187
20217
  function computeGemsFingerprint(repoDir) {
20188
- const lockfile = path33.join(repoDir, "Gemfile.lock");
20189
- if (!fs29.existsSync(lockfile))
20218
+ const lockfile = path34.join(repoDir, "Gemfile.lock");
20219
+ if (!fs30.existsSync(lockfile))
20190
20220
  return null;
20191
- return hashBuffers([{ path: "Gemfile.lock", content: fs29.readFileSync(lockfile) }]);
20221
+ return hashBuffers([{ path: "Gemfile.lock", content: fs30.readFileSync(lockfile) }]);
20192
20222
  }
20193
20223
  function computeNodeFingerprint(repoDir) {
20194
20224
  const candidates = ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"];
20195
20225
  for (const name of candidates) {
20196
- const lockfile = path33.join(repoDir, name);
20197
- if (fs29.existsSync(lockfile)) {
20198
- return hashBuffers([{ path: name, content: fs29.readFileSync(lockfile) }]);
20226
+ const lockfile = path34.join(repoDir, name);
20227
+ if (fs30.existsSync(lockfile)) {
20228
+ return hashBuffers([{ path: name, content: fs30.readFileSync(lockfile) }]);
20199
20229
  }
20200
20230
  }
20201
20231
  return null;
@@ -20205,16 +20235,16 @@ function computePgFingerprint(repoDirs) {
20205
20235
  const entries = [];
20206
20236
  for (const repoDir of repoDirs) {
20207
20237
  for (const pattern of patterns) {
20208
- const filePath = path33.join(repoDir, pattern);
20209
- if (fs29.existsSync(filePath)) {
20210
- entries.push({ path: filePath, content: fs29.readFileSync(filePath) });
20238
+ const filePath = path34.join(repoDir, pattern);
20239
+ if (fs30.existsSync(filePath)) {
20240
+ entries.push({ path: filePath, content: fs30.readFileSync(filePath) });
20211
20241
  }
20212
20242
  }
20213
20243
  }
20214
20244
  return entries.length > 0 ? hashBuffers(entries) : null;
20215
20245
  }
20216
20246
  function packTarball(srcDir, destPath, opts = {}) {
20217
- fs29.mkdirSync(path33.dirname(destPath), { recursive: true });
20247
+ fs30.mkdirSync(path34.dirname(destPath), { recursive: true });
20218
20248
  const tmp = `${destPath}.tmp`;
20219
20249
  const args = [];
20220
20250
  if (opts.followSymlinks)
@@ -20222,47 +20252,47 @@ function packTarball(srcDir, destPath, opts = {}) {
20222
20252
  args.push("-czf", tmp, "-C", srcDir, ".");
20223
20253
  try {
20224
20254
  execFileSync6("tar", args, { stdio: "pipe" });
20225
- fs29.renameSync(tmp, destPath);
20255
+ fs30.renameSync(tmp, destPath);
20226
20256
  } catch (err) {
20227
20257
  try {
20228
- fs29.rmSync(tmp, { force: true });
20258
+ fs30.rmSync(tmp, { force: true });
20229
20259
  } catch {
20230
20260
  }
20231
20261
  throw err;
20232
20262
  }
20233
20263
  }
20234
20264
  function writeManifest(manifest, tarPath) {
20235
- fs29.writeFileSync(manifestPath(tarPath), JSON.stringify(manifest, null, 2), "utf-8");
20265
+ fs30.writeFileSync(manifestPath(tarPath), JSON.stringify(manifest, null, 2), "utf-8");
20236
20266
  }
20237
20267
  function readManifest(tarPath) {
20238
20268
  const mPath = manifestPath(tarPath);
20239
- if (!fs29.existsSync(mPath))
20269
+ if (!fs30.existsSync(mPath))
20240
20270
  return null;
20241
20271
  try {
20242
- return JSON.parse(fs29.readFileSync(mPath, "utf-8"));
20272
+ return JSON.parse(fs30.readFileSync(mPath, "utf-8"));
20243
20273
  } catch {
20244
20274
  return null;
20245
20275
  }
20246
20276
  }
20247
20277
  function listSnapshots(worldIdFilter) {
20248
20278
  const root = snapshotsDir();
20249
- if (!fs29.existsSync(root))
20279
+ if (!fs30.existsSync(root))
20250
20280
  return [];
20251
20281
  const now = Date.now();
20252
20282
  const results = [];
20253
- const worlds = worldIdFilter ? [worldIdFilter] : fs29.readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
20283
+ const worlds = worldIdFilter ? [worldIdFilter] : fs30.readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
20254
20284
  for (const worldId of worlds) {
20255
- const worldDir = path33.join(root, worldId);
20256
- if (!fs29.existsSync(worldDir) || !fs29.statSync(worldDir).isDirectory())
20285
+ const worldDir = path34.join(root, worldId);
20286
+ if (!fs30.existsSync(worldDir) || !fs30.statSync(worldDir).isDirectory())
20257
20287
  continue;
20258
20288
  for (const kind of ["gems", "node", "pg"]) {
20259
- const kindDir = path33.join(worldDir, kind);
20260
- if (!fs29.existsSync(kindDir))
20289
+ const kindDir = path34.join(worldDir, kind);
20290
+ if (!fs30.existsSync(kindDir))
20261
20291
  continue;
20262
- const tarballs = fs29.readdirSync(kindDir).filter((f) => f.endsWith(".tar.gz"));
20292
+ const tarballs = fs30.readdirSync(kindDir).filter((f) => f.endsWith(".tar.gz"));
20263
20293
  for (const tarFile of tarballs) {
20264
- const tarPath = path33.join(kindDir, tarFile);
20265
- const stat = fs29.statSync(tarPath);
20294
+ const tarPath = path34.join(kindDir, tarFile);
20295
+ const stat = fs30.statSync(tarPath);
20266
20296
  const manifest = readManifest(tarPath);
20267
20297
  if (!manifest)
20268
20298
  continue;
@@ -20352,17 +20382,17 @@ function resolveKinds(arg) {
20352
20382
  return [];
20353
20383
  }
20354
20384
  async function captureGems(worldId, workspacePath, repo) {
20355
- const repoDir = path34.join(workspacePath, repo);
20385
+ const repoDir = path35.join(workspacePath, repo);
20356
20386
  const fingerprint = computeGemsFingerprint(repoDir);
20357
20387
  if (!fingerprint) {
20358
20388
  return { ok: false, tarPath: "", msg: "no Gemfile.lock \u2014 layer does not apply" };
20359
20389
  }
20360
20390
  const tarPath = snapshotTarPath(worldId, "gems", repo, fingerprint);
20361
- const vendorBundle = path34.join(repoDir, "vendor", "bundle");
20362
- if (fs30.existsSync(vendorBundle)) {
20391
+ const vendorBundle = path35.join(repoDir, "vendor", "bundle");
20392
+ if (fs31.existsSync(vendorBundle)) {
20363
20393
  try {
20364
20394
  packTarball(vendorBundle, tarPath);
20365
- const stat = fs30.statSync(tarPath);
20395
+ const stat = fs31.statSync(tarPath);
20366
20396
  const manifest = {
20367
20397
  kind: "gems",
20368
20398
  worldId,
@@ -20395,10 +20425,10 @@ async function captureGems(worldId, workspacePath, repo) {
20395
20425
  `docker exec ${containerName} sh -c 'mkdir -p "$(dirname ${tmpTar})" && tar -czf ${tmpTar}.tmp -C ${bundlePath} . && mv ${tmpTar}.tmp ${tmpTar}'`,
20396
20426
  { stdio: "pipe", timeout: 12e4 }
20397
20427
  );
20398
- fs30.mkdirSync(path34.dirname(tarPath), { recursive: true });
20428
+ fs31.mkdirSync(path35.dirname(tarPath), { recursive: true });
20399
20429
  execSync9(`docker cp ${containerName}:${tmpTar} "${tarPath}"`, { stdio: "pipe", timeout: 12e4 });
20400
20430
  execSync9(`docker exec ${containerName} rm -f ${tmpTar}`, { stdio: "pipe" });
20401
- const stat = fs30.statSync(tarPath);
20431
+ const stat = fs31.statSync(tarPath);
20402
20432
  const manifest = {
20403
20433
  kind: "gems",
20404
20434
  worldId,
@@ -20415,19 +20445,19 @@ async function captureGems(worldId, workspacePath, repo) {
20415
20445
  }
20416
20446
  }
20417
20447
  async function captureNode(worldId, workspacePath, repo) {
20418
- const repoDir = path34.join(workspacePath, repo);
20448
+ const repoDir = path35.join(workspacePath, repo);
20419
20449
  const fingerprint = computeNodeFingerprint(repoDir);
20420
20450
  if (!fingerprint) {
20421
20451
  return { ok: false, tarPath: "", msg: "no lockfile \u2014 layer does not apply" };
20422
20452
  }
20423
- const nodeModules = path34.join(repoDir, "node_modules");
20424
- if (!fs30.existsSync(nodeModules)) {
20453
+ const nodeModules = path35.join(repoDir, "node_modules");
20454
+ if (!fs31.existsSync(nodeModules)) {
20425
20455
  return { ok: false, tarPath: "", msg: "node_modules not installed yet" };
20426
20456
  }
20427
20457
  const tarPath = snapshotTarPath(worldId, "node", repo, fingerprint);
20428
20458
  try {
20429
20459
  packTarball(nodeModules, tarPath);
20430
- const stat = fs30.statSync(tarPath);
20460
+ const stat = fs31.statSync(tarPath);
20431
20461
  const manifest = {
20432
20462
  kind: "node",
20433
20463
  worldId,
@@ -20444,7 +20474,7 @@ async function captureNode(worldId, workspacePath, repo) {
20444
20474
  }
20445
20475
  }
20446
20476
  async function capturePg(worldId, workspacePath, repoNames) {
20447
- const repoDirs = repoNames.map((r) => path34.join(workspacePath, r));
20477
+ const repoDirs = repoNames.map((r) => path35.join(workspacePath, r));
20448
20478
  const fingerprint = computePgFingerprint(repoDirs);
20449
20479
  if (!fingerprint) {
20450
20480
  return { ok: false, tarPath: "", msg: "no Gemfile.lock / schema.rb \u2014 layer does not apply" };
@@ -20459,13 +20489,13 @@ async function capturePg(worldId, workspacePath, repoNames) {
20459
20489
  }
20460
20490
  try {
20461
20491
  execSync9(`docker stop ${containerName}`, { stdio: "pipe", timeout: 3e4 });
20462
- fs30.mkdirSync(path34.dirname(tarPath), { recursive: true });
20492
+ fs31.mkdirSync(path35.dirname(tarPath), { recursive: true });
20463
20493
  execSync9(
20464
- `docker run --rm -v "${volumeName2}:/pgdata:ro" -v "${path34.dirname(tarPath)}:/dest" alpine sh -c 'tar -czf /dest/${path34.basename(tarPath)}.tmp -C /pgdata . && mv /dest/${path34.basename(tarPath)}.tmp /dest/${path34.basename(tarPath)}'`,
20494
+ `docker run --rm -v "${volumeName2}:/pgdata:ro" -v "${path35.dirname(tarPath)}:/dest" alpine sh -c 'tar -czf /dest/${path35.basename(tarPath)}.tmp -C /pgdata . && mv /dest/${path35.basename(tarPath)}.tmp /dest/${path35.basename(tarPath)}'`,
20465
20495
  { stdio: "pipe", timeout: 18e4 }
20466
20496
  );
20467
20497
  execSync9(`docker start ${containerName}`, { stdio: "pipe", timeout: 3e4 });
20468
- const stat = fs30.statSync(tarPath);
20498
+ const stat = fs31.statSync(tarPath);
20469
20499
  const manifest = {
20470
20500
  kind: "pg",
20471
20501
  worldId,
@@ -20540,35 +20570,35 @@ function formatAge2(ms) {
20540
20570
  // src/commands/refresh.ts
20541
20571
  init_context();
20542
20572
  init_output();
20543
- import * as fs32 from "node:fs";
20573
+ import * as fs33 from "node:fs";
20544
20574
  import * as os19 from "node:os";
20545
- import * as path36 from "node:path";
20575
+ import * as path37 from "node:path";
20546
20576
  import { spawnSync as spawnSync13 } from "node:child_process";
20547
20577
  import ora8 from "ora";
20548
20578
 
20549
20579
  // src/commands/refresh-helpers.ts
20550
- import * as fs31 from "node:fs";
20551
- import * as path35 from "node:path";
20580
+ import * as fs32 from "node:fs";
20581
+ import * as path36 from "node:path";
20552
20582
  function collectCpSourceFiles(standaloneDir) {
20553
- if (!fs31.existsSync(standaloneDir)) {
20583
+ if (!fs32.existsSync(standaloneDir)) {
20554
20584
  throw new Error(`CP standalone dir not found: ${standaloneDir}`);
20555
20585
  }
20556
20586
  const entries = [];
20557
- const topLevel = fs31.readdirSync(standaloneDir).filter((f) => {
20558
- const stat = fs31.statSync(path35.join(standaloneDir, f));
20587
+ const topLevel = fs32.readdirSync(standaloneDir).filter((f) => {
20588
+ const stat = fs32.statSync(path36.join(standaloneDir, f));
20559
20589
  return stat.isFile() && f.endsWith(".mjs") && !f.endsWith(".test.mjs");
20560
20590
  }).sort();
20561
20591
  for (const f of topLevel) {
20562
- entries.push({ srcPath: path35.join(standaloneDir, f), destRelPath: f });
20592
+ entries.push({ srcPath: path36.join(standaloneDir, f), destRelPath: f });
20563
20593
  }
20564
- const libDir = path35.join(standaloneDir, "lib");
20565
- if (fs31.existsSync(libDir) && fs31.statSync(libDir).isDirectory()) {
20566
- const libFiles = fs31.readdirSync(libDir).filter((f) => {
20567
- const stat = fs31.statSync(path35.join(libDir, f));
20594
+ const libDir = path36.join(standaloneDir, "lib");
20595
+ if (fs32.existsSync(libDir) && fs32.statSync(libDir).isDirectory()) {
20596
+ const libFiles = fs32.readdirSync(libDir).filter((f) => {
20597
+ const stat = fs32.statSync(path36.join(libDir, f));
20568
20598
  return stat.isFile() && f.endsWith(".mjs") && !f.endsWith(".test.mjs");
20569
20599
  }).sort();
20570
20600
  for (const f of libFiles) {
20571
- entries.push({ srcPath: path35.join(libDir, f), destRelPath: `lib/${f}` });
20601
+ entries.push({ srcPath: path36.join(libDir, f), destRelPath: `lib/${f}` });
20572
20602
  }
20573
20603
  }
20574
20604
  return entries;
@@ -20626,16 +20656,16 @@ async function refreshWorld(worldId, portOffset, standaloneDir, opts) {
20626
20656
  error: err instanceof Error ? err.message : String(err)
20627
20657
  };
20628
20658
  }
20629
- const stagingDir = fs32.mkdtempSync(
20630
- path36.join(os19.tmpdir(), `olam-refresh-${worldId}-`)
20659
+ const stagingDir = fs33.mkdtempSync(
20660
+ path37.join(os19.tmpdir(), `olam-refresh-${worldId}-`)
20631
20661
  );
20632
20662
  try {
20633
20663
  const hasLib = entries.some((e) => e.destRelPath.startsWith("lib/"));
20634
20664
  if (hasLib) {
20635
- fs32.mkdirSync(path36.join(stagingDir, "lib"), { recursive: true });
20665
+ fs33.mkdirSync(path37.join(stagingDir, "lib"), { recursive: true });
20636
20666
  }
20637
20667
  for (const { srcPath, destRelPath } of entries) {
20638
- fs32.copyFileSync(srcPath, path36.join(stagingDir, destRelPath));
20668
+ fs33.copyFileSync(srcPath, path37.join(stagingDir, destRelPath));
20639
20669
  }
20640
20670
  const cpResult = docker([
20641
20671
  "cp",
@@ -20650,7 +20680,7 @@ async function refreshWorld(worldId, portOffset, standaloneDir, opts) {
20650
20680
  };
20651
20681
  }
20652
20682
  } finally {
20653
- fs32.rmSync(stagingDir, { recursive: true, force: true });
20683
+ fs33.rmSync(stagingDir, { recursive: true, force: true });
20654
20684
  }
20655
20685
  if (opts.restart) {
20656
20686
  const restartResult = docker([
@@ -20687,11 +20717,11 @@ function registerRefresh(program2) {
20687
20717
  process.exitCode = 1;
20688
20718
  return;
20689
20719
  }
20690
- const standaloneDir = path36.join(
20720
+ const standaloneDir = path37.join(
20691
20721
  process.cwd(),
20692
20722
  "packages/control-plane/standalone"
20693
20723
  );
20694
- if (!fs32.existsSync(standaloneDir)) {
20724
+ if (!fs33.existsSync(standaloneDir)) {
20695
20725
  printError(
20696
20726
  `CP standalone source not found at ${standaloneDir}.
20697
20727
  Run \`olam refresh\` from the olam repo root.`
@@ -20770,9 +20800,9 @@ Run \`olam refresh\` from the olam repo root.`
20770
20800
  }
20771
20801
 
20772
20802
  // src/commands/diagnose.ts
20773
- import * as fs33 from "node:fs";
20803
+ import * as fs34 from "node:fs";
20774
20804
  import * as os20 from "node:os";
20775
- import * as path37 from "node:path";
20805
+ import * as path38 from "node:path";
20776
20806
  import { execFileSync as execFileSync7, execSync as execSync10 } from "node:child_process";
20777
20807
  import pc21 from "picocolors";
20778
20808
 
@@ -20807,9 +20837,9 @@ function stripSecrets(input) {
20807
20837
  }
20808
20838
 
20809
20839
  // src/commands/diagnose.ts
20810
- var DIAGNOSTICS_DIR = path37.join(os20.homedir(), ".olam", "diagnostics");
20811
- var LOG_DIR = path37.join(os20.homedir(), ".olam", "log");
20812
- var CACHE_DIR = path37.join(os20.homedir(), ".olam", "cache");
20840
+ var DIAGNOSTICS_DIR = path38.join(os20.homedir(), ".olam", "diagnostics");
20841
+ var LOG_DIR = path38.join(os20.homedir(), ".olam", "log");
20842
+ var CACHE_DIR = path38.join(os20.homedir(), ".olam", "cache");
20813
20843
  var LOG_TAIL_LINES = 200;
20814
20844
  function safeExec(cmd) {
20815
20845
  try {
@@ -20823,10 +20853,10 @@ function defaultZip(zipPath, files) {
20823
20853
  }
20824
20854
  async function buildDiagnosticsZip(_exec = (cmd) => safeExec(cmd), _outDir = DIAGNOSTICS_DIR, _logDir = LOG_DIR, _zip = defaultZip) {
20825
20855
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 23);
20826
- const zipPath = path37.join(_outDir, `olam-diag-${ts}.zip`);
20827
- const tmpDir = fs33.mkdtempSync(path37.join(os20.tmpdir(), "olam-diag-"));
20856
+ const zipPath = path38.join(_outDir, `olam-diag-${ts}.zip`);
20857
+ const tmpDir = fs34.mkdtempSync(path38.join(os20.tmpdir(), "olam-diag-"));
20828
20858
  try {
20829
- fs33.mkdirSync(_outDir, { recursive: true });
20859
+ fs34.mkdirSync(_outDir, { recursive: true });
20830
20860
  const entries = [];
20831
20861
  const version = process.env["OLAM_CLI_VERSION"] ?? "unknown";
20832
20862
  const nodeVersion = process.version;
@@ -20842,14 +20872,14 @@ platform: ${platform}
20842
20872
  `uptime: ${os20.uptime()}s`
20843
20873
  ].join("\n") + "\n";
20844
20874
  _writeEntry(tmpDir, "os-info.txt", stripSecrets(osContent), entries);
20845
- const depsFile = path37.join(CACHE_DIR, "deps.json");
20846
- if (fs33.existsSync(depsFile)) {
20847
- const deps = fs33.readFileSync(depsFile, "utf-8");
20875
+ const depsFile = path38.join(CACHE_DIR, "deps.json");
20876
+ if (fs34.existsSync(depsFile)) {
20877
+ const deps = fs34.readFileSync(depsFile, "utf-8");
20848
20878
  _writeEntry(tmpDir, "deps.json", stripSecrets(deps), entries);
20849
20879
  }
20850
20880
  const latestLog = _latestLog(_logDir);
20851
20881
  if (latestLog) {
20852
- const lines = fs33.readFileSync(latestLog, "utf-8").split("\n");
20882
+ const lines = fs34.readFileSync(latestLog, "utf-8").split("\n");
20853
20883
  const tail = lines.slice(-LOG_TAIL_LINES).join("\n");
20854
20884
  _writeEntry(tmpDir, "log-tail.txt", stripSecrets(tail), entries);
20855
20885
  }
@@ -20861,38 +20891,38 @@ platform: ${platform}
20861
20891
  if (authAudit) {
20862
20892
  _writeEntry(tmpDir, "audit-auth-callers.txt", stripSecrets(authAudit), entries);
20863
20893
  }
20864
- const fileArgs = entries.map((e) => path37.join(tmpDir, e));
20894
+ const fileArgs = entries.map((e) => path38.join(tmpDir, e));
20865
20895
  try {
20866
20896
  _zip(zipPath, fileArgs);
20867
20897
  } catch (err) {
20868
20898
  throw new Error(`zip command produced no output file. zip stderr: ${err.message}`);
20869
20899
  }
20870
- if (!fs33.existsSync(zipPath)) {
20900
+ if (!fs34.existsSync(zipPath)) {
20871
20901
  throw new Error("zip command produced no output file.");
20872
20902
  }
20873
20903
  return { zipPath, entries };
20874
20904
  } finally {
20875
20905
  try {
20876
- fs33.rmSync(tmpDir, { recursive: true, force: true });
20906
+ fs34.rmSync(tmpDir, { recursive: true, force: true });
20877
20907
  } catch {
20878
20908
  }
20879
20909
  }
20880
20910
  }
20881
20911
  function _writeEntry(dir, name, content, entries) {
20882
- fs33.writeFileSync(path37.join(dir, name), content, { mode: 420 });
20912
+ fs34.writeFileSync(path38.join(dir, name), content, { mode: 420 });
20883
20913
  entries.push(name);
20884
20914
  }
20885
20915
  function _latestLog(logDir) {
20886
- if (!fs33.existsSync(logDir)) return null;
20887
- const files = fs33.readdirSync(logDir).filter((f) => f.startsWith("host-")).sort().reverse();
20888
- return files.length > 0 ? path37.join(logDir, files[0]) : null;
20916
+ if (!fs34.existsSync(logDir)) return null;
20917
+ const files = fs34.readdirSync(logDir).filter((f) => f.startsWith("host-")).sort().reverse();
20918
+ return files.length > 0 ? path38.join(logDir, files[0]) : null;
20889
20919
  }
20890
20920
  async function buildTelemetryPayload() {
20891
20921
  const channel = "stable";
20892
- const manifestFile = path37.join(CACHE_DIR, "manifest.json");
20922
+ const manifestFile = path38.join(CACHE_DIR, "manifest.json");
20893
20923
  let manifestAgeHours = null;
20894
- if (fs33.existsSync(manifestFile)) {
20895
- const mtime = fs33.statSync(manifestFile).mtime.getTime();
20924
+ if (fs34.existsSync(manifestFile)) {
20925
+ const mtime = fs34.statSync(manifestFile).mtime.getTime();
20896
20926
  manifestAgeHours = Math.round((Date.now() - mtime) / 36e5);
20897
20927
  }
20898
20928
  return {
@@ -20935,24 +20965,24 @@ function registerDiagnose(program2) {
20935
20965
  }
20936
20966
 
20937
20967
  // src/commands/update.ts
20938
- import * as fs36 from "node:fs";
20968
+ import * as fs37 from "node:fs";
20939
20969
  import * as os22 from "node:os";
20940
- import * as path40 from "node:path";
20970
+ import * as path41 from "node:path";
20941
20971
  import { execSync as execSync11 } from "node:child_process";
20942
20972
  import pc22 from "picocolors";
20943
20973
 
20944
20974
  // src/lib/symlink-reconcile.ts
20945
- import * as fs34 from "node:fs";
20946
- import * as path38 from "node:path";
20975
+ import * as fs35 from "node:fs";
20976
+ import * as path39 from "node:path";
20947
20977
  var realFs = {
20948
- readdirSync: (p) => fs34.readdirSync(p),
20949
- existsSync: (p) => fs34.existsSync(p),
20950
- lstatSync: (p) => fs34.lstatSync(p),
20951
- readlinkSync: (p) => fs34.readlinkSync(p),
20952
- symlinkSync: (t, l) => fs34.symlinkSync(t, l),
20953
- unlinkSync: (p) => fs34.unlinkSync(p),
20978
+ readdirSync: (p) => fs35.readdirSync(p),
20979
+ existsSync: (p) => fs35.existsSync(p),
20980
+ lstatSync: (p) => fs35.lstatSync(p),
20981
+ readlinkSync: (p) => fs35.readlinkSync(p),
20982
+ symlinkSync: (t, l) => fs35.symlinkSync(t, l),
20983
+ unlinkSync: (p) => fs35.unlinkSync(p),
20954
20984
  mkdirSync: (p, o) => {
20955
- fs34.mkdirSync(p, o);
20985
+ fs35.mkdirSync(p, o);
20956
20986
  }
20957
20987
  };
20958
20988
  function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
@@ -20962,8 +20992,8 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
20962
20992
  _fs.mkdirSync(claudeSkillsDir, { recursive: true });
20963
20993
  const sourceSkills = _fs.existsSync(npmSkillsDir) ? _fs.readdirSync(npmSkillsDir).filter((d) => d.startsWith("olam-")) : [];
20964
20994
  for (const skill of sourceSkills) {
20965
- const linkPath = path38.join(claudeSkillsDir, skill);
20966
- const target = path38.join(npmSkillsDir, skill);
20995
+ const linkPath = path39.join(claudeSkillsDir, skill);
20996
+ const target = path39.join(npmSkillsDir, skill);
20967
20997
  if (!_fs.existsSync(linkPath)) {
20968
20998
  try {
20969
20999
  _fs.symlinkSync(target, linkPath);
@@ -20976,7 +21006,7 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
20976
21006
  }
20977
21007
  const deployedEntries = _fs.existsSync(claudeSkillsDir) ? _fs.readdirSync(claudeSkillsDir).filter((d) => d.startsWith("olam-")) : [];
20978
21008
  for (const entry of deployedEntries) {
20979
- const linkPath = path38.join(claudeSkillsDir, entry);
21009
+ const linkPath = path39.join(claudeSkillsDir, entry);
20980
21010
  let isSymlink = false;
20981
21011
  try {
20982
21012
  isSymlink = _fs.lstatSync(linkPath).isSymbolicLink();
@@ -21001,9 +21031,9 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
21001
21031
 
21002
21032
  // src/commands/update.ts
21003
21033
  var PACKAGE_NAME = "@pleri/olam-cli";
21004
- var CACHE_DIR2 = path40.join(os22.homedir(), ".olam", "cache");
21005
- var LOG_DIR2 = path40.join(os22.homedir(), ".olam", "log");
21006
- var LAST_STABLE_FILE = path40.join(CACHE_DIR2, "last-stable.txt");
21034
+ var CACHE_DIR2 = path41.join(os22.homedir(), ".olam", "cache");
21035
+ var LOG_DIR2 = path41.join(os22.homedir(), ".olam", "log");
21036
+ var LAST_STABLE_FILE = path41.join(CACHE_DIR2, "last-stable.txt");
21007
21037
  function defaultExec(cmd) {
21008
21038
  try {
21009
21039
  const stdout = execSync11(cmd, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
@@ -21025,22 +21055,22 @@ function getCurrentVersion(_exec = defaultExec) {
21025
21055
  }
21026
21056
  function readLastStable(file = LAST_STABLE_FILE) {
21027
21057
  try {
21028
- const v = fs36.readFileSync(file, "utf-8").trim();
21058
+ const v = fs37.readFileSync(file, "utf-8").trim();
21029
21059
  return v || null;
21030
21060
  } catch {
21031
21061
  return null;
21032
21062
  }
21033
21063
  }
21034
21064
  function writeLastStable(version, file = LAST_STABLE_FILE) {
21035
- fs36.mkdirSync(path40.dirname(file), { recursive: true });
21036
- fs36.writeFileSync(file, version, { mode: 420 });
21065
+ fs37.mkdirSync(path41.dirname(file), { recursive: true });
21066
+ fs37.writeFileSync(file, version, { mode: 420 });
21037
21067
  }
21038
21068
  function logUpdateFailure(stderr) {
21039
21069
  const ts = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
21040
- const logFile = path40.join(LOG_DIR2, `update-${ts}.log`);
21070
+ const logFile = path41.join(LOG_DIR2, `update-${ts}.log`);
21041
21071
  try {
21042
- fs36.mkdirSync(LOG_DIR2, { recursive: true });
21043
- fs36.appendFileSync(logFile, `[update-failure ${(/* @__PURE__ */ new Date()).toISOString()}]
21072
+ fs37.mkdirSync(LOG_DIR2, { recursive: true });
21073
+ fs37.appendFileSync(logFile, `[update-failure ${(/* @__PURE__ */ new Date()).toISOString()}]
21044
21074
  ${stderr}
21045
21075
  `, "utf-8");
21046
21076
  } catch {
@@ -21127,8 +21157,8 @@ async function doUpdate(opts, _exec = defaultExec, _reconcile = reconcileSkillSy
21127
21157
  let symlinkResult = { added: [], removed: [] };
21128
21158
  if (npmRootResult.exitCode === 0) {
21129
21159
  const npmRoot = npmRootResult.stdout.trim();
21130
- const npmSkillsDir = path40.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills");
21131
- const claudeSkillsDir = path40.join(os22.homedir(), ".claude", "skills");
21160
+ const npmSkillsDir = path41.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills");
21161
+ const claudeSkillsDir = path41.join(os22.homedir(), ".claude", "skills");
21132
21162
  const rec = _reconcile(npmSkillsDir, claudeSkillsDir);
21133
21163
  symlinkResult = { added: rec.added, removed: rec.removed };
21134
21164
  if (!quiet && (rec.added.length > 0 || rec.removed.length > 0)) {
@@ -21174,8 +21204,8 @@ async function doRollback(_exec = defaultExec, _reconcile = reconcileSkillSymlin
21174
21204
  if (npmRootResult.exitCode === 0) {
21175
21205
  const npmRoot = npmRootResult.stdout.trim();
21176
21206
  _reconcile(
21177
- path40.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills"),
21178
- path40.join(os22.homedir(), ".claude", "skills")
21207
+ path41.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills"),
21208
+ path41.join(os22.homedir(), ".claude", "skills")
21179
21209
  );
21180
21210
  }
21181
21211
  return { action: "rolled-back", restoredVersion: prev, exitCode: 0 };
@@ -21256,7 +21286,7 @@ function registerBegin(program2) {
21256
21286
  }
21257
21287
 
21258
21288
  // src/commands/config.ts
21259
- import * as fs39 from "node:fs";
21289
+ import * as fs40 from "node:fs";
21260
21290
  import { createRequire as createRequire3 } from "node:module";
21261
21291
 
21262
21292
  // ../core/dist/global-config/schema.js
@@ -21333,9 +21363,9 @@ var DEFAULT_GLOBAL_CONFIG = {
21333
21363
  };
21334
21364
 
21335
21365
  // ../core/dist/global-config/store.js
21336
- import * as fs37 from "node:fs";
21366
+ import * as fs38 from "node:fs";
21337
21367
  import * as os23 from "node:os";
21338
- import * as path41 from "node:path";
21368
+ import * as path42 from "node:path";
21339
21369
  var GlobalConfigReadError = class extends Error {
21340
21370
  constructor(configPath, cause) {
21341
21371
  const msg = cause instanceof Error ? cause.message : String(cause);
@@ -21348,16 +21378,16 @@ function globalConfigPath() {
21348
21378
  const override = process.env["OLAM_GLOBAL_CONFIG_PATH"];
21349
21379
  if (override && override.length > 0)
21350
21380
  return override;
21351
- return path41.join(os23.homedir(), ".olam", "config.json");
21381
+ return path42.join(os23.homedir(), ".olam", "config.json");
21352
21382
  }
21353
21383
  function readGlobalConfig() {
21354
21384
  const configPath = globalConfigPath();
21355
- if (!fs37.existsSync(configPath)) {
21385
+ if (!fs38.existsSync(configPath)) {
21356
21386
  return { ...DEFAULT_GLOBAL_CONFIG };
21357
21387
  }
21358
21388
  let raw;
21359
21389
  try {
21360
- raw = fs37.readFileSync(configPath, "utf-8");
21390
+ raw = fs38.readFileSync(configPath, "utf-8");
21361
21391
  } catch (err) {
21362
21392
  throw new GlobalConfigReadError(configPath, err);
21363
21393
  }
@@ -21376,20 +21406,20 @@ function readGlobalConfig() {
21376
21406
  function writeGlobalConfig(config) {
21377
21407
  const configPath = globalConfigPath();
21378
21408
  const validated = GlobalConfigSchema.parse(config);
21379
- const dir = path41.dirname(configPath);
21380
- fs37.mkdirSync(dir, { recursive: true });
21409
+ const dir = path42.dirname(configPath);
21410
+ fs38.mkdirSync(dir, { recursive: true });
21381
21411
  const tmp = `${configPath}.tmp-${process.pid}`;
21382
- fs37.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
21383
- fs37.renameSync(tmp, configPath);
21412
+ fs38.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
21413
+ fs38.renameSync(tmp, configPath);
21384
21414
  }
21385
21415
 
21386
21416
  // ../core/dist/global-config/repos.js
21387
- import * as fs38 from "node:fs";
21417
+ import * as fs39 from "node:fs";
21388
21418
  import * as os24 from "node:os";
21389
- import * as path42 from "node:path";
21419
+ import * as path43 from "node:path";
21390
21420
  function expandPath(p) {
21391
21421
  if (p === "~" || p.startsWith("~/")) {
21392
- return path42.join(os24.homedir(), p.slice(1));
21422
+ return path43.join(os24.homedir(), p.slice(1));
21393
21423
  }
21394
21424
  return p;
21395
21425
  }
@@ -21402,7 +21432,7 @@ function addRepo(entry) {
21402
21432
  throw new Error(`repo "${entry.name}" already registered. Use "olam repos update" to change its path.`);
21403
21433
  }
21404
21434
  const resolvedPath = expandPath(entry.path);
21405
- if (!fs38.existsSync(resolvedPath)) {
21435
+ if (!fs39.existsSync(resolvedPath)) {
21406
21436
  throw new Error(`path "${entry.path}" does not exist. Verify the path is correct.`);
21407
21437
  }
21408
21438
  const now = Date.now();
@@ -21431,7 +21461,7 @@ function updateRepo(name, updates) {
21431
21461
  throw new Error(`repo "${name}" is not registered. Run "olam repos list" to see registered repos.`);
21432
21462
  }
21433
21463
  const resolvedUpdatePath = updates.path !== void 0 ? expandPath(updates.path) : void 0;
21434
- if (resolvedUpdatePath !== void 0 && !fs38.existsSync(resolvedUpdatePath)) {
21464
+ if (resolvedUpdatePath !== void 0 && !fs39.existsSync(resolvedUpdatePath)) {
21435
21465
  throw new Error(`path "${updates.path}" does not exist. Verify the path is correct.`);
21436
21466
  }
21437
21467
  const existing = config.repos[idx];
@@ -21455,14 +21485,14 @@ function registerConfig(program2) {
21455
21485
  const config = program2.command("config").description("Manage global olam configuration");
21456
21486
  config.command("validate [path]").description("Validate ~/.olam/config.json (or a custom path) against the schema").action((filePath) => {
21457
21487
  const resolvedPath = filePath ?? globalConfigPath();
21458
- if (!fs39.existsSync(resolvedPath)) {
21488
+ if (!fs40.existsSync(resolvedPath)) {
21459
21489
  process.stderr.write(`config file not found: ${resolvedPath}
21460
21490
  `);
21461
21491
  process.exit(1);
21462
21492
  }
21463
21493
  let raw;
21464
21494
  try {
21465
- raw = fs39.readFileSync(resolvedPath, "utf-8");
21495
+ raw = fs40.readFileSync(resolvedPath, "utf-8");
21466
21496
  } catch (err) {
21467
21497
  const msg = err instanceof Error ? err.message : String(err);
21468
21498
  process.stderr.write(`cannot read ${resolvedPath}: ${msg}
@@ -21899,12 +21929,12 @@ import * as readline3 from "node:readline";
21899
21929
  import pc27 from "picocolors";
21900
21930
 
21901
21931
  // src/commands/mcp/import-discovery.ts
21902
- import * as fs40 from "node:fs";
21932
+ import * as fs41 from "node:fs";
21903
21933
  import * as os25 from "node:os";
21904
- import * as path43 from "node:path";
21934
+ import * as path44 from "node:path";
21905
21935
  function readJsonFile(filePath) {
21906
21936
  try {
21907
- const raw = fs40.readFileSync(filePath, "utf-8");
21937
+ const raw = fs41.readFileSync(filePath, "utf-8");
21908
21938
  return JSON.parse(raw);
21909
21939
  } catch {
21910
21940
  return null;
@@ -21933,24 +21963,24 @@ function extractMcpServers(obj, source, sourceLabel) {
21933
21963
  }
21934
21964
  function getClaudeDesktopPath() {
21935
21965
  if (process.platform === "darwin") {
21936
- return path43.join(os25.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
21966
+ return path44.join(os25.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
21937
21967
  }
21938
21968
  if (process.platform === "win32") {
21939
- const appData = process.env["APPDATA"] ?? path43.join(os25.homedir(), "AppData", "Roaming");
21940
- return path43.join(appData, "Claude", "claude_desktop_config.json");
21969
+ const appData = process.env["APPDATA"] ?? path44.join(os25.homedir(), "AppData", "Roaming");
21970
+ return path44.join(appData, "Claude", "claude_desktop_config.json");
21941
21971
  }
21942
- return path43.join(os25.homedir(), ".config", "Claude", "claude_desktop_config.json");
21972
+ return path44.join(os25.homedir(), ".config", "Claude", "claude_desktop_config.json");
21943
21973
  }
21944
21974
  function getOlamRepoPaths() {
21945
21975
  const configPaths = [
21946
- path43.join(os25.homedir(), ".olam", "config.yaml"),
21947
- path43.join(process.cwd(), ".olam", "config.yaml")
21976
+ path44.join(os25.homedir(), ".olam", "config.yaml"),
21977
+ path44.join(process.cwd(), ".olam", "config.yaml")
21948
21978
  ];
21949
21979
  const paths = [];
21950
21980
  for (const configPath of configPaths) {
21951
- if (!fs40.existsSync(configPath)) continue;
21981
+ if (!fs41.existsSync(configPath)) continue;
21952
21982
  try {
21953
- const raw = fs40.readFileSync(configPath, "utf-8");
21983
+ const raw = fs41.readFileSync(configPath, "utf-8");
21954
21984
  const repoMatches = [...raw.matchAll(/path:\s*["']?([^\s"'\n]+)/g)];
21955
21985
  for (const m of repoMatches) {
21956
21986
  if (m[1]) paths.push(m[1]);
@@ -21966,7 +21996,7 @@ async function discoverMcpSources(repoPaths) {
21966
21996
  const sources = [];
21967
21997
  const sourceDefs = [
21968
21998
  {
21969
- path: path43.join(os25.homedir(), ".claude.json"),
21999
+ path: path44.join(os25.homedir(), ".claude.json"),
21970
22000
  label: "Claude Code (~/.claude.json)"
21971
22001
  },
21972
22002
  {
@@ -21974,19 +22004,19 @@ async function discoverMcpSources(repoPaths) {
21974
22004
  label: "Claude Desktop"
21975
22005
  },
21976
22006
  {
21977
- path: path43.join(os25.homedir(), ".cursor", "mcp.json"),
22007
+ path: path44.join(os25.homedir(), ".cursor", "mcp.json"),
21978
22008
  label: "Cursor (~/.cursor/mcp.json)"
21979
22009
  },
21980
22010
  {
21981
- path: path43.join(os25.homedir(), ".codeium", "windsurf", "mcp_config.json"),
22011
+ path: path44.join(os25.homedir(), ".codeium", "windsurf", "mcp_config.json"),
21982
22012
  label: "Windsurf (~/.codeium/windsurf/mcp_config.json)"
21983
22013
  }
21984
22014
  ];
21985
22015
  const resolvedRepoPaths = repoPaths ?? getOlamRepoPaths();
21986
22016
  for (const repoPath of resolvedRepoPaths) {
21987
22017
  sourceDefs.push({
21988
- path: path43.join(repoPath, ".mcp.json"),
21989
- label: `.mcp.json (${path43.basename(repoPath)})`
22018
+ path: path44.join(repoPath, ".mcp.json"),
22019
+ label: `.mcp.json (${path44.basename(repoPath)})`
21990
22020
  });
21991
22021
  }
21992
22022
  const reads = await Promise.all(
@@ -22216,18 +22246,18 @@ function registerMcp(program2) {
22216
22246
  }
22217
22247
 
22218
22248
  // src/pleri-config.ts
22219
- import * as fs41 from "node:fs";
22220
- import * as path44 from "node:path";
22249
+ import * as fs42 from "node:fs";
22250
+ import * as path45 from "node:path";
22221
22251
  function isPleriConfigured(configDir = process.env.OLAM_CONFIG_DIR ?? ".olam") {
22222
22252
  if (process.env.PLERI_BASE_URL) {
22223
22253
  return true;
22224
22254
  }
22225
- const configPath = path44.join(configDir, "config.yaml");
22226
- if (!fs41.existsSync(configPath)) {
22255
+ const configPath = path45.join(configDir, "config.yaml");
22256
+ if (!fs42.existsSync(configPath)) {
22227
22257
  return false;
22228
22258
  }
22229
22259
  try {
22230
- const contents = fs41.readFileSync(configPath, "utf8");
22260
+ const contents = fs42.readFileSync(configPath, "utf8");
22231
22261
  return /^[^#\n]*\bpleri:/m.test(contents);
22232
22262
  } catch {
22233
22263
  return false;
@@ -22236,23 +22266,6 @@ function isPleriConfigured(configDir = process.env.OLAM_CONFIG_DIR ?? ".olam") {
22236
22266
 
22237
22267
  // src/index.ts
22238
22268
  var program = new Command();
22239
- function readCliVersion() {
22240
- try {
22241
- const here = path45.dirname(fileURLToPath4(import.meta.url));
22242
- for (const candidate of [
22243
- path45.join(here, "package.json"),
22244
- path45.join(here, "..", "package.json"),
22245
- path45.join(here, "..", "..", "package.json")
22246
- ]) {
22247
- if (fs42.existsSync(candidate)) {
22248
- const pkg = JSON.parse(fs42.readFileSync(candidate, "utf-8"));
22249
- if (typeof pkg.version === "string" && pkg.version.length > 0) return pkg.version;
22250
- }
22251
- }
22252
- } catch {
22253
- }
22254
- return "0.0.0-unknown";
22255
- }
22256
22269
  program.name("olam").description("Olam \u2014 isolated development worlds with thought graph capture").version(readCliVersion());
22257
22270
  registerInit(program);
22258
22271
  registerInstall(program);