@pleri/olam-cli 0.1.68 → 0.1.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/audit-publish-deps-contract.test.d.ts +26 -0
- package/dist/__tests__/audit-publish-deps-contract.test.d.ts.map +1 -0
- package/dist/__tests__/audit-publish-deps-contract.test.js +86 -0
- package/dist/__tests__/audit-publish-deps-contract.test.js.map +1 -0
- package/dist/__tests__/host-cp-gh-token.test.js +18 -8
- package/dist/__tests__/host-cp-gh-token.test.js.map +1 -1
- package/dist/__tests__/host-cp.test.js +13 -5
- package/dist/__tests__/host-cp.test.js.map +1 -1
- package/dist/cli-version.d.ts +16 -0
- package/dist/cli-version.d.ts.map +1 -0
- package/dist/cli-version.js +39 -0
- package/dist/cli-version.js.map +1 -0
- package/dist/commands/host-cp.d.ts.map +1 -1
- package/dist/commands/host-cp.js +10 -0
- package/dist/commands/host-cp.js.map +1 -1
- package/dist/image-digests.json +5 -5
- package/dist/index.js +609 -596
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +301 -164
- package/host-cp/compose.yaml +6 -0
- package/host-cp/src/listening-server-poller.mjs +141 -0
- package/host-cp/src/port-bridge-manager.mjs +290 -0
- package/host-cp/src/server.mjs +48 -94
- package/host-cp/src/version-status.mjs +36 -0
- package/package.json +4 -2
package/dist/mcp-server.js
CHANGED
|
@@ -3228,8 +3228,8 @@ var require_utils = __commonJS({
|
|
|
3228
3228
|
}
|
|
3229
3229
|
return ind;
|
|
3230
3230
|
}
|
|
3231
|
-
function removeDotSegments(
|
|
3232
|
-
let input =
|
|
3231
|
+
function removeDotSegments(path24) {
|
|
3232
|
+
let input = path24;
|
|
3233
3233
|
const output = [];
|
|
3234
3234
|
let nextSlash = -1;
|
|
3235
3235
|
let len = 0;
|
|
@@ -3428,8 +3428,8 @@ var require_schemes = __commonJS({
|
|
|
3428
3428
|
wsComponent.secure = void 0;
|
|
3429
3429
|
}
|
|
3430
3430
|
if (wsComponent.resourceName) {
|
|
3431
|
-
const [
|
|
3432
|
-
wsComponent.path =
|
|
3431
|
+
const [path24, query] = wsComponent.resourceName.split("?");
|
|
3432
|
+
wsComponent.path = path24 && path24 !== "/" ? path24 : void 0;
|
|
3433
3433
|
wsComponent.query = query;
|
|
3434
3434
|
wsComponent.resourceName = void 0;
|
|
3435
3435
|
}
|
|
@@ -6791,12 +6791,12 @@ var require_dist = __commonJS({
|
|
|
6791
6791
|
throw new Error(`Unknown format "${name}"`);
|
|
6792
6792
|
return f;
|
|
6793
6793
|
};
|
|
6794
|
-
function addFormats(ajv, list,
|
|
6794
|
+
function addFormats(ajv, list, fs20, exportName) {
|
|
6795
6795
|
var _a;
|
|
6796
6796
|
var _b;
|
|
6797
6797
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
6798
6798
|
for (const f of list)
|
|
6799
|
-
ajv.addFormat(f,
|
|
6799
|
+
ajv.addFormat(f, fs20[f]);
|
|
6800
6800
|
}
|
|
6801
6801
|
module.exports = exports = formatsPlugin;
|
|
6802
6802
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -7002,10 +7002,10 @@ function assignProp(target, prop, value) {
|
|
|
7002
7002
|
configurable: true
|
|
7003
7003
|
});
|
|
7004
7004
|
}
|
|
7005
|
-
function getElementAtPath(obj,
|
|
7006
|
-
if (!
|
|
7005
|
+
function getElementAtPath(obj, path24) {
|
|
7006
|
+
if (!path24)
|
|
7007
7007
|
return obj;
|
|
7008
|
-
return
|
|
7008
|
+
return path24.reduce((acc, key) => acc?.[key], obj);
|
|
7009
7009
|
}
|
|
7010
7010
|
function promiseAllObject(promisesObj) {
|
|
7011
7011
|
const keys = Object.keys(promisesObj);
|
|
@@ -7325,11 +7325,11 @@ function aborted(x, startIndex = 0) {
|
|
|
7325
7325
|
}
|
|
7326
7326
|
return false;
|
|
7327
7327
|
}
|
|
7328
|
-
function prefixIssues(
|
|
7328
|
+
function prefixIssues(path24, issues) {
|
|
7329
7329
|
return issues.map((iss) => {
|
|
7330
7330
|
var _a;
|
|
7331
7331
|
(_a = iss).path ?? (_a.path = []);
|
|
7332
|
-
iss.path.unshift(
|
|
7332
|
+
iss.path.unshift(path24);
|
|
7333
7333
|
return iss;
|
|
7334
7334
|
});
|
|
7335
7335
|
}
|
|
@@ -13403,8 +13403,8 @@ function getErrorMap() {
|
|
|
13403
13403
|
|
|
13404
13404
|
// ../../node_modules/zod/v3/helpers/parseUtil.js
|
|
13405
13405
|
var makeIssue = (params) => {
|
|
13406
|
-
const { data, path:
|
|
13407
|
-
const fullPath = [...
|
|
13406
|
+
const { data, path: path24, errorMaps, issueData } = params;
|
|
13407
|
+
const fullPath = [...path24, ...issueData.path || []];
|
|
13408
13408
|
const fullIssue = {
|
|
13409
13409
|
...issueData,
|
|
13410
13410
|
path: fullPath
|
|
@@ -13520,11 +13520,11 @@ var errorUtil;
|
|
|
13520
13520
|
|
|
13521
13521
|
// ../../node_modules/zod/v3/types.js
|
|
13522
13522
|
var ParseInputLazyPath = class {
|
|
13523
|
-
constructor(parent, value,
|
|
13523
|
+
constructor(parent, value, path24, key) {
|
|
13524
13524
|
this._cachedPath = [];
|
|
13525
13525
|
this.parent = parent;
|
|
13526
13526
|
this.data = value;
|
|
13527
|
-
this._path =
|
|
13527
|
+
this._path = path24;
|
|
13528
13528
|
this._key = key;
|
|
13529
13529
|
}
|
|
13530
13530
|
get path() {
|
|
@@ -21365,8 +21365,8 @@ var AuthClient = class {
|
|
|
21365
21365
|
throw new Error(`failed to report rate-limit for ${accountId} (HTTP ${res.status})`);
|
|
21366
21366
|
}
|
|
21367
21367
|
}
|
|
21368
|
-
async request(method,
|
|
21369
|
-
const url = `${this.baseUrl}${
|
|
21368
|
+
async request(method, path24, body, attempt = 0) {
|
|
21369
|
+
const url = `${this.baseUrl}${path24}`;
|
|
21370
21370
|
const controller = new AbortController();
|
|
21371
21371
|
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
21372
21372
|
const headers = {};
|
|
@@ -21384,7 +21384,7 @@ var AuthClient = class {
|
|
|
21384
21384
|
} catch (err) {
|
|
21385
21385
|
if (attempt < RETRY_COUNT && isTransient(err)) {
|
|
21386
21386
|
await sleep(RETRY_BACKOFF_MS * (attempt + 1));
|
|
21387
|
-
return this.request(method,
|
|
21387
|
+
return this.request(method, path24, body, attempt + 1);
|
|
21388
21388
|
}
|
|
21389
21389
|
throw err;
|
|
21390
21390
|
} finally {
|
|
@@ -22191,12 +22191,12 @@ function register3(server, _ctx, _initError) {
|
|
|
22191
22191
|
registry2.close();
|
|
22192
22192
|
}
|
|
22193
22193
|
try {
|
|
22194
|
-
const { default:
|
|
22195
|
-
const { default:
|
|
22196
|
-
const { default:
|
|
22197
|
-
const tokenPath =
|
|
22198
|
-
if (
|
|
22199
|
-
const token =
|
|
22194
|
+
const { default: fs20 } = await import("node:fs");
|
|
22195
|
+
const { default: os13 } = await import("node:os");
|
|
22196
|
+
const { default: path24 } = await import("node:path");
|
|
22197
|
+
const tokenPath = path24.join(os13.homedir(), ".olam", "host-cp.token");
|
|
22198
|
+
if (fs20.existsSync(tokenPath)) {
|
|
22199
|
+
const token = fs20.readFileSync(tokenPath, "utf-8").trim();
|
|
22200
22200
|
await fetch("http://127.0.0.1:19000/api/admin/world-pr", {
|
|
22201
22201
|
method: "POST",
|
|
22202
22202
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
@@ -22389,7 +22389,7 @@ var KNOWN_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
22389
22389
|
"deploy"
|
|
22390
22390
|
]);
|
|
22391
22391
|
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
22392
|
-
function refineForbiddenKeys(value,
|
|
22392
|
+
function refineForbiddenKeys(value, path24, ctx, rejectSource) {
|
|
22393
22393
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
22394
22394
|
return;
|
|
22395
22395
|
}
|
|
@@ -22397,12 +22397,12 @@ function refineForbiddenKeys(value, path23, ctx, rejectSource) {
|
|
|
22397
22397
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
22398
22398
|
ctx.addIssue({
|
|
22399
22399
|
code: external_exports.ZodIssueCode.custom,
|
|
22400
|
-
path: [...
|
|
22400
|
+
path: [...path24, key],
|
|
22401
22401
|
message: `forbidden key "${key}" (prototype-pollution surface)`
|
|
22402
22402
|
});
|
|
22403
22403
|
continue;
|
|
22404
22404
|
}
|
|
22405
|
-
if (rejectSource &&
|
|
22405
|
+
if (rejectSource && path24.length === 0 && key === "source") {
|
|
22406
22406
|
ctx.addIssue({
|
|
22407
22407
|
code: external_exports.ZodIssueCode.custom,
|
|
22408
22408
|
path: ["source"],
|
|
@@ -22410,21 +22410,21 @@ function refineForbiddenKeys(value, path23, ctx, rejectSource) {
|
|
|
22410
22410
|
});
|
|
22411
22411
|
continue;
|
|
22412
22412
|
}
|
|
22413
|
-
refineForbiddenKeys(value[key], [...
|
|
22413
|
+
refineForbiddenKeys(value[key], [...path24, key], ctx, false);
|
|
22414
22414
|
}
|
|
22415
22415
|
}
|
|
22416
|
-
function rejectForbiddenKeys(value,
|
|
22416
|
+
function rejectForbiddenKeys(value, path24, rejectSource) {
|
|
22417
22417
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
22418
22418
|
return;
|
|
22419
22419
|
}
|
|
22420
22420
|
for (const key of Object.keys(value)) {
|
|
22421
22421
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
22422
|
-
throw new Error(`[manifest] ${
|
|
22422
|
+
throw new Error(`[manifest] ${path24}: forbidden key "${key}" (prototype-pollution surface)`);
|
|
22423
22423
|
}
|
|
22424
22424
|
if (rejectSource && key === "source") {
|
|
22425
|
-
throw new Error(`[manifest] ${
|
|
22425
|
+
throw new Error(`[manifest] ${path24}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
|
|
22426
22426
|
}
|
|
22427
|
-
rejectForbiddenKeys(value[key], `${
|
|
22427
|
+
rejectForbiddenKeys(value[key], `${path24}.${key}`, false);
|
|
22428
22428
|
}
|
|
22429
22429
|
}
|
|
22430
22430
|
function unknownTopLevelKeys(parsed) {
|
|
@@ -22862,10 +22862,10 @@ function extractMcpConfig(claudeJsonPath) {
|
|
|
22862
22862
|
}
|
|
22863
22863
|
return { mcpServers, secrets };
|
|
22864
22864
|
}
|
|
22865
|
-
function readOptional(
|
|
22866
|
-
if (!existsSync6(
|
|
22865
|
+
function readOptional(path24) {
|
|
22866
|
+
if (!existsSync6(path24)) return null;
|
|
22867
22867
|
try {
|
|
22868
|
-
return readFileSync5(
|
|
22868
|
+
return readFileSync5(path24, "utf8");
|
|
22869
22869
|
} catch {
|
|
22870
22870
|
return null;
|
|
22871
22871
|
}
|
|
@@ -24008,8 +24008,8 @@ var CloudflareProvider = class extends ComputeProvider {
|
|
|
24008
24008
|
// -----------------------------------------------------------------------
|
|
24009
24009
|
// Internal fetch helper
|
|
24010
24010
|
// -----------------------------------------------------------------------
|
|
24011
|
-
async request(
|
|
24012
|
-
const url = `${this.config.workerUrl}${
|
|
24011
|
+
async request(path24, method, body) {
|
|
24012
|
+
const url = `${this.config.workerUrl}${path24}`;
|
|
24013
24013
|
const bearer = await this.config.mintToken();
|
|
24014
24014
|
const headers = {
|
|
24015
24015
|
Authorization: `Bearer ${bearer}`
|
|
@@ -26442,10 +26442,10 @@ async function writeManifest(args) {
|
|
|
26442
26442
|
capturedAt: args.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
26443
26443
|
shots: entries
|
|
26444
26444
|
};
|
|
26445
|
-
const
|
|
26446
|
-
await writeFile(
|
|
26445
|
+
const path24 = join12(args.outDir, "manifest.json");
|
|
26446
|
+
await writeFile(path24, `${JSON.stringify(manifest, null, 2)}
|
|
26447
26447
|
`, "utf8");
|
|
26448
|
-
return { path:
|
|
26448
|
+
return { path: path24, manifest };
|
|
26449
26449
|
}
|
|
26450
26450
|
|
|
26451
26451
|
// ../mcp-server/src/tools/_capture/proxy.ts
|
|
@@ -26699,9 +26699,9 @@ async function startProxy(opts) {
|
|
|
26699
26699
|
const liveCompiled = verified.allowedPaths.map(compileGlob);
|
|
26700
26700
|
const target = parseRequestTarget(req);
|
|
26701
26701
|
if (!target) return httpReject(400, "invalid_target");
|
|
26702
|
-
const
|
|
26703
|
-
if (!liveCompiled.some((re) => re.test(
|
|
26704
|
-
return httpReject(403, "outside_allow_list", { path:
|
|
26702
|
+
const path24 = target.pathname;
|
|
26703
|
+
if (!liveCompiled.some((re) => re.test(path24))) {
|
|
26704
|
+
return httpReject(403, "outside_allow_list", { path: path24 });
|
|
26705
26705
|
}
|
|
26706
26706
|
const headerWorld = req.headers[WORLD_ASSERT_HEADER];
|
|
26707
26707
|
const headerWorldStr = typeof headerWorld === "string" ? headerWorld : Array.isArray(headerWorld) && headerWorld.length > 0 ? headerWorld[0] : void 0;
|
|
@@ -27480,14 +27480,14 @@ async function runShot(browser, shot, outDir, format, jpegQuality, allowEval, as
|
|
|
27480
27480
|
await page.waitForTimeout(shot.afterLoadMs);
|
|
27481
27481
|
}
|
|
27482
27482
|
const ext = format === "jpeg" ? "jpg" : "png";
|
|
27483
|
-
const
|
|
27483
|
+
const path24 = join13(outDir, `${shot.name}.${ext}`);
|
|
27484
27484
|
await page.screenshot({
|
|
27485
|
-
path:
|
|
27485
|
+
path: path24,
|
|
27486
27486
|
type: format,
|
|
27487
27487
|
...format === "jpeg" ? { quality: jpegQuality } : {},
|
|
27488
27488
|
fullPage: false
|
|
27489
27489
|
});
|
|
27490
|
-
return { name: shot.name, path:
|
|
27490
|
+
return { name: shot.name, path: path24, urlRedacted: redactUrl(shot.url), viewport };
|
|
27491
27491
|
} finally {
|
|
27492
27492
|
await context.close();
|
|
27493
27493
|
}
|
|
@@ -27930,12 +27930,12 @@ function openUrl(url) {
|
|
|
27930
27930
|
var HOST_CP_URL = "http://127.0.0.1:19000";
|
|
27931
27931
|
async function readHostCpToken2() {
|
|
27932
27932
|
try {
|
|
27933
|
-
const { default:
|
|
27934
|
-
const { default:
|
|
27935
|
-
const { default:
|
|
27936
|
-
const tp =
|
|
27937
|
-
if (!
|
|
27938
|
-
return { token:
|
|
27933
|
+
const { default: fs20 } = await import("node:fs");
|
|
27934
|
+
const { default: os13 } = await import("node:os");
|
|
27935
|
+
const { default: path24 } = await import("node:path");
|
|
27936
|
+
const tp = path24.join(os13.homedir(), ".olam", "host-cp.token");
|
|
27937
|
+
if (!fs20.existsSync(tp)) return { token: null };
|
|
27938
|
+
return { token: fs20.readFileSync(tp, "utf-8").trim() };
|
|
27939
27939
|
} catch {
|
|
27940
27940
|
return { token: null };
|
|
27941
27941
|
}
|
|
@@ -28382,9 +28382,9 @@ function register22(server, _ctx, _initError) {
|
|
|
28382
28382
|
description: external_exports.string().optional().describe("Optional human-readable description."),
|
|
28383
28383
|
defaultBranch: external_exports.string().optional().describe("Default branch name (e.g. main).")
|
|
28384
28384
|
},
|
|
28385
|
-
async ({ name, path:
|
|
28385
|
+
async ({ name, path: path24, description, defaultBranch }) => {
|
|
28386
28386
|
try {
|
|
28387
|
-
const entry = addRepo({ name, path:
|
|
28387
|
+
const entry = addRepo({ name, path: path24, description, defaultBranch });
|
|
28388
28388
|
return {
|
|
28389
28389
|
content: [{
|
|
28390
28390
|
type: "text",
|
|
@@ -28425,9 +28425,9 @@ function register22(server, _ctx, _initError) {
|
|
|
28425
28425
|
description: external_exports.string().optional().describe("New description."),
|
|
28426
28426
|
defaultBranch: external_exports.string().optional().describe("New default branch.")
|
|
28427
28427
|
},
|
|
28428
|
-
async ({ name, path:
|
|
28428
|
+
async ({ name, path: path24, description, defaultBranch }) => {
|
|
28429
28429
|
try {
|
|
28430
|
-
const entry = updateRepo(name, { path:
|
|
28430
|
+
const entry = updateRepo(name, { path: path24, description, defaultBranch });
|
|
28431
28431
|
return {
|
|
28432
28432
|
content: [{
|
|
28433
28433
|
type: "text",
|
|
@@ -28441,6 +28441,142 @@ function register22(server, _ctx, _initError) {
|
|
|
28441
28441
|
);
|
|
28442
28442
|
}
|
|
28443
28443
|
|
|
28444
|
+
// ../mcp-server/src/tools/process-port.ts
|
|
28445
|
+
var process_port_exports = {};
|
|
28446
|
+
__export(process_port_exports, {
|
|
28447
|
+
register: () => register23,
|
|
28448
|
+
resolveHostCpToken: () => resolveHostCpToken
|
|
28449
|
+
});
|
|
28450
|
+
import fs10 from "node:fs";
|
|
28451
|
+
import os9 from "node:os";
|
|
28452
|
+
import path14 from "node:path";
|
|
28453
|
+
var HOST_CP_BASE = "http://127.0.0.1:19000";
|
|
28454
|
+
function resolveHostCpToken() {
|
|
28455
|
+
const envToken = process.env["OLAM_HOST_CP_TOKEN"];
|
|
28456
|
+
if (envToken) return envToken;
|
|
28457
|
+
const tokenPath = path14.join(os9.homedir(), ".olam", "host-cp.token");
|
|
28458
|
+
if (fs10.existsSync(tokenPath)) return fs10.readFileSync(tokenPath, "utf-8").trim();
|
|
28459
|
+
return null;
|
|
28460
|
+
}
|
|
28461
|
+
function tokenMissingError() {
|
|
28462
|
+
return {
|
|
28463
|
+
content: [{
|
|
28464
|
+
type: "text",
|
|
28465
|
+
text: "host-cp token not found. Set OLAM_HOST_CP_TOKEN or write ~/.olam/host-cp.token."
|
|
28466
|
+
}],
|
|
28467
|
+
isError: true
|
|
28468
|
+
};
|
|
28469
|
+
}
|
|
28470
|
+
function asMessage5(err) {
|
|
28471
|
+
return err instanceof Error ? err.message : String(err);
|
|
28472
|
+
}
|
|
28473
|
+
function register23(server, _ctx, _initError) {
|
|
28474
|
+
server.tool(
|
|
28475
|
+
"olam_process_list",
|
|
28476
|
+
"List running processes inside a world container. Returns a process table snapshot via host-cp. Fields per process: pid, user, cpu, mem, started, state, command.",
|
|
28477
|
+
{
|
|
28478
|
+
world_id: external_exports.string().describe("World ID.")
|
|
28479
|
+
},
|
|
28480
|
+
async ({ world_id }) => {
|
|
28481
|
+
const token = resolveHostCpToken();
|
|
28482
|
+
if (!token) return tokenMissingError();
|
|
28483
|
+
try {
|
|
28484
|
+
const res = await fetch(`${HOST_CP_BASE}/api/worlds/${world_id}/processes`, {
|
|
28485
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
28486
|
+
signal: AbortSignal.timeout(1e4)
|
|
28487
|
+
});
|
|
28488
|
+
const body = await res.text();
|
|
28489
|
+
if (!res.ok) {
|
|
28490
|
+
return {
|
|
28491
|
+
content: [{ type: "text", text: `host-cp ${res.status}: ${body}` }],
|
|
28492
|
+
isError: true
|
|
28493
|
+
};
|
|
28494
|
+
}
|
|
28495
|
+
const data = JSON.parse(body);
|
|
28496
|
+
return {
|
|
28497
|
+
content: [{ type: "text", text: JSON.stringify({ processes: data.processes }, null, 2) }]
|
|
28498
|
+
};
|
|
28499
|
+
} catch (err) {
|
|
28500
|
+
return { content: [{ type: "text", text: asMessage5(err) }], isError: true };
|
|
28501
|
+
}
|
|
28502
|
+
}
|
|
28503
|
+
);
|
|
28504
|
+
server.tool(
|
|
28505
|
+
"olam_port_expose",
|
|
28506
|
+
"Expose a port inside a world container to the host by creating a socat bridge. Returns the host-side URL and bridge metadata. The bridge persists until removed with olam_port_unexpose.",
|
|
28507
|
+
{
|
|
28508
|
+
world_id: external_exports.string().describe("World ID."),
|
|
28509
|
+
port: external_exports.number().int().min(1).max(65535).describe("Container port to expose on the host.")
|
|
28510
|
+
},
|
|
28511
|
+
async ({ world_id, port }) => {
|
|
28512
|
+
const token = resolveHostCpToken();
|
|
28513
|
+
if (!token) return tokenMissingError();
|
|
28514
|
+
try {
|
|
28515
|
+
const res = await fetch(`${HOST_CP_BASE}/api/worlds/${world_id}/server-bridges`, {
|
|
28516
|
+
method: "POST",
|
|
28517
|
+
headers: {
|
|
28518
|
+
"Content-Type": "application/json",
|
|
28519
|
+
Authorization: `Bearer ${token}`
|
|
28520
|
+
},
|
|
28521
|
+
body: JSON.stringify({ port }),
|
|
28522
|
+
signal: AbortSignal.timeout(3e4)
|
|
28523
|
+
});
|
|
28524
|
+
const body = await res.text();
|
|
28525
|
+
if (!res.ok) {
|
|
28526
|
+
return {
|
|
28527
|
+
content: [{ type: "text", text: `host-cp ${res.status}: ${body}` }],
|
|
28528
|
+
isError: true
|
|
28529
|
+
};
|
|
28530
|
+
}
|
|
28531
|
+
const data = JSON.parse(body);
|
|
28532
|
+
return {
|
|
28533
|
+
content: [{
|
|
28534
|
+
type: "text",
|
|
28535
|
+
text: JSON.stringify({
|
|
28536
|
+
url: `http://localhost:${data.hostPort}`,
|
|
28537
|
+
host_port: data.hostPort,
|
|
28538
|
+
sidecar_container_id: data.containerId,
|
|
28539
|
+
container_port: data.containerPort,
|
|
28540
|
+
container_name: data.containerName
|
|
28541
|
+
}, null, 2)
|
|
28542
|
+
}]
|
|
28543
|
+
};
|
|
28544
|
+
} catch (err) {
|
|
28545
|
+
return { content: [{ type: "text", text: asMessage5(err) }], isError: true };
|
|
28546
|
+
}
|
|
28547
|
+
}
|
|
28548
|
+
);
|
|
28549
|
+
server.tool(
|
|
28550
|
+
"olam_port_unexpose",
|
|
28551
|
+
"Tear down a port bridge for a world container. Removes the socat sidecar and frees the host port.",
|
|
28552
|
+
{
|
|
28553
|
+
world_id: external_exports.string().describe("World ID."),
|
|
28554
|
+
port: external_exports.number().int().min(1).max(65535).describe("Container port whose bridge should be removed.")
|
|
28555
|
+
},
|
|
28556
|
+
async ({ world_id, port }) => {
|
|
28557
|
+
const token = resolveHostCpToken();
|
|
28558
|
+
if (!token) return tokenMissingError();
|
|
28559
|
+
try {
|
|
28560
|
+
const res = await fetch(`${HOST_CP_BASE}/api/worlds/${world_id}/server-bridges/${port}`, {
|
|
28561
|
+
method: "DELETE",
|
|
28562
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
28563
|
+
signal: AbortSignal.timeout(1e4)
|
|
28564
|
+
});
|
|
28565
|
+
if (!res.ok) {
|
|
28566
|
+
const body = await res.text();
|
|
28567
|
+
return {
|
|
28568
|
+
content: [{ type: "text", text: `host-cp ${res.status}: ${body}` }],
|
|
28569
|
+
isError: true
|
|
28570
|
+
};
|
|
28571
|
+
}
|
|
28572
|
+
return { content: [{ type: "text", text: JSON.stringify({ ok: true }) }] };
|
|
28573
|
+
} catch (err) {
|
|
28574
|
+
return { content: [{ type: "text", text: asMessage5(err) }], isError: true };
|
|
28575
|
+
}
|
|
28576
|
+
}
|
|
28577
|
+
);
|
|
28578
|
+
}
|
|
28579
|
+
|
|
28444
28580
|
// ../mcp-server/src/tools/index.ts
|
|
28445
28581
|
var toolModules = [
|
|
28446
28582
|
init_exports,
|
|
@@ -28464,7 +28600,8 @@ var toolModules = [
|
|
|
28464
28600
|
lane_merge_exports,
|
|
28465
28601
|
capture_view_exports,
|
|
28466
28602
|
create_from_prompt_exports,
|
|
28467
|
-
repo_exports
|
|
28603
|
+
repo_exports,
|
|
28604
|
+
process_port_exports
|
|
28468
28605
|
];
|
|
28469
28606
|
function registerAllTools(server, ctx, initError) {
|
|
28470
28607
|
for (const mod of toolModules) {
|
|
@@ -28496,8 +28633,8 @@ function createServer3(ctx, initError) {
|
|
|
28496
28633
|
}
|
|
28497
28634
|
|
|
28498
28635
|
// ../core/dist/config/loader.js
|
|
28499
|
-
import * as
|
|
28500
|
-
import * as
|
|
28636
|
+
import * as fs12 from "node:fs";
|
|
28637
|
+
import * as path15 from "node:path";
|
|
28501
28638
|
import { parse as parseYaml2 } from "yaml";
|
|
28502
28639
|
|
|
28503
28640
|
// ../core/dist/config/schema.js
|
|
@@ -28877,11 +29014,11 @@ function substituteEnvVars(obj) {
|
|
|
28877
29014
|
}
|
|
28878
29015
|
|
|
28879
29016
|
// ../core/dist/config/dotenv.js
|
|
28880
|
-
import * as
|
|
29017
|
+
import * as fs11 from "node:fs";
|
|
28881
29018
|
function loadDotEnv(envPath) {
|
|
28882
|
-
if (!
|
|
29019
|
+
if (!fs11.existsSync(envPath))
|
|
28883
29020
|
return;
|
|
28884
|
-
const content =
|
|
29021
|
+
const content = fs11.readFileSync(envPath, "utf-8");
|
|
28885
29022
|
for (const line of content.split("\n")) {
|
|
28886
29023
|
const trimmed = line.trim();
|
|
28887
29024
|
if (!trimmed || trimmed.startsWith("#"))
|
|
@@ -28900,18 +29037,18 @@ function loadDotEnv(envPath) {
|
|
|
28900
29037
|
// ../core/dist/config/loader.js
|
|
28901
29038
|
function findConfigFile(startDir) {
|
|
28902
29039
|
const searched = [];
|
|
28903
|
-
let current =
|
|
29040
|
+
let current = path15.resolve(startDir);
|
|
28904
29041
|
while (true) {
|
|
28905
|
-
const newLayout =
|
|
28906
|
-
const legacyLayout =
|
|
29042
|
+
const newLayout = path15.join(current, CONFIG_DIR_NAME, CONFIG_FILENAME);
|
|
29043
|
+
const legacyLayout = path15.join(current, LEGACY_CONFIG_FILENAME);
|
|
28907
29044
|
searched.push(newLayout, legacyLayout);
|
|
28908
|
-
if (
|
|
29045
|
+
if (fs12.existsSync(newLayout)) {
|
|
28909
29046
|
return { path: newLayout, isLegacy: false };
|
|
28910
29047
|
}
|
|
28911
|
-
if (
|
|
29048
|
+
if (fs12.existsSync(legacyLayout)) {
|
|
28912
29049
|
return { path: legacyLayout, isLegacy: true };
|
|
28913
29050
|
}
|
|
28914
|
-
const parent =
|
|
29051
|
+
const parent = path15.dirname(current);
|
|
28915
29052
|
if (parent === current)
|
|
28916
29053
|
break;
|
|
28917
29054
|
current = parent;
|
|
@@ -28926,12 +29063,12 @@ function loadConfig(startDir) {
|
|
|
28926
29063
|
Run /olam:init to migrate to .olam/config.yaml
|
|
28927
29064
|
`);
|
|
28928
29065
|
} else {
|
|
28929
|
-
const envPath =
|
|
29066
|
+
const envPath = path15.join(path15.dirname(found.path), ".env");
|
|
28930
29067
|
loadDotEnv(envPath);
|
|
28931
29068
|
}
|
|
28932
29069
|
let rawContent;
|
|
28933
29070
|
try {
|
|
28934
|
-
rawContent =
|
|
29071
|
+
rawContent = fs12.readFileSync(found.path, "utf-8");
|
|
28935
29072
|
} catch (err) {
|
|
28936
29073
|
throw new Error(`Failed to read ${found.path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
28937
29074
|
}
|
|
@@ -28963,9 +29100,9 @@ function loadConfig(startDir) {
|
|
|
28963
29100
|
// ../core/dist/world/manager.js
|
|
28964
29101
|
import * as crypto4 from "node:crypto";
|
|
28965
29102
|
import { execSync as execSync4 } from "node:child_process";
|
|
28966
|
-
import * as
|
|
28967
|
-
import * as
|
|
28968
|
-
import * as
|
|
29103
|
+
import * as fs17 from "node:fs";
|
|
29104
|
+
import * as os11 from "node:os";
|
|
29105
|
+
import * as path21 from "node:path";
|
|
28969
29106
|
|
|
28970
29107
|
// ../core/dist/world/state.js
|
|
28971
29108
|
var VALID_TRANSITIONS = {
|
|
@@ -29047,8 +29184,8 @@ function resolveDevboxImage(config2, tag) {
|
|
|
29047
29184
|
|
|
29048
29185
|
// ../core/dist/world/worktree.js
|
|
29049
29186
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
29050
|
-
import * as
|
|
29051
|
-
import * as
|
|
29187
|
+
import * as fs13 from "node:fs";
|
|
29188
|
+
import * as path16 from "node:path";
|
|
29052
29189
|
function resolveGitDir(repo) {
|
|
29053
29190
|
if (repo.path) {
|
|
29054
29191
|
return repo.path;
|
|
@@ -29058,11 +29195,11 @@ function resolveGitDir(repo) {
|
|
|
29058
29195
|
async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
29059
29196
|
const created = [];
|
|
29060
29197
|
for (const repo of repos) {
|
|
29061
|
-
const worktreePath =
|
|
29198
|
+
const worktreePath = path16.join(workspacePath, repo.name);
|
|
29062
29199
|
const gitDir = resolveGitDir(repo);
|
|
29063
29200
|
const branchName = branch || `olam/${worldId}`;
|
|
29064
29201
|
try {
|
|
29065
|
-
|
|
29202
|
+
fs13.mkdirSync(path16.dirname(worktreePath), { recursive: true });
|
|
29066
29203
|
execFileSync2("git", ["worktree", "add", worktreePath, "-b", branchName], {
|
|
29067
29204
|
cwd: gitDir,
|
|
29068
29205
|
stdio: "pipe"
|
|
@@ -29095,7 +29232,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
|
29095
29232
|
}
|
|
29096
29233
|
async function removeWorktrees(repos, workspacePath) {
|
|
29097
29234
|
for (const repo of repos) {
|
|
29098
|
-
const worktreePath =
|
|
29235
|
+
const worktreePath = path16.join(workspacePath, repo.name);
|
|
29099
29236
|
let gitDir;
|
|
29100
29237
|
try {
|
|
29101
29238
|
gitDir = resolveGitDir(repo);
|
|
@@ -29170,9 +29307,9 @@ function removeBranch(repo, branch) {
|
|
|
29170
29307
|
|
|
29171
29308
|
// ../core/dist/world/baseline-diff.js
|
|
29172
29309
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
29173
|
-
import * as
|
|
29174
|
-
import * as
|
|
29175
|
-
import * as
|
|
29310
|
+
import * as fs14 from "node:fs";
|
|
29311
|
+
import * as os10 from "node:os";
|
|
29312
|
+
import * as path17 from "node:path";
|
|
29176
29313
|
var DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
29177
29314
|
function expandHome(p, homedir13) {
|
|
29178
29315
|
return p.replace(/^~(?=$|\/|\\)/, homedir13());
|
|
@@ -29198,10 +29335,10 @@ ${stderr}`;
|
|
|
29198
29335
|
}
|
|
29199
29336
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
29200
29337
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync3(cmd, args, opts));
|
|
29201
|
-
const homedir13 = deps.homedir ?? (() =>
|
|
29202
|
-
const baselineDir =
|
|
29338
|
+
const homedir13 = deps.homedir ?? (() => os10.homedir());
|
|
29339
|
+
const baselineDir = path17.join(workspacePath, ".olam", "baseline");
|
|
29203
29340
|
try {
|
|
29204
|
-
|
|
29341
|
+
fs14.mkdirSync(baselineDir, { recursive: true });
|
|
29205
29342
|
} catch (err) {
|
|
29206
29343
|
const msg = err instanceof Error ? err.message : String(err);
|
|
29207
29344
|
console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
|
|
@@ -29213,9 +29350,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
29213
29350
|
if (!repo.path)
|
|
29214
29351
|
continue;
|
|
29215
29352
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
29216
|
-
const outPath =
|
|
29353
|
+
const outPath = path17.join(baselineDir, filename);
|
|
29217
29354
|
const repoPath = expandHome(repo.path, homedir13);
|
|
29218
|
-
if (!
|
|
29355
|
+
if (!fs14.existsSync(repoPath)) {
|
|
29219
29356
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
29220
29357
|
# (skipped: path ${repoPath} does not exist)
|
|
29221
29358
|
`);
|
|
@@ -29282,7 +29419,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
29282
29419
|
}
|
|
29283
29420
|
function writeBaselineFile(outPath, content) {
|
|
29284
29421
|
try {
|
|
29285
|
-
|
|
29422
|
+
fs14.writeFileSync(outPath, content);
|
|
29286
29423
|
} catch (err) {
|
|
29287
29424
|
const msg = err instanceof Error ? err.message : String(err);
|
|
29288
29425
|
console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
|
|
@@ -29290,8 +29427,8 @@ function writeBaselineFile(outPath, content) {
|
|
|
29290
29427
|
}
|
|
29291
29428
|
function stripWorktreeEdits(repos, workspacePath) {
|
|
29292
29429
|
for (const repo of repos) {
|
|
29293
|
-
const worktreePath =
|
|
29294
|
-
if (!
|
|
29430
|
+
const worktreePath = path17.join(workspacePath, repo.name);
|
|
29431
|
+
if (!fs14.existsSync(worktreePath))
|
|
29295
29432
|
continue;
|
|
29296
29433
|
try {
|
|
29297
29434
|
execFileSync3("git", ["checkout", "--", "."], {
|
|
@@ -29321,12 +29458,12 @@ function formatBaselineSummary(result) {
|
|
|
29321
29458
|
}
|
|
29322
29459
|
|
|
29323
29460
|
// ../core/dist/world/context-injection.js
|
|
29324
|
-
import * as
|
|
29325
|
-
import * as
|
|
29461
|
+
import * as fs15 from "node:fs";
|
|
29462
|
+
import * as path18 from "node:path";
|
|
29326
29463
|
function injectWorldContext(opts) {
|
|
29327
29464
|
const { world, task, linearTicketId, claudeMdExtra, taskContext, services, pleriPlaneUrl } = opts;
|
|
29328
|
-
const claudeDir =
|
|
29329
|
-
|
|
29465
|
+
const claudeDir = path18.join(world.workspacePath, ".claude");
|
|
29466
|
+
fs15.mkdirSync(claudeDir, { recursive: true });
|
|
29330
29467
|
const sections = [];
|
|
29331
29468
|
sections.push(`# Olam World: ${world.name}`);
|
|
29332
29469
|
sections.push("");
|
|
@@ -29487,7 +29624,7 @@ function injectWorldContext(opts) {
|
|
|
29487
29624
|
sections.push("");
|
|
29488
29625
|
}
|
|
29489
29626
|
const content = sections.join("\n");
|
|
29490
|
-
|
|
29627
|
+
fs15.writeFileSync(path18.join(claudeDir, "CLAUDE.md"), content);
|
|
29491
29628
|
}
|
|
29492
29629
|
function formatTaskSource(ctx) {
|
|
29493
29630
|
if (ctx.source === "linear" && ctx.ticketId) {
|
|
@@ -29501,9 +29638,9 @@ function formatTaskSource(ctx) {
|
|
|
29501
29638
|
function hasPlanFile(world) {
|
|
29502
29639
|
if (world.repos.length === 0)
|
|
29503
29640
|
return false;
|
|
29504
|
-
const plansDir =
|
|
29641
|
+
const plansDir = path18.join(world.workspacePath, world.repos[0], "docs", "plans");
|
|
29505
29642
|
try {
|
|
29506
|
-
return
|
|
29643
|
+
return fs15.existsSync(plansDir) && fs15.readdirSync(plansDir).length > 0;
|
|
29507
29644
|
} catch {
|
|
29508
29645
|
return false;
|
|
29509
29646
|
}
|
|
@@ -30169,14 +30306,14 @@ function gcloudAvailable(execFn = defaultExecFn) {
|
|
|
30169
30306
|
}
|
|
30170
30307
|
|
|
30171
30308
|
// ../core/dist/world/olam-yaml.js
|
|
30172
|
-
import * as
|
|
30309
|
+
import * as path19 from "node:path";
|
|
30173
30310
|
import YAML2 from "yaml";
|
|
30174
30311
|
function enrichReposWithManifests(repos, workspacePath) {
|
|
30175
30312
|
return repos.map((repo) => {
|
|
30176
30313
|
if (repo.manifest !== void 0 && repo.manifest !== null) {
|
|
30177
30314
|
return repo;
|
|
30178
30315
|
}
|
|
30179
|
-
const repoDir =
|
|
30316
|
+
const repoDir = path19.join(workspacePath, repo.name);
|
|
30180
30317
|
let manifest = null;
|
|
30181
30318
|
try {
|
|
30182
30319
|
manifest = loadRepoManifest(repoDir);
|
|
@@ -30191,8 +30328,8 @@ function enrichReposWithManifests(repos, workspacePath) {
|
|
|
30191
30328
|
}
|
|
30192
30329
|
|
|
30193
30330
|
// ../core/dist/policies/loader.js
|
|
30194
|
-
import * as
|
|
30195
|
-
import * as
|
|
30331
|
+
import * as fs16 from "node:fs";
|
|
30332
|
+
import * as path20 from "node:path";
|
|
30196
30333
|
import { parse as parseYaml3 } from "yaml";
|
|
30197
30334
|
function parseFrontmatter(content) {
|
|
30198
30335
|
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
|
|
@@ -30212,20 +30349,20 @@ function toStringArray(v) {
|
|
|
30212
30349
|
return v.filter((x) => typeof x === "string");
|
|
30213
30350
|
}
|
|
30214
30351
|
function loadPolicies(workspaceRoot) {
|
|
30215
|
-
const policiesDir =
|
|
30216
|
-
if (!
|
|
30352
|
+
const policiesDir = path20.join(workspaceRoot, ".olam", "policies");
|
|
30353
|
+
if (!fs16.existsSync(policiesDir))
|
|
30217
30354
|
return [];
|
|
30218
30355
|
let files;
|
|
30219
30356
|
try {
|
|
30220
|
-
files =
|
|
30357
|
+
files = fs16.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
|
|
30221
30358
|
} catch {
|
|
30222
30359
|
return [];
|
|
30223
30360
|
}
|
|
30224
30361
|
const policies = [];
|
|
30225
30362
|
for (const file of files) {
|
|
30226
|
-
const filePath =
|
|
30363
|
+
const filePath = path20.join(policiesDir, file);
|
|
30227
30364
|
try {
|
|
30228
|
-
const content =
|
|
30365
|
+
const content = fs16.readFileSync(filePath, "utf8");
|
|
30229
30366
|
const parsed = parseFrontmatter(content);
|
|
30230
30367
|
if (!parsed) {
|
|
30231
30368
|
console.warn(`[policies] skipping ${file}: no valid frontmatter block`);
|
|
@@ -30764,7 +30901,7 @@ var WorldManager = class {
|
|
|
30764
30901
|
}
|
|
30765
30902
|
}
|
|
30766
30903
|
const worldId = generateWorldId();
|
|
30767
|
-
const workspacePath =
|
|
30904
|
+
const workspacePath = path21.join(os11.homedir(), ".olam", "worlds", worldId);
|
|
30768
30905
|
const portOffset = this.registry.getNextPortOffset();
|
|
30769
30906
|
const branch = opts.branchName ?? `olam/${worldId}`;
|
|
30770
30907
|
const repos = this.resolveReposWithWorkspace(opts);
|
|
@@ -30820,38 +30957,38 @@ var WorldManager = class {
|
|
|
30820
30957
|
for (const repo of repos) {
|
|
30821
30958
|
if (!repo.path)
|
|
30822
30959
|
continue;
|
|
30823
|
-
const sourceRoot = repo.path.replace(/^~/,
|
|
30824
|
-
const worktreeRoot =
|
|
30825
|
-
if (!
|
|
30960
|
+
const sourceRoot = repo.path.replace(/^~/, os11.homedir());
|
|
30961
|
+
const worktreeRoot = path21.join(workspacePath, repo.name);
|
|
30962
|
+
if (!fs17.existsSync(sourceRoot) || !fs17.existsSync(worktreeRoot))
|
|
30826
30963
|
continue;
|
|
30827
30964
|
let copied = 0;
|
|
30828
30965
|
for (const pattern of RUNTIME_FILE_PATTERNS) {
|
|
30829
30966
|
const matches2 = [];
|
|
30830
30967
|
if (pattern.includes("*")) {
|
|
30831
|
-
const [dir, glob] = [
|
|
30832
|
-
const sourceDir =
|
|
30833
|
-
if (
|
|
30968
|
+
const [dir, glob] = [path21.dirname(pattern), path21.basename(pattern)];
|
|
30969
|
+
const sourceDir = path21.join(sourceRoot, dir);
|
|
30970
|
+
if (fs17.existsSync(sourceDir)) {
|
|
30834
30971
|
const ext = glob.replace(/^\*+/, "");
|
|
30835
30972
|
try {
|
|
30836
|
-
for (const entry of
|
|
30973
|
+
for (const entry of fs17.readdirSync(sourceDir)) {
|
|
30837
30974
|
if (ext === "" || entry.endsWith(ext))
|
|
30838
|
-
matches2.push(
|
|
30975
|
+
matches2.push(path21.join(dir, entry));
|
|
30839
30976
|
}
|
|
30840
30977
|
} catch {
|
|
30841
30978
|
}
|
|
30842
30979
|
}
|
|
30843
|
-
} else if (
|
|
30980
|
+
} else if (fs17.existsSync(path21.join(sourceRoot, pattern))) {
|
|
30844
30981
|
matches2.push(pattern);
|
|
30845
30982
|
}
|
|
30846
30983
|
for (const rel of matches2) {
|
|
30847
|
-
const src =
|
|
30848
|
-
const dst =
|
|
30984
|
+
const src = path21.join(sourceRoot, rel);
|
|
30985
|
+
const dst = path21.join(worktreeRoot, rel);
|
|
30849
30986
|
try {
|
|
30850
|
-
const st =
|
|
30987
|
+
const st = fs17.statSync(src);
|
|
30851
30988
|
if (!st.isFile())
|
|
30852
30989
|
continue;
|
|
30853
|
-
|
|
30854
|
-
|
|
30990
|
+
fs17.mkdirSync(path21.dirname(dst), { recursive: true });
|
|
30991
|
+
fs17.copyFileSync(src, dst);
|
|
30855
30992
|
copied++;
|
|
30856
30993
|
} catch {
|
|
30857
30994
|
}
|
|
@@ -30951,7 +31088,7 @@ var WorldManager = class {
|
|
|
30951
31088
|
try {
|
|
30952
31089
|
const hostExec = makeHostExecFn();
|
|
30953
31090
|
for (const repo of repos) {
|
|
30954
|
-
const repoDir =
|
|
31091
|
+
const repoDir = path21.join(workspacePath, repo.name);
|
|
30955
31092
|
if (repo.stack && Object.keys(repo.stack).length > 0) {
|
|
30956
31093
|
preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
|
|
30957
31094
|
} else {
|
|
@@ -31008,10 +31145,10 @@ var WorldManager = class {
|
|
|
31008
31145
|
const worldEnv = {};
|
|
31009
31146
|
if (opts.task)
|
|
31010
31147
|
worldEnv.OLAM_TASK = opts.task;
|
|
31011
|
-
const r2CredsPath =
|
|
31012
|
-
if (
|
|
31148
|
+
const r2CredsPath = path21.join(os11.homedir(), ".olam", "r2-credentials.json");
|
|
31149
|
+
if (fs17.existsSync(r2CredsPath)) {
|
|
31013
31150
|
try {
|
|
31014
|
-
const r2Raw =
|
|
31151
|
+
const r2Raw = fs17.readFileSync(r2CredsPath, "utf-8").trim();
|
|
31015
31152
|
if (r2Raw.length > 0) {
|
|
31016
31153
|
const r2 = JSON.parse(r2Raw);
|
|
31017
31154
|
if (typeof r2.account_id === "string")
|
|
@@ -31028,10 +31165,10 @@ var WorldManager = class {
|
|
|
31028
31165
|
} catch {
|
|
31029
31166
|
}
|
|
31030
31167
|
}
|
|
31031
|
-
const keysYamlPath =
|
|
31032
|
-
if (
|
|
31168
|
+
const keysYamlPath = path21.join(os11.homedir(), ".olam", "keys.yaml");
|
|
31169
|
+
if (fs17.existsSync(keysYamlPath)) {
|
|
31033
31170
|
try {
|
|
31034
|
-
const keysRaw =
|
|
31171
|
+
const keysRaw = fs17.readFileSync(keysYamlPath, "utf-8").trim();
|
|
31035
31172
|
if (keysRaw.length > 0) {
|
|
31036
31173
|
const parsed = YAML3.parse(keysRaw);
|
|
31037
31174
|
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
@@ -31078,10 +31215,10 @@ var WorldManager = class {
|
|
|
31078
31215
|
worldEnv[k] = v;
|
|
31079
31216
|
}
|
|
31080
31217
|
for (const { repoName, relativePath, content } of fileWrites) {
|
|
31081
|
-
const absPath =
|
|
31218
|
+
const absPath = path21.join(workspacePath, repoName, relativePath);
|
|
31082
31219
|
try {
|
|
31083
|
-
|
|
31084
|
-
|
|
31220
|
+
fs17.mkdirSync(path21.dirname(absPath), { recursive: true });
|
|
31221
|
+
fs17.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
|
|
31085
31222
|
mode: 384
|
|
31086
31223
|
});
|
|
31087
31224
|
console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
|
|
@@ -31233,7 +31370,7 @@ var WorldManager = class {
|
|
|
31233
31370
|
let taskWithPolicies = opts.task;
|
|
31234
31371
|
try {
|
|
31235
31372
|
const allPolicies = repos.flatMap((repo) => {
|
|
31236
|
-
const repoWorktree =
|
|
31373
|
+
const repoWorktree = path21.join(workspacePath, repo.name);
|
|
31237
31374
|
return loadPolicies(repoWorktree);
|
|
31238
31375
|
});
|
|
31239
31376
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -31249,8 +31386,8 @@ var WorldManager = class {
|
|
|
31249
31386
|
${opts.task}`;
|
|
31250
31387
|
execSync4(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
|
|
31251
31388
|
for (const repo of repos) {
|
|
31252
|
-
const policiesDir =
|
|
31253
|
-
if (
|
|
31389
|
+
const policiesDir = path21.join(workspacePath, repo.name, ".olam", "policies");
|
|
31390
|
+
if (fs17.existsSync(policiesDir)) {
|
|
31254
31391
|
execSync4(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
|
|
31255
31392
|
}
|
|
31256
31393
|
}
|
|
@@ -31329,8 +31466,8 @@ ${opts.task}`;
|
|
|
31329
31466
|
} catch {
|
|
31330
31467
|
}
|
|
31331
31468
|
try {
|
|
31332
|
-
|
|
31333
|
-
if (
|
|
31469
|
+
fs17.rmSync(world.workspacePath, { recursive: true, force: true });
|
|
31470
|
+
if (fs17.existsSync(world.workspacePath)) {
|
|
31334
31471
|
console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
|
|
31335
31472
|
}
|
|
31336
31473
|
} catch (err) {
|
|
@@ -31415,14 +31552,14 @@ ${opts.task}`;
|
|
|
31415
31552
|
return names.map((name) => this.config.repos.find((r) => r.name === name)).filter((r) => r !== void 0);
|
|
31416
31553
|
}
|
|
31417
31554
|
transportPlanFile(planFilePath, workspacePath, repoNames) {
|
|
31418
|
-
const planContent =
|
|
31419
|
-
const planFileName =
|
|
31555
|
+
const planContent = fs17.readFileSync(planFilePath, "utf-8");
|
|
31556
|
+
const planFileName = path21.basename(planFilePath);
|
|
31420
31557
|
const targetRepo = repoNames[0];
|
|
31421
31558
|
if (!targetRepo)
|
|
31422
31559
|
return;
|
|
31423
|
-
const plansDir =
|
|
31424
|
-
|
|
31425
|
-
|
|
31560
|
+
const plansDir = path21.join(workspacePath, targetRepo, "docs", "plans");
|
|
31561
|
+
fs17.mkdirSync(plansDir, { recursive: true });
|
|
31562
|
+
fs17.writeFileSync(path21.join(plansDir, planFileName), planContent);
|
|
31426
31563
|
}
|
|
31427
31564
|
resolveServices(repos) {
|
|
31428
31565
|
const services = [];
|
|
@@ -31507,8 +31644,8 @@ import * as http2 from "node:http";
|
|
|
31507
31644
|
|
|
31508
31645
|
// ../core/dist/dashboard/server.js
|
|
31509
31646
|
import * as http from "node:http";
|
|
31510
|
-
import * as
|
|
31511
|
-
import * as
|
|
31647
|
+
import * as fs18 from "node:fs";
|
|
31648
|
+
import * as path22 from "node:path";
|
|
31512
31649
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
31513
31650
|
|
|
31514
31651
|
// ../core/dist/dashboard/serialize.js
|
|
@@ -31843,7 +31980,7 @@ function notFound(res) {
|
|
|
31843
31980
|
}
|
|
31844
31981
|
function openThoughtStore(workspacePath) {
|
|
31845
31982
|
const dbPath = getWorldDbPath(workspacePath);
|
|
31846
|
-
if (!
|
|
31983
|
+
if (!fs18.existsSync(dbPath))
|
|
31847
31984
|
return null;
|
|
31848
31985
|
return new ThoughtLocalStore(dbPath);
|
|
31849
31986
|
}
|
|
@@ -32014,13 +32151,13 @@ function findSessionInWorld(registry2, sessionId) {
|
|
|
32014
32151
|
}
|
|
32015
32152
|
function createDashboardServer(opts) {
|
|
32016
32153
|
const { port, registry: registry2 } = opts;
|
|
32017
|
-
const thisDir =
|
|
32018
|
-
const defaultPublicDir =
|
|
32154
|
+
const thisDir = path22.dirname(fileURLToPath2(import.meta.url));
|
|
32155
|
+
const defaultPublicDir = path22.resolve(thisDir, "../../../control-plane/public");
|
|
32019
32156
|
const publicDir = opts.publicDir ?? defaultPublicDir;
|
|
32020
|
-
let hasPublicDir =
|
|
32157
|
+
let hasPublicDir = fs18.existsSync(publicDir);
|
|
32021
32158
|
const server = http.createServer((req, res) => {
|
|
32022
32159
|
if (!hasPublicDir) {
|
|
32023
|
-
hasPublicDir =
|
|
32160
|
+
hasPublicDir = fs18.existsSync(publicDir);
|
|
32024
32161
|
}
|
|
32025
32162
|
const host = req.headers.host ?? `localhost:${port}`;
|
|
32026
32163
|
const url = new URL(req.url ?? "/", `http://${host}`);
|
|
@@ -32294,22 +32431,22 @@ function createDashboardServer(opts) {
|
|
|
32294
32431
|
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>`);
|
|
32295
32432
|
return;
|
|
32296
32433
|
}
|
|
32297
|
-
let filePath =
|
|
32434
|
+
let filePath = path22.join(publicDir, pathname === "/" ? "index.html" : pathname);
|
|
32298
32435
|
if (!filePath.startsWith(publicDir)) {
|
|
32299
32436
|
notFound(res);
|
|
32300
32437
|
return;
|
|
32301
32438
|
}
|
|
32302
|
-
if (
|
|
32303
|
-
const ext =
|
|
32439
|
+
if (fs18.existsSync(filePath) && fs18.statSync(filePath).isFile()) {
|
|
32440
|
+
const ext = path22.extname(filePath);
|
|
32304
32441
|
const contentType = MIME[ext] ?? "application/octet-stream";
|
|
32305
32442
|
res.writeHead(200, { "Content-Type": contentType });
|
|
32306
|
-
|
|
32443
|
+
fs18.createReadStream(filePath).pipe(res);
|
|
32307
32444
|
return;
|
|
32308
32445
|
}
|
|
32309
|
-
filePath =
|
|
32310
|
-
if (
|
|
32446
|
+
filePath = path22.join(publicDir, "index.html");
|
|
32447
|
+
if (fs18.existsSync(filePath)) {
|
|
32311
32448
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
32312
|
-
|
|
32449
|
+
fs18.createReadStream(filePath).pipe(res);
|
|
32313
32450
|
return;
|
|
32314
32451
|
}
|
|
32315
32452
|
notFound(res);
|
|
@@ -32319,17 +32456,17 @@ function createDashboardServer(opts) {
|
|
|
32319
32456
|
}
|
|
32320
32457
|
|
|
32321
32458
|
// ../core/dist/dashboard/state.js
|
|
32322
|
-
import * as
|
|
32323
|
-
import * as
|
|
32324
|
-
import * as
|
|
32325
|
-
var STATE_PATH =
|
|
32459
|
+
import * as fs19 from "node:fs";
|
|
32460
|
+
import * as os12 from "node:os";
|
|
32461
|
+
import * as path23 from "node:path";
|
|
32462
|
+
var STATE_PATH = path23.join(os12.homedir(), ".olam", "dashboard.json");
|
|
32326
32463
|
function saveDashboardState(state) {
|
|
32327
|
-
|
|
32328
|
-
|
|
32464
|
+
fs19.mkdirSync(path23.dirname(STATE_PATH), { recursive: true });
|
|
32465
|
+
fs19.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
|
|
32329
32466
|
}
|
|
32330
32467
|
function loadDashboardState() {
|
|
32331
32468
|
try {
|
|
32332
|
-
const raw =
|
|
32469
|
+
const raw = fs19.readFileSync(STATE_PATH, "utf-8");
|
|
32333
32470
|
return JSON.parse(raw);
|
|
32334
32471
|
} catch {
|
|
32335
32472
|
return null;
|
|
@@ -32337,7 +32474,7 @@ function loadDashboardState() {
|
|
|
32337
32474
|
}
|
|
32338
32475
|
function clearDashboardState() {
|
|
32339
32476
|
try {
|
|
32340
|
-
|
|
32477
|
+
fs19.unlinkSync(STATE_PATH);
|
|
32341
32478
|
} catch {
|
|
32342
32479
|
}
|
|
32343
32480
|
}
|
|
@@ -32647,9 +32784,9 @@ function findProjectRoot2(startDir) {
|
|
|
32647
32784
|
dir = parent;
|
|
32648
32785
|
}
|
|
32649
32786
|
}
|
|
32650
|
-
function parseEnvFile(
|
|
32787
|
+
function parseEnvFile(path24) {
|
|
32651
32788
|
const out = {};
|
|
32652
|
-
const raw = readFileSync15(
|
|
32789
|
+
const raw = readFileSync15(path24, "utf8");
|
|
32653
32790
|
for (const line of raw.split(/\r?\n/)) {
|
|
32654
32791
|
const trimmed = line.trim();
|
|
32655
32792
|
if (!trimmed || trimmed.startsWith("#")) continue;
|