@cerefox/memory 1.0.5 → 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 +221 -34
- package/dist/frontend/assets/{index-Csj-6UHY.js → index-VeqA60-v.js} +2 -2
- package/dist/frontend/assets/{index-Csj-6UHY.js.map → index-VeqA60-v.js.map} +1 -1
- package/dist/frontend/index.html +1 -1
- package/dist/server-assets/_shared/ef-meta/index.ts +2 -2
- package/dist/server-assets/_shared/mcp-tools/_utils.ts +48 -12
- package/dist/server-assets/_shared/mcp-tools/search.ts +2 -2
- package/dist/server-assets/db/rpcs.sql +20 -4
- package/dist/server-assets/db/schema.sql +1 -1
- package/docs/guides/configuration.md +8 -5
- package/docs/guides/content-format.md +8 -1
- package/package.json +1 -1
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
|
|
@@ -25217,21 +25217,35 @@ function getMaxResponseBytes() {
|
|
|
25217
25217
|
const n = Number.parseInt(raw, 10);
|
|
25218
25218
|
return Number.isNaN(n) || n <= 0 ? MAX_RESPONSE_BYTES : n;
|
|
25219
25219
|
}
|
|
25220
|
-
function
|
|
25221
|
-
const
|
|
25222
|
-
const
|
|
25223
|
-
if (
|
|
25224
|
-
return
|
|
25225
|
-
|
|
25226
|
-
|
|
25220
|
+
function readEnv(name) {
|
|
25221
|
+
const g = globalThis;
|
|
25222
|
+
const fromProcess = g.process?.env?.[name];
|
|
25223
|
+
if (fromProcess !== undefined && fromProcess !== "")
|
|
25224
|
+
return fromProcess;
|
|
25225
|
+
try {
|
|
25226
|
+
const fromDeno = g.Deno?.env?.get(name);
|
|
25227
|
+
return fromDeno === "" ? undefined : fromDeno;
|
|
25228
|
+
} catch {
|
|
25229
|
+
return;
|
|
25230
|
+
}
|
|
25227
25231
|
}
|
|
25228
|
-
function
|
|
25229
|
-
const raw =
|
|
25230
|
-
if (raw === undefined
|
|
25232
|
+
function readUnitInterval(name) {
|
|
25233
|
+
const raw = readEnv(name);
|
|
25234
|
+
if (raw === undefined)
|
|
25231
25235
|
return;
|
|
25232
25236
|
const n = Number.parseFloat(raw);
|
|
25233
25237
|
return Number.isNaN(n) || n < 0 || n > 1 ? undefined : n;
|
|
25234
25238
|
}
|
|
25239
|
+
function getSearchAlpha() {
|
|
25240
|
+
return readUnitInterval("CEREFOX_SEARCH_ALPHA") ?? DEFAULT_SEARCH_ALPHA;
|
|
25241
|
+
}
|
|
25242
|
+
function getMinSearchScore() {
|
|
25243
|
+
const fallback = readEnv("CEREFOX_EMBEDDER") === "local" ? DEFAULT_MIN_SEARCH_SCORE_LOCAL : DEFAULT_MIN_SEARCH_SCORE;
|
|
25244
|
+
return readUnitInterval("CEREFOX_MIN_SEARCH_SCORE") ?? fallback;
|
|
25245
|
+
}
|
|
25246
|
+
function getMinTermCoverage() {
|
|
25247
|
+
return readUnitInterval("CEREFOX_MIN_TERM_COVERAGE");
|
|
25248
|
+
}
|
|
25235
25249
|
function applyByteBudget(rows, maxBytes) {
|
|
25236
25250
|
const accepted = [];
|
|
25237
25251
|
let usedBytes = 0;
|
|
@@ -25259,7 +25273,7 @@ function logUsage(supabase, params) {
|
|
|
25259
25273
|
p_extra: params.extra ?? {}
|
|
25260
25274
|
})).catch(() => {});
|
|
25261
25275
|
}
|
|
25262
|
-
var MAX_RESPONSE_BYTES = 200000, DEFAULT_MIN_SEARCH_SCORE = 0.5, DEFAULT_MIN_SEARCH_SCORE_LOCAL = 0.6;
|
|
25276
|
+
var MAX_RESPONSE_BYTES = 200000, DEFAULT_MIN_SEARCH_SCORE = 0.5, DEFAULT_MIN_SEARCH_SCORE_LOCAL = 0.6, DEFAULT_SEARCH_ALPHA = 0.7;
|
|
25263
25277
|
|
|
25264
25278
|
// ../../_shared/mcp-tools/_projects.ts
|
|
25265
25279
|
async function ensureDocumentInProject(supabase, documentId, projectName) {
|
|
@@ -55577,7 +55591,7 @@ async function handler9(supabase, args, ctx) {
|
|
|
55577
55591
|
const project_name = args.project_name;
|
|
55578
55592
|
const match_count = args.match_count ?? 5;
|
|
55579
55593
|
const mode = args.mode ?? "docs";
|
|
55580
|
-
const alpha = args.alpha ??
|
|
55594
|
+
const alpha = args.alpha ?? getSearchAlpha();
|
|
55581
55595
|
const min_score = args.min_score ?? getMinSearchScore();
|
|
55582
55596
|
const min_term_coverage = args.min_term_coverage ?? getMinTermCoverage();
|
|
55583
55597
|
const coverageParam = min_term_coverage !== undefined ? { p_min_term_coverage: min_term_coverage } : {};
|
|
@@ -69090,6 +69104,7 @@ async function fetchAllPages(makeQuery, batchSize = 200) {
|
|
|
69090
69104
|
|
|
69091
69105
|
// src/cli/commands/backup.ts
|
|
69092
69106
|
init_client();
|
|
69107
|
+
init_meta();
|
|
69093
69108
|
function expandHome(path) {
|
|
69094
69109
|
if (path === "~")
|
|
69095
69110
|
return homedir2();
|
|
@@ -69110,12 +69125,24 @@ async function action(options) {
|
|
|
69110
69125
|
const filename = `cerefox-${stamp}${options.label ? "-" + options.label : ""}.json`;
|
|
69111
69126
|
const dest = join2(outDir, filename);
|
|
69112
69127
|
const client = getClient();
|
|
69128
|
+
let schemaVersion = "unknown";
|
|
69129
|
+
try {
|
|
69130
|
+
schemaVersion = await client.rpc("cerefox_schema_version", {}) ?? "unknown";
|
|
69131
|
+
} catch {}
|
|
69113
69132
|
let docs;
|
|
69114
69133
|
try {
|
|
69115
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));
|
|
69116
69135
|
} catch (err) {
|
|
69117
69136
|
throw systemError(`Document fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
69118
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
|
+
}
|
|
69119
69146
|
let chunkTotal = 0;
|
|
69120
69147
|
const enriched = [];
|
|
69121
69148
|
for (let i = 0;i < docs.length; i++) {
|
|
@@ -69138,15 +69165,21 @@ async function action(options) {
|
|
|
69138
69165
|
`);
|
|
69139
69166
|
const payload = {
|
|
69140
69167
|
created_at: new Date().toISOString(),
|
|
69141
|
-
cerefox_version:
|
|
69168
|
+
cerefox_version: PKG_VERSION,
|
|
69169
|
+
backup_format: 2,
|
|
69170
|
+
schema_version: schemaVersion,
|
|
69142
69171
|
document_count: docs.length,
|
|
69143
69172
|
chunk_count: chunkTotal,
|
|
69173
|
+
project_count: projects.length,
|
|
69174
|
+
membership_count: memberships.length,
|
|
69175
|
+
projects,
|
|
69176
|
+
memberships,
|
|
69144
69177
|
documents: enriched
|
|
69145
69178
|
};
|
|
69146
69179
|
writeFileSync(dest, JSON.stringify(payload, null, 2), "utf8");
|
|
69147
69180
|
println("");
|
|
69148
69181
|
println(c.green("✓ ") + `Backup written: ${dest}`);
|
|
69149
|
-
println(c.dim(` documents: ${docs.length} · chunks: ${chunkTotal}`));
|
|
69182
|
+
println(c.dim(` documents: ${docs.length} · chunks: ${chunkTotal} · ` + `projects: ${projects.length} · memberships: ${memberships.length}`));
|
|
69150
69183
|
if (options.git) {
|
|
69151
69184
|
println(c.yellow("⚠ ") + "--git commit is not implemented; the snapshot was written without a git checkpoint.");
|
|
69152
69185
|
println(c.dim(" Commit the backup directory yourself if you want it version-controlled."));
|
|
@@ -75006,8 +75039,8 @@ import { homedir as homedir6 } from "node:os";
|
|
|
75006
75039
|
import { join as join9 } from "node:path";
|
|
75007
75040
|
|
|
75008
75041
|
// ../../_shared/ef-meta/index.ts
|
|
75009
|
-
var EF_VERSION = "1.0.
|
|
75010
|
-
var EF_LAST_CHANGED = "1.0.
|
|
75042
|
+
var EF_VERSION = "1.0.7";
|
|
75043
|
+
var EF_LAST_CHANGED = "1.0.6";
|
|
75011
75044
|
|
|
75012
75045
|
// src/cli/util/checks.ts
|
|
75013
75046
|
init_config();
|
|
@@ -75356,7 +75389,7 @@ async function checkContentFormat() {
|
|
|
75356
75389
|
name: CONTENT_FORMAT_CHECK_NAME,
|
|
75357
75390
|
status: "skipped",
|
|
75358
75391
|
detail: `${legacy} of ${total} document(s) use the legacy reconstruction format (format 1).`,
|
|
75359
|
-
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`."
|
|
75360
75393
|
};
|
|
75361
75394
|
} catch (err) {
|
|
75362
75395
|
return {
|
|
@@ -77367,6 +77400,114 @@ function registerReindex(program2) {
|
|
|
77367
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);
|
|
77368
77401
|
}
|
|
77369
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
|
+
|
|
77370
77511
|
// src/cli/commands/restore.ts
|
|
77371
77512
|
init_cli_core();
|
|
77372
77513
|
init_client();
|
|
@@ -77394,7 +77535,7 @@ function resolveBackupFile(target) {
|
|
|
77394
77535
|
}
|
|
77395
77536
|
return join12(path, candidates[0].name);
|
|
77396
77537
|
}
|
|
77397
|
-
async function
|
|
77538
|
+
async function action29(target, options) {
|
|
77398
77539
|
const file = resolveBackupFile(target);
|
|
77399
77540
|
let payload;
|
|
77400
77541
|
try {
|
|
@@ -77406,7 +77547,13 @@ async function action28(target, options) {
|
|
|
77406
77547
|
throw userError(`Backup file is missing "documents" array: ${file}`);
|
|
77407
77548
|
}
|
|
77408
77549
|
println(c.bold(`Restoring from ${file}`));
|
|
77409
|
-
|
|
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
|
+
}
|
|
77410
77557
|
println("");
|
|
77411
77558
|
const client = getClient();
|
|
77412
77559
|
let restored = 0;
|
|
@@ -77441,8 +77588,47 @@ async function action28(target, options) {
|
|
|
77441
77588
|
}
|
|
77442
77589
|
restored++;
|
|
77443
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
|
+
}
|
|
77444
77627
|
println("");
|
|
77445
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
|
+
}
|
|
77446
77632
|
if (errors4 > 0) {
|
|
77447
77633
|
println("");
|
|
77448
77634
|
printTable(errorDetails);
|
|
@@ -77450,7 +77636,7 @@ async function action28(target, options) {
|
|
|
77450
77636
|
}
|
|
77451
77637
|
}
|
|
77452
77638
|
function registerRestore(program2) {
|
|
77453
|
-
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);
|
|
77454
77640
|
}
|
|
77455
77641
|
|
|
77456
77642
|
// src/cli/commands/search.ts
|
|
@@ -77475,12 +77661,12 @@ async function embedQuery(query) {
|
|
|
77475
77661
|
}
|
|
77476
77662
|
|
|
77477
77663
|
// src/cli/commands/search.ts
|
|
77478
|
-
async function
|
|
77664
|
+
async function action30(query, options) {
|
|
77479
77665
|
if (!query || query.trim() === "") {
|
|
77480
77666
|
throw userError("Empty query.");
|
|
77481
77667
|
}
|
|
77482
77668
|
const matchCount = parsePositiveInt(options.matchCount, "--match-count", 5);
|
|
77483
|
-
const alpha = parseFloat01(options.alpha, "--alpha",
|
|
77669
|
+
const alpha = parseFloat01(options.alpha, "--alpha", getSearchAlpha());
|
|
77484
77670
|
const minScore = parseFloat01(options.minScore, "--min-score", getMinSearchScore());
|
|
77485
77671
|
const envCoverage = getMinTermCoverage();
|
|
77486
77672
|
const coverageParam = options.minTermCoverage !== undefined ? { p_min_term_coverage: parseFloat01(options.minTermCoverage, "--min-term-coverage", envCoverage ?? 0.5) } : envCoverage !== undefined ? { p_min_term_coverage: envCoverage } : {};
|
|
@@ -77639,7 +77825,7 @@ async function action29(query, options) {
|
|
|
77639
77825
|
}
|
|
77640
77826
|
}
|
|
77641
77827
|
function registerSearch(program2) {
|
|
77642
|
-
program2.command("search").description("Search the knowledge base (hybrid FTS + semantic).").argument("<query>", "Natural-language search query.").option("-c, --match-count <n>", "Maximum number of documents to return.", "5").option("-p, --project-name <name>", "Filter results to a specific project.").option("-f, --metadata-filter <json>", "JSON containment filter; only docs whose metadata contains ALL pairs are returned.").option("--mode <mode>", "Search mode: docs (default), hybrid, fts.", "docs").option("--alpha <float>", "Semantic weight 0..1 (default: 0.7)."
|
|
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);
|
|
77643
77829
|
}
|
|
77644
77830
|
|
|
77645
77831
|
// src/cli/commands/self-update.ts
|
|
@@ -77686,7 +77872,7 @@ async function fetchLatestVersion() {
|
|
|
77686
77872
|
}
|
|
77687
77873
|
return body.version;
|
|
77688
77874
|
}
|
|
77689
|
-
async function
|
|
77875
|
+
async function action31(options) {
|
|
77690
77876
|
let target;
|
|
77691
77877
|
try {
|
|
77692
77878
|
target = options.version ?? await fetchLatestVersion();
|
|
@@ -77738,7 +77924,7 @@ async function action30(options) {
|
|
|
77738
77924
|
}
|
|
77739
77925
|
function registerSelfUpdate(program2) {
|
|
77740
77926
|
const desc = "Upgrade Cerefox in place. Alias: `cerefox upgrade`.";
|
|
77741
|
-
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);
|
|
77742
77928
|
declaration(program2.command("self-update"));
|
|
77743
77929
|
declaration(program2.command("upgrade"));
|
|
77744
77930
|
}
|
|
@@ -77757,7 +77943,7 @@ function symbol2(status) {
|
|
|
77757
77943
|
return cErr.dim("ℹ");
|
|
77758
77944
|
}
|
|
77759
77945
|
}
|
|
77760
|
-
async function
|
|
77946
|
+
async function action32(options) {
|
|
77761
77947
|
const useSpinner = !options.json && process.stderr.isTTY;
|
|
77762
77948
|
const spinner = useSpinner ? ora({ text: "Starting checks…", spinner: "dots", stream: process.stderr }).start() : null;
|
|
77763
77949
|
const results = await runFastChecks({
|
|
@@ -77778,7 +77964,7 @@ async function action31(options) {
|
|
|
77778
77964
|
}
|
|
77779
77965
|
}
|
|
77780
77966
|
function registerStatus(program2) {
|
|
77781
|
-
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);
|
|
77782
77968
|
}
|
|
77783
77969
|
|
|
77784
77970
|
// src/cli/commands/token.ts
|
|
@@ -77811,10 +77997,10 @@ function upsertEnvVar(path, key, value, opts = {}) {
|
|
|
77811
77997
|
}
|
|
77812
77998
|
const re = new RegExp(`^(\\s*)${escapeRegExp(key)}=.*$`, "m");
|
|
77813
77999
|
let next;
|
|
77814
|
-
let
|
|
78000
|
+
let action33;
|
|
77815
78001
|
if (re.test(original)) {
|
|
77816
78002
|
next = original.replace(re, `$1${line}`);
|
|
77817
|
-
|
|
78003
|
+
action33 = "updated";
|
|
77818
78004
|
} else {
|
|
77819
78005
|
const base = original.endsWith(`
|
|
77820
78006
|
`) ? original : `${original}
|
|
@@ -77822,10 +78008,10 @@ function upsertEnvVar(path, key, value, opts = {}) {
|
|
|
77822
78008
|
next = `${base}
|
|
77823
78009
|
${header}${line}
|
|
77824
78010
|
`;
|
|
77825
|
-
|
|
78011
|
+
action33 = "added";
|
|
77826
78012
|
}
|
|
77827
78013
|
writeFileSync5(path, next);
|
|
77828
|
-
return { path, action:
|
|
78014
|
+
return { path, action: action33, backupPath };
|
|
77829
78015
|
}
|
|
77830
78016
|
function readEnvVar(path, key) {
|
|
77831
78017
|
if (!existsSync14(path))
|
|
@@ -81643,7 +81829,7 @@ async function runSearch(ctx, opts) {
|
|
|
81643
81829
|
p_query_text: query,
|
|
81644
81830
|
p_query_embedding: embedding,
|
|
81645
81831
|
p_match_count: count,
|
|
81646
|
-
p_alpha:
|
|
81832
|
+
p_alpha: getSearchAlpha(),
|
|
81647
81833
|
p_use_upgrade: false,
|
|
81648
81834
|
p_project_id: projectId,
|
|
81649
81835
|
p_min_score: getMinSearchScore()
|
|
@@ -81659,7 +81845,7 @@ async function runSearch(ctx, opts) {
|
|
|
81659
81845
|
p_query_text: query,
|
|
81660
81846
|
p_query_embedding: embedding,
|
|
81661
81847
|
p_match_count: Math.min(count, 5),
|
|
81662
|
-
p_alpha:
|
|
81848
|
+
p_alpha: getSearchAlpha(),
|
|
81663
81849
|
p_project_id: projectId,
|
|
81664
81850
|
p_min_score: getMinSearchScore()
|
|
81665
81851
|
};
|
|
@@ -83437,6 +83623,7 @@ Learn more:
|
|
|
83437
83623
|
const server = program2.command("server").description("Server side: deploy, reindex.");
|
|
83438
83624
|
moveInto(server, registerDeployServer, "deploy");
|
|
83439
83625
|
moveInto(server, registerReindex, "reindex");
|
|
83626
|
+
registerMigrateFormat(server);
|
|
83440
83627
|
const guides = program2.command("guides").description("Bundled docs: list, open, show, ingest (into the KB).");
|
|
83441
83628
|
registerGuides(guides);
|
|
83442
83629
|
moveInto(guides, registerSyncSelfDocs, "ingest");
|