@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/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 output;
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
- output = await Promise.race([outputPromise, timer]);
6400
+ output2 = await Promise.race([outputPromise, timer]);
6407
6401
  } else {
6408
- output = await outputPromise;
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: output.stdout,
6415
- stderr: output.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 output = execFileSync2("git", ["rev-list", "--count", branch, "--not", "--remotes"], { cwd: gitDir, stdio: "pipe" }).toString().trim();
8485
- localCommitCount = parseInt(output, 10) || 0;
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 output = { mcpServers: stripped };
8721
- fs13.writeFileSync(path15.join(destClaudeDir, ".claude.json"), JSON.stringify(output, null, 2), { mode: 384 });
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, homedir54) {
9245
- return p.replace(/^~(?=$|\/|\\)/, homedir54());
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 homedir54 = deps.homedir ?? (() => os9.homedir());
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, homedir54);
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 homedir54 = deps.homedir ?? (() => os9.homedir());
9405
- const existsSync102 = deps.existsSync ?? ((p) => fs15.existsSync(p));
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, homedir54);
9387
+ const repoPath = expandHome2(repo.path, homedir55);
9415
9388
  const worktreePath = path17.join(workspacePath, repo.name);
9416
- if (!existsSync102(repoPath))
9389
+ if (!existsSync103(repoPath))
9417
9390
  continue;
9418
- if (!existsSync102(worktreePath)) {
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 (!existsSync102(src))
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) => fs92.readdirSync(p, { encoding: "utf-8" }),
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 = fs92.lstatSync(p, { throwIfNoEntry: true });
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 = fs92.statSync(p, { throwIfNoEntry: true });
19125
+ const s = statSync23(p, { throwIfNoEntry: true });
19153
19126
  return { isDirectory: () => s.isDirectory(), mtimeMs: s.mtimeMs };
19154
19127
  },
19155
- existsSync: (p) => fs92.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 readdirSync27 = deps.readdirSync ?? fs31.readdirSync;
22145
- const readFileSync78 = deps.readFileSync ?? fs31.readFileSync;
22116
+ const readdirSync28 = deps.readdirSync ?? fs31.readdirSync;
22117
+ const readFileSync80 = deps.readFileSync ?? fs31.readFileSync;
22146
22118
  const writeFileSyncImpl = deps.writeFileSync ?? fs31.writeFileSync;
