@cerefox/memory 1.21.0 → 1.22.1

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.
@@ -5318,7 +5318,7 @@ var init_cli_core = __esm(() => {
5318
5318
  });
5319
5319
 
5320
5320
  // src/meta.ts
5321
- var PKG_VERSION = "1.21.0";
5321
+ var PKG_VERSION = "1.22.1";
5322
5322
  var init_meta = () => {};
5323
5323
 
5324
5324
  // ../../_shared/config/paths.ts
@@ -5405,7 +5405,7 @@ function loadEnv(opts = {}) {
5405
5405
  for (const [k, v] of Object.entries(parseDotenv(content))) {
5406
5406
  if (k === "CEREFOX_CONFIG_DIR")
5407
5407
  continue;
5408
- if (env2[k] === undefined || configDirNamed) {
5408
+ if (env2[k] === undefined || configDirNamed || k === "CEREFOX_PROG_NAME") {
5409
5409
  env2[k] = v;
5410
5410
  count++;
5411
5411
  }
@@ -23699,17 +23699,28 @@ var init_db_client = __esm(() => {
23699
23699
  });
23700
23700
  });
23701
23701
 
23702
+ // src/cli/util/prog-name.ts
23703
+ function progName() {
23704
+ const name = (process.env.CEREFOX_PROG_NAME ?? "").trim();
23705
+ if (name)
23706
+ return name;
23707
+ const dir = (process.env.CEREFOX_CONFIG_DIR ?? "").trim();
23708
+ if (!dir)
23709
+ return "cerefox";
23710
+ return /^[A-Za-z0-9_\/.~+,:@%=-]+$/.test(dir) ? `CEREFOX_CONFIG_DIR=${dir} cerefox` : `CEREFOX_CONFIG_DIR='${dir.replace(/'/g, `'\\''`)}' cerefox`;
23711
+ }
23712
+
23702
23713
  // src/cli/util/client.ts
23703
23714
  function getClient() {
23704
23715
  const settings = loadSettings();
23705
23716
  if (!settings.supabaseUrl || !settings.supabaseKey) {
23706
- throw systemError("CEREFOX_SUPABASE_URL and CEREFOX_SUPABASE_KEY must be set in your .env file.", "Run `cerefox init` to create a config, or see docs/guides/setup-supabase.md.");
23717
+ throw systemError("CEREFOX_SUPABASE_URL and CEREFOX_SUPABASE_KEY must be set in your .env file.", `Run \`${progName()} init\` to create a config, or see docs/guides/setup-supabase.md.`);
23707
23718
  }
23708
23719
  try {
23709
23720
  return createClient2(settings);
23710
23721
  } catch (err) {
23711
23722
  const msg = err instanceof Error ? err.message : String(err);
23712
- throw systemError(`Failed to initialize Supabase client: ${msg}`, "Run `cerefox doctor` to verify your credentials.");
23723
+ throw systemError(`Failed to initialize Supabase client: ${msg}`, `Run \`${progName()} doctor\` to verify your credentials.`);
23713
23724
  }
23714
23725
  }
