@cerefox/memory 1.15.3 → 1.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1103,6 +1103,82 @@ AS $$
1103
1103
  ORDER BY created_at DESC;
1104
1104
  $$;
1105
1105
 
1106
+ -- ── cerefox_purge_expired_trash (#251, 0.17.0) ───────────────────────────────
1107
+ -- Permanently purges documents that have been in the trash longer than
1108
+ -- `trash_retention_days`, when `trash_auto_purge_enabled` is exactly 'true'.
1109
+ -- Called by cerefox_delete_document after every real soft delete: the write
1110
+ -- that adds to the trash also sweeps it. There is no scheduler, by decision
1111
+ -- (docs/specs/trash-auto-purge.md): the trash only grows through deletes, so
1112
+ -- this keeps it bounded on every deployment without pg_cron or a daemon.
1113
+ --
1114
+ -- Safeguards, each load-bearing:
1115
+ -- * at most p_max documents per call, oldest first (partial index on
1116
+ -- deleted_at), so a large first backlog drains over several deletes;
1117
+ -- * FOR UPDATE SKIP LOCKED, so concurrent deletes sweep disjoint rows;
1118
+ -- * an unparsable or < 1 retention purges NOTHING (never "purge everything");
1119
+ -- * one audit entry per purge, authored 'trash-retention' / 'user': the
1120
+ -- authority is the operator's setting, not whoever's delete triggered it.
1121
+ -- Not exposed on MCP, the Edge Functions or the CLI: there is still no
1122
+ -- agent-callable purge (access-paths.md → trust model).
1123
+ CREATE OR REPLACE FUNCTION cerefox_purge_expired_trash(
1124
+ p_max INT DEFAULT 100
1125
+ )
1126
+ RETURNS INT
1127
+ LANGUAGE plpgsql
1128
+ SECURITY DEFINER
1129
+ SET search_path = public, pg_catalog
1130
+ AS $$
1131
+ DECLARE
1132
+ v_enabled TEXT;
1133
+ v_days_txt TEXT;
1134
+ v_days INT;
1135
+ v_cutoff TIMESTAMPTZ;
1136
+ v_count INT := 0;
1137
+ r RECORD;
1138
+ BEGIN
1139
+ SELECT value INTO v_enabled FROM cerefox_config WHERE key = 'trash_auto_purge_enabled';
1140
+ IF v_enabled IS DISTINCT FROM 'true' THEN
1141
+ RETURN 0;
1142
+ END IF;
1143
+
1144
+ SELECT value INTO v_days_txt FROM cerefox_config WHERE key = 'trash_retention_days';
1145
+ IF v_days_txt IS NULL OR BTRIM(v_days_txt) !~ '^[0-9]{1,6}$' THEN
1146
+ RETURN 0;
1147
+ END IF;
1148
+ v_days := BTRIM(v_days_txt)::INT;
1149
+ IF v_days < 1 THEN
1150
+ RETURN 0;
1151
+ END IF;
1152
+ v_cutoff := NOW() - make_interval(days => v_days);
1153
+
1154
+ FOR r IN
1155
+ SELECT id, title, total_chars, deleted_at
1156
+ FROM cerefox_documents
1157
+ WHERE deleted_at IS NOT NULL AND deleted_at < v_cutoff
1158
+ ORDER BY deleted_at
1159
+ LIMIT GREATEST(COALESCE(p_max, 0), 0)
1160
+ FOR UPDATE SKIP LOCKED
1161
+ LOOP
1162
+ PERFORM cerefox_create_audit_entry(
1163
+ p_document_id := r.id,
1164
+ p_operation := 'delete',
1165
+ p_author := 'trash-retention',
1166
+ p_author_type := 'user',
1167
+ p_size_before := r.total_chars,
1168
+ p_size_after := 0,
1169
+ p_description := 'Auto-purged from the trash (trash_retention_days = ' || v_days ||
1170
+ '; trashed ' || to_char(r.deleted_at AT TIME ZONE 'UTC', 'YYYY-MM-DD') ||
1171
+ '): ' || COALESCE(r.title, '(untitled)') ||
1172
+ ' (' || COALESCE(r.total_chars, 0) || ' chars)'
1173
+ );
1174
+ DELETE FROM cerefox_documents WHERE id = r.id;
1175
+ v_count := v_count + 1;
1176
+ END LOOP;
1177
+
1178
+ RETURN v_count;
1179
+ END;
1180
+ $$;
1181
+
1106
1182
  -- ── cerefox_delete_document (soft delete) ────────────────────────────────────
1107
1183
  -- Soft-deletes a document by setting deleted_at = NOW(). The document, its
1108
1184
  -- chunks, and versions remain in the database but are excluded from search.
@@ -1123,6 +1199,12 @@ $$;
1123
1199
  --
1124
1200
  -- Deleting an already-deleted document is a reported no-op: the original
1125
1201
  -- deleted_at is preserved and no duplicate audit entry is written.
1202
+ --
1203
+ -- 0.17.0 (#251): a real soft delete then sweeps the trash
1204
+ -- (cerefox_purge_expired_trash) and reports how many documents it purged as
1205
+ -- `auto_purged`. The sweep runs in its own sub-block: if it fails, only its
1206
+ -- savepoint rolls back, a WARNING is raised, and the delete commits exactly as
1207
+ -- it would with auto-purge off. A sweep can never fail a delete.
1126
1208
 
1127
1209
  DROP FUNCTION IF EXISTS cerefox_delete_document(UUID, TEXT, TEXT, TEXT, TEXT);
1128
1210
  DROP FUNCTION IF EXISTS cerefox_delete_document(UUID, TEXT, TEXT);
@@ -1144,6 +1226,7 @@ DECLARE
1144
1226
  v_total_chars INT;
1145
1227
  v_current_hash TEXT;
1146
1228
  v_deleted_at TIMESTAMPTZ;
1229
+ v_auto_purged INT := 0;
1147
1230
  BEGIN
1148
1231
  -- FOR UPDATE: makes the hash check atomic with the delete — a concurrent
1149
1232
  -- content update serializes here, and a stale deleter sees its hash.
@@ -1202,12 +1285,21 @@ BEGIN
1202
1285
  COALESCE('; reason: ' || NULLIF(BTRIM(p_reason), ''), '')
1203
1286
  );
1204
1287
 
1288
+ BEGIN
1289
+ v_auto_purged := cerefox_purge_expired_trash(100);
1290
+ EXCEPTION WHEN OTHERS THEN
1291
+ v_auto_purged := 0;
1292
+ RAISE WARNING 'cerefox: trash auto-purge skipped after deleting %: % (%)',
1293
+ p_document_id, SQLERRM, SQLSTATE;
1294
+ END;
1295
+
1205
1296
  RETURN jsonb_build_object(
1206
1297
  'document_id', p_document_id,
1207
1298
  'title', v_title,
1208
1299
  'total_chars', v_total_chars,
1209
1300
  'deleted_at', v_deleted_at,
1210
- 'already_deleted', FALSE
1301
+ 'already_deleted', FALSE,
1302
+ 'auto_purged', v_auto_purged
1211
1303
  );
1212
1304
  END;
1213
1305
  $$;
@@ -2742,7 +2834,10 @@ DECLARE
2742
2834
  -- (0 = off). Partial edits make writes cheap, so an insert-only agent
2743
2835
  -- never assembles the document and never sees it grow past its split
2744
2836
  -- point. A signal in the write's response, never a refusal.
2745
- 'document_size_warning_chars'
2837
+ 'document_size_warning_chars',
2838
+ -- #251: trash auto-purge, off by default; read by
2839
+ -- cerefox_purge_expired_trash on every soft delete.
2840
+ 'trash_auto_purge_enabled', 'trash_retention_days'
2746
2841
  ];
