@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.
Files changed (74) hide show
  1. package/dist/docs/export-document.js +626 -310
  2. package/dist/docs/export-document.js.map +3 -3
  3. package/dist/llm/catalog-cache.d.ts +3 -0
  4. package/dist/llm/catalog-cache.d.ts.map +1 -1
  5. package/dist/llm/catalog-cache.js.map +1 -1
  6. package/dist/llm/catalog-model-resolver.d.ts +89 -0
  7. package/dist/llm/catalog-model-resolver.d.ts.map +1 -0
  8. package/dist/llm/catalog-model-resolver.js +158 -0
  9. package/dist/llm/catalog-model-resolver.js.map +1 -0
  10. package/dist/llm/cli-ops.d.ts +14 -0
  11. package/dist/llm/cli-ops.d.ts.map +1 -1
  12. package/dist/llm/cli-ops.js +35 -0
  13. package/dist/llm/cli-ops.js.map +1 -1
  14. package/dist/llm/index.d.ts +3 -0
  15. package/dist/llm/index.d.ts.map +1 -1
  16. package/dist/llm/index.js +3 -0
  17. package/dist/llm/index.js.map +1 -1
  18. package/dist/llm/oauth/pkce.js +27 -5
  19. package/dist/llm/oauth/pkce.js.map +1 -1
  20. package/dist/llm/plugin-facade.js +613 -325
  21. package/dist/llm/plugin-facade.js.map +3 -3
  22. package/dist/llm/provider-registry/builtin/openai.d.ts +11 -2
  23. package/dist/llm/provider-registry/builtin/openai.d.ts.map +1 -1
  24. package/dist/llm/provider-registry/builtin/openai.js +15 -3
  25. package/dist/llm/provider-registry/builtin/openai.js.map +1 -1
  26. package/dist/llm/system-resolver.d.ts +94 -0
  27. package/dist/llm/system-resolver.d.ts.map +1 -0
  28. package/dist/llm/system-resolver.js +165 -0
  29. package/dist/llm/system-resolver.js.map +1 -0
  30. package/dist/memory/dialectic-evaluator.d.ts +13 -6
  31. package/dist/memory/dialectic-evaluator.d.ts.map +1 -1
  32. package/dist/memory/dialectic-evaluator.js +18 -7
  33. package/dist/memory/dialectic-evaluator.js.map +1 -1
  34. package/dist/memory/llm-backend-resolver.d.ts +23 -3
  35. package/dist/memory/llm-backend-resolver.d.ts.map +1 -1
  36. package/dist/memory/llm-backend-resolver.js +135 -0
  37. package/dist/memory/llm-backend-resolver.js.map +1 -1
  38. package/dist/store/dual-scope-db.d.ts +20 -2
  39. package/dist/store/dual-scope-db.d.ts.map +1 -1
  40. package/dist/store/dual-scope-db.js +74 -7
  41. package/dist/store/dual-scope-db.js.map +1 -1
  42. package/dist/store/exodus/archive.d.ts +216 -0
  43. package/dist/store/exodus/archive.d.ts.map +1 -0
  44. package/dist/store/exodus/archive.js +314 -0
  45. package/dist/store/exodus/archive.js.map +1 -0
  46. package/dist/store/exodus/index.d.ts +1 -0
  47. package/dist/store/exodus/index.d.ts.map +1 -1
  48. package/dist/store/exodus/index.js +1 -0
  49. package/dist/store/exodus/index.js.map +1 -1
  50. package/dist/store/exodus/migrate.d.ts.map +1 -1
  51. package/dist/store/exodus/migrate.js +118 -24
  52. package/dist/store/exodus/migrate.js.map +1 -1
  53. package/dist/store/exodus/on-open.d.ts.map +1 -1
  54. package/dist/store/exodus/on-open.js +95 -34
  55. package/dist/store/exodus/on-open.js.map +1 -1
  56. package/dist/store/exodus/types.d.ts +10 -1
  57. package/dist/store/exodus/types.d.ts.map +1 -1
  58. package/dist/store/exodus/types.js.map +1 -1
  59. package/dist/store/exodus/verify-migration.d.ts.map +1 -1
  60. package/dist/store/exodus/verify-migration.js +12 -1
  61. package/dist/store/exodus/verify-migration.js.map +1 -1
  62. package/dist/store/sqlite.d.ts +16 -0
  63. package/dist/store/sqlite.d.ts.map +1 -1
  64. package/dist/store/sqlite.js +160 -39
  65. package/dist/store/sqlite.js.map +1 -1
  66. package/dist/validation/doctor/checks.d.ts +22 -0
  67. package/dist/validation/doctor/checks.d.ts.map +1 -1
  68. package/dist/validation/doctor/checks.js +67 -0
  69. package/dist/validation/doctor/checks.js.map +1 -1
  70. package/dist/validation/doctor/index.d.ts +1 -1
  71. package/dist/validation/doctor/index.d.ts.map +1 -1
  72. package/dist/validation/doctor/index.js +1 -1
  73. package/dist/validation/doctor/index.js.map +1 -1
  74. 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 join26(chunks, separator) {
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 = join26;
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((join26) => join26.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
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, join26]) => {
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: join26,
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) || join26 !== true && !!join26.where
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((join26) => join26.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
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 log4 = getLogger(logSubsystem);
22556
- log4.debug(
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 log4 = getLogger(logSubsystem);
22604
+ const log5 = getLogger(logSubsystem);
22597
22605
  if (allLocalHashesPresentInDb) {
22598
- log4.debug(
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
- log4.warn(
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 log4 = getLogger(logSubsystem);
22640
- log4.debug(
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 log4 = getLogger(logSubsystem);
22678
- log4.warn(
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 log4 = getLogger(logSubsystem);
22687
- log4.warn(
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
- log4.warn(
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
- log4.warn(
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 log4 = getLogger(logSubsystem);
22725
- log4.debug(
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 log4 = getLogger(logSubsystem);
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
- log4.error(fields, `${message} \u2014 MIGRATION DEFECT (fresh DB should not need repair)`);
22812
+ log5.error(fields, `${message} \u2014 MIGRATION DEFECT (fresh DB should not need repair)`);
22805
22813
  } else {
22806
- log4.warn(fields, message);
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 existsSync3,
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 join6 } from "node:path";
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 = join6(stagingDir, JOURNAL_FILENAME);
31802
+ const journalPath = join7(stagingDir, JOURNAL_FILENAME);
31650
31803
  const tmpPath = `${journalPath}.tmp`;
31651
- writeFileSync(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
31652
- renameSync(tmpPath, journalPath);
31804
+ writeFileSync2(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
31805
+ renameSync2(tmpPath, journalPath);
31653
31806
  }
31654
31807
  function readJournal(stagingDir) {
31655
- const journalPath = join6(stagingDir, JOURNAL_FILENAME);
31656
- if (!existsSync3(journalPath)) return null;
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 = join6(stagingDir, JOURNAL_FILENAME);
31817
+ const journalPath = join7(stagingDir, JOURNAL_FILENAME);
31665
31818
  try {
31666
- if (!existsSync3(journalPath)) return false;
31667
- unlinkSync(journalPath);
31668
- log.info(
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
- log.warn(
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
- writeFileSync(lp, JSON.stringify({ pid: process.pid, ts: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
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
- unlinkSync(lockPath(dbPath));
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
- log.warn(
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
- log.warn(
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
- log.warn({ legacyTableName, targetTableName, sourceName }, `Exodus: ${reason}`);
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
- log.info(
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
- log.info(
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
- log.info(
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
- log.error(
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
- log.warn(
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
- log.warn(msg + " (--force-cross-version: continuing anyway)");
32075
+ log2.warn(msg + " (--force-cross-version: continuing anyway)");
31901
32076
  return true;
31902
32077
  }
31903
- log.error(msg + " \u2014 pass --force-cross-version to override");
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
- mkdirSync(stagingDir, { recursive: true });
32094
+ mkdirSync2(stagingDir, { recursive: true });
31920
32095
  let sqliteVersion = "unknown";
31921
32096
  for (const src of sources) {
31922
- if (existsSync3(src.path)) {
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 (!existsSync3(src.path)) continue;
31962
- const backupDest = join6(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
31963
- if (!existsSync3(backupDest)) {
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
- copyFileSync(src.path, backupDest);
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 consolidated project-scope cleo.db (running migrations)\u2026");
31972
- const projectHandle = await openDualScopeDb("project");
31973
- onProgress?.("Opening consolidated global-scope cleo.db (running migrations)\u2026");
31974
- const globalHandle = await openDualScopeDb("global");
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" && existsSync3(s.path));
31978
- const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync3(s.path));
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
- log.error({ err }, "Exodus migration failed");
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
- log.info({ scope }, "Exodus: foreign_keys=OFF for bulk copy (T11533 FK-defer)");
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 = "skipped";
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
- log.warn({ tableName, sourceDb: src.name, err }, "Table copy failed \u2014 skipping");
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
- log.warn(
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
- log.warn(
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
- log.warn(
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
- log.info({ scope }, "Exodus: PRAGMA foreign_key_check PASSED \u2014 no orphan rows");
32346
+ log2.info({ scope }, "Exodus: PRAGMA foreign_key_check PASSED \u2014 no orphan rows");
32160
32347
  }
32161
32348
  } catch (checkErr) {
32162
- log.warn(
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
- log.info({ scope }, "Exodus: foreign_keys=ON restored after bulk copy");
32356
+ log2.info({ scope }, "Exodus: foreign_keys=ON restored after bulk copy");
32170
32357
  } catch (fkErr) {
32171
- log.warn({ scope, err: fkErr }, "Exodus: could not restore foreign_keys=ON (non-fatal)");
32358
+ log2.warn({ scope, err: fkErr }, "Exodus: could not restore foreign_keys=ON (non-fatal)");
32172
32359
  }
32173
32360
  }
32174
32361
  }
32175
- var log, LOCK_SENTINEL_SUFFIX, JOURNAL_FILENAME, ENUM_NORMALIZATIONS, ISO_CHECK_REGEX, SOURCE_EPOCH_UNITS, EPOCH_SECONDS_THRESHOLD;
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
- log = getLogger("exodus-migrate");
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 existsSync4, readdirSync as readdirSync2, statfsSync, statSync } from "node:fs";
32294
- import { join as join7 } from "node:path";
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: join7(cleoDir, "tasks.db"),
32498
+ path: join8(cleoDir, "tasks.db"),
32303
32499
  targetScope: "project"
32304
32500
  },
32305
32501
  {
32306
32502
  name: "brain (project)",
32307
- path: join7(cleoDir, "brain.db"),
32503
+ path: join8(cleoDir, "brain.db"),
32308
32504
  targetScope: "project"
32309
32505
  },
32310
32506
  {
32311
32507
  name: "conduit",
32312
- path: join7(cleoDir, "conduit.db"),
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: join7(cleoHome, "nexus.db"),
32514
+ path: join8(cleoHome, "nexus.db"),
32319
32515
  targetScope: "global"
32320
32516
  },
32321
32517
  {
32322
32518
  name: "signaldock",
32323
- path: join7(cleoHome, "signaldock.db"),
32519
+ path: join8(cleoHome, "signaldock.db"),
32324
32520
  targetScope: "global"
32325
32521
  },
32326
32522
  {
32327
32523
  name: "skills",
32328
- path: join7(cleoHome, "skills.db"),
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 join7(cleoDir, stagingDirs[0]);
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 ?? join7(cleoDir, deriveStagingDirName());
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) => existsSync4(s.path));
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 existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
32398
- import { join as join8 } from "node:path";
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 = join8(stagingDir, JOURNAL_FILENAME2);
32401
- if (!existsSync5(p)) return null;
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) => join8(cleoDir, e.name)).sort().reverse();
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: existsSync5(s.path),
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: existsSync5(projectDbPath),
32441
- globalDbExists: existsSync5(globalDbPath),
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 existsSync6 } from "node:fs";
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
- log2.warn(
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
- hasher.update(JSON.stringify(row));
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
- log2.warn(
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
- log2.warn({ scope, err }, "verifyMigration: PRAGMA foreign_key_check failed (non-fatal)");
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
- log2.warn(
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
- log2.warn({ scope, err }, "verifyMigration: source PRAGMA foreign_key_check failed (non-fatal)");
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 (!existsSync6(projectDbPath)) {
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 (!existsSync6(globalDbPath)) {
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 (!existsSync6(src.path)) {
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
- log2.warn(
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
- log2.warn(
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
- log2.error({ err }, "verifyMigration failed");
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
- log2.error({ failureCount: failureLines.length }, error);
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 log2, _require, CHECK_ENUM_REGEX;
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
- log2 = getLogger("verify-migration");
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 existsSync7 } from "node:fs";
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
- log3.error({ err, scope }, "exodus-on-open: failed to enumerate tables for rollback");
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
- log3.warn({ err, table, scope }, "exodus-on-open: failed to clear table during rollback");
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
- log3.error({ err, scope }, "exodus-on-open: rollback transaction failed");
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 { openDualScopeDb: openDualScopeDb2 } = await Promise.resolve().then(() => (init_dual_scope_db(), dual_scope_db_exports));
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
- const handle = s === "project" ? await openDualScopeDb2("project") : await openDualScopeDb2("global");
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
- log3.warn(
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
- log3.warn(
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) => existsSync7(s.path))) {
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
- log3.info(
33276
+ log4.info(
33058
33277
  {
33059
33278
  scope,
33060
33279
  dbPath,
33061
- sources: plan.sources.filter((s) => existsSync7(s.path)).map((s) => s.name)
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) => log3.debug({ scope }, `exodus-on-open: ${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
- log3.error({ scope, error: migrateResult.error }, `exodus-on-open: ${reason}`);
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) => log3.debug({ scope }, `exodus-on-open verify: ${msg}`)
33302
+ (msg) => log4.debug({ scope }, `exodus-on-open verify: ${msg}`)
33084
33303
  );
33085
33304
  if (!verifyResult.ok) {
33086
- log3.warn(
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
- log3.error(
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
- log3.info(
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 log3, _exodusInProgress;
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
- log3 = getLogger("exodus-on-open");
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 existsSync8, mkdirSync as mkdirSync2 } from "node:fs";
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 join9 } from "node:path";
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 join9(resolveCleoDir(cwd), "cleo.db");
33399
+ return join10(resolveCleoDir(cwd), "cleo.db");
33163
33400
  }
33164
- return join9(getCleoHome(), "cleo.db");
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 openDualScopeDbAtPath(scope, dbPath, exodusCwd) {
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
- const existing = _cache.get(key);
33205
- if (existing) {
33206
- if (existing.initPromise) {
33207
- return existing.initPromise;
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 log4 = getLogger("dual-scope-db");
33485
+ const log5 = getLogger("dual-scope-db");
33486
+ if (dedicated) {
33487
+ return openDedicatedDualScopeDb(scope, dbPath, log5);
33488
+ }
33212
33489
  const initPromise = (async () => {
33213
- log4.debug({ scope, dbPath }, "opening dual-scope cleo.db");
33490
+ log5.debug({ scope, dbPath }, "opening dual-scope cleo.db");
33214
33491
  const dir = dirname4(dbPath);
33215
- if (!existsSync8(dir)) {
33216
- mkdirSync2(dir, { recursive: true });
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
- log4.debug({ scope, dbPath }, "dual-scope cleo.db ready");
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
- log4.warn(
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
- log4.warn(
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 copyFileSync2, existsSync as existsSync9 } from "node:fs";
33850
- import { join as join10 } from "node:path";
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 join10(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
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 (!existsSync9(nestedPath)) return false;
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 log4 = getLogger("nexus-sqlite");
33896
- log4.warn(
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 (!existsSync9(backupPath)) {
34327
+ if (!existsSync10(backupPath)) {
34051
34328
  try {
34052
- copyFileSync2(_nexusDbPath, backupPath);
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 existsSync10, readFileSync as readFileSync4, statSync as statSync3 } from "node:fs";
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 basename3, dirname as dirname5, join as join11, resolve as resolve3 } from "node:path";
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 = join11(cleoHome, "cleo.db");
34276
- if (!existsSync10(globalDbPath)) return null;
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(join11(current, ".cleo")).isDirectory()) {
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 join11(scope.worktreeRoot, ".cleo");
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 join11(root, ".cleo");
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 join11(mainRepo, ".cleo");
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 = join11(current, ".git");
34664
+ const gitMarker = join12(current, ".git");
34388
34665
  try {
34389
- if (existsSync10(gitMarker)) {
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 = join11(gitlinkDir, ".git");
34402
- if (!existsSync10(gitLinkPath)) return null;
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 (existsSync10(join11(mainRepo, ".cleo")) && validateProjectRoot(mainRepo)) {
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 = join11(candidate, ".cleo");
34419
- if (!existsSync10(cleoDir)) {
34695
+ const cleoDir = join12(candidate, ".cleo");
34696
+ if (!existsSync11(cleoDir)) {
34420
34697
  return false;
34421
34698
  }
34422
- const projectInfoPath = join11(cleoDir, "project-info.json");
34423
- if (existsSync10(projectInfoPath)) {
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 = join11(candidate, ".git");
34429
- if (existsSync10(gitMarker)) {
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 = join11(candidate, ".git");
34444
- if (existsSync10(gitDir)) {
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 = join11(current, ".cleo");
34492
- const gitDir = join11(current, ".git");
34768
+ const cleoDir = join12(current, ".cleo");
34769
+ const gitDir = join12(current, ".git");
34493
34770
  const isDangerousRoot = current === homeRoot || current === "/" || current === "";
34494
- if (existsSync10(cleoDir) && !isDangerousRoot) {
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 (existsSync10(gitDir) && !isDangerousRoot) {
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 join11(_resolveCleoDir(cwd), "config.json");
34822
+ return join12(_resolveCleoDir(cwd), "config.json");
34546
34823
  }
34547
34824
  function getGlobalConfigPath() {
34548
- return join11(getCleoHome(), "config.json");
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 = join11(projectRoot, ".cleo", "project-info.json");
34556
- if (!existsSync10(infoPath)) return void 0;
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) || basename3(projectRoot) || "unnamed";
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 = join11(resolvedPath, ".cleo", "brain.db");
34583
- const newTasksDbPath = join11(resolvedPath, ".cleo", "tasks.db");
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: join11(resolvedPath, ".cleo", "brain.db"),
34615
- tasksDbPath: join11(resolvedPath, ".cleo", "tasks.db"),
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 existsSync11,
34649
- mkdirSync as mkdirSync3,
34925
+ existsSync as existsSync12,
34926
+ mkdirSync as mkdirSync4,
34650
34927
  readdirSync as readdirSync4,
34651
34928
  readFileSync as readFileSync5,
34652
- renameSync as renameSync2,
34653
- unlinkSync as unlinkSync2,
34654
- writeFileSync as writeFileSync2
34929
+ renameSync as renameSync3,
34930
+ unlinkSync as unlinkSync3,
34931
+ writeFileSync as writeFileSync3
34655
34932
  } from "node:fs";
34656
- import { basename as basename4, dirname as dirname6, join as join12 } from "node:path";
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 = basename4(filePath);
34661
- const backupDir = join12(dir, ".backups");
34937
+ const name2 = basename5(filePath);
34938
+ const backupDir = join13(dir, ".backups");
34662
34939
  const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
34663
- if (!existsSync11(backupDir)) {
34664
- mkdirSync3(backupDir, { recursive: true, mode: dirMode });
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 = join12(backupDir, `${name2}.${i}`);
34944
+ const current = join13(backupDir, `${name2}.${i}`);
34668
34945
  if (i === MAX_BACKUPS) {
34669
34946
  try {
34670
- unlinkSync2(current);
34947
+ unlinkSync3(current);
34671
34948
  } catch {
34672
34949
  }
34673
34950
  } else {
34674
- const next = join12(backupDir, `${name2}.${i + 1}`);
34951
+ const next = join13(backupDir, `${name2}.${i + 1}`);
34675
34952
  try {
34676
- if (existsSync11(current)) renameSync2(current, next);
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 = join12(backupDir, `${name2}.1`);
34960
+ const backupPath = join13(backupDir, `${name2}.1`);
34684
34961
  if (typeof mode === "number") {
34685
- writeFileSync2(backupPath, content, { encoding: "utf-8", mode });
34962
+ writeFileSync3(backupPath, content, { encoding: "utf-8", mode });
34686
34963
  } else {
34687
- writeFileSync2(backupPath, content, "utf-8");
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 = join12(dir, `.${basename4(filePath)}.${randomBytes(6).toString("hex")}.tmp`);
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
- writeFileSync2(tempPath, content, { encoding: "utf-8", mode });
34984
+ writeFileSync3(tempPath, content, { encoding: "utf-8", mode });
34708
34985
  } else {
34709
- writeFileSync2(tempPath, content, "utf-8");
34986
+ writeFileSync3(tempPath, content, "utf-8");
34710
34987
  }
34711
34988
  try {
34712
- if (existsSync11(filePath)) {
34989
+ if (existsSync12(filePath)) {
34713
34990
  rotateBackup(filePath, mode);
34714
34991
  }
34715
- renameSync2(tempPath, filePath);
34992
+ renameSync3(tempPath, filePath);
34716
34993
  } catch (error) {
34717
34994
  try {
34718
- unlinkSync2(tempPath);
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 (!existsSync11(dir)) {
34739
- mkdirSync3(dir, { recursive: true, mode: dirMode });
35015
+ if (!existsSync12(dir)) {
35016
+ mkdirSync4(dir, { recursive: true, mode: dirMode });
34740
35017
  }
34741
- if (!existsSync11(filePath)) {
35018
+ if (!existsSync12(filePath)) {
34742
35019
  if (typeof opts.mode === "number") {
34743
- writeFileSync2(filePath, "", { encoding: "utf-8", mode: opts.mode });
35020
+ writeFileSync3(filePath, "", { encoding: "utf-8", mode: opts.mode });
34744
35021
  } else {
34745
- writeFileSync2(filePath, "", "utf-8");
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 (!existsSync11(dir)) {
34764
- mkdirSync3(dir, { recursive: true });
35040
+ if (!existsSync12(dir)) {
35041
+ mkdirSync4(dir, { recursive: true });
34765
35042
  }
34766
- if (!existsSync11(filePath)) {
34767
- writeFileSync2(filePath, "", "utf-8");
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 unlinkSync3 } from "node:fs";
34800
- import { join as join13 } from "node:path";
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 join13(getCleoHome2(), SUPPRESSION_FILENAME);
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 = join13(getCleoHome2(), "anthropic-oauth.json");
35184
+ const path = join14(getCleoHome2(), "anthropic-oauth.json");
34908
35185
  const cleaned = [];
34909
35186
  try {
34910
- unlinkSync3(path);
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 existsSync12 } from "node:fs";
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 (!existsSync12(configPath)) {
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 (!existsSync12(configPath)) {
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 join14 } from "node:path";
35603
+ import { join as join15 } from "node:path";
35327
35604
  function defaultReadCredentialFile() {
35328
35605
  try {
35329
- return readFileSync6(join14(homedir2(), ".claude", ".credentials.json"), "utf-8");
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 join15 } from "node:path";
35701
+ import { join as join16 } from "node:path";
35425
35702
  function defaultCleoPkcePath() {
35426
- return join15(getCleoHome(), "anthropic-oauth.json");
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 existsSync13, readFileSync as readFileSync8 } from "node:fs";
35774
+ import { existsSync as existsSync14, readFileSync as readFileSync8 } from "node:fs";
35498
35775
  import { homedir as homedir3 } from "node:os";
35499
- import { join as join16 } from "node:path";
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 || join16(homedir3(), ".codex");
35503
- return join16(root, "auth.json");
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 (!existsSync13(authPath)) {
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 existsSync14, readFileSync as readFileSync9 } from "node:fs";
35653
- import { join as join17 } from "node:path";
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 join17(getCleoHome3(), "google_oauth.json");
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 (!existsSync14(path)) {
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 existsSync15,
35927
- mkdirSync as mkdirSync4,
36203
+ existsSync as existsSync16,
36204
+ mkdirSync as mkdirSync5,
35928
36205
  readFileSync as readFileSync10,
35929
- renameSync as renameSync3,
35930
- unlinkSync as unlinkSync4,
35931
- writeFileSync as writeFileSync3
36206
+ renameSync as renameSync4,
36207
+ unlinkSync as unlinkSync5,
36208
+ writeFileSync as writeFileSync4
35932
36209
  } from "node:fs";
35933
- import { join as join18 } from "node:path";
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 join18(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
36213
+ return join19(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
35937
36214
  }
35938
36215
  function legacyGlobalConfigPath() {
35939
- return join18(getCleoHome4(), GLOBAL_CONFIG_FILENAME);
36216
+ return join19(getCleoHome4(), GLOBAL_CONFIG_FILENAME);
35940
36217
  }
35941
36218
  function migrationMarkerPath() {
35942
- return join18(getCleoHome4(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
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 (existsSync15(marker)) return false;
35953
- if (!existsSync15(source)) {
36229
+ if (existsSync16(marker)) return false;
36230
+ if (!existsSync16(source)) {
35954
36231
  stampMarker(marker);
35955
36232
  return false;
35956
36233
  }
35957
- if (existsSync15(target)) {
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
- mkdirSync4(getCleoPlatformPaths2().config, { recursive: true });
36248
+ mkdirSync5(getCleoPlatformPaths2().config, { recursive: true });
35972
36249
  const temp = tempTargetPath();
35973
- writeFileSync3(temp, raw, { mode: 420 });
35974
- renameSync3(temp, target);
36250
+ writeFileSync4(temp, raw, { mode: 420 });
36251
+ renameSync4(temp, target);
35975
36252
  stampMarker(marker);
35976
36253
  try {
35977
- renameSync3(source, `${source}${BACKUP_SUFFIX}`);
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 (existsSync15(temp)) unlinkSync4(temp);
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
- mkdirSync4(join18(getCleoHome4(), MIGRATIONS_SUBDIR), { recursive: true });
36002
- writeFileSync3(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
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 (existsSync15(backup)) return;
36011
- renameSync3(source, backup);
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 existsSync16, readFileSync as readFileSync11, renameSync as renameSync4, writeFileSync as writeFileSync4 } from "node:fs";
36034
- import { join as join19 } from "node:path";
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: join19(home, "anthropic-key"),
36040
- bakPath: join19(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
36041
- markerPath: join19(home, LEGACY_FLAT_KEY_MARKER)
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
- writeFileSync4(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
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 (!existsSync16(flatPath)) return null;
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 (existsSync16(markerPath)) {
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 (!existsSync16(flatPath)) {
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
- renameSync4(flatPath, bakPath);
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 existsSync17, mkdirSync as mkdirSync5, readFileSync as readFileSync12, writeFileSync as writeFileSync5 } from "node:fs";
36169
- import { join as join20 } from "node:path";
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 join20(projectRoot, cleoDir, "config.json");
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 = join20(getCleoHome6(), "anthropic-key");
36187
- if (!existsSync17(keyFile)) return null;
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 (!existsSync17(configFile)) return null;
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 (!existsSync17(dir)) {
36360
- mkdirSync5(dir, { recursive: true });
36636
+ if (!existsSync18(dir)) {
36637
+ mkdirSync6(dir, { recursive: true });
36361
36638
  }
36362
- const keyFile = join20(dir, "anthropic-key");
36363
- writeFileSync5(keyFile, apiKey.trim(), { mode: 384 });
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 existsSync18, mkdirSync as mkdirSync6, readFileSync as readFileSync13, statSync as statSync4, writeFileSync as writeFileSync6 } from "node:fs";
36415
- import { dirname as dirname8, join as join21 } from "node:path";
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 join21(getCleoHome7(), "llm-credentials.json");
36695
+ return join22(getCleoHome7(), "llm-credentials.json");
36419
36696
  }
36420
36697
  function ensureFileInitialized(path) {
36421
- if (existsSync18(path)) return;
36698
+ if (existsSync19(path)) return;
36422
36699
  const dir = dirname8(path);
36423
- if (!existsSync18(dir)) {
36424
- mkdirSync6(dir, { recursive: true, mode: 448 });
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
- writeFileSync6(path, `${JSON.stringify(emptyStore(), null, 2)}
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 resp.json();
36960
+ const body = await clone.json();
36683
36961
  const desc2 = body["error_description"] ?? body["error"];
36684
- return desc2 ? ` \u2014 ${String(desc2)}` : "";
36962
+ if (desc2) return ` \u2014 ${String(desc2)}`;
36963
+ const text3 = JSON.stringify(body);
36964
+ return ` \u2014 ${text3.slice(0, 512)}`;
36685
36965
  } catch {
36686
- return "";
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 existsSync19, mkdirSync as mkdirSync7, readFileSync as readFileSync14, renameSync as renameSync5, writeFileSync as writeFileSync7 } from "node:fs";
36785
- import { dirname as dirname9, join as join22 } from "node:path";
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 = join22(getCleoHome8(), DEVICE_ID_FILE);
36790
- if (existsSync19(path)) {
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 (!existsSync19(dir)) {
36804
- mkdirSync7(dir, { recursive: true });
37088
+ if (!existsSync20(dir)) {
37089
+ mkdirSync8(dir, { recursive: true });
36805
37090
  }
36806
37091
  const tmpPath = `${path}.tmp.${process.pid}`;
36807
- writeFileSync7(tmpPath, fresh, { mode: 384 });
36808
- renameSync5(tmpPath, path);
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
- defaultModel: "gpt-5-codex",
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 join23 } from "node:path";
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 join23(getCleoHome(), "plugins", "model-providers");
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(join23(pluginDir, name2)).isFile();
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(join23(pluginDir, filename), api);
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 existsSync20, mkdirSync as mkdirSync8, unlinkSync as unlinkSync5 } from "node:fs";
37235
- import { join as join24 } from "node:path";
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 = join24(getCleoHome9(), "rate-limit-state");
37242
- return join24(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
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 = join24(getCleoHome9(), "rate-limit-state");
37290
- if (!existsSync20(dir)) {
37291
- mkdirSync8(dir, { recursive: true });
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 join25 } from "node:path";
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 = join25(thisDir, "curated-models.json");
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;