@cerefox/memory 1.0.0-beta.1 → 1.0.0-beta.2

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.
@@ -15,7 +15,7 @@
15
15
  href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700&display=swap"
16
16
  />
17
17
  <title>Cerefox</title>
18
- <script type="module" crossorigin src="/app/assets/index-CCkg5PXt.js"></script>
18
+ <script type="module" crossorigin src="/app/assets/index-D3FshoP3.js"></script>
19
19
  <link rel="stylesheet" crossorigin href="/app/assets/index-Asx5wD7g.css">
20
20
  </head>
21
21
  <body>
@@ -18,7 +18,7 @@
18
18
  * doesn't touch `supabase/functions/` leaves it alone).
19
19
  */
20
20
 
21
- export const EF_VERSION = "1.0.0-beta.1";
21
+ export const EF_VERSION = "1.0.0-beta.2";
22
22
 
23
23
  /**
24
24
  * The 8 peer EFs the cerefox-mcp aggregator probes (excludes cerefox-mcp
@@ -11,7 +11,7 @@
11
11
  * docs/specs/polish-and-distribution-design.md §10d.
12
12
  */
13
13
 
14
- export const HELP_FULL = "# Cerefox Knowledge Base -- Agent Quick Reference\n\nCerefox is a persistent, shared knowledge base. You have **10 MCP tools** (9 of them have CLI equivalents — `cerefox_get_help` is MCP-only). For the full guide, search Cerefox for \"How AI Agents Use Cerefox\" or call `cerefox_get_help` to retrieve this content over MCP.\n\n## Tools\n\n| Tool | Purpose | Key params |\n|------|---------|------------|\n| `cerefox_search` | Find documents (hybrid FTS + semantic) | `query` (required), `project_name`, `metadata_filter`, `requestor` |\n| `cerefox_ingest` | Save or update a document | `title`, `content` (required), `document_id` (update by ID), `expected_content_hash` (**required on content updates** — see rule 9), `last_write_wins`, `update_if_exists`, `project_name` (single, non-destructive add on update), `project_names` (list, destructive replace on update), `metadata` (omit on update to keep existing tags; `{}` clears), `author` |\n| `cerefox_get_document` | Get full document by ID (header includes `content_hash` — the update token) | `document_id` (required) |\n| `cerefox_list_versions` | Version history of a document | `document_id` (required) |\n| `cerefox_metadata_search` | Find or list docs by metadata, project, or time (no text query) | `metadata_filter`, `project_name` (list a project's docs), `updated_since`, `include_content` — **at least one** of metadata_filter/project_name/updated_since/created_since |\n| `cerefox_list_metadata_keys` | Discover available metadata keys | (none required) |\n| `cerefox_list_projects` | List all projects | (none required) |\n| `cerefox_set_document_projects` | Set doc's project memberships to exactly the given list (destructive replace; metadata-only, no content change) | `document_id`, `project_names` (required) |\n| `cerefox_get_audit_log` | Query write operation history | `document_id`, `author`, `operation`, `since` |\n| `cerefox_get_help` | Retrieve Cerefox conventions (this reference) over MCP. **Call this whenever uncertain.** | `topic` (optional, case-insensitive H2 substring match) |\n\n## Essential Rules\n\n1. **Search before ingesting** -- check if the document exists first.\n2. **Prefer ID-based updates** -- pass `document_id` from search results for deterministic updates. Falls back to title-matching with `update_if_exists: true`.\n3. **Set `author`/`requestor`** to your name on every call (e.g., \"Claude Code\", \"archiver\"). On MCP, pass as parameters. On CLI, pass `--author`/`--author-type`/`--requestor` flags, or rely on `CEREFOX_AUTHOR_NAME`/`CEREFOX_AUTHOR_TYPE`/`CEREFOX_REQUESTOR_NAME` env vars set in the user's `.env`.\n4. **Use `document_id` from search results** `[id: uuid]` for get_document and list_versions.\n5. **Add metadata** -- at minimum `type` (\"decision-log\", \"research\", \"design-doc\") and `status` (\"active\", \"draft\").\n6. **Write structured Markdown** with H1/H2/H3 headings for good chunking and search.\n7. **Deletes are soft (recoverable); purge is web-UI-only.** If you decide to delete, surface it to the user (`I soft-deleted X — recoverable from the Cerefox web UI trash`). You cannot un-do your own delete from agent code by design.\n8. **Cross-doc links inside content**: **always use `[Text](document-uuid)`.** UUIDs are the only fully reliable link form — stable across title changes, never ambiguous, no encoding gotchas. Every `cerefox_search` result shows `[id: <uuid>]` after the title; grab it and use it. Title-based linking (`[Text](<Title With Spaces>)`) is fragile (breaks on colons, parens, ampersands, brackets — silently navigates to wrong page) — **don't write title-based links**; do an extra search to get the UUID instead. Repo-path forms (`[Text](docs/path.md)`) exist for repo-ingested files; don't construct manually. See `AGENT_GUIDE.md → Writing linkable content` for the full rule.\n9. **Concurrency: content updates require `expected_content_hash`.** Pass the `content_hash` you read (shown by `cerefox_get_document`, `cerefox_search`, and `cerefox_metadata_search`) when updating a document. If it's stale you get a **conflict** — re-read the document, merge your changes into the latest content, retry with the new hash. **Never resolve a conflict by overwriting blindly** — the current content includes another writer's work. `last_write_wins: true` skips the check; use it ONLY when an external source of truth makes conflicts meaningless (file re-sync), never to silence a conflict.\n10. **Project memberships — non-destructive by default**: on `cerefox_ingest` updates, **`project_name` (singular) is a non-destructive add** (ensures membership, preserves others). Use **`project_names` (list)** when you want to set the doc's full project set in one call (destructive replace). For metadata-only project changes without writing content, use **`cerefox_set_document_projects(document_id, project_names)`** — that tool is the destructive-replace contract made explicit. Never call `cerefox_set_document_projects` with a single name when you mean \"add\" — that would REMOVE the doc from all other projects. When in doubt, use `cerefox_ingest` with singular `project_name`.\n\n## Update Workflow (ID-based -- preferred)\n\n```\nsearch(\"topic\") -> find doc [id: abc123] -> get_document(abc123) -> note its content_hash -> modify ->\ningest(title=\"Same Title\", content=\"...\", document_id=\"abc123\",\n expected_content_hash=\"<the hash you read>\", author=\"my-agent\")\n```\n\nOn a **conflict** error: get_document again (fresh content + fresh hash) -> merge your changes -> retry with the new hash.\n\n## Update Workflow (title-based -- fallback)\n\n```\nsearch(\"topic\") -> find doc (note its hash) -> modify ->\ningest(title=\"Same Title\", content=\"...\", update_if_exists=true,\n expected_content_hash=\"<the hash you read>\", author=\"my-agent\")\n```\n\n## Catch-Up Workflow\n\n```\nmetadata_search(metadata_filter={\"type\": \"decision-log\"}, updated_since=\"2026-03-28T00:00:00Z\")\n```\n\n## CLI fallback (when MCP is unavailable)\n\nIf `cerefox_search` is not in your tool list, your user has likely installed the Cerefox CLI. The canonical invocation is plain **`cerefox <subcommand>`** (the TypeScript CLI, installed via `npm install -g @cerefox/memory`). It uses a resource-verb shape (`cerefox document get`, `cerefox project list`, …). The legacy Python `uv run cerefox` is now a frozen husk as of v0.9 — only `uv run cerefox mcp` still works.\n\nSame operations, same conventions. Full reference: [`docs/guides/cli.md`](docs/guides/cli.md). CLI flag names match MCP parameter names exactly (e.g. `metadata_filter` ↔ `--metadata-filter`); common flags also have single-letter short forms (`-f`, `-p`, `-c`, `-m`, `-u`, `-a`, `-r`). Use the canonical long name (what `--help` shows) or its short form — there are no long-form aliases like `--filter` or `--count`.\n\n| MCP tool | CLI |\n|---|---|\n| `cerefox_search` | `cerefox search \"<q>\" --requestor \"<your-name>\"` |\n| `cerefox_ingest` (paste) | `printf '...' \\| cerefox document ingest --paste --title \"<t>\" --author \"<your-name>\" --author-type agent` |\n| `cerefox_ingest` (update by ID) | `printf '...' \\| cerefox document ingest --paste --title \"<t>\" --document-id \"<uuid>\" --expected-content-hash \"<hash>\" --author \"<your-name>\" --author-type agent` |\n| `cerefox_get_document` | `cerefox document get <id> --version-id <vid> --requestor \"<your-name>\"` |\n| `cerefox_list_versions` | `cerefox document version list <id> --requestor \"<your-name>\"` |\n| `cerefox_list_projects` | `cerefox project list --requestor \"<your-name>\"` |\n| `cerefox_list_metadata_keys` | `cerefox metadata keys` |\n| `cerefox_metadata_search` | `cerefox metadata search --metadata-filter '<json>' --requestor \"<your-name>\"` (list a project: `cerefox document list --project <name>`) |\n| `cerefox_set_document_projects` | `cerefox document set-projects <id> <name...> --author \"<your-name>\" --author-type agent` (or `--clear` to remove all) |\n| `cerefox_get_audit_log` | `cerefox audit list --requestor \"<your-name>\"` (add `--json` for scripted access) |\n| `cerefox_get_help` | `cerefox guides show agent-quick-reference` (or `cerefox guides list` for the full bundled-docs index) |\n\n**Set identity on every call**, exactly as you would on MCP:\n- Writes (`document ingest`, `document ingest-dir`): `--author \"<your-name>\" --author-type agent`\n- Reads: `--requestor \"<your-name>\"`\n\nOr have your user set `CEREFOX_AUTHOR_NAME` / `CEREFOX_AUTHOR_TYPE` / `CEREFOX_REQUESTOR_NAME` in their `.env` to apply defaults once.\n";
14
+ export const HELP_FULL = "# Cerefox Knowledge Base -- Agent Quick Reference\n\nCerefox is a persistent, shared knowledge base. You have **10 MCP tools** (9 of them have CLI equivalents — `cerefox_get_help` is MCP-only). For the full guide, search Cerefox for \"How AI Agents Use Cerefox\" or call `cerefox_get_help` to retrieve this content over MCP.\n\n## Tools\n\n| Tool | Purpose | Key params |\n|------|---------|------------|\n| `cerefox_search` | Find documents (hybrid FTS + semantic) | `query` (required), `project_name`, `metadata_filter`, `requestor` |\n| `cerefox_ingest` | Save or update a document | `title`, `content` (required), `document_id` (update by ID), `expected_content_hash` (**required on content updates** — see rule 9), `last_write_wins`, `update_if_exists`, `project_name` (single, non-destructive add on update), `project_names` (list, destructive replace on update), `metadata` (omit on update to keep existing tags; `{}` clears), `author` |\n| `cerefox_get_document` | Get full document by ID (header includes `content_hash` — the update token) | `document_id` (required) |\n| `cerefox_list_versions` | Version history of a document | `document_id` (required) |\n| `cerefox_metadata_search` | Find or list docs by metadata, project, or time (no text query) | `metadata_filter`, `project_name` (list a project's docs), `updated_since`, `include_content` — **at least one** of metadata_filter/project_name/updated_since/created_since |\n| `cerefox_list_metadata_keys` | Discover available metadata keys | (none required) |\n| `cerefox_list_projects` | List all projects | (none required) |\n| `cerefox_set_document_projects` | Set doc's project memberships to exactly the given list (destructive replace; metadata-only, no content change) | `document_id`, `project_names` (required) |\n| `cerefox_get_audit_log` | Query write operation history | `document_id`, `author`, `operation`, `since` |\n| `cerefox_get_help` | Retrieve Cerefox conventions (this reference) over MCP. **Call this whenever uncertain.** | `topic` (optional, case-insensitive H2 substring match) |\n\n## Essential Rules\n\n1. **Search before ingesting** -- check if the document exists first.\n2. **Prefer ID-based updates** -- pass `document_id` from search results for deterministic updates. Falls back to title-matching with `update_if_exists: true`.\n3. **Set `author`/`requestor`** to your name on every call (e.g., \"Claude Code\", \"archiver\"). On MCP, pass as parameters. On CLI, pass `--author`/`--author-type`/`--requestor` flags, or rely on `CEREFOX_AUTHOR_NAME`/`CEREFOX_AUTHOR_TYPE`/`CEREFOX_REQUESTOR_NAME` env vars set in the user's `.env`.\n4. **Use `document_id` from search results** `[id: uuid]` for get_document and list_versions.\n5. **Add metadata** -- at minimum `type` (\"decision-log\", \"research\", \"design-doc\") and `status` (\"active\", \"draft\").\n6. **Write structured Markdown** with H1/H2/H3 headings for good chunking and search.\n7. **Deletes are soft (recoverable); purge is web-UI-only.** If you decide to delete, surface it to the user (`I soft-deleted X — recoverable from the Cerefox web UI trash`). You cannot un-do your own delete from agent code by design.\n8. **Cross-doc links inside content**: **always use `[Text](document-uuid)`.** UUIDs are the only fully reliable link form — stable across title changes, never ambiguous, no encoding gotchas. Every `cerefox_search` result shows `[id: <uuid>]` after the title; grab it and use it. Title-based linking (`[Text](<Title With Spaces>)`) is fragile (breaks on colons, parens, ampersands, brackets — silently navigates to wrong page) — **don't write title-based links**; do an extra search to get the UUID instead. Repo-path forms (`[Text](docs/path.md)`) exist for repo-ingested files; don't construct manually. See `AGENT_GUIDE.md → Writing linkable content` for the full rule.\n9. **Concurrency: content updates require `expected_content_hash`.** Pass the `content_hash` you read (shown by `cerefox_get_document`, `cerefox_search`, and `cerefox_metadata_search`) when updating a document. If it's stale you get a **conflict** — re-read the document, merge your changes into the latest content, retry with the new hash. **Never resolve a conflict by overwriting blindly** — the current content includes another writer's work. `last_write_wins: true` skips the check; use it ONLY when an external source of truth makes conflicts meaningless (file re-sync), never to silence a conflict.\n10. **Project memberships — non-destructive by default**: on `cerefox_ingest` updates, **`project_name` (singular) is a non-destructive add** (ensures membership, preserves others). Use **`project_names` (list)** when you want to set the doc's full project set in one call (destructive replace). For metadata-only project changes without writing content, use **`cerefox_set_document_projects(document_id, project_names)`** — that tool is the destructive-replace contract made explicit. Never call `cerefox_set_document_projects` with a single name when you mean \"add\" — that would REMOVE the doc from all other projects. When in doubt, use `cerefox_ingest` with singular `project_name`.\n\n## Update Workflow (ID-based -- preferred)\n\n```\nsearch(\"topic\") -> find doc [id: abc123] -> get_document(abc123) -> note its content_hash -> modify ->\ningest(title=\"Same Title\", content=\"...\", document_id=\"abc123\",\n expected_content_hash=\"<the hash you read>\", author=\"my-agent\")\n```\n\nOn a **conflict** error: get_document again (fresh content + fresh hash) -> merge your changes -> retry with the new hash.\n\n## Update Workflow (title-based -- fallback)\n\n```\nsearch(\"topic\") -> find doc (note its hash) -> modify ->\ningest(title=\"Same Title\", content=\"...\", update_if_exists=true,\n expected_content_hash=\"<the hash you read>\", author=\"my-agent\")\n```\n\n## Catch-Up Workflow\n\n```\nmetadata_search(metadata_filter={\"type\": \"decision-log\"}, updated_since=\"2026-03-28T00:00:00Z\")\n```\n\n## CLI fallback (when MCP is unavailable)\n\nIf `cerefox_search` is not in your tool list, your user has likely installed the Cerefox CLI. The canonical invocation is plain **`cerefox <subcommand>`** (the TypeScript CLI, installed via `npm install -g @cerefox/memory`). It uses a resource-verb shape (`cerefox document get`, `cerefox project list`, …).\n\nSame operations, same conventions. Full reference: [`docs/guides/cli.md`](docs/guides/cli.md). CLI flag names match MCP parameter names exactly (e.g. `metadata_filter` ↔ `--metadata-filter`); common flags also have single-letter short forms (`-f`, `-p`, `-c`, `-m`, `-u`, `-a`, `-r`). Use the canonical long name (what `--help` shows) or its short form — there are no long-form aliases like `--filter` or `--count`.\n\n| MCP tool | CLI |\n|---|---|\n| `cerefox_search` | `cerefox search \"<q>\" --requestor \"<your-name>\"` |\n| `cerefox_ingest` (paste) | `printf '...' \\| cerefox document ingest --paste --title \"<t>\" --author \"<your-name>\" --author-type agent` |\n| `cerefox_ingest` (update by ID) | `printf '...' \\| cerefox document ingest --paste --title \"<t>\" --document-id \"<uuid>\" --expected-content-hash \"<hash>\" --author \"<your-name>\" --author-type agent` |\n| `cerefox_get_document` | `cerefox document get <id> --version-id <vid> --requestor \"<your-name>\"` |\n| `cerefox_list_versions` | `cerefox document version list <id> --requestor \"<your-name>\"` |\n| `cerefox_list_projects` | `cerefox project list --requestor \"<your-name>\"` |\n| `cerefox_list_metadata_keys` | `cerefox metadata keys` |\n| `cerefox_metadata_search` | `cerefox metadata search --metadata-filter '<json>' --requestor \"<your-name>\"` (list a project: `cerefox document list --project <name>`) |\n| `cerefox_set_document_projects` | `cerefox document set-projects <id> <name...> --author \"<your-name>\" --author-type agent` (or `--clear` to remove all) |\n| `cerefox_get_audit_log` | `cerefox audit list --requestor \"<your-name>\"` (add `--json` for scripted access) |\n| `cerefox_get_help` | `cerefox guides show agent-quick-reference` (or `cerefox guides list` for the full bundled-docs index) |\n\n**Set identity on every call**, exactly as you would on MCP:\n- Writes (`document ingest`, `document ingest-dir`): `--author \"<your-name>\" --author-type agent`\n- Reads: `--requestor \"<your-name>\"`\n\nOr have your user set `CEREFOX_AUTHOR_NAME` / `CEREFOX_AUTHOR_TYPE` / `CEREFOX_REQUESTOR_NAME` in their `.env` to apply defaults once.\n";
15
15
 
16
16
  /** Sections keyed by their H2 heading text (lower-cased for matching). */
17
17
  export const HELP_SECTIONS: Record<string, string> = {
@@ -20,7 +20,7 @@ export const HELP_SECTIONS: Record<string, string> = {
20
20
  "Update Workflow (ID-based -- preferred)": "## Update Workflow (ID-based -- preferred)\n\n```\nsearch(\"topic\") -> find doc [id: abc123] -> get_document(abc123) -> note its content_hash -> modify ->\ningest(title=\"Same Title\", content=\"...\", document_id=\"abc123\",\n expected_content_hash=\"<the hash you read>\", author=\"my-agent\")\n```\n\nOn a **conflict** error: get_document again (fresh content + fresh hash) -> merge your changes -> retry with the new hash.",
21
21
  "Update Workflow (title-based -- fallback)": "## Update Workflow (title-based -- fallback)\n\n```\nsearch(\"topic\") -> find doc (note its hash) -> modify ->\ningest(title=\"Same Title\", content=\"...\", update_if_exists=true,\n expected_content_hash=\"<the hash you read>\", author=\"my-agent\")\n```",
22
22
  "Catch-Up Workflow": "## Catch-Up Workflow\n\n```\nmetadata_search(metadata_filter={\"type\": \"decision-log\"}, updated_since=\"2026-03-28T00:00:00Z\")\n```",
23
- "CLI fallback (when MCP is unavailable)": "## CLI fallback (when MCP is unavailable)\n\nIf `cerefox_search` is not in your tool list, your user has likely installed the Cerefox CLI. The canonical invocation is plain **`cerefox <subcommand>`** (the TypeScript CLI, installed via `npm install -g @cerefox/memory`). It uses a resource-verb shape (`cerefox document get`, `cerefox project list`, …). The legacy Python `uv run cerefox` is now a frozen husk as of v0.9 — only `uv run cerefox mcp` still works.\n\nSame operations, same conventions. Full reference: [`docs/guides/cli.md`](docs/guides/cli.md). CLI flag names match MCP parameter names exactly (e.g. `metadata_filter` ↔ `--metadata-filter`); common flags also have single-letter short forms (`-f`, `-p`, `-c`, `-m`, `-u`, `-a`, `-r`). Use the canonical long name (what `--help` shows) or its short form — there are no long-form aliases like `--filter` or `--count`.\n\n| MCP tool | CLI |\n|---|---|\n| `cerefox_search` | `cerefox search \"<q>\" --requestor \"<your-name>\"` |\n| `cerefox_ingest` (paste) | `printf '...' \\| cerefox document ingest --paste --title \"<t>\" --author \"<your-name>\" --author-type agent` |\n| `cerefox_ingest` (update by ID) | `printf '...' \\| cerefox document ingest --paste --title \"<t>\" --document-id \"<uuid>\" --expected-content-hash \"<hash>\" --author \"<your-name>\" --author-type agent` |\n| `cerefox_get_document` | `cerefox document get <id> --version-id <vid> --requestor \"<your-name>\"` |\n| `cerefox_list_versions` | `cerefox document version list <id> --requestor \"<your-name>\"` |\n| `cerefox_list_projects` | `cerefox project list --requestor \"<your-name>\"` |\n| `cerefox_list_metadata_keys` | `cerefox metadata keys` |\n| `cerefox_metadata_search` | `cerefox metadata search --metadata-filter '<json>' --requestor \"<your-name>\"` (list a project: `cerefox document list --project <name>`) |\n| `cerefox_set_document_projects` | `cerefox document set-projects <id> <name...> --author \"<your-name>\" --author-type agent` (or `--clear` to remove all) |\n| `cerefox_get_audit_log` | `cerefox audit list --requestor \"<your-name>\"` (add `--json` for scripted access) |\n| `cerefox_get_help` | `cerefox guides show agent-quick-reference` (or `cerefox guides list` for the full bundled-docs index) |\n\n**Set identity on every call**, exactly as you would on MCP:\n- Writes (`document ingest`, `document ingest-dir`): `--author \"<your-name>\" --author-type agent`\n- Reads: `--requestor \"<your-name>\"`\n\nOr have your user set `CEREFOX_AUTHOR_NAME` / `CEREFOX_AUTHOR_TYPE` / `CEREFOX_REQUESTOR_NAME` in their `.env` to apply defaults once.",
23
+ "CLI fallback (when MCP is unavailable)": "## CLI fallback (when MCP is unavailable)\n\nIf `cerefox_search` is not in your tool list, your user has likely installed the Cerefox CLI. The canonical invocation is plain **`cerefox <subcommand>`** (the TypeScript CLI, installed via `npm install -g @cerefox/memory`). It uses a resource-verb shape (`cerefox document get`, `cerefox project list`, …).\n\nSame operations, same conventions. Full reference: [`docs/guides/cli.md`](docs/guides/cli.md). CLI flag names match MCP parameter names exactly (e.g. `metadata_filter` ↔ `--metadata-filter`); common flags also have single-letter short forms (`-f`, `-p`, `-c`, `-m`, `-u`, `-a`, `-r`). Use the canonical long name (what `--help` shows) or its short form — there are no long-form aliases like `--filter` or `--count`.\n\n| MCP tool | CLI |\n|---|---|\n| `cerefox_search` | `cerefox search \"<q>\" --requestor \"<your-name>\"` |\n| `cerefox_ingest` (paste) | `printf '...' \\| cerefox document ingest --paste --title \"<t>\" --author \"<your-name>\" --author-type agent` |\n| `cerefox_ingest` (update by ID) | `printf '...' \\| cerefox document ingest --paste --title \"<t>\" --document-id \"<uuid>\" --expected-content-hash \"<hash>\" --author \"<your-name>\" --author-type agent` |\n| `cerefox_get_document` | `cerefox document get <id> --version-id <vid> --requestor \"<your-name>\"` |\n| `cerefox_list_versions` | `cerefox document version list <id> --requestor \"<your-name>\"` |\n| `cerefox_list_projects` | `cerefox project list --requestor \"<your-name>\"` |\n| `cerefox_list_metadata_keys` | `cerefox metadata keys` |\n| `cerefox_metadata_search` | `cerefox metadata search --metadata-filter '<json>' --requestor \"<your-name>\"` (list a project: `cerefox document list --project <name>`) |\n| `cerefox_set_document_projects` | `cerefox document set-projects <id> <name...> --author \"<your-name>\" --author-type agent` (or `--clear` to remove all) |\n| `cerefox_get_audit_log` | `cerefox audit list --requestor \"<your-name>\"` (add `--json` for scripted access) |\n| `cerefox_get_help` | `cerefox guides show agent-quick-reference` (or `cerefox guides list` for the full bundled-docs index) |\n\n**Set identity on every call**, exactly as you would on MCP:\n- Writes (`document ingest`, `document ingest-dir`): `--author \"<your-name>\" --author-type agent`\n- Reads: `--requestor \"<your-name>\"`\n\nOr have your user set `CEREFOX_AUTHOR_NAME` / `CEREFOX_AUTHOR_TYPE` / `CEREFOX_REQUESTOR_NAME` in their `.env` to apply defaults once.",
24
24
  };
25
25
 
26
26
  export const HELP_SECTION_HEADINGS: string[] = ["Tools", "Essential Rules", "Update Workflow (ID-based -- preferred)", "Update Workflow (title-based -- fallback)", "Catch-Up Workflow", "CLI fallback (when MCP is unavailable)"];
@@ -56,12 +56,27 @@ interface IngestRequest {
56
56
  last_write_wins?: boolean;
57
57
  }
58
58
 
59
- // Map the RPC's CEREFOX_CONFLICT / CEREFOX_TOKEN_REQUIRED errors to HTTP
60
- // responses (409 conflict / 400 missing token). Returns null for other errors.
59
+ // Map the RPC's expected/validation errors to proper HTTP responses:
60
+ // CEREFOX_CONFLICT → 409 (stale optimistic-concurrency token)
61
+ // CEREFOX_TOKEN_REQUIRED → 400 (missing expected_content_hash)
62
+ // cerefox_documents_hash_unique → 409 (content de-dup: another doc already
63
+ // holds identical content)
64
+ // Returns null for genuinely unexpected errors (→ 500 at the call site).
61
65
  function concurrencyErrorResponse(
62
66
  message: string,
63
67
  headers: Record<string, string>,
64
68
  ): Response | null {
69
+ if (message.includes("cerefox_documents_hash_unique")) {
70
+ return new Response(
71
+ JSON.stringify({
72
+ error: "duplicate_content",
73
+ message:
74
+ "Another document already has identical content. Cerefox de-duplicates by content hash — update that document instead of creating or editing a second copy to match it.",
75
+ detail: message,
76
+ }),
77
+ { status: 409, headers },
78
+ );
79
+ }
65
80
  if (message.includes("CEREFOX_CONFLICT")) {
66
81
  return new Response(
67
82
  JSON.stringify({
@@ -114,9 +114,8 @@ to Supabase over its REST API (PostgREST), authenticating with a **service-role-
114
114
  key** rather than the anon key — either the new **secret key** (`sb_secret_…`) or the legacy
115
115
  `service_role` JWT. Both are accepted by the Data API gateway.
116
116
 
117
- > The legacy Python FastAPI web app and Python CLI are husks slated for removal; only
118
- > `uv run cerefox mcp` survives as a frozen, unmaintained fallback. The TS `cerefox` CLI
119
- > and `cerefox web` are the current implementations.
117
+ > The Python implementation (FastAPI web app, CLI, and the MCP-server fallback) was fully
118
+ > removed at v1.0.0. The TS `cerefox` CLI and `cerefox web` are the implementations.
120
119
 
121
120
  The service-role key bypasses Supabase Row Level Security (RLS) policies and grants
122
121
  unrestricted read and write access. This is intentional — the CLI and web app are trusted,
@@ -156,8 +155,7 @@ For end users, `cerefox server deploy` (which bundles schema + RPCs + the nine E
156
155
  Functions from the npm package) handles schema deployment directly. For contributors, the
157
156
  canonical deployment and migration scripts (`bun scripts/db_deploy.ts`,
158
157
  `bun scripts/db_migrate.ts`, `bun scripts/backup_restore.ts`) connect directly to Postgres
159
- over TCP using the database connection string. (The legacy `.py` equivalents still exist
160
- but are deprecated.) This is the only path that can run DDL statements (`CREATE TABLE`,
158
+ over TCP using the database connection string. This is the only path that can run DDL statements (`CREATE TABLE`,
161
159
  `CREATE FUNCTION`) — the REST API does not support them.
162
160
 
163
161
  ```
@@ -55,10 +55,9 @@ Full rule documented in [`docs/specs/polish-and-distribution-design.md` §7](../
55
55
 
56
56
  Cerefox uses cloud-based embedding APIs. Local models (mpnet, Ollama) are not supported — they require large downloads, fail on some hardware, and add installation complexity.
57
57
 
58
- > **TS runtime: OpenAI only (today).** The current TypeScript runtime implements the
59
- > OpenAI embedder. `CEREFOX_EMBEDDER` and the `CEREFOX_FIREWORKS_*` variables are
60
- > documented (they worked in the retired Python runtime) but are **not yet wired in TS** —
61
- > they're currently no-ops, tracked for a future release.
58
+ > **OpenAI only (today).** The TypeScript runtime implements the OpenAI embedder.
59
+ > `CEREFOX_EMBEDDER` and the `CEREFOX_FIREWORKS_*` variables are documented but **not yet
60
+ > wired in TS** — they're currently no-ops, tracked for a future release.
62
61
 
63
62
  ### OpenAI (default, recommended)
64
63
 
@@ -254,8 +253,8 @@ OPENAI_API_KEY=sk-...
254
253
  ```
255
254
 
256
255
  > **Fireworks is not wired in the TS runtime yet** — `CEREFOX_EMBEDDER=fireworks` /
257
- > `CEREFOX_FIREWORKS_*` are documented for the retired Python runtime but are currently
258
- > no-ops (OpenAI is the only embedder implemented today). Tracked for a future release.
256
+ > `CEREFOX_FIREWORKS_*` are documented but currently no-ops (OpenAI is the only embedder
257
+ > implemented today). Tracked for a future release.
259
258
 
260
259
  ---
261
260
 
@@ -332,7 +331,7 @@ key currently in use is `usage_tracking_enabled`. Every usage logging call goes
332
331
  - If `usage_tracking_enabled` is anything else (including missing) -- the RPC returns immediately without inserting
333
332
 
334
333
  The check happens **inside Postgres on every call**. All callers (Edge Functions, MCP tools,
335
- Python routes, CLI) call `cerefox_log_usage` unconditionally -- the RPC decides whether to
334
+ CLI) call `cerefox_log_usage` unconditionally -- the RPC decides whether to
336
335
  actually log. Callers never wait for the logging result or handle errors from it
337
336
  (fire-and-forget).
338
337
 
@@ -41,7 +41,6 @@ Three top-level paths plus a few special cases:
41
41
  | Gemini CLI (remote) | Path A-Remote — `cerefox-mcp` Edge Function | Hybrid | URL + Cerefox token only; no local install. Advanced/fallback — prefer Path A-Local |
42
42
  | Local coding agents (Claude Code, Codex CLI, opencode, OpenClaw, Hermes, …) | Path C — Shell CLI (Bash tool) | Hybrid | `npm install -g @cerefox/memory`; agent runs `cerefox …` as a shell command. Useful when MCP setup is friction. |
43
43
  | curl / scripts | Path B — Edge Functions directly | Hybrid | Direct HTTP; no client needed |
44
- | Custom Python agents | Python SDK directly (legacy) | Hybrid | Local Python + repo clone; the Python path is legacy/frozen |
45
44
 
46
45
  > **"Hybrid"** = FTS + semantic, document-level (complete reconstructed notes, not isolated chunks).
47
46
  > **"FTS only"** = keyword search only; no semantic/vector search.
@@ -92,8 +91,6 @@ in the container.
92
91
  in the per-client configs below if your client can't see the file)
93
92
  - `.env` must define `CEREFOX_SUPABASE_URL`, `CEREFOX_SUPABASE_KEY`, and your
94
93
  embedding API key (`OPENAI_API_KEY`)
95
- - A frozen Python MCP server still exists as a standalone fallback (`uv run cerefox mcp` from a
96
- repo clone), but the npm package is the maintained path.
97
94
 
98
95
  > **Important — the Cerefox access token (iter-28E):** Path A-Remote and Path B both require a
99
96
  > **Bearer token** on every request. That credential is now the **Cerefox access token**
@@ -140,12 +137,6 @@ Edge Function, communicating with clients over stdio.
140
137
  The local server ships as an npm package — **[`@cerefox/memory`](https://www.npmjs.com/package/@cerefox/memory)** — built with the official `@modelcontextprotocol/sdk`.
141
138
  The bin entry is `cerefox` (run as `cerefox mcp`). The recommended client config is `npx -y --package=@cerefox/memory cerefox mcp`, or if you've installed the package globally, just `cerefox mcp`.
142
139
 
143
- A separate, **frozen** Python MCP server still exists as a standalone fallback — invoke it
144
- explicitly with `uv run cerefox mcp` from a Cerefox repo clone. It is independent and
145
- unmaintained; the npm package is the maintained path. (A "soft wrapper" that auto-delegated
146
- the Python `cerefox mcp` to the npm package was removed in v0.5.2 — the two are now fully
147
- separate. Pick one explicitly in your MCP client config.)
148
-
149
140
  - Embeddings are computed locally using your `.env` key (no extra credentials)
150
141
  - Works offline except for the OpenAI embedding API call per query
151
142
  - One setup, all compatible local clients (Claude Desktop, Cursor, Claude Code, Codex CLI, …)
@@ -1281,39 +1272,6 @@ There is nothing Cerefox-specific to configure for the agent itself — just the
1281
1272
 
1282
1273
  ---
1283
1274
 
1284
- ## Custom agents (Python SDK — legacy)
1285
-
1286
- > **Legacy/frozen path.** The Python codebase is no longer the maintained runtime — the CLI,
1287
- > local MCP server, and deploy tooling have all moved to TypeScript (`@cerefox/memory`). The
1288
- > Python client below still works from a repo clone but is unmaintained. Prefer Path A (MCP),
1289
- > Path B (Edge Functions HTTP), or Path C (the `cerefox` CLI) for new integrations.
1290
-
1291
- Use the Cerefox Python client directly for scripted or embedded agents (from a repo clone):
1292
-
1293
- ```python
1294
- from cerefox.config import Settings
1295
- from cerefox.db.client import CerefoxClient
1296
- from cerefox.embeddings.cloud import CloudEmbedder
1297
- from cerefox.retrieval.search import SearchClient
1298
-
1299
- settings = Settings() # reads from .env
1300
- client = CerefoxClient(settings)
1301
- embedder = CloudEmbedder(
1302
- api_key=settings.get_embedder_api_key(),
1303
- base_url=settings.get_embedder_base_url(),
1304
- model=settings.get_embedder_model(),
1305
- dimensions=settings.get_embedder_dimensions(),
1306
- )
1307
- sc = SearchClient(client, embedder, settings)
1308
-
1309
- resp = sc.search_docs("what did I write about Rust?", match_count=5)
1310
- for hit in resp.results:
1311
- print(f"[{hit.best_score:.2f}] {hit.doc_title}")
1312
- print(hit.full_content[:400])
1313
- ```
1314
-
1315
- ---
1316
-
1317
1275
  ## Keeping both paths in sync
1318
1276
 
1319
1277
  Both paths use the same Postgres RPCs and the same stored embeddings, but embed queries
@@ -1583,7 +1541,3 @@ claude mcp add --scope user cerefox \
1583
1541
  If `.env` isn't resolvable from your shell's CWD, edit the resulting JSON config to add an
1584
1542
  `env` block (see the Claude Desktop block above). The **Code** tab inside Claude Desktop uses
1585
1543
  this same config — run the `claude mcp add` above and it picks it up automatically.
1586
-
1587
- > The legacy Python MCP server can be wired manually as a standalone fallback by pointing the
1588
- > `command` at `uv` with args `["--directory", "/path/to/cerefox", "run", "cerefox", "mcp"]`.
1589
- > It is frozen and unmaintained — prefer the npm entry above.
@@ -69,12 +69,21 @@ The migration is **lazy and safe**:
69
69
 
70
70
  Details: `cerefox guides show content-format` (or [`content-format.md`](content-format.md)).
71
71
 
72
- ## 3. Python is retired at 1.0.0
72
+ ## 3. Python is fully removed at 1.0.0 (breaking)
73
73
 
74
- The frozen Python MCP fallback (`uv run cerefox mcp`) is retired in 1.0.0. If you still rely
75
- on it, migrate to the `@cerefox/memory` npm package (`npx --package=@cerefox/memory cerefox
76
- mcp`), or stay on 0.11.x until you have. The TypeScript CLI, local MCP, remote MCP, and web
77
- app are the maintained paths.
74
+ **The Python implementation is deleted in 1.0.0** — including the frozen MCP-server fallback
75
+ (`uv run cerefox mcp`), the husked Python CLI / web / ingestion packages, and
76
+ `pyproject.toml`. There is no Python code left to run.
77
+
78
+ If you still invoke `uv run cerefox mcp`, switch to the maintained local server:
79
+
80
+ ```bash
81
+ npx --package=@cerefox/memory cerefox mcp
82
+ ```
83
+
84
+ (or stay on 0.11.x until you have migrated). The TypeScript CLI, local MCP, remote MCP, and
85
+ web app are the only maintained paths. The SQL schema assets under `src/cerefox/db/` are
86
+ unaffected — they are not Python and remain the source of truth for the schema + RPCs.
78
87
 
79
88
  ## Upgrade order summary
80
89
 
@@ -30,10 +30,8 @@ The canonical scripts are **TypeScript**, run with [Bun](https://bun.sh) (instal
30
30
  | `backup_restore.ts` | `bun scripts/backup_restore.ts` |
31
31
  | `reindex_all.ts` | `bun scripts/reindex_all.ts` |
32
32
 
33
- The `.py` equivalents are **legacy** — they still exist as a migration aid but are no longer
34
- maintained; use the `.ts` scripts. The legacy `db_status.py` and `sync_docs.py` are
35
- deprecation shims that exit non-zero with a pointer to the TS replacement, so update any cron
36
- jobs / CI / make targets that invoke them.
33
+ Use the `.ts` scripts. The former `.py` equivalents were **removed at v1.0.0** — update any
34
+ cron jobs / CI / make targets that still invoke a `python scripts/*.py` path.
37
35
 
38
36
  ### TS scripts and `.env` resolution
39
37
 
@@ -75,7 +73,7 @@ CEREFOX_DATABASE_URL=postgresql://cerefox:cerefox@localhost:5432/cerefox \
75
73
 
76
74
  ## db_status.ts — Schema verification
77
75
 
78
- **TypeScript (v0.3.0+).** Checks that the schema is correctly deployed and reports table statistics. Replaces the legacy `db_status.py`, which now prints a deprecation notice and exits non-zero.
76
+ **TypeScript (v0.3.0+).** Checks that the schema is correctly deployed and reports table statistics. Replaces the former `db_status.py` (removed at v1.0.0).
79
77
 
80
78
  ```bash
81
79
  bun scripts/db_status.ts # human-readable report
@@ -223,7 +221,7 @@ The backup directory (`./backup-data/` by default) is gitignored. Back up the ba
223
221
 
224
222
  Ingests `README.md`, `AGENT_GUIDE.md`, `AGENT_QUICK_REFERENCE.md`, and every Markdown file under `docs/` into your Cerefox knowledge base, updating existing documents in-place. Run this any time after editing documentation so AI agents always have access to the current state of the project.
225
223
 
226
- Replaces the legacy `sync_docs.py`, which now prints a deprecation notice and exits non-zero.
224
+ Replaces the former `sync_docs.py` (removed at v1.0.0).
227
225
 
228
226
  ```bash
229
227
  bun scripts/sync_docs.ts [OPTIONS]
@@ -133,8 +133,8 @@ You should see results from the bundled self-docs.
133
133
 
134
134
  The path above is for **end users** (no clone). If you want to hack on Cerefox,
135
135
  clone the repo, run `bun install`, and use the contributor scripts
136
- (`bun scripts/db_deploy.ts`, `bun scripts/db_migrate.ts`). `uv` is only needed
137
- for the legacy Python MCP fallback. See [`CONTRIBUTING.md`](../../CONTRIBUTING.md).
136
+ (`bun scripts/db_deploy.ts`, `bun scripts/db_migrate.ts`). See
137
+ [`CONTRIBUTING.md`](../../CONTRIBUTING.md).
138
138
  (Want a no-cloud install instead? That's the self-hosted Docker backend —
139
139
  [`setup-local.md`](setup-local.md).)
140
140
 
@@ -9,12 +9,9 @@
9
9
 
10
10
  Deploy the Cerefox web UI to Google Cloud Run for a lightweight, serverless hosting option. This guide uses Supabase (free tier) for the database.
11
11
 
12
- > **Note (v0.9):** The Cerefox web UI is now the TypeScript server (`cerefox web` — Hono
13
- > backend + React/Mantine SPA), not the retired Python/FastAPI app. The container build and
14
- > env-var wiring below still apply, but the `Dockerfile` must build/serve the TS `cerefox web`
15
- > server (port 8000), and any reference to the old Python image should be treated as **needing
16
- > revalidation** against the current `Dockerfile`. The "Securing access" middleware example is
17
- > flagged inline.
12
+ > **Note:** The Cerefox web UI is the TypeScript server (`cerefox web` — Hono backend +
13
+ > React/Mantine SPA); the Python/FastAPI app was removed at v1.0.0. The container `Dockerfile`
14
+ > builds and serves the TS `cerefox web` server (port 8000).
18
15
 
19
16
  ---
20
17
 
@@ -128,7 +125,6 @@ Use Identity-Aware Proxy (IAP) in front of Cloud Run for Google SSO.
128
125
  ### Option 3 — Add HTTP basic auth
129
126
 
130
127
  Add a Hono middleware to the TS `cerefox web` server that checks `Authorization: Basic ...`
131
- headers, using `CEREFOX_BASIC_AUTH_USER` / `CEREFOX_BASIC_AUTH_PASSWORD` env vars. (The
132
- old Python `src/cerefox/api/app.py` middleware path is retired — this needs revalidation
133
- against the current TS web server's middleware hook.)
128
+ headers, using `CEREFOX_BASIC_AUTH_USER` / `CEREFOX_BASIC_AUTH_PASSWORD` env vars
129
+ (implement it against the current TS `cerefox web` server's middleware hook).
134
130
 
@@ -12,7 +12,7 @@ This guide walks you from a blank Supabase project to a fully deployed Cerefox s
12
12
  - **Node.js 20+** or **Bun 1.0+** (the CLI runtime; also used for `npx supabase`).
13
13
  - A Supabase account (free tier is enough): [supabase.com](https://supabase.com)
14
14
 
15
- > The `python scripts/db_*.py` paths shown in the contributor footnotes below are **legacy**. The Python implementation is legacy and slated for removal in a future release; only the Python MCP server remains as a fallback. Contributors with a repo clone should use `bun scripts/db_deploy.ts` / `bun scripts/db_migrate.ts`.
15
+ > Contributors with a repo clone use `bun scripts/db_deploy.ts` / `bun scripts/db_migrate.ts` for the low-level schema path. (The former `python scripts/db_*.py` equivalents were removed at v1.0.0.)
16
16
 
17
17
  ---
18
18
 
@@ -161,7 +161,7 @@ Re-run `cerefox doctor` — the "edge functions" check goes green.
161
161
 
162
162
  > **Contributors** (repo clone): the low-level path is `bun scripts/db_deploy.ts`
163
163
  > / `bun scripts/db_migrate.ts` for schema, and `npx supabase functions deploy
164
- > <name>` per Edge Function. The `python scripts/db_deploy.py` path is legacy.
164
+ > <name>` per Edge Function.
165
165
 
166
166
  ---
167
167
 
@@ -349,7 +349,7 @@ In 2026 Supabase rolled out a new API key system. The dashboard now shows two ke
349
349
 
350
350
  | Variable | Recommended value | Why |
351
351
  |---|---|---|
352
- | `CEREFOX_SUPABASE_KEY` | New **secret key** (`sb_secret_…`). Legacy `service_role` JWT also works. | Used by `db/client.py` to reach the Data API (PostgREST). Both formats are accepted by the gateway. |
352
+ | `CEREFOX_SUPABASE_KEY` | New **secret key** (`sb_secret_…`). Legacy `service_role` JWT also works. | Used by the CLI / web app to reach the Data API (PostgREST). Both formats are accepted by the gateway. |
353
353
  | `CEREFOX_ACCESS_TOKEN` | **Cerefox access token** (`cfx_pat_…`) from `cerefox token generate`. | The `Authorization: Bearer …` credential for Edge Function calls (remote MCP, GPT Actions, e2e tests, direct curl). Validated in-function; rotatable via `cerefox token rotate`. |
354
354
  | `CEREFOX_SUPABASE_ANON_KEY` | *(deprecated / unused)* | Formerly the Edge Function Bearer credential. Retired in iter-28E; retained only so an old `.env` still parses. |
355
355
 
@@ -52,9 +52,8 @@ migrations) + `bun scripts/db_deploy.ts` (re-apply RPCs) + `npx supabase
52
52
  functions deploy <fn>`. These need `CEREFOX_DATABASE_URL` (direct Postgres) and
53
53
  a linked Supabase project.
54
54
 
55
- > Python is legacy: the Python CLI and FastAPI web app are husks; only
56
- > `uv run cerefox mcp` survives as a frozen, unmaintained fallback. Tests run
57
- > via `bun test` (pytest is retired).
55
+ > Python was **fully removed at v1.0.0** (CLI, FastAPI web app, and the
56
+ > `uv run cerefox mcp` fallback). Tests run via `bun test`.
58
57
 
59
58
  ## Notable cross-version transitions
60
59
 
@@ -66,8 +65,7 @@ knowing about:
66
65
  `deploy-server`, `docs`, …) still run but print the new form and exit
67
66
  non-zero — so any scripts or aliases tell you exactly what to change. Re-run
68
67
  `cerefox completion install` to refresh tab-completion. The Python CLI + web
69
- app became husks at v0.9; `uv run cerefox mcp` is the only surviving Python
70
- path.
68
+ app became husks at v0.9 and were fully removed at v1.0.0.
71
69
  - **v0.4–v0.5 — the runtime moved Python → TypeScript** and became the
72
70
  `@cerefox/memory` npm package (CLI, MCP server, web server, ingestion). If
73
71
  you're coming from a pre-installer 0.1.x clone, see the "old pre-installer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cerefox/memory",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.2",
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",