@pleri/olam-cli 0.1.157 → 0.1.159
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/commands/doctor.d.ts +21 -10
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +95 -39
- package/dist/commands/doctor.js.map +1 -1
- package/dist/image-digests.json +7 -7
- package/dist/index.js +638 -289
- package/dist/index.js.map +1 -1
- package/dist/lib/host-side-proxy.d.ts +67 -0
- package/dist/lib/host-side-proxy.d.ts.map +1 -0
- package/dist/lib/host-side-proxy.js +177 -0
- package/dist/lib/host-side-proxy.js.map +1 -0
- package/dist/lib/k8s-secret-render.d.ts.map +1 -1
- package/dist/lib/k8s-secret-render.js +7 -4
- package/dist/lib/k8s-secret-render.js.map +1 -1
- package/dist/lib/upgrade-kubernetes.d.ts +17 -13
- package/dist/lib/upgrade-kubernetes.d.ts.map +1 -1
- package/dist/lib/upgrade-kubernetes.js +122 -165
- package/dist/lib/upgrade-kubernetes.js.map +1 -1
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/host-side/docker-socket-proxy.compose.yaml +58 -0
- package/host-cp/k8s/manifests/50-deployment.yaml +47 -70
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/docker-socket-proxy/60-service.yaml +37 -0
- package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
- package/host-cp/src/metrics.mjs +281 -0
- package/host-cp/src/server.mjs +31 -2
- package/host-cp/src/tasks-route.mjs +191 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,12 +3,6 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
7
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
8
|
-
}) : x)(function(x) {
|
|
9
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
10
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
11
|
-
});
|
|
12
6
|
var __esm = (fn, res) => function __init() {
|
|
13
7
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
14
8
|
};
|
|
@@ -6398,21 +6392,21 @@ var init_exec = __esm({
|
|
|
6398
6392
|
const stream = await exec.start({ Detach: false, Tty: false });
|
|
6399
6393
|
const timeoutMs = opts?.timeout ? opts.timeout * 1e3 : void 0;
|
|
6400
6394
|
const outputPromise = demuxStream(stream);
|
|
6401
|
-
let
|
|
6395
|
+
let output2;
|
|
6402
6396
|
if (timeoutMs) {
|
|
6403
6397
|
const timer = new Promise((_, reject) => {
|
|
6404
6398
|
setTimeout(() => reject(new Error(`Command timed out after ${opts.timeout}s`)), timeoutMs);
|
|
6405
6399
|
});
|
|
6406
|
-
|
|
6400
|
+
output2 = await Promise.race([outputPromise, timer]);
|
|
6407
6401
|
} else {
|
|
6408
|
-
|
|
6402
|
+
output2 = await outputPromise;
|
|
6409
6403
|
}
|
|
6410
6404
|
const inspection = await exec.inspect();
|
|
6411
6405
|
const exitCode = inspection.ExitCode ?? 1;
|
|
6412
6406
|
return {
|
|
6413
6407
|
exitCode,
|
|
6414
|
-
stdout:
|
|
6415
|
-
stderr:
|
|
6408
|
+
stdout: output2.stdout,
|
|
6409
|
+
stderr: output2.stderr
|
|
6416
6410
|
};
|
|
6417
6411
|
};
|
|
6418
6412
|
}
|
|
@@ -7890,27 +7884,6 @@ function hasImageRef(present, ref) {
|
|
|
7890
7884
|
const variants = [`docker.io/library/${ref}`, `docker.io/${ref}`];
|
|
7891
7885
|
return variants.some((v) => present.has(v));
|
|
7892
7886
|
}
|
|
7893
|
-
function defaultDetectK8sClusterType(kubectlContext) {
|
|
7894
|
-
const ctx = kubectlContext ?? readCurrentKubectlContext();
|
|
7895
|
-
if (!ctx) return "unknown";
|
|
7896
|
-
if (ctx.startsWith("colima")) return "colima";
|
|
7897
|
-
if (ctx.startsWith("k3d-")) return "k3d";
|
|
7898
|
-
return "unknown";
|
|
7899
|
-
}
|
|
7900
|
-
function readCurrentKubectlContext() {
|
|
7901
|
-
const r = spawnSync3("kubectl", ["config", "current-context"], {
|
|
7902
|
-
encoding: "utf-8",
|
|
7903
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
7904
|
-
});
|
|
7905
|
-
if (r.status !== 0) return void 0;
|
|
7906
|
-
return r.stdout?.trim() || void 0;
|
|
7907
|
-
}
|
|
7908
|
-
function buildDockerSocketRemedy(clusterType) {
|
|
7909
|
-
if (clusterType === "colima") {
|
|
7910
|
-
return "Recreate the Colima k3s cluster with the docker socket bind-mount:\n colima stop\n colima start --kubernetes \\\n --mount /var/run/docker.sock:/var/run/docker.sock:w \\\n --mount ~/.config/gh:/host/.config/gh:r\nThen run: olam upgrade";
|
|
7911
|
-
}
|
|
7912
|
-
return "Recreate the k3d cluster with the docker socket bind-mount:\n k3d cluster create olam-host \\\n --volume /var/run/docker.sock:/var/run/docker.sock@server:* \\\n --volume ~/.config/gh:/host/.config/gh \\\n --wait --timeout 90s\nThen run: olam upgrade";
|
|
7913
|
-
}
|
|
7914
7887
|
var HEALTH_TIMEOUT_MS, COLIMA_010_WARN_TEXT, COLIMA_010_RANGE, defaultDockerExec, defaultFetch;
|
|
7915
7888
|
var init_health_probes = __esm({
|
|
7916
7889
|
"src/lib/health-probes.ts"() {
|
|
@@ -8481,8 +8454,8 @@ function removeBranch(repo, branch) {
|
|
|
8481
8454
|
}
|
|
8482
8455
|
let localCommitCount = 0;
|
|
8483
8456
|
try {
|
|
8484
|
-
const
|
|
8485
|
-
localCommitCount = parseInt(
|
|
8457
|
+
const output2 = execFileSync2("git", ["rev-list", "--count", branch, "--not", "--remotes"], { cwd: gitDir, stdio: "pipe" }).toString().trim();
|
|
8458
|
+
localCommitCount = parseInt(output2, 10) || 0;
|
|
8486
8459
|
} catch {
|
|
8487
8460
|
localCommitCount = 1;
|
|
8488
8461
|
}
|
|
@@ -8717,8 +8690,8 @@ function writeStrippedMcpServersSnapshot(homeDir, workspacePath, destClaudeDir)
|
|
|
8717
8690
|
...stripMcpServers(hostMcpServers),
|
|
8718
8691
|
...stripMcpServers(projectMcpServers)
|
|
8719
8692
|
};
|
|
8720
|
-
const
|
|
8721
|
-
fs13.writeFileSync(path15.join(destClaudeDir, ".claude.json"), JSON.stringify(
|
|
8693
|
+
const output2 = { mcpServers: stripped };
|
|
8694
|
+
fs13.writeFileSync(path15.join(destClaudeDir, ".claude.json"), JSON.stringify(output2, null, 2), { mode: 384 });
|
|
8722
8695
|
}
|
|
8723
8696
|
function writeWorldEntitlementsJson(workspacePath, configCtx) {
|
|
8724
8697
|
const olamDir = path15.join(workspacePath, ".olam");
|
|
@@ -9241,8 +9214,8 @@ import { execFileSync as execFileSync4 } from "node:child_process";
|
|
|
9241
9214
|
import * as fs15 from "node:fs";
|
|
9242
9215
|
import * as os9 from "node:os";
|
|
9243
9216
|
import * as path17 from "node:path";
|
|
9244
|
-
function expandHome2(p,
|
|
9245
|
-
return p.replace(/^~(?=$|\/|\\)/,
|
|
9217
|
+
function expandHome2(p, homedir55) {
|
|
9218
|
+
return p.replace(/^~(?=$|\/|\\)/, homedir55());
|
|
9246
9219
|
}
|
|
9247
9220
|
function sanitizeRepoFilename(name) {
|
|
9248
9221
|
const sanitized = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
@@ -9265,7 +9238,7 @@ ${stderr}`;
|
|
|
9265
9238
|
}
|
|
9266
9239
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
9267
9240
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync4(cmd, args, opts));
|
|
9268
|
-
const
|
|
9241
|
+
const homedir55 = deps.homedir ?? (() => os9.homedir());
|
|
9269
9242
|
const baselineDir = path17.join(workspacePath, ".olam", "baseline");
|
|
9270
9243
|
try {
|
|
9271
9244
|
fs15.mkdirSync(baselineDir, { recursive: true });
|
|
@@ -9281,7 +9254,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
9281
9254
|
continue;
|
|
9282
9255
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
9283
9256
|
const outPath = path17.join(baselineDir, filename);
|
|
9284
|
-
const repoPath = expandHome2(repo.path,
|
|
9257
|
+
const repoPath = expandHome2(repo.path, homedir55);
|
|
9285
9258
|
if (!fs15.existsSync(repoPath)) {
|
|
9286
9259
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
9287
9260
|
# (skipped: path ${repoPath} does not exist)
|
|
@@ -9401,8 +9374,8 @@ function extractStderr(err) {
|
|
|
9401
9374
|
}
|
|
9402
9375
|
function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
9403
9376
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync4(cmd, args, opts));
|
|
9404
|
-
const
|
|
9405
|
-
const
|
|
9377
|
+
const homedir55 = deps.homedir ?? (() => os9.homedir());
|
|
9378
|
+
const existsSync103 = deps.existsSync ?? ((p) => fs15.existsSync(p));
|
|
9406
9379
|
const copyFileSync12 = deps.copyFileSync ?? ((src, dest) => fs15.copyFileSync(src, dest));
|
|
9407
9380
|
const mkdirSync60 = deps.mkdirSync ?? ((dirPath, opts) => {
|
|
9408
9381
|
fs15.mkdirSync(dirPath, opts);
|
|
@@ -9411,11 +9384,11 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
9411
9384
|
for (const repo of repos) {
|
|
9412
9385
|
if (!repo.path)
|
|
9413
9386
|
continue;
|
|
9414
|
-
const repoPath = expandHome2(repo.path,
|
|
9387
|
+
const repoPath = expandHome2(repo.path, homedir55);
|
|
9415
9388
|
const worktreePath = path17.join(workspacePath, repo.name);
|
|
9416
|
-
if (!
|
|
9389
|
+
if (!existsSync103(repoPath))
|
|
9417
9390
|
continue;
|
|
9418
|
-
if (!
|
|
9391
|
+
if (!existsSync103(worktreePath)) {
|
|
9419
9392
|
console.warn(`[carry] ${repo.name}: world worktree ${worktreePath} missing; skipping carry for this repo`);
|
|
9420
9393
|
continue;
|
|
9421
9394
|
}
|
|
@@ -9475,7 +9448,7 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
9475
9448
|
for (const rel of plan.diff.untracked) {
|
|
9476
9449
|
const src = path17.join(plan.repoPath, rel);
|
|
9477
9450
|
const dest = path17.join(plan.worktreePath, rel);
|
|
9478
|
-
if (!
|
|
9451
|
+
if (!existsSync103(src))
|
|
9479
9452
|
continue;
|
|
9480
9453
|
try {
|
|
9481
9454
|
mkdirSync60(path17.dirname(dest), { recursive: true });
|
|
@@ -19073,6 +19046,7 @@ __export(project_sweep_exports, {
|
|
|
19073
19046
|
walkProjectRoot: () => walkProjectRoot
|
|
19074
19047
|
});
|
|
19075
19048
|
import * as path69 from "node:path";
|
|
19049
|
+
import { readdirSync as readdirSync22, lstatSync as lstatSync5, statSync as statSync23, existsSync as existsSync77 } from "node:fs";
|
|
19076
19050
|
function isSkipped(basename13, extra) {
|
|
19077
19051
|
if (DEFAULT_SKIP.has(basename13))
|
|
19078
19052
|
return true;
|
|
@@ -19135,12 +19109,11 @@ function walk2(currentPath, depth, maxDepth, extraExclude, fsAdapter, results) {
|
|
|
19135
19109
|
}
|
|
19136
19110
|
}
|
|
19137
19111
|
function makeRealFsAdapter() {
|
|
19138
|
-
const fs92 = __require("node:fs");
|
|
19139
19112
|
return {
|
|
19140
|
-
readdirSync: (p) =>
|
|
19113
|
+
readdirSync: (p) => readdirSync22(p, { encoding: "utf-8" }),
|
|
19141
19114
|
// lstatSync does NOT follow symlinks — used for descent decisions.
|
|
19142
19115
|
lstatSync: (p) => {
|
|
19143
|
-
const s =
|
|
19116
|
+
const s = lstatSync5(p, { throwIfNoEntry: true });
|
|
19144
19117
|
return {
|
|
19145
19118
|
isDirectory: () => s.isDirectory(),
|
|
19146
19119
|
isSymbolicLink: () => s.isSymbolicLink(),
|
|
@@ -19149,10 +19122,10 @@ function makeRealFsAdapter() {
|
|
|
19149
19122
|
},
|
|
19150
19123
|
// statSync DOES follow symlinks — used only for mtime reads on manifest/HEAD files.
|
|
19151
19124
|
statSync: (p) => {
|
|
19152
|
-
const s =
|
|
19125
|
+
const s = statSync23(p, { throwIfNoEntry: true });
|
|
19153
19126
|
return { isDirectory: () => s.isDirectory(), mtimeMs: s.mtimeMs };
|
|
19154
19127
|
},
|
|
19155
|
-
existsSync: (p) =>
|
|
19128
|
+
existsSync: (p) => existsSync77(p)
|
|
19156
19129
|
};
|
|
19157
19130
|
}
|
|
19158
19131
|
function walkProjectRoot(rootPath, opts = {}) {
|
|
@@ -21774,7 +21747,6 @@ import { stringify as yamlStringify2 } from "yaml";
|
|
|
21774
21747
|
|
|
21775
21748
|
// src/lib/upgrade-kubernetes.ts
|
|
21776
21749
|
init_output();
|
|
21777
|
-
init_health_probes();
|
|
21778
21750
|
import * as fs32 from "node:fs";
|
|
21779
21751
|
import "node:os";
|
|
21780
21752
|
import * as path33 from "node:path";
|
|
@@ -22141,13 +22113,13 @@ function appendAuditEntry(entry, auditLogPath, writeFileSyncImpl) {
|
|
|
22141
22113
|
}
|
|
22142
22114
|
async function runManifestRefresh(manifestsDir, acceptRegression, deps = {}, peripheral) {
|
|
22143
22115
|
const auditLogPath = deps.auditLogPath ?? MANIFEST_REFRESH_AUDIT_LOG;
|
|
22144
|
-
const
|
|
22145
|
-
const
|
|
22116
|
+
const readdirSync28 = deps.readdirSync ?? fs31.readdirSync;
|
|
22117
|
+
const readFileSync80 = deps.readFileSync ?? fs31.readFileSync;
|
|
22146
22118
|
const writeFileSyncImpl = deps.writeFileSync ?? fs31.writeFileSync;
|
|
22147
|
-
const
|
|
22119
|
+
const existsSync103 = deps.existsSync ?? fs31.existsSync;
|
|
22148
22120
|
const now = deps.now ? deps.now() : /* @__PURE__ */ new Date();
|
|
22149
22121
|
const targetDir = peripheral ? path32.join(manifestsDir, peripheral) : manifestsDir;
|
|
22150
|
-
if (!
|
|
22122
|
+
if (!existsSync103(targetDir)) {
|
|
22151
22123
|
return {
|
|
22152
22124
|
ok: false,
|
|
22153
22125
|
message: peripheral ? `peripheral manifests directory not found: ${targetDir}` : `manifests directory not found: ${targetDir}`
|
|
@@ -22155,7 +22127,7 @@ async function runManifestRefresh(manifestsDir, acceptRegression, deps = {}, per
|
|
|
22155
22127
|
}
|
|
22156
22128
|
let files;
|
|
22157
22129
|
try {
|
|
22158
|
-
const entries =
|
|
22130
|
+
const entries = readdirSync28(targetDir, { withFileTypes: true });
|
|
22159
22131
|
files = entries.filter((e) => e.isFile() && (e.name.endsWith(".yaml") || e.name.endsWith(".json"))).map((e) => e.name);
|
|
22160
22132
|
} catch (err) {
|
|
22161
22133
|
return {
|
|
@@ -22168,7 +22140,7 @@ async function runManifestRefresh(manifestsDir, acceptRegression, deps = {}, per
|
|
|
22168
22140
|
const filePath = path32.join(targetDir, file);
|
|
22169
22141
|
let content;
|
|
22170
22142
|
try {
|
|
22171
|
-
content =
|
|
22143
|
+
content = readFileSync80(filePath, "utf8");
|
|
22172
22144
|
} catch {
|
|
22173
22145
|
continue;
|
|
22174
22146
|
}
|
|
@@ -22216,7 +22188,7 @@ init_install_root();
|
|
|
22216
22188
|
|
|
22217
22189
|
// src/lib/k8s-secret-render.ts
|
|
22218
22190
|
import { spawnSync as spawnSync14 } from "node:child_process";
|
|
22219
|
-
import { existsSync as existsSync32, readFileSync as readFileSync26, writeFileSync as writeFileSync17, mkdirSync as mkdirSync23, chmodSync as chmodSync4 } from "node:fs";
|
|
22191
|
+
import { existsSync as existsSync32, readFileSync as readFileSync26, writeFileSync as writeFileSync17, mkdirSync as mkdirSync23, chmodSync as chmodSync4, renameSync as renameSync7 } from "node:fs";
|
|
22220
22192
|
import { join as join38, dirname as dirname24 } from "node:path";
|
|
22221
22193
|
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
22222
22194
|
var K8S_SECRETS_STATE_PATH = join38(OLAM_HOME, "k8s-secrets-state.json");
|
|
@@ -22314,7 +22286,7 @@ function writeSecretsState(state, statePath = K8S_SECRETS_STATE_PATH) {
|
|
|
22314
22286
|
const tmp = `${statePath}.tmp.${process.pid}`;
|
|
22315
22287
|
writeFileSync17(tmp, JSON.stringify(state, null, 2) + "\n", { encoding: "utf8", mode: 384 });
|
|
22316
22288
|
chmodSync4(tmp, 384);
|
|
22317
|
-
|
|
22289
|
+
renameSync7(tmp, statePath);
|
|
22318
22290
|
}
|
|
22319
22291
|
function resolveSourceValue(source, olamHome5, reuseFromState, rotate, deps) {
|
|
22320
22292
|
if (!rotate && reuseFromState !== void 0 && reuseFromState !== "") {
|
|
@@ -22537,7 +22509,100 @@ ${a.stderr}
|
|
|
22537
22509
|
return { exitCode: 0, result: { applied, skipped, secretResults: results } };
|
|
22538
22510
|
}
|
|
22539
22511
|
|
|
22512
|
+
// src/lib/host-side-proxy.ts
|
|
22513
|
+
import { spawnSync as spawnSync16 } from "node:child_process";
|
|
22514
|
+
function probeDockerCompose(deps) {
|
|
22515
|
+
const spawn13 = deps.spawnSyncImpl ?? spawnSync16;
|
|
22516
|
+
const env = deps.dockerContext !== void 0 ? { ...process.env, DOCKER_CONTEXT: deps.dockerContext } : process.env;
|
|
22517
|
+
const r = spawn13("docker", ["compose", "version"], {
|
|
22518
|
+
env,
|
|
22519
|
+
encoding: "utf8",
|
|
22520
|
+
timeout: 5e3
|
|
22521
|
+
});
|
|
22522
|
+
if (r.error !== void 0 || r.status !== 0) {
|
|
22523
|
+
return {
|
|
22524
|
+
ok: false,
|
|
22525
|
+
reason: "docker compose plugin not found. Install via `brew install docker-compose` or the Docker Desktop installer. The legacy `docker-compose` binary is NOT a substitute \u2014 olam requires `docker compose` (v2 plugin) for the host-side docker-socket-proxy lifecycle on macOS."
|
|
22526
|
+
};
|
|
22527
|
+
}
|
|
22528
|
+
return { ok: true };
|
|
22529
|
+
}
|
|
22530
|
+
function startHostSideProxy(composePath, deps = {}) {
|
|
22531
|
+
const probe2 = probeDockerCompose(deps);
|
|
22532
|
+
if (!probe2.ok) {
|
|
22533
|
+
return probe2;
|
|
22534
|
+
}
|
|
22535
|
+
const spawn13 = deps.spawnSyncImpl ?? spawnSync16;
|
|
22536
|
+
const env = deps.dockerContext !== void 0 ? { ...process.env, DOCKER_CONTEXT: deps.dockerContext } : process.env;
|
|
22537
|
+
const r = spawn13("docker", ["compose", "-f", composePath, "up", "-d"], {
|
|
22538
|
+
env,
|
|
22539
|
+
encoding: "utf8",
|
|
22540
|
+
timeout: 6e4
|
|
22541
|
+
});
|
|
22542
|
+
if (r.error !== void 0) {
|
|
22543
|
+
return { ok: false, reason: `docker compose up failed: ${r.error.message}` };
|
|
22544
|
+
}
|
|
22545
|
+
if (r.status !== 0) {
|
|
22546
|
+
const stderr = (r.stderr ?? "").toString().trim();
|
|
22547
|
+
return {
|
|
22548
|
+
ok: false,
|
|
22549
|
+
reason: `docker compose -f ${composePath} up -d exited ${r.status ?? "null"}: ${stderr || "(no stderr)"}. Check: \`docker context ls\` shows colima active; \`docker info\` succeeds; the compose file exists at the printed path.`
|
|
22550
|
+
};
|
|
22551
|
+
}
|
|
22552
|
+
return { ok: true };
|
|
22553
|
+
}
|
|
22554
|
+
function statusHostSideProxy(composePath, deps = {}) {
|
|
22555
|
+
const probe2 = probeDockerCompose(deps);
|
|
22556
|
+
if (!probe2.ok) {
|
|
22557
|
+
return { ok: false, status: "unknown", reason: probe2.reason };
|
|
22558
|
+
}
|
|
22559
|
+
const spawn13 = deps.spawnSyncImpl ?? spawnSync16;
|
|
22560
|
+
const env = deps.dockerContext !== void 0 ? { ...process.env, DOCKER_CONTEXT: deps.dockerContext } : process.env;
|
|
22561
|
+
const r = spawn13("docker", ["compose", "-f", composePath, "ps", "--format", "json"], {
|
|
22562
|
+
env,
|
|
22563
|
+
encoding: "utf8",
|
|
22564
|
+
timeout: 1e4
|
|
22565
|
+
});
|
|
22566
|
+
if (r.error !== void 0 || r.status !== 0) {
|
|
22567
|
+
return {
|
|
22568
|
+
ok: false,
|
|
22569
|
+
status: "unknown",
|
|
22570
|
+
reason: `docker compose ps failed: ${(r.stderr ?? r.error?.message ?? "(no detail)").toString().trim()}`
|
|
22571
|
+
};
|
|
22572
|
+
}
|
|
22573
|
+
const stdout = (r.stdout ?? "").toString().trim();
|
|
22574
|
+
if (stdout === "" || stdout === "[]") {
|
|
22575
|
+
return { ok: true, status: "stopped" };
|
|
22576
|
+
}
|
|
22577
|
+
try {
|
|
22578
|
+
const parsed = stdout.startsWith("[") ? JSON.parse(stdout) : stdout.split("\n").filter((line) => line.trim() !== "").map((line) => JSON.parse(line));
|
|
22579
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
22580
|
+
return { ok: true, status: "stopped" };
|
|
22581
|
+
}
|
|
22582
|
+
const allRunning = parsed.every((entry) => {
|
|
22583
|
+
if (typeof entry !== "object" || entry === null) {
|
|
22584
|
+
return false;
|
|
22585
|
+
}
|
|
22586
|
+
const state = entry.State;
|
|
22587
|
+
return typeof state === "string" && state.toLowerCase() === "running";
|
|
22588
|
+
});
|
|
22589
|
+
return { ok: true, status: allRunning ? "running" : "stopped" };
|
|
22590
|
+
} catch {
|
|
22591
|
+
return {
|
|
22592
|
+
ok: false,
|
|
22593
|
+
status: "unknown",
|
|
22594
|
+
reason: "docker compose ps emitted unparseable JSON; check `docker compose version`."
|
|
22595
|
+
};
|
|
22596
|
+
}
|
|
22597
|
+
}
|
|
22598
|
+
|
|
22540
22599
|
// src/lib/upgrade-kubernetes.ts
|
|
22600
|
+
function resolveHostSideProxyComposePath() {
|
|
22601
|
+
const root = resolveK8sAssetsRoot();
|
|
22602
|
+
if (root === null) return null;
|
|
22603
|
+
const candidate = path33.join(root, "host-side", "docker-socket-proxy.compose.yaml");
|
|
22604
|
+
return fs32.existsSync(candidate) ? candidate : null;
|
|
22605
|
+
}
|
|
22541
22606
|
var OLAM_K8S_MANIFESTS_DIR = path33.join(OLAM_HOME, "k8s", "manifests");
|
|
22542
22607
|
var K8S_NAMESPACE3 = "olam";
|
|
22543
22608
|
var HOST_CP_SECRET_NAME = "olam-host-cp-secret";
|
|
@@ -22603,28 +22668,6 @@ async function detectManagedK8sProvider(deps) {
|
|
|
22603
22668
|
}
|
|
22604
22669
|
return null;
|
|
22605
22670
|
}
|
|
22606
|
-
async function checkDockerSocketAccessible(context, deps) {
|
|
22607
|
-
if (deps.checkDockerSocketImpl) {
|
|
22608
|
-
return deps.checkDockerSocketImpl(context);
|
|
22609
|
-
}
|
|
22610
|
-
const wrap = deps.kubectlWrapImpl ?? kubectlWrap;
|
|
22611
|
-
const result = await wrap(
|
|
22612
|
-
[
|
|
22613
|
-
"--context",
|
|
22614
|
-
context,
|
|
22615
|
-
"exec",
|
|
22616
|
-
"deploy/olam-host-cp",
|
|
22617
|
-
"-n",
|
|
22618
|
-
"olam",
|
|
22619
|
-
"--",
|
|
22620
|
-
"test",
|
|
22621
|
-
"-S",
|
|
22622
|
-
"/var/run/docker.sock"
|
|
22623
|
-
],
|
|
22624
|
-
{ timeout: 1e4 }
|
|
22625
|
-
);
|
|
22626
|
-
return result.ok;
|
|
22627
|
-
}
|
|
22628
22671
|
async function probeKubernetesApiReachable(context, deps) {
|
|
22629
22672
|
const wrap = deps.kubectlWrapImpl ?? kubectlWrap;
|
|
22630
22673
|
const result = await wrap(
|
|
@@ -22678,11 +22721,11 @@ async function checkSecretPreCondition(context, deps) {
|
|
|
22678
22721
|
}
|
|
22679
22722
|
async function applyConfigMapSubstitution(context, manifestsDir, deps) {
|
|
22680
22723
|
const wrap = deps.kubectlWrapImpl ?? kubectlWrap;
|
|
22681
|
-
const
|
|
22724
|
+
const readFileSync80 = deps.readFileSyncImpl ?? fs32.readFileSync;
|
|
22682
22725
|
const configMapPath = path33.join(manifestsDir, "30-configmap.yaml");
|
|
22683
22726
|
let rawYaml;
|
|
22684
22727
|
try {
|
|
22685
|
-
rawYaml =
|
|
22728
|
+
rawYaml = readFileSync80(configMapPath, "utf8");
|
|
22686
22729
|
} catch (err) {
|
|
22687
22730
|
return `Failed to read ConfigMap at ${configMapPath}: ${err instanceof Error ? err.message : String(err)}`;
|
|
22688
22731
|
}
|
|
@@ -22824,48 +22867,6 @@ async function createGhcrPullSecret(context, deps, stderr) {
|
|
|
22824
22867
|
}
|
|
22825
22868
|
return { skipped: false };
|
|
22826
22869
|
}
|
|
22827
|
-
var K3D_NODE_CONTAINER = "k3d-olam-host-server-0";
|
|
22828
|
-
async function defaultCheckK3dNodeMounts() {
|
|
22829
|
-
const { execFile } = await import("node:child_process");
|
|
22830
|
-
const { promisify } = await import("node:util");
|
|
22831
|
-
const execFileAsync = promisify(execFile);
|
|
22832
|
-
try {
|
|
22833
|
-
const { stdout } = await execFileAsync(
|
|
22834
|
-
"docker",
|
|
22835
|
-
["inspect", K3D_NODE_CONTAINER, "--format", "{{json .HostConfig.Binds}}"],
|
|
22836
|
-
{ timeout: 8e3 }
|
|
22837
|
-
);
|
|
22838
|
-
const binds = JSON.parse(stdout.trim());
|
|
22839
|
-
if (!Array.isArray(binds)) return "none";
|
|
22840
|
-
if (binds.some((b) => b.includes("/host-colima/"))) return "new-form";
|
|
22841
|
-
if (binds.some((b) => b.startsWith("/var/run/docker.sock:"))) return "old-form";
|
|
22842
|
-
return "none";
|
|
22843
|
-
} catch {
|
|
22844
|
-
return "none";
|
|
22845
|
-
}
|
|
22846
|
-
}
|
|
22847
|
-
async function preflightK3dNodeMounts(deps, stderr) {
|
|
22848
|
-
const check = deps.checkK3dNodeMountsImpl ?? defaultCheckK3dNodeMounts;
|
|
22849
|
-
const form = await check();
|
|
22850
|
-
if (form === "new-form") {
|
|
22851
|
-
return null;
|
|
22852
|
-
}
|
|
22853
|
-
if (form === "old-form") {
|
|
22854
|
-
return `Your k3d cluster was created with the old --volume form which fails on colima.
|
|
22855
|
-
Recreate the cluster with:
|
|
22856
|
-
k3d cluster delete olam-host
|
|
22857
|
-
k3d cluster create olam-host --volume "$HOME/.colima/default/:/host-colima/@server:*"
|
|
22858
|
-
Then re-run olam upgrade.`;
|
|
22859
|
-
}
|
|
22860
|
-
stderr.write(
|
|
22861
|
-
`${pc9.yellow("[warn]")} step 0.5: k3d node container "${K3D_NODE_CONTAINER}" not found or bind form undetectable.
|
|
22862
|
-
This is expected on non-k3d clusters (bare k3s, minikube). Continuing.
|
|
22863
|
-
On colima+k3d: ensure the cluster was created with:
|
|
22864
|
-
k3d cluster create olam-host --volume "$HOME/.colima/default/:/host-colima/@server:*"
|
|
22865
|
-
`
|
|
22866
|
-
);
|
|
22867
|
-
return null;
|
|
22868
|
-
}
|
|
22869
22870
|
async function runUpgradeKubernetes(opts = {}, deps = {}) {
|
|
22870
22871
|
const stdout = deps.stdout ?? process.stdout;
|
|
22871
22872
|
const stderr = deps.stderr ?? process.stderr;
|
|
@@ -22883,32 +22884,6 @@ async function runUpgradeKubernetes(opts = {}, deps = {}) {
|
|
|
22883
22884
|
return { exitCode: 1, summary: "manifest seed failed" };
|
|
22884
22885
|
}
|
|
22885
22886
|
}
|
|
22886
|
-
{
|
|
22887
|
-
const preliminaryResolved = resolveKubectlContext(deps.configPath);
|
|
22888
|
-
if (preliminaryResolved.error === void 0) {
|
|
22889
|
-
const preliminaryContext = preliminaryResolved.context;
|
|
22890
|
-
const step04Spinner = ora3("Creating ghcr-pull imagePullSecret (R3-C)").start();
|
|
22891
|
-
const pullSecretResult = await createGhcrPullSecret(preliminaryContext, deps, stderr);
|
|
22892
|
-
if (pullSecretResult.skipped) {
|
|
22893
|
-
step04Spinner.warn(`ghcr-pull Secret skipped: ${pullSecretResult.reason ?? "no token"}`);
|
|
22894
|
-
} else if (pullSecretResult.reason) {
|
|
22895
|
-
const warnMsg = `ghcr-pull Secret apply failed (continuing): ${pullSecretResult.reason}`;
|
|
22896
|
-
step04Spinner.warn(warnMsg);
|
|
22897
|
-
stderr.write(`${pc9.yellow("[warn]")} ${warnMsg}
|
|
22898
|
-
`);
|
|
22899
|
-
} else {
|
|
22900
|
-
step04Spinner.succeed("ghcr-pull imagePullSecret created/updated");
|
|
22901
|
-
}
|
|
22902
|
-
}
|
|
22903
|
-
}
|
|
22904
|
-
{
|
|
22905
|
-
const step05Error = await preflightK3dNodeMounts(deps, stderr);
|
|
22906
|
-
if (step05Error !== null) {
|
|
22907
|
-
stderr.write(`${pc9.red("error:")} ${step05Error}
|
|
22908
|
-
`);
|
|
22909
|
-
return { exitCode: 1, summary: "k3d node bind-mount preflight failed (Decision #11)" };
|
|
22910
|
-
}
|
|
22911
|
-
}
|
|
22912
22887
|
const resolved = resolveKubectlContext(deps.configPath);
|
|
22913
22888
|
if (resolved.error !== void 0) {
|
|
22914
22889
|
stderr.write(`${pc9.red("error:")} ${resolved.error}
|
|
@@ -22935,22 +22910,6 @@ async function runUpgradeKubernetes(opts = {}, deps = {}) {
|
|
|
22935
22910
|
return { exitCode: 1, summary: "managed-k8s context detected (Decision #18 retraction)" };
|
|
22936
22911
|
}
|
|
22937
22912
|
}
|
|
22938
|
-
{
|
|
22939
|
-
const socketAccessible = await checkDockerSocketAccessible(pinnedContext, deps);
|
|
22940
|
-
if (!socketAccessible) {
|
|
22941
|
-
const clusterType = defaultDetectK8sClusterType(pinnedContext);
|
|
22942
|
-
const remedyText = buildDockerSocketRemedy(clusterType).split("\n").map((line) => ` ${line}`).join("\n");
|
|
22943
|
-
stderr.write(
|
|
22944
|
-
`${pc9.yellow("[WARN]")} docker socket not accessible at /var/run/docker.sock inside the host-cp pod.
|
|
22945
|
-
This means the cluster was not created with the docker socket bind-mount,
|
|
22946
|
-
or host-cp is not yet deployed (first install \u2014 this warning is expected).
|
|
22947
|
-
For subsequent upgrades:
|
|
22948
|
-
${remedyText}
|
|
22949
|
-
Run olam doctor to check probe 28 (probeDockerSocketBindMount).
|
|
22950
|
-
`
|
|
22951
|
-
);
|
|
22952
|
-
}
|
|
22953
|
-
}
|
|
22954
22913
|
const step0Spinner = ora3("Probing Kubernetes API reachability").start();
|
|
22955
22914
|
const reachable = await probeKubernetesApiReachable(pinnedContext, deps);
|
|
22956
22915
|
if (!reachable) {
|
|
@@ -22989,6 +22948,41 @@ ${remedyText}
|
|
|
22989
22948
|
const note = skippedCount > 0 ? ` (${skippedCount} skipped \u2014 see warnings above)` : "";
|
|
22990
22949
|
step05Spinner.succeed(`k8s bootstrap: ${appliedCount} applied${note}`);
|
|
22991
22950
|
}
|
|
22951
|
+
{
|
|
22952
|
+
const step06Spinner = ora3("Creating ghcr-pull imagePullSecret (R3-C)").start();
|
|
22953
|
+
const pullSecretResult = await createGhcrPullSecret(pinnedContext, deps, stderr);
|
|
22954
|
+
if (pullSecretResult.skipped) {
|
|
22955
|
+
step06Spinner.warn(`ghcr-pull Secret skipped: ${pullSecretResult.reason ?? "no token"}`);
|
|
22956
|
+
} else if (pullSecretResult.reason) {
|
|
22957
|
+
const warnMsg = `ghcr-pull Secret apply failed (continuing): ${pullSecretResult.reason}`;
|
|
22958
|
+
step06Spinner.warn(warnMsg);
|
|
22959
|
+
stderr.write(`${pc9.yellow("[warn]")} ${warnMsg}
|
|
22960
|
+
`);
|
|
22961
|
+
} else {
|
|
22962
|
+
step06Spinner.succeed("ghcr-pull imagePullSecret created/updated");
|
|
22963
|
+
}
|
|
22964
|
+
}
|
|
22965
|
+
if (process.platform === "darwin") {
|
|
22966
|
+
const step07Spinner = ora3("Starting host-side docker-socket-proxy (R4-W2-F)").start();
|
|
22967
|
+
const composePath = resolveHostSideProxyComposePath();
|
|
22968
|
+
if (composePath === null) {
|
|
22969
|
+
step07Spinner.warn("host-side docker-socket-proxy compose yaml not found (bundle layout?)");
|
|
22970
|
+
stderr.write(
|
|
22971
|
+
`${pc9.yellow("[warn]")} could not locate docker-socket-proxy.compose.yaml in the bundled k8s assets.
|
|
22972
|
+
This is a packaging bug \u2014 please report. Continuing without auto-start.
|
|
22973
|
+
`
|
|
22974
|
+
);
|
|
22975
|
+
} else {
|
|
22976
|
+
const startResult = startHostSideProxy(composePath);
|
|
22977
|
+
if (!startResult.ok) {
|
|
22978
|
+
step07Spinner.warn(`host-side docker-socket-proxy start failed (continuing): ${startResult.reason ?? "unknown"}`);
|
|
22979
|
+
stderr.write(`${pc9.yellow("[warn]")} ${startResult.reason ?? "unknown error"}
|
|
22980
|
+
`);
|
|
22981
|
+
} else {
|
|
22982
|
+
step07Spinner.succeed("docker-socket-proxy ready on host");
|
|
22983
|
+
}
|
|
22984
|
+
}
|
|
22985
|
+
}
|
|
22992
22986
|
const step1Spinner = ora3("Verifying kubectl context (D10)").start();
|
|
22993
22987
|
if (!isContextAllowed(pinnedContext)) {
|
|
22994
22988
|
step1Spinner.fail("Context disallowed");
|
|
@@ -23474,7 +23468,7 @@ ${pc11.dim("Next: olam create --name my-world")}`);
|
|
|
23474
23468
|
|
|
23475
23469
|
// src/commands/create.ts
|
|
23476
23470
|
init_manager();
|
|
23477
|
-
import { spawnSync as
|
|
23471
|
+
import { spawnSync as spawnSync19 } from "node:child_process";
|
|
23478
23472
|
import { existsSync as existsSync38 } from "node:fs";
|
|
23479
23473
|
import { dirname as dirname27, resolve as resolve14 } from "node:path";
|
|
23480
23474
|
import ora5 from "ora";
|
|
@@ -23712,9 +23706,9 @@ init_output();
|
|
|
23712
23706
|
init_host_cp();
|
|
23713
23707
|
|
|
23714
23708
|
// src/lib/world-mcp-register.ts
|
|
23715
|
-
import { spawnSync as
|
|
23709
|
+
import { spawnSync as spawnSync17 } from "node:child_process";
|
|
23716
23710
|
var DEFAULT_DOCKER_EXEC_DEPS = {
|
|
23717
|
-
spawn:
|
|
23711
|
+
spawn: spawnSync17,
|
|
23718
23712
|
log: (msg) => console.log(msg)
|
|
23719
23713
|
};
|
|
23720
23714
|
var MCP_NAME = "agentmemory";
|
|
@@ -23779,7 +23773,7 @@ function registerAgentMemoryMcp(opts, deps = DEFAULT_DOCKER_EXEC_DEPS) {
|
|
|
23779
23773
|
init_install_root();
|
|
23780
23774
|
import * as fs34 from "node:fs";
|
|
23781
23775
|
import * as path35 from "node:path";
|
|
23782
|
-
import { spawnSync as
|
|
23776
|
+
import { spawnSync as spawnSync18 } from "node:child_process";
|
|
23783
23777
|
import ora4 from "ora";
|
|
23784
23778
|
|
|
23785
23779
|
// src/lib/bundle-source.ts
|
|
@@ -23902,7 +23896,7 @@ function buildIfStale(repoRoot, env = process.env) {
|
|
|
23902
23896
|
}
|
|
23903
23897
|
const reason = distMtime === 0 ? "dist is absent" : `source newer by ${Math.round((srcMtime - distMtime) / 1e3)}s`;
|
|
23904
23898
|
const spinner = ora4(`Rebuilding agent-stream bundle\u2026 (${reason})`).start();
|
|
23905
|
-
const result =
|
|
23899
|
+
const result = spawnSync18(
|
|
23906
23900
|
"npm",
|
|
23907
23901
|
["run", "build", "--workspace=@olam/intelligence"],
|
|
23908
23902
|
{
|
|
@@ -23966,7 +23960,7 @@ function registerCreate(program2) {
|
|
|
23966
23960
|
if (decision.stderrLine) {
|
|
23967
23961
|
process.stderr.write(decision.stderrLine + "\n");
|
|
23968
23962
|
}
|
|
23969
|
-
|
|
23963
|
+
spawnSync19("docker", ["pull", overrideRef], { stdio: "pipe" });
|
|
23970
23964
|
const { inspectImageProtocolVersions: inspectImageProtocolVersions2, checkProtocolOverlap: checkProtocolOverlap2 } = await Promise.resolve().then(() => (init_protocol_version(), protocol_version_exports));
|
|
23971
23965
|
const inspect = inspectImageProtocolVersions2(overrideRef);
|
|
23972
23966
|
if (inspect.inspectFailed) {
|
|
@@ -24083,7 +24077,7 @@ function registerCreate(program2) {
|
|
|
24083
24077
|
throw err;
|
|
24084
24078
|
}
|
|
24085
24079
|
const spinner2 = ora5("Rebuilding olam-devbox:latest\u2026").start();
|
|
24086
|
-
const rebuild =
|
|
24080
|
+
const rebuild = spawnSync19(
|
|
24087
24081
|
"bash",
|
|
24088
24082
|
[buildScript],
|
|
24089
24083
|
{ cwd: repoRoot, stdio: "inherit" }
|
|
@@ -30341,7 +30335,7 @@ init_output();
|
|
|
30341
30335
|
init_host_cp();
|
|
30342
30336
|
import * as fs42 from "node:fs";
|
|
30343
30337
|
import * as path44 from "node:path";
|
|
30344
|
-
import { spawnSync as
|
|
30338
|
+
import { spawnSync as spawnSync21 } from "node:child_process";
|
|
30345
30339
|
import ora9 from "ora";
|
|
30346
30340
|
import pc20 from "picocolors";
|
|
30347
30341
|
|
|
@@ -30349,7 +30343,7 @@ import pc20 from "picocolors";
|
|
|
30349
30343
|
import * as fs40 from "node:fs";
|
|
30350
30344
|
import * as os21 from "node:os";
|
|
30351
30345
|
import * as path42 from "node:path";
|
|
30352
|
-
import { spawnSync as
|
|
30346
|
+
import { spawnSync as spawnSync20 } from "node:child_process";
|
|
30353
30347
|
var LOCK_FILE_PATH = path42.join(os21.homedir(), ".olam", ".upgrade.lock");
|
|
30354
30348
|
var STALE_LOCK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
30355
30349
|
function readLockFile(lockPath) {
|
|
@@ -30374,7 +30368,7 @@ function isPidAlive2(pid) {
|
|
|
30374
30368
|
}
|
|
30375
30369
|
var PS_UNAVAILABLE = "__ps_unavailable__";
|
|
30376
30370
|
function getPidCommand(pid) {
|
|
30377
|
-
const result =
|
|
30371
|
+
const result = spawnSync20("ps", ["-p", String(pid), "-o", "comm="], {
|
|
30378
30372
|
encoding: "utf-8",
|
|
30379
30373
|
stdio: ["ignore", "pipe", "ignore"]
|
|
30380
30374
|
});
|
|
@@ -30635,7 +30629,7 @@ function extractBundleHash(indexHtml) {
|
|
|
30635
30629
|
function runStep2(label, cmd, args, opts = {}) {
|
|
30636
30630
|
const start = Date.now();
|
|
30637
30631
|
process.stdout.write(` ${pc20.dim(label.padEnd(34))}`);
|
|
30638
|
-
const result =
|
|
30632
|
+
const result = spawnSync21(cmd, [...args], {
|
|
30639
30633
|
encoding: "utf-8",
|
|
30640
30634
|
stdio: ["ignore", "pipe", "pipe"],
|
|
30641
30635
|
cwd: opts.cwd ?? process.cwd(),
|
|
@@ -30654,7 +30648,7 @@ function runStep2(label, cmd, args, opts = {}) {
|
|
|
30654
30648
|
};
|
|
30655
30649
|
}
|
|
30656
30650
|
function isGitDirty(cwd) {
|
|
30657
|
-
const result =
|
|
30651
|
+
const result = spawnSync21("git", ["status", "--porcelain"], {
|
|
30658
30652
|
encoding: "utf-8",
|
|
30659
30653
|
stdio: ["ignore", "pipe", "pipe"],
|
|
30660
30654
|
cwd
|
|
@@ -30662,7 +30656,7 @@ function isGitDirty(cwd) {
|
|
|
30662
30656
|
return (result.stdout ?? "").trim().length > 0;
|
|
30663
30657
|
}
|
|
30664
30658
|
function hasGitUpstream(cwd) {
|
|
30665
|
-
const result =
|
|
30659
|
+
const result = spawnSync21("git", ["rev-parse", "--abbrev-ref", "@{u}"], {
|
|
30666
30660
|
encoding: "utf-8",
|
|
30667
30661
|
stdio: ["ignore", "pipe", "pipe"],
|
|
30668
30662
|
cwd
|
|
@@ -30670,7 +30664,7 @@ function hasGitUpstream(cwd) {
|
|
|
30670
30664
|
return result.status === 0;
|
|
30671
30665
|
}
|
|
30672
30666
|
function captureHeadSha(cwd) {
|
|
30673
|
-
const result =
|
|
30667
|
+
const result = spawnSync21("git", ["rev-parse", "HEAD"], {
|
|
30674
30668
|
encoding: "utf-8",
|
|
30675
30669
|
stdio: ["ignore", "pipe", "pipe"],
|
|
30676
30670
|
cwd
|
|
@@ -30685,7 +30679,7 @@ function abbreviateSha(sha) {
|
|
|
30685
30679
|
}
|
|
30686
30680
|
function imageExists(tag) {
|
|
30687
30681
|
try {
|
|
30688
|
-
const result =
|
|
30682
|
+
const result = spawnSync21("docker", ["image", "inspect", "--format", "{{.Id}}", tag], {
|
|
30689
30683
|
encoding: "utf-8",
|
|
30690
30684
|
stdio: ["ignore", "pipe", "ignore"]
|
|
30691
30685
|
});
|
|
@@ -30701,7 +30695,7 @@ function checkRollbackSetExists(plan) {
|
|
|
30701
30695
|
}
|
|
30702
30696
|
var SMOKE_DOCKER_TIMEOUT_MS = 3e4;
|
|
30703
30697
|
function smokeImage(image, targetSha) {
|
|
30704
|
-
const createResult =
|
|
30698
|
+
const createResult = spawnSync21("docker", ["create", "--name", `olam-smoke-${Date.now()}`, image], {
|
|
30705
30699
|
encoding: "utf-8",
|
|
30706
30700
|
stdio: ["ignore", "pipe", "pipe"],
|
|
30707
30701
|
timeout: SMOKE_DOCKER_TIMEOUT_MS
|
|
@@ -30715,7 +30709,7 @@ function smokeImage(image, targetSha) {
|
|
|
30715
30709
|
};
|
|
30716
30710
|
}
|
|
30717
30711
|
const containerId = (createResult.stdout ?? "").trim();
|
|
30718
|
-
const inspectResult =
|
|
30712
|
+
const inspectResult = spawnSync21(
|
|
30719
30713
|
"docker",
|
|
30720
30714
|
["inspect", "--format", '{{index .Config.Labels "olam.build.sha"}}', image],
|
|
30721
30715
|
{
|
|
@@ -30725,7 +30719,7 @@ function smokeImage(image, targetSha) {
|
|
|
30725
30719
|
}
|
|
30726
30720
|
);
|
|
30727
30721
|
if (containerId.length > 0) {
|
|
30728
|
-
|
|
30722
|
+
spawnSync21("docker", ["rm", "-f", containerId], {
|
|
30729
30723
|
encoding: "utf-8",
|
|
30730
30724
|
stdio: ["ignore", "ignore", "ignore"],
|
|
30731
30725
|
timeout: SMOKE_DOCKER_TIMEOUT_MS
|
|
@@ -30767,7 +30761,7 @@ var PRODUCTION_SWAP_PLAN = [
|
|
|
30767
30761
|
];
|
|
30768
30762
|
function dockerTag(source, dest) {
|
|
30769
30763
|
try {
|
|
30770
|
-
const result =
|
|
30764
|
+
const result = spawnSync21("docker", ["tag", source, dest], {
|
|
30771
30765
|
encoding: "utf-8",
|
|
30772
30766
|
stdio: ["ignore", "ignore", "pipe"]
|
|
30773
30767
|
});
|
|
@@ -30931,11 +30925,11 @@ async function waitForAuthHealthLocal(timeoutMs = AUTH_HEALTH_TIMEOUT_MS) {
|
|
|
30931
30925
|
async function recreateAuthService() {
|
|
30932
30926
|
const start = Date.now();
|
|
30933
30927
|
try {
|
|
30934
|
-
|
|
30928
|
+
spawnSync21("docker", ["stop", "olam-auth"], {
|
|
30935
30929
|
encoding: "utf-8",
|
|
30936
30930
|
stdio: ["ignore", "ignore", "ignore"]
|
|
30937
30931
|
});
|
|
30938
|
-
|
|
30932
|
+
spawnSync21("docker", ["rm", "olam-auth"], {
|
|
30939
30933
|
encoding: "utf-8",
|
|
30940
30934
|
stdio: ["ignore", "ignore", "ignore"]
|
|
30941
30935
|
});
|
|
@@ -31233,11 +31227,11 @@ async function defaultRecreateMcpAuthForUpgrade() {
|
|
|
31233
31227
|
}
|
|
31234
31228
|
async function defaultRecreateAuthForUpgrade() {
|
|
31235
31229
|
try {
|
|
31236
|
-
|
|
31230
|
+
spawnSync21("docker", ["stop", "olam-auth"], {
|
|
31237
31231
|
encoding: "utf-8",
|
|
31238
31232
|
stdio: ["ignore", "ignore", "ignore"]
|
|
31239
31233
|
});
|
|
31240
|
-
|
|
31234
|
+
spawnSync21("docker", ["rm", "olam-auth"], {
|
|
31241
31235
|
encoding: "utf-8",
|
|
31242
31236
|
stdio: ["ignore", "ignore", "ignore"]
|
|
31243
31237
|
});
|
|
@@ -31259,7 +31253,7 @@ async function defaultRecreateAuthForUpgrade() {
|
|
|
31259
31253
|
}
|
|
31260
31254
|
}
|
|
31261
31255
|
function defaultInspectContainerLabels(containerName) {
|
|
31262
|
-
const result =
|
|
31256
|
+
const result = spawnSync21(
|
|
31263
31257
|
"docker",
|
|
31264
31258
|
[
|
|
31265
31259
|
"inspect",
|
|
@@ -31283,7 +31277,7 @@ function defaultInspectContainerLabels(containerName) {
|
|
|
31283
31277
|
return { ok: false, exists: false, project: "", service: "", stderr };
|
|
31284
31278
|
}
|
|
31285
31279
|
function defaultRemoveContainer(containerName) {
|
|
31286
|
-
const result =
|
|
31280
|
+
const result = spawnSync21("docker", ["rm", "-f", containerName], {
|
|
31287
31281
|
encoding: "utf-8",
|
|
31288
31282
|
stdio: ["ignore", "pipe", "pipe"]
|
|
31289
31283
|
});
|
|
@@ -31614,7 +31608,7 @@ ${spaResult.stderr}`);
|
|
|
31614
31608
|
process.stdout.write(` ${pc20.dim(step.label.padEnd(34))}
|
|
31615
31609
|
`);
|
|
31616
31610
|
const start = Date.now();
|
|
31617
|
-
const result =
|
|
31611
|
+
const result = spawnSync21("bash", [scriptPath], {
|
|
31618
31612
|
stdio: "inherit",
|
|
31619
31613
|
cwd,
|
|
31620
31614
|
env: { ...process.env, ...olamTagEnv }
|
|
@@ -31970,7 +31964,7 @@ function registerLogs(program2) {
|
|
|
31970
31964
|
init_context();
|
|
31971
31965
|
init_output();
|
|
31972
31966
|
import pc22 from "picocolors";
|
|
31973
|
-
import { spawnSync as
|
|
31967
|
+
import { spawnSync as spawnSync22 } from "node:child_process";
|
|
31974
31968
|
var SAFE_IDENT4 = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
31975
31969
|
function parseDockerTop(stdout) {
|
|
31976
31970
|
const trimmed = stdout.trim();
|
|
@@ -32070,7 +32064,7 @@ function registerPs(program2) {
|
|
|
32070
32064
|
const containerName = `olam-${worldId}-devbox`;
|
|
32071
32065
|
let watchInterval;
|
|
32072
32066
|
function fetchAndPrint() {
|
|
32073
|
-
const result =
|
|
32067
|
+
const result = spawnSync22(
|
|
32074
32068
|
"docker",
|
|
32075
32069
|
["top", containerName, "pid", "user", "pcpu", "pmem", "stime", "stat", "cmd"],
|
|
32076
32070
|
{ encoding: "utf-8", timeout: 3e3 }
|
|
@@ -32563,7 +32557,7 @@ init_output();
|
|
|
32563
32557
|
import * as fs46 from "node:fs";
|
|
32564
32558
|
import * as os24 from "node:os";
|
|
32565
32559
|
import * as path48 from "node:path";
|
|
32566
|
-
import { spawnSync as
|
|
32560
|
+
import { spawnSync as spawnSync23 } from "node:child_process";
|
|
32567
32561
|
import ora10 from "ora";
|
|
32568
32562
|
|
|
32569
32563
|
// src/commands/refresh-helpers.ts
|
|
@@ -32607,7 +32601,7 @@ var RESTART_TIMEOUT_S = 30;
|
|
|
32607
32601
|
var HEALTH_POLL_MS = 500;
|
|
32608
32602
|
var HEALTH_TIMEOUT_MS2 = 3e4;
|
|
32609
32603
|
function docker(args) {
|
|
32610
|
-
const result =
|
|
32604
|
+
const result = spawnSync23("docker", args, {
|
|
32611
32605
|
encoding: "utf-8",
|
|
32612
32606
|
stdio: ["ignore", "pipe", "pipe"]
|
|
32613
32607
|
});
|
|
@@ -32794,10 +32788,10 @@ init_context();
|
|
|
32794
32788
|
init_output();
|
|
32795
32789
|
import { existsSync as existsSync53 } from "node:fs";
|
|
32796
32790
|
import { dirname as dirname32, resolve as resolve15 } from "node:path";
|
|
32797
|
-
import { spawnSync as
|
|
32791
|
+
import { spawnSync as spawnSync24 } from "node:child_process";
|
|
32798
32792
|
var RESTART_TIMEOUT_S2 = 30;
|
|
32799
32793
|
function docker2(args) {
|
|
32800
|
-
const result =
|
|
32794
|
+
const result = spawnSync24("docker", args, {
|
|
32801
32795
|
encoding: "utf-8",
|
|
32802
32796
|
stdio: ["ignore", "pipe", "pipe"]
|
|
32803
32797
|
});
|
|
@@ -33318,9 +33312,9 @@ async function runDoctor(opts, deps = {}) {
|
|
|
33318
33312
|
const nodeMemResult = probeNodeMemory(dockerExec, k8sCtx);
|
|
33319
33313
|
rows.push({ name: "node memory", result: nodeMemResult, position: 27 });
|
|
33320
33314
|
const socketCheckImpl = deps.dockerSocketCheckImpl;
|
|
33321
|
-
const
|
|
33322
|
-
const socketResult = await
|
|
33323
|
-
rows.push({ name: "
|
|
33315
|
+
const composePath = deps.hostSideProxyComposePathOverride !== void 0 ? deps.hostSideProxyComposePathOverride : defaultResolveHostSideProxyComposePath();
|
|
33316
|
+
const socketResult = await probeHostSideProxyReachability(composePath, socketCheckImpl);
|
|
33317
|
+
rows.push({ name: "host-side proxy", result: socketResult, position: 28 });
|
|
33324
33318
|
} else {
|
|
33325
33319
|
const bundleResult = await probeBundleFreshness({
|
|
33326
33320
|
dockerExec,
|
|
@@ -33540,36 +33534,50 @@ function probeNodeMemory(dockerExec, kubectlContext) {
|
|
|
33540
33534
|
message: `node free RAM ${freeGiB.toFixed(1)} GiB (\u2265${WARN_THRESHOLD_GIB} GiB threshold)`
|
|
33541
33535
|
};
|
|
33542
33536
|
}
|
|
33543
|
-
|
|
33544
|
-
const
|
|
33545
|
-
|
|
33546
|
-
|
|
33547
|
-
|
|
33548
|
-
|
|
33549
|
-
|
|
33550
|
-
|
|
33551
|
-
|
|
33552
|
-
"--",
|
|
33553
|
-
"test",
|
|
33554
|
-
"-S",
|
|
33555
|
-
"/var/run/docker.sock"
|
|
33556
|
-
],
|
|
33557
|
-
{ timeout: 1e4 }
|
|
33558
|
-
);
|
|
33559
|
-
return result.ok;
|
|
33537
|
+
function defaultResolveHostSideProxyComposePath() {
|
|
33538
|
+
const root = resolveK8sAssetsRoot();
|
|
33539
|
+
if (root === null) return null;
|
|
33540
|
+
const candidate = path51.join(root, "host-side", "docker-socket-proxy.compose.yaml");
|
|
33541
|
+
return fs49.existsSync(candidate) ? candidate : null;
|
|
33542
|
+
}
|
|
33543
|
+
async function defaultDockerSocketCheck(composePath) {
|
|
33544
|
+
const result = statusHostSideProxy(composePath);
|
|
33545
|
+
return result.status;
|
|
33560
33546
|
}
|
|
33561
|
-
async function
|
|
33547
|
+
async function probeHostSideProxyReachability(composePath, checkImpl) {
|
|
33548
|
+
if (composePath === null) {
|
|
33549
|
+
return {
|
|
33550
|
+
ok: true,
|
|
33551
|
+
warn: true,
|
|
33552
|
+
message: "host-side proxy compose yaml not found in CLI bundle",
|
|
33553
|
+
remedy: "The bundled `docker-socket-proxy.compose.yaml` could not be resolved.\nThis is a packaging issue \u2014 try `npm install -g @pleri/olam-cli@latest`\nto restore the bundled k8s assets."
|
|
33554
|
+
};
|
|
33555
|
+
}
|
|
33562
33556
|
const check = checkImpl ?? defaultDockerSocketCheck;
|
|
33563
|
-
const
|
|
33564
|
-
if (
|
|
33565
|
-
return {
|
|
33557
|
+
const status2 = await check(composePath);
|
|
33558
|
+
if (status2 === "running") {
|
|
33559
|
+
return {
|
|
33560
|
+
ok: true,
|
|
33561
|
+
message: "host-side docker-socket-proxy running on operator docker daemon"
|
|
33562
|
+
};
|
|
33563
|
+
}
|
|
33564
|
+
if (status2 === "stopped") {
|
|
33565
|
+
return {
|
|
33566
|
+
ok: true,
|
|
33567
|
+
warn: true,
|
|
33568
|
+
message: "host-side docker-socket-proxy not running",
|
|
33569
|
+
remedy: `Start the proxy on the operator host:
|
|
33570
|
+
- macOS: re-run \`olam upgrade\` (Step 0.7 auto-starts the proxy)
|
|
33571
|
+
- Linux: \`docker compose -f ${composePath} up -d\`
|
|
33572
|
+
host-cp connects to docker through this proxy via the in-cluster
|
|
33573
|
+
ExternalName Service \`docker-socket-proxy.olam.svc.cluster.local:2375\`.`
|
|
33574
|
+
};
|
|
33566
33575
|
}
|
|
33567
|
-
const clusterType = (detectClusterTypeImpl ?? defaultDetectK8sClusterType)(kubectlContext);
|
|
33568
33576
|
return {
|
|
33569
33577
|
ok: true,
|
|
33570
33578
|
warn: true,
|
|
33571
|
-
message: "docker
|
|
33572
|
-
remedy:
|
|
33579
|
+
message: "host-side docker-socket-proxy status unknown",
|
|
33580
|
+
remedy: "Probe failed before reaching the docker daemon. Check:\n - `docker compose version` succeeds (compose v2 plugin installed)\n - `docker context ls` shows your active context (colima for macOS)\n - `docker info` succeeds against that context"
|
|
33573
33581
|
};
|
|
33574
33582
|
}
|
|
33575
33583
|
async function runK8sPreflight(opts, deps = {}) {
|
|
@@ -33981,6 +33989,345 @@ function registerSubstrate(program2) {
|
|
|
33981
33989
|
registerSubstrateAuditLog(sub);
|
|
33982
33990
|
}
|
|
33983
33991
|
|
|
33992
|
+
// ../cli-plugin-tasks/dist/client.js
|
|
33993
|
+
import { readFileSync as readFileSync45 } from "node:fs";
|
|
33994
|
+
import { homedir as homedir28 } from "node:os";
|
|
33995
|
+
import { join as join59 } from "node:path";
|
|
33996
|
+
var TasksClient = class {
|
|
33997
|
+
baseUrl;
|
|
33998
|
+
token;
|
|
33999
|
+
olamNodeId;
|
|
34000
|
+
sessionId;
|
|
34001
|
+
constructor(opts) {
|
|
34002
|
+
this.baseUrl = (opts.hostCpUrl ?? process.env.OLAM_HOST_CP_URL ?? "http://localhost:19000").replace(/\/$/, "");
|
|
34003
|
+
const tokenPath2 = opts.tokenPath ?? join59(homedir28(), ".olam", "host-cp.token");
|
|
34004
|
+
try {
|
|
34005
|
+
this.token = readFileSync45(tokenPath2, "utf8").trim();
|
|
34006
|
+
} catch (e) {
|
|
34007
|
+
throw new Error(`cli-plugin-tasks: cannot read host-cp token at ${tokenPath2} (${e instanceof Error ? e.message : "unknown"}). Bootstrap host-cp first.`);
|
|
34008
|
+
}
|
|
34009
|
+
this.olamNodeId = opts.olamNodeId;
|
|
34010
|
+
this.sessionId = opts.sessionId;
|
|
34011
|
+
}
|
|
34012
|
+
async call(method, path91, scopes, body, query) {
|
|
34013
|
+
const qs = query ? "?" + new URLSearchParams(Object.entries(query).filter(([, v]) => v !== void 0)).toString() : "";
|
|
34014
|
+
const url2 = `${this.baseUrl}${path91}${qs}`;
|
|
34015
|
+
const res = await fetch(url2, {
|
|
34016
|
+
method,
|
|
34017
|
+
headers: {
|
|
34018
|
+
"Content-Type": "application/json",
|
|
34019
|
+
Authorization: `Bearer ${this.token}`,
|
|
34020
|
+
"X-Olam-Node-Id": this.olamNodeId,
|
|
34021
|
+
"X-Olam-Session-Id": this.sessionId,
|
|
34022
|
+
"X-Olam-Tasks-Scopes": scopes.join(",")
|
|
34023
|
+
},
|
|
34024
|
+
body: body && method === "POST" ? JSON.stringify(body) : void 0
|
|
34025
|
+
});
|
|
34026
|
+
const envelope = await res.json().catch(() => ({ success: false, data: null, error: "invalid JSON response" }));
|
|
34027
|
+
return { status: res.status, envelope };
|
|
34028
|
+
}
|
|
34029
|
+
};
|
|
34030
|
+
|
|
34031
|
+
// ../cli-plugin-tasks/dist/tracker-parser.js
|
|
34032
|
+
import { readFileSync as readFileSync46 } from "node:fs";
|
|
34033
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
34034
|
+
function contentHash(parts) {
|
|
34035
|
+
const normalized = parts.map((p) => (p ?? "").trim()).join("|");
|
|
34036
|
+
const h = createHash6("sha256").update(normalized).digest("hex");
|
|
34037
|
+
return `sha256-${h.slice(0, 16)}`;
|
|
34038
|
+
}
|
|
34039
|
+
function parseFrontmatter2(raw) {
|
|
34040
|
+
if (!raw.startsWith("---\n"))
|
|
34041
|
+
return { frontmatter: {}, body: raw };
|
|
34042
|
+
const end = raw.indexOf("\n---\n", 4);
|
|
34043
|
+
if (end === -1)
|
|
34044
|
+
return { frontmatter: {}, body: raw };
|
|
34045
|
+
const yaml = raw.slice(4, end);
|
|
34046
|
+
const body = raw.slice(end + 5);
|
|
34047
|
+
const fm = {};
|
|
34048
|
+
for (const line of yaml.split("\n")) {
|
|
34049
|
+
const m = /^(\w+):\s*(.+?)\s*$/.exec(line);
|
|
34050
|
+
if (!m)
|
|
34051
|
+
continue;
|
|
34052
|
+
const key = m[1] ?? "";
|
|
34053
|
+
const value = m[2] ?? "";
|
|
34054
|
+
if (key === "feature")
|
|
34055
|
+
fm.feature = value;
|
|
34056
|
+
else if (key === "phase")
|
|
34057
|
+
fm.phase = value;
|
|
34058
|
+
else if (key === "tier")
|
|
34059
|
+
fm.tier = value;
|
|
34060
|
+
else if (key === "autonomous")
|
|
34061
|
+
fm.autonomous = value === "true";
|
|
34062
|
+
}
|
|
34063
|
+
return { frontmatter: fm, body };
|
|
34064
|
+
}
|
|
34065
|
+
function parseTracker(path91) {
|
|
34066
|
+
const raw = readFileSync46(path91, "utf8");
|
|
34067
|
+
const { frontmatter, body } = parseFrontmatter2(raw);
|
|
34068
|
+
const lines = body.split("\n");
|
|
34069
|
+
const tasks = [];
|
|
34070
|
+
let current = null;
|
|
34071
|
+
let currentGoal = null;
|
|
34072
|
+
const flush = () => {
|
|
34073
|
+
if (!current)
|
|
34074
|
+
return;
|
|
34075
|
+
tasks.push({
|
|
34076
|
+
taskId: contentHash([current.title, currentGoal ?? "", frontmatter.feature ?? ""]),
|
|
34077
|
+
rawId: current.rawId,
|
|
34078
|
+
title: current.title,
|
|
34079
|
+
feature: frontmatter.feature ?? null,
|
|
34080
|
+
phase: frontmatter.phase ?? null,
|
|
34081
|
+
goal: currentGoal
|
|
34082
|
+
});
|
|
34083
|
+
current = null;
|
|
34084
|
+
currentGoal = null;
|
|
34085
|
+
};
|
|
34086
|
+
for (let i = 0; i < lines.length; i++) {
|
|
34087
|
+
const line = lines[i];
|
|
34088
|
+
const headerMatch = line ? /^### ([A-Za-z]+\d+(?:\.\d+)*) — (.+?)\s*$/.exec(line) : null;
|
|
34089
|
+
if (headerMatch) {
|
|
34090
|
+
flush();
|
|
34091
|
+
current = { rawId: headerMatch[1] ?? "", title: headerMatch[2] ?? "", lineNo: i };
|
|
34092
|
+
continue;
|
|
34093
|
+
}
|
|
34094
|
+
if (current && !currentGoal && line) {
|
|
34095
|
+
const goalMatch = /^> \*\*Goal\*\*:\s*(.+?)\s*$/.exec(line);
|
|
34096
|
+
if (goalMatch)
|
|
34097
|
+
currentGoal = goalMatch[1] ?? null;
|
|
34098
|
+
}
|
|
34099
|
+
}
|
|
34100
|
+
flush();
|
|
34101
|
+
return { frontmatter, tasks };
|
|
34102
|
+
}
|
|
34103
|
+
|
|
34104
|
+
// ../cli-plugin-tasks/dist/commands/workers.js
|
|
34105
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
34106
|
+
var SUBSTRATES = ["mac-mini", "cloudflare-container", "gcp-vm"];
|
|
34107
|
+
function generateProvisionPlan(opts) {
|
|
34108
|
+
const workerId = opts.workerId ?? `worker-${randomUUID2().slice(0, 8)}`;
|
|
34109
|
+
const hostCpUrl = opts.hostCpUrl ?? "http://localhost:19000";
|
|
34110
|
+
const nodeId = opts.olamNodeId ?? `<OLAM_NODE_ID>`;
|
|
34111
|
+
const sessionId = opts.sessionId ?? `<OLAM_SESSION_ID>`;
|
|
34112
|
+
const tokenPlaceholder = `<TASK_TOKEN_FROM_AUTH_SERVICE>`;
|
|
34113
|
+
let lines;
|
|
34114
|
+
switch (opts.substrate) {
|
|
34115
|
+
case "mac-mini":
|
|
34116
|
+
lines = [
|
|
34117
|
+
`# 1. Issue task-token from auth-service:`,
|
|
34118
|
+
`# curl -X POST $AUTH_SERVICE_URL/credentials/issue-task-token \\`,
|
|
34119
|
+
`# -d '{"sub":"${workerId}","scopes":["tasks-claim","tasks-state-update"]}'`,
|
|
34120
|
+
`# 2. Install launchd plist:`,
|
|
34121
|
+
`cd packages/worker-runner/profiles/mac-mini && bash install.sh \\`,
|
|
34122
|
+
` --worker-id "${workerId}" \\`,
|
|
34123
|
+
` --host-cp-url "${hostCpUrl}" \\`,
|
|
34124
|
+
` --olam-node-id "${nodeId}" \\`,
|
|
34125
|
+
` --session-id "${sessionId}" \\`,
|
|
34126
|
+
` --task-token "${tokenPlaceholder}"`,
|
|
34127
|
+
`# 3. Verify: launchctl list | grep com.olam.worker-runner`
|
|
34128
|
+
];
|
|
34129
|
+
break;
|
|
34130
|
+
case "cloudflare-container":
|
|
34131
|
+
lines = [
|
|
34132
|
+
`# 1. Issue task-token (same as mac-mini above)`,
|
|
34133
|
+
`# 2. Deploy Cloudflare Container:`,
|
|
34134
|
+
`cd packages/worker-runner/profiles/cloudflare-container`,
|
|
34135
|
+
`wrangler secret put OLAM_TASK_TOKEN # paste ${tokenPlaceholder}`,
|
|
34136
|
+
`wrangler secret put OLAM_NODE_ID # paste ${nodeId}`,
|
|
34137
|
+
`wrangler secret put OLAM_HOST_CP_URL # paste ${hostCpUrl}`,
|
|
34138
|
+
`wrangler deploy`,
|
|
34139
|
+
`# 3. Verify: wrangler tail (watch worker logs)`
|
|
34140
|
+
];
|
|
34141
|
+
break;
|
|
34142
|
+
case "gcp-vm":
|
|
34143
|
+
lines = [
|
|
34144
|
+
`# 1. Issue task-token (same as mac-mini above)`,
|
|
34145
|
+
`# 2. Provision GCP VM with workload-identity-federation:`,
|
|
34146
|
+
`cd packages/worker-runner/profiles/gcp-vm`,
|
|
34147
|
+
`terraform apply -var="worker_id=${workerId}"`,
|
|
34148
|
+
`gcloud compute instances create olam-worker-${workerId} \\`,
|
|
34149
|
+
` --metadata-from-file startup-script=startup-script.sh \\`,
|
|
34150
|
+
` --metadata olam-host-cp-url=${hostCpUrl},olam-node-id=${nodeId}`,
|
|
34151
|
+
`# 3. Verify: gcloud compute ssh olam-worker-${workerId} -- systemctl status olam-worker-runner`
|
|
34152
|
+
];
|
|
34153
|
+
break;
|
|
34154
|
+
default: {
|
|
34155
|
+
const _exhaustive = opts.substrate;
|
|
34156
|
+
throw new Error(`Unknown substrate: ${_exhaustive}`);
|
|
34157
|
+
}
|
|
34158
|
+
}
|
|
34159
|
+
return {
|
|
34160
|
+
substrate: opts.substrate,
|
|
34161
|
+
workerId,
|
|
34162
|
+
taskTokenPlaceholder: tokenPlaceholder,
|
|
34163
|
+
installLines: lines
|
|
34164
|
+
};
|
|
34165
|
+
}
|
|
34166
|
+
function registerWorkers(program2) {
|
|
34167
|
+
const workers = program2.command("workers").description("Manage multi-substrate workers (B4.6; provision/list/revoke task-tokens for mac-mini/cloudflare-container/gcp-vm deploy profiles)");
|
|
34168
|
+
workers.command("provision <substrate>").description(`Generate substrate-specific install lines + token-issuance instructions. substrate: ${SUBSTRATES.join(" | ")}`).option("--worker-id <id>", "Worker identifier (default: random uuid-prefix)").option("--host-cp-url <url>", "host-cp URL (default: http://localhost:19000)").option("--node-id <uuid>", "Olam node ID this worker reports as (default: env OLAM_NODE_ID)").option("--session-id <uuid>", "Session ID this worker uses for claims (default: env OLAM_SESSION_ID)").option("--json", "Output structured JSON instead of operator-friendly lines").action((substrate, opts) => {
|
|
34169
|
+
if (!SUBSTRATES.includes(substrate)) {
|
|
34170
|
+
process.stderr.write(`Error: substrate must be one of: ${SUBSTRATES.join(", ")}
|
|
34171
|
+
`);
|
|
34172
|
+
process.exitCode = 1;
|
|
34173
|
+
return;
|
|
34174
|
+
}
|
|
34175
|
+
const plan = generateProvisionPlan({
|
|
34176
|
+
substrate,
|
|
34177
|
+
workerId: opts.workerId,
|
|
34178
|
+
hostCpUrl: opts.hostCpUrl,
|
|
34179
|
+
olamNodeId: opts.nodeId ?? process.env.OLAM_NODE_ID,
|
|
34180
|
+
sessionId: opts.sessionId ?? process.env.OLAM_SESSION_ID
|
|
34181
|
+
});
|
|
34182
|
+
if (opts.json) {
|
|
34183
|
+
process.stdout.write(JSON.stringify(plan, null, 2) + "\n");
|
|
34184
|
+
} else {
|
|
34185
|
+
process.stdout.write(`# olam workers provision: ${plan.substrate} substrate (worker-id=${plan.workerId})
|
|
34186
|
+
|
|
34187
|
+
`);
|
|
34188
|
+
for (const line of plan.installLines)
|
|
34189
|
+
process.stdout.write(line + "\n");
|
|
34190
|
+
}
|
|
34191
|
+
});
|
|
34192
|
+
workers.command("list").description("List active task-tokens (calls auth-service /credentials/list-task-tokens; B4.5-HTTP follow-up)").option("--json", "Output structured JSON").action((opts) => {
|
|
34193
|
+
const message = "olam workers list: auth-service HTTP wrap not yet shipped (B4.5-HTTP follow-up). For v1: inspect TaskTokenService blocklist via auth-service in-process surface.";
|
|
34194
|
+
if (opts.json) {
|
|
34195
|
+
process.stdout.write(JSON.stringify({ status: "pending-http-wrap", message }, null, 2) + "\n");
|
|
34196
|
+
} else {
|
|
34197
|
+
process.stderr.write(`${message}
|
|
34198
|
+
`);
|
|
34199
|
+
}
|
|
34200
|
+
process.exitCode = 1;
|
|
34201
|
+
});
|
|
34202
|
+
workers.command("revoke <token-or-worker-id>").description("Revoke a task-token (calls auth-service /credentials/revoke-task-token; B4.5-HTTP follow-up)").action((_target) => {
|
|
34203
|
+
const message = "olam workers revoke: auth-service HTTP wrap not yet shipped (B4.5-HTTP follow-up). For v1: call TaskTokenService.revoke() directly from auth-service process.";
|
|
34204
|
+
process.stderr.write(`${message}
|
|
34205
|
+
`);
|
|
34206
|
+
process.exitCode = 1;
|
|
34207
|
+
});
|
|
34208
|
+
}
|
|
34209
|
+
|
|
34210
|
+
// ../cli-plugin-tasks/dist/index.js
|
|
34211
|
+
function makeClient(opts) {
|
|
34212
|
+
const olamNodeId = opts.nodeId ?? process.env.OLAM_NODE_ID;
|
|
34213
|
+
const sessionId = opts.sessionId ?? process.env.OLAM_SESSION_ID;
|
|
34214
|
+
if (!olamNodeId)
|
|
34215
|
+
throw new Error("olam tasks: --node-id <uuid> or OLAM_NODE_ID env required");
|
|
34216
|
+
if (!sessionId)
|
|
34217
|
+
throw new Error("olam tasks: --session-id <uuid> or OLAM_SESSION_ID env required");
|
|
34218
|
+
return new TasksClient({ olamNodeId, sessionId });
|
|
34219
|
+
}
|
|
34220
|
+
function output(envelope, status2, json) {
|
|
34221
|
+
if (json) {
|
|
34222
|
+
process.stdout.write(JSON.stringify({ status: status2, envelope }, null, 2) + "\n");
|
|
34223
|
+
return;
|
|
34224
|
+
}
|
|
34225
|
+
if (status2 >= 200 && status2 < 300) {
|
|
34226
|
+
process.stdout.write(JSON.stringify(envelope, null, 2) + "\n");
|
|
34227
|
+
} else {
|
|
34228
|
+
process.stderr.write(`[${status2}] ${JSON.stringify(envelope, null, 2)}
|
|
34229
|
+
`);
|
|
34230
|
+
process.exitCode = 1;
|
|
34231
|
+
}
|
|
34232
|
+
}
|
|
34233
|
+
function registerTasks(program2) {
|
|
34234
|
+
const tasks = program2.command("tasks").description("Manage @olam/tasks substrate (per-node task tracking with multi-tenant compound PK + RLS)");
|
|
34235
|
+
tasks.command("new <title>").description("Create a new task (POST /api/tasks)").option("--feature <slug>", "Feature slug").option("--phase <letter>", "Phase letter").option("--priority <n>", "Priority 0-10", (v) => parseInt(v, 10)).option("--node-id <uuid>", "Olam node ID (or OLAM_NODE_ID env)").option("--session-id <uuid>", "Session ID (or OLAM_SESSION_ID env)").option("--json", "Output raw JSON envelope").action(async (title, opts) => {
|
|
34236
|
+
const client = makeClient(opts);
|
|
34237
|
+
const body = { title, feature: opts.feature, phase: opts.phase, priority: opts.priority };
|
|
34238
|
+
const { status: status2, envelope } = await client.call("POST", "/api/tasks", ["tasks-create"], body);
|
|
34239
|
+
output(envelope, status2, !!opts.json);
|
|
34240
|
+
});
|
|
34241
|
+
tasks.command("list").description("List tasks (GET /api/tasks)").option("--feature <slug>", "Filter by feature").option("--state <state>", "Filter by state (open|claimed|done|cancelled|blocked)").option("--limit <n>", "Max rows", (v) => parseInt(v, 10)).option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--json", "Output raw JSON envelope").action(async (opts) => {
|
|
34242
|
+
const client = makeClient(opts);
|
|
34243
|
+
const query = {
|
|
34244
|
+
feature: opts.feature,
|
|
34245
|
+
state: opts.state,
|
|
34246
|
+
limit: opts.limit ? String(opts.limit) : void 0
|
|
34247
|
+
};
|
|
34248
|
+
const { status: status2, envelope } = await client.call("GET", "/api/tasks", ["tasks-query"], void 0, query);
|
|
34249
|
+
output(envelope, status2, !!opts.json);
|
|
34250
|
+
});
|
|
34251
|
+
tasks.command("claim").description("Claim the next open task (POST /api/tasks/claim)").option("--feature <slug>", "Filter by feature").option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--json", "Output raw JSON envelope").action(async (opts) => {
|
|
34252
|
+
const client = makeClient(opts);
|
|
34253
|
+
const body = opts.feature ? { filter: { feature: opts.feature } } : {};
|
|
34254
|
+
const { status: status2, envelope } = await client.call("POST", "/api/tasks/claim", ["tasks-claim"], body);
|
|
34255
|
+
output(envelope, status2, !!opts.json);
|
|
34256
|
+
});
|
|
34257
|
+
tasks.command("heartbeat <task-id>").description("Heartbeat an active claim (POST /api/tasks/:id/heartbeat)").requiredOption("--creator-node-id <uuid>", "Task creator olam node ID").requiredOption("--claim-token <token>", "Claim token from `olam tasks claim`").option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--json", "Output raw JSON envelope").action(async (taskId, opts) => {
|
|
34258
|
+
const client = makeClient(opts);
|
|
34259
|
+
const body = { creatorOlamNodeId: opts.creatorNodeId, claimToken: opts.claimToken };
|
|
34260
|
+
const { status: status2, envelope } = await client.call("POST", `/api/tasks/${taskId}/heartbeat`, ["tasks-state-update"], body);
|
|
34261
|
+
output(envelope, status2, !!opts.json);
|
|
34262
|
+
});
|
|
34263
|
+
tasks.command("done <task-id>").description("Complete a claimed task (POST /api/tasks/:id/complete)").requiredOption("--creator-node-id <uuid>", "Task creator olam node ID").requiredOption("--claim-token <token>", "Claim token from `olam tasks claim`").option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--json", "Output raw JSON envelope").action(async (taskId, opts) => {
|
|
34264
|
+
const client = makeClient(opts);
|
|
34265
|
+
const body = { creatorOlamNodeId: opts.creatorNodeId, claimToken: opts.claimToken };
|
|
34266
|
+
const { status: status2, envelope } = await client.call("POST", `/api/tasks/${taskId}/complete`, ["tasks-state-update"], body);
|
|
34267
|
+
output(envelope, status2, !!opts.json);
|
|
34268
|
+
});
|
|
34269
|
+
tasks.command("update <task-id>").description("Update task fields (POST /api/tasks/:id/update)").requiredOption("--creator-node-id <uuid>", "Task creator olam node ID").option("--priority <n>", "New priority 0-10", (v) => parseInt(v, 10)).option("--feature <slug>", "New feature slug").option("--phase <letter>", "New phase letter").option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--json", "Output raw JSON envelope").action(async (taskId, opts) => {
|
|
34270
|
+
const client = makeClient(opts);
|
|
34271
|
+
const body = { creatorOlamNodeId: opts.creatorNodeId };
|
|
34272
|
+
if (opts.priority !== void 0)
|
|
34273
|
+
body.priority = opts.priority;
|
|
34274
|
+
if (opts.feature)
|
|
34275
|
+
body.feature = opts.feature;
|
|
34276
|
+
if (opts.phase)
|
|
34277
|
+
body.phase = opts.phase;
|
|
34278
|
+
const { status: status2, envelope } = await client.call("POST", `/api/tasks/${taskId}/update`, ["tasks-state-update"], body);
|
|
34279
|
+
output(envelope, status2, !!opts.json);
|
|
34280
|
+
});
|
|
34281
|
+
tasks.command("pickup").description("B2.5 execute-workflow convenience: claim next + emit parseable claim-token + creator-node-id for downstream heartbeat/done").option("--feature <slug>", "Filter to a specific feature").option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--json", "Output raw JSON envelope").action(async (opts) => {
|
|
34282
|
+
const client = makeClient(opts);
|
|
34283
|
+
const body = opts.feature ? { filter: { feature: opts.feature } } : {};
|
|
34284
|
+
const { status: status2, envelope } = await client.call("POST", "/api/tasks/claim", ["tasks-claim"], body);
|
|
34285
|
+
if (status2 !== 200 || !envelope.success || !envelope.data) {
|
|
34286
|
+
output(envelope, status2, !!opts.json);
|
|
34287
|
+
return;
|
|
34288
|
+
}
|
|
34289
|
+
const task = envelope.data;
|
|
34290
|
+
if (opts.json) {
|
|
34291
|
+
process.stdout.write(JSON.stringify({ status: status2, envelope, exports: { OLAM_TASK_ID: task.id, OLAM_TASK_CREATOR: task.creatorOlamNodeId } }, null, 2) + "\n");
|
|
34292
|
+
} else {
|
|
34293
|
+
process.stdout.write(`# olam tasks pickup: claimed ${task.id}
|
|
34294
|
+
`);
|
|
34295
|
+
process.stdout.write(`export OLAM_TASK_ID="${task.id}"
|
|
34296
|
+
`);
|
|
34297
|
+
process.stdout.write(`export OLAM_TASK_CREATOR="${task.creatorOlamNodeId}"
|
|
34298
|
+
`);
|
|
34299
|
+
process.stdout.write(`# eval "$(olam tasks pickup --feature B2)" # exports vars; downstream uses them for heartbeat / done
|
|
34300
|
+
`);
|
|
34301
|
+
}
|
|
34302
|
+
});
|
|
34303
|
+
tasks.command("sync-tracker <path>").description("Parse /10x:commit-plan tracker.md + upsert each task via POST /api/tasks (B2.4; dual-emit pattern, olam-side per cross-ownership decoupling)").option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--dry-run", "Parse + print task records; do not POST").option("--json", "Output raw JSON envelope").action(async (path91, opts) => {
|
|
34304
|
+
const parsed = parseTracker(path91);
|
|
34305
|
+
if (opts.dryRun) {
|
|
34306
|
+
process.stdout.write(JSON.stringify(parsed, null, 2) + "\n");
|
|
34307
|
+
return;
|
|
34308
|
+
}
|
|
34309
|
+
const client = makeClient(opts);
|
|
34310
|
+
const results = [];
|
|
34311
|
+
for (const task of parsed.tasks) {
|
|
34312
|
+
const body = {
|
|
34313
|
+
title: task.title,
|
|
34314
|
+
feature: task.feature ?? void 0,
|
|
34315
|
+
phase: task.phase ?? void 0
|
|
34316
|
+
};
|
|
34317
|
+
const { status: status2, envelope } = await client.call("POST", "/api/tasks", ["tasks-create"], body);
|
|
34318
|
+
results.push({ rawId: task.rawId, taskId: task.taskId, status: status2, success: envelope.success, error: envelope.error });
|
|
34319
|
+
}
|
|
34320
|
+
output({ total: parsed.tasks.length, results }, 200, !!opts.json);
|
|
34321
|
+
});
|
|
34322
|
+
tasks.command("distill").description("Cross-cutting distillation query (GET /api/tasks/distill) \u2014 B2.7 scope").option("--query <name>", "Query name (per-phase-complexity-drift | contested-tasks | prior-art-pull)").option("--corpus <type>", "local | team", "local").option("--keyword <str>", "Keyword for prior-art-pull").option("--node-id <uuid>", "Olam node ID").option("--session-id <uuid>", "Session ID").option("--json", "Output raw JSON envelope").action(async (opts) => {
|
|
34323
|
+
const client = makeClient(opts);
|
|
34324
|
+
const query = { query: opts.query, corpus: opts.corpus, keyword: opts.keyword };
|
|
34325
|
+
const scopes = opts.corpus === "team" ? ["tasks-query"] : ["tasks-query"];
|
|
34326
|
+
const { status: status2, envelope } = await client.call("GET", "/api/tasks/distill", scopes, void 0, query);
|
|
34327
|
+
output(envelope, status2, !!opts.json);
|
|
34328
|
+
});
|
|
34329
|
+
}
|
|
34330
|
+
|
|
33984
34331
|
// src/lib/completion-generator.ts
|
|
33985
34332
|
var UnsupportedShellError = class extends Error {
|
|
33986
34333
|
constructor(shell) {
|
|
@@ -34091,8 +34438,8 @@ function registerCompletion(program2) {
|
|
|
34091
34438
|
).argument("<shell>", "zsh | bash").action((shell) => {
|
|
34092
34439
|
const tree = program2.parent ?? program2;
|
|
34093
34440
|
try {
|
|
34094
|
-
const
|
|
34095
|
-
process.stdout.write(
|
|
34441
|
+
const output2 = generateCompletion(tree, shell);
|
|
34442
|
+
process.stdout.write(output2);
|
|
34096
34443
|
} catch (err) {
|
|
34097
34444
|
if (err instanceof UnsupportedShellError) {
|
|
34098
34445
|
process.stderr.write(`${err.message}
|
|
@@ -34109,20 +34456,20 @@ function registerCompletion(program2) {
|
|
|
34109
34456
|
init_cli_version();
|
|
34110
34457
|
init_health_probes();
|
|
34111
34458
|
import { spawn as spawn7 } from "node:child_process";
|
|
34112
|
-
import { existsSync as
|
|
34113
|
-
import { homedir as
|
|
34459
|
+
import { existsSync as existsSync80 } from "node:fs";
|
|
34460
|
+
import { homedir as homedir42 } from "node:os";
|
|
34114
34461
|
import path72 from "node:path";
|
|
34115
34462
|
import { createInterface as createInterface3 } from "node:readline";
|
|
34116
34463
|
|
|
34117
34464
|
// src/lib/shell-rc.ts
|
|
34118
|
-
import { copyFileSync as copyFileSync5, existsSync as existsSync59, readFileSync as
|
|
34465
|
+
import { copyFileSync as copyFileSync5, existsSync as existsSync59, readFileSync as readFileSync47, renameSync as renameSync8, writeFileSync as writeFileSync28 } from "node:fs";
|
|
34119
34466
|
import path52 from "node:path";
|
|
34120
34467
|
function appendIdempotent(opts) {
|
|
34121
34468
|
const { rcPath, marker, contentLine, clock = () => /* @__PURE__ */ new Date() } = opts;
|
|
34122
34469
|
if (!existsSync59(rcPath)) {
|
|
34123
34470
|
return { status: "no-rc-file", backupPath: null };
|
|
34124
34471
|
}
|
|
34125
|
-
const content =
|
|
34472
|
+
const content = readFileSync47(rcPath, "utf-8");
|
|
34126
34473
|
if (content.includes(marker)) {
|
|
34127
34474
|
return { status: "already-present", backupPath: null };
|
|
34128
34475
|
}
|
|
@@ -34134,7 +34481,7 @@ function appendIdempotent(opts) {
|
|
|
34134
34481
|
const nextContent = `${content}${separator}${contentLine}${trailing}`;
|
|
34135
34482
|
const tmpPath = `${rcPath}.olam-tmp.${process.pid}`;
|
|
34136
34483
|
writeFileSync28(tmpPath, nextContent, { encoding: "utf-8" });
|
|
34137
|
-
|
|
34484
|
+
renameSync8(tmpPath, rcPath);
|
|
34138
34485
|
return { status: "appended", backupPath };
|
|
34139
34486
|
}
|
|
34140
34487
|
function resolveShellRc(home, shellEnv) {
|
|
@@ -34300,7 +34647,7 @@ async function pickSkillSourcePhase(opts, deps) {
|
|
|
34300
34647
|
}
|
|
34301
34648
|
|
|
34302
34649
|
// src/commands/setup-phase-5b-project-sweep.ts
|
|
34303
|
-
import { homedir as
|
|
34650
|
+
import { homedir as homedir41 } from "node:os";
|
|
34304
34651
|
import * as path71 from "node:path";
|
|
34305
34652
|
import * as fs71 from "node:fs";
|
|
34306
34653
|
async function loadWalkFn() {
|
|
@@ -34333,7 +34680,7 @@ async function runProjectSweepPhase(opts, deps, sweepDeps = {}) {
|
|
|
34333
34680
|
if (opts.skipProjectSweep) {
|
|
34334
34681
|
return { ok: true, skipped: true, message: "skipped via --skip-project-sweep" };
|
|
34335
34682
|
}
|
|
34336
|
-
const home = deps.home ??
|
|
34683
|
+
const home = deps.home ?? homedir41();
|
|
34337
34684
|
const projectsRoot = opts.projects ?? path71.join(home, "Projects");
|
|
34338
34685
|
const existsSyncFn = sweepDeps.existsSync ?? fs71.existsSync;
|
|
34339
34686
|
if (!existsSyncFn(projectsRoot)) {
|
|
@@ -34532,7 +34879,7 @@ async function phase4ShellInit(opts, deps) {
|
|
|
34532
34879
|
if (opts.skipShellInit) {
|
|
34533
34880
|
return { ok: true, skipped: true, message: "skipped via --skip-shell-init" };
|
|
34534
34881
|
}
|
|
34535
|
-
const home = deps.home ??
|
|
34882
|
+
const home = deps.home ?? homedir42();
|
|
34536
34883
|
const shellEnv = deps.shellEnv ?? process.env.SHELL;
|
|
34537
34884
|
const rcPath = resolveShellRc(home, shellEnv);
|
|
34538
34885
|
if (rcPath === null) {
|
|
@@ -34569,7 +34916,7 @@ async function phase5InitProject(opts, deps) {
|
|
|
34569
34916
|
const cwd = deps.cwd ?? process.cwd();
|
|
34570
34917
|
const projectRoot = findProjectRoot(cwd);
|
|
34571
34918
|
const configPath = path72.join(projectRoot, ".olam", "config.yaml");
|
|
34572
|
-
if (
|
|
34919
|
+
if (existsSync80(configPath)) {
|
|
34573
34920
|
return { ok: true, message: `${configPath} present (no change)` };
|
|
34574
34921
|
}
|
|
34575
34922
|
const promptFn = deps.prompt ?? defaultPrompt;
|
|
@@ -37524,7 +37871,7 @@ function registerWorldUpgrade(program2) {
|
|
|
37524
37871
|
|
|
37525
37872
|
// src/commands/mcp/serve.ts
|
|
37526
37873
|
init_output();
|
|
37527
|
-
import { existsSync as
|
|
37874
|
+
import { existsSync as existsSync92 } from "node:fs";
|
|
37528
37875
|
import { dirname as dirname52, resolve as resolve22 } from "node:path";
|
|
37529
37876
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
37530
37877
|
var here = dirname52(fileURLToPath7(import.meta.url));
|
|
@@ -37534,7 +37881,7 @@ var BUNDLE_PATH_CANDIDATES = [
|
|
|
37534
37881
|
// dev / tsc-only (`dist/commands/mcp/serve.js`) — up two levels
|
|
37535
37882
|
resolve22(here, "..", "..", "mcp-server.js")
|
|
37536
37883
|
];
|
|
37537
|
-
function resolveBundlePath(candidates2 = BUNDLE_PATH_CANDIDATES, exists =
|
|
37884
|
+
function resolveBundlePath(candidates2 = BUNDLE_PATH_CANDIDATES, exists = existsSync92) {
|
|
37538
37885
|
return candidates2.find(exists) ?? null;
|
|
37539
37886
|
}
|
|
37540
37887
|
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.";
|
|
@@ -37556,9 +37903,9 @@ function registerMcpServe(cmd) {
|
|
|
37556
37903
|
init_output();
|
|
37557
37904
|
|
|
37558
37905
|
// src/commands/mcp/install-shared.ts
|
|
37559
|
-
import { spawnSync as
|
|
37906
|
+
import { spawnSync as spawnSync26 } from "node:child_process";
|
|
37560
37907
|
var DEFAULT_CLAUDE_SHELL_DEPS = {
|
|
37561
|
-
spawn:
|
|
37908
|
+
spawn: spawnSync26,
|
|
37562
37909
|
log: (msg) => console.log(msg)
|
|
37563
37910
|
};
|
|
37564
37911
|
function isOnPath(deps, bin) {
|
|
@@ -38275,27 +38622,27 @@ function registerMcp(program2) {
|
|
|
38275
38622
|
init_output();
|
|
38276
38623
|
|
|
38277
38624
|
// src/lib/memory-host-process-migration.ts
|
|
38278
|
-
import { existsSync as
|
|
38279
|
-
import { spawnSync as
|
|
38625
|
+
import { existsSync as existsSync94, readFileSync as readFileSync73, unlinkSync as unlinkSync23 } from "node:fs";
|
|
38626
|
+
import { spawnSync as spawnSync27 } from "node:child_process";
|
|
38280
38627
|
|
|
38281
38628
|
// src/commands/memory/_paths.ts
|
|
38282
|
-
import { homedir as
|
|
38283
|
-
import { join as
|
|
38629
|
+
import { homedir as homedir47 } from "node:os";
|
|
38630
|
+
import { join as join87, dirname as dirname53 } from "node:path";
|
|
38284
38631
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
38285
|
-
var OLAM_HOME3 =
|
|
38286
|
-
var MEMORY_PID_PATH =
|
|
38287
|
-
var MEMORY_LOG_PATH =
|
|
38288
|
-
var MEMORY_DATA_DIR =
|
|
38632
|
+
var OLAM_HOME3 = join87(homedir47(), ".olam");
|
|
38633
|
+
var MEMORY_PID_PATH = join87(OLAM_HOME3, "memory.pid");
|
|
38634
|
+
var MEMORY_LOG_PATH = join87(OLAM_HOME3, "memory-service.log");
|
|
38635
|
+
var MEMORY_DATA_DIR = join87(OLAM_HOME3, "memory-data");
|
|
38289
38636
|
var MEMORY_REST_PORT = 3111;
|
|
38290
38637
|
var MEMORY_LIVEZ_URL = `http://localhost:${MEMORY_REST_PORT}/agentmemory/livez`;
|
|
38291
38638
|
var here2 = dirname53(fileURLToPath8(import.meta.url));
|
|
38292
38639
|
var candidates = [
|
|
38293
38640
|
// 1. Workspace dev (built): packages/cli/dist/commands/memory/_paths.js → packages/cli → packages/memory-service
|
|
38294
|
-
|
|
38641
|
+
join87(here2, "..", "..", "..", "..", "memory-service"),
|
|
38295
38642
|
// 2. Workspace bundled: packages/cli/dist/index.js → packages/cli → packages/memory-service
|
|
38296
|
-
|
|
38643
|
+
join87(here2, "..", "..", "memory-service"),
|
|
38297
38644
|
// 3. CWD fallback
|
|
38298
|
-
|
|
38645
|
+
join87(process.cwd(), "packages", "memory-service")
|
|
38299
38646
|
];
|
|
38300
38647
|
var MEMORY_SERVICE_CANDIDATES = candidates;
|
|
38301
38648
|
|
|
@@ -38304,8 +38651,8 @@ var KILL_TIMEOUT_MS = 5e3;
|
|
|
38304
38651
|
function migrateFromHostProcess(opts = {}) {
|
|
38305
38652
|
const pidPath2 = opts.pidPath ?? MEMORY_PID_PATH;
|
|
38306
38653
|
const logPath = opts.logPath ?? MEMORY_LOG_PATH;
|
|
38307
|
-
const pidfileExists =
|
|
38308
|
-
const logExists =
|
|
38654
|
+
const pidfileExists = existsSync94(pidPath2);
|
|
38655
|
+
const logExists = existsSync94(logPath);
|
|
38309
38656
|
if (!pidfileExists && !logExists) {
|
|
38310
38657
|
return { cleaned: false, summary: "no legacy host-process state to clean" };
|
|
38311
38658
|
}
|
|
@@ -38344,7 +38691,7 @@ function migrateFromHostProcess(opts = {}) {
|
|
|
38344
38691
|
}
|
|
38345
38692
|
function readPidFromFile(pidPath2) {
|
|
38346
38693
|
try {
|
|
38347
|
-
const raw =
|
|
38694
|
+
const raw = readFileSync73(pidPath2, "utf8").trim();
|
|
38348
38695
|
const pid = parseInt(raw, 10);
|
|
38349
38696
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
38350
38697
|
return pid;
|
|
@@ -38361,7 +38708,7 @@ function isProcessAlive(pid) {
|
|
|
38361
38708
|
}
|
|
38362
38709
|
}
|
|
38363
38710
|
function processCommName(pid) {
|
|
38364
|
-
const r =
|
|
38711
|
+
const r = spawnSync27("ps", ["-p", String(pid), "-o", "comm="], { encoding: "utf-8" });
|
|
38365
38712
|
if (r.status !== 0) return null;
|
|
38366
38713
|
const comm = r.stdout.trim();
|
|
38367
38714
|
return comm.split("/").pop() ?? null;
|
|
@@ -38375,7 +38722,7 @@ function terminateProcess(pid) {
|
|
|
38375
38722
|
const deadline = Date.now() + KILL_TIMEOUT_MS;
|
|
38376
38723
|
while (Date.now() < deadline) {
|
|
38377
38724
|
if (!isProcessAlive(pid)) return true;
|
|
38378
|
-
|
|
38725
|
+
spawnSync27("sleep", ["0.1"]);
|
|
38379
38726
|
}
|
|
38380
38727
|
try {
|
|
38381
38728
|
process.kill(pid, "SIGKILL");
|
|
@@ -38472,7 +38819,7 @@ function registerMemoryStop(cmd) {
|
|
|
38472
38819
|
|
|
38473
38820
|
// src/commands/memory/status.ts
|
|
38474
38821
|
init_output();
|
|
38475
|
-
import { existsSync as
|
|
38822
|
+
import { existsSync as existsSync95 } from "node:fs";
|
|
38476
38823
|
async function probe(secret) {
|
|
38477
38824
|
try {
|
|
38478
38825
|
const headers = {};
|
|
@@ -38497,7 +38844,7 @@ async function collectMemoryStatus() {
|
|
|
38497
38844
|
livez,
|
|
38498
38845
|
secretSet: hasMemorySecret(),
|
|
38499
38846
|
port: MEMORY_REST_PORT,
|
|
38500
|
-
legacyPidfilePresent:
|
|
38847
|
+
legacyPidfilePresent: existsSync95(MEMORY_PID_PATH)
|
|
38501
38848
|
};
|
|
38502
38849
|
}
|
|
38503
38850
|
async function runMemoryStatus(opts = {}) {
|
|
@@ -38580,7 +38927,7 @@ function registerMemoryLogs(cmd) {
|
|
|
38580
38927
|
}
|
|
38581
38928
|
|
|
38582
38929
|
// src/commands/memory/secret.ts
|
|
38583
|
-
import { existsSync as
|
|
38930
|
+
import { existsSync as existsSync96 } from "node:fs";
|
|
38584
38931
|
init_output();
|
|
38585
38932
|
async function runMemorySecretShow() {
|
|
38586
38933
|
if (!hasMemorySecret()) {
|
|
@@ -38595,7 +38942,7 @@ async function runMemorySecretShow() {
|
|
|
38595
38942
|
}
|
|
38596
38943
|
async function runMemorySecretRotate() {
|
|
38597
38944
|
printHeader("olam memory secret rotate");
|
|
38598
|
-
const wasRunning =
|
|
38945
|
+
const wasRunning = existsSync96(MEMORY_PID_PATH);
|
|
38599
38946
|
if (wasRunning) {
|
|
38600
38947
|
printInfo("current state", "service running; will restart with new secret");
|
|
38601
38948
|
const stopRc = await runMemoryStop();
|
|
@@ -38777,14 +39124,14 @@ function registerMemoryUninstall(cmd) {
|
|
|
38777
39124
|
// src/commands/memory/mode.ts
|
|
38778
39125
|
init_schema2();
|
|
38779
39126
|
init_output();
|
|
38780
|
-
import { existsSync as
|
|
38781
|
-
import { join as
|
|
39127
|
+
import { existsSync as existsSync97, readFileSync as readFileSync74, writeFileSync as writeFileSync45 } from "node:fs";
|
|
39128
|
+
import { join as join88 } from "node:path";
|
|
38782
39129
|
import * as readline6 from "node:readline/promises";
|
|
38783
39130
|
import { parse as parseYaml7, stringify as stringifyYaml6 } from "yaml";
|
|
38784
39131
|
var CONFIG_REL = ".olam/config.yaml";
|
|
38785
39132
|
function locateConfig(cwd) {
|
|
38786
|
-
const absPath =
|
|
38787
|
-
if (!
|
|
39133
|
+
const absPath = join88(cwd, CONFIG_REL);
|
|
39134
|
+
if (!existsSync97(absPath)) {
|
|
38788
39135
|
throw new Error(
|
|
38789
39136
|
`No ${CONFIG_REL} at ${cwd}. Run \`olam init\` in your workspace root first.`
|
|
38790
39137
|
);
|
|
@@ -38792,7 +39139,7 @@ function locateConfig(cwd) {
|
|
|
38792
39139
|
return { absPath };
|
|
38793
39140
|
}
|
|
38794
39141
|
function readConfigYaml(absPath) {
|
|
38795
|
-
const raw =
|
|
39142
|
+
const raw = readFileSync74(absPath, "utf-8");
|
|
38796
39143
|
const parsed = parseYaml7(raw) ?? {};
|
|
38797
39144
|
if (typeof parsed !== "object" || parsed === null) {
|
|
38798
39145
|
throw new Error(`${absPath} is not a YAML object`);
|
|
@@ -38920,20 +39267,20 @@ function registerMemoryMode(cmd) {
|
|
|
38920
39267
|
// src/commands/memory/bridge.ts
|
|
38921
39268
|
init_output();
|
|
38922
39269
|
import { spawn as spawn11 } from "node:child_process";
|
|
38923
|
-
import { existsSync as
|
|
38924
|
-
import { join as
|
|
39270
|
+
import { existsSync as existsSync98 } from "node:fs";
|
|
39271
|
+
import { join as join89 } from "node:path";
|
|
38925
39272
|
var DEFAULT_PORT2 = 8788;
|
|
38926
39273
|
function resolveMemoryServiceDir() {
|
|
38927
39274
|
for (const c of MEMORY_SERVICE_CANDIDATES) {
|
|
38928
|
-
if (
|
|
39275
|
+
if (existsSync98(c)) return c;
|
|
38929
39276
|
}
|
|
38930
39277
|
throw new Error(
|
|
38931
39278
|
`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.`
|
|
38932
39279
|
);
|
|
38933
39280
|
}
|
|
38934
39281
|
function resolveLocalBridgeScript(serviceDir) {
|
|
38935
|
-
const path91 =
|
|
38936
|
-
if (!
|
|
39282
|
+
const path91 = join89(serviceDir, "scripts", "local-bridge-server.mjs");
|
|
39283
|
+
if (!existsSync98(path91)) {
|
|
38937
39284
|
throw new Error(
|
|
38938
39285
|
`Could not find local-bridge-server.mjs at ${path91}. Verify packages/memory-service ships the scripts/ directory.`
|
|
38939
39286
|
);
|
|
@@ -39394,10 +39741,10 @@ init_workspace_name();
|
|
|
39394
39741
|
init_kg_caps();
|
|
39395
39742
|
init_output();
|
|
39396
39743
|
import fs85 from "node:fs";
|
|
39397
|
-
import { homedir as
|
|
39744
|
+
import { homedir as homedir48 } from "node:os";
|
|
39398
39745
|
import path84 from "node:path";
|
|
39399
39746
|
function olamHome4() {
|
|
39400
|
-
return process.env.OLAM_HOME ?? path84.join(
|
|
39747
|
+
return process.env.OLAM_HOME ?? path84.join(homedir48(), ".olam");
|
|
39401
39748
|
}
|
|
39402
39749
|
function kgRoot2() {
|
|
39403
39750
|
return path84.join(olamHome4(), "kg");
|
|
@@ -40507,16 +40854,16 @@ function registerKg(program2) {
|
|
|
40507
40854
|
// src/commands/flywheel/emit-breadcrumb.ts
|
|
40508
40855
|
init_file_lock();
|
|
40509
40856
|
import { mkdirSync as mkdirSync57, appendFileSync as appendFileSync6 } from "node:fs";
|
|
40510
|
-
import { homedir as
|
|
40511
|
-
import { dirname as dirname56, join as
|
|
40512
|
-
import { randomUUID as
|
|
40857
|
+
import { homedir as homedir52 } from "node:os";
|
|
40858
|
+
import { dirname as dirname56, join as join93 } from "node:path";
|
|
40859
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
40513
40860
|
var VALID_SEVERITIES = /* @__PURE__ */ new Set(["critical", "high", "medium", "low", "info", "warn"]);
|
|
40514
40861
|
var PROMPT_FEEDING_FIELDS = ["extracted_pattern", "severity", "affected_persona", "proposed_edit"];
|
|
40515
|
-
var BREADCRUMBS_BASE =
|
|
40862
|
+
var BREADCRUMBS_BASE = join93(homedir52(), ".local", "share", "claude", "breadcrumbs");
|
|
40516
40863
|
var LOCK_FILENAME = ".flywheel-emit.lock";
|
|
40517
40864
|
function buildRecord(opts) {
|
|
40518
40865
|
const rec = {
|
|
40519
|
-
breadcrumb_id:
|
|
40866
|
+
breadcrumb_id: randomUUID3().replace(/-/g, ""),
|
|
40520
40867
|
emitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40521
40868
|
emitted_by_skill: opts.skill,
|
|
40522
40869
|
pass_number: opts.pass !== void 0 ? Number.parseInt(opts.pass, 10) : 0,
|
|
@@ -40559,7 +40906,7 @@ function validatePromptFeeding(rec) {
|
|
|
40559
40906
|
}
|
|
40560
40907
|
function destPath(projectSlug) {
|
|
40561
40908
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
40562
|
-
return
|
|
40909
|
+
return join93(BREADCRUMBS_BASE, projectSlug, `${today}.jsonl`);
|
|
40563
40910
|
}
|
|
40564
40911
|
async function emitBreadcrumb(opts) {
|
|
40565
40912
|
if (!VALID_SEVERITIES.has(opts.severity)) {
|
|
@@ -40660,7 +41007,7 @@ function registerFlywheelK5Score(parent) {
|
|
|
40660
41007
|
}
|
|
40661
41008
|
|
|
40662
41009
|
// src/commands/flywheel/k5-validate.ts
|
|
40663
|
-
import { readFileSync as
|
|
41010
|
+
import { readFileSync as readFileSync78, statSync as statSync24 } from "node:fs";
|
|
40664
41011
|
import { parse as parseYAML } from "yaml";
|
|
40665
41012
|
var K5_DIMS = ["direction", "approach", "open_questions", "constraints", "reuse"];
|
|
40666
41013
|
var MAX_PLAN_BYTES = 1048576;
|
|
@@ -40721,7 +41068,7 @@ function validateK5ScoredAt(scoredAt) {
|
|
|
40721
41068
|
function validatePlan(path91) {
|
|
40722
41069
|
let stat;
|
|
40723
41070
|
try {
|
|
40724
|
-
stat =
|
|
41071
|
+
stat = statSync24(path91);
|
|
40725
41072
|
} catch (err) {
|
|
40726
41073
|
return { ok: false, message: `FAIL cannot stat ${path91}: ${err instanceof Error ? err.message : "unknown"}` };
|
|
40727
41074
|
}
|
|
@@ -40730,7 +41077,7 @@ function validatePlan(path91) {
|
|
|
40730
41077
|
}
|
|
40731
41078
|
let text;
|
|
40732
41079
|
try {
|
|
40733
|
-
text =
|
|
41080
|
+
text = readFileSync78(path91, "utf8");
|
|
40734
41081
|
} catch (err) {
|
|
40735
41082
|
return { ok: false, message: `FAIL cannot read ${path91}: ${err instanceof Error ? err.message : "unknown"}` };
|
|
40736
41083
|
}
|
|
@@ -40855,8 +41202,8 @@ function registerFlywheelDiversityCheck(parent) {
|
|
|
40855
41202
|
|
|
40856
41203
|
// src/commands/flywheel/ping.ts
|
|
40857
41204
|
import { mkdirSync as mkdirSync58, writeFileSync as writeFileSync49 } from "node:fs";
|
|
40858
|
-
import { homedir as
|
|
40859
|
-
import { dirname as dirname57, join as
|
|
41205
|
+
import { homedir as homedir53 } from "node:os";
|
|
41206
|
+
import { dirname as dirname57, join as join94 } from "node:path";
|
|
40860
41207
|
var COLD_START_BUDGET_GOOD_MS = 200;
|
|
40861
41208
|
var COLD_START_BUDGET_FAIR_MS = 500;
|
|
40862
41209
|
function classifyColdStart(coldStartMs) {
|
|
@@ -40872,7 +41219,7 @@ function readOlamVersion() {
|
|
|
40872
41219
|
}
|
|
40873
41220
|
}
|
|
40874
41221
|
function writeBaseline(record) {
|
|
40875
|
-
const baselinePath =
|
|
41222
|
+
const baselinePath = join94(homedir53(), ".local", "share", "olam", "flywheel-baseline.json");
|
|
40876
41223
|
mkdirSync58(dirname57(baselinePath), { recursive: true });
|
|
40877
41224
|
writeFileSync49(baselinePath, JSON.stringify(record, null, 2) + "\n", "utf8");
|
|
40878
41225
|
return baselinePath;
|
|
@@ -40936,7 +41283,7 @@ function registerFlywheel(program2) {
|
|
|
40936
41283
|
|
|
40937
41284
|
// src/commands/seed.ts
|
|
40938
41285
|
init_output();
|
|
40939
|
-
import { spawnSync as
|
|
41286
|
+
import { spawnSync as spawnSync28, spawn as spawnAsync2 } from "node:child_process";
|
|
40940
41287
|
var DEFAULT_SINGLETON_CONTAINER = "olam-postgres";
|
|
40941
41288
|
var DEFAULT_SINGLETON_USER = "development";
|
|
40942
41289
|
function assertValidSeedName(name) {
|
|
@@ -40947,7 +41294,7 @@ function assertValidSeedName(name) {
|
|
|
40947
41294
|
}
|
|
40948
41295
|
}
|
|
40949
41296
|
function singletonDocker(container, user, args, stdin) {
|
|
40950
|
-
return
|
|
41297
|
+
return spawnSync28(
|
|
40951
41298
|
"docker",
|
|
40952
41299
|
["exec", "-i", container, "psql", "-U", user, ...args],
|
|
40953
41300
|
{ encoding: "utf-8", input: stdin }
|
|
@@ -41002,7 +41349,7 @@ async function handleBake(opts) {
|
|
|
41002
41349
|
if (sources.length > 1) {
|
|
41003
41350
|
throw new Error("multiple sources specified \u2014 pass exactly one of --source-container, --source-url, --source-local");
|
|
41004
41351
|
}
|
|
41005
|
-
const ping =
|
|
41352
|
+
const ping = spawnSync28("docker", ["inspect", "--format", "{{.State.Status}}", singleton], { encoding: "utf-8" });
|
|
41006
41353
|
if (ping.status !== 0 || (ping.stdout || "").trim() !== "running") {
|
|
41007
41354
|
throw new Error(`singleton container "${singleton}" not running \u2014 run \`olam bootstrap\` first`);
|
|
41008
41355
|
}
|
|
@@ -41391,6 +41738,8 @@ registerBootstrap(program);
|
|
|
41391
41738
|
registerDiagnose(program);
|
|
41392
41739
|
registerDoctor(program);
|
|
41393
41740
|
registerSubstrate(program);
|
|
41741
|
+
registerTasks(program);
|
|
41742
|
+
registerWorkers(program);
|
|
41394
41743
|
registerCompletion(program);
|
|
41395
41744
|
registerSetup(program);
|
|
41396
41745
|
registerSetupMetrics(program);
|