@pleri/olam-cli 0.1.158 → 0.1.160
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/agent-stream/agent-sdk-to-chunks.js +3 -0
- package/dist/agent-stream/driver-runner.js +9 -4
- package/dist/agent-stream/host-driver-launch.js +48 -0
- package/dist/commands/doctor.d.ts +21 -10
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +95 -39
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/flywheel/check-persona-skeleton.d.ts +30 -2
- package/dist/commands/flywheel/check-persona-skeleton.d.ts.map +1 -1
- package/dist/commands/flywheel/check-persona-skeleton.js +143 -6
- package/dist/commands/flywheel/check-persona-skeleton.js.map +1 -1
- package/dist/commands/flywheel/diversity-check.d.ts +12 -2
- package/dist/commands/flywheel/diversity-check.d.ts.map +1 -1
- package/dist/commands/flywheel/diversity-check.js +56 -6
- package/dist/commands/flywheel/diversity-check.js.map +1 -1
- package/dist/commands/flywheel/index.d.ts.map +1 -1
- package/dist/commands/flywheel/index.js +2 -0
- package/dist/commands/flywheel/index.js.map +1 -1
- package/dist/commands/flywheel/install-shims.d.ts +36 -3
- package/dist/commands/flywheel/install-shims.d.ts.map +1 -1
- package/dist/commands/flywheel/install-shims.js +118 -7
- package/dist/commands/flywheel/install-shims.js.map +1 -1
- package/dist/commands/flywheel/k10-measure.d.ts +12 -2
- package/dist/commands/flywheel/k10-measure.d.ts.map +1 -1
- package/dist/commands/flywheel/k10-measure.js +55 -6
- package/dist/commands/flywheel/k10-measure.js.map +1 -1
- package/dist/commands/flywheel/migrate-overlays.d.ts +115 -0
- package/dist/commands/flywheel/migrate-overlays.d.ts.map +1 -0
- package/dist/commands/flywheel/migrate-overlays.js +766 -0
- package/dist/commands/flywheel/migrate-overlays.js.map +1 -0
- package/dist/commands/flywheel/sanitize-persona-output.d.ts +33 -2
- package/dist/commands/flywheel/sanitize-persona-output.d.ts.map +1 -1
- package/dist/commands/flywheel/sanitize-persona-output.js +94 -6
- package/dist/commands/flywheel/sanitize-persona-output.js.map +1 -1
- package/dist/commands/memory/index.d.ts.map +1 -1
- package/dist/commands/memory/index.js +2 -0
- package/dist/commands/memory/index.js.map +1 -1
- package/dist/commands/memory/install-hooks.d.ts +22 -0
- package/dist/commands/memory/install-hooks.d.ts.map +1 -0
- package/dist/commands/memory/install-hooks.js +156 -0
- package/dist/commands/memory/install-hooks.js.map +1 -0
- package/dist/commands/skills-doctor.js +2 -2
- package/dist/commands/skills-doctor.js.map +1 -1
- package/dist/commands/skills-source.d.ts.map +1 -1
- package/dist/commands/skills-source.js +10 -0
- package/dist/commands/skills-source.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +169 -1
- package/dist/commands/skills.js.map +1 -1
- package/dist/image-digests.json +7 -7
- package/dist/index.js +3592 -905
- package/dist/index.js.map +1 -1
- package/dist/lib/flywheel-probes.d.ts +58 -0
- package/dist/lib/flywheel-probes.d.ts.map +1 -0
- package/dist/lib/flywheel-probes.js +163 -0
- package/dist/lib/flywheel-probes.js.map +1 -0
- package/dist/lib/host-side-proxy.d.ts +67 -0
- package/dist/lib/host-side-proxy.d.ts.map +1 -0
- package/dist/lib/host-side-proxy.js +177 -0
- package/dist/lib/host-side-proxy.js.map +1 -0
- package/dist/lib/shim-generator.d.ts +51 -0
- package/dist/lib/shim-generator.d.ts.map +1 -0
- package/dist/lib/shim-generator.js +88 -0
- package/dist/lib/shim-generator.js.map +1 -0
- package/dist/lib/skills-apply-overlays.d.ts +35 -0
- package/dist/lib/skills-apply-overlays.d.ts.map +1 -0
- package/dist/lib/skills-apply-overlays.js +243 -0
- package/dist/lib/skills-apply-overlays.js.map +1 -0
- package/dist/lib/upgrade-kubernetes.d.ts +13 -12
- package/dist/lib/upgrade-kubernetes.d.ts.map +1 -1
- package/dist/lib/upgrade-kubernetes.js +87 -134
- package/dist/lib/upgrade-kubernetes.js.map +1 -1
- package/dist/mcp-server.js +1106 -453
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/host-side/docker-socket-proxy.compose.yaml +58 -0
- package/host-cp/k8s/manifests/50-deployment.yaml +47 -70
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/docker-socket-proxy/60-service.yaml +37 -0
- package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/memory-service/30-configmap.yaml +11 -0
- package/host-cp/k8s/manifests/memory-service/35-configmap-iii-config.yaml +76 -0
- package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +11 -1
- package/host-cp/src/crystallize-planning.mjs +261 -0
- package/host-cp/src/plan-chat-service.mjs +84 -2
- package/host-cp/src/planning-sessions.mjs +270 -0
- package/host-cp/src/server.mjs +9 -0
- package/host-cp/src/tasks-route.mjs +191 -0
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -445,8 +445,8 @@ var init_parseUtil = __esm({
|
|
|
445
445
|
init_errors();
|
|
446
446
|
init_en();
|
|
447
447
|
makeIssue = (params) => {
|
|
448
|
-
const { data, path:
|
|
449
|
-
const fullPath = [...
|
|
448
|
+
const { data, path: path48, errorMaps, issueData } = params;
|
|
449
|
+
const fullPath = [...path48, ...issueData.path || []];
|
|
450
450
|
const fullIssue = {
|
|
451
451
|
...issueData,
|
|
452
452
|
path: fullPath
|
|
@@ -754,11 +754,11 @@ var init_types = __esm({
|
|
|
754
754
|
init_parseUtil();
|
|
755
755
|
init_util();
|
|
756
756
|
ParseInputLazyPath = class {
|
|
757
|
-
constructor(parent, value,
|
|
757
|
+
constructor(parent, value, path48, key) {
|
|
758
758
|
this._cachedPath = [];
|
|
759
759
|
this.parent = parent;
|
|
760
760
|
this.data = value;
|
|
761
|
-
this._path =
|
|
761
|
+
this._path = path48;
|
|
762
762
|
this._key = key;
|
|
763
763
|
}
|
|
764
764
|
get path() {
|
|
@@ -7090,7 +7090,7 @@ var require_compile = __commonJS({
|
|
|
7090
7090
|
const schOrFunc = root.refs[ref];
|
|
7091
7091
|
if (schOrFunc)
|
|
7092
7092
|
return schOrFunc;
|
|
7093
|
-
let _sch =
|
|
7093
|
+
let _sch = resolve14.call(this, root, ref);
|
|
7094
7094
|
if (_sch === void 0) {
|
|
7095
7095
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
7096
7096
|
const { schemaId } = this.opts;
|
|
@@ -7117,7 +7117,7 @@ var require_compile = __commonJS({
|
|
|
7117
7117
|
function sameSchemaEnv(s1, s2) {
|
|
7118
7118
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
7119
7119
|
}
|
|
7120
|
-
function
|
|
7120
|
+
function resolve14(root, ref) {
|
|
7121
7121
|
let sch;
|
|
7122
7122
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
7123
7123
|
ref = sch;
|
|
@@ -7332,8 +7332,8 @@ var require_utils = __commonJS({
|
|
|
7332
7332
|
}
|
|
7333
7333
|
return ind;
|
|
7334
7334
|
}
|
|
7335
|
-
function removeDotSegments(
|
|
7336
|
-
let input =
|
|
7335
|
+
function removeDotSegments(path48) {
|
|
7336
|
+
let input = path48;
|
|
7337
7337
|
const output = [];
|
|
7338
7338
|
let nextSlash = -1;
|
|
7339
7339
|
let len = 0;
|
|
@@ -7532,8 +7532,8 @@ var require_schemes = __commonJS({
|
|
|
7532
7532
|
wsComponent.secure = void 0;
|
|
7533
7533
|
}
|
|
7534
7534
|
if (wsComponent.resourceName) {
|
|
7535
|
-
const [
|
|
7536
|
-
wsComponent.path =
|
|
7535
|
+
const [path48, query] = wsComponent.resourceName.split("?");
|
|
7536
|
+
wsComponent.path = path48 && path48 !== "/" ? path48 : void 0;
|
|
7537
7537
|
wsComponent.query = query;
|
|
7538
7538
|
wsComponent.resourceName = void 0;
|
|
7539
7539
|
}
|
|
@@ -7692,55 +7692,55 @@ var require_fast_uri = __commonJS({
|
|
|
7692
7692
|
}
|
|
7693
7693
|
return uri;
|
|
7694
7694
|
}
|
|
7695
|
-
function
|
|
7695
|
+
function resolve14(baseURI, relativeURI, options) {
|
|
7696
7696
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
7697
7697
|
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
7698
7698
|
schemelessOptions.skipEscape = true;
|
|
7699
7699
|
return serialize(resolved, schemelessOptions);
|
|
7700
7700
|
}
|
|
7701
|
-
function resolveComponent(base,
|
|
7701
|
+
function resolveComponent(base, relative5, options, skipNormalization) {
|
|
7702
7702
|
const target = {};
|
|
7703
7703
|
if (!skipNormalization) {
|
|
7704
7704
|
base = parse4(serialize(base, options), options);
|
|
7705
|
-
|
|
7705
|
+
relative5 = parse4(serialize(relative5, options), options);
|
|
7706
7706
|
}
|
|
7707
7707
|
options = options || {};
|
|
7708
|
-
if (!options.tolerant &&
|
|
7709
|
-
target.scheme =
|
|
7710
|
-
target.userinfo =
|
|
7711
|
-
target.host =
|
|
7712
|
-
target.port =
|
|
7713
|
-
target.path = removeDotSegments(
|
|
7714
|
-
target.query =
|
|
7708
|
+
if (!options.tolerant && relative5.scheme) {
|
|
7709
|
+
target.scheme = relative5.scheme;
|
|
7710
|
+
target.userinfo = relative5.userinfo;
|
|
7711
|
+
target.host = relative5.host;
|
|
7712
|
+
target.port = relative5.port;
|
|
7713
|
+
target.path = removeDotSegments(relative5.path || "");
|
|
7714
|
+
target.query = relative5.query;
|
|
7715
7715
|
} else {
|
|
7716
|
-
if (
|
|
7717
|
-
target.userinfo =
|
|
7718
|
-
target.host =
|
|
7719
|
-
target.port =
|
|
7720
|
-
target.path = removeDotSegments(
|
|
7721
|
-
target.query =
|
|
7716
|
+
if (relative5.userinfo !== void 0 || relative5.host !== void 0 || relative5.port !== void 0) {
|
|
7717
|
+
target.userinfo = relative5.userinfo;
|
|
7718
|
+
target.host = relative5.host;
|
|
7719
|
+
target.port = relative5.port;
|
|
7720
|
+
target.path = removeDotSegments(relative5.path || "");
|
|
7721
|
+
target.query = relative5.query;
|
|
7722
7722
|
} else {
|
|
7723
|
-
if (!
|
|
7723
|
+
if (!relative5.path) {
|
|
7724
7724
|
target.path = base.path;
|
|
7725
|
-
if (
|
|
7726
|
-
target.query =
|
|
7725
|
+
if (relative5.query !== void 0) {
|
|
7726
|
+
target.query = relative5.query;
|
|
7727
7727
|
} else {
|
|
7728
7728
|
target.query = base.query;
|
|
7729
7729
|
}
|
|
7730
7730
|
} else {
|
|
7731
|
-
if (
|
|
7732
|
-
target.path = removeDotSegments(
|
|
7731
|
+
if (relative5.path[0] === "/") {
|
|
7732
|
+
target.path = removeDotSegments(relative5.path);
|
|
7733
7733
|
} else {
|
|
7734
7734
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
7735
|
-
target.path = "/" +
|
|
7735
|
+
target.path = "/" + relative5.path;
|
|
7736
7736
|
} else if (!base.path) {
|
|
7737
|
-
target.path =
|
|
7737
|
+
target.path = relative5.path;
|
|
7738
7738
|
} else {
|
|
7739
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
7739
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative5.path;
|
|
7740
7740
|
}
|
|
7741
7741
|
target.path = removeDotSegments(target.path);
|
|
7742
7742
|
}
|
|
7743
|
-
target.query =
|
|
7743
|
+
target.query = relative5.query;
|
|
7744
7744
|
}
|
|
7745
7745
|
target.userinfo = base.userinfo;
|
|
7746
7746
|
target.host = base.host;
|
|
@@ -7748,7 +7748,7 @@ var require_fast_uri = __commonJS({
|
|
|
7748
7748
|
}
|
|
7749
7749
|
target.scheme = base.scheme;
|
|
7750
7750
|
}
|
|
7751
|
-
target.fragment =
|
|
7751
|
+
target.fragment = relative5.fragment;
|
|
7752
7752
|
return target;
|
|
7753
7753
|
}
|
|
7754
7754
|
function equal(uriA, uriB, options) {
|
|
@@ -7919,7 +7919,7 @@ var require_fast_uri = __commonJS({
|
|
|
7919
7919
|
var fastUri = {
|
|
7920
7920
|
SCHEMES,
|
|
7921
7921
|
normalize,
|
|
7922
|
-
resolve:
|
|
7922
|
+
resolve: resolve14,
|
|
7923
7923
|
resolveComponent,
|
|
7924
7924
|
equal,
|
|
7925
7925
|
serialize,
|
|
@@ -10895,12 +10895,12 @@ var require_dist = __commonJS({
|
|
|
10895
10895
|
throw new Error(`Unknown format "${name}"`);
|
|
10896
10896
|
return f;
|
|
10897
10897
|
};
|
|
10898
|
-
function addFormats(ajv, list,
|
|
10898
|
+
function addFormats(ajv, list, fs48, exportName) {
|
|
10899
10899
|
var _a3;
|
|
10900
10900
|
var _b;
|
|
10901
10901
|
(_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
10902
10902
|
for (const f of list)
|
|
10903
|
-
ajv.addFormat(f,
|
|
10903
|
+
ajv.addFormat(f, fs48[f]);
|
|
10904
10904
|
}
|
|
10905
10905
|
module.exports = exports = formatsPlugin;
|
|
10906
10906
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -11008,7 +11008,7 @@ import YAML from "yaml";
|
|
|
11008
11008
|
function bootstrapStepCmd(entry) {
|
|
11009
11009
|
return typeof entry === "string" ? entry : entry.cmd;
|
|
11010
11010
|
}
|
|
11011
|
-
function refineForbiddenKeys(value,
|
|
11011
|
+
function refineForbiddenKeys(value, path48, ctx, rejectSource) {
|
|
11012
11012
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
11013
11013
|
return;
|
|
11014
11014
|
}
|
|
@@ -11016,12 +11016,12 @@ function refineForbiddenKeys(value, path46, ctx, rejectSource) {
|
|
|
11016
11016
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
11017
11017
|
ctx.addIssue({
|
|
11018
11018
|
code: external_exports.ZodIssueCode.custom,
|
|
11019
|
-
path: [...
|
|
11019
|
+
path: [...path48, key],
|
|
11020
11020
|
message: `forbidden key "${key}" (prototype-pollution surface)`
|
|
11021
11021
|
});
|
|
11022
11022
|
continue;
|
|
11023
11023
|
}
|
|
11024
|
-
if (rejectSource &&
|
|
11024
|
+
if (rejectSource && path48.length === 0 && key === "source") {
|
|
11025
11025
|
ctx.addIssue({
|
|
11026
11026
|
code: external_exports.ZodIssueCode.custom,
|
|
11027
11027
|
path: ["source"],
|
|
@@ -11029,21 +11029,21 @@ function refineForbiddenKeys(value, path46, ctx, rejectSource) {
|
|
|
11029
11029
|
});
|
|
11030
11030
|
continue;
|
|
11031
11031
|
}
|
|
11032
|
-
refineForbiddenKeys(value[key], [...
|
|
11032
|
+
refineForbiddenKeys(value[key], [...path48, key], ctx, false);
|
|
11033
11033
|
}
|
|
11034
11034
|
}
|
|
11035
|
-
function rejectForbiddenKeys(value,
|
|
11035
|
+
function rejectForbiddenKeys(value, path48, rejectSource) {
|
|
11036
11036
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
11037
11037
|
return;
|
|
11038
11038
|
}
|
|
11039
11039
|
for (const key of Object.keys(value)) {
|
|
11040
11040
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
11041
|
-
throw new Error(`[manifest] ${
|
|
11041
|
+
throw new Error(`[manifest] ${path48}: forbidden key "${key}" (prototype-pollution surface)`);
|
|
11042
11042
|
}
|
|
11043
11043
|
if (rejectSource && key === "source") {
|
|
11044
|
-
throw new Error(`[manifest] ${
|
|
11044
|
+
throw new Error(`[manifest] ${path48}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
|
|
11045
11045
|
}
|
|
11046
|
-
rejectForbiddenKeys(value[key], `${
|
|
11046
|
+
rejectForbiddenKeys(value[key], `${path48}.${key}`, false);
|
|
11047
11047
|
}
|
|
11048
11048
|
}
|
|
11049
11049
|
function unknownTopLevelKeys(parsed) {
|
|
@@ -12462,6 +12462,9 @@ function listSkillSources() {
|
|
|
12462
12462
|
function getSkillSource(id) {
|
|
12463
12463
|
return readGlobalConfig().skillSources.find((s) => s.id === id);
|
|
12464
12464
|
}
|
|
12465
|
+
function getSkillSourceByName(name) {
|
|
12466
|
+
return readGlobalConfig().skillSources.find((s) => s.name === name) ?? null;
|
|
12467
|
+
}
|
|
12465
12468
|
function addSkillSource(entry) {
|
|
12466
12469
|
const config2 = readGlobalConfig();
|
|
12467
12470
|
const id = deriveSkillSourceId(entry.gitUrl);
|
|
@@ -13184,6 +13187,26 @@ function resolveJsonDir(opts) {
|
|
|
13184
13187
|
}
|
|
13185
13188
|
return out;
|
|
13186
13189
|
}
|
|
13190
|
+
function resolveOverlaysDir(opts) {
|
|
13191
|
+
const { sourceId, baseDir, targetKind } = opts;
|
|
13192
|
+
const out = [];
|
|
13193
|
+
for (const name of listDirSafe(baseDir)) {
|
|
13194
|
+
if (!name.endsWith(".md"))
|
|
13195
|
+
continue;
|
|
13196
|
+
const full = path20.join(baseDir, name);
|
|
13197
|
+
if (!fs19.statSync(full).isFile())
|
|
13198
|
+
continue;
|
|
13199
|
+
const deployBasename = name.replace(/\.md$/, "");
|
|
13200
|
+
out.push({
|
|
13201
|
+
kind: "overlay",
|
|
13202
|
+
sourceId,
|
|
13203
|
+
sourcePath: full,
|
|
13204
|
+
deployBasename,
|
|
13205
|
+
targetKind
|
|
13206
|
+
});
|
|
13207
|
+
}
|
|
13208
|
+
return out;
|
|
13209
|
+
}
|
|
13187
13210
|
function resolveSourceArtifacts(opts) {
|
|
13188
13211
|
const { sourceId, clonePath, atlasUser } = opts;
|
|
13189
13212
|
const subscription = resolveSubscriptions({ clonePath, atlasUser });
|
|
@@ -13208,6 +13231,16 @@ function resolveSourceArtifacts(opts) {
|
|
|
13208
13231
|
artifacts.push(...resolveRulesDir({ sourceId, baseDir: path20.join(memberRoot, "rules") }));
|
|
13209
13232
|
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path20.join(memberRoot, "hooks"), kind: "hook" }));
|
|
13210
13233
|
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path20.join(memberRoot, "permissions"), kind: "permission" }));
|
|
13234
|
+
artifacts.push(...resolveOverlaysDir({
|
|
13235
|
+
sourceId,
|
|
13236
|
+
baseDir: path20.join(memberRoot, "skills.overrides"),
|
|
13237
|
+
targetKind: "skill"
|
|
13238
|
+
}));
|
|
13239
|
+
artifacts.push(...resolveOverlaysDir({
|
|
13240
|
+
sourceId,
|
|
13241
|
+
baseDir: path20.join(memberRoot, "agents.overrides"),
|
|
13242
|
+
targetKind: "agent"
|
|
13243
|
+
}));
|
|
13211
13244
|
}
|
|
13212
13245
|
}
|
|
13213
13246
|
return { subscription, artifacts };
|
|
@@ -13218,6 +13251,57 @@ var init_artifact_resolver = __esm({
|
|
|
13218
13251
|
}
|
|
13219
13252
|
});
|
|
13220
13253
|
|
|
13254
|
+
// ../core/dist/lib/shim-targets.js
|
|
13255
|
+
function lookupShimTarget(basename6) {
|
|
13256
|
+
return SHIM_TARGETS.find((t) => t.basename === basename6);
|
|
13257
|
+
}
|
|
13258
|
+
function compareSemver(installed, required2) {
|
|
13259
|
+
const norm = (s) => {
|
|
13260
|
+
const clean = s.replace(/^v/, "").split(/[-+]/)[0] ?? "0";
|
|
13261
|
+
const parts = clean.split(".").map((p) => Number.parseInt(p, 10) || 0);
|
|
13262
|
+
while (parts.length < 3)
|
|
13263
|
+
parts.push(0);
|
|
13264
|
+
return parts.slice(0, 3);
|
|
13265
|
+
};
|
|
13266
|
+
const i = norm(installed);
|
|
13267
|
+
const r = norm(required2);
|
|
13268
|
+
for (let idx = 0; idx < 3; idx++) {
|
|
13269
|
+
const diff = (i[idx] ?? 0) - (r[idx] ?? 0);
|
|
13270
|
+
if (diff !== 0)
|
|
13271
|
+
return diff;
|
|
13272
|
+
}
|
|
13273
|
+
return 0;
|
|
13274
|
+
}
|
|
13275
|
+
function checkShimRemoval(basename6, installedOlamVersion) {
|
|
13276
|
+
const target = lookupShimTarget(basename6);
|
|
13277
|
+
if (target === void 0)
|
|
13278
|
+
return null;
|
|
13279
|
+
return {
|
|
13280
|
+
basename: target.basename,
|
|
13281
|
+
replacedBy: target.replacedBy,
|
|
13282
|
+
installedOlamVersion,
|
|
13283
|
+
minOlamVersion: target.minOlamVersion,
|
|
13284
|
+
safeToRemove: compareSemver(installedOlamVersion, target.minOlamVersion) >= 0
|
|
13285
|
+
};
|
|
13286
|
+
}
|
|
13287
|
+
var SHIM_TARGETS;
|
|
13288
|
+
var init_shim_targets = __esm({
|
|
13289
|
+
"../core/dist/lib/shim-targets.js"() {
|
|
13290
|
+
"use strict";
|
|
13291
|
+
SHIM_TARGETS = Object.freeze([
|
|
13292
|
+
{ basename: "emit-breadcrumb.sh", minOlamVersion: "0.2.0", replacedBy: "olam flywheel emit-breadcrumb" },
|
|
13293
|
+
{ basename: "emit-breadcrumb.py", minOlamVersion: "0.2.0", replacedBy: "olam flywheel emit-breadcrumb" },
|
|
13294
|
+
{ basename: "sanitize-persona-output.py", minOlamVersion: "0.2.0", replacedBy: "olam flywheel sanitize-persona-output" },
|
|
13295
|
+
{ basename: "check-persona-skeleton.py", minOlamVersion: "0.2.0", replacedBy: "olam flywheel check-persona-skeleton" },
|
|
13296
|
+
{ basename: "k5-rubric-helper.py", minOlamVersion: "0.2.0", replacedBy: "olam flywheel k5-validate" },
|
|
13297
|
+
{ basename: "k10_budget.py", minOlamVersion: "0.2.0", replacedBy: "olam flywheel k10-measure" },
|
|
13298
|
+
{ basename: "diversity_check.py", minOlamVersion: "0.2.0", replacedBy: "olam flywheel diversity-check" },
|
|
13299
|
+
{ basename: "apply-overlays.py", minOlamVersion: "0.2.0", replacedBy: "olam skills apply-overlays" },
|
|
13300
|
+
{ basename: "sync-with-overlays.sh", minOlamVersion: "0.2.0", replacedBy: "olam skills sync --with-overlays" }
|
|
13301
|
+
]);
|
|
13302
|
+
}
|
|
13303
|
+
});
|
|
13304
|
+
|
|
13221
13305
|
// ../core/dist/skill-sync/symlink-deployer.js
|
|
13222
13306
|
import * as fs20 from "node:fs";
|
|
13223
13307
|
import * as os13 from "node:os";
|
|
@@ -13243,6 +13327,9 @@ function bucketFor(kind) {
|
|
|
13243
13327
|
case "hook":
|
|
13244
13328
|
case "permission":
|
|
13245
13329
|
return void 0;
|
|
13330
|
+
// handled by settings-merger
|
|
13331
|
+
case "overlay":
|
|
13332
|
+
return void 0;
|
|
13246
13333
|
}
|
|
13247
13334
|
}
|
|
13248
13335
|
function detectCollisions(artifacts) {
|
|
@@ -13280,22 +13367,48 @@ function detectCollisions(artifacts) {
|
|
|
13280
13367
|
}
|
|
13281
13368
|
return { winners, collisions };
|
|
13282
13369
|
}
|
|
13283
|
-
function cleanManagedSymlinks(claude) {
|
|
13370
|
+
function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences) {
|
|
13371
|
+
const shadowBackups = [];
|
|
13284
13372
|
for (const bucket of BUCKETS) {
|
|
13285
13373
|
const dir = path21.join(claude, bucket);
|
|
13286
13374
|
if (!fs20.existsSync(dir))
|
|
13287
13375
|
continue;
|
|
13288
13376
|
for (const name of fs20.readdirSync(dir)) {
|
|
13377
|
+
if (name === ".olam-merged")
|
|
13378
|
+
continue;
|
|
13289
13379
|
const p = path21.join(dir, name);
|
|
13290
13380
|
try {
|
|
13291
13381
|
const stat = fs20.lstatSync(p);
|
|
13292
13382
|
if (stat.isSymbolicLink()) {
|
|
13383
|
+
if (bucket === "scripts" && overlayReferences !== void 0) {
|
|
13384
|
+
const refs = overlayReferences.get(name);
|
|
13385
|
+
if (refs !== void 0 && refs.length > 0 && checkShimRemoval(name, "0.0.0") !== null) {
|
|
13386
|
+
const firstRef = refs[0];
|
|
13387
|
+
const extraCount = refs.length - 1;
|
|
13388
|
+
const refDisplay = extraCount > 0 ? `${firstRef} (+${extraCount} more)` : firstRef;
|
|
13389
|
+
const nameNoExt = name.replace(/\.[^.]+$/, "");
|
|
13390
|
+
process.stderr.write(`[shim-preserved] ~/.claude/scripts/${name} \u2014 referenced by overlay ${refDisplay}; run \`olam flywheel migrate-overlays\` to update the overlay path, then \`olam flywheel ${nameNoExt}\` to install the replacement.
|
|
13391
|
+
`);
|
|
13392
|
+
continue;
|
|
13393
|
+
}
|
|
13394
|
+
}
|
|
13395
|
+
if (bucket === "scripts" && installedOlamVersion !== void 0) {
|
|
13396
|
+
const check = checkShimRemoval(name, installedOlamVersion);
|
|
13397
|
+
if (check !== null && !check.safeToRemove) {
|
|
13398
|
+
process.stderr.write(`[shim-removal-warn] ~/.claude/scripts/${name} is being removed but operator olam ${check.installedOlamVersion} < flywheel min ${check.minOlamVersion}. After atlas-toolbox stops shipping this script, chain skills hardcoding the path will break. Upgrade to olam \u2265${check.minOlamVersion} + run \`olam flywheel install-shims\` to install the replacement (${check.replacedBy}).
|
|
13399
|
+
`);
|
|
13400
|
+
}
|
|
13401
|
+
}
|
|
13293
13402
|
fs20.unlinkSync(p);
|
|
13403
|
+
} else if (bucket === "agents" && stat.isFile() && !name.includes(".shadow-backup-")) {
|
|
13404
|
+
const backup = shadowBackup(p);
|
|
13405
|
+
shadowBackups.push(backup);
|
|
13294
13406
|
}
|
|
13295
13407
|
} catch {
|
|
13296
13408
|
}
|
|
13297
13409
|
}
|
|
13298
13410
|
}
|
|
13411
|
+
return shadowBackups;
|
|
13299
13412
|
}
|
|
13300
13413
|
function shadowBackup(link) {
|
|
13301
13414
|
const epoch = Math.floor(Date.now() / 1e3);
|
|
@@ -13324,19 +13437,26 @@ function linkIfNeeded(target, link) {
|
|
|
13324
13437
|
fs20.symlinkSync(target, link);
|
|
13325
13438
|
return { created: true, shadowBackup: backup };
|
|
13326
13439
|
}
|
|
13327
|
-
function deployArtifacts(artifacts) {
|
|
13440
|
+
function deployArtifacts(artifacts, opts) {
|
|
13328
13441
|
const claude = claudeDir();
|
|
13329
13442
|
for (const bucket of BUCKETS) {
|
|
13330
13443
|
fs20.mkdirSync(path21.join(claude, bucket), { recursive: true });
|
|
13331
13444
|
}
|
|
13332
|
-
cleanManagedSymlinks(claude);
|
|
13445
|
+
const sweepShadowBackups = cleanManagedSymlinks(claude, opts?.installedOlamVersion, opts?.overlayReferences);
|
|
13333
13446
|
const { winners, collisions } = detectCollisions(artifacts);
|
|
13334
|
-
const result = { linked: 0, shadowBackups: [], collisions };
|
|
13447
|
+
const result = { linked: 0, shadowBackups: [...sweepShadowBackups], collisions };
|
|
13335
13448
|
for (const artifact of winners) {
|
|
13336
13449
|
const bucket = bucketFor(artifact.kind);
|
|
13337
13450
|
if (!bucket)
|
|
13338
13451
|
continue;
|
|
13339
13452
|
const linkPath = path21.join(claude, bucket, artifact.deployBasename);
|
|
13453
|
+
if (artifact.kind === "agent" && artifact.resolvedContent !== void 0) {
|
|
13454
|
+
const tmpPath = `${linkPath}.tmp-${process.pid}-${Date.now()}`;
|
|
13455
|
+
fs20.writeFileSync(tmpPath, artifact.resolvedContent);
|
|
13456
|
+
fs20.renameSync(tmpPath, linkPath);
|
|
13457
|
+
result.linked += 1;
|
|
13458
|
+
continue;
|
|
13459
|
+
}
|
|
13340
13460
|
const { created, shadowBackup: backup } = linkIfNeeded(artifact.sourcePath, linkPath);
|
|
13341
13461
|
if (created)
|
|
13342
13462
|
result.linked += 1;
|
|
@@ -13349,6 +13469,7 @@ var BUCKETS;
|
|
|
13349
13469
|
var init_symlink_deployer = __esm({
|
|
13350
13470
|
"../core/dist/skill-sync/symlink-deployer.js"() {
|
|
13351
13471
|
"use strict";
|
|
13472
|
+
init_shim_targets();
|
|
13352
13473
|
BUCKETS = ["commands", "agents", "skills", "scripts", "rules"];
|
|
13353
13474
|
}
|
|
13354
13475
|
});
|
|
@@ -13817,7 +13938,7 @@ function defaultIsPidAlive(pid) {
|
|
|
13817
13938
|
}
|
|
13818
13939
|
}
|
|
13819
13940
|
function sleep3(ms) {
|
|
13820
|
-
return new Promise((
|
|
13941
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
13821
13942
|
}
|
|
13822
13943
|
function readLockMeta(lockPath) {
|
|
13823
13944
|
try {
|
|
@@ -13931,13 +14052,179 @@ var init_file_lock = __esm({
|
|
|
13931
14052
|
}
|
|
13932
14053
|
});
|
|
13933
14054
|
|
|
13934
|
-
// ../core/dist/
|
|
14055
|
+
// ../core/dist/lib/min-version-filter.js
|
|
14056
|
+
import { existsSync as existsSync27, readFileSync as readFileSync23 } from "node:fs";
|
|
14057
|
+
function readOlamMinVersion(filepath) {
|
|
14058
|
+
if (!existsSync27(filepath))
|
|
14059
|
+
return void 0;
|
|
14060
|
+
let text;
|
|
14061
|
+
try {
|
|
14062
|
+
text = readFileSync23(filepath, "utf8");
|
|
14063
|
+
} catch {
|
|
14064
|
+
return void 0;
|
|
14065
|
+
}
|
|
14066
|
+
const match = FM_RE.exec(text);
|
|
14067
|
+
if (match === null)
|
|
14068
|
+
return void 0;
|
|
14069
|
+
const fmText = match[1] ?? "";
|
|
14070
|
+
for (const rawLine of fmText.split("\n")) {
|
|
14071
|
+
const line = rawLine.trim();
|
|
14072
|
+
if (line === "" || line.startsWith("#"))
|
|
14073
|
+
continue;
|
|
14074
|
+
const colonIdx = line.indexOf(":");
|
|
14075
|
+
if (colonIdx === -1)
|
|
14076
|
+
continue;
|
|
14077
|
+
const key = line.slice(0, colonIdx).trim();
|
|
14078
|
+
if (key !== "olam-min-version")
|
|
14079
|
+
continue;
|
|
14080
|
+
const value = line.slice(colonIdx + 1).trim().replace(/^['"]|['"]$/g, "");
|
|
14081
|
+
if (value === "" || !/^v?\d+(\.\d+)*/.test(value))
|
|
14082
|
+
return void 0;
|
|
14083
|
+
return value;
|
|
14084
|
+
}
|
|
14085
|
+
return void 0;
|
|
14086
|
+
}
|
|
14087
|
+
function filterArtifactsByMinVersion(artifacts, installedOlamVersion) {
|
|
14088
|
+
const kept = [];
|
|
14089
|
+
const dropped = [];
|
|
14090
|
+
const warnings = [];
|
|
14091
|
+
for (const artifact of artifacts) {
|
|
14092
|
+
if (!artifact.sourcePath.endsWith(".md")) {
|
|
14093
|
+
kept.push(artifact);
|
|
14094
|
+
continue;
|
|
14095
|
+
}
|
|
14096
|
+
const required2 = readOlamMinVersion(artifact.sourcePath);
|
|
14097
|
+
if (required2 === void 0) {
|
|
14098
|
+
kept.push(artifact);
|
|
14099
|
+
continue;
|
|
14100
|
+
}
|
|
14101
|
+
if (compareSemver(installedOlamVersion, required2) >= 0) {
|
|
14102
|
+
kept.push(artifact);
|
|
14103
|
+
} else {
|
|
14104
|
+
dropped.push({ artifact, required: required2, installed: installedOlamVersion });
|
|
14105
|
+
warnings.push(`[olam-min-version] dropping ${artifact.deployBasename}: requires olam \u2265${required2} but installed is ${installedOlamVersion}. Upgrade olam to deploy this skill.`);
|
|
14106
|
+
}
|
|
14107
|
+
}
|
|
14108
|
+
return { kept, dropped, warnings };
|
|
14109
|
+
}
|
|
14110
|
+
var FM_RE;
|
|
14111
|
+
var init_min_version_filter = __esm({
|
|
14112
|
+
"../core/dist/lib/min-version-filter.js"() {
|
|
14113
|
+
"use strict";
|
|
14114
|
+
init_shim_targets();
|
|
14115
|
+
FM_RE = /^---\n([\s\S]*?)\n---\n?/;
|
|
14116
|
+
}
|
|
14117
|
+
});
|
|
14118
|
+
|
|
14119
|
+
// ../core/dist/skill-sync/overlay-scan.js
|
|
13935
14120
|
import * as fs26 from "node:fs";
|
|
13936
|
-
import * as os16 from "node:os";
|
|
13937
14121
|
import * as path25 from "node:path";
|
|
14122
|
+
function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
14123
|
+
const result = /* @__PURE__ */ new Map();
|
|
14124
|
+
if (!fs26.existsSync(overlayRoot)) {
|
|
14125
|
+
return result;
|
|
14126
|
+
}
|
|
14127
|
+
if (basenames.length === 0) {
|
|
14128
|
+
return result;
|
|
14129
|
+
}
|
|
14130
|
+
const mdFiles = [];
|
|
14131
|
+
let overlayRootReal;
|
|
14132
|
+
try {
|
|
14133
|
+
overlayRootReal = fs26.realpathSync(overlayRoot);
|
|
14134
|
+
} catch {
|
|
14135
|
+
return result;
|
|
14136
|
+
}
|
|
14137
|
+
for (const subdir of OVERRIDE_SUBDIRS) {
|
|
14138
|
+
const dir = path25.join(overlayRoot, subdir);
|
|
14139
|
+
if (!fs26.existsSync(dir))
|
|
14140
|
+
continue;
|
|
14141
|
+
walkMarkdown(dir, mdFiles, caps.maxFiles);
|
|
14142
|
+
}
|
|
14143
|
+
let totalBytes = 0;
|
|
14144
|
+
for (const filepath of mdFiles) {
|
|
14145
|
+
let realFile;
|
|
14146
|
+
try {
|
|
14147
|
+
realFile = fs26.realpathSync(filepath);
|
|
14148
|
+
} catch (err) {
|
|
14149
|
+
const code = err.code;
|
|
14150
|
+
if (code === "ENOENT" || code === "EACCES")
|
|
14151
|
+
continue;
|
|
14152
|
+
throw err;
|
|
14153
|
+
}
|
|
14154
|
+
const rel = path25.relative(overlayRootReal, realFile);
|
|
14155
|
+
if (rel.startsWith("..") || path25.isAbsolute(rel)) {
|
|
14156
|
+
continue;
|
|
14157
|
+
}
|
|
14158
|
+
let content;
|
|
14159
|
+
try {
|
|
14160
|
+
const stat = fs26.statSync(filepath);
|
|
14161
|
+
totalBytes += stat.size;
|
|
14162
|
+
if (totalBytes > caps.maxTotalBytes) {
|
|
14163
|
+
throw new Error(`[overlay-scan] aborted: overlay tree exceeds ${caps.maxTotalBytes} total bytes. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
|
|
14164
|
+
}
|
|
14165
|
+
content = fs26.readFileSync(filepath, "utf8");
|
|
14166
|
+
} catch (err) {
|
|
14167
|
+
const code = err.code;
|
|
14168
|
+
if (code === "ENOENT" || code === "EACCES") {
|
|
14169
|
+
continue;
|
|
14170
|
+
}
|
|
14171
|
+
throw err;
|
|
14172
|
+
}
|
|
14173
|
+
const relpath = path25.relative(overlayRoot, filepath).split(path25.sep).join("/");
|
|
14174
|
+
for (const basename6 of basenames) {
|
|
14175
|
+
if (content.includes(basename6)) {
|
|
14176
|
+
const list = result.get(basename6) ?? [];
|
|
14177
|
+
list.push(relpath);
|
|
14178
|
+
result.set(basename6, list);
|
|
14179
|
+
}
|
|
14180
|
+
}
|
|
14181
|
+
}
|
|
14182
|
+
return result;
|
|
14183
|
+
}
|
|
14184
|
+
function walkMarkdown(dir, out, cap) {
|
|
14185
|
+
let entries;
|
|
14186
|
+
try {
|
|
14187
|
+
entries = fs26.readdirSync(dir, { withFileTypes: true });
|
|
14188
|
+
} catch (err) {
|
|
14189
|
+
if (err.code === "ENOENT")
|
|
14190
|
+
return;
|
|
14191
|
+
throw err;
|
|
14192
|
+
}
|
|
14193
|
+
for (const entry of entries) {
|
|
14194
|
+
if (out.length >= cap) {
|
|
14195
|
+
throw new Error(`[overlay-scan] aborted: overlay tree contains > ${cap} markdown files. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
|
|
14196
|
+
}
|
|
14197
|
+
const full = path25.join(dir, entry.name);
|
|
14198
|
+
if (entry.isSymbolicLink())
|
|
14199
|
+
continue;
|
|
14200
|
+
if (entry.isDirectory()) {
|
|
14201
|
+
walkMarkdown(full, out, cap);
|
|
14202
|
+
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
14203
|
+
out.push(full);
|
|
14204
|
+
}
|
|
14205
|
+
}
|
|
14206
|
+
}
|
|
14207
|
+
var OVERRIDE_SUBDIRS, MAX_FILES, MAX_TOTAL_BYTES, DEFAULT_CAPS;
|
|
14208
|
+
var init_overlay_scan = __esm({
|
|
14209
|
+
"../core/dist/skill-sync/overlay-scan.js"() {
|
|
14210
|
+
"use strict";
|
|
14211
|
+
OVERRIDE_SUBDIRS = ["skills.overrides", "agents.overrides"];
|
|
14212
|
+
MAX_FILES = 5e3;
|
|
14213
|
+
MAX_TOTAL_BYTES = 10 * 1024 * 1024;
|
|
14214
|
+
DEFAULT_CAPS = {
|
|
14215
|
+
maxFiles: MAX_FILES,
|
|
14216
|
+
maxTotalBytes: MAX_TOTAL_BYTES
|
|
14217
|
+
};
|
|
14218
|
+
}
|
|
14219
|
+
});
|
|
14220
|
+
|
|
14221
|
+
// ../core/dist/skill-sync/settings-json-lock.js
|
|
14222
|
+
import * as fs27 from "node:fs";
|
|
14223
|
+
import * as os16 from "node:os";
|
|
14224
|
+
import * as path26 from "node:path";
|
|
13938
14225
|
function defaultSettingsJsonLockPath() {
|
|
13939
|
-
const stateDir = process.env["OLAM_STATE_DIR"] ??
|
|
13940
|
-
return
|
|
14226
|
+
const stateDir = process.env["OLAM_STATE_DIR"] ?? path26.join(os16.homedir(), ".olam", "state");
|
|
14227
|
+
return path26.join(stateDir, SETTINGS_JSON_LOCK_FILENAME);
|
|
13941
14228
|
}
|
|
13942
14229
|
function defaultIsPidAlive2(pid) {
|
|
13943
14230
|
try {
|
|
@@ -13949,11 +14236,11 @@ function defaultIsPidAlive2(pid) {
|
|
|
13949
14236
|
}
|
|
13950
14237
|
}
|
|
13951
14238
|
function sleep4(ms) {
|
|
13952
|
-
return new Promise((
|
|
14239
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
13953
14240
|
}
|
|
13954
14241
|
function readLockMeta2(lockPath) {
|
|
13955
14242
|
try {
|
|
13956
|
-
const raw =
|
|
14243
|
+
const raw = fs27.readFileSync(lockPath, "utf-8");
|
|
13957
14244
|
const parsed = JSON.parse(raw);
|
|
13958
14245
|
if (typeof parsed?.pid === "number" && typeof parsed?.hostname === "string" && typeof parsed?.timestamp === "number") {
|
|
13959
14246
|
return parsed;
|
|
@@ -13976,12 +14263,12 @@ function isLockStale2(meta2, opts) {
|
|
|
13976
14263
|
function tryAcquireOnce2(lockPath, meta2, opts) {
|
|
13977
14264
|
for (let attempt = 0; attempt <= MAX_STEAL_ATTEMPTS; attempt += 1) {
|
|
13978
14265
|
try {
|
|
13979
|
-
|
|
13980
|
-
const fd =
|
|
14266
|
+
fs27.mkdirSync(path26.dirname(lockPath), { recursive: true });
|
|
14267
|
+
const fd = fs27.openSync(lockPath, "wx", 384);
|
|
13981
14268
|
try {
|
|
13982
|
-
|
|
14269
|
+
fs27.writeSync(fd, JSON.stringify(meta2));
|
|
13983
14270
|
} finally {
|
|
13984
|
-
|
|
14271
|
+
fs27.closeSync(fd);
|
|
13985
14272
|
}
|
|
13986
14273
|
return true;
|
|
13987
14274
|
} catch (err) {
|
|
@@ -13999,9 +14286,9 @@ function tryAcquireOnce2(lockPath, meta2, opts) {
|
|
|
13999
14286
|
}
|
|
14000
14287
|
const victimPath = `${lockPath}.victim-${process.pid}-${attempt}-${Date.now()}`;
|
|
14001
14288
|
try {
|
|
14002
|
-
|
|
14289
|
+
fs27.renameSync(lockPath, victimPath);
|
|
14003
14290
|
try {
|
|
14004
|
-
|
|
14291
|
+
fs27.unlinkSync(victimPath);
|
|
14005
14292
|
} catch {
|
|
14006
14293
|
}
|
|
14007
14294
|
} catch (err) {
|
|
@@ -14033,7 +14320,7 @@ async function acquireSettingsJsonLock(options = {}) {
|
|
|
14033
14320
|
lockPath,
|
|
14034
14321
|
release: () => {
|
|
14035
14322
|
try {
|
|
14036
|
-
|
|
14323
|
+
fs27.unlinkSync(lockPath);
|
|
14037
14324
|
} catch {
|
|
14038
14325
|
}
|
|
14039
14326
|
}
|
|
@@ -14136,14 +14423,14 @@ var init_services_status = __esm({
|
|
|
14136
14423
|
|
|
14137
14424
|
// ../core/dist/skill-sources/meta-hooks-migration-snapshot.js
|
|
14138
14425
|
import * as crypto5 from "node:crypto";
|
|
14139
|
-
import * as
|
|
14426
|
+
import * as fs28 from "node:fs";
|
|
14140
14427
|
import * as os17 from "node:os";
|
|
14141
|
-
import * as
|
|
14428
|
+
import * as path27 from "node:path";
|
|
14142
14429
|
function migrationSnapshotsDir2() {
|
|
14143
14430
|
const override = process.env["OLAM_MIGRATION_SNAPSHOTS_DIR"];
|
|
14144
14431
|
if (override && override.length > 0)
|
|
14145
14432
|
return override;
|
|
14146
|
-
return
|
|
14433
|
+
return path27.join(os17.homedir(), ".olam", "state", "migration-snapshots");
|
|
14147
14434
|
}
|
|
14148
14435
|
function writeMetaHooksSnapshot(originalSettings) {
|
|
14149
14436
|
const snapshot = {
|
|
@@ -14154,11 +14441,11 @@ function writeMetaHooksSnapshot(originalSettings) {
|
|
|
14154
14441
|
};
|
|
14155
14442
|
const validated = MetaHooksMigrationSnapshotSchema.parse(snapshot);
|
|
14156
14443
|
const dir = migrationSnapshotsDir2();
|
|
14157
|
-
|
|
14444
|
+
fs28.mkdirSync(dir, { recursive: true });
|
|
14158
14445
|
const stamp = validated.takenAt.replace(/[:.]/g, "-");
|
|
14159
14446
|
const rand = crypto5.randomBytes(3).toString("hex");
|
|
14160
|
-
const file =
|
|
14161
|
-
|
|
14447
|
+
const file = path27.join(dir, `${META_HOOKS_SNAPSHOT_PREFIX}${stamp}-${process.pid}-${rand}.json`);
|
|
14448
|
+
fs28.writeFileSync(file, JSON.stringify(validated, null, 2) + "\n", { mode: 384 });
|
|
14162
14449
|
return file;
|
|
14163
14450
|
}
|
|
14164
14451
|
var META_HOOKS_SNAPSHOT_SCHEMA_VERSION, META_HOOKS_SNAPSHOT_PREFIX, SettingsLooseSchema, MetaHooksMigrationSnapshotSchema;
|
|
@@ -14389,17 +14676,206 @@ var init_meta_hook_injector = __esm({
|
|
|
14389
14676
|
}
|
|
14390
14677
|
});
|
|
14391
14678
|
|
|
14679
|
+
// ../core/dist/lib/markdown-merger.js
|
|
14680
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
14681
|
+
import { readFileSync as readFileSync27, existsSync as existsSync30, statSync as statSync8 } from "node:fs";
|
|
14682
|
+
function parseFrontmatter(text) {
|
|
14683
|
+
const match = FM_RE2.exec(text);
|
|
14684
|
+
if (match === null)
|
|
14685
|
+
return { fm: {}, body: text };
|
|
14686
|
+
const fmText = match[1] ?? "";
|
|
14687
|
+
const body = text.slice(match[0].length);
|
|
14688
|
+
const fm = {};
|
|
14689
|
+
for (const rawLine of fmText.split("\n")) {
|
|
14690
|
+
const line = rawLine.trim();
|
|
14691
|
+
if (line === "" || line.startsWith("#"))
|
|
14692
|
+
continue;
|
|
14693
|
+
const colonIdx = line.indexOf(":");
|
|
14694
|
+
if (colonIdx === -1)
|
|
14695
|
+
continue;
|
|
14696
|
+
const key = line.slice(0, colonIdx).trim();
|
|
14697
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
14698
|
+
fm[key] = value;
|
|
14699
|
+
}
|
|
14700
|
+
return { fm, body };
|
|
14701
|
+
}
|
|
14702
|
+
function serializeFrontmatter(fm) {
|
|
14703
|
+
if (Object.keys(fm).length === 0)
|
|
14704
|
+
return "";
|
|
14705
|
+
const lines = ["---"];
|
|
14706
|
+
for (const [k, v] of Object.entries(fm)) {
|
|
14707
|
+
lines.push(`${k}: ${v}`);
|
|
14708
|
+
}
|
|
14709
|
+
lines.push("---");
|
|
14710
|
+
return lines.join("\n") + "\n";
|
|
14711
|
+
}
|
|
14712
|
+
function parseSections(body) {
|
|
14713
|
+
H2_RE.lastIndex = 0;
|
|
14714
|
+
const parts = body.split(H2_RE);
|
|
14715
|
+
const sections = [[null, parts[0] ?? ""]];
|
|
14716
|
+
for (let i = 1; i < parts.length; i += 2) {
|
|
14717
|
+
const heading = parts[i] ?? "";
|
|
14718
|
+
const content = parts[i + 1] ?? "";
|
|
14719
|
+
sections.push([heading, content]);
|
|
14720
|
+
}
|
|
14721
|
+
return sections;
|
|
14722
|
+
}
|
|
14723
|
+
function sectionsToBody(sections) {
|
|
14724
|
+
const out = [];
|
|
14725
|
+
for (const [heading, content] of sections) {
|
|
14726
|
+
if (heading === null) {
|
|
14727
|
+
out.push(content);
|
|
14728
|
+
} else {
|
|
14729
|
+
const current = out.join("");
|
|
14730
|
+
if (current !== "" && !current.endsWith("\n\n")) {
|
|
14731
|
+
if (current.endsWith("\n"))
|
|
14732
|
+
out.push("\n");
|
|
14733
|
+
else
|
|
14734
|
+
out.push("\n\n");
|
|
14735
|
+
}
|
|
14736
|
+
out.push(heading + content);
|
|
14737
|
+
}
|
|
14738
|
+
}
|
|
14739
|
+
return out.join("");
|
|
14740
|
+
}
|
|
14741
|
+
function mergeMarkdown(upstreamText, overlayText, labelForError, upstreamPath, overlayPath) {
|
|
14742
|
+
const upstream = parseFrontmatter(upstreamText);
|
|
14743
|
+
const overlay = parseFrontmatter(overlayText);
|
|
14744
|
+
const upHasName = "name" in upstream.fm;
|
|
14745
|
+
const ovHasName = "name" in overlay.fm;
|
|
14746
|
+
if (upHasName !== ovHasName) {
|
|
14747
|
+
return {
|
|
14748
|
+
error: {
|
|
14749
|
+
kind: "schema-mismatch",
|
|
14750
|
+
reason: `[schema-mismatch] ${labelForError}: upstream ${upHasName ? "has" : "lacks"} \`name:\` in frontmatter but overlay ${ovHasName ? "has" : "lacks"} it.` + (upstreamPath !== void 0 ? `
|
|
14751
|
+
upstream: ${upstreamPath}` : "") + (overlayPath !== void 0 ? `
|
|
14752
|
+
overlay: ${overlayPath}` : "")
|
|
14753
|
+
}
|
|
14754
|
+
};
|
|
14755
|
+
}
|
|
14756
|
+
const upstreamStartsFm = upstreamText.startsWith("---");
|
|
14757
|
+
const overlayStartsFm = overlayText.startsWith("---");
|
|
14758
|
+
if (upstreamStartsFm !== overlayStartsFm) {
|
|
14759
|
+
return {
|
|
14760
|
+
error: {
|
|
14761
|
+
kind: "schema-mismatch",
|
|
14762
|
+
reason: `[schema-mismatch] ${labelForError}: one file has YAML frontmatter, the other does not.` + (upstreamPath !== void 0 ? `
|
|
14763
|
+
upstream: ${upstreamPath}` : "") + (overlayPath !== void 0 ? `
|
|
14764
|
+
overlay: ${overlayPath}` : "")
|
|
14765
|
+
}
|
|
14766
|
+
};
|
|
14767
|
+
}
|
|
14768
|
+
const mergedFm = { ...upstream.fm, ...overlay.fm };
|
|
14769
|
+
const upSections = parseSections(upstream.body);
|
|
14770
|
+
const ovSections = parseSections(overlay.body);
|
|
14771
|
+
const ovByHeading = /* @__PURE__ */ new Map();
|
|
14772
|
+
const ovHeadingsOrder = [];
|
|
14773
|
+
for (const [heading, content] of ovSections) {
|
|
14774
|
+
if (heading !== null) {
|
|
14775
|
+
ovByHeading.set(heading, content);
|
|
14776
|
+
ovHeadingsOrder.push(heading);
|
|
14777
|
+
}
|
|
14778
|
+
}
|
|
14779
|
+
const mergedSections = [];
|
|
14780
|
+
const upHeadingsSeen = /* @__PURE__ */ new Set();
|
|
14781
|
+
for (const [heading, content] of upSections) {
|
|
14782
|
+
if (heading === null) {
|
|
14783
|
+
const preamble = content.trim() !== "" ? content : ovSections[0]?.[1] ?? content;
|
|
14784
|
+
mergedSections.push([null, preamble]);
|
|
14785
|
+
} else {
|
|
14786
|
+
const overrideContent = ovByHeading.get(heading);
|
|
14787
|
+
mergedSections.push([heading, overrideContent !== void 0 ? overrideContent : content]);
|
|
14788
|
+
upHeadingsSeen.add(heading);
|
|
14789
|
+
}
|
|
14790
|
+
}
|
|
14791
|
+
for (const heading of ovHeadingsOrder) {
|
|
14792
|
+
if (!upHeadingsSeen.has(heading)) {
|
|
14793
|
+
mergedSections.push([heading, ovByHeading.get(heading)]);
|
|
14794
|
+
}
|
|
14795
|
+
}
|
|
14796
|
+
const mergedBody = sectionsToBody(mergedSections);
|
|
14797
|
+
const fmBlock = serializeFrontmatter(mergedFm);
|
|
14798
|
+
return { merged: fmBlock !== "" ? fmBlock + mergedBody : mergedBody };
|
|
14799
|
+
}
|
|
14800
|
+
function sha256OfPath(p) {
|
|
14801
|
+
if (!existsSync30(p) || !statSync8(p).isFile())
|
|
14802
|
+
return "MISSING";
|
|
14803
|
+
return createHash5("sha256").update(readFileSync27(p)).digest("hex");
|
|
14804
|
+
}
|
|
14805
|
+
var FM_RE2, H2_RE;
|
|
14806
|
+
var init_markdown_merger = __esm({
|
|
14807
|
+
"../core/dist/lib/markdown-merger.js"() {
|
|
14808
|
+
"use strict";
|
|
14809
|
+
FM_RE2 = /^---\n([\s\S]*?)\n---\n?/;
|
|
14810
|
+
H2_RE = /^(## .+)$/gm;
|
|
14811
|
+
}
|
|
14812
|
+
});
|
|
14813
|
+
|
|
14814
|
+
// ../core/dist/skill-sync/managed-merge.js
|
|
14815
|
+
import * as fs29 from "node:fs";
|
|
14816
|
+
import * as path28 from "node:path";
|
|
14817
|
+
function materializeMergedSkill(opts) {
|
|
14818
|
+
const { sourceId, sourcePath, deployBasename, mergedContent, claudeDir: claudeDir2 } = opts;
|
|
14819
|
+
const managedDir = path28.join(claudeDir2, ".olam-merged", sourceId, deployBasename);
|
|
14820
|
+
const sourceRoot = path28.resolve(path28.join(claudeDir2, ".olam-merged", sourceId));
|
|
14821
|
+
const managedResolved = path28.resolve(managedDir);
|
|
14822
|
+
if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot + path28.sep))) {
|
|
14823
|
+
throw new Error(`[managed-merge] refusing to materialize: deployBasename "${deployBasename}" escapes managed root "${sourceRoot}" (resolved to "${managedResolved}")`);
|
|
14824
|
+
}
|
|
14825
|
+
fs29.mkdirSync(managedDir, { recursive: true });
|
|
14826
|
+
const skillMdPath = path28.join(managedDir, "SKILL.md");
|
|
14827
|
+
const tmpPath = `${skillMdPath}.tmp-${process.pid}-${Date.now()}`;
|
|
14828
|
+
fs29.writeFileSync(tmpPath, mergedContent);
|
|
14829
|
+
fs29.renameSync(tmpPath, skillMdPath);
|
|
14830
|
+
const baseEntries = fs29.readdirSync(sourcePath);
|
|
14831
|
+
for (const entry of baseEntries) {
|
|
14832
|
+
if (entry === "SKILL.md")
|
|
14833
|
+
continue;
|
|
14834
|
+
const linkPath = path28.join(managedDir, entry);
|
|
14835
|
+
const targetAbsolute = path28.join(sourcePath, entry);
|
|
14836
|
+
const targetRelative = path28.relative(managedDir, targetAbsolute);
|
|
14837
|
+
try {
|
|
14838
|
+
fs29.lstatSync(linkPath);
|
|
14839
|
+
fs29.rmSync(linkPath, { recursive: true, force: true });
|
|
14840
|
+
} catch {
|
|
14841
|
+
}
|
|
14842
|
+
fs29.symlinkSync(targetRelative, linkPath);
|
|
14843
|
+
}
|
|
14844
|
+
const managedEntries = fs29.readdirSync(managedDir);
|
|
14845
|
+
const baseEntrySet = new Set(baseEntries);
|
|
14846
|
+
for (const entry of managedEntries) {
|
|
14847
|
+
if (entry === "SKILL.md")
|
|
14848
|
+
continue;
|
|
14849
|
+
if (!baseEntrySet.has(entry)) {
|
|
14850
|
+
const stalePath = path28.join(managedDir, entry);
|
|
14851
|
+
try {
|
|
14852
|
+
fs29.rmSync(stalePath, { recursive: true, force: true });
|
|
14853
|
+
} catch {
|
|
14854
|
+
}
|
|
14855
|
+
}
|
|
14856
|
+
}
|
|
14857
|
+
return managedDir;
|
|
14858
|
+
}
|
|
14859
|
+
function cleanMergedDir(claudeDir2) {
|
|
14860
|
+
fs29.rmSync(path28.join(claudeDir2, ".olam-merged"), { recursive: true, force: true });
|
|
14861
|
+
}
|
|
14862
|
+
var init_managed_merge = __esm({
|
|
14863
|
+
"../core/dist/skill-sync/managed-merge.js"() {
|
|
14864
|
+
"use strict";
|
|
14865
|
+
}
|
|
14866
|
+
});
|
|
14867
|
+
|
|
14392
14868
|
// ../core/dist/skill-sync/engine.js
|
|
14393
|
-
import * as
|
|
14869
|
+
import * as fs30 from "node:fs";
|
|
14394
14870
|
import * as os18 from "node:os";
|
|
14395
|
-
import * as
|
|
14871
|
+
import * as path29 from "node:path";
|
|
14396
14872
|
function resolveAtlasUser(override) {
|
|
14397
14873
|
if (override)
|
|
14398
14874
|
return override;
|
|
14399
|
-
const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] ||
|
|
14400
|
-
const f =
|
|
14401
|
-
if (
|
|
14402
|
-
return
|
|
14875
|
+
const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] || path29.join(os18.homedir(), ".claude");
|
|
14876
|
+
const f = path29.join(claudeDir2, ".atlas-user");
|
|
14877
|
+
if (fs30.existsSync(f)) {
|
|
14878
|
+
return fs30.readFileSync(f, "utf-8").trim() || void 0;
|
|
14403
14879
|
}
|
|
14404
14880
|
return void 0;
|
|
14405
14881
|
}
|
|
@@ -14411,7 +14887,7 @@ async function syncSkills(opts = {}) {
|
|
|
14411
14887
|
const perSource = [];
|
|
14412
14888
|
for (const source of sources) {
|
|
14413
14889
|
const clonePath = skillSourceClonePath(source.id);
|
|
14414
|
-
if (!
|
|
14890
|
+
if (!fs30.existsSync(clonePath))
|
|
14415
14891
|
continue;
|
|
14416
14892
|
const { artifacts, subscription } = await withFileLock(clonePath, () => {
|
|
14417
14893
|
const pinRef = projectOverride?.override.pin?.[source.id];
|
|
@@ -14438,7 +14914,57 @@ async function syncSkills(opts = {}) {
|
|
|
14438
14914
|
fromSubscriptionsFile: subscription.fromSubscriptionsFile
|
|
14439
14915
|
});
|
|
14440
14916
|
}
|
|
14441
|
-
const
|
|
14917
|
+
const projectOverrideFilteredArtifacts = projectOverride ? applyOverrideToArtifacts(allArtifacts, projectOverride.override) : allArtifacts;
|
|
14918
|
+
const installedOlamVersion = opts.installedOlamVersion ?? process.env["OLAM_VERSION"] ?? "0.0.0";
|
|
14919
|
+
const minVersionResult = filterArtifactsByMinVersion(projectOverrideFilteredArtifacts, installedOlamVersion);
|
|
14920
|
+
for (const warning of minVersionResult.warnings) {
|
|
14921
|
+
process.stderr.write(`${warning}
|
|
14922
|
+
`);
|
|
14923
|
+
}
|
|
14924
|
+
const projectFilteredArtifacts = minVersionResult.kept;
|
|
14925
|
+
const memberOverlaysEnabled = process.env["OLAM_MEMBER_OVERLAYS"] === "1";
|
|
14926
|
+
const baseArtifacts = projectFilteredArtifacts.filter((a) => a.kind !== "overlay");
|
|
14927
|
+
const overlayArtifacts = memberOverlaysEnabled ? projectFilteredArtifacts.filter((a) => a.kind === "overlay") : [];
|
|
14928
|
+
if (memberOverlaysEnabled && overlayArtifacts.length > 0 && !opts.dryRun) {
|
|
14929
|
+
const claude = claudeDir();
|
|
14930
|
+
cleanMergedDir(claude);
|
|
14931
|
+
for (const overlay of overlayArtifacts) {
|
|
14932
|
+
if (!overlay.targetKind)
|
|
14933
|
+
continue;
|
|
14934
|
+
const base = baseArtifacts.find((a) => a.sourceId === overlay.sourceId && a.kind === overlay.targetKind && a.deployBasename === overlay.deployBasename);
|
|
14935
|
+
if (!base)
|
|
14936
|
+
continue;
|
|
14937
|
+
let baseContent;
|
|
14938
|
+
let basePath;
|
|
14939
|
+
if (overlay.targetKind === "skill") {
|
|
14940
|
+
basePath = path29.join(base.sourcePath, "SKILL.md");
|
|
14941
|
+
baseContent = fs30.readFileSync(basePath, "utf-8");
|
|
14942
|
+
} else {
|
|
14943
|
+
basePath = base.sourcePath;
|
|
14944
|
+
baseContent = fs30.readFileSync(basePath, "utf-8");
|
|
14945
|
+
}
|
|
14946
|
+
const overlayContent = fs30.readFileSync(overlay.sourcePath, "utf-8");
|
|
14947
|
+
const label = `${overlay.sourceId}/${overlay.deployBasename}`;
|
|
14948
|
+
const mergeResult = mergeMarkdown(baseContent, overlayContent, label, basePath, overlay.sourcePath);
|
|
14949
|
+
if ("error" in mergeResult) {
|
|
14950
|
+
process.stderr.write(`[no-such-section] ${label}
|
|
14951
|
+
`);
|
|
14952
|
+
continue;
|
|
14953
|
+
}
|
|
14954
|
+
const mergedBuffer = Buffer.from(mergeResult.merged, "utf-8");
|
|
14955
|
+
base.resolvedContent = mergedBuffer;
|
|
14956
|
+
if (overlay.targetKind === "skill") {
|
|
14957
|
+
const managedDir = materializeMergedSkill({
|
|
14958
|
+
sourceId: base.sourceId,
|
|
14959
|
+
sourcePath: base.sourcePath,
|
|
14960
|
+
deployBasename: base.deployBasename,
|
|
14961
|
+
mergedContent: mergedBuffer,
|
|
14962
|
+
claudeDir: claude
|
|
14963
|
+
});
|
|
14964
|
+
base.sourcePath = managedDir;
|
|
14965
|
+
}
|
|
14966
|
+
}
|
|
14967
|
+
}
|
|
14442
14968
|
const hookFiles = projectFilteredArtifacts.filter((a) => a.kind === "hook").map((a) => a.sourcePath);
|
|
14443
14969
|
const permissionFiles = projectFilteredArtifacts.filter((a) => a.kind === "permission").map((a) => a.sourcePath);
|
|
14444
14970
|
const summary = {
|
|
@@ -14454,10 +14980,15 @@ async function syncSkills(opts = {}) {
|
|
|
14454
14980
|
perSource
|
|
14455
14981
|
};
|
|
14456
14982
|
if (opts.dryRun) {
|
|
14457
|
-
summary.collisions = detectCollisions(
|
|
14983
|
+
summary.collisions = detectCollisions(baseArtifacts).collisions;
|
|
14458
14984
|
return summary;
|
|
14459
14985
|
}
|
|
14460
|
-
|
|
14986
|
+
const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] || path29.join(os18.homedir(), ".claude");
|
|
14987
|
+
const overlayReferences = scanOverlayReferences(claudeDirPath, SHIM_TARGETS.map((t) => t.basename));
|
|
14988
|
+
summary.deploy = deployArtifacts(baseArtifacts, {
|
|
14989
|
+
installedOlamVersion,
|
|
14990
|
+
overlayReferences
|
|
14991
|
+
});
|
|
14461
14992
|
summary.collisions = summary.deploy.collisions;
|
|
14462
14993
|
summary.merge = mergeSettings({ hookFiles, permissionFiles });
|
|
14463
14994
|
if (opts.metaHooks !== "never") {
|
|
@@ -14478,19 +15009,19 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
14478
15009
|
const result = await withSettingsJsonLock(() => {
|
|
14479
15010
|
let currentSettings = {};
|
|
14480
15011
|
let settingsExisted = false;
|
|
14481
|
-
if (
|
|
15012
|
+
if (fs30.existsSync(settingsFile)) {
|
|
14482
15013
|
settingsExisted = true;
|
|
14483
15014
|
try {
|
|
14484
|
-
const raw =
|
|
15015
|
+
const raw = fs30.readFileSync(settingsFile, "utf-8");
|
|
14485
15016
|
currentSettings = raw.trim() ? JSON.parse(raw) : {};
|
|
14486
15017
|
} catch {
|
|
14487
15018
|
try {
|
|
14488
|
-
const raw =
|
|
14489
|
-
const bakDir =
|
|
14490
|
-
|
|
15019
|
+
const raw = fs30.readFileSync(settingsFile);
|
|
15020
|
+
const bakDir = path29.join(path29.dirname(settingsFile), ".malformed-backups");
|
|
15021
|
+
fs30.mkdirSync(bakDir, { recursive: true });
|
|
14491
15022
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
14492
|
-
const bakFile =
|
|
14493
|
-
|
|
15023
|
+
const bakFile = path29.join(bakDir, `settings.json.malformed.${stamp}.bak`);
|
|
15024
|
+
fs30.writeFileSync(bakFile, raw, { mode: 384 });
|
|
14494
15025
|
snapshotError = `settings.json was malformed; original bytes preserved at ${bakFile}`;
|
|
14495
15026
|
} catch (bakErr) {
|
|
14496
15027
|
snapshotError = `settings.json malformed AND .bak write failed: ${bakErr instanceof Error ? bakErr.message : String(bakErr)}`;
|
|
@@ -14540,10 +15071,10 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
14540
15071
|
} catch {
|
|
14541
15072
|
}
|
|
14542
15073
|
}
|
|
14543
|
-
|
|
15074
|
+
fs30.mkdirSync(path29.dirname(settingsFile), { recursive: true });
|
|
14544
15075
|
const tmpPath = `${settingsFile}.tmp-${process.pid}-${Date.now()}`;
|
|
14545
|
-
|
|
14546
|
-
|
|
15076
|
+
fs30.writeFileSync(tmpPath, JSON.stringify(inject.nextSettings, null, 2) + "\n");
|
|
15077
|
+
fs30.renameSync(tmpPath, settingsFile);
|
|
14547
15078
|
return inject;
|
|
14548
15079
|
}, { reason: `syncSkills meta-hook injection (mode=${mode})` });
|
|
14549
15080
|
return {
|
|
@@ -14566,29 +15097,34 @@ var init_engine = __esm({
|
|
|
14566
15097
|
init_settings_merger();
|
|
14567
15098
|
init_per_project_override();
|
|
14568
15099
|
init_file_lock();
|
|
15100
|
+
init_min_version_filter();
|
|
15101
|
+
init_shim_targets();
|
|
15102
|
+
init_overlay_scan();
|
|
14569
15103
|
init_settings_json_lock();
|
|
14570
15104
|
init_services_status();
|
|
14571
15105
|
init_meta_hooks_migration_snapshot();
|
|
14572
15106
|
init_trust_audit_log();
|
|
14573
15107
|
init_atlas_hook_strip();
|
|
14574
15108
|
init_meta_hook_injector();
|
|
15109
|
+
init_markdown_merger();
|
|
15110
|
+
init_managed_merge();
|
|
14575
15111
|
}
|
|
14576
15112
|
});
|
|
14577
15113
|
|
|
14578
15114
|
// ../core/dist/skill-sync/shadow-backup-manager.js
|
|
14579
|
-
import * as
|
|
14580
|
-
import * as
|
|
15115
|
+
import * as fs31 from "node:fs";
|
|
15116
|
+
import * as path30 from "node:path";
|
|
14581
15117
|
function listShadowBackups(opts = {}) {
|
|
14582
15118
|
const claude = opts.claudeDirOverride ?? claudeDir();
|
|
14583
15119
|
const now = opts.now ?? Date.now();
|
|
14584
15120
|
const out = [];
|
|
14585
15121
|
for (const bucket of SHADOW_BACKUP_BUCKETS) {
|
|
14586
|
-
const bucketDir =
|
|
14587
|
-
if (!
|
|
15122
|
+
const bucketDir = path30.join(claude, bucket);
|
|
15123
|
+
if (!fs31.existsSync(bucketDir))
|
|
14588
15124
|
continue;
|
|
14589
15125
|
let entries;
|
|
14590
15126
|
try {
|
|
14591
|
-
entries =
|
|
15127
|
+
entries = fs31.readdirSync(bucketDir);
|
|
14592
15128
|
} catch {
|
|
14593
15129
|
continue;
|
|
14594
15130
|
}
|
|
@@ -14599,10 +15135,10 @@ function listShadowBackups(opts = {}) {
|
|
|
14599
15135
|
const epochSeconds = Number.parseInt(match[1], 10);
|
|
14600
15136
|
if (!Number.isFinite(epochSeconds) || epochSeconds < 0)
|
|
14601
15137
|
continue;
|
|
14602
|
-
const full =
|
|
15138
|
+
const full = path30.join(bucketDir, name);
|
|
14603
15139
|
let sizeBytes = 0;
|
|
14604
15140
|
try {
|
|
14605
|
-
const st =
|
|
15141
|
+
const st = fs31.statSync(full);
|
|
14606
15142
|
if (st.isDirectory())
|
|
14607
15143
|
continue;
|
|
14608
15144
|
sizeBytes = st.size;
|
|
@@ -14615,7 +15151,7 @@ function listShadowBackups(opts = {}) {
|
|
|
14615
15151
|
bucket,
|
|
14616
15152
|
basename: name,
|
|
14617
15153
|
originalBasename,
|
|
14618
|
-
originalPath:
|
|
15154
|
+
originalPath: path30.join(bucketDir, originalBasename),
|
|
14619
15155
|
epochSeconds,
|
|
14620
15156
|
ageMs: now - epochSeconds * 1e3,
|
|
14621
15157
|
sizeBytes
|
|
@@ -14658,7 +15194,7 @@ function pruneShadowBackups(opts) {
|
|
|
14658
15194
|
}
|
|
14659
15195
|
if (!opts.dryRun) {
|
|
14660
15196
|
try {
|
|
14661
|
-
|
|
15197
|
+
fs31.unlinkSync(b.path);
|
|
14662
15198
|
} catch {
|
|
14663
15199
|
skipped.push(b);
|
|
14664
15200
|
continue;
|
|
@@ -14669,24 +15205,24 @@ function pruneShadowBackups(opts) {
|
|
|
14669
15205
|
return { deleted, skipped };
|
|
14670
15206
|
}
|
|
14671
15207
|
function restoreShadowBackup(opts) {
|
|
14672
|
-
const abs =
|
|
14673
|
-
if (!
|
|
15208
|
+
const abs = path30.resolve(opts.backupPath);
|
|
15209
|
+
if (!fs31.existsSync(abs)) {
|
|
14674
15210
|
throw new Error(`backup file not found: ${abs}`);
|
|
14675
15211
|
}
|
|
14676
|
-
const basename6 =
|
|
15212
|
+
const basename6 = path30.basename(abs);
|
|
14677
15213
|
const match = SHADOW_BACKUP_SUFFIX_RE.exec(basename6);
|
|
14678
15214
|
if (!match) {
|
|
14679
15215
|
throw new Error(`not a shadow-backup file (basename "${basename6}" does not match \`.shadow-backup-<epoch>\`): ${abs}`);
|
|
14680
15216
|
}
|
|
14681
15217
|
const originalBasename = basename6.slice(0, basename6.length - match[0].length);
|
|
14682
|
-
const originalPath =
|
|
14683
|
-
if (
|
|
15218
|
+
const originalPath = path30.join(path30.dirname(abs), originalBasename);
|
|
15219
|
+
if (fs31.existsSync(originalPath) && !opts.force) {
|
|
14684
15220
|
throw new Error(`original path already occupied: ${originalPath}. Move/rename it first OR re-run with --force.`);
|
|
14685
15221
|
}
|
|
14686
|
-
if (opts.force &&
|
|
14687
|
-
|
|
15222
|
+
if (opts.force && fs31.existsSync(originalPath)) {
|
|
15223
|
+
fs31.unlinkSync(originalPath);
|
|
14688
15224
|
}
|
|
14689
|
-
|
|
15225
|
+
fs31.renameSync(abs, originalPath);
|
|
14690
15226
|
return { restoredTo: originalPath };
|
|
14691
15227
|
}
|
|
14692
15228
|
var SHADOW_BACKUP_BUCKETS, SHADOW_BACKUP_SUFFIX_RE;
|
|
@@ -14700,14 +15236,14 @@ var init_shadow_backup_manager = __esm({
|
|
|
14700
15236
|
});
|
|
14701
15237
|
|
|
14702
15238
|
// ../core/dist/skill-sources/doctor-checks.js
|
|
14703
|
-
import * as
|
|
14704
|
-
import * as
|
|
15239
|
+
import * as fs32 from "node:fs";
|
|
15240
|
+
import * as path31 from "node:path";
|
|
14705
15241
|
import * as os19 from "node:os";
|
|
14706
15242
|
function claudeDirInternal3() {
|
|
14707
15243
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
14708
15244
|
if (override && override.length > 0)
|
|
14709
15245
|
return override;
|
|
14710
|
-
return
|
|
15246
|
+
return path31.join(os19.homedir(), ".claude");
|
|
14711
15247
|
}
|
|
14712
15248
|
function checkStateFileParse() {
|
|
14713
15249
|
const filePath = globalConfigPath();
|
|
@@ -14716,11 +15252,11 @@ function checkStateFileParse() {
|
|
|
14716
15252
|
healthy: true,
|
|
14717
15253
|
description: `~/.olam state file (${filePath})`
|
|
14718
15254
|
};
|
|
14719
|
-
if (!
|
|
15255
|
+
if (!fs32.existsSync(filePath)) {
|
|
14720
15256
|
result.details = ["(file does not yet exist \u2014 will be created on first write)"];
|
|
14721
15257
|
return result;
|
|
14722
15258
|
}
|
|
14723
|
-
const raw =
|
|
15259
|
+
const raw = fs32.readFileSync(filePath, "utf-8");
|
|
14724
15260
|
let parsed;
|
|
14725
15261
|
try {
|
|
14726
15262
|
parsed = JSON.parse(raw);
|
|
@@ -14730,8 +15266,8 @@ function checkStateFileParse() {
|
|
|
14730
15266
|
result.details = [err instanceof Error ? err.message : String(err)];
|
|
14731
15267
|
result.repair = () => {
|
|
14732
15268
|
const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
|
|
14733
|
-
|
|
14734
|
-
|
|
15269
|
+
fs32.renameSync(filePath, aside);
|
|
15270
|
+
fs32.writeFileSync(filePath, JSON.stringify({ schemaVersion: 1, repos: [], runbooks: [], skillSources: [] }, null, 2));
|
|
14735
15271
|
};
|
|
14736
15272
|
return result;
|
|
14737
15273
|
}
|
|
@@ -14742,7 +15278,7 @@ function checkStateFileParse() {
|
|
|
14742
15278
|
result.details = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
|
|
14743
15279
|
result.repair = () => {
|
|
14744
15280
|
const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
|
|
14745
|
-
|
|
15281
|
+
fs32.copyFileSync(filePath, aside);
|
|
14746
15282
|
const base = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
14747
15283
|
const next = {
|
|
14748
15284
|
...base,
|
|
@@ -14751,7 +15287,7 @@ function checkStateFileParse() {
|
|
|
14751
15287
|
runbooks: [],
|
|
14752
15288
|
skillSources: []
|
|
14753
15289
|
};
|
|
14754
|
-
|
|
15290
|
+
fs32.writeFileSync(filePath, JSON.stringify(next, null, 2));
|
|
14755
15291
|
};
|
|
14756
15292
|
return result;
|
|
14757
15293
|
}
|
|
@@ -14762,16 +15298,16 @@ function checkDanglingSymlinks() {
|
|
|
14762
15298
|
const buckets = ["commands", "agents", "skills", "scripts", "rules"];
|
|
14763
15299
|
const dangling = [];
|
|
14764
15300
|
for (const bucket of buckets) {
|
|
14765
|
-
const dir =
|
|
14766
|
-
if (!
|
|
15301
|
+
const dir = path31.join(claude, bucket);
|
|
15302
|
+
if (!fs32.existsSync(dir))
|
|
14767
15303
|
continue;
|
|
14768
|
-
for (const name of
|
|
14769
|
-
const linkPath =
|
|
15304
|
+
for (const name of fs32.readdirSync(dir)) {
|
|
15305
|
+
const linkPath = path31.join(dir, name);
|
|
14770
15306
|
try {
|
|
14771
|
-
const lst =
|
|
15307
|
+
const lst = fs32.lstatSync(linkPath);
|
|
14772
15308
|
if (!lst.isSymbolicLink())
|
|
14773
15309
|
continue;
|
|
14774
|
-
if (!
|
|
15310
|
+
if (!fs32.existsSync(linkPath)) {
|
|
14775
15311
|
dangling.push(linkPath);
|
|
14776
15312
|
}
|
|
14777
15313
|
} catch {
|
|
@@ -14789,7 +15325,7 @@ function checkDanglingSymlinks() {
|
|
|
14789
15325
|
result.repair = () => {
|
|
14790
15326
|
for (const p of dangling) {
|
|
14791
15327
|
try {
|
|
14792
|
-
|
|
15328
|
+
fs32.unlinkSync(p);
|
|
14793
15329
|
} catch {
|
|
14794
15330
|
}
|
|
14795
15331
|
}
|
|
@@ -14804,19 +15340,19 @@ function checkOrphanedSnapshots() {
|
|
|
14804
15340
|
healthy: true,
|
|
14805
15341
|
description: `orphaned migration snapshots under ${dir}`
|
|
14806
15342
|
};
|
|
14807
|
-
if (!
|
|
15343
|
+
if (!fs32.existsSync(dir)) {
|
|
14808
15344
|
return result;
|
|
14809
15345
|
}
|
|
14810
15346
|
const orphans = [];
|
|
14811
|
-
for (const name of
|
|
15347
|
+
for (const name of fs32.readdirSync(dir)) {
|
|
14812
15348
|
if (!name.endsWith(".json"))
|
|
14813
15349
|
continue;
|
|
14814
|
-
const full =
|
|
15350
|
+
const full = path31.join(dir, name);
|
|
14815
15351
|
try {
|
|
14816
|
-
const stat =
|
|
15352
|
+
const stat = fs32.statSync(full);
|
|
14817
15353
|
if (!stat.isFile())
|
|
14818
15354
|
continue;
|
|
14819
|
-
const raw =
|
|
15355
|
+
const raw = fs32.readFileSync(full, "utf-8");
|
|
14820
15356
|
let parsed;
|
|
14821
15357
|
try {
|
|
14822
15358
|
parsed = JSON.parse(raw);
|
|
@@ -14841,7 +15377,7 @@ function checkOrphanedSnapshots() {
|
|
|
14841
15377
|
result.repair = () => {
|
|
14842
15378
|
for (const o of orphans) {
|
|
14843
15379
|
try {
|
|
14844
|
-
|
|
15380
|
+
fs32.unlinkSync(o.path);
|
|
14845
15381
|
} catch {
|
|
14846
15382
|
}
|
|
14847
15383
|
}
|
|
@@ -14856,12 +15392,12 @@ function checkSentinelDrift() {
|
|
|
14856
15392
|
healthy: true,
|
|
14857
15393
|
description: `olam-skills sentinel block in ${filePath}`
|
|
14858
15394
|
};
|
|
14859
|
-
if (!
|
|
15395
|
+
if (!fs32.existsSync(filePath)) {
|
|
14860
15396
|
return result;
|
|
14861
15397
|
}
|
|
14862
15398
|
let parsed;
|
|
14863
15399
|
try {
|
|
14864
|
-
parsed = JSON.parse(
|
|
15400
|
+
parsed = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
|
|
14865
15401
|
} catch {
|
|
14866
15402
|
return result;
|
|
14867
15403
|
}
|
|
@@ -14902,7 +15438,7 @@ function checkSentinelDrift() {
|
|
|
14902
15438
|
backupSettings();
|
|
14903
15439
|
} catch {
|
|
14904
15440
|
}
|
|
14905
|
-
const next = JSON.parse(
|
|
15441
|
+
const next = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
|
|
14906
15442
|
if (!next.hooks)
|
|
14907
15443
|
return;
|
|
14908
15444
|
for (const stage of Object.keys(next.hooks)) {
|
|
@@ -14925,18 +15461,125 @@ function checkSentinelDrift() {
|
|
|
14925
15461
|
return bad === void 0;
|
|
14926
15462
|
});
|
|
14927
15463
|
}
|
|
14928
|
-
|
|
15464
|
+
fs32.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
14929
15465
|
};
|
|
14930
15466
|
}
|
|
14931
15467
|
return result;
|
|
14932
15468
|
}
|
|
15469
|
+
function checkMemberNameMissing() {
|
|
15470
|
+
const result = {
|
|
15471
|
+
name: "[member-name-missing]",
|
|
15472
|
+
healthy: true,
|
|
15473
|
+
description: "atlas-toolbox registered and ~/.claude/.atlas-user configured"
|
|
15474
|
+
};
|
|
15475
|
+
let atlasSource;
|
|
15476
|
+
try {
|
|
15477
|
+
atlasSource = getSkillSourceByName("atlas-toolbox");
|
|
15478
|
+
} catch (err) {
|
|
15479
|
+
result.healthy = false;
|
|
15480
|
+
result.issue = `global config unreadable: ${err instanceof Error ? err.message : String(err)}`;
|
|
15481
|
+
return result;
|
|
15482
|
+
}
|
|
15483
|
+
if (atlasSource === null) {
|
|
15484
|
+
result.details = ["(atlas-toolbox source not registered \u2014 check not applicable)"];
|
|
15485
|
+
return result;
|
|
15486
|
+
}
|
|
15487
|
+
const claudeDir2 = claudeDirInternal3();
|
|
15488
|
+
const atlasUserPath = path31.join(claudeDir2, ".atlas-user");
|
|
15489
|
+
const value = fs32.existsSync(atlasUserPath) ? fs32.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
15490
|
+
if (value.length > 0) {
|
|
15491
|
+
result.details = [`atlas-user: ${value}`];
|
|
15492
|
+
return result;
|
|
15493
|
+
}
|
|
15494
|
+
result.healthy = false;
|
|
15495
|
+
result.issue = "atlas-toolbox source registered but ~/.claude/.atlas-user not set";
|
|
15496
|
+
const clonePath = skillSourceClonePath(atlasSource.id);
|
|
15497
|
+
const membersDir = path31.join(clonePath, "members");
|
|
15498
|
+
const existing = fs32.existsSync(membersDir) ? fs32.readdirSync(membersDir).filter((e) => {
|
|
15499
|
+
try {
|
|
15500
|
+
return fs32.statSync(path31.join(membersDir, e)).isDirectory();
|
|
15501
|
+
} catch {
|
|
15502
|
+
return false;
|
|
15503
|
+
}
|
|
15504
|
+
}).sort() : [];
|
|
15505
|
+
result.details = [
|
|
15506
|
+
`Set via: echo <name> > ${atlasUserPath}`,
|
|
15507
|
+
`List existing members: ls ${membersDir}`,
|
|
15508
|
+
...existing.length > 0 ? [`Existing members: ${existing.join(", ")}`] : []
|
|
15509
|
+
];
|
|
15510
|
+
return result;
|
|
15511
|
+
}
|
|
15512
|
+
function checkMemberOverlayDrift() {
|
|
15513
|
+
const claudeDir2 = claudeDirInternal3();
|
|
15514
|
+
const atlasUserPath = path31.join(claudeDir2, ".atlas-user");
|
|
15515
|
+
const atlasUser = fs32.existsSync(atlasUserPath) ? fs32.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
15516
|
+
if (atlasUser.length === 0) {
|
|
15517
|
+
return [];
|
|
15518
|
+
}
|
|
15519
|
+
let atlasSource;
|
|
15520
|
+
try {
|
|
15521
|
+
atlasSource = getSkillSourceByName("atlas-toolbox");
|
|
15522
|
+
} catch {
|
|
15523
|
+
return [];
|
|
15524
|
+
}
|
|
15525
|
+
if (atlasSource === null) {
|
|
15526
|
+
return [];
|
|
15527
|
+
}
|
|
15528
|
+
const clonePath = skillSourceClonePath(atlasSource.id);
|
|
15529
|
+
const results = [];
|
|
15530
|
+
for (const kind of ["skills", "agents"]) {
|
|
15531
|
+
const localRoot = path31.join(claudeDir2, `${kind}.overrides`);
|
|
15532
|
+
if (!fs32.existsSync(localRoot))
|
|
15533
|
+
continue;
|
|
15534
|
+
let entries;
|
|
15535
|
+
try {
|
|
15536
|
+
entries = fs32.readdirSync(localRoot);
|
|
15537
|
+
} catch {
|
|
15538
|
+
continue;
|
|
15539
|
+
}
|
|
15540
|
+
for (const entry of entries) {
|
|
15541
|
+
const localFile = path31.join(localRoot, entry);
|
|
15542
|
+
let stat;
|
|
15543
|
+
try {
|
|
15544
|
+
stat = fs32.statSync(localFile);
|
|
15545
|
+
} catch {
|
|
15546
|
+
continue;
|
|
15547
|
+
}
|
|
15548
|
+
if (!stat.isFile())
|
|
15549
|
+
continue;
|
|
15550
|
+
const cloneFile = path31.join(clonePath, "members", atlasUser, `${kind}.overrides`, entry);
|
|
15551
|
+
const localSha = sha256OfPath(localFile);
|
|
15552
|
+
const cloneSha = sha256OfPath(cloneFile);
|
|
15553
|
+
if (localSha === cloneSha) {
|
|
15554
|
+
continue;
|
|
15555
|
+
}
|
|
15556
|
+
const driftResult = {
|
|
15557
|
+
name: `[member-overlay-drift: ${kind}/${entry}]`,
|
|
15558
|
+
healthy: false,
|
|
15559
|
+
description: `Local ${kind}.overrides/${entry} differs from atlas-toolbox member copy`,
|
|
15560
|
+
issue: `SHA mismatch: local=${localSha.slice(0, 8)}\u2026 clone=${cloneSha.slice(0, 8)}\u2026`,
|
|
15561
|
+
details: [
|
|
15562
|
+
`Diff: olam flywheel migrate-overlays --diff ${entry}`,
|
|
15563
|
+
`Push local \u2192 atlas: olam flywheel migrate-overlays --push --target=atlas-toolbox`,
|
|
15564
|
+
`Pull atlas \u2192 local: cp ${cloneFile} ${localFile}`,
|
|
15565
|
+
`Discard local: rm ${localFile}`
|
|
15566
|
+
]
|
|
15567
|
+
};
|
|
15568
|
+
results.push(driftResult);
|
|
15569
|
+
}
|
|
15570
|
+
}
|
|
15571
|
+
return results;
|
|
15572
|
+
}
|
|
14933
15573
|
function runAllDoctorChecks() {
|
|
14934
|
-
|
|
15574
|
+
const base = [
|
|
14935
15575
|
checkStateFileParse(),
|
|
14936
15576
|
checkDanglingSymlinks(),
|
|
14937
15577
|
checkOrphanedSnapshots(),
|
|
14938
|
-
checkSentinelDrift()
|
|
15578
|
+
checkSentinelDrift(),
|
|
15579
|
+
checkMemberNameMissing()
|
|
14939
15580
|
];
|
|
15581
|
+
const driftResults = checkMemberOverlayDrift();
|
|
15582
|
+
return [...base, ...driftResults];
|
|
14940
15583
|
}
|
|
14941
15584
|
var MigrationSnapshotMinimalSchema;
|
|
14942
15585
|
var init_doctor_checks = __esm({
|
|
@@ -14948,6 +15591,9 @@ var init_doctor_checks = __esm({
|
|
|
14948
15591
|
init_migration_snapshot();
|
|
14949
15592
|
init_hook_template();
|
|
14950
15593
|
init_settings_merger();
|
|
15594
|
+
init_store2();
|
|
15595
|
+
init_clone();
|
|
15596
|
+
init_markdown_merger();
|
|
14951
15597
|
MigrationSnapshotMinimalSchema = external_exports.object({
|
|
14952
15598
|
schemaVersion: external_exports.literal(MIGRATION_SNAPSHOT_SCHEMA_VERSION),
|
|
14953
15599
|
takenAt: external_exports.string()
|
|
@@ -14985,6 +15631,8 @@ __export(skill_sources_exports, {
|
|
|
14985
15631
|
backupSettings: () => backupSettings,
|
|
14986
15632
|
buildSkillsHookEntry: () => buildSkillsHookEntry,
|
|
14987
15633
|
checkDanglingSymlinks: () => checkDanglingSymlinks,
|
|
15634
|
+
checkMemberNameMissing: () => checkMemberNameMissing,
|
|
15635
|
+
checkMemberOverlayDrift: () => checkMemberOverlayDrift,
|
|
14988
15636
|
checkOrphanedSnapshots: () => checkOrphanedSnapshots,
|
|
14989
15637
|
checkSentinelDrift: () => checkSentinelDrift,
|
|
14990
15638
|
checkStateFileParse: () => checkStateFileParse,
|
|
@@ -14998,6 +15646,7 @@ __export(skill_sources_exports, {
|
|
|
14998
15646
|
detectToolboxState: () => detectToolboxState,
|
|
14999
15647
|
findProjectOverride: () => findProjectOverride,
|
|
15000
15648
|
getSkillSource: () => getSkillSource,
|
|
15649
|
+
getSkillSourceByName: () => getSkillSourceByName,
|
|
15001
15650
|
installSkillsHookToFile: () => installSkillsHookToFile,
|
|
15002
15651
|
isSkillsHookInstalled: () => isSkillsHookInstalled,
|
|
15003
15652
|
listShadowBackups: () => listShadowBackups,
|
|
@@ -15015,6 +15664,7 @@ __export(skill_sources_exports, {
|
|
|
15015
15664
|
removeSkillSource: () => removeSkillSource,
|
|
15016
15665
|
removeSkillSourceClone: () => removeSkillSourceClone,
|
|
15017
15666
|
reorderSkillSource: () => reorderSkillSource,
|
|
15667
|
+
resolveAtlasUser: () => resolveAtlasUser,
|
|
15018
15668
|
resolveSourceArtifacts: () => resolveSourceArtifacts,
|
|
15019
15669
|
resolveSubscriptions: () => resolveSubscriptions,
|
|
15020
15670
|
restoreCloneToBranchHead: () => restoreCloneToBranchHead,
|
|
@@ -15310,10 +15960,10 @@ function mergeDefs(...defs) {
|
|
|
15310
15960
|
function cloneDef(schema) {
|
|
15311
15961
|
return mergeDefs(schema._zod.def);
|
|
15312
15962
|
}
|
|
15313
|
-
function getElementAtPath(obj,
|
|
15314
|
-
if (!
|
|
15963
|
+
function getElementAtPath(obj, path48) {
|
|
15964
|
+
if (!path48)
|
|
15315
15965
|
return obj;
|
|
15316
|
-
return
|
|
15966
|
+
return path48.reduce((acc, key) => acc?.[key], obj);
|
|
15317
15967
|
}
|
|
15318
15968
|
function promiseAllObject(promisesObj) {
|
|
15319
15969
|
const keys = Object.keys(promisesObj);
|
|
@@ -15722,11 +16372,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
15722
16372
|
}
|
|
15723
16373
|
return false;
|
|
15724
16374
|
}
|
|
15725
|
-
function prefixIssues(
|
|
16375
|
+
function prefixIssues(path48, issues) {
|
|
15726
16376
|
return issues.map((iss) => {
|
|
15727
16377
|
var _a3;
|
|
15728
16378
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
15729
|
-
iss.path.unshift(
|
|
16379
|
+
iss.path.unshift(path48);
|
|
15730
16380
|
return iss;
|
|
15731
16381
|
});
|
|
15732
16382
|
}
|
|
@@ -15873,16 +16523,16 @@ function flattenError(error2, mapper = (issue2) => issue2.message) {
|
|
|
15873
16523
|
}
|
|
15874
16524
|
function formatError(error2, mapper = (issue2) => issue2.message) {
|
|
15875
16525
|
const fieldErrors = { _errors: [] };
|
|
15876
|
-
const processError = (error3,
|
|
16526
|
+
const processError = (error3, path48 = []) => {
|
|
15877
16527
|
for (const issue2 of error3.issues) {
|
|
15878
16528
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
15879
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
16529
|
+
issue2.errors.map((issues) => processError({ issues }, [...path48, ...issue2.path]));
|
|
15880
16530
|
} else if (issue2.code === "invalid_key") {
|
|
15881
|
-
processError({ issues: issue2.issues }, [...
|
|
16531
|
+
processError({ issues: issue2.issues }, [...path48, ...issue2.path]);
|
|
15882
16532
|
} else if (issue2.code === "invalid_element") {
|
|
15883
|
-
processError({ issues: issue2.issues }, [...
|
|
16533
|
+
processError({ issues: issue2.issues }, [...path48, ...issue2.path]);
|
|
15884
16534
|
} else {
|
|
15885
|
-
const fullpath = [...
|
|
16535
|
+
const fullpath = [...path48, ...issue2.path];
|
|
15886
16536
|
if (fullpath.length === 0) {
|
|
15887
16537
|
fieldErrors._errors.push(mapper(issue2));
|
|
15888
16538
|
} else {
|
|
@@ -22099,12 +22749,12 @@ var StdioServerTransport = class {
|
|
|
22099
22749
|
this.onclose?.();
|
|
22100
22750
|
}
|
|
22101
22751
|
send(message) {
|
|
22102
|
-
return new Promise((
|
|
22752
|
+
return new Promise((resolve14) => {
|
|
22103
22753
|
const json = serializeMessage(message);
|
|
22104
22754
|
if (this._stdout.write(json)) {
|
|
22105
|
-
|
|
22755
|
+
resolve14();
|
|
22106
22756
|
} else {
|
|
22107
|
-
this._stdout.once("drain",
|
|
22757
|
+
this._stdout.once("drain", resolve14);
|
|
22108
22758
|
}
|
|
22109
22759
|
});
|
|
22110
22760
|
}
|
|
@@ -24141,7 +24791,7 @@ var Protocol = class {
|
|
|
24141
24791
|
return;
|
|
24142
24792
|
}
|
|
24143
24793
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
24144
|
-
await new Promise((
|
|
24794
|
+
await new Promise((resolve14) => setTimeout(resolve14, pollInterval));
|
|
24145
24795
|
options?.signal?.throwIfAborted();
|
|
24146
24796
|
}
|
|
24147
24797
|
} catch (error2) {
|
|
@@ -24158,7 +24808,7 @@ var Protocol = class {
|
|
|
24158
24808
|
*/
|
|
24159
24809
|
request(request2, resultSchema, options) {
|
|
24160
24810
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
24161
|
-
return new Promise((
|
|
24811
|
+
return new Promise((resolve14, reject2) => {
|
|
24162
24812
|
const earlyReject = (error2) => {
|
|
24163
24813
|
reject2(error2);
|
|
24164
24814
|
};
|
|
@@ -24236,7 +24886,7 @@ var Protocol = class {
|
|
|
24236
24886
|
if (!parseResult.success) {
|
|
24237
24887
|
reject2(parseResult.error);
|
|
24238
24888
|
} else {
|
|
24239
|
-
|
|
24889
|
+
resolve14(parseResult.data);
|
|
24240
24890
|
}
|
|
24241
24891
|
} catch (error2) {
|
|
24242
24892
|
reject2(error2);
|
|
@@ -24497,12 +25147,12 @@ var Protocol = class {
|
|
|
24497
25147
|
}
|
|
24498
25148
|
} catch {
|
|
24499
25149
|
}
|
|
24500
|
-
return new Promise((
|
|
25150
|
+
return new Promise((resolve14, reject2) => {
|
|
24501
25151
|
if (signal.aborted) {
|
|
24502
25152
|
reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
24503
25153
|
return;
|
|
24504
25154
|
}
|
|
24505
|
-
const timeoutId = setTimeout(
|
|
25155
|
+
const timeoutId = setTimeout(resolve14, interval);
|
|
24506
25156
|
signal.addEventListener("abort", () => {
|
|
24507
25157
|
clearTimeout(timeoutId);
|
|
24508
25158
|
reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -25602,7 +26252,7 @@ var McpServer = class {
|
|
|
25602
26252
|
let task = createTaskResult.task;
|
|
25603
26253
|
const pollInterval = task.pollInterval ?? 5e3;
|
|
25604
26254
|
while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
|
|
25605
|
-
await new Promise((
|
|
26255
|
+
await new Promise((resolve14) => setTimeout(resolve14, pollInterval));
|
|
25606
26256
|
const updatedTask = await extra.taskStore.getTask(taskId);
|
|
25607
26257
|
if (!updatedTask) {
|
|
25608
26258
|
throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
|
|
@@ -26521,8 +27171,8 @@ var AuthClient = class {
|
|
|
26521
27171
|
throw new Error(`failed to report rate-limit for ${accountId} (HTTP ${res.status})`);
|
|
26522
27172
|
}
|
|
26523
27173
|
}
|
|
26524
|
-
async request(method,
|
|
26525
|
-
const url2 = `${this.baseUrl}${
|
|
27174
|
+
async request(method, path48, body, attempt = 0) {
|
|
27175
|
+
const url2 = `${this.baseUrl}${path48}`;
|
|
26526
27176
|
const controller = new AbortController();
|
|
26527
27177
|
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
26528
27178
|
const headers = {};
|
|
@@ -26540,7 +27190,7 @@ var AuthClient = class {
|
|
|
26540
27190
|
} catch (err) {
|
|
26541
27191
|
if (attempt < RETRY_COUNT && isTransient(err)) {
|
|
26542
27192
|
await sleep(RETRY_BACKOFF_MS * (attempt + 1));
|
|
26543
|
-
return this.request(method,
|
|
27193
|
+
return this.request(method, path48, body, attempt + 1);
|
|
26544
27194
|
}
|
|
26545
27195
|
throw err;
|
|
26546
27196
|
} finally {
|
|
@@ -26567,7 +27217,7 @@ async function safeText(res) {
|
|
|
26567
27217
|
}
|
|
26568
27218
|
}
|
|
26569
27219
|
function sleep(ms) {
|
|
26570
|
-
return new Promise((
|
|
27220
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
26571
27221
|
}
|
|
26572
27222
|
|
|
26573
27223
|
// ../core/dist/auth/container.js
|
|
@@ -26699,7 +27349,7 @@ function resolveAuthServicePath() {
|
|
|
26699
27349
|
return path3.join(pkgsDir, "auth-service");
|
|
26700
27350
|
}
|
|
26701
27351
|
function sleep2(ms) {
|
|
26702
|
-
return new Promise((
|
|
27352
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
26703
27353
|
}
|
|
26704
27354
|
|
|
26705
27355
|
// ../core/dist/auth/preflight.js
|
|
@@ -27068,6 +27718,9 @@ var WorldRegistry = class {
|
|
|
27068
27718
|
}
|
|
27069
27719
|
}
|
|
27070
27720
|
register(world) {
|
|
27721
|
+
if (world.id === "_planning") {
|
|
27722
|
+
throw new Error("world.id '_planning' is reserved for in-flight planning sessions; see packages/chunks/src/schema.ts PLANNING_WORLD_ID");
|
|
27723
|
+
}
|
|
27071
27724
|
this.db.prepare(`INSERT INTO worlds
|
|
27072
27725
|
(id, name, status, repos, branch, port_offset, workspace_path,
|
|
27073
27726
|
compute_provider, total_cost_usd, thought_count, created_at, updated_at,
|
|
@@ -27391,12 +28044,12 @@ function register3(server, _ctx, _initError) {
|
|
|
27391
28044
|
registry2.close();
|
|
27392
28045
|
}
|
|
27393
28046
|
try {
|
|
27394
|
-
const { default:
|
|
28047
|
+
const { default: fs48 } = await import("node:fs");
|
|
27395
28048
|
const { default: os28 } = await import("node:os");
|
|
27396
|
-
const { default:
|
|
27397
|
-
const tokenPath =
|
|
27398
|
-
if (
|
|
27399
|
-
const token =
|
|
28049
|
+
const { default: path48 } = await import("node:path");
|
|
28050
|
+
const tokenPath = path48.join(os28.homedir(), ".olam", "host-cp.token");
|
|
28051
|
+
if (fs48.existsSync(tokenPath)) {
|
|
28052
|
+
const token = fs48.readFileSync(tokenPath, "utf-8").trim();
|
|
27400
28053
|
await fetch("http://127.0.0.1:19000/api/admin/world-pr", {
|
|
27401
28054
|
method: "POST",
|
|
27402
28055
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
@@ -27816,10 +28469,10 @@ function extractMcpConfig(claudeJsonPath) {
|
|
|
27816
28469
|
}
|
|
27817
28470
|
return { mcpServers, secrets };
|
|
27818
28471
|
}
|
|
27819
|
-
function readOptional(
|
|
27820
|
-
if (!existsSync6(
|
|
28472
|
+
function readOptional(path48) {
|
|
28473
|
+
if (!existsSync6(path48)) return null;
|
|
27821
28474
|
try {
|
|
27822
|
-
return readFileSync5(
|
|
28475
|
+
return readFileSync5(path48, "utf8");
|
|
27823
28476
|
} catch {
|
|
27824
28477
|
return null;
|
|
27825
28478
|
}
|
|
@@ -27944,7 +28597,7 @@ var realDocker = {
|
|
|
27944
28597
|
}
|
|
27945
28598
|
};
|
|
27946
28599
|
function spawnAsync(cmd, args, opts = {}) {
|
|
27947
|
-
return new Promise((
|
|
28600
|
+
return new Promise((resolve14) => {
|
|
27948
28601
|
const child = spawn(cmd, [...args], {
|
|
27949
28602
|
stdio: ["ignore", "pipe", "pipe"],
|
|
27950
28603
|
signal: opts.signal
|
|
@@ -27958,10 +28611,10 @@ function spawnAsync(cmd, args, opts = {}) {
|
|
|
27958
28611
|
stderr += chunk.toString();
|
|
27959
28612
|
});
|
|
27960
28613
|
child.on("error", (err) => {
|
|
27961
|
-
|
|
28614
|
+
resolve14({ exitCode: -1, stdout, stderr: stderr + err.message });
|
|
27962
28615
|
});
|
|
27963
28616
|
child.on("close", (code) => {
|
|
27964
|
-
|
|
28617
|
+
resolve14({ exitCode: code ?? -1, stdout, stderr });
|
|
27965
28618
|
});
|
|
27966
28619
|
});
|
|
27967
28620
|
}
|
|
@@ -28412,7 +29065,7 @@ var stopAndRemove = async (container) => {
|
|
|
28412
29065
|
|
|
28413
29066
|
// ../adapters/dist/docker/exec.js
|
|
28414
29067
|
import { PassThrough } from "node:stream";
|
|
28415
|
-
var demuxStream = (stream) => new Promise((
|
|
29068
|
+
var demuxStream = (stream) => new Promise((resolve14, reject2) => {
|
|
28416
29069
|
const stdoutChunks = [];
|
|
28417
29070
|
const stderrChunks = [];
|
|
28418
29071
|
const stdout = new PassThrough();
|
|
@@ -28426,7 +29079,7 @@ var demuxStream = (stream) => new Promise((resolve13, reject2) => {
|
|
|
28426
29079
|
stream.pipe(stdout);
|
|
28427
29080
|
}
|
|
28428
29081
|
stream.on("end", () => {
|
|
28429
|
-
|
|
29082
|
+
resolve14({
|
|
28430
29083
|
stdout: Buffer.concat(stdoutChunks).toString("utf-8"),
|
|
28431
29084
|
stderr: Buffer.concat(stderrChunks).toString("utf-8")
|
|
28432
29085
|
});
|
|
@@ -28799,7 +29452,7 @@ var SSHConnectionPool = class {
|
|
|
28799
29452
|
// -----------------------------------------------------------------------
|
|
28800
29453
|
async exec(host, command) {
|
|
28801
29454
|
const client = await this.getConnection(host);
|
|
28802
|
-
return new Promise((
|
|
29455
|
+
return new Promise((resolve14, reject2) => {
|
|
28803
29456
|
client.exec(command, (err, stream) => {
|
|
28804
29457
|
if (err) {
|
|
28805
29458
|
reject2(new Error(`SSH exec failed on ${host}: ${err.message}`));
|
|
@@ -28814,7 +29467,7 @@ var SSHConnectionPool = class {
|
|
|
28814
29467
|
stderr += data.toString();
|
|
28815
29468
|
});
|
|
28816
29469
|
stream.on("close", (code) => {
|
|
28817
|
-
|
|
29470
|
+
resolve14({
|
|
28818
29471
|
exitCode: code ?? 0,
|
|
28819
29472
|
stdout: stdout.trimEnd(),
|
|
28820
29473
|
stderr: stderr.trimEnd()
|
|
@@ -28845,10 +29498,10 @@ var SSHConnectionPool = class {
|
|
|
28845
29498
|
throw new Error(`No SSH configuration found for host: ${host}`);
|
|
28846
29499
|
}
|
|
28847
29500
|
const client = new SSHClient();
|
|
28848
|
-
return new Promise((
|
|
29501
|
+
return new Promise((resolve14, reject2) => {
|
|
28849
29502
|
client.on("ready", () => {
|
|
28850
29503
|
this.connections.set(host, client);
|
|
28851
|
-
|
|
29504
|
+
resolve14(client);
|
|
28852
29505
|
}).on("error", (err) => {
|
|
28853
29506
|
this.connections.delete(host);
|
|
28854
29507
|
reject2(new Error(`SSH connection to ${host} failed: ${err.message}`));
|
|
@@ -29265,8 +29918,8 @@ var CloudflareProvider = class extends ComputeProvider {
|
|
|
29265
29918
|
// -----------------------------------------------------------------------
|
|
29266
29919
|
// Internal fetch helper
|
|
29267
29920
|
// -----------------------------------------------------------------------
|
|
29268
|
-
async request(
|
|
29269
|
-
const url2 = `${this.config.workerUrl}${
|
|
29921
|
+
async request(path48, method, body) {
|
|
29922
|
+
const url2 = `${this.config.workerUrl}${path48}`;
|
|
29270
29923
|
const bearer = await this.config.mintToken();
|
|
29271
29924
|
const headers = {
|
|
29272
29925
|
Authorization: `Bearer ${bearer}`
|
|
@@ -29828,7 +30481,7 @@ function register6(server, ctx, initError) {
|
|
|
29828
30481
|
}
|
|
29829
30482
|
} catch {
|
|
29830
30483
|
}
|
|
29831
|
-
await new Promise((
|
|
30484
|
+
await new Promise((resolve14) => setTimeout(resolve14, POLL_INTERVAL_MS));
|
|
29832
30485
|
}
|
|
29833
30486
|
}
|
|
29834
30487
|
if (authenticated) {
|
|
@@ -30764,8 +31417,8 @@ function copyMatchingFiles(sourcePath, destPath, pattern) {
|
|
|
30764
31417
|
try {
|
|
30765
31418
|
const matches2 = globSync(fullPattern);
|
|
30766
31419
|
for (const match of matches2) {
|
|
30767
|
-
const
|
|
30768
|
-
const dest = path10.join(destPath,
|
|
31420
|
+
const relative5 = path10.relative(sourcePath, match);
|
|
31421
|
+
const dest = path10.join(destPath, relative5);
|
|
30769
31422
|
fs8.mkdirSync(path10.dirname(dest), { recursive: true });
|
|
30770
31423
|
fs8.copyFileSync(match, dest);
|
|
30771
31424
|
}
|
|
@@ -31717,10 +32370,10 @@ async function writeManifest(args) {
|
|
|
31717
32370
|
capturedAt: args.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
31718
32371
|
shots: entries
|
|
31719
32372
|
};
|
|
31720
|
-
const
|
|
31721
|
-
await writeFile(
|
|
32373
|
+
const path48 = join13(args.outDir, "manifest.json");
|
|
32374
|
+
await writeFile(path48, `${JSON.stringify(manifest, null, 2)}
|
|
31722
32375
|
`, "utf8");
|
|
31723
|
-
return { path:
|
|
32376
|
+
return { path: path48, manifest };
|
|
31724
32377
|
}
|
|
31725
32378
|
|
|
31726
32379
|
// ../mcp-server/src/tools/_capture/proxy.ts
|
|
@@ -31974,9 +32627,9 @@ async function startProxy(opts) {
|
|
|
31974
32627
|
const liveCompiled = verified.allowedPaths.map(compileGlob);
|
|
31975
32628
|
const target = parseRequestTarget(req);
|
|
31976
32629
|
if (!target) return httpReject(400, "invalid_target");
|
|
31977
|
-
const
|
|
31978
|
-
if (!liveCompiled.some((re) => re.test(
|
|
31979
|
-
return httpReject(403, "outside_allow_list", { path:
|
|
32630
|
+
const path48 = target.pathname;
|
|
32631
|
+
if (!liveCompiled.some((re) => re.test(path48))) {
|
|
32632
|
+
return httpReject(403, "outside_allow_list", { path: path48 });
|
|
31980
32633
|
}
|
|
31981
32634
|
const headerWorld = req.headers[WORLD_ASSERT_HEADER];
|
|
31982
32635
|
const headerWorldStr = typeof headerWorld === "string" ? headerWorld : Array.isArray(headerWorld) && headerWorld.length > 0 ? headerWorld[0] : void 0;
|
|
@@ -32080,15 +32733,15 @@ ${JSON.stringify({ error: reason })}`
|
|
|
32080
32733
|
unlinkSync2(udsPath);
|
|
32081
32734
|
} catch {
|
|
32082
32735
|
}
|
|
32083
|
-
await new Promise((
|
|
32084
|
-
server.listen(udsPath, () =>
|
|
32736
|
+
await new Promise((resolve14, reject2) => {
|
|
32737
|
+
server.listen(udsPath, () => resolve14());
|
|
32085
32738
|
server.once("error", reject2);
|
|
32086
32739
|
});
|
|
32087
32740
|
chmodSync3(udsPath, 384);
|
|
32088
32741
|
port2 = 0;
|
|
32089
32742
|
} else {
|
|
32090
|
-
await new Promise((
|
|
32091
|
-
server.listen(opts.port ?? 0, "127.0.0.1", () =>
|
|
32743
|
+
await new Promise((resolve14, reject2) => {
|
|
32744
|
+
server.listen(opts.port ?? 0, "127.0.0.1", () => resolve14());
|
|
32092
32745
|
server.once("error", reject2);
|
|
32093
32746
|
});
|
|
32094
32747
|
const addr = server.address();
|
|
@@ -32104,10 +32757,10 @@ ${JSON.stringify({ error: reason })}`
|
|
|
32104
32757
|
} catch {
|
|
32105
32758
|
}
|
|
32106
32759
|
await Promise.race([
|
|
32107
|
-
new Promise((
|
|
32108
|
-
server.close((err) => err ? reject2(err) :
|
|
32760
|
+
new Promise((resolve14, reject2) => {
|
|
32761
|
+
server.close((err) => err ? reject2(err) : resolve14());
|
|
32109
32762
|
}),
|
|
32110
|
-
new Promise((
|
|
32763
|
+
new Promise((resolve14) => setTimeout(resolve14, 5e3))
|
|
32111
32764
|
]);
|
|
32112
32765
|
if (udsPath) {
|
|
32113
32766
|
try {
|
|
@@ -32439,10 +33092,10 @@ async function acquireLaunchSlot() {
|
|
|
32439
33092
|
_inFlightLaunches++;
|
|
32440
33093
|
return releaseLaunchSlot;
|
|
32441
33094
|
}
|
|
32442
|
-
return new Promise((
|
|
33095
|
+
return new Promise((resolve14) => {
|
|
32443
33096
|
_launchQueue.push(() => {
|
|
32444
33097
|
_inFlightLaunches++;
|
|
32445
|
-
|
|
33098
|
+
resolve14(releaseLaunchSlot);
|
|
32446
33099
|
});
|
|
32447
33100
|
});
|
|
32448
33101
|
}
|
|
@@ -32458,8 +33111,8 @@ function resolveShootsRoot() {
|
|
|
32458
33111
|
}
|
|
32459
33112
|
function isUnderRoot(absPath, root) {
|
|
32460
33113
|
if (absPath === root) return true;
|
|
32461
|
-
const
|
|
32462
|
-
return absPath.startsWith(root +
|
|
33114
|
+
const sep4 = root.endsWith("/") ? "" : "/";
|
|
33115
|
+
return absPath.startsWith(root + sep4);
|
|
32463
33116
|
}
|
|
32464
33117
|
function deriveAllowedPaths(shots) {
|
|
32465
33118
|
const paths = /* @__PURE__ */ new Set();
|
|
@@ -32755,14 +33408,14 @@ async function runShot(browser, shot, outDir, format, jpegQuality, allowEval, as
|
|
|
32755
33408
|
await page.waitForTimeout(shot.afterLoadMs);
|
|
32756
33409
|
}
|
|
32757
33410
|
const ext = format === "jpeg" ? "jpg" : "png";
|
|
32758
|
-
const
|
|
33411
|
+
const path48 = join14(outDir, `${shot.name}.${ext}`);
|
|
32759
33412
|
await page.screenshot({
|
|
32760
|
-
path:
|
|
33413
|
+
path: path48,
|
|
32761
33414
|
type: format,
|
|
32762
33415
|
...format === "jpeg" ? { quality: jpegQuality } : {},
|
|
32763
33416
|
fullPage: false
|
|
32764
33417
|
});
|
|
32765
|
-
return { name: shot.name, path:
|
|
33418
|
+
return { name: shot.name, path: path48, urlRedacted: redactUrl(shot.url), viewport };
|
|
32766
33419
|
} finally {
|
|
32767
33420
|
await context.close();
|
|
32768
33421
|
}
|
|
@@ -33206,12 +33859,12 @@ function openUrl(url2) {
|
|
|
33206
33859
|
var HOST_CP_URL = "http://127.0.0.1:19000";
|
|
33207
33860
|
async function readHostCpToken2() {
|
|
33208
33861
|
try {
|
|
33209
|
-
const { default:
|
|
33862
|
+
const { default: fs48 } = await import("node:fs");
|
|
33210
33863
|
const { default: os28 } = await import("node:os");
|
|
33211
|
-
const { default:
|
|
33212
|
-
const tp =
|
|
33213
|
-
if (!
|
|
33214
|
-
return { token:
|
|
33864
|
+
const { default: path48 } = await import("node:path");
|
|
33865
|
+
const tp = path48.join(os28.homedir(), ".olam", "host-cp.token");
|
|
33866
|
+
if (!fs48.existsSync(tp)) return { token: null };
|
|
33867
|
+
return { token: fs48.readFileSync(tp, "utf-8").trim() };
|
|
33215
33868
|
} catch {
|
|
33216
33869
|
return { token: null };
|
|
33217
33870
|
}
|
|
@@ -33471,9 +34124,9 @@ function register22(server, _ctx, _initError) {
|
|
|
33471
34124
|
description: external_exports.string().optional().describe("Optional human-readable description."),
|
|
33472
34125
|
defaultBranch: external_exports.string().optional().describe("Default branch name (e.g. main).")
|
|
33473
34126
|
},
|
|
33474
|
-
async ({ name, path:
|
|
34127
|
+
async ({ name, path: path48, description, defaultBranch }) => {
|
|
33475
34128
|
try {
|
|
33476
|
-
const entry = addRepo({ name, path:
|
|
34129
|
+
const entry = addRepo({ name, path: path48, description, defaultBranch });
|
|
33477
34130
|
return {
|
|
33478
34131
|
content: [{
|
|
33479
34132
|
type: "text",
|
|
@@ -33514,9 +34167,9 @@ function register22(server, _ctx, _initError) {
|
|
|
33514
34167
|
description: external_exports.string().optional().describe("New description."),
|
|
33515
34168
|
defaultBranch: external_exports.string().optional().describe("New default branch.")
|
|
33516
34169
|
},
|
|
33517
|
-
async ({ name, path:
|
|
34170
|
+
async ({ name, path: path48, description, defaultBranch }) => {
|
|
33518
34171
|
try {
|
|
33519
|
-
const entry = updateRepo(name, { path:
|
|
34172
|
+
const entry = updateRepo(name, { path: path48, description, defaultBranch });
|
|
33520
34173
|
return {
|
|
33521
34174
|
content: [{
|
|
33522
34175
|
type: "text",
|
|
@@ -33537,15 +34190,15 @@ __export(process_port_exports, {
|
|
|
33537
34190
|
resolveHostCpToken: () => resolveHostCpToken
|
|
33538
34191
|
});
|
|
33539
34192
|
init_v3();
|
|
33540
|
-
import
|
|
34193
|
+
import fs33 from "node:fs";
|
|
33541
34194
|
import os20 from "node:os";
|
|
33542
|
-
import
|
|
34195
|
+
import path32 from "node:path";
|
|
33543
34196
|
var HOST_CP_BASE = "http://127.0.0.1:19000";
|
|
33544
34197
|
function resolveHostCpToken() {
|
|
33545
34198
|
const envToken = process.env["OLAM_HOST_CP_TOKEN"];
|
|
33546
34199
|
if (envToken) return envToken;
|
|
33547
|
-
const tokenPath =
|
|
33548
|
-
if (
|
|
34200
|
+
const tokenPath = path32.join(os20.homedir(), ".olam", "host-cp.token");
|
|
34201
|
+
if (fs33.existsSync(tokenPath)) return fs33.readFileSync(tokenPath, "utf-8").trim();
|
|
33549
34202
|
return null;
|
|
33550
34203
|
}
|
|
33551
34204
|
function tokenMissingError() {
|
|
@@ -33977,8 +34630,8 @@ __export(skills_exports, {
|
|
|
33977
34630
|
});
|
|
33978
34631
|
init_v3();
|
|
33979
34632
|
init_skill_sources();
|
|
33980
|
-
import * as
|
|
33981
|
-
import * as
|
|
34633
|
+
import * as fs34 from "node:fs";
|
|
34634
|
+
import * as path33 from "node:path";
|
|
33982
34635
|
function asMessage8(err) {
|
|
33983
34636
|
return err instanceof Error ? err.message : String(err);
|
|
33984
34637
|
}
|
|
@@ -34001,14 +34654,14 @@ function listDeployed() {
|
|
|
34001
34654
|
);
|
|
34002
34655
|
const entries = [];
|
|
34003
34656
|
for (const bucket of ["skills", "agents", "scripts", "rules", "commands"]) {
|
|
34004
|
-
const bucketDir =
|
|
34005
|
-
if (!
|
|
34006
|
-
for (const name of
|
|
34007
|
-
const full =
|
|
34657
|
+
const bucketDir = path33.join(dir, bucket);
|
|
34658
|
+
if (!fs34.existsSync(bucketDir)) continue;
|
|
34659
|
+
for (const name of fs34.readdirSync(bucketDir)) {
|
|
34660
|
+
const full = path33.join(bucketDir, name);
|
|
34008
34661
|
try {
|
|
34009
|
-
const stat =
|
|
34662
|
+
const stat = fs34.lstatSync(full);
|
|
34010
34663
|
if (!stat.isSymbolicLink()) continue;
|
|
34011
|
-
const target =
|
|
34664
|
+
const target = fs34.readlinkSync(full);
|
|
34012
34665
|
let sourceId;
|
|
34013
34666
|
for (const [clonePath, id] of sourcePaths.entries()) {
|
|
34014
34667
|
if (target.startsWith(clonePath)) {
|
|
@@ -34104,8 +34757,8 @@ function port() {
|
|
|
34104
34757
|
const n = Number.parseInt(env, 10);
|
|
34105
34758
|
return Number.isFinite(n) && n > 0 ? n : KG_SERVICE_PORT_DEFAULT;
|
|
34106
34759
|
}
|
|
34107
|
-
function url(
|
|
34108
|
-
return `http://127.0.0.1:${port()}${
|
|
34760
|
+
function url(path48) {
|
|
34761
|
+
return `http://127.0.0.1:${port()}${path48}`;
|
|
34109
34762
|
}
|
|
34110
34763
|
function kgServiceHealthUrl() {
|
|
34111
34764
|
return url("/health");
|
|
@@ -34304,8 +34957,8 @@ __export(kg_install_hook_exports, {
|
|
|
34304
34957
|
});
|
|
34305
34958
|
init_v3();
|
|
34306
34959
|
init_merge_settings();
|
|
34307
|
-
import * as
|
|
34308
|
-
import * as
|
|
34960
|
+
import * as fs35 from "node:fs";
|
|
34961
|
+
import * as path34 from "node:path";
|
|
34309
34962
|
import * as os21 from "node:os";
|
|
34310
34963
|
|
|
34311
34964
|
// ../core/dist/kg/hook-template.js
|
|
@@ -34356,10 +35009,10 @@ function buildHookMatcherEntry(opts) {
|
|
|
34356
35009
|
// ../mcp-server/src/tools/kg-install-hook.ts
|
|
34357
35010
|
function settingsPathFor2(scope, projectPath) {
|
|
34358
35011
|
if (scope === "user") {
|
|
34359
|
-
return
|
|
35012
|
+
return path34.join(os21.homedir(), ".claude", "settings.json");
|
|
34360
35013
|
}
|
|
34361
35014
|
const root = projectPath ?? process.cwd();
|
|
34362
|
-
return
|
|
35015
|
+
return path34.join(root, ".claude", "settings.json");
|
|
34363
35016
|
}
|
|
34364
35017
|
function register29(server, _ctx, _initError) {
|
|
34365
35018
|
server.tool(
|
|
@@ -34373,12 +35026,12 @@ function register29(server, _ctx, _initError) {
|
|
|
34373
35026
|
const scope = params.scope === "user" ? "user" : "project";
|
|
34374
35027
|
const filePath = settingsPathFor2(scope, params.projectPath);
|
|
34375
35028
|
try {
|
|
34376
|
-
|
|
35029
|
+
fs35.mkdirSync(path34.dirname(filePath), { recursive: true });
|
|
34377
35030
|
let backupPath = null;
|
|
34378
|
-
if (
|
|
35031
|
+
if (fs35.existsSync(filePath)) {
|
|
34379
35032
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
34380
35033
|
backupPath = `${filePath}.olam-bak.${ts}`;
|
|
34381
|
-
|
|
35034
|
+
fs35.copyFileSync(filePath, backupPath);
|
|
34382
35035
|
}
|
|
34383
35036
|
const result = mergeHomeSettingsJson(filePath, {
|
|
34384
35037
|
ensureHook: {
|
|
@@ -34389,7 +35042,7 @@ function register29(server, _ctx, _initError) {
|
|
|
34389
35042
|
});
|
|
34390
35043
|
if (result.status === "already-present" && backupPath) {
|
|
34391
35044
|
try {
|
|
34392
|
-
|
|
35045
|
+
fs35.unlinkSync(backupPath);
|
|
34393
35046
|
} catch {
|
|
34394
35047
|
}
|
|
34395
35048
|
}
|
|
@@ -34433,15 +35086,15 @@ __export(kg_uninstall_hook_exports, {
|
|
|
34433
35086
|
register: () => register30
|
|
34434
35087
|
});
|
|
34435
35088
|
init_v3();
|
|
34436
|
-
import * as
|
|
34437
|
-
import * as
|
|
35089
|
+
import * as fs36 from "node:fs";
|
|
35090
|
+
import * as path35 from "node:path";
|
|
34438
35091
|
import * as os22 from "node:os";
|
|
34439
35092
|
function settingsPathFor3(scope, projectPath) {
|
|
34440
35093
|
if (scope === "user") {
|
|
34441
|
-
return
|
|
35094
|
+
return path35.join(os22.homedir(), ".claude", "settings.json");
|
|
34442
35095
|
}
|
|
34443
35096
|
const root = projectPath ?? process.cwd();
|
|
34444
|
-
return
|
|
35097
|
+
return path35.join(root, ".claude", "settings.json");
|
|
34445
35098
|
}
|
|
34446
35099
|
function dropSentinel(matchers) {
|
|
34447
35100
|
let changed = false;
|
|
@@ -34475,7 +35128,7 @@ function register30(server, _ctx, _initError) {
|
|
|
34475
35128
|
const scope = params.scope === "user" ? "user" : "project";
|
|
34476
35129
|
const filePath = settingsPathFor3(scope, params.projectPath);
|
|
34477
35130
|
try {
|
|
34478
|
-
if (!
|
|
35131
|
+
if (!fs36.existsSync(filePath)) {
|
|
34479
35132
|
return {
|
|
34480
35133
|
content: [
|
|
34481
35134
|
{
|
|
@@ -34489,7 +35142,7 @@ function register30(server, _ctx, _initError) {
|
|
|
34489
35142
|
]
|
|
34490
35143
|
};
|
|
34491
35144
|
}
|
|
34492
|
-
const raw =
|
|
35145
|
+
const raw = fs36.readFileSync(filePath, "utf-8");
|
|
34493
35146
|
const settings = raw.trim() ? JSON.parse(raw) : {};
|
|
34494
35147
|
const preToolUse = settings.hooks?.PreToolUse;
|
|
34495
35148
|
if (!Array.isArray(preToolUse) || preToolUse.length === 0) {
|
|
@@ -34524,7 +35177,7 @@ function register30(server, _ctx, _initError) {
|
|
|
34524
35177
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
34525
35178
|
const backupPath = `${filePath}.olam-bak.${ts}`;
|
|
34526
35179
|
try {
|
|
34527
|
-
|
|
35180
|
+
fs36.copyFileSync(filePath, backupPath);
|
|
34528
35181
|
} catch {
|
|
34529
35182
|
}
|
|
34530
35183
|
const next = {
|
|
@@ -34536,7 +35189,7 @@ function register30(server, _ctx, _initError) {
|
|
|
34536
35189
|
if (otherStages.length === 0) delete next.hooks;
|
|
34537
35190
|
else delete next.hooks.PreToolUse;
|
|
34538
35191
|
}
|
|
34539
|
-
|
|
35192
|
+
fs36.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
34540
35193
|
return {
|
|
34541
35194
|
content: [
|
|
34542
35195
|
{
|
|
@@ -34751,9 +35404,9 @@ init_loader();
|
|
|
34751
35404
|
// ../core/dist/world/manager.js
|
|
34752
35405
|
import * as crypto8 from "node:crypto";
|
|
34753
35406
|
import { execSync as execSync5, spawnSync as spawnSync4 } from "node:child_process";
|
|
34754
|
-
import * as
|
|
35407
|
+
import * as fs45 from "node:fs";
|
|
34755
35408
|
import * as os26 from "node:os";
|
|
34756
|
-
import * as
|
|
35409
|
+
import * as path45 from "node:path";
|
|
34757
35410
|
|
|
34758
35411
|
// ../core/dist/world/state.js
|
|
34759
35412
|
var VALID_TRANSITIONS = {
|
|
@@ -34849,8 +35502,8 @@ function resolveDevboxImage(config2, tag) {
|
|
|
34849
35502
|
|
|
34850
35503
|
// ../core/dist/world/worktree.js
|
|
34851
35504
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
34852
|
-
import * as
|
|
34853
|
-
import * as
|
|
35505
|
+
import * as fs37 from "node:fs";
|
|
35506
|
+
import * as path36 from "node:path";
|
|
34854
35507
|
function resolveGitDir(repo) {
|
|
34855
35508
|
if (repo.path) {
|
|
34856
35509
|
return repo.path;
|
|
@@ -34860,11 +35513,11 @@ function resolveGitDir(repo) {
|
|
|
34860
35513
|
async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
34861
35514
|
const created = [];
|
|
34862
35515
|
for (const repo of repos) {
|
|
34863
|
-
const worktreePath =
|
|
35516
|
+
const worktreePath = path36.join(workspacePath, repo.name);
|
|
34864
35517
|
const gitDir = resolveGitDir(repo);
|
|
34865
35518
|
const branchName = branch || `olam/${worldId}`;
|
|
34866
35519
|
try {
|
|
34867
|
-
|
|
35520
|
+
fs37.mkdirSync(path36.dirname(worktreePath), { recursive: true });
|
|
34868
35521
|
execFileSync4("git", ["worktree", "add", worktreePath, "-b", branchName], {
|
|
34869
35522
|
cwd: gitDir,
|
|
34870
35523
|
stdio: "pipe"
|
|
@@ -34897,7 +35550,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
|
34897
35550
|
}
|
|
34898
35551
|
async function removeWorktrees(repos, workspacePath) {
|
|
34899
35552
|
for (const repo of repos) {
|
|
34900
|
-
const worktreePath =
|
|
35553
|
+
const worktreePath = path36.join(workspacePath, repo.name);
|
|
34901
35554
|
let gitDir;
|
|
34902
35555
|
try {
|
|
34903
35556
|
gitDir = resolveGitDir(repo);
|
|
@@ -34972,12 +35625,12 @@ function removeBranch(repo, branch) {
|
|
|
34972
35625
|
|
|
34973
35626
|
// ../core/dist/world/kg-overlay.js
|
|
34974
35627
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
34975
|
-
import * as
|
|
34976
|
-
import * as
|
|
35628
|
+
import * as fs38 from "node:fs";
|
|
35629
|
+
import * as path37 from "node:path";
|
|
34977
35630
|
|
|
34978
35631
|
// ../core/dist/kg/storage-paths.js
|
|
34979
35632
|
import { homedir as homedir22 } from "node:os";
|
|
34980
|
-
import { join as
|
|
35633
|
+
import { join as join37, resolve as resolve9 } from "node:path";
|
|
34981
35634
|
|
|
34982
35635
|
// ../core/dist/world/workspace-name.js
|
|
34983
35636
|
var InvalidWorkspaceNameError = class extends Error {
|
|
@@ -34998,25 +35651,25 @@ function validateWorkspaceName(name) {
|
|
|
34998
35651
|
|
|
34999
35652
|
// ../core/dist/kg/storage-paths.js
|
|
35000
35653
|
function olamHome() {
|
|
35001
|
-
return process.env.OLAM_HOME ??
|
|
35654
|
+
return process.env.OLAM_HOME ?? join37(homedir22(), ".olam");
|
|
35002
35655
|
}
|
|
35003
35656
|
function kgRoot() {
|
|
35004
|
-
return
|
|
35657
|
+
return join37(olamHome(), "kg");
|
|
35005
35658
|
}
|
|
35006
35659
|
function worldsRoot() {
|
|
35007
|
-
return
|
|
35660
|
+
return join37(olamHome(), "worlds");
|
|
35008
35661
|
}
|
|
35009
|
-
function assertWithinPrefix(
|
|
35010
|
-
if (!
|
|
35011
|
-
throw new Error(`${label} escape: ${
|
|
35662
|
+
function assertWithinPrefix(path48, prefix, label) {
|
|
35663
|
+
if (!path48.startsWith(prefix + "/")) {
|
|
35664
|
+
throw new Error(`${label} escape: ${path48} not under ${prefix}/`);
|
|
35012
35665
|
}
|
|
35013
35666
|
}
|
|
35014
35667
|
function kgPristinePath(workspace) {
|
|
35015
35668
|
validateWorkspaceName(workspace);
|
|
35016
35669
|
const root = kgRoot();
|
|
35017
|
-
const
|
|
35018
|
-
assertWithinPrefix(
|
|
35019
|
-
return
|
|
35670
|
+
const path48 = resolve9(join37(root, workspace));
|
|
35671
|
+
assertWithinPrefix(path48, root, "kgPristinePath");
|
|
35672
|
+
return path48;
|
|
35020
35673
|
}
|
|
35021
35674
|
var KG_PATHS_INTERNALS = Object.freeze({
|
|
35022
35675
|
olamHome,
|
|
@@ -35032,10 +35685,10 @@ var KgOverlayError = class extends Error {
|
|
|
35032
35685
|
}
|
|
35033
35686
|
};
|
|
35034
35687
|
function ensureGitignoreEntry(worldClonePath) {
|
|
35035
|
-
const gitignorePath =
|
|
35036
|
-
if (!
|
|
35688
|
+
const gitignorePath = path37.join(worldClonePath, ".gitignore");
|
|
35689
|
+
if (!fs38.existsSync(gitignorePath))
|
|
35037
35690
|
return "no-gitignore";
|
|
35038
|
-
const content =
|
|
35691
|
+
const content = fs38.readFileSync(gitignorePath, "utf-8");
|
|
35039
35692
|
const lines = content.split("\n").map((l) => l.trim());
|
|
35040
35693
|
const recognised = /* @__PURE__ */ new Set([
|
|
35041
35694
|
"graphify-out",
|
|
@@ -35050,24 +35703,24 @@ function ensureGitignoreEntry(worldClonePath) {
|
|
|
35050
35703
|
const eol = content.includes("\r\n") ? "\r\n" : "\n";
|
|
35051
35704
|
const needsLeadingNewline = content.length > 0 && !content.endsWith(eol);
|
|
35052
35705
|
const block = `${needsLeadingNewline ? eol : ""}${eol}# olam-kg-service: per-world KG overlay (Phase B1)${eol}graphify-out/${eol}`;
|
|
35053
|
-
|
|
35706
|
+
fs38.appendFileSync(gitignorePath, block, "utf-8");
|
|
35054
35707
|
return "appended";
|
|
35055
35708
|
}
|
|
35056
35709
|
function createWorldOverlay(opts) {
|
|
35057
35710
|
const pristineRoot = kgPristinePath(opts.workspace);
|
|
35058
|
-
const pristinePath =
|
|
35059
|
-
if (!
|
|
35711
|
+
const pristinePath = path37.join(pristineRoot, "graphify-out");
|
|
35712
|
+
if (!fs38.existsSync(pristinePath)) {
|
|
35060
35713
|
throw new KgOverlayError(`Pristine KG for workspace ${JSON.stringify(opts.workspace)} not found at ${pristinePath}. Run \`olam kg build ${opts.workspace}\` first.`);
|
|
35061
35714
|
}
|
|
35062
|
-
if (!
|
|
35715
|
+
if (!path37.isAbsolute(opts.worldClonePath)) {
|
|
35063
35716
|
throw new KgOverlayError(`worldClonePath must be absolute (got ${opts.worldClonePath})`);
|
|
35064
35717
|
}
|
|
35065
|
-
if (!
|
|
35718
|
+
if (!fs38.existsSync(opts.worldClonePath)) {
|
|
35066
35719
|
throw new KgOverlayError(`worldClonePath does not exist: ${opts.worldClonePath}. Create the clone before reflinking.`);
|
|
35067
35720
|
}
|
|
35068
|
-
const overlayPath =
|
|
35069
|
-
if (
|
|
35070
|
-
|
|
35721
|
+
const overlayPath = path37.join(opts.worldClonePath, "graphify-out");
|
|
35722
|
+
if (fs38.existsSync(overlayPath)) {
|
|
35723
|
+
fs38.rmSync(overlayPath, { recursive: true, force: true });
|
|
35071
35724
|
}
|
|
35072
35725
|
const useReflink = process.platform === "darwin";
|
|
35073
35726
|
let strategy;
|
|
@@ -35085,7 +35738,7 @@ function createWorldOverlay(opts) {
|
|
|
35085
35738
|
} else {
|
|
35086
35739
|
strategy = "cp-r";
|
|
35087
35740
|
}
|
|
35088
|
-
if (strategy === "cp-r" || !
|
|
35741
|
+
if (strategy === "cp-r" || !fs38.existsSync(overlayPath)) {
|
|
35089
35742
|
try {
|
|
35090
35743
|
execFileSync5("cp", ["-r", pristinePath, opts.worldClonePath], {
|
|
35091
35744
|
stdio: ["ignore", "ignore", "pipe"]
|
|
@@ -35097,7 +35750,7 @@ function createWorldOverlay(opts) {
|
|
|
35097
35750
|
throw new KgOverlayError(`cp -r failed: ${msg}${reflinkMsg}`);
|
|
35098
35751
|
}
|
|
35099
35752
|
}
|
|
35100
|
-
if (!
|
|
35753
|
+
if (!fs38.existsSync(overlayPath)) {
|
|
35101
35754
|
throw new KgOverlayError(`Overlay creation produced no ${overlayPath} after cp \u2014 filesystem returned without error?`);
|
|
35102
35755
|
}
|
|
35103
35756
|
const gitignoreAction = ensureGitignoreEntry(opts.worldClonePath);
|
|
@@ -35111,9 +35764,9 @@ function createWorldOverlay(opts) {
|
|
|
35111
35764
|
|
|
35112
35765
|
// ../core/dist/world/baseline-diff.js
|
|
35113
35766
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
35114
|
-
import * as
|
|
35767
|
+
import * as fs39 from "node:fs";
|
|
35115
35768
|
import * as os23 from "node:os";
|
|
35116
|
-
import * as
|
|
35769
|
+
import * as path38 from "node:path";
|
|
35117
35770
|
var DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
35118
35771
|
function expandHome2(p, homedir28) {
|
|
35119
35772
|
return p.replace(/^~(?=$|\/|\\)/, homedir28());
|
|
@@ -35140,9 +35793,9 @@ ${stderr}`;
|
|
|
35140
35793
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
35141
35794
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync6(cmd, args, opts));
|
|
35142
35795
|
const homedir28 = deps.homedir ?? (() => os23.homedir());
|
|
35143
|
-
const baselineDir =
|
|
35796
|
+
const baselineDir = path38.join(workspacePath, ".olam", "baseline");
|
|
35144
35797
|
try {
|
|
35145
|
-
|
|
35798
|
+
fs39.mkdirSync(baselineDir, { recursive: true });
|
|
35146
35799
|
} catch (err) {
|
|
35147
35800
|
const msg = err instanceof Error ? err.message : String(err);
|
|
35148
35801
|
console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
|
|
@@ -35154,9 +35807,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
35154
35807
|
if (!repo.path)
|
|
35155
35808
|
continue;
|
|
35156
35809
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
35157
|
-
const outPath =
|
|
35810
|
+
const outPath = path38.join(baselineDir, filename);
|
|
35158
35811
|
const repoPath = expandHome2(repo.path, homedir28);
|
|
35159
|
-
if (!
|
|
35812
|
+
if (!fs39.existsSync(repoPath)) {
|
|
35160
35813
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
35161
35814
|
# (skipped: path ${repoPath} does not exist)
|
|
35162
35815
|
`);
|
|
@@ -35223,7 +35876,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
35223
35876
|
}
|
|
35224
35877
|
function writeBaselineFile(outPath, content) {
|
|
35225
35878
|
try {
|
|
35226
|
-
|
|
35879
|
+
fs39.writeFileSync(outPath, content);
|
|
35227
35880
|
} catch (err) {
|
|
35228
35881
|
const msg = err instanceof Error ? err.message : String(err);
|
|
35229
35882
|
console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
|
|
@@ -35231,8 +35884,8 @@ function writeBaselineFile(outPath, content) {
|
|
|
35231
35884
|
}
|
|
35232
35885
|
function stripWorktreeEdits(repos, workspacePath) {
|
|
35233
35886
|
for (const repo of repos) {
|
|
35234
|
-
const worktreePath =
|
|
35235
|
-
if (!
|
|
35887
|
+
const worktreePath = path38.join(workspacePath, repo.name);
|
|
35888
|
+
if (!fs39.existsSync(worktreePath))
|
|
35236
35889
|
continue;
|
|
35237
35890
|
try {
|
|
35238
35891
|
execFileSync6("git", ["checkout", "--", "."], {
|
|
@@ -35292,20 +35945,20 @@ function extractStderr(err) {
|
|
|
35292
35945
|
function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
35293
35946
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync6(cmd, args, opts));
|
|
35294
35947
|
const homedir28 = deps.homedir ?? (() => os23.homedir());
|
|
35295
|
-
const
|
|
35296
|
-
const copyFileSync9 = deps.copyFileSync ?? ((src, dest) =>
|
|
35297
|
-
const
|
|
35298
|
-
|
|
35948
|
+
const existsSync46 = deps.existsSync ?? ((p) => fs39.existsSync(p));
|
|
35949
|
+
const copyFileSync9 = deps.copyFileSync ?? ((src, dest) => fs39.copyFileSync(src, dest));
|
|
35950
|
+
const mkdirSync29 = deps.mkdirSync ?? ((dirPath, opts) => {
|
|
35951
|
+
fs39.mkdirSync(dirPath, opts);
|
|
35299
35952
|
});
|
|
35300
35953
|
const plans = [];
|
|
35301
35954
|
for (const repo of repos) {
|
|
35302
35955
|
if (!repo.path)
|
|
35303
35956
|
continue;
|
|
35304
35957
|
const repoPath = expandHome2(repo.path, homedir28);
|
|
35305
|
-
const worktreePath =
|
|
35306
|
-
if (!
|
|
35958
|
+
const worktreePath = path38.join(workspacePath, repo.name);
|
|
35959
|
+
if (!existsSync46(repoPath))
|
|
35307
35960
|
continue;
|
|
35308
|
-
if (!
|
|
35961
|
+
if (!existsSync46(worktreePath)) {
|
|
35309
35962
|
console.warn(`[carry] ${repo.name}: world worktree ${worktreePath} missing; skipping carry for this repo`);
|
|
35310
35963
|
continue;
|
|
35311
35964
|
}
|
|
@@ -35363,12 +36016,12 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
35363
36016
|
}
|
|
35364
36017
|
}
|
|
35365
36018
|
for (const rel of plan.diff.untracked) {
|
|
35366
|
-
const src =
|
|
35367
|
-
const dest =
|
|
35368
|
-
if (!
|
|
36019
|
+
const src = path38.join(plan.repoPath, rel);
|
|
36020
|
+
const dest = path38.join(plan.worktreePath, rel);
|
|
36021
|
+
if (!existsSync46(src))
|
|
35369
36022
|
continue;
|
|
35370
36023
|
try {
|
|
35371
|
-
|
|
36024
|
+
mkdirSync29(path38.dirname(dest), { recursive: true });
|
|
35372
36025
|
copyFileSync9(src, dest);
|
|
35373
36026
|
} catch (err) {
|
|
35374
36027
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -35394,8 +36047,8 @@ function formatBaselineSummary(result) {
|
|
|
35394
36047
|
}
|
|
35395
36048
|
|
|
35396
36049
|
// ../core/dist/world/context-injection.js
|
|
35397
|
-
import * as
|
|
35398
|
-
import * as
|
|
36050
|
+
import * as fs40 from "node:fs";
|
|
36051
|
+
import * as path39 from "node:path";
|
|
35399
36052
|
|
|
35400
36053
|
// ../core/dist/world/templates/_generated.js
|
|
35401
36054
|
var GH_PR_CREATE = '# Creating PRs from inside an Olam world\n\n## The problem\n\nCalling `gh pr create` directly inside an Olam container **hangs forever** on a\nTTY confirmation prompt that the agent cannot answer. This is a known, reproduced issue.\n\n## The fix\n\nAlways use this exact pattern:\n\n```bash\necho y | timeout 30 gh pr create \\\n --base main \\\n --head <branch> \\\n --title "<title>" \\\n --body-file /tmp/pr-body.md\n```\n\n## Why each part matters\n\n- **`echo y |`** \u2014 answers the "Submit?" confirmation prompt up front so `gh` never pauses.\n- **`timeout 30`** \u2014 hard deadline. If `gh` hangs anyway, the command exits non-zero so the\n agent can react instead of stalling the world indefinitely.\n- **`--body-file /tmp/pr-body.md`** \u2014 write the PR body to a temp file first. Avoids\n shell-escaping bugs that occur with `--body "..."` for long or multi-line bodies.\n- **`--head` and `--base` explicitly** \u2014 removes all interactive prompts; `gh` has nothing to ask.\n\n## Troubleshooting\n\n**"no commits" or "branch not found" error:**\n\n```bash\ngit push -u origin <branch>\n# then retry:\necho y | timeout 30 gh pr create --base main --head <branch> --title "..." --body-file /tmp/pr-body.md\n```\n\n**Timeout exceeded (command exits 124):**\n\n- Check if the branch was pushed: `git log origin/<branch> --oneline -1`\n- Check GitHub CLI auth: `gh auth status`\n- Retry once; if it hangs again, open the PR via the GitHub web UI.\n';
|
|
@@ -35405,10 +36058,10 @@ var WORLD_CLAUDE_MD = '# Olam World: {{worldName}}\n\n{{taskBlock}}\n\n## Enviro
|
|
|
35405
36058
|
// ../core/dist/world/context-injection.js
|
|
35406
36059
|
function injectWorldContext(opts) {
|
|
35407
36060
|
const { world } = opts;
|
|
35408
|
-
const claudeDir2 =
|
|
35409
|
-
|
|
36061
|
+
const claudeDir2 = path39.join(world.workspacePath, ".claude");
|
|
36062
|
+
fs40.mkdirSync(claudeDir2, { recursive: true });
|
|
35410
36063
|
const content = WORLD_CLAUDE_MD.replace("{{worldName}}", world.name).replace("{{worldId}}", world.id).replace("{{branch}}", world.branch).replace("{{taskBlock}}", buildTaskBlock(opts)).replace("{{reposList}}", buildReposList(world)).replace("{{servicesLine}}", buildServicesLine(opts.services)).replace("{{pleriPlaneLine}}", buildPleriPlaneLine(opts.pleriPlaneUrl)).replace("{{planFileBlock}}", buildPlanFileBlock(world)).replace("{{extraContextBlock}}", buildExtraContextBlock(opts.claudeMdExtra));
|
|
35411
|
-
|
|
36064
|
+
fs40.writeFileSync(path39.join(claudeDir2, "CLAUDE.md"), content);
|
|
35412
36065
|
writeOlamDocs(world.workspacePath);
|
|
35413
36066
|
}
|
|
35414
36067
|
function buildTaskBlock(opts) {
|
|
@@ -35482,10 +36135,10 @@ function buildExtraContextBlock(extra) {
|
|
|
35482
36135
|
${extra}`;
|
|
35483
36136
|
}
|
|
35484
36137
|
function writeOlamDocs(workspacePath) {
|
|
35485
|
-
const docsDir =
|
|
35486
|
-
|
|
35487
|
-
|
|
35488
|
-
|
|
36138
|
+
const docsDir = path39.join(workspacePath, ".olam", "docs");
|
|
36139
|
+
fs40.mkdirSync(docsDir, { recursive: true });
|
|
36140
|
+
fs40.writeFileSync(path39.join(docsDir, "gh-pr-create.md"), GH_PR_CREATE);
|
|
36141
|
+
fs40.writeFileSync(path39.join(docsDir, "lane-orchestration.md"), LANE_ORCHESTRATION);
|
|
35489
36142
|
}
|
|
35490
36143
|
function formatTaskSource(ctx) {
|
|
35491
36144
|
if (ctx.source === "linear" && ctx.ticketId) {
|
|
@@ -35499,9 +36152,9 @@ function formatTaskSource(ctx) {
|
|
|
35499
36152
|
function hasPlanFile(world) {
|
|
35500
36153
|
if (world.repos.length === 0)
|
|
35501
36154
|
return false;
|
|
35502
|
-
const plansDir =
|
|
36155
|
+
const plansDir = path39.join(world.workspacePath, world.repos[0], "docs", "plans");
|
|
35503
36156
|
try {
|
|
35504
|
-
return
|
|
36157
|
+
return fs40.existsSync(plansDir) && fs40.readdirSync(plansDir).length > 0;
|
|
35505
36158
|
} catch {
|
|
35506
36159
|
return false;
|
|
35507
36160
|
}
|
|
@@ -36073,25 +36726,25 @@ init_repo_manifest();
|
|
|
36073
36726
|
|
|
36074
36727
|
// ../core/dist/world/snapshot.js
|
|
36075
36728
|
import * as crypto7 from "node:crypto";
|
|
36076
|
-
import * as
|
|
36729
|
+
import * as fs41 from "node:fs";
|
|
36077
36730
|
import * as os24 from "node:os";
|
|
36078
|
-
import * as
|
|
36731
|
+
import * as path40 from "node:path";
|
|
36079
36732
|
import { execFileSync as execFileSync7, spawn as spawn2 } from "node:child_process";
|
|
36080
36733
|
import { gunzipSync } from "node:zlib";
|
|
36081
36734
|
function snapshotsDir() {
|
|
36082
|
-
return process.env["OLAM_SNAPSHOTS_DIR"] ??
|
|
36735
|
+
return process.env["OLAM_SNAPSHOTS_DIR"] ?? path40.join(os24.homedir(), ".olam", "snapshots");
|
|
36083
36736
|
}
|
|
36084
36737
|
function snapshotKindDirByWorkspace(workspace, arch, kind) {
|
|
36085
|
-
return
|
|
36738
|
+
return path40.join(snapshotsDir(), "by-workspace", workspace, arch, kind);
|
|
36086
36739
|
}
|
|
36087
36740
|
function cleanupLegacyByWorldDir(worldId) {
|
|
36088
|
-
const legacyDir =
|
|
36741
|
+
const legacyDir = path40.join(snapshotsDir(), worldId);
|
|
36089
36742
|
if (worldId === "by-workspace")
|
|
36090
36743
|
return;
|
|
36091
|
-
if (!
|
|
36744
|
+
if (!fs41.existsSync(legacyDir))
|
|
36092
36745
|
return;
|
|
36093
36746
|
try {
|
|
36094
|
-
|
|
36747
|
+
fs41.rmSync(legacyDir, { recursive: true, force: true });
|
|
36095
36748
|
} catch {
|
|
36096
36749
|
}
|
|
36097
36750
|
}
|
|
@@ -36110,11 +36763,11 @@ function hashBuffers(entries) {
|
|
|
36110
36763
|
return hash.digest("hex").slice(0, 12);
|
|
36111
36764
|
}
|
|
36112
36765
|
function computeGemsFingerprint(repoDir, imageDigest) {
|
|
36113
|
-
const lockfile =
|
|
36114
|
-
if (!
|
|
36766
|
+
const lockfile = path40.join(repoDir, "Gemfile.lock");
|
|
36767
|
+
if (!fs41.existsSync(lockfile))
|
|
36115
36768
|
return null;
|
|
36116
36769
|
const entries = [
|
|
36117
|
-
{ path: "Gemfile.lock", content:
|
|
36770
|
+
{ path: "Gemfile.lock", content: fs41.readFileSync(lockfile) }
|
|
36118
36771
|
];
|
|
36119
36772
|
if (imageDigest) {
|
|
36120
36773
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -36124,10 +36777,10 @@ function computeGemsFingerprint(repoDir, imageDigest) {
|
|
|
36124
36777
|
function computeNodeFingerprint(repoDir, imageDigest) {
|
|
36125
36778
|
const candidates = ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"];
|
|
36126
36779
|
for (const name of candidates) {
|
|
36127
|
-
const lockfile =
|
|
36128
|
-
if (
|
|
36780
|
+
const lockfile = path40.join(repoDir, name);
|
|
36781
|
+
if (fs41.existsSync(lockfile)) {
|
|
36129
36782
|
const entries = [
|
|
36130
|
-
{ path: name, content:
|
|
36783
|
+
{ path: name, content: fs41.readFileSync(lockfile) }
|
|
36131
36784
|
];
|
|
36132
36785
|
if (imageDigest) {
|
|
36133
36786
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -36146,18 +36799,18 @@ function unpackTarballAtomic(srcPath, destDir) {
|
|
|
36146
36799
|
detail: validation.detail ?? `unsafe entry: ${validation.unsafePath}`
|
|
36147
36800
|
};
|
|
36148
36801
|
}
|
|
36149
|
-
const parent =
|
|
36150
|
-
|
|
36802
|
+
const parent = path40.dirname(destDir);
|
|
36803
|
+
fs41.mkdirSync(parent, { recursive: true });
|
|
36151
36804
|
const tmpSuffix = `.tmp-${process.pid}-${crypto7.randomBytes(4).toString("hex")}`;
|
|
36152
36805
|
const tmpDir = `${destDir}${tmpSuffix}`;
|
|
36153
36806
|
try {
|
|
36154
|
-
|
|
36807
|
+
fs41.mkdirSync(tmpDir, { recursive: true });
|
|
36155
36808
|
execFileSync7("tar", ["-xzf", srcPath, "-C", tmpDir], { stdio: "pipe" });
|
|
36156
|
-
|
|
36809
|
+
fs41.renameSync(tmpDir, destDir);
|
|
36157
36810
|
return { ok: true, entryCount: validation.entries.length };
|
|
36158
36811
|
} catch (err) {
|
|
36159
36812
|
try {
|
|
36160
|
-
|
|
36813
|
+
fs41.rmSync(tmpDir, { recursive: true, force: true });
|
|
36161
36814
|
} catch {
|
|
36162
36815
|
}
|
|
36163
36816
|
return {
|
|
@@ -36168,12 +36821,12 @@ function unpackTarballAtomic(srcPath, destDir) {
|
|
|
36168
36821
|
}
|
|
36169
36822
|
}
|
|
36170
36823
|
function resolvesWithin(base, target) {
|
|
36171
|
-
const resolved =
|
|
36172
|
-
const baseResolved =
|
|
36173
|
-
const rel =
|
|
36824
|
+
const resolved = path40.resolve(base, target);
|
|
36825
|
+
const baseResolved = path40.resolve(base);
|
|
36826
|
+
const rel = path40.relative(baseResolved, resolved);
|
|
36174
36827
|
if (rel === "")
|
|
36175
36828
|
return true;
|
|
36176
|
-
return !rel.startsWith("..") && !
|
|
36829
|
+
return !rel.startsWith("..") && !path40.isAbsolute(rel);
|
|
36177
36830
|
}
|
|
36178
36831
|
var TYPE_CHAR_TO_TYPE = {
|
|
36179
36832
|
"-": "file",
|
|
@@ -36223,7 +36876,7 @@ function parseTarListLine(line) {
|
|
|
36223
36876
|
function validateHardlinksBinary(tarPath, targetDir) {
|
|
36224
36877
|
let raw;
|
|
36225
36878
|
try {
|
|
36226
|
-
raw = gunzipSync(
|
|
36879
|
+
raw = gunzipSync(fs41.readFileSync(tarPath));
|
|
36227
36880
|
} catch {
|
|
36228
36881
|
return null;
|
|
36229
36882
|
}
|
|
@@ -36238,7 +36891,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
|
|
|
36238
36891
|
const name = block.subarray(0, nameNull >= 0 && nameNull <= 99 ? nameNull : 100).toString("utf-8");
|
|
36239
36892
|
const linkNull = block.indexOf(0, 157);
|
|
36240
36893
|
const linkname = block.subarray(157, linkNull >= 157 && linkNull <= 256 ? linkNull : 257).toString("utf-8");
|
|
36241
|
-
if (linkname && (
|
|
36894
|
+
if (linkname && (path40.isAbsolute(linkname) || !resolvesWithin(targetDir, linkname))) {
|
|
36242
36895
|
return {
|
|
36243
36896
|
valid: false,
|
|
36244
36897
|
reason: "hardlink-escape",
|
|
@@ -36276,7 +36929,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
36276
36929
|
const entry = parseTarListLine(line);
|
|
36277
36930
|
if (!entry)
|
|
36278
36931
|
continue;
|
|
36279
|
-
if (
|
|
36932
|
+
if (path40.isAbsolute(entry.name) || !resolvesWithin(targetDir, entry.name)) {
|
|
36280
36933
|
return {
|
|
36281
36934
|
valid: false,
|
|
36282
36935
|
reason: "path-traversal",
|
|
@@ -36284,8 +36937,8 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
36284
36937
|
};
|
|
36285
36938
|
}
|
|
36286
36939
|
if (entry.type === "symlink" && entry.linkname !== void 0) {
|
|
36287
|
-
const symlinkParent =
|
|
36288
|
-
if (
|
|
36940
|
+
const symlinkParent = path40.join(targetDir, path40.dirname(entry.name));
|
|
36941
|
+
if (path40.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, path40.join(path40.dirname(entry.name), entry.linkname))) {
|
|
36289
36942
|
return {
|
|
36290
36943
|
valid: false,
|
|
36291
36944
|
reason: "symlink-escape",
|
|
@@ -36295,7 +36948,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
36295
36948
|
}
|
|
36296
36949
|
}
|
|
36297
36950
|
if (entry.type === "hardlink" && entry.linkname !== void 0) {
|
|
36298
|
-
if (
|
|
36951
|
+
if (path40.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, entry.linkname)) {
|
|
36299
36952
|
return {
|
|
36300
36953
|
valid: false,
|
|
36301
36954
|
reason: "hardlink-escape",
|
|
@@ -36328,8 +36981,8 @@ function restoreSnapshotsForRepos(input) {
|
|
|
36328
36981
|
}
|
|
36329
36982
|
const archDir = snapshotKindDirByWorkspace(input.workspace, input.arch, kind);
|
|
36330
36983
|
const tarFilename = `${repo.name}-${input.arch}-${fingerprint}.tar.gz`;
|
|
36331
|
-
const tarPath =
|
|
36332
|
-
if (!
|
|
36984
|
+
const tarPath = path40.join(archDir, tarFilename);
|
|
36985
|
+
if (!fs41.existsSync(tarPath)) {
|
|
36333
36986
|
outcomes.push({ repo: repo.name, kind, outcome: "miss", reason: "no-tarball", fingerprint });
|
|
36334
36987
|
continue;
|
|
36335
36988
|
}
|
|
@@ -36344,9 +36997,9 @@ function restoreSnapshotsForRepos(input) {
|
|
|
36344
36997
|
});
|
|
36345
36998
|
continue;
|
|
36346
36999
|
}
|
|
36347
|
-
const targetDir =
|
|
37000
|
+
const targetDir = path40.join(repo.worktreeDir, targetSubpath);
|
|
36348
37001
|
try {
|
|
36349
|
-
|
|
37002
|
+
fs41.rmSync(targetDir, { recursive: true, force: true });
|
|
36350
37003
|
} catch {
|
|
36351
37004
|
}
|
|
36352
37005
|
const result = unpackTarballAtomic(tarPath, targetDir);
|
|
@@ -36359,8 +37012,8 @@ function restoreSnapshotsForRepos(input) {
|
|
|
36359
37012
|
fingerprint
|
|
36360
37013
|
});
|
|
36361
37014
|
try {
|
|
36362
|
-
|
|
36363
|
-
|
|
37015
|
+
fs41.rmSync(tarPath, { force: true });
|
|
37016
|
+
fs41.rmSync(manifestPath(tarPath), { force: true });
|
|
36364
37017
|
} catch {
|
|
36365
37018
|
}
|
|
36366
37019
|
continue;
|
|
@@ -36376,10 +37029,10 @@ function restoreSnapshotsForRepos(input) {
|
|
|
36376
37029
|
}
|
|
36377
37030
|
function readManifest(tarPath) {
|
|
36378
37031
|
const mPath = manifestPath(tarPath);
|
|
36379
|
-
if (!
|
|
37032
|
+
if (!fs41.existsSync(mPath))
|
|
36380
37033
|
return null;
|
|
36381
37034
|
try {
|
|
36382
|
-
return JSON.parse(
|
|
37035
|
+
return JSON.parse(fs41.readFileSync(mPath, "utf-8"));
|
|
36383
37036
|
} catch {
|
|
36384
37037
|
return null;
|
|
36385
37038
|
}
|
|
@@ -36394,17 +37047,17 @@ function isPidAlive(pid) {
|
|
|
36394
37047
|
}
|
|
36395
37048
|
}
|
|
36396
37049
|
function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
36397
|
-
|
|
36398
|
-
const lockPath =
|
|
37050
|
+
fs41.mkdirSync(dir, { recursive: true });
|
|
37051
|
+
const lockPath = path40.join(dir, EVICT_LOCK_FILENAME);
|
|
36399
37052
|
let fd;
|
|
36400
37053
|
try {
|
|
36401
|
-
fd =
|
|
37054
|
+
fd = fs41.openSync(lockPath, fs41.constants.O_WRONLY | fs41.constants.O_CREAT | fs41.constants.O_EXCL, 384);
|
|
36402
37055
|
} catch (err) {
|
|
36403
37056
|
if (err.code !== "EEXIST")
|
|
36404
37057
|
return 0;
|
|
36405
37058
|
let holderPid = null;
|
|
36406
37059
|
try {
|
|
36407
|
-
holderPid = parseInt(
|
|
37060
|
+
holderPid = parseInt(fs41.readFileSync(lockPath, "utf-8").trim(), 10);
|
|
36408
37061
|
} catch {
|
|
36409
37062
|
holderPid = null;
|
|
36410
37063
|
}
|
|
@@ -36412,23 +37065,23 @@ function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
|
36412
37065
|
return 0;
|
|
36413
37066
|
}
|
|
36414
37067
|
try {
|
|
36415
|
-
|
|
36416
|
-
fd =
|
|
37068
|
+
fs41.unlinkSync(lockPath);
|
|
37069
|
+
fd = fs41.openSync(lockPath, fs41.constants.O_WRONLY | fs41.constants.O_CREAT | fs41.constants.O_EXCL, 384);
|
|
36417
37070
|
} catch {
|
|
36418
37071
|
return 0;
|
|
36419
37072
|
}
|
|
36420
37073
|
}
|
|
36421
37074
|
try {
|
|
36422
|
-
|
|
37075
|
+
fs41.writeSync(fd, `${process.pid}
|
|
36423
37076
|
`);
|
|
36424
37077
|
} finally {
|
|
36425
|
-
|
|
37078
|
+
fs41.closeSync(fd);
|
|
36426
37079
|
}
|
|
36427
37080
|
try {
|
|
36428
37081
|
return evictOldSnapshots(maxBytes, dir);
|
|
36429
37082
|
} finally {
|
|
36430
37083
|
try {
|
|
36431
|
-
|
|
37084
|
+
fs41.unlinkSync(lockPath);
|
|
36432
37085
|
} catch {
|
|
36433
37086
|
}
|
|
36434
37087
|
}
|
|
@@ -36461,16 +37114,16 @@ function spawnAutoCapture(worldId, olamBin = "olam") {
|
|
|
36461
37114
|
}
|
|
36462
37115
|
}
|
|
36463
37116
|
function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
36464
|
-
if (!
|
|
37117
|
+
if (!fs41.existsSync(dir))
|
|
36465
37118
|
return 0;
|
|
36466
37119
|
const allTars = [];
|
|
36467
37120
|
const walk = (d) => {
|
|
36468
|
-
for (const entry of
|
|
36469
|
-
const full =
|
|
37121
|
+
for (const entry of fs41.readdirSync(d, { withFileTypes: true })) {
|
|
37122
|
+
const full = path40.join(d, entry.name);
|
|
36470
37123
|
if (entry.isDirectory()) {
|
|
36471
37124
|
walk(full);
|
|
36472
37125
|
} else if (entry.name.endsWith(".tar.gz")) {
|
|
36473
|
-
const stat =
|
|
37126
|
+
const stat = fs41.statSync(full);
|
|
36474
37127
|
allTars.push({ path: full, size: stat.size, mtime: stat.mtimeMs });
|
|
36475
37128
|
}
|
|
36476
37129
|
}
|
|
@@ -36485,8 +37138,8 @@ function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
|
36485
37138
|
for (const tar of allTars) {
|
|
36486
37139
|
if (remaining <= maxBytes)
|
|
36487
37140
|
break;
|
|
36488
|
-
|
|
36489
|
-
|
|
37141
|
+
fs41.rmSync(tar.path, { force: true });
|
|
37142
|
+
fs41.rmSync(manifestPath(tar.path), { force: true });
|
|
36490
37143
|
freed += tar.size;
|
|
36491
37144
|
remaining -= tar.size;
|
|
36492
37145
|
}
|
|
@@ -36603,14 +37256,14 @@ function gcloudAvailable(execFn = defaultExecFn) {
|
|
|
36603
37256
|
|
|
36604
37257
|
// ../core/dist/world/olam-yaml.js
|
|
36605
37258
|
init_repo_manifest();
|
|
36606
|
-
import * as
|
|
37259
|
+
import * as path41 from "node:path";
|
|
36607
37260
|
import YAML2 from "yaml";
|
|
36608
37261
|
function enrichReposWithManifests(repos, workspacePath) {
|
|
36609
37262
|
return repos.map((repo) => {
|
|
36610
37263
|
if (repo.manifest !== void 0 && repo.manifest !== null) {
|
|
36611
37264
|
return repo;
|
|
36612
37265
|
}
|
|
36613
|
-
const repoDir =
|
|
37266
|
+
const repoDir = path41.join(workspacePath, repo.name);
|
|
36614
37267
|
let manifest = null;
|
|
36615
37268
|
try {
|
|
36616
37269
|
manifest = loadRepoManifest(repoDir);
|
|
@@ -36625,10 +37278,10 @@ function enrichReposWithManifests(repos, workspacePath) {
|
|
|
36625
37278
|
}
|
|
36626
37279
|
|
|
36627
37280
|
// ../core/dist/policies/loader.js
|
|
36628
|
-
import * as
|
|
36629
|
-
import * as
|
|
37281
|
+
import * as fs42 from "node:fs";
|
|
37282
|
+
import * as path42 from "node:path";
|
|
36630
37283
|
import { parse as parseYaml4 } from "yaml";
|
|
36631
|
-
function
|
|
37284
|
+
function parseFrontmatter2(content) {
|
|
36632
37285
|
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
|
|
36633
37286
|
if (!match)
|
|
36634
37287
|
return null;
|
|
@@ -36646,21 +37299,21 @@ function toStringArray(v) {
|
|
|
36646
37299
|
return v.filter((x) => typeof x === "string");
|
|
36647
37300
|
}
|
|
36648
37301
|
function loadPolicies(workspaceRoot) {
|
|
36649
|
-
const policiesDir =
|
|
36650
|
-
if (!
|
|
37302
|
+
const policiesDir = path42.join(workspaceRoot, ".olam", "policies");
|
|
37303
|
+
if (!fs42.existsSync(policiesDir))
|
|
36651
37304
|
return [];
|
|
36652
37305
|
let files;
|
|
36653
37306
|
try {
|
|
36654
|
-
files =
|
|
37307
|
+
files = fs42.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
|
|
36655
37308
|
} catch {
|
|
36656
37309
|
return [];
|
|
36657
37310
|
}
|
|
36658
37311
|
const policies = [];
|
|
36659
37312
|
for (const file of files) {
|
|
36660
|
-
const filePath =
|
|
37313
|
+
const filePath = path42.join(policiesDir, file);
|
|
36661
37314
|
try {
|
|
36662
|
-
const content =
|
|
36663
|
-
const parsed =
|
|
37315
|
+
const content = fs42.readFileSync(filePath, "utf8");
|
|
37316
|
+
const parsed = parseFrontmatter2(content);
|
|
36664
37317
|
if (!parsed) {
|
|
36665
37318
|
console.warn(`[policies] skipping ${file}: no valid frontmatter block`);
|
|
36666
37319
|
continue;
|
|
@@ -36742,7 +37395,7 @@ var TaskDispatchError = class extends Error {
|
|
|
36742
37395
|
this.name = "TaskDispatchError";
|
|
36743
37396
|
}
|
|
36744
37397
|
};
|
|
36745
|
-
var DEFAULT_SLEEP = (ms) => new Promise((
|
|
37398
|
+
var DEFAULT_SLEEP = (ms) => new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
36746
37399
|
async function probeHealth(containerName, dockerExec, budgetMs, sleep5) {
|
|
36747
37400
|
const deadline = Date.now() + budgetMs;
|
|
36748
37401
|
const cadenceMs = 100;
|
|
@@ -36806,12 +37459,12 @@ init_store();
|
|
|
36806
37459
|
init_bridge();
|
|
36807
37460
|
|
|
36808
37461
|
// ../core/dist/global-config/runbook-resolver.js
|
|
36809
|
-
import * as
|
|
37462
|
+
import * as fs43 from "node:fs";
|
|
36810
37463
|
import * as os25 from "node:os";
|
|
36811
|
-
import * as
|
|
37464
|
+
import * as path43 from "node:path";
|
|
36812
37465
|
function expandTilde(p) {
|
|
36813
37466
|
if (p === "~" || p.startsWith("~/")) {
|
|
36814
|
-
return
|
|
37467
|
+
return path43.join(os25.homedir(), p.slice(1));
|
|
36815
37468
|
}
|
|
36816
37469
|
return p;
|
|
36817
37470
|
}
|
|
@@ -36823,7 +37476,7 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
|
|
|
36823
37476
|
throw new Error(`repo "${repoName}" is referenced by runbook "${runbook.name}" but is not in the registry. Run "olam repos add ${repoName} --path <path>" to register it.`);
|
|
36824
37477
|
}
|
|
36825
37478
|
const resolvedPath = expandTilde(entry.path);
|
|
36826
|
-
if (!
|
|
37479
|
+
if (!fs43.existsSync(resolvedPath)) {
|
|
36827
37480
|
throw new Error(`repo "${repoName}" path "${resolvedPath}" no longer exists. Run "olam repos update ${repoName} --path <new-path>" to fix.`);
|
|
36828
37481
|
}
|
|
36829
37482
|
}
|
|
@@ -36839,19 +37492,19 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
|
|
|
36839
37492
|
init_port_validator();
|
|
36840
37493
|
|
|
36841
37494
|
// ../core/dist/world/bootstrap-hooks.js
|
|
36842
|
-
import * as
|
|
36843
|
-
import * as
|
|
37495
|
+
import * as fs44 from "node:fs";
|
|
37496
|
+
import * as path44 from "node:path";
|
|
36844
37497
|
function runFixtureCopySeeds(seeds, workspacePath) {
|
|
36845
37498
|
if (!seeds)
|
|
36846
37499
|
return;
|
|
36847
37500
|
for (const seed of seeds) {
|
|
36848
37501
|
if (seed.type !== "fixture-copy")
|
|
36849
37502
|
continue;
|
|
36850
|
-
const srcAbs =
|
|
36851
|
-
const destAbs =
|
|
36852
|
-
const destDir =
|
|
36853
|
-
|
|
36854
|
-
|
|
37503
|
+
const srcAbs = path44.resolve(workspacePath, seed.repo, seed.src);
|
|
37504
|
+
const destAbs = path44.resolve(workspacePath, seed.repo, seed.dest);
|
|
37505
|
+
const destDir = path44.dirname(destAbs);
|
|
37506
|
+
fs44.mkdirSync(destDir, { recursive: true });
|
|
37507
|
+
fs44.cpSync(srcAbs, destAbs, { recursive: true, force: true });
|
|
36855
37508
|
}
|
|
36856
37509
|
}
|
|
36857
37510
|
async function runSeedHooks(seeds, containerName, servicePortMap, exec) {
|
|
@@ -37487,7 +38140,7 @@ ${detail}`);
|
|
|
37487
38140
|
runbookSeeds = resolved.seeds;
|
|
37488
38141
|
}
|
|
37489
38142
|
const worldId = generateWorldId();
|
|
37490
|
-
const workspacePath =
|
|
38143
|
+
const workspacePath = path45.join(os26.homedir(), ".olam", "worlds", worldId);
|
|
37491
38144
|
const portOffset = this.registry.getNextPortOffset();
|
|
37492
38145
|
const branch = opts.branchName ?? `olam/${worldId}`;
|
|
37493
38146
|
const repos = this.resolveReposWithWorkspace(opts);
|
|
@@ -37569,37 +38222,37 @@ ${detail}`);
|
|
|
37569
38222
|
if (!repo.path)
|
|
37570
38223
|
continue;
|
|
37571
38224
|
const sourceRoot = repo.path.replace(/^~/, os26.homedir());
|
|
37572
|
-
const worktreeRoot =
|
|
37573
|
-
if (!
|
|
38225
|
+
const worktreeRoot = path45.join(workspacePath, repo.name);
|
|
38226
|
+
if (!fs45.existsSync(sourceRoot) || !fs45.existsSync(worktreeRoot))
|
|
37574
38227
|
continue;
|
|
37575
38228
|
let copied = 0;
|
|
37576
38229
|
for (const pattern of RUNTIME_FILE_PATTERNS) {
|
|
37577
38230
|
const matches2 = [];
|
|
37578
38231
|
if (pattern.includes("*")) {
|
|
37579
|
-
const [dir, glob] = [
|
|
37580
|
-
const sourceDir =
|
|
37581
|
-
if (
|
|
38232
|
+
const [dir, glob] = [path45.dirname(pattern), path45.basename(pattern)];
|
|
38233
|
+
const sourceDir = path45.join(sourceRoot, dir);
|
|
38234
|
+
if (fs45.existsSync(sourceDir)) {
|
|
37582
38235
|
const ext = glob.replace(/^\*+/, "");
|
|
37583
38236
|
try {
|
|
37584
|
-
for (const entry of
|
|
38237
|
+
for (const entry of fs45.readdirSync(sourceDir)) {
|
|
37585
38238
|
if (ext === "" || entry.endsWith(ext))
|
|
37586
|
-
matches2.push(
|
|
38239
|
+
matches2.push(path45.join(dir, entry));
|
|
37587
38240
|
}
|
|
37588
38241
|
} catch {
|
|
37589
38242
|
}
|
|
37590
38243
|
}
|
|
37591
|
-
} else if (
|
|
38244
|
+
} else if (fs45.existsSync(path45.join(sourceRoot, pattern))) {
|
|
37592
38245
|
matches2.push(pattern);
|
|
37593
38246
|
}
|
|
37594
38247
|
for (const rel of matches2) {
|
|
37595
|
-
const src =
|
|
37596
|
-
const dst =
|
|
38248
|
+
const src = path45.join(sourceRoot, rel);
|
|
38249
|
+
const dst = path45.join(worktreeRoot, rel);
|
|
37597
38250
|
try {
|
|
37598
|
-
const st =
|
|
38251
|
+
const st = fs45.statSync(src);
|
|
37599
38252
|
if (!st.isFile())
|
|
37600
38253
|
continue;
|
|
37601
|
-
|
|
37602
|
-
|
|
38254
|
+
fs45.mkdirSync(path45.dirname(dst), { recursive: true });
|
|
38255
|
+
fs45.copyFileSync(src, dst);
|
|
37603
38256
|
copied++;
|
|
37604
38257
|
} catch {
|
|
37605
38258
|
}
|
|
@@ -37685,7 +38338,7 @@ ${detail}`);
|
|
|
37685
38338
|
}
|
|
37686
38339
|
const overlayAttachments = [];
|
|
37687
38340
|
for (const repo of repos) {
|
|
37688
|
-
const worldClonePath =
|
|
38341
|
+
const worldClonePath = path45.join(workspacePath, repo.name);
|
|
37689
38342
|
try {
|
|
37690
38343
|
const result = createWorldOverlay({
|
|
37691
38344
|
workspace: repo.name,
|
|
@@ -37740,7 +38393,7 @@ ${detail}`);
|
|
|
37740
38393
|
try {
|
|
37741
38394
|
const hostExec = makeHostExecFn();
|
|
37742
38395
|
for (const repo of repos) {
|
|
37743
|
-
const repoDir =
|
|
38396
|
+
const repoDir = path45.join(workspacePath, repo.name);
|
|
37744
38397
|
if (repo.stack && Object.keys(repo.stack).length > 0) {
|
|
37745
38398
|
preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
|
|
37746
38399
|
} else {
|
|
@@ -37784,10 +38437,10 @@ ${detail}`);
|
|
|
37784
38437
|
const worldEnv = {};
|
|
37785
38438
|
if (opts.task)
|
|
37786
38439
|
worldEnv.OLAM_TASK = opts.task;
|
|
37787
|
-
const r2CredsPath =
|
|
37788
|
-
if (
|
|
38440
|
+
const r2CredsPath = path45.join(os26.homedir(), ".olam", "r2-credentials.json");
|
|
38441
|
+
if (fs45.existsSync(r2CredsPath)) {
|
|
37789
38442
|
try {
|
|
37790
|
-
const r2Raw =
|
|
38443
|
+
const r2Raw = fs45.readFileSync(r2CredsPath, "utf-8").trim();
|
|
37791
38444
|
if (r2Raw.length > 0) {
|
|
37792
38445
|
const r2 = JSON.parse(r2Raw);
|
|
37793
38446
|
if (typeof r2.account_id === "string")
|
|
@@ -37804,10 +38457,10 @@ ${detail}`);
|
|
|
37804
38457
|
} catch {
|
|
37805
38458
|
}
|
|
37806
38459
|
}
|
|
37807
|
-
const keysYamlPath =
|
|
37808
|
-
if (
|
|
38460
|
+
const keysYamlPath = path45.join(os26.homedir(), ".olam", "keys.yaml");
|
|
38461
|
+
if (fs45.existsSync(keysYamlPath)) {
|
|
37809
38462
|
try {
|
|
37810
|
-
const keysRaw =
|
|
38463
|
+
const keysRaw = fs45.readFileSync(keysYamlPath, "utf-8").trim();
|
|
37811
38464
|
if (keysRaw.length > 0) {
|
|
37812
38465
|
const parsed = YAML3.parse(keysRaw);
|
|
37813
38466
|
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
@@ -37866,10 +38519,10 @@ ${detail}`);
|
|
|
37866
38519
|
worldEnv[k] = v;
|
|
37867
38520
|
}
|
|
37868
38521
|
for (const { repoName, relativePath, content } of fileWrites) {
|
|
37869
|
-
const absPath =
|
|
38522
|
+
const absPath = path45.join(workspacePath, repoName, relativePath);
|
|
37870
38523
|
try {
|
|
37871
|
-
|
|
37872
|
-
|
|
38524
|
+
fs45.mkdirSync(path45.dirname(absPath), { recursive: true });
|
|
38525
|
+
fs45.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
|
|
37873
38526
|
mode: 384
|
|
37874
38527
|
});
|
|
37875
38528
|
console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
|
|
@@ -38046,7 +38699,7 @@ ${detail}`);
|
|
|
38046
38699
|
imageDigest: void 0,
|
|
38047
38700
|
repos: enrichedRepos.map((r) => ({
|
|
38048
38701
|
name: r.name,
|
|
38049
|
-
worktreeDir:
|
|
38702
|
+
worktreeDir: path45.join(workspacePath, r.name)
|
|
38050
38703
|
}))
|
|
38051
38704
|
});
|
|
38052
38705
|
for (const out of restoreResult.outcomes) {
|
|
@@ -38152,7 +38805,7 @@ ${detail}`);
|
|
|
38152
38805
|
}
|
|
38153
38806
|
if (opts.task) {
|
|
38154
38807
|
const allPolicies = repos.flatMap((repo) => {
|
|
38155
|
-
const repoWorktree =
|
|
38808
|
+
const repoWorktree = path45.join(workspacePath, repo.name);
|
|
38156
38809
|
try {
|
|
38157
38810
|
return loadPolicies(repoWorktree);
|
|
38158
38811
|
} catch (err) {
|
|
@@ -38165,8 +38818,8 @@ ${detail}`);
|
|
|
38165
38818
|
try {
|
|
38166
38819
|
execSync5(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
|
|
38167
38820
|
for (const repo of repos) {
|
|
38168
|
-
const policiesDir =
|
|
38169
|
-
if (
|
|
38821
|
+
const policiesDir = path45.join(workspacePath, repo.name, ".olam", "policies");
|
|
38822
|
+
if (fs45.existsSync(policiesDir)) {
|
|
38170
38823
|
execSync5(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
|
|
38171
38824
|
}
|
|
38172
38825
|
}
|
|
@@ -38274,8 +38927,8 @@ ${detail}`);
|
|
|
38274
38927
|
} catch {
|
|
38275
38928
|
}
|
|
38276
38929
|
try {
|
|
38277
|
-
|
|
38278
|
-
if (
|
|
38930
|
+
fs45.rmSync(world.workspacePath, { recursive: true, force: true });
|
|
38931
|
+
if (fs45.existsSync(world.workspacePath)) {
|
|
38279
38932
|
console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
|
|
38280
38933
|
}
|
|
38281
38934
|
} catch (err) {
|
|
@@ -38384,14 +39037,14 @@ ${detail}`);
|
|
|
38384
39037
|
}).filter((r) => r !== void 0);
|
|
38385
39038
|
}
|
|
38386
39039
|
transportPlanFile(planFilePath, workspacePath, repoNames) {
|
|
38387
|
-
const planContent =
|
|
38388
|
-
const planFileName =
|
|
39040
|
+
const planContent = fs45.readFileSync(planFilePath, "utf-8");
|
|
39041
|
+
const planFileName = path45.basename(planFilePath);
|
|
38389
39042
|
const targetRepo = repoNames[0];
|
|
38390
39043
|
if (!targetRepo)
|
|
38391
39044
|
return;
|
|
38392
|
-
const plansDir =
|
|
38393
|
-
|
|
38394
|
-
|
|
39045
|
+
const plansDir = path45.join(workspacePath, targetRepo, "docs", "plans");
|
|
39046
|
+
fs45.mkdirSync(plansDir, { recursive: true });
|
|
39047
|
+
fs45.writeFileSync(path45.join(plansDir, planFileName), planContent);
|
|
38395
39048
|
}
|
|
38396
39049
|
resolveServices(repos) {
|
|
38397
39050
|
const services = [];
|
|
@@ -38825,8 +39478,8 @@ import * as http2 from "node:http";
|
|
|
38825
39478
|
|
|
38826
39479
|
// ../core/dist/dashboard/server.js
|
|
38827
39480
|
import * as http from "node:http";
|
|
38828
|
-
import * as
|
|
38829
|
-
import * as
|
|
39481
|
+
import * as fs46 from "node:fs";
|
|
39482
|
+
import * as path46 from "node:path";
|
|
38830
39483
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
38831
39484
|
|
|
38832
39485
|
// ../core/dist/dashboard/serialize.js
|
|
@@ -39161,7 +39814,7 @@ function notFound(res) {
|
|
|
39161
39814
|
}
|
|
39162
39815
|
function openThoughtStore(workspacePath) {
|
|
39163
39816
|
const dbPath = getWorldDbPath(workspacePath);
|
|
39164
|
-
if (!
|
|
39817
|
+
if (!fs46.existsSync(dbPath))
|
|
39165
39818
|
return null;
|
|
39166
39819
|
return new ThoughtLocalStore(dbPath);
|
|
39167
39820
|
}
|
|
@@ -39332,13 +39985,13 @@ function findSessionInWorld(registry2, sessionId) {
|
|
|
39332
39985
|
}
|
|
39333
39986
|
function createDashboardServer(opts) {
|
|
39334
39987
|
const { port: port2, registry: registry2 } = opts;
|
|
39335
|
-
const thisDir =
|
|
39336
|
-
const defaultPublicDir =
|
|
39988
|
+
const thisDir = path46.dirname(fileURLToPath3(import.meta.url));
|
|
39989
|
+
const defaultPublicDir = path46.resolve(thisDir, "../../../control-plane/public");
|
|
39337
39990
|
const publicDir = opts.publicDir ?? defaultPublicDir;
|
|
39338
|
-
let hasPublicDir =
|
|
39991
|
+
let hasPublicDir = fs46.existsSync(publicDir);
|
|
39339
39992
|
const server = http.createServer((req, res) => {
|
|
39340
39993
|
if (!hasPublicDir) {
|
|
39341
|
-
hasPublicDir =
|
|
39994
|
+
hasPublicDir = fs46.existsSync(publicDir);
|
|
39342
39995
|
}
|
|
39343
39996
|
const host = req.headers.host ?? `localhost:${port2}`;
|
|
39344
39997
|
const url2 = new URL(req.url ?? "/", `http://${host}`);
|
|
@@ -39612,22 +40265,22 @@ function createDashboardServer(opts) {
|
|
|
39612
40265
|
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>`);
|
|
39613
40266
|
return;
|
|
39614
40267
|
}
|
|
39615
|
-
let filePath =
|
|
40268
|
+
let filePath = path46.join(publicDir, pathname === "/" ? "index.html" : pathname);
|
|
39616
40269
|
if (!filePath.startsWith(publicDir)) {
|
|
39617
40270
|
notFound(res);
|
|
39618
40271
|
return;
|
|
39619
40272
|
}
|
|
39620
|
-
if (
|
|
39621
|
-
const ext =
|
|
40273
|
+
if (fs46.existsSync(filePath) && fs46.statSync(filePath).isFile()) {
|
|
40274
|
+
const ext = path46.extname(filePath);
|
|
39622
40275
|
const contentType = MIME[ext] ?? "application/octet-stream";
|
|
39623
40276
|
res.writeHead(200, { "Content-Type": contentType });
|
|
39624
|
-
|
|
40277
|
+
fs46.createReadStream(filePath).pipe(res);
|
|
39625
40278
|
return;
|
|
39626
40279
|
}
|
|
39627
|
-
filePath =
|
|
39628
|
-
if (
|
|
40280
|
+
filePath = path46.join(publicDir, "index.html");
|
|
40281
|
+
if (fs46.existsSync(filePath)) {
|
|
39629
40282
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
39630
|
-
|
|
40283
|
+
fs46.createReadStream(filePath).pipe(res);
|
|
39631
40284
|
return;
|
|
39632
40285
|
}
|
|
39633
40286
|
notFound(res);
|
|
@@ -39637,17 +40290,17 @@ function createDashboardServer(opts) {
|
|
|
39637
40290
|
}
|
|
39638
40291
|
|
|
39639
40292
|
// ../core/dist/dashboard/state.js
|
|
39640
|
-
import * as
|
|
40293
|
+
import * as fs47 from "node:fs";
|
|
39641
40294
|
import * as os27 from "node:os";
|
|
39642
|
-
import * as
|
|
39643
|
-
var STATE_PATH =
|
|
40295
|
+
import * as path47 from "node:path";
|
|
40296
|
+
var STATE_PATH = path47.join(os27.homedir(), ".olam", "dashboard.json");
|
|
39644
40297
|
function saveDashboardState(state) {
|
|
39645
|
-
|
|
39646
|
-
|
|
40298
|
+
fs47.mkdirSync(path47.dirname(STATE_PATH), { recursive: true });
|
|
40299
|
+
fs47.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
|
|
39647
40300
|
}
|
|
39648
40301
|
function loadDashboardState() {
|
|
39649
40302
|
try {
|
|
39650
|
-
const raw =
|
|
40303
|
+
const raw = fs47.readFileSync(STATE_PATH, "utf-8");
|
|
39651
40304
|
return JSON.parse(raw);
|
|
39652
40305
|
} catch {
|
|
39653
40306
|
return null;
|
|
@@ -39655,7 +40308,7 @@ function loadDashboardState() {
|
|
|
39655
40308
|
}
|
|
39656
40309
|
function clearDashboardState() {
|
|
39657
40310
|
try {
|
|
39658
|
-
|
|
40311
|
+
fs47.unlinkSync(STATE_PATH);
|
|
39659
40312
|
} catch {
|
|
39660
40313
|
}
|
|
39661
40314
|
}
|
|
@@ -39684,7 +40337,7 @@ function isCloudflaredAvailable() {
|
|
|
39684
40337
|
}
|
|
39685
40338
|
}
|
|
39686
40339
|
function startTunnel(port2) {
|
|
39687
|
-
return new Promise((
|
|
40340
|
+
return new Promise((resolve14, reject2) => {
|
|
39688
40341
|
const child = spawn3("cloudflared", ["tunnel", "--url", `http://localhost:${port2}`], {
|
|
39689
40342
|
stdio: ["ignore", "pipe", "pipe"],
|
|
39690
40343
|
detached: false
|
|
@@ -39706,7 +40359,7 @@ function startTunnel(port2) {
|
|
|
39706
40359
|
if (match) {
|
|
39707
40360
|
resolved = true;
|
|
39708
40361
|
clearTimeout(timeout);
|
|
39709
|
-
|
|
40362
|
+
resolve14(match[0]);
|
|
39710
40363
|
}
|
|
39711
40364
|
}
|
|
39712
40365
|
child.stdout?.on("data", scan);
|
|
@@ -39774,8 +40427,8 @@ var DashboardManager = class {
|
|
|
39774
40427
|
}
|
|
39775
40428
|
throw err;
|
|
39776
40429
|
}
|
|
39777
|
-
await new Promise((
|
|
39778
|
-
this.server.on("listening",
|
|
40430
|
+
await new Promise((resolve14, reject2) => {
|
|
40431
|
+
this.server.on("listening", resolve14);
|
|
39779
40432
|
this.server.on("error", reject2);
|
|
39780
40433
|
});
|
|
39781
40434
|
this.info = { localUrl: `http://localhost:${port2}` };
|
|
@@ -39821,8 +40474,8 @@ var DashboardManager = class {
|
|
|
39821
40474
|
async stop() {
|
|
39822
40475
|
stopTunnel();
|
|
39823
40476
|
if (this.server) {
|
|
39824
|
-
await new Promise((
|
|
39825
|
-
this.server.close(() =>
|
|
40477
|
+
await new Promise((resolve14) => {
|
|
40478
|
+
this.server.close(() => resolve14());
|
|
39826
40479
|
});
|
|
39827
40480
|
this.server = null;
|
|
39828
40481
|
}
|
|
@@ -39935,8 +40588,8 @@ var PleriClient = class {
|
|
|
39935
40588
|
};
|
|
39936
40589
|
|
|
39937
40590
|
// ../mcp-server/src/env-loader.ts
|
|
39938
|
-
import { readFileSync as
|
|
39939
|
-
import { join as
|
|
40591
|
+
import { readFileSync as readFileSync36, existsSync as existsSync45, statSync as statSync14 } from "node:fs";
|
|
40592
|
+
import { join as join48, dirname as dirname28, resolve as resolve13 } from "node:path";
|
|
39940
40593
|
var PROJECT_MARKERS = [
|
|
39941
40594
|
".olam/config.yaml",
|
|
39942
40595
|
".olam/config.yml",
|
|
@@ -39944,16 +40597,16 @@ var PROJECT_MARKERS = [
|
|
|
39944
40597
|
"olam.yml"
|
|
39945
40598
|
];
|
|
39946
40599
|
function findProjectRoot2(startDir) {
|
|
39947
|
-
let dir =
|
|
39948
|
-
const root =
|
|
40600
|
+
let dir = resolve13(startDir);
|
|
40601
|
+
const root = resolve13("/");
|
|
39949
40602
|
while (true) {
|
|
39950
40603
|
for (const marker of PROJECT_MARKERS) {
|
|
39951
|
-
if (
|
|
40604
|
+
if (existsSync45(join48(dir, marker))) return dir;
|
|
39952
40605
|
}
|
|
39953
|
-
const pkg =
|
|
39954
|
-
if (
|
|
40606
|
+
const pkg = join48(dir, "package.json");
|
|
40607
|
+
if (existsSync45(pkg)) {
|
|
39955
40608
|
try {
|
|
39956
|
-
const json = JSON.parse(
|
|
40609
|
+
const json = JSON.parse(readFileSync36(pkg, "utf8"));
|
|
39957
40610
|
const isOlamWorkspace = typeof json.name === "string" && json.name.startsWith("@olam/");
|
|
39958
40611
|
const hasOlamDep = json.dependencies && Object.keys(json.dependencies).some((k) => k.startsWith("@olam/")) || json.devDependencies && Object.keys(json.devDependencies).some((k) => k.startsWith("@olam/"));
|
|
39959
40612
|
if (isOlamWorkspace || hasOlamDep) return dir;
|
|
@@ -39965,9 +40618,9 @@ function findProjectRoot2(startDir) {
|
|
|
39965
40618
|
dir = parent;
|
|
39966
40619
|
}
|
|
39967
40620
|
}
|
|
39968
|
-
function parseEnvFile(
|
|
40621
|
+
function parseEnvFile(path48) {
|
|
39969
40622
|
const out = {};
|
|
39970
|
-
const raw =
|
|
40623
|
+
const raw = readFileSync36(path48, "utf8");
|
|
39971
40624
|
for (const line of raw.split(/\r?\n/)) {
|
|
39972
40625
|
const trimmed = line.trim();
|
|
39973
40626
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -39990,8 +40643,8 @@ function loadProjectEnv(startDir = process.cwd()) {
|
|
|
39990
40643
|
const filesRead = [];
|
|
39991
40644
|
const merged = {};
|
|
39992
40645
|
for (const name of [".env", ".env.local"]) {
|
|
39993
|
-
const p =
|
|
39994
|
-
if (
|
|
40646
|
+
const p = join48(root, name);
|
|
40647
|
+
if (existsSync45(p) && statSync14(p).isFile()) {
|
|
39995
40648
|
Object.assign(merged, parseEnvFile(p));
|
|
39996
40649
|
filesRead.push(p);
|
|
39997
40650
|
}
|