@cerefox/memory 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/cerefox.js
CHANGED
|
@@ -7184,7 +7184,7 @@ var exports_meta = {};
|
|
|
7184
7184
|
__export(exports_meta, {
|
|
7185
7185
|
PKG_VERSION: () => PKG_VERSION
|
|
7186
7186
|
});
|
|
7187
|
-
var PKG_VERSION = "1.0.
|
|
7187
|
+
var PKG_VERSION = "1.0.7";
|
|
7188
7188
|
var init_meta = () => {};
|
|
7189
7189
|
|
|
7190
7190
|
// ../../node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.js
|
|
@@ -69104,6 +69104,7 @@ async function fetchAllPages(makeQuery, batchSize = 200) {
|
|
|
69104
69104
|
|
|
69105
69105
|
// src/cli/commands/backup.ts
|
|
69106
69106
|
init_client();
|
|
69107
|
+
init_meta();
|
|
69107
69108
|
function expandHome(path) {
|
|
69108
69109
|
if (path === "~")
|
|
69109
69110
|
return homedir2();
|
|
@@ -69124,12 +69125,24 @@ async function action(options) {
|
|
|
69124
69125
|
const filename = `cerefox-${stamp}${options.label ? "-" + options.label : ""}.json`;
|
|
69125
69126
|
const dest = join2(outDir, filename);
|
|
69126
69127
|
const client = getClient();
|
|
69128
|
+
let schemaVersion = "unknown";
|
|
69129
|
+
try {
|
|
69130
|
+
schemaVersion = await client.rpc("cerefox_schema_version", {}) ?? "unknown";
|
|
69131
|
+
} catch {}
|
|
69127
69132
|
let docs;
|
|
69128
69133
|
try {
|
|
69129
69134
|
docs = await fetchAllPages((from, to) => client.raw.from("cerefox_documents").select("id, title, content_hash, source, metadata, total_chars, chunk_count, " + "review_status, created_at, updated_at, deleted_at").is("deleted_at", null).order("created_at", { ascending: true }).order("id", { ascending: true }).range(from, to));
|
|
69130
69135
|
} catch (err) {
|
|
69131
69136
|
throw systemError(`Document fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
69132
69137
|
}
|
|
69138
|
+
let projects = [];
|
|
69139
|
+
let memberships = [];
|
|
69140
|
+
try {
|
|
69141
|
+
projects = await fetchAllPages((from, to) => client.raw.from("cerefox_projects").select("id, name, description, created_at, updated_at").order("id", { ascending: true }).range(from, to));
|
|
69142
|
+
memberships = await fetchAllPages((from, to) => client.raw.from("cerefox_document_projects").select("document_id, project_id").order("document_id", { ascending: true }).order("project_id", { ascending: true }).range(from, to));
|
|
69143
|
+
} catch (err) {
|
|
69144
|
+
throw systemError(`Project/membership fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
69145
|
+
}
|
|
69133
69146
|
let chunkTotal = 0;
|
|
69134
69147
|
const enriched = [];
|
|
69135
69148
|
for (let i = 0;i < docs.length; i++) {
|
|
@@ -69152,15 +69165,21 @@ async function action(options) {
|
|
|
69152
69165
|
`);
|
|
69153
69166
|
const payload = {
|
|
69154
69167
|
created_at: new Date().toISOString(),
|
|
69155
|
-
cerefox_version:
|
|
69168
|
+
cerefox_version: PKG_VERSION,
|
|
69169
|
+
backup_format: 2,
|
|
69170
|
+
schema_version: schemaVersion,
|
|
69156
69171
|
document_count: docs.length,
|
|
69157
69172
|
chunk_count: chunkTotal,
|
|
69173
|
+
project_count: projects.length,
|
|
69174
|
+
membership_count: memberships.length,
|
|
69175
|
+
projects,
|
|
69176
|
+
memberships,
|
|
69158
69177
|
documents: enriched
|
|
69159
69178
|
};
|
|
69160
69179
|
writeFileSync(dest, JSON.stringify(payload, null, 2), "utf8");
|
|
69161
69180
|
println("");
|
|
69162
69181
|
println(c.green("✓ ") + `Backup written: ${dest}`);
|
|
69163
|
-
println(c.dim(` documents: ${docs.length} · chunks: ${chunkTotal}`));
|
|
69182
|
+
println(c.dim(` documents: ${docs.length} · chunks: ${chunkTotal} · ` + `projects: ${projects.length} · memberships: ${memberships.length}`));
|
|
69164
69183
|
if (options.git) {
|
|
69165
69184
|
println(c.yellow("⚠ ") + "--git commit is not implemented; the snapshot was written without a git checkpoint.");
|
|
69166
69185
|
println(c.dim(" Commit the backup directory yourself if you want it version-controlled."));
|
|
@@ -75020,7 +75039,7 @@ import { homedir as homedir6 } from "node:os";
|
|
|
75020
75039
|
import { join as join9 } from "node:path";
|
|
75021
75040
|
|
|
75022
75041
|
// ../../_shared/ef-meta/index.ts
|
|
75023
|
-
var EF_VERSION = "1.0.
|
|
75042
|
+
var EF_VERSION = "1.0.7";
|
|
75024
75043
|
var EF_LAST_CHANGED = "1.0.6";
|
|
75025
75044
|
|
|
75026
75045
|
// src/cli/util/checks.ts
|
|
@@ -75370,7 +75389,7 @@ async function checkContentFormat() {
|
|
|
75370
75389
|
name: CONTENT_FORMAT_CHECK_NAME,
|
|
75371
75390
|
status: "skipped",
|
|
75372
75391
|
detail: `${legacy} of ${total} document(s) use the legacy reconstruction format (format 1).`,
|
|
75373
|
-
hint: "They auto-convert on next edit; run `cerefox server
|
|
75392
|
+
hint: "They auto-convert on next edit; run `cerefox server migrate-format` to convert all now (re-embeds; `--dry-run` first). What this means: `cerefox guides show content-format`."
|
|
75374
75393
|
};
|
|
75375
75394
|
} catch (err) {
|
|
75376
75395
|
return {
|
|
@@ -77381,6 +77400,114 @@ function registerReindex(program2) {
|
|
|
77381
77400
|
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(action27);
|
|
77382
77401
|
}
|
|
77383
77402
|
|
|
77403
|
+
// src/cli/commands/migrate-format.ts
|
|
77404
|
+
init_cli_core();
|
|
77405
|
+
init_config();
|
|
77406
|
+
init_client();
|
|
77407
|
+
var CURRENT_FORMAT = 2;
|
|
77408
|
+
async function action28(options) {
|
|
77409
|
+
const settings = loadSettings();
|
|
77410
|
+
const client = getClient();
|
|
77411
|
+
const supabase = client.raw;
|
|
77412
|
+
let legacyChunkRows;
|
|
77413
|
+
try {
|
|
77414
|
+
legacyChunkRows = await fetchAllPages((from, to) => {
|
|
77415
|
+
let q = supabase.from("cerefox_chunks").select("document_id").is("version_id", null).lt("content_format", CURRENT_FORMAT);
|
|
77416
|
+
if (options.documentId)
|
|
77417
|
+
q = q.eq("document_id", options.documentId);
|
|
77418
|
+
return q.order("document_id", { ascending: true }).range(from, to);
|
|
77419
|
+
}, 1000);
|
|
77420
|
+
} catch (err) {
|
|
77421
|
+
throw systemError(`Could not list legacy chunks: ${err instanceof Error ? err.message : String(err)}`);
|
|
77422
|
+
}
|
|
77423
|
+
const docIds = [...new Set(legacyChunkRows.map((r) => r.document_id))];
|
|
77424
|
+
const limit = options.limit ? parsePositiveInt(options.limit, "--limit", docIds.length) : docIds.length;
|
|
77425
|
+
const targets = docIds.slice(0, limit);
|
|
77426
|
+
if (targets.length === 0) {
|
|
77427
|
+
println(c.green("✓ Nothing to migrate — every document already uses the current format."));
|
|
77428
|
+
return;
|
|
77429
|
+
}
|
|
77430
|
+
println(c.bold(`${docIds.length} document(s) on the legacy format` + (targets.length < docIds.length ? `; converting ${targets.length} (--limit)` : "")));
|
|
77431
|
+
if (options.dryRun) {
|
|
77432
|
+
println(c.yellow("⚠ --dry-run: nothing was written."));
|
|
77433
|
+
println(c.dim(" Each document would be re-chunked and RE-EMBEDDED (embedding spend)."));
|
|
77434
|
+
return;
|
|
77435
|
+
}
|
|
77436
|
+
println(c.dim("Each document is re-chunked and re-embedded — this costs embedding spend."));
|
|
77437
|
+
println("");
|
|
77438
|
+
const author = resolveAuthor(options.author);
|
|
77439
|
+
const authorType = resolveAuthorType(undefined);
|
|
77440
|
+
const pipeline2 = new IngestionPipeline({
|
|
77441
|
+
supabase,
|
|
77442
|
+
openAiApiKey: settings.openaiApiKey
|
|
77443
|
+
});
|
|
77444
|
+
let converted = 0;
|
|
77445
|
+
let skipped = 0;
|
|
77446
|
+
const duplicates = [];
|
|
77447
|
+
const failures = [];
|
|
77448
|
+
for (let i = 0;i < targets.length; i++) {
|
|
77449
|
+
const id = targets[i];
|
|
77450
|
+
if (process.stdout.isTTY) {
|
|
77451
|
+
process.stderr.write(`\r Converting ${i + 1}/${targets.length}…`);
|
|
77452
|
+
}
|
|
77453
|
+
let doc2 = null;
|
|
77454
|
+
try {
|
|
77455
|
+
const rows = await client.rpc("cerefox_get_document", { p_document_id: id, p_version_id: null });
|
|
77456
|
+
doc2 = rows?.[0] ?? null;
|
|
77457
|
+
} catch (err) {
|
|
77458
|
+
failures.push({ document: id, reason: `read: ${err instanceof Error ? err.message : String(err)}` });
|
|
77459
|
+
continue;
|
|
77460
|
+
}
|
|
77461
|
+
if (!doc2) {
|
|
77462
|
+
failures.push({ document: id, reason: "read: document not found" });
|
|
77463
|
+
continue;
|
|
77464
|
+
}
|
|
77465
|
+
try {
|
|
77466
|
+
await pipeline2.ingestText({
|
|
77467
|
+
text: doc2.full_content,
|
|
77468
|
+
title: doc2.doc_title,
|
|
77469
|
+
documentId: id,
|
|
77470
|
+
source: "migrate-format",
|
|
77471
|
+
author,
|
|
77472
|
+
authorType,
|
|
77473
|
+
expectedContentHash: doc2.content_hash
|
|
77474
|
+
});
|
|
77475
|
+
converted++;
|
|
77476
|
+
} catch (err) {
|
|
77477
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
77478
|
+
if (/conflict/i.test(message)) {
|
|
77479
|
+
skipped++;
|
|
77480
|
+
} else if (/identical content already exists/i.test(message)) {
|
|
77481
|
+
duplicates.push({ document: `${doc2.doc_title} (${id})`, reason: message });
|
|
77482
|
+
} else {
|
|
77483
|
+
failures.push({ document: `${doc2.doc_title} (${id})`, reason: message });
|
|
77484
|
+
}
|
|
77485
|
+
}
|
|
77486
|
+
}
|
|
77487
|
+
if (process.stdout.isTTY)
|
|
77488
|
+
process.stderr.write(`
|
|
77489
|
+
`);
|
|
77490
|
+
println("");
|
|
77491
|
+
println(c.bold(`Converted ${converted} · skipped ${skipped} (changed mid-run) · failed ${failures.length}`));
|
|
77492
|
+
if (targets.length < docIds.length) {
|
|
77493
|
+
println(c.dim(` ${docIds.length - targets.length} document(s) still pending — re-run to continue.`));
|
|
77494
|
+
}
|
|
77495
|
+
if (duplicates.length > 0) {
|
|
77496
|
+
println("");
|
|
77497
|
+
println(c.yellow(`⚠ ${duplicates.length} document(s) could not be converted because their content is ` + "byte-identical to another document."));
|
|
77498
|
+
println(c.dim(" Re-ingesting them would collide with the content-hash dedup check. They keep working " + "on the legacy format; de-duplicate them if you want them converted."));
|
|
77499
|
+
printTable(duplicates.map((d) => ({ document: d.document })));
|
|
77500
|
+
}
|
|
77501
|
+
if (failures.length > 0) {
|
|
77502
|
+
println("");
|
|
77503
|
+
printTable(failures);
|
|
77504
|
+
throw systemError(`${failures.length} document(s) failed to convert.`);
|
|
77505
|
+
}
|
|
77506
|
+
}
|
|
77507
|
+
function registerMigrateFormat(program2) {
|
|
77508
|
+
program2.command("migrate-format").description("Convert legacy-format documents to the current chunk format (re-chunks + re-embeds).").option("--dry-run", "Report how many documents would be converted; write nothing.").option("-l, --limit <n>", "Convert at most N documents (re-run to continue).").option("--document-id <uuid>", "Convert a single document.").option("--author <name>", "Recorded in the audit log for each conversion.").action(action28);
|
|
77509
|
+
}
|
|
77510
|
+
|
|
77384
77511
|
// src/cli/commands/restore.ts
|
|
77385
77512
|
init_cli_core();
|
|
77386
77513
|
init_client();
|
|
@@ -77408,7 +77535,7 @@ function resolveBackupFile(target) {
|
|
|
77408
77535
|
}
|
|
77409
77536
|
return join12(path, candidates[0].name);
|
|
77410
77537
|
}
|
|
77411
|
-
async function
|
|
77538
|
+
async function action29(target, options) {
|
|
77412
77539
|
const file = resolveBackupFile(target);
|
|
77413
77540
|
let payload;
|
|
77414
77541
|
try {
|
|
@@ -77420,7 +77547,13 @@ async function action28(target, options) {
|
|
|
77420
77547
|
throw userError(`Backup file is missing "documents" array: ${file}`);
|
|
77421
77548
|
}
|
|
77422
77549
|
println(c.bold(`Restoring from ${file}`));
|
|
77423
|
-
|
|
77550
|
+
const hasMemberships = Array.isArray(payload.memberships);
|
|
77551
|
+
println(c.dim(` cerefox_version: ${payload.cerefox_version ?? "?"} · ` + `schema: ${payload.schema_version ?? "?"} · ` + `documents in file: ${payload.documents.length} · chunks in file: ${payload.chunk_count ?? "?"}`));
|
|
77552
|
+
if (hasMemberships) {
|
|
77553
|
+
println(c.dim(` projects: ${payload.projects?.length ?? 0} · memberships: ${payload.memberships?.length ?? 0}`));
|
|
77554
|
+
} else {
|
|
77555
|
+
warn("This backup predates project-membership capture (format 1) — documents " + "will be restored WITHOUT their project assignments.");
|
|
77556
|
+
}
|
|
77424
77557
|
println("");
|
|
77425
77558
|
const client = getClient();
|
|
77426
77559
|
let restored = 0;
|
|
@@ -77455,8 +77588,47 @@ async function action28(target, options) {
|
|
|
77455
77588
|
}
|
|
77456
77589
|
restored++;
|
|
77457
77590
|
}
|
|
77591
|
+
let projectsRestored = 0;
|
|
77592
|
+
let membershipsRestored = 0;
|
|
77593
|
+
if (!options.dryRun && hasMemberships) {
|
|
77594
|
+
const projects = payload.projects ?? [];
|
|
77595
|
+
if (projects.length > 0) {
|
|
77596
|
+
const { error: projErr } = await client.raw.from("cerefox_projects").upsert(projects, { onConflict: "id", ignoreDuplicates: true });
|
|
77597
|
+
if (projErr) {
|
|
77598
|
+
errors4++;
|
|
77599
|
+
errorDetails.push({ title: "(projects)", error: projErr.message });
|
|
77600
|
+
} else {
|
|
77601
|
+
projectsRestored = projects.length;
|
|
77602
|
+
}
|
|
77603
|
+
}
|
|
77604
|
+
const presentDocIds = new Set;
|
|
77605
|
+
{
|
|
77606
|
+
const ids = (payload.documents ?? []).map((d) => d.id);
|
|
77607
|
+
for (let i = 0;i < ids.length; i += 200) {
|
|
77608
|
+
const { data } = await client.raw.from("cerefox_documents").select("id").in("id", ids.slice(i, i + 200));
|
|
77609
|
+
for (const row of data ?? [])
|
|
77610
|
+
presentDocIds.add(row.id);
|
|
77611
|
+
}
|
|
77612
|
+
}
|
|
77613
|
+
const links = (payload.memberships ?? []).filter((m) => presentDocIds.has(m.document_id));
|
|
77614
|
+
for (let i = 0;i < links.length; i += 500) {
|
|
77615
|
+
const { error: linkErr } = await client.raw.from("cerefox_document_projects").upsert(links.slice(i, i + 500), {
|
|
77616
|
+
onConflict: "document_id,project_id",
|
|
77617
|
+
ignoreDuplicates: true
|
|
77618
|
+
});
|
|
77619
|
+
if (linkErr) {
|
|
77620
|
+
errors4++;
|
|
77621
|
+
errorDetails.push({ title: "(memberships)", error: linkErr.message });
|
|
77622
|
+
break;
|
|
77623
|
+
}
|
|
77624
|
+
membershipsRestored += links.slice(i, i + 500).length;
|
|
77625
|
+
}
|
|
77626
|
+
}
|
|
77458
77627
|
println("");
|
|
77459
77628
|
println((options.dryRun ? c.yellow("(dry-run) ") : "") + c.bold(`Summary: ${restored} restored · ${skipped} skipped · ${errors4} errors`));
|
|
77629
|
+
if (hasMemberships && !options.dryRun) {
|
|
77630
|
+
println(c.dim(` projects: ${projectsRestored} · memberships: ${membershipsRestored}`));
|
|
77631
|
+
}
|
|
77460
77632
|
if (errors4 > 0) {
|
|
77461
77633
|
println("");
|
|
77462
77634
|
printTable(errorDetails);
|
|
@@ -77464,7 +77636,7 @@ async function action28(target, options) {
|
|
|
77464
77636
|
}
|
|
77465
77637
|
}
|
|
77466
77638
|
function registerRestore(program2) {
|
|
77467
|
-
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
|
|
77639
|
+
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 are restored from the backup itself (format 2+).").action(action29);
|
|
77468
77640
|
}
|
|
77469
77641
|
|
|
77470
77642
|
// src/cli/commands/search.ts
|
|
@@ -77489,7 +77661,7 @@ async function embedQuery(query) {
|
|
|
77489
77661
|
}
|
|
77490
77662
|
|
|
77491
77663
|
// src/cli/commands/search.ts
|
|
77492
|
-
async function
|
|
77664
|
+
async function action30(query, options) {
|
|
77493
77665
|
if (!query || query.trim() === "") {
|
|
77494
77666
|
throw userError("Empty query.");
|
|
77495
77667
|
}
|
|
@@ -77653,7 +77825,7 @@ async function action29(query, options) {
|
|
|
77653
77825
|
}
|
|
77654
77826
|
}
|
|
77655
77827
|
function registerSearch(program2) {
|
|
77656
|
-
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: CEREFOX_SEARCH_ALPHA; else 0.7).").option("--min-score <float>", "Minimum cosine similarity threshold (default: CEREFOX_MIN_SEARCH_SCORE; else 0.5, or 0.6 with the local embedder).").option("--min-term-coverage <float>", "OR-fallback keyword matches must cover at least this fraction of the query's meaningful terms to count as confident hits (default: CEREFOX_MIN_TERM_COVERAGE; else the server default 0.5; needs schema ≥ 0.9.1).").option("--max-bytes <n>", "Response size budget in bytes (default: CEREFOX_MAX_RESPONSE_BYTES or 200000).").option("-r, --requestor <name>", "Agent / user name (recorded in usage log).").option("--json", "Emit machine-readable JSON instead of the default text.").option("--only-metadata", "List matching docs (id, score, chunks, chars, partial/full) WITHOUT their content — like the web UI's collapsed result list. Grab a [id:…] then `cerefox document get <id>`.").action(
|
|
77828
|
+
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: CEREFOX_SEARCH_ALPHA; else 0.7).").option("--min-score <float>", "Minimum cosine similarity threshold (default: CEREFOX_MIN_SEARCH_SCORE; else 0.5, or 0.6 with the local embedder).").option("--min-term-coverage <float>", "OR-fallback keyword matches must cover at least this fraction of the query's meaningful terms to count as confident hits (default: CEREFOX_MIN_TERM_COVERAGE; else the server default 0.5; needs schema ≥ 0.9.1).").option("--max-bytes <n>", "Response size budget in bytes (default: CEREFOX_MAX_RESPONSE_BYTES or 200000).").option("-r, --requestor <name>", "Agent / user name (recorded in usage log).").option("--json", "Emit machine-readable JSON instead of the default text.").option("--only-metadata", "List matching docs (id, score, chunks, chars, partial/full) WITHOUT their content — like the web UI's collapsed result list. Grab a [id:…] then `cerefox document get <id>`.").action(action30);
|
|
77657
77829
|
}
|
|
77658
77830
|
|
|
77659
77831
|
// src/cli/commands/self-update.ts
|
|
@@ -77700,7 +77872,7 @@ async function fetchLatestVersion() {
|
|
|
77700
77872
|
}
|
|
77701
77873
|
return body.version;
|
|
77702
77874
|
}
|
|
77703
|
-
async function
|
|
77875
|
+
async function action31(options) {
|
|
77704
77876
|
let target;
|
|
77705
77877
|
try {
|
|
77706
77878
|
target = options.version ?? await fetchLatestVersion();
|
|
@@ -77752,7 +77924,7 @@ async function action30(options) {
|
|
|
77752
77924
|
}
|
|
77753
77925
|
function registerSelfUpdate(program2) {
|
|
77754
77926
|
const desc = "Upgrade Cerefox in place. Alias: `cerefox upgrade`.";
|
|
77755
|
-
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(
|
|
77927
|
+
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(action31);
|
|
77756
77928
|
declaration(program2.command("self-update"));
|
|
77757
77929
|
declaration(program2.command("upgrade"));
|
|
77758
77930
|
}
|
|
@@ -77771,7 +77943,7 @@ function symbol2(status) {
|
|
|
77771
77943
|
return cErr.dim("ℹ");
|
|
77772
77944
|
}
|
|
77773
77945
|
}
|
|
77774
|
-
async function
|
|
77946
|
+
async function action32(options) {
|
|
77775
77947
|
const useSpinner = !options.json && process.stderr.isTTY;
|
|
77776
77948
|
const spinner = useSpinner ? ora({ text: "Starting checks…", spinner: "dots", stream: process.stderr }).start() : null;
|
|
77777
77949
|
const results = await runFastChecks({
|
|
@@ -77792,7 +77964,7 @@ async function action31(options) {
|
|
|
77792
77964
|
}
|
|
77793
77965
|
}
|
|
77794
77966
|
function registerStatus(program2) {
|
|
77795
|
-
program2.command("status").description("Quick sanity check (fast subset of `cerefox doctor`).").option("--json", "Emit machine-readable JSON.").action(
|
|
77967
|
+
program2.command("status").description("Quick sanity check (fast subset of `cerefox doctor`).").option("--json", "Emit machine-readable JSON.").action(action32);
|
|
77796
77968
|
}
|
|
77797
77969
|
|
|
77798
77970
|
// src/cli/commands/token.ts
|
|
@@ -77825,10 +77997,10 @@ function upsertEnvVar(path, key, value, opts = {}) {
|
|
|
77825
77997
|
}
|
|
77826
77998
|
const re = new RegExp(`^(\\s*)${escapeRegExp(key)}=.*$`, "m");
|
|
77827
77999
|
let next;
|
|
77828
|
-
let
|
|
78000
|
+
let action33;
|
|
77829
78001
|
if (re.test(original)) {
|
|
77830
78002
|
next = original.replace(re, `$1${line}`);
|
|
77831
|
-
|
|
78003
|
+
action33 = "updated";
|
|
77832
78004
|
} else {
|
|
77833
78005
|
const base = original.endsWith(`
|
|
77834
78006
|
`) ? original : `${original}
|
|
@@ -77836,10 +78008,10 @@ function upsertEnvVar(path, key, value, opts = {}) {
|
|
|
77836
78008
|
next = `${base}
|
|
77837
78009
|
${header}${line}
|
|
77838
78010
|
`;
|
|
77839
|
-
|
|
78011
|
+
action33 = "added";
|
|
77840
78012
|
}
|
|
77841
78013
|
writeFileSync5(path, next);
|
|
77842
|
-
return { path, action:
|
|
78014
|
+
return { path, action: action33, backupPath };
|
|
77843
78015
|
}
|
|
77844
78016
|
function readEnvVar(path, key) {
|
|
77845
78017
|
if (!existsSync14(path))
|
|
@@ -83451,6 +83623,7 @@ Learn more:
|
|
|
83451
83623
|
const server = program2.command("server").description("Server side: deploy, reindex.");
|
|
83452
83624
|
moveInto(server, registerDeployServer, "deploy");
|
|
83453
83625
|
moveInto(server, registerReindex, "reindex");
|
|
83626
|
+
registerMigrateFormat(server);
|
|
83454
83627
|
const guides = program2.command("guides").description("Bundled docs: list, open, show, ingest (into the KB).");
|
|
83455
83628
|
registerGuides(guides);
|
|
83456
83629
|
moveInto(guides, registerSyncSelfDocs, "ingest");
|
|
@@ -40,7 +40,14 @@ in — even after the current version has moved to format 2.
|
|
|
40
40
|
- A document **moves to format 2 automatically the next time it is edited/saved**
|
|
41
41
|
(it gets re-chunked by the new chunker).
|
|
42
42
|
- If you want to convert everything now rather than on next edit, run
|
|
43
|
-
`cerefox server
|
|
43
|
+
`cerefox server migrate-format`. It re-ingests each legacy document through
|
|
44
|
+
the normal pipeline (re-chunk + re-embed + stamp the current format), which
|
|
45
|
+
costs embedding spend — so it is opt-in, supports `--dry-run` and `--limit`,
|
|
46
|
+
and skips any document that changes mid-run rather than overwriting it.
|
|
47
|
+
|
|
48
|
+
> **Not `cerefox server reindex`.** Reindex refreshes *embeddings* on the
|
|
49
|
+
> existing chunk rows; it never re-chunks, so it cannot advance the stored
|
|
50
|
+
> format. Earlier versions of this guide said otherwise (#164).
|
|
44
51
|
|
|
45
52
|
`cerefox doctor` reports how many documents still use the legacy format — purely
|
|
46
53
|
informational, never a failure. A fresh install shows zero.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cerefox/memory",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Cerefox — 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",
|