@pleri/olam-cli 0.1.205 → 0.1.207
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/image-digests.json +8 -8
- package/dist/index.js +1886 -1386
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +1100 -795
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- 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/50-deployment.yaml +1 -1
- package/host-cp/src/server.mjs +30 -1
- package/memory-hooks/agentmemory-recall-trigger.mjs +5 -0
- package/memory-hooks/agentmemory-save.mjs +138 -0
- package/memory-hooks/agentmemory-session-recall.js +4 -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: path62, errorMaps, issueData } = params;
|
|
449
|
+
const fullPath = [...path62, ...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, path62, key) {
|
|
758
758
|
this._cachedPath = [];
|
|
759
759
|
this.parent = parent;
|
|
760
760
|
this.data = value;
|
|
761
|
-
this._path =
|
|
761
|
+
this._path = path62;
|
|
762
762
|
this._key = key;
|
|
763
763
|
}
|
|
764
764
|
get path() {
|
|
@@ -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(path62) {
|
|
7336
|
+
let input = path62;
|
|
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 [path62, query] = wsComponent.resourceName.split("?");
|
|
7536
|
+
wsComponent.path = path62 && path62 !== "/" ? path62 : void 0;
|
|
7537
7537
|
wsComponent.query = query;
|
|
7538
7538
|
wsComponent.resourceName = void 0;
|
|
7539
7539
|
}
|
|
@@ -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, fs62, 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, fs62[f]);
|
|
10904
10904
|
}
|
|
10905
10905
|
module.exports = exports = formatsPlugin;
|
|
10906
10906
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -11053,7 +11053,7 @@ import YAML from "yaml";
|
|
|
11053
11053
|
function bootstrapStepCmd(entry) {
|
|
11054
11054
|
return typeof entry === "string" ? entry : entry.cmd;
|
|
11055
11055
|
}
|
|
11056
|
-
function refineForbiddenKeys(value,
|
|
11056
|
+
function refineForbiddenKeys(value, path62, ctx, rejectSource) {
|
|
11057
11057
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
11058
11058
|
return;
|
|
11059
11059
|
}
|
|
@@ -11061,12 +11061,12 @@ function refineForbiddenKeys(value, path60, ctx, rejectSource) {
|
|
|
11061
11061
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
11062
11062
|
ctx.addIssue({
|
|
11063
11063
|
code: external_exports2.ZodIssueCode.custom,
|
|
11064
|
-
path: [...
|
|
11064
|
+
path: [...path62, key],
|
|
11065
11065
|
message: `forbidden key "${key}" (prototype-pollution surface)`
|
|
11066
11066
|
});
|
|
11067
11067
|
continue;
|
|
11068
11068
|
}
|
|
11069
|
-
if (rejectSource &&
|
|
11069
|
+
if (rejectSource && path62.length === 0 && key === "source") {
|
|
11070
11070
|
ctx.addIssue({
|
|
11071
11071
|
code: external_exports2.ZodIssueCode.custom,
|
|
11072
11072
|
path: ["source"],
|
|
@@ -11074,21 +11074,21 @@ function refineForbiddenKeys(value, path60, ctx, rejectSource) {
|
|
|
11074
11074
|
});
|
|
11075
11075
|
continue;
|
|
11076
11076
|
}
|
|
11077
|
-
refineForbiddenKeys(value[key], [...
|
|
11077
|
+
refineForbiddenKeys(value[key], [...path62, key], ctx, false);
|
|
11078
11078
|
}
|
|
11079
11079
|
}
|
|
11080
|
-
function rejectForbiddenKeys(value,
|
|
11080
|
+
function rejectForbiddenKeys(value, path62, rejectSource) {
|
|
11081
11081
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
11082
11082
|
return;
|
|
11083
11083
|
}
|
|
11084
11084
|
for (const key of Object.keys(value)) {
|
|
11085
11085
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
11086
|
-
throw new Error(`[manifest] ${
|
|
11086
|
+
throw new Error(`[manifest] ${path62}: forbidden key "${key}" (prototype-pollution surface)`);
|
|
11087
11087
|
}
|
|
11088
11088
|
if (rejectSource && key === "source") {
|
|
11089
|
-
throw new Error(`[manifest] ${
|
|
11089
|
+
throw new Error(`[manifest] ${path62}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
|
|
11090
11090
|
}
|
|
11091
|
-
rejectForbiddenKeys(value[key], `${
|
|
11091
|
+
rejectForbiddenKeys(value[key], `${path62}.${key}`, false);
|
|
11092
11092
|
}
|
|
11093
11093
|
}
|
|
11094
11094
|
function unknownTopLevelKeys(parsed) {
|
|
@@ -13873,8 +13873,8 @@ var init_provider3 = __esm({
|
|
|
13873
13873
|
// -----------------------------------------------------------------------
|
|
13874
13874
|
// Internal fetch helper
|
|
13875
13875
|
// -----------------------------------------------------------------------
|
|
13876
|
-
async request(
|
|
13877
|
-
const url3 = `${this.config.workerUrl}${
|
|
13876
|
+
async request(path62, method, body) {
|
|
13877
|
+
const url3 = `${this.config.workerUrl}${path62}`;
|
|
13878
13878
|
const bearer = await this.config.mintToken();
|
|
13879
13879
|
const headers = {
|
|
13880
13880
|
Authorization: `Bearer ${bearer}`
|
|
@@ -14283,10 +14283,81 @@ function readGlobalConfig() {
|
|
|
14283
14283
|
}
|
|
14284
14284
|
}
|
|
14285
14285
|
return validated;
|
|
14286
|
-
} catch (
|
|
14287
|
-
|
|
14286
|
+
} catch (strictErr) {
|
|
14287
|
+
const salvaged = quarantineGlobalConfig(migrated.value);
|
|
14288
|
+
if (salvaged !== null) {
|
|
14289
|
+
let backupPath = null;
|
|
14290
|
+
try {
|
|
14291
|
+
backupPath = `${configPath}.quarantine-${Date.now()}`;
|
|
14292
|
+
fs13.copyFileSync(configPath, backupPath);
|
|
14293
|
+
} catch {
|
|
14294
|
+
backupPath = null;
|
|
14295
|
+
}
|
|
14296
|
+
try {
|
|
14297
|
+
writeGlobalConfig(salvaged.value);
|
|
14298
|
+
} catch {
|
|
14299
|
+
}
|
|
14300
|
+
quarantineSink(configPath, { drops: salvaged.drops, backupPath });
|
|
14301
|
+
return salvaged.value;
|
|
14302
|
+
}
|
|
14303
|
+
throw new GlobalConfigReadError(configPath, strictErr);
|
|
14288
14304
|
}
|
|
14289
14305
|
}
|
|
14306
|
+
function quarantineGlobalConfig(migratedValue) {
|
|
14307
|
+
if (migratedValue === null || typeof migratedValue !== "object" || Array.isArray(migratedValue)) {
|
|
14308
|
+
return null;
|
|
14309
|
+
}
|
|
14310
|
+
const obj = migratedValue;
|
|
14311
|
+
const drops = [];
|
|
14312
|
+
const filterField = (field, schema, dedupeKeys) => {
|
|
14313
|
+
const v = obj[field];
|
|
14314
|
+
if (v === void 0)
|
|
14315
|
+
return [];
|
|
14316
|
+
if (!Array.isArray(v)) {
|
|
14317
|
+
drops.push({ field, entry: v, reason: `${field} is not an array` });
|
|
14318
|
+
return [];
|
|
14319
|
+
}
|
|
14320
|
+
const out = [];
|
|
14321
|
+
const seen = dedupeKeys.map(() => /* @__PURE__ */ new Set());
|
|
14322
|
+
for (const e of v) {
|
|
14323
|
+
const r = schema.safeParse(e);
|
|
14324
|
+
if (!r.success || r.data === void 0) {
|
|
14325
|
+
drops.push({ field, entry: e, reason: r.error?.issues[0]?.message ?? "invalid entry" });
|
|
14326
|
+
continue;
|
|
14327
|
+
}
|
|
14328
|
+
let dupeKey = null;
|
|
14329
|
+
for (let i = 0; i < dedupeKeys.length; i++) {
|
|
14330
|
+
const k = dedupeKeys[i](r.data);
|
|
14331
|
+
if (seen[i].has(k)) {
|
|
14332
|
+
dupeKey = k;
|
|
14333
|
+
break;
|
|
14334
|
+
}
|
|
14335
|
+
}
|
|
14336
|
+
if (dupeKey !== null) {
|
|
14337
|
+
drops.push({ field, entry: e, reason: `duplicate key "${dupeKey}"` });
|
|
14338
|
+
continue;
|
|
14339
|
+
}
|
|
14340
|
+
for (let i = 0; i < dedupeKeys.length; i++)
|
|
14341
|
+
seen[i].add(dedupeKeys[i](r.data));
|
|
14342
|
+
out.push(r.data);
|
|
14343
|
+
}
|
|
14344
|
+
return out;
|
|
14345
|
+
};
|
|
14346
|
+
const repos = filterField("repos", RepoEntrySchema, [(r) => r.name]);
|
|
14347
|
+
const runbooks = filterField("runbooks", RunbookSchema, [(r) => r.name]);
|
|
14348
|
+
const skillSources = filterField("skillSources", SkillSourceSchema, [
|
|
14349
|
+
(s) => s.id,
|
|
14350
|
+
(s) => s.name
|
|
14351
|
+
]);
|
|
14352
|
+
const metaHooksDisabled = filterField("metaHooksDisabled", MetaHookBlockKindSchema, [
|
|
14353
|
+
(m) => m
|
|
14354
|
+
]);
|
|
14355
|
+
const candidate = { schemaVersion: 1, repos, runbooks, skillSources, metaHooksDisabled };
|
|
14356
|
+
const final = GlobalConfigSchema.safeParse(candidate);
|
|
14357
|
+
if (!final.success)
|
|
14358
|
+
return null;
|
|
14359
|
+
return { value: final.data, drops };
|
|
14360
|
+
}
|
|
14290
14361
|
function migrateSchemaVersion(parsed) {
|
|
14291
14362
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
14292
14363
|
return { value: parsed, changed: false };
|
|
@@ -14306,11 +14377,26 @@ function writeGlobalConfig(config2) {
|
|
|
14306
14377
|
fs13.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
|
|
14307
14378
|
fs13.renameSync(tmp, configPath);
|
|
14308
14379
|
}
|
|
14309
|
-
var GlobalConfigReadError;
|
|
14380
|
+
var quarantineSink, GlobalConfigReadError;
|
|
14310
14381
|
var init_store2 = __esm({
|
|
14311
14382
|
"../core/dist/global-config/store.js"() {
|
|
14312
14383
|
"use strict";
|
|
14313
14384
|
init_schema4();
|
|
14385
|
+
init_schema3();
|
|
14386
|
+
quarantineSink = (configPath, report) => {
|
|
14387
|
+
if (report.drops.length === 0)
|
|
14388
|
+
return;
|
|
14389
|
+
process.stderr.write(`\x1B[33m\u26A0 global config at ${configPath} had ${report.drops.length} invalid entr${report.drops.length === 1 ? "y" : "ies"} \u2014 quarantined (kept the rest):\x1B[0m
|
|
14390
|
+
`);
|
|
14391
|
+
for (const d of report.drops) {
|
|
14392
|
+
process.stderr.write(` \xB7 ${d.field}: ${d.reason}
|
|
14393
|
+
`);
|
|
14394
|
+
}
|
|
14395
|
+
if (report.backupPath) {
|
|
14396
|
+
process.stderr.write(` \u2192 original backed up to ${report.backupPath}
|
|
14397
|
+
`);
|
|
14398
|
+
}
|
|
14399
|
+
};
|
|
14314
14400
|
GlobalConfigReadError = class extends Error {
|
|
14315
14401
|
constructor(configPath, cause) {
|
|
14316
14402
|
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
@@ -14684,6 +14770,145 @@ var init_trust_audit_log = __esm({
|
|
|
14684
14770
|
}
|
|
14685
14771
|
});
|
|
14686
14772
|
|
|
14773
|
+
// ../core/dist/skill-sources/clone.js
|
|
14774
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
14775
|
+
import * as fs17 from "node:fs";
|
|
14776
|
+
import * as os12 from "node:os";
|
|
14777
|
+
import * as path19 from "node:path";
|
|
14778
|
+
function skillSourcesRootDir() {
|
|
14779
|
+
const override = process.env["OLAM_SKILL_SOURCES_DIR"];
|
|
14780
|
+
if (override && override.length > 0)
|
|
14781
|
+
return override;
|
|
14782
|
+
return path19.join(os12.homedir(), ".olam", "state", "skill-sources");
|
|
14783
|
+
}
|
|
14784
|
+
function skillSourceClonePath(id) {
|
|
14785
|
+
return path19.join(skillSourcesRootDir(), id);
|
|
14786
|
+
}
|
|
14787
|
+
function runGit(args, cwd) {
|
|
14788
|
+
try {
|
|
14789
|
+
return execFileSync2("git", args, {
|
|
14790
|
+
cwd,
|
|
14791
|
+
encoding: "utf-8",
|
|
14792
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
14793
|
+
});
|
|
14794
|
+
} catch (err) {
|
|
14795
|
+
throw err;
|
|
14796
|
+
}
|
|
14797
|
+
}
|
|
14798
|
+
function cloneSkillSource(opts) {
|
|
14799
|
+
const clonePath = skillSourceClonePath(opts.id);
|
|
14800
|
+
if (fs17.existsSync(clonePath)) {
|
|
14801
|
+
throw new Error(`clone path "${clonePath}" already exists. Remove the existing skill-source first.`);
|
|
14802
|
+
}
|
|
14803
|
+
fs17.mkdirSync(skillSourcesRootDir(), { recursive: true });
|
|
14804
|
+
try {
|
|
14805
|
+
runGit(["clone", "--depth", "1", "--branch", opts.branch, opts.gitUrl, clonePath]);
|
|
14806
|
+
} catch (err) {
|
|
14807
|
+
if (fs17.existsSync(clonePath)) {
|
|
14808
|
+
fs17.rmSync(clonePath, { recursive: true, force: true });
|
|
14809
|
+
}
|
|
14810
|
+
throw new SkillSourceGitError("clone", opts.gitUrl, err);
|
|
14811
|
+
}
|
|
14812
|
+
let headSha;
|
|
14813
|
+
try {
|
|
14814
|
+
headSha = runGit(["rev-parse", "HEAD"], clonePath).trim();
|
|
14815
|
+
} catch (err) {
|
|
14816
|
+
throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
|
|
14817
|
+
}
|
|
14818
|
+
return { clonePath, headSha };
|
|
14819
|
+
}
|
|
14820
|
+
function pullSkillSource(opts) {
|
|
14821
|
+
const clonePath = skillSourceClonePath(opts.id);
|
|
14822
|
+
if (!fs17.existsSync(clonePath)) {
|
|
14823
|
+
throw new Error(`clone path "${clonePath}" does not exist. Run "olam skills source add" first.`);
|
|
14824
|
+
}
|
|
14825
|
+
try {
|
|
14826
|
+
runGit(["fetch", "origin", opts.branch], clonePath);
|
|
14827
|
+
runGit(["reset", "--hard", `origin/${opts.branch}`], clonePath);
|
|
14828
|
+
} catch (err) {
|
|
14829
|
+
throw new SkillSourceGitError("fetch/reset", opts.gitUrl, err);
|
|
14830
|
+
}
|
|
14831
|
+
try {
|
|
14832
|
+
const headSha = runGit(["rev-parse", "HEAD"], clonePath).trim();
|
|
14833
|
+
return { headSha };
|
|
14834
|
+
} catch (err) {
|
|
14835
|
+
throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
|
|
14836
|
+
}
|
|
14837
|
+
}
|
|
14838
|
+
function removeSkillSourceClone(id) {
|
|
14839
|
+
const clonePath = skillSourceClonePath(id);
|
|
14840
|
+
if (fs17.existsSync(clonePath)) {
|
|
14841
|
+
fs17.rmSync(clonePath, { recursive: true, force: true });
|
|
14842
|
+
}
|
|
14843
|
+
}
|
|
14844
|
+
var SkillSourceGitError;
|
|
14845
|
+
var init_clone = __esm({
|
|
14846
|
+
"../core/dist/skill-sources/clone.js"() {
|
|
14847
|
+
"use strict";
|
|
14848
|
+
SkillSourceGitError = class extends Error {
|
|
14849
|
+
op;
|
|
14850
|
+
gitUrl;
|
|
14851
|
+
constructor(op, gitUrl, cause) {
|
|
14852
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
14853
|
+
super(`git ${op} failed for "${gitUrl}": ${msg}`);
|
|
14854
|
+
this.op = op;
|
|
14855
|
+
this.gitUrl = gitUrl;
|
|
14856
|
+
this.name = "SkillSourceGitError";
|
|
14857
|
+
this.cause = cause;
|
|
14858
|
+
}
|
|
14859
|
+
};
|
|
14860
|
+
}
|
|
14861
|
+
});
|
|
14862
|
+
|
|
14863
|
+
// ../core/dist/skill-sources/source-file.js
|
|
14864
|
+
import * as fs18 from "node:fs";
|
|
14865
|
+
import * as path20 from "node:path";
|
|
14866
|
+
function sourceSidecarPath(id) {
|
|
14867
|
+
return path20.join(skillSourceClonePath(id), SOURCE_SIDECAR_FILENAME);
|
|
14868
|
+
}
|
|
14869
|
+
function writeSourceSidecar(entry) {
|
|
14870
|
+
const clonePath = skillSourceClonePath(entry.id);
|
|
14871
|
+
if (!fs18.existsSync(clonePath))
|
|
14872
|
+
return false;
|
|
14873
|
+
try {
|
|
14874
|
+
const validated = SourceSidecarSchema.parse(entry);
|
|
14875
|
+
const target = sourceSidecarPath(entry.id);
|
|
14876
|
+
const tmp = `${target}.tmp-${process.pid}`;
|
|
14877
|
+
fs18.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
|
|
14878
|
+
fs18.renameSync(tmp, target);
|
|
14879
|
+
return true;
|
|
14880
|
+
} catch {
|
|
14881
|
+
return false;
|
|
14882
|
+
}
|
|
14883
|
+
}
|
|
14884
|
+
function readSourceSidecar(id) {
|
|
14885
|
+
const target = sourceSidecarPath(id);
|
|
14886
|
+
let raw;
|
|
14887
|
+
try {
|
|
14888
|
+
raw = fs18.readFileSync(target, "utf-8");
|
|
14889
|
+
} catch {
|
|
14890
|
+
return null;
|
|
14891
|
+
}
|
|
14892
|
+
let parsed;
|
|
14893
|
+
try {
|
|
14894
|
+
parsed = JSON.parse(raw);
|
|
14895
|
+
} catch {
|
|
14896
|
+
return null;
|
|
14897
|
+
}
|
|
14898
|
+
const result = SourceSidecarSchema.safeParse(parsed);
|
|
14899
|
+
return result.success ? result.data : null;
|
|
14900
|
+
}
|
|
14901
|
+
var SOURCE_SIDECAR_FILENAME, SourceSidecarSchema;
|
|
14902
|
+
var init_source_file = __esm({
|
|
14903
|
+
"../core/dist/skill-sources/source-file.js"() {
|
|
14904
|
+
"use strict";
|
|
14905
|
+
init_schema3();
|
|
14906
|
+
init_clone();
|
|
14907
|
+
SOURCE_SIDECAR_FILENAME = ".olam-source.json";
|
|
14908
|
+
SourceSidecarSchema = SkillSourceSchema;
|
|
14909
|
+
}
|
|
14910
|
+
});
|
|
14911
|
+
|
|
14687
14912
|
// ../core/dist/skill-sources/store.js
|
|
14688
14913
|
import * as crypto3 from "node:crypto";
|
|
14689
14914
|
function deriveSkillSourceId(gitUrl) {
|
|
@@ -14716,6 +14941,7 @@ function addSkillSource(entry) {
|
|
|
14716
14941
|
addedAt: now
|
|
14717
14942
|
};
|
|
14718
14943
|
writeGlobalConfig({ ...config2, skillSources: [...config2.skillSources, newEntry] });
|
|
14944
|
+
writeSourceSidecar(newEntry);
|
|
14719
14945
|
try {
|
|
14720
14946
|
appendTrustAudit({
|
|
14721
14947
|
gitUrl: redactUrl2(entry.gitUrl),
|
|
@@ -14833,6 +15059,7 @@ function updateSkillSource(id, patch) {
|
|
|
14833
15059
|
const next = [...config2.skillSources];
|
|
14834
15060
|
next[idx] = updated;
|
|
14835
15061
|
writeGlobalConfig({ ...config2, skillSources: next });
|
|
15062
|
+
writeSourceSidecar(updated);
|
|
14836
15063
|
return updated;
|
|
14837
15064
|
}
|
|
14838
15065
|
var PREFIX_PATTERN3;
|
|
@@ -14843,102 +15070,141 @@ var init_store3 = __esm({
|
|
|
14843
15070
|
init_schema3();
|
|
14844
15071
|
init_trust_audit_log();
|
|
14845
15072
|
init_source_config_schema();
|
|
15073
|
+
init_source_file();
|
|
14846
15074
|
PREFIX_PATTERN3 = /^[a-z0-9][a-z0-9_-]{0,38}$/;
|
|
14847
15075
|
}
|
|
14848
15076
|
});
|
|
14849
15077
|
|
|
14850
|
-
// ../core/dist/skill-sources/
|
|
14851
|
-
import { execFileSync as
|
|
14852
|
-
import * as
|
|
14853
|
-
import * as
|
|
14854
|
-
|
|
14855
|
-
function skillSourcesRootDir() {
|
|
14856
|
-
const override = process.env["OLAM_SKILL_SOURCES_DIR"];
|
|
14857
|
-
if (override && override.length > 0)
|
|
14858
|
-
return override;
|
|
14859
|
-
return path19.join(os12.homedir(), ".olam", "state", "skill-sources");
|
|
14860
|
-
}
|
|
14861
|
-
function skillSourceClonePath(id) {
|
|
14862
|
-
return path19.join(skillSourcesRootDir(), id);
|
|
14863
|
-
}
|
|
14864
|
-
function runGit(args, cwd) {
|
|
15078
|
+
// ../core/dist/skill-sources/reconcile.js
|
|
15079
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
15080
|
+
import * as fs19 from "node:fs";
|
|
15081
|
+
import * as path21 from "node:path";
|
|
15082
|
+
function gitRead(args, cwd) {
|
|
14865
15083
|
try {
|
|
14866
|
-
return
|
|
15084
|
+
return execFileSync3("git", args, {
|
|
14867
15085
|
cwd,
|
|
14868
15086
|
encoding: "utf-8",
|
|
14869
|
-
stdio: ["ignore", "pipe", "
|
|
14870
|
-
});
|
|
14871
|
-
} catch
|
|
14872
|
-
|
|
15087
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
15088
|
+
}).trim();
|
|
15089
|
+
} catch {
|
|
15090
|
+
return null;
|
|
14873
15091
|
}
|
|
14874
15092
|
}
|
|
14875
|
-
function
|
|
14876
|
-
const
|
|
14877
|
-
if (
|
|
14878
|
-
|
|
14879
|
-
|
|
14880
|
-
|
|
15093
|
+
function nameFromGitUrl(gitUrl) {
|
|
15094
|
+
const tail = gitUrl.replace(/\.git$/, "").replace(/\/+$/, "").split(/[/:]/).filter((s) => s.length > 0).pop();
|
|
15095
|
+
if (!tail)
|
|
15096
|
+
return null;
|
|
15097
|
+
const sanitized = tail.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
15098
|
+
return NAME_PATTERN2.test(sanitized) ? sanitized : null;
|
|
15099
|
+
}
|
|
15100
|
+
function recoverFromGit(id, clonePath) {
|
|
15101
|
+
const gitUrl = gitRead(["remote", "get-url", "origin"], clonePath);
|
|
15102
|
+
if (!gitUrl)
|
|
15103
|
+
return null;
|
|
15104
|
+
const branch = gitRead(["symbolic-ref", "--short", "HEAD"], clonePath) ?? gitRead(["rev-parse", "--abbrev-ref", "HEAD"], clonePath) ?? "main";
|
|
15105
|
+
const headSha = gitRead(["rev-parse", "HEAD"], clonePath);
|
|
15106
|
+
let addedAt = 0;
|
|
14881
15107
|
try {
|
|
14882
|
-
|
|
14883
|
-
} catch
|
|
14884
|
-
|
|
14885
|
-
fs17.rmSync(clonePath, { recursive: true, force: true });
|
|
14886
|
-
}
|
|
14887
|
-
throw new SkillSourceGitError("clone", opts.gitUrl, err);
|
|
15108
|
+
addedAt = Math.floor(fs19.statSync(clonePath).ctimeMs);
|
|
15109
|
+
} catch {
|
|
15110
|
+
addedAt = 0;
|
|
14888
15111
|
}
|
|
14889
|
-
|
|
15112
|
+
const entry = {
|
|
15113
|
+
id,
|
|
15114
|
+
name: nameFromGitUrl(gitUrl) ?? `source-${id}`,
|
|
15115
|
+
gitUrl,
|
|
15116
|
+
branch,
|
|
15117
|
+
addedAt,
|
|
15118
|
+
...headSha && SHA_PATTERN.test(headSha) ? { lastPulledSha: headSha } : {}
|
|
15119
|
+
};
|
|
15120
|
+
return entry;
|
|
15121
|
+
}
|
|
15122
|
+
function listCloneIds() {
|
|
15123
|
+
const root = skillSourcesRootDir();
|
|
15124
|
+
let dirents;
|
|
14890
15125
|
try {
|
|
14891
|
-
|
|
14892
|
-
} catch
|
|
14893
|
-
|
|
15126
|
+
dirents = fs19.readdirSync(root, { withFileTypes: true });
|
|
15127
|
+
} catch {
|
|
15128
|
+
return [];
|
|
14894
15129
|
}
|
|
14895
|
-
return
|
|
15130
|
+
return dirents.filter((d) => d.isDirectory() && fs19.existsSync(path21.join(root, d.name, ".git"))).map((d) => d.name);
|
|
14896
15131
|
}
|
|
14897
|
-
function
|
|
14898
|
-
const
|
|
14899
|
-
|
|
14900
|
-
|
|
15132
|
+
function reconcileSkillSources(opts = {}) {
|
|
15133
|
+
const config2 = readGlobalConfig();
|
|
15134
|
+
const existingById = new Map(config2.skillSources.map((s) => [s.id, s]));
|
|
15135
|
+
const diskIds = new Set(listCloneIds());
|
|
15136
|
+
const added = [];
|
|
15137
|
+
const registryOnly = [];
|
|
15138
|
+
const sidecarsBackfilled = [];
|
|
15139
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
15140
|
+
const ensureUniqueName = (entry) => {
|
|
15141
|
+
if (!usedNames.has(entry.name)) {
|
|
15142
|
+
usedNames.add(entry.name);
|
|
15143
|
+
return entry;
|
|
15144
|
+
}
|
|
15145
|
+
const suffixed = `${entry.name}-${entry.id.slice(0, 6)}`.slice(0, 64).replace(/-+$/g, "");
|
|
15146
|
+
usedNames.add(suffixed);
|
|
15147
|
+
return { ...entry, name: suffixed };
|
|
15148
|
+
};
|
|
15149
|
+
const next = [];
|
|
15150
|
+
for (const entry of config2.skillSources) {
|
|
15151
|
+
if (diskIds.has(entry.id)) {
|
|
15152
|
+
usedNames.add(entry.name);
|
|
15153
|
+
next.push(entry);
|
|
15154
|
+
} else {
|
|
15155
|
+
registryOnly.push(entry);
|
|
15156
|
+
if (!opts.prune) {
|
|
15157
|
+
usedNames.add(entry.name);
|
|
15158
|
+
next.push(entry);
|
|
15159
|
+
}
|
|
15160
|
+
}
|
|
14901
15161
|
}
|
|
14902
|
-
|
|
14903
|
-
|
|
14904
|
-
|
|
14905
|
-
|
|
14906
|
-
|
|
15162
|
+
for (const id of diskIds) {
|
|
15163
|
+
if (existingById.has(id)) {
|
|
15164
|
+
if (readSourceSidecar(id) === null && writeSourceSidecar(existingById.get(id))) {
|
|
15165
|
+
sidecarsBackfilled.push(id);
|
|
15166
|
+
}
|
|
15167
|
+
continue;
|
|
15168
|
+
}
|
|
15169
|
+
const sidecar = readSourceSidecar(id);
|
|
15170
|
+
const recovered = sidecar ? { ...sidecar, id } : recoverFromGit(id, skillSourceClonePath(id));
|
|
15171
|
+
if (recovered === null)
|
|
15172
|
+
continue;
|
|
15173
|
+
const unique = ensureUniqueName(recovered);
|
|
15174
|
+
next.push(unique);
|
|
15175
|
+
added.push(unique);
|
|
15176
|
+
if (sidecar === null && writeSourceSidecar(unique))
|
|
15177
|
+
sidecarsBackfilled.push(id);
|
|
14907
15178
|
}
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
|
|
14912
|
-
throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
|
|
15179
|
+
const pruned = opts.prune ? registryOnly : [];
|
|
15180
|
+
const changed = next.length !== config2.skillSources.length || next.some((e, i) => e !== config2.skillSources[i]);
|
|
15181
|
+
if (changed) {
|
|
15182
|
+
writeGlobalConfig({ ...config2, skillSources: next });
|
|
14913
15183
|
}
|
|
15184
|
+
return { added, registryOnly, pruned, sidecarsBackfilled, changed };
|
|
14914
15185
|
}
|
|
14915
|
-
function
|
|
14916
|
-
|
|
14917
|
-
|
|
14918
|
-
|
|
14919
|
-
|
|
15186
|
+
function reconcileIfRegistryEmpty() {
|
|
15187
|
+
if (readGlobalConfig().skillSources.length > 0)
|
|
15188
|
+
return null;
|
|
15189
|
+
if (listCloneIds().length === 0)
|
|
15190
|
+
return null;
|
|
15191
|
+
return reconcileSkillSources();
|
|
14920
15192
|
}
|
|
14921
|
-
var
|
|
14922
|
-
var
|
|
14923
|
-
"../core/dist/skill-sources/
|
|
15193
|
+
var NAME_PATTERN2, SHA_PATTERN;
|
|
15194
|
+
var init_reconcile = __esm({
|
|
15195
|
+
"../core/dist/skill-sources/reconcile.js"() {
|
|
14924
15196
|
"use strict";
|
|
14925
|
-
|
|
14926
|
-
|
|
14927
|
-
|
|
14928
|
-
|
|
14929
|
-
|
|
14930
|
-
|
|
14931
|
-
this.op = op;
|
|
14932
|
-
this.gitUrl = gitUrl;
|
|
14933
|
-
this.name = "SkillSourceGitError";
|
|
14934
|
-
this.cause = cause;
|
|
14935
|
-
}
|
|
14936
|
-
};
|
|
15197
|
+
init_store2();
|
|
15198
|
+
init_schema3();
|
|
15199
|
+
init_clone();
|
|
15200
|
+
init_source_file();
|
|
15201
|
+
NAME_PATTERN2 = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
15202
|
+
SHA_PATTERN = /^[a-f0-9]{40}$/;
|
|
14937
15203
|
}
|
|
14938
15204
|
});
|
|
14939
15205
|
|
|
14940
15206
|
// ../core/dist/skill-sources/hook-template.js
|
|
14941
|
-
import * as
|
|
15207
|
+
import * as fs20 from "node:fs";
|
|
14942
15208
|
function buildSkillsHookEntry() {
|
|
14943
15209
|
return {
|
|
14944
15210
|
matcher: "",
|
|
@@ -14997,14 +15263,14 @@ function computeUninstall(settings) {
|
|
|
14997
15263
|
return { status: "removed", settingsAfter: next };
|
|
14998
15264
|
}
|
|
14999
15265
|
function uninstallSkillsHookFromFile(filePath) {
|
|
15000
|
-
if (!
|
|
15266
|
+
if (!fs20.existsSync(filePath)) {
|
|
15001
15267
|
return { status: "no-settings" };
|
|
15002
15268
|
}
|
|
15003
|
-
const raw =
|
|
15269
|
+
const raw = fs20.readFileSync(filePath, "utf-8");
|
|
15004
15270
|
const settings = raw.trim() ? JSON.parse(raw) : {};
|
|
15005
15271
|
const result = computeUninstall(settings);
|
|
15006
15272
|
if (result.status === "removed" && result.settingsAfter) {
|
|
15007
|
-
|
|
15273
|
+
fs20.writeFileSync(filePath, JSON.stringify(result.settingsAfter, null, 2) + "\n");
|
|
15008
15274
|
}
|
|
15009
15275
|
return result;
|
|
15010
15276
|
}
|
|
@@ -15020,8 +15286,8 @@ var init_hook_template = __esm({
|
|
|
15020
15286
|
});
|
|
15021
15287
|
|
|
15022
15288
|
// ../core/dist/world/merge-settings.js
|
|
15023
|
-
import * as
|
|
15024
|
-
import * as
|
|
15289
|
+
import * as fs21 from "node:fs";
|
|
15290
|
+
import * as path22 from "node:path";
|
|
15025
15291
|
import * as crypto4 from "node:crypto";
|
|
15026
15292
|
function mergeHomeSettingsJson(filePath, options) {
|
|
15027
15293
|
let settings;
|
|
@@ -15051,11 +15317,12 @@ function mergeHomeSettingsJson(filePath, options) {
|
|
|
15051
15317
|
return { status: "already-present", message: `hook already present at ${filePath}` };
|
|
15052
15318
|
}
|
|
15053
15319
|
} else {
|
|
15320
|
+
const filteredArr = options.ensureHook.staleSentinelPrefix ? dropStaleHooks(stageArr, options.ensureHook.staleSentinelPrefix, sentinel) : stageArr;
|
|
15054
15321
|
settings = {
|
|
15055
15322
|
...settings,
|
|
15056
15323
|
hooks: {
|
|
15057
15324
|
...settings.hooks,
|
|
15058
|
-
[stage]: [...
|
|
15325
|
+
[stage]: [...filteredArr, entry]
|
|
15059
15326
|
}
|
|
15060
15327
|
};
|
|
15061
15328
|
changed = true;
|
|
@@ -15081,14 +15348,32 @@ function mergeHomeSettingsJson(filePath, options) {
|
|
|
15081
15348
|
return { status: "installed", message: `settings.json updated at ${filePath}` };
|
|
15082
15349
|
}
|
|
15083
15350
|
function readSettings(filePath) {
|
|
15084
|
-
if (!
|
|
15351
|
+
if (!fs21.existsSync(filePath)) {
|
|
15085
15352
|
return {};
|
|
15086
15353
|
}
|
|
15087
|
-
const raw =
|
|
15354
|
+
const raw = fs21.readFileSync(filePath, "utf-8");
|
|
15088
15355
|
if (!raw.trim())
|
|
15089
15356
|
return {};
|
|
15090
15357
|
return JSON.parse(raw);
|
|
15091
15358
|
}
|
|
15359
|
+
function dropStaleHooks(matchers, stalePrefix, currentSentinel) {
|
|
15360
|
+
const out = [];
|
|
15361
|
+
for (const matcher of matchers) {
|
|
15362
|
+
const allCmds = [];
|
|
15363
|
+
if (typeof matcher.command === "string")
|
|
15364
|
+
allCmds.push(matcher.command);
|
|
15365
|
+
if (Array.isArray(matcher.hooks)) {
|
|
15366
|
+
for (const h of matcher.hooks) {
|
|
15367
|
+
if (typeof h.command === "string")
|
|
15368
|
+
allCmds.push(h.command);
|
|
15369
|
+
}
|
|
15370
|
+
}
|
|
15371
|
+
const isStale = allCmds.some((c) => c.includes(stalePrefix)) && !allCmds.some((c) => c.includes(currentSentinel));
|
|
15372
|
+
if (!isStale)
|
|
15373
|
+
out.push(matcher);
|
|
15374
|
+
}
|
|
15375
|
+
return out;
|
|
15376
|
+
}
|
|
15092
15377
|
function isHookSentinelPresent(matchers, sentinel) {
|
|
15093
15378
|
for (const matcher of matchers) {
|
|
15094
15379
|
if (typeof matcher?.command === "string" && matcher.command.includes(sentinel)) {
|
|
@@ -15105,13 +15390,13 @@ function isHookSentinelPresent(matchers, sentinel) {
|
|
|
15105
15390
|
return false;
|
|
15106
15391
|
}
|
|
15107
15392
|
function atomicWriteJson(filePath, data) {
|
|
15108
|
-
const dir =
|
|
15109
|
-
|
|
15393
|
+
const dir = path22.dirname(filePath);
|
|
15394
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
15110
15395
|
const rand = crypto4.randomBytes(6).toString("hex");
|
|
15111
15396
|
const tmp = `${filePath}.tmp.${process.pid}.${rand}`;
|
|
15112
15397
|
const json2 = JSON.stringify(data, null, 2) + "\n";
|
|
15113
|
-
|
|
15114
|
-
|
|
15398
|
+
fs21.writeFileSync(tmp, json2, { mode: 420 });
|
|
15399
|
+
fs21.renameSync(tmp, filePath);
|
|
15115
15400
|
}
|
|
15116
15401
|
var init_merge_settings = __esm({
|
|
15117
15402
|
"../core/dist/world/merge-settings.js"() {
|
|
@@ -15120,25 +15405,25 @@ var init_merge_settings = __esm({
|
|
|
15120
15405
|
});
|
|
15121
15406
|
|
|
15122
15407
|
// ../core/dist/skill-sources/hook-install.js
|
|
15123
|
-
import * as
|
|
15124
|
-
import * as
|
|
15408
|
+
import * as fs22 from "node:fs";
|
|
15409
|
+
import * as path23 from "node:path";
|
|
15125
15410
|
import * as os13 from "node:os";
|
|
15126
15411
|
function settingsPathFor(scope, cwd) {
|
|
15127
15412
|
if (scope === "user") {
|
|
15128
|
-
return
|
|
15413
|
+
return path23.join(os13.homedir(), ".claude", "settings.json");
|
|
15129
15414
|
}
|
|
15130
|
-
return
|
|
15415
|
+
return path23.join(cwd ?? process.cwd(), ".claude", "settings.json");
|
|
15131
15416
|
}
|
|
15132
15417
|
function backupFile(filePath) {
|
|
15133
|
-
if (!
|
|
15418
|
+
if (!fs22.existsSync(filePath))
|
|
15134
15419
|
return null;
|
|
15135
15420
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
15136
15421
|
const backupPath = `${filePath}.olam-bak.${ts}`;
|
|
15137
|
-
|
|
15422
|
+
fs22.copyFileSync(filePath, backupPath);
|
|
15138
15423
|
return backupPath;
|
|
15139
15424
|
}
|
|
15140
15425
|
function installSkillsHookToFile(filePath) {
|
|
15141
|
-
|
|
15426
|
+
fs22.mkdirSync(path23.dirname(filePath), { recursive: true });
|
|
15142
15427
|
const backupPath = backupFile(filePath);
|
|
15143
15428
|
const result = mergeHomeSettingsJson(filePath, {
|
|
15144
15429
|
ensureHook: {
|
|
@@ -15149,7 +15434,7 @@ function installSkillsHookToFile(filePath) {
|
|
|
15149
15434
|
});
|
|
15150
15435
|
if (result.status === "already-present" && backupPath) {
|
|
15151
15436
|
try {
|
|
15152
|
-
|
|
15437
|
+
fs22.unlinkSync(backupPath);
|
|
15153
15438
|
} catch {
|
|
15154
15439
|
}
|
|
15155
15440
|
return { status: "already-present", filePath, backupPath: null };
|
|
@@ -15157,11 +15442,11 @@ function installSkillsHookToFile(filePath) {
|
|
|
15157
15442
|
return { status: result.status, filePath, backupPath };
|
|
15158
15443
|
}
|
|
15159
15444
|
function isSkillsHookInstalled(filePath) {
|
|
15160
|
-
if (!
|
|
15445
|
+
if (!fs22.existsSync(filePath))
|
|
15161
15446
|
return false;
|
|
15162
15447
|
let parsed;
|
|
15163
15448
|
try {
|
|
15164
|
-
parsed = JSON.parse(
|
|
15449
|
+
parsed = JSON.parse(fs22.readFileSync(filePath, "utf-8"));
|
|
15165
15450
|
} catch {
|
|
15166
15451
|
return false;
|
|
15167
15452
|
}
|
|
@@ -15199,36 +15484,36 @@ var init_hook_install = __esm({
|
|
|
15199
15484
|
});
|
|
15200
15485
|
|
|
15201
15486
|
// ../core/dist/skill-sources/migration-snapshot.js
|
|
15202
|
-
import * as
|
|
15487
|
+
import * as fs23 from "node:fs";
|
|
15203
15488
|
import * as os14 from "node:os";
|
|
15204
|
-
import * as
|
|
15489
|
+
import * as path24 from "node:path";
|
|
15205
15490
|
function claudeDirInternal() {
|
|
15206
15491
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
15207
15492
|
if (override && override.length > 0)
|
|
15208
15493
|
return override;
|
|
15209
|
-
return
|
|
15494
|
+
return path24.join(os14.homedir(), ".claude");
|
|
15210
15495
|
}
|
|
15211
15496
|
function migrationSnapshotsDir() {
|
|
15212
15497
|
const override = process.env["OLAM_MIGRATION_SNAPSHOTS_DIR"];
|
|
15213
15498
|
if (override && override.length > 0)
|
|
15214
15499
|
return override;
|
|
15215
|
-
return
|
|
15500
|
+
return path24.join(os14.homedir(), ".olam", "state", "migration-snapshots");
|
|
15216
15501
|
}
|
|
15217
15502
|
function listToolboxManagedSymlinks(toolboxPath) {
|
|
15218
15503
|
const claude = claudeDirInternal();
|
|
15219
15504
|
const out = [];
|
|
15220
15505
|
const BUCKETS2 = ["skills", "agents", "scripts", "rules", "commands"];
|
|
15221
15506
|
for (const bucket of BUCKETS2) {
|
|
15222
|
-
const dir =
|
|
15223
|
-
if (!
|
|
15507
|
+
const dir = path24.join(claude, bucket);
|
|
15508
|
+
if (!fs23.existsSync(dir))
|
|
15224
15509
|
continue;
|
|
15225
|
-
for (const name of
|
|
15226
|
-
const link =
|
|
15510
|
+
for (const name of fs23.readdirSync(dir)) {
|
|
15511
|
+
const link = path24.join(dir, name);
|
|
15227
15512
|
try {
|
|
15228
|
-
const stat2 =
|
|
15513
|
+
const stat2 = fs23.lstatSync(link);
|
|
15229
15514
|
if (!stat2.isSymbolicLink())
|
|
15230
15515
|
continue;
|
|
15231
|
-
const target =
|
|
15516
|
+
const target = fs23.readlinkSync(link);
|
|
15232
15517
|
if (target.startsWith(toolboxPath)) {
|
|
15233
15518
|
out.push({ link, target });
|
|
15234
15519
|
}
|
|
@@ -15241,25 +15526,25 @@ function listToolboxManagedSymlinks(toolboxPath) {
|
|
|
15241
15526
|
function detectToolboxState(opts) {
|
|
15242
15527
|
const claude = claudeDirInternal();
|
|
15243
15528
|
const toolboxPath = opts.toolboxPath;
|
|
15244
|
-
const namespace = opts.namespace ??
|
|
15245
|
-
const atlasUserFile =
|
|
15246
|
-
const atlasUser =
|
|
15529
|
+
const namespace = opts.namespace ?? path24.basename(toolboxPath);
|
|
15530
|
+
const atlasUserFile = path24.join(claude, ".atlas-user");
|
|
15531
|
+
const atlasUser = fs23.existsSync(atlasUserFile) ? fs23.readFileSync(atlasUserFile, "utf-8").trim() || void 0 : void 0;
|
|
15247
15532
|
let subscriptionsJson;
|
|
15248
15533
|
if (atlasUser) {
|
|
15249
|
-
const sp =
|
|
15250
|
-
if (
|
|
15534
|
+
const sp = path24.join(toolboxPath, "members", atlasUser, "subscriptions.json");
|
|
15535
|
+
if (fs23.existsSync(sp)) {
|
|
15251
15536
|
try {
|
|
15252
|
-
subscriptionsJson = JSON.parse(
|
|
15537
|
+
subscriptionsJson = JSON.parse(fs23.readFileSync(sp, "utf-8"));
|
|
15253
15538
|
} catch {
|
|
15254
15539
|
}
|
|
15255
15540
|
}
|
|
15256
15541
|
}
|
|
15257
15542
|
const atlasManagedSymlinks = listToolboxManagedSymlinks(toolboxPath);
|
|
15258
15543
|
let originalSessionStartHook;
|
|
15259
|
-
const settingsPath =
|
|
15260
|
-
if (
|
|
15544
|
+
const settingsPath = path24.join(claude, "settings.json");
|
|
15545
|
+
if (fs23.existsSync(settingsPath)) {
|
|
15261
15546
|
try {
|
|
15262
|
-
const settings = JSON.parse(
|
|
15547
|
+
const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
|
|
15263
15548
|
const ss = settings?.hooks?.SessionStart;
|
|
15264
15549
|
if (Array.isArray(ss))
|
|
15265
15550
|
originalSessionStartHook = ss;
|
|
@@ -15282,21 +15567,21 @@ function detectToolboxState(opts) {
|
|
|
15282
15567
|
}
|
|
15283
15568
|
function writeMigrationSnapshot(snapshot) {
|
|
15284
15569
|
const dir = migrationSnapshotsDir();
|
|
15285
|
-
|
|
15570
|
+
fs23.mkdirSync(dir, { recursive: true });
|
|
15286
15571
|
const stamp = snapshot.takenAt.replace(/[:.]/g, "-");
|
|
15287
|
-
const file2 =
|
|
15288
|
-
|
|
15572
|
+
const file2 = path24.join(dir, `${snapshot.namespace}-${stamp}.json`);
|
|
15573
|
+
fs23.writeFileSync(file2, JSON.stringify(snapshot, null, 2) + "\n", { mode: 420 });
|
|
15289
15574
|
return file2;
|
|
15290
15575
|
}
|
|
15291
15576
|
function readLatestMigrationSnapshot(opts = {}) {
|
|
15292
15577
|
const dir = migrationSnapshotsDir();
|
|
15293
|
-
if (!
|
|
15578
|
+
if (!fs23.existsSync(dir))
|
|
15294
15579
|
return void 0;
|
|
15295
|
-
const files =
|
|
15580
|
+
const files = fs23.readdirSync(dir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
15296
15581
|
for (const f of files) {
|
|
15297
|
-
const full =
|
|
15582
|
+
const full = path24.join(dir, f);
|
|
15298
15583
|
try {
|
|
15299
|
-
const snapshot = JSON.parse(
|
|
15584
|
+
const snapshot = JSON.parse(fs23.readFileSync(full, "utf-8"));
|
|
15300
15585
|
if (snapshot.schemaVersion !== MIGRATION_SNAPSHOT_SCHEMA_VERSION)
|
|
15301
15586
|
continue;
|
|
15302
15587
|
if (typeof snapshot.atlasToolboxRepoPath !== "string")
|
|
@@ -15313,7 +15598,7 @@ function readLatestMigrationSnapshot(opts = {}) {
|
|
|
15313
15598
|
return void 0;
|
|
15314
15599
|
}
|
|
15315
15600
|
function readMigrationSnapshotFromPath(p) {
|
|
15316
|
-
return JSON.parse(
|
|
15601
|
+
return JSON.parse(fs23.readFileSync(p, "utf-8"));
|
|
15317
15602
|
}
|
|
15318
15603
|
var MIGRATION_SNAPSHOT_SCHEMA_VERSION;
|
|
15319
15604
|
var init_migration_snapshot = __esm({
|
|
@@ -15324,15 +15609,15 @@ var init_migration_snapshot = __esm({
|
|
|
15324
15609
|
});
|
|
15325
15610
|
|
|
15326
15611
|
// ../core/dist/skill-sync/artifact-resolver.js
|
|
15327
|
-
import * as
|
|
15328
|
-
import * as
|
|
15612
|
+
import * as fs24 from "node:fs";
|
|
15613
|
+
import * as path25 from "node:path";
|
|
15329
15614
|
function resolveSubscriptions(opts) {
|
|
15330
15615
|
const { clonePath, atlasUser } = opts;
|
|
15331
15616
|
if (atlasUser) {
|
|
15332
|
-
const subsPath =
|
|
15333
|
-
if (
|
|
15617
|
+
const subsPath = path25.join(clonePath, "members", atlasUser, "subscriptions.json");
|
|
15618
|
+
if (fs24.existsSync(subsPath)) {
|
|
15334
15619
|
try {
|
|
15335
|
-
const parsed = JSON.parse(
|
|
15620
|
+
const parsed = JSON.parse(fs24.readFileSync(subsPath, "utf-8"));
|
|
15336
15621
|
if (Array.isArray(parsed?.categories)) {
|
|
15337
15622
|
return {
|
|
15338
15623
|
categories: parsed.categories.filter((c) => typeof c === "string"),
|
|
@@ -15344,10 +15629,10 @@ function resolveSubscriptions(opts) {
|
|
|
15344
15629
|
}
|
|
15345
15630
|
}
|
|
15346
15631
|
}
|
|
15347
|
-
const catsPath =
|
|
15348
|
-
if (
|
|
15632
|
+
const catsPath = path25.join(clonePath, "shared", "categories.json");
|
|
15633
|
+
if (fs24.existsSync(catsPath)) {
|
|
15349
15634
|
try {
|
|
15350
|
-
const parsed = JSON.parse(
|
|
15635
|
+
const parsed = JSON.parse(fs24.readFileSync(catsPath, "utf-8"));
|
|
15351
15636
|
if (Array.isArray(parsed?.categories)) {
|
|
15352
15637
|
return {
|
|
15353
15638
|
categories: parsed.categories.map((c) => c.id).filter((id) => typeof id === "string"),
|
|
@@ -15358,14 +15643,14 @@ function resolveSubscriptions(opts) {
|
|
|
15358
15643
|
} catch {
|
|
15359
15644
|
}
|
|
15360
15645
|
}
|
|
15361
|
-
const sharedDir =
|
|
15646
|
+
const sharedDir = path25.join(clonePath, "shared");
|
|
15362
15647
|
const cats = [];
|
|
15363
|
-
if (
|
|
15364
|
-
for (const name of
|
|
15365
|
-
const dir =
|
|
15366
|
-
if (!
|
|
15648
|
+
if (fs24.existsSync(sharedDir)) {
|
|
15649
|
+
for (const name of fs24.readdirSync(sharedDir)) {
|
|
15650
|
+
const dir = path25.join(sharedDir, name);
|
|
15651
|
+
if (!fs24.statSync(dir).isDirectory())
|
|
15367
15652
|
continue;
|
|
15368
|
-
if (
|
|
15653
|
+
if (fs24.existsSync(path25.join(dir, "skills")) || fs24.existsSync(path25.join(dir, "agents"))) {
|
|
15369
15654
|
cats.push(name);
|
|
15370
15655
|
}
|
|
15371
15656
|
}
|
|
@@ -15373,29 +15658,29 @@ function resolveSubscriptions(opts) {
|
|
|
15373
15658
|
return { categories: cats, fromSubscriptionsFile: false, atlasUser };
|
|
15374
15659
|
}
|
|
15375
15660
|
function listDirSafe(dir) {
|
|
15376
|
-
if (!
|
|
15661
|
+
if (!fs24.existsSync(dir))
|
|
15377
15662
|
return [];
|
|
15378
|
-
return
|
|
15663
|
+
return fs24.readdirSync(dir);
|
|
15379
15664
|
}
|
|
15380
15665
|
function resolveSkillsDir(opts) {
|
|
15381
15666
|
const { sourceId, baseDir } = opts;
|
|
15382
15667
|
const out = [];
|
|
15383
15668
|
for (const name of listDirSafe(baseDir)) {
|
|
15384
|
-
const subdir =
|
|
15385
|
-
if (!
|
|
15669
|
+
const subdir = path25.join(baseDir, name);
|
|
15670
|
+
if (!fs24.statSync(subdir).isDirectory())
|
|
15386
15671
|
continue;
|
|
15387
|
-
if (!
|
|
15672
|
+
if (!fs24.existsSync(path25.join(subdir, "SKILL.md")))
|
|
15388
15673
|
continue;
|
|
15389
15674
|
out.push({ kind: "skill", sourceId, sourcePath: subdir, deployBasename: name });
|
|
15390
|
-
const subagentsDir =
|
|
15391
|
-
if (
|
|
15675
|
+
const subagentsDir = path25.join(subdir, "references", "agents");
|
|
15676
|
+
if (fs24.existsSync(subagentsDir) && fs24.statSync(subagentsDir).isDirectory()) {
|
|
15392
15677
|
for (const f of listDirSafe(subagentsDir)) {
|
|
15393
15678
|
if (!f.endsWith(".md"))
|
|
15394
15679
|
continue;
|
|
15395
15680
|
out.push({
|
|
15396
15681
|
kind: "subagent",
|
|
15397
15682
|
sourceId,
|
|
15398
|
-
sourcePath:
|
|
15683
|
+
sourcePath: path25.join(subagentsDir, f),
|
|
15399
15684
|
deployBasename: f,
|
|
15400
15685
|
parentSkill: name
|
|
15401
15686
|
});
|
|
@@ -15408,8 +15693,8 @@ function resolveAgentsDir(opts) {
|
|
|
15408
15693
|
const { sourceId, baseDir } = opts;
|
|
15409
15694
|
const out = [];
|
|
15410
15695
|
for (const name of listDirSafe(baseDir)) {
|
|
15411
|
-
const full =
|
|
15412
|
-
const stat2 =
|
|
15696
|
+
const full = path25.join(baseDir, name);
|
|
15697
|
+
const stat2 = fs24.statSync(full);
|
|
15413
15698
|
if (stat2.isFile() && name.endsWith(".md")) {
|
|
15414
15699
|
out.push({ kind: "agent", sourceId, sourcePath: full, deployBasename: name });
|
|
15415
15700
|
} else if (stat2.isDirectory()) {
|
|
@@ -15419,7 +15704,7 @@ function resolveAgentsDir(opts) {
|
|
|
15419
15704
|
out.push({
|
|
15420
15705
|
kind: "agent",
|
|
15421
15706
|
sourceId,
|
|
15422
|
-
sourcePath:
|
|
15707
|
+
sourcePath: path25.join(full, f),
|
|
15423
15708
|
deployBasename: `${name}-${f}`
|
|
15424
15709
|
});
|
|
15425
15710
|
}
|
|
@@ -15431,8 +15716,8 @@ function resolveScriptsDir(opts) {
|
|
|
15431
15716
|
const { sourceId, baseDir } = opts;
|
|
15432
15717
|
const out = [];
|
|
15433
15718
|
for (const name of listDirSafe(baseDir)) {
|
|
15434
|
-
const full =
|
|
15435
|
-
const stat2 =
|
|
15719
|
+
const full = path25.join(baseDir, name);
|
|
15720
|
+
const stat2 = fs24.statSync(full);
|
|
15436
15721
|
if (stat2.isFile() && name.endsWith(".sh")) {
|
|
15437
15722
|
out.push({ kind: "script", sourceId, sourcePath: full, deployBasename: name });
|
|
15438
15723
|
} else if (stat2.isDirectory()) {
|
|
@@ -15447,8 +15732,8 @@ function resolveRulesDir(opts) {
|
|
|
15447
15732
|
for (const name of listDirSafe(baseDir)) {
|
|
15448
15733
|
if (!name.endsWith(".md"))
|
|
15449
15734
|
continue;
|
|
15450
|
-
const full =
|
|
15451
|
-
if (!
|
|
15735
|
+
const full = path25.join(baseDir, name);
|
|
15736
|
+
if (!fs24.statSync(full).isFile())
|
|
15452
15737
|
continue;
|
|
15453
15738
|
out.push({ kind: "rule", sourceId, sourcePath: full, deployBasename: name });
|
|
15454
15739
|
}
|
|
@@ -15460,8 +15745,8 @@ function resolveJsonDir(opts) {
|
|
|
15460
15745
|
for (const name of listDirSafe(baseDir)) {
|
|
15461
15746
|
if (!name.endsWith(".json"))
|
|
15462
15747
|
continue;
|
|
15463
|
-
const full =
|
|
15464
|
-
if (!
|
|
15748
|
+
const full = path25.join(baseDir, name);
|
|
15749
|
+
if (!fs24.statSync(full).isFile())
|
|
15465
15750
|
continue;
|
|
15466
15751
|
out.push({ kind, sourceId, sourcePath: full, deployBasename: name });
|
|
15467
15752
|
}
|
|
@@ -15473,8 +15758,8 @@ function resolveOverlaysDir(opts) {
|
|
|
15473
15758
|
for (const name of listDirSafe(baseDir)) {
|
|
15474
15759
|
if (!name.endsWith(".md"))
|
|
15475
15760
|
continue;
|
|
15476
|
-
const full =
|
|
15477
|
-
if (!
|
|
15761
|
+
const full = path25.join(baseDir, name);
|
|
15762
|
+
if (!fs24.statSync(full).isFile())
|
|
15478
15763
|
continue;
|
|
15479
15764
|
const deployBasename = name.replace(/\.md$/, "");
|
|
15480
15765
|
out.push({
|
|
@@ -15492,33 +15777,33 @@ function resolveSourceArtifacts(opts) {
|
|
|
15492
15777
|
const subscription = resolveSubscriptions({ clonePath, atlasUser });
|
|
15493
15778
|
const artifacts = [];
|
|
15494
15779
|
for (const cat of subscription.categories) {
|
|
15495
|
-
const catDir =
|
|
15496
|
-
if (!
|
|
15780
|
+
const catDir = path25.join(clonePath, "shared", cat);
|
|
15781
|
+
if (!fs24.existsSync(catDir))
|
|
15497
15782
|
continue;
|
|
15498
|
-
artifacts.push(...resolveSkillsDir({ sourceId, baseDir:
|
|
15499
|
-
artifacts.push(...resolveAgentsDir({ sourceId, baseDir:
|
|
15500
|
-
artifacts.push(...resolveScriptsDir({ sourceId, baseDir:
|
|
15501
|
-
artifacts.push(...resolveRulesDir({ sourceId, baseDir:
|
|
15502
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
15503
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
15783
|
+
artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path25.join(catDir, "skills") }));
|
|
15784
|
+
artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path25.join(catDir, "agents") }));
|
|
15785
|
+
artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path25.join(catDir, "scripts") }));
|
|
15786
|
+
artifacts.push(...resolveRulesDir({ sourceId, baseDir: path25.join(catDir, "rules") }));
|
|
15787
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(catDir, "hooks"), kind: "hook" }));
|
|
15788
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(catDir, "permissions"), kind: "permission" }));
|
|
15504
15789
|
}
|
|
15505
15790
|
if (atlasUser) {
|
|
15506
|
-
const memberRoot =
|
|
15507
|
-
if (
|
|
15508
|
-
artifacts.push(...resolveSkillsDir({ sourceId, baseDir:
|
|
15509
|
-
artifacts.push(...resolveAgentsDir({ sourceId, baseDir:
|
|
15510
|
-
artifacts.push(...resolveScriptsDir({ sourceId, baseDir:
|
|
15511
|
-
artifacts.push(...resolveRulesDir({ sourceId, baseDir:
|
|
15512
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
15513
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
15791
|
+
const memberRoot = path25.join(clonePath, "members", atlasUser);
|
|
15792
|
+
if (fs24.existsSync(memberRoot)) {
|
|
15793
|
+
artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path25.join(memberRoot, "skills") }));
|
|
15794
|
+
artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path25.join(memberRoot, "agents") }));
|
|
15795
|
+
artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path25.join(memberRoot, "scripts") }));
|
|
15796
|
+
artifacts.push(...resolveRulesDir({ sourceId, baseDir: path25.join(memberRoot, "rules") }));
|
|
15797
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(memberRoot, "hooks"), kind: "hook" }));
|
|
15798
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(memberRoot, "permissions"), kind: "permission" }));
|
|
15514
15799
|
artifacts.push(...resolveOverlaysDir({
|
|
15515
15800
|
sourceId,
|
|
15516
|
-
baseDir:
|
|
15801
|
+
baseDir: path25.join(memberRoot, "skills.overrides"),
|
|
15517
15802
|
targetKind: "skill"
|
|
15518
15803
|
}));
|
|
15519
15804
|
artifacts.push(...resolveOverlaysDir({
|
|
15520
15805
|
sourceId,
|
|
15521
|
-
baseDir:
|
|
15806
|
+
baseDir: path25.join(memberRoot, "agents.overrides"),
|
|
15522
15807
|
targetKind: "agent"
|
|
15523
15808
|
}));
|
|
15524
15809
|
}
|
|
@@ -15584,14 +15869,14 @@ var init_shim_targets = __esm({
|
|
|
15584
15869
|
});
|
|
15585
15870
|
|
|
15586
15871
|
// ../core/dist/skill-sync/symlink-deployer.js
|
|
15587
|
-
import * as
|
|
15872
|
+
import * as fs25 from "node:fs";
|
|
15588
15873
|
import * as os15 from "node:os";
|
|
15589
|
-
import * as
|
|
15874
|
+
import * as path26 from "node:path";
|
|
15590
15875
|
function claudeDir() {
|
|
15591
15876
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
15592
15877
|
if (override && override.length > 0)
|
|
15593
15878
|
return override;
|
|
15594
|
-
return
|
|
15879
|
+
return path26.join(os15.homedir(), ".claude");
|
|
15595
15880
|
}
|
|
15596
15881
|
function bucketFor(kind) {
|
|
15597
15882
|
switch (kind) {
|
|
@@ -15651,15 +15936,15 @@ function detectCollisions(artifacts) {
|
|
|
15651
15936
|
function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, expectedAgentWinnerNames) {
|
|
15652
15937
|
const shadowBackups = [];
|
|
15653
15938
|
for (const bucket of BUCKETS) {
|
|
15654
|
-
const dir =
|
|
15655
|
-
if (!
|
|
15939
|
+
const dir = path26.join(claude, bucket);
|
|
15940
|
+
if (!fs25.existsSync(dir))
|
|
15656
15941
|
continue;
|
|
15657
|
-
for (const name of
|
|
15942
|
+
for (const name of fs25.readdirSync(dir)) {
|
|
15658
15943
|
if (name === ".olam-merged")
|
|
15659
15944
|
continue;
|
|
15660
|
-
const p =
|
|
15945
|
+
const p = path26.join(dir, name);
|
|
15661
15946
|
try {
|
|
15662
|
-
const stat2 =
|
|
15947
|
+
const stat2 = fs25.lstatSync(p);
|
|
15663
15948
|
if (stat2.isSymbolicLink()) {
|
|
15664
15949
|
if (bucket === "scripts" && overlayReferences !== void 0) {
|
|
15665
15950
|
const refs = overlayReferences.get(name);
|
|
@@ -15680,7 +15965,7 @@ function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, e
|
|
|
15680
15965
|
`);
|
|
15681
15966
|
}
|
|
15682
15967
|
}
|
|
15683
|
-
|
|
15968
|
+
fs25.unlinkSync(p);
|
|
15684
15969
|
} else if (bucket === "agents" && stat2.isFile() && !name.includes(".shadow-backup-")) {
|
|
15685
15970
|
const hasWinner = expectedAgentWinnerNames !== void 0 ? expectedAgentWinnerNames.has(name) : true;
|
|
15686
15971
|
if (hasWinner) {
|
|
@@ -15697,34 +15982,34 @@ function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, e
|
|
|
15697
15982
|
function shadowBackup(link) {
|
|
15698
15983
|
const epoch = Math.floor(Date.now() / 1e3);
|
|
15699
15984
|
const backup = `${link}.shadow-backup-${epoch}`;
|
|
15700
|
-
|
|
15985
|
+
fs25.renameSync(link, backup);
|
|
15701
15986
|
return backup;
|
|
15702
15987
|
}
|
|
15703
15988
|
function linkIfNeeded(target, link) {
|
|
15704
15989
|
try {
|
|
15705
|
-
const existing =
|
|
15990
|
+
const existing = fs25.readlinkSync(link);
|
|
15706
15991
|
if (existing === target)
|
|
15707
15992
|
return { created: false };
|
|
15708
15993
|
} catch {
|
|
15709
15994
|
}
|
|
15710
15995
|
let isLink = false;
|
|
15711
15996
|
try {
|
|
15712
|
-
isLink =
|
|
15997
|
+
isLink = fs25.lstatSync(link).isSymbolicLink();
|
|
15713
15998
|
} catch {
|
|
15714
15999
|
}
|
|
15715
16000
|
let backup;
|
|
15716
16001
|
if (isLink) {
|
|
15717
|
-
|
|
15718
|
-
} else if (
|
|
16002
|
+
fs25.unlinkSync(link);
|
|
16003
|
+
} else if (fs25.existsSync(link)) {
|
|
15719
16004
|
backup = shadowBackup(link);
|
|
15720
16005
|
}
|
|
15721
|
-
|
|
16006
|
+
fs25.symlinkSync(target, link);
|
|
15722
16007
|
return { created: true, shadowBackup: backup };
|
|
15723
16008
|
}
|
|
15724
16009
|
function deployArtifacts(artifacts, opts) {
|
|
15725
16010
|
const claude = claudeDir();
|
|
15726
16011
|
for (const bucket of BUCKETS) {
|
|
15727
|
-
|
|
16012
|
+
fs25.mkdirSync(path26.join(claude, bucket), { recursive: true });
|
|
15728
16013
|
}
|
|
15729
16014
|
const { winners, collisions } = detectCollisions(artifacts);
|
|
15730
16015
|
const expectedAgentWinnerNames = new Set(winners.filter((a) => a.kind === "agent").map((a) => a.deployBasename));
|
|
@@ -15734,11 +16019,11 @@ function deployArtifacts(artifacts, opts) {
|
|
|
15734
16019
|
const bucket = bucketFor(artifact.kind);
|
|
15735
16020
|
if (!bucket)
|
|
15736
16021
|
continue;
|
|
15737
|
-
const linkPath =
|
|
16022
|
+
const linkPath = path26.join(claude, bucket, artifact.deployBasename);
|
|
15738
16023
|
if (artifact.kind === "agent" && artifact.resolvedContent !== void 0) {
|
|
15739
16024
|
const tmpPath = `${linkPath}.tmp-${process.pid}-${Date.now()}`;
|
|
15740
|
-
|
|
15741
|
-
|
|
16025
|
+
fs25.writeFileSync(tmpPath, artifact.resolvedContent);
|
|
16026
|
+
fs25.renameSync(tmpPath, linkPath);
|
|
15742
16027
|
result.linked += 1;
|
|
15743
16028
|
continue;
|
|
15744
16029
|
}
|
|
@@ -15760,7 +16045,7 @@ var init_symlink_deployer = __esm({
|
|
|
15760
16045
|
});
|
|
15761
16046
|
|
|
15762
16047
|
// ../core/dist/meta-hooks/memory-recall.js
|
|
15763
|
-
import * as
|
|
16048
|
+
import * as fs26 from "node:fs";
|
|
15764
16049
|
function buildMemoryRecallHookEntry() {
|
|
15765
16050
|
return {
|
|
15766
16051
|
matcher: OLAM_META_MEMORY_RECALL_MATCHER,
|
|
@@ -15835,7 +16120,7 @@ var init_memory_recall = __esm({
|
|
|
15835
16120
|
});
|
|
15836
16121
|
|
|
15837
16122
|
// ../core/dist/meta-hooks/memory-classify.js
|
|
15838
|
-
import * as
|
|
16123
|
+
import * as fs27 from "node:fs";
|
|
15839
16124
|
function buildMemoryClassifyHookEntry() {
|
|
15840
16125
|
return {
|
|
15841
16126
|
matcher: OLAM_META_MEMORY_CLASSIFY_MATCHER,
|
|
@@ -15910,7 +16195,7 @@ var init_memory_classify = __esm({
|
|
|
15910
16195
|
});
|
|
15911
16196
|
|
|
15912
16197
|
// ../core/dist/meta-hooks/model-router.js
|
|
15913
|
-
import * as
|
|
16198
|
+
import * as fs28 from "node:fs";
|
|
15914
16199
|
function buildModelRouterHookEntry() {
|
|
15915
16200
|
return {
|
|
15916
16201
|
hooks: [
|
|
@@ -15984,9 +16269,9 @@ var init_model_router = __esm({
|
|
|
15984
16269
|
});
|
|
15985
16270
|
|
|
15986
16271
|
// ../core/dist/meta-hooks/model-router-deploy.js
|
|
15987
|
-
import { existsSync as
|
|
16272
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync16, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
|
|
15988
16273
|
import { homedir as homedir18 } from "node:os";
|
|
15989
|
-
import { dirname as dirname13, join as
|
|
16274
|
+
import { dirname as dirname13, join as join29, resolve as resolve7 } from "node:path";
|
|
15990
16275
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
15991
16276
|
function resolveModelRouterSourcePath() {
|
|
15992
16277
|
const here = dirname13(fileURLToPath3(import.meta.url));
|
|
@@ -16000,28 +16285,28 @@ function resolveModelRouterSourcePath() {
|
|
|
16000
16285
|
resolve7(here, "..", "..", "hooks", MODEL_ROUTER_SCRIPT_BASENAME)
|
|
16001
16286
|
];
|
|
16002
16287
|
for (const candidate of candidates) {
|
|
16003
|
-
if (
|
|
16288
|
+
if (existsSync32(candidate))
|
|
16004
16289
|
return candidate;
|
|
16005
16290
|
}
|
|
16006
16291
|
return candidates[0];
|
|
16007
16292
|
}
|
|
16008
16293
|
function deployModelRouterScript(opts = {}) {
|
|
16009
|
-
const targetDir = opts.targetDir ??
|
|
16010
|
-
const targetPath =
|
|
16294
|
+
const targetDir = opts.targetDir ?? join29(homedir18(), ".claude", "hooks");
|
|
16295
|
+
const targetPath = join29(targetDir, MODEL_ROUTER_SCRIPT_BASENAME);
|
|
16011
16296
|
const sourcePath = opts.sourcePath ?? resolveModelRouterSourcePath();
|
|
16012
|
-
if (!
|
|
16297
|
+
if (!existsSync32(sourcePath)) {
|
|
16013
16298
|
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "source-missing", targetPath };
|
|
16014
16299
|
}
|
|
16015
|
-
const newContent =
|
|
16016
|
-
if (
|
|
16017
|
-
const existing =
|
|
16300
|
+
const newContent = readFileSync23(sourcePath, "utf8");
|
|
16301
|
+
if (existsSync32(targetPath)) {
|
|
16302
|
+
const existing = readFileSync23(targetPath, "utf8");
|
|
16018
16303
|
if (existing === newContent) {
|
|
16019
16304
|
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "unchanged", targetPath };
|
|
16020
16305
|
}
|
|
16021
16306
|
}
|
|
16022
16307
|
if (opts.dryRun !== true) {
|
|
16023
16308
|
mkdirSync16(dirname13(targetPath), { recursive: true });
|
|
16024
|
-
|
|
16309
|
+
writeFileSync15(targetPath, newContent, { mode: 493 });
|
|
16025
16310
|
}
|
|
16026
16311
|
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "written", targetPath };
|
|
16027
16312
|
}
|
|
@@ -16045,26 +16330,26 @@ var init_meta_hooks = __esm({
|
|
|
16045
16330
|
});
|
|
16046
16331
|
|
|
16047
16332
|
// ../core/dist/skill-sync/settings-merger.js
|
|
16048
|
-
import * as
|
|
16333
|
+
import * as fs29 from "node:fs";
|
|
16049
16334
|
import * as os16 from "node:os";
|
|
16050
|
-
import * as
|
|
16335
|
+
import * as path27 from "node:path";
|
|
16051
16336
|
function claudeSettingsPath() {
|
|
16052
16337
|
const override = process.env["OLAM_CLAUDE_SETTINGS_PATH"];
|
|
16053
16338
|
if (override && override.length > 0)
|
|
16054
16339
|
return override;
|
|
16055
|
-
return
|
|
16340
|
+
return path27.join(claudeDirInternal2(), "settings.json");
|
|
16056
16341
|
}
|
|
16057
16342
|
function claudeDirInternal2() {
|
|
16058
16343
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
16059
16344
|
if (override && override.length > 0)
|
|
16060
16345
|
return override;
|
|
16061
|
-
return
|
|
16346
|
+
return path27.join(os16.homedir(), ".claude");
|
|
16062
16347
|
}
|
|
16063
16348
|
function settingsBackupDir() {
|
|
16064
16349
|
const override = process.env["OLAM_SETTINGS_BACKUP_DIR"];
|
|
16065
16350
|
if (override && override.length > 0)
|
|
16066
16351
|
return override;
|
|
16067
|
-
return
|
|
16352
|
+
return path27.join(os16.homedir(), ".olam", "state", "settings-backups");
|
|
16068
16353
|
}
|
|
16069
16354
|
function dedupeByMatcher(entries) {
|
|
16070
16355
|
const map2 = /* @__PURE__ */ new Map();
|
|
@@ -16114,28 +16399,28 @@ function tagOlam(entry) {
|
|
|
16114
16399
|
return { ...entry, [OLAM_SKILLS_MARKER]: true };
|
|
16115
16400
|
}
|
|
16116
16401
|
function readJson(file2) {
|
|
16117
|
-
return JSON.parse(
|
|
16402
|
+
return JSON.parse(fs29.readFileSync(file2, "utf-8"));
|
|
16118
16403
|
}
|
|
16119
16404
|
function rotateBackups(backupDir) {
|
|
16120
|
-
if (!
|
|
16405
|
+
if (!fs29.existsSync(backupDir))
|
|
16121
16406
|
return;
|
|
16122
|
-
const files =
|
|
16407
|
+
const files = fs29.readdirSync(backupDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, full: path27.join(backupDir, f), mtime: fs29.statSync(path27.join(backupDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
16123
16408
|
for (const f of files.slice(BACKUP_RETENTION)) {
|
|
16124
16409
|
try {
|
|
16125
|
-
|
|
16410
|
+
fs29.unlinkSync(f.full);
|
|
16126
16411
|
} catch {
|
|
16127
16412
|
}
|
|
16128
16413
|
}
|
|
16129
16414
|
}
|
|
16130
16415
|
function backupSettings() {
|
|
16131
16416
|
const src = claudeSettingsPath();
|
|
16132
|
-
if (!
|
|
16417
|
+
if (!fs29.existsSync(src))
|
|
16133
16418
|
return void 0;
|
|
16134
16419
|
const dir = settingsBackupDir();
|
|
16135
|
-
|
|
16420
|
+
fs29.mkdirSync(dir, { recursive: true });
|
|
16136
16421
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
16137
|
-
const dest =
|
|
16138
|
-
|
|
16422
|
+
const dest = path27.join(dir, `settings-${stamp}.json`);
|
|
16423
|
+
fs29.copyFileSync(src, dest);
|
|
16139
16424
|
rotateBackups(dir);
|
|
16140
16425
|
return dest;
|
|
16141
16426
|
}
|
|
@@ -16143,7 +16428,7 @@ function mergeSettings(input) {
|
|
|
16143
16428
|
const settingsPath = claudeSettingsPath();
|
|
16144
16429
|
const backupPath = backupSettings();
|
|
16145
16430
|
let base = {};
|
|
16146
|
-
if (
|
|
16431
|
+
if (fs29.existsSync(settingsPath)) {
|
|
16147
16432
|
try {
|
|
16148
16433
|
base = readJson(settingsPath);
|
|
16149
16434
|
} catch {
|
|
@@ -16211,10 +16496,10 @@ function mergeSettings(input) {
|
|
|
16211
16496
|
...input.permissionFiles.length > 0 ? { allow: [...permSet] } : {}
|
|
16212
16497
|
}
|
|
16213
16498
|
};
|
|
16214
|
-
|
|
16499
|
+
fs29.mkdirSync(path27.dirname(settingsPath), { recursive: true });
|
|
16215
16500
|
const tmp = `${settingsPath}.tmp-${process.pid}`;
|
|
16216
|
-
|
|
16217
|
-
|
|
16501
|
+
fs29.writeFileSync(tmp, JSON.stringify(next, null, 2) + "\n", { mode: 420 });
|
|
16502
|
+
fs29.renameSync(tmp, settingsPath);
|
|
16218
16503
|
return { backupPath, hooksAdded, permissionsCount: permSet.size, dualWriteDeduped, dualWriteDroppedCommands };
|
|
16219
16504
|
}
|
|
16220
16505
|
var OLAM_SKILLS_MARKER, BACKUP_RETENTION, DUAL_WRITE_DEDUP_RULES;
|
|
@@ -16270,17 +16555,17 @@ var init_schema5 = __esm({
|
|
|
16270
16555
|
});
|
|
16271
16556
|
|
|
16272
16557
|
// ../core/dist/skill-sync/per-project-override.js
|
|
16273
|
-
import { execFileSync as
|
|
16274
|
-
import * as
|
|
16275
|
-
import * as
|
|
16558
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
16559
|
+
import * as fs30 from "node:fs";
|
|
16560
|
+
import * as path28 from "node:path";
|
|
16276
16561
|
import { parse as parseYaml3 } from "yaml";
|
|
16277
16562
|
function findProjectOverride(startDir) {
|
|
16278
|
-
let dir =
|
|
16279
|
-
const root =
|
|
16563
|
+
let dir = path28.resolve(startDir);
|
|
16564
|
+
const root = path28.parse(dir).root;
|
|
16280
16565
|
while (true) {
|
|
16281
|
-
const candidate =
|
|
16282
|
-
if (
|
|
16283
|
-
const raw =
|
|
16566
|
+
const candidate = path28.join(dir, PROJECT_OVERRIDE_RELATIVE_PATH);
|
|
16567
|
+
if (fs30.existsSync(candidate) && fs30.statSync(candidate).isFile()) {
|
|
16568
|
+
const raw = fs30.readFileSync(candidate, "utf-8");
|
|
16284
16569
|
let parsed;
|
|
16285
16570
|
try {
|
|
16286
16571
|
parsed = parseYaml3(raw);
|
|
@@ -16293,7 +16578,7 @@ function findProjectOverride(startDir) {
|
|
|
16293
16578
|
}
|
|
16294
16579
|
if (dir === root)
|
|
16295
16580
|
return void 0;
|
|
16296
|
-
dir =
|
|
16581
|
+
dir = path28.dirname(dir);
|
|
16297
16582
|
}
|
|
16298
16583
|
}
|
|
16299
16584
|
function applyOverrideToArtifacts(artifacts, override) {
|
|
@@ -16313,7 +16598,7 @@ function applyPinToClone(opts) {
|
|
|
16313
16598
|
if (ref.startsWith("-")) {
|
|
16314
16599
|
throw new Error(`refuses ref "${ref}" \u2014 must not start with "-" (would be parsed as a git option)`);
|
|
16315
16600
|
}
|
|
16316
|
-
|
|
16601
|
+
execFileSync4("git", ["-C", clonePath, "checkout", "-q", ref], {
|
|
16317
16602
|
stdio: ["ignore", "ignore", "pipe"]
|
|
16318
16603
|
});
|
|
16319
16604
|
}
|
|
@@ -16323,7 +16608,7 @@ function restoreCloneToBranchHead(opts) {
|
|
|
16323
16608
|
return;
|
|
16324
16609
|
}
|
|
16325
16610
|
try {
|
|
16326
|
-
|
|
16611
|
+
execFileSync4("git", ["-C", clonePath, "checkout", "-q", branch], {
|
|
16327
16612
|
stdio: ["ignore", "ignore", "pipe"]
|
|
16328
16613
|
});
|
|
16329
16614
|
} catch {
|
|
@@ -16334,14 +16619,14 @@ var init_per_project_override = __esm({
|
|
|
16334
16619
|
"../core/dist/skill-sync/per-project-override.js"() {
|
|
16335
16620
|
"use strict";
|
|
16336
16621
|
init_schema5();
|
|
16337
|
-
PROJECT_OVERRIDE_RELATIVE_PATH =
|
|
16622
|
+
PROJECT_OVERRIDE_RELATIVE_PATH = path28.join(".olam", "skill-overrides.yaml");
|
|
16338
16623
|
}
|
|
16339
16624
|
});
|
|
16340
16625
|
|
|
16341
16626
|
// ../core/dist/lib/file-lock.js
|
|
16342
|
-
import * as
|
|
16627
|
+
import * as fs31 from "node:fs";
|
|
16343
16628
|
import * as os17 from "node:os";
|
|
16344
|
-
import * as
|
|
16629
|
+
import * as path29 from "node:path";
|
|
16345
16630
|
function defaultIsPidAlive(pid) {
|
|
16346
16631
|
try {
|
|
16347
16632
|
process.kill(pid, 0);
|
|
@@ -16356,7 +16641,7 @@ function sleep3(ms) {
|
|
|
16356
16641
|
}
|
|
16357
16642
|
function readLockMeta(lockPath) {
|
|
16358
16643
|
try {
|
|
16359
|
-
const raw =
|
|
16644
|
+
const raw = fs31.readFileSync(lockPath, "utf-8");
|
|
16360
16645
|
const parsed = JSON.parse(raw);
|
|
16361
16646
|
if (typeof parsed?.pid === "number" && typeof parsed?.hostname === "string" && typeof parsed?.timestamp === "number") {
|
|
16362
16647
|
return parsed;
|
|
@@ -16375,12 +16660,12 @@ function isLockStale(meta3, opts) {
|
|
|
16375
16660
|
}
|
|
16376
16661
|
function tryAcquireOnce(lockPath, meta3, opts) {
|
|
16377
16662
|
try {
|
|
16378
|
-
|
|
16379
|
-
const fd =
|
|
16663
|
+
fs31.mkdirSync(path29.dirname(lockPath), { recursive: true });
|
|
16664
|
+
const fd = fs31.openSync(lockPath, "wx", 384);
|
|
16380
16665
|
try {
|
|
16381
|
-
|
|
16666
|
+
fs31.writeSync(fd, JSON.stringify(meta3));
|
|
16382
16667
|
} finally {
|
|
16383
|
-
|
|
16668
|
+
fs31.closeSync(fd);
|
|
16384
16669
|
}
|
|
16385
16670
|
return true;
|
|
16386
16671
|
} catch (err) {
|
|
@@ -16390,14 +16675,14 @@ function tryAcquireOnce(lockPath, meta3, opts) {
|
|
|
16390
16675
|
const existing = readLockMeta(lockPath);
|
|
16391
16676
|
if (existing === void 0) {
|
|
16392
16677
|
try {
|
|
16393
|
-
|
|
16678
|
+
fs31.unlinkSync(lockPath);
|
|
16394
16679
|
} catch {
|
|
16395
16680
|
}
|
|
16396
16681
|
return tryAcquireOnce(lockPath, meta3, opts);
|
|
16397
16682
|
}
|
|
16398
16683
|
if (isLockStale(existing, opts)) {
|
|
16399
16684
|
try {
|
|
16400
|
-
|
|
16685
|
+
fs31.unlinkSync(lockPath);
|
|
16401
16686
|
} catch {
|
|
16402
16687
|
}
|
|
16403
16688
|
return tryAcquireOnce(lockPath, meta3, opts);
|
|
@@ -16407,7 +16692,7 @@ function tryAcquireOnce(lockPath, meta3, opts) {
|
|
|
16407
16692
|
}
|
|
16408
16693
|
async function acquireFileLock(lockDir, options = {}) {
|
|
16409
16694
|
const lockFilename = options.lockFilename ?? DEFAULT_LOCK_FILENAME;
|
|
16410
|
-
const lockPath =
|
|
16695
|
+
const lockPath = path29.join(lockDir, lockFilename);
|
|
16411
16696
|
const acquireTimeoutMs = options.acquireTimeoutMs ?? DEFAULT_ACQUIRE_TIMEOUT_MS;
|
|
16412
16697
|
const staleLockMs = options.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
|
|
16413
16698
|
const now = options.now ?? Date.now;
|
|
@@ -16427,7 +16712,7 @@ async function acquireFileLock(lockDir, options = {}) {
|
|
|
16427
16712
|
lockPath,
|
|
16428
16713
|
release: () => {
|
|
16429
16714
|
try {
|
|
16430
|
-
|
|
16715
|
+
fs31.unlinkSync(lockPath);
|
|
16431
16716
|
} catch {
|
|
16432
16717
|
}
|
|
16433
16718
|
}
|
|
@@ -16467,13 +16752,13 @@ var init_file_lock = __esm({
|
|
|
16467
16752
|
});
|
|
16468
16753
|
|
|
16469
16754
|
// ../core/dist/lib/min-version-filter.js
|
|
16470
|
-
import { existsSync as
|
|
16755
|
+
import { existsSync as existsSync35, readFileSync as readFileSync27 } from "node:fs";
|
|
16471
16756
|
function readOlamMinVersion(filepath) {
|
|
16472
|
-
if (!
|
|
16757
|
+
if (!existsSync35(filepath))
|
|
16473
16758
|
return void 0;
|
|
16474
16759
|
let text;
|
|
16475
16760
|
try {
|
|
16476
|
-
text =
|
|
16761
|
+
text = readFileSync27(filepath, "utf8");
|
|
16477
16762
|
} catch {
|
|
16478
16763
|
return void 0;
|
|
16479
16764
|
}
|
|
@@ -16531,11 +16816,11 @@ var init_min_version_filter = __esm({
|
|
|
16531
16816
|
});
|
|
16532
16817
|
|
|
16533
16818
|
// ../core/dist/skill-sync/overlay-scan.js
|
|
16534
|
-
import * as
|
|
16535
|
-
import * as
|
|
16819
|
+
import * as fs32 from "node:fs";
|
|
16820
|
+
import * as path30 from "node:path";
|
|
16536
16821
|
function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
16537
16822
|
const result = /* @__PURE__ */ new Map();
|
|
16538
|
-
if (!
|
|
16823
|
+
if (!fs32.existsSync(overlayRoot)) {
|
|
16539
16824
|
return result;
|
|
16540
16825
|
}
|
|
16541
16826
|
if (basenames.length === 0) {
|
|
@@ -16544,13 +16829,13 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
16544
16829
|
const mdFiles = [];
|
|
16545
16830
|
let overlayRootReal;
|
|
16546
16831
|
try {
|
|
16547
|
-
overlayRootReal =
|
|
16832
|
+
overlayRootReal = fs32.realpathSync(overlayRoot);
|
|
16548
16833
|
} catch {
|
|
16549
16834
|
return result;
|
|
16550
16835
|
}
|
|
16551
16836
|
for (const subdir of OVERRIDE_SUBDIRS) {
|
|
16552
|
-
const dir =
|
|
16553
|
-
if (!
|
|
16837
|
+
const dir = path30.join(overlayRoot, subdir);
|
|
16838
|
+
if (!fs32.existsSync(dir))
|
|
16554
16839
|
continue;
|
|
16555
16840
|
walkMarkdown(dir, mdFiles, caps.maxFiles);
|
|
16556
16841
|
}
|
|
@@ -16558,25 +16843,25 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
16558
16843
|
for (const filepath of mdFiles) {
|
|
16559
16844
|
let realFile;
|
|
16560
16845
|
try {
|
|
16561
|
-
realFile =
|
|
16846
|
+
realFile = fs32.realpathSync(filepath);
|
|
16562
16847
|
} catch (err) {
|
|
16563
16848
|
const code = err.code;
|
|
16564
16849
|
if (code === "ENOENT" || code === "EACCES")
|
|
16565
16850
|
continue;
|
|
16566
16851
|
throw err;
|
|
16567
16852
|
}
|
|
16568
|
-
const rel =
|
|
16569
|
-
if (rel.startsWith("..") ||
|
|
16853
|
+
const rel = path30.relative(overlayRootReal, realFile);
|
|
16854
|
+
if (rel.startsWith("..") || path30.isAbsolute(rel)) {
|
|
16570
16855
|
continue;
|
|
16571
16856
|
}
|
|
16572
16857
|
let content;
|
|
16573
16858
|
try {
|
|
16574
|
-
const stat2 =
|
|
16859
|
+
const stat2 = fs32.statSync(filepath);
|
|
16575
16860
|
totalBytes += stat2.size;
|
|
16576
16861
|
if (totalBytes > caps.maxTotalBytes) {
|
|
16577
16862
|
throw new Error(`[overlay-scan] aborted: overlay tree exceeds ${caps.maxTotalBytes} total bytes. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
|
|
16578
16863
|
}
|
|
16579
|
-
content =
|
|
16864
|
+
content = fs32.readFileSync(filepath, "utf8");
|
|
16580
16865
|
} catch (err) {
|
|
16581
16866
|
const code = err.code;
|
|
16582
16867
|
if (code === "ENOENT" || code === "EACCES") {
|
|
@@ -16584,7 +16869,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
16584
16869
|
}
|
|
16585
16870
|
throw err;
|
|
16586
16871
|
}
|
|
16587
|
-
const relpath =
|
|
16872
|
+
const relpath = path30.relative(overlayRoot, filepath).split(path30.sep).join("/");
|
|
16588
16873
|
for (const basename6 of basenames) {
|
|
16589
16874
|
if (content.includes(basename6)) {
|
|
16590
16875
|
const list = result.get(basename6) ?? [];
|
|
@@ -16598,7 +16883,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
16598
16883
|
function walkMarkdown(dir, out, cap) {
|
|
16599
16884
|
let entries;
|
|
16600
16885
|
try {
|
|
16601
|
-
entries =
|
|
16886
|
+
entries = fs32.readdirSync(dir, { withFileTypes: true });
|
|
16602
16887
|
} catch (err) {
|
|
16603
16888
|
if (err.code === "ENOENT")
|
|
16604
16889
|
return;
|
|
@@ -16608,7 +16893,7 @@ function walkMarkdown(dir, out, cap) {
|
|
|
16608
16893
|
if (out.length >= cap) {
|
|
16609
16894
|
throw new Error(`[overlay-scan] aborted: overlay tree contains > ${cap} markdown files. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
|
|
16610
16895
|
}
|
|
16611
|
-
const full =
|
|
16896
|
+
const full = path30.join(dir, entry.name);
|
|
16612
16897
|
if (entry.isSymbolicLink())
|
|
16613
16898
|
continue;
|
|
16614
16899
|
if (entry.isDirectory()) {
|
|
@@ -16633,12 +16918,12 @@ var init_overlay_scan = __esm({
|
|
|
16633
16918
|
});
|
|
16634
16919
|
|
|
16635
16920
|
// ../core/dist/skill-sync/settings-json-lock.js
|
|
16636
|
-
import * as
|
|
16921
|
+
import * as fs33 from "node:fs";
|
|
16637
16922
|
import * as os18 from "node:os";
|
|
16638
|
-
import * as
|
|
16923
|
+
import * as path31 from "node:path";
|
|
16639
16924
|
function defaultSettingsJsonLockPath() {
|
|
16640
|
-
const stateDir = process.env["OLAM_STATE_DIR"] ??
|
|
16641
|
-
return
|
|
16925
|
+
const stateDir = process.env["OLAM_STATE_DIR"] ?? path31.join(os18.homedir(), ".olam", "state");
|
|
16926
|
+
return path31.join(stateDir, SETTINGS_JSON_LOCK_FILENAME);
|
|
16642
16927
|
}
|
|
16643
16928
|
function defaultIsPidAlive2(pid) {
|
|
16644
16929
|
try {
|
|
@@ -16654,7 +16939,7 @@ function sleep4(ms) {
|
|
|
16654
16939
|
}
|
|
16655
16940
|
function readLockMeta2(lockPath) {
|
|
16656
16941
|
try {
|
|
16657
|
-
const raw =
|
|
16942
|
+
const raw = fs33.readFileSync(lockPath, "utf-8");
|
|
16658
16943
|
const parsed = JSON.parse(raw);
|
|
16659
16944
|
if (typeof parsed?.pid === "number" && typeof parsed?.hostname === "string" && typeof parsed?.timestamp === "number") {
|
|
16660
16945
|
return parsed;
|
|
@@ -16677,12 +16962,12 @@ function isLockStale2(meta3, opts) {
|
|
|
16677
16962
|
function tryAcquireOnce2(lockPath, meta3, opts) {
|
|
16678
16963
|
for (let attempt = 0; attempt <= MAX_STEAL_ATTEMPTS; attempt += 1) {
|
|
16679
16964
|
try {
|
|
16680
|
-
|
|
16681
|
-
const fd =
|
|
16965
|
+
fs33.mkdirSync(path31.dirname(lockPath), { recursive: true });
|
|
16966
|
+
const fd = fs33.openSync(lockPath, "wx", 384);
|
|
16682
16967
|
try {
|
|
16683
|
-
|
|
16968
|
+
fs33.writeSync(fd, JSON.stringify(meta3));
|
|
16684
16969
|
} finally {
|
|
16685
|
-
|
|
16970
|
+
fs33.closeSync(fd);
|
|
16686
16971
|
}
|
|
16687
16972
|
return true;
|
|
16688
16973
|
} catch (err) {
|
|
@@ -16700,9 +16985,9 @@ function tryAcquireOnce2(lockPath, meta3, opts) {
|
|
|
16700
16985
|
}
|
|
16701
16986
|
const victimPath = `${lockPath}.victim-${process.pid}-${attempt}-${Date.now()}`;
|
|
16702
16987
|
try {
|
|
16703
|
-
|
|
16988
|
+
fs33.renameSync(lockPath, victimPath);
|
|
16704
16989
|
try {
|
|
16705
|
-
|
|
16990
|
+
fs33.unlinkSync(victimPath);
|
|
16706
16991
|
} catch {
|
|
16707
16992
|
}
|
|
16708
16993
|
} catch (err) {
|
|
@@ -16734,7 +17019,7 @@ async function acquireSettingsJsonLock(options = {}) {
|
|
|
16734
17019
|
lockPath,
|
|
16735
17020
|
release: () => {
|
|
16736
17021
|
try {
|
|
16737
|
-
|
|
17022
|
+
fs33.unlinkSync(lockPath);
|
|
16738
17023
|
} catch {
|
|
16739
17024
|
}
|
|
16740
17025
|
}
|
|
@@ -16837,14 +17122,14 @@ var init_services_status = __esm({
|
|
|
16837
17122
|
|
|
16838
17123
|
// ../core/dist/skill-sources/meta-hooks-migration-snapshot.js
|
|
16839
17124
|
import * as crypto5 from "node:crypto";
|
|
16840
|
-
import * as
|
|
17125
|
+
import * as fs34 from "node:fs";
|
|
16841
17126
|
import * as os19 from "node:os";
|
|
16842
|
-
import * as
|
|
17127
|
+
import * as path32 from "node:path";
|
|
16843
17128
|
function migrationSnapshotsDir2() {
|
|
16844
17129
|
const override = process.env["OLAM_MIGRATION_SNAPSHOTS_DIR"];
|
|
16845
17130
|
if (override && override.length > 0)
|
|
16846
17131
|
return override;
|
|
16847
|
-
return
|
|
17132
|
+
return path32.join(os19.homedir(), ".olam", "state", "migration-snapshots");
|
|
16848
17133
|
}
|
|
16849
17134
|
function writeMetaHooksSnapshot(originalSettings) {
|
|
16850
17135
|
const snapshot = {
|
|
@@ -16855,11 +17140,11 @@ function writeMetaHooksSnapshot(originalSettings) {
|
|
|
16855
17140
|
};
|
|
16856
17141
|
const validated = MetaHooksMigrationSnapshotSchema.parse(snapshot);
|
|
16857
17142
|
const dir = migrationSnapshotsDir2();
|
|
16858
|
-
|
|
17143
|
+
fs34.mkdirSync(dir, { recursive: true });
|
|
16859
17144
|
const stamp = validated.takenAt.replace(/[:.]/g, "-");
|
|
16860
17145
|
const rand = crypto5.randomBytes(3).toString("hex");
|
|
16861
|
-
const file2 =
|
|
16862
|
-
|
|
17146
|
+
const file2 = path32.join(dir, `${META_HOOKS_SNAPSHOT_PREFIX}${stamp}-${process.pid}-${rand}.json`);
|
|
17147
|
+
fs34.writeFileSync(file2, JSON.stringify(validated, null, 2) + "\n", { mode: 384 });
|
|
16863
17148
|
return file2;
|
|
16864
17149
|
}
|
|
16865
17150
|
var META_HOOKS_SNAPSHOT_SCHEMA_VERSION, META_HOOKS_SNAPSHOT_PREFIX, SettingsLooseSchema, MetaHooksMigrationSnapshotSchema;
|
|
@@ -17149,7 +17434,7 @@ var init_meta_hook_injector = __esm({
|
|
|
17149
17434
|
|
|
17150
17435
|
// ../core/dist/lib/markdown-merger.js
|
|
17151
17436
|
import { createHash as createHash5 } from "node:crypto";
|
|
17152
|
-
import { readFileSync as
|
|
17437
|
+
import { readFileSync as readFileSync31, existsSync as existsSync38, statSync as statSync9 } from "node:fs";
|
|
17153
17438
|
function parseFrontmatter(text) {
|
|
17154
17439
|
const match = FM_RE2.exec(text);
|
|
17155
17440
|
if (match === null)
|
|
@@ -17278,9 +17563,9 @@ function mergeMarkdown(upstreamText, overlayText, labelForError, upstreamPath, o
|
|
|
17278
17563
|
return { merged: fmBlock !== "" ? fmBlock + mergedBody : mergedBody };
|
|
17279
17564
|
}
|
|
17280
17565
|
function sha256OfPath(p) {
|
|
17281
|
-
if (!
|
|
17566
|
+
if (!existsSync38(p) || !statSync9(p).isFile())
|
|
17282
17567
|
return "MISSING";
|
|
17283
|
-
return createHash5("sha256").update(
|
|
17568
|
+
return createHash5("sha256").update(readFileSync31(p)).digest("hex");
|
|
17284
17569
|
}
|
|
17285
17570
|
var FM_RE2, H2_RE;
|
|
17286
17571
|
var init_markdown_merger = __esm({
|
|
@@ -17292,44 +17577,44 @@ var init_markdown_merger = __esm({
|
|
|
17292
17577
|
});
|
|
17293
17578
|
|
|
17294
17579
|
// ../core/dist/skill-sync/managed-merge.js
|
|
17295
|
-
import * as
|
|
17296
|
-
import * as
|
|
17580
|
+
import * as fs35 from "node:fs";
|
|
17581
|
+
import * as path33 from "node:path";
|
|
17297
17582
|
function materializeMergedSkill(opts) {
|
|
17298
17583
|
const { sourceId, sourcePath, deployBasename, mergedContent, claudeDir: claudeDir2 } = opts;
|
|
17299
|
-
const managedDir =
|
|
17300
|
-
const sourceRoot =
|
|
17301
|
-
const managedResolved =
|
|
17302
|
-
if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot +
|
|
17584
|
+
const managedDir = path33.join(claudeDir2, ".olam-merged", sourceId, deployBasename);
|
|
17585
|
+
const sourceRoot = path33.resolve(path33.join(claudeDir2, ".olam-merged", sourceId));
|
|
17586
|
+
const managedResolved = path33.resolve(managedDir);
|
|
17587
|
+
if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot + path33.sep))) {
|
|
17303
17588
|
throw new Error(`[managed-merge] refusing to materialize: deployBasename "${deployBasename}" escapes managed root "${sourceRoot}" (resolved to "${managedResolved}")`);
|
|
17304
17589
|
}
|
|
17305
|
-
|
|
17306
|
-
const skillMdPath =
|
|
17590
|
+
fs35.mkdirSync(managedDir, { recursive: true });
|
|
17591
|
+
const skillMdPath = path33.join(managedDir, "SKILL.md");
|
|
17307
17592
|
const tmpPath = `${skillMdPath}.tmp-${process.pid}-${Date.now()}`;
|
|
17308
|
-
|
|
17309
|
-
|
|
17310
|
-
const baseEntries =
|
|
17593
|
+
fs35.writeFileSync(tmpPath, mergedContent);
|
|
17594
|
+
fs35.renameSync(tmpPath, skillMdPath);
|
|
17595
|
+
const baseEntries = fs35.readdirSync(sourcePath);
|
|
17311
17596
|
for (const entry of baseEntries) {
|
|
17312
17597
|
if (entry === "SKILL.md")
|
|
17313
17598
|
continue;
|
|
17314
|
-
const linkPath =
|
|
17315
|
-
const targetAbsolute =
|
|
17316
|
-
const targetRelative =
|
|
17599
|
+
const linkPath = path33.join(managedDir, entry);
|
|
17600
|
+
const targetAbsolute = path33.join(sourcePath, entry);
|
|
17601
|
+
const targetRelative = path33.relative(managedDir, targetAbsolute);
|
|
17317
17602
|
try {
|
|
17318
|
-
|
|
17319
|
-
|
|
17603
|
+
fs35.lstatSync(linkPath);
|
|
17604
|
+
fs35.rmSync(linkPath, { recursive: true, force: true });
|
|
17320
17605
|
} catch {
|
|
17321
17606
|
}
|
|
17322
|
-
|
|
17607
|
+
fs35.symlinkSync(targetRelative, linkPath);
|
|
17323
17608
|
}
|
|
17324
|
-
const managedEntries =
|
|
17609
|
+
const managedEntries = fs35.readdirSync(managedDir);
|
|
17325
17610
|
const baseEntrySet = new Set(baseEntries);
|
|
17326
17611
|
for (const entry of managedEntries) {
|
|
17327
17612
|
if (entry === "SKILL.md")
|
|
17328
17613
|
continue;
|
|
17329
17614
|
if (!baseEntrySet.has(entry)) {
|
|
17330
|
-
const stalePath =
|
|
17615
|
+
const stalePath = path33.join(managedDir, entry);
|
|
17331
17616
|
try {
|
|
17332
|
-
|
|
17617
|
+
fs35.rmSync(stalePath, { recursive: true, force: true });
|
|
17333
17618
|
} catch {
|
|
17334
17619
|
}
|
|
17335
17620
|
}
|
|
@@ -17337,7 +17622,7 @@ function materializeMergedSkill(opts) {
|
|
|
17337
17622
|
return managedDir;
|
|
17338
17623
|
}
|
|
17339
17624
|
function cleanMergedDir(claudeDir2) {
|
|
17340
|
-
|
|
17625
|
+
fs35.rmSync(path33.join(claudeDir2, ".olam-merged"), { recursive: true, force: true });
|
|
17341
17626
|
}
|
|
17342
17627
|
var init_managed_merge = __esm({
|
|
17343
17628
|
"../core/dist/skill-sync/managed-merge.js"() {
|
|
@@ -17435,8 +17720,8 @@ var init_prefix_rules = __esm({
|
|
|
17435
17720
|
});
|
|
17436
17721
|
|
|
17437
17722
|
// ../core/dist/skill-sync/prefix-deploy.js
|
|
17438
|
-
import * as
|
|
17439
|
-
import * as
|
|
17723
|
+
import * as fs36 from "node:fs";
|
|
17724
|
+
import * as path34 from "node:path";
|
|
17440
17725
|
function buildSourcePrefixMap(sources) {
|
|
17441
17726
|
const byId = /* @__PURE__ */ new Map();
|
|
17442
17727
|
const scopeById = /* @__PURE__ */ new Map();
|
|
@@ -17490,8 +17775,8 @@ function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir2, dryRun) {
|
|
|
17490
17775
|
continue;
|
|
17491
17776
|
}
|
|
17492
17777
|
if (artifact.kind === "skill") {
|
|
17493
|
-
const skillMdPath =
|
|
17494
|
-
const content =
|
|
17778
|
+
const skillMdPath = path34.join(artifact.sourcePath, "SKILL.md");
|
|
17779
|
+
const content = fs36.readFileSync(skillMdPath);
|
|
17495
17780
|
const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
|
|
17496
17781
|
const managedDir = materializeMergedSkill({
|
|
17497
17782
|
sourceId: artifact.sourceId,
|
|
@@ -17503,7 +17788,7 @@ function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir2, dryRun) {
|
|
|
17503
17788
|
artifact.sourcePath = managedDir;
|
|
17504
17789
|
artifact.deployBasename = renamed;
|
|
17505
17790
|
} else {
|
|
17506
|
-
const content = artifact.resolvedContent !== void 0 ? artifact.resolvedContent :
|
|
17791
|
+
const content = artifact.resolvedContent !== void 0 ? artifact.resolvedContent : fs36.readFileSync(artifact.sourcePath);
|
|
17507
17792
|
const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
|
|
17508
17793
|
artifact.resolvedContent = rewritten;
|
|
17509
17794
|
artifact.deployBasename = renamed;
|
|
@@ -17548,19 +17833,19 @@ var init_prefix_deploy = __esm({
|
|
|
17548
17833
|
});
|
|
17549
17834
|
|
|
17550
17835
|
// ../core/dist/skill-sync/resolve-source-config.js
|
|
17551
|
-
import { readFileSync as
|
|
17552
|
-
import { join as
|
|
17836
|
+
import { readFileSync as readFileSync33, existsSync as existsSync39 } from "node:fs";
|
|
17837
|
+
import { join as join38 } from "node:path";
|
|
17553
17838
|
import { parse as parseYaml4 } from "yaml";
|
|
17554
17839
|
function sourceConfigPath(clonePath) {
|
|
17555
|
-
return
|
|
17840
|
+
return join38(clonePath, "shared", "source-config.yaml");
|
|
17556
17841
|
}
|
|
17557
17842
|
function readSourceConfig(clonePath, sourceId) {
|
|
17558
|
-
const
|
|
17559
|
-
if (!
|
|
17843
|
+
const path62 = sourceConfigPath(clonePath);
|
|
17844
|
+
if (!existsSync39(path62))
|
|
17560
17845
|
return void 0;
|
|
17561
17846
|
let raw;
|
|
17562
17847
|
try {
|
|
17563
|
-
raw =
|
|
17848
|
+
raw = readFileSync33(path62, "utf-8");
|
|
17564
17849
|
} catch (err) {
|
|
17565
17850
|
emitMalformedWarning(sourceId, `read failed: ${errToMsg(err)}`);
|
|
17566
17851
|
return void 0;
|
|
@@ -17655,16 +17940,16 @@ var init_resolve_source_config = __esm({
|
|
|
17655
17940
|
});
|
|
17656
17941
|
|
|
17657
17942
|
// ../core/dist/skill-sync/engine.js
|
|
17658
|
-
import * as
|
|
17943
|
+
import * as fs37 from "node:fs";
|
|
17659
17944
|
import * as os20 from "node:os";
|
|
17660
|
-
import * as
|
|
17945
|
+
import * as path35 from "node:path";
|
|
17661
17946
|
function resolveAtlasUser(override) {
|
|
17662
17947
|
if (override)
|
|
17663
17948
|
return override;
|
|
17664
|
-
const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] ||
|
|
17665
|
-
const f =
|
|
17666
|
-
if (
|
|
17667
|
-
return
|
|
17949
|
+
const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] || path35.join(os20.homedir(), ".claude");
|
|
17950
|
+
const f = path35.join(claudeDir2, ".atlas-user");
|
|
17951
|
+
if (fs37.existsSync(f)) {
|
|
17952
|
+
return fs37.readFileSync(f, "utf-8").trim() || void 0;
|
|
17668
17953
|
}
|
|
17669
17954
|
return void 0;
|
|
17670
17955
|
}
|
|
@@ -17676,7 +17961,7 @@ async function syncSkills(opts = {}) {
|
|
|
17676
17961
|
const perSource = [];
|
|
17677
17962
|
for (const source of sources) {
|
|
17678
17963
|
const clonePath = skillSourceClonePath(source.id);
|
|
17679
|
-
if (!
|
|
17964
|
+
if (!fs37.existsSync(clonePath))
|
|
17680
17965
|
continue;
|
|
17681
17966
|
const { artifacts, subscription } = await withFileLock(clonePath, () => {
|
|
17682
17967
|
const pinRef = projectOverride?.override.pin?.[source.id];
|
|
@@ -17716,7 +18001,7 @@ async function syncSkills(opts = {}) {
|
|
|
17716
18001
|
const overlayArtifacts = memberOverlaysEnabled ? projectFilteredArtifacts.filter((a) => a.kind === "overlay") : [];
|
|
17717
18002
|
const effectiveSources = sources.map((s) => {
|
|
17718
18003
|
const clonePath = skillSourceClonePath(s.id);
|
|
17719
|
-
const sourceConfig =
|
|
18004
|
+
const sourceConfig = fs37.existsSync(clonePath) ? readSourceConfig(clonePath, s.id) : void 0;
|
|
17720
18005
|
const eff = resolveEffectivePrefix(s, sourceConfig);
|
|
17721
18006
|
const entry = {
|
|
17722
18007
|
id: s.id,
|
|
@@ -17822,13 +18107,13 @@ async function syncSkills(opts = {}) {
|
|
|
17822
18107
|
let baseContent;
|
|
17823
18108
|
let basePath;
|
|
17824
18109
|
if (overlay.targetKind === "skill") {
|
|
17825
|
-
basePath =
|
|
17826
|
-
baseContent =
|
|
18110
|
+
basePath = path35.join(base.sourcePath, "SKILL.md");
|
|
18111
|
+
baseContent = fs37.readFileSync(basePath, "utf-8");
|
|
17827
18112
|
} else {
|
|
17828
18113
|
basePath = base.sourcePath;
|
|
17829
|
-
baseContent =
|
|
18114
|
+
baseContent = fs37.readFileSync(basePath, "utf-8");
|
|
17830
18115
|
}
|
|
17831
|
-
const overlayContent =
|
|
18116
|
+
const overlayContent = fs37.readFileSync(overlay.sourcePath, "utf-8");
|
|
17832
18117
|
const label = `${overlay.sourceId}/${overlay.deployBasename}`;
|
|
17833
18118
|
const mergeResult = mergeMarkdown(baseContent, overlayContent, label, basePath, overlay.sourcePath);
|
|
17834
18119
|
if ("error" in mergeResult) {
|
|
@@ -17889,7 +18174,7 @@ async function syncSkills(opts = {}) {
|
|
|
17889
18174
|
summary.collisions = detectCollisions(baseArtifacts).collisions;
|
|
17890
18175
|
return summary;
|
|
17891
18176
|
}
|
|
17892
|
-
const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] ||
|
|
18177
|
+
const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] || path35.join(os20.homedir(), ".claude");
|
|
17893
18178
|
const overlayReferences = scanOverlayReferences(claudeDirPath, SHIM_TARGETS.map((t) => t.basename));
|
|
17894
18179
|
summary.deploy = deployArtifacts(baseArtifacts, {
|
|
17895
18180
|
installedOlamVersion,
|
|
@@ -17925,19 +18210,19 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
17925
18210
|
const result = await withSettingsJsonLock(() => {
|
|
17926
18211
|
let currentSettings = {};
|
|
17927
18212
|
let settingsExisted = false;
|
|
17928
|
-
if (
|
|
18213
|
+
if (fs37.existsSync(settingsFile)) {
|
|
17929
18214
|
settingsExisted = true;
|
|
17930
18215
|
try {
|
|
17931
|
-
const raw =
|
|
18216
|
+
const raw = fs37.readFileSync(settingsFile, "utf-8");
|
|
17932
18217
|
currentSettings = raw.trim() ? JSON.parse(raw) : {};
|
|
17933
18218
|
} catch {
|
|
17934
18219
|
try {
|
|
17935
|
-
const raw =
|
|
17936
|
-
const bakDir =
|
|
17937
|
-
|
|
18220
|
+
const raw = fs37.readFileSync(settingsFile);
|
|
18221
|
+
const bakDir = path35.join(path35.dirname(settingsFile), ".malformed-backups");
|
|
18222
|
+
fs37.mkdirSync(bakDir, { recursive: true });
|
|
17938
18223
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
17939
|
-
const bakFile =
|
|
17940
|
-
|
|
18224
|
+
const bakFile = path35.join(bakDir, `settings.json.malformed.${stamp}.bak`);
|
|
18225
|
+
fs37.writeFileSync(bakFile, raw, { mode: 384 });
|
|
17941
18226
|
snapshotError = `settings.json was malformed; original bytes preserved at ${bakFile}`;
|
|
17942
18227
|
} catch (bakErr) {
|
|
17943
18228
|
snapshotError = `settings.json malformed AND .bak write failed: ${bakErr instanceof Error ? bakErr.message : String(bakErr)}`;
|
|
@@ -17977,10 +18262,10 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
17977
18262
|
} catch {
|
|
17978
18263
|
}
|
|
17979
18264
|
}
|
|
17980
|
-
|
|
18265
|
+
fs37.mkdirSync(path35.dirname(settingsFile), { recursive: true });
|
|
17981
18266
|
const tmpPath = `${settingsFile}.tmp-${process.pid}-${Date.now()}`;
|
|
17982
|
-
|
|
17983
|
-
|
|
18267
|
+
fs37.writeFileSync(tmpPath, JSON.stringify(inject.nextSettings, null, 2) + "\n");
|
|
18268
|
+
fs37.renameSync(tmpPath, settingsFile);
|
|
17984
18269
|
return inject;
|
|
17985
18270
|
}, { reason: `syncSkills meta-hook injection (mode=${mode})` });
|
|
17986
18271
|
let scriptDeploy;
|
|
@@ -17988,7 +18273,7 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
17988
18273
|
if (modelRouterTargeted) {
|
|
17989
18274
|
try {
|
|
17990
18275
|
scriptDeploy = deployModelRouterScript({
|
|
17991
|
-
targetDir:
|
|
18276
|
+
targetDir: path35.join(claudeDir(), "hooks")
|
|
17992
18277
|
});
|
|
17993
18278
|
} catch (err) {
|
|
17994
18279
|
scriptDeploy = {
|
|
@@ -18039,19 +18324,19 @@ var init_engine = __esm({
|
|
|
18039
18324
|
});
|
|
18040
18325
|
|
|
18041
18326
|
// ../core/dist/skill-sync/shadow-backup-manager.js
|
|
18042
|
-
import * as
|
|
18043
|
-
import * as
|
|
18327
|
+
import * as fs38 from "node:fs";
|
|
18328
|
+
import * as path36 from "node:path";
|
|
18044
18329
|
function listShadowBackups(opts = {}) {
|
|
18045
18330
|
const claude = opts.claudeDirOverride ?? claudeDir();
|
|
18046
18331
|
const now = opts.now ?? Date.now();
|
|
18047
18332
|
const out = [];
|
|
18048
18333
|
for (const bucket of SHADOW_BACKUP_BUCKETS) {
|
|
18049
|
-
const bucketDir =
|
|
18050
|
-
if (!
|
|
18334
|
+
const bucketDir = path36.join(claude, bucket);
|
|
18335
|
+
if (!fs38.existsSync(bucketDir))
|
|
18051
18336
|
continue;
|
|
18052
18337
|
let entries;
|
|
18053
18338
|
try {
|
|
18054
|
-
entries =
|
|
18339
|
+
entries = fs38.readdirSync(bucketDir);
|
|
18055
18340
|
} catch {
|
|
18056
18341
|
continue;
|
|
18057
18342
|
}
|
|
@@ -18062,11 +18347,11 @@ function listShadowBackups(opts = {}) {
|
|
|
18062
18347
|
const epochSeconds = Number.parseInt(match[1], 10);
|
|
18063
18348
|
if (!Number.isFinite(epochSeconds) || epochSeconds < 0)
|
|
18064
18349
|
continue;
|
|
18065
|
-
const full =
|
|
18350
|
+
const full = path36.join(bucketDir, name);
|
|
18066
18351
|
let sizeBytes = 0;
|
|
18067
18352
|
let isDir = false;
|
|
18068
18353
|
try {
|
|
18069
|
-
const st =
|
|
18354
|
+
const st = fs38.statSync(full);
|
|
18070
18355
|
isDir = st.isDirectory();
|
|
18071
18356
|
if (!isDir)
|
|
18072
18357
|
sizeBytes = st.size;
|
|
@@ -18079,7 +18364,7 @@ function listShadowBackups(opts = {}) {
|
|
|
18079
18364
|
bucket,
|
|
18080
18365
|
basename: name,
|
|
18081
18366
|
originalBasename,
|
|
18082
|
-
originalPath:
|
|
18367
|
+
originalPath: path36.join(bucketDir, originalBasename),
|
|
18083
18368
|
epochSeconds,
|
|
18084
18369
|
ageMs: now - epochSeconds * 1e3,
|
|
18085
18370
|
sizeBytes,
|
|
@@ -18124,9 +18409,9 @@ function pruneShadowBackups(opts) {
|
|
|
18124
18409
|
if (!opts.dryRun) {
|
|
18125
18410
|
try {
|
|
18126
18411
|
if (b.isDir) {
|
|
18127
|
-
|
|
18412
|
+
fs38.rmSync(b.path, { recursive: true, force: true });
|
|
18128
18413
|
} else {
|
|
18129
|
-
|
|
18414
|
+
fs38.unlinkSync(b.path);
|
|
18130
18415
|
}
|
|
18131
18416
|
} catch {
|
|
18132
18417
|
skipped.push(b);
|
|
@@ -18138,29 +18423,29 @@ function pruneShadowBackups(opts) {
|
|
|
18138
18423
|
return { deleted, skipped };
|
|
18139
18424
|
}
|
|
18140
18425
|
function restoreShadowBackup(opts) {
|
|
18141
|
-
const abs =
|
|
18142
|
-
if (!
|
|
18426
|
+
const abs = path36.resolve(opts.backupPath);
|
|
18427
|
+
if (!fs38.existsSync(abs)) {
|
|
18143
18428
|
throw new Error(`backup file not found: ${abs}`);
|
|
18144
18429
|
}
|
|
18145
|
-
const basename6 =
|
|
18430
|
+
const basename6 = path36.basename(abs);
|
|
18146
18431
|
const match = SHADOW_BACKUP_SUFFIX_RE.exec(basename6);
|
|
18147
18432
|
if (!match) {
|
|
18148
18433
|
throw new Error(`not a shadow-backup file (basename "${basename6}" does not match \`.shadow-backup-<epoch>\`): ${abs}`);
|
|
18149
18434
|
}
|
|
18150
18435
|
const originalBasename = basename6.slice(0, basename6.length - match[0].length);
|
|
18151
|
-
const originalPath =
|
|
18152
|
-
if (
|
|
18436
|
+
const originalPath = path36.join(path36.dirname(abs), originalBasename);
|
|
18437
|
+
if (fs38.existsSync(originalPath) && !opts.force) {
|
|
18153
18438
|
throw new Error(`original path already occupied: ${originalPath}. Move/rename it first OR re-run with --force.`);
|
|
18154
18439
|
}
|
|
18155
|
-
if (opts.force &&
|
|
18156
|
-
const existingStat =
|
|
18440
|
+
if (opts.force && fs38.existsSync(originalPath)) {
|
|
18441
|
+
const existingStat = fs38.statSync(originalPath);
|
|
18157
18442
|
if (existingStat.isDirectory()) {
|
|
18158
|
-
|
|
18443
|
+
fs38.rmSync(originalPath, { recursive: true, force: true });
|
|
18159
18444
|
} else {
|
|
18160
|
-
|
|
18445
|
+
fs38.unlinkSync(originalPath);
|
|
18161
18446
|
}
|
|
18162
18447
|
}
|
|
18163
|
-
|
|
18448
|
+
fs38.renameSync(abs, originalPath);
|
|
18164
18449
|
return { restoredTo: originalPath };
|
|
18165
18450
|
}
|
|
18166
18451
|
var SHADOW_BACKUP_BUCKETS, SHADOW_BACKUP_SUFFIX_RE;
|
|
@@ -18174,14 +18459,14 @@ var init_shadow_backup_manager = __esm({
|
|
|
18174
18459
|
});
|
|
18175
18460
|
|
|
18176
18461
|
// ../core/dist/skill-sources/doctor-checks.js
|
|
18177
|
-
import * as
|
|
18178
|
-
import * as
|
|
18462
|
+
import * as fs39 from "node:fs";
|
|
18463
|
+
import * as path37 from "node:path";
|
|
18179
18464
|
import * as os21 from "node:os";
|
|
18180
18465
|
function claudeDirInternal3() {
|
|
18181
18466
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
18182
18467
|
if (override && override.length > 0)
|
|
18183
18468
|
return override;
|
|
18184
|
-
return
|
|
18469
|
+
return path37.join(os21.homedir(), ".claude");
|
|
18185
18470
|
}
|
|
18186
18471
|
function checkStateFileParse() {
|
|
18187
18472
|
const filePath = globalConfigPath();
|
|
@@ -18190,11 +18475,11 @@ function checkStateFileParse() {
|
|
|
18190
18475
|
healthy: true,
|
|
18191
18476
|
description: `~/.olam state file (${filePath})`
|
|
18192
18477
|
};
|
|
18193
|
-
if (!
|
|
18478
|
+
if (!fs39.existsSync(filePath)) {
|
|
18194
18479
|
result.details = ["(file does not yet exist \u2014 will be created on first write)"];
|
|
18195
18480
|
return result;
|
|
18196
18481
|
}
|
|
18197
|
-
const raw =
|
|
18482
|
+
const raw = fs39.readFileSync(filePath, "utf-8");
|
|
18198
18483
|
let parsed;
|
|
18199
18484
|
try {
|
|
18200
18485
|
parsed = JSON.parse(raw);
|
|
@@ -18204,8 +18489,8 @@ function checkStateFileParse() {
|
|
|
18204
18489
|
result.details = [err instanceof Error ? err.message : String(err)];
|
|
18205
18490
|
result.repair = () => {
|
|
18206
18491
|
const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
|
|
18207
|
-
|
|
18208
|
-
|
|
18492
|
+
fs39.renameSync(filePath, aside);
|
|
18493
|
+
fs39.writeFileSync(filePath, JSON.stringify({ schemaVersion: 1, repos: [], runbooks: [], skillSources: [] }, null, 2));
|
|
18209
18494
|
};
|
|
18210
18495
|
return result;
|
|
18211
18496
|
}
|
|
@@ -18214,18 +18499,20 @@ function checkStateFileParse() {
|
|
|
18214
18499
|
result.healthy = false;
|
|
18215
18500
|
result.issue = "state file does not match GlobalConfigSchema";
|
|
18216
18501
|
result.details = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
|
|
18502
|
+
const salvaged = quarantineGlobalConfig(parsed);
|
|
18503
|
+
const droppedCount = salvaged?.drops.length ?? 0;
|
|
18504
|
+
if (salvaged !== null) {
|
|
18505
|
+
result.details.push(`auto-fix will keep ${salvaged.value.skillSources.length} skill-source(s), ${salvaged.value.repos.length} repo(s), ${salvaged.value.runbooks.length} runbook(s); dropping ${droppedCount} invalid entr${droppedCount === 1 ? "y" : "ies"}.`);
|
|
18506
|
+
} else {
|
|
18507
|
+
result.details.push("auto-fix cannot salvage any entries (top-level corruption) \u2014 will reset to empty.");
|
|
18508
|
+
}
|
|
18217
18509
|
result.repair = () => {
|
|
18218
18510
|
const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
|
|
18219
|
-
|
|
18511
|
+
fs39.copyFileSync(filePath, aside);
|
|
18220
18512
|
const base = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
18221
|
-
const
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
repos: [],
|
|
18225
|
-
runbooks: [],
|
|
18226
|
-
skillSources: []
|
|
18227
|
-
};
|
|
18228
|
-
fs37.writeFileSync(filePath, JSON.stringify(next, null, 2));
|
|
18513
|
+
const recovered = quarantineGlobalConfig(parsed);
|
|
18514
|
+
const next = recovered !== null ? { ...base, ...recovered.value } : { ...base, schemaVersion: 1, repos: [], runbooks: [], skillSources: [] };
|
|
18515
|
+
fs39.writeFileSync(filePath, JSON.stringify(next, null, 2));
|
|
18229
18516
|
};
|
|
18230
18517
|
return result;
|
|
18231
18518
|
}
|
|
@@ -18236,16 +18523,16 @@ function checkDanglingSymlinks() {
|
|
|
18236
18523
|
const buckets = ["commands", "agents", "skills", "scripts", "rules"];
|
|
18237
18524
|
const dangling = [];
|
|
18238
18525
|
for (const bucket of buckets) {
|
|
18239
|
-
const dir =
|
|
18240
|
-
if (!
|
|
18526
|
+
const dir = path37.join(claude, bucket);
|
|
18527
|
+
if (!fs39.existsSync(dir))
|
|
18241
18528
|
continue;
|
|
18242
|
-
for (const name of
|
|
18243
|
-
const linkPath =
|
|
18529
|
+
for (const name of fs39.readdirSync(dir)) {
|
|
18530
|
+
const linkPath = path37.join(dir, name);
|
|
18244
18531
|
try {
|
|
18245
|
-
const lst =
|
|
18532
|
+
const lst = fs39.lstatSync(linkPath);
|
|
18246
18533
|
if (!lst.isSymbolicLink())
|
|
18247
18534
|
continue;
|
|
18248
|
-
if (!
|
|
18535
|
+
if (!fs39.existsSync(linkPath)) {
|
|
18249
18536
|
dangling.push(linkPath);
|
|
18250
18537
|
}
|
|
18251
18538
|
} catch {
|
|
@@ -18263,7 +18550,7 @@ function checkDanglingSymlinks() {
|
|
|
18263
18550
|
result.repair = () => {
|
|
18264
18551
|
for (const p of dangling) {
|
|
18265
18552
|
try {
|
|
18266
|
-
|
|
18553
|
+
fs39.unlinkSync(p);
|
|
18267
18554
|
} catch {
|
|
18268
18555
|
}
|
|
18269
18556
|
}
|
|
@@ -18278,19 +18565,19 @@ function checkOrphanedSnapshots() {
|
|
|
18278
18565
|
healthy: true,
|
|
18279
18566
|
description: `orphaned migration snapshots under ${dir}`
|
|
18280
18567
|
};
|
|
18281
|
-
if (!
|
|
18568
|
+
if (!fs39.existsSync(dir)) {
|
|
18282
18569
|
return result;
|
|
18283
18570
|
}
|
|
18284
18571
|
const orphans = [];
|
|
18285
|
-
for (const name of
|
|
18572
|
+
for (const name of fs39.readdirSync(dir)) {
|
|
18286
18573
|
if (!name.endsWith(".json"))
|
|
18287
18574
|
continue;
|
|
18288
|
-
const full =
|
|
18575
|
+
const full = path37.join(dir, name);
|
|
18289
18576
|
try {
|
|
18290
|
-
const stat2 =
|
|
18577
|
+
const stat2 = fs39.statSync(full);
|
|
18291
18578
|
if (!stat2.isFile())
|
|
18292
18579
|
continue;
|
|
18293
|
-
const raw =
|
|
18580
|
+
const raw = fs39.readFileSync(full, "utf-8");
|
|
18294
18581
|
let parsed;
|
|
18295
18582
|
try {
|
|
18296
18583
|
parsed = JSON.parse(raw);
|
|
@@ -18315,7 +18602,7 @@ function checkOrphanedSnapshots() {
|
|
|
18315
18602
|
result.repair = () => {
|
|
18316
18603
|
for (const o of orphans) {
|
|
18317
18604
|
try {
|
|
18318
|
-
|
|
18605
|
+
fs39.unlinkSync(o.path);
|
|
18319
18606
|
} catch {
|
|
18320
18607
|
}
|
|
18321
18608
|
}
|
|
@@ -18330,12 +18617,12 @@ function checkSentinelDrift() {
|
|
|
18330
18617
|
healthy: true,
|
|
18331
18618
|
description: `olam-skills sentinel block in ${filePath}`
|
|
18332
18619
|
};
|
|
18333
|
-
if (!
|
|
18620
|
+
if (!fs39.existsSync(filePath)) {
|
|
18334
18621
|
return result;
|
|
18335
18622
|
}
|
|
18336
18623
|
let parsed;
|
|
18337
18624
|
try {
|
|
18338
|
-
parsed = JSON.parse(
|
|
18625
|
+
parsed = JSON.parse(fs39.readFileSync(filePath, "utf-8"));
|
|
18339
18626
|
} catch {
|
|
18340
18627
|
return result;
|
|
18341
18628
|
}
|
|
@@ -18376,7 +18663,7 @@ function checkSentinelDrift() {
|
|
|
18376
18663
|
backupSettings();
|
|
18377
18664
|
} catch {
|
|
18378
18665
|
}
|
|
18379
|
-
const next = JSON.parse(
|
|
18666
|
+
const next = JSON.parse(fs39.readFileSync(filePath, "utf-8"));
|
|
18380
18667
|
if (!next.hooks)
|
|
18381
18668
|
return;
|
|
18382
18669
|
for (const stage of Object.keys(next.hooks)) {
|
|
@@ -18399,7 +18686,7 @@ function checkSentinelDrift() {
|
|
|
18399
18686
|
return bad === void 0;
|
|
18400
18687
|
});
|
|
18401
18688
|
}
|
|
18402
|
-
|
|
18689
|
+
fs39.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
18403
18690
|
};
|
|
18404
18691
|
}
|
|
18405
18692
|
return result;
|
|
@@ -18423,8 +18710,8 @@ function checkMemberNameMissing() {
|
|
|
18423
18710
|
return result;
|
|
18424
18711
|
}
|
|
18425
18712
|
const claudeDir2 = claudeDirInternal3();
|
|
18426
|
-
const atlasUserPath =
|
|
18427
|
-
const value =
|
|
18713
|
+
const atlasUserPath = path37.join(claudeDir2, ".atlas-user");
|
|
18714
|
+
const value = fs39.existsSync(atlasUserPath) ? fs39.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
18428
18715
|
if (value.length > 0) {
|
|
18429
18716
|
result.details = [`atlas-user: ${value}`];
|
|
18430
18717
|
return result;
|
|
@@ -18432,10 +18719,10 @@ function checkMemberNameMissing() {
|
|
|
18432
18719
|
result.healthy = false;
|
|
18433
18720
|
result.issue = "atlas-toolbox source registered but ~/.claude/.atlas-user not set";
|
|
18434
18721
|
const clonePath = skillSourceClonePath(atlasSource.id);
|
|
18435
|
-
const membersDir =
|
|
18436
|
-
const existing =
|
|
18722
|
+
const membersDir = path37.join(clonePath, "members");
|
|
18723
|
+
const existing = fs39.existsSync(membersDir) ? fs39.readdirSync(membersDir).filter((e) => {
|
|
18437
18724
|
try {
|
|
18438
|
-
return
|
|
18725
|
+
return fs39.statSync(path37.join(membersDir, e)).isDirectory();
|
|
18439
18726
|
} catch {
|
|
18440
18727
|
return false;
|
|
18441
18728
|
}
|
|
@@ -18449,8 +18736,8 @@ function checkMemberNameMissing() {
|
|
|
18449
18736
|
}
|
|
18450
18737
|
function checkMemberOverlayDrift() {
|
|
18451
18738
|
const claudeDir2 = claudeDirInternal3();
|
|
18452
|
-
const atlasUserPath =
|
|
18453
|
-
const atlasUser =
|
|
18739
|
+
const atlasUserPath = path37.join(claudeDir2, ".atlas-user");
|
|
18740
|
+
const atlasUser = fs39.existsSync(atlasUserPath) ? fs39.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
18454
18741
|
if (atlasUser.length === 0) {
|
|
18455
18742
|
return [];
|
|
18456
18743
|
}
|
|
@@ -18466,26 +18753,26 @@ function checkMemberOverlayDrift() {
|
|
|
18466
18753
|
const clonePath = skillSourceClonePath(atlasSource.id);
|
|
18467
18754
|
const results = [];
|
|
18468
18755
|
for (const kind of ["skills", "agents"]) {
|
|
18469
|
-
const localRoot =
|
|
18470
|
-
if (!
|
|
18756
|
+
const localRoot = path37.join(claudeDir2, `${kind}.overrides`);
|
|
18757
|
+
if (!fs39.existsSync(localRoot))
|
|
18471
18758
|
continue;
|
|
18472
18759
|
let entries;
|
|
18473
18760
|
try {
|
|
18474
|
-
entries =
|
|
18761
|
+
entries = fs39.readdirSync(localRoot);
|
|
18475
18762
|
} catch {
|
|
18476
18763
|
continue;
|
|
18477
18764
|
}
|
|
18478
18765
|
for (const entry of entries) {
|
|
18479
|
-
const localFile =
|
|
18766
|
+
const localFile = path37.join(localRoot, entry);
|
|
18480
18767
|
let stat2;
|
|
18481
18768
|
try {
|
|
18482
|
-
stat2 =
|
|
18769
|
+
stat2 = fs39.statSync(localFile);
|
|
18483
18770
|
} catch {
|
|
18484
18771
|
continue;
|
|
18485
18772
|
}
|
|
18486
18773
|
if (!stat2.isFile())
|
|
18487
18774
|
continue;
|
|
18488
|
-
const cloneFile =
|
|
18775
|
+
const cloneFile = path37.join(clonePath, "members", atlasUser, `${kind}.overrides`, entry);
|
|
18489
18776
|
const localSha = sha256OfPath(localFile);
|
|
18490
18777
|
const cloneSha = sha256OfPath(cloneFile);
|
|
18491
18778
|
if (localSha === cloneSha) {
|
|
@@ -18540,16 +18827,16 @@ var init_doctor_checks = __esm({
|
|
|
18540
18827
|
});
|
|
18541
18828
|
|
|
18542
18829
|
// ../core/dist/skill-sync/detect-pull-deploy-drift.js
|
|
18543
|
-
import * as
|
|
18544
|
-
import * as
|
|
18830
|
+
import * as fs40 from "node:fs";
|
|
18831
|
+
import * as path38 from "node:path";
|
|
18545
18832
|
function deployedSymlinkBasenames(bucketDir) {
|
|
18546
18833
|
const result = /* @__PURE__ */ new Set();
|
|
18547
|
-
if (!
|
|
18834
|
+
if (!fs40.existsSync(bucketDir))
|
|
18548
18835
|
return result;
|
|
18549
|
-
for (const name of
|
|
18550
|
-
const p =
|
|
18836
|
+
for (const name of fs40.readdirSync(bucketDir)) {
|
|
18837
|
+
const p = path38.join(bucketDir, name);
|
|
18551
18838
|
try {
|
|
18552
|
-
if (
|
|
18839
|
+
if (fs40.lstatSync(p).isSymbolicLink()) {
|
|
18553
18840
|
result.add(name);
|
|
18554
18841
|
}
|
|
18555
18842
|
} catch {
|
|
@@ -18560,7 +18847,7 @@ function deployedSymlinkBasenames(bucketDir) {
|
|
|
18560
18847
|
function detectPullDeployDrift(opts) {
|
|
18561
18848
|
const { clonePath, sourceId, atlasUser } = opts;
|
|
18562
18849
|
const { artifacts } = resolveSourceArtifacts({ sourceId, clonePath, atlasUser });
|
|
18563
|
-
const sourceConfig =
|
|
18850
|
+
const sourceConfig = fs40.existsSync(clonePath) ? readSourceConfig(clonePath, sourceId) : void 0;
|
|
18564
18851
|
const eff = resolveEffectivePrefix(opts.operatorSource ?? {}, sourceConfig);
|
|
18565
18852
|
const prefixEntry = { id: sourceId };
|
|
18566
18853
|
if (eff.prefix !== void 0)
|
|
@@ -18597,7 +18884,7 @@ function detectPullDeployDrift(opts) {
|
|
|
18597
18884
|
let total = 0;
|
|
18598
18885
|
for (const kind of Object.keys(KIND_TO_BUCKET)) {
|
|
18599
18886
|
const bucket = KIND_TO_BUCKET[kind];
|
|
18600
|
-
const bucketDir =
|
|
18887
|
+
const bucketDir = path38.join(claude, bucket);
|
|
18601
18888
|
const deployed = deployedSymlinkBasenames(bucketDir);
|
|
18602
18889
|
const cloneBasenames = cloneByKind[kind];
|
|
18603
18890
|
const added = [];
|
|
@@ -18648,11 +18935,13 @@ __export(skill_sources_exports, {
|
|
|
18648
18935
|
PROJECT_OVERRIDE_RELATIVE_PATH: () => PROJECT_OVERRIDE_RELATIVE_PATH,
|
|
18649
18936
|
SKILL_SOURCES_AUDIT_LOG_FILENAME: () => SKILL_SOURCES_AUDIT_LOG_FILENAME,
|
|
18650
18937
|
SKILL_SOURCE_ID_LENGTH: () => SKILL_SOURCE_ID_LENGTH,
|
|
18938
|
+
SOURCE_SIDECAR_FILENAME: () => SOURCE_SIDECAR_FILENAME,
|
|
18651
18939
|
SkillOverrideSchema: () => SkillOverrideSchema,
|
|
18652
18940
|
SkillSourceGitError: () => SkillSourceGitError,
|
|
18653
18941
|
SkillSourceSchema: () => SkillSourceSchema,
|
|
18654
18942
|
SourceConfigSchema: () => SourceConfigSchema,
|
|
18655
18943
|
SourceConfigSnapshotSchema: () => SourceConfigSnapshotSchema,
|
|
18944
|
+
SourceSidecarSchema: () => SourceSidecarSchema,
|
|
18656
18945
|
TrustActionSchema: () => TrustActionSchema,
|
|
18657
18946
|
TrustAuditEntrySchema: () => TrustAuditEntrySchema,
|
|
18658
18947
|
TrustMethodSchema: () => TrustMethodSchema,
|
|
@@ -18694,7 +18983,10 @@ __export(skill_sources_exports, {
|
|
|
18694
18983
|
readLatestMigrationSnapshot: () => readLatestMigrationSnapshot,
|
|
18695
18984
|
readMigrationSnapshotFromPath: () => readMigrationSnapshotFromPath,
|
|
18696
18985
|
readSourceConfig: () => readSourceConfig,
|
|
18986
|
+
readSourceSidecar: () => readSourceSidecar,
|
|
18697
18987
|
readTrustAuditLog: () => readTrustAuditLog,
|
|
18988
|
+
reconcileIfRegistryEmpty: () => reconcileIfRegistryEmpty,
|
|
18989
|
+
reconcileSkillSources: () => reconcileSkillSources,
|
|
18698
18990
|
redactUrl: () => redactUrl2,
|
|
18699
18991
|
removeSkillSource: () => removeSkillSource,
|
|
18700
18992
|
removeSkillSourceClone: () => removeSkillSourceClone,
|
|
@@ -18713,11 +19005,13 @@ __export(skill_sources_exports, {
|
|
|
18713
19005
|
skillsHookSettingsPathFor: () => settingsPathFor,
|
|
18714
19006
|
sourceConfigPath: () => sourceConfigPath,
|
|
18715
19007
|
sourceConfigsEqual: () => sourceConfigsEqual,
|
|
19008
|
+
sourceSidecarPath: () => sourceSidecarPath,
|
|
18716
19009
|
syncSkills: () => syncSkills,
|
|
18717
19010
|
uninstallSkillsHookFromFile: () => uninstallSkillsHookFromFile,
|
|
18718
19011
|
updateSkillSource: () => updateSkillSource,
|
|
18719
19012
|
withFileLock: () => withFileLock,
|
|
18720
|
-
writeMigrationSnapshot: () => writeMigrationSnapshot
|
|
19013
|
+
writeMigrationSnapshot: () => writeMigrationSnapshot,
|
|
19014
|
+
writeSourceSidecar: () => writeSourceSidecar
|
|
18721
19015
|
});
|
|
18722
19016
|
var init_skill_sources = __esm({
|
|
18723
19017
|
"../core/dist/skill-sources/index.js"() {
|
|
@@ -18725,6 +19019,8 @@ var init_skill_sources = __esm({
|
|
|
18725
19019
|
init_schema3();
|
|
18726
19020
|
init_store3();
|
|
18727
19021
|
init_clone();
|
|
19022
|
+
init_source_file();
|
|
19023
|
+
init_reconcile();
|
|
18728
19024
|
init_hook_template();
|
|
18729
19025
|
init_hook_install();
|
|
18730
19026
|
init_migration_snapshot();
|
|
@@ -19530,10 +19826,10 @@ function mergeDefs(...defs) {
|
|
|
19530
19826
|
function cloneDef(schema) {
|
|
19531
19827
|
return mergeDefs(schema._zod.def);
|
|
19532
19828
|
}
|
|
19533
|
-
function getElementAtPath(obj,
|
|
19534
|
-
if (!
|
|
19829
|
+
function getElementAtPath(obj, path62) {
|
|
19830
|
+
if (!path62)
|
|
19535
19831
|
return obj;
|
|
19536
|
-
return
|
|
19832
|
+
return path62.reduce((acc, key) => acc?.[key], obj);
|
|
19537
19833
|
}
|
|
19538
19834
|
function promiseAllObject(promisesObj) {
|
|
19539
19835
|
const keys = Object.keys(promisesObj);
|
|
@@ -19942,11 +20238,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
19942
20238
|
}
|
|
19943
20239
|
return false;
|
|
19944
20240
|
}
|
|
19945
|
-
function prefixIssues(
|
|
20241
|
+
function prefixIssues(path62, issues) {
|
|
19946
20242
|
return issues.map((iss) => {
|
|
19947
20243
|
var _a3;
|
|
19948
20244
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
19949
|
-
iss.path.unshift(
|
|
20245
|
+
iss.path.unshift(path62);
|
|
19950
20246
|
return iss;
|
|
19951
20247
|
});
|
|
19952
20248
|
}
|
|
@@ -20093,16 +20389,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
20093
20389
|
}
|
|
20094
20390
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
20095
20391
|
const fieldErrors = { _errors: [] };
|
|
20096
|
-
const processError = (error52,
|
|
20392
|
+
const processError = (error52, path62 = []) => {
|
|
20097
20393
|
for (const issue2 of error52.issues) {
|
|
20098
20394
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
20099
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
20395
|
+
issue2.errors.map((issues) => processError({ issues }, [...path62, ...issue2.path]));
|
|
20100
20396
|
} else if (issue2.code === "invalid_key") {
|
|
20101
|
-
processError({ issues: issue2.issues }, [...
|
|
20397
|
+
processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
|
|
20102
20398
|
} else if (issue2.code === "invalid_element") {
|
|
20103
|
-
processError({ issues: issue2.issues }, [...
|
|
20399
|
+
processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
|
|
20104
20400
|
} else {
|
|
20105
|
-
const fullpath = [...
|
|
20401
|
+
const fullpath = [...path62, ...issue2.path];
|
|
20106
20402
|
if (fullpath.length === 0) {
|
|
20107
20403
|
fieldErrors._errors.push(mapper(issue2));
|
|
20108
20404
|
} else {
|
|
@@ -20129,17 +20425,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
20129
20425
|
}
|
|
20130
20426
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
20131
20427
|
const result = { errors: [] };
|
|
20132
|
-
const processError = (error52,
|
|
20428
|
+
const processError = (error52, path62 = []) => {
|
|
20133
20429
|
var _a3, _b;
|
|
20134
20430
|
for (const issue2 of error52.issues) {
|
|
20135
20431
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
20136
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
20432
|
+
issue2.errors.map((issues) => processError({ issues }, [...path62, ...issue2.path]));
|
|
20137
20433
|
} else if (issue2.code === "invalid_key") {
|
|
20138
|
-
processError({ issues: issue2.issues }, [...
|
|
20434
|
+
processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
|
|
20139
20435
|
} else if (issue2.code === "invalid_element") {
|
|
20140
|
-
processError({ issues: issue2.issues }, [...
|
|
20436
|
+
processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
|
|
20141
20437
|
} else {
|
|
20142
|
-
const fullpath = [...
|
|
20438
|
+
const fullpath = [...path62, ...issue2.path];
|
|
20143
20439
|
if (fullpath.length === 0) {
|
|
20144
20440
|
result.errors.push(mapper(issue2));
|
|
20145
20441
|
continue;
|
|
@@ -20171,8 +20467,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
20171
20467
|
}
|
|
20172
20468
|
function toDotPath(_path) {
|
|
20173
20469
|
const segs = [];
|
|
20174
|
-
const
|
|
20175
|
-
for (const seg of
|
|
20470
|
+
const path62 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
20471
|
+
for (const seg of path62) {
|
|
20176
20472
|
if (typeof seg === "number")
|
|
20177
20473
|
segs.push(`[${seg}]`);
|
|
20178
20474
|
else if (typeof seg === "symbol")
|
|
@@ -32864,13 +33160,13 @@ function resolveRef(ref, ctx) {
|
|
|
32864
33160
|
if (!ref.startsWith("#")) {
|
|
32865
33161
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
32866
33162
|
}
|
|
32867
|
-
const
|
|
32868
|
-
if (
|
|
33163
|
+
const path62 = ref.slice(1).split("/").filter(Boolean);
|
|
33164
|
+
if (path62.length === 0) {
|
|
32869
33165
|
return ctx.rootSchema;
|
|
32870
33166
|
}
|
|
32871
33167
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
32872
|
-
if (
|
|
32873
|
-
const key =
|
|
33168
|
+
if (path62[0] === defsKey) {
|
|
33169
|
+
const key = path62[1];
|
|
32874
33170
|
if (!key || !ctx.defs[key]) {
|
|
32875
33171
|
throw new Error(`Reference not found: ${ref}`);
|
|
32876
33172
|
}
|
|
@@ -39370,8 +39666,8 @@ var initSkill = defineSkill({
|
|
|
39370
39666
|
// ../mcp-server/src/lib/validated-tool.ts
|
|
39371
39667
|
function formatIssues(issues) {
|
|
39372
39668
|
return issues.map((issue2) => {
|
|
39373
|
-
const
|
|
39374
|
-
return `${
|
|
39669
|
+
const path62 = issue2.path.length > 0 ? issue2.path.join(".") : "<root>";
|
|
39670
|
+
return `${path62}: ${issue2.message}`;
|
|
39375
39671
|
}).join("; ");
|
|
39376
39672
|
}
|
|
39377
39673
|
function validatedTool(server, skill, name, handler) {
|
|
@@ -39722,8 +40018,8 @@ var AuthClient = class {
|
|
|
39722
40018
|
throw new Error(`failed to report rate-limit for ${accountId} (HTTP ${res.status})`);
|
|
39723
40019
|
}
|
|
39724
40020
|
}
|
|
39725
|
-
async request(method,
|
|
39726
|
-
const url3 = `${this.baseUrl}${
|
|
40021
|
+
async request(method, path62, body, attempt = 0) {
|
|
40022
|
+
const url3 = `${this.baseUrl}${path62}`;
|
|
39727
40023
|
const controller = new AbortController();
|
|
39728
40024
|
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
39729
40025
|
const headers = {};
|
|
@@ -39741,7 +40037,7 @@ var AuthClient = class {
|
|
|
39741
40037
|
} catch (err) {
|
|
39742
40038
|
if (attempt < RETRY_COUNT && isTransient(err)) {
|
|
39743
40039
|
await sleep(RETRY_BACKOFF_MS * (attempt + 1));
|
|
39744
|
-
return this.request(method,
|
|
40040
|
+
return this.request(method, path62, body, attempt + 1);
|
|
39745
40041
|
}
|
|
39746
40042
|
throw err;
|
|
39747
40043
|
} finally {
|
|
@@ -40740,12 +41036,12 @@ function register3(server, _ctx, _initError) {
|
|
|
40740
41036
|
registry2.close();
|
|
40741
41037
|
}
|
|
40742
41038
|
try {
|
|
40743
|
-
const { default:
|
|
41039
|
+
const { default: fs62 } = await import("node:fs");
|
|
40744
41040
|
const { default: os36 } = await import("node:os");
|
|
40745
|
-
const { default:
|
|
40746
|
-
const tokenPath =
|
|
40747
|
-
if (
|
|
40748
|
-
const token =
|
|
41041
|
+
const { default: path62 } = await import("node:path");
|
|
41042
|
+
const tokenPath = path62.join(os36.homedir(), ".olam", "host-cp.token");
|
|
41043
|
+
if (fs62.existsSync(tokenPath)) {
|
|
41044
|
+
const token = fs62.readFileSync(tokenPath, "utf-8").trim();
|
|
40749
41045
|
await fetch("http://127.0.0.1:19000/api/admin/world-pr", {
|
|
40750
41046
|
method: "POST",
|
|
40751
41047
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
@@ -41050,10 +41346,10 @@ function extractMcpConfig(claudeJsonPath) {
|
|
|
41050
41346
|
}
|
|
41051
41347
|
return { mcpServers, secrets };
|
|
41052
41348
|
}
|
|
41053
|
-
function readOptional(
|
|
41054
|
-
if (!existsSync7(
|
|
41349
|
+
function readOptional(path62) {
|
|
41350
|
+
if (!existsSync7(path62)) return null;
|
|
41055
41351
|
try {
|
|
41056
|
-
return readFileSync5(
|
|
41352
|
+
return readFileSync5(path62, "utf8");
|
|
41057
41353
|
} catch {
|
|
41058
41354
|
return null;
|
|
41059
41355
|
}
|
|
@@ -44232,10 +44528,10 @@ async function writeManifest(args) {
|
|
|
44232
44528
|
capturedAt: args.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
44233
44529
|
shots: entries
|
|
44234
44530
|
};
|
|
44235
|
-
const
|
|
44236
|
-
await writeFile(
|
|
44531
|
+
const path62 = join14(args.outDir, "manifest.json");
|
|
44532
|
+
await writeFile(path62, `${JSON.stringify(manifest, null, 2)}
|
|
44237
44533
|
`, "utf8");
|
|
44238
|
-
return { path:
|
|
44534
|
+
return { path: path62, manifest };
|
|
44239
44535
|
}
|
|
44240
44536
|
|
|
44241
44537
|
// ../mcp-server/src/tools/_capture/proxy.ts
|
|
@@ -44489,9 +44785,9 @@ async function startProxy(opts) {
|
|
|
44489
44785
|
const liveCompiled = verified.allowedPaths.map(compileGlob);
|
|
44490
44786
|
const target = parseRequestTarget(req);
|
|
44491
44787
|
if (!target) return httpReject(400, "invalid_target");
|
|
44492
|
-
const
|
|
44493
|
-
if (!liveCompiled.some((re) => re.test(
|
|
44494
|
-
return httpReject(403, "outside_allow_list", { path:
|
|
44788
|
+
const path62 = target.pathname;
|
|
44789
|
+
if (!liveCompiled.some((re) => re.test(path62))) {
|
|
44790
|
+
return httpReject(403, "outside_allow_list", { path: path62 });
|
|
44495
44791
|
}
|
|
44496
44792
|
const headerWorld = req.headers[WORLD_ASSERT_HEADER];
|
|
44497
44793
|
const headerWorldStr = typeof headerWorld === "string" ? headerWorld : Array.isArray(headerWorld) && headerWorld.length > 0 ? headerWorld[0] : void 0;
|
|
@@ -45331,14 +45627,14 @@ async function runShot(browser, shot, outDir, format, jpegQuality, allowEval, as
|
|
|
45331
45627
|
await page.waitForTimeout(shot.afterLoadMs);
|
|
45332
45628
|
}
|
|
45333
45629
|
const ext = format === "jpeg" ? "jpg" : "png";
|
|
45334
|
-
const
|
|
45630
|
+
const path62 = join15(outDir, `${shot.name}.${ext}`);
|
|
45335
45631
|
await page.screenshot({
|
|
45336
|
-
path:
|
|
45632
|
+
path: path62,
|
|
45337
45633
|
type: format,
|
|
45338
45634
|
...format === "jpeg" ? { quality: jpegQuality } : {},
|
|
45339
45635
|
fullPage: false
|
|
45340
45636
|
});
|
|
45341
|
-
return { name: shot.name, path:
|
|
45637
|
+
return { name: shot.name, path: path62, urlRedacted: redactUrl(shot.url), viewport };
|
|
45342
45638
|
} finally {
|
|
45343
45639
|
await context.close();
|
|
45344
45640
|
}
|
|
@@ -45770,9 +46066,9 @@ import { join as join17 } from "node:path";
|
|
|
45770
46066
|
var PLACEHOLDER_ANTHROPIC_API_KEY = "olam-vault-routed-placeholder-stripped-by-proxy";
|
|
45771
46067
|
var DEFAULT_WEB_TASK_MODEL = "claude-opus-4-7";
|
|
45772
46068
|
var AnthropicBaseUrlMissingError = class extends Error {
|
|
45773
|
-
constructor(
|
|
46069
|
+
constructor(path62, cause) {
|
|
45774
46070
|
super(
|
|
45775
|
-
`vault base URL is not resolvable from "${
|
|
46071
|
+
`vault base URL is not resolvable from "${path62}" (${cause}). The web-task model call routes through olam's auth-worker vault, not a raw API key \u2014 this host has no vault base URL configured. Run \`olam auth login\` (or set OLAM_ANTHROPIC_BASE_URL) so the path-encoded /auth/<sub>/<secret> base exists.`
|
|
45776
46072
|
);
|
|
45777
46073
|
this.name = "AnthropicBaseUrlMissingError";
|
|
45778
46074
|
}
|
|
@@ -46671,12 +46967,12 @@ function openUrl(url3) {
|
|
|
46671
46967
|
var HOST_CP_URL = "http://127.0.0.1:19000";
|
|
46672
46968
|
async function readHostCpToken2() {
|
|
46673
46969
|
try {
|
|
46674
|
-
const { default:
|
|
46970
|
+
const { default: fs62 } = await import("node:fs");
|
|
46675
46971
|
const { default: os36 } = await import("node:os");
|
|
46676
|
-
const { default:
|
|
46677
|
-
const tp =
|
|
46678
|
-
if (!
|
|
46679
|
-
return { token:
|
|
46972
|
+
const { default: path62 } = await import("node:path");
|
|
46973
|
+
const tp = path62.join(os36.homedir(), ".olam", "host-cp.token");
|
|
46974
|
+
if (!fs62.existsSync(tp)) return { token: null };
|
|
46975
|
+
return { token: fs62.readFileSync(tp, "utf-8").trim() };
|
|
46680
46976
|
} catch {
|
|
46681
46977
|
return { token: null };
|
|
46682
46978
|
}
|
|
@@ -46970,9 +47266,9 @@ function register22(server, _ctx, _initError) {
|
|
|
46970
47266
|
}]
|
|
46971
47267
|
};
|
|
46972
47268
|
});
|
|
46973
|
-
validatedTool(server, repoAddSkill, "olam_repo_add", async ({ name, path:
|
|
47269
|
+
validatedTool(server, repoAddSkill, "olam_repo_add", async ({ name, path: path62, description, defaultBranch }) => {
|
|
46974
47270
|
try {
|
|
46975
|
-
const entry = addRepo({ name, path:
|
|
47271
|
+
const entry = addRepo({ name, path: path62, description, defaultBranch });
|
|
46976
47272
|
return {
|
|
46977
47273
|
content: [{
|
|
46978
47274
|
type: "text",
|
|
@@ -47008,9 +47304,9 @@ function register22(server, _ctx, _initError) {
|
|
|
47008
47304
|
};
|
|
47009
47305
|
}
|
|
47010
47306
|
});
|
|
47011
|
-
validatedTool(server, repoUpdateSkill, "olam_repo_update", async ({ name, path:
|
|
47307
|
+
validatedTool(server, repoUpdateSkill, "olam_repo_update", async ({ name, path: path62, description, defaultBranch }) => {
|
|
47012
47308
|
try {
|
|
47013
|
-
const entry = updateRepo(name, { path:
|
|
47309
|
+
const entry = updateRepo(name, { path: path62, description, defaultBranch });
|
|
47014
47310
|
return {
|
|
47015
47311
|
content: [{
|
|
47016
47312
|
type: "text",
|
|
@@ -47035,9 +47331,9 @@ __export(process_port_exports, {
|
|
|
47035
47331
|
register: () => register23,
|
|
47036
47332
|
resolveHostCpToken: () => resolveHostCpToken
|
|
47037
47333
|
});
|
|
47038
|
-
import
|
|
47334
|
+
import fs41 from "node:fs";
|
|
47039
47335
|
import os22 from "node:os";
|
|
47040
|
-
import
|
|
47336
|
+
import path39 from "node:path";
|
|
47041
47337
|
|
|
47042
47338
|
// ../skill-runtime/dist/skills/process-list.js
|
|
47043
47339
|
init_v3();
|
|
@@ -47082,8 +47378,8 @@ var HOST_CP_BASE = "http://127.0.0.1:19000";
|
|
|
47082
47378
|
function resolveHostCpToken() {
|
|
47083
47379
|
const envToken = process.env["OLAM_HOST_CP_TOKEN"];
|
|
47084
47380
|
if (envToken) return envToken;
|
|
47085
|
-
const tokenPath =
|
|
47086
|
-
if (
|
|
47381
|
+
const tokenPath = path39.join(os22.homedir(), ".olam", "host-cp.token");
|
|
47382
|
+
if (fs41.existsSync(tokenPath)) return fs41.readFileSync(tokenPath, "utf-8").trim();
|
|
47087
47383
|
return null;
|
|
47088
47384
|
}
|
|
47089
47385
|
function tokenMissingError() {
|
|
@@ -47606,8 +47902,8 @@ __export(skills_exports, {
|
|
|
47606
47902
|
register: () => register26
|
|
47607
47903
|
});
|
|
47608
47904
|
init_skill_sources();
|
|
47609
|
-
import * as
|
|
47610
|
-
import * as
|
|
47905
|
+
import * as fs42 from "node:fs";
|
|
47906
|
+
import * as path40 from "node:path";
|
|
47611
47907
|
|
|
47612
47908
|
// ../skill-runtime/dist/skills/skills-sync.js
|
|
47613
47909
|
init_v3();
|
|
@@ -47688,14 +47984,14 @@ function listDeployed() {
|
|
|
47688
47984
|
);
|
|
47689
47985
|
const entries = [];
|
|
47690
47986
|
for (const bucket of ["skills", "agents", "scripts", "rules", "commands"]) {
|
|
47691
|
-
const bucketDir =
|
|
47692
|
-
if (!
|
|
47693
|
-
for (const name of
|
|
47694
|
-
const full =
|
|
47987
|
+
const bucketDir = path40.join(dir, bucket);
|
|
47988
|
+
if (!fs42.existsSync(bucketDir)) continue;
|
|
47989
|
+
for (const name of fs42.readdirSync(bucketDir)) {
|
|
47990
|
+
const full = path40.join(bucketDir, name);
|
|
47695
47991
|
try {
|
|
47696
|
-
const stat2 =
|
|
47992
|
+
const stat2 = fs42.lstatSync(full);
|
|
47697
47993
|
if (!stat2.isSymbolicLink()) continue;
|
|
47698
|
-
const target =
|
|
47994
|
+
const target = fs42.readlinkSync(full);
|
|
47699
47995
|
let sourceId;
|
|
47700
47996
|
for (const [clonePath, id] of sourcePaths.entries()) {
|
|
47701
47997
|
if (target.startsWith(clonePath)) {
|
|
@@ -47783,15 +48079,15 @@ function deriveModeId(name, taken) {
|
|
|
47783
48079
|
|
|
47784
48080
|
// ../core/dist/ree-modes/store.js
|
|
47785
48081
|
init_skill_sources();
|
|
47786
|
-
import * as
|
|
48082
|
+
import * as fs44 from "node:fs";
|
|
47787
48083
|
import * as os24 from "node:os";
|
|
47788
|
-
import * as
|
|
48084
|
+
import * as path42 from "node:path";
|
|
47789
48085
|
|
|
47790
48086
|
// ../core/dist/ree-modes/registry.js
|
|
47791
48087
|
init_v3();
|
|
47792
|
-
import * as
|
|
48088
|
+
import * as fs43 from "node:fs";
|
|
47793
48089
|
import * as os23 from "node:os";
|
|
47794
|
-
import * as
|
|
48090
|
+
import * as path41 from "node:path";
|
|
47795
48091
|
var CadenceStatusSchema = external_exports2.enum(["running", "stopped"]);
|
|
47796
48092
|
var CadenceEntrySchema = external_exports2.object({
|
|
47797
48093
|
/** Unique cadence id (modeId + short timestamp). */
|
|
@@ -47813,18 +48109,18 @@ function olamRootDir() {
|
|
|
47813
48109
|
const override = process.env["OLAM_STATE_DIR"];
|
|
47814
48110
|
if (override && override.length > 0)
|
|
47815
48111
|
return override;
|
|
47816
|
-
return
|
|
48112
|
+
return path41.join(os23.homedir(), ".olam");
|
|
47817
48113
|
}
|
|
47818
48114
|
function cadenceRegistryPath() {
|
|
47819
|
-
return
|
|
48115
|
+
return path41.join(olamRootDir(), "ree-cadences.json");
|
|
47820
48116
|
}
|
|
47821
48117
|
function readCadenceRegistry() {
|
|
47822
48118
|
const file2 = cadenceRegistryPath();
|
|
47823
|
-
if (!
|
|
48119
|
+
if (!fs43.existsSync(file2))
|
|
47824
48120
|
return { cadences: [] };
|
|
47825
48121
|
let raw;
|
|
47826
48122
|
try {
|
|
47827
|
-
raw = JSON.parse(
|
|
48123
|
+
raw = JSON.parse(fs43.readFileSync(file2, "utf-8"));
|
|
47828
48124
|
} catch {
|
|
47829
48125
|
return { cadences: [] };
|
|
47830
48126
|
}
|
|
@@ -47833,10 +48129,10 @@ function readCadenceRegistry() {
|
|
|
47833
48129
|
}
|
|
47834
48130
|
function writeCadenceRegistry(registry2) {
|
|
47835
48131
|
const file2 = cadenceRegistryPath();
|
|
47836
|
-
|
|
48132
|
+
fs43.mkdirSync(path41.dirname(file2), { recursive: true });
|
|
47837
48133
|
const tmp = `${file2}.tmp-${process.pid}`;
|
|
47838
|
-
|
|
47839
|
-
|
|
48134
|
+
fs43.writeFileSync(tmp, JSON.stringify(registry2, null, 2) + "\n", "utf-8");
|
|
48135
|
+
fs43.renameSync(tmp, file2);
|
|
47840
48136
|
}
|
|
47841
48137
|
function startCadence(input) {
|
|
47842
48138
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -47880,18 +48176,18 @@ function claudeRootDir() {
|
|
|
47880
48176
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
47881
48177
|
if (override && override.length > 0)
|
|
47882
48178
|
return override;
|
|
47883
|
-
return
|
|
48179
|
+
return path42.join(os24.homedir(), ".claude");
|
|
47884
48180
|
}
|
|
47885
48181
|
function localModesDir() {
|
|
47886
|
-
return
|
|
48182
|
+
return path42.join(claudeRootDir(), "ree-modes.local");
|
|
47887
48183
|
}
|
|
47888
48184
|
var SOURCE_CATALOG_RELATIVE_PATH = "shared/engineering/skills/ree-cadence/references/modes.md";
|
|
47889
48185
|
function findSourceCatalogPath(opts) {
|
|
47890
48186
|
if (opts && "_testCatalogPath" in opts)
|
|
47891
48187
|
return opts._testCatalogPath ?? null;
|
|
47892
48188
|
for (const source of listSkillSources()) {
|
|
47893
|
-
const candidate =
|
|
47894
|
-
if (
|
|
48189
|
+
const candidate = path42.join(skillSourceClonePath(source.id), SOURCE_CATALOG_RELATIVE_PATH);
|
|
48190
|
+
if (fs44.existsSync(candidate))
|
|
47895
48191
|
return candidate;
|
|
47896
48192
|
}
|
|
47897
48193
|
return null;
|
|
@@ -47941,16 +48237,16 @@ function parseModeCatalog(content, origin) {
|
|
|
47941
48237
|
}
|
|
47942
48238
|
function loadLocalModes() {
|
|
47943
48239
|
const dir = localModesDir();
|
|
47944
|
-
if (!
|
|
48240
|
+
if (!fs44.existsSync(dir))
|
|
47945
48241
|
return [];
|
|
47946
48242
|
const out = [];
|
|
47947
|
-
for (const entry of
|
|
48243
|
+
for (const entry of fs44.readdirSync(dir).sort()) {
|
|
47948
48244
|
if (!entry.endsWith(".md"))
|
|
47949
48245
|
continue;
|
|
47950
|
-
const full =
|
|
48246
|
+
const full = path42.join(dir, entry);
|
|
47951
48247
|
let content;
|
|
47952
48248
|
try {
|
|
47953
|
-
content =
|
|
48249
|
+
content = fs44.readFileSync(full, "utf-8");
|
|
47954
48250
|
} catch {
|
|
47955
48251
|
continue;
|
|
47956
48252
|
}
|
|
@@ -47966,7 +48262,7 @@ function loadSourceModes(opts) {
|
|
|
47966
48262
|
return [];
|
|
47967
48263
|
let content;
|
|
47968
48264
|
try {
|
|
47969
|
-
content =
|
|
48265
|
+
content = fs44.readFileSync(catalogPath, "utf-8");
|
|
47970
48266
|
} catch {
|
|
47971
48267
|
return [];
|
|
47972
48268
|
}
|
|
@@ -48033,12 +48329,12 @@ function createLocalMode(input) {
|
|
|
48033
48329
|
id = deriveModeId(name, taken);
|
|
48034
48330
|
}
|
|
48035
48331
|
const dir = localModesDir();
|
|
48036
|
-
|
|
48037
|
-
const file2 =
|
|
48038
|
-
if (
|
|
48332
|
+
fs44.mkdirSync(dir, { recursive: true });
|
|
48333
|
+
const file2 = path42.join(dir, `${id}.md`);
|
|
48334
|
+
if (fs44.existsSync(file2)) {
|
|
48039
48335
|
throw new Error(`local mode file already exists: ${file2}`);
|
|
48040
48336
|
}
|
|
48041
|
-
|
|
48337
|
+
fs44.writeFileSync(file2, scaffoldModeBlock({ id, name, instruction }), "utf-8");
|
|
48042
48338
|
return { id, name, origin: "local", path: file2 };
|
|
48043
48339
|
}
|
|
48044
48340
|
function renameLocalMode(oldId, newId) {
|
|
@@ -48049,8 +48345,8 @@ function renameLocalMode(oldId, newId) {
|
|
|
48049
48345
|
throw new Error(`invalid new id "${newId}" \u2014 must match ${MODE_ID_RE}.`);
|
|
48050
48346
|
}
|
|
48051
48347
|
const dir = localModesDir();
|
|
48052
|
-
const oldFile =
|
|
48053
|
-
if (!
|
|
48348
|
+
const oldFile = path42.join(dir, `${oldId}.md`);
|
|
48349
|
+
if (!fs44.existsSync(oldFile)) {
|
|
48054
48350
|
const isSource = loadSourceModes().some((m) => m.id === oldId);
|
|
48055
48351
|
if (isSource) {
|
|
48056
48352
|
throw new Error(`"${oldId}" is a source built-in mode, not a local one \u2014 it can't be renamed directly. Create a local override (olam skills ree-modes add) and promote it instead.`);
|
|
@@ -48060,11 +48356,11 @@ function renameLocalMode(oldId, newId) {
|
|
|
48060
48356
|
if (takenModeIds().has(newId)) {
|
|
48061
48357
|
throw new Error(`target id "${newId}" already exists (source or local).`);
|
|
48062
48358
|
}
|
|
48063
|
-
const content =
|
|
48359
|
+
const content = fs44.readFileSync(oldFile, "utf-8");
|
|
48064
48360
|
const rewritten = content.replace(new RegExp(`^## ${escapeRegex2(oldId)} \u2014 `, "m"), `## ${newId} \u2014 `);
|
|
48065
|
-
const newFile =
|
|
48066
|
-
|
|
48067
|
-
|
|
48361
|
+
const newFile = path42.join(dir, `${newId}.md`);
|
|
48362
|
+
fs44.writeFileSync(newFile, rewritten, "utf-8");
|
|
48363
|
+
fs44.rmSync(oldFile);
|
|
48068
48364
|
const danglingCadences = listCadences({ runningOnly: true }).filter((c) => c.modeId === oldId).map((c) => c.id);
|
|
48069
48365
|
return { from: oldId, to: newId, origin: "local", path: newFile, danglingCadences };
|
|
48070
48366
|
}
|
|
@@ -48084,8 +48380,8 @@ function deriveNameFromInstruction(instruction) {
|
|
|
48084
48380
|
}
|
|
48085
48381
|
|
|
48086
48382
|
// ../core/dist/ree-modes/promote.js
|
|
48087
|
-
import * as
|
|
48088
|
-
import * as
|
|
48383
|
+
import * as fs45 from "node:fs";
|
|
48384
|
+
import * as path43 from "node:path";
|
|
48089
48385
|
|
|
48090
48386
|
// ../core/dist/ree-modes/disambiguation.js
|
|
48091
48387
|
var PICKER_THRESHOLD = 4;
|
|
@@ -48260,13 +48556,13 @@ var skills_search_exports = {};
|
|
|
48260
48556
|
__export(skills_search_exports, {
|
|
48261
48557
|
register: () => register28
|
|
48262
48558
|
});
|
|
48263
|
-
import * as
|
|
48559
|
+
import * as path45 from "node:path";
|
|
48264
48560
|
import * as os26 from "node:os";
|
|
48265
48561
|
|
|
48266
48562
|
// ../mcp-server/src/lib/skills-index.mjs
|
|
48267
48563
|
import { createRequire as createRequire5 } from "node:module";
|
|
48268
|
-
import * as
|
|
48269
|
-
import * as
|
|
48564
|
+
import * as fs46 from "node:fs";
|
|
48565
|
+
import * as path44 from "node:path";
|
|
48270
48566
|
import * as os25 from "node:os";
|
|
48271
48567
|
var VECTOR_DIM = 256;
|
|
48272
48568
|
var SCHEMA_VERSION3 = "1";
|
|
@@ -48356,7 +48652,7 @@ function bufferToVector(buf) {
|
|
|
48356
48652
|
return vec;
|
|
48357
48653
|
}
|
|
48358
48654
|
function openIndex(dbPath) {
|
|
48359
|
-
if (!
|
|
48655
|
+
if (!fs46.existsSync(dbPath)) {
|
|
48360
48656
|
throw new Error(
|
|
48361
48657
|
`skills index not found at ${dbPath}. Run \`node scripts/skills-index-build.mjs --out ${dbPath}\` first.`
|
|
48362
48658
|
);
|
|
@@ -48398,8 +48694,8 @@ function searchIndex(dbPath, query, k = 5) {
|
|
|
48398
48694
|
db.close();
|
|
48399
48695
|
}
|
|
48400
48696
|
}
|
|
48401
|
-
var DEFAULT_DB_PATH =
|
|
48402
|
-
var DEFAULT_SOURCE_DIR =
|
|
48697
|
+
var DEFAULT_DB_PATH = path44.join(os25.homedir(), ".olam", "skills.vec.db");
|
|
48698
|
+
var DEFAULT_SOURCE_DIR = path44.join(os25.homedir(), ".claude", "skills");
|
|
48403
48699
|
|
|
48404
48700
|
// ../skill-runtime/dist/skills/skills-search.js
|
|
48405
48701
|
init_v3();
|
|
@@ -48418,7 +48714,7 @@ var skillsSearchSkill = defineSkill({
|
|
|
48418
48714
|
function defaultDbPath() {
|
|
48419
48715
|
const override = process.env["SKILLS_INDEX_PATH"];
|
|
48420
48716
|
if (override) return override;
|
|
48421
|
-
return
|
|
48717
|
+
return path45.join(os26.homedir(), ".olam", "skills.vec.db");
|
|
48422
48718
|
}
|
|
48423
48719
|
function asMessage10(err) {
|
|
48424
48720
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -48462,8 +48758,8 @@ function port() {
|
|
|
48462
48758
|
const n = Number.parseInt(env, 10);
|
|
48463
48759
|
return Number.isFinite(n) && n > 0 ? n : KG_SERVICE_PORT_DEFAULT;
|
|
48464
48760
|
}
|
|
48465
|
-
function url2(
|
|
48466
|
-
return `http://127.0.0.1:${port()}${
|
|
48761
|
+
function url2(path62) {
|
|
48762
|
+
return `http://127.0.0.1:${port()}${path62}`;
|
|
48467
48763
|
}
|
|
48468
48764
|
function kgServiceHealthUrl() {
|
|
48469
48765
|
return url2("/health");
|
|
@@ -48692,12 +48988,12 @@ __export(kg_install_hook_exports, {
|
|
|
48692
48988
|
register: () => register31
|
|
48693
48989
|
});
|
|
48694
48990
|
init_merge_settings();
|
|
48695
|
-
import * as
|
|
48696
|
-
import * as
|
|
48991
|
+
import * as fs47 from "node:fs";
|
|
48992
|
+
import * as path46 from "node:path";
|
|
48697
48993
|
import * as os27 from "node:os";
|
|
48698
48994
|
|
|
48699
48995
|
// ../core/dist/kg/hook-template.js
|
|
48700
|
-
var KG_HOOK_SENTINEL = "kg-service-
|
|
48996
|
+
var KG_HOOK_SENTINEL = "kg-service-v3-classifier-hook";
|
|
48701
48997
|
function defaultUrl(flavor) {
|
|
48702
48998
|
if (flavor === "host")
|
|
48703
48999
|
return "http://127.0.0.1:9997/classify";
|
|
@@ -48711,10 +49007,20 @@ function buildHookCommand(opts) {
|
|
|
48711
49007
|
const emitContext = `python3 -c 'import json,sys,os
|
|
48712
49008
|
try:
|
|
48713
49009
|
d=json.loads(sys.stdin.read())
|
|
48714
|
-
|
|
49010
|
+
route=d.get("route","")
|
|
49011
|
+
if route:
|
|
49012
|
+
if route in ("kg","both"):
|
|
49013
|
+
label=d.get("top_match") or d.get("reason","")
|
|
49014
|
+
layer=d.get("layer","?")
|
|
49015
|
+
nodes=d.get("nodes_matched",0)
|
|
49016
|
+
saved=(d.get("savings") or {}).get("saved_tokens_est",0)
|
|
49017
|
+
saved_k=round(saved/1000)
|
|
49018
|
+
sys.stderr.write(f"\\x1b[32m\\u29bf\\u29bf\\x1b[0m KG hit \\u2713 {label} \\u2192 L{layer}/{route} \\u00b7 {nodes} nodes \\u00b7 \\x1b[32m~{saved_k}k tokens saved\\x1b[0m\\n")
|
|
49019
|
+
else:
|
|
49020
|
+
sys.stderr.write("\\U0001f50d Grep used\\n")
|
|
49021
|
+
if route and route != "grep":
|
|
48715
49022
|
label=d.get("top_match") or d.get("reason","")
|
|
48716
49023
|
layer=d.get("layer","?")
|
|
48717
|
-
route=d["route"]
|
|
48718
49024
|
nodes=d.get("nodes_matched",0)
|
|
48719
49025
|
saved=(d.get("savings") or {}).get("saved_tokens_est",0)
|
|
48720
49026
|
saved_k=round(saved/1000)
|
|
@@ -48725,7 +49031,6 @@ try:
|
|
|
48725
49031
|
rel=any(k in ql for k in ("call","caller","import","uses","used","reference","who "))
|
|
48726
49032
|
g="olam kg mirror graph \\"" + sym + "\\" --workspace <ws>"
|
|
48727
49033
|
hint=g + (" --relates" if rel else "") + " (where X is defined; add --relates for what calls/imports it; --repo <name> to browse a repo)"
|
|
48728
|
-
sys.stderr.write(f"\\x1b[32m\\u2713 KG hit\\x1b[0m \\"{q}\\" \\u2192 L{layer}/{route} \\u00b7 {nodes} nodes \\u00b7 ~{saved_k}k tokens saved\\n")
|
|
48729
49034
|
print(json.dumps({"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":f"[kg-classifier L{layer}|{route}] {label[:140]}\\n\\u21b3 graph: {hint}"}}))
|
|
48730
49035
|
except Exception: pass' 2>/dev/null`;
|
|
48731
49036
|
const isCloud = opts.flavor === "cloud-sandbox";
|
|
@@ -48734,7 +49039,7 @@ except Exception: pass' 2>/dev/null`;
|
|
|
48734
49039
|
const cloudGuard = isCloud ? `if [ -z "\${OLAM_KG_PROXY_URL:-}" ] || [ -z "\${OLAM_KG_PROXY_BEARER:-}" ]; then exit 0; fi; ` : "";
|
|
48735
49040
|
const wsField = isCloud ? `,\\"workspace\\":\\"\${OLAM_KG_PROXY_WORKSPACE:-}\\"` : "";
|
|
48736
49041
|
const curlPost = `RESP=$(curl -s --max-time 1 -X POST -H 'Content-Type: application/json' ${authHeader2} -d "{\\"q\\":\\"$(echo \\"$CMD\\" | head -c 200 | tr '\\"' ' ')\\"${wsField}}" ${resolvedUrl} 2>/dev/null)`;
|
|
48737
|
-
const hostRemoteFallback = opts.flavor === "host" ? `; if [ -z "$RESP" ] && [ -r "$HOME/.olam/kg-proxy-url" ] && [ -r "$HOME/.olam/kg-proxy-bearer" ]; then RESP=$(curl -s --max-time
|
|
49042
|
+
const hostRemoteFallback = opts.flavor === "host" ? `; if [ -z "$RESP" ] && [ -r "$HOME/.olam/kg-proxy-url" ] && [ -r "$HOME/.olam/kg-proxy-bearer" ]; then KG_ORIGIN=$(sed 's|\\(https*://[^/]*\\).*|\\1|' "$HOME/.olam/kg-proxy-url" 2>/dev/null); RESP=$(curl -s --max-time 3 -X POST -H 'Content-Type: application/json' -H "Authorization: Bearer $(cat "$HOME/.olam/kg-proxy-bearer")" -d "{\\"q\\":\\"$(echo \\"$CMD\\" | head -c 200 | tr '\\"' ' ')\\"}" "$KG_ORIGIN/v1/classify" 2>/dev/null); fi` : "";
|
|
48738
49043
|
return [
|
|
48739
49044
|
`KG_SENTINEL=${KG_HOOK_SENTINEL}`,
|
|
48740
49045
|
`CMD=$(${extractCmd})`,
|
|
@@ -48781,22 +49086,22 @@ var kgInstallHookSkill = defineSkill({
|
|
|
48781
49086
|
// ../mcp-server/src/tools/kg-install-hook.ts
|
|
48782
49087
|
function settingsPathFor2(scope, projectPath) {
|
|
48783
49088
|
if (scope === "user") {
|
|
48784
|
-
return
|
|
49089
|
+
return path46.join(os27.homedir(), ".claude", "settings.json");
|
|
48785
49090
|
}
|
|
48786
49091
|
const root = projectPath ?? process.cwd();
|
|
48787
|
-
return
|
|
49092
|
+
return path46.join(root, ".claude", "settings.json");
|
|
48788
49093
|
}
|
|
48789
49094
|
function register31(server, _ctx, _initError) {
|
|
48790
49095
|
validatedTool(server, kgInstallHookSkill, "olam_kg_install_hook", async (params) => {
|
|
48791
49096
|
const scope = params.scope === "user" ? "user" : "project";
|
|
48792
49097
|
const filePath = settingsPathFor2(scope, params.projectPath);
|
|
48793
49098
|
try {
|
|
48794
|
-
|
|
49099
|
+
fs47.mkdirSync(path46.dirname(filePath), { recursive: true });
|
|
48795
49100
|
let backupPath = null;
|
|
48796
|
-
if (
|
|
49101
|
+
if (fs47.existsSync(filePath)) {
|
|
48797
49102
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
48798
49103
|
backupPath = `${filePath}.olam-bak.${ts}`;
|
|
48799
|
-
|
|
49104
|
+
fs47.copyFileSync(filePath, backupPath);
|
|
48800
49105
|
}
|
|
48801
49106
|
const result = mergeHomeSettingsJson(filePath, {
|
|
48802
49107
|
ensureHook: {
|
|
@@ -48807,7 +49112,7 @@ function register31(server, _ctx, _initError) {
|
|
|
48807
49112
|
});
|
|
48808
49113
|
if (result.status === "already-present" && backupPath) {
|
|
48809
49114
|
try {
|
|
48810
|
-
|
|
49115
|
+
fs47.unlinkSync(backupPath);
|
|
48811
49116
|
} catch {
|
|
48812
49117
|
}
|
|
48813
49118
|
}
|
|
@@ -48849,8 +49154,8 @@ var kg_uninstall_hook_exports = {};
|
|
|
48849
49154
|
__export(kg_uninstall_hook_exports, {
|
|
48850
49155
|
register: () => register32
|
|
48851
49156
|
});
|
|
48852
|
-
import * as
|
|
48853
|
-
import * as
|
|
49157
|
+
import * as fs48 from "node:fs";
|
|
49158
|
+
import * as path47 from "node:path";
|
|
48854
49159
|
import * as os28 from "node:os";
|
|
48855
49160
|
|
|
48856
49161
|
// ../skill-runtime/dist/skills/kg-uninstall-hook.js
|
|
@@ -48873,10 +49178,10 @@ var kgUninstallHookSkill = defineSkill({
|
|
|
48873
49178
|
// ../mcp-server/src/tools/kg-uninstall-hook.ts
|
|
48874
49179
|
function settingsPathFor3(scope, projectPath) {
|
|
48875
49180
|
if (scope === "user") {
|
|
48876
|
-
return
|
|
49181
|
+
return path47.join(os28.homedir(), ".claude", "settings.json");
|
|
48877
49182
|
}
|
|
48878
49183
|
const root = projectPath ?? process.cwd();
|
|
48879
|
-
return
|
|
49184
|
+
return path47.join(root, ".claude", "settings.json");
|
|
48880
49185
|
}
|
|
48881
49186
|
function dropSentinel(matchers) {
|
|
48882
49187
|
let changed = false;
|
|
@@ -48903,7 +49208,7 @@ function register32(server, _ctx, _initError) {
|
|
|
48903
49208
|
const scope = params.scope === "user" ? "user" : "project";
|
|
48904
49209
|
const filePath = settingsPathFor3(scope, params.projectPath);
|
|
48905
49210
|
try {
|
|
48906
|
-
if (!
|
|
49211
|
+
if (!fs48.existsSync(filePath)) {
|
|
48907
49212
|
return {
|
|
48908
49213
|
content: [
|
|
48909
49214
|
{
|
|
@@ -48917,7 +49222,7 @@ function register32(server, _ctx, _initError) {
|
|
|
48917
49222
|
]
|
|
48918
49223
|
};
|
|
48919
49224
|
}
|
|
48920
|
-
const raw =
|
|
49225
|
+
const raw = fs48.readFileSync(filePath, "utf-8");
|
|
48921
49226
|
const settings = raw.trim() ? JSON.parse(raw) : {};
|
|
48922
49227
|
const preToolUse = settings.hooks?.PreToolUse;
|
|
48923
49228
|
if (!Array.isArray(preToolUse) || preToolUse.length === 0) {
|
|
@@ -48952,7 +49257,7 @@ function register32(server, _ctx, _initError) {
|
|
|
48952
49257
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
48953
49258
|
const backupPath = `${filePath}.olam-bak.${ts}`;
|
|
48954
49259
|
try {
|
|
48955
|
-
|
|
49260
|
+
fs48.copyFileSync(filePath, backupPath);
|
|
48956
49261
|
} catch {
|
|
48957
49262
|
}
|
|
48958
49263
|
const next = {
|
|
@@ -48964,7 +49269,7 @@ function register32(server, _ctx, _initError) {
|
|
|
48964
49269
|
if (otherStages.length === 0) delete next.hooks;
|
|
48965
49270
|
else delete next.hooks.PreToolUse;
|
|
48966
49271
|
}
|
|
48967
|
-
|
|
49272
|
+
fs48.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
48968
49273
|
return {
|
|
48969
49274
|
content: [
|
|
48970
49275
|
{
|
|
@@ -49702,11 +50007,11 @@ function registerAllTools(server, ctx, initError) {
|
|
|
49702
50007
|
}
|
|
49703
50008
|
|
|
49704
50009
|
// ../mcp-server/src/resources/chunks.ts
|
|
49705
|
-
import
|
|
50010
|
+
import fs49 from "node:fs";
|
|
49706
50011
|
import os29 from "node:os";
|
|
49707
|
-
import
|
|
50012
|
+
import path48 from "node:path";
|
|
49708
50013
|
var DEFAULT_HOST_CP_URL = "http://127.0.0.1:19000";
|
|
49709
|
-
var DEFAULT_PLAN_CHAT_SECRET_PATH =
|
|
50014
|
+
var DEFAULT_PLAN_CHAT_SECRET_PATH = path48.join(
|
|
49710
50015
|
os29.homedir(),
|
|
49711
50016
|
".olam",
|
|
49712
50017
|
"plan-chat-secret"
|
|
@@ -49721,7 +50026,7 @@ function loadBearer(bearerOpt, secretPath) {
|
|
|
49721
50026
|
const envBearer = process.env.OLAM_PLAN_CHAT_BEARER?.trim();
|
|
49722
50027
|
if (envBearer && envBearer.length > 0) return envBearer;
|
|
49723
50028
|
try {
|
|
49724
|
-
const onDisk =
|
|
50029
|
+
const onDisk = fs49.readFileSync(secretPath, "utf8").trim();
|
|
49725
50030
|
return onDisk.length > 0 ? onDisk : null;
|
|
49726
50031
|
} catch (err) {
|
|
49727
50032
|
if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
|
|
@@ -51495,9 +51800,9 @@ init_loader();
|
|
|
51495
51800
|
// ../core/dist/world/manager.js
|
|
51496
51801
|
import * as crypto8 from "node:crypto";
|
|
51497
51802
|
import { execSync as execSync6, spawnSync as spawnSync4 } from "node:child_process";
|
|
51498
|
-
import * as
|
|
51803
|
+
import * as fs59 from "node:fs";
|
|
51499
51804
|
import * as os34 from "node:os";
|
|
51500
|
-
import * as
|
|
51805
|
+
import * as path59 from "node:path";
|
|
51501
51806
|
|
|
51502
51807
|
// ../core/dist/world/state.js
|
|
51503
51808
|
var VALID_TRANSITIONS = {
|
|
@@ -51592,9 +51897,9 @@ function resolveDevboxImage(config2, tag) {
|
|
|
51592
51897
|
}
|
|
51593
51898
|
|
|
51594
51899
|
// ../core/dist/world/worktree.js
|
|
51595
|
-
import { execFileSync as
|
|
51596
|
-
import * as
|
|
51597
|
-
import * as
|
|
51900
|
+
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
51901
|
+
import * as fs50 from "node:fs";
|
|
51902
|
+
import * as path49 from "node:path";
|
|
51598
51903
|
function resolveGitDir(repo) {
|
|
51599
51904
|
if (repo.path) {
|
|
51600
51905
|
return repo.path;
|
|
@@ -51604,18 +51909,18 @@ function resolveGitDir(repo) {
|
|
|
51604
51909
|
async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
51605
51910
|
const created = [];
|
|
51606
51911
|
for (const repo of repos) {
|
|
51607
|
-
const worktreePath =
|
|
51912
|
+
const worktreePath = path49.join(workspacePath, repo.name);
|
|
51608
51913
|
const gitDir = resolveGitDir(repo);
|
|
51609
51914
|
const branchName = branch || `olam/${worldId}`;
|
|
51610
51915
|
try {
|
|
51611
|
-
|
|
51612
|
-
|
|
51916
|
+
fs50.mkdirSync(path49.dirname(worktreePath), { recursive: true });
|
|
51917
|
+
execFileSync5("git", ["worktree", "add", worktreePath, "-b", branchName], {
|
|
51613
51918
|
cwd: gitDir,
|
|
51614
51919
|
stdio: "pipe"
|
|
51615
51920
|
});
|
|
51616
51921
|
if (repo.submodules) {
|
|
51617
51922
|
try {
|
|
51618
|
-
|
|
51923
|
+
execFileSync5("git", ["submodule", "update", "--init", "--recursive"], {
|
|
51619
51924
|
cwd: worktreePath,
|
|
51620
51925
|
stdio: "pipe"
|
|
51621
51926
|
});
|
|
@@ -51627,7 +51932,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
|
51627
51932
|
for (const entry of created) {
|
|
51628
51933
|
try {
|
|
51629
51934
|
const entryGitDir = resolveGitDir(entry.repo);
|
|
51630
|
-
|
|
51935
|
+
execFileSync5("git", ["worktree", "remove", entry.worktreePath, "--force"], {
|
|
51631
51936
|
cwd: entryGitDir,
|
|
51632
51937
|
stdio: "pipe"
|
|
51633
51938
|
});
|
|
@@ -51641,7 +51946,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
|
51641
51946
|
}
|
|
51642
51947
|
async function removeWorktrees(repos, workspacePath) {
|
|
51643
51948
|
for (const repo of repos) {
|
|
51644
|
-
const worktreePath =
|
|
51949
|
+
const worktreePath = path49.join(workspacePath, repo.name);
|
|
51645
51950
|
let gitDir;
|
|
51646
51951
|
try {
|
|
51647
51952
|
gitDir = resolveGitDir(repo);
|
|
@@ -51650,7 +51955,7 @@ async function removeWorktrees(repos, workspacePath) {
|
|
|
51650
51955
|
}
|
|
51651
51956
|
let removed = false;
|
|
51652
51957
|
try {
|
|
51653
|
-
|
|
51958
|
+
execFileSync5("git", ["worktree", "remove", "--force", worktreePath], {
|
|
51654
51959
|
cwd: gitDir,
|
|
51655
51960
|
stdio: "pipe"
|
|
51656
51961
|
});
|
|
@@ -51659,7 +51964,7 @@ async function removeWorktrees(repos, workspacePath) {
|
|
|
51659
51964
|
}
|
|
51660
51965
|
if (!removed) {
|
|
51661
51966
|
try {
|
|
51662
|
-
|
|
51967
|
+
execFileSync5("git", ["worktree", "prune"], {
|
|
51663
51968
|
cwd: gitDir,
|
|
51664
51969
|
stdio: "pipe"
|
|
51665
51970
|
});
|
|
@@ -51676,7 +51981,7 @@ function removeBranch(repo, branch) {
|
|
|
51676
51981
|
return { branch, action: "not-found" };
|
|
51677
51982
|
}
|
|
51678
51983
|
try {
|
|
51679
|
-
|
|
51984
|
+
execFileSync5("git", ["show-ref", "--quiet", `refs/heads/${branch}`], {
|
|
51680
51985
|
cwd: gitDir,
|
|
51681
51986
|
stdio: "pipe"
|
|
51682
51987
|
});
|
|
@@ -51685,7 +51990,7 @@ function removeBranch(repo, branch) {
|
|
|
51685
51990
|
}
|
|
51686
51991
|
let hasUpstream = false;
|
|
51687
51992
|
try {
|
|
51688
|
-
|
|
51993
|
+
execFileSync5("git", ["rev-parse", "--abbrev-ref", `${branch}@{upstream}`], { cwd: gitDir, stdio: "pipe" });
|
|
51689
51994
|
hasUpstream = true;
|
|
51690
51995
|
} catch {
|
|
51691
51996
|
}
|
|
@@ -51694,14 +51999,14 @@ function removeBranch(repo, branch) {
|
|
|
51694
51999
|
}
|
|
51695
52000
|
let localCommitCount = 0;
|
|
51696
52001
|
try {
|
|
51697
|
-
const output =
|
|
52002
|
+
const output = execFileSync5("git", ["rev-list", "--count", branch, "--not", "--remotes"], { cwd: gitDir, stdio: "pipe" }).toString().trim();
|
|
51698
52003
|
localCommitCount = parseInt(output, 10) || 0;
|
|
51699
52004
|
} catch {
|
|
51700
52005
|
localCommitCount = 1;
|
|
51701
52006
|
}
|
|
51702
52007
|
if (localCommitCount === 0) {
|
|
51703
52008
|
try {
|
|
51704
|
-
|
|
52009
|
+
execFileSync5("git", ["branch", "-D", branch], {
|
|
51705
52010
|
cwd: gitDir,
|
|
51706
52011
|
stdio: "pipe"
|
|
51707
52012
|
});
|
|
@@ -51715,13 +52020,13 @@ function removeBranch(repo, branch) {
|
|
|
51715
52020
|
}
|
|
51716
52021
|
|
|
51717
52022
|
// ../core/dist/world/kg-overlay.js
|
|
51718
|
-
import { execFileSync as
|
|
51719
|
-
import * as
|
|
51720
|
-
import * as
|
|
52023
|
+
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
52024
|
+
import * as fs51 from "node:fs";
|
|
52025
|
+
import * as path50 from "node:path";
|
|
51721
52026
|
|
|
51722
52027
|
// ../core/dist/kg/storage-paths.js
|
|
51723
52028
|
import { homedir as homedir30 } from "node:os";
|
|
51724
|
-
import { join as
|
|
52029
|
+
import { join as join52, resolve as resolve11 } from "node:path";
|
|
51725
52030
|
|
|
51726
52031
|
// ../core/dist/world/workspace-name.js
|
|
51727
52032
|
var InvalidWorkspaceNameError = class extends Error {
|
|
@@ -51742,25 +52047,25 @@ function validateWorkspaceName(name) {
|
|
|
51742
52047
|
|
|
51743
52048
|
// ../core/dist/kg/storage-paths.js
|
|
51744
52049
|
function olamHome2() {
|
|
51745
|
-
return process.env.OLAM_HOME ??
|
|
52050
|
+
return process.env.OLAM_HOME ?? join52(homedir30(), ".olam");
|
|
51746
52051
|
}
|
|
51747
52052
|
function kgRoot() {
|
|
51748
|
-
return
|
|
52053
|
+
return join52(olamHome2(), "kg");
|
|
51749
52054
|
}
|
|
51750
52055
|
function worldsRoot() {
|
|
51751
|
-
return
|
|
52056
|
+
return join52(olamHome2(), "worlds");
|
|
51752
52057
|
}
|
|
51753
|
-
function assertWithinPrefix(
|
|
51754
|
-
if (!
|
|
51755
|
-
throw new Error(`${label} escape: ${
|
|
52058
|
+
function assertWithinPrefix(path62, prefix, label) {
|
|
52059
|
+
if (!path62.startsWith(prefix + "/")) {
|
|
52060
|
+
throw new Error(`${label} escape: ${path62} not under ${prefix}/`);
|
|
51756
52061
|
}
|
|
51757
52062
|
}
|
|
51758
52063
|
function kgPristinePath(workspace) {
|
|
51759
52064
|
validateWorkspaceName(workspace);
|
|
51760
52065
|
const root = kgRoot();
|
|
51761
|
-
const
|
|
51762
|
-
assertWithinPrefix(
|
|
51763
|
-
return
|
|
52066
|
+
const path62 = resolve11(join52(root, workspace));
|
|
52067
|
+
assertWithinPrefix(path62, root, "kgPristinePath");
|
|
52068
|
+
return path62;
|
|
51764
52069
|
}
|
|
51765
52070
|
var KG_PATHS_INTERNALS = Object.freeze({
|
|
51766
52071
|
olamHome: olamHome2,
|
|
@@ -51776,10 +52081,10 @@ var KgOverlayError = class extends Error {
|
|
|
51776
52081
|
}
|
|
51777
52082
|
};
|
|
51778
52083
|
function ensureGitignoreEntry(worldClonePath) {
|
|
51779
|
-
const gitignorePath =
|
|
51780
|
-
if (!
|
|
52084
|
+
const gitignorePath = path50.join(worldClonePath, ".gitignore");
|
|
52085
|
+
if (!fs51.existsSync(gitignorePath))
|
|
51781
52086
|
return "no-gitignore";
|
|
51782
|
-
const content =
|
|
52087
|
+
const content = fs51.readFileSync(gitignorePath, "utf-8");
|
|
51783
52088
|
const lines = content.split("\n").map((l) => l.trim());
|
|
51784
52089
|
const recognised = /* @__PURE__ */ new Set([
|
|
51785
52090
|
"graphify-out",
|
|
@@ -51794,31 +52099,31 @@ function ensureGitignoreEntry(worldClonePath) {
|
|
|
51794
52099
|
const eol = content.includes("\r\n") ? "\r\n" : "\n";
|
|
51795
52100
|
const needsLeadingNewline = content.length > 0 && !content.endsWith(eol);
|
|
51796
52101
|
const block = `${needsLeadingNewline ? eol : ""}${eol}# olam-kg-service: per-world KG overlay (Phase B1)${eol}graphify-out/${eol}`;
|
|
51797
|
-
|
|
52102
|
+
fs51.appendFileSync(gitignorePath, block, "utf-8");
|
|
51798
52103
|
return "appended";
|
|
51799
52104
|
}
|
|
51800
52105
|
function createWorldOverlay(opts) {
|
|
51801
52106
|
const pristineRoot = kgPristinePath(opts.workspace);
|
|
51802
|
-
const pristinePath =
|
|
51803
|
-
if (!
|
|
52107
|
+
const pristinePath = path50.join(pristineRoot, "graphify-out");
|
|
52108
|
+
if (!fs51.existsSync(pristinePath)) {
|
|
51804
52109
|
throw new KgOverlayError(`Pristine KG for workspace ${JSON.stringify(opts.workspace)} not found at ${pristinePath}. Run \`olam kg build ${opts.workspace}\` first.`);
|
|
51805
52110
|
}
|
|
51806
|
-
if (!
|
|
52111
|
+
if (!path50.isAbsolute(opts.worldClonePath)) {
|
|
51807
52112
|
throw new KgOverlayError(`worldClonePath must be absolute (got ${opts.worldClonePath})`);
|
|
51808
52113
|
}
|
|
51809
|
-
if (!
|
|
52114
|
+
if (!fs51.existsSync(opts.worldClonePath)) {
|
|
51810
52115
|
throw new KgOverlayError(`worldClonePath does not exist: ${opts.worldClonePath}. Create the clone before reflinking.`);
|
|
51811
52116
|
}
|
|
51812
|
-
const overlayPath =
|
|
51813
|
-
if (
|
|
51814
|
-
|
|
52117
|
+
const overlayPath = path50.join(opts.worldClonePath, "graphify-out");
|
|
52118
|
+
if (fs51.existsSync(overlayPath)) {
|
|
52119
|
+
fs51.rmSync(overlayPath, { recursive: true, force: true });
|
|
51815
52120
|
}
|
|
51816
52121
|
const useReflink = process.platform === "darwin";
|
|
51817
52122
|
let strategy;
|
|
51818
52123
|
let reflinkError;
|
|
51819
52124
|
if (useReflink) {
|
|
51820
52125
|
try {
|
|
51821
|
-
|
|
52126
|
+
execFileSync6("cp", ["-c", "-r", pristinePath, opts.worldClonePath], {
|
|
51822
52127
|
stdio: ["ignore", "ignore", "pipe"]
|
|
51823
52128
|
});
|
|
51824
52129
|
strategy = "cp-c-r-reflink";
|
|
@@ -51829,9 +52134,9 @@ function createWorldOverlay(opts) {
|
|
|
51829
52134
|
} else {
|
|
51830
52135
|
strategy = "cp-r";
|
|
51831
52136
|
}
|
|
51832
|
-
if (strategy === "cp-r" || !
|
|
52137
|
+
if (strategy === "cp-r" || !fs51.existsSync(overlayPath)) {
|
|
51833
52138
|
try {
|
|
51834
|
-
|
|
52139
|
+
execFileSync6("cp", ["-r", pristinePath, opts.worldClonePath], {
|
|
51835
52140
|
stdio: ["ignore", "ignore", "pipe"]
|
|
51836
52141
|
});
|
|
51837
52142
|
strategy = "cp-r";
|
|
@@ -51841,7 +52146,7 @@ function createWorldOverlay(opts) {
|
|
|
51841
52146
|
throw new KgOverlayError(`cp -r failed: ${msg}${reflinkMsg}`);
|
|
51842
52147
|
}
|
|
51843
52148
|
}
|
|
51844
|
-
if (!
|
|
52149
|
+
if (!fs51.existsSync(overlayPath)) {
|
|
51845
52150
|
throw new KgOverlayError(`Overlay creation produced no ${overlayPath} after cp \u2014 filesystem returned without error?`);
|
|
51846
52151
|
}
|
|
51847
52152
|
const gitignoreAction = ensureGitignoreEntry(opts.worldClonePath);
|
|
@@ -51854,10 +52159,10 @@ function createWorldOverlay(opts) {
|
|
|
51854
52159
|
}
|
|
51855
52160
|
|
|
51856
52161
|
// ../core/dist/world/baseline-diff.js
|
|
51857
|
-
import { execFileSync as
|
|
51858
|
-
import * as
|
|
52162
|
+
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
52163
|
+
import * as fs52 from "node:fs";
|
|
51859
52164
|
import * as os30 from "node:os";
|
|
51860
|
-
import * as
|
|
52165
|
+
import * as path51 from "node:path";
|
|
51861
52166
|
var DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
51862
52167
|
function expandHome2(p, homedir37) {
|
|
51863
52168
|
return p.replace(/^~(?=$|\/|\\)/, homedir37());
|
|
@@ -51882,11 +52187,11 @@ ${stderr}`;
|
|
|
51882
52187
|
return /unknown revision|bad revision|does not have any commits|HEAD'?: ambiguous|Needed a single revision/.test(blob);
|
|
51883
52188
|
}
|
|
51884
52189
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
51885
|
-
const exec = deps.exec ?? ((cmd, args, opts) =>
|
|
52190
|
+
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
|
|
51886
52191
|
const homedir37 = deps.homedir ?? (() => os30.homedir());
|
|
51887
|
-
const baselineDir =
|
|
52192
|
+
const baselineDir = path51.join(workspacePath, ".olam", "baseline");
|
|
51888
52193
|
try {
|
|
51889
|
-
|
|
52194
|
+
fs52.mkdirSync(baselineDir, { recursive: true });
|
|
51890
52195
|
} catch (err) {
|
|
51891
52196
|
const msg = err instanceof Error ? err.message : String(err);
|
|
51892
52197
|
console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
|
|
@@ -51898,9 +52203,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
51898
52203
|
if (!repo.path)
|
|
51899
52204
|
continue;
|
|
51900
52205
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
51901
|
-
const outPath =
|
|
52206
|
+
const outPath = path51.join(baselineDir, filename);
|
|
51902
52207
|
const repoPath = expandHome2(repo.path, homedir37);
|
|
51903
|
-
if (!
|
|
52208
|
+
if (!fs52.existsSync(repoPath)) {
|
|
51904
52209
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
51905
52210
|
# (skipped: path ${repoPath} does not exist)
|
|
51906
52211
|
`);
|
|
@@ -51967,7 +52272,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
51967
52272
|
}
|
|
51968
52273
|
function writeBaselineFile(outPath, content) {
|
|
51969
52274
|
try {
|
|
51970
|
-
|
|
52275
|
+
fs52.writeFileSync(outPath, content);
|
|
51971
52276
|
} catch (err) {
|
|
51972
52277
|
const msg = err instanceof Error ? err.message : String(err);
|
|
51973
52278
|
console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
|
|
@@ -51975,11 +52280,11 @@ function writeBaselineFile(outPath, content) {
|
|
|
51975
52280
|
}
|
|
51976
52281
|
function stripWorktreeEdits(repos, workspacePath) {
|
|
51977
52282
|
for (const repo of repos) {
|
|
51978
|
-
const worktreePath =
|
|
51979
|
-
if (!
|
|
52283
|
+
const worktreePath = path51.join(workspacePath, repo.name);
|
|
52284
|
+
if (!fs52.existsSync(worktreePath))
|
|
51980
52285
|
continue;
|
|
51981
52286
|
try {
|
|
51982
|
-
|
|
52287
|
+
execFileSync7("git", ["checkout", "--", "."], {
|
|
51983
52288
|
cwd: worktreePath,
|
|
51984
52289
|
stdio: "pipe"
|
|
51985
52290
|
});
|
|
@@ -52006,7 +52311,7 @@ ${stderr.trim()}` : "";
|
|
|
52006
52311
|
}
|
|
52007
52312
|
};
|
|
52008
52313
|
function captureOperatorDiff(repoPath, deps = {}) {
|
|
52009
|
-
const exec = deps.exec ?? ((cmd, args, opts) =>
|
|
52314
|
+
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
|
|
52010
52315
|
const unstaged = exec("git", ["diff"], {
|
|
52011
52316
|
cwd: repoPath,
|
|
52012
52317
|
encoding: "utf-8",
|
|
@@ -52034,22 +52339,22 @@ function extractStderr(err) {
|
|
|
52034
52339
|
return typeof raw === "string" ? raw : raw.toString("utf-8");
|
|
52035
52340
|
}
|
|
52036
52341
|
function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
52037
|
-
const exec = deps.exec ?? ((cmd, args, opts) =>
|
|
52342
|
+
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
|
|
52038
52343
|
const homedir37 = deps.homedir ?? (() => os30.homedir());
|
|
52039
|
-
const
|
|
52040
|
-
const
|
|
52344
|
+
const existsSync61 = deps.existsSync ?? ((p) => fs52.existsSync(p));
|
|
52345
|
+
const copyFileSync10 = deps.copyFileSync ?? ((src, dest) => fs52.copyFileSync(src, dest));
|
|
52041
52346
|
const mkdirSync34 = deps.mkdirSync ?? ((dirPath, opts) => {
|
|
52042
|
-
|
|
52347
|
+
fs52.mkdirSync(dirPath, opts);
|
|
52043
52348
|
});
|
|
52044
52349
|
const plans = [];
|
|
52045
52350
|
for (const repo of repos) {
|
|
52046
52351
|
if (!repo.path)
|
|
52047
52352
|
continue;
|
|
52048
52353
|
const repoPath = expandHome2(repo.path, homedir37);
|
|
52049
|
-
const worktreePath =
|
|
52050
|
-
if (!
|
|
52354
|
+
const worktreePath = path51.join(workspacePath, repo.name);
|
|
52355
|
+
if (!existsSync61(repoPath))
|
|
52051
52356
|
continue;
|
|
52052
|
-
if (!
|
|
52357
|
+
if (!existsSync61(worktreePath)) {
|
|
52053
52358
|
console.warn(`[carry] ${repo.name}: world worktree ${worktreePath} missing; skipping carry for this repo`);
|
|
52054
52359
|
continue;
|
|
52055
52360
|
}
|
|
@@ -52107,13 +52412,13 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
52107
52412
|
}
|
|
52108
52413
|
}
|
|
52109
52414
|
for (const rel of plan.diff.untracked) {
|
|
52110
|
-
const src =
|
|
52111
|
-
const dest =
|
|
52112
|
-
if (!
|
|
52415
|
+
const src = path51.join(plan.repoPath, rel);
|
|
52416
|
+
const dest = path51.join(plan.worktreePath, rel);
|
|
52417
|
+
if (!existsSync61(src))
|
|
52113
52418
|
continue;
|
|
52114
52419
|
try {
|
|
52115
|
-
mkdirSync34(
|
|
52116
|
-
|
|
52420
|
+
mkdirSync34(path51.dirname(dest), { recursive: true });
|
|
52421
|
+
copyFileSync10(src, dest);
|
|
52117
52422
|
} catch (err) {
|
|
52118
52423
|
const msg = err instanceof Error ? err.message : String(err);
|
|
52119
52424
|
console.warn(`[carry] ${plan.name}: copy untracked ${rel} failed: ${msg}`);
|
|
@@ -52138,8 +52443,8 @@ function formatBaselineSummary(result) {
|
|
|
52138
52443
|
}
|
|
52139
52444
|
|
|
52140
52445
|
// ../core/dist/world/context-injection.js
|
|
52141
|
-
import * as
|
|
52142
|
-
import * as
|
|
52446
|
+
import * as fs53 from "node:fs";
|
|
52447
|
+
import * as path52 from "node:path";
|
|
52143
52448
|
|
|
52144
52449
|
// ../core/dist/world/templates/_generated.js
|
|
52145
52450
|
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';
|
|
@@ -52149,10 +52454,10 @@ var WORLD_CLAUDE_MD = '# Olam World: {{worldName}}\n\n{{taskBlock}}\n\n## Enviro
|
|
|
52149
52454
|
// ../core/dist/world/context-injection.js
|
|
52150
52455
|
function injectWorldContext(opts) {
|
|
52151
52456
|
const { world } = opts;
|
|
52152
|
-
const claudeDir2 =
|
|
52153
|
-
|
|
52457
|
+
const claudeDir2 = path52.join(world.workspacePath, ".claude");
|
|
52458
|
+
fs53.mkdirSync(claudeDir2, { recursive: true });
|
|
52154
52459
|
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));
|
|
52155
|
-
|
|
52460
|
+
fs53.writeFileSync(path52.join(claudeDir2, "CLAUDE.md"), content);
|
|
52156
52461
|
writeOlamDocs(world.workspacePath);
|
|
52157
52462
|
}
|
|
52158
52463
|
function buildTaskBlock(opts) {
|
|
@@ -52226,10 +52531,10 @@ function buildExtraContextBlock(extra) {
|
|
|
52226
52531
|
${extra}`;
|
|
52227
52532
|
}
|
|
52228
52533
|
function writeOlamDocs(workspacePath) {
|
|
52229
|
-
const docsDir =
|
|
52230
|
-
|
|
52231
|
-
|
|
52232
|
-
|
|
52534
|
+
const docsDir = path52.join(workspacePath, ".olam", "docs");
|
|
52535
|
+
fs53.mkdirSync(docsDir, { recursive: true });
|
|
52536
|
+
fs53.writeFileSync(path52.join(docsDir, "gh-pr-create.md"), GH_PR_CREATE);
|
|
52537
|
+
fs53.writeFileSync(path52.join(docsDir, "lane-orchestration.md"), LANE_ORCHESTRATION);
|
|
52233
52538
|
}
|
|
52234
52539
|
function formatTaskSource(ctx) {
|
|
52235
52540
|
if (ctx.source === "linear" && ctx.ticketId) {
|
|
@@ -52243,9 +52548,9 @@ function formatTaskSource(ctx) {
|
|
|
52243
52548
|
function hasPlanFile(world) {
|
|
52244
52549
|
if (world.repos.length === 0)
|
|
52245
52550
|
return false;
|
|
52246
|
-
const plansDir =
|
|
52551
|
+
const plansDir = path52.join(world.workspacePath, world.repos[0], "docs", "plans");
|
|
52247
52552
|
try {
|
|
52248
|
-
return
|
|
52553
|
+
return fs53.existsSync(plansDir) && fs53.readdirSync(plansDir).length > 0;
|
|
52249
52554
|
} catch {
|
|
52250
52555
|
return false;
|
|
52251
52556
|
}
|
|
@@ -52814,25 +53119,25 @@ init_repo_manifest();
|
|
|
52814
53119
|
|
|
52815
53120
|
// ../core/dist/world/snapshot.js
|
|
52816
53121
|
import * as crypto7 from "node:crypto";
|
|
52817
|
-
import * as
|
|
53122
|
+
import * as fs54 from "node:fs";
|
|
52818
53123
|
import * as os31 from "node:os";
|
|
52819
|
-
import * as
|
|
52820
|
-
import { execFileSync as
|
|
53124
|
+
import * as path53 from "node:path";
|
|
53125
|
+
import { execFileSync as execFileSync8, spawn as spawn5 } from "node:child_process";
|
|
52821
53126
|
import { gunzipSync } from "node:zlib";
|
|
52822
53127
|
function snapshotsDir() {
|
|
52823
|
-
return process.env["OLAM_SNAPSHOTS_DIR"] ??
|
|
53128
|
+
return process.env["OLAM_SNAPSHOTS_DIR"] ?? path53.join(os31.homedir(), ".olam", "snapshots");
|
|
52824
53129
|
}
|
|
52825
53130
|
function snapshotKindDirByWorkspace(workspace, arch, kind) {
|
|
52826
|
-
return
|
|
53131
|
+
return path53.join(snapshotsDir(), "by-workspace", workspace, arch, kind);
|
|
52827
53132
|
}
|
|
52828
53133
|
function cleanupLegacyByWorldDir(worldId) {
|
|
52829
|
-
const legacyDir =
|
|
53134
|
+
const legacyDir = path53.join(snapshotsDir(), worldId);
|
|
52830
53135
|
if (worldId === "by-workspace")
|
|
52831
53136
|
return;
|
|
52832
|
-
if (!
|
|
53137
|
+
if (!fs54.existsSync(legacyDir))
|
|
52833
53138
|
return;
|
|
52834
53139
|
try {
|
|
52835
|
-
|
|
53140
|
+
fs54.rmSync(legacyDir, { recursive: true, force: true });
|
|
52836
53141
|
} catch {
|
|
52837
53142
|
}
|
|
52838
53143
|
}
|
|
@@ -52851,11 +53156,11 @@ function hashBuffers(entries) {
|
|
|
52851
53156
|
return hash2.digest("hex").slice(0, 12);
|
|
52852
53157
|
}
|
|
52853
53158
|
function computeGemsFingerprint(repoDir, imageDigest) {
|
|
52854
|
-
const lockfile =
|
|
52855
|
-
if (!
|
|
53159
|
+
const lockfile = path53.join(repoDir, "Gemfile.lock");
|
|
53160
|
+
if (!fs54.existsSync(lockfile))
|
|
52856
53161
|
return null;
|
|
52857
53162
|
const entries = [
|
|
52858
|
-
{ path: "Gemfile.lock", content:
|
|
53163
|
+
{ path: "Gemfile.lock", content: fs54.readFileSync(lockfile) }
|
|
52859
53164
|
];
|
|
52860
53165
|
if (imageDigest) {
|
|
52861
53166
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -52865,10 +53170,10 @@ function computeGemsFingerprint(repoDir, imageDigest) {
|
|
|
52865
53170
|
function computeNodeFingerprint(repoDir, imageDigest) {
|
|
52866
53171
|
const candidates = ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"];
|
|
52867
53172
|
for (const name of candidates) {
|
|
52868
|
-
const lockfile =
|
|
52869
|
-
if (
|
|
53173
|
+
const lockfile = path53.join(repoDir, name);
|
|
53174
|
+
if (fs54.existsSync(lockfile)) {
|
|
52870
53175
|
const entries = [
|
|
52871
|
-
{ path: name, content:
|
|
53176
|
+
{ path: name, content: fs54.readFileSync(lockfile) }
|
|
52872
53177
|
];
|
|
52873
53178
|
if (imageDigest) {
|
|
52874
53179
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -52887,18 +53192,18 @@ function unpackTarballAtomic(srcPath, destDir) {
|
|
|
52887
53192
|
detail: validation.detail ?? `unsafe entry: ${validation.unsafePath}`
|
|
52888
53193
|
};
|
|
52889
53194
|
}
|
|
52890
|
-
const parent =
|
|
52891
|
-
|
|
53195
|
+
const parent = path53.dirname(destDir);
|
|
53196
|
+
fs54.mkdirSync(parent, { recursive: true });
|
|
52892
53197
|
const tmpSuffix = `.tmp-${process.pid}-${crypto7.randomBytes(4).toString("hex")}`;
|
|
52893
53198
|
const tmpDir = `${destDir}${tmpSuffix}`;
|
|
52894
53199
|
try {
|
|
52895
|
-
|
|
52896
|
-
|
|
52897
|
-
|
|
53200
|
+
fs54.mkdirSync(tmpDir, { recursive: true });
|
|
53201
|
+
execFileSync8("tar", ["-xzf", srcPath, "-C", tmpDir], { stdio: "pipe" });
|
|
53202
|
+
fs54.renameSync(tmpDir, destDir);
|
|
52898
53203
|
return { ok: true, entryCount: validation.entries.length };
|
|
52899
53204
|
} catch (err) {
|
|
52900
53205
|
try {
|
|
52901
|
-
|
|
53206
|
+
fs54.rmSync(tmpDir, { recursive: true, force: true });
|
|
52902
53207
|
} catch {
|
|
52903
53208
|
}
|
|
52904
53209
|
return {
|
|
@@ -52909,12 +53214,12 @@ function unpackTarballAtomic(srcPath, destDir) {
|
|
|
52909
53214
|
}
|
|
52910
53215
|
}
|
|
52911
53216
|
function resolvesWithin(base, target) {
|
|
52912
|
-
const resolved =
|
|
52913
|
-
const baseResolved =
|
|
52914
|
-
const rel =
|
|
53217
|
+
const resolved = path53.resolve(base, target);
|
|
53218
|
+
const baseResolved = path53.resolve(base);
|
|
53219
|
+
const rel = path53.relative(baseResolved, resolved);
|
|
52915
53220
|
if (rel === "")
|
|
52916
53221
|
return true;
|
|
52917
|
-
return !rel.startsWith("..") && !
|
|
53222
|
+
return !rel.startsWith("..") && !path53.isAbsolute(rel);
|
|
52918
53223
|
}
|
|
52919
53224
|
var TYPE_CHAR_TO_TYPE = {
|
|
52920
53225
|
"-": "file",
|
|
@@ -52964,7 +53269,7 @@ function parseTarListLine(line) {
|
|
|
52964
53269
|
function validateHardlinksBinary(tarPath, targetDir) {
|
|
52965
53270
|
let raw;
|
|
52966
53271
|
try {
|
|
52967
|
-
raw = gunzipSync(
|
|
53272
|
+
raw = gunzipSync(fs54.readFileSync(tarPath));
|
|
52968
53273
|
} catch {
|
|
52969
53274
|
return null;
|
|
52970
53275
|
}
|
|
@@ -52979,7 +53284,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
|
|
|
52979
53284
|
const name = block.subarray(0, nameNull >= 0 && nameNull <= 99 ? nameNull : 100).toString("utf-8");
|
|
52980
53285
|
const linkNull = block.indexOf(0, 157);
|
|
52981
53286
|
const linkname = block.subarray(157, linkNull >= 157 && linkNull <= 256 ? linkNull : 257).toString("utf-8");
|
|
52982
|
-
if (linkname && (
|
|
53287
|
+
if (linkname && (path53.isAbsolute(linkname) || !resolvesWithin(targetDir, linkname))) {
|
|
52983
53288
|
return {
|
|
52984
53289
|
valid: false,
|
|
52985
53290
|
reason: "hardlink-escape",
|
|
@@ -52997,7 +53302,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
|
|
|
52997
53302
|
function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
52998
53303
|
let raw;
|
|
52999
53304
|
try {
|
|
53000
|
-
raw =
|
|
53305
|
+
raw = execFileSync8("tar", ["-tvf", tarPath], {
|
|
53001
53306
|
stdio: ["ignore", "pipe", "pipe"],
|
|
53002
53307
|
env: { ...process.env, LC_ALL: "C", TZ: "UTC" },
|
|
53003
53308
|
encoding: "utf-8",
|
|
@@ -53017,7 +53322,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
53017
53322
|
const entry = parseTarListLine(line);
|
|
53018
53323
|
if (!entry)
|
|
53019
53324
|
continue;
|
|
53020
|
-
if (
|
|
53325
|
+
if (path53.isAbsolute(entry.name) || !resolvesWithin(targetDir, entry.name)) {
|
|
53021
53326
|
return {
|
|
53022
53327
|
valid: false,
|
|
53023
53328
|
reason: "path-traversal",
|
|
@@ -53025,8 +53330,8 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
53025
53330
|
};
|
|
53026
53331
|
}
|
|
53027
53332
|
if (entry.type === "symlink" && entry.linkname !== void 0) {
|
|
53028
|
-
const symlinkParent =
|
|
53029
|
-
if (
|
|
53333
|
+
const symlinkParent = path53.join(targetDir, path53.dirname(entry.name));
|
|
53334
|
+
if (path53.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, path53.join(path53.dirname(entry.name), entry.linkname))) {
|
|
53030
53335
|
return {
|
|
53031
53336
|
valid: false,
|
|
53032
53337
|
reason: "symlink-escape",
|
|
@@ -53036,7 +53341,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
53036
53341
|
}
|
|
53037
53342
|
}
|
|
53038
53343
|
if (entry.type === "hardlink" && entry.linkname !== void 0) {
|
|
53039
|
-
if (
|
|
53344
|
+
if (path53.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, entry.linkname)) {
|
|
53040
53345
|
return {
|
|
53041
53346
|
valid: false,
|
|
53042
53347
|
reason: "hardlink-escape",
|
|
@@ -53069,8 +53374,8 @@ function restoreSnapshotsForRepos(input) {
|
|
|
53069
53374
|
}
|
|
53070
53375
|
const archDir = snapshotKindDirByWorkspace(input.workspace, input.arch, kind);
|
|
53071
53376
|
const tarFilename = `${repo.name}-${input.arch}-${fingerprint}.tar.gz`;
|
|
53072
|
-
const tarPath =
|
|
53073
|
-
if (!
|
|
53377
|
+
const tarPath = path53.join(archDir, tarFilename);
|
|
53378
|
+
if (!fs54.existsSync(tarPath)) {
|
|
53074
53379
|
outcomes.push({ repo: repo.name, kind, outcome: "miss", reason: "no-tarball", fingerprint });
|
|
53075
53380
|
continue;
|
|
53076
53381
|
}
|
|
@@ -53085,9 +53390,9 @@ function restoreSnapshotsForRepos(input) {
|
|
|
53085
53390
|
});
|
|
53086
53391
|
continue;
|
|
53087
53392
|
}
|
|
53088
|
-
const targetDir =
|
|
53393
|
+
const targetDir = path53.join(repo.worktreeDir, targetSubpath);
|
|
53089
53394
|
try {
|
|
53090
|
-
|
|
53395
|
+
fs54.rmSync(targetDir, { recursive: true, force: true });
|
|
53091
53396
|
} catch {
|
|
53092
53397
|
}
|
|
53093
53398
|
const result = unpackTarballAtomic(tarPath, targetDir);
|
|
@@ -53100,8 +53405,8 @@ function restoreSnapshotsForRepos(input) {
|
|
|
53100
53405
|
fingerprint
|
|
53101
53406
|
});
|
|
53102
53407
|
try {
|
|
53103
|
-
|
|
53104
|
-
|
|
53408
|
+
fs54.rmSync(tarPath, { force: true });
|
|
53409
|
+
fs54.rmSync(manifestPath(tarPath), { force: true });
|
|
53105
53410
|
} catch {
|
|
53106
53411
|
}
|
|
53107
53412
|
continue;
|
|
@@ -53117,10 +53422,10 @@ function restoreSnapshotsForRepos(input) {
|
|
|
53117
53422
|
}
|
|
53118
53423
|
function readManifest(tarPath) {
|
|
53119
53424
|
const mPath = manifestPath(tarPath);
|
|
53120
|
-
if (!
|
|
53425
|
+
if (!fs54.existsSync(mPath))
|
|
53121
53426
|
return null;
|
|
53122
53427
|
try {
|
|
53123
|
-
return JSON.parse(
|
|
53428
|
+
return JSON.parse(fs54.readFileSync(mPath, "utf-8"));
|
|
53124
53429
|
} catch {
|
|
53125
53430
|
return null;
|
|
53126
53431
|
}
|
|
@@ -53135,17 +53440,17 @@ function isPidAlive(pid) {
|
|
|
53135
53440
|
}
|
|
53136
53441
|
}
|
|
53137
53442
|
function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
53138
|
-
|
|
53139
|
-
const lockPath =
|
|
53443
|
+
fs54.mkdirSync(dir, { recursive: true });
|
|
53444
|
+
const lockPath = path53.join(dir, EVICT_LOCK_FILENAME);
|
|
53140
53445
|
let fd;
|
|
53141
53446
|
try {
|
|
53142
|
-
fd =
|
|
53447
|
+
fd = fs54.openSync(lockPath, fs54.constants.O_WRONLY | fs54.constants.O_CREAT | fs54.constants.O_EXCL, 384);
|
|
53143
53448
|
} catch (err) {
|
|
53144
53449
|
if (err.code !== "EEXIST")
|
|
53145
53450
|
return 0;
|
|
53146
53451
|
let holderPid = null;
|
|
53147
53452
|
try {
|
|
53148
|
-
holderPid = parseInt(
|
|
53453
|
+
holderPid = parseInt(fs54.readFileSync(lockPath, "utf-8").trim(), 10);
|
|
53149
53454
|
} catch {
|
|
53150
53455
|
holderPid = null;
|
|
53151
53456
|
}
|
|
@@ -53153,23 +53458,23 @@ function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
|
53153
53458
|
return 0;
|
|
53154
53459
|
}
|
|
53155
53460
|
try {
|
|
53156
|
-
|
|
53157
|
-
fd =
|
|
53461
|
+
fs54.unlinkSync(lockPath);
|
|
53462
|
+
fd = fs54.openSync(lockPath, fs54.constants.O_WRONLY | fs54.constants.O_CREAT | fs54.constants.O_EXCL, 384);
|
|
53158
53463
|
} catch {
|
|
53159
53464
|
return 0;
|
|
53160
53465
|
}
|
|
53161
53466
|
}
|
|
53162
53467
|
try {
|
|
53163
|
-
|
|
53468
|
+
fs54.writeSync(fd, `${process.pid}
|
|
53164
53469
|
`);
|
|
53165
53470
|
} finally {
|
|
53166
|
-
|
|
53471
|
+
fs54.closeSync(fd);
|
|
53167
53472
|
}
|
|
53168
53473
|
try {
|
|
53169
53474
|
return evictOldSnapshots(maxBytes, dir);
|
|
53170
53475
|
} finally {
|
|
53171
53476
|
try {
|
|
53172
|
-
|
|
53477
|
+
fs54.unlinkSync(lockPath);
|
|
53173
53478
|
} catch {
|
|
53174
53479
|
}
|
|
53175
53480
|
}
|
|
@@ -53202,16 +53507,16 @@ function spawnAutoCapture(worldId, olamBin = "olam") {
|
|
|
53202
53507
|
}
|
|
53203
53508
|
}
|
|
53204
53509
|
function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
53205
|
-
if (!
|
|
53510
|
+
if (!fs54.existsSync(dir))
|
|
53206
53511
|
return 0;
|
|
53207
53512
|
const allTars = [];
|
|
53208
53513
|
const walk = (d) => {
|
|
53209
|
-
for (const entry of
|
|
53210
|
-
const full =
|
|
53514
|
+
for (const entry of fs54.readdirSync(d, { withFileTypes: true })) {
|
|
53515
|
+
const full = path53.join(d, entry.name);
|
|
53211
53516
|
if (entry.isDirectory()) {
|
|
53212
53517
|
walk(full);
|
|
53213
53518
|
} else if (entry.name.endsWith(".tar.gz")) {
|
|
53214
|
-
const stat2 =
|
|
53519
|
+
const stat2 = fs54.statSync(full);
|
|
53215
53520
|
allTars.push({ path: full, size: stat2.size, mtime: stat2.mtimeMs });
|
|
53216
53521
|
}
|
|
53217
53522
|
}
|
|
@@ -53226,8 +53531,8 @@ function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
|
53226
53531
|
for (const tar of allTars) {
|
|
53227
53532
|
if (remaining <= maxBytes)
|
|
53228
53533
|
break;
|
|
53229
|
-
|
|
53230
|
-
|
|
53534
|
+
fs54.rmSync(tar.path, { force: true });
|
|
53535
|
+
fs54.rmSync(manifestPath(tar.path), { force: true });
|
|
53231
53536
|
freed += tar.size;
|
|
53232
53537
|
remaining -= tar.size;
|
|
53233
53538
|
}
|
|
@@ -53344,14 +53649,14 @@ function gcloudAvailable(execFn = defaultExecFn) {
|
|
|
53344
53649
|
|
|
53345
53650
|
// ../core/dist/world/olam-yaml.js
|
|
53346
53651
|
init_repo_manifest();
|
|
53347
|
-
import * as
|
|
53652
|
+
import * as path54 from "node:path";
|
|
53348
53653
|
import YAML2 from "yaml";
|
|
53349
53654
|
function enrichReposWithManifests(repos, workspacePath) {
|
|
53350
53655
|
return repos.map((repo) => {
|
|
53351
53656
|
if (repo.manifest !== void 0 && repo.manifest !== null) {
|
|
53352
53657
|
return repo;
|
|
53353
53658
|
}
|
|
53354
|
-
const repoDir =
|
|
53659
|
+
const repoDir = path54.join(workspacePath, repo.name);
|
|
53355
53660
|
let manifest = null;
|
|
53356
53661
|
try {
|
|
53357
53662
|
manifest = loadRepoManifest(repoDir);
|
|
@@ -53366,8 +53671,8 @@ function enrichReposWithManifests(repos, workspacePath) {
|
|
|
53366
53671
|
}
|
|
53367
53672
|
|
|
53368
53673
|
// ../core/dist/policies/loader.js
|
|
53369
|
-
import * as
|
|
53370
|
-
import * as
|
|
53674
|
+
import * as fs55 from "node:fs";
|
|
53675
|
+
import * as path55 from "node:path";
|
|
53371
53676
|
import { parse as parseYaml5 } from "yaml";
|
|
53372
53677
|
function parseFrontmatter2(content) {
|
|
53373
53678
|
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
|
|
@@ -53387,20 +53692,20 @@ function toStringArray(v) {
|
|
|
53387
53692
|
return v.filter((x) => typeof x === "string");
|
|
53388
53693
|
}
|
|
53389
53694
|
function loadPolicies(workspaceRoot) {
|
|
53390
|
-
const policiesDir =
|
|
53391
|
-
if (!
|
|
53695
|
+
const policiesDir = path55.join(workspaceRoot, ".olam", "policies");
|
|
53696
|
+
if (!fs55.existsSync(policiesDir))
|
|
53392
53697
|
return [];
|
|
53393
53698
|
let files;
|
|
53394
53699
|
try {
|
|
53395
|
-
files =
|
|
53700
|
+
files = fs55.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
|
|
53396
53701
|
} catch {
|
|
53397
53702
|
return [];
|
|
53398
53703
|
}
|
|
53399
53704
|
const policies = [];
|
|
53400
53705
|
for (const file2 of files) {
|
|
53401
|
-
const filePath =
|
|
53706
|
+
const filePath = path55.join(policiesDir, file2);
|
|
53402
53707
|
try {
|
|
53403
|
-
const content =
|
|
53708
|
+
const content = fs55.readFileSync(filePath, "utf8");
|
|
53404
53709
|
const parsed = parseFrontmatter2(content);
|
|
53405
53710
|
if (!parsed) {
|
|
53406
53711
|
console.warn(`[policies] skipping ${file2}: no valid frontmatter block`);
|
|
@@ -53544,9 +53849,9 @@ async function autoDispatchTask(opts) {
|
|
|
53544
53849
|
}
|
|
53545
53850
|
|
|
53546
53851
|
// ../core/dist/world/wiki-injection-loader.js
|
|
53547
|
-
import * as
|
|
53852
|
+
import * as fs56 from "node:fs";
|
|
53548
53853
|
import * as os32 from "node:os";
|
|
53549
|
-
import * as
|
|
53854
|
+
import * as path56 from "node:path";
|
|
53550
53855
|
var WIKI_INJECTION_FLAG = "OLAM_WIKI_INJECTION";
|
|
53551
53856
|
var WIKI_PATH_ENV = "OLAM_WIKI_PATH";
|
|
53552
53857
|
function flagEnabled(value) {
|
|
@@ -53559,14 +53864,14 @@ function wikiBlobPath() {
|
|
|
53559
53864
|
const override = process.env[WIKI_PATH_ENV];
|
|
53560
53865
|
if (override && override.length > 0)
|
|
53561
53866
|
return override;
|
|
53562
|
-
return
|
|
53867
|
+
return path56.join(os32.homedir(), ".olam", "wiki.json");
|
|
53563
53868
|
}
|
|
53564
53869
|
function defaultReadBlob() {
|
|
53565
53870
|
const p = wikiBlobPath();
|
|
53566
53871
|
try {
|
|
53567
|
-
if (!
|
|
53872
|
+
if (!fs56.existsSync(p))
|
|
53568
53873
|
return null;
|
|
53569
|
-
return
|
|
53874
|
+
return fs56.readFileSync(p, "utf8");
|
|
53570
53875
|
} catch {
|
|
53571
53876
|
return null;
|
|
53572
53877
|
}
|
|
@@ -53605,12 +53910,12 @@ init_store2();
|
|
|
53605
53910
|
init_bridge();
|
|
53606
53911
|
|
|
53607
53912
|
// ../core/dist/global-config/runbook-resolver.js
|
|
53608
|
-
import * as
|
|
53913
|
+
import * as fs57 from "node:fs";
|
|
53609
53914
|
import * as os33 from "node:os";
|
|
53610
|
-
import * as
|
|
53915
|
+
import * as path57 from "node:path";
|
|
53611
53916
|
function expandTilde(p) {
|
|
53612
53917
|
if (p === "~" || p.startsWith("~/")) {
|
|
53613
|
-
return
|
|
53918
|
+
return path57.join(os33.homedir(), p.slice(1));
|
|
53614
53919
|
}
|
|
53615
53920
|
return p;
|
|
53616
53921
|
}
|
|
@@ -53622,7 +53927,7 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
|
|
|
53622
53927
|
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.`);
|
|
53623
53928
|
}
|
|
53624
53929
|
const resolvedPath = expandTilde(entry.path);
|
|
53625
|
-
if (!
|
|
53930
|
+
if (!fs57.existsSync(resolvedPath)) {
|
|
53626
53931
|
throw new Error(`repo "${repoName}" path "${resolvedPath}" no longer exists. Run "olam repos update ${repoName} --path <new-path>" to fix.`);
|
|
53627
53932
|
}
|
|
53628
53933
|
}
|
|
@@ -53638,19 +53943,19 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
|
|
|
53638
53943
|
init_port_validator();
|
|
53639
53944
|
|
|
53640
53945
|
// ../core/dist/world/bootstrap-hooks.js
|
|
53641
|
-
import * as
|
|
53642
|
-
import * as
|
|
53946
|
+
import * as fs58 from "node:fs";
|
|
53947
|
+
import * as path58 from "node:path";
|
|
53643
53948
|
function runFixtureCopySeeds(seeds, workspacePath) {
|
|
53644
53949
|
if (!seeds)
|
|
53645
53950
|
return;
|
|
53646
53951
|
for (const seed of seeds) {
|
|
53647
53952
|
if (seed.type !== "fixture-copy")
|
|
53648
53953
|
continue;
|
|
53649
|
-
const srcAbs =
|
|
53650
|
-
const destAbs =
|
|
53651
|
-
const destDir =
|
|
53652
|
-
|
|
53653
|
-
|
|
53954
|
+
const srcAbs = path58.resolve(workspacePath, seed.repo, seed.src);
|
|
53955
|
+
const destAbs = path58.resolve(workspacePath, seed.repo, seed.dest);
|
|
53956
|
+
const destDir = path58.dirname(destAbs);
|
|
53957
|
+
fs58.mkdirSync(destDir, { recursive: true });
|
|
53958
|
+
fs58.cpSync(srcAbs, destAbs, { recursive: true, force: true });
|
|
53654
53959
|
}
|
|
53655
53960
|
}
|
|
53656
53961
|
async function runSeedHooks(seeds, containerName, servicePortMap, exec) {
|
|
@@ -54353,7 +54658,7 @@ ${detail}`);
|
|
|
54353
54658
|
runbookSeeds = resolved.seeds;
|
|
54354
54659
|
}
|
|
54355
54660
|
const worldId = generateWorldId();
|
|
54356
|
-
const workspacePath =
|
|
54661
|
+
const workspacePath = path59.join(os34.homedir(), ".olam", "worlds", worldId);
|
|
54357
54662
|
const portOffset = this.registry.getNextPortOffset();
|
|
54358
54663
|
const branch = opts.branchName ?? `olam/${worldId}`;
|
|
54359
54664
|
const repos = await this.resolveReposWithWorkspace(opts);
|
|
@@ -54436,37 +54741,37 @@ ${detail}`);
|
|
|
54436
54741
|
if (!repo.path)
|
|
54437
54742
|
continue;
|
|
54438
54743
|
const sourceRoot = repo.path.replace(/^~/, os34.homedir());
|
|
54439
|
-
const worktreeRoot =
|
|
54440
|
-
if (!
|
|
54744
|
+
const worktreeRoot = path59.join(workspacePath, repo.name);
|
|
54745
|
+
if (!fs59.existsSync(sourceRoot) || !fs59.existsSync(worktreeRoot))
|
|
54441
54746
|
continue;
|
|
54442
54747
|
let copied = 0;
|
|
54443
54748
|
for (const pattern of RUNTIME_FILE_PATTERNS) {
|
|
54444
54749
|
const matches2 = [];
|
|
54445
54750
|
if (pattern.includes("*")) {
|
|
54446
|
-
const [dir, glob] = [
|
|
54447
|
-
const sourceDir =
|
|
54448
|
-
if (
|
|
54751
|
+
const [dir, glob] = [path59.dirname(pattern), path59.basename(pattern)];
|
|
54752
|
+
const sourceDir = path59.join(sourceRoot, dir);
|
|
54753
|
+
if (fs59.existsSync(sourceDir)) {
|
|
54449
54754
|
const ext = glob.replace(/^\*+/, "");
|
|
54450
54755
|
try {
|
|
54451
|
-
for (const entry of
|
|
54756
|
+
for (const entry of fs59.readdirSync(sourceDir)) {
|
|
54452
54757
|
if (ext === "" || entry.endsWith(ext))
|
|
54453
|
-
matches2.push(
|
|
54758
|
+
matches2.push(path59.join(dir, entry));
|
|
54454
54759
|
}
|
|
54455
54760
|
} catch {
|
|
54456
54761
|
}
|
|
54457
54762
|
}
|
|
54458
|
-
} else if (
|
|
54763
|
+
} else if (fs59.existsSync(path59.join(sourceRoot, pattern))) {
|
|
54459
54764
|
matches2.push(pattern);
|
|
54460
54765
|
}
|
|
54461
54766
|
for (const rel of matches2) {
|
|
54462
|
-
const src =
|
|
54463
|
-
const dst =
|
|
54767
|
+
const src = path59.join(sourceRoot, rel);
|
|
54768
|
+
const dst = path59.join(worktreeRoot, rel);
|
|
54464
54769
|
try {
|
|
54465
|
-
const st =
|
|
54770
|
+
const st = fs59.statSync(src);
|
|
54466
54771
|
if (!st.isFile())
|
|
54467
54772
|
continue;
|
|
54468
|
-
|
|
54469
|
-
|
|
54773
|
+
fs59.mkdirSync(path59.dirname(dst), { recursive: true });
|
|
54774
|
+
fs59.copyFileSync(src, dst);
|
|
54470
54775
|
copied++;
|
|
54471
54776
|
} catch {
|
|
54472
54777
|
}
|
|
@@ -54552,7 +54857,7 @@ ${detail}`);
|
|
|
54552
54857
|
}
|
|
54553
54858
|
const overlayAttachments = [];
|
|
54554
54859
|
for (const repo of repos) {
|
|
54555
|
-
const worldClonePath =
|
|
54860
|
+
const worldClonePath = path59.join(workspacePath, repo.name);
|
|
54556
54861
|
try {
|
|
54557
54862
|
const result = createWorldOverlay({
|
|
54558
54863
|
workspace: repo.name,
|
|
@@ -54607,7 +54912,7 @@ ${detail}`);
|
|
|
54607
54912
|
try {
|
|
54608
54913
|
const hostExec = makeHostExecFn();
|
|
54609
54914
|
for (const repo of repos) {
|
|
54610
|
-
const repoDir =
|
|
54915
|
+
const repoDir = path59.join(workspacePath, repo.name);
|
|
54611
54916
|
if (repo.stack && Object.keys(repo.stack).length > 0) {
|
|
54612
54917
|
preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
|
|
54613
54918
|
} else {
|
|
@@ -54651,10 +54956,10 @@ ${detail}`);
|
|
|
54651
54956
|
const worldEnv = {};
|
|
54652
54957
|
if (opts.task)
|
|
54653
54958
|
worldEnv.OLAM_TASK = opts.task;
|
|
54654
|
-
const r2CredsPath =
|
|
54655
|
-
if (
|
|
54959
|
+
const r2CredsPath = path59.join(os34.homedir(), ".olam", "r2-credentials.json");
|
|
54960
|
+
if (fs59.existsSync(r2CredsPath)) {
|
|
54656
54961
|
try {
|
|
54657
|
-
const r2Raw =
|
|
54962
|
+
const r2Raw = fs59.readFileSync(r2CredsPath, "utf-8").trim();
|
|
54658
54963
|
if (r2Raw.length > 0) {
|
|
54659
54964
|
const r2 = JSON.parse(r2Raw);
|
|
54660
54965
|
if (typeof r2.account_id === "string")
|
|
@@ -54671,10 +54976,10 @@ ${detail}`);
|
|
|
54671
54976
|
} catch {
|
|
54672
54977
|
}
|
|
54673
54978
|
}
|
|
54674
|
-
const keysYamlPath =
|
|
54675
|
-
if (
|
|
54979
|
+
const keysYamlPath = path59.join(os34.homedir(), ".olam", "keys.yaml");
|
|
54980
|
+
if (fs59.existsSync(keysYamlPath)) {
|
|
54676
54981
|
try {
|
|
54677
|
-
const keysRaw =
|
|
54982
|
+
const keysRaw = fs59.readFileSync(keysYamlPath, "utf-8").trim();
|
|
54678
54983
|
if (keysRaw.length > 0) {
|
|
54679
54984
|
const { default: YAML3 } = await import("yaml");
|
|
54680
54985
|
const parsed = YAML3.parse(keysRaw);
|
|
@@ -54734,10 +55039,10 @@ ${detail}`);
|
|
|
54734
55039
|
worldEnv[k] = v;
|
|
54735
55040
|
}
|
|
54736
55041
|
for (const { repoName, relativePath, content } of fileWrites) {
|
|
54737
|
-
const absPath =
|
|
55042
|
+
const absPath = path59.join(workspacePath, repoName, relativePath);
|
|
54738
55043
|
try {
|
|
54739
|
-
|
|
54740
|
-
|
|
55044
|
+
fs59.mkdirSync(path59.dirname(absPath), { recursive: true });
|
|
55045
|
+
fs59.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
|
|
54741
55046
|
mode: 384
|
|
54742
55047
|
});
|
|
54743
55048
|
console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
|
|
@@ -54914,7 +55219,7 @@ ${detail}`);
|
|
|
54914
55219
|
imageDigest: void 0,
|
|
54915
55220
|
repos: enrichedRepos.map((r) => ({
|
|
54916
55221
|
name: r.name,
|
|
54917
|
-
worktreeDir:
|
|
55222
|
+
worktreeDir: path59.join(workspacePath, r.name)
|
|
54918
55223
|
}))
|
|
54919
55224
|
});
|
|
54920
55225
|
for (const out of restoreResult.outcomes) {
|
|
@@ -55020,7 +55325,7 @@ ${detail}`);
|
|
|
55020
55325
|
}
|
|
55021
55326
|
if (opts.task) {
|
|
55022
55327
|
const allPolicies = repos.flatMap((repo) => {
|
|
55023
|
-
const repoWorktree =
|
|
55328
|
+
const repoWorktree = path59.join(workspacePath, repo.name);
|
|
55024
55329
|
try {
|
|
55025
55330
|
return loadPolicies(repoWorktree);
|
|
55026
55331
|
} catch (err) {
|
|
@@ -55033,8 +55338,8 @@ ${detail}`);
|
|
|
55033
55338
|
try {
|
|
55034
55339
|
execSync6(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
|
|
55035
55340
|
for (const repo of repos) {
|
|
55036
|
-
const policiesDir =
|
|
55037
|
-
if (
|
|
55341
|
+
const policiesDir = path59.join(workspacePath, repo.name, ".olam", "policies");
|
|
55342
|
+
if (fs59.existsSync(policiesDir)) {
|
|
55038
55343
|
execSync6(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
|
|
55039
55344
|
}
|
|
55040
55345
|
}
|
|
@@ -55144,8 +55449,8 @@ ${detail}`);
|
|
|
55144
55449
|
} catch {
|
|
55145
55450
|
}
|
|
55146
55451
|
try {
|
|
55147
|
-
|
|
55148
|
-
if (
|
|
55452
|
+
fs59.rmSync(world.workspacePath, { recursive: true, force: true });
|
|
55453
|
+
if (fs59.existsSync(world.workspacePath)) {
|
|
55149
55454
|
console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
|
|
55150
55455
|
}
|
|
55151
55456
|
} catch (err) {
|
|
@@ -55255,14 +55560,14 @@ ${detail}`);
|
|
|
55255
55560
|
}).filter((r) => r !== void 0);
|
|
55256
55561
|
}
|
|
55257
55562
|
transportPlanFile(planFilePath, workspacePath, repoNames) {
|
|
55258
|
-
const planContent =
|
|
55259
|
-
const planFileName =
|
|
55563
|
+
const planContent = fs59.readFileSync(planFilePath, "utf-8");
|
|
55564
|
+
const planFileName = path59.basename(planFilePath);
|
|
55260
55565
|
const targetRepo = repoNames[0];
|
|
55261
55566
|
if (!targetRepo)
|
|
55262
55567
|
return;
|
|
55263
|
-
const plansDir =
|
|
55264
|
-
|
|
55265
|
-
|
|
55568
|
+
const plansDir = path59.join(workspacePath, targetRepo, "docs", "plans");
|
|
55569
|
+
fs59.mkdirSync(plansDir, { recursive: true });
|
|
55570
|
+
fs59.writeFileSync(path59.join(plansDir, planFileName), planContent);
|
|
55266
55571
|
}
|
|
55267
55572
|
resolveServices(repos) {
|
|
55268
55573
|
const services = [];
|
|
@@ -55726,8 +56031,8 @@ import * as http2 from "node:http";
|
|
|
55726
56031
|
|
|
55727
56032
|
// ../core/dist/dashboard/server.js
|
|
55728
56033
|
import * as http from "node:http";
|
|
55729
|
-
import * as
|
|
55730
|
-
import * as
|
|
56034
|
+
import * as fs60 from "node:fs";
|
|
56035
|
+
import * as path60 from "node:path";
|
|
55731
56036
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
55732
56037
|
|
|
55733
56038
|
// ../core/dist/dashboard/serialize.js
|
|
@@ -56062,7 +56367,7 @@ function notFound(res) {
|
|
|
56062
56367
|
}
|
|
56063
56368
|
function openThoughtStore(workspacePath) {
|
|
56064
56369
|
const dbPath = getWorldDbPath(workspacePath);
|
|
56065
|
-
if (!
|
|
56370
|
+
if (!fs60.existsSync(dbPath))
|
|
56066
56371
|
return null;
|
|
56067
56372
|
return new ThoughtLocalStore(dbPath);
|
|
56068
56373
|
}
|
|
@@ -56233,13 +56538,13 @@ function findSessionInWorld(registry2, sessionId) {
|
|
|
56233
56538
|
}
|
|
56234
56539
|
function createDashboardServer(opts) {
|
|
56235
56540
|
const { port: port2, registry: registry2 } = opts;
|
|
56236
|
-
const thisDir =
|
|
56237
|
-
const defaultPublicDir =
|
|
56541
|
+
const thisDir = path60.dirname(fileURLToPath4(import.meta.url));
|
|
56542
|
+
const defaultPublicDir = path60.resolve(thisDir, "../../../control-plane/public");
|
|
56238
56543
|
const publicDir = opts.publicDir ?? defaultPublicDir;
|
|
56239
|
-
let hasPublicDir =
|
|
56544
|
+
let hasPublicDir = fs60.existsSync(publicDir);
|
|
56240
56545
|
const server = http.createServer((req, res) => {
|
|
56241
56546
|
if (!hasPublicDir) {
|
|
56242
|
-
hasPublicDir =
|
|
56547
|
+
hasPublicDir = fs60.existsSync(publicDir);
|
|
56243
56548
|
}
|
|
56244
56549
|
const host = req.headers.host ?? `localhost:${port2}`;
|
|
56245
56550
|
const url3 = new URL(req.url ?? "/", `http://${host}`);
|
|
@@ -56513,22 +56818,22 @@ function createDashboardServer(opts) {
|
|
|
56513
56818
|
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>`);
|
|
56514
56819
|
return;
|
|
56515
56820
|
}
|
|
56516
|
-
let filePath =
|
|
56821
|
+
let filePath = path60.join(publicDir, pathname === "/" ? "index.html" : pathname);
|
|
56517
56822
|
if (!filePath.startsWith(publicDir)) {
|
|
56518
56823
|
notFound(res);
|
|
56519
56824
|
return;
|
|
56520
56825
|
}
|
|
56521
|
-
if (
|
|
56522
|
-
const ext =
|
|
56826
|
+
if (fs60.existsSync(filePath) && fs60.statSync(filePath).isFile()) {
|
|
56827
|
+
const ext = path60.extname(filePath);
|
|
56523
56828
|
const contentType = MIME[ext] ?? "application/octet-stream";
|
|
56524
56829
|
res.writeHead(200, { "Content-Type": contentType });
|
|
56525
|
-
|
|
56830
|
+
fs60.createReadStream(filePath).pipe(res);
|
|
56526
56831
|
return;
|
|
56527
56832
|
}
|
|
56528
|
-
filePath =
|
|
56529
|
-
if (
|
|
56833
|
+
filePath = path60.join(publicDir, "index.html");
|
|
56834
|
+
if (fs60.existsSync(filePath)) {
|
|
56530
56835
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
56531
|
-
|
|
56836
|
+
fs60.createReadStream(filePath).pipe(res);
|
|
56532
56837
|
return;
|
|
56533
56838
|
}
|
|
56534
56839
|
notFound(res);
|
|
@@ -56538,17 +56843,17 @@ function createDashboardServer(opts) {
|
|
|
56538
56843
|
}
|
|
56539
56844
|
|
|
56540
56845
|
// ../core/dist/dashboard/state.js
|
|
56541
|
-
import * as
|
|
56846
|
+
import * as fs61 from "node:fs";
|
|
56542
56847
|
import * as os35 from "node:os";
|
|
56543
|
-
import * as
|
|
56544
|
-
var STATE_PATH =
|
|
56848
|
+
import * as path61 from "node:path";
|
|
56849
|
+
var STATE_PATH = path61.join(os35.homedir(), ".olam", "dashboard.json");
|
|
56545
56850
|
function saveDashboardState(state) {
|
|
56546
|
-
|
|
56547
|
-
|
|
56851
|
+
fs61.mkdirSync(path61.dirname(STATE_PATH), { recursive: true });
|
|
56852
|
+
fs61.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
|
|
56548
56853
|
}
|
|
56549
56854
|
function loadDashboardState() {
|
|
56550
56855
|
try {
|
|
56551
|
-
const raw =
|
|
56856
|
+
const raw = fs61.readFileSync(STATE_PATH, "utf-8");
|
|
56552
56857
|
return JSON.parse(raw);
|
|
56553
56858
|
} catch {
|
|
56554
56859
|
return null;
|
|
@@ -56556,7 +56861,7 @@ function loadDashboardState() {
|
|
|
56556
56861
|
}
|
|
56557
56862
|
function clearDashboardState() {
|
|
56558
56863
|
try {
|
|
56559
|
-
|
|
56864
|
+
fs61.unlinkSync(STATE_PATH);
|
|
56560
56865
|
} catch {
|
|
56561
56866
|
}
|
|
56562
56867
|
}
|
|
@@ -56836,8 +57141,8 @@ var PleriClient = class {
|
|
|
56836
57141
|
};
|
|
56837
57142
|
|
|
56838
57143
|
// ../mcp-server/src/env-loader.ts
|
|
56839
|
-
import { readFileSync as
|
|
56840
|
-
import { join as
|
|
57144
|
+
import { readFileSync as readFileSync47, existsSync as existsSync60, statSync as statSync15 } from "node:fs";
|
|
57145
|
+
import { join as join64, dirname as dirname31, resolve as resolve15 } from "node:path";
|
|
56841
57146
|
var PROJECT_MARKERS = [
|
|
56842
57147
|
".olam/config.yaml",
|
|
56843
57148
|
".olam/config.yml",
|
|
@@ -56849,12 +57154,12 @@ function findProjectRoot2(startDir) {
|
|
|
56849
57154
|
const root = resolve15("/");
|
|
56850
57155
|
while (true) {
|
|
56851
57156
|
for (const marker of PROJECT_MARKERS) {
|
|
56852
|
-
if (
|
|
57157
|
+
if (existsSync60(join64(dir, marker))) return dir;
|
|
56853
57158
|
}
|
|
56854
|
-
const pkg =
|
|
56855
|
-
if (
|
|
57159
|
+
const pkg = join64(dir, "package.json");
|
|
57160
|
+
if (existsSync60(pkg)) {
|
|
56856
57161
|
try {
|
|
56857
|
-
const json2 = JSON.parse(
|
|
57162
|
+
const json2 = JSON.parse(readFileSync47(pkg, "utf8"));
|
|
56858
57163
|
const isOlamWorkspace = typeof json2.name === "string" && json2.name.startsWith("@olam/");
|
|
56859
57164
|
const hasOlamDep = json2.dependencies && Object.keys(json2.dependencies).some((k) => k.startsWith("@olam/")) || json2.devDependencies && Object.keys(json2.devDependencies).some((k) => k.startsWith("@olam/"));
|
|
56860
57165
|
if (isOlamWorkspace || hasOlamDep) return dir;
|
|
@@ -56866,9 +57171,9 @@ function findProjectRoot2(startDir) {
|
|
|
56866
57171
|
dir = parent;
|
|
56867
57172
|
}
|
|
56868
57173
|
}
|
|
56869
|
-
function parseEnvFile(
|
|
57174
|
+
function parseEnvFile(path62) {
|
|
56870
57175
|
const out = {};
|
|
56871
|
-
const raw =
|
|
57176
|
+
const raw = readFileSync47(path62, "utf8");
|
|
56872
57177
|
for (const line of raw.split(/\r?\n/)) {
|
|
56873
57178
|
const trimmed = line.trim();
|
|
56874
57179
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -56891,8 +57196,8 @@ function loadProjectEnv(startDir = process.cwd()) {
|
|
|
56891
57196
|
const filesRead = [];
|
|
56892
57197
|
const merged = {};
|
|
56893
57198
|
for (const name of [".env", ".env.local"]) {
|
|
56894
|
-
const p =
|
|
56895
|
-
if (
|
|
57199
|
+
const p = join64(root, name);
|
|
57200
|
+
if (existsSync60(p) && statSync15(p).isFile()) {
|
|
56896
57201
|
Object.assign(merged, parseEnvFile(p));
|
|
56897
57202
|
filesRead.push(p);
|
|
56898
57203
|
}
|