23715
23726
  var init_client = __esm(() => {
@@ -23727,8 +23738,20 @@ function auditDocLabel(docTitle, documentId, operation) {
23727
23738
  return docTitle;
23728
23739
  if (documentId)
23729
23740
  return documentId.slice(0, 8) + "…";
23741
+ if (operation === "config-change")
23742
+ return "(setting)";
23743
+ if (operation?.startsWith("project-"))
23744
+ return "(project)";
23730
23745
  return isStoreLevelAuditOp(operation) ? "(store)" : "(deleted)";
23731
23746
  }
23747
+ function storeChangeSummary(operation, description) {
23748
+ if (!isStoreLevelAuditOp(operation))
23749
+ return null;
23750
+ const d = (description ?? "").trim();
23751
+ if (!d)
23752
+ return null;
23753
+ return operation === "config-change" ? d.replace(/^config:\s*/, "") : d;
23754
+ }
23732
23755
  function metadataChangeSummary(before, after) {
23733
23756
  if (before == null && after == null)
23734
23757
  return null;
@@ -26658,6 +26681,7 @@ function apiAuth(keys = () => process.env.CEREFOX_API_KEY ?? "") {
26658
26681
  if (!guard.allow)
26659
26682
  return c.json({ detail: guard.message }, 403);
26660
26683
  }
26684
+ c.set("cerefoxAuthReason", decision.reason);
26661
26685
  return next();
26662
26686
  }
26663
26687
  return c.json({ detail: decision.message }, 401, {
@@ -26768,7 +26792,7 @@ async function isResponding(host, port, timeoutMs = 1500) {
26768
26792
  }
26769
26793
  function assertUnix() {
26770
26794
  if (process.platform === "win32") {
26771
- throw new Error("Daemon mode (`cerefox web start/stop/status`) is not supported on Windows yet. " + "Run `cerefox web` in the foreground, or set up a Windows service manually.");
26795
+ throw new Error(`Daemon mode (\`${progName()} web start/stop/status\`) is not supported on Windows yet. ` + `Run \`${progName()} web\` in the foreground, or set up a Windows service manually.`);
26772
26796
  }
26773
26797
  }
26774
26798
  async function startDaemon(opts) {
@@ -26834,7 +26858,8 @@ async function stopDaemon() {
26834
26858
  }
26835
26859
  function restartCommand(host, port) {
26836
26860
  const flags = `${host === "127.0.0.1" ? "" : ` --host ${host}`}${port === 8000 ? "" : ` --port ${port}`}`;
26837
- return `cerefox web stop && cerefox web start${flags}`;
26861
+ const p = progName();
26862
+ return `${p} web stop && ${p} web start${flags}`;
26838
26863
  }
26839
26864
  async function statusDaemon() {
26840
26865
  const info = readPidFile();
@@ -26918,7 +26943,7 @@ function startPeriodicRefresh() {
26918
26943
  if (updateCheckDisabled())
26919
26944
  return;
26920
26945
  refreshLatest();
26921
- const timer = setInterval(() => void refreshLatest(), CACHE_TTL_MS);
26946
+ const timer = setInterval(() => void refreshLatest(), REFRESH_TICK_MS);
26922
26947
  timer.unref?.();
26923
26948
  }
26924
26949
  function newerRelease(latest, installed = PKG_VERSION) {
@@ -26926,8 +26951,10 @@ function newerRelease(latest, installed = PKG_VERSION) {
26926
26951
  return null;
26927
26952
  return compareSemver(latest, installed) > 0 ? latest : null;
26928
26953
  }
26929
- function upgradeCommand() {
26930
- return isContainerised() ? "cerefox-local upgrade" : "cerefox self-update";
26954
+ function upgradeCommand(env = process.env, containerised = isContainerised()) {
26955
+ if (!containerised)
26956
+ return "cerefox self-update";
26957
+ return env.CEREFOX_PROG_NAME === "cerefox-local" ? "cerefox-local upgrade" : null;
26931
26958
  }
26932
26959
  function takeCliNotice(opts = {}) {
26933
26960
  if (updateCheckDisabled(opts.env))
@@ -26944,21 +26971,24 @@ function takeCliNotice(opts = {}) {
26944
26971
  return null;
26945
26972
  }
26946
26973
  writeCache({ ...cached, notifiedAt: now.toISOString() }, path);
26947
- return `Cerefox ${newer} is available (you have ${opts.installed ?? PKG_VERSION}). Run \`${upgradeCommand()}\`.`;
26974
+ const cmd = upgradeCommand(opts.env);
26975
+ return `Cerefox ${newer} is available (you have ${opts.installed ?? PKG_VERSION}).` + (cmd ? ` Run \`${cmd}\`.` : "");
26948
26976
  }
26949
- var LATEST_URL = "https://registry.npmjs.org/@cerefox%2Fmemory/latest", DAY_MS, CACHE_TTL_MS, NOTIFY_INTERVAL_MS, releaseNotesUrl = (version) => `https://github.com/fstamatelopoulos/cerefox/releases/tag/v${version}`;
26977
+ var LATEST_URL = "https://registry.npmjs.org/@cerefox%2Fmemory/latest", DAY_MS, HOUR_MS, CACHE_TTL_MS, REFRESH_TICK_MS, NOTIFY_INTERVAL_MS, releaseNotesUrl = (version) => `https://github.com/fstamatelopoulos/cerefox/releases/tag/v${version}`;
26950
26978
  var init_update_check = __esm(() => {
26951
26979
  init_compatibility();
26952
26980
  init_meta();
26953
26981
  init_auth();
26954
26982
  init_daemon();
26955
26983
  DAY_MS = 24 * 60 * 60 * 1000;
26956
- CACHE_TTL_MS = DAY_MS;
26984
+ HOUR_MS = 60 * 60 * 1000;
26985
+ CACHE_TTL_MS = HOUR_MS;
26986
+ REFRESH_TICK_MS = 15 * 60 * 1000;
26957
26987
  NOTIFY_INTERVAL_MS = DAY_MS;
26958
26988
  });
26959
26989
 
26960
26990
  // ../../_shared/ef-meta/index.ts
26961
- var EF_VERSION = "1.21.0", CEREFOX_VERSION = "1.21.0", EF_LAST_CHANGED = "1.19.0";
26991
+ var EF_VERSION = "1.22.1", CEREFOX_VERSION = "1.22.1", EF_LAST_CHANGED = "1.22.0";
26962
26992
  var init_ef_meta = () => {};
26963
26993
 
26964
26994
  // ../../_shared/embeddings/onnx-embedder.ts
@@ -63952,7 +63982,7 @@ async function warnIfSchemaVersionMismatch(supabase) {
63952
63982
  if (!bundled)
63953
63983
  return;
63954
63984
  if (compareSemver(deployed, bundled) < 0) {
63955
- process.stderr.write(`[cerefox-mcp] ⚠ schema version mismatch: this client bundles v${bundled} but the deployed schema is v${deployed}. Run \`cerefox server deploy\` to update it. Tools may behave unexpectedly until then.
63985
+ process.stderr.write(`[cerefox-mcp] ⚠ schema version mismatch: this client bundles v${bundled} but the deployed schema is v${deployed}. Run \`${progName()} server deploy\` to update it. Tools may behave unexpectedly until then.
63956
63986
  `);
63957
63987
  }
63958
63988
  } catch {}
@@ -66357,7 +66387,7 @@ end
66357
66387
  complete -c ${prog} -f -a '(__${fn}_complete)'
66358
66388
  `;
66359
66389
  }
66360
- function progName() {
66390
+ function progName2() {
66361
66391
  return buildProgram().name();
66362
66392
  }
66363
66393
  function fnId(prog) {
@@ -66365,7 +66395,7 @@ function fnId(prog) {
66365
66395
  }
66366
66396
  function scriptFor(shell) {
66367
66397
  const nodes = collectNodes();
66368
- const prog = progName();
66398
+ const prog = progName2();
66369
66399
  const fn = fnId(prog);
66370
66400
  switch (shell) {
66371
66401
  case "bash":
@@ -66397,7 +66427,7 @@ async function installMode(options) {
66397
66427
  throw userError(`Unsupported --shell "${shell}". Use bash, zsh, or fish.`);
66398
66428
  }
66399
66429
  const home = homedir3();
66400
- const prog = progName();
66430
+ const prog = progName2();
66401
66431
  const rcBegin = rcBeginFor(prog);
66402
66432
  const rcEnd = rcEndFor(prog);
66403
66433
  const scriptPath = join3(home, `.${prog}-completion.${shell}`);
@@ -66445,7 +66475,7 @@ async function action2(target, options) {
66445
66475
  println(scriptFor(target));
66446
66476
  if (process.stdout.isTTY) {
66447
66477
  eprintln(c.dim(`
66448
- # Tip: \`cerefox completion install\` writes this + wires your shell rc automatically.`));
66478
+ # Tip: \`${progName()} completion install\` writes this + wires your shell rc automatically.`));
66449
66479
  }
66450
66480
  }
66451
66481
  function registerCompletion(program) {
@@ -66655,7 +66685,7 @@ function action4(options) {
66655
66685
  });
66656
66686
  return;
66657
66687
  }
66658
- println(c.bold("Runtime config keys (stored in cerefox_config; read with `cerefox config get <key>`):"));
66688
+ println(c.bold(`Runtime config keys (stored in cerefox_config; read with \`${progName()} config get <key>\`):`));
66659
66689
  let group = null;
66660
66690
  for (const spec of CONFIG_CATALOG) {
66661
66691
  if (spec.group !== group) {
@@ -68052,7 +68082,7 @@ function delegatedWrite(writer, opts) {
68052
68082
  if (result.error) {
68053
68083
  const err = result.error;
68054
68084
  if (err.code === "ENOENT") {
68055
- throw new Error(`${writer.label}: \`${cmd}\` not found on PATH. ` + `Install ${writer.label} (https://docs.claude.com/en/docs/claude-code) ` + `and re-run \`cerefox configure-agent --tool ${writer.id}\`.`);
68085
+ throw new Error(`${writer.label}: \`${cmd}\` not found on PATH. ` + `Install ${writer.label} (https://docs.claude.com/en/docs/claude-code) ` + `and re-run \`${progName()} configure-agent --tool ${writer.id}\`.`);
68056
68086
  }
68057
68087
  throw new Error(`${writer.label}: failed to spawn \`${cmd}\`: ${err.message}`);
68058
68088
  }
@@ -68169,18 +68199,18 @@ async function action7(documentId, options) {
68169
68199
  } catch (e) {
68170
68200
  const message = e instanceof Error ? e.message : String(e);
68171
68201
  if (isMissingFunctionError(message, "cerefox_delete_document")) {
68172
- throw systemError(options.reason ? `This server is behind: \`--reason\` needs schema 0.12.0 or newer. ` + `Run \`cerefox server deploy\` and retry, or retry without --reason.` : `The delete did not run: the server has no matching cerefox_delete_document ` + `(mid-deploy window, or an old schema). Run \`cerefox server deploy\` and retry.`);
68202
+ throw systemError(options.reason ? `This server is behind: \`--reason\` needs schema 0.12.0 or newer. ` + `Run \`${progName()} server deploy\` and retry, or retry without --reason.` : `The delete did not run: the server has no matching cerefox_delete_document ` + `(mid-deploy window, or an old schema). Run \`${progName()} server deploy\` and retry.`);
68173
68203
  }
68174
68204
  throw e;
68175
68205
  }
68176
68206
  if (result === null) {
68177
68207
  const { data: check, error: checkError } = await client.raw.from("cerefox_documents").select("deleted_at").eq("id", documentId).maybeSingle();
68178
68208
  if (checkError) {
68179
- warn(`Delete submitted, but the follow-up verification read failed (${checkError.message}). ` + `Confirm with: cerefox document get ${documentId}`);
68209
+ warn(`Delete submitted, but the follow-up verification read failed (${checkError.message}). ` + `Confirm with: ${progName()} document get ${documentId}`);
68180
68210
  return;
68181
68211
  }
68182
68212
  if (!check?.deleted_at) {
68183
- throw systemError(`The delete did not take effect — the server has no matching ` + `cerefox_delete_document (mid-deploy window, or an old schema). ` + `Run \`cerefox server deploy\` and retry.`);
68213
+ throw systemError(`The delete did not take effect — the server has no matching ` + `cerefox_delete_document (mid-deploy window, or an old schema). ` + `Run \`${progName()} server deploy\` and retry.`);
68184
68214
  }
68185
68215
  }
68186
68216
  if (result?.already_deleted) {
@@ -68203,7 +68233,7 @@ function registerDeleteDoc(program) {
68203
68233
  init_cli_core();
68204
68234
  init__utils();
68205
68235
  init_client();
68206
- var SERVER_BEHIND = "The sweep did not run: this server has no cerefox_find_dead_links (needs schema 0.12.2). " + "Run `cerefox server deploy`, then retry.";
68236
+ var serverBehind = () => "The sweep did not run: this server has no cerefox_find_dead_links (needs schema 0.12.2). " + `Run \`${progName()} server deploy\`, then retry.`;
68207
68237
  async function action8(options) {
68208
68238
  const client = getClient();
68209
68239
  let rows;
@@ -68212,12 +68242,12 @@ async function action8(options) {
68212
68242
  } catch (e) {
68213
68243
  const message = e instanceof Error ? e.message : String(e);
68214
68244
  if (isMissingFunctionError(message, "cerefox_find_dead_links")) {
68215
- throw systemError(SERVER_BEHIND);
68245
+ throw systemError(serverBehind());
68216
68246
  }
68217
68247
  throw e;
68218
68248
  }
68219
68249
  if (rows === null)
68220
- throw systemError(SERVER_BEHIND);
68250
+ throw systemError(serverBehind());
68221
68251
  if (options.json) {
68222
68252
  printJson(rows);
68223
68253
  return;
@@ -68574,7 +68604,8 @@ async function action10(options) {
68574
68604
  ${c.red("✗")} ${ch.label}`);
68575
68605
  eprintln(c.dim(` → ${ch.remediation}`));
68576
68606
  }
68577
- eprintln("\nFix the above and re-run `cerefox server deploy` (it's idempotent).");
68607
+ eprintln(`
68608
+ Fix the above and re-run \`${progName()} server deploy\` (it's idempotent).`);
68578
68609
  process.exit(1);
68579
68610
  }
68580
68611
  println(c.green(`
@@ -68724,9 +68755,9 @@ ${r.stderr ?? ""}`);
68724
68755
  eprintln(c.dim(" published yet, and bundling fails."));
68725
68756
  eprintln(c.dim(" Your deployed functions were NOT changed — the previous version is"));
68726
68757
  eprintln(c.dim(" still serving, so nothing is down."));
68727
- eprintln(c.cyan(" → Wait a few minutes, then re-run: cerefox server deploy --functions-only"));
68758
+ eprintln(c.cyan(` → Wait a few minutes, then re-run: ${progName()} server deploy --functions-only`));
68728
68759
  } else {
68729
- eprintln(c.dim(" Re-run `cerefox server deploy --functions-only` after fixing the cause."));
68760
+ eprintln(c.dim(` Re-run \`${progName()} server deploy --functions-only\` after fixing the cause.`));
68730
68761
  }
68731
68762
  process.exit(1);
68732
68763
  }
@@ -68745,15 +68776,16 @@ ${r.stderr ?? ""}`);
68745
68776
  println(c.cyan(`
68746
68777
  ℹ The primitive Edge Functions now require the Cerefox access token.
68747
68778
  ` + ` If CEREFOX_ACCESS_TOKENS is unset they reject ALL callers (fail closed) —
68748
- ` + " GPT Actions, remote HTTP, and `cerefox doctor`. Generate it now:\n" + ` cerefox token generate
68779
+ ` + ` GPT Actions, remote HTTP, and \`${progName()} doctor\`. Generate it now:
68780
+ ` + ` ${progName()} token generate
68749
68781
  ` + ` (or manually: supabase secrets set CEREFOX_ACCESS_TOKENS=<token> --project-ref ${ref})
68750
68782
  ` + " Migration + client cutover: docs/specs/ef-auth-migration-design.md §6."));
68751
68783
  }
68752
68784
  }
68753
68785
  println(c.green(`
68754
68786
  ✓ Server deploy complete.`));
68755
- println(c.dim("Verify with: cerefox doctor"));
68756
- println(c.dim("Refresh the bundled guides: cerefox guides ingest"));
68787
+ println(c.dim(`Verify with: ${progName()} doctor`));
68788
+ println(c.dim(`Refresh the bundled guides: ${progName()} guides ingest`));
68757
68789
  }
68758
68790
  function efDeployArgs(ef, workdir, projectRef) {
68759
68791
  const args = ["--yes", "supabase", "functions", "deploy", ef, "--use-api", "--workdir", workdir];
@@ -68804,7 +68836,7 @@ async function action11(documentId, options) {
68804
68836
  if (!doc)
68805
68837
  throw notFound(`Document ${documentId} not found.`);
68806
68838
  if (doc.deleted_at) {
68807
- throw userError(`Document ${documentId} is soft-deleted — restore it first (cerefox document restore).`);
68839
+ throw userError(`Document ${documentId} is soft-deleted — restore it first (${progName()} document restore).`);
68808
68840
  }
68809
68841
  const metaTouched = sets.length > 0 || unsets.length > 0;
68810
68842
  const newTitle = hasTitle ? options.title.trim() : doc.title;
@@ -68831,7 +68863,7 @@ async function action11(documentId, options) {
68831
68863
  });
68832
68864
  if (metaErr) {
68833
68865
  if (metaErr.message?.includes("CEREFOX_BAD_METADATA")) {
68834
- throw userError(`Document ${documentId} has non-object metadata; a patch cannot repair it. ` + `Repair it first with: cerefox document set-metadata ${documentId} --replace --json '<the intended object>'`);
68866
+ throw userError(`Document ${documentId} has non-object metadata; a patch cannot repair it. ` + `Repair it first with: ${progName()} document set-metadata ${documentId} --replace --json '<the intended object>'`);
68835
68867
  }
68836
68868
  throw systemError(`Metadata update failed: ${metaErr.message}`);
68837
68869
  }
@@ -68850,7 +68882,7 @@ async function action11(documentId, options) {
68850
68882
  }
68851
68883
  println(c.green(`✓ Edited "${newTitle}" (id: ${documentId}).`));
68852
68884
  if (titleChanged) {
68853
- println(c.dim(" Title changed: FTS refreshed; semantic embeddings update on next `cerefox server reindex`."));
68885
+ println(c.dim(` Title changed: FTS refreshed; semantic embeddings update on next \`${progName()} server reindex\`.`));
68854
68886
  }
68855
68887
  }
68856
68888
  function collect(value, prev) {
@@ -68891,21 +68923,21 @@ async function action12(documentId, options) {
68891
68923
  } catch (e) {
68892
68924
  const message = e instanceof Error ? e.message : String(e);
68893
68925
  if (isMissingFunctionError(message, "cerefox_restore_document")) {
68894
- throw systemError(options.reason ? `This server is behind: \`--reason\` needs schema 0.12.0 or newer. ` + `Run \`cerefox server deploy\` and retry, or retry without --reason.` : `The restore did not run: the server has no matching cerefox_restore_document ` + `(mid-deploy window, or an old schema). Run \`cerefox server deploy\` and retry.`);
68926
+ throw systemError(options.reason ? `This server is behind: \`--reason\` needs schema 0.12.0 or newer. ` + `Run \`${progName()} server deploy\` and retry, or retry without --reason.` : `The restore did not run: the server has no matching cerefox_restore_document ` + `(mid-deploy window, or an old schema). Run \`${progName()} server deploy\` and retry.`);
68895
68927
  }
68896
68928
  throw e;
68897
68929
  }
68898
68930
  if (result === null) {
68899
68931
  const { data: check, error: checkError } = await client.raw.from("cerefox_documents").select("deleted_at").eq("id", documentId).maybeSingle();
68900
68932
  if (checkError) {
68901
- warn(`Restore submitted, but the follow-up verification read failed (${checkError.message}). ` + `Confirm with: cerefox document get ${documentId}`);
68933
+ warn(`Restore submitted, but the follow-up verification read failed (${checkError.message}). ` + `Confirm with: ${progName()} document get ${documentId}`);
68902
68934
  return;
68903
68935
  }
68904
68936
  if (!check) {
68905
68937
  throw systemError(`Document ${documentId} no longer exists — it may have been purged concurrently. Nothing was restored.`);
68906
68938
  }
68907
68939
  if (check.deleted_at) {
68908
- throw systemError(`The restore did not take effect — the server has no matching ` + `cerefox_restore_document (mid-deploy window, or an old schema). ` + `Run \`cerefox server deploy\` and retry.`);
68940
+ throw systemError(`The restore did not take effect — the server has no matching ` + `cerefox_restore_document (mid-deploy window, or an old schema). ` + `Run \`${progName()} server deploy\` and retry.`);
68909
68941
  }
68910
68942
  }
68911
68943
  if (result && result.restored === false) {
@@ -68986,15 +69018,15 @@ async function action13(documentId, options) {
68986
69018
  if (/not found/i.test(msg))
68987
69019
  throw notFound(`Document ${documentId} not found (or is deleted).`);
68988
69020
  if (msg.includes("CEREFOX_METADATA_CONFLICT")) {
68989
- throw userError(`The metadata of ${documentId} changed since you read it. Re-read it ` + `(cerefox document get ${documentId} --outline), reapply your change, and retry ` + `with the new --expected-metadata-revision.`);
69021
+ throw userError(`The metadata of ${documentId} changed since you read it. Re-read it ` + `(${progName()} document get ${documentId} --outline), reapply your change, and retry ` + `with the new --expected-metadata-revision.`);
68990
69022
  }
68991
69023
  if (msg.includes("CEREFOX_METADATA_TOKEN_REQUIRED")) {
68992
- throw userError(`--replace discards every key you do not list, so it needs --expected-metadata-revision ` + `(from cerefox document get ${documentId} --outline) or --last-write-wins.`);
69024
+ throw userError(`--replace discards every key you do not list, so it needs --expected-metadata-revision ` + `(from ${progName()} document get ${documentId} --outline) or --last-write-wins.`);
68993
69025
  }
68994
69026
  throw systemError(`Could not set metadata: ${msg}`);
68995
69027
  }
68996
69028
  if (!rows || rows.length === 0) {
68997
- throw systemError("cerefox_set_document_metadata returned no data.", "Verify the RPC is deployed: `cerefox server deploy`.");
69029
+ throw systemError("cerefox_set_document_metadata returned no data.", `Verify the RPC is deployed: \`${progName()} server deploy\`.`);
68998
69030
  }
68999
69031
  const row = rows[0];
69000
69032
  if (options.jsonOut) {
@@ -69067,7 +69099,7 @@ function openInBrowser(path) {
69067
69099
  function resolveDoc(topic) {
69068
69100
  const doc = readBundledDoc(topic);
69069
69101
  if (!doc) {
69070
- throw notFound(`No bundled guide named "${topic}".`, "Run `cerefox guides list` to see available topics.");
69102
+ throw notFound(`No bundled guide named "${topic}".`, `Run \`${progName()} guides list\` to see available topics.`);
69071
69103
  }
69072
69104
  return doc;
69073
69105
  }
@@ -69081,7 +69113,7 @@ function listAction() {
69081
69113
  println("");
69082
69114
  printTable(docs.map((d) => ({ topic: d.topic, size_kb: Math.round(d.size / 1024) + " KB" })));
69083
69115
  println("");
69084
- println(c.dim("Open with `cerefox guides open <topic>` (browser) or `cerefox guides show <topic>` (stdout)."));
69116
+ println(c.dim(`Open with \`${progName()} guides open <topic>\` (browser) or \`${progName()} guides show <topic>\` (stdout).`));
69085
69117
  }
69086
69118
  function openAction(topic) {
69087
69119
  const doc = resolveDoc(topic);
@@ -69204,8 +69236,8 @@ async function setArchived(versionId, archived, options) {
69204
69236
  println(c.green(`✓ Version ${data.version_number} (${versionId}) ${op}d.`));
69205
69237
  }
69206
69238
  function registerVersionArchive(parent) {
69207
- parent.command("archive").description("Archive a document version (protect it from version cleanup).").argument("<version-id>", "UUID of the version (from `cerefox version list`).").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").action((versionId, options) => setArchived(versionId, true, options));
69208
- parent.command("unarchive").description("Unarchive a document version (allow version cleanup again).").argument("<version-id>", "UUID of the version (from `cerefox version list`).").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").action((versionId, options) => setArchived(versionId, false, options));
69239
+ parent.command("archive").description("Archive a document version (protect it from version cleanup).").argument("<version-id>", `UUID of the version (from \`${progName()} document version list\`).`).option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").action((versionId, options) => setArchived(versionId, true, options));
69240
+ parent.command("unarchive").description("Unarchive a document version (allow version cleanup again).").argument("<version-id>", `UUID of the version (from \`${progName()} document version list\`).`).option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").action((versionId, options) => setArchived(versionId, false, options));
69209
69241
  }
69210
69242
 
69211
69243
  // ../../node_modules/.bun/ora@9.4.1/node_modules/ora/index.js
@@ -72671,11 +72703,12 @@ async function checkUpdates() {
72671
72703
  const newer = newerRelease(latest);
72672
72704
  if (!newer)
72673
72705
  return { name, status: "ok", detail: `up to date (latest release: v${latest})` };
72706
+ const cmd = upgradeCommand();
72674
72707
  return {
72675
72708
  name,
72676
72709
  status: "skipped",
72677
72710
  detail: `v${newer} is available (installed: v${PKG_VERSION})`,
72678
- hint: `Run \`${upgradeCommand()}\`. Release notes: ${releaseNotesUrl(newer)}`
72711
+ hint: `${cmd ? `Run \`${cmd}\`. ` : ""}Release notes: ${releaseNotesUrl(newer)}`
72679
72712
  };
72680
72713
  }
72681
72714
  function checkConfig() {
@@ -72687,7 +72720,7 @@ function checkConfig() {
72687
72720
  name: "config",
72688
72721
  status: "error",
72689
72722
  detail: `Could not resolve config dir: ${err instanceof Error ? err.message : String(err)}`,
72690
- hint: "Run `cerefox init` to bootstrap."
72723
+ hint: `Run \`${progName()} init\` to bootstrap.`
72691
72724
  };
72692
72725
  }
72693
72726
  if (!existsSync12(envPath)) {
@@ -72703,7 +72736,7 @@ function checkConfig() {
72703
72736
  name: "config",
72704
72737
  status: "error",
72705
72738
  detail: `No config file at ${envPath}`,
72706
- hint: "Run `cerefox init` to create one."
72739
+ hint: `Run \`${progName()} init\` to create one.`
72707
72740
  };
72708
72741
  }
72709
72742
  let modeDetail = "";
@@ -72781,7 +72814,7 @@ async function checkRetiredEnvVars() {
72781
72814
  hint: "Safe to delete those lines; nothing reads them."
72782
72815
  };
72783
72816
  }
72784
- const moves = pending.map((v) => `cerefox config set ${v.configKey} ${(process.env[v.name] ?? "").trim()}`).join(`
72817
+ const moves = pending.map((v) => `${progName()} config set ${v.configKey} ${(process.env[v.name] ?? "").trim()}`).join(`
72785
72818
  `);
72786
72819
  const prunedWasDisabled = pending.some((v) => v.configKey.startsWith("version_"));
72787
72820
  return {
@@ -72795,6 +72828,17 @@ async function checkRetiredEnvVars() {
72795
72828
  Then delete those lines from your .env — nothing reads them.`
72796
72829
  };
72797
72830
  }
72831
+ function dataApiHint(status, body, key) {
72832
+ if (status !== 401)
72833
+ return "Verify CEREFOX_SUPABASE_URL.";
72834
+ if (key.trim().startsWith("cfx_lak_")) {
72835
+ if (/PGRST30\d|JWT/.test(body)) {
72836
+ return "This Cerefox Local container is older than 1.22.0 and cannot accept an API key here. " + "Upgrade the container image to 1.22.0 or later.";
72837
+ }
72838
+ return "The server does not accept this API key. Check CEREFOX_SUPABASE_KEY against the server's key.";
72839
+ }
72840
+ return "Verify CEREFOX_SUPABASE_KEY (use the service-role / sb_secret key).";
72841
+ }
72798
72842
  async function checkSupabase() {
72799
72843
  let settings;
72800
72844
  try {
@@ -72804,7 +72848,7 @@ async function checkSupabase() {
72804
72848
  name: "supabase",
72805
72849
  status: "error",
72806
72850
  detail: `Could not load settings: ${err instanceof Error ? err.message : String(err)}`,
72807
- hint: "Run `cerefox init`."
72851
+ hint: `Run \`${progName()} init\`.`
72808
72852
  };
72809
72853
  }
72810
72854
  if (!settings.supabaseUrl || !settings.supabaseKey) {
@@ -72812,7 +72856,7 @@ async function checkSupabase() {
72812
72856
  name: "supabase",
72813
72857
  status: "error",
72814
72858
  detail: "CEREFOX_SUPABASE_URL or CEREFOX_SUPABASE_KEY is not set.",
72815
- hint: "Run `cerefox init` to bootstrap."
72859
+ hint: `Run \`${progName()} init\` to bootstrap.`
72816
72860
  };
72817
72861
  }
72818
72862
  try {
@@ -72824,11 +72868,12 @@ async function checkSupabase() {
72824
72868
  }
72825
72869
  });
72826
72870
  if (!resp.ok) {
72871
+ const body = await resp.text().catch(() => "");
72827
72872
  return {
72828
72873
  name: "supabase",
72829
72874
  status: "error",
72830
72875
  detail: `Data API returned ${resp.status} ${resp.statusText}`,
72831
- hint: resp.status === 401 ? "Verify CEREFOX_SUPABASE_KEY (use the service-role / sb_secret key)." : "Verify CEREFOX_SUPABASE_URL."
72876
+ hint: dataApiHint(resp.status, body, settings.supabaseKey)
72832
72877
  };
72833
72878
  }
72834
72879
  return {
@@ -72860,7 +72905,7 @@ async function checkOpenAI() {
72860
72905
  name: "openai",
72861
72906
  status: "warn",
72862
72907
  detail: "No OPENAI_API_KEY / CEREFOX_OPENAI_API_KEY set.",
72863
- hint: "Required for `cerefox search` (semantic mode) and ingest. Set in your .env."
72908
+ hint: `Required for \`${progName()} search\` (semantic mode) and ingest. Set in your .env.`
72864
72909
  };
72865
72910
  }
72866
72911
  try {
@@ -72991,7 +73036,7 @@ async function checkReviewWorkflow() {
72991
73036
  name,
72992
73037
  status: "warn",
72993
73038
  detail: "review_workflow_enabled is not set — treated as OFF until the schema is updated",
72994
- hint: "Run `cerefox server deploy --schema-only` (v1.13.0+) to seed it."
73039
+ hint: `Run \`${progName()} server deploy --schema-only\` (v1.13.0+) to seed it.`
72995
73040
  };
72996
73041
  }
72997
73042
  const on = raw.trim().toLowerCase() === "true";
@@ -72999,7 +73044,7 @@ async function checkReviewWorkflow() {
72999
73044
  name,
73000
73045
  status: "ok",
73001
73046
  detail: on ? "ON — agent writes land pending_review; review_status is shown everywhere" : "OFF — review_status is hidden everywhere (still recorded from author_type)",
73002
- hint: on ? undefined : "Turn it on with `cerefox config set review_workflow_enabled true`."
73047
+ hint: on ? undefined : `Turn it on with \`${progName()} config set review_workflow_enabled true\`.`
73003
73048
  };
73004
73049
  }
73005
73050
  async function checkTrashAutoPurge() {
@@ -73038,7 +73083,7 @@ async function checkTrashAutoPurge() {
73038
73083
  name,
73039
73084
  status: "ok",
73040
73085
  detail: "off — the trash is only emptied by hand",
73041
- hint: "Opt in with `cerefox config set trash_auto_purge_enabled true` (period: trash_retention_days)."
73086
+ hint: `Opt in with \`${progName()} config set trash_auto_purge_enabled true\` (period: trash_retention_days).`
73042
73087
  };
73043
73088
  }
73044
73089
  return {
@@ -73073,7 +73118,7 @@ async function checkEmbedderMismatch() {
73073
73118
  name: EMBEDDER_CHECK_NAME,
73074
73119
  status: "warn",
73075
73120
  detail: `configured "${active}", but the model is not downloaded yet; the first search or write will fetch it (~130 MB).`,
73076
- hint: "Fetch it now with `cerefox embedder-warmup` (Cerefox Local: `cerefox-local embedder-warmup`); it resumes if the connection drops."
73121
+ hint: `Fetch it now with \`${progName()} embedder-warmup\`${progName() === "cerefox" ? " (Cerefox Local: `cerefox-local embedder-warmup`)" : ""}; it resumes if the connection drops.`
73077
73122
  };
73078
73123
  }
73079
73124
  }
@@ -73087,7 +73132,7 @@ async function checkEmbedderMismatch() {
73087
73132
  name: EMBEDDER_CHECK_NAME,
73088
73133
  status: "warn",
73089
73134
  detail: `configured "${active}" but existing chunks were embedded with ${stale.map((r) => `"${r}"`).join(", ")} — semantic search across them is broken.`,
73090
- hint: "Run `cerefox server reindex` to re-embed everything with the configured embedder."
73135
+ hint: `Run \`${progName()} server reindex\` to re-embed everything with the configured embedder.`
73091
73136
  };
73092
73137
  } catch (err) {
73093
73138
  return {
@@ -73195,7 +73240,7 @@ async function checkContentFormat() {
73195
73240
  name: CONTENT_FORMAT_CHECK_NAME,
73196
73241
  status: "skipped",
73197
73242
  detail: `${legacy} of ${total} document(s) use the legacy reconstruction format (format 1).`,
73198
- hint: "Harmless — they auto-convert on next edit. To convert them all now: `cerefox server migrate-format` (re-embeds, so try `--dry-run` first). To read what chunk formats are: `cerefox guides show content-format`."
73243
+ hint: `Harmless — they auto-convert on next edit. To convert them all now: \`${progName()} server migrate-format\` (re-embeds, so try \`--dry-run\` first). To read what chunk formats are: \`${progName()} guides show content-format\`.`
73199
73244
  };
73200
73245
  }
73201
73246
  }
@@ -73228,7 +73273,7 @@ async function checkMetadataHealth() {
73228
73273
  name: METADATA_HEALTH_CHECK_NAME,
73229
73274
  status: "skipped",
73230
73275
  detail: `${probe.rows.length} document(s) hold non-object metadata: ${sample}${probe.rows.length > 3 ? ", …" : ""}.`,
73231
- hint: "Writes that would merge onto these rows are refused (#212). Repair each with `cerefox document set-metadata <id> --replace --json '<the intended object>'`."
73276
+ hint: `Writes that would merge onto these rows are refused (#212). Repair each with \`${progName()} document set-metadata <id> --replace --json '<the intended object>'\`.`
73232
73277
  };
73233
73278
  }
73234
73279
  function hasCerefoxInJsonFile(path) {
@@ -73257,7 +73302,7 @@ async function checkWebDaemon() {
73257
73302
  name: "web server",
73258
73303
  status: "skipped",
73259
73304
  detail: `no daemon running (stale pidfile for process ${status.info.pid}).`,
73260
- hint: "Clean it up: cerefox web stop"
73305
+ hint: `Clean it up: ${progName()} web stop`
73261
73306
  };
73262
73307
  }
73263
73308
  if (!status.responding) {
@@ -73307,7 +73352,7 @@ function checkMcpConfigs() {
73307
73352
  name: "mcp clients",
73308
73353
  status: isLocalBackend() ? "skipped" : "warn",
73309
73354
  detail: isLocalBackend() ? "checked from inside the container — host MCP configs are not visible here." : "No MCP client configs reference Cerefox.",
73310
- hint: isLocalBackend() ? "Configure agents on the host with `cerefox-local configure-agent`." : "Run `cerefox configure-agent --tool claude-code` (or `--tool claude-desktop`) to wire up a client."
73355
+ hint: isLocalBackend() ? "Configure agents on the host with `cerefox-local configure-agent`." : `Run \`${progName()} configure-agent --tool claude-code\` (or \`--tool claude-desktop\`) to wire up a client.`
73311
73356
  };
73312
73357
  }
73313
73358
  return {
@@ -73405,7 +73450,7 @@ async function checkEdgeFunctionsCompat() {
73405
73450
  name: "edge functions",
73406
73451
  status: "skipped",
73407
73452
  detail: "No CEREFOX_ACCESS_TOKEN set; EF version check skipped.",
73408
- hint: "Run `cerefox token generate` to enable client↔server version checks."
73453
+ hint: `Run \`${progName()} token generate\` to enable client↔server version checks.`
73409
73454
  };
73410
73455
  }
73411
73456
  let compat;
@@ -73557,11 +73602,11 @@ async function action17(options) {
73557
73602
  const needsEf = stale("edge functions");
73558
73603
  let remediation = null;
73559
73604
  if (needsSchema && needsEf) {
73560
- remediation = "This release needs a server update (schema + RPCs + Edge Functions): cerefox server deploy";
73605
+ remediation = `This release needs a server update (schema + RPCs + Edge Functions): ${progName()} server deploy`;
73561
73606
  } else if (needsSchema) {
73562
- remediation = "This release needs a schema + RPC update: cerefox server deploy --schema-only";
73607
+ remediation = `This release needs a schema + RPC update: ${progName()} server deploy --schema-only`;
73563
73608
  } else if (needsEf) {
73564
- remediation = "This release needs an Edge Function update: cerefox server deploy --functions-only";
73609
+ remediation = `This release needs an Edge Function update: ${progName()} server deploy --functions-only`;
73565
73610
  }
73566
73611
  if (remediation) {
73567
73612
  println(cErr.yellow("→ " + remediation));
@@ -73649,7 +73694,7 @@ async function action18(options) {
73649
73694
  doc: auditDocLabel(row.doc_title, row.document_id, row.operation).slice(0, 40),
73650
73695
  author: (row.author ?? "") + (row.author_type ? `(${row.author_type})` : ""),
73651
73696
  size_delta: row.size_before !== null && row.size_after !== null ? `${row.size_before} → ${row.size_after}` : "",
73652
- change: (metadataChangeSummary(row.metadata_before, row.metadata_after) ?? "").slice(0, 60)
73697
+ change: (metadataChangeSummary(row.metadata_before, row.metadata_after) ?? storeChangeSummary(row.operation, row.description) ?? "").slice(0, 60)
73653
73698
  })));
73654
73699
  }
73655
73700
  function registerGetAuditLog(program) {
@@ -74674,7 +74719,7 @@ async function readContent(path, paste) {
74674
74719
  return { content, titleFromPath: undefined };
74675
74720
  }
74676
74721
  if (!path) {
74677
- throw userError("Provide a file path or use --paste.", "Example: cerefox document ingest notes.md --title 'My Note'");
74722
+ throw userError("Provide a file path or use --paste.", `Example: ${progName()} document ingest notes.md --title 'My Note'`);
74678
74723
  }
74679
74724
  let content;
74680
74725
  try {
@@ -74716,7 +74761,7 @@ async function action20(path, options) {
74716
74761
  }
74717
74762
  const settings = loadSettings();
74718
74763
  if (!settings.supabaseUrl || !settings.supabaseKey) {
74719
- throw userError("Supabase credentials not configured — run `cerefox init` first.");
74764
+ throw userError(`Supabase credentials not configured — run \`${progName()} init\` first.`);
74720
74765
  }
74721
74766
  if (!settings.openaiApiKey && resolveEmbedderKind() !== "local") {
74722
74767
  throw userError("OPENAI_API_KEY not set — required for embeddings during ingest.");
@@ -74828,7 +74873,7 @@ async function runTool(toolName, args) {
74828
74873
  }
74829
74874
  }
74830
74875
  function registerDocumentInsert(program) {
74831
- program.command("insert <document-id>").description("Add text to a document without resending it (purely additive)").requiredOption("-t, --text <text>", "Markdown to insert. Use '-' for stdin or '@path' for a file.").option("-p, --position <position>", "end_of_document | end_of_section | after_heading | before_heading", "end_of_document").option("-a, --anchor-heading <heading>", "Heading line, or a ' > ' path. Required unless end_of_document.").option("--section-part <part>", "own_body | subtree — required when the target section has child sections").requiredOption("-e, --expected-content-hash <hash>", "content_hash you are basing this on (cerefox document get --outline shows it)").addOption(authorOption("write", { short: false })).addOption(requestorAliasOption()).option("--author-type <type>", "user (default for the CLI) or agent, when scripting on an agent's behalf", "user").action(async (documentId, options) => {
74876
+ program.command("insert <document-id>").description("Add text to a document without resending it (purely additive)").requiredOption("-t, --text <text>", "Markdown to insert. Use '-' for stdin or '@path' for a file.").option("-p, --position <position>", "end_of_document | end_of_section | after_heading | before_heading", "end_of_document").option("-a, --anchor-heading <heading>", "Heading line, or a ' > ' path. Required unless end_of_document.").option("--section-part <part>", "own_body | subtree — required when the target section has child sections").requiredOption("-e, --expected-content-hash <hash>", `content_hash you are basing this on (${progName()} document get --outline shows it)`).addOption(authorOption("write", { short: false })).addOption(requestorAliasOption()).option("--author-type <type>", "user (default for the CLI) or agent, when scripting on an agent's behalf", "user").action(async (documentId, options) => {
74832
74877
  await runTool("cerefox_insert", {
74833
74878
  document_id: documentId,
74834
74879
  text: resolveText(options.text, "--text"),
@@ -74909,7 +74954,7 @@ async function action21(dir, options) {
74909
74954
  const metadata = parseJsonObjectArg(options.metadata, "--metadata");
74910
74955
  const settings = loadSettings();
74911
74956
  if (!settings.supabaseUrl || !settings.supabaseKey) {
74912
- throw userError("Supabase credentials not configured — run `cerefox init` first.");
74957
+ throw userError(`Supabase credentials not configured — run \`${progName()} init\` first.`);
74913
74958
  }
74914
74959
  if (!settings.openaiApiKey && resolveEmbedderKind() !== "local") {
74915
74960
  throw userError("OPENAI_API_KEY not set — required for embeddings during ingest.");
@@ -75039,7 +75084,7 @@ function answersFromEnvFile(path) {
75039
75084
  const required = ["CEREFOX_SUPABASE_URL", "CEREFOX_SUPABASE_KEY", "OPENAI_API_KEY"];
75040
75085
  for (const key of required) {
75041
75086
  if (!parsed[key] || parsed[key].trim() === "") {
75042
- throw userError(`Existing .env at ${path} is missing required key "${key}".`, `Fix it manually or run \`cerefox init --force\` to start fresh.`);
75087
+ throw userError(`Existing .env at ${path} is missing required key "${key}".`, `Fix it manually or run \`${progName()} init --force\` to start fresh.`);
75043
75088
  }
75044
75089
  }
75045
75090
  return {
@@ -75084,7 +75129,8 @@ async function promptForAnswers() {
75084
75129
  });
75085
75130
  println("");
75086
75131
  println(c.cyan("▶ Step 4/5 — Direct Postgres connection (optional for npm-installed users)"));
75087
- println(c.dim(" Only needed for `cerefox server deploy` (schema deploy + migrations).\n" + ` You can skip this and set CEREFOX_DATABASE_URL later — press Enter.
75132
+ println(c.dim(` Only needed for \`${progName()} server deploy\` (schema deploy + migrations).
75133
+ ` + ` You can skip this and set CEREFOX_DATABASE_URL later — press Enter.
75088
75134
  ` + " Format: postgresql://postgres.<project-ref>:<pw>@…:5432/postgres?sslmode=require"));
75089
75135
  const databaseUrl = await ask({
75090
75136
  type: "text",
@@ -75229,7 +75275,7 @@ async function maybeOfferServerDeploy() {
75229
75275
  if (yes)
75230
75276
  launchDeployServer();
75231
75277
  else
75232
- println(c.dim(" Skipped. Run `cerefox server deploy` later (or `cerefox doctor` to recheck)."));
75278
+ println(c.dim(` Skipped. Run \`${progName()} server deploy\` later (or \`${progName()} doctor\` to recheck).`));
75233
75279
  println("");
75234
75280
  return;
75235
75281
  }
@@ -75240,7 +75286,7 @@ async function maybeOfferServerDeploy() {
75240
75286
  if (yes)
75241
75287
  launchDeployServer();
75242
75288
  else
75243
- println(c.dim(" Skipped. Run `cerefox server deploy` when ready."));
75289
+ println(c.dim(` Skipped. Run \`${progName()} server deploy\` when ready.`));
75244
75290
  println("");
75245
75291
  return;
75246
75292
  }
@@ -75259,7 +75305,7 @@ async function postWriteLifecycle(envPath, options) {
75259
75305
  await Promise.resolve().then(() => init_sync_self_docs());
75260
75306
  await runSyncSelfDocs({});
75261
75307
  } catch (err) {
75262
- warn(`Self-doc ingest failed: ${err instanceof Error ? err.message : String(err)}. Run \`cerefox guides ingest\` manually after init.`);
75308
+ warn(`Self-doc ingest failed: ${err instanceof Error ? err.message : String(err)}. Run \`${progName()} guides ingest\` manually after init.`);
75263
75309
  }
75264
75310
  println("");
75265
75311
  }
@@ -75283,9 +75329,9 @@ async function postWriteLifecycle(envPath, options) {
75283
75329
  }
75284
75330
  println("");
75285
75331
  println(c.green("Done. Try:"));
75286
- println(c.dim(" cerefox doctor # verify everything"));
75287
- println(c.dim(' cerefox search "…" # search the KB'));
75288
- println(c.dim(" cerefox document ingest <file> # add a doc"));
75332
+ println(c.dim(` ${progName()} doctor # verify everything`));
75333
+ println(c.dim(` ${progName()} search "…" # search the KB`));
75334
+ println(c.dim(` ${progName()} document ingest <file> # add a doc`));
75289
75335
  println("");
75290
75336
  println(c.dim(` Config in effect: ${envPath}`));
75291
75337
  }
@@ -75386,7 +75432,7 @@ async function action23(options) {
75386
75432
  println("");
75387
75433
  println(c.green(`✓ Using existing config at ${cwdEnv}`));
75388
75434
  println(c.dim(` TS reads it via the legacy dev-mode fallback (~/.cerefox/.env not present).`));
75389
- println(c.dim(` Run \`cerefox init\` again later to migrate to the new home.`));
75435
+ println(c.dim(` Run \`${progName()} init\` again later to migrate to the new home.`));
75390
75436
  println("");
75391
75437
  await postWriteLifecycle(cwdEnv, options);
75392
75438
  return;
@@ -75427,7 +75473,7 @@ async function action24(options) {
75427
75473
  throw systemError(`Project lookup failed: ${projectError.message}`);
75428
75474
  }
75429
75475
  if (!project) {
75430
- throw userError(`Project "${options.project}" not found.`, "Run `cerefox project list` to see available names.");
75476
+ throw userError(`Project "${options.project}" not found.`, `Run \`${progName()} project list\` to see available names.`);
75431
75477
  }
75432
75478
  projectId = project.id;
75433
75479
  }
@@ -75743,7 +75789,7 @@ function warnLargeBulkWrite(opts) {
75743
75789
  async function action29(options) {
75744
75790
  const settings = loadSettings();
75745
75791
  if (!settings.supabaseUrl || !settings.supabaseKey) {
75746
- throw userError("Supabase credentials not configured — run `cerefox init` first.");
75792
+ throw userError(`Supabase credentials not configured — run \`${progName()} init\` first.`);
75747
75793
  }
75748
75794
  if (!settings.openaiApiKey && resolveEmbedderKind() !== "local") {
75749
75795
  throw userError("OPENAI_API_KEY not set — required for embeddings.");
@@ -76014,7 +76060,7 @@ async function action31(target, options) {
76014
76060
  }
76015
76061
  const trashedInFile = payload.documents.filter((d) => d.deleted_at != null).length;
76016
76062
  if (trashedInFile > 0) {
76017
- println(c.dim(` trashed documents in file: ${trashedInFile} — restored as trash ` + "(still deleted; recover with `cerefox document restore`)"));
76063
+ println(c.dim(` trashed documents in file: ${trashedInFile} — restored as trash ` + `(still deleted; recover with \`${progName()} document restore\`)`));
76018
76064
  }
76019
76065
  println("");
76020
76066
  const client = getClient();
@@ -76133,7 +76179,7 @@ async function action31(target, options) {
76133
76179
  }
76134
76180
  }
76135
76181
  function registerRestore(program) {
76136
- program.command("restore").description("Restore a JSON-snapshot backup into the knowledge base.").argument("<snapshot>", "Backup file (or directory; most recent is picked) produced by `cerefox backup`.").option("--dry-run", "Print what would be restored without writing.").option("-p, --project-name <name>", "Reserved for future use; currently ignored. Project memberships are restored from the backup itself (format 2+).").action(action31);
76182
+ program.command("restore").description("Restore a JSON-snapshot backup into the knowledge base.").argument("<snapshot>", `Backup file (or directory; most recent is picked) produced by \`${progName()} backup\`.`).option("--dry-run", "Print what would be restored without writing.").option("-p, --project-name <name>", "Reserved for future use; currently ignored. Project memberships are restored from the backup itself (format 2+).").action(action31);
76137
76183
  }
76138
76184
 
76139
76185
  // src/cli/commands/search.ts
@@ -76148,13 +76194,13 @@ async function embedQuery(query) {
76148
76194
  const settings = loadSettings();
76149
76195
  const apiKey = settings.openaiApiKey;
76150
76196
  if (!apiKey && resolveEmbedderKind() !== "local") {
76151
- throw userError("OPENAI_API_KEY (or CEREFOX_OPENAI_API_KEY) is required for search.", "Set the key in your .env, or run `cerefox init` to bootstrap.");
76197
+ throw userError("OPENAI_API_KEY (or CEREFOX_OPENAI_API_KEY) is required for search.", `Set the key in your .env, or run \`${progName()} init\` to bootstrap.`);
76152
76198
  }
76153
76199
  try {
76154
76200
  return await getEmbedding(query, apiKey);
76155
76201
  } catch (err) {
76156
76202
  const msg = err instanceof Error ? err.message : String(err);
76157
- throw systemError(`Failed to embed query: ${msg}`, "Run `cerefox doctor` to verify the OpenAI API path.");
76203
+ throw systemError(`Failed to embed query: ${msg}`, `Run \`${progName()} doctor\` to verify the OpenAI API path.`);
76158
76204
  }
76159
76205
  }
76160
76206
 
@@ -76326,7 +76372,7 @@ async function action32(query, options) {
76326
76372
  }
76327
76373
  }
76328
76374
  function registerSearch(program) {
76329
- program.command("search").description("Search the knowledge base (hybrid FTS + semantic).").argument("<query>", "Natural-language search query.").option("-c, --match-count <n>", "Maximum number of documents to return.", "5").option("-p, --project-name <name>", "Filter results to a specific project.").option("-f, --metadata-filter <json>", "JSON containment filter; only docs whose metadata contains ALL pairs are returned.").option("--mode <mode>", "Search mode: docs (default), hybrid, fts.", "docs").option("--alpha <float>", "Semantic weight 0..1 (default: CEREFOX_SEARCH_ALPHA; else 0.7).").option("--min-score <float>", "Minimum cosine similarity threshold (default: the store's min_search_score; else 0.5, or 0.6 on a local-embedder store).").option("--min-term-coverage <float>", "OR-fallback keyword matches must cover at least this fraction of the query's meaningful terms to count as confident hits (default: the store's min_term_coverage; else 0.66; needs schema ≥ 0.9.1).").option("--max-bytes <n>", "Response size budget in bytes (default: CEREFOX_MAX_RESPONSE_BYTES or 200000).").addOption(authorOption("read")).addOption(requestorAliasOption()).option("--json", "Emit machine-readable JSON instead of the default text.").option("--only-metadata", "List matching docs (id, score, chunks, chars, partial/full) WITHOUT their content — like the web UI's collapsed result list. Grab a [id:…] then `cerefox document get <id>`.").action(action32);
76375
+ program.command("search").description("Search the knowledge base (hybrid FTS + semantic).").argument("<query>", "Natural-language search query.").option("-c, --match-count <n>", "Maximum number of documents to return.", "5").option("-p, --project-name <name>", "Filter results to a specific project.").option("-f, --metadata-filter <json>", "JSON containment filter; only docs whose metadata contains ALL pairs are returned.").option("--mode <mode>", "Search mode: docs (default), hybrid, fts.", "docs").option("--alpha <float>", "Semantic weight 0..1 (default: CEREFOX_SEARCH_ALPHA; else 0.7).").option("--min-score <float>", "Minimum cosine similarity threshold (default: the store's min_search_score; else 0.5, or 0.6 on a local-embedder store).").option("--min-term-coverage <float>", "OR-fallback keyword matches must cover at least this fraction of the query's meaningful terms to count as confident hits (default: the store's min_term_coverage; else 0.66; needs schema ≥ 0.9.1).").option("--max-bytes <n>", "Response size budget in bytes (default: CEREFOX_MAX_RESPONSE_BYTES or 200000).").addOption(authorOption("read")).addOption(requestorAliasOption()).option("--json", "Emit machine-readable JSON instead of the default text.").option("--only-metadata", `List matching docs (id, score, chunks, chars, partial/full) WITHOUT their content — like the web UI's collapsed result list. Grab a [id:…] then \`${progName()} document get <id>\`.`).action(action32);
76330
76376
  }
76331
76377
 
76332
76378
  // src/cli/commands/self-update.ts
@@ -76391,7 +76437,7 @@ async function action33(options) {
76391
76437
  if (options.check) {
76392
76438
  if (newerRelease(target)) {
76393
76439
  println(c.yellow(`Update available: ${PKG_VERSION} → ${target}`));
76394
- println(c.dim("Run `cerefox self-update` to upgrade."));
76440
+ println(c.dim(`Run \`${progName()} self-update\` to upgrade.`));
76395
76441
  }
76396
76442
  return;
76397
76443
  }
@@ -76422,12 +76468,12 @@ async function action33(options) {
76422
76468
  }
76423
76469
  println("");
76424
76470
  println("Next steps:");
76425
- println(" 1. " + c.bold("cerefox server deploy") + " apply this release's schema/RPC/EF updates");
76426
- println(" 2. " + c.bold("cerefox guides ingest") + " re-sync the bundled guides into your KB");
76471
+ println(" 1. " + c.bold(`${progName()} server deploy`) + " apply this release's schema/RPC/EF updates");
76472
+ println(" 2. " + c.bold(`${progName()} guides ingest`) + " re-sync the bundled guides into your KB");
76427
76473
  println(c.dim(" (order matters: the new client may require the new schema — run the deploy first)"));
76428
76474
  }
76429
76475
  function registerSelfUpdate(program) {
76430
- const desc = "Upgrade Cerefox in place. Alias: `cerefox upgrade`.";
76476
+ const desc = `Upgrade Cerefox in place. Alias: \`${progName()} upgrade\`.`;
76431
76477
  const declaration = (cmd) => cmd.description(desc).option("--check", "Print current vs latest; do nothing.").option("--yes", "Non-interactive (skip confirmation).").option("--version <version>", "Pin a specific version (e.g. 0.5.1 or 0.6.0-rc.1).").action(action33);
76432
76478
  declaration(program.command("self-update"));
76433
76479
  declaration(program.command("upgrade"));
@@ -76468,7 +76514,7 @@ async function action34(options) {
76468
76514
  }
76469
76515
  }
76470
76516
  function registerStatus(program) {
76471
- program.command("status").description("Quick sanity check (fast subset of `cerefox doctor`).").option("--json", "Emit machine-readable JSON.").action(action34);
76517
+ program.command("status").description(`Quick sanity check (fast subset of \`${progName()} doctor\`).`).option("--json", "Emit machine-readable JSON.").action(action34);
76472
76518
  }
76473
76519
 
76474
76520
  // src/cli/commands/api-key.ts
@@ -76581,7 +76627,7 @@ function generateAction(opts) {
76581
76627
  const envPath = resolveEnvFile();
76582
76628
  const existing = readEnvVar(envPath, ENV_NAME);
76583
76629
  if (existing) {
76584
- throw userError(`${ENV_NAME} is already set in ${envPath} (${mask(existing)}).`, "Use `cerefox api-key show` to see it, or `cerefox api-key rotate` to replace it. " + "Refusing to overwrite silently: any client already configured with the old key " + "would start getting 401s with no indication why.");
76630
+ throw userError(`${ENV_NAME} is already set in ${envPath} (${mask(existing)}).`, `Use \`${progName()} api-key show\` to see it, or \`${progName()} api-key rotate\` to replace it. ` + "Refusing to overwrite silently: any client already configured with the old key " + "would start getting 401s with no indication why.");
76585
76631
  }
76586
76632
  println(c.bold("Minting a local API key"));
76587
76633
  writeKey(mint(), opts, "write");
@@ -76591,13 +76637,13 @@ function rotateAction(opts) {
76591
76637
  const envPath = resolveEnvFile();
76592
76638
  const existing = readEnvVar(envPath, ENV_NAME);
76593
76639
  if (!existing) {
76594
- throw userError(`No ${ENV_NAME} in ${envPath} — nothing to rotate.`, "Run `cerefox api-key generate` first.");
76640
+ throw userError(`No ${ENV_NAME} in ${envPath} — nothing to rotate.`, `Run \`${progName()} api-key generate\` first.`);
76595
76641
  }
76596
76642
  println(c.bold("Rotating the local API key"));
76597
76643
  println(c.dim(` replacing ${mask(existing)}`));
76598
76644
  writeKey(mint(), opts, "replace");
76599
76645
  println(c.yellow(` The previous key stops working as soon as the server restarts.
76600
- ` + " Update every remote client, then: cerefox web restart"));
76646
+ ` + ` Update every remote client, then: ${progName()} web restart`));
76601
76647
  }
76602
76648
  function showAction2() {
76603
76649
  const envPath = resolveEnvFile();
@@ -76607,7 +76653,7 @@ function showAction2() {
76607
76653
  println(c.dim(` none set in ${envPath}`));
76608
76654
  println(c.dim(` The server is not gated: callers from any interface it is bound to can
76609
76655
  ` + ` reach it without a credential. That is fine while it binds 127.0.0.1.
76610
- ` + " Mint one with: cerefox api-key generate"));
76656
+ ` + ` Mint one with: ${progName()} api-key generate`));
76611
76657
  containerHint();
76612
76658
  return;
76613
76659
  }
@@ -76688,7 +76734,7 @@ function printTokenOnce(token) {
76688
76734
  println(c.dim(" • Custom GPT → Configure → Actions → Authentication → API Key (Bearer)"));
76689
76735
  println(c.dim(" • Remote HTTP MCP → the Authorization: Bearer header"));
76690
76736
  println(c.dim(" If the GPT Actions schema changed this release, re-paste it too"));
76691
- println(c.dim(" (see docs/guides/connect-agents.md). Lose the token → `cerefox token rotate`."));
76737
+ println(c.dim(` (see docs/guides/connect-agents.md). Lose the token → \`${progName()} token rotate\`.`));
76692
76738
  }
76693
76739
  function generateAction2(opts) {
76694
76740
  const projectRef = opts.projectRef ?? parseProjectRef2(loadSettings().supabaseUrl);
@@ -76705,7 +76751,7 @@ function rotateAction2(opts) {
76705
76751
  const current = readEnvVar(envPath, LOCAL_NAME);
76706
76752
  if (opts.finalize) {
76707
76753
  if (!current) {
76708
- throw userError(`No ${LOCAL_NAME} in ${envPath} to finalize to.`, "Run `cerefox token generate` or `cerefox token rotate` first.");
76754
+ throw userError(`No ${LOCAL_NAME} in ${envPath} to finalize to.`, `Run \`${progName()} token generate\` or \`${progName()} token rotate\` first.`);
76709
76755
  }
76710
76756
  println(c.bold("Finalizing rotation (dropping the previous token)…"));
76711
76757
  setSecret(current, projectRef, opts.dryRun);
@@ -76722,14 +76768,15 @@ function rotateAction2(opts) {
76722
76768
  printTokenOnce(token);
76723
76769
  println("");
76724
76770
  println(c.yellow(` Both the new and previous tokens are accepted right now. Update every
76725
- ` + " client to the new token, then run `cerefox token rotate --finalize`\n" + " to stop accepting the old one."));
76771
+ ` + ` client to the new token, then run \`${progName()} token rotate --finalize\`
76772
+ ` + " to stop accepting the old one."));
76726
76773
  }
76727
76774
  }
76728
76775
  function listAction2() {
76729
76776
  const envPath = resolveEnvFile();
76730
76777
  const local = readEnvVar(envPath, LOCAL_NAME);
76731
76778
  println(c.bold("Cerefox access token"));
76732
- println(local ? ` local (${LOCAL_NAME} in ${envPath}): ${c.green(mask2(local))}` : c.dim(` no ${LOCAL_NAME} in ${envPath} — run \`cerefox token generate\``));
76779
+ println(local ? ` local (${LOCAL_NAME} in ${envPath}): ${c.green(mask2(local))}` : c.dim(` no ${LOCAL_NAME} in ${envPath} — run \`${progName()} token generate\``));
76733
76780
  println(c.dim(` The server-side accepted set (${SECRET_NAME}) is write-only; list names/digests
76734
76781
  ` + " with: npx supabase secrets list"));
76735
76782
  }
@@ -81888,6 +81935,7 @@ function registerMetaRoutes(app, ctx) {
81888
81935
  ...VERSION_INFO,
81889
81936
  env_label: label.length > 0 ? label : null,
81890
81937
  latest,
81938
+ update_available: newerRelease(latest) !== null,
81891
81939
  update_command: newerRelease(latest) ? upgradeCommand() : null
81892
81940
  });
81893
81941
  });
@@ -81964,6 +82012,14 @@ var STRIP_RESPONSE_HEADERS = [
81964
82012
  "proxy-authenticate",
81965
82013
  "proxy-authorization"
81966
82014
  ];
82015
+ function upstreamCredentials(headers, reason, internalJwt) {
82016
+ const jwt = internalJwt.trim();
82017
+ if (reason !== "valid_key" || !jwt)
82018
+ return false;
82019
+ headers.set("authorization", `Bearer ${jwt}`);
82020
+ headers.set("apikey", jwt);
82021
+ return true;
82022
+ }
81967
82023
  function registerPostgrestProxy(app) {
81968
82024
  const upstream = (process.env.CEREFOX_POSTGREST_UPSTREAM ?? "").trim().replace(/\/+$/, "");
81969
82025
  if (!upstream)
@@ -81975,6 +82031,7 @@ function registerPostgrestProxy(app) {
81975
82031
  const headers = new Headers(c.req.raw.headers);
81976
82032
  headers.delete("host");
81977
82033
  headers.delete("accept-encoding");
82034
+ upstreamCredentials(headers, c.get("cerefoxAuthReason"), process.env.CEREFOX_SUPABASE_KEY ?? "");
81978
82035
  const method = c.req.method;
81979
82036
  const init = { method, headers };
81980
82037
  if (method !== "GET" && method !== "HEAD") {
@@ -82342,7 +82399,7 @@ async function assertServerCompatible() {
82342
82399
  ` + parts.join(`
82343
82400
  `) + `
82344
82401
 
82345
- Redeploy your server: cerefox server deploy
82402
+ Redeploy your server: ${progName()} server deploy
82346
82403
  ` + `(or downgrade the client to match the deployed server).`);
82347
82404
  }
82348
82405
  async function buildWebServer(options = {}) {
@@ -82357,7 +82414,7 @@ async function buildWebServer(options = {}) {
82357
82414
  ⚠ Binding ${host} with NO API key configured.
82358
82415
  ` + ` Every read, write, delete and purge on this server is reachable by
82359
82416
  ` + ` anything that can connect to port ${port}, with no credential.
82360
- ` + ` Mint one: cerefox api-key generate
82417
+ ` + ` Mint one: ${progName()} api-key generate
82361
82418
  `);
82362
82419
  }
82363
82420
  const app = buildApp();
@@ -82439,7 +82496,7 @@ function registerWeb(program) {
82439
82496
  break;
82440
82497
  case "port-conflict":
82441
82498
  eprintln(`A Cerefox web daemon is already running on :${outcome.info.port} (pid ${outcome.info.pid}).
82442
- ` + `Stop it first (\`cerefox web stop\`) or start on its port.`);
82499
+ ` + `Stop it first (\`${progName()} web stop\`) or start on its port.`);
82443
82500
  process.exit(1);
82444
82501
  break;
82445
82502
  case "started":
@@ -82447,7 +82504,7 @@ function registerWeb(program) {
82447
82504
  info(`Cerefox web started (pid ${outcome.pid}) on http://${rawOpts.host}:${port}/`);
82448
82505
  println(` Web UI: http://${rawOpts.host}:${port}/app/`);
82449
82506
  println(c.dim(` Logs: ${daemonPaths.logFile}`));
82450
- println(c.dim(` Stop: cerefox web stop`));
82507
+ println(c.dim(` Stop: ${progName()} web stop`));
82451
82508
  } else {
82452
82509
  const refusal = readStartupRefusal();
82453
82510
  if (refusal) {
@@ -82489,7 +82546,7 @@ Full log: ${daemonPaths.logFile}`);
82489
82546
  break;
82490
82547
  case "stale":
82491
82548
  println(c.yellow(`Cerefox web: stale pidfile — process ${status.info.pid} is not running.`));
82492
- println(c.dim(` Clean up: cerefox web stop (removes ${daemonPaths.pidFile})`));
82549
+ println(c.dim(` Clean up: ${progName()} web stop (removes ${daemonPaths.pidFile})`));
82493
82550
  break;
82494
82551
  case "running":
82495
82552
  if (status.responding) {
@@ -82541,16 +82598,16 @@ var RENAMED_VERBS = [
82541
82598
  function registerRenameHusks(program) {
82542
82599
  for (const [oldName, newForm] of RENAMED_VERBS) {
82543
82600
  program.command(oldName, { hidden: true }).allowUnknownOption(true).allowExcessArguments(true).argument("[args...]", "(renamed)").action(() => {
82544
- eprintln(c.yellow(`✗ \`cerefox ${oldName}\` was renamed.`));
82545
- eprintln(` Use \`cerefox ${newForm}\` instead (run \`cerefox ${newForm.split(" ")[0]} --help\`).`);
82601
+ eprintln(c.yellow(`✗ \`${progName()} ${oldName}\` was renamed.`));
82602
+ eprintln(` Use \`${progName()} ${newForm}\` instead (run \`${progName()} ${newForm.split(" ")[0]} --help\`).`);
82546
82603
  process.exit(1);
82547
82604
  });
82548
82605
  }
82549
82606
  }
82550
82607
  function buildProgram() {
82551
- const progName = process.env.CEREFOX_PROG_NAME || "cerefox";
82552
- const program = new Command(progName).description("Cerefox — user-owned shared memory for AI agents.").version(PKG_VERSION, "-v, --version", `Print the ${progName} version and exit.`).addOption(new Option("--json", "Emit machine-readable JSON on stdout instead of the default human text. " + "Available on read commands; ignored on commands without a JSON shape.").hideHelp()).showHelpAfterError(`(run \`${progName} --help\` for usage)`).enablePositionalOptions().addHelpText("after", `
82553
- Resource groups (run \`${progName} <group> --help\`):
82608
+ const progName2 = process.env.CEREFOX_PROG_NAME || "cerefox";
82609
+ const program = new Command(progName2).description("Cerefox — user-owned shared memory for AI agents.").version(PKG_VERSION, "-v, --version", `Print the ${progName2} version and exit.`).addOption(new Option("--json", "Emit machine-readable JSON on stdout instead of the default human text. " + "Available on read commands; ignored on commands without a JSON shape.").hideHelp()).showHelpAfterError(`(run \`${progName2} --help\` for usage)`).enablePositionalOptions().addHelpText("after", `
82610
+ Resource groups (run \`${progName2} <group> --help\`):
82554
82611
  ` + ` document get · list · edit · delete · restore · ingest · ingest-dir · version {list·archive·unarchive}
82555
82612
  ` + ` project list · create · edit · delete
82556
82613
  ` + ` metadata keys · search
@@ -82573,8 +82630,8 @@ Exit codes:
82573
82630
  ` + ` 1 user error 3 not found (document / version / project)
82574
82631
  ` + `
82575
82632
  Learn more:
82576
- ` + ` ${progName} guides list # bundled docs (offline)
82577
- ` + ` ${progName} doctor # diagnose your install
82633
+ ` + ` ${progName2} guides list # bundled docs (offline)
82634
+ ` + ` ${progName2} doctor # diagnose your install
82578
82635
  ` + ` https://github.com/fstamatelopoulos/cerefox
82579
82636
  `);
82580
82637
  registerSearch(program);
@@ -82625,8 +82682,8 @@ Learn more:
82625
82682
  moveInto(config, registerConfigGet, "get");
82626
82683
  moveInto(config, registerConfigSet, "set");
82627
82684
  const backup = program.command("backup").description("Backup + restore the knowledge base: create, restore.").action(() => {
82628
- eprintln(c.yellow("`cerefox backup` needs a subcommand."));
82629
- eprintln(" Use `cerefox backup create` or `cerefox backup restore`.");
82685
+ eprintln(c.yellow(`\`${progName()} backup\` needs a subcommand.`));
82686
+ eprintln(` Use \`${progName()} backup create\` or \`${progName()} backup restore\`.`);
82630
82687
  process.exit(1);
82631
82688
  });
82632
82689
  moveInto(backup, registerBackup, "create");
@@ -82663,22 +82720,22 @@ async function bareEntryPoint() {
82663
82720
  if (!configExists) {
82664
82721
  println(c.yellow("⚠ No config detected."));
82665
82722
  println("Next step:");
82666
- println(" " + c.bold("cerefox init") + " # interactive first-run setup (~2 min)");
82723
+ println(" " + c.bold(`${progName()} init`) + " # interactive first-run setup (~2 min)");
82667
82724
  println("");
82668
82725
  println(c.dim("Once configured, try:"));
82669
- println(c.dim(" cerefox doctor # verify your install"));
82670
- println(c.dim(' cerefox search "…" # search the KB'));
82671
- println(c.dim(" cerefox document ingest <file> # add a doc"));
82726
+ println(c.dim(` ${progName()} doctor # verify your install`));
82727
+ println(c.dim(` ${progName()} search "…" # search the KB`));
82728
+ println(c.dim(` ${progName()} document ingest <file> # add a doc`));
82672
82729
  } else {
82673
82730
  println(c.green("✓ Config detected. You're good to go."));
82674
82731
  println("");
82675
82732
  println("Common commands:");
82676
- println(c.dim(" cerefox doctor # diagnose your install"));
82677
- println(c.dim(' cerefox search "…" # search the KB'));
82678
- println(c.dim(" cerefox document ingest <file> # add a doc"));
82679
- println(c.dim(" cerefox configure-agent # wire up an MCP client"));
82733
+ println(c.dim(` ${progName()} doctor # diagnose your install`));
82734
+ println(c.dim(` ${progName()} search "…" # search the KB`));
82735
+ println(c.dim(` ${progName()} document ingest <file> # add a doc`));
82736
+ println(c.dim(` ${progName()} configure-agent # wire up an MCP client`));
82680
82737
  println("");
82681
- println(c.dim("Run `cerefox --help` for the full command list."));
82738
+ println(c.dim(`Run \`${progName()} --help\` for the full command list.`));
82682
82739
  }
82683
82740
  }
82684
82741
  async function main() {