@pleri/olam-cli 0.1.114 → 0.1.116
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/README.md +127 -0
- package/dist/image-digests.json +1 -1
- package/dist/index.js +881 -706
- package/dist/mcp-server.js +461 -265
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -487,8 +487,8 @@ var init_parseUtil = __esm({
|
|
|
487
487
|
init_errors();
|
|
488
488
|
init_en();
|
|
489
489
|
makeIssue = (params) => {
|
|
490
|
-
const { data, path:
|
|
491
|
-
const fullPath = [...
|
|
490
|
+
const { data, path: path56, errorMaps, issueData } = params;
|
|
491
|
+
const fullPath = [...path56, ...issueData.path || []];
|
|
492
492
|
const fullIssue = {
|
|
493
493
|
...issueData,
|
|
494
494
|
path: fullPath
|
|
@@ -796,11 +796,11 @@ var init_types = __esm({
|
|
|
796
796
|
init_parseUtil();
|
|
797
797
|
init_util();
|
|
798
798
|
ParseInputLazyPath = class {
|
|
799
|
-
constructor(parent, value,
|
|
799
|
+
constructor(parent, value, path56, key) {
|
|
800
800
|
this._cachedPath = [];
|
|
801
801
|
this.parent = parent;
|
|
802
802
|
this.data = value;
|
|
803
|
-
this._path =
|
|
803
|
+
this._path = path56;
|
|
804
804
|
this._key = key;
|
|
805
805
|
}
|
|
806
806
|
get path() {
|
|
@@ -4281,7 +4281,7 @@ import YAML from "yaml";
|
|
|
4281
4281
|
function bootstrapStepCmd(entry) {
|
|
4282
4282
|
return typeof entry === "string" ? entry : entry.cmd;
|
|
4283
4283
|
}
|
|
4284
|
-
function refineForbiddenKeys(value,
|
|
4284
|
+
function refineForbiddenKeys(value, path56, ctx, rejectSource) {
|
|
4285
4285
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
4286
4286
|
return;
|
|
4287
4287
|
}
|
|
@@ -4289,12 +4289,12 @@ function refineForbiddenKeys(value, path55, ctx, rejectSource) {
|
|
|
4289
4289
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
4290
4290
|
ctx.addIssue({
|
|
4291
4291
|
code: external_exports.ZodIssueCode.custom,
|
|
4292
|
-
path: [...
|
|
4292
|
+
path: [...path56, key],
|
|
4293
4293
|
message: `forbidden key "${key}" (prototype-pollution surface)`
|
|
4294
4294
|
});
|
|
4295
4295
|
continue;
|
|
4296
4296
|
}
|
|
4297
|
-
if (rejectSource &&
|
|
4297
|
+
if (rejectSource && path56.length === 0 && key === "source") {
|
|
4298
4298
|
ctx.addIssue({
|
|
4299
4299
|
code: external_exports.ZodIssueCode.custom,
|
|
4300
4300
|
path: ["source"],
|
|
@@ -4302,21 +4302,21 @@ function refineForbiddenKeys(value, path55, ctx, rejectSource) {
|
|
|
4302
4302
|
});
|
|
4303
4303
|
continue;
|
|
4304
4304
|
}
|
|
4305
|
-
refineForbiddenKeys(value[key], [...
|
|
4305
|
+
refineForbiddenKeys(value[key], [...path56, key], ctx, false);
|
|
4306
4306
|
}
|
|
4307
4307
|
}
|
|
4308
|
-
function rejectForbiddenKeys(value,
|
|
4308
|
+
function rejectForbiddenKeys(value, path56, rejectSource) {
|
|
4309
4309
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
4310
4310
|
return;
|
|
4311
4311
|
}
|
|
4312
4312
|
for (const key of Object.keys(value)) {
|
|
4313
4313
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
4314
|
-
throw new Error(`[manifest] ${
|
|
4314
|
+
throw new Error(`[manifest] ${path56}: forbidden key "${key}" (prototype-pollution surface)`);
|
|
4315
4315
|
}
|
|
4316
4316
|
if (rejectSource && key === "source") {
|
|
4317
|
-
throw new Error(`[manifest] ${
|
|
4317
|
+
throw new Error(`[manifest] ${path56}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
|
|
4318
4318
|
}
|
|
4319
|
-
rejectForbiddenKeys(value[key], `${
|
|
4319
|
+
rejectForbiddenKeys(value[key], `${path56}.${key}`, false);
|
|
4320
4320
|
}
|
|
4321
4321
|
}
|
|
4322
4322
|
function unknownTopLevelKeys(parsed) {
|
|
@@ -5309,8 +5309,8 @@ var init_client = __esm({
|
|
|
5309
5309
|
throw new Error(`failed to report rate-limit for ${accountId} (HTTP ${res.status})`);
|
|
5310
5310
|
}
|
|
5311
5311
|
}
|
|
5312
|
-
async request(method,
|
|
5313
|
-
const url = `${this.baseUrl}${
|
|
5312
|
+
async request(method, path56, body, attempt = 0) {
|
|
5313
|
+
const url = `${this.baseUrl}${path56}`;
|
|
5314
5314
|
const controller = new AbortController();
|
|
5315
5315
|
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
5316
5316
|
const headers = {};
|
|
@@ -5328,7 +5328,7 @@ var init_client = __esm({
|
|
|
5328
5328
|
} catch (err) {
|
|
5329
5329
|
if (attempt < RETRY_COUNT && isTransient(err)) {
|
|
5330
5330
|
await sleep(RETRY_BACKOFF_MS * (attempt + 1));
|
|
5331
|
-
return this.request(method,
|
|
5331
|
+
return this.request(method, path56, body, attempt + 1);
|
|
5332
5332
|
}
|
|
5333
5333
|
throw err;
|
|
5334
5334
|
} finally {
|
|
@@ -6984,8 +6984,8 @@ var init_provider3 = __esm({
|
|
|
6984
6984
|
// -----------------------------------------------------------------------
|
|
6985
6985
|
// Internal fetch helper
|
|
6986
6986
|
// -----------------------------------------------------------------------
|
|
6987
|
-
async request(
|
|
6988
|
-
const url = `${this.config.workerUrl}${
|
|
6987
|
+
async request(path56, method, body) {
|
|
6988
|
+
const url = `${this.config.workerUrl}${path56}`;
|
|
6989
6989
|
const bearer = await this.config.mintToken();
|
|
6990
6990
|
const headers = {
|
|
6991
6991
|
Authorization: `Bearer ${bearer}`
|
|
@@ -8275,11 +8275,202 @@ var init_env_setup = __esm({
|
|
|
8275
8275
|
}
|
|
8276
8276
|
});
|
|
8277
8277
|
|
|
8278
|
-
// ../core/dist/world/
|
|
8278
|
+
// ../core/dist/world/workspace-name.js
|
|
8279
|
+
function validateWorkspaceName(name) {
|
|
8280
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
8281
|
+
throw new InvalidWorkspaceNameError(String(name), "must be a non-empty string");
|
|
8282
|
+
}
|
|
8283
|
+
if (!WORKSPACE_NAME_RE.test(name)) {
|
|
8284
|
+
throw new InvalidWorkspaceNameError(name, "must match ^[a-z0-9][a-z0-9_-]*$ (lowercase letters, digits, hyphens, underscores; must start with letter or digit)");
|
|
8285
|
+
}
|
|
8286
|
+
}
|
|
8287
|
+
var InvalidWorkspaceNameError, WORKSPACE_NAME_RE;
|
|
8288
|
+
var init_workspace_name = __esm({
|
|
8289
|
+
"../core/dist/world/workspace-name.js"() {
|
|
8290
|
+
"use strict";
|
|
8291
|
+
InvalidWorkspaceNameError = class extends Error {
|
|
8292
|
+
constructor(name, reason) {
|
|
8293
|
+
super(`invalid workspace name ${JSON.stringify(name)}: ${reason}`);
|
|
8294
|
+
this.name = "InvalidWorkspaceNameError";
|
|
8295
|
+
}
|
|
8296
|
+
};
|
|
8297
|
+
WORKSPACE_NAME_RE = /^[a-z0-9][a-z0-9_-]*$/;
|
|
8298
|
+
}
|
|
8299
|
+
});
|
|
8300
|
+
|
|
8301
|
+
// ../core/dist/kg/storage-paths.js
|
|
8302
|
+
import { homedir as homedir9 } from "node:os";
|
|
8303
|
+
import { join as join16, resolve as resolve4 } from "node:path";
|
|
8304
|
+
function olamHome() {
|
|
8305
|
+
return process.env.OLAM_HOME ?? join16(homedir9(), ".olam");
|
|
8306
|
+
}
|
|
8307
|
+
function kgRoot() {
|
|
8308
|
+
return join16(olamHome(), "kg");
|
|
8309
|
+
}
|
|
8310
|
+
function worldsRoot() {
|
|
8311
|
+
return join16(olamHome(), "worlds");
|
|
8312
|
+
}
|
|
8313
|
+
function assertWithinPrefix(path56, prefix, label) {
|
|
8314
|
+
if (!path56.startsWith(prefix + "/")) {
|
|
8315
|
+
throw new Error(`${label} escape: ${path56} not under ${prefix}/`);
|
|
8316
|
+
}
|
|
8317
|
+
}
|
|
8318
|
+
function kgPristinePath(workspace) {
|
|
8319
|
+
validateWorkspaceName(workspace);
|
|
8320
|
+
const root = kgRoot();
|
|
8321
|
+
const path56 = resolve4(join16(root, workspace));
|
|
8322
|
+
assertWithinPrefix(path56, root, "kgPristinePath");
|
|
8323
|
+
return path56;
|
|
8324
|
+
}
|
|
8325
|
+
var KG_PATHS_INTERNALS;
|
|
8326
|
+
var init_storage_paths = __esm({
|
|
8327
|
+
"../core/dist/kg/storage-paths.js"() {
|
|
8328
|
+
"use strict";
|
|
8329
|
+
init_workspace_name();
|
|
8330
|
+
KG_PATHS_INTERNALS = Object.freeze({
|
|
8331
|
+
olamHome,
|
|
8332
|
+
kgRoot,
|
|
8333
|
+
worldsRoot
|
|
8334
|
+
});
|
|
8335
|
+
}
|
|
8336
|
+
});
|
|
8337
|
+
|
|
8338
|
+
// ../core/dist/world/kg-overlay.js
|
|
8279
8339
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
8280
8340
|
import * as fs14 from "node:fs";
|
|
8281
|
-
import * as os9 from "node:os";
|
|
8282
8341
|
import * as path15 from "node:path";
|
|
8342
|
+
function ensureGitignoreEntry(worldClonePath) {
|
|
8343
|
+
const gitignorePath = path15.join(worldClonePath, ".gitignore");
|
|
8344
|
+
if (!fs14.existsSync(gitignorePath))
|
|
8345
|
+
return "no-gitignore";
|
|
8346
|
+
const content = fs14.readFileSync(gitignorePath, "utf-8");
|
|
8347
|
+
const lines = content.split("\n").map((l) => l.trim());
|
|
8348
|
+
const recognised = /* @__PURE__ */ new Set([
|
|
8349
|
+
"graphify-out",
|
|
8350
|
+
"graphify-out/",
|
|
8351
|
+
"/graphify-out",
|
|
8352
|
+
"/graphify-out/",
|
|
8353
|
+
"**/graphify-out",
|
|
8354
|
+
"**/graphify-out/"
|
|
8355
|
+
]);
|
|
8356
|
+
if (lines.some((l) => recognised.has(l)))
|
|
8357
|
+
return "present";
|
|
8358
|
+
const eol = content.includes("\r\n") ? "\r\n" : "\n";
|
|
8359
|
+
const needsLeadingNewline = content.length > 0 && !content.endsWith(eol);
|
|
8360
|
+
const block = `${needsLeadingNewline ? eol : ""}${eol}# olam-kg-service: per-world KG overlay (Phase B1)${eol}graphify-out/${eol}`;
|
|
8361
|
+
fs14.appendFileSync(gitignorePath, block, "utf-8");
|
|
8362
|
+
return "appended";
|
|
8363
|
+
}
|
|
8364
|
+
function createWorldOverlay(opts) {
|
|
8365
|
+
const pristineRoot = kgPristinePath(opts.workspace);
|
|
8366
|
+
const pristinePath = path15.join(pristineRoot, "graphify-out");
|
|
8367
|
+
if (!fs14.existsSync(pristinePath)) {
|
|
8368
|
+
throw new KgOverlayError(`Pristine KG for workspace ${JSON.stringify(opts.workspace)} not found at ${pristinePath}. Run \`olam kg build ${opts.workspace}\` first.`);
|
|
8369
|
+
}
|
|
8370
|
+
if (!path15.isAbsolute(opts.worldClonePath)) {
|
|
8371
|
+
throw new KgOverlayError(`worldClonePath must be absolute (got ${opts.worldClonePath})`);
|
|
8372
|
+
}
|
|
8373
|
+
if (!fs14.existsSync(opts.worldClonePath)) {
|
|
8374
|
+
throw new KgOverlayError(`worldClonePath does not exist: ${opts.worldClonePath}. Create the clone before reflinking.`);
|
|
8375
|
+
}
|
|
8376
|
+
const overlayPath = path15.join(opts.worldClonePath, "graphify-out");
|
|
8377
|
+
if (fs14.existsSync(overlayPath)) {
|
|
8378
|
+
fs14.rmSync(overlayPath, { recursive: true, force: true });
|
|
8379
|
+
}
|
|
8380
|
+
const useReflink = process.platform === "darwin";
|
|
8381
|
+
let strategy;
|
|
8382
|
+
let reflinkError;
|
|
8383
|
+
if (useReflink) {
|
|
8384
|
+
try {
|
|
8385
|
+
execFileSync3("cp", ["-c", "-r", pristinePath, opts.worldClonePath], {
|
|
8386
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
8387
|
+
});
|
|
8388
|
+
strategy = "cp-c-r-reflink";
|
|
8389
|
+
} catch (err) {
|
|
8390
|
+
reflinkError = err;
|
|
8391
|
+
strategy = "cp-r";
|
|
8392
|
+
}
|
|
8393
|
+
} else {
|
|
8394
|
+
strategy = "cp-r";
|
|
8395
|
+
}
|
|
8396
|
+
if (strategy === "cp-r" || !fs14.existsSync(overlayPath)) {
|
|
8397
|
+
try {
|
|
8398
|
+
execFileSync3("cp", ["-r", pristinePath, opts.worldClonePath], {
|
|
8399
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
8400
|
+
});
|
|
8401
|
+
strategy = "cp-r";
|
|
8402
|
+
} catch (err) {
|
|
8403
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
8404
|
+
const reflinkMsg = reflinkError instanceof Error ? ` (reflink also failed: ${reflinkError.message})` : "";
|
|
8405
|
+
throw new KgOverlayError(`cp -r failed: ${msg}${reflinkMsg}`);
|
|
8406
|
+
}
|
|
8407
|
+
}
|
|
8408
|
+
if (!fs14.existsSync(overlayPath)) {
|
|
8409
|
+
throw new KgOverlayError(`Overlay creation produced no ${overlayPath} after cp \u2014 filesystem returned without error?`);
|
|
8410
|
+
}
|
|
8411
|
+
const gitignoreAction = ensureGitignoreEntry(opts.worldClonePath);
|
|
8412
|
+
return {
|
|
8413
|
+
pristinePath,
|
|
8414
|
+
overlayPath,
|
|
8415
|
+
strategy,
|
|
8416
|
+
gitignoreAction
|
|
8417
|
+
};
|
|
8418
|
+
}
|
|
8419
|
+
var KgOverlayError;
|
|
8420
|
+
var init_kg_overlay = __esm({
|
|
8421
|
+
"../core/dist/world/kg-overlay.js"() {
|
|
8422
|
+
"use strict";
|
|
8423
|
+
init_storage_paths();
|
|
8424
|
+
KgOverlayError = class extends Error {
|
|
8425
|
+
constructor(message) {
|
|
8426
|
+
super(message);
|
|
8427
|
+
this.name = "KgOverlayError";
|
|
8428
|
+
}
|
|
8429
|
+
};
|
|
8430
|
+
}
|
|
8431
|
+
});
|
|
8432
|
+
|
|
8433
|
+
// ../core/dist/world/kg-install-hook.js
|
|
8434
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
8435
|
+
function installGraphifyHookInWorld(opts) {
|
|
8436
|
+
const timeout = opts.timeoutMs ?? 3e4;
|
|
8437
|
+
try {
|
|
8438
|
+
execFileSync4("docker", [
|
|
8439
|
+
"exec",
|
|
8440
|
+
"-u",
|
|
8441
|
+
"olam",
|
|
8442
|
+
"-w",
|
|
8443
|
+
`/home/olam/workspace/${opts.repoName}`,
|
|
8444
|
+
opts.containerName,
|
|
8445
|
+
"graphify",
|
|
8446
|
+
"claude",
|
|
8447
|
+
"install",
|
|
8448
|
+
"--platform",
|
|
8449
|
+
"claude"
|
|
8450
|
+
], { stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8", timeout });
|
|
8451
|
+
} catch (err) {
|
|
8452
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
8453
|
+
throw new KgHookInstallError(`graphify claude install failed in ${opts.containerName} (repo=${opts.repoName}): ${msg}`);
|
|
8454
|
+
}
|
|
8455
|
+
}
|
|
8456
|
+
var KgHookInstallError;
|
|
8457
|
+
var init_kg_install_hook = __esm({
|
|
8458
|
+
"../core/dist/world/kg-install-hook.js"() {
|
|
8459
|
+
"use strict";
|
|
8460
|
+
KgHookInstallError = class extends Error {
|
|
8461
|
+
constructor(message) {
|
|
8462
|
+
super(message);
|
|
8463
|
+
this.name = "KgHookInstallError";
|
|
8464
|
+
}
|
|
8465
|
+
};
|
|
8466
|
+
}
|
|
8467
|
+
});
|
|
8468
|
+
|
|
8469
|
+
// ../core/dist/world/baseline-diff.js
|
|
8470
|
+
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
8471
|
+
import * as fs15 from "node:fs";
|
|
8472
|
+
import * as os9 from "node:os";
|
|
8473
|
+
import * as path16 from "node:path";
|
|
8283
8474
|
function expandHome(p, homedir30) {
|
|
8284
8475
|
return p.replace(/^~(?=$|\/|\\)/, homedir30());
|
|
8285
8476
|
}
|
|
@@ -8303,11 +8494,11 @@ ${stderr}`;
|
|
|
8303
8494
|
return /unknown revision|bad revision|does not have any commits|HEAD'?: ambiguous|Needed a single revision/.test(blob);
|
|
8304
8495
|
}
|
|
8305
8496
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
8306
|
-
const exec = deps.exec ?? ((cmd, args, opts) =>
|
|
8497
|
+
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync5(cmd, args, opts));
|
|
8307
8498
|
const homedir30 = deps.homedir ?? (() => os9.homedir());
|
|
8308
|
-
const baselineDir =
|
|
8499
|
+
const baselineDir = path16.join(workspacePath, ".olam", "baseline");
|
|
8309
8500
|
try {
|
|
8310
|
-
|
|
8501
|
+
fs15.mkdirSync(baselineDir, { recursive: true });
|
|
8311
8502
|
} catch (err) {
|
|
8312
8503
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8313
8504
|
console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
|
|
@@ -8319,9 +8510,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
8319
8510
|
if (!repo.path)
|
|
8320
8511
|
continue;
|
|
8321
8512
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
8322
|
-
const outPath =
|
|
8513
|
+
const outPath = path16.join(baselineDir, filename);
|
|
8323
8514
|
const repoPath = expandHome(repo.path, homedir30);
|
|
8324
|
-
if (!
|
|
8515
|
+
if (!fs15.existsSync(repoPath)) {
|
|
8325
8516
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
8326
8517
|
# (skipped: path ${repoPath} does not exist)
|
|
8327
8518
|
`);
|
|
@@ -8388,7 +8579,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
8388
8579
|
}
|
|
8389
8580
|
function writeBaselineFile(outPath, content) {
|
|
8390
8581
|
try {
|
|
8391
|
-
|
|
8582
|
+
fs15.writeFileSync(outPath, content);
|
|
8392
8583
|
} catch (err) {
|
|
8393
8584
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8394
8585
|
console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
|
|
@@ -8396,11 +8587,11 @@ function writeBaselineFile(outPath, content) {
|
|
|
8396
8587
|
}
|
|
8397
8588
|
function stripWorktreeEdits(repos, workspacePath) {
|
|
8398
8589
|
for (const repo of repos) {
|
|
8399
|
-
const worktreePath =
|
|
8400
|
-
if (!
|
|
8590
|
+
const worktreePath = path16.join(workspacePath, repo.name);
|
|
8591
|
+
if (!fs15.existsSync(worktreePath))
|
|
8401
8592
|
continue;
|
|
8402
8593
|
try {
|
|
8403
|
-
|
|
8594
|
+
execFileSync5("git", ["checkout", "--", "."], {
|
|
8404
8595
|
cwd: worktreePath,
|
|
8405
8596
|
stdio: "pipe"
|
|
8406
8597
|
});
|
|
@@ -8434,13 +8625,13 @@ var init_baseline_diff = __esm({
|
|
|
8434
8625
|
});
|
|
8435
8626
|
|
|
8436
8627
|
// ../core/dist/world/context-injection.js
|
|
8437
|
-
import * as
|
|
8438
|
-
import * as
|
|
8628
|
+
import * as fs16 from "node:fs";
|
|
8629
|
+
import * as path17 from "node:path";
|
|
8439
8630
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
8440
8631
|
function injectWorldContext(opts) {
|
|
8441
8632
|
const { world, task, linearTicketId, claudeMdExtra, taskContext, services, pleriPlaneUrl } = opts;
|
|
8442
|
-
const claudeDir =
|
|
8443
|
-
|
|
8633
|
+
const claudeDir = path17.join(world.workspacePath, ".claude");
|
|
8634
|
+
fs16.mkdirSync(claudeDir, { recursive: true });
|
|
8444
8635
|
const sections = [];
|
|
8445
8636
|
sections.push(`# Olam World: ${world.name}`);
|
|
8446
8637
|
sections.push("");
|
|
@@ -8541,16 +8732,16 @@ function injectWorldContext(opts) {
|
|
|
8541
8732
|
sections.push("");
|
|
8542
8733
|
}
|
|
8543
8734
|
const content = sections.join("\n");
|
|
8544
|
-
|
|
8735
|
+
fs16.writeFileSync(path17.join(claudeDir, "CLAUDE.md"), content);
|
|
8545
8736
|
writeOlamDocs(world.workspacePath);
|
|
8546
8737
|
}
|
|
8547
8738
|
function writeOlamDocs(workspacePath) {
|
|
8548
|
-
const docsDir =
|
|
8549
|
-
|
|
8739
|
+
const docsDir = path17.join(workspacePath, ".olam", "docs");
|
|
8740
|
+
fs16.mkdirSync(docsDir, { recursive: true });
|
|
8550
8741
|
for (const filename of ["lane-orchestration.md", "gh-pr-create.md"]) {
|
|
8551
|
-
const src =
|
|
8552
|
-
const dest =
|
|
8553
|
-
|
|
8742
|
+
const src = path17.join(TEMPLATES_DIR, filename);
|
|
8743
|
+
const dest = path17.join(docsDir, filename);
|
|
8744
|
+
fs16.copyFileSync(src, dest);
|
|
8554
8745
|
}
|
|
8555
8746
|
}
|
|
8556
8747
|
function formatTaskSource(ctx) {
|
|
@@ -8565,9 +8756,9 @@ function formatTaskSource(ctx) {
|
|
|
8565
8756
|
function hasPlanFile(world) {
|
|
8566
8757
|
if (world.repos.length === 0)
|
|
8567
8758
|
return false;
|
|
8568
|
-
const plansDir =
|
|
8759
|
+
const plansDir = path17.join(world.workspacePath, world.repos[0], "docs", "plans");
|
|
8569
8760
|
try {
|
|
8570
|
-
return
|
|
8761
|
+
return fs16.existsSync(plansDir) && fs16.readdirSync(plansDir).length > 0;
|
|
8571
8762
|
} catch {
|
|
8572
8763
|
return false;
|
|
8573
8764
|
}
|
|
@@ -9163,35 +9354,35 @@ ${stderr}`);
|
|
|
9163
9354
|
|
|
9164
9355
|
// ../core/dist/world/snapshot.js
|
|
9165
9356
|
import * as crypto4 from "node:crypto";
|
|
9166
|
-
import * as
|
|
9357
|
+
import * as fs17 from "node:fs";
|
|
9167
9358
|
import * as os10 from "node:os";
|
|
9168
|
-
import * as
|
|
9169
|
-
import { execFileSync as
|
|
9359
|
+
import * as path18 from "node:path";
|
|
9360
|
+
import { execFileSync as execFileSync6, spawn as spawn2 } from "node:child_process";
|
|
9170
9361
|
import { gunzipSync } from "node:zlib";
|
|
9171
9362
|
function snapshotsDir() {
|
|
9172
|
-
return process.env["OLAM_SNAPSHOTS_DIR"] ??
|
|
9363
|
+
return process.env["OLAM_SNAPSHOTS_DIR"] ?? path18.join(os10.homedir(), ".olam", "snapshots");
|
|
9173
9364
|
}
|
|
9174
9365
|
function snapshotKindDir(worldId, kind) {
|
|
9175
|
-
return
|
|
9366
|
+
return path18.join(snapshotsDir(), worldId, kind);
|
|
9176
9367
|
}
|
|
9177
9368
|
function snapshotKindDirByWorkspace(workspace, arch2, kind) {
|
|
9178
|
-
return
|
|
9369
|
+
return path18.join(snapshotsDir(), "by-workspace", workspace, arch2, kind);
|
|
9179
9370
|
}
|
|
9180
9371
|
function cleanupLegacyByWorldDir(worldId) {
|
|
9181
|
-
const legacyDir =
|
|
9372
|
+
const legacyDir = path18.join(snapshotsDir(), worldId);
|
|
9182
9373
|
if (worldId === "by-workspace")
|
|
9183
9374
|
return;
|
|
9184
|
-
if (!
|
|
9375
|
+
if (!fs17.existsSync(legacyDir))
|
|
9185
9376
|
return;
|
|
9186
9377
|
try {
|
|
9187
|
-
|
|
9378
|
+
fs17.rmSync(legacyDir, { recursive: true, force: true });
|
|
9188
9379
|
} catch {
|
|
9189
9380
|
}
|
|
9190
9381
|
}
|
|
9191
9382
|
function snapshotTarPath(worldId, kind, repoName, hash, arch2) {
|
|
9192
9383
|
const archSuffix = arch2 && (kind === "gems" || kind === "node") ? `-${arch2}` : "";
|
|
9193
9384
|
const base = repoName ? `${repoName}${archSuffix}-${hash}` : hash;
|
|
9194
|
-
return
|
|
9385
|
+
return path18.join(snapshotKindDir(worldId, kind), `${base}.tar.gz`);
|
|
9195
9386
|
}
|
|
9196
9387
|
function manifestPath(tarPath) {
|
|
9197
9388
|
return tarPath.replace(/\.tar\.gz$/, ".manifest.json");
|
|
@@ -9208,11 +9399,11 @@ function hashBuffers(entries) {
|
|
|
9208
9399
|
return hash.digest("hex").slice(0, 12);
|
|
9209
9400
|
}
|
|
9210
9401
|
function computeGemsFingerprint(repoDir, imageDigest) {
|
|
9211
|
-
const lockfile =
|
|
9212
|
-
if (!
|
|
9402
|
+
const lockfile = path18.join(repoDir, "Gemfile.lock");
|
|
9403
|
+
if (!fs17.existsSync(lockfile))
|
|
9213
9404
|
return null;
|
|
9214
9405
|
const entries = [
|
|
9215
|
-
{ path: "Gemfile.lock", content:
|
|
9406
|
+
{ path: "Gemfile.lock", content: fs17.readFileSync(lockfile) }
|
|
9216
9407
|
];
|
|
9217
9408
|
if (imageDigest) {
|
|
9218
9409
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -9222,10 +9413,10 @@ function computeGemsFingerprint(repoDir, imageDigest) {
|
|
|
9222
9413
|
function computeNodeFingerprint(repoDir, imageDigest) {
|
|
9223
9414
|
const candidates = ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"];
|
|
9224
9415
|
for (const name of candidates) {
|
|
9225
|
-
const lockfile =
|
|
9226
|
-
if (
|
|
9416
|
+
const lockfile = path18.join(repoDir, name);
|
|
9417
|
+
if (fs17.existsSync(lockfile)) {
|
|
9227
9418
|
const entries = [
|
|
9228
|
-
{ path: name, content:
|
|
9419
|
+
{ path: name, content: fs17.readFileSync(lockfile) }
|
|
9229
9420
|
];
|
|
9230
9421
|
if (imageDigest) {
|
|
9231
9422
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -9240,27 +9431,27 @@ function computePgFingerprint(repoDirs) {
|
|
|
9240
9431
|
const entries = [];
|
|
9241
9432
|
for (const repoDir of repoDirs) {
|
|
9242
9433
|
for (const pattern of patterns) {
|
|
9243
|
-
const filePath =
|
|
9244
|
-
if (
|
|
9245
|
-
entries.push({ path: filePath, content:
|
|
9434
|
+
const filePath = path18.join(repoDir, pattern);
|
|
9435
|
+
if (fs17.existsSync(filePath)) {
|
|
9436
|
+
entries.push({ path: filePath, content: fs17.readFileSync(filePath) });
|
|
9246
9437
|
}
|
|
9247
9438
|
}
|
|
9248
9439
|
}
|
|
9249
9440
|
return entries.length > 0 ? hashBuffers(entries) : null;
|
|
9250
9441
|
}
|
|
9251
9442
|
function packTarball(srcDir, destPath, opts = {}) {
|
|
9252
|
-
|
|
9443
|
+
fs17.mkdirSync(path18.dirname(destPath), { recursive: true });
|
|
9253
9444
|
const tmp = `${destPath}.tmp`;
|
|
9254
9445
|
const args = [];
|
|
9255
9446
|
if (opts.followSymlinks)
|
|
9256
9447
|
args.push("-h");
|
|
9257
9448
|
args.push("-czf", tmp, "-C", srcDir, ".");
|
|
9258
9449
|
try {
|
|
9259
|
-
|
|
9260
|
-
|
|
9450
|
+
execFileSync6("tar", args, { stdio: "pipe" });
|
|
9451
|
+
fs17.renameSync(tmp, destPath);
|
|
9261
9452
|
} catch (err) {
|
|
9262
9453
|
try {
|
|
9263
|
-
|
|
9454
|
+
fs17.rmSync(tmp, { force: true });
|
|
9264
9455
|
} catch {
|
|
9265
9456
|
}
|
|
9266
9457
|
throw err;
|
|
@@ -9275,18 +9466,18 @@ function unpackTarballAtomic(srcPath, destDir) {
|
|
|
9275
9466
|
detail: validation.detail ?? `unsafe entry: ${validation.unsafePath}`
|
|
9276
9467
|
};
|
|
9277
9468
|
}
|
|
9278
|
-
const parent =
|
|
9279
|
-
|
|
9469
|
+
const parent = path18.dirname(destDir);
|
|
9470
|
+
fs17.mkdirSync(parent, { recursive: true });
|
|
9280
9471
|
const tmpSuffix = `.tmp-${process.pid}-${crypto4.randomBytes(4).toString("hex")}`;
|
|
9281
9472
|
const tmpDir = `${destDir}${tmpSuffix}`;
|
|
9282
9473
|
try {
|
|
9283
|
-
|
|
9284
|
-
|
|
9285
|
-
|
|
9474
|
+
fs17.mkdirSync(tmpDir, { recursive: true });
|
|
9475
|
+
execFileSync6("tar", ["-xzf", srcPath, "-C", tmpDir], { stdio: "pipe" });
|
|
9476
|
+
fs17.renameSync(tmpDir, destDir);
|
|
9286
9477
|
return { ok: true, entryCount: validation.entries.length };
|
|
9287
9478
|
} catch (err) {
|
|
9288
9479
|
try {
|
|
9289
|
-
|
|
9480
|
+
fs17.rmSync(tmpDir, { recursive: true, force: true });
|
|
9290
9481
|
} catch {
|
|
9291
9482
|
}
|
|
9292
9483
|
return {
|
|
@@ -9297,12 +9488,12 @@ function unpackTarballAtomic(srcPath, destDir) {
|
|
|
9297
9488
|
}
|
|
9298
9489
|
}
|
|
9299
9490
|
function resolvesWithin(base, target) {
|
|
9300
|
-
const resolved =
|
|
9301
|
-
const baseResolved =
|
|
9302
|
-
const rel =
|
|
9491
|
+
const resolved = path18.resolve(base, target);
|
|
9492
|
+
const baseResolved = path18.resolve(base);
|
|
9493
|
+
const rel = path18.relative(baseResolved, resolved);
|
|
9303
9494
|
if (rel === "")
|
|
9304
9495
|
return true;
|
|
9305
|
-
return !rel.startsWith("..") && !
|
|
9496
|
+
return !rel.startsWith("..") && !path18.isAbsolute(rel);
|
|
9306
9497
|
}
|
|
9307
9498
|
function parseTarListLine(line) {
|
|
9308
9499
|
const trimmed = line.trimEnd();
|
|
@@ -9345,7 +9536,7 @@ function parseTarListLine(line) {
|
|
|
9345
9536
|
function validateHardlinksBinary(tarPath, targetDir) {
|
|
9346
9537
|
let raw;
|
|
9347
9538
|
try {
|
|
9348
|
-
raw = gunzipSync(
|
|
9539
|
+
raw = gunzipSync(fs17.readFileSync(tarPath));
|
|
9349
9540
|
} catch {
|
|
9350
9541
|
return null;
|
|
9351
9542
|
}
|
|
@@ -9360,7 +9551,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
|
|
|
9360
9551
|
const name = block.subarray(0, nameNull >= 0 && nameNull <= 99 ? nameNull : 100).toString("utf-8");
|
|
9361
9552
|
const linkNull = block.indexOf(0, 157);
|
|
9362
9553
|
const linkname = block.subarray(157, linkNull >= 157 && linkNull <= 256 ? linkNull : 257).toString("utf-8");
|
|
9363
|
-
if (linkname && (
|
|
9554
|
+
if (linkname && (path18.isAbsolute(linkname) || !resolvesWithin(targetDir, linkname))) {
|
|
9364
9555
|
return {
|
|
9365
9556
|
valid: false,
|
|
9366
9557
|
reason: "hardlink-escape",
|
|
@@ -9378,7 +9569,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
|
|
|
9378
9569
|
function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
9379
9570
|
let raw;
|
|
9380
9571
|
try {
|
|
9381
|
-
raw =
|
|
9572
|
+
raw = execFileSync6("tar", ["-tvf", tarPath], {
|
|
9382
9573
|
stdio: ["ignore", "pipe", "pipe"],
|
|
9383
9574
|
env: { ...process.env, LC_ALL: "C", TZ: "UTC" },
|
|
9384
9575
|
encoding: "utf-8",
|
|
@@ -9398,7 +9589,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
9398
9589
|
const entry = parseTarListLine(line);
|
|
9399
9590
|
if (!entry)
|
|
9400
9591
|
continue;
|
|
9401
|
-
if (
|
|
9592
|
+
if (path18.isAbsolute(entry.name) || !resolvesWithin(targetDir, entry.name)) {
|
|
9402
9593
|
return {
|
|
9403
9594
|
valid: false,
|
|
9404
9595
|
reason: "path-traversal",
|
|
@@ -9406,8 +9597,8 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
9406
9597
|
};
|
|
9407
9598
|
}
|
|
9408
9599
|
if (entry.type === "symlink" && entry.linkname !== void 0) {
|
|
9409
|
-
const symlinkParent =
|
|
9410
|
-
if (
|
|
9600
|
+
const symlinkParent = path18.join(targetDir, path18.dirname(entry.name));
|
|
9601
|
+
if (path18.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, path18.join(path18.dirname(entry.name), entry.linkname))) {
|
|
9411
9602
|
return {
|
|
9412
9603
|
valid: false,
|
|
9413
9604
|
reason: "symlink-escape",
|
|
@@ -9417,7 +9608,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
9417
9608
|
}
|
|
9418
9609
|
}
|
|
9419
9610
|
if (entry.type === "hardlink" && entry.linkname !== void 0) {
|
|
9420
|
-
if (
|
|
9611
|
+
if (path18.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, entry.linkname)) {
|
|
9421
9612
|
return {
|
|
9422
9613
|
valid: false,
|
|
9423
9614
|
reason: "hardlink-escape",
|
|
@@ -9446,8 +9637,8 @@ function restoreSnapshotsForRepos(input) {
|
|
|
9446
9637
|
}
|
|
9447
9638
|
const archDir = snapshotKindDirByWorkspace(input.workspace, input.arch, kind);
|
|
9448
9639
|
const tarFilename = `${repo.name}-${input.arch}-${fingerprint}.tar.gz`;
|
|
9449
|
-
const tarPath =
|
|
9450
|
-
if (!
|
|
9640
|
+
const tarPath = path18.join(archDir, tarFilename);
|
|
9641
|
+
if (!fs17.existsSync(tarPath)) {
|
|
9451
9642
|
outcomes.push({ repo: repo.name, kind, outcome: "miss", reason: "no-tarball", fingerprint });
|
|
9452
9643
|
continue;
|
|
9453
9644
|
}
|
|
@@ -9462,9 +9653,9 @@ function restoreSnapshotsForRepos(input) {
|
|
|
9462
9653
|
});
|
|
9463
9654
|
continue;
|
|
9464
9655
|
}
|
|
9465
|
-
const targetDir =
|
|
9656
|
+
const targetDir = path18.join(repo.worktreeDir, targetSubpath);
|
|
9466
9657
|
try {
|
|
9467
|
-
|
|
9658
|
+
fs17.rmSync(targetDir, { recursive: true, force: true });
|
|
9468
9659
|
} catch {
|
|
9469
9660
|
}
|
|
9470
9661
|
const result = unpackTarballAtomic(tarPath, targetDir);
|
|
@@ -9477,8 +9668,8 @@ function restoreSnapshotsForRepos(input) {
|
|
|
9477
9668
|
fingerprint
|
|
9478
9669
|
});
|
|
9479
9670
|
try {
|
|
9480
|
-
|
|
9481
|
-
|
|
9671
|
+
fs17.rmSync(tarPath, { force: true });
|
|
9672
|
+
fs17.rmSync(manifestPath(tarPath), { force: true });
|
|
9482
9673
|
} catch {
|
|
9483
9674
|
}
|
|
9484
9675
|
continue;
|
|
@@ -9493,37 +9684,37 @@ function restoreSnapshotsForRepos(input) {
|
|
|
9493
9684
|
return { restored, outcomes };
|
|
9494
9685
|
}
|
|
9495
9686
|
function writeManifest(manifest, tarPath) {
|
|
9496
|
-
|
|
9687
|
+
fs17.writeFileSync(manifestPath(tarPath), JSON.stringify(manifest, null, 2), "utf-8");
|
|
9497
9688
|
}
|
|
9498
9689
|
function readManifest(tarPath) {
|
|
9499
9690
|
const mPath = manifestPath(tarPath);
|
|
9500
|
-
if (!
|
|
9691
|
+
if (!fs17.existsSync(mPath))
|
|
9501
9692
|
return null;
|
|
9502
9693
|
try {
|
|
9503
|
-
return JSON.parse(
|
|
9694
|
+
return JSON.parse(fs17.readFileSync(mPath, "utf-8"));
|
|
9504
9695
|
} catch {
|
|
9505
9696
|
return null;
|
|
9506
9697
|
}
|
|
9507
9698
|
}
|
|
9508
9699
|
function listSnapshots(worldIdFilter) {
|
|
9509
9700
|
const root = snapshotsDir();
|
|
9510
|
-
if (!
|
|
9701
|
+
if (!fs17.existsSync(root))
|
|
9511
9702
|
return [];
|
|
9512
9703
|
const now = Date.now();
|
|
9513
9704
|
const results = [];
|
|
9514
|
-
const worlds = worldIdFilter ? [worldIdFilter] :
|
|
9705
|
+
const worlds = worldIdFilter ? [worldIdFilter] : fs17.readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
9515
9706
|
for (const worldId of worlds) {
|
|
9516
|
-
const worldDir =
|
|
9517
|
-
if (!
|
|
9707
|
+
const worldDir = path18.join(root, worldId);
|
|
9708
|
+
if (!fs17.existsSync(worldDir) || !fs17.statSync(worldDir).isDirectory())
|
|
9518
9709
|
continue;
|
|
9519
9710
|
for (const kind of ["gems", "node", "pg"]) {
|
|
9520
|
-
const kindDir =
|
|
9521
|
-
if (!
|
|
9711
|
+
const kindDir = path18.join(worldDir, kind);
|
|
9712
|
+
if (!fs17.existsSync(kindDir))
|
|
9522
9713
|
continue;
|
|
9523
|
-
const tarballs =
|
|
9714
|
+
const tarballs = fs17.readdirSync(kindDir).filter((f) => f.endsWith(".tar.gz"));
|
|
9524
9715
|
for (const tarFile of tarballs) {
|
|
9525
|
-
const tarPath =
|
|
9526
|
-
const stat =
|
|
9716
|
+
const tarPath = path18.join(kindDir, tarFile);
|
|
9717
|
+
const stat = fs17.statSync(tarPath);
|
|
9527
9718
|
const manifest = readManifest(tarPath);
|
|
9528
9719
|
if (!manifest)
|
|
9529
9720
|
continue;
|
|
@@ -9542,17 +9733,17 @@ function isPidAlive(pid) {
|
|
|
9542
9733
|
}
|
|
9543
9734
|
}
|
|
9544
9735
|
function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
9545
|
-
|
|
9546
|
-
const lockPath =
|
|
9736
|
+
fs17.mkdirSync(dir, { recursive: true });
|
|
9737
|
+
const lockPath = path18.join(dir, EVICT_LOCK_FILENAME);
|
|
9547
9738
|
let fd;
|
|
9548
9739
|
try {
|
|
9549
|
-
fd =
|
|
9740
|
+
fd = fs17.openSync(lockPath, fs17.constants.O_WRONLY | fs17.constants.O_CREAT | fs17.constants.O_EXCL, 384);
|
|
9550
9741
|
} catch (err) {
|
|
9551
9742
|
if (err.code !== "EEXIST")
|
|
9552
9743
|
return 0;
|
|
9553
9744
|
let holderPid = null;
|
|
9554
9745
|
try {
|
|
9555
|
-
holderPid = parseInt(
|
|
9746
|
+
holderPid = parseInt(fs17.readFileSync(lockPath, "utf-8").trim(), 10);
|
|
9556
9747
|
} catch {
|
|
9557
9748
|
holderPid = null;
|
|
9558
9749
|
}
|
|
@@ -9560,23 +9751,23 @@ function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
|
9560
9751
|
return 0;
|
|
9561
9752
|
}
|
|
9562
9753
|
try {
|
|
9563
|
-
|
|
9564
|
-
fd =
|
|
9754
|
+
fs17.unlinkSync(lockPath);
|
|
9755
|
+
fd = fs17.openSync(lockPath, fs17.constants.O_WRONLY | fs17.constants.O_CREAT | fs17.constants.O_EXCL, 384);
|
|
9565
9756
|
} catch {
|
|
9566
9757
|
return 0;
|
|
9567
9758
|
}
|
|
9568
9759
|
}
|
|
9569
9760
|
try {
|
|
9570
|
-
|
|
9761
|
+
fs17.writeSync(fd, `${process.pid}
|
|
9571
9762
|
`);
|
|
9572
9763
|
} finally {
|
|
9573
|
-
|
|
9764
|
+
fs17.closeSync(fd);
|
|
9574
9765
|
}
|
|
9575
9766
|
try {
|
|
9576
9767
|
return evictOldSnapshots(maxBytes, dir);
|
|
9577
9768
|
} finally {
|
|
9578
9769
|
try {
|
|
9579
|
-
|
|
9770
|
+
fs17.unlinkSync(lockPath);
|
|
9580
9771
|
} catch {
|
|
9581
9772
|
}
|
|
9582
9773
|
}
|
|
@@ -9609,16 +9800,16 @@ function spawnAutoCapture(worldId, olamBin = "olam") {
|
|
|
9609
9800
|
}
|
|
9610
9801
|
}
|
|
9611
9802
|
function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
9612
|
-
if (!
|
|
9803
|
+
if (!fs17.existsSync(dir))
|
|
9613
9804
|
return 0;
|
|
9614
9805
|
const allTars = [];
|
|
9615
9806
|
const walk2 = (d) => {
|
|
9616
|
-
for (const entry of
|
|
9617
|
-
const full =
|
|
9807
|
+
for (const entry of fs17.readdirSync(d, { withFileTypes: true })) {
|
|
9808
|
+
const full = path18.join(d, entry.name);
|
|
9618
9809
|
if (entry.isDirectory()) {
|
|
9619
9810
|
walk2(full);
|
|
9620
9811
|
} else if (entry.name.endsWith(".tar.gz")) {
|
|
9621
|
-
const stat =
|
|
9812
|
+
const stat = fs17.statSync(full);
|
|
9622
9813
|
allTars.push({ path: full, size: stat.size, mtime: stat.mtimeMs });
|
|
9623
9814
|
}
|
|
9624
9815
|
}
|
|
@@ -9633,8 +9824,8 @@ function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
|
9633
9824
|
for (const tar of allTars) {
|
|
9634
9825
|
if (remaining <= maxBytes)
|
|
9635
9826
|
break;
|
|
9636
|
-
|
|
9637
|
-
|
|
9827
|
+
fs17.rmSync(tar.path, { force: true });
|
|
9828
|
+
fs17.rmSync(manifestPath(tar.path), { force: true });
|
|
9638
9829
|
freed += tar.size;
|
|
9639
9830
|
remaining -= tar.size;
|
|
9640
9831
|
}
|
|
@@ -9774,14 +9965,14 @@ var init_secrets_fetcher = __esm({
|
|
|
9774
9965
|
});
|
|
9775
9966
|
|
|
9776
9967
|
// ../core/dist/world/olam-yaml.js
|
|
9777
|
-
import * as
|
|
9968
|
+
import * as path19 from "node:path";
|
|
9778
9969
|
import YAML2 from "yaml";
|
|
9779
9970
|
function enrichReposWithManifests(repos, workspacePath) {
|
|
9780
9971
|
return repos.map((repo) => {
|
|
9781
9972
|
if (repo.manifest !== void 0 && repo.manifest !== null) {
|
|
9782
9973
|
return repo;
|
|
9783
9974
|
}
|
|
9784
|
-
const repoDir =
|
|
9975
|
+
const repoDir = path19.join(workspacePath, repo.name);
|
|
9785
9976
|
let manifest = null;
|
|
9786
9977
|
try {
|
|
9787
9978
|
manifest = loadRepoManifest(repoDir);
|
|
@@ -9802,8 +9993,8 @@ var init_olam_yaml = __esm({
|
|
|
9802
9993
|
});
|
|
9803
9994
|
|
|
9804
9995
|
// ../core/dist/policies/loader.js
|
|
9805
|
-
import * as
|
|
9806
|
-
import * as
|
|
9996
|
+
import * as fs18 from "node:fs";
|
|
9997
|
+
import * as path20 from "node:path";
|
|
9807
9998
|
import { parse as parseYaml3 } from "yaml";
|
|
9808
9999
|
function parseFrontmatter(content) {
|
|
9809
10000
|
const match2 = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
|
|
@@ -9823,20 +10014,20 @@ function toStringArray(v) {
|
|
|
9823
10014
|
return v.filter((x) => typeof x === "string");
|
|
9824
10015
|
}
|
|
9825
10016
|
function loadPolicies(workspaceRoot) {
|
|
9826
|
-
const policiesDir =
|
|
9827
|
-
if (!
|
|
10017
|
+
const policiesDir = path20.join(workspaceRoot, ".olam", "policies");
|
|
10018
|
+
if (!fs18.existsSync(policiesDir))
|
|
9828
10019
|
return [];
|
|
9829
10020
|
let files;
|
|
9830
10021
|
try {
|
|
9831
|
-
files =
|
|
10022
|
+
files = fs18.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
|
|
9832
10023
|
} catch {
|
|
9833
10024
|
return [];
|
|
9834
10025
|
}
|
|
9835
10026
|
const policies = [];
|
|
9836
10027
|
for (const file of files) {
|
|
9837
|
-
const filePath =
|
|
10028
|
+
const filePath = path20.join(policiesDir, file);
|
|
9838
10029
|
try {
|
|
9839
|
-
const content =
|
|
10030
|
+
const content = fs18.readFileSync(filePath, "utf8");
|
|
9840
10031
|
const parsed = parseFrontmatter(content);
|
|
9841
10032
|
if (!parsed) {
|
|
9842
10033
|
console.warn(`[policies] skipping ${file}: no valid frontmatter block`);
|
|
@@ -9972,23 +10163,23 @@ var init_schema3 = __esm({
|
|
|
9972
10163
|
});
|
|
9973
10164
|
|
|
9974
10165
|
// ../core/dist/global-config/store.js
|
|
9975
|
-
import * as
|
|
10166
|
+
import * as fs19 from "node:fs";
|
|
9976
10167
|
import * as os11 from "node:os";
|
|
9977
|
-
import * as
|
|
10168
|
+
import * as path21 from "node:path";
|
|
9978
10169
|
function globalConfigPath() {
|
|
9979
10170
|
const override = process.env["OLAM_GLOBAL_CONFIG_PATH"];
|
|
9980
10171
|
if (override && override.length > 0)
|
|
9981
10172
|
return override;
|
|
9982
|
-
return
|
|
10173
|
+
return path21.join(os11.homedir(), ".olam", "config.json");
|
|
9983
10174
|
}
|
|
9984
10175
|
function readGlobalConfig() {
|
|
9985
10176
|
const configPath = globalConfigPath();
|
|
9986
|
-
if (!
|
|
10177
|
+
if (!fs19.existsSync(configPath)) {
|
|
9987
10178
|
return { ...DEFAULT_GLOBAL_CONFIG };
|
|
9988
10179
|
}
|
|
9989
10180
|
let raw;
|
|
9990
10181
|
try {
|
|
9991
|
-
raw =
|
|
10182
|
+
raw = fs19.readFileSync(configPath, "utf-8");
|
|
9992
10183
|
} catch (err) {
|
|
9993
10184
|
throw new GlobalConfigReadError(configPath, err);
|
|
9994
10185
|
}
|
|
@@ -10007,11 +10198,11 @@ function readGlobalConfig() {
|
|
|
10007
10198
|
function writeGlobalConfig(config) {
|
|
10008
10199
|
const configPath = globalConfigPath();
|
|
10009
10200
|
const validated = GlobalConfigSchema.parse(config);
|
|
10010
|
-
const dir =
|
|
10011
|
-
|
|
10201
|
+
const dir = path21.dirname(configPath);
|
|
10202
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
10012
10203
|
const tmp = `${configPath}.tmp-${process.pid}`;
|
|
10013
|
-
|
|
10014
|
-
|
|
10204
|
+
fs19.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
|
|
10205
|
+
fs19.renameSync(tmp, configPath);
|
|
10015
10206
|
}
|
|
10016
10207
|
var GlobalConfigReadError;
|
|
10017
10208
|
var init_store2 = __esm({
|
|
@@ -10121,7 +10312,7 @@ var init_runbooks = __esm({
|
|
|
10121
10312
|
});
|
|
10122
10313
|
|
|
10123
10314
|
// ../core/dist/global-config/bridge.js
|
|
10124
|
-
import * as
|
|
10315
|
+
import * as fs20 from "node:fs";
|
|
10125
10316
|
function repoEntryToRepoConfig(entry) {
|
|
10126
10317
|
if (!entry.url) {
|
|
10127
10318
|
throw new Error(`Repo "${entry.name}" has no url. Re-register:
|
|
@@ -10129,7 +10320,7 @@ function repoEntryToRepoConfig(entry) {
|
|
|
10129
10320
|
olam repos add ${entry.name} --path ${entry.path}`);
|
|
10130
10321
|
}
|
|
10131
10322
|
const repoPath = resolveTildePath(entry.path);
|
|
10132
|
-
if (!
|
|
10323
|
+
if (!fs20.existsSync(repoPath)) {
|
|
10133
10324
|
throw new Error(`Repo "${entry.name}" path "${repoPath}" no longer exists. Run: olam repos update ${entry.name} --path <new-path>`);
|
|
10134
10325
|
}
|
|
10135
10326
|
let manifest = null;
|
|
@@ -10160,12 +10351,12 @@ var init_bridge = __esm({
|
|
|
10160
10351
|
});
|
|
10161
10352
|
|
|
10162
10353
|
// ../core/dist/global-config/runbook-resolver.js
|
|
10163
|
-
import * as
|
|
10354
|
+
import * as fs21 from "node:fs";
|
|
10164
10355
|
import * as os12 from "node:os";
|
|
10165
|
-
import * as
|
|
10356
|
+
import * as path22 from "node:path";
|
|
10166
10357
|
function expandTilde(p) {
|
|
10167
10358
|
if (p === "~" || p.startsWith("~/")) {
|
|
10168
|
-
return
|
|
10359
|
+
return path22.join(os12.homedir(), p.slice(1));
|
|
10169
10360
|
}
|
|
10170
10361
|
return p;
|
|
10171
10362
|
}
|
|
@@ -10177,7 +10368,7 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
|
|
|
10177
10368
|
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.`);
|
|
10178
10369
|
}
|
|
10179
10370
|
const resolvedPath = expandTilde(entry.path);
|
|
10180
|
-
if (!
|
|
10371
|
+
if (!fs21.existsSync(resolvedPath)) {
|
|
10181
10372
|
throw new Error(`repo "${repoName}" path "${resolvedPath}" no longer exists. Run "olam repos update ${repoName} --path <new-path>" to fix.`);
|
|
10182
10373
|
}
|
|
10183
10374
|
}
|
|
@@ -10277,19 +10468,19 @@ var init_port_validator = __esm({
|
|
|
10277
10468
|
});
|
|
10278
10469
|
|
|
10279
10470
|
// ../core/dist/world/bootstrap-hooks.js
|
|
10280
|
-
import * as
|
|
10281
|
-
import * as
|
|
10471
|
+
import * as fs22 from "node:fs";
|
|
10472
|
+
import * as path23 from "node:path";
|
|
10282
10473
|
function runFixtureCopySeeds(seeds, workspacePath) {
|
|
10283
10474
|
if (!seeds)
|
|
10284
10475
|
return;
|
|
10285
10476
|
for (const seed of seeds) {
|
|
10286
10477
|
if (seed.type !== "fixture-copy")
|
|
10287
10478
|
continue;
|
|
10288
|
-
const srcAbs =
|
|
10289
|
-
const destAbs =
|
|
10290
|
-
const destDir =
|
|
10291
|
-
|
|
10292
|
-
|
|
10479
|
+
const srcAbs = path23.resolve(workspacePath, seed.repo, seed.src);
|
|
10480
|
+
const destAbs = path23.resolve(workspacePath, seed.repo, seed.dest);
|
|
10481
|
+
const destDir = path23.dirname(destAbs);
|
|
10482
|
+
fs22.mkdirSync(destDir, { recursive: true });
|
|
10483
|
+
fs22.cpSync(srcAbs, destAbs, { recursive: true, force: true });
|
|
10293
10484
|
}
|
|
10294
10485
|
}
|
|
10295
10486
|
async function runSeedHooks(seeds, containerName, servicePortMap, exec) {
|
|
@@ -10477,9 +10668,9 @@ __export(manager_exports, {
|
|
|
10477
10668
|
});
|
|
10478
10669
|
import * as crypto5 from "node:crypto";
|
|
10479
10670
|
import { execSync as execSync5 } from "node:child_process";
|
|
10480
|
-
import * as
|
|
10671
|
+
import * as fs23 from "node:fs";
|
|
10481
10672
|
import * as os13 from "node:os";
|
|
10482
|
-
import * as
|
|
10673
|
+
import * as path24 from "node:path";
|
|
10483
10674
|
import YAML3 from "yaml";
|
|
10484
10675
|
function getTokenScopes(ghToken, _exec = execSync5) {
|
|
10485
10676
|
try {
|
|
@@ -10905,6 +11096,8 @@ var init_manager = __esm({
|
|
|
10905
11096
|
init_devbox_image();
|
|
10906
11097
|
init_worktree();
|
|
10907
11098
|
init_env_setup();
|
|
11099
|
+
init_kg_overlay();
|
|
11100
|
+
init_kg_install_hook();
|
|
10908
11101
|
init_baseline_diff();
|
|
10909
11102
|
init_context_injection();
|
|
10910
11103
|
init_stack_detect();
|
|
@@ -10999,7 +11192,7 @@ ${detail}`);
|
|
|
10999
11192
|
runbookSeeds = resolved.seeds;
|
|
11000
11193
|
}
|
|
11001
11194
|
const worldId = generateWorldId();
|
|
11002
|
-
const workspacePath =
|
|
11195
|
+
const workspacePath = path24.join(os13.homedir(), ".olam", "worlds", worldId);
|
|
11003
11196
|
const portOffset = this.registry.getNextPortOffset();
|
|
11004
11197
|
const branch = opts.branchName ?? `olam/${worldId}`;
|
|
11005
11198
|
const repos = this.resolveReposWithWorkspace(opts);
|
|
@@ -11069,37 +11262,37 @@ ${detail}`);
|
|
|
11069
11262
|
if (!repo.path)
|
|
11070
11263
|
continue;
|
|
11071
11264
|
const sourceRoot = repo.path.replace(/^~/, os13.homedir());
|
|
11072
|
-
const worktreeRoot =
|
|
11073
|
-
if (!
|
|
11265
|
+
const worktreeRoot = path24.join(workspacePath, repo.name);
|
|
11266
|
+
if (!fs23.existsSync(sourceRoot) || !fs23.existsSync(worktreeRoot))
|
|
11074
11267
|
continue;
|
|
11075
11268
|
let copied = 0;
|
|
11076
11269
|
for (const pattern of RUNTIME_FILE_PATTERNS) {
|
|
11077
11270
|
const matches2 = [];
|
|
11078
11271
|
if (pattern.includes("*")) {
|
|
11079
|
-
const [dir, glob] = [
|
|
11080
|
-
const sourceDir =
|
|
11081
|
-
if (
|
|
11272
|
+
const [dir, glob] = [path24.dirname(pattern), path24.basename(pattern)];
|
|
11273
|
+
const sourceDir = path24.join(sourceRoot, dir);
|
|
11274
|
+
if (fs23.existsSync(sourceDir)) {
|
|
11082
11275
|
const ext2 = glob.replace(/^\*+/, "");
|
|
11083
11276
|
try {
|
|
11084
|
-
for (const entry of
|
|
11277
|
+
for (const entry of fs23.readdirSync(sourceDir)) {
|
|
11085
11278
|
if (ext2 === "" || entry.endsWith(ext2))
|
|
11086
|
-
matches2.push(
|
|
11279
|
+
matches2.push(path24.join(dir, entry));
|
|
11087
11280
|
}
|
|
11088
11281
|
} catch {
|
|
11089
11282
|
}
|
|
11090
11283
|
}
|
|
11091
|
-
} else if (
|
|
11284
|
+
} else if (fs23.existsSync(path24.join(sourceRoot, pattern))) {
|
|
11092
11285
|
matches2.push(pattern);
|
|
11093
11286
|
}
|
|
11094
11287
|
for (const rel of matches2) {
|
|
11095
|
-
const src =
|
|
11096
|
-
const dst =
|
|
11288
|
+
const src = path24.join(sourceRoot, rel);
|
|
11289
|
+
const dst = path24.join(worktreeRoot, rel);
|
|
11097
11290
|
try {
|
|
11098
|
-
const st =
|
|
11291
|
+
const st = fs23.statSync(src);
|
|
11099
11292
|
if (!st.isFile())
|
|
11100
11293
|
continue;
|
|
11101
|
-
|
|
11102
|
-
|
|
11294
|
+
fs23.mkdirSync(path24.dirname(dst), { recursive: true });
|
|
11295
|
+
fs23.copyFileSync(src, dst);
|
|
11103
11296
|
copied++;
|
|
11104
11297
|
} catch {
|
|
11105
11298
|
}
|
|
@@ -11183,6 +11376,24 @@ ${detail}`);
|
|
|
11183
11376
|
console.warn(`[WorldManager] context injection failed: ${msg}`);
|
|
11184
11377
|
}
|
|
11185
11378
|
}
|
|
11379
|
+
const overlayAttachments = [];
|
|
11380
|
+
for (const repo of repos) {
|
|
11381
|
+
const worldClonePath = path24.join(workspacePath, repo.name);
|
|
11382
|
+
try {
|
|
11383
|
+
const result = createWorldOverlay({
|
|
11384
|
+
workspace: repo.name,
|
|
11385
|
+
worldClonePath
|
|
11386
|
+
});
|
|
11387
|
+
overlayAttachments.push({ repo: repo.name, overlayPath: result.overlayPath });
|
|
11388
|
+
console.log(`[WorldManager] KG overlay attached for ${repo.name}: ${result.strategy} (.gitignore: ${result.gitignoreAction})`);
|
|
11389
|
+
} catch (err) {
|
|
11390
|
+
if (err instanceof KgOverlayError && /pristine.*not found|MISSING/i.test(err.message)) {
|
|
11391
|
+
continue;
|
|
11392
|
+
}
|
|
11393
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
11394
|
+
console.warn(`[WorldManager] KG overlay attach failed for ${repo.name}: ${msg}`);
|
|
11395
|
+
}
|
|
11396
|
+
}
|
|
11186
11397
|
if (opts.planFile) {
|
|
11187
11398
|
try {
|
|
11188
11399
|
this.transportPlanFile(opts.planFile, workspacePath, repos.map((r) => r.name));
|
|
@@ -11199,7 +11410,7 @@ ${detail}`);
|
|
|
11199
11410
|
try {
|
|
11200
11411
|
const hostExec = makeHostExecFn();
|
|
11201
11412
|
for (const repo of repos) {
|
|
11202
|
-
const repoDir =
|
|
11413
|
+
const repoDir = path24.join(workspacePath, repo.name);
|
|
11203
11414
|
if (repo.stack && Object.keys(repo.stack).length > 0) {
|
|
11204
11415
|
preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
|
|
11205
11416
|
} else {
|
|
@@ -11265,10 +11476,10 @@ ${detail}`);
|
|
|
11265
11476
|
const worldEnv = {};
|
|
11266
11477
|
if (opts.task)
|
|
11267
11478
|
worldEnv.OLAM_TASK = opts.task;
|
|
11268
|
-
const r2CredsPath =
|
|
11269
|
-
if (
|
|
11479
|
+
const r2CredsPath = path24.join(os13.homedir(), ".olam", "r2-credentials.json");
|
|
11480
|
+
if (fs23.existsSync(r2CredsPath)) {
|
|
11270
11481
|
try {
|
|
11271
|
-
const r2Raw =
|
|
11482
|
+
const r2Raw = fs23.readFileSync(r2CredsPath, "utf-8").trim();
|
|
11272
11483
|
if (r2Raw.length > 0) {
|
|
11273
11484
|
const r2 = JSON.parse(r2Raw);
|
|
11274
11485
|
if (typeof r2.account_id === "string")
|
|
@@ -11285,10 +11496,10 @@ ${detail}`);
|
|
|
11285
11496
|
} catch {
|
|
11286
11497
|
}
|
|
11287
11498
|
}
|
|
11288
|
-
const keysYamlPath =
|
|
11289
|
-
if (
|
|
11499
|
+
const keysYamlPath = path24.join(os13.homedir(), ".olam", "keys.yaml");
|
|
11500
|
+
if (fs23.existsSync(keysYamlPath)) {
|
|
11290
11501
|
try {
|
|
11291
|
-
const keysRaw =
|
|
11502
|
+
const keysRaw = fs23.readFileSync(keysYamlPath, "utf-8").trim();
|
|
11292
11503
|
if (keysRaw.length > 0) {
|
|
11293
11504
|
const parsed = YAML3.parse(keysRaw);
|
|
11294
11505
|
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
@@ -11347,10 +11558,10 @@ ${detail}`);
|
|
|
11347
11558
|
worldEnv[k] = v;
|
|
11348
11559
|
}
|
|
11349
11560
|
for (const { repoName, relativePath, content } of fileWrites) {
|
|
11350
|
-
const absPath =
|
|
11561
|
+
const absPath = path24.join(workspacePath, repoName, relativePath);
|
|
11351
11562
|
try {
|
|
11352
|
-
|
|
11353
|
-
|
|
11563
|
+
fs23.mkdirSync(path24.dirname(absPath), { recursive: true });
|
|
11564
|
+
fs23.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
|
|
11354
11565
|
mode: 384
|
|
11355
11566
|
});
|
|
11356
11567
|
console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
|
|
@@ -11401,6 +11612,15 @@ ${detail}`);
|
|
|
11401
11612
|
await copyClaudeConfigIntoContainer(containerName);
|
|
11402
11613
|
} catch {
|
|
11403
11614
|
}
|
|
11615
|
+
for (const { repo: repoName } of overlayAttachments) {
|
|
11616
|
+
try {
|
|
11617
|
+
installGraphifyHookInWorld({ containerName, repoName });
|
|
11618
|
+
console.log(`[WorldManager] KG hook installed for ${repoName}`);
|
|
11619
|
+
} catch (err) {
|
|
11620
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
11621
|
+
console.warn(`[WorldManager] KG hook install failed for ${repoName}: ${msg}`);
|
|
11622
|
+
}
|
|
11623
|
+
}
|
|
11404
11624
|
const credentialsInjected = { claude: !opts.noAuth, codex: false };
|
|
11405
11625
|
try {
|
|
11406
11626
|
await setupContainerGit(containerName, repos, branch);
|
|
@@ -11465,7 +11685,7 @@ ${detail}`);
|
|
|
11465
11685
|
imageDigest: void 0,
|
|
11466
11686
|
repos: enrichedRepos.map((r) => ({
|
|
11467
11687
|
name: r.name,
|
|
11468
|
-
worktreeDir:
|
|
11688
|
+
worktreeDir: path24.join(workspacePath, r.name)
|
|
11469
11689
|
}))
|
|
11470
11690
|
});
|
|
11471
11691
|
for (const out of restoreResult.outcomes) {
|
|
@@ -11578,7 +11798,7 @@ ${detail}`);
|
|
|
11578
11798
|
let taskWithPolicies = opts.task;
|
|
11579
11799
|
try {
|
|
11580
11800
|
const allPolicies = repos.flatMap((repo) => {
|
|
11581
|
-
const repoWorktree =
|
|
11801
|
+
const repoWorktree = path24.join(workspacePath, repo.name);
|
|
11582
11802
|
return loadPolicies(repoWorktree);
|
|
11583
11803
|
});
|
|
11584
11804
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -11594,8 +11814,8 @@ ${detail}`);
|
|
|
11594
11814
|
${opts.task}`;
|
|
11595
11815
|
execSync5(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
|
|
11596
11816
|
for (const repo of repos) {
|
|
11597
|
-
const policiesDir =
|
|
11598
|
-
if (
|
|
11817
|
+
const policiesDir = path24.join(workspacePath, repo.name, ".olam", "policies");
|
|
11818
|
+
if (fs23.existsSync(policiesDir)) {
|
|
11599
11819
|
execSync5(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
|
|
11600
11820
|
}
|
|
11601
11821
|
}
|
|
@@ -11695,8 +11915,8 @@ ${opts.task}`;
|
|
|
11695
11915
|
} catch {
|
|
11696
11916
|
}
|
|
11697
11917
|
try {
|
|
11698
|
-
|
|
11699
|
-
if (
|
|
11918
|
+
fs23.rmSync(world.workspacePath, { recursive: true, force: true });
|
|
11919
|
+
if (fs23.existsSync(world.workspacePath)) {
|
|
11700
11920
|
console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
|
|
11701
11921
|
}
|
|
11702
11922
|
} catch (err) {
|
|
@@ -11805,14 +12025,14 @@ ${opts.task}`;
|
|
|
11805
12025
|
}).filter((r) => r !== void 0);
|
|
11806
12026
|
}
|
|
11807
12027
|
transportPlanFile(planFilePath, workspacePath, repoNames) {
|
|
11808
|
-
const planContent =
|
|
11809
|
-
const planFileName =
|
|
12028
|
+
const planContent = fs23.readFileSync(planFilePath, "utf-8");
|
|
12029
|
+
const planFileName = path24.basename(planFilePath);
|
|
11810
12030
|
const targetRepo = repoNames[0];
|
|
11811
12031
|
if (!targetRepo)
|
|
11812
12032
|
return;
|
|
11813
|
-
const plansDir =
|
|
11814
|
-
|
|
11815
|
-
|
|
12033
|
+
const plansDir = path24.join(workspacePath, targetRepo, "docs", "plans");
|
|
12034
|
+
fs23.mkdirSync(plansDir, { recursive: true });
|
|
12035
|
+
fs23.writeFileSync(path24.join(plansDir, planFileName), planContent);
|
|
11816
12036
|
}
|
|
11817
12037
|
resolveServices(repos) {
|
|
11818
12038
|
const services = [];
|
|
@@ -11905,9 +12125,9 @@ var init_tracker = __esm({
|
|
|
11905
12125
|
});
|
|
11906
12126
|
|
|
11907
12127
|
// ../core/dist/world-paths.js
|
|
11908
|
-
import * as
|
|
12128
|
+
import * as path25 from "node:path";
|
|
11909
12129
|
function getWorldDbPath(workspacePath) {
|
|
11910
|
-
return
|
|
12130
|
+
return path25.join(workspacePath, WORLD_DB_FILENAME);
|
|
11911
12131
|
}
|
|
11912
12132
|
var WORLD_DB_FILENAME;
|
|
11913
12133
|
var init_world_paths = __esm({
|
|
@@ -12525,8 +12745,8 @@ var init_session_aggregator = __esm({
|
|
|
12525
12745
|
|
|
12526
12746
|
// ../core/dist/dashboard/server.js
|
|
12527
12747
|
import * as http from "node:http";
|
|
12528
|
-
import * as
|
|
12529
|
-
import * as
|
|
12748
|
+
import * as fs24 from "node:fs";
|
|
12749
|
+
import * as path26 from "node:path";
|
|
12530
12750
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
12531
12751
|
function jsonResponse(res, data, status = 200) {
|
|
12532
12752
|
res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
|
|
@@ -12537,7 +12757,7 @@ function notFound(res) {
|
|
|
12537
12757
|
}
|
|
12538
12758
|
function openThoughtStore(workspacePath) {
|
|
12539
12759
|
const dbPath = getWorldDbPath(workspacePath);
|
|
12540
|
-
if (!
|
|
12760
|
+
if (!fs24.existsSync(dbPath))
|
|
12541
12761
|
return null;
|
|
12542
12762
|
return new ThoughtLocalStore(dbPath);
|
|
12543
12763
|
}
|
|
@@ -12708,13 +12928,13 @@ function findSessionInWorld(registry, sessionId) {
|
|
|
12708
12928
|
}
|
|
12709
12929
|
function createDashboardServer(opts) {
|
|
12710
12930
|
const { port, registry } = opts;
|
|
12711
|
-
const thisDir =
|
|
12712
|
-
const defaultPublicDir =
|
|
12931
|
+
const thisDir = path26.dirname(fileURLToPath4(import.meta.url));
|
|
12932
|
+
const defaultPublicDir = path26.resolve(thisDir, "../../../control-plane/public");
|
|
12713
12933
|
const publicDir = opts.publicDir ?? defaultPublicDir;
|
|
12714
|
-
let hasPublicDir =
|
|
12934
|
+
let hasPublicDir = fs24.existsSync(publicDir);
|
|
12715
12935
|
const server = http.createServer((req, res) => {
|
|
12716
12936
|
if (!hasPublicDir) {
|
|
12717
|
-
hasPublicDir =
|
|
12937
|
+
hasPublicDir = fs24.existsSync(publicDir);
|
|
12718
12938
|
}
|
|
12719
12939
|
const host = req.headers.host ?? `localhost:${port}`;
|
|
12720
12940
|
const url = new URL(req.url ?? "/", `http://${host}`);
|
|
@@ -12988,22 +13208,22 @@ function createDashboardServer(opts) {
|
|
|
12988
13208
|
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>`);
|
|
12989
13209
|
return;
|
|
12990
13210
|
}
|
|
12991
|
-
let filePath =
|
|
13211
|
+
let filePath = path26.join(publicDir, pathname === "/" ? "index.html" : pathname);
|
|
12992
13212
|
if (!filePath.startsWith(publicDir)) {
|
|
12993
13213
|
notFound(res);
|
|
12994
13214
|
return;
|
|
12995
13215
|
}
|
|
12996
|
-
if (
|
|
12997
|
-
const ext2 =
|
|
13216
|
+
if (fs24.existsSync(filePath) && fs24.statSync(filePath).isFile()) {
|
|
13217
|
+
const ext2 = path26.extname(filePath);
|
|
12998
13218
|
const contentType = MIME[ext2] ?? "application/octet-stream";
|
|
12999
13219
|
res.writeHead(200, { "Content-Type": contentType });
|
|
13000
|
-
|
|
13220
|
+
fs24.createReadStream(filePath).pipe(res);
|
|
13001
13221
|
return;
|
|
13002
13222
|
}
|
|
13003
|
-
filePath =
|
|
13004
|
-
if (
|
|
13223
|
+
filePath = path26.join(publicDir, "index.html");
|
|
13224
|
+
if (fs24.existsSync(filePath)) {
|
|
13005
13225
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
13006
|
-
|
|
13226
|
+
fs24.createReadStream(filePath).pipe(res);
|
|
13007
13227
|
return;
|
|
13008
13228
|
}
|
|
13009
13229
|
notFound(res);
|
|
@@ -13034,16 +13254,16 @@ var init_server = __esm({
|
|
|
13034
13254
|
});
|
|
13035
13255
|
|
|
13036
13256
|
// ../core/dist/dashboard/state.js
|
|
13037
|
-
import * as
|
|
13257
|
+
import * as fs25 from "node:fs";
|
|
13038
13258
|
import * as os14 from "node:os";
|
|
13039
|
-
import * as
|
|
13259
|
+
import * as path27 from "node:path";
|
|
13040
13260
|
function saveDashboardState(state) {
|
|
13041
|
-
|
|
13042
|
-
|
|
13261
|
+
fs25.mkdirSync(path27.dirname(STATE_PATH), { recursive: true });
|
|
13262
|
+
fs25.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
|
|
13043
13263
|
}
|
|
13044
13264
|
function loadDashboardState() {
|
|
13045
13265
|
try {
|
|
13046
|
-
const raw =
|
|
13266
|
+
const raw = fs25.readFileSync(STATE_PATH, "utf-8");
|
|
13047
13267
|
return JSON.parse(raw);
|
|
13048
13268
|
} catch {
|
|
13049
13269
|
return null;
|
|
@@ -13051,7 +13271,7 @@ function loadDashboardState() {
|
|
|
13051
13271
|
}
|
|
13052
13272
|
function clearDashboardState() {
|
|
13053
13273
|
try {
|
|
13054
|
-
|
|
13274
|
+
fs25.unlinkSync(STATE_PATH);
|
|
13055
13275
|
} catch {
|
|
13056
13276
|
}
|
|
13057
13277
|
}
|
|
@@ -13071,7 +13291,7 @@ var STATE_PATH;
|
|
|
13071
13291
|
var init_state2 = __esm({
|
|
13072
13292
|
"../core/dist/dashboard/state.js"() {
|
|
13073
13293
|
"use strict";
|
|
13074
|
-
STATE_PATH =
|
|
13294
|
+
STATE_PATH = path27.join(os14.homedir(), ".olam", "dashboard.json");
|
|
13075
13295
|
}
|
|
13076
13296
|
});
|
|
13077
13297
|
|
|
@@ -13466,50 +13686,50 @@ __export(host_cp_exports, {
|
|
|
13466
13686
|
writeToken: () => writeToken
|
|
13467
13687
|
});
|
|
13468
13688
|
import * as crypto6 from "node:crypto";
|
|
13469
|
-
import * as
|
|
13689
|
+
import * as fs26 from "node:fs";
|
|
13470
13690
|
import * as os15 from "node:os";
|
|
13471
|
-
import * as
|
|
13691
|
+
import * as path28 from "node:path";
|
|
13472
13692
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
13473
13693
|
import Dockerode2 from "dockerode";
|
|
13474
13694
|
function findComposeFile() {
|
|
13475
13695
|
const candidates = [
|
|
13476
13696
|
// Bundled path: dist/index.js lives at <pkg>/dist/; host-cp/ is a sibling of dist/
|
|
13477
|
-
|
|
13697
|
+
path28.resolve(path28.dirname(new URL(import.meta.url).pathname), "../host-cp/compose.yaml"),
|
|
13478
13698
|
// Source-mode: cwd is monorepo root
|
|
13479
|
-
|
|
13699
|
+
path28.resolve(process.cwd(), "packages/host-cp/compose.yaml"),
|
|
13480
13700
|
// Source-mode: cwd is one level inside the monorepo
|
|
13481
|
-
|
|
13701
|
+
path28.resolve(process.cwd(), "../packages/host-cp/compose.yaml")
|
|
13482
13702
|
];
|
|
13483
13703
|
for (const c of candidates) {
|
|
13484
|
-
if (
|
|
13704
|
+
if (fs26.existsSync(c)) return c;
|
|
13485
13705
|
}
|
|
13486
|
-
return
|
|
13706
|
+
return path28.resolve(process.cwd(), "packages/host-cp/compose.yaml");
|
|
13487
13707
|
}
|
|
13488
|
-
function
|
|
13489
|
-
return process.env.OLAM_HOME ??
|
|
13708
|
+
function olamHome2() {
|
|
13709
|
+
return process.env.OLAM_HOME ?? path28.join(os15.homedir(), ".olam");
|
|
13490
13710
|
}
|
|
13491
13711
|
function tokenPath() {
|
|
13492
|
-
return
|
|
13712
|
+
return path28.join(olamHome2(), "host-cp.token");
|
|
13493
13713
|
}
|
|
13494
13714
|
function pidPath() {
|
|
13495
|
-
return
|
|
13715
|
+
return path28.join(olamHome2(), "host-cp.pid");
|
|
13496
13716
|
}
|
|
13497
13717
|
function authSecretPath() {
|
|
13498
|
-
return
|
|
13718
|
+
return path28.join(olamHome2(), "auth-secret");
|
|
13499
13719
|
}
|
|
13500
13720
|
function readAuthSecret2() {
|
|
13501
13721
|
const filePath = authSecretPath();
|
|
13502
|
-
if (!
|
|
13503
|
-
const raw =
|
|
13722
|
+
if (!fs26.existsSync(filePath)) return null;
|
|
13723
|
+
const raw = fs26.readFileSync(filePath, "utf-8").trim();
|
|
13504
13724
|
return raw.length > 0 ? raw : null;
|
|
13505
13725
|
}
|
|
13506
13726
|
function r2CredentialsPath() {
|
|
13507
|
-
return
|
|
13727
|
+
return path28.join(olamHome2(), "r2-credentials.json");
|
|
13508
13728
|
}
|
|
13509
13729
|
function readR2Credentials() {
|
|
13510
13730
|
const filePath = r2CredentialsPath();
|
|
13511
|
-
if (!
|
|
13512
|
-
const raw =
|
|
13731
|
+
if (!fs26.existsSync(filePath)) return null;
|
|
13732
|
+
const raw = fs26.readFileSync(filePath, "utf-8").trim();
|
|
13513
13733
|
if (raw.length === 0) return null;
|
|
13514
13734
|
try {
|
|
13515
13735
|
const parsed = JSON.parse(raw);
|
|
@@ -13532,37 +13752,37 @@ function readR2Credentials() {
|
|
|
13532
13752
|
function writeToken() {
|
|
13533
13753
|
const token = crypto6.randomBytes(32).toString("hex");
|
|
13534
13754
|
const filePath = tokenPath();
|
|
13535
|
-
|
|
13536
|
-
|
|
13755
|
+
fs26.mkdirSync(path28.dirname(filePath), { recursive: true });
|
|
13756
|
+
fs26.writeFileSync(filePath, token, { mode: 384 });
|
|
13537
13757
|
return token;
|
|
13538
13758
|
}
|
|
13539
13759
|
function readToken() {
|
|
13540
13760
|
const filePath = tokenPath();
|
|
13541
|
-
if (!
|
|
13542
|
-
return
|
|
13761
|
+
if (!fs26.existsSync(filePath)) return null;
|
|
13762
|
+
return fs26.readFileSync(filePath, "utf-8").trim();
|
|
13543
13763
|
}
|
|
13544
13764
|
function removeToken() {
|
|
13545
13765
|
const filePath = tokenPath();
|
|
13546
|
-
if (!
|
|
13547
|
-
|
|
13766
|
+
if (!fs26.existsSync(filePath)) return false;
|
|
13767
|
+
fs26.unlinkSync(filePath);
|
|
13548
13768
|
return true;
|
|
13549
13769
|
}
|
|
13550
13770
|
function writePid(pid) {
|
|
13551
13771
|
const filePath = pidPath();
|
|
13552
|
-
|
|
13553
|
-
|
|
13772
|
+
fs26.mkdirSync(path28.dirname(filePath), { recursive: true });
|
|
13773
|
+
fs26.writeFileSync(filePath, String(pid), { mode: 420 });
|
|
13554
13774
|
}
|
|
13555
13775
|
function readPid() {
|
|
13556
13776
|
const filePath = pidPath();
|
|
13557
|
-
if (!
|
|
13558
|
-
const raw =
|
|
13777
|
+
if (!fs26.existsSync(filePath)) return null;
|
|
13778
|
+
const raw = fs26.readFileSync(filePath, "utf-8").trim();
|
|
13559
13779
|
const n = parseInt(raw, 10);
|
|
13560
13780
|
return Number.isFinite(n) ? n : null;
|
|
13561
13781
|
}
|
|
13562
13782
|
function removePid() {
|
|
13563
13783
|
const filePath = pidPath();
|
|
13564
|
-
if (!
|
|
13565
|
-
|
|
13784
|
+
if (!fs26.existsSync(filePath)) return false;
|
|
13785
|
+
fs26.unlinkSync(filePath);
|
|
13566
13786
|
return true;
|
|
13567
13787
|
}
|
|
13568
13788
|
async function findHostCpContainer() {
|
|
@@ -13725,7 +13945,7 @@ async function handleStart(opts) {
|
|
|
13725
13945
|
}
|
|
13726
13946
|
const token = writeToken();
|
|
13727
13947
|
const composeFile = findComposeFile();
|
|
13728
|
-
if (!
|
|
13948
|
+
if (!fs26.existsSync(composeFile)) {
|
|
13729
13949
|
printError(`compose.yaml not found at ${composeFile}. Run from the olam project root.`);
|
|
13730
13950
|
removeToken();
|
|
13731
13951
|
process.exitCode = 1;
|
|
@@ -13807,7 +14027,7 @@ async function stopHostCp() {
|
|
|
13807
14027
|
}
|
|
13808
14028
|
async function handleStop() {
|
|
13809
14029
|
const composeFile = findComposeFile();
|
|
13810
|
-
if (!
|
|
14030
|
+
if (!fs26.existsSync(composeFile)) {
|
|
13811
14031
|
printWarning(`compose.yaml not found at ${composeFile}. Cleaning up token + PID anyway.`);
|
|
13812
14032
|
removeToken();
|
|
13813
14033
|
removePid();
|
|
@@ -13835,13 +14055,13 @@ async function buildStatusReport() {
|
|
|
13835
14055
|
const container = await findHostCpContainer();
|
|
13836
14056
|
const health = await probeHealth();
|
|
13837
14057
|
const tokenFile = tokenPath();
|
|
13838
|
-
const tokenPresent =
|
|
14058
|
+
const tokenPresent = fs26.existsSync(tokenFile);
|
|
13839
14059
|
let tokenModeOk = false;
|
|
13840
14060
|
if (tokenPresent) {
|
|
13841
|
-
const mode =
|
|
14061
|
+
const mode = fs26.statSync(tokenFile).mode & 511;
|
|
13842
14062
|
tokenModeOk = mode === 384;
|
|
13843
14063
|
}
|
|
13844
|
-
const pidPresent =
|
|
14064
|
+
const pidPresent = fs26.existsSync(pidPath());
|
|
13845
14065
|
let stack;
|
|
13846
14066
|
if (!container) {
|
|
13847
14067
|
stack = "not_started";
|
|
@@ -13929,13 +14149,13 @@ async function discoverWorldPort(worldId) {
|
|
|
13929
14149
|
}
|
|
13930
14150
|
async function readHostCpToken2() {
|
|
13931
14151
|
const tp = tokenPath();
|
|
13932
|
-
if (!
|
|
13933
|
-
return
|
|
14152
|
+
if (!fs26.existsSync(tp)) return null;
|
|
14153
|
+
return fs26.readFileSync(tp, "utf-8").trim();
|
|
13934
14154
|
}
|
|
13935
|
-
async function callHostCpProxy(method, worldId,
|
|
14155
|
+
async function callHostCpProxy(method, worldId, path56, body) {
|
|
13936
14156
|
const token = await readHostCpToken2();
|
|
13937
14157
|
if (!token) return { ok: false, status: 0, error: "no token (host CP not started)" };
|
|
13938
|
-
const url = `http://127.0.0.1:${HOST_CP_PORT}/api/world/${encodeURIComponent(worldId)}${
|
|
14158
|
+
const url = `http://127.0.0.1:${HOST_CP_PORT}/api/world/${encodeURIComponent(worldId)}${path56}`;
|
|
13939
14159
|
try {
|
|
13940
14160
|
const headers = {
|
|
13941
14161
|
Authorization: `Bearer ${token}`
|
|
@@ -14061,25 +14281,25 @@ __export(install_root_exports, {
|
|
|
14061
14281
|
isDevMode: () => isDevMode,
|
|
14062
14282
|
resolveBuildScript: () => resolveBuildScript
|
|
14063
14283
|
});
|
|
14064
|
-
import { existsSync as
|
|
14065
|
-
import { dirname as dirname17, join as
|
|
14284
|
+
import { existsSync as existsSync24 } from "node:fs";
|
|
14285
|
+
import { dirname as dirname17, join as join30, resolve as resolve9 } from "node:path";
|
|
14066
14286
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
14067
14287
|
function installRoot(metaUrl = import.meta.url) {
|
|
14068
14288
|
const here2 = fileURLToPath5(metaUrl);
|
|
14069
|
-
return
|
|
14289
|
+
return resolve9(dirname17(here2), "..");
|
|
14070
14290
|
}
|
|
14071
14291
|
function isDevMode(env = process.env, installRootDir = installRoot()) {
|
|
14072
14292
|
if (env.OLAM_DEV !== "1") return false;
|
|
14073
|
-
const repoRoot =
|
|
14074
|
-
return
|
|
14293
|
+
const repoRoot = resolve9(installRootDir, "..", "..");
|
|
14294
|
+
return existsSync24(join30(repoRoot, "packages")) && existsSync24(join30(repoRoot, "package.json"));
|
|
14075
14295
|
}
|
|
14076
14296
|
function resolveBuildScript(input) {
|
|
14077
14297
|
const { scriptRelPath, env = process.env, installRootDir = installRoot() } = input;
|
|
14078
14298
|
if (!isDevMode(env, installRootDir)) {
|
|
14079
14299
|
throw new MissingBuildScriptError(scriptRelPath);
|
|
14080
14300
|
}
|
|
14081
|
-
const repoRoot =
|
|
14082
|
-
return
|
|
14301
|
+
const repoRoot = resolve9(installRootDir, "..", "..");
|
|
14302
|
+
return join30(repoRoot, scriptRelPath);
|
|
14083
14303
|
}
|
|
14084
14304
|
var MissingBuildScriptError;
|
|
14085
14305
|
var init_install_root = __esm({
|
|
@@ -14250,20 +14470,20 @@ var init_registry_allowlist = __esm({
|
|
|
14250
14470
|
});
|
|
14251
14471
|
|
|
14252
14472
|
// ../core/dist/world/world-yaml.js
|
|
14253
|
-
import * as
|
|
14254
|
-
import * as
|
|
14473
|
+
import * as fs28 from "node:fs";
|
|
14474
|
+
import * as path30 from "node:path";
|
|
14255
14475
|
import { parse as parseYaml4, stringify as stringifyYaml4 } from "yaml";
|
|
14256
14476
|
function writeWorldYaml(worldPath, data) {
|
|
14257
|
-
const olamDir =
|
|
14258
|
-
|
|
14259
|
-
|
|
14477
|
+
const olamDir = path30.join(worldPath, ".olam");
|
|
14478
|
+
fs28.mkdirSync(olamDir, { recursive: true });
|
|
14479
|
+
fs28.writeFileSync(path30.join(olamDir, "world.yaml"), stringifyYaml4(data), "utf-8");
|
|
14260
14480
|
}
|
|
14261
14481
|
function readWorldYaml(worldPath) {
|
|
14262
|
-
const yamlPath =
|
|
14263
|
-
if (!
|
|
14482
|
+
const yamlPath = path30.join(worldPath, ".olam", "world.yaml");
|
|
14483
|
+
if (!fs28.existsSync(yamlPath))
|
|
14264
14484
|
return null;
|
|
14265
14485
|
try {
|
|
14266
|
-
const raw =
|
|
14486
|
+
const raw = fs28.readFileSync(yamlPath, "utf-8");
|
|
14267
14487
|
const parsed = parseYaml4(raw);
|
|
14268
14488
|
return WorldYamlSchema.parse(parsed);
|
|
14269
14489
|
} catch {
|
|
@@ -14394,16 +14614,16 @@ __export(machine_schema_exports, {
|
|
|
14394
14614
|
readMachineConfig: () => readMachineConfig,
|
|
14395
14615
|
writeMachineConfig: () => writeMachineConfig
|
|
14396
14616
|
});
|
|
14397
|
-
import * as
|
|
14398
|
-
import * as
|
|
14617
|
+
import * as fs42 from "node:fs";
|
|
14618
|
+
import * as path48 from "node:path";
|
|
14399
14619
|
import * as os24 from "node:os";
|
|
14400
14620
|
import { parse as parseYaml5, stringify as stringifyYaml5 } from "yaml";
|
|
14401
14621
|
function readMachineConfig(configPath) {
|
|
14402
14622
|
const p = configPath ?? DEFAULT_CONFIG_PATH;
|
|
14403
|
-
if (!
|
|
14623
|
+
if (!fs42.existsSync(p))
|
|
14404
14624
|
return null;
|
|
14405
14625
|
try {
|
|
14406
|
-
const raw =
|
|
14626
|
+
const raw = fs42.readFileSync(p, "utf-8");
|
|
14407
14627
|
const parsed = parseYaml5(raw);
|
|
14408
14628
|
return MachineConfigSchema.parse(parsed);
|
|
14409
14629
|
} catch {
|
|
@@ -14412,8 +14632,8 @@ function readMachineConfig(configPath) {
|
|
|
14412
14632
|
}
|
|
14413
14633
|
function writeMachineConfig(config, configPath) {
|
|
14414
14634
|
const p = configPath ?? DEFAULT_CONFIG_PATH;
|
|
14415
|
-
|
|
14416
|
-
|
|
14635
|
+
fs42.mkdirSync(path48.dirname(p), { recursive: true });
|
|
14636
|
+
fs42.writeFileSync(p, stringifyYaml5({ ...config }), { mode: 420 });
|
|
14417
14637
|
}
|
|
14418
14638
|
function initMachineConfig(opts = {}) {
|
|
14419
14639
|
const configPath = opts.configPath ?? DEFAULT_CONFIG_PATH;
|
|
@@ -14436,9 +14656,9 @@ var init_machine_schema = __esm({
|
|
|
14436
14656
|
channel: external_exports.enum(["stable", "beta", "edge"]).default("stable"),
|
|
14437
14657
|
auto_update: external_exports.boolean().default(true),
|
|
14438
14658
|
telemetry: external_exports.boolean().default(true),
|
|
14439
|
-
worlds_dir: external_exports.string().default(() =>
|
|
14659
|
+
worlds_dir: external_exports.string().default(() => path48.join(os24.homedir(), ".olam", "worlds"))
|
|
14440
14660
|
});
|
|
14441
|
-
DEFAULT_CONFIG_PATH =
|
|
14661
|
+
DEFAULT_CONFIG_PATH = path48.join(os24.homedir(), ".olam", "config.yaml");
|
|
14442
14662
|
}
|
|
14443
14663
|
});
|
|
14444
14664
|
|
|
@@ -14820,9 +15040,9 @@ var UnknownArchetypeError = class extends Error {
|
|
|
14820
15040
|
};
|
|
14821
15041
|
var ArchetypeCycleError = class extends Error {
|
|
14822
15042
|
path;
|
|
14823
|
-
constructor(
|
|
14824
|
-
super(`Archetype inheritance cycle detected: ${
|
|
14825
|
-
this.path =
|
|
15043
|
+
constructor(path56) {
|
|
15044
|
+
super(`Archetype inheritance cycle detected: ${path56.join(" \u2192 ")} \u2192 ${path56[0] ?? "?"}`);
|
|
15045
|
+
this.path = path56;
|
|
14826
15046
|
this.name = "ArchetypeCycleError";
|
|
14827
15047
|
}
|
|
14828
15048
|
};
|
|
@@ -15034,8 +15254,8 @@ var LOCAL_DATA_DIR = path10.join(os5.homedir(), ".olam", "auth-data");
|
|
|
15034
15254
|
init_output();
|
|
15035
15255
|
init_host_cp();
|
|
15036
15256
|
init_auth();
|
|
15037
|
-
import * as
|
|
15038
|
-
import * as
|
|
15257
|
+
import * as fs27 from "node:fs";
|
|
15258
|
+
import * as path29 from "node:path";
|
|
15039
15259
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
15040
15260
|
import ora2 from "ora";
|
|
15041
15261
|
import pc7 from "picocolors";
|
|
@@ -15047,20 +15267,20 @@ init_exit_codes();
|
|
|
15047
15267
|
init_protocol_version();
|
|
15048
15268
|
init_output();
|
|
15049
15269
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
15050
|
-
import { existsSync as
|
|
15051
|
-
import { join as
|
|
15270
|
+
import { existsSync as existsSync25, readFileSync as readFileSync19 } from "node:fs";
|
|
15271
|
+
import { join as join31 } from "node:path";
|
|
15052
15272
|
import ora from "ora";
|
|
15053
15273
|
import pc6 from "picocolors";
|
|
15054
15274
|
function loadImageDigests(installRootDir = installRoot()) {
|
|
15055
|
-
const digestsPath =
|
|
15056
|
-
if (!
|
|
15275
|
+
const digestsPath = join31(installRootDir, "dist", "image-digests.json");
|
|
15276
|
+
if (!existsSync25(digestsPath)) {
|
|
15057
15277
|
throw new Error(
|
|
15058
15278
|
`image-digests.json missing at ${digestsPath}. Re-run \`npm install -g @pleri/olam-cli@<version>\` to refresh the tarball.`
|
|
15059
15279
|
);
|
|
15060
15280
|
}
|
|
15061
15281
|
let parsed;
|
|
15062
15282
|
try {
|
|
15063
|
-
parsed = JSON.parse(
|
|
15283
|
+
parsed = JSON.parse(readFileSync19(digestsPath, "utf8"));
|
|
15064
15284
|
} catch (err) {
|
|
15065
15285
|
throw new Error(`image-digests.json is not valid JSON: ${err.message}`);
|
|
15066
15286
|
}
|
|
@@ -15316,8 +15536,8 @@ function parseAuthUpgradeOpts(raw) {
|
|
|
15316
15536
|
};
|
|
15317
15537
|
}
|
|
15318
15538
|
function validateAuthRepoRoot(cwd) {
|
|
15319
|
-
const marker =
|
|
15320
|
-
if (!
|
|
15539
|
+
const marker = path29.join(cwd, "packages/auth-service/Dockerfile");
|
|
15540
|
+
if (!fs27.existsSync(marker)) {
|
|
15321
15541
|
return {
|
|
15322
15542
|
ok: false,
|
|
15323
15543
|
error: `Not an olam repo root (expected ${marker}).
|
|
@@ -15687,7 +15907,7 @@ function registerAuthUpgrade(auth) {
|
|
|
15687
15907
|
// src/commands/services.ts
|
|
15688
15908
|
init_auth();
|
|
15689
15909
|
init_output();
|
|
15690
|
-
import { execFileSync as
|
|
15910
|
+
import { execFileSync as execFileSync7, spawnSync as spawnSync8 } from "node:child_process";
|
|
15691
15911
|
import pc8 from "picocolors";
|
|
15692
15912
|
var MCP_AUTH_PORT = 9998;
|
|
15693
15913
|
var MCP_AUTH_VOLUME = "olam-mcp-auth-data";
|
|
@@ -15721,7 +15941,7 @@ var McpAuthContainerController = class {
|
|
|
15721
15941
|
const current = this.status();
|
|
15722
15942
|
if (current.state === "running") return;
|
|
15723
15943
|
if (current.state === "stopped") {
|
|
15724
|
-
|
|
15944
|
+
execFileSync7("docker", ["start", MCP_AUTH_CONTAINER], { stdio: "pipe" });
|
|
15725
15945
|
return;
|
|
15726
15946
|
}
|
|
15727
15947
|
if (!this.imageExists()) {
|
|
@@ -15733,7 +15953,7 @@ var McpAuthContainerController = class {
|
|
|
15733
15953
|
);
|
|
15734
15954
|
}
|
|
15735
15955
|
}
|
|
15736
|
-
|
|
15956
|
+
execFileSync7(
|
|
15737
15957
|
"docker",
|
|
15738
15958
|
[
|
|
15739
15959
|
"run",
|
|
@@ -15754,7 +15974,7 @@ var McpAuthContainerController = class {
|
|
|
15754
15974
|
stop() {
|
|
15755
15975
|
const current = this.status();
|
|
15756
15976
|
if (current.state !== "running") return;
|
|
15757
|
-
|
|
15977
|
+
execFileSync7("docker", ["stop", MCP_AUTH_CONTAINER], { stdio: "pipe" });
|
|
15758
15978
|
}
|
|
15759
15979
|
remove() {
|
|
15760
15980
|
spawnSync8("docker", ["rm", "-f", MCP_AUTH_CONTAINER], { stdio: "pipe" });
|
|
@@ -16051,15 +16271,15 @@ ${pc9.dim("Next: olam create --name my-world")}`);
|
|
|
16051
16271
|
// src/commands/create.ts
|
|
16052
16272
|
init_manager();
|
|
16053
16273
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
16054
|
-
import { existsSync as
|
|
16055
|
-
import { dirname as dirname18, resolve as
|
|
16274
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
16275
|
+
import { dirname as dirname18, resolve as resolve10 } from "node:path";
|
|
16056
16276
|
import ora3 from "ora";
|
|
16057
16277
|
import pc10 from "picocolors";
|
|
16058
16278
|
|
|
16059
16279
|
// ../core/dist/world/devbox-freshness.js
|
|
16060
16280
|
import { execSync as execSync7 } from "node:child_process";
|
|
16061
|
-
import { existsSync as
|
|
16062
|
-
import { join as
|
|
16281
|
+
import { existsSync as existsSync27, statSync as statSync6 } from "node:fs";
|
|
16282
|
+
import { join as join33 } from "node:path";
|
|
16063
16283
|
var DEFAULT_DEVBOX_IMAGE = "olam-devbox:base";
|
|
16064
16284
|
var DEVBOX_BAKED_SOURCES = [
|
|
16065
16285
|
"packages/adapters/src/docker/devbox.base.Dockerfile",
|
|
@@ -16096,7 +16316,7 @@ function getDevboxFreshness(deps) {
|
|
|
16096
16316
|
}
|
|
16097
16317
|
const newerSources = [];
|
|
16098
16318
|
for (const relPath of DEVBOX_BAKED_SOURCES) {
|
|
16099
|
-
const absPath =
|
|
16319
|
+
const absPath = join33(deps.repoRoot, relPath);
|
|
16100
16320
|
const mtimeMs = statMtime(absPath);
|
|
16101
16321
|
if (mtimeMs === null)
|
|
16102
16322
|
continue;
|
|
@@ -16128,9 +16348,9 @@ function formatFreshnessWarning(result, image = DEFAULT_DEVBOX_IMAGE) {
|
|
|
16128
16348
|
"These source files have changed since the image was built; the",
|
|
16129
16349
|
"changes will NOT take effect in fresh worlds until you rebuild:"
|
|
16130
16350
|
];
|
|
16131
|
-
for (const { path:
|
|
16351
|
+
for (const { path: path56, mtimeMs } of result.newerSources) {
|
|
16132
16352
|
const when = new Date(mtimeMs).toISOString();
|
|
16133
|
-
lines.push(` \u2022 ${
|
|
16353
|
+
lines.push(` \u2022 ${path56} (modified ${when})`);
|
|
16134
16354
|
}
|
|
16135
16355
|
lines.push("");
|
|
16136
16356
|
lines.push("Rebuild with:");
|
|
@@ -16149,7 +16369,7 @@ function defaultDockerInspect(image) {
|
|
|
16149
16369
|
}
|
|
16150
16370
|
function defaultStatMtime(absPath) {
|
|
16151
16371
|
try {
|
|
16152
|
-
if (!
|
|
16372
|
+
if (!existsSync27(absPath))
|
|
16153
16373
|
return null;
|
|
16154
16374
|
return statSync6(absPath).mtimeMs;
|
|
16155
16375
|
} catch {
|
|
@@ -16289,15 +16509,15 @@ init_host_cp();
|
|
|
16289
16509
|
var HOST_CP_URL = "http://127.0.0.1:19000";
|
|
16290
16510
|
async function readHostCpTokenForCreate() {
|
|
16291
16511
|
try {
|
|
16292
|
-
const { default:
|
|
16512
|
+
const { default: fs51 } = await import("node:fs");
|
|
16293
16513
|
const { default: os28 } = await import("node:os");
|
|
16294
|
-
const { default:
|
|
16295
|
-
const tp =
|
|
16296
|
-
process.env.OLAM_HOME ??
|
|
16514
|
+
const { default: path56 } = await import("node:path");
|
|
16515
|
+
const tp = path56.join(
|
|
16516
|
+
process.env.OLAM_HOME ?? path56.join(os28.homedir(), ".olam"),
|
|
16297
16517
|
"host-cp.token"
|
|
16298
16518
|
);
|
|
16299
|
-
if (!
|
|
16300
|
-
return
|
|
16519
|
+
if (!fs51.existsSync(tp)) return null;
|
|
16520
|
+
return fs51.readFileSync(tp, "utf-8").trim();
|
|
16301
16521
|
} catch {
|
|
16302
16522
|
return null;
|
|
16303
16523
|
}
|
|
@@ -16646,7 +16866,7 @@ ${pc10.cyan("Host CP UI:")} ${worldUrl}`);
|
|
|
16646
16866
|
function resolveRepoRoot(start) {
|
|
16647
16867
|
let cur = start;
|
|
16648
16868
|
while (true) {
|
|
16649
|
-
if (
|
|
16869
|
+
if (existsSync28(resolve10(cur, "packages")) && existsSync28(resolve10(cur, "package.json"))) {
|
|
16650
16870
|
return cur;
|
|
16651
16871
|
}
|
|
16652
16872
|
const parent = dirname18(cur);
|
|
@@ -16660,12 +16880,12 @@ function defaultNameFromPrompt(prompt) {
|
|
|
16660
16880
|
}
|
|
16661
16881
|
async function readHostCpToken3() {
|
|
16662
16882
|
try {
|
|
16663
|
-
const { default:
|
|
16883
|
+
const { default: fs51 } = await import("node:fs");
|
|
16664
16884
|
const { default: os28 } = await import("node:os");
|
|
16665
|
-
const { default:
|
|
16666
|
-
const tp =
|
|
16667
|
-
if (!
|
|
16668
|
-
const raw =
|
|
16885
|
+
const { default: path56 } = await import("node:path");
|
|
16886
|
+
const tp = path56.join(os28.homedir(), ".olam", "host-cp.token");
|
|
16887
|
+
if (!fs51.existsSync(tp)) return null;
|
|
16888
|
+
const raw = fs51.readFileSync(tp, "utf-8").trim();
|
|
16669
16889
|
return raw.length > 0 ? raw : null;
|
|
16670
16890
|
} catch {
|
|
16671
16891
|
return null;
|
|
@@ -16877,9 +17097,9 @@ function registerList(program2) {
|
|
|
16877
17097
|
|
|
16878
17098
|
// src/commands/status.ts
|
|
16879
17099
|
init_output();
|
|
16880
|
-
import * as
|
|
17100
|
+
import * as fs29 from "node:fs";
|
|
16881
17101
|
import * as os16 from "node:os";
|
|
16882
|
-
import * as
|
|
17102
|
+
import * as path31 from "node:path";
|
|
16883
17103
|
var CLI_VERSION2 = process.env["OLAM_CLI_VERSION"] ?? "0.0.0";
|
|
16884
17104
|
var HOST_CP_PORT2 = 19e3;
|
|
16885
17105
|
async function getMachineStatus(_probe, _loadCtx, _readToken) {
|
|
@@ -16909,14 +17129,14 @@ async function getMachineStatus(_probe, _loadCtx, _readToken) {
|
|
|
16909
17129
|
}
|
|
16910
17130
|
} catch {
|
|
16911
17131
|
}
|
|
16912
|
-
const manifestPath2 =
|
|
17132
|
+
const manifestPath2 = path31.join(os16.homedir(), ".olam", "cache", "manifest.json");
|
|
16913
17133
|
let updateAvailable = null;
|
|
16914
17134
|
let lastUpdateCheck = null;
|
|
16915
|
-
if (
|
|
16916
|
-
const mtime =
|
|
17135
|
+
if (fs29.existsSync(manifestPath2)) {
|
|
17136
|
+
const mtime = fs29.statSync(manifestPath2).mtime;
|
|
16917
17137
|
lastUpdateCheck = mtime.toISOString();
|
|
16918
17138
|
try {
|
|
16919
|
-
const manifest = JSON.parse(
|
|
17139
|
+
const manifest = JSON.parse(fs29.readFileSync(manifestPath2, "utf-8"));
|
|
16920
17140
|
const latest = manifest["version"];
|
|
16921
17141
|
updateAvailable = latest !== void 0 && latest !== CLI_VERSION2;
|
|
16922
17142
|
} catch {
|
|
@@ -17039,10 +17259,10 @@ function registerDestroy(program2) {
|
|
|
17039
17259
|
// src/commands/clean.ts
|
|
17040
17260
|
init_context();
|
|
17041
17261
|
init_output();
|
|
17042
|
-
import
|
|
17262
|
+
import fs30 from "node:fs";
|
|
17043
17263
|
import os17 from "node:os";
|
|
17044
|
-
import
|
|
17045
|
-
import { execFileSync as
|
|
17264
|
+
import path32 from "node:path";
|
|
17265
|
+
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
17046
17266
|
function registerClean(program2) {
|
|
17047
17267
|
program2.command("clean").description("Reap orphan world filesystem state under ~/.olam/worlds/").option("--apply", "Actually delete the orphans (default is dry-run)", false).option(
|
|
17048
17268
|
"--include-dirty",
|
|
@@ -17065,8 +17285,8 @@ async function runClean(opts) {
|
|
|
17065
17285
|
printError(error?.message ?? "Olam is not configured. Run `olam init` first.");
|
|
17066
17286
|
return 1;
|
|
17067
17287
|
}
|
|
17068
|
-
const worldsDir =
|
|
17069
|
-
if (!
|
|
17288
|
+
const worldsDir = path32.join(os17.homedir(), ".olam", "worlds");
|
|
17289
|
+
if (!fs30.existsSync(worldsDir)) {
|
|
17070
17290
|
if (opts.json) {
|
|
17071
17291
|
process.stdout.write(`${JSON.stringify({ worldsDir, entries: [] })}
|
|
17072
17292
|
`);
|
|
@@ -17081,8 +17301,8 @@ async function runClean(opts) {
|
|
|
17081
17301
|
}
|
|
17082
17302
|
const worktreeMap = collectWorktrees(worldsDir);
|
|
17083
17303
|
const entries = [];
|
|
17084
|
-
for (const id of
|
|
17085
|
-
const fullPath =
|
|
17304
|
+
for (const id of fs30.readdirSync(worldsDir).sort()) {
|
|
17305
|
+
const fullPath = path32.join(worldsDir, id);
|
|
17086
17306
|
const stat = safeStat(fullPath);
|
|
17087
17307
|
if (!stat || !stat.isDirectory()) continue;
|
|
17088
17308
|
entries.push(classifyWorld({ id, fullPath, liveIds, worktreeMap }));
|
|
@@ -17148,7 +17368,7 @@ function classifyWorld(args) {
|
|
|
17148
17368
|
if (liveIds.has(id)) {
|
|
17149
17369
|
return { id, path: fullPath, bytes, category: "active", note: "in registry" };
|
|
17150
17370
|
}
|
|
17151
|
-
const worktreeChild =
|
|
17371
|
+
const worktreeChild = path32.join(fullPath, "olam");
|
|
17152
17372
|
const worktreeInfo = worktreeMap.get(worktreeChild);
|
|
17153
17373
|
if (worktreeInfo) {
|
|
17154
17374
|
if (worktreeInfo.dirty > 0 || worktreeInfo.unpushed > 0) {
|
|
@@ -17185,7 +17405,7 @@ function reapEntry(entry) {
|
|
|
17185
17405
|
try {
|
|
17186
17406
|
const gitDir = resolveGitDirForWorktree(entry.worktreePath);
|
|
17187
17407
|
if (gitDir) {
|
|
17188
|
-
|
|
17408
|
+
execFileSync8("git", ["worktree", "remove", "--force", entry.worktreePath], {
|
|
17189
17409
|
cwd: gitDir,
|
|
17190
17410
|
stdio: "pipe"
|
|
17191
17411
|
});
|
|
@@ -17194,20 +17414,20 @@ function reapEntry(entry) {
|
|
|
17194
17414
|
}
|
|
17195
17415
|
}
|
|
17196
17416
|
try {
|
|
17197
|
-
|
|
17417
|
+
fs30.rmSync(entry.path, { recursive: true, force: true });
|
|
17198
17418
|
} catch (err) {
|
|
17199
17419
|
process.stderr.write(` ! rm ${entry.path}: ${err instanceof Error ? err.message : String(err)}
|
|
17200
17420
|
`);
|
|
17201
17421
|
return false;
|
|
17202
17422
|
}
|
|
17203
|
-
return !
|
|
17423
|
+
return !fs30.existsSync(entry.path);
|
|
17204
17424
|
}
|
|
17205
17425
|
function collectWorktrees(worldsDir) {
|
|
17206
17426
|
const out = /* @__PURE__ */ new Map();
|
|
17207
|
-
for (const id of
|
|
17208
|
-
const child =
|
|
17209
|
-
const gitMarker =
|
|
17210
|
-
if (!
|
|
17427
|
+
for (const id of fs30.readdirSync(worldsDir)) {
|
|
17428
|
+
const child = path32.join(worldsDir, id, "olam");
|
|
17429
|
+
const gitMarker = path32.join(child, ".git");
|
|
17430
|
+
if (!fs30.existsSync(gitMarker)) continue;
|
|
17211
17431
|
const gitDir = resolveGitDirForWorktree(child);
|
|
17212
17432
|
if (!gitDir) continue;
|
|
17213
17433
|
const branch = readBranch(child);
|
|
@@ -17218,21 +17438,21 @@ function collectWorktrees(worldsDir) {
|
|
|
17218
17438
|
return out;
|
|
17219
17439
|
}
|
|
17220
17440
|
function resolveGitDirForWorktree(worktreePath) {
|
|
17221
|
-
const gitMarker =
|
|
17441
|
+
const gitMarker = path32.join(worktreePath, ".git");
|
|
17222
17442
|
try {
|
|
17223
|
-
const top =
|
|
17443
|
+
const top = execFileSync8("git", ["rev-parse", "--show-toplevel"], {
|
|
17224
17444
|
cwd: worktreePath,
|
|
17225
17445
|
encoding: "utf-8",
|
|
17226
17446
|
stdio: "pipe"
|
|
17227
17447
|
}).trim();
|
|
17228
17448
|
if (!top) return null;
|
|
17229
|
-
const common =
|
|
17449
|
+
const common = execFileSync8("git", ["rev-parse", "--git-common-dir"], {
|
|
17230
17450
|
cwd: worktreePath,
|
|
17231
17451
|
encoding: "utf-8",
|
|
17232
17452
|
stdio: "pipe"
|
|
17233
17453
|
}).trim();
|
|
17234
17454
|
if (!common) return top;
|
|
17235
|
-
return
|
|
17455
|
+
return path32.dirname(path32.resolve(worktreePath, common));
|
|
17236
17456
|
} catch {
|
|
17237
17457
|
return null;
|
|
17238
17458
|
}
|
|
@@ -17240,7 +17460,7 @@ function resolveGitDirForWorktree(worktreePath) {
|
|
|
17240
17460
|
}
|
|
17241
17461
|
function readBranch(worktreePath) {
|
|
17242
17462
|
try {
|
|
17243
|
-
return
|
|
17463
|
+
return execFileSync8("git", ["branch", "--show-current"], {
|
|
17244
17464
|
cwd: worktreePath,
|
|
17245
17465
|
encoding: "utf-8",
|
|
17246
17466
|
stdio: "pipe"
|
|
@@ -17251,7 +17471,7 @@ function readBranch(worktreePath) {
|
|
|
17251
17471
|
}
|
|
17252
17472
|
function countDirty(worktreePath) {
|
|
17253
17473
|
try {
|
|
17254
|
-
const out =
|
|
17474
|
+
const out = execFileSync8("git", ["status", "--porcelain"], {
|
|
17255
17475
|
cwd: worktreePath,
|
|
17256
17476
|
encoding: "utf-8",
|
|
17257
17477
|
stdio: "pipe"
|
|
@@ -17263,7 +17483,7 @@ function countDirty(worktreePath) {
|
|
|
17263
17483
|
}
|
|
17264
17484
|
function countUnpushed(worktreePath) {
|
|
17265
17485
|
try {
|
|
17266
|
-
const out =
|
|
17486
|
+
const out = execFileSync8("git", ["log", "@{u}..HEAD", "--oneline"], {
|
|
17267
17487
|
cwd: worktreePath,
|
|
17268
17488
|
encoding: "utf-8",
|
|
17269
17489
|
stdio: "pipe"
|
|
@@ -17275,7 +17495,7 @@ function countUnpushed(worktreePath) {
|
|
|
17275
17495
|
}
|
|
17276
17496
|
function safeStat(p) {
|
|
17277
17497
|
try {
|
|
17278
|
-
return
|
|
17498
|
+
return fs30.statSync(p);
|
|
17279
17499
|
} catch {
|
|
17280
17500
|
return null;
|
|
17281
17501
|
}
|
|
@@ -17287,7 +17507,7 @@ function computeBytes(p) {
|
|
|
17287
17507
|
const cur = stack.pop();
|
|
17288
17508
|
let st;
|
|
17289
17509
|
try {
|
|
17290
|
-
st =
|
|
17510
|
+
st = fs30.lstatSync(cur);
|
|
17291
17511
|
} catch {
|
|
17292
17512
|
continue;
|
|
17293
17513
|
}
|
|
@@ -17295,11 +17515,11 @@ function computeBytes(p) {
|
|
|
17295
17515
|
if (st.isDirectory()) {
|
|
17296
17516
|
let entries;
|
|
17297
17517
|
try {
|
|
17298
|
-
entries =
|
|
17518
|
+
entries = fs30.readdirSync(cur);
|
|
17299
17519
|
} catch {
|
|
17300
17520
|
continue;
|
|
17301
17521
|
}
|
|
17302
|
-
for (const name of entries) stack.push(
|
|
17522
|
+
for (const name of entries) stack.push(path32.join(cur, name));
|
|
17303
17523
|
} else {
|
|
17304
17524
|
total += st.size;
|
|
17305
17525
|
}
|
|
@@ -17350,16 +17570,16 @@ async function confirmInteractive() {
|
|
|
17350
17570
|
|
|
17351
17571
|
// src/commands/implode.ts
|
|
17352
17572
|
init_output();
|
|
17353
|
-
import { execFileSync as
|
|
17354
|
-
import * as
|
|
17573
|
+
import { execFileSync as execFileSync9 } from "node:child_process";
|
|
17574
|
+
import * as fs31 from "node:fs";
|
|
17355
17575
|
import * as os18 from "node:os";
|
|
17356
|
-
import * as
|
|
17576
|
+
import * as path33 from "node:path";
|
|
17357
17577
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
17358
17578
|
import pc14 from "picocolors";
|
|
17359
17579
|
var NPM_PACKAGE = "@pleri/olam-cli";
|
|
17360
17580
|
var realExec = (cmd, args) => {
|
|
17361
17581
|
try {
|
|
17362
|
-
const stdout =
|
|
17582
|
+
const stdout = execFileSync9(cmd, [...args], {
|
|
17363
17583
|
encoding: "utf-8",
|
|
17364
17584
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17365
17585
|
});
|
|
@@ -17375,7 +17595,7 @@ var realExec = (cmd, args) => {
|
|
|
17375
17595
|
};
|
|
17376
17596
|
function surveyOlam(opts = {}) {
|
|
17377
17597
|
const exec = opts.exec ?? realExec;
|
|
17378
|
-
const home = opts.olamHome ??
|
|
17598
|
+
const home = opts.olamHome ?? path33.join(os18.homedir(), ".olam");
|
|
17379
17599
|
const containers = listDocker(exec, ["ps", "-a", "--format", "{{.Names}}"]).filter(
|
|
17380
17600
|
(n) => n.startsWith("olam-")
|
|
17381
17601
|
);
|
|
@@ -17389,20 +17609,20 @@ function surveyOlam(opts = {}) {
|
|
|
17389
17609
|
(n) => n.startsWith("olam-") && n !== "olam-host-cp-internal-default"
|
|
17390
17610
|
);
|
|
17391
17611
|
const worlds = [];
|
|
17392
|
-
const worldsDir =
|
|
17393
|
-
if (
|
|
17394
|
-
for (const entry of
|
|
17612
|
+
const worldsDir = path33.join(home, "worlds");
|
|
17613
|
+
if (fs31.existsSync(worldsDir)) {
|
|
17614
|
+
for (const entry of fs31.readdirSync(worldsDir, { withFileTypes: true })) {
|
|
17395
17615
|
if (!entry.isDirectory()) continue;
|
|
17396
|
-
const wPath =
|
|
17616
|
+
const wPath = path33.join(worldsDir, entry.name);
|
|
17397
17617
|
const bytes = dirSize(wPath);
|
|
17398
17618
|
const { dirty, note } = inspectWorldGitState(wPath);
|
|
17399
17619
|
worlds.push({ id: entry.name, bytes, dirty, note, path: wPath });
|
|
17400
17620
|
}
|
|
17401
17621
|
}
|
|
17402
|
-
const homeBytesNonWorld =
|
|
17622
|
+
const homeBytesNonWorld = fs31.existsSync(home) ? Math.max(0, dirSize(home) - worlds.reduce((acc, w) => acc + w.bytes, 0)) : 0;
|
|
17403
17623
|
const npmRoot = exec("npm", ["root", "-g"]);
|
|
17404
17624
|
const npmGlobalRoot = npmRoot.exitCode === 0 ? npmRoot.stdout.trim() : null;
|
|
17405
|
-
const npmInstalled = npmGlobalRoot !== null &&
|
|
17625
|
+
const npmInstalled = npmGlobalRoot !== null && fs31.existsSync(path33.join(npmGlobalRoot, NPM_PACKAGE));
|
|
17406
17626
|
return {
|
|
17407
17627
|
containers,
|
|
17408
17628
|
images,
|
|
@@ -17427,15 +17647,15 @@ function dirSize(p) {
|
|
|
17427
17647
|
const cur = stack.pop();
|
|
17428
17648
|
let entries;
|
|
17429
17649
|
try {
|
|
17430
|
-
entries =
|
|
17650
|
+
entries = fs31.readdirSync(cur, { withFileTypes: true });
|
|
17431
17651
|
} catch {
|
|
17432
17652
|
continue;
|
|
17433
17653
|
}
|
|
17434
17654
|
for (const e of entries) {
|
|
17435
|
-
const full =
|
|
17655
|
+
const full = path33.join(cur, e.name);
|
|
17436
17656
|
try {
|
|
17437
17657
|
if (e.isDirectory()) stack.push(full);
|
|
17438
|
-
else if (e.isFile()) total +=
|
|
17658
|
+
else if (e.isFile()) total += fs31.statSync(full).size;
|
|
17439
17659
|
} catch {
|
|
17440
17660
|
}
|
|
17441
17661
|
}
|
|
@@ -17448,13 +17668,13 @@ function inspectWorldGitState(worldPath) {
|
|
|
17448
17668
|
const repoNotes = [];
|
|
17449
17669
|
let dirty = false;
|
|
17450
17670
|
try {
|
|
17451
|
-
for (const entry of
|
|
17671
|
+
for (const entry of fs31.readdirSync(worldPath, { withFileTypes: true })) {
|
|
17452
17672
|
if (!entry.isDirectory()) continue;
|
|
17453
|
-
const repo =
|
|
17454
|
-
const gitDir =
|
|
17455
|
-
if (!
|
|
17673
|
+
const repo = path33.join(worldPath, entry.name);
|
|
17674
|
+
const gitDir = path33.join(repo, ".git");
|
|
17675
|
+
if (!fs31.existsSync(gitDir)) continue;
|
|
17456
17676
|
try {
|
|
17457
|
-
const status =
|
|
17677
|
+
const status = execFileSync9("git", ["status", "--porcelain"], {
|
|
17458
17678
|
cwd: repo,
|
|
17459
17679
|
encoding: "utf-8",
|
|
17460
17680
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -17468,7 +17688,7 @@ function inspectWorldGitState(worldPath) {
|
|
|
17468
17688
|
continue;
|
|
17469
17689
|
}
|
|
17470
17690
|
try {
|
|
17471
|
-
const ahead =
|
|
17691
|
+
const ahead = execFileSync9(
|
|
17472
17692
|
"git",
|
|
17473
17693
|
["rev-list", "--count", "@{upstream}..HEAD"],
|
|
17474
17694
|
{ cwd: repo, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }
|
|
@@ -17545,7 +17765,7 @@ function formatBytes2(n) {
|
|
|
17545
17765
|
}
|
|
17546
17766
|
async function executeImplode(survey, opts) {
|
|
17547
17767
|
const exec = opts.exec ?? realExec;
|
|
17548
|
-
const home = opts.olamHome ??
|
|
17768
|
+
const home = opts.olamHome ?? path33.join(os18.homedir(), ".olam");
|
|
17549
17769
|
const removed = [];
|
|
17550
17770
|
const skipped = [];
|
|
17551
17771
|
const errors = [];
|
|
@@ -17602,16 +17822,16 @@ async function executeImplode(survey, opts) {
|
|
|
17602
17822
|
} else {
|
|
17603
17823
|
for (const n of survey.networks) skipped.push(`network:${n}`);
|
|
17604
17824
|
}
|
|
17605
|
-
if (
|
|
17825
|
+
if (fs31.existsSync(home)) {
|
|
17606
17826
|
if (opts.keepVault) {
|
|
17607
|
-
for (const entry of
|
|
17827
|
+
for (const entry of fs31.readdirSync(home, { withFileTypes: true })) {
|
|
17608
17828
|
if (entry.name === "auth-data") {
|
|
17609
17829
|
skipped.push(`fs:~/.olam/auth-data (--keep-vault)`);
|
|
17610
17830
|
continue;
|
|
17611
17831
|
}
|
|
17612
|
-
const target =
|
|
17832
|
+
const target = path33.join(home, entry.name);
|
|
17613
17833
|
try {
|
|
17614
|
-
|
|
17834
|
+
fs31.rmSync(target, { recursive: true, force: true });
|
|
17615
17835
|
removed.push(`fs:${target}`);
|
|
17616
17836
|
} catch (err) {
|
|
17617
17837
|
errors.push(`fs:${target}: ${err.message}`);
|
|
@@ -17619,7 +17839,7 @@ async function executeImplode(survey, opts) {
|
|
|
17619
17839
|
}
|
|
17620
17840
|
} else {
|
|
17621
17841
|
try {
|
|
17622
|
-
|
|
17842
|
+
fs31.rmSync(home, { recursive: true, force: true });
|
|
17623
17843
|
removed.push(`fs:${home}`);
|
|
17624
17844
|
} catch (err) {
|
|
17625
17845
|
errors.push(`fs:${home}: ${err.message}`);
|
|
@@ -17877,7 +18097,7 @@ init_context();
|
|
|
17877
18097
|
init_output();
|
|
17878
18098
|
init_exit_codes();
|
|
17879
18099
|
init_world_paths();
|
|
17880
|
-
import * as
|
|
18100
|
+
import * as fs32 from "node:fs";
|
|
17881
18101
|
import "node:path";
|
|
17882
18102
|
import ora6 from "ora";
|
|
17883
18103
|
function registerCrystallize(program2, options = {}) {
|
|
@@ -17909,7 +18129,7 @@ function registerCrystallize(program2, options = {}) {
|
|
|
17909
18129
|
return;
|
|
17910
18130
|
}
|
|
17911
18131
|
const thoughtDbPath = getWorldDbPath(world.workspacePath);
|
|
17912
|
-
if (!
|
|
18132
|
+
if (!fs32.existsSync(thoughtDbPath)) {
|
|
17913
18133
|
printError(`No thoughts captured yet for "${worldId}". Run a dispatch first.`);
|
|
17914
18134
|
process.exitCode = EXIT_GENERIC_ERROR;
|
|
17915
18135
|
return;
|
|
@@ -19283,11 +19503,11 @@ var qmarksTestNoExtDot = ([$0]) => {
|
|
|
19283
19503
|
return (f) => f.length === len && f !== "." && f !== "..";
|
|
19284
19504
|
};
|
|
19285
19505
|
var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
|
|
19286
|
-
var
|
|
19506
|
+
var path35 = {
|
|
19287
19507
|
win32: { sep: "\\" },
|
|
19288
19508
|
posix: { sep: "/" }
|
|
19289
19509
|
};
|
|
19290
|
-
var sep = defaultPlatform === "win32" ?
|
|
19510
|
+
var sep = defaultPlatform === "win32" ? path35.win32.sep : path35.posix.sep;
|
|
19291
19511
|
minimatch.sep = sep;
|
|
19292
19512
|
var GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
|
|
19293
19513
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
@@ -20113,7 +20333,7 @@ function registerPolicyCheck(program2) {
|
|
|
20113
20333
|
}
|
|
20114
20334
|
|
|
20115
20335
|
// src/commands/worldspec/compile.ts
|
|
20116
|
-
import { existsSync as
|
|
20336
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync18, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "node:fs";
|
|
20117
20337
|
import { resolve as resolvePath } from "node:path";
|
|
20118
20338
|
import YAML5 from "yaml";
|
|
20119
20339
|
|
|
@@ -20396,11 +20616,11 @@ function zodIssueToError(issue, doc, lineCounter) {
|
|
|
20396
20616
|
suggestion: deriveSuggestion(issue)
|
|
20397
20617
|
};
|
|
20398
20618
|
}
|
|
20399
|
-
function formatJsonPath(
|
|
20400
|
-
if (
|
|
20619
|
+
function formatJsonPath(path56) {
|
|
20620
|
+
if (path56.length === 0)
|
|
20401
20621
|
return "<root>";
|
|
20402
20622
|
let out = "";
|
|
20403
|
-
for (const seg of
|
|
20623
|
+
for (const seg of path56) {
|
|
20404
20624
|
if (typeof seg === "number") {
|
|
20405
20625
|
out += `[${seg}]`;
|
|
20406
20626
|
} else {
|
|
@@ -20409,11 +20629,11 @@ function formatJsonPath(path55) {
|
|
|
20409
20629
|
}
|
|
20410
20630
|
return out;
|
|
20411
20631
|
}
|
|
20412
|
-
function resolveYamlLocation(
|
|
20632
|
+
function resolveYamlLocation(path56, doc, lineCounter) {
|
|
20413
20633
|
let bestLine = 0;
|
|
20414
20634
|
let bestColumn = 0;
|
|
20415
|
-
for (let depth =
|
|
20416
|
-
const segment =
|
|
20635
|
+
for (let depth = path56.length; depth >= 0; depth -= 1) {
|
|
20636
|
+
const segment = path56.slice(0, depth);
|
|
20417
20637
|
try {
|
|
20418
20638
|
const node = doc.getIn(segment, true);
|
|
20419
20639
|
if (node && typeof node === "object" && "range" in node) {
|
|
@@ -20631,11 +20851,11 @@ function topoSort(nodes) {
|
|
|
20631
20851
|
}
|
|
20632
20852
|
function traceCycle(start, byId) {
|
|
20633
20853
|
const seen = /* @__PURE__ */ new Set();
|
|
20634
|
-
const
|
|
20854
|
+
const path56 = [];
|
|
20635
20855
|
let current = start;
|
|
20636
20856
|
while (current && !seen.has(current)) {
|
|
20637
20857
|
seen.add(current);
|
|
20638
|
-
|
|
20858
|
+
path56.push(current);
|
|
20639
20859
|
const node = byId.get(current);
|
|
20640
20860
|
const next = node?.dependsOn[0];
|
|
20641
20861
|
if (next === void 0)
|
|
@@ -20643,10 +20863,10 @@ function traceCycle(start, byId) {
|
|
|
20643
20863
|
current = next;
|
|
20644
20864
|
}
|
|
20645
20865
|
if (current && seen.has(current)) {
|
|
20646
|
-
const idx =
|
|
20647
|
-
return [...
|
|
20866
|
+
const idx = path56.indexOf(current);
|
|
20867
|
+
return [...path56.slice(idx), current];
|
|
20648
20868
|
}
|
|
20649
|
-
return
|
|
20869
|
+
return path56;
|
|
20650
20870
|
}
|
|
20651
20871
|
|
|
20652
20872
|
// ../core/dist/executor/types.js
|
|
@@ -20870,11 +21090,11 @@ async function resolveDigests(lockfile, resolver) {
|
|
|
20870
21090
|
}
|
|
20871
21091
|
|
|
20872
21092
|
// ../core/dist/worldspec/image-digest.js
|
|
20873
|
-
import { execFileSync as
|
|
21093
|
+
import { execFileSync as execFileSync10 } from "node:child_process";
|
|
20874
21094
|
var DOCKER_SUBPROCESS_TIMEOUT_MS = 3e4;
|
|
20875
21095
|
var dockerDigestResolver = async (image, source) => {
|
|
20876
21096
|
if (source === "local") {
|
|
20877
|
-
const out =
|
|
21097
|
+
const out = execFileSync10("docker", ["inspect", image, "--format", "{{.Id}}"], {
|
|
20878
21098
|
encoding: "utf8",
|
|
20879
21099
|
stdio: ["ignore", "pipe", "pipe"],
|
|
20880
21100
|
timeout: DOCKER_SUBPROCESS_TIMEOUT_MS,
|
|
@@ -20885,7 +21105,7 @@ var dockerDigestResolver = async (image, source) => {
|
|
|
20885
21105
|
}
|
|
20886
21106
|
return out;
|
|
20887
21107
|
}
|
|
20888
|
-
const raw =
|
|
21108
|
+
const raw = execFileSync10("docker", ["buildx", "imagetools", "inspect", image], {
|
|
20889
21109
|
encoding: "utf8",
|
|
20890
21110
|
stdio: ["ignore", "pipe", "pipe"],
|
|
20891
21111
|
timeout: DOCKER_SUBPROCESS_TIMEOUT_MS,
|
|
@@ -20916,13 +21136,13 @@ function registerWorldspecCompile(parent) {
|
|
|
20916
21136
|
const sourcePolicies = [];
|
|
20917
21137
|
for (const p of paths) {
|
|
20918
21138
|
const abs = resolvePath(process.cwd(), p);
|
|
20919
|
-
if (!
|
|
21139
|
+
if (!existsSync33(abs)) {
|
|
20920
21140
|
printError(`worldspec not found at ${abs}`);
|
|
20921
21141
|
process.exit(EXIT_WORLDSPEC_FILE_NOT_FOUND);
|
|
20922
21142
|
}
|
|
20923
21143
|
let yaml;
|
|
20924
21144
|
try {
|
|
20925
|
-
yaml = YAML5.parse(
|
|
21145
|
+
yaml = YAML5.parse(readFileSync22(abs, "utf8"));
|
|
20926
21146
|
} catch (err) {
|
|
20927
21147
|
printError(
|
|
20928
21148
|
`${p}: YAML parse error: ${err.message}`
|
|
@@ -21007,7 +21227,7 @@ function getPkgVersion() {
|
|
|
21007
21227
|
// src/commands/worldspec/init.ts
|
|
21008
21228
|
init_exit_codes();
|
|
21009
21229
|
init_output();
|
|
21010
|
-
import { existsSync as
|
|
21230
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync19, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
|
|
21011
21231
|
import { execSync as execSync10 } from "node:child_process";
|
|
21012
21232
|
import { basename as basename3, resolve as resolvePath2 } from "node:path";
|
|
21013
21233
|
function registerWorldspecInit(parent) {
|
|
@@ -21025,7 +21245,7 @@ function registerWorldspecInit(parent) {
|
|
|
21025
21245
|
const cwd = process.cwd();
|
|
21026
21246
|
const targetDir = resolvePath2(cwd, ".olam/worldspecs");
|
|
21027
21247
|
const targetFile = resolvePath2(targetDir, "default.yaml");
|
|
21028
|
-
if (
|
|
21248
|
+
if (existsSync34(targetFile) && !opts.force) {
|
|
21029
21249
|
printError(
|
|
21030
21250
|
`${targetFile} already exists; pass --force to overwrite`
|
|
21031
21251
|
);
|
|
@@ -21059,14 +21279,14 @@ function registerWorldspecInit(parent) {
|
|
|
21059
21279
|
});
|
|
21060
21280
|
}
|
|
21061
21281
|
function detectProjectShape(root, useAdbYaml) {
|
|
21062
|
-
const hasGemfile =
|
|
21063
|
-
const hasNodePackageJson =
|
|
21064
|
-
const hasAdbYaml =
|
|
21282
|
+
const hasGemfile = existsSync34(resolvePath2(root, "Gemfile"));
|
|
21283
|
+
const hasNodePackageJson = existsSync34(resolvePath2(root, "package.json"));
|
|
21284
|
+
const hasAdbYaml = existsSync34(resolvePath2(root, ".adb.yaml"));
|
|
21065
21285
|
let rubyVersion = null;
|
|
21066
21286
|
const rubyVersionPath = resolvePath2(root, ".ruby-version");
|
|
21067
|
-
if (
|
|
21287
|
+
if (existsSync34(rubyVersionPath)) {
|
|
21068
21288
|
try {
|
|
21069
|
-
const raw =
|
|
21289
|
+
const raw = readFileSync23(rubyVersionPath, "utf8").trim();
|
|
21070
21290
|
const match2 = raw.match(/(\d+\.\d+\.\d+)/);
|
|
21071
21291
|
if (match2) rubyVersion = match2[1] ?? null;
|
|
21072
21292
|
} catch {
|
|
@@ -22469,7 +22689,7 @@ function registerWorldspecSchema(parent) {
|
|
|
22469
22689
|
}
|
|
22470
22690
|
|
|
22471
22691
|
// src/commands/worldspec/validate.ts
|
|
22472
|
-
import { existsSync as
|
|
22692
|
+
import { existsSync as existsSync35, readFileSync as readFileSync24 } from "node:fs";
|
|
22473
22693
|
import { resolve as resolvePath4 } from "node:path";
|
|
22474
22694
|
init_exit_codes();
|
|
22475
22695
|
init_output();
|
|
@@ -22486,13 +22706,13 @@ function registerWorldspecValidate(parent) {
|
|
|
22486
22706
|
"human"
|
|
22487
22707
|
).action(async (pathArg, opts) => {
|
|
22488
22708
|
const absPath = resolvePath4(process.cwd(), pathArg);
|
|
22489
|
-
if (!
|
|
22709
|
+
if (!existsSync35(absPath)) {
|
|
22490
22710
|
printError(`worldspec not found at ${absPath}`);
|
|
22491
22711
|
process.exit(EXIT_WORLDSPEC_FILE_NOT_FOUND);
|
|
22492
22712
|
}
|
|
22493
22713
|
let yamlSource;
|
|
22494
22714
|
try {
|
|
22495
|
-
yamlSource =
|
|
22715
|
+
yamlSource = readFileSync24(absPath, "utf8");
|
|
22496
22716
|
} catch (err) {
|
|
22497
22717
|
printError(
|
|
22498
22718
|
`failed to read ${absPath}: ${err.message}`
|
|
@@ -22538,23 +22758,23 @@ function registerWorldspec(program2) {
|
|
|
22538
22758
|
// src/commands/upgrade.ts
|
|
22539
22759
|
init_output();
|
|
22540
22760
|
init_host_cp();
|
|
22541
|
-
import * as
|
|
22542
|
-
import * as
|
|
22761
|
+
import * as fs35 from "node:fs";
|
|
22762
|
+
import * as path38 from "node:path";
|
|
22543
22763
|
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
22544
22764
|
import ora7 from "ora";
|
|
22545
22765
|
import pc18 from "picocolors";
|
|
22546
22766
|
|
|
22547
22767
|
// src/commands/upgrade-lock.ts
|
|
22548
|
-
import * as
|
|
22768
|
+
import * as fs33 from "node:fs";
|
|
22549
22769
|
import * as os19 from "node:os";
|
|
22550
|
-
import * as
|
|
22770
|
+
import * as path36 from "node:path";
|
|
22551
22771
|
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
22552
|
-
var LOCK_FILE_PATH =
|
|
22772
|
+
var LOCK_FILE_PATH = path36.join(os19.homedir(), ".olam", ".upgrade.lock");
|
|
22553
22773
|
var STALE_LOCK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
22554
22774
|
function readLockFile(lockPath) {
|
|
22555
22775
|
try {
|
|
22556
|
-
if (!
|
|
22557
|
-
const raw =
|
|
22776
|
+
if (!fs33.existsSync(lockPath)) return null;
|
|
22777
|
+
const raw = fs33.readFileSync(lockPath, "utf-8").trim();
|
|
22558
22778
|
if (raw.length === 0) return null;
|
|
22559
22779
|
const parsed = JSON.parse(raw);
|
|
22560
22780
|
if (typeof parsed.pid !== "number" || typeof parsed.startTs !== "number") return null;
|
|
@@ -22599,16 +22819,16 @@ function isStaleLock(content, nowMs = Date.now()) {
|
|
|
22599
22819
|
return false;
|
|
22600
22820
|
}
|
|
22601
22821
|
function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
|
|
22602
|
-
const dir =
|
|
22603
|
-
|
|
22822
|
+
const dir = path36.dirname(lockPath);
|
|
22823
|
+
fs33.mkdirSync(dir, { recursive: true });
|
|
22604
22824
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
22605
22825
|
try {
|
|
22606
|
-
const fd =
|
|
22826
|
+
const fd = fs33.openSync(lockPath, "wx", 420);
|
|
22607
22827
|
try {
|
|
22608
22828
|
const content = { pid: process.pid, startTs: nowMs };
|
|
22609
|
-
|
|
22829
|
+
fs33.writeSync(fd, JSON.stringify(content));
|
|
22610
22830
|
} finally {
|
|
22611
|
-
|
|
22831
|
+
fs33.closeSync(fd);
|
|
22612
22832
|
}
|
|
22613
22833
|
return { acquired: true, lockPath };
|
|
22614
22834
|
} catch (err) {
|
|
@@ -22617,7 +22837,7 @@ function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
|
|
|
22617
22837
|
const existing2 = readLockFile(lockPath);
|
|
22618
22838
|
if (isStaleLock(existing2, nowMs)) {
|
|
22619
22839
|
try {
|
|
22620
|
-
|
|
22840
|
+
fs33.unlinkSync(lockPath);
|
|
22621
22841
|
} catch (unlinkErr) {
|
|
22622
22842
|
const ucode = unlinkErr.code;
|
|
22623
22843
|
if (ucode !== "ENOENT") throw unlinkErr;
|
|
@@ -22642,7 +22862,7 @@ function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
|
|
|
22642
22862
|
}
|
|
22643
22863
|
function releaseLock(lockPath = LOCK_FILE_PATH) {
|
|
22644
22864
|
try {
|
|
22645
|
-
|
|
22865
|
+
fs33.unlinkSync(lockPath);
|
|
22646
22866
|
} catch (err) {
|
|
22647
22867
|
const code = err.code;
|
|
22648
22868
|
if (code !== "ENOENT") throw err;
|
|
@@ -22660,19 +22880,19 @@ function formatRefusalMessage(result, lockPath = LOCK_FILE_PATH) {
|
|
|
22660
22880
|
}
|
|
22661
22881
|
|
|
22662
22882
|
// src/commands/upgrade-log.ts
|
|
22663
|
-
import * as
|
|
22883
|
+
import * as fs34 from "node:fs";
|
|
22664
22884
|
import * as os20 from "node:os";
|
|
22665
|
-
import * as
|
|
22885
|
+
import * as path37 from "node:path";
|
|
22666
22886
|
function getUpgradeLogPath() {
|
|
22667
22887
|
const home = process.env["HOME"] ?? os20.homedir();
|
|
22668
|
-
return
|
|
22888
|
+
return path37.join(home, ".olam", "upgrade.log");
|
|
22669
22889
|
}
|
|
22670
22890
|
var UPGRADE_LOG_PATH = getUpgradeLogPath();
|
|
22671
22891
|
function appendUpgradeLog(row, logPath = getUpgradeLogPath()) {
|
|
22672
22892
|
try {
|
|
22673
|
-
|
|
22893
|
+
fs34.mkdirSync(path37.dirname(logPath), { recursive: true });
|
|
22674
22894
|
const line = JSON.stringify(row) + "\n";
|
|
22675
|
-
|
|
22895
|
+
fs34.appendFileSync(logPath, line, { mode: 420 });
|
|
22676
22896
|
} catch (err) {
|
|
22677
22897
|
process.stderr.write(
|
|
22678
22898
|
`[upgrade-log] failed to append: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -22681,10 +22901,10 @@ function appendUpgradeLog(row, logPath = getUpgradeLogPath()) {
|
|
|
22681
22901
|
}
|
|
22682
22902
|
}
|
|
22683
22903
|
function readUpgradeLog(limit = 10, logPath = getUpgradeLogPath()) {
|
|
22684
|
-
if (!
|
|
22904
|
+
if (!fs34.existsSync(logPath)) return [];
|
|
22685
22905
|
let raw;
|
|
22686
22906
|
try {
|
|
22687
|
-
raw =
|
|
22907
|
+
raw = fs34.readFileSync(logPath, "utf-8");
|
|
22688
22908
|
} catch (err) {
|
|
22689
22909
|
process.stderr.write(
|
|
22690
22910
|
`[upgrade-log] failed to read: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -22777,12 +22997,12 @@ init_protocol_version();
|
|
|
22777
22997
|
init_install_root();
|
|
22778
22998
|
var AUTH_HEALTH_URL2 = "http://127.0.0.1:9999/health";
|
|
22779
22999
|
function isNodeModulesInSync(cwd) {
|
|
22780
|
-
const lockPath =
|
|
22781
|
-
const markerPath =
|
|
22782
|
-
if (!
|
|
23000
|
+
const lockPath = path38.join(cwd, "package-lock.json");
|
|
23001
|
+
const markerPath = path38.join(cwd, "node_modules", ".package-lock.json");
|
|
23002
|
+
if (!fs35.existsSync(lockPath) || !fs35.existsSync(markerPath)) return false;
|
|
22783
23003
|
try {
|
|
22784
|
-
const lockStat =
|
|
22785
|
-
const markerStat =
|
|
23004
|
+
const lockStat = fs35.statSync(lockPath);
|
|
23005
|
+
const markerStat = fs35.statSync(markerPath);
|
|
22786
23006
|
return markerStat.mtimeMs >= lockStat.mtimeMs;
|
|
22787
23007
|
} catch {
|
|
22788
23008
|
return false;
|
|
@@ -22798,8 +23018,8 @@ function shouldSkipInstall(opts, cwd) {
|
|
|
22798
23018
|
return { skip: false };
|
|
22799
23019
|
}
|
|
22800
23020
|
function validateRepoRoot(cwd) {
|
|
22801
|
-
const marker =
|
|
22802
|
-
if (!
|
|
23021
|
+
const marker = path38.join(cwd, "packages/host-cp/compose.yaml");
|
|
23022
|
+
if (!fs35.existsSync(marker)) {
|
|
22803
23023
|
return {
|
|
22804
23024
|
ok: false,
|
|
22805
23025
|
error: `Not an olam repo root (expected ${marker}).
|
|
@@ -23155,9 +23375,9 @@ async function recreateAuthService() {
|
|
|
23155
23375
|
}
|
|
23156
23376
|
}
|
|
23157
23377
|
function readBundleHash(cwd) {
|
|
23158
|
-
const indexPath =
|
|
23159
|
-
if (!
|
|
23160
|
-
return extractBundleHash(
|
|
23378
|
+
const indexPath = path38.join(cwd, "packages/control-plane/public/index.html");
|
|
23379
|
+
if (!fs35.existsSync(indexPath)) return null;
|
|
23380
|
+
return extractBundleHash(fs35.readFileSync(indexPath, "utf-8"));
|
|
23161
23381
|
}
|
|
23162
23382
|
async function runUpgradePullByDigest(deps = {}) {
|
|
23163
23383
|
const docker2 = deps.docker ?? realDocker;
|
|
@@ -23691,7 +23911,7 @@ ${buildResult.stderr}`);
|
|
|
23691
23911
|
return;
|
|
23692
23912
|
}
|
|
23693
23913
|
const authSecret = readAuthSecret2();
|
|
23694
|
-
const spaDir =
|
|
23914
|
+
const spaDir = path38.join(cwd, "packages/control-plane/app");
|
|
23695
23915
|
const spaResult = runStep2(
|
|
23696
23916
|
"vite build (SPA)",
|
|
23697
23917
|
"npx",
|
|
@@ -24225,20 +24445,20 @@ ${pc20.dim(`world: ${worldId} sort: ${sortKey} refresh: 5s Ctrl-C to exit`)}
|
|
|
24225
24445
|
|
|
24226
24446
|
// src/commands/keys.ts
|
|
24227
24447
|
init_output();
|
|
24228
|
-
import * as
|
|
24448
|
+
import * as fs36 from "node:fs";
|
|
24229
24449
|
import * as os21 from "node:os";
|
|
24230
|
-
import * as
|
|
24450
|
+
import * as path39 from "node:path";
|
|
24231
24451
|
import YAML6 from "yaml";
|
|
24232
|
-
function
|
|
24233
|
-
return process.env.OLAM_HOME ??
|
|
24452
|
+
function olamHome3() {
|
|
24453
|
+
return process.env.OLAM_HOME ?? path39.join(os21.homedir(), ".olam");
|
|
24234
24454
|
}
|
|
24235
24455
|
function keysFilePath() {
|
|
24236
|
-
return
|
|
24456
|
+
return path39.join(olamHome3(), "keys.yaml");
|
|
24237
24457
|
}
|
|
24238
24458
|
function readKeysFile() {
|
|
24239
24459
|
const filePath = keysFilePath();
|
|
24240
|
-
if (!
|
|
24241
|
-
const raw =
|
|
24460
|
+
if (!fs36.existsSync(filePath)) return null;
|
|
24461
|
+
const raw = fs36.readFileSync(filePath, "utf-8").trim();
|
|
24242
24462
|
if (raw.length === 0) return null;
|
|
24243
24463
|
try {
|
|
24244
24464
|
const parsed = YAML6.parse(raw);
|
|
@@ -24253,14 +24473,14 @@ function readKeysFile() {
|
|
|
24253
24473
|
}
|
|
24254
24474
|
}
|
|
24255
24475
|
function writeKeysFile(keys) {
|
|
24256
|
-
const dir =
|
|
24257
|
-
if (!
|
|
24258
|
-
|
|
24476
|
+
const dir = olamHome3();
|
|
24477
|
+
if (!fs36.existsSync(dir)) {
|
|
24478
|
+
fs36.mkdirSync(dir, { recursive: true });
|
|
24259
24479
|
}
|
|
24260
24480
|
const filePath = keysFilePath();
|
|
24261
24481
|
const content = YAML6.stringify(keys);
|
|
24262
|
-
|
|
24263
|
-
|
|
24482
|
+
fs36.writeFileSync(filePath, content, { encoding: "utf-8", mode: 384 });
|
|
24483
|
+
fs36.chmodSync(filePath, 384);
|
|
24264
24484
|
}
|
|
24265
24485
|
function redact(value) {
|
|
24266
24486
|
if (value.length <= 8) return value + "...";
|
|
@@ -24303,7 +24523,7 @@ function registerKeys(program2) {
|
|
|
24303
24523
|
}
|
|
24304
24524
|
const { [key]: _removed, ...rest } = existing;
|
|
24305
24525
|
if (Object.keys(rest).length === 0) {
|
|
24306
|
-
|
|
24526
|
+
fs36.unlinkSync(keysFilePath());
|
|
24307
24527
|
} else {
|
|
24308
24528
|
writeKeysFile(rest);
|
|
24309
24529
|
}
|
|
@@ -24328,8 +24548,8 @@ function registerKeys(program2) {
|
|
|
24328
24548
|
// src/commands/world-snapshot.ts
|
|
24329
24549
|
init_snapshot();
|
|
24330
24550
|
init_output();
|
|
24331
|
-
import * as
|
|
24332
|
-
import * as
|
|
24551
|
+
import * as fs37 from "node:fs";
|
|
24552
|
+
import * as path40 from "node:path";
|
|
24333
24553
|
import { execSync as execSync11 } from "node:child_process";
|
|
24334
24554
|
import pc21 from "picocolors";
|
|
24335
24555
|
|
|
@@ -24352,16 +24572,16 @@ function emitDeprecationWarning(subcommand) {
|
|
|
24352
24572
|
}
|
|
24353
24573
|
function bumpDeprecationCounter() {
|
|
24354
24574
|
if (process.env[INTERNAL_SENTINEL_ENV] === "1") return;
|
|
24355
|
-
const counterPath =
|
|
24575
|
+
const counterPath = path40.join(snapshotsDir(), ".deprecation-counter");
|
|
24356
24576
|
try {
|
|
24357
|
-
|
|
24577
|
+
fs37.mkdirSync(path40.dirname(counterPath), { recursive: true });
|
|
24358
24578
|
let current = 0;
|
|
24359
|
-
if (
|
|
24360
|
-
const raw =
|
|
24579
|
+
if (fs37.existsSync(counterPath)) {
|
|
24580
|
+
const raw = fs37.readFileSync(counterPath, "utf-8").trim();
|
|
24361
24581
|
const parsed = parseInt(raw, 10);
|
|
24362
24582
|
if (Number.isInteger(parsed) && parsed >= 0) current = parsed;
|
|
24363
24583
|
}
|
|
24364
|
-
|
|
24584
|
+
fs37.writeFileSync(counterPath, String(current + 1), { mode: 384 });
|
|
24365
24585
|
} catch {
|
|
24366
24586
|
}
|
|
24367
24587
|
}
|
|
@@ -24437,17 +24657,17 @@ function resolveKinds(arg) {
|
|
|
24437
24657
|
return [];
|
|
24438
24658
|
}
|
|
24439
24659
|
async function captureGems(worldId, workspacePath, repo) {
|
|
24440
|
-
const repoDir =
|
|
24660
|
+
const repoDir = path40.join(workspacePath, repo);
|
|
24441
24661
|
const fingerprint = computeGemsFingerprint(repoDir);
|
|
24442
24662
|
if (!fingerprint) {
|
|
24443
24663
|
return { ok: false, tarPath: "", msg: "no Gemfile.lock \u2014 layer does not apply" };
|
|
24444
24664
|
}
|
|
24445
24665
|
const tarPath = snapshotTarPath(worldId, "gems", repo, fingerprint);
|
|
24446
|
-
const vendorBundle =
|
|
24447
|
-
if (
|
|
24666
|
+
const vendorBundle = path40.join(repoDir, "vendor", "bundle");
|
|
24667
|
+
if (fs37.existsSync(vendorBundle)) {
|
|
24448
24668
|
try {
|
|
24449
24669
|
packTarball(vendorBundle, tarPath);
|
|
24450
|
-
const stat =
|
|
24670
|
+
const stat = fs37.statSync(tarPath);
|
|
24451
24671
|
const manifest = {
|
|
24452
24672
|
kind: "gems",
|
|
24453
24673
|
worldId,
|
|
@@ -24480,10 +24700,10 @@ async function captureGems(worldId, workspacePath, repo) {
|
|
|
24480
24700
|
`docker exec ${containerName} sh -c 'mkdir -p "$(dirname ${tmpTar})" && tar -czf ${tmpTar}.tmp -C ${bundlePath} . && mv ${tmpTar}.tmp ${tmpTar}'`,
|
|
24481
24701
|
{ stdio: "pipe", timeout: 12e4 }
|
|
24482
24702
|
);
|
|
24483
|
-
|
|
24703
|
+
fs37.mkdirSync(path40.dirname(tarPath), { recursive: true });
|
|
24484
24704
|
execSync11(`docker cp ${containerName}:${tmpTar} "${tarPath}"`, { stdio: "pipe", timeout: 12e4 });
|
|
24485
24705
|
execSync11(`docker exec ${containerName} rm -f ${tmpTar}`, { stdio: "pipe" });
|
|
24486
|
-
const stat =
|
|
24706
|
+
const stat = fs37.statSync(tarPath);
|
|
24487
24707
|
const manifest = {
|
|
24488
24708
|
kind: "gems",
|
|
24489
24709
|
worldId,
|
|
@@ -24500,19 +24720,19 @@ async function captureGems(worldId, workspacePath, repo) {
|
|
|
24500
24720
|
}
|
|
24501
24721
|
}
|
|
24502
24722
|
async function captureNode(worldId, workspacePath, repo) {
|
|
24503
|
-
const repoDir =
|
|
24723
|
+
const repoDir = path40.join(workspacePath, repo);
|
|
24504
24724
|
const fingerprint = computeNodeFingerprint(repoDir);
|
|
24505
24725
|
if (!fingerprint) {
|
|
24506
24726
|
return { ok: false, tarPath: "", msg: "no lockfile \u2014 layer does not apply" };
|
|
24507
24727
|
}
|
|
24508
|
-
const nodeModules =
|
|
24509
|
-
if (!
|
|
24728
|
+
const nodeModules = path40.join(repoDir, "node_modules");
|
|
24729
|
+
if (!fs37.existsSync(nodeModules)) {
|
|
24510
24730
|
return { ok: false, tarPath: "", msg: "node_modules not installed yet" };
|
|
24511
24731
|
}
|
|
24512
24732
|
const tarPath = snapshotTarPath(worldId, "node", repo, fingerprint);
|
|
24513
24733
|
try {
|
|
24514
24734
|
packTarball(nodeModules, tarPath);
|
|
24515
|
-
const stat =
|
|
24735
|
+
const stat = fs37.statSync(tarPath);
|
|
24516
24736
|
const manifest = {
|
|
24517
24737
|
kind: "node",
|
|
24518
24738
|
worldId,
|
|
@@ -24529,7 +24749,7 @@ async function captureNode(worldId, workspacePath, repo) {
|
|
|
24529
24749
|
}
|
|
24530
24750
|
}
|
|
24531
24751
|
async function capturePg(worldId, workspacePath, repoNames) {
|
|
24532
|
-
const repoDirs = repoNames.map((r) =>
|
|
24752
|
+
const repoDirs = repoNames.map((r) => path40.join(workspacePath, r));
|
|
24533
24753
|
const fingerprint = computePgFingerprint(repoDirs);
|
|
24534
24754
|
if (!fingerprint) {
|
|
24535
24755
|
return { ok: false, tarPath: "", msg: "no Gemfile.lock / schema.rb \u2014 layer does not apply" };
|
|
@@ -24544,13 +24764,13 @@ async function capturePg(worldId, workspacePath, repoNames) {
|
|
|
24544
24764
|
}
|
|
24545
24765
|
try {
|
|
24546
24766
|
execSync11(`docker stop ${containerName}`, { stdio: "pipe", timeout: 3e4 });
|
|
24547
|
-
|
|
24767
|
+
fs37.mkdirSync(path40.dirname(tarPath), { recursive: true });
|
|
24548
24768
|
execSync11(
|
|
24549
|
-
`docker run --rm -v "${volumeName2}:/pgdata:ro" -v "${
|
|
24769
|
+
`docker run --rm -v "${volumeName2}:/pgdata:ro" -v "${path40.dirname(tarPath)}:/dest" alpine sh -c 'tar -czf /dest/${path40.basename(tarPath)}.tmp -C /pgdata . && mv /dest/${path40.basename(tarPath)}.tmp /dest/${path40.basename(tarPath)}'`,
|
|
24550
24770
|
{ stdio: "pipe", timeout: 18e4 }
|
|
24551
24771
|
);
|
|
24552
24772
|
execSync11(`docker start ${containerName}`, { stdio: "pipe", timeout: 3e4 });
|
|
24553
|
-
const stat =
|
|
24773
|
+
const stat = fs37.statSync(tarPath);
|
|
24554
24774
|
const manifest = {
|
|
24555
24775
|
kind: "pg",
|
|
24556
24776
|
worldId,
|
|
@@ -24574,18 +24794,18 @@ async function handleEvict(opts) {
|
|
|
24574
24794
|
const maxBytes = Number.isInteger(cap) && cap > 0 ? cap : 5 * 1024 * 1024 * 1024;
|
|
24575
24795
|
if (opts.dryRun) {
|
|
24576
24796
|
const root = snapshotsDir();
|
|
24577
|
-
if (!
|
|
24797
|
+
if (!fs37.existsSync(root)) {
|
|
24578
24798
|
console.log(pc21.dim("No snapshot dir; nothing to evict."));
|
|
24579
24799
|
return;
|
|
24580
24800
|
}
|
|
24581
24801
|
const allTars = [];
|
|
24582
24802
|
const walk2 = (d) => {
|
|
24583
|
-
for (const entry of
|
|
24584
|
-
const full =
|
|
24803
|
+
for (const entry of fs37.readdirSync(d, { withFileTypes: true })) {
|
|
24804
|
+
const full = path40.join(d, entry.name);
|
|
24585
24805
|
if (entry.isDirectory()) {
|
|
24586
24806
|
walk2(full);
|
|
24587
24807
|
} else if (entry.name.endsWith(".tar.gz")) {
|
|
24588
|
-
const stat =
|
|
24808
|
+
const stat = fs37.statSync(full);
|
|
24589
24809
|
allTars.push({ path: full, size: stat.size, mtime: stat.mtimeMs });
|
|
24590
24810
|
}
|
|
24591
24811
|
}
|
|
@@ -24678,35 +24898,35 @@ function formatAge2(ms) {
|
|
|
24678
24898
|
// src/commands/refresh.ts
|
|
24679
24899
|
init_context();
|
|
24680
24900
|
init_output();
|
|
24681
|
-
import * as
|
|
24901
|
+
import * as fs39 from "node:fs";
|
|
24682
24902
|
import * as os22 from "node:os";
|
|
24683
|
-
import * as
|
|
24903
|
+
import * as path42 from "node:path";
|
|
24684
24904
|
import { spawnSync as spawnSync13 } from "node:child_process";
|
|
24685
24905
|
import ora8 from "ora";
|
|
24686
24906
|
|
|
24687
24907
|
// src/commands/refresh-helpers.ts
|
|
24688
|
-
import * as
|
|
24689
|
-
import * as
|
|
24908
|
+
import * as fs38 from "node:fs";
|
|
24909
|
+
import * as path41 from "node:path";
|
|
24690
24910
|
function collectCpSourceFiles(standaloneDir) {
|
|
24691
|
-
if (!
|
|
24911
|
+
if (!fs38.existsSync(standaloneDir)) {
|
|
24692
24912
|
throw new Error(`CP standalone dir not found: ${standaloneDir}`);
|
|
24693
24913
|
}
|
|
24694
24914
|
const entries = [];
|
|
24695
|
-
const topLevel =
|
|
24696
|
-
const stat =
|
|
24915
|
+
const topLevel = fs38.readdirSync(standaloneDir).filter((f) => {
|
|
24916
|
+
const stat = fs38.statSync(path41.join(standaloneDir, f));
|
|
24697
24917
|
return stat.isFile() && f.endsWith(".mjs") && !f.endsWith(".test.mjs");
|
|
24698
24918
|
}).sort();
|
|
24699
24919
|
for (const f of topLevel) {
|
|
24700
|
-
entries.push({ srcPath:
|
|
24920
|
+
entries.push({ srcPath: path41.join(standaloneDir, f), destRelPath: f });
|
|
24701
24921
|
}
|
|
24702
|
-
const libDir =
|
|
24703
|
-
if (
|
|
24704
|
-
const libFiles =
|
|
24705
|
-
const stat =
|
|
24922
|
+
const libDir = path41.join(standaloneDir, "lib");
|
|
24923
|
+
if (fs38.existsSync(libDir) && fs38.statSync(libDir).isDirectory()) {
|
|
24924
|
+
const libFiles = fs38.readdirSync(libDir).filter((f) => {
|
|
24925
|
+
const stat = fs38.statSync(path41.join(libDir, f));
|
|
24706
24926
|
return stat.isFile() && f.endsWith(".mjs") && !f.endsWith(".test.mjs");
|
|
24707
24927
|
}).sort();
|
|
24708
24928
|
for (const f of libFiles) {
|
|
24709
|
-
entries.push({ srcPath:
|
|
24929
|
+
entries.push({ srcPath: path41.join(libDir, f), destRelPath: `lib/${f}` });
|
|
24710
24930
|
}
|
|
24711
24931
|
}
|
|
24712
24932
|
return entries;
|
|
@@ -24764,16 +24984,16 @@ async function refreshWorld(worldId, portOffset, standaloneDir, opts) {
|
|
|
24764
24984
|
error: err instanceof Error ? err.message : String(err)
|
|
24765
24985
|
};
|
|
24766
24986
|
}
|
|
24767
|
-
const stagingDir =
|
|
24768
|
-
|
|
24987
|
+
const stagingDir = fs39.mkdtempSync(
|
|
24988
|
+
path42.join(os22.tmpdir(), `olam-refresh-${worldId}-`)
|
|
24769
24989
|
);
|
|
24770
24990
|
try {
|
|
24771
24991
|
const hasLib = entries.some((e) => e.destRelPath.startsWith("lib/"));
|
|
24772
24992
|
if (hasLib) {
|
|
24773
|
-
|
|
24993
|
+
fs39.mkdirSync(path42.join(stagingDir, "lib"), { recursive: true });
|
|
24774
24994
|
}
|
|
24775
24995
|
for (const { srcPath, destRelPath } of entries) {
|
|
24776
|
-
|
|
24996
|
+
fs39.copyFileSync(srcPath, path42.join(stagingDir, destRelPath));
|
|
24777
24997
|
}
|
|
24778
24998
|
const cpResult = docker([
|
|
24779
24999
|
"cp",
|
|
@@ -24788,7 +25008,7 @@ async function refreshWorld(worldId, portOffset, standaloneDir, opts) {
|
|
|
24788
25008
|
};
|
|
24789
25009
|
}
|
|
24790
25010
|
} finally {
|
|
24791
|
-
|
|
25011
|
+
fs39.rmSync(stagingDir, { recursive: true, force: true });
|
|
24792
25012
|
}
|
|
24793
25013
|
if (opts.restart) {
|
|
24794
25014
|
const restartResult = docker([
|
|
@@ -24825,11 +25045,11 @@ function registerRefresh(program2) {
|
|
|
24825
25045
|
process.exitCode = 1;
|
|
24826
25046
|
return;
|
|
24827
25047
|
}
|
|
24828
|
-
const standaloneDir =
|
|
25048
|
+
const standaloneDir = path42.join(
|
|
24829
25049
|
process.cwd(),
|
|
24830
25050
|
"packages/control-plane/standalone"
|
|
24831
25051
|
);
|
|
24832
|
-
if (!
|
|
25052
|
+
if (!fs39.existsSync(standaloneDir)) {
|
|
24833
25053
|
printError(
|
|
24834
25054
|
`CP standalone source not found at ${standaloneDir}.
|
|
24835
25055
|
Run \`olam refresh\` from the olam repo root.`
|
|
@@ -24908,10 +25128,10 @@ Run \`olam refresh\` from the olam repo root.`
|
|
|
24908
25128
|
}
|
|
24909
25129
|
|
|
24910
25130
|
// src/commands/diagnose.ts
|
|
24911
|
-
import * as
|
|
25131
|
+
import * as fs40 from "node:fs";
|
|
24912
25132
|
import * as os23 from "node:os";
|
|
24913
|
-
import * as
|
|
24914
|
-
import { execFileSync as
|
|
25133
|
+
import * as path43 from "node:path";
|
|
25134
|
+
import { execFileSync as execFileSync11, execSync as execSync12 } from "node:child_process";
|
|
24915
25135
|
import pc22 from "picocolors";
|
|
24916
25136
|
|
|
24917
25137
|
// ../core/dist/diagnose/secret-stripper.js
|
|
@@ -24945,9 +25165,9 @@ function stripSecrets(input) {
|
|
|
24945
25165
|
}
|
|
24946
25166
|
|
|
24947
25167
|
// src/commands/diagnose.ts
|
|
24948
|
-
var DIAGNOSTICS_DIR =
|
|
24949
|
-
var LOG_DIR =
|
|
24950
|
-
var CACHE_DIR =
|
|
25168
|
+
var DIAGNOSTICS_DIR = path43.join(os23.homedir(), ".olam", "diagnostics");
|
|
25169
|
+
var LOG_DIR = path43.join(os23.homedir(), ".olam", "log");
|
|
25170
|
+
var CACHE_DIR = path43.join(os23.homedir(), ".olam", "cache");
|
|
24951
25171
|
var LOG_TAIL_LINES = 200;
|
|
24952
25172
|
function safeExec(cmd) {
|
|
24953
25173
|
try {
|
|
@@ -24957,14 +25177,14 @@ function safeExec(cmd) {
|
|
|
24957
25177
|
}
|
|
24958
25178
|
}
|
|
24959
25179
|
function defaultZip(zipPath, files) {
|
|
24960
|
-
|
|
25180
|
+
execFileSync11("zip", ["-j", zipPath, ...files]);
|
|
24961
25181
|
}
|
|
24962
25182
|
async function buildDiagnosticsZip(_exec = (cmd) => safeExec(cmd), _outDir = DIAGNOSTICS_DIR, _logDir = LOG_DIR, _zip = defaultZip) {
|
|
24963
25183
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 23);
|
|
24964
|
-
const zipPath =
|
|
24965
|
-
const tmpDir =
|
|
25184
|
+
const zipPath = path43.join(_outDir, `olam-diag-${ts}.zip`);
|
|
25185
|
+
const tmpDir = fs40.mkdtempSync(path43.join(os23.tmpdir(), "olam-diag-"));
|
|
24966
25186
|
try {
|
|
24967
|
-
|
|
25187
|
+
fs40.mkdirSync(_outDir, { recursive: true });
|
|
24968
25188
|
const entries = [];
|
|
24969
25189
|
const version = process.env["OLAM_CLI_VERSION"] ?? "unknown";
|
|
24970
25190
|
const nodeVersion = process.version;
|
|
@@ -24980,14 +25200,14 @@ platform: ${platform}
|
|
|
24980
25200
|
`uptime: ${os23.uptime()}s`
|
|
24981
25201
|
].join("\n") + "\n";
|
|
24982
25202
|
_writeEntry(tmpDir, "os-info.txt", stripSecrets(osContent), entries);
|
|
24983
|
-
const depsFile =
|
|
24984
|
-
if (
|
|
24985
|
-
const deps =
|
|
25203
|
+
const depsFile = path43.join(CACHE_DIR, "deps.json");
|
|
25204
|
+
if (fs40.existsSync(depsFile)) {
|
|
25205
|
+
const deps = fs40.readFileSync(depsFile, "utf-8");
|
|
24986
25206
|
_writeEntry(tmpDir, "deps.json", stripSecrets(deps), entries);
|
|
24987
25207
|
}
|
|
24988
25208
|
const latestLog = _latestLog(_logDir);
|
|
24989
25209
|
if (latestLog) {
|
|
24990
|
-
const lines =
|
|
25210
|
+
const lines = fs40.readFileSync(latestLog, "utf-8").split("\n");
|
|
24991
25211
|
const tail = lines.slice(-LOG_TAIL_LINES).join("\n");
|
|
24992
25212
|
_writeEntry(tmpDir, "log-tail.txt", stripSecrets(tail), entries);
|
|
24993
25213
|
}
|
|
@@ -24999,38 +25219,38 @@ platform: ${platform}
|
|
|
24999
25219
|
if (authAudit) {
|
|
25000
25220
|
_writeEntry(tmpDir, "audit-auth-callers.txt", stripSecrets(authAudit), entries);
|
|
25001
25221
|
}
|
|
25002
|
-
const fileArgs = entries.map((e) =>
|
|
25222
|
+
const fileArgs = entries.map((e) => path43.join(tmpDir, e));
|
|
25003
25223
|
try {
|
|
25004
25224
|
_zip(zipPath, fileArgs);
|
|
25005
25225
|
} catch (err) {
|
|
25006
25226
|
throw new Error(`zip command produced no output file. zip stderr: ${err.message}`);
|
|
25007
25227
|
}
|
|
25008
|
-
if (!
|
|
25228
|
+
if (!fs40.existsSync(zipPath)) {
|
|
25009
25229
|
throw new Error("zip command produced no output file.");
|
|
25010
25230
|
}
|
|
25011
25231
|
return { zipPath, entries };
|
|
25012
25232
|
} finally {
|
|
25013
25233
|
try {
|
|
25014
|
-
|
|
25234
|
+
fs40.rmSync(tmpDir, { recursive: true, force: true });
|
|
25015
25235
|
} catch {
|
|
25016
25236
|
}
|
|
25017
25237
|
}
|
|
25018
25238
|
}
|
|
25019
25239
|
function _writeEntry(dir, name, content, entries) {
|
|
25020
|
-
|
|
25240
|
+
fs40.writeFileSync(path43.join(dir, name), content, { mode: 420 });
|
|
25021
25241
|
entries.push(name);
|
|
25022
25242
|
}
|
|
25023
25243
|
function _latestLog(logDir) {
|
|
25024
|
-
if (!
|
|
25025
|
-
const files =
|
|
25026
|
-
return files.length > 0 ?
|
|
25244
|
+
if (!fs40.existsSync(logDir)) return null;
|
|
25245
|
+
const files = fs40.readdirSync(logDir).filter((f) => f.startsWith("host-")).sort().reverse();
|
|
25246
|
+
return files.length > 0 ? path43.join(logDir, files[0]) : null;
|
|
25027
25247
|
}
|
|
25028
25248
|
async function buildTelemetryPayload() {
|
|
25029
25249
|
const channel = "stable";
|
|
25030
|
-
const manifestFile =
|
|
25250
|
+
const manifestFile = path43.join(CACHE_DIR, "manifest.json");
|
|
25031
25251
|
let manifestAgeHours = null;
|
|
25032
|
-
if (
|
|
25033
|
-
const mtime =
|
|
25252
|
+
if (fs40.existsSync(manifestFile)) {
|
|
25253
|
+
const mtime = fs40.statSync(manifestFile).mtime.getTime();
|
|
25034
25254
|
manifestAgeHours = Math.round((Date.now() - mtime) / 36e5);
|
|
25035
25255
|
}
|
|
25036
25256
|
return {
|
|
@@ -25074,9 +25294,9 @@ function registerDiagnose(program2) {
|
|
|
25074
25294
|
|
|
25075
25295
|
// src/lib/health-probes.ts
|
|
25076
25296
|
import { spawnSync as spawnSync14 } from "node:child_process";
|
|
25077
|
-
import { existsSync as
|
|
25078
|
-
import { homedir as
|
|
25079
|
-
import
|
|
25297
|
+
import { existsSync as existsSync44, readdirSync as readdirSync11, readFileSync as readFileSync31, statSync as statSync13 } from "node:fs";
|
|
25298
|
+
import { homedir as homedir23 } from "node:os";
|
|
25299
|
+
import path44 from "node:path";
|
|
25080
25300
|
|
|
25081
25301
|
// src/lib/kg-caps.ts
|
|
25082
25302
|
var SOFT_CAP_BYTES = 15e8;
|
|
@@ -25171,7 +25391,7 @@ function isHostCpHealthEnvelope(body) {
|
|
|
25171
25391
|
}
|
|
25172
25392
|
async function probeAuthVault(olamHomeOverride) {
|
|
25173
25393
|
const vaultPath = resolveAccountsPath(olamHomeOverride);
|
|
25174
|
-
if (!
|
|
25394
|
+
if (!existsSync44(vaultPath)) {
|
|
25175
25395
|
return {
|
|
25176
25396
|
ok: false,
|
|
25177
25397
|
message: `auth vault missing at ${vaultPath}`,
|
|
@@ -25180,7 +25400,7 @@ async function probeAuthVault(olamHomeOverride) {
|
|
|
25180
25400
|
}
|
|
25181
25401
|
let parsed;
|
|
25182
25402
|
try {
|
|
25183
|
-
parsed = JSON.parse(
|
|
25403
|
+
parsed = JSON.parse(readFileSync31(vaultPath, "utf-8"));
|
|
25184
25404
|
} catch (err) {
|
|
25185
25405
|
return {
|
|
25186
25406
|
ok: false,
|
|
@@ -25210,8 +25430,8 @@ async function probeAuthVault(olamHomeOverride) {
|
|
|
25210
25430
|
function resolveAccountsPath(olamHomeOverride) {
|
|
25211
25431
|
const explicit = process.env.OLAM_AUTH_DATA_PATH;
|
|
25212
25432
|
if (explicit) return explicit;
|
|
25213
|
-
const olamHome5 = olamHomeOverride ?? process.env.OLAM_HOME ??
|
|
25214
|
-
return
|
|
25433
|
+
const olamHome5 = olamHomeOverride ?? process.env.OLAM_HOME ?? path44.join(homedir23(), ".olam");
|
|
25434
|
+
return path44.join(olamHome5, "auth-data", "accounts.json");
|
|
25215
25435
|
}
|
|
25216
25436
|
function effectiveState2(account, now) {
|
|
25217
25437
|
const persisted = account.state ?? (account.rateLimited ? "cooldown" : "active");
|
|
@@ -25224,9 +25444,9 @@ function effectiveState2(account, now) {
|
|
|
25224
25444
|
return persisted;
|
|
25225
25445
|
}
|
|
25226
25446
|
async function probeKgStorage(olamHomeOverride) {
|
|
25227
|
-
const olamHome5 = olamHomeOverride ?? process.env.OLAM_HOME ??
|
|
25228
|
-
const kgRoot3 =
|
|
25229
|
-
const worldsRoot3 =
|
|
25447
|
+
const olamHome5 = olamHomeOverride ?? process.env.OLAM_HOME ?? path44.join(homedir23(), ".olam");
|
|
25448
|
+
const kgRoot3 = path44.join(olamHome5, "kg");
|
|
25449
|
+
const worldsRoot3 = path44.join(olamHome5, "worlds");
|
|
25230
25450
|
const kgBytes = enumerateGraphifyOut(kgRoot3, "pristine");
|
|
25231
25451
|
const overlayBytes = enumerateGraphifyOut(worldsRoot3, "overlay");
|
|
25232
25452
|
const totalBytes = kgBytes + overlayBytes;
|
|
@@ -25246,7 +25466,7 @@ async function probeKgStorage(olamHomeOverride) {
|
|
|
25246
25466
|
return { ok: true, message: `KG storage ${formatBytes4(totalBytes)} (under cap)` };
|
|
25247
25467
|
}
|
|
25248
25468
|
function enumerateGraphifyOut(root, layout) {
|
|
25249
|
-
if (!
|
|
25469
|
+
if (!existsSync44(root)) return 0;
|
|
25250
25470
|
let total = 0;
|
|
25251
25471
|
let entries;
|
|
25252
25472
|
try {
|
|
@@ -25257,9 +25477,9 @@ function enumerateGraphifyOut(root, layout) {
|
|
|
25257
25477
|
for (const entry of entries) {
|
|
25258
25478
|
if (!entry.isDirectory()) continue;
|
|
25259
25479
|
if (layout === "pristine") {
|
|
25260
|
-
total += dirSizeBytes(
|
|
25480
|
+
total += dirSizeBytes(path44.join(root, entry.name, "graphify-out"));
|
|
25261
25481
|
} else {
|
|
25262
|
-
const worldDir =
|
|
25482
|
+
const worldDir = path44.join(root, entry.name);
|
|
25263
25483
|
let clones;
|
|
25264
25484
|
try {
|
|
25265
25485
|
clones = readdirSync11(worldDir, { withFileTypes: true });
|
|
@@ -25268,14 +25488,14 @@ function enumerateGraphifyOut(root, layout) {
|
|
|
25268
25488
|
}
|
|
25269
25489
|
for (const clone of clones) {
|
|
25270
25490
|
if (!clone.isDirectory()) continue;
|
|
25271
|
-
total += dirSizeBytes(
|
|
25491
|
+
total += dirSizeBytes(path44.join(worldDir, clone.name, "graphify-out"));
|
|
25272
25492
|
}
|
|
25273
25493
|
}
|
|
25274
25494
|
}
|
|
25275
25495
|
return total;
|
|
25276
25496
|
}
|
|
25277
25497
|
function dirSizeBytes(dir) {
|
|
25278
|
-
if (!
|
|
25498
|
+
if (!existsSync44(dir)) return 0;
|
|
25279
25499
|
let total = 0;
|
|
25280
25500
|
const stack = [dir];
|
|
25281
25501
|
while (stack.length > 0) {
|
|
@@ -25287,7 +25507,7 @@ function dirSizeBytes(dir) {
|
|
|
25287
25507
|
continue;
|
|
25288
25508
|
}
|
|
25289
25509
|
for (const entry of entries) {
|
|
25290
|
-
const full =
|
|
25510
|
+
const full = path44.join(cur, entry.name);
|
|
25291
25511
|
if (entry.isSymbolicLink()) continue;
|
|
25292
25512
|
if (entry.isDirectory()) {
|
|
25293
25513
|
stack.push(full);
|
|
@@ -25531,20 +25751,20 @@ function registerCompletion(program2) {
|
|
|
25531
25751
|
// src/commands/setup.ts
|
|
25532
25752
|
init_cli_version();
|
|
25533
25753
|
import { spawn as spawn5 } from "node:child_process";
|
|
25534
|
-
import { existsSync as
|
|
25535
|
-
import { homedir as
|
|
25536
|
-
import
|
|
25754
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
25755
|
+
import { homedir as homedir24 } from "node:os";
|
|
25756
|
+
import path46 from "node:path";
|
|
25537
25757
|
import { createInterface as createInterface3 } from "node:readline";
|
|
25538
25758
|
|
|
25539
25759
|
// src/lib/shell-rc.ts
|
|
25540
|
-
import { copyFileSync as copyFileSync5, existsSync as
|
|
25541
|
-
import
|
|
25760
|
+
import { copyFileSync as copyFileSync5, existsSync as existsSync45, readFileSync as readFileSync32, renameSync as renameSync4, writeFileSync as writeFileSync20 } from "node:fs";
|
|
25761
|
+
import path45 from "node:path";
|
|
25542
25762
|
function appendIdempotent(opts) {
|
|
25543
25763
|
const { rcPath, marker, contentLine, clock = () => /* @__PURE__ */ new Date() } = opts;
|
|
25544
|
-
if (!
|
|
25764
|
+
if (!existsSync45(rcPath)) {
|
|
25545
25765
|
return { status: "no-rc-file", backupPath: null };
|
|
25546
25766
|
}
|
|
25547
|
-
const content =
|
|
25767
|
+
const content = readFileSync32(rcPath, "utf-8");
|
|
25548
25768
|
if (content.includes(marker)) {
|
|
25549
25769
|
return { status: "already-present", backupPath: null };
|
|
25550
25770
|
}
|
|
@@ -25561,9 +25781,9 @@ function appendIdempotent(opts) {
|
|
|
25561
25781
|
}
|
|
25562
25782
|
function resolveShellRc(home, shellEnv) {
|
|
25563
25783
|
if (!shellEnv) return null;
|
|
25564
|
-
const basename6 =
|
|
25565
|
-
if (basename6 === "zsh") return
|
|
25566
|
-
if (basename6 === "bash") return
|
|
25784
|
+
const basename6 = path45.basename(shellEnv);
|
|
25785
|
+
if (basename6 === "zsh") return path45.join(home, ".zshrc");
|
|
25786
|
+
if (basename6 === "bash") return path45.join(home, ".bashrc");
|
|
25567
25787
|
return null;
|
|
25568
25788
|
}
|
|
25569
25789
|
|
|
@@ -25665,7 +25885,7 @@ async function phase4ShellInit(opts, deps) {
|
|
|
25665
25885
|
if (opts.skipShellInit) {
|
|
25666
25886
|
return { ok: true, skipped: true, message: "skipped via --skip-shell-init" };
|
|
25667
25887
|
}
|
|
25668
|
-
const home = deps.home ??
|
|
25888
|
+
const home = deps.home ?? homedir24();
|
|
25669
25889
|
const shellEnv = deps.shellEnv ?? process.env.SHELL;
|
|
25670
25890
|
const rcPath = resolveShellRc(home, shellEnv);
|
|
25671
25891
|
if (rcPath === null) {
|
|
@@ -25675,7 +25895,7 @@ async function phase4ShellInit(opts, deps) {
|
|
|
25675
25895
|
message: `unsupported $SHELL (${shellEnv ?? "unset"}); add \`eval "$(olam completion <shell>)"\` to your shell rc manually`
|
|
25676
25896
|
};
|
|
25677
25897
|
}
|
|
25678
|
-
const shellBasename =
|
|
25898
|
+
const shellBasename = path46.basename(shellEnv);
|
|
25679
25899
|
const evalLine = `eval "$(olam completion ${shellBasename})"`;
|
|
25680
25900
|
const result = appendIdempotent({
|
|
25681
25901
|
rcPath,
|
|
@@ -25701,8 +25921,8 @@ async function phase4ShellInit(opts, deps) {
|
|
|
25701
25921
|
async function phase5InitProject(opts, deps) {
|
|
25702
25922
|
const cwd = deps.cwd ?? process.cwd();
|
|
25703
25923
|
const projectRoot = findProjectRoot(cwd);
|
|
25704
|
-
const configPath =
|
|
25705
|
-
if (
|
|
25924
|
+
const configPath = path46.join(projectRoot, ".olam", "config.yaml");
|
|
25925
|
+
if (existsSync46(configPath)) {
|
|
25706
25926
|
return { ok: true, message: `${configPath} present (no change)` };
|
|
25707
25927
|
}
|
|
25708
25928
|
const promptFn = deps.prompt ?? defaultPrompt;
|
|
@@ -25831,24 +26051,24 @@ function registerSetup(program2) {
|
|
|
25831
26051
|
}
|
|
25832
26052
|
|
|
25833
26053
|
// src/commands/update.ts
|
|
25834
|
-
import * as
|
|
26054
|
+
import * as fs43 from "node:fs";
|
|
25835
26055
|
import * as os25 from "node:os";
|
|
25836
|
-
import * as
|
|
26056
|
+
import * as path49 from "node:path";
|
|
25837
26057
|
import { execSync as execSync13 } from "node:child_process";
|
|
25838
26058
|
import pc23 from "picocolors";
|
|
25839
26059
|
|
|
25840
26060
|
// src/lib/symlink-reconcile.ts
|
|
25841
|
-
import * as
|
|
25842
|
-
import * as
|
|
26061
|
+
import * as fs41 from "node:fs";
|
|
26062
|
+
import * as path47 from "node:path";
|
|
25843
26063
|
var realFs = {
|
|
25844
|
-
readdirSync: (p) =>
|
|
25845
|
-
existsSync: (p) =>
|
|
25846
|
-
lstatSync: (p) =>
|
|
25847
|
-
readlinkSync: (p) =>
|
|
25848
|
-
symlinkSync: (t, l) =>
|
|
25849
|
-
unlinkSync: (p) =>
|
|
26064
|
+
readdirSync: (p) => fs41.readdirSync(p),
|
|
26065
|
+
existsSync: (p) => fs41.existsSync(p),
|
|
26066
|
+
lstatSync: (p) => fs41.lstatSync(p),
|
|
26067
|
+
readlinkSync: (p) => fs41.readlinkSync(p),
|
|
26068
|
+
symlinkSync: (t, l) => fs41.symlinkSync(t, l),
|
|
26069
|
+
unlinkSync: (p) => fs41.unlinkSync(p),
|
|
25850
26070
|
mkdirSync: (p, o) => {
|
|
25851
|
-
|
|
26071
|
+
fs41.mkdirSync(p, o);
|
|
25852
26072
|
}
|
|
25853
26073
|
};
|
|
25854
26074
|
function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
|
|
@@ -25858,8 +26078,8 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
|
|
|
25858
26078
|
_fs.mkdirSync(claudeSkillsDir, { recursive: true });
|
|
25859
26079
|
const sourceSkills = _fs.existsSync(npmSkillsDir) ? _fs.readdirSync(npmSkillsDir).filter((d) => d.startsWith("olam-")) : [];
|
|
25860
26080
|
for (const skill of sourceSkills) {
|
|
25861
|
-
const linkPath =
|
|
25862
|
-
const target =
|
|
26081
|
+
const linkPath = path47.join(claudeSkillsDir, skill);
|
|
26082
|
+
const target = path47.join(npmSkillsDir, skill);
|
|
25863
26083
|
if (!_fs.existsSync(linkPath)) {
|
|
25864
26084
|
try {
|
|
25865
26085
|
_fs.symlinkSync(target, linkPath);
|
|
@@ -25872,7 +26092,7 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
|
|
|
25872
26092
|
}
|
|
25873
26093
|
const deployedEntries = _fs.existsSync(claudeSkillsDir) ? _fs.readdirSync(claudeSkillsDir).filter((d) => d.startsWith("olam-")) : [];
|
|
25874
26094
|
for (const entry of deployedEntries) {
|
|
25875
|
-
const linkPath =
|
|
26095
|
+
const linkPath = path47.join(claudeSkillsDir, entry);
|
|
25876
26096
|
let isSymlink = false;
|
|
25877
26097
|
try {
|
|
25878
26098
|
isSymlink = _fs.lstatSync(linkPath).isSymbolicLink();
|
|
@@ -25897,9 +26117,9 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
|
|
|
25897
26117
|
|
|
25898
26118
|
// src/commands/update.ts
|
|
25899
26119
|
var PACKAGE_NAME = "@pleri/olam-cli";
|
|
25900
|
-
var CACHE_DIR2 =
|
|
25901
|
-
var LOG_DIR2 =
|
|
25902
|
-
var LAST_STABLE_FILE =
|
|
26120
|
+
var CACHE_DIR2 = path49.join(os25.homedir(), ".olam", "cache");
|
|
26121
|
+
var LOG_DIR2 = path49.join(os25.homedir(), ".olam", "log");
|
|
26122
|
+
var LAST_STABLE_FILE = path49.join(CACHE_DIR2, "last-stable.txt");
|
|
25903
26123
|
function defaultExec(cmd) {
|
|
25904
26124
|
try {
|
|
25905
26125
|
const stdout = execSync13(cmd, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
@@ -25921,22 +26141,22 @@ function getCurrentVersion(_exec = defaultExec) {
|
|
|
25921
26141
|
}
|
|
25922
26142
|
function readLastStable(file = LAST_STABLE_FILE) {
|
|
25923
26143
|
try {
|
|
25924
|
-
const v =
|
|
26144
|
+
const v = fs43.readFileSync(file, "utf-8").trim();
|
|
25925
26145
|
return v || null;
|
|
25926
26146
|
} catch {
|
|
25927
26147
|
return null;
|
|
25928
26148
|
}
|
|
25929
26149
|
}
|
|
25930
26150
|
function writeLastStable(version, file = LAST_STABLE_FILE) {
|
|
25931
|
-
|
|
25932
|
-
|
|
26151
|
+
fs43.mkdirSync(path49.dirname(file), { recursive: true });
|
|
26152
|
+
fs43.writeFileSync(file, version, { mode: 420 });
|
|
25933
26153
|
}
|
|
25934
26154
|
function logUpdateFailure(stderr) {
|
|
25935
26155
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
25936
|
-
const logFile =
|
|
26156
|
+
const logFile = path49.join(LOG_DIR2, `update-${ts}.log`);
|
|
25937
26157
|
try {
|
|
25938
|
-
|
|
25939
|
-
|
|
26158
|
+
fs43.mkdirSync(LOG_DIR2, { recursive: true });
|
|
26159
|
+
fs43.appendFileSync(logFile, `[update-failure ${(/* @__PURE__ */ new Date()).toISOString()}]
|
|
25940
26160
|
${stderr}
|
|
25941
26161
|
`, "utf-8");
|
|
25942
26162
|
} catch {
|
|
@@ -26023,8 +26243,8 @@ async function doUpdate(opts, _exec = defaultExec, _reconcile = reconcileSkillSy
|
|
|
26023
26243
|
let symlinkResult = { added: [], removed: [] };
|
|
26024
26244
|
if (npmRootResult.exitCode === 0) {
|
|
26025
26245
|
const npmRoot = npmRootResult.stdout.trim();
|
|
26026
|
-
const npmSkillsDir =
|
|
26027
|
-
const claudeSkillsDir =
|
|
26246
|
+
const npmSkillsDir = path49.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills");
|
|
26247
|
+
const claudeSkillsDir = path49.join(os25.homedir(), ".claude", "skills");
|
|
26028
26248
|
const rec = _reconcile(npmSkillsDir, claudeSkillsDir);
|
|
26029
26249
|
symlinkResult = { added: rec.added, removed: rec.removed };
|
|
26030
26250
|
if (!quiet && (rec.added.length > 0 || rec.removed.length > 0)) {
|
|
@@ -26070,8 +26290,8 @@ async function doRollback(_exec = defaultExec, _reconcile = reconcileSkillSymlin
|
|
|
26070
26290
|
if (npmRootResult.exitCode === 0) {
|
|
26071
26291
|
const npmRoot = npmRootResult.stdout.trim();
|
|
26072
26292
|
_reconcile(
|
|
26073
|
-
|
|
26074
|
-
|
|
26293
|
+
path49.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills"),
|
|
26294
|
+
path49.join(os25.homedir(), ".claude", "skills")
|
|
26075
26295
|
);
|
|
26076
26296
|
}
|
|
26077
26297
|
return { action: "rolled-back", restoredVersion: prev, exitCode: 0 };
|
|
@@ -26152,7 +26372,7 @@ function registerBegin(program2) {
|
|
|
26152
26372
|
}
|
|
26153
26373
|
|
|
26154
26374
|
// src/commands/config.ts
|
|
26155
|
-
import * as
|
|
26375
|
+
import * as fs45 from "node:fs";
|
|
26156
26376
|
import { createRequire as createRequire4 } from "node:module";
|
|
26157
26377
|
|
|
26158
26378
|
// ../core/dist/global-config/index.js
|
|
@@ -26161,12 +26381,12 @@ init_store2();
|
|
|
26161
26381
|
|
|
26162
26382
|
// ../core/dist/global-config/repos.js
|
|
26163
26383
|
init_store2();
|
|
26164
|
-
import * as
|
|
26384
|
+
import * as fs44 from "node:fs";
|
|
26165
26385
|
import * as os26 from "node:os";
|
|
26166
|
-
import * as
|
|
26386
|
+
import * as path50 from "node:path";
|
|
26167
26387
|
function expandPath(p) {
|
|
26168
26388
|
if (p === "~" || p.startsWith("~/")) {
|
|
26169
|
-
return
|
|
26389
|
+
return path50.join(os26.homedir(), p.slice(1));
|
|
26170
26390
|
}
|
|
26171
26391
|
return p;
|
|
26172
26392
|
}
|
|
@@ -26179,7 +26399,7 @@ function addRepo(entry) {
|
|
|
26179
26399
|
throw new Error(`repo "${entry.name}" already registered. Use "olam repos update" to change its path.`);
|
|
26180
26400
|
}
|
|
26181
26401
|
const resolvedPath = expandPath(entry.path);
|
|
26182
|
-
if (!
|
|
26402
|
+
if (!fs44.existsSync(resolvedPath)) {
|
|
26183
26403
|
throw new Error(`path "${entry.path}" does not exist. Verify the path is correct.`);
|
|
26184
26404
|
}
|
|
26185
26405
|
const now = Date.now();
|
|
@@ -26208,7 +26428,7 @@ function updateRepo(name, updates) {
|
|
|
26208
26428
|
throw new Error(`repo "${name}" is not registered. Run "olam repos list" to see registered repos.`);
|
|
26209
26429
|
}
|
|
26210
26430
|
const resolvedUpdatePath = updates.path !== void 0 ? expandPath(updates.path) : void 0;
|
|
26211
|
-
if (resolvedUpdatePath !== void 0 && !
|
|
26431
|
+
if (resolvedUpdatePath !== void 0 && !fs44.existsSync(resolvedUpdatePath)) {
|
|
26212
26432
|
throw new Error(`path "${updates.path}" does not exist. Verify the path is correct.`);
|
|
26213
26433
|
}
|
|
26214
26434
|
const existing = config.repos[idx];
|
|
@@ -26238,14 +26458,14 @@ function registerConfig(program2) {
|
|
|
26238
26458
|
const config = program2.command("config").description("Manage global olam configuration");
|
|
26239
26459
|
config.command("validate [path]").description("Validate ~/.olam/config.json (or a custom path) against the schema").action((filePath) => {
|
|
26240
26460
|
const resolvedPath = filePath ?? globalConfigPath();
|
|
26241
|
-
if (!
|
|
26461
|
+
if (!fs45.existsSync(resolvedPath)) {
|
|
26242
26462
|
process.stderr.write(`config file not found: ${resolvedPath}
|
|
26243
26463
|
`);
|
|
26244
26464
|
process.exit(1);
|
|
26245
26465
|
}
|
|
26246
26466
|
let raw;
|
|
26247
26467
|
try {
|
|
26248
|
-
raw =
|
|
26468
|
+
raw = fs45.readFileSync(resolvedPath, "utf-8");
|
|
26249
26469
|
} catch (err) {
|
|
26250
26470
|
const msg = err instanceof Error ? err.message : String(err);
|
|
26251
26471
|
process.stderr.write(`cannot read ${resolvedPath}: ${msg}
|
|
@@ -26568,17 +26788,17 @@ function registerWorldUpgrade(program2) {
|
|
|
26568
26788
|
|
|
26569
26789
|
// src/commands/mcp/serve.ts
|
|
26570
26790
|
init_output();
|
|
26571
|
-
import { existsSync as
|
|
26572
|
-
import { dirname as dirname25, resolve as
|
|
26791
|
+
import { existsSync as existsSync51 } from "node:fs";
|
|
26792
|
+
import { dirname as dirname25, resolve as resolve11 } from "node:path";
|
|
26573
26793
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
26574
26794
|
var here = dirname25(fileURLToPath6(import.meta.url));
|
|
26575
|
-
var BUNDLE_PATH =
|
|
26795
|
+
var BUNDLE_PATH = resolve11(here, "..", "..", "mcp-server.js");
|
|
26576
26796
|
var MISSING_BUNDLE_REMEDY = "olam mcp server bundle missing at dist/mcp-server.js. For local dev, run: node packages/cli/scripts/bundle-mcp-server.mjs. Published @pleri/olam-cli tarballs always include this bundle (per prepublishOnly).";
|
|
26577
26797
|
function registerMcpServe(cmd) {
|
|
26578
26798
|
cmd.command("serve").description(
|
|
26579
26799
|
"Run the olam MCP server (stdio transport). Claude Code wires this via `claude mcp add olam --scope user -- npx -y @pleri/olam-cli mcp serve`."
|
|
26580
26800
|
).action(async () => {
|
|
26581
|
-
if (!
|
|
26801
|
+
if (!existsSync51(BUNDLE_PATH)) {
|
|
26582
26802
|
printError(MISSING_BUNDLE_REMEDY);
|
|
26583
26803
|
process.exitCode = 1;
|
|
26584
26804
|
return;
|
|
@@ -26726,8 +26946,8 @@ var SECRET = process.env["OLAM_MCP_AUTH_SECRET"] ?? "";
|
|
|
26726
26946
|
function authHeaders() {
|
|
26727
26947
|
return SECRET ? { "X-Olam-Mcp-Secret": SECRET } : {};
|
|
26728
26948
|
}
|
|
26729
|
-
async function apiFetch(
|
|
26730
|
-
const res = await fetch(`${BASE_URL}${
|
|
26949
|
+
async function apiFetch(path56, init = {}) {
|
|
26950
|
+
const res = await fetch(`${BASE_URL}${path56}`, {
|
|
26731
26951
|
...init,
|
|
26732
26952
|
headers: {
|
|
26733
26953
|
"Content-Type": "application/json",
|
|
@@ -26987,12 +27207,12 @@ import * as readline3 from "node:readline";
|
|
|
26987
27207
|
import pc29 from "picocolors";
|
|
26988
27208
|
|
|
26989
27209
|
// src/commands/mcp/import-discovery.ts
|
|
26990
|
-
import * as
|
|
27210
|
+
import * as fs46 from "node:fs";
|
|
26991
27211
|
import * as os27 from "node:os";
|
|
26992
|
-
import * as
|
|
27212
|
+
import * as path51 from "node:path";
|
|
26993
27213
|
function readJsonFile(filePath) {
|
|
26994
27214
|
try {
|
|
26995
|
-
const raw =
|
|
27215
|
+
const raw = fs46.readFileSync(filePath, "utf-8");
|
|
26996
27216
|
return JSON.parse(raw);
|
|
26997
27217
|
} catch {
|
|
26998
27218
|
return null;
|
|
@@ -27021,24 +27241,24 @@ function extractMcpServers(obj, source, sourceLabel) {
|
|
|
27021
27241
|
}
|
|
27022
27242
|
function getClaudeDesktopPath() {
|
|
27023
27243
|
if (process.platform === "darwin") {
|
|
27024
|
-
return
|
|
27244
|
+
return path51.join(os27.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
27025
27245
|
}
|
|
27026
27246
|
if (process.platform === "win32") {
|
|
27027
|
-
const appData = process.env["APPDATA"] ??
|
|
27028
|
-
return
|
|
27247
|
+
const appData = process.env["APPDATA"] ?? path51.join(os27.homedir(), "AppData", "Roaming");
|
|
27248
|
+
return path51.join(appData, "Claude", "claude_desktop_config.json");
|
|
27029
27249
|
}
|
|
27030
|
-
return
|
|
27250
|
+
return path51.join(os27.homedir(), ".config", "Claude", "claude_desktop_config.json");
|
|
27031
27251
|
}
|
|
27032
27252
|
function getOlamRepoPaths() {
|
|
27033
27253
|
const configPaths = [
|
|
27034
|
-
|
|
27035
|
-
|
|
27254
|
+
path51.join(os27.homedir(), ".olam", "config.yaml"),
|
|
27255
|
+
path51.join(process.cwd(), ".olam", "config.yaml")
|
|
27036
27256
|
];
|
|
27037
27257
|
const paths = [];
|
|
27038
27258
|
for (const configPath of configPaths) {
|
|
27039
|
-
if (!
|
|
27259
|
+
if (!fs46.existsSync(configPath)) continue;
|
|
27040
27260
|
try {
|
|
27041
|
-
const raw =
|
|
27261
|
+
const raw = fs46.readFileSync(configPath, "utf-8");
|
|
27042
27262
|
const repoMatches = [...raw.matchAll(/path:\s*["']?([^\s"'\n]+)/g)];
|
|
27043
27263
|
for (const m of repoMatches) {
|
|
27044
27264
|
if (m[1]) paths.push(m[1]);
|
|
@@ -27054,7 +27274,7 @@ async function discoverMcpSources(repoPaths) {
|
|
|
27054
27274
|
const sources = [];
|
|
27055
27275
|
const sourceDefs = [
|
|
27056
27276
|
{
|
|
27057
|
-
path:
|
|
27277
|
+
path: path51.join(os27.homedir(), ".claude.json"),
|
|
27058
27278
|
label: "Claude Code (~/.claude.json)"
|
|
27059
27279
|
},
|
|
27060
27280
|
{
|
|
@@ -27062,19 +27282,19 @@ async function discoverMcpSources(repoPaths) {
|
|
|
27062
27282
|
label: "Claude Desktop"
|
|
27063
27283
|
},
|
|
27064
27284
|
{
|
|
27065
|
-
path:
|
|
27285
|
+
path: path51.join(os27.homedir(), ".cursor", "mcp.json"),
|
|
27066
27286
|
label: "Cursor (~/.cursor/mcp.json)"
|
|
27067
27287
|
},
|
|
27068
27288
|
{
|
|
27069
|
-
path:
|
|
27289
|
+
path: path51.join(os27.homedir(), ".codeium", "windsurf", "mcp_config.json"),
|
|
27070
27290
|
label: "Windsurf (~/.codeium/windsurf/mcp_config.json)"
|
|
27071
27291
|
}
|
|
27072
27292
|
];
|
|
27073
27293
|
const resolvedRepoPaths = repoPaths ?? getOlamRepoPaths();
|
|
27074
27294
|
for (const repoPath of resolvedRepoPaths) {
|
|
27075
27295
|
sourceDefs.push({
|
|
27076
|
-
path:
|
|
27077
|
-
label: `.mcp.json (${
|
|
27296
|
+
path: path51.join(repoPath, ".mcp.json"),
|
|
27297
|
+
label: `.mcp.json (${path51.basename(repoPath)})`
|
|
27078
27298
|
});
|
|
27079
27299
|
}
|
|
27080
27300
|
const reads = await Promise.all(
|
|
@@ -27307,97 +27527,50 @@ function registerMcp(program2) {
|
|
|
27307
27527
|
}
|
|
27308
27528
|
|
|
27309
27529
|
// src/commands/kg-build.ts
|
|
27310
|
-
|
|
27311
|
-
|
|
27312
|
-
import path53 from "node:path";
|
|
27313
|
-
|
|
27314
|
-
// ../core/dist/kg/storage-paths.js
|
|
27315
|
-
import { homedir as homedir28 } from "node:os";
|
|
27316
|
-
import { join as join48, resolve as resolve11 } from "node:path";
|
|
27317
|
-
|
|
27318
|
-
// ../core/dist/world/workspace-name.js
|
|
27319
|
-
var InvalidWorkspaceNameError = class extends Error {
|
|
27320
|
-
constructor(name, reason) {
|
|
27321
|
-
super(`invalid workspace name ${JSON.stringify(name)}: ${reason}`);
|
|
27322
|
-
this.name = "InvalidWorkspaceNameError";
|
|
27323
|
-
}
|
|
27324
|
-
};
|
|
27325
|
-
var WORKSPACE_NAME_RE = /^[a-z0-9][a-z0-9_-]*$/;
|
|
27326
|
-
function validateWorkspaceName(name) {
|
|
27327
|
-
if (typeof name !== "string" || name.length === 0) {
|
|
27328
|
-
throw new InvalidWorkspaceNameError(String(name), "must be a non-empty string");
|
|
27329
|
-
}
|
|
27330
|
-
if (!WORKSPACE_NAME_RE.test(name)) {
|
|
27331
|
-
throw new InvalidWorkspaceNameError(name, "must match ^[a-z0-9][a-z0-9_-]*$ (lowercase letters, digits, hyphens, underscores; must start with letter or digit)");
|
|
27332
|
-
}
|
|
27333
|
-
}
|
|
27334
|
-
|
|
27335
|
-
// ../core/dist/kg/storage-paths.js
|
|
27336
|
-
function olamHome3() {
|
|
27337
|
-
return process.env.OLAM_HOME ?? join48(homedir28(), ".olam");
|
|
27338
|
-
}
|
|
27339
|
-
function kgRoot() {
|
|
27340
|
-
return join48(olamHome3(), "kg");
|
|
27341
|
-
}
|
|
27342
|
-
function worldsRoot() {
|
|
27343
|
-
return join48(olamHome3(), "worlds");
|
|
27344
|
-
}
|
|
27345
|
-
function assertWithinPrefix(path55, prefix, label) {
|
|
27346
|
-
if (!path55.startsWith(prefix + "/")) {
|
|
27347
|
-
throw new Error(`${label} escape: ${path55} not under ${prefix}/`);
|
|
27348
|
-
}
|
|
27349
|
-
}
|
|
27350
|
-
function kgPristinePath(workspace) {
|
|
27351
|
-
validateWorkspaceName(workspace);
|
|
27352
|
-
const root = kgRoot();
|
|
27353
|
-
const path55 = resolve11(join48(root, workspace));
|
|
27354
|
-
assertWithinPrefix(path55, root, "kgPristinePath");
|
|
27355
|
-
return path55;
|
|
27356
|
-
}
|
|
27357
|
-
var KG_PATHS_INTERNALS = Object.freeze({
|
|
27358
|
-
olamHome: olamHome3,
|
|
27359
|
-
kgRoot,
|
|
27360
|
-
worldsRoot
|
|
27361
|
-
});
|
|
27362
|
-
|
|
27363
|
-
// src/commands/kg-build.ts
|
|
27530
|
+
init_storage_paths();
|
|
27531
|
+
init_workspace_name();
|
|
27364
27532
|
init_output();
|
|
27533
|
+
import { spawnSync as spawnSync16 } from "node:child_process";
|
|
27534
|
+
import fs49 from "node:fs";
|
|
27535
|
+
import path54 from "node:path";
|
|
27365
27536
|
|
|
27366
27537
|
// src/commands/kg-status.ts
|
|
27367
|
-
|
|
27538
|
+
init_storage_paths();
|
|
27539
|
+
init_workspace_name();
|
|
27540
|
+
import fs47 from "node:fs";
|
|
27368
27541
|
import { homedir as homedir29 } from "node:os";
|
|
27369
|
-
import
|
|
27542
|
+
import path52 from "node:path";
|
|
27370
27543
|
init_output();
|
|
27371
27544
|
function olamHome4() {
|
|
27372
|
-
return process.env.OLAM_HOME ??
|
|
27545
|
+
return process.env.OLAM_HOME ?? path52.join(homedir29(), ".olam");
|
|
27373
27546
|
}
|
|
27374
27547
|
function kgRoot2() {
|
|
27375
|
-
return
|
|
27548
|
+
return path52.join(olamHome4(), "kg");
|
|
27376
27549
|
}
|
|
27377
27550
|
function worldsRoot2() {
|
|
27378
|
-
return
|
|
27551
|
+
return path52.join(olamHome4(), "worlds");
|
|
27379
27552
|
}
|
|
27380
27553
|
function dirSizeBytes2(dir) {
|
|
27381
|
-
if (!
|
|
27554
|
+
if (!fs47.existsSync(dir)) return 0;
|
|
27382
27555
|
let total = 0;
|
|
27383
27556
|
const stack = [dir];
|
|
27384
27557
|
while (stack.length > 0) {
|
|
27385
27558
|
const cur = stack.pop();
|
|
27386
27559
|
let entries;
|
|
27387
27560
|
try {
|
|
27388
|
-
entries =
|
|
27561
|
+
entries = fs47.readdirSync(cur, { withFileTypes: true });
|
|
27389
27562
|
} catch {
|
|
27390
27563
|
continue;
|
|
27391
27564
|
}
|
|
27392
27565
|
for (const entry of entries) {
|
|
27393
|
-
const full =
|
|
27566
|
+
const full = path52.join(cur, entry.name);
|
|
27394
27567
|
if (entry.isSymbolicLink()) continue;
|
|
27395
27568
|
if (entry.isDirectory()) {
|
|
27396
27569
|
stack.push(full);
|
|
27397
27570
|
continue;
|
|
27398
27571
|
}
|
|
27399
27572
|
try {
|
|
27400
|
-
total +=
|
|
27573
|
+
total += fs47.statSync(full).size;
|
|
27401
27574
|
} catch {
|
|
27402
27575
|
}
|
|
27403
27576
|
}
|
|
@@ -27411,10 +27584,10 @@ function formatBytes5(n) {
|
|
|
27411
27584
|
return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
|
|
27412
27585
|
}
|
|
27413
27586
|
function readFreshness(workspace) {
|
|
27414
|
-
const file =
|
|
27415
|
-
if (!
|
|
27587
|
+
const file = path52.join(kgPristinePath(workspace), "freshness.json");
|
|
27588
|
+
if (!fs47.existsSync(file)) return null;
|
|
27416
27589
|
try {
|
|
27417
|
-
const raw = JSON.parse(
|
|
27590
|
+
const raw = JSON.parse(fs47.readFileSync(file, "utf-8"));
|
|
27418
27591
|
if (raw && typeof raw === "object") return raw;
|
|
27419
27592
|
return null;
|
|
27420
27593
|
} catch {
|
|
@@ -27422,10 +27595,10 @@ function readFreshness(workspace) {
|
|
|
27422
27595
|
}
|
|
27423
27596
|
}
|
|
27424
27597
|
function readOverlayNodeCount(graphifyOutDir) {
|
|
27425
|
-
const graphPath =
|
|
27426
|
-
if (!
|
|
27598
|
+
const graphPath = path52.join(graphifyOutDir, "graph.json");
|
|
27599
|
+
if (!fs47.existsSync(graphPath)) return null;
|
|
27427
27600
|
try {
|
|
27428
|
-
const raw = JSON.parse(
|
|
27601
|
+
const raw = JSON.parse(fs47.readFileSync(graphPath, "utf-8"));
|
|
27429
27602
|
if (raw && typeof raw === "object") {
|
|
27430
27603
|
const nodes = raw.nodes;
|
|
27431
27604
|
if (Array.isArray(nodes)) return nodes.length;
|
|
@@ -27437,28 +27610,28 @@ function readOverlayNodeCount(graphifyOutDir) {
|
|
|
27437
27610
|
}
|
|
27438
27611
|
function listOverlays() {
|
|
27439
27612
|
const root = worldsRoot2();
|
|
27440
|
-
if (!
|
|
27613
|
+
if (!fs47.existsSync(root)) return [];
|
|
27441
27614
|
const records = [];
|
|
27442
27615
|
let worldDirs;
|
|
27443
27616
|
try {
|
|
27444
|
-
worldDirs =
|
|
27617
|
+
worldDirs = fs47.readdirSync(root, { withFileTypes: true });
|
|
27445
27618
|
} catch {
|
|
27446
27619
|
return [];
|
|
27447
27620
|
}
|
|
27448
27621
|
for (const worldEntry of worldDirs) {
|
|
27449
27622
|
if (!worldEntry.isDirectory()) continue;
|
|
27450
27623
|
const worldId = worldEntry.name;
|
|
27451
|
-
const worldDir =
|
|
27624
|
+
const worldDir = path52.join(root, worldId);
|
|
27452
27625
|
let cloneDirs;
|
|
27453
27626
|
try {
|
|
27454
|
-
cloneDirs =
|
|
27627
|
+
cloneDirs = fs47.readdirSync(worldDir, { withFileTypes: true });
|
|
27455
27628
|
} catch {
|
|
27456
27629
|
continue;
|
|
27457
27630
|
}
|
|
27458
27631
|
for (const cloneEntry of cloneDirs) {
|
|
27459
27632
|
if (!cloneEntry.isDirectory()) continue;
|
|
27460
|
-
const graphifyOut =
|
|
27461
|
-
if (!
|
|
27633
|
+
const graphifyOut = path52.join(worldDir, cloneEntry.name, "graphify-out");
|
|
27634
|
+
if (!fs47.existsSync(graphifyOut)) continue;
|
|
27462
27635
|
records.push({
|
|
27463
27636
|
world_id: worldId,
|
|
27464
27637
|
clone_dir: cloneEntry.name,
|
|
@@ -27472,11 +27645,11 @@ function listOverlays() {
|
|
|
27472
27645
|
}
|
|
27473
27646
|
function listPristines(overlays) {
|
|
27474
27647
|
const root = kgRoot2();
|
|
27475
|
-
if (!
|
|
27648
|
+
if (!fs47.existsSync(root)) return [];
|
|
27476
27649
|
const records = [];
|
|
27477
27650
|
let entries;
|
|
27478
27651
|
try {
|
|
27479
|
-
entries =
|
|
27652
|
+
entries = fs47.readdirSync(root, { withFileTypes: true });
|
|
27480
27653
|
} catch {
|
|
27481
27654
|
return [];
|
|
27482
27655
|
}
|
|
@@ -27489,7 +27662,7 @@ function listPristines(overlays) {
|
|
|
27489
27662
|
continue;
|
|
27490
27663
|
}
|
|
27491
27664
|
const fresh = readFreshness(workspace);
|
|
27492
|
-
const graphifyOut =
|
|
27665
|
+
const graphifyOut = path52.join(kgPristinePath(workspace), "graphify-out");
|
|
27493
27666
|
const size = dirSizeBytes2(graphifyOut);
|
|
27494
27667
|
const worldCount = overlays.filter((o) => o.clone_dir === workspace).length;
|
|
27495
27668
|
records.push({
|
|
@@ -27621,12 +27794,14 @@ function registerKgStatusCommand(kg) {
|
|
|
27621
27794
|
}
|
|
27622
27795
|
|
|
27623
27796
|
// src/commands/kg-watch.ts
|
|
27624
|
-
|
|
27625
|
-
|
|
27626
|
-
import path52 from "node:path";
|
|
27797
|
+
init_storage_paths();
|
|
27798
|
+
init_workspace_name();
|
|
27627
27799
|
init_output();
|
|
27800
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
27801
|
+
import fs48 from "node:fs";
|
|
27802
|
+
import path53 from "node:path";
|
|
27628
27803
|
function pidFilePath(workspace) {
|
|
27629
|
-
return
|
|
27804
|
+
return path53.join(kgPristinePath(workspace), ".watch.pid");
|
|
27630
27805
|
}
|
|
27631
27806
|
function isPidAlive3(pid) {
|
|
27632
27807
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
@@ -27641,39 +27816,39 @@ function isPidAlive3(pid) {
|
|
|
27641
27816
|
}
|
|
27642
27817
|
function readAndClassifyPid(workspace) {
|
|
27643
27818
|
const file = pidFilePath(workspace);
|
|
27644
|
-
if (!
|
|
27819
|
+
if (!fs48.existsSync(file)) return { status: "no-pidfile", pid: null };
|
|
27645
27820
|
let pid;
|
|
27646
27821
|
try {
|
|
27647
|
-
const raw =
|
|
27822
|
+
const raw = fs48.readFileSync(file, "utf-8").trim();
|
|
27648
27823
|
pid = Number.parseInt(raw, 10);
|
|
27649
27824
|
} catch {
|
|
27650
|
-
|
|
27825
|
+
fs48.rmSync(file, { force: true });
|
|
27651
27826
|
return { status: "stale-reclaimed", pid: null };
|
|
27652
27827
|
}
|
|
27653
27828
|
if (!Number.isInteger(pid) || pid <= 0) {
|
|
27654
|
-
|
|
27829
|
+
fs48.rmSync(file, { force: true });
|
|
27655
27830
|
return { status: "stale-reclaimed", pid: null };
|
|
27656
27831
|
}
|
|
27657
27832
|
if (isPidAlive3(pid)) return { status: "active", pid };
|
|
27658
|
-
|
|
27833
|
+
fs48.rmSync(file, { force: true });
|
|
27659
27834
|
return { status: "stale-reclaimed", pid: null };
|
|
27660
27835
|
}
|
|
27661
27836
|
function writePidFile(workspace, pid) {
|
|
27662
27837
|
const file = pidFilePath(workspace);
|
|
27663
|
-
const dir =
|
|
27664
|
-
|
|
27665
|
-
|
|
27838
|
+
const dir = path53.dirname(file);
|
|
27839
|
+
fs48.mkdirSync(dir, { recursive: true });
|
|
27840
|
+
fs48.writeFileSync(file, String(pid), { encoding: "utf-8" });
|
|
27666
27841
|
}
|
|
27667
27842
|
function removePidFile(workspace) {
|
|
27668
27843
|
const file = pidFilePath(workspace);
|
|
27669
27844
|
try {
|
|
27670
|
-
|
|
27845
|
+
fs48.rmSync(file, { force: true });
|
|
27671
27846
|
} catch {
|
|
27672
27847
|
}
|
|
27673
27848
|
}
|
|
27674
27849
|
async function runKgWatch(workspaceArg, opts, deps = {}) {
|
|
27675
27850
|
const cwd = deps.cwd ?? opts.cwd ?? process.cwd();
|
|
27676
|
-
const name = workspaceArg ??
|
|
27851
|
+
const name = workspaceArg ?? path53.basename(cwd).toLowerCase();
|
|
27677
27852
|
try {
|
|
27678
27853
|
validateWorkspaceName(name);
|
|
27679
27854
|
} catch (err) {
|
|
@@ -27681,7 +27856,7 @@ async function runKgWatch(workspaceArg, opts, deps = {}) {
|
|
|
27681
27856
|
return { exitCode: 1, pidWritten: false };
|
|
27682
27857
|
}
|
|
27683
27858
|
const pristinePath = kgPristinePath(name);
|
|
27684
|
-
const graphPath =
|
|
27859
|
+
const graphPath = path53.join(pristinePath, "graphify-out", "graph.json");
|
|
27685
27860
|
const pidState = readAndClassifyPid(name);
|
|
27686
27861
|
if (pidState.status === "active") {
|
|
27687
27862
|
printError(
|
|
@@ -27747,7 +27922,7 @@ function registerKgWatchCommand(kg) {
|
|
|
27747
27922
|
var DEFAULT_DEVBOX_IMAGE2 = "olam-devbox:latest";
|
|
27748
27923
|
function resolveWorkspace(arg) {
|
|
27749
27924
|
const cwd = process.cwd();
|
|
27750
|
-
const name = arg ??
|
|
27925
|
+
const name = arg ?? path54.basename(cwd).toLowerCase();
|
|
27751
27926
|
validateWorkspaceName(name);
|
|
27752
27927
|
return { name, sourcePath: cwd };
|
|
27753
27928
|
}
|
|
@@ -27769,10 +27944,10 @@ function copyWorkspaceToScratch(source, scratch) {
|
|
|
27769
27944
|
return "cp-r";
|
|
27770
27945
|
}
|
|
27771
27946
|
function parseNodeCount(graphifyOutDir) {
|
|
27772
|
-
const graphPath =
|
|
27773
|
-
if (!
|
|
27947
|
+
const graphPath = path54.join(graphifyOutDir, "graph.json");
|
|
27948
|
+
if (!fs49.existsSync(graphPath)) return null;
|
|
27774
27949
|
try {
|
|
27775
|
-
const content =
|
|
27950
|
+
const content = fs49.readFileSync(graphPath, "utf-8");
|
|
27776
27951
|
const data = JSON.parse(content);
|
|
27777
27952
|
return Array.isArray(data.nodes) ? data.nodes.length : null;
|
|
27778
27953
|
} catch {
|
|
@@ -27806,10 +27981,10 @@ async function runKgBuild(workspaceArg, options = {}) {
|
|
|
27806
27981
|
return { exitCode: 2 };
|
|
27807
27982
|
}
|
|
27808
27983
|
const outDir = kgPristinePath(workspace.name);
|
|
27809
|
-
const scratchDir =
|
|
27810
|
-
|
|
27811
|
-
if (
|
|
27812
|
-
|
|
27984
|
+
const scratchDir = path54.join(outDir, "scratch");
|
|
27985
|
+
fs49.mkdirSync(outDir, { recursive: true });
|
|
27986
|
+
if (fs49.existsSync(scratchDir)) fs49.rmSync(scratchDir, { recursive: true, force: true });
|
|
27987
|
+
fs49.mkdirSync(scratchDir);
|
|
27813
27988
|
const human = !options.json;
|
|
27814
27989
|
if (human) {
|
|
27815
27990
|
printInfo("kg build", `workspace=${workspace.name} source=${workspace.sourcePath}`);
|
|
@@ -27837,14 +28012,14 @@ async function runKgBuild(workspaceArg, options = {}) {
|
|
|
27837
28012
|
printError(`graphify update failed (exit ${r.status})`);
|
|
27838
28013
|
return { exitCode: r.status ?? 1 };
|
|
27839
28014
|
}
|
|
27840
|
-
const scratchOut =
|
|
27841
|
-
const finalOut =
|
|
27842
|
-
if (!
|
|
28015
|
+
const scratchOut = path54.join(scratchDir, "graphify-out");
|
|
28016
|
+
const finalOut = path54.join(outDir, "graphify-out");
|
|
28017
|
+
if (!fs49.existsSync(scratchOut)) {
|
|
27843
28018
|
printError(`graphify produced no graphify-out/ in scratch (${scratchOut})`);
|
|
27844
28019
|
return { exitCode: 1 };
|
|
27845
28020
|
}
|
|
27846
|
-
if (
|
|
27847
|
-
|
|
28021
|
+
if (fs49.existsSync(finalOut)) fs49.rmSync(finalOut, { recursive: true, force: true });
|
|
28022
|
+
fs49.renameSync(scratchOut, finalOut);
|
|
27848
28023
|
const durationMs = Date.now() - started;
|
|
27849
28024
|
const nodeCount = parseNodeCount(finalOut);
|
|
27850
28025
|
const version = readGraphifyVersion(image);
|
|
@@ -27856,8 +28031,8 @@ async function runKgBuild(workspaceArg, options = {}) {
|
|
|
27856
28031
|
workspace: workspace.name,
|
|
27857
28032
|
scratch_strategy: scratchStrategy
|
|
27858
28033
|
};
|
|
27859
|
-
|
|
27860
|
-
|
|
28034
|
+
fs49.writeFileSync(
|
|
28035
|
+
path54.join(outDir, "freshness.json"),
|
|
27861
28036
|
JSON.stringify(freshness, null, 2) + "\n",
|
|
27862
28037
|
"utf-8"
|
|
27863
28038
|
);
|
|
@@ -27871,8 +28046,8 @@ async function runKgBuild(workspaceArg, options = {}) {
|
|
|
27871
28046
|
}
|
|
27872
28047
|
return { exitCode: 0, freshness, outputDir: finalOut };
|
|
27873
28048
|
} finally {
|
|
27874
|
-
if (
|
|
27875
|
-
|
|
28049
|
+
if (fs49.existsSync(scratchDir)) {
|
|
28050
|
+
fs49.rmSync(scratchDir, { recursive: true, force: true });
|
|
27876
28051
|
}
|
|
27877
28052
|
}
|
|
27878
28053
|
}
|
|
@@ -27889,18 +28064,18 @@ function registerKg(program2) {
|
|
|
27889
28064
|
}
|
|
27890
28065
|
|
|
27891
28066
|
// src/pleri-config.ts
|
|
27892
|
-
import * as
|
|
27893
|
-
import * as
|
|
28067
|
+
import * as fs50 from "node:fs";
|
|
28068
|
+
import * as path55 from "node:path";
|
|
27894
28069
|
function isPleriConfigured(configDir = process.env.OLAM_CONFIG_DIR ?? ".olam") {
|
|
27895
28070
|
if (process.env.PLERI_BASE_URL) {
|
|
27896
28071
|
return true;
|
|
27897
28072
|
}
|
|
27898
|
-
const configPath =
|
|
27899
|
-
if (!
|
|
28073
|
+
const configPath = path55.join(configDir, "config.yaml");
|
|
28074
|
+
if (!fs50.existsSync(configPath)) {
|
|
27900
28075
|
return false;
|
|
27901
28076
|
}
|
|
27902
28077
|
try {
|
|
27903
|
-
const contents =
|
|
28078
|
+
const contents = fs50.readFileSync(configPath, "utf8");
|
|
27904
28079
|
return /^[^#\n]*\bpleri:/m.test(contents);
|
|
27905
28080
|
} catch {
|
|
27906
28081
|
return false;
|