22147
- const existsSync102 = deps.existsSync ?? fs31.existsSync;
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 (!existsSync102(targetDir)) {
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 = readdirSync27(targetDir, { withFileTypes: true });
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 = readFileSync78(filePath, "utf8");
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
- __require("node:fs").renameSync(tmp, statePath);
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 readFileSync78 = deps.readFileSyncImpl ?? fs32.readFileSync;
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 = readFileSync78(configMapPath, "utf8");
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 spawnSync18 } from "node:child_process";
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 spawnSync16 } from "node:child_process";
23709
+ import { spawnSync as spawnSync17 } from "node:child_process";
23716
23710
  var DEFAULT_DOCKER_EXEC_DEPS = {
23717
- spawn: spawnSync16,
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 spawnSync17 } from "node:child_process";
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 = spawnSync17(
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
- spawnSync18("docker", ["pull", overrideRef], { stdio: "pipe" });
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 = spawnSync18(
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 spawnSync20 } from "node:child_process";
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 spawnSync19 } from "node:child_process";
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 = spawnSync19("ps", ["-p", String(pid), "-o", "comm="], {
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 = spawnSync20(cmd, [...args], {
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 = spawnSync20("git", ["status", "--porcelain"], {
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 = spawnSync20("git", ["rev-parse", "--abbrev-ref", "@{u}"], {
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 = spawnSync20("git", ["rev-parse", "HEAD"], {
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 = spawnSync20("docker", ["image", "inspect", "--format", "{{.Id}}", tag], {
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 = spawnSync20("docker", ["create", "--name", `olam-smoke-${Date.now()}`, image], {
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 = spawnSync20(
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
- spawnSync20("docker", ["rm", "-f", containerId], {
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 = spawnSync20("docker", ["tag", source, dest], {
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
- spawnSync20("docker", ["stop", "olam-auth"], {
30928
+ spawnSync21("docker", ["stop", "olam-auth"], {
30935
30929
  encoding: "utf-8",
30936
30930
  stdio: ["ignore", "ignore", "ignore"]
30937
30931
  });
30938
- spawnSync20("docker", ["rm", "olam-auth"], {
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
- spawnSync20("docker", ["stop", "olam-auth"], {
31230
+ spawnSync21("docker", ["stop", "olam-auth"], {
31237
31231
  encoding: "utf-8",
31238
31232
  stdio: ["ignore", "ignore", "ignore"]
31239
31233
  });
31240
- spawnSync20("docker", ["rm", "olam-auth"], {
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 = spawnSync20(
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 = spawnSync20("docker", ["rm", "-f", containerName], {
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 = spawnSync20("bash", [scriptPath], {
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 spawnSync21 } from "node:child_process";
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 = spawnSync21(
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 spawnSync22 } from "node:child_process";
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 = spawnSync22("docker", args, {
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 spawnSync23 } from "node:child_process";
32791
+ import { spawnSync as spawnSync24 } from "node:child_process";
32798
32792
  var RESTART_TIMEOUT_S2 = 30;
32799
32793
  function docker2(args) {
32800
- const result = spawnSync23("docker", args, {
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 detectClusterTypeImpl = deps.detectK8sClusterTypeImpl;
33322
- const socketResult = await probeDockerSocketBindMount(k8sCtx, wrapImpl, socketCheckImpl, detectClusterTypeImpl);
33323
- rows.push({ name: "docker socket bind-mount", result: socketResult, position: 28 });
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
- async function defaultDockerSocketCheck(kubectlContext, wrapImpl) {
33544
- const ctxArgs = kubectlContext ? ["--context", kubectlContext] : [];
33545
- const result = await wrapImpl(
33546
- [
33547
- ...ctxArgs,
33548
- "exec",
33549
- "deploy/olam-host-cp",
33550
- "-n",
33551
- "olam",
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 probeDockerSocketBindMount(kubectlContext, wrapImpl, checkImpl, detectClusterTypeImpl) {
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 accessible = await check(kubectlContext, wrapImpl);
33564
- if (accessible) {
33565
- return { ok: true, message: "docker socket accessible at /var/run/docker.sock" };
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 socket not accessible at /var/run/docker.sock",
33572
- remedy: buildDockerSocketRemedy(clusterType)
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 output = generateCompletion(tree, shell);
34095
- process.stdout.write(output);
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 existsSync79 } from "node:fs";
34113
- import { homedir as homedir41 } from "node:os";
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 readFileSync45, renameSync as renameSync7, writeFileSync as writeFileSync28 } from "node:fs";
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 = readFileSync45(rcPath, "utf-8");
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
- renameSync7(tmpPath, rcPath);
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 homedir40 } from "node:os";
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 ?? homedir40();
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 ?? homedir41();
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 (existsSync79(configPath)) {
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 existsSync91 } from "node:fs";
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 = existsSync91) {
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 spawnSync25 } from "node:child_process";
37906
+ import { spawnSync as spawnSync26 } from "node:child_process";
37560
37907
  var DEFAULT_CLAUDE_SHELL_DEPS = {
37561
- spawn: spawnSync25,
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 existsSync93, readFileSync as readFileSync71, unlinkSync as unlinkSync23 } from "node:fs";
38279
- import { spawnSync as spawnSync26 } from "node:child_process";
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 homedir46 } from "node:os";
38283
- import { join as join86, dirname as dirname53 } from "node:path";
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 = join86(homedir46(), ".olam");
38286
- var MEMORY_PID_PATH = join86(OLAM_HOME3, "memory.pid");
38287
- var MEMORY_LOG_PATH = join86(OLAM_HOME3, "memory-service.log");
38288
- var MEMORY_DATA_DIR = join86(OLAM_HOME3, "memory-data");
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
- join86(here2, "..", "..", "..", "..", "memory-service"),
38641
+ join87(here2, "..", "..", "..", "..", "memory-service"),
38295
38642
  // 2. Workspace bundled: packages/cli/dist/index.js → packages/cli → packages/memory-service
38296
- join86(here2, "..", "..", "memory-service"),
38643
+ join87(here2, "..", "..", "memory-service"),
38297
38644
  // 3. CWD fallback
38298
- join86(process.cwd(), "packages", "memory-service")
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 = existsSync93(pidPath2);
38308
- const logExists = existsSync93(logPath);
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 = readFileSync71(pidPath2, "utf8").trim();
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 = spawnSync26("ps", ["-p", String(pid), "-o", "comm="], { encoding: "utf-8" });
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
- spawnSync26("sleep", ["0.1"]);
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 existsSync94 } from "node:fs";
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: existsSync94(MEMORY_PID_PATH)
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 existsSync95 } from "node:fs";
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 = existsSync95(MEMORY_PID_PATH);
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 existsSync96, readFileSync as readFileSync72, writeFileSync as writeFileSync45 } from "node:fs";
38781
- import { join as join87 } from "node:path";
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 = join87(cwd, CONFIG_REL);
38787
- if (!existsSync96(absPath)) {
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 = readFileSync72(absPath, "utf-8");
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 existsSync97 } from "node:fs";
38924
- import { join as join88 } from "node:path";
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 (existsSync97(c)) return c;
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 = join88(serviceDir, "scripts", "local-bridge-server.mjs");
38936
- if (!existsSync97(path91)) {
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 homedir47 } from "node:os";
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(homedir47(), ".olam");
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 homedir51 } from "node:os";
40511
- import { dirname as dirname56, join as join92 } from "node:path";
40512
- import { randomUUID as randomUUID2 } from "node:crypto";
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 = join92(homedir51(), ".local", "share", "claude", "breadcrumbs");
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: randomUUID2().replace(/-/g, ""),
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 join92(BREADCRUMBS_BASE, projectSlug, `${today}.jsonl`);
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 readFileSync76, statSync as statSync23 } from "node:fs";
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 = statSync23(path91);
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 = readFileSync76(path91, "utf8");
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 homedir52 } from "node:os";
40859
- import { dirname as dirname57, join as join93 } from "node:path";
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 = join93(homedir52(), ".local", "share", "olam", "flywheel-baseline.json");
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 spawnSync27, spawn as spawnAsync2 } from "node:child_process";
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 spawnSync27(
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 = spawnSync27("docker", ["inspect", "--format", "{{.State.Status}}", singleton], { encoding: "utf-8" });
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);