@pleri/olam-cli 0.1.169 → 0.1.170
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/README.md +38 -0
- package/dist/commands/auth-status.d.ts +1 -0
- package/dist/commands/auth-status.d.ts.map +1 -1
- package/dist/commands/auth-status.js +45 -4
- package/dist/commands/auth-status.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +26 -0
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/enter.d.ts.map +1 -1
- package/dist/commands/enter.js +5 -0
- package/dist/commands/enter.js.map +1 -1
- package/dist/commands/resume.d.ts +63 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +174 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/setup.d.ts +19 -0
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +157 -19
- package/dist/commands/setup.js.map +1 -1
- package/dist/image-digests.json +8 -8
- package/dist/index.js +1021 -576
- package/dist/index.js.map +1 -1
- package/dist/lib/health-probes.d.ts +28 -0
- package/dist/lib/health-probes.d.ts.map +1 -1
- package/dist/lib/health-probes.js +75 -0
- package/dist/lib/health-probes.js.map +1 -1
- package/dist/lib/k8s-context-discovery.d.ts +80 -0
- package/dist/lib/k8s-context-discovery.d.ts.map +1 -0
- package/dist/lib/k8s-context-discovery.js +102 -0
- package/dist/lib/k8s-context-discovery.js.map +1 -0
- package/dist/mcp-server.js +1273 -771
- package/dist/spawn/home-override.d.ts +82 -0
- package/dist/spawn/home-override.d.ts.map +1 -0
- package/dist/spawn/home-override.js +107 -0
- package/dist/spawn/home-override.js.map +1 -0
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/manifests/30-configmap.yaml +5 -0
- package/host-cp/k8s/manifests/50-deployment.yaml +9 -2
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
- package/host-cp/lifecycle/classify.mjs +110 -0
- package/host-cp/lifecycle/emit.mjs +119 -0
- package/host-cp/lifecycle/evidence.mjs +45 -0
- package/host-cp/lifecycle/failure-kinds.mjs +56 -0
- package/host-cp/lifecycle/index.mjs +22 -0
- package/host-cp/lifecycle/phases.mjs +52 -0
- package/host-cp/observability/grafana-port-forward.sh +1 -1
- package/host-cp/observability/kyverno-cardinality-mutate.sh +2 -2
- package/host-cp/observability/loki-ingest.sh +1 -1
- package/host-cp/observability/ndjson-span-sink.mjs +131 -0
- package/host-cp/observability/prom-no-double-grafana.sh +4 -4
- package/host-cp/observability/redactor.mjs +72 -0
- package/host-cp/recovery/engine.mjs +148 -0
- package/host-cp/recovery/index.mjs +16 -0
- package/host-cp/recovery/ledger.mjs +105 -0
- package/host-cp/recovery/recipes.mjs +46 -0
- package/host-cp/recovery/scenarios.mjs +124 -0
- package/host-cp/recovery/step-runners.mjs +263 -0
- package/host-cp/src/docker-events.mjs +30 -6
- package/host-cp/src/pr-nanny.mjs +55 -3
- package/host-cp/src/server.mjs +173 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -492,8 +492,8 @@ var init_parseUtil = __esm({
|
|
|
492
492
|
init_errors();
|
|
493
493
|
init_en();
|
|
494
494
|
makeIssue = (params) => {
|
|
495
|
-
const { data, path:
|
|
496
|
-
const fullPath = [...
|
|
495
|
+
const { data, path: path96, errorMaps, issueData } = params;
|
|
496
|
+
const fullPath = [...path96, ...issueData.path || []];
|
|
497
497
|
const fullIssue = {
|
|
498
498
|
...issueData,
|
|
499
499
|
path: fullPath
|
|
@@ -801,11 +801,11 @@ var init_types = __esm({
|
|
|
801
801
|
init_parseUtil();
|
|
802
802
|
init_util();
|
|
803
803
|
ParseInputLazyPath = class {
|
|
804
|
-
constructor(parent, value,
|
|
804
|
+
constructor(parent, value, path96, key) {
|
|
805
805
|
this._cachedPath = [];
|
|
806
806
|
this.parent = parent;
|
|
807
807
|
this.data = value;
|
|
808
|
-
this._path =
|
|
808
|
+
this._path = path96;
|
|
809
809
|
this._key = key;
|
|
810
810
|
}
|
|
811
811
|
get path() {
|
|
@@ -4286,7 +4286,7 @@ import YAML from "yaml";
|
|
|
4286
4286
|
function bootstrapStepCmd(entry) {
|
|
4287
4287
|
return typeof entry === "string" ? entry : entry.cmd;
|
|
4288
4288
|
}
|
|
4289
|
-
function refineForbiddenKeys(value,
|
|
4289
|
+
function refineForbiddenKeys(value, path96, ctx, rejectSource) {
|
|
4290
4290
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
4291
4291
|
return;
|
|
4292
4292
|
}
|
|
@@ -4294,12 +4294,12 @@ function refineForbiddenKeys(value, path95, ctx, rejectSource) {
|
|
|
4294
4294
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
4295
4295
|
ctx.addIssue({
|
|
4296
4296
|
code: external_exports.ZodIssueCode.custom,
|
|
4297
|
-
path: [...
|
|
4297
|
+
path: [...path96, key],
|
|
4298
4298
|
message: `forbidden key "${key}" (prototype-pollution surface)`
|
|
4299
4299
|
});
|
|
4300
4300
|
continue;
|
|
4301
4301
|
}
|
|
4302
|
-
if (rejectSource &&
|
|
4302
|
+
if (rejectSource && path96.length === 0 && key === "source") {
|
|
4303
4303
|
ctx.addIssue({
|
|
4304
4304
|
code: external_exports.ZodIssueCode.custom,
|
|
4305
4305
|
path: ["source"],
|
|
@@ -4307,21 +4307,21 @@ function refineForbiddenKeys(value, path95, ctx, rejectSource) {
|
|
|
4307
4307
|
});
|
|
4308
4308
|
continue;
|
|
4309
4309
|
}
|
|
4310
|
-
refineForbiddenKeys(value[key], [...
|
|
4310
|
+
refineForbiddenKeys(value[key], [...path96, key], ctx, false);
|
|
4311
4311
|
}
|
|
4312
4312
|
}
|
|
4313
|
-
function rejectForbiddenKeys(value,
|
|
4313
|
+
function rejectForbiddenKeys(value, path96, rejectSource) {
|
|
4314
4314
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
4315
4315
|
return;
|
|
4316
4316
|
}
|
|
4317
4317
|
for (const key of Object.keys(value)) {
|
|
4318
4318
|
if (FORBIDDEN_KEYS.has(key)) {
|
|
4319
|
-
throw new Error(`[manifest] ${
|
|
4319
|
+
throw new Error(`[manifest] ${path96}: forbidden key "${key}" (prototype-pollution surface)`);
|
|
4320
4320
|
}
|
|
4321
4321
|
if (rejectSource && key === "source") {
|
|
4322
|
-
throw new Error(`[manifest] ${
|
|
4322
|
+
throw new Error(`[manifest] ${path96}: top-level "source" is loader-stamped \u2014 manifests must not author it`);
|
|
4323
4323
|
}
|
|
4324
|
-
rejectForbiddenKeys(value[key], `${
|
|
4324
|
+
rejectForbiddenKeys(value[key], `${path96}.${key}`, false);
|
|
4325
4325
|
}
|
|
4326
4326
|
}
|
|
4327
4327
|
function unknownTopLevelKeys(parsed) {
|
|
@@ -4860,7 +4860,13 @@ var init_schema2 = __esm({
|
|
|
4860
4860
|
user: external_exports.string().min(1),
|
|
4861
4861
|
key: external_exports.string().optional()
|
|
4862
4862
|
});
|
|
4863
|
-
computeProviderType = external_exports.enum([
|
|
4863
|
+
computeProviderType = external_exports.enum([
|
|
4864
|
+
"docker",
|
|
4865
|
+
"ssh",
|
|
4866
|
+
"e2b",
|
|
4867
|
+
"cloudflare",
|
|
4868
|
+
"cloudflare-isolate"
|
|
4869
|
+
]);
|
|
4864
4870
|
stackImageSchema = external_exports.object({
|
|
4865
4871
|
enabled: external_exports.boolean().optional().default(true),
|
|
4866
4872
|
auto_commit: external_exports.boolean().optional().default(true),
|
|
@@ -4872,6 +4878,15 @@ var init_schema2 = __esm({
|
|
|
4872
4878
|
}).optional(),
|
|
4873
4879
|
ssh: external_exports.object({ hosts: external_exports.array(sshHostSchema).optional() }).optional(),
|
|
4874
4880
|
e2b: external_exports.object({ template: external_exports.string().optional() }).optional(),
|
|
4881
|
+
// V8-isolate runtime tier per ADR 022. Pure isolate, no DO, no Container.
|
|
4882
|
+
// worker_url points at the deployed olam-worker-runner-isolate Worker.
|
|
4883
|
+
// Same https-or-localhost guard as the cloudflare profile — bearer token
|
|
4884
|
+
// in cleartext would leak the OLAM_TASK_TOKEN.
|
|
4885
|
+
"cloudflare-isolate": external_exports.object({
|
|
4886
|
+
worker_url: external_exports.string().url("worker_url must be a valid URL").refine(isSecureOrLocalhost, {
|
|
4887
|
+
message: "worker_url must use https:// (or http://localhost for dev)"
|
|
4888
|
+
}).optional()
|
|
4889
|
+
}).optional(),
|
|
4875
4890
|
cloudflare: external_exports.object({
|
|
4876
4891
|
account_id: external_exports.string().optional(),
|
|
4877
4892
|
// https-only refine: bare http:// would send the operator's Pylon
|
|
@@ -5500,8 +5515,8 @@ var init_client = __esm({
|
|
|
5500
5515
|
throw new Error(`failed to report rate-limit for ${accountId} (HTTP ${res.status})`);
|
|
5501
5516
|
}
|
|
5502
5517
|
}
|
|
5503
|
-
async request(method,
|
|
5504
|
-
const url2 = `${this.baseUrl}${
|
|
5518
|
+
async request(method, path96, body, attempt = 0) {
|
|
5519
|
+
const url2 = `${this.baseUrl}${path96}`;
|
|
5505
5520
|
const controller = new AbortController();
|
|
5506
5521
|
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
5507
5522
|
const headers = {};
|
|
@@ -5519,7 +5534,7 @@ var init_client = __esm({
|
|
|
5519
5534
|
} catch (err) {
|
|
5520
5535
|
if (attempt < RETRY_COUNT && isTransient(err)) {
|
|
5521
5536
|
await sleep(RETRY_BACKOFF_MS * (attempt + 1));
|
|
5522
|
-
return this.request(method,
|
|
5537
|
+
return this.request(method, path96, body, attempt + 1);
|
|
5523
5538
|
}
|
|
5524
5539
|
throw err;
|
|
5525
5540
|
} finally {
|
|
@@ -7322,8 +7337,8 @@ var init_provider3 = __esm({
|
|
|
7322
7337
|
// -----------------------------------------------------------------------
|
|
7323
7338
|
// Internal fetch helper
|
|
7324
7339
|
// -----------------------------------------------------------------------
|
|
7325
|
-
async request(
|
|
7326
|
-
const url2 = `${this.config.workerUrl}${
|
|
7340
|
+
async request(path96, method, body) {
|
|
7341
|
+
const url2 = `${this.config.workerUrl}${path96}`;
|
|
7327
7342
|
const bearer = await this.config.mintToken();
|
|
7328
7343
|
const headers = {
|
|
7329
7344
|
Authorization: `Bearer ${bearer}`
|
|
@@ -7884,6 +7899,46 @@ function hasImageRef(present, ref) {
|
|
|
7884
7899
|
const variants = [`docker.io/library/${ref}`, `docker.io/${ref}`];
|
|
7885
7900
|
return variants.some((v) => present.has(v));
|
|
7886
7901
|
}
|
|
7902
|
+
function probeColimaKubernetesEnabled(opts) {
|
|
7903
|
+
const { platform: platform2, home } = opts;
|
|
7904
|
+
const colimaProfile = opts.colimaProfile ?? process.env.COLIMA_PROFILE ?? "default";
|
|
7905
|
+
const readFileFn = opts.readFileFn ?? ((p, enc) => readFileSync13(p, enc));
|
|
7906
|
+
const existsFn = opts.existsFn ?? existsSync13;
|
|
7907
|
+
if (platform2 !== "darwin") {
|
|
7908
|
+
return { ok: true, message: "colima k8s lint: not darwin, skip" };
|
|
7909
|
+
}
|
|
7910
|
+
const colimaYamlPath = path12.join(home, ".colima", colimaProfile, "colima.yaml");
|
|
7911
|
+
if (!existsFn(colimaYamlPath)) {
|
|
7912
|
+
return { ok: true, message: `colima k8s lint: ${colimaYamlPath} not found, skip` };
|
|
7913
|
+
}
|
|
7914
|
+
let yaml;
|
|
7915
|
+
try {
|
|
7916
|
+
yaml = readFileFn(colimaYamlPath, "utf8");
|
|
7917
|
+
} catch {
|
|
7918
|
+
return { ok: true, message: `colima k8s lint: could not read ${colimaYamlPath}` };
|
|
7919
|
+
}
|
|
7920
|
+
const kubernetesSection = yaml.split(/^kubernetes:/m)[1];
|
|
7921
|
+
if (!kubernetesSection) {
|
|
7922
|
+
return { ok: true, message: "colima k8s lint: no kubernetes section found" };
|
|
7923
|
+
}
|
|
7924
|
+
const sectionLines = kubernetesSection.split("\n");
|
|
7925
|
+
const sectionBody2 = [];
|
|
7926
|
+
for (const line of sectionLines) {
|
|
7927
|
+
if (line.length > 0 && !/^\s/.test(line)) break;
|
|
7928
|
+
sectionBody2.push(line);
|
|
7929
|
+
}
|
|
7930
|
+
const section = sectionBody2.join("\n");
|
|
7931
|
+
const enabled = /^\s+enabled:\s*true\s*$/m.test(section);
|
|
7932
|
+
if (!enabled) {
|
|
7933
|
+
return { ok: true, message: "colima k8s lint: kubernetes.enabled is not true" };
|
|
7934
|
+
}
|
|
7935
|
+
return {
|
|
7936
|
+
ok: true,
|
|
7937
|
+
warn: true,
|
|
7938
|
+
message: `Colima has Kubernetes mode enabled at profile '${colimaProfile}'`,
|
|
7939
|
+
remedy: `Colima has Kubernetes mode enabled at profile '${colimaProfile}'. k3d will attempt to coexist but may fail to start with 'context deadline exceeded' due to port conflicts. To fix: \`colima stop && colima start --kubernetes=false\`, OR re-run \`olam setup --reuse-cluster=colima\` to use Colima's existing k3s.`
|
|
7940
|
+
};
|
|
7941
|
+
}
|
|
7887
7942
|
async function probeKubectl(exec = defaultDockerExec) {
|
|
7888
7943
|
const r = exec("kubectl", ["version", "--client", "--output=json"]);
|
|
7889
7944
|
if (r.status === 0 && r.stdout.length > 0) {
|
|
@@ -8104,7 +8159,8 @@ function rowToMetadata(row) {
|
|
|
8104
8159
|
...expectedServices !== void 0 ? { expectedServices } : {},
|
|
8105
8160
|
...appPortUrls !== void 0 ? { appPortUrls } : {},
|
|
8106
8161
|
...worldDbNames !== void 0 ? { worldDbNames } : {},
|
|
8107
|
-
...row.world_role_name ? { worldRoleName: row.world_role_name } : {}
|
|
8162
|
+
...row.world_role_name ? { worldRoleName: row.world_role_name } : {},
|
|
8163
|
+
...row.claude_home ? { claudeHome: row.claude_home } : {}
|
|
8108
8164
|
};
|
|
8109
8165
|
}
|
|
8110
8166
|
var _require, _Database, SCHEMA_VERSION, CREATE_TABLE, CREATE_META, WorldRegistry;
|
|
@@ -8165,7 +8221,9 @@ CREATE TABLE IF NOT EXISTS meta (
|
|
|
8165
8221
|
// world_db_names (SQLite has no native array; matches repos column shape).
|
|
8166
8222
|
// TEXT[] would fail at DDL time (closes OQ13/OQ22 / FS-03).
|
|
8167
8223
|
"world_db_names TEXT",
|
|
8168
|
-
"world_role_name TEXT"
|
|
8224
|
+
"world_role_name TEXT",
|
|
8225
|
+
// ADR 045 — per-world Claude Code HOME path. Additive migration.
|
|
8226
|
+
"claude_home TEXT"
|
|
8169
8227
|
]) {
|
|
8170
8228
|
try {
|
|
8171
8229
|
this.db.exec(`ALTER TABLE worlds ADD COLUMN ${col}`);
|
|
@@ -8196,8 +8254,8 @@ CREATE TABLE IF NOT EXISTS meta (
|
|
|
8196
8254
|
compute_provider, total_cost_usd, thought_count, created_at, updated_at,
|
|
8197
8255
|
pr_url, pr_number, pr_repo, pr_created_at, pr_state, pr_merged_at, auto_destroy_on_merge,
|
|
8198
8256
|
readiness_chain, expected_services, app_port_urls,
|
|
8199
|
-
world_db_names, world_role_name)
|
|
8200
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(world.id, world.name, world.status, JSON.stringify(world.repos), world.branch, world.portOffset, world.workspacePath, world.computeProvider, world.totalCostUsd, world.thoughtCount, world.createdAt, world.updatedAt, world.prUrl ?? null, world.prNumber ?? null, world.prRepo ?? null, world.prCreatedAt ?? null, world.prState ?? "none", world.prMergedAt ?? null, world.autoDestroyOnMerge === false ? 0 : 1, world.readinessChain !== void 0 ? JSON.stringify(world.readinessChain) : null, world.expectedServices !== void 0 ? JSON.stringify(world.expectedServices) : null, world.appPortUrls !== void 0 ? JSON.stringify(world.appPortUrls) : null, world.worldDbNames !== void 0 ? JSON.stringify(world.worldDbNames) : null, world.worldRoleName ?? null);
|
|
8257
|
+
world_db_names, world_role_name, claude_home)
|
|
8258
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(world.id, world.name, world.status, JSON.stringify(world.repos), world.branch, world.portOffset, world.workspacePath, world.computeProvider, world.totalCostUsd, world.thoughtCount, world.createdAt, world.updatedAt, world.prUrl ?? null, world.prNumber ?? null, world.prRepo ?? null, world.prCreatedAt ?? null, world.prState ?? "none", world.prMergedAt ?? null, world.autoDestroyOnMerge === false ? 0 : 1, world.readinessChain !== void 0 ? JSON.stringify(world.readinessChain) : null, world.expectedServices !== void 0 ? JSON.stringify(world.expectedServices) : null, world.appPortUrls !== void 0 ? JSON.stringify(world.appPortUrls) : null, world.worldDbNames !== void 0 ? JSON.stringify(world.worldDbNames) : null, world.worldRoleName ?? null, world.claudeHome ?? null);
|
|
8201
8259
|
}
|
|
8202
8260
|
update(worldId, updates) {
|
|
8203
8261
|
const setClauses = [];
|
|
@@ -8225,7 +8283,9 @@ CREATE TABLE IF NOT EXISTS meta (
|
|
|
8225
8283
|
appPortUrls: "app_port_urls",
|
|
8226
8284
|
// olam-hybrid-shared-postgres Phase A task A7.
|
|
8227
8285
|
worldDbNames: "world_db_names",
|
|
8228
|
-
worldRoleName: "world_role_name"
|
|
8286
|
+
worldRoleName: "world_role_name",
|
|
8287
|
+
// ADR 045 — per-world Claude Code HOME (multi-account isolation).
|
|
8288
|
+
claudeHome: "claude_home"
|
|
8229
8289
|
};
|
|
8230
8290
|
const jsonColumns = /* @__PURE__ */ new Set(["repos", "readinessChain", "expectedServices", "appPortUrls", "worldDbNames"]);
|
|
8231
8291
|
for (const [key, col] of Object.entries(columnMap)) {
|
|
@@ -8922,9 +8982,9 @@ function buildRepoEnvBundle(repoName, serviceEnv, crossRepoEnv, envOverrides) {
|
|
|
8922
8982
|
const merged = { ...serviceEnv, ...injectables };
|
|
8923
8983
|
return { merged, injectables };
|
|
8924
8984
|
}
|
|
8925
|
-
function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, configCtx) {
|
|
8985
|
+
function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, configCtx, claudeHomeOverride) {
|
|
8926
8986
|
try {
|
|
8927
|
-
copyClaudeConfig(workspacePath,
|
|
8987
|
+
copyClaudeConfig(workspacePath, claudeHomeOverride, configCtx);
|
|
8928
8988
|
} catch {
|
|
8929
8989
|
}
|
|
8930
8990
|
if (configCtx) {
|
|
@@ -9124,17 +9184,17 @@ function kgRoot() {
|
|
|
9124
9184
|
function worldsRoot() {
|
|
9125
9185
|
return join17(olamHome(), "worlds");
|
|
9126
9186
|
}
|
|
9127
|
-
function assertWithinPrefix(
|
|
9128
|
-
if (!
|
|
9129
|
-
throw new Error(`${label} escape: ${
|
|
9187
|
+
function assertWithinPrefix(path96, prefix, label) {
|
|
9188
|
+
if (!path96.startsWith(prefix + "/")) {
|
|
9189
|
+
throw new Error(`${label} escape: ${path96} not under ${prefix}/`);
|
|
9130
9190
|
}
|
|
9131
9191
|
}
|
|
9132
9192
|
function kgPristinePath(workspace) {
|
|
9133
9193
|
validateWorkspaceName(workspace);
|
|
9134
9194
|
const root = kgRoot();
|
|
9135
|
-
const
|
|
9136
|
-
assertWithinPrefix(
|
|
9137
|
-
return
|
|
9195
|
+
const path96 = resolve6(join17(root, workspace));
|
|
9196
|
+
assertWithinPrefix(path96, root, "kgPristinePath");
|
|
9197
|
+
return path96;
|
|
9138
9198
|
}
|
|
9139
9199
|
var KG_PATHS_INTERNALS;
|
|
9140
9200
|
var init_storage_paths = __esm({
|
|
@@ -9249,8 +9309,8 @@ import { execFileSync as execFileSync4 } from "node:child_process";
|
|
|
9249
9309
|
import * as fs15 from "node:fs";
|
|
9250
9310
|
import * as os9 from "node:os";
|
|
9251
9311
|
import * as path17 from "node:path";
|
|
9252
|
-
function expandHome2(p,
|
|
9253
|
-
return p.replace(/^~(?=$|\/|\\)/,
|
|
9312
|
+
function expandHome2(p, homedir64) {
|
|
9313
|
+
return p.replace(/^~(?=$|\/|\\)/, homedir64());
|
|
9254
9314
|
}
|
|
9255
9315
|
function sanitizeRepoFilename(name) {
|
|
9256
9316
|
const sanitized = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
@@ -9273,7 +9333,7 @@ ${stderr}`;
|
|
|
9273
9333
|
}
|
|
9274
9334
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
9275
9335
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync4(cmd, args, opts));
|
|
9276
|
-
const
|
|
9336
|
+
const homedir64 = deps.homedir ?? (() => os9.homedir());
|
|
9277
9337
|
const baselineDir = path17.join(workspacePath, ".olam", "baseline");
|
|
9278
9338
|
try {
|
|
9279
9339
|
fs15.mkdirSync(baselineDir, { recursive: true });
|
|
@@ -9289,7 +9349,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
9289
9349
|
continue;
|
|
9290
9350
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
9291
9351
|
const outPath = path17.join(baselineDir, filename);
|
|
9292
|
-
const repoPath = expandHome2(repo.path,
|
|
9352
|
+
const repoPath = expandHome2(repo.path, homedir64);
|
|
9293
9353
|
if (!fs15.existsSync(repoPath)) {
|
|
9294
9354
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
9295
9355
|
# (skipped: path ${repoPath} does not exist)
|
|
@@ -9409,7 +9469,7 @@ function extractStderr(err) {
|
|
|
9409
9469
|
}
|
|
9410
9470
|
function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
9411
9471
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync4(cmd, args, opts));
|
|
9412
|
-
const
|
|
9472
|
+
const homedir64 = deps.homedir ?? (() => os9.homedir());
|
|
9413
9473
|
const existsSync113 = deps.existsSync ?? ((p) => fs15.existsSync(p));
|
|
9414
9474
|
const copyFileSync16 = deps.copyFileSync ?? ((src, dest) => fs15.copyFileSync(src, dest));
|
|
9415
9475
|
const mkdirSync67 = deps.mkdirSync ?? ((dirPath, opts) => {
|
|
@@ -9419,7 +9479,7 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
9419
9479
|
for (const repo of repos) {
|
|
9420
9480
|
if (!repo.path)
|
|
9421
9481
|
continue;
|
|
9422
|
-
const repoPath = expandHome2(repo.path,
|
|
9482
|
+
const repoPath = expandHome2(repo.path, homedir64);
|
|
9423
9483
|
const worktreePath = path17.join(workspacePath, repo.name);
|
|
9424
9484
|
if (!existsSync113(repoPath))
|
|
9425
9485
|
continue;
|
|
@@ -12692,7 +12752,8 @@ ${detail}`);
|
|
|
12692
12752
|
createdAt: now,
|
|
12693
12753
|
updatedAt: now,
|
|
12694
12754
|
readinessChain,
|
|
12695
|
-
expectedServices
|
|
12755
|
+
expectedServices,
|
|
12756
|
+
...opts.claudeHome ? { claudeHome: opts.claudeHome } : {}
|
|
12696
12757
|
};
|
|
12697
12758
|
const sm = new WorldStateMachine(worldId, "creating");
|
|
12698
12759
|
this.registry.register(metadata);
|
|
@@ -12830,7 +12891,7 @@ ${detail}`);
|
|
|
12830
12891
|
worlds_default: this.config.worlds_default,
|
|
12831
12892
|
repos: enrichedRepos
|
|
12832
12893
|
};
|
|
12833
|
-
setupWorldEnv(enrichedRepos, workspacePath, serviceEnv, crossRepoEnv, configCtx);
|
|
12894
|
+
setupWorldEnv(enrichedRepos, workspacePath, serviceEnv, crossRepoEnv, configCtx, opts.claudeHome);
|
|
12834
12895
|
} catch (err) {
|
|
12835
12896
|
const msg = err instanceof Error ? err.message : String(err);
|
|
12836
12897
|
console.warn(`[WorldManager] env setup failed: ${msg}`);
|
|
@@ -15704,10 +15765,10 @@ async function readHostCpToken2() {
|
|
|
15704
15765
|
if (!fs26.existsSync(tp)) return null;
|
|
15705
15766
|
return fs26.readFileSync(tp, "utf-8").trim();
|
|
15706
15767
|
}
|
|
15707
|
-
async function callHostCpProxy(method, worldId,
|
|
15768
|
+
async function callHostCpProxy(method, worldId, path96, body) {
|
|
15708
15769
|
const token = await readHostCpToken2();
|
|
15709
15770
|
if (!token) return { ok: false, status: 0, error: "no token (host CP not started)" };
|
|
15710
|
-
const url2 = `http://127.0.0.1:${HOST_CP_PORT}/api/world/${encodeURIComponent(worldId)}${
|
|
15771
|
+
const url2 = `http://127.0.0.1:${HOST_CP_PORT}/api/world/${encodeURIComponent(worldId)}${path96}`;
|
|
15711
15772
|
try {
|
|
15712
15773
|
const headers = {
|
|
15713
15774
|
Authorization: `Bearer ${token}`
|
|
@@ -16174,17 +16235,75 @@ var init_registry_allowlist = __esm({
|
|
|
16174
16235
|
}
|
|
16175
16236
|
});
|
|
16176
16237
|
|
|
16238
|
+
// src/spawn/home-override.ts
|
|
16239
|
+
var home_override_exports = {};
|
|
16240
|
+
__export(home_override_exports, {
|
|
16241
|
+
CLAUDE_HOMES_BASE: () => CLAUDE_HOMES_BASE,
|
|
16242
|
+
HOME_ID_RE: () => HOME_ID_RE,
|
|
16243
|
+
SENTINEL_FILENAME: () => SENTINEL_FILENAME,
|
|
16244
|
+
ensureClaudeHomeDir: () => ensureClaudeHomeDir,
|
|
16245
|
+
resolveClaudeHome: () => resolveClaudeHome
|
|
16246
|
+
});
|
|
16247
|
+
import { mkdir, writeFile, access } from "node:fs/promises";
|
|
16248
|
+
import { homedir as homedir22 } from "node:os";
|
|
16249
|
+
import path36 from "node:path";
|
|
16250
|
+
function resolveClaudeHome(args) {
|
|
16251
|
+
const home = args.homeDir ?? homedir22();
|
|
16252
|
+
if (args.flag !== void 0 && args.flag.length > 0) {
|
|
16253
|
+
return resolveSpec(args.flag, home);
|
|
16254
|
+
}
|
|
16255
|
+
const stored = args.existingWorldConfig?.claudeHome;
|
|
16256
|
+
if (stored !== void 0 && stored.length > 0) {
|
|
16257
|
+
return resolveSpec(stored, home);
|
|
16258
|
+
}
|
|
16259
|
+
return args.envHome ?? home;
|
|
16260
|
+
}
|
|
16261
|
+
function resolveSpec(spec, home) {
|
|
16262
|
+
if (path36.isAbsolute(spec)) {
|
|
16263
|
+
return spec;
|
|
16264
|
+
}
|
|
16265
|
+
if (!HOME_ID_RE.test(spec)) {
|
|
16266
|
+
throw new Error(
|
|
16267
|
+
`--claude-home value "${spec}" must be either an absolute path or a bare id matching ${HOME_ID_RE} (alphanumeric, underscore, dash; starts with alphanumeric; max 64 chars). Rejected: relative paths, parent refs, uppercase, whitespace.`
|
|
16268
|
+
);
|
|
16269
|
+
}
|
|
16270
|
+
return path36.join(home, CLAUDE_HOMES_BASE, spec);
|
|
16271
|
+
}
|
|
16272
|
+
async function ensureClaudeHomeDir(targetPath) {
|
|
16273
|
+
await mkdir(targetPath, { recursive: true });
|
|
16274
|
+
const sentinelPath2 = path36.join(targetPath, SENTINEL_FILENAME);
|
|
16275
|
+
try {
|
|
16276
|
+
await access(sentinelPath2);
|
|
16277
|
+
return;
|
|
16278
|
+
} catch {
|
|
16279
|
+
}
|
|
16280
|
+
await writeFile(
|
|
16281
|
+
sentinelPath2,
|
|
16282
|
+
"# olam claude-home \u2014 managed by `olam create --claude-home`.\n# Do not delete. Re-create by running `olam create --claude-home <id>` again.\n",
|
|
16283
|
+
"utf-8"
|
|
16284
|
+
);
|
|
16285
|
+
}
|
|
16286
|
+
var CLAUDE_HOMES_BASE, SENTINEL_FILENAME, HOME_ID_RE;
|
|
16287
|
+
var init_home_override = __esm({
|
|
16288
|
+
"src/spawn/home-override.ts"() {
|
|
16289
|
+
"use strict";
|
|
16290
|
+
CLAUDE_HOMES_BASE = path36.join(".olam", "claude-homes");
|
|
16291
|
+
SENTINEL_FILENAME = ".olam-claude-home";
|
|
16292
|
+
HOME_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
16293
|
+
}
|
|
16294
|
+
});
|
|
16295
|
+
|
|
16177
16296
|
// ../core/dist/world/world-yaml.js
|
|
16178
16297
|
import * as fs35 from "node:fs";
|
|
16179
|
-
import * as
|
|
16298
|
+
import * as path37 from "node:path";
|
|
16180
16299
|
import { parse as parseYaml4, stringify as stringifyYaml4 } from "yaml";
|
|
16181
16300
|
function writeWorldYaml(worldPath, data) {
|
|
16182
|
-
const olamDir =
|
|
16301
|
+
const olamDir = path37.join(worldPath, ".olam");
|
|
16183
16302
|
fs35.mkdirSync(olamDir, { recursive: true });
|
|
16184
|
-
fs35.writeFileSync(
|
|
16303
|
+
fs35.writeFileSync(path37.join(olamDir, "world.yaml"), stringifyYaml4(data), "utf-8");
|
|
16185
16304
|
}
|
|
16186
16305
|
function readWorldYaml(worldPath) {
|
|
16187
|
-
const yamlPath =
|
|
16306
|
+
const yamlPath = path37.join(worldPath, ".olam", "world.yaml");
|
|
16188
16307
|
if (!fs35.existsSync(yamlPath))
|
|
16189
16308
|
return null;
|
|
16190
16309
|
try {
|
|
@@ -16313,14 +16432,14 @@ var init_checksum = __esm({
|
|
|
16313
16432
|
|
|
16314
16433
|
// ../core/dist/skill-sources/trust-audit-log.js
|
|
16315
16434
|
import * as fs52 from "node:fs";
|
|
16316
|
-
import * as
|
|
16435
|
+
import * as path55 from "node:path";
|
|
16317
16436
|
import * as os28 from "node:os";
|
|
16318
16437
|
function skillSourcesAuditLogPath() {
|
|
16319
16438
|
const override = process.env["OLAM_SKILL_SOURCES_AUDIT_LOG_PATH"];
|
|
16320
16439
|
if (override && override.length > 0)
|
|
16321
16440
|
return override;
|
|
16322
|
-
const stateDir = process.env["OLAM_STATE_DIR"] ??
|
|
16323
|
-
return
|
|
16441
|
+
const stateDir = process.env["OLAM_STATE_DIR"] ?? path55.join(os28.homedir(), ".olam", "state");
|
|
16442
|
+
return path55.join(stateDir, SKILL_SOURCES_AUDIT_LOG_FILENAME);
|
|
16324
16443
|
}
|
|
16325
16444
|
function appendTrustAudit(entry) {
|
|
16326
16445
|
const candidate = {
|
|
@@ -16329,7 +16448,7 @@ function appendTrustAudit(entry) {
|
|
|
16329
16448
|
};
|
|
16330
16449
|
const validated = TrustAuditEntrySchema.parse(candidate);
|
|
16331
16450
|
const filePath = skillSourcesAuditLogPath();
|
|
16332
|
-
fs52.mkdirSync(
|
|
16451
|
+
fs52.mkdirSync(path55.dirname(filePath), { recursive: true, mode: 448 });
|
|
16333
16452
|
const fd = fs52.openSync(filePath, "a", 384);
|
|
16334
16453
|
try {
|
|
16335
16454
|
fs52.writeSync(fd, JSON.stringify(validated) + "\n");
|
|
@@ -16542,22 +16661,22 @@ var init_store3 = __esm({
|
|
|
16542
16661
|
});
|
|
16543
16662
|
|
|
16544
16663
|
// ../core/dist/skill-sources/clone.js
|
|
16545
|
-
import { execFileSync as
|
|
16664
|
+
import { execFileSync as execFileSync14 } from "node:child_process";
|
|
16546
16665
|
import * as fs53 from "node:fs";
|
|
16547
16666
|
import * as os29 from "node:os";
|
|
16548
|
-
import * as
|
|
16667
|
+
import * as path56 from "node:path";
|
|
16549
16668
|
function skillSourcesRootDir() {
|
|
16550
16669
|
const override = process.env["OLAM_SKILL_SOURCES_DIR"];
|
|
16551
16670
|
if (override && override.length > 0)
|
|
16552
16671
|
return override;
|
|
16553
|
-
return
|
|
16672
|
+
return path56.join(os29.homedir(), ".olam", "state", "skill-sources");
|
|
16554
16673
|
}
|
|
16555
16674
|
function skillSourceClonePath(id) {
|
|
16556
|
-
return
|
|
16675
|
+
return path56.join(skillSourcesRootDir(), id);
|
|
16557
16676
|
}
|
|
16558
16677
|
function runGit(args, cwd) {
|
|
16559
16678
|
try {
|
|
16560
|
-
return
|
|
16679
|
+
return execFileSync14("git", args, {
|
|
16561
16680
|
cwd,
|
|
16562
16681
|
encoding: "utf-8",
|
|
16563
16682
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -16715,7 +16834,7 @@ var init_hook_template = __esm({
|
|
|
16715
16834
|
|
|
16716
16835
|
// ../core/dist/world/merge-settings.js
|
|
16717
16836
|
import * as fs55 from "node:fs";
|
|
16718
|
-
import * as
|
|
16837
|
+
import * as path57 from "node:path";
|
|
16719
16838
|
import * as crypto8 from "node:crypto";
|
|
16720
16839
|
function mergeHomeSettingsJson(filePath, options) {
|
|
16721
16840
|
let settings;
|
|
@@ -16799,7 +16918,7 @@ function isHookSentinelPresent(matchers, sentinel) {
|
|
|
16799
16918
|
return false;
|
|
16800
16919
|
}
|
|
16801
16920
|
function atomicWriteJson(filePath, data) {
|
|
16802
|
-
const dir =
|
|
16921
|
+
const dir = path57.dirname(filePath);
|
|
16803
16922
|
fs55.mkdirSync(dir, { recursive: true });
|
|
16804
16923
|
const rand = crypto8.randomBytes(6).toString("hex");
|
|
16805
16924
|
const tmp = `${filePath}.tmp.${process.pid}.${rand}`;
|
|
@@ -16815,13 +16934,13 @@ var init_merge_settings = __esm({
|
|
|
16815
16934
|
|
|
16816
16935
|
// ../core/dist/skill-sources/hook-install.js
|
|
16817
16936
|
import * as fs56 from "node:fs";
|
|
16818
|
-
import * as
|
|
16937
|
+
import * as path58 from "node:path";
|
|
16819
16938
|
import * as os30 from "node:os";
|
|
16820
16939
|
function settingsPathFor(scope, cwd) {
|
|
16821
16940
|
if (scope === "user") {
|
|
16822
|
-
return
|
|
16941
|
+
return path58.join(os30.homedir(), ".claude", "settings.json");
|
|
16823
16942
|
}
|
|
16824
|
-
return
|
|
16943
|
+
return path58.join(cwd ?? process.cwd(), ".claude", "settings.json");
|
|
16825
16944
|
}
|
|
16826
16945
|
function backupFile(filePath) {
|
|
16827
16946
|
if (!fs56.existsSync(filePath))
|
|
@@ -16832,7 +16951,7 @@ function backupFile(filePath) {
|
|
|
16832
16951
|
return backupPath;
|
|
16833
16952
|
}
|
|
16834
16953
|
function installSkillsHookToFile(filePath) {
|
|
16835
|
-
fs56.mkdirSync(
|
|
16954
|
+
fs56.mkdirSync(path58.dirname(filePath), { recursive: true });
|
|
16836
16955
|
const backupPath = backupFile(filePath);
|
|
16837
16956
|
const result = mergeHomeSettingsJson(filePath, {
|
|
16838
16957
|
ensureHook: {
|
|
@@ -16895,29 +17014,29 @@ var init_hook_install = __esm({
|
|
|
16895
17014
|
// ../core/dist/skill-sources/migration-snapshot.js
|
|
16896
17015
|
import * as fs57 from "node:fs";
|
|
16897
17016
|
import * as os31 from "node:os";
|
|
16898
|
-
import * as
|
|
17017
|
+
import * as path59 from "node:path";
|
|
16899
17018
|
function claudeDirInternal() {
|
|
16900
17019
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
16901
17020
|
if (override && override.length > 0)
|
|
16902
17021
|
return override;
|
|
16903
|
-
return
|
|
17022
|
+
return path59.join(os31.homedir(), ".claude");
|
|
16904
17023
|
}
|
|
16905
17024
|
function migrationSnapshotsDir() {
|
|
16906
17025
|
const override = process.env["OLAM_MIGRATION_SNAPSHOTS_DIR"];
|
|
16907
17026
|
if (override && override.length > 0)
|
|
16908
17027
|
return override;
|
|
16909
|
-
return
|
|
17028
|
+
return path59.join(os31.homedir(), ".olam", "state", "migration-snapshots");
|
|
16910
17029
|
}
|
|
16911
17030
|
function listToolboxManagedSymlinks(toolboxPath) {
|
|
16912
17031
|
const claude = claudeDirInternal();
|
|
16913
17032
|
const out = [];
|
|
16914
17033
|
const BUCKETS2 = ["skills", "agents", "scripts", "rules", "commands"];
|
|
16915
17034
|
for (const bucket of BUCKETS2) {
|
|
16916
|
-
const dir =
|
|
17035
|
+
const dir = path59.join(claude, bucket);
|
|
16917
17036
|
if (!fs57.existsSync(dir))
|
|
16918
17037
|
continue;
|
|
16919
17038
|
for (const name of fs57.readdirSync(dir)) {
|
|
16920
|
-
const link =
|
|
17039
|
+
const link = path59.join(dir, name);
|
|
16921
17040
|
try {
|
|
16922
17041
|
const stat = fs57.lstatSync(link);
|
|
16923
17042
|
if (!stat.isSymbolicLink())
|
|
@@ -16935,12 +17054,12 @@ function listToolboxManagedSymlinks(toolboxPath) {
|
|
|
16935
17054
|
function detectToolboxState(opts) {
|
|
16936
17055
|
const claude = claudeDirInternal();
|
|
16937
17056
|
const toolboxPath = opts.toolboxPath;
|
|
16938
|
-
const namespace = opts.namespace ??
|
|
16939
|
-
const atlasUserFile =
|
|
17057
|
+
const namespace = opts.namespace ?? path59.basename(toolboxPath);
|
|
17058
|
+
const atlasUserFile = path59.join(claude, ".atlas-user");
|
|
16940
17059
|
const atlasUser = fs57.existsSync(atlasUserFile) ? fs57.readFileSync(atlasUserFile, "utf-8").trim() || void 0 : void 0;
|
|
16941
17060
|
let subscriptionsJson;
|
|
16942
17061
|
if (atlasUser) {
|
|
16943
|
-
const sp =
|
|
17062
|
+
const sp = path59.join(toolboxPath, "members", atlasUser, "subscriptions.json");
|
|
16944
17063
|
if (fs57.existsSync(sp)) {
|
|
16945
17064
|
try {
|
|
16946
17065
|
subscriptionsJson = JSON.parse(fs57.readFileSync(sp, "utf-8"));
|
|
@@ -16950,7 +17069,7 @@ function detectToolboxState(opts) {
|
|
|
16950
17069
|
}
|
|
16951
17070
|
const atlasManagedSymlinks = listToolboxManagedSymlinks(toolboxPath);
|
|
16952
17071
|
let originalSessionStartHook;
|
|
16953
|
-
const settingsPath =
|
|
17072
|
+
const settingsPath = path59.join(claude, "settings.json");
|
|
16954
17073
|
if (fs57.existsSync(settingsPath)) {
|
|
16955
17074
|
try {
|
|
16956
17075
|
const settings = JSON.parse(fs57.readFileSync(settingsPath, "utf-8"));
|
|
@@ -16978,7 +17097,7 @@ function writeMigrationSnapshot(snapshot) {
|
|
|
16978
17097
|
const dir = migrationSnapshotsDir();
|
|
16979
17098
|
fs57.mkdirSync(dir, { recursive: true });
|
|
16980
17099
|
const stamp = snapshot.takenAt.replace(/[:.]/g, "-");
|
|
16981
|
-
const file =
|
|
17100
|
+
const file = path59.join(dir, `${snapshot.namespace}-${stamp}.json`);
|
|
16982
17101
|
fs57.writeFileSync(file, JSON.stringify(snapshot, null, 2) + "\n", { mode: 420 });
|
|
16983
17102
|
return file;
|
|
16984
17103
|
}
|
|
@@ -16988,7 +17107,7 @@ function readLatestMigrationSnapshot(opts = {}) {
|
|
|
16988
17107
|
return void 0;
|
|
16989
17108
|
const files = fs57.readdirSync(dir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
16990
17109
|
for (const f of files) {
|
|
16991
|
-
const full =
|
|
17110
|
+
const full = path59.join(dir, f);
|
|
16992
17111
|
try {
|
|
16993
17112
|
const snapshot = JSON.parse(fs57.readFileSync(full, "utf-8"));
|
|
16994
17113
|
if (snapshot.schemaVersion !== MIGRATION_SNAPSHOT_SCHEMA_VERSION)
|
|
@@ -17015,11 +17134,11 @@ var init_migration_snapshot = __esm({
|
|
|
17015
17134
|
|
|
17016
17135
|
// ../core/dist/skill-sync/artifact-resolver.js
|
|
17017
17136
|
import * as fs58 from "node:fs";
|
|
17018
|
-
import * as
|
|
17137
|
+
import * as path60 from "node:path";
|
|
17019
17138
|
function resolveSubscriptions(opts) {
|
|
17020
17139
|
const { clonePath, atlasUser } = opts;
|
|
17021
17140
|
if (atlasUser) {
|
|
17022
|
-
const subsPath =
|
|
17141
|
+
const subsPath = path60.join(clonePath, "members", atlasUser, "subscriptions.json");
|
|
17023
17142
|
if (fs58.existsSync(subsPath)) {
|
|
17024
17143
|
try {
|
|
17025
17144
|
const parsed = JSON.parse(fs58.readFileSync(subsPath, "utf-8"));
|
|
@@ -17034,7 +17153,7 @@ function resolveSubscriptions(opts) {
|
|
|
17034
17153
|
}
|
|
17035
17154
|
}
|
|
17036
17155
|
}
|
|
17037
|
-
const catsPath =
|
|
17156
|
+
const catsPath = path60.join(clonePath, "shared", "categories.json");
|
|
17038
17157
|
if (fs58.existsSync(catsPath)) {
|
|
17039
17158
|
try {
|
|
17040
17159
|
const parsed = JSON.parse(fs58.readFileSync(catsPath, "utf-8"));
|
|
@@ -17048,14 +17167,14 @@ function resolveSubscriptions(opts) {
|
|
|
17048
17167
|
} catch {
|
|
17049
17168
|
}
|
|
17050
17169
|
}
|
|
17051
|
-
const sharedDir =
|
|
17170
|
+
const sharedDir = path60.join(clonePath, "shared");
|
|
17052
17171
|
const cats = [];
|
|
17053
17172
|
if (fs58.existsSync(sharedDir)) {
|
|
17054
17173
|
for (const name of fs58.readdirSync(sharedDir)) {
|
|
17055
|
-
const dir =
|
|
17174
|
+
const dir = path60.join(sharedDir, name);
|
|
17056
17175
|
if (!fs58.statSync(dir).isDirectory())
|
|
17057
17176
|
continue;
|
|
17058
|
-
if (fs58.existsSync(
|
|
17177
|
+
if (fs58.existsSync(path60.join(dir, "skills")) || fs58.existsSync(path60.join(dir, "agents"))) {
|
|
17059
17178
|
cats.push(name);
|
|
17060
17179
|
}
|
|
17061
17180
|
}
|
|
@@ -17071,13 +17190,13 @@ function resolveSkillsDir(opts) {
|
|
|
17071
17190
|
const { sourceId, baseDir } = opts;
|
|
17072
17191
|
const out = [];
|
|
17073
17192
|
for (const name of listDirSafe(baseDir)) {
|
|
17074
|
-
const subdir =
|
|
17193
|
+
const subdir = path60.join(baseDir, name);
|
|
17075
17194
|
if (!fs58.statSync(subdir).isDirectory())
|
|
17076
17195
|
continue;
|
|
17077
|
-
if (!fs58.existsSync(
|
|
17196
|
+
if (!fs58.existsSync(path60.join(subdir, "SKILL.md")))
|
|
17078
17197
|
continue;
|
|
17079
17198
|
out.push({ kind: "skill", sourceId, sourcePath: subdir, deployBasename: name });
|
|
17080
|
-
const subagentsDir =
|
|
17199
|
+
const subagentsDir = path60.join(subdir, "references", "agents");
|
|
17081
17200
|
if (fs58.existsSync(subagentsDir) && fs58.statSync(subagentsDir).isDirectory()) {
|
|
17082
17201
|
for (const f of listDirSafe(subagentsDir)) {
|
|
17083
17202
|
if (!f.endsWith(".md"))
|
|
@@ -17085,7 +17204,7 @@ function resolveSkillsDir(opts) {
|
|
|
17085
17204
|
out.push({
|
|
17086
17205
|
kind: "subagent",
|
|
17087
17206
|
sourceId,
|
|
17088
|
-
sourcePath:
|
|
17207
|
+
sourcePath: path60.join(subagentsDir, f),
|
|
17089
17208
|
deployBasename: f,
|
|
17090
17209
|
parentSkill: name
|
|
17091
17210
|
});
|
|
@@ -17098,7 +17217,7 @@ function resolveAgentsDir(opts) {
|
|
|
17098
17217
|
const { sourceId, baseDir } = opts;
|
|
17099
17218
|
const out = [];
|
|
17100
17219
|
for (const name of listDirSafe(baseDir)) {
|
|
17101
|
-
const full =
|
|
17220
|
+
const full = path60.join(baseDir, name);
|
|
17102
17221
|
const stat = fs58.statSync(full);
|
|
17103
17222
|
if (stat.isFile() && name.endsWith(".md")) {
|
|
17104
17223
|
out.push({ kind: "agent", sourceId, sourcePath: full, deployBasename: name });
|
|
@@ -17109,7 +17228,7 @@ function resolveAgentsDir(opts) {
|
|
|
17109
17228
|
out.push({
|
|
17110
17229
|
kind: "agent",
|
|
17111
17230
|
sourceId,
|
|
17112
|
-
sourcePath:
|
|
17231
|
+
sourcePath: path60.join(full, f),
|
|
17113
17232
|
deployBasename: `${name}-${f}`
|
|
17114
17233
|
});
|
|
17115
17234
|
}
|
|
@@ -17121,7 +17240,7 @@ function resolveScriptsDir(opts) {
|
|
|
17121
17240
|
const { sourceId, baseDir } = opts;
|
|
17122
17241
|
const out = [];
|
|
17123
17242
|
for (const name of listDirSafe(baseDir)) {
|
|
17124
|
-
const full =
|
|
17243
|
+
const full = path60.join(baseDir, name);
|
|
17125
17244
|
const stat = fs58.statSync(full);
|
|
17126
17245
|
if (stat.isFile() && name.endsWith(".sh")) {
|
|
17127
17246
|
out.push({ kind: "script", sourceId, sourcePath: full, deployBasename: name });
|
|
@@ -17137,7 +17256,7 @@ function resolveRulesDir(opts) {
|
|
|
17137
17256
|
for (const name of listDirSafe(baseDir)) {
|
|
17138
17257
|
if (!name.endsWith(".md"))
|
|
17139
17258
|
continue;
|
|
17140
|
-
const full =
|
|
17259
|
+
const full = path60.join(baseDir, name);
|
|
17141
17260
|
if (!fs58.statSync(full).isFile())
|
|
17142
17261
|
continue;
|
|
17143
17262
|
out.push({ kind: "rule", sourceId, sourcePath: full, deployBasename: name });
|
|
@@ -17150,7 +17269,7 @@ function resolveJsonDir(opts) {
|
|
|
17150
17269
|
for (const name of listDirSafe(baseDir)) {
|
|
17151
17270
|
if (!name.endsWith(".json"))
|
|
17152
17271
|
continue;
|
|
17153
|
-
const full =
|
|
17272
|
+
const full = path60.join(baseDir, name);
|
|
17154
17273
|
if (!fs58.statSync(full).isFile())
|
|
17155
17274
|
continue;
|
|
17156
17275
|
out.push({ kind, sourceId, sourcePath: full, deployBasename: name });
|
|
@@ -17163,7 +17282,7 @@ function resolveOverlaysDir(opts) {
|
|
|
17163
17282
|
for (const name of listDirSafe(baseDir)) {
|
|
17164
17283
|
if (!name.endsWith(".md"))
|
|
17165
17284
|
continue;
|
|
17166
|
-
const full =
|
|
17285
|
+
const full = path60.join(baseDir, name);
|
|
17167
17286
|
if (!fs58.statSync(full).isFile())
|
|
17168
17287
|
continue;
|
|
17169
17288
|
const deployBasename = name.replace(/\.md$/, "");
|
|
@@ -17182,33 +17301,33 @@ function resolveSourceArtifacts(opts) {
|
|
|
17182
17301
|
const subscription = resolveSubscriptions({ clonePath, atlasUser });
|
|
17183
17302
|
const artifacts = [];
|
|
17184
17303
|
for (const cat of subscription.categories) {
|
|
17185
|
-
const catDir =
|
|
17304
|
+
const catDir = path60.join(clonePath, "shared", cat);
|
|
17186
17305
|
if (!fs58.existsSync(catDir))
|
|
17187
17306
|
continue;
|
|
17188
|
-
artifacts.push(...resolveSkillsDir({ sourceId, baseDir:
|
|
17189
|
-
artifacts.push(...resolveAgentsDir({ sourceId, baseDir:
|
|
17190
|
-
artifacts.push(...resolveScriptsDir({ sourceId, baseDir:
|
|
17191
|
-
artifacts.push(...resolveRulesDir({ sourceId, baseDir:
|
|
17192
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
17193
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
17307
|
+
artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path60.join(catDir, "skills") }));
|
|
17308
|
+
artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path60.join(catDir, "agents") }));
|
|
17309
|
+
artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path60.join(catDir, "scripts") }));
|
|
17310
|
+
artifacts.push(...resolveRulesDir({ sourceId, baseDir: path60.join(catDir, "rules") }));
|
|
17311
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path60.join(catDir, "hooks"), kind: "hook" }));
|
|
17312
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path60.join(catDir, "permissions"), kind: "permission" }));
|
|
17194
17313
|
}
|
|
17195
17314
|
if (atlasUser) {
|
|
17196
|
-
const memberRoot =
|
|
17315
|
+
const memberRoot = path60.join(clonePath, "members", atlasUser);
|
|
17197
17316
|
if (fs58.existsSync(memberRoot)) {
|
|
17198
|
-
artifacts.push(...resolveSkillsDir({ sourceId, baseDir:
|
|
17199
|
-
artifacts.push(...resolveAgentsDir({ sourceId, baseDir:
|
|
17200
|
-
artifacts.push(...resolveScriptsDir({ sourceId, baseDir:
|
|
17201
|
-
artifacts.push(...resolveRulesDir({ sourceId, baseDir:
|
|
17202
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
17203
|
-
artifacts.push(...resolveJsonDir({ sourceId, baseDir:
|
|
17317
|
+
artifacts.push(...resolveSkillsDir({ sourceId, baseDir: path60.join(memberRoot, "skills") }));
|
|
17318
|
+
artifacts.push(...resolveAgentsDir({ sourceId, baseDir: path60.join(memberRoot, "agents") }));
|
|
17319
|
+
artifacts.push(...resolveScriptsDir({ sourceId, baseDir: path60.join(memberRoot, "scripts") }));
|
|
17320
|
+
artifacts.push(...resolveRulesDir({ sourceId, baseDir: path60.join(memberRoot, "rules") }));
|
|
17321
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path60.join(memberRoot, "hooks"), kind: "hook" }));
|
|
17322
|
+
artifacts.push(...resolveJsonDir({ sourceId, baseDir: path60.join(memberRoot, "permissions"), kind: "permission" }));
|
|
17204
17323
|
artifacts.push(...resolveOverlaysDir({
|
|
17205
17324
|
sourceId,
|
|
17206
|
-
baseDir:
|
|
17325
|
+
baseDir: path60.join(memberRoot, "skills.overrides"),
|
|
17207
17326
|
targetKind: "skill"
|
|
17208
17327
|
}));
|
|
17209
17328
|
artifacts.push(...resolveOverlaysDir({
|
|
17210
17329
|
sourceId,
|
|
17211
|
-
baseDir:
|
|
17330
|
+
baseDir: path60.join(memberRoot, "agents.overrides"),
|
|
17212
17331
|
targetKind: "agent"
|
|
17213
17332
|
}));
|
|
17214
17333
|
}
|
|
@@ -17275,12 +17394,12 @@ var init_shim_targets = __esm({
|
|
|
17275
17394
|
// ../core/dist/skill-sync/symlink-deployer.js
|
|
17276
17395
|
import * as fs59 from "node:fs";
|
|
17277
17396
|
import * as os32 from "node:os";
|
|
17278
|
-
import * as
|
|
17397
|
+
import * as path61 from "node:path";
|
|
17279
17398
|
function claudeDir() {
|
|
17280
17399
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
17281
17400
|
if (override && override.length > 0)
|
|
17282
17401
|
return override;
|
|
17283
|
-
return
|
|
17402
|
+
return path61.join(os32.homedir(), ".claude");
|
|
17284
17403
|
}
|
|
17285
17404
|
function bucketFor(kind) {
|
|
17286
17405
|
switch (kind) {
|
|
@@ -17340,13 +17459,13 @@ function detectCollisions(artifacts) {
|
|
|
17340
17459
|
function cleanManagedSymlinks(claude, installedOlamVersion, overlayReferences, expectedAgentWinnerNames) {
|
|
17341
17460
|
const shadowBackups = [];
|
|
17342
17461
|
for (const bucket of BUCKETS) {
|
|
17343
|
-
const dir =
|
|
17462
|
+
const dir = path61.join(claude, bucket);
|
|
17344
17463
|
if (!fs59.existsSync(dir))
|
|
17345
17464
|
continue;
|
|
17346
17465
|
for (const name of fs59.readdirSync(dir)) {
|
|
17347
17466
|
if (name === ".olam-merged")
|
|
17348
17467
|
continue;
|
|
17349
|
-
const p =
|
|
17468
|
+
const p = path61.join(dir, name);
|
|
17350
17469
|
try {
|
|
17351
17470
|
const stat = fs59.lstatSync(p);
|
|
17352
17471
|
if (stat.isSymbolicLink()) {
|
|
@@ -17413,7 +17532,7 @@ function linkIfNeeded(target, link) {
|
|
|
17413
17532
|
function deployArtifacts(artifacts, opts) {
|
|
17414
17533
|
const claude = claudeDir();
|
|
17415
17534
|
for (const bucket of BUCKETS) {
|
|
17416
|
-
fs59.mkdirSync(
|
|
17535
|
+
fs59.mkdirSync(path61.join(claude, bucket), { recursive: true });
|
|
17417
17536
|
}
|
|
17418
17537
|
const { winners, collisions } = detectCollisions(artifacts);
|
|
17419
17538
|
const expectedAgentWinnerNames = new Set(winners.filter((a) => a.kind === "agent").map((a) => a.deployBasename));
|
|
@@ -17423,7 +17542,7 @@ function deployArtifacts(artifacts, opts) {
|
|
|
17423
17542
|
const bucket = bucketFor(artifact.kind);
|
|
17424
17543
|
if (!bucket)
|
|
17425
17544
|
continue;
|
|
17426
|
-
const linkPath =
|
|
17545
|
+
const linkPath = path61.join(claude, bucket, artifact.deployBasename);
|
|
17427
17546
|
if (artifact.kind === "agent" && artifact.resolvedContent !== void 0) {
|
|
17428
17547
|
const tmpPath = `${linkPath}.tmp-${process.pid}-${Date.now()}`;
|
|
17429
17548
|
fs59.writeFileSync(tmpPath, artifact.resolvedContent);
|
|
@@ -17610,24 +17729,24 @@ var init_meta_hooks = __esm({
|
|
|
17610
17729
|
// ../core/dist/skill-sync/settings-merger.js
|
|
17611
17730
|
import * as fs62 from "node:fs";
|
|
17612
17731
|
import * as os33 from "node:os";
|
|
17613
|
-
import * as
|
|
17732
|
+
import * as path62 from "node:path";
|
|
17614
17733
|
function claudeSettingsPath() {
|
|
17615
17734
|
const override = process.env["OLAM_CLAUDE_SETTINGS_PATH"];
|
|
17616
17735
|
if (override && override.length > 0)
|
|
17617
17736
|
return override;
|
|
17618
|
-
return
|
|
17737
|
+
return path62.join(claudeDirInternal2(), "settings.json");
|
|
17619
17738
|
}
|
|
17620
17739
|
function claudeDirInternal2() {
|
|
17621
17740
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
17622
17741
|
if (override && override.length > 0)
|
|
17623
17742
|
return override;
|
|
17624
|
-
return
|
|
17743
|
+
return path62.join(os33.homedir(), ".claude");
|
|
17625
17744
|
}
|
|
17626
17745
|
function settingsBackupDir() {
|
|
17627
17746
|
const override = process.env["OLAM_SETTINGS_BACKUP_DIR"];
|
|
17628
17747
|
if (override && override.length > 0)
|
|
17629
17748
|
return override;
|
|
17630
|
-
return
|
|
17749
|
+
return path62.join(os33.homedir(), ".olam", "state", "settings-backups");
|
|
17631
17750
|
}
|
|
17632
17751
|
function dedupeByMatcher(entries) {
|
|
17633
17752
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -17679,7 +17798,7 @@ function readJson(file) {
|
|
|
17679
17798
|
function rotateBackups(backupDir) {
|
|
17680
17799
|
if (!fs62.existsSync(backupDir))
|
|
17681
17800
|
return;
|
|
17682
|
-
const files = fs62.readdirSync(backupDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, full:
|
|
17801
|
+
const files = fs62.readdirSync(backupDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, full: path62.join(backupDir, f), mtime: fs62.statSync(path62.join(backupDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
17683
17802
|
for (const f of files.slice(BACKUP_RETENTION)) {
|
|
17684
17803
|
try {
|
|
17685
17804
|
fs62.unlinkSync(f.full);
|
|
@@ -17694,7 +17813,7 @@ function backupSettings() {
|
|
|
17694
17813
|
const dir = settingsBackupDir();
|
|
17695
17814
|
fs62.mkdirSync(dir, { recursive: true });
|
|
17696
17815
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
17697
|
-
const dest =
|
|
17816
|
+
const dest = path62.join(dir, `settings-${stamp}.json`);
|
|
17698
17817
|
fs62.copyFileSync(src, dest);
|
|
17699
17818
|
rotateBackups(dir);
|
|
17700
17819
|
return dest;
|
|
@@ -17771,7 +17890,7 @@ function mergeSettings(input2) {
|
|
|
17771
17890
|
...input2.permissionFiles.length > 0 ? { allow: [...permSet] } : {}
|
|
17772
17891
|
}
|
|
17773
17892
|
};
|
|
17774
|
-
fs62.mkdirSync(
|
|
17893
|
+
fs62.mkdirSync(path62.dirname(settingsPath), { recursive: true });
|
|
17775
17894
|
const tmp = `${settingsPath}.tmp-${process.pid}`;
|
|
17776
17895
|
fs62.writeFileSync(tmp, JSON.stringify(next, null, 2) + "\n", { mode: 420 });
|
|
17777
17896
|
fs62.renameSync(tmp, settingsPath);
|
|
@@ -17830,15 +17949,15 @@ var init_schema5 = __esm({
|
|
|
17830
17949
|
});
|
|
17831
17950
|
|
|
17832
17951
|
// ../core/dist/skill-sync/per-project-override.js
|
|
17833
|
-
import { execFileSync as
|
|
17952
|
+
import { execFileSync as execFileSync15 } from "node:child_process";
|
|
17834
17953
|
import * as fs63 from "node:fs";
|
|
17835
|
-
import * as
|
|
17954
|
+
import * as path63 from "node:path";
|
|
17836
17955
|
import { parse as parseYaml5 } from "yaml";
|
|
17837
17956
|
function findProjectOverride(startDir) {
|
|
17838
|
-
let dir =
|
|
17839
|
-
const root =
|
|
17957
|
+
let dir = path63.resolve(startDir);
|
|
17958
|
+
const root = path63.parse(dir).root;
|
|
17840
17959
|
while (true) {
|
|
17841
|
-
const candidate =
|
|
17960
|
+
const candidate = path63.join(dir, PROJECT_OVERRIDE_RELATIVE_PATH);
|
|
17842
17961
|
if (fs63.existsSync(candidate) && fs63.statSync(candidate).isFile()) {
|
|
17843
17962
|
const raw = fs63.readFileSync(candidate, "utf-8");
|
|
17844
17963
|
let parsed;
|
|
@@ -17853,7 +17972,7 @@ function findProjectOverride(startDir) {
|
|
|
17853
17972
|
}
|
|
17854
17973
|
if (dir === root)
|
|
17855
17974
|
return void 0;
|
|
17856
|
-
dir =
|
|
17975
|
+
dir = path63.dirname(dir);
|
|
17857
17976
|
}
|
|
17858
17977
|
}
|
|
17859
17978
|
function applyOverrideToArtifacts(artifacts, override) {
|
|
@@ -17873,7 +17992,7 @@ function applyPinToClone(opts) {
|
|
|
17873
17992
|
if (ref.startsWith("-")) {
|
|
17874
17993
|
throw new Error(`refuses ref "${ref}" \u2014 must not start with "-" (would be parsed as a git option)`);
|
|
17875
17994
|
}
|
|
17876
|
-
|
|
17995
|
+
execFileSync15("git", ["-C", clonePath, "checkout", "-q", ref], {
|
|
17877
17996
|
stdio: ["ignore", "ignore", "pipe"]
|
|
17878
17997
|
});
|
|
17879
17998
|
}
|
|
@@ -17883,7 +18002,7 @@ function restoreCloneToBranchHead(opts) {
|
|
|
17883
18002
|
return;
|
|
17884
18003
|
}
|
|
17885
18004
|
try {
|
|
17886
|
-
|
|
18005
|
+
execFileSync15("git", ["-C", clonePath, "checkout", "-q", branch], {
|
|
17887
18006
|
stdio: ["ignore", "ignore", "pipe"]
|
|
17888
18007
|
});
|
|
17889
18008
|
} catch {
|
|
@@ -17894,14 +18013,14 @@ var init_per_project_override = __esm({
|
|
|
17894
18013
|
"../core/dist/skill-sync/per-project-override.js"() {
|
|
17895
18014
|
"use strict";
|
|
17896
18015
|
init_schema5();
|
|
17897
|
-
PROJECT_OVERRIDE_RELATIVE_PATH =
|
|
18016
|
+
PROJECT_OVERRIDE_RELATIVE_PATH = path63.join(".olam", "skill-overrides.yaml");
|
|
17898
18017
|
}
|
|
17899
18018
|
});
|
|
17900
18019
|
|
|
17901
18020
|
// ../core/dist/lib/file-lock.js
|
|
17902
18021
|
import * as fs64 from "node:fs";
|
|
17903
18022
|
import * as os34 from "node:os";
|
|
17904
|
-
import * as
|
|
18023
|
+
import * as path64 from "node:path";
|
|
17905
18024
|
function defaultIsPidAlive(pid) {
|
|
17906
18025
|
try {
|
|
17907
18026
|
process.kill(pid, 0);
|
|
@@ -17935,7 +18054,7 @@ function isLockStale(meta, opts) {
|
|
|
17935
18054
|
}
|
|
17936
18055
|
function tryAcquireOnce(lockPath, meta, opts) {
|
|
17937
18056
|
try {
|
|
17938
|
-
fs64.mkdirSync(
|
|
18057
|
+
fs64.mkdirSync(path64.dirname(lockPath), { recursive: true });
|
|
17939
18058
|
const fd = fs64.openSync(lockPath, "wx", 384);
|
|
17940
18059
|
try {
|
|
17941
18060
|
fs64.writeSync(fd, JSON.stringify(meta));
|
|
@@ -17967,7 +18086,7 @@ function tryAcquireOnce(lockPath, meta, opts) {
|
|
|
17967
18086
|
}
|
|
17968
18087
|
async function acquireFileLock(lockDir, options = {}) {
|
|
17969
18088
|
const lockFilename = options.lockFilename ?? DEFAULT_LOCK_FILENAME;
|
|
17970
|
-
const lockPath =
|
|
18089
|
+
const lockPath = path64.join(lockDir, lockFilename);
|
|
17971
18090
|
const acquireTimeoutMs = options.acquireTimeoutMs ?? DEFAULT_ACQUIRE_TIMEOUT_MS;
|
|
17972
18091
|
const staleLockMs = options.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
|
|
17973
18092
|
const now = options.now ?? Date.now;
|
|
@@ -18092,7 +18211,7 @@ var init_min_version_filter = __esm({
|
|
|
18092
18211
|
|
|
18093
18212
|
// ../core/dist/skill-sync/overlay-scan.js
|
|
18094
18213
|
import * as fs65 from "node:fs";
|
|
18095
|
-
import * as
|
|
18214
|
+
import * as path65 from "node:path";
|
|
18096
18215
|
function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
18097
18216
|
const result = /* @__PURE__ */ new Map();
|
|
18098
18217
|
if (!fs65.existsSync(overlayRoot)) {
|
|
@@ -18109,7 +18228,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
18109
18228
|
return result;
|
|
18110
18229
|
}
|
|
18111
18230
|
for (const subdir of OVERRIDE_SUBDIRS) {
|
|
18112
|
-
const dir =
|
|
18231
|
+
const dir = path65.join(overlayRoot, subdir);
|
|
18113
18232
|
if (!fs65.existsSync(dir))
|
|
18114
18233
|
continue;
|
|
18115
18234
|
walkMarkdown(dir, mdFiles, caps.maxFiles);
|
|
@@ -18125,8 +18244,8 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
18125
18244
|
continue;
|
|
18126
18245
|
throw err;
|
|
18127
18246
|
}
|
|
18128
|
-
const rel =
|
|
18129
|
-
if (rel.startsWith("..") ||
|
|
18247
|
+
const rel = path65.relative(overlayRootReal, realFile);
|
|
18248
|
+
if (rel.startsWith("..") || path65.isAbsolute(rel)) {
|
|
18130
18249
|
continue;
|
|
18131
18250
|
}
|
|
18132
18251
|
let content;
|
|
@@ -18144,7 +18263,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
18144
18263
|
}
|
|
18145
18264
|
throw err;
|
|
18146
18265
|
}
|
|
18147
|
-
const relpath =
|
|
18266
|
+
const relpath = path65.relative(overlayRoot, filepath).split(path65.sep).join("/");
|
|
18148
18267
|
for (const basename16 of basenames) {
|
|
18149
18268
|
if (content.includes(basename16)) {
|
|
18150
18269
|
const list = result.get(basename16) ?? [];
|
|
@@ -18168,7 +18287,7 @@ function walkMarkdown(dir, out, cap) {
|
|
|
18168
18287
|
if (out.length >= cap) {
|
|
18169
18288
|
throw new Error(`[overlay-scan] aborted: overlay tree contains > ${cap} markdown files. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
|
|
18170
18289
|
}
|
|
18171
|
-
const full =
|
|
18290
|
+
const full = path65.join(dir, entry.name);
|
|
18172
18291
|
if (entry.isSymbolicLink())
|
|
18173
18292
|
continue;
|
|
18174
18293
|
if (entry.isDirectory()) {
|
|
@@ -18195,10 +18314,10 @@ var init_overlay_scan = __esm({
|
|
|
18195
18314
|
// ../core/dist/skill-sync/settings-json-lock.js
|
|
18196
18315
|
import * as fs66 from "node:fs";
|
|
18197
18316
|
import * as os35 from "node:os";
|
|
18198
|
-
import * as
|
|
18317
|
+
import * as path66 from "node:path";
|
|
18199
18318
|
function defaultSettingsJsonLockPath() {
|
|
18200
|
-
const stateDir = process.env["OLAM_STATE_DIR"] ??
|
|
18201
|
-
return
|
|
18319
|
+
const stateDir = process.env["OLAM_STATE_DIR"] ?? path66.join(os35.homedir(), ".olam", "state");
|
|
18320
|
+
return path66.join(stateDir, SETTINGS_JSON_LOCK_FILENAME);
|
|
18202
18321
|
}
|
|
18203
18322
|
function defaultIsPidAlive2(pid) {
|
|
18204
18323
|
try {
|
|
@@ -18237,7 +18356,7 @@ function isLockStale2(meta, opts) {
|
|
|
18237
18356
|
function tryAcquireOnce2(lockPath, meta, opts) {
|
|
18238
18357
|
for (let attempt = 0; attempt <= MAX_STEAL_ATTEMPTS; attempt += 1) {
|
|
18239
18358
|
try {
|
|
18240
|
-
fs66.mkdirSync(
|
|
18359
|
+
fs66.mkdirSync(path66.dirname(lockPath), { recursive: true });
|
|
18241
18360
|
const fd = fs66.openSync(lockPath, "wx", 384);
|
|
18242
18361
|
try {
|
|
18243
18362
|
fs66.writeSync(fd, JSON.stringify(meta));
|
|
@@ -18399,12 +18518,12 @@ var init_services_status = __esm({
|
|
|
18399
18518
|
import * as crypto9 from "node:crypto";
|
|
18400
18519
|
import * as fs67 from "node:fs";
|
|
18401
18520
|
import * as os36 from "node:os";
|
|
18402
|
-
import * as
|
|
18521
|
+
import * as path67 from "node:path";
|
|
18403
18522
|
function migrationSnapshotsDir2() {
|
|
18404
18523
|
const override = process.env["OLAM_MIGRATION_SNAPSHOTS_DIR"];
|
|
18405
18524
|
if (override && override.length > 0)
|
|
18406
18525
|
return override;
|
|
18407
|
-
return
|
|
18526
|
+
return path67.join(os36.homedir(), ".olam", "state", "migration-snapshots");
|
|
18408
18527
|
}
|
|
18409
18528
|
function writeMetaHooksSnapshot(originalSettings) {
|
|
18410
18529
|
const snapshot = {
|
|
@@ -18418,7 +18537,7 @@ function writeMetaHooksSnapshot(originalSettings) {
|
|
|
18418
18537
|
fs67.mkdirSync(dir, { recursive: true });
|
|
18419
18538
|
const stamp = validated.takenAt.replace(/[:.]/g, "-");
|
|
18420
18539
|
const rand = crypto9.randomBytes(3).toString("hex");
|
|
18421
|
-
const file =
|
|
18540
|
+
const file = path67.join(dir, `${META_HOOKS_SNAPSHOT_PREFIX}${stamp}-${process.pid}-${rand}.json`);
|
|
18422
18541
|
fs67.writeFileSync(file, JSON.stringify(validated, null, 2) + "\n", { mode: 384 });
|
|
18423
18542
|
return file;
|
|
18424
18543
|
}
|
|
@@ -18437,7 +18556,7 @@ function findLatestMetaHooksSnapshot() {
|
|
|
18437
18556
|
const candidates2 = fs67.readdirSync(dir).filter((n) => n.startsWith(META_HOOKS_SNAPSHOT_PREFIX) && n.endsWith(".json")).sort().reverse();
|
|
18438
18557
|
if (candidates2.length === 0)
|
|
18439
18558
|
return void 0;
|
|
18440
|
-
return
|
|
18559
|
+
return path67.join(dir, candidates2[0]);
|
|
18441
18560
|
}
|
|
18442
18561
|
function restoreSettingsFromSnapshot(snapshot, settingsPath) {
|
|
18443
18562
|
if (snapshot.originalSettings === null) {
|
|
@@ -18446,7 +18565,7 @@ function restoreSettingsFromSnapshot(snapshot, settingsPath) {
|
|
|
18446
18565
|
}
|
|
18447
18566
|
return;
|
|
18448
18567
|
}
|
|
18449
|
-
fs67.mkdirSync(
|
|
18568
|
+
fs67.mkdirSync(path67.dirname(settingsPath), { recursive: true });
|
|
18450
18569
|
const tmp = `${settingsPath}.tmp-restore-${process.pid}-${Date.now()}`;
|
|
18451
18570
|
fs67.writeFileSync(tmp, JSON.stringify(snapshot.originalSettings, null, 2) + "\n");
|
|
18452
18571
|
fs67.renameSync(tmp, settingsPath);
|
|
@@ -18816,17 +18935,17 @@ var init_markdown_merger = __esm({
|
|
|
18816
18935
|
|
|
18817
18936
|
// ../core/dist/skill-sync/managed-merge.js
|
|
18818
18937
|
import * as fs68 from "node:fs";
|
|
18819
|
-
import * as
|
|
18938
|
+
import * as path68 from "node:path";
|
|
18820
18939
|
function materializeMergedSkill(opts) {
|
|
18821
18940
|
const { sourceId, sourcePath, deployBasename, mergedContent, claudeDir: claudeDir2 } = opts;
|
|
18822
|
-
const managedDir =
|
|
18823
|
-
const sourceRoot =
|
|
18824
|
-
const managedResolved =
|
|
18825
|
-
if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot +
|
|
18941
|
+
const managedDir = path68.join(claudeDir2, ".olam-merged", sourceId, deployBasename);
|
|
18942
|
+
const sourceRoot = path68.resolve(path68.join(claudeDir2, ".olam-merged", sourceId));
|
|
18943
|
+
const managedResolved = path68.resolve(managedDir);
|
|
18944
|
+
if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot + path68.sep))) {
|
|
18826
18945
|
throw new Error(`[managed-merge] refusing to materialize: deployBasename "${deployBasename}" escapes managed root "${sourceRoot}" (resolved to "${managedResolved}")`);
|
|
18827
18946
|
}
|
|
18828
18947
|
fs68.mkdirSync(managedDir, { recursive: true });
|
|
18829
|
-
const skillMdPath =
|
|
18948
|
+
const skillMdPath = path68.join(managedDir, "SKILL.md");
|
|
18830
18949
|
const tmpPath = `${skillMdPath}.tmp-${process.pid}-${Date.now()}`;
|
|
18831
18950
|
fs68.writeFileSync(tmpPath, mergedContent);
|
|
18832
18951
|
fs68.renameSync(tmpPath, skillMdPath);
|
|
@@ -18834,9 +18953,9 @@ function materializeMergedSkill(opts) {
|
|
|
18834
18953
|
for (const entry of baseEntries) {
|
|
18835
18954
|
if (entry === "SKILL.md")
|
|
18836
18955
|
continue;
|
|
18837
|
-
const linkPath =
|
|
18838
|
-
const targetAbsolute =
|
|
18839
|
-
const targetRelative =
|
|
18956
|
+
const linkPath = path68.join(managedDir, entry);
|
|
18957
|
+
const targetAbsolute = path68.join(sourcePath, entry);
|
|
18958
|
+
const targetRelative = path68.relative(managedDir, targetAbsolute);
|
|
18840
18959
|
try {
|
|
18841
18960
|
fs68.lstatSync(linkPath);
|
|
18842
18961
|
fs68.rmSync(linkPath, { recursive: true, force: true });
|
|
@@ -18850,7 +18969,7 @@ function materializeMergedSkill(opts) {
|
|
|
18850
18969
|
if (entry === "SKILL.md")
|
|
18851
18970
|
continue;
|
|
18852
18971
|
if (!baseEntrySet.has(entry)) {
|
|
18853
|
-
const stalePath =
|
|
18972
|
+
const stalePath = path68.join(managedDir, entry);
|
|
18854
18973
|
try {
|
|
18855
18974
|
fs68.rmSync(stalePath, { recursive: true, force: true });
|
|
18856
18975
|
} catch {
|
|
@@ -18860,7 +18979,7 @@ function materializeMergedSkill(opts) {
|
|
|
18860
18979
|
return managedDir;
|
|
18861
18980
|
}
|
|
18862
18981
|
function cleanMergedDir(claudeDir2) {
|
|
18863
|
-
fs68.rmSync(
|
|
18982
|
+
fs68.rmSync(path68.join(claudeDir2, ".olam-merged"), { recursive: true, force: true });
|
|
18864
18983
|
}
|
|
18865
18984
|
var init_managed_merge = __esm({
|
|
18866
18985
|
"../core/dist/skill-sync/managed-merge.js"() {
|
|
@@ -18949,7 +19068,7 @@ var init_prefix_rules = __esm({
|
|
|
18949
19068
|
|
|
18950
19069
|
// ../core/dist/skill-sync/prefix-deploy.js
|
|
18951
19070
|
import * as fs69 from "node:fs";
|
|
18952
|
-
import * as
|
|
19071
|
+
import * as path69 from "node:path";
|
|
18953
19072
|
function buildSourcePrefixMap(sources) {
|
|
18954
19073
|
const byId = /* @__PURE__ */ new Map();
|
|
18955
19074
|
const scopeById = /* @__PURE__ */ new Map();
|
|
@@ -18997,7 +19116,7 @@ function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir2, dryRun) {
|
|
|
18997
19116
|
continue;
|
|
18998
19117
|
}
|
|
18999
19118
|
if (artifact.kind === "skill") {
|
|
19000
|
-
const skillMdPath =
|
|
19119
|
+
const skillMdPath = path69.join(artifact.sourcePath, "SKILL.md");
|
|
19001
19120
|
const content = fs69.readFileSync(skillMdPath);
|
|
19002
19121
|
const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
|
|
19003
19122
|
const managedDir = materializeMergedSkill({
|
|
@@ -19062,12 +19181,12 @@ function sourceConfigPath(clonePath) {
|
|
|
19062
19181
|
return join76(clonePath, "shared", "source-config.yaml");
|
|
19063
19182
|
}
|
|
19064
19183
|
function readSourceConfig(clonePath, sourceId) {
|
|
19065
|
-
const
|
|
19066
|
-
if (!existsSync77(
|
|
19184
|
+
const path96 = sourceConfigPath(clonePath);
|
|
19185
|
+
if (!existsSync77(path96))
|
|
19067
19186
|
return void 0;
|
|
19068
19187
|
let raw;
|
|
19069
19188
|
try {
|
|
19070
|
-
raw = readFileSync66(
|
|
19189
|
+
raw = readFileSync66(path96, "utf-8");
|
|
19071
19190
|
} catch (err) {
|
|
19072
19191
|
emitMalformedWarning(sourceId, `read failed: ${errToMsg(err)}`);
|
|
19073
19192
|
return void 0;
|
|
@@ -19148,12 +19267,12 @@ var init_resolve_source_config = __esm({
|
|
|
19148
19267
|
// ../core/dist/skill-sync/engine.js
|
|
19149
19268
|
import * as fs70 from "node:fs";
|
|
19150
19269
|
import * as os37 from "node:os";
|
|
19151
|
-
import * as
|
|
19270
|
+
import * as path70 from "node:path";
|
|
19152
19271
|
function resolveAtlasUser(override) {
|
|
19153
19272
|
if (override)
|
|
19154
19273
|
return override;
|
|
19155
|
-
const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] ||
|
|
19156
|
-
const f =
|
|
19274
|
+
const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] || path70.join(os37.homedir(), ".claude");
|
|
19275
|
+
const f = path70.join(claudeDir2, ".atlas-user");
|
|
19157
19276
|
if (fs70.existsSync(f)) {
|
|
19158
19277
|
return fs70.readFileSync(f, "utf-8").trim() || void 0;
|
|
19159
19278
|
}
|
|
@@ -19310,7 +19429,7 @@ async function syncSkills(opts = {}) {
|
|
|
19310
19429
|
let baseContent;
|
|
19311
19430
|
let basePath;
|
|
19312
19431
|
if (overlay.targetKind === "skill") {
|
|
19313
|
-
basePath =
|
|
19432
|
+
basePath = path70.join(base.sourcePath, "SKILL.md");
|
|
19314
19433
|
baseContent = fs70.readFileSync(basePath, "utf-8");
|
|
19315
19434
|
} else {
|
|
19316
19435
|
basePath = base.sourcePath;
|
|
@@ -19377,7 +19496,7 @@ async function syncSkills(opts = {}) {
|
|
|
19377
19496
|
summary2.collisions = detectCollisions(baseArtifacts).collisions;
|
|
19378
19497
|
return summary2;
|
|
19379
19498
|
}
|
|
19380
|
-
const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] ||
|
|
19499
|
+
const claudeDirPath = process.env["OLAM_CLAUDE_DIR"] || path70.join(os37.homedir(), ".claude");
|
|
19381
19500
|
const overlayReferences = scanOverlayReferences(claudeDirPath, SHIM_TARGETS.map((t) => t.basename));
|
|
19382
19501
|
summary2.deploy = deployArtifacts(baseArtifacts, {
|
|
19383
19502
|
installedOlamVersion,
|
|
@@ -19411,10 +19530,10 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
19411
19530
|
} catch {
|
|
19412
19531
|
try {
|
|
19413
19532
|
const raw = fs70.readFileSync(settingsFile);
|
|
19414
|
-
const bakDir =
|
|
19533
|
+
const bakDir = path70.join(path70.dirname(settingsFile), ".malformed-backups");
|
|
19415
19534
|
fs70.mkdirSync(bakDir, { recursive: true });
|
|
19416
19535
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
19417
|
-
const bakFile =
|
|
19536
|
+
const bakFile = path70.join(bakDir, `settings.json.malformed.${stamp}.bak`);
|
|
19418
19537
|
fs70.writeFileSync(bakFile, raw, { mode: 384 });
|
|
19419
19538
|
snapshotError = `settings.json was malformed; original bytes preserved at ${bakFile}`;
|
|
19420
19539
|
} catch (bakErr) {
|
|
@@ -19465,7 +19584,7 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
19465
19584
|
} catch {
|
|
19466
19585
|
}
|
|
19467
19586
|
}
|
|
19468
|
-
fs70.mkdirSync(
|
|
19587
|
+
fs70.mkdirSync(path70.dirname(settingsFile), { recursive: true });
|
|
19469
19588
|
const tmpPath = `${settingsFile}.tmp-${process.pid}-${Date.now()}`;
|
|
19470
19589
|
fs70.writeFileSync(tmpPath, JSON.stringify(inject.nextSettings, null, 2) + "\n");
|
|
19471
19590
|
fs70.renameSync(tmpPath, settingsFile);
|
|
@@ -19510,13 +19629,13 @@ var init_engine = __esm({
|
|
|
19510
19629
|
|
|
19511
19630
|
// ../core/dist/skill-sync/shadow-backup-manager.js
|
|
19512
19631
|
import * as fs71 from "node:fs";
|
|
19513
|
-
import * as
|
|
19632
|
+
import * as path71 from "node:path";
|
|
19514
19633
|
function listShadowBackups(opts = {}) {
|
|
19515
19634
|
const claude = opts.claudeDirOverride ?? claudeDir();
|
|
19516
19635
|
const now = opts.now ?? Date.now();
|
|
19517
19636
|
const out = [];
|
|
19518
19637
|
for (const bucket of SHADOW_BACKUP_BUCKETS) {
|
|
19519
|
-
const bucketDir =
|
|
19638
|
+
const bucketDir = path71.join(claude, bucket);
|
|
19520
19639
|
if (!fs71.existsSync(bucketDir))
|
|
19521
19640
|
continue;
|
|
19522
19641
|
let entries;
|
|
@@ -19532,7 +19651,7 @@ function listShadowBackups(opts = {}) {
|
|
|
19532
19651
|
const epochSeconds = Number.parseInt(match2[1], 10);
|
|
19533
19652
|
if (!Number.isFinite(epochSeconds) || epochSeconds < 0)
|
|
19534
19653
|
continue;
|
|
19535
|
-
const full =
|
|
19654
|
+
const full = path71.join(bucketDir, name);
|
|
19536
19655
|
let sizeBytes = 0;
|
|
19537
19656
|
try {
|
|
19538
19657
|
const st = fs71.statSync(full);
|
|
@@ -19548,7 +19667,7 @@ function listShadowBackups(opts = {}) {
|
|
|
19548
19667
|
bucket,
|
|
19549
19668
|
basename: name,
|
|
19550
19669
|
originalBasename,
|
|
19551
|
-
originalPath:
|
|
19670
|
+
originalPath: path71.join(bucketDir, originalBasename),
|
|
19552
19671
|
epochSeconds,
|
|
19553
19672
|
ageMs: now - epochSeconds * 1e3,
|
|
19554
19673
|
sizeBytes
|
|
@@ -19602,17 +19721,17 @@ function pruneShadowBackups(opts) {
|
|
|
19602
19721
|
return { deleted, skipped };
|
|
19603
19722
|
}
|
|
19604
19723
|
function restoreShadowBackup(opts) {
|
|
19605
|
-
const abs =
|
|
19724
|
+
const abs = path71.resolve(opts.backupPath);
|
|
19606
19725
|
if (!fs71.existsSync(abs)) {
|
|
19607
19726
|
throw new Error(`backup file not found: ${abs}`);
|
|
19608
19727
|
}
|
|
19609
|
-
const basename16 =
|
|
19728
|
+
const basename16 = path71.basename(abs);
|
|
19610
19729
|
const match2 = SHADOW_BACKUP_SUFFIX_RE.exec(basename16);
|
|
19611
19730
|
if (!match2) {
|
|
19612
19731
|
throw new Error(`not a shadow-backup file (basename "${basename16}" does not match \`.shadow-backup-<epoch>\`): ${abs}`);
|
|
19613
19732
|
}
|
|
19614
19733
|
const originalBasename = basename16.slice(0, basename16.length - match2[0].length);
|
|
19615
|
-
const originalPath =
|
|
19734
|
+
const originalPath = path71.join(path71.dirname(abs), originalBasename);
|
|
19616
19735
|
if (fs71.existsSync(originalPath) && !opts.force) {
|
|
19617
19736
|
throw new Error(`original path already occupied: ${originalPath}. Move/rename it first OR re-run with --force.`);
|
|
19618
19737
|
}
|
|
@@ -19635,10 +19754,10 @@ var init_shadow_backup_manager = __esm({
|
|
|
19635
19754
|
// ../core/dist/global-config/repos.js
|
|
19636
19755
|
import * as fs72 from "node:fs";
|
|
19637
19756
|
import * as os38 from "node:os";
|
|
19638
|
-
import * as
|
|
19757
|
+
import * as path72 from "node:path";
|
|
19639
19758
|
function expandPath(p) {
|
|
19640
19759
|
if (p === "~" || p.startsWith("~/")) {
|
|
19641
|
-
return
|
|
19760
|
+
return path72.join(os38.homedir(), p.slice(1));
|
|
19642
19761
|
}
|
|
19643
19762
|
return p;
|
|
19644
19763
|
}
|
|
@@ -19750,13 +19869,13 @@ var init_global_config = __esm({
|
|
|
19750
19869
|
|
|
19751
19870
|
// ../core/dist/skill-sources/doctor-checks.js
|
|
19752
19871
|
import * as fs73 from "node:fs";
|
|
19753
|
-
import * as
|
|
19872
|
+
import * as path73 from "node:path";
|
|
19754
19873
|
import * as os39 from "node:os";
|
|
19755
19874
|
function claudeDirInternal3() {
|
|
19756
19875
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
19757
19876
|
if (override && override.length > 0)
|
|
19758
19877
|
return override;
|
|
19759
|
-
return
|
|
19878
|
+
return path73.join(os39.homedir(), ".claude");
|
|
19760
19879
|
}
|
|
19761
19880
|
function checkStateFileParse() {
|
|
19762
19881
|
const filePath = globalConfigPath();
|
|
@@ -19811,11 +19930,11 @@ function checkDanglingSymlinks() {
|
|
|
19811
19930
|
const buckets = ["commands", "agents", "skills", "scripts", "rules"];
|
|
19812
19931
|
const dangling = [];
|
|
19813
19932
|
for (const bucket of buckets) {
|
|
19814
|
-
const dir =
|
|
19933
|
+
const dir = path73.join(claude, bucket);
|
|
19815
19934
|
if (!fs73.existsSync(dir))
|
|
19816
19935
|
continue;
|
|
19817
19936
|
for (const name of fs73.readdirSync(dir)) {
|
|
19818
|
-
const linkPath =
|
|
19937
|
+
const linkPath = path73.join(dir, name);
|
|
19819
19938
|
try {
|
|
19820
19939
|
const lst = fs73.lstatSync(linkPath);
|
|
19821
19940
|
if (!lst.isSymbolicLink())
|
|
@@ -19860,7 +19979,7 @@ function checkOrphanedSnapshots() {
|
|
|
19860
19979
|
for (const name of fs73.readdirSync(dir)) {
|
|
19861
19980
|
if (!name.endsWith(".json"))
|
|
19862
19981
|
continue;
|
|
19863
|
-
const full =
|
|
19982
|
+
const full = path73.join(dir, name);
|
|
19864
19983
|
try {
|
|
19865
19984
|
const stat = fs73.statSync(full);
|
|
19866
19985
|
if (!stat.isFile())
|
|
@@ -19998,7 +20117,7 @@ function checkMemberNameMissing() {
|
|
|
19998
20117
|
return result;
|
|
19999
20118
|
}
|
|
20000
20119
|
const claudeDir2 = claudeDirInternal3();
|
|
20001
|
-
const atlasUserPath =
|
|
20120
|
+
const atlasUserPath = path73.join(claudeDir2, ".atlas-user");
|
|
20002
20121
|
const value = fs73.existsSync(atlasUserPath) ? fs73.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
20003
20122
|
if (value.length > 0) {
|
|
20004
20123
|
result.details = [`atlas-user: ${value}`];
|
|
@@ -20007,10 +20126,10 @@ function checkMemberNameMissing() {
|
|
|
20007
20126
|
result.healthy = false;
|
|
20008
20127
|
result.issue = "atlas-toolbox source registered but ~/.claude/.atlas-user not set";
|
|
20009
20128
|
const clonePath = skillSourceClonePath(atlasSource.id);
|
|
20010
|
-
const membersDir =
|
|
20129
|
+
const membersDir = path73.join(clonePath, "members");
|
|
20011
20130
|
const existing = fs73.existsSync(membersDir) ? fs73.readdirSync(membersDir).filter((e) => {
|
|
20012
20131
|
try {
|
|
20013
|
-
return fs73.statSync(
|
|
20132
|
+
return fs73.statSync(path73.join(membersDir, e)).isDirectory();
|
|
20014
20133
|
} catch {
|
|
20015
20134
|
return false;
|
|
20016
20135
|
}
|
|
@@ -20024,7 +20143,7 @@ function checkMemberNameMissing() {
|
|
|
20024
20143
|
}
|
|
20025
20144
|
function checkMemberOverlayDrift() {
|
|
20026
20145
|
const claudeDir2 = claudeDirInternal3();
|
|
20027
|
-
const atlasUserPath =
|
|
20146
|
+
const atlasUserPath = path73.join(claudeDir2, ".atlas-user");
|
|
20028
20147
|
const atlasUser = fs73.existsSync(atlasUserPath) ? fs73.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
20029
20148
|
if (atlasUser.length === 0) {
|
|
20030
20149
|
return [];
|
|
@@ -20041,7 +20160,7 @@ function checkMemberOverlayDrift() {
|
|
|
20041
20160
|
const clonePath = skillSourceClonePath(atlasSource.id);
|
|
20042
20161
|
const results = [];
|
|
20043
20162
|
for (const kind of ["skills", "agents"]) {
|
|
20044
|
-
const localRoot =
|
|
20163
|
+
const localRoot = path73.join(claudeDir2, `${kind}.overrides`);
|
|
20045
20164
|
if (!fs73.existsSync(localRoot))
|
|
20046
20165
|
continue;
|
|
20047
20166
|
let entries;
|
|
@@ -20051,7 +20170,7 @@ function checkMemberOverlayDrift() {
|
|
|
20051
20170
|
continue;
|
|
20052
20171
|
}
|
|
20053
20172
|
for (const entry of entries) {
|
|
20054
|
-
const localFile =
|
|
20173
|
+
const localFile = path73.join(localRoot, entry);
|
|
20055
20174
|
let stat;
|
|
20056
20175
|
try {
|
|
20057
20176
|
stat = fs73.statSync(localFile);
|
|
@@ -20060,7 +20179,7 @@ function checkMemberOverlayDrift() {
|
|
|
20060
20179
|
}
|
|
20061
20180
|
if (!stat.isFile())
|
|
20062
20181
|
continue;
|
|
20063
|
-
const cloneFile =
|
|
20182
|
+
const cloneFile = path73.join(clonePath, "members", atlasUser, `${kind}.overrides`, entry);
|
|
20064
20183
|
const localSha = sha256OfPath(localFile);
|
|
20065
20184
|
const cloneSha = sha256OfPath(cloneFile);
|
|
20066
20185
|
if (localSha === cloneSha) {
|
|
@@ -20229,7 +20348,7 @@ var project_sweep_exports = {};
|
|
|
20229
20348
|
__export(project_sweep_exports, {
|
|
20230
20349
|
walkProjectRoot: () => walkProjectRoot
|
|
20231
20350
|
});
|
|
20232
|
-
import * as
|
|
20351
|
+
import * as path74 from "node:path";
|
|
20233
20352
|
import { readdirSync as readdirSync25, lstatSync as lstatSync6, statSync as statSync25, existsSync as existsSync82 } from "node:fs";
|
|
20234
20353
|
function isSkipped(basename16, extra) {
|
|
20235
20354
|
if (DEFAULT_SKIP.has(basename16))
|
|
@@ -20241,7 +20360,7 @@ function isSkipped(basename16, extra) {
|
|
|
20241
20360
|
return false;
|
|
20242
20361
|
}
|
|
20243
20362
|
function resolveMtime(dirPath, manifestFile, fsAdapter) {
|
|
20244
|
-
const gitHead =
|
|
20363
|
+
const gitHead = path74.join(dirPath, ".git", "HEAD");
|
|
20245
20364
|
if (fsAdapter.existsSync(gitHead)) {
|
|
20246
20365
|
try {
|
|
20247
20366
|
return fsAdapter.statSync(gitHead).mtimeMs;
|
|
@@ -20255,8 +20374,8 @@ function resolveMtime(dirPath, manifestFile, fsAdapter) {
|
|
|
20255
20374
|
}
|
|
20256
20375
|
}
|
|
20257
20376
|
function walk2(currentPath, depth, maxDepth, extraExclude, fsAdapter, results) {
|
|
20258
|
-
const adbManifest =
|
|
20259
|
-
const olamManifest =
|
|
20377
|
+
const adbManifest = path74.join(currentPath, ".adb.yaml");
|
|
20378
|
+
const olamManifest = path74.join(currentPath, ".olam.yaml");
|
|
20260
20379
|
if (fsAdapter.existsSync(adbManifest)) {
|
|
20261
20380
|
const mtime = resolveMtime(currentPath, adbManifest, fsAdapter);
|
|
20262
20381
|
results.push({ path: currentPath, manifestType: "adb", mtime });
|
|
@@ -20278,7 +20397,7 @@ function walk2(currentPath, depth, maxDepth, extraExclude, fsAdapter, results) {
|
|
|
20278
20397
|
for (const entry of entries) {
|
|
20279
20398
|
if (isSkipped(entry, extraExclude))
|
|
20280
20399
|
continue;
|
|
20281
|
-
const childPath =
|
|
20400
|
+
const childPath = path74.join(currentPath, entry);
|
|
20282
20401
|
let stat;
|
|
20283
20402
|
try {
|
|
20284
20403
|
stat = fsAdapter.lstatSync(childPath);
|
|
@@ -20336,11 +20455,11 @@ __export(kg_eager_exports, {
|
|
|
20336
20455
|
writeQueue: () => writeQueue
|
|
20337
20456
|
});
|
|
20338
20457
|
import * as fs74 from "node:fs";
|
|
20339
|
-
import * as
|
|
20458
|
+
import * as path75 from "node:path";
|
|
20340
20459
|
import * as os40 from "node:os";
|
|
20341
20460
|
function defaultQueuePath() {
|
|
20342
|
-
const stateDir = process.env["OLAM_STATE_DIR"] ??
|
|
20343
|
-
return
|
|
20461
|
+
const stateDir = process.env["OLAM_STATE_DIR"] ?? path75.join(os40.homedir(), ".olam", "state");
|
|
20462
|
+
return path75.join(stateDir, "kg-pending.jsonl");
|
|
20344
20463
|
}
|
|
20345
20464
|
function readQueue(queuePath) {
|
|
20346
20465
|
if (!fs74.existsSync(queuePath))
|
|
@@ -20359,14 +20478,14 @@ function readQueue(queuePath) {
|
|
|
20359
20478
|
return entries;
|
|
20360
20479
|
}
|
|
20361
20480
|
function writeQueue(queuePath, entries) {
|
|
20362
|
-
fs74.mkdirSync(
|
|
20481
|
+
fs74.mkdirSync(path75.dirname(queuePath), { recursive: true });
|
|
20363
20482
|
const content = entries.map((e) => JSON.stringify(e)).join("\n") + (entries.length > 0 ? "\n" : "");
|
|
20364
20483
|
fs74.writeFileSync(queuePath, content, "utf-8");
|
|
20365
20484
|
}
|
|
20366
20485
|
function appendQueue(queuePath, repos, nowMs) {
|
|
20367
20486
|
if (repos.length === 0)
|
|
20368
20487
|
return;
|
|
20369
|
-
fs74.mkdirSync(
|
|
20488
|
+
fs74.mkdirSync(path75.dirname(queuePath), { recursive: true });
|
|
20370
20489
|
const lines = repos.map((r) => JSON.stringify({ path: r.path, addedAt: nowMs })).join("\n") + "\n";
|
|
20371
20490
|
fs74.appendFileSync(queuePath, lines, "utf-8");
|
|
20372
20491
|
}
|
|
@@ -20422,7 +20541,7 @@ __export(machine_schema_exports, {
|
|
|
20422
20541
|
writeMachineConfig: () => writeMachineConfig
|
|
20423
20542
|
});
|
|
20424
20543
|
import * as fs77 from "node:fs";
|
|
20425
|
-
import * as
|
|
20544
|
+
import * as path79 from "node:path";
|
|
20426
20545
|
import * as os41 from "node:os";
|
|
20427
20546
|
import { parse as parseYaml7, stringify as stringifyYaml5 } from "yaml";
|
|
20428
20547
|
function readMachineConfig(configPath) {
|
|
@@ -20439,7 +20558,7 @@ function readMachineConfig(configPath) {
|
|
|
20439
20558
|
}
|
|
20440
20559
|
function writeMachineConfig(config, configPath) {
|
|
20441
20560
|
const p = configPath ?? DEFAULT_CONFIG_PATH;
|
|
20442
|
-
fs77.mkdirSync(
|
|
20561
|
+
fs77.mkdirSync(path79.dirname(p), { recursive: true });
|
|
20443
20562
|
fs77.writeFileSync(p, stringifyYaml5({ ...config }), { mode: 420 });
|
|
20444
20563
|
}
|
|
20445
20564
|
function initMachineConfig(opts = {}) {
|
|
@@ -20463,9 +20582,9 @@ var init_machine_schema = __esm({
|
|
|
20463
20582
|
channel: external_exports.enum(["stable", "beta", "edge"]).default("stable"),
|
|
20464
20583
|
auto_update: external_exports.boolean().default(true),
|
|
20465
20584
|
telemetry: external_exports.boolean().default(true),
|
|
20466
|
-
worlds_dir: external_exports.string().default(() =>
|
|
20585
|
+
worlds_dir: external_exports.string().default(() => path79.join(os41.homedir(), ".olam", "worlds"))
|
|
20467
20586
|
});
|
|
20468
|
-
DEFAULT_CONFIG_PATH =
|
|
20587
|
+
DEFAULT_CONFIG_PATH = path79.join(os41.homedir(), ".olam", "config.yaml");
|
|
20469
20588
|
}
|
|
20470
20589
|
});
|
|
20471
20590
|
|
|
@@ -20660,16 +20779,16 @@ function isValidConfig(value) {
|
|
|
20660
20779
|
if (typeof v.install_id !== "string" || v.install_id.length === 0) return false;
|
|
20661
20780
|
return true;
|
|
20662
20781
|
}
|
|
20663
|
-
function atomicWriteJSON(
|
|
20782
|
+
function atomicWriteJSON(path96, value, stderr = process.stderr) {
|
|
20664
20783
|
ensureStateDir();
|
|
20665
|
-
const dir = dirname3(
|
|
20784
|
+
const dir = dirname3(path96);
|
|
20666
20785
|
if (!existsSync6(dir)) {
|
|
20667
20786
|
mkdirSync2(dir, { recursive: true });
|
|
20668
20787
|
}
|
|
20669
|
-
const tmp = `${
|
|
20788
|
+
const tmp = `${path96}.tmp.${process.pid}`;
|
|
20670
20789
|
try {
|
|
20671
20790
|
writeFileSync2(tmp, JSON.stringify(value, null, 2) + "\n", { encoding: "utf8" });
|
|
20672
|
-
renameSync2(tmp,
|
|
20791
|
+
renameSync2(tmp, path96);
|
|
20673
20792
|
} catch (err) {
|
|
20674
20793
|
if (existsSync6(tmp)) {
|
|
20675
20794
|
try {
|
|
@@ -21030,9 +21149,9 @@ var UnknownArchetypeError = class extends Error {
|
|
|
21030
21149
|
};
|
|
21031
21150
|
var ArchetypeCycleError = class extends Error {
|
|
21032
21151
|
path;
|
|
21033
|
-
constructor(
|
|
21034
|
-
super(`Archetype inheritance cycle detected: ${
|
|
21035
|
-
this.path =
|
|
21152
|
+
constructor(path96) {
|
|
21153
|
+
super(`Archetype inheritance cycle detected: ${path96.join(" \u2192 ")} \u2192 ${path96[0] ?? "?"}`);
|
|
21154
|
+
this.path = path96;
|
|
21036
21155
|
this.name = "ArchetypeCycleError";
|
|
21037
21156
|
}
|
|
21038
21157
|
};
|
|
@@ -21520,7 +21639,7 @@ function substitutePlaceholders(templateYaml, values) {
|
|
|
21520
21639
|
function renderOneSecret(binding, templatesRoot, reuse, deps = {}, rotate = false) {
|
|
21521
21640
|
const olamHome5 = deps.olamHome ?? OLAM_HOME;
|
|
21522
21641
|
const readFile = deps.readFile ?? defaultReadFile;
|
|
21523
|
-
const
|
|
21642
|
+
const writeFile2 = deps.writeFile ?? defaultWriteFile;
|
|
21524
21643
|
const fileExists = deps.fileExists ?? defaultFileExists;
|
|
21525
21644
|
const genRandomHex = deps.genRandomHex ?? defaultGenRandomHex;
|
|
21526
21645
|
const runGhTokenCmd = deps.runGhTokenCmd ?? defaultRunGhTokenCmd;
|
|
@@ -21535,7 +21654,7 @@ function renderOneSecret(binding, templatesRoot, reuse, deps = {}, rotate = fals
|
|
|
21535
21654
|
olamHome5,
|
|
21536
21655
|
reuse?.keys[p.key],
|
|
21537
21656
|
rotate,
|
|
21538
|
-
{ readFile, writeFile, fileExists, genRandomHex, runGhTokenCmd }
|
|
21657
|
+
{ readFile, writeFile: writeFile2, fileExists, genRandomHex, runGhTokenCmd }
|
|
21539
21658
|
);
|
|
21540
21659
|
if (!resolved.ok) {
|
|
21541
21660
|
missingSources.push(`${p.key}: ${resolved.reason}`);
|
|
@@ -21831,14 +21950,14 @@ function ensureSecrets() {
|
|
|
21831
21950
|
step("1/6 \u2014 operator secrets");
|
|
21832
21951
|
mkdirSync19(OLAM_HOME3, { recursive: true });
|
|
21833
21952
|
for (const name of SECRET_FILES) {
|
|
21834
|
-
const
|
|
21835
|
-
if (existsSync29(
|
|
21953
|
+
const path96 = join34(OLAM_HOME3, name);
|
|
21954
|
+
if (existsSync29(path96)) {
|
|
21836
21955
|
printInfo("skip", `~/.olam/${name} already exists`);
|
|
21837
21956
|
continue;
|
|
21838
21957
|
}
|
|
21839
21958
|
const hex = randomBytes7(32).toString("hex");
|
|
21840
|
-
writeFileSync15(
|
|
21841
|
-
chmodSync4(
|
|
21959
|
+
writeFileSync15(path96, hex + "\n", { encoding: "utf8", mode: 384 });
|
|
21960
|
+
chmodSync4(path96, 384);
|
|
21842
21961
|
printSuccess(`generated ~/.olam/${name}`);
|
|
21843
21962
|
}
|
|
21844
21963
|
}
|
|
@@ -21961,13 +22080,13 @@ function installObservability(opts) {
|
|
|
21961
22080
|
scriptEnv.OLAM_BUNDLE_ROOT = bundleRoot;
|
|
21962
22081
|
}
|
|
21963
22082
|
for (const script of OBSERVABILITY_SCRIPTS) {
|
|
21964
|
-
const
|
|
21965
|
-
if (!existsSync29(
|
|
22083
|
+
const path96 = join34(observabilityDir, script);
|
|
22084
|
+
if (!existsSync29(path96)) {
|
|
21966
22085
|
printWarning(`observability script missing: ${script} \u2014 skipping`);
|
|
21967
22086
|
continue;
|
|
21968
22087
|
}
|
|
21969
22088
|
printInfo("run", script);
|
|
21970
|
-
const result = spawnSync10("bash", [
|
|
22089
|
+
const result = spawnSync10("bash", [path96], {
|
|
21971
22090
|
stdio: "inherit",
|
|
21972
22091
|
env: scriptEnv
|
|
21973
22092
|
});
|
|
@@ -22976,56 +23095,56 @@ var SECRET_LEN_BYTES = 32;
|
|
|
22976
23095
|
function generateSecret() {
|
|
22977
23096
|
return randomBytes8(SECRET_LEN_BYTES).toString("hex");
|
|
22978
23097
|
}
|
|
22979
|
-
function writeSecretAtPath(
|
|
22980
|
-
mkdirSync21(dirname22(
|
|
22981
|
-
const tmp = `${
|
|
23098
|
+
function writeSecretAtPath(path96, value) {
|
|
23099
|
+
mkdirSync21(dirname22(path96), { recursive: true });
|
|
23100
|
+
const tmp = `${path96}.tmp.${process.pid}`;
|
|
22982
23101
|
writeFileSync16(tmp, value, { mode: 384 });
|
|
22983
23102
|
chmodSync5(tmp, 384);
|
|
22984
|
-
renameSync6(tmp,
|
|
23103
|
+
renameSync6(tmp, path96);
|
|
22985
23104
|
}
|
|
22986
|
-
function readSecretAtPathOrNull(
|
|
22987
|
-
if (!existsSync32(
|
|
22988
|
-
const mode = statSync8(
|
|
23105
|
+
function readSecretAtPathOrNull(path96) {
|
|
23106
|
+
if (!existsSync32(path96)) return null;
|
|
23107
|
+
const mode = statSync8(path96).mode & 511;
|
|
22989
23108
|
if (mode !== 384) {
|
|
22990
23109
|
process.stderr.write(
|
|
22991
|
-
`warn: ${
|
|
23110
|
+
`warn: ${path96} has mode 0${mode.toString(8)}; expected 0600. Run 'olam memory secret rotate' to regenerate.
|
|
22992
23111
|
`
|
|
22993
23112
|
);
|
|
22994
23113
|
}
|
|
22995
|
-
return readFileSync25(
|
|
23114
|
+
return readFileSync25(path96, "utf8").trim();
|
|
22996
23115
|
}
|
|
22997
|
-
function readSecretAtPath(
|
|
22998
|
-
const v = readSecretAtPathOrNull(
|
|
23116
|
+
function readSecretAtPath(path96) {
|
|
23117
|
+
const v = readSecretAtPathOrNull(path96);
|
|
22999
23118
|
if (v === null) {
|
|
23000
23119
|
throw new Error(
|
|
23001
|
-
`Secret not found at ${
|
|
23120
|
+
`Secret not found at ${path96}. Run 'olam memory start' to generate it.`
|
|
23002
23121
|
);
|
|
23003
23122
|
}
|
|
23004
23123
|
return v;
|
|
23005
23124
|
}
|
|
23006
|
-
function ensureMemorySecret(
|
|
23007
|
-
const existing = readSecretAtPathOrNull(
|
|
23125
|
+
function ensureMemorySecret(path96 = MEMORY_SECRET_PATH) {
|
|
23126
|
+
const existing = readSecretAtPathOrNull(path96);
|
|
23008
23127
|
if (existing) return existing;
|
|
23009
23128
|
const fresh = generateSecret();
|
|
23010
|
-
writeSecretAtPath(
|
|
23129
|
+
writeSecretAtPath(path96, fresh);
|
|
23011
23130
|
return fresh;
|
|
23012
23131
|
}
|
|
23013
|
-
function readMemorySecretOrNull(
|
|
23014
|
-
return readSecretAtPathOrNull(
|
|
23132
|
+
function readMemorySecretOrNull(path96 = MEMORY_SECRET_PATH) {
|
|
23133
|
+
return readSecretAtPathOrNull(path96);
|
|
23015
23134
|
}
|
|
23016
|
-
function readMemorySecret(
|
|
23017
|
-
return readSecretAtPath(
|
|
23135
|
+
function readMemorySecret(path96 = MEMORY_SECRET_PATH) {
|
|
23136
|
+
return readSecretAtPath(path96);
|
|
23018
23137
|
}
|
|
23019
|
-
function rotateMemorySecret(
|
|
23138
|
+
function rotateMemorySecret(path96 = MEMORY_SECRET_PATH) {
|
|
23020
23139
|
const fresh = generateSecret();
|
|
23021
|
-
writeSecretAtPath(
|
|
23140
|
+
writeSecretAtPath(path96, fresh);
|
|
23022
23141
|
return fresh;
|
|
23023
23142
|
}
|
|
23024
|
-
function hasMemorySecret(
|
|
23025
|
-
return existsSync32(
|
|
23143
|
+
function hasMemorySecret(path96 = MEMORY_SECRET_PATH) {
|
|
23144
|
+
return existsSync32(path96);
|
|
23026
23145
|
}
|
|
23027
|
-
function writeCloudMemorySecret(value,
|
|
23028
|
-
writeSecretAtPath(
|
|
23146
|
+
function writeCloudMemorySecret(value, path96 = CLOUD_MEMORY_SECRET_PATH) {
|
|
23147
|
+
writeSecretAtPath(path96, value);
|
|
23029
23148
|
}
|
|
23030
23149
|
|
|
23031
23150
|
// src/commands/memory-service-container.ts
|
|
@@ -25194,9 +25313,9 @@ function formatFreshnessWarning(result, image = DEFAULT_DEVBOX_IMAGE) {
|
|
|
25194
25313
|
"These source files have changed since the image was built; the",
|
|
25195
25314
|
"changes will NOT take effect in fresh worlds until you rebuild:"
|
|
25196
25315
|
];
|
|
25197
|
-
for (const { path:
|
|
25316
|
+
for (const { path: path96, mtimeMs } of result.newerSources) {
|
|
25198
25317
|
const when = new Date(mtimeMs).toISOString();
|
|
25199
|
-
lines.push(` \u2022 ${
|
|
25318
|
+
lines.push(` \u2022 ${path96} (modified ${when})`);
|
|
25200
25319
|
}
|
|
25201
25320
|
lines.push("");
|
|
25202
25321
|
lines.push("Rebuild with:");
|
|
@@ -25577,9 +25696,9 @@ async function readHostCpTokenForCreate() {
|
|
|
25577
25696
|
try {
|
|
25578
25697
|
const { default: fs96 } = await import("node:fs");
|
|
25579
25698
|
const { default: os50 } = await import("node:os");
|
|
25580
|
-
const { default:
|
|
25581
|
-
const tp =
|
|
25582
|
-
process.env.OLAM_HOME ??
|
|
25699
|
+
const { default: path96 } = await import("node:path");
|
|
25700
|
+
const tp = path96.join(
|
|
25701
|
+
process.env.OLAM_HOME ?? path96.join(os50.homedir(), ".olam"),
|
|
25583
25702
|
"host-cp.token"
|
|
25584
25703
|
);
|
|
25585
25704
|
if (!fs96.existsSync(tp)) return null;
|
|
@@ -25592,7 +25711,10 @@ function registerCreate(program2) {
|
|
|
25592
25711
|
program2.command("create").description("Create a new development world").option("--name <name>", "World name (required unless --from-prompt is set; auto-derived in that case)").option("--repos <repos...>", "Repos to include (names from .olam/config.yaml; wins over --workspace)").option("--workspace <name>", "Named workspace from the host catalog (~/.olam/workspaces/<name>.yaml)").option("--task <task>", "Initial task to dispatch").option("--branch <branch>", "Override default branch name").option("--plan <file>", "Path to a plan file to inject").option("--no-auth", "Skip auto-injecting host credentials").option("--no-host-cp", 'Suppress the host CP "you might want to start it" hint').option("--auto-codex-review", "Spawn a parallel codex-review lane that critiques main as it works").option("--no-open", "Suppress auto-opening the Host CP UI in the browser on success").option("--rebuild-base", "Rebuild olam-devbox:latest before creating (slow)").option("--no-freshness-check", "Skip the devbox image freshness check").option("--from-prompt <prompt>", "NL prompt \u2192 infer workspace + dispatch (CLI parity for olam_create_from_prompt MCP tool)").option("--keep-after-merge", "Disable auto-destroy when the world's PR merges (useful for inspection/debugging)").option("--carry-uncommitted", "Preserve operator's uncommitted edits in the world's worktree").option(
|
|
25593
25712
|
"--allow-bootstrap-failure",
|
|
25594
25713
|
"Treat bootstrap step failures as warnings instead of destroying the world (dogfood escape hatch for cross-repo seed coupling)"
|
|
25595
|
-
).option("--devbox-image <ref>", "Override the default devbox image (full registry/name:tag or @sha256: ref)").option("--allow-custom-registry", "Allow --devbox-image refs outside ghcr.io/pleri/* (logs a warning)").option("--runbook <name>", "Named runbook profile from ~/.olam/config.json").
|
|
25714
|
+
).option("--devbox-image <ref>", "Override the default devbox image (full registry/name:tag or @sha256: ref)").option("--allow-custom-registry", "Allow --devbox-image refs outside ghcr.io/pleri/* (logs a warning)").option("--runbook <name>", "Named runbook profile from ~/.olam/config.json").option(
|
|
25715
|
+
"--claude-home <id-or-path>",
|
|
25716
|
+
"Use a per-world Claude Code HOME (multi-account isolation; see docs/decisions/045-claude-home-override.md)"
|
|
25717
|
+
).action(async (opts) => {
|
|
25596
25718
|
const { resolveDevboxImageOverride: resolveDevboxImageOverride2, decideAllowlist: decideAllowlist2 } = await Promise.resolve().then(() => (init_registry_allowlist(), registry_allowlist_exports));
|
|
25597
25719
|
const overrideRef = resolveDevboxImageOverride2(opts.devboxImage);
|
|
25598
25720
|
if (overrideRef) {
|
|
@@ -25770,6 +25892,25 @@ function registerCreate(program2) {
|
|
|
25770
25892
|
throw err;
|
|
25771
25893
|
}
|
|
25772
25894
|
}
|
|
25895
|
+
let resolvedClaudeHome;
|
|
25896
|
+
if (opts.claudeHome !== void 0 && opts.claudeHome.length > 0) {
|
|
25897
|
+
try {
|
|
25898
|
+
const { resolveClaudeHome: resolveClaudeHome2, ensureClaudeHomeDir: ensureClaudeHomeDir2 } = await Promise.resolve().then(() => (init_home_override(), home_override_exports));
|
|
25899
|
+
const target = resolveClaudeHome2({ flag: opts.claudeHome });
|
|
25900
|
+
await ensureClaudeHomeDir2(target);
|
|
25901
|
+
resolvedClaudeHome = target;
|
|
25902
|
+
printInfo(
|
|
25903
|
+
"Claude home",
|
|
25904
|
+
`${target} (per-world Claude Code instance \u2014 see ADR 045)`
|
|
25905
|
+
);
|
|
25906
|
+
} catch (err) {
|
|
25907
|
+
printError(
|
|
25908
|
+
`Invalid --claude-home: ${err instanceof Error ? err.message : String(err)}`
|
|
25909
|
+
);
|
|
25910
|
+
process.exitCode = 1;
|
|
25911
|
+
return;
|
|
25912
|
+
}
|
|
25913
|
+
}
|
|
25773
25914
|
const spinner = ora5("Creating world...").start();
|
|
25774
25915
|
try {
|
|
25775
25916
|
const world = await ctx.worldManager.createWorld({
|
|
@@ -25788,7 +25929,8 @@ function registerCreate(program2) {
|
|
|
25788
25929
|
// manager, matching the manager's strict `if (!opts.carryUncommitted)`.
|
|
25789
25930
|
carryUncommitted: opts.carryUncommitted === true,
|
|
25790
25931
|
allowBootstrapFailure: opts.allowBootstrapFailure === true,
|
|
25791
|
-
...opts.runbook ? { runbookName: opts.runbook } : {}
|
|
25932
|
+
...opts.runbook ? { runbookName: opts.runbook } : {},
|
|
25933
|
+
...resolvedClaudeHome ? { claudeHome: resolvedClaudeHome } : {}
|
|
25792
25934
|
});
|
|
25793
25935
|
spinner.succeed("World created");
|
|
25794
25936
|
try {
|
|
@@ -26022,8 +26164,8 @@ async function readHostCpToken3() {
|
|
|
26022
26164
|
try {
|
|
26023
26165
|
const { default: fs96 } = await import("node:fs");
|
|
26024
26166
|
const { default: os50 } = await import("node:os");
|
|
26025
|
-
const { default:
|
|
26026
|
-
const tp =
|
|
26167
|
+
const { default: path96 } = await import("node:path");
|
|
26168
|
+
const tp = path96.join(os50.homedir(), ".olam", "host-cp.token");
|
|
26027
26169
|
if (!fs96.existsSync(tp)) return null;
|
|
26028
26170
|
const raw = fs96.readFileSync(tp, "utf-8").trim();
|
|
26029
26171
|
return raw.length > 0 ? raw : null;
|
|
@@ -26240,7 +26382,7 @@ init_output();
|
|
|
26240
26382
|
import * as fs36 from "node:fs";
|
|
26241
26383
|
import * as http3 from "node:http";
|
|
26242
26384
|
import * as os18 from "node:os";
|
|
26243
|
-
import * as
|
|
26385
|
+
import * as path38 from "node:path";
|
|
26244
26386
|
var CLI_VERSION2 = process.env["OLAM_CLI_VERSION"] ?? "0.0.0";
|
|
26245
26387
|
var HOST_CP_PORT2 = 19e3;
|
|
26246
26388
|
var STATE_ENUM = [
|
|
@@ -26331,7 +26473,7 @@ async function getMachineStatus(_probe, _loadCtx, _readToken) {
|
|
|
26331
26473
|
}
|
|
26332
26474
|
} catch {
|
|
26333
26475
|
}
|
|
26334
|
-
const manifestPath2 =
|
|
26476
|
+
const manifestPath2 = path38.join(os18.homedir(), ".olam", "cache", "manifest.json");
|
|
26335
26477
|
let updateAvailable = null;
|
|
26336
26478
|
let lastUpdateCheck = null;
|
|
26337
26479
|
if (fs36.existsSync(manifestPath2)) {
|
|
@@ -26477,7 +26619,7 @@ init_context();
|
|
|
26477
26619
|
init_output();
|
|
26478
26620
|
import fs37 from "node:fs";
|
|
26479
26621
|
import os19 from "node:os";
|
|
26480
|
-
import
|
|
26622
|
+
import path39 from "node:path";
|
|
26481
26623
|
import { execFileSync as execFileSync9 } from "node:child_process";
|
|
26482
26624
|
function registerClean(program2) {
|
|
26483
26625
|
program2.command("clean").description("Reap orphan world filesystem state under ~/.olam/worlds/").option("--apply", "Actually delete the orphans (default is dry-run)", false).option(
|
|
@@ -26501,7 +26643,7 @@ async function runClean(opts) {
|
|
|
26501
26643
|
printError(error?.message ?? "Olam is not configured. Run `olam init` first.");
|
|
26502
26644
|
return 1;
|
|
26503
26645
|
}
|
|
26504
|
-
const worldsDir =
|
|
26646
|
+
const worldsDir = path39.join(os19.homedir(), ".olam", "worlds");
|
|
26505
26647
|
if (!fs37.existsSync(worldsDir)) {
|
|
26506
26648
|
if (opts.json) {
|
|
26507
26649
|
process.stdout.write(`${JSON.stringify({ worldsDir, entries: [] })}
|
|
@@ -26518,7 +26660,7 @@ async function runClean(opts) {
|
|
|
26518
26660
|
const worktreeMap = collectWorktrees(worldsDir);
|
|
26519
26661
|
const entries = [];
|
|
26520
26662
|
for (const id of fs37.readdirSync(worldsDir).sort()) {
|
|
26521
|
-
const fullPath =
|
|
26663
|
+
const fullPath = path39.join(worldsDir, id);
|
|
26522
26664
|
const stat = safeStat(fullPath);
|
|
26523
26665
|
if (!stat || !stat.isDirectory()) continue;
|
|
26524
26666
|
entries.push(classifyWorld({ id, fullPath, liveIds, worktreeMap }));
|
|
@@ -26584,7 +26726,7 @@ function classifyWorld(args) {
|
|
|
26584
26726
|
if (liveIds.has(id)) {
|
|
26585
26727
|
return { id, path: fullPath, bytes, category: "active", note: "in registry" };
|
|
26586
26728
|
}
|
|
26587
|
-
const worktreeChild =
|
|
26729
|
+
const worktreeChild = path39.join(fullPath, "olam");
|
|
26588
26730
|
const worktreeInfo = worktreeMap.get(worktreeChild);
|
|
26589
26731
|
if (worktreeInfo) {
|
|
26590
26732
|
if (worktreeInfo.dirty > 0 || worktreeInfo.unpushed > 0) {
|
|
@@ -26641,8 +26783,8 @@ function reapEntry(entry) {
|
|
|
26641
26783
|
function collectWorktrees(worldsDir) {
|
|
26642
26784
|
const out = /* @__PURE__ */ new Map();
|
|
26643
26785
|
for (const id of fs37.readdirSync(worldsDir)) {
|
|
26644
|
-
const child =
|
|
26645
|
-
const gitMarker =
|
|
26786
|
+
const child = path39.join(worldsDir, id, "olam");
|
|
26787
|
+
const gitMarker = path39.join(child, ".git");
|
|
26646
26788
|
if (!fs37.existsSync(gitMarker)) continue;
|
|
26647
26789
|
const gitDir = resolveGitDirForWorktree(child);
|
|
26648
26790
|
if (!gitDir) continue;
|
|
@@ -26654,7 +26796,7 @@ function collectWorktrees(worldsDir) {
|
|
|
26654
26796
|
return out;
|
|
26655
26797
|
}
|
|
26656
26798
|
function resolveGitDirForWorktree(worktreePath) {
|
|
26657
|
-
const gitMarker =
|
|
26799
|
+
const gitMarker = path39.join(worktreePath, ".git");
|
|
26658
26800
|
try {
|
|
26659
26801
|
const top = execFileSync9("git", ["rev-parse", "--show-toplevel"], {
|
|
26660
26802
|
cwd: worktreePath,
|
|
@@ -26668,7 +26810,7 @@ function resolveGitDirForWorktree(worktreePath) {
|
|
|
26668
26810
|
stdio: "pipe"
|
|
26669
26811
|
}).trim();
|
|
26670
26812
|
if (!common) return top;
|
|
26671
|
-
return
|
|
26813
|
+
return path39.dirname(path39.resolve(worktreePath, common));
|
|
26672
26814
|
} catch {
|
|
26673
26815
|
return null;
|
|
26674
26816
|
}
|
|
@@ -26735,7 +26877,7 @@ function computeBytes(p) {
|
|
|
26735
26877
|
} catch {
|
|
26736
26878
|
continue;
|
|
26737
26879
|
}
|
|
26738
|
-
for (const name of entries) stack.push(
|
|
26880
|
+
for (const name of entries) stack.push(path39.join(cur, name));
|
|
26739
26881
|
} else {
|
|
26740
26882
|
total += st.size;
|
|
26741
26883
|
}
|
|
@@ -26789,7 +26931,7 @@ init_output();
|
|
|
26789
26931
|
import { execFileSync as execFileSync10 } from "node:child_process";
|
|
26790
26932
|
import * as fs38 from "node:fs";
|
|
26791
26933
|
import * as os20 from "node:os";
|
|
26792
|
-
import * as
|
|
26934
|
+
import * as path40 from "node:path";
|
|
26793
26935
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
26794
26936
|
import pc17 from "picocolors";
|
|
26795
26937
|
var NPM_PACKAGE = "@pleri/olam-cli";
|
|
@@ -26811,7 +26953,7 @@ var realExec = (cmd, args) => {
|
|
|
26811
26953
|
};
|
|
26812
26954
|
function surveyOlam(opts = {}) {
|
|
26813
26955
|
const exec = opts.exec ?? realExec;
|
|
26814
|
-
const home = opts.olamHome ??
|
|
26956
|
+
const home = opts.olamHome ?? path40.join(os20.homedir(), ".olam");
|
|
26815
26957
|
const containers = listDocker(exec, ["ps", "-a", "--format", "{{.Names}}"]).filter(
|
|
26816
26958
|
(n) => n.startsWith("olam-")
|
|
26817
26959
|
);
|
|
@@ -26825,11 +26967,11 @@ function surveyOlam(opts = {}) {
|
|
|
26825
26967
|
(n) => n.startsWith("olam-") && n !== "olam-host-cp-internal-default"
|
|
26826
26968
|
);
|
|
26827
26969
|
const worlds = [];
|
|
26828
|
-
const worldsDir =
|
|
26970
|
+
const worldsDir = path40.join(home, "worlds");
|
|
26829
26971
|
if (fs38.existsSync(worldsDir)) {
|
|
26830
26972
|
for (const entry of fs38.readdirSync(worldsDir, { withFileTypes: true })) {
|
|
26831
26973
|
if (!entry.isDirectory()) continue;
|
|
26832
|
-
const wPath =
|
|
26974
|
+
const wPath = path40.join(worldsDir, entry.name);
|
|
26833
26975
|
const bytes = dirSize(wPath);
|
|
26834
26976
|
const { dirty, note } = inspectWorldGitState(wPath);
|
|
26835
26977
|
worlds.push({ id: entry.name, bytes, dirty, note, path: wPath });
|
|
@@ -26838,7 +26980,7 @@ function surveyOlam(opts = {}) {
|
|
|
26838
26980
|
const homeBytesNonWorld = fs38.existsSync(home) ? Math.max(0, dirSize(home) - worlds.reduce((acc, w) => acc + w.bytes, 0)) : 0;
|
|
26839
26981
|
const npmRoot = exec("npm", ["root", "-g"]);
|
|
26840
26982
|
const npmGlobalRoot = npmRoot.exitCode === 0 ? npmRoot.stdout.trim() : null;
|
|
26841
|
-
const npmInstalled = npmGlobalRoot !== null && fs38.existsSync(
|
|
26983
|
+
const npmInstalled = npmGlobalRoot !== null && fs38.existsSync(path40.join(npmGlobalRoot, NPM_PACKAGE));
|
|
26842
26984
|
return {
|
|
26843
26985
|
containers,
|
|
26844
26986
|
images,
|
|
@@ -26868,7 +27010,7 @@ function dirSize(p) {
|
|
|
26868
27010
|
continue;
|
|
26869
27011
|
}
|
|
26870
27012
|
for (const e of entries) {
|
|
26871
|
-
const full =
|
|
27013
|
+
const full = path40.join(cur, e.name);
|
|
26872
27014
|
try {
|
|
26873
27015
|
if (e.isDirectory()) stack.push(full);
|
|
26874
27016
|
else if (e.isFile()) total += fs38.statSync(full).size;
|
|
@@ -26886,8 +27028,8 @@ function inspectWorldGitState(worldPath) {
|
|
|
26886
27028
|
try {
|
|
26887
27029
|
for (const entry of fs38.readdirSync(worldPath, { withFileTypes: true })) {
|
|
26888
27030
|
if (!entry.isDirectory()) continue;
|
|
26889
|
-
const repo =
|
|
26890
|
-
const gitDir =
|
|
27031
|
+
const repo = path40.join(worldPath, entry.name);
|
|
27032
|
+
const gitDir = path40.join(repo, ".git");
|
|
26891
27033
|
if (!fs38.existsSync(gitDir)) continue;
|
|
26892
27034
|
try {
|
|
26893
27035
|
const status2 = execFileSync10("git", ["status", "--porcelain"], {
|
|
@@ -26981,7 +27123,7 @@ function formatBytes3(n) {
|
|
|
26981
27123
|
}
|
|
26982
27124
|
async function executeImplode(survey, opts) {
|
|
26983
27125
|
const exec = opts.exec ?? realExec;
|
|
26984
|
-
const home = opts.olamHome ??
|
|
27126
|
+
const home = opts.olamHome ?? path40.join(os20.homedir(), ".olam");
|
|
26985
27127
|
const removed = [];
|
|
26986
27128
|
const skipped = [];
|
|
26987
27129
|
const errors = [];
|
|
@@ -27045,7 +27187,7 @@ async function executeImplode(survey, opts) {
|
|
|
27045
27187
|
skipped.push(`fs:~/.olam/auth-data (--keep-vault)`);
|
|
27046
27188
|
continue;
|
|
27047
27189
|
}
|
|
27048
|
-
const target =
|
|
27190
|
+
const target = path40.join(home, entry.name);
|
|
27049
27191
|
try {
|
|
27050
27192
|
fs38.rmSync(target, { recursive: true, force: true });
|
|
27051
27193
|
removed.push(`fs:${target}`);
|
|
@@ -27220,6 +27362,11 @@ function registerEnter(program2) {
|
|
|
27220
27362
|
if (worldMeta) {
|
|
27221
27363
|
const { checkVersionPin: checkVersionPin2 } = await Promise.resolve().then(() => (init_version_pin(), version_pin_exports));
|
|
27222
27364
|
checkVersionPin2(worldId, worldMeta.workspacePath);
|
|
27365
|
+
if (worldMeta.claudeHome) {
|
|
27366
|
+
console.log(
|
|
27367
|
+
pc18.dim(`# claude-home: ${worldMeta.claudeHome} (per-world Claude Code instance, ADR 045)`)
|
|
27368
|
+
);
|
|
27369
|
+
}
|
|
27223
27370
|
}
|
|
27224
27371
|
const computeWorld = await ctx.computeProvider.getWorld(worldId);
|
|
27225
27372
|
if (!computeWorld) {
|
|
@@ -27308,6 +27455,138 @@ ${pc18.dim(`Observe dispatch: docker exec -it ${containerName} tmux attach -t ol
|
|
|
27308
27455
|
});
|
|
27309
27456
|
}
|
|
27310
27457
|
|
|
27458
|
+
// src/commands/resume.ts
|
|
27459
|
+
init_context();
|
|
27460
|
+
init_output();
|
|
27461
|
+
import { execFileSync as execFileSync11 } from "node:child_process";
|
|
27462
|
+
function looksLikePrIdentifier(input2) {
|
|
27463
|
+
if (/^\d+$/.test(input2.trim())) return true;
|
|
27464
|
+
if (/^https?:\/\/[^\s]*\/pull\/\d+(?:[/?#].*)?$/i.test(input2.trim())) return true;
|
|
27465
|
+
return false;
|
|
27466
|
+
}
|
|
27467
|
+
async function runResume(input2, deps) {
|
|
27468
|
+
const trimmed = input2.trim();
|
|
27469
|
+
if (trimmed.length === 0) {
|
|
27470
|
+
deps.stderr("resume: argument <pr> is required (PR number, URL, or branch name).");
|
|
27471
|
+
return 1;
|
|
27472
|
+
}
|
|
27473
|
+
let resolved;
|
|
27474
|
+
try {
|
|
27475
|
+
resolved = await deps.resolveInput(trimmed);
|
|
27476
|
+
} catch (err) {
|
|
27477
|
+
deps.stderr(
|
|
27478
|
+
`resume: could not resolve "${trimmed}" via gh pr view \u2014 ` + (err instanceof Error ? err.message : String(err))
|
|
27479
|
+
);
|
|
27480
|
+
return 1;
|
|
27481
|
+
}
|
|
27482
|
+
const { branch, prNumber } = resolved;
|
|
27483
|
+
const worlds = deps.listWorlds();
|
|
27484
|
+
const matches2 = worlds.filter((w) => w.branch === branch);
|
|
27485
|
+
const prLabel = prNumber !== void 0 ? `PR #${prNumber}` : `branch ${branch}`;
|
|
27486
|
+
if (matches2.length === 0) {
|
|
27487
|
+
deps.stderr(
|
|
27488
|
+
`No active world found for ${prLabel} (branch ${branch}). Worlds visible via olam list.`
|
|
27489
|
+
);
|
|
27490
|
+
return 1;
|
|
27491
|
+
}
|
|
27492
|
+
if (matches2.length > 1) {
|
|
27493
|
+
deps.stderr(
|
|
27494
|
+
`Multiple worlds match ${prLabel} (branch ${branch}); operator decides:`
|
|
27495
|
+
);
|
|
27496
|
+
for (const w of matches2) {
|
|
27497
|
+
deps.stderr(` - ${w.name} (${w.id})`);
|
|
27498
|
+
}
|
|
27499
|
+
return 1;
|
|
27500
|
+
}
|
|
27501
|
+
const match2 = matches2[0];
|
|
27502
|
+
deps.stdout(
|
|
27503
|
+
`Found world ${match2.name} (${match2.id}) for ${prLabel}. Entering...`
|
|
27504
|
+
);
|
|
27505
|
+
try {
|
|
27506
|
+
deps.enterWorld(match2.id);
|
|
27507
|
+
} catch (err) {
|
|
27508
|
+
deps.stderr(
|
|
27509
|
+
`resume: olam enter ${match2.id} failed \u2014 ` + (err instanceof Error ? err.message : String(err))
|
|
27510
|
+
);
|
|
27511
|
+
return 1;
|
|
27512
|
+
}
|
|
27513
|
+
return 0;
|
|
27514
|
+
}
|
|
27515
|
+
function resolveInputViaGh(input2) {
|
|
27516
|
+
if (!looksLikePrIdentifier(input2)) {
|
|
27517
|
+
if (input2.length === 0) {
|
|
27518
|
+
return Promise.reject(new Error("empty branch name"));
|
|
27519
|
+
}
|
|
27520
|
+
return Promise.resolve({ branch: input2 });
|
|
27521
|
+
}
|
|
27522
|
+
let stdout;
|
|
27523
|
+
try {
|
|
27524
|
+
stdout = execFileSync11("gh", ["pr", "view", input2, "--json", "number,headRefName"], {
|
|
27525
|
+
encoding: "utf-8",
|
|
27526
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
27527
|
+
timeout: 1e4
|
|
27528
|
+
});
|
|
27529
|
+
} catch (err) {
|
|
27530
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
27531
|
+
return Promise.reject(new Error(`gh pr view failed: ${msg}`));
|
|
27532
|
+
}
|
|
27533
|
+
let parsed;
|
|
27534
|
+
try {
|
|
27535
|
+
parsed = JSON.parse(stdout);
|
|
27536
|
+
} catch (err) {
|
|
27537
|
+
return Promise.reject(
|
|
27538
|
+
new Error(`gh pr view returned non-JSON output: ${err instanceof Error ? err.message : String(err)}`)
|
|
27539
|
+
);
|
|
27540
|
+
}
|
|
27541
|
+
if (typeof parsed.headRefName !== "string" || parsed.headRefName.length === 0) {
|
|
27542
|
+
return Promise.reject(new Error("gh pr view response missing headRefName"));
|
|
27543
|
+
}
|
|
27544
|
+
const prNumber = typeof parsed.number === "number" ? parsed.number : void 0;
|
|
27545
|
+
return Promise.resolve({ branch: parsed.headRefName, prNumber });
|
|
27546
|
+
}
|
|
27547
|
+
function registerResume(program2) {
|
|
27548
|
+
program2.command("resume").description(
|
|
27549
|
+
"Resume a world by PR number, URL, or branch \u2014 finds the world that opened the PR and enters it."
|
|
27550
|
+
).argument("<pr>", "PR number (876), PR URL, or branch name").addHelpText(
|
|
27551
|
+
"after",
|
|
27552
|
+
`
|
|
27553
|
+
Examples:
|
|
27554
|
+
$ olam resume 876
|
|
27555
|
+
$ olam resume https://github.com/pleri/olam/pull/876
|
|
27556
|
+
$ olam resume night/feat/foo
|
|
27557
|
+
`
|
|
27558
|
+
).action(async (pr) => {
|
|
27559
|
+
const { ctx, error } = await loadContext();
|
|
27560
|
+
if (!ctx) {
|
|
27561
|
+
printError(error?.message ?? "Olam is not configured. Run `olam init` first.");
|
|
27562
|
+
process.exitCode = 1;
|
|
27563
|
+
return;
|
|
27564
|
+
}
|
|
27565
|
+
const code = await runResume(pr, {
|
|
27566
|
+
resolveInput: resolveInputViaGh,
|
|
27567
|
+
listWorlds: () => ctx.worldManager.listWorlds().map((w) => ({
|
|
27568
|
+
id: w.id,
|
|
27569
|
+
name: w.name,
|
|
27570
|
+
branch: w.branch
|
|
27571
|
+
})),
|
|
27572
|
+
enterWorld: (worldId) => {
|
|
27573
|
+
const entry = process.argv[1];
|
|
27574
|
+
if (!entry) {
|
|
27575
|
+
throw new Error("cannot locate CLI entry script (process.argv[1] missing)");
|
|
27576
|
+
}
|
|
27577
|
+
execFileSync11(process.execPath, [entry, "enter", worldId, "--exec"], {
|
|
27578
|
+
stdio: "inherit"
|
|
27579
|
+
});
|
|
27580
|
+
},
|
|
27581
|
+
stdout: (line) => console.log(line),
|
|
27582
|
+
stderr: (line) => printError(line)
|
|
27583
|
+
});
|
|
27584
|
+
if (code !== 0) {
|
|
27585
|
+
process.exitCode = code;
|
|
27586
|
+
}
|
|
27587
|
+
});
|
|
27588
|
+
}
|
|
27589
|
+
|
|
27311
27590
|
// src/commands/crystallize.ts
|
|
27312
27591
|
init_context();
|
|
27313
27592
|
init_output();
|
|
@@ -27573,7 +27852,7 @@ init_host_cp();
|
|
|
27573
27852
|
// src/lib/plans-client.ts
|
|
27574
27853
|
import * as fs40 from "node:fs";
|
|
27575
27854
|
import * as os21 from "node:os";
|
|
27576
|
-
import * as
|
|
27855
|
+
import * as path42 from "node:path";
|
|
27577
27856
|
var PlansClientError = class extends Error {
|
|
27578
27857
|
constructor(status2, message, body) {
|
|
27579
27858
|
super(message);
|
|
@@ -27584,7 +27863,7 @@ var PlansClientError = class extends Error {
|
|
|
27584
27863
|
status;
|
|
27585
27864
|
body;
|
|
27586
27865
|
};
|
|
27587
|
-
var OLAM_HOME4 =
|
|
27866
|
+
var OLAM_HOME4 = path42.join(os21.homedir(), ".olam");
|
|
27588
27867
|
function readFileOrNull(p) {
|
|
27589
27868
|
try {
|
|
27590
27869
|
return fs40.readFileSync(p, "utf8").trim();
|
|
@@ -27593,9 +27872,9 @@ function readFileOrNull(p) {
|
|
|
27593
27872
|
}
|
|
27594
27873
|
}
|
|
27595
27874
|
function resolveCloudConfig() {
|
|
27596
|
-
const cloudUrl = process.env.OLAM_CLOUD_URL ?? readFileOrNull(
|
|
27875
|
+
const cloudUrl = process.env.OLAM_CLOUD_URL ?? readFileOrNull(path42.join(OLAM_HOME4, "cloud-url"));
|
|
27597
27876
|
if (!cloudUrl) return null;
|
|
27598
|
-
const bearer = process.env.OLAM_SHOWCASE_PASSWORD ?? readFileOrNull(
|
|
27877
|
+
const bearer = process.env.OLAM_SHOWCASE_PASSWORD ?? readFileOrNull(path42.join(OLAM_HOME4, "showcase-password"));
|
|
27599
27878
|
if (!bearer) return null;
|
|
27600
27879
|
return { cloudUrl: cloudUrl.replace(/\/+$/, ""), bearer };
|
|
27601
27880
|
}
|
|
@@ -27609,13 +27888,13 @@ var PlansClient = class {
|
|
|
27609
27888
|
const credentials = Buffer.from(`operator:${this.cfg.bearer}`).toString("base64");
|
|
27610
27889
|
return `Basic ${credentials}`;
|
|
27611
27890
|
}
|
|
27612
|
-
async request(
|
|
27891
|
+
async request(path96, init) {
|
|
27613
27892
|
const headers = {
|
|
27614
27893
|
Authorization: this.authHeader()
|
|
27615
27894
|
};
|
|
27616
27895
|
if (init.body) headers["content-type"] = "application/json";
|
|
27617
27896
|
if (init.adminSecret) headers["X-Admin-Secret"] = init.adminSecret;
|
|
27618
|
-
return fetch(`${this.cfg.cloudUrl}${
|
|
27897
|
+
return fetch(`${this.cfg.cloudUrl}${path96}`, {
|
|
27619
27898
|
method: init.method,
|
|
27620
27899
|
headers,
|
|
27621
27900
|
body: init.body ? JSON.stringify(init.body) : void 0
|
|
@@ -28987,11 +29266,11 @@ var qmarksTestNoExtDot = ([$0]) => {
|
|
|
28987
29266
|
return (f) => f.length === len && f !== "." && f !== "..";
|
|
28988
29267
|
};
|
|
28989
29268
|
var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
|
|
28990
|
-
var
|
|
29269
|
+
var path43 = {
|
|
28991
29270
|
win32: { sep: "\\" },
|
|
28992
29271
|
posix: { sep: "/" }
|
|
28993
29272
|
};
|
|
28994
|
-
var sep2 = defaultPlatform === "win32" ?
|
|
29273
|
+
var sep2 = defaultPlatform === "win32" ? path43.win32.sep : path43.posix.sep;
|
|
28995
29274
|
minimatch.sep = sep2;
|
|
28996
29275
|
var GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
|
|
28997
29276
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
@@ -30100,11 +30379,11 @@ function zodIssueToError(issue, doc, lineCounter) {
|
|
|
30100
30379
|
suggestion: deriveSuggestion(issue)
|
|
30101
30380
|
};
|
|
30102
30381
|
}
|
|
30103
|
-
function formatJsonPath(
|
|
30104
|
-
if (
|
|
30382
|
+
function formatJsonPath(path96) {
|
|
30383
|
+
if (path96.length === 0)
|
|
30105
30384
|
return "<root>";
|
|
30106
30385
|
let out = "";
|
|
30107
|
-
for (const seg of
|
|
30386
|
+
for (const seg of path96) {
|
|
30108
30387
|
if (typeof seg === "number") {
|
|
30109
30388
|
out += `[${seg}]`;
|
|
30110
30389
|
} else {
|
|
@@ -30113,11 +30392,11 @@ function formatJsonPath(path95) {
|
|
|
30113
30392
|
}
|
|
30114
30393
|
return out;
|
|
30115
30394
|
}
|
|
30116
|
-
function resolveYamlLocation(
|
|
30395
|
+
function resolveYamlLocation(path96, doc, lineCounter) {
|
|
30117
30396
|
let bestLine = 0;
|
|
30118
30397
|
let bestColumn = 0;
|
|
30119
|
-
for (let depth =
|
|
30120
|
-
const segment =
|
|
30398
|
+
for (let depth = path96.length; depth >= 0; depth -= 1) {
|
|
30399
|
+
const segment = path96.slice(0, depth);
|
|
30121
30400
|
try {
|
|
30122
30401
|
const node = doc.getIn(segment, true);
|
|
30123
30402
|
if (node && typeof node === "object" && "range" in node) {
|
|
@@ -30335,11 +30614,11 @@ function topoSort(nodes) {
|
|
|
30335
30614
|
}
|
|
30336
30615
|
function traceCycle(start, byId) {
|
|
30337
30616
|
const seen = /* @__PURE__ */ new Set();
|
|
30338
|
-
const
|
|
30617
|
+
const path96 = [];
|
|
30339
30618
|
let current = start;
|
|
30340
30619
|
while (current && !seen.has(current)) {
|
|
30341
30620
|
seen.add(current);
|
|
30342
|
-
|
|
30621
|
+
path96.push(current);
|
|
30343
30622
|
const node = byId.get(current);
|
|
30344
30623
|
const next = node?.dependsOn[0];
|
|
30345
30624
|
if (next === void 0)
|
|
@@ -30347,10 +30626,10 @@ function traceCycle(start, byId) {
|
|
|
30347
30626
|
current = next;
|
|
30348
30627
|
}
|
|
30349
30628
|
if (current && seen.has(current)) {
|
|
30350
|
-
const idx =
|
|
30351
|
-
return [...
|
|
30629
|
+
const idx = path96.indexOf(current);
|
|
30630
|
+
return [...path96.slice(idx), current];
|
|
30352
30631
|
}
|
|
30353
|
-
return
|
|
30632
|
+
return path96;
|
|
30354
30633
|
}
|
|
30355
30634
|
|
|
30356
30635
|
// ../core/dist/executor/types.js
|
|
@@ -30574,11 +30853,11 @@ async function resolveDigests(lockfile, resolver) {
|
|
|
30574
30853
|
}
|
|
30575
30854
|
|
|
30576
30855
|
// ../core/dist/worldspec/image-digest.js
|
|
30577
|
-
import { execFileSync as
|
|
30856
|
+
import { execFileSync as execFileSync12 } from "node:child_process";
|
|
30578
30857
|
var DOCKER_SUBPROCESS_TIMEOUT_MS = 3e4;
|
|
30579
30858
|
var dockerDigestResolver = async (image, source) => {
|
|
30580
30859
|
if (source === "local") {
|
|
30581
|
-
const out =
|
|
30860
|
+
const out = execFileSync12("docker", ["inspect", image, "--format", "{{.Id}}"], {
|
|
30582
30861
|
encoding: "utf8",
|
|
30583
30862
|
stdio: ["ignore", "pipe", "pipe"],
|
|
30584
30863
|
timeout: DOCKER_SUBPROCESS_TIMEOUT_MS,
|
|
@@ -30589,7 +30868,7 @@ var dockerDigestResolver = async (image, source) => {
|
|
|
30589
30868
|
}
|
|
30590
30869
|
return out;
|
|
30591
30870
|
}
|
|
30592
|
-
const raw =
|
|
30871
|
+
const raw = execFileSync12("docker", ["buildx", "imagetools", "inspect", image], {
|
|
30593
30872
|
encoding: "utf8",
|
|
30594
30873
|
stdio: ["ignore", "pipe", "pipe"],
|
|
30595
30874
|
timeout: DOCKER_SUBPROCESS_TIMEOUT_MS,
|
|
@@ -32250,7 +32529,7 @@ function registerWorldspec(program2) {
|
|
|
32250
32529
|
init_output();
|
|
32251
32530
|
init_host_cp();
|
|
32252
32531
|
import * as fs43 from "node:fs";
|
|
32253
|
-
import * as
|
|
32532
|
+
import * as path46 from "node:path";
|
|
32254
32533
|
import { spawnSync as spawnSync22 } from "node:child_process";
|
|
32255
32534
|
import ora9 from "ora";
|
|
32256
32535
|
import pc21 from "picocolors";
|
|
@@ -32258,9 +32537,9 @@ import pc21 from "picocolors";
|
|
|
32258
32537
|
// src/commands/upgrade-lock.ts
|
|
32259
32538
|
import * as fs41 from "node:fs";
|
|
32260
32539
|
import * as os22 from "node:os";
|
|
32261
|
-
import * as
|
|
32540
|
+
import * as path44 from "node:path";
|
|
32262
32541
|
import { spawnSync as spawnSync21 } from "node:child_process";
|
|
32263
|
-
var LOCK_FILE_PATH =
|
|
32542
|
+
var LOCK_FILE_PATH = path44.join(os22.homedir(), ".olam", ".upgrade.lock");
|
|
32264
32543
|
var STALE_LOCK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
32265
32544
|
function readLockFile(lockPath) {
|
|
32266
32545
|
try {
|
|
@@ -32310,7 +32589,7 @@ function isStaleLock(content, nowMs = Date.now()) {
|
|
|
32310
32589
|
return false;
|
|
32311
32590
|
}
|
|
32312
32591
|
function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
|
|
32313
|
-
const dir =
|
|
32592
|
+
const dir = path44.dirname(lockPath);
|
|
32314
32593
|
fs41.mkdirSync(dir, { recursive: true });
|
|
32315
32594
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
32316
32595
|
try {
|
|
@@ -32373,15 +32652,15 @@ function formatRefusalMessage(result, lockPath = LOCK_FILE_PATH) {
|
|
|
32373
32652
|
// src/commands/upgrade-log.ts
|
|
32374
32653
|
import * as fs42 from "node:fs";
|
|
32375
32654
|
import * as os23 from "node:os";
|
|
32376
|
-
import * as
|
|
32655
|
+
import * as path45 from "node:path";
|
|
32377
32656
|
function getUpgradeLogPath() {
|
|
32378
32657
|
const home = process.env["HOME"] ?? os23.homedir();
|
|
32379
|
-
return
|
|
32658
|
+
return path45.join(home, ".olam", "upgrade.log");
|
|
32380
32659
|
}
|
|
32381
32660
|
var UPGRADE_LOG_PATH = getUpgradeLogPath();
|
|
32382
32661
|
function appendUpgradeLog(row, logPath = getUpgradeLogPath()) {
|
|
32383
32662
|
try {
|
|
32384
|
-
fs42.mkdirSync(
|
|
32663
|
+
fs42.mkdirSync(path45.dirname(logPath), { recursive: true });
|
|
32385
32664
|
const line = JSON.stringify(row) + "\n";
|
|
32386
32665
|
fs42.appendFileSync(logPath, line, { mode: 420 });
|
|
32387
32666
|
} catch (err) {
|
|
@@ -32488,8 +32767,8 @@ init_protocol_version();
|
|
|
32488
32767
|
init_install_root();
|
|
32489
32768
|
var AUTH_HEALTH_URL2 = "http://127.0.0.1:9999/health";
|
|
32490
32769
|
function isNodeModulesInSync(cwd) {
|
|
32491
|
-
const lockPath =
|
|
32492
|
-
const markerPath =
|
|
32770
|
+
const lockPath = path46.join(cwd, "package-lock.json");
|
|
32771
|
+
const markerPath = path46.join(cwd, "node_modules", ".package-lock.json");
|
|
32493
32772
|
if (!fs43.existsSync(lockPath) || !fs43.existsSync(markerPath)) return false;
|
|
32494
32773
|
try {
|
|
32495
32774
|
const lockStat = fs43.statSync(lockPath);
|
|
@@ -32509,7 +32788,7 @@ function shouldSkipInstall(opts, cwd) {
|
|
|
32509
32788
|
return { skip: false };
|
|
32510
32789
|
}
|
|
32511
32790
|
function validateRepoRoot(cwd) {
|
|
32512
|
-
const marker =
|
|
32791
|
+
const marker = path46.join(cwd, "packages/host-cp/compose.yaml");
|
|
32513
32792
|
if (!fs43.existsSync(marker)) {
|
|
32514
32793
|
return {
|
|
32515
32794
|
ok: false,
|
|
@@ -32870,7 +33149,7 @@ async function recreateAuthService() {
|
|
|
32870
33149
|
}
|
|
32871
33150
|
}
|
|
32872
33151
|
function readBundleHash(cwd) {
|
|
32873
|
-
const indexPath =
|
|
33152
|
+
const indexPath = path46.join(cwd, "packages/control-plane/public/index.html");
|
|
32874
33153
|
if (!fs43.existsSync(indexPath)) return null;
|
|
32875
33154
|
return extractBundleHash(fs43.readFileSync(indexPath, "utf-8"));
|
|
32876
33155
|
}
|
|
@@ -33476,7 +33755,7 @@ ${buildResult.stderr}`);
|
|
|
33476
33755
|
return;
|
|
33477
33756
|
}
|
|
33478
33757
|
const authSecret = readAuthSecret2();
|
|
33479
|
-
const spaDir =
|
|
33758
|
+
const spaDir = path46.join(cwd, "packages/control-plane/app");
|
|
33480
33759
|
const spaResult = runStep2(
|
|
33481
33760
|
"vite build (SPA)",
|
|
33482
33761
|
"npx",
|
|
@@ -34019,13 +34298,13 @@ ${pc23.dim(`world: ${worldId} sort: ${sortKey} refresh: 5s Ctrl-C to exit`)}
|
|
|
34019
34298
|
init_output();
|
|
34020
34299
|
import * as fs44 from "node:fs";
|
|
34021
34300
|
import * as os24 from "node:os";
|
|
34022
|
-
import * as
|
|
34301
|
+
import * as path47 from "node:path";
|
|
34023
34302
|
import YAML6 from "yaml";
|
|
34024
34303
|
function olamHome3() {
|
|
34025
|
-
return process.env.OLAM_HOME ??
|
|
34304
|
+
return process.env.OLAM_HOME ?? path47.join(os24.homedir(), ".olam");
|
|
34026
34305
|
}
|
|
34027
34306
|
function keysFilePath() {
|
|
34028
|
-
return
|
|
34307
|
+
return path47.join(olamHome3(), "keys.yaml");
|
|
34029
34308
|
}
|
|
34030
34309
|
function readKeysFile() {
|
|
34031
34310
|
const filePath = keysFilePath();
|
|
@@ -34121,7 +34400,7 @@ function registerKeys(program2) {
|
|
|
34121
34400
|
init_snapshot();
|
|
34122
34401
|
init_output();
|
|
34123
34402
|
import * as fs45 from "node:fs";
|
|
34124
|
-
import * as
|
|
34403
|
+
import * as path48 from "node:path";
|
|
34125
34404
|
import { execSync as execSync11 } from "node:child_process";
|
|
34126
34405
|
import pc24 from "picocolors";
|
|
34127
34406
|
|
|
@@ -34144,9 +34423,9 @@ function emitDeprecationWarning(subcommand) {
|
|
|
34144
34423
|
}
|
|
34145
34424
|
function bumpDeprecationCounter() {
|
|
34146
34425
|
if (process.env[INTERNAL_SENTINEL_ENV] === "1") return;
|
|
34147
|
-
const counterPath =
|
|
34426
|
+
const counterPath = path48.join(snapshotsDir(), ".deprecation-counter");
|
|
34148
34427
|
try {
|
|
34149
|
-
fs45.mkdirSync(
|
|
34428
|
+
fs45.mkdirSync(path48.dirname(counterPath), { recursive: true });
|
|
34150
34429
|
let current = 0;
|
|
34151
34430
|
if (fs45.existsSync(counterPath)) {
|
|
34152
34431
|
const raw = fs45.readFileSync(counterPath, "utf-8").trim();
|
|
@@ -34229,13 +34508,13 @@ function resolveKinds(arg) {
|
|
|
34229
34508
|
return [];
|
|
34230
34509
|
}
|
|
34231
34510
|
async function captureGems(worldId, workspacePath, repo) {
|
|
34232
|
-
const repoDir =
|
|
34511
|
+
const repoDir = path48.join(workspacePath, repo);
|
|
34233
34512
|
const fingerprint = computeGemsFingerprint(repoDir);
|
|
34234
34513
|
if (!fingerprint) {
|
|
34235
34514
|
return { ok: false, tarPath: "", msg: "no Gemfile.lock \u2014 layer does not apply" };
|
|
34236
34515
|
}
|
|
34237
34516
|
const tarPath = snapshotTarPath(worldId, "gems", repo, fingerprint);
|
|
34238
|
-
const vendorBundle =
|
|
34517
|
+
const vendorBundle = path48.join(repoDir, "vendor", "bundle");
|
|
34239
34518
|
if (fs45.existsSync(vendorBundle)) {
|
|
34240
34519
|
try {
|
|
34241
34520
|
packTarball(vendorBundle, tarPath);
|
|
@@ -34272,7 +34551,7 @@ async function captureGems(worldId, workspacePath, repo) {
|
|
|
34272
34551
|
`docker exec ${containerName} sh -c 'mkdir -p "$(dirname ${tmpTar})" && tar -czf ${tmpTar}.tmp -C ${bundlePath} . && mv ${tmpTar}.tmp ${tmpTar}'`,
|
|
34273
34552
|
{ stdio: "pipe", timeout: 12e4 }
|
|
34274
34553
|
);
|
|
34275
|
-
fs45.mkdirSync(
|
|
34554
|
+
fs45.mkdirSync(path48.dirname(tarPath), { recursive: true });
|
|
34276
34555
|
execSync11(`docker cp ${containerName}:${tmpTar} "${tarPath}"`, { stdio: "pipe", timeout: 12e4 });
|
|
34277
34556
|
execSync11(`docker exec ${containerName} rm -f ${tmpTar}`, { stdio: "pipe" });
|
|
34278
34557
|
const stat = fs45.statSync(tarPath);
|
|
@@ -34292,12 +34571,12 @@ async function captureGems(worldId, workspacePath, repo) {
|
|
|
34292
34571
|
}
|
|
34293
34572
|
}
|
|
34294
34573
|
async function captureNode(worldId, workspacePath, repo) {
|
|
34295
|
-
const repoDir =
|
|
34574
|
+
const repoDir = path48.join(workspacePath, repo);
|
|
34296
34575
|
const fingerprint = computeNodeFingerprint(repoDir);
|
|
34297
34576
|
if (!fingerprint) {
|
|
34298
34577
|
return { ok: false, tarPath: "", msg: "no lockfile \u2014 layer does not apply" };
|
|
34299
34578
|
}
|
|
34300
|
-
const nodeModules =
|
|
34579
|
+
const nodeModules = path48.join(repoDir, "node_modules");
|
|
34301
34580
|
if (!fs45.existsSync(nodeModules)) {
|
|
34302
34581
|
return { ok: false, tarPath: "", msg: "node_modules not installed yet" };
|
|
34303
34582
|
}
|
|
@@ -34321,7 +34600,7 @@ async function captureNode(worldId, workspacePath, repo) {
|
|
|
34321
34600
|
}
|
|
34322
34601
|
}
|
|
34323
34602
|
async function capturePg(worldId, workspacePath, repoNames) {
|
|
34324
|
-
const repoDirs = repoNames.map((r) =>
|
|
34603
|
+
const repoDirs = repoNames.map((r) => path48.join(workspacePath, r));
|
|
34325
34604
|
const fingerprint = computePgFingerprint(repoDirs);
|
|
34326
34605
|
if (!fingerprint) {
|
|
34327
34606
|
return { ok: false, tarPath: "", msg: "no Gemfile.lock / schema.rb \u2014 layer does not apply" };
|
|
@@ -34336,9 +34615,9 @@ async function capturePg(worldId, workspacePath, repoNames) {
|
|
|
34336
34615
|
}
|
|
34337
34616
|
try {
|
|
34338
34617
|
execSync11(`docker stop ${containerName}`, { stdio: "pipe", timeout: 3e4 });
|
|
34339
|
-
fs45.mkdirSync(
|
|
34618
|
+
fs45.mkdirSync(path48.dirname(tarPath), { recursive: true });
|
|
34340
34619
|
execSync11(
|
|
34341
|
-
`docker run --rm -v "${volumeName2}:/pgdata:ro" -v "${
|
|
34620
|
+
`docker run --rm -v "${volumeName2}:/pgdata:ro" -v "${path48.dirname(tarPath)}:/dest" alpine sh -c 'tar -czf /dest/${path48.basename(tarPath)}.tmp -C /pgdata . && mv /dest/${path48.basename(tarPath)}.tmp /dest/${path48.basename(tarPath)}'`,
|
|
34342
34621
|
{ stdio: "pipe", timeout: 18e4 }
|
|
34343
34622
|
);
|
|
34344
34623
|
execSync11(`docker start ${containerName}`, { stdio: "pipe", timeout: 3e4 });
|
|
@@ -34373,7 +34652,7 @@ async function handleEvict(opts) {
|
|
|
34373
34652
|
const allTars = [];
|
|
34374
34653
|
const walk3 = (d) => {
|
|
34375
34654
|
for (const entry of fs45.readdirSync(d, { withFileTypes: true })) {
|
|
34376
|
-
const full =
|
|
34655
|
+
const full = path48.join(d, entry.name);
|
|
34377
34656
|
if (entry.isDirectory()) {
|
|
34378
34657
|
walk3(full);
|
|
34379
34658
|
} else if (entry.name.endsWith(".tar.gz")) {
|
|
@@ -34472,33 +34751,33 @@ init_context();
|
|
|
34472
34751
|
init_output();
|
|
34473
34752
|
import * as fs47 from "node:fs";
|
|
34474
34753
|
import * as os25 from "node:os";
|
|
34475
|
-
import * as
|
|
34754
|
+
import * as path50 from "node:path";
|
|
34476
34755
|
import { spawnSync as spawnSync24 } from "node:child_process";
|
|
34477
34756
|
import ora10 from "ora";
|
|
34478
34757
|
|
|
34479
34758
|
// src/commands/refresh-helpers.ts
|
|
34480
34759
|
import * as fs46 from "node:fs";
|
|
34481
|
-
import * as
|
|
34760
|
+
import * as path49 from "node:path";
|
|
34482
34761
|
function collectCpSourceFiles(standaloneDir) {
|
|
34483
34762
|
if (!fs46.existsSync(standaloneDir)) {
|
|
34484
34763
|
throw new Error(`CP standalone dir not found: ${standaloneDir}`);
|
|
34485
34764
|
}
|
|
34486
34765
|
const entries = [];
|
|
34487
34766
|
const topLevel = fs46.readdirSync(standaloneDir).filter((f) => {
|
|
34488
|
-
const stat = fs46.statSync(
|
|
34767
|
+
const stat = fs46.statSync(path49.join(standaloneDir, f));
|
|
34489
34768
|
return stat.isFile() && f.endsWith(".mjs") && !f.endsWith(".test.mjs");
|
|
34490
34769
|
}).sort();
|
|
34491
34770
|
for (const f of topLevel) {
|
|
34492
|
-
entries.push({ srcPath:
|
|
34771
|
+
entries.push({ srcPath: path49.join(standaloneDir, f), destRelPath: f });
|
|
34493
34772
|
}
|
|
34494
|
-
const libDir =
|
|
34773
|
+
const libDir = path49.join(standaloneDir, "lib");
|
|
34495
34774
|
if (fs46.existsSync(libDir) && fs46.statSync(libDir).isDirectory()) {
|
|
34496
34775
|
const libFiles = fs46.readdirSync(libDir).filter((f) => {
|
|
34497
|
-
const stat = fs46.statSync(
|
|
34776
|
+
const stat = fs46.statSync(path49.join(libDir, f));
|
|
34498
34777
|
return stat.isFile() && f.endsWith(".mjs") && !f.endsWith(".test.mjs");
|
|
34499
34778
|
}).sort();
|
|
34500
34779
|
for (const f of libFiles) {
|
|
34501
|
-
entries.push({ srcPath:
|
|
34780
|
+
entries.push({ srcPath: path49.join(libDir, f), destRelPath: `lib/${f}` });
|
|
34502
34781
|
}
|
|
34503
34782
|
}
|
|
34504
34783
|
return entries;
|
|
@@ -34557,15 +34836,15 @@ async function refreshWorld(worldId, portOffset, standaloneDir, opts) {
|
|
|
34557
34836
|
};
|
|
34558
34837
|
}
|
|
34559
34838
|
const stagingDir = fs47.mkdtempSync(
|
|
34560
|
-
|
|
34839
|
+
path50.join(os25.tmpdir(), `olam-refresh-${worldId}-`)
|
|
34561
34840
|
);
|
|
34562
34841
|
try {
|
|
34563
34842
|
const hasLib = entries.some((e) => e.destRelPath.startsWith("lib/"));
|
|
34564
34843
|
if (hasLib) {
|
|
34565
|
-
fs47.mkdirSync(
|
|
34844
|
+
fs47.mkdirSync(path50.join(stagingDir, "lib"), { recursive: true });
|
|
34566
34845
|
}
|
|
34567
34846
|
for (const { srcPath, destRelPath } of entries) {
|
|
34568
|
-
fs47.copyFileSync(srcPath,
|
|
34847
|
+
fs47.copyFileSync(srcPath, path50.join(stagingDir, destRelPath));
|
|
34569
34848
|
}
|
|
34570
34849
|
const cpResult = docker([
|
|
34571
34850
|
"cp",
|
|
@@ -34617,7 +34896,7 @@ function registerRefresh(program2) {
|
|
|
34617
34896
|
process.exitCode = 1;
|
|
34618
34897
|
return;
|
|
34619
34898
|
}
|
|
34620
|
-
const standaloneDir =
|
|
34899
|
+
const standaloneDir = path50.join(
|
|
34621
34900
|
process.cwd(),
|
|
34622
34901
|
"packages/control-plane/standalone"
|
|
34623
34902
|
);
|
|
@@ -34785,8 +35064,8 @@ function registerRestart(program2) {
|
|
|
34785
35064
|
// src/commands/diagnose.ts
|
|
34786
35065
|
import * as fs48 from "node:fs";
|
|
34787
35066
|
import * as os26 from "node:os";
|
|
34788
|
-
import * as
|
|
34789
|
-
import { execFileSync as
|
|
35067
|
+
import * as path51 from "node:path";
|
|
35068
|
+
import { execFileSync as execFileSync13, execSync as execSync12 } from "node:child_process";
|
|
34790
35069
|
import pc25 from "picocolors";
|
|
34791
35070
|
|
|
34792
35071
|
// ../core/dist/diagnose/secret-stripper.js
|
|
@@ -34820,9 +35099,9 @@ function stripSecrets(input2) {
|
|
|
34820
35099
|
}
|
|
34821
35100
|
|
|
34822
35101
|
// src/commands/diagnose.ts
|
|
34823
|
-
var DIAGNOSTICS_DIR =
|
|
34824
|
-
var LOG_DIR =
|
|
34825
|
-
var CACHE_DIR =
|
|
35102
|
+
var DIAGNOSTICS_DIR = path51.join(os26.homedir(), ".olam", "diagnostics");
|
|
35103
|
+
var LOG_DIR = path51.join(os26.homedir(), ".olam", "log");
|
|
35104
|
+
var CACHE_DIR = path51.join(os26.homedir(), ".olam", "cache");
|
|
34826
35105
|
var LOG_TAIL_LINES = 200;
|
|
34827
35106
|
function safeExec(cmd) {
|
|
34828
35107
|
try {
|
|
@@ -34832,12 +35111,12 @@ function safeExec(cmd) {
|
|
|
34832
35111
|
}
|
|
34833
35112
|
}
|
|
34834
35113
|
function defaultZip(zipPath, files) {
|
|
34835
|
-
|
|
35114
|
+
execFileSync13("zip", ["-j", zipPath, ...files]);
|
|
34836
35115
|
}
|
|
34837
35116
|
async function buildDiagnosticsZip(_exec = (cmd) => safeExec(cmd), _outDir = DIAGNOSTICS_DIR, _logDir = LOG_DIR, _zip = defaultZip) {
|
|
34838
35117
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 23);
|
|
34839
|
-
const zipPath =
|
|
34840
|
-
const tmpDir = fs48.mkdtempSync(
|
|
35118
|
+
const zipPath = path51.join(_outDir, `olam-diag-${ts}.zip`);
|
|
35119
|
+
const tmpDir = fs48.mkdtempSync(path51.join(os26.tmpdir(), "olam-diag-"));
|
|
34841
35120
|
try {
|
|
34842
35121
|
fs48.mkdirSync(_outDir, { recursive: true });
|
|
34843
35122
|
const entries = [];
|
|
@@ -34855,7 +35134,7 @@ platform: ${platform2}
|
|
|
34855
35134
|
`uptime: ${os26.uptime()}s`
|
|
34856
35135
|
].join("\n") + "\n";
|
|
34857
35136
|
_writeEntry(tmpDir, "os-info.txt", stripSecrets(osContent), entries);
|
|
34858
|
-
const depsFile =
|
|
35137
|
+
const depsFile = path51.join(CACHE_DIR, "deps.json");
|
|
34859
35138
|
if (fs48.existsSync(depsFile)) {
|
|
34860
35139
|
const deps = fs48.readFileSync(depsFile, "utf-8");
|
|
34861
35140
|
_writeEntry(tmpDir, "deps.json", stripSecrets(deps), entries);
|
|
@@ -34874,7 +35153,7 @@ platform: ${platform2}
|
|
|
34874
35153
|
if (authAudit) {
|
|
34875
35154
|
_writeEntry(tmpDir, "audit-auth-callers.txt", stripSecrets(authAudit), entries);
|
|
34876
35155
|
}
|
|
34877
|
-
const fileArgs = entries.map((e) =>
|
|
35156
|
+
const fileArgs = entries.map((e) => path51.join(tmpDir, e));
|
|
34878
35157
|
try {
|
|
34879
35158
|
_zip(zipPath, fileArgs);
|
|
34880
35159
|
} catch (err) {
|
|
@@ -34892,17 +35171,17 @@ platform: ${platform2}
|
|
|
34892
35171
|
}
|
|
34893
35172
|
}
|
|
34894
35173
|
function _writeEntry(dir, name, content, entries) {
|
|
34895
|
-
fs48.writeFileSync(
|
|
35174
|
+
fs48.writeFileSync(path51.join(dir, name), content, { mode: 420 });
|
|
34896
35175
|
entries.push(name);
|
|
34897
35176
|
}
|
|
34898
35177
|
function _latestLog(logDir) {
|
|
34899
35178
|
if (!fs48.existsSync(logDir)) return null;
|
|
34900
35179
|
const files = fs48.readdirSync(logDir).filter((f) => f.startsWith("host-")).sort().reverse();
|
|
34901
|
-
return files.length > 0 ?
|
|
35180
|
+
return files.length > 0 ? path51.join(logDir, files[0]) : null;
|
|
34902
35181
|
}
|
|
34903
35182
|
async function buildTelemetryPayload() {
|
|
34904
35183
|
const channel = "stable";
|
|
34905
|
-
const manifestFile =
|
|
35184
|
+
const manifestFile = path51.join(CACHE_DIR, "manifest.json");
|
|
34906
35185
|
let manifestAgeHours = null;
|
|
34907
35186
|
if (fs48.existsSync(manifestFile)) {
|
|
34908
35187
|
const mtime = fs48.statSync(manifestFile).mtime.getTime();
|
|
@@ -35057,8 +35336,8 @@ function checkWorld(container, hostShas, dockerExec) {
|
|
|
35057
35336
|
const m = shaLine.match(/^([a-f0-9]{64})\s+(.+)$/);
|
|
35058
35337
|
if (!m) continue;
|
|
35059
35338
|
const sha = m[1];
|
|
35060
|
-
const
|
|
35061
|
-
const filename =
|
|
35339
|
+
const path96 = m[2];
|
|
35340
|
+
const filename = path96?.split("/").pop();
|
|
35062
35341
|
if (!filename) continue;
|
|
35063
35342
|
const mtimeSecs = parseInt(mtimeLine.trim(), 10);
|
|
35064
35343
|
if (Number.isNaN(mtimeSecs) || !sha) continue;
|
|
@@ -35106,28 +35385,28 @@ function resolveRepoRootBestEffort() {
|
|
|
35106
35385
|
init_output();
|
|
35107
35386
|
import * as fs50 from "node:fs";
|
|
35108
35387
|
import * as net4 from "node:net";
|
|
35109
|
-
import * as
|
|
35388
|
+
import * as path53 from "node:path";
|
|
35110
35389
|
import * as os27 from "node:os";
|
|
35111
35390
|
|
|
35112
35391
|
// src/commands/hermes-kg-hook.ts
|
|
35113
35392
|
import * as fs49 from "node:fs";
|
|
35114
|
-
import * as
|
|
35393
|
+
import * as path52 from "node:path";
|
|
35115
35394
|
import { createHash as createHash5 } from "node:crypto";
|
|
35116
35395
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
35117
35396
|
var HERMES_KG_HOOK_SENTINEL = "OLAM_KG_HOOK";
|
|
35118
35397
|
function bundleDir() {
|
|
35119
35398
|
const thisFile = fileURLToPath6(import.meta.url);
|
|
35120
|
-
return
|
|
35399
|
+
return path52.resolve(path52.dirname(thisFile), "..", "..", "hermes-bundle");
|
|
35121
35400
|
}
|
|
35122
35401
|
function templateContent() {
|
|
35123
|
-
const templatePath =
|
|
35402
|
+
const templatePath = path52.join(bundleDir(), "kg-first.sh");
|
|
35124
35403
|
return fs49.readFileSync(templatePath);
|
|
35125
35404
|
}
|
|
35126
35405
|
function sha256(buf) {
|
|
35127
35406
|
return createHash5("sha256").update(buf).digest("hex");
|
|
35128
35407
|
}
|
|
35129
35408
|
function installKgFirstHookForHermes(hooksDir, dryRun) {
|
|
35130
|
-
const destPath2 =
|
|
35409
|
+
const destPath2 = path52.join(hooksDir, "kg-first.sh");
|
|
35131
35410
|
const template = templateContent();
|
|
35132
35411
|
if (fs49.existsSync(destPath2)) {
|
|
35133
35412
|
const existing = fs49.readFileSync(destPath2);
|
|
@@ -35203,7 +35482,7 @@ async function runDoctor(opts, deps = {}) {
|
|
|
35203
35482
|
if (isK8s) {
|
|
35204
35483
|
const wrapImpl = deps.kubectlWrapImpl ?? kubectlWrap;
|
|
35205
35484
|
const k8sCtx = deps.kubectlContext;
|
|
35206
|
-
const manifestsDir = deps.manifestsDir ??
|
|
35485
|
+
const manifestsDir = deps.manifestsDir ?? path53.join(OLAM_HOME, "k8s", "manifests");
|
|
35207
35486
|
const readFileSyncImpl = deps.readFileSyncImpl ?? fs50.readFileSync;
|
|
35208
35487
|
const sortedPeripherals = [...PERIPHERALS].sort((a, b) => a.name.localeCompare(b.name));
|
|
35209
35488
|
let peripheralPosition = 14;
|
|
@@ -35340,7 +35619,7 @@ async function probeStorageClassMatch(peripherals, kubectlContext, manifestsDir,
|
|
|
35340
35619
|
const ctxArgs = kubectlContext ? ["--context", kubectlContext] : [];
|
|
35341
35620
|
const mismatches = [];
|
|
35342
35621
|
for (const peripheral of peripherals) {
|
|
35343
|
-
const pvcManifestPath =
|
|
35622
|
+
const pvcManifestPath = path53.join(manifestsDir, peripheral.name, "45-pvc.yaml");
|
|
35344
35623
|
let declaredClass;
|
|
35345
35624
|
try {
|
|
35346
35625
|
const raw = readFileSyncImpl(pvcManifestPath, "utf8");
|
|
@@ -35453,7 +35732,7 @@ function probeNodeMemory(dockerExec, kubectlContext) {
|
|
|
35453
35732
|
function defaultResolveHostSideProxyComposePath() {
|
|
35454
35733
|
const root = resolveK8sAssetsRoot();
|
|
35455
35734
|
if (root === null) return null;
|
|
35456
|
-
const candidate =
|
|
35735
|
+
const candidate = path53.join(root, "host-side", "docker-socket-proxy.compose.yaml");
|
|
35457
35736
|
return fs50.existsSync(candidate) ? candidate : null;
|
|
35458
35737
|
}
|
|
35459
35738
|
async function defaultDockerSocketCheck(composePath) {
|
|
@@ -35590,8 +35869,8 @@ function renderHuman(report) {
|
|
|
35590
35869
|
}
|
|
35591
35870
|
}
|
|
35592
35871
|
function probeHermesIntegration(hermesDir) {
|
|
35593
|
-
const configPath =
|
|
35594
|
-
const hookPath =
|
|
35872
|
+
const configPath = path53.join(hermesDir, "config.yaml");
|
|
35873
|
+
const hookPath = path53.join(hermesDir, "hooks", "kg-first.sh");
|
|
35595
35874
|
const issues = [];
|
|
35596
35875
|
if (!fs50.existsSync(configPath)) {
|
|
35597
35876
|
issues.push("~/.hermes/config.yaml not found");
|
|
@@ -35632,7 +35911,7 @@ function registerDoctor(program2) {
|
|
|
35632
35911
|
program2.command("doctor").description(
|
|
35633
35912
|
"Pass/fail host-health check. Exits 0 on a healthy host (including WARN-only); 1 on any FAIL probe. Auto-detects substrate from ~/.olam/config.yaml (host.substrate) \u2014 runs 28 probes on kubernetes, 7 on docker/compose. Override with OLAM_HOST_CP_ENGINE env var."
|
|
35634
35913
|
).option("--json", "emit the report as JSON instead of a human-readable table").action(async (opts) => {
|
|
35635
|
-
const hermesDir =
|
|
35914
|
+
const hermesDir = path53.join(os27.homedir(), ".hermes");
|
|
35636
35915
|
const r = await runDoctor(opts, {
|
|
35637
35916
|
// Pass hermesHomeOverride so the probe fires when ~/.hermes/ exists.
|
|
35638
35917
|
// When the dir is absent the probe is skipped; when present it WARNs
|
|
@@ -35907,7 +36186,7 @@ function registerSubstrate(program2) {
|
|
|
35907
36186
|
|
|
35908
36187
|
// ../cli-plugin-tasks/dist/client.js
|
|
35909
36188
|
import { readFileSync as readFileSync46 } from "node:fs";
|
|
35910
|
-
import { homedir as
|
|
36189
|
+
import { homedir as homedir31 } from "node:os";
|
|
35911
36190
|
import { join as join61 } from "node:path";
|
|
35912
36191
|
var TasksClient = class {
|
|
35913
36192
|
baseUrl;
|
|
@@ -35916,7 +36195,7 @@ var TasksClient = class {
|
|
|
35916
36195
|
sessionId;
|
|
35917
36196
|
constructor(opts) {
|
|
35918
36197
|
this.baseUrl = (opts.hostCpUrl ?? process.env.OLAM_HOST_CP_URL ?? "http://localhost:19000").replace(/\/$/, "");
|
|
35919
|
-
const tokenPath2 = opts.tokenPath ?? join61(
|
|
36198
|
+
const tokenPath2 = opts.tokenPath ?? join61(homedir31(), ".olam", "host-cp.token");
|
|
35920
36199
|
try {
|
|
35921
36200
|
this.token = readFileSync46(tokenPath2, "utf8").trim();
|
|
35922
36201
|
} catch (e) {
|
|
@@ -35925,9 +36204,9 @@ var TasksClient = class {
|
|
|
35925
36204
|
this.olamNodeId = opts.olamNodeId;
|
|
35926
36205
|
this.sessionId = opts.sessionId;
|
|
35927
36206
|
}
|
|
35928
|
-
async call(method,
|
|
36207
|
+
async call(method, path96, scopes, body, query) {
|
|
35929
36208
|
const qs = query ? "?" + new URLSearchParams(Object.entries(query).filter(([, v]) => v !== void 0)).toString() : "";
|
|
35930
|
-
const url2 = `${this.baseUrl}${
|
|
36209
|
+
const url2 = `${this.baseUrl}${path96}${qs}`;
|
|
35931
36210
|
const res = await fetch(url2, {
|
|
35932
36211
|
method,
|
|
35933
36212
|
headers: {
|
|
@@ -35978,8 +36257,8 @@ function parseFrontmatter2(raw) {
|
|
|
35978
36257
|
}
|
|
35979
36258
|
return { frontmatter: fm, body };
|
|
35980
36259
|
}
|
|
35981
|
-
function parseTracker(
|
|
35982
|
-
const raw = readFileSync47(
|
|
36260
|
+
function parseTracker(path96) {
|
|
36261
|
+
const raw = readFileSync47(path96, "utf8");
|
|
35983
36262
|
const { frontmatter, body } = parseFrontmatter2(raw);
|
|
35984
36263
|
const lines = body.split("\n");
|
|
35985
36264
|
const tasks = [];
|
|
@@ -36216,8 +36495,8 @@ function registerTasks(program2) {
|
|
|
36216
36495
|
`);
|
|
36217
36496
|
}
|
|
36218
36497
|
});
|
|
36219
|
-
tasks.command("sync-tracker <path>").description("Parse /10x:commit-plan tracker.md + upsert each task via POST /api/tasks (B2.4; dual-emit pattern, olam-side per cross-ownership decoupling)").option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--dry-run", "Parse + print task records; do not POST").option("--json", "Output raw JSON envelope").action(async (
|
|
36220
|
-
const parsed = parseTracker(
|
|
36498
|
+
tasks.command("sync-tracker <path>").description("Parse /10x:commit-plan tracker.md + upsert each task via POST /api/tasks (B2.4; dual-emit pattern, olam-side per cross-ownership decoupling)").option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--dry-run", "Parse + print task records; do not POST").option("--json", "Output raw JSON envelope").action(async (path96, opts) => {
|
|
36499
|
+
const parsed = parseTracker(path96);
|
|
36221
36500
|
if (opts.dryRun) {
|
|
36222
36501
|
process.stdout.write(JSON.stringify(parsed, null, 2) + "\n");
|
|
36223
36502
|
return;
|
|
@@ -36371,15 +36650,76 @@ function registerCompletion(program2) {
|
|
|
36371
36650
|
// src/commands/setup.ts
|
|
36372
36651
|
init_cli_version();
|
|
36373
36652
|
init_health_probes();
|
|
36374
|
-
import { spawn as spawn7, spawnSync as
|
|
36653
|
+
import { spawn as spawn7, spawnSync as spawnSync27 } from "node:child_process";
|
|
36375
36654
|
import { existsSync as existsSync85, readFileSync as readFileSync70 } from "node:fs";
|
|
36376
|
-
import { homedir as
|
|
36377
|
-
import
|
|
36655
|
+
import { homedir as homedir45 } from "node:os";
|
|
36656
|
+
import path77 from "node:path";
|
|
36378
36657
|
import { createInterface as createInterface3 } from "node:readline";
|
|
36379
36658
|
|
|
36659
|
+
// src/lib/k8s-context-discovery.ts
|
|
36660
|
+
import { spawnSync as spawnSync26 } from "node:child_process";
|
|
36661
|
+
var OLAM_MANAGED_CONTEXT_PREFIX = "k3d-olam-";
|
|
36662
|
+
function isOlamManagedContext(name) {
|
|
36663
|
+
return name.startsWith(OLAM_MANAGED_CONTEXT_PREFIX);
|
|
36664
|
+
}
|
|
36665
|
+
function defaultGetContexts() {
|
|
36666
|
+
const r = spawnSync26(
|
|
36667
|
+
"kubectl",
|
|
36668
|
+
["config", "get-contexts", "-o", "name"],
|
|
36669
|
+
{ encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }
|
|
36670
|
+
);
|
|
36671
|
+
if (r.status !== 0 || !r.stdout) return [];
|
|
36672
|
+
return r.stdout.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
36673
|
+
}
|
|
36674
|
+
function defaultClusterInfo(context) {
|
|
36675
|
+
const r = spawnSync26(
|
|
36676
|
+
"kubectl",
|
|
36677
|
+
["--context", context, "cluster-info", "--request-timeout=3s"],
|
|
36678
|
+
{ encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }
|
|
36679
|
+
);
|
|
36680
|
+
if (r.status === 0) {
|
|
36681
|
+
const match2 = r.stdout.match(/running at (https?:\/\/\S+)/i);
|
|
36682
|
+
return { reachable: true, serverUrl: match2?.[1] };
|
|
36683
|
+
}
|
|
36684
|
+
const err = (r.stderr || "").trim().slice(0, 200);
|
|
36685
|
+
return { reachable: false, error: err || "cluster-info failed" };
|
|
36686
|
+
}
|
|
36687
|
+
function defaultIsIdle(context) {
|
|
36688
|
+
const nsResult = spawnSync26(
|
|
36689
|
+
"kubectl",
|
|
36690
|
+
["--context", context, "get", "namespace", "olam", "--ignore-not-found", "-o", "name"],
|
|
36691
|
+
{ encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }
|
|
36692
|
+
);
|
|
36693
|
+
const nsLine = (nsResult.stdout || "").trim();
|
|
36694
|
+
if (!nsLine) {
|
|
36695
|
+
return true;
|
|
36696
|
+
}
|
|
36697
|
+
const podsResult = spawnSync26(
|
|
36698
|
+
"kubectl",
|
|
36699
|
+
["--context", context, "get", "pods", "-n", "olam", "--no-headers"],
|
|
36700
|
+
{ encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }
|
|
36701
|
+
);
|
|
36702
|
+
const podsOut = (podsResult.stdout || "").trim();
|
|
36703
|
+
return !podsOut || /no resources found/i.test(podsOut);
|
|
36704
|
+
}
|
|
36705
|
+
function discoverOfferableContexts(deps = {}) {
|
|
36706
|
+
const getContextsFn = deps.getContexts ?? defaultGetContexts;
|
|
36707
|
+
const clusterInfoFn = deps.clusterInfo ?? defaultClusterInfo;
|
|
36708
|
+
const isIdleFn = deps.isIdle ?? defaultIsIdle;
|
|
36709
|
+
const allContexts = getContextsFn();
|
|
36710
|
+
const offerable = [];
|
|
36711
|
+
for (const ctx of allContexts) {
|
|
36712
|
+
if (isOlamManagedContext(ctx)) continue;
|
|
36713
|
+
const probe2 = clusterInfoFn(ctx);
|
|
36714
|
+
if (!probe2.reachable) continue;
|
|
36715
|
+
if (isIdleFn(ctx)) offerable.push(ctx);
|
|
36716
|
+
}
|
|
36717
|
+
return { offerable, allContexts };
|
|
36718
|
+
}
|
|
36719
|
+
|
|
36380
36720
|
// src/lib/shell-rc.ts
|
|
36381
36721
|
import { copyFileSync as copyFileSync5, existsSync as existsSync60, readFileSync as readFileSync48, renameSync as renameSync8, writeFileSync as writeFileSync29 } from "node:fs";
|
|
36382
|
-
import
|
|
36722
|
+
import path54 from "node:path";
|
|
36383
36723
|
function appendIdempotent(opts) {
|
|
36384
36724
|
const { rcPath, marker, contentLine, clock = () => /* @__PURE__ */ new Date() } = opts;
|
|
36385
36725
|
if (!existsSync60(rcPath)) {
|
|
@@ -36402,9 +36742,9 @@ function appendIdempotent(opts) {
|
|
|
36402
36742
|
}
|
|
36403
36743
|
function resolveShellRc(home, shellEnv) {
|
|
36404
36744
|
if (!shellEnv) return null;
|
|
36405
|
-
const basename16 =
|
|
36406
|
-
if (basename16 === "zsh") return
|
|
36407
|
-
if (basename16 === "bash") return
|
|
36745
|
+
const basename16 = path54.basename(shellEnv);
|
|
36746
|
+
if (basename16 === "zsh") return path54.join(home, ".zshrc");
|
|
36747
|
+
if (basename16 === "bash") return path54.join(home, ".bashrc");
|
|
36408
36748
|
return null;
|
|
36409
36749
|
}
|
|
36410
36750
|
|
|
@@ -36563,8 +36903,8 @@ async function pickSkillSourcePhase(opts, deps) {
|
|
|
36563
36903
|
}
|
|
36564
36904
|
|
|
36565
36905
|
// src/commands/setup-phase-5b-project-sweep.ts
|
|
36566
|
-
import { homedir as
|
|
36567
|
-
import * as
|
|
36906
|
+
import { homedir as homedir44 } from "node:os";
|
|
36907
|
+
import * as path76 from "node:path";
|
|
36568
36908
|
import * as fs75 from "node:fs";
|
|
36569
36909
|
async function loadWalkFn() {
|
|
36570
36910
|
const m = await Promise.resolve().then(() => (init_project_sweep(), project_sweep_exports));
|
|
@@ -36583,9 +36923,9 @@ async function loadAppendTrustAuditFn() {
|
|
|
36583
36923
|
return m.appendTrustAudit;
|
|
36584
36924
|
}
|
|
36585
36925
|
function deriveRepoName(repoPath, existingNames) {
|
|
36586
|
-
const base =
|
|
36926
|
+
const base = path76.basename(repoPath).toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
36587
36927
|
if (!existingNames.has(base)) return base;
|
|
36588
|
-
const parent =
|
|
36928
|
+
const parent = path76.basename(path76.dirname(repoPath)).toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
36589
36929
|
const composite = `${parent}-${base}`;
|
|
36590
36930
|
if (!existingNames.has(composite)) return composite;
|
|
36591
36931
|
let suffix = 2;
|
|
@@ -36596,8 +36936,8 @@ async function runProjectSweepPhase(opts, deps, sweepDeps = {}) {
|
|
|
36596
36936
|
if (opts.skipProjectSweep) {
|
|
36597
36937
|
return { ok: true, skipped: true, message: "skipped via --skip-project-sweep" };
|
|
36598
36938
|
}
|
|
36599
|
-
const home = deps.home ??
|
|
36600
|
-
const projectsRoot = opts.projects ??
|
|
36939
|
+
const home = deps.home ?? homedir44();
|
|
36940
|
+
const projectsRoot = opts.projects ?? path76.join(home, "Projects");
|
|
36601
36941
|
const existsSyncFn = sweepDeps.existsSync ?? fs75.existsSync;
|
|
36602
36942
|
if (!existsSyncFn(projectsRoot)) {
|
|
36603
36943
|
return {
|
|
@@ -36771,6 +37111,67 @@ function resolveSubstrate(opts, deps) {
|
|
|
36771
37111
|
}
|
|
36772
37112
|
return "kubernetes";
|
|
36773
37113
|
}
|
|
37114
|
+
async function phase0_5DetectExistingContext(substrate, opts, deps) {
|
|
37115
|
+
if (substrate !== "kubernetes") {
|
|
37116
|
+
return { ok: true, skipped: true, message: "no-op for docker substrate" };
|
|
37117
|
+
}
|
|
37118
|
+
if (opts.reuseCluster) {
|
|
37119
|
+
const name = opts.reuseCluster;
|
|
37120
|
+
const clusterInfoFn = deps.kubectlClusterInfo ?? defaultClusterInfo;
|
|
37121
|
+
const probe2 = clusterInfoFn(name);
|
|
37122
|
+
if (!probe2.reachable) {
|
|
37123
|
+
return {
|
|
37124
|
+
ok: false,
|
|
37125
|
+
message: `--reuse-cluster=${name} but context is not reachable: ${probe2.error ?? "unknown error"}`,
|
|
37126
|
+
remedy: `Verify the context exists (\`kubectl config get-contexts\`) and is reachable (\`kubectl --context=${name} cluster-info\`), then re-run \`olam setup --reuse-cluster=${name}\`.`,
|
|
37127
|
+
reuseContext: void 0
|
|
37128
|
+
};
|
|
37129
|
+
}
|
|
37130
|
+
return {
|
|
37131
|
+
ok: true,
|
|
37132
|
+
message: `will reuse context ${name}${probe2.serverUrl ? ` (${probe2.serverUrl})` : ""}`,
|
|
37133
|
+
reuseContext: name
|
|
37134
|
+
};
|
|
37135
|
+
}
|
|
37136
|
+
const { offerable } = discoverOfferableContexts(deps.kubeContextDeps);
|
|
37137
|
+
if (offerable.length === 0) {
|
|
37138
|
+
return {
|
|
37139
|
+
ok: true,
|
|
37140
|
+
skipped: true,
|
|
37141
|
+
message: "no idle reachable contexts detected; will provision k3d cluster"
|
|
37142
|
+
};
|
|
37143
|
+
}
|
|
37144
|
+
if (opts.yes) {
|
|
37145
|
+
process.stdout.write(
|
|
37146
|
+
` Detected ${offerable.length} existing Kubernetes context(s): ${offerable.join(", ")}. To reuse one, pass --reuse-cluster=<name>. Provisioning k3d (--yes default).
|
|
37147
|
+
`
|
|
37148
|
+
);
|
|
37149
|
+
return {
|
|
37150
|
+
ok: true,
|
|
37151
|
+
skipped: true,
|
|
37152
|
+
message: `idle context(s) available but --yes defaults to k3d provision; use --reuse-cluster=<name> to opt in`
|
|
37153
|
+
};
|
|
37154
|
+
}
|
|
37155
|
+
const promptFn = deps.prompt ?? defaultPrompt;
|
|
37156
|
+
for (const ctx of offerable) {
|
|
37157
|
+
const reuse = await promptFn(
|
|
37158
|
+
`Detected existing Kubernetes context \`${ctx}\`. Use this cluster instead of provisioning a new k3d cluster?`,
|
|
37159
|
+
false
|
|
37160
|
+
);
|
|
37161
|
+
if (reuse) {
|
|
37162
|
+
return {
|
|
37163
|
+
ok: true,
|
|
37164
|
+
message: `operator chose to reuse context ${ctx}`,
|
|
37165
|
+
reuseContext: ctx
|
|
37166
|
+
};
|
|
37167
|
+
}
|
|
37168
|
+
}
|
|
37169
|
+
return {
|
|
37170
|
+
ok: true,
|
|
37171
|
+
skipped: true,
|
|
37172
|
+
message: "operator declined reuse; will provision k3d cluster"
|
|
37173
|
+
};
|
|
37174
|
+
}
|
|
36774
37175
|
async function phase1SystemCheck(substrate, deps) {
|
|
36775
37176
|
const nodeVersion = deps.nodeVersion ?? process.version;
|
|
36776
37177
|
const nodeMajor = parseNodeMajor(nodeVersion);
|
|
@@ -36795,6 +37196,13 @@ async function phase1SystemCheck(substrate, deps) {
|
|
|
36795
37196
|
remedy: `Install Node.js ${REQUIRED_NODE_MAJOR}+ LTS via nvm/fnm/asdf and re-run \`olam setup\`.`
|
|
36796
37197
|
};
|
|
36797
37198
|
}
|
|
37199
|
+
const platform2 = String(deps.osPlatform ?? process.platform);
|
|
37200
|
+
const home = deps.home ?? homedir45();
|
|
37201
|
+
const colimaLint = probeColimaKubernetesEnabled({ platform: platform2, home });
|
|
37202
|
+
if (colimaLint.ok && "warn" in colimaLint && colimaLint.warn === true) {
|
|
37203
|
+
const lintWithWarn = colimaLint;
|
|
37204
|
+
printWarning(` \u26A0 ${lintWithWarn.remedy}`);
|
|
37205
|
+
}
|
|
36798
37206
|
return { ok: true, message: `kubectl on PATH; docker ready; node ${nodeVersion}` };
|
|
36799
37207
|
}
|
|
36800
37208
|
const dockerProbe = await probeDockerDaemon(deps.dockerExec);
|
|
@@ -36817,17 +37225,24 @@ async function phase1SystemCheck(substrate, deps) {
|
|
|
36817
37225
|
message: `${dockerProbe.message}; ${composeProbe.message}; node ${nodeVersion}`
|
|
36818
37226
|
};
|
|
36819
37227
|
}
|
|
36820
|
-
async function phase1_5InstallSubstrate(substrate, opts, deps) {
|
|
37228
|
+
async function phase1_5InstallSubstrate(substrate, opts, deps, reuseContext) {
|
|
36821
37229
|
if (substrate === "docker") {
|
|
36822
37230
|
return { ok: true, skipped: true, message: "no-op for docker substrate" };
|
|
36823
37231
|
}
|
|
37232
|
+
if (reuseContext) {
|
|
37233
|
+
return {
|
|
37234
|
+
ok: true,
|
|
37235
|
+
skipped: true,
|
|
37236
|
+
message: `skipped k3d install (reusing context ${reuseContext})`
|
|
37237
|
+
};
|
|
37238
|
+
}
|
|
36824
37239
|
const spawnFn = deps.spawnSubprocess ?? defaultSpawn;
|
|
36825
37240
|
const promptFn = deps.prompt ?? defaultPrompt;
|
|
36826
37241
|
const k3dProbe = await probeK3d(deps.dockerExec);
|
|
36827
37242
|
if (k3dProbe.ok) {
|
|
36828
37243
|
return { ok: true, message: `k3d already present: ${k3dProbe.message}` };
|
|
36829
37244
|
}
|
|
36830
|
-
const hasBrew =
|
|
37245
|
+
const hasBrew = spawnSync27("command", ["-v", "brew"], { shell: true, stdio: "pipe" }).status === 0;
|
|
36831
37246
|
const useBrewMsg = hasBrew ? "Homebrew" : "upstream install script";
|
|
36832
37247
|
if (!opts.yes) {
|
|
36833
37248
|
const confirmed = await promptFn(
|
|
@@ -36886,10 +37301,17 @@ function phaseFromProbe(probe2) {
|
|
|
36886
37301
|
if (probe2.ok) return { ok: true, message: probe2.message };
|
|
36887
37302
|
return { ok: false, message: probe2.message, remedy: probe2.remedy };
|
|
36888
37303
|
}
|
|
36889
|
-
async function phase2_5ProvisionCluster(substrate, clusterName, opts, deps) {
|
|
37304
|
+
async function phase2_5ProvisionCluster(substrate, clusterName, opts, deps, reuseContext) {
|
|
36890
37305
|
if (substrate === "docker") {
|
|
36891
37306
|
return { ok: true, skipped: true, message: "no-op for docker substrate" };
|
|
36892
37307
|
}
|
|
37308
|
+
if (reuseContext) {
|
|
37309
|
+
return {
|
|
37310
|
+
ok: true,
|
|
37311
|
+
skipped: true,
|
|
37312
|
+
message: `skipped k3d cluster provision (reusing context ${reuseContext})`
|
|
37313
|
+
};
|
|
37314
|
+
}
|
|
36893
37315
|
const spawnFn = deps.spawnSubprocess ?? defaultSpawn;
|
|
36894
37316
|
const listResult = await captureSpawn("k3d", ["cluster", "list", "--output", "json"], deps.dockerExec);
|
|
36895
37317
|
if (listResult.ok) {
|
|
@@ -36903,7 +37325,7 @@ async function phase2_5ProvisionCluster(substrate, clusterName, opts, deps) {
|
|
|
36903
37325
|
}
|
|
36904
37326
|
process.stdout.write(`Creating k3d cluster ${clusterName}...
|
|
36905
37327
|
`);
|
|
36906
|
-
const ghConfigBind = `${
|
|
37328
|
+
const ghConfigBind = `${homedir45()}/.config/gh:/host/.config/gh`;
|
|
36907
37329
|
const createResult = await spawnFn("k3d", [
|
|
36908
37330
|
"cluster",
|
|
36909
37331
|
"create",
|
|
@@ -36927,14 +37349,14 @@ async function phase2_5ProvisionCluster(substrate, clusterName, opts, deps) {
|
|
|
36927
37349
|
}
|
|
36928
37350
|
async function captureSpawn(cmd, args, dockerExec) {
|
|
36929
37351
|
const exec = dockerExec ?? ((c, a) => {
|
|
36930
|
-
const r2 =
|
|
37352
|
+
const r2 = spawnSync27(c, [...a], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
36931
37353
|
return { status: r2.status, stdout: r2.stdout ?? "", stderr: r2.stderr ?? "" };
|
|
36932
37354
|
});
|
|
36933
37355
|
const r = exec(cmd, args);
|
|
36934
37356
|
return { ok: r.status === 0, stdout: r.stdout, stderr: r.stderr };
|
|
36935
37357
|
}
|
|
36936
37358
|
function captureSpawnSync(cmd, args) {
|
|
36937
|
-
const r =
|
|
37359
|
+
const r = spawnSync27(cmd, [...args], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
36938
37360
|
return { ok: r.status === 0, stdout: r.stdout ?? "" };
|
|
36939
37361
|
}
|
|
36940
37362
|
function clusterExistsInList(json, clusterName) {
|
|
@@ -36963,11 +37385,11 @@ function safeReadCliVersion() {
|
|
|
36963
37385
|
return null;
|
|
36964
37386
|
}
|
|
36965
37387
|
}
|
|
36966
|
-
async function phase2_6PinKubectlContext(substrate, clusterName, deps) {
|
|
37388
|
+
async function phase2_6PinKubectlContext(substrate, clusterName, deps, reuseContext) {
|
|
36967
37389
|
if (substrate !== "kubernetes") {
|
|
36968
37390
|
return { ok: true, skipped: true, message: "no-op for docker substrate" };
|
|
36969
37391
|
}
|
|
36970
|
-
const expectedContext = `k3d-${clusterName}`;
|
|
37392
|
+
const expectedContext = reuseContext ?? `k3d-${clusterName}`;
|
|
36971
37393
|
writeConfig({ host: { substrate: "kubernetes" } }, { configPath: deps.configPath });
|
|
36972
37394
|
const result = applyKubectlContextPin([expectedContext], {
|
|
36973
37395
|
configPath: deps.configPath
|
|
@@ -37004,7 +37426,7 @@ async function phase4ShellInit(opts, deps) {
|
|
|
37004
37426
|
if (opts.skipShellInit) {
|
|
37005
37427
|
return { ok: true, skipped: true, message: "skipped via --skip-shell-init" };
|
|
37006
37428
|
}
|
|
37007
|
-
const home = deps.home ??
|
|
37429
|
+
const home = deps.home ?? homedir45();
|
|
37008
37430
|
const shellEnv = deps.shellEnv ?? process.env.SHELL;
|
|
37009
37431
|
const rcPath = resolveShellRc(home, shellEnv);
|
|
37010
37432
|
if (rcPath === null) {
|
|
@@ -37014,7 +37436,7 @@ async function phase4ShellInit(opts, deps) {
|
|
|
37014
37436
|
message: `unsupported $SHELL (${shellEnv ?? "unset"}); add \`eval "$(olam completion <shell>)"\` to your shell rc manually`
|
|
37015
37437
|
};
|
|
37016
37438
|
}
|
|
37017
|
-
const shellBasename =
|
|
37439
|
+
const shellBasename = path77.basename(shellEnv);
|
|
37018
37440
|
const evalLine = `eval "$(olam completion ${shellBasename})"`;
|
|
37019
37441
|
const result = appendIdempotent({
|
|
37020
37442
|
rcPath,
|
|
@@ -37040,7 +37462,7 @@ async function phase4ShellInit(opts, deps) {
|
|
|
37040
37462
|
async function phase5InitProject(opts, deps) {
|
|
37041
37463
|
const cwd = deps.cwd ?? process.cwd();
|
|
37042
37464
|
const projectRoot = findProjectRoot(cwd);
|
|
37043
|
-
const configPath =
|
|
37465
|
+
const configPath = path77.join(projectRoot, ".olam", "config.yaml");
|
|
37044
37466
|
if (existsSync85(configPath)) {
|
|
37045
37467
|
return { ok: true, message: `${configPath} present (no change)` };
|
|
37046
37468
|
}
|
|
@@ -37119,7 +37541,8 @@ async function phase7Verify(opts, deps) {
|
|
|
37119
37541
|
remedy: "Inspect doctor output above; the specific failing probe names its remedy."
|
|
37120
37542
|
};
|
|
37121
37543
|
}
|
|
37122
|
-
var
|
|
37544
|
+
var PHASE_TITLES = [
|
|
37545
|
+
"Phase 0.5: Detect existing k8s context",
|
|
37123
37546
|
"Phase 1: System check",
|
|
37124
37547
|
"Phase 1.5: Substrate tools install",
|
|
37125
37548
|
"Phase 2: olam CLI sanity",
|
|
@@ -37157,12 +37580,32 @@ async function runSetup(opts, deps = {}) {
|
|
|
37157
37580
|
process.stdout.write(`cluster: ${clusterName}
|
|
37158
37581
|
`);
|
|
37159
37582
|
}
|
|
37583
|
+
const results = [];
|
|
37584
|
+
let failureAt = null;
|
|
37585
|
+
const phase0_5Title = PHASE_TITLES[0];
|
|
37586
|
+
process.stdout.write(`
|
|
37587
|
+
${phase0_5Title}
|
|
37588
|
+
`);
|
|
37589
|
+
const phase0_5Result = await phase0_5DetectExistingContext(substrate, opts, deps);
|
|
37590
|
+
results.push({ name: phase0_5Title, result: phase0_5Result });
|
|
37591
|
+
if (phase0_5Result.ok && phase0_5Result.skipped) {
|
|
37592
|
+
printWarning(` \u2298 ${phase0_5Result.message}`);
|
|
37593
|
+
} else if (phase0_5Result.ok) {
|
|
37594
|
+
printSuccess(` \u2713 ${phase0_5Result.message}`);
|
|
37595
|
+
} else {
|
|
37596
|
+
printError(` \u2717 ${phase0_5Result.message}`);
|
|
37597
|
+
if (phase0_5Result.remedy) printWarning(` remedy: ${phase0_5Result.remedy}`);
|
|
37598
|
+
process.stdout.write("\n");
|
|
37599
|
+
printError("Setup FAILED at Phase 1");
|
|
37600
|
+
return { phases: results, failureAt: 1, exitCode: 1 };
|
|
37601
|
+
}
|
|
37602
|
+
const reuseContext = phase0_5Result.reuseContext;
|
|
37160
37603
|
const phaseFns = [
|
|
37161
37604
|
() => phase1SystemCheck(substrate, deps),
|
|
37162
|
-
() => phase1_5InstallSubstrate(substrate, opts, deps),
|
|
37605
|
+
() => phase1_5InstallSubstrate(substrate, opts, deps, reuseContext),
|
|
37163
37606
|
() => phase2CliSanity(deps),
|
|
37164
|
-
() => phase2_5ProvisionCluster(substrate, clusterName, opts, deps),
|
|
37165
|
-
() => phase2_6PinKubectlContext(substrate, clusterName, deps),
|
|
37607
|
+
() => phase2_5ProvisionCluster(substrate, clusterName, opts, deps, reuseContext),
|
|
37608
|
+
() => phase2_6PinKubectlContext(substrate, clusterName, deps, reuseContext),
|
|
37166
37609
|
() => phase3Bootstrap(substrate, deps),
|
|
37167
37610
|
() => phase4ShellInit(opts, deps),
|
|
37168
37611
|
() => phase5InitProject(opts, deps),
|
|
@@ -37171,10 +37614,8 @@ async function runSetup(opts, deps = {}) {
|
|
|
37171
37614
|
() => phase6Auth(opts, deps),
|
|
37172
37615
|
() => phase7Verify(opts, deps)
|
|
37173
37616
|
];
|
|
37174
|
-
const results = [];
|
|
37175
|
-
let failureAt = null;
|
|
37176
37617
|
for (let i = 0; i < phaseFns.length; i += 1) {
|
|
37177
|
-
const name =
|
|
37618
|
+
const name = PHASE_TITLES[i + 1];
|
|
37178
37619
|
process.stdout.write(`
|
|
37179
37620
|
${name}
|
|
37180
37621
|
`);
|
|
@@ -37187,7 +37628,7 @@ ${name}
|
|
|
37187
37628
|
} else {
|
|
37188
37629
|
printError(` \u2717 ${result.message}`);
|
|
37189
37630
|
if (result.remedy) printWarning(` remedy: ${result.remedy}`);
|
|
37190
|
-
failureAt = i +
|
|
37631
|
+
failureAt = i + 2;
|
|
37191
37632
|
break;
|
|
37192
37633
|
}
|
|
37193
37634
|
}
|
|
@@ -37214,6 +37655,9 @@ function registerSetup(program2) {
|
|
|
37214
37655
|
).option(
|
|
37215
37656
|
"--cluster-name <name>",
|
|
37216
37657
|
"k3d cluster name to create/use (kubernetes substrate only; default: olam-dev). Use a different name to avoid colliding with a pre-existing olam-dev cluster, to run multiple olam stacks side-by-side, or for per-run unique names in CI smoke. Must be DNS-compatible: lowercase alphanumeric, hyphens allowed in the middle."
|
|
37658
|
+
).option(
|
|
37659
|
+
"--reuse-cluster <name>",
|
|
37660
|
+
"Reuse an existing kubeconfig context instead of provisioning a new k3d cluster. Pair with --substrate=kubernetes. Skips Phase 1.5 (k3d install) and Phase 2.5 (cluster provision); Phase 2.6 pins to this context. Operator owns the cluster lifecycle (teardown not handled by olam setup). Example: --reuse-cluster=colima (for Colima k8s users)."
|
|
37217
37661
|
).option("--skip-shell-init", "Skip Phase 4 (do not append to ~/.zshrc / ~/.bashrc)").option("--skip-auth", "Skip Phase 6 (do not prompt for `olam auth login`)").option("--skip-skill-source", "Skip Phase 5a (do not pick a skill source; run `olam skills source add` later)").option("--skill-source <id-or-url>", "Non-interactive Phase 5a: curated name (e.g. atlas-toolbox) or git URL").option("--skip-project-sweep", "Skip Phase 5b (do not walk projects directory for repo discovery)").option("--projects <path>", "Phase 5b: project root path to walk (default: ~/Projects)").option("--dry-run", "Phase 5b: print matches without registering or building (no side effects)").option("--exclude <glob...>", "Phase 5b: additional skip patterns for project sweep").option("--skip-kg", "Phase 5b: skip KG eager-build sub-step (sources still registered)").option(
|
|
37218
37662
|
"--skip-doctor",
|
|
37219
37663
|
"Skip Phase 7 final `olam doctor` verification (for CI or minimal setups)"
|
|
@@ -37412,13 +37856,13 @@ function registerSetupLinuxGate(program2) {
|
|
|
37412
37856
|
// src/commands/update.ts
|
|
37413
37857
|
import * as fs78 from "node:fs";
|
|
37414
37858
|
import * as os42 from "node:os";
|
|
37415
|
-
import * as
|
|
37859
|
+
import * as path80 from "node:path";
|
|
37416
37860
|
import { execSync as execSync14 } from "node:child_process";
|
|
37417
37861
|
import pc28 from "picocolors";
|
|
37418
37862
|
|
|
37419
37863
|
// src/lib/symlink-reconcile.ts
|
|
37420
37864
|
import * as fs76 from "node:fs";
|
|
37421
|
-
import * as
|
|
37865
|
+
import * as path78 from "node:path";
|
|
37422
37866
|
var realFs = {
|
|
37423
37867
|
readdirSync: (p) => fs76.readdirSync(p),
|
|
37424
37868
|
existsSync: (p) => fs76.existsSync(p),
|
|
@@ -37437,8 +37881,8 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir2, _fs = realFs) {
|
|
|
37437
37881
|
_fs.mkdirSync(claudeSkillsDir2, { recursive: true });
|
|
37438
37882
|
const sourceSkills = _fs.existsSync(npmSkillsDir) ? _fs.readdirSync(npmSkillsDir).filter((d) => d.startsWith("olam-")) : [];
|
|
37439
37883
|
for (const skill of sourceSkills) {
|
|
37440
|
-
const linkPath =
|
|
37441
|
-
const target =
|
|
37884
|
+
const linkPath = path78.join(claudeSkillsDir2, skill);
|
|
37885
|
+
const target = path78.join(npmSkillsDir, skill);
|
|
37442
37886
|
if (!_fs.existsSync(linkPath)) {
|
|
37443
37887
|
try {
|
|
37444
37888
|
_fs.symlinkSync(target, linkPath);
|
|
@@ -37451,7 +37895,7 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir2, _fs = realFs) {
|
|
|
37451
37895
|
}
|
|
37452
37896
|
const deployedEntries = _fs.existsSync(claudeSkillsDir2) ? _fs.readdirSync(claudeSkillsDir2).filter((d) => d.startsWith("olam-")) : [];
|
|
37453
37897
|
for (const entry of deployedEntries) {
|
|
37454
|
-
const linkPath =
|
|
37898
|
+
const linkPath = path78.join(claudeSkillsDir2, entry);
|
|
37455
37899
|
let isSymlink = false;
|
|
37456
37900
|
try {
|
|
37457
37901
|
isSymlink = _fs.lstatSync(linkPath).isSymbolicLink();
|
|
@@ -37476,9 +37920,9 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir2, _fs = realFs) {
|
|
|
37476
37920
|
|
|
37477
37921
|
// src/commands/update.ts
|
|
37478
37922
|
var PACKAGE_NAME = "@pleri/olam-cli";
|
|
37479
|
-
var CACHE_DIR2 =
|
|
37480
|
-
var LOG_DIR2 =
|
|
37481
|
-
var LAST_STABLE_FILE =
|
|
37923
|
+
var CACHE_DIR2 = path80.join(os42.homedir(), ".olam", "cache");
|
|
37924
|
+
var LOG_DIR2 = path80.join(os42.homedir(), ".olam", "log");
|
|
37925
|
+
var LAST_STABLE_FILE = path80.join(CACHE_DIR2, "last-stable.txt");
|
|
37482
37926
|
function defaultExec(cmd) {
|
|
37483
37927
|
try {
|
|
37484
37928
|
const stdout = execSync14(cmd, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
@@ -37507,12 +37951,12 @@ function readLastStable(file = LAST_STABLE_FILE) {
|
|
|
37507
37951
|
}
|
|
37508
37952
|
}
|
|
37509
37953
|
function writeLastStable(version, file = LAST_STABLE_FILE) {
|
|
37510
|
-
fs78.mkdirSync(
|
|
37954
|
+
fs78.mkdirSync(path80.dirname(file), { recursive: true });
|
|
37511
37955
|
fs78.writeFileSync(file, version, { mode: 420 });
|
|
37512
37956
|
}
|
|
37513
37957
|
function logUpdateFailure(stderr) {
|
|
37514
37958
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
37515
|
-
const logFile =
|
|
37959
|
+
const logFile = path80.join(LOG_DIR2, `update-${ts}.log`);
|
|
37516
37960
|
try {
|
|
37517
37961
|
fs78.mkdirSync(LOG_DIR2, { recursive: true });
|
|
37518
37962
|
fs78.appendFileSync(logFile, `[update-failure ${(/* @__PURE__ */ new Date()).toISOString()}]
|
|
@@ -37602,8 +38046,8 @@ async function doUpdate(opts, _exec = defaultExec, _reconcile = reconcileSkillSy
|
|
|
37602
38046
|
let symlinkResult = { added: [], removed: [] };
|
|
37603
38047
|
if (npmRootResult.exitCode === 0) {
|
|
37604
38048
|
const npmRoot = npmRootResult.stdout.trim();
|
|
37605
|
-
const npmSkillsDir =
|
|
37606
|
-
const claudeSkillsDir2 =
|
|
38049
|
+
const npmSkillsDir = path80.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills");
|
|
38050
|
+
const claudeSkillsDir2 = path80.join(os42.homedir(), ".claude", "skills");
|
|
37607
38051
|
const rec = _reconcile(npmSkillsDir, claudeSkillsDir2);
|
|
37608
38052
|
symlinkResult = { added: rec.added, removed: rec.removed };
|
|
37609
38053
|
if (!quiet && (rec.added.length > 0 || rec.removed.length > 0)) {
|
|
@@ -37649,8 +38093,8 @@ async function doRollback(_exec = defaultExec, _reconcile = reconcileSkillSymlin
|
|
|
37649
38093
|
if (npmRootResult.exitCode === 0) {
|
|
37650
38094
|
const npmRoot = npmRootResult.stdout.trim();
|
|
37651
38095
|
_reconcile(
|
|
37652
|
-
|
|
37653
|
-
|
|
38096
|
+
path80.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills"),
|
|
38097
|
+
path80.join(os42.homedir(), ".claude", "skills")
|
|
37654
38098
|
);
|
|
37655
38099
|
}
|
|
37656
38100
|
return { action: "rolled-back", restoredVersion: prev, exitCode: 0 };
|
|
@@ -38007,7 +38451,7 @@ import pc32 from "picocolors";
|
|
|
38007
38451
|
|
|
38008
38452
|
// src/commands/flywheel/install-shims.ts
|
|
38009
38453
|
import { copyFileSync as copyFileSync9, existsSync as existsSync89, mkdirSync as mkdirSync53, readFileSync as readFileSync74, writeFileSync as writeFileSync44 } from "node:fs";
|
|
38010
|
-
import { homedir as
|
|
38454
|
+
import { homedir as homedir48 } from "node:os";
|
|
38011
38455
|
import { dirname as dirname48, join as join87 } from "node:path";
|
|
38012
38456
|
|
|
38013
38457
|
// src/lib/shim-generator.ts
|
|
@@ -38071,7 +38515,7 @@ ${argsBlock}
|
|
|
38071
38515
|
// src/commands/flywheel/install-shims.ts
|
|
38072
38516
|
var SHIM_HEADER_MARKER = "# AUTO-GENERATED by `olam flywheel install-shims`";
|
|
38073
38517
|
function refreshShims(opts = {}) {
|
|
38074
|
-
const targetDir = opts.targetDir ?? join87(
|
|
38518
|
+
const targetDir = opts.targetDir ?? join87(homedir48(), ".claude", "scripts");
|
|
38075
38519
|
const results = [];
|
|
38076
38520
|
let written = 0;
|
|
38077
38521
|
let overwritten = 0;
|
|
@@ -38132,7 +38576,7 @@ function installOne(spec, targetDir, opts) {
|
|
|
38132
38576
|
}
|
|
38133
38577
|
function registerFlywheelInstallShims(parent) {
|
|
38134
38578
|
parent.command("install-shims").description("Install backwards-compat bash shims under ~/.claude/scripts/ that delegate to olam flywheel <subcmd>").option("--force", "overwrite existing non-shim files (backs them up to .shim-backup-<ts>)").option("--dry-run", "preview which shims would be written without modifying disk").option("--target-dir <path>", "override target directory (default: ~/.claude/scripts/); for tests").action((opts) => {
|
|
38135
|
-
const targetDir = opts.targetDir ?? join87(
|
|
38579
|
+
const targetDir = opts.targetDir ?? join87(homedir48(), ".claude", "scripts");
|
|
38136
38580
|
const summary2 = refreshShims(opts);
|
|
38137
38581
|
const lines = [];
|
|
38138
38582
|
const dryRunSuffix = opts.dryRun === true ? " (dry-run)" : "";
|
|
@@ -38757,7 +39201,7 @@ init_skill_sources();
|
|
|
38757
39201
|
init_output();
|
|
38758
39202
|
import * as fs80 from "node:fs";
|
|
38759
39203
|
import * as os43 from "node:os";
|
|
38760
|
-
import * as
|
|
39204
|
+
import * as path81 from "node:path";
|
|
38761
39205
|
import * as readline3 from "node:readline";
|
|
38762
39206
|
import pc33 from "picocolors";
|
|
38763
39207
|
|
|
@@ -38776,7 +39220,7 @@ import {
|
|
|
38776
39220
|
statSync as statSync27,
|
|
38777
39221
|
writeFileSync as writeFileSync45
|
|
38778
39222
|
} from "node:fs";
|
|
38779
|
-
import { homedir as
|
|
39223
|
+
import { homedir as homedir49 } from "node:os";
|
|
38780
39224
|
import { basename as basename8, dirname as dirname49, isAbsolute as isAbsolute4, join as join88, relative as relative5, resolve as resolve21 } from "node:path";
|
|
38781
39225
|
|
|
38782
39226
|
// src/commands/flywheel/sanitize-persona-output.ts
|
|
@@ -38839,7 +39283,7 @@ function registerFlywheelSanitizePersonaOutput(parent) {
|
|
|
38839
39283
|
|
|
38840
39284
|
// src/lib/skills-apply-overlays.ts
|
|
38841
39285
|
function claudeRoot(opts) {
|
|
38842
|
-
return opts.claudeDir ?? opts.fixtureRoot ?? join88(
|
|
39286
|
+
return opts.claudeDir ?? opts.fixtureRoot ?? join88(homedir49(), ".claude");
|
|
38843
39287
|
}
|
|
38844
39288
|
function ensureRealDir(p) {
|
|
38845
39289
|
if (!existsSync90(p)) {
|
|
@@ -39036,12 +39480,12 @@ function asMessage4(err) {
|
|
|
39036
39480
|
}
|
|
39037
39481
|
var ATLAS_USER_PICKER_RE = /^[a-z0-9][a-z0-9_-]{0,38}$/;
|
|
39038
39482
|
function listMemberNames(clonePath) {
|
|
39039
|
-
const membersDir =
|
|
39483
|
+
const membersDir = path81.join(clonePath, "members");
|
|
39040
39484
|
if (!fs80.existsSync(membersDir)) return [];
|
|
39041
39485
|
try {
|
|
39042
39486
|
return fs80.readdirSync(membersDir).filter((e) => {
|
|
39043
39487
|
try {
|
|
39044
|
-
return fs80.statSync(
|
|
39488
|
+
return fs80.statSync(path81.join(membersDir, e)).isDirectory();
|
|
39045
39489
|
} catch {
|
|
39046
39490
|
return false;
|
|
39047
39491
|
}
|
|
@@ -39090,8 +39534,8 @@ function defaultAtlasUserPrompt(question) {
|
|
|
39090
39534
|
async function resolveAtlasUserWithPicker(cliOverride, opts) {
|
|
39091
39535
|
if (cliOverride !== void 0) return cliOverride;
|
|
39092
39536
|
const ATLAS_USER_RE2 = /^[a-z0-9][a-z0-9_-]{0,38}$/;
|
|
39093
|
-
const claudeDirPathForRead = opts?._testClaudeDir ?? (process.env["OLAM_CLAUDE_DIR"] ??
|
|
39094
|
-
const atlasUserFile =
|
|
39537
|
+
const claudeDirPathForRead = opts?._testClaudeDir ?? (process.env["OLAM_CLAUDE_DIR"] ?? path81.join(os43.homedir(), ".claude"));
|
|
39538
|
+
const atlasUserFile = path81.join(claudeDirPathForRead, ".atlas-user");
|
|
39095
39539
|
if (fs80.existsSync(atlasUserFile)) {
|
|
39096
39540
|
const existing = fs80.readFileSync(atlasUserFile, "utf-8").trim();
|
|
39097
39541
|
if (existing.length > 0) {
|
|
@@ -39152,10 +39596,10 @@ async function resolveAtlasUserWithPicker(cliOverride, opts) {
|
|
|
39152
39596
|
);
|
|
39153
39597
|
return void 0;
|
|
39154
39598
|
}
|
|
39155
|
-
const claudeDirPath = opts?._testClaudeDir ?? (process.env["OLAM_CLAUDE_DIR"] ??
|
|
39599
|
+
const claudeDirPath = opts?._testClaudeDir ?? (process.env["OLAM_CLAUDE_DIR"] ?? path81.join(os43.homedir(), ".claude"));
|
|
39156
39600
|
fs80.mkdirSync(claudeDirPath, { recursive: true });
|
|
39157
|
-
fs80.writeFileSync(
|
|
39158
|
-
process.stdout.write(pc33.green(`\u2713 atlas-user set to "${picked}" (written to ${
|
|
39601
|
+
fs80.writeFileSync(path81.join(claudeDirPath, ".atlas-user"), picked + "\n", "utf8");
|
|
39602
|
+
process.stdout.write(pc33.green(`\u2713 atlas-user set to "${picked}" (written to ${path81.join(claudeDirPath, ".atlas-user")})
|
|
39159
39603
|
`));
|
|
39160
39604
|
return picked;
|
|
39161
39605
|
}
|
|
@@ -39167,10 +39611,10 @@ function listDeployed() {
|
|
|
39167
39611
|
);
|
|
39168
39612
|
const entries = [];
|
|
39169
39613
|
for (const bucket of ["skills", "agents", "scripts", "rules", "commands"]) {
|
|
39170
|
-
const bucketDir =
|
|
39614
|
+
const bucketDir = path81.join(dir, bucket);
|
|
39171
39615
|
if (!fs80.existsSync(bucketDir)) continue;
|
|
39172
39616
|
for (const name of fs80.readdirSync(bucketDir)) {
|
|
39173
|
-
const full =
|
|
39617
|
+
const full = path81.join(bucketDir, name);
|
|
39174
39618
|
try {
|
|
39175
39619
|
const stat = fs80.lstatSync(full);
|
|
39176
39620
|
if (!stat.isSymbolicLink()) continue;
|
|
@@ -39621,7 +40065,7 @@ init_merge_settings();
|
|
|
39621
40065
|
init_skill_sources();
|
|
39622
40066
|
init_output();
|
|
39623
40067
|
import * as fs82 from "node:fs";
|
|
39624
|
-
import * as
|
|
40068
|
+
import * as path82 from "node:path";
|
|
39625
40069
|
var MIGRATE_FROM_TOOLBOX_COMMAND = "migrate-from-toolbox";
|
|
39626
40070
|
function asMessage6(err) {
|
|
39627
40071
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -39689,7 +40133,7 @@ function registerSkillsMigrate(program2) {
|
|
|
39689
40133
|
return;
|
|
39690
40134
|
}
|
|
39691
40135
|
const toolboxPath = opts.path;
|
|
39692
|
-
const namespace = opts.namespace ??
|
|
40136
|
+
const namespace = opts.namespace ?? path82.basename(toolboxPath);
|
|
39693
40137
|
const sourceName = opts.sourceName ?? namespace;
|
|
39694
40138
|
const snapshot = detectToolboxState({ toolboxPath, namespace });
|
|
39695
40139
|
if (!snapshot) {
|
|
@@ -39743,9 +40187,9 @@ function registerSkillsMigrate(program2) {
|
|
|
39743
40187
|
printWarning(`legacy hook removal failed: ${asMessage6(err)}; proceeding`);
|
|
39744
40188
|
}
|
|
39745
40189
|
const scope = opts.scope === "user" ? "user" : "project";
|
|
39746
|
-
const olamHookPath = scope === "user" ? settingsFile :
|
|
40190
|
+
const olamHookPath = scope === "user" ? settingsFile : path82.join(process.cwd(), ".claude", "settings.json");
|
|
39747
40191
|
try {
|
|
39748
|
-
fs82.mkdirSync(
|
|
40192
|
+
fs82.mkdirSync(path82.dirname(olamHookPath), { recursive: true });
|
|
39749
40193
|
const result = mergeHomeSettingsJson(olamHookPath, {
|
|
39750
40194
|
ensureHook: {
|
|
39751
40195
|
stage: OLAM_SKILLS_HOOK_STAGE,
|
|
@@ -39779,7 +40223,7 @@ function registerSkillsMigrate(program2) {
|
|
|
39779
40223
|
init_skill_sources();
|
|
39780
40224
|
init_output();
|
|
39781
40225
|
import * as fs83 from "node:fs";
|
|
39782
|
-
import * as
|
|
40226
|
+
import * as path83 from "node:path";
|
|
39783
40227
|
var MIGRATE_BACK_TO_TOOLBOX_COMMAND = "migrate-back-to-toolbox";
|
|
39784
40228
|
function asMessage7(err) {
|
|
39785
40229
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -39787,7 +40231,7 @@ function asMessage7(err) {
|
|
|
39787
40231
|
function claudeDirInternal4() {
|
|
39788
40232
|
const override = process.env["OLAM_CLAUDE_DIR"];
|
|
39789
40233
|
if (override && override.length > 0) return override;
|
|
39790
|
-
return
|
|
40234
|
+
return path83.join(process.env["HOME"] ?? "", ".claude");
|
|
39791
40235
|
}
|
|
39792
40236
|
function restoreSessionStartFromSnapshot(filePath, originalSessionStartHook) {
|
|
39793
40237
|
if (!originalSessionStartHook || originalSessionStartHook.length === 0) {
|
|
@@ -39812,7 +40256,7 @@ function restoreSessionStartFromSnapshot(filePath, originalSessionStartHook) {
|
|
|
39812
40256
|
SessionStart: originalSessionStartHook
|
|
39813
40257
|
}
|
|
39814
40258
|
};
|
|
39815
|
-
fs83.mkdirSync(
|
|
40259
|
+
fs83.mkdirSync(path83.dirname(filePath), { recursive: true });
|
|
39816
40260
|
fs83.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
39817
40261
|
return { restored: true };
|
|
39818
40262
|
}
|
|
@@ -39822,10 +40266,10 @@ function removeOlamManagedSymlinks() {
|
|
|
39822
40266
|
const olamClonePaths = sources.map((s) => skillSourceClonePath(s.id));
|
|
39823
40267
|
let removed = 0;
|
|
39824
40268
|
for (const bucket of ["skills", "agents", "scripts", "rules", "commands"]) {
|
|
39825
|
-
const dir =
|
|
40269
|
+
const dir = path83.join(claude, bucket);
|
|
39826
40270
|
if (!fs83.existsSync(dir)) continue;
|
|
39827
40271
|
for (const name of fs83.readdirSync(dir)) {
|
|
39828
|
-
const linkPath =
|
|
40272
|
+
const linkPath = path83.join(dir, name);
|
|
39829
40273
|
try {
|
|
39830
40274
|
const stat = fs83.lstatSync(linkPath);
|
|
39831
40275
|
if (!stat.isSymbolicLink()) continue;
|
|
@@ -39844,7 +40288,7 @@ function restoreToolboxSymlinks(symlinks) {
|
|
|
39844
40288
|
let restored = 0;
|
|
39845
40289
|
for (const { link, target } of symlinks) {
|
|
39846
40290
|
try {
|
|
39847
|
-
fs83.mkdirSync(
|
|
40291
|
+
fs83.mkdirSync(path83.dirname(link), { recursive: true });
|
|
39848
40292
|
if (fs83.existsSync(link) || (() => {
|
|
39849
40293
|
try {
|
|
39850
40294
|
fs83.lstatSync(link);
|
|
@@ -39864,8 +40308,8 @@ function restoreToolboxSymlinks(symlinks) {
|
|
|
39864
40308
|
}
|
|
39865
40309
|
function restoreAtlasUserMarker(atlasUser) {
|
|
39866
40310
|
if (!atlasUser) return false;
|
|
39867
|
-
const file =
|
|
39868
|
-
fs83.mkdirSync(
|
|
40311
|
+
const file = path83.join(claudeDirInternal4(), ".atlas-user");
|
|
40312
|
+
fs83.mkdirSync(path83.dirname(file), { recursive: true });
|
|
39869
40313
|
fs83.writeFileSync(file, atlasUser);
|
|
39870
40314
|
return true;
|
|
39871
40315
|
}
|
|
@@ -39879,7 +40323,7 @@ function registerSkillsMigrateBack(program2) {
|
|
|
39879
40323
|
let snapshot;
|
|
39880
40324
|
try {
|
|
39881
40325
|
if (opts.snapshot) {
|
|
39882
|
-
snapshotPath =
|
|
40326
|
+
snapshotPath = path83.resolve(opts.snapshot);
|
|
39883
40327
|
if (!fs83.existsSync(snapshotPath)) {
|
|
39884
40328
|
printError(`snapshot not found at ${snapshotPath}`);
|
|
39885
40329
|
process.exitCode = 1;
|
|
@@ -39887,7 +40331,7 @@ function registerSkillsMigrateBack(program2) {
|
|
|
39887
40331
|
}
|
|
39888
40332
|
snapshot = readMigrationSnapshotFromPath(snapshotPath);
|
|
39889
40333
|
} else {
|
|
39890
|
-
const filterNamespace = opts.namespace ?? (opts.path ?
|
|
40334
|
+
const filterNamespace = opts.namespace ?? (opts.path ? path83.basename(opts.path) : void 0);
|
|
39891
40335
|
const latest = readLatestMigrationSnapshot({ namespace: filterNamespace });
|
|
39892
40336
|
if (!latest) {
|
|
39893
40337
|
const where = filterNamespace ? ` for namespace "${filterNamespace}"` : "";
|
|
@@ -39965,7 +40409,7 @@ init_trust_audit_log();
|
|
|
39965
40409
|
init_atlas_hook_strip();
|
|
39966
40410
|
init_output();
|
|
39967
40411
|
import * as fs84 from "node:fs";
|
|
39968
|
-
import * as
|
|
40412
|
+
import * as path84 from "node:path";
|
|
39969
40413
|
import pc35 from "picocolors";
|
|
39970
40414
|
var MIGRATE_HOOKS_COMMAND = "migrate-hooks";
|
|
39971
40415
|
function settingsHasOlamMetaSentinel(settings) {
|
|
@@ -39992,7 +40436,7 @@ function readSettings2(filePath) {
|
|
|
39992
40436
|
return JSON.parse(raw);
|
|
39993
40437
|
}
|
|
39994
40438
|
function writeSettings(filePath, settings) {
|
|
39995
|
-
fs84.mkdirSync(
|
|
40439
|
+
fs84.mkdirSync(path84.dirname(filePath), { recursive: true });
|
|
39996
40440
|
const tmp = `${filePath}.tmp-migrate-hooks-${process.pid}-${Date.now()}`;
|
|
39997
40441
|
fs84.writeFileSync(tmp, JSON.stringify(settings, null, 2) + "\n");
|
|
39998
40442
|
fs84.renameSync(tmp, filePath);
|
|
@@ -40075,7 +40519,7 @@ function registerSkillsMigrateHooks(program2) {
|
|
|
40075
40519
|
init_meta_hooks_migration_snapshot();
|
|
40076
40520
|
init_skill_sources();
|
|
40077
40521
|
init_output();
|
|
40078
|
-
import * as
|
|
40522
|
+
import * as path85 from "node:path";
|
|
40079
40523
|
function asMessage9(err) {
|
|
40080
40524
|
return err instanceof Error ? err.message : String(err);
|
|
40081
40525
|
}
|
|
@@ -40092,16 +40536,16 @@ function registerSkillsMigrateHooksBack(program2) {
|
|
|
40092
40536
|
return;
|
|
40093
40537
|
}
|
|
40094
40538
|
if (opts.snapshot) {
|
|
40095
|
-
const resolved =
|
|
40096
|
-
const allowedDir =
|
|
40097
|
-
if (!resolved.startsWith(allowedDir +
|
|
40539
|
+
const resolved = path85.resolve(opts.snapshot);
|
|
40540
|
+
const allowedDir = path85.resolve(migrationSnapshotsDir2());
|
|
40541
|
+
if (!resolved.startsWith(allowedDir + path85.sep)) {
|
|
40098
40542
|
printError(
|
|
40099
40543
|
`--snapshot path must be inside ${allowedDir} (got "${resolved}"). Refusing to restore from an arbitrary path \u2014 settings.json would land operator-chosen content.`
|
|
40100
40544
|
);
|
|
40101
40545
|
process.exitCode = 1;
|
|
40102
40546
|
return;
|
|
40103
40547
|
}
|
|
40104
|
-
const basename16 =
|
|
40548
|
+
const basename16 = path85.basename(resolved);
|
|
40105
40549
|
if (!basename16.startsWith(META_HOOKS_SNAPSHOT_PREFIX)) {
|
|
40106
40550
|
printError(
|
|
40107
40551
|
`--snapshot filename must start with "${META_HOOKS_SNAPSHOT_PREFIX}" (got "${basename16}"). Cross-namespace snapshots (atlas-toolbox-*) are not valid restore targets for olam-meta hooks.`
|
|
@@ -40335,9 +40779,9 @@ function registerSkillsDoctor(program2) {
|
|
|
40335
40779
|
init_skill_sources();
|
|
40336
40780
|
init_cli_version();
|
|
40337
40781
|
init_output();
|
|
40338
|
-
import { execFileSync as
|
|
40782
|
+
import { execFileSync as execFileSync16 } from "node:child_process";
|
|
40339
40783
|
import * as fs86 from "node:fs";
|
|
40340
|
-
import * as
|
|
40784
|
+
import * as path86 from "node:path";
|
|
40341
40785
|
var CHAIN_SKILL_NAMES = [
|
|
40342
40786
|
"10x:brainstorm",
|
|
40343
40787
|
"10x:plan-hard",
|
|
@@ -40353,17 +40797,17 @@ function asMessage12(err) {
|
|
|
40353
40797
|
}
|
|
40354
40798
|
function hasBeadsCli() {
|
|
40355
40799
|
try {
|
|
40356
|
-
|
|
40800
|
+
execFileSync16("bd", ["--version"], { stdio: "ignore" });
|
|
40357
40801
|
return true;
|
|
40358
40802
|
} catch {
|
|
40359
40803
|
return false;
|
|
40360
40804
|
}
|
|
40361
40805
|
}
|
|
40362
40806
|
function hasBeadsProjectInit(cwd) {
|
|
40363
|
-
return fs86.existsSync(
|
|
40807
|
+
return fs86.existsSync(path86.join(cwd, ".beads"));
|
|
40364
40808
|
}
|
|
40365
40809
|
function hasBeadsClaudeSetup() {
|
|
40366
|
-
const settingsPath =
|
|
40810
|
+
const settingsPath = path86.join(claudeDir(), "settings.json");
|
|
40367
40811
|
if (!fs86.existsSync(settingsPath)) return false;
|
|
40368
40812
|
try {
|
|
40369
40813
|
const content = fs86.readFileSync(settingsPath, "utf8");
|
|
@@ -40382,7 +40826,7 @@ async function bootstrapBeads(cwd) {
|
|
|
40382
40826
|
if (!hasBeadsProjectInit(cwd)) {
|
|
40383
40827
|
console.log("bd init \u2014 initializing beads in current project");
|
|
40384
40828
|
try {
|
|
40385
|
-
|
|
40829
|
+
execFileSync16("bd", ["init", "--quiet", "--stealth"], {
|
|
40386
40830
|
cwd,
|
|
40387
40831
|
stdio: "inherit"
|
|
40388
40832
|
});
|
|
@@ -40395,7 +40839,7 @@ async function bootstrapBeads(cwd) {
|
|
|
40395
40839
|
if (!hasBeadsClaudeSetup()) {
|
|
40396
40840
|
console.log("bd setup claude \u2014 installing beads Claude Code hooks");
|
|
40397
40841
|
try {
|
|
40398
|
-
|
|
40842
|
+
execFileSync16("bd", ["setup", "claude"], { cwd, stdio: "inherit" });
|
|
40399
40843
|
} catch (err) {
|
|
40400
40844
|
printWarning(`bd setup claude failed (continuing): ${asMessage12(err)}`);
|
|
40401
40845
|
}
|
|
@@ -40431,12 +40875,12 @@ function shortSha(sha) {
|
|
|
40431
40875
|
return sha.slice(0, 8);
|
|
40432
40876
|
}
|
|
40433
40877
|
function listInstalledClaudeSkills() {
|
|
40434
|
-
const skillsDir =
|
|
40878
|
+
const skillsDir = path86.join(claudeDir(), "skills");
|
|
40435
40879
|
if (!fs86.existsSync(skillsDir)) return [];
|
|
40436
40880
|
try {
|
|
40437
40881
|
return fs86.readdirSync(skillsDir).filter((name) => {
|
|
40438
40882
|
try {
|
|
40439
|
-
const stat = fs86.lstatSync(
|
|
40883
|
+
const stat = fs86.lstatSync(path86.join(skillsDir, name));
|
|
40440
40884
|
return stat.isSymbolicLink() || stat.isDirectory();
|
|
40441
40885
|
} catch {
|
|
40442
40886
|
return false;
|
|
@@ -40511,14 +40955,14 @@ function registerSkills10x(program2) {
|
|
|
40511
40955
|
tenx.command("uninstall").description(
|
|
40512
40956
|
"Remove /10x: chain skill symlinks from ~/.claude/skills (preserves user-authored skills + non-chain skill sources)"
|
|
40513
40957
|
).action(() => {
|
|
40514
|
-
const skillsDir =
|
|
40958
|
+
const skillsDir = path86.join(claudeDir(), "skills");
|
|
40515
40959
|
if (!fs86.existsSync(skillsDir)) {
|
|
40516
40960
|
printWarning("No ~/.claude/skills/ directory found; nothing to uninstall");
|
|
40517
40961
|
return;
|
|
40518
40962
|
}
|
|
40519
40963
|
let removed = 0;
|
|
40520
40964
|
for (const name of fs86.readdirSync(skillsDir)) {
|
|
40521
|
-
const full =
|
|
40965
|
+
const full = path86.join(skillsDir, name);
|
|
40522
40966
|
try {
|
|
40523
40967
|
const stat = fs86.lstatSync(full);
|
|
40524
40968
|
if (!stat.isSymbolicLink()) continue;
|
|
@@ -40594,17 +41038,17 @@ function registerSkills10x(program2) {
|
|
|
40594
41038
|
init_output();
|
|
40595
41039
|
import * as fs87 from "node:fs";
|
|
40596
41040
|
import * as os44 from "node:os";
|
|
40597
|
-
import * as
|
|
41041
|
+
import * as path87 from "node:path";
|
|
40598
41042
|
import * as child_process from "node:child_process";
|
|
40599
41043
|
import { parse as yamlParse2, stringify as yamlStringify3 } from "yaml";
|
|
40600
41044
|
function hermesConfigPath() {
|
|
40601
|
-
return
|
|
41045
|
+
return path87.join(os44.homedir(), ".hermes", "config.yaml");
|
|
40602
41046
|
}
|
|
40603
41047
|
function hermesSkillsDir() {
|
|
40604
|
-
return
|
|
41048
|
+
return path87.join(os44.homedir(), ".hermes", "skills");
|
|
40605
41049
|
}
|
|
40606
41050
|
function claudeSkillsDir() {
|
|
40607
|
-
return
|
|
41051
|
+
return path87.join(os44.homedir(), ".claude", "skills");
|
|
40608
41052
|
}
|
|
40609
41053
|
function readHermesConfig(configPath) {
|
|
40610
41054
|
const raw = fs87.readFileSync(configPath, "utf-8");
|
|
@@ -40716,8 +41160,8 @@ function mirrorSkillSymlinks(dryRun, summary2) {
|
|
|
40716
41160
|
let mirrored = 0;
|
|
40717
41161
|
let collisions = 0;
|
|
40718
41162
|
for (const entry of entries) {
|
|
40719
|
-
const srcPath =
|
|
40720
|
-
const destPath2 =
|
|
41163
|
+
const srcPath = path87.join(srcDir, entry);
|
|
41164
|
+
const destPath2 = path87.join(destDir, entry);
|
|
40721
41165
|
if (fs87.existsSync(destPath2) || fs87.lstatSync(srcPath).isFile()) {
|
|
40722
41166
|
if (fs87.existsSync(destPath2)) collisions++;
|
|
40723
41167
|
continue;
|
|
@@ -40772,7 +41216,7 @@ async function runHermesBootstrap(opts, deps = {}) {
|
|
|
40772
41216
|
} else {
|
|
40773
41217
|
summary2.skipped.push("mcp_servers.agentmemory-atlas (AGENTMEMORY_BRIDGE_URL/SECRET not set; use --bridge-url/--bridge-secret to add)");
|
|
40774
41218
|
}
|
|
40775
|
-
const hooksDir =
|
|
41219
|
+
const hooksDir = path87.join(path87.dirname(configPath), "hooks");
|
|
40776
41220
|
const hookResult = installHookFn(hooksDir, dryRun);
|
|
40777
41221
|
switch (hookResult.status) {
|
|
40778
41222
|
case "installed":
|
|
@@ -40819,7 +41263,7 @@ async function runHermesBootstrap(opts, deps = {}) {
|
|
|
40819
41263
|
}
|
|
40820
41264
|
var HOOK_MATCHERS = ["terminal", "bash", "shell", "search_files", "grep", "ripgrep"];
|
|
40821
41265
|
function ensureHermesHookEntry(config, hooksDir, dryRun, summary2) {
|
|
40822
|
-
const hookScriptPath =
|
|
41266
|
+
const hookScriptPath = path87.join(hooksDir, "kg-first.sh");
|
|
40823
41267
|
const hooks = config["hooks"] ?? {};
|
|
40824
41268
|
const preToolCall = Array.isArray(hooks["pre_tool_call"]) ? hooks["pre_tool_call"] : [];
|
|
40825
41269
|
const alreadyPresent = preToolCall.some(
|
|
@@ -40957,9 +41401,9 @@ function registerMcpServe(cmd) {
|
|
|
40957
41401
|
init_output();
|
|
40958
41402
|
|
|
40959
41403
|
// src/commands/mcp/install-shared.ts
|
|
40960
|
-
import { spawnSync as
|
|
41404
|
+
import { spawnSync as spawnSync29 } from "node:child_process";
|
|
40961
41405
|
var DEFAULT_CLAUDE_SHELL_DEPS = {
|
|
40962
|
-
spawn:
|
|
41406
|
+
spawn: spawnSync29,
|
|
40963
41407
|
log: (msg) => console.log(msg)
|
|
40964
41408
|
};
|
|
40965
41409
|
function isOnPath(deps, bin) {
|
|
@@ -41092,8 +41536,8 @@ var SECRET = process.env["OLAM_MCP_AUTH_SECRET"] ?? "";
|
|
|
41092
41536
|
function authHeaders() {
|
|
41093
41537
|
return SECRET ? { "X-Olam-Mcp-Secret": SECRET } : {};
|
|
41094
41538
|
}
|
|
41095
|
-
async function apiFetch(
|
|
41096
|
-
const res = await fetch(`${BASE_URL}${
|
|
41539
|
+
async function apiFetch(path96, init = {}) {
|
|
41540
|
+
const res = await fetch(`${BASE_URL}${path96}`, {
|
|
41097
41541
|
...init,
|
|
41098
41542
|
headers: {
|
|
41099
41543
|
"Content-Type": "application/json",
|
|
@@ -41355,7 +41799,7 @@ import pc40 from "picocolors";
|
|
|
41355
41799
|
// src/commands/mcp/import-discovery.ts
|
|
41356
41800
|
import * as fs88 from "node:fs";
|
|
41357
41801
|
import * as os45 from "node:os";
|
|
41358
|
-
import * as
|
|
41802
|
+
import * as path88 from "node:path";
|
|
41359
41803
|
function readJsonFile(filePath) {
|
|
41360
41804
|
try {
|
|
41361
41805
|
const raw = fs88.readFileSync(filePath, "utf-8");
|
|
@@ -41387,18 +41831,18 @@ function extractMcpServers(obj, source, sourceLabel) {
|
|
|
41387
41831
|
}
|
|
41388
41832
|
function getClaudeDesktopPath() {
|
|
41389
41833
|
if (process.platform === "darwin") {
|
|
41390
|
-
return
|
|
41834
|
+
return path88.join(os45.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
41391
41835
|
}
|
|
41392
41836
|
if (process.platform === "win32") {
|
|
41393
|
-
const appData = process.env["APPDATA"] ??
|
|
41394
|
-
return
|
|
41837
|
+
const appData = process.env["APPDATA"] ?? path88.join(os45.homedir(), "AppData", "Roaming");
|
|
41838
|
+
return path88.join(appData, "Claude", "claude_desktop_config.json");
|
|
41395
41839
|
}
|
|
41396
|
-
return
|
|
41840
|
+
return path88.join(os45.homedir(), ".config", "Claude", "claude_desktop_config.json");
|
|
41397
41841
|
}
|
|
41398
41842
|
function getOlamRepoPaths() {
|
|
41399
41843
|
const configPaths = [
|
|
41400
|
-
|
|
41401
|
-
|
|
41844
|
+
path88.join(os45.homedir(), ".olam", "config.yaml"),
|
|
41845
|
+
path88.join(process.cwd(), ".olam", "config.yaml")
|
|
41402
41846
|
];
|
|
41403
41847
|
const paths = [];
|
|
41404
41848
|
for (const configPath of configPaths) {
|
|
@@ -41420,7 +41864,7 @@ async function discoverMcpSources(repoPaths) {
|
|
|
41420
41864
|
const sources = [];
|
|
41421
41865
|
const sourceDefs = [
|
|
41422
41866
|
{
|
|
41423
|
-
path:
|
|
41867
|
+
path: path88.join(os45.homedir(), ".claude.json"),
|
|
41424
41868
|
label: "Claude Code (~/.claude.json)"
|
|
41425
41869
|
},
|
|
41426
41870
|
{
|
|
@@ -41428,19 +41872,19 @@ async function discoverMcpSources(repoPaths) {
|
|
|
41428
41872
|
label: "Claude Desktop"
|
|
41429
41873
|
},
|
|
41430
41874
|
{
|
|
41431
|
-
path:
|
|
41875
|
+
path: path88.join(os45.homedir(), ".cursor", "mcp.json"),
|
|
41432
41876
|
label: "Cursor (~/.cursor/mcp.json)"
|
|
41433
41877
|
},
|
|
41434
41878
|
{
|
|
41435
|
-
path:
|
|
41879
|
+
path: path88.join(os45.homedir(), ".codeium", "windsurf", "mcp_config.json"),
|
|
41436
41880
|
label: "Windsurf (~/.codeium/windsurf/mcp_config.json)"
|
|
41437
41881
|
}
|
|
41438
41882
|
];
|
|
41439
41883
|
const resolvedRepoPaths = repoPaths ?? getOlamRepoPaths();
|
|
41440
41884
|
for (const repoPath of resolvedRepoPaths) {
|
|
41441
41885
|
sourceDefs.push({
|
|
41442
|
-
path:
|
|
41443
|
-
label: `.mcp.json (${
|
|
41886
|
+
path: path88.join(repoPath, ".mcp.json"),
|
|
41887
|
+
label: `.mcp.json (${path88.basename(repoPath)})`
|
|
41444
41888
|
});
|
|
41445
41889
|
}
|
|
41446
41890
|
const reads = await Promise.all(
|
|
@@ -41677,13 +42121,13 @@ init_output();
|
|
|
41677
42121
|
|
|
41678
42122
|
// src/lib/memory-host-process-migration.ts
|
|
41679
42123
|
import { existsSync as existsSync101, readFileSync as readFileSync83, unlinkSync as unlinkSync23 } from "node:fs";
|
|
41680
|
-
import { spawnSync as
|
|
42124
|
+
import { spawnSync as spawnSync30 } from "node:child_process";
|
|
41681
42125
|
|
|
41682
42126
|
// src/commands/memory/_paths.ts
|
|
41683
|
-
import { homedir as
|
|
42127
|
+
import { homedir as homedir53 } from "node:os";
|
|
41684
42128
|
import { join as join95, dirname as dirname55 } from "node:path";
|
|
41685
42129
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
41686
|
-
var OLAM_HOME5 = join95(
|
|
42130
|
+
var OLAM_HOME5 = join95(homedir53(), ".olam");
|
|
41687
42131
|
var MEMORY_PID_PATH = join95(OLAM_HOME5, "memory.pid");
|
|
41688
42132
|
var MEMORY_LOG_PATH = join95(OLAM_HOME5, "memory-service.log");
|
|
41689
42133
|
var MEMORY_DATA_DIR = join95(OLAM_HOME5, "memory-data");
|
|
@@ -41762,7 +42206,7 @@ function isProcessAlive(pid) {
|
|
|
41762
42206
|
}
|
|
41763
42207
|
}
|
|
41764
42208
|
function processCommName(pid) {
|
|
41765
|
-
const r =
|
|
42209
|
+
const r = spawnSync30("ps", ["-p", String(pid), "-o", "comm="], { encoding: "utf-8" });
|
|
41766
42210
|
if (r.status !== 0) return null;
|
|
41767
42211
|
const comm = r.stdout.trim();
|
|
41768
42212
|
return comm.split("/").pop() ?? null;
|
|
@@ -41776,7 +42220,7 @@ function terminateProcess(pid) {
|
|
|
41776
42220
|
const deadline = Date.now() + KILL_TIMEOUT_MS;
|
|
41777
42221
|
while (Date.now() < deadline) {
|
|
41778
42222
|
if (!isProcessAlive(pid)) return true;
|
|
41779
|
-
|
|
42223
|
+
spawnSync30("sleep", ["0.1"]);
|
|
41780
42224
|
}
|
|
41781
42225
|
try {
|
|
41782
42226
|
process.kill(pid, "SIGKILL");
|
|
@@ -42333,13 +42777,13 @@ function resolveMemoryServiceDir() {
|
|
|
42333
42777
|
);
|
|
42334
42778
|
}
|
|
42335
42779
|
function resolveLocalBridgeScript(serviceDir) {
|
|
42336
|
-
const
|
|
42337
|
-
if (!existsSync105(
|
|
42780
|
+
const path96 = join97(serviceDir, "scripts", "local-bridge-server.mjs");
|
|
42781
|
+
if (!existsSync105(path96)) {
|
|
42338
42782
|
throw new Error(
|
|
42339
|
-
`Could not find local-bridge-server.mjs at ${
|
|
42783
|
+
`Could not find local-bridge-server.mjs at ${path96}. Verify packages/memory-service ships the scripts/ directory.`
|
|
42340
42784
|
);
|
|
42341
42785
|
}
|
|
42342
|
-
return
|
|
42786
|
+
return path96;
|
|
42343
42787
|
}
|
|
42344
42788
|
function validateBridgeOpts(opts) {
|
|
42345
42789
|
const local = opts.local ?? false;
|
|
@@ -42681,7 +43125,7 @@ function registerMemoryStats(cmd) {
|
|
|
42681
43125
|
|
|
42682
43126
|
// src/commands/memory/install-hooks.ts
|
|
42683
43127
|
import { copyFileSync as copyFileSync12, existsSync as existsSync106, mkdirSync as mkdirSync60, readFileSync as readFileSync85, writeFileSync as writeFileSync52 } from "node:fs";
|
|
42684
|
-
import { homedir as
|
|
43128
|
+
import { homedir as homedir54 } from "node:os";
|
|
42685
43129
|
import { dirname as dirname56, join as join98, resolve as resolve25 } from "node:path";
|
|
42686
43130
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
42687
43131
|
var HOOK_BASENAMES = [
|
|
@@ -42750,7 +43194,7 @@ If existing entries already point at the same paths, no edit needed.
|
|
|
42750
43194
|
}
|
|
42751
43195
|
function registerMemoryInstallHooks(parent) {
|
|
42752
43196
|
parent.command("install-hooks").description("Install agentmemory hooks (PreToolUse + PostToolUse + SessionStart) to ~/.claude/scripts/hooks/").option("--force", "overwrite existing non-canonical files (backs them up to .agentmemory-hook-backup-<ts>)").option("--dry-run", "preview which hooks would be written without modifying disk").option("--target-dir <path>", "override target directory (default: ~/.claude/scripts/hooks/); for tests").option("--source-dir <path>", "override source directory (default: packages/memory-service/hooks/); for tests").action((opts) => {
|
|
42753
|
-
const targetDir = opts.targetDir ?? join98(
|
|
43197
|
+
const targetDir = opts.targetDir ?? join98(homedir54(), ".claude", "scripts", "hooks");
|
|
42754
43198
|
const sourceDir = opts.sourceDir ?? defaultSourceDir();
|
|
42755
43199
|
let written = 0;
|
|
42756
43200
|
let unchanged = 0;
|
|
@@ -42830,7 +43274,7 @@ init_storage_paths();
|
|
|
42830
43274
|
init_workspace_name();
|
|
42831
43275
|
import * as fs93 from "node:fs";
|
|
42832
43276
|
import * as os48 from "node:os";
|
|
42833
|
-
import * as
|
|
43277
|
+
import * as path93 from "node:path";
|
|
42834
43278
|
|
|
42835
43279
|
// ../core/dist/kg/kg-service-client.js
|
|
42836
43280
|
var KG_SERVICE_PORT_DEFAULT = 9997;
|
|
@@ -42841,8 +43285,8 @@ function port() {
|
|
|
42841
43285
|
const n = Number.parseInt(env, 10);
|
|
42842
43286
|
return Number.isFinite(n) && n > 0 ? n : KG_SERVICE_PORT_DEFAULT;
|
|
42843
43287
|
}
|
|
42844
|
-
function url(
|
|
42845
|
-
return `http://127.0.0.1:${port()}${
|
|
43288
|
+
function url(path96) {
|
|
43289
|
+
return `http://127.0.0.1:${port()}${path96}`;
|
|
42846
43290
|
}
|
|
42847
43291
|
function kgServiceHealthUrl() {
|
|
42848
43292
|
return url("/health");
|
|
@@ -42923,16 +43367,16 @@ init_workspace_name();
|
|
|
42923
43367
|
init_kg_caps();
|
|
42924
43368
|
init_output();
|
|
42925
43369
|
import fs89 from "node:fs";
|
|
42926
|
-
import { homedir as
|
|
42927
|
-
import
|
|
43370
|
+
import { homedir as homedir55 } from "node:os";
|
|
43371
|
+
import path89 from "node:path";
|
|
42928
43372
|
function olamHome4() {
|
|
42929
|
-
return process.env.OLAM_HOME ??
|
|
43373
|
+
return process.env.OLAM_HOME ?? path89.join(homedir55(), ".olam");
|
|
42930
43374
|
}
|
|
42931
43375
|
function kgRoot2() {
|
|
42932
|
-
return
|
|
43376
|
+
return path89.join(olamHome4(), "kg");
|
|
42933
43377
|
}
|
|
42934
43378
|
function worldsRoot2() {
|
|
42935
|
-
return
|
|
43379
|
+
return path89.join(olamHome4(), "worlds");
|
|
42936
43380
|
}
|
|
42937
43381
|
function dirSizeBytes2(dir) {
|
|
42938
43382
|
if (!fs89.existsSync(dir)) return 0;
|
|
@@ -42947,7 +43391,7 @@ function dirSizeBytes2(dir) {
|
|
|
42947
43391
|
continue;
|
|
42948
43392
|
}
|
|
42949
43393
|
for (const entry of entries) {
|
|
42950
|
-
const full =
|
|
43394
|
+
const full = path89.join(cur, entry.name);
|
|
42951
43395
|
if (entry.isSymbolicLink()) continue;
|
|
42952
43396
|
if (entry.isDirectory()) {
|
|
42953
43397
|
stack.push(full);
|
|
@@ -42968,7 +43412,7 @@ function formatBytes5(n) {
|
|
|
42968
43412
|
return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
|
|
42969
43413
|
}
|
|
42970
43414
|
function readFreshness(workspace) {
|
|
42971
|
-
const file =
|
|
43415
|
+
const file = path89.join(kgPristinePath(workspace), "freshness.json");
|
|
42972
43416
|
if (!fs89.existsSync(file)) return null;
|
|
42973
43417
|
try {
|
|
42974
43418
|
const raw = JSON.parse(fs89.readFileSync(file, "utf-8"));
|
|
@@ -42979,7 +43423,7 @@ function readFreshness(workspace) {
|
|
|
42979
43423
|
}
|
|
42980
43424
|
}
|
|
42981
43425
|
function readOverlayNodeCount(graphifyOutDir) {
|
|
42982
|
-
const graphPath =
|
|
43426
|
+
const graphPath = path89.join(graphifyOutDir, "graph.json");
|
|
42983
43427
|
if (!fs89.existsSync(graphPath)) return null;
|
|
42984
43428
|
try {
|
|
42985
43429
|
const raw = JSON.parse(fs89.readFileSync(graphPath, "utf-8"));
|
|
@@ -43005,7 +43449,7 @@ function listOverlays() {
|
|
|
43005
43449
|
for (const worldEntry of worldDirs) {
|
|
43006
43450
|
if (!worldEntry.isDirectory()) continue;
|
|
43007
43451
|
const worldId = worldEntry.name;
|
|
43008
|
-
const worldDir =
|
|
43452
|
+
const worldDir = path89.join(root, worldId);
|
|
43009
43453
|
let cloneDirs;
|
|
43010
43454
|
try {
|
|
43011
43455
|
cloneDirs = fs89.readdirSync(worldDir, { withFileTypes: true });
|
|
@@ -43014,7 +43458,7 @@ function listOverlays() {
|
|
|
43014
43458
|
}
|
|
43015
43459
|
for (const cloneEntry of cloneDirs) {
|
|
43016
43460
|
if (!cloneEntry.isDirectory()) continue;
|
|
43017
|
-
const graphifyOut =
|
|
43461
|
+
const graphifyOut = path89.join(worldDir, cloneEntry.name, "graphify-out");
|
|
43018
43462
|
if (!fs89.existsSync(graphifyOut)) continue;
|
|
43019
43463
|
records.push({
|
|
43020
43464
|
world_id: worldId,
|
|
@@ -43046,7 +43490,7 @@ function listPristines(overlays) {
|
|
|
43046
43490
|
continue;
|
|
43047
43491
|
}
|
|
43048
43492
|
const fresh = readFreshness(workspace);
|
|
43049
|
-
const graphifyOut =
|
|
43493
|
+
const graphifyOut = path89.join(kgPristinePath(workspace), "graphify-out");
|
|
43050
43494
|
const size = dirSizeBytes2(graphifyOut);
|
|
43051
43495
|
const worldCount = overlays.filter((o) => o.clone_dir === workspace).length;
|
|
43052
43496
|
records.push({
|
|
@@ -43183,9 +43627,9 @@ init_workspace_name();
|
|
|
43183
43627
|
init_output();
|
|
43184
43628
|
import { spawn as spawn12 } from "node:child_process";
|
|
43185
43629
|
import fs90 from "node:fs";
|
|
43186
|
-
import
|
|
43630
|
+
import path90 from "node:path";
|
|
43187
43631
|
function pidFilePath2(workspace) {
|
|
43188
|
-
return
|
|
43632
|
+
return path90.join(kgPristinePath(workspace), ".watch.pid");
|
|
43189
43633
|
}
|
|
43190
43634
|
function isPidAlive3(pid) {
|
|
43191
43635
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
@@ -43219,7 +43663,7 @@ function readAndClassifyPid(workspace) {
|
|
|
43219
43663
|
}
|
|
43220
43664
|
function writePidFile2(workspace, pid) {
|
|
43221
43665
|
const file = pidFilePath2(workspace);
|
|
43222
|
-
const dir =
|
|
43666
|
+
const dir = path90.dirname(file);
|
|
43223
43667
|
fs90.mkdirSync(dir, { recursive: true });
|
|
43224
43668
|
fs90.writeFileSync(file, String(pid), { encoding: "utf-8" });
|
|
43225
43669
|
}
|
|
@@ -43232,7 +43676,7 @@ function removePidFile(workspace) {
|
|
|
43232
43676
|
}
|
|
43233
43677
|
async function runKgWatch(workspaceArg, opts, deps = {}) {
|
|
43234
43678
|
const cwd = deps.cwd ?? opts.cwd ?? process.cwd();
|
|
43235
|
-
const name = workspaceArg ??
|
|
43679
|
+
const name = workspaceArg ?? path90.basename(cwd).toLowerCase();
|
|
43236
43680
|
try {
|
|
43237
43681
|
validateWorkspaceName(name);
|
|
43238
43682
|
} catch (err) {
|
|
@@ -43240,7 +43684,7 @@ async function runKgWatch(workspaceArg, opts, deps = {}) {
|
|
|
43240
43684
|
return { exitCode: 1, pidWritten: false };
|
|
43241
43685
|
}
|
|
43242
43686
|
const pristinePath = kgPristinePath(name);
|
|
43243
|
-
const graphPath =
|
|
43687
|
+
const graphPath = path90.join(pristinePath, "graphify-out", "graph.json");
|
|
43244
43688
|
const pidState = readAndClassifyPid(name);
|
|
43245
43689
|
if (pidState.status === "active") {
|
|
43246
43690
|
printError(
|
|
@@ -43479,7 +43923,7 @@ function registerKgDoctorCommand(kg) {
|
|
|
43479
43923
|
// src/commands/kg-install-hook.ts
|
|
43480
43924
|
init_merge_settings();
|
|
43481
43925
|
import * as fs91 from "node:fs";
|
|
43482
|
-
import * as
|
|
43926
|
+
import * as path91 from "node:path";
|
|
43483
43927
|
import * as os46 from "node:os";
|
|
43484
43928
|
import { parse as yamlParse3, stringify as yamlStringify4 } from "yaml";
|
|
43485
43929
|
|
|
@@ -43532,9 +43976,9 @@ function buildHookMatcherEntry(opts) {
|
|
|
43532
43976
|
init_output();
|
|
43533
43977
|
function settingsPathFor2(scope) {
|
|
43534
43978
|
if (scope === "user") {
|
|
43535
|
-
return
|
|
43979
|
+
return path91.join(os46.homedir(), ".claude", "settings.json");
|
|
43536
43980
|
}
|
|
43537
|
-
return
|
|
43981
|
+
return path91.join(process.cwd(), ".claude", "settings.json");
|
|
43538
43982
|
}
|
|
43539
43983
|
function backup2(filePath) {
|
|
43540
43984
|
if (!fs91.existsSync(filePath)) return null;
|
|
@@ -43545,10 +43989,10 @@ function backup2(filePath) {
|
|
|
43545
43989
|
}
|
|
43546
43990
|
var HERMES_HOOK_MATCHERS = ["terminal", "bash", "shell", "search_files", "grep", "ripgrep"];
|
|
43547
43991
|
function hermesConfigPath2() {
|
|
43548
|
-
return
|
|
43992
|
+
return path91.join(os46.homedir(), ".hermes", "config.yaml");
|
|
43549
43993
|
}
|
|
43550
43994
|
function hermesHooksDir() {
|
|
43551
|
-
return
|
|
43995
|
+
return path91.join(os46.homedir(), ".hermes", "hooks");
|
|
43552
43996
|
}
|
|
43553
43997
|
function patchHermesConfigForHook(action) {
|
|
43554
43998
|
const configPath = hermesConfigPath2();
|
|
@@ -43561,7 +44005,7 @@ function patchHermesConfigForHook(action) {
|
|
|
43561
44005
|
(e) => typeof e["command"] === "string" && e["command"].includes(HERMES_KG_HOOK_SENTINEL)
|
|
43562
44006
|
);
|
|
43563
44007
|
if (alreadyPresent) return "already-present";
|
|
43564
|
-
const hookScriptPath =
|
|
44008
|
+
const hookScriptPath = path91.join(hermesHooksDir(), "kg-first.sh");
|
|
43565
44009
|
const entry = {
|
|
43566
44010
|
matcher: HERMES_HOOK_MATCHERS.join("|"),
|
|
43567
44011
|
command: `${hookScriptPath} # ${HERMES_KG_HOOK_SENTINEL}`
|
|
@@ -43615,7 +44059,7 @@ function doInstallForHermes() {
|
|
|
43615
44059
|
function doUninstallForHermes() {
|
|
43616
44060
|
const configPath = hermesConfigPath2();
|
|
43617
44061
|
const hooksDir = hermesHooksDir();
|
|
43618
|
-
const hookScriptPath =
|
|
44062
|
+
const hookScriptPath = path91.join(hooksDir, "kg-first.sh");
|
|
43619
44063
|
let scriptRemoved = false;
|
|
43620
44064
|
if (fs91.existsSync(hookScriptPath)) {
|
|
43621
44065
|
const content = fs91.readFileSync(hookScriptPath, "utf-8");
|
|
@@ -43650,9 +44094,9 @@ function registerKgInstallHookCommand(kg) {
|
|
|
43650
44094
|
const scope = opts.scope === "user" ? "user" : "project";
|
|
43651
44095
|
const filePath = settingsPathFor2(scope);
|
|
43652
44096
|
try {
|
|
43653
|
-
fs91.mkdirSync(
|
|
44097
|
+
fs91.mkdirSync(path91.dirname(filePath), { recursive: true });
|
|
43654
44098
|
} catch (err) {
|
|
43655
|
-
printError(`could not create ${
|
|
44099
|
+
printError(`could not create ${path91.dirname(filePath)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
43656
44100
|
process.exitCode = 1;
|
|
43657
44101
|
return;
|
|
43658
44102
|
}
|
|
@@ -43695,14 +44139,14 @@ function registerKgInstallHookCommand(kg) {
|
|
|
43695
44139
|
|
|
43696
44140
|
// src/commands/kg-uninstall-hook.ts
|
|
43697
44141
|
import * as fs92 from "node:fs";
|
|
43698
|
-
import * as
|
|
44142
|
+
import * as path92 from "node:path";
|
|
43699
44143
|
import * as os47 from "node:os";
|
|
43700
44144
|
init_output();
|
|
43701
44145
|
function settingsPathFor3(scope) {
|
|
43702
44146
|
if (scope === "user") {
|
|
43703
|
-
return
|
|
44147
|
+
return path92.join(os47.homedir(), ".claude", "settings.json");
|
|
43704
44148
|
}
|
|
43705
|
-
return
|
|
44149
|
+
return path92.join(process.cwd(), ".claude", "settings.json");
|
|
43706
44150
|
}
|
|
43707
44151
|
function dropSentinel(matchers) {
|
|
43708
44152
|
let changed = false;
|
|
@@ -43864,14 +44308,14 @@ function readQueueFromDisk(queuePath) {
|
|
|
43864
44308
|
return entries;
|
|
43865
44309
|
}
|
|
43866
44310
|
function writeQueueToDisk(queuePath, entries) {
|
|
43867
|
-
fs93.mkdirSync(
|
|
44311
|
+
fs93.mkdirSync(path93.dirname(queuePath), { recursive: true });
|
|
43868
44312
|
const content = entries.map((e) => JSON.stringify(e)).join("\n") + (entries.length > 0 ? "\n" : "");
|
|
43869
44313
|
fs93.writeFileSync(queuePath, content, "utf-8");
|
|
43870
44314
|
}
|
|
43871
44315
|
async function runKgBuildPending(opts = {}) {
|
|
43872
44316
|
const queuePath = opts.queuePath ?? (() => {
|
|
43873
|
-
const stateDir = process.env["OLAM_STATE_DIR"] ??
|
|
43874
|
-
return
|
|
44317
|
+
const stateDir = process.env["OLAM_STATE_DIR"] ?? path93.join(os48.homedir(), ".olam", "state");
|
|
44318
|
+
return path93.join(stateDir, "kg-pending.jsonl");
|
|
43875
44319
|
})();
|
|
43876
44320
|
const readQueue2 = opts.readQueueFn ?? readQueueFromDisk;
|
|
43877
44321
|
const writeQueue2 = opts.writeQueueFn ?? writeQueueToDisk;
|
|
@@ -43887,7 +44331,7 @@ async function runKgBuildPending(opts = {}) {
|
|
|
43887
44331
|
const remaining = [];
|
|
43888
44332
|
for (const entry of deduped) {
|
|
43889
44333
|
const repoPath = entry.path;
|
|
43890
|
-
const workspaceName =
|
|
44334
|
+
const workspaceName = path93.basename(repoPath).toLowerCase();
|
|
43891
44335
|
printInfo("kg build --pending", `building ${repoPath} (workspace=${workspaceName})`);
|
|
43892
44336
|
let containerPath;
|
|
43893
44337
|
try {
|
|
@@ -43925,20 +44369,20 @@ async function runKgBuildPending(opts = {}) {
|
|
|
43925
44369
|
}
|
|
43926
44370
|
function resolveWorkspace(arg) {
|
|
43927
44371
|
const cwd = process.cwd();
|
|
43928
|
-
const name = arg ??
|
|
44372
|
+
const name = arg ?? path93.basename(cwd).toLowerCase();
|
|
43929
44373
|
validateWorkspaceName(name);
|
|
43930
44374
|
return { name, sourcePath: cwd };
|
|
43931
44375
|
}
|
|
43932
44376
|
function toContainerPath(hostPath) {
|
|
43933
44377
|
const home = os48.homedir();
|
|
43934
|
-
const resolved =
|
|
43935
|
-
if (!resolved.startsWith(home +
|
|
44378
|
+
const resolved = path93.resolve(hostPath);
|
|
44379
|
+
if (!resolved.startsWith(home + path93.sep) && resolved !== home) {
|
|
43936
44380
|
throw new Error(
|
|
43937
44381
|
`source path "${resolved}" is not under $HOME (${home}). kg-service can only build repos that live under your home dir (it bind-mounts $HOME:/host-home:ro at start). Move the repo or set OLAM_HOME if you need a different root.`
|
|
43938
44382
|
);
|
|
43939
44383
|
}
|
|
43940
|
-
const rel =
|
|
43941
|
-
return rel === "" ? "/host-home" :
|
|
44384
|
+
const rel = path93.relative(home, resolved);
|
|
44385
|
+
return rel === "" ? "/host-home" : path93.posix.join("/host-home", rel.split(path93.sep).join("/"));
|
|
43942
44386
|
}
|
|
43943
44387
|
async function runKgBuild(workspaceArg, options = {}) {
|
|
43944
44388
|
let workspace;
|
|
@@ -43990,11 +44434,11 @@ async function runKgBuild(workspaceArg, options = {}) {
|
|
|
43990
44434
|
graphify_path: "container"
|
|
43991
44435
|
};
|
|
43992
44436
|
fs93.writeFileSync(
|
|
43993
|
-
|
|
44437
|
+
path93.join(outDir, "freshness.json"),
|
|
43994
44438
|
JSON.stringify(freshness, null, 2) + "\n",
|
|
43995
44439
|
"utf-8"
|
|
43996
44440
|
);
|
|
43997
|
-
const finalOut =
|
|
44441
|
+
const finalOut = path93.join(outDir, "graphify-out");
|
|
43998
44442
|
if (options.json) {
|
|
43999
44443
|
process.stdout.write(JSON.stringify(freshness) + "\n");
|
|
44000
44444
|
} else {
|
|
@@ -44036,12 +44480,12 @@ function registerKg(program2) {
|
|
|
44036
44480
|
// src/commands/flywheel/emit-breadcrumb.ts
|
|
44037
44481
|
init_file_lock();
|
|
44038
44482
|
import { mkdirSync as mkdirSync63, appendFileSync as appendFileSync6 } from "node:fs";
|
|
44039
|
-
import { homedir as
|
|
44483
|
+
import { homedir as homedir59 } from "node:os";
|
|
44040
44484
|
import { dirname as dirname59, join as join102 } from "node:path";
|
|
44041
44485
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
44042
44486
|
var VALID_SEVERITIES = /* @__PURE__ */ new Set(["critical", "high", "medium", "low", "info", "warn"]);
|
|
44043
44487
|
var PROMPT_FEEDING_FIELDS = ["extracted_pattern", "severity", "affected_persona", "proposed_edit"];
|
|
44044
|
-
var BREADCRUMBS_BASE = join102(
|
|
44488
|
+
var BREADCRUMBS_BASE = join102(homedir59(), ".local", "share", "claude", "breadcrumbs");
|
|
44045
44489
|
var LOCK_FILENAME = ".flywheel-emit.lock";
|
|
44046
44490
|
function buildRecord(opts) {
|
|
44047
44491
|
const rec = {
|
|
@@ -44107,14 +44551,14 @@ async function emitBreadcrumb(opts) {
|
|
|
44107
44551
|
);
|
|
44108
44552
|
process.exit(2);
|
|
44109
44553
|
}
|
|
44110
|
-
const
|
|
44111
|
-
const lockDir = dirname59(
|
|
44554
|
+
const path96 = destPath(rec.project_slug);
|
|
44555
|
+
const lockDir = dirname59(path96);
|
|
44112
44556
|
mkdirSync63(lockDir, { recursive: true });
|
|
44113
44557
|
const line = JSON.stringify(rec) + "\n";
|
|
44114
44558
|
await withFileLock(
|
|
44115
44559
|
lockDir,
|
|
44116
44560
|
() => {
|
|
44117
|
-
appendFileSync6(
|
|
44561
|
+
appendFileSync6(path96, line, "utf8");
|
|
44118
44562
|
},
|
|
44119
44563
|
{
|
|
44120
44564
|
lockFilename: LOCK_FILENAME,
|
|
@@ -44124,7 +44568,7 @@ async function emitBreadcrumb(opts) {
|
|
|
44124
44568
|
acquireTimeoutMs: 5e3
|
|
44125
44569
|
}
|
|
44126
44570
|
);
|
|
44127
|
-
process.stdout.write(`[K7-emit] ${
|
|
44571
|
+
process.stdout.write(`[K7-emit] ${path96}: ${rec.extracted_pattern} (${rec.severity})
|
|
44128
44572
|
`);
|
|
44129
44573
|
}
|
|
44130
44574
|
function registerFlywheelEmitBreadcrumb(parent) {
|
|
@@ -44247,38 +44691,38 @@ function validateK5ScoredAt(scoredAt) {
|
|
|
44247
44691
|
}
|
|
44248
44692
|
return null;
|
|
44249
44693
|
}
|
|
44250
|
-
function validatePlan(
|
|
44694
|
+
function validatePlan(path96) {
|
|
44251
44695
|
let stat;
|
|
44252
44696
|
try {
|
|
44253
|
-
stat = statSync30(
|
|
44697
|
+
stat = statSync30(path96);
|
|
44254
44698
|
} catch (err) {
|
|
44255
|
-
return { ok: false, message: `FAIL cannot stat ${
|
|
44699
|
+
return { ok: false, message: `FAIL cannot stat ${path96}: ${err instanceof Error ? err.message : "unknown"}` };
|
|
44256
44700
|
}
|
|
44257
44701
|
if (stat.size > MAX_PLAN_BYTES) {
|
|
44258
|
-
return { ok: false, message: `FAIL ${
|
|
44702
|
+
return { ok: false, message: `FAIL ${path96}: plan file exceeds 1MB (${stat.size} bytes); refusing to parse` };
|
|
44259
44703
|
}
|
|
44260
44704
|
let text;
|
|
44261
44705
|
try {
|
|
44262
|
-
text = readFileSync89(
|
|
44706
|
+
text = readFileSync89(path96, "utf8");
|
|
44263
44707
|
} catch (err) {
|
|
44264
|
-
return { ok: false, message: `FAIL cannot read ${
|
|
44708
|
+
return { ok: false, message: `FAIL cannot read ${path96}: ${err instanceof Error ? err.message : "unknown"}` };
|
|
44265
44709
|
}
|
|
44266
44710
|
if (!text.replace(/^/, "").startsWith("---")) {
|
|
44267
|
-
return { ok: false, message: `FAIL ${
|
|
44711
|
+
return { ok: false, message: `FAIL ${path96}: no YAML frontmatter (missing opening --- marker)` };
|
|
44268
44712
|
}
|
|
44269
44713
|
if (!text.includes("\n---", 3)) {
|
|
44270
|
-
return { ok: false, message: `FAIL ${
|
|
44714
|
+
return { ok: false, message: `FAIL ${path96}: frontmatter block never closed (missing closing --- marker)` };
|
|
44271
44715
|
}
|
|
44272
44716
|
const fm = extractFrontmatter(text);
|
|
44273
44717
|
if (fm === null) {
|
|
44274
|
-
return { ok: false, message: `FAIL ${
|
|
44718
|
+
return { ok: false, message: `FAIL ${path96}: frontmatter could not be parsed as YAML` };
|
|
44275
44719
|
}
|
|
44276
44720
|
const hasScores = "k5_scores" in fm;
|
|
44277
44721
|
const hasBoost = "k5_boost" in fm;
|
|
44278
44722
|
const hasComposite = "k5_composite" in fm;
|
|
44279
44723
|
const hasScoredAt = "k5_scored_at" in fm;
|
|
44280
44724
|
if (!hasScores && !hasBoost && !hasComposite && !hasScoredAt) {
|
|
44281
|
-
return { ok: true, message: `PASS ${
|
|
44725
|
+
return { ok: true, message: `PASS ${path96}: k5_scores absent (acceptable \u2014 legacy plan)` };
|
|
44282
44726
|
}
|
|
44283
44727
|
const errors = [];
|
|
44284
44728
|
if (hasScores) {
|
|
@@ -44298,9 +44742,9 @@ function validatePlan(path95) {
|
|
|
44298
44742
|
if (err !== null) errors.push(err);
|
|
44299
44743
|
}
|
|
44300
44744
|
if (errors.length > 0) {
|
|
44301
|
-
return { ok: false, message: `FAIL ${
|
|
44745
|
+
return { ok: false, message: `FAIL ${path96}: ${errors.join("; ")}` };
|
|
44302
44746
|
}
|
|
44303
|
-
const lines = [`PASS ${
|
|
44747
|
+
const lines = [`PASS ${path96}: k5_scores valid`];
|
|
44304
44748
|
if (hasScores && typeof fm.k5_scores === "object" && fm.k5_scores !== null) {
|
|
44305
44749
|
const scoresObj = fm.k5_scores;
|
|
44306
44750
|
const vals = [];
|
|
@@ -44445,12 +44889,12 @@ function registerFlywheelK10Measure(parent) {
|
|
|
44445
44889
|
|
|
44446
44890
|
// src/commands/flywheel/check-persona-skeleton.ts
|
|
44447
44891
|
import { existsSync as existsSync110, readFileSync as readFileSync91, statSync as statSync31 } from "node:fs";
|
|
44448
|
-
import { homedir as
|
|
44892
|
+
import { homedir as homedir60 } from "node:os";
|
|
44449
44893
|
import { basename as basename14, join as join103 } from "node:path";
|
|
44450
44894
|
import { parse as parseYAML2 } from "yaml";
|
|
44451
44895
|
var CHARS_PER_TOKEN3 = 4;
|
|
44452
44896
|
var K10_TOKEN_CAP2 = 6e3;
|
|
44453
|
-
var AGENTS_DIR = join103(
|
|
44897
|
+
var AGENTS_DIR = join103(homedir60(), ".claude", "agents");
|
|
44454
44898
|
var REQUIRED_FRONTMATTER_KEYS = ["name", "description", "allowed-tools"];
|
|
44455
44899
|
var REQUIRED_SECTIONS = [
|
|
44456
44900
|
"## Role",
|
|
@@ -44700,7 +45144,7 @@ ${formatRedivergencePrompt(persona_a, persona_b, score, void 0, void 0, threshol
|
|
|
44700
45144
|
|
|
44701
45145
|
// src/commands/flywheel/ping.ts
|
|
44702
45146
|
import { mkdirSync as mkdirSync64, writeFileSync as writeFileSync56 } from "node:fs";
|
|
44703
|
-
import { homedir as
|
|
45147
|
+
import { homedir as homedir61 } from "node:os";
|
|
44704
45148
|
import { dirname as dirname60, join as join104 } from "node:path";
|
|
44705
45149
|
var COLD_START_BUDGET_GOOD_MS = 200;
|
|
44706
45150
|
var COLD_START_BUDGET_FAIR_MS = 500;
|
|
@@ -44717,7 +45161,7 @@ function readOlamVersion() {
|
|
|
44717
45161
|
}
|
|
44718
45162
|
}
|
|
44719
45163
|
function writeBaseline(record) {
|
|
44720
|
-
const baselinePath = join104(
|
|
45164
|
+
const baselinePath = join104(homedir61(), ".local", "share", "olam", "flywheel-baseline.json");
|
|
44721
45165
|
mkdirSync64(dirname60(baselinePath), { recursive: true });
|
|
44722
45166
|
writeFileSync56(baselinePath, JSON.stringify(record, null, 2) + "\n", "utf8");
|
|
44723
45167
|
return baselinePath;
|
|
@@ -44766,8 +45210,8 @@ import {
|
|
|
44766
45210
|
statSync as statSync32,
|
|
44767
45211
|
writeFileSync as writeFileSync57
|
|
44768
45212
|
} from "node:fs";
|
|
44769
|
-
import { spawnSync as
|
|
44770
|
-
import { homedir as
|
|
45213
|
+
import { spawnSync as spawnSync31 } from "node:child_process";
|
|
45214
|
+
import { homedir as homedir62 } from "node:os";
|
|
44771
45215
|
import { dirname as dirname61, join as join105, relative as relative7 } from "node:path";
|
|
44772
45216
|
function escapeRegex(s) {
|
|
44773
45217
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -44844,7 +45288,7 @@ function resolveAtlasUser2(opts) {
|
|
|
44844
45288
|
assertValidAtlasUser(v);
|
|
44845
45289
|
return v;
|
|
44846
45290
|
}
|
|
44847
|
-
const claudeDir2 = opts._testClaudeDir ?? process.env["OLAM_CLAUDE_DIR"] ?? join105(
|
|
45291
|
+
const claudeDir2 = opts._testClaudeDir ?? process.env["OLAM_CLAUDE_DIR"] ?? join105(homedir62(), ".claude");
|
|
44848
45292
|
const f = join105(claudeDir2, ".atlas-user");
|
|
44849
45293
|
if (existsSync111(f)) {
|
|
44850
45294
|
const v = readFileSync93(f, "utf-8").trim();
|
|
@@ -44855,7 +45299,7 @@ function resolveAtlasUser2(opts) {
|
|
|
44855
45299
|
return null;
|
|
44856
45300
|
}
|
|
44857
45301
|
function runGit2(args, cwd) {
|
|
44858
|
-
const result =
|
|
45302
|
+
const result = spawnSync31("git", args, {
|
|
44859
45303
|
cwd,
|
|
44860
45304
|
encoding: "utf-8",
|
|
44861
45305
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -44981,7 +45425,7 @@ function pushOverlays(opts) {
|
|
|
44981
45425
|
Run \`olam skills atlas-user set <name>\` to configure your atlas user.`
|
|
44982
45426
|
);
|
|
44983
45427
|
}
|
|
44984
|
-
const claudeDir2 = opts._testClaudeDir ?? opts.targetDir ?? process.env["OLAM_CLAUDE_DIR"] ?? join105(
|
|
45428
|
+
const claudeDir2 = opts._testClaudeDir ?? opts.targetDir ?? process.env["OLAM_CLAUDE_DIR"] ?? join105(homedir62(), ".claude");
|
|
44985
45429
|
const sourceFiles = walkPushSourceFiles(claudeDir2);
|
|
44986
45430
|
const registeredPrefixes = (opts._testSkillSources ?? listSkillSources()).map((s) => s.prefix).filter((p) => typeof p === "string" && p.length > 0);
|
|
44987
45431
|
if (registeredPrefixes.length > 0) {
|
|
@@ -45289,7 +45733,7 @@ Next steps (run in ${clonePath}):`,
|
|
|
45289
45733
|
};
|
|
45290
45734
|
}
|
|
45291
45735
|
function migrateOverlays(opts = {}) {
|
|
45292
|
-
const root = opts.targetDir ?? join105(
|
|
45736
|
+
const root = opts.targetDir ?? join105(homedir62(), ".claude");
|
|
45293
45737
|
const overrideRoots = [
|
|
45294
45738
|
join105(root, "skills.overrides"),
|
|
45295
45739
|
join105(root, "agents.overrides")
|
|
@@ -45411,7 +45855,7 @@ function registerFlywheelMigrateOverlays(parent) {
|
|
|
45411
45855
|
}
|
|
45412
45856
|
return;
|
|
45413
45857
|
}
|
|
45414
|
-
const root = opts.targetDir ?? join105(
|
|
45858
|
+
const root = opts.targetDir ?? join105(homedir62(), ".claude");
|
|
45415
45859
|
const summary2 = migrateOverlays(opts);
|
|
45416
45860
|
if (opts.json === true) {
|
|
45417
45861
|
process.stdout.write(JSON.stringify(summary2, null, 2) + "\n");
|
|
@@ -45468,7 +45912,7 @@ function registerFlywheel(program2) {
|
|
|
45468
45912
|
|
|
45469
45913
|
// src/commands/seed.ts
|
|
45470
45914
|
init_output();
|
|
45471
|
-
import { spawnSync as
|
|
45915
|
+
import { spawnSync as spawnSync32, spawn as spawnAsync2 } from "node:child_process";
|
|
45472
45916
|
var DEFAULT_SINGLETON_CONTAINER = "olam-postgres";
|
|
45473
45917
|
var DEFAULT_SINGLETON_USER = "development";
|
|
45474
45918
|
function assertValidSeedName(name) {
|
|
@@ -45479,7 +45923,7 @@ function assertValidSeedName(name) {
|
|
|
45479
45923
|
}
|
|
45480
45924
|
}
|
|
45481
45925
|
function singletonDocker(container, user, args, stdin) {
|
|
45482
|
-
return
|
|
45926
|
+
return spawnSync32(
|
|
45483
45927
|
"docker",
|
|
45484
45928
|
["exec", "-i", container, "psql", "-U", user, ...args],
|
|
45485
45929
|
{ encoding: "utf-8", input: stdin }
|
|
@@ -45534,7 +45978,7 @@ async function handleBake(opts) {
|
|
|
45534
45978
|
if (sources.length > 1) {
|
|
45535
45979
|
throw new Error("multiple sources specified \u2014 pass exactly one of --source-container, --source-url, --source-local");
|
|
45536
45980
|
}
|
|
45537
|
-
const ping =
|
|
45981
|
+
const ping = spawnSync32("docker", ["inspect", "--format", "{{.State.Status}}", singleton], { encoding: "utf-8" });
|
|
45538
45982
|
if (ping.status !== 0 || (ping.stdout || "").trim() !== "running") {
|
|
45539
45983
|
throw new Error(`singleton container "${singleton}" not running \u2014 run \`olam bootstrap\` first`);
|
|
45540
45984
|
}
|
|
@@ -45717,12 +46161,12 @@ init_output();
|
|
|
45717
46161
|
import { spawnSync as defaultSpawnSync } from "node:child_process";
|
|
45718
46162
|
import * as fs94 from "node:fs";
|
|
45719
46163
|
import * as os49 from "node:os";
|
|
45720
|
-
import * as
|
|
46164
|
+
import * as path94 from "node:path";
|
|
45721
46165
|
function devboxContainerName(worldId) {
|
|
45722
46166
|
return `olam-${worldId}-devbox`;
|
|
45723
46167
|
}
|
|
45724
46168
|
function olamHomeDir() {
|
|
45725
|
-
return process.env["OLAM_HOME"] ??
|
|
46169
|
+
return process.env["OLAM_HOME"] ?? path94.join(os49.homedir(), ".olam");
|
|
45726
46170
|
}
|
|
45727
46171
|
function defaultRestartContainer(name, spawn13 = defaultSpawnSync) {
|
|
45728
46172
|
const r = spawn13("docker", ["restart", "--time", "30", name], {
|
|
@@ -45736,7 +46180,7 @@ function defaultRestartContainer(name, spawn13 = defaultSpawnSync) {
|
|
|
45736
46180
|
}
|
|
45737
46181
|
function defaultAppendAuditLog(homeDir, line) {
|
|
45738
46182
|
fs94.mkdirSync(homeDir, { recursive: true });
|
|
45739
|
-
fs94.appendFileSync(
|
|
46183
|
+
fs94.appendFileSync(path94.join(homeDir, "usage.log"), line.endsWith("\n") ? line : line + "\n", {
|
|
45740
46184
|
encoding: "utf-8"
|
|
45741
46185
|
});
|
|
45742
46186
|
}
|
|
@@ -45781,9 +46225,9 @@ async function doRekey(worldId, deps) {
|
|
|
45781
46225
|
);
|
|
45782
46226
|
const rotatedAt = deps.now().toISOString();
|
|
45783
46227
|
const homeDir = deps.olamHomeDir();
|
|
45784
|
-
const worldDir =
|
|
46228
|
+
const worldDir = path94.join(homeDir, "worlds", worldId);
|
|
45785
46229
|
fs94.mkdirSync(worldDir, { recursive: true });
|
|
45786
|
-
const credentialsPath =
|
|
46230
|
+
const credentialsPath = path94.join(worldDir, "credentials.json");
|
|
45787
46231
|
const payload = {
|
|
45788
46232
|
worldRoleName,
|
|
45789
46233
|
password,
|
|
@@ -45858,12 +46302,12 @@ function registerRekey(program2) {
|
|
|
45858
46302
|
|
|
45859
46303
|
// src/pleri-config.ts
|
|
45860
46304
|
import * as fs95 from "node:fs";
|
|
45861
|
-
import * as
|
|
46305
|
+
import * as path95 from "node:path";
|
|
45862
46306
|
function isPleriConfigured(configDir = process.env.OLAM_CONFIG_DIR ?? ".olam") {
|
|
45863
46307
|
if (process.env.PLERI_BASE_URL) {
|
|
45864
46308
|
return true;
|
|
45865
46309
|
}
|
|
45866
|
-
const configPath =
|
|
46310
|
+
const configPath = path95.join(configDir, "config.yaml");
|
|
45867
46311
|
if (!fs95.existsSync(configPath)) {
|
|
45868
46312
|
return false;
|
|
45869
46313
|
}
|
|
@@ -45902,6 +46346,7 @@ registerDestroy(program);
|
|
|
45902
46346
|
registerClean(program);
|
|
45903
46347
|
registerImplode(program);
|
|
45904
46348
|
registerEnter(program);
|
|
46349
|
+
registerResume(program);
|
|
45905
46350
|
registerCrystallize(program, { hidden: !isPleriConfigured() });
|
|
45906
46351
|
registerPr(program);
|
|
45907
46352
|
registerWorkspace(program);
|