2747
2842
  v_old TEXT;
2748
2843
  BEGIN
@@ -3091,6 +3186,9 @@ SET search_path = public, pg_catalog
3091
3186
  AS $$
3092
3187
  -- Keep in lockstep with the `@version:` marker in schema.sql (cut_release.ts
3093
3188
  -- enforces it). Bump whenever schema.sql OR rpcs.sql changes.
3189
+ -- 0.17.0 (#251): trash auto-purge. New cerefox_purge_expired_trash, called
3190
+ -- by cerefox_delete_document after a real soft delete (which now returns
3191
+ -- `auto_purged`); two config keys, off by default. Migration 0033.
3094
3192
  -- 0.16.2 (#26 follow-up): the Data API grant list is DERIVED from pg_class
3095
3193
  -- rather than a hand-written array that has to match the set of tables. The
3096
3194
  -- array had drifted (cerefox_document_relations), which only a FRESH cloud
@@ -3129,7 +3227,7 @@ AS $$
3129
3227
  -- 0.11.0 supersedes 0.10.6 (v1.2.1, #191): this branch carries that fix plus
3130
3228
  -- the partial-edit surface, and both migrations (0019, 0020) are in the
3131
3229
  -- sequence, so a store deploying this gets everything from both lines.
3132
- SELECT '0.16.2'::TEXT;
3230
+ SELECT '0.17.0'::TEXT;
3133
3231
  $$;
3134
3232
 
3135
3233
  -- ── 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.2
8
+ -- @version: 0.17.0
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 —
@@ -413,6 +413,15 @@ ON CONFLICT (key) DO NOTHING;
413
413
  INSERT INTO cerefox_config (key, value)
414
414
  VALUES ('review_workflow_enabled', 'false')
415
415
  ON CONFLICT (key) DO NOTHING;
416
+ -- Trash auto-purge (#251): OFF by default. When on, the soft delete that adds
417
+ -- to the trash also purges documents trashed more than trash_retention_days
418
+ -- ago (cerefox_purge_expired_trash). Design: docs/specs/trash-auto-purge.md.
419
+ INSERT INTO cerefox_config (key, value)
420
+ VALUES ('trash_auto_purge_enabled', 'false')
421
+ ON CONFLICT (key) DO NOTHING;
422
+ INSERT INTO cerefox_config (key, value)
423
+ VALUES ('trash_retention_days', '60')
424
+ ON CONFLICT (key) DO NOTHING;
416
425
 
417
426
 
418
427
  -- ── Usage log ────────────────────────────────────────────────────────────────
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "Cerefox /api/v1",
5
- "version": "1.1.0",
5
+ "version": "1.2.0",
6
6
  "description": "The HTTP API served by `cerefox web`. Intended for callers that embed Cerefox rather than\nusing MCP or the CLI — MCP remains the recommended path for AI agents.\n\nGENERATED by `bun scripts/gen_openapi.ts`; do not edit by hand. Paths and every input a route\nreads come from the route handlers, summaries from the endpoint table in docs/guides/api.md,\nand body shapes from the zod schemas in `_shared/schemas/` (responses verified against a live\nserver by `api-schema-truth.test.ts`).\n\nAUTH: a request arriving on loopback needs no credential. From any other interface, an\n`X-API-Key` (or `Authorization: Bearer`) matching `CEREFOX_API_KEY` is required.\nSee docs/guides/securing-local-access.md.\n\nIDENTITY: send `X-Cerefox-Author` (and optionally `X-Cerefox-Author-Type`) to be recorded as\nyourself. Without them you are recorded as the bundled web UI.\n\nCONCURRENCY: read before you write. A content update (`POST /ingest` with `document_id` or\n`update_if_exists`, `POST /documents/{id}/edit`, `/upload`) needs the `content_hash` you read\nas `expected_content_hash`, or an explicit `last_write_wins`. `DELETE /documents/{id}` needs it\ntoo when you identify yourself, as `X-Cerefox-Expected-Content-Hash` or a query parameter.\nNeither is a 400 (`CEREFOX_TOKEN_REQUIRED`); a stale hash is a 409 carrying `current_hash`.\nRestore and purge take no hash.\n\nDISCOVERY: this document is served at `GET /api/v1/openapi.json` by the server it describes,\nand every /api/v1 response carries `Link: </api/v1/openapi.json>; rel=\"service-desc\"` (RFC 8631)."
7
7
  },
8
8
  "servers": [
@@ -1289,6 +1289,11 @@
1289
1289
  },
1290
1290
  "already_deleted": {
1291
1291
  "type": "boolean"
1292
+ },
1293
+ "auto_purged": {
1294
+ "type": "integer",
1295
+ "minimum": -9007199254740991,
1296
+ "maximum": 9007199254740991
1292
1297
  }
1293
1298
  },
1294
1299
  "required": [
@@ -3096,7 +3101,7 @@
3096
3101
  },
3097
3102
  "/api/v1/documents/trash": {
3098
3103
  "get": {
3099
- "summary": "Soft-deleted documents, newest first, `limit` ≤ 500. The exact total is in the `X-Total-Count` response header (v1.14.1).",
3104
+ "summary": "Soft-deleted documents, newest first, `limit` ≤ 500. The exact total is in the `X-Total-Count` response header (v1.14.1). `deleted_before=<ISO timestamp>` restricts both to documents trashed before then.",
3100
3105
  "operationId": "get_documents_trash",
3101
3106
  "parameters": [
3102
3107
  {
@@ -3110,6 +3115,16 @@
3110
3115
  "maximum": 500,
3111
3116
  "default": 50
3112
3117
  }
3118
+ },
3119
+ {
3120
+ "name": "deleted_before",
3121
+ "in": "query",
3122
+ "required": false,
3123
+ "description": "Only documents trashed before this instant; `X-Total-Count` then counts exactly those. With now minus `trash_retention_days`, it is what trash auto-purge would make eligible.",
3124
+ "schema": {
3125
+ "type": "string",
3126
+ "format": "date-time"
3127
+ }
3113
3128
  }
3114
3129
  ],
3115
3130
  "responses": {
@@ -3194,6 +3209,16 @@
3194
3209
  }
3195
3210
  }
3196
3211
  },
3212
+ "400": {
3213
+ "description": "The request is malformed or incomplete: a bad parameter or body, an unknown body field, a blank identity header, or a content update with no `expected_content_hash` and no `last_write_wins` (`CEREFOX_TOKEN_REQUIRED`).",
3214
+ "content": {
3215
+ "application/json": {
3216
+ "schema": {
3217
+ "$ref": "#/components/schemas/Error"
3218
+ }
3219
+ }
3220
+ }
3221
+ },
3197
3222
  "401": {
3198
3223
  "description": "An API key is required: a non-loopback request while `CEREFOX_API_KEY` is set. See docs/guides/securing-local-access.md.",
3199
3224
  "content": {
@@ -5777,7 +5802,7 @@
5777
5802
  "x-cerefox-coverage": {
5778
5803
  "routes": 40,
5779
5804
  "withResponseSchema": 36,
5780
- "queryParameters": 41,
5805
+ "queryParameters": 42,
5781
5806
  "note": "Routes without a response schema are listed with their parameters and summary only. Nothing is invented; see `uncovered`.",
5782
5807
  "nonJson": [
5783
5808
  "GET /openapi.json",
@@ -258,7 +258,12 @@ before "completing" the parity table by adding purge to agent-facing access path
258
258
  > that in #210 (2026-08-13): every delete and restore is audited with author
259
259
  > attribution, restore cannot destroy content, and the CLI had `document restore`
260
260
  > all along — the boundary the docs described had already outgrown the code. The
261
- > guarded property is now exactly one thing: **no agent path to permanent purge.**
261
+ > guarded property is now exactly one thing: **no MCP, Edge Function or CLI path to
262
+ > permanent purge.** Stated precisely: the web UI's own backend, `/api/v1`, has a
263
+ > per-document purge endpoint, and any client that can reach the web server (on
264
+ > loopback, or elsewhere with the API key) can call it, an agent harness built on the
265
+ > HTTP API included. Securing that port is what keeps it human-only; see
266
+ > `securing-local-access.md`.
262
267
 
263
268
  ### The three tiers
264
269
 
@@ -266,7 +271,7 @@ before "completing" the parity table by adding purge to agent-facing access path
266
271
  |---|---|---|---|
267
272
  | 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 |
268
273
  | 2. Soft-destructive + recovery | `delete_document` (soft delete to trash), `restore_document` (un-trash), `set_review_status` (web only; a `404` while `review_workflow_enabled` is off) | yes — delete is restorable; restore recovers | CLI (`cerefox document delete` / `restore`), web UI, and — since v1.7.0 (#208, #210) — MCP (`cerefox_delete_document`, which requires the caller's read-hash, and `cerefox_restore_document`). **Not** the primitive GPT-Actions Edge Functions (deliberately deferred). |
269
- | 3. **Hard-destructive** | `purge_document` (permanent), `set_version_archived` (toggle version retention) | no (purge) | **Web UI only** |
274
+ | 3. **Hard-destructive** | `purge_document` (permanent), `set_version_archived` (toggle version retention) | no (purge) | **Web UI**, through its backend `/api/v1`, which any client that can reach the web server can also call. Never MCP, the Edge Functions or the CLI. |
270
275
 
271
276
  ### Why purge is web-UI-only
272
277
 
@@ -295,6 +300,23 @@ states the count, with a Stop button and a per-document audit entry; there is no
295
300
  server-side "purge everything" endpoint, on purpose, because `/api/v1` is
296
301
  reachable by anything holding the local key.
297
302
 
303
+ **Trash auto-purge (v1.16.0, opt-in) does not weaken this either, and here is exactly
304
+ why.** With `trash_auto_purge_enabled` on, every soft delete (including an agent's) also
305
+ purges documents that have been in the trash longer than `trash_retention_days`. So an
306
+ agent's action can *trigger* a purge. It stays within the model because:
307
+
308
+ - **a human turned the policy on and chose the period**: that period is the review
309
+ window of step 2, decided in advance instead of per document;
310
+ - the sweep purges only documents **older than that period**, never the one being
311
+ deleted and never anything an agent selects;
312
+ - it adds **no new way to purge**: the sweep function is not exposed over MCP or the
313
+ Edge Functions, has no CLI verb, and, like every RPC, is callable over the Data API
314
+ only with the service-role key. Explicit purge stays where it was: the web UI, and
315
+ `/api/v1`'s per-document endpoint for any client that can reach the web server.
316
+
317
+ With the setting off (the default), nothing here changes. Design:
318
+ [`docs/specs/trash-auto-purge.md`](../specs/trash-auto-purge.md).
319
+
298
320
  A `cerefox purge-doc` CLI command, a `cerefox_purge_document` MCP tool, or a
299
321
  `/documents/{id}/purge` HTTP endpoint accessible via the Cerefox token would each break this
300
322
  property. **Do not add them without a governance design that replaces the human-in-the-
@@ -189,7 +189,7 @@ default; Cerefox Local picks its own port and `cerefox-local status` prints it).
189
189
  | `GET /documents/{id}/versions` | Version history. |
190
190
  | `POST /documents/{id}/versions/{version_id}/archive` | Archive or unarchive one stored version (body `{ "archived": true\|false }`). Archiving strips a version's search artifacts; its content is kept as the safety copy. |
191
191
  | `GET /documents/{id}/download` | Raw markdown. |
192
- | `GET /documents/trash` | Soft-deleted documents, newest first, `limit` ≤ 500. The exact total is in the `X-Total-Count` response header (v1.14.1). |
192
+ | `GET /documents/trash` | Soft-deleted documents, newest first, `limit` ≤ 500. The exact total is in the `X-Total-Count` response header (v1.14.1). `deleted_before=<ISO timestamp>` restricts both to documents trashed before then. |
193
193
  | `POST /documents/metadata-search` | Query by metadata / project / time, no text query. |
194
194
  | `GET /metadata-keys` | Metadata keys with counts and example values. |
195
195
  | `GET /resolve-link`, `GET /check-filename` | Link and title resolution helpers. |
@@ -197,7 +197,7 @@ default; Cerefox Local picks its own port and `cerefox-local status` prints it).
197
197
  | `POST /ingest/file` | Create from a multipart file upload. |
198
198
  | `POST /documents/{id}/upload` | Replace a document's content from a file. |
199
199
  | `POST /documents/{id}/edit` | Update title, content, metadata, projects. Unknown fields are a `400`. |
200
- | `DELETE /documents/{id}` | Soft-delete (to trash). |
200
+ | `DELETE /documents/{id}` | Soft-delete (to trash). Returns `auto_purged`: documents this delete purged because they had outlived `trash_retention_days` (only while trash auto-purge is on). |
201
201
  | `POST /documents/{id}/restore` | Restore from trash. |
202
202
  | `DELETE /documents/{id}/purge` | Permanent delete. Irreversible. |
203
203
  | `POST /documents/{id}/review-status` | Approve or re-queue for review. `404` while the review workflow is off. |
@@ -270,6 +270,53 @@ cerefox document get <document-id> --version-id <version-id>
270
270
 
271
271
  ---
272
272
 
273
+ ## Trash auto-purge
274
+
275
+ Deleting a document moves it to the trash, where it stays until someone restores or
276
+ purges it. On a store where agents create and delete a lot, the trash grows without
277
+ bound. Since v1.16.0 you can have Cerefox purge old trash automatically. It is
278
+ **off by default**.
279
+
280
+ | Setting | Default | What it does |
281
+ |---|---|---|
282
+ | `trash_auto_purge_enabled` | `false` | Turn automatic purging on or off. |
283
+ | `trash_retention_days` | `60` | How long a document stays in the trash before it may be purged: your window to restore it. Whole days, 1 to 3650. |
284
+
285
+ Set them from **Settings** (Retention) or the CLI:
286
+
287
+ ```bash
288
+ cerefox config set trash_retention_days 60
289
+ cerefox config set trash_auto_purge_enabled true
290
+ ```
291
+
292
+ **When it runs.** Cerefox has no scheduler. The trash only grows when a document is
293
+ deleted, so that is when it is swept: each delete also purges documents that have been
294
+ in the trash longer than `trash_retention_days`, up to 100 per delete, oldest first.
295
+ A document therefore becomes *eligible* after the retention period and is removed by
296
+ **the next delete after that**. If nothing is deleted, expired documents stay, and
297
+ nothing new arrives in the trash either.
298
+
299
+ **What you can rely on.**
300
+
301
+ - Only documents already older than the retention period are purged, never the one
302
+ being deleted.
303
+ - A failure while sweeping never fails the delete: the delete completes, and the sweep
304
+ is retried on the next one.
305
+ - Every purge is in the audit log (author `trash-retention`), naming the retention in
306
+ force and the day the document was trashed.
307
+ - A delete reports how many documents it purged: `auto_purged` in the
308
+ `/api/v1` response, a line in the CLI and MCP output.
309
+ - `cerefox doctor` shows whether it is on and with which period.
310
+ - Settings asks for confirmation and tells you how many documents already in the trash
311
+ the next delete would purge. Shortening the period while it is on gets the same
312
+ confirmation.
313
+
314
+ Purged documents cannot be restored. Turning this on for a store with a large, old
315
+ trash purges it over the next few deletes; check the Trash page first if anything
316
+ there matters.
317
+
318
+ ---
319
+
273
320
  ## Storage & Backup
274
321
 
275
322
  | Variable | Default | Description |
@@ -149,7 +149,7 @@ cerefox-local upgrade # newest stable release + recreate (keeps data + OP
149
149
  cerefox-local upgrade v1.2.3 # pin an exact version (also how you downgrade)
150
150
  cerefox-local upgrade --latest # follow the moving :latest tag from now on
151
151
  cerefox-local uninstall # remove the container, KEEP the data volume
152
- cerefox-local uninstall --purge # remove the container AND delete the data volume
152
+ cerefox-local uninstall --purge # remove the container AND delete the data volume (asks you to confirm; --yes in scripts)
153
153
  ```
154
154
 
155
155
  > **Coming from an image older than v1.1.0?** Run `cerefox-local upgrade v1.1.1`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cerefox/memory",
3
- "version": "1.15.3",
3
+ "version": "1.16.1",
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",
@@ -65,7 +65,7 @@
65
65
  "typescript": "^6.0.3"
66
66
  },
67
67
  "scripts": {
68
- "build": "bun run bundle-server-assets && bun build src/bin/cerefox.ts --outdir dist/bin --target node --format esm --external @huggingface/transformers --external onnxruntime-node",
68
+ "build": "bun run bundle-server-assets && bun run bundle-docs && bun build src/bin/cerefox.ts --outdir dist/bin --target node --format esm --external @huggingface/transformers --external onnxruntime-node",
69
69
  "clean": "rm -rf dist docs AGENT_GUIDE.md AGENT_QUICK_REFERENCE.md",
70
70
  "bundle-docs": "bun run ../../scripts/bundle_package_docs.ts",
71
71
  "bundle-server-assets": "bun run ../../scripts/bundle_server_assets.ts",