@cerefox/memory 1.20.0 → 1.22.0
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/bin/cerefox.js +181 -122
- package/dist/frontend/assets/Courier-BRJ-B_ND.js +1370 -0
- package/dist/frontend/assets/Courier-BRJ-B_ND.js.map +1 -0
- package/dist/frontend/assets/docx-Ch26gbLd.js +29 -0
- package/dist/frontend/assets/docx-Ch26gbLd.js.map +1 -0
- package/dist/frontend/assets/index-CV1iy1p2.css +1 -0
- package/dist/frontend/assets/index-Dhpoy6w3.js +122 -0
- package/dist/frontend/assets/index-Dhpoy6w3.js.map +1 -0
- package/dist/frontend/assets/markdown-YrYQtnOl.js +2 -0
- package/dist/frontend/assets/markdown-YrYQtnOl.js.map +1 -0
- package/dist/frontend/assets/pdf-Bpjaodjd.js +7 -0
- package/dist/frontend/assets/pdf-Bpjaodjd.js.map +1 -0
- package/dist/frontend/assets/pdfmake-L7DGtDcB.js +229 -0
- package/dist/frontend/assets/pdfmake-L7DGtDcB.js.map +1 -0
- package/dist/frontend/assets/rolldown-runtime-COiEfhsA.js +1 -0
- package/dist/frontend/assets/vfs_fonts-D9BViC6C.js +2 -0
- package/dist/frontend/assets/vfs_fonts-D9BViC6C.js.map +1 -0
- package/dist/frontend/index.html +3 -2
- package/dist/server-assets/_shared/ef-meta/index.ts +3 -3
- package/dist/server-assets/_shared/mcp-tools/_utils.ts +1 -0
- package/dist/server-assets/_shared/mcp-tools/audit-ops.ts +23 -2
- package/docs/guides/configuration.md +5 -2
- package/docs/guides/connect-agents.md +4 -0
- package/docs/guides/securing-local-access.md +17 -0
- package/docs/guides/setup-lan.md +160 -9
- package/docs/guides/staging-env.md +12 -2
- package/package.json +2 -2
- package/dist/frontend/assets/index-01k5C3sG.css +0 -1
- package/dist/frontend/assets/index-BQKYExx3.js +0 -121
- package/dist/frontend/assets/index-BQKYExx3.js.map +0 -1
package/dist/bin/cerefox.js
CHANGED
|
@@ -5318,7 +5318,7 @@ var init_cli_core = __esm(() => {
|
|
|
5318
5318
|
});
|
|
5319
5319
|
|
|
5320
5320
|
// src/meta.ts
|
|
5321
|
-
var PKG_VERSION = "1.
|
|
5321
|
+
var PKG_VERSION = "1.22.0";
|
|
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.",
|
|
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}`,
|
|
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(
|
|
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
|
-
|
|
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(),
|
|
26946
|
+
const timer = setInterval(() => void refreshLatest(), REFRESH_TICK_MS);
|
|
26922
26947
|
timer.unref?.();
|
|
26923
26948
|
}
|
|
26924
26949
|
function newerRelease(latest, installed = PKG_VERSION) {
|
|
@@ -26946,19 +26971,21 @@ function takeCliNotice(opts = {}) {
|
|
|
26946
26971
|
writeCache({ ...cached, notifiedAt: now.toISOString() }, path);
|
|
26947
26972
|
return `Cerefox ${newer} is available (you have ${opts.installed ?? PKG_VERSION}). Run \`${upgradeCommand()}\`.`;
|
|
26948
26973
|
}
|
|
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}`;
|
|
26974
|
+
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
26975
|
var init_update_check = __esm(() => {
|
|
26951
26976
|
init_compatibility();
|
|
26952
26977
|
init_meta();
|
|
26953
26978
|
init_auth();
|
|
26954
26979
|
init_daemon();
|
|
26955
26980
|
DAY_MS = 24 * 60 * 60 * 1000;
|
|
26956
|
-
|
|
26981
|
+
HOUR_MS = 60 * 60 * 1000;
|
|
26982
|
+
CACHE_TTL_MS = HOUR_MS;
|
|
26983
|
+
REFRESH_TICK_MS = 15 * 60 * 1000;
|
|
26957
26984
|
NOTIFY_INTERVAL_MS = DAY_MS;
|
|
26958
26985
|
});
|
|
26959
26986
|
|
|
26960
26987
|
// ../../_shared/ef-meta/index.ts
|
|
26961
|
-
var EF_VERSION = "1.
|
|
26988
|
+
var EF_VERSION = "1.22.0", CEREFOX_VERSION = "1.22.0", EF_LAST_CHANGED = "1.22.0";
|
|
26962
26989
|
var init_ef_meta = () => {};
|
|
26963
26990
|
|
|
26964
26991
|
// ../../_shared/embeddings/onnx-embedder.ts
|
|
@@ -63952,7 +63979,7 @@ async function warnIfSchemaVersionMismatch(supabase) {
|
|
|
63952
63979
|
if (!bundled)
|
|
63953
63980
|
return;
|
|
63954
63981
|
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
|
|
63982
|
+
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
63983
|
`);
|
|
63957
63984
|
}
|
|
63958
63985
|
} catch {}
|
|
@@ -66357,7 +66384,7 @@ end
|
|
|
66357
66384
|
complete -c ${prog} -f -a '(__${fn}_complete)'
|
|
66358
66385
|
`;
|
|
66359
66386
|
}
|
|
66360
|
-
function
|
|
66387
|
+
function progName2() {
|
|
66361
66388
|
return buildProgram().name();
|
|
66362
66389
|
}
|
|
66363
66390
|
function fnId(prog) {
|
|
@@ -66365,7 +66392,7 @@ function fnId(prog) {
|
|
|
66365
66392
|
}
|
|
66366
66393
|
function scriptFor(shell) {
|
|
66367
66394
|
const nodes = collectNodes();
|
|
66368
|
-
const prog =
|
|
66395
|
+
const prog = progName2();
|
|
66369
66396
|
const fn = fnId(prog);
|
|
66370
66397
|
switch (shell) {
|
|
66371
66398
|
case "bash":
|
|
@@ -66397,7 +66424,7 @@ async function installMode(options) {
|
|
|
66397
66424
|
throw userError(`Unsupported --shell "${shell}". Use bash, zsh, or fish.`);
|
|
66398
66425
|
}
|
|
66399
66426
|
const home = homedir3();
|
|
66400
|
-
const prog =
|
|
66427
|
+
const prog = progName2();
|
|
66401
66428
|
const rcBegin = rcBeginFor(prog);
|
|
66402
66429
|
const rcEnd = rcEndFor(prog);
|
|
66403
66430
|
const scriptPath = join3(home, `.${prog}-completion.${shell}`);
|
|
@@ -66445,7 +66472,7 @@ async function action2(target, options) {
|
|
|
66445
66472
|
println(scriptFor(target));
|
|
66446
66473
|
if (process.stdout.isTTY) {
|
|
66447
66474
|
eprintln(c.dim(`
|
|
66448
|
-
# Tip:
|
|
66475
|
+
# Tip: \`${progName()} completion install\` writes this + wires your shell rc automatically.`));
|
|
66449
66476
|
}
|
|
66450
66477
|
}
|
|
66451
66478
|
function registerCompletion(program) {
|
|
@@ -66655,7 +66682,7 @@ function action4(options) {
|
|
|
66655
66682
|
});
|
|
66656
66683
|
return;
|
|
66657
66684
|
}
|
|
66658
|
-
println(c.bold(
|
|
66685
|
+
println(c.bold(`Runtime config keys (stored in cerefox_config; read with \`${progName()} config get <key>\`):`));
|
|
66659
66686
|
let group = null;
|
|
66660
66687
|
for (const spec of CONFIG_CATALOG) {
|
|
66661
66688
|
if (spec.group !== group) {
|
|
@@ -68052,7 +68079,7 @@ function delegatedWrite(writer, opts) {
|
|
|
68052
68079
|
if (result.error) {
|
|
68053
68080
|
const err = result.error;
|
|
68054
68081
|
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
|
|
68082
|
+
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
68083
|
}
|
|
68057
68084
|
throw new Error(`${writer.label}: failed to spawn \`${cmd}\`: ${err.message}`);
|
|
68058
68085
|
}
|
|
@@ -68169,18 +68196,18 @@ async function action7(documentId, options) {
|
|
|
68169
68196
|
} catch (e) {
|
|
68170
68197
|
const message = e instanceof Error ? e.message : String(e);
|
|
68171
68198
|
if (isMissingFunctionError(message, "cerefox_delete_document")) {
|
|
68172
|
-
throw systemError(options.reason ? `This server is behind: \`--reason\` needs schema 0.12.0 or newer. ` + `Run
|
|
68199
|
+
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
68200
|
}
|
|
68174
68201
|
throw e;
|
|
68175
68202
|
}
|
|
68176
68203
|
if (result === null) {
|
|
68177
68204
|
const { data: check, error: checkError } = await client.raw.from("cerefox_documents").select("deleted_at").eq("id", documentId).maybeSingle();
|
|
68178
68205
|
if (checkError) {
|
|
68179
|
-
warn(`Delete submitted, but the follow-up verification read failed (${checkError.message}). ` + `Confirm with:
|
|
68206
|
+
warn(`Delete submitted, but the follow-up verification read failed (${checkError.message}). ` + `Confirm with: ${progName()} document get ${documentId}`);
|
|
68180
68207
|
return;
|
|
68181
68208
|
}
|
|
68182
68209
|
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
|
|
68210
|
+
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
68211
|
}
|
|
68185
68212
|
}
|
|
68186
68213
|
if (result?.already_deleted) {
|
|
@@ -68203,7 +68230,7 @@ function registerDeleteDoc(program) {
|
|
|
68203
68230
|
init_cli_core();
|
|
68204
68231
|
init__utils();
|
|
68205
68232
|
init_client();
|
|
68206
|
-
var
|
|
68233
|
+
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
68234
|
async function action8(options) {
|
|
68208
68235
|
const client = getClient();
|
|
68209
68236
|
let rows;
|
|
@@ -68212,12 +68239,12 @@ async function action8(options) {
|
|
|
68212
68239
|
} catch (e) {
|
|
68213
68240
|
const message = e instanceof Error ? e.message : String(e);
|
|
68214
68241
|
if (isMissingFunctionError(message, "cerefox_find_dead_links")) {
|
|
68215
|
-
throw systemError(
|
|
68242
|
+
throw systemError(serverBehind());
|
|
68216
68243
|
}
|
|
68217
68244
|
throw e;
|
|
68218
68245
|
}
|
|
68219
68246
|
if (rows === null)
|
|
68220
|
-
throw systemError(
|
|
68247
|
+
throw systemError(serverBehind());
|
|
68221
68248
|
if (options.json) {
|
|
68222
68249
|
printJson(rows);
|
|
68223
68250
|
return;
|
|
@@ -68479,10 +68506,16 @@ async function applyRpcs(opts) {
|
|
|
68479
68506
|
}
|
|
68480
68507
|
}
|
|
68481
68508
|
|
|
68509
|
+
// src/cli/util/npx-env.ts
|
|
68510
|
+
function nestedNpxEnv(env = process.env) {
|
|
68511
|
+
const { npm_config_package: _leaked, ...rest } = env;
|
|
68512
|
+
return rest;
|
|
68513
|
+
}
|
|
68514
|
+
|
|
68482
68515
|
// src/cli/commands/deploy-server.ts
|
|
68483
68516
|
function commandSucceeds(cmd, args) {
|
|
68484
68517
|
try {
|
|
68485
|
-
const r = spawnSync2(cmd, args, { encoding: "utf8", timeout: 15000 });
|
|
68518
|
+
const r = spawnSync2(cmd, args, { encoding: "utf8", timeout: 15000, env: nestedNpxEnv() });
|
|
68486
68519
|
return r.status === 0;
|
|
68487
68520
|
} catch {
|
|
68488
68521
|
return false;
|
|
@@ -68568,7 +68601,8 @@ async function action10(options) {
|
|
|
68568
68601
|
${c.red("✗")} ${ch.label}`);
|
|
68569
68602
|
eprintln(c.dim(` → ${ch.remediation}`));
|
|
68570
68603
|
}
|
|
68571
|
-
eprintln(
|
|
68604
|
+
eprintln(`
|
|
68605
|
+
Fix the above and re-run \`${progName()} server deploy\` (it's idempotent).`);
|
|
68572
68606
|
process.exit(1);
|
|
68573
68607
|
}
|
|
68574
68608
|
println(c.green(`
|
|
@@ -68689,7 +68723,8 @@ Proceed with deployment to Supabase?`, true);
|
|
|
68689
68723
|
encoding: "utf8",
|
|
68690
68724
|
stdio: ["inherit", "pipe", "pipe"],
|
|
68691
68725
|
cwd: workdir,
|
|
68692
|
-
timeout: 120000
|
|
68726
|
+
timeout: 120000,
|
|
68727
|
+
env: nestedNpxEnv()
|
|
68693
68728
|
});
|
|
68694
68729
|
if (r.stdout)
|
|
68695
68730
|
process.stdout.write(r.stdout);
|
|
@@ -68717,9 +68752,9 @@ ${r.stderr ?? ""}`);
|
|
|
68717
68752
|
eprintln(c.dim(" published yet, and bundling fails."));
|
|
68718
68753
|
eprintln(c.dim(" Your deployed functions were NOT changed — the previous version is"));
|
|
68719
68754
|
eprintln(c.dim(" still serving, so nothing is down."));
|
|
68720
|
-
eprintln(c.cyan(
|
|
68755
|
+
eprintln(c.cyan(` → Wait a few minutes, then re-run: ${progName()} server deploy --functions-only`));
|
|
68721
68756
|
} else {
|
|
68722
|
-
eprintln(c.dim(
|
|
68757
|
+
eprintln(c.dim(` Re-run \`${progName()} server deploy --functions-only\` after fixing the cause.`));
|
|
68723
68758
|
}
|
|
68724
68759
|
process.exit(1);
|
|
68725
68760
|
}
|
|
@@ -68738,15 +68773,16 @@ ${r.stderr ?? ""}`);
|
|
|
68738
68773
|
println(c.cyan(`
|
|
68739
68774
|
ℹ The primitive Edge Functions now require the Cerefox access token.
|
|
68740
68775
|
` + ` If CEREFOX_ACCESS_TOKENS is unset they reject ALL callers (fail closed) —
|
|
68741
|
-
` +
|
|
68776
|
+
` + ` GPT Actions, remote HTTP, and \`${progName()} doctor\`. Generate it now:
|
|
68777
|
+
` + ` ${progName()} token generate
|
|
68742
68778
|
` + ` (or manually: supabase secrets set CEREFOX_ACCESS_TOKENS=<token> --project-ref ${ref})
|
|
68743
68779
|
` + " Migration + client cutover: docs/specs/ef-auth-migration-design.md §6."));
|
|
68744
68780
|
}
|
|
68745
68781
|
}
|
|
68746
68782
|
println(c.green(`
|
|
68747
68783
|
✓ Server deploy complete.`));
|
|
68748
|
-
println(c.dim(
|
|
68749
|
-
println(c.dim(
|
|
68784
|
+
println(c.dim(`Verify with: ${progName()} doctor`));
|
|
68785
|
+
println(c.dim(`Refresh the bundled guides: ${progName()} guides ingest`));
|
|
68750
68786
|
}
|
|
68751
68787
|
function efDeployArgs(ef, workdir, projectRef) {
|
|
68752
68788
|
const args = ["--yes", "supabase", "functions", "deploy", ef, "--use-api", "--workdir", workdir];
|
|
@@ -68797,7 +68833,7 @@ async function action11(documentId, options) {
|
|
|
68797
68833
|
if (!doc)
|
|
68798
68834
|
throw notFound(`Document ${documentId} not found.`);
|
|
68799
68835
|
if (doc.deleted_at) {
|
|
68800
|
-
throw userError(`Document ${documentId} is soft-deleted — restore it first (
|
|
68836
|
+
throw userError(`Document ${documentId} is soft-deleted — restore it first (${progName()} document restore).`);
|
|
68801
68837
|
}
|
|
68802
68838
|
const metaTouched = sets.length > 0 || unsets.length > 0;
|
|
68803
68839
|
const newTitle = hasTitle ? options.title.trim() : doc.title;
|
|
@@ -68824,7 +68860,7 @@ async function action11(documentId, options) {
|
|
|
68824
68860
|
});
|
|
68825
68861
|
if (metaErr) {
|
|
68826
68862
|
if (metaErr.message?.includes("CEREFOX_BAD_METADATA")) {
|
|
68827
|
-
throw userError(`Document ${documentId} has non-object metadata; a patch cannot repair it. ` + `Repair it first with:
|
|
68863
|
+
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>'`);
|
|
68828
68864
|
}
|
|
68829
68865
|
throw systemError(`Metadata update failed: ${metaErr.message}`);
|
|
68830
68866
|
}
|
|
@@ -68843,7 +68879,7 @@ async function action11(documentId, options) {
|
|
|
68843
68879
|
}
|
|
68844
68880
|
println(c.green(`✓ Edited "${newTitle}" (id: ${documentId}).`));
|
|
68845
68881
|
if (titleChanged) {
|
|
68846
|
-
println(c.dim(
|
|
68882
|
+
println(c.dim(` Title changed: FTS refreshed; semantic embeddings update on next \`${progName()} server reindex\`.`));
|
|
68847
68883
|
}
|
|
68848
68884
|
}
|
|
68849
68885
|
function collect(value, prev) {
|
|
@@ -68884,21 +68920,21 @@ async function action12(documentId, options) {
|
|
|
68884
68920
|
} catch (e) {
|
|
68885
68921
|
const message = e instanceof Error ? e.message : String(e);
|
|
68886
68922
|
if (isMissingFunctionError(message, "cerefox_restore_document")) {
|
|
68887
|
-
throw systemError(options.reason ? `This server is behind: \`--reason\` needs schema 0.12.0 or newer. ` + `Run
|
|
68923
|
+
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.`);
|
|
68888
68924
|
}
|
|
68889
68925
|
throw e;
|
|
68890
68926
|
}
|
|
68891
68927
|
if (result === null) {
|
|
68892
68928
|
const { data: check, error: checkError } = await client.raw.from("cerefox_documents").select("deleted_at").eq("id", documentId).maybeSingle();
|
|
68893
68929
|
if (checkError) {
|
|
68894
|
-
warn(`Restore submitted, but the follow-up verification read failed (${checkError.message}). ` + `Confirm with:
|
|
68930
|
+
warn(`Restore submitted, but the follow-up verification read failed (${checkError.message}). ` + `Confirm with: ${progName()} document get ${documentId}`);
|
|
68895
68931
|
return;
|
|
68896
68932
|
}
|
|
68897
68933
|
if (!check) {
|
|
68898
68934
|
throw systemError(`Document ${documentId} no longer exists — it may have been purged concurrently. Nothing was restored.`);
|
|
68899
68935
|
}
|
|
68900
68936
|
if (check.deleted_at) {
|
|
68901
|
-
throw systemError(`The restore did not take effect — the server has no matching ` + `cerefox_restore_document (mid-deploy window, or an old schema). ` + `Run
|
|
68937
|
+
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.`);
|
|
68902
68938
|
}
|
|
68903
68939
|
}
|
|
68904
68940
|
if (result && result.restored === false) {
|
|
@@ -68979,15 +69015,15 @@ async function action13(documentId, options) {
|
|
|
68979
69015
|
if (/not found/i.test(msg))
|
|
68980
69016
|
throw notFound(`Document ${documentId} not found (or is deleted).`);
|
|
68981
69017
|
if (msg.includes("CEREFOX_METADATA_CONFLICT")) {
|
|
68982
|
-
throw userError(`The metadata of ${documentId} changed since you read it. Re-read it ` + `(
|
|
69018
|
+
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.`);
|
|
68983
69019
|
}
|
|
68984
69020
|
if (msg.includes("CEREFOX_METADATA_TOKEN_REQUIRED")) {
|
|
68985
|
-
throw userError(`--replace discards every key you do not list, so it needs --expected-metadata-revision ` + `(from
|
|
69021
|
+
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.`);
|
|
68986
69022
|
}
|
|
68987
69023
|
throw systemError(`Could not set metadata: ${msg}`);
|
|
68988
69024
|
}
|
|
68989
69025
|
if (!rows || rows.length === 0) {
|
|
68990
|
-
throw systemError("cerefox_set_document_metadata returned no data.",
|
|
69026
|
+
throw systemError("cerefox_set_document_metadata returned no data.", `Verify the RPC is deployed: \`${progName()} server deploy\`.`);
|
|
68991
69027
|
}
|
|
68992
69028
|
const row = rows[0];
|
|
68993
69029
|
if (options.jsonOut) {
|
|
@@ -69060,7 +69096,7 @@ function openInBrowser(path) {
|
|
|
69060
69096
|
function resolveDoc(topic) {
|
|
69061
69097
|
const doc = readBundledDoc(topic);
|
|
69062
69098
|
if (!doc) {
|
|
69063
|
-
throw notFound(`No bundled guide named "${topic}".`,
|
|
69099
|
+
throw notFound(`No bundled guide named "${topic}".`, `Run \`${progName()} guides list\` to see available topics.`);
|
|
69064
69100
|
}
|
|
69065
69101
|
return doc;
|
|
69066
69102
|
}
|
|
@@ -69074,7 +69110,7 @@ function listAction() {
|
|
|
69074
69110
|
println("");
|
|
69075
69111
|
printTable(docs.map((d) => ({ topic: d.topic, size_kb: Math.round(d.size / 1024) + " KB" })));
|
|
69076
69112
|
println("");
|
|
69077
|
-
println(c.dim(
|
|
69113
|
+
println(c.dim(`Open with \`${progName()} guides open <topic>\` (browser) or \`${progName()} guides show <topic>\` (stdout).`));
|
|
69078
69114
|
}
|
|
69079
69115
|
function openAction(topic) {
|
|
69080
69116
|
const doc = resolveDoc(topic);
|
|
@@ -69197,8 +69233,8 @@ async function setArchived(versionId, archived, options) {
|
|
|
69197
69233
|
println(c.green(`✓ Version ${data.version_number} (${versionId}) ${op}d.`));
|
|
69198
69234
|
}
|
|
69199
69235
|
function registerVersionArchive(parent) {
|
|
69200
|
-
parent.command("archive").description("Archive a document version (protect it from version cleanup).").argument("<version-id>",
|
|
69201
|
-
parent.command("unarchive").description("Unarchive a document version (allow version cleanup again).").argument("<version-id>",
|
|
69236
|
+
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));
|
|
69237
|
+
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));
|
|
69202
69238
|
}
|
|
69203
69239
|
|
|
69204
69240
|
// ../../node_modules/.bun/ora@9.4.1/node_modules/ora/index.js
|
|
@@ -72680,7 +72716,7 @@ function checkConfig() {
|
|
|
72680
72716
|
name: "config",
|
|
72681
72717
|
status: "error",
|
|
72682
72718
|
detail: `Could not resolve config dir: ${err instanceof Error ? err.message : String(err)}`,
|
|
72683
|
-
hint:
|
|
72719
|
+
hint: `Run \`${progName()} init\` to bootstrap.`
|
|
72684
72720
|
};
|
|
72685
72721
|
}
|
|
72686
72722
|
if (!existsSync12(envPath)) {
|
|
@@ -72696,7 +72732,7 @@ function checkConfig() {
|
|
|
72696
72732
|
name: "config",
|
|
72697
72733
|
status: "error",
|
|
72698
72734
|
detail: `No config file at ${envPath}`,
|
|
72699
|
-
hint:
|
|
72735
|
+
hint: `Run \`${progName()} init\` to create one.`
|
|
72700
72736
|
};
|
|
72701
72737
|
}
|
|
72702
72738
|
let modeDetail = "";
|
|
@@ -72774,7 +72810,7 @@ async function checkRetiredEnvVars() {
|
|
|
72774
72810
|
hint: "Safe to delete those lines; nothing reads them."
|
|
72775
72811
|
};
|
|
72776
72812
|
}
|
|
72777
|
-
const moves = pending.map((v) =>
|
|
72813
|
+
const moves = pending.map((v) => `${progName()} config set ${v.configKey} ${(process.env[v.name] ?? "").trim()}`).join(`
|
|
72778
72814
|
`);
|
|
72779
72815
|
const prunedWasDisabled = pending.some((v) => v.configKey.startsWith("version_"));
|
|
72780
72816
|
return {
|
|
@@ -72788,6 +72824,17 @@ async function checkRetiredEnvVars() {
|
|
|
72788
72824
|
Then delete those lines from your .env — nothing reads them.`
|
|
72789
72825
|
};
|
|
72790
72826
|
}
|
|
72827
|
+
function dataApiHint(status, body, key) {
|
|
72828
|
+
if (status !== 401)
|
|
72829
|
+
return "Verify CEREFOX_SUPABASE_URL.";
|
|
72830
|
+
if (key.trim().startsWith("cfx_lak_")) {
|
|
72831
|
+
if (/PGRST30\d|JWT/.test(body)) {
|
|
72832
|
+
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.";
|
|
72833
|
+
}
|
|
72834
|
+
return "The server does not accept this API key. Check CEREFOX_SUPABASE_KEY against the server's key.";
|
|
72835
|
+
}
|
|
72836
|
+
return "Verify CEREFOX_SUPABASE_KEY (use the service-role / sb_secret key).";
|
|
72837
|
+
}
|
|
72791
72838
|
async function checkSupabase() {
|
|
72792
72839
|
let settings;
|
|
72793
72840
|
try {
|
|
@@ -72797,7 +72844,7 @@ async function checkSupabase() {
|
|
|
72797
72844
|
name: "supabase",
|
|
72798
72845
|
status: "error",
|
|
72799
72846
|
detail: `Could not load settings: ${err instanceof Error ? err.message : String(err)}`,
|
|
72800
|
-
hint:
|
|
72847
|
+
hint: `Run \`${progName()} init\`.`
|
|
72801
72848
|
};
|
|
72802
72849
|
}
|
|
72803
72850
|
if (!settings.supabaseUrl || !settings.supabaseKey) {
|
|
@@ -72805,7 +72852,7 @@ async function checkSupabase() {
|
|
|
72805
72852
|
name: "supabase",
|
|
72806
72853
|
status: "error",
|
|
72807
72854
|
detail: "CEREFOX_SUPABASE_URL or CEREFOX_SUPABASE_KEY is not set.",
|
|
72808
|
-
hint:
|
|
72855
|
+
hint: `Run \`${progName()} init\` to bootstrap.`
|
|
72809
72856
|
};
|
|
72810
72857
|
}
|
|
72811
72858
|
try {
|
|
@@ -72817,11 +72864,12 @@ async function checkSupabase() {
|
|
|
72817
72864
|
}
|
|
72818
72865
|
});
|
|
72819
72866
|
if (!resp.ok) {
|
|
72867
|
+
const body = await resp.text().catch(() => "");
|
|
72820
72868
|
return {
|
|
72821
72869
|
name: "supabase",
|
|
72822
72870
|
status: "error",
|
|
72823
72871
|
detail: `Data API returned ${resp.status} ${resp.statusText}`,
|
|
72824
|
-
hint: resp.status
|
|
72872
|
+
hint: dataApiHint(resp.status, body, settings.supabaseKey)
|
|
72825
72873
|
};
|
|
72826
72874
|
}
|
|
72827
72875
|
return {
|
|
@@ -72853,7 +72901,7 @@ async function checkOpenAI() {
|
|
|
72853
72901
|
name: "openai",
|
|
72854
72902
|
status: "warn",
|
|
72855
72903
|
detail: "No OPENAI_API_KEY / CEREFOX_OPENAI_API_KEY set.",
|
|
72856
|
-
hint:
|
|
72904
|
+
hint: `Required for \`${progName()} search\` (semantic mode) and ingest. Set in your .env.`
|
|
72857
72905
|
};
|
|
72858
72906
|
}
|
|
72859
72907
|
try {
|
|
@@ -72984,7 +73032,7 @@ async function checkReviewWorkflow() {
|
|
|
72984
73032
|
name,
|
|
72985
73033
|
status: "warn",
|
|
72986
73034
|
detail: "review_workflow_enabled is not set — treated as OFF until the schema is updated",
|
|
72987
|
-
hint:
|
|
73035
|
+
hint: `Run \`${progName()} server deploy --schema-only\` (v1.13.0+) to seed it.`
|
|
72988
73036
|
};
|
|
72989
73037
|
}
|
|
72990
73038
|
const on = raw.trim().toLowerCase() === "true";
|
|
@@ -72992,7 +73040,7 @@ async function checkReviewWorkflow() {
|
|
|
72992
73040
|
name,
|
|
72993
73041
|
status: "ok",
|
|
72994
73042
|
detail: on ? "ON — agent writes land pending_review; review_status is shown everywhere" : "OFF — review_status is hidden everywhere (still recorded from author_type)",
|
|
72995
|
-
hint: on ? undefined :
|
|
73043
|
+
hint: on ? undefined : `Turn it on with \`${progName()} config set review_workflow_enabled true\`.`
|
|
72996
73044
|
};
|
|
72997
73045
|
}
|
|
72998
73046
|
async function checkTrashAutoPurge() {
|
|
@@ -73031,7 +73079,7 @@ async function checkTrashAutoPurge() {
|
|
|
73031
73079
|
name,
|
|
73032
73080
|
status: "ok",
|
|
73033
73081
|
detail: "off — the trash is only emptied by hand",
|
|
73034
|
-
hint:
|
|
73082
|
+
hint: `Opt in with \`${progName()} config set trash_auto_purge_enabled true\` (period: trash_retention_days).`
|
|
73035
73083
|
};
|
|
73036
73084
|
}
|
|
73037
73085
|
return {
|
|
@@ -73066,7 +73114,7 @@ async function checkEmbedderMismatch() {
|
|
|
73066
73114
|
name: EMBEDDER_CHECK_NAME,
|
|
73067
73115
|
status: "warn",
|
|
73068
73116
|
detail: `configured "${active}", but the model is not downloaded yet; the first search or write will fetch it (~130 MB).`,
|
|
73069
|
-
hint:
|
|
73117
|
+
hint: `Fetch it now with \`${progName()} embedder-warmup\`${progName() === "cerefox" ? " (Cerefox Local: `cerefox-local embedder-warmup`)" : ""}; it resumes if the connection drops.`
|
|
73070
73118
|
};
|
|
73071
73119
|
}
|
|
73072
73120
|
}
|
|
@@ -73080,7 +73128,7 @@ async function checkEmbedderMismatch() {
|
|
|
73080
73128
|
name: EMBEDDER_CHECK_NAME,
|
|
73081
73129
|
status: "warn",
|
|
73082
73130
|
detail: `configured "${active}" but existing chunks were embedded with ${stale.map((r) => `"${r}"`).join(", ")} — semantic search across them is broken.`,
|
|
73083
|
-
hint:
|
|
73131
|
+
hint: `Run \`${progName()} server reindex\` to re-embed everything with the configured embedder.`
|
|
73084
73132
|
};
|
|
73085
73133
|
} catch (err) {
|
|
73086
73134
|
return {
|
|
@@ -73188,7 +73236,7 @@ async function checkContentFormat() {
|
|
|
73188
73236
|
name: CONTENT_FORMAT_CHECK_NAME,
|
|
73189
73237
|
status: "skipped",
|
|
73190
73238
|
detail: `${legacy} of ${total} document(s) use the legacy reconstruction format (format 1).`,
|
|
73191
|
-
hint:
|
|
73239
|
+
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\`.`
|
|
73192
73240
|
};
|
|
73193
73241
|
}
|
|
73194
73242
|
}
|
|
@@ -73221,7 +73269,7 @@ async function checkMetadataHealth() {
|
|
|
73221
73269
|
name: METADATA_HEALTH_CHECK_NAME,
|
|
73222
73270
|
status: "skipped",
|
|
73223
73271
|
detail: `${probe.rows.length} document(s) hold non-object metadata: ${sample}${probe.rows.length > 3 ? ", …" : ""}.`,
|
|
73224
|
-
hint:
|
|
73272
|
+
hint: `Writes that would merge onto these rows are refused (#212). Repair each with \`${progName()} document set-metadata <id> --replace --json '<the intended object>'\`.`
|
|
73225
73273
|
};
|
|
73226
73274
|
}
|
|
73227
73275
|
function hasCerefoxInJsonFile(path) {
|
|
@@ -73250,7 +73298,7 @@ async function checkWebDaemon() {
|
|
|
73250
73298
|
name: "web server",
|
|
73251
73299
|
status: "skipped",
|
|
73252
73300
|
detail: `no daemon running (stale pidfile for process ${status.info.pid}).`,
|
|
73253
|
-
hint:
|
|
73301
|
+
hint: `Clean it up: ${progName()} web stop`
|
|
73254
73302
|
};
|
|
73255
73303
|
}
|
|
73256
73304
|
if (!status.responding) {
|
|
@@ -73300,7 +73348,7 @@ function checkMcpConfigs() {
|
|
|
73300
73348
|
name: "mcp clients",
|
|
73301
73349
|
status: isLocalBackend() ? "skipped" : "warn",
|
|
73302
73350
|
detail: isLocalBackend() ? "checked from inside the container — host MCP configs are not visible here." : "No MCP client configs reference Cerefox.",
|
|
73303
|
-
hint: isLocalBackend() ? "Configure agents on the host with `cerefox-local configure-agent`." :
|
|
73351
|
+
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.`
|
|
73304
73352
|
};
|
|
73305
73353
|
}
|
|
73306
73354
|
return {
|
|
@@ -73398,7 +73446,7 @@ async function checkEdgeFunctionsCompat() {
|
|
|
73398
73446
|
name: "edge functions",
|
|
73399
73447
|
status: "skipped",
|
|
73400
73448
|
detail: "No CEREFOX_ACCESS_TOKEN set; EF version check skipped.",
|
|
73401
|
-
hint:
|
|
73449
|
+
hint: `Run \`${progName()} token generate\` to enable client↔server version checks.`
|
|
73402
73450
|
};
|
|
73403
73451
|
}
|
|
73404
73452
|
let compat;
|
|
@@ -73550,11 +73598,11 @@ async function action17(options) {
|
|
|
73550
73598
|
const needsEf = stale("edge functions");
|
|
73551
73599
|
let remediation = null;
|
|
73552
73600
|
if (needsSchema && needsEf) {
|
|
73553
|
-
remediation =
|
|
73601
|
+
remediation = `This release needs a server update (schema + RPCs + Edge Functions): ${progName()} server deploy`;
|
|
73554
73602
|
} else if (needsSchema) {
|
|
73555
|
-
remediation =
|
|
73603
|
+
remediation = `This release needs a schema + RPC update: ${progName()} server deploy --schema-only`;
|
|
73556
73604
|
} else if (needsEf) {
|
|
73557
|
-
remediation =
|
|
73605
|
+
remediation = `This release needs an Edge Function update: ${progName()} server deploy --functions-only`;
|
|
73558
73606
|
}
|
|
73559
73607
|
if (remediation) {
|
|
73560
73608
|
println(cErr.yellow("→ " + remediation));
|
|
@@ -73642,7 +73690,7 @@ async function action18(options) {
|
|
|
73642
73690
|
doc: auditDocLabel(row.doc_title, row.document_id, row.operation).slice(0, 40),
|
|
73643
73691
|
author: (row.author ?? "") + (row.author_type ? `(${row.author_type})` : ""),
|
|
73644
73692
|
size_delta: row.size_before !== null && row.size_after !== null ? `${row.size_before} → ${row.size_after}` : "",
|
|
73645
|
-
change: (metadataChangeSummary(row.metadata_before, row.metadata_after) ?? "").slice(0, 60)
|
|
73693
|
+
change: (metadataChangeSummary(row.metadata_before, row.metadata_after) ?? storeChangeSummary(row.operation, row.description) ?? "").slice(0, 60)
|
|
73646
73694
|
})));
|
|
73647
73695
|
}
|
|
73648
73696
|
function registerGetAuditLog(program) {
|
|
@@ -74667,7 +74715,7 @@ async function readContent(path, paste) {
|
|
|
74667
74715
|
return { content, titleFromPath: undefined };
|
|
74668
74716
|
}
|
|
74669
74717
|
if (!path) {
|
|
74670
|
-
throw userError("Provide a file path or use --paste.",
|
|
74718
|
+
throw userError("Provide a file path or use --paste.", `Example: ${progName()} document ingest notes.md --title 'My Note'`);
|
|
74671
74719
|
}
|
|
74672
74720
|
let content;
|
|
74673
74721
|
try {
|
|
@@ -74709,7 +74757,7 @@ async function action20(path, options) {
|
|
|
74709
74757
|
}
|
|
74710
74758
|
const settings = loadSettings();
|
|
74711
74759
|
if (!settings.supabaseUrl || !settings.supabaseKey) {
|
|
74712
|
-
throw userError(
|
|
74760
|
+
throw userError(`Supabase credentials not configured — run \`${progName()} init\` first.`);
|
|
74713
74761
|
}
|
|
74714
74762
|
if (!settings.openaiApiKey && resolveEmbedderKind() !== "local") {
|
|
74715
74763
|
throw userError("OPENAI_API_KEY not set — required for embeddings during ingest.");
|
|
@@ -74821,7 +74869,7 @@ async function runTool(toolName, args) {
|
|
|
74821
74869
|
}
|
|
74822
74870
|
}
|
|
74823
74871
|
function registerDocumentInsert(program) {
|
|
74824
|
-
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>",
|
|
74872
|
+
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) => {
|
|
74825
74873
|
await runTool("cerefox_insert", {
|
|
74826
74874
|
document_id: documentId,
|
|
74827
74875
|
text: resolveText(options.text, "--text"),
|
|
@@ -74902,7 +74950,7 @@ async function action21(dir, options) {
|
|
|
74902
74950
|
const metadata = parseJsonObjectArg(options.metadata, "--metadata");
|
|
74903
74951
|
const settings = loadSettings();
|
|
74904
74952
|
if (!settings.supabaseUrl || !settings.supabaseKey) {
|
|
74905
|
-
throw userError(
|
|
74953
|
+
throw userError(`Supabase credentials not configured — run \`${progName()} init\` first.`);
|
|
74906
74954
|
}
|
|
74907
74955
|
if (!settings.openaiApiKey && resolveEmbedderKind() !== "local") {
|
|
74908
74956
|
throw userError("OPENAI_API_KEY not set — required for embeddings during ingest.");
|
|
@@ -75032,7 +75080,7 @@ function answersFromEnvFile(path) {
|
|
|
75032
75080
|
const required = ["CEREFOX_SUPABASE_URL", "CEREFOX_SUPABASE_KEY", "OPENAI_API_KEY"];
|
|
75033
75081
|
for (const key of required) {
|
|
75034
75082
|
if (!parsed[key] || parsed[key].trim() === "") {
|
|
75035
|
-
throw userError(`Existing .env at ${path} is missing required key "${key}".`, `Fix it manually or run
|
|
75083
|
+
throw userError(`Existing .env at ${path} is missing required key "${key}".`, `Fix it manually or run \`${progName()} init --force\` to start fresh.`);
|
|
75036
75084
|
}
|
|
75037
75085
|
}
|
|
75038
75086
|
return {
|
|
@@ -75077,7 +75125,8 @@ async function promptForAnswers() {
|
|
|
75077
75125
|
});
|
|
75078
75126
|
println("");
|
|
75079
75127
|
println(c.cyan("▶ Step 4/5 — Direct Postgres connection (optional for npm-installed users)"));
|
|
75080
|
-
println(c.dim(
|
|
75128
|
+
println(c.dim(` Only needed for \`${progName()} server deploy\` (schema deploy + migrations).
|
|
75129
|
+
` + ` You can skip this and set CEREFOX_DATABASE_URL later — press Enter.
|
|
75081
75130
|
` + " Format: postgresql://postgres.<project-ref>:<pw>@…:5432/postgres?sslmode=require"));
|
|
75082
75131
|
const databaseUrl = await ask({
|
|
75083
75132
|
type: "text",
|
|
@@ -75222,7 +75271,7 @@ async function maybeOfferServerDeploy() {
|
|
|
75222
75271
|
if (yes)
|
|
75223
75272
|
launchDeployServer();
|
|
75224
75273
|
else
|
|
75225
|
-
println(c.dim(
|
|
75274
|
+
println(c.dim(` Skipped. Run \`${progName()} server deploy\` later (or \`${progName()} doctor\` to recheck).`));
|
|
75226
75275
|
println("");
|
|
75227
75276
|
return;
|
|
75228
75277
|
}
|
|
@@ -75233,7 +75282,7 @@ async function maybeOfferServerDeploy() {
|
|
|
75233
75282
|
if (yes)
|
|
75234
75283
|
launchDeployServer();
|
|
75235
75284
|
else
|
|
75236
|
-
println(c.dim(
|
|
75285
|
+
println(c.dim(` Skipped. Run \`${progName()} server deploy\` when ready.`));
|
|
75237
75286
|
println("");
|
|
75238
75287
|
return;
|
|
75239
75288
|
}
|
|
@@ -75252,7 +75301,7 @@ async function postWriteLifecycle(envPath, options) {
|
|
|
75252
75301
|
await Promise.resolve().then(() => init_sync_self_docs());
|
|
75253
75302
|
await runSyncSelfDocs({});
|
|
75254
75303
|
} catch (err) {
|
|
75255
|
-
warn(`Self-doc ingest failed: ${err instanceof Error ? err.message : String(err)}. Run
|
|
75304
|
+
warn(`Self-doc ingest failed: ${err instanceof Error ? err.message : String(err)}. Run \`${progName()} guides ingest\` manually after init.`);
|
|
75256
75305
|
}
|
|
75257
75306
|
println("");
|
|
75258
75307
|
}
|
|
@@ -75276,9 +75325,9 @@ async function postWriteLifecycle(envPath, options) {
|
|
|
75276
75325
|
}
|
|
75277
75326
|
println("");
|
|
75278
75327
|
println(c.green("Done. Try:"));
|
|
75279
|
-
println(c.dim(
|
|
75280
|
-
println(c.dim(
|
|
75281
|
-
println(c.dim(
|
|
75328
|
+
println(c.dim(` ${progName()} doctor # verify everything`));
|
|
75329
|
+
println(c.dim(` ${progName()} search "…" # search the KB`));
|
|
75330
|
+
println(c.dim(` ${progName()} document ingest <file> # add a doc`));
|
|
75282
75331
|
println("");
|
|
75283
75332
|
println(c.dim(` Config in effect: ${envPath}`));
|
|
75284
75333
|
}
|
|
@@ -75379,7 +75428,7 @@ async function action23(options) {
|
|
|
75379
75428
|
println("");
|
|
75380
75429
|
println(c.green(`✓ Using existing config at ${cwdEnv}`));
|
|
75381
75430
|
println(c.dim(` TS reads it via the legacy dev-mode fallback (~/.cerefox/.env not present).`));
|
|
75382
|
-
println(c.dim(` Run
|
|
75431
|
+
println(c.dim(` Run \`${progName()} init\` again later to migrate to the new home.`));
|
|
75383
75432
|
println("");
|
|
75384
75433
|
await postWriteLifecycle(cwdEnv, options);
|
|
75385
75434
|
return;
|
|
@@ -75420,7 +75469,7 @@ async function action24(options) {
|
|
|
75420
75469
|
throw systemError(`Project lookup failed: ${projectError.message}`);
|
|
75421
75470
|
}
|
|
75422
75471
|
if (!project) {
|
|
75423
|
-
throw userError(`Project "${options.project}" not found.`,
|
|
75472
|
+
throw userError(`Project "${options.project}" not found.`, `Run \`${progName()} project list\` to see available names.`);
|
|
75424
75473
|
}
|
|
75425
75474
|
projectId = project.id;
|
|
75426
75475
|
}
|
|
@@ -75736,7 +75785,7 @@ function warnLargeBulkWrite(opts) {
|
|
|
75736
75785
|
async function action29(options) {
|
|
75737
75786
|
const settings = loadSettings();
|
|
75738
75787
|
if (!settings.supabaseUrl || !settings.supabaseKey) {
|
|
75739
|
-
throw userError(
|
|
75788
|
+
throw userError(`Supabase credentials not configured — run \`${progName()} init\` first.`);
|
|
75740
75789
|
}
|
|
75741
75790
|
if (!settings.openaiApiKey && resolveEmbedderKind() !== "local") {
|
|
75742
75791
|
throw userError("OPENAI_API_KEY not set — required for embeddings.");
|
|
@@ -76007,7 +76056,7 @@ async function action31(target, options) {
|
|
|
76007
76056
|
}
|
|
76008
76057
|
const trashedInFile = payload.documents.filter((d) => d.deleted_at != null).length;
|
|
76009
76058
|
if (trashedInFile > 0) {
|
|
76010
|
-
println(c.dim(` trashed documents in file: ${trashedInFile} — restored as trash ` +
|
|
76059
|
+
println(c.dim(` trashed documents in file: ${trashedInFile} — restored as trash ` + `(still deleted; recover with \`${progName()} document restore\`)`));
|
|
76011
76060
|
}
|
|
76012
76061
|
println("");
|
|
76013
76062
|
const client = getClient();
|
|
@@ -76126,7 +76175,7 @@ async function action31(target, options) {
|
|
|
76126
76175
|
}
|
|
76127
76176
|
}
|
|
76128
76177
|
function registerRestore(program) {
|
|
76129
|
-
program.command("restore").description("Restore a JSON-snapshot backup into the knowledge base.").argument("<snapshot>",
|
|
76178
|
+
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);
|
|
76130
76179
|
}
|
|
76131
76180
|
|
|
76132
76181
|
// src/cli/commands/search.ts
|
|
@@ -76141,13 +76190,13 @@ async function embedQuery(query) {
|
|
|
76141
76190
|
const settings = loadSettings();
|
|
76142
76191
|
const apiKey = settings.openaiApiKey;
|
|
76143
76192
|
if (!apiKey && resolveEmbedderKind() !== "local") {
|
|
76144
|
-
throw userError("OPENAI_API_KEY (or CEREFOX_OPENAI_API_KEY) is required for search.",
|
|
76193
|
+
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.`);
|
|
76145
76194
|
}
|
|
76146
76195
|
try {
|
|
76147
76196
|
return await getEmbedding(query, apiKey);
|
|
76148
76197
|
} catch (err) {
|
|
76149
76198
|
const msg = err instanceof Error ? err.message : String(err);
|
|
76150
|
-
throw systemError(`Failed to embed query: ${msg}`,
|
|
76199
|
+
throw systemError(`Failed to embed query: ${msg}`, `Run \`${progName()} doctor\` to verify the OpenAI API path.`);
|
|
76151
76200
|
}
|
|
76152
76201
|
}
|
|
76153
76202
|
|
|
@@ -76319,7 +76368,7 @@ async function action32(query, options) {
|
|
|
76319
76368
|
}
|
|
76320
76369
|
}
|
|
76321
76370
|
function registerSearch(program) {
|
|
76322
|
-
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",
|
|
76371
|
+
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);
|
|
76323
76372
|
}
|
|
76324
76373
|
|
|
76325
76374
|
// src/cli/commands/self-update.ts
|
|
@@ -76384,7 +76433,7 @@ async function action33(options) {
|
|
|
76384
76433
|
if (options.check) {
|
|
76385
76434
|
if (newerRelease(target)) {
|
|
76386
76435
|
println(c.yellow(`Update available: ${PKG_VERSION} → ${target}`));
|
|
76387
|
-
println(c.dim(
|
|
76436
|
+
println(c.dim(`Run \`${progName()} self-update\` to upgrade.`));
|
|
76388
76437
|
}
|
|
76389
76438
|
return;
|
|
76390
76439
|
}
|
|
@@ -76415,12 +76464,12 @@ async function action33(options) {
|
|
|
76415
76464
|
}
|
|
76416
76465
|
println("");
|
|
76417
76466
|
println("Next steps:");
|
|
76418
|
-
println(" 1. " + c.bold(
|
|
76419
|
-
println(" 2. " + c.bold(
|
|
76467
|
+
println(" 1. " + c.bold(`${progName()} server deploy`) + " apply this release's schema/RPC/EF updates");
|
|
76468
|
+
println(" 2. " + c.bold(`${progName()} guides ingest`) + " re-sync the bundled guides into your KB");
|
|
76420
76469
|
println(c.dim(" (order matters: the new client may require the new schema — run the deploy first)"));
|
|
76421
76470
|
}
|
|
76422
76471
|
function registerSelfUpdate(program) {
|
|
76423
|
-
const desc =
|
|
76472
|
+
const desc = `Upgrade Cerefox in place. Alias: \`${progName()} upgrade\`.`;
|
|
76424
76473
|
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);
|
|
76425
76474
|
declaration(program.command("self-update"));
|
|
76426
76475
|
declaration(program.command("upgrade"));
|
|
@@ -76461,7 +76510,7 @@ async function action34(options) {
|
|
|
76461
76510
|
}
|
|
76462
76511
|
}
|
|
76463
76512
|
function registerStatus(program) {
|
|
76464
|
-
program.command("status").description(
|
|
76513
|
+
program.command("status").description(`Quick sanity check (fast subset of \`${progName()} doctor\`).`).option("--json", "Emit machine-readable JSON.").action(action34);
|
|
76465
76514
|
}
|
|
76466
76515
|
|
|
76467
76516
|
// src/cli/commands/api-key.ts
|
|
@@ -76574,7 +76623,7 @@ function generateAction(opts) {
|
|
|
76574
76623
|
const envPath = resolveEnvFile();
|
|
76575
76624
|
const existing = readEnvVar(envPath, ENV_NAME);
|
|
76576
76625
|
if (existing) {
|
|
76577
|
-
throw userError(`${ENV_NAME} is already set in ${envPath} (${mask(existing)}).`,
|
|
76626
|
+
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.");
|
|
76578
76627
|
}
|
|
76579
76628
|
println(c.bold("Minting a local API key"));
|
|
76580
76629
|
writeKey(mint(), opts, "write");
|
|
@@ -76584,13 +76633,13 @@ function rotateAction(opts) {
|
|
|
76584
76633
|
const envPath = resolveEnvFile();
|
|
76585
76634
|
const existing = readEnvVar(envPath, ENV_NAME);
|
|
76586
76635
|
if (!existing) {
|
|
76587
|
-
throw userError(`No ${ENV_NAME} in ${envPath} — nothing to rotate.`,
|
|
76636
|
+
throw userError(`No ${ENV_NAME} in ${envPath} — nothing to rotate.`, `Run \`${progName()} api-key generate\` first.`);
|
|
76588
76637
|
}
|
|
76589
76638
|
println(c.bold("Rotating the local API key"));
|
|
76590
76639
|
println(c.dim(` replacing ${mask(existing)}`));
|
|
76591
76640
|
writeKey(mint(), opts, "replace");
|
|
76592
76641
|
println(c.yellow(` The previous key stops working as soon as the server restarts.
|
|
76593
|
-
` +
|
|
76642
|
+
` + ` Update every remote client, then: ${progName()} web restart`));
|
|
76594
76643
|
}
|
|
76595
76644
|
function showAction2() {
|
|
76596
76645
|
const envPath = resolveEnvFile();
|
|
@@ -76600,7 +76649,7 @@ function showAction2() {
|
|
|
76600
76649
|
println(c.dim(` none set in ${envPath}`));
|
|
76601
76650
|
println(c.dim(` The server is not gated: callers from any interface it is bound to can
|
|
76602
76651
|
` + ` reach it without a credential. That is fine while it binds 127.0.0.1.
|
|
76603
|
-
` +
|
|
76652
|
+
` + ` Mint one with: ${progName()} api-key generate`));
|
|
76604
76653
|
containerHint();
|
|
76605
76654
|
return;
|
|
76606
76655
|
}
|
|
@@ -76647,7 +76696,7 @@ function setSecret(setValue, projectRef, dryRun) {
|
|
|
76647
76696
|
println(c.dim(` (dry-run) npx supabase secrets set ${SECRET_NAME}=${shown}` + (projectRef ? ` --project-ref ${projectRef}` : "")));
|
|
76648
76697
|
return;
|
|
76649
76698
|
}
|
|
76650
|
-
const r = spawnSync7("npx", args, { encoding: "utf8", stdio: "inherit" });
|
|
76699
|
+
const r = spawnSync7("npx", args, { encoding: "utf8", stdio: "inherit", env: nestedNpxEnv() });
|
|
76651
76700
|
if (r.status !== 0) {
|
|
76652
76701
|
throw userError(`Failed to set the ${SECRET_NAME} Function secret.`, "Install the Supabase CLI and link the project (or pass --project-ref <ref>).");
|
|
76653
76702
|
}
|
|
@@ -76681,7 +76730,7 @@ function printTokenOnce(token) {
|
|
|
76681
76730
|
println(c.dim(" • Custom GPT → Configure → Actions → Authentication → API Key (Bearer)"));
|
|
76682
76731
|
println(c.dim(" • Remote HTTP MCP → the Authorization: Bearer header"));
|
|
76683
76732
|
println(c.dim(" If the GPT Actions schema changed this release, re-paste it too"));
|
|
76684
|
-
println(c.dim(
|
|
76733
|
+
println(c.dim(` (see docs/guides/connect-agents.md). Lose the token → \`${progName()} token rotate\`.`));
|
|
76685
76734
|
}
|
|
76686
76735
|
function generateAction2(opts) {
|
|
76687
76736
|
const projectRef = opts.projectRef ?? parseProjectRef2(loadSettings().supabaseUrl);
|
|
@@ -76698,7 +76747,7 @@ function rotateAction2(opts) {
|
|
|
76698
76747
|
const current = readEnvVar(envPath, LOCAL_NAME);
|
|
76699
76748
|
if (opts.finalize) {
|
|
76700
76749
|
if (!current) {
|
|
76701
|
-
throw userError(`No ${LOCAL_NAME} in ${envPath} to finalize to.`,
|
|
76750
|
+
throw userError(`No ${LOCAL_NAME} in ${envPath} to finalize to.`, `Run \`${progName()} token generate\` or \`${progName()} token rotate\` first.`);
|
|
76702
76751
|
}
|
|
76703
76752
|
println(c.bold("Finalizing rotation (dropping the previous token)…"));
|
|
76704
76753
|
setSecret(current, projectRef, opts.dryRun);
|
|
@@ -76715,14 +76764,15 @@ function rotateAction2(opts) {
|
|
|
76715
76764
|
printTokenOnce(token);
|
|
76716
76765
|
println("");
|
|
76717
76766
|
println(c.yellow(` Both the new and previous tokens are accepted right now. Update every
|
|
76718
|
-
` +
|
|
76767
|
+
` + ` client to the new token, then run \`${progName()} token rotate --finalize\`
|
|
76768
|
+
` + " to stop accepting the old one."));
|
|
76719
76769
|
}
|
|
76720
76770
|
}
|
|
76721
76771
|
function listAction2() {
|
|
76722
76772
|
const envPath = resolveEnvFile();
|
|
76723
76773
|
const local = readEnvVar(envPath, LOCAL_NAME);
|
|
76724
76774
|
println(c.bold("Cerefox access token"));
|
|
76725
|
-
println(local ? ` local (${LOCAL_NAME} in ${envPath}): ${c.green(mask2(local))}` : c.dim(` no ${LOCAL_NAME} in ${envPath} — run
|
|
76775
|
+
println(local ? ` local (${LOCAL_NAME} in ${envPath}): ${c.green(mask2(local))}` : c.dim(` no ${LOCAL_NAME} in ${envPath} — run \`${progName()} token generate\``));
|
|
76726
76776
|
println(c.dim(` The server-side accepted set (${SECRET_NAME}) is write-only; list names/digests
|
|
76727
76777
|
` + " with: npx supabase secrets list"));
|
|
76728
76778
|
}
|
|
@@ -81957,6 +82007,14 @@ var STRIP_RESPONSE_HEADERS = [
|
|
|
81957
82007
|
"proxy-authenticate",
|
|
81958
82008
|
"proxy-authorization"
|
|
81959
82009
|
];
|
|
82010
|
+
function upstreamCredentials(headers, reason, internalJwt) {
|
|
82011
|
+
const jwt = internalJwt.trim();
|
|
82012
|
+
if (reason !== "valid_key" || !jwt)
|
|
82013
|
+
return false;
|
|
82014
|
+
headers.set("authorization", `Bearer ${jwt}`);
|
|
82015
|
+
headers.set("apikey", jwt);
|
|
82016
|
+
return true;
|
|
82017
|
+
}
|
|
81960
82018
|
function registerPostgrestProxy(app) {
|
|
81961
82019
|
const upstream = (process.env.CEREFOX_POSTGREST_UPSTREAM ?? "").trim().replace(/\/+$/, "");
|
|
81962
82020
|
if (!upstream)
|
|
@@ -81968,6 +82026,7 @@ function registerPostgrestProxy(app) {
|
|
|
81968
82026
|
const headers = new Headers(c.req.raw.headers);
|
|
81969
82027
|
headers.delete("host");
|
|
81970
82028
|
headers.delete("accept-encoding");
|
|
82029
|
+
upstreamCredentials(headers, c.get("cerefoxAuthReason"), process.env.CEREFOX_SUPABASE_KEY ?? "");
|
|
81971
82030
|
const method = c.req.method;
|
|
81972
82031
|
const init = { method, headers };
|
|
81973
82032
|
if (method !== "GET" && method !== "HEAD") {
|
|
@@ -82335,7 +82394,7 @@ async function assertServerCompatible() {
|
|
|
82335
82394
|
` + parts.join(`
|
|
82336
82395
|
`) + `
|
|
82337
82396
|
|
|
82338
|
-
Redeploy your server:
|
|
82397
|
+
Redeploy your server: ${progName()} server deploy
|
|
82339
82398
|
` + `(or downgrade the client to match the deployed server).`);
|
|
82340
82399
|
}
|
|
82341
82400
|
async function buildWebServer(options = {}) {
|
|
@@ -82350,7 +82409,7 @@ async function buildWebServer(options = {}) {
|
|
|
82350
82409
|
⚠ Binding ${host} with NO API key configured.
|
|
82351
82410
|
` + ` Every read, write, delete and purge on this server is reachable by
|
|
82352
82411
|
` + ` anything that can connect to port ${port}, with no credential.
|
|
82353
|
-
` + ` Mint one:
|
|
82412
|
+
` + ` Mint one: ${progName()} api-key generate
|
|
82354
82413
|
`);
|
|
82355
82414
|
}
|
|
82356
82415
|
const app = buildApp();
|
|
@@ -82432,7 +82491,7 @@ function registerWeb(program) {
|
|
|
82432
82491
|
break;
|
|
82433
82492
|
case "port-conflict":
|
|
82434
82493
|
eprintln(`A Cerefox web daemon is already running on :${outcome.info.port} (pid ${outcome.info.pid}).
|
|
82435
|
-
` + `Stop it first (
|
|
82494
|
+
` + `Stop it first (\`${progName()} web stop\`) or start on its port.`);
|
|
82436
82495
|
process.exit(1);
|
|
82437
82496
|
break;
|
|
82438
82497
|
case "started":
|
|
@@ -82440,7 +82499,7 @@ function registerWeb(program) {
|
|
|
82440
82499
|
info(`Cerefox web started (pid ${outcome.pid}) on http://${rawOpts.host}:${port}/`);
|
|
82441
82500
|
println(` Web UI: http://${rawOpts.host}:${port}/app/`);
|
|
82442
82501
|
println(c.dim(` Logs: ${daemonPaths.logFile}`));
|
|
82443
|
-
println(c.dim(` Stop:
|
|
82502
|
+
println(c.dim(` Stop: ${progName()} web stop`));
|
|
82444
82503
|
} else {
|
|
82445
82504
|
const refusal = readStartupRefusal();
|
|
82446
82505
|
if (refusal) {
|
|
@@ -82482,7 +82541,7 @@ Full log: ${daemonPaths.logFile}`);
|
|
|
82482
82541
|
break;
|
|
82483
82542
|
case "stale":
|
|
82484
82543
|
println(c.yellow(`Cerefox web: stale pidfile — process ${status.info.pid} is not running.`));
|
|
82485
|
-
println(c.dim(` Clean up:
|
|
82544
|
+
println(c.dim(` Clean up: ${progName()} web stop (removes ${daemonPaths.pidFile})`));
|
|
82486
82545
|
break;
|
|
82487
82546
|
case "running":
|
|
82488
82547
|
if (status.responding) {
|
|
@@ -82534,16 +82593,16 @@ var RENAMED_VERBS = [
|
|
|
82534
82593
|
function registerRenameHusks(program) {
|
|
82535
82594
|
for (const [oldName, newForm] of RENAMED_VERBS) {
|
|
82536
82595
|
program.command(oldName, { hidden: true }).allowUnknownOption(true).allowExcessArguments(true).argument("[args...]", "(renamed)").action(() => {
|
|
82537
|
-
eprintln(c.yellow(`✗
|
|
82538
|
-
eprintln(` Use
|
|
82596
|
+
eprintln(c.yellow(`✗ \`${progName()} ${oldName}\` was renamed.`));
|
|
82597
|
+
eprintln(` Use \`${progName()} ${newForm}\` instead (run \`${progName()} ${newForm.split(" ")[0]} --help\`).`);
|
|
82539
82598
|
process.exit(1);
|
|
82540
82599
|
});
|
|
82541
82600
|
}
|
|
82542
82601
|
}
|
|
82543
82602
|
function buildProgram() {
|
|
82544
|
-
const
|
|
82545
|
-
const program = new Command(
|
|
82546
|
-
Resource groups (run \`${
|
|
82603
|
+
const progName2 = process.env.CEREFOX_PROG_NAME || "cerefox";
|
|
82604
|
+
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", `
|
|
82605
|
+
Resource groups (run \`${progName2} <group> --help\`):
|
|
82547
82606
|
` + ` document get · list · edit · delete · restore · ingest · ingest-dir · version {list·archive·unarchive}
|
|
82548
82607
|
` + ` project list · create · edit · delete
|
|
82549
82608
|
` + ` metadata keys · search
|
|
@@ -82566,8 +82625,8 @@ Exit codes:
|
|
|
82566
82625
|
` + ` 1 user error 3 not found (document / version / project)
|
|
82567
82626
|
` + `
|
|
82568
82627
|
Learn more:
|
|
82569
|
-
` + ` ${
|
|
82570
|
-
` + ` ${
|
|
82628
|
+
` + ` ${progName2} guides list # bundled docs (offline)
|
|
82629
|
+
` + ` ${progName2} doctor # diagnose your install
|
|
82571
82630
|
` + ` https://github.com/fstamatelopoulos/cerefox
|
|
82572
82631
|
`);
|
|
82573
82632
|
registerSearch(program);
|
|
@@ -82618,8 +82677,8 @@ Learn more:
|
|
|
82618
82677
|
moveInto(config, registerConfigGet, "get");
|
|
82619
82678
|
moveInto(config, registerConfigSet, "set");
|
|
82620
82679
|
const backup = program.command("backup").description("Backup + restore the knowledge base: create, restore.").action(() => {
|
|
82621
|
-
eprintln(c.yellow(
|
|
82622
|
-
eprintln(
|
|
82680
|
+
eprintln(c.yellow(`\`${progName()} backup\` needs a subcommand.`));
|
|
82681
|
+
eprintln(` Use \`${progName()} backup create\` or \`${progName()} backup restore\`.`);
|
|
82623
82682
|
process.exit(1);
|
|
82624
82683
|
});
|
|
82625
82684
|
moveInto(backup, registerBackup, "create");
|
|
@@ -82656,22 +82715,22 @@ async function bareEntryPoint() {
|
|
|
82656
82715
|
if (!configExists) {
|
|
82657
82716
|
println(c.yellow("⚠ No config detected."));
|
|
82658
82717
|
println("Next step:");
|
|
82659
|
-
println(" " + c.bold(
|
|
82718
|
+
println(" " + c.bold(`${progName()} init`) + " # interactive first-run setup (~2 min)");
|
|
82660
82719
|
println("");
|
|
82661
82720
|
println(c.dim("Once configured, try:"));
|
|
82662
|
-
println(c.dim(
|
|
82663
|
-
println(c.dim(
|
|
82664
|
-
println(c.dim(
|
|
82721
|
+
println(c.dim(` ${progName()} doctor # verify your install`));
|
|
82722
|
+
println(c.dim(` ${progName()} search "…" # search the KB`));
|
|
82723
|
+
println(c.dim(` ${progName()} document ingest <file> # add a doc`));
|
|
82665
82724
|
} else {
|
|
82666
82725
|
println(c.green("✓ Config detected. You're good to go."));
|
|
82667
82726
|
println("");
|
|
82668
82727
|
println("Common commands:");
|
|
82669
|
-
println(c.dim(
|
|
82670
|
-
println(c.dim(
|
|
82671
|
-
println(c.dim(
|
|
82672
|
-
println(c.dim(
|
|
82728
|
+
println(c.dim(` ${progName()} doctor # diagnose your install`));
|
|
82729
|
+
println(c.dim(` ${progName()} search "…" # search the KB`));
|
|
82730
|
+
println(c.dim(` ${progName()} document ingest <file> # add a doc`));
|
|
82731
|
+
println(c.dim(` ${progName()} configure-agent # wire up an MCP client`));
|
|
82673
82732
|
println("");
|
|
82674
|
-
println(c.dim(
|
|
82733
|
+
println(c.dim(`Run \`${progName()} --help\` for the full command list.`));
|
|
82675
82734
|
}
|
|
82676
82735
|
}
|
|
82677
82736
|
async function main() {
|