@cerefox/memory 0.8.0 → 0.8.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.
- package/dist/bin/cerefox.js +378 -134
- package/docs/guides/connect-agents.md +20 -0
- package/docs/guides/quickstart.md +6 -2
- package/package.json +1 -1
package/dist/bin/cerefox.js
CHANGED
|
@@ -182,6 +182,10 @@ function printTable(rows, emptyMessage = "(no rows)") {
|
|
|
182
182
|
println(line(headers.map((h) => String(row[h] ?? ""))));
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
+
function localTimestamp(d = new Date) {
|
|
186
|
+
const p = (n, w = 2) => String(n).padStart(w, "0");
|
|
187
|
+
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ` + `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}.${p(d.getMilliseconds(), 3)}`;
|
|
188
|
+
}
|
|
185
189
|
function eprintln(line = "") {
|
|
186
190
|
process.stderr.write(line + `
|
|
187
191
|
`);
|
|
@@ -5315,6 +5319,7 @@ __export(exports_cli_core, {
|
|
|
5315
5319
|
parseFloat01: () => parseFloat01,
|
|
5316
5320
|
ok: () => ok,
|
|
5317
5321
|
notFound: () => notFound,
|
|
5322
|
+
localTimestamp: () => localTimestamp,
|
|
5318
5323
|
info: () => info,
|
|
5319
5324
|
errorln: () => errorln,
|
|
5320
5325
|
eprintln: () => eprintln,
|
|
@@ -7179,7 +7184,7 @@ var exports_meta = {};
|
|
|
7179
7184
|
__export(exports_meta, {
|
|
7180
7185
|
PKG_VERSION: () => PKG_VERSION
|
|
7181
7186
|
});
|
|
7182
|
-
var PKG_VERSION = "0.8.
|
|
7187
|
+
var PKG_VERSION = "0.8.1";
|
|
7183
7188
|
var init_meta = () => {};
|
|
7184
7189
|
|
|
7185
7190
|
// ../../node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.js
|
|
@@ -24624,12 +24629,12 @@ var init_src = __esm(() => {
|
|
|
24624
24629
|
|
|
24625
24630
|
// src/cli/util/bundled-docs.ts
|
|
24626
24631
|
import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync } from "node:fs";
|
|
24627
|
-
import { dirname as dirname3, join as
|
|
24632
|
+
import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
|
|
24628
24633
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
24629
24634
|
function findPackageRoot() {
|
|
24630
24635
|
let dir = dirname3(fileURLToPath2(import.meta.url));
|
|
24631
24636
|
for (let i = 0;i < 10; i++) {
|
|
24632
|
-
const pkgJson =
|
|
24637
|
+
const pkgJson = join6(dir, "package.json");
|
|
24633
24638
|
if (existsSync7(pkgJson)) {
|
|
24634
24639
|
try {
|
|
24635
24640
|
const parsed = JSON.parse(readFileSync5(pkgJson, "utf8"));
|
|
@@ -24645,14 +24650,14 @@ function findPackageRoot() {
|
|
|
24645
24650
|
return resolve2(dirname3(fileURLToPath2(import.meta.url)), "..", "..", "..");
|
|
24646
24651
|
}
|
|
24647
24652
|
function bundledDocsDir() {
|
|
24648
|
-
const inPackage =
|
|
24653
|
+
const inPackage = join6(PACKAGE_ROOT, "docs");
|
|
24649
24654
|
if (existsSync7(inPackage))
|
|
24650
24655
|
return inPackage;
|
|
24651
24656
|
return resolve2(PACKAGE_ROOT, "..", "..", "docs");
|
|
24652
24657
|
}
|
|
24653
24658
|
function agentGuidePath() {
|
|
24654
24659
|
const candidates = [
|
|
24655
|
-
|
|
24660
|
+
join6(PACKAGE_ROOT, "AGENT_GUIDE.md"),
|
|
24656
24661
|
resolve2(PACKAGE_ROOT, "..", "..", "AGENT_GUIDE.md")
|
|
24657
24662
|
];
|
|
24658
24663
|
for (const c2 of candidates)
|
|
@@ -24662,7 +24667,7 @@ function agentGuidePath() {
|
|
|
24662
24667
|
}
|
|
24663
24668
|
function agentQuickReferencePath() {
|
|
24664
24669
|
const candidates = [
|
|
24665
|
-
|
|
24670
|
+
join6(PACKAGE_ROOT, "AGENT_QUICK_REFERENCE.md"),
|
|
24666
24671
|
resolve2(PACKAGE_ROOT, "..", "..", "AGENT_QUICK_REFERENCE.md")
|
|
24667
24672
|
];
|
|
24668
24673
|
for (const c2 of candidates)
|
|
@@ -24673,12 +24678,12 @@ function agentQuickReferencePath() {
|
|
|
24673
24678
|
function listBundledDocs() {
|
|
24674
24679
|
const entries = [];
|
|
24675
24680
|
const docsDir = bundledDocsDir();
|
|
24676
|
-
const guidesDir =
|
|
24681
|
+
const guidesDir = join6(docsDir, "guides");
|
|
24677
24682
|
if (existsSync7(guidesDir) && statSync(guidesDir).isDirectory()) {
|
|
24678
24683
|
for (const name of readdirSync3(guidesDir)) {
|
|
24679
24684
|
if (!name.endsWith(".md"))
|
|
24680
24685
|
continue;
|
|
24681
|
-
const full =
|
|
24686
|
+
const full = join6(guidesDir, name);
|
|
24682
24687
|
entries.push({
|
|
24683
24688
|
topic: name.replace(/\.md$/, ""),
|
|
24684
24689
|
path: full,
|
|
@@ -26814,11 +26819,11 @@ async function runSyncSelfDocs(options = {}) {
|
|
|
26814
26819
|
printTable(outcomes.filter((o) => o.status === "error").map((o) => ({ topic: o.topic, error: o.detail.slice(0, 100) })));
|
|
26815
26820
|
}
|
|
26816
26821
|
}
|
|
26817
|
-
async function
|
|
26822
|
+
async function action15(options) {
|
|
26818
26823
|
await runSyncSelfDocs(options);
|
|
26819
26824
|
}
|
|
26820
26825
|
function registerSyncSelfDocs(program2) {
|
|
26821
|
-
program2.command("sync-self-docs").description("Ingest bundled Cerefox docs under the _cerefox-self-docs project.").option("--dry-run", "List what would be ingested without writing.").option("--project <name>", "Override the target project name.", "_cerefox-self-docs").action(
|
|
26826
|
+
program2.command("sync-self-docs").description("Ingest bundled Cerefox docs under the _cerefox-self-docs project.").option("--dry-run", "List what would be ingested without writing.").option("--project <name>", "Override the target project name.", "_cerefox-self-docs").action(action15);
|
|
26822
26827
|
}
|
|
26823
26828
|
var init_sync_self_docs = __esm(() => {
|
|
26824
26829
|
init_cli_core();
|
|
@@ -41528,6 +41533,49 @@ function registerDeleteDoc(program2) {
|
|
|
41528
41533
|
program2.command("delete-doc").description("Soft-delete a document (recoverable via the web UI trash).").argument("<document-id>", "UUID of the document to delete.").option("--reason <text>", "Optional reason recorded in the audit log.").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").option("--yes", "Skip the confirmation prompt.").action(action6);
|
|
41529
41534
|
}
|
|
41530
41535
|
|
|
41536
|
+
// src/cli/commands/delete-project.ts
|
|
41537
|
+
init_cli_core();
|
|
41538
|
+
init_client();
|
|
41539
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
41540
|
+
async function action7(target, options) {
|
|
41541
|
+
const client = getClient();
|
|
41542
|
+
const isUuid = UUID_RE.test(target);
|
|
41543
|
+
const lookup = isUuid ? client.raw.from("cerefox_projects").select("id, name, description").eq("id", target).maybeSingle() : client.raw.from("cerefox_projects").select("id, name, description").eq("name", target).maybeSingle();
|
|
41544
|
+
const { data: project, error } = await lookup;
|
|
41545
|
+
if (error) {
|
|
41546
|
+
throw systemError(`Project lookup failed: ${error.message}`);
|
|
41547
|
+
}
|
|
41548
|
+
if (!project) {
|
|
41549
|
+
throw notFound(`Project "${target}" not found.`);
|
|
41550
|
+
}
|
|
41551
|
+
const { count, error: countErr } = await client.raw.from("cerefox_document_projects").select("*", { count: "exact", head: true }).eq("project_id", project.id);
|
|
41552
|
+
if (countErr) {
|
|
41553
|
+
throw systemError(`Could not count documents in project: ${countErr.message}`);
|
|
41554
|
+
}
|
|
41555
|
+
const docCount = count ?? 0;
|
|
41556
|
+
if (docCount > 0 && !options.force) {
|
|
41557
|
+
throw userError(`Project "${project.name}" still has ${docCount} document link(s).`, "Pass --force to delete the project anyway (documents remain; only the project row is removed).");
|
|
41558
|
+
}
|
|
41559
|
+
println(c.yellow("About to delete project:"));
|
|
41560
|
+
println(` ${project.name}`);
|
|
41561
|
+
println(c.dim(` ${project.id} · ${docCount} doc link(s)`));
|
|
41562
|
+
if (!options.yes) {
|
|
41563
|
+
const ok2 = await confirm("Continue?", true);
|
|
41564
|
+
if (!ok2) {
|
|
41565
|
+
println(c.dim("Aborted."));
|
|
41566
|
+
return;
|
|
41567
|
+
}
|
|
41568
|
+
}
|
|
41569
|
+
const { error: delErr } = await client.raw.from("cerefox_projects").delete().eq("id", project.id);
|
|
41570
|
+
if (delErr) {
|
|
41571
|
+
throw systemError(`Delete failed: ${delErr.message}`);
|
|
41572
|
+
}
|
|
41573
|
+
println(c.green(`✓ Deleted project "${project.name}" (id: ${project.id}).`));
|
|
41574
|
+
}
|
|
41575
|
+
function registerDeleteProject(program2) {
|
|
41576
|
+
program2.command("delete-project").description("Delete an empty project (use --force to remove a non-empty one).").argument("<name-or-id>", "Project name (exact match) or UUID.").option("--yes", "Skip the confirmation prompt.").option("--force", "Allow deletion when documents are still linked to the project.").action(action7);
|
|
41577
|
+
}
|
|
41578
|
+
|
|
41531
41579
|
// src/cli/commands/deploy-server.ts
|
|
41532
41580
|
init_cli_core();
|
|
41533
41581
|
init_config();
|
|
@@ -41584,8 +41632,9 @@ function resolveServerAssets(opts = {}) {
|
|
|
41584
41632
|
}
|
|
41585
41633
|
|
|
41586
41634
|
// ../../_shared/db-deploy/index.ts
|
|
41587
|
-
import { existsSync as existsSync5, readFileSync as readFileSync4, readdirSync } from "node:fs";
|
|
41588
41635
|
init_src();
|
|
41636
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4, readdirSync } from "node:fs";
|
|
41637
|
+
import { join as join5 } from "node:path";
|
|
41589
41638
|
var RESET_SQL = `
|
|
41590
41639
|
DROP TABLE IF EXISTS cerefox_chunks CASCADE;
|
|
41591
41640
|
DROP TABLE IF EXISTS cerefox_documents CASCADE;
|
|
@@ -41651,6 +41700,95 @@ async function runDbDeploy(opts) {
|
|
|
41651
41700
|
await sql.end({ timeout: 5 }).catch(() => {});
|
|
41652
41701
|
}
|
|
41653
41702
|
}
|
|
41703
|
+
var BOOTSTRAP_MIGRATIONS_SQL = `
|
|
41704
|
+
CREATE TABLE IF NOT EXISTS cerefox_migrations (
|
|
41705
|
+
id SERIAL PRIMARY KEY,
|
|
41706
|
+
filename TEXT NOT NULL UNIQUE,
|
|
41707
|
+
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
41708
|
+
);
|
|
41709
|
+
`;
|
|
41710
|
+
async function detectExistingSchema(dbUrl) {
|
|
41711
|
+
const sql = src_default(dbUrl, { prepare: false, onnotice: () => {} });
|
|
41712
|
+
try {
|
|
41713
|
+
const rows = await sql`SELECT to_regclass('public.cerefox_documents') AS t`;
|
|
41714
|
+
return rows[0]?.t != null;
|
|
41715
|
+
} finally {
|
|
41716
|
+
await sql.end({ timeout: 5 }).catch(() => {});
|
|
41717
|
+
}
|
|
41718
|
+
}
|
|
41719
|
+
async function migrationStatus(opts) {
|
|
41720
|
+
const sql = src_default(opts.dbUrl, { prepare: false, onnotice: () => {} });
|
|
41721
|
+
try {
|
|
41722
|
+
await sql.unsafe(BOOTSTRAP_MIGRATIONS_SQL);
|
|
41723
|
+
const all = listMigrationFiles(opts.assets.migrationsDir);
|
|
41724
|
+
const appliedRows = await sql`SELECT filename FROM cerefox_migrations ORDER BY filename`;
|
|
41725
|
+
const appliedSet = new Set(appliedRows.map((r) => r.filename));
|
|
41726
|
+
return {
|
|
41727
|
+
all,
|
|
41728
|
+
applied: all.filter((f) => appliedSet.has(f)),
|
|
41729
|
+
pending: all.filter((f) => !appliedSet.has(f))
|
|
41730
|
+
};
|
|
41731
|
+
} finally {
|
|
41732
|
+
await sql.end({ timeout: 5 }).catch(() => {});
|
|
41733
|
+
}
|
|
41734
|
+
}
|
|
41735
|
+
async function runDbMigrate(opts) {
|
|
41736
|
+
const log = opts.log ?? (() => {});
|
|
41737
|
+
const sql = src_default(opts.dbUrl, { prepare: false, onnotice: () => {} });
|
|
41738
|
+
try {
|
|
41739
|
+
await sql.unsafe(BOOTSTRAP_MIGRATIONS_SQL);
|
|
41740
|
+
const allFiles = listMigrationFiles(opts.assets.migrationsDir);
|
|
41741
|
+
const appliedRows = await sql`SELECT filename FROM cerefox_migrations ORDER BY filename`;
|
|
41742
|
+
const appliedSet = new Set(appliedRows.map((r) => r.filename));
|
|
41743
|
+
const pending = allFiles.filter((f) => !appliedSet.has(f));
|
|
41744
|
+
if (pending.length === 0)
|
|
41745
|
+
return { ok: true, applied: [], pending: [] };
|
|
41746
|
+
if (opts.dryRun) {
|
|
41747
|
+
for (const f of pending)
|
|
41748
|
+
log(`Would apply ${f}`);
|
|
41749
|
+
return { ok: true, applied: [], pending };
|
|
41750
|
+
}
|
|
41751
|
+
const applied = [];
|
|
41752
|
+
for (const f of pending) {
|
|
41753
|
+
const body = readFileSync4(join5(opts.assets.migrationsDir, f), "utf8");
|
|
41754
|
+
log(`Applying ${f}…`);
|
|
41755
|
+
try {
|
|
41756
|
+
await sql.begin(async (tx) => {
|
|
41757
|
+
await tx.unsafe(body);
|
|
41758
|
+
await tx`INSERT INTO cerefox_migrations (filename) VALUES (${f}) ON CONFLICT DO NOTHING`;
|
|
41759
|
+
});
|
|
41760
|
+
applied.push(f);
|
|
41761
|
+
} catch (err) {
|
|
41762
|
+
return {
|
|
41763
|
+
ok: false,
|
|
41764
|
+
applied,
|
|
41765
|
+
pending,
|
|
41766
|
+
failedFile: f,
|
|
41767
|
+
error: err instanceof Error ? err.message : String(err)
|
|
41768
|
+
};
|
|
41769
|
+
}
|
|
41770
|
+
}
|
|
41771
|
+
return { ok: true, applied, pending };
|
|
41772
|
+
} finally {
|
|
41773
|
+
await sql.end({ timeout: 5 }).catch(() => {});
|
|
41774
|
+
}
|
|
41775
|
+
}
|
|
41776
|
+
async function applyRpcs(opts) {
|
|
41777
|
+
const log = opts.log ?? (() => {});
|
|
41778
|
+
log("Refresh RPCs (rpcs.sql)…");
|
|
41779
|
+
if (opts.dryRun)
|
|
41780
|
+
return { ok: true };
|
|
41781
|
+
const rpcsSql = readFileSync4(opts.assets.rpcsFile, "utf8");
|
|
41782
|
+
const sql = src_default(opts.dbUrl, { prepare: false, onnotice: () => {} });
|
|
41783
|
+
try {
|
|
41784
|
+
await sql.unsafe(rpcsSql);
|
|
41785
|
+
return { ok: true };
|
|
41786
|
+
} catch (err) {
|
|
41787
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
41788
|
+
} finally {
|
|
41789
|
+
await sql.end({ timeout: 5 }).catch(() => {});
|
|
41790
|
+
}
|
|
41791
|
+
}
|
|
41654
41792
|
|
|
41655
41793
|
// src/cli/commands/deploy-server.ts
|
|
41656
41794
|
function commandSucceeds(cmd, args) {
|
|
@@ -41666,7 +41804,7 @@ function listEdgeFunctions(functionsDir) {
|
|
|
41666
41804
|
return [];
|
|
41667
41805
|
return readdirSync2(functionsDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("cerefox-")).map((e) => e.name).sort();
|
|
41668
41806
|
}
|
|
41669
|
-
async function
|
|
41807
|
+
async function action8(options) {
|
|
41670
41808
|
const settings = loadSettings();
|
|
41671
41809
|
const assets = resolveServerAssets();
|
|
41672
41810
|
const doSchema = !options.functionsOnly;
|
|
@@ -41724,9 +41862,35 @@ async function action7(options) {
|
|
|
41724
41862
|
}
|
|
41725
41863
|
println(c.green(`
|
|
41726
41864
|
✓ All prerequisites satisfied.`));
|
|
41865
|
+
let schemaMode = "unknown";
|
|
41866
|
+
let pending = [];
|
|
41867
|
+
if (doSchema) {
|
|
41868
|
+
try {
|
|
41869
|
+
const exists = await detectExistingSchema(settings.databaseUrl);
|
|
41870
|
+
schemaMode = exists ? "existing" : "fresh";
|
|
41871
|
+
if (exists) {
|
|
41872
|
+
pending = (await migrationStatus({ dbUrl: settings.databaseUrl, assets })).pending;
|
|
41873
|
+
}
|
|
41874
|
+
} catch (err) {
|
|
41875
|
+
if (!options.dryRun) {
|
|
41876
|
+
eprintln(c.red(`
|
|
41877
|
+
✗ Could not connect to the database: ${err instanceof Error ? err.message : String(err)}`));
|
|
41878
|
+
eprintln(c.dim(" Verify CEREFOX_DATABASE_URL (Session Pooler, port 5432)."));
|
|
41879
|
+
process.exit(1);
|
|
41880
|
+
}
|
|
41881
|
+
}
|
|
41882
|
+
}
|
|
41727
41883
|
const planLines = [];
|
|
41728
41884
|
if (doSchema) {
|
|
41729
|
-
|
|
41885
|
+
if (schemaMode === "fresh") {
|
|
41886
|
+
planLines.push(` • Deploy fresh schema + RPCs to ${settings.supabaseUrl || "your Supabase database"}`);
|
|
41887
|
+
} else if (schemaMode === "existing") {
|
|
41888
|
+
planLines.push(` • Update existing schema: apply ${pending.length} pending migration(s) + refresh RPCs`);
|
|
41889
|
+
for (const f of pending)
|
|
41890
|
+
planLines.push(c.dim(` – ${f}`));
|
|
41891
|
+
} else {
|
|
41892
|
+
planLines.push(` • Schema + RPCs (fresh or update — couldn't probe the DB)`);
|
|
41893
|
+
}
|
|
41730
41894
|
}
|
|
41731
41895
|
if (doFunctions) {
|
|
41732
41896
|
planLines.push(` • Deploy ${efNames.length} Edge Function(s): ${efNames.join(", ")}`);
|
|
@@ -41741,26 +41905,52 @@ Plan:`));
|
|
|
41741
41905
|
process.exit(0);
|
|
41742
41906
|
}
|
|
41743
41907
|
const proceed = await confirm(`
|
|
41744
|
-
Proceed with deployment to Supabase
|
|
41908
|
+
Proceed with deployment to Supabase?`, true);
|
|
41745
41909
|
if (!proceed) {
|
|
41746
41910
|
println(c.dim("Aborted."));
|
|
41747
41911
|
process.exit(0);
|
|
41748
41912
|
}
|
|
41749
41913
|
if (doSchema) {
|
|
41750
|
-
|
|
41751
|
-
|
|
41752
|
-
|
|
41753
|
-
|
|
41754
|
-
|
|
41755
|
-
|
|
41756
|
-
|
|
41757
|
-
|
|
41758
|
-
|
|
41759
|
-
|
|
41914
|
+
if (schemaMode === "fresh") {
|
|
41915
|
+
println(c.bold(`
|
|
41916
|
+
▶ Deploying fresh schema + RPCs…`));
|
|
41917
|
+
const result = await runDbDeploy({
|
|
41918
|
+
dbUrl: settings.databaseUrl,
|
|
41919
|
+
assets,
|
|
41920
|
+
log: (line) => println(c.dim(` ${line}`))
|
|
41921
|
+
});
|
|
41922
|
+
if (!result.ok) {
|
|
41923
|
+
eprintln(c.red(`
|
|
41760
41924
|
✗ Schema deploy failed at "${result.failedStep}": ${result.error}`));
|
|
41761
|
-
|
|
41925
|
+
process.exit(1);
|
|
41926
|
+
}
|
|
41927
|
+
println(c.green(` ✓ Fresh schema deployed (${result.stepsRun} steps).`));
|
|
41928
|
+
} else {
|
|
41929
|
+
println(c.bold(`
|
|
41930
|
+
▶ Updating existing schema (migrations + RPC refresh)…`));
|
|
41931
|
+
const mig = await runDbMigrate({
|
|
41932
|
+
dbUrl: settings.databaseUrl,
|
|
41933
|
+
assets,
|
|
41934
|
+
log: (line) => println(c.dim(` ${line}`))
|
|
41935
|
+
});
|
|
41936
|
+
if (!mig.ok) {
|
|
41937
|
+
eprintln(c.red(`
|
|
41938
|
+
✗ Migration "${mig.failedFile}" failed: ${mig.error}`));
|
|
41939
|
+
eprintln(c.dim(" Earlier migrations in this run were committed. Fix + re-run."));
|
|
41940
|
+
process.exit(1);
|
|
41941
|
+
}
|
|
41942
|
+
const rpcs = await applyRpcs({
|
|
41943
|
+
dbUrl: settings.databaseUrl,
|
|
41944
|
+
assets,
|
|
41945
|
+
log: (line) => println(c.dim(` ${line}`))
|
|
41946
|
+
});
|
|
41947
|
+
if (!rpcs.ok) {
|
|
41948
|
+
eprintln(c.red(`
|
|
41949
|
+
✗ RPC refresh failed: ${rpcs.error}`));
|
|
41950
|
+
process.exit(1);
|
|
41951
|
+
}
|
|
41952
|
+
println(c.green(` ✓ Applied ${mig.applied.length} migration(s); RPCs refreshed.`));
|
|
41762
41953
|
}
|
|
41763
|
-
println(c.green(` ✓ Schema deployed (${result.stepsRun} steps).`));
|
|
41764
41954
|
}
|
|
41765
41955
|
if (doFunctions) {
|
|
41766
41956
|
println(c.bold(`
|
|
@@ -41794,7 +41984,7 @@ Proceed with deployment to Supabase${options.reset ? " (--reset DROPS existing d
|
|
|
41794
41984
|
println(c.dim("Verify with: cerefox doctor"));
|
|
41795
41985
|
}
|
|
41796
41986
|
function registerDeployServer(program2) {
|
|
41797
|
-
program2.command("deploy-server").description("Deploy the Cerefox server side (schema + RPCs + Edge Functions)
|
|
41987
|
+
program2.command("deploy-server").description("Deploy/update the Cerefox server side (schema + RPCs + Edge Functions) on Supabase.").option("--dry-run", "Print the plan + pre-flight without deploying.").option("--schema-only", "Deploy/update only the schema + RPCs (skip Edge Functions).").option("--functions-only", "Deploy only the Edge Functions (skip the schema/RPCs).").action(action8);
|
|
41798
41988
|
}
|
|
41799
41989
|
|
|
41800
41990
|
// src/cli/commands/docs.ts
|
|
@@ -41808,7 +41998,7 @@ function openInBrowser(path) {
|
|
|
41808
41998
|
println(c.dim(`(could not auto-open; the file is at: ${path})`));
|
|
41809
41999
|
}
|
|
41810
42000
|
}
|
|
41811
|
-
function
|
|
42001
|
+
function action9(topic, options) {
|
|
41812
42002
|
const docs = listBundledDocs();
|
|
41813
42003
|
if (options.list || !topic && !options.print) {
|
|
41814
42004
|
if (docs.length === 0) {
|
|
@@ -41837,7 +42027,7 @@ function action8(topic, options) {
|
|
|
41837
42027
|
openInBrowser(doc.path);
|
|
41838
42028
|
}
|
|
41839
42029
|
function registerDocs(program2) {
|
|
41840
|
-
program2.command("docs").description("Open bundled Cerefox docs in your browser (or print to stdout).").argument("[topic]", "Doc topic (e.g. quickstart, connect-agents). Omit for the index.").option("--print", "Print to stdout instead of opening a browser.").option("--list", "List available topics.").action(
|
|
42030
|
+
program2.command("docs").description("Open bundled Cerefox docs in your browser (or print to stdout).").argument("[topic]", "Doc topic (e.g. quickstart, connect-agents). Omit for the index.").option("--print", "Print to stdout instead of opening a browser.").option("--list", "List available topics.").action(action9);
|
|
41841
42031
|
}
|
|
41842
42032
|
|
|
41843
42033
|
// ../../node_modules/.bun/ora@9.4.0/node_modules/ora/index.js
|
|
@@ -45231,7 +45421,7 @@ init_config();
|
|
|
45231
45421
|
init_config();
|
|
45232
45422
|
import { existsSync as existsSync8, readFileSync as readFileSync6, realpathSync, statSync as statSync2 } from "node:fs";
|
|
45233
45423
|
import { homedir as homedir4 } from "node:os";
|
|
45234
|
-
import { join as
|
|
45424
|
+
import { join as join7 } from "node:path";
|
|
45235
45425
|
|
|
45236
45426
|
// ../../_shared/compatibility/index.ts
|
|
45237
45427
|
var COMPATIBILITY = {
|
|
@@ -45502,11 +45692,24 @@ async function checkOpenAI() {
|
|
|
45502
45692
|
};
|
|
45503
45693
|
}
|
|
45504
45694
|
}
|
|
45695
|
+
var SCHEMA_VERSION_RE = /^--\s*@version:\s*(\S+)/m;
|
|
45696
|
+
function readBundledSchemaVersion() {
|
|
45697
|
+
try {
|
|
45698
|
+
const assets = resolveServerAssets();
|
|
45699
|
+
if (!existsSync8(assets.schemaFile))
|
|
45700
|
+
return null;
|
|
45701
|
+
const m = readFileSync6(assets.schemaFile, "utf8").match(SCHEMA_VERSION_RE);
|
|
45702
|
+
return m ? m[1] : null;
|
|
45703
|
+
} catch {
|
|
45704
|
+
return null;
|
|
45705
|
+
}
|
|
45706
|
+
}
|
|
45707
|
+
var SCHEMA_CHECK_NAME = "schema + RPCs";
|
|
45505
45708
|
async function checkSchemaVersion() {
|
|
45506
45709
|
const settings = loadSettings();
|
|
45507
45710
|
if (!settings.supabaseUrl || !settings.supabaseKey) {
|
|
45508
45711
|
return {
|
|
45509
|
-
name:
|
|
45712
|
+
name: SCHEMA_CHECK_NAME,
|
|
45510
45713
|
status: "skipped",
|
|
45511
45714
|
detail: "Supabase config missing; skipped."
|
|
45512
45715
|
};
|
|
@@ -45524,21 +45727,40 @@ async function checkSchemaVersion() {
|
|
|
45524
45727
|
});
|
|
45525
45728
|
if (!resp.ok) {
|
|
45526
45729
|
return {
|
|
45527
|
-
name:
|
|
45730
|
+
name: SCHEMA_CHECK_NAME,
|
|
45528
45731
|
status: "error",
|
|
45529
|
-
detail: `cerefox_schema_version returned ${resp.status}
|
|
45530
|
-
hint: "Deploy the schema
|
|
45732
|
+
detail: `cerefox_schema_version returned ${resp.status} — schema not deployed.`,
|
|
45733
|
+
hint: "Deploy the schema + RPCs (see remediation below)."
|
|
45531
45734
|
};
|
|
45532
45735
|
}
|
|
45533
45736
|
const deployed = await resp.json();
|
|
45534
|
-
|
|
45535
|
-
|
|
45536
|
-
|
|
45537
|
-
|
|
45538
|
-
|
|
45737
|
+
const bundled = readBundledSchemaVersion();
|
|
45738
|
+
const level = classifyCompat(deployed, COMPATIBILITY.minSchema, bundled);
|
|
45739
|
+
switch (level) {
|
|
45740
|
+
case "below-min":
|
|
45741
|
+
return {
|
|
45742
|
+
name: SCHEMA_CHECK_NAME,
|
|
45743
|
+
status: "error",
|
|
45744
|
+
detail: `Deployed schema v${deployed} is below the required minimum v${COMPATIBILITY.minSchema}.`,
|
|
45745
|
+
hint: "Update the schema + RPCs (see remediation below)."
|
|
45746
|
+
};
|
|
45747
|
+
case "above-min-but-old":
|
|
45748
|
+
return {
|
|
45749
|
+
name: SCHEMA_CHECK_NAME,
|
|
45750
|
+
status: "warn",
|
|
45751
|
+
detail: `Deployed schema v${deployed} works but is older than this client's bundled v${bundled}.`,
|
|
45752
|
+
hint: "Update the schema + RPCs (see remediation below)."
|
|
45753
|
+
};
|
|
45754
|
+
default:
|
|
45755
|
+
return {
|
|
45756
|
+
name: SCHEMA_CHECK_NAME,
|
|
45757
|
+
status: "ok",
|
|
45758
|
+
detail: `cerefox_schema_version() → "${deployed}"${bundled ? ` (bundled v${bundled})` : ""}`
|
|
45759
|
+
};
|
|
45760
|
+
}
|
|
45539
45761
|
} catch (err) {
|
|
45540
45762
|
return {
|
|
45541
|
-
name:
|
|
45763
|
+
name: SCHEMA_CHECK_NAME,
|
|
45542
45764
|
status: "error",
|
|
45543
45765
|
detail: `Schema version probe failed: ${err instanceof Error ? err.message : String(err)}`
|
|
45544
45766
|
};
|
|
@@ -45557,9 +45779,9 @@ function hasCerefoxInJsonFile(path) {
|
|
|
45557
45779
|
}
|
|
45558
45780
|
function checkMcpConfigs() {
|
|
45559
45781
|
const home = homedir4();
|
|
45560
|
-
const claudeCodeUser =
|
|
45561
|
-
const claudeCodeProj =
|
|
45562
|
-
const claudeDesktop = process.platform === "darwin" ?
|
|
45782
|
+
const claudeCodeUser = join7(home, ".claude.json");
|
|
45783
|
+
const claudeCodeProj = join7(process.cwd(), ".mcp.json");
|
|
45784
|
+
const claudeDesktop = process.platform === "darwin" ? join7(home, "Library", "Application Support", "Claude", "claude_desktop_config.json") : process.platform === "win32" ? join7(process.env.APPDATA ?? "", "Claude", "claude_desktop_config.json") : join7(home, ".config", "Claude", "claude_desktop_config.json");
|
|
45563
45785
|
const found = [];
|
|
45564
45786
|
if (hasCerefoxInJsonFile(claudeCodeUser))
|
|
45565
45787
|
found.push("Claude Code (user)");
|
|
@@ -45583,8 +45805,8 @@ function checkMcpConfigs() {
|
|
|
45583
45805
|
}
|
|
45584
45806
|
function checkLegacyShadowEnv() {
|
|
45585
45807
|
const home = homedir4();
|
|
45586
|
-
const homeEnv =
|
|
45587
|
-
const cwdEnv =
|
|
45808
|
+
const homeEnv = join7(home, USER_STATE_DIR_NAME, ".env");
|
|
45809
|
+
const cwdEnv = join7(process.cwd(), ".env");
|
|
45588
45810
|
if (!existsSync8(homeEnv) || !existsSync8(cwdEnv))
|
|
45589
45811
|
return null;
|
|
45590
45812
|
try {
|
|
@@ -45689,14 +45911,14 @@ async function checkEdgeFunctionsCompat() {
|
|
|
45689
45911
|
name: "edge functions",
|
|
45690
45912
|
status: "error",
|
|
45691
45913
|
detail: `Deployed EF v${deployed} is below the required minimum v${compat.edgeFunctions.min}.`,
|
|
45692
|
-
hint: "
|
|
45914
|
+
hint: "Update the Edge Functions (see remediation below)."
|
|
45693
45915
|
};
|
|
45694
45916
|
case "above-min-but-old":
|
|
45695
45917
|
return {
|
|
45696
45918
|
name: "edge functions",
|
|
45697
45919
|
status: "warn",
|
|
45698
45920
|
detail: `Deployed EF v${deployed} works but is older than this client (v${PKG_VERSION}).`,
|
|
45699
|
-
hint: "
|
|
45921
|
+
hint: "Update the Edge Functions (see remediation below)."
|
|
45700
45922
|
};
|
|
45701
45923
|
default:
|
|
45702
45924
|
return {
|
|
@@ -45731,7 +45953,7 @@ async function runAllChecks(opts = {}) {
|
|
|
45731
45953
|
{ name: "legacy env", phase: "Checking legacy env shadowing", run: () => checkLegacyShadowEnv() },
|
|
45732
45954
|
{ name: "supabase", phase: "Probing Supabase Data API", run: () => checkSupabase() },
|
|
45733
45955
|
{ name: "openai", phase: "Probing OpenAI embeddings", run: () => checkOpenAI() },
|
|
45734
|
-
{ name: "schema", phase: "Reading schema version", run: () => checkSchemaVersion() },
|
|
45956
|
+
{ name: "schema + RPCs", phase: "Reading schema + RPC version", run: () => checkSchemaVersion() },
|
|
45735
45957
|
{ name: "edge functions", phase: "Probing Edge Function versions", run: () => checkEdgeFunctionsCompat() },
|
|
45736
45958
|
{ name: "postgres", phase: "Probing Postgres DDL endpoint", run: () => checkPostgres() },
|
|
45737
45959
|
{ name: "mcp clients", phase: "Scanning MCP client configs", run: () => checkMcpConfigs() }
|
|
@@ -45760,7 +45982,7 @@ function symbol(status) {
|
|
|
45760
45982
|
return cErr.dim("ℹ");
|
|
45761
45983
|
}
|
|
45762
45984
|
}
|
|
45763
|
-
async function
|
|
45985
|
+
async function action10(options) {
|
|
45764
45986
|
const useSpinner = !options.json && process.stderr.isTTY;
|
|
45765
45987
|
const spinner = useSpinner ? ora({ text: "Starting checks…", spinner: "dots", stream: process.stderr }).start() : null;
|
|
45766
45988
|
const results = await runAllChecks({
|
|
@@ -45784,6 +46006,26 @@ async function action9(options) {
|
|
|
45784
46006
|
}
|
|
45785
46007
|
println("");
|
|
45786
46008
|
}
|
|
46009
|
+
if (!options.json) {
|
|
46010
|
+
const stale = (name) => {
|
|
46011
|
+
const r = results.find((x) => x.name === name);
|
|
46012
|
+
return r != null && (r.status === "error" || r.status === "warn");
|
|
46013
|
+
};
|
|
46014
|
+
const needsSchema = stale("schema + RPCs");
|
|
46015
|
+
const needsEf = stale("edge functions");
|
|
46016
|
+
let remediation = null;
|
|
46017
|
+
if (needsSchema && needsEf) {
|
|
46018
|
+
remediation = "Update the server (schema + RPCs + Edge Functions): cerefox deploy-server";
|
|
46019
|
+
} else if (needsSchema) {
|
|
46020
|
+
remediation = "Update the schema + RPCs: cerefox deploy-server --schema-only";
|
|
46021
|
+
} else if (needsEf) {
|
|
46022
|
+
remediation = "Update the Edge Functions: cerefox deploy-server --functions-only";
|
|
46023
|
+
}
|
|
46024
|
+
if (remediation) {
|
|
46025
|
+
println(cErr.yellow("→ " + remediation));
|
|
46026
|
+
println("");
|
|
46027
|
+
}
|
|
46028
|
+
}
|
|
45787
46029
|
const errCount = results.filter((r) => r.status === "error").length;
|
|
45788
46030
|
const warnCount = results.filter((r) => r.status === "warn").length;
|
|
45789
46031
|
if (errCount > 0) {
|
|
@@ -45797,13 +46039,13 @@ async function action9(options) {
|
|
|
45797
46039
|
}
|
|
45798
46040
|
}
|
|
45799
46041
|
function registerDoctor(program2) {
|
|
45800
|
-
program2.command("doctor").description("Run diagnostic checks against the installed Cerefox.").option("--json", "Emit machine-readable JSON (no colours, structured output).").action(
|
|
46042
|
+
program2.command("doctor").description("Run diagnostic checks against the installed Cerefox.").option("--json", "Emit machine-readable JSON (no colours, structured output).").action(action10);
|
|
45801
46043
|
}
|
|
45802
46044
|
|
|
45803
46045
|
// src/cli/commands/get-audit-log.ts
|
|
45804
46046
|
init_cli_core();
|
|
45805
46047
|
init_client();
|
|
45806
|
-
async function
|
|
46048
|
+
async function action11(options) {
|
|
45807
46049
|
const limit = parsePositiveInt(options.limit, "--limit", 50);
|
|
45808
46050
|
const client = getClient();
|
|
45809
46051
|
const data = await client.rpc("cerefox_list_audit_entries", {
|
|
@@ -45841,14 +46083,14 @@ async function action10(options) {
|
|
|
45841
46083
|
})));
|
|
45842
46084
|
}
|
|
45843
46085
|
function registerGetAuditLog(program2) {
|
|
45844
|
-
program2.command("get-audit-log").description("Query the audit log with optional filters.").option("-d, --document-id <uuid>", "Filter by document.").option("-a, --author <name>", "Filter by author.").option("-o, --operation <type>", "Filter by operation: create, update-content, update-metadata, delete, restore.").option("--since <iso>", "Lower-bound ISO timestamp.").option("--until <iso>", "Upper-bound ISO timestamp.").option("-l, --limit <n>", "Maximum entries (max 200).", "50").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(
|
|
46086
|
+
program2.command("get-audit-log").description("Query the audit log with optional filters.").option("-d, --document-id <uuid>", "Filter by document.").option("-a, --author <name>", "Filter by author.").option("-o, --operation <type>", "Filter by operation: create, update-content, update-metadata, delete, restore.").option("--since <iso>", "Lower-bound ISO timestamp.").option("--until <iso>", "Upper-bound ISO timestamp.").option("-l, --limit <n>", "Maximum entries (max 200).", "50").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action11);
|
|
45845
46087
|
}
|
|
45846
46088
|
|
|
45847
46089
|
// src/cli/commands/get-doc.ts
|
|
45848
46090
|
init_cli_core();
|
|
45849
46091
|
init_cli_core();
|
|
45850
46092
|
init_client();
|
|
45851
|
-
async function
|
|
46093
|
+
async function action12(documentId, options) {
|
|
45852
46094
|
const client = getClient();
|
|
45853
46095
|
const rows = await client.rpc("cerefox_get_document", {
|
|
45854
46096
|
p_document_id: documentId,
|
|
@@ -45878,7 +46120,7 @@ async function action11(documentId, options) {
|
|
|
45878
46120
|
println(doc.full_content);
|
|
45879
46121
|
}
|
|
45880
46122
|
function registerGetDoc(program2) {
|
|
45881
|
-
program2.command("get-doc").description("Retrieve the full content of a document by ID.").argument("<document-id>", "UUID of the document.").option("--version-id <uuid>", "Specific archived version (default: current).").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(
|
|
46123
|
+
program2.command("get-doc").description("Retrieve the full content of a document by ID.").argument("<document-id>", "UUID of the document.").option("--version-id <uuid>", "Specific archived version (default: current).").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action12);
|
|
45882
46124
|
}
|
|
45883
46125
|
|
|
45884
46126
|
// src/cli/commands/ingest.ts
|
|
@@ -46615,7 +46857,7 @@ async function readContent(path, paste) {
|
|
|
46615
46857
|
const titleFromPath = basename2(path, extname2(path));
|
|
46616
46858
|
return { content, titleFromPath };
|
|
46617
46859
|
}
|
|
46618
|
-
async function
|
|
46860
|
+
async function action13(path, options) {
|
|
46619
46861
|
const { content, titleFromPath } = await readContent(path, Boolean(options.paste));
|
|
46620
46862
|
const title = options.title ?? titleFromPath;
|
|
46621
46863
|
if (!title || title.trim() === "") {
|
|
@@ -46687,7 +46929,7 @@ async function action12(path, options) {
|
|
|
46687
46929
|
}
|
|
46688
46930
|
}
|
|
46689
46931
|
function registerIngest(program2) {
|
|
46690
|
-
program2.command("ingest").description("Ingest a file (or stdin paste) into the knowledge base.").argument("[path]", "Path to the file to ingest. Omit when using --paste.").option("--paste", "Read content from stdin instead of a file.").option("-t, --title <title>", "Document title (required with --paste; defaults to filename without extension).").option("-p, --project-name <name>", "Single project membership (non-destructive on update).").option("-P, --project-names <names>", "Comma-separated full project membership set (destructive replace on update).").option("-m, --metadata <json>", "JSON metadata object.").option("--source <label>", "Origin label (default: cli).", "cli").option("-u, --update-if-exists", "Update an existing doc with the same title.").option("-i, --document-id <uuid>", "Update a specific document by UUID (overrides --update-if-exists).").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").action(
|
|
46932
|
+
program2.command("ingest").description("Ingest a file (or stdin paste) into the knowledge base.").argument("[path]", "Path to the file to ingest. Omit when using --paste.").option("--paste", "Read content from stdin instead of a file.").option("-t, --title <title>", "Document title (required with --paste; defaults to filename without extension).").option("-p, --project-name <name>", "Single project membership (non-destructive on update).").option("-P, --project-names <names>", "Comma-separated full project membership set (destructive replace on update).").option("-m, --metadata <json>", "JSON metadata object.").option("--source <label>", "Origin label (default: cli).", "cli").option("-u, --update-if-exists", "Update an existing doc with the same title.").option("-i, --document-id <uuid>", "Update a specific document by UUID (overrides --update-if-exists).").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").action(action13);
|
|
46691
46933
|
}
|
|
46692
46934
|
|
|
46693
46935
|
// src/cli/commands/ingest-dir.ts
|
|
@@ -46696,7 +46938,7 @@ init_cli_core();
|
|
|
46696
46938
|
init_config();
|
|
46697
46939
|
var import_cli_progress = __toESM(require_cli_progress(), 1);
|
|
46698
46940
|
import { readdirSync as readdirSync4, statSync as statSync3 } from "node:fs";
|
|
46699
|
-
import { basename as basename3, extname as extname3, join as
|
|
46941
|
+
import { basename as basename3, extname as extname3, join as join8 } from "node:path";
|
|
46700
46942
|
function walk(dir, extensions) {
|
|
46701
46943
|
let entries;
|
|
46702
46944
|
try {
|
|
@@ -46706,7 +46948,7 @@ function walk(dir, extensions) {
|
|
|
46706
46948
|
}
|
|
46707
46949
|
const files = [];
|
|
46708
46950
|
for (const name of entries) {
|
|
46709
|
-
const full =
|
|
46951
|
+
const full = join8(dir, name);
|
|
46710
46952
|
let stat;
|
|
46711
46953
|
try {
|
|
46712
46954
|
stat = statSync3(full);
|
|
@@ -46723,7 +46965,7 @@ function walk(dir, extensions) {
|
|
|
46723
46965
|
}
|
|
46724
46966
|
return files;
|
|
46725
46967
|
}
|
|
46726
|
-
async function
|
|
46968
|
+
async function action14(dir, options) {
|
|
46727
46969
|
const extensions = new Set((options.extensions ?? ".md,.txt").split(",").map((e) => e.trim().toLowerCase()).map((e) => e.startsWith(".") ? e : "." + e).filter((e) => e.length > 0));
|
|
46728
46970
|
const files = walk(dir, extensions);
|
|
46729
46971
|
if (files.length === 0) {
|
|
@@ -46796,7 +47038,7 @@ async function action13(dir, options) {
|
|
|
46796
47038
|
}
|
|
46797
47039
|
}
|
|
46798
47040
|
function registerIngestDir(program2) {
|
|
46799
|
-
program2.command("ingest-dir").description("Recursively ingest a directory of markdown / text files.").argument("<dir>", "Root directory to walk.").option("-p, --project-name <name>", "Project membership for all ingested docs.").option("-m, --metadata <json>", "JSON metadata applied to every doc.").option("--source <label>", "Origin label (default: cli).", "cli").option("-u, --update-if-exists", "Update an existing doc with the same title.").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").option("-e, --extensions <list>", "Comma-separated file extensions to ingest.", ".md,.txt").action(
|
|
47041
|
+
program2.command("ingest-dir").description("Recursively ingest a directory of markdown / text files.").argument("<dir>", "Root directory to walk.").option("-p, --project-name <name>", "Project membership for all ingested docs.").option("-m, --metadata <json>", "JSON metadata applied to every doc.").option("--source <label>", "Origin label (default: cli).", "cli").option("-u, --update-if-exists", "Update an existing doc with the same title.").option("-a, --author <name>", "Caller identity (audit log).").option("--author-type <type>", "'user' or 'agent' (default: user).", "user").option("-e, --extensions <list>", "Comma-separated file extensions to ingest.", ".md,.txt").action(action14);
|
|
46800
47042
|
}
|
|
46801
47043
|
|
|
46802
47044
|
// src/cli/commands/init.ts
|
|
@@ -46812,7 +47054,7 @@ import {
|
|
|
46812
47054
|
writeFileSync as writeFileSync3
|
|
46813
47055
|
} from "node:fs";
|
|
46814
47056
|
import { homedir as homedir5 } from "node:os";
|
|
46815
|
-
import { dirname as dirname4, join as
|
|
47057
|
+
import { dirname as dirname4, join as join9 } from "node:path";
|
|
46816
47058
|
async function readConfigFile(path) {
|
|
46817
47059
|
if (!existsSync9(path)) {
|
|
46818
47060
|
throw userError(`--config file not found: ${path}`);
|
|
@@ -47062,11 +47304,11 @@ async function maybeOfferServerDeploy() {
|
|
|
47062
47304
|
if (compareSemver(deployed, COMPATIBILITY.minSchema) < 0) {
|
|
47063
47305
|
println(c.bold("Schema deploy"));
|
|
47064
47306
|
println(c.yellow(` Deployed schema v${deployed} is below the required v${COMPATIBILITY.minSchema}.`));
|
|
47065
|
-
const yes = await confirm("
|
|
47307
|
+
const yes = await confirm(" Update the server now (applies pending migrations, refreshes RPCs + EFs)?", true);
|
|
47066
47308
|
if (yes)
|
|
47067
|
-
launchDeployServer(
|
|
47309
|
+
launchDeployServer();
|
|
47068
47310
|
else
|
|
47069
|
-
println(c.dim(" Skipped. Run `cerefox deploy-server
|
|
47311
|
+
println(c.dim(" Skipped. Run `cerefox deploy-server` when ready."));
|
|
47070
47312
|
println("");
|
|
47071
47313
|
return;
|
|
47072
47314
|
}
|
|
@@ -47126,9 +47368,9 @@ function writeAnswersTo(target, answers) {
|
|
|
47126
47368
|
}
|
|
47127
47369
|
}
|
|
47128
47370
|
}
|
|
47129
|
-
async function
|
|
47130
|
-
const homeEnv =
|
|
47131
|
-
const cwdEnv =
|
|
47371
|
+
async function action16(options) {
|
|
47372
|
+
const homeEnv = join9(homedir5(), USER_STATE_DIR_NAME, ".env");
|
|
47373
|
+
const cwdEnv = join9(process.cwd(), ".env");
|
|
47132
47374
|
const explicitDir = (process.env.CEREFOX_CONFIG_DIR ?? "").trim();
|
|
47133
47375
|
if (explicitDir) {
|
|
47134
47376
|
const target2 = resolveEnvFile();
|
|
@@ -47235,13 +47477,13 @@ async function action15(options) {
|
|
|
47235
47477
|
await postWriteLifecycle(target, options);
|
|
47236
47478
|
}
|
|
47237
47479
|
function registerInit(program2) {
|
|
47238
|
-
program2.command("init").description("Interactive first-run setup (config, schema deploy stub, optional MCP wiring).").option("-c, --config <file>", "Non-interactive mode: read answers from a JSON file.").option("--force", "Overwrite existing configuration without prompting.").option("--skip-schema", "Skip the schema deploy step.").option("--skip-self-docs", "Skip the bundled self-doc ingest.").option("--skip-agent-config", "Skip the optional MCP agent wiring.").action(
|
|
47480
|
+
program2.command("init").description("Interactive first-run setup (config, schema deploy stub, optional MCP wiring).").option("-c, --config <file>", "Non-interactive mode: read answers from a JSON file.").option("--force", "Overwrite existing configuration without prompting.").option("--skip-schema", "Skip the schema deploy step.").option("--skip-self-docs", "Skip the bundled self-doc ingest.").option("--skip-agent-config", "Skip the optional MCP agent wiring.").action(action16);
|
|
47239
47481
|
}
|
|
47240
47482
|
|
|
47241
47483
|
// src/cli/commands/list-docs.ts
|
|
47242
47484
|
init_cli_core();
|
|
47243
47485
|
init_client();
|
|
47244
|
-
async function
|
|
47486
|
+
async function action17(options) {
|
|
47245
47487
|
const limit = parsePositiveInt(options.limit, "--limit", 100);
|
|
47246
47488
|
const client = getClient();
|
|
47247
47489
|
let projectId;
|
|
@@ -47296,13 +47538,13 @@ async function action16(options) {
|
|
|
47296
47538
|
})));
|
|
47297
47539
|
}
|
|
47298
47540
|
function registerListDocs(program2) {
|
|
47299
|
-
program2.command("list-docs").description("List documents in the knowledge base.").option("-p, --project <name>", "Filter to a specific project.").option("-l, --limit <n>", "Maximum docs to return.", "100").option("--json", "Emit machine-readable JSON.").action(
|
|
47541
|
+
program2.command("list-docs").description("List documents in the knowledge base.").option("-p, --project <name>", "Filter to a specific project.").option("-l, --limit <n>", "Maximum docs to return.", "100").option("--json", "Emit machine-readable JSON.").action(action17);
|
|
47300
47542
|
}
|
|
47301
47543
|
|
|
47302
47544
|
// src/cli/commands/list-metadata-keys.ts
|
|
47303
47545
|
init_cli_core();
|
|
47304
47546
|
init_client();
|
|
47305
|
-
async function
|
|
47547
|
+
async function action18(options) {
|
|
47306
47548
|
const client = getClient();
|
|
47307
47549
|
const data = await client.rpc("cerefox_list_metadata_keys");
|
|
47308
47550
|
if (data === null) {
|
|
@@ -47330,13 +47572,13 @@ async function action17(options) {
|
|
|
47330
47572
|
})));
|
|
47331
47573
|
}
|
|
47332
47574
|
function registerListMetadataKeys(program2) {
|
|
47333
|
-
program2.command("list-metadata-keys").description("List all metadata keys with document counts and example values.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(
|
|
47575
|
+
program2.command("list-metadata-keys").description("List all metadata keys with document counts and example values.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action18);
|
|
47334
47576
|
}
|
|
47335
47577
|
|
|
47336
47578
|
// src/cli/commands/list-projects.ts
|
|
47337
47579
|
init_cli_core();
|
|
47338
47580
|
init_client();
|
|
47339
|
-
async function
|
|
47581
|
+
async function action19(options) {
|
|
47340
47582
|
const client = getClient();
|
|
47341
47583
|
const { data, error: error2 } = await client.raw.from("cerefox_projects").select("id, name, description, created_at").order("name", { ascending: true });
|
|
47342
47584
|
if (error2) {
|
|
@@ -47365,13 +47607,13 @@ async function action18(options) {
|
|
|
47365
47607
|
})), "(no projects)");
|
|
47366
47608
|
}
|
|
47367
47609
|
function registerListProjects(program2) {
|
|
47368
|
-
program2.command("list-projects").description("List all projects in the knowledge base.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(
|
|
47610
|
+
program2.command("list-projects").description("List all projects in the knowledge base.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action19);
|
|
47369
47611
|
}
|
|
47370
47612
|
|
|
47371
47613
|
// src/cli/commands/list-versions.ts
|
|
47372
47614
|
init_cli_core();
|
|
47373
47615
|
init_client();
|
|
47374
|
-
async function
|
|
47616
|
+
async function action20(documentId, options) {
|
|
47375
47617
|
const client = getClient();
|
|
47376
47618
|
const data = await client.rpc("cerefox_list_document_versions", {
|
|
47377
47619
|
p_document_id: documentId
|
|
@@ -47412,7 +47654,7 @@ async function action19(documentId, options) {
|
|
|
47412
47654
|
})));
|
|
47413
47655
|
}
|
|
47414
47656
|
function registerListVersions(program2) {
|
|
47415
|
-
program2.command("list-versions").description("List archived versions of a document.").argument("<document-id>", "UUID of the document.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(
|
|
47657
|
+
program2.command("list-versions").description("List archived versions of a document.").argument("<document-id>", "UUID of the document.").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action20);
|
|
47416
47658
|
}
|
|
47417
47659
|
|
|
47418
47660
|
// src/cli/commands/mcp.ts
|
|
@@ -47427,7 +47669,7 @@ function registerMcp(program2) {
|
|
|
47427
47669
|
// src/cli/commands/metadata-search.ts
|
|
47428
47670
|
init_cli_core();
|
|
47429
47671
|
init_client();
|
|
47430
|
-
async function
|
|
47672
|
+
async function action21(options) {
|
|
47431
47673
|
const metadataFilter = parseJsonObjectArg(options.metadataFilter, "--metadata-filter");
|
|
47432
47674
|
if (!metadataFilter || Object.keys(metadataFilter).length === 0) {
|
|
47433
47675
|
throw userError("--metadata-filter is required and must be a non-empty JSON object.", `Example: --metadata-filter '{"type":"decision-log"}'.`);
|
|
@@ -47490,7 +47732,7 @@ async function action20(options) {
|
|
|
47490
47732
|
}
|
|
47491
47733
|
}
|
|
47492
47734
|
function registerMetadataSearch(program2) {
|
|
47493
|
-
program2.command("metadata-search").description("Find documents by metadata criteria (no text query).").requiredOption("-f, --metadata-filter <json>", "JSON object; only docs whose metadata contains ALL pairs are returned.").option("-p, --project-name <name>", "Filter to a specific project.").option("--updated-since <iso>", "Only docs updated on/after this ISO timestamp.").option("--created-since <iso>", "Only docs created on/after this ISO timestamp.").option("--include-content", "Include full document text in results.").option("-l, --limit <n>", "Maximum docs to return.", "10").option("--max-bytes <n>", "Response size budget in bytes (with --include-content).", "200000").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(
|
|
47735
|
+
program2.command("metadata-search").description("Find documents by metadata criteria (no text query).").requiredOption("-f, --metadata-filter <json>", "JSON object; only docs whose metadata contains ALL pairs are returned.").option("-p, --project-name <name>", "Filter to a specific project.").option("--updated-since <iso>", "Only docs updated on/after this ISO timestamp.").option("--created-since <iso>", "Only docs created on/after this ISO timestamp.").option("--include-content", "Include full document text in results.").option("-l, --limit <n>", "Maximum docs to return.", "10").option("--max-bytes <n>", "Response size budget in bytes (with --include-content).", "200000").option("-r, --requestor <name>", "Agent / user name (usage log).").option("--json", "Emit machine-readable JSON.").action(action21);
|
|
47494
47736
|
}
|
|
47495
47737
|
|
|
47496
47738
|
// src/cli/commands/reindex.ts
|
|
@@ -47498,7 +47740,7 @@ init_dist4();
|
|
|
47498
47740
|
init_cli_core();
|
|
47499
47741
|
init_config();
|
|
47500
47742
|
var DEFAULT_MODEL = "text-embedding-3-small";
|
|
47501
|
-
async function
|
|
47743
|
+
async function action22(options) {
|
|
47502
47744
|
const settings = loadSettings();
|
|
47503
47745
|
if (!settings.supabaseUrl || !settings.supabaseKey) {
|
|
47504
47746
|
throw userError("Supabase credentials not configured — run `cerefox init` first.");
|
|
@@ -47577,7 +47819,7 @@ ${c2.content}`;
|
|
|
47577
47819
|
}
|
|
47578
47820
|
}
|
|
47579
47821
|
function registerReindex(program2) {
|
|
47580
|
-
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(
|
|
47822
|
+
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(action22);
|
|
47581
47823
|
}
|
|
47582
47824
|
|
|
47583
47825
|
// src/cli/commands/restore.ts
|
|
@@ -47585,12 +47827,12 @@ init_cli_core();
|
|
|
47585
47827
|
init_client();
|
|
47586
47828
|
import { existsSync as existsSync10, readFileSync as readFileSync11, readdirSync as readdirSync5, statSync as statSync4 } from "node:fs";
|
|
47587
47829
|
import { homedir as homedir6 } from "node:os";
|
|
47588
|
-
import { join as
|
|
47830
|
+
import { join as join10, resolve as resolve4 } from "node:path";
|
|
47589
47831
|
function expandHome2(path) {
|
|
47590
47832
|
if (path === "~")
|
|
47591
47833
|
return homedir6();
|
|
47592
47834
|
if (path.startsWith("~/"))
|
|
47593
|
-
return
|
|
47835
|
+
return join10(homedir6(), path.slice(2));
|
|
47594
47836
|
return path;
|
|
47595
47837
|
}
|
|
47596
47838
|
function resolveBackupFile(target) {
|
|
@@ -47601,13 +47843,13 @@ function resolveBackupFile(target) {
|
|
|
47601
47843
|
const stat = statSync4(path);
|
|
47602
47844
|
if (stat.isFile())
|
|
47603
47845
|
return path;
|
|
47604
|
-
const candidates = readdirSync5(path).filter((n) => n.endsWith(".json") && n.startsWith("cerefox-")).map((n) => ({ name: n, mtime: statSync4(
|
|
47846
|
+
const candidates = readdirSync5(path).filter((n) => n.endsWith(".json") && n.startsWith("cerefox-")).map((n) => ({ name: n, mtime: statSync4(join10(path, n)).mtimeMs })).sort((a, b2) => b2.mtime - a.mtime);
|
|
47605
47847
|
if (candidates.length === 0) {
|
|
47606
47848
|
throw userError(`No cerefox-*.json files in ${path}`);
|
|
47607
47849
|
}
|
|
47608
|
-
return
|
|
47850
|
+
return join10(path, candidates[0].name);
|
|
47609
47851
|
}
|
|
47610
|
-
async function
|
|
47852
|
+
async function action23(target, options) {
|
|
47611
47853
|
const file = resolveBackupFile(target);
|
|
47612
47854
|
let payload;
|
|
47613
47855
|
try {
|
|
@@ -47663,7 +47905,7 @@ async function action22(target, options) {
|
|
|
47663
47905
|
}
|
|
47664
47906
|
}
|
|
47665
47907
|
function registerRestore(program2) {
|
|
47666
|
-
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 ride along with each doc's metadata).").action(
|
|
47908
|
+
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 ride along with each doc's metadata).").action(action23);
|
|
47667
47909
|
}
|
|
47668
47910
|
|
|
47669
47911
|
// src/cli/commands/search.ts
|
|
@@ -47688,7 +47930,7 @@ async function embedQuery(query) {
|
|
|
47688
47930
|
}
|
|
47689
47931
|
|
|
47690
47932
|
// src/cli/commands/search.ts
|
|
47691
|
-
async function
|
|
47933
|
+
async function action24(query, options) {
|
|
47692
47934
|
if (!query || query.trim() === "") {
|
|
47693
47935
|
throw userError("Empty query.");
|
|
47694
47936
|
}
|
|
@@ -47822,7 +48064,7 @@ async function action23(query, options) {
|
|
|
47822
48064
|
}
|
|
47823
48065
|
}
|
|
47824
48066
|
function registerSearch(program2) {
|
|
47825
|
-
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).", "0.7").option("--min-score <float>", "Minimum cosine similarity threshold.", "0.5").option("--max-bytes <n>", "Response size budget in bytes.", "200000").option("-r, --requestor <name>", "Agent / user name (recorded in usage log).").option("--json", "Emit machine-readable JSON instead of the default text.").action(
|
|
48067
|
+
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).", "0.7").option("--min-score <float>", "Minimum cosine similarity threshold.", "0.5").option("--max-bytes <n>", "Response size budget in bytes.", "200000").option("-r, --requestor <name>", "Agent / user name (recorded in usage log).").option("--json", "Emit machine-readable JSON instead of the default text.").action(action24);
|
|
47826
48068
|
}
|
|
47827
48069
|
|
|
47828
48070
|
// src/cli/commands/self-update.ts
|
|
@@ -47869,7 +48111,7 @@ async function fetchLatestVersion() {
|
|
|
47869
48111
|
}
|
|
47870
48112
|
return body.version;
|
|
47871
48113
|
}
|
|
47872
|
-
async function
|
|
48114
|
+
async function action25(options) {
|
|
47873
48115
|
let target;
|
|
47874
48116
|
try {
|
|
47875
48117
|
target = options.version ?? await fetchLatestVersion();
|
|
@@ -47921,7 +48163,7 @@ async function action24(options) {
|
|
|
47921
48163
|
}
|
|
47922
48164
|
function registerSelfUpdate(program2) {
|
|
47923
48165
|
const desc = "Upgrade Cerefox in place. Alias: `cerefox upgrade`.";
|
|
47924
|
-
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(
|
|
48166
|
+
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(action25);
|
|
47925
48167
|
declaration(program2.command("self-update"));
|
|
47926
48168
|
declaration(program2.command("upgrade"));
|
|
47927
48169
|
}
|
|
@@ -47940,7 +48182,7 @@ function symbol2(status) {
|
|
|
47940
48182
|
return cErr.dim("ℹ");
|
|
47941
48183
|
}
|
|
47942
48184
|
}
|
|
47943
|
-
async function
|
|
48185
|
+
async function action26(options) {
|
|
47944
48186
|
const useSpinner = !options.json && process.stderr.isTTY;
|
|
47945
48187
|
const spinner = useSpinner ? ora({ text: "Starting checks…", spinner: "dots", stream: process.stderr }).start() : null;
|
|
47946
48188
|
const results = await runFastChecks({
|
|
@@ -47961,7 +48203,7 @@ async function action25(options) {
|
|
|
47961
48203
|
}
|
|
47962
48204
|
}
|
|
47963
48205
|
function registerStatus(program2) {
|
|
47964
|
-
program2.command("status").description("Quick sanity check (fast subset of `cerefox doctor`).").option("--json", "Emit machine-readable JSON.").action(
|
|
48206
|
+
program2.command("status").description("Quick sanity check (fast subset of `cerefox doctor`).").option("--json", "Emit machine-readable JSON.").action(action26);
|
|
47965
48207
|
}
|
|
47966
48208
|
|
|
47967
48209
|
// src/cli/commands/sync-docs.ts
|
|
@@ -47975,14 +48217,14 @@ import {
|
|
|
47975
48217
|
readdirSync as readdirSync6,
|
|
47976
48218
|
statSync as statSync5
|
|
47977
48219
|
} from "node:fs";
|
|
47978
|
-
import { basename as basename5, extname as extname5, join as
|
|
48220
|
+
import { basename as basename5, extname as extname5, join as join11, relative } from "node:path";
|
|
47979
48221
|
var ROOT_LEVEL_DOCS = ["README.md", "AGENT_GUIDE.md", "AGENT_QUICK_REFERENCE.md"];
|
|
47980
48222
|
function walkMarkdown(dir) {
|
|
47981
48223
|
const out = [];
|
|
47982
48224
|
if (!existsSync11(dir))
|
|
47983
48225
|
return out;
|
|
47984
48226
|
for (const name of readdirSync6(dir)) {
|
|
47985
|
-
const full =
|
|
48227
|
+
const full = join11(dir, name);
|
|
47986
48228
|
let stat;
|
|
47987
48229
|
try {
|
|
47988
48230
|
stat = statSync5(full);
|
|
@@ -47997,16 +48239,16 @@ function walkMarkdown(dir) {
|
|
|
47997
48239
|
}
|
|
47998
48240
|
return out;
|
|
47999
48241
|
}
|
|
48000
|
-
async function
|
|
48242
|
+
async function action27(options) {
|
|
48001
48243
|
const cwd = process.cwd();
|
|
48002
48244
|
const project = options.project ?? "cerefox";
|
|
48003
48245
|
const targets = [];
|
|
48004
48246
|
for (const rel of ROOT_LEVEL_DOCS) {
|
|
48005
|
-
const abs =
|
|
48247
|
+
const abs = join11(cwd, rel);
|
|
48006
48248
|
if (existsSync11(abs))
|
|
48007
48249
|
targets.push({ abs, rel });
|
|
48008
48250
|
}
|
|
48009
|
-
for (const abs of walkMarkdown(
|
|
48251
|
+
for (const abs of walkMarkdown(join11(cwd, "docs"))) {
|
|
48010
48252
|
targets.push({ abs, rel: relative(cwd, abs) });
|
|
48011
48253
|
}
|
|
48012
48254
|
if (targets.length === 0) {
|
|
@@ -48059,7 +48301,7 @@ async function action26(options) {
|
|
|
48059
48301
|
}
|
|
48060
48302
|
}
|
|
48061
48303
|
function registerSyncDocs(program2) {
|
|
48062
|
-
program2.command("sync-docs").description("Sync repo docs (README, AGENT_*, docs/) into a Cerefox project.").option("--dry-run", "Print what would be synced without writing.").option("-p, --project <name>", "Target project for the sync.", "cerefox").action(
|
|
48304
|
+
program2.command("sync-docs").description("Sync repo docs (README, AGENT_*, docs/) into a Cerefox project.").option("--dry-run", "Print what would be synced without writing.").option("-p, --project <name>", "Target project for the sync.", "cerefox").action(action27);
|
|
48063
48305
|
}
|
|
48064
48306
|
|
|
48065
48307
|
// src/cli/program.ts
|
|
@@ -49395,7 +49637,7 @@ var baseMimes = _baseMimes;
|
|
|
49395
49637
|
|
|
49396
49638
|
// ../../node_modules/.bun/@hono+node-server@2.0.4+1bbe96acb4c5ebf1/node_modules/@hono/node-server/dist/serve-static.mjs
|
|
49397
49639
|
import { createReadStream, existsSync as existsSync12, statSync as statSync6 } from "node:fs";
|
|
49398
|
-
import { join as
|
|
49640
|
+
import { join as join12 } from "node:path";
|
|
49399
49641
|
var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
|
|
49400
49642
|
var ENCODINGS = {
|
|
49401
49643
|
br: ".br",
|
|
@@ -49444,11 +49686,11 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
49444
49686
|
await options.onNotFound?.(c2.req.path, c2);
|
|
49445
49687
|
return next();
|
|
49446
49688
|
}
|
|
49447
|
-
let path =
|
|
49689
|
+
let path = join12(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c2) : filename);
|
|
49448
49690
|
let stats = getStats(path);
|
|
49449
49691
|
if (stats && stats.isDirectory()) {
|
|
49450
49692
|
const indexFile = options.index ?? "index.html";
|
|
49451
|
-
path =
|
|
49693
|
+
path = join12(path, indexFile);
|
|
49452
49694
|
stats = getStats(path);
|
|
49453
49695
|
}
|
|
49454
49696
|
if (!stats) {
|
|
@@ -49507,7 +49749,7 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
49507
49749
|
// src/web/server.ts
|
|
49508
49750
|
import { existsSync as existsSync15 } from "node:fs";
|
|
49509
49751
|
import { readFileSync as readFileSync14 } from "node:fs";
|
|
49510
|
-
import { join as
|
|
49752
|
+
import { join as join15 } from "node:path";
|
|
49511
49753
|
|
|
49512
49754
|
// ../../node_modules/.bun/hono@4.12.23/node_modules/hono/dist/compose.js
|
|
49513
49755
|
var compose = (middleware, onError, onNotFound) => {
|
|
@@ -51314,7 +51556,7 @@ function registerConfigRoutes(app, ctx) {
|
|
|
51314
51556
|
}
|
|
51315
51557
|
|
|
51316
51558
|
// src/web/routes/discovery.ts
|
|
51317
|
-
var
|
|
51559
|
+
var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
51318
51560
|
var DOC_COLS = "id, title, source, source_path, content_hash, metadata, chunk_count, total_chars, review_status, created_at, updated_at, deleted_at";
|
|
51319
51561
|
function jsonByteLength(value) {
|
|
51320
51562
|
return Buffer.byteLength(JSON.stringify(value), "utf8");
|
|
@@ -51760,7 +52002,7 @@ function registerDiscoveryRoutes(app, ctx) {
|
|
|
51760
52002
|
if (!path) {
|
|
51761
52003
|
return c2.json({ tried_path: "", anchor, matches: [] });
|
|
51762
52004
|
}
|
|
51763
|
-
if (
|
|
52005
|
+
if (UUID_RE2.test(path)) {
|
|
51764
52006
|
if (path === fromDocId) {
|
|
51765
52007
|
return c2.json({ tried_path: path, anchor, matches: [] });
|
|
51766
52008
|
}
|
|
@@ -52361,7 +52603,7 @@ import {
|
|
|
52361
52603
|
readdirSync as readdirSync7,
|
|
52362
52604
|
statSync as statSync7
|
|
52363
52605
|
} from "node:fs";
|
|
52364
|
-
import { basename as basename6, dirname as dirname5, join as
|
|
52606
|
+
import { basename as basename6, dirname as dirname5, join as join13, resolve as resolve5 } from "node:path";
|
|
52365
52607
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
52366
52608
|
var TOP_LEVEL_DOCS = [
|
|
52367
52609
|
{ filename: "README.md", path: "README.md", category: "readme" },
|
|
@@ -52382,27 +52624,27 @@ function moduleDir2() {
|
|
|
52382
52624
|
function resolveDocsRoots() {
|
|
52383
52625
|
const here = moduleDir2();
|
|
52384
52626
|
const pkgRootCandidates = [
|
|
52385
|
-
|
|
52386
|
-
|
|
52627
|
+
join13(here, "..", ".."),
|
|
52628
|
+
join13(here, "..", "..", "..", "..")
|
|
52387
52629
|
];
|
|
52388
52630
|
let pkgGuides = null;
|
|
52389
52631
|
let pkgTopLevel = null;
|
|
52390
52632
|
for (const pkg of pkgRootCandidates) {
|
|
52391
|
-
const guides =
|
|
52633
|
+
const guides = join13(pkg, "docs", "guides");
|
|
52392
52634
|
if (existsSync13(guides) && statSync7(guides).isDirectory()) {
|
|
52393
52635
|
pkgGuides = guides;
|
|
52394
52636
|
pkgTopLevel = pkg;
|
|
52395
52637
|
break;
|
|
52396
52638
|
}
|
|
52397
52639
|
}
|
|
52398
|
-
const repoCandidate =
|
|
52399
|
-
const repoGuides =
|
|
52640
|
+
const repoCandidate = join13(here, "..", "..", "..", "..");
|
|
52641
|
+
const repoGuides = join13(repoCandidate, "docs", "guides");
|
|
52400
52642
|
const repoTopLevel = repoCandidate;
|
|
52401
52643
|
return {
|
|
52402
52644
|
pkgGuides,
|
|
52403
52645
|
pkgTopLevel,
|
|
52404
52646
|
repoGuides: existsSync13(repoGuides) ? repoGuides : null,
|
|
52405
|
-
repoTopLevel: existsSync13(
|
|
52647
|
+
repoTopLevel: existsSync13(join13(repoTopLevel, "README.md")) ? repoTopLevel : null
|
|
52406
52648
|
};
|
|
52407
52649
|
}
|
|
52408
52650
|
function readH1(filePath) {
|
|
@@ -52427,7 +52669,7 @@ function listBundledDocs2() {
|
|
|
52427
52669
|
const topRoot = pkgTopLevel ?? repoTopLevel;
|
|
52428
52670
|
if (topRoot) {
|
|
52429
52671
|
for (const t of TOP_LEVEL_DOCS) {
|
|
52430
|
-
const abs =
|
|
52672
|
+
const abs = join13(topRoot, t.filename);
|
|
52431
52673
|
if (existsSync13(abs)) {
|
|
52432
52674
|
entries.push(entryForFile(abs, t.path, t.category));
|
|
52433
52675
|
}
|
|
@@ -52437,7 +52679,7 @@ function listBundledDocs2() {
|
|
|
52437
52679
|
if (guidesRoot) {
|
|
52438
52680
|
const names = readdirSync7(guidesRoot).filter((n) => n.endsWith(".md")).sort();
|
|
52439
52681
|
for (const name of names) {
|
|
52440
|
-
const abs =
|
|
52682
|
+
const abs = join13(guidesRoot, name);
|
|
52441
52683
|
entries.push(entryForFile(abs, `guides/${name}`, "guide"));
|
|
52442
52684
|
}
|
|
52443
52685
|
}
|
|
@@ -52482,7 +52724,7 @@ var VERSION_INFO = {
|
|
|
52482
52724
|
git_commit_short: resolveGitCommitShort(),
|
|
52483
52725
|
build_date: process.env.CEREFOX_BUILD_DATE ?? null
|
|
52484
52726
|
};
|
|
52485
|
-
var
|
|
52727
|
+
var SCHEMA_VERSION_RE2 = /^--\s*@version:\s*(\S+)/m;
|
|
52486
52728
|
function registerMetaRoutes(app, ctx) {
|
|
52487
52729
|
app.get("/api/v1/version", (c2) => c2.json(VERSION_INFO));
|
|
52488
52730
|
app.get("/api/v1/docs", (c2) => c2.json(listBundledDocs2()));
|
|
@@ -52501,16 +52743,16 @@ function registerMetaRoutes(app, ctx) {
|
|
|
52501
52743
|
try {
|
|
52502
52744
|
const { readFileSync: readFileSync14, existsSync: existsSync14 } = await import("node:fs");
|
|
52503
52745
|
const { fileURLToPath: fileURLToPath4 } = await import("node:url");
|
|
52504
|
-
const { dirname: dirname6, join:
|
|
52746
|
+
const { dirname: dirname6, join: join14 } = await import("node:path");
|
|
52505
52747
|
const here = dirname6(fileURLToPath4(import.meta.url));
|
|
52506
52748
|
const candidates = [
|
|
52507
|
-
|
|
52508
|
-
|
|
52749
|
+
join14(here, "..", "..", "..", "db", "schema.sql"),
|
|
52750
|
+
join14(here, "..", "..", "..", "..", "..", "src", "cerefox", "db", "schema.sql")
|
|
52509
52751
|
];
|
|
52510
52752
|
for (const path of candidates) {
|
|
52511
52753
|
if (existsSync14(path)) {
|
|
52512
52754
|
const sql = readFileSync14(path, "utf8");
|
|
52513
|
-
const match2 = sql.match(
|
|
52755
|
+
const match2 = sql.match(SCHEMA_VERSION_RE2);
|
|
52514
52756
|
bundled = match2 ? match2[1] : null;
|
|
52515
52757
|
break;
|
|
52516
52758
|
}
|
|
@@ -52620,20 +52862,20 @@ function registerProjectsRoutes(app, ctx) {
|
|
|
52620
52862
|
|
|
52621
52863
|
// src/web/static.ts
|
|
52622
52864
|
import { existsSync as existsSync14, statSync as statSync8 } from "node:fs";
|
|
52623
|
-
import { dirname as dirname6, join as
|
|
52865
|
+
import { dirname as dirname6, join as join14 } from "node:path";
|
|
52624
52866
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
52625
52867
|
function moduleDir3() {
|
|
52626
52868
|
return dirname6(fileURLToPath4(import.meta.url));
|
|
52627
52869
|
}
|
|
52628
52870
|
function isUsableSpaDir(dir) {
|
|
52629
|
-
return existsSync14(dir) && statSync8(dir).isDirectory() && existsSync14(
|
|
52871
|
+
return existsSync14(dir) && statSync8(dir).isDirectory() && existsSync14(join14(dir, "index.html"));
|
|
52630
52872
|
}
|
|
52631
52873
|
function resolveSpaDist() {
|
|
52632
52874
|
const here = moduleDir3();
|
|
52633
52875
|
const candidates = [
|
|
52634
|
-
|
|
52635
|
-
|
|
52636
|
-
|
|
52876
|
+
join14(here, "..", "frontend"),
|
|
52877
|
+
join14(here, "..", "..", "..", "..", "frontend", "dist"),
|
|
52878
|
+
join14(here, "..", "..", "dist", "frontend")
|
|
52637
52879
|
];
|
|
52638
52880
|
for (const c2 of candidates) {
|
|
52639
52881
|
if (isUsableSpaDir(c2))
|
|
@@ -52644,8 +52886,8 @@ function resolveSpaDist() {
|
|
|
52644
52886
|
function resolveStaticDir() {
|
|
52645
52887
|
const here = moduleDir3();
|
|
52646
52888
|
const candidates = [
|
|
52647
|
-
|
|
52648
|
-
|
|
52889
|
+
join14(here, "..", "static"),
|
|
52890
|
+
join14(here, "..", "..", "..", "..", "web", "static")
|
|
52649
52891
|
];
|
|
52650
52892
|
for (const c2 of candidates) {
|
|
52651
52893
|
if (existsSync14(c2) && statSync8(c2).isDirectory())
|
|
@@ -52691,11 +52933,12 @@ var ROOT_REDIRECT_HTML = `<!DOCTYPE html>
|
|
|
52691
52933
|
|
|
52692
52934
|
// src/web/server.ts
|
|
52693
52935
|
init_meta();
|
|
52936
|
+
init_cli_core();
|
|
52694
52937
|
init_config();
|
|
52695
52938
|
function buildApp(ctx = buildWebContext()) {
|
|
52696
52939
|
const app = new Hono2;
|
|
52697
52940
|
if (true) {
|
|
52698
|
-
app.use(logger());
|
|
52941
|
+
app.use(logger((message, ...rest) => console.log(`${localTimestamp()} ${message}`, ...rest)));
|
|
52699
52942
|
}
|
|
52700
52943
|
registerMetaRoutes(app, ctx);
|
|
52701
52944
|
if (ctx) {
|
|
@@ -52731,7 +52974,7 @@ function buildApp(ctx = buildWebContext()) {
|
|
|
52731
52974
|
root: spaDist,
|
|
52732
52975
|
rewriteRequestPath: (path) => path.replace(/^\/app/, "") || "/"
|
|
52733
52976
|
}));
|
|
52734
|
-
const indexPath =
|
|
52977
|
+
const indexPath = join15(spaDist, "index.html");
|
|
52735
52978
|
if (existsSync15(indexPath)) {
|
|
52736
52979
|
const indexHtml = readFileSync14(indexPath, "utf8");
|
|
52737
52980
|
app.get("/app/*", (c2) => c2.html(indexHtml));
|
|
@@ -52799,10 +53042,10 @@ import {
|
|
|
52799
53042
|
writeFileSync as writeFileSync4
|
|
52800
53043
|
} from "node:fs";
|
|
52801
53044
|
import { homedir as homedir7 } from "node:os";
|
|
52802
|
-
import { join as
|
|
52803
|
-
var STATE_DIR =
|
|
52804
|
-
var PID_FILE =
|
|
52805
|
-
var LOG_FILE =
|
|
53045
|
+
import { join as join16 } from "node:path";
|
|
53046
|
+
var STATE_DIR = join16(homedir7(), ".cerefox");
|
|
53047
|
+
var PID_FILE = join16(STATE_DIR, "web.pid");
|
|
53048
|
+
var LOG_FILE = join16(STATE_DIR, "web.log");
|
|
52806
53049
|
var daemonPaths = { stateDir: STATE_DIR, pidFile: PID_FILE, logFile: LOG_FILE };
|
|
52807
53050
|
function ensureStateDir() {
|
|
52808
53051
|
if (!existsSync16(STATE_DIR))
|
|
@@ -52950,11 +53193,11 @@ async function runForeground(host, port, watch) {
|
|
|
52950
53193
|
}
|
|
52951
53194
|
try {
|
|
52952
53195
|
const handle = await buildWebServer({ host, port });
|
|
52953
|
-
|
|
53196
|
+
println(`${localTimestamp()} Cerefox web listening on http://${handle.host}:${handle.port}/`);
|
|
52954
53197
|
println(` Web UI: http://${handle.host}:${handle.port}/app/`);
|
|
52955
53198
|
println(` API: http://${handle.host}:${handle.port}/api/v1/`);
|
|
52956
53199
|
const shutdown = async (signal) => {
|
|
52957
|
-
|
|
53200
|
+
println(`${localTimestamp()} Received ${signal}; shutting down.`);
|
|
52958
53201
|
await handle.close().catch(() => {});
|
|
52959
53202
|
process.exit(0);
|
|
52960
53203
|
};
|
|
@@ -53056,7 +53299,7 @@ function buildProgram() {
|
|
|
53056
53299
|
Command groups (each row in the list above falls into one):
|
|
53057
53300
|
` + ` READS search · get-doc · list-docs · list-versions · list-projects
|
|
53058
53301
|
` + ` · list-metadata-keys · metadata-search · get-audit-log
|
|
53059
|
-
` + ` WRITES ingest · ingest-dir · delete-doc
|
|
53302
|
+
` + ` WRITES ingest · ingest-dir · delete-doc · delete-project
|
|
53060
53303
|
` + ` SERVERS mcp · web
|
|
53061
53304
|
` + ` LIFECYCLE init · doctor · status · configure-agent · self-update · upgrade · sync-self-docs · deploy-server
|
|
53062
53305
|
` + ` OPS backup · restore · sync-docs · docs · reindex · config-get · config-set · completion
|
|
@@ -53081,6 +53324,7 @@ Learn more:
|
|
|
53081
53324
|
registerIngest(program2);
|
|
53082
53325
|
registerIngestDir(program2);
|
|
53083
53326
|
registerDeleteDoc(program2);
|
|
53327
|
+
registerDeleteProject(program2);
|
|
53084
53328
|
registerMcp(program2);
|
|
53085
53329
|
registerWeb(program2);
|
|
53086
53330
|
registerInit(program2);
|
|
@@ -133,6 +133,26 @@ change.
|
|
|
133
133
|
> make authenticated POST calls to the Edge Functions. The built-in local server is
|
|
134
134
|
> the correct solution.
|
|
135
135
|
|
|
136
|
+
### Fastest setup: `cerefox configure-agent`
|
|
137
|
+
|
|
138
|
+
You don't have to hand-edit the per-client config files below. `cerefox configure-agent
|
|
139
|
+
--tool <client>` writes the correct local-stdio entry (`npx -y --package=@cerefox/memory
|
|
140
|
+
cerefox mcp`) into the right config file for you. Supported clients:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
cerefox configure-agent --tool claude-code # ~/.claude.json (via `claude mcp add`)
|
|
144
|
+
cerefox configure-agent --tool claude-desktop # Claude Desktop config
|
|
145
|
+
cerefox configure-agent --tool cursor # ~/.cursor/mcp.json
|
|
146
|
+
cerefox configure-agent --tool codex # ~/.codex/config.toml
|
|
147
|
+
cerefox configure-agent --tool gemini # ~/.gemini/settings.json
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Useful flags: `--dry-run` (print the planned write without touching any file), `--json`
|
|
151
|
+
(machine-readable result), `--config-path <path>` (override the target file), `--no-backup`
|
|
152
|
+
(skip the `.pre-cerefox.bak` backup). The command is idempotent and backs up any existing
|
|
153
|
+
config before writing. The per-client sections below document the same entries for anyone
|
|
154
|
+
who prefers to edit by hand or needs the remote (`Path A-Remote`) HTTP transport instead.
|
|
155
|
+
|
|
136
156
|
### Path A MCP tools
|
|
137
157
|
|
|
138
158
|
Once configured, every Path A client has these tools:
|
|
@@ -49,14 +49,18 @@ Cerefox usage guidance.
|
|
|
49
49
|
# Run the commands that apply to your setup:
|
|
50
50
|
cerefox configure-agent --tool claude-code # Claude Code (~/.claude.json)
|
|
51
51
|
cerefox configure-agent --tool claude-desktop # Claude Desktop config
|
|
52
|
+
cerefox configure-agent --tool cursor # Cursor (~/.cursor/mcp.json)
|
|
53
|
+
cerefox configure-agent --tool codex # OpenAI Codex CLI (~/.codex/config.toml)
|
|
54
|
+
cerefox configure-agent --tool gemini # Gemini CLI (~/.gemini/settings.json)
|
|
52
55
|
```
|
|
53
56
|
|
|
54
57
|
Then restart your client:
|
|
55
58
|
- **Claude Code**: start a fresh session — running sessions cache the MCP tool list.
|
|
56
59
|
- **Claude Desktop**: Cmd+Q to fully quit, then relaunch.
|
|
60
|
+
- **Cursor / Codex CLI / Gemini CLI**: reload or restart the client/session.
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
All five writers configure the local stdio server. For the remote (Edge Function)
|
|
63
|
+
HTTP transport, or to edit configs by hand, see [`connect-agents.md`](connect-agents.md).
|
|
60
64
|
|
|
61
65
|
## 4. Try it
|
|
62
66
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cerefox/memory",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Cerefox — user-owned shared memory for AI agents. The local TypeScript runtime: stdio MCP server in v0.4; CLI binary added in v0.5; in-process web server in v0.6; ingestion pipeline in v0.7.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/fstamatelopoulos/cerefox",
|