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