@cerefox/memory 0.8.3 → 0.9.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.
@@ -7184,7 +7184,7 @@ var exports_meta = {};
7184
7184
  __export(exports_meta, {
7185
7185
  PKG_VERSION: () => PKG_VERSION
7186
7186
  });
7187
- var PKG_VERSION = "0.8.3";
7187
+ var PKG_VERSION = "0.9.0";
7188
7188
  var init_meta = () => {};
7189
7189
 
7190
7190
  // ../../node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.js
@@ -26819,11 +26819,11 @@ async function runSyncSelfDocs(options = {}) {
26819
26819
  printTable(outcomes.filter((o) => o.status === "error").map((o) => ({ topic: o.topic, error: o.detail.slice(0, 100) })));
26820
26820
  }
26821
26821
  }
26822
- async function action15(options) {
26822
+ async function action16(options) {
26823
26823
  await runSyncSelfDocs(options);
26824
26824
  }
26825
26825
  function registerSyncSelfDocs(program2) {
26826
- program2.command("sync-self-docs").description("Ingest bundled Cerefox docs under the _cerefox-self-docs project.").option("--dry-run", "List what would be ingested without writing.").option("--project <name>", "Override the target project name.", "_cerefox-self-docs").action(action15);
26826
+ program2.command("sync-self-docs").description("Ingest bundled Cerefox docs under the _cerefox-self-docs project.").option("--dry-run", "List what would be ingested without writing.").option("--project <name>", "Override the target project name.", "_cerefox-self-docs").action(action16);
26827
26827
  }
26828
26828
  var init_sync_self_docs = __esm(() => {
26829
26829
  init_cli_core();
@@ -39930,6 +39930,7 @@ var {
39930
39930
 
39931
39931
  // src/cli/program.ts
39932
39932
  init_meta();
39933
+ init_cli_core();
39933
39934
 
39934
39935
  // src/cli/commands/backup.ts
39935
39936
  init_cli_core();
@@ -42001,6 +42002,64 @@ function registerDeployServer(program2) {
42001
42002
  program2.command("deploy-server").description("Deploy/update the Cerefox server side (schema + RPCs + Edge Functions) on Supabase.").option("--dry-run", "Print the plan + pre-flight without deploying.").option("--schema-only", "Deploy/update only the schema + RPCs (skip Edge Functions).").option("--functions-only", "Deploy only the Edge Functions (skip the schema/RPCs).").option("--project-ref <ref>", "Supabase project ref for Edge Function deploys (default: derived from CEREFOX_SUPABASE_URL).").action(action8);
42002
42003
  }
42003
42004
 
42005
+ // src/cli/commands/document-restore.ts
42006
+ init_cli_core();
42007
+ init_client();
42008
+ async function action9(documentId, options) {
42009
+ const client = getClient();
42010
+ const { data: doc, error } = await client.raw.from("cerefox_documents").select("id, title, deleted_at").eq("id", documentId).maybeSingle();
42011
+ if (error)
42012
+ throw systemError(`Lookup failed: ${error.message}`);
42013
+ if (!doc)
42014
+ throw notFound(`Document ${documentId} not found.`);
42015
+ if (!doc.deleted_at) {
42016
+ println(c.dim(`Document ${documentId} ("${doc.title}") is not soft-deleted — nothing to restore.`));
42017
+ return;
42018
+ }
42019
+ const author = resolveAuthor(options.author);
42020
+ const authorType = resolveAuthorType(options.authorType);
42021
+ if (author === "unknown") {
42022
+ warn("No --author / CEREFOX_AUTHOR_NAME set — audit log will record this restore as 'unknown'.");
42023
+ }
42024
+ await client.rpc("cerefox_restore_document", {
42025
+ p_document_id: documentId,
42026
+ p_author: author,
42027
+ p_author_type: authorType
42028
+ });
42029
+ println(c.green(`✓ Restored "${doc.title}" (id: ${documentId}) from the trash.`));
42030
+ }
42031
+ function registerDocumentRestore(parent) {
42032
+ parent.command("restore").description("Restore a soft-deleted document from the trash (inverse of `document delete`).").argument("<document-id>", "UUID of the soft-deleted document.").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").action(action9);
42033
+ }
42034
+
42035
+ // src/cli/commands/version-archive.ts
42036
+ init_cli_core();
42037
+ init_client();
42038
+ async function setArchived(versionId, archived, options) {
42039
+ const client = getClient();
42040
+ const { data, error } = await client.raw.from("cerefox_document_versions").update({ archived }).eq("id", versionId).select("document_id, version_number").maybeSingle();
42041
+ if (error)
42042
+ throw systemError(`Update failed: ${error.message}`);
42043
+ if (!data)
42044
+ throw notFound(`Version ${versionId} not found.`);
42045
+ const author = resolveAuthor(options.author);
42046
+ const authorType = resolveAuthorType(options.authorType);
42047
+ const op = archived ? "archive" : "unarchive";
42048
+ await client.raw.rpc("cerefox_create_audit_entry", {
42049
+ p_document_id: data.document_id,
42050
+ p_version_id: versionId,
42051
+ p_operation: op,
42052
+ p_author: author,
42053
+ p_author_type: authorType,
42054
+ p_description: `Version ${data.version_number} ${op}d`
42055
+ });
42056
+ println(c.green(`✓ Version ${data.version_number} (${versionId}) ${op}d.`));
42057
+ }
42058
+ function registerVersionArchive(parent) {
42059
+ 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));
42060
+ 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));
42061
+ }
42062
+
42004
42063
  // src/cli/commands/docs.ts
42005
42064
  init_cli_core();
42006
42065
  init_bundled_docs();
@@ -42012,7 +42071,7 @@ function openInBrowser(path) {
42012
42071
  println(c.dim(`(could not auto-open; the file is at: ${path})`));
42013
42072
  }
42014
42073
  }
42015
- function action9(topic, options) {
42074
+ function action10(topic, options) {
42016
42075
  const docs = listBundledDocs();
42017
42076
  if (options.list || !topic && !options.print) {
42018
42077
  if (docs.length === 0) {
@@ -42041,7 +42100,7 @@ function action9(topic, options) {
42041
42100
  openInBrowser(doc.path);
42042
42101
  }
42043
42102
  function registerDocs(program2) {
42044
- program2.command("docs").description("Open bundled Cerefox docs in your browser (or print to stdout).").argument("[topic]", "Doc topic (e.g. quickstart, connect-agents). Omit for the index.").option("--print", "Print to stdout instead of opening a browser.").option("--list", "List available topics.").action(action9);
42103
+ program2.command("docs").description("Open bundled Cerefox docs in your browser (or print to stdout).").argument("[topic]", "Doc topic (e.g. quickstart, connect-agents). Omit for the index.").option("--print", "Print to stdout instead of opening a browser.").option("--list", "List available topics.").action(action10);
42045
42104
  }
42046
42105
 
42047
42106
  // ../../node_modules/.bun/ora@9.4.0/node_modules/ora/index.js
@@ -46001,7 +46060,7 @@ function symbol(status) {
46001
46060
  return cErr.dim("ℹ");
46002
46061
  }
46003
46062
  }
46004
- async function action10(options) {
46063
+ async function action11(options) {
46005
46064
  const useSpinner = !options.json && process.stderr.isTTY;
46006
46065
  const spinner = useSpinner ? ora({ text: "Starting checks…", spinner: "dots", stream: process.stderr }).start() : null;
46007
46066
  const results = await runAllChecks({
@@ -46058,13 +46117,13 @@ async function action10(options) {
46058
46117
  }
46059
46118
  }
46060
46119
  function registerDoctor(program2) {
46061
- program2.command("doctor").description("Run diagnostic checks against the installed Cerefox.").option("--json", "Emit machine-readable JSON (no colours, structured output).").action(action10);
46120
+ program2.command("doctor").description("Run diagnostic checks against the installed Cerefox.").option("--json", "Emit machine-readable JSON (no colours, structured output).").action(action11);
46062
46121
  }
46063
46122
 
46064
46123
  // src/cli/commands/get-audit-log.ts
46065
46124
  init_cli_core();
46066
46125
  init_client();
46067
- async function action11(options) {
46126
+ async function action12(options) {
46068
46127
  const limit = parsePositiveInt(options.limit, "--limit", 50);
46069
46128
  const client = getClient();
46070
46129
  const data = await client.rpc("cerefox_list_audit_entries", {
@@ -46102,14 +46161,14 @@ async function action11(options) {
46102
46161
  })));
46103
46162
  }
46104
46163
  function registerGetAuditLog(program2) {
46105
- program2.command("get-audit-log").description("Query the audit log with optional filters.").option("-d, --document-id <uuid>", "Filter by document.").option("-a, --author <name>", "Filter by author.").option("-o, --operation <type>", "Filter by operation: create, update-content, update-metadata, delete, restore.").option("--since <iso>", "Lower-bound ISO timestamp.").option("--until <iso>", "Upper-bound ISO timestamp.").option("-l, --limit <n>", "Maximum entries (max 200).", "50").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action11);
46164
+ program2.command("get-audit-log").description("Query the audit log with optional filters.").option("-d, --document-id <uuid>", "Filter by document.").option("-a, --author <name>", "Filter by author.").option("-o, --operation <type>", "Filter by operation: create, update-content, update-metadata, delete, restore.").option("--since <iso>", "Lower-bound ISO timestamp.").option("--until <iso>", "Upper-bound ISO timestamp.").option("-l, --limit <n>", "Maximum entries (max 200).", "50").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action12);
46106
46165
  }
46107
46166
 
46108
46167
  // src/cli/commands/get-doc.ts
46109
46168
  init_cli_core();
46110
46169
  init_cli_core();
46111
46170
  init_client();
46112
- async function action12(documentId, options) {
46171
+ async function action13(documentId, options) {
46113
46172
  const client = getClient();
46114
46173
  const rows = await client.rpc("cerefox_get_document", {
46115
46174
  p_document_id: documentId,
@@ -46139,7 +46198,7 @@ async function action12(documentId, options) {
46139
46198
  println(doc.full_content);
46140
46199
  }
46141
46200
  function registerGetDoc(program2) {
46142
- program2.command("get-doc").description("Retrieve the full content of a document by ID.").argument("<document-id>", "UUID of the document.").option("--version-id <uuid>", "Specific archived version (default: current).").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action12);
46201
+ program2.command("get-doc").description("Retrieve the full content of a document by ID.").argument("<document-id>", "UUID of the document.").option("--version-id <uuid>", "Specific archived version (default: current).").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action13);
46143
46202
  }
46144
46203
 
46145
46204
  // src/cli/commands/ingest.ts
@@ -46876,7 +46935,7 @@ async function readContent(path, paste) {
46876
46935
  const titleFromPath = basename2(path, extname2(path));
46877
46936
  return { content, titleFromPath };
46878
46937
  }
46879
- async function action13(path, options) {
46938
+ async function action14(path, options) {
46880
46939
  const { content, titleFromPath } = await readContent(path, Boolean(options.paste));
46881
46940
  const title = options.title ?? titleFromPath;
46882
46941
  if (!title || title.trim() === "") {
@@ -46948,7 +47007,7 @@ async function action13(path, options) {
46948
47007
  }
46949
47008
  }
46950
47009
  function registerIngest(program2) {
46951
- program2.command("ingest").description("Ingest a file (or stdin paste) into the knowledge base.").argument("[path]", "Path to the file to ingest. Omit when using --paste.").option("--paste", "Read content from stdin instead of a file.").option("-t, --title <title>", "Document title (required with --paste; defaults to filename without extension).").option("-p, --project-name <name>", "Single project membership (non-destructive on update).").option("-P, --project-names <names>", "Comma-separated full project membership set (destructive replace on update).").option("-m, --metadata <json>", "JSON metadata object.").option("--source <label>", "Origin label (default: cli).", "cli").option("-u, --update-if-exists", "Update an existing doc with the same title.").option("-i, --document-id <uuid>", "Update a specific document by UUID (overrides --update-if-exists).").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").action(action13);
47010
+ program2.command("ingest").description("Ingest a file (or stdin paste) into the knowledge base.").argument("[path]", "Path to the file to ingest. Omit when using --paste.").option("--paste", "Read content from stdin instead of a file.").option("-t, --title <title>", "Document title (required with --paste; defaults to filename without extension).").option("-p, --project-name <name>", "Single project membership (non-destructive on update).").option("-P, --project-names <names>", "Comma-separated full project membership set (destructive replace on update).").option("-m, --metadata <json>", "JSON metadata object.").option("--source <label>", "Origin label (default: cli).", "cli").option("-u, --update-if-exists", "Update an existing doc with the same title.").option("-i, --document-id <uuid>", "Update a specific document by UUID (overrides --update-if-exists).").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").action(action14);
46952
47011
  }
46953
47012
 
46954
47013
  // src/cli/commands/ingest-dir.ts
@@ -46984,7 +47043,7 @@ function walk(dir, extensions) {
46984
47043
  }
46985
47044
  return files;
46986
47045
  }
46987
- async function action14(dir, options) {
47046
+ async function action15(dir, options) {
46988
47047
  const extensions = new Set((options.extensions ?? ".md,.txt").split(",").map((e) => e.trim().toLowerCase()).map((e) => e.startsWith(".") ? e : "." + e).filter((e) => e.length > 0));
46989
47048
  const files = walk(dir, extensions);
46990
47049
  if (files.length === 0) {
@@ -47057,7 +47116,7 @@ async function action14(dir, options) {
47057
47116
  }
47058
47117
  }
47059
47118
  function registerIngestDir(program2) {
47060
- program2.command("ingest-dir").description("Recursively ingest a directory of markdown / text files.").argument("<dir>", "Root directory to walk.").option("-p, --project-name <name>", "Project membership for all ingested docs.").option("-m, --metadata <json>", "JSON metadata applied to every doc.").option("--source <label>", "Origin label (default: cli).", "cli").option("-u, --update-if-exists", "Update an existing doc with the same title.").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").option("-e, --extensions <list>", "Comma-separated file extensions to ingest.", ".md,.txt").action(action14);
47119
+ program2.command("ingest-dir").description("Recursively ingest a directory of markdown / text files.").argument("<dir>", "Root directory to walk.").option("-p, --project-name <name>", "Project membership for all ingested docs.").option("-m, --metadata <json>", "JSON metadata applied to every doc.").option("--source <label>", "Origin label (default: cli).", "cli").option("-u, --update-if-exists", "Update an existing doc with the same title.").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").option("-e, --extensions <list>", "Comma-separated file extensions to ingest.", ".md,.txt").action(action15);
47061
47120
  }
47062
47121
 
47063
47122
  // src/cli/commands/init.ts
@@ -47387,7 +47446,7 @@ function writeAnswersTo(target, answers) {
47387
47446
  }
47388
47447
  }
47389
47448
  }
47390
- async function action16(options) {
47449
+ async function action17(options) {
47391
47450
  const homeEnv = join9(homedir5(), USER_STATE_DIR_NAME, ".env");
47392
47451
  const cwdEnv = join9(process.cwd(), ".env");
47393
47452
  const explicitDir = (process.env.CEREFOX_CONFIG_DIR ?? "").trim();
@@ -47496,13 +47555,13 @@ async function action16(options) {
47496
47555
  await postWriteLifecycle(target, options);
47497
47556
  }
47498
47557
  function registerInit(program2) {
47499
- program2.command("init").description("Interactive first-run setup (config, schema deploy stub, optional MCP wiring).").option("-c, --config <file>", "Non-interactive mode: read answers from a JSON file.").option("--force", "Overwrite existing configuration without prompting.").option("--skip-schema", "Skip the schema deploy step.").option("--skip-self-docs", "Skip the bundled self-doc ingest.").option("--skip-agent-config", "Skip the optional MCP agent wiring.").action(action16);
47558
+ program2.command("init").description("Interactive first-run setup (config, schema deploy stub, optional MCP wiring).").option("-c, --config <file>", "Non-interactive mode: read answers from a JSON file.").option("--force", "Overwrite existing configuration without prompting.").option("--skip-schema", "Skip the schema deploy step.").option("--skip-self-docs", "Skip the bundled self-doc ingest.").option("--skip-agent-config", "Skip the optional MCP agent wiring.").action(action17);
47500
47559
  }
47501
47560
 
47502
47561
  // src/cli/commands/list-docs.ts
47503
47562
  init_cli_core();
47504
47563
  init_client();
47505
- async function action17(options) {
47564
+ async function action18(options) {
47506
47565
  const limit = parsePositiveInt(options.limit, "--limit", 100);
47507
47566
  const client = getClient();
47508
47567
  let projectId;
@@ -47557,13 +47616,13 @@ async function action17(options) {
47557
47616
  })));
47558
47617
  }
47559
47618
  function registerListDocs(program2) {
47560
- program2.command("list-docs").description("List documents in the knowledge base.").option("-p, --project <name>", "Filter to a specific project.").option("-l, --limit <n>", "Maximum docs to return.", "100").option("--json", "Emit machine-readable JSON.").action(action17);
47619
+ program2.command("list-docs").description("List documents in the knowledge base.").option("-p, --project <name>", "Filter to a specific project.").option("-l, --limit <n>", "Maximum docs to return.", "100").option("--json", "Emit machine-readable JSON.").action(action18);
47561
47620
  }
47562
47621
 
47563
47622
  // src/cli/commands/list-metadata-keys.ts
47564
47623
  init_cli_core();
47565
47624
  init_client();
47566
- async function action18(options) {
47625
+ async function action19(options) {
47567
47626
  const client = getClient();
47568
47627
  const data = await client.rpc("cerefox_list_metadata_keys");
47569
47628
  if (data === null) {
@@ -47591,13 +47650,13 @@ async function action18(options) {
47591
47650
  })));
47592
47651
  }
47593
47652
  function registerListMetadataKeys(program2) {
47594
- program2.command("list-metadata-keys").description("List all metadata keys with document counts and example values.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action18);
47653
+ program2.command("list-metadata-keys").description("List all metadata keys with document counts and example values.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action19);
47595
47654
  }
47596
47655
 
47597
47656
  // src/cli/commands/list-projects.ts
47598
47657
  init_cli_core();
47599
47658
  init_client();
47600
- async function action19(options) {
47659
+ async function action20(options) {
47601
47660
  const client = getClient();
47602
47661
  const { data, error: error2 } = await client.raw.from("cerefox_projects").select("id, name, description, created_at").order("name", { ascending: true });
47603
47662
  if (error2) {
@@ -47626,13 +47685,13 @@ async function action19(options) {
47626
47685
  })), "(no projects)");
47627
47686
  }
47628
47687
  function registerListProjects(program2) {
47629
- program2.command("list-projects").description("List all projects in the knowledge base.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action19);
47688
+ program2.command("list-projects").description("List all projects in the knowledge base.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action20);
47630
47689
  }
47631
47690
 
47632
47691
  // src/cli/commands/list-versions.ts
47633
47692
  init_cli_core();
47634
47693
  init_client();
47635
- async function action20(documentId, options) {
47694
+ async function action21(documentId, options) {
47636
47695
  const client = getClient();
47637
47696
  const data = await client.rpc("cerefox_list_document_versions", {
47638
47697
  p_document_id: documentId
@@ -47673,7 +47732,7 @@ async function action20(documentId, options) {
47673
47732
  })));
47674
47733
  }
47675
47734
  function registerListVersions(program2) {
47676
- program2.command("list-versions").description("List archived versions of a document.").argument("<document-id>", "UUID of the document.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action20);
47735
+ program2.command("list-versions").description("List archived versions of a document.").argument("<document-id>", "UUID of the document.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action21);
47677
47736
  }
47678
47737
 
47679
47738
  // src/cli/commands/mcp.ts
@@ -47688,7 +47747,7 @@ function registerMcp(program2) {
47688
47747
  // src/cli/commands/metadata-search.ts
47689
47748
  init_cli_core();
47690
47749
  init_client();
47691
- async function action21(options) {
47750
+ async function action22(options) {
47692
47751
  const metadataFilter = parseJsonObjectArg(options.metadataFilter, "--metadata-filter");
47693
47752
  if (!metadataFilter || Object.keys(metadataFilter).length === 0) {
47694
47753
  throw userError("--metadata-filter is required and must be a non-empty JSON object.", `Example: --metadata-filter '{"type":"decision-log"}'.`);
@@ -47751,7 +47810,7 @@ async function action21(options) {
47751
47810
  }
47752
47811
  }
47753
47812
  function registerMetadataSearch(program2) {
47754
- program2.command("metadata-search").description("Find documents by metadata criteria (no text query).").requiredOption("-f, --metadata-filter <json>", "JSON object; only docs whose metadata contains ALL pairs are returned.").option("-p, --project-name <name>", "Filter to a specific project.").option("--updated-since <iso>", "Only docs updated on/after this ISO timestamp.").option("--created-since <iso>", "Only docs created on/after this ISO timestamp.").option("--include-content", "Include full document text in results.").option("-l, --limit <n>", "Maximum docs to return.", "10").option("--max-bytes <n>", "Response size budget in bytes (with --include-content).", "200000").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action21);
47813
+ program2.command("metadata-search").description("Find documents by metadata criteria (no text query).").requiredOption("-f, --metadata-filter <json>", "JSON object; only docs whose metadata contains ALL pairs are returned.").option("-p, --project-name <name>", "Filter to a specific project.").option("--updated-since <iso>", "Only docs updated on/after this ISO timestamp.").option("--created-since <iso>", "Only docs created on/after this ISO timestamp.").option("--include-content", "Include full document text in results.").option("-l, --limit <n>", "Maximum docs to return.", "10").option("--max-bytes <n>", "Response size budget in bytes (with --include-content).", "200000").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action22);
47755
47814
  }
47756
47815
 
47757
47816
  // src/cli/commands/reindex.ts
@@ -47759,7 +47818,7 @@ init_dist4();
47759
47818
  init_cli_core();
47760
47819
  init_config();
47761
47820
  var DEFAULT_MODEL = "text-embedding-3-small";
47762
- async function action22(options) {
47821
+ async function action23(options) {
47763
47822
  const settings = loadSettings();
47764
47823
  if (!settings.supabaseUrl || !settings.supabaseKey) {
47765
47824
  throw userError("Supabase credentials not configured — run `cerefox init` first.");
@@ -47838,7 +47897,7 @@ ${c2.content}`;
47838
47897
  }
47839
47898
  }
47840
47899
  function registerReindex(program2) {
47841
- program2.command("reindex").description("Re-embed existing document chunks (v0.7+).").option("--all", "Reindex every chunk regardless of embedder.").option("--batch <n>", "Chunks per OpenAI batch call. Capped at 96 internally.", "32").option("--dry-run", "Show counts without re-embedding.").option("-i, --document-id <uuid>", "Limit reindex to a single document.").action(action22);
47900
+ program2.command("reindex").description("Re-embed existing document chunks (v0.7+).").option("--all", "Reindex every chunk regardless of embedder.").option("--batch <n>", "Chunks per OpenAI batch call. Capped at 96 internally.", "32").option("--dry-run", "Show counts without re-embedding.").option("-i, --document-id <uuid>", "Limit reindex to a single document.").action(action23);
47842
47901
  }
47843
47902
 
47844
47903
  // src/cli/commands/restore.ts
@@ -47868,7 +47927,7 @@ function resolveBackupFile(target) {
47868
47927
  }
47869
47928
  return join10(path, candidates[0].name);
47870
47929
  }
47871
- async function action23(target, options) {
47930
+ async function action24(target, options) {
47872
47931
  const file = resolveBackupFile(target);
47873
47932
  let payload;
47874
47933
  try {
@@ -47924,7 +47983,7 @@ async function action23(target, options) {
47924
47983
  }
47925
47984
  }
47926
47985
  function registerRestore(program2) {
47927
- program2.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 ride along with each doc's metadata).").action(action23);
47986
+ program2.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 ride along with each doc's metadata).").action(action24);
47928
47987
  }
47929
47988
 
47930
47989
  // src/cli/commands/search.ts
@@ -47949,7 +48008,7 @@ async function embedQuery(query) {
47949
48008
  }
47950
48009
 
47951
48010
  // src/cli/commands/search.ts
47952
- async function action24(query, options) {
48011
+ async function action25(query, options) {
47953
48012
  if (!query || query.trim() === "") {
47954
48013
  throw userError("Empty query.");
47955
48014
  }
@@ -48083,7 +48142,7 @@ async function action24(query, options) {
48083
48142
  }
48084
48143
  }
48085
48144
  function registerSearch(program2) {
48086
- program2.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: 0.7).", "0.7").option("--min-score <float>", "Minimum cosine similarity threshold.", "0.5").option("--max-bytes <n>", "Response size budget in bytes.", "200000").option("-r, --requestor <name>", "Agent / user name (recorded in usage log).").option("--json", "Emit machine-readable JSON instead of the default text.").action(action24);
48145
+ program2.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: 0.7).", "0.7").option("--min-score <float>", "Minimum cosine similarity threshold.", "0.5").option("--max-bytes <n>", "Response size budget in bytes.", "200000").option("-r, --requestor <name>", "Agent / user name (recorded in usage log).").option("--json", "Emit machine-readable JSON instead of the default text.").action(action25);
48087
48146
  }
48088
48147
 
48089
48148
  // src/cli/commands/self-update.ts
@@ -48130,7 +48189,7 @@ async function fetchLatestVersion() {
48130
48189
  }
48131
48190
  return body.version;
48132
48191
  }
48133
- async function action25(options) {
48192
+ async function action26(options) {
48134
48193
  let target;
48135
48194
  try {
48136
48195
  target = options.version ?? await fetchLatestVersion();
@@ -48182,7 +48241,7 @@ async function action25(options) {
48182
48241
  }
48183
48242
  function registerSelfUpdate(program2) {
48184
48243
  const desc = "Upgrade Cerefox in place. Alias: `cerefox upgrade`.";
48185
- 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(action25);
48244
+ 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(action26);
48186
48245
  declaration(program2.command("self-update"));
48187
48246
  declaration(program2.command("upgrade"));
48188
48247
  }
@@ -48201,7 +48260,7 @@ function symbol2(status) {
48201
48260
  return cErr.dim("ℹ");
48202
48261
  }
48203
48262
  }
48204
- async function action26(options) {
48263
+ async function action27(options) {
48205
48264
  const useSpinner = !options.json && process.stderr.isTTY;
48206
48265
  const spinner = useSpinner ? ora({ text: "Starting checks…", spinner: "dots", stream: process.stderr }).start() : null;
48207
48266
  const results = await runFastChecks({
@@ -48222,7 +48281,7 @@ async function action26(options) {
48222
48281
  }
48223
48282
  }
48224
48283
  function registerStatus(program2) {
48225
- program2.command("status").description("Quick sanity check (fast subset of `cerefox doctor`).").option("--json", "Emit machine-readable JSON.").action(action26);
48284
+ program2.command("status").description("Quick sanity check (fast subset of `cerefox doctor`).").option("--json", "Emit machine-readable JSON.").action(action27);
48226
48285
  }
48227
48286
 
48228
48287
  // src/cli/commands/sync-docs.ts
@@ -48258,7 +48317,7 @@ function walkMarkdown(dir) {
48258
48317
  }
48259
48318
  return out;
48260
48319
  }
48261
- async function action27(options) {
48320
+ async function action28(options) {
48262
48321
  const cwd = process.cwd();
48263
48322
  const project = options.project ?? "cerefox";
48264
48323
  const targets = [];
@@ -48320,7 +48379,7 @@ async function action27(options) {
48320
48379
  }
48321
48380
  }
48322
48381
  function registerSyncDocs(program2) {
48323
- program2.command("sync-docs").description("Sync repo docs (README, AGENT_*, docs/) into a Cerefox project.").option("--dry-run", "Print what would be synced without writing.").option("-p, --project <name>", "Target project for the sync.", "cerefox").action(action27);
48382
+ program2.command("sync-docs").description("Sync repo docs (README, AGENT_*, docs/) into a Cerefox project.").option("--dry-run", "Print what would be synced without writing.").option("-p, --project <name>", "Target project for the sync.", "cerefox").action(action28);
48324
48383
  }
48325
48384
 
48326
48385
  // src/cli/program.ts
@@ -53313,15 +53372,56 @@ function registerWeb(program2) {
53313
53372
  }
53314
53373
 
53315
53374
  // src/cli/program.ts
53375
+ function moveInto(parent, register, newName) {
53376
+ register(parent);
53377
+ const cmd = parent.commands[parent.commands.length - 1];
53378
+ cmd.name(newName);
53379
+ return cmd;
53380
+ }
53381
+ var RENAMED_VERBS = [
53382
+ ["get-doc", "document get"],
53383
+ ["list-docs", "document list"],
53384
+ ["delete-doc", "document delete"],
53385
+ ["ingest", "document ingest"],
53386
+ ["ingest-dir", "document ingest-dir"],
53387
+ ["list-projects", "project list"],
53388
+ ["delete-project", "project delete"],
53389
+ ["list-versions", "version list"],
53390
+ ["get-audit-log", "audit list"],
53391
+ ["list-metadata-keys", "metadata keys"],
53392
+ ["metadata-search", "metadata search"],
53393
+ ["config-get", "config get"],
53394
+ ["config-set", "config set"],
53395
+ ["restore", "backup restore"],
53396
+ ["deploy-server", "server deploy"],
53397
+ ["reindex", "server reindex"]
53398
+ ];
53399
+ function registerRenameHusks(program2) {
53400
+ for (const [oldName, newForm] of RENAMED_VERBS) {
53401
+ program2.command(oldName, { hidden: true }).allowUnknownOption(true).allowExcessArguments(true).argument("[args...]", "(renamed)").action(() => {
53402
+ eprintln(c.yellow(`✗ \`cerefox ${oldName}\` was renamed in v0.9.0.`));
53403
+ eprintln(` Use \`cerefox ${newForm}\` instead (run \`cerefox ${newForm.split(" ")[0]} --help\`).`);
53404
+ process.exit(1);
53405
+ });
53406
+ }
53407
+ }
53316
53408
  function buildProgram() {
53317
- const program2 = new Command("cerefox").description("Cerefox — user-owned shared memory for AI agents.").version(PKG_VERSION, "-v, --version", "Print the cerefox 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 `cerefox --help` for usage)").enablePositionalOptions().addHelpText("after", `
53318
- Command groups (each row in the list above falls into one):
53319
- ` + ` READS search · get-doc · list-docs · list-versions · list-projects
53320
- ` + ` · list-metadata-keys · metadata-search · get-audit-log
53321
- ` + ` WRITES ingest · ingest-dir · delete-doc · delete-project
53322
- ` + ` SERVERS mcp · web
53323
- ` + ` LIFECYCLE init · doctor · status · configure-agent · self-update · upgrade · sync-self-docs · deploy-server
53324
- ` + ` OPS backup · restore · sync-docs · docs · reindex · config-get · config-set · completion
53409
+ const program2 = new Command("cerefox").description("Cerefox — user-owned shared memory for AI agents.").version(PKG_VERSION, "-v, --version", "Print the cerefox 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 `cerefox --help` for usage)").enablePositionalOptions().addHelpText("after", "\nResource groups (run `cerefox <group> --help`):\n" + ` document get · list · delete · ingest · ingest-dir
53410
+ ` + ` project list · delete
53411
+ ` + ` version list
53412
+ ` + ` metadata keys · search
53413
+ ` + ` audit list
53414
+ ` + ` config get · set
53415
+ ` + ` backup create · restore
53416
+ ` + ` server deploy · reindex
53417
+ ` + `
53418
+ Top-level commands:
53419
+ ` + ` search · init · doctor · status · configure-agent · self-update
53420
+ ` + ` mcp · web · docs · completion · sync-docs · sync-self-docs
53421
+ ` + `
53422
+ Renamed in v0.9.0: the old flat verbs (get-doc, list-docs, ingest, …)
53423
+ ` + ` now live under the groups above. The old names still run but exit with
53424
+ ` + ` a pointer to the new form. They are removed in v1.0.
53325
53425
  ` + `
53326
53426
  Exit codes:
53327
53427
  ` + ` 0 success 2 system error (unreachable Supabase, RPC failure, …)
@@ -53333,34 +53433,49 @@ Learn more:
53333
53433
  ` + ` https://github.com/fstamatelopoulos/cerefox
53334
53434
  `);
53335
53435
  registerSearch(program2);
53336
- registerGetDoc(program2);
53337
- registerListDocs(program2);
53338
- registerListVersions(program2);
53339
- registerListProjects(program2);
53340
- registerListMetadataKeys(program2);
53341
- registerMetadataSearch(program2);
53342
- registerGetAuditLog(program2);
53343
- registerIngest(program2);
53344
- registerIngestDir(program2);
53345
- registerDeleteDoc(program2);
53346
- registerDeleteProject(program2);
53347
- registerMcp(program2);
53348
- registerWeb(program2);
53349
53436
  registerInit(program2);
53350
53437
  registerDoctor(program2);
53351
53438
  registerStatus(program2);
53352
53439
  registerConfigureAgent(program2);
53353
53440
  registerSelfUpdate(program2);
53354
- registerSyncSelfDocs(program2);
53355
- registerDeployServer(program2);
53356
- registerBackup(program2);
53357
- registerRestore(program2);
53358
- registerSyncDocs(program2);
53441
+ registerMcp(program2);
53442
+ registerWeb(program2);
53359
53443
  registerDocs(program2);
53360
- registerReindex(program2);
53361
- registerConfigGet(program2);
53362
- registerConfigSet(program2);
53363
53444
  registerCompletion(program2);
53445
+ registerSyncDocs(program2);
53446
+ registerSyncSelfDocs(program2);
53447
+ const document2 = program2.command("document").description("Documents: get, list, delete, ingest.");
53448
+ moveInto(document2, registerGetDoc, "get");
53449
+ moveInto(document2, registerListDocs, "list");
53450
+ moveInto(document2, registerDeleteDoc, "delete");
53451
+ registerDocumentRestore(document2);
53452
+ moveInto(document2, registerIngest, "ingest");
53453
+ moveInto(document2, registerIngestDir, "ingest-dir");
53454
+ const project = program2.command("project").description("Projects: list, delete.");
53455
+ moveInto(project, registerListProjects, "list");
53456
+ moveInto(project, registerDeleteProject, "delete");
53457
+ const version4 = program2.command("version").description("Document version history: list, archive, unarchive.");
53458
+ moveInto(version4, registerListVersions, "list");
53459
+ registerVersionArchive(version4);
53460
+ const metadata = program2.command("metadata").description("Metadata: keys, search.");
53461
+ moveInto(metadata, registerListMetadataKeys, "keys");
53462
+ moveInto(metadata, registerMetadataSearch, "search");
53463
+ const audit = program2.command("audit").description("Audit log: list.");
53464
+ moveInto(audit, registerGetAuditLog, "list");
53465
+ const config2 = program2.command("config").description("Runtime config: get, set.");
53466
+ moveInto(config2, registerConfigGet, "get");
53467
+ moveInto(config2, registerConfigSet, "set");
53468
+ const backup = program2.command("backup").description("Backup + restore the knowledge base: create, restore.").action(() => {
53469
+ eprintln(c.yellow("`cerefox backup` needs a subcommand."));
53470
+ eprintln(" Use `cerefox backup create` or `cerefox backup restore`.");
53471
+ process.exit(1);
53472
+ });
53473
+ moveInto(backup, registerBackup, "create");
53474
+ moveInto(backup, registerRestore, "restore");
53475
+ const server = program2.command("server").description("Server side: deploy, reindex.");
53476
+ moveInto(server, registerDeployServer, "deploy");
53477
+ moveInto(server, registerReindex, "reindex");
53478
+ registerRenameHusks(program2);
53364
53479
  return program2;
53365
53480
  }
53366
53481
 
@@ -177,7 +177,7 @@ paths.
177
177
  | Tier | Operations | Reversible? | Where exposed |
178
178
  |---|---|---|---|
179
179
  | 1. Reads + soft mutations | search, get, list-*, ingest (create/update), metadata-search, get-audit-log | n/a (reads) / yes (versioned) | All paths — MCP, Edge Functions, CLI, web UI |
180
- | 2. Soft-destructive | `delete_document` (soft delete to trash), `set_review_status` | yes — restorable via web UI | All paths (CLI: `cerefox delete-doc`; web UI; Python; **not** MCP or Edge Functions today) |
180
+ | 2. Soft-destructive | `delete_document` (soft delete to trash), `set_review_status` | yes — restorable via web UI | All paths (CLI: `cerefox document delete`; web UI; Python; **not** MCP or Edge Functions today) |
181
181
  | 3. **Hard-destructive** | `purge_document` (permanent), `restore_document` (un-trash), `set_version_archived` (toggle version retention) | no (purge) / yes (restore, but recovers from a destructive action) | **Web UI only** |
182
182
 
183
183
  ### Why purge / restore are web-UI-only
@@ -210,7 +210,7 @@ clear before the operation actually runs).
210
210
 
211
211
  If you're building tooling that uses the CLI (Path C) or any MCP/Edge Function path:
212
212
 
213
- - **Use `cerefox delete-doc` freely** to soft-delete agent-authored content. Pair it
213
+ - **Use `cerefox document delete` freely** to soft-delete agent-authored content. Pair it
214
214
  with `--author <name> --author-type agent` so the audit trail is correct.
215
215
  - **Surface the soft-delete to the user.** When your agent decides to delete something,
216
216
  tell the user explicitly: "I soft-deleted X (recoverable from the Cerefox trash in
@@ -221,13 +221,13 @@ If you're building tooling that uses the CLI (Path C) or any MCP/Edge Function p
221
221
 
222
222
  ### CLI delete-doc — interactive vs scripted
223
223
 
224
- `cerefox delete-doc` prompts for confirmation by default (since `click.confirm` requires
224
+ `cerefox document delete` prompts for confirmation by default (since `click.confirm` requires
225
225
  a TTY, an agent's Bash tool will get an abort instead of accidentally deleting). Agents
226
226
  that legitimately need to soft-delete must pass `--yes` *and* set `--author` /
227
227
  `--author-type` so the audit log captures who acted:
228
228
 
229
229
  ```bash
230
- cerefox delete-doc <doc-id> --yes \
230
+ cerefox document delete <doc-id> --yes \
231
231
  --author "claude-code" --author-type "agent"
232
232
  ```
233
233
 
@@ -16,14 +16,14 @@ Invoke any command with `uv run cerefox <subcommand>`. Inside an activated venv,
16
16
 
17
17
  ## Commands
18
18
 
19
- ### `cerefox ingest`
19
+ ### `cerefox document ingest`
20
20
 
21
21
  **Purpose**: ingest a markdown / PDF / DOCX file (or stdin) into the knowledge base.
22
22
 
23
23
  **Synopsis**:
24
24
  ```
25
- cerefox ingest [OPTIONS] [PATH]
26
- cerefox ingest --paste --title "<title>" [OPTIONS] # stdin
25
+ cerefox document ingest [OPTIONS] [PATH]
26
+ cerefox document ingest --paste --title "<title>" [OPTIONS] # stdin
27
27
  ```
28
28
 
29
29
  **Options**:
@@ -45,18 +45,18 @@ cerefox ingest --paste --title "<title>" [OPTIONS] # stdin
45
45
  **Examples**:
46
46
  ```bash
47
47
  # Minimal: ingest a file
48
- cerefox ingest notes.md
48
+ cerefox document ingest notes.md
49
49
 
50
50
  # Paste from stdin
51
- printf '# Title\n\nbody' | cerefox ingest --paste --title "Title"
51
+ printf '# Title\n\nbody' | cerefox document ingest --paste --title "Title"
52
52
 
53
53
  # Agent ingestion with full attribution
54
- cerefox ingest notes.md \
54
+ cerefox document ingest notes.md \
55
55
  --author "claude-code" --author-type "agent" \
56
56
  --project-name "research" --metadata '{"type":"design-doc"}'
57
57
 
58
58
  # Deterministic update (preferred — agents should search → grab ID → ingest)
59
- cerefox ingest --paste --title "Same Title" \
59
+ cerefox document ingest --paste --title "Same Title" \
60
60
  --document-id "abc12345-..." \
61
61
  --author "claude-code" --author-type "agent"
62
62
  ```
@@ -69,13 +69,13 @@ cerefox ingest --paste --title "Same Title" \
69
69
 
70
70
  ---
71
71
 
72
- ### `cerefox ingest-dir`
72
+ ### `cerefox document ingest-dir`
73
73
 
74
74
  **Purpose**: bulk-ingest every matching file in a directory.
75
75
 
76
76
  **Synopsis**:
77
77
  ```
78
- cerefox ingest-dir [OPTIONS] DIRECTORY
78
+ cerefox document ingest-dir [OPTIONS] DIRECTORY
79
79
  ```
80
80
 
81
81
  **Options**:
@@ -94,11 +94,11 @@ cerefox ingest-dir [OPTIONS] DIRECTORY
94
94
  **Examples**:
95
95
  ```bash
96
96
  # Bulk import research notes with shared metadata
97
- cerefox ingest-dir ./research-notes --recursive \
97
+ cerefox document ingest-dir ./research-notes --recursive \
98
98
  --project-name "research" --metadata '{"type":"research","status":"active"}'
99
99
 
100
100
  # Re-ingest after editing files
101
- cerefox ingest-dir ./notes --update-if-exists
101
+ cerefox document ingest-dir ./notes --update-if-exists
102
102
  ```
103
103
 
104
104
  **Output**: one line per file showing `✓` (ingested), `↑` (updated), `⏭` (skipped: hash match), or `❌` (error); summary at the end.
@@ -143,27 +143,27 @@ cerefox search "what we tried" --mode semantic --requestor "claude-code"
143
143
 
144
144
  ---
145
145
 
146
- ### `cerefox get-doc`
146
+ ### `cerefox document get`
147
147
 
148
148
  **Purpose**: print the full markdown content of a document to stdout.
149
149
 
150
150
  **Synopsis**:
151
151
  ```
152
- cerefox get-doc [OPTIONS] DOCUMENT_ID
152
+ cerefox document get [OPTIONS] DOCUMENT_ID
153
153
  ```
154
154
 
155
155
  **Options**:
156
156
 
157
157
  | Flag | Type | Default | Description |
158
158
  |---|---|---|---|
159
- | `--version-id TEXT` (alias: `--version`) | UUID | _none_ (current) | Archived version UUID — get from `cerefox list-versions`. |
159
+ | `--version-id TEXT` (alias: `--version`) | UUID | _none_ (current) | Archived version UUID — get from `cerefox version list`. |
160
160
  | `--requestor TEXT` | str | `CEREFOX_REQUESTOR_NAME` or `user` | Identity recorded in the usage log. |
161
161
 
162
162
  **Examples**:
163
163
  ```bash
164
- cerefox get-doc abc12345-...
165
- cerefox get-doc abc12345-... --version-id <version-uuid> # archived
166
- cerefox get-doc abc12345-... | bat -l md # pipe to viewer
164
+ cerefox document get abc12345-...
165
+ cerefox document get abc12345-... --version-id <version-uuid> # archived
166
+ cerefox document get abc12345-... | bat -l md # pipe to viewer
167
167
  ```
168
168
 
169
169
  **Output**: title + metadata line, blank line, then raw markdown.
@@ -172,13 +172,13 @@ cerefox get-doc abc12345-... | bat -l md # pipe to viewer
172
172
 
173
173
  ---
174
174
 
175
- ### `cerefox list-docs`
175
+ ### `cerefox document list`
176
176
 
177
177
  **Purpose**: list documents in the knowledge base.
178
178
 
179
179
  **Synopsis**:
180
180
  ```
181
- cerefox list-docs [OPTIONS]
181
+ cerefox document list [OPTIONS]
182
182
  ```
183
183
 
184
184
  **Options**:
@@ -192,13 +192,13 @@ cerefox list-docs [OPTIONS]
192
192
 
193
193
  ---
194
194
 
195
- ### `cerefox list-versions`
195
+ ### `cerefox version list`
196
196
 
197
197
  **Purpose**: list all archived versions of a document.
198
198
 
199
199
  **Synopsis**:
200
200
  ```
201
- cerefox list-versions [OPTIONS] DOCUMENT_ID
201
+ cerefox version list [OPTIONS] DOCUMENT_ID
202
202
  ```
203
203
 
204
204
  **Options**:
@@ -207,19 +207,19 @@ cerefox list-versions [OPTIONS] DOCUMENT_ID
207
207
  |---|---|---|---|
208
208
  | `--requestor TEXT` | str | `CEREFOX_REQUESTOR_NAME` or `user` | Identity recorded in the usage log. |
209
209
 
210
- **Output**: table with version number, created timestamp, source, chunk/char counts, and version UUID. Pass the UUID to `cerefox get-doc --version-id <uuid>` to retrieve the archived content.
210
+ **Output**: table with version number, created timestamp, source, chunk/char counts, and version UUID. Pass the UUID to `cerefox document get --version-id <uuid>` to retrieve the archived content.
211
211
 
212
212
  **MCP equivalent**: [`cerefox_list_versions`](../../AGENT_GUIDE.md).
213
213
 
214
214
  ---
215
215
 
216
- ### `cerefox list-projects`
216
+ ### `cerefox project list`
217
217
 
218
218
  **Purpose**: list all projects.
219
219
 
220
220
  **Synopsis**:
221
221
  ```
222
- cerefox list-projects [OPTIONS]
222
+ cerefox project list [OPTIONS]
223
223
  ```
224
224
 
225
225
  **Options**:
@@ -232,23 +232,23 @@ cerefox list-projects [OPTIONS]
232
232
 
233
233
  ---
234
234
 
235
- ### `cerefox list-metadata-keys`
235
+ ### `cerefox metadata keys`
236
236
 
237
237
  **Purpose**: discover metadata keys used across all documents (with example values and document counts).
238
238
 
239
- **Synopsis**: `cerefox list-metadata-keys`
239
+ **Synopsis**: `cerefox metadata keys`
240
240
 
241
241
  **MCP equivalent**: [`cerefox_list_metadata_keys`](../../AGENT_GUIDE.md).
242
242
 
243
243
  ---
244
244
 
245
- ### `cerefox metadata-search`
245
+ ### `cerefox metadata search`
246
246
 
247
247
  **Purpose**: find documents by metadata key-value criteria (no text query needed).
248
248
 
249
249
  **Synopsis**:
250
250
  ```
251
- cerefox metadata-search --metadata-filter '<json>' [OPTIONS]
251
+ cerefox metadata search --metadata-filter '<json>' [OPTIONS]
252
252
  ```
253
253
 
254
254
  **Options**:
@@ -265,21 +265,21 @@ cerefox metadata-search --metadata-filter '<json>' [OPTIONS]
265
265
 
266
266
  **Examples**:
267
267
  ```bash
268
- cerefox metadata-search --metadata-filter '{"type":"decision-log"}' --updated-since 2026-05-01
269
- cerefox metadata-search --metadata-filter '{"status":"active"}' --project-name "research" --include-content
268
+ cerefox metadata search --metadata-filter '{"type":"decision-log"}' --updated-since 2026-05-01
269
+ cerefox metadata search --metadata-filter '{"status":"active"}' --project-name "research" --include-content
270
270
  ```
271
271
 
272
272
  **MCP equivalent**: [`cerefox_metadata_search`](../../AGENT_GUIDE.md).
273
273
 
274
274
  ---
275
275
 
276
- ### `cerefox get-audit-log`
276
+ ### `cerefox audit list`
277
277
 
278
278
  **Purpose**: query the immutable audit log (who changed what, when).
279
279
 
280
280
  **Synopsis**:
281
281
  ```
282
- cerefox get-audit-log [OPTIONS]
282
+ cerefox audit list [OPTIONS]
283
283
  ```
284
284
 
285
285
  **Options**:
@@ -298,24 +298,24 @@ cerefox get-audit-log [OPTIONS]
298
298
  **Examples**:
299
299
  ```bash
300
300
  # All audit entries in the last week
301
- cerefox get-audit-log --since 2026-05-11
301
+ cerefox audit list --since 2026-05-11
302
302
 
303
303
  # All edits by a specific agent
304
- cerefox get-audit-log --author "claude-code" --operation update-content
304
+ cerefox audit list --author "claude-code" --operation update-content
305
305
 
306
306
  # JSON output, piped to jq
307
- cerefox get-audit-log --json --limit 1000 | jq 'select(.author_type == "agent")'
307
+ cerefox audit list --json --limit 1000 | jq 'select(.author_type == "agent")'
308
308
  ```
309
309
 
310
310
  **MCP equivalent**: [`cerefox_get_audit_log`](../../AGENT_GUIDE.md).
311
311
 
312
312
  ---
313
313
 
314
- ### `cerefox delete-doc`
314
+ ### `cerefox document delete`
315
315
 
316
316
  **Purpose**: **soft-delete** a document — moves it to trash, recoverable. The CLI cannot permanently delete or restore; see [Destructive operations and the trust model](access-paths.md#destructive-operations-and-the-trust-model) for the rationale.
317
317
 
318
- **Synopsis**: `cerefox delete-doc [OPTIONS] DOCUMENT_ID`
318
+ **Synopsis**: `cerefox document delete [OPTIONS] DOCUMENT_ID`
319
319
 
320
320
  **Options**:
321
321
 
@@ -327,7 +327,7 @@ cerefox get-audit-log --json --limit 1000 | jq 'select(.author_type == "agent")'
327
327
 
328
328
  **What this command does:**
329
329
  - Sets `deleted_at` on the document row. The document stays in the database.
330
- - Excludes the document from search and from `cerefox list-docs`.
330
+ - Excludes the document from search and from `cerefox document list`.
331
331
  - Writes an immutable `delete` audit-log entry with the resolved author / author_type and timestamp.
332
332
 
333
333
  **What this command does NOT do:**
@@ -340,7 +340,7 @@ cerefox get-audit-log --json --limit 1000 | jq 'select(.author_type == "agent")'
340
340
  **Agent usage**:
341
341
  ```bash
342
342
  # Required: --yes (no TTY for confirmation) + identity flags
343
- cerefox delete-doc <doc-id> --yes \
343
+ cerefox document delete <doc-id> --yes \
344
344
  --author "claude-code" --author-type "agent"
345
345
  ```
346
346
  The success message echoes the resolved author / author_type back so you can surface it to the user in your response.
@@ -349,11 +349,11 @@ The success message echoes the resolved author / author_type back so you can sur
349
349
 
350
350
  ---
351
351
 
352
- ### `cerefox reindex`
352
+ ### `cerefox server reindex`
353
353
 
354
354
  **Purpose**: re-embed chunks (e.g. after switching embedding models or pulling a schema change like title-boosting).
355
355
 
356
- **Synopsis**: `cerefox reindex [OPTIONS]`
356
+ **Synopsis**: `cerefox server reindex [OPTIONS]`
357
357
 
358
358
  **Options**:
359
359
 
@@ -365,14 +365,14 @@ The success message echoes the resolved author / author_type back so you can sur
365
365
 
366
366
  ---
367
367
 
368
- ### `cerefox config-get` / `cerefox config-set`
368
+ ### `cerefox config get` / `cerefox config set`
369
369
 
370
370
  **Purpose**: read/write runtime config in `cerefox_config` (e.g. `usage_tracking_enabled`).
371
371
 
372
372
  **Synopsis**:
373
373
  ```
374
- cerefox config-get KEY
375
- cerefox config-set KEY VALUE
374
+ cerefox config get KEY
375
+ cerefox config set KEY VALUE
376
376
  ```
377
377
 
378
378
  Used for toggling features at runtime without a redeploy — see [Decision Log Q1 Part 2 — usage tracking opt-in](https://github.com/fstamatelopoulos/cerefox) entry.
@@ -436,14 +436,14 @@ Every MCP parameter has an exact-name CLI flag (kebab-cased). Short forms exist
436
436
  | MCP tool | CLI command |
437
437
  |---|---|
438
438
  | `cerefox_search(query, match_count, project_name, metadata_filter, requestor)` | `cerefox search "<q>" --match-count N --project-name <name> --metadata-filter '<json>' --requestor <name>` |
439
- | `cerefox_ingest(title, content, project_name, metadata, update_if_exists, document_id, source, author, author_type)` (file) | `cerefox ingest <path> --title <t> --project-name <n> --metadata '<json>' --update-if-exists\|--document-id <uuid> --source <s> --author <a> --author-type <t>` |
440
- | `cerefox_ingest(...)` (paste) | `printf '...' \| cerefox ingest --paste --title "<t>"` (same flags) |
441
- | `cerefox_get_document(document_id, version_id, requestor)` | `cerefox get-doc <id> --version-id <vid> --requestor <name>` |
442
- | `cerefox_list_versions(document_id, requestor)` | `cerefox list-versions <id> --requestor <name>` |
443
- | `cerefox_list_projects(requestor)` | `cerefox list-projects --requestor <name>` |
444
- | `cerefox_list_metadata_keys()` | `cerefox list-metadata-keys` |
445
- | `cerefox_metadata_search(metadata_filter, project_name, updated_since, created_since, limit, include_content, requestor)` | `cerefox metadata-search --metadata-filter '<json>' --project-name <n> --updated-since <iso> --created-since <iso> --limit N --include-content --requestor <name>` |
446
- | `cerefox_get_audit_log(document_id, author, operation, since, until, limit, requestor)` | `cerefox get-audit-log --document-id <id> --author <a> --operation <op> --since <iso> --until <iso> --limit N --requestor <name>` |
439
+ | `cerefox_ingest(title, content, project_name, metadata, update_if_exists, document_id, source, author, author_type)` (file) | `cerefox document ingest <path> --title <t> --project-name <n> --metadata '<json>' --update-if-exists\|--document-id <uuid> --source <s> --author <a> --author-type <t>` |
440
+ | `cerefox_ingest(...)` (paste) | `printf '...' \| cerefox document ingest --paste --title "<t>"` (same flags) |
441
+ | `cerefox_get_document(document_id, version_id, requestor)` | `cerefox document get <id> --version-id <vid> --requestor <name>` |
442
+ | `cerefox_list_versions(document_id, requestor)` | `cerefox version list <id> --requestor <name>` |
443
+ | `cerefox_list_projects(requestor)` | `cerefox project list --requestor <name>` |
444
+ | `cerefox_list_metadata_keys()` | `cerefox metadata keys` |
445
+ | `cerefox_metadata_search(metadata_filter, project_name, updated_since, created_since, limit, include_content, requestor)` | `cerefox metadata search --metadata-filter '<json>' --project-name <n> --updated-since <iso> --created-since <iso> --limit N --include-content --requestor <name>` |
446
+ | `cerefox_get_audit_log(document_id, author, operation, since, until, limit, requestor)` | `cerefox audit list --document-id <id> --author <a> --operation <op> --since <iso> --until <iso> --limit N --requestor <name>` |
447
447
 
448
448
  ## Known issues
449
449
 
@@ -453,7 +453,7 @@ None outstanding as of v0.1.17 (cerefox#27 — the `cerefox search` NameError
453
453
 
454
454
  ### Bulk-import a directory with shared metadata
455
455
  ```bash
456
- cerefox ingest-dir ./papers --recursive --pattern '*.pdf' \
456
+ cerefox document ingest-dir ./papers --recursive --pattern '*.pdf' \
457
457
  --project-name "literature" \
458
458
  --metadata '{"type":"paper","status":"reviewed"}'
459
459
  ```
@@ -465,7 +465,7 @@ cerefox search "the OAuth design doc" --match-count 1
465
465
 
466
466
  # Step 2: copy the id from `Doc: ... (id: <uuid>)` line
467
467
  # Step 3: update in place
468
- printf '%s' "$NEW_CONTENT" | cerefox ingest --paste \
468
+ printf '%s' "$NEW_CONTENT" | cerefox document ingest --paste \
469
469
  --title "OAuth 2.1 Design Document" \
470
470
  --document-id "<uuid>" \
471
471
  --author "claude-code" --author-type "agent"
@@ -474,7 +474,7 @@ printf '%s' "$NEW_CONTENT" | cerefox ingest --paste \
474
474
  ### Unattended sync job
475
475
  ```bash
476
476
  # In a cron job / launchd plist. Set CEREFOX_AUTHOR_NAME=sync-script in env.
477
- cd /path/to/cerefox && uv run cerefox ingest-dir ~/notes --recursive --update-if-exists
477
+ cd /path/to/cerefox && uv run cerefox document ingest-dir ~/notes --recursive --update-if-exists
478
478
  ```
479
479
 
480
480
  ### Use the CLI from an agent's Bash tool
@@ -121,7 +121,7 @@ The `metadata_filter` search parameter (available in all search modes, all acces
121
121
  - All key-value pairs must match (AND semantics via PostgreSQL `@>` operator)
122
122
  - Uses the existing GIN index on `cerefox_documents.metadata` — no additional schema changes needed
123
123
  - `NULL` filter = no restriction (backwards-compatible default)
124
- - Discover available keys via `cerefox_list_metadata_keys` MCP tool or `cerefox list-metadata-keys` CLI
124
+ - Discover available keys via `cerefox_list_metadata_keys` MCP tool or `cerefox metadata keys` CLI
125
125
 
126
126
  Access paths:
127
127
  - **MCP tool**: `metadata_filter` argument on `cerefox_search`
@@ -209,8 +209,8 @@ Metadata-only updates (same content, different title or project) do **not** crea
209
209
 
210
210
  To view and retrieve previous versions:
211
211
  ```bash
212
- uv run cerefox list-versions <document-id>
213
- uv run cerefox get-doc <document-id> --version <version-id>
212
+ uv run cerefox version list <document-id>
213
+ uv run cerefox document get <document-id> --version <version-id>
214
214
  ```
215
215
 
216
216
  ---
@@ -281,7 +281,7 @@ Change `CEREFOX_OPENAI_EMBEDDING_MODEL` and `CEREFOX_OPENAI_EMBEDDING_DIMENSIONS
281
281
  ### Step 2 — Re-embed all stored chunks
282
282
 
283
283
  ```bash
284
- uv run cerefox reindex
284
+ uv run cerefox server reindex
285
285
  ```
286
286
 
287
287
  This re-embeds every chunk in the database using the model now configured in `.env`.
@@ -351,13 +351,13 @@ This means:
351
351
  **Via CLI:**
352
352
  ```bash
353
353
  # Enable
354
- cerefox config-set usage_tracking_enabled true
354
+ cerefox config set usage_tracking_enabled true
355
355
 
356
356
  # Disable
357
- cerefox config-set usage_tracking_enabled false
357
+ cerefox config set usage_tracking_enabled false
358
358
 
359
359
  # Check current state
360
- cerefox config-get usage_tracking_enabled
360
+ cerefox config get usage_tracking_enabled
361
361
  ```
362
362
 
363
363
  **Via REST API:**
@@ -401,7 +401,7 @@ The `access_path` is set by the caller layer (not the end user):
401
401
 
402
402
  **CLI:**
403
403
  ```bash
404
- cerefox config-get usage_tracking_enabled
404
+ cerefox config get usage_tracking_enabled
405
405
  ```
406
406
 
407
407
  ---
@@ -421,11 +421,11 @@ with a helpful message telling the agent what to provide.
421
421
 
422
422
  ```bash
423
423
  # Require all MCP tool calls to include requestor/author
424
- cerefox config-set require_requestor_identity true
424
+ cerefox config set require_requestor_identity true
425
425
 
426
426
  # Optionally override the default naming format (regex)
427
427
  # Default: ^[a-zA-Z0-9_:.\- ]+$ (letters, numbers, underscores, colons, dots, hyphens, spaces)
428
- cerefox config-set requestor_identity_format "^[a-z]+:[a-z]+$"
428
+ cerefox config set requestor_identity_format "^[a-z]+:[a-z]+$"
429
429
  ```
430
430
 
431
431
  ### Format examples
@@ -441,7 +441,7 @@ The format is applied to both `requestor` (read tools) and `author` (ingest).
441
441
  ### Disabling enforcement
442
442
 
443
443
  ```bash
444
- cerefox config-set require_requestor_identity false
444
+ cerefox config set require_requestor_identity false
445
445
  ```
446
446
 
447
447
  When disabled, the requestor parameter remains optional with the `"mcp-agent"` default.
@@ -65,7 +65,7 @@ Three top-level paths plus a few special cases:
65
65
 
66
66
  **For all paths:**
67
67
  - Supabase project set up and schema deployed (see `setup-supabase.md`)
68
- - Some content ingested (`cerefox ingest my-notes.md`)
68
+ - Some content ingested (`cerefox document ingest my-notes.md`)
69
69
 
70
70
  **For Path A-Local only:**
71
71
  - **Recommended (v0.4.0+):** [Node.js ≥20](https://nodejs.org) (for `npx --package=@cerefox/memory cerefox mcp`)
@@ -1177,7 +1177,7 @@ Quick sanity check before pointing an agent at it:
1177
1177
  ```bash
1178
1178
  cd /path/to/cerefox
1179
1179
  uv run cerefox search "any query"
1180
- uv run cerefox list-projects
1180
+ uv run cerefox project list
1181
1181
  ```
1182
1182
 
1183
1183
  If both work for you, they'll work for the agent.
@@ -1218,14 +1218,14 @@ The agent docs are written around MCP tool names. **CLI flag names match MCP par
1218
1218
  | MCP tool | CLI command |
1219
1219
  |---|---|
1220
1220
  | `cerefox_search` | `uv run cerefox search "<query>" --match-count N --project-name <n> --metadata-filter '<json>' --requestor <name>` (CLI-only: `--mode`, `--alpha`, `--min-score`) |
1221
- | `cerefox_ingest` (file) | `uv run cerefox ingest <path> --title <t> --project-name <n> --metadata '<json>' --update-if-exists\|--document-id <uuid> --source <s> --author <a> --author-type user\|agent` |
1222
- | `cerefox_ingest` (paste) | `printf '...' \| uv run cerefox ingest --paste --title "<title>"` (same flags) |
1223
- | `cerefox_get_document` | `uv run cerefox get-doc <document-id> --version-id <vid> --requestor <name>` |
1224
- | `cerefox_list_versions` | `uv run cerefox list-versions <document-id> --requestor <name>` |
1225
- | `cerefox_list_projects` | `uv run cerefox list-projects --requestor <name>` |
1226
- | `cerefox_list_metadata_keys` | `uv run cerefox list-metadata-keys` |
1227
- | `cerefox_metadata_search` | `uv run cerefox metadata-search --metadata-filter '<json>' --project-name <n> --requestor <name>` |
1228
- | `cerefox_get_audit_log` | `uv run cerefox get-audit-log --document-id <id> --author <a> --operation <op> --since <iso> --until <iso> --limit N --json --requestor <name>` |
1221
+ | `cerefox_ingest` (file) | `uv run cerefox document ingest <path> --title <t> --project-name <n> --metadata '<json>' --update-if-exists\|--document-id <uuid> --source <s> --author <a> --author-type user\|agent` |
1222
+ | `cerefox_ingest` (paste) | `printf '...' \| uv run cerefox document ingest --paste --title "<title>"` (same flags) |
1223
+ | `cerefox_get_document` | `uv run cerefox document get <document-id> --version-id <vid> --requestor <name>` |
1224
+ | `cerefox_list_versions` | `uv run cerefox version list <document-id> --requestor <name>` |
1225
+ | `cerefox_list_projects` | `uv run cerefox project list --requestor <name>` |
1226
+ | `cerefox_list_metadata_keys` | `uv run cerefox metadata keys` |
1227
+ | `cerefox_metadata_search` | `uv run cerefox metadata search --metadata-filter '<json>' --project-name <n> --requestor <name>` |
1228
+ | `cerefox_get_audit_log` | `uv run cerefox audit list --document-id <id> --author <a> --operation <op> --since <iso> --until <iso> --limit N --json --requestor <name>` |
1229
1229
 
1230
1230
  ### Path C verification prompts
1231
1231
 
@@ -1235,16 +1235,16 @@ After pointing your agent at the repo, ask it:
1235
1235
  > Expected: agent runs `uv run cerefox search "second brain"` via its Bash tool and reports results.
1236
1236
 
1237
1237
  > "Save a note titled 'Test Note' to Cerefox with the content '# Test\nThis is a Path C test.'"
1238
- > Expected: agent runs `cerefox ingest --paste --title "Test Note"` (or equivalent) and reports the new document ID.
1238
+ > Expected: agent runs `cerefox document ingest --paste --title "Test Note"` (or equivalent) and reports the new document ID.
1239
1239
 
1240
1240
  > "List my Cerefox projects."
1241
- > Expected: agent runs `uv run cerefox list-projects`.
1241
+ > Expected: agent runs `uv run cerefox project list`.
1242
1242
 
1243
1243
  ### Caveats
1244
1244
 
1245
1245
  - **Privilege level**: the CLI uses the **service-role key** (`CEREFOX_SUPABASE_KEY`), which bypasses Row Level Security. An agent with Bash access has the same full read/write power you do. Only enable Path C for agents you trust to act on your behalf — the same trust level you'd grant Cursor/Claude Code for editing your source code.
1246
1246
  - **Audit attribution**: Path C records `access_path = "cli"` in usage logs, distinct from `"local-mcp"` / `"remote-mcp"`. **Agents must set `--author <name> --author-type agent` on writes and `--requestor <name>` on reads** (or rely on `CEREFOX_AUTHOR_NAME` / `CEREFOX_AUTHOR_TYPE` / `CEREFOX_REQUESTOR_NAME` env vars). Without these flags, writes attribute to `"unknown"` / `"user"`, which under-reports agent activity. See the 2026-05-18 Decision Log Q2 entry for the design rationale (`author_type` is caller-declared on ambiguous channels — CLI and Edge Functions — but `access_path` is always derived from the code layer).
1247
- - **Soft-delete is reachable; purge and restore are not** — by design. `cerefox delete-doc` is exposed on the CLI and sends documents to trash with an audit entry. **Permanent purge** (irreversible) and **restore from trash** (un-doing a destructive action) are intentionally web-UI-only and require human-in-the-loop confirmation. If an agent on Path C decides to delete content, it should surface that to the user explicitly so they can review and either restore or commit. See [`access-paths.md` → Destructive operations and the trust model](access-paths.md#destructive-operations-and-the-trust-model) for the full rationale and contributor guidance.
1247
+ - **Soft-delete is reachable; purge and restore are not** — by design. `cerefox document delete` is exposed on the CLI and sends documents to trash with an audit entry. **Permanent purge** (irreversible) and **restore from trash** (un-doing a destructive action) are intentionally web-UI-only and require human-in-the-loop confirmation. If an agent on Path C decides to delete content, it should surface that to the user explicitly so they can review and either restore or commit. See [`access-paths.md` → Destructive operations and the trust model](access-paths.md#destructive-operations-and-the-trust-model) for the full rationale and contributor guidance.
1248
1248
  - **Cross-doc links in content you ingest** become clickable when the user views them in the Cerefox web UI. Author them as `[Text](uuid)` (most stable), `[Text](docs/path.md)` (repo files), or `[Text](<Title With Spaces>)` (angle-bracket form — bare spaces break markdown). See [`AGENT_GUIDE.md` → "Writing linkable content"](../../AGENT_GUIDE.md#writing-linkable-content) for the full set of rules.
1249
1249
  - **One repo per machine**: the agent needs your checkout — there's no "Path C without a local clone". If you skip the local install entirely, Path A-Remote or Path B is the only option.
1250
1250
  - **No sandboxing beyond the agent's existing Bash sandbox**: the CLI is just shell. If your agent's tool framework restricts which commands run, allowlist `uv run cerefox …` explicitly.
@@ -1295,7 +1295,7 @@ for hit in resp.results:
1295
1295
  Both paths use the same Postgres RPCs and the same stored embeddings, but embed queries
1296
1296
  independently. If you change the embedding model, **update both paths** before searching:
1297
1297
 
1298
- 1. Update `.env` + run `cerefox reindex` (re-embeds stored chunks via Python)
1298
+ 1. Update `.env` + run `cerefox server reindex` (re-embeds stored chunks via Python)
1299
1299
  2. Update the TypeScript constants in `supabase/functions/*/index.ts` + redeploy Edge Functions
1300
1300
 
1301
1301
  See `docs/guides/configuration.md` → "Changing the embedding model" for the full procedure.
@@ -100,7 +100,7 @@ If you want to keep costs as low as possible:
100
100
  See `docs/guides/configuration.md` for how to switch.
101
101
  - **Batch ingest, don't re-ingest**: Cerefox deduplicates by content hash — re-ingesting the
102
102
  same file twice costs nothing. Only new or changed content triggers embedding calls.
103
- - **`cerefox reindex`**: Re-embeds all existing chunks if you switch embedders. Run this once
103
+ - **`cerefox server reindex`**: Re-embeds all existing chunks if you switch embedders. Run this once
104
104
  after switching, not repeatedly.
105
105
 
106
106
  ---
@@ -200,7 +200,7 @@ Backups are JSON files with the following structure:
200
200
  }
201
201
  ```
202
202
 
203
- **Embeddings are included** in backups. This means a restored database is immediately searchable — no `cerefox reindex` required after restore.
203
+ **Embeddings are included** in backups. This means a restored database is immediately searchable — no `cerefox server reindex` required after restore.
204
204
 
205
205
  The backup directory (`./backup-data/` by default) is gitignored. Back up the backup files separately if you want off-site copies (e.g. copy to cloud storage).
206
206
 
@@ -257,15 +257,15 @@ The `cerefox` CLI also provides data management commands:
257
257
 
258
258
  | Command | Description |
259
259
  |---------|-------------|
260
- | `uv run cerefox ingest FILE` | Ingest a markdown file |
261
- | `uv run cerefox ingest --paste --title TITLE` | Ingest text from stdin |
260
+ | `uv run cerefox document ingest FILE` | Ingest a markdown file |
261
+ | `uv run cerefox document ingest --paste --title TITLE` | Ingest text from stdin |
262
262
  | `uv run cerefox search QUERY` | Search the knowledge base |
263
- | `uv run cerefox list-docs` | List all documents |
264
- | `uv run cerefox delete-doc ID` | Delete a document by ID |
265
- | `uv run cerefox list-projects` | List all projects |
266
- | `uv run cerefox list-versions ID` | List all archived versions of a document |
267
- | `uv run cerefox get-doc ID` | Retrieve current content of a document |
268
- | `uv run cerefox get-doc ID --version VERSION_ID` | Retrieve a specific archived version |
263
+ | `uv run cerefox document list` | List all documents |
264
+ | `uv run cerefox document delete ID` | Delete a document by ID |
265
+ | `uv run cerefox project list` | List all projects |
266
+ | `uv run cerefox version list ID` | List all archived versions of a document |
267
+ | `uv run cerefox document get ID` | Retrieve current content of a document |
268
+ | `uv run cerefox document get ID --version VERSION_ID` | Retrieve a specific archived version |
269
269
  | `uv run cerefox web` | Start the web UI |
270
270
 
271
271
  Run `uv run cerefox --help` or `uv run cerefox COMMAND --help` for details.
@@ -93,8 +93,8 @@ After v0.6.0, `cerefox init` will offer to do this for you.
93
93
 
94
94
  ## What's next
95
95
 
96
- - **Ingest your notes**: `cerefox ingest my-notes.md`, or
97
- `cerefox ingest-dir ./notes/ --recursive`
96
+ - **Ingest your notes**: `cerefox document ingest my-notes.md`, or
97
+ `cerefox document ingest-dir ./notes/ --recursive`
98
98
  - **Search from the CLI**: `cerefox search "your query"`
99
99
  - **Discover all commands**: `cerefox --help`
100
100
  - **Run the web UI** (Python-only until v0.6): [`setup-local.md`](setup-local.md)
@@ -95,10 +95,10 @@ You should see all tables (cerefox_documents, cerefox_chunks, cerefox_projects)
95
95
 
96
96
  ```bash
97
97
  # Ingest a markdown file
98
- cerefox ingest my-notes.md --project-name "personal"
98
+ cerefox document ingest my-notes.md --project-name "personal"
99
99
 
100
100
  # Or paste content from stdin
101
- echo "# Quick Note\n\nThis is a quick note." | cerefox ingest --paste --title "Quick Note"
101
+ echo "# Quick Note\n\nThis is a quick note." | cerefox document ingest --paste --title "Quick Note"
102
102
  ```
103
103
 
104
104
  Each ingest calls the OpenAI embedding API once per batch of chunks (fast, typically under a second).
@@ -227,10 +227,10 @@ appear with a green "Active" status.
227
227
  > Supabase compiles them in the cloud. **Docker is not a prerequisite for deploying Cerefox's
228
228
  > Edge Functions.** A deploy succeeded as long as each function ends with
229
229
  > `Deployed Functions on project …`. This applies to both the manual commands here and
230
- > `cerefox deploy-server --functions-only`.
230
+ > `cerefox server deploy --functions-only`.
231
231
 
232
232
  > **Re-deploying after updates**: run the same `npx supabase functions deploy` commands
233
- > again from the project root, or just `cerefox deploy-server --functions-only` (it deploys
233
+ > again from the project root, or just `cerefox server deploy --functions-only` (it deploys
234
234
  > all 9 from the bundled assets). `npx supabase login` only needs to be run once per machine.
235
235
 
236
236
  ---
@@ -213,7 +213,7 @@ uv run python scripts/reindex_all.py --dry-run
213
213
  uv run python scripts/reindex_all.py
214
214
 
215
215
  # Or run directly via the CLI (same effect)
216
- uv run cerefox reindex --all
216
+ uv run cerefox server reindex --all
217
217
  ```
218
218
 
219
219
  The reindex is **resumable**: if interrupted, re-running it skips chunks already embedded with the current model. Archived chunks (historical versions) are not reindexed -- they are not searched.
@@ -238,7 +238,7 @@ redeploy RPCs via `db_deploy.py` (step 4) to update the canonical function defin
238
238
 
239
239
  **Usage tracking is opt-in**: disabled by default. Enable via CLI:
240
240
  ```bash
241
- cerefox config-set usage_tracking_enabled true
241
+ cerefox config set usage_tracking_enabled true
242
242
  ```
243
243
  Or via the toggle on the Analytics page. When enabled, **all operations** (both reads
244
244
  and writes) are logged with operation type, access path, requestor identity, query text,
@@ -290,7 +290,7 @@ MCP clients pick up new tools automatically on the next connection.
290
290
 
291
291
  ### Upgrading to v0.1.1+ (from v0.1.0)
292
292
 
293
- **Cloud-only embeddings**: Local embedders (mpnet, Ollama) were removed. If you were using a local embedder, switch to OpenAI or Fireworks AI and run `uv run cerefox reindex` to re-embed all chunks.
293
+ **Cloud-only embeddings**: Local embedders (mpnet, Ollama) were removed. If you were using a local embedder, switch to OpenAI or Fireworks AI and run `uv run cerefox server reindex` to re-embed all chunks.
294
294
 
295
295
  ## AI Agent Integration After Upgrade
296
296
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cerefox/memory",
3
- "version": "0.8.3",
3
+ "version": "0.9.0",
4
4
  "description": "Cerefox — user-owned shared memory for AI agents. The local TypeScript runtime: stdio MCP server in v0.4; CLI binary added in v0.5; in-process web server in v0.6; ingestion pipeline in v0.7.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/fstamatelopoulos/cerefox",