@pleri/olam-cli 0.1.198 → 0.1.200
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ask/knowledge-pack.generated.d.ts.map +1 -1
- package/dist/ask/knowledge-pack.generated.js +3 -1
- package/dist/ask/knowledge-pack.generated.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +23 -8
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/bootstrap.d.ts.map +1 -1
- package/dist/commands/bootstrap.js +4 -0
- package/dist/commands/bootstrap.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +3 -0
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/flywheel/diversity-check.d.ts +1 -1
- package/dist/commands/flywheel/diversity-check.js +1 -1
- package/dist/commands/flywheel/k5-score.d.ts +1 -1
- package/dist/commands/flywheel/k5-score.js +1 -1
- package/dist/commands/flywheel/k5-validate.d.ts +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/kg-mirror.d.ts +16 -0
- package/dist/commands/kg-mirror.d.ts.map +1 -1
- package/dist/commands/kg-mirror.js +94 -0
- package/dist/commands/kg-mirror.js.map +1 -1
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +7 -3
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/refresh.js +1 -1
- package/dist/commands/refresh.js.map +1 -1
- package/dist/commands/services.d.ts +10 -2
- package/dist/commands/services.d.ts.map +1 -1
- package/dist/commands/services.js +45 -39
- package/dist/commands/services.js.map +1 -1
- package/dist/commands/skills-100x.d.ts +34 -0
- package/dist/commands/skills-100x.d.ts.map +1 -0
- package/dist/commands/{skills-10x.js → skills-100x.js} +138 -41
- package/dist/commands/skills-100x.js.map +1 -0
- package/dist/commands/skills-install-model-router.d.ts +20 -0
- package/dist/commands/skills-install-model-router.d.ts.map +1 -0
- package/dist/commands/skills-install-model-router.js +55 -0
- package/dist/commands/skills-install-model-router.js.map +1 -0
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +2 -0
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +0 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/workspace.d.ts.map +1 -1
- package/dist/commands/workspace.js +1 -2
- package/dist/commands/workspace.js.map +1 -1
- package/dist/image-digests.json +8 -8
- package/dist/index.js +1236 -756
- package/dist/index.js.map +1 -1
- package/dist/lib/bootstrap-kubernetes.d.ts +24 -2
- package/dist/lib/bootstrap-kubernetes.d.ts.map +1 -1
- package/dist/lib/bootstrap-kubernetes.js +100 -7
- package/dist/lib/bootstrap-kubernetes.js.map +1 -1
- package/dist/lib/help-groups.js +1 -1
- package/dist/lib/help-groups.js.map +1 -1
- package/dist/mcp-server.js +547 -346
- package/hermes-bundle/version.json +1 -1
- package/hooks/model-router.py +445 -0
- package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
- package/package.json +2 -1
- package/dist/commands/skills-10x.d.ts +0 -23
- package/dist/commands/skills-10x.d.ts.map +0 -1
- package/dist/commands/skills-10x.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -5568,7 +5568,7 @@ async function safeText(res) {
|
|
|
5568
5568
|
}
|
|
5569
5569
|
}
|
|
5570
5570
|
function sleep(ms) {
|
|
5571
|
-
return new Promise((
|
|
5571
|
+
return new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
5572
5572
|
}
|
|
5573
5573
|
var DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, RETRY_COUNT, RETRY_BACKOFF_MS, AuthClient;
|
|
5574
5574
|
var init_client = __esm({
|
|
@@ -5721,7 +5721,7 @@ function resolveAuthServicePath() {
|
|
|
5721
5721
|
return path10.join(pkgsDir, "auth-service");
|
|
5722
5722
|
}
|
|
5723
5723
|
function sleep2(ms) {
|
|
5724
|
-
return new Promise((
|
|
5724
|
+
return new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
5725
5725
|
}
|
|
5726
5726
|
var DEFAULT_PORT, DEFAULT_VOLUME, DEFAULT_CONTAINER, DEFAULT_IMAGE, AuthContainerController;
|
|
5727
5727
|
var init_container = __esm({
|
|
@@ -6032,7 +6032,7 @@ var init_network = __esm({
|
|
|
6032
6032
|
// ../adapters/dist/docker/pull.js
|
|
6033
6033
|
import { spawn } from "node:child_process";
|
|
6034
6034
|
function spawnAsync(cmd, args, opts = {}) {
|
|
6035
|
-
return new Promise((
|
|
6035
|
+
return new Promise((resolve31) => {
|
|
6036
6036
|
const child = spawn(cmd, [...args], {
|
|
6037
6037
|
stdio: ["ignore", "pipe", "pipe"],
|
|
6038
6038
|
signal: opts.signal
|
|
@@ -6046,10 +6046,10 @@ function spawnAsync(cmd, args, opts = {}) {
|
|
|
6046
6046
|
stderr += chunk.toString();
|
|
6047
6047
|
});
|
|
6048
6048
|
child.on("error", (err) => {
|
|
6049
|
-
|
|
6049
|
+
resolve31({ exitCode: -1, stdout, stderr: stderr + err.message });
|
|
6050
6050
|
});
|
|
6051
6051
|
child.on("close", (code) => {
|
|
6052
|
-
|
|
6052
|
+
resolve31({ exitCode: code ?? -1, stdout, stderr });
|
|
6053
6053
|
});
|
|
6054
6054
|
});
|
|
6055
6055
|
}
|
|
@@ -6614,7 +6614,7 @@ var demuxStream, execInContainer;
|
|
|
6614
6614
|
var init_exec = __esm({
|
|
6615
6615
|
"../adapters/dist/docker/exec.js"() {
|
|
6616
6616
|
"use strict";
|
|
6617
|
-
demuxStream = (stream) => new Promise((
|
|
6617
|
+
demuxStream = (stream) => new Promise((resolve31, reject) => {
|
|
6618
6618
|
const stdoutChunks = [];
|
|
6619
6619
|
const stderrChunks = [];
|
|
6620
6620
|
const stdout = new PassThrough();
|
|
@@ -6628,7 +6628,7 @@ var init_exec = __esm({
|
|
|
6628
6628
|
stream.pipe(stdout);
|
|
6629
6629
|
}
|
|
6630
6630
|
stream.on("end", () => {
|
|
6631
|
-
|
|
6631
|
+
resolve31({
|
|
6632
6632
|
stdout: Buffer.concat(stdoutChunks).toString("utf-8"),
|
|
6633
6633
|
stderr: Buffer.concat(stderrChunks).toString("utf-8")
|
|
6634
6634
|
});
|
|
@@ -7088,7 +7088,7 @@ var init_connection = __esm({
|
|
|
7088
7088
|
// -----------------------------------------------------------------------
|
|
7089
7089
|
async exec(host, command) {
|
|
7090
7090
|
const client = await this.getConnection(host);
|
|
7091
|
-
return new Promise((
|
|
7091
|
+
return new Promise((resolve31, reject) => {
|
|
7092
7092
|
client.exec(command, (err, stream) => {
|
|
7093
7093
|
if (err) {
|
|
7094
7094
|
reject(new Error(`SSH exec failed on ${host}: ${err.message}`));
|
|
@@ -7103,7 +7103,7 @@ var init_connection = __esm({
|
|
|
7103
7103
|
stderr += data.toString();
|
|
7104
7104
|
});
|
|
7105
7105
|
stream.on("close", (code) => {
|
|
7106
|
-
|
|
7106
|
+
resolve31({
|
|
7107
7107
|
exitCode: code ?? 0,
|
|
7108
7108
|
stdout: stdout.trimEnd(),
|
|
7109
7109
|
stderr: stderr.trimEnd()
|
|
@@ -7134,10 +7134,10 @@ var init_connection = __esm({
|
|
|
7134
7134
|
throw new Error(`No SSH configuration found for host: ${host}`);
|
|
7135
7135
|
}
|
|
7136
7136
|
const client = new SSHClient();
|
|
7137
|
-
return new Promise((
|
|
7137
|
+
return new Promise((resolve31, reject) => {
|
|
7138
7138
|
client.on("ready", () => {
|
|
7139
7139
|
this.connections.set(host, client);
|
|
7140
|
-
|
|
7140
|
+
resolve31(client);
|
|
7141
7141
|
}).on("error", (err) => {
|
|
7142
7142
|
this.connections.delete(host);
|
|
7143
7143
|
reject(new Error(`SSH connection to ${host} failed: ${err.message}`));
|
|
@@ -9539,8 +9539,8 @@ import { execFileSync as execFileSync4 } from "node:child_process";
|
|
|
9539
9539
|
import * as fs17 from "node:fs";
|
|
9540
9540
|
import * as os11 from "node:os";
|
|
9541
9541
|
import * as path19 from "node:path";
|
|
9542
|
-
function expandHome2(p,
|
|
9543
|
-
return p.replace(/^~(?=$|\/|\\)/,
|
|
9542
|
+
function expandHome2(p, homedir77) {
|
|
9543
|
+
return p.replace(/^~(?=$|\/|\\)/, homedir77());
|
|
9544
9544
|
}
|
|
9545
9545
|
function sanitizeRepoFilename(name) {
|
|
9546
9546
|
const sanitized = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
@@ -9563,7 +9563,7 @@ ${stderr}`;
|
|
|
9563
9563
|
}
|
|
9564
9564
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
9565
9565
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync4(cmd, args, opts));
|
|
9566
|
-
const
|
|
9566
|
+
const homedir77 = deps.homedir ?? (() => os11.homedir());
|
|
9567
9567
|
const baselineDir = path19.join(workspacePath, ".olam", "baseline");
|
|
9568
9568
|
try {
|
|
9569
9569
|
fs17.mkdirSync(baselineDir, { recursive: true });
|
|
@@ -9579,7 +9579,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
9579
9579
|
continue;
|
|
9580
9580
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
9581
9581
|
const outPath = path19.join(baselineDir, filename);
|
|
9582
|
-
const repoPath = expandHome2(repo.path,
|
|
9582
|
+
const repoPath = expandHome2(repo.path, homedir77);
|
|
9583
9583
|
if (!fs17.existsSync(repoPath)) {
|
|
9584
9584
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
9585
9585
|
# (skipped: path ${repoPath} does not exist)
|
|
@@ -9699,21 +9699,21 @@ function extractStderr(err) {
|
|
|
9699
9699
|
}
|
|
9700
9700
|
function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
9701
9701
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync4(cmd, args, opts));
|
|
9702
|
-
const
|
|
9703
|
-
const
|
|
9702
|
+
const homedir77 = deps.homedir ?? (() => os11.homedir());
|
|
9703
|
+
const existsSync122 = deps.existsSync ?? ((p) => fs17.existsSync(p));
|
|
9704
9704
|
const copyFileSync17 = deps.copyFileSync ?? ((src, dest) => fs17.copyFileSync(src, dest));
|
|
9705
|
-
const
|
|
9705
|
+
const mkdirSync73 = deps.mkdirSync ?? ((dirPath, opts) => {
|
|
9706
9706
|
fs17.mkdirSync(dirPath, opts);
|
|
9707
9707
|
});
|
|
9708
9708
|
const plans = [];
|
|
9709
9709
|
for (const repo of repos) {
|
|
9710
9710
|
if (!repo.path)
|
|
9711
9711
|
continue;
|
|
9712
|
-
const repoPath = expandHome2(repo.path,
|
|
9712
|
+
const repoPath = expandHome2(repo.path, homedir77);
|
|
9713
9713
|
const worktreePath = path19.join(workspacePath, repo.name);
|
|
9714
|
-
if (!
|
|
9714
|
+
if (!existsSync122(repoPath))
|
|
9715
9715
|
continue;
|
|
9716
|
-
if (!
|
|
9716
|
+
if (!existsSync122(worktreePath)) {
|
|
9717
9717
|
console.warn(`[carry] ${repo.name}: world worktree ${worktreePath} missing; skipping carry for this repo`);
|
|
9718
9718
|
continue;
|
|
9719
9719
|
}
|
|
@@ -9773,10 +9773,10 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
9773
9773
|
for (const rel of plan.diff.untracked) {
|
|
9774
9774
|
const src = path19.join(plan.repoPath, rel);
|
|
9775
9775
|
const dest = path19.join(plan.worktreePath, rel);
|
|
9776
|
-
if (!
|
|
9776
|
+
if (!existsSync122(src))
|
|
9777
9777
|
continue;
|
|
9778
9778
|
try {
|
|
9779
|
-
|
|
9779
|
+
mkdirSync73(path19.dirname(dest), { recursive: true });
|
|
9780
9780
|
copyFileSync17(src, dest);
|
|
9781
9781
|
} catch (err) {
|
|
9782
9782
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -11425,7 +11425,7 @@ var init_auto_dispatch_task = __esm({
|
|
|
11425
11425
|
this.name = "TaskDispatchError";
|
|
11426
11426
|
}
|
|
11427
11427
|
};
|
|
11428
|
-
DEFAULT_SLEEP = (ms) => new Promise((
|
|
11428
|
+
DEFAULT_SLEEP = (ms) => new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
11429
11429
|
}
|
|
11430
11430
|
});
|
|
11431
11431
|
|
|
@@ -11660,7 +11660,7 @@ var init_schema4 = __esm({
|
|
|
11660
11660
|
env: external_exports.record(external_exports.string().min(1), external_exports.record(external_exports.string().min(1), external_exports.string())).optional(),
|
|
11661
11661
|
updatedAt: external_exports.number().int().nonnegative()
|
|
11662
11662
|
});
|
|
11663
|
-
MetaHookBlockKindSchema = external_exports.enum(["memory-recall", "memory-classify"]);
|
|
11663
|
+
MetaHookBlockKindSchema = external_exports.enum(["memory-recall", "memory-classify", "model-router"]);
|
|
11664
11664
|
GlobalConfigSchema = external_exports.object({
|
|
11665
11665
|
schemaVersion: external_exports.literal(1),
|
|
11666
11666
|
repos: external_exports.array(RepoEntrySchema).optional().default([]),
|
|
@@ -15417,7 +15417,7 @@ function isCloudflaredAvailable() {
|
|
|
15417
15417
|
}
|
|
15418
15418
|
}
|
|
15419
15419
|
function startTunnel(port2) {
|
|
15420
|
-
return new Promise((
|
|
15420
|
+
return new Promise((resolve31, reject) => {
|
|
15421
15421
|
const child = spawn3("cloudflared", ["tunnel", "--url", `http://localhost:${port2}`], {
|
|
15422
15422
|
stdio: ["ignore", "pipe", "pipe"],
|
|
15423
15423
|
detached: false
|
|
@@ -15439,7 +15439,7 @@ function startTunnel(port2) {
|
|
|
15439
15439
|
if (match2) {
|
|
15440
15440
|
resolved = true;
|
|
15441
15441
|
clearTimeout(timeout);
|
|
15442
|
-
|
|
15442
|
+
resolve31(match2[0]);
|
|
15443
15443
|
}
|
|
15444
15444
|
}
|
|
15445
15445
|
child.stdout?.on("data", scan);
|
|
@@ -15526,8 +15526,8 @@ var init_dashboard = __esm({
|
|
|
15526
15526
|
}
|
|
15527
15527
|
throw err;
|
|
15528
15528
|
}
|
|
15529
|
-
await new Promise((
|
|
15530
|
-
this.server.on("listening",
|
|
15529
|
+
await new Promise((resolve31, reject) => {
|
|
15530
|
+
this.server.on("listening", resolve31);
|
|
15531
15531
|
this.server.on("error", reject);
|
|
15532
15532
|
});
|
|
15533
15533
|
this.info = { localUrl: `http://localhost:${port2}` };
|
|
@@ -15573,8 +15573,8 @@ var init_dashboard = __esm({
|
|
|
15573
15573
|
async stop() {
|
|
15574
15574
|
stopTunnel();
|
|
15575
15575
|
if (this.server) {
|
|
15576
|
-
await new Promise((
|
|
15577
|
-
this.server.close(() =>
|
|
15576
|
+
await new Promise((resolve31) => {
|
|
15577
|
+
this.server.close(() => resolve31());
|
|
15578
15578
|
});
|
|
15579
15579
|
this.server = null;
|
|
15580
15580
|
}
|
|
@@ -15903,8 +15903,8 @@ async function findHostCpContainer() {
|
|
|
15903
15903
|
const docker3 = new Dockerode2(resolveDockerHostOptions());
|
|
15904
15904
|
let timer = null;
|
|
15905
15905
|
const listing = docker3.listContainers({ all: true }).then((cs) => cs);
|
|
15906
|
-
const timeout = new Promise((
|
|
15907
|
-
timer = setTimeout(() =>
|
|
15906
|
+
const timeout = new Promise((resolve31) => {
|
|
15907
|
+
timer = setTimeout(() => resolve31(null), DOCKER_PROBE_TIMEOUT_MS);
|
|
15908
15908
|
});
|
|
15909
15909
|
let containers;
|
|
15910
15910
|
try {
|
|
@@ -16688,7 +16688,7 @@ async function ensureOlamPostgresSingleton(options = {}) {
|
|
|
16688
16688
|
};
|
|
16689
16689
|
}
|
|
16690
16690
|
function sleep3(ms) {
|
|
16691
|
-
return new Promise((
|
|
16691
|
+
return new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
16692
16692
|
}
|
|
16693
16693
|
var DEFAULT_POSTGRES_NETWORK, DEFAULT_POSTGRES_CONTAINER, DEFAULT_POSTGRES_HOST_PORT, DEFAULT_POSTGRES_IMAGE, DEFAULT_POSTGRES_USER, DEFAULT_POSTGRES_PASSWORD, DEFAULT_POSTGRES_DB, DEFAULT_POSTGRES_READY_TIMEOUT_MS;
|
|
16694
16694
|
var init_postgres_init_helpers = __esm({
|
|
@@ -18399,17 +18399,143 @@ var init_memory_classify = __esm({
|
|
|
18399
18399
|
}
|
|
18400
18400
|
});
|
|
18401
18401
|
|
|
18402
|
+
// ../core/dist/meta-hooks/model-router.js
|
|
18403
|
+
import * as fs69 from "node:fs";
|
|
18404
|
+
function buildModelRouterHookEntry() {
|
|
18405
|
+
return {
|
|
18406
|
+
hooks: [
|
|
18407
|
+
{
|
|
18408
|
+
type: "command",
|
|
18409
|
+
command: `OLAM_META_SENTINEL=${OLAM_META_MODEL_ROUTER_SENTINEL}; ${OLAM_META_NOOP_GUARD3} python3 "${OLAM_META_MODEL_ROUTER_SCRIPT_PATH}"`,
|
|
18410
|
+
timeout: OLAM_META_MODEL_ROUTER_TIMEOUT_MS
|
|
18411
|
+
}
|
|
18412
|
+
]
|
|
18413
|
+
};
|
|
18414
|
+
}
|
|
18415
|
+
function computeModelRouterUninstall(settings) {
|
|
18416
|
+
const matchers = settings.hooks?.UserPromptSubmit;
|
|
18417
|
+
if (!Array.isArray(matchers) || matchers.length === 0) {
|
|
18418
|
+
return { status: "not-found" };
|
|
18419
|
+
}
|
|
18420
|
+
let changed = false;
|
|
18421
|
+
const filteredMatchers = [];
|
|
18422
|
+
for (const matcher of matchers) {
|
|
18423
|
+
const innerHooks = matcher.hooks ?? [];
|
|
18424
|
+
const keptInner = innerHooks.filter((h) => {
|
|
18425
|
+
if (typeof h.command === "string" && h.command.includes(OLAM_META_MODEL_ROUTER_SENTINEL)) {
|
|
18426
|
+
changed = true;
|
|
18427
|
+
return false;
|
|
18428
|
+
}
|
|
18429
|
+
return true;
|
|
18430
|
+
});
|
|
18431
|
+
if (keptInner.length === 0 && innerHooks.length > 0) {
|
|
18432
|
+
changed = true;
|
|
18433
|
+
continue;
|
|
18434
|
+
}
|
|
18435
|
+
if (keptInner.length === innerHooks.length) {
|
|
18436
|
+
filteredMatchers.push(matcher);
|
|
18437
|
+
} else {
|
|
18438
|
+
filteredMatchers.push({ ...matcher, hooks: keptInner });
|
|
18439
|
+
}
|
|
18440
|
+
}
|
|
18441
|
+
if (!changed)
|
|
18442
|
+
return { status: "not-found" };
|
|
18443
|
+
const next = {
|
|
18444
|
+
...settings,
|
|
18445
|
+
hooks: {
|
|
18446
|
+
...settings.hooks,
|
|
18447
|
+
UserPromptSubmit: filteredMatchers
|
|
18448
|
+
}
|
|
18449
|
+
};
|
|
18450
|
+
if (filteredMatchers.length === 0) {
|
|
18451
|
+
const otherStages = Object.keys(next.hooks ?? {}).filter((k) => k !== "UserPromptSubmit");
|
|
18452
|
+
if (otherStages.length === 0) {
|
|
18453
|
+
delete next.hooks;
|
|
18454
|
+
} else {
|
|
18455
|
+
delete next.hooks.UserPromptSubmit;
|
|
18456
|
+
}
|
|
18457
|
+
}
|
|
18458
|
+
return { status: "removed", settingsAfter: next };
|
|
18459
|
+
}
|
|
18460
|
+
function matchModelRouterSentinel(commandLine) {
|
|
18461
|
+
return commandLine.includes(OLAM_META_MODEL_ROUTER_SENTINEL);
|
|
18462
|
+
}
|
|
18463
|
+
var OLAM_META_MODEL_ROUTER_SENTINEL, OLAM_META_MODEL_ROUTER_STAGE, OLAM_META_MODEL_ROUTER_TIMEOUT_MS, OLAM_META_MODEL_ROUTER_SCRIPT_PATH, OLAM_META_MODEL_ROUTER_SCRIPT_BASENAME, OLAM_META_NOOP_GUARD3;
|
|
18464
|
+
var init_model_router = __esm({
|
|
18465
|
+
"../core/dist/meta-hooks/model-router.js"() {
|
|
18466
|
+
"use strict";
|
|
18467
|
+
OLAM_META_MODEL_ROUTER_SENTINEL = "olam-meta-model-router-v1";
|
|
18468
|
+
OLAM_META_MODEL_ROUTER_STAGE = "UserPromptSubmit";
|
|
18469
|
+
OLAM_META_MODEL_ROUTER_TIMEOUT_MS = 5e3;
|
|
18470
|
+
OLAM_META_MODEL_ROUTER_SCRIPT_PATH = "$HOME/.claude/hooks/model-router.py";
|
|
18471
|
+
OLAM_META_MODEL_ROUTER_SCRIPT_BASENAME = "model-router.py";
|
|
18472
|
+
OLAM_META_NOOP_GUARD3 = "command -v olam >/dev/null 2>&1 || exit 0;";
|
|
18473
|
+
}
|
|
18474
|
+
});
|
|
18475
|
+
|
|
18476
|
+
// ../core/dist/meta-hooks/model-router-deploy.js
|
|
18477
|
+
import { existsSync as existsSync77, mkdirSync as mkdirSync45, readFileSync as readFileSync66, writeFileSync as writeFileSync41 } from "node:fs";
|
|
18478
|
+
import { homedir as homedir43 } from "node:os";
|
|
18479
|
+
import { dirname as dirname39, join as join75, resolve as resolve20 } from "node:path";
|
|
18480
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
18481
|
+
function resolveModelRouterSourcePath() {
|
|
18482
|
+
const here3 = dirname39(fileURLToPath8(import.meta.url));
|
|
18483
|
+
const candidates2 = [
|
|
18484
|
+
// (1) in-repo tsc dist: core/dist/meta-hooks → ../../../cli/hooks
|
|
18485
|
+
resolve20(here3, "..", "..", "..", "cli", "hooks", MODEL_ROUTER_SCRIPT_BASENAME),
|
|
18486
|
+
// (1b) in-repo src (tsx / vitest): core/src/meta-hooks → ../../../cli/hooks
|
|
18487
|
+
resolve20(here3, "..", "..", "..", "cli", "hooks", MODEL_ROUTER_SCRIPT_BASENAME),
|
|
18488
|
+
// (2) bundled CLI: dist/<bundle> → ../hooks (hooks is sibling of dist)
|
|
18489
|
+
resolve20(here3, "..", "hooks", MODEL_ROUTER_SCRIPT_BASENAME),
|
|
18490
|
+
resolve20(here3, "..", "..", "hooks", MODEL_ROUTER_SCRIPT_BASENAME)
|
|
18491
|
+
];
|
|
18492
|
+
for (const candidate of candidates2) {
|
|
18493
|
+
if (existsSync77(candidate))
|
|
18494
|
+
return candidate;
|
|
18495
|
+
}
|
|
18496
|
+
return candidates2[0];
|
|
18497
|
+
}
|
|
18498
|
+
function deployModelRouterScript(opts = {}) {
|
|
18499
|
+
const targetDir = opts.targetDir ?? join75(homedir43(), ".claude", "hooks");
|
|
18500
|
+
const targetPath = join75(targetDir, MODEL_ROUTER_SCRIPT_BASENAME);
|
|
18501
|
+
const sourcePath = opts.sourcePath ?? resolveModelRouterSourcePath();
|
|
18502
|
+
if (!existsSync77(sourcePath)) {
|
|
18503
|
+
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "source-missing", targetPath };
|
|
18504
|
+
}
|
|
18505
|
+
const newContent = readFileSync66(sourcePath, "utf8");
|
|
18506
|
+
if (existsSync77(targetPath)) {
|
|
18507
|
+
const existing = readFileSync66(targetPath, "utf8");
|
|
18508
|
+
if (existing === newContent) {
|
|
18509
|
+
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "unchanged", targetPath };
|
|
18510
|
+
}
|
|
18511
|
+
}
|
|
18512
|
+
if (opts.dryRun !== true) {
|
|
18513
|
+
mkdirSync45(dirname39(targetPath), { recursive: true });
|
|
18514
|
+
writeFileSync41(targetPath, newContent, { mode: 493 });
|
|
18515
|
+
}
|
|
18516
|
+
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "written", targetPath };
|
|
18517
|
+
}
|
|
18518
|
+
var MODEL_ROUTER_SCRIPT_BASENAME;
|
|
18519
|
+
var init_model_router_deploy = __esm({
|
|
18520
|
+
"../core/dist/meta-hooks/model-router-deploy.js"() {
|
|
18521
|
+
"use strict";
|
|
18522
|
+
MODEL_ROUTER_SCRIPT_BASENAME = "model-router.py";
|
|
18523
|
+
}
|
|
18524
|
+
});
|
|
18525
|
+
|
|
18402
18526
|
// ../core/dist/meta-hooks/index.js
|
|
18403
18527
|
var init_meta_hooks = __esm({
|
|
18404
18528
|
"../core/dist/meta-hooks/index.js"() {
|
|
18405
18529
|
"use strict";
|
|
18406
18530
|
init_memory_recall();
|
|
18407
18531
|
init_memory_classify();
|
|
18532
|
+
init_model_router();
|
|
18533
|
+
init_model_router_deploy();
|
|
18408
18534
|
}
|
|
18409
18535
|
});
|
|
18410
18536
|
|
|
18411
18537
|
// ../core/dist/skill-sync/settings-merger.js
|
|
18412
|
-
import * as
|
|
18538
|
+
import * as fs70 from "node:fs";
|
|
18413
18539
|
import * as os39 from "node:os";
|
|
18414
18540
|
import * as path68 from "node:path";
|
|
18415
18541
|
function claudeSettingsPath() {
|
|
@@ -18478,28 +18604,28 @@ function tagOlam(entry) {
|
|
|
18478
18604
|
return { ...entry, [OLAM_SKILLS_MARKER]: true };
|
|
18479
18605
|
}
|
|
18480
18606
|
function readJson(file) {
|
|
18481
|
-
return JSON.parse(
|
|
18607
|
+
return JSON.parse(fs70.readFileSync(file, "utf-8"));
|
|
18482
18608
|
}
|
|
18483
18609
|
function rotateBackups(backupDir) {
|
|
18484
|
-
if (!
|
|
18610
|
+
if (!fs70.existsSync(backupDir))
|
|
18485
18611
|
return;
|
|
18486
|
-
const files =
|
|
18612
|
+
const files = fs70.readdirSync(backupDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, full: path68.join(backupDir, f), mtime: fs70.statSync(path68.join(backupDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
18487
18613
|
for (const f of files.slice(BACKUP_RETENTION)) {
|
|
18488
18614
|
try {
|
|
18489
|
-
|
|
18615
|
+
fs70.unlinkSync(f.full);
|
|
18490
18616
|
} catch {
|
|
18491
18617
|
}
|
|
18492
18618
|
}
|
|
18493
18619
|
}
|
|
18494
18620
|
function backupSettings() {
|
|
18495
18621
|
const src = claudeSettingsPath();
|
|
18496
|
-
if (!
|
|
18622
|
+
if (!fs70.existsSync(src))
|
|
18497
18623
|
return void 0;
|
|
18498
18624
|
const dir = settingsBackupDir();
|
|
18499
|
-
|
|
18625
|
+
fs70.mkdirSync(dir, { recursive: true });
|
|
18500
18626
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
18501
18627
|
const dest = path68.join(dir, `settings-${stamp}.json`);
|
|
18502
|
-
|
|
18628
|
+
fs70.copyFileSync(src, dest);
|
|
18503
18629
|
rotateBackups(dir);
|
|
18504
18630
|
return dest;
|
|
18505
18631
|
}
|
|
@@ -18507,7 +18633,7 @@ function mergeSettings(input2) {
|
|
|
18507
18633
|
const settingsPath = claudeSettingsPath();
|
|
18508
18634
|
const backupPath = backupSettings();
|
|
18509
18635
|
let base = {};
|
|
18510
|
-
if (
|
|
18636
|
+
if (fs70.existsSync(settingsPath)) {
|
|
18511
18637
|
try {
|
|
18512
18638
|
base = readJson(settingsPath);
|
|
18513
18639
|
} catch {
|
|
@@ -18575,10 +18701,10 @@ function mergeSettings(input2) {
|
|
|
18575
18701
|
...input2.permissionFiles.length > 0 ? { allow: [...permSet] } : {}
|
|
18576
18702
|
}
|
|
18577
18703
|
};
|
|
18578
|
-
|
|
18704
|
+
fs70.mkdirSync(path68.dirname(settingsPath), { recursive: true });
|
|
18579
18705
|
const tmp = `${settingsPath}.tmp-${process.pid}`;
|
|
18580
|
-
|
|
18581
|
-
|
|
18706
|
+
fs70.writeFileSync(tmp, JSON.stringify(next, null, 2) + "\n", { mode: 420 });
|
|
18707
|
+
fs70.renameSync(tmp, settingsPath);
|
|
18582
18708
|
return { backupPath, hooksAdded, permissionsCount: permSet.size, dualWriteDeduped, dualWriteDroppedCommands };
|
|
18583
18709
|
}
|
|
18584
18710
|
var OLAM_SKILLS_MARKER, BACKUP_RETENTION, DUAL_WRITE_DEDUP_RULES;
|
|
@@ -18635,7 +18761,7 @@ var init_schema5 = __esm({
|
|
|
18635
18761
|
|
|
18636
18762
|
// ../core/dist/skill-sync/per-project-override.js
|
|
18637
18763
|
import { execFileSync as execFileSync16 } from "node:child_process";
|
|
18638
|
-
import * as
|
|
18764
|
+
import * as fs71 from "node:fs";
|
|
18639
18765
|
import * as path69 from "node:path";
|
|
18640
18766
|
import { parse as parseYaml6 } from "yaml";
|
|
18641
18767
|
function findProjectOverride(startDir) {
|
|
@@ -18643,8 +18769,8 @@ function findProjectOverride(startDir) {
|
|
|
18643
18769
|
const root = path69.parse(dir).root;
|
|
18644
18770
|
while (true) {
|
|
18645
18771
|
const candidate = path69.join(dir, PROJECT_OVERRIDE_RELATIVE_PATH);
|
|
18646
|
-
if (
|
|
18647
|
-
const raw =
|
|
18772
|
+
if (fs71.existsSync(candidate) && fs71.statSync(candidate).isFile()) {
|
|
18773
|
+
const raw = fs71.readFileSync(candidate, "utf-8");
|
|
18648
18774
|
let parsed;
|
|
18649
18775
|
try {
|
|
18650
18776
|
parsed = parseYaml6(raw);
|
|
@@ -18703,7 +18829,7 @@ var init_per_project_override = __esm({
|
|
|
18703
18829
|
});
|
|
18704
18830
|
|
|
18705
18831
|
// ../core/dist/lib/file-lock.js
|
|
18706
|
-
import * as
|
|
18832
|
+
import * as fs72 from "node:fs";
|
|
18707
18833
|
import * as os40 from "node:os";
|
|
18708
18834
|
import * as path70 from "node:path";
|
|
18709
18835
|
function defaultIsPidAlive(pid) {
|
|
@@ -18716,11 +18842,11 @@ function defaultIsPidAlive(pid) {
|
|
|
18716
18842
|
}
|
|
18717
18843
|
}
|
|
18718
18844
|
function sleep7(ms) {
|
|
18719
|
-
return new Promise((
|
|
18845
|
+
return new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
18720
18846
|
}
|
|
18721
18847
|
function readLockMeta(lockPath) {
|
|
18722
18848
|
try {
|
|
18723
|
-
const raw =
|
|
18849
|
+
const raw = fs72.readFileSync(lockPath, "utf-8");
|
|
18724
18850
|
const parsed = JSON.parse(raw);
|
|
18725
18851
|
if (typeof parsed?.pid === "number" && typeof parsed?.hostname === "string" && typeof parsed?.timestamp === "number") {
|
|
18726
18852
|
return parsed;
|
|
@@ -18739,12 +18865,12 @@ function isLockStale(meta, opts) {
|
|
|
18739
18865
|
}
|
|
18740
18866
|
function tryAcquireOnce(lockPath, meta, opts) {
|
|
18741
18867
|
try {
|
|
18742
|
-
|
|
18743
|
-
const fd =
|
|
18868
|
+
fs72.mkdirSync(path70.dirname(lockPath), { recursive: true });
|
|
18869
|
+
const fd = fs72.openSync(lockPath, "wx", 384);
|
|
18744
18870
|
try {
|
|
18745
|
-
|
|
18871
|
+
fs72.writeSync(fd, JSON.stringify(meta));
|
|
18746
18872
|
} finally {
|
|
18747
|
-
|
|
18873
|
+
fs72.closeSync(fd);
|
|
18748
18874
|
}
|
|
18749
18875
|
return true;
|
|
18750
18876
|
} catch (err) {
|
|
@@ -18754,14 +18880,14 @@ function tryAcquireOnce(lockPath, meta, opts) {
|
|
|
18754
18880
|
const existing = readLockMeta(lockPath);
|
|
18755
18881
|
if (existing === void 0) {
|
|
18756
18882
|
try {
|
|
18757
|
-
|
|
18883
|
+
fs72.unlinkSync(lockPath);
|
|
18758
18884
|
} catch {
|
|
18759
18885
|
}
|
|
18760
18886
|
return tryAcquireOnce(lockPath, meta, opts);
|
|
18761
18887
|
}
|
|
18762
18888
|
if (isLockStale(existing, opts)) {
|
|
18763
18889
|
try {
|
|
18764
|
-
|
|
18890
|
+
fs72.unlinkSync(lockPath);
|
|
18765
18891
|
} catch {
|
|
18766
18892
|
}
|
|
18767
18893
|
return tryAcquireOnce(lockPath, meta, opts);
|
|
@@ -18791,7 +18917,7 @@ async function acquireFileLock(lockDir, options = {}) {
|
|
|
18791
18917
|
lockPath,
|
|
18792
18918
|
release: () => {
|
|
18793
18919
|
try {
|
|
18794
|
-
|
|
18920
|
+
fs72.unlinkSync(lockPath);
|
|
18795
18921
|
} catch {
|
|
18796
18922
|
}
|
|
18797
18923
|
}
|
|
@@ -18831,13 +18957,13 @@ var init_file_lock = __esm({
|
|
|
18831
18957
|
});
|
|
18832
18958
|
|
|
18833
18959
|
// ../core/dist/lib/min-version-filter.js
|
|
18834
|
-
import { existsSync as
|
|
18960
|
+
import { existsSync as existsSync80, readFileSync as readFileSync70 } from "node:fs";
|
|
18835
18961
|
function readOlamMinVersion(filepath) {
|
|
18836
|
-
if (!
|
|
18962
|
+
if (!existsSync80(filepath))
|
|
18837
18963
|
return void 0;
|
|
18838
18964
|
let text;
|
|
18839
18965
|
try {
|
|
18840
|
-
text =
|
|
18966
|
+
text = readFileSync70(filepath, "utf8");
|
|
18841
18967
|
} catch {
|
|
18842
18968
|
return void 0;
|
|
18843
18969
|
}
|
|
@@ -18895,11 +19021,11 @@ var init_min_version_filter = __esm({
|
|
|
18895
19021
|
});
|
|
18896
19022
|
|
|
18897
19023
|
// ../core/dist/skill-sync/overlay-scan.js
|
|
18898
|
-
import * as
|
|
19024
|
+
import * as fs73 from "node:fs";
|
|
18899
19025
|
import * as path71 from "node:path";
|
|
18900
19026
|
function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
18901
19027
|
const result = /* @__PURE__ */ new Map();
|
|
18902
|
-
if (!
|
|
19028
|
+
if (!fs73.existsSync(overlayRoot)) {
|
|
18903
19029
|
return result;
|
|
18904
19030
|
}
|
|
18905
19031
|
if (basenames.length === 0) {
|
|
@@ -18908,13 +19034,13 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
18908
19034
|
const mdFiles = [];
|
|
18909
19035
|
let overlayRootReal;
|
|
18910
19036
|
try {
|
|
18911
|
-
overlayRootReal =
|
|
19037
|
+
overlayRootReal = fs73.realpathSync(overlayRoot);
|
|
18912
19038
|
} catch {
|
|
18913
19039
|
return result;
|
|
18914
19040
|
}
|
|
18915
19041
|
for (const subdir of OVERRIDE_SUBDIRS) {
|
|
18916
19042
|
const dir = path71.join(overlayRoot, subdir);
|
|
18917
|
-
if (!
|
|
19043
|
+
if (!fs73.existsSync(dir))
|
|
18918
19044
|
continue;
|
|
18919
19045
|
walkMarkdown(dir, mdFiles, caps.maxFiles);
|
|
18920
19046
|
}
|
|
@@ -18922,7 +19048,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
18922
19048
|
for (const filepath of mdFiles) {
|
|
18923
19049
|
let realFile;
|
|
18924
19050
|
try {
|
|
18925
|
-
realFile =
|
|
19051
|
+
realFile = fs73.realpathSync(filepath);
|
|
18926
19052
|
} catch (err) {
|
|
18927
19053
|
const code = err.code;
|
|
18928
19054
|
if (code === "ENOENT" || code === "EACCES")
|
|
@@ -18935,12 +19061,12 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
18935
19061
|
}
|
|
18936
19062
|
let content;
|
|
18937
19063
|
try {
|
|
18938
|
-
const stat =
|
|
19064
|
+
const stat = fs73.statSync(filepath);
|
|
18939
19065
|
totalBytes += stat.size;
|
|
18940
19066
|
if (totalBytes > caps.maxTotalBytes) {
|
|
18941
19067
|
throw new Error(`[overlay-scan] aborted: overlay tree exceeds ${caps.maxTotalBytes} total bytes. Check OLAM_CLAUDE_DIR / overlay paths are correctly scoped.`);
|
|
18942
19068
|
}
|
|
18943
|
-
content =
|
|
19069
|
+
content = fs73.readFileSync(filepath, "utf8");
|
|
18944
19070
|
} catch (err) {
|
|
18945
19071
|
const code = err.code;
|
|
18946
19072
|
if (code === "ENOENT" || code === "EACCES") {
|
|
@@ -18962,7 +19088,7 @@ function scanOverlayReferences(overlayRoot, basenames, caps = DEFAULT_CAPS) {
|
|
|
18962
19088
|
function walkMarkdown(dir, out, cap) {
|
|
18963
19089
|
let entries;
|
|
18964
19090
|
try {
|
|
18965
|
-
entries =
|
|
19091
|
+
entries = fs73.readdirSync(dir, { withFileTypes: true });
|
|
18966
19092
|
} catch (err) {
|
|
18967
19093
|
if (err.code === "ENOENT")
|
|
18968
19094
|
return;
|
|
@@ -18997,7 +19123,7 @@ var init_overlay_scan = __esm({
|
|
|
18997
19123
|
});
|
|
18998
19124
|
|
|
18999
19125
|
// ../core/dist/skill-sync/settings-json-lock.js
|
|
19000
|
-
import * as
|
|
19126
|
+
import * as fs74 from "node:fs";
|
|
19001
19127
|
import * as os41 from "node:os";
|
|
19002
19128
|
import * as path72 from "node:path";
|
|
19003
19129
|
function defaultSettingsJsonLockPath() {
|
|
@@ -19014,11 +19140,11 @@ function defaultIsPidAlive2(pid) {
|
|
|
19014
19140
|
}
|
|
19015
19141
|
}
|
|
19016
19142
|
function sleep8(ms) {
|
|
19017
|
-
return new Promise((
|
|
19143
|
+
return new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
19018
19144
|
}
|
|
19019
19145
|
function readLockMeta2(lockPath) {
|
|
19020
19146
|
try {
|
|
19021
|
-
const raw =
|
|
19147
|
+
const raw = fs74.readFileSync(lockPath, "utf-8");
|
|
19022
19148
|
const parsed = JSON.parse(raw);
|
|
19023
19149
|
if (typeof parsed?.pid === "number" && typeof parsed?.hostname === "string" && typeof parsed?.timestamp === "number") {
|
|
19024
19150
|
return parsed;
|
|
@@ -19041,12 +19167,12 @@ function isLockStale2(meta, opts) {
|
|
|
19041
19167
|
function tryAcquireOnce2(lockPath, meta, opts) {
|
|
19042
19168
|
for (let attempt = 0; attempt <= MAX_STEAL_ATTEMPTS; attempt += 1) {
|
|
19043
19169
|
try {
|
|
19044
|
-
|
|
19045
|
-
const fd =
|
|
19170
|
+
fs74.mkdirSync(path72.dirname(lockPath), { recursive: true });
|
|
19171
|
+
const fd = fs74.openSync(lockPath, "wx", 384);
|
|
19046
19172
|
try {
|
|
19047
|
-
|
|
19173
|
+
fs74.writeSync(fd, JSON.stringify(meta));
|
|
19048
19174
|
} finally {
|
|
19049
|
-
|
|
19175
|
+
fs74.closeSync(fd);
|
|
19050
19176
|
}
|
|
19051
19177
|
return true;
|
|
19052
19178
|
} catch (err) {
|
|
@@ -19064,9 +19190,9 @@ function tryAcquireOnce2(lockPath, meta, opts) {
|
|
|
19064
19190
|
}
|
|
19065
19191
|
const victimPath = `${lockPath}.victim-${process.pid}-${attempt}-${Date.now()}`;
|
|
19066
19192
|
try {
|
|
19067
|
-
|
|
19193
|
+
fs74.renameSync(lockPath, victimPath);
|
|
19068
19194
|
try {
|
|
19069
|
-
|
|
19195
|
+
fs74.unlinkSync(victimPath);
|
|
19070
19196
|
} catch {
|
|
19071
19197
|
}
|
|
19072
19198
|
} catch (err) {
|
|
@@ -19098,7 +19224,7 @@ async function acquireSettingsJsonLock(options = {}) {
|
|
|
19098
19224
|
lockPath,
|
|
19099
19225
|
release: () => {
|
|
19100
19226
|
try {
|
|
19101
|
-
|
|
19227
|
+
fs74.unlinkSync(lockPath);
|
|
19102
19228
|
} catch {
|
|
19103
19229
|
}
|
|
19104
19230
|
}
|
|
@@ -19201,7 +19327,7 @@ var init_services_status = __esm({
|
|
|
19201
19327
|
|
|
19202
19328
|
// ../core/dist/skill-sources/meta-hooks-migration-snapshot.js
|
|
19203
19329
|
import * as crypto10 from "node:crypto";
|
|
19204
|
-
import * as
|
|
19330
|
+
import * as fs75 from "node:fs";
|
|
19205
19331
|
import * as os42 from "node:os";
|
|
19206
19332
|
import * as path73 from "node:path";
|
|
19207
19333
|
function migrationSnapshotsDir2() {
|
|
@@ -19219,41 +19345,41 @@ function writeMetaHooksSnapshot(originalSettings) {
|
|
|
19219
19345
|
};
|
|
19220
19346
|
const validated = MetaHooksMigrationSnapshotSchema.parse(snapshot);
|
|
19221
19347
|
const dir = migrationSnapshotsDir2();
|
|
19222
|
-
|
|
19348
|
+
fs75.mkdirSync(dir, { recursive: true });
|
|
19223
19349
|
const stamp = validated.takenAt.replace(/[:.]/g, "-");
|
|
19224
19350
|
const rand = crypto10.randomBytes(3).toString("hex");
|
|
19225
19351
|
const file = path73.join(dir, `${META_HOOKS_SNAPSHOT_PREFIX}${stamp}-${process.pid}-${rand}.json`);
|
|
19226
|
-
|
|
19352
|
+
fs75.writeFileSync(file, JSON.stringify(validated, null, 2) + "\n", { mode: 384 });
|
|
19227
19353
|
return file;
|
|
19228
19354
|
}
|
|
19229
19355
|
function readMetaHooksSnapshot(filePath) {
|
|
19230
|
-
if (!
|
|
19356
|
+
if (!fs75.existsSync(filePath)) {
|
|
19231
19357
|
throw new Error(`snapshot file not found: ${filePath}`);
|
|
19232
19358
|
}
|
|
19233
|
-
const raw =
|
|
19359
|
+
const raw = fs75.readFileSync(filePath, "utf-8");
|
|
19234
19360
|
const parsed = JSON.parse(raw);
|
|
19235
19361
|
return MetaHooksMigrationSnapshotSchema.parse(parsed);
|
|
19236
19362
|
}
|
|
19237
19363
|
function findLatestMetaHooksSnapshot() {
|
|
19238
19364
|
const dir = migrationSnapshotsDir2();
|
|
19239
|
-
if (!
|
|
19365
|
+
if (!fs75.existsSync(dir))
|
|
19240
19366
|
return void 0;
|
|
19241
|
-
const candidates2 =
|
|
19367
|
+
const candidates2 = fs75.readdirSync(dir).filter((n) => n.startsWith(META_HOOKS_SNAPSHOT_PREFIX) && n.endsWith(".json")).sort().reverse();
|
|
19242
19368
|
if (candidates2.length === 0)
|
|
19243
19369
|
return void 0;
|
|
19244
19370
|
return path73.join(dir, candidates2[0]);
|
|
19245
19371
|
}
|
|
19246
19372
|
function restoreSettingsFromSnapshot(snapshot, settingsPath) {
|
|
19247
19373
|
if (snapshot.originalSettings === null) {
|
|
19248
|
-
if (
|
|
19249
|
-
|
|
19374
|
+
if (fs75.existsSync(settingsPath)) {
|
|
19375
|
+
fs75.unlinkSync(settingsPath);
|
|
19250
19376
|
}
|
|
19251
19377
|
return;
|
|
19252
19378
|
}
|
|
19253
|
-
|
|
19379
|
+
fs75.mkdirSync(path73.dirname(settingsPath), { recursive: true });
|
|
19254
19380
|
const tmp = `${settingsPath}.tmp-restore-${process.pid}-${Date.now()}`;
|
|
19255
|
-
|
|
19256
|
-
|
|
19381
|
+
fs75.writeFileSync(tmp, JSON.stringify(snapshot.originalSettings, null, 2) + "\n");
|
|
19382
|
+
fs75.renameSync(tmp, settingsPath);
|
|
19257
19383
|
}
|
|
19258
19384
|
var META_HOOKS_SNAPSHOT_SCHEMA_VERSION, META_HOOKS_SNAPSHOT_PREFIX, SettingsLooseSchema, MetaHooksMigrationSnapshotSchema;
|
|
19259
19385
|
var init_meta_hooks_migration_snapshot = __esm({
|
|
@@ -19393,6 +19519,8 @@ function decideTargetBlocks(opts) {
|
|
|
19393
19519
|
target.add("memory-recall");
|
|
19394
19520
|
if (wantMemory && !disabled.has("memory-classify"))
|
|
19395
19521
|
target.add("memory-classify");
|
|
19522
|
+
if (!disabled.has("model-router"))
|
|
19523
|
+
target.add("model-router");
|
|
19396
19524
|
return target;
|
|
19397
19525
|
}
|
|
19398
19526
|
function injectMetaHooks(opts) {
|
|
@@ -19400,6 +19528,7 @@ function injectMetaHooks(opts) {
|
|
|
19400
19528
|
let working = JSON.parse(JSON.stringify(opts.currentSettings ?? {}));
|
|
19401
19529
|
const blocksAdded = [];
|
|
19402
19530
|
const blocksRemoved = [];
|
|
19531
|
+
const blocksSkippedForeign = [];
|
|
19403
19532
|
const memoryRecallPresent = hasMemoryRecallBlock(working);
|
|
19404
19533
|
if (target.has("memory-recall")) {
|
|
19405
19534
|
if (!memoryRecallPresent) {
|
|
@@ -19430,10 +19559,30 @@ function injectMetaHooks(opts) {
|
|
|
19430
19559
|
}
|
|
19431
19560
|
}
|
|
19432
19561
|
}
|
|
19562
|
+
const modelRouterPresent = hasModelRouterBlock(working);
|
|
19563
|
+
if (target.has("model-router")) {
|
|
19564
|
+
if (!modelRouterPresent) {
|
|
19565
|
+
if (hasForeignModelRouterEntry(working)) {
|
|
19566
|
+
blocksSkippedForeign.push("model-router");
|
|
19567
|
+
} else {
|
|
19568
|
+
working = appendBlock(working, OLAM_META_MODEL_ROUTER_STAGE, buildModelRouterHookEntry());
|
|
19569
|
+
blocksAdded.push("model-router");
|
|
19570
|
+
}
|
|
19571
|
+
}
|
|
19572
|
+
} else {
|
|
19573
|
+
if (modelRouterPresent) {
|
|
19574
|
+
const r = computeModelRouterUninstall(working);
|
|
19575
|
+
if (r.status === "removed" && r.settingsAfter) {
|
|
19576
|
+
working = r.settingsAfter;
|
|
19577
|
+
blocksRemoved.push("model-router");
|
|
19578
|
+
}
|
|
19579
|
+
}
|
|
19580
|
+
}
|
|
19433
19581
|
return {
|
|
19434
19582
|
nextSettings: working,
|
|
19435
19583
|
blocksAdded,
|
|
19436
19584
|
blocksRemoved,
|
|
19585
|
+
blocksSkippedForeign,
|
|
19437
19586
|
mode: opts.mode ?? "auto"
|
|
19438
19587
|
};
|
|
19439
19588
|
}
|
|
@@ -19467,6 +19616,40 @@ function hasMemoryClassifyBlock(settings) {
|
|
|
19467
19616
|
}
|
|
19468
19617
|
return false;
|
|
19469
19618
|
}
|
|
19619
|
+
function hasModelRouterBlock(settings) {
|
|
19620
|
+
const entries = settings.hooks?.UserPromptSubmit;
|
|
19621
|
+
if (!Array.isArray(entries))
|
|
19622
|
+
return false;
|
|
19623
|
+
for (const matcher of entries) {
|
|
19624
|
+
const inner = matcher?.hooks ?? [];
|
|
19625
|
+
if (!Array.isArray(inner))
|
|
19626
|
+
continue;
|
|
19627
|
+
for (const h of inner) {
|
|
19628
|
+
if (typeof h?.command === "string" && matchModelRouterSentinel(h.command))
|
|
19629
|
+
return true;
|
|
19630
|
+
}
|
|
19631
|
+
}
|
|
19632
|
+
return false;
|
|
19633
|
+
}
|
|
19634
|
+
function hasForeignModelRouterEntry(settings) {
|
|
19635
|
+
const entries = settings.hooks?.UserPromptSubmit;
|
|
19636
|
+
if (!Array.isArray(entries))
|
|
19637
|
+
return false;
|
|
19638
|
+
for (const matcher of entries) {
|
|
19639
|
+
const inner = matcher?.hooks ?? [];
|
|
19640
|
+
if (!Array.isArray(inner))
|
|
19641
|
+
continue;
|
|
19642
|
+
for (const h of inner) {
|
|
19643
|
+
if (typeof h?.command !== "string")
|
|
19644
|
+
continue;
|
|
19645
|
+
if (matchModelRouterSentinel(h.command))
|
|
19646
|
+
continue;
|
|
19647
|
+
if (h.command.includes(OLAM_META_MODEL_ROUTER_SCRIPT_BASENAME))
|
|
19648
|
+
return true;
|
|
19649
|
+
}
|
|
19650
|
+
}
|
|
19651
|
+
return false;
|
|
19652
|
+
}
|
|
19470
19653
|
function appendBlock(settings, stage, entry) {
|
|
19471
19654
|
const next = { ...settings };
|
|
19472
19655
|
const hooks = { ...settings.hooks ?? {} };
|
|
@@ -19485,7 +19668,7 @@ var init_meta_hook_injector = __esm({
|
|
|
19485
19668
|
|
|
19486
19669
|
// ../core/dist/lib/markdown-merger.js
|
|
19487
19670
|
import { createHash as createHash9 } from "node:crypto";
|
|
19488
|
-
import { readFileSync as
|
|
19671
|
+
import { readFileSync as readFileSync74, existsSync as existsSync83, statSync as statSync23 } from "node:fs";
|
|
19489
19672
|
function parseFrontmatter3(text) {
|
|
19490
19673
|
const match2 = FM_RE2.exec(text);
|
|
19491
19674
|
if (match2 === null)
|
|
@@ -19614,9 +19797,9 @@ function mergeMarkdown(upstreamText, overlayText, labelForError, upstreamPath, o
|
|
|
19614
19797
|
return { merged: fmBlock !== "" ? fmBlock + mergedBody : mergedBody };
|
|
19615
19798
|
}
|
|
19616
19799
|
function sha256OfPath(p) {
|
|
19617
|
-
if (!
|
|
19800
|
+
if (!existsSync83(p) || !statSync23(p).isFile())
|
|
19618
19801
|
return "MISSING";
|
|
19619
|
-
return createHash9("sha256").update(
|
|
19802
|
+
return createHash9("sha256").update(readFileSync74(p)).digest("hex");
|
|
19620
19803
|
}
|
|
19621
19804
|
var FM_RE2, H2_RE;
|
|
19622
19805
|
var init_markdown_merger = __esm({
|
|
@@ -19628,7 +19811,7 @@ var init_markdown_merger = __esm({
|
|
|
19628
19811
|
});
|
|
19629
19812
|
|
|
19630
19813
|
// ../core/dist/skill-sync/managed-merge.js
|
|
19631
|
-
import * as
|
|
19814
|
+
import * as fs76 from "node:fs";
|
|
19632
19815
|
import * as path74 from "node:path";
|
|
19633
19816
|
function materializeMergedSkill(opts) {
|
|
19634
19817
|
const { sourceId, sourcePath, deployBasename, mergedContent, claudeDir: claudeDir2 } = opts;
|
|
@@ -19638,12 +19821,12 @@ function materializeMergedSkill(opts) {
|
|
|
19638
19821
|
if (!(managedResolved === sourceRoot || managedResolved.startsWith(sourceRoot + path74.sep))) {
|
|
19639
19822
|
throw new Error(`[managed-merge] refusing to materialize: deployBasename "${deployBasename}" escapes managed root "${sourceRoot}" (resolved to "${managedResolved}")`);
|
|
19640
19823
|
}
|
|
19641
|
-
|
|
19824
|
+
fs76.mkdirSync(managedDir, { recursive: true });
|
|
19642
19825
|
const skillMdPath = path74.join(managedDir, "SKILL.md");
|
|
19643
19826
|
const tmpPath = `${skillMdPath}.tmp-${process.pid}-${Date.now()}`;
|
|
19644
|
-
|
|
19645
|
-
|
|
19646
|
-
const baseEntries =
|
|
19827
|
+
fs76.writeFileSync(tmpPath, mergedContent);
|
|
19828
|
+
fs76.renameSync(tmpPath, skillMdPath);
|
|
19829
|
+
const baseEntries = fs76.readdirSync(sourcePath);
|
|
19647
19830
|
for (const entry of baseEntries) {
|
|
19648
19831
|
if (entry === "SKILL.md")
|
|
19649
19832
|
continue;
|
|
@@ -19651,13 +19834,13 @@ function materializeMergedSkill(opts) {
|
|
|
19651
19834
|
const targetAbsolute = path74.join(sourcePath, entry);
|
|
19652
19835
|
const targetRelative = path74.relative(managedDir, targetAbsolute);
|
|
19653
19836
|
try {
|
|
19654
|
-
|
|
19655
|
-
|
|
19837
|
+
fs76.lstatSync(linkPath);
|
|
19838
|
+
fs76.rmSync(linkPath, { recursive: true, force: true });
|
|
19656
19839
|
} catch {
|
|
19657
19840
|
}
|
|
19658
|
-
|
|
19841
|
+
fs76.symlinkSync(targetRelative, linkPath);
|
|
19659
19842
|
}
|
|
19660
|
-
const managedEntries =
|
|
19843
|
+
const managedEntries = fs76.readdirSync(managedDir);
|
|
19661
19844
|
const baseEntrySet = new Set(baseEntries);
|
|
19662
19845
|
for (const entry of managedEntries) {
|
|
19663
19846
|
if (entry === "SKILL.md")
|
|
@@ -19665,7 +19848,7 @@ function materializeMergedSkill(opts) {
|
|
|
19665
19848
|
if (!baseEntrySet.has(entry)) {
|
|
19666
19849
|
const stalePath = path74.join(managedDir, entry);
|
|
19667
19850
|
try {
|
|
19668
|
-
|
|
19851
|
+
fs76.rmSync(stalePath, { recursive: true, force: true });
|
|
19669
19852
|
} catch {
|
|
19670
19853
|
}
|
|
19671
19854
|
}
|
|
@@ -19673,7 +19856,7 @@ function materializeMergedSkill(opts) {
|
|
|
19673
19856
|
return managedDir;
|
|
19674
19857
|
}
|
|
19675
19858
|
function cleanMergedDir(claudeDir2) {
|
|
19676
|
-
|
|
19859
|
+
fs76.rmSync(path74.join(claudeDir2, ".olam-merged"), { recursive: true, force: true });
|
|
19677
19860
|
}
|
|
19678
19861
|
var init_managed_merge = __esm({
|
|
19679
19862
|
"../core/dist/skill-sync/managed-merge.js"() {
|
|
@@ -19812,7 +19995,7 @@ var init_prefix_rules = __esm({
|
|
|
19812
19995
|
});
|
|
19813
19996
|
|
|
19814
19997
|
// ../core/dist/skill-sync/prefix-deploy.js
|
|
19815
|
-
import * as
|
|
19998
|
+
import * as fs77 from "node:fs";
|
|
19816
19999
|
import * as path75 from "node:path";
|
|
19817
20000
|
function buildSourcePrefixMap(sources) {
|
|
19818
20001
|
const byId = /* @__PURE__ */ new Map();
|
|
@@ -19868,7 +20051,7 @@ function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir2, dryRun) {
|
|
|
19868
20051
|
}
|
|
19869
20052
|
if (artifact.kind === "skill") {
|
|
19870
20053
|
const skillMdPath = path75.join(artifact.sourcePath, "SKILL.md");
|
|
19871
|
-
const content =
|
|
20054
|
+
const content = fs77.readFileSync(skillMdPath);
|
|
19872
20055
|
const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
|
|
19873
20056
|
const managedDir = materializeMergedSkill({
|
|
19874
20057
|
sourceId: artifact.sourceId,
|
|
@@ -19880,7 +20063,7 @@ function applyPrefixRewrites(baseArtifacts, sourceMap, claudeDir2, dryRun) {
|
|
|
19880
20063
|
artifact.sourcePath = managedDir;
|
|
19881
20064
|
artifact.deployBasename = renamed;
|
|
19882
20065
|
} else {
|
|
19883
|
-
const content = artifact.resolvedContent !== void 0 ? artifact.resolvedContent :
|
|
20066
|
+
const content = artifact.resolvedContent !== void 0 ? artifact.resolvedContent : fs77.readFileSync(artifact.sourcePath);
|
|
19884
20067
|
const rewritten = rewriteFrontmatterName(content, () => renamedFrontmatterName);
|
|
19885
20068
|
artifact.resolvedContent = rewritten;
|
|
19886
20069
|
artifact.deployBasename = renamed;
|
|
@@ -19925,19 +20108,19 @@ var init_prefix_deploy = __esm({
|
|
|
19925
20108
|
});
|
|
19926
20109
|
|
|
19927
20110
|
// ../core/dist/skill-sync/resolve-source-config.js
|
|
19928
|
-
import { readFileSync as
|
|
19929
|
-
import { join as
|
|
20111
|
+
import { readFileSync as readFileSync76, existsSync as existsSync84 } from "node:fs";
|
|
20112
|
+
import { join as join84 } from "node:path";
|
|
19930
20113
|
import { parse as parseYaml7 } from "yaml";
|
|
19931
20114
|
function sourceConfigPath(clonePath) {
|
|
19932
|
-
return
|
|
20115
|
+
return join84(clonePath, "shared", "source-config.yaml");
|
|
19933
20116
|
}
|
|
19934
20117
|
function readSourceConfig(clonePath, sourceId) {
|
|
19935
20118
|
const path106 = sourceConfigPath(clonePath);
|
|
19936
|
-
if (!
|
|
20119
|
+
if (!existsSync84(path106))
|
|
19937
20120
|
return void 0;
|
|
19938
20121
|
let raw;
|
|
19939
20122
|
try {
|
|
19940
|
-
raw =
|
|
20123
|
+
raw = readFileSync76(path106, "utf-8");
|
|
19941
20124
|
} catch (err) {
|
|
19942
20125
|
emitMalformedWarning(sourceId, `read failed: ${errToMsg(err)}`);
|
|
19943
20126
|
return void 0;
|
|
@@ -20032,7 +20215,7 @@ var init_resolve_source_config = __esm({
|
|
|
20032
20215
|
});
|
|
20033
20216
|
|
|
20034
20217
|
// ../core/dist/skill-sync/engine.js
|
|
20035
|
-
import * as
|
|
20218
|
+
import * as fs78 from "node:fs";
|
|
20036
20219
|
import * as os43 from "node:os";
|
|
20037
20220
|
import * as path76 from "node:path";
|
|
20038
20221
|
function resolveAtlasUser(override) {
|
|
@@ -20040,8 +20223,8 @@ function resolveAtlasUser(override) {
|
|
|
20040
20223
|
return override;
|
|
20041
20224
|
const claudeDir2 = process.env["OLAM_CLAUDE_DIR"] || path76.join(os43.homedir(), ".claude");
|
|
20042
20225
|
const f = path76.join(claudeDir2, ".atlas-user");
|
|
20043
|
-
if (
|
|
20044
|
-
return
|
|
20226
|
+
if (fs78.existsSync(f)) {
|
|
20227
|
+
return fs78.readFileSync(f, "utf-8").trim() || void 0;
|
|
20045
20228
|
}
|
|
20046
20229
|
return void 0;
|
|
20047
20230
|
}
|
|
@@ -20053,7 +20236,7 @@ async function syncSkills(opts = {}) {
|
|
|
20053
20236
|
const perSource = [];
|
|
20054
20237
|
for (const source of sources) {
|
|
20055
20238
|
const clonePath = skillSourceClonePath(source.id);
|
|
20056
|
-
if (!
|
|
20239
|
+
if (!fs78.existsSync(clonePath))
|
|
20057
20240
|
continue;
|
|
20058
20241
|
const { artifacts, subscription } = await withFileLock(clonePath, () => {
|
|
20059
20242
|
const pinRef = projectOverride?.override.pin?.[source.id];
|
|
@@ -20093,7 +20276,7 @@ async function syncSkills(opts = {}) {
|
|
|
20093
20276
|
const overlayArtifacts = memberOverlaysEnabled ? projectFilteredArtifacts.filter((a) => a.kind === "overlay") : [];
|
|
20094
20277
|
const effectiveSources = sources.map((s) => {
|
|
20095
20278
|
const clonePath = skillSourceClonePath(s.id);
|
|
20096
|
-
const sourceConfig =
|
|
20279
|
+
const sourceConfig = fs78.existsSync(clonePath) ? readSourceConfig(clonePath, s.id) : void 0;
|
|
20097
20280
|
const eff = resolveEffectivePrefix(s, sourceConfig);
|
|
20098
20281
|
const entry = {
|
|
20099
20282
|
id: s.id,
|
|
@@ -20200,12 +20383,12 @@ async function syncSkills(opts = {}) {
|
|
|
20200
20383
|
let basePath;
|
|
20201
20384
|
if (overlay.targetKind === "skill") {
|
|
20202
20385
|
basePath = path76.join(base.sourcePath, "SKILL.md");
|
|
20203
|
-
baseContent =
|
|
20386
|
+
baseContent = fs78.readFileSync(basePath, "utf-8");
|
|
20204
20387
|
} else {
|
|
20205
20388
|
basePath = base.sourcePath;
|
|
20206
|
-
baseContent =
|
|
20389
|
+
baseContent = fs78.readFileSync(basePath, "utf-8");
|
|
20207
20390
|
}
|
|
20208
|
-
const overlayContent =
|
|
20391
|
+
const overlayContent = fs78.readFileSync(overlay.sourcePath, "utf-8");
|
|
20209
20392
|
const label = `${overlay.sourceId}/${overlay.deployBasename}`;
|
|
20210
20393
|
const mergeResult = mergeMarkdown(baseContent, overlayContent, label, basePath, overlay.sourcePath);
|
|
20211
20394
|
if ("error" in mergeResult) {
|
|
@@ -20287,24 +20470,34 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
20287
20470
|
...memoryProbe.detail !== void 0 ? { memoryDetail: memoryProbe.detail } : {}
|
|
20288
20471
|
};
|
|
20289
20472
|
const settingsFile = claudeSettingsPath();
|
|
20473
|
+
let configDisabled = [];
|
|
20474
|
+
try {
|
|
20475
|
+
const cfg = readGlobalConfig();
|
|
20476
|
+
configDisabled = cfg.metaHooksDisabled ?? [];
|
|
20477
|
+
} catch {
|
|
20478
|
+
}
|
|
20479
|
+
const disabledBlocks = Array.from(/* @__PURE__ */ new Set([
|
|
20480
|
+
...configDisabled,
|
|
20481
|
+
...opts.metaHooksDisabled ?? []
|
|
20482
|
+
]));
|
|
20290
20483
|
let snapshotError;
|
|
20291
20484
|
let stripCandidates = [];
|
|
20292
20485
|
const result = await withSettingsJsonLock(() => {
|
|
20293
20486
|
let currentSettings = {};
|
|
20294
20487
|
let settingsExisted = false;
|
|
20295
|
-
if (
|
|
20488
|
+
if (fs78.existsSync(settingsFile)) {
|
|
20296
20489
|
settingsExisted = true;
|
|
20297
20490
|
try {
|
|
20298
|
-
const raw =
|
|
20491
|
+
const raw = fs78.readFileSync(settingsFile, "utf-8");
|
|
20299
20492
|
currentSettings = raw.trim() ? JSON.parse(raw) : {};
|
|
20300
20493
|
} catch {
|
|
20301
20494
|
try {
|
|
20302
|
-
const raw =
|
|
20495
|
+
const raw = fs78.readFileSync(settingsFile);
|
|
20303
20496
|
const bakDir = path76.join(path76.dirname(settingsFile), ".malformed-backups");
|
|
20304
|
-
|
|
20497
|
+
fs78.mkdirSync(bakDir, { recursive: true });
|
|
20305
20498
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
20306
20499
|
const bakFile = path76.join(bakDir, `settings.json.malformed.${stamp}.bak`);
|
|
20307
|
-
|
|
20500
|
+
fs78.writeFileSync(bakFile, raw, { mode: 384 });
|
|
20308
20501
|
snapshotError = `settings.json was malformed; original bytes preserved at ${bakFile}`;
|
|
20309
20502
|
} catch (bakErr) {
|
|
20310
20503
|
snapshotError = `settings.json malformed AND .bak write failed: ${bakErr instanceof Error ? bakErr.message : String(bakErr)}`;
|
|
@@ -20315,16 +20508,6 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
20315
20508
|
}
|
|
20316
20509
|
stripCandidates = findStripCandidates(currentSettings);
|
|
20317
20510
|
const settingsForInject = stripCandidates.length > 0 ? applyStrip(currentSettings, stripCandidates).nextSettings : currentSettings;
|
|
20318
|
-
let configDisabled = [];
|
|
20319
|
-
try {
|
|
20320
|
-
const cfg = readGlobalConfig();
|
|
20321
|
-
configDisabled = cfg.metaHooksDisabled ?? [];
|
|
20322
|
-
} catch {
|
|
20323
|
-
}
|
|
20324
|
-
const disabledBlocks = Array.from(/* @__PURE__ */ new Set([
|
|
20325
|
-
...configDisabled,
|
|
20326
|
-
...opts.metaHooksDisabled ?? []
|
|
20327
|
-
]));
|
|
20328
20511
|
const inject = injectMetaHooks({
|
|
20329
20512
|
servicesStatus: servicesStatus2,
|
|
20330
20513
|
currentSettings: settingsForInject,
|
|
@@ -20354,17 +20537,34 @@ async function injectMetaHooksIntoSettings(opts) {
|
|
|
20354
20537
|
} catch {
|
|
20355
20538
|
}
|
|
20356
20539
|
}
|
|
20357
|
-
|
|
20540
|
+
fs78.mkdirSync(path76.dirname(settingsFile), { recursive: true });
|
|
20358
20541
|
const tmpPath = `${settingsFile}.tmp-${process.pid}-${Date.now()}`;
|
|
20359
|
-
|
|
20360
|
-
|
|
20542
|
+
fs78.writeFileSync(tmpPath, JSON.stringify(inject.nextSettings, null, 2) + "\n");
|
|
20543
|
+
fs78.renameSync(tmpPath, settingsFile);
|
|
20361
20544
|
return inject;
|
|
20362
20545
|
}, { reason: `syncSkills meta-hook injection (mode=${mode})` });
|
|
20546
|
+
let scriptDeploy;
|
|
20547
|
+
const modelRouterTargeted = mode !== "never" && !disabledBlocks.includes("model-router");
|
|
20548
|
+
if (modelRouterTargeted) {
|
|
20549
|
+
try {
|
|
20550
|
+
scriptDeploy = deployModelRouterScript({
|
|
20551
|
+
targetDir: path76.join(claudeDir(), "hooks")
|
|
20552
|
+
});
|
|
20553
|
+
} catch (err) {
|
|
20554
|
+
scriptDeploy = {
|
|
20555
|
+
basename: "model-router.py",
|
|
20556
|
+
action: "source-missing",
|
|
20557
|
+
targetPath: `${err instanceof Error ? err.message : String(err)}`
|
|
20558
|
+
};
|
|
20559
|
+
}
|
|
20560
|
+
}
|
|
20363
20561
|
return {
|
|
20364
20562
|
mode: result.mode,
|
|
20365
20563
|
servicesStatus: servicesStatus2,
|
|
20366
20564
|
blocksAdded: result.blocksAdded,
|
|
20367
20565
|
blocksRemoved: result.blocksRemoved,
|
|
20566
|
+
...result.blocksSkippedForeign.length > 0 ? { blocksSkippedForeign: result.blocksSkippedForeign } : {},
|
|
20567
|
+
...scriptDeploy !== void 0 ? { scriptDeploy } : {},
|
|
20368
20568
|
...snapshotError !== void 0 ? { snapshotError } : {},
|
|
20369
20569
|
...stripCandidates.length > 0 ? { autoMigrated: { strippedCount: stripCandidates.length, stripCandidates } } : {}
|
|
20370
20570
|
};
|
|
@@ -20389,6 +20589,7 @@ var init_engine = __esm({
|
|
|
20389
20589
|
init_trust_audit_log();
|
|
20390
20590
|
init_atlas_hook_strip();
|
|
20391
20591
|
init_meta_hook_injector();
|
|
20592
|
+
init_model_router_deploy();
|
|
20392
20593
|
init_markdown_merger();
|
|
20393
20594
|
init_managed_merge();
|
|
20394
20595
|
init_prefix_deploy();
|
|
@@ -20398,7 +20599,7 @@ var init_engine = __esm({
|
|
|
20398
20599
|
});
|
|
20399
20600
|
|
|
20400
20601
|
// ../core/dist/skill-sync/shadow-backup-manager.js
|
|
20401
|
-
import * as
|
|
20602
|
+
import * as fs79 from "node:fs";
|
|
20402
20603
|
import * as path77 from "node:path";
|
|
20403
20604
|
function listShadowBackups(opts = {}) {
|
|
20404
20605
|
const claude = opts.claudeDirOverride ?? claudeDir();
|
|
@@ -20406,11 +20607,11 @@ function listShadowBackups(opts = {}) {
|
|
|
20406
20607
|
const out = [];
|
|
20407
20608
|
for (const bucket of SHADOW_BACKUP_BUCKETS) {
|
|
20408
20609
|
const bucketDir = path77.join(claude, bucket);
|
|
20409
|
-
if (!
|
|
20610
|
+
if (!fs79.existsSync(bucketDir))
|
|
20410
20611
|
continue;
|
|
20411
20612
|
let entries;
|
|
20412
20613
|
try {
|
|
20413
|
-
entries =
|
|
20614
|
+
entries = fs79.readdirSync(bucketDir);
|
|
20414
20615
|
} catch {
|
|
20415
20616
|
continue;
|
|
20416
20617
|
}
|
|
@@ -20424,7 +20625,7 @@ function listShadowBackups(opts = {}) {
|
|
|
20424
20625
|
const full = path77.join(bucketDir, name);
|
|
20425
20626
|
let sizeBytes = 0;
|
|
20426
20627
|
try {
|
|
20427
|
-
const st =
|
|
20628
|
+
const st = fs79.statSync(full);
|
|
20428
20629
|
if (st.isDirectory())
|
|
20429
20630
|
continue;
|
|
20430
20631
|
sizeBytes = st.size;
|
|
@@ -20480,7 +20681,7 @@ function pruneShadowBackups(opts) {
|
|
|
20480
20681
|
}
|
|
20481
20682
|
if (!opts.dryRun) {
|
|
20482
20683
|
try {
|
|
20483
|
-
|
|
20684
|
+
fs79.unlinkSync(b.path);
|
|
20484
20685
|
} catch {
|
|
20485
20686
|
skipped.push(b);
|
|
20486
20687
|
continue;
|
|
@@ -20492,7 +20693,7 @@ function pruneShadowBackups(opts) {
|
|
|
20492
20693
|
}
|
|
20493
20694
|
function restoreShadowBackup(opts) {
|
|
20494
20695
|
const abs = path77.resolve(opts.backupPath);
|
|
20495
|
-
if (!
|
|
20696
|
+
if (!fs79.existsSync(abs)) {
|
|
20496
20697
|
throw new Error(`backup file not found: ${abs}`);
|
|
20497
20698
|
}
|
|
20498
20699
|
const basename17 = path77.basename(abs);
|
|
@@ -20502,13 +20703,13 @@ function restoreShadowBackup(opts) {
|
|
|
20502
20703
|
}
|
|
20503
20704
|
const originalBasename = basename17.slice(0, basename17.length - match2[0].length);
|
|
20504
20705
|
const originalPath = path77.join(path77.dirname(abs), originalBasename);
|
|
20505
|
-
if (
|
|
20706
|
+
if (fs79.existsSync(originalPath) && !opts.force) {
|
|
20506
20707
|
throw new Error(`original path already occupied: ${originalPath}. Move/rename it first OR re-run with --force.`);
|
|
20507
20708
|
}
|
|
20508
|
-
if (opts.force &&
|
|
20509
|
-
|
|
20709
|
+
if (opts.force && fs79.existsSync(originalPath)) {
|
|
20710
|
+
fs79.unlinkSync(originalPath);
|
|
20510
20711
|
}
|
|
20511
|
-
|
|
20712
|
+
fs79.renameSync(abs, originalPath);
|
|
20512
20713
|
return { restoredTo: originalPath };
|
|
20513
20714
|
}
|
|
20514
20715
|
var SHADOW_BACKUP_BUCKETS, SHADOW_BACKUP_SUFFIX_RE;
|
|
@@ -20522,7 +20723,7 @@ var init_shadow_backup_manager = __esm({
|
|
|
20522
20723
|
});
|
|
20523
20724
|
|
|
20524
20725
|
// ../core/dist/global-config/repos.js
|
|
20525
|
-
import * as
|
|
20726
|
+
import * as fs80 from "node:fs";
|
|
20526
20727
|
import * as os44 from "node:os";
|
|
20527
20728
|
import * as path78 from "node:path";
|
|
20528
20729
|
function expandPath(p) {
|
|
@@ -20540,7 +20741,7 @@ function addRepo(entry) {
|
|
|
20540
20741
|
throw new Error(`repo "${entry.name}" already registered. Use "olam repos update" to change its path.`);
|
|
20541
20742
|
}
|
|
20542
20743
|
const resolvedPath = expandPath(entry.path);
|
|
20543
|
-
if (!
|
|
20744
|
+
if (!fs80.existsSync(resolvedPath)) {
|
|
20544
20745
|
throw new Error(`path "${entry.path}" does not exist. Verify the path is correct.`);
|
|
20545
20746
|
}
|
|
20546
20747
|
const now = Date.now();
|
|
@@ -20569,7 +20770,7 @@ function updateRepo(name, updates) {
|
|
|
20569
20770
|
throw new Error(`repo "${name}" is not registered. Run "olam repos list" to see registered repos.`);
|
|
20570
20771
|
}
|
|
20571
20772
|
const resolvedUpdatePath = updates.path !== void 0 ? expandPath(updates.path) : void 0;
|
|
20572
|
-
if (resolvedUpdatePath !== void 0 && !
|
|
20773
|
+
if (resolvedUpdatePath !== void 0 && !fs80.existsSync(resolvedUpdatePath)) {
|
|
20573
20774
|
throw new Error(`path "${updates.path}" does not exist. Verify the path is correct.`);
|
|
20574
20775
|
}
|
|
20575
20776
|
const existing = config.repos[idx];
|
|
@@ -20638,7 +20839,7 @@ var init_global_config = __esm({
|
|
|
20638
20839
|
});
|
|
20639
20840
|
|
|
20640
20841
|
// ../core/dist/skill-sources/doctor-checks.js
|
|
20641
|
-
import * as
|
|
20842
|
+
import * as fs81 from "node:fs";
|
|
20642
20843
|
import * as path79 from "node:path";
|
|
20643
20844
|
import * as os45 from "node:os";
|
|
20644
20845
|
function claudeDirInternal3() {
|
|
@@ -20654,11 +20855,11 @@ function checkStateFileParse() {
|
|
|
20654
20855
|
healthy: true,
|
|
20655
20856
|
description: `~/.olam state file (${filePath})`
|
|
20656
20857
|
};
|
|
20657
|
-
if (!
|
|
20858
|
+
if (!fs81.existsSync(filePath)) {
|
|
20658
20859
|
result.details = ["(file does not yet exist \u2014 will be created on first write)"];
|
|
20659
20860
|
return result;
|
|
20660
20861
|
}
|
|
20661
|
-
const raw =
|
|
20862
|
+
const raw = fs81.readFileSync(filePath, "utf-8");
|
|
20662
20863
|
let parsed;
|
|
20663
20864
|
try {
|
|
20664
20865
|
parsed = JSON.parse(raw);
|
|
@@ -20668,8 +20869,8 @@ function checkStateFileParse() {
|
|
|
20668
20869
|
result.details = [err instanceof Error ? err.message : String(err)];
|
|
20669
20870
|
result.repair = () => {
|
|
20670
20871
|
const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
|
|
20671
|
-
|
|
20672
|
-
|
|
20872
|
+
fs81.renameSync(filePath, aside);
|
|
20873
|
+
fs81.writeFileSync(filePath, JSON.stringify({ schemaVersion: 1, repos: [], runbooks: [], skillSources: [] }, null, 2));
|
|
20673
20874
|
};
|
|
20674
20875
|
return result;
|
|
20675
20876
|
}
|
|
@@ -20680,7 +20881,7 @@ function checkStateFileParse() {
|
|
|
20680
20881
|
result.details = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
|
|
20681
20882
|
result.repair = () => {
|
|
20682
20883
|
const aside = `${filePath}.corrupt-${Math.floor(Date.now() / 1e3)}`;
|
|
20683
|
-
|
|
20884
|
+
fs81.copyFileSync(filePath, aside);
|
|
20684
20885
|
const base = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
20685
20886
|
const next = {
|
|
20686
20887
|
...base,
|
|
@@ -20689,7 +20890,7 @@ function checkStateFileParse() {
|
|
|
20689
20890
|
runbooks: [],
|
|
20690
20891
|
skillSources: []
|
|
20691
20892
|
};
|
|
20692
|
-
|
|
20893
|
+
fs81.writeFileSync(filePath, JSON.stringify(next, null, 2));
|
|
20693
20894
|
};
|
|
20694
20895
|
return result;
|
|
20695
20896
|
}
|
|
@@ -20701,15 +20902,15 @@ function checkDanglingSymlinks() {
|
|
|
20701
20902
|
const dangling = [];
|
|
20702
20903
|
for (const bucket of buckets) {
|
|
20703
20904
|
const dir = path79.join(claude, bucket);
|
|
20704
|
-
if (!
|
|
20905
|
+
if (!fs81.existsSync(dir))
|
|
20705
20906
|
continue;
|
|
20706
|
-
for (const name of
|
|
20907
|
+
for (const name of fs81.readdirSync(dir)) {
|
|
20707
20908
|
const linkPath = path79.join(dir, name);
|
|
20708
20909
|
try {
|
|
20709
|
-
const lst =
|
|
20910
|
+
const lst = fs81.lstatSync(linkPath);
|
|
20710
20911
|
if (!lst.isSymbolicLink())
|
|
20711
20912
|
continue;
|
|
20712
|
-
if (!
|
|
20913
|
+
if (!fs81.existsSync(linkPath)) {
|
|
20713
20914
|
dangling.push(linkPath);
|
|
20714
20915
|
}
|
|
20715
20916
|
} catch {
|
|
@@ -20727,7 +20928,7 @@ function checkDanglingSymlinks() {
|
|
|
20727
20928
|
result.repair = () => {
|
|
20728
20929
|
for (const p of dangling) {
|
|
20729
20930
|
try {
|
|
20730
|
-
|
|
20931
|
+
fs81.unlinkSync(p);
|
|
20731
20932
|
} catch {
|
|
20732
20933
|
}
|
|
20733
20934
|
}
|
|
@@ -20742,19 +20943,19 @@ function checkOrphanedSnapshots() {
|
|
|
20742
20943
|
healthy: true,
|
|
20743
20944
|
description: `orphaned migration snapshots under ${dir}`
|
|
20744
20945
|
};
|
|
20745
|
-
if (!
|
|
20946
|
+
if (!fs81.existsSync(dir)) {
|
|
20746
20947
|
return result;
|
|
20747
20948
|
}
|
|
20748
20949
|
const orphans = [];
|
|
20749
|
-
for (const name of
|
|
20950
|
+
for (const name of fs81.readdirSync(dir)) {
|
|
20750
20951
|
if (!name.endsWith(".json"))
|
|
20751
20952
|
continue;
|
|
20752
20953
|
const full = path79.join(dir, name);
|
|
20753
20954
|
try {
|
|
20754
|
-
const stat =
|
|
20955
|
+
const stat = fs81.statSync(full);
|
|
20755
20956
|
if (!stat.isFile())
|
|
20756
20957
|
continue;
|
|
20757
|
-
const raw =
|
|
20958
|
+
const raw = fs81.readFileSync(full, "utf-8");
|
|
20758
20959
|
let parsed;
|
|
20759
20960
|
try {
|
|
20760
20961
|
parsed = JSON.parse(raw);
|
|
@@ -20779,7 +20980,7 @@ function checkOrphanedSnapshots() {
|
|
|
20779
20980
|
result.repair = () => {
|
|
20780
20981
|
for (const o of orphans) {
|
|
20781
20982
|
try {
|
|
20782
|
-
|
|
20983
|
+
fs81.unlinkSync(o.path);
|
|
20783
20984
|
} catch {
|
|
20784
20985
|
}
|
|
20785
20986
|
}
|
|
@@ -20794,12 +20995,12 @@ function checkSentinelDrift() {
|
|
|
20794
20995
|
healthy: true,
|
|
20795
20996
|
description: `olam-skills sentinel block in ${filePath}`
|
|
20796
20997
|
};
|
|
20797
|
-
if (!
|
|
20998
|
+
if (!fs81.existsSync(filePath)) {
|
|
20798
20999
|
return result;
|
|
20799
21000
|
}
|
|
20800
21001
|
let parsed;
|
|
20801
21002
|
try {
|
|
20802
|
-
parsed = JSON.parse(
|
|
21003
|
+
parsed = JSON.parse(fs81.readFileSync(filePath, "utf-8"));
|
|
20803
21004
|
} catch {
|
|
20804
21005
|
return result;
|
|
20805
21006
|
}
|
|
@@ -20840,7 +21041,7 @@ function checkSentinelDrift() {
|
|
|
20840
21041
|
backupSettings();
|
|
20841
21042
|
} catch {
|
|
20842
21043
|
}
|
|
20843
|
-
const next = JSON.parse(
|
|
21044
|
+
const next = JSON.parse(fs81.readFileSync(filePath, "utf-8"));
|
|
20844
21045
|
if (!next.hooks)
|
|
20845
21046
|
return;
|
|
20846
21047
|
for (const stage of Object.keys(next.hooks)) {
|
|
@@ -20863,7 +21064,7 @@ function checkSentinelDrift() {
|
|
|
20863
21064
|
return bad === void 0;
|
|
20864
21065
|
});
|
|
20865
21066
|
}
|
|
20866
|
-
|
|
21067
|
+
fs81.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
20867
21068
|
};
|
|
20868
21069
|
}
|
|
20869
21070
|
return result;
|
|
@@ -20888,7 +21089,7 @@ function checkMemberNameMissing() {
|
|
|
20888
21089
|
}
|
|
20889
21090
|
const claudeDir2 = claudeDirInternal3();
|
|
20890
21091
|
const atlasUserPath = path79.join(claudeDir2, ".atlas-user");
|
|
20891
|
-
const value =
|
|
21092
|
+
const value = fs81.existsSync(atlasUserPath) ? fs81.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
20892
21093
|
if (value.length > 0) {
|
|
20893
21094
|
result.details = [`atlas-user: ${value}`];
|
|
20894
21095
|
return result;
|
|
@@ -20897,9 +21098,9 @@ function checkMemberNameMissing() {
|
|
|
20897
21098
|
result.issue = "atlas-toolbox source registered but ~/.claude/.atlas-user not set";
|
|
20898
21099
|
const clonePath = skillSourceClonePath(atlasSource.id);
|
|
20899
21100
|
const membersDir = path79.join(clonePath, "members");
|
|
20900
|
-
const existing =
|
|
21101
|
+
const existing = fs81.existsSync(membersDir) ? fs81.readdirSync(membersDir).filter((e) => {
|
|
20901
21102
|
try {
|
|
20902
|
-
return
|
|
21103
|
+
return fs81.statSync(path79.join(membersDir, e)).isDirectory();
|
|
20903
21104
|
} catch {
|
|
20904
21105
|
return false;
|
|
20905
21106
|
}
|
|
@@ -20914,7 +21115,7 @@ function checkMemberNameMissing() {
|
|
|
20914
21115
|
function checkMemberOverlayDrift() {
|
|
20915
21116
|
const claudeDir2 = claudeDirInternal3();
|
|
20916
21117
|
const atlasUserPath = path79.join(claudeDir2, ".atlas-user");
|
|
20917
|
-
const atlasUser =
|
|
21118
|
+
const atlasUser = fs81.existsSync(atlasUserPath) ? fs81.readFileSync(atlasUserPath, "utf-8").trim() : "";
|
|
20918
21119
|
if (atlasUser.length === 0) {
|
|
20919
21120
|
return [];
|
|
20920
21121
|
}
|
|
@@ -20931,11 +21132,11 @@ function checkMemberOverlayDrift() {
|
|
|
20931
21132
|
const results = [];
|
|
20932
21133
|
for (const kind of ["skills", "agents"]) {
|
|
20933
21134
|
const localRoot = path79.join(claudeDir2, `${kind}.overrides`);
|
|
20934
|
-
if (!
|
|
21135
|
+
if (!fs81.existsSync(localRoot))
|
|
20935
21136
|
continue;
|
|
20936
21137
|
let entries;
|
|
20937
21138
|
try {
|
|
20938
|
-
entries =
|
|
21139
|
+
entries = fs81.readdirSync(localRoot);
|
|
20939
21140
|
} catch {
|
|
20940
21141
|
continue;
|
|
20941
21142
|
}
|
|
@@ -20943,7 +21144,7 @@ function checkMemberOverlayDrift() {
|
|
|
20943
21144
|
const localFile = path79.join(localRoot, entry);
|
|
20944
21145
|
let stat;
|
|
20945
21146
|
try {
|
|
20946
|
-
stat =
|
|
21147
|
+
stat = fs81.statSync(localFile);
|
|
20947
21148
|
} catch {
|
|
20948
21149
|
continue;
|
|
20949
21150
|
}
|
|
@@ -21119,7 +21320,7 @@ __export(project_sweep_exports, {
|
|
|
21119
21320
|
walkProjectRoot: () => walkProjectRoot
|
|
21120
21321
|
});
|
|
21121
21322
|
import * as path80 from "node:path";
|
|
21122
|
-
import { readdirSync as readdirSync26, lstatSync as lstatSync6, statSync as statSync26, existsSync as
|
|
21323
|
+
import { readdirSync as readdirSync26, lstatSync as lstatSync6, statSync as statSync26, existsSync as existsSync89 } from "node:fs";
|
|
21123
21324
|
function isSkipped(basename17, extra) {
|
|
21124
21325
|
if (DEFAULT_SKIP.has(basename17))
|
|
21125
21326
|
return true;
|
|
@@ -21198,7 +21399,7 @@ function makeRealFsAdapter() {
|
|
|
21198
21399
|
const s = statSync26(p, { throwIfNoEntry: true });
|
|
21199
21400
|
return { isDirectory: () => s.isDirectory(), mtimeMs: s.mtimeMs };
|
|
21200
21401
|
},
|
|
21201
|
-
existsSync: (p) =>
|
|
21402
|
+
existsSync: (p) => existsSync89(p)
|
|
21202
21403
|
};
|
|
21203
21404
|
}
|
|
21204
21405
|
function walkProjectRoot(rootPath, opts = {}) {
|
|
@@ -21224,7 +21425,7 @@ __export(kg_eager_exports, {
|
|
|
21224
21425
|
runEagerKgBuild: () => runEagerKgBuild,
|
|
21225
21426
|
writeQueue: () => writeQueue
|
|
21226
21427
|
});
|
|
21227
|
-
import * as
|
|
21428
|
+
import * as fs82 from "node:fs";
|
|
21228
21429
|
import * as path81 from "node:path";
|
|
21229
21430
|
import * as os46 from "node:os";
|
|
21230
21431
|
function defaultQueuePath() {
|
|
@@ -21232,9 +21433,9 @@ function defaultQueuePath() {
|
|
|
21232
21433
|
return path81.join(stateDir, "kg-pending.jsonl");
|
|
21233
21434
|
}
|
|
21234
21435
|
function readQueue(queuePath) {
|
|
21235
|
-
if (!
|
|
21436
|
+
if (!fs82.existsSync(queuePath))
|
|
21236
21437
|
return [];
|
|
21237
|
-
const raw =
|
|
21438
|
+
const raw = fs82.readFileSync(queuePath, "utf-8");
|
|
21238
21439
|
const entries = [];
|
|
21239
21440
|
for (const line of raw.split("\n")) {
|
|
21240
21441
|
const trimmed = line.trim();
|
|
@@ -21248,16 +21449,16 @@ function readQueue(queuePath) {
|
|
|
21248
21449
|
return entries;
|
|
21249
21450
|
}
|
|
21250
21451
|
function writeQueue(queuePath, entries) {
|
|
21251
|
-
|
|
21452
|
+
fs82.mkdirSync(path81.dirname(queuePath), { recursive: true });
|
|
21252
21453
|
const content = entries.map((e) => JSON.stringify(e)).join("\n") + (entries.length > 0 ? "\n" : "");
|
|
21253
|
-
|
|
21454
|
+
fs82.writeFileSync(queuePath, content, "utf-8");
|
|
21254
21455
|
}
|
|
21255
21456
|
function appendQueue(queuePath, repos, nowMs) {
|
|
21256
21457
|
if (repos.length === 0)
|
|
21257
21458
|
return;
|
|
21258
|
-
|
|
21459
|
+
fs82.mkdirSync(path81.dirname(queuePath), { recursive: true });
|
|
21259
21460
|
const lines = repos.map((r) => JSON.stringify({ path: r.path, addedAt: nowMs })).join("\n") + "\n";
|
|
21260
|
-
|
|
21461
|
+
fs82.appendFileSync(queuePath, lines, "utf-8");
|
|
21261
21462
|
}
|
|
21262
21463
|
async function defaultBuildOne(_repo) {
|
|
21263
21464
|
return { ok: true, ms: 0 };
|
|
@@ -21397,27 +21598,27 @@ var init_install_shared = __esm({
|
|
|
21397
21598
|
});
|
|
21398
21599
|
|
|
21399
21600
|
// src/commands/memory/_paths.ts
|
|
21400
|
-
import { homedir as
|
|
21401
|
-
import { join as
|
|
21402
|
-
import { fileURLToPath as
|
|
21601
|
+
import { homedir as homedir53 } from "node:os";
|
|
21602
|
+
import { join as join93, dirname as dirname50 } from "node:path";
|
|
21603
|
+
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
21403
21604
|
var OLAM_HOME5, MEMORY_PID_PATH, MEMORY_LOG_PATH, MEMORY_DATA_DIR, MEMORY_REST_PORT, MEMORY_LIVEZ_URL, here, candidates, MEMORY_SERVICE_CANDIDATES;
|
|
21404
21605
|
var init_paths2 = __esm({
|
|
21405
21606
|
"src/commands/memory/_paths.ts"() {
|
|
21406
21607
|
"use strict";
|
|
21407
|
-
OLAM_HOME5 =
|
|
21408
|
-
MEMORY_PID_PATH =
|
|
21409
|
-
MEMORY_LOG_PATH =
|
|
21410
|
-
MEMORY_DATA_DIR =
|
|
21608
|
+
OLAM_HOME5 = join93(homedir53(), ".olam");
|
|
21609
|
+
MEMORY_PID_PATH = join93(OLAM_HOME5, "memory.pid");
|
|
21610
|
+
MEMORY_LOG_PATH = join93(OLAM_HOME5, "memory-service.log");
|
|
21611
|
+
MEMORY_DATA_DIR = join93(OLAM_HOME5, "memory-data");
|
|
21411
21612
|
MEMORY_REST_PORT = 3111;
|
|
21412
21613
|
MEMORY_LIVEZ_URL = `http://localhost:${MEMORY_REST_PORT}/agentmemory/livez`;
|
|
21413
|
-
here =
|
|
21614
|
+
here = dirname50(fileURLToPath9(import.meta.url));
|
|
21414
21615
|
candidates = [
|
|
21415
21616
|
// 1. Workspace dev (built): packages/cli/dist/commands/memory/_paths.js → packages/cli → packages/memory-service
|
|
21416
|
-
|
|
21617
|
+
join93(here, "..", "..", "..", "..", "memory-service"),
|
|
21417
21618
|
// 2. Workspace bundled: packages/cli/dist/index.js → packages/cli → packages/memory-service
|
|
21418
|
-
|
|
21619
|
+
join93(here, "..", "..", "memory-service"),
|
|
21419
21620
|
// 3. CWD fallback
|
|
21420
|
-
|
|
21621
|
+
join93(process.cwd(), "packages", "memory-service")
|
|
21421
21622
|
];
|
|
21422
21623
|
MEMORY_SERVICE_CANDIDATES = candidates;
|
|
21423
21624
|
}
|
|
@@ -21526,16 +21727,16 @@ __export(machine_schema_exports, {
|
|
|
21526
21727
|
readMachineConfig: () => readMachineConfig,
|
|
21527
21728
|
writeMachineConfig: () => writeMachineConfig
|
|
21528
21729
|
});
|
|
21529
|
-
import * as
|
|
21730
|
+
import * as fs86 from "node:fs";
|
|
21530
21731
|
import * as path86 from "node:path";
|
|
21531
21732
|
import * as os48 from "node:os";
|
|
21532
21733
|
import { parse as parseYaml8, stringify as stringifyYaml6 } from "yaml";
|
|
21533
21734
|
function readMachineConfig(configPath) {
|
|
21534
21735
|
const p = configPath ?? DEFAULT_CONFIG_PATH;
|
|
21535
|
-
if (!
|
|
21736
|
+
if (!fs86.existsSync(p))
|
|
21536
21737
|
return null;
|
|
21537
21738
|
try {
|
|
21538
|
-
const raw =
|
|
21739
|
+
const raw = fs86.readFileSync(p, "utf-8");
|
|
21539
21740
|
const parsed = parseYaml8(raw);
|
|
21540
21741
|
return MachineConfigSchema.parse(parsed);
|
|
21541
21742
|
} catch {
|
|
@@ -21544,8 +21745,8 @@ function readMachineConfig(configPath) {
|
|
|
21544
21745
|
}
|
|
21545
21746
|
function writeMachineConfig(config, configPath) {
|
|
21546
21747
|
const p = configPath ?? DEFAULT_CONFIG_PATH;
|
|
21547
|
-
|
|
21548
|
-
|
|
21748
|
+
fs86.mkdirSync(path86.dirname(p), { recursive: true });
|
|
21749
|
+
fs86.writeFileSync(p, stringifyYaml6({ ...config }), { mode: 420 });
|
|
21549
21750
|
}
|
|
21550
21751
|
function initMachineConfig(opts = {}) {
|
|
21551
21752
|
const configPath = opts.configPath ?? DEFAULT_CONFIG_PATH;
|
|
@@ -21671,7 +21872,7 @@ function registerWorkspace(program2) {
|
|
|
21671
21872
|
process.exitCode = 1;
|
|
21672
21873
|
}
|
|
21673
21874
|
});
|
|
21674
|
-
workspace.command("remove").description("Delete a workspace (does NOT touch worlds that already referenced it)").argument("<name>", "Workspace name").
|
|
21875
|
+
workspace.command("remove").description("Delete a workspace (does NOT touch worlds that already referenced it)").argument("<name>", "Workspace name").action((name) => {
|
|
21675
21876
|
try {
|
|
21676
21877
|
if (removeWorkspace(name)) {
|
|
21677
21878
|
printSuccess(`Removed workspace "${name}"`);
|
|
@@ -22040,7 +22241,7 @@ function runGlobalInit(opts) {
|
|
|
22040
22241
|
}
|
|
22041
22242
|
}
|
|
22042
22243
|
function registerInit(program2) {
|
|
22043
|
-
program2.command("init").description("Initialize olam in the current project or globally").option("--path <path>", "Project root path", process.cwd()).option("--skip-pleri", "
|
|
22244
|
+
program2.command("init").description("Initialize olam in the current project or globally").option("--path <path>", "Project root path", process.cwd()).option("--skip-pleri", "No-op (deprecated \u2014 PLERI is always optional; accepted for backward compat but has no effect)").option("--global", "Write only ~/.olam/config.json (global scope); skip per-repo .olam/config.yaml").option("--project", "Write .olam/config.yaml in the nearest git repo (per-repo scope; default when --global is absent)").option("--yes / -y", "Auto-affirm prompts (non-interactive)").action(async (opts) => {
|
|
22044
22245
|
if (opts.global) {
|
|
22045
22246
|
try {
|
|
22046
22247
|
const result = runGlobalInit({});
|
|
@@ -22594,7 +22795,7 @@ async function kubectlWrap(args, opts = {}) {
|
|
|
22594
22795
|
const spawnImpl = opts.spawnImpl ?? spawn4;
|
|
22595
22796
|
const stdout = [];
|
|
22596
22797
|
const stderr = [];
|
|
22597
|
-
return new Promise((
|
|
22798
|
+
return new Promise((resolve31) => {
|
|
22598
22799
|
let resolved = false;
|
|
22599
22800
|
let killTimer = null;
|
|
22600
22801
|
let sigkillTimer = null;
|
|
@@ -22609,7 +22810,7 @@ async function kubectlWrap(args, opts = {}) {
|
|
|
22609
22810
|
clearTimeout(sigkillTimer);
|
|
22610
22811
|
sigkillTimer = null;
|
|
22611
22812
|
}
|
|
22612
|
-
|
|
22813
|
+
resolve31(r);
|
|
22613
22814
|
}
|
|
22614
22815
|
let child;
|
|
22615
22816
|
try {
|
|
@@ -22618,7 +22819,7 @@ async function kubectlWrap(args, opts = {}) {
|
|
|
22618
22819
|
env: { ...process.env, ...opts.env ?? {} }
|
|
22619
22820
|
});
|
|
22620
22821
|
} catch (err) {
|
|
22621
|
-
|
|
22822
|
+
resolve31({
|
|
22622
22823
|
ok: false,
|
|
22623
22824
|
stdout: "",
|
|
22624
22825
|
stderr: err instanceof Error ? err.message : String(err),
|
|
@@ -23134,7 +23335,7 @@ function runLiveTask(label, cmd, args, opts) {
|
|
|
23134
23335
|
const startMs = Date.now();
|
|
23135
23336
|
const settle = opts.settle ?? "auto";
|
|
23136
23337
|
const useSpinner = !opts.verbose && Boolean(process.stdout.isTTY);
|
|
23137
|
-
return new Promise((
|
|
23338
|
+
return new Promise((resolve31) => {
|
|
23138
23339
|
const child = spawn5(cmd, [...args], {
|
|
23139
23340
|
env: opts.env ?? process.env,
|
|
23140
23341
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -23198,7 +23399,7 @@ function runLiveTask(label, cmd, args, opts) {
|
|
|
23198
23399
|
);
|
|
23199
23400
|
}
|
|
23200
23401
|
}
|
|
23201
|
-
|
|
23402
|
+
resolve31({ ok, exitCode: code, durationMs, logPath });
|
|
23202
23403
|
};
|
|
23203
23404
|
child.on("error", (err) => {
|
|
23204
23405
|
chunks.push(`
|
|
@@ -23263,10 +23464,17 @@ function preflight(opts) {
|
|
|
23263
23464
|
}
|
|
23264
23465
|
printSuccess("gh authenticated");
|
|
23265
23466
|
if (!runCapture("docker", ["info"]).ok) {
|
|
23266
|
-
|
|
23267
|
-
|
|
23467
|
+
if (platform() === "darwin") {
|
|
23468
|
+
printWarning(
|
|
23469
|
+
"docker daemon not reachable yet \u2014 starting the container runtime next"
|
|
23470
|
+
);
|
|
23471
|
+
} else {
|
|
23472
|
+
printError("docker daemon unreachable \u2014 start Docker Desktop or colima");
|
|
23473
|
+
process.exit(1);
|
|
23474
|
+
}
|
|
23475
|
+
} else {
|
|
23476
|
+
printSuccess("docker daemon reachable");
|
|
23268
23477
|
}
|
|
23269
|
-
printSuccess("docker daemon reachable");
|
|
23270
23478
|
}
|
|
23271
23479
|
function ensureSecrets() {
|
|
23272
23480
|
step("1/7 \u2014 operator secrets");
|
|
@@ -23285,6 +23493,60 @@ function ensureSecrets() {
|
|
|
23285
23493
|
printSuccess(`generated ~/.olam/secrets/${name}`);
|
|
23286
23494
|
}
|
|
23287
23495
|
}
|
|
23496
|
+
function resolveMacRuntime(preferred, dockerDesktopInstalled) {
|
|
23497
|
+
if (preferred) return preferred;
|
|
23498
|
+
return dockerDesktopInstalled ? "docker-desktop" : "colima";
|
|
23499
|
+
}
|
|
23500
|
+
function isDockerDesktopInstalled() {
|
|
23501
|
+
return existsSync31("/Applications/Docker.app");
|
|
23502
|
+
}
|
|
23503
|
+
function dockerDaemonReachable() {
|
|
23504
|
+
return runCapture("docker", ["info"]).ok;
|
|
23505
|
+
}
|
|
23506
|
+
function ensureContainerRuntime(opts) {
|
|
23507
|
+
if (platform() !== "darwin") return;
|
|
23508
|
+
const runtime = resolveMacRuntime(opts.preferredRuntime, isDockerDesktopInstalled());
|
|
23509
|
+
if (runtime === "external-k8s") {
|
|
23510
|
+
step("2/7 \u2014 container runtime (external-k8s)");
|
|
23511
|
+
printInfo(
|
|
23512
|
+
"runtime",
|
|
23513
|
+
"preferred_runtime=external-k8s \u2014 not managing Docker Desktop/Colima"
|
|
23514
|
+
);
|
|
23515
|
+
return;
|
|
23516
|
+
}
|
|
23517
|
+
if (runtime === "docker-desktop") {
|
|
23518
|
+
ensureDockerDesktop();
|
|
23519
|
+
return;
|
|
23520
|
+
}
|
|
23521
|
+
ensureColima();
|
|
23522
|
+
}
|
|
23523
|
+
function ensureDockerDesktop() {
|
|
23524
|
+
step("2/7 \u2014 Docker Desktop (macOS)");
|
|
23525
|
+
if (runCapture("docker", ["context", "use", "desktop-linux"]).ok) {
|
|
23526
|
+
printSuccess("docker context \u2192 desktop-linux");
|
|
23527
|
+
} else {
|
|
23528
|
+
printWarning(
|
|
23529
|
+
"could not select the 'desktop-linux' docker context \u2014 using the current context"
|
|
23530
|
+
);
|
|
23531
|
+
}
|
|
23532
|
+
if (dockerDaemonReachable()) {
|
|
23533
|
+
printSuccess("Docker Desktop daemon reachable");
|
|
23534
|
+
return;
|
|
23535
|
+
}
|
|
23536
|
+
printWarning("Docker Desktop not running \u2014 starting (open -a Docker)");
|
|
23537
|
+
runCapture("open", ["-a", "Docker"]);
|
|
23538
|
+
for (let waited = 0; waited < 90; waited += 3) {
|
|
23539
|
+
spawnSync10("sleep", ["3"]);
|
|
23540
|
+
if (dockerDaemonReachable()) {
|
|
23541
|
+
printSuccess(`Docker Desktop daemon reachable (after ~${waited + 3}s)`);
|
|
23542
|
+
return;
|
|
23543
|
+
}
|
|
23544
|
+
}
|
|
23545
|
+
printError(
|
|
23546
|
+
"Docker Desktop did not become ready within 90s \u2014 start it manually and re-run `olam bootstrap`"
|
|
23547
|
+
);
|
|
23548
|
+
process.exit(1);
|
|
23549
|
+
}
|
|
23288
23550
|
function ensureColima() {
|
|
23289
23551
|
if (platform() !== "darwin") return;
|
|
23290
23552
|
step("2/7 \u2014 colima (macOS)");
|
|
@@ -23868,7 +24130,8 @@ async function runBootstrapKubernetes(rawOpts) {
|
|
|
23868
24130
|
skipPrepull: rawOpts.skipPrepull ?? false,
|
|
23869
24131
|
verbose,
|
|
23870
24132
|
verboseObservability: rawOpts.verboseObservability ?? false,
|
|
23871
|
-
hostCpDevPath: rawOpts.hostCpDevPath
|
|
24133
|
+
hostCpDevPath: rawOpts.hostCpDevPath,
|
|
24134
|
+
preferredRuntime: rawOpts.preferredRuntime
|
|
23872
24135
|
};
|
|
23873
24136
|
printHeader("olam setup \u2014 k3s mode");
|
|
23874
24137
|
printInfo(
|
|
@@ -23877,7 +24140,7 @@ async function runBootstrapKubernetes(rawOpts) {
|
|
|
23877
24140
|
);
|
|
23878
24141
|
preflight(opts);
|
|
23879
24142
|
ensureSecrets();
|
|
23880
|
-
|
|
24143
|
+
ensureContainerRuntime(opts);
|
|
23881
24144
|
ensureCluster(opts);
|
|
23882
24145
|
await installObservability(opts);
|
|
23883
24146
|
applyPeripheralServicesManifests();
|
|
@@ -23939,7 +24202,11 @@ async function runBootstrap2(opts, deps = {}) {
|
|
|
23939
24202
|
skipClusterCreate: opts.skipClusterCreate ?? false,
|
|
23940
24203
|
skipPrepull: opts.skipPrepull ?? false,
|
|
23941
24204
|
verbose: opts.verbose ?? false,
|
|
23942
|
-
hostCpDevPath: opts.hostCpDevPath
|
|
24205
|
+
hostCpDevPath: opts.hostCpDevPath,
|
|
24206
|
+
// Honour the operator's Phase 0 substrate-picker choice. When unset,
|
|
24207
|
+
// bootstrap-kubernetes auto-detects (prefers an installed Docker
|
|
24208
|
+
// Desktop over imposing Colima).
|
|
24209
|
+
preferredRuntime: cfg.host.preferred_runtime
|
|
23943
24210
|
});
|
|
23944
24211
|
return { exitCode: k8s.exitCode, summary: k8s.summary };
|
|
23945
24212
|
}
|
|
@@ -24322,10 +24589,10 @@ async function confirm(message) {
|
|
|
24322
24589
|
if (!process.stdin.isTTY) return true;
|
|
24323
24590
|
const { createInterface: createInterface12 } = await import("node:readline");
|
|
24324
24591
|
const rl = createInterface12({ input: process.stdin, output: process.stdout });
|
|
24325
|
-
return new Promise((
|
|
24592
|
+
return new Promise((resolve31) => {
|
|
24326
24593
|
rl.question(`${message} [y/N] `, (answer) => {
|
|
24327
24594
|
rl.close();
|
|
24328
|
-
|
|
24595
|
+
resolve31(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
24329
24596
|
});
|
|
24330
24597
|
});
|
|
24331
24598
|
}
|
|
@@ -24797,7 +25064,7 @@ var KgServiceContainerController = class {
|
|
|
24797
25064
|
}
|
|
24798
25065
|
};
|
|
24799
25066
|
function sleep4(ms) {
|
|
24800
|
-
return new Promise((
|
|
25067
|
+
return new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
24801
25068
|
}
|
|
24802
25069
|
|
|
24803
25070
|
// src/commands/memory-service-container.ts
|
|
@@ -25020,7 +25287,7 @@ var MemoryServiceContainerController = class {
|
|
|
25020
25287
|
}
|
|
25021
25288
|
};
|
|
25022
25289
|
function sleep5(ms) {
|
|
25023
|
-
return new Promise((
|
|
25290
|
+
return new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
25024
25291
|
}
|
|
25025
25292
|
|
|
25026
25293
|
// src/lib/peripheral-registry.ts
|
|
@@ -25615,7 +25882,7 @@ var McpAuthContainerController = class {
|
|
|
25615
25882
|
}
|
|
25616
25883
|
};
|
|
25617
25884
|
function sleep6(ms) {
|
|
25618
|
-
return new Promise((
|
|
25885
|
+
return new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
25619
25886
|
}
|
|
25620
25887
|
var K8S_NAMESPACE2 = "olam";
|
|
25621
25888
|
function assertK8sContext(configPath) {
|
|
@@ -26058,39 +26325,32 @@ async function servicesUp(deps = {}) {
|
|
|
26058
26325
|
printInfo("olam-memory-service", `:${MEMORY_SERVICE_PORT}`);
|
|
26059
26326
|
return { exitCode: 0 };
|
|
26060
26327
|
}
|
|
26061
|
-
function servicesDown() {
|
|
26062
|
-
const
|
|
26063
|
-
const
|
|
26064
|
-
|
|
26065
|
-
|
|
26066
|
-
|
|
26067
|
-
|
|
26068
|
-
|
|
26069
|
-
|
|
26070
|
-
|
|
26071
|
-
|
|
26072
|
-
|
|
26073
|
-
|
|
26074
|
-
|
|
26075
|
-
|
|
26076
|
-
printSuccess("olam-mcp-auth stopped.");
|
|
26077
|
-
} catch (err) {
|
|
26078
|
-
printError(`olam-mcp-auth: ${err instanceof Error ? err.message : String(err)}`);
|
|
26079
|
-
exitCode = 1;
|
|
26080
|
-
}
|
|
26081
|
-
try {
|
|
26082
|
-
kgService.stop();
|
|
26083
|
-
printSuccess("olam-kg-service stopped.");
|
|
26084
|
-
} catch (err) {
|
|
26085
|
-
printError(`olam-kg-service: ${err instanceof Error ? err.message : String(err)}`);
|
|
26086
|
-
exitCode = 1;
|
|
26328
|
+
function servicesDown(opts = {}) {
|
|
26329
|
+
const { include } = opts;
|
|
26330
|
+
const services = [
|
|
26331
|
+
{ name: "olam-auth", stop: () => new AuthContainerController().stop() },
|
|
26332
|
+
{ name: "olam-mcp-auth", stop: () => new McpAuthContainerController().stop() },
|
|
26333
|
+
{ name: "olam-kg-service", stop: () => new KgServiceContainerController().stop() },
|
|
26334
|
+
{ name: "olam-memory-service", stop: () => new MemoryServiceContainerController().stop() }
|
|
26335
|
+
];
|
|
26336
|
+
const known = new Set(services.map((s) => s.name));
|
|
26337
|
+
if (include && include.length > 0) {
|
|
26338
|
+
for (const name of include) {
|
|
26339
|
+
if (!known.has(name)) {
|
|
26340
|
+
printError(`--include: unknown service '${name}'; known: ${[...known].join(", ")}`);
|
|
26341
|
+
}
|
|
26342
|
+
}
|
|
26087
26343
|
}
|
|
26088
|
-
|
|
26089
|
-
|
|
26090
|
-
|
|
26091
|
-
|
|
26092
|
-
|
|
26093
|
-
|
|
26344
|
+
let exitCode = 0;
|
|
26345
|
+
for (const svc of services) {
|
|
26346
|
+
if (include && include.length > 0 && !include.includes(svc.name)) continue;
|
|
26347
|
+
try {
|
|
26348
|
+
svc.stop();
|
|
26349
|
+
printSuccess(`${svc.name} stopped.`);
|
|
26350
|
+
} catch (err) {
|
|
26351
|
+
printError(`${svc.name}: ${err instanceof Error ? err.message : String(err)}`);
|
|
26352
|
+
exitCode = 1;
|
|
26353
|
+
}
|
|
26094
26354
|
}
|
|
26095
26355
|
return { exitCode };
|
|
26096
26356
|
}
|
|
@@ -26148,13 +26408,23 @@ function registerServices(program2) {
|
|
|
26148
26408
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
26149
26409
|
}
|
|
26150
26410
|
});
|
|
26151
|
-
services.command("down").description("Stop all service containers").
|
|
26411
|
+
services.command("down").description("Stop all service containers").option(
|
|
26412
|
+
"--include <name>",
|
|
26413
|
+
"Stop only the named service container (repeatable). Known names: olam-auth, olam-mcp-auth, olam-kg-service, olam-memory-service. When omitted, all containers are stopped.",
|
|
26414
|
+
(val, acc) => [...acc, val],
|
|
26415
|
+
[]
|
|
26416
|
+
).action(async (opts) => {
|
|
26152
26417
|
const cfg = readConfig();
|
|
26153
26418
|
if (cfg.host.substrate === "kubernetes") {
|
|
26419
|
+
if (opts.include.length > 0) {
|
|
26420
|
+
process.stderr.write(
|
|
26421
|
+
"[services down] --include is not supported on kubernetes substrate; stopping all services\n"
|
|
26422
|
+
);
|
|
26423
|
+
}
|
|
26154
26424
|
const result = await servicesDownKubernetes();
|
|
26155
26425
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
26156
26426
|
} else {
|
|
26157
|
-
const result = servicesDown();
|
|
26427
|
+
const result = servicesDown({ include: opts.include });
|
|
26158
26428
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
26159
26429
|
}
|
|
26160
26430
|
});
|
|
@@ -26218,14 +26488,14 @@ async function probePortForwardLiveness(deps = {}) {
|
|
|
26218
26488
|
return probe2("127.0.0.1", PORT_FORWARD_PORT, TCP_PROBE_TIMEOUT_MS);
|
|
26219
26489
|
}
|
|
26220
26490
|
function realTcpProbe(host, port2, timeoutMs) {
|
|
26221
|
-
return new Promise((
|
|
26491
|
+
return new Promise((resolve31) => {
|
|
26222
26492
|
const socket = new net3.Socket();
|
|
26223
26493
|
let done = false;
|
|
26224
26494
|
function finish(result) {
|
|
26225
26495
|
if (done) return;
|
|
26226
26496
|
done = true;
|
|
26227
26497
|
socket.destroy();
|
|
26228
|
-
|
|
26498
|
+
resolve31(result);
|
|
26229
26499
|
}
|
|
26230
26500
|
const timer = setTimeout(() => finish(false), timeoutMs);
|
|
26231
26501
|
socket.once("connect", () => {
|
|
@@ -26563,12 +26833,12 @@ function appendAuditEntry(entry, auditLogPath, writeFileSyncImpl) {
|
|
|
26563
26833
|
async function runManifestRefresh(manifestsDir, acceptRegression, deps = {}, peripheral) {
|
|
26564
26834
|
const auditLogPath = deps.auditLogPath ?? MANIFEST_REFRESH_AUDIT_LOG;
|
|
26565
26835
|
const readdirSync34 = deps.readdirSync ?? fs35.readdirSync;
|
|
26566
|
-
const
|
|
26836
|
+
const readFileSync110 = deps.readFileSync ?? fs35.readFileSync;
|
|
26567
26837
|
const writeFileSyncImpl = deps.writeFileSync ?? fs35.writeFileSync;
|
|
26568
|
-
const
|
|
26838
|
+
const existsSync122 = deps.existsSync ?? fs35.existsSync;
|
|
26569
26839
|
const now = deps.now ? deps.now() : /* @__PURE__ */ new Date();
|
|
26570
26840
|
const targetDir = peripheral ? path36.join(manifestsDir, peripheral) : manifestsDir;
|
|
26571
|
-
if (!
|
|
26841
|
+
if (!existsSync122(targetDir)) {
|
|
26572
26842
|
return {
|
|
26573
26843
|
ok: false,
|
|
26574
26844
|
message: peripheral ? `peripheral manifests directory not found: ${targetDir}` : `manifests directory not found: ${targetDir}`
|
|
@@ -26589,7 +26859,7 @@ async function runManifestRefresh(manifestsDir, acceptRegression, deps = {}, per
|
|
|
26589
26859
|
const filePath = path36.join(targetDir, file);
|
|
26590
26860
|
let content;
|
|
26591
26861
|
try {
|
|
26592
|
-
content =
|
|
26862
|
+
content = readFileSync110(filePath, "utf8");
|
|
26593
26863
|
} catch {
|
|
26594
26864
|
continue;
|
|
26595
26865
|
}
|
|
@@ -26845,11 +27115,11 @@ async function checkSecretPreCondition(context, deps) {
|
|
|
26845
27115
|
}
|
|
26846
27116
|
async function applyConfigMapSubstitution(context, manifestsDir, deps) {
|
|
26847
27117
|
const wrap = deps.kubectlWrapImpl ?? kubectlWrap;
|
|
26848
|
-
const
|
|
27118
|
+
const readFileSync110 = deps.readFileSyncImpl ?? fs36.readFileSync;
|
|
26849
27119
|
const configMapPath = path37.join(manifestsDir, "30-configmap.yaml");
|
|
26850
27120
|
let rawYaml;
|
|
26851
27121
|
try {
|
|
26852
|
-
rawYaml =
|
|
27122
|
+
rawYaml = readFileSync110(configMapPath, "utf8");
|
|
26853
27123
|
} catch (err) {
|
|
26854
27124
|
return `Failed to read ConfigMap at ${configMapPath}: ${err instanceof Error ? err.message : String(err)}`;
|
|
26855
27125
|
}
|
|
@@ -28124,10 +28394,10 @@ function emptyMigrationState() {
|
|
|
28124
28394
|
return { version: 1, migrated: {} };
|
|
28125
28395
|
}
|
|
28126
28396
|
function readMigrationState(statePath, deps) {
|
|
28127
|
-
const
|
|
28128
|
-
const
|
|
28129
|
-
if (!
|
|
28130
|
-
const raw =
|
|
28397
|
+
const existsSync122 = deps.existsSync ?? fs40.existsSync;
|
|
28398
|
+
const readFileSync110 = deps.readFileSync ?? ((p) => fs40.readFileSync(p, "utf-8"));
|
|
28399
|
+
if (!existsSync122(statePath)) return emptyMigrationState();
|
|
28400
|
+
const raw = readFileSync110(statePath);
|
|
28131
28401
|
let parsed;
|
|
28132
28402
|
try {
|
|
28133
28403
|
parsed = JSON.parse(raw);
|
|
@@ -28144,17 +28414,17 @@ function readMigrationState(statePath, deps) {
|
|
|
28144
28414
|
return parsed;
|
|
28145
28415
|
}
|
|
28146
28416
|
function writeMigrationStateAtomic(statePath, state, deps) {
|
|
28147
|
-
const
|
|
28417
|
+
const writeFileSync67 = deps.writeFileSync ?? ((p, d) => fs40.writeFileSync(p, d, "utf-8"));
|
|
28148
28418
|
const renameSync21 = deps.renameSync ?? fs40.renameSync;
|
|
28149
28419
|
const tmpPath = `${statePath}.tmp`;
|
|
28150
|
-
|
|
28420
|
+
writeFileSync67(tmpPath, JSON.stringify(state, null, 2) + "\n");
|
|
28151
28421
|
renameSync21(tmpPath, statePath);
|
|
28152
28422
|
}
|
|
28153
28423
|
function readLocalAccounts(accountsPath, deps) {
|
|
28154
|
-
const
|
|
28155
|
-
const
|
|
28156
|
-
if (!
|
|
28157
|
-
const raw =
|
|
28424
|
+
const existsSync122 = deps.existsSync ?? fs40.existsSync;
|
|
28425
|
+
const readFileSync110 = deps.readFileSync ?? ((p) => fs40.readFileSync(p, "utf-8"));
|
|
28426
|
+
if (!existsSync122(accountsPath)) return null;
|
|
28427
|
+
const raw = readFileSync110(accountsPath);
|
|
28158
28428
|
let parsed;
|
|
28159
28429
|
try {
|
|
28160
28430
|
parsed = JSON.parse(raw);
|
|
@@ -29039,18 +29309,31 @@ ${pc13.dim("Tip: set ANTHROPIC_BASE_URL=" + baseUrl.replace(/\/+$/, "") + "/v1/p
|
|
|
29039
29309
|
auth.command("revoke-anthropic-token").description("Revoke an Anthropic proxy token on the remote auth-worker (g4)").requiredOption("--remote <url>", "Auth-worker base URL").requiredOption("--token-hash <hash>", "Token hash to revoke (from issue or list output)").action(async (opts) => {
|
|
29040
29310
|
const baseUrl = opts.remote;
|
|
29041
29311
|
printHeader("Auth worker \u2014 revoke Anthropic proxy token");
|
|
29042
|
-
|
|
29312
|
+
const serviceToken = resolveCfAccessServiceToken();
|
|
29313
|
+
let remoteOpts;
|
|
29314
|
+
if (serviceToken) {
|
|
29315
|
+
console.log(`
|
|
29316
|
+
${pc13.dim("Using CF Access service token (machine-to-machine; no cookie needed).")}`);
|
|
29317
|
+
remoteOpts = {
|
|
29318
|
+
baseUrl,
|
|
29319
|
+
cfAccessClientId: serviceToken.clientId,
|
|
29320
|
+
cfAccessClientSecret: serviceToken.clientSecret
|
|
29321
|
+
};
|
|
29322
|
+
} else {
|
|
29323
|
+
console.log(`
|
|
29043
29324
|
Open ${pc13.cyan(baseUrl.replace(/\/+$/, "") + "/v1/oauth/start")} in a browser to authenticate via CF Access SSO.`);
|
|
29044
|
-
|
|
29325
|
+
console.log(` Once you've completed SSO, paste your CF_Authorization cookie below.
|
|
29045
29326
|
`);
|
|
29046
|
-
|
|
29047
|
-
|
|
29048
|
-
|
|
29049
|
-
|
|
29050
|
-
|
|
29327
|
+
const rawCookie = await promptLine(` ${pc13.dim("CF_Authorization cookie:")} `);
|
|
29328
|
+
if (!rawCookie) {
|
|
29329
|
+
printError("No cookie provided. Aborting.");
|
|
29330
|
+
process.exitCode = 1;
|
|
29331
|
+
return;
|
|
29332
|
+
}
|
|
29333
|
+
remoteOpts = { baseUrl, cfAuthCookie: rawCookie };
|
|
29051
29334
|
}
|
|
29052
29335
|
try {
|
|
29053
|
-
const revoked = await remoteRevokeAnthropicToken(
|
|
29336
|
+
const revoked = await remoteRevokeAnthropicToken(remoteOpts, opts.tokenHash);
|
|
29054
29337
|
if (revoked) {
|
|
29055
29338
|
printSuccess(`Token ${opts.tokenHash} revoked.`);
|
|
29056
29339
|
} else {
|
|
@@ -31342,6 +31625,7 @@ Top-level commands (run \`olam <command> --help\` for flags and subcommands):
|
|
|
31342
31625
|
- \`olam enter\` \u2014 Open terminal to a world
|
|
31343
31626
|
- \`olam evict\` \u2014 Evict oldest snapshots until total size \u2264 cap (default 5GB; override via OLAM_SNAPSHOT_MAX_BYTES)
|
|
31344
31627
|
- \`olam get\` \u2014 Print the active substrate
|
|
31628
|
+
- \`olam graph\` \u2014 Query the cross-repo graph: locate a symbol, its relationships, or browse a repo (POST /v1/graph)
|
|
31345
31629
|
- \`olam hermes\` \u2014 Hermes integration commands
|
|
31346
31630
|
- \`olam host-cp\` \u2014 Manage the Olam host control plane container
|
|
31347
31631
|
- \`olam implode\` \u2014 Destroy ALL local olam install and configs (dry-run by default)
|
|
@@ -31349,6 +31633,7 @@ Top-level commands (run \`olam <command> --help\` for flags and subcommands):
|
|
|
31349
31633
|
- \`olam inspect\` \u2014 Diagnose warm-create cache hits/misses for a workspace (read-only; mutates nothing)
|
|
31350
31634
|
- \`olam install\` \u2014 Pick an archetype preset for this Olam install
|
|
31351
31635
|
- \`olam install-hook\` \u2014 Install kg-service hook (idempotent). --for hermes targets ~/.hermes/; default targets .claude/settings.json
|
|
31636
|
+
- \`olam install-model-router\` \u2014 Deploy the model-router.py UserPromptSubmit hook script to ~/.claude/hooks/ (idempotent; auto-run by
|
|
31352
31637
|
- \`olam issue-anthropic-token\` \u2014 Mint a new Anthropic proxy token via the remote auth-worker (g4)
|
|
31353
31638
|
- \`olam keys\` \u2014 Manage LLM API keys stored at ~/.olam/keys.yaml
|
|
31354
31639
|
- \`olam kg\` \u2014 Knowledge-graph operations (kg-service container)
|
|
@@ -31403,7 +31688,7 @@ Top-level commands (run \`olam <command> --help\` for flags and subcommands):
|
|
|
31403
31688
|
- \`olam substrate\` \u2014 Manage deployment substrate (beta)
|
|
31404
31689
|
- \`olam sync\` \u2014 Sync registered skill sources to ~/.claude/
|
|
31405
31690
|
- \`olam tls-install\` \u2014 Provision a locally-trusted TLS cert (mkcert) for the Traefik IngressRoute
|
|
31406
|
-
- \`olam uninstall\` \u2014 Remove /
|
|
31691
|
+
- \`olam uninstall\` \u2014 Remove /100x: chain skill symlinks from ~/.claude/skills (preserves user-authored skills + non-chain skill sources)
|
|
31407
31692
|
- \`olam uninstall-hook\` \u2014 Remove kg-service PreToolUse hook from .claude/settings.json (sentinel-matched; surgical)
|
|
31408
31693
|
- \`olam unset-prefix\` \u2014 Remove the deploy prefix from a registered skill source (reverts to canonical deploy names)
|
|
31409
31694
|
- \`olam unset-prefix-scope\` \u2014 Remove the prefix-scope override from a registered skill source (reverts to default: both skill and agent are renamed)
|
|
@@ -31609,12 +31894,12 @@ async function runRepl(deps = {}) {
|
|
|
31609
31894
|
closed = true;
|
|
31610
31895
|
onClose?.();
|
|
31611
31896
|
});
|
|
31612
|
-
const ask = () => new Promise((
|
|
31613
|
-
if (closed) return
|
|
31614
|
-
onClose = () =>
|
|
31897
|
+
const ask = () => new Promise((resolve31) => {
|
|
31898
|
+
if (closed) return resolve31(null);
|
|
31899
|
+
onClose = () => resolve31(null);
|
|
31615
31900
|
rl.question(pc14.cyan("olam ask> "), (line) => {
|
|
31616
31901
|
onClose = null;
|
|
31617
|
-
|
|
31902
|
+
resolve31(line);
|
|
31618
31903
|
});
|
|
31619
31904
|
});
|
|
31620
31905
|
try {
|
|
@@ -32152,15 +32437,15 @@ var AGENTMEMORY_LOCAL_URL = "http://host.docker.internal:3111";
|
|
|
32152
32437
|
var HOST_CP_URL = "http://127.0.0.1:19000";
|
|
32153
32438
|
async function readHostCpTokenForCreate() {
|
|
32154
32439
|
try {
|
|
32155
|
-
const { default:
|
|
32440
|
+
const { default: fs108 } = await import("node:fs");
|
|
32156
32441
|
const { default: os60 } = await import("node:os");
|
|
32157
32442
|
const { default: path106 } = await import("node:path");
|
|
32158
32443
|
const tp = path106.join(
|
|
32159
32444
|
process.env.OLAM_HOME ?? path106.join(os60.homedir(), ".olam"),
|
|
32160
32445
|
"host-cp.token"
|
|
32161
32446
|
);
|
|
32162
|
-
if (!
|
|
32163
|
-
return
|
|
32447
|
+
if (!fs108.existsSync(tp)) return null;
|
|
32448
|
+
return fs108.readFileSync(tp, "utf-8").trim();
|
|
32164
32449
|
} catch {
|
|
32165
32450
|
return null;
|
|
32166
32451
|
}
|
|
@@ -32172,7 +32457,7 @@ function registerCreate(program2) {
|
|
|
32172
32457
|
).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(
|
|
32173
32458
|
"--claude-home <id-or-path>",
|
|
32174
32459
|
"Use a per-world Claude Code HOME (multi-account isolation; see docs/decisions/045-claude-home-override.md)"
|
|
32175
|
-
).action(async (opts) => {
|
|
32460
|
+
).option("--json", "Emit machine-readable JSON on success (suppresses interactive hints)").action(async (opts) => {
|
|
32176
32461
|
const { resolveDevboxImageOverride: resolveDevboxImageOverride2, decideAllowlist: decideAllowlist2 } = await Promise.resolve().then(() => (init_registry_allowlist(), registry_allowlist_exports));
|
|
32177
32462
|
const overrideRef = resolveDevboxImageOverride2(opts.devboxImage);
|
|
32178
32463
|
if (overrideRef) {
|
|
@@ -32660,12 +32945,12 @@ function defaultNameFromPrompt(prompt) {
|
|
|
32660
32945
|
}
|
|
32661
32946
|
async function readHostCpToken3() {
|
|
32662
32947
|
try {
|
|
32663
|
-
const { default:
|
|
32948
|
+
const { default: fs108 } = await import("node:fs");
|
|
32664
32949
|
const { default: os60 } = await import("node:os");
|
|
32665
32950
|
const { default: path106 } = await import("node:path");
|
|
32666
32951
|
const tp = path106.join(os60.homedir(), ".olam", "host-cp.token");
|
|
32667
|
-
if (!
|
|
32668
|
-
const raw =
|
|
32952
|
+
if (!fs108.existsSync(tp)) return null;
|
|
32953
|
+
const raw = fs108.readFileSync(tp, "utf-8").trim();
|
|
32669
32954
|
return raw.length > 0 ? raw : null;
|
|
32670
32955
|
} catch {
|
|
32671
32956
|
return null;
|
|
@@ -33039,7 +33324,7 @@ function parseRuntimeStatus(raw) {
|
|
|
33039
33324
|
last_event_age_seconds
|
|
33040
33325
|
};
|
|
33041
33326
|
}
|
|
33042
|
-
var fetchWorldRuntimeStatus = (worldId, token) => new Promise((
|
|
33327
|
+
var fetchWorldRuntimeStatus = (worldId, token) => new Promise((resolve31) => {
|
|
33043
33328
|
const opts = {
|
|
33044
33329
|
host: "127.0.0.1",
|
|
33045
33330
|
port: HOST_CP_PORT2,
|
|
@@ -33051,7 +33336,7 @@ var fetchWorldRuntimeStatus = (worldId, token) => new Promise((resolve30) => {
|
|
|
33051
33336
|
const req = http3.request(opts, (res) => {
|
|
33052
33337
|
if (res.statusCode !== 200) {
|
|
33053
33338
|
res.resume();
|
|
33054
|
-
return
|
|
33339
|
+
return resolve31(null);
|
|
33055
33340
|
}
|
|
33056
33341
|
let body = "";
|
|
33057
33342
|
res.setEncoding("utf-8");
|
|
@@ -33061,17 +33346,17 @@ var fetchWorldRuntimeStatus = (worldId, token) => new Promise((resolve30) => {
|
|
|
33061
33346
|
res.on("end", () => {
|
|
33062
33347
|
try {
|
|
33063
33348
|
const parsed = parseRuntimeStatus(JSON.parse(body));
|
|
33064
|
-
|
|
33349
|
+
resolve31(parsed);
|
|
33065
33350
|
} catch {
|
|
33066
|
-
|
|
33351
|
+
resolve31(null);
|
|
33067
33352
|
}
|
|
33068
33353
|
});
|
|
33069
|
-
res.on("error", () =>
|
|
33354
|
+
res.on("error", () => resolve31(null));
|
|
33070
33355
|
});
|
|
33071
|
-
req.on("error", () =>
|
|
33356
|
+
req.on("error", () => resolve31(null));
|
|
33072
33357
|
req.on("timeout", () => {
|
|
33073
33358
|
req.destroy();
|
|
33074
|
-
|
|
33359
|
+
resolve31(null);
|
|
33075
33360
|
});
|
|
33076
33361
|
req.end();
|
|
33077
33362
|
});
|
|
@@ -33127,7 +33412,7 @@ async function getMachineStatus(_probe, _loadCtx, _readToken) {
|
|
|
33127
33412
|
};
|
|
33128
33413
|
}
|
|
33129
33414
|
function registerStatus(program2) {
|
|
33130
|
-
program2.command("status").description("Show machine status, or world details when a world ID is given").argument("[world]", "World ID \u2014 omit to show machine status").option("--json", "Output as JSON").
|
|
33415
|
+
program2.command("status").description("Show machine status, or world details when a world ID is given").argument("[world]", "World ID \u2014 omit to show machine status").option("--json", "Output as JSON").action(async (worldId, opts) => {
|
|
33131
33416
|
if (!worldId) {
|
|
33132
33417
|
const ms = await getMachineStatus();
|
|
33133
33418
|
if (opts.json) {
|
|
@@ -33261,12 +33546,12 @@ async function readlineConfirm(world) {
|
|
|
33261
33546
|
|
|
33262
33547
|
`
|
|
33263
33548
|
);
|
|
33264
|
-
return new Promise((
|
|
33549
|
+
return new Promise((resolve31) => {
|
|
33265
33550
|
rl.question(
|
|
33266
33551
|
`Destroy ${pc20.bold(world.name)}? This cannot be undone. [y/N] `,
|
|
33267
33552
|
(answer) => {
|
|
33268
33553
|
rl.close();
|
|
33269
|
-
|
|
33554
|
+
resolve31(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
33270
33555
|
}
|
|
33271
33556
|
);
|
|
33272
33557
|
});
|
|
@@ -33621,14 +33906,14 @@ function printTable(entries) {
|
|
|
33621
33906
|
async function confirmInteractive() {
|
|
33622
33907
|
process.stdout.write(" Type `yes` to proceed: ");
|
|
33623
33908
|
const buf = [];
|
|
33624
|
-
return new Promise((
|
|
33909
|
+
return new Promise((resolve31) => {
|
|
33625
33910
|
const onData = (chunk) => {
|
|
33626
33911
|
buf.push(chunk);
|
|
33627
33912
|
if (Buffer.concat(buf).toString("utf-8").includes("\n")) {
|
|
33628
33913
|
process.stdin.removeListener("data", onData);
|
|
33629
33914
|
process.stdin.pause();
|
|
33630
33915
|
const answer = Buffer.concat(buf).toString("utf-8").trim();
|
|
33631
|
-
|
|
33916
|
+
resolve31(answer.toLowerCase() === "yes");
|
|
33632
33917
|
}
|
|
33633
33918
|
};
|
|
33634
33919
|
process.stdin.resume();
|
|
@@ -39824,10 +40109,10 @@ async function confirm2(message) {
|
|
|
39824
40109
|
if (!process.stdin.isTTY) return true;
|
|
39825
40110
|
const { createInterface: createInterface12 } = await import("node:readline");
|
|
39826
40111
|
const rl = createInterface12({ input: process.stdin, output: process.stdout });
|
|
39827
|
-
return new Promise((
|
|
40112
|
+
return new Promise((resolve31) => {
|
|
39828
40113
|
rl.question(`${message} [y/N] `, (answer) => {
|
|
39829
40114
|
rl.close();
|
|
39830
|
-
|
|
40115
|
+
resolve31(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
39831
40116
|
});
|
|
39832
40117
|
});
|
|
39833
40118
|
}
|
|
@@ -41071,7 +41356,15 @@ function registerPs(program2) {
|
|
|
41071
41356
|
process.exitCode = 1;
|
|
41072
41357
|
return;
|
|
41073
41358
|
}
|
|
41074
|
-
const
|
|
41359
|
+
const VALID_SORT_KEYS = ["cpu", "mem", "pid"];
|
|
41360
|
+
if (!VALID_SORT_KEYS.includes(opts.sort)) {
|
|
41361
|
+
printError(
|
|
41362
|
+
`Invalid --sort key "${opts.sort}". Valid values: ${VALID_SORT_KEYS.join(", ")}.`
|
|
41363
|
+
);
|
|
41364
|
+
process.exitCode = 1;
|
|
41365
|
+
return;
|
|
41366
|
+
}
|
|
41367
|
+
const sortKey = opts.sort;
|
|
41075
41368
|
const containerName = `olam-${worldId}-devbox`;
|
|
41076
41369
|
let watchInterval;
|
|
41077
41370
|
function fetchAndPrint() {
|
|
@@ -41811,7 +42104,7 @@ async function refreshWorld(worldId, portOffset, standaloneDir, opts) {
|
|
|
41811
42104
|
return { worldId, ok: true };
|
|
41812
42105
|
}
|
|
41813
42106
|
function registerRefresh(program2) {
|
|
41814
|
-
program2.command("refresh").description("Hot-refresh a running world's per-world CP
|
|
42107
|
+
program2.command("refresh").description("Hot-refresh a running world's per-world container-CP bundle (packages/control-plane/standalone/ \u2014 legacy per-world CP surface)").argument("[world]", "World ID").option("--all", "Refresh every running world sequentially (overrides positional arg)").option("--no-restart", "Copy files but skip CP restart (for debugging)").option("--skip-build", "Skip the prerequisite server.mjs presence check").action(async (worldId, opts) => {
|
|
41815
42108
|
if (!opts.all && !worldId) {
|
|
41816
42109
|
printError("Specify a world ID or use --all to refresh all running worlds.");
|
|
41817
42110
|
process.exitCode = 1;
|
|
@@ -42497,7 +42790,7 @@ async function runPeripheralProbes(peripheral, startPosition, kubectlContext, wr
|
|
|
42497
42790
|
})();
|
|
42498
42791
|
rows.push({ name: `${peripheral.name} ready`, result: reachableResult, position: startPosition });
|
|
42499
42792
|
const pfLivenessResult = await (async () => {
|
|
42500
|
-
return new Promise((
|
|
42793
|
+
return new Promise((resolve31) => {
|
|
42501
42794
|
const socket = new net4.Socket();
|
|
42502
42795
|
let done = false;
|
|
42503
42796
|
const finish = (alive) => {
|
|
@@ -42505,9 +42798,9 @@ async function runPeripheralProbes(peripheral, startPosition, kubectlContext, wr
|
|
|
42505
42798
|
done = true;
|
|
42506
42799
|
socket.destroy();
|
|
42507
42800
|
if (alive) {
|
|
42508
|
-
|
|
42801
|
+
resolve31({ ok: true, message: `${peripheral.name} port-forward live on :${peripheral.port}` });
|
|
42509
42802
|
} else {
|
|
42510
|
-
|
|
42803
|
+
resolve31({
|
|
42511
42804
|
ok: true,
|
|
42512
42805
|
warn: true,
|
|
42513
42806
|
message: `${peripheral.name} port-forward not live on :${peripheral.port}`,
|
|
@@ -43735,8 +44028,8 @@ function registerCompletion(program2) {
|
|
|
43735
44028
|
init_cli_version();
|
|
43736
44029
|
init_health_probes();
|
|
43737
44030
|
import { spawn as spawn8, spawnSync as spawnSync29 } from "node:child_process";
|
|
43738
|
-
import { existsSync as
|
|
43739
|
-
import { homedir as
|
|
44031
|
+
import { existsSync as existsSync92, readFileSync as readFileSync80 } from "node:fs";
|
|
44032
|
+
import { homedir as homedir54 } from "node:os";
|
|
43740
44033
|
import path84 from "node:path";
|
|
43741
44034
|
import { createInterface as createInterface5 } from "node:readline";
|
|
43742
44035
|
|
|
@@ -43983,9 +44276,9 @@ async function pickSkillSourcePhase(opts, deps) {
|
|
|
43983
44276
|
}
|
|
43984
44277
|
|
|
43985
44278
|
// src/commands/setup-phase-5b-project-sweep.ts
|
|
43986
|
-
import { homedir as
|
|
44279
|
+
import { homedir as homedir51 } from "node:os";
|
|
43987
44280
|
import * as path82 from "node:path";
|
|
43988
|
-
import * as
|
|
44281
|
+
import * as fs83 from "node:fs";
|
|
43989
44282
|
async function loadWalkFn() {
|
|
43990
44283
|
const m = await Promise.resolve().then(() => (init_project_sweep(), project_sweep_exports));
|
|
43991
44284
|
return m.walkProjectRoot;
|
|
@@ -44016,9 +44309,9 @@ async function runProjectSweepPhase(opts, deps, sweepDeps = {}) {
|
|
|
44016
44309
|
if (opts.skipProjectSweep) {
|
|
44017
44310
|
return { ok: true, skipped: true, message: "skipped via --skip-project-sweep" };
|
|
44018
44311
|
}
|
|
44019
|
-
const home = deps.home ??
|
|
44312
|
+
const home = deps.home ?? homedir51();
|
|
44020
44313
|
const projectsRoot = opts.projects ?? path82.join(home, "Projects");
|
|
44021
|
-
const existsSyncFn = sweepDeps.existsSync ??
|
|
44314
|
+
const existsSyncFn = sweepDeps.existsSync ?? fs83.existsSync;
|
|
44022
44315
|
if (!existsSyncFn(projectsRoot)) {
|
|
44023
44316
|
return {
|
|
44024
44317
|
ok: true,
|
|
@@ -44119,7 +44412,7 @@ async function runProjectSweepPhase(opts, deps, sweepDeps = {}) {
|
|
|
44119
44412
|
}
|
|
44120
44413
|
|
|
44121
44414
|
// src/commands/setup-phase-8-kg-hook.ts
|
|
44122
|
-
import * as
|
|
44415
|
+
import * as fs84 from "node:fs";
|
|
44123
44416
|
import * as path83 from "node:path";
|
|
44124
44417
|
import * as os47 from "node:os";
|
|
44125
44418
|
async function loadMergeHookFn() {
|
|
@@ -44149,7 +44442,7 @@ async function runKgHookPhase(opts, _deps, kgDeps = {}) {
|
|
|
44149
44442
|
message: `dry-run: would install KG hook into ${settingsPath}`
|
|
44150
44443
|
};
|
|
44151
44444
|
}
|
|
44152
|
-
const mkdirFn = kgDeps.mkdirSync ?? ((p, o) =>
|
|
44445
|
+
const mkdirFn = kgDeps.mkdirSync ?? ((p, o) => fs84.mkdirSync(p, o));
|
|
44153
44446
|
try {
|
|
44154
44447
|
mkdirFn(path83.dirname(settingsPath), { recursive: true });
|
|
44155
44448
|
} catch (err) {
|
|
@@ -44237,10 +44530,10 @@ var NEXT_STEPS_DOCS_KUBERNETES = [
|
|
|
44237
44530
|
"https://github.com/pleri/olam/blob/main/docs/architecture/config-spec.md \u2014 workspace .olam/config.yaml schema",
|
|
44238
44531
|
"https://github.com/pleri/olam/blob/main/docs/k8s/SETUP.md \u2014 k3d operator guide"
|
|
44239
44532
|
];
|
|
44240
|
-
var defaultSpawn2 = (cmd, args) => new Promise((
|
|
44533
|
+
var defaultSpawn2 = (cmd, args) => new Promise((resolve31) => {
|
|
44241
44534
|
const child = spawn8(cmd, [...args], { stdio: "inherit" });
|
|
44242
|
-
child.on("exit", (code) =>
|
|
44243
|
-
child.on("error", () =>
|
|
44535
|
+
child.on("exit", (code) => resolve31({ status: code }));
|
|
44536
|
+
child.on("error", () => resolve31({ status: 1 }));
|
|
44244
44537
|
});
|
|
44245
44538
|
var defaultPrompt = (question, defaultYes) => {
|
|
44246
44539
|
if (!process.stdin.isTTY) {
|
|
@@ -44250,18 +44543,18 @@ var defaultPrompt = (question, defaultYes) => {
|
|
|
44250
44543
|
);
|
|
44251
44544
|
return Promise.resolve(defaultYes);
|
|
44252
44545
|
}
|
|
44253
|
-
return new Promise((
|
|
44546
|
+
return new Promise((resolve31) => {
|
|
44254
44547
|
const rl = createInterface5({ input: process.stdin, output: process.stdout });
|
|
44255
44548
|
const suffix = defaultYes ? " [Y/n]: " : " [y/N]: ";
|
|
44256
44549
|
rl.question(`${question}${suffix}`, (answer) => {
|
|
44257
44550
|
rl.close();
|
|
44258
44551
|
const t = answer.trim().toLowerCase();
|
|
44259
|
-
if (t === "")
|
|
44260
|
-
else if (t === "y" || t === "yes")
|
|
44261
|
-
else if (t === "n" || t === "no")
|
|
44262
|
-
else
|
|
44552
|
+
if (t === "") resolve31(defaultYes);
|
|
44553
|
+
else if (t === "y" || t === "yes") resolve31(true);
|
|
44554
|
+
else if (t === "n" || t === "no") resolve31(false);
|
|
44555
|
+
else resolve31(defaultYes);
|
|
44263
44556
|
});
|
|
44264
|
-
rl.on("close", () =>
|
|
44557
|
+
rl.on("close", () => resolve31(defaultYes));
|
|
44265
44558
|
});
|
|
44266
44559
|
};
|
|
44267
44560
|
var CLUSTER_NAME_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
@@ -44281,9 +44574,9 @@ function resolveSubstrate(opts, deps) {
|
|
|
44281
44574
|
if (opts.substrate === "kubernetes") return "kubernetes";
|
|
44282
44575
|
if (opts.substrate === "docker") return "docker";
|
|
44283
44576
|
const configPath = deps.configPath ?? OLAM_CONFIG_PATH;
|
|
44284
|
-
if (
|
|
44577
|
+
if (existsSync92(configPath)) {
|
|
44285
44578
|
try {
|
|
44286
|
-
const raw =
|
|
44579
|
+
const raw = readFileSync80(configPath, "utf8");
|
|
44287
44580
|
const parsed = JSON.parse(raw);
|
|
44288
44581
|
const host = parsed.host;
|
|
44289
44582
|
if (host?.substrate === "kubernetes") return "kubernetes";
|
|
@@ -44350,9 +44643,9 @@ async function phase0SubstratePicker(opts, deps) {
|
|
|
44350
44643
|
return { ok: true, skipped: true, message: "skipped via --skip-substrate-picker" };
|
|
44351
44644
|
}
|
|
44352
44645
|
const configPath = deps.configPath ?? OLAM_CONFIG_PATH;
|
|
44353
|
-
if (
|
|
44646
|
+
if (existsSync92(configPath)) {
|
|
44354
44647
|
try {
|
|
44355
|
-
const raw =
|
|
44648
|
+
const raw = readFileSync80(configPath, "utf8");
|
|
44356
44649
|
const parsed = JSON.parse(raw);
|
|
44357
44650
|
const host = parsed.host;
|
|
44358
44651
|
if (host?.substrate !== void 0 && host?.preferred_runtime !== void 0) {
|
|
@@ -44402,9 +44695,9 @@ async function phase0SubstratePicker(opts, deps) {
|
|
|
44402
44695
|
const choice = SUBSTRATE_CHOICES[Number(pickedIndex)] ?? DEFAULT_SUBSTRATE_CHOICE;
|
|
44403
44696
|
if (choice.requirePinnedContext) {
|
|
44404
44697
|
let hasPinnedContext = false;
|
|
44405
|
-
if (
|
|
44698
|
+
if (existsSync92(configPath)) {
|
|
44406
44699
|
try {
|
|
44407
|
-
const raw =
|
|
44700
|
+
const raw = readFileSync80(configPath, "utf8");
|
|
44408
44701
|
const parsed = JSON.parse(raw);
|
|
44409
44702
|
const host = parsed.host;
|
|
44410
44703
|
hasPinnedContext = typeof host?.kubectl_context_pinned === "string" && host.kubectl_context_pinned.length > 0;
|
|
@@ -44561,7 +44854,7 @@ async function phase1SystemCheck(substrate, deps) {
|
|
|
44561
44854
|
};
|
|
44562
44855
|
}
|
|
44563
44856
|
const platform2 = String(deps.osPlatform ?? process.platform);
|
|
44564
|
-
const home = deps.home ??
|
|
44857
|
+
const home = deps.home ?? homedir54();
|
|
44565
44858
|
const colimaLint = probeColimaKubernetesEnabled({ platform: platform2, home });
|
|
44566
44859
|
if (colimaLint.ok && "warn" in colimaLint && colimaLint.warn === true) {
|
|
44567
44860
|
const lintWithWarn = colimaLint;
|
|
@@ -44700,8 +44993,8 @@ async function phase2_5ProvisionCluster(substrate, clusterName, opts, deps, reus
|
|
|
44700
44993
|
process.stdout.write(`Creating k3d cluster ${clusterName}...
|
|
44701
44994
|
`);
|
|
44702
44995
|
const volumes = [];
|
|
44703
|
-
const ghConfigDir = `${
|
|
44704
|
-
if (
|
|
44996
|
+
const ghConfigDir = `${homedir54()}/.config/gh`;
|
|
44997
|
+
if (existsSync92(ghConfigDir)) {
|
|
44705
44998
|
volumes.push("--volume", `${ghConfigDir}:/host/.config/gh`);
|
|
44706
44999
|
} else {
|
|
44707
45000
|
process.stdout.write(
|
|
@@ -44710,7 +45003,7 @@ async function phase2_5ProvisionCluster(substrate, clusterName, opts, deps, reus
|
|
|
44710
45003
|
);
|
|
44711
45004
|
}
|
|
44712
45005
|
if (opts.hostCpDevPath) {
|
|
44713
|
-
if (!
|
|
45006
|
+
if (!existsSync92(opts.hostCpDevPath)) {
|
|
44714
45007
|
return {
|
|
44715
45008
|
ok: false,
|
|
44716
45009
|
message: `--host-cp-dev-path ${opts.hostCpDevPath} does not exist`,
|
|
@@ -44875,7 +45168,7 @@ async function phase3_5K3dHttpsBootstrap(substrate, opts, _deps) {
|
|
|
44875
45168
|
const result = await ensureTlsInstalled();
|
|
44876
45169
|
let hostsWarning = "";
|
|
44877
45170
|
try {
|
|
44878
|
-
const hostsBody =
|
|
45171
|
+
const hostsBody = readFileSync80("/etc/hosts", "utf-8");
|
|
44879
45172
|
if (!/^[^#\n]*\bolam\.local\b/m.test(hostsBody)) {
|
|
44880
45173
|
hostsWarning = " Add to /etc/hosts: echo '127.0.0.1 olam.local' | sudo tee -a /etc/hosts";
|
|
44881
45174
|
}
|
|
@@ -44901,7 +45194,7 @@ async function phase4ShellInit(opts, deps) {
|
|
|
44901
45194
|
if (opts.skipShellInit) {
|
|
44902
45195
|
return { ok: true, skipped: true, message: "skipped via --skip-shell-init" };
|
|
44903
45196
|
}
|
|
44904
|
-
const home = deps.home ??
|
|
45197
|
+
const home = deps.home ?? homedir54();
|
|
44905
45198
|
const shellEnv = deps.shellEnv ?? process.env.SHELL;
|
|
44906
45199
|
const rcPath = resolveShellRc(home, shellEnv);
|
|
44907
45200
|
if (rcPath === null) {
|
|
@@ -45415,24 +45708,24 @@ function registerSetupLinuxGate(program2) {
|
|
|
45415
45708
|
}
|
|
45416
45709
|
|
|
45417
45710
|
// src/commands/update.ts
|
|
45418
|
-
import * as
|
|
45711
|
+
import * as fs87 from "node:fs";
|
|
45419
45712
|
import * as os49 from "node:os";
|
|
45420
45713
|
import * as path87 from "node:path";
|
|
45421
45714
|
import { execSync as execSync15 } from "node:child_process";
|
|
45422
45715
|
import pc33 from "picocolors";
|
|
45423
45716
|
|
|
45424
45717
|
// src/lib/symlink-reconcile.ts
|
|
45425
|
-
import * as
|
|
45718
|
+
import * as fs85 from "node:fs";
|
|
45426
45719
|
import * as path85 from "node:path";
|
|
45427
45720
|
var realFs = {
|
|
45428
|
-
readdirSync: (p) =>
|
|
45429
|
-
existsSync: (p) =>
|
|
45430
|
-
lstatSync: (p) =>
|
|
45431
|
-
readlinkSync: (p) =>
|
|
45432
|
-
symlinkSync: (t, l) =>
|
|
45433
|
-
unlinkSync: (p) =>
|
|
45721
|
+
readdirSync: (p) => fs85.readdirSync(p),
|
|
45722
|
+
existsSync: (p) => fs85.existsSync(p),
|
|
45723
|
+
lstatSync: (p) => fs85.lstatSync(p),
|
|
45724
|
+
readlinkSync: (p) => fs85.readlinkSync(p),
|
|
45725
|
+
symlinkSync: (t, l) => fs85.symlinkSync(t, l),
|
|
45726
|
+
unlinkSync: (p) => fs85.unlinkSync(p),
|
|
45434
45727
|
mkdirSync: (p, o) => {
|
|
45435
|
-
|
|
45728
|
+
fs85.mkdirSync(p, o);
|
|
45436
45729
|
}
|
|
45437
45730
|
};
|
|
45438
45731
|
function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir2, _fs = realFs) {
|
|
@@ -45526,22 +45819,22 @@ function getCurrentVersion(_exec = defaultExec) {
|
|
|
45526
45819
|
}
|
|
45527
45820
|
function readLastStable(file = LAST_STABLE_FILE) {
|
|
45528
45821
|
try {
|
|
45529
|
-
const v =
|
|
45822
|
+
const v = fs87.readFileSync(file, "utf-8").trim();
|
|
45530
45823
|
return v || null;
|
|
45531
45824
|
} catch {
|
|
45532
45825
|
return null;
|
|
45533
45826
|
}
|
|
45534
45827
|
}
|
|
45535
45828
|
function writeLastStable(version, file = LAST_STABLE_FILE) {
|
|
45536
|
-
|
|
45537
|
-
|
|
45829
|
+
fs87.mkdirSync(path87.dirname(file), { recursive: true });
|
|
45830
|
+
fs87.writeFileSync(file, version, { mode: 420 });
|
|
45538
45831
|
}
|
|
45539
45832
|
function logUpdateFailure(stderr) {
|
|
45540
45833
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
45541
45834
|
const logFile = path87.join(LOG_DIR2, `update-${ts}.log`);
|
|
45542
45835
|
try {
|
|
45543
|
-
|
|
45544
|
-
|
|
45836
|
+
fs87.mkdirSync(LOG_DIR2, { recursive: true });
|
|
45837
|
+
fs87.appendFileSync(logFile, `[update-failure ${(/* @__PURE__ */ new Date()).toISOString()}]
|
|
45545
45838
|
${stderr}
|
|
45546
45839
|
`, "utf-8");
|
|
45547
45840
|
} catch {
|
|
@@ -45762,7 +46055,7 @@ function registerBegin(program2) {
|
|
|
45762
46055
|
// src/commands/config.ts
|
|
45763
46056
|
init_global_config();
|
|
45764
46057
|
init_store2();
|
|
45765
|
-
import * as
|
|
46058
|
+
import * as fs88 from "node:fs";
|
|
45766
46059
|
import { createRequire as createRequire4 } from "node:module";
|
|
45767
46060
|
var _require4 = createRequire4(import.meta.url);
|
|
45768
46061
|
var { parse: parseWithMap } = _require4("json-source-map");
|
|
@@ -45779,14 +46072,14 @@ function registerConfig(program2) {
|
|
|
45779
46072
|
const config = program2.command("config").description("Manage global olam configuration");
|
|
45780
46073
|
config.command("validate [path]").description("Validate ~/.olam/config.json (or a custom path) against the schema").action((filePath) => {
|
|
45781
46074
|
const resolvedPath = filePath ?? globalConfigPath();
|
|
45782
|
-
if (!
|
|
46075
|
+
if (!fs88.existsSync(resolvedPath)) {
|
|
45783
46076
|
process.stderr.write(`config file not found: ${resolvedPath}
|
|
45784
46077
|
`);
|
|
45785
46078
|
process.exit(1);
|
|
45786
46079
|
}
|
|
45787
46080
|
let raw;
|
|
45788
46081
|
try {
|
|
45789
|
-
raw =
|
|
46082
|
+
raw = fs88.readFileSync(resolvedPath, "utf-8");
|
|
45790
46083
|
} catch (err) {
|
|
45791
46084
|
const msg = err instanceof Error ? err.message : String(err);
|
|
45792
46085
|
process.stderr.write(`cannot read ${resolvedPath}: ${msg}
|
|
@@ -46234,9 +46527,9 @@ import * as readline3 from "node:readline";
|
|
|
46234
46527
|
import pc37 from "picocolors";
|
|
46235
46528
|
|
|
46236
46529
|
// src/commands/flywheel/install-shims.ts
|
|
46237
|
-
import { copyFileSync as copyFileSync9, existsSync as
|
|
46238
|
-
import { homedir as
|
|
46239
|
-
import { dirname as
|
|
46530
|
+
import { copyFileSync as copyFileSync9, existsSync as existsSync96, mkdirSync as mkdirSync57, readFileSync as readFileSync84, writeFileSync as writeFileSync50 } from "node:fs";
|
|
46531
|
+
import { homedir as homedir57 } from "node:os";
|
|
46532
|
+
import { dirname as dirname53, join as join97 } from "node:path";
|
|
46240
46533
|
|
|
46241
46534
|
// src/lib/shim-generator.ts
|
|
46242
46535
|
var SHIM_SPECS = Object.freeze([
|
|
@@ -46299,7 +46592,7 @@ ${argsBlock}
|
|
|
46299
46592
|
// src/commands/flywheel/install-shims.ts
|
|
46300
46593
|
var SHIM_HEADER_MARKER = "# AUTO-GENERATED by `olam flywheel install-shims`";
|
|
46301
46594
|
function refreshShims(opts = {}) {
|
|
46302
|
-
const targetDir = opts.targetDir ??
|
|
46595
|
+
const targetDir = opts.targetDir ?? join97(homedir57(), ".claude", "scripts");
|
|
46303
46596
|
const results = [];
|
|
46304
46597
|
let written = 0;
|
|
46305
46598
|
let overwritten = 0;
|
|
@@ -46329,22 +46622,22 @@ function isOlamGeneratedShim(text) {
|
|
|
46329
46622
|
return text.includes(SHIM_HEADER_MARKER);
|
|
46330
46623
|
}
|
|
46331
46624
|
function installOne(spec, targetDir, opts) {
|
|
46332
|
-
const targetPath =
|
|
46625
|
+
const targetPath = join97(targetDir, spec.basename);
|
|
46333
46626
|
const newContent = generateShim(spec);
|
|
46334
|
-
if (!
|
|
46627
|
+
if (!existsSync96(targetPath)) {
|
|
46335
46628
|
if (opts.dryRun !== true) {
|
|
46336
|
-
|
|
46337
|
-
|
|
46629
|
+
mkdirSync57(dirname53(targetPath), { recursive: true });
|
|
46630
|
+
writeFileSync50(targetPath, newContent, { mode: 493 });
|
|
46338
46631
|
}
|
|
46339
46632
|
return { basename: spec.basename, action: "written", targetPath };
|
|
46340
46633
|
}
|
|
46341
|
-
const existing =
|
|
46634
|
+
const existing = readFileSync84(targetPath, "utf8");
|
|
46342
46635
|
if (existing === newContent) {
|
|
46343
46636
|
return { basename: spec.basename, action: "unchanged", targetPath };
|
|
46344
46637
|
}
|
|
46345
46638
|
if (isOlamGeneratedShim(existing)) {
|
|
46346
46639
|
if (opts.dryRun !== true) {
|
|
46347
|
-
|
|
46640
|
+
writeFileSync50(targetPath, newContent, { mode: 493 });
|
|
46348
46641
|
}
|
|
46349
46642
|
return { basename: spec.basename, action: "overwritten", targetPath };
|
|
46350
46643
|
}
|
|
@@ -46352,7 +46645,7 @@ function installOne(spec, targetDir, opts) {
|
|
|
46352
46645
|
const backupPath = `${targetPath}.shim-backup-${Math.floor(Date.now() / 1e3)}`;
|
|
46353
46646
|
if (opts.dryRun !== true) {
|
|
46354
46647
|
copyFileSync9(targetPath, backupPath);
|
|
46355
|
-
|
|
46648
|
+
writeFileSync50(targetPath, newContent, { mode: 493 });
|
|
46356
46649
|
}
|
|
46357
46650
|
return { basename: spec.basename, action: "overwritten", targetPath, backupPath };
|
|
46358
46651
|
}
|
|
@@ -46360,7 +46653,7 @@ function installOne(spec, targetDir, opts) {
|
|
|
46360
46653
|
}
|
|
46361
46654
|
function registerFlywheelInstallShims(parent) {
|
|
46362
46655
|
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) => {
|
|
46363
|
-
const targetDir = opts.targetDir ??
|
|
46656
|
+
const targetDir = opts.targetDir ?? join97(homedir57(), ".claude", "scripts");
|
|
46364
46657
|
const summary2 = refreshShims(opts);
|
|
46365
46658
|
const lines = [];
|
|
46366
46659
|
const dryRunSuffix = opts.dryRun === true ? " (dry-run)" : "";
|
|
@@ -46413,7 +46706,7 @@ async function decideTrust(opts) {
|
|
|
46413
46706
|
return { granted: !denied, method: "interactive" };
|
|
46414
46707
|
}
|
|
46415
46708
|
function defaultTrustPrompt(gitUrl) {
|
|
46416
|
-
return new Promise((
|
|
46709
|
+
return new Promise((resolve31) => {
|
|
46417
46710
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
46418
46711
|
process.stdout.write(
|
|
46419
46712
|
`${pc37.yellow("Trust gate:")} register "${gitUrl}" as a skill source?
|
|
@@ -46423,12 +46716,12 @@ Trust this source? ${pc37.dim("[Y/n] ")}`
|
|
|
46423
46716
|
);
|
|
46424
46717
|
rl.question("", (a) => {
|
|
46425
46718
|
rl.close();
|
|
46426
|
-
|
|
46719
|
+
resolve31(a);
|
|
46427
46720
|
});
|
|
46428
46721
|
});
|
|
46429
46722
|
}
|
|
46430
46723
|
function defaultSourcePrefixPrompt(input2) {
|
|
46431
|
-
return new Promise((
|
|
46724
|
+
return new Promise((resolve31) => {
|
|
46432
46725
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
46433
46726
|
const cfg = input2.newConfig;
|
|
46434
46727
|
const prefixLabel = cfg.prefix !== void 0 ? `'${cfg.prefix}:'` : "(no prefix)";
|
|
@@ -46440,12 +46733,12 @@ Adopt for this host? ${pc37.dim("[Y/n] ")}`
|
|
|
46440
46733
|
);
|
|
46441
46734
|
rl.question("", (a) => {
|
|
46442
46735
|
rl.close();
|
|
46443
|
-
|
|
46736
|
+
resolve31(!/^n(o)?$/i.test(a.trim()));
|
|
46444
46737
|
});
|
|
46445
46738
|
});
|
|
46446
46739
|
}
|
|
46447
46740
|
function defaultPostAddPrompt(input2) {
|
|
46448
|
-
return new Promise((
|
|
46741
|
+
return new Promise((resolve31) => {
|
|
46449
46742
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
46450
46743
|
process.stdout.write(`
|
|
46451
46744
|
${pc37.bold("Sync now?")} ${pc37.dim("[Y/n] ")}`);
|
|
@@ -46453,7 +46746,7 @@ ${pc37.bold("Sync now?")} ${pc37.dim("[Y/n] ")}`);
|
|
|
46453
46746
|
const sync = !/^n(o)?$/i.test(syncAnswer.trim());
|
|
46454
46747
|
if (input2.hookAlreadyInstalled) {
|
|
46455
46748
|
rl.close();
|
|
46456
|
-
|
|
46749
|
+
resolve31({ syncNow: sync, installHook: false });
|
|
46457
46750
|
return;
|
|
46458
46751
|
}
|
|
46459
46752
|
process.stdout.write(
|
|
@@ -46462,7 +46755,7 @@ ${pc37.bold("Sync now?")} ${pc37.dim("[Y/n] ")}`);
|
|
|
46462
46755
|
rl.question("", (hookAnswer) => {
|
|
46463
46756
|
rl.close();
|
|
46464
46757
|
const installHook = !/^n(o)?$/i.test(hookAnswer.trim());
|
|
46465
|
-
|
|
46758
|
+
resolve31({ syncNow: sync, installHook });
|
|
46466
46759
|
});
|
|
46467
46760
|
});
|
|
46468
46761
|
});
|
|
@@ -47119,7 +47412,7 @@ function registerSkillsSource(program2) {
|
|
|
47119
47412
|
// src/commands/skills.ts
|
|
47120
47413
|
init_skill_sources();
|
|
47121
47414
|
init_output();
|
|
47122
|
-
import * as
|
|
47415
|
+
import * as fs89 from "node:fs";
|
|
47123
47416
|
import * as os50 from "node:os";
|
|
47124
47417
|
import * as path88 from "node:path";
|
|
47125
47418
|
import * as readline4 from "node:readline";
|
|
@@ -47130,18 +47423,18 @@ init_markdown_merger();
|
|
|
47130
47423
|
init_file_lock();
|
|
47131
47424
|
import {
|
|
47132
47425
|
copyFileSync as copyFileSync10,
|
|
47133
|
-
existsSync as
|
|
47426
|
+
existsSync as existsSync97,
|
|
47134
47427
|
lstatSync as lstatSync8,
|
|
47135
|
-
mkdirSync as
|
|
47428
|
+
mkdirSync as mkdirSync58,
|
|
47136
47429
|
readdirSync as readdirSync28,
|
|
47137
|
-
readFileSync as
|
|
47430
|
+
readFileSync as readFileSync85,
|
|
47138
47431
|
readlinkSync as readlinkSync4,
|
|
47139
47432
|
rmSync as rmSync11,
|
|
47140
47433
|
statSync as statSync28,
|
|
47141
|
-
writeFileSync as
|
|
47434
|
+
writeFileSync as writeFileSync51
|
|
47142
47435
|
} from "node:fs";
|
|
47143
|
-
import { homedir as
|
|
47144
|
-
import { basename as basename8, dirname as
|
|
47436
|
+
import { homedir as homedir58 } from "node:os";
|
|
47437
|
+
import { basename as basename8, dirname as dirname54, isAbsolute as isAbsolute4, join as join98, relative as relative5, resolve as resolve24 } from "node:path";
|
|
47145
47438
|
|
|
47146
47439
|
// src/commands/flywheel/sanitize-persona-output.ts
|
|
47147
47440
|
var FORBIDDEN_HEADERS = [
|
|
@@ -47203,23 +47496,23 @@ function registerFlywheelSanitizePersonaOutput(parent) {
|
|
|
47203
47496
|
|
|
47204
47497
|
// src/lib/skills-apply-overlays.ts
|
|
47205
47498
|
function claudeRoot(opts) {
|
|
47206
|
-
return opts.claudeDir ?? opts.fixtureRoot ??
|
|
47499
|
+
return opts.claudeDir ?? opts.fixtureRoot ?? join98(homedir58(), ".claude");
|
|
47207
47500
|
}
|
|
47208
47501
|
function ensureRealDir(p) {
|
|
47209
|
-
if (!
|
|
47210
|
-
|
|
47502
|
+
if (!existsSync97(p)) {
|
|
47503
|
+
mkdirSync58(p, { recursive: true });
|
|
47211
47504
|
return;
|
|
47212
47505
|
}
|
|
47213
47506
|
const stat = lstatSync8(p);
|
|
47214
47507
|
if (stat.isSymbolicLink()) {
|
|
47215
47508
|
const targetRaw = readlinkSync4(p);
|
|
47216
|
-
const target = isAbsolute4(targetRaw) ? targetRaw :
|
|
47509
|
+
const target = isAbsolute4(targetRaw) ? targetRaw : resolve24(dirname54(p), targetRaw);
|
|
47217
47510
|
rmSync11(p);
|
|
47218
|
-
|
|
47219
|
-
if (
|
|
47511
|
+
mkdirSync58(p, { recursive: true });
|
|
47512
|
+
if (existsSync97(target) && statSync28(target).isDirectory()) {
|
|
47220
47513
|
for (const entry of readdirSync28(target)) {
|
|
47221
|
-
const src =
|
|
47222
|
-
const dest =
|
|
47514
|
+
const src = join98(target, entry);
|
|
47515
|
+
const dest = join98(p, entry);
|
|
47223
47516
|
const srcStat = lstatSync8(src);
|
|
47224
47517
|
if (srcStat.isDirectory()) {
|
|
47225
47518
|
try {
|
|
@@ -47241,8 +47534,8 @@ function postMergeSanitize(mergedText, label) {
|
|
|
47241
47534
|
return { ok: false, reason: `[post-merge-sanitize] ${label} merged output failed sanitizer: ${result.reason}` };
|
|
47242
47535
|
}
|
|
47243
47536
|
function mergeOne(upstreamPath, overlayPath, destPath2, label, dryRun, messages) {
|
|
47244
|
-
const upstreamText =
|
|
47245
|
-
const overlayText =
|
|
47537
|
+
const upstreamText = readFileSync85(upstreamPath, "utf8");
|
|
47538
|
+
const overlayText = readFileSync85(overlayPath, "utf8");
|
|
47246
47539
|
const result = mergeMarkdown(upstreamText, overlayText, label, upstreamPath, overlayPath);
|
|
47247
47540
|
if ("error" in result) {
|
|
47248
47541
|
messages.push(`ERROR ${result.error.reason}`);
|
|
@@ -47254,15 +47547,15 @@ function mergeOne(upstreamPath, overlayPath, destPath2, label, dryRun, messages)
|
|
|
47254
47547
|
return { ok: false, kind: "sanitize" };
|
|
47255
47548
|
}
|
|
47256
47549
|
if (!dryRun) {
|
|
47257
|
-
|
|
47258
|
-
|
|
47550
|
+
mkdirSync58(dirname54(destPath2), { recursive: true });
|
|
47551
|
+
writeFileSync51(destPath2, result.merged, "utf8");
|
|
47259
47552
|
}
|
|
47260
47553
|
messages.push(`MERGED ${label} \u2192 ${destPath2}${dryRun ? " (dry-run)" : ""}`);
|
|
47261
47554
|
return { ok: true };
|
|
47262
47555
|
}
|
|
47263
47556
|
function isNewAgentOverlay(overlayPath) {
|
|
47264
47557
|
try {
|
|
47265
|
-
const text =
|
|
47558
|
+
const text = readFileSync85(overlayPath, "utf8");
|
|
47266
47559
|
const { fm } = parseFrontmatter3(text);
|
|
47267
47560
|
return fm["overlay-intent"] === "new-agent";
|
|
47268
47561
|
} catch {
|
|
@@ -47271,18 +47564,18 @@ function isNewAgentOverlay(overlayPath) {
|
|
|
47271
47564
|
}
|
|
47272
47565
|
function copyNewAgent(overlayPath, destPath2, label, dryRun, messages) {
|
|
47273
47566
|
if (!dryRun) {
|
|
47274
|
-
|
|
47567
|
+
mkdirSync58(dirname54(destPath2), { recursive: true });
|
|
47275
47568
|
copyFileSync10(overlayPath, destPath2);
|
|
47276
47569
|
}
|
|
47277
47570
|
messages.push(`NEW-AGENT ${label} \u2192 ${destPath2}${dryRun ? " (dry-run)" : ""}`);
|
|
47278
47571
|
}
|
|
47279
47572
|
function walkSkillsOverlays(skillsOverridesDir, skillsDir, opts, result) {
|
|
47280
|
-
if (!
|
|
47573
|
+
if (!existsSync97(skillsOverridesDir)) return;
|
|
47281
47574
|
for (const skillName of readdirSync28(skillsOverridesDir)) {
|
|
47282
|
-
const overlaySkillDir =
|
|
47575
|
+
const overlaySkillDir = join98(skillsOverridesDir, skillName);
|
|
47283
47576
|
if (!statSync28(overlaySkillDir).isDirectory()) continue;
|
|
47284
|
-
const upstreamSkillDir =
|
|
47285
|
-
if (!
|
|
47577
|
+
const upstreamSkillDir = join98(skillsDir, skillName);
|
|
47578
|
+
if (!existsSync97(upstreamSkillDir)) {
|
|
47286
47579
|
result.messages.push(`SKIP ${skillName}: no upstream skill at ${upstreamSkillDir} (skill overlays require an upstream skill dir)`);
|
|
47287
47580
|
continue;
|
|
47288
47581
|
}
|
|
@@ -47295,7 +47588,7 @@ function walkOverlayTree(overlayRoot, upstreamRoot, labelPrefix, opts, result, i
|
|
|
47295
47588
|
while (stack.length > 0) {
|
|
47296
47589
|
const current = stack.pop();
|
|
47297
47590
|
for (const entry of readdirSync28(current)) {
|
|
47298
|
-
const overlayPath =
|
|
47591
|
+
const overlayPath = join98(current, entry);
|
|
47299
47592
|
const stat = lstatSync8(overlayPath);
|
|
47300
47593
|
if (stat.isDirectory()) {
|
|
47301
47594
|
stack.push(overlayPath);
|
|
@@ -47303,17 +47596,17 @@ function walkOverlayTree(overlayRoot, upstreamRoot, labelPrefix, opts, result, i
|
|
|
47303
47596
|
}
|
|
47304
47597
|
if (!stat.isFile() && !stat.isSymbolicLink()) continue;
|
|
47305
47598
|
const rel = relative5(overlayRoot, overlayPath);
|
|
47306
|
-
const upstreamPath =
|
|
47599
|
+
const upstreamPath = join98(upstreamRoot, rel);
|
|
47307
47600
|
const label = `${labelPrefix} ${rel}`;
|
|
47308
47601
|
if (!entry.endsWith(".md")) {
|
|
47309
47602
|
if (!opts.dryRun) {
|
|
47310
|
-
|
|
47603
|
+
mkdirSync58(dirname54(upstreamPath), { recursive: true });
|
|
47311
47604
|
copyFileSync10(overlayPath, upstreamPath);
|
|
47312
47605
|
}
|
|
47313
47606
|
result.messages.push(`COPY ${label} \u2192 ${upstreamPath}${opts.dryRun === true ? " (dry-run)" : ""}`);
|
|
47314
47607
|
continue;
|
|
47315
47608
|
}
|
|
47316
|
-
if (!
|
|
47609
|
+
if (!existsSync97(upstreamPath)) {
|
|
47317
47610
|
if (isAgentsContext && isNewAgentOverlay(overlayPath)) {
|
|
47318
47611
|
copyNewAgent(overlayPath, upstreamPath, label, opts.dryRun === true, result.messages);
|
|
47319
47612
|
result.newAgentsCreated += 1;
|
|
@@ -47322,7 +47615,7 @@ function walkOverlayTree(overlayRoot, upstreamRoot, labelPrefix, opts, result, i
|
|
|
47322
47615
|
result.renameHalts += 1;
|
|
47323
47616
|
} else {
|
|
47324
47617
|
if (!opts.dryRun) {
|
|
47325
|
-
|
|
47618
|
+
mkdirSync58(dirname54(upstreamPath), { recursive: true });
|
|
47326
47619
|
copyFileSync10(overlayPath, upstreamPath);
|
|
47327
47620
|
}
|
|
47328
47621
|
result.messages.push(`NEW-FILE ${label} \u2192 ${upstreamPath}${opts.dryRun === true ? " (dry-run)" : ""}`);
|
|
@@ -47342,16 +47635,16 @@ function walkOverlayTree(overlayRoot, upstreamRoot, labelPrefix, opts, result, i
|
|
|
47342
47635
|
}
|
|
47343
47636
|
}
|
|
47344
47637
|
function walkAgentsOverlays(agentsOverridesDir, agentsDir, opts, result) {
|
|
47345
|
-
if (!
|
|
47638
|
+
if (!existsSync97(agentsOverridesDir)) return;
|
|
47346
47639
|
ensureRealDir(agentsDir);
|
|
47347
47640
|
walkOverlayTree(agentsOverridesDir, agentsDir, "agent", opts, result, true);
|
|
47348
47641
|
}
|
|
47349
47642
|
async function applyOverlays(opts = {}) {
|
|
47350
47643
|
const root = claudeRoot(opts);
|
|
47351
|
-
const skillsDir =
|
|
47352
|
-
const agentsDir =
|
|
47353
|
-
const skillsOverridesDir =
|
|
47354
|
-
const agentsOverridesDir =
|
|
47644
|
+
const skillsDir = join98(root, "skills");
|
|
47645
|
+
const agentsDir = join98(root, "agents");
|
|
47646
|
+
const skillsOverridesDir = join98(root, "skills.overrides");
|
|
47647
|
+
const agentsOverridesDir = join98(root, "agents.overrides");
|
|
47355
47648
|
const result = {
|
|
47356
47649
|
rc: 0,
|
|
47357
47650
|
skillsMerged: 0,
|
|
@@ -47394,6 +47687,44 @@ function formatSummary(result) {
|
|
|
47394
47687
|
return lines.join("\n") + "\n";
|
|
47395
47688
|
}
|
|
47396
47689
|
|
|
47690
|
+
// src/commands/skills-install-model-router.ts
|
|
47691
|
+
init_model_router_deploy();
|
|
47692
|
+
init_output();
|
|
47693
|
+
function registerSkillsInstallModelRouter(skills) {
|
|
47694
|
+
skills.command("install-model-router").description("Deploy the model-router.py UserPromptSubmit hook script to ~/.claude/hooks/ (idempotent; auto-run by `olam skills sync`)").option("--dry-run", "preview the action without writing to disk").option("--target-dir <path>", "override target directory (default: ~/.claude/hooks/); for tests").option("--source-path <path>", "override canonical source path; for tests").action((opts) => {
|
|
47695
|
+
try {
|
|
47696
|
+
const result = deployModelRouterScript({
|
|
47697
|
+
...opts.sourcePath !== void 0 ? { sourcePath: opts.sourcePath } : {},
|
|
47698
|
+
...opts.targetDir !== void 0 ? { targetDir: opts.targetDir } : {},
|
|
47699
|
+
...opts.dryRun !== void 0 ? { dryRun: opts.dryRun } : {}
|
|
47700
|
+
});
|
|
47701
|
+
const dryRunSuffix = opts.dryRun === true ? " (dry-run)" : "";
|
|
47702
|
+
switch (result.action) {
|
|
47703
|
+
case "written":
|
|
47704
|
+
process.stdout.write(` WRITTEN ${result.targetPath}${dryRunSuffix}
|
|
47705
|
+
`);
|
|
47706
|
+
break;
|
|
47707
|
+
case "unchanged":
|
|
47708
|
+
process.stdout.write(` UNCHANGED ${result.targetPath}
|
|
47709
|
+
`);
|
|
47710
|
+
break;
|
|
47711
|
+
case "source-missing":
|
|
47712
|
+
printError(
|
|
47713
|
+
`canonical model-router.py source not found \u2014 olam install may be corrupt. Expected at packages/cli/hooks/model-router.py.`
|
|
47714
|
+
);
|
|
47715
|
+
process.exitCode = 2;
|
|
47716
|
+
return;
|
|
47717
|
+
}
|
|
47718
|
+
process.stdout.write(`
|
|
47719
|
+
model-router hook script ready at ${result.targetPath}
|
|
47720
|
+
`);
|
|
47721
|
+
} catch (err) {
|
|
47722
|
+
printError(`[install-model-router-error] ${err instanceof Error ? err.message : "unknown error"}`);
|
|
47723
|
+
process.exitCode = 2;
|
|
47724
|
+
}
|
|
47725
|
+
});
|
|
47726
|
+
}
|
|
47727
|
+
|
|
47397
47728
|
// src/commands/skills.ts
|
|
47398
47729
|
function asMessage4(err) {
|
|
47399
47730
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -47401,11 +47732,11 @@ function asMessage4(err) {
|
|
|
47401
47732
|
var ATLAS_USER_PICKER_RE = /^[a-z0-9][a-z0-9_-]{0,38}$/;
|
|
47402
47733
|
function listMemberNames(clonePath) {
|
|
47403
47734
|
const membersDir = path88.join(clonePath, "members");
|
|
47404
|
-
if (!
|
|
47735
|
+
if (!fs89.existsSync(membersDir)) return [];
|
|
47405
47736
|
try {
|
|
47406
|
-
return
|
|
47737
|
+
return fs89.readdirSync(membersDir).filter((e) => {
|
|
47407
47738
|
try {
|
|
47408
|
-
return
|
|
47739
|
+
return fs89.statSync(path88.join(membersDir, e)).isDirectory();
|
|
47409
47740
|
} catch {
|
|
47410
47741
|
return false;
|
|
47411
47742
|
}
|
|
@@ -47421,7 +47752,7 @@ function formatSourcePrefix(cfg) {
|
|
|
47421
47752
|
return `${p}${s}`;
|
|
47422
47753
|
}
|
|
47423
47754
|
function defaultSourcePrefixSyncPrompt(input2) {
|
|
47424
|
-
return new Promise((
|
|
47755
|
+
return new Promise((resolve31) => {
|
|
47425
47756
|
const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
|
|
47426
47757
|
const newLabel = formatSourcePrefix(input2.newConfig);
|
|
47427
47758
|
let line;
|
|
@@ -47438,16 +47769,16 @@ Accept change? ${pc38.dim("[Y/n] ")}`;
|
|
|
47438
47769
|
process.stdout.write(line);
|
|
47439
47770
|
rl.question("", (a) => {
|
|
47440
47771
|
rl.close();
|
|
47441
|
-
|
|
47772
|
+
resolve31(!/^n(o)?$/i.test(a.trim()));
|
|
47442
47773
|
});
|
|
47443
47774
|
});
|
|
47444
47775
|
}
|
|
47445
47776
|
function defaultAtlasUserPrompt(question) {
|
|
47446
|
-
return new Promise((
|
|
47777
|
+
return new Promise((resolve31) => {
|
|
47447
47778
|
const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
|
|
47448
47779
|
rl.question(question, (a) => {
|
|
47449
47780
|
rl.close();
|
|
47450
|
-
|
|
47781
|
+
resolve31(a);
|
|
47451
47782
|
});
|
|
47452
47783
|
});
|
|
47453
47784
|
}
|
|
@@ -47456,8 +47787,8 @@ async function resolveAtlasUserWithPicker(cliOverride, opts) {
|
|
|
47456
47787
|
const ATLAS_USER_RE2 = /^[a-z0-9][a-z0-9_-]{0,38}$/;
|
|
47457
47788
|
const claudeDirPathForRead = opts?._testClaudeDir ?? (process.env["OLAM_CLAUDE_DIR"] ?? path88.join(os50.homedir(), ".claude"));
|
|
47458
47789
|
const atlasUserFile = path88.join(claudeDirPathForRead, ".atlas-user");
|
|
47459
|
-
if (
|
|
47460
|
-
const existing =
|
|
47790
|
+
if (fs89.existsSync(atlasUserFile)) {
|
|
47791
|
+
const existing = fs89.readFileSync(atlasUserFile, "utf-8").trim();
|
|
47461
47792
|
if (existing.length > 0) {
|
|
47462
47793
|
if (ATLAS_USER_RE2.test(existing)) {
|
|
47463
47794
|
return existing;
|
|
@@ -47517,8 +47848,8 @@ async function resolveAtlasUserWithPicker(cliOverride, opts) {
|
|
|
47517
47848
|
return void 0;
|
|
47518
47849
|
}
|
|
47519
47850
|
const claudeDirPath = opts?._testClaudeDir ?? (process.env["OLAM_CLAUDE_DIR"] ?? path88.join(os50.homedir(), ".claude"));
|
|
47520
|
-
|
|
47521
|
-
|
|
47851
|
+
fs89.mkdirSync(claudeDirPath, { recursive: true });
|
|
47852
|
+
fs89.writeFileSync(path88.join(claudeDirPath, ".atlas-user"), picked + "\n", "utf8");
|
|
47522
47853
|
process.stdout.write(pc38.green(`\u2713 atlas-user set to "${picked}" (written to ${path88.join(claudeDirPath, ".atlas-user")})
|
|
47523
47854
|
`));
|
|
47524
47855
|
return picked;
|
|
@@ -47532,13 +47863,13 @@ function listDeployed() {
|
|
|
47532
47863
|
const entries = [];
|
|
47533
47864
|
for (const bucket of ["skills", "agents", "scripts", "rules", "commands"]) {
|
|
47534
47865
|
const bucketDir = path88.join(dir, bucket);
|
|
47535
|
-
if (!
|
|
47536
|
-
for (const name of
|
|
47866
|
+
if (!fs89.existsSync(bucketDir)) continue;
|
|
47867
|
+
for (const name of fs89.readdirSync(bucketDir)) {
|
|
47537
47868
|
const full = path88.join(bucketDir, name);
|
|
47538
47869
|
try {
|
|
47539
|
-
const stat =
|
|
47870
|
+
const stat = fs89.lstatSync(full);
|
|
47540
47871
|
if (!stat.isSymbolicLink()) continue;
|
|
47541
|
-
const target =
|
|
47872
|
+
const target = fs89.readlinkSync(full);
|
|
47542
47873
|
let sourceId;
|
|
47543
47874
|
for (const [clonePath, id] of sourcePaths.entries()) {
|
|
47544
47875
|
if (target.startsWith(clonePath)) {
|
|
@@ -47754,17 +48085,18 @@ function registerSkills(program2) {
|
|
|
47754
48085
|
process.exitCode = 2;
|
|
47755
48086
|
}
|
|
47756
48087
|
});
|
|
48088
|
+
registerSkillsInstallModelRouter(skills);
|
|
47757
48089
|
}
|
|
47758
48090
|
|
|
47759
48091
|
// src/commands/skills-hook.ts
|
|
47760
48092
|
init_skill_sources();
|
|
47761
48093
|
init_output();
|
|
47762
|
-
import * as
|
|
48094
|
+
import * as fs90 from "node:fs";
|
|
47763
48095
|
function backup(filePath) {
|
|
47764
|
-
if (!
|
|
48096
|
+
if (!fs90.existsSync(filePath)) return null;
|
|
47765
48097
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
47766
48098
|
const backupPath = `${filePath}.olam-bak.${ts}`;
|
|
47767
|
-
|
|
48099
|
+
fs90.copyFileSync(filePath, backupPath);
|
|
47768
48100
|
return backupPath;
|
|
47769
48101
|
}
|
|
47770
48102
|
function registerSkillsHook(program2) {
|
|
@@ -47812,7 +48144,7 @@ function registerSkillsHook(program2) {
|
|
|
47812
48144
|
printInfo("olam-skills hook", `not found in ${filePath} \u2014 already uninstalled`);
|
|
47813
48145
|
if (backupPath) {
|
|
47814
48146
|
try {
|
|
47815
|
-
|
|
48147
|
+
fs90.unlinkSync(backupPath);
|
|
47816
48148
|
} catch {
|
|
47817
48149
|
}
|
|
47818
48150
|
}
|
|
@@ -47999,24 +48331,24 @@ init_skill_sources();
|
|
|
47999
48331
|
init_merge_settings();
|
|
48000
48332
|
init_skill_sources();
|
|
48001
48333
|
init_output();
|
|
48002
|
-
import * as
|
|
48334
|
+
import * as fs91 from "node:fs";
|
|
48003
48335
|
import * as path89 from "node:path";
|
|
48004
48336
|
var MIGRATE_FROM_TOOLBOX_COMMAND = "migrate-from-toolbox";
|
|
48005
48337
|
function asMessage6(err) {
|
|
48006
48338
|
return err instanceof Error ? err.message : String(err);
|
|
48007
48339
|
}
|
|
48008
48340
|
function isOlamSkillsHookPresent(filePath) {
|
|
48009
|
-
if (!
|
|
48341
|
+
if (!fs91.existsSync(filePath)) return false;
|
|
48010
48342
|
try {
|
|
48011
|
-
const raw =
|
|
48343
|
+
const raw = fs91.readFileSync(filePath, "utf-8");
|
|
48012
48344
|
return raw.includes(OLAM_SKILLS_HOOK_SENTINEL);
|
|
48013
48345
|
} catch {
|
|
48014
48346
|
return false;
|
|
48015
48347
|
}
|
|
48016
48348
|
}
|
|
48017
48349
|
function uninstallLegacyToolboxSessionStartHook(filePath, toolboxPath) {
|
|
48018
|
-
if (!
|
|
48019
|
-
const raw =
|
|
48350
|
+
if (!fs91.existsSync(filePath)) return { removed: 0 };
|
|
48351
|
+
const raw = fs91.readFileSync(filePath, "utf-8");
|
|
48020
48352
|
const settings = raw.trim() ? JSON.parse(raw) : {};
|
|
48021
48353
|
const ss = settings?.hooks?.SessionStart;
|
|
48022
48354
|
if (!Array.isArray(ss)) return { removed: 0 };
|
|
@@ -48045,7 +48377,7 @@ function uninstallLegacyToolboxSessionStartHook(filePath, toolboxPath) {
|
|
|
48045
48377
|
if (otherStages.length === 0) delete next.hooks;
|
|
48046
48378
|
else delete next.hooks.SessionStart;
|
|
48047
48379
|
}
|
|
48048
|
-
|
|
48380
|
+
fs91.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
48049
48381
|
return { removed };
|
|
48050
48382
|
}
|
|
48051
48383
|
function registerSkillsMigrate(program2) {
|
|
@@ -48124,7 +48456,7 @@ function registerSkillsMigrate(program2) {
|
|
|
48124
48456
|
const scope = opts.scope === "user" ? "user" : "project";
|
|
48125
48457
|
const olamHookPath = scope === "user" ? settingsFile : path89.join(process.cwd(), ".claude", "settings.json");
|
|
48126
48458
|
try {
|
|
48127
|
-
|
|
48459
|
+
fs91.mkdirSync(path89.dirname(olamHookPath), { recursive: true });
|
|
48128
48460
|
const result = mergeHomeSettingsJson(olamHookPath, {
|
|
48129
48461
|
ensureHook: {
|
|
48130
48462
|
stage: OLAM_SKILLS_HOOK_STAGE,
|
|
@@ -48157,7 +48489,7 @@ function registerSkillsMigrate(program2) {
|
|
|
48157
48489
|
// src/commands/skills-migrate-back.ts
|
|
48158
48490
|
init_skill_sources();
|
|
48159
48491
|
init_output();
|
|
48160
|
-
import * as
|
|
48492
|
+
import * as fs92 from "node:fs";
|
|
48161
48493
|
import * as path90 from "node:path";
|
|
48162
48494
|
var MIGRATE_BACK_TO_TOOLBOX_COMMAND = "migrate-back-to-toolbox";
|
|
48163
48495
|
function asMessage7(err) {
|
|
@@ -48173,9 +48505,9 @@ function restoreSessionStartFromSnapshot(filePath, originalSessionStartHook) {
|
|
|
48173
48505
|
return { restored: false };
|
|
48174
48506
|
}
|
|
48175
48507
|
let settings;
|
|
48176
|
-
if (
|
|
48508
|
+
if (fs92.existsSync(filePath)) {
|
|
48177
48509
|
try {
|
|
48178
|
-
const raw =
|
|
48510
|
+
const raw = fs92.readFileSync(filePath, "utf-8");
|
|
48179
48511
|
settings = raw.trim() ? JSON.parse(raw) : {};
|
|
48180
48512
|
} catch {
|
|
48181
48513
|
settings = {};
|
|
@@ -48191,8 +48523,8 @@ function restoreSessionStartFromSnapshot(filePath, originalSessionStartHook) {
|
|
|
48191
48523
|
SessionStart: originalSessionStartHook
|
|
48192
48524
|
}
|
|
48193
48525
|
};
|
|
48194
|
-
|
|
48195
|
-
|
|
48526
|
+
fs92.mkdirSync(path90.dirname(filePath), { recursive: true });
|
|
48527
|
+
fs92.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
48196
48528
|
return { restored: true };
|
|
48197
48529
|
}
|
|
48198
48530
|
function removeOlamManagedSymlinks() {
|
|
@@ -48202,15 +48534,15 @@ function removeOlamManagedSymlinks() {
|
|
|
48202
48534
|
let removed = 0;
|
|
48203
48535
|
for (const bucket of ["skills", "agents", "scripts", "rules", "commands"]) {
|
|
48204
48536
|
const dir = path90.join(claude, bucket);
|
|
48205
|
-
if (!
|
|
48206
|
-
for (const name of
|
|
48537
|
+
if (!fs92.existsSync(dir)) continue;
|
|
48538
|
+
for (const name of fs92.readdirSync(dir)) {
|
|
48207
48539
|
const linkPath = path90.join(dir, name);
|
|
48208
48540
|
try {
|
|
48209
|
-
const stat =
|
|
48541
|
+
const stat = fs92.lstatSync(linkPath);
|
|
48210
48542
|
if (!stat.isSymbolicLink()) continue;
|
|
48211
|
-
const target =
|
|
48543
|
+
const target = fs92.readlinkSync(linkPath);
|
|
48212
48544
|
if (olamClonePaths.some((cp) => target.startsWith(cp))) {
|
|
48213
|
-
|
|
48545
|
+
fs92.unlinkSync(linkPath);
|
|
48214
48546
|
removed += 1;
|
|
48215
48547
|
}
|
|
48216
48548
|
} catch {
|
|
@@ -48223,18 +48555,18 @@ function restoreToolboxSymlinks(symlinks) {
|
|
|
48223
48555
|
let restored = 0;
|
|
48224
48556
|
for (const { link, target } of symlinks) {
|
|
48225
48557
|
try {
|
|
48226
|
-
|
|
48227
|
-
if (
|
|
48558
|
+
fs92.mkdirSync(path90.dirname(link), { recursive: true });
|
|
48559
|
+
if (fs92.existsSync(link) || (() => {
|
|
48228
48560
|
try {
|
|
48229
|
-
|
|
48561
|
+
fs92.lstatSync(link);
|
|
48230
48562
|
return true;
|
|
48231
48563
|
} catch {
|
|
48232
48564
|
return false;
|
|
48233
48565
|
}
|
|
48234
48566
|
})()) {
|
|
48235
|
-
|
|
48567
|
+
fs92.unlinkSync(link);
|
|
48236
48568
|
}
|
|
48237
|
-
|
|
48569
|
+
fs92.symlinkSync(target, link);
|
|
48238
48570
|
restored += 1;
|
|
48239
48571
|
} catch {
|
|
48240
48572
|
}
|
|
@@ -48244,8 +48576,8 @@ function restoreToolboxSymlinks(symlinks) {
|
|
|
48244
48576
|
function restoreAtlasUserMarker(atlasUser) {
|
|
48245
48577
|
if (!atlasUser) return false;
|
|
48246
48578
|
const file = path90.join(claudeDirInternal4(), ".atlas-user");
|
|
48247
|
-
|
|
48248
|
-
|
|
48579
|
+
fs92.mkdirSync(path90.dirname(file), { recursive: true });
|
|
48580
|
+
fs92.writeFileSync(file, atlasUser);
|
|
48249
48581
|
return true;
|
|
48250
48582
|
}
|
|
48251
48583
|
function registerSkillsMigrateBack(program2) {
|
|
@@ -48259,7 +48591,7 @@ function registerSkillsMigrateBack(program2) {
|
|
|
48259
48591
|
try {
|
|
48260
48592
|
if (opts.snapshot) {
|
|
48261
48593
|
snapshotPath = path90.resolve(opts.snapshot);
|
|
48262
|
-
if (!
|
|
48594
|
+
if (!fs92.existsSync(snapshotPath)) {
|
|
48263
48595
|
printError(`snapshot not found at ${snapshotPath}`);
|
|
48264
48596
|
process.exitCode = 1;
|
|
48265
48597
|
return;
|
|
@@ -48343,7 +48675,7 @@ init_meta_hooks_migration_snapshot();
|
|
|
48343
48675
|
init_trust_audit_log();
|
|
48344
48676
|
init_atlas_hook_strip();
|
|
48345
48677
|
init_output();
|
|
48346
|
-
import * as
|
|
48678
|
+
import * as fs93 from "node:fs";
|
|
48347
48679
|
import * as path91 from "node:path";
|
|
48348
48680
|
import pc40 from "picocolors";
|
|
48349
48681
|
var MIGRATE_HOOKS_COMMAND = "migrate-hooks";
|
|
@@ -48365,16 +48697,16 @@ function settingsHasOlamMetaSentinel(settings) {
|
|
|
48365
48697
|
return false;
|
|
48366
48698
|
}
|
|
48367
48699
|
function readSettings2(filePath) {
|
|
48368
|
-
if (!
|
|
48369
|
-
const raw =
|
|
48700
|
+
if (!fs93.existsSync(filePath)) return null;
|
|
48701
|
+
const raw = fs93.readFileSync(filePath, "utf-8");
|
|
48370
48702
|
if (raw.trim().length === 0) return {};
|
|
48371
48703
|
return JSON.parse(raw);
|
|
48372
48704
|
}
|
|
48373
48705
|
function writeSettings(filePath, settings) {
|
|
48374
|
-
|
|
48706
|
+
fs93.mkdirSync(path91.dirname(filePath), { recursive: true });
|
|
48375
48707
|
const tmp = `${filePath}.tmp-migrate-hooks-${process.pid}-${Date.now()}`;
|
|
48376
|
-
|
|
48377
|
-
|
|
48708
|
+
fs93.writeFileSync(tmp, JSON.stringify(settings, null, 2) + "\n");
|
|
48709
|
+
fs93.renameSync(tmp, filePath);
|
|
48378
48710
|
}
|
|
48379
48711
|
function printSummary(candidates2, opts) {
|
|
48380
48712
|
if (candidates2.length === 0) {
|
|
@@ -48509,7 +48841,7 @@ function registerSkillsMigrateHooksBack(program2) {
|
|
|
48509
48841
|
// src/commands/skills-shadow-backups.ts
|
|
48510
48842
|
init_skill_sources();
|
|
48511
48843
|
init_output();
|
|
48512
|
-
import * as
|
|
48844
|
+
import * as fs94 from "node:fs";
|
|
48513
48845
|
import pc41 from "picocolors";
|
|
48514
48846
|
function asMessage10(err) {
|
|
48515
48847
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -48592,7 +48924,7 @@ function registerSkillsShadowBackups(program2) {
|
|
|
48592
48924
|
});
|
|
48593
48925
|
sb.command("restore").description("Move a shadow-backup file back to its original path").argument("<path>", "Absolute path to the .shadow-backup-<epoch> file").option("--force", "Overwrite the original path if it already exists").action((p, opts) => {
|
|
48594
48926
|
try {
|
|
48595
|
-
if (!
|
|
48927
|
+
if (!fs94.existsSync(p)) {
|
|
48596
48928
|
printError(`backup file not found: ${p}`);
|
|
48597
48929
|
process.exitCode = 1;
|
|
48598
48930
|
return;
|
|
@@ -48615,11 +48947,11 @@ function asMessage11(err) {
|
|
|
48615
48947
|
return err instanceof Error ? err.message : String(err);
|
|
48616
48948
|
}
|
|
48617
48949
|
function defaultDoctorPrompt(question) {
|
|
48618
|
-
return new Promise((
|
|
48950
|
+
return new Promise((resolve31) => {
|
|
48619
48951
|
const rl = readline5.createInterface({ input: process.stdin, output: process.stdout });
|
|
48620
48952
|
rl.question(question, (a) => {
|
|
48621
48953
|
rl.close();
|
|
48622
|
-
|
|
48954
|
+
resolve31(a);
|
|
48623
48955
|
});
|
|
48624
48956
|
});
|
|
48625
48957
|
}
|
|
@@ -48710,23 +49042,26 @@ function registerSkillsDoctor(program2) {
|
|
|
48710
49042
|
});
|
|
48711
49043
|
}
|
|
48712
49044
|
|
|
48713
|
-
// src/commands/skills-
|
|
49045
|
+
// src/commands/skills-100x.ts
|
|
48714
49046
|
init_skill_sources();
|
|
48715
49047
|
init_cli_version();
|
|
48716
49048
|
init_output();
|
|
48717
49049
|
import { execFileSync as execFileSync17 } from "node:child_process";
|
|
48718
|
-
import * as
|
|
49050
|
+
import * as fs95 from "node:fs";
|
|
48719
49051
|
import * as path93 from "node:path";
|
|
48720
49052
|
var CHAIN_SKILL_NAMES = [
|
|
48721
|
-
"
|
|
48722
|
-
"
|
|
48723
|
-
"
|
|
48724
|
-
"
|
|
48725
|
-
"
|
|
48726
|
-
"
|
|
48727
|
-
"
|
|
48728
|
-
"
|
|
49053
|
+
"100x:brainstorm",
|
|
49054
|
+
"100x:plan-hard",
|
|
49055
|
+
"100x:review-plan",
|
|
49056
|
+
"100x:break-plan",
|
|
49057
|
+
"100x:commit-plan",
|
|
49058
|
+
"100x:execute",
|
|
49059
|
+
"100x:retro",
|
|
49060
|
+
"100x:learn"
|
|
48729
49061
|
];
|
|
49062
|
+
var PLUGIN_MARKETPLACE = "atlas-builders/atlas-toolbox";
|
|
49063
|
+
var PLUGIN_SPEC = "100x@atlas-one";
|
|
49064
|
+
var PLUGIN_SCOPES = ["user", "project", "local"];
|
|
48730
49065
|
function asMessage12(err) {
|
|
48731
49066
|
return err instanceof Error ? err.message : String(err);
|
|
48732
49067
|
}
|
|
@@ -48739,13 +49074,13 @@ function hasBeadsCli() {
|
|
|
48739
49074
|
}
|
|
48740
49075
|
}
|
|
48741
49076
|
function hasBeadsProjectInit(cwd) {
|
|
48742
|
-
return
|
|
49077
|
+
return fs95.existsSync(path93.join(cwd, ".beads"));
|
|
48743
49078
|
}
|
|
48744
49079
|
function hasBeadsClaudeSetup() {
|
|
48745
49080
|
const settingsPath = path93.join(claudeDir(), "settings.json");
|
|
48746
|
-
if (!
|
|
49081
|
+
if (!fs95.existsSync(settingsPath)) return false;
|
|
48747
49082
|
try {
|
|
48748
|
-
const content =
|
|
49083
|
+
const content = fs95.readFileSync(settingsPath, "utf8");
|
|
48749
49084
|
return /"command"\s*:\s*"bd\b/.test(content) || /"bd setup\b/.test(content);
|
|
48750
49085
|
} catch {
|
|
48751
49086
|
return false;
|
|
@@ -48782,6 +49117,37 @@ async function bootstrapBeads(cwd) {
|
|
|
48782
49117
|
console.log("beads Claude hooks already installed \u2014 skipping bd setup");
|
|
48783
49118
|
}
|
|
48784
49119
|
}
|
|
49120
|
+
function normalizeScope(raw) {
|
|
49121
|
+
if (raw === void 0) return "user";
|
|
49122
|
+
if (PLUGIN_SCOPES.includes(raw)) {
|
|
49123
|
+
return raw;
|
|
49124
|
+
}
|
|
49125
|
+
throw new Error(
|
|
49126
|
+
`invalid --scope '${raw}' \u2014 expected one of: ${PLUGIN_SCOPES.join(", ")}`
|
|
49127
|
+
);
|
|
49128
|
+
}
|
|
49129
|
+
function addPluginMarketplace(scope) {
|
|
49130
|
+
console.log(
|
|
49131
|
+
`claude plugin marketplace add ${PLUGIN_MARKETPLACE} (scope: ${scope})`
|
|
49132
|
+
);
|
|
49133
|
+
try {
|
|
49134
|
+
execFileSync17(
|
|
49135
|
+
"claude",
|
|
49136
|
+
["plugin", "marketplace", "add", PLUGIN_MARKETPLACE, "--scope", scope],
|
|
49137
|
+
{ stdio: "inherit" }
|
|
49138
|
+
);
|
|
49139
|
+
} catch (err) {
|
|
49140
|
+
printWarning(
|
|
49141
|
+
`claude plugin marketplace add returned an error (continuing \u2014 likely already added): ${asMessage12(err)}`
|
|
49142
|
+
);
|
|
49143
|
+
}
|
|
49144
|
+
}
|
|
49145
|
+
function installPlugin(scope) {
|
|
49146
|
+
console.log(`claude plugin install ${PLUGIN_SPEC} (scope: ${scope})`);
|
|
49147
|
+
execFileSync17("claude", ["plugin", "install", PLUGIN_SPEC, "--scope", scope], {
|
|
49148
|
+
stdio: "inherit"
|
|
49149
|
+
});
|
|
49150
|
+
}
|
|
48785
49151
|
function captureSourceShas() {
|
|
48786
49152
|
return listSkillSources().map((s) => ({
|
|
48787
49153
|
id: s.id,
|
|
@@ -48811,11 +49177,11 @@ function shortSha(sha) {
|
|
|
48811
49177
|
}
|
|
48812
49178
|
function listInstalledClaudeSkills() {
|
|
48813
49179
|
const skillsDir = path93.join(claudeDir(), "skills");
|
|
48814
|
-
if (!
|
|
49180
|
+
if (!fs95.existsSync(skillsDir)) return [];
|
|
48815
49181
|
try {
|
|
48816
|
-
return
|
|
49182
|
+
return fs95.readdirSync(skillsDir).filter((name) => {
|
|
48817
49183
|
try {
|
|
48818
|
-
const stat =
|
|
49184
|
+
const stat = fs95.lstatSync(path93.join(skillsDir, name));
|
|
48819
49185
|
return stat.isSymbolicLink() || stat.isDirectory();
|
|
48820
49186
|
} catch {
|
|
48821
49187
|
return false;
|
|
@@ -48828,24 +49194,64 @@ function listInstalledClaudeSkills() {
|
|
|
48828
49194
|
function isChainSkill(name) {
|
|
48829
49195
|
const lower = name.toLowerCase();
|
|
48830
49196
|
return CHAIN_SKILL_NAMES.some((canonical) => {
|
|
48831
|
-
const slug = canonical.replace(/^
|
|
48832
|
-
return lower === canonical.toLowerCase() || lower === slug || lower === `
|
|
49197
|
+
const slug = canonical.replace(/^100x:/, "");
|
|
49198
|
+
return lower === canonical.toLowerCase() || lower === slug || lower === `100x-${slug}` || // Legacy pre-rename forms (10x:slug / 10x-slug).
|
|
49199
|
+
lower === `10x:${slug}` || lower === `10x-${slug}`;
|
|
48833
49200
|
});
|
|
48834
49201
|
}
|
|
48835
|
-
function
|
|
48836
|
-
|
|
48837
|
-
|
|
48838
|
-
|
|
49202
|
+
function registerSkills100x(program2) {
|
|
49203
|
+
registerTopLevel100x(program2);
|
|
49204
|
+
registerDeprecatedSkills10xAlias(program2);
|
|
49205
|
+
}
|
|
49206
|
+
function registerTopLevel100x(program2) {
|
|
49207
|
+
const onex = program2.command("100x").description(
|
|
49208
|
+
"Install the /100x: planning chain as a native Claude Code plugin + beads integration"
|
|
48839
49209
|
);
|
|
49210
|
+
onex.command("install").description(
|
|
49211
|
+
"Install the native Claude Code plugin (claude plugin marketplace add + plugin install) + auto-bootstrap beads (bd init + bd setup claude)."
|
|
49212
|
+
).option("--no-beads", "Skip beads auto-bootstrap (plugin install only)").option(
|
|
49213
|
+
"--scope <scope>",
|
|
49214
|
+
"Plugin scope passed through to claude (user|project|local)",
|
|
49215
|
+
"user"
|
|
49216
|
+
).action(async (opts) => {
|
|
49217
|
+
try {
|
|
49218
|
+
const scope = normalizeScope(opts.scope);
|
|
49219
|
+
console.log(
|
|
49220
|
+
"Installing the /100x: chain via the native Claude Code plugin..."
|
|
49221
|
+
);
|
|
49222
|
+
addPluginMarketplace(scope);
|
|
49223
|
+
installPlugin(scope);
|
|
49224
|
+
printSuccess(`Installed plugin ${PLUGIN_SPEC} (scope: ${scope})`);
|
|
49225
|
+
if (opts.beads !== false) {
|
|
49226
|
+
await bootstrapBeads(process.cwd());
|
|
49227
|
+
} else {
|
|
49228
|
+
console.log("--no-beads \u2014 skipping beads auto-bootstrap");
|
|
49229
|
+
}
|
|
49230
|
+
printSuccess("olam 100x install complete");
|
|
49231
|
+
} catch (err) {
|
|
49232
|
+
printError(`Install failed: ${asMessage12(err)}`);
|
|
49233
|
+
process.exitCode = 1;
|
|
49234
|
+
}
|
|
49235
|
+
});
|
|
49236
|
+
}
|
|
49237
|
+
function registerDeprecatedSkills10xAlias(program2) {
|
|
49238
|
+
const skills = program2.commands.find((c) => c.name() === "skills") ?? program2.command("skills").description("Manage skill sources and synchronization");
|
|
49239
|
+
const tenx = skills.command("10x", { hidden: true }).description(
|
|
49240
|
+
"DEPRECATED \u2014 use `olam 100x install`. Manage the /100x: planning chain skills via syncSkills() + beads."
|
|
49241
|
+
).hook("preAction", () => {
|
|
49242
|
+
printWarning(
|
|
49243
|
+
"DEPRECATED: `olam skills 10x` \u2014 use `olam 100x install` (native Claude Code plugin) instead."
|
|
49244
|
+
);
|
|
49245
|
+
});
|
|
48840
49246
|
tenx.command("install").description(
|
|
48841
|
-
"Sync /
|
|
49247
|
+
"Sync /100x: chain skills from registered sources + auto-bootstrap beads (bd init + bd setup claude). Surfaces source-SHA bumps + shadow-backups for sentinel-versioned upgrade."
|
|
48842
49248
|
).option("--no-beads", "Skip beads auto-bootstrap (chain skills only)").option(
|
|
48843
49249
|
"--force",
|
|
48844
49250
|
"Suppress shadow-backup warning + proceed without operator attention (shadow backups are still created by the sync engine; this flag only suppresses the surface-prominence)"
|
|
48845
49251
|
).action(async (opts) => {
|
|
48846
49252
|
try {
|
|
48847
49253
|
const preSync = captureSourceShas();
|
|
48848
|
-
console.log("Syncing /
|
|
49254
|
+
console.log("Syncing /100x: chain skills from registered sources...");
|
|
48849
49255
|
const summary2 = await syncSkills({});
|
|
48850
49256
|
printSuccess(
|
|
48851
49257
|
`Synced ${summary2.artifactCount} artifact(s) from ${summary2.sourceCount} source(s)`
|
|
@@ -48888,43 +49294,43 @@ function registerSkills10x(program2) {
|
|
|
48888
49294
|
}
|
|
48889
49295
|
});
|
|
48890
49296
|
tenx.command("uninstall").description(
|
|
48891
|
-
"Remove /
|
|
49297
|
+
"Remove /100x: chain skill symlinks from ~/.claude/skills (preserves user-authored skills + non-chain skill sources)"
|
|
48892
49298
|
).action(() => {
|
|
48893
49299
|
const skillsDir = path93.join(claudeDir(), "skills");
|
|
48894
|
-
if (!
|
|
49300
|
+
if (!fs95.existsSync(skillsDir)) {
|
|
48895
49301
|
printWarning("No ~/.claude/skills/ directory found; nothing to uninstall");
|
|
48896
49302
|
return;
|
|
48897
49303
|
}
|
|
48898
49304
|
let removed = 0;
|
|
48899
|
-
for (const name of
|
|
49305
|
+
for (const name of fs95.readdirSync(skillsDir)) {
|
|
48900
49306
|
const full = path93.join(skillsDir, name);
|
|
48901
49307
|
try {
|
|
48902
|
-
const stat =
|
|
49308
|
+
const stat = fs95.lstatSync(full);
|
|
48903
49309
|
if (!stat.isSymbolicLink()) continue;
|
|
48904
|
-
const target =
|
|
48905
|
-
if (isChainSkill(name) || /\/10x[-:]/.test(target)) {
|
|
48906
|
-
|
|
49310
|
+
const target = fs95.readlinkSync(full);
|
|
49311
|
+
if (isChainSkill(name) || /\/(100x|10x)[-:]/.test(target)) {
|
|
49312
|
+
fs95.unlinkSync(full);
|
|
48907
49313
|
removed += 1;
|
|
48908
49314
|
}
|
|
48909
49315
|
} catch {
|
|
48910
49316
|
}
|
|
48911
49317
|
}
|
|
48912
|
-
printSuccess(`Removed ${removed} /
|
|
49318
|
+
printSuccess(`Removed ${removed} /100x: chain skill symlink(s)`);
|
|
48913
49319
|
console.log("User-authored + non-chain skill sources preserved");
|
|
48914
49320
|
});
|
|
48915
49321
|
tenx.command("doctor").description(
|
|
48916
|
-
"Diagnose /
|
|
49322
|
+
"Diagnose /100x: chain skill installation + beads bootstrap state"
|
|
48917
49323
|
).action(() => {
|
|
48918
|
-
console.log("=== /
|
|
49324
|
+
console.log("=== /100x: chain skills + beads health ===");
|
|
48919
49325
|
const installed = listInstalledClaudeSkills();
|
|
48920
49326
|
const chainInstalled = installed.filter(isChainSkill);
|
|
48921
49327
|
console.log(
|
|
48922
|
-
` /
|
|
49328
|
+
` /100x: chain skills: ${chainInstalled.length} / ${CHAIN_SKILL_NAMES.length} installed`
|
|
48923
49329
|
);
|
|
48924
49330
|
for (const canonical of CHAIN_SKILL_NAMES) {
|
|
48925
|
-
const slug = canonical.replace(/^
|
|
49331
|
+
const slug = canonical.replace(/^100x:/, "");
|
|
48926
49332
|
const found = installed.some(
|
|
48927
|
-
(n) => n.toLowerCase() === canonical.toLowerCase() || n.toLowerCase() === slug || n.toLowerCase() === `10x-${slug}`
|
|
49333
|
+
(n) => n.toLowerCase() === canonical.toLowerCase() || n.toLowerCase() === slug || n.toLowerCase() === `100x-${slug}` || n.toLowerCase() === `10x:${slug}` || n.toLowerCase() === `10x-${slug}`
|
|
48928
49334
|
);
|
|
48929
49335
|
console.log(` ${found ? "\u2713" : "\u2717"} ${canonical}`);
|
|
48930
49336
|
}
|
|
@@ -48937,11 +49343,11 @@ function registerSkills10x(program2) {
|
|
|
48937
49343
|
const allChainPresent = chainInstalled.length === CHAIN_SKILL_NAMES.length;
|
|
48938
49344
|
const allOk = allChainPresent && bdCli && bdInit && bdHooks;
|
|
48939
49345
|
if (allOk) {
|
|
48940
|
-
printSuccess("All /
|
|
49346
|
+
printSuccess("All /100x: chain skill + beads checks pass");
|
|
48941
49347
|
return;
|
|
48942
49348
|
}
|
|
48943
49349
|
const fixHints = [];
|
|
48944
|
-
if (!allChainPresent) fixHints.push("olam
|
|
49350
|
+
if (!allChainPresent) fixHints.push("olam 100x install");
|
|
48945
49351
|
if (!bdCli) fixHints.push("brew install beads OR npm i -g @beads/bd");
|
|
48946
49352
|
if (!bdInit) fixHints.push("bd init");
|
|
48947
49353
|
if (!bdHooks) fixHints.push("bd setup claude");
|
|
@@ -48955,7 +49361,7 @@ function registerSkills10x(program2) {
|
|
|
48955
49361
|
const olamVersion = readCliVersion();
|
|
48956
49362
|
const sources = listSkillSources();
|
|
48957
49363
|
console.log(`olam-cli: ${olamVersion}`);
|
|
48958
|
-
console.log(`chain canonical: ${CHAIN_SKILL_NAMES.length} skills (/
|
|
49364
|
+
console.log(`chain canonical: ${CHAIN_SKILL_NAMES.length} skills (/100x: chain)`);
|
|
48959
49365
|
console.log(`registered sources: ${sources.length}`);
|
|
48960
49366
|
for (const s of sources) {
|
|
48961
49367
|
const shortId = s.id ? s.id.slice(0, 8) : "????????";
|
|
@@ -48971,7 +49377,7 @@ function registerSkills10x(program2) {
|
|
|
48971
49377
|
|
|
48972
49378
|
// src/commands/hermes.ts
|
|
48973
49379
|
init_output();
|
|
48974
|
-
import * as
|
|
49380
|
+
import * as fs96 from "node:fs";
|
|
48975
49381
|
import * as os51 from "node:os";
|
|
48976
49382
|
import * as path94 from "node:path";
|
|
48977
49383
|
import * as child_process from "node:child_process";
|
|
@@ -48986,7 +49392,7 @@ function claudeSkillsDir() {
|
|
|
48986
49392
|
return path94.join(os51.homedir(), ".claude", "skills");
|
|
48987
49393
|
}
|
|
48988
49394
|
function readHermesConfig(configPath) {
|
|
48989
|
-
const raw =
|
|
49395
|
+
const raw = fs96.readFileSync(configPath, "utf-8");
|
|
48990
49396
|
const parsed = yamlParse2(raw);
|
|
48991
49397
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
48992
49398
|
throw new Error(`${configPath} is not a YAML mapping`);
|
|
@@ -48994,13 +49400,13 @@ function readHermesConfig(configPath) {
|
|
|
48994
49400
|
return parsed;
|
|
48995
49401
|
}
|
|
48996
49402
|
function writeHermesConfig(configPath, config) {
|
|
48997
|
-
|
|
49403
|
+
fs96.writeFileSync(configPath, yamlStringify3(config), "utf-8");
|
|
48998
49404
|
}
|
|
48999
49405
|
function resolveOlamBinary() {
|
|
49000
49406
|
try {
|
|
49001
49407
|
const result = child_process.spawnSync("which", ["olam"], { encoding: "utf-8" });
|
|
49002
49408
|
const found = result.stdout.trim();
|
|
49003
|
-
if (found &&
|
|
49409
|
+
if (found && fs96.existsSync(found)) return found;
|
|
49004
49410
|
} catch {
|
|
49005
49411
|
}
|
|
49006
49412
|
return process.argv[1] ?? "olam";
|
|
@@ -49013,7 +49419,7 @@ function resolveWorkspaceDir() {
|
|
|
49013
49419
|
{ encoding: "utf-8" }
|
|
49014
49420
|
);
|
|
49015
49421
|
const out = result.stdout.trim();
|
|
49016
|
-
if (out &&
|
|
49422
|
+
if (out && fs96.existsSync(out)) return out;
|
|
49017
49423
|
} catch {
|
|
49018
49424
|
}
|
|
49019
49425
|
return process.cwd();
|
|
@@ -49083,22 +49489,22 @@ function ensureTerminalBackendLocal(config, dryRun, summary2) {
|
|
|
49083
49489
|
}
|
|
49084
49490
|
function mirrorSkillSymlinks(dryRun, summary2) {
|
|
49085
49491
|
const srcDir = claudeSkillsDir();
|
|
49086
|
-
if (!
|
|
49492
|
+
if (!fs96.existsSync(srcDir)) {
|
|
49087
49493
|
summary2.skipped.push("skills mirror (no ~/.claude/skills/ found)");
|
|
49088
49494
|
return;
|
|
49089
49495
|
}
|
|
49090
49496
|
const destDir = hermesSkillsDir();
|
|
49091
49497
|
if (!dryRun) {
|
|
49092
|
-
|
|
49498
|
+
fs96.mkdirSync(destDir, { recursive: true });
|
|
49093
49499
|
}
|
|
49094
|
-
const entries =
|
|
49500
|
+
const entries = fs96.readdirSync(srcDir);
|
|
49095
49501
|
let mirrored = 0;
|
|
49096
49502
|
let collisions = 0;
|
|
49097
49503
|
for (const entry of entries) {
|
|
49098
49504
|
const srcPath = path94.join(srcDir, entry);
|
|
49099
49505
|
const destPath2 = path94.join(destDir, entry);
|
|
49100
|
-
if (
|
|
49101
|
-
if (
|
|
49506
|
+
if (fs96.existsSync(destPath2) || fs96.lstatSync(srcPath).isFile()) {
|
|
49507
|
+
if (fs96.existsSync(destPath2)) collisions++;
|
|
49102
49508
|
continue;
|
|
49103
49509
|
}
|
|
49104
49510
|
if (dryRun) {
|
|
@@ -49106,7 +49512,7 @@ function mirrorSkillSymlinks(dryRun, summary2) {
|
|
|
49106
49512
|
continue;
|
|
49107
49513
|
}
|
|
49108
49514
|
try {
|
|
49109
|
-
|
|
49515
|
+
fs96.symlinkSync(srcPath, destPath2);
|
|
49110
49516
|
mirrored++;
|
|
49111
49517
|
} catch (err) {
|
|
49112
49518
|
printWarning(`skills mirror: skipping ${entry} \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -49125,7 +49531,7 @@ async function runHermesBootstrap(opts, deps = {}) {
|
|
|
49125
49531
|
const writeConfig2 = deps.writeConfig ?? writeHermesConfig;
|
|
49126
49532
|
const mirrorSkillsFn = deps.mirrorSkills ?? mirrorSkillSymlinks;
|
|
49127
49533
|
const installHookFn = deps.installHook ?? installKgFirstHookForHermes;
|
|
49128
|
-
if (!
|
|
49534
|
+
if (!fs96.existsSync(configPath)) {
|
|
49129
49535
|
printError(`~/.hermes/config.yaml not found at ${configPath}`);
|
|
49130
49536
|
printInfo(
|
|
49131
49537
|
"remedy",
|
|
@@ -49242,7 +49648,7 @@ function registerStop(program2) {
|
|
|
49242
49648
|
}
|
|
49243
49649
|
|
|
49244
49650
|
// src/lib/upgrade-check.ts
|
|
49245
|
-
import * as
|
|
49651
|
+
import * as fs97 from "node:fs";
|
|
49246
49652
|
import * as os52 from "node:os";
|
|
49247
49653
|
import * as path95 from "node:path";
|
|
49248
49654
|
var UPGRADE_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -49261,7 +49667,7 @@ function isNewer(latest, current) {
|
|
|
49261
49667
|
}
|
|
49262
49668
|
function readCache(cachePath) {
|
|
49263
49669
|
try {
|
|
49264
|
-
const raw =
|
|
49670
|
+
const raw = fs97.readFileSync(cachePath, "utf-8");
|
|
49265
49671
|
const parsed = JSON.parse(raw);
|
|
49266
49672
|
if (typeof parsed === "object" && parsed !== null && typeof parsed["checkedAt"] === "number" && typeof parsed["latestVersion"] === "string") {
|
|
49267
49673
|
return parsed;
|
|
@@ -49273,8 +49679,8 @@ function readCache(cachePath) {
|
|
|
49273
49679
|
function writeCache(cachePath, data) {
|
|
49274
49680
|
try {
|
|
49275
49681
|
const dir = path95.dirname(cachePath);
|
|
49276
|
-
|
|
49277
|
-
|
|
49682
|
+
fs97.mkdirSync(dir, { recursive: true });
|
|
49683
|
+
fs97.writeFileSync(cachePath, JSON.stringify(data), "utf-8");
|
|
49278
49684
|
} catch {
|
|
49279
49685
|
}
|
|
49280
49686
|
}
|
|
@@ -49417,17 +49823,17 @@ function registerWorldUpgrade(program2) {
|
|
|
49417
49823
|
|
|
49418
49824
|
// src/commands/mcp/serve.ts
|
|
49419
49825
|
init_output();
|
|
49420
|
-
import { existsSync as
|
|
49421
|
-
import { dirname as
|
|
49422
|
-
import { fileURLToPath as
|
|
49423
|
-
var here2 =
|
|
49826
|
+
import { existsSync as existsSync106 } from "node:fs";
|
|
49827
|
+
import { dirname as dirname60, resolve as resolve27 } from "node:path";
|
|
49828
|
+
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
49829
|
+
var here2 = dirname60(fileURLToPath10(import.meta.url));
|
|
49424
49830
|
var BUNDLE_PATH_CANDIDATES = [
|
|
49425
49831
|
// bundled (`dist/index.js` after bundle-cli.mjs) — sibling
|
|
49426
|
-
|
|
49832
|
+
resolve27(here2, "mcp-server.js"),
|
|
49427
49833
|
// dev / tsc-only (`dist/commands/mcp/serve.js`) — up two levels
|
|
49428
|
-
|
|
49834
|
+
resolve27(here2, "..", "..", "mcp-server.js")
|
|
49429
49835
|
];
|
|
49430
|
-
function resolveBundlePath(candidates2 = BUNDLE_PATH_CANDIDATES, exists =
|
|
49836
|
+
function resolveBundlePath(candidates2 = BUNDLE_PATH_CANDIDATES, exists = existsSync106) {
|
|
49431
49837
|
return candidates2.find(exists) ?? null;
|
|
49432
49838
|
}
|
|
49433
49839
|
var MISSING_BUNDLE_REMEDY = "olam mcp server bundle missing. Searched: " + BUNDLE_PATH_CANDIDATES.join(", ") + ". For local dev, run: node packages/cli/scripts/bundle-mcp-server.mjs. A fresh `npm install -g @pleri/olam-cli@latest` should always include the bundle (see prepublishOnly in packages/cli/package.json); file an issue if it does not.";
|
|
@@ -49691,7 +50097,7 @@ function registerMcpComplete(cmd) {
|
|
|
49691
50097
|
init_output();
|
|
49692
50098
|
import * as readline6 from "node:readline";
|
|
49693
50099
|
async function readTokenSilent(prompt) {
|
|
49694
|
-
return new Promise((
|
|
50100
|
+
return new Promise((resolve31, reject) => {
|
|
49695
50101
|
const rl = readline6.createInterface({
|
|
49696
50102
|
input: process.stdin,
|
|
49697
50103
|
output: process.stdout,
|
|
@@ -49709,7 +50115,7 @@ async function readTokenSilent(prompt) {
|
|
|
49709
50115
|
process.stdin.removeListener("data", onData);
|
|
49710
50116
|
process.stdout.write("\n");
|
|
49711
50117
|
rl.close();
|
|
49712
|
-
|
|
50118
|
+
resolve31(token);
|
|
49713
50119
|
} else if (char === "") {
|
|
49714
50120
|
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
49715
50121
|
process.stdin.removeListener("data", onData);
|
|
@@ -49864,12 +50270,12 @@ import * as readline7 from "node:readline";
|
|
|
49864
50270
|
import pc45 from "picocolors";
|
|
49865
50271
|
|
|
49866
50272
|
// src/commands/mcp/import-discovery.ts
|
|
49867
|
-
import * as
|
|
50273
|
+
import * as fs98 from "node:fs";
|
|
49868
50274
|
import * as os53 from "node:os";
|
|
49869
50275
|
import * as path96 from "node:path";
|
|
49870
50276
|
function readJsonFile(filePath) {
|
|
49871
50277
|
try {
|
|
49872
|
-
const raw =
|
|
50278
|
+
const raw = fs98.readFileSync(filePath, "utf-8");
|
|
49873
50279
|
return JSON.parse(raw);
|
|
49874
50280
|
} catch {
|
|
49875
50281
|
return null;
|
|
@@ -49913,9 +50319,9 @@ function getOlamRepoPaths() {
|
|
|
49913
50319
|
];
|
|
49914
50320
|
const paths = [];
|
|
49915
50321
|
for (const configPath of configPaths) {
|
|
49916
|
-
if (!
|
|
50322
|
+
if (!fs98.existsSync(configPath)) continue;
|
|
49917
50323
|
try {
|
|
49918
|
-
const raw =
|
|
50324
|
+
const raw = fs98.readFileSync(configPath, "utf-8");
|
|
49919
50325
|
const repoMatches = [...raw.matchAll(/path:\s*["']?([^\s"'\n]+)/g)];
|
|
49920
50326
|
for (const m of repoMatches) {
|
|
49921
50327
|
if (m[1]) paths.push(m[1]);
|
|
@@ -49984,7 +50390,7 @@ async function discoverMcpSources(repoPaths) {
|
|
|
49984
50390
|
import { spawn as spawn10 } from "node:child_process";
|
|
49985
50391
|
var VALIDATION_TIMEOUT_MS = 5e3;
|
|
49986
50392
|
async function validateMcpEntry(entry) {
|
|
49987
|
-
return new Promise((
|
|
50393
|
+
return new Promise((resolve31) => {
|
|
49988
50394
|
let stdout = "";
|
|
49989
50395
|
let timedOut = false;
|
|
49990
50396
|
let child;
|
|
@@ -49994,7 +50400,7 @@ async function validateMcpEntry(entry) {
|
|
|
49994
50400
|
env: { ...process.env, ...entry.env ?? {} }
|
|
49995
50401
|
});
|
|
49996
50402
|
} catch (err) {
|
|
49997
|
-
|
|
50403
|
+
resolve31({
|
|
49998
50404
|
name: entry.name,
|
|
49999
50405
|
validated: false,
|
|
50000
50406
|
reason: err instanceof Error ? err.message : "spawn failed"
|
|
@@ -50011,11 +50417,11 @@ async function validateMcpEntry(entry) {
|
|
|
50011
50417
|
child.on("close", (code) => {
|
|
50012
50418
|
clearTimeout(timer);
|
|
50013
50419
|
if (timedOut) {
|
|
50014
|
-
|
|
50420
|
+
resolve31({ name: entry.name, validated: false, reason: "timeout (5s)" });
|
|
50015
50421
|
return;
|
|
50016
50422
|
}
|
|
50017
50423
|
const validated = code === 0 && stdout.trim().length > 0;
|
|
50018
|
-
|
|
50424
|
+
resolve31({
|
|
50019
50425
|
name: entry.name,
|
|
50020
50426
|
validated,
|
|
50021
50427
|
reason: validated ? "ok" : `exit code ${code ?? "null"}`
|
|
@@ -50023,7 +50429,7 @@ async function validateMcpEntry(entry) {
|
|
|
50023
50429
|
});
|
|
50024
50430
|
child.on("error", (err) => {
|
|
50025
50431
|
clearTimeout(timer);
|
|
50026
|
-
|
|
50432
|
+
resolve31({ name: entry.name, validated: false, reason: err.message });
|
|
50027
50433
|
});
|
|
50028
50434
|
});
|
|
50029
50435
|
}
|
|
@@ -50038,11 +50444,11 @@ async function multiSelectPicker(entries) {
|
|
|
50038
50444
|
);
|
|
50039
50445
|
});
|
|
50040
50446
|
console.log("\n" + pc45.dim('Enter numbers to import (e.g. 1,2,3 or "all" or Enter to skip):'));
|
|
50041
|
-
const answer = await new Promise((
|
|
50447
|
+
const answer = await new Promise((resolve31) => {
|
|
50042
50448
|
const rl = readline7.createInterface({ input: process.stdin, output: process.stdout });
|
|
50043
50449
|
rl.question("> ", (ans) => {
|
|
50044
50450
|
rl.close();
|
|
50045
|
-
|
|
50451
|
+
resolve31(ans.trim());
|
|
50046
50452
|
});
|
|
50047
50453
|
});
|
|
50048
50454
|
if (!answer || answer === "") return [];
|
|
@@ -50189,14 +50595,14 @@ init_output();
|
|
|
50189
50595
|
|
|
50190
50596
|
// src/lib/memory-host-process-migration.ts
|
|
50191
50597
|
init_paths2();
|
|
50192
|
-
import { existsSync as
|
|
50598
|
+
import { existsSync as existsSync108, readFileSync as readFileSync94, unlinkSync as unlinkSync23 } from "node:fs";
|
|
50193
50599
|
import { spawnSync as spawnSync31 } from "node:child_process";
|
|
50194
50600
|
var KILL_TIMEOUT_MS = 5e3;
|
|
50195
50601
|
function migrateFromHostProcess(opts = {}) {
|
|
50196
50602
|
const pidPath2 = opts.pidPath ?? MEMORY_PID_PATH;
|
|
50197
50603
|
const logPath = opts.logPath ?? MEMORY_LOG_PATH;
|
|
50198
|
-
const pidfileExists =
|
|
50199
|
-
const logExists =
|
|
50604
|
+
const pidfileExists = existsSync108(pidPath2);
|
|
50605
|
+
const logExists = existsSync108(logPath);
|
|
50200
50606
|
if (!pidfileExists && !logExists) {
|
|
50201
50607
|
return { cleaned: false, summary: "no legacy host-process state to clean" };
|
|
50202
50608
|
}
|
|
@@ -50235,7 +50641,7 @@ function migrateFromHostProcess(opts = {}) {
|
|
|
50235
50641
|
}
|
|
50236
50642
|
function readPidFromFile(pidPath2) {
|
|
50237
50643
|
try {
|
|
50238
|
-
const raw =
|
|
50644
|
+
const raw = readFileSync94(pidPath2, "utf8").trim();
|
|
50239
50645
|
const pid = parseInt(raw, 10);
|
|
50240
50646
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
50241
50647
|
return pid;
|
|
@@ -50365,7 +50771,7 @@ function registerMemoryStop(cmd) {
|
|
|
50365
50771
|
init_output();
|
|
50366
50772
|
init_memory_secret();
|
|
50367
50773
|
init_paths2();
|
|
50368
|
-
import { existsSync as
|
|
50774
|
+
import { existsSync as existsSync109 } from "node:fs";
|
|
50369
50775
|
var RESTART_CHURN_THRESHOLD = 3;
|
|
50370
50776
|
async function probe(secret) {
|
|
50371
50777
|
try {
|
|
@@ -50392,7 +50798,7 @@ async function collectMemoryStatus() {
|
|
|
50392
50798
|
livez,
|
|
50393
50799
|
secretSet: hasMemorySecret(),
|
|
50394
50800
|
port: MEMORY_REST_PORT,
|
|
50395
|
-
legacyPidfilePresent:
|
|
50801
|
+
legacyPidfilePresent: existsSync109(MEMORY_PID_PATH),
|
|
50396
50802
|
startedAt: runtime?.startedAt ?? null,
|
|
50397
50803
|
restartCount: runtime?.restartCount ?? null,
|
|
50398
50804
|
health: runtime?.health ?? "unknown"
|
|
@@ -50479,8 +50885,8 @@ async function runMemoryLogs(opts) {
|
|
|
50479
50885
|
args.push(MEMORY_SERVICE_CONTAINER);
|
|
50480
50886
|
printHeader(`olam memory logs (${opts.follow ? "follow" : `tail -n ${tailN}`})`);
|
|
50481
50887
|
const child = spawn11("docker", args, { stdio: "inherit" });
|
|
50482
|
-
return new Promise((
|
|
50483
|
-
child.on("exit", (code) =>
|
|
50888
|
+
return new Promise((resolve31) => {
|
|
50889
|
+
child.on("exit", (code) => resolve31(code ?? 0));
|
|
50484
50890
|
});
|
|
50485
50891
|
}
|
|
50486
50892
|
function registerMemoryLogs(cmd) {
|
|
@@ -50616,14 +51022,14 @@ function registerMemoryUninstall(cmd) {
|
|
|
50616
51022
|
init_schema2();
|
|
50617
51023
|
init_output();
|
|
50618
51024
|
init_memory_secret();
|
|
50619
|
-
import { existsSync as
|
|
50620
|
-
import { join as
|
|
51025
|
+
import { existsSync as existsSync110, readFileSync as readFileSync95, writeFileSync as writeFileSync58 } from "node:fs";
|
|
51026
|
+
import { join as join106 } from "node:path";
|
|
50621
51027
|
import * as readline8 from "node:readline/promises";
|
|
50622
51028
|
import { parse as parseYaml9, stringify as stringifyYaml7 } from "yaml";
|
|
50623
51029
|
var CONFIG_REL = ".olam/config.yaml";
|
|
50624
51030
|
function locateConfig(cwd) {
|
|
50625
|
-
const absPath =
|
|
50626
|
-
if (!
|
|
51031
|
+
const absPath = join106(cwd, CONFIG_REL);
|
|
51032
|
+
if (!existsSync110(absPath)) {
|
|
50627
51033
|
throw new Error(
|
|
50628
51034
|
`No ${CONFIG_REL} at ${cwd}. Run \`olam init\` in your workspace root first.`
|
|
50629
51035
|
);
|
|
@@ -50631,7 +51037,7 @@ function locateConfig(cwd) {
|
|
|
50631
51037
|
return { absPath };
|
|
50632
51038
|
}
|
|
50633
51039
|
function readConfigYaml(absPath) {
|
|
50634
|
-
const raw =
|
|
51040
|
+
const raw = readFileSync95(absPath, "utf-8");
|
|
50635
51041
|
const parsed = parseYaml9(raw) ?? {};
|
|
50636
51042
|
if (typeof parsed !== "object" || parsed === null) {
|
|
50637
51043
|
throw new Error(`${absPath} is not a YAML object`);
|
|
@@ -50640,7 +51046,7 @@ function readConfigYaml(absPath) {
|
|
|
50640
51046
|
}
|
|
50641
51047
|
function writeConfigYaml(absPath, parsed) {
|
|
50642
51048
|
const out = stringifyYaml7(parsed, { aliasDuplicateObjects: false });
|
|
50643
|
-
|
|
51049
|
+
writeFileSync58(absPath, out, "utf-8");
|
|
50644
51050
|
}
|
|
50645
51051
|
async function defaultPromptText(question) {
|
|
50646
51052
|
const rl = readline8.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -50761,20 +51167,20 @@ init_output();
|
|
|
50761
51167
|
init_memory_secret();
|
|
50762
51168
|
init_paths2();
|
|
50763
51169
|
import { spawn as spawn12 } from "node:child_process";
|
|
50764
|
-
import { existsSync as
|
|
50765
|
-
import { join as
|
|
51170
|
+
import { existsSync as existsSync111 } from "node:fs";
|
|
51171
|
+
import { join as join107 } from "node:path";
|
|
50766
51172
|
var DEFAULT_PORT2 = 8788;
|
|
50767
51173
|
function resolveMemoryServiceDir() {
|
|
50768
51174
|
for (const c of MEMORY_SERVICE_CANDIDATES) {
|
|
50769
|
-
if (
|
|
51175
|
+
if (existsSync111(c)) return c;
|
|
50770
51176
|
}
|
|
50771
51177
|
throw new Error(
|
|
50772
51178
|
`Could not find packages/memory-service/. Searched: ${MEMORY_SERVICE_CANDIDATES.join(", ")}. If running from a published @pleri/olam-cli tarball, this is a packaging bug \u2014 please file an issue.`
|
|
50773
51179
|
);
|
|
50774
51180
|
}
|
|
50775
51181
|
function resolveLocalBridgeScript(serviceDir) {
|
|
50776
|
-
const path106 =
|
|
50777
|
-
if (!
|
|
51182
|
+
const path106 = join107(serviceDir, "scripts", "local-bridge-server.mjs");
|
|
51183
|
+
if (!existsSync111(path106)) {
|
|
50778
51184
|
throw new Error(
|
|
50779
51185
|
`Could not find local-bridge-server.mjs at ${path106}. Verify packages/memory-service ships the scripts/ directory.`
|
|
50780
51186
|
);
|
|
@@ -50822,12 +51228,12 @@ async function runBridgeServe(opts, deps = {}) {
|
|
|
50822
51228
|
stdio: "inherit"
|
|
50823
51229
|
}));
|
|
50824
51230
|
const child = spawner(process.execPath, [scriptPath, ...args], env);
|
|
50825
|
-
return new Promise((
|
|
51231
|
+
return new Promise((resolve31) => {
|
|
50826
51232
|
let resolved = false;
|
|
50827
51233
|
const finish = (code) => {
|
|
50828
51234
|
if (resolved) return;
|
|
50829
51235
|
resolved = true;
|
|
50830
|
-
|
|
51236
|
+
resolve31(code);
|
|
50831
51237
|
};
|
|
50832
51238
|
const forward = (signal) => () => {
|
|
50833
51239
|
if (!child.killed) {
|
|
@@ -51115,38 +51521,38 @@ function registerMemoryStats(cmd) {
|
|
|
51115
51521
|
}
|
|
51116
51522
|
|
|
51117
51523
|
// src/commands/memory/install-hooks.ts
|
|
51118
|
-
import { copyFileSync as copyFileSync12, existsSync as
|
|
51119
|
-
import { homedir as
|
|
51120
|
-
import { dirname as
|
|
51121
|
-
import { fileURLToPath as
|
|
51524
|
+
import { copyFileSync as copyFileSync12, existsSync as existsSync112, mkdirSync as mkdirSync65, readFileSync as readFileSync96, writeFileSync as writeFileSync59 } from "node:fs";
|
|
51525
|
+
import { homedir as homedir63 } from "node:os";
|
|
51526
|
+
import { dirname as dirname61, join as join108, resolve as resolve28 } from "node:path";
|
|
51527
|
+
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
51122
51528
|
var HOOK_BASENAMES = [
|
|
51123
51529
|
"agentmemory-session-recall.js",
|
|
51124
51530
|
"agentmemory-recall-trigger.mjs",
|
|
51125
51531
|
"agentmemory-classify-queue.mjs"
|
|
51126
51532
|
];
|
|
51127
51533
|
function defaultSourceDir() {
|
|
51128
|
-
const here3 =
|
|
51129
|
-
const candidate =
|
|
51130
|
-
if (
|
|
51131
|
-
const srcCandidate =
|
|
51132
|
-
if (
|
|
51534
|
+
const here3 = dirname61(fileURLToPath11(import.meta.url));
|
|
51535
|
+
const candidate = resolve28(here3, "..", "..", "..", "memory-service", "hooks");
|
|
51536
|
+
if (existsSync112(candidate)) return candidate;
|
|
51537
|
+
const srcCandidate = resolve28(here3, "..", "..", "..", "..", "memory-service", "hooks");
|
|
51538
|
+
if (existsSync112(srcCandidate)) return srcCandidate;
|
|
51133
51539
|
return candidate;
|
|
51134
51540
|
}
|
|
51135
51541
|
function installOne2(basename17, sourceDir, targetDir, opts) {
|
|
51136
|
-
const sourcePath =
|
|
51137
|
-
const targetPath =
|
|
51138
|
-
if (!
|
|
51542
|
+
const sourcePath = join108(sourceDir, basename17);
|
|
51543
|
+
const targetPath = join108(targetDir, basename17);
|
|
51544
|
+
if (!existsSync112(sourcePath)) {
|
|
51139
51545
|
throw new Error(`canonical hook source missing at ${sourcePath} \u2014 olam install corrupt or sourceDir is wrong`);
|
|
51140
51546
|
}
|
|
51141
|
-
const newContent =
|
|
51142
|
-
if (!
|
|
51547
|
+
const newContent = readFileSync96(sourcePath, "utf8");
|
|
51548
|
+
if (!existsSync112(targetPath)) {
|
|
51143
51549
|
if (opts.dryRun !== true) {
|
|
51144
|
-
|
|
51145
|
-
|
|
51550
|
+
mkdirSync65(dirname61(targetPath), { recursive: true });
|
|
51551
|
+
writeFileSync59(targetPath, newContent, { mode: 493 });
|
|
51146
51552
|
}
|
|
51147
51553
|
return { basename: basename17, action: "written", targetPath };
|
|
51148
51554
|
}
|
|
51149
|
-
const existing =
|
|
51555
|
+
const existing = readFileSync96(targetPath, "utf8");
|
|
51150
51556
|
if (existing === newContent) {
|
|
51151
51557
|
return { basename: basename17, action: "unchanged", targetPath };
|
|
51152
51558
|
}
|
|
@@ -51154,7 +51560,7 @@ function installOne2(basename17, sourceDir, targetDir, opts) {
|
|
|
51154
51560
|
const backupPath = `${targetPath}.agentmemory-hook-backup-${Math.floor(Date.now() / 1e3)}`;
|
|
51155
51561
|
if (opts.dryRun !== true) {
|
|
51156
51562
|
copyFileSync12(targetPath, backupPath);
|
|
51157
|
-
|
|
51563
|
+
writeFileSync59(targetPath, newContent, { mode: 493 });
|
|
51158
51564
|
}
|
|
51159
51565
|
return { basename: basename17, action: "force-overwritten", targetPath, backupPath };
|
|
51160
51566
|
}
|
|
@@ -51169,13 +51575,13 @@ Add these hook entries to ~/.claude/settings.json:
|
|
|
51169
51575
|
{
|
|
51170
51576
|
"hooks": {
|
|
51171
51577
|
"SessionStart": [
|
|
51172
|
-
{ "command": "node ${
|
|
51578
|
+
{ "command": "node ${join108(targetDir, "agentmemory-session-recall.js")}" }
|
|
51173
51579
|
],
|
|
51174
51580
|
"PreToolUse": [
|
|
51175
|
-
{ "command": "node ${
|
|
51581
|
+
{ "command": "node ${join108(targetDir, "agentmemory-recall-trigger.mjs")}" }
|
|
51176
51582
|
],
|
|
51177
51583
|
"PostToolUse": [
|
|
51178
|
-
{ "command": "node ${
|
|
51584
|
+
{ "command": "node ${join108(targetDir, "agentmemory-classify-queue.mjs")}" }
|
|
51179
51585
|
]
|
|
51180
51586
|
}
|
|
51181
51587
|
}
|
|
@@ -51185,7 +51591,7 @@ If existing entries already point at the same paths, no edit needed.
|
|
|
51185
51591
|
}
|
|
51186
51592
|
function registerMemoryInstallHooks(parent) {
|
|
51187
51593
|
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) => {
|
|
51188
|
-
const targetDir = opts.targetDir ??
|
|
51594
|
+
const targetDir = opts.targetDir ?? join108(homedir63(), ".claude", "scripts", "hooks");
|
|
51189
51595
|
const sourceDir = opts.sourceDir ?? defaultSourceDir();
|
|
51190
51596
|
let written = 0;
|
|
51191
51597
|
let unchanged = 0;
|
|
@@ -51261,7 +51667,7 @@ function registerMemory(program2) {
|
|
|
51261
51667
|
// src/commands/kg-build.ts
|
|
51262
51668
|
init_storage_paths();
|
|
51263
51669
|
init_workspace_name();
|
|
51264
|
-
import * as
|
|
51670
|
+
import * as fs104 from "node:fs";
|
|
51265
51671
|
import * as os57 from "node:os";
|
|
51266
51672
|
import * as path102 from "node:path";
|
|
51267
51673
|
|
|
@@ -51355,11 +51761,11 @@ init_storage_paths();
|
|
|
51355
51761
|
init_workspace_name();
|
|
51356
51762
|
init_kg_caps();
|
|
51357
51763
|
init_output();
|
|
51358
|
-
import
|
|
51359
|
-
import { homedir as
|
|
51764
|
+
import fs99 from "node:fs";
|
|
51765
|
+
import { homedir as homedir64 } from "node:os";
|
|
51360
51766
|
import path97 from "node:path";
|
|
51361
51767
|
function olamHome5() {
|
|
51362
|
-
return process.env.OLAM_HOME ?? path97.join(
|
|
51768
|
+
return process.env.OLAM_HOME ?? path97.join(homedir64(), ".olam");
|
|
51363
51769
|
}
|
|
51364
51770
|
function kgRoot2() {
|
|
51365
51771
|
return path97.join(olamHome5(), "kg");
|
|
@@ -51368,14 +51774,14 @@ function worldsRoot2() {
|
|
|
51368
51774
|
return path97.join(olamHome5(), "worlds");
|
|
51369
51775
|
}
|
|
51370
51776
|
function dirSizeBytes2(dir) {
|
|
51371
|
-
if (!
|
|
51777
|
+
if (!fs99.existsSync(dir)) return 0;
|
|
51372
51778
|
let total = 0;
|
|
51373
51779
|
const stack = [dir];
|
|
51374
51780
|
while (stack.length > 0) {
|
|
51375
51781
|
const cur = stack.pop();
|
|
51376
51782
|
let entries;
|
|
51377
51783
|
try {
|
|
51378
|
-
entries =
|
|
51784
|
+
entries = fs99.readdirSync(cur, { withFileTypes: true });
|
|
51379
51785
|
} catch {
|
|
51380
51786
|
continue;
|
|
51381
51787
|
}
|
|
@@ -51387,7 +51793,7 @@ function dirSizeBytes2(dir) {
|
|
|
51387
51793
|
continue;
|
|
51388
51794
|
}
|
|
51389
51795
|
try {
|
|
51390
|
-
total +=
|
|
51796
|
+
total += fs99.statSync(full).size;
|
|
51391
51797
|
} catch {
|
|
51392
51798
|
}
|
|
51393
51799
|
}
|
|
@@ -51402,9 +51808,9 @@ function formatBytes5(n) {
|
|
|
51402
51808
|
}
|
|
51403
51809
|
function readFreshness(workspace) {
|
|
51404
51810
|
const file = path97.join(kgPristinePath(workspace), "freshness.json");
|
|
51405
|
-
if (!
|
|
51811
|
+
if (!fs99.existsSync(file)) return null;
|
|
51406
51812
|
try {
|
|
51407
|
-
const raw = JSON.parse(
|
|
51813
|
+
const raw = JSON.parse(fs99.readFileSync(file, "utf-8"));
|
|
51408
51814
|
if (raw && typeof raw === "object") return raw;
|
|
51409
51815
|
return null;
|
|
51410
51816
|
} catch {
|
|
@@ -51413,9 +51819,9 @@ function readFreshness(workspace) {
|
|
|
51413
51819
|
}
|
|
51414
51820
|
function readOverlayNodeCount(graphifyOutDir) {
|
|
51415
51821
|
const graphPath = path97.join(graphifyOutDir, "graph.json");
|
|
51416
|
-
if (!
|
|
51822
|
+
if (!fs99.existsSync(graphPath)) return null;
|
|
51417
51823
|
try {
|
|
51418
|
-
const raw = JSON.parse(
|
|
51824
|
+
const raw = JSON.parse(fs99.readFileSync(graphPath, "utf-8"));
|
|
51419
51825
|
if (raw && typeof raw === "object") {
|
|
51420
51826
|
const nodes = raw.nodes;
|
|
51421
51827
|
if (Array.isArray(nodes)) return nodes.length;
|
|
@@ -51427,11 +51833,11 @@ function readOverlayNodeCount(graphifyOutDir) {
|
|
|
51427
51833
|
}
|
|
51428
51834
|
function listOverlays() {
|
|
51429
51835
|
const root = worldsRoot2();
|
|
51430
|
-
if (!
|
|
51836
|
+
if (!fs99.existsSync(root)) return [];
|
|
51431
51837
|
const records = [];
|
|
51432
51838
|
let worldDirs;
|
|
51433
51839
|
try {
|
|
51434
|
-
worldDirs =
|
|
51840
|
+
worldDirs = fs99.readdirSync(root, { withFileTypes: true });
|
|
51435
51841
|
} catch {
|
|
51436
51842
|
return [];
|
|
51437
51843
|
}
|
|
@@ -51441,14 +51847,14 @@ function listOverlays() {
|
|
|
51441
51847
|
const worldDir = path97.join(root, worldId);
|
|
51442
51848
|
let cloneDirs;
|
|
51443
51849
|
try {
|
|
51444
|
-
cloneDirs =
|
|
51850
|
+
cloneDirs = fs99.readdirSync(worldDir, { withFileTypes: true });
|
|
51445
51851
|
} catch {
|
|
51446
51852
|
continue;
|
|
51447
51853
|
}
|
|
51448
51854
|
for (const cloneEntry of cloneDirs) {
|
|
51449
51855
|
if (!cloneEntry.isDirectory()) continue;
|
|
51450
51856
|
const graphifyOut = path97.join(worldDir, cloneEntry.name, "graphify-out");
|
|
51451
|
-
if (!
|
|
51857
|
+
if (!fs99.existsSync(graphifyOut)) continue;
|
|
51452
51858
|
records.push({
|
|
51453
51859
|
world_id: worldId,
|
|
51454
51860
|
clone_dir: cloneEntry.name,
|
|
@@ -51462,11 +51868,11 @@ function listOverlays() {
|
|
|
51462
51868
|
}
|
|
51463
51869
|
function listPristines(overlays) {
|
|
51464
51870
|
const root = kgRoot2();
|
|
51465
|
-
if (!
|
|
51871
|
+
if (!fs99.existsSync(root)) return [];
|
|
51466
51872
|
const records = [];
|
|
51467
51873
|
let entries;
|
|
51468
51874
|
try {
|
|
51469
|
-
entries =
|
|
51875
|
+
entries = fs99.readdirSync(root, { withFileTypes: true });
|
|
51470
51876
|
} catch {
|
|
51471
51877
|
return [];
|
|
51472
51878
|
}
|
|
@@ -51615,7 +52021,7 @@ init_storage_paths();
|
|
|
51615
52021
|
init_workspace_name();
|
|
51616
52022
|
init_output();
|
|
51617
52023
|
import { spawn as spawn13 } from "node:child_process";
|
|
51618
|
-
import
|
|
52024
|
+
import fs100 from "node:fs";
|
|
51619
52025
|
import path98 from "node:path";
|
|
51620
52026
|
function pidFilePath2(workspace) {
|
|
51621
52027
|
return path98.join(kgPristinePath(workspace), ".watch.pid");
|
|
@@ -51633,33 +52039,33 @@ function isPidAlive3(pid) {
|
|
|
51633
52039
|
}
|
|
51634
52040
|
function readAndClassifyPid(workspace) {
|
|
51635
52041
|
const file = pidFilePath2(workspace);
|
|
51636
|
-
if (!
|
|
52042
|
+
if (!fs100.existsSync(file)) return { status: "no-pidfile", pid: null };
|
|
51637
52043
|
let pid;
|
|
51638
52044
|
try {
|
|
51639
|
-
const raw =
|
|
52045
|
+
const raw = fs100.readFileSync(file, "utf-8").trim();
|
|
51640
52046
|
pid = Number.parseInt(raw, 10);
|
|
51641
52047
|
} catch {
|
|
51642
|
-
|
|
52048
|
+
fs100.rmSync(file, { force: true });
|
|
51643
52049
|
return { status: "stale-reclaimed", pid: null };
|
|
51644
52050
|
}
|
|
51645
52051
|
if (!Number.isInteger(pid) || pid <= 0) {
|
|
51646
|
-
|
|
52052
|
+
fs100.rmSync(file, { force: true });
|
|
51647
52053
|
return { status: "stale-reclaimed", pid: null };
|
|
51648
52054
|
}
|
|
51649
52055
|
if (isPidAlive3(pid)) return { status: "active", pid };
|
|
51650
|
-
|
|
52056
|
+
fs100.rmSync(file, { force: true });
|
|
51651
52057
|
return { status: "stale-reclaimed", pid: null };
|
|
51652
52058
|
}
|
|
51653
52059
|
function writePidFile2(workspace, pid) {
|
|
51654
52060
|
const file = pidFilePath2(workspace);
|
|
51655
52061
|
const dir = path98.dirname(file);
|
|
51656
|
-
|
|
51657
|
-
|
|
52062
|
+
fs100.mkdirSync(dir, { recursive: true });
|
|
52063
|
+
fs100.writeFileSync(file, String(pid), { encoding: "utf-8" });
|
|
51658
52064
|
}
|
|
51659
52065
|
function removePidFile(workspace) {
|
|
51660
52066
|
const file = pidFilePath2(workspace);
|
|
51661
52067
|
try {
|
|
51662
|
-
|
|
52068
|
+
fs100.rmSync(file, { force: true });
|
|
51663
52069
|
} catch {
|
|
51664
52070
|
}
|
|
51665
52071
|
}
|
|
@@ -51713,16 +52119,16 @@ async function runKgWatch(workspaceArg, opts, deps = {}) {
|
|
|
51713
52119
|
process.on("SIGINT", () => forward("SIGINT"));
|
|
51714
52120
|
process.on("SIGTERM", () => forward("SIGTERM"));
|
|
51715
52121
|
}
|
|
51716
|
-
return new Promise((
|
|
52122
|
+
return new Promise((resolve31) => {
|
|
51717
52123
|
child.on("exit", (code, signal) => {
|
|
51718
52124
|
removePidFile(name);
|
|
51719
52125
|
const exitCode = typeof code === "number" ? code : signal === "SIGINT" || signal === "SIGTERM" ? 0 : 1;
|
|
51720
|
-
|
|
52126
|
+
resolve31({ exitCode, pidWritten: true });
|
|
51721
52127
|
});
|
|
51722
52128
|
child.on("error", (err) => {
|
|
51723
52129
|
removePidFile(name);
|
|
51724
52130
|
printError(`graphify subprocess error: ${err.message}`);
|
|
51725
|
-
|
|
52131
|
+
resolve31({ exitCode: 1, pidWritten: true });
|
|
51726
52132
|
});
|
|
51727
52133
|
});
|
|
51728
52134
|
}
|
|
@@ -51986,7 +52392,7 @@ function registerKgDoctorCommand(kg) {
|
|
|
51986
52392
|
init_merge_settings();
|
|
51987
52393
|
init_hook_template2();
|
|
51988
52394
|
init_output();
|
|
51989
|
-
import * as
|
|
52395
|
+
import * as fs101 from "node:fs";
|
|
51990
52396
|
import * as path99 from "node:path";
|
|
51991
52397
|
import * as os54 from "node:os";
|
|
51992
52398
|
import { parse as yamlParse3, stringify as yamlStringify4 } from "yaml";
|
|
@@ -51997,10 +52403,10 @@ function settingsPathFor2(scope) {
|
|
|
51997
52403
|
return path99.join(process.cwd(), ".claude", "settings.json");
|
|
51998
52404
|
}
|
|
51999
52405
|
function backup2(filePath) {
|
|
52000
|
-
if (!
|
|
52406
|
+
if (!fs101.existsSync(filePath)) return null;
|
|
52001
52407
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
52002
52408
|
const backupPath = `${filePath}.olam-bak.${ts}`;
|
|
52003
|
-
|
|
52409
|
+
fs101.copyFileSync(filePath, backupPath);
|
|
52004
52410
|
return backupPath;
|
|
52005
52411
|
}
|
|
52006
52412
|
var HERMES_HOOK_MATCHERS = ["terminal", "bash", "shell", "search_files", "grep", "ripgrep"];
|
|
@@ -52012,7 +52418,7 @@ function hermesHooksDir() {
|
|
|
52012
52418
|
}
|
|
52013
52419
|
function patchHermesConfigForHook(action) {
|
|
52014
52420
|
const configPath = hermesConfigPath2();
|
|
52015
|
-
const raw =
|
|
52421
|
+
const raw = fs101.readFileSync(configPath, "utf-8");
|
|
52016
52422
|
const config = yamlParse3(raw);
|
|
52017
52423
|
const hooks = config["hooks"] ?? {};
|
|
52018
52424
|
const preToolCall = Array.isArray(hooks["pre_tool_call"]) ? hooks["pre_tool_call"] : [];
|
|
@@ -52031,7 +52437,7 @@ function patchHermesConfigForHook(action) {
|
|
|
52031
52437
|
hooks: { ...hooks, pre_tool_call: [...preToolCall, entry] },
|
|
52032
52438
|
hooks_auto_accept: true
|
|
52033
52439
|
};
|
|
52034
|
-
|
|
52440
|
+
fs101.writeFileSync(configPath, yamlStringify4(updated2), "utf-8");
|
|
52035
52441
|
return "patched";
|
|
52036
52442
|
}
|
|
52037
52443
|
const filtered = preToolCall.filter(
|
|
@@ -52042,12 +52448,12 @@ function patchHermesConfigForHook(action) {
|
|
|
52042
52448
|
...config,
|
|
52043
52449
|
hooks: { ...hooks, pre_tool_call: filtered }
|
|
52044
52450
|
};
|
|
52045
|
-
|
|
52451
|
+
fs101.writeFileSync(configPath, yamlStringify4(updated), "utf-8");
|
|
52046
52452
|
return "patched";
|
|
52047
52453
|
}
|
|
52048
52454
|
function doInstallForHermes() {
|
|
52049
52455
|
const configPath = hermesConfigPath2();
|
|
52050
|
-
if (!
|
|
52456
|
+
if (!fs101.existsSync(configPath)) {
|
|
52051
52457
|
printError(`~/.hermes/config.yaml not found at ${configPath}`);
|
|
52052
52458
|
printInfo("remedy", "Install Hermes first, then re-run `olam kg install-hook --for hermes`");
|
|
52053
52459
|
process.exitCode = 1;
|
|
@@ -52077,15 +52483,15 @@ function doUninstallForHermes() {
|
|
|
52077
52483
|
const hooksDir = hermesHooksDir();
|
|
52078
52484
|
const hookScriptPath = path99.join(hooksDir, "kg-first.sh");
|
|
52079
52485
|
let scriptRemoved = false;
|
|
52080
|
-
if (
|
|
52081
|
-
const content =
|
|
52486
|
+
if (fs101.existsSync(hookScriptPath)) {
|
|
52487
|
+
const content = fs101.readFileSync(hookScriptPath, "utf-8");
|
|
52082
52488
|
if (content.includes(HERMES_KG_HOOK_SENTINEL)) {
|
|
52083
|
-
|
|
52489
|
+
fs101.unlinkSync(hookScriptPath);
|
|
52084
52490
|
scriptRemoved = true;
|
|
52085
52491
|
}
|
|
52086
52492
|
}
|
|
52087
52493
|
let configPatched = false;
|
|
52088
|
-
if (
|
|
52494
|
+
if (fs101.existsSync(configPath)) {
|
|
52089
52495
|
const result = patchHermesConfigForHook("uninstall");
|
|
52090
52496
|
configPatched = result === "patched";
|
|
52091
52497
|
}
|
|
@@ -52110,7 +52516,7 @@ function registerKgInstallHookCommand(kg) {
|
|
|
52110
52516
|
const scope = opts.scope === "user" ? "user" : "project";
|
|
52111
52517
|
const filePath = settingsPathFor2(scope);
|
|
52112
52518
|
try {
|
|
52113
|
-
|
|
52519
|
+
fs101.mkdirSync(path99.dirname(filePath), { recursive: true });
|
|
52114
52520
|
} catch (err) {
|
|
52115
52521
|
printError(`could not create ${path99.dirname(filePath)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
52116
52522
|
process.exitCode = 1;
|
|
@@ -52136,7 +52542,7 @@ function registerKgInstallHookCommand(kg) {
|
|
|
52136
52542
|
printInfo("kg-service hook", `already installed at ${filePath}`);
|
|
52137
52543
|
if (backupPath) {
|
|
52138
52544
|
try {
|
|
52139
|
-
|
|
52545
|
+
fs101.unlinkSync(backupPath);
|
|
52140
52546
|
} catch {
|
|
52141
52547
|
}
|
|
52142
52548
|
}
|
|
@@ -52156,7 +52562,7 @@ function registerKgInstallHookCommand(kg) {
|
|
|
52156
52562
|
// src/commands/kg-uninstall-hook.ts
|
|
52157
52563
|
init_hook_template2();
|
|
52158
52564
|
init_output();
|
|
52159
|
-
import * as
|
|
52565
|
+
import * as fs102 from "node:fs";
|
|
52160
52566
|
import * as path100 from "node:path";
|
|
52161
52567
|
import * as os55 from "node:os";
|
|
52162
52568
|
function settingsPathFor3(scope) {
|
|
@@ -52193,13 +52599,13 @@ function registerKgUninstallHookCommand(kg) {
|
|
|
52193
52599
|
kg.command("uninstall-hook").description("Remove kg-service PreToolUse hook from .claude/settings.json (sentinel-matched; surgical)").option("--scope <scope>", "project (default) or user", "project").action((opts) => {
|
|
52194
52600
|
const scope = opts.scope === "user" ? "user" : "project";
|
|
52195
52601
|
const filePath = settingsPathFor3(scope);
|
|
52196
|
-
if (!
|
|
52602
|
+
if (!fs102.existsSync(filePath)) {
|
|
52197
52603
|
printInfo("kg-service hook", `no settings.json at ${filePath} \u2014 nothing to remove`);
|
|
52198
52604
|
return;
|
|
52199
52605
|
}
|
|
52200
52606
|
let settings;
|
|
52201
52607
|
try {
|
|
52202
|
-
const raw =
|
|
52608
|
+
const raw = fs102.readFileSync(filePath, "utf-8");
|
|
52203
52609
|
settings = raw.trim() ? JSON.parse(raw) : {};
|
|
52204
52610
|
} catch (err) {
|
|
52205
52611
|
printError(`could not parse ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -52219,7 +52625,7 @@ function registerKgUninstallHookCommand(kg) {
|
|
|
52219
52625
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
52220
52626
|
const backupPath = `${filePath}.olam-bak.${ts}`;
|
|
52221
52627
|
try {
|
|
52222
|
-
|
|
52628
|
+
fs102.copyFileSync(filePath, backupPath);
|
|
52223
52629
|
} catch {
|
|
52224
52630
|
}
|
|
52225
52631
|
const next = {
|
|
@@ -52238,7 +52644,7 @@ function registerKgUninstallHookCommand(kg) {
|
|
|
52238
52644
|
}
|
|
52239
52645
|
}
|
|
52240
52646
|
try {
|
|
52241
|
-
|
|
52647
|
+
fs102.writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
52242
52648
|
printSuccess(`kg-service hook removed from ${filePath}`);
|
|
52243
52649
|
printInfo("backup", backupPath);
|
|
52244
52650
|
} catch (err) {
|
|
@@ -52311,7 +52717,7 @@ function registerKgSavingsCommand(kg) {
|
|
|
52311
52717
|
|
|
52312
52718
|
// src/commands/kg-mirror.ts
|
|
52313
52719
|
init_output();
|
|
52314
|
-
import * as
|
|
52720
|
+
import * as fs103 from "node:fs";
|
|
52315
52721
|
import * as os56 from "node:os";
|
|
52316
52722
|
import * as path101 from "node:path";
|
|
52317
52723
|
function readEnvOrFile(envVar, fileName) {
|
|
@@ -52319,7 +52725,7 @@ function readEnvOrFile(envVar, fileName) {
|
|
|
52319
52725
|
if (fromEnv && fromEnv.length > 0) return fromEnv.trim();
|
|
52320
52726
|
try {
|
|
52321
52727
|
const file = path101.join(os56.homedir(), ".olam", fileName);
|
|
52322
|
-
const content =
|
|
52728
|
+
const content = fs103.readFileSync(file, "utf-8").trim();
|
|
52323
52729
|
if (content.length > 0) return content;
|
|
52324
52730
|
} catch {
|
|
52325
52731
|
}
|
|
@@ -52499,6 +52905,76 @@ async function runKgMirrorClassify(question, options = {}) {
|
|
|
52499
52905
|
printInfo("est. savings", `~${Math.round(Number(savings2) / 1e3)}k tokens`);
|
|
52500
52906
|
return { exitCode: 0 };
|
|
52501
52907
|
}
|
|
52908
|
+
async function runKgMirrorGraph(symbol, options = {}) {
|
|
52909
|
+
const cfg = resolveClassifier();
|
|
52910
|
+
if (!cfg) {
|
|
52911
|
+
printError(
|
|
52912
|
+
"kg-mirror URL/bearer not configured. Set OLAM_KG_PROXY_URL + OLAM_KG_PROXY_BEARER (or ~/.olam/kg-proxy-url + ~/.olam/kg-proxy-bearer)."
|
|
52913
|
+
);
|
|
52914
|
+
return { exitCode: 3 };
|
|
52915
|
+
}
|
|
52916
|
+
if (!options.workspace) {
|
|
52917
|
+
printError("graph query needs a --workspace (e.g. --workspace atlas-one).");
|
|
52918
|
+
return { exitCode: 2 };
|
|
52919
|
+
}
|
|
52920
|
+
const sym = (symbol ?? "").trim();
|
|
52921
|
+
if (!sym && !options.repo) {
|
|
52922
|
+
printError("provide a <symbol> to search, and/or --repo <name> to browse a repo.");
|
|
52923
|
+
return { exitCode: 2 };
|
|
52924
|
+
}
|
|
52925
|
+
const mode = options.relates ? "relates" : "where";
|
|
52926
|
+
const body = { workspace: options.workspace, symbol: sym, mode };
|
|
52927
|
+
if (options.repo) body.repo = options.repo;
|
|
52928
|
+
if (options.limit) {
|
|
52929
|
+
const n = Number.parseInt(options.limit, 10);
|
|
52930
|
+
if (Number.isFinite(n) && n > 0) body.limit = n;
|
|
52931
|
+
}
|
|
52932
|
+
let res;
|
|
52933
|
+
try {
|
|
52934
|
+
res = await fetch(`${cfg.url}/v1/graph`, {
|
|
52935
|
+
method: "POST",
|
|
52936
|
+
headers: { Authorization: `Bearer ${cfg.bearer}`, "Content-Type": "application/json" },
|
|
52937
|
+
body: JSON.stringify(body)
|
|
52938
|
+
});
|
|
52939
|
+
} catch (err) {
|
|
52940
|
+
printError(`kg-mirror unreachable: ${err instanceof Error ? err.message : String(err)}`);
|
|
52941
|
+
return { exitCode: 4 };
|
|
52942
|
+
}
|
|
52943
|
+
const text = await res.text();
|
|
52944
|
+
if (options.json) {
|
|
52945
|
+
process.stdout.write(text + "\n");
|
|
52946
|
+
return { exitCode: res.ok ? 0 : 1 };
|
|
52947
|
+
}
|
|
52948
|
+
let j;
|
|
52949
|
+
try {
|
|
52950
|
+
j = JSON.parse(text);
|
|
52951
|
+
} catch {
|
|
52952
|
+
printError(`kg-mirror returned non-JSON (HTTP ${res.status}): ${text.slice(0, 200)}`);
|
|
52953
|
+
return { exitCode: 1 };
|
|
52954
|
+
}
|
|
52955
|
+
if (!res.ok) {
|
|
52956
|
+
printError(`graph /v1/graph failed (HTTP ${res.status}): ${j.error ?? "?"}`);
|
|
52957
|
+
if (j.detail) printInfo("detail", String(j.detail));
|
|
52958
|
+
return { exitCode: 1 };
|
|
52959
|
+
}
|
|
52960
|
+
const matched = j.matched ?? [];
|
|
52961
|
+
printInfo("graph", `${options.workspace} \xB7 ${mode} \xB7 "${symbol}"`);
|
|
52962
|
+
if (matched.length === 0) {
|
|
52963
|
+
printInfo("matched", "no nodes match that symbol");
|
|
52964
|
+
}
|
|
52965
|
+
for (const m of matched) {
|
|
52966
|
+
printSuccess(`${m.label} ${m.file}:${String(m.loc ?? "").replace(/^L/, "")}`);
|
|
52967
|
+
}
|
|
52968
|
+
if (mode === "relates") {
|
|
52969
|
+
const relates = j.relates ?? [];
|
|
52970
|
+
for (const e of relates) {
|
|
52971
|
+
const arrow = e.direction === "out" ? "\u2192" : "\u2190";
|
|
52972
|
+
printInfo(String(e.relation), `${arrow} ${e.label} (${e.file})`);
|
|
52973
|
+
}
|
|
52974
|
+
}
|
|
52975
|
+
if (j.truncated) printInfo("note", "results truncated \u2014 pass --limit to widen");
|
|
52976
|
+
return { exitCode: 0 };
|
|
52977
|
+
}
|
|
52502
52978
|
function guessGitUrl(workspace) {
|
|
52503
52979
|
try {
|
|
52504
52980
|
const { spawnSync: spawnSync35 } = __require("node:child_process");
|
|
@@ -52509,7 +52985,7 @@ function guessGitUrl(workspace) {
|
|
|
52509
52985
|
path101.join(os56.homedir(), "Projects", workspace)
|
|
52510
52986
|
];
|
|
52511
52987
|
for (const dir of candidates2) {
|
|
52512
|
-
if (!
|
|
52988
|
+
if (!fs103.existsSync(path101.join(dir, ".git"))) continue;
|
|
52513
52989
|
const r = spawnSync35("git", ["-C", dir, "remote", "get-url", "origin"], {
|
|
52514
52990
|
encoding: "utf-8"
|
|
52515
52991
|
});
|
|
@@ -52538,12 +53014,16 @@ function registerKgMirrorCommand(kg) {
|
|
|
52538
53014
|
const r = await runKgMirrorClassify(question, opts);
|
|
52539
53015
|
if (r.exitCode !== 0) process.exitCode = r.exitCode;
|
|
52540
53016
|
});
|
|
53017
|
+
mirror.command("graph").description("Query the cross-repo graph: locate a symbol, its relationships, or browse a repo (POST /v1/graph)").argument("[symbol]", "symbol/label to look up (e.g. UserService); omit with --repo to browse a repo").requiredOption("--workspace <name>", "workspace to query (e.g. atlas-one)").option("--repo <name>", "scope to / browse a submodule by path prefix (e.g. diner-app)").option("--relates", "return relationships (calls/imports/contains) instead of just locations").option("--limit <n>", "max results (default 50)").option("--json", "emit raw JSON response").action(async (symbol, opts) => {
|
|
53018
|
+
const r = await runKgMirrorGraph(symbol, opts);
|
|
53019
|
+
if (r.exitCode !== 0) process.exitCode = r.exitCode;
|
|
53020
|
+
});
|
|
52541
53021
|
}
|
|
52542
53022
|
|
|
52543
53023
|
// src/commands/kg-build.ts
|
|
52544
53024
|
function readQueueFromDisk(queuePath) {
|
|
52545
|
-
if (!
|
|
52546
|
-
const raw =
|
|
53025
|
+
if (!fs104.existsSync(queuePath)) return [];
|
|
53026
|
+
const raw = fs104.readFileSync(queuePath, "utf-8");
|
|
52547
53027
|
const entries = [];
|
|
52548
53028
|
for (const line of raw.split("\n")) {
|
|
52549
53029
|
const t = line.trim();
|
|
@@ -52556,9 +53036,9 @@ function readQueueFromDisk(queuePath) {
|
|
|
52556
53036
|
return entries;
|
|
52557
53037
|
}
|
|
52558
53038
|
function writeQueueToDisk(queuePath, entries) {
|
|
52559
|
-
|
|
53039
|
+
fs104.mkdirSync(path102.dirname(queuePath), { recursive: true });
|
|
52560
53040
|
const content = entries.map((e) => JSON.stringify(e)).join("\n") + (entries.length > 0 ? "\n" : "");
|
|
52561
|
-
|
|
53041
|
+
fs104.writeFileSync(queuePath, content, "utf-8");
|
|
52562
53042
|
}
|
|
52563
53043
|
async function runKgBuildPending(opts = {}) {
|
|
52564
53044
|
const queuePath = opts.queuePath ?? (() => {
|
|
@@ -52648,7 +53128,7 @@ async function runKgBuild(workspaceArg, options = {}) {
|
|
|
52648
53128
|
return { exitCode: 2 };
|
|
52649
53129
|
}
|
|
52650
53130
|
const outDir = kgPristinePath(workspace.name);
|
|
52651
|
-
|
|
53131
|
+
fs104.mkdirSync(outDir, { recursive: true });
|
|
52652
53132
|
const human = !options.json;
|
|
52653
53133
|
if (human) {
|
|
52654
53134
|
printInfo("kg build", `workspace=${workspace.name} source=${workspace.sourcePath}`);
|
|
@@ -52681,7 +53161,7 @@ async function runKgBuild(workspaceArg, options = {}) {
|
|
|
52681
53161
|
workspace: workspace.name,
|
|
52682
53162
|
graphify_path: "container"
|
|
52683
53163
|
};
|
|
52684
|
-
|
|
53164
|
+
fs104.writeFileSync(
|
|
52685
53165
|
path102.join(outDir, "freshness.json"),
|
|
52686
53166
|
JSON.stringify(freshness, null, 2) + "\n",
|
|
52687
53167
|
"utf-8"
|
|
@@ -52728,13 +53208,13 @@ function registerKg(program2) {
|
|
|
52728
53208
|
|
|
52729
53209
|
// src/commands/flywheel/emit-breadcrumb.ts
|
|
52730
53210
|
init_file_lock();
|
|
52731
|
-
import { mkdirSync as
|
|
52732
|
-
import { homedir as
|
|
52733
|
-
import { dirname as
|
|
53211
|
+
import { mkdirSync as mkdirSync68, appendFileSync as appendFileSync6 } from "node:fs";
|
|
53212
|
+
import { homedir as homedir69 } from "node:os";
|
|
53213
|
+
import { dirname as dirname65, join as join113 } from "node:path";
|
|
52734
53214
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
52735
53215
|
var VALID_SEVERITIES = /* @__PURE__ */ new Set(["critical", "high", "medium", "low", "info", "warn"]);
|
|
52736
53216
|
var PROMPT_FEEDING_FIELDS = ["extracted_pattern", "severity", "affected_persona", "proposed_edit"];
|
|
52737
|
-
var BREADCRUMBS_BASE =
|
|
53217
|
+
var BREADCRUMBS_BASE = join113(homedir69(), ".local", "share", "claude", "breadcrumbs");
|
|
52738
53218
|
var LOCK_FILENAME = ".flywheel-emit.lock";
|
|
52739
53219
|
function buildRecord(opts) {
|
|
52740
53220
|
const rec = {
|
|
@@ -52781,7 +53261,7 @@ function validatePromptFeeding(rec) {
|
|
|
52781
53261
|
}
|
|
52782
53262
|
function destPath(projectSlug) {
|
|
52783
53263
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
52784
|
-
return
|
|
53264
|
+
return join113(BREADCRUMBS_BASE, projectSlug, `${today}.jsonl`);
|
|
52785
53265
|
}
|
|
52786
53266
|
async function emitBreadcrumb(opts) {
|
|
52787
53267
|
if (!VALID_SEVERITIES.has(opts.severity)) {
|
|
@@ -52801,8 +53281,8 @@ async function emitBreadcrumb(opts) {
|
|
|
52801
53281
|
process.exit(2);
|
|
52802
53282
|
}
|
|
52803
53283
|
const path106 = destPath(rec.project_slug);
|
|
52804
|
-
const lockDir =
|
|
52805
|
-
|
|
53284
|
+
const lockDir = dirname65(path106);
|
|
53285
|
+
mkdirSync68(lockDir, { recursive: true });
|
|
52806
53286
|
const line = JSON.stringify(rec) + "\n";
|
|
52807
53287
|
await withFileLock(
|
|
52808
53288
|
lockDir,
|
|
@@ -52882,7 +53362,7 @@ function registerFlywheelK5Score(parent) {
|
|
|
52882
53362
|
}
|
|
52883
53363
|
|
|
52884
53364
|
// src/commands/flywheel/k5-validate.ts
|
|
52885
|
-
import { readFileSync as
|
|
53365
|
+
import { readFileSync as readFileSync101, statSync as statSync31 } from "node:fs";
|
|
52886
53366
|
import { parse as parseYAML } from "yaml";
|
|
52887
53367
|
var K5_DIMS = ["direction", "approach", "open_questions", "constraints", "reuse"];
|
|
52888
53368
|
var MAX_PLAN_BYTES = 1048576;
|
|
@@ -52964,7 +53444,7 @@ function validatePlan(path106) {
|
|
|
52964
53444
|
}
|
|
52965
53445
|
let text;
|
|
52966
53446
|
try {
|
|
52967
|
-
text =
|
|
53447
|
+
text = readFileSync101(path106, "utf8");
|
|
52968
53448
|
} catch (err) {
|
|
52969
53449
|
const m = `FAIL cannot read ${path106}: ${err instanceof Error ? err.message : "unknown"}`;
|
|
52970
53450
|
return { ok: false, message: m, json: emptyJson("error", [m]) };
|
|
@@ -53088,7 +53568,7 @@ function registerFlywheelK5Validate(parent) {
|
|
|
53088
53568
|
}
|
|
53089
53569
|
|
|
53090
53570
|
// src/commands/flywheel/k10-measure.ts
|
|
53091
|
-
import { readFileSync as
|
|
53571
|
+
import { readFileSync as readFileSync102 } from "node:fs";
|
|
53092
53572
|
|
|
53093
53573
|
// ../core/dist/lib/k10-budget.js
|
|
53094
53574
|
var K10_TOKEN_CAP = 5500;
|
|
@@ -53145,7 +53625,7 @@ function registerFlywheelK10Measure(parent) {
|
|
|
53145
53625
|
parent.command("k10-measure").description("Measure K10 token budget for upstream + optional overlay; emit PASS/REJECT verdict").requiredOption("--upstream <path>", "path to upstream file (e.g. persona prompt)").option("--overlay <path>", "path to overlay file (omit if none \u2014 PASS without enforcement)").option("--json", "emit verdict as JSON instead of human-readable").action((opts) => {
|
|
53146
53626
|
let upstreamText;
|
|
53147
53627
|
try {
|
|
53148
|
-
upstreamText =
|
|
53628
|
+
upstreamText = readFileSync102(opts.upstream, "utf8");
|
|
53149
53629
|
} catch (err) {
|
|
53150
53630
|
process.stderr.write(
|
|
53151
53631
|
`[k10-measure-error] cannot read upstream ${opts.upstream}: ${err instanceof Error ? err.message : "unknown"}
|
|
@@ -53157,7 +53637,7 @@ function registerFlywheelK10Measure(parent) {
|
|
|
53157
53637
|
let overlayTokens = null;
|
|
53158
53638
|
if (opts.overlay !== void 0) {
|
|
53159
53639
|
try {
|
|
53160
|
-
const overlayText =
|
|
53640
|
+
const overlayText = readFileSync102(opts.overlay, "utf8");
|
|
53161
53641
|
overlayTokens = tokensFromText(overlayText);
|
|
53162
53642
|
} catch (err) {
|
|
53163
53643
|
process.stderr.write(
|
|
@@ -53191,13 +53671,13 @@ function registerFlywheelK10Measure(parent) {
|
|
|
53191
53671
|
}
|
|
53192
53672
|
|
|
53193
53673
|
// src/commands/flywheel/check-persona-skeleton.ts
|
|
53194
|
-
import { existsSync as
|
|
53195
|
-
import { homedir as
|
|
53196
|
-
import { basename as basename14, join as
|
|
53674
|
+
import { existsSync as existsSync117, readFileSync as readFileSync103, statSync as statSync32 } from "node:fs";
|
|
53675
|
+
import { homedir as homedir70 } from "node:os";
|
|
53676
|
+
import { basename as basename14, join as join114 } from "node:path";
|
|
53197
53677
|
import { parse as parseYAML2 } from "yaml";
|
|
53198
53678
|
var CHARS_PER_TOKEN3 = 4;
|
|
53199
53679
|
var K10_TOKEN_CAP2 = 6e3;
|
|
53200
|
-
var AGENTS_DIR =
|
|
53680
|
+
var AGENTS_DIR = join114(homedir70(), ".claude", "agents");
|
|
53201
53681
|
var REQUIRED_FRONTMATTER_KEYS = ["name", "description", "allowed-tools"];
|
|
53202
53682
|
var REQUIRED_SECTIONS = [
|
|
53203
53683
|
"## Role",
|
|
@@ -53237,10 +53717,10 @@ function countNamedPatterns(sectionText) {
|
|
|
53237
53717
|
return Math.max(h3Count, bulletCount);
|
|
53238
53718
|
}
|
|
53239
53719
|
function checkFile(filepath) {
|
|
53240
|
-
if (!
|
|
53720
|
+
if (!existsSync117(filepath) || !statSync32(filepath).isFile()) {
|
|
53241
53721
|
return { passed: false, failures: [`file not found: ${filepath}`], tokens: 0, mergedSkipped: false };
|
|
53242
53722
|
}
|
|
53243
|
-
const text =
|
|
53723
|
+
const text = readFileSync103(filepath, "utf8");
|
|
53244
53724
|
const { fm, body } = parseFile(text);
|
|
53245
53725
|
const failures = [];
|
|
53246
53726
|
for (const key of REQUIRED_FRONTMATTER_KEYS) {
|
|
@@ -53253,8 +53733,8 @@ function checkFile(filepath) {
|
|
|
53253
53733
|
const agentName = typeof fm.name === "string" ? fm.name : "";
|
|
53254
53734
|
let mergedSkipped = false;
|
|
53255
53735
|
if (!isNewAgent && agentName !== "") {
|
|
53256
|
-
const upstreamPath =
|
|
53257
|
-
if (
|
|
53736
|
+
const upstreamPath = join114(AGENTS_DIR, `${agentName}.md`);
|
|
53737
|
+
if (existsSync117(upstreamPath)) {
|
|
53258
53738
|
mergedSkipped = true;
|
|
53259
53739
|
}
|
|
53260
53740
|
}
|
|
@@ -53306,7 +53786,7 @@ Results: ${passCount} passed, ${failCount} failed
|
|
|
53306
53786
|
}
|
|
53307
53787
|
|
|
53308
53788
|
// src/commands/flywheel/diversity-check.ts
|
|
53309
|
-
import { readFileSync as
|
|
53789
|
+
import { readFileSync as readFileSync104 } from "node:fs";
|
|
53310
53790
|
import { basename as basename15 } from "node:path";
|
|
53311
53791
|
import { globSync as globSync2 } from "node:fs";
|
|
53312
53792
|
|
|
@@ -53386,7 +53866,7 @@ function formatRedivergencePrompt(personaA, personaB, score, drifted, revisionCo
|
|
|
53386
53866
|
` jaccard: ${score.toFixed(3)} (threshold: ${threshold})`,
|
|
53387
53867
|
` drifted: ${driftedName}`,
|
|
53388
53868
|
"",
|
|
53389
|
-
` Suggestion for next /
|
|
53869
|
+
` Suggestion for next /100x:learn revision of ${driftedName}:`,
|
|
53390
53870
|
` ADD content that reinforces ${driftedName}'s historically-owned cognitive patterns.`,
|
|
53391
53871
|
` DO NOT remove shared content \u2014 removing shared boilerplate lowers Jaccard arithmetically`,
|
|
53392
53872
|
` but does not restore identity differentiation.`,
|
|
@@ -53416,7 +53896,7 @@ function registerFlywheelDiversityCheck(parent) {
|
|
|
53416
53896
|
const personas = /* @__PURE__ */ new Map();
|
|
53417
53897
|
for (const filepath of files) {
|
|
53418
53898
|
try {
|
|
53419
|
-
const body =
|
|
53899
|
+
const body = readFileSync104(filepath, "utf8");
|
|
53420
53900
|
if (body.trim().length > 0) {
|
|
53421
53901
|
personas.set(basename15(filepath, ".md"), body);
|
|
53422
53902
|
}
|
|
@@ -53447,9 +53927,9 @@ ${formatRedivergencePrompt(persona_a, persona_b, score, void 0, void 0, threshol
|
|
|
53447
53927
|
}
|
|
53448
53928
|
|
|
53449
53929
|
// src/commands/flywheel/ping.ts
|
|
53450
|
-
import { mkdirSync as
|
|
53451
|
-
import { homedir as
|
|
53452
|
-
import { dirname as
|
|
53930
|
+
import { mkdirSync as mkdirSync69, writeFileSync as writeFileSync63 } from "node:fs";
|
|
53931
|
+
import { homedir as homedir71 } from "node:os";
|
|
53932
|
+
import { dirname as dirname66, join as join115 } from "node:path";
|
|
53453
53933
|
var COLD_START_BUDGET_GOOD_MS = 200;
|
|
53454
53934
|
var COLD_START_BUDGET_FAIR_MS = 500;
|
|
53455
53935
|
function classifyColdStart(coldStartMs) {
|
|
@@ -53465,9 +53945,9 @@ function readOlamVersion() {
|
|
|
53465
53945
|
}
|
|
53466
53946
|
}
|
|
53467
53947
|
function writeBaseline(record) {
|
|
53468
|
-
const baselinePath =
|
|
53469
|
-
|
|
53470
|
-
|
|
53948
|
+
const baselinePath = join115(homedir71(), ".local", "share", "olam", "flywheel-baseline.json");
|
|
53949
|
+
mkdirSync69(dirname66(baselinePath), { recursive: true });
|
|
53950
|
+
writeFileSync63(baselinePath, JSON.stringify(record, null, 2) + "\n", "utf8");
|
|
53471
53951
|
return baselinePath;
|
|
53472
53952
|
}
|
|
53473
53953
|
function registerFlywheelPing(parent) {
|
|
@@ -53507,16 +53987,16 @@ init_skill_sources();
|
|
|
53507
53987
|
init_prefix_rules();
|
|
53508
53988
|
import {
|
|
53509
53989
|
copyFileSync as copyFileSync15,
|
|
53510
|
-
existsSync as
|
|
53511
|
-
mkdirSync as
|
|
53512
|
-
readFileSync as
|
|
53990
|
+
existsSync as existsSync118,
|
|
53991
|
+
mkdirSync as mkdirSync70,
|
|
53992
|
+
readFileSync as readFileSync105,
|
|
53513
53993
|
readdirSync as readdirSync33,
|
|
53514
53994
|
statSync as statSync33,
|
|
53515
|
-
writeFileSync as
|
|
53995
|
+
writeFileSync as writeFileSync64
|
|
53516
53996
|
} from "node:fs";
|
|
53517
53997
|
import { spawnSync as spawnSync32 } from "node:child_process";
|
|
53518
|
-
import { homedir as
|
|
53519
|
-
import { dirname as
|
|
53998
|
+
import { homedir as homedir72 } from "node:os";
|
|
53999
|
+
import { dirname as dirname67, join as join116, relative as relative7 } from "node:path";
|
|
53520
54000
|
function escapeRegex(s) {
|
|
53521
54001
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
53522
54002
|
}
|
|
@@ -53553,7 +54033,7 @@ function walkOverlayFiles(dir) {
|
|
|
53553
54033
|
return [];
|
|
53554
54034
|
}
|
|
53555
54035
|
for (const entry of entries) {
|
|
53556
|
-
const fullPath =
|
|
54036
|
+
const fullPath = join116(dir, entry);
|
|
53557
54037
|
let stat;
|
|
53558
54038
|
try {
|
|
53559
54039
|
stat = statSync33(fullPath);
|
|
@@ -53592,10 +54072,10 @@ function resolveAtlasUser2(opts) {
|
|
|
53592
54072
|
assertValidAtlasUser(v);
|
|
53593
54073
|
return v;
|
|
53594
54074
|
}
|
|
53595
|
-
const claudeDir2 = opts._testClaudeDir ?? process.env["OLAM_CLAUDE_DIR"] ??
|
|
53596
|
-
const f =
|
|
53597
|
-
if (
|
|
53598
|
-
const v =
|
|
54075
|
+
const claudeDir2 = opts._testClaudeDir ?? process.env["OLAM_CLAUDE_DIR"] ?? join116(homedir72(), ".claude");
|
|
54076
|
+
const f = join116(claudeDir2, ".atlas-user");
|
|
54077
|
+
if (existsSync118(f)) {
|
|
54078
|
+
const v = readFileSync105(f, "utf-8").trim();
|
|
53599
54079
|
if (v.length === 0) return null;
|
|
53600
54080
|
assertValidAtlasUser(v);
|
|
53601
54081
|
return v;
|
|
@@ -53617,8 +54097,8 @@ function runGit2(args, cwd) {
|
|
|
53617
54097
|
function walkPushSourceFiles(claudeDir2) {
|
|
53618
54098
|
const result = [];
|
|
53619
54099
|
const roots = [
|
|
53620
|
-
{ dir:
|
|
53621
|
-
{ dir:
|
|
54100
|
+
{ dir: join116(claudeDir2, "skills.overrides"), overlayKind: "skills" },
|
|
54101
|
+
{ dir: join116(claudeDir2, "agents.overrides"), overlayKind: "agents" }
|
|
53622
54102
|
];
|
|
53623
54103
|
for (const { dir, overlayKind } of roots) {
|
|
53624
54104
|
const files = walkOverlayFiles(dir);
|
|
@@ -53729,7 +54209,7 @@ function pushOverlays(opts) {
|
|
|
53729
54209
|
Run \`olam skills atlas-user set <name>\` to configure your atlas user.`
|
|
53730
54210
|
);
|
|
53731
54211
|
}
|
|
53732
|
-
const claudeDir2 = opts._testClaudeDir ?? opts.targetDir ?? process.env["OLAM_CLAUDE_DIR"] ??
|
|
54212
|
+
const claudeDir2 = opts._testClaudeDir ?? opts.targetDir ?? process.env["OLAM_CLAUDE_DIR"] ?? join116(homedir72(), ".claude");
|
|
53733
54213
|
const sourceFiles = walkPushSourceFiles(claudeDir2);
|
|
53734
54214
|
const registeredPrefixes = (opts._testSkillSources ?? listSkillSources()).map((s) => s.prefix).filter((p) => typeof p === "string" && p.length > 0);
|
|
53735
54215
|
if (registeredPrefixes.length > 0) {
|
|
@@ -53737,7 +54217,7 @@ function pushOverlays(opts) {
|
|
|
53737
54217
|
const basename17 = relPath.split("/").pop() ?? relPath;
|
|
53738
54218
|
let content;
|
|
53739
54219
|
try {
|
|
53740
|
-
content =
|
|
54220
|
+
content = readFileSync105(srcFile);
|
|
53741
54221
|
} catch {
|
|
53742
54222
|
continue;
|
|
53743
54223
|
}
|
|
@@ -53776,21 +54256,21 @@ function pushOverlays(opts) {
|
|
|
53776
54256
|
` + preflightWarnings.map((w) => ` - ${w.split("\n")[0]}`).join("\n") + "\n"
|
|
53777
54257
|
);
|
|
53778
54258
|
}
|
|
53779
|
-
const membersBase2 =
|
|
54259
|
+
const membersBase2 = join116(clonePath, "members", atlasUser);
|
|
53780
54260
|
let wouldCopy = 0;
|
|
53781
54261
|
let wouldUnchange = 0;
|
|
53782
54262
|
let wouldCreate = 0;
|
|
53783
54263
|
for (const { srcFile, overlayKind, relPath } of sourceFiles) {
|
|
53784
|
-
const targetDir =
|
|
53785
|
-
const targetFile =
|
|
54264
|
+
const targetDir = join116(membersBase2, `${overlayKind}.overrides`);
|
|
54265
|
+
const targetFile = join116(targetDir, relPath);
|
|
53786
54266
|
let srcBuf;
|
|
53787
54267
|
try {
|
|
53788
|
-
srcBuf =
|
|
54268
|
+
srcBuf = readFileSync105(srcFile);
|
|
53789
54269
|
} catch {
|
|
53790
54270
|
continue;
|
|
53791
54271
|
}
|
|
53792
|
-
if (
|
|
53793
|
-
const dstBuf =
|
|
54272
|
+
if (existsSync118(targetFile)) {
|
|
54273
|
+
const dstBuf = readFileSync105(targetFile);
|
|
53794
54274
|
if (srcBuf.equals(dstBuf)) {
|
|
53795
54275
|
wouldUnchange += 1;
|
|
53796
54276
|
process.stdout.write(` [skip] ${overlayKind}.overrides/${relPath} (unchanged)
|
|
@@ -53831,32 +54311,32 @@ function pushOverlays(opts) {
|
|
|
53831
54311
|
`failed to create branch "${branchName}": ${err instanceof Error ? err.message : String(err)}`
|
|
53832
54312
|
);
|
|
53833
54313
|
}
|
|
53834
|
-
const membersBase =
|
|
54314
|
+
const membersBase = join116(clonePath, "members", atlasUser);
|
|
53835
54315
|
let filesCopied = 0;
|
|
53836
54316
|
let filesUnchanged = 0;
|
|
53837
54317
|
let filesCreated = 0;
|
|
53838
54318
|
try {
|
|
53839
54319
|
for (const { srcFile, overlayKind, relPath } of sourceFiles) {
|
|
53840
|
-
const targetDir =
|
|
53841
|
-
const targetFile =
|
|
54320
|
+
const targetDir = join116(membersBase, `${overlayKind}.overrides`, dirname67(relPath));
|
|
54321
|
+
const targetFile = join116(membersBase, `${overlayKind}.overrides`, relPath);
|
|
53842
54322
|
let srcBuf;
|
|
53843
54323
|
try {
|
|
53844
|
-
srcBuf =
|
|
54324
|
+
srcBuf = readFileSync105(srcFile);
|
|
53845
54325
|
} catch {
|
|
53846
54326
|
continue;
|
|
53847
54327
|
}
|
|
53848
|
-
const targetExists =
|
|
54328
|
+
const targetExists = existsSync118(targetFile);
|
|
53849
54329
|
if (targetExists) {
|
|
53850
|
-
const dstBuf =
|
|
54330
|
+
const dstBuf = readFileSync105(targetFile);
|
|
53851
54331
|
if (srcBuf.equals(dstBuf)) {
|
|
53852
54332
|
filesUnchanged += 1;
|
|
53853
54333
|
continue;
|
|
53854
54334
|
}
|
|
53855
|
-
|
|
54335
|
+
mkdirSync70(targetDir, { recursive: true });
|
|
53856
54336
|
copyFileSync15(srcFile, targetFile);
|
|
53857
54337
|
filesCopied += 1;
|
|
53858
54338
|
} else {
|
|
53859
|
-
|
|
54339
|
+
mkdirSync70(targetDir, { recursive: true });
|
|
53860
54340
|
copyFileSync15(srcFile, targetFile);
|
|
53861
54341
|
filesCreated += 1;
|
|
53862
54342
|
}
|
|
@@ -53924,8 +54404,8 @@ function initMember(opts) {
|
|
|
53924
54404
|
clonePath = skillSourceClonePath(source.id);
|
|
53925
54405
|
}
|
|
53926
54406
|
const atlasUser = resolveAtlasUser2(opts) ?? memberName;
|
|
53927
|
-
const memberDir =
|
|
53928
|
-
if (
|
|
54407
|
+
const memberDir = join116(clonePath, "members", memberName);
|
|
54408
|
+
if (existsSync118(memberDir)) {
|
|
53929
54409
|
throw new PushError(
|
|
53930
54410
|
1,
|
|
53931
54411
|
`members/${memberName}/ already exists; use --push to update; or remove manually first
|
|
@@ -53933,9 +54413,9 @@ function initMember(opts) {
|
|
|
53933
54413
|
);
|
|
53934
54414
|
}
|
|
53935
54415
|
const wouldCreate = [
|
|
53936
|
-
|
|
53937
|
-
|
|
53938
|
-
|
|
54416
|
+
join116(memberDir, "skills.overrides", ".gitkeep"),
|
|
54417
|
+
join116(memberDir, "agents.overrides", ".gitkeep"),
|
|
54418
|
+
join116(memberDir, "README.md")
|
|
53939
54419
|
];
|
|
53940
54420
|
if (opts.dryRun === true) {
|
|
53941
54421
|
const { preflightWarnings } = runPreFlight(clonePath, opts.forceCurrentBranch === true, true);
|
|
@@ -53991,12 +54471,12 @@ function initMember(opts) {
|
|
|
53991
54471
|
);
|
|
53992
54472
|
}
|
|
53993
54473
|
try {
|
|
53994
|
-
|
|
53995
|
-
|
|
53996
|
-
|
|
53997
|
-
|
|
53998
|
-
|
|
53999
|
-
|
|
54474
|
+
mkdirSync70(join116(memberDir, "skills.overrides"), { recursive: true });
|
|
54475
|
+
writeFileSync64(join116(memberDir, "skills.overrides", ".gitkeep"), "");
|
|
54476
|
+
mkdirSync70(join116(memberDir, "agents.overrides"), { recursive: true });
|
|
54477
|
+
writeFileSync64(join116(memberDir, "agents.overrides", ".gitkeep"), "");
|
|
54478
|
+
writeFileSync64(
|
|
54479
|
+
join116(memberDir, "README.md"),
|
|
54000
54480
|
`# Member overlays for \`${memberName}\`
|
|
54001
54481
|
|
|
54002
54482
|
See docs/plans/member-overlays-sync/ for layer architecture.
|
|
@@ -54037,10 +54517,10 @@ Next steps (run in ${clonePath}):`,
|
|
|
54037
54517
|
};
|
|
54038
54518
|
}
|
|
54039
54519
|
function migrateOverlays(opts = {}) {
|
|
54040
|
-
const root = opts.targetDir ??
|
|
54520
|
+
const root = opts.targetDir ?? join116(homedir72(), ".claude");
|
|
54041
54521
|
const overrideRoots = [
|
|
54042
|
-
|
|
54043
|
-
|
|
54522
|
+
join116(root, "skills.overrides"),
|
|
54523
|
+
join116(root, "agents.overrides")
|
|
54044
54524
|
];
|
|
54045
54525
|
const allFiles = [];
|
|
54046
54526
|
for (const overrideRoot of overrideRoots) {
|
|
@@ -54056,7 +54536,7 @@ function migrateOverlays(opts = {}) {
|
|
|
54056
54536
|
for (const filePath of allFiles) {
|
|
54057
54537
|
let original;
|
|
54058
54538
|
try {
|
|
54059
|
-
original =
|
|
54539
|
+
original = readFileSync105(filePath, "utf8");
|
|
54060
54540
|
} catch {
|
|
54061
54541
|
continue;
|
|
54062
54542
|
}
|
|
@@ -54067,7 +54547,7 @@ function migrateOverlays(opts = {}) {
|
|
|
54067
54547
|
continue;
|
|
54068
54548
|
}
|
|
54069
54549
|
if (opts.dryRun !== true) {
|
|
54070
|
-
|
|
54550
|
+
writeFileSync64(filePath, newContent, "utf8");
|
|
54071
54551
|
}
|
|
54072
54552
|
summary2.modified += 1;
|
|
54073
54553
|
summary2.totalReplacements += totalReplacements;
|
|
@@ -54159,7 +54639,7 @@ function registerFlywheelMigrateOverlays(parent) {
|
|
|
54159
54639
|
}
|
|
54160
54640
|
return;
|
|
54161
54641
|
}
|
|
54162
|
-
const root = opts.targetDir ??
|
|
54642
|
+
const root = opts.targetDir ?? join116(homedir72(), ".claude");
|
|
54163
54643
|
const summary2 = migrateOverlays(opts);
|
|
54164
54644
|
if (opts.json === true) {
|
|
54165
54645
|
process.stdout.write(JSON.stringify(summary2, null, 2) + "\n");
|
|
@@ -54198,9 +54678,9 @@ Per-file changes:
|
|
|
54198
54678
|
}
|
|
54199
54679
|
|
|
54200
54680
|
// src/commands/flywheel/session-start.ts
|
|
54201
|
-
import { readFileSync as
|
|
54202
|
-
import { homedir as
|
|
54203
|
-
import { join as
|
|
54681
|
+
import { readFileSync as readFileSync106, statSync as statSync34 } from "node:fs";
|
|
54682
|
+
import { homedir as homedir73 } from "node:os";
|
|
54683
|
+
import { join as join117 } from "node:path";
|
|
54204
54684
|
var SESSIONSTART_HOOK_SENTINEL = "olam-sessionstart-context-hook-v1";
|
|
54205
54685
|
var MAX_WAKE_BRIEF_BYTES = 8 * 1024;
|
|
54206
54686
|
var MAX_ACTIVE_WORLD_BYTES = 4 * 1024;
|
|
@@ -54216,7 +54696,7 @@ function tryReadCapped(path106, maxBytes) {
|
|
|
54216
54696
|
);
|
|
54217
54697
|
return null;
|
|
54218
54698
|
}
|
|
54219
|
-
return
|
|
54699
|
+
return readFileSync106(path106, "utf-8");
|
|
54220
54700
|
} catch (err) {
|
|
54221
54701
|
const code = err?.code;
|
|
54222
54702
|
if (code === "ENOENT") return null;
|
|
@@ -54241,15 +54721,15 @@ function tryParseJson(raw, label) {
|
|
|
54241
54721
|
}
|
|
54242
54722
|
function buildContextBlock(olamHome6) {
|
|
54243
54723
|
const config = tryParseJson(
|
|
54244
|
-
tryReadCapped(
|
|
54724
|
+
tryReadCapped(join117(olamHome6, "config.json"), MAX_CONFIG_BYTES),
|
|
54245
54725
|
"config.json"
|
|
54246
54726
|
);
|
|
54247
54727
|
const activeWorld = tryParseJson(
|
|
54248
|
-
tryReadCapped(
|
|
54728
|
+
tryReadCapped(join117(olamHome6, "state", "active-world.json"), MAX_ACTIVE_WORLD_BYTES),
|
|
54249
54729
|
"active-world.json"
|
|
54250
54730
|
);
|
|
54251
54731
|
const wakeBrief = tryReadCapped(
|
|
54252
|
-
|
|
54732
|
+
join117(olamHome6, "state", "wake-brief.md"),
|
|
54253
54733
|
MAX_WAKE_BRIEF_BYTES
|
|
54254
54734
|
);
|
|
54255
54735
|
const sections = [];
|
|
@@ -54301,7 +54781,7 @@ function registerFlywheelSessionStart(parent) {
|
|
|
54301
54781
|
parent.command("session-start").description(
|
|
54302
54782
|
"Emit operator-state context for the SessionStart hook (4th defense layer). Reads ~/.olam/state/* and writes the additionalContext JSON to stdout. Fail-soft: always exits 0."
|
|
54303
54783
|
).action(() => {
|
|
54304
|
-
const olamHome6 = process.env.OLAM_HOME ??
|
|
54784
|
+
const olamHome6 = process.env.OLAM_HOME ?? join117(homedir73(), ".olam");
|
|
54305
54785
|
emitSessionStartContext(olamHome6);
|
|
54306
54786
|
process.exit(0);
|
|
54307
54787
|
});
|
|
@@ -54310,9 +54790,9 @@ function registerFlywheelSessionStart(parent) {
|
|
|
54310
54790
|
// src/commands/flywheel/install-sessionstart-hook.ts
|
|
54311
54791
|
init_merge_settings();
|
|
54312
54792
|
init_output();
|
|
54313
|
-
import { existsSync as
|
|
54314
|
-
import { homedir as
|
|
54315
|
-
import { dirname as
|
|
54793
|
+
import { existsSync as existsSync119, copyFileSync as copyFileSync16, mkdirSync as mkdirSync71, readFileSync as readFileSync107, unlinkSync as unlinkSync25, writeFileSync as writeFileSync65 } from "node:fs";
|
|
54794
|
+
import { homedir as homedir74 } from "node:os";
|
|
54795
|
+
import { dirname as dirname68, join as join118 } from "node:path";
|
|
54316
54796
|
var SESSIONSTART_HOOK_STAGE = "SessionStart";
|
|
54317
54797
|
var SESSIONSTART_HOOK_TIMEOUT_MS = 5e3;
|
|
54318
54798
|
var NOOP_GUARD = "command -v olam >/dev/null 2>&1 || exit 0;";
|
|
@@ -54329,18 +54809,18 @@ function buildSessionStartHookEntry() {
|
|
|
54329
54809
|
};
|
|
54330
54810
|
}
|
|
54331
54811
|
function settingsPathFor4(scope, cwd) {
|
|
54332
|
-
if (scope === "user") return
|
|
54333
|
-
return
|
|
54812
|
+
if (scope === "user") return join118(homedir74(), ".claude", "settings.json");
|
|
54813
|
+
return join118(cwd ?? process.cwd(), ".claude", "settings.json");
|
|
54334
54814
|
}
|
|
54335
54815
|
function backup3(filePath) {
|
|
54336
|
-
if (!
|
|
54816
|
+
if (!existsSync119(filePath)) return null;
|
|
54337
54817
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
54338
54818
|
const backupPath = `${filePath}.olam-bak.${ts}`;
|
|
54339
54819
|
copyFileSync16(filePath, backupPath);
|
|
54340
54820
|
return backupPath;
|
|
54341
54821
|
}
|
|
54342
54822
|
function installSessionStartHook(filePath) {
|
|
54343
|
-
|
|
54823
|
+
mkdirSync71(dirname68(filePath), { recursive: true });
|
|
54344
54824
|
const backupPath = backup3(filePath);
|
|
54345
54825
|
const result = mergeHomeSettingsJson(filePath, {
|
|
54346
54826
|
ensureHook: {
|
|
@@ -54359,8 +54839,8 @@ function installSessionStartHook(filePath) {
|
|
|
54359
54839
|
return { status: result.status, filePath, backupPath };
|
|
54360
54840
|
}
|
|
54361
54841
|
function uninstallSessionStartHook(filePath) {
|
|
54362
|
-
if (!
|
|
54363
|
-
const raw =
|
|
54842
|
+
if (!existsSync119(filePath)) return { status: "no-settings", filePath };
|
|
54843
|
+
const raw = readFileSync107(filePath, "utf-8");
|
|
54364
54844
|
const settings = raw.trim() ? JSON.parse(raw) : {};
|
|
54365
54845
|
const matchers = settings.hooks?.SessionStart;
|
|
54366
54846
|
if (!Array.isArray(matchers) || matchers.length === 0) {
|
|
@@ -54400,7 +54880,7 @@ function uninstallSessionStartHook(filePath) {
|
|
|
54400
54880
|
delete next.hooks.SessionStart;
|
|
54401
54881
|
}
|
|
54402
54882
|
}
|
|
54403
|
-
|
|
54883
|
+
writeFileSync65(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
54404
54884
|
return { status: "removed", filePath };
|
|
54405
54885
|
}
|
|
54406
54886
|
function registerFlywheelInstallSessionStartHook(parent) {
|
|
@@ -54718,7 +55198,7 @@ init_manager();
|
|
|
54718
55198
|
init_context();
|
|
54719
55199
|
init_output();
|
|
54720
55200
|
import { spawnSync as defaultSpawnSync } from "node:child_process";
|
|
54721
|
-
import * as
|
|
55201
|
+
import * as fs105 from "node:fs";
|
|
54722
55202
|
import * as os58 from "node:os";
|
|
54723
55203
|
import * as path103 from "node:path";
|
|
54724
55204
|
function devboxContainerName(worldId) {
|
|
@@ -54738,8 +55218,8 @@ function defaultRestartContainer(name, spawn14 = defaultSpawnSync) {
|
|
|
54738
55218
|
};
|
|
54739
55219
|
}
|
|
54740
55220
|
function defaultAppendAuditLog(homeDir, line) {
|
|
54741
|
-
|
|
54742
|
-
|
|
55221
|
+
fs105.mkdirSync(homeDir, { recursive: true });
|
|
55222
|
+
fs105.appendFileSync(path103.join(homeDir, "usage.log"), line.endsWith("\n") ? line : line + "\n", {
|
|
54743
55223
|
encoding: "utf-8"
|
|
54744
55224
|
});
|
|
54745
55225
|
}
|
|
@@ -54785,18 +55265,18 @@ async function doRekey(worldId, deps) {
|
|
|
54785
55265
|
const rotatedAt = deps.now().toISOString();
|
|
54786
55266
|
const homeDir = deps.olamHomeDir();
|
|
54787
55267
|
const worldDir = path103.join(homeDir, "worlds", worldId);
|
|
54788
|
-
|
|
55268
|
+
fs105.mkdirSync(worldDir, { recursive: true });
|
|
54789
55269
|
const credentialsPath = path103.join(worldDir, "credentials.json");
|
|
54790
55270
|
const payload = {
|
|
54791
55271
|
worldRoleName,
|
|
54792
55272
|
password,
|
|
54793
55273
|
rotatedAt
|
|
54794
55274
|
};
|
|
54795
|
-
|
|
55275
|
+
fs105.writeFileSync(credentialsPath, JSON.stringify(payload, null, 2) + "\n", {
|
|
54796
55276
|
encoding: "utf-8",
|
|
54797
55277
|
mode: 384
|
|
54798
55278
|
});
|
|
54799
|
-
|
|
55279
|
+
fs105.chmodSync(credentialsPath, 384);
|
|
54800
55280
|
const restart = deps.restartContainer(devboxContainerName(worldId));
|
|
54801
55281
|
deps.appendAuditLog(`${rotatedAt} ${worldId} rekey`);
|
|
54802
55282
|
if (!restart.ok) {
|
|
@@ -54862,7 +55342,7 @@ function registerRekey(program2) {
|
|
|
54862
55342
|
// src/commands/yolo.ts
|
|
54863
55343
|
init_output();
|
|
54864
55344
|
import * as childProcess2 from "node:child_process";
|
|
54865
|
-
import * as
|
|
55345
|
+
import * as fs106 from "node:fs";
|
|
54866
55346
|
import * as os59 from "node:os";
|
|
54867
55347
|
import * as path104 from "node:path";
|
|
54868
55348
|
import pc49 from "picocolors";
|
|
@@ -54887,12 +55367,12 @@ function defaultRunner(cmd, args, opts) {
|
|
|
54887
55367
|
};
|
|
54888
55368
|
}
|
|
54889
55369
|
function defaultSleeper(ms) {
|
|
54890
|
-
return new Promise((
|
|
55370
|
+
return new Promise((resolve31) => setTimeout(resolve31, ms));
|
|
54891
55371
|
}
|
|
54892
55372
|
function detectTmuxBinary(runner = defaultRunner) {
|
|
54893
55373
|
for (const p of TMUX_PROBE_PATHS) {
|
|
54894
55374
|
if (TMUX_SHIM_MARKERS.some((m) => p.includes(m))) continue;
|
|
54895
|
-
if (
|
|
55375
|
+
if (fs106.existsSync(p)) return p;
|
|
54896
55376
|
}
|
|
54897
55377
|
const result = runner("which", ["tmux"]);
|
|
54898
55378
|
if (result.status === 0 && result.stdout) {
|
|
@@ -54907,8 +55387,8 @@ function resolveWorktreeRoot(runner = defaultRunner, cwd = process.cwd()) {
|
|
|
54907
55387
|
return process.env["OLAM_TMUX_YOLO_ROOT"];
|
|
54908
55388
|
}
|
|
54909
55389
|
const rootFile = path104.join(os59.homedir(), ".olam-tmux-yolo-root");
|
|
54910
|
-
if (
|
|
54911
|
-
const line =
|
|
55390
|
+
if (fs106.existsSync(rootFile)) {
|
|
55391
|
+
const line = fs106.readFileSync(rootFile, "utf-8").trim();
|
|
54912
55392
|
if (line) return line;
|
|
54913
55393
|
}
|
|
54914
55394
|
const gitResult = runner("git", ["rev-parse", "--show-toplevel"], { cwd });
|
|
@@ -54942,7 +55422,7 @@ async function spawnYolo(opts) {
|
|
|
54942
55422
|
);
|
|
54943
55423
|
}
|
|
54944
55424
|
try {
|
|
54945
|
-
|
|
55425
|
+
fs106.accessSync(opts.promptFile, fs106.constants.R_OK);
|
|
54946
55426
|
} catch {
|
|
54947
55427
|
throw new Error(
|
|
54948
55428
|
`Prompt file not found or not readable: ${opts.promptFile}
|
|
@@ -54958,7 +55438,7 @@ Create the file with your task description and try again.`
|
|
|
54958
55438
|
Run: olam yolo --cleanup ${opts.name} (or use --force to bypass the merged check)`
|
|
54959
55439
|
);
|
|
54960
55440
|
}
|
|
54961
|
-
if (
|
|
55441
|
+
if (fs106.existsSync(worktreePath)) {
|
|
54962
55442
|
throw new Error(
|
|
54963
55443
|
`Worktree directory already exists: ${worktreePath}
|
|
54964
55444
|
Run: olam yolo --cleanup ${opts.name} to remove it first.`
|
|
@@ -55026,7 +55506,7 @@ function listYoloWindows(opts = {}) {
|
|
|
55026
55506
|
const worktreePath = path104.join(worktreeRoot, name);
|
|
55027
55507
|
return {
|
|
55028
55508
|
name,
|
|
55029
|
-
worktreePath:
|
|
55509
|
+
worktreePath: fs106.existsSync(worktreePath) ? worktreePath : void 0
|
|
55030
55510
|
};
|
|
55031
55511
|
});
|
|
55032
55512
|
}
|
|
@@ -55160,18 +55640,18 @@ function registerYolo(program2) {
|
|
|
55160
55640
|
}
|
|
55161
55641
|
|
|
55162
55642
|
// src/pleri-config.ts
|
|
55163
|
-
import * as
|
|
55643
|
+
import * as fs107 from "node:fs";
|
|
55164
55644
|
import * as path105 from "node:path";
|
|
55165
55645
|
function isPleriConfigured(configDir = process.env.OLAM_CONFIG_DIR ?? ".olam") {
|
|
55166
55646
|
if (process.env.PLERI_BASE_URL) {
|
|
55167
55647
|
return true;
|
|
55168
55648
|
}
|
|
55169
55649
|
const configPath = path105.join(configDir, "config.yaml");
|
|
55170
|
-
if (!
|
|
55650
|
+
if (!fs107.existsSync(configPath)) {
|
|
55171
55651
|
return false;
|
|
55172
55652
|
}
|
|
55173
55653
|
try {
|
|
55174
|
-
const contents =
|
|
55654
|
+
const contents = fs107.readFileSync(configPath, "utf8");
|
|
55175
55655
|
return /^[^#\n]*\bpleri:/m.test(contents);
|
|
55176
55656
|
} catch {
|
|
55177
55657
|
return false;
|
|
@@ -55210,7 +55690,7 @@ var HELP_GROUPS = [
|
|
|
55210
55690
|
},
|
|
55211
55691
|
{
|
|
55212
55692
|
title: "Skills & knowledge",
|
|
55213
|
-
names: ["skills", "kg", "ask", "flywheel"]
|
|
55693
|
+
names: ["skills", "100x", "kg", "ask", "flywheel"]
|
|
55214
55694
|
},
|
|
55215
55695
|
{
|
|
55216
55696
|
title: "Substrate & infra",
|
|
@@ -55373,7 +55853,7 @@ registerSkillsMigrateHooks(program);
|
|
|
55373
55853
|
registerSkillsMigrateHooksBack(program);
|
|
55374
55854
|
registerSkillsShadowBackups(program);
|
|
55375
55855
|
registerSkillsDoctor(program);
|
|
55376
|
-
|
|
55856
|
+
registerSkills100x(program);
|
|
55377
55857
|
registerHermes(program);
|
|
55378
55858
|
void scheduleUpgradeCheck(cliVersion);
|
|
55379
55859
|
await program.parseAsync();
|