@pleri/olam-cli 0.1.206 → 0.1.208
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 +2907 -1932
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +1292 -932
- 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/memory-hooks/agentmemory-classify-queue.mjs +4 -0
- package/memory-hooks/agentmemory-recall-trigger.mjs +4 -0
- package/memory-hooks/agentmemory-save.mjs +138 -0
- package/memory-hooks/agentmemory-session-recall.js +27 -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 });
|
|
@@ -10908,24 +10908,62 @@ var require_dist = __commonJS({
|
|
|
10908
10908
|
}
|
|
10909
10909
|
});
|
|
10910
10910
|
|
|
10911
|
+
// ../core/dist/paths/olam-paths.js
|
|
10912
|
+
import { homedir } from "node:os";
|
|
10913
|
+
import { join as join2 } from "node:path";
|
|
10914
|
+
function olamHome() {
|
|
10915
|
+
const fromEnv = process.env["OLAM_HOME"];
|
|
10916
|
+
if (fromEnv && fromEnv.length > 0)
|
|
10917
|
+
return fromEnv;
|
|
10918
|
+
return join2(homedir(), ".olam");
|
|
10919
|
+
}
|
|
10920
|
+
function claudeDir() {
|
|
10921
|
+
const fromEnv = process.env["OLAM_CLAUDE_DIR"];
|
|
10922
|
+
if (fromEnv && fromEnv.length > 0)
|
|
10923
|
+
return fromEnv;
|
|
10924
|
+
return join2(homedir(), ".claude");
|
|
10925
|
+
}
|
|
10926
|
+
function globalConfigPath() {
|
|
10927
|
+
const override = process.env["OLAM_GLOBAL_CONFIG_PATH"];
|
|
10928
|
+
if (override && override.length > 0)
|
|
10929
|
+
return override;
|
|
10930
|
+
return join2(olamHome(), "config.json");
|
|
10931
|
+
}
|
|
10932
|
+
function stateDir() {
|
|
10933
|
+
const override = process.env["OLAM_STATE_DIR"];
|
|
10934
|
+
if (override && override.length > 0)
|
|
10935
|
+
return override;
|
|
10936
|
+
return join2(olamHome(), "state");
|
|
10937
|
+
}
|
|
10938
|
+
function skillSourcesDir() {
|
|
10939
|
+
const override = process.env["OLAM_SKILL_SOURCES_DIR"];
|
|
10940
|
+
if (override && override.length > 0)
|
|
10941
|
+
return override;
|
|
10942
|
+
return join2(stateDir(), "skill-sources");
|
|
10943
|
+
}
|
|
10944
|
+
var init_olam_paths = __esm({
|
|
10945
|
+
"../core/dist/paths/olam-paths.js"() {
|
|
10946
|
+
"use strict";
|
|
10947
|
+
}
|
|
10948
|
+
});
|
|
10949
|
+
|
|
10911
10950
|
// ../core/dist/secrets/paths.js
|
|
10912
10951
|
import * as fs2 from "node:fs";
|
|
10913
|
-
import * as os from "node:os";
|
|
10914
10952
|
import * as path2 from "node:path";
|
|
10915
|
-
function
|
|
10916
|
-
return
|
|
10953
|
+
function olamHome2() {
|
|
10954
|
+
return olamHome();
|
|
10917
10955
|
}
|
|
10918
10956
|
function canonicalSecretPath(name) {
|
|
10919
|
-
return path2.join(
|
|
10957
|
+
return path2.join(olamHome2(), "secrets", name);
|
|
10920
10958
|
}
|
|
10921
10959
|
function ensureSecretsDir() {
|
|
10922
|
-
fs2.mkdirSync(path2.join(
|
|
10960
|
+
fs2.mkdirSync(path2.join(olamHome2(), "secrets"), { recursive: true, mode: 448 });
|
|
10923
10961
|
}
|
|
10924
10962
|
function resolveSecretPath(name) {
|
|
10925
10963
|
const newPath = canonicalSecretPath(name);
|
|
10926
10964
|
if (fs2.existsSync(newPath))
|
|
10927
10965
|
return newPath;
|
|
10928
|
-
const oldPath = path2.join(
|
|
10966
|
+
const oldPath = path2.join(olamHome2(), name);
|
|
10929
10967
|
if (fs2.existsSync(oldPath)) {
|
|
10930
10968
|
if (!_warnedNames.has(name)) {
|
|
10931
10969
|
_warnedNames.add(name);
|
|
@@ -10942,6 +10980,7 @@ var _warnedNames;
|
|
|
10942
10980
|
var init_paths = __esm({
|
|
10943
10981
|
"../core/dist/secrets/paths.js"() {
|
|
10944
10982
|
"use strict";
|
|
10983
|
+
init_olam_paths();
|
|
10945
10984
|
_warnedNames = /* @__PURE__ */ new Set();
|
|
10946
10985
|
}
|
|
10947
10986
|
});
|
|
@@ -11048,12 +11087,12 @@ var init_version2 = __esm({
|
|
|
11048
11087
|
|
|
11049
11088
|
// ../core/dist/world/repo-manifest.js
|
|
11050
11089
|
import { existsSync as existsSync5, lstatSync, readFileSync as readFileSync3 } from "node:fs";
|
|
11051
|
-
import { join as
|
|
11090
|
+
import { join as join6, resolve as resolve3, sep } from "node:path";
|
|
11052
11091
|
import YAML from "yaml";
|
|
11053
11092
|
function bootstrapStepCmd(entry) {
|
|
11054
11093
|
return typeof entry === "string" ? entry : entry.cmd;
|
|
11055
11094
|
}
|
|
11056
|
-
function refineForbiddenKeys(value,
|
|
11095
|
+
function refineForbiddenKeys(value, path62, ctx, rejectSource) {
|
|
11057
11096
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
11058
11097
|
return;
|
|
11059
11098
|
}
|
|
@@ -11061,12 +11100,12 @@ function refineForbiddenKeys(value, path60, ctx, rejectSource) {
|
|
|
11061
11100
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
11062
11101
|
ctx.addIssue({
|
|
11063
11102
|
code: external_exports2.ZodIssueCode.custom,
|
|
11064
|
-
path: [...
|
|
11103
|
+
path: [...path62, key],
|
|
11065
11104
|
message: `forbidden key "${key}" (prototype-pollution surface)`
|
|
11066
11105
|
});
|
|
11067
11106
|
continue;
|
|
11068
11107
|
}
|
|
11069
|
-
if (rejectSource &&
|
|
11108
|
+
if (rejectSource && path62.length === 0 && key === "source") {
|
|
11070
11109
|
ctx.addIssue({
|
|
11071
11110
|
code: external_exports2.ZodIssueCode.custom,
|
|
11072
11111
|
path: ["source"],
|
|
@@ -11074,21 +11113,21 @@ function refineForbiddenKeys(value, path60, ctx, rejectSource) {
|
|
|
11074
11113
|
});
|
|
11075
11114
|
continue;
|
|
11076
11115
|
}
|
|
11077
|
-
refineForbiddenKeys(value[key], [...
|
|
11116
|
+
refineForbiddenKeys(value[key], [...path62, key], ctx, false);
|
|
11078
11117
|
}
|
|
11079
11118
|
}
|
|
11080
|
-
function rejectForbiddenKeys(value,
|
|
11119
|
+
function rejectForbiddenKeys(value, path62, rejectSource) {
|
|
11081
11120
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
11082
11121
|
return;
|
|
11083
11122
|
}
|
|
11084
11123
|
for (const key of Object.keys(value)) {
|
|
11085
11124
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
11086
|
-
throw new Error(`[manifest] ${
|
|
11125
|
+
throw new Error(`[manifest] ${path62}: forbidden key "${key}" (prototype-pollution surface)`);
|
|
11087
11126
|
}
|
|
11088
11127
|
if (rejectSource && key === "source") {
|
|
11089
|
-
throw new Error(`[manifest] ${
|
|
11128
|
+
throw new Error(`[manifest] ${path62}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
|
|
11090
11129
|
}
|
|
11091
|
-
rejectForbiddenKeys(value[key], `${
|
|
11130
|
+
rejectForbiddenKeys(value[key], `${path62}.${key}`, false);
|
|
11092
11131
|
}
|
|
11093
11132
|
}
|
|
11094
11133
|
function unknownTopLevelKeys(parsed) {
|
|
@@ -11112,8 +11151,8 @@ function isPlainObject3(value) {
|
|
|
11112
11151
|
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
11113
11152
|
}
|
|
11114
11153
|
function loadRepoManifest(repoDir) {
|
|
11115
|
-
const olamPath =
|
|
11116
|
-
const adbPath =
|
|
11154
|
+
const olamPath = join6(repoDir, ".olam.yaml");
|
|
11155
|
+
const adbPath = join6(repoDir, ".adb.yaml");
|
|
11117
11156
|
let manifestPath2;
|
|
11118
11157
|
let source;
|
|
11119
11158
|
if (existsSync5(olamPath)) {
|
|
@@ -11354,13 +11393,13 @@ var init_repo_manifest = __esm({
|
|
|
11354
11393
|
});
|
|
11355
11394
|
|
|
11356
11395
|
// ../core/dist/util/path.js
|
|
11357
|
-
import * as
|
|
11396
|
+
import * as os3 from "node:os";
|
|
11358
11397
|
import * as path6 from "node:path";
|
|
11359
11398
|
function resolveTildePath(p) {
|
|
11360
11399
|
if (p === "~")
|
|
11361
|
-
return
|
|
11400
|
+
return os3.homedir();
|
|
11362
11401
|
if (p.startsWith("~/"))
|
|
11363
|
-
return path6.join(
|
|
11402
|
+
return path6.join(os3.homedir(), p.slice(2));
|
|
11364
11403
|
if (p.startsWith("~")) {
|
|
11365
11404
|
throw new Error(`[path] POSIX "~user" syntax is not supported (got "${p}"). Use "~/..." for the operator's home or an absolute path.`);
|
|
11366
11405
|
}
|
|
@@ -11376,14 +11415,14 @@ var init_path = __esm({
|
|
|
11376
11415
|
|
|
11377
11416
|
// ../core/dist/workspace/store.js
|
|
11378
11417
|
import * as fs5 from "node:fs";
|
|
11379
|
-
import * as
|
|
11418
|
+
import * as os4 from "node:os";
|
|
11380
11419
|
import * as path7 from "node:path";
|
|
11381
11420
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
11382
11421
|
function workspacesDir() {
|
|
11383
11422
|
const override = process.env["OLAM_WORKSPACES_DIR"];
|
|
11384
11423
|
if (override && override.length > 0)
|
|
11385
11424
|
return override;
|
|
11386
|
-
return path7.join(
|
|
11425
|
+
return path7.join(os4.homedir(), ".olam", "workspaces");
|
|
11387
11426
|
}
|
|
11388
11427
|
function validateName(name) {
|
|
11389
11428
|
if (!WORKSPACE_NAME_PATTERN.test(name)) {
|
|
@@ -11752,7 +11791,7 @@ var init_volume = __esm({
|
|
|
11752
11791
|
|
|
11753
11792
|
// ../adapters/dist/shared/anthropic-base-url.js
|
|
11754
11793
|
import * as fs6 from "node:fs";
|
|
11755
|
-
import * as
|
|
11794
|
+
import * as os5 from "node:os";
|
|
11756
11795
|
import * as path8 from "node:path";
|
|
11757
11796
|
function normalizeAnthropicBaseUrl(raw) {
|
|
11758
11797
|
if (!raw)
|
|
@@ -11780,7 +11819,7 @@ function readAnthropicBaseUrl() {
|
|
|
11780
11819
|
if (fromOlamEnv && fromOlamEnv.length > 0) {
|
|
11781
11820
|
return normalizeAnthropicBaseUrl(fromOlamEnv.trim());
|
|
11782
11821
|
}
|
|
11783
|
-
const file2 = path8.join(
|
|
11822
|
+
const file2 = path8.join(os5.homedir(), ".olam", "anthropic-base-url");
|
|
11784
11823
|
try {
|
|
11785
11824
|
const content = fs6.readFileSync(file2, "utf-8").trim();
|
|
11786
11825
|
if (content.length > 0)
|
|
@@ -12458,7 +12497,7 @@ var init_loader = __esm({
|
|
|
12458
12497
|
|
|
12459
12498
|
// ../adapters/dist/docker/container.js
|
|
12460
12499
|
import * as fs9 from "node:fs";
|
|
12461
|
-
import * as
|
|
12500
|
+
import * as os6 from "node:os";
|
|
12462
12501
|
import * as path10 from "node:path";
|
|
12463
12502
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
12464
12503
|
function readAuthSecret() {
|
|
@@ -12476,7 +12515,7 @@ function readHostCpToken() {
|
|
|
12476
12515
|
const fromEnv = process.env["OLAM_HOST_CP_TOKEN"];
|
|
12477
12516
|
if (fromEnv && fromEnv.length > 0)
|
|
12478
12517
|
return fromEnv;
|
|
12479
|
-
const file2 = path10.join(
|
|
12518
|
+
const file2 = path10.join(os6.homedir(), ".olam", "host-cp.token");
|
|
12480
12519
|
try {
|
|
12481
12520
|
return fs9.readFileSync(file2, "utf-8").trim();
|
|
12482
12521
|
} catch {
|
|
@@ -12499,9 +12538,9 @@ function isKubernetesServiceSubstrate() {
|
|
|
12499
12538
|
}
|
|
12500
12539
|
function expandHome(p) {
|
|
12501
12540
|
if (p.startsWith("~/"))
|
|
12502
|
-
return path10.join(
|
|
12541
|
+
return path10.join(os6.homedir(), p.slice(2));
|
|
12503
12542
|
if (p === "~")
|
|
12504
|
-
return
|
|
12543
|
+
return os6.homedir();
|
|
12505
12544
|
return p;
|
|
12506
12545
|
}
|
|
12507
12546
|
function readCloudMemorySecretAtPath(secretRef) {
|
|
@@ -12743,7 +12782,7 @@ var init_container = __esm({
|
|
|
12743
12782
|
...env
|
|
12744
12783
|
};
|
|
12745
12784
|
const envList = Object.entries(worldEnv).map(([k, v]) => `${k}=${v}`);
|
|
12746
|
-
const olamHomeDir = process.env["HOME"] ??
|
|
12785
|
+
const olamHomeDir = process.env["HOME"] ?? os6.homedir();
|
|
12747
12786
|
const hostWorkspacesDir = `${olamHomeDir}/.olam/workspaces`;
|
|
12748
12787
|
const binds = [
|
|
12749
12788
|
"/var/run/docker.sock:/var/run/docker.sock",
|
|
@@ -13873,8 +13912,8 @@ var init_provider3 = __esm({
|
|
|
13873
13912
|
// -----------------------------------------------------------------------
|
|
13874
13913
|
// Internal fetch helper
|
|
13875
13914
|
// -----------------------------------------------------------------------
|
|
13876
|
-
async request(
|
|
13877
|
-
const url3 = `${this.config.workerUrl}${
|
|
13915
|
+
async request(path62, method, body) {
|
|
13916
|
+
const url3 = `${this.config.workerUrl}${path62}`;
|
|
13878
13917
|
const bearer = await this.config.mintToken();
|
|
13879
13918
|
const headers = {
|
|
13880
13919
|
Authorization: `Bearer ${bearer}`
|
|
@@ -14245,19 +14284,19 @@ var init_schema4 = __esm({
|
|
|
14245
14284
|
|
|
14246
14285
|
// ../core/dist/global-config/store.js
|
|
14247
14286
|
import * as fs13 from "node:fs";
|
|
14248
|
-
import * as
|
|
14287
|
+
import * as os8 from "node:os";
|
|
14249
14288
|
import * as path16 from "node:path";
|
|
14250
|
-
function
|
|
14289
|
+
function globalConfigPath2() {
|
|
14251
14290
|
const override = process.env["OLAM_GLOBAL_CONFIG_PATH"];
|
|
14252
14291
|
if (override && override.length > 0)
|
|
14253
14292
|
return override;
|
|
14254
14293
|
if (process.env["VITEST"]) {
|
|
14255
|
-
return path16.join(
|
|
14294
|
+
return path16.join(os8.tmpdir(), `olam-vitest-global-config-${process.pid}.json`);
|
|
14256
14295
|
}
|
|
14257
|
-
return
|
|
14296
|
+
return globalConfigPath();
|
|
14258
14297
|
}
|
|
14259
14298
|
function readGlobalConfig() {
|
|
14260
|
-
const configPath =
|
|
14299
|
+
const configPath = globalConfigPath2();
|
|
14261
14300
|
if (!fs13.existsSync(configPath)) {
|
|
14262
14301
|
return { ...DEFAULT_GLOBAL_CONFIG };
|
|
14263
14302
|
}
|
|
@@ -14283,9 +14322,80 @@ function readGlobalConfig() {
|
|
|
14283
14322
|
}
|
|
14284
14323
|
}
|
|
14285
14324
|
return validated;
|
|
14286
|
-
} catch (
|
|
14287
|
-
|
|
14325
|
+
} catch (strictErr) {
|
|
14326
|
+
const salvaged = quarantineGlobalConfig(migrated.value);
|
|
14327
|
+
if (salvaged !== null) {
|
|
14328
|
+
let backupPath = null;
|
|
14329
|
+
try {
|
|
14330
|
+
backupPath = `${configPath}.quarantine-${Date.now()}`;
|
|
14331
|
+
fs13.copyFileSync(configPath, backupPath);
|
|
14332
|
+
} catch {
|
|
14333
|
+
backupPath = null;
|
|
14334
|
+
}
|
|
14335
|
+
try {
|
|
14336
|
+
writeGlobalConfig(salvaged.value);
|
|
14337
|
+
} catch {
|
|
14338
|
+
}
|
|
14339
|
+
quarantineSink(configPath, { drops: salvaged.drops, backupPath });
|
|
14340
|
+
return salvaged.value;
|
|
14341
|
+
}
|
|
14342
|
+
throw new GlobalConfigReadError(configPath, strictErr);
|
|
14343
|
+
}
|
|
14344
|
+
}
|
|
14345
|
+
function quarantineGlobalConfig(migratedValue) {
|
|
14346
|
+
if (migratedValue === null || typeof migratedValue !== "object" || Array.isArray(migratedValue)) {
|
|
14347
|
+
return null;
|
|
14288
14348
|
}
|
|
14349
|
+
const obj = migratedValue;
|
|
14350
|
+
const drops = [];
|
|
14351
|
+
const filterField = (field, schema, dedupeKeys) => {
|
|
14352
|
+
const v = obj[field];
|
|
14353
|
+
if (v === void 0)
|
|
14354
|
+
return [];
|
|
14355
|
+
if (!Array.isArray(v)) {
|
|
14356
|
+
drops.push({ field, entry: v, reason: `${field} is not an array` });
|
|
14357
|
+
return [];
|
|
14358
|
+
}
|
|
14359
|
+
const out = [];
|
|
14360
|
+
const seen = dedupeKeys.map(() => /* @__PURE__ */ new Set());
|
|
14361
|
+
for (const e of v) {
|
|
14362
|
+
const r = schema.safeParse(e);
|
|
14363
|
+
if (!r.success || r.data === void 0) {
|
|
14364
|
+
drops.push({ field, entry: e, reason: r.error?.issues[0]?.message ?? "invalid entry" });
|
|
14365
|
+
continue;
|
|
14366
|
+
}
|
|
14367
|
+
let dupeKey = null;
|
|
14368
|
+
for (let i = 0; i < dedupeKeys.length; i++) {
|
|
14369
|
+
const k = dedupeKeys[i](r.data);
|
|
14370
|
+
if (seen[i].has(k)) {
|
|
14371
|
+
dupeKey = k;
|
|
14372
|
+
break;
|
|
14373
|
+
}
|
|
14374
|
+
}
|
|
14375
|
+
if (dupeKey !== null) {
|
|
14376
|
+
drops.push({ field, entry: e, reason: `duplicate key "${dupeKey}"` });
|
|
14377
|
+
continue;
|
|
14378
|
+
}
|
|
14379
|
+
for (let i = 0; i < dedupeKeys.length; i++)
|
|
14380
|
+
seen[i].add(dedupeKeys[i](r.data));
|
|
14381
|
+
out.push(r.data);
|
|
14382
|
+
}
|
|
14383
|
+
return out;
|
|
14384
|
+
};
|
|
14385
|
+
const repos = filterField("repos", RepoEntrySchema, [(r) => r.name]);
|
|
14386
|
+
const runbooks = filterField("runbooks", RunbookSchema, [(r) => r.name]);
|
|
14387
|
+
const skillSources = filterField("skillSources", SkillSourceSchema, [
|
|
14388
|
+
(s) => s.id,
|
|
14389
|
+
(s) => s.name
|
|
14390
|
+
]);
|
|
14391
|
+
const metaHooksDisabled = filterField("metaHooksDisabled", MetaHookBlockKindSchema, [
|
|
14392
|
+
(m) => m
|
|
14393
|
+
]);
|
|
14394
|
+
const candidate = { schemaVersion: 1, repos, runbooks, skillSources, metaHooksDisabled };
|
|
14395
|
+
const final = GlobalConfigSchema.safeParse(candidate);
|
|
14396
|
+
if (!final.success)
|
|
14397
|
+
return null;
|
|
14398
|
+
return { value: final.data, drops };
|
|
14289
14399
|
}
|
|
14290
14400
|
function migrateSchemaVersion(parsed) {
|
|
14291
14401
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -14298,7 +14408,7 @@ function migrateSchemaVersion(parsed) {
|
|
|
14298
14408
|
return { value: { ...obj, schemaVersion: 1 }, changed: true };
|
|
14299
14409
|
}
|
|
14300
14410
|
function writeGlobalConfig(config2) {
|
|
14301
|
-
const configPath =
|
|
14411
|
+
const configPath = globalConfigPath2();
|
|
14302
14412
|
const validated = GlobalConfigSchema.parse(config2);
|
|
14303
14413
|
const dir = path16.dirname(configPath);
|
|
14304
14414
|
fs13.mkdirSync(dir, { recursive: true });
|
|
@@ -14306,11 +14416,27 @@ function writeGlobalConfig(config2) {
|
|
|
14306
14416
|
fs13.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
|
|
14307
14417
|
fs13.renameSync(tmp, configPath);
|
|
14308
14418
|
}
|
|
14309
|
-
var GlobalConfigReadError;
|
|
14419
|
+
var quarantineSink, GlobalConfigReadError;
|
|
14310
14420
|
var init_store2 = __esm({
|
|
14311
14421
|
"../core/dist/global-config/store.js"() {
|
|
14312
14422
|
"use strict";
|
|
14313
14423
|
init_schema4();
|
|
14424
|
+
init_schema3();
|
|
14425
|
+
init_olam_paths();
|
|
14426
|
+
quarantineSink = (configPath, report) => {
|
|
14427
|
+
if (report.drops.length === 0)
|
|
14428
|
+
return;
|
|
14429
|
+
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
|
|
14430
|
+
`);
|
|
14431
|
+
for (const d of report.drops) {
|
|
14432
|
+
process.stderr.write(` \xB7 ${d.field}: ${d.reason}
|
|
14433
|
+
`);
|
|
14434
|
+
}
|
|
14435
|
+
if (report.backupPath) {
|
|
14436
|
+
process.stderr.write(` \u2192 original backed up to ${report.backupPath}
|
|
14437
|
+
`);
|
|
14438
|
+
}
|
|
14439
|
+
};
|
|
14314
14440
|
GlobalConfigReadError = class extends Error {
|
|
14315
14441
|
constructor(configPath, cause) {
|
|
14316
14442
|
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
@@ -14324,11 +14450,11 @@ var init_store2 = __esm({
|
|
|
14324
14450
|
|
|
14325
14451
|
// ../core/dist/global-config/repos.js
|
|
14326
14452
|
import * as fs14 from "node:fs";
|
|
14327
|
-
import * as
|
|
14453
|
+
import * as os9 from "node:os";
|
|
14328
14454
|
import * as path17 from "node:path";
|
|
14329
14455
|
function expandPath(p) {
|
|
14330
14456
|
if (p === "~" || p.startsWith("~/")) {
|
|
14331
|
-
return path17.join(
|
|
14457
|
+
return path17.join(os9.homedir(), p.slice(1));
|
|
14332
14458
|
}
|
|
14333
14459
|
return p;
|
|
14334
14460
|
}
|
|
@@ -14608,13 +14734,11 @@ var init_bridge = __esm({
|
|
|
14608
14734
|
// ../core/dist/skill-sources/trust-audit-log.js
|
|
14609
14735
|
import * as fs16 from "node:fs";
|
|
14610
14736
|
import * as path18 from "node:path";
|
|
14611
|
-
import * as os11 from "node:os";
|
|
14612
14737
|
function skillSourcesAuditLogPath() {
|
|
14613
14738
|
const override = process.env["OLAM_SKILL_SOURCES_AUDIT_LOG_PATH"];
|
|
14614
14739
|
if (override && override.length > 0)
|
|
14615
14740
|
return override;
|
|
14616
|
-
|
|
14617
|
-
return path18.join(stateDir, SKILL_SOURCES_AUDIT_LOG_FILENAME);
|
|
14741
|
+
return path18.join(stateDir(), SKILL_SOURCES_AUDIT_LOG_FILENAME);
|
|
14618
14742
|
}
|
|
14619
14743
|
function appendTrustAudit(entry) {
|
|
14620
14744
|
const candidate = {
|
|
@@ -14658,6 +14782,7 @@ var init_trust_audit_log = __esm({
|
|
|
14658
14782
|
"../core/dist/skill-sources/trust-audit-log.js"() {
|
|
14659
14783
|
"use strict";
|
|
14660
14784
|
init_v3();
|
|
14785
|
+
init_olam_paths();
|
|
14661
14786
|
SKILL_SOURCES_AUDIT_LOG_FILENAME = "skill-sources-audit.log";
|
|
14662
14787
|
TrustActionSchema = external_exports2.enum([
|
|
14663
14788
|
"added",
|
|
@@ -14684,6 +14809,142 @@ var init_trust_audit_log = __esm({
|
|
|
14684
14809
|
}
|
|
14685
14810
|
});
|
|
14686
14811
|
|
|
14812
|
+
// ../core/dist/skill-sources/clone.js
|
|
14813
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
14814
|
+
import * as fs17 from "node:fs";
|
|
14815
|
+
import * as path19 from "node:path";
|
|
14816
|
+
function skillSourcesRootDir() {
|
|
14817
|
+
return skillSourcesDir();
|
|
14818
|
+
}
|
|
14819
|
+
function skillSourceClonePath(id) {
|
|
14820
|
+
return path19.join(skillSourcesRootDir(), id);
|
|
14821
|
+
}
|
|
14822
|
+
function runGit(args, cwd) {
|
|
14823
|
+
try {
|
|
14824
|
+
return execFileSync2("git", args, {
|
|
14825
|
+
cwd,
|
|
14826
|
+
encoding: "utf-8",
|
|
14827
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
14828
|
+
});
|
|
14829
|
+
} catch (err) {
|
|
14830
|
+
throw err;
|
|
14831
|
+
}
|
|
14832
|
+
}
|
|
14833
|
+
function cloneSkillSource(opts) {
|
|
14834
|
+
const clonePath = skillSourceClonePath(opts.id);
|
|
14835
|
+
if (fs17.existsSync(clonePath)) {
|
|
14836
|
+
throw new Error(`clone path "${clonePath}" already exists. Remove the existing skill-source first.`);
|
|
14837
|
+
}
|
|
14838
|
+
fs17.mkdirSync(skillSourcesRootDir(), { recursive: true });
|
|
14839
|
+
try {
|
|
14840
|
+
runGit(["clone", "--depth", "1", "--branch", opts.branch, opts.gitUrl, clonePath]);
|
|
14841
|
+
} catch (err) {
|
|
14842
|
+
if (fs17.existsSync(clonePath)) {
|
|
14843
|
+
fs17.rmSync(clonePath, { recursive: true, force: true });
|
|
14844
|
+
}
|
|
14845
|
+
throw new SkillSourceGitError("clone", opts.gitUrl, err);
|
|
14846
|
+
}
|
|
14847
|
+
let headSha;
|
|
14848
|
+
try {
|
|
14849
|
+
headSha = runGit(["rev-parse", "HEAD"], clonePath).trim();
|
|
14850
|
+
} catch (err) {
|
|
14851
|
+
throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
|
|
14852
|
+
}
|
|
14853
|
+
return { clonePath, headSha };
|
|
14854
|
+
}
|
|
14855
|
+
function pullSkillSource(opts) {
|
|
14856
|
+
const clonePath = skillSourceClonePath(opts.id);
|
|
14857
|
+
if (!fs17.existsSync(clonePath)) {
|
|
14858
|
+
throw new Error(`clone path "${clonePath}" does not exist. Run "olam skills source add" first.`);
|
|
14859
|
+
}
|
|
14860
|
+
try {
|
|
14861
|
+
runGit(["fetch", "origin", opts.branch], clonePath);
|
|
14862
|
+
runGit(["reset", "--hard", `origin/${opts.branch}`], clonePath);
|
|
14863
|
+
} catch (err) {
|
|
14864
|
+
throw new SkillSourceGitError("fetch/reset", opts.gitUrl, err);
|
|
14865
|
+
}
|
|
14866
|
+
try {
|
|
14867
|
+
const headSha = runGit(["rev-parse", "HEAD"], clonePath).trim();
|
|
14868
|
+
return { headSha };
|
|
14869
|
+
} catch (err) {
|
|
14870
|
+
throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
|
|
14871
|
+
}
|
|
14872
|
+
}
|
|
14873
|
+
function removeSkillSourceClone(id) {
|
|
14874
|
+
const clonePath = skillSourceClonePath(id);
|
|
14875
|
+
if (fs17.existsSync(clonePath)) {
|
|
14876
|
+
fs17.rmSync(clonePath, { recursive: true, force: true });
|
|
14877
|
+
}
|
|
14878
|
+
}
|
|
14879
|
+
var SkillSourceGitError;
|
|
14880
|
+
var init_clone = __esm({
|
|
14881
|
+
"../core/dist/skill-sources/clone.js"() {
|
|
14882
|
+
"use strict";
|
|
14883
|
+
init_olam_paths();
|
|
14884
|
+
SkillSourceGitError = class extends Error {
|
|
14885
|
+
op;
|
|
14886
|
+
gitUrl;
|
|
14887
|
+
constructor(op, gitUrl, cause) {
|
|
14888
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
14889
|
+
super(`git ${op} failed for "${gitUrl}": ${msg}`);
|
|
14890
|
+
this.op = op;
|
|
14891
|
+
this.gitUrl = gitUrl;
|
|
14892
|
+
this.name = "SkillSourceGitError";
|
|
14893
|
+
this.cause = cause;
|
|
14894
|
+
}
|
|
14895
|
+
};
|
|
14896
|
+
}
|
|
14897
|
+
});
|
|
14898
|
+
|
|
14899
|
+
// ../core/dist/skill-sources/source-file.js
|
|
14900
|
+
import * as fs18 from "node:fs";
|
|
14901
|
+
import * as path20 from "node:path";
|
|
14902
|
+
function sourceSidecarPath(id) {
|
|
14903
|
+
return path20.join(skillSourceClonePath(id), SOURCE_SIDECAR_FILENAME);
|
|
14904
|
+
}
|
|
14905
|
+
function writeSourceSidecar(entry) {
|
|
14906
|
+
const clonePath = skillSourceClonePath(entry.id);
|
|
14907
|
+
if (!fs18.existsSync(clonePath))
|
|
14908
|
+
return false;
|
|
14909
|
+
try {
|
|
14910
|
+
const validated = SourceSidecarSchema.parse(entry);
|
|
14911
|
+
const target = sourceSidecarPath(entry.id);
|
|
14912
|
+
const tmp = `${target}.tmp-${process.pid}`;
|
|
14913
|
+
fs18.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
|
|
14914
|
+
fs18.renameSync(tmp, target);
|
|
14915
|
+
return true;
|
|
14916
|
+
} catch {
|
|
14917
|
+
return false;
|
|
14918
|
+
}
|
|
14919
|
+
}
|
|
14920
|
+
function readSourceSidecar(id) {
|
|
14921
|
+
const target = sourceSidecarPath(id);
|
|
14922
|
+
let raw;
|
|
14923
|
+
try {
|
|
14924
|
+
raw = fs18.readFileSync(target, "utf-8");
|
|
14925
|
+
} catch {
|
|
14926
|
+
return null;
|
|
14927
|
+
}
|
|
14928
|
+
let parsed;
|
|
14929
|
+
try {
|
|
14930
|
+
parsed = JSON.parse(raw);
|
|
14931
|
+
} catch {
|
|
14932
|
+
return null;
|
|
14933
|
+
}
|
|
14934
|
+
const result = SourceSidecarSchema.safeParse(parsed);
|
|
14935
|
+
return result.success ? result.data : null;
|
|
14936
|
+
}
|
|
14937
|
+
var SOURCE_SIDECAR_FILENAME, SourceSidecarSchema;
|
|
14938
|
+
var init_source_file = __esm({
|
|
14939
|
+
"../core/dist/skill-sources/source-file.js"() {
|
|
14940
|
+
"use strict";
|
|
14941
|
+
init_schema3();
|
|
14942
|
+
init_clone();
|
|
14943
|
+
SOURCE_SIDECAR_FILENAME = ".olam-source.json";
|
|
14944
|
+
SourceSidecarSchema = SkillSourceSchema;
|
|
14945
|
+
}
|
|
14946
|
+
});
|
|
14947
|
+
|
|
14687
14948
|
// ../core/dist/skill-sources/store.js
|
|
14688
14949
|
import * as crypto3 from "node:crypto";
|
|
14689
14950
|
function deriveSkillSourceId(gitUrl) {
|
|
@@ -14716,6 +14977,7 @@ function addSkillSource(entry) {
|
|
|
14716
14977
|
addedAt: now
|
|
14717
14978
|
};
|
|
14718
14979
|
writeGlobalConfig({ ...config2, skillSources: [...config2.skillSources, newEntry] });
|
|
14980
|
+
writeSourceSidecar(newEntry);
|
|
14719
14981
|
try {
|
|
14720
14982
|
appendTrustAudit({
|
|
14721
14983
|
gitUrl: redactUrl2(entry.gitUrl),
|
|
@@ -14833,6 +15095,7 @@ function updateSkillSource(id, patch) {
|
|
|
14833
15095
|
const next = [...config2.skillSources];
|
|
14834
15096
|
next[idx] = updated;
|
|
14835
15097
|
writeGlobalConfig({ ...config2, skillSources: next });
|
|
15098
|
+
writeSourceSidecar(updated);
|
|
14836
15099
|
return updated;
|
|
14837
15100
|
}
|
|
14838
15101
|
var PREFIX_PATTERN3;
|
|
@@ -14843,102 +15106,141 @@ var init_store3 = __esm({
|
|
|
14843
15106
|
init_schema3();
|
|
14844
15107
|
init_trust_audit_log();
|
|
14845
15108
|
init_source_config_schema();
|
|
15109
|
+
init_source_file();
|
|
14846
15110
|
PREFIX_PATTERN3 = /^[a-z0-9][a-z0-9_-]{0,38}$/;
|
|
14847
15111
|
}
|
|
14848
15112
|
});
|
|
14849
15113
|
|
|
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) {
|
|
15114
|
+
// ../core/dist/skill-sources/reconcile.js
|
|
15115
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
15116
|
+
import * as fs19 from "node:fs";
|
|
15117
|
+
import * as path21 from "node:path";
|
|
15118
|
+
function gitRead(args, cwd) {
|
|
14865
15119
|
try {
|
|
14866
|
-
return
|
|
15120
|
+
return execFileSync3("git", args, {
|
|
14867
15121
|
cwd,
|
|
14868
15122
|
encoding: "utf-8",
|
|
14869
|
-
stdio: ["ignore", "pipe", "
|
|
14870
|
-
});
|
|
14871
|
-
} catch
|
|
14872
|
-
|
|
15123
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
15124
|
+
}).trim();
|
|
15125
|
+
} catch {
|
|
15126
|
+
return null;
|
|
14873
15127
|
}
|
|
14874
15128
|
}
|
|
14875
|
-
function
|
|
14876
|
-
const
|
|
14877
|
-
if (
|
|
14878
|
-
|
|
14879
|
-
|
|
14880
|
-
|
|
15129
|
+
function nameFromGitUrl(gitUrl) {
|
|
15130
|
+
const tail = gitUrl.replace(/\.git$/, "").replace(/\/+$/, "").split(/[/:]/).filter((s) => s.length > 0).pop();
|
|
15131
|
+
if (!tail)
|
|
15132
|
+
return null;
|
|
15133
|
+
const sanitized = tail.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
15134
|
+
return NAME_PATTERN2.test(sanitized) ? sanitized : null;
|
|
15135
|
+
}
|
|
15136
|
+
function recoverFromGit(id, clonePath) {
|
|
15137
|
+
const gitUrl = gitRead(["remote", "get-url", "origin"], clonePath);
|
|
15138
|
+
if (!gitUrl)
|
|
15139
|
+
return null;
|
|
15140
|
+
const branch = gitRead(["symbolic-ref", "--short", "HEAD"], clonePath) ?? gitRead(["rev-parse", "--abbrev-ref", "HEAD"], clonePath) ?? "main";
|
|
15141
|
+
const headSha = gitRead(["rev-parse", "HEAD"], clonePath);
|
|
15142
|
+
let addedAt = 0;
|
|
14881
15143
|
try {
|
|
14882
|
-
|
|
14883
|
-
} catch
|
|
14884
|
-
|
|
14885
|
-
fs17.rmSync(clonePath, { recursive: true, force: true });
|
|
14886
|
-
}
|
|
14887
|
-
throw new SkillSourceGitError("clone", opts.gitUrl, err);
|
|
15144
|
+
addedAt = Math.floor(fs19.statSync(clonePath).ctimeMs);
|
|
15145
|
+
} catch {
|
|
15146
|
+
addedAt = 0;
|
|
14888
15147
|
}
|
|
14889
|
-
|
|
15148
|
+
const entry = {
|
|
15149
|
+
id,
|
|
15150
|
+
name: nameFromGitUrl(gitUrl) ?? `source-${id}`,
|
|
15151
|
+
gitUrl,
|
|
15152
|
+
branch,
|
|
15153
|
+
addedAt,
|
|
15154
|
+
...headSha && SHA_PATTERN.test(headSha) ? { lastPulledSha: headSha } : {}
|
|
15155
|
+
};
|
|
15156
|
+
return entry;
|
|
15157
|
+
}
|
|
15158
|
+
function listCloneIds() {
|
|
15159
|
+
const root = skillSourcesRootDir();
|
|
15160
|
+
let dirents;
|
|
14890
15161
|
try {
|
|
14891
|
-
|
|
14892
|
-
} catch
|
|
14893
|
-
|
|
15162
|
+
dirents = fs19.readdirSync(root, { withFileTypes: true });
|
|
15163
|
+
} catch {
|
|
15164
|
+
return [];
|
|
14894
15165
|
}
|
|
14895
|
-
return
|
|
15166
|
+
return dirents.filter((d) => d.isDirectory() && fs19.existsSync(path21.join(root, d.name, ".git"))).map((d) => d.name);
|
|
14896
15167
|
}
|
|
14897
|
-
function
|
|
14898
|
-
const
|
|
14899
|
-
|
|
14900
|
-
|
|
15168
|
+
function reconcileSkillSources(opts = {}) {
|
|
15169
|
+
const config2 = readGlobalConfig();
|
|
15170
|
+
const existingById = new Map(config2.skillSources.map((s) => [s.id, s]));
|
|
15171
|
+
const diskIds = new Set(listCloneIds());
|
|
15172
|
+
const added = [];
|
|
15173
|
+
const registryOnly = [];
|
|
15174
|
+
const sidecarsBackfilled = [];
|
|
15175
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
15176
|
+
const ensureUniqueName = (entry) => {
|
|
15177
|
+
if (!usedNames.has(entry.name)) {
|
|
15178
|
+
usedNames.add(entry.name);
|
|
15179
|
+
return entry;
|
|
15180
|
+
}
|
|
15181
|
+
const suffixed = `${entry.name}-${entry.id.slice(0, 6)}`.slice(0, 64).replace(/-+$/g, "");
|
|
15182
|
+
usedNames.add(suffixed);
|
|
15183
|
+
return { ...entry, name: suffixed };
|
|
15184
|
+
};
|
|
15185
|
+
const next = [];
|
|
15186
|
+
for (const entry of config2.skillSources) {
|
|
15187
|
+
if (diskIds.has(entry.id)) {
|
|
15188
|
+
usedNames.add(entry.name);
|
|
15189
|
+
next.push(entry);
|
|
15190
|
+
} else {
|
|
15191
|
+
registryOnly.push(entry);
|
|
15192
|
+
if (!opts.prune) {
|
|
15193
|
+
usedNames.add(entry.name);
|
|
15194
|
+
next.push(entry);
|
|
15195
|
+
}
|
|
15196
|
+
}
|
|
14901
15197
|
}
|
|
14902
|
-
|
|
14903
|
-
|
|
14904
|
-
|
|
14905
|
-
|
|
14906
|
-
|
|
15198
|
+
for (const id of diskIds) {
|
|
15199
|
+
if (existingById.has(id)) {
|
|
15200
|
+
if (readSourceSidecar(id) === null && writeSourceSidecar(existingById.get(id))) {
|
|
15201
|
+
sidecarsBackfilled.push(id);
|
|
15202
|
+
}
|
|
15203
|
+
continue;
|
|
15204
|
+
}
|
|
15205
|
+
const sidecar = readSourceSidecar(id);
|
|
15206
|
+
const recovered = sidecar ? { ...sidecar, id } : recoverFromGit(id, skillSourceClonePath(id));
|
|
15207
|
+
if (recovered === null)
|
|
15208
|
+
continue;
|
|
15209
|
+
const unique = ensureUniqueName(recovered);
|
|
15210
|
+
next.push(unique);
|
|
15211
|
+
added.push(unique);
|
|
15212
|
+
if (sidecar === null && writeSourceSidecar(unique))
|
|
15213
|
+
sidecarsBackfilled.push(id);
|
|
14907
15214
|
}
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
|
|
14912
|
-
throw new SkillSourceGitError("rev-parse", opts.gitUrl, err);
|
|
15215
|
+
const pruned = opts.prune ? registryOnly : [];
|
|
15216
|
+
const changed = next.length !== config2.skillSources.length || next.some((e, i) => e !== config2.skillSources[i]);
|
|
15217
|
+
if (changed) {
|
|
15218
|
+
writeGlobalConfig({ ...config2, skillSources: next });
|
|
14913
15219
|
}
|
|
15220
|
+
return { added, registryOnly, pruned, sidecarsBackfilled, changed };
|
|
14914
15221
|
}
|
|
14915
|
-
function
|
|
14916
|
-
|
|
14917
|
-
|
|
14918
|
-
|
|
14919
|
-
|
|
15222
|
+
function reconcileIfRegistryEmpty() {
|
|
15223
|
+
if (readGlobalConfig().skillSources.length > 0)
|
|
15224
|
+
return null;
|
|
15225
|
+
if (listCloneIds().length === 0)
|
|
15226
|
+
return null;
|
|
15227
|
+
return reconcileSkillSources();
|
|
14920
15228
|
}
|
|
14921
|
-
var
|
|
14922
|
-
var
|
|
14923
|
-
"../core/dist/skill-sources/
|
|
15229
|
+
var NAME_PATTERN2, SHA_PATTERN;
|
|
15230
|
+
var init_reconcile = __esm({
|
|
15231
|
+
"../core/dist/skill-sources/reconcile.js"() {
|
|
14924
15232
|
"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
|
-
};
|
|
15233
|
+
init_store2();
|
|
15234
|
+
init_schema3();
|
|
15235
|
+
init_clone();
|
|
15236
|
+
init_source_file();
|
|
15237
|
+
NAME_PATTERN2 = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
15238
|
+
SHA_PATTERN = /^[a-f0-9]{40}$/;
|
|
14937
15239
|
}
|
|
14938
15240
|
});
|
|
14939
15241
|
|
|
14940
15242
|
// ../core/dist/skill-sources/hook-template.js
|
|
14941
|
-
import * as
|
|
15243
|
+
import * as fs20 from "node:fs";
|
|
14942
15244
|
function buildSkillsHookEntry() {
|
|
14943
15245
|
return {
|
|
14944
15246
|
matcher: "",
|
|
@@ -14997,14 +15299,14 @@ function computeUninstall(settings) {
|
|
|
14997
15299
|
return { status: "removed", settingsAfter: next };
|
|
14998
15300
|
}
|
|
14999
15301
|
function uninstallSkillsHookFromFile(filePath) {
|
|
15000
|
-
if (!
|
|
15302
|
+
if (!fs20.existsSync(filePath)) {
|
|
15001
15303
|
return { status: "no-settings" };
|
|
15002
15304
|
}
|
|
15003
|
-
const raw =
|
|
15305
|
+
const raw = fs20.readFileSync(filePath, "utf-8");
|
|
15004
15306
|
const settings = raw.trim() ? JSON.parse(raw) : {};
|
|
15005
15307
|
const result = computeUninstall(settings);
|
|
15006
15308
|
if (result.status === "removed" && result.settingsAfter) {
|
|
15007
|
-
|
|
15309
|
+
fs20.writeFileSync(filePath, JSON.stringify(result.settingsAfter, null, 2) + "\n");
|
|
15008
15310
|
}
|
|
15009
15311
|
return result;
|
|
15010
15312
|
}
|
|
@@ -15020,8 +15322,8 @@ var init_hook_template = __esm({
|
|
|
15020
15322
|
});
|
|
15021
15323
|
|
|
15022
15324
|
// ../core/dist/world/merge-settings.js
|
|
15023
|
-
import * as
|
|
15024
|
-
import * as
|
|
15325
|
+
import * as fs21 from "node:fs";
|
|
15326
|
+
import * as path22 from "node:path";
|
|
15025
15327
|
import * as crypto4 from "node:crypto";
|
|
15026
15328
|
function mergeHomeSettingsJson(filePath, options) {
|
|
15027
15329
|
let settings;
|
|
@@ -15082,10 +15384,10 @@ function mergeHomeSettingsJson(filePath, options) {
|
|
|
15082
15384
|
return { status: "installed", message: `settings.json updated at ${filePath}` };
|
|
15083
15385
|
}
|
|
15084
15386
|
function readSettings(filePath) {
|
|
15085
|
-
if (!
|
|
15387
|
+
if (!fs21.existsSync(filePath)) {
|
|
15086
15388
|
return {};
|
|
15087
15389
|
}
|
|
15088
|
-
const raw =
|
|
15390
|
+
const raw = fs21.readFileSync(filePath, "utf-8");
|
|
15089
15391
|
if (!raw.trim())
|
|
15090
15392
|
return {};
|
|
15091
15393
|
return JSON.parse(raw);
|
|
@@ -15124,13 +15426,13 @@ function isHookSentinelPresent(matchers, sentinel) {
|
|
|
15124
15426
|
return false;
|
|
15125
15427
|
}
|
|
15126
15428
|
function atomicWriteJson(filePath, data) {
|
|
15127
|
-
const dir =
|
|
15128
|
-
|
|
15429
|
+
const dir = path22.dirname(filePath);
|
|
15430
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
15129
15431
|
const rand = crypto4.randomBytes(6).toString("hex");
|
|
15130
15432
|
const tmp = `${filePath}.tmp.${process.pid}.${rand}`;
|
|
15131
15433
|
const json2 = JSON.stringify(data, null, 2) + "\n";
|
|
15132
|
-
|
|
15133
|
-
|
|
15434
|
+
fs21.writeFileSync(tmp, json2, { mode: 420 });
|
|
15435
|
+
fs21.renameSync(tmp, filePath);
|
|
15134
15436
|
}
|
|
15135
15437
|
var init_merge_settings = __esm({
|
|
15136
15438
|
"../core/dist/world/merge-settings.js"() {
|
|
@@ -15139,25 +15441,24 @@ var init_merge_settings = __esm({
|
|
|
15139
15441
|
});
|
|
15140
15442
|
|
|
15141
15443
|
// ../core/dist/skill-sources/hook-install.js
|
|
15142
|
-
import * as
|
|
15143
|
-
import * as
|
|
15144
|
-
import * as os13 from "node:os";
|
|
15444
|
+
import * as fs22 from "node:fs";
|
|
15445
|
+
import * as path23 from "node:path";
|
|
15145
15446
|
function settingsPathFor(scope, cwd) {
|
|
15146
15447
|
if (scope === "user") {
|
|
15147
|
-
return
|
|
15448
|
+
return path23.join(claudeDir(), "settings.json");
|
|
15148
15449
|
}
|
|
15149
|
-
return
|
|
15450
|
+
return path23.join(cwd ?? process.cwd(), ".claude", "settings.json");
|
|
15150
15451
|
}
|
|
15151
15452
|
function backupFile(filePath) {
|
|
15152
|
-
if (!
|
|
15453
|
+
if (!fs22.existsSync(filePath))
|
|
15153
15454
|
return null;
|
|
15154
15455
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
15155
15456
|
const backupPath = `${filePath}.olam-bak.${ts}`;
|
|
15156
|
-
|
|
15457
|
+
fs22.copyFileSync(filePath, backupPath);
|
|
15157
15458
|
return backupPath;
|
|
15158
15459
|
}
|
|
15159
15460
|
function installSkillsHookToFile(filePath) {
|
|
15160
|
-
|
|
15461
|
+
fs22.mkdirSync(path23.dirname(filePath), { recursive: true });
|
|
15161
15462
|
const backupPath = backupFile(filePath);
|
|
15162
15463
|
const result = mergeHomeSettingsJson(filePath, {
|
|
15163
15464
|
ensureHook: {
|
|
@@ -15168,7 +15469,7 @@ function installSkillsHookToFile(filePath) {
|
|
|
15168
15469
|
});
|
|
15169
15470
|
if (result.status === "already-present" && backupPath) {
|
|
15170
15471
|
try {
|
|
15171
|
-
|
|
15472
|
+
fs22.unlinkSync(backupPath);
|
|
15172
15473
|
} catch {
|
|
15173
15474
|
}
|
|
15174
15475
|
return { status: "already-present", filePath, backupPath: null };
|
|
@@ -15176,11 +15477,11 @@ function installSkillsHookToFile(filePath) {
|
|
|
15176
15477
|
return { status: result.status, filePath, backupPath };
|
|
15177
15478
|
}
|
|
15178
15479
|
function isSkillsHookInstalled(filePath) {
|
|
15179
|
-
if (!
|
|
15480
|
+
if (!fs22.existsSync(filePath))
|
|
15180
15481
|
return false;
|
|
15181
15482
|
let parsed;
|
|
15182
15483
|
try {
|
|
15183
|
-
parsed = JSON.parse(
|
|
15484
|
+
parsed = JSON.parse(fs22.readFileSync(filePath, "utf-8"));
|
|
15184
15485
|
} catch {
|
|
15185
15486
|
return false;
|
|
15186
15487
|
}
|
|
@@ -15212,42 +15513,43 @@ function isSkillsHookInstalled(filePath) {
|
|
|
15212
15513
|
var init_hook_install = __esm({
|
|
15213
15514
|
"../core/dist/skill-sources/hook-install.js"() {
|
|
15214
15515
|
"use strict";
|
|
15516
|
+
init_olam_paths();
|
|
15215
15517
|
init_merge_settings();
|
|
15216
15518
|
init_hook_template();
|
|
15217
15519
|
}
|
|
15218
15520
|
});
|
|
15219
15521
|
|
|
15220
15522
|
// ../core/dist/skill-sources/migration-snapshot.js
|
|
15221
|
-
import * as
|
|
15222
|
-
import * as
|
|
15223
|
-
import * as
|
|
15523
|
+
import * as fs23 from "node:fs";
|
|
15524
|
+
import * as os10 from "node:os";
|
|
15525
|
+
import * as path24 from "node:path";
|
|
15224
15526
|
function claudeDirInternal() {
|
|
15225
15527
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
15226
15528
|
if (override && override.length > 0)
|
|
15227
15529
|
return override;
|
|
15228
|
-
return
|
|
15530
|
+
return path24.join(os10.homedir(), ".claude");
|
|
15229
15531
|
}
|
|
15230
15532
|
function migrationSnapshotsDir() {
|
|
15231
15533
|
const override = process.env["OLAM_MIGRATION_SNAPSHOTS_DIR"];
|
|
15232
15534
|
if (override && override.length > 0)
|
|
15233
15535
|
return override;
|
|
15234
|
-
return
|
|
15536
|
+
return path24.join(os10.homedir(), ".olam", "state", "migration-snapshots");
|
|
15235
15537
|
}
|
|
15236
15538
|
function listToolboxManagedSymlinks(toolboxPath) {
|
|
15237
15539
|
const claude = claudeDirInternal();
|
|
15238
15540
|
const out = [];
|
|
15239
15541
|
const BUCKETS2 = ["skills", "agents", "scripts", "rules", "commands"];
|
|
15240
15542
|
for (const bucket of BUCKETS2) {
|
|
15241
|
-
const dir =
|
|
15242
|
-
if (!
|
|
15543
|
+
const dir = path24.join(claude, bucket);
|
|
15544
|
+
if (!fs23.existsSync(dir))
|
|
15243
15545
|
continue;
|
|
15244
|
-
for (const name of
|
|
15245
|
-
const link =
|
|
15546
|
+
for (const name of fs23.readdirSync(dir)) {
|
|
15547
|
+
const link = path24.join(dir, name);
|
|
15246
15548
|
try {
|
|
15247
|
-
const stat2 =
|
|
15549
|
+
const stat2 = fs23.lstatSync(link);
|
|
15248
15550
|
if (!stat2.isSymbolicLink())
|
|
15249
15551
|
continue;
|
|
15250
|
-
const target =
|
|
15552
|
+
const target = fs23.readlinkSync(link);
|
|
15251
15553
|
if (target.startsWith(toolboxPath)) {
|
|
15252
15554
|
out.push({ link, target });
|
|
15253
15555
|
}
|
|
@@ -15260,25 +15562,25 @@ function listToolboxManagedSymlinks(toolboxPath) {
|
|
|
15260
15562
|
function detectToolboxState(opts) {
|
|
15261
15563
|
const claude = claudeDirInternal();
|
|
15262
15564
|
const toolboxPath = opts.toolboxPath;
|
|
15263
|
-
const namespace = opts.namespace ??
|
|
15264
|
-
const atlasUserFile =
|
|
15265
|
-
const atlasUser =
|
|
15565
|
+
const namespace = opts.namespace ?? path24.basename(toolboxPath);
|
|
15566
|
+
const atlasUserFile = path24.join(claude, ".atlas-user");
|
|
15567
|
+
const atlasUser = fs23.existsSync(atlasUserFile) ? fs23.readFileSync(atlasUserFile, "utf-8").trim() || void 0 : void 0;
|
|
15266
15568
|
let subscriptionsJson;
|
|
15267
15569
|
if (atlasUser) {
|
|
15268
|
-
const sp =
|
|
15269
|
-
if (
|
|
15570
|
+
const sp = path24.join(toolboxPath, "members", atlasUser, "subscriptions.json");
|
|
15571
|
+
if (fs23.existsSync(sp)) {
|
|
15270
15572
|
try {
|
|
15271
|
-
subscriptionsJson = JSON.parse(
|
|
15573
|
+
subscriptionsJson = JSON.parse(fs23.readFileSync(sp, "utf-8"));
|
|
15272
15574
|
} catch {
|
|
15273
15575
|
}
|
|
15274
15576
|
}
|
|
15275
15577
|
}
|
|
15276
15578
|
const atlasManagedSymlinks = listToolboxManagedSymlinks(toolboxPath);
|
|
15277
15579
|
let originalSessionStartHook;
|
|
15278
|
-
const settingsPath =
|
|
15279
|
-
if (
|
|
15580
|
+
const settingsPath = path24.join(claude, "settings.json");
|
|
15581
|
+
if (fs23.existsSync(settingsPath)) {
|
|
15280
15582
|
try {
|
|
15281
|
-
const settings = JSON.parse(
|
|
15583
|
+
const settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
|
|
15282
15584
|
const ss = settings?.hooks?.SessionStart;
|
|
15283
15585
|
if (Array.isArray(ss))
|
|
15284
15586
|
originalSessionStartHook = ss;
|
|
@@ -15301,21 +15603,21 @@ function detectToolboxState(opts) {
|
|
|
15301
15603
|
}
|
|
15302
15604
|
function writeMigrationSnapshot(snapshot) {
|
|
15303
15605
|
const dir = migrationSnapshotsDir();
|
|
15304
|
-
|
|
15606
|
+
fs23.mkdirSync(dir, { recursive: true });
|
|
15305
15607
|
const stamp = snapshot.takenAt.replace(/[:.]/g, "-");
|
|
15306
|
-
const file2 =
|
|
15307
|
-
|
|
15608
|
+
const file2 = path24.join(dir, `${snapshot.namespace}-${stamp}.json`);
|
|
15609
|
+
fs23.writeFileSync(file2, JSON.stringify(snapshot, null, 2) + "\n", { mode: 420 });
|
|
15308
15610
|
return file2;
|
|
15309
15611
|
}
|
|
15310
15612
|
function readLatestMigrationSnapshot(opts = {}) {
|
|
15311
15613
|
const dir = migrationSnapshotsDir();
|
|
15312
|
-
if (!
|
|
15614
|
+
if (!fs23.existsSync(dir))
|
|
15313
15615
|
return void 0;
|
|
15314
|
-
const files =
|
|
15616
|
+
const files = fs23.readdirSync(dir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
15315
15617
|
for (const f of files) {
|
|
15316
|
-
const full =
|
|
15618
|
+
const full = path24.join(dir, f);
|
|
15317
15619
|
try {
|
|
15318
|
-
const snapshot = JSON.parse(
|
|
15620
|
+
const snapshot = JSON.parse(fs23.readFileSync(full, "utf-8"));
|
|
15319
15621
|
if (snapshot.schemaVersion !== MIGRATION_SNAPSHOT_SCHEMA_VERSION)
|
|
15320
15622
|
continue;
|
|
15321
15623
|
if (typeof snapshot.atlasToolboxRepoPath !== "string")
|
|
@@ -15332,7 +15634,7 @@ function readLatestMigrationSnapshot(opts = {}) {
|
|
|
15332
15634
|
return void 0;
|
|
15333
15635
|
}
|
|
15334
15636
|
function readMigrationSnapshotFromPath(p) {
|
|
15335
|
-
return JSON.parse(
|
|
15637
|
+
return JSON.parse(fs23.readFileSync(p, "utf-8"));
|
|
15336
15638
|
}
|
|
15337
15639
|
var MIGRATION_SNAPSHOT_SCHEMA_VERSION;
|
|
15338
15640
|
var init_migration_snapshot = __esm({
|
|
@@ -15343,15 +15645,15 @@ var init_migration_snapshot = __esm({
|
|
|
15343
15645
|
});
|
|
15344
15646
|
|
|
15345
15647
|
// ../core/dist/skill-sync/artifact-resolver.js
|
|
15346
|
-
import * as
|
|
15347
|
-
import * as
|
|
15648
|
+
import * as fs24 from "node:fs";
|
|
15649
|
+
import * as path25 from "node:path";
|
|
15348
15650
|
function resolveSubscriptions(opts) {
|
|
15349
15651
|
const { clonePath, atlasUser } = opts;
|
|
15350
15652
|
if (atlasUser) {
|
|
15351
|
-
const subsPath =
|
|
15352
|
-
if (
|
|
15653
|
+
const subsPath = path25.join(clonePath, "members", atlasUser, "subscriptions.json");
|
|
15654
|
+
if (fs24.existsSync(subsPath)) {
|
|
15353
15655
|
try {
|
|
15354
|
-
const parsed = JSON.parse(
|
|
15656
|
+
const parsed = JSON.parse(fs24.readFileSync(subsPath, "utf-8"));
|
|
15355
15657
|
if (Array.isArray(parsed?.categories)) {
|
|
15356
15658
|
return {
|
|
15357
15659
|
categories: parsed.categories.filter((c) => typeof c === "string"),
|
|
@@ -15363,10 +15665,10 @@ function resolveSubscriptions(opts) {
|
|
|
15363
15665
|
}
|
|
15364
15666
|
}
|
|
15365
15667
|
}
|
|
15366
|
-
const catsPath =
|
|
15367
|
-
if (
|
|
15668
|
+
const catsPath = path25.join(clonePath, "shared", "categories.json");
|
|
15669
|
+
if (fs24.existsSync(catsPath)) {
|
|
15368
15670
|
try {
|
|
15369
|
-
const parsed = JSON.parse(
|
|
15671
|
+
const parsed = JSON.parse(fs24.readFileSync(catsPath, "utf-8"));
|
|
15370
15672
|
if (Array.isArray(parsed?.categories)) {
|
|
15371
15673
|
return {
|
|
15372
15674
|
categories: parsed.categories.map((c) => c.id).filter((id) => typeof id === "string"),
|
|
@@ -15377,14 +15679,14 @@ function resolveSubscriptions(opts) {
|
|
|
15377
15679
|
} catch {
|
|
15378
15680
|
}
|
|
15379
15681
|
}
|
|
15380
|
-
const sharedDir =
|
|
15682
|
+
const sharedDir = path25.join(clonePath, "shared");
|
|
15381
15683
|
const cats = [];
|
|
15382
|
-
if (
|
|
15383
|
-
for (const name of
|
|
15384
|
-
const dir =
|
|
15385
|
-
if (!
|
|
15684
|
+
if (fs24.existsSync(sharedDir)) {
|
|
15685
|
+
for (const name of fs24.readdirSync(sharedDir)) {
|
|
15686
|
+
const dir = path25.join(sharedDir, name);
|
|
15687
|
+
if (!fs24.statSync(dir).isDirectory())
|
|
15386
15688
|
continue;
|
|
15387
|
-
if (
|
|
15689
|
+
if (fs24.existsSync(path25.join(dir, "skills")) || fs24.existsSync(path25.join(dir, "agents"))) {
|
|
15388
15690
|
cats.push(name);
|
|
15389
15691
|
}
|
|
15390
15692
|
}
|
|
@@ -15392,29 +15694,29 @@ function resolveSubscriptions(opts) {
|
|
|
15392
15694
|
return { categories: cats, fromSubscriptionsFile: false, atlasUser };
|
|
15393
15695
|
}
|
|
15394
15696
|
function listDirSafe(dir) {
|
|
15395
|
-
if (!
|
|
15697
|
+
if (!fs24.existsSync(dir))
|
|
15396
15698
|
return [];
|
|
15397
|
-
return
|
|
15699
|
+
return fs24.readdirSync(dir);
|
|
15398
15700
|
}
|
|
15399
15701
|
function resolveSkillsDir(opts) {
|
|
15400
15702
|
const { sourceId, baseDir } = opts;
|
|
15401
15703
|
const out = [];
|
|
15402
15704
|
for (const name of listDirSafe(baseDir)) {
|
|
15403
|
-
const subdir =
|
|
15404
|
-
if (!
|
|
15705
|
+
const subdir = path25.join(baseDir, name);
|
|
15706
|
+
if (!fs24.statSync(subdir).isDirectory())
|
|
15405
15707
|
continue;
|
|
15406
|
-
if (!
|
|
15708
|
+
if (!fs24.existsSync(path25.join(subdir, "SKILL.md")))
|
|
15407
15709
|
continue;
|
|
15408
15710
|
out.push({ kind: "skill", sourceId, sourcePath: subdir, deployBasename: name });
|
|
15409
|
-
const subagentsDir =
|
|
15410
|
-
if (
|
|
15711
|
+
const subagentsDir = path25.join(subdir, "references", "agents");
|
|
15712
|
+
if (fs24.existsSync(subagentsDir) && fs24.statSync(subagentsDir).isDirectory()) {
|
|
15411
15713
|
for (const f of listDirSafe(subagentsDir)) {
|
|
15412
15714
|
if (!f.endsWith(".md"))
|
|
15413
15715
|
continue;
|
|
15414
15716
|
out.push({
|
|
15415
15717
|
kind: "subagent",
|
|
15416
15718
|
sourceId,
|
|
15417
|
-
sourcePath:
|
|
15719
|
+
sourcePath: path25.join(subagentsDir, f),
|
|
15418
15720
|
deployBasename: f,
|
|
15419
15721
|
parentSkill: name
|
|
15420
15722
|
});
|
|
@@ -15427,8 +15729,8 @@ function resolveAgentsDir(opts) {
|
|
|
15427
15729
|
const { sourceId, baseDir } = opts;
|
|
15428
15730
|
const out = [];
|
|
15429
15731
|
for (const name of listDirSafe(baseDir)) {
|
|
15430
|
-
const full =
|
|
15431
|
-
const stat2 =
|
|
15732
|
+
const full = path25.join(baseDir, name);
|
|
15733
|
+
const stat2 = fs24.statSync(full);
|
|
15432
15734
|
if (stat2.isFile() && name.endsWith(".md")) {
|
|
15433
15735
|
out.push({ kind: "agent", sourceId, sourcePath: full, deployBasename: name });
|
|
15434
15736
|
} else if (stat2.isDirectory()) {
|
|
@@ -15438,7 +15740,7 @@ function resolveAgentsDir(opts) {
|
|
|
15438
15740
|
out.push({
|
|
15439
15741
|
kind: "agent",
|
|
15440
15742
|
sourceId,
|
|
15441
|
-
sourcePath:
|
|
15743
|
+
sourcePath: path25.join(full, f),
|
|
15442
15744
|
deployBasename: `${name}-${f}`
|
|
15443
15745
|
});
|
|
15444
15746
|
}
|
|
@@ -15450,8 +15752,8 @@ function resolveScriptsDir(opts) {
|
|
|
15450
15752
|
const { sourceId, baseDir } = opts;
|
|
15451
15753
|
const out = [];
|
|
15452
15754
|
for (const name of listDirSafe(baseDir)) {
|
|
15453
|
-
const full =
|
|
15454
|
-
const stat2 =
|
|
15755
|
+
const full = path25.join(baseDir, name);
|
|
15756
|
+
const stat2 = fs24.statSync(full);
|
|
15455
15757
|
if (stat2.isFile() && name.endsWith(".sh")) {
|
|
15456
15758
|
out.push({ kind: "script", sourceId, sourcePath: full, deployBasename: name });
|
|
15457
15759
|
} else if (stat2.isDirectory()) {
|
|
@@ -15466,8 +15768,8 @@ function resolveRulesDir(opts) {
|
|
|
15466
15768
|
for (const name of listDirSafe(baseDir)) {
|
|
15467
15769
|
if (!name.endsWith(".md"))
|
|
15468
15770
|
continue;
|
|
15469
|
-
const full =
|
|
15470
|
-
if (!
|
|
15771
|
+
const full = path25.join(baseDir, name);
|
|
15772
|
+
if (!fs24.statSync(full).isFile())
|
|
15471
15773
|
continue;
|
|
15472
15774
|
out.push({ kind: "rule", sourceId, sourcePath: full, deployBasename: name });
|
|
15473
15775
|
}
|
|
@@ -15479,8 +15781,8 @@ function resolveJsonDir(opts) {
|
|
|
15479
15781
|
for (const name of listDirSafe(baseDir)) {
|
|
15480
15782
|
if (!name.endsWith(".json"))
|
|
15481
15783
|
continue;
|
|
15482
|
-
const full =
|
|
15483
|
-
if (!
|
|
15784
|
+
const full = path25.join(baseDir, name);
|
|
15785
|
+
if (!fs24.statSync(full).isFile())
|
|
15484
15786
|
continue;
|
|
15485
15787
|
out.push({ kind, sourceId, sourcePath: full, deployBasename: name });
|
|
15486
15788
|
}
|
|
@@ -15492,8 +15794,8 @@ function resolveOverlaysDir(opts) {
|
|
|
15492
15794
|
for (const name of listDirSafe(baseDir)) {
|
|
15493
15795
|
if (!name.endsWith(".md"))
|
|
15494
15796
|
continue;
|
|
15495
|
-
const full =
|
|
15496
|
-
if (!
|
|
15797
|
+
const full = path25.join(baseDir, name);
|
|
15798
|
+
if (!fs24.statSync(full).isFile())
|
|
15497
15799
|
continue;
|
|
15498
15800
|
const deployBasename = name.replace(/\.md$/, "");
|
|
15499
15801
|
out.push({
|
|
@@ -15511,33 +15813,33 @@ function resolveSourceArtifacts(opts) {
|
|
|
15511
15813
|
const subscription = resolveSubscriptions({ clonePath, atlasUser });
|
|
15512
15814
|
const artifacts = [];
|
|
15513
15815
|
for (const cat of subscription.categories) {
|
|
15514
|
-
const catDir =
|
|
15515
|
-
if (!
|
|
15816
|
+
const catDir = path25.join(clonePath, "shared", cat);
|
|
15817
|
+
if (!fs24.existsSync(catDir))
|
|
15516
15818
|
continue;
|
|
15517
|
-
artifacts.push(...resolveSkillsDir({ sourceId, baseDir:
|
|
15518
|
-
artifacts.push(...resolveAgentsDir({ sourceId, baseDir:
|
|
15519
|
-
artifacts.push(...resolveScriptsDir({ sourceId, baseDir:
|
|
15520
|
-
artifacts.push(...resolveRulesDir({ sourceId, baseDir:
|
|
15521
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
15522
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
15819
|
+
artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path25.join(catDir, "skills") }));
|
|
15820
|
+
artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path25.join(catDir, "agents") }));
|
|
15821
|
+
artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path25.join(catDir, "scripts") }));
|
|
15822
|
+
artifacts.push(...resolveRulesDir({ sourceId, baseDir: path25.join(catDir, "rules") }));
|
|
15823
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(catDir, "hooks"), kind: "hook" }));
|
|
15824
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(catDir, "permissions"), kind: "permission" }));
|
|
15523
15825
|
}
|
|
15524
15826
|
if (atlasUser) {
|
|
15525
|
-
const memberRoot =
|
|
15526
|
-
if (
|
|
15527
|
-
artifacts.push(...resolveSkillsDir({ sourceId, baseDir:
|
|
15528
|
-
artifacts.push(...resolveAgentsDir({ sourceId, baseDir:
|
|
15529
|
-
artifacts.push(...resolveScriptsDir({ sourceId, baseDir:
|
|
15530
|
-
artifacts.push(...resolveRulesDir({ sourceId, baseDir:
|
|
15531
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
15532
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
15827
|
+
const memberRoot = path25.join(clonePath, "members", atlasUser);
|
|
15828
|
+
if (fs24.existsSync(memberRoot)) {
|
|
15829
|
+
artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path25.join(memberRoot, "skills") }));
|
|
15830
|
+
artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path25.join(memberRoot, "agents") }));
|
|
15831
|
+
artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path25.join(memberRoot, "scripts") }));
|
|
15832
|
+
artifacts.push(...resolveRulesDir({ sourceId, baseDir: path25.join(memberRoot, "rules") }));
|
|
15833
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(memberRoot, "hooks"), kind: "hook" }));
|
|
15834
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path25.join(memberRoot, "permissions"), kind: "permission" }));
|
|
15533
15835
|
artifacts.push(...resolveOverlaysDir({
|
|
15534
15836
|
sourceId,
|
|
15535
|
-
baseDir:
|
|
15837
|
+
baseDir: path25.join(memberRoot, "skills.overrides"),
|
|
15536
15838
|
targetKind: "skill"
|
|
15537
15839
|
}));
|
|
15538
15840
|
artifacts.push(...resolveOverlaysDir({
|
|
15539
15841
|
sourceId,
|
|
15540
|
-
baseDir:
|
|
15842
|
+
baseDir: path25.join(memberRoot, "agents.overrides"),
|
|
15541
15843
|
targetKind: "agent"
|
|
15542
15844
|
}));
|
|
15543
15845
|
}
|
|
@@ -15603,14 +15905,14 @@ var init_shim_targets = __esm({
|
|
|
15603
15905
|
});
|
|
15604
15906
|
|
|
15605
15907
|
// ../core/dist/skill-sync/symlink-deployer.js
|
|
15606
|
-
import * as
|
|
15607
|
-
import * as
|
|
15608
|
-
import * as
|
|
15609
|
-
function
|
|
15908
|
+
import * as fs25 from "node:fs";
|
|
15909
|
+
import * as os11 from "node:os";
|
|
15910
|
+
import * as path26 from "node:path";
|
|
15911
|
+
function claudeDir2() {
|
|
15610
15912
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
15611
15913
|
if (override && override.length > 0)
|
|
15612
15914
|
return override;
|
|
15613
|
-
return
|
|
15915
|
+
return path26.join(os11.homedir(), ".claude");
|
|
15614
15916
|
}
|
|
15615
15917
|
function bucketFor(kind) {
|
|
15616
15918
|
switch (kind) {
|
|
@@ -15670,15 +15972,15 @@ function detectCollisions(artifacts) {
|
|
|
15670
15972
|
function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, expectedAgentWinnerNames) {
|
|
15671
15973
|
const shadowBackups = [];
|
|
15672
15974
|
for (const bucket of BUCKETS) {
|
|
15673
|
-
const dir =
|
|
15674
|
-
if (!
|
|
15975
|
+
const dir = path26.join(claude, bucket);
|
|
15976
|
+
if (!fs25.existsSync(dir))
|
|
15675
15977
|
continue;
|
|
15676
|
-
for (const name of
|
|
15978
|
+
for (const name of fs25.readdirSync(dir)) {
|
|
15677
15979
|
if (name === ".olam-merged")
|
|
15678
15980
|
continue;
|
|
15679
|
-
const p =
|
|
15981
|
+
const p = path26.join(dir, name);
|
|
15680
15982
|
try {
|
|
15681
|
-
const stat2 =
|
|
15983
|
+
const stat2 = fs25.lstatSync(p);
|
|
15682
15984
|
if (stat2.isSymbolicLink()) {
|
|
15683
15985
|
if (bucket === "scripts" && overlayReferences !== void 0) {
|
|
15684
15986
|
const refs = overlayReferences.get(name);
|
|
@@ -15699,7 +16001,7 @@ function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, e
|
|
|
15699
16001
|
`);
|
|
15700
16002
|
}
|
|
15701
16003
|
}
|
|
15702
|
-
|
|
16004
|
+
fs25.unlinkSync(p);
|
|
15703
16005
|
} else if (bucket === "agents" && stat2.isFile() && !name.includes(".shadow-backup-")) {
|
|
15704
16006
|
const hasWinner = expectedAgentWinnerNames !== void 0 ? expectedAgentWinnerNames.has(name) : true;
|
|
15705
16007
|
if (hasWinner) {
|
|
@@ -15716,34 +16018,34 @@ function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, e
|
|
|
15716
16018
|
function shadowBackup(link) {
|
|
15717
16019
|
const epoch = Math.floor(Date.now() / 1e3);
|
|
15718
16020
|
const backup = `${link}.shadow-backup-${epoch}`;
|
|
15719
|
-
|
|
16021
|
+
fs25.renameSync(link, backup);
|
|
15720
16022
|
return backup;
|
|
15721
16023
|
}
|
|
15722
16024
|
function linkIfNeeded(target, link) {
|
|
15723
16025
|
try {
|
|
15724
|
-
const existing =
|
|
16026
|
+
const existing = fs25.readlinkSync(link);
|
|
15725
16027
|
if (existing === target)
|
|
15726
16028
|
return { created: false };
|
|
15727
16029
|
} catch {
|
|
15728
16030
|
}
|
|
15729
16031
|
let isLink = false;
|
|
15730
16032
|
try {
|
|
15731
|
-
isLink =
|
|
16033
|
+
isLink = fs25.lstatSync(link).isSymbolicLink();
|
|
15732
16034
|
} catch {
|
|
15733
16035
|
}
|
|
15734
16036
|
let backup;
|
|
15735
16037
|
if (isLink) {
|
|
15736
|
-
|
|
15737
|
-
} else if (
|
|
16038
|
+
fs25.unlinkSync(link);
|
|
16039
|
+
} else if (fs25.existsSync(link)) {
|
|
15738
16040
|
backup = shadowBackup(link);
|
|
15739
16041
|
}
|
|
15740
|
-
|
|
16042
|
+
fs25.symlinkSync(target, link);
|
|
15741
16043
|
return { created: true, shadowBackup: backup };
|
|
15742
16044
|
}
|
|
15743
16045
|
function deployArtifacts(artifacts, opts) {
|
|
15744
|
-
const claude =
|
|
16046
|
+
const claude = claudeDir2();
|
|
15745
16047
|
for (const bucket of BUCKETS) {
|
|
15746
|
-
|
|
16048
|
+
fs25.mkdirSync(path26.join(claude, bucket), { recursive: true });
|
|
15747
16049
|
}
|
|
15748
16050
|
const { winners, collisions } = detectCollisions(artifacts);
|
|
15749
16051
|
const expectedAgentWinnerNames = new Set(winners.filter((a) => a.kind === "agent").map((a) => a.deployBasename));
|
|
@@ -15753,11 +16055,11 @@ function deployArtifacts(artifacts, opts) {
|
|
|
15753
16055
|
const bucket = bucketFor(artifact.kind);
|
|
15754
16056
|
if (!bucket)
|
|
15755
16057
|
continue;
|
|
15756
|
-
const linkPath =
|
|
16058
|
+
const linkPath = path26.join(claude, bucket, artifact.deployBasename);
|
|
15757
16059
|
if (artifact.kind === "agent" && artifact.resolvedContent !== void 0) {
|
|
15758
16060
|
const tmpPath = `${linkPath}.tmp-${process.pid}-${Date.now()}`;
|
|
15759
|
-
|
|
15760
|
-
|
|
16061
|
+
fs25.writeFileSync(tmpPath, artifact.resolvedContent);
|
|
16062
|
+
fs25.renameSync(tmpPath, linkPath);
|
|
15761
16063
|
result.linked += 1;
|
|
15762
16064
|
continue;
|
|
15763
16065
|
}
|
|
@@ -15779,7 +16081,7 @@ var init_symlink_deployer = __esm({
|
|
|
15779
16081
|
});
|
|
15780
16082
|
|
|
15781
16083
|
// ../core/dist/meta-hooks/memory-recall.js
|
|
15782
|
-
import * as
|
|
16084
|
+
import * as fs26 from "node:fs";
|
|
15783
16085
|
function buildMemoryRecallHookEntry() {
|
|
15784
16086
|
return {
|
|
15785
16087
|
matcher: OLAM_META_MEMORY_RECALL_MATCHER,
|
|
@@ -15854,7 +16156,7 @@ var init_memory_recall = __esm({
|
|
|
15854
16156
|
});
|
|
15855
16157
|
|
|
15856
16158
|
// ../core/dist/meta-hooks/memory-classify.js
|
|
15857
|
-
import * as
|
|
16159
|
+
import * as fs27 from "node:fs";
|
|
15858
16160
|
function buildMemoryClassifyHookEntry() {
|
|
15859
16161
|
return {
|
|
15860
16162
|
matcher: OLAM_META_MEMORY_CLASSIFY_MATCHER,
|
|
@@ -15929,7 +16231,7 @@ var init_memory_classify = __esm({
|
|
|
15929
16231
|
});
|
|
15930
16232
|
|
|
15931
16233
|
// ../core/dist/meta-hooks/model-router.js
|
|
15932
|
-
import * as
|
|
16234
|
+
import * as fs28 from "node:fs";
|
|
15933
16235
|
function buildModelRouterHookEntry() {
|
|
15934
16236
|
return {
|
|
15935
16237
|
hooks: [
|
|
@@ -16003,9 +16305,9 @@ var init_model_router = __esm({
|
|
|
16003
16305
|
});
|
|
16004
16306
|
|
|
16005
16307
|
// ../core/dist/meta-hooks/model-router-deploy.js
|
|
16006
|
-
import { existsSync as
|
|
16007
|
-
import { homedir as
|
|
16008
|
-
import { dirname as dirname13, join as
|
|
16308
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync16, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
|
|
16309
|
+
import { homedir as homedir14 } from "node:os";
|
|
16310
|
+
import { dirname as dirname13, join as join30, resolve as resolve7 } from "node:path";
|
|
16009
16311
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
16010
16312
|
function resolveModelRouterSourcePath() {
|
|
16011
16313
|
const here = dirname13(fileURLToPath3(import.meta.url));
|
|
@@ -16019,28 +16321,28 @@ function resolveModelRouterSourcePath() {
|
|
|
16019
16321
|
resolve7(here, "..", "..", "hooks", MODEL_ROUTER_SCRIPT_BASENAME)
|
|
16020
16322
|
];
|
|
16021
16323
|
for (const candidate of candidates) {
|
|
16022
|
-
if (
|
|
16324
|
+
if (existsSync32(candidate))
|
|
16023
16325
|
return candidate;
|
|
16024
16326
|
}
|
|
16025
16327
|
return candidates[0];
|
|
16026
16328
|
}
|
|
16027
16329
|
function deployModelRouterScript(opts = {}) {
|
|
16028
|
-
const targetDir = opts.targetDir ??
|
|
16029
|
-
const targetPath =
|
|
16330
|
+
const targetDir = opts.targetDir ?? join30(homedir14(), ".claude", "hooks");
|
|
16331
|
+
const targetPath = join30(targetDir, MODEL_ROUTER_SCRIPT_BASENAME);
|
|
16030
16332
|
const sourcePath = opts.sourcePath ?? resolveModelRouterSourcePath();
|
|
16031
|
-
if (!
|
|
16333
|
+
if (!existsSync32(sourcePath)) {
|
|
16032
16334
|
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "source-missing", targetPath };
|
|
16033
16335
|
}
|
|
16034
|
-
const newContent =
|
|
16035
|
-
if (
|
|
16036
|
-
const existing =
|
|
16336
|
+
const newContent = readFileSync23(sourcePath, "utf8");
|
|
16337
|
+
if (existsSync32(targetPath)) {
|
|
16338
|
+
const existing = readFileSync23(targetPath, "utf8");
|
|
16037
16339
|
if (existing === newContent) {
|
|
16038
16340
|
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "unchanged", targetPath };
|
|
16039
16341
|
}
|
|
16040
16342
|
}
|
|
16041
16343
|
if (opts.dryRun !== true) {
|
|
16042
16344
|
mkdirSync16(dirname13(targetPath), { recursive: true });
|
|
16043
|
-
|
|
16345
|
+
writeFileSync15(targetPath, newContent, { mode: 493 });
|
|
16044
16346
|
}
|
|
16045
16347
|
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "written", targetPath };
|
|
16046
16348
|
}
|
|
@@ -16064,26 +16366,26 @@ var init_meta_hooks = __esm({
|
|
|
16064
16366
|
});
|
|
16065
16367
|
|
|
16066
16368
|
// ../core/dist/skill-sync/settings-merger.js
|
|
16067
|
-
import * as
|
|
16068
|
-
import * as
|
|
16069
|
-
import * as
|
|
16369
|
+
import * as fs29 from "node:fs";
|
|
16370
|
+
import * as os12 from "node:os";
|
|
16371
|
+
import * as path27 from "node:path";
|
|
16070
16372
|
function claudeSettingsPath() {
|
|
16071
16373
|
const override = process.env["OLAM_CLAUDE_SETTINGS_PATH"];
|
|
16072
16374
|
if (override && override.length > 0)
|
|
16073
16375
|
return override;
|
|
16074
|
-
return
|
|
16376
|
+
return path27.join(claudeDirInternal2(), "settings.json");
|
|
16075
16377
|
}
|
|
16076
16378
|
function claudeDirInternal2() {
|
|
16077
16379
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
16078
16380
|
if (override && override.length > 0)
|
|
16079
16381
|
return override;
|
|
16080
|
-
return
|
|
16382
|
+
return path27.join(os12.homedir(), ".claude");
|
|
16081
16383
|
}
|
|
16082
16384
|
function settingsBackupDir() {
|
|
16083
16385
|
const override = process.env["OLAM_SETTINGS_BACKUP_DIR"];
|
|
16084
16386
|
if (override && override.length > 0)
|
|
16085
16387
|
return override;
|
|
16086
|
-
return
|
|
16388
|
+
return path27.join(os12.homedir(), ".olam", "state", "settings-backups");
|
|
16087
16389
|
}
|
|
16088
16390
|
function dedupeByMatcher(entries) {
|
|
16089
16391
|
const map2 = /* @__PURE__ */ new Map();
|
|
@@ -16133,28 +16435,28 @@ function tagOlam(entry) {
|
|
|
16133
16435
|
return { ...entry, [OLAM_SKILLS_MARKER]: true };
|
|
16134
16436
|
}
|
|
16135
16437
|
function readJson(file2) {
|
|
16136
|
-
return JSON.parse(
|
|
16438
|
+
return JSON.parse(fs29.readFileSync(file2, "utf-8"));
|
|
16137
16439
|
}
|
|
16138
16440
|
function rotateBackups(backupDir) {
|
|
16139
|
-
if (!
|
|
16441
|
+
if (!fs29.existsSync(backupDir))
|
|
16140
16442
|
return;
|
|
16141
|
-
const files =
|
|
16443
|
+
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);
|
|
16142
16444
|
for (const f of files.slice(BACKUP_RETENTION)) {
|
|
16143
16445
|
try {
|
|
16144
|
-
|
|
16446
|
+
fs29.unlinkSync(f.full);
|
|
16145
16447
|
} catch {
|
|
16146
16448
|
}
|
|
16147
16449
|
}
|
|
16148
16450
|
}
|
|
16149
16451
|
function backupSettings() {
|
|
16150
16452
|
const src = claudeSettingsPath();
|
|
16151
|
-
if (!
|
|
16453
|
+
if (!fs29.existsSync(src))
|
|
16152
16454
|
return void 0;
|
|
16153
16455
|
const dir = settingsBackupDir();
|
|
16154
|
-
|
|
16456
|
+
fs29.mkdirSync(dir, { recursive: true });
|
|
16155
16457
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
16156
|
-
const dest =
|
|
16157
|
-
|
|
16458
|
+
const dest = path27.join(dir, `settings-${stamp}.json`);
|
|
16459
|
+
fs29.copyFileSync(src, dest);
|
|
16158
16460
|
rotateBackups(dir);
|
|
16159
16461
|
return dest;
|
|
16160
16462
|
}
|
|
@@ -16162,7 +16464,7 @@ function mergeSettings(input) {
|
|
|
16162
16464
|
const settingsPath = claudeSettingsPath();
|
|
16163
16465
|
const backupPath = backupSettings();
|
|
16164
16466
|
let base = {};
|
|
16165
|
-
if (
|
|
16467
|
+
if (fs29.existsSync(settingsPath)) {
|
|
16166
16468
|
try {
|
|
16167
16469
|
base = readJson(settingsPath);
|
|
16168
16470
|
} catch {
|
|
@@ -16230,10 +16532,10 @@ function mergeSettings(input) {
|
|
|
16230
16532
|
...input.permissionFiles.length > 0 ? { allow: [...permSet] } : {}
|
|
16231
16533
|
}
|
|
16232
16534
|
};
|
|
16233
|
-
|
|
16535
|
+
fs29.mkdirSync(path27.dirname(settingsPath), { recursive: true });
|
|
16234
16536
|
const tmp = `${settingsPath}.tmp-${process.pid}`;
|
|
16235
|
-
|
|
16236
|
-
|
|
16537
|
+
fs29.writeFileSync(tmp, JSON.stringify(next, null, 2) + "\n", { mode: 420 });
|
|
16538
|
+
fs29.renameSync(tmp, settingsPath);
|
|
16237
16539
|
return { backupPath, hooksAdded, permissionsCount: permSet.size, dualWriteDeduped, dualWriteDroppedCommands };
|
|
16238
16540
|
}
|
|
16239
16541
|
var OLAM_SKILLS_MARKER, BACKUP_RETENTION, DUAL_WRITE_DEDUP_RULES;
|
|
@@ -16289,17 +16591,17 @@ var init_schema5 = __esm({
|
|
|
16289
16591
|
});
|
|
16290
16592
|
|
|
16291
16593
|
// ../core/dist/skill-sync/per-project-override.js
|
|
16292
|
-
import { execFileSync as
|
|
16293
|
-
import * as
|
|
16294
|
-
import * as
|
|
16594
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
16595
|
+
import * as fs30 from "node:fs";
|
|
16596
|
+
import * as path28 from "node:path";
|
|
16295
16597
|
import { parse as parseYaml3 } from "yaml";
|
|
16296
16598
|
function findProjectOverride(startDir) {
|
|
16297
|
-
let dir =
|
|
16298
|
-
const root =
|
|
16599
|
+
let dir = path28.resolve(startDir);
|
|
16600
|
+
const root = path28.parse(dir).root;
|
|
16299
16601
|
while (true) {
|
|
16300
|
-
const candidate =
|
|
16301
|
-
if (
|
|
16302
|
-
const raw =
|
|
16602
|
+
const candidate = path28.join(dir, PROJECT_OVERRIDE_RELATIVE_PATH);
|
|
16603
|
+
if (fs30.existsSync(candidate) && fs30.statSync(candidate).isFile()) {
|
|
16604
|
+
const raw = fs30.readFileSync(candidate, "utf-8");
|
|
16303
16605
|
let parsed;
|
|
16304
16606
|
try {
|
|
16305
16607
|
parsed = parseYaml3(raw);
|
|
@@ -16312,7 +16614,7 @@ function findProjectOverride(startDir) {
|
|
|
16312
16614
|
}
|
|
16313
16615
|
if (dir === root)
|
|
16314
16616
|
return void 0;
|
|
16315
|
-
dir =
|
|
16617
|
+
dir = path28.dirname(dir);
|
|
16316
16618
|
}
|
|
16317
16619
|
}
|
|
16318
16620
|
function applyOverrideToArtifacts(artifacts, override) {
|
|
@@ -16332,7 +16634,7 @@ function applyPinToClone(opts) {
|
|
|
16332
16634
|
if (ref.startsWith("-")) {
|
|
16333
16635
|
throw new Error(`refuses ref "${ref}" \u2014 must not start with "-" (would be parsed as a git option)`);
|
|
16334
16636
|
}
|
|
16335
|
-
|
|
16637
|
+
execFileSync4("git", ["-C", clonePath, "checkout", "-q", ref], {
|
|
16336
16638
|
stdio: ["ignore", "ignore", "pipe"]
|
|
16337
16639
|
});
|
|
16338
16640
|
}
|
|
@@ -16342,7 +16644,7 @@ function restoreCloneToBranchHead(opts) {
|
|
|
16342
16644
|
return;
|
|
16343
16645
|
}
|
|
16344
16646
|
try {
|
|
16345
|
-
|
|
16647
|
+
execFileSync4("git", ["-C", clonePath, "checkout", "-q", branch], {
|
|
16346
16648
|
stdio: ["ignore", "ignore", "pipe"]
|
|
16347
16649
|
});
|
|
16348
16650
|
} catch {
|
|
@@ -16353,14 +16655,18 @@ var init_per_project_override = __esm({
|
|
|
16353
16655
|
"../core/dist/skill-sync/per-project-override.js"() {
|
|
16354
16656
|
"use strict";
|
|
16355
16657
|
init_schema5();
|
|
16356
|
-
PROJECT_OVERRIDE_RELATIVE_PATH =
|
|
16658
|
+
PROJECT_OVERRIDE_RELATIVE_PATH = path28.join(".olam", "skill-overrides.yaml");
|
|
16357
16659
|
}
|
|
16358
16660
|
});
|
|
16359
16661
|
|
|
16360
16662
|
// ../core/dist/lib/file-lock.js
|
|
16361
|
-
import * as
|
|
16362
|
-
import * as
|
|
16363
|
-
import * as
|
|
16663
|
+
import * as fs31 from "node:fs";
|
|
16664
|
+
import * as os13 from "node:os";
|
|
16665
|
+
import * as path29 from "node:path";
|
|
16666
|
+
function mintToken2() {
|
|
16667
|
+
tokenCounter += 1;
|
|
16668
|
+
return `${process.pid}-${tokenCounter}-${Math.random().toString(36).slice(2, 10)}`;
|
|
16669
|
+
}
|
|
16364
16670
|
function defaultIsPidAlive(pid) {
|
|
16365
16671
|
try {
|
|
16366
16672
|
process.kill(pid, 0);
|
|
@@ -16375,7 +16681,7 @@ function sleep3(ms) {
|
|
|
16375
16681
|
}
|
|
16376
16682
|
function readLockMeta(lockPath) {
|
|
16377
16683
|
try {
|
|
16378
|
-
const raw =
|
|
16684
|
+
const raw = fs31.readFileSync(lockPath, "utf-8");
|
|
16379
16685
|
const parsed = JSON.parse(raw);
|
|
16380
16686
|
if (typeof parsed?.pid === "number" && typeof parsed?.hostname === "string" && typeof parsed?.timestamp === "number") {
|
|
16381
16687
|
return parsed;
|
|
@@ -16385,68 +16691,109 @@ function readLockMeta(lockPath) {
|
|
|
16385
16691
|
return void 0;
|
|
16386
16692
|
}
|
|
16387
16693
|
function isLockStale(meta3, opts) {
|
|
16388
|
-
if (meta3.hostname !==
|
|
16694
|
+
if (meta3.hostname !== os13.hostname()) {
|
|
16389
16695
|
return opts.now - meta3.timestamp > opts.staleLockMs * 2;
|
|
16390
16696
|
}
|
|
16391
16697
|
if (!opts.isPidAlive(meta3.pid))
|
|
16392
16698
|
return true;
|
|
16393
16699
|
return opts.now - meta3.timestamp > opts.staleLockMs;
|
|
16394
16700
|
}
|
|
16701
|
+
function sameAcquisition(a, b) {
|
|
16702
|
+
if (a.token !== void 0 && b.token !== void 0)
|
|
16703
|
+
return a.token === b.token;
|
|
16704
|
+
return a.pid === b.pid && a.timestamp === b.timestamp;
|
|
16705
|
+
}
|
|
16706
|
+
function createLockFile(lockPath, meta3) {
|
|
16707
|
+
const fd = fs31.openSync(lockPath, "wx", 384);
|
|
16708
|
+
try {
|
|
16709
|
+
fs31.writeSync(fd, JSON.stringify(meta3));
|
|
16710
|
+
fs31.fsyncSync(fd);
|
|
16711
|
+
} finally {
|
|
16712
|
+
fs31.closeSync(fd);
|
|
16713
|
+
}
|
|
16714
|
+
}
|
|
16395
16715
|
function tryAcquireOnce(lockPath, meta3, opts) {
|
|
16716
|
+
fs31.mkdirSync(path29.dirname(lockPath), { recursive: true });
|
|
16396
16717
|
try {
|
|
16397
|
-
|
|
16398
|
-
const fd = fs29.openSync(lockPath, "wx", 384);
|
|
16399
|
-
try {
|
|
16400
|
-
fs29.writeSync(fd, JSON.stringify(meta3));
|
|
16401
|
-
} finally {
|
|
16402
|
-
fs29.closeSync(fd);
|
|
16403
|
-
}
|
|
16718
|
+
createLockFile(lockPath, meta3);
|
|
16404
16719
|
return true;
|
|
16405
16720
|
} catch (err) {
|
|
16406
16721
|
const code = err.code;
|
|
16407
16722
|
if (code !== "EEXIST")
|
|
16408
16723
|
throw err;
|
|
16409
|
-
|
|
16410
|
-
|
|
16411
|
-
|
|
16412
|
-
|
|
16413
|
-
|
|
16414
|
-
|
|
16415
|
-
|
|
16724
|
+
}
|
|
16725
|
+
const existing = readLockMeta(lockPath);
|
|
16726
|
+
if (existing === void 0) {
|
|
16727
|
+
let mtimeMs;
|
|
16728
|
+
try {
|
|
16729
|
+
mtimeMs = fs31.statSync(lockPath).mtimeMs;
|
|
16730
|
+
} catch {
|
|
16731
|
+
mtimeMs = 0;
|
|
16416
16732
|
}
|
|
16417
|
-
|
|
16418
|
-
|
|
16419
|
-
|
|
16420
|
-
} catch {
|
|
16421
|
-
}
|
|
16422
|
-
return tryAcquireOnce(lockPath, meta3, opts);
|
|
16733
|
+
const graceMs = Math.min(2e3, opts.staleLockMs);
|
|
16734
|
+
if (mtimeMs !== 0 && opts.now - mtimeMs <= graceMs) {
|
|
16735
|
+
return false;
|
|
16423
16736
|
}
|
|
16737
|
+
} else if (!isLockStale(existing, opts)) {
|
|
16424
16738
|
return false;
|
|
16739
|
+
} else {
|
|
16740
|
+
const recheck = readLockMeta(lockPath);
|
|
16741
|
+
if (recheck !== void 0 && (!sameAcquisition(existing, recheck) || !isLockStale(recheck, opts))) {
|
|
16742
|
+
return false;
|
|
16743
|
+
}
|
|
16744
|
+
}
|
|
16745
|
+
try {
|
|
16746
|
+
fs31.unlinkSync(lockPath);
|
|
16747
|
+
} catch {
|
|
16748
|
+
}
|
|
16749
|
+
try {
|
|
16750
|
+
createLockFile(lockPath, meta3);
|
|
16751
|
+
return true;
|
|
16752
|
+
} catch (err) {
|
|
16753
|
+
const code = err.code;
|
|
16754
|
+
if (code === "EEXIST")
|
|
16755
|
+
return false;
|
|
16756
|
+
throw err;
|
|
16425
16757
|
}
|
|
16426
16758
|
}
|
|
16427
16759
|
async function acquireFileLock(lockDir, options = {}) {
|
|
16428
16760
|
const lockFilename = options.lockFilename ?? DEFAULT_LOCK_FILENAME;
|
|
16429
|
-
const lockPath =
|
|
16761
|
+
const lockPath = path29.join(lockDir, lockFilename);
|
|
16430
16762
|
const acquireTimeoutMs = options.acquireTimeoutMs ?? DEFAULT_ACQUIRE_TIMEOUT_MS;
|
|
16431
16763
|
const staleLockMs = options.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
|
|
16432
16764
|
const now = options.now ?? Date.now;
|
|
16433
16765
|
const isPidAlive2 = options.isPidAlive ?? defaultIsPidAlive;
|
|
16766
|
+
const ownToken = mintToken2();
|
|
16434
16767
|
const deadline = now() + acquireTimeoutMs;
|
|
16435
16768
|
let backoffMs = 25;
|
|
16436
16769
|
while (true) {
|
|
16437
16770
|
const meta3 = {
|
|
16771
|
+
token: ownToken,
|
|
16438
16772
|
pid: process.pid,
|
|
16439
|
-
hostname:
|
|
16773
|
+
hostname: os13.hostname(),
|
|
16440
16774
|
timestamp: now(),
|
|
16441
16775
|
...options.reason ? { reason: options.reason } : {}
|
|
16442
16776
|
};
|
|
16443
16777
|
const acquired = tryAcquireOnce(lockPath, meta3, { now: now(), staleLockMs, isPidAlive: isPidAlive2 });
|
|
16444
16778
|
if (acquired) {
|
|
16779
|
+
let released = false;
|
|
16445
16780
|
return {
|
|
16446
16781
|
lockPath,
|
|
16782
|
+
// Ownership-checked release: only unlink if WE still own the file.
|
|
16783
|
+
// A holder that overran its lease and was stolen must not delete
|
|
16784
|
+
// the new holder's lock. Idempotent (safe to call twice).
|
|
16447
16785
|
release: () => {
|
|
16786
|
+
if (released)
|
|
16787
|
+
return;
|
|
16788
|
+
released = true;
|
|
16789
|
+
const current = readLockMeta(lockPath);
|
|
16790
|
+
if (current === void 0)
|
|
16791
|
+
return;
|
|
16792
|
+
const isOurs = current.token !== void 0 ? current.token === ownToken : current.pid === process.pid;
|
|
16793
|
+
if (!isOurs)
|
|
16794
|
+
return;
|
|
16448
16795
|
try {
|
|
16449
|
-
|
|
16796
|
+
fs31.unlinkSync(lockPath);
|
|
16450
16797
|
} catch {
|
|
16451
16798
|
}
|
|
16452
16799
|
}
|
|
@@ -16457,7 +16804,8 @@ async function acquireFileLock(lockDir, options = {}) {
|
|
|
16457
16804
|
const held = existing ? `(held by pid ${existing.pid} on ${existing.hostname}, since ${new Date(existing.timestamp).toISOString()})` : "(holder unknown)";
|
|
16458
16805
|
throw new FileLockError(`failed to acquire file lock at ${lockPath} within ${acquireTimeoutMs}ms ${held}`);
|
|
16459
16806
|
}
|
|
16460
|
-
|
|
16807
|
+
const jittered = backoffMs * (0.5 + Math.random());
|
|
16808
|
+
await sleep3(Math.min(jittered, 200));
|
|
16461
16809
|
backoffMs = Math.min(backoffMs * 2, 200);
|
|
16462
16810
|
}
|
|
16463
16811
|
}
|
|
@@ -16469,7 +16817,7 @@ async function withFileLock(lockDir, fn, options) {
|
|
|
16469
16817
|
release();
|
|
16470
16818
|
}
|
|
16471
16819
|
}
|
|
16472
|
-
var DEFAULT_LOCK_FILENAME, DEFAULT_ACQUIRE_TIMEOUT_MS, DEFAULT_STALE_LOCK_MS, FileLockError;
|
|
16820
|
+
var DEFAULT_LOCK_FILENAME, DEFAULT_ACQUIRE_TIMEOUT_MS, DEFAULT_STALE_LOCK_MS, FileLockError, tokenCounter;
|
|
16473
16821
|
var init_file_lock = __esm({
|
|
16474
16822
|
"../core/dist/lib/file-lock.js"() {
|
|
16475
16823
|
"use strict";
|
|
@@ -16482,17 +16830,18 @@ var init_file_lock = __esm({
|
|
|
16482
16830
|
this.name = "FileLockError";
|
|
16483
16831
|
}
|
|
16484
16832
|
};
|
|
16833
|
+
tokenCounter = 0;
|
|
16485
16834
|
}
|
|
16486
16835
|
});
|
|
16487
16836
|
|
|
16488
16837
|
// ../core/dist/lib/min-version-filter.js
|
|
16489
|
-
import { existsSync as
|
|
16838
|
+
import { existsSync as existsSync35, readFileSync as readFileSync27 } from "node:fs";
|
|
16490
16839
|
function readOlamMinVersion(filepath) {
|
|
16491
|
-
if (!
|
|
16840
|
+
if (!existsSync35(filepath))
|
|
16492
16841
|
return void 0;
|
|
16493
16842
|
let text;
|
|
16494
16843
|
try {
|
|
16495
|
-
text =
|
|
16844
|
+
text = readFileSync27(filepath, "utf8");
|
|
16496
16845
|
} catch {
|
|
16497
16846
|
return void 0;
|
|
16498
16847
|
}
|
|
@@ -16550,11 +16899,11 @@ var init_min_version_filter = __esm({
|
|
|
16550
16899
|
});
|
|
16551
16900
|
|
|
16552
16901
|
// ../core/dist/skill-sync/overlay-scan.js
|
|
16553
|
-
import * as
|
|
16554
|
-
import * as
|
|
16902
|
+
import * as fs32 from "node:fs";
|
|
16903
|
+
import * as path30 from "node:path";
|
|
16555
16904
|
function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
16556
16905
|
const result = /* @__PURE__ */ new Map();
|
|
16557
|
-
if (!
|
|
16906
|
+
if (!fs32.existsSync(overlayRoot)) {
|
|
16558
16907
|
return result;
|
|
16559
16908
|
}
|
|
16560
16909
|
if (basenames.length === 0) {
|
|
@@ -16563,13 +16912,13 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
16563
16912
|
const mdFiles = [];
|
|
16564
16913
|
let overlayRootReal;
|
|
16565
16914
|
try {
|
|
16566
|
-
overlayRootReal =
|
|
16915
|
+
overlayRootReal = fs32.realpathSync(overlayRoot);
|
|
16567
16916
|
} catch {
|
|
16568
16917
|
return result;
|
|
16569
16918
|
}
|
|
16570
16919
|
for (const subdir of OVERRIDE_SUBDIRS) {
|
|
16571
|
-
const dir =
|
|
16572
|
-
if (!
|
|
16920
|
+
const dir = path30.join(overlayRoot, subdir);
|
|
16921
|
+
if (!fs32.existsSync(dir))
|
|
16573
16922
|
continue;
|
|
16574
16923
|
walkMarkdown(dir, mdFiles, caps.maxFiles);
|
|
16575
16924
|
}
|
|
@@ -16577,25 +16926,25 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
16577
16926
|
for (const filepath of mdFiles) {
|
|
16578
16927
|
let realFile;
|
|
16579
16928
|
try {
|
|
16580
|
-
realFile =
|
|
16929
|
+
realFile = fs32.realpathSync(filepath);
|
|
16581
16930
|
} catch (err) {
|
|
16582
16931
|
const code = err.code;
|
|
16583
16932
|
if (code === "ENOENT" || code === "EACCES")
|
|
16584
16933
|
continue;
|
|
16585
16934
|
throw err;
|
|
16586
16935
|
}
|
|
16587
|
-
const rel =
|
|
16588
|
-
if (rel.startsWith("..") ||
|
|
16936
|
+
const rel = path30.relative(overlayRootReal, realFile);
|
|
16937
|
+
if (rel.startsWith("..") || path30.isAbsolute(rel)) {
|
|
16589
16938
|
continue;
|
|
16590
16939
|
}
|
|
16591
16940
|
let content;
|
|
16592
16941
|
try {
|
|
16593
|
-
const stat2 =
|
|
16942
|
+
const stat2 = fs32.statSync(filepath);
|
|
16594
16943
|
totalBytes += stat2.size;
|
|
16595
16944
|
if (totalBytes > caps.maxTotalBytes) {
|
|
16596
16945
|
throw new Error(`[overlay-scan] aborted: overlay tree exceeds ${caps.maxTotalBytes} total bytes. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
|
|
16597
16946
|
}
|
|
16598
|
-
content =
|
|
16947
|
+
content = fs32.readFileSync(filepath, "utf8");
|
|
16599
16948
|
} catch (err) {
|
|
16600
16949
|
const code = err.code;
|
|
16601
16950
|
if (code === "ENOENT" || code === "EACCES") {
|
|
@@ -16603,7 +16952,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
16603
16952
|
}
|
|
16604
16953
|
throw err;
|
|
16605
16954
|
}
|
|
16606
|
-
const relpath =
|
|
16955
|
+
const relpath = path30.relative(overlayRoot, filepath).split(path30.sep).join("/");
|
|
16607
16956
|
for (const basename6 of basenames) {
|
|
16608
16957
|
if (content.includes(basename6)) {
|
|
16609
16958
|
const list = result.get(basename6) ?? [];
|
|
@@ -16617,7 +16966,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
16617
16966
|
function walkMarkdown(dir, out, cap) {
|
|
16618
16967
|
let entries;
|
|
16619
16968
|
try {
|
|
16620
|
-
entries =
|
|
16969
|
+
entries = fs32.readdirSync(dir, { withFileTypes: true });
|
|
16621
16970
|
} catch (err) {
|
|
16622
16971
|
if (err.code === "ENOENT")
|
|
16623
16972
|
return;
|
|
@@ -16627,7 +16976,7 @@ function walkMarkdown(dir, out, cap) {
|
|
|
16627
16976
|
if (out.length >= cap) {
|
|
16628
16977
|
throw new Error(`[overlay-scan] aborted: overlay tree contains > ${cap} markdown files. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
|
|
16629
16978
|
}
|
|
16630
|
-
const full =
|
|
16979
|
+
const full = path30.join(dir, entry.name);
|
|
16631
16980
|
if (entry.isSymbolicLink())
|
|
16632
16981
|
continue;
|
|
16633
16982
|
if (entry.isDirectory()) {
|
|
@@ -16652,12 +17001,12 @@ var init_overlay_scan = __esm({
|
|
|
16652
17001
|
});
|
|
16653
17002
|
|
|
16654
17003
|
// ../core/dist/skill-sync/settings-json-lock.js
|
|
16655
|
-
import * as
|
|
16656
|
-
import * as
|
|
16657
|
-
import * as
|
|
17004
|
+
import * as fs33 from "node:fs";
|
|
17005
|
+
import * as os14 from "node:os";
|
|
17006
|
+
import * as path31 from "node:path";
|
|
16658
17007
|
function defaultSettingsJsonLockPath() {
|
|
16659
|
-
const
|
|
16660
|
-
return
|
|
17008
|
+
const stateDir2 = process.env["OLAM_STATE_DIR"] ?? path31.join(os14.homedir(), ".olam", "state");
|
|
17009
|
+
return path31.join(stateDir2, SETTINGS_JSON_LOCK_FILENAME);
|
|
16661
17010
|
}
|
|
16662
17011
|
function defaultIsPidAlive2(pid) {
|
|
16663
17012
|
try {
|
|
@@ -16673,7 +17022,7 @@ function sleep4(ms) {
|
|
|
16673
17022
|
}
|
|
16674
17023
|
function readLockMeta2(lockPath) {
|
|
16675
17024
|
try {
|
|
16676
|
-
const raw =
|
|
17025
|
+
const raw = fs33.readFileSync(lockPath, "utf-8");
|
|
16677
17026
|
const parsed = JSON.parse(raw);
|
|
16678
17027
|
if (typeof parsed?.pid === "number" && typeof parsed?.hostname === "string" && typeof parsed?.timestamp === "number") {
|
|
16679
17028
|
return parsed;
|
|
@@ -16686,7 +17035,7 @@ function isLockStale2(meta3, opts) {
|
|
|
16686
17035
|
const ageMs = opts.now - meta3.timestamp;
|
|
16687
17036
|
if (ageMs < opts.staleLockMs / 2)
|
|
16688
17037
|
return false;
|
|
16689
|
-
if (meta3.hostname !==
|
|
17038
|
+
if (meta3.hostname !== os14.hostname()) {
|
|
16690
17039
|
return ageMs > opts.staleLockMs * 2;
|
|
16691
17040
|
}
|
|
16692
17041
|
if (!opts.isPidAlive(meta3.pid))
|
|
@@ -16696,12 +17045,12 @@ function isLockStale2(meta3, opts) {
|
|
|
16696
17045
|
function tryAcquireOnce2(lockPath, meta3, opts) {
|
|
16697
17046
|
for (let attempt = 0; attempt <= MAX_STEAL_ATTEMPTS; attempt += 1) {
|
|
16698
17047
|
try {
|
|
16699
|
-
|
|
16700
|
-
const fd =
|
|
17048
|
+
fs33.mkdirSync(path31.dirname(lockPath), { recursive: true });
|
|
17049
|
+
const fd = fs33.openSync(lockPath, "wx", 384);
|
|
16701
17050
|
try {
|
|
16702
|
-
|
|
17051
|
+
fs33.writeSync(fd, JSON.stringify(meta3));
|
|
16703
17052
|
} finally {
|
|
16704
|
-
|
|
17053
|
+
fs33.closeSync(fd);
|
|
16705
17054
|
}
|
|
16706
17055
|
return true;
|
|
16707
17056
|
} catch (err) {
|
|
@@ -16719,9 +17068,9 @@ function tryAcquireOnce2(lockPath, meta3, opts) {
|
|
|
16719
17068
|
}
|
|
16720
17069
|
const victimPath = `${lockPath}.victim-${process.pid}-${attempt}-${Date.now()}`;
|
|
16721
17070
|
try {
|
|
16722
|
-
|
|
17071
|
+
fs33.renameSync(lockPath, victimPath);
|
|
16723
17072
|
try {
|
|
16724
|
-
|
|
17073
|
+
fs33.unlinkSync(victimPath);
|
|
16725
17074
|
} catch {
|
|
16726
17075
|
}
|
|
16727
17076
|
} catch (err) {
|
|
@@ -16743,7 +17092,7 @@ async function acquireSettingsJsonLock(options = {}) {
|
|
|
16743
17092
|
while (true) {
|
|
16744
17093
|
const meta3 = {
|
|
16745
17094
|
pid: process.pid,
|
|
16746
|
-
hostname:
|
|
17095
|
+
hostname: os14.hostname(),
|
|
16747
17096
|
timestamp: now(),
|
|
16748
17097
|
...options.reason ? { reason: options.reason } : {}
|
|
16749
17098
|
};
|
|
@@ -16753,7 +17102,7 @@ async function acquireSettingsJsonLock(options = {}) {
|
|
|
16753
17102
|
lockPath,
|
|
16754
17103
|
release: () => {
|
|
16755
17104
|
try {
|
|
16756
|
-
|
|
17105
|
+
fs33.unlinkSync(lockPath);
|
|
16757
17106
|
} catch {
|
|
16758
17107
|
}
|
|
16759
17108
|
}
|
|
@@ -16856,14 +17205,14 @@ var init_services_status = __esm({
|
|
|
16856
17205
|
|
|
16857
17206
|
// ../core/dist/skill-sources/meta-hooks-migration-snapshot.js
|
|
16858
17207
|
import * as crypto5 from "node:crypto";
|
|
16859
|
-
import * as
|
|
16860
|
-
import * as
|
|
16861
|
-
import * as
|
|
17208
|
+
import * as fs34 from "node:fs";
|
|
17209
|
+
import * as os15 from "node:os";
|
|
17210
|
+
import * as path32 from "node:path";
|
|
16862
17211
|
function migrationSnapshotsDir2() {
|
|
16863
17212
|
const override = process.env["OLAM_MIGRATION_SNAPSHOTS_DIR"];
|
|
16864
17213
|
if (override && override.length > 0)
|
|
16865
17214
|
return override;
|
|
16866
|
-
return
|
|
17215
|
+
return path32.join(os15.homedir(), ".olam", "state", "migration-snapshots");
|
|
16867
17216
|
}
|
|
16868
17217
|
function writeMetaHooksSnapshot(originalSettings) {
|
|
16869
17218
|
const snapshot = {
|
|
@@ -16874,11 +17223,11 @@ function writeMetaHooksSnapshot(originalSettings) {
|
|
|
16874
17223
|
};
|
|
16875
17224
|
const validated = MetaHooksMigrationSnapshotSchema.parse(snapshot);
|
|
16876
17225
|
const dir = migrationSnapshotsDir2();
|
|
16877
|
-
|
|
17226
|
+
fs34.mkdirSync(dir, { recursive: true });
|
|
16878
17227
|
const stamp = validated.takenAt.replace(/[:.]/g, "-");
|
|
16879
17228
|
const rand = crypto5.randomBytes(3).toString("hex");
|
|
16880
|
-
const file2 =
|
|
16881
|
-
|
|
17229
|
+
const file2 = path32.join(dir, `${META_HOOKS_SNAPSHOT_PREFIX}${stamp}-${process.pid}-${rand}.json`);
|
|
17230
|
+
fs34.writeFileSync(file2, JSON.stringify(validated, null, 2) + "\n", { mode: 384 });
|
|
16882
17231
|
return file2;
|
|
16883
17232
|
}
|
|
16884
17233
|
var META_HOOKS_SNAPSHOT_SCHEMA_VERSION, META_HOOKS_SNAPSHOT_PREFIX, SettingsLooseSchema, MetaHooksMigrationSnapshotSchema;
|
|
@@ -17168,7 +17517,7 @@ var init_meta_hook_injector = __esm({
|
|
|
17168
17517
|
|
|
17169
17518
|
// ../core/dist/lib/markdown-merger.js
|
|
17170
17519
|
import { createHash as createHash5 } from "node:crypto";
|
|
17171
|
-
import { readFileSync as
|
|
17520
|
+
import { readFileSync as readFileSync31, existsSync as existsSync38, statSync as statSync10 } from "node:fs";
|
|
17172
17521
|
function parseFrontmatter(text) {
|
|
17173
17522
|
const match = FM_RE2.exec(text);
|
|
17174
17523
|
if (match === null)
|
|
@@ -17297,9 +17646,9 @@ function mergeMarkdown(upstreamText, overlayText, labelForError, upstreamPath, o
|
|
|
17297
17646
|
return { merged: fmBlock !== "" ? fmBlock + mergedBody : mergedBody };
|
|
17298
17647
|
}
|
|
17299
17648
|
function sha256OfPath(p) {
|
|
17300
|
-
if (!
|
|
17649
|
+
if (!existsSync38(p) || !statSync10(p).isFile())
|
|
17301
17650
|
return "MISSING";
|
|
17302
|
-
return createHash5("sha256").update(
|
|
17651
|
+
return createHash5("sha256").update(readFileSync31(p)).digest("hex");
|
|
17303
17652
|
}
|
|
17304
17653
|
var FM_RE2, H2_RE;
|
|
17305
17654
|
var init_markdown_merger = __esm({
|
|
@@ -17311,52 +17660,52 @@ var init_markdown_merger = __esm({
|
|
|
17311
17660
|
});
|
|
17312
17661
|
|
|
17313
17662
|
// ../core/dist/skill-sync/managed-merge.js
|
|
17314
|
-
import * as
|
|
17315
|
-
import * as
|
|
17663
|
+
import * as fs35 from "node:fs";
|
|
17664
|
+
import * as path33 from "node:path";
|
|
17316
17665
|
function materializeMergedSkill(opts) {
|
|
17317
|
-
const { sourceId, sourcePath, deployBasename, mergedContent, claudeDir:
|
|
17318
|
-
const managedDir =
|
|
17319
|
-
const sourceRoot =
|
|
17320
|
-
const managedResolved =
|
|
17321
|
-
if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot +
|
|
17666
|
+
const { sourceId, sourcePath, deployBasename, mergedContent, claudeDir: claudeDir3 } = opts;
|
|
17667
|
+
const managedDir = path33.join(claudeDir3, ".olam-merged", sourceId, deployBasename);
|
|
17668
|
+
const sourceRoot = path33.resolve(path33.join(claudeDir3, ".olam-merged", sourceId));
|
|
17669
|
+
const managedResolved = path33.resolve(managedDir);
|
|
17670
|
+
if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot + path33.sep))) {
|
|
17322
17671
|
throw new Error(`[managed-merge] refusing to materialize: deployBasename "${deployBasename}" escapes managed root "${sourceRoot}" (resolved to "${managedResolved}")`);
|
|
17323
17672
|
}
|
|
17324
|
-
|
|
17325
|
-
const skillMdPath =
|
|
17673
|
+
fs35.mkdirSync(managedDir, { recursive: true });
|
|
17674
|
+
const skillMdPath = path33.join(managedDir, "SKILL.md");
|
|
17326
17675
|
const tmpPath = `${skillMdPath}.tmp-${process.pid}-${Date.now()}`;
|
|
17327
|
-
|
|
17328
|
-
|
|
17329
|
-
const baseEntries =
|
|
17676
|
+
fs35.writeFileSync(tmpPath, mergedContent);
|
|
17677
|
+
fs35.renameSync(tmpPath, skillMdPath);
|
|
17678
|
+
const baseEntries = fs35.readdirSync(sourcePath);
|
|
17330
17679
|
for (const entry of baseEntries) {
|
|
17331
17680
|
if (entry === "SKILL.md")
|
|
17332
17681
|
continue;
|
|
17333
|
-
const linkPath =
|
|
17334
|
-
const targetAbsolute =
|
|
17335
|
-
const targetRelative =
|
|
17682
|
+
const linkPath = path33.join(managedDir, entry);
|
|
17683
|
+
const targetAbsolute = path33.join(sourcePath, entry);
|
|
17684
|
+
const targetRelative = path33.relative(managedDir, targetAbsolute);
|
|
17336
17685
|
try {
|
|
17337
|
-
|
|
17338
|
-
|
|
17686
|
+
fs35.lstatSync(linkPath);
|
|
17687
|
+
fs35.rmSync(linkPath, { recursive: true, force: true });
|
|
17339
17688
|
} catch {
|
|
17340
17689
|
}
|
|
17341
|
-
|
|
17690
|
+
fs35.symlinkSync(targetRelative, linkPath);
|
|
17342
17691
|
}
|
|
17343
|
-
const managedEntries =
|
|
17692
|
+
const managedEntries = fs35.readdirSync(managedDir);
|
|
17344
17693
|
const baseEntrySet = new Set(baseEntries);
|
|
17345
17694
|
for (const entry of managedEntries) {
|
|
17346
17695
|
if (entry === "SKILL.md")
|
|
17347
17696
|
continue;
|
|
17348
17697
|
if (!baseEntrySet.has(entry)) {
|
|
17349
|
-
const stalePath =
|
|
17698
|
+
const stalePath = path33.join(managedDir, entry);
|
|
17350
17699
|
try {
|
|
17351
|
-
|
|
17700
|
+
fs35.rmSync(stalePath, { recursive: true, force: true });
|
|
17352
17701
|
} catch {
|
|
17353
17702
|
}
|
|
17354
17703
|
}
|
|
17355
17704
|
}
|
|
17356
17705
|
return managedDir;
|
|
17357
17706
|
}
|
|
17358
|
-
function cleanMergedDir(
|
|
17359
|
-
|
|
17707
|
+
function cleanMergedDir(claudeDir3) {
|
|
17708
|
+
fs35.rmSync(path33.join(claudeDir3, ".olam-merged"), { recursive: true, force: true });
|
|
17360
17709
|
}
|
|
17361
17710
|
var init_managed_merge = __esm({
|
|
17362
17711
|
"../core/dist/skill-sync/managed-merge.js"() {
|
|
@@ -17454,8 +17803,8 @@ var init_prefix_rules = __esm({
|
|
|
17454
17803
|
});
|
|
17455
17804
|
|
|
17456
17805
|
// ../core/dist/skill-sync/prefix-deploy.js
|
|
17457
|
-
import * as
|
|
17458
|
-
import * as
|
|
17806
|
+
import * as fs36 from "node:fs";
|
|
17807
|
+
import * as path34 from "node:path";
|
|
17459
17808
|
function buildSourcePrefixMap(sources) {
|
|
17460
17809
|
const byId = /* @__PURE__ */ new Map();
|
|
17461
17810
|
const scopeById = /* @__PURE__ */ new Map();
|
|
@@ -17476,7 +17825,7 @@ function buildSourcePrefixMap(sources) {
|
|
|
17476
17825
|
registeredPrefixes: Array.from(prefixes)
|
|
17477
17826
|
};
|
|
17478
17827
|
}
|
|
17479
|
-
function applyPrefixRewrites(baseArtifacts, sourceMap,
|
|
17828
|
+
function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir3, dryRun) {
|
|
17480
17829
|
const result = { rewrittenCount: 0, entries: [] };
|
|
17481
17830
|
for (const artifact of baseArtifacts) {
|
|
17482
17831
|
if (artifact.kind !== "skill" && artifact.kind !== "agent")
|
|
@@ -17509,20 +17858,20 @@ function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir2, dryRun) {
|
|
|
17509
17858
|
continue;
|
|
17510
17859
|
}
|
|
17511
17860
|
if (artifact.kind === "skill") {
|
|
17512
|
-
const skillMdPath =
|
|
17513
|
-
const content =
|
|
17861
|
+
const skillMdPath = path34.join(artifact.sourcePath, "SKILL.md");
|
|
17862
|
+
const content = fs36.readFileSync(skillMdPath);
|
|
17514
17863
|
const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
|
|
17515
17864
|
const managedDir = materializeMergedSkill({
|
|
17516
17865
|
sourceId: artifact.sourceId,
|
|
17517
17866
|
sourcePath: artifact.sourcePath,
|
|
17518
17867
|
deployBasename: renamed,
|
|
17519
17868
|
mergedContent: rewritten,
|
|
17520
|
-
claudeDir:
|
|
17869
|
+
claudeDir: claudeDir3
|
|
17521
17870
|
});
|
|
17522
17871
|
artifact.sourcePath = managedDir;
|
|
17523
17872
|
artifact.deployBasename = renamed;
|
|
17524
17873
|
} else {
|
|
17525
|
-
const content = artifact.resolvedContent !== void 0 ? artifact.resolvedContent :
|
|
17874
|
+
const content = artifact.resolvedContent !== void 0 ? artifact.resolvedContent : fs36.readFileSync(artifact.sourcePath);
|
|
17526
17875
|
const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
|
|
17527
17876
|
artifact.resolvedContent = rewritten;
|
|
17528
17877
|
artifact.deployBasename = renamed;
|
|
@@ -17567,19 +17916,19 @@ var init_prefix_deploy = __esm({
|
|
|
17567
17916
|
});
|
|
17568
17917
|
|
|
17569
17918
|
// ../core/dist/skill-sync/resolve-source-config.js
|
|
17570
|
-
import { readFileSync as
|
|
17571
|
-
import { join as
|
|
17919
|
+
import { readFileSync as readFileSync33, existsSync as existsSync39 } from "node:fs";
|
|
17920
|
+
import { join as join39 } from "node:path";
|
|
17572
17921
|
import { parse as parseYaml4 } from "yaml";
|
|
17573
17922
|
function sourceConfigPath(clonePath) {
|
|
17574
|
-
return
|
|
17923
|
+
return join39(clonePath, "shared", "source-config.yaml");
|
|
17575
17924
|
}
|
|
17576
17925
|
function readSourceConfig(clonePath, sourceId) {
|
|
17577
|
-
const
|
|
17578
|
-
if (!
|
|
17926
|
+
const path62 = sourceConfigPath(clonePath);
|
|
17927
|
+
if (!existsSync39(path62))
|
|
17579
17928
|
return void 0;
|
|
17580
17929
|
let raw;
|
|
17581
17930
|
try {
|
|
17582
|
-
raw =
|
|
17931
|
+
raw = readFileSync33(path62, "utf-8");
|
|
17583
17932
|
} catch (err) {
|
|
17584
17933
|
emitMalformedWarning(sourceId, `read failed: ${errToMsg(err)}`);
|
|
17585
17934
|
return void 0;
|
|
@@ -17674,16 +18023,16 @@ var init_resolve_source_config = __esm({
|
|
|
17674
18023
|
});
|
|
17675
18024
|
|
|
17676
18025
|
// ../core/dist/skill-sync/engine.js
|
|
17677
|
-
import * as
|
|
17678
|
-
import * as
|
|
17679
|
-
import * as
|
|
18026
|
+
import * as fs37 from "node:fs";
|
|
18027
|
+
import * as os16 from "node:os";
|
|
18028
|
+
import * as path35 from "node:path";
|
|
17680
18029
|
function resolveAtlasUser(override) {
|
|
17681
18030
|
if (override)
|
|
17682
18031
|
return override;
|
|
17683
|
-
const
|
|
17684
|
-
const f =
|
|
17685
|
-
if (
|
|
17686
|
-
return
|
|
18032
|
+
const claudeDir3 = process.env["OLAM_CLAUDE_DIR"] || path35.join(os16.homedir(), ".claude");
|
|
18033
|
+
const f = path35.join(claudeDir3, ".atlas-user");
|
|
18034
|
+
if (fs37.existsSync(f)) {
|
|
18035
|
+
return fs37.readFileSync(f, "utf-8").trim() || void 0;
|
|
17687
18036
|
}
|
|
17688
18037
|
return void 0;
|
|
17689
18038
|
}
|
|
@@ -17695,7 +18044,7 @@ async function syncSkills(opts = {}) {
|
|
|
17695
18044
|
const perSource = [];
|
|
17696
18045
|
for (const source of sources) {
|
|
17697
18046
|
const clonePath = skillSourceClonePath(source.id);
|
|
17698
|
-
if (!
|
|
18047
|
+
if (!fs37.existsSync(clonePath))
|
|
17699
18048
|
continue;
|
|
17700
18049
|
const { artifacts, subscription } = await withFileLock(clonePath, () => {
|
|
17701
18050
|
const pinRef = projectOverride?.override.pin?.[source.id];
|
|
@@ -17735,7 +18084,7 @@ async function syncSkills(opts = {}) {
|
|
|
17735
18084
|
const overlayArtifacts = memberOverlaysEnabled ? projectFilteredArtifacts.filter((a) => a.kind === "overlay") : [];
|
|
17736
18085
|
const effectiveSources = sources.map((s) => {
|
|
17737
18086
|
const clonePath = skillSourceClonePath(s.id);
|
|
17738
|
-
const sourceConfig =
|
|
18087
|
+
const sourceConfig = fs37.existsSync(clonePath) ? readSourceConfig(clonePath, s.id) : void 0;
|
|
17739
18088
|
const eff = resolveEffectivePrefix(s, sourceConfig);
|
|
17740
18089
|
const entry = {
|
|
17741
18090
|
id: s.id,
|
|
@@ -17827,11 +18176,11 @@ async function syncSkills(opts = {}) {
|
|
|
17827
18176
|
}
|
|
17828
18177
|
const willMutateManagedDir = !opts.dryRun && (memberOverlaysEnabled && overlayArtifacts.length > 0 || hasPrefixRewrites);
|
|
17829
18178
|
if (willMutateManagedDir) {
|
|
17830
|
-
const claude =
|
|
18179
|
+
const claude = claudeDir2();
|
|
17831
18180
|
cleanMergedDir(claude);
|
|
17832
18181
|
}
|
|
17833
18182
|
if (memberOverlaysEnabled && overlayArtifacts.length > 0 && !opts.dryRun) {
|
|
17834
|
-
const claude =
|
|
18183
|
+
const claude = claudeDir2();
|
|
17835
18184
|
for (const overlay of overlayArtifacts) {
|
|
17836
18185
|
if (!overlay.targetKind)
|
|
17837
18186
|
continue;
|
|
@@ -17841,13 +18190,13 @@ async function syncSkills(opts = {}) {
|
|
|
17841
18190
|
let baseContent;
|
|
17842
18191
|
let basePath;
|
|
17843
18192
|
if (overlay.targetKind === "skill") {
|
|
17844
|
-
basePath =
|
|
17845
|
-
baseContent =
|
|
18193
|
+
basePath = path35.join(base.sourcePath, "SKILL.md");
|
|
18194
|
+
baseContent = fs37.readFileSync(basePath, "utf-8");
|
|
17846
18195
|
} else {
|
|
17847
18196
|
basePath = base.sourcePath;
|
|
17848
|
-
baseContent =
|
|
18197
|
+
baseContent = fs37.readFileSync(basePath, "utf-8");
|
|
17849
18198
|
}
|
|
17850
|
-
const overlayContent =
|
|
18199
|
+
const overlayContent = fs37.readFileSync(overlay.sourcePath, "utf-8");
|
|
17851
18200
|
const label = `${overlay.sourceId}/${overlay.deployBasename}`;
|
|
17852
18201
|
const mergeResult = mergeMarkdown(baseContent, overlayContent, label, basePath, overlay.sourcePath);
|
|
17853
18202
|
if ("error" in mergeResult) {
|
|
@@ -17871,7 +18220,7 @@ async function syncSkills(opts = {}) {
|
|
|
17871
18220
|
}
|
|
17872
18221
|
const hookFiles = projectFilteredArtifacts.filter((a) => a.kind === "hook").map((a) => a.sourcePath);
|
|
17873
18222
|
const permissionFiles = projectFilteredArtifacts.filter((a) => a.kind === "permission").map((a) => a.sourcePath);
|
|
17874
|
-
const claudeDirForRewrites =
|
|
18223
|
+
const claudeDirForRewrites = claudeDir2();
|
|
17875
18224
|
const prefixRewriteResult = applyPrefixRewrites(baseArtifacts, sourcePrefixMap, claudeDirForRewrites, opts.dryRun === true);
|
|
17876
18225
|
const prefixCollisions = detectPrefixCollisions(effectiveSources);
|
|
17877
18226
|
if (!opts.dryRun) {
|
|
@@ -17908,7 +18257,7 @@ async function syncSkills(opts = {}) {
|
|
|
17908
18257
|
summary.collisions = detectCollisions(baseArtifacts).collisions;
|
|
17909
18258
|
return summary;
|
|
17910
18259
|
}
|
|
17911
|
-
const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] ||
|
|
18260
|
+
const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] || path35.join(os16.homedir(), ".claude");
|
|
17912
18261
|
const overlayReferences = scanOverlayReferences(claudeDirPath, SHIM_TARGETS.map((t) => t.basename));
|
|
17913
18262
|
summary.deploy = deployArtifacts(baseArtifacts, {
|
|
17914
18263
|
installedOlamVersion,
|
|
@@ -17944,19 +18293,19 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
17944
18293
|
const result = await withSettingsJsonLock(() => {
|
|
17945
18294
|
let currentSettings = {};
|
|
17946
18295
|
let settingsExisted = false;
|
|
17947
|
-
if (
|
|
18296
|
+
if (fs37.existsSync(settingsFile)) {
|
|
17948
18297
|
settingsExisted = true;
|
|
17949
18298
|
try {
|
|
17950
|
-
const raw =
|
|
18299
|
+
const raw = fs37.readFileSync(settingsFile, "utf-8");
|
|
17951
18300
|
currentSettings = raw.trim() ? JSON.parse(raw) : {};
|
|
17952
18301
|
} catch {
|
|
17953
18302
|
try {
|
|
17954
|
-
const raw =
|
|
17955
|
-
const bakDir =
|
|
17956
|
-
|
|
18303
|
+
const raw = fs37.readFileSync(settingsFile);
|
|
18304
|
+
const bakDir = path35.join(path35.dirname(settingsFile), ".malformed-backups");
|
|
18305
|
+
fs37.mkdirSync(bakDir, { recursive: true });
|
|
17957
18306
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
17958
|
-
const bakFile =
|
|
17959
|
-
|
|
18307
|
+
const bakFile = path35.join(bakDir, `settings.json.malformed.${stamp}.bak`);
|
|
18308
|
+
fs37.writeFileSync(bakFile, raw, { mode: 384 });
|
|
17960
18309
|
snapshotError = `settings.json was malformed; original bytes preserved at ${bakFile}`;
|
|
17961
18310
|
} catch (bakErr) {
|
|
17962
18311
|
snapshotError = `settings.json malformed AND .bak write failed: ${bakErr instanceof Error ? bakErr.message : String(bakErr)}`;
|
|
@@ -17996,10 +18345,10 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
17996
18345
|
} catch {
|
|
17997
18346
|
}
|
|
17998
18347
|
}
|
|
17999
|
-
|
|
18348
|
+
fs37.mkdirSync(path35.dirname(settingsFile), { recursive: true });
|
|
18000
18349
|
const tmpPath = `${settingsFile}.tmp-${process.pid}-${Date.now()}`;
|
|
18001
|
-
|
|
18002
|
-
|
|
18350
|
+
fs37.writeFileSync(tmpPath, JSON.stringify(inject.nextSettings, null, 2) + "\n");
|
|
18351
|
+
fs37.renameSync(tmpPath, settingsFile);
|
|
18003
18352
|
return inject;
|
|
18004
18353
|
}, { reason: `syncSkills meta-hook injection (mode=${mode})` });
|
|
18005
18354
|
let scriptDeploy;
|
|
@@ -18007,7 +18356,7 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
18007
18356
|
if (modelRouterTargeted) {
|
|
18008
18357
|
try {
|
|
18009
18358
|
scriptDeploy = deployModelRouterScript({
|
|
18010
|
-
targetDir:
|
|
18359
|
+
targetDir: path35.join(claudeDir2(), "hooks")
|
|
18011
18360
|
});
|
|
18012
18361
|
} catch (err) {
|
|
18013
18362
|
scriptDeploy = {
|
|
@@ -18058,19 +18407,19 @@ var init_engine = __esm({
|
|
|
18058
18407
|
});
|
|
18059
18408
|
|
|
18060
18409
|
// ../core/dist/skill-sync/shadow-backup-manager.js
|
|
18061
|
-
import * as
|
|
18062
|
-
import * as
|
|
18410
|
+
import * as fs38 from "node:fs";
|
|
18411
|
+
import * as path36 from "node:path";
|
|
18063
18412
|
function listShadowBackups(opts = {}) {
|
|
18064
|
-
const claude = opts.claudeDirOverride ??
|
|
18413
|
+
const claude = opts.claudeDirOverride ?? claudeDir2();
|
|
18065
18414
|
const now = opts.now ?? Date.now();
|
|
18066
18415
|
const out = [];
|
|
18067
18416
|
for (const bucket of SHADOW_BACKUP_BUCKETS) {
|
|
18068
|
-
const bucketDir =
|
|
18069
|
-
if (!
|
|
18417
|
+
const bucketDir = path36.join(claude, bucket);
|
|
18418
|
+
if (!fs38.existsSync(bucketDir))
|
|
18070
18419
|
continue;
|
|
18071
18420
|
let entries;
|
|
18072
18421
|
try {
|
|
18073
|
-
entries =
|
|
18422
|
+
entries = fs38.readdirSync(bucketDir);
|
|
18074
18423
|
} catch {
|
|
18075
18424
|
continue;
|
|
18076
18425
|
}
|
|
@@ -18081,11 +18430,11 @@ function listShadowBackups(opts = {}) {
|
|
|
18081
18430
|
const epochSeconds = Number.parseInt(match[1], 10);
|
|
18082
18431
|
if (!Number.isFinite(epochSeconds) || epochSeconds < 0)
|
|
18083
18432
|
continue;
|
|
18084
|
-
const full =
|
|
18433
|
+
const full = path36.join(bucketDir, name);
|
|
18085
18434
|
let sizeBytes = 0;
|
|
18086
18435
|
let isDir = false;
|
|
18087
18436
|
try {
|
|
18088
|
-
const st =
|
|
18437
|
+
const st = fs38.statSync(full);
|
|
18089
18438
|
isDir = st.isDirectory();
|
|
18090
18439
|
if (!isDir)
|
|
18091
18440
|
sizeBytes = st.size;
|
|
@@ -18098,7 +18447,7 @@ function listShadowBackups(opts = {}) {
|
|
|
18098
18447
|
bucket,
|
|
18099
18448
|
basename: name,
|
|
18100
18449
|
originalBasename,
|
|
18101
|
-
originalPath:
|
|
18450
|
+
originalPath: path36.join(bucketDir, originalBasename),
|
|
18102
18451
|
epochSeconds,
|
|
18103
18452
|
ageMs: now - epochSeconds * 1e3,
|
|
18104
18453
|
sizeBytes,
|
|
@@ -18143,9 +18492,9 @@ function pruneShadowBackups(opts) {
|
|
|
18143
18492
|
if (!opts.dryRun) {
|
|
18144
18493
|
try {
|
|
18145
18494
|
if (b.isDir) {
|
|
18146
|
-
|
|
18495
|
+
fs38.rmSync(b.path, { recursive: true, force: true });
|
|
18147
18496
|
} else {
|
|
18148
|
-
|
|
18497
|
+
fs38.unlinkSync(b.path);
|
|
18149
18498
|
}
|
|
18150
18499
|
} catch {
|
|
18151
18500
|
skipped.push(b);
|
|
@@ -18157,29 +18506,29 @@ function pruneShadowBackups(opts) {
|
|
|
18157
18506
|
return { deleted, skipped };
|
|
18158
18507
|
}
|
|
18159
18508
|
function restoreShadowBackup(opts) {
|
|
18160
|
-
const abs =
|
|
18161
|
-
if (!
|
|
18509
|
+
const abs = path36.resolve(opts.backupPath);
|
|
18510
|
+
if (!fs38.existsSync(abs)) {
|
|
18162
18511
|
throw new Error(`backup file not found: ${abs}`);
|
|
18163
18512
|
}
|
|
18164
|
-
const basename6 =
|
|
18513
|
+
const basename6 = path36.basename(abs);
|
|
18165
18514
|
const match = SHADOW_BACKUP_SUFFIX_RE.exec(basename6);
|
|
18166
18515
|
if (!match) {
|
|
18167
18516
|
throw new Error(`not a shadow-backup file (basename "${basename6}" does not match \`.shadow-backup-<epoch>\`): ${abs}`);
|
|
18168
18517
|
}
|
|
18169
18518
|
const originalBasename = basename6.slice(0, basename6.length - match[0].length);
|
|
18170
|
-
const originalPath =
|
|
18171
|
-
if (
|
|
18519
|
+
const originalPath = path36.join(path36.dirname(abs), originalBasename);
|
|
18520
|
+
if (fs38.existsSync(originalPath) && !opts.force) {
|
|
18172
18521
|
throw new Error(`original path already occupied: ${originalPath}. Move/rename it first OR re-run with --force.`);
|
|
18173
18522
|
}
|
|
18174
|
-
if (opts.force &&
|
|
18175
|
-
const existingStat =
|
|
18523
|
+
if (opts.force && fs38.existsSync(originalPath)) {
|
|
18524
|
+
const existingStat = fs38.statSync(originalPath);
|
|
18176
18525
|
if (existingStat.isDirectory()) {
|
|
18177
|
-
|
|
18526
|
+
fs38.rmSync(originalPath, { recursive: true, force: true });
|
|
18178
18527
|
} else {
|
|
18179
|
-
|
|
18528
|
+
fs38.unlinkSync(originalPath);
|
|
18180
18529
|
}
|
|
18181
18530
|
}
|
|
18182
|
-
|
|
18531
|
+
fs38.renameSync(abs, originalPath);
|
|
18183
18532
|
return { restoredTo: originalPath };
|
|
18184
18533
|
}
|
|
18185
18534
|
var SHADOW_BACKUP_BUCKETS, SHADOW_BACKUP_SUFFIX_RE;
|
|
@@ -18193,27 +18542,27 @@ var init_shadow_backup_manager = __esm({
|
|
|
18193
18542
|
});
|
|
18194
18543
|
|
|
18195
18544
|
// ../core/dist/skill-sources/doctor-checks.js
|
|
18196
|
-
import * as
|
|
18197
|
-
import * as
|
|
18198
|
-
import * as
|
|
18545
|
+
import * as fs39 from "node:fs";
|
|
18546
|
+
import * as path37 from "node:path";
|
|
18547
|
+
import * as os17 from "node:os";
|
|
18199
18548
|
function claudeDirInternal3() {
|
|
18200
18549
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
18201
18550
|
if (override && override.length > 0)
|
|
18202
18551
|
return override;
|
|
18203
|
-
return
|
|
18552
|
+
return path37.join(os17.homedir(), ".claude");
|
|
18204
18553
|
}
|
|
18205
18554
|
function checkStateFileParse() {
|
|
18206
|
-
const filePath =
|
|
18555
|
+
const filePath = globalConfigPath2();
|
|
18207
18556
|
const result = {
|
|
18208
18557
|
name: "state-parse",
|
|
18209
18558
|
healthy: true,
|
|
18210
18559
|
description: `~/.olam state file (${filePath})`
|
|
18211
18560
|
};
|
|
18212
|
-
if (!
|
|
18561
|
+
if (!fs39.existsSync(filePath)) {
|
|
18213
18562
|
result.details = ["(file does not yet exist \u2014 will be created on first write)"];
|
|
18214
18563
|
return result;
|
|
18215
18564
|
}
|
|
18216
|
-
const raw =
|
|
18565
|
+
const raw = fs39.readFileSync(filePath, "utf-8");
|
|
18217
18566
|
let parsed;
|
|
18218
18567
|
try {
|
|
18219
18568
|
parsed = JSON.parse(raw);
|
|
@@ -18223,8 +18572,8 @@ function checkStateFileParse() {
|
|
|
18223
18572
|
result.details = [err instanceof Error ? err.message : String(err)];
|
|
18224
18573
|
result.repair = () => {
|
|
18225
18574
|
const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
|
|
18226
|
-
|
|
18227
|
-
|
|
18575
|
+
fs39.renameSync(filePath, aside);
|
|
18576
|
+
fs39.writeFileSync(filePath, JSON.stringify({ schemaVersion: 1, repos: [], runbooks: [], skillSources: [] }, null, 2));
|
|
18228
18577
|
};
|
|
18229
18578
|
return result;
|
|
18230
18579
|
}
|
|
@@ -18233,18 +18582,20 @@ function checkStateFileParse() {
|
|
|
18233
18582
|
result.healthy = false;
|
|
18234
18583
|
result.issue = "state file does not match GlobalConfigSchema";
|
|
18235
18584
|
result.details = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
|
|
18585
|
+
const salvaged = quarantineGlobalConfig(parsed);
|
|
18586
|
+
const droppedCount = salvaged?.drops.length ?? 0;
|
|
18587
|
+
if (salvaged !== null) {
|
|
18588
|
+
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"}.`);
|
|
18589
|
+
} else {
|
|
18590
|
+
result.details.push("auto-fix cannot salvage any entries (top-level corruption) \u2014 will reset to empty.");
|
|
18591
|
+
}
|
|
18236
18592
|
result.repair = () => {
|
|
18237
18593
|
const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
|
|
18238
|
-
|
|
18594
|
+
fs39.copyFileSync(filePath, aside);
|
|
18239
18595
|
const base = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
18240
|
-
const
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
repos: [],
|
|
18244
|
-
runbooks: [],
|
|
18245
|
-
skillSources: []
|
|
18246
|
-
};
|
|
18247
|
-
fs37.writeFileSync(filePath, JSON.stringify(next, null, 2));
|
|
18596
|
+
const recovered = quarantineGlobalConfig(parsed);
|
|
18597
|
+
const next = recovered !== null ? { ...base, ...recovered.value } : { ...base, schemaVersion: 1, repos: [], runbooks: [], skillSources: [] };
|
|
18598
|
+
fs39.writeFileSync(filePath, JSON.stringify(next, null, 2));
|
|
18248
18599
|
};
|
|
18249
18600
|
return result;
|
|
18250
18601
|
}
|
|
@@ -18255,16 +18606,16 @@ function checkDanglingSymlinks() {
|
|
|
18255
18606
|
const buckets = ["commands", "agents", "skills", "scripts", "rules"];
|
|
18256
18607
|
const dangling = [];
|
|
18257
18608
|
for (const bucket of buckets) {
|
|
18258
|
-
const dir =
|
|
18259
|
-
if (!
|
|
18609
|
+
const dir = path37.join(claude, bucket);
|
|
18610
|
+
if (!fs39.existsSync(dir))
|
|
18260
18611
|
continue;
|
|
18261
|
-
for (const name of
|
|
18262
|
-
const linkPath =
|
|
18612
|
+
for (const name of fs39.readdirSync(dir)) {
|
|
18613
|
+
const linkPath = path37.join(dir, name);
|
|
18263
18614
|
try {
|
|
18264
|
-
const lst =
|
|
18615
|
+
const lst = fs39.lstatSync(linkPath);
|
|
18265
18616
|
if (!lst.isSymbolicLink())
|
|
18266
18617
|
continue;
|
|
18267
|
-
if (!
|
|
18618
|
+
if (!fs39.existsSync(linkPath)) {
|
|
18268
18619
|
dangling.push(linkPath);
|
|
18269
18620
|
}
|
|
18270
18621
|
} catch {
|
|
@@ -18282,7 +18633,7 @@ function checkDanglingSymlinks() {
|
|
|
18282
18633
|
result.repair = () => {
|
|
18283
18634
|
for (const p of dangling) {
|
|
18284
18635
|
try {
|
|
18285
|
-
|
|
18636
|
+
fs39.unlinkSync(p);
|
|
18286
18637
|
} catch {
|
|
18287
18638
|
}
|
|
18288
18639
|
}
|
|
@@ -18297,19 +18648,19 @@ function checkOrphanedSnapshots() {
|
|
|
18297
18648
|
healthy: true,
|
|
18298
18649
|
description: `orphaned migration snapshots under ${dir}`
|
|
18299
18650
|
};
|
|
18300
|
-
if (!
|
|
18651
|
+
if (!fs39.existsSync(dir)) {
|
|
18301
18652
|
return result;
|
|
18302
18653
|
}
|
|
18303
18654
|
const orphans = [];
|
|
18304
|
-
for (const name of
|
|
18655
|
+
for (const name of fs39.readdirSync(dir)) {
|
|
18305
18656
|
if (!name.endsWith(".json"))
|
|
18306
18657
|
continue;
|
|
18307
|
-
const full =
|
|
18658
|
+
const full = path37.join(dir, name);
|
|
18308
18659
|
try {
|
|
18309
|
-
const stat2 =
|
|
18660
|
+
const stat2 = fs39.statSync(full);
|
|
18310
18661
|
if (!stat2.isFile())
|
|
18311
18662
|
continue;
|
|
18312
|
-
const raw =
|
|
18663
|
+
const raw = fs39.readFileSync(full, "utf-8");
|
|
18313
18664
|
let parsed;
|
|
18314
18665
|
try {
|
|
18315
18666
|
parsed = JSON.parse(raw);
|
|
@@ -18334,7 +18685,7 @@ function checkOrphanedSnapshots() {
|
|
|
18334
18685
|
result.repair = () => {
|
|
18335
18686
|
for (const o of orphans) {
|
|
18336
18687
|
try {
|
|
18337
|
-
|
|
18688
|
+
fs39.unlinkSync(o.path);
|
|
18338
18689
|
} catch {
|
|
18339
18690
|
}
|
|
18340
18691
|
}
|
|
@@ -18349,12 +18700,12 @@ function checkSentinelDrift() {
|
|
|
18349
18700
|
healthy: true,
|
|
18350
18701
|
description: `olam-skills sentinel block in ${filePath}`
|
|
18351
18702
|
};
|
|
18352
|
-
if (!
|
|
18703
|
+
if (!fs39.existsSync(filePath)) {
|
|
18353
18704
|
return result;
|
|
18354
18705
|
}
|
|
18355
18706
|
let parsed;
|
|
18356
18707
|
try {
|
|
18357
|
-
parsed = JSON.parse(
|
|
18708
|
+
parsed = JSON.parse(fs39.readFileSync(filePath, "utf-8"));
|
|
18358
18709
|
} catch {
|
|
18359
18710
|
return result;
|
|
18360
18711
|
}
|
|
@@ -18395,7 +18746,7 @@ function checkSentinelDrift() {
|
|
|
18395
18746
|
backupSettings();
|
|
18396
18747
|
} catch {
|
|
18397
18748
|
}
|
|
18398
|
-
const next = JSON.parse(
|
|
18749
|
+
const next = JSON.parse(fs39.readFileSync(filePath, "utf-8"));
|
|
18399
18750
|
if (!next.hooks)
|
|
18400
18751
|
return;
|
|
18401
18752
|
for (const stage of Object.keys(next.hooks)) {
|
|
@@ -18418,7 +18769,7 @@ function checkSentinelDrift() {
|
|
|
18418
18769
|
return bad === void 0;
|
|
18419
18770
|
});
|
|
18420
18771
|
}
|
|
18421
|
-
|
|
18772
|
+
fs39.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
18422
18773
|
};
|
|
18423
18774
|
}
|
|
18424
18775
|
return result;
|
|
@@ -18441,9 +18792,9 @@ function checkMemberNameMissing() {
|
|
|
18441
18792
|
result.details = ["(atlas-toolbox source not registered \u2014 check not applicable)"];
|
|
18442
18793
|
return result;
|
|
18443
18794
|
}
|
|
18444
|
-
const
|
|
18445
|
-
const atlasUserPath =
|
|
18446
|
-
const value =
|
|
18795
|
+
const claudeDir3 = claudeDirInternal3();
|
|
18796
|
+
const atlasUserPath = path37.join(claudeDir3, ".atlas-user");
|
|
18797
|
+
const value = fs39.existsSync(atlasUserPath) ? fs39.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
18447
18798
|
if (value.length > 0) {
|
|
18448
18799
|
result.details = [`atlas-user: ${value}`];
|
|
18449
18800
|
return result;
|
|
@@ -18451,10 +18802,10 @@ function checkMemberNameMissing() {
|
|
|
18451
18802
|
result.healthy = false;
|
|
18452
18803
|
result.issue = "atlas-toolbox source registered but ~/.claude/.atlas-user not set";
|
|
18453
18804
|
const clonePath = skillSourceClonePath(atlasSource.id);
|
|
18454
|
-
const membersDir =
|
|
18455
|
-
const existing =
|
|
18805
|
+
const membersDir = path37.join(clonePath, "members");
|
|
18806
|
+
const existing = fs39.existsSync(membersDir) ? fs39.readdirSync(membersDir).filter((e) => {
|
|
18456
18807
|
try {
|
|
18457
|
-
return
|
|
18808
|
+
return fs39.statSync(path37.join(membersDir, e)).isDirectory();
|
|
18458
18809
|
} catch {
|
|
18459
18810
|
return false;
|
|
18460
18811
|
}
|
|
@@ -18467,9 +18818,9 @@ function checkMemberNameMissing() {
|
|
|
18467
18818
|
return result;
|
|
18468
18819
|
}
|
|
18469
18820
|
function checkMemberOverlayDrift() {
|
|
18470
|
-
const
|
|
18471
|
-
const atlasUserPath =
|
|
18472
|
-
const atlasUser =
|
|
18821
|
+
const claudeDir3 = claudeDirInternal3();
|
|
18822
|
+
const atlasUserPath = path37.join(claudeDir3, ".atlas-user");
|
|
18823
|
+
const atlasUser = fs39.existsSync(atlasUserPath) ? fs39.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
18473
18824
|
if (atlasUser.length === 0) {
|
|
18474
18825
|
return [];
|
|
18475
18826
|
}
|
|
@@ -18485,26 +18836,26 @@ function checkMemberOverlayDrift() {
|
|
|
18485
18836
|
const clonePath = skillSourceClonePath(atlasSource.id);
|
|
18486
18837
|
const results = [];
|
|
18487
18838
|
for (const kind of ["skills", "agents"]) {
|
|
18488
|
-
const localRoot =
|
|
18489
|
-
if (!
|
|
18839
|
+
const localRoot = path37.join(claudeDir3, `${kind}.overrides`);
|
|
18840
|
+
if (!fs39.existsSync(localRoot))
|
|
18490
18841
|
continue;
|
|
18491
18842
|
let entries;
|
|
18492
18843
|
try {
|
|
18493
|
-
entries =
|
|
18844
|
+
entries = fs39.readdirSync(localRoot);
|
|
18494
18845
|
} catch {
|
|
18495
18846
|
continue;
|
|
18496
18847
|
}
|
|
18497
18848
|
for (const entry of entries) {
|
|
18498
|
-
const localFile =
|
|
18849
|
+
const localFile = path37.join(localRoot, entry);
|
|
18499
18850
|
let stat2;
|
|
18500
18851
|
try {
|
|
18501
|
-
stat2 =
|
|
18852
|
+
stat2 = fs39.statSync(localFile);
|
|
18502
18853
|
} catch {
|
|
18503
18854
|
continue;
|
|
18504
18855
|
}
|
|
18505
18856
|
if (!stat2.isFile())
|
|
18506
18857
|
continue;
|
|
18507
|
-
const cloneFile =
|
|
18858
|
+
const cloneFile = path37.join(clonePath, "members", atlasUser, `${kind}.overrides`, entry);
|
|
18508
18859
|
const localSha = sha256OfPath(localFile);
|
|
18509
18860
|
const cloneSha = sha256OfPath(cloneFile);
|
|
18510
18861
|
if (localSha === cloneSha) {
|
|
@@ -18559,16 +18910,16 @@ var init_doctor_checks = __esm({
|
|
|
18559
18910
|
});
|
|
18560
18911
|
|
|
18561
18912
|
// ../core/dist/skill-sync/detect-pull-deploy-drift.js
|
|
18562
|
-
import * as
|
|
18563
|
-
import * as
|
|
18913
|
+
import * as fs40 from "node:fs";
|
|
18914
|
+
import * as path38 from "node:path";
|
|
18564
18915
|
function deployedSymlinkBasenames(bucketDir) {
|
|
18565
18916
|
const result = /* @__PURE__ */ new Set();
|
|
18566
|
-
if (!
|
|
18917
|
+
if (!fs40.existsSync(bucketDir))
|
|
18567
18918
|
return result;
|
|
18568
|
-
for (const name of
|
|
18569
|
-
const p =
|
|
18919
|
+
for (const name of fs40.readdirSync(bucketDir)) {
|
|
18920
|
+
const p = path38.join(bucketDir, name);
|
|
18570
18921
|
try {
|
|
18571
|
-
if (
|
|
18922
|
+
if (fs40.lstatSync(p).isSymbolicLink()) {
|
|
18572
18923
|
result.add(name);
|
|
18573
18924
|
}
|
|
18574
18925
|
} catch {
|
|
@@ -18579,7 +18930,7 @@ function deployedSymlinkBasenames(bucketDir) {
|
|
|
18579
18930
|
function detectPullDeployDrift(opts) {
|
|
18580
18931
|
const { clonePath, sourceId, atlasUser } = opts;
|
|
18581
18932
|
const { artifacts } = resolveSourceArtifacts({ sourceId, clonePath, atlasUser });
|
|
18582
|
-
const sourceConfig =
|
|
18933
|
+
const sourceConfig = fs40.existsSync(clonePath) ? readSourceConfig(clonePath, sourceId) : void 0;
|
|
18583
18934
|
const eff = resolveEffectivePrefix(opts.operatorSource ?? {}, sourceConfig);
|
|
18584
18935
|
const prefixEntry = { id: sourceId };
|
|
18585
18936
|
if (eff.prefix !== void 0)
|
|
@@ -18588,7 +18939,7 @@ function detectPullDeployDrift(opts) {
|
|
|
18588
18939
|
prefixEntry.prefixScope = eff.prefixScope;
|
|
18589
18940
|
if (eff.prefixTarget !== void 0)
|
|
18590
18941
|
prefixEntry.prefixTarget = eff.prefixTarget;
|
|
18591
|
-
applyPrefixRewrites(artifacts, buildSourcePrefixMap([prefixEntry]),
|
|
18942
|
+
applyPrefixRewrites(artifacts, buildSourcePrefixMap([prefixEntry]), claudeDir2(), true);
|
|
18592
18943
|
const cloneByKind = {
|
|
18593
18944
|
skill: /* @__PURE__ */ new Set(),
|
|
18594
18945
|
agent: /* @__PURE__ */ new Set(),
|
|
@@ -18606,7 +18957,7 @@ function detectPullDeployDrift(opts) {
|
|
|
18606
18957
|
const kind = artifact.kind;
|
|
18607
18958
|
cloneByKind[kind].add(artifact.deployBasename);
|
|
18608
18959
|
}
|
|
18609
|
-
const claude =
|
|
18960
|
+
const claude = claudeDir2();
|
|
18610
18961
|
const perKind = {
|
|
18611
18962
|
skill: { added: [], removed: [] },
|
|
18612
18963
|
agent: { added: [], removed: [] },
|
|
@@ -18616,7 +18967,7 @@ function detectPullDeployDrift(opts) {
|
|
|
18616
18967
|
let total = 0;
|
|
18617
18968
|
for (const kind of Object.keys(KIND_TO_BUCKET)) {
|
|
18618
18969
|
const bucket = KIND_TO_BUCKET[kind];
|
|
18619
|
-
const bucketDir =
|
|
18970
|
+
const bucketDir = path38.join(claude, bucket);
|
|
18620
18971
|
const deployed = deployedSymlinkBasenames(bucketDir);
|
|
18621
18972
|
const cloneBasenames = cloneByKind[kind];
|
|
18622
18973
|
const added = [];
|
|
@@ -18667,11 +19018,13 @@ __export(skill_sources_exports, {
|
|
|
18667
19018
|
PROJECT_OVERRIDE_RELATIVE_PATH: () => PROJECT_OVERRIDE_RELATIVE_PATH,
|
|
18668
19019
|
SKILL_SOURCES_AUDIT_LOG_FILENAME: () => SKILL_SOURCES_AUDIT_LOG_FILENAME,
|
|
18669
19020
|
SKILL_SOURCE_ID_LENGTH: () => SKILL_SOURCE_ID_LENGTH,
|
|
19021
|
+
SOURCE_SIDECAR_FILENAME: () => SOURCE_SIDECAR_FILENAME,
|
|
18670
19022
|
SkillOverrideSchema: () => SkillOverrideSchema,
|
|
18671
19023
|
SkillSourceGitError: () => SkillSourceGitError,
|
|
18672
19024
|
SkillSourceSchema: () => SkillSourceSchema,
|
|
18673
19025
|
SourceConfigSchema: () => SourceConfigSchema,
|
|
18674
19026
|
SourceConfigSnapshotSchema: () => SourceConfigSnapshotSchema,
|
|
19027
|
+
SourceSidecarSchema: () => SourceSidecarSchema,
|
|
18675
19028
|
TrustActionSchema: () => TrustActionSchema,
|
|
18676
19029
|
TrustAuditEntrySchema: () => TrustAuditEntrySchema,
|
|
18677
19030
|
TrustMethodSchema: () => TrustMethodSchema,
|
|
@@ -18688,7 +19041,7 @@ __export(skill_sources_exports, {
|
|
|
18688
19041
|
checkOrphanedSnapshots: () => checkOrphanedSnapshots,
|
|
18689
19042
|
checkSentinelDrift: () => checkSentinelDrift,
|
|
18690
19043
|
checkStateFileParse: () => checkStateFileParse,
|
|
18691
|
-
claudeDir: () =>
|
|
19044
|
+
claudeDir: () => claudeDir2,
|
|
18692
19045
|
claudeSettingsPath: () => claudeSettingsPath,
|
|
18693
19046
|
cloneSkillSource: () => cloneSkillSource,
|
|
18694
19047
|
computeSkillsHookUninstall: () => computeUninstall,
|
|
@@ -18713,7 +19066,10 @@ __export(skill_sources_exports, {
|
|
|
18713
19066
|
readLatestMigrationSnapshot: () => readLatestMigrationSnapshot,
|
|
18714
19067
|
readMigrationSnapshotFromPath: () => readMigrationSnapshotFromPath,
|
|
18715
19068
|
readSourceConfig: () => readSourceConfig,
|
|
19069
|
+
readSourceSidecar: () => readSourceSidecar,
|
|
18716
19070
|
readTrustAuditLog: () => readTrustAuditLog,
|
|
19071
|
+
reconcileIfRegistryEmpty: () => reconcileIfRegistryEmpty,
|
|
19072
|
+
reconcileSkillSources: () => reconcileSkillSources,
|
|
18717
19073
|
redactUrl: () => redactUrl2,
|
|
18718
19074
|
removeSkillSource: () => removeSkillSource,
|
|
18719
19075
|
removeSkillSourceClone: () => removeSkillSourceClone,
|
|
@@ -18732,11 +19088,13 @@ __export(skill_sources_exports, {
|
|
|
18732
19088
|
skillsHookSettingsPathFor: () => settingsPathFor,
|
|
18733
19089
|
sourceConfigPath: () => sourceConfigPath,
|
|
18734
19090
|
sourceConfigsEqual: () => sourceConfigsEqual,
|
|
19091
|
+
sourceSidecarPath: () => sourceSidecarPath,
|
|
18735
19092
|
syncSkills: () => syncSkills,
|
|
18736
19093
|
uninstallSkillsHookFromFile: () => uninstallSkillsHookFromFile,
|
|
18737
19094
|
updateSkillSource: () => updateSkillSource,
|
|
18738
19095
|
withFileLock: () => withFileLock,
|
|
18739
|
-
writeMigrationSnapshot: () => writeMigrationSnapshot
|
|
19096
|
+
writeMigrationSnapshot: () => writeMigrationSnapshot,
|
|
19097
|
+
writeSourceSidecar: () => writeSourceSidecar
|
|
18740
19098
|
});
|
|
18741
19099
|
var init_skill_sources = __esm({
|
|
18742
19100
|
"../core/dist/skill-sources/index.js"() {
|
|
@@ -18744,6 +19102,8 @@ var init_skill_sources = __esm({
|
|
|
18744
19102
|
init_schema3();
|
|
18745
19103
|
init_store3();
|
|
18746
19104
|
init_clone();
|
|
19105
|
+
init_source_file();
|
|
19106
|
+
init_reconcile();
|
|
18747
19107
|
init_hook_template();
|
|
18748
19108
|
init_hook_install();
|
|
18749
19109
|
init_migration_snapshot();
|
|
@@ -19549,10 +19909,10 @@ function mergeDefs(...defs) {
|
|
|
19549
19909
|
function cloneDef(schema) {
|
|
19550
19910
|
return mergeDefs(schema._zod.def);
|
|
19551
19911
|
}
|
|
19552
|
-
function getElementAtPath(obj,
|
|
19553
|
-
if (!
|
|
19912
|
+
function getElementAtPath(obj, path62) {
|
|
19913
|
+
if (!path62)
|
|
19554
19914
|
return obj;
|
|
19555
|
-
return
|
|
19915
|
+
return path62.reduce((acc, key) => acc?.[key], obj);
|
|
19556
19916
|
}
|
|
19557
19917
|
function promiseAllObject(promisesObj) {
|
|
19558
19918
|
const keys = Object.keys(promisesObj);
|
|
@@ -19961,11 +20321,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
19961
20321
|
}
|
|
19962
20322
|
return false;
|
|
19963
20323
|
}
|
|
19964
|
-
function prefixIssues(
|
|
20324
|
+
function prefixIssues(path62, issues) {
|
|
19965
20325
|
return issues.map((iss) => {
|
|
19966
20326
|
var _a3;
|
|
19967
20327
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
19968
|
-
iss.path.unshift(
|
|
20328
|
+
iss.path.unshift(path62);
|
|
19969
20329
|
return iss;
|
|
19970
20330
|
});
|
|
19971
20331
|
}
|
|
@@ -20112,16 +20472,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
20112
20472
|
}
|
|
20113
20473
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
20114
20474
|
const fieldErrors = { _errors: [] };
|
|
20115
|
-
const processError = (error52,
|
|
20475
|
+
const processError = (error52, path62 = []) => {
|
|
20116
20476
|
for (const issue2 of error52.issues) {
|
|
20117
20477
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
20118
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
20478
|
+
issue2.errors.map((issues) => processError({ issues }, [...path62, ...issue2.path]));
|
|
20119
20479
|
} else if (issue2.code === "invalid_key") {
|
|
20120
|
-
processError({ issues: issue2.issues }, [...
|
|
20480
|
+
processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
|
|
20121
20481
|
} else if (issue2.code === "invalid_element") {
|
|
20122
|
-
processError({ issues: issue2.issues }, [...
|
|
20482
|
+
processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
|
|
20123
20483
|
} else {
|
|
20124
|
-
const fullpath = [...
|
|
20484
|
+
const fullpath = [...path62, ...issue2.path];
|
|
20125
20485
|
if (fullpath.length === 0) {
|
|
20126
20486
|
fieldErrors._errors.push(mapper(issue2));
|
|
20127
20487
|
} else {
|
|
@@ -20148,17 +20508,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
20148
20508
|
}
|
|
20149
20509
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
20150
20510
|
const result = { errors: [] };
|
|
20151
|
-
const processError = (error52,
|
|
20511
|
+
const processError = (error52, path62 = []) => {
|
|
20152
20512
|
var _a3, _b;
|
|
20153
20513
|
for (const issue2 of error52.issues) {
|
|
20154
20514
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
20155
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
20515
|
+
issue2.errors.map((issues) => processError({ issues }, [...path62, ...issue2.path]));
|
|
20156
20516
|
} else if (issue2.code === "invalid_key") {
|
|
20157
|
-
processError({ issues: issue2.issues }, [...
|
|
20517
|
+
processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
|
|
20158
20518
|
} else if (issue2.code === "invalid_element") {
|
|
20159
|
-
processError({ issues: issue2.issues }, [...
|
|
20519
|
+
processError({ issues: issue2.issues }, [...path62, ...issue2.path]);
|
|
20160
20520
|
} else {
|
|
20161
|
-
const fullpath = [...
|
|
20521
|
+
const fullpath = [...path62, ...issue2.path];
|
|
20162
20522
|
if (fullpath.length === 0) {
|
|
20163
20523
|
result.errors.push(mapper(issue2));
|
|
20164
20524
|
continue;
|
|
@@ -20190,8 +20550,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
20190
20550
|
}
|
|
20191
20551
|
function toDotPath(_path) {
|
|
20192
20552
|
const segs = [];
|
|
20193
|
-
const
|
|
20194
|
-
for (const seg of
|
|
20553
|
+
const path62 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
20554
|
+
for (const seg of path62) {
|
|
20195
20555
|
if (typeof seg === "number")
|
|
20196
20556
|
segs.push(`[${seg}]`);
|
|
20197
20557
|
else if (typeof seg === "symbol")
|
|
@@ -32883,13 +33243,13 @@ function resolveRef(ref, ctx) {
|
|
|
32883
33243
|
if (!ref.startsWith("#")) {
|
|
32884
33244
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
32885
33245
|
}
|
|
32886
|
-
const
|
|
32887
|
-
if (
|
|
33246
|
+
const path62 = ref.slice(1).split("/").filter(Boolean);
|
|
33247
|
+
if (path62.length === 0) {
|
|
32888
33248
|
return ctx.rootSchema;
|
|
32889
33249
|
}
|
|
32890
33250
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
32891
|
-
if (
|
|
32892
|
-
const key =
|
|
33251
|
+
if (path62[0] === defsKey) {
|
|
33252
|
+
const key = path62[1];
|
|
32893
33253
|
if (!key || !ctx.defs[key]) {
|
|
32894
33254
|
throw new Error(`Reference not found: ${ref}`);
|
|
32895
33255
|
}
|
|
@@ -39389,8 +39749,8 @@ var initSkill = defineSkill({
|
|
|
39389
39749
|
// ../mcp-server/src/lib/validated-tool.ts
|
|
39390
39750
|
function formatIssues(issues) {
|
|
39391
39751
|
return issues.map((issue2) => {
|
|
39392
|
-
const
|
|
39393
|
-
return `${
|
|
39752
|
+
const path62 = issue2.path.length > 0 ? issue2.path.join(".") : "<root>";
|
|
39753
|
+
return `${path62}: ${issue2.message}`;
|
|
39394
39754
|
}).join("; ");
|
|
39395
39755
|
}
|
|
39396
39756
|
function validatedTool(server, skill, name, handler) {
|
|
@@ -39599,7 +39959,7 @@ __export(auth_exports, {
|
|
|
39599
39959
|
init_paths();
|
|
39600
39960
|
import * as crypto from "node:crypto";
|
|
39601
39961
|
import * as fs3 from "node:fs";
|
|
39602
|
-
import * as
|
|
39962
|
+
import * as os from "node:os";
|
|
39603
39963
|
import * as path3 from "node:path";
|
|
39604
39964
|
var SECRET_ENV_VAR = "OLAM_AUTH_SECRET";
|
|
39605
39965
|
var SECRET_NAME = "auth-secret";
|
|
@@ -39741,8 +40101,8 @@ var AuthClient = class {
|
|
|
39741
40101
|
throw new Error(`failed to report rate-limit for ${accountId} (HTTP ${res.status})`);
|
|
39742
40102
|
}
|
|
39743
40103
|
}
|
|
39744
|
-
async request(method,
|
|
39745
|
-
const url3 = `${this.baseUrl}${
|
|
40104
|
+
async request(method, path62, body, attempt = 0) {
|
|
40105
|
+
const url3 = `${this.baseUrl}${path62}`;
|
|
39746
40106
|
const controller = new AbortController();
|
|
39747
40107
|
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
39748
40108
|
const headers = {};
|
|
@@ -39760,7 +40120,7 @@ var AuthClient = class {
|
|
|
39760
40120
|
} catch (err) {
|
|
39761
40121
|
if (attempt < RETRY_COUNT && isTransient(err)) {
|
|
39762
40122
|
await sleep(RETRY_BACKOFF_MS * (attempt + 1));
|
|
39763
|
-
return this.request(method,
|
|
40123
|
+
return this.request(method, path62, body, attempt + 1);
|
|
39764
40124
|
}
|
|
39765
40125
|
throw err;
|
|
39766
40126
|
} finally {
|
|
@@ -40182,7 +40542,7 @@ __export(pr_exports, {
|
|
|
40182
40542
|
// ../core/dist/world/registry.js
|
|
40183
40543
|
import { createRequire } from "node:module";
|
|
40184
40544
|
import * as net from "node:net";
|
|
40185
|
-
import * as
|
|
40545
|
+
import * as os2 from "node:os";
|
|
40186
40546
|
import * as path5 from "node:path";
|
|
40187
40547
|
import * as fs4 from "node:fs";
|
|
40188
40548
|
var _require = createRequire(import.meta.url);
|
|
@@ -40295,7 +40655,7 @@ CREATE TABLE IF NOT EXISTS meta (
|
|
|
40295
40655
|
var WorldRegistry = class {
|
|
40296
40656
|
db;
|
|
40297
40657
|
constructor(dbPath) {
|
|
40298
|
-
const resolvedPath = dbPath ?? path5.join(
|
|
40658
|
+
const resolvedPath = dbPath ?? path5.join(os2.homedir(), ".olam", "worlds.db");
|
|
40299
40659
|
if (resolvedPath !== ":memory:") {
|
|
40300
40660
|
fs4.mkdirSync(path5.dirname(resolvedPath), { recursive: true });
|
|
40301
40661
|
}
|
|
@@ -40759,12 +41119,12 @@ function register3(server, _ctx, _initError) {
|
|
|
40759
41119
|
registry2.close();
|
|
40760
41120
|
}
|
|
40761
41121
|
try {
|
|
40762
|
-
const { default:
|
|
40763
|
-
const { default:
|
|
40764
|
-
const { default:
|
|
40765
|
-
const tokenPath =
|
|
40766
|
-
if (
|
|
40767
|
-
const token =
|
|
41122
|
+
const { default: fs62 } = await import("node:fs");
|
|
41123
|
+
const { default: os32 } = await import("node:os");
|
|
41124
|
+
const { default: path62 } = await import("node:path");
|
|
41125
|
+
const tokenPath = path62.join(os32.homedir(), ".olam", "host-cp.token");
|
|
41126
|
+
if (fs62.existsSync(tokenPath)) {
|
|
41127
|
+
const token = fs62.readFileSync(tokenPath, "utf-8").trim();
|
|
40768
41128
|
await fetch("http://127.0.0.1:19000/api/admin/world-pr", {
|
|
40769
41129
|
method: "POST",
|
|
40770
41130
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
@@ -41013,7 +41373,7 @@ import { execFile } from "node:child_process";
|
|
|
41013
41373
|
import { promisify } from "node:util";
|
|
41014
41374
|
import { readFileSync as readFileSync5, existsSync as existsSync7, statSync } from "node:fs";
|
|
41015
41375
|
import { homedir as homedir5 } from "node:os";
|
|
41016
|
-
import { join as
|
|
41376
|
+
import { join as join9 } from "node:path";
|
|
41017
41377
|
var execFileP = promisify(execFile);
|
|
41018
41378
|
async function tarSkillsDir(skillsDir) {
|
|
41019
41379
|
if (!existsSync7(skillsDir) || !statSync(skillsDir).isDirectory()) {
|
|
@@ -41069,20 +41429,20 @@ function extractMcpConfig(claudeJsonPath) {
|
|
|
41069
41429
|
}
|
|
41070
41430
|
return { mcpServers, secrets };
|
|
41071
41431
|
}
|
|
41072
|
-
function readOptional(
|
|
41073
|
-
if (!existsSync7(
|
|
41432
|
+
function readOptional(path62) {
|
|
41433
|
+
if (!existsSync7(path62)) return null;
|
|
41074
41434
|
try {
|
|
41075
|
-
return readFileSync5(
|
|
41435
|
+
return readFileSync5(path62, "utf8");
|
|
41076
41436
|
} catch {
|
|
41077
41437
|
return null;
|
|
41078
41438
|
}
|
|
41079
41439
|
}
|
|
41080
41440
|
async function syncProfileToCloudflare(opts) {
|
|
41081
41441
|
const home = opts.homeDir ?? homedir5();
|
|
41082
|
-
const skillsDir =
|
|
41083
|
-
const claudeJsonPath =
|
|
41084
|
-
const claudeMdPath =
|
|
41085
|
-
const agentsMdPath =
|
|
41442
|
+
const skillsDir = join9(home, ".claude", "skills");
|
|
41443
|
+
const claudeJsonPath = join9(home, ".claude.json");
|
|
41444
|
+
const claudeMdPath = join9(home, ".claude", "CLAUDE.md");
|
|
41445
|
+
const agentsMdPath = join9(home, ".claude", "AGENTS.md");
|
|
41086
41446
|
const form = new FormData();
|
|
41087
41447
|
const skillsBuf = await tarSkillsDir(skillsDir);
|
|
41088
41448
|
if (skillsBuf) {
|
|
@@ -41306,10 +41666,10 @@ async function selectComputeProvider(config2, env) {
|
|
|
41306
41666
|
function createCloudflareProvider(CloudflareProviderClass, config2, env) {
|
|
41307
41667
|
const resolved = resolveCloudflareCallerConfig(config2, env);
|
|
41308
41668
|
warnOnWorkerPylonMismatch(resolved.workerUrl, resolved.pylonOrgUrl);
|
|
41309
|
-
const
|
|
41669
|
+
const mintToken3 = buildMintTokenForResolvedConfig(resolved);
|
|
41310
41670
|
return new CloudflareProviderClass({
|
|
41311
41671
|
workerUrl: resolved.workerUrl,
|
|
41312
|
-
mintToken:
|
|
41672
|
+
mintToken: mintToken3,
|
|
41313
41673
|
cfAccessClientId: resolved.cfAccessClientId,
|
|
41314
41674
|
cfAccessClientSecret: resolved.cfAccessClientSecret
|
|
41315
41675
|
});
|
|
@@ -41677,8 +42037,8 @@ function register5(server, ctx, initError) {
|
|
|
41677
42037
|
}
|
|
41678
42038
|
if (resolved) {
|
|
41679
42039
|
try {
|
|
41680
|
-
const
|
|
41681
|
-
const authToken = await
|
|
42040
|
+
const mintToken3 = createMintTokenForCtx(resolved);
|
|
42041
|
+
const authToken = await mintToken3();
|
|
41682
42042
|
await syncProfileToCloudflare({
|
|
41683
42043
|
workerUrl: resolved.workerUrl,
|
|
41684
42044
|
authToken,
|
|
@@ -42234,7 +42594,7 @@ var ThoughtLocalStore = class {
|
|
|
42234
42594
|
// ../core/dist/world/env-setup.js
|
|
42235
42595
|
import * as crypto2 from "node:crypto";
|
|
42236
42596
|
import * as fs10 from "node:fs";
|
|
42237
|
-
import * as
|
|
42597
|
+
import * as os7 from "node:os";
|
|
42238
42598
|
import * as path12 from "node:path";
|
|
42239
42599
|
import { globSync } from "node:fs";
|
|
42240
42600
|
|
|
@@ -42324,7 +42684,7 @@ function generateHooksConfig(hookServerUrl = DEFAULT_HOOK_SERVER_URL) {
|
|
|
42324
42684
|
// ../core/dist/world/env-setup.js
|
|
42325
42685
|
var DEFAULT_CLAUDE_MODEL = "claude-opus-4-7";
|
|
42326
42686
|
function copyClaudeConfig(workspacePath, homeDir, configCtx) {
|
|
42327
|
-
const sourceClaudeDir = path12.join(homeDir ??
|
|
42687
|
+
const sourceClaudeDir = path12.join(homeDir ?? os7.homedir(), ".claude");
|
|
42328
42688
|
const destClaudeDir = path12.join(workspacePath, ".claude-host-config");
|
|
42329
42689
|
void configCtx;
|
|
42330
42690
|
if (!fs10.existsSync(sourceClaudeDir))
|
|
@@ -42370,7 +42730,7 @@ function copyClaudeConfig(workspacePath, homeDir, configCtx) {
|
|
|
42370
42730
|
copyDirRecursive(scriptsDir, path12.join(destClaudeDir, "scripts"));
|
|
42371
42731
|
}
|
|
42372
42732
|
applyProjectClaudeOverlay(workspacePath, destClaudeDir);
|
|
42373
|
-
writeStrippedMcpServersSnapshot(homeDir ??
|
|
42733
|
+
writeStrippedMcpServersSnapshot(homeDir ?? os7.homedir(), workspacePath, destClaudeDir);
|
|
42374
42734
|
}
|
|
42375
42735
|
function applyProjectClaudeOverlay(workspacePath, destClaudeDir) {
|
|
42376
42736
|
const projectClaudeDir = path12.join(workspacePath, ".claude");
|
|
@@ -44203,12 +44563,12 @@ __export(capture_view_exports, {
|
|
|
44203
44563
|
});
|
|
44204
44564
|
init_v3();
|
|
44205
44565
|
import { mkdir } from "node:fs/promises";
|
|
44206
|
-
import { join as
|
|
44566
|
+
import { join as join16, resolve as resolvePath } from "node:path";
|
|
44207
44567
|
|
|
44208
44568
|
// ../mcp-server/src/tools/_capture/manifest.ts
|
|
44209
44569
|
import { createHash as createHash3 } from "node:crypto";
|
|
44210
44570
|
import { readFile, writeFile } from "node:fs/promises";
|
|
44211
|
-
import { basename as basename2, join as
|
|
44571
|
+
import { basename as basename2, join as join15 } from "node:path";
|
|
44212
44572
|
function redactUrl(url3) {
|
|
44213
44573
|
if (url3.startsWith("world://")) return url3;
|
|
44214
44574
|
let parsed;
|
|
@@ -44251,10 +44611,10 @@ async function writeManifest(args) {
|
|
|
44251
44611
|
capturedAt: args.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
44252
44612
|
shots: entries
|
|
44253
44613
|
};
|
|
44254
|
-
const
|
|
44255
|
-
await writeFile(
|
|
44614
|
+
const path62 = join15(args.outDir, "manifest.json");
|
|
44615
|
+
await writeFile(path62, `${JSON.stringify(manifest, null, 2)}
|
|
44256
44616
|
`, "utf8");
|
|
44257
|
-
return { path:
|
|
44617
|
+
return { path: path62, manifest };
|
|
44258
44618
|
}
|
|
44259
44619
|
|
|
44260
44620
|
// ../mcp-server/src/tools/_capture/proxy.ts
|
|
@@ -44508,9 +44868,9 @@ async function startProxy(opts) {
|
|
|
44508
44868
|
const liveCompiled = verified.allowedPaths.map(compileGlob);
|
|
44509
44869
|
const target = parseRequestTarget(req);
|
|
44510
44870
|
if (!target) return httpReject(400, "invalid_target");
|
|
44511
|
-
const
|
|
44512
|
-
if (!liveCompiled.some((re) => re.test(
|
|
44513
|
-
return httpReject(403, "outside_allow_list", { path:
|
|
44871
|
+
const path62 = target.pathname;
|
|
44872
|
+
if (!liveCompiled.some((re) => re.test(path62))) {
|
|
44873
|
+
return httpReject(403, "outside_allow_list", { path: path62 });
|
|
44514
44874
|
}
|
|
44515
44875
|
const headerWorld = req.headers[WORLD_ASSERT_HEADER];
|
|
44516
44876
|
const headerWorldStr = typeof headerWorld === "string" ? headerWorld : Array.isArray(headerWorld) && headerWorld.length > 0 ? headerWorld[0] : void 0;
|
|
@@ -45049,7 +45409,7 @@ function releaseLaunchSlot() {
|
|
|
45049
45409
|
function resolveShootsRoot() {
|
|
45050
45410
|
const fromEnv = process.env.OLAM_SHOOTS_ROOT;
|
|
45051
45411
|
if (fromEnv && fromEnv.length > 0) return resolvePath(fromEnv);
|
|
45052
|
-
return resolvePath(
|
|
45412
|
+
return resolvePath(join16(process.cwd(), ".olam", "shoots"));
|
|
45053
45413
|
}
|
|
45054
45414
|
function isUnderRoot(absPath, root) {
|
|
45055
45415
|
if (absPath === root) return true;
|
|
@@ -45350,14 +45710,14 @@ async function runShot(browser, shot, outDir, format, jpegQuality, allowEval, as
|
|
|
45350
45710
|
await page.waitForTimeout(shot.afterLoadMs);
|
|
45351
45711
|
}
|
|
45352
45712
|
const ext = format === "jpeg" ? "jpg" : "png";
|
|
45353
|
-
const
|
|
45713
|
+
const path62 = join16(outDir, `${shot.name}.${ext}`);
|
|
45354
45714
|
await page.screenshot({
|
|
45355
|
-
path:
|
|
45715
|
+
path: path62,
|
|
45356
45716
|
type: format,
|
|
45357
45717
|
...format === "jpeg" ? { quality: jpegQuality } : {},
|
|
45358
45718
|
fullPage: false
|
|
45359
45719
|
});
|
|
45360
|
-
return { name: shot.name, path:
|
|
45720
|
+
return { name: shot.name, path: path62, urlRedacted: redactUrl(shot.url), viewport };
|
|
45361
45721
|
} finally {
|
|
45362
45722
|
await context.close();
|
|
45363
45723
|
}
|
|
@@ -45664,17 +46024,17 @@ var webTaskShape = external_exports2.object(webTaskInput);
|
|
|
45664
46024
|
import { spawn as spawn3 } from "node:child_process";
|
|
45665
46025
|
import { existsSync as existsSync14 } from "node:fs";
|
|
45666
46026
|
import { homedir as homedir9 } from "node:os";
|
|
45667
|
-
import { join as
|
|
46027
|
+
import { join as join17 } from "node:path";
|
|
45668
46028
|
var WEBWRIGHT_SETUP_COMMAND = "olam webwright setup";
|
|
45669
46029
|
function resolveVenvPath(cfg) {
|
|
45670
46030
|
if (cfg?.venvPath && cfg.venvPath.length > 0) return cfg.venvPath;
|
|
45671
|
-
return
|
|
46031
|
+
return join17(homedir9(), ".olam", "venvs", "webwright");
|
|
45672
46032
|
}
|
|
45673
46033
|
function resolveConfigDir(cfg) {
|
|
45674
46034
|
if (cfg?.configDir && cfg.configDir.length > 0) {
|
|
45675
46035
|
return existsSync14(cfg.configDir) ? cfg.configDir : null;
|
|
45676
46036
|
}
|
|
45677
|
-
const candidate =
|
|
46037
|
+
const candidate = join17(
|
|
45678
46038
|
homedir9(),
|
|
45679
46039
|
".claude",
|
|
45680
46040
|
"plugins",
|
|
@@ -45692,9 +46052,9 @@ function isWebwrightEnabled(cfg) {
|
|
|
45692
46052
|
return cfg?.enabled === true;
|
|
45693
46053
|
}
|
|
45694
46054
|
function venvPython(venvPath) {
|
|
45695
|
-
const posix =
|
|
46055
|
+
const posix = join17(venvPath, "bin", "python");
|
|
45696
46056
|
if (existsSync14(posix)) return posix;
|
|
45697
|
-
const win =
|
|
46057
|
+
const win = join17(venvPath, "Scripts", "python.exe");
|
|
45698
46058
|
if (existsSync14(win)) return win;
|
|
45699
46059
|
return null;
|
|
45700
46060
|
}
|
|
@@ -45780,18 +46140,18 @@ import { spawn as spawn4 } from "node:child_process";
|
|
|
45780
46140
|
import { mkdir as mkdir2, mkdtemp, readFile as readFile3, readdir, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
45781
46141
|
import { existsSync as existsSync15 } from "node:fs";
|
|
45782
46142
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
45783
|
-
import { join as
|
|
46143
|
+
import { join as join19, resolve as resolvePath2 } from "node:path";
|
|
45784
46144
|
|
|
45785
46145
|
// ../mcp-server/src/tools/_web_task/model-config.ts
|
|
45786
46146
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
45787
46147
|
import { homedir as homedir10 } from "node:os";
|
|
45788
|
-
import { join as
|
|
46148
|
+
import { join as join18 } from "node:path";
|
|
45789
46149
|
var PLACEHOLDER_ANTHROPIC_API_KEY = "olam-vault-routed-placeholder-stripped-by-proxy";
|
|
45790
46150
|
var DEFAULT_WEB_TASK_MODEL = "claude-opus-4-7";
|
|
45791
46151
|
var AnthropicBaseUrlMissingError = class extends Error {
|
|
45792
|
-
constructor(
|
|
46152
|
+
constructor(path62, cause) {
|
|
45793
46153
|
super(
|
|
45794
|
-
`vault base URL is not resolvable from "${
|
|
46154
|
+
`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.`
|
|
45795
46155
|
);
|
|
45796
46156
|
this.name = "AnthropicBaseUrlMissingError";
|
|
45797
46157
|
}
|
|
@@ -45800,7 +46160,7 @@ async function resolveVaultBaseUrl(opts = {}) {
|
|
|
45800
46160
|
const env = opts.env ?? process.env;
|
|
45801
46161
|
const fromEnv = env.OLAM_ANTHROPIC_BASE_URL;
|
|
45802
46162
|
if (fromEnv && fromEnv.trim().length > 0) return fromEnv.trim();
|
|
45803
|
-
const file2 = opts.baseUrlFile ??
|
|
46163
|
+
const file2 = opts.baseUrlFile ?? join18(homedir10(), ".olam", "anthropic-base-url");
|
|
45804
46164
|
let raw;
|
|
45805
46165
|
try {
|
|
45806
46166
|
raw = await readFile2(file2, "utf-8");
|
|
@@ -45850,7 +46210,7 @@ var WebTaskSpawnError = class extends Error {
|
|
|
45850
46210
|
function resolveWebTaskRoot() {
|
|
45851
46211
|
const fromEnv = process.env.OLAM_WEB_TASK_ROOT;
|
|
45852
46212
|
if (fromEnv && fromEnv.length > 0) return resolvePath2(fromEnv);
|
|
45853
|
-
return resolvePath2(
|
|
46213
|
+
return resolvePath2(join19(process.cwd(), ".olam", "web-tasks"));
|
|
45854
46214
|
}
|
|
45855
46215
|
function isUnderRoot2(absPath, root) {
|
|
45856
46216
|
if (absPath === root) return true;
|
|
@@ -45913,7 +46273,7 @@ async function runWebwright(pythonPath, args, spawnEnv, timeoutMs, deps) {
|
|
|
45913
46273
|
});
|
|
45914
46274
|
}
|
|
45915
46275
|
async function locateRunDir(outDir) {
|
|
45916
|
-
if (existsSync15(
|
|
46276
|
+
if (existsSync15(join19(outDir, "trajectory.json"))) return outDir;
|
|
45917
46277
|
let entries = [];
|
|
45918
46278
|
try {
|
|
45919
46279
|
entries = await readdir(outDir);
|
|
@@ -45922,8 +46282,8 @@ async function locateRunDir(outDir) {
|
|
|
45922
46282
|
}
|
|
45923
46283
|
const candidates = [];
|
|
45924
46284
|
for (const name of entries) {
|
|
45925
|
-
const sub =
|
|
45926
|
-
if (existsSync15(
|
|
46285
|
+
const sub = join19(outDir, name);
|
|
46286
|
+
if (existsSync15(join19(sub, "trajectory.json"))) candidates.push({ dir: sub });
|
|
45927
46287
|
}
|
|
45928
46288
|
if (candidates.length === 0) return outDir;
|
|
45929
46289
|
candidates.sort((a, b) => a.dir < b.dir ? 1 : -1);
|
|
@@ -45936,14 +46296,14 @@ async function collectScreenshots(runDir) {
|
|
|
45936
46296
|
} catch {
|
|
45937
46297
|
return [];
|
|
45938
46298
|
}
|
|
45939
|
-
const shots = entries.filter((n) => /\.(png|jpe?g)$/i.test(n)).sort().map((n, i) => ({ step: i, path:
|
|
46299
|
+
const shots = entries.filter((n) => /\.(png|jpe?g)$/i.test(n)).sort().map((n, i) => ({ step: i, path: join19(runDir, n) }));
|
|
45940
46300
|
return shots;
|
|
45941
46301
|
}
|
|
45942
46302
|
async function readTrajectoryFacts(runDir, stdoutTail) {
|
|
45943
46303
|
let answer = null;
|
|
45944
46304
|
let modelCalls = null;
|
|
45945
46305
|
try {
|
|
45946
|
-
const raw = await readFile3(
|
|
46306
|
+
const raw = await readFile3(join19(runDir, "trajectory.json"), "utf-8");
|
|
45947
46307
|
const parsed = JSON.parse(raw);
|
|
45948
46308
|
answer = extractFinalAnswer(parsed);
|
|
45949
46309
|
modelCalls = extractModelCalls(parsed);
|
|
@@ -46076,11 +46436,11 @@ async function runSpawnExecutor(spec, ctx, provision, deps = { spawn: spawn4 })
|
|
|
46076
46436
|
} catch (err) {
|
|
46077
46437
|
throw new WebTaskSpawnError("vault_base_url_missing", err.message);
|
|
46078
46438
|
}
|
|
46079
|
-
const tmpDirRoot = await mkdtemp(
|
|
46080
|
-
const modelYamlPath =
|
|
46439
|
+
const tmpDirRoot = await mkdtemp(join19(tmpdir2(), "olam-web-task-"));
|
|
46440
|
+
const modelYamlPath = join19(tmpDirRoot, "model_olam.yaml");
|
|
46081
46441
|
await writeFile2(modelYamlPath, modelYaml.yaml, "utf-8");
|
|
46082
46442
|
try {
|
|
46083
|
-
const baseYaml =
|
|
46443
|
+
const baseYaml = join19(provision.configDir, "base.yaml");
|
|
46084
46444
|
const args = [
|
|
46085
46445
|
"-m",
|
|
46086
46446
|
"webwright.run.cli",
|
|
@@ -46134,10 +46494,10 @@ ${tail}` : ""}`
|
|
|
46134
46494
|
);
|
|
46135
46495
|
}
|
|
46136
46496
|
const runDir = await locateRunDir(absOutDir);
|
|
46137
|
-
const trajectoryPath =
|
|
46497
|
+
const trajectoryPath = join19(runDir, "trajectory.json");
|
|
46138
46498
|
const screenshots = await collectScreenshots(runDir);
|
|
46139
46499
|
const facts = await readTrajectoryFacts(runDir, outcome.stdout);
|
|
46140
|
-
const scriptPath = existsSync15(
|
|
46500
|
+
const scriptPath = existsSync15(join19(runDir, "final_script.py")) ? join19(runDir, "final_script.py") : void 0;
|
|
46141
46501
|
return {
|
|
46142
46502
|
result: facts.answer,
|
|
46143
46503
|
trajectoryPath,
|
|
@@ -46690,12 +47050,12 @@ function openUrl(url3) {
|
|
|
46690
47050
|
var HOST_CP_URL = "http://127.0.0.1:19000";
|
|
46691
47051
|
async function readHostCpToken2() {
|
|
46692
47052
|
try {
|
|
46693
|
-
const { default:
|
|
46694
|
-
const { default:
|
|
46695
|
-
const { default:
|
|
46696
|
-
const tp =
|
|
46697
|
-
if (!
|
|
46698
|
-
return { token:
|
|
47053
|
+
const { default: fs62 } = await import("node:fs");
|
|
47054
|
+
const { default: os32 } = await import("node:os");
|
|
47055
|
+
const { default: path62 } = await import("node:path");
|
|
47056
|
+
const tp = path62.join(os32.homedir(), ".olam", "host-cp.token");
|
|
47057
|
+
if (!fs62.existsSync(tp)) return { token: null };
|
|
47058
|
+
return { token: fs62.readFileSync(tp, "utf-8").trim() };
|
|
46699
47059
|
} catch {
|
|
46700
47060
|
return { token: null };
|
|
46701
47061
|
}
|
|
@@ -46989,9 +47349,9 @@ function register22(server, _ctx, _initError) {
|
|
|
46989
47349
|
}]
|
|
46990
47350
|
};
|
|
46991
47351
|
});
|
|
46992
|
-
validatedTool(server, repoAddSkill, "olam_repo_add", async ({ name, path:
|
|
47352
|
+
validatedTool(server, repoAddSkill, "olam_repo_add", async ({ name, path: path62, description, defaultBranch }) => {
|
|
46993
47353
|
try {
|
|
46994
|
-
const entry = addRepo({ name, path:
|
|
47354
|
+
const entry = addRepo({ name, path: path62, description, defaultBranch });
|
|
46995
47355
|
return {
|
|
46996
47356
|
content: [{
|
|
46997
47357
|
type: "text",
|
|
@@ -47027,9 +47387,9 @@ function register22(server, _ctx, _initError) {
|
|
|
47027
47387
|
};
|
|
47028
47388
|
}
|
|
47029
47389
|
});
|
|
47030
|
-
validatedTool(server, repoUpdateSkill, "olam_repo_update", async ({ name, path:
|
|
47390
|
+
validatedTool(server, repoUpdateSkill, "olam_repo_update", async ({ name, path: path62, description, defaultBranch }) => {
|
|
47031
47391
|
try {
|
|
47032
|
-
const entry = updateRepo(name, { path:
|
|
47392
|
+
const entry = updateRepo(name, { path: path62, description, defaultBranch });
|
|
47033
47393
|
return {
|
|
47034
47394
|
content: [{
|
|
47035
47395
|
type: "text",
|
|
@@ -47054,9 +47414,9 @@ __export(process_port_exports, {
|
|
|
47054
47414
|
register: () => register23,
|
|
47055
47415
|
resolveHostCpToken: () => resolveHostCpToken
|
|
47056
47416
|
});
|
|
47057
|
-
import
|
|
47058
|
-
import
|
|
47059
|
-
import
|
|
47417
|
+
import fs41 from "node:fs";
|
|
47418
|
+
import os18 from "node:os";
|
|
47419
|
+
import path39 from "node:path";
|
|
47060
47420
|
|
|
47061
47421
|
// ../skill-runtime/dist/skills/process-list.js
|
|
47062
47422
|
init_v3();
|
|
@@ -47101,8 +47461,8 @@ var HOST_CP_BASE = "http://127.0.0.1:19000";
|
|
|
47101
47461
|
function resolveHostCpToken() {
|
|
47102
47462
|
const envToken = process.env["OLAM_HOST_CP_TOKEN"];
|
|
47103
47463
|
if (envToken) return envToken;
|
|
47104
|
-
const tokenPath =
|
|
47105
|
-
if (
|
|
47464
|
+
const tokenPath = path39.join(os18.homedir(), ".olam", "host-cp.token");
|
|
47465
|
+
if (fs41.existsSync(tokenPath)) return fs41.readFileSync(tokenPath, "utf-8").trim();
|
|
47106
47466
|
return null;
|
|
47107
47467
|
}
|
|
47108
47468
|
function tokenMissingError() {
|
|
@@ -47625,8 +47985,8 @@ __export(skills_exports, {
|
|
|
47625
47985
|
register: () => register26
|
|
47626
47986
|
});
|
|
47627
47987
|
init_skill_sources();
|
|
47628
|
-
import * as
|
|
47629
|
-
import * as
|
|
47988
|
+
import * as fs42 from "node:fs";
|
|
47989
|
+
import * as path40 from "node:path";
|
|
47630
47990
|
|
|
47631
47991
|
// ../skill-runtime/dist/skills/skills-sync.js
|
|
47632
47992
|
init_v3();
|
|
@@ -47700,21 +48060,21 @@ function fail2(err, hint) {
|
|
|
47700
48060
|
};
|
|
47701
48061
|
}
|
|
47702
48062
|
function listDeployed() {
|
|
47703
|
-
const dir =
|
|
48063
|
+
const dir = claudeDir2();
|
|
47704
48064
|
const sources = listSkillSources();
|
|
47705
48065
|
const sourcePaths = new Map(
|
|
47706
48066
|
sources.map((s) => [skillSourceClonePath(s.id), s.id])
|
|
47707
48067
|
);
|
|
47708
48068
|
const entries = [];
|
|
47709
48069
|
for (const bucket of ["skills", "agents", "scripts", "rules", "commands"]) {
|
|
47710
|
-
const bucketDir =
|
|
47711
|
-
if (!
|
|
47712
|
-
for (const name of
|
|
47713
|
-
const full =
|
|
48070
|
+
const bucketDir = path40.join(dir, bucket);
|
|
48071
|
+
if (!fs42.existsSync(bucketDir)) continue;
|
|
48072
|
+
for (const name of fs42.readdirSync(bucketDir)) {
|
|
48073
|
+
const full = path40.join(bucketDir, name);
|
|
47714
48074
|
try {
|
|
47715
|
-
const stat2 =
|
|
48075
|
+
const stat2 = fs42.lstatSync(full);
|
|
47716
48076
|
if (!stat2.isSymbolicLink()) continue;
|
|
47717
|
-
const target =
|
|
48077
|
+
const target = fs42.readlinkSync(full);
|
|
47718
48078
|
let sourceId;
|
|
47719
48079
|
for (const [clonePath, id] of sourcePaths.entries()) {
|
|
47720
48080
|
if (target.startsWith(clonePath)) {
|
|
@@ -47802,15 +48162,15 @@ function deriveModeId(name, taken) {
|
|
|
47802
48162
|
|
|
47803
48163
|
// ../core/dist/ree-modes/store.js
|
|
47804
48164
|
init_skill_sources();
|
|
47805
|
-
import * as
|
|
47806
|
-
import * as
|
|
47807
|
-
import * as
|
|
48165
|
+
import * as fs44 from "node:fs";
|
|
48166
|
+
import * as os20 from "node:os";
|
|
48167
|
+
import * as path42 from "node:path";
|
|
47808
48168
|
|
|
47809
48169
|
// ../core/dist/ree-modes/registry.js
|
|
47810
48170
|
init_v3();
|
|
47811
|
-
import * as
|
|
47812
|
-
import * as
|
|
47813
|
-
import * as
|
|
48171
|
+
import * as fs43 from "node:fs";
|
|
48172
|
+
import * as os19 from "node:os";
|
|
48173
|
+
import * as path41 from "node:path";
|
|
47814
48174
|
var CadenceStatusSchema = external_exports2.enum(["running", "stopped"]);
|
|
47815
48175
|
var CadenceEntrySchema = external_exports2.object({
|
|
47816
48176
|
/** Unique cadence id (modeId + short timestamp). */
|
|
@@ -47832,18 +48192,18 @@ function olamRootDir() {
|
|
|
47832
48192
|
const override = process.env["OLAM_STATE_DIR"];
|
|
47833
48193
|
if (override && override.length > 0)
|
|
47834
48194
|
return override;
|
|
47835
|
-
return
|
|
48195
|
+
return path41.join(os19.homedir(), ".olam");
|
|
47836
48196
|
}
|
|
47837
48197
|
function cadenceRegistryPath() {
|
|
47838
|
-
return
|
|
48198
|
+
return path41.join(olamRootDir(), "ree-cadences.json");
|
|
47839
48199
|
}
|
|
47840
48200
|
function readCadenceRegistry() {
|
|
47841
48201
|
const file2 = cadenceRegistryPath();
|
|
47842
|
-
if (!
|
|
48202
|
+
if (!fs43.existsSync(file2))
|
|
47843
48203
|
return { cadences: [] };
|
|
47844
48204
|
let raw;
|
|
47845
48205
|
try {
|
|
47846
|
-
raw = JSON.parse(
|
|
48206
|
+
raw = JSON.parse(fs43.readFileSync(file2, "utf-8"));
|
|
47847
48207
|
} catch {
|
|
47848
48208
|
return { cadences: [] };
|
|
47849
48209
|
}
|
|
@@ -47852,10 +48212,10 @@ function readCadenceRegistry() {
|
|
|
47852
48212
|
}
|
|
47853
48213
|
function writeCadenceRegistry(registry2) {
|
|
47854
48214
|
const file2 = cadenceRegistryPath();
|
|
47855
|
-
|
|
48215
|
+
fs43.mkdirSync(path41.dirname(file2), { recursive: true });
|
|
47856
48216
|
const tmp = `${file2}.tmp-${process.pid}`;
|
|
47857
|
-
|
|
47858
|
-
|
|
48217
|
+
fs43.writeFileSync(tmp, JSON.stringify(registry2, null, 2) + "\n", "utf-8");
|
|
48218
|
+
fs43.renameSync(tmp, file2);
|
|
47859
48219
|
}
|
|
47860
48220
|
function startCadence(input) {
|
|
47861
48221
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -47899,18 +48259,18 @@ function claudeRootDir() {
|
|
|
47899
48259
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
47900
48260
|
if (override && override.length > 0)
|
|
47901
48261
|
return override;
|
|
47902
|
-
return
|
|
48262
|
+
return path42.join(os20.homedir(), ".claude");
|
|
47903
48263
|
}
|
|
47904
48264
|
function localModesDir() {
|
|
47905
|
-
return
|
|
48265
|
+
return path42.join(claudeRootDir(), "ree-modes.local");
|
|
47906
48266
|
}
|
|
47907
48267
|
var SOURCE_CATALOG_RELATIVE_PATH = "shared/engineering/skills/ree-cadence/references/modes.md";
|
|
47908
48268
|
function findSourceCatalogPath(opts) {
|
|
47909
48269
|
if (opts && "_testCatalogPath" in opts)
|
|
47910
48270
|
return opts._testCatalogPath ?? null;
|
|
47911
48271
|
for (const source of listSkillSources()) {
|
|
47912
|
-
const candidate =
|
|
47913
|
-
if (
|
|
48272
|
+
const candidate = path42.join(skillSourceClonePath(source.id), SOURCE_CATALOG_RELATIVE_PATH);
|
|
48273
|
+
if (fs44.existsSync(candidate))
|
|
47914
48274
|
return candidate;
|
|
47915
48275
|
}
|
|
47916
48276
|
return null;
|
|
@@ -47960,16 +48320,16 @@ function parseModeCatalog(content, origin) {
|
|
|
47960
48320
|
}
|
|
47961
48321
|
function loadLocalModes() {
|
|
47962
48322
|
const dir = localModesDir();
|
|
47963
|
-
if (!
|
|
48323
|
+
if (!fs44.existsSync(dir))
|
|
47964
48324
|
return [];
|
|
47965
48325
|
const out = [];
|
|
47966
|
-
for (const entry of
|
|
48326
|
+
for (const entry of fs44.readdirSync(dir).sort()) {
|
|
47967
48327
|
if (!entry.endsWith(".md"))
|
|
47968
48328
|
continue;
|
|
47969
|
-
const full =
|
|
48329
|
+
const full = path42.join(dir, entry);
|
|
47970
48330
|
let content;
|
|
47971
48331
|
try {
|
|
47972
|
-
content =
|
|
48332
|
+
content = fs44.readFileSync(full, "utf-8");
|
|
47973
48333
|
} catch {
|
|
47974
48334
|
continue;
|
|
47975
48335
|
}
|
|
@@ -47985,7 +48345,7 @@ function loadSourceModes(opts) {
|
|
|
47985
48345
|
return [];
|
|
47986
48346
|
let content;
|
|
47987
48347
|
try {
|
|
47988
|
-
content =
|
|
48348
|
+
content = fs44.readFileSync(catalogPath, "utf-8");
|
|
47989
48349
|
} catch {
|
|
47990
48350
|
return [];
|
|
47991
48351
|
}
|
|
@@ -48052,12 +48412,12 @@ function createLocalMode(input) {
|
|
|
48052
48412
|
id = deriveModeId(name, taken);
|
|
48053
48413
|
}
|
|
48054
48414
|
const dir = localModesDir();
|
|
48055
|
-
|
|
48056
|
-
const file2 =
|
|
48057
|
-
if (
|
|
48415
|
+
fs44.mkdirSync(dir, { recursive: true });
|
|
48416
|
+
const file2 = path42.join(dir, `${id}.md`);
|
|
48417
|
+
if (fs44.existsSync(file2)) {
|
|
48058
48418
|
throw new Error(`local mode file already exists: ${file2}`);
|
|
48059
48419
|
}
|
|
48060
|
-
|
|
48420
|
+
fs44.writeFileSync(file2, scaffoldModeBlock({ id, name, instruction }), "utf-8");
|
|
48061
48421
|
return { id, name, origin: "local", path: file2 };
|
|
48062
48422
|
}
|
|
48063
48423
|
function renameLocalMode(oldId, newId) {
|
|
@@ -48068,8 +48428,8 @@ function renameLocalMode(oldId, newId) {
|
|
|
48068
48428
|
throw new Error(`invalid new id "${newId}" \u2014 must match ${MODE_ID_RE}.`);
|
|
48069
48429
|
}
|
|
48070
48430
|
const dir = localModesDir();
|
|
48071
|
-
const oldFile =
|
|
48072
|
-
if (!
|
|
48431
|
+
const oldFile = path42.join(dir, `${oldId}.md`);
|
|
48432
|
+
if (!fs44.existsSync(oldFile)) {
|
|
48073
48433
|
const isSource = loadSourceModes().some((m) => m.id === oldId);
|
|
48074
48434
|
if (isSource) {
|
|
48075
48435
|
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.`);
|
|
@@ -48079,11 +48439,11 @@ function renameLocalMode(oldId, newId) {
|
|
|
48079
48439
|
if (takenModeIds().has(newId)) {
|
|
48080
48440
|
throw new Error(`target id "${newId}" already exists (source or local).`);
|
|
48081
48441
|
}
|
|
48082
|
-
const content =
|
|
48442
|
+
const content = fs44.readFileSync(oldFile, "utf-8");
|
|
48083
48443
|
const rewritten = content.replace(new RegExp(`^## ${escapeRegex2(oldId)} \u2014 `, "m"), `## ${newId} \u2014 `);
|
|
48084
|
-
const newFile =
|
|
48085
|
-
|
|
48086
|
-
|
|
48444
|
+
const newFile = path42.join(dir, `${newId}.md`);
|
|
48445
|
+
fs44.writeFileSync(newFile, rewritten, "utf-8");
|
|
48446
|
+
fs44.rmSync(oldFile);
|
|
48087
48447
|
const danglingCadences = listCadences({ runningOnly: true }).filter((c) => c.modeId === oldId).map((c) => c.id);
|
|
48088
48448
|
return { from: oldId, to: newId, origin: "local", path: newFile, danglingCadences };
|
|
48089
48449
|
}
|
|
@@ -48103,8 +48463,8 @@ function deriveNameFromInstruction(instruction) {
|
|
|
48103
48463
|
}
|
|
48104
48464
|
|
|
48105
48465
|
// ../core/dist/ree-modes/promote.js
|
|
48106
|
-
import * as
|
|
48107
|
-
import * as
|
|
48466
|
+
import * as fs45 from "node:fs";
|
|
48467
|
+
import * as path43 from "node:path";
|
|
48108
48468
|
|
|
48109
48469
|
// ../core/dist/ree-modes/disambiguation.js
|
|
48110
48470
|
var PICKER_THRESHOLD = 4;
|
|
@@ -48279,14 +48639,14 @@ var skills_search_exports = {};
|
|
|
48279
48639
|
__export(skills_search_exports, {
|
|
48280
48640
|
register: () => register28
|
|
48281
48641
|
});
|
|
48282
|
-
import * as
|
|
48283
|
-
import * as
|
|
48642
|
+
import * as path45 from "node:path";
|
|
48643
|
+
import * as os22 from "node:os";
|
|
48284
48644
|
|
|
48285
48645
|
// ../mcp-server/src/lib/skills-index.mjs
|
|
48286
48646
|
import { createRequire as createRequire5 } from "node:module";
|
|
48287
|
-
import * as
|
|
48288
|
-
import * as
|
|
48289
|
-
import * as
|
|
48647
|
+
import * as fs46 from "node:fs";
|
|
48648
|
+
import * as path44 from "node:path";
|
|
48649
|
+
import * as os21 from "node:os";
|
|
48290
48650
|
var VECTOR_DIM = 256;
|
|
48291
48651
|
var SCHEMA_VERSION3 = "1";
|
|
48292
48652
|
var SCHEMA_KEY = "skills_index_schema_version";
|
|
@@ -48375,7 +48735,7 @@ function bufferToVector(buf) {
|
|
|
48375
48735
|
return vec;
|
|
48376
48736
|
}
|
|
48377
48737
|
function openIndex(dbPath) {
|
|
48378
|
-
if (!
|
|
48738
|
+
if (!fs46.existsSync(dbPath)) {
|
|
48379
48739
|
throw new Error(
|
|
48380
48740
|
`skills index not found at ${dbPath}. Run \`node scripts/skills-index-build.mjs --out ${dbPath}\` first.`
|
|
48381
48741
|
);
|
|
@@ -48417,8 +48777,8 @@ function searchIndex(dbPath, query, k = 5) {
|
|
|
48417
48777
|
db.close();
|
|
48418
48778
|
}
|
|
48419
48779
|
}
|
|
48420
|
-
var DEFAULT_DB_PATH =
|
|
48421
|
-
var DEFAULT_SOURCE_DIR =
|
|
48780
|
+
var DEFAULT_DB_PATH = path44.join(os21.homedir(), ".olam", "skills.vec.db");
|
|
48781
|
+
var DEFAULT_SOURCE_DIR = path44.join(os21.homedir(), ".claude", "skills");
|
|
48422
48782
|
|
|
48423
48783
|
// ../skill-runtime/dist/skills/skills-search.js
|
|
48424
48784
|
init_v3();
|
|
@@ -48437,7 +48797,7 @@ var skillsSearchSkill = defineSkill({
|
|
|
48437
48797
|
function defaultDbPath() {
|
|
48438
48798
|
const override = process.env["SKILLS_INDEX_PATH"];
|
|
48439
48799
|
if (override) return override;
|
|
48440
|
-
return
|
|
48800
|
+
return path45.join(os22.homedir(), ".olam", "skills.vec.db");
|
|
48441
48801
|
}
|
|
48442
48802
|
function asMessage10(err) {
|
|
48443
48803
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -48481,8 +48841,8 @@ function port() {
|
|
|
48481
48841
|
const n = Number.parseInt(env, 10);
|
|
48482
48842
|
return Number.isFinite(n) && n > 0 ? n : KG_SERVICE_PORT_DEFAULT;
|
|
48483
48843
|
}
|
|
48484
|
-
function url2(
|
|
48485
|
-
return `http://127.0.0.1:${port()}${
|
|
48844
|
+
function url2(path62) {
|
|
48845
|
+
return `http://127.0.0.1:${port()}${path62}`;
|
|
48486
48846
|
}
|
|
48487
48847
|
function kgServiceHealthUrl() {
|
|
48488
48848
|
return url2("/health");
|
|
@@ -48711,9 +49071,9 @@ __export(kg_install_hook_exports, {
|
|
|
48711
49071
|
register: () => register31
|
|
48712
49072
|
});
|
|
48713
49073
|
init_merge_settings();
|
|
48714
|
-
import * as
|
|
48715
|
-
import * as
|
|
48716
|
-
import * as
|
|
49074
|
+
import * as fs47 from "node:fs";
|
|
49075
|
+
import * as path46 from "node:path";
|
|
49076
|
+
import * as os23 from "node:os";
|
|
48717
49077
|
|
|
48718
49078
|
// ../core/dist/kg/hook-template.js
|
|
48719
49079
|
var KG_HOOK_SENTINEL = "kg-service-v3-classifier-hook";
|
|
@@ -48809,22 +49169,22 @@ var kgInstallHookSkill = defineSkill({
|
|
|
48809
49169
|
// ../mcp-server/src/tools/kg-install-hook.ts
|
|
48810
49170
|
function settingsPathFor2(scope, projectPath) {
|
|
48811
49171
|
if (scope === "user") {
|
|
48812
|
-
return
|
|
49172
|
+
return path46.join(os23.homedir(), ".claude", "settings.json");
|
|
48813
49173
|
}
|
|
48814
49174
|
const root = projectPath ?? process.cwd();
|
|
48815
|
-
return
|
|
49175
|
+
return path46.join(root, ".claude", "settings.json");
|
|
48816
49176
|
}
|
|
48817
49177
|
function register31(server, _ctx, _initError) {
|
|
48818
49178
|
validatedTool(server, kgInstallHookSkill, "olam_kg_install_hook", async (params) => {
|
|
48819
49179
|
const scope = params.scope === "user" ? "user" : "project";
|
|
48820
49180
|
const filePath = settingsPathFor2(scope, params.projectPath);
|
|
48821
49181
|
try {
|
|
48822
|
-
|
|
49182
|
+
fs47.mkdirSync(path46.dirname(filePath), { recursive: true });
|
|
48823
49183
|
let backupPath = null;
|
|
48824
|
-
if (
|
|
49184
|
+
if (fs47.existsSync(filePath)) {
|
|
48825
49185
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
48826
49186
|
backupPath = `${filePath}.olam-bak.${ts}`;
|
|
48827
|
-
|
|
49187
|
+
fs47.copyFileSync(filePath, backupPath);
|
|
48828
49188
|
}
|
|
48829
49189
|
const result = mergeHomeSettingsJson(filePath, {
|
|
48830
49190
|
ensureHook: {
|
|
@@ -48835,7 +49195,7 @@ function register31(server, _ctx, _initError) {
|
|
|
48835
49195
|
});
|
|
48836
49196
|
if (result.status === "already-present" && backupPath) {
|
|
48837
49197
|
try {
|
|
48838
|
-
|
|
49198
|
+
fs47.unlinkSync(backupPath);
|
|
48839
49199
|
} catch {
|
|
48840
49200
|
}
|
|
48841
49201
|
}
|
|
@@ -48877,9 +49237,9 @@ var kg_uninstall_hook_exports = {};
|
|
|
48877
49237
|
__export(kg_uninstall_hook_exports, {
|
|
48878
49238
|
register: () => register32
|
|
48879
49239
|
});
|
|
48880
|
-
import * as
|
|
48881
|
-
import * as
|
|
48882
|
-
import * as
|
|
49240
|
+
import * as fs48 from "node:fs";
|
|
49241
|
+
import * as path47 from "node:path";
|
|
49242
|
+
import * as os24 from "node:os";
|
|
48883
49243
|
|
|
48884
49244
|
// ../skill-runtime/dist/skills/kg-uninstall-hook.js
|
|
48885
49245
|
init_v3();
|
|
@@ -48901,10 +49261,10 @@ var kgUninstallHookSkill = defineSkill({
|
|
|
48901
49261
|
// ../mcp-server/src/tools/kg-uninstall-hook.ts
|
|
48902
49262
|
function settingsPathFor3(scope, projectPath) {
|
|
48903
49263
|
if (scope === "user") {
|
|
48904
|
-
return
|
|
49264
|
+
return path47.join(os24.homedir(), ".claude", "settings.json");
|
|
48905
49265
|
}
|
|
48906
49266
|
const root = projectPath ?? process.cwd();
|
|
48907
|
-
return
|
|
49267
|
+
return path47.join(root, ".claude", "settings.json");
|
|
48908
49268
|
}
|
|
48909
49269
|
function dropSentinel(matchers) {
|
|
48910
49270
|
let changed = false;
|
|
@@ -48931,7 +49291,7 @@ function register32(server, _ctx, _initError) {
|
|
|
48931
49291
|
const scope = params.scope === "user" ? "user" : "project";
|
|
48932
49292
|
const filePath = settingsPathFor3(scope, params.projectPath);
|
|
48933
49293
|
try {
|
|
48934
|
-
if (!
|
|
49294
|
+
if (!fs48.existsSync(filePath)) {
|
|
48935
49295
|
return {
|
|
48936
49296
|
content: [
|
|
48937
49297
|
{
|
|
@@ -48945,7 +49305,7 @@ function register32(server, _ctx, _initError) {
|
|
|
48945
49305
|
]
|
|
48946
49306
|
};
|
|
48947
49307
|
}
|
|
48948
|
-
const raw =
|
|
49308
|
+
const raw = fs48.readFileSync(filePath, "utf-8");
|
|
48949
49309
|
const settings = raw.trim() ? JSON.parse(raw) : {};
|
|
48950
49310
|
const preToolUse = settings.hooks?.PreToolUse;
|
|
48951
49311
|
if (!Array.isArray(preToolUse) || preToolUse.length === 0) {
|
|
@@ -48980,7 +49340,7 @@ function register32(server, _ctx, _initError) {
|
|
|
48980
49340
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
48981
49341
|
const backupPath = `${filePath}.olam-bak.${ts}`;
|
|
48982
49342
|
try {
|
|
48983
|
-
|
|
49343
|
+
fs48.copyFileSync(filePath, backupPath);
|
|
48984
49344
|
} catch {
|
|
48985
49345
|
}
|
|
48986
49346
|
const next = {
|
|
@@ -48992,7 +49352,7 @@ function register32(server, _ctx, _initError) {
|
|
|
48992
49352
|
if (otherStages.length === 0) delete next.hooks;
|
|
48993
49353
|
else delete next.hooks.PreToolUse;
|
|
48994
49354
|
}
|
|
48995
|
-
|
|
49355
|
+
fs48.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
48996
49356
|
return {
|
|
48997
49357
|
content: [
|
|
48998
49358
|
{
|
|
@@ -49730,12 +50090,12 @@ function registerAllTools(server, ctx, initError) {
|
|
|
49730
50090
|
}
|
|
49731
50091
|
|
|
49732
50092
|
// ../mcp-server/src/resources/chunks.ts
|
|
49733
|
-
import
|
|
49734
|
-
import
|
|
49735
|
-
import
|
|
50093
|
+
import fs49 from "node:fs";
|
|
50094
|
+
import os25 from "node:os";
|
|
50095
|
+
import path48 from "node:path";
|
|
49736
50096
|
var DEFAULT_HOST_CP_URL = "http://127.0.0.1:19000";
|
|
49737
|
-
var DEFAULT_PLAN_CHAT_SECRET_PATH =
|
|
49738
|
-
|
|
50097
|
+
var DEFAULT_PLAN_CHAT_SECRET_PATH = path48.join(
|
|
50098
|
+
os25.homedir(),
|
|
49739
50099
|
".olam",
|
|
49740
50100
|
"plan-chat-secret"
|
|
49741
50101
|
);
|
|
@@ -49749,7 +50109,7 @@ function loadBearer(bearerOpt, secretPath) {
|
|
|
49749
50109
|
const envBearer = process.env.OLAM_PLAN_CHAT_BEARER?.trim();
|
|
49750
50110
|
if (envBearer && envBearer.length > 0) return envBearer;
|
|
49751
50111
|
try {
|
|
49752
|
-
const onDisk =
|
|
50112
|
+
const onDisk = fs49.readFileSync(secretPath, "utf8").trim();
|
|
49753
50113
|
return onDisk.length > 0 ? onDisk : null;
|
|
49754
50114
|
} catch (err) {
|
|
49755
50115
|
if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
|
|
@@ -51523,9 +51883,9 @@ init_loader();
|
|
|
51523
51883
|
// ../core/dist/world/manager.js
|
|
51524
51884
|
import * as crypto8 from "node:crypto";
|
|
51525
51885
|
import { execSync as execSync6, spawnSync as spawnSync4 } from "node:child_process";
|
|
51526
|
-
import * as
|
|
51527
|
-
import * as
|
|
51528
|
-
import * as
|
|
51886
|
+
import * as fs59 from "node:fs";
|
|
51887
|
+
import * as os30 from "node:os";
|
|
51888
|
+
import * as path59 from "node:path";
|
|
51529
51889
|
|
|
51530
51890
|
// ../core/dist/world/state.js
|
|
51531
51891
|
var VALID_TRANSITIONS = {
|
|
@@ -51620,9 +51980,9 @@ function resolveDevboxImage(config2, tag) {
|
|
|
51620
51980
|
}
|
|
51621
51981
|
|
|
51622
51982
|
// ../core/dist/world/worktree.js
|
|
51623
|
-
import { execFileSync as
|
|
51624
|
-
import * as
|
|
51625
|
-
import * as
|
|
51983
|
+
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
51984
|
+
import * as fs50 from "node:fs";
|
|
51985
|
+
import * as path49 from "node:path";
|
|
51626
51986
|
function resolveGitDir(repo) {
|
|
51627
51987
|
if (repo.path) {
|
|
51628
51988
|
return repo.path;
|
|
@@ -51632,18 +51992,18 @@ function resolveGitDir(repo) {
|
|
|
51632
51992
|
async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
51633
51993
|
const created = [];
|
|
51634
51994
|
for (const repo of repos) {
|
|
51635
|
-
const worktreePath =
|
|
51995
|
+
const worktreePath = path49.join(workspacePath, repo.name);
|
|
51636
51996
|
const gitDir = resolveGitDir(repo);
|
|
51637
51997
|
const branchName = branch || `olam/${worldId}`;
|
|
51638
51998
|
try {
|
|
51639
|
-
|
|
51640
|
-
|
|
51999
|
+
fs50.mkdirSync(path49.dirname(worktreePath), { recursive: true });
|
|
52000
|
+
execFileSync5("git", ["worktree", "add", worktreePath, "-b", branchName], {
|
|
51641
52001
|
cwd: gitDir,
|
|
51642
52002
|
stdio: "pipe"
|
|
51643
52003
|
});
|
|
51644
52004
|
if (repo.submodules) {
|
|
51645
52005
|
try {
|
|
51646
|
-
|
|
52006
|
+
execFileSync5("git", ["submodule", "update", "--init", "--recursive"], {
|
|
51647
52007
|
cwd: worktreePath,
|
|
51648
52008
|
stdio: "pipe"
|
|
51649
52009
|
});
|
|
@@ -51655,7 +52015,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
|
51655
52015
|
for (const entry of created) {
|
|
51656
52016
|
try {
|
|
51657
52017
|
const entryGitDir = resolveGitDir(entry.repo);
|
|
51658
|
-
|
|
52018
|
+
execFileSync5("git", ["worktree", "remove", entry.worktreePath, "--force"], {
|
|
51659
52019
|
cwd: entryGitDir,
|
|
51660
52020
|
stdio: "pipe"
|
|
51661
52021
|
});
|
|
@@ -51669,7 +52029,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
|
51669
52029
|
}
|
|
51670
52030
|
async function removeWorktrees(repos, workspacePath) {
|
|
51671
52031
|
for (const repo of repos) {
|
|
51672
|
-
const worktreePath =
|
|
52032
|
+
const worktreePath = path49.join(workspacePath, repo.name);
|
|
51673
52033
|
let gitDir;
|
|
51674
52034
|
try {
|
|
51675
52035
|
gitDir = resolveGitDir(repo);
|
|
@@ -51678,7 +52038,7 @@ async function removeWorktrees(repos, workspacePath) {
|
|
|
51678
52038
|
}
|
|
51679
52039
|
let removed = false;
|
|
51680
52040
|
try {
|
|
51681
|
-
|
|
52041
|
+
execFileSync5("git", ["worktree", "remove", "--force", worktreePath], {
|
|
51682
52042
|
cwd: gitDir,
|
|
51683
52043
|
stdio: "pipe"
|
|
51684
52044
|
});
|
|
@@ -51687,7 +52047,7 @@ async function removeWorktrees(repos, workspacePath) {
|
|
|
51687
52047
|
}
|
|
51688
52048
|
if (!removed) {
|
|
51689
52049
|
try {
|
|
51690
|
-
|
|
52050
|
+
execFileSync5("git", ["worktree", "prune"], {
|
|
51691
52051
|
cwd: gitDir,
|
|
51692
52052
|
stdio: "pipe"
|
|
51693
52053
|
});
|
|
@@ -51704,7 +52064,7 @@ function removeBranch(repo, branch) {
|
|
|
51704
52064
|
return { branch, action: "not-found" };
|
|
51705
52065
|
}
|
|
51706
52066
|
try {
|
|
51707
|
-
|
|
52067
|
+
execFileSync5("git", ["show-ref", "--quiet", `refs/heads/${branch}`], {
|
|
51708
52068
|
cwd: gitDir,
|
|
51709
52069
|
stdio: "pipe"
|
|
51710
52070
|
});
|
|
@@ -51713,7 +52073,7 @@ function removeBranch(repo, branch) {
|
|
|
51713
52073
|
}
|
|
51714
52074
|
let hasUpstream = false;
|
|
51715
52075
|
try {
|
|
51716
|
-
|
|
52076
|
+
execFileSync5("git", ["rev-parse", "--abbrev-ref", `${branch}@{upstream}`], { cwd: gitDir, stdio: "pipe" });
|
|
51717
52077
|
hasUpstream = true;
|
|
51718
52078
|
} catch {
|
|
51719
52079
|
}
|
|
@@ -51722,14 +52082,14 @@ function removeBranch(repo, branch) {
|
|
|
51722
52082
|
}
|
|
51723
52083
|
let localCommitCount = 0;
|
|
51724
52084
|
try {
|
|
51725
|
-
const output =
|
|
52085
|
+
const output = execFileSync5("git", ["rev-list", "--count", branch, "--not", "--remotes"], { cwd: gitDir, stdio: "pipe" }).toString().trim();
|
|
51726
52086
|
localCommitCount = parseInt(output, 10) || 0;
|
|
51727
52087
|
} catch {
|
|
51728
52088
|
localCommitCount = 1;
|
|
51729
52089
|
}
|
|
51730
52090
|
if (localCommitCount === 0) {
|
|
51731
52091
|
try {
|
|
51732
|
-
|
|
52092
|
+
execFileSync5("git", ["branch", "-D", branch], {
|
|
51733
52093
|
cwd: gitDir,
|
|
51734
52094
|
stdio: "pipe"
|
|
51735
52095
|
});
|
|
@@ -51743,13 +52103,13 @@ function removeBranch(repo, branch) {
|
|
|
51743
52103
|
}
|
|
51744
52104
|
|
|
51745
52105
|
// ../core/dist/world/kg-overlay.js
|
|
51746
|
-
import { execFileSync as
|
|
51747
|
-
import * as
|
|
51748
|
-
import * as
|
|
52106
|
+
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
52107
|
+
import * as fs51 from "node:fs";
|
|
52108
|
+
import * as path50 from "node:path";
|
|
51749
52109
|
|
|
51750
52110
|
// ../core/dist/kg/storage-paths.js
|
|
51751
|
-
import { homedir as
|
|
51752
|
-
import { join as
|
|
52111
|
+
import { homedir as homedir26 } from "node:os";
|
|
52112
|
+
import { join as join53, resolve as resolve11 } from "node:path";
|
|
51753
52113
|
|
|
51754
52114
|
// ../core/dist/world/workspace-name.js
|
|
51755
52115
|
var InvalidWorkspaceNameError = class extends Error {
|
|
@@ -51769,29 +52129,29 @@ function validateWorkspaceName(name) {
|
|
|
51769
52129
|
}
|
|
51770
52130
|
|
|
51771
52131
|
// ../core/dist/kg/storage-paths.js
|
|
51772
|
-
function
|
|
51773
|
-
return process.env.OLAM_HOME ??
|
|
52132
|
+
function olamHome3() {
|
|
52133
|
+
return process.env.OLAM_HOME ?? join53(homedir26(), ".olam");
|
|
51774
52134
|
}
|
|
51775
52135
|
function kgRoot() {
|
|
51776
|
-
return
|
|
52136
|
+
return join53(olamHome3(), "kg");
|
|
51777
52137
|
}
|
|
51778
52138
|
function worldsRoot() {
|
|
51779
|
-
return
|
|
52139
|
+
return join53(olamHome3(), "worlds");
|
|
51780
52140
|
}
|
|
51781
|
-
function assertWithinPrefix(
|
|
51782
|
-
if (!
|
|
51783
|
-
throw new Error(`${label} escape: ${
|
|
52141
|
+
function assertWithinPrefix(path62, prefix, label) {
|
|
52142
|
+
if (!path62.startsWith(prefix + "/")) {
|
|
52143
|
+
throw new Error(`${label} escape: ${path62} not under ${prefix}/`);
|
|
51784
52144
|
}
|
|
51785
52145
|
}
|
|
51786
52146
|
function kgPristinePath(workspace) {
|
|
51787
52147
|
validateWorkspaceName(workspace);
|
|
51788
52148
|
const root = kgRoot();
|
|
51789
|
-
const
|
|
51790
|
-
assertWithinPrefix(
|
|
51791
|
-
return
|
|
52149
|
+
const path62 = resolve11(join53(root, workspace));
|
|
52150
|
+
assertWithinPrefix(path62, root, "kgPristinePath");
|
|
52151
|
+
return path62;
|
|
51792
52152
|
}
|
|
51793
52153
|
var KG_PATHS_INTERNALS = Object.freeze({
|
|
51794
|
-
olamHome:
|
|
52154
|
+
olamHome: olamHome3,
|
|
51795
52155
|
kgRoot,
|
|
51796
52156
|
worldsRoot
|
|
51797
52157
|
});
|
|
@@ -51804,10 +52164,10 @@ var KgOverlayError = class extends Error {
|
|
|
51804
52164
|
}
|
|
51805
52165
|
};
|
|
51806
52166
|
function ensureGitignoreEntry(worldClonePath) {
|
|
51807
|
-
const gitignorePath =
|
|
51808
|
-
if (!
|
|
52167
|
+
const gitignorePath = path50.join(worldClonePath, ".gitignore");
|
|
52168
|
+
if (!fs51.existsSync(gitignorePath))
|
|
51809
52169
|
return "no-gitignore";
|
|
51810
|
-
const content =
|
|
52170
|
+
const content = fs51.readFileSync(gitignorePath, "utf-8");
|
|
51811
52171
|
const lines = content.split("\n").map((l) => l.trim());
|
|
51812
52172
|
const recognised = /* @__PURE__ */ new Set([
|
|
51813
52173
|
"graphify-out",
|
|
@@ -51822,31 +52182,31 @@ function ensureGitignoreEntry(worldClonePath) {
|
|
|
51822
52182
|
const eol = content.includes("\r\n") ? "\r\n" : "\n";
|
|
51823
52183
|
const needsLeadingNewline = content.length > 0 && !content.endsWith(eol);
|
|
51824
52184
|
const block = `${needsLeadingNewline ? eol : ""}${eol}# olam-kg-service: per-world KG overlay (Phase B1)${eol}graphify-out/${eol}`;
|
|
51825
|
-
|
|
52185
|
+
fs51.appendFileSync(gitignorePath, block, "utf-8");
|
|
51826
52186
|
return "appended";
|
|
51827
52187
|
}
|
|
51828
52188
|
function createWorldOverlay(opts) {
|
|
51829
52189
|
const pristineRoot = kgPristinePath(opts.workspace);
|
|
51830
|
-
const pristinePath =
|
|
51831
|
-
if (!
|
|
52190
|
+
const pristinePath = path50.join(pristineRoot, "graphify-out");
|
|
52191
|
+
if (!fs51.existsSync(pristinePath)) {
|
|
51832
52192
|
throw new KgOverlayError(`Pristine KG for workspace ${JSON.stringify(opts.workspace)} not found at ${pristinePath}. Run \`olam kg build ${opts.workspace}\` first.`);
|
|
51833
52193
|
}
|
|
51834
|
-
if (!
|
|
52194
|
+
if (!path50.isAbsolute(opts.worldClonePath)) {
|
|
51835
52195
|
throw new KgOverlayError(`worldClonePath must be absolute (got ${opts.worldClonePath})`);
|
|
51836
52196
|
}
|
|
51837
|
-
if (!
|
|
52197
|
+
if (!fs51.existsSync(opts.worldClonePath)) {
|
|
51838
52198
|
throw new KgOverlayError(`worldClonePath does not exist: ${opts.worldClonePath}. Create the clone before reflinking.`);
|
|
51839
52199
|
}
|
|
51840
|
-
const overlayPath =
|
|
51841
|
-
if (
|
|
51842
|
-
|
|
52200
|
+
const overlayPath = path50.join(opts.worldClonePath, "graphify-out");
|
|
52201
|
+
if (fs51.existsSync(overlayPath)) {
|
|
52202
|
+
fs51.rmSync(overlayPath, { recursive: true, force: true });
|
|
51843
52203
|
}
|
|
51844
52204
|
const useReflink = process.platform === "darwin";
|
|
51845
52205
|
let strategy;
|
|
51846
52206
|
let reflinkError;
|
|
51847
52207
|
if (useReflink) {
|
|
51848
52208
|
try {
|
|
51849
|
-
|
|
52209
|
+
execFileSync6("cp", ["-c", "-r", pristinePath, opts.worldClonePath], {
|
|
51850
52210
|
stdio: ["ignore", "ignore", "pipe"]
|
|
51851
52211
|
});
|
|
51852
52212
|
strategy = "cp-c-r-reflink";
|
|
@@ -51857,9 +52217,9 @@ function createWorldOverlay(opts) {
|
|
|
51857
52217
|
} else {
|
|
51858
52218
|
strategy = "cp-r";
|
|
51859
52219
|
}
|
|
51860
|
-
if (strategy === "cp-r" || !
|
|
52220
|
+
if (strategy === "cp-r" || !fs51.existsSync(overlayPath)) {
|
|
51861
52221
|
try {
|
|
51862
|
-
|
|
52222
|
+
execFileSync6("cp", ["-r", pristinePath, opts.worldClonePath], {
|
|
51863
52223
|
stdio: ["ignore", "ignore", "pipe"]
|
|
51864
52224
|
});
|
|
51865
52225
|
strategy = "cp-r";
|
|
@@ -51869,7 +52229,7 @@ function createWorldOverlay(opts) {
|
|
|
51869
52229
|
throw new KgOverlayError(`cp -r failed: ${msg}${reflinkMsg}`);
|
|
51870
52230
|
}
|
|
51871
52231
|
}
|
|
51872
|
-
if (!
|
|
52232
|
+
if (!fs51.existsSync(overlayPath)) {
|
|
51873
52233
|
throw new KgOverlayError(`Overlay creation produced no ${overlayPath} after cp \u2014 filesystem returned without error?`);
|
|
51874
52234
|
}
|
|
51875
52235
|
const gitignoreAction = ensureGitignoreEntry(opts.worldClonePath);
|
|
@@ -51882,13 +52242,13 @@ function createWorldOverlay(opts) {
|
|
|
51882
52242
|
}
|
|
51883
52243
|
|
|
51884
52244
|
// ../core/dist/world/baseline-diff.js
|
|
51885
|
-
import { execFileSync as
|
|
51886
|
-
import * as
|
|
51887
|
-
import * as
|
|
51888
|
-
import * as
|
|
52245
|
+
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
52246
|
+
import * as fs52 from "node:fs";
|
|
52247
|
+
import * as os26 from "node:os";
|
|
52248
|
+
import * as path51 from "node:path";
|
|
51889
52249
|
var DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
51890
|
-
function expandHome2(p,
|
|
51891
|
-
return p.replace(/^~(?=$|\/|\\)/,
|
|
52250
|
+
function expandHome2(p, homedir33) {
|
|
52251
|
+
return p.replace(/^~(?=$|\/|\\)/, homedir33());
|
|
51892
52252
|
}
|
|
51893
52253
|
function sanitizeRepoFilename(name) {
|
|
51894
52254
|
const sanitized = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
@@ -51910,11 +52270,11 @@ ${stderr}`;
|
|
|
51910
52270
|
return /unknown revision|bad revision|does not have any commits|HEAD'?: ambiguous|Needed a single revision/.test(blob);
|
|
51911
52271
|
}
|
|
51912
52272
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
51913
|
-
const exec = deps.exec ?? ((cmd, args, opts) =>
|
|
51914
|
-
const
|
|
51915
|
-
const baselineDir =
|
|
52273
|
+
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
|
|
52274
|
+
const homedir33 = deps.homedir ?? (() => os26.homedir());
|
|
52275
|
+
const baselineDir = path51.join(workspacePath, ".olam", "baseline");
|
|
51916
52276
|
try {
|
|
51917
|
-
|
|
52277
|
+
fs52.mkdirSync(baselineDir, { recursive: true });
|
|
51918
52278
|
} catch (err) {
|
|
51919
52279
|
const msg = err instanceof Error ? err.message : String(err);
|
|
51920
52280
|
console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
|
|
@@ -51926,9 +52286,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
51926
52286
|
if (!repo.path)
|
|
51927
52287
|
continue;
|
|
51928
52288
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
51929
|
-
const outPath =
|
|
51930
|
-
const repoPath = expandHome2(repo.path,
|
|
51931
|
-
if (!
|
|
52289
|
+
const outPath = path51.join(baselineDir, filename);
|
|
52290
|
+
const repoPath = expandHome2(repo.path, homedir33);
|
|
52291
|
+
if (!fs52.existsSync(repoPath)) {
|
|
51932
52292
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
51933
52293
|
# (skipped: path ${repoPath} does not exist)
|
|
51934
52294
|
`);
|
|
@@ -51995,7 +52355,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
51995
52355
|
}
|
|
51996
52356
|
function writeBaselineFile(outPath, content) {
|
|
51997
52357
|
try {
|
|
51998
|
-
|
|
52358
|
+
fs52.writeFileSync(outPath, content);
|
|
51999
52359
|
} catch (err) {
|
|
52000
52360
|
const msg = err instanceof Error ? err.message : String(err);
|
|
52001
52361
|
console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
|
|
@@ -52003,11 +52363,11 @@ function writeBaselineFile(outPath, content) {
|
|
|
52003
52363
|
}
|
|
52004
52364
|
function stripWorktreeEdits(repos, workspacePath) {
|
|
52005
52365
|
for (const repo of repos) {
|
|
52006
|
-
const worktreePath =
|
|
52007
|
-
if (!
|
|
52366
|
+
const worktreePath = path51.join(workspacePath, repo.name);
|
|
52367
|
+
if (!fs52.existsSync(worktreePath))
|
|
52008
52368
|
continue;
|
|
52009
52369
|
try {
|
|
52010
|
-
|
|
52370
|
+
execFileSync7("git", ["checkout", "--", "."], {
|
|
52011
52371
|
cwd: worktreePath,
|
|
52012
52372
|
stdio: "pipe"
|
|
52013
52373
|
});
|
|
@@ -52034,7 +52394,7 @@ ${stderr.trim()}` : "";
|
|
|
52034
52394
|
}
|
|
52035
52395
|
};
|
|
52036
52396
|
function captureOperatorDiff(repoPath, deps = {}) {
|
|
52037
|
-
const exec = deps.exec ?? ((cmd, args, opts) =>
|
|
52397
|
+
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
|
|
52038
52398
|
const unstaged = exec("git", ["diff"], {
|
|
52039
52399
|
cwd: repoPath,
|
|
52040
52400
|
encoding: "utf-8",
|
|
@@ -52062,22 +52422,22 @@ function extractStderr(err) {
|
|
|
52062
52422
|
return typeof raw === "string" ? raw : raw.toString("utf-8");
|
|
52063
52423
|
}
|
|
52064
52424
|
function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
52065
|
-
const exec = deps.exec ?? ((cmd, args, opts) =>
|
|
52066
|
-
const
|
|
52067
|
-
const
|
|
52068
|
-
const
|
|
52425
|
+
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
|
|
52426
|
+
const homedir33 = deps.homedir ?? (() => os26.homedir());
|
|
52427
|
+
const existsSync61 = deps.existsSync ?? ((p) => fs52.existsSync(p));
|
|
52428
|
+
const copyFileSync10 = deps.copyFileSync ?? ((src, dest) => fs52.copyFileSync(src, dest));
|
|
52069
52429
|
const mkdirSync34 = deps.mkdirSync ?? ((dirPath, opts) => {
|
|
52070
|
-
|
|
52430
|
+
fs52.mkdirSync(dirPath, opts);
|
|
52071
52431
|
});
|
|
52072
52432
|
const plans = [];
|
|
52073
52433
|
for (const repo of repos) {
|
|
52074
52434
|
if (!repo.path)
|
|
52075
52435
|
continue;
|
|
52076
|
-
const repoPath = expandHome2(repo.path,
|
|
52077
|
-
const worktreePath =
|
|
52078
|
-
if (!
|
|
52436
|
+
const repoPath = expandHome2(repo.path, homedir33);
|
|
52437
|
+
const worktreePath = path51.join(workspacePath, repo.name);
|
|
52438
|
+
if (!existsSync61(repoPath))
|
|
52079
52439
|
continue;
|
|
52080
|
-
if (!
|
|
52440
|
+
if (!existsSync61(worktreePath)) {
|
|
52081
52441
|
console.warn(`[carry] ${repo.name}: world worktree ${worktreePath} missing; skipping carry for this repo`);
|
|
52082
52442
|
continue;
|
|
52083
52443
|
}
|
|
@@ -52135,13 +52495,13 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
52135
52495
|
}
|
|
52136
52496
|
}
|
|
52137
52497
|
for (const rel of plan.diff.untracked) {
|
|
52138
|
-
const src =
|
|
52139
|
-
const dest =
|
|
52140
|
-
if (!
|
|
52498
|
+
const src = path51.join(plan.repoPath, rel);
|
|
52499
|
+
const dest = path51.join(plan.worktreePath, rel);
|
|
52500
|
+
if (!existsSync61(src))
|
|
52141
52501
|
continue;
|
|
52142
52502
|
try {
|
|
52143
|
-
mkdirSync34(
|
|
52144
|
-
|
|
52503
|
+
mkdirSync34(path51.dirname(dest), { recursive: true });
|
|
52504
|
+
copyFileSync10(src, dest);
|
|
52145
52505
|
} catch (err) {
|
|
52146
52506
|
const msg = err instanceof Error ? err.message : String(err);
|
|
52147
52507
|
console.warn(`[carry] ${plan.name}: copy untracked ${rel} failed: ${msg}`);
|
|
@@ -52166,8 +52526,8 @@ function formatBaselineSummary(result) {
|
|
|
52166
52526
|
}
|
|
52167
52527
|
|
|
52168
52528
|
// ../core/dist/world/context-injection.js
|
|
52169
|
-
import * as
|
|
52170
|
-
import * as
|
|
52529
|
+
import * as fs53 from "node:fs";
|
|
52530
|
+
import * as path52 from "node:path";
|
|
52171
52531
|
|
|
52172
52532
|
// ../core/dist/world/templates/_generated.js
|
|
52173
52533
|
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';
|
|
@@ -52177,10 +52537,10 @@ var WORLD_CLAUDE_MD = '# Olam World: {{worldName}}\n\n{{taskBlock}}\n\n## Enviro
|
|
|
52177
52537
|
// ../core/dist/world/context-injection.js
|
|
52178
52538
|
function injectWorldContext(opts) {
|
|
52179
52539
|
const { world } = opts;
|
|
52180
|
-
const
|
|
52181
|
-
|
|
52540
|
+
const claudeDir3 = path52.join(world.workspacePath, ".claude");
|
|
52541
|
+
fs53.mkdirSync(claudeDir3, { recursive: true });
|
|
52182
52542
|
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));
|
|
52183
|
-
|
|
52543
|
+
fs53.writeFileSync(path52.join(claudeDir3, "CLAUDE.md"), content);
|
|
52184
52544
|
writeOlamDocs(world.workspacePath);
|
|
52185
52545
|
}
|
|
52186
52546
|
function buildTaskBlock(opts) {
|
|
@@ -52254,10 +52614,10 @@ function buildExtraContextBlock(extra) {
|
|
|
52254
52614
|
${extra}`;
|
|
52255
52615
|
}
|
|
52256
52616
|
function writeOlamDocs(workspacePath) {
|
|
52257
|
-
const docsDir =
|
|
52258
|
-
|
|
52259
|
-
|
|
52260
|
-
|
|
52617
|
+
const docsDir = path52.join(workspacePath, ".olam", "docs");
|
|
52618
|
+
fs53.mkdirSync(docsDir, { recursive: true });
|
|
52619
|
+
fs53.writeFileSync(path52.join(docsDir, "gh-pr-create.md"), GH_PR_CREATE);
|
|
52620
|
+
fs53.writeFileSync(path52.join(docsDir, "lane-orchestration.md"), LANE_ORCHESTRATION);
|
|
52261
52621
|
}
|
|
52262
52622
|
function formatTaskSource(ctx) {
|
|
52263
52623
|
if (ctx.source === "linear" && ctx.ticketId) {
|
|
@@ -52271,9 +52631,9 @@ function formatTaskSource(ctx) {
|
|
|
52271
52631
|
function hasPlanFile(world) {
|
|
52272
52632
|
if (world.repos.length === 0)
|
|
52273
52633
|
return false;
|
|
52274
|
-
const plansDir =
|
|
52634
|
+
const plansDir = path52.join(world.workspacePath, world.repos[0], "docs", "plans");
|
|
52275
52635
|
try {
|
|
52276
|
-
return
|
|
52636
|
+
return fs53.existsSync(plansDir) && fs53.readdirSync(plansDir).length > 0;
|
|
52277
52637
|
} catch {
|
|
52278
52638
|
return false;
|
|
52279
52639
|
}
|
|
@@ -52842,25 +53202,25 @@ init_repo_manifest();
|
|
|
52842
53202
|
|
|
52843
53203
|
// ../core/dist/world/snapshot.js
|
|
52844
53204
|
import * as crypto7 from "node:crypto";
|
|
52845
|
-
import * as
|
|
52846
|
-
import * as
|
|
52847
|
-
import * as
|
|
52848
|
-
import { execFileSync as
|
|
53205
|
+
import * as fs54 from "node:fs";
|
|
53206
|
+
import * as os27 from "node:os";
|
|
53207
|
+
import * as path53 from "node:path";
|
|
53208
|
+
import { execFileSync as execFileSync8, spawn as spawn5 } from "node:child_process";
|
|
52849
53209
|
import { gunzipSync } from "node:zlib";
|
|
52850
53210
|
function snapshotsDir() {
|
|
52851
|
-
return process.env["OLAM_SNAPSHOTS_DIR"] ??
|
|
53211
|
+
return process.env["OLAM_SNAPSHOTS_DIR"] ?? path53.join(os27.homedir(), ".olam", "snapshots");
|
|
52852
53212
|
}
|
|
52853
53213
|
function snapshotKindDirByWorkspace(workspace, arch, kind) {
|
|
52854
|
-
return
|
|
53214
|
+
return path53.join(snapshotsDir(), "by-workspace", workspace, arch, kind);
|
|
52855
53215
|
}
|
|
52856
53216
|
function cleanupLegacyByWorldDir(worldId) {
|
|
52857
|
-
const legacyDir =
|
|
53217
|
+
const legacyDir = path53.join(snapshotsDir(), worldId);
|
|
52858
53218
|
if (worldId === "by-workspace")
|
|
52859
53219
|
return;
|
|
52860
|
-
if (!
|
|
53220
|
+
if (!fs54.existsSync(legacyDir))
|
|
52861
53221
|
return;
|
|
52862
53222
|
try {
|
|
52863
|
-
|
|
53223
|
+
fs54.rmSync(legacyDir, { recursive: true, force: true });
|
|
52864
53224
|
} catch {
|
|
52865
53225
|
}
|
|
52866
53226
|
}
|
|
@@ -52879,11 +53239,11 @@ function hashBuffers(entries) {
|
|
|
52879
53239
|
return hash2.digest("hex").slice(0, 12);
|
|
52880
53240
|
}
|
|
52881
53241
|
function computeGemsFingerprint(repoDir, imageDigest) {
|
|
52882
|
-
const lockfile =
|
|
52883
|
-
if (!
|
|
53242
|
+
const lockfile = path53.join(repoDir, "Gemfile.lock");
|
|
53243
|
+
if (!fs54.existsSync(lockfile))
|
|
52884
53244
|
return null;
|
|
52885
53245
|
const entries = [
|
|
52886
|
-
{ path: "Gemfile.lock", content:
|
|
53246
|
+
{ path: "Gemfile.lock", content: fs54.readFileSync(lockfile) }
|
|
52887
53247
|
];
|
|
52888
53248
|
if (imageDigest) {
|
|
52889
53249
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -52893,10 +53253,10 @@ function computeGemsFingerprint(repoDir, imageDigest) {
|
|
|
52893
53253
|
function computeNodeFingerprint(repoDir, imageDigest) {
|
|
52894
53254
|
const candidates = ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"];
|
|
52895
53255
|
for (const name of candidates) {
|
|
52896
|
-
const lockfile =
|
|
52897
|
-
if (
|
|
53256
|
+
const lockfile = path53.join(repoDir, name);
|
|
53257
|
+
if (fs54.existsSync(lockfile)) {
|
|
52898
53258
|
const entries = [
|
|
52899
|
-
{ path: name, content:
|
|
53259
|
+
{ path: name, content: fs54.readFileSync(lockfile) }
|
|
52900
53260
|
];
|
|
52901
53261
|
if (imageDigest) {
|
|
52902
53262
|
entries.push({ path: "__image_digest__", content: Buffer.from(imageDigest, "utf-8") });
|
|
@@ -52915,18 +53275,18 @@ function unpackTarballAtomic(srcPath, destDir) {
|
|
|
52915
53275
|
detail: validation.detail ?? `unsafe entry: ${validation.unsafePath}`
|
|
52916
53276
|
};
|
|
52917
53277
|
}
|
|
52918
|
-
const parent =
|
|
52919
|
-
|
|
53278
|
+
const parent = path53.dirname(destDir);
|
|
53279
|
+
fs54.mkdirSync(parent, { recursive: true });
|
|
52920
53280
|
const tmpSuffix = `.tmp-${process.pid}-${crypto7.randomBytes(4).toString("hex")}`;
|
|
52921
53281
|
const tmpDir = `${destDir}${tmpSuffix}`;
|
|
52922
53282
|
try {
|
|
52923
|
-
|
|
52924
|
-
|
|
52925
|
-
|
|
53283
|
+
fs54.mkdirSync(tmpDir, { recursive: true });
|
|
53284
|
+
execFileSync8("tar", ["-xzf", srcPath, "-C", tmpDir], { stdio: "pipe" });
|
|
53285
|
+
fs54.renameSync(tmpDir, destDir);
|
|
52926
53286
|
return { ok: true, entryCount: validation.entries.length };
|
|
52927
53287
|
} catch (err) {
|
|
52928
53288
|
try {
|
|
52929
|
-
|
|
53289
|
+
fs54.rmSync(tmpDir, { recursive: true, force: true });
|
|
52930
53290
|
} catch {
|
|
52931
53291
|
}
|
|
52932
53292
|
return {
|
|
@@ -52937,12 +53297,12 @@ function unpackTarballAtomic(srcPath, destDir) {
|
|
|
52937
53297
|
}
|
|
52938
53298
|
}
|
|
52939
53299
|
function resolvesWithin(base, target) {
|
|
52940
|
-
const resolved =
|
|
52941
|
-
const baseResolved =
|
|
52942
|
-
const rel =
|
|
53300
|
+
const resolved = path53.resolve(base, target);
|
|
53301
|
+
const baseResolved = path53.resolve(base);
|
|
53302
|
+
const rel = path53.relative(baseResolved, resolved);
|
|
52943
53303
|
if (rel === "")
|
|
52944
53304
|
return true;
|
|
52945
|
-
return !rel.startsWith("..") && !
|
|
53305
|
+
return !rel.startsWith("..") && !path53.isAbsolute(rel);
|
|
52946
53306
|
}
|
|
52947
53307
|
var TYPE_CHAR_TO_TYPE = {
|
|
52948
53308
|
"-": "file",
|
|
@@ -52992,7 +53352,7 @@ function parseTarListLine(line) {
|
|
|
52992
53352
|
function validateHardlinksBinary(tarPath, targetDir) {
|
|
52993
53353
|
let raw;
|
|
52994
53354
|
try {
|
|
52995
|
-
raw = gunzipSync(
|
|
53355
|
+
raw = gunzipSync(fs54.readFileSync(tarPath));
|
|
52996
53356
|
} catch {
|
|
52997
53357
|
return null;
|
|
52998
53358
|
}
|
|
@@ -53007,7 +53367,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
|
|
|
53007
53367
|
const name = block.subarray(0, nameNull >= 0 && nameNull <= 99 ? nameNull : 100).toString("utf-8");
|
|
53008
53368
|
const linkNull = block.indexOf(0, 157);
|
|
53009
53369
|
const linkname = block.subarray(157, linkNull >= 157 && linkNull <= 256 ? linkNull : 257).toString("utf-8");
|
|
53010
|
-
if (linkname && (
|
|
53370
|
+
if (linkname && (path53.isAbsolute(linkname) || !resolvesWithin(targetDir, linkname))) {
|
|
53011
53371
|
return {
|
|
53012
53372
|
valid: false,
|
|
53013
53373
|
reason: "hardlink-escape",
|
|
@@ -53025,7 +53385,7 @@ function validateHardlinksBinary(tarPath, targetDir) {
|
|
|
53025
53385
|
function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
53026
53386
|
let raw;
|
|
53027
53387
|
try {
|
|
53028
|
-
raw =
|
|
53388
|
+
raw = execFileSync8("tar", ["-tvf", tarPath], {
|
|
53029
53389
|
stdio: ["ignore", "pipe", "pipe"],
|
|
53030
53390
|
env: { ...process.env, LC_ALL: "C", TZ: "UTC" },
|
|
53031
53391
|
encoding: "utf-8",
|
|
@@ -53045,7 +53405,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
53045
53405
|
const entry = parseTarListLine(line);
|
|
53046
53406
|
if (!entry)
|
|
53047
53407
|
continue;
|
|
53048
|
-
if (
|
|
53408
|
+
if (path53.isAbsolute(entry.name) || !resolvesWithin(targetDir, entry.name)) {
|
|
53049
53409
|
return {
|
|
53050
53410
|
valid: false,
|
|
53051
53411
|
reason: "path-traversal",
|
|
@@ -53053,8 +53413,8 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
53053
53413
|
};
|
|
53054
53414
|
}
|
|
53055
53415
|
if (entry.type === "symlink" && entry.linkname !== void 0) {
|
|
53056
|
-
const symlinkParent =
|
|
53057
|
-
if (
|
|
53416
|
+
const symlinkParent = path53.join(targetDir, path53.dirname(entry.name));
|
|
53417
|
+
if (path53.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, path53.join(path53.dirname(entry.name), entry.linkname))) {
|
|
53058
53418
|
return {
|
|
53059
53419
|
valid: false,
|
|
53060
53420
|
reason: "symlink-escape",
|
|
@@ -53064,7 +53424,7 @@ function enumerateAndValidateTarballEntries(tarPath, targetDir) {
|
|
|
53064
53424
|
}
|
|
53065
53425
|
}
|
|
53066
53426
|
if (entry.type === "hardlink" && entry.linkname !== void 0) {
|
|
53067
|
-
if (
|
|
53427
|
+
if (path53.isAbsolute(entry.linkname) || !resolvesWithin(targetDir, entry.linkname)) {
|
|
53068
53428
|
return {
|
|
53069
53429
|
valid: false,
|
|
53070
53430
|
reason: "hardlink-escape",
|
|
@@ -53097,8 +53457,8 @@ function restoreSnapshotsForRepos(input) {
|
|
|
53097
53457
|
}
|
|
53098
53458
|
const archDir = snapshotKindDirByWorkspace(input.workspace, input.arch, kind);
|
|
53099
53459
|
const tarFilename = `${repo.name}-${input.arch}-${fingerprint}.tar.gz`;
|
|
53100
|
-
const tarPath =
|
|
53101
|
-
if (!
|
|
53460
|
+
const tarPath = path53.join(archDir, tarFilename);
|
|
53461
|
+
if (!fs54.existsSync(tarPath)) {
|
|
53102
53462
|
outcomes.push({ repo: repo.name, kind, outcome: "miss", reason: "no-tarball", fingerprint });
|
|
53103
53463
|
continue;
|
|
53104
53464
|
}
|
|
@@ -53113,9 +53473,9 @@ function restoreSnapshotsForRepos(input) {
|
|
|
53113
53473
|
});
|
|
53114
53474
|
continue;
|
|
53115
53475
|
}
|
|
53116
|
-
const targetDir =
|
|
53476
|
+
const targetDir = path53.join(repo.worktreeDir, targetSubpath);
|
|
53117
53477
|
try {
|
|
53118
|
-
|
|
53478
|
+
fs54.rmSync(targetDir, { recursive: true, force: true });
|
|
53119
53479
|
} catch {
|
|
53120
53480
|
}
|
|
53121
53481
|
const result = unpackTarballAtomic(tarPath, targetDir);
|
|
@@ -53128,8 +53488,8 @@ function restoreSnapshotsForRepos(input) {
|
|
|
53128
53488
|
fingerprint
|
|
53129
53489
|
});
|
|
53130
53490
|
try {
|
|
53131
|
-
|
|
53132
|
-
|
|
53491
|
+
fs54.rmSync(tarPath, { force: true });
|
|
53492
|
+
fs54.rmSync(manifestPath(tarPath), { force: true });
|
|
53133
53493
|
} catch {
|
|
53134
53494
|
}
|
|
53135
53495
|
continue;
|
|
@@ -53145,10 +53505,10 @@ function restoreSnapshotsForRepos(input) {
|
|
|
53145
53505
|
}
|
|
53146
53506
|
function readManifest(tarPath) {
|
|
53147
53507
|
const mPath = manifestPath(tarPath);
|
|
53148
|
-
if (!
|
|
53508
|
+
if (!fs54.existsSync(mPath))
|
|
53149
53509
|
return null;
|
|
53150
53510
|
try {
|
|
53151
|
-
return JSON.parse(
|
|
53511
|
+
return JSON.parse(fs54.readFileSync(mPath, "utf-8"));
|
|
53152
53512
|
} catch {
|
|
53153
53513
|
return null;
|
|
53154
53514
|
}
|
|
@@ -53163,17 +53523,17 @@ function isPidAlive(pid) {
|
|
|
53163
53523
|
}
|
|
53164
53524
|
}
|
|
53165
53525
|
function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
53166
|
-
|
|
53167
|
-
const lockPath =
|
|
53526
|
+
fs54.mkdirSync(dir, { recursive: true });
|
|
53527
|
+
const lockPath = path53.join(dir, EVICT_LOCK_FILENAME);
|
|
53168
53528
|
let fd;
|
|
53169
53529
|
try {
|
|
53170
|
-
fd =
|
|
53530
|
+
fd = fs54.openSync(lockPath, fs54.constants.O_WRONLY | fs54.constants.O_CREAT | fs54.constants.O_EXCL, 384);
|
|
53171
53531
|
} catch (err) {
|
|
53172
53532
|
if (err.code !== "EEXIST")
|
|
53173
53533
|
return 0;
|
|
53174
53534
|
let holderPid = null;
|
|
53175
53535
|
try {
|
|
53176
|
-
holderPid = parseInt(
|
|
53536
|
+
holderPid = parseInt(fs54.readFileSync(lockPath, "utf-8").trim(), 10);
|
|
53177
53537
|
} catch {
|
|
53178
53538
|
holderPid = null;
|
|
53179
53539
|
}
|
|
@@ -53181,23 +53541,23 @@ function evictOldSnapshotsWithFlock(maxBytes, dir = snapshotsDir()) {
|
|
|
53181
53541
|
return 0;
|
|
53182
53542
|
}
|
|
53183
53543
|
try {
|
|
53184
|
-
|
|
53185
|
-
fd =
|
|
53544
|
+
fs54.unlinkSync(lockPath);
|
|
53545
|
+
fd = fs54.openSync(lockPath, fs54.constants.O_WRONLY | fs54.constants.O_CREAT | fs54.constants.O_EXCL, 384);
|
|
53186
53546
|
} catch {
|
|
53187
53547
|
return 0;
|
|
53188
53548
|
}
|
|
53189
53549
|
}
|
|
53190
53550
|
try {
|
|
53191
|
-
|
|
53551
|
+
fs54.writeSync(fd, `${process.pid}
|
|
53192
53552
|
`);
|
|
53193
53553
|
} finally {
|
|
53194
|
-
|
|
53554
|
+
fs54.closeSync(fd);
|
|
53195
53555
|
}
|
|
53196
53556
|
try {
|
|
53197
53557
|
return evictOldSnapshots(maxBytes, dir);
|
|
53198
53558
|
} finally {
|
|
53199
53559
|
try {
|
|
53200
|
-
|
|
53560
|
+
fs54.unlinkSync(lockPath);
|
|
53201
53561
|
} catch {
|
|
53202
53562
|
}
|
|
53203
53563
|
}
|
|
@@ -53230,16 +53590,16 @@ function spawnAutoCapture(worldId, olamBin = "olam") {
|
|
|
53230
53590
|
}
|
|
53231
53591
|
}
|
|
53232
53592
|
function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
53233
|
-
if (!
|
|
53593
|
+
if (!fs54.existsSync(dir))
|
|
53234
53594
|
return 0;
|
|
53235
53595
|
const allTars = [];
|
|
53236
53596
|
const walk = (d) => {
|
|
53237
|
-
for (const entry of
|
|
53238
|
-
const full =
|
|
53597
|
+
for (const entry of fs54.readdirSync(d, { withFileTypes: true })) {
|
|
53598
|
+
const full = path53.join(d, entry.name);
|
|
53239
53599
|
if (entry.isDirectory()) {
|
|
53240
53600
|
walk(full);
|
|
53241
53601
|
} else if (entry.name.endsWith(".tar.gz")) {
|
|
53242
|
-
const stat2 =
|
|
53602
|
+
const stat2 = fs54.statSync(full);
|
|
53243
53603
|
allTars.push({ path: full, size: stat2.size, mtime: stat2.mtimeMs });
|
|
53244
53604
|
}
|
|
53245
53605
|
}
|
|
@@ -53254,8 +53614,8 @@ function evictOldSnapshots(maxBytes, dir = snapshotsDir()) {
|
|
|
53254
53614
|
for (const tar of allTars) {
|
|
53255
53615
|
if (remaining <= maxBytes)
|
|
53256
53616
|
break;
|
|
53257
|
-
|
|
53258
|
-
|
|
53617
|
+
fs54.rmSync(tar.path, { force: true });
|
|
53618
|
+
fs54.rmSync(manifestPath(tar.path), { force: true });
|
|
53259
53619
|
freed += tar.size;
|
|
53260
53620
|
remaining -= tar.size;
|
|
53261
53621
|
}
|
|
@@ -53372,14 +53732,14 @@ function gcloudAvailable(execFn = defaultExecFn) {
|
|
|
53372
53732
|
|
|
53373
53733
|
// ../core/dist/world/olam-yaml.js
|
|
53374
53734
|
init_repo_manifest();
|
|
53375
|
-
import * as
|
|
53735
|
+
import * as path54 from "node:path";
|
|
53376
53736
|
import YAML2 from "yaml";
|
|
53377
53737
|
function enrichReposWithManifests(repos, workspacePath) {
|
|
53378
53738
|
return repos.map((repo) => {
|
|
53379
53739
|
if (repo.manifest !== void 0 && repo.manifest !== null) {
|
|
53380
53740
|
return repo;
|
|
53381
53741
|
}
|
|
53382
|
-
const repoDir =
|
|
53742
|
+
const repoDir = path54.join(workspacePath, repo.name);
|
|
53383
53743
|
let manifest = null;
|
|
53384
53744
|
try {
|
|
53385
53745
|
manifest = loadRepoManifest(repoDir);
|
|
@@ -53394,8 +53754,8 @@ function enrichReposWithManifests(repos, workspacePath) {
|
|
|
53394
53754
|
}
|
|
53395
53755
|
|
|
53396
53756
|
// ../core/dist/policies/loader.js
|
|
53397
|
-
import * as
|
|
53398
|
-
import * as
|
|
53757
|
+
import * as fs55 from "node:fs";
|
|
53758
|
+
import * as path55 from "node:path";
|
|
53399
53759
|
import { parse as parseYaml5 } from "yaml";
|
|
53400
53760
|
function parseFrontmatter2(content) {
|
|
53401
53761
|
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
|
|
@@ -53415,20 +53775,20 @@ function toStringArray(v) {
|
|
|
53415
53775
|
return v.filter((x) => typeof x === "string");
|
|
53416
53776
|
}
|
|
53417
53777
|
function loadPolicies(workspaceRoot) {
|
|
53418
|
-
const policiesDir =
|
|
53419
|
-
if (!
|
|
53778
|
+
const policiesDir = path55.join(workspaceRoot, ".olam", "policies");
|
|
53779
|
+
if (!fs55.existsSync(policiesDir))
|
|
53420
53780
|
return [];
|
|
53421
53781
|
let files;
|
|
53422
53782
|
try {
|
|
53423
|
-
files =
|
|
53783
|
+
files = fs55.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
|
|
53424
53784
|
} catch {
|
|
53425
53785
|
return [];
|
|
53426
53786
|
}
|
|
53427
53787
|
const policies = [];
|
|
53428
53788
|
for (const file2 of files) {
|
|
53429
|
-
const filePath =
|
|
53789
|
+
const filePath = path55.join(policiesDir, file2);
|
|
53430
53790
|
try {
|
|
53431
|
-
const content =
|
|
53791
|
+
const content = fs55.readFileSync(filePath, "utf8");
|
|
53432
53792
|
const parsed = parseFrontmatter2(content);
|
|
53433
53793
|
if (!parsed) {
|
|
53434
53794
|
console.warn(`[policies] skipping ${file2}: no valid frontmatter block`);
|
|
@@ -53572,9 +53932,9 @@ async function autoDispatchTask(opts) {
|
|
|
53572
53932
|
}
|
|
53573
53933
|
|
|
53574
53934
|
// ../core/dist/world/wiki-injection-loader.js
|
|
53575
|
-
import * as
|
|
53576
|
-
import * as
|
|
53577
|
-
import * as
|
|
53935
|
+
import * as fs56 from "node:fs";
|
|
53936
|
+
import * as os28 from "node:os";
|
|
53937
|
+
import * as path56 from "node:path";
|
|
53578
53938
|
var WIKI_INJECTION_FLAG = "OLAM_WIKI_INJECTION";
|
|
53579
53939
|
var WIKI_PATH_ENV = "OLAM_WIKI_PATH";
|
|
53580
53940
|
function flagEnabled(value) {
|
|
@@ -53587,14 +53947,14 @@ function wikiBlobPath() {
|
|
|
53587
53947
|
const override = process.env[WIKI_PATH_ENV];
|
|
53588
53948
|
if (override && override.length > 0)
|
|
53589
53949
|
return override;
|
|
53590
|
-
return
|
|
53950
|
+
return path56.join(os28.homedir(), ".olam", "wiki.json");
|
|
53591
53951
|
}
|
|
53592
53952
|
function defaultReadBlob() {
|
|
53593
53953
|
const p = wikiBlobPath();
|
|
53594
53954
|
try {
|
|
53595
|
-
if (!
|
|
53955
|
+
if (!fs56.existsSync(p))
|
|
53596
53956
|
return null;
|
|
53597
|
-
return
|
|
53957
|
+
return fs56.readFileSync(p, "utf8");
|
|
53598
53958
|
} catch {
|
|
53599
53959
|
return null;
|
|
53600
53960
|
}
|
|
@@ -53633,12 +53993,12 @@ init_store2();
|
|
|
53633
53993
|
init_bridge();
|
|
53634
53994
|
|
|
53635
53995
|
// ../core/dist/global-config/runbook-resolver.js
|
|
53636
|
-
import * as
|
|
53637
|
-
import * as
|
|
53638
|
-
import * as
|
|
53996
|
+
import * as fs57 from "node:fs";
|
|
53997
|
+
import * as os29 from "node:os";
|
|
53998
|
+
import * as path57 from "node:path";
|
|
53639
53999
|
function expandTilde(p) {
|
|
53640
54000
|
if (p === "~" || p.startsWith("~/")) {
|
|
53641
|
-
return
|
|
54001
|
+
return path57.join(os29.homedir(), p.slice(1));
|
|
53642
54002
|
}
|
|
53643
54003
|
return p;
|
|
53644
54004
|
}
|
|
@@ -53650,7 +54010,7 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
|
|
|
53650
54010
|
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.`);
|
|
53651
54011
|
}
|
|
53652
54012
|
const resolvedPath = expandTilde(entry.path);
|
|
53653
|
-
if (!
|
|
54013
|
+
if (!fs57.existsSync(resolvedPath)) {
|
|
53654
54014
|
throw new Error(`repo "${repoName}" path "${resolvedPath}" no longer exists. Run "olam repos update ${repoName} --path <new-path>" to fix.`);
|
|
53655
54015
|
}
|
|
53656
54016
|
}
|
|
@@ -53666,19 +54026,19 @@ function resolveRunbookToWorldParams(runbook, repoRegistry) {
|
|
|
53666
54026
|
init_port_validator();
|
|
53667
54027
|
|
|
53668
54028
|
// ../core/dist/world/bootstrap-hooks.js
|
|
53669
|
-
import * as
|
|
53670
|
-
import * as
|
|
54029
|
+
import * as fs58 from "node:fs";
|
|
54030
|
+
import * as path58 from "node:path";
|
|
53671
54031
|
function runFixtureCopySeeds(seeds, workspacePath) {
|
|
53672
54032
|
if (!seeds)
|
|
53673
54033
|
return;
|
|
53674
54034
|
for (const seed of seeds) {
|
|
53675
54035
|
if (seed.type !== "fixture-copy")
|
|
53676
54036
|
continue;
|
|
53677
|
-
const srcAbs =
|
|
53678
|
-
const destAbs =
|
|
53679
|
-
const destDir =
|
|
53680
|
-
|
|
53681
|
-
|
|
54037
|
+
const srcAbs = path58.resolve(workspacePath, seed.repo, seed.src);
|
|
54038
|
+
const destAbs = path58.resolve(workspacePath, seed.repo, seed.dest);
|
|
54039
|
+
const destDir = path58.dirname(destAbs);
|
|
54040
|
+
fs58.mkdirSync(destDir, { recursive: true });
|
|
54041
|
+
fs58.cpSync(srcAbs, destAbs, { recursive: true, force: true });
|
|
53682
54042
|
}
|
|
53683
54043
|
}
|
|
53684
54044
|
async function runSeedHooks(seeds, containerName, servicePortMap, exec) {
|
|
@@ -54381,7 +54741,7 @@ ${detail}`);
|
|
|
54381
54741
|
runbookSeeds = resolved.seeds;
|
|
54382
54742
|
}
|
|
54383
54743
|
const worldId = generateWorldId();
|
|
54384
|
-
const workspacePath =
|
|
54744
|
+
const workspacePath = path59.join(os30.homedir(), ".olam", "worlds", worldId);
|
|
54385
54745
|
const portOffset = this.registry.getNextPortOffset();
|
|
54386
54746
|
const branch = opts.branchName ?? `olam/${worldId}`;
|
|
54387
54747
|
const repos = await this.resolveReposWithWorkspace(opts);
|
|
@@ -54463,38 +54823,38 @@ ${detail}`);
|
|
|
54463
54823
|
for (const repo of repos) {
|
|
54464
54824
|
if (!repo.path)
|
|
54465
54825
|
continue;
|
|
54466
|
-
const sourceRoot = repo.path.replace(/^~/,
|
|
54467
|
-
const worktreeRoot =
|
|
54468
|
-
if (!
|
|
54826
|
+
const sourceRoot = repo.path.replace(/^~/, os30.homedir());
|
|
54827
|
+
const worktreeRoot = path59.join(workspacePath, repo.name);
|
|
54828
|
+
if (!fs59.existsSync(sourceRoot) || !fs59.existsSync(worktreeRoot))
|
|
54469
54829
|
continue;
|
|
54470
54830
|
let copied = 0;
|
|
54471
54831
|
for (const pattern of RUNTIME_FILE_PATTERNS) {
|
|
54472
54832
|
const matches2 = [];
|
|
54473
54833
|
if (pattern.includes("*")) {
|
|
54474
|
-
const [dir, glob] = [
|
|
54475
|
-
const sourceDir =
|
|
54476
|
-
if (
|
|
54834
|
+
const [dir, glob] = [path59.dirname(pattern), path59.basename(pattern)];
|
|
54835
|
+
const sourceDir = path59.join(sourceRoot, dir);
|
|
54836
|
+
if (fs59.existsSync(sourceDir)) {
|
|
54477
54837
|
const ext = glob.replace(/^\*+/, "");
|
|
54478
54838
|
try {
|
|
54479
|
-
for (const entry of
|
|
54839
|
+
for (const entry of fs59.readdirSync(sourceDir)) {
|
|
54480
54840
|
if (ext === "" || entry.endsWith(ext))
|
|
54481
|
-
matches2.push(
|
|
54841
|
+
matches2.push(path59.join(dir, entry));
|
|
54482
54842
|
}
|
|
54483
54843
|
} catch {
|
|
54484
54844
|
}
|
|
54485
54845
|
}
|
|
54486
|
-
} else if (
|
|
54846
|
+
} else if (fs59.existsSync(path59.join(sourceRoot, pattern))) {
|
|
54487
54847
|
matches2.push(pattern);
|
|
54488
54848
|
}
|
|
54489
54849
|
for (const rel of matches2) {
|
|
54490
|
-
const src =
|
|
54491
|
-
const dst =
|
|
54850
|
+
const src = path59.join(sourceRoot, rel);
|
|
54851
|
+
const dst = path59.join(worktreeRoot, rel);
|
|
54492
54852
|
try {
|
|
54493
|
-
const st =
|
|
54853
|
+
const st = fs59.statSync(src);
|
|
54494
54854
|
if (!st.isFile())
|
|
54495
54855
|
continue;
|
|
54496
|
-
|
|
54497
|
-
|
|
54856
|
+
fs59.mkdirSync(path59.dirname(dst), { recursive: true });
|
|
54857
|
+
fs59.copyFileSync(src, dst);
|
|
54498
54858
|
copied++;
|
|
54499
54859
|
} catch {
|
|
54500
54860
|
}
|
|
@@ -54580,7 +54940,7 @@ ${detail}`);
|
|
|
54580
54940
|
}
|
|
54581
54941
|
const overlayAttachments = [];
|
|
54582
54942
|
for (const repo of repos) {
|
|
54583
|
-
const worldClonePath =
|
|
54943
|
+
const worldClonePath = path59.join(workspacePath, repo.name);
|
|
54584
54944
|
try {
|
|
54585
54945
|
const result = createWorldOverlay({
|
|
54586
54946
|
workspace: repo.name,
|
|
@@ -54635,7 +54995,7 @@ ${detail}`);
|
|
|
54635
54995
|
try {
|
|
54636
54996
|
const hostExec = makeHostExecFn();
|
|
54637
54997
|
for (const repo of repos) {
|
|
54638
|
-
const repoDir =
|
|
54998
|
+
const repoDir = path59.join(workspacePath, repo.name);
|
|
54639
54999
|
if (repo.stack && Object.keys(repo.stack).length > 0) {
|
|
54640
55000
|
preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
|
|
54641
55001
|
} else {
|
|
@@ -54679,10 +55039,10 @@ ${detail}`);
|
|
|
54679
55039
|
const worldEnv = {};
|
|
54680
55040
|
if (opts.task)
|
|
54681
55041
|
worldEnv.OLAM_TASK = opts.task;
|
|
54682
|
-
const r2CredsPath =
|
|
54683
|
-
if (
|
|
55042
|
+
const r2CredsPath = path59.join(os30.homedir(), ".olam", "r2-credentials.json");
|
|
55043
|
+
if (fs59.existsSync(r2CredsPath)) {
|
|
54684
55044
|
try {
|
|
54685
|
-
const r2Raw =
|
|
55045
|
+
const r2Raw = fs59.readFileSync(r2CredsPath, "utf-8").trim();
|
|
54686
55046
|
if (r2Raw.length > 0) {
|
|
54687
55047
|
const r2 = JSON.parse(r2Raw);
|
|
54688
55048
|
if (typeof r2.account_id === "string")
|
|
@@ -54699,10 +55059,10 @@ ${detail}`);
|
|
|
54699
55059
|
} catch {
|
|
54700
55060
|
}
|
|
54701
55061
|
}
|
|
54702
|
-
const keysYamlPath =
|
|
54703
|
-
if (
|
|
55062
|
+
const keysYamlPath = path59.join(os30.homedir(), ".olam", "keys.yaml");
|
|
55063
|
+
if (fs59.existsSync(keysYamlPath)) {
|
|
54704
55064
|
try {
|
|
54705
|
-
const keysRaw =
|
|
55065
|
+
const keysRaw = fs59.readFileSync(keysYamlPath, "utf-8").trim();
|
|
54706
55066
|
if (keysRaw.length > 0) {
|
|
54707
55067
|
const { default: YAML3 } = await import("yaml");
|
|
54708
55068
|
const parsed = YAML3.parse(keysRaw);
|
|
@@ -54762,10 +55122,10 @@ ${detail}`);
|
|
|
54762
55122
|
worldEnv[k] = v;
|
|
54763
55123
|
}
|
|
54764
55124
|
for (const { repoName, relativePath, content } of fileWrites) {
|
|
54765
|
-
const absPath =
|
|
55125
|
+
const absPath = path59.join(workspacePath, repoName, relativePath);
|
|
54766
55126
|
try {
|
|
54767
|
-
|
|
54768
|
-
|
|
55127
|
+
fs59.mkdirSync(path59.dirname(absPath), { recursive: true });
|
|
55128
|
+
fs59.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
|
|
54769
55129
|
mode: 384
|
|
54770
55130
|
});
|
|
54771
55131
|
console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
|
|
@@ -54942,7 +55302,7 @@ ${detail}`);
|
|
|
54942
55302
|
imageDigest: void 0,
|
|
54943
55303
|
repos: enrichedRepos.map((r) => ({
|
|
54944
55304
|
name: r.name,
|
|
54945
|
-
worktreeDir:
|
|
55305
|
+
worktreeDir: path59.join(workspacePath, r.name)
|
|
54946
55306
|
}))
|
|
54947
55307
|
});
|
|
54948
55308
|
for (const out of restoreResult.outcomes) {
|
|
@@ -55048,7 +55408,7 @@ ${detail}`);
|
|
|
55048
55408
|
}
|
|
55049
55409
|
if (opts.task) {
|
|
55050
55410
|
const allPolicies = repos.flatMap((repo) => {
|
|
55051
|
-
const repoWorktree =
|
|
55411
|
+
const repoWorktree = path59.join(workspacePath, repo.name);
|
|
55052
55412
|
try {
|
|
55053
55413
|
return loadPolicies(repoWorktree);
|
|
55054
55414
|
} catch (err) {
|
|
@@ -55061,8 +55421,8 @@ ${detail}`);
|
|
|
55061
55421
|
try {
|
|
55062
55422
|
execSync6(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
|
|
55063
55423
|
for (const repo of repos) {
|
|
55064
|
-
const policiesDir =
|
|
55065
|
-
if (
|
|
55424
|
+
const policiesDir = path59.join(workspacePath, repo.name, ".olam", "policies");
|
|
55425
|
+
if (fs59.existsSync(policiesDir)) {
|
|
55066
55426
|
execSync6(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
|
|
55067
55427
|
}
|
|
55068
55428
|
}
|
|
@@ -55172,8 +55532,8 @@ ${detail}`);
|
|
|
55172
55532
|
} catch {
|
|
55173
55533
|
}
|
|
55174
55534
|
try {
|
|
55175
|
-
|
|
55176
|
-
if (
|
|
55535
|
+
fs59.rmSync(world.workspacePath, { recursive: true, force: true });
|
|
55536
|
+
if (fs59.existsSync(world.workspacePath)) {
|
|
55177
55537
|
console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
|
|
55178
55538
|
}
|
|
55179
55539
|
} catch (err) {
|
|
@@ -55283,14 +55643,14 @@ ${detail}`);
|
|
|
55283
55643
|
}).filter((r) => r !== void 0);
|
|
55284
55644
|
}
|
|
55285
55645
|
transportPlanFile(planFilePath, workspacePath, repoNames) {
|
|
55286
|
-
const planContent =
|
|
55287
|
-
const planFileName =
|
|
55646
|
+
const planContent = fs59.readFileSync(planFilePath, "utf-8");
|
|
55647
|
+
const planFileName = path59.basename(planFilePath);
|
|
55288
55648
|
const targetRepo = repoNames[0];
|
|
55289
55649
|
if (!targetRepo)
|
|
55290
55650
|
return;
|
|
55291
|
-
const plansDir =
|
|
55292
|
-
|
|
55293
|
-
|
|
55651
|
+
const plansDir = path59.join(workspacePath, targetRepo, "docs", "plans");
|
|
55652
|
+
fs59.mkdirSync(plansDir, { recursive: true });
|
|
55653
|
+
fs59.writeFileSync(path59.join(plansDir, planFileName), planContent);
|
|
55294
55654
|
}
|
|
55295
55655
|
resolveServices(repos) {
|
|
55296
55656
|
const services = [];
|
|
@@ -55754,8 +56114,8 @@ import * as http2 from "node:http";
|
|
|
55754
56114
|
|
|
55755
56115
|
// ../core/dist/dashboard/server.js
|
|
55756
56116
|
import * as http from "node:http";
|
|
55757
|
-
import * as
|
|
55758
|
-
import * as
|
|
56117
|
+
import * as fs60 from "node:fs";
|
|
56118
|
+
import * as path60 from "node:path";
|
|
55759
56119
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
55760
56120
|
|
|
55761
56121
|
// ../core/dist/dashboard/serialize.js
|
|
@@ -56090,7 +56450,7 @@ function notFound(res) {
|
|
|
56090
56450
|
}
|
|
56091
56451
|
function openThoughtStore(workspacePath) {
|
|
56092
56452
|
const dbPath = getWorldDbPath(workspacePath);
|
|
56093
|
-
if (!
|
|
56453
|
+
if (!fs60.existsSync(dbPath))
|
|
56094
56454
|
return null;
|
|
56095
56455
|
return new ThoughtLocalStore(dbPath);
|
|
56096
56456
|
}
|
|
@@ -56261,13 +56621,13 @@ function findSessionInWorld(registry2, sessionId) {
|
|
|
56261
56621
|
}
|
|
56262
56622
|
function createDashboardServer(opts) {
|
|
56263
56623
|
const { port: port2, registry: registry2 } = opts;
|
|
56264
|
-
const thisDir =
|
|
56265
|
-
const defaultPublicDir =
|
|
56624
|
+
const thisDir = path60.dirname(fileURLToPath4(import.meta.url));
|
|
56625
|
+
const defaultPublicDir = path60.resolve(thisDir, "../../../control-plane/public");
|
|
56266
56626
|
const publicDir = opts.publicDir ?? defaultPublicDir;
|
|
56267
|
-
let hasPublicDir =
|
|
56627
|
+
let hasPublicDir = fs60.existsSync(publicDir);
|
|
56268
56628
|
const server = http.createServer((req, res) => {
|
|
56269
56629
|
if (!hasPublicDir) {
|
|
56270
|
-
hasPublicDir =
|
|
56630
|
+
hasPublicDir = fs60.existsSync(publicDir);
|
|
56271
56631
|
}
|
|
56272
56632
|
const host = req.headers.host ?? `localhost:${port2}`;
|
|
56273
56633
|
const url3 = new URL(req.url ?? "/", `http://${host}`);
|
|
@@ -56541,22 +56901,22 @@ function createDashboardServer(opts) {
|
|
|
56541
56901
|
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>`);
|
|
56542
56902
|
return;
|
|
56543
56903
|
}
|
|
56544
|
-
let filePath =
|
|
56904
|
+
let filePath = path60.join(publicDir, pathname === "/" ? "index.html" : pathname);
|
|
56545
56905
|
if (!filePath.startsWith(publicDir)) {
|
|
56546
56906
|
notFound(res);
|
|
56547
56907
|
return;
|
|
56548
56908
|
}
|
|
56549
|
-
if (
|
|
56550
|
-
const ext =
|
|
56909
|
+
if (fs60.existsSync(filePath) && fs60.statSync(filePath).isFile()) {
|
|
56910
|
+
const ext = path60.extname(filePath);
|
|
56551
56911
|
const contentType = MIME[ext] ?? "application/octet-stream";
|
|
56552
56912
|
res.writeHead(200, { "Content-Type": contentType });
|
|
56553
|
-
|
|
56913
|
+
fs60.createReadStream(filePath).pipe(res);
|
|
56554
56914
|
return;
|
|
56555
56915
|
}
|
|
56556
|
-
filePath =
|
|
56557
|
-
if (
|
|
56916
|
+
filePath = path60.join(publicDir, "index.html");
|
|
56917
|
+
if (fs60.existsSync(filePath)) {
|
|
56558
56918
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
56559
|
-
|
|
56919
|
+
fs60.createReadStream(filePath).pipe(res);
|
|
56560
56920
|
return;
|
|
56561
56921
|
}
|
|
56562
56922
|
notFound(res);
|
|
@@ -56566,17 +56926,17 @@ function createDashboardServer(opts) {
|
|
|
56566
56926
|
}
|
|
56567
56927
|
|
|
56568
56928
|
// ../core/dist/dashboard/state.js
|
|
56569
|
-
import * as
|
|
56570
|
-
import * as
|
|
56571
|
-
import * as
|
|
56572
|
-
var STATE_PATH =
|
|
56929
|
+
import * as fs61 from "node:fs";
|
|
56930
|
+
import * as os31 from "node:os";
|
|
56931
|
+
import * as path61 from "node:path";
|
|
56932
|
+
var STATE_PATH = path61.join(os31.homedir(), ".olam", "dashboard.json");
|
|
56573
56933
|
function saveDashboardState(state) {
|
|
56574
|
-
|
|
56575
|
-
|
|
56934
|
+
fs61.mkdirSync(path61.dirname(STATE_PATH), { recursive: true });
|
|
56935
|
+
fs61.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
|
|
56576
56936
|
}
|
|
56577
56937
|
function loadDashboardState() {
|
|
56578
56938
|
try {
|
|
56579
|
-
const raw =
|
|
56939
|
+
const raw = fs61.readFileSync(STATE_PATH, "utf-8");
|
|
56580
56940
|
return JSON.parse(raw);
|
|
56581
56941
|
} catch {
|
|
56582
56942
|
return null;
|
|
@@ -56584,7 +56944,7 @@ function loadDashboardState() {
|
|
|
56584
56944
|
}
|
|
56585
56945
|
function clearDashboardState() {
|
|
56586
56946
|
try {
|
|
56587
|
-
|
|
56947
|
+
fs61.unlinkSync(STATE_PATH);
|
|
56588
56948
|
} catch {
|
|
56589
56949
|
}
|
|
56590
56950
|
}
|
|
@@ -56864,8 +57224,8 @@ var PleriClient = class {
|
|
|
56864
57224
|
};
|
|
56865
57225
|
|
|
56866
57226
|
// ../mcp-server/src/env-loader.ts
|
|
56867
|
-
import { readFileSync as
|
|
56868
|
-
import { join as
|
|
57227
|
+
import { readFileSync as readFileSync47, existsSync as existsSync60, statSync as statSync16 } from "node:fs";
|
|
57228
|
+
import { join as join65, dirname as dirname31, resolve as resolve15 } from "node:path";
|
|
56869
57229
|
var PROJECT_MARKERS = [
|
|
56870
57230
|
".olam/config.yaml",
|
|
56871
57231
|
".olam/config.yml",
|
|
@@ -56877,12 +57237,12 @@ function findProjectRoot2(startDir) {
|
|
|
56877
57237
|
const root = resolve15("/");
|
|
56878
57238
|
while (true) {
|
|
56879
57239
|
for (const marker of PROJECT_MARKERS) {
|
|
56880
|
-
if (
|
|
57240
|
+
if (existsSync60(join65(dir, marker))) return dir;
|
|
56881
57241
|
}
|
|
56882
|
-
const pkg =
|
|
56883
|
-
if (
|
|
57242
|
+
const pkg = join65(dir, "package.json");
|
|
57243
|
+
if (existsSync60(pkg)) {
|
|
56884
57244
|
try {
|
|
56885
|
-
const json2 = JSON.parse(
|
|
57245
|
+
const json2 = JSON.parse(readFileSync47(pkg, "utf8"));
|
|
56886
57246
|
const isOlamWorkspace = typeof json2.name === "string" && json2.name.startsWith("@olam/");
|
|
56887
57247
|
const hasOlamDep = json2.dependencies && Object.keys(json2.dependencies).some((k) => k.startsWith("@olam/")) || json2.devDependencies && Object.keys(json2.devDependencies).some((k) => k.startsWith("@olam/"));
|
|
56888
57248
|
if (isOlamWorkspace || hasOlamDep) return dir;
|
|
@@ -56894,9 +57254,9 @@ function findProjectRoot2(startDir) {
|
|
|
56894
57254
|
dir = parent;
|
|
56895
57255
|
}
|
|
56896
57256
|
}
|
|
56897
|
-
function parseEnvFile(
|
|
57257
|
+
function parseEnvFile(path62) {
|
|
56898
57258
|
const out = {};
|
|
56899
|
-
const raw =
|
|
57259
|
+
const raw = readFileSync47(path62, "utf8");
|
|
56900
57260
|
for (const line of raw.split(/\r?\n/)) {
|
|
56901
57261
|
const trimmed = line.trim();
|
|
56902
57262
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -56919,8 +57279,8 @@ function loadProjectEnv(startDir = process.cwd()) {
|
|
|
56919
57279
|
const filesRead = [];
|
|
56920
57280
|
const merged = {};
|
|
56921
57281
|
for (const name of [".env", ".env.local"]) {
|
|
56922
|
-
const p =
|
|
56923
|
-
if (
|
|
57282
|
+
const p = join65(root, name);
|
|
57283
|
+
if (existsSync60(p) && statSync16(p).isFile()) {
|
|
56924
57284
|
Object.assign(merged, parseEnvFile(p));
|
|
56925
57285
|
filesRead.push(p);
|
|
56926
57286
|
}
|