@cleocode/core 2026.6.3 → 2026.6.5
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/docs/export-document.js +626 -310
- package/dist/docs/export-document.js.map +3 -3
- package/dist/llm/catalog-cache.d.ts +3 -0
- package/dist/llm/catalog-cache.d.ts.map +1 -1
- package/dist/llm/catalog-cache.js.map +1 -1
- package/dist/llm/catalog-model-resolver.d.ts +89 -0
- package/dist/llm/catalog-model-resolver.d.ts.map +1 -0
- package/dist/llm/catalog-model-resolver.js +158 -0
- package/dist/llm/catalog-model-resolver.js.map +1 -0
- package/dist/llm/cli-ops.d.ts +14 -0
- package/dist/llm/cli-ops.d.ts.map +1 -1
- package/dist/llm/cli-ops.js +35 -0
- package/dist/llm/cli-ops.js.map +1 -1
- package/dist/llm/index.d.ts +3 -0
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +3 -0
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/oauth/pkce.js +27 -5
- package/dist/llm/oauth/pkce.js.map +1 -1
- package/dist/llm/plugin-facade.js +613 -325
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/llm/provider-registry/builtin/openai.d.ts +11 -2
- package/dist/llm/provider-registry/builtin/openai.d.ts.map +1 -1
- package/dist/llm/provider-registry/builtin/openai.js +15 -3
- package/dist/llm/provider-registry/builtin/openai.js.map +1 -1
- package/dist/llm/system-resolver.d.ts +94 -0
- package/dist/llm/system-resolver.d.ts.map +1 -0
- package/dist/llm/system-resolver.js +165 -0
- package/dist/llm/system-resolver.js.map +1 -0
- package/dist/memory/dialectic-evaluator.d.ts +13 -6
- package/dist/memory/dialectic-evaluator.d.ts.map +1 -1
- package/dist/memory/dialectic-evaluator.js +18 -7
- package/dist/memory/dialectic-evaluator.js.map +1 -1
- package/dist/memory/llm-backend-resolver.d.ts +23 -3
- package/dist/memory/llm-backend-resolver.d.ts.map +1 -1
- package/dist/memory/llm-backend-resolver.js +135 -0
- package/dist/memory/llm-backend-resolver.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +20 -2
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +74 -7
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/archive.d.ts +216 -0
- package/dist/store/exodus/archive.d.ts.map +1 -0
- package/dist/store/exodus/archive.js +314 -0
- package/dist/store/exodus/archive.js.map +1 -0
- package/dist/store/exodus/index.d.ts +1 -0
- package/dist/store/exodus/index.d.ts.map +1 -1
- package/dist/store/exodus/index.js +1 -0
- package/dist/store/exodus/index.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +118 -24
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts.map +1 -1
- package/dist/store/exodus/on-open.js +95 -34
- package/dist/store/exodus/on-open.js.map +1 -1
- package/dist/store/exodus/types.d.ts +10 -1
- package/dist/store/exodus/types.d.ts.map +1 -1
- package/dist/store/exodus/types.js.map +1 -1
- package/dist/store/exodus/verify-migration.d.ts.map +1 -1
- package/dist/store/exodus/verify-migration.js +12 -1
- package/dist/store/exodus/verify-migration.js.map +1 -1
- package/dist/store/sqlite.d.ts +16 -0
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +160 -39
- package/dist/store/sqlite.js.map +1 -1
- package/dist/validation/doctor/checks.d.ts +22 -0
- package/dist/validation/doctor/checks.d.ts.map +1 -1
- package/dist/validation/doctor/checks.js +67 -0
- package/dist/validation/doctor/checks.js.map +1 -1
- package/dist/validation/doctor/index.d.ts +1 -1
- package/dist/validation/doctor/index.d.ts.map +1 -1
- package/dist/validation/doctor/index.js +1 -1
- package/dist/validation/doctor/index.js.map +1 -1
- package/package.json +12 -12
|
@@ -10652,6 +10652,13 @@ var init_plugin_llm = __esm({
|
|
|
10652
10652
|
}
|
|
10653
10653
|
});
|
|
10654
10654
|
|
|
10655
|
+
// packages/contracts/src/llm/system-resolver.ts
|
|
10656
|
+
var init_system_resolver = __esm({
|
|
10657
|
+
"packages/contracts/src/llm/system-resolver.ts"() {
|
|
10658
|
+
"use strict";
|
|
10659
|
+
}
|
|
10660
|
+
});
|
|
10661
|
+
|
|
10655
10662
|
// packages/contracts/src/memory/observe.ts
|
|
10656
10663
|
var BRAIN_OBSERVATION_SOURCE_TYPES;
|
|
10657
10664
|
var init_observe = __esm({
|
|
@@ -12576,6 +12583,7 @@ var init_src = __esm({
|
|
|
12576
12583
|
init_invariants();
|
|
12577
12584
|
init_lafs();
|
|
12578
12585
|
init_plugin_llm();
|
|
12586
|
+
init_system_resolver();
|
|
12579
12587
|
init_observe();
|
|
12580
12588
|
init_migration_parity();
|
|
12581
12589
|
init_mvi();
|
|
@@ -14523,7 +14531,7 @@ var init_sql = __esm({
|
|
|
14523
14531
|
return new SQL([new StringChunk(str)]);
|
|
14524
14532
|
}
|
|
14525
14533
|
_sql.raw = raw;
|
|
14526
|
-
function
|
|
14534
|
+
function join27(chunks, separator) {
|
|
14527
14535
|
const result = [];
|
|
14528
14536
|
for (const [i, chunk] of chunks.entries()) {
|
|
14529
14537
|
if (i > 0 && separator !== void 0) result.push(separator);
|
|
@@ -14531,7 +14539,7 @@ var init_sql = __esm({
|
|
|
14531
14539
|
}
|
|
14532
14540
|
return new SQL(result);
|
|
14533
14541
|
}
|
|
14534
|
-
_sql.join =
|
|
14542
|
+
_sql.join = join27;
|
|
14535
14543
|
function identifier(value) {
|
|
14536
14544
|
return new Name(value);
|
|
14537
14545
|
}
|
|
@@ -16918,7 +16926,7 @@ var init_select2 = __esm({
|
|
|
16918
16926
|
const baseTableName = this.tableName;
|
|
16919
16927
|
const tableName = getTableLikeName(table);
|
|
16920
16928
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
16921
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
16929
|
+
if (typeof tableName === "string" && this.config.joins?.some((join27) => join27.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
16922
16930
|
if (!this.isPartialSelect) {
|
|
16923
16931
|
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
|
|
16924
16932
|
if (typeof tableName === "string" && !is(table, SQL)) {
|
|
@@ -20728,7 +20736,7 @@ var init_dialect = __esm({
|
|
|
20728
20736
|
if (!joins2) return;
|
|
20729
20737
|
const withEntries = Object.entries(joins2).filter(([_, v]) => v);
|
|
20730
20738
|
if (!withEntries.length) return;
|
|
20731
|
-
return sql.join(withEntries.map(([k,
|
|
20739
|
+
return sql.join(withEntries.map(([k, join27]) => {
|
|
20732
20740
|
const relation = tableConfig.relations[k];
|
|
20733
20741
|
const isSingle2 = is(relation, One);
|
|
20734
20742
|
const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
|
|
@@ -20739,7 +20747,7 @@ var init_dialect = __esm({
|
|
|
20739
20747
|
table: targetTable,
|
|
20740
20748
|
mode: isSingle2 ? "first" : "many",
|
|
20741
20749
|
schema,
|
|
20742
|
-
queryConfig:
|
|
20750
|
+
queryConfig: join27,
|
|
20743
20751
|
tableConfig: schema[relation.targetTableName],
|
|
20744
20752
|
relationWhere: filter,
|
|
20745
20753
|
isNested: true,
|
|
@@ -20753,7 +20761,7 @@ var init_dialect = __esm({
|
|
|
20753
20761
|
key: k,
|
|
20754
20762
|
selection: innerQuery.selection,
|
|
20755
20763
|
isArray: !isSingle2,
|
|
20756
|
-
isOptional: (relation.optional ?? false) ||
|
|
20764
|
+
isOptional: (relation.optional ?? false) || join27 !== true && !!join27.where
|
|
20757
20765
|
});
|
|
20758
20766
|
const jsonColumns = sql.join(innerQuery.selection.map((s) => {
|
|
20759
20767
|
return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb3}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
|
|
@@ -21574,7 +21582,7 @@ var init_update = __esm({
|
|
|
21574
21582
|
createJoin(joinType) {
|
|
21575
21583
|
return ((table, on) => {
|
|
21576
21584
|
const tableName = getTableLikeName(table);
|
|
21577
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
21585
|
+
if (typeof tableName === "string" && this.config.joins.some((join27) => join27.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
21578
21586
|
if (typeof on === "function") {
|
|
21579
21587
|
const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
|
|
21580
21588
|
on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
|
|
@@ -22552,8 +22560,8 @@ function probeAndMarkApplied(nativeDb, migration, logSubsystem) {
|
|
|
22552
22560
|
});
|
|
22553
22561
|
if (allAltersPresent && allTablesPresent && allIndexesPresent && allTriggersPresent) {
|
|
22554
22562
|
insertJournalEntry(nativeDb, migration.hash, migration.folderMillis, migration.name ?? "");
|
|
22555
|
-
const
|
|
22556
|
-
|
|
22563
|
+
const log5 = getLogger(logSubsystem);
|
|
22564
|
+
log5.debug(
|
|
22557
22565
|
{
|
|
22558
22566
|
migration: migration.name,
|
|
22559
22567
|
alters: alterTargets.length,
|
|
@@ -22593,14 +22601,14 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22593
22601
|
if (hasOrphanedEntries) {
|
|
22594
22602
|
const dbHashes = new Set(dbEntries.map((e) => e.hash));
|
|
22595
22603
|
const allLocalHashesPresentInDb = localMigrations.every((m) => dbHashes.has(m.hash));
|
|
22596
|
-
const
|
|
22604
|
+
const log5 = getLogger(logSubsystem);
|
|
22597
22605
|
if (allLocalHashesPresentInDb) {
|
|
22598
|
-
|
|
22606
|
+
log5.debug(
|
|
22599
22607
|
{ extra: orphanedEntries.length },
|
|
22600
22608
|
`Migration journal has ${orphanedEntries.length} entries for migrations not known to this install (DB is ahead). Skipping reconciliation.`
|
|
22601
22609
|
);
|
|
22602
22610
|
} else {
|
|
22603
|
-
|
|
22611
|
+
log5.warn(
|
|
22604
22612
|
{ orphaned: orphanedEntries.length },
|
|
22605
22613
|
`Detected ${orphanedEntries.length} true-orphan journal entries from a previous CLEO lineage. Reconciling via DDL probe.`
|
|
22606
22614
|
);
|
|
@@ -22636,8 +22644,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22636
22644
|
if (alterMatches.length === 0) {
|
|
22637
22645
|
const stripped = fullSql.replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").trim();
|
|
22638
22646
|
if (stripped === "") {
|
|
22639
|
-
const
|
|
22640
|
-
|
|
22647
|
+
const log5 = getLogger(logSubsystem);
|
|
22648
|
+
log5.debug(
|
|
22641
22649
|
{ migration: migration.name },
|
|
22642
22650
|
`Migration ${migration.name} is a comment-only baseline marker \u2014 marking applied on existing DB.`
|
|
22643
22651
|
);
|
|
@@ -22674,8 +22682,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22674
22682
|
}
|
|
22675
22683
|
}
|
|
22676
22684
|
if (missingColumns.length === 0) {
|
|
22677
|
-
const
|
|
22678
|
-
|
|
22685
|
+
const log5 = getLogger(logSubsystem);
|
|
22686
|
+
log5.warn(
|
|
22679
22687
|
{ migration: migration.name, columns: alterMatches },
|
|
22680
22688
|
`Detected partially-applied migration ${migration.name} \u2014 columns exist but journal entry missing. Auto-reconciling.`
|
|
22681
22689
|
);
|
|
@@ -22683,8 +22691,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22683
22691
|
continue;
|
|
22684
22692
|
}
|
|
22685
22693
|
if (existingColumns.length > 0 && missingColumns.length > 0) {
|
|
22686
|
-
const
|
|
22687
|
-
|
|
22694
|
+
const log5 = getLogger(logSubsystem);
|
|
22695
|
+
log5.warn(
|
|
22688
22696
|
{
|
|
22689
22697
|
migration: migration.name,
|
|
22690
22698
|
existingColumns: existingColumns.map((c) => `${c.table}.${c.column}`),
|
|
@@ -22696,12 +22704,12 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22696
22704
|
if (!tableExists(nativeDb, table)) continue;
|
|
22697
22705
|
try {
|
|
22698
22706
|
nativeDb.exec(`ALTER TABLE ${table} ADD COLUMN ${column}${ddl ? ` ${ddl}` : ""}`);
|
|
22699
|
-
|
|
22707
|
+
log5.warn(
|
|
22700
22708
|
{ migration: migration.name, table, column },
|
|
22701
22709
|
`T920: Added missing column ${table}.${column} to complete partial migration.`
|
|
22702
22710
|
);
|
|
22703
22711
|
} catch {
|
|
22704
|
-
|
|
22712
|
+
log5.warn(
|
|
22705
22713
|
{ migration: migration.name, table, column },
|
|
22706
22714
|
`T920: Could not add missing column ${table}.${column} \u2014 will let Drizzle migrate() handle it.`
|
|
22707
22715
|
);
|
|
@@ -22721,8 +22729,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
|
|
|
22721
22729
|
for (const entry of unnamedEntries) {
|
|
22722
22730
|
const migrationName = hashToName.get(entry.hash);
|
|
22723
22731
|
if (!migrationName) continue;
|
|
22724
|
-
const
|
|
22725
|
-
|
|
22732
|
+
const log5 = getLogger(logSubsystem);
|
|
22733
|
+
log5.debug(
|
|
22726
22734
|
{ id: entry.id, hash: entry.hash, name: migrationName },
|
|
22727
22735
|
`Backfilling missing name on journal entry id=${entry.id} (Drizzle v1 beta legacy compat).`
|
|
22728
22736
|
);
|
|
@@ -22797,13 +22805,13 @@ function ensureColumns(nativeDb, tableName, requiredColumns, logSubsystem, conte
|
|
|
22797
22805
|
const existingCols = new Set(columns.map((c) => c.name));
|
|
22798
22806
|
for (const req of requiredColumns) {
|
|
22799
22807
|
if (!existingCols.has(req.name)) {
|
|
22800
|
-
const
|
|
22808
|
+
const log5 = getLogger(logSubsystem);
|
|
22801
22809
|
const message = `Adding missing column ${tableName}.${req.name} via ALTER TABLE`;
|
|
22802
22810
|
const fields = { column: req.name, context };
|
|
22803
22811
|
if (context === "fresh") {
|
|
22804
|
-
|
|
22812
|
+
log5.error(fields, `${message} \u2014 MIGRATION DEFECT (fresh DB should not need repair)`);
|
|
22805
22813
|
} else {
|
|
22806
|
-
|
|
22814
|
+
log5.warn(fields, message);
|
|
22807
22815
|
}
|
|
22808
22816
|
nativeDb.exec(`ALTER TABLE ${tableName} ADD COLUMN ${req.name} ${req.ddl}`);
|
|
22809
22817
|
}
|
|
@@ -31228,6 +31236,151 @@ var init_ensure_config = __esm({
|
|
|
31228
31236
|
}
|
|
31229
31237
|
});
|
|
31230
31238
|
|
|
31239
|
+
// packages/core/src/store/exodus/archive.ts
|
|
31240
|
+
import {
|
|
31241
|
+
copyFileSync,
|
|
31242
|
+
existsSync as existsSync3,
|
|
31243
|
+
mkdirSync,
|
|
31244
|
+
renameSync,
|
|
31245
|
+
unlinkSync,
|
|
31246
|
+
writeFileSync
|
|
31247
|
+
} from "node:fs";
|
|
31248
|
+
import { basename as basename3, join as join6 } from "node:path";
|
|
31249
|
+
function scopeBaseDir(scope, cwd) {
|
|
31250
|
+
return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
|
|
31251
|
+
}
|
|
31252
|
+
function exodusArchiveDir(scope, cwd) {
|
|
31253
|
+
return join6(scopeBaseDir(scope, cwd), ARCHIVE_DIR_NAME);
|
|
31254
|
+
}
|
|
31255
|
+
function exodusMarkerPath(scope, cwd) {
|
|
31256
|
+
return join6(scopeBaseDir(scope, cwd), MARKER_FILENAME_BY_SCOPE[scope]);
|
|
31257
|
+
}
|
|
31258
|
+
function hasExodusCompleteMarker(scope, cwd) {
|
|
31259
|
+
try {
|
|
31260
|
+
return existsSync3(exodusMarkerPath(scope, cwd));
|
|
31261
|
+
} catch {
|
|
31262
|
+
return false;
|
|
31263
|
+
}
|
|
31264
|
+
}
|
|
31265
|
+
function writeExodusCompleteMarker(scope, archivedSources, cwd) {
|
|
31266
|
+
const markerPath = exodusMarkerPath(scope, cwd);
|
|
31267
|
+
const baseDir = scopeBaseDir(scope, cwd);
|
|
31268
|
+
mkdirSync(baseDir, { recursive: true });
|
|
31269
|
+
const marker = {
|
|
31270
|
+
version: 1,
|
|
31271
|
+
scope,
|
|
31272
|
+
cleoVersion: getCleoVersion(),
|
|
31273
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31274
|
+
archivedSources: [...archivedSources]
|
|
31275
|
+
};
|
|
31276
|
+
const tmpPath = `${markerPath}.tmp`;
|
|
31277
|
+
writeFileSync(tmpPath, JSON.stringify(marker, null, 2) + "\n", "utf8");
|
|
31278
|
+
renameSync(tmpPath, markerPath);
|
|
31279
|
+
log.info({ scope, markerPath, archivedSources }, "exodus: wrote completion marker");
|
|
31280
|
+
return markerPath;
|
|
31281
|
+
}
|
|
31282
|
+
function moveFileInto(srcPath, destDir) {
|
|
31283
|
+
mkdirSync(destDir, { recursive: true });
|
|
31284
|
+
let dest = join6(destDir, basename3(srcPath));
|
|
31285
|
+
if (existsSync3(dest)) {
|
|
31286
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
|
|
31287
|
+
dest = join6(destDir, `${basename3(srcPath)}.${stamp}`);
|
|
31288
|
+
}
|
|
31289
|
+
try {
|
|
31290
|
+
renameSync(srcPath, dest);
|
|
31291
|
+
} catch {
|
|
31292
|
+
copyFileSync(srcPath, dest);
|
|
31293
|
+
unlinkSync(srcPath);
|
|
31294
|
+
}
|
|
31295
|
+
return dest;
|
|
31296
|
+
}
|
|
31297
|
+
function archiveSourceDb(source, cwd) {
|
|
31298
|
+
if (!existsSync3(source.path)) {
|
|
31299
|
+
return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
|
|
31300
|
+
}
|
|
31301
|
+
const destDir = exodusArchiveDir(source.targetScope, cwd);
|
|
31302
|
+
const archivedTo = moveFileInto(source.path, destDir);
|
|
31303
|
+
for (const suffix of SIDECAR_SUFFIXES) {
|
|
31304
|
+
const sidecar = `${source.path}${suffix}`;
|
|
31305
|
+
if (existsSync3(sidecar)) {
|
|
31306
|
+
try {
|
|
31307
|
+
moveFileInto(sidecar, destDir);
|
|
31308
|
+
} catch (err) {
|
|
31309
|
+
log.warn(
|
|
31310
|
+
{ err, sidecar, sourceName: source.name },
|
|
31311
|
+
"exodus-archive: failed to archive sidecar (non-fatal)"
|
|
31312
|
+
);
|
|
31313
|
+
}
|
|
31314
|
+
}
|
|
31315
|
+
}
|
|
31316
|
+
log.info(
|
|
31317
|
+
{ sourceName: source.name, sourcePath: source.path, archivedTo, scope: source.targetScope },
|
|
31318
|
+
"exodus-archive: archived legacy source DB"
|
|
31319
|
+
);
|
|
31320
|
+
return {
|
|
31321
|
+
name: source.name,
|
|
31322
|
+
sourcePath: source.path,
|
|
31323
|
+
archivedTo,
|
|
31324
|
+
action: "archived"
|
|
31325
|
+
};
|
|
31326
|
+
}
|
|
31327
|
+
function archiveMigratedSources(consumed, cwd) {
|
|
31328
|
+
const results = [];
|
|
31329
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
31330
|
+
for (const source of consumed) {
|
|
31331
|
+
scopes.add(source.targetScope);
|
|
31332
|
+
results.push(archiveSourceDb(source, cwd));
|
|
31333
|
+
}
|
|
31334
|
+
const markersWritten = [];
|
|
31335
|
+
for (const scope of scopes) {
|
|
31336
|
+
const archivedForScope = consumed.filter((s) => s.targetScope === scope).map((s) => s.name);
|
|
31337
|
+
writeExodusCompleteMarker(scope, archivedForScope, cwd);
|
|
31338
|
+
markersWritten.push(scope);
|
|
31339
|
+
}
|
|
31340
|
+
return { sources: results, markersWritten };
|
|
31341
|
+
}
|
|
31342
|
+
function detectStrandedResidue(sources, cwd) {
|
|
31343
|
+
const markedScopes = /* @__PURE__ */ new Set();
|
|
31344
|
+
for (const scope of ["project", "global"]) {
|
|
31345
|
+
if (hasExodusCompleteMarker(scope, cwd)) markedScopes.add(scope);
|
|
31346
|
+
}
|
|
31347
|
+
if (markedScopes.size === 0) return [];
|
|
31348
|
+
const stranded = [];
|
|
31349
|
+
for (const source of sources) {
|
|
31350
|
+
if (!markedScopes.has(source.targetScope)) continue;
|
|
31351
|
+
if (existsSync3(source.path)) {
|
|
31352
|
+
stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
|
|
31353
|
+
}
|
|
31354
|
+
}
|
|
31355
|
+
return stranded;
|
|
31356
|
+
}
|
|
31357
|
+
function archiveStrandedResidue(stranded, sources, cwd) {
|
|
31358
|
+
const byName = new Map(sources.map((s) => [s.name, s]));
|
|
31359
|
+
const results = [];
|
|
31360
|
+
for (const entry of stranded) {
|
|
31361
|
+
const descriptor = byName.get(entry.name);
|
|
31362
|
+
if (descriptor === void 0) continue;
|
|
31363
|
+
results.push(archiveSourceDb(descriptor, cwd));
|
|
31364
|
+
}
|
|
31365
|
+
return results;
|
|
31366
|
+
}
|
|
31367
|
+
var log, ARCHIVE_DIR_NAME, MARKER_FILENAME_BY_SCOPE, SIDECAR_SUFFIXES;
|
|
31368
|
+
var init_archive2 = __esm({
|
|
31369
|
+
"packages/core/src/store/exodus/archive.ts"() {
|
|
31370
|
+
"use strict";
|
|
31371
|
+
init_logger2();
|
|
31372
|
+
init_paths();
|
|
31373
|
+
init_ensure_config();
|
|
31374
|
+
log = getLogger("exodus-archive");
|
|
31375
|
+
ARCHIVE_DIR_NAME = "_archive";
|
|
31376
|
+
MARKER_FILENAME_BY_SCOPE = {
|
|
31377
|
+
project: "exodus-complete",
|
|
31378
|
+
global: "exodus-complete"
|
|
31379
|
+
};
|
|
31380
|
+
SIDECAR_SUFFIXES = ["-wal", "-shm"];
|
|
31381
|
+
}
|
|
31382
|
+
});
|
|
31383
|
+
|
|
31231
31384
|
// packages/core/src/project-info.ts
|
|
31232
31385
|
var init_project_info = __esm({
|
|
31233
31386
|
"packages/core/src/project-info.ts"() {
|
|
@@ -31622,15 +31775,15 @@ var init_types = __esm({
|
|
|
31622
31775
|
|
|
31623
31776
|
// packages/core/src/store/exodus/migrate.ts
|
|
31624
31777
|
import {
|
|
31625
|
-
copyFileSync,
|
|
31626
|
-
existsSync as
|
|
31627
|
-
mkdirSync,
|
|
31778
|
+
copyFileSync as copyFileSync2,
|
|
31779
|
+
existsSync as existsSync4,
|
|
31780
|
+
mkdirSync as mkdirSync2,
|
|
31628
31781
|
readFileSync as readFileSync2,
|
|
31629
|
-
renameSync,
|
|
31630
|
-
unlinkSync,
|
|
31631
|
-
writeFileSync
|
|
31782
|
+
renameSync as renameSync2,
|
|
31783
|
+
unlinkSync as unlinkSync2,
|
|
31784
|
+
writeFileSync as writeFileSync2
|
|
31632
31785
|
} from "node:fs";
|
|
31633
|
-
import { join as
|
|
31786
|
+
import { join as join7 } from "node:path";
|
|
31634
31787
|
function getSqliteVersion(db) {
|
|
31635
31788
|
try {
|
|
31636
31789
|
const row = db.prepare("SELECT sqlite_version() AS v").get();
|
|
@@ -31646,14 +31799,14 @@ function listTables(db) {
|
|
|
31646
31799
|
return rows.map((r) => r.name);
|
|
31647
31800
|
}
|
|
31648
31801
|
function writeJournal(stagingDir, journal) {
|
|
31649
|
-
const journalPath =
|
|
31802
|
+
const journalPath = join7(stagingDir, JOURNAL_FILENAME);
|
|
31650
31803
|
const tmpPath = `${journalPath}.tmp`;
|
|
31651
|
-
|
|
31652
|
-
|
|
31804
|
+
writeFileSync2(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
|
|
31805
|
+
renameSync2(tmpPath, journalPath);
|
|
31653
31806
|
}
|
|
31654
31807
|
function readJournal(stagingDir) {
|
|
31655
|
-
const journalPath =
|
|
31656
|
-
if (!
|
|
31808
|
+
const journalPath = join7(stagingDir, JOURNAL_FILENAME);
|
|
31809
|
+
if (!existsSync4(journalPath)) return null;
|
|
31657
31810
|
try {
|
|
31658
31811
|
return JSON.parse(readFileSync2(journalPath, "utf8"));
|
|
31659
31812
|
} catch {
|
|
@@ -31661,17 +31814,17 @@ function readJournal(stagingDir) {
|
|
|
31661
31814
|
}
|
|
31662
31815
|
}
|
|
31663
31816
|
function clearExodusJournal(stagingDir) {
|
|
31664
|
-
const journalPath =
|
|
31817
|
+
const journalPath = join7(stagingDir, JOURNAL_FILENAME);
|
|
31665
31818
|
try {
|
|
31666
|
-
if (!
|
|
31667
|
-
|
|
31668
|
-
|
|
31819
|
+
if (!existsSync4(journalPath)) return false;
|
|
31820
|
+
unlinkSync2(journalPath);
|
|
31821
|
+
log2.info(
|
|
31669
31822
|
{ stagingDir },
|
|
31670
31823
|
"exodus: cleared migrate journal after abort/rollback \u2014 a retry will RE-COPY all tables"
|
|
31671
31824
|
);
|
|
31672
31825
|
return true;
|
|
31673
31826
|
} catch (err) {
|
|
31674
|
-
|
|
31827
|
+
log2.warn(
|
|
31675
31828
|
{ err, stagingDir },
|
|
31676
31829
|
'exodus: failed to clear migrate journal after rollback (a retry may skip already-"done" tables)'
|
|
31677
31830
|
);
|
|
@@ -31696,11 +31849,11 @@ function lockPath(dbPath) {
|
|
|
31696
31849
|
}
|
|
31697
31850
|
function acquireAdvisoryLock(dbPath) {
|
|
31698
31851
|
const lp = lockPath(dbPath);
|
|
31699
|
-
|
|
31852
|
+
writeFileSync2(lp, JSON.stringify({ pid: process.pid, ts: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
|
|
31700
31853
|
}
|
|
31701
31854
|
function releaseAdvisoryLock(dbPath) {
|
|
31702
31855
|
try {
|
|
31703
|
-
|
|
31856
|
+
unlinkSync2(lockPath(dbPath));
|
|
31704
31857
|
} catch {
|
|
31705
31858
|
}
|
|
31706
31859
|
}
|
|
@@ -31720,6 +31873,11 @@ function enumNormExpr(targetTableName, col, srcRef) {
|
|
|
31720
31873
|
const fn = ENUM_NORMALIZATIONS.get(key);
|
|
31721
31874
|
return fn ? fn(srcRef) : null;
|
|
31722
31875
|
}
|
|
31876
|
+
function numericClampExpr(targetTableName, col, srcRef) {
|
|
31877
|
+
const key = `${targetTableName}.${col}`;
|
|
31878
|
+
const fn = NUMERIC_CLAMPS.get(key);
|
|
31879
|
+
return fn ? fn(srcRef) : null;
|
|
31880
|
+
}
|
|
31723
31881
|
function epochUnitForSource(sourceName) {
|
|
31724
31882
|
const key = sourceName.toLowerCase();
|
|
31725
31883
|
for (const [pattern, unit] of SOURCE_EPOCH_UNITS) {
|
|
@@ -31755,6 +31913,14 @@ function buildSelectExpr(attachAlias, legacyTable, targetTableName, col, srcType
|
|
|
31755
31913
|
}
|
|
31756
31914
|
return `${isoExpr} AS "${col}"`;
|
|
31757
31915
|
}
|
|
31916
|
+
const clampExpr = numericClampExpr(targetTableName, col, srcRef);
|
|
31917
|
+
if (clampExpr !== null) {
|
|
31918
|
+
if (isNotNullWithoutDefault) {
|
|
31919
|
+
const defLiteral = typeDefaultLiteral(tgtInfo.type);
|
|
31920
|
+
return `COALESCE(${clampExpr}, ${defLiteral}) AS "${col}"`;
|
|
31921
|
+
}
|
|
31922
|
+
return `${clampExpr} AS "${col}"`;
|
|
31923
|
+
}
|
|
31758
31924
|
const normExpr = enumNormExpr(targetTableName, col, srcRef);
|
|
31759
31925
|
if (normExpr !== null) {
|
|
31760
31926
|
if (isNotNullWithoutDefault) {
|
|
@@ -31772,7 +31938,7 @@ function buildSelectExpr(attachAlias, legacyTable, targetTableName, col, srcType
|
|
|
31772
31938
|
function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyTableName, sourceName, targetSchema = "main") {
|
|
31773
31939
|
const resolution = resolveConsolidatedTableName(sourceName, legacyTableName);
|
|
31774
31940
|
if (resolution.kind === "skip") {
|
|
31775
|
-
|
|
31941
|
+
log2.warn(
|
|
31776
31942
|
{ legacyTableName, sourceName, reason: resolution.reason },
|
|
31777
31943
|
`Exodus: explicitly skipping table \u2014 ${resolution.reason}`
|
|
31778
31944
|
);
|
|
@@ -31791,7 +31957,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
|
|
|
31791
31957
|
).get();
|
|
31792
31958
|
if (!existsRow) {
|
|
31793
31959
|
const reason = `consolidated target '${targetTableName}' not found (mapped from legacy '${legacyTableName}')`;
|
|
31794
|
-
|
|
31960
|
+
log2.warn(
|
|
31795
31961
|
{ legacyTableName, targetTableName, sourceName, attachAlias, targetSchema },
|
|
31796
31962
|
`Exodus: ${reason}`
|
|
31797
31963
|
);
|
|
@@ -31802,13 +31968,13 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
|
|
|
31802
31968
|
const sharedColumns = srcPragma.map((r) => r.name).filter((col) => tgtColMap.has(col));
|
|
31803
31969
|
if (sharedColumns.length === 0) {
|
|
31804
31970
|
const reason = `no overlapping columns between source '${legacyTableName}' and target '${targetTableName}'`;
|
|
31805
|
-
|
|
31971
|
+
log2.warn({ legacyTableName, targetTableName, sourceName }, `Exodus: ${reason}`);
|
|
31806
31972
|
return { rowsCopied: 0, skipped: true, reason };
|
|
31807
31973
|
}
|
|
31808
31974
|
const srcOnlyColumns = srcPragma.map((r) => r.name).filter((c) => !tgtColMap.has(c));
|
|
31809
31975
|
const tgtOnlyColumns = tgtPragma.map((r) => r.name).filter((c) => !srcColumns.has(c));
|
|
31810
31976
|
if (srcOnlyColumns.length > 0 || tgtOnlyColumns.length > 0) {
|
|
31811
|
-
|
|
31977
|
+
log2.info(
|
|
31812
31978
|
{ legacyTableName, targetTableName, sourceName, srcOnlyColumns, tgtOnlyColumns },
|
|
31813
31979
|
"Exodus: column drift detected \u2014 copying intersection, dropping src-only cols, using defaults for tgt-only cols"
|
|
31814
31980
|
);
|
|
@@ -31823,7 +31989,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
|
|
|
31823
31989
|
return isoGlobCols.has(col) && (upper.includes("INT") || upper === "" || upper === "NUMERIC");
|
|
31824
31990
|
});
|
|
31825
31991
|
if (coercedCols.length > 0) {
|
|
31826
|
-
|
|
31992
|
+
log2.info(
|
|
31827
31993
|
{
|
|
31828
31994
|
legacyTableName,
|
|
31829
31995
|
targetTableName,
|
|
@@ -31839,11 +32005,20 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
|
|
|
31839
32005
|
(col) => ENUM_NORMALIZATIONS.has(`${targetTableName}.${col}`)
|
|
31840
32006
|
);
|
|
31841
32007
|
if (normalizedCols.length > 0) {
|
|
31842
|
-
|
|
32008
|
+
log2.info(
|
|
31843
32009
|
{ legacyTableName, targetTableName, sourceName, normalizedCols },
|
|
31844
32010
|
`Exodus: applying enum-value normalization for ${normalizedCols.length} column(s) (T11547)`
|
|
31845
32011
|
);
|
|
31846
32012
|
}
|
|
32013
|
+
const clampedCols = sharedColumns.filter(
|
|
32014
|
+
(col) => NUMERIC_CLAMPS.has(`${targetTableName}.${col}`)
|
|
32015
|
+
);
|
|
32016
|
+
if (clampedCols.length > 0) {
|
|
32017
|
+
log2.info(
|
|
32018
|
+
{ legacyTableName, targetTableName, sourceName, clampedCols },
|
|
32019
|
+
`Exodus: applying non-finite numeric clamp for ${clampedCols.length} column(s) (T11782)`
|
|
32020
|
+
);
|
|
32021
|
+
}
|
|
31847
32022
|
const selectExprs = sharedColumns.map((col) => {
|
|
31848
32023
|
const srcType = srcTypeMap.get(col) ?? "";
|
|
31849
32024
|
const tgtInfo = tgtColMap.get(col);
|
|
@@ -31880,13 +32055,13 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
|
|
|
31880
32055
|
const dropped = sourceCount - rowsCopied;
|
|
31881
32056
|
if (rowsCopied === 0) {
|
|
31882
32057
|
const reason = `INSERT OR IGNORE dropped ALL ${sourceCount} rows from '${legacyTableName}'\u2192'${targetTableName}' (rowsCopied=0, sourceCount=${sourceCount}). Likely a CHECK/type constraint violation \u2014 check epoch coercion or enum values.`;
|
|
31883
|
-
|
|
32058
|
+
log2.error(
|
|
31884
32059
|
{ legacyTableName, targetTableName, sourceName, sourceCount, rowsCopied },
|
|
31885
32060
|
`Exodus: ${reason}`
|
|
31886
32061
|
);
|
|
31887
32062
|
return { rowsCopied: 0, skipped: false, reason };
|
|
31888
32063
|
}
|
|
31889
|
-
|
|
32064
|
+
log2.warn(
|
|
31890
32065
|
{ legacyTableName, targetTableName, sourceName, sourceCount, rowsCopied, dropped },
|
|
31891
32066
|
`Exodus: INSERT OR IGNORE dropped ${dropped}/${sourceCount} rows from '${legacyTableName}'\u2192'${targetTableName}' \u2014 may be idempotent-resume dedup or a constraint violation; verify will confirm`
|
|
31892
32067
|
);
|
|
@@ -31897,16 +32072,16 @@ function checkSchemaVersion(journal, forceCrossVersion) {
|
|
|
31897
32072
|
if (journal.targetSchemaVersion !== EXODUS_TARGET_SCHEMA_VERSION) {
|
|
31898
32073
|
const msg = `Schema version mismatch: journal=${journal.targetSchemaVersion}, expected=${EXODUS_TARGET_SCHEMA_VERSION}`;
|
|
31899
32074
|
if (forceCrossVersion) {
|
|
31900
|
-
|
|
32075
|
+
log2.warn(msg + " (--force-cross-version: continuing anyway)");
|
|
31901
32076
|
return true;
|
|
31902
32077
|
}
|
|
31903
|
-
|
|
32078
|
+
log2.error(msg + " \u2014 pass --force-cross-version to override");
|
|
31904
32079
|
return false;
|
|
31905
32080
|
}
|
|
31906
32081
|
return true;
|
|
31907
32082
|
}
|
|
31908
32083
|
async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
|
|
31909
|
-
const { sources, stagingDir, diskPreflight, projectDbPath } = plan;
|
|
32084
|
+
const { sources, stagingDir, diskPreflight, projectDbPath, globalDbPath } = plan;
|
|
31910
32085
|
if (!diskPreflight) {
|
|
31911
32086
|
return {
|
|
31912
32087
|
ok: false,
|
|
@@ -31916,10 +32091,10 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
|
|
|
31916
32091
|
error: `Insufficient disk space: need \u22653\xD7 source size (${plan.totalSourceBytes} bytes source, ${plan.availableBytes} bytes available). Free up space or use a different storage location.`
|
|
31917
32092
|
};
|
|
31918
32093
|
}
|
|
31919
|
-
|
|
32094
|
+
mkdirSync2(stagingDir, { recursive: true });
|
|
31920
32095
|
let sqliteVersion = "unknown";
|
|
31921
32096
|
for (const src of sources) {
|
|
31922
|
-
if (
|
|
32097
|
+
if (existsSync4(src.path)) {
|
|
31923
32098
|
const snap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
31924
32099
|
sqliteVersion = getSqliteVersion(snap.db);
|
|
31925
32100
|
snap.close();
|
|
@@ -31944,6 +32119,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
|
|
|
31944
32119
|
const backupPaths = [];
|
|
31945
32120
|
const allTableResults = [];
|
|
31946
32121
|
const lockedPaths = [];
|
|
32122
|
+
let projectHandle = null;
|
|
32123
|
+
let globalHandle = null;
|
|
31947
32124
|
try {
|
|
31948
32125
|
let extractNativeDb2 = function(handle) {
|
|
31949
32126
|
const drizzleHandle = handle.db;
|
|
@@ -31958,24 +32135,28 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
|
|
|
31958
32135
|
};
|
|
31959
32136
|
var extractNativeDb = extractNativeDb2;
|
|
31960
32137
|
for (const src of sources) {
|
|
31961
|
-
if (!
|
|
31962
|
-
const backupDest =
|
|
31963
|
-
if (!
|
|
32138
|
+
if (!existsSync4(src.path)) continue;
|
|
32139
|
+
const backupDest = join7(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
|
|
32140
|
+
if (!existsSync4(backupDest)) {
|
|
31964
32141
|
onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
|
|
31965
|
-
|
|
32142
|
+
copyFileSync2(src.path, backupDest);
|
|
31966
32143
|
backupPaths.push(backupDest);
|
|
31967
32144
|
}
|
|
31968
32145
|
acquireAdvisoryLock(src.path);
|
|
31969
32146
|
lockedPaths.push(src.path);
|
|
31970
32147
|
}
|
|
31971
|
-
onProgress?.("Opening
|
|
31972
|
-
|
|
31973
|
-
|
|
31974
|
-
|
|
32148
|
+
onProgress?.("Opening DEDICATED project-scope cleo.db connection (running migrations)\u2026");
|
|
32149
|
+
projectHandle = await openDualScopeDbAtPath("project", projectDbPath, void 0, {
|
|
32150
|
+
dedicated: true
|
|
32151
|
+
});
|
|
32152
|
+
onProgress?.("Opening DEDICATED global-scope cleo.db connection (running migrations)\u2026");
|
|
32153
|
+
globalHandle = await openDualScopeDbAtPath("global", globalDbPath, void 0, {
|
|
32154
|
+
dedicated: true
|
|
32155
|
+
});
|
|
31975
32156
|
const projectNative = extractNativeDb2(projectHandle);
|
|
31976
32157
|
const globalNative = extractNativeDb2(globalHandle);
|
|
31977
|
-
const projectSources = sources.filter((s) => s.targetScope === "project" &&
|
|
31978
|
-
const globalSources = sources.filter((s) => s.targetScope === "global" &&
|
|
32158
|
+
const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync4(s.path));
|
|
32159
|
+
const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync4(s.path));
|
|
31979
32160
|
await migrateScope(
|
|
31980
32161
|
"project",
|
|
31981
32162
|
projectSources,
|
|
@@ -31997,14 +32178,20 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
|
|
|
31997
32178
|
);
|
|
31998
32179
|
journal.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
31999
32180
|
writeJournal(stagingDir, journal);
|
|
32000
|
-
projectHandle.close();
|
|
32001
|
-
globalHandle.close();
|
|
32002
32181
|
return { ok: true, tables: allTableResults, stagingDir, backupPaths };
|
|
32003
32182
|
} catch (err) {
|
|
32004
32183
|
const error = err instanceof Error ? err.message : String(err);
|
|
32005
|
-
|
|
32184
|
+
log2.error({ err }, "Exodus migration failed");
|
|
32006
32185
|
return { ok: false, tables: allTableResults, stagingDir, backupPaths, error };
|
|
32007
32186
|
} finally {
|
|
32187
|
+
try {
|
|
32188
|
+
projectHandle?.close();
|
|
32189
|
+
} catch {
|
|
32190
|
+
}
|
|
32191
|
+
try {
|
|
32192
|
+
globalHandle?.close();
|
|
32193
|
+
} catch {
|
|
32194
|
+
}
|
|
32008
32195
|
for (const p of lockedPaths) {
|
|
32009
32196
|
releaseAdvisoryLock(p);
|
|
32010
32197
|
}
|
|
@@ -32014,7 +32201,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
|
|
|
32014
32201
|
if (sources.length === 0) return;
|
|
32015
32202
|
onProgress?.(`Migrating ${scope}-scope sources\u2026`);
|
|
32016
32203
|
targetNativeDb.exec("PRAGMA foreign_keys = OFF");
|
|
32017
|
-
|
|
32204
|
+
log2.info({ scope }, "Exodus: foreign_keys=OFF for bulk copy (T11533 FK-defer)");
|
|
32018
32205
|
try {
|
|
32019
32206
|
for (let i = 0; i < sources.length; i++) {
|
|
32020
32207
|
const src = sources[i];
|
|
@@ -32076,12 +32263,12 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
|
|
|
32076
32263
|
errorMsg = copyResult.reason;
|
|
32077
32264
|
skipped = true;
|
|
32078
32265
|
} else if (copyResult.reason) {
|
|
32079
|
-
status = "
|
|
32266
|
+
status = "partial";
|
|
32080
32267
|
errorMsg = copyResult.reason;
|
|
32081
32268
|
}
|
|
32082
32269
|
} catch (err) {
|
|
32083
32270
|
const msg = err instanceof Error ? err.message : String(err);
|
|
32084
|
-
|
|
32271
|
+
log2.warn({ tableName, sourceDb: src.name, err }, "Table copy failed \u2014 skipping");
|
|
32085
32272
|
status = "skipped";
|
|
32086
32273
|
errorMsg = msg;
|
|
32087
32274
|
skipped = true;
|
|
@@ -32129,7 +32316,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
|
|
|
32129
32316
|
targetNativeDb.exec(`DETACH DATABASE "${attachAlias}"`);
|
|
32130
32317
|
onProgress?.(` [${src.name}] Detached "${attachAlias}"`);
|
|
32131
32318
|
} catch (detachErr) {
|
|
32132
|
-
|
|
32319
|
+
log2.warn(
|
|
32133
32320
|
{ attachAlias, sourceDb: src.name, err: detachErr },
|
|
32134
32321
|
"DETACH failed \u2014 alias will be released on DB close"
|
|
32135
32322
|
);
|
|
@@ -32139,7 +32326,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
|
|
|
32139
32326
|
targetNativeDb.exec(`DETACH DATABASE "${crossAlias}"`);
|
|
32140
32327
|
onProgress?.(` [${src.name}] Cross-scope target detached "${crossAlias}"`);
|
|
32141
32328
|
} catch (detachErr) {
|
|
32142
|
-
|
|
32329
|
+
log2.warn(
|
|
32143
32330
|
{ crossAlias, sourceDb: src.name, err: detachErr },
|
|
32144
32331
|
"Cross-scope DETACH failed \u2014 alias will be released on DB close"
|
|
32145
32332
|
);
|
|
@@ -32151,28 +32338,28 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
|
|
|
32151
32338
|
try {
|
|
32152
32339
|
const orphans = targetNativeDb.prepare("PRAGMA foreign_key_check").all();
|
|
32153
32340
|
if (orphans.length > 0) {
|
|
32154
|
-
|
|
32341
|
+
log2.warn(
|
|
32155
32342
|
{ scope, orphanCount: orphans.length, sample: orphans.slice(0, 5) },
|
|
32156
32343
|
`Exodus: PRAGMA foreign_key_check found ${orphans.length} orphan row(s) after bulk copy \u2014 these are genuine data orphans (not ordering artifacts)`
|
|
32157
32344
|
);
|
|
32158
32345
|
} else {
|
|
32159
|
-
|
|
32346
|
+
log2.info({ scope }, "Exodus: PRAGMA foreign_key_check PASSED \u2014 no orphan rows");
|
|
32160
32347
|
}
|
|
32161
32348
|
} catch (checkErr) {
|
|
32162
|
-
|
|
32349
|
+
log2.warn(
|
|
32163
32350
|
{ scope, err: checkErr },
|
|
32164
32351
|
"Exodus: PRAGMA foreign_key_check failed (non-fatal) \u2014 target schema may not have FK constraints enabled"
|
|
32165
32352
|
);
|
|
32166
32353
|
}
|
|
32167
32354
|
try {
|
|
32168
32355
|
targetNativeDb.exec("PRAGMA foreign_keys = ON");
|
|
32169
|
-
|
|
32356
|
+
log2.info({ scope }, "Exodus: foreign_keys=ON restored after bulk copy");
|
|
32170
32357
|
} catch (fkErr) {
|
|
32171
|
-
|
|
32358
|
+
log2.warn({ scope, err: fkErr }, "Exodus: could not restore foreign_keys=ON (non-fatal)");
|
|
32172
32359
|
}
|
|
32173
32360
|
}
|
|
32174
32361
|
}
|
|
32175
|
-
var
|
|
32362
|
+
var log2, LOCK_SENTINEL_SUFFIX, JOURNAL_FILENAME, ENUM_NORMALIZATIONS, NUMERIC_CLAMPS, ISO_CHECK_REGEX, SOURCE_EPOCH_UNITS, EPOCH_SECONDS_THRESHOLD;
|
|
32176
32363
|
var init_migrate = __esm({
|
|
32177
32364
|
"packages/core/src/store/exodus/migrate.ts"() {
|
|
32178
32365
|
"use strict";
|
|
@@ -32182,7 +32369,7 @@ var init_migrate = __esm({
|
|
|
32182
32369
|
init_open_cleo_db();
|
|
32183
32370
|
init_table_name_map();
|
|
32184
32371
|
init_types();
|
|
32185
|
-
|
|
32372
|
+
log2 = getLogger("exodus-migrate");
|
|
32186
32373
|
LOCK_SENTINEL_SUFFIX = ".exodus-lock";
|
|
32187
32374
|
JOURNAL_FILENAME = "exodus-journal.json";
|
|
32188
32375
|
ENUM_NORMALIZATIONS = /* @__PURE__ */ new Map([
|
|
@@ -32274,6 +32461,15 @@ var init_migrate = __esm({
|
|
|
32274
32461
|
// brain target = runtime shape with no CHECK; legacy values like 'accepted',
|
|
32275
32462
|
// 'rejected', 'prime' now survive VERBATIM instead of being coerced.)
|
|
32276
32463
|
]);
|
|
32464
|
+
NUMERIC_CLAMPS = /* @__PURE__ */ new Map([
|
|
32465
|
+
// --- brain_weight_history.delta_weight (T11782) -------------------------
|
|
32466
|
+
// +Inf → 1.0 (max canonical reinforcement), -Inf → -1.0 (max canonical
|
|
32467
|
+
// depression), NaN → 0.0 (no-op delta). Finite values pass through.
|
|
32468
|
+
[
|
|
32469
|
+
"brain_weight_history.delta_weight",
|
|
32470
|
+
(src) => `CASE WHEN ${src} = 9e999 THEN 1.0 WHEN ${src} = -9e999 THEN -1.0 WHEN ${src} != ${src} THEN 0.0 ELSE ${src} END`
|
|
32471
|
+
]
|
|
32472
|
+
]);
|
|
32277
32473
|
ISO_CHECK_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+IS\s+NULL\s+OR\s+"[^"]+"\s+GLOB\s+'\[0-9/gi;
|
|
32278
32474
|
SOURCE_EPOCH_UNITS = /* @__PURE__ */ new Map([
|
|
32279
32475
|
["conduit", "seconds"],
|
|
@@ -32290,8 +32486,8 @@ var init_migrate = __esm({
|
|
|
32290
32486
|
});
|
|
32291
32487
|
|
|
32292
32488
|
// packages/core/src/store/exodus/plan.ts
|
|
32293
|
-
import { existsSync as
|
|
32294
|
-
import { join as
|
|
32489
|
+
import { existsSync as existsSync5, readdirSync as readdirSync2, statfsSync, statSync } from "node:fs";
|
|
32490
|
+
import { join as join8 } from "node:path";
|
|
32295
32491
|
function buildSourceDescriptors(cwd) {
|
|
32296
32492
|
const cleoDir = resolveCleoDir(cwd);
|
|
32297
32493
|
const cleoHome = getCleoHome();
|
|
@@ -32299,33 +32495,33 @@ function buildSourceDescriptors(cwd) {
|
|
|
32299
32495
|
// Project-tier — go into consolidated project-scope cleo.db
|
|
32300
32496
|
{
|
|
32301
32497
|
name: "tasks",
|
|
32302
|
-
path:
|
|
32498
|
+
path: join8(cleoDir, "tasks.db"),
|
|
32303
32499
|
targetScope: "project"
|
|
32304
32500
|
},
|
|
32305
32501
|
{
|
|
32306
32502
|
name: "brain (project)",
|
|
32307
|
-
path:
|
|
32503
|
+
path: join8(cleoDir, "brain.db"),
|
|
32308
32504
|
targetScope: "project"
|
|
32309
32505
|
},
|
|
32310
32506
|
{
|
|
32311
32507
|
name: "conduit",
|
|
32312
|
-
path:
|
|
32508
|
+
path: join8(cleoDir, "conduit.db"),
|
|
32313
32509
|
targetScope: "project"
|
|
32314
32510
|
},
|
|
32315
32511
|
// Global-tier — go into consolidated global-scope cleo.db
|
|
32316
32512
|
{
|
|
32317
32513
|
name: "nexus",
|
|
32318
|
-
path:
|
|
32514
|
+
path: join8(cleoHome, "nexus.db"),
|
|
32319
32515
|
targetScope: "global"
|
|
32320
32516
|
},
|
|
32321
32517
|
{
|
|
32322
32518
|
name: "signaldock",
|
|
32323
|
-
path:
|
|
32519
|
+
path: join8(cleoHome, "signaldock.db"),
|
|
32324
32520
|
targetScope: "global"
|
|
32325
32521
|
},
|
|
32326
32522
|
{
|
|
32327
32523
|
name: "skills",
|
|
32328
|
-
path:
|
|
32524
|
+
path: join8(cleoHome, "skills.db"),
|
|
32329
32525
|
targetScope: "global"
|
|
32330
32526
|
}
|
|
32331
32527
|
];
|
|
@@ -32354,7 +32550,7 @@ function findExistingStaging(cleoDir) {
|
|
|
32354
32550
|
const entries = readdirSync2(cleoDir, { withFileTypes: true });
|
|
32355
32551
|
const stagingDirs = entries.filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => e.name).sort().reverse();
|
|
32356
32552
|
if (stagingDirs.length > 0) {
|
|
32357
|
-
return
|
|
32553
|
+
return join8(cleoDir, stagingDirs[0]);
|
|
32358
32554
|
}
|
|
32359
32555
|
} catch {
|
|
32360
32556
|
}
|
|
@@ -32367,7 +32563,7 @@ function buildExodusPlan(cwd) {
|
|
|
32367
32563
|
const availableBytes = getAvailableBytes(cleoDir);
|
|
32368
32564
|
const diskPreflight = totalSourceBytes === 0 || availableBytes >= 3 * totalSourceBytes;
|
|
32369
32565
|
const existingStaging = findExistingStaging(cleoDir);
|
|
32370
|
-
const stagingDir = existingStaging ??
|
|
32566
|
+
const stagingDir = existingStaging ?? join8(cleoDir, deriveStagingDirName());
|
|
32371
32567
|
const resumeFromStaging = existingStaging !== null;
|
|
32372
32568
|
const projectDbPath = resolveDualScopeDbPath("project", cwd);
|
|
32373
32569
|
const globalDbPath = resolveDualScopeDbPath("global");
|
|
@@ -32383,7 +32579,7 @@ function buildExodusPlan(cwd) {
|
|
|
32383
32579
|
};
|
|
32384
32580
|
}
|
|
32385
32581
|
function sourcesPresent(sources) {
|
|
32386
|
-
return sources.some((s) =>
|
|
32582
|
+
return sources.some((s) => existsSync5(s.path));
|
|
32387
32583
|
}
|
|
32388
32584
|
var init_plan2 = __esm({
|
|
32389
32585
|
"packages/core/src/store/exodus/plan.ts"() {
|
|
@@ -32394,11 +32590,11 @@ var init_plan2 = __esm({
|
|
|
32394
32590
|
});
|
|
32395
32591
|
|
|
32396
32592
|
// packages/core/src/store/exodus/status.ts
|
|
32397
|
-
import { existsSync as
|
|
32398
|
-
import { join as
|
|
32593
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
|
|
32594
|
+
import { join as join9 } from "node:path";
|
|
32399
32595
|
function readJournal2(stagingDir) {
|
|
32400
|
-
const p =
|
|
32401
|
-
if (!
|
|
32596
|
+
const p = join9(stagingDir, JOURNAL_FILENAME2);
|
|
32597
|
+
if (!existsSync6(p)) return null;
|
|
32402
32598
|
try {
|
|
32403
32599
|
return JSON.parse(readFileSync3(p, "utf8"));
|
|
32404
32600
|
} catch {
|
|
@@ -32407,7 +32603,7 @@ function readJournal2(stagingDir) {
|
|
|
32407
32603
|
}
|
|
32408
32604
|
function findStagingDirs(cleoDir) {
|
|
32409
32605
|
try {
|
|
32410
|
-
return readdirSync3(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) =>
|
|
32606
|
+
return readdirSync3(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join9(cleoDir, e.name)).sort().reverse();
|
|
32411
32607
|
} catch {
|
|
32412
32608
|
return [];
|
|
32413
32609
|
}
|
|
@@ -32430,15 +32626,15 @@ function runExodusStatus(cwd) {
|
|
|
32430
32626
|
const sourcesInfo = plan.sources.map((s) => ({
|
|
32431
32627
|
name: s.name,
|
|
32432
32628
|
path: s.path,
|
|
32433
|
-
exists:
|
|
32629
|
+
exists: existsSync6(s.path),
|
|
32434
32630
|
bytes: safeBytes(s.path)
|
|
32435
32631
|
}));
|
|
32436
32632
|
return {
|
|
32437
32633
|
hasStaging: latestStaging !== null,
|
|
32438
32634
|
stagingDir: latestStaging,
|
|
32439
32635
|
journal,
|
|
32440
|
-
projectDbExists:
|
|
32441
|
-
globalDbExists:
|
|
32636
|
+
projectDbExists: existsSync6(projectDbPath),
|
|
32637
|
+
globalDbExists: existsSync6(globalDbPath),
|
|
32442
32638
|
sourcesPresent: sourcesInfo.some((s) => s.exists),
|
|
32443
32639
|
sources: sourcesInfo
|
|
32444
32640
|
};
|
|
@@ -32455,7 +32651,7 @@ var init_status = __esm({
|
|
|
32455
32651
|
});
|
|
32456
32652
|
|
|
32457
32653
|
// packages/core/src/store/exodus/verify-migration.ts
|
|
32458
|
-
import { existsSync as
|
|
32654
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
32459
32655
|
import { createRequire as createRequire3 } from "node:module";
|
|
32460
32656
|
function orderByClause(db, tableName) {
|
|
32461
32657
|
try {
|
|
@@ -32478,14 +32674,15 @@ function computeTableDigest(db, tableName, columns) {
|
|
|
32478
32674
|
rows = db.prepare(`SELECT ${selectClause} FROM "${tableName}" ORDER BY ${orderBy}`).all();
|
|
32479
32675
|
} catch (err) {
|
|
32480
32676
|
const msg = err instanceof Error ? err.message : String(err);
|
|
32481
|
-
|
|
32677
|
+
log3.warn(
|
|
32482
32678
|
{ tableName, err: msg },
|
|
32483
32679
|
"computeTableDigest: SELECT failed (possibly a virtual/FTS table) \u2014 treating as 0 rows"
|
|
32484
32680
|
);
|
|
32485
32681
|
return { count: 0, hash: "" };
|
|
32486
32682
|
}
|
|
32487
32683
|
for (const row of rows) {
|
|
32488
|
-
|
|
32684
|
+
const rowObj = row;
|
|
32685
|
+
hasher.update(JSON.stringify(rowObj, Object.keys(rowObj).sort()));
|
|
32489
32686
|
}
|
|
32490
32687
|
return {
|
|
32491
32688
|
count: rows.length,
|
|
@@ -32590,7 +32787,7 @@ function foreignKeyCheck(db, scope) {
|
|
|
32590
32787
|
try {
|
|
32591
32788
|
const rows = db.prepare("PRAGMA foreign_key_check").all();
|
|
32592
32789
|
if (rows.length > 0) {
|
|
32593
|
-
|
|
32790
|
+
log3.warn(
|
|
32594
32791
|
{ scope, count: rows.length, sample: rows.slice(0, 5) },
|
|
32595
32792
|
`verifyMigration: PRAGMA foreign_key_check found ${rows.length} orphan row(s)`
|
|
32596
32793
|
);
|
|
@@ -32602,7 +32799,7 @@ function foreignKeyCheck(db, scope) {
|
|
|
32602
32799
|
fkid: r.fkid
|
|
32603
32800
|
}));
|
|
32604
32801
|
} catch (err) {
|
|
32605
|
-
|
|
32802
|
+
log3.warn({ scope, err }, "verifyMigration: PRAGMA foreign_key_check failed (non-fatal)");
|
|
32606
32803
|
return [];
|
|
32607
32804
|
}
|
|
32608
32805
|
}
|
|
@@ -32639,13 +32836,13 @@ function sourceOrphanSignatures(db, sourceName, scope) {
|
|
|
32639
32836
|
const rows = db.prepare("PRAGMA foreign_key_check").all();
|
|
32640
32837
|
for (const r of rows) sigs.add(orphanSignature(db, r, sourceName));
|
|
32641
32838
|
if (rows.length > 0) {
|
|
32642
|
-
|
|
32839
|
+
log3.warn(
|
|
32643
32840
|
{ scope, count: rows.length, sample: rows.slice(0, 5) },
|
|
32644
32841
|
`verifyMigration: source already has ${rows.length} pre-existing FK orphan(s) \u2014 these are tolerated (carried forward losslessly, flagged for data-hygiene)`
|
|
32645
32842
|
);
|
|
32646
32843
|
}
|
|
32647
32844
|
} catch (err) {
|
|
32648
|
-
|
|
32845
|
+
log3.warn({ scope, err }, "verifyMigration: source PRAGMA foreign_key_check failed (non-fatal)");
|
|
32649
32846
|
}
|
|
32650
32847
|
return sigs;
|
|
32651
32848
|
}
|
|
@@ -32657,7 +32854,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
32657
32854
|
const preExistingForeignKeyViolations = [];
|
|
32658
32855
|
const failureLines = [];
|
|
32659
32856
|
const sourceOrphanSigs = /* @__PURE__ */ new Set();
|
|
32660
|
-
if (!
|
|
32857
|
+
if (!existsSync7(projectDbPath)) {
|
|
32661
32858
|
return {
|
|
32662
32859
|
ok: false,
|
|
32663
32860
|
tables: [],
|
|
@@ -32668,7 +32865,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
32668
32865
|
error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
|
|
32669
32866
|
};
|
|
32670
32867
|
}
|
|
32671
|
-
if (!
|
|
32868
|
+
if (!existsSync7(globalDbPath)) {
|
|
32672
32869
|
return {
|
|
32673
32870
|
ok: false,
|
|
32674
32871
|
tables: [],
|
|
@@ -32683,7 +32880,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
32683
32880
|
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
32684
32881
|
try {
|
|
32685
32882
|
for (const src of sources) {
|
|
32686
|
-
if (!
|
|
32883
|
+
if (!existsSync7(src.path)) {
|
|
32687
32884
|
onProgress?.(`Skipping ${src.name} (not present)`);
|
|
32688
32885
|
continue;
|
|
32689
32886
|
}
|
|
@@ -32762,7 +32959,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
32762
32959
|
`[${scope}] ${src.name}.${legacyTableName} \u2192 ${targetTableName}: DEFICIT \u2014 source=${srcDigest.count} rows, target=${tgtDigest.count} rows (${srcDigest.count - tgtDigest.count} missing), hashMatch=${hashMatch}`
|
|
32763
32960
|
);
|
|
32764
32961
|
} else if (tgtDigest.count > srcDigest.count) {
|
|
32765
|
-
|
|
32962
|
+
log3.warn(
|
|
32766
32963
|
{
|
|
32767
32964
|
scope,
|
|
32768
32965
|
source: src.name,
|
|
@@ -32812,7 +33009,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
32812
33009
|
}
|
|
32813
33010
|
}
|
|
32814
33011
|
if (preExistingForeignKeyViolations.length > 0) {
|
|
32815
|
-
|
|
33012
|
+
log3.warn(
|
|
32816
33013
|
{
|
|
32817
33014
|
count: preExistingForeignKeyViolations.length,
|
|
32818
33015
|
sample: preExistingForeignKeyViolations.slice(0, 5)
|
|
@@ -32822,7 +33019,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
32822
33019
|
}
|
|
32823
33020
|
} catch (err) {
|
|
32824
33021
|
const error = err instanceof Error ? err.message : String(err);
|
|
32825
|
-
|
|
33022
|
+
log3.error({ err }, "verifyMigration failed");
|
|
32826
33023
|
return {
|
|
32827
33024
|
ok: false,
|
|
32828
33025
|
tables,
|
|
@@ -32839,7 +33036,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
32839
33036
|
if (failureLines.length > 0) {
|
|
32840
33037
|
const error = `verifyMigration FAILED: ${failureLines.length} issue(s):
|
|
32841
33038
|
${failureLines.map((l) => ` \u2022 ${l}`).join("\n")}`;
|
|
32842
|
-
|
|
33039
|
+
log3.error({ failureCount: failureLines.length }, error);
|
|
32843
33040
|
return {
|
|
32844
33041
|
ok: false,
|
|
32845
33042
|
tables,
|
|
@@ -32859,7 +33056,7 @@ ${failureLines.map((l) => ` \u2022 ${l}`).join("\n")}`;
|
|
|
32859
33056
|
enumDrift
|
|
32860
33057
|
};
|
|
32861
33058
|
}
|
|
32862
|
-
var
|
|
33059
|
+
var log3, _require, CHECK_ENUM_REGEX;
|
|
32863
33060
|
var init_verify_migration = __esm({
|
|
32864
33061
|
"packages/core/src/store/exodus/verify-migration.ts"() {
|
|
32865
33062
|
"use strict";
|
|
@@ -32867,7 +33064,7 @@ var init_verify_migration = __esm({
|
|
|
32867
33064
|
init_logger2();
|
|
32868
33065
|
init_open_cleo_db();
|
|
32869
33066
|
init_table_name_map();
|
|
32870
|
-
|
|
33067
|
+
log3 = getLogger("verify-migration");
|
|
32871
33068
|
_require = createRequire3(import.meta.url);
|
|
32872
33069
|
CHECK_ENUM_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+(?:IS\s+NULL\s+OR\s+"[^"]+"\s+)?IN\s*\(([^)]*)\)\s*\)/gi;
|
|
32873
33070
|
}
|
|
@@ -32907,9 +33104,16 @@ var init_verify = __esm({
|
|
|
32907
33104
|
var exodus_exports = {};
|
|
32908
33105
|
__export(exodus_exports, {
|
|
32909
33106
|
EXODUS_TARGET_SCHEMA_VERSION: () => EXODUS_TARGET_SCHEMA_VERSION,
|
|
33107
|
+
archiveMigratedSources: () => archiveMigratedSources,
|
|
33108
|
+
archiveSourceDb: () => archiveSourceDb,
|
|
33109
|
+
archiveStrandedResidue: () => archiveStrandedResidue,
|
|
32910
33110
|
buildExodusPlan: () => buildExodusPlan,
|
|
32911
33111
|
clearExodusJournal: () => clearExodusJournal,
|
|
32912
33112
|
deriveStagingDirName: () => deriveStagingDirName,
|
|
33113
|
+
detectStrandedResidue: () => detectStrandedResidue,
|
|
33114
|
+
exodusArchiveDir: () => exodusArchiveDir,
|
|
33115
|
+
exodusMarkerPath: () => exodusMarkerPath,
|
|
33116
|
+
hasExodusCompleteMarker: () => hasExodusCompleteMarker,
|
|
32913
33117
|
isDerivedOrInternalTable: () => isDerivedOrInternalTable,
|
|
32914
33118
|
resolveConsolidatedTableName: () => resolveConsolidatedTableName,
|
|
32915
33119
|
reverseLookup: () => reverseLookup,
|
|
@@ -32917,11 +33121,13 @@ __export(exodus_exports, {
|
|
|
32917
33121
|
runExodusStatus: () => runExodusStatus,
|
|
32918
33122
|
runExodusVerify: () => runExodusVerify,
|
|
32919
33123
|
sourcesPresent: () => sourcesPresent,
|
|
32920
|
-
verifyMigration: () => verifyMigration
|
|
33124
|
+
verifyMigration: () => verifyMigration,
|
|
33125
|
+
writeExodusCompleteMarker: () => writeExodusCompleteMarker
|
|
32921
33126
|
});
|
|
32922
33127
|
var init_exodus = __esm({
|
|
32923
33128
|
"packages/core/src/store/exodus/index.ts"() {
|
|
32924
33129
|
"use strict";
|
|
33130
|
+
init_archive2();
|
|
32925
33131
|
init_migrate();
|
|
32926
33132
|
init_plan2();
|
|
32927
33133
|
init_status();
|
|
@@ -32939,7 +33145,7 @@ __export(on_open_exports, {
|
|
|
32939
33145
|
isDataContinuityOk: () => isDataContinuityOk,
|
|
32940
33146
|
maybeRunExodusOnOpen: () => maybeRunExodusOnOpen
|
|
32941
33147
|
});
|
|
32942
|
-
import { existsSync as
|
|
33148
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
32943
33149
|
function isDisabledByEnv() {
|
|
32944
33150
|
const v = process.env.CLEO_DISABLE_EXODUS_ON_OPEN;
|
|
32945
33151
|
return v === "1" || v === "true";
|
|
@@ -32965,7 +33171,7 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
|
|
|
32965
33171
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%'"
|
|
32966
33172
|
).all().map((r) => r.name);
|
|
32967
33173
|
} catch (err) {
|
|
32968
|
-
|
|
33174
|
+
log4.error({ err, scope }, "exodus-on-open: failed to enumerate tables for rollback");
|
|
32969
33175
|
return;
|
|
32970
33176
|
}
|
|
32971
33177
|
try {
|
|
@@ -32975,7 +33181,7 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
|
|
|
32975
33181
|
try {
|
|
32976
33182
|
nativeDb.exec(`DELETE FROM "${table}"`);
|
|
32977
33183
|
} catch (err) {
|
|
32978
|
-
|
|
33184
|
+
log4.warn({ err, table, scope }, "exodus-on-open: failed to clear table during rollback");
|
|
32979
33185
|
}
|
|
32980
33186
|
}
|
|
32981
33187
|
nativeDb.exec("COMMIT");
|
|
@@ -32984,7 +33190,7 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
|
|
|
32984
33190
|
nativeDb.exec("ROLLBACK");
|
|
32985
33191
|
} catch {
|
|
32986
33192
|
}
|
|
32987
|
-
|
|
33193
|
+
log4.error({ err, scope }, "exodus-on-open: rollback transaction failed");
|
|
32988
33194
|
} finally {
|
|
32989
33195
|
try {
|
|
32990
33196
|
nativeDb.exec("PRAGMA foreign_keys = ON");
|
|
@@ -32992,20 +33198,27 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
|
|
|
32992
33198
|
}
|
|
32993
33199
|
}
|
|
32994
33200
|
}
|
|
32995
|
-
async function rollbackBothScopes(scope) {
|
|
32996
|
-
const {
|
|
33201
|
+
async function rollbackBothScopes(scope, projectDbPath, globalDbPath) {
|
|
33202
|
+
const { openDualScopeDbAtPath: openDualScopeDbAtPath2 } = await Promise.resolve().then(() => (init_dual_scope_db(), dual_scope_db_exports));
|
|
32997
33203
|
for (const s of ["project", "global"]) {
|
|
33204
|
+
const path = s === "project" ? projectDbPath : globalDbPath;
|
|
33205
|
+
let handle = null;
|
|
32998
33206
|
try {
|
|
32999
|
-
|
|
33207
|
+
handle = s === "project" ? await openDualScopeDbAtPath2("project", path, void 0, { dedicated: true }) : await openDualScopeDbAtPath2("global", path, void 0, { dedicated: true });
|
|
33000
33208
|
const native = handle.db.$client;
|
|
33001
33209
|
if (native) {
|
|
33002
33210
|
rollbackConsolidatedToEmpty(native, s);
|
|
33003
33211
|
}
|
|
33004
33212
|
} catch (err) {
|
|
33005
|
-
|
|
33213
|
+
log4.warn(
|
|
33006
33214
|
{ err, scope: s, openingScope: scope },
|
|
33007
33215
|
"exodus-on-open: could not roll back scope (best-effort)"
|
|
33008
33216
|
);
|
|
33217
|
+
} finally {
|
|
33218
|
+
try {
|
|
33219
|
+
handle?.close();
|
|
33220
|
+
} catch {
|
|
33221
|
+
}
|
|
33009
33222
|
}
|
|
33010
33223
|
}
|
|
33011
33224
|
}
|
|
@@ -33013,7 +33226,7 @@ function isDataContinuityOk(result) {
|
|
|
33013
33226
|
const deficits = result.tables.filter((t) => t.targetCount < t.sourceCount);
|
|
33014
33227
|
const surpluses = result.tables.filter((t) => t.targetCount > t.sourceCount);
|
|
33015
33228
|
if (surpluses.length > 0) {
|
|
33016
|
-
|
|
33229
|
+
log4.warn(
|
|
33017
33230
|
{
|
|
33018
33231
|
surpluses: surpluses.map((t) => ({
|
|
33019
33232
|
table: t.targetTable,
|
|
@@ -33035,13 +33248,19 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
33035
33248
|
if (isDisabledByEnv()) {
|
|
33036
33249
|
return { outcome: "skipped", reason: "CLEO_DISABLE_EXODUS_ON_OPEN set" };
|
|
33037
33250
|
}
|
|
33251
|
+
if (hasExodusCompleteMarker(scope, cwd)) {
|
|
33252
|
+
return {
|
|
33253
|
+
outcome: "skipped",
|
|
33254
|
+
reason: "exodus completion marker present \u2014 scope already migrated (cutover sealed)"
|
|
33255
|
+
};
|
|
33256
|
+
}
|
|
33038
33257
|
if (!consolidatedIsEmpty(nativeDb, scope)) {
|
|
33039
33258
|
return { outcome: "skipped", reason: "consolidated cleo.db already populated" };
|
|
33040
33259
|
}
|
|
33041
33260
|
const { buildExodusPlan: buildExodusPlan2, runExodusMigrate: runExodusMigrate2, verifyMigration: verifyMigration2, clearExodusJournal: clearExodusJournal2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
|
|
33042
33261
|
const plan = buildExodusPlan2(cwd);
|
|
33043
33262
|
const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
|
|
33044
|
-
if (!scopeSources.some((s) =>
|
|
33263
|
+
if (!scopeSources.some((s) => existsSync8(s.path))) {
|
|
33045
33264
|
return {
|
|
33046
33265
|
outcome: "skipped",
|
|
33047
33266
|
reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
|
|
@@ -33054,11 +33273,11 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
33054
33273
|
if (!consolidatedIsEmpty(nativeDb, scope)) {
|
|
33055
33274
|
return { outcome: "skipped", reason: "migrated by a concurrent process (lock winner)" };
|
|
33056
33275
|
}
|
|
33057
|
-
|
|
33276
|
+
log4.info(
|
|
33058
33277
|
{
|
|
33059
33278
|
scope,
|
|
33060
33279
|
dbPath,
|
|
33061
|
-
sources: plan.sources.filter((s) =>
|
|
33280
|
+
sources: plan.sources.filter((s) => existsSync8(s.path)).map((s) => s.name)
|
|
33062
33281
|
},
|
|
33063
33282
|
"exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
|
|
33064
33283
|
);
|
|
@@ -33067,23 +33286,23 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
33067
33286
|
const migrateResult = await runExodusMigrate2(
|
|
33068
33287
|
plan,
|
|
33069
33288
|
false,
|
|
33070
|
-
(msg) =>
|
|
33289
|
+
(msg) => log4.debug({ scope }, `exodus-on-open: ${msg}`)
|
|
33071
33290
|
);
|
|
33072
33291
|
if (!migrateResult.ok) {
|
|
33073
|
-
await rollbackBothScopes(scope);
|
|
33292
|
+
await rollbackBothScopes(scope, plan.projectDbPath, plan.globalDbPath);
|
|
33074
33293
|
clearExodusJournal2(migrateResult.stagingDir);
|
|
33075
33294
|
const reason = `migration failed: ${migrateResult.error ?? "unknown error"} \u2014 legacy DBs kept as source`;
|
|
33076
|
-
|
|
33295
|
+
log4.error({ scope, error: migrateResult.error }, `exodus-on-open: ${reason}`);
|
|
33077
33296
|
return { outcome: "aborted", reason };
|
|
33078
33297
|
}
|
|
33079
33298
|
const verifyResult = verifyMigration2(
|
|
33080
33299
|
plan.sources,
|
|
33081
33300
|
plan.projectDbPath,
|
|
33082
33301
|
plan.globalDbPath,
|
|
33083
|
-
(msg) =>
|
|
33302
|
+
(msg) => log4.debug({ scope }, `exodus-on-open verify: ${msg}`)
|
|
33084
33303
|
);
|
|
33085
33304
|
if (!verifyResult.ok) {
|
|
33086
|
-
|
|
33305
|
+
log4.warn(
|
|
33087
33306
|
{
|
|
33088
33307
|
scope,
|
|
33089
33308
|
enumDrift: verifyResult.enumDrift.length,
|
|
@@ -33093,11 +33312,11 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
33093
33312
|
);
|
|
33094
33313
|
}
|
|
33095
33314
|
if (!isDataContinuityOk(verifyResult)) {
|
|
33096
|
-
await rollbackBothScopes(scope);
|
|
33315
|
+
await rollbackBothScopes(scope, plan.projectDbPath, plan.globalDbPath);
|
|
33097
33316
|
clearExodusJournal2(plan.stagingDir);
|
|
33098
33317
|
const deficits = verifyResult.tables.filter((t) => t.targetCount < t.sourceCount).map((t) => `${t.targetTable}(${t.sourceCount}\u2192${t.targetCount})`);
|
|
33099
33318
|
const reason = `parity verification failed \u2014 cutover aborted, legacy DBs kept as source. count deficits: [${deficits.join(", ")}]; INTRODUCED fk orphans: ${verifyResult.introducedForeignKeyViolations.length} (pre-existing source orphans tolerated: ${verifyResult.preExistingForeignKeyViolations.length}). ` + `${verifyResult.error ?? ""}`.trim();
|
|
33100
|
-
|
|
33319
|
+
log4.error(
|
|
33101
33320
|
{
|
|
33102
33321
|
scope,
|
|
33103
33322
|
countDeficits: deficits,
|
|
@@ -33109,10 +33328,27 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
33109
33328
|
return { outcome: "aborted", reason };
|
|
33110
33329
|
}
|
|
33111
33330
|
const rowsCopied = migrateResult.tables.filter((t) => !t.skipped).reduce((n, t) => n + t.rowsCopied, 0);
|
|
33112
|
-
|
|
33331
|
+
log4.info(
|
|
33113
33332
|
{ scope, rowsCopied, tables: migrateResult.tables.length },
|
|
33114
33333
|
"exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
|
|
33115
33334
|
);
|
|
33335
|
+
try {
|
|
33336
|
+
const consumed = plan.sources.filter((s) => existsSync8(s.path));
|
|
33337
|
+
const archiveResult = archiveMigratedSources(consumed, cwd);
|
|
33338
|
+
log4.info(
|
|
33339
|
+
{
|
|
33340
|
+
scope,
|
|
33341
|
+
archived: archiveResult.sources.filter((s) => s.action === "archived").length,
|
|
33342
|
+
markersWritten: archiveResult.markersWritten
|
|
33343
|
+
},
|
|
33344
|
+
"exodus-on-open: archived legacy sources + sealed completion marker(s)"
|
|
33345
|
+
);
|
|
33346
|
+
} catch (err) {
|
|
33347
|
+
log4.error(
|
|
33348
|
+
{ err, scope },
|
|
33349
|
+
"exodus-on-open: post-migration archive/marker step failed (migration itself succeeded \u2014 legacy DBs left in place, will be re-checked by `cleo doctor exodus-residue`)"
|
|
33350
|
+
);
|
|
33351
|
+
}
|
|
33116
33352
|
return {
|
|
33117
33353
|
outcome: "migrated",
|
|
33118
33354
|
reason: `migrated ${rowsCopied} rows across ${migrateResult.tables.length} tables; parity verified`,
|
|
@@ -33130,13 +33366,14 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
|
|
|
33130
33366
|
function _isExodusInProgress() {
|
|
33131
33367
|
return _exodusInProgress;
|
|
33132
33368
|
}
|
|
33133
|
-
var
|
|
33369
|
+
var log4, _exodusInProgress;
|
|
33134
33370
|
var init_on_open = __esm({
|
|
33135
33371
|
"packages/core/src/store/exodus/on-open.ts"() {
|
|
33136
33372
|
"use strict";
|
|
33137
33373
|
init_logger2();
|
|
33138
33374
|
init_lock();
|
|
33139
|
-
|
|
33375
|
+
init_archive2();
|
|
33376
|
+
log4 = getLogger("exodus-on-open");
|
|
33140
33377
|
_exodusInProgress = false;
|
|
33141
33378
|
}
|
|
33142
33379
|
});
|
|
@@ -33151,17 +33388,17 @@ __export(dual_scope_db_exports, {
|
|
|
33151
33388
|
resolveDualScopeDbPath: () => resolveDualScopeDbPath,
|
|
33152
33389
|
upsertIdempotent: () => upsertIdempotent
|
|
33153
33390
|
});
|
|
33154
|
-
import { existsSync as
|
|
33391
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3 } from "node:fs";
|
|
33155
33392
|
import { createRequire as createRequire4 } from "node:module";
|
|
33156
|
-
import { dirname as dirname4, join as
|
|
33393
|
+
import { dirname as dirname4, join as join10 } from "node:path";
|
|
33157
33394
|
function cacheKey(scope, dbPath) {
|
|
33158
33395
|
return `${scope}::${dbPath}`;
|
|
33159
33396
|
}
|
|
33160
33397
|
function resolveDualScopeDbPath(scope, cwd) {
|
|
33161
33398
|
if (scope === "project") {
|
|
33162
|
-
return
|
|
33399
|
+
return join10(resolveCleoDir(cwd), "cleo.db");
|
|
33163
33400
|
}
|
|
33164
|
-
return
|
|
33401
|
+
return join10(getCleoHome(), "cleo.db");
|
|
33165
33402
|
}
|
|
33166
33403
|
function migrationsSetName(scope) {
|
|
33167
33404
|
return scope === "project" ? "drizzle-cleo-project" : "drizzle-cleo-global";
|
|
@@ -33199,21 +33436,61 @@ async function openDualScopeDb(scope, cwd) {
|
|
|
33199
33436
|
const dbPath = resolveDualScopeDbPath(scope, cwd);
|
|
33200
33437
|
return scope === "project" ? openDualScopeDbAtPath("project", dbPath, cwd) : openDualScopeDbAtPath("global", dbPath, cwd);
|
|
33201
33438
|
}
|
|
33202
|
-
async function
|
|
33439
|
+
async function openDedicatedDualScopeDb(scope, dbPath, log5) {
|
|
33440
|
+
log5.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
|
|
33441
|
+
const dir = dirname4(dbPath);
|
|
33442
|
+
if (!existsSync9(dir)) {
|
|
33443
|
+
mkdirSync3(dir, { recursive: true });
|
|
33444
|
+
}
|
|
33445
|
+
const DatabaseSyncCtor = getDatabaseSyncCtor();
|
|
33446
|
+
const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
|
|
33447
|
+
applyPerfPragmas(nativeDb);
|
|
33448
|
+
const schema = scope === "project" ? await loadProjectSchema() : await loadGlobalSchema();
|
|
33449
|
+
const drizzle2 = getDrizzle();
|
|
33450
|
+
const db = drizzle2({ client: nativeDb, schema });
|
|
33451
|
+
const migrationsFolder = resolveCorePackageMigrationsFolder(migrationsSetName(scope));
|
|
33452
|
+
reconcileJournal(nativeDb, migrationsFolder, existenceTable(scope), `dual-scope-db[${scope}]`);
|
|
33453
|
+
migrateWithRetry(
|
|
33454
|
+
db,
|
|
33455
|
+
migrationsFolder,
|
|
33456
|
+
nativeDb,
|
|
33457
|
+
existenceTable(scope),
|
|
33458
|
+
`dual-scope-db[${scope}]`
|
|
33459
|
+
);
|
|
33460
|
+
log5.debug({ scope, dbPath }, "DEDICATED dual-scope cleo.db ready (T11782 FIX D)");
|
|
33461
|
+
return {
|
|
33462
|
+
db,
|
|
33463
|
+
scope,
|
|
33464
|
+
dbPath,
|
|
33465
|
+
close() {
|
|
33466
|
+
try {
|
|
33467
|
+
nativeDb.close();
|
|
33468
|
+
} catch {
|
|
33469
|
+
}
|
|
33470
|
+
}
|
|
33471
|
+
};
|
|
33472
|
+
}
|
|
33473
|
+
async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
|
|
33474
|
+
const dedicated = options?.dedicated === true;
|
|
33203
33475
|
const key = cacheKey(scope, dbPath);
|
|
33204
|
-
|
|
33205
|
-
|
|
33206
|
-
if (existing
|
|
33207
|
-
|
|
33476
|
+
if (!dedicated) {
|
|
33477
|
+
const existing = _cache.get(key);
|
|
33478
|
+
if (existing) {
|
|
33479
|
+
if (existing.initPromise) {
|
|
33480
|
+
return existing.initPromise;
|
|
33481
|
+
}
|
|
33482
|
+
return existing.handle;
|
|
33208
33483
|
}
|
|
33209
|
-
return existing.handle;
|
|
33210
33484
|
}
|
|
33211
|
-
const
|
|
33485
|
+
const log5 = getLogger("dual-scope-db");
|
|
33486
|
+
if (dedicated) {
|
|
33487
|
+
return openDedicatedDualScopeDb(scope, dbPath, log5);
|
|
33488
|
+
}
|
|
33212
33489
|
const initPromise = (async () => {
|
|
33213
|
-
|
|
33490
|
+
log5.debug({ scope, dbPath }, "opening dual-scope cleo.db");
|
|
33214
33491
|
const dir = dirname4(dbPath);
|
|
33215
|
-
if (!
|
|
33216
|
-
|
|
33492
|
+
if (!existsSync9(dir)) {
|
|
33493
|
+
mkdirSync3(dir, { recursive: true });
|
|
33217
33494
|
}
|
|
33218
33495
|
const DatabaseSyncCtor = getDatabaseSyncCtor();
|
|
33219
33496
|
const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
|
|
@@ -33230,7 +33507,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd) {
|
|
|
33230
33507
|
existenceTable(scope),
|
|
33231
33508
|
`dual-scope-db[${scope}]`
|
|
33232
33509
|
);
|
|
33233
|
-
|
|
33510
|
+
log5.debug({ scope, dbPath }, "dual-scope cleo.db ready");
|
|
33234
33511
|
const handle = {
|
|
33235
33512
|
db,
|
|
33236
33513
|
scope,
|
|
@@ -33254,7 +33531,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd) {
|
|
|
33254
33531
|
const result = await maybeRunExodusOnOpen2(scope, dbPath, nativeDb, exodusCwd);
|
|
33255
33532
|
if (result.outcome === "migrated" || result.outcome === "aborted") {
|
|
33256
33533
|
if (result.outcome === "aborted") {
|
|
33257
|
-
|
|
33534
|
+
log5.warn(
|
|
33258
33535
|
{ scope, reason: result.reason },
|
|
33259
33536
|
"exodus-on-open aborted; consolidated cleo.db left empty, legacy kept as source"
|
|
33260
33537
|
);
|
|
@@ -33262,7 +33539,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd) {
|
|
|
33262
33539
|
return scope === "project" ? openDualScopeDbAtPath("project", dbPath) : openDualScopeDbAtPath("global", dbPath);
|
|
33263
33540
|
}
|
|
33264
33541
|
} catch (err) {
|
|
33265
|
-
|
|
33542
|
+
log5.warn(
|
|
33266
33543
|
{ err, scope },
|
|
33267
33544
|
"exodus-on-open hook failed (non-fatal); re-opening consolidated handle"
|
|
33268
33545
|
);
|
|
@@ -33846,8 +34123,8 @@ __export(nexus_sqlite_exports, {
|
|
|
33846
34123
|
resetNexusDbState: () => resetNexusDbState,
|
|
33847
34124
|
resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
|
|
33848
34125
|
});
|
|
33849
|
-
import { copyFileSync as
|
|
33850
|
-
import { join as
|
|
34126
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync10 } from "node:fs";
|
|
34127
|
+
import { join as join11 } from "node:path";
|
|
33851
34128
|
function getNexusDbPath(cwd) {
|
|
33852
34129
|
return resolveDualScopeDbPath("project", cwd);
|
|
33853
34130
|
}
|
|
@@ -33879,7 +34156,7 @@ function resolveNexusMigrationsFolder() {
|
|
|
33879
34156
|
return resolveCorePackageMigrationsFolder("drizzle-nexus");
|
|
33880
34157
|
}
|
|
33881
34158
|
function getNestedNexusSentinelPath() {
|
|
33882
|
-
return
|
|
34159
|
+
return join11(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
|
|
33883
34160
|
}
|
|
33884
34161
|
function detectAndWarnOnNestedNexus() {
|
|
33885
34162
|
let nestedPath;
|
|
@@ -33888,12 +34165,12 @@ function detectAndWarnOnNestedNexus() {
|
|
|
33888
34165
|
} catch {
|
|
33889
34166
|
return false;
|
|
33890
34167
|
}
|
|
33891
|
-
if (!
|
|
34168
|
+
if (!existsSync10(nestedPath)) return false;
|
|
33892
34169
|
if (_warnedNestedPaths.has(nestedPath)) return false;
|
|
33893
34170
|
_warnedNestedPaths.add(nestedPath);
|
|
33894
34171
|
const canonicalPath = getNexusDbPath();
|
|
33895
|
-
const
|
|
33896
|
-
|
|
34172
|
+
const log5 = getLogger("nexus-sqlite");
|
|
34173
|
+
log5.warn(
|
|
33897
34174
|
{
|
|
33898
34175
|
nestedPath,
|
|
33899
34176
|
canonicalPath,
|
|
@@ -34047,9 +34324,9 @@ function runNexusMigrations(nativeDb, db) {
|
|
|
34047
34324
|
const migrationsFolder = resolveNexusMigrationsFolder();
|
|
34048
34325
|
if (tableExists3(nativeDb, "nexus_nodes") && _nexusDbPath) {
|
|
34049
34326
|
const backupPath = _nexusDbPath.replace(/\.db$/, "-pre-cleo.db.bak");
|
|
34050
|
-
if (!
|
|
34327
|
+
if (!existsSync10(backupPath)) {
|
|
34051
34328
|
try {
|
|
34052
|
-
|
|
34329
|
+
copyFileSync3(_nexusDbPath, backupPath);
|
|
34053
34330
|
} catch {
|
|
34054
34331
|
}
|
|
34055
34332
|
}
|
|
@@ -34179,10 +34456,10 @@ var init_nexus_sqlite = __esm({
|
|
|
34179
34456
|
|
|
34180
34457
|
// packages/core/src/paths.ts
|
|
34181
34458
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
34182
|
-
import { existsSync as
|
|
34459
|
+
import { existsSync as existsSync11, readFileSync as readFileSync4, statSync as statSync3 } from "node:fs";
|
|
34183
34460
|
import { createRequire as createRequire5 } from "node:module";
|
|
34184
34461
|
import { homedir } from "node:os";
|
|
34185
|
-
import { basename as
|
|
34462
|
+
import { basename as basename4, dirname as dirname5, join as join12, resolve as resolve3 } from "node:path";
|
|
34186
34463
|
import {
|
|
34187
34464
|
computeCanonicalProjectId as _computeCanonicalProjectId,
|
|
34188
34465
|
getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath,
|
|
@@ -34272,8 +34549,8 @@ function getCleoDirAbsolute(cwd, opts) {
|
|
|
34272
34549
|
function _resolveProjectByCwdFromNexus(cwd) {
|
|
34273
34550
|
try {
|
|
34274
34551
|
const cleoHome = getCleoHome();
|
|
34275
|
-
const globalDbPath =
|
|
34276
|
-
if (!
|
|
34552
|
+
const globalDbPath = join12(cleoHome, "cleo.db");
|
|
34553
|
+
if (!existsSync11(globalDbPath)) return null;
|
|
34277
34554
|
const start = resolve3(cwd ?? process.cwd());
|
|
34278
34555
|
let current = start;
|
|
34279
34556
|
const DatabaseSync2 = _getDatabaseSyncCtor();
|
|
@@ -34312,7 +34589,7 @@ function _findCleoDirRoot(cwd) {
|
|
|
34312
34589
|
const isDangerousRoot = current === homeRoot || current === "/" || current === "";
|
|
34313
34590
|
if (!isDangerousRoot) {
|
|
34314
34591
|
try {
|
|
34315
|
-
if (statSync3(
|
|
34592
|
+
if (statSync3(join12(current, ".cleo")).isDirectory()) {
|
|
34316
34593
|
return current;
|
|
34317
34594
|
}
|
|
34318
34595
|
} catch {
|
|
@@ -34327,7 +34604,7 @@ function _findCleoDirRoot(cwd) {
|
|
|
34327
34604
|
function resolveCleoDir(cwd) {
|
|
34328
34605
|
const scope = worktreeScope.getStore();
|
|
34329
34606
|
if (scope !== void 0) {
|
|
34330
|
-
return
|
|
34607
|
+
return join12(scope.worktreeRoot, ".cleo");
|
|
34331
34608
|
}
|
|
34332
34609
|
const override = _cleoDirEnvOverride();
|
|
34333
34610
|
if (override !== null) {
|
|
@@ -34335,14 +34612,14 @@ function resolveCleoDir(cwd) {
|
|
|
34335
34612
|
}
|
|
34336
34613
|
const root = _findCleoDirRoot(cwd);
|
|
34337
34614
|
if (root !== null) {
|
|
34338
|
-
return
|
|
34615
|
+
return join12(root, ".cleo");
|
|
34339
34616
|
}
|
|
34340
34617
|
const start = resolve3(cwd ?? process.cwd());
|
|
34341
34618
|
let current = start;
|
|
34342
34619
|
while (true) {
|
|
34343
34620
|
const mainRepo = _resolveMainRepoFromGitlink(current);
|
|
34344
34621
|
if (mainRepo !== null) {
|
|
34345
|
-
return
|
|
34622
|
+
return join12(mainRepo, ".cleo");
|
|
34346
34623
|
}
|
|
34347
34624
|
const parent = dirname5(current);
|
|
34348
34625
|
if (parent === current) {
|
|
@@ -34384,9 +34661,9 @@ function _cwdHasGitAncestor(cwd) {
|
|
|
34384
34661
|
const start = resolve3(cwd ?? process.cwd());
|
|
34385
34662
|
let current = start;
|
|
34386
34663
|
while (true) {
|
|
34387
|
-
const gitMarker =
|
|
34664
|
+
const gitMarker = join12(current, ".git");
|
|
34388
34665
|
try {
|
|
34389
|
-
if (
|
|
34666
|
+
if (existsSync11(gitMarker)) {
|
|
34390
34667
|
return true;
|
|
34391
34668
|
}
|
|
34392
34669
|
} catch {
|
|
@@ -34398,8 +34675,8 @@ function _cwdHasGitAncestor(cwd) {
|
|
|
34398
34675
|
}
|
|
34399
34676
|
function _resolveMainRepoFromGitlink(gitlinkDir) {
|
|
34400
34677
|
try {
|
|
34401
|
-
const gitLinkPath =
|
|
34402
|
-
if (!
|
|
34678
|
+
const gitLinkPath = join12(gitlinkDir, ".git");
|
|
34679
|
+
if (!existsSync11(gitLinkPath)) return null;
|
|
34403
34680
|
const stat2 = statSync3(gitLinkPath);
|
|
34404
34681
|
if (!stat2.isFile()) return null;
|
|
34405
34682
|
const gitLinkContent = readFileSync4(gitLinkPath, "utf-8").trim();
|
|
@@ -34407,7 +34684,7 @@ function _resolveMainRepoFromGitlink(gitlinkDir) {
|
|
|
34407
34684
|
if (!match) return null;
|
|
34408
34685
|
const gitdir = match[1].trim();
|
|
34409
34686
|
const mainRepo = dirname5(dirname5(dirname5(gitdir)));
|
|
34410
|
-
if (
|
|
34687
|
+
if (existsSync11(join12(mainRepo, ".cleo")) && validateProjectRoot(mainRepo)) {
|
|
34411
34688
|
return mainRepo;
|
|
34412
34689
|
}
|
|
34413
34690
|
} catch {
|
|
@@ -34415,18 +34692,18 @@ function _resolveMainRepoFromGitlink(gitlinkDir) {
|
|
|
34415
34692
|
return null;
|
|
34416
34693
|
}
|
|
34417
34694
|
function validateProjectRoot(candidate) {
|
|
34418
|
-
const cleoDir =
|
|
34419
|
-
if (!
|
|
34695
|
+
const cleoDir = join12(candidate, ".cleo");
|
|
34696
|
+
if (!existsSync11(cleoDir)) {
|
|
34420
34697
|
return false;
|
|
34421
34698
|
}
|
|
34422
|
-
const projectInfoPath =
|
|
34423
|
-
if (
|
|
34699
|
+
const projectInfoPath = join12(cleoDir, "project-info.json");
|
|
34700
|
+
if (existsSync11(projectInfoPath)) {
|
|
34424
34701
|
try {
|
|
34425
34702
|
const raw = readFileSync4(projectInfoPath, "utf-8");
|
|
34426
34703
|
const parsed = JSON.parse(raw);
|
|
34427
34704
|
if (typeof parsed === "object" && parsed !== null && "projectId" in parsed && typeof parsed["projectId"] === "string" && parsed["projectId"] !== "") {
|
|
34428
|
-
const gitMarker =
|
|
34429
|
-
if (
|
|
34705
|
+
const gitMarker = join12(candidate, ".git");
|
|
34706
|
+
if (existsSync11(gitMarker)) {
|
|
34430
34707
|
try {
|
|
34431
34708
|
if (!statSync3(gitMarker).isDirectory()) {
|
|
34432
34709
|
return false;
|
|
@@ -34440,8 +34717,8 @@ function validateProjectRoot(candidate) {
|
|
|
34440
34717
|
} catch {
|
|
34441
34718
|
}
|
|
34442
34719
|
}
|
|
34443
|
-
const gitDir =
|
|
34444
|
-
if (
|
|
34720
|
+
const gitDir = join12(candidate, ".git");
|
|
34721
|
+
if (existsSync11(gitDir)) {
|
|
34445
34722
|
let isRealGitDir = false;
|
|
34446
34723
|
try {
|
|
34447
34724
|
const stat2 = statSync3(gitDir);
|
|
@@ -34488,16 +34765,16 @@ function getProjectRoot(cwd) {
|
|
|
34488
34765
|
const homeRoot = homedir();
|
|
34489
34766
|
const skippedCleoDirs = [];
|
|
34490
34767
|
while (true) {
|
|
34491
|
-
const cleoDir =
|
|
34492
|
-
const gitDir =
|
|
34768
|
+
const cleoDir = join12(current, ".cleo");
|
|
34769
|
+
const gitDir = join12(current, ".git");
|
|
34493
34770
|
const isDangerousRoot = current === homeRoot || current === "/" || current === "";
|
|
34494
|
-
if (
|
|
34771
|
+
if (existsSync11(cleoDir) && !isDangerousRoot) {
|
|
34495
34772
|
if (validateProjectRoot(current)) {
|
|
34496
34773
|
return current;
|
|
34497
34774
|
}
|
|
34498
34775
|
skippedCleoDirs.push(current);
|
|
34499
34776
|
}
|
|
34500
|
-
if (
|
|
34777
|
+
if (existsSync11(gitDir) && !isDangerousRoot) {
|
|
34501
34778
|
let isRealGitDir = false;
|
|
34502
34779
|
try {
|
|
34503
34780
|
isRealGitDir = statSync3(gitDir).isDirectory();
|
|
@@ -34542,18 +34819,18 @@ function resolveOrCwd(maybeRoot) {
|
|
|
34542
34819
|
return getProjectRoot();
|
|
34543
34820
|
}
|
|
34544
34821
|
function getConfigPath(cwd) {
|
|
34545
|
-
return
|
|
34822
|
+
return join12(_resolveCleoDir(cwd), "config.json");
|
|
34546
34823
|
}
|
|
34547
34824
|
function getGlobalConfigPath() {
|
|
34548
|
-
return
|
|
34825
|
+
return join12(getCleoHome(), "config.json");
|
|
34549
34826
|
}
|
|
34550
34827
|
function isAbsolutePath(path) {
|
|
34551
34828
|
return _isAbsolutePath(path);
|
|
34552
34829
|
}
|
|
34553
34830
|
function _readProjectNameFromInfo(projectRoot) {
|
|
34554
34831
|
try {
|
|
34555
|
-
const infoPath =
|
|
34556
|
-
if (!
|
|
34832
|
+
const infoPath = join12(projectRoot, ".cleo", "project-info.json");
|
|
34833
|
+
if (!existsSync11(infoPath)) return void 0;
|
|
34557
34834
|
const raw = readFileSync4(infoPath, "utf-8");
|
|
34558
34835
|
const data = JSON.parse(raw);
|
|
34559
34836
|
return typeof data.name === "string" && data.name.length > 0 ? data.name : void 0;
|
|
@@ -34575,12 +34852,12 @@ async function registerProjectOnEncounter(projectRoot, infoProjectId) {
|
|
|
34575
34852
|
const existingRows = await db.select().from(projectRegistry2).where(eq2(projectRegistry2.projectId, immutableId)).limit(1);
|
|
34576
34853
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
34577
34854
|
const resolvedPath = resolve3(projectRoot);
|
|
34578
|
-
const projectName = _readProjectNameFromInfo(resolvedPath) ||
|
|
34855
|
+
const projectName = _readProjectNameFromInfo(resolvedPath) || basename4(projectRoot) || "unnamed";
|
|
34579
34856
|
if (existingRows.length > 0) {
|
|
34580
34857
|
const existingPath = existingRows[0].projectPath;
|
|
34581
34858
|
if (existingPath !== resolvedPath) {
|
|
34582
|
-
const newBrainDbPath =
|
|
34583
|
-
const newTasksDbPath =
|
|
34859
|
+
const newBrainDbPath = join12(resolvedPath, ".cleo", "brain.db");
|
|
34860
|
+
const newTasksDbPath = join12(resolvedPath, ".cleo", "tasks.db");
|
|
34584
34861
|
await db.update(projectRegistry2).set({
|
|
34585
34862
|
projectPath: resolvedPath,
|
|
34586
34863
|
projectHash: generateProjectHash2(resolvedPath),
|
|
@@ -34611,8 +34888,8 @@ async function registerProjectOnEncounter(projectRoot, infoProjectId) {
|
|
|
34611
34888
|
lastSync: now,
|
|
34612
34889
|
taskCount: 0,
|
|
34613
34890
|
labelsJson: "[]",
|
|
34614
|
-
brainDbPath:
|
|
34615
|
-
tasksDbPath:
|
|
34891
|
+
brainDbPath: join12(resolvedPath, ".cleo", "brain.db"),
|
|
34892
|
+
tasksDbPath: join12(resolvedPath, ".cleo", "tasks.db"),
|
|
34616
34893
|
statsJson: "{}"
|
|
34617
34894
|
}).onConflictDoNothing();
|
|
34618
34895
|
const aliases = canonicalResult.legacyAliases ?? [];
|
|
@@ -34645,46 +34922,46 @@ var init_paths = __esm({
|
|
|
34645
34922
|
// packages/core/src/store/file-utils.ts
|
|
34646
34923
|
import { randomBytes } from "node:crypto";
|
|
34647
34924
|
import {
|
|
34648
|
-
existsSync as
|
|
34649
|
-
mkdirSync as
|
|
34925
|
+
existsSync as existsSync12,
|
|
34926
|
+
mkdirSync as mkdirSync4,
|
|
34650
34927
|
readdirSync as readdirSync4,
|
|
34651
34928
|
readFileSync as readFileSync5,
|
|
34652
|
-
renameSync as
|
|
34653
|
-
unlinkSync as
|
|
34654
|
-
writeFileSync as
|
|
34929
|
+
renameSync as renameSync3,
|
|
34930
|
+
unlinkSync as unlinkSync3,
|
|
34931
|
+
writeFileSync as writeFileSync3
|
|
34655
34932
|
} from "node:fs";
|
|
34656
|
-
import { basename as
|
|
34933
|
+
import { basename as basename5, dirname as dirname6, join as join13 } from "node:path";
|
|
34657
34934
|
import * as lockfile2 from "proper-lockfile";
|
|
34658
34935
|
function rotateBackup(filePath, mode) {
|
|
34659
34936
|
const dir = dirname6(filePath);
|
|
34660
|
-
const name2 =
|
|
34661
|
-
const backupDir =
|
|
34937
|
+
const name2 = basename5(filePath);
|
|
34938
|
+
const backupDir = join13(dir, ".backups");
|
|
34662
34939
|
const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
|
|
34663
|
-
if (!
|
|
34664
|
-
|
|
34940
|
+
if (!existsSync12(backupDir)) {
|
|
34941
|
+
mkdirSync4(backupDir, { recursive: true, mode: dirMode });
|
|
34665
34942
|
}
|
|
34666
34943
|
for (let i = MAX_BACKUPS; i >= 1; i--) {
|
|
34667
|
-
const current =
|
|
34944
|
+
const current = join13(backupDir, `${name2}.${i}`);
|
|
34668
34945
|
if (i === MAX_BACKUPS) {
|
|
34669
34946
|
try {
|
|
34670
|
-
|
|
34947
|
+
unlinkSync3(current);
|
|
34671
34948
|
} catch {
|
|
34672
34949
|
}
|
|
34673
34950
|
} else {
|
|
34674
|
-
const next =
|
|
34951
|
+
const next = join13(backupDir, `${name2}.${i + 1}`);
|
|
34675
34952
|
try {
|
|
34676
|
-
if (
|
|
34953
|
+
if (existsSync12(current)) renameSync3(current, next);
|
|
34677
34954
|
} catch {
|
|
34678
34955
|
}
|
|
34679
34956
|
}
|
|
34680
34957
|
}
|
|
34681
34958
|
try {
|
|
34682
34959
|
const content = readFileSync5(filePath, "utf-8");
|
|
34683
|
-
const backupPath =
|
|
34960
|
+
const backupPath = join13(backupDir, `${name2}.1`);
|
|
34684
34961
|
if (typeof mode === "number") {
|
|
34685
|
-
|
|
34962
|
+
writeFileSync3(backupPath, content, { encoding: "utf-8", mode });
|
|
34686
34963
|
} else {
|
|
34687
|
-
|
|
34964
|
+
writeFileSync3(backupPath, content, "utf-8");
|
|
34688
34965
|
}
|
|
34689
34966
|
} catch {
|
|
34690
34967
|
}
|
|
@@ -34701,21 +34978,21 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
|
|
|
34701
34978
|
const indent = opts.indent ?? 2;
|
|
34702
34979
|
const mode = opts.mode;
|
|
34703
34980
|
const dir = dirname6(filePath);
|
|
34704
|
-
const tempPath =
|
|
34981
|
+
const tempPath = join13(dir, `.${basename5(filePath)}.${randomBytes(6).toString("hex")}.tmp`);
|
|
34705
34982
|
const content = JSON.stringify(data, null, indent) + "\n";
|
|
34706
34983
|
if (typeof mode === "number") {
|
|
34707
|
-
|
|
34984
|
+
writeFileSync3(tempPath, content, { encoding: "utf-8", mode });
|
|
34708
34985
|
} else {
|
|
34709
|
-
|
|
34986
|
+
writeFileSync3(tempPath, content, "utf-8");
|
|
34710
34987
|
}
|
|
34711
34988
|
try {
|
|
34712
|
-
if (
|
|
34989
|
+
if (existsSync12(filePath)) {
|
|
34713
34990
|
rotateBackup(filePath, mode);
|
|
34714
34991
|
}
|
|
34715
|
-
|
|
34992
|
+
renameSync3(tempPath, filePath);
|
|
34716
34993
|
} catch (error) {
|
|
34717
34994
|
try {
|
|
34718
|
-
|
|
34995
|
+
unlinkSync3(tempPath);
|
|
34719
34996
|
} catch {
|
|
34720
34997
|
}
|
|
34721
34998
|
throw error;
|
|
@@ -34735,14 +35012,14 @@ function readJsonFile(filePath) {
|
|
|
34735
35012
|
async function withLock2(filePath, transform, opts = {}) {
|
|
34736
35013
|
const dir = dirname6(filePath);
|
|
34737
35014
|
const dirMode = typeof opts.mode === "number" ? modeToDirMode(opts.mode) : void 0;
|
|
34738
|
-
if (!
|
|
34739
|
-
|
|
35015
|
+
if (!existsSync12(dir)) {
|
|
35016
|
+
mkdirSync4(dir, { recursive: true, mode: dirMode });
|
|
34740
35017
|
}
|
|
34741
|
-
if (!
|
|
35018
|
+
if (!existsSync12(filePath)) {
|
|
34742
35019
|
if (typeof opts.mode === "number") {
|
|
34743
|
-
|
|
35020
|
+
writeFileSync3(filePath, "", { encoding: "utf-8", mode: opts.mode });
|
|
34744
35021
|
} else {
|
|
34745
|
-
|
|
35022
|
+
writeFileSync3(filePath, "", "utf-8");
|
|
34746
35023
|
}
|
|
34747
35024
|
}
|
|
34748
35025
|
let release;
|
|
@@ -34760,11 +35037,11 @@ async function withLock2(filePath, transform, opts = {}) {
|
|
|
34760
35037
|
}
|
|
34761
35038
|
async function withFileLock(filePath, operation) {
|
|
34762
35039
|
const dir = dirname6(filePath);
|
|
34763
|
-
if (!
|
|
34764
|
-
|
|
35040
|
+
if (!existsSync12(dir)) {
|
|
35041
|
+
mkdirSync4(dir, { recursive: true });
|
|
34765
35042
|
}
|
|
34766
|
-
if (!
|
|
34767
|
-
|
|
35043
|
+
if (!existsSync12(filePath)) {
|
|
35044
|
+
writeFileSync3(filePath, "", "utf-8");
|
|
34768
35045
|
}
|
|
34769
35046
|
let release;
|
|
34770
35047
|
try {
|
|
@@ -34796,11 +35073,11 @@ var init_file_utils = __esm({
|
|
|
34796
35073
|
});
|
|
34797
35074
|
|
|
34798
35075
|
// packages/core/src/llm/credential-removal.ts
|
|
34799
|
-
import { unlinkSync as
|
|
34800
|
-
import { join as
|
|
35076
|
+
import { unlinkSync as unlinkSync4 } from "node:fs";
|
|
35077
|
+
import { join as join14 } from "node:path";
|
|
34801
35078
|
import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
|
|
34802
35079
|
function suppressionStatePath() {
|
|
34803
|
-
return
|
|
35080
|
+
return join14(getCleoHome2(), SUPPRESSION_FILENAME);
|
|
34804
35081
|
}
|
|
34805
35082
|
function readSuppressionFile() {
|
|
34806
35083
|
const data = readJsonFile(suppressionStatePath());
|
|
@@ -34904,10 +35181,10 @@ var init_credential_removal = __esm({
|
|
|
34904
35181
|
sourceId: "cleo-pkce",
|
|
34905
35182
|
description: "Delete CLEO-issued PKCE token at <CLEO_HOME>/anthropic-oauth.json",
|
|
34906
35183
|
async remove() {
|
|
34907
|
-
const path =
|
|
35184
|
+
const path = join14(getCleoHome2(), "anthropic-oauth.json");
|
|
34908
35185
|
const cleaned = [];
|
|
34909
35186
|
try {
|
|
34910
|
-
|
|
35187
|
+
unlinkSync4(path);
|
|
34911
35188
|
cleaned.push(path);
|
|
34912
35189
|
} catch (err) {
|
|
34913
35190
|
const code = err.code;
|
|
@@ -34983,7 +35260,7 @@ __export(config_exports, {
|
|
|
34983
35260
|
parseConfigValue: () => parseConfigValue,
|
|
34984
35261
|
setConfigValue: () => setConfigValue
|
|
34985
35262
|
});
|
|
34986
|
-
import { existsSync as
|
|
35263
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
34987
35264
|
import { mkdir as mkdir3, writeFile } from "node:fs/promises";
|
|
34988
35265
|
import { dirname as dirname7 } from "node:path";
|
|
34989
35266
|
function getNestedValue(obj, path) {
|
|
@@ -35107,7 +35384,7 @@ function parseConfigValue(value) {
|
|
|
35107
35384
|
}
|
|
35108
35385
|
async function setConfigValue(key, value, cwd, opts) {
|
|
35109
35386
|
const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
|
|
35110
|
-
if (!
|
|
35387
|
+
if (!existsSync13(configPath)) {
|
|
35111
35388
|
const dir = dirname7(configPath);
|
|
35112
35389
|
await mkdir3(dir, { recursive: true });
|
|
35113
35390
|
await writeFile(configPath, "{}", "utf-8");
|
|
@@ -35121,7 +35398,7 @@ async function setConfigValue(key, value, cwd, opts) {
|
|
|
35121
35398
|
async function applyStrictnessPreset(preset, cwd, opts) {
|
|
35122
35399
|
const definition = STRICTNESS_PRESETS[preset];
|
|
35123
35400
|
const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
|
|
35124
|
-
if (!
|
|
35401
|
+
if (!existsSync13(configPath)) {
|
|
35125
35402
|
const dir = dirname7(configPath);
|
|
35126
35403
|
await mkdir3(dir, { recursive: true });
|
|
35127
35404
|
await writeFile(configPath, "{}", "utf-8");
|
|
@@ -35323,10 +35600,10 @@ var init_config = __esm({
|
|
|
35323
35600
|
// packages/core/src/llm/credential-seeders/claude-code-seeder.ts
|
|
35324
35601
|
import { readFileSync as readFileSync6 } from "node:fs";
|
|
35325
35602
|
import { homedir as homedir2 } from "node:os";
|
|
35326
|
-
import { join as
|
|
35603
|
+
import { join as join15 } from "node:path";
|
|
35327
35604
|
function defaultReadCredentialFile() {
|
|
35328
35605
|
try {
|
|
35329
|
-
return readFileSync6(
|
|
35606
|
+
return readFileSync6(join15(homedir2(), ".claude", ".credentials.json"), "utf-8");
|
|
35330
35607
|
} catch {
|
|
35331
35608
|
return null;
|
|
35332
35609
|
}
|
|
@@ -35421,9 +35698,9 @@ var init_claude_code_seeder = __esm({
|
|
|
35421
35698
|
|
|
35422
35699
|
// packages/core/src/llm/credential-seeders/cleo-pkce-seeder.ts
|
|
35423
35700
|
import { readFileSync as readFileSync7 } from "node:fs";
|
|
35424
|
-
import { join as
|
|
35701
|
+
import { join as join16 } from "node:path";
|
|
35425
35702
|
function defaultCleoPkcePath() {
|
|
35426
|
-
return
|
|
35703
|
+
return join16(getCleoHome(), "anthropic-oauth.json");
|
|
35427
35704
|
}
|
|
35428
35705
|
function defaultReadCredentialFile2() {
|
|
35429
35706
|
try {
|
|
@@ -35494,13 +35771,13 @@ var init_cleo_pkce_seeder = __esm({
|
|
|
35494
35771
|
});
|
|
35495
35772
|
|
|
35496
35773
|
// packages/core/src/llm/credential-seeders/codex-cli-seeder.ts
|
|
35497
|
-
import { existsSync as
|
|
35774
|
+
import { existsSync as existsSync14, readFileSync as readFileSync8 } from "node:fs";
|
|
35498
35775
|
import { homedir as homedir3 } from "node:os";
|
|
35499
|
-
import { join as
|
|
35776
|
+
import { join as join17 } from "node:path";
|
|
35500
35777
|
function getCodexAuthPath() {
|
|
35501
35778
|
const codexHome = (process.env["CODEX_HOME"] ?? "").trim();
|
|
35502
|
-
const root = codexHome ||
|
|
35503
|
-
return
|
|
35779
|
+
const root = codexHome || join17(homedir3(), ".codex");
|
|
35780
|
+
return join17(root, "auth.json");
|
|
35504
35781
|
}
|
|
35505
35782
|
var CodexCliSeeder, codexCliSeeder;
|
|
35506
35783
|
var init_codex_cli_seeder = __esm({
|
|
@@ -35519,7 +35796,7 @@ var init_codex_cli_seeder = __esm({
|
|
|
35519
35796
|
*/
|
|
35520
35797
|
async seed() {
|
|
35521
35798
|
const authPath = getCodexAuthPath();
|
|
35522
|
-
if (!
|
|
35799
|
+
if (!existsSync14(authPath)) {
|
|
35523
35800
|
return { entries: [] };
|
|
35524
35801
|
}
|
|
35525
35802
|
let raw;
|
|
@@ -35649,11 +35926,11 @@ var init_google_pkce = __esm({
|
|
|
35649
35926
|
});
|
|
35650
35927
|
|
|
35651
35928
|
// packages/core/src/llm/credential-seeders/gemini-cli-seeder.ts
|
|
35652
|
-
import { existsSync as
|
|
35653
|
-
import { join as
|
|
35929
|
+
import { existsSync as existsSync15, readFileSync as readFileSync9 } from "node:fs";
|
|
35930
|
+
import { join as join18 } from "node:path";
|
|
35654
35931
|
import { getCleoHome as getCleoHome3 } from "@cleocode/paths";
|
|
35655
35932
|
function getGoogleOauthPath() {
|
|
35656
|
-
return
|
|
35933
|
+
return join18(getCleoHome3(), "google_oauth.json");
|
|
35657
35934
|
}
|
|
35658
35935
|
function parseGoogleOauthFile(raw) {
|
|
35659
35936
|
let json2;
|
|
@@ -35698,7 +35975,7 @@ var init_gemini_cli_seeder = __esm({
|
|
|
35698
35975
|
*/
|
|
35699
35976
|
async seed() {
|
|
35700
35977
|
const path = getGoogleOauthPath();
|
|
35701
|
-
if (!
|
|
35978
|
+
if (!existsSync15(path)) {
|
|
35702
35979
|
return { entries: [] };
|
|
35703
35980
|
}
|
|
35704
35981
|
let raw;
|
|
@@ -35923,23 +36200,23 @@ var init_credential_seeders = __esm({
|
|
|
35923
36200
|
|
|
35924
36201
|
// packages/core/src/llm/global-config-migration.ts
|
|
35925
36202
|
import {
|
|
35926
|
-
existsSync as
|
|
35927
|
-
mkdirSync as
|
|
36203
|
+
existsSync as existsSync16,
|
|
36204
|
+
mkdirSync as mkdirSync5,
|
|
35928
36205
|
readFileSync as readFileSync10,
|
|
35929
|
-
renameSync as
|
|
35930
|
-
unlinkSync as
|
|
35931
|
-
writeFileSync as
|
|
36206
|
+
renameSync as renameSync4,
|
|
36207
|
+
unlinkSync as unlinkSync5,
|
|
36208
|
+
writeFileSync as writeFileSync4
|
|
35932
36209
|
} from "node:fs";
|
|
35933
|
-
import { join as
|
|
36210
|
+
import { join as join19 } from "node:path";
|
|
35934
36211
|
import { getCleoHome as getCleoHome4, getCleoPlatformPaths as getCleoPlatformPaths2 } from "@cleocode/paths";
|
|
35935
36212
|
function configDirGlobalConfigPath() {
|
|
35936
|
-
return
|
|
36213
|
+
return join19(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
|
|
35937
36214
|
}
|
|
35938
36215
|
function legacyGlobalConfigPath() {
|
|
35939
|
-
return
|
|
36216
|
+
return join19(getCleoHome4(), GLOBAL_CONFIG_FILENAME);
|
|
35940
36217
|
}
|
|
35941
36218
|
function migrationMarkerPath() {
|
|
35942
|
-
return
|
|
36219
|
+
return join19(getCleoHome4(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
|
|
35943
36220
|
}
|
|
35944
36221
|
function tempTargetPath() {
|
|
35945
36222
|
return `${configDirGlobalConfigPath()}.tmp`;
|
|
@@ -35949,12 +36226,12 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
35949
36226
|
const source = legacyGlobalConfigPath();
|
|
35950
36227
|
const target = configDirGlobalConfigPath();
|
|
35951
36228
|
const marker = migrationMarkerPath();
|
|
35952
|
-
if (
|
|
35953
|
-
if (!
|
|
36229
|
+
if (existsSync16(marker)) return false;
|
|
36230
|
+
if (!existsSync16(source)) {
|
|
35954
36231
|
stampMarker(marker);
|
|
35955
36232
|
return false;
|
|
35956
36233
|
}
|
|
35957
|
-
if (
|
|
36234
|
+
if (existsSync16(target)) {
|
|
35958
36235
|
backupSourceQuiet(source);
|
|
35959
36236
|
stampMarker(marker);
|
|
35960
36237
|
return false;
|
|
@@ -35968,13 +36245,13 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
35968
36245
|
);
|
|
35969
36246
|
return false;
|
|
35970
36247
|
}
|
|
35971
|
-
|
|
36248
|
+
mkdirSync5(getCleoPlatformPaths2().config, { recursive: true });
|
|
35972
36249
|
const temp = tempTargetPath();
|
|
35973
|
-
|
|
35974
|
-
|
|
36250
|
+
writeFileSync4(temp, raw, { mode: 420 });
|
|
36251
|
+
renameSync4(temp, target);
|
|
35975
36252
|
stampMarker(marker);
|
|
35976
36253
|
try {
|
|
35977
|
-
|
|
36254
|
+
renameSync4(source, `${source}${BACKUP_SUFFIX}`);
|
|
35978
36255
|
} catch (err) {
|
|
35979
36256
|
console.error(
|
|
35980
36257
|
`[cleo] global config migrated, but backup rename failed: ${err.message}. The legacy file at ${source} can be removed manually.`
|
|
@@ -35987,7 +36264,7 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
35987
36264
|
} catch (err) {
|
|
35988
36265
|
try {
|
|
35989
36266
|
const temp = tempTargetPath();
|
|
35990
|
-
if (
|
|
36267
|
+
if (existsSync16(temp)) unlinkSync5(temp);
|
|
35991
36268
|
} catch {
|
|
35992
36269
|
}
|
|
35993
36270
|
console.error(
|
|
@@ -35998,8 +36275,8 @@ function migrateGlobalConfigToConfigDir() {
|
|
|
35998
36275
|
}
|
|
35999
36276
|
function stampMarker(markerPath) {
|
|
36000
36277
|
try {
|
|
36001
|
-
|
|
36002
|
-
|
|
36278
|
+
mkdirSync5(join19(getCleoHome4(), MIGRATIONS_SUBDIR), { recursive: true });
|
|
36279
|
+
writeFileSync4(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
|
|
36003
36280
|
`, { mode: 420 });
|
|
36004
36281
|
} catch {
|
|
36005
36282
|
}
|
|
@@ -36007,8 +36284,8 @@ function stampMarker(markerPath) {
|
|
|
36007
36284
|
function backupSourceQuiet(source) {
|
|
36008
36285
|
try {
|
|
36009
36286
|
const backup = `${source}${BACKUP_SUFFIX}`;
|
|
36010
|
-
if (
|
|
36011
|
-
|
|
36287
|
+
if (existsSync16(backup)) return;
|
|
36288
|
+
renameSync4(source, backup);
|
|
36012
36289
|
} catch {
|
|
36013
36290
|
}
|
|
36014
36291
|
}
|
|
@@ -36030,20 +36307,20 @@ var init_global_config_migration = __esm({
|
|
|
36030
36307
|
});
|
|
36031
36308
|
|
|
36032
36309
|
// packages/core/src/llm/legacy-flat-key-import.ts
|
|
36033
|
-
import { existsSync as
|
|
36034
|
-
import { join as
|
|
36310
|
+
import { existsSync as existsSync17, readFileSync as readFileSync11, renameSync as renameSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
36311
|
+
import { join as join20 } from "node:path";
|
|
36035
36312
|
import { getCleoHome as getCleoHome5 } from "@cleocode/paths";
|
|
36036
36313
|
function migrationPaths() {
|
|
36037
36314
|
const home = getCleoHome5();
|
|
36038
36315
|
return {
|
|
36039
|
-
flatPath:
|
|
36040
|
-
bakPath:
|
|
36041
|
-
markerPath:
|
|
36316
|
+
flatPath: join20(home, "anthropic-key"),
|
|
36317
|
+
bakPath: join20(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
|
|
36318
|
+
markerPath: join20(home, LEGACY_FLAT_KEY_MARKER)
|
|
36042
36319
|
};
|
|
36043
36320
|
}
|
|
36044
36321
|
function writeMarker(markerPath) {
|
|
36045
36322
|
try {
|
|
36046
|
-
|
|
36323
|
+
writeFileSync5(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
|
|
36047
36324
|
`, {
|
|
36048
36325
|
encoding: "utf-8",
|
|
36049
36326
|
flag: "wx",
|
|
@@ -36059,7 +36336,7 @@ function writeMarker(markerPath) {
|
|
|
36059
36336
|
}
|
|
36060
36337
|
function readFlatKey(flatPath) {
|
|
36061
36338
|
try {
|
|
36062
|
-
if (!
|
|
36339
|
+
if (!existsSync17(flatPath)) return null;
|
|
36063
36340
|
const raw = readFileSync11(flatPath, "utf-8").trim();
|
|
36064
36341
|
return raw || null;
|
|
36065
36342
|
} catch (err) {
|
|
@@ -36072,7 +36349,7 @@ function readFlatKey(flatPath) {
|
|
|
36072
36349
|
}
|
|
36073
36350
|
async function importLegacyFlatAnthropicKey() {
|
|
36074
36351
|
const { flatPath, bakPath, markerPath } = migrationPaths();
|
|
36075
|
-
if (
|
|
36352
|
+
if (existsSync17(markerPath)) {
|
|
36076
36353
|
return { status: "marker-present", flatPath, bakPath: null, markerPath };
|
|
36077
36354
|
}
|
|
36078
36355
|
let existing = null;
|
|
@@ -36089,7 +36366,7 @@ async function importLegacyFlatAnthropicKey() {
|
|
|
36089
36366
|
writeMarker(markerPath);
|
|
36090
36367
|
return { status: "already-imported", flatPath, bakPath: null, markerPath };
|
|
36091
36368
|
}
|
|
36092
|
-
if (!
|
|
36369
|
+
if (!existsSync17(flatPath)) {
|
|
36093
36370
|
writeMarker(markerPath);
|
|
36094
36371
|
return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
|
|
36095
36372
|
}
|
|
@@ -36115,7 +36392,7 @@ async function importLegacyFlatAnthropicKey() {
|
|
|
36115
36392
|
return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
|
|
36116
36393
|
}
|
|
36117
36394
|
try {
|
|
36118
|
-
|
|
36395
|
+
renameSync5(flatPath, bakPath);
|
|
36119
36396
|
} catch (err) {
|
|
36120
36397
|
logger.warn(
|
|
36121
36398
|
{ err: err instanceof Error ? err.message : String(err), flatPath, bakPath },
|
|
@@ -36165,15 +36442,15 @@ __export(credentials_exports, {
|
|
|
36165
36442
|
resolveProviderStatus: () => resolveProviderStatus,
|
|
36166
36443
|
storeAnthropicApiKey: () => storeAnthropicApiKey
|
|
36167
36444
|
});
|
|
36168
|
-
import { existsSync as
|
|
36169
|
-
import { join as
|
|
36445
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
|
|
36446
|
+
import { join as join21 } from "node:path";
|
|
36170
36447
|
import { getCleoHome as getCleoHome6 } from "@cleocode/paths";
|
|
36171
36448
|
function globalConfigPath() {
|
|
36172
36449
|
return configDirGlobalConfigPath();
|
|
36173
36450
|
}
|
|
36174
36451
|
function projectConfigPath(projectRoot) {
|
|
36175
36452
|
const cleoDir = process.env["CLEO_DIR"] ?? ".cleo";
|
|
36176
|
-
return
|
|
36453
|
+
return join21(projectRoot, cleoDir, "config.json");
|
|
36177
36454
|
}
|
|
36178
36455
|
function readGlobalProviderKey(provider) {
|
|
36179
36456
|
ensureGlobalConfigMigrated();
|
|
@@ -36183,8 +36460,8 @@ function readGlobalProviderKey(provider) {
|
|
|
36183
36460
|
}
|
|
36184
36461
|
function readFlatAnthropicKey() {
|
|
36185
36462
|
try {
|
|
36186
|
-
const keyFile =
|
|
36187
|
-
if (!
|
|
36463
|
+
const keyFile = join21(getCleoHome6(), "anthropic-key");
|
|
36464
|
+
if (!existsSync18(keyFile)) return null;
|
|
36188
36465
|
const stored = readFileSync12(keyFile, "utf-8").trim();
|
|
36189
36466
|
return stored || null;
|
|
36190
36467
|
} catch {
|
|
@@ -36193,7 +36470,7 @@ function readFlatAnthropicKey() {
|
|
|
36193
36470
|
}
|
|
36194
36471
|
function readProviderKeyFromConfig(configFile, provider) {
|
|
36195
36472
|
try {
|
|
36196
|
-
if (!
|
|
36473
|
+
if (!existsSync18(configFile)) return null;
|
|
36197
36474
|
const raw = readFileSync12(configFile, "utf-8");
|
|
36198
36475
|
const config = JSON.parse(raw);
|
|
36199
36476
|
const llm = config["llm"];
|
|
@@ -36356,11 +36633,11 @@ function resolveProviderStatus(provider) {
|
|
|
36356
36633
|
}
|
|
36357
36634
|
function storeAnthropicApiKey(apiKey) {
|
|
36358
36635
|
const dir = getCleoHome6();
|
|
36359
|
-
if (!
|
|
36360
|
-
|
|
36636
|
+
if (!existsSync18(dir)) {
|
|
36637
|
+
mkdirSync6(dir, { recursive: true });
|
|
36361
36638
|
}
|
|
36362
|
-
const keyFile =
|
|
36363
|
-
|
|
36639
|
+
const keyFile = join21(dir, "anthropic-key");
|
|
36640
|
+
writeFileSync6(keyFile, apiKey.trim(), { mode: 384 });
|
|
36364
36641
|
}
|
|
36365
36642
|
function clearAnthropicKeyCache() {
|
|
36366
36643
|
}
|
|
@@ -36411,17 +36688,17 @@ var init_credentials2 = __esm({
|
|
|
36411
36688
|
});
|
|
36412
36689
|
|
|
36413
36690
|
// packages/core/src/llm/credentials-store.ts
|
|
36414
|
-
import { chmodSync, existsSync as
|
|
36415
|
-
import { dirname as dirname8, join as
|
|
36691
|
+
import { chmodSync, existsSync as existsSync19, mkdirSync as mkdirSync7, readFileSync as readFileSync13, statSync as statSync4, writeFileSync as writeFileSync7 } from "node:fs";
|
|
36692
|
+
import { dirname as dirname8, join as join22 } from "node:path";
|
|
36416
36693
|
import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
|
|
36417
36694
|
function credentialsStorePath() {
|
|
36418
|
-
return
|
|
36695
|
+
return join22(getCleoHome7(), "llm-credentials.json");
|
|
36419
36696
|
}
|
|
36420
36697
|
function ensureFileInitialized(path) {
|
|
36421
|
-
if (
|
|
36698
|
+
if (existsSync19(path)) return;
|
|
36422
36699
|
const dir = dirname8(path);
|
|
36423
|
-
if (!
|
|
36424
|
-
|
|
36700
|
+
if (!existsSync19(dir)) {
|
|
36701
|
+
mkdirSync7(dir, { recursive: true, mode: 448 });
|
|
36425
36702
|
} else {
|
|
36426
36703
|
try {
|
|
36427
36704
|
chmodSync(dir, 448);
|
|
@@ -36429,7 +36706,7 @@ function ensureFileInitialized(path) {
|
|
|
36429
36706
|
}
|
|
36430
36707
|
}
|
|
36431
36708
|
try {
|
|
36432
|
-
|
|
36709
|
+
writeFileSync7(path, `${JSON.stringify(emptyStore(), null, 2)}
|
|
36433
36710
|
`, {
|
|
36434
36711
|
encoding: "utf-8",
|
|
36435
36712
|
flag: "wx",
|
|
@@ -36678,12 +36955,20 @@ function parseTokenResponse(provider, data) {
|
|
|
36678
36955
|
};
|
|
36679
36956
|
}
|
|
36680
36957
|
async function extractErrorDetail2(resp) {
|
|
36958
|
+
const clone = resp.clone();
|
|
36681
36959
|
try {
|
|
36682
|
-
const body = await
|
|
36960
|
+
const body = await clone.json();
|
|
36683
36961
|
const desc2 = body["error_description"] ?? body["error"];
|
|
36684
|
-
|
|
36962
|
+
if (desc2) return ` \u2014 ${String(desc2)}`;
|
|
36963
|
+
const text3 = JSON.stringify(body);
|
|
36964
|
+
return ` \u2014 ${text3.slice(0, 512)}`;
|
|
36685
36965
|
} catch {
|
|
36686
|
-
|
|
36966
|
+
try {
|
|
36967
|
+
const text3 = (await resp.text()).trim();
|
|
36968
|
+
return text3 ? ` \u2014 ${text3.slice(0, 512)}` : "";
|
|
36969
|
+
} catch {
|
|
36970
|
+
return "";
|
|
36971
|
+
}
|
|
36687
36972
|
}
|
|
36688
36973
|
}
|
|
36689
36974
|
var init_pkce = __esm({
|
|
@@ -36781,13 +37066,13 @@ var init_gemini = __esm({
|
|
|
36781
37066
|
|
|
36782
37067
|
// packages/core/src/llm/stable-device-id.ts
|
|
36783
37068
|
import { randomUUID } from "node:crypto";
|
|
36784
|
-
import { existsSync as
|
|
36785
|
-
import { dirname as dirname9, join as
|
|
37069
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync8, readFileSync as readFileSync14, renameSync as renameSync6, writeFileSync as writeFileSync8 } from "node:fs";
|
|
37070
|
+
import { dirname as dirname9, join as join23 } from "node:path";
|
|
36786
37071
|
import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
|
|
36787
37072
|
function getStableDeviceId() {
|
|
36788
37073
|
if (_cachedDeviceId !== null) return _cachedDeviceId;
|
|
36789
|
-
const path =
|
|
36790
|
-
if (
|
|
37074
|
+
const path = join23(getCleoHome8(), DEVICE_ID_FILE);
|
|
37075
|
+
if (existsSync20(path)) {
|
|
36791
37076
|
try {
|
|
36792
37077
|
const raw = readFileSync14(path, "utf-8").trim();
|
|
36793
37078
|
if (raw.length > 0) {
|
|
@@ -36800,12 +37085,12 @@ function getStableDeviceId() {
|
|
|
36800
37085
|
const fresh = randomUUID();
|
|
36801
37086
|
try {
|
|
36802
37087
|
const dir = dirname9(path);
|
|
36803
|
-
if (!
|
|
36804
|
-
|
|
37088
|
+
if (!existsSync20(dir)) {
|
|
37089
|
+
mkdirSync8(dir, { recursive: true });
|
|
36805
37090
|
}
|
|
36806
37091
|
const tmpPath = `${path}.tmp.${process.pid}`;
|
|
36807
|
-
|
|
36808
|
-
|
|
37092
|
+
writeFileSync8(tmpPath, fresh, { mode: 384 });
|
|
37093
|
+
renameSync6(tmpPath, path);
|
|
36809
37094
|
} catch {
|
|
36810
37095
|
}
|
|
36811
37096
|
_cachedDeviceId = fresh;
|
|
@@ -36980,7 +37265,10 @@ var init_openai = __esm({
|
|
|
36980
37265
|
displayName: "OpenAI Codex (ChatGPT)",
|
|
36981
37266
|
authTypes: ["api_key", "oauth"],
|
|
36982
37267
|
baseUrl: "https://api.openai.com/v1",
|
|
36983
|
-
|
|
37268
|
+
// Static fallback — catalog-driven resolver replaces this at runtime when a
|
|
37269
|
+
// disk snapshot is available (T11773 · E8). Updated from stale 'gpt-5-codex'
|
|
37270
|
+
// to the confirmed latest OpenAI model (catalog release_date 2026-04-23).
|
|
37271
|
+
defaultModel: "gpt-5.5",
|
|
36984
37272
|
aliases: ["codex", "chatgpt", "openai-codex"],
|
|
36985
37273
|
oauth: OPENAI_CODEX_OAUTH
|
|
36986
37274
|
};
|
|
@@ -37090,13 +37378,13 @@ var init_xai = __esm({
|
|
|
37090
37378
|
|
|
37091
37379
|
// packages/core/src/llm/provider-registry/loader.ts
|
|
37092
37380
|
import { readdirSync as readdirSync5, statSync as statSync5 } from "node:fs";
|
|
37093
|
-
import { join as
|
|
37381
|
+
import { join as join24 } from "node:path";
|
|
37094
37382
|
import { pathToFileURL } from "node:url";
|
|
37095
37383
|
function isPluginFile(filename) {
|
|
37096
37384
|
return PLUGIN_EXTENSIONS.some((ext) => filename.endsWith(ext));
|
|
37097
37385
|
}
|
|
37098
37386
|
function getPluginDir() {
|
|
37099
|
-
return
|
|
37387
|
+
return join24(getCleoHome(), "plugins", "model-providers");
|
|
37100
37388
|
}
|
|
37101
37389
|
async function loadOnePlugin(absPath, api) {
|
|
37102
37390
|
let mod;
|
|
@@ -37144,13 +37432,13 @@ async function scanAndLoadPlugins(pluginDir, api) {
|
|
|
37144
37432
|
}
|
|
37145
37433
|
const pluginFiles = entries.filter((name2) => !name2.startsWith(".") && isPluginFile(name2)).filter((name2) => {
|
|
37146
37434
|
try {
|
|
37147
|
-
return statSync5(
|
|
37435
|
+
return statSync5(join24(pluginDir, name2)).isFile();
|
|
37148
37436
|
} catch {
|
|
37149
37437
|
return false;
|
|
37150
37438
|
}
|
|
37151
37439
|
}).sort();
|
|
37152
37440
|
for (const filename of pluginFiles) {
|
|
37153
|
-
await loadOnePlugin(
|
|
37441
|
+
await loadOnePlugin(join24(pluginDir, filename), api);
|
|
37154
37442
|
}
|
|
37155
37443
|
}
|
|
37156
37444
|
async function runDiscovery(registerProvider2, builtins) {
|
|
@@ -37231,15 +37519,15 @@ var init_provider_registry = __esm({
|
|
|
37231
37519
|
});
|
|
37232
37520
|
|
|
37233
37521
|
// packages/core/src/llm/rate-limit-guard.ts
|
|
37234
|
-
import { existsSync as
|
|
37235
|
-
import { join as
|
|
37522
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync9, unlinkSync as unlinkSync6 } from "node:fs";
|
|
37523
|
+
import { join as join25 } from "node:path";
|
|
37236
37524
|
import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
|
|
37237
37525
|
function sanitize(value) {
|
|
37238
37526
|
return value.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
37239
37527
|
}
|
|
37240
37528
|
function rateLimitStatePath(provider, label) {
|
|
37241
|
-
const dir =
|
|
37242
|
-
return
|
|
37529
|
+
const dir = join25(getCleoHome9(), "rate-limit-state");
|
|
37530
|
+
return join25(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
|
|
37243
37531
|
}
|
|
37244
37532
|
function parseResetFromHeaders(headers) {
|
|
37245
37533
|
const get = (k) => {
|
|
@@ -37286,9 +37574,9 @@ async function recordRateLimit(provider, label, opts) {
|
|
|
37286
37574
|
source = "default";
|
|
37287
37575
|
}
|
|
37288
37576
|
const filePath = rateLimitStatePath(provider, label);
|
|
37289
|
-
const dir =
|
|
37290
|
-
if (!
|
|
37291
|
-
|
|
37577
|
+
const dir = join25(getCleoHome9(), "rate-limit-state");
|
|
37578
|
+
if (!existsSync21(dir)) {
|
|
37579
|
+
mkdirSync9(dir, { recursive: true });
|
|
37292
37580
|
}
|
|
37293
37581
|
const state = { resetAt, recordedAt: now, source };
|
|
37294
37582
|
await withFileLock(filePath, () => {
|
|
@@ -38130,14 +38418,14 @@ var init_catalog_cache = __esm({
|
|
|
38130
38418
|
|
|
38131
38419
|
// packages/core/src/llm/model-metadata.ts
|
|
38132
38420
|
import { readFileSync as readFileSync15 } from "node:fs";
|
|
38133
|
-
import { dirname as dirname10, join as
|
|
38421
|
+
import { dirname as dirname10, join as join26 } from "node:path";
|
|
38134
38422
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
38135
38423
|
function getCuratedTable() {
|
|
38136
38424
|
if (_curated !== void 0) {
|
|
38137
38425
|
return _curated;
|
|
38138
38426
|
}
|
|
38139
38427
|
const thisDir = dirname10(fileURLToPath3(import.meta.url));
|
|
38140
|
-
const jsonPath =
|
|
38428
|
+
const jsonPath = join26(thisDir, "curated-models.json");
|
|
38141
38429
|
const raw = JSON.parse(readFileSync15(jsonPath, "utf-8"));
|
|
38142
38430
|
_curated = raw.models;
|
|
38143
38431
|
return _curated;
|