@pleri/olam-cli 0.1.74 → 0.1.76
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/image-digests.json +3 -3
- package/dist/index.js +285 -219
- package/dist/mcp-server.js +168 -111
- package/host-cp/src/plan-orchestrator.mjs +12 -10
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -6791,12 +6791,12 @@ var require_dist = __commonJS({
|
|
|
6791
6791
|
throw new Error(`Unknown format "${name}"`);
|
|
6792
6792
|
return f;
|
|
6793
6793
|
};
|
|
6794
|
-
function addFormats(ajv, list,
|
|
6794
|
+
function addFormats(ajv, list, fs24, exportName) {
|
|
6795
6795
|
var _a;
|
|
6796
6796
|
var _b;
|
|
6797
6797
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
6798
6798
|
for (const f of list)
|
|
6799
|
-
ajv.addFormat(f,
|
|
6799
|
+
ajv.addFormat(f, fs24[f]);
|
|
6800
6800
|
}
|
|
6801
6801
|
module.exports = exports = formatsPlugin;
|
|
6802
6802
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -22191,12 +22191,12 @@ function register3(server, _ctx, _initError) {
|
|
|
22191
22191
|
registry2.close();
|
|
22192
22192
|
}
|
|
22193
22193
|
try {
|
|
22194
|
-
const { default:
|
|
22194
|
+
const { default: fs24 } = await import("node:fs");
|
|
22195
22195
|
const { default: os15 } = await import("node:os");
|
|
22196
22196
|
const { default: path27 } = await import("node:path");
|
|
22197
22197
|
const tokenPath = path27.join(os15.homedir(), ".olam", "host-cp.token");
|
|
22198
|
-
if (
|
|
22199
|
-
const token =
|
|
22198
|
+
if (fs24.existsSync(tokenPath)) {
|
|
22199
|
+
const token = fs24.readFileSync(tokenPath, "utf-8").trim();
|
|
22200
22200
|
await fetch("http://127.0.0.1:19000/api/admin/world-pr", {
|
|
22201
22201
|
method: "POST",
|
|
22202
22202
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
@@ -27938,12 +27938,12 @@ function openUrl(url) {
|
|
|
27938
27938
|
var HOST_CP_URL = "http://127.0.0.1:19000";
|
|
27939
27939
|
async function readHostCpToken2() {
|
|
27940
27940
|
try {
|
|
27941
|
-
const { default:
|
|
27941
|
+
const { default: fs24 } = await import("node:fs");
|
|
27942
27942
|
const { default: os15 } = await import("node:os");
|
|
27943
27943
|
const { default: path27 } = await import("node:path");
|
|
27944
27944
|
const tp = path27.join(os15.homedir(), ".olam", "host-cp.token");
|
|
27945
|
-
if (!
|
|
27946
|
-
return { token:
|
|
27945
|
+
if (!fs24.existsSync(tp)) return { token: null };
|
|
27946
|
+
return { token: fs24.readFileSync(tp, "utf-8").trim() };
|
|
27947
27947
|
} catch {
|
|
27948
27948
|
return { token: null };
|
|
27949
27949
|
}
|
|
@@ -28187,6 +28187,7 @@ var RepoEntrySchema = external_exports.object({
|
|
|
28187
28187
|
path: external_exports.string().min(1, "path must not be empty").refine(isAbsoluteOrTilde, {
|
|
28188
28188
|
message: `path must be absolute (e.g. "/home/user/atlas-core") or "~/..." for the operator's home directory`
|
|
28189
28189
|
}).refine(hasNoTraversalComponents, { message: 'path must not contain ".." components' }),
|
|
28190
|
+
url: external_exports.string().min(1, "url must not be empty").optional(),
|
|
28190
28191
|
description: external_exports.string().optional(),
|
|
28191
28192
|
defaultBranch: external_exports.string().optional(),
|
|
28192
28193
|
addedAt: external_exports.number().int().nonnegative(),
|
|
@@ -28524,6 +28525,38 @@ function validateRunbookPorts(runbook, deps) {
|
|
|
28524
28525
|
return { conflicts };
|
|
28525
28526
|
}
|
|
28526
28527
|
|
|
28528
|
+
// ../core/dist/global-config/bridge.js
|
|
28529
|
+
import * as fs10 from "node:fs";
|
|
28530
|
+
function repoEntryToRepoConfig(entry) {
|
|
28531
|
+
if (!entry.url) {
|
|
28532
|
+
throw new Error(`Repo "${entry.name}" has no url. Re-register:
|
|
28533
|
+
olam repos remove ${entry.name}
|
|
28534
|
+
olam repos add ${entry.name} --path ${entry.path}`);
|
|
28535
|
+
}
|
|
28536
|
+
const repoPath = resolveTildePath(entry.path);
|
|
28537
|
+
if (!fs10.existsSync(repoPath)) {
|
|
28538
|
+
throw new Error(`Repo "${entry.name}" path "${repoPath}" no longer exists. Run: olam repos update ${entry.name} --path <new-path>`);
|
|
28539
|
+
}
|
|
28540
|
+
let manifest = null;
|
|
28541
|
+
try {
|
|
28542
|
+
manifest = loadRepoManifest(repoPath);
|
|
28543
|
+
} catch {
|
|
28544
|
+
}
|
|
28545
|
+
const config2 = {
|
|
28546
|
+
name: entry.name,
|
|
28547
|
+
url: entry.url,
|
|
28548
|
+
// RepoEntry has no type field; generic is the safe universal default.
|
|
28549
|
+
// Operators needing non-generic type behavior should declare the repo in local config.
|
|
28550
|
+
type: "generic",
|
|
28551
|
+
path: repoPath,
|
|
28552
|
+
submodules: false,
|
|
28553
|
+
services: [],
|
|
28554
|
+
setup_commands: [],
|
|
28555
|
+
...manifest !== null ? { manifest } : {}
|
|
28556
|
+
};
|
|
28557
|
+
return config2;
|
|
28558
|
+
}
|
|
28559
|
+
|
|
28527
28560
|
// ../mcp-server/src/tools/repo.ts
|
|
28528
28561
|
function asMessage4(err) {
|
|
28529
28562
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -28617,7 +28650,7 @@ __export(process_port_exports, {
|
|
|
28617
28650
|
register: () => register23,
|
|
28618
28651
|
resolveHostCpToken: () => resolveHostCpToken
|
|
28619
28652
|
});
|
|
28620
|
-
import
|
|
28653
|
+
import fs11 from "node:fs";
|
|
28621
28654
|
import os9 from "node:os";
|
|
28622
28655
|
import path14 from "node:path";
|
|
28623
28656
|
var HOST_CP_BASE = "http://127.0.0.1:19000";
|
|
@@ -28625,7 +28658,7 @@ function resolveHostCpToken() {
|
|
|
28625
28658
|
const envToken = process.env["OLAM_HOST_CP_TOKEN"];
|
|
28626
28659
|
if (envToken) return envToken;
|
|
28627
28660
|
const tokenPath = path14.join(os9.homedir(), ".olam", "host-cp.token");
|
|
28628
|
-
if (
|
|
28661
|
+
if (fs11.existsSync(tokenPath)) return fs11.readFileSync(tokenPath, "utf-8").trim();
|
|
28629
28662
|
return null;
|
|
28630
28663
|
}
|
|
28631
28664
|
function tokenMissingError() {
|
|
@@ -28961,7 +28994,7 @@ function createServer4(ctx, initError) {
|
|
|
28961
28994
|
}
|
|
28962
28995
|
|
|
28963
28996
|
// ../core/dist/config/loader.js
|
|
28964
|
-
import * as
|
|
28997
|
+
import * as fs13 from "node:fs";
|
|
28965
28998
|
import * as path15 from "node:path";
|
|
28966
28999
|
import { parse as parseYaml2 } from "yaml";
|
|
28967
29000
|
|
|
@@ -29342,11 +29375,11 @@ function substituteEnvVars(obj) {
|
|
|
29342
29375
|
}
|
|
29343
29376
|
|
|
29344
29377
|
// ../core/dist/config/dotenv.js
|
|
29345
|
-
import * as
|
|
29378
|
+
import * as fs12 from "node:fs";
|
|
29346
29379
|
function loadDotEnv(envPath) {
|
|
29347
|
-
if (!
|
|
29380
|
+
if (!fs12.existsSync(envPath))
|
|
29348
29381
|
return;
|
|
29349
|
-
const content =
|
|
29382
|
+
const content = fs12.readFileSync(envPath, "utf-8");
|
|
29350
29383
|
for (const line of content.split("\n")) {
|
|
29351
29384
|
const trimmed = line.trim();
|
|
29352
29385
|
if (!trimmed || trimmed.startsWith("#"))
|
|
@@ -29370,10 +29403,10 @@ function findConfigFile(startDir) {
|
|
|
29370
29403
|
const newLayout = path15.join(current, CONFIG_DIR_NAME, CONFIG_FILENAME);
|
|
29371
29404
|
const legacyLayout = path15.join(current, LEGACY_CONFIG_FILENAME);
|
|
29372
29405
|
searched.push(newLayout, legacyLayout);
|
|
29373
|
-
if (
|
|
29406
|
+
if (fs13.existsSync(newLayout)) {
|
|
29374
29407
|
return { path: newLayout, isLegacy: false };
|
|
29375
29408
|
}
|
|
29376
|
-
if (
|
|
29409
|
+
if (fs13.existsSync(legacyLayout)) {
|
|
29377
29410
|
return { path: legacyLayout, isLegacy: true };
|
|
29378
29411
|
}
|
|
29379
29412
|
const parent = path15.dirname(current);
|
|
@@ -29396,7 +29429,7 @@ function loadConfig(startDir) {
|
|
|
29396
29429
|
}
|
|
29397
29430
|
let rawContent;
|
|
29398
29431
|
try {
|
|
29399
|
-
rawContent =
|
|
29432
|
+
rawContent = fs13.readFileSync(found.path, "utf-8");
|
|
29400
29433
|
} catch (err) {
|
|
29401
29434
|
throw new Error(`Failed to read ${found.path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
29402
29435
|
}
|
|
@@ -29428,7 +29461,7 @@ function loadConfig(startDir) {
|
|
|
29428
29461
|
// ../core/dist/world/manager.js
|
|
29429
29462
|
import * as crypto5 from "node:crypto";
|
|
29430
29463
|
import { execSync as execSync5 } from "node:child_process";
|
|
29431
|
-
import * as
|
|
29464
|
+
import * as fs21 from "node:fs";
|
|
29432
29465
|
import * as os13 from "node:os";
|
|
29433
29466
|
import * as path24 from "node:path";
|
|
29434
29467
|
|
|
@@ -29526,7 +29559,7 @@ function resolveDevboxImage(config2, tag) {
|
|
|
29526
29559
|
|
|
29527
29560
|
// ../core/dist/world/worktree.js
|
|
29528
29561
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
29529
|
-
import * as
|
|
29562
|
+
import * as fs14 from "node:fs";
|
|
29530
29563
|
import * as path16 from "node:path";
|
|
29531
29564
|
function resolveGitDir(repo) {
|
|
29532
29565
|
if (repo.path) {
|
|
@@ -29541,7 +29574,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
|
29541
29574
|
const gitDir = resolveGitDir(repo);
|
|
29542
29575
|
const branchName = branch || `olam/${worldId}`;
|
|
29543
29576
|
try {
|
|
29544
|
-
|
|
29577
|
+
fs14.mkdirSync(path16.dirname(worktreePath), { recursive: true });
|
|
29545
29578
|
execFileSync2("git", ["worktree", "add", worktreePath, "-b", branchName], {
|
|
29546
29579
|
cwd: gitDir,
|
|
29547
29580
|
stdio: "pipe"
|
|
@@ -29649,7 +29682,7 @@ function removeBranch(repo, branch) {
|
|
|
29649
29682
|
|
|
29650
29683
|
// ../core/dist/world/baseline-diff.js
|
|
29651
29684
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
29652
|
-
import * as
|
|
29685
|
+
import * as fs15 from "node:fs";
|
|
29653
29686
|
import * as os10 from "node:os";
|
|
29654
29687
|
import * as path17 from "node:path";
|
|
29655
29688
|
var DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
@@ -29680,7 +29713,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
29680
29713
|
const homedir15 = deps.homedir ?? (() => os10.homedir());
|
|
29681
29714
|
const baselineDir = path17.join(workspacePath, ".olam", "baseline");
|
|
29682
29715
|
try {
|
|
29683
|
-
|
|
29716
|
+
fs15.mkdirSync(baselineDir, { recursive: true });
|
|
29684
29717
|
} catch (err) {
|
|
29685
29718
|
const msg = err instanceof Error ? err.message : String(err);
|
|
29686
29719
|
console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
|
|
@@ -29694,7 +29727,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
29694
29727
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
29695
29728
|
const outPath = path17.join(baselineDir, filename);
|
|
29696
29729
|
const repoPath = expandHome(repo.path, homedir15);
|
|
29697
|
-
if (!
|
|
29730
|
+
if (!fs15.existsSync(repoPath)) {
|
|
29698
29731
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
29699
29732
|
# (skipped: path ${repoPath} does not exist)
|
|
29700
29733
|
`);
|
|
@@ -29761,7 +29794,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
29761
29794
|
}
|
|
29762
29795
|
function writeBaselineFile(outPath, content) {
|
|
29763
29796
|
try {
|
|
29764
|
-
|
|
29797
|
+
fs15.writeFileSync(outPath, content);
|
|
29765
29798
|
} catch (err) {
|
|
29766
29799
|
const msg = err instanceof Error ? err.message : String(err);
|
|
29767
29800
|
console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
|
|
@@ -29770,7 +29803,7 @@ function writeBaselineFile(outPath, content) {
|
|
|
29770
29803
|
function stripWorktreeEdits(repos, workspacePath) {
|
|
29771
29804
|
for (const repo of repos) {
|
|
29772
29805
|
const worktreePath = path17.join(workspacePath, repo.name);
|
|
29773
|
-
if (!
|
|
29806
|
+
if (!fs15.existsSync(worktreePath))
|
|
29774
29807
|
continue;
|
|
29775
29808
|
try {
|
|
29776
29809
|
execFileSync3("git", ["checkout", "--", "."], {
|
|
@@ -29800,12 +29833,12 @@ function formatBaselineSummary(result) {
|
|
|
29800
29833
|
}
|
|
29801
29834
|
|
|
29802
29835
|
// ../core/dist/world/context-injection.js
|
|
29803
|
-
import * as
|
|
29836
|
+
import * as fs16 from "node:fs";
|
|
29804
29837
|
import * as path18 from "node:path";
|
|
29805
29838
|
function injectWorldContext(opts) {
|
|
29806
29839
|
const { world, task, linearTicketId, claudeMdExtra, taskContext, services, pleriPlaneUrl } = opts;
|
|
29807
29840
|
const claudeDir = path18.join(world.workspacePath, ".claude");
|
|
29808
|
-
|
|
29841
|
+
fs16.mkdirSync(claudeDir, { recursive: true });
|
|
29809
29842
|
const sections = [];
|
|
29810
29843
|
sections.push(`# Olam World: ${world.name}`);
|
|
29811
29844
|
sections.push("");
|
|
@@ -29966,7 +29999,7 @@ function injectWorldContext(opts) {
|
|
|
29966
29999
|
sections.push("");
|
|
29967
30000
|
}
|
|
29968
30001
|
const content = sections.join("\n");
|
|
29969
|
-
|
|
30002
|
+
fs16.writeFileSync(path18.join(claudeDir, "CLAUDE.md"), content);
|
|
29970
30003
|
}
|
|
29971
30004
|
function formatTaskSource(ctx) {
|
|
29972
30005
|
if (ctx.source === "linear" && ctx.ticketId) {
|
|
@@ -29982,7 +30015,7 @@ function hasPlanFile(world) {
|
|
|
29982
30015
|
return false;
|
|
29983
30016
|
const plansDir = path18.join(world.workspacePath, world.repos[0], "docs", "plans");
|
|
29984
30017
|
try {
|
|
29985
|
-
return
|
|
30018
|
+
return fs16.existsSync(plansDir) && fs16.readdirSync(plansDir).length > 0;
|
|
29986
30019
|
} catch {
|
|
29987
30020
|
return false;
|
|
29988
30021
|
}
|
|
@@ -30544,7 +30577,7 @@ function shellQuote(s) {
|
|
|
30544
30577
|
|
|
30545
30578
|
// ../core/dist/world/snapshot.js
|
|
30546
30579
|
import * as crypto4 from "node:crypto";
|
|
30547
|
-
import * as
|
|
30580
|
+
import * as fs17 from "node:fs";
|
|
30548
30581
|
import * as os11 from "node:os";
|
|
30549
30582
|
import * as path19 from "node:path";
|
|
30550
30583
|
import { execFileSync as execFileSync4, spawn } from "node:child_process";
|
|
@@ -30559,10 +30592,10 @@ function cleanupLegacyByWorldDir(worldId) {
|
|
|
30559
30592
|
const legacyDir = path19.join(snapshotsDir(), worldId);
|
|
30560
30593
|
if (worldId === "by-workspace")
|
|
30561
30594
|
return;
|
|
30562
|
-
if (!
|
|
30595
|
+
if (!fs17.existsSync(legacyDir))
|
|
30563
30596
|
return;
|
|
30564
30597
|
try {
|
|
30565
|
-
|
|
30598
|
+
fs17.rmSync(legacyDir, { recursive: true, force: true });
|
|
30566
30599
|
} catch {
|
|
30567
30600
|
}
|
|
30568
30601
|
}
|
|
@@ -30582,10 +30615,10 @@ function hashBuffers(entries) {
|
|
|
30582
30615
|
}
|
|
30583
30616
|
function computeGemsFingerprint(repoDir, imageDigest) {
|
|
30584
30617
|
const lockfile = path19.join(repoDir, "Gemfile.lock");
|
|
30585
|
-
if (!
|
|
30618
|
+
if (!fs17.existsSync(lockfile))
|
|
30586
30619
|
return null;
|
|
30587
30620
|
const entries = [
|
|
30588
|
-
{ path: "Gemfile.lock", content:
|
|
30621
|
+
{ path: "Gemfile.lock", content: fs17.readFileSync(lockfile) }
|
|
30589
30622
|
];
|
|
30590
30623
|
if (imageDigest) {
|
|
30591
30624
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -30596,9 +30629,9 @@ function computeNodeFingerprint(repoDir, imageDigest) {
|
|
|
30596
30629
|
const candidates = ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"];
|
|
30597
30630
|
for (const name of candidates) {
|
|
30598
30631
|
const lockfile = path19.join(repoDir, name);
|
|
30599
|
-
if (
|
|
30632
|
+
if (fs17.existsSync(lockfile)) {
|
|
30600
30633
|
const entries = [
|
|
30601
|
-
{ path: name, content:
|
|
30634
|
+
{ path: name, content: fs17.readFileSync(lockfile) }
|
|
30602
30635
|
];
|
|
30603
30636
|
if (imageDigest) {
|
|
30604
30637
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -30618,17 +30651,17 @@ function unpackTarballAtomic(srcPath, destDir) {
|
|
|
30618
30651
|
};
|
|
30619
30652
|
}
|
|
30620
30653
|
const parent = path19.dirname(destDir);
|
|
30621
|
-
|
|
30654
|
+
fs17.mkdirSync(parent, { recursive: true });
|
|
30622
30655
|
const tmpSuffix = `.tmp-${process.pid}-${crypto4.randomBytes(4).toString("hex")}`;
|
|
30623
30656
|
const tmpDir = `${destDir}${tmpSuffix}`;
|
|
30624
30657
|
try {
|
|
30625
|
-
|
|
30658
|
+
fs17.mkdirSync(tmpDir, { recursive: true });
|
|
30626
30659
|
execFileSync4("tar", ["-xzf", srcPath, "-C", tmpDir], { stdio: "pipe" });
|
|
30627
|
-
|
|
30660
|
+
fs17.renameSync(tmpDir, destDir);
|
|
30628
30661
|
return { ok: true, entryCount: validation.entries.length };
|
|
30629
30662
|
} catch (err) {
|
|
30630
30663
|
try {
|
|
30631
|
-
|
|
30664
|
+
fs17.rmSync(tmpDir, { recursive: true, force: true });
|
|
30632
30665
|
} catch {
|
|
30633
30666
|
}
|
|
30634
30667
|
return {
|
|
@@ -30694,7 +30727,7 @@ function parseTarListLine(line) {
|
|
|
30694
30727
|
function validateHardlinksBinary(tarPath, targetDir) {
|
|
30695
30728
|
let raw;
|
|
30696
30729
|
try {
|
|
30697
|
-
raw = gunzipSync(
|
|
30730
|
+
raw = gunzipSync(fs17.readFileSync(tarPath));
|
|
30698
30731
|
} catch {
|
|
30699
30732
|
return null;
|
|
30700
30733
|
}
|
|
@@ -30800,7 +30833,7 @@ function restoreSnapshotsForRepos(input) {
|
|
|
30800
30833
|
const archDir = snapshotKindDirByWorkspace(input.workspace, input.arch, kind);
|
|
30801
30834
|
const tarFilename = `${repo.name}-${input.arch}-${fingerprint}.tar.gz`;
|
|
30802
30835
|
const tarPath = path19.join(archDir, tarFilename);
|
|
30803
|
-
if (!
|
|
30836
|
+
if (!fs17.existsSync(tarPath)) {
|
|
30804
30837
|
outcomes.push({ repo: repo.name, kind, outcome: "miss", reason: "no-tarball", fingerprint });
|
|
30805
30838
|
continue;
|
|
30806
30839
|
}
|
|
@@ -30817,7 +30850,7 @@ function restoreSnapshotsForRepos(input) {
|
|
|
30817
30850
|
}
|
|
30818
30851
|
const targetDir = path19.join(repo.worktreeDir, targetSubpath);
|
|
30819
30852
|
try {
|
|
30820
|
-
|
|
30853
|
+
fs17.rmSync(targetDir, { recursive: true, force: true });
|
|
30821
30854
|
} catch {
|
|
30822
30855
|
}
|
|
30823
30856
|
const result = unpackTarballAtomic(tarPath, targetDir);
|
|
@@ -30830,8 +30863,8 @@ function restoreSnapshotsForRepos(input) {
|
|
|
30830
30863
|
fingerprint
|
|
30831
30864
|
});
|
|
30832
30865
|
try {
|
|
30833
|
-
|
|
30834
|
-
|
|
30866
|
+
fs17.rmSync(tarPath, { force: true });
|
|
30867
|
+
fs17.rmSync(manifestPath(tarPath), { force: true });
|
|
30835
30868
|
} catch {
|
|
30836
30869
|
}
|
|
30837
30870
|
continue;
|
|
@@ -30847,10 +30880,10 @@ function restoreSnapshotsForRepos(input) {
|
|
|
30847
30880
|
}
|
|
30848
30881
|
function readManifest(tarPath) {
|
|
30849
30882
|
const mPath = manifestPath(tarPath);
|
|
30850
|
-
if (!
|
|
30883
|
+
if (!fs17.existsSync(mPath))
|
|
30851
30884
|
return null;
|
|
30852
30885
|
try {
|
|
30853
|
-
return JSON.parse(
|
|
30886
|
+
return JSON.parse(fs17.readFileSync(mPath, "utf-8"));
|
|
30854
30887
|
} catch {
|
|
30855
30888
|
return null;
|
|
30856
30889
|
}
|
|
@@ -30865,17 +30898,17 @@ function isPidAlive(pid) {
|
|
|
30865
30898
|
}
|
|
30866
30899
|
}
|
|
30867
30900
|
function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
30868
|
-
|
|
30901
|
+
fs17.mkdirSync(dir, { recursive: true });
|
|
30869
30902
|
const lockPath = path19.join(dir, EVICT_LOCK_FILENAME);
|
|
30870
30903
|
let fd;
|
|
30871
30904
|
try {
|
|
30872
|
-
fd =
|
|
30905
|
+
fd = fs17.openSync(lockPath, fs17.constants.O_WRONLY | fs17.constants.O_CREAT | fs17.constants.O_EXCL, 384);
|
|
30873
30906
|
} catch (err) {
|
|
30874
30907
|
if (err.code !== "EEXIST")
|
|
30875
30908
|
return 0;
|
|
30876
30909
|
let holderPid = null;
|
|
30877
30910
|
try {
|
|
30878
|
-
holderPid = parseInt(
|
|
30911
|
+
holderPid = parseInt(fs17.readFileSync(lockPath, "utf-8").trim(), 10);
|
|
30879
30912
|
} catch {
|
|
30880
30913
|
holderPid = null;
|
|
30881
30914
|
}
|
|
@@ -30883,23 +30916,23 @@ function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
|
30883
30916
|
return 0;
|
|
30884
30917
|
}
|
|
30885
30918
|
try {
|
|
30886
|
-
|
|
30887
|
-
fd =
|
|
30919
|
+
fs17.unlinkSync(lockPath);
|
|
30920
|
+
fd = fs17.openSync(lockPath, fs17.constants.O_WRONLY | fs17.constants.O_CREAT | fs17.constants.O_EXCL, 384);
|
|
30888
30921
|
} catch {
|
|
30889
30922
|
return 0;
|
|
30890
30923
|
}
|
|
30891
30924
|
}
|
|
30892
30925
|
try {
|
|
30893
|
-
|
|
30926
|
+
fs17.writeSync(fd, `${process.pid}
|
|
30894
30927
|
`);
|
|
30895
30928
|
} finally {
|
|
30896
|
-
|
|
30929
|
+
fs17.closeSync(fd);
|
|
30897
30930
|
}
|
|
30898
30931
|
try {
|
|
30899
30932
|
return evictOldSnapshots(maxBytes, dir);
|
|
30900
30933
|
} finally {
|
|
30901
30934
|
try {
|
|
30902
|
-
|
|
30935
|
+
fs17.unlinkSync(lockPath);
|
|
30903
30936
|
} catch {
|
|
30904
30937
|
}
|
|
30905
30938
|
}
|
|
@@ -30932,16 +30965,16 @@ function spawnAutoCapture(worldId, olamBin = "olam") {
|
|
|
30932
30965
|
}
|
|
30933
30966
|
}
|
|
30934
30967
|
function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
30935
|
-
if (!
|
|
30968
|
+
if (!fs17.existsSync(dir))
|
|
30936
30969
|
return 0;
|
|
30937
30970
|
const allTars = [];
|
|
30938
30971
|
const walk = (d) => {
|
|
30939
|
-
for (const entry of
|
|
30972
|
+
for (const entry of fs17.readdirSync(d, { withFileTypes: true })) {
|
|
30940
30973
|
const full = path19.join(d, entry.name);
|
|
30941
30974
|
if (entry.isDirectory()) {
|
|
30942
30975
|
walk(full);
|
|
30943
30976
|
} else if (entry.name.endsWith(".tar.gz")) {
|
|
30944
|
-
const stat =
|
|
30977
|
+
const stat = fs17.statSync(full);
|
|
30945
30978
|
allTars.push({ path: full, size: stat.size, mtime: stat.mtimeMs });
|
|
30946
30979
|
}
|
|
30947
30980
|
}
|
|
@@ -30956,8 +30989,8 @@ function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
|
30956
30989
|
for (const tar of allTars) {
|
|
30957
30990
|
if (remaining <= maxBytes)
|
|
30958
30991
|
break;
|
|
30959
|
-
|
|
30960
|
-
|
|
30992
|
+
fs17.rmSync(tar.path, { force: true });
|
|
30993
|
+
fs17.rmSync(manifestPath(tar.path), { force: true });
|
|
30961
30994
|
freed += tar.size;
|
|
30962
30995
|
remaining -= tar.size;
|
|
30963
30996
|
}
|
|
@@ -31095,7 +31128,7 @@ function enrichReposWithManifests(repos, workspacePath) {
|
|
|
31095
31128
|
}
|
|
31096
31129
|
|
|
31097
31130
|
// ../core/dist/policies/loader.js
|
|
31098
|
-
import * as
|
|
31131
|
+
import * as fs18 from "node:fs";
|
|
31099
31132
|
import * as path21 from "node:path";
|
|
31100
31133
|
import { parse as parseYaml3 } from "yaml";
|
|
31101
31134
|
function parseFrontmatter(content) {
|
|
@@ -31117,11 +31150,11 @@ function toStringArray(v) {
|
|
|
31117
31150
|
}
|
|
31118
31151
|
function loadPolicies(workspaceRoot) {
|
|
31119
31152
|
const policiesDir = path21.join(workspaceRoot, ".olam", "policies");
|
|
31120
|
-
if (!
|
|
31153
|
+
if (!fs18.existsSync(policiesDir))
|
|
31121
31154
|
return [];
|
|
31122
31155
|
let files;
|
|
31123
31156
|
try {
|
|
31124
|
-
files =
|
|
31157
|
+
files = fs18.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
|
|
31125
31158
|
} catch {
|
|
31126
31159
|
return [];
|
|
31127
31160
|
}
|
|
@@ -31129,7 +31162,7 @@ function loadPolicies(workspaceRoot) {
|
|
|
31129
31162
|
for (const file of files) {
|
|
31130
31163
|
const filePath = path21.join(policiesDir, file);
|
|
31131
31164
|
try {
|
|
31132
|
-
const content =
|
|
31165
|
+
const content = fs18.readFileSync(filePath, "utf8");
|
|
31133
31166
|
const parsed = parseFrontmatter(content);
|
|
31134
31167
|
if (!parsed) {
|
|
31135
31168
|
console.warn(`[policies] skipping ${file}: no valid frontmatter block`);
|
|
@@ -31180,7 +31213,7 @@ function formatPoliciesBrief(policies) {
|
|
|
31180
31213
|
}
|
|
31181
31214
|
|
|
31182
31215
|
// ../core/dist/global-config/runbook-resolver.js
|
|
31183
|
-
import * as
|
|
31216
|
+
import * as fs19 from "node:fs";
|
|
31184
31217
|
import * as os12 from "node:os";
|
|
31185
31218
|
import * as path22 from "node:path";
|
|
31186
31219
|
function expandTilde(p) {
|
|
@@ -31197,7 +31230,7 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
|
|
|
31197
31230
|
throw new Error(`repo "${repoName}" is referenced by runbook "${runbook.name}" but is not in the registry. Run "olam repos add ${repoName} --path <path>" to register it.`);
|
|
31198
31231
|
}
|
|
31199
31232
|
const resolvedPath = expandTilde(entry.path);
|
|
31200
|
-
if (!
|
|
31233
|
+
if (!fs19.existsSync(resolvedPath)) {
|
|
31201
31234
|
throw new Error(`repo "${repoName}" path "${resolvedPath}" no longer exists. Run "olam repos update ${repoName} --path <new-path>" to fix.`);
|
|
31202
31235
|
}
|
|
31203
31236
|
}
|
|
@@ -31210,7 +31243,7 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
|
|
|
31210
31243
|
}
|
|
31211
31244
|
|
|
31212
31245
|
// ../core/dist/world/bootstrap-hooks.js
|
|
31213
|
-
import * as
|
|
31246
|
+
import * as fs20 from "node:fs";
|
|
31214
31247
|
import * as path23 from "node:path";
|
|
31215
31248
|
function runFixtureCopySeeds(seeds, workspacePath) {
|
|
31216
31249
|
if (!seeds)
|
|
@@ -31221,8 +31254,8 @@ function runFixtureCopySeeds(seeds, workspacePath) {
|
|
|
31221
31254
|
const srcAbs = path23.resolve(workspacePath, seed.repo, seed.src);
|
|
31222
31255
|
const destAbs = path23.resolve(workspacePath, seed.repo, seed.dest);
|
|
31223
31256
|
const destDir = path23.dirname(destAbs);
|
|
31224
|
-
|
|
31225
|
-
|
|
31257
|
+
fs20.mkdirSync(destDir, { recursive: true });
|
|
31258
|
+
fs20.cpSync(srcAbs, destAbs, { recursive: true, force: true });
|
|
31226
31259
|
}
|
|
31227
31260
|
}
|
|
31228
31261
|
async function runSeedHooks(seeds, containerName, servicePortMap, exec) {
|
|
@@ -31835,7 +31868,7 @@ ${detail}`);
|
|
|
31835
31868
|
continue;
|
|
31836
31869
|
const sourceRoot = repo.path.replace(/^~/, os13.homedir());
|
|
31837
31870
|
const worktreeRoot = path24.join(workspacePath, repo.name);
|
|
31838
|
-
if (!
|
|
31871
|
+
if (!fs21.existsSync(sourceRoot) || !fs21.existsSync(worktreeRoot))
|
|
31839
31872
|
continue;
|
|
31840
31873
|
let copied = 0;
|
|
31841
31874
|
for (const pattern of RUNTIME_FILE_PATTERNS) {
|
|
@@ -31843,28 +31876,28 @@ ${detail}`);
|
|
|
31843
31876
|
if (pattern.includes("*")) {
|
|
31844
31877
|
const [dir, glob] = [path24.dirname(pattern), path24.basename(pattern)];
|
|
31845
31878
|
const sourceDir = path24.join(sourceRoot, dir);
|
|
31846
|
-
if (
|
|
31879
|
+
if (fs21.existsSync(sourceDir)) {
|
|
31847
31880
|
const ext = glob.replace(/^\*+/, "");
|
|
31848
31881
|
try {
|
|
31849
|
-
for (const entry of
|
|
31882
|
+
for (const entry of fs21.readdirSync(sourceDir)) {
|
|
31850
31883
|
if (ext === "" || entry.endsWith(ext))
|
|
31851
31884
|
matches2.push(path24.join(dir, entry));
|
|
31852
31885
|
}
|
|
31853
31886
|
} catch {
|
|
31854
31887
|
}
|
|
31855
31888
|
}
|
|
31856
|
-
} else if (
|
|
31889
|
+
} else if (fs21.existsSync(path24.join(sourceRoot, pattern))) {
|
|
31857
31890
|
matches2.push(pattern);
|
|
31858
31891
|
}
|
|
31859
31892
|
for (const rel of matches2) {
|
|
31860
31893
|
const src = path24.join(sourceRoot, rel);
|
|
31861
31894
|
const dst = path24.join(worktreeRoot, rel);
|
|
31862
31895
|
try {
|
|
31863
|
-
const st =
|
|
31896
|
+
const st = fs21.statSync(src);
|
|
31864
31897
|
if (!st.isFile())
|
|
31865
31898
|
continue;
|
|
31866
|
-
|
|
31867
|
-
|
|
31899
|
+
fs21.mkdirSync(path24.dirname(dst), { recursive: true });
|
|
31900
|
+
fs21.copyFileSync(src, dst);
|
|
31868
31901
|
copied++;
|
|
31869
31902
|
} catch {
|
|
31870
31903
|
}
|
|
@@ -32031,9 +32064,9 @@ ${detail}`);
|
|
|
32031
32064
|
if (opts.task)
|
|
32032
32065
|
worldEnv.OLAM_TASK = opts.task;
|
|
32033
32066
|
const r2CredsPath = path24.join(os13.homedir(), ".olam", "r2-credentials.json");
|
|
32034
|
-
if (
|
|
32067
|
+
if (fs21.existsSync(r2CredsPath)) {
|
|
32035
32068
|
try {
|
|
32036
|
-
const r2Raw =
|
|
32069
|
+
const r2Raw = fs21.readFileSync(r2CredsPath, "utf-8").trim();
|
|
32037
32070
|
if (r2Raw.length > 0) {
|
|
32038
32071
|
const r2 = JSON.parse(r2Raw);
|
|
32039
32072
|
if (typeof r2.account_id === "string")
|
|
@@ -32051,9 +32084,9 @@ ${detail}`);
|
|
|
32051
32084
|
}
|
|
32052
32085
|
}
|
|
32053
32086
|
const keysYamlPath = path24.join(os13.homedir(), ".olam", "keys.yaml");
|
|
32054
|
-
if (
|
|
32087
|
+
if (fs21.existsSync(keysYamlPath)) {
|
|
32055
32088
|
try {
|
|
32056
|
-
const keysRaw =
|
|
32089
|
+
const keysRaw = fs21.readFileSync(keysYamlPath, "utf-8").trim();
|
|
32057
32090
|
if (keysRaw.length > 0) {
|
|
32058
32091
|
const parsed = YAML3.parse(keysRaw);
|
|
32059
32092
|
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
@@ -32114,8 +32147,8 @@ ${detail}`);
|
|
|
32114
32147
|
for (const { repoName, relativePath, content } of fileWrites) {
|
|
32115
32148
|
const absPath = path24.join(workspacePath, repoName, relativePath);
|
|
32116
32149
|
try {
|
|
32117
|
-
|
|
32118
|
-
|
|
32150
|
+
fs21.mkdirSync(path24.dirname(absPath), { recursive: true });
|
|
32151
|
+
fs21.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
|
|
32119
32152
|
mode: 384
|
|
32120
32153
|
});
|
|
32121
32154
|
console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
|
|
@@ -32340,7 +32373,7 @@ ${opts.task}`;
|
|
|
32340
32373
|
execSync5(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
|
|
32341
32374
|
for (const repo of repos) {
|
|
32342
32375
|
const policiesDir = path24.join(workspacePath, repo.name, ".olam", "policies");
|
|
32343
|
-
if (
|
|
32376
|
+
if (fs21.existsSync(policiesDir)) {
|
|
32344
32377
|
execSync5(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
|
|
32345
32378
|
}
|
|
32346
32379
|
}
|
|
@@ -32432,8 +32465,8 @@ ${opts.task}`;
|
|
|
32432
32465
|
} catch {
|
|
32433
32466
|
}
|
|
32434
32467
|
try {
|
|
32435
|
-
|
|
32436
|
-
if (
|
|
32468
|
+
fs21.rmSync(world.workspacePath, { recursive: true, force: true });
|
|
32469
|
+
if (fs21.existsSync(world.workspacePath)) {
|
|
32437
32470
|
console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
|
|
32438
32471
|
}
|
|
32439
32472
|
} catch (err) {
|
|
@@ -32506,26 +32539,50 @@ ${opts.task}`;
|
|
|
32506
32539
|
if (!repoNames || repoNames.length === 0) {
|
|
32507
32540
|
return [...this.config.repos];
|
|
32508
32541
|
}
|
|
32542
|
+
let globalRepos = [];
|
|
32543
|
+
try {
|
|
32544
|
+
globalRepos = readGlobalConfig().repos;
|
|
32545
|
+
} catch {
|
|
32546
|
+
}
|
|
32509
32547
|
return repoNames.map((name) => {
|
|
32510
|
-
const
|
|
32511
|
-
if (
|
|
32512
|
-
|
|
32513
|
-
|
|
32514
|
-
|
|
32548
|
+
const local = this.config.repos.find((r) => r.name === name);
|
|
32549
|
+
if (local)
|
|
32550
|
+
return local;
|
|
32551
|
+
const globalEntry = globalRepos.find((r) => r.name === name);
|
|
32552
|
+
if (globalEntry)
|
|
32553
|
+
return repoEntryToRepoConfig(globalEntry);
|
|
32554
|
+
throw new Error(`Repo "${name}" not found in config`);
|
|
32515
32555
|
});
|
|
32516
32556
|
}
|
|
32517
32557
|
resolveReposFromNames(names) {
|
|
32518
|
-
|
|
32558
|
+
let globalRepos = [];
|
|
32559
|
+
try {
|
|
32560
|
+
globalRepos = readGlobalConfig().repos;
|
|
32561
|
+
} catch {
|
|
32562
|
+
}
|
|
32563
|
+
return names.map((name) => {
|
|
32564
|
+
const local = this.config.repos.find((r) => r.name === name);
|
|
32565
|
+
if (local)
|
|
32566
|
+
return local;
|
|
32567
|
+
const globalEntry = globalRepos.find((r) => r.name === name);
|
|
32568
|
+
if (!globalEntry)
|
|
32569
|
+
return void 0;
|
|
32570
|
+
try {
|
|
32571
|
+
return repoEntryToRepoConfig(globalEntry);
|
|
32572
|
+
} catch {
|
|
32573
|
+
return void 0;
|
|
32574
|
+
}
|
|
32575
|
+
}).filter((r) => r !== void 0);
|
|
32519
32576
|
}
|
|
32520
32577
|
transportPlanFile(planFilePath, workspacePath, repoNames) {
|
|
32521
|
-
const planContent =
|
|
32578
|
+
const planContent = fs21.readFileSync(planFilePath, "utf-8");
|
|
32522
32579
|
const planFileName = path24.basename(planFilePath);
|
|
32523
32580
|
const targetRepo = repoNames[0];
|
|
32524
32581
|
if (!targetRepo)
|
|
32525
32582
|
return;
|
|
32526
32583
|
const plansDir = path24.join(workspacePath, targetRepo, "docs", "plans");
|
|
32527
|
-
|
|
32528
|
-
|
|
32584
|
+
fs21.mkdirSync(plansDir, { recursive: true });
|
|
32585
|
+
fs21.writeFileSync(path24.join(plansDir, planFileName), planContent);
|
|
32529
32586
|
}
|
|
32530
32587
|
resolveServices(repos) {
|
|
32531
32588
|
const services = [];
|
|
@@ -32610,7 +32667,7 @@ import * as http2 from "node:http";
|
|
|
32610
32667
|
|
|
32611
32668
|
// ../core/dist/dashboard/server.js
|
|
32612
32669
|
import * as http from "node:http";
|
|
32613
|
-
import * as
|
|
32670
|
+
import * as fs22 from "node:fs";
|
|
32614
32671
|
import * as path25 from "node:path";
|
|
32615
32672
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
32616
32673
|
|
|
@@ -32946,7 +33003,7 @@ function notFound(res) {
|
|
|
32946
33003
|
}
|
|
32947
33004
|
function openThoughtStore(workspacePath) {
|
|
32948
33005
|
const dbPath = getWorldDbPath(workspacePath);
|
|
32949
|
-
if (!
|
|
33006
|
+
if (!fs22.existsSync(dbPath))
|
|
32950
33007
|
return null;
|
|
32951
33008
|
return new ThoughtLocalStore(dbPath);
|
|
32952
33009
|
}
|
|
@@ -33120,10 +33177,10 @@ function createDashboardServer(opts) {
|
|
|
33120
33177
|
const thisDir = path25.dirname(fileURLToPath2(import.meta.url));
|
|
33121
33178
|
const defaultPublicDir = path25.resolve(thisDir, "../../../control-plane/public");
|
|
33122
33179
|
const publicDir = opts.publicDir ?? defaultPublicDir;
|
|
33123
|
-
let hasPublicDir =
|
|
33180
|
+
let hasPublicDir = fs22.existsSync(publicDir);
|
|
33124
33181
|
const server = http.createServer((req, res) => {
|
|
33125
33182
|
if (!hasPublicDir) {
|
|
33126
|
-
hasPublicDir =
|
|
33183
|
+
hasPublicDir = fs22.existsSync(publicDir);
|
|
33127
33184
|
}
|
|
33128
33185
|
const host = req.headers.host ?? `localhost:${port}`;
|
|
33129
33186
|
const url = new URL(req.url ?? "/", `http://${host}`);
|
|
@@ -33402,17 +33459,17 @@ function createDashboardServer(opts) {
|
|
|
33402
33459
|
notFound(res);
|
|
33403
33460
|
return;
|
|
33404
33461
|
}
|
|
33405
|
-
if (
|
|
33462
|
+
if (fs22.existsSync(filePath) && fs22.statSync(filePath).isFile()) {
|
|
33406
33463
|
const ext = path25.extname(filePath);
|
|
33407
33464
|
const contentType = MIME[ext] ?? "application/octet-stream";
|
|
33408
33465
|
res.writeHead(200, { "Content-Type": contentType });
|
|
33409
|
-
|
|
33466
|
+
fs22.createReadStream(filePath).pipe(res);
|
|
33410
33467
|
return;
|
|
33411
33468
|
}
|
|
33412
33469
|
filePath = path25.join(publicDir, "index.html");
|
|
33413
|
-
if (
|
|
33470
|
+
if (fs22.existsSync(filePath)) {
|
|
33414
33471
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
33415
|
-
|
|
33472
|
+
fs22.createReadStream(filePath).pipe(res);
|
|
33416
33473
|
return;
|
|
33417
33474
|
}
|
|
33418
33475
|
notFound(res);
|
|
@@ -33422,17 +33479,17 @@ function createDashboardServer(opts) {
|
|
|
33422
33479
|
}
|
|
33423
33480
|
|
|
33424
33481
|
// ../core/dist/dashboard/state.js
|
|
33425
|
-
import * as
|
|
33482
|
+
import * as fs23 from "node:fs";
|
|
33426
33483
|
import * as os14 from "node:os";
|
|
33427
33484
|
import * as path26 from "node:path";
|
|
33428
33485
|
var STATE_PATH = path26.join(os14.homedir(), ".olam", "dashboard.json");
|
|
33429
33486
|
function saveDashboardState(state) {
|
|
33430
|
-
|
|
33431
|
-
|
|
33487
|
+
fs23.mkdirSync(path26.dirname(STATE_PATH), { recursive: true });
|
|
33488
|
+
fs23.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
|
|
33432
33489
|
}
|
|
33433
33490
|
function loadDashboardState() {
|
|
33434
33491
|
try {
|
|
33435
|
-
const raw =
|
|
33492
|
+
const raw = fs23.readFileSync(STATE_PATH, "utf-8");
|
|
33436
33493
|
return JSON.parse(raw);
|
|
33437
33494
|
} catch {
|
|
33438
33495
|
return null;
|
|
@@ -33440,7 +33497,7 @@ function loadDashboardState() {
|
|
|
33440
33497
|
}
|
|
33441
33498
|
function clearDashboardState() {
|
|
33442
33499
|
try {
|
|
33443
|
-
|
|
33500
|
+
fs23.unlinkSync(STATE_PATH);
|
|
33444
33501
|
} catch {
|
|
33445
33502
|
}
|
|
33446
33503
|
}
|
|
@@ -33720,7 +33777,7 @@ var PleriClient = class {
|
|
|
33720
33777
|
};
|
|
33721
33778
|
|
|
33722
33779
|
// ../mcp-server/src/env-loader.ts
|
|
33723
|
-
import { readFileSync as readFileSync16, existsSync as
|
|
33780
|
+
import { readFileSync as readFileSync16, existsSync as existsSync22, statSync as statSync7 } from "node:fs";
|
|
33724
33781
|
import { join as join27, dirname as dirname15, resolve as resolve7 } from "node:path";
|
|
33725
33782
|
var PROJECT_MARKERS = [
|
|
33726
33783
|
".olam/config.yaml",
|
|
@@ -33733,10 +33790,10 @@ function findProjectRoot2(startDir) {
|
|
|
33733
33790
|
const root = resolve7("/");
|
|
33734
33791
|
while (true) {
|
|
33735
33792
|
for (const marker of PROJECT_MARKERS) {
|
|
33736
|
-
if (
|
|
33793
|
+
if (existsSync22(join27(dir, marker))) return dir;
|
|
33737
33794
|
}
|
|
33738
33795
|
const pkg = join27(dir, "package.json");
|
|
33739
|
-
if (
|
|
33796
|
+
if (existsSync22(pkg)) {
|
|
33740
33797
|
try {
|
|
33741
33798
|
const json = JSON.parse(readFileSync16(pkg, "utf8"));
|
|
33742
33799
|
const isOlamWorkspace = typeof json.name === "string" && json.name.startsWith("@olam/");
|
|
@@ -33776,7 +33833,7 @@ function loadProjectEnv(startDir = process.cwd()) {
|
|
|
33776
33833
|
const merged = {};
|
|
33777
33834
|
for (const name of [".env", ".env.local"]) {
|
|
33778
33835
|
const p = join27(root, name);
|
|
33779
|
-
if (
|
|
33836
|
+
if (existsSync22(p) && statSync7(p).isFile()) {
|
|
33780
33837
|
Object.assign(merged, parseEnvFile(p));
|
|
33781
33838
|
filesRead.push(p);
|
|
33782
33839
|
}
|