@cerefox/memory 1.1.0-beta.2 → 1.1.0-beta.4
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 +243 -168
- package/dist/frontend/assets/index-BLqrpbNz.js +121 -0
- package/dist/frontend/assets/index-BLqrpbNz.js.map +1 -0
- package/dist/frontend/index.html +1 -1
- package/docs/guides/configuration.md +2 -1
- package/docs/guides/content-format.md +18 -0
- package/package.json +1 -1
- package/dist/frontend/assets/index-CMNl_LF9.js +0 -121
- package/dist/frontend/assets/index-CMNl_LF9.js.map +0 -1
package/dist/bin/cerefox.js
CHANGED
|
@@ -7438,9 +7438,143 @@ var exports_meta = {};
|
|
|
7438
7438
|
__export(exports_meta, {
|
|
7439
7439
|
PKG_VERSION: () => PKG_VERSION
|
|
7440
7440
|
});
|
|
7441
|
-
var PKG_VERSION = "1.1.0-beta.
|
|
7441
|
+
var PKG_VERSION = "1.1.0-beta.4";
|
|
7442
7442
|
var init_meta = () => {};
|
|
7443
7443
|
|
|
7444
|
+
// ../../_shared/config/paths.ts
|
|
7445
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
7446
|
+
import { homedir } from "node:os";
|
|
7447
|
+
import { join, resolve as resolvePath } from "node:path";
|
|
7448
|
+
import { cwd as processCwd, env } from "node:process";
|
|
7449
|
+
function expandTilde(p) {
|
|
7450
|
+
if (p === "~" || p.startsWith("~/")) {
|
|
7451
|
+
return join(homedir(), p.slice(2));
|
|
7452
|
+
}
|
|
7453
|
+
return p;
|
|
7454
|
+
}
|
|
7455
|
+
function userStateDirAbs(opts) {
|
|
7456
|
+
return resolvePath(join(opts.home ?? homedir(), USER_STATE_DIR_NAME));
|
|
7457
|
+
}
|
|
7458
|
+
function resolveConfigDir(opts = {}) {
|
|
7459
|
+
const override = (env.CEREFOX_CONFIG_DIR ?? "").trim();
|
|
7460
|
+
if (override) {
|
|
7461
|
+
return resolvePath(expandTilde(override));
|
|
7462
|
+
}
|
|
7463
|
+
const userState = userStateDirAbs(opts);
|
|
7464
|
+
if (existsSync(join(userState, ".env"))) {
|
|
7465
|
+
return userState;
|
|
7466
|
+
}
|
|
7467
|
+
const here = opts.cwd ?? processCwd();
|
|
7468
|
+
const cwdEnv = join(here, ".env");
|
|
7469
|
+
if (existsSync(cwdEnv) && cwdEnvHasCerefoxKey(cwdEnv)) {
|
|
7470
|
+
return resolvePath(here);
|
|
7471
|
+
}
|
|
7472
|
+
return userState;
|
|
7473
|
+
}
|
|
7474
|
+
function cwdEnvHasCerefoxKey(envPath) {
|
|
7475
|
+
try {
|
|
7476
|
+
const contents = readFileSync(envPath, "utf8");
|
|
7477
|
+
return /^\s*CEREFOX_[A-Z0-9_]+\s*=/m.test(contents);
|
|
7478
|
+
} catch {
|
|
7479
|
+
return false;
|
|
7480
|
+
}
|
|
7481
|
+
}
|
|
7482
|
+
function resolveEnvFile(opts = {}) {
|
|
7483
|
+
return join(resolveConfigDir(opts), ".env");
|
|
7484
|
+
}
|
|
7485
|
+
function userStateDir(opts = {}) {
|
|
7486
|
+
return userStateDirAbs(opts);
|
|
7487
|
+
}
|
|
7488
|
+
function isDevMode(opts = {}) {
|
|
7489
|
+
if ((env.CEREFOX_CONFIG_DIR ?? "").trim())
|
|
7490
|
+
return false;
|
|
7491
|
+
if (existsSync(join(userStateDirAbs(opts), ".env")))
|
|
7492
|
+
return false;
|
|
7493
|
+
const here = opts.cwd ?? processCwd();
|
|
7494
|
+
const cwdEnv = join(here, ".env");
|
|
7495
|
+
return existsSync(cwdEnv) && cwdEnvHasCerefoxKey(cwdEnv);
|
|
7496
|
+
}
|
|
7497
|
+
var USER_STATE_DIR_NAME = ".cerefox";
|
|
7498
|
+
var init_paths = () => {};
|
|
7499
|
+
|
|
7500
|
+
// ../../_shared/config/env.ts
|
|
7501
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
7502
|
+
import { env as env2 } from "node:process";
|
|
7503
|
+
function parseDotenv(content) {
|
|
7504
|
+
const result = {};
|
|
7505
|
+
for (const rawLine of content.split(/\r?\n/)) {
|
|
7506
|
+
const line = rawLine.trim();
|
|
7507
|
+
if (!line || line.startsWith("#"))
|
|
7508
|
+
continue;
|
|
7509
|
+
const match = line.match(KV_LINE);
|
|
7510
|
+
if (!match)
|
|
7511
|
+
continue;
|
|
7512
|
+
let value = match[2];
|
|
7513
|
+
if (value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
|
|
7514
|
+
value = value.slice(1, -1);
|
|
7515
|
+
}
|
|
7516
|
+
result[match[1]] = value;
|
|
7517
|
+
}
|
|
7518
|
+
return result;
|
|
7519
|
+
}
|
|
7520
|
+
function loadEnv(opts = {}) {
|
|
7521
|
+
if (_loaded) {
|
|
7522
|
+
return { path: "(already loaded)", vars: 0 };
|
|
7523
|
+
}
|
|
7524
|
+
_loaded = true;
|
|
7525
|
+
const envPath = resolveEnvFile(opts);
|
|
7526
|
+
let content;
|
|
7527
|
+
try {
|
|
7528
|
+
content = readFileSync2(envPath, "utf8");
|
|
7529
|
+
} catch {
|
|
7530
|
+
return { path: envPath, vars: 0 };
|
|
7531
|
+
}
|
|
7532
|
+
const configDirNamed = (env2.CEREFOX_CONFIG_DIR ?? "").trim() !== "";
|
|
7533
|
+
let count = 0;
|
|
7534
|
+
for (const [k, v] of Object.entries(parseDotenv(content))) {
|
|
7535
|
+
if (k === "CEREFOX_CONFIG_DIR")
|
|
7536
|
+
continue;
|
|
7537
|
+
if (env2[k] === undefined || configDirNamed) {
|
|
7538
|
+
env2[k] = v;
|
|
7539
|
+
count++;
|
|
7540
|
+
}
|
|
7541
|
+
}
|
|
7542
|
+
return { path: envPath, vars: count };
|
|
7543
|
+
}
|
|
7544
|
+
function loadSettings(opts = {}) {
|
|
7545
|
+
loadEnv(opts);
|
|
7546
|
+
return {
|
|
7547
|
+
supabaseUrl: env2.CEREFOX_SUPABASE_URL ?? "",
|
|
7548
|
+
supabaseKey: env2.CEREFOX_SUPABASE_KEY ?? "",
|
|
7549
|
+
supabaseAnonKey: env2.CEREFOX_SUPABASE_ANON_KEY ?? "",
|
|
7550
|
+
accessToken: env2.CEREFOX_ACCESS_TOKEN ?? "",
|
|
7551
|
+
databaseUrl: env2.CEREFOX_DATABASE_URL ?? "",
|
|
7552
|
+
openaiApiKey: env2.CEREFOX_OPENAI_API_KEY ?? env2.OPENAI_API_KEY ?? "",
|
|
7553
|
+
fireworksApiKey: env2.CEREFOX_FIREWORKS_API_KEY ?? ""
|
|
7554
|
+
};
|
|
7555
|
+
}
|
|
7556
|
+
var KV_LINE, _loaded = false;
|
|
7557
|
+
var init_env = __esm(() => {
|
|
7558
|
+
init_paths();
|
|
7559
|
+
KV_LINE = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/;
|
|
7560
|
+
});
|
|
7561
|
+
|
|
7562
|
+
// ../../_shared/config/index.ts
|
|
7563
|
+
var exports_config = {};
|
|
7564
|
+
__export(exports_config, {
|
|
7565
|
+
userStateDir: () => userStateDir,
|
|
7566
|
+
resolveEnvFile: () => resolveEnvFile,
|
|
7567
|
+
resolveConfigDir: () => resolveConfigDir,
|
|
7568
|
+
loadSettings: () => loadSettings,
|
|
7569
|
+
loadEnv: () => loadEnv,
|
|
7570
|
+
isDevMode: () => isDevMode,
|
|
7571
|
+
USER_STATE_DIR_NAME: () => USER_STATE_DIR_NAME
|
|
7572
|
+
});
|
|
7573
|
+
var init_config = __esm(() => {
|
|
7574
|
+
init_paths();
|
|
7575
|
+
init_env();
|
|
7576
|
+
});
|
|
7577
|
+
|
|
7444
7578
|
// ../../node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.js
|
|
7445
7579
|
var require_tslib = __commonJS((exports, module) => {
|
|
7446
7580
|
var __extends;
|
|
@@ -7935,7 +8069,7 @@ var require_tslib = __commonJS((exports, module) => {
|
|
|
7935
8069
|
throw new TypeError("Cannot use 'in' operator on non-object");
|
|
7936
8070
|
return typeof state === "function" ? receiver === state : state.has(receiver);
|
|
7937
8071
|
};
|
|
7938
|
-
__addDisposableResource = function(
|
|
8072
|
+
__addDisposableResource = function(env3, value, async) {
|
|
7939
8073
|
if (value !== null && value !== undefined) {
|
|
7940
8074
|
if (typeof value !== "object" && typeof value !== "function")
|
|
7941
8075
|
throw new TypeError("Object expected.");
|
|
@@ -7962,9 +8096,9 @@ var require_tslib = __commonJS((exports, module) => {
|
|
|
7962
8096
|
return Promise.reject(e);
|
|
7963
8097
|
}
|
|
7964
8098
|
};
|
|
7965
|
-
|
|
8099
|
+
env3.stack.push({ value, dispose, async });
|
|
7966
8100
|
} else if (async) {
|
|
7967
|
-
|
|
8101
|
+
env3.stack.push({ async: true });
|
|
7968
8102
|
}
|
|
7969
8103
|
return value;
|
|
7970
8104
|
};
|
|
@@ -7972,17 +8106,17 @@ var require_tslib = __commonJS((exports, module) => {
|
|
|
7972
8106
|
var e = new Error(message);
|
|
7973
8107
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
7974
8108
|
};
|
|
7975
|
-
__disposeResources = function(
|
|
8109
|
+
__disposeResources = function(env3) {
|
|
7976
8110
|
function fail(e) {
|
|
7977
|
-
|
|
7978
|
-
|
|
8111
|
+
env3.error = env3.hasError ? new _SuppressedError(e, env3.error, "An error was suppressed during disposal.") : e;
|
|
8112
|
+
env3.hasError = true;
|
|
7979
8113
|
}
|
|
7980
8114
|
var r, s = 0;
|
|
7981
8115
|
function next() {
|
|
7982
|
-
while (r =
|
|
8116
|
+
while (r = env3.stack.pop()) {
|
|
7983
8117
|
try {
|
|
7984
8118
|
if (!r.async && s === 1)
|
|
7985
|
-
return s = 0,
|
|
8119
|
+
return s = 0, env3.stack.push(r), Promise.resolve().then(next);
|
|
7986
8120
|
if (r.dispose) {
|
|
7987
8121
|
var result = r.dispose.call(r.value);
|
|
7988
8122
|
if (r.async)
|
|
@@ -7997,9 +8131,9 @@ var require_tslib = __commonJS((exports, module) => {
|
|
|
7997
8131
|
}
|
|
7998
8132
|
}
|
|
7999
8133
|
if (s === 1)
|
|
8000
|
-
return
|
|
8001
|
-
if (
|
|
8002
|
-
throw
|
|
8134
|
+
return env3.hasError ? Promise.reject(env3.error) : Promise.resolve();
|
|
8135
|
+
if (env3.hasError)
|
|
8136
|
+
throw env3.error;
|
|
8003
8137
|
}
|
|
8004
8138
|
return next();
|
|
8005
8139
|
};
|
|
@@ -9128,22 +9262,22 @@ var require_websocket_factory = __commonJS((exports) => {
|
|
|
9128
9262
|
};
|
|
9129
9263
|
}
|
|
9130
9264
|
static getWebSocketConstructor() {
|
|
9131
|
-
const
|
|
9132
|
-
if (
|
|
9133
|
-
return
|
|
9265
|
+
const env3 = this.detectEnvironment();
|
|
9266
|
+
if (env3.wsConstructor) {
|
|
9267
|
+
return env3.wsConstructor;
|
|
9134
9268
|
}
|
|
9135
|
-
let errorMessage =
|
|
9136
|
-
if (
|
|
9269
|
+
let errorMessage = env3.error || "WebSocket not supported in this environment.";
|
|
9270
|
+
if (env3.workaround) {
|
|
9137
9271
|
errorMessage += `
|
|
9138
9272
|
|
|
9139
|
-
Suggested solution: ${
|
|
9273
|
+
Suggested solution: ${env3.workaround}`;
|
|
9140
9274
|
}
|
|
9141
9275
|
throw new Error(errorMessage);
|
|
9142
9276
|
}
|
|
9143
9277
|
static isWebSocketSupported() {
|
|
9144
9278
|
try {
|
|
9145
|
-
const
|
|
9146
|
-
return
|
|
9279
|
+
const env3 = this.detectEnvironment();
|
|
9280
|
+
return env3.type === "native";
|
|
9147
9281
|
} catch (_a) {
|
|
9148
9282
|
return false;
|
|
9149
9283
|
}
|
|
@@ -11592,8 +11726,8 @@ var require_RealtimeChannel = __commonJS((exports) => {
|
|
|
11592
11726
|
});
|
|
11593
11727
|
}
|
|
11594
11728
|
_notThisChannelEvent(event, ref) {
|
|
11595
|
-
const { close, error, leave, join } = constants_1.CHANNEL_EVENTS;
|
|
11596
|
-
const events = [close, error, leave,
|
|
11729
|
+
const { close, error, leave, join: join2 } = constants_1.CHANNEL_EVENTS;
|
|
11730
|
+
const events = [close, error, leave, join2];
|
|
11597
11731
|
return ref && events.includes(event) && ref !== this.joinPush.ref;
|
|
11598
11732
|
}
|
|
11599
11733
|
_updateFilterTransform() {
|
|
@@ -23274,140 +23408,6 @@ var init_db_client = __esm(() => {
|
|
|
23274
23408
|
});
|
|
23275
23409
|
});
|
|
23276
23410
|
|
|
23277
|
-
// ../../_shared/config/paths.ts
|
|
23278
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
23279
|
-
import { homedir } from "node:os";
|
|
23280
|
-
import { join, resolve as resolvePath } from "node:path";
|
|
23281
|
-
import { cwd as processCwd, env } from "node:process";
|
|
23282
|
-
function expandTilde(p) {
|
|
23283
|
-
if (p === "~" || p.startsWith("~/")) {
|
|
23284
|
-
return join(homedir(), p.slice(2));
|
|
23285
|
-
}
|
|
23286
|
-
return p;
|
|
23287
|
-
}
|
|
23288
|
-
function userStateDirAbs(opts) {
|
|
23289
|
-
return resolvePath(join(opts.home ?? homedir(), USER_STATE_DIR_NAME));
|
|
23290
|
-
}
|
|
23291
|
-
function resolveConfigDir(opts = {}) {
|
|
23292
|
-
const override = (env.CEREFOX_CONFIG_DIR ?? "").trim();
|
|
23293
|
-
if (override) {
|
|
23294
|
-
return resolvePath(expandTilde(override));
|
|
23295
|
-
}
|
|
23296
|
-
const userState = userStateDirAbs(opts);
|
|
23297
|
-
if (existsSync(join(userState, ".env"))) {
|
|
23298
|
-
return userState;
|
|
23299
|
-
}
|
|
23300
|
-
const here = opts.cwd ?? processCwd();
|
|
23301
|
-
const cwdEnv = join(here, ".env");
|
|
23302
|
-
if (existsSync(cwdEnv) && cwdEnvHasCerefoxKey(cwdEnv)) {
|
|
23303
|
-
return resolvePath(here);
|
|
23304
|
-
}
|
|
23305
|
-
return userState;
|
|
23306
|
-
}
|
|
23307
|
-
function cwdEnvHasCerefoxKey(envPath) {
|
|
23308
|
-
try {
|
|
23309
|
-
const contents = readFileSync(envPath, "utf8");
|
|
23310
|
-
return /^\s*CEREFOX_[A-Z0-9_]+\s*=/m.test(contents);
|
|
23311
|
-
} catch {
|
|
23312
|
-
return false;
|
|
23313
|
-
}
|
|
23314
|
-
}
|
|
23315
|
-
function resolveEnvFile(opts = {}) {
|
|
23316
|
-
return join(resolveConfigDir(opts), ".env");
|
|
23317
|
-
}
|
|
23318
|
-
function userStateDir(opts = {}) {
|
|
23319
|
-
return userStateDirAbs(opts);
|
|
23320
|
-
}
|
|
23321
|
-
function isDevMode(opts = {}) {
|
|
23322
|
-
if ((env.CEREFOX_CONFIG_DIR ?? "").trim())
|
|
23323
|
-
return false;
|
|
23324
|
-
if (existsSync(join(userStateDirAbs(opts), ".env")))
|
|
23325
|
-
return false;
|
|
23326
|
-
const here = opts.cwd ?? processCwd();
|
|
23327
|
-
const cwdEnv = join(here, ".env");
|
|
23328
|
-
return existsSync(cwdEnv) && cwdEnvHasCerefoxKey(cwdEnv);
|
|
23329
|
-
}
|
|
23330
|
-
var USER_STATE_DIR_NAME = ".cerefox";
|
|
23331
|
-
var init_paths = () => {};
|
|
23332
|
-
|
|
23333
|
-
// ../../_shared/config/env.ts
|
|
23334
|
-
import { readFileSync as readFileSync2 } from "node:fs";
|
|
23335
|
-
import { env as env2 } from "node:process";
|
|
23336
|
-
function parseDotenv(content) {
|
|
23337
|
-
const result = {};
|
|
23338
|
-
for (const rawLine of content.split(/\r?\n/)) {
|
|
23339
|
-
const line = rawLine.trim();
|
|
23340
|
-
if (!line || line.startsWith("#"))
|
|
23341
|
-
continue;
|
|
23342
|
-
const match = line.match(KV_LINE);
|
|
23343
|
-
if (!match)
|
|
23344
|
-
continue;
|
|
23345
|
-
let value = match[2];
|
|
23346
|
-
if (value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
|
|
23347
|
-
value = value.slice(1, -1);
|
|
23348
|
-
}
|
|
23349
|
-
result[match[1]] = value;
|
|
23350
|
-
}
|
|
23351
|
-
return result;
|
|
23352
|
-
}
|
|
23353
|
-
function loadEnv(opts = {}) {
|
|
23354
|
-
if (_loaded) {
|
|
23355
|
-
return { path: "(already loaded)", vars: 0 };
|
|
23356
|
-
}
|
|
23357
|
-
_loaded = true;
|
|
23358
|
-
const envPath = resolveEnvFile(opts);
|
|
23359
|
-
let content;
|
|
23360
|
-
try {
|
|
23361
|
-
content = readFileSync2(envPath, "utf8");
|
|
23362
|
-
} catch {
|
|
23363
|
-
return { path: envPath, vars: 0 };
|
|
23364
|
-
}
|
|
23365
|
-
const configDirNamed = (env2.CEREFOX_CONFIG_DIR ?? "").trim() !== "";
|
|
23366
|
-
let count = 0;
|
|
23367
|
-
for (const [k, v] of Object.entries(parseDotenv(content))) {
|
|
23368
|
-
if (k === "CEREFOX_CONFIG_DIR")
|
|
23369
|
-
continue;
|
|
23370
|
-
if (env2[k] === undefined || configDirNamed) {
|
|
23371
|
-
env2[k] = v;
|
|
23372
|
-
count++;
|
|
23373
|
-
}
|
|
23374
|
-
}
|
|
23375
|
-
return { path: envPath, vars: count };
|
|
23376
|
-
}
|
|
23377
|
-
function loadSettings(opts = {}) {
|
|
23378
|
-
loadEnv(opts);
|
|
23379
|
-
return {
|
|
23380
|
-
supabaseUrl: env2.CEREFOX_SUPABASE_URL ?? "",
|
|
23381
|
-
supabaseKey: env2.CEREFOX_SUPABASE_KEY ?? "",
|
|
23382
|
-
supabaseAnonKey: env2.CEREFOX_SUPABASE_ANON_KEY ?? "",
|
|
23383
|
-
accessToken: env2.CEREFOX_ACCESS_TOKEN ?? "",
|
|
23384
|
-
databaseUrl: env2.CEREFOX_DATABASE_URL ?? "",
|
|
23385
|
-
openaiApiKey: env2.CEREFOX_OPENAI_API_KEY ?? env2.OPENAI_API_KEY ?? "",
|
|
23386
|
-
fireworksApiKey: env2.CEREFOX_FIREWORKS_API_KEY ?? ""
|
|
23387
|
-
};
|
|
23388
|
-
}
|
|
23389
|
-
var KV_LINE, _loaded = false;
|
|
23390
|
-
var init_env = __esm(() => {
|
|
23391
|
-
init_paths();
|
|
23392
|
-
KV_LINE = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/;
|
|
23393
|
-
});
|
|
23394
|
-
|
|
23395
|
-
// ../../_shared/config/index.ts
|
|
23396
|
-
var exports_config = {};
|
|
23397
|
-
__export(exports_config, {
|
|
23398
|
-
userStateDir: () => userStateDir,
|
|
23399
|
-
resolveEnvFile: () => resolveEnvFile,
|
|
23400
|
-
resolveConfigDir: () => resolveConfigDir,
|
|
23401
|
-
loadSettings: () => loadSettings,
|
|
23402
|
-
loadEnv: () => loadEnv,
|
|
23403
|
-
isDevMode: () => isDevMode,
|
|
23404
|
-
USER_STATE_DIR_NAME: () => USER_STATE_DIR_NAME
|
|
23405
|
-
});
|
|
23406
|
-
var init_config = __esm(() => {
|
|
23407
|
-
init_paths();
|
|
23408
|
-
init_env();
|
|
23409
|
-
});
|
|
23410
|
-
|
|
23411
23411
|
// src/cli/util/client.ts
|
|
23412
23412
|
function getClient() {
|
|
23413
23413
|
const settings = loadSettings();
|
|
@@ -69592,6 +69592,7 @@ init_cli_core();
|
|
|
69592
69592
|
|
|
69593
69593
|
// src/cli/commands/backup.ts
|
|
69594
69594
|
init_cli_core();
|
|
69595
|
+
init_config();
|
|
69595
69596
|
import { existsSync as existsSync2, mkdirSync, writeFileSync } from "node:fs";
|
|
69596
69597
|
import { homedir as homedir2 } from "node:os";
|
|
69597
69598
|
import { join as join2, resolve } from "node:path";
|
|
@@ -69635,6 +69636,7 @@ function utcStamp() {
|
|
|
69635
69636
|
return d.getUTCFullYear().toString() + pad(d.getUTCMonth() + 1) + pad(d.getUTCDate()) + "T" + pad(d.getUTCHours()) + pad(d.getUTCMinutes()) + pad(d.getUTCSeconds()) + "Z";
|
|
69636
69637
|
}
|
|
69637
69638
|
async function action(options) {
|
|
69639
|
+
loadEnv();
|
|
69638
69640
|
const configuredDir = options.outputDir ?? process.env.CEREFOX_BACKUP_DIR;
|
|
69639
69641
|
const outDir = resolve(expandHome(configuredDir ?? "~/.cerefox/backups"));
|
|
69640
69642
|
if (configuredDir !== undefined && !configuredDir.startsWith("/") && !configuredDir.startsWith("~")) {
|
|
@@ -69644,8 +69646,9 @@ async function action(options) {
|
|
|
69644
69646
|
}
|
|
69645
69647
|
if (!existsSync2(outDir))
|
|
69646
69648
|
mkdirSync(outDir, { recursive: true });
|
|
69649
|
+
const envLabel = (process.env.CEREFOX_ENV_LABEL ?? "").trim().replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
69647
69650
|
const stamp = utcStamp();
|
|
69648
|
-
const filename = `cerefox-${
|
|
69651
|
+
const filename = `cerefox-${envLabel ? envLabel + "-" : ""}${stamp}` + `${options.label ? "-" + options.label : ""}.json`;
|
|
69649
69652
|
const dest = join2(outDir, filename);
|
|
69650
69653
|
const client = getClient();
|
|
69651
69654
|
let schemaVersion = "unknown";
|
|
@@ -69725,6 +69728,7 @@ async function action(options) {
|
|
|
69725
69728
|
document_count: docs.length,
|
|
69726
69729
|
trashed_count: trashedCount,
|
|
69727
69730
|
includes_trash: includeTrash,
|
|
69731
|
+
env_label: envLabel || null,
|
|
69728
69732
|
includes_lifecycle_status: lifecycleCaptured,
|
|
69729
69733
|
chunk_count: chunkTotal,
|
|
69730
69734
|
project_count: projects.length,
|
|
@@ -76226,7 +76230,8 @@ async function action15(options) {
|
|
|
76226
76230
|
if (options.json) {
|
|
76227
76231
|
printJson(results);
|
|
76228
76232
|
} else {
|
|
76229
|
-
|
|
76233
|
+
const envLabel = (process.env.CEREFOX_ENV_LABEL ?? "").trim();
|
|
76234
|
+
println(envLabel ? `Cerefox doctor ${c.yellow(`[${envLabel.toUpperCase()}]`)}` : "Cerefox doctor");
|
|
76230
76235
|
println("");
|
|
76231
76236
|
const nameWidth = Math.max(...results.map((r) => r.name.length));
|
|
76232
76237
|
for (const r of results) {
|
|
@@ -76788,7 +76793,8 @@ class IngestionPipeline {
|
|
|
76788
76793
|
author = "unknown",
|
|
76789
76794
|
authorType = "user",
|
|
76790
76795
|
expectedContentHash,
|
|
76791
|
-
lastWriteWins = false
|
|
76796
|
+
lastWriteWins = false,
|
|
76797
|
+
forceRechunk = false
|
|
76792
76798
|
} = opts;
|
|
76793
76799
|
const listFormProvided = projectIds !== undefined && projectIds !== null || projectNames !== undefined && projectNames !== null;
|
|
76794
76800
|
const getOrCreate = (name) => this.db.getOrCreateProject(name);
|
|
@@ -76811,7 +76817,8 @@ class IngestionPipeline {
|
|
|
76811
76817
|
author,
|
|
76812
76818
|
authorType,
|
|
76813
76819
|
expectedContentHash,
|
|
76814
|
-
lastWriteWins
|
|
76820
|
+
lastWriteWins,
|
|
76821
|
+
forceRechunk
|
|
76815
76822
|
});
|
|
76816
76823
|
if (!listFormProvided && (projectId || projectName)) {
|
|
76817
76824
|
const singular = await resolveProjectIds({ projectId, projectName }, getOrCreate);
|
|
@@ -76936,7 +76943,8 @@ class IngestionPipeline {
|
|
|
76936
76943
|
author = "unknown",
|
|
76937
76944
|
authorType = "user",
|
|
76938
76945
|
expectedContentHash,
|
|
76939
|
-
lastWriteWins = false
|
|
76946
|
+
lastWriteWins = false,
|
|
76947
|
+
forceRechunk = false
|
|
76940
76948
|
} = opts;
|
|
76941
76949
|
const existing = await this.db.getDocumentById(documentId);
|
|
76942
76950
|
if (!existing) {
|
|
@@ -76961,7 +76969,7 @@ class IngestionPipeline {
|
|
|
76961
76969
|
}
|
|
76962
76970
|
const actualChunks = await this.db.listChunksForDocument(documentId);
|
|
76963
76971
|
const hasChunks = actualChunks.length > 0;
|
|
76964
|
-
if (contentUnchanged && hasChunks) {
|
|
76972
|
+
if (contentUnchanged && hasChunks && !forceRechunk) {
|
|
76965
76973
|
const oldTitle = existing.title ?? "";
|
|
76966
76974
|
const titleChanged = oldTitle !== title;
|
|
76967
76975
|
const updates = { title };
|
|
@@ -77048,7 +77056,7 @@ class IngestionPipeline {
|
|
|
77048
77056
|
sourceLabel: source,
|
|
77049
77057
|
retentionHours: this.settings.versionRetentionHours,
|
|
77050
77058
|
cleanupEnabled: this.settings.versionCleanupEnabled,
|
|
77051
|
-
expectedContentHash: expectedContentHash ?? null,
|
|
77059
|
+
expectedContentHash: expectedContentHash ?? (forceRechunk && contentUnchanged ? existing.content_hash : null),
|
|
77052
77060
|
lastWriteWins
|
|
77053
77061
|
});
|
|
77054
77062
|
let finalProjectIds;
|
|
@@ -78027,6 +78035,25 @@ function registerMetadataSearch(program2) {
|
|
|
78027
78035
|
init_dist4();
|
|
78028
78036
|
init_cli_core();
|
|
78029
78037
|
init_config();
|
|
78038
|
+
|
|
78039
|
+
// src/cli/util/bulk-write-warning.ts
|
|
78040
|
+
init_cli_core();
|
|
78041
|
+
function warnLargeBulkWrite(opts) {
|
|
78042
|
+
if (opts.count < opts.threshold)
|
|
78043
|
+
return false;
|
|
78044
|
+
println("");
|
|
78045
|
+
println(c.yellow("⚠ ") + `${opts.count.toLocaleString()} ${opts.unit}(s) is a large bulk rewrite.`);
|
|
78046
|
+
println(c.dim(` On Supabase (especially the free tier and small compute add-ons) this can
|
|
78047
|
+
` + ` deplete the project's Disk IO Budget. Symptoms: slower responses, CPU
|
|
78048
|
+
` + ` climbing on IO wait, and in the worst case a briefly unresponsive
|
|
78049
|
+
` + " instance. It recovers on its own once the budget refills."));
|
|
78050
|
+
println(c.dim(` Gentler: ${opts.batchHint}, leaving time between runs and ideally
|
|
78051
|
+
` + " picking a quiet period. The work is resumable — re-run to continue."));
|
|
78052
|
+
println("");
|
|
78053
|
+
return true;
|
|
78054
|
+
}
|
|
78055
|
+
|
|
78056
|
+
// src/cli/commands/reindex.ts
|
|
78030
78057
|
async function action27(options) {
|
|
78031
78058
|
const settings = loadSettings();
|
|
78032
78059
|
if (!settings.supabaseUrl || !settings.supabaseKey) {
|
|
@@ -78065,6 +78092,12 @@ async function action27(options) {
|
|
|
78065
78092
|
return;
|
|
78066
78093
|
}
|
|
78067
78094
|
println(c.bold(`Reindexing ${chunks.length} chunk(s) ${reindexAll ? "(--all)" : "(stale only)"}${dryRun ? " — DRY RUN" : ""}`));
|
|
78095
|
+
warnLargeBulkWrite({
|
|
78096
|
+
count: chunks.length,
|
|
78097
|
+
threshold: 1000,
|
|
78098
|
+
unit: "chunk",
|
|
78099
|
+
batchHint: "reindex in stages with --document-id"
|
|
78100
|
+
});
|
|
78068
78101
|
if (dryRun) {
|
|
78069
78102
|
const byDoc = new Map;
|
|
78070
78103
|
for (const ch of chunks)
|
|
@@ -78134,7 +78167,16 @@ async function action28(options) {
|
|
|
78134
78167
|
} catch (err) {
|
|
78135
78168
|
throw systemError(`Could not list legacy chunks: ${err instanceof Error ? err.message : String(err)}`);
|
|
78136
78169
|
}
|
|
78137
|
-
|
|
78170
|
+
let liveIds = new Set;
|
|
78171
|
+
try {
|
|
78172
|
+
const liveRows = await fetchAllPages((from, to) => supabase.from("cerefox_documents").select("id").is("deleted_at", null).order("id", { ascending: true }).range(from, to));
|
|
78173
|
+
liveIds = new Set(liveRows.map((r) => r.id));
|
|
78174
|
+
} catch (err) {
|
|
78175
|
+
throw systemError(`Could not list documents: ${err instanceof Error ? err.message : String(err)}`);
|
|
78176
|
+
}
|
|
78177
|
+
const allLegacy = [...new Set(legacyChunkRows.map((r) => r.document_id))];
|
|
78178
|
+
const docIds = allLegacy.filter((id) => liveIds.has(id));
|
|
78179
|
+
const trashedSkipped = allLegacy.length - docIds.length;
|
|
78138
78180
|
const limit = options.limit ? parsePositiveInt(options.limit, "--limit", docIds.length) : docIds.length;
|
|
78139
78181
|
const targets = docIds.slice(0, limit);
|
|
78140
78182
|
if (targets.length === 0) {
|
|
@@ -78142,6 +78184,15 @@ async function action28(options) {
|
|
|
78142
78184
|
return;
|
|
78143
78185
|
}
|
|
78144
78186
|
println(c.bold(`${docIds.length} document(s) on the legacy format` + (targets.length < docIds.length ? `; converting ${targets.length} (--limit)` : "")));
|
|
78187
|
+
if (trashedSkipped > 0) {
|
|
78188
|
+
println(c.dim(` (${trashedSkipped} trashed document(s) on the legacy format ignored)`));
|
|
78189
|
+
}
|
|
78190
|
+
warnLargeBulkWrite({
|
|
78191
|
+
count: targets.length,
|
|
78192
|
+
threshold: 500,
|
|
78193
|
+
unit: "document",
|
|
78194
|
+
batchHint: "run it in batches with --limit 200"
|
|
78195
|
+
});
|
|
78145
78196
|
if (options.dryRun) {
|
|
78146
78197
|
println(c.yellow("⚠ --dry-run: nothing was written."));
|
|
78147
78198
|
println(c.dim(" Each document would be re-chunked and RE-EMBEDDED (embedding spend)."));
|
|
@@ -78177,16 +78228,24 @@ async function action28(options) {
|
|
|
78177
78228
|
continue;
|
|
78178
78229
|
}
|
|
78179
78230
|
try {
|
|
78180
|
-
await pipeline2.ingestText({
|
|
78231
|
+
const result = await pipeline2.ingestText({
|
|
78181
78232
|
text: doc2.full_content,
|
|
78182
78233
|
title: doc2.doc_title,
|
|
78183
78234
|
documentId: id,
|
|
78184
78235
|
source: "migrate-format",
|
|
78185
78236
|
author,
|
|
78186
78237
|
authorType,
|
|
78187
|
-
expectedContentHash: doc2.content_hash
|
|
78238
|
+
expectedContentHash: doc2.content_hash,
|
|
78239
|
+
forceRechunk: true
|
|
78188
78240
|
});
|
|
78189
|
-
|
|
78241
|
+
if (result.reindexed) {
|
|
78242
|
+
converted++;
|
|
78243
|
+
} else {
|
|
78244
|
+
failures.push({
|
|
78245
|
+
document: `${doc2.doc_title} (${id})`,
|
|
78246
|
+
reason: `pipeline reported no re-chunk (action=${result.action}); format not advanced`
|
|
78247
|
+
});
|
|
78248
|
+
}
|
|
78190
78249
|
} catch (err) {
|
|
78191
78250
|
const message = err instanceof Error ? err.message : String(err);
|
|
78192
78251
|
if (/conflict/i.test(message)) {
|
|
@@ -78268,6 +78327,13 @@ async function action29(target, options) {
|
|
|
78268
78327
|
} else {
|
|
78269
78328
|
warn("This backup predates project-membership capture (format 1) — documents " + "will be restored WITHOUT their project assignments.");
|
|
78270
78329
|
}
|
|
78330
|
+
{
|
|
78331
|
+
const fileEnv = (payload.env_label ?? "").trim();
|
|
78332
|
+
const targetEnv = (process.env.CEREFOX_ENV_LABEL ?? "").trim();
|
|
78333
|
+
if (fileEnv !== targetEnv) {
|
|
78334
|
+
warn(`This snapshot came from ${fileEnv ? `the "${fileEnv}" environment` : "an unlabelled (production) environment"}, ` + `but you are restoring into ${targetEnv ? `"${targetEnv}"` : "an unlabelled (production) environment"}.`);
|
|
78335
|
+
}
|
|
78336
|
+
}
|
|
78271
78337
|
const trashedInFile = payload.documents.filter((d) => d.deleted_at != null).length;
|
|
78272
78338
|
if (trashedInFile > 0) {
|
|
78273
78339
|
println(c.dim(` trashed documents in file: ${trashedInFile} — restored as trash ` + "(still deleted; recover with `cerefox document restore`)"));
|
|
@@ -83600,7 +83666,10 @@ var VERSION_INFO = {
|
|
|
83600
83666
|
};
|
|
83601
83667
|
var SCHEMA_VERSION_RE3 = /^--\s*@version:\s*(\S+)/m;
|
|
83602
83668
|
function registerMetaRoutes(app, ctx) {
|
|
83603
|
-
app.get("/api/v1/version", (c2) =>
|
|
83669
|
+
app.get("/api/v1/version", (c2) => {
|
|
83670
|
+
const label = (process.env.CEREFOX_ENV_LABEL ?? "").trim();
|
|
83671
|
+
return c2.json({ ...VERSION_INFO, env_label: label.length > 0 ? label : null });
|
|
83672
|
+
});
|
|
83604
83673
|
app.get("/api/v1/docs", (c2) => c2.json(listBundledDocs2()));
|
|
83605
83674
|
app.get("/api/v1/docs/:path{.+}", (c2) => {
|
|
83606
83675
|
const docPath = c2.req.param("path");
|
|
@@ -84426,6 +84495,12 @@ async function bareEntryPoint() {
|
|
|
84426
84495
|
}
|
|
84427
84496
|
}
|
|
84428
84497
|
async function main() {
|
|
84498
|
+
{
|
|
84499
|
+
const { loadEnv: loadEnv2 } = await Promise.resolve().then(() => (init_config(), exports_config));
|
|
84500
|
+
try {
|
|
84501
|
+
loadEnv2();
|
|
84502
|
+
} catch {}
|
|
84503
|
+
}
|
|
84429
84504
|
if (process.argv.length === 2) {
|
|
84430
84505
|
await bareEntryPoint();
|
|
84431
84506
|
return;
|