@cerefox/memory 1.15.0 → 1.15.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,8 +15,8 @@
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-DUY9wimN.js"></script>
19
- <link rel="stylesheet" crossorigin href="/app/assets/index-Dm_zCch4.css">
18
+ <script type="module" crossorigin src="/app/assets/index-DWeD_pcf.js"></script>
19
+ <link rel="stylesheet" crossorigin href="/app/assets/index-B0H_N4if.css">
20
20
  </head>
21
21
  <body>
22
22
  <div id="root"></div>
@@ -18,7 +18,7 @@
18
18
  * doesn't touch `supabase/functions/` leaves it alone).
19
19
  */
20
20
 
21
- export const EF_VERSION = "1.15.0";
21
+ export const EF_VERSION = "1.15.2";
22
22
 
23
23
  /**
24
24
  * The Cerefox RELEASE version — what `cerefox --version` reports and what npm
@@ -36,7 +36,7 @@ export const EF_VERSION = "1.15.0";
36
36
  * is imported by the Deno Edge Functions, which cannot reach into the npm
37
37
  * package.
38
38
  */
39
- export const CEREFOX_VERSION = "1.15.0";
39
+ export const CEREFOX_VERSION = "1.15.2";
40
40
 
41
41
  /**
42
42
  * The most recent version whose EF-side SOURCE actually changed (#127).
@@ -46,7 +46,7 @@ export const CEREFOX_VERSION = "1.15.0";
46
46
  * `cut_release.ts` ONLY when EF source changed since the last tag; doctor
47
47
  * uses it to stay silent on label-only drift.
48
48
  */
49
- export const EF_LAST_CHANGED = "1.14.5";
49
+ export const EF_LAST_CHANGED = "1.15.2";
50
50
 
51
51
  /**
52
52
  * The 8 peer EFs the cerefox-mcp aggregator probes (excludes cerefox-mcp
@@ -65,6 +65,12 @@ async function loadTransformers(): Promise<typeof transformersModule> {
65
65
  // eszip for the EF) from statically resolving the ~30 MB package + native
66
66
  // onnxruntime binary. Resolved at runtime from node_modules.
67
67
  const spec = "@huggingface/transformers";
68
+ // onnxruntime 1.29+ ships Microsoft usage telemetry (a device id plus usage
69
+ // events, queued on disk and posted to mobile.events.data.microsoft.com).
70
+ // This is the embedder that exists so nothing leaves the machine, so opt out
71
+ // before the native library loads. `??=`: an operator who sets it explicitly
72
+ // (to anything) keeps their choice.
73
+ process.env.ORT_DISABLE_TELEMETRY ??= "1";
68
74
  transformersModule = await import(spec);
69
75
  const dir = getCacheDir();
70
76
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
@@ -0,0 +1,55 @@
1
+ -- 0032_derive_grants.sql — derive the Data API grant list instead of listing it
2
+ --
3
+ -- Issue: the explicit-grant block (0013, #26) names its tables in a hand-written
4
+ -- ARRAY. That array has to match the set of `cerefox_*` tables, and it drifted:
5
+ -- `cerefox_document_relations` was added to schema.sql and never added to the
6
+ -- array. On an UPGRADE path that table is fine (0014 grants it inline), and on
7
+ -- the self-hosted stack `roles.sql` grants broadly via its own PostgREST wiring
8
+ -- — so the gap is invisible everywhere except the case nobody runs by hand: a
9
+ -- FRESH cloud deploy, where `ALTER DEFAULT PRIVILEGES` cannot help because it
10
+ -- only affects tables created AFTER it runs.
11
+ --
12
+ -- From 2026-10-30 Supabase stops granting Data API access to new tables in
13
+ -- `public` automatically, so a missing grant stops being cosmetic and becomes a
14
+ -- 42501 the first time anything reaches that table over PostgREST.
15
+ --
16
+ -- The fix is the one this project keeps arriving at: derive the list. Every
17
+ -- `cerefox_*` table in `public` is granted, so a new table cannot be forgotten.
18
+ -- Idempotent and safe to re-run.
19
+ --
20
+ -- `anon` and `authenticated` still get NOTHING, deliberately: every Cerefox
21
+ -- client authenticates with a service-role-equivalent key, and the RPCs are
22
+ -- SECURITY DEFINER. Supabase's migration note suggests granting all three
23
+ -- roles; doing so here would widen the surface for no caller.
24
+
25
+ DO $$
26
+ DECLARE t TEXT;
27
+ BEGIN
28
+ IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'service_role') THEN
29
+ RAISE NOTICE 'service_role absent (self-hosted stack) — grants skipped; roles.sql wires PostgREST';
30
+ RETURN;
31
+ END IF;
32
+
33
+ GRANT USAGE ON SCHEMA public TO service_role;
34
+
35
+ -- Derived from the catalogue, not from a list someone has to remember.
36
+ FOR t IN
37
+ SELECT c.relname
38
+ FROM pg_class c
39
+ JOIN pg_namespace n ON n.oid = c.relnamespace
40
+ WHERE n.nspname = 'public'
41
+ AND c.relkind = 'r'
42
+ AND c.relname LIKE 'cerefox\_%'
43
+ LOOP
44
+ EXECUTE format(
45
+ 'GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE public.%I TO service_role', t
46
+ );
47
+ END LOOP;
48
+
49
+ -- Tables created LATER by the deploying role inherit the same grants. This
50
+ -- is belt-and-braces next to the loop above, not a substitute for it: it
51
+ -- cannot retro-grant anything that already exists, which is exactly how
52
+ -- cerefox_document_relations slipped through.
53
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
54
+ GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO service_role;
55
+ END $$;
@@ -3091,6 +3091,11 @@ SET search_path = public, pg_catalog
3091
3091
  AS $$
3092
3092
  -- Keep in lockstep with the `@version:` marker in schema.sql (cut_release.ts
3093
3093
  -- enforces it). Bump whenever schema.sql OR rpcs.sql changes.
3094
+ -- 0.16.2 (#26 follow-up): the Data API grant list is DERIVED from pg_class
3095
+ -- rather than a hand-written array that has to match the set of tables. The
3096
+ -- array had drifted (cerefox_document_relations), which only a FRESH cloud
3097
+ -- deploy would have surfaced, and only after Supabase stops granting new
3098
+ -- public tables automatically on 2026-10-30. Migration 0032.
3094
3099
  -- 0.16.1 (v1.13.1): cerefox_ingest_document no longer consults
3095
3100
  -- `review_workflow_enabled` — review_status follows author_type whatever
3096
3101
  -- the flag says; the flag governs visibility/enforcement only. RPC-only,
@@ -3124,7 +3129,7 @@ AS $$
3124
3129
  -- 0.11.0 supersedes 0.10.6 (v1.2.1, #191): this branch carries that fix plus
3125
3130
  -- the partial-edit surface, and both migrations (0019, 0020) are in the
3126
3131
  -- sequence, so a store deploying this gets everything from both lines.
3127
- SELECT '0.16.1'::TEXT;
3132
+ SELECT '0.16.2'::TEXT;
3128
3133
  $$;
3129
3134
 
3130
3135
  -- ── cerefox_find_dead_links ──────────────────────────────────────────────────
@@ -5,7 +5,7 @@
5
5
  -- Requires extensions: vector (pgvector), uuid-ossp
6
6
  -- These are enabled at the top of db_deploy.py before this file is applied.
7
7
  --
8
- -- @version: 0.16.1
8
+ -- @version: 0.16.2
9
9
  -- The `@version` marker above is read by the schema-version-mismatch banner
10
10
  -- (see /api/v1/schema-version). Bump it whenever schema.sql OR rpcs.sql
11
11
  -- changes in a way that requires `cerefox server deploy` to be re-run —
@@ -482,21 +482,29 @@ ALTER TABLE cerefox_document_relations ENABLE ROW LEVEL SECURITY;
482
482
  -- Guarded: on the local (World B) stack this file deploys BEFORE roles.sql
483
483
  -- creates service_role, so missing-role must be a no-op (roles.sql re-runs the
484
484
  -- grants implicitly via its own PostgREST wiring; the next deploy picks them up).
485
+ -- DERIVED from the catalogue, never listed. The list used to be a hand-written
486
+ -- ARRAY and it drifted: cerefox_document_relations was added above and never
487
+ -- added to the array, so a FRESH cloud deploy left that table with no Data API
488
+ -- grant. Upgrades hid it (migration 0014 grants it inline) and the self-hosted
489
+ -- stack hid it (roles.sql grants broadly), which is why it survived unnoticed.
490
+ -- ALTER DEFAULT PRIVILEGES below cannot cover it either — that only affects
491
+ -- tables created AFTER it runs. See migration 0032.
485
492
  DO $$
486
493
  DECLARE t TEXT;
487
494
  BEGIN
488
495
  IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'service_role') THEN
489
496
  GRANT USAGE ON SCHEMA public TO service_role;
490
- FOREACH t IN ARRAY ARRAY[
491
- 'cerefox_projects', 'cerefox_documents', 'cerefox_document_versions',
492
- 'cerefox_audit_log', 'cerefox_document_projects', 'cerefox_chunks',
493
- 'cerefox_migrations', 'cerefox_config', 'cerefox_usage_log'
494
- ] LOOP
495
- IF to_regclass('public.' || t) IS NOT NULL THEN
496
- EXECUTE format('GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE public.%I TO service_role', t);
497
- END IF;
497
+ FOR t IN
498
+ SELECT c.relname
499
+ FROM pg_class c
500
+ JOIN pg_namespace n ON n.oid = c.relnamespace
501
+ WHERE n.nspname = 'public'
502
+ AND c.relkind = 'r'
503
+ AND c.relname LIKE 'cerefox\_%'
504
+ LOOP
505
+ EXECUTE format('GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE public.%I TO service_role', t);
498
506
  END LOOP;
499
- -- Future cerefox_* tables created by the deploying role keep working.
507
+ -- Tables created LATER by the deploying role inherit the same grants.
500
508
  ALTER DEFAULT PRIVILEGES IN SCHEMA public
501
509
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO service_role;
502
510
  END IF;
@@ -29,6 +29,16 @@ The canonical scripts are **TypeScript**, run with [Bun](https://bun.sh) (instal
29
29
  | `backup_create.ts` | `bun scripts/backup_create.ts` |
30
30
  | `backup_restore.ts` | `bun scripts/backup_restore.ts` |
31
31
  | `reindex_all.ts` | `bun scripts/reindex_all.ts` |
32
+ | `cerefox_export.ts` | `bun scripts/cerefox_export.ts` |
33
+ | `gen_openapi.ts` | `bun scripts/gen_openapi.ts` |
34
+ | `cut_release.ts` | `bun scripts/cut_release.ts` (see [RELEASING.md](../../RELEASING.md)) |
35
+
36
+ The remaining files under `scripts/` are not run by hand: `bundle_help.ts`,
37
+ `bundle_package_docs.ts` and `bundle_server_assets.ts` are `prepublishOnly` steps,
38
+ and `check_ef_parity.ts` and `check_help_bundle.ts` are CI checks.
39
+ `_shared/__tests__/ops-scripts-documented.test.ts` holds that split, so a new
40
+ script has to be either documented here or deliberately classified — it cannot be
41
+ silently forgotten.
32
42
 
33
43
  Use the `.ts` scripts. The former `.py` equivalents were **removed at v1.0.0** — update any
34
44
  cron jobs / CI / make targets that still invoke a `python scripts/*.py` path.
@@ -230,6 +240,92 @@ The backup directory (`./backup-data/` by default) is gitignored. Back up the ba
230
240
 
231
241
  ---
232
242
 
243
+ ## cerefox_export.ts — Export every document as markdown files
244
+
245
+ A one-way dump for local browsing, grepping and offline copies. **Not** a restore
246
+ path: use `backup_create.ts` / `backup_restore.ts` for that.
247
+
248
+ ```bash
249
+ bun scripts/cerefox_export.ts <target-folder>
250
+ bun scripts/cerefox_export.ts <target-folder> --project "My Project"
251
+ bun scripts/cerefox_export.ts <target-folder> --force # allow a non-empty target
252
+ bun scripts/cerefox_export.ts <target-folder> --no-metadata # content only
253
+ ```
254
+
255
+ Layout — one folder per project, documents with no project at the root:
256
+
257
+ ```
258
+ <target>/<project-slug>/<title-slug>.md the reconstructed markdown
259
+ <target>/<project-slug>/<title-slug>-metadata.md the metadata sidecar
260
+ ```
261
+
262
+ A document in several projects is written **once per project** (copies), so each
263
+ folder stands alone.
264
+
265
+ ### The metadata sidecar
266
+
267
+ Each document gets a `-metadata.md` beside it, so an exported file is
268
+ self-describing rather than anonymous prose. It carries the document id, source,
269
+ **every** project membership (not just the folder that copy is in), created and
270
+ updated timestamps, character and chunk counts, the metadata keys as a table, and
271
+ the **`content_hash`** — the concurrency token, so an exported copy can be edited
272
+ and re-ingested with `expected_content_hash`.
273
+
274
+ `review_status` appears only when the store has the review workflow enabled; when
275
+ it is off the field is absent from every other surface, and an export is not the
276
+ place to resurrect it.
277
+
278
+ Markdown rather than JSON so the sidecars are readable in the same editor as the
279
+ documents. Pass `--no-metadata` for the older content-only behaviour.
280
+
281
+ Two naming details worth knowing:
282
+
283
+ - Title collisions get a numeric suffix (`doc-2.md`), and the sidecar follows the
284
+ file it describes (`doc-2-metadata.md`).
285
+ - A document whose own title ends in "metadata" produces a content file named
286
+ exactly like another document's sidecar (`foo-metadata.md` is both the export
287
+ of "Foo Metadata" and the sidecar of "Foo"). Sidecar names share the same
288
+ uniqueness domain as content files, so whichever is written second gets the
289
+ numeric suffix and neither can overwrite the other. A real store contains such
290
+ a pair.
291
+
292
+ ## gen_openapi.ts — Regenerate the OpenAPI document
293
+
294
+ `docs/api/openapi.json` describes `/api/v1` in OpenAPI 3.1, for callers that embed
295
+ Cerefox instead of using MCP or the CLI. Point any OpenAPI tool at it to generate
296
+ a client or a tool set.
297
+
298
+ ```bash
299
+ bun scripts/gen_openapi.ts # write docs/api/openapi.json
300
+ bun scripts/gen_openapi.ts --check # fail if the committed file is stale (CI)
301
+ bun scripts/gen_openapi.ts --stdout # print, write nothing
302
+ ```
303
+
304
+ **Run it after changing a route, a summary in [`api.md`](api.md), or a zod schema
305
+ in `_shared/schemas/`.** You will not forget silently:
306
+ `_shared/__tests__/api-openapi-spec.test.ts` fails when the committed artifact is
307
+ not what the generator produces.
308
+
309
+ It is assembled from three sources rather than written, so no fact about the API
310
+ is authored twice:
311
+
312
+ | Part of the spec | Comes from |
313
+ |---|---|
314
+ | paths and methods | the route registrations in `packages/memory/src/web/routes/` |
315
+ | summaries | the endpoint table in `docs/guides/api.md` |
316
+ | request/response shapes | the zod schemas in `_shared/schemas/` |
317
+
318
+ Two things worth knowing about what it does *not* claim:
319
+
320
+ - **Coverage is stated, not implied.** `x-cerefox-coverage` in the document lists
321
+ how many routes carry a response schema, which routes legitimately return
322
+ something other than JSON, and which are unmodelled. An unmodelled route gets
323
+ **no** schema rather than a guessed one.
324
+ - **`info.version` is the API's, not the release's.** It moves when `/api/v1`
325
+ changes. Binding it to the package version made the committed artifact stale at
326
+ every release cut — which broke the v1.15.1 npm publish — and churned every
327
+ generated client on patch releases that did not touch the API.
328
+
233
329
  ## sync_docs.ts — Sync project documentation into Cerefox
234
330
 
235
331
  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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cerefox/memory",
3
- "version": "1.15.0",
3
+ "version": "1.15.2",
4
4
  "description": "Cerefox \u2014 user-owned shared memory for AI agents. CLI + stdio MCP server + web UI + ingestion for a knowledge base on your own Supabase project (or fully self-hosted with Cerefox Local).",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/fstamatelopoulos/cerefox",
@@ -40,27 +40,27 @@
40
40
  ],
41
41
  "dependencies": {
42
42
  "@hono/node-server": "^2.1.1",
43
- "@modelcontextprotocol/sdk": "^1.30.0",
44
- "@supabase/supabase-js": "^2.45.0",
43
+ "@modelcontextprotocol/sdk": "^1.30.1",
44
+ "@supabase/supabase-js": "^2.117.2",
45
45
  "cli-progress": "^3.12.0",
46
46
  "commander": "^15.0.0",
47
- "hono": "^4.13.7",
48
- "mammoth": "^1.9.0",
47
+ "hono": "^4.13.9",
48
+ "mammoth": "^1.13.0",
49
49
  "ora": "^9.4.0",
50
50
  "picocolors": "^1.0.0",
51
51
  "postgres": "^3.4.9",
52
52
  "prompts": "^2.4.2",
53
- "smol-toml": "^1.6.1",
53
+ "smol-toml": "^1.9.0",
54
54
  "zod": "^4.6.5"
55
55
  },
56
56
  "optionalDependencies": {
57
- "@huggingface/transformers": "^4.2.0",
57
+ "@huggingface/transformers": "^4.3.0",
58
58
  "onnxruntime-node": "^1.21.0"
59
59
  },
60
60
  "devDependencies": {
61
- "@types/bun": "^1.3.14",
61
+ "@types/bun": "^1.4.2",
62
62
  "@types/cli-progress": "^3.11.5",
63
- "@types/node": "^24.13.3",
63
+ "@types/node": "^24.19.0",
64
64
  "@types/prompts": "^2.4.9",
65
65
  "typescript": "^6.0.3"
66
66
  },