@cleocode/core 2026.6.19 → 2026.7.2

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 (52) hide show
  1. package/dist/docs/export-document.js +1160 -329
  2. package/dist/docs/export-document.js.map +3 -3
  3. package/dist/llm/plugin-facade.js +1211 -383
  4. package/dist/llm/plugin-facade.js.map +3 -3
  5. package/dist/memory/brain-writer-handlers.d.ts.map +1 -1
  6. package/dist/memory/brain-writer-handlers.js +39 -0
  7. package/dist/memory/brain-writer-handlers.js.map +1 -1
  8. package/dist/orchestrate/admission.d.ts +65 -0
  9. package/dist/orchestrate/admission.d.ts.map +1 -0
  10. package/dist/orchestrate/admission.js +54 -0
  11. package/dist/orchestrate/admission.js.map +1 -0
  12. package/dist/orchestrate/query-ops.d.ts.map +1 -1
  13. package/dist/orchestrate/query-ops.js +37 -8
  14. package/dist/orchestrate/query-ops.js.map +1 -1
  15. package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
  16. package/dist/orchestrate/spawn-ops.js +24 -0
  17. package/dist/orchestrate/spawn-ops.js.map +1 -1
  18. package/dist/resources/governor.d.ts +133 -0
  19. package/dist/resources/governor.d.ts.map +1 -0
  20. package/dist/resources/governor.js +377 -0
  21. package/dist/resources/governor.js.map +1 -0
  22. package/dist/resources/supervisor-admit.d.ts +42 -0
  23. package/dist/resources/supervisor-admit.d.ts.map +1 -0
  24. package/dist/resources/supervisor-admit.js +136 -0
  25. package/dist/resources/supervisor-admit.js.map +1 -0
  26. package/dist/selfimprove/draft-pr.d.ts +93 -9
  27. package/dist/selfimprove/draft-pr.d.ts.map +1 -1
  28. package/dist/selfimprove/draft-pr.js +164 -23
  29. package/dist/selfimprove/draft-pr.js.map +1 -1
  30. package/dist/selfimprove/fix-gen.js +1209 -381
  31. package/dist/selfimprove/fix-gen.js.map +3 -3
  32. package/dist/selfimprove/run-loop.d.ts +9 -1
  33. package/dist/selfimprove/run-loop.d.ts.map +1 -1
  34. package/dist/selfimprove/run-loop.js +7 -1
  35. package/dist/selfimprove/run-loop.js.map +1 -1
  36. package/dist/sentient/tick.d.ts.map +1 -1
  37. package/dist/sentient/tick.js +29 -0
  38. package/dist/sentient/tick.js.map +1 -1
  39. package/dist/store/agent-registry-store.d.ts.map +1 -1
  40. package/dist/store/agent-registry-store.js +17 -2
  41. package/dist/store/agent-registry-store.js.map +1 -1
  42. package/dist/store/dual-scope-db.d.ts.map +1 -1
  43. package/dist/store/dual-scope-db.js +35 -0
  44. package/dist/store/dual-scope-db.js.map +1 -1
  45. package/dist/store/sqlite.d.ts.map +1 -1
  46. package/dist/store/sqlite.js +15 -0
  47. package/dist/store/sqlite.js.map +1 -1
  48. package/dist/tasks/tool-semaphore.d.ts +25 -0
  49. package/dist/tasks/tool-semaphore.d.ts.map +1 -1
  50. package/dist/tasks/tool-semaphore.js +68 -1
  51. package/dist/tasks/tool-semaphore.js.map +1 -1
  52. package/package.json +12 -12
@@ -12443,7 +12443,7 @@ var init_lafs = __esm({
12443
12443
 
12444
12444
  // packages/contracts/src/lease-ipc/messages.ts
12445
12445
  import { z as z11 } from "zod";
12446
- var LeaseScopeSchema, LeaseLaneSchema, LeaseAcquireRequestSchema, LeaseReleaseRequestSchema, LeaseRenewRequestSchema, RateCheckRequestSchema, ToolGrantRequestSchema, QueuePriorityClassSchema, QueueAdmitRequestSchema, WorkerHeartbeatRequestSchema, LeaseIpcRequestSchema, LeaseGrantedResponseSchema, LeaseQueuedResponseSchema, LeaseDeniedResponseSchema, RateResultResponseSchema, ToolGrantedResponseSchema, LeaseRevokedResponseSchema, ChildKilledUnresponsiveResponseSchema, QueueAdmitDispositionSchema, QueueAdmitResultResponseSchema, HeartbeatAckResponseSchema, LeaseErrorResponseSchema, LeaseIpcResponseSchema, LeaseIpcRequestEnvelopeSchema, LeaseIpcResponseEnvelopeSchema, LeaseIpcEnvelopeSchema, LEASE_IPC_REQUEST_KINDS, LEASE_IPC_RESPONSE_KINDS, LEASE_IPC_MESSAGE_KINDS;
12446
+ var LeaseScopeSchema, LeaseLaneSchema, LeaseAcquireRequestSchema, LeaseReleaseRequestSchema, LeaseRenewRequestSchema, RateCheckRequestSchema, ToolGrantRequestSchema, QueuePriorityClassSchema, QueueAdmitRequestSchema, WorkerHeartbeatRequestSchema, ResourceAdmitRequestSchema, ResourceReleaseRequestSchema, LeaseIpcRequestSchema, LeaseGrantedResponseSchema, LeaseQueuedResponseSchema, LeaseDeniedResponseSchema, RateResultResponseSchema, ToolGrantedResponseSchema, LeaseRevokedResponseSchema, ChildKilledUnresponsiveResponseSchema, QueueAdmitDispositionSchema, QueueAdmitResultResponseSchema, HeartbeatAckResponseSchema, ResourceAdmitDispositionSchema, ResourceAdmitResultResponseSchema, ResourceReleaseResultResponseSchema, LeaseErrorResponseSchema, LeaseIpcResponseSchema, LeaseIpcRequestEnvelopeSchema, LeaseIpcResponseEnvelopeSchema, LeaseIpcEnvelopeSchema, LEASE_IPC_REQUEST_KINDS, LEASE_IPC_RESPONSE_KINDS, LEASE_IPC_MESSAGE_KINDS;
12447
12447
  var init_messages2 = __esm({
12448
12448
  "packages/contracts/src/lease-ipc/messages.ts"() {
12449
12449
  "use strict";
@@ -12528,6 +12528,24 @@ var init_messages2 = __esm({
12528
12528
  /** The worker's own view of whether it is currently inside an LLM call. */
12529
12529
  in_flight_llm: z11.boolean()
12530
12530
  }).strict();
12531
+ ResourceAdmitRequestSchema = z11.object({
12532
+ /** Tag discriminating this request variant. */
12533
+ kind: z11.literal("resource_admit"),
12534
+ /** The resource class (e.g. `"db-heavy"`, `"full-build"`, `"test-run"`). */
12535
+ class: z11.string().min(1),
12536
+ /** The caller holding the slot — process/worktree-unique; the release key. */
12537
+ holder_id: z11.string().min(1),
12538
+ /** The client-computed budget: the max concurrent holders for this class. */
12539
+ budget: z11.number().int().nonnegative()
12540
+ }).strict();
12541
+ ResourceReleaseRequestSchema = z11.object({
12542
+ /** Tag discriminating this request variant. */
12543
+ kind: z11.literal("resource_release"),
12544
+ /** The resource class the slot belongs to. */
12545
+ class: z11.string().min(1),
12546
+ /** The holder that was admitted (matches the admit `holder_id`). */
12547
+ holder_id: z11.string().min(1)
12548
+ }).strict();
12531
12549
  LeaseIpcRequestSchema = z11.discriminatedUnion("kind", [
12532
12550
  LeaseAcquireRequestSchema,
12533
12551
  LeaseReleaseRequestSchema,
@@ -12535,7 +12553,9 @@ var init_messages2 = __esm({
12535
12553
  RateCheckRequestSchema,
12536
12554
  ToolGrantRequestSchema,
12537
12555
  QueueAdmitRequestSchema,
12538
- WorkerHeartbeatRequestSchema
12556
+ WorkerHeartbeatRequestSchema,
12557
+ ResourceAdmitRequestSchema,
12558
+ ResourceReleaseRequestSchema
12539
12559
  ]);
12540
12560
  LeaseGrantedResponseSchema = z11.object({
12541
12561
  /** Tag discriminating this response variant. */
@@ -12636,6 +12656,25 @@ var init_messages2 = __esm({
12636
12656
  /** Tag discriminating this response variant. */
12637
12657
  kind: z11.literal("heartbeat_ack")
12638
12658
  }).strict();
12659
+ ResourceAdmitDispositionSchema = z11.enum(["admitted", "deferred"]);
12660
+ ResourceAdmitResultResponseSchema = z11.object({
12661
+ /** Tag discriminating this response variant. */
12662
+ kind: z11.literal("resource_admit_result"),
12663
+ /** Whether the heavy op was admitted or deferred. */
12664
+ disposition: ResourceAdmitDispositionSchema,
12665
+ /** Back-off in ms before re-requesting (0 when admitted). */
12666
+ retry_after_ms: z11.number().int().nonnegative(),
12667
+ /** Remaining slots for the class after this decision. */
12668
+ slots_remaining: z11.number().int().nonnegative()
12669
+ }).strict();
12670
+ ResourceReleaseResultResponseSchema = z11.object({
12671
+ /** Tag discriminating this response variant. */
12672
+ kind: z11.literal("resource_release_result"),
12673
+ /** Whether a held slot was actually released (false = no such holder). */
12674
+ released: z11.boolean(),
12675
+ /** Remaining in-flight holders for the class after the release. */
12676
+ slots_remaining: z11.number().int().nonnegative()
12677
+ }).strict();
12639
12678
  LeaseErrorResponseSchema = z11.object({
12640
12679
  /** Tag discriminating this response variant. */
12641
12680
  kind: z11.literal("error"),
@@ -12654,6 +12693,8 @@ var init_messages2 = __esm({
12654
12693
  ChildKilledUnresponsiveResponseSchema,
12655
12694
  QueueAdmitResultResponseSchema,
12656
12695
  HeartbeatAckResponseSchema,
12696
+ ResourceAdmitResultResponseSchema,
12697
+ ResourceReleaseResultResponseSchema,
12657
12698
  LeaseErrorResponseSchema
12658
12699
  ]);
12659
12700
  LeaseIpcRequestEnvelopeSchema = z11.object({
@@ -12687,7 +12728,9 @@ var init_messages2 = __esm({
12687
12728
  "rate_check",
12688
12729
  "tool_grant",
12689
12730
  "queue_admit",
12690
- "worker_heartbeat"
12731
+ "worker_heartbeat",
12732
+ "resource_admit",
12733
+ "resource_release"
12691
12734
  ];
12692
12735
  LEASE_IPC_RESPONSE_KINDS = [
12693
12736
  "lease_granted",
@@ -12699,6 +12742,8 @@ var init_messages2 = __esm({
12699
12742
  "child_killed_unresponsive",
12700
12743
  "queue_admit_result",
12701
12744
  "heartbeat_ack",
12745
+ "resource_admit_result",
12746
+ "resource_release_result",
12702
12747
  "error"
12703
12748
  ];
12704
12749
  LEASE_IPC_MESSAGE_KINDS = [
@@ -12709,9 +12754,11 @@ var init_messages2 = __esm({
12709
12754
  });
12710
12755
 
12711
12756
  // packages/contracts/src/lease-ipc/version.ts
12757
+ var LEASE_IPC_PROTOCOL_VERSION;
12712
12758
  var init_version2 = __esm({
12713
12759
  "packages/contracts/src/lease-ipc/version.ts"() {
12714
12760
  "use strict";
12761
+ LEASE_IPC_PROTOCOL_VERSION = "1.2.0";
12715
12762
  }
12716
12763
  });
12717
12764
 
@@ -13971,6 +14018,25 @@ var init_render = __esm({
13971
14018
  }
13972
14019
  });
13973
14020
 
14021
+ // packages/contracts/src/resource-governor.ts
14022
+ var RESOURCE_CLASSES, DEFAULT_RESOURCE_RETRY_AFTER_MS;
14023
+ var init_resource_governor = __esm({
14024
+ "packages/contracts/src/resource-governor.ts"() {
14025
+ "use strict";
14026
+ RESOURCE_CLASSES = Object.freeze([
14027
+ "interactive-cli",
14028
+ "agent-session",
14029
+ "llm-call",
14030
+ "test-run",
14031
+ "scoped-build",
14032
+ "full-build",
14033
+ "db-heavy",
14034
+ "background-autonomous"
14035
+ ]);
14036
+ DEFAULT_RESOURCE_RETRY_AFTER_MS = 2e3;
14037
+ }
14038
+ });
14039
+
13974
14040
  // packages/contracts/src/session.ts
13975
14041
  var init_session2 = __esm({
13976
14042
  "packages/contracts/src/session.ts"() {
@@ -15721,6 +15787,7 @@ var init_src = __esm({
15721
15787
  init_evidence_atoms();
15722
15788
  init_plan();
15723
15789
  init_render();
15790
+ init_resource_governor();
15724
15791
  init_session2();
15725
15792
  init_session_journal();
15726
15793
  init_status_registry();
@@ -17656,7 +17723,7 @@ var init_sql = __esm({
17656
17723
  return new SQL([new StringChunk(str)]);
17657
17724
  }
17658
17725
  _sql.raw = raw;
17659
- function join29(chunks, separator) {
17726
+ function join31(chunks, separator) {
17660
17727
  const result = [];
17661
17728
  for (const [i, chunk] of chunks.entries()) {
17662
17729
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -17664,7 +17731,7 @@ var init_sql = __esm({
17664
17731
  }
17665
17732
  return new SQL(result);
17666
17733
  }
17667
- _sql.join = join29;
17734
+ _sql.join = join31;
17668
17735
  function identifier(value) {
17669
17736
  return new Name(value);
17670
17737
  }
@@ -20051,7 +20118,7 @@ var init_select2 = __esm({
20051
20118
  const baseTableName = this.tableName;
20052
20119
  const tableName = getTableLikeName(table);
20053
20120
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
20054
- if (typeof tableName === "string" && this.config.joins?.some((join29) => join29.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
20121
+ if (typeof tableName === "string" && this.config.joins?.some((join31) => join31.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
20055
20122
  if (!this.isPartialSelect) {
20056
20123
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
20057
20124
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -23861,7 +23928,7 @@ var init_dialect = __esm({
23861
23928
  if (!joins2) return;
23862
23929
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
23863
23930
  if (!withEntries.length) return;
23864
- return sql.join(withEntries.map(([k, join29]) => {
23931
+ return sql.join(withEntries.map(([k, join31]) => {
23865
23932
  const relation = tableConfig.relations[k];
23866
23933
  const isSingle2 = is(relation, One);
23867
23934
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -23872,7 +23939,7 @@ var init_dialect = __esm({
23872
23939
  table: targetTable,
23873
23940
  mode: isSingle2 ? "first" : "many",
23874
23941
  schema,
23875
- queryConfig: join29,
23942
+ queryConfig: join31,
23876
23943
  tableConfig: schema[relation.targetTableName],
23877
23944
  relationWhere: filter2,
23878
23945
  isNested: true,
@@ -23886,7 +23953,7 @@ var init_dialect = __esm({
23886
23953
  key: k,
23887
23954
  selection: innerQuery.selection,
23888
23955
  isArray: !isSingle2,
23889
- isOptional: (relation.optional ?? false) || join29 !== true && !!join29.where
23956
+ isOptional: (relation.optional ?? false) || join31 !== true && !!join31.where
23890
23957
  });
23891
23958
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
23892
23959
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb3}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -24707,7 +24774,7 @@ var init_update = __esm({
24707
24774
  createJoin(joinType) {
24708
24775
  return ((table, on) => {
24709
24776
  const tableName = getTableLikeName(table);
24710
- if (typeof tableName === "string" && this.config.joins.some((join29) => join29.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
24777
+ if (typeof tableName === "string" && this.config.joins.some((join31) => join31.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
24711
24778
  if (typeof on === "function") {
24712
24779
  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;
24713
24780
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -25805,8 +25872,8 @@ function probeAndMarkApplied(nativeDb, migration, logSubsystem, eliminatedTables
25805
25872
  });
25806
25873
  if (allAltersPresent && allTablesPresent && allIndexesPresent && allTriggersPresent) {
25807
25874
  insertJournalEntry(nativeDb, migration.hash, migration.folderMillis, migration.name ?? "");
25808
- const log8 = getLogger(logSubsystem);
25809
- log8.debug(
25875
+ const log9 = getLogger(logSubsystem);
25876
+ log9.debug(
25810
25877
  {
25811
25878
  migration: migration.name,
25812
25879
  alters: alterTargets.length,
@@ -25875,14 +25942,14 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
25875
25942
  if (hasOrphanedEntries) {
25876
25943
  const dbHashes = new Set(dbEntries.map((e) => e.hash));
25877
25944
  const allLocalHashesPresentInDb = localMigrations.every((m) => dbHashes.has(m.hash));
25878
- const log8 = getLogger(logSubsystem);
25945
+ const log9 = getLogger(logSubsystem);
25879
25946
  if (allLocalHashesPresentInDb) {
25880
- log8.debug(
25947
+ log9.debug(
25881
25948
  { extra: orphanedEntries.length },
25882
25949
  `Migration journal has ${orphanedEntries.length} entries for migrations not known to this install (DB is ahead). Skipping reconciliation.`
25883
25950
  );
25884
25951
  } else {
25885
- log8.warn(
25952
+ log9.warn(
25886
25953
  { orphaned: orphanedEntries.length },
25887
25954
  `Detected ${orphanedEntries.length} true-orphan journal entries from a previous CLEO lineage. Reconciling via DDL probe.`
25888
25955
  );
@@ -25918,8 +25985,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
25918
25985
  if (alterMatches.length === 0) {
25919
25986
  const stripped = stripSqlComments(fullSql).trim();
25920
25987
  if (stripped === "") {
25921
- const log8 = getLogger(logSubsystem);
25922
- log8.debug(
25988
+ const log9 = getLogger(logSubsystem);
25989
+ log9.debug(
25923
25990
  { migration: migration.name },
25924
25991
  `Migration ${migration.name} is a comment-only baseline marker \u2014 marking applied on existing DB.`
25925
25992
  );
@@ -25958,8 +26025,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
25958
26025
  }
25959
26026
  }
25960
26027
  if (missingColumns.length === 0) {
25961
- const log8 = getLogger(logSubsystem);
25962
- log8.warn(
26028
+ const log9 = getLogger(logSubsystem);
26029
+ log9.warn(
25963
26030
  { migration: migration.name, columns: alterMatches },
25964
26031
  `Detected partially-applied migration ${migration.name} \u2014 columns exist but journal entry missing. Auto-reconciling.`
25965
26032
  );
@@ -25967,8 +26034,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
25967
26034
  continue;
25968
26035
  }
25969
26036
  if (existingColumns.length > 0 && missingColumns.length > 0) {
25970
- const log8 = getLogger(logSubsystem);
25971
- log8.warn(
26037
+ const log9 = getLogger(logSubsystem);
26038
+ log9.warn(
25972
26039
  {
25973
26040
  migration: migration.name,
25974
26041
  existingColumns: existingColumns.map((c) => `${c.table}.${c.column}`),
@@ -25980,12 +26047,12 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
25980
26047
  if (!tableExists(nativeDb, table)) continue;
25981
26048
  try {
25982
26049
  nativeDb.exec(`ALTER TABLE ${table} ADD COLUMN ${column}${ddl ? ` ${ddl}` : ""}`);
25983
- log8.warn(
26050
+ log9.warn(
25984
26051
  { migration: migration.name, table, column },
25985
26052
  `T920: Added missing column ${table}.${column} to complete partial migration.`
25986
26053
  );
25987
26054
  } catch {
25988
- log8.warn(
26055
+ log9.warn(
25989
26056
  { migration: migration.name, table, column },
25990
26057
  `T920: Could not add missing column ${table}.${column} \u2014 will let Drizzle migrate() handle it.`
25991
26058
  );
@@ -26005,8 +26072,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
26005
26072
  for (const entry of unnamedEntries) {
26006
26073
  const migrationName = hashToName.get(entry.hash);
26007
26074
  if (!migrationName) continue;
26008
- const log8 = getLogger(logSubsystem);
26009
- log8.debug(
26075
+ const log9 = getLogger(logSubsystem);
26076
+ log9.debug(
26010
26077
  { id: entry.id, hash: entry.hash, name: migrationName },
26011
26078
  `Backfilling missing name on journal entry id=${entry.id} (Drizzle v1 beta legacy compat).`
26012
26079
  );
@@ -26090,13 +26157,13 @@ function ensureColumns(nativeDb, tableName, requiredColumns, logSubsystem, conte
26090
26157
  const existingCols = new Set(columns.map((c) => c.name));
26091
26158
  for (const req of requiredColumns) {
26092
26159
  if (!existingCols.has(req.name)) {
26093
- const log8 = getLogger(logSubsystem);
26160
+ const log9 = getLogger(logSubsystem);
26094
26161
  const message = `Adding missing column ${tableName}.${req.name} via ALTER TABLE`;
26095
26162
  const fields = { column: req.name, context };
26096
26163
  if (context === "fresh") {
26097
- log8.error(fields, `${message} \u2014 MIGRATION DEFECT (fresh DB should not need repair)`);
26164
+ log9.error(fields, `${message} \u2014 MIGRATION DEFECT (fresh DB should not need repair)`);
26098
26165
  } else {
26099
- log8.warn(fields, message);
26166
+ log9.warn(fields, message);
26100
26167
  }
26101
26168
  nativeDb.exec(`ALTER TABLE ${tableName} ADD COLUMN ${req.name} ${req.ddl}`);
26102
26169
  }
@@ -35177,11 +35244,750 @@ var init_cleo_global = __esm({
35177
35244
  }
35178
35245
  });
35179
35246
 
35180
- // packages/core/src/store/lock.ts
35247
+ // packages/core/src/resources/linux-backend.ts
35248
+ import { readFile as readFile2, stat } from "node:fs/promises";
35249
+ function parsePressureLine(line2) {
35250
+ const avg10Match = /avg10=([\d.]+)/.exec(line2);
35251
+ const avg60Match = /avg60=([\d.]+)/.exec(line2);
35252
+ const avg300Match = /avg300=([\d.]+)/.exec(line2);
35253
+ const totalMatch = /total=(\d+)/.exec(line2);
35254
+ if (!avg10Match?.[1] || !avg60Match?.[1] || !avg300Match?.[1] || !totalMatch?.[1]) {
35255
+ return null;
35256
+ }
35257
+ return {
35258
+ avg10: parseFloat(avg10Match[1]),
35259
+ avg60: parseFloat(avg60Match[1]),
35260
+ avg300: parseFloat(avg300Match[1]),
35261
+ totalUs: parseInt(totalMatch[1], 10)
35262
+ };
35263
+ }
35264
+ function parsePsiFile(content) {
35265
+ const lines = content.split("\n").map((l) => l.trim()).filter(Boolean);
35266
+ let some = null;
35267
+ let full = null;
35268
+ for (const line2 of lines) {
35269
+ if (line2.startsWith("some ")) {
35270
+ some = parsePressureLine(line2);
35271
+ } else if (line2.startsWith("full ")) {
35272
+ full = parsePressureLine(line2);
35273
+ }
35274
+ }
35275
+ if (!some) {
35276
+ return null;
35277
+ }
35278
+ return { some, full };
35279
+ }
35280
+ function parseMemAvailable(content) {
35281
+ for (const line2 of content.split("\n")) {
35282
+ if (line2.startsWith("MemAvailable:")) {
35283
+ const match = /MemAvailable:\s+(\d+)\s+kB/.exec(line2);
35284
+ if (match?.[1]) {
35285
+ return parseInt(match[1], 10) * 1024;
35286
+ }
35287
+ }
35288
+ }
35289
+ return null;
35290
+ }
35291
+ function parseSmapsRollup(content) {
35292
+ let rssKb = null;
35293
+ let pssKb = null;
35294
+ for (const line2 of content.split("\n")) {
35295
+ if (line2.startsWith("Rss:")) {
35296
+ const m = /Rss:\s+(\d+)\s+kB/.exec(line2);
35297
+ if (m?.[1]) rssKb = parseInt(m[1], 10);
35298
+ } else if (line2.startsWith("Pss:")) {
35299
+ const m = /Pss:\s+(\d+)\s+kB/.exec(line2);
35300
+ if (m?.[1]) pssKb = parseInt(m[1], 10);
35301
+ }
35302
+ }
35303
+ if (rssKb === null || pssKb === null) return null;
35304
+ return { rssBytes: rssKb * 1024, pssBytes: pssKb * 1024 };
35305
+ }
35306
+ var defaultReadFile, defaultStat, LinuxResourceBackend;
35307
+ var init_linux_backend = __esm({
35308
+ "packages/core/src/resources/linux-backend.ts"() {
35309
+ "use strict";
35310
+ defaultReadFile = (path, encoding) => readFile2(path, encoding);
35311
+ defaultStat = async (path) => {
35312
+ try {
35313
+ const s = await stat(path);
35314
+ return { size: s.size };
35315
+ } catch {
35316
+ return null;
35317
+ }
35318
+ };
35319
+ LinuxResourceBackend = class {
35320
+ globalPressurePath;
35321
+ cgroupSlicePressurePath;
35322
+ walPaths;
35323
+ readFileFn;
35324
+ statFileFn;
35325
+ constructor(opts = {}) {
35326
+ this.globalPressurePath = opts.globalPressurePath ?? "/proc/pressure/memory";
35327
+ this.cgroupSlicePressurePath = opts.cgroupSlicePressurePath ?? null;
35328
+ this.walPaths = opts.walPaths ?? [];
35329
+ this.readFileFn = opts.readFileFn ?? defaultReadFile;
35330
+ this.statFileFn = opts.statFileFn ?? defaultStat;
35331
+ }
35332
+ /**
35333
+ * Take a bounded point-in-time resource sample.
35334
+ *
35335
+ * Read-count (bounded by Amendment 1):
35336
+ * - 1 read: `/proc/pressure/memory`
35337
+ * - 0–1 reads: slice `memory.pressure` (if configured)
35338
+ * - 1 read: `/proc/meminfo`
35339
+ * - N stat calls: one per WAL path in `walPaths`
35340
+ *
35341
+ * Never spawns a child process.
35342
+ */
35343
+ async sample() {
35344
+ const sampledAtMs = Date.now();
35345
+ const globalPressure = await this._readPsi(this.globalPressurePath);
35346
+ const pressureAvailable = globalPressure !== null;
35347
+ let slicePressure = null;
35348
+ if (this.cgroupSlicePressurePath) {
35349
+ slicePressure = await this._readPsi(this.cgroupSlicePressurePath);
35350
+ }
35351
+ const memAvailableBytes = await this._readMemAvailable();
35352
+ const walObservations = await this._readWalObservations();
35353
+ return {
35354
+ sampledAtMs,
35355
+ pressureAvailable,
35356
+ memAvailableBytes,
35357
+ globalPressure,
35358
+ slicePressure,
35359
+ walObservations
35360
+ };
35361
+ }
35362
+ /**
35363
+ * Sweep per-child RSS via `/proc/<pid>/smaps_rollup`.
35364
+ *
35365
+ * **STRUCTURALLY SEPARATED from sample()** — smaps_rollup reads are
35366
+ * ms-scale per multi-GB process and must never appear in the hot path.
35367
+ * Call on a separate low-frequency cadence (e.g. every 60s or on
35368
+ * backoff→hold state transition).
35369
+ *
35370
+ * @param pids - PIDs to sweep. Dead/unknown PIDs are silently skipped.
35371
+ */
35372
+ async sweepChildRss(pids) {
35373
+ const sampledAtMs = Date.now();
35374
+ const entries = [];
35375
+ for (const pid of pids) {
35376
+ try {
35377
+ const content = await this.readFileFn(`/proc/${pid}/smaps_rollup`, "utf-8");
35378
+ const parsed = parseSmapsRollup(content);
35379
+ if (parsed) {
35380
+ entries.push({ pid, ...parsed });
35381
+ }
35382
+ } catch {
35383
+ }
35384
+ }
35385
+ return { sampledAtMs, entries };
35386
+ }
35387
+ // -------------------------------------------------------------------------
35388
+ // Private helpers
35389
+ // -------------------------------------------------------------------------
35390
+ async _readPsi(path) {
35391
+ try {
35392
+ const content = await this.readFileFn(path, "utf-8");
35393
+ return parsePsiFile(content);
35394
+ } catch {
35395
+ return null;
35396
+ }
35397
+ }
35398
+ async _readMemAvailable() {
35399
+ try {
35400
+ const content = await this.readFileFn("/proc/meminfo", "utf-8");
35401
+ return parseMemAvailable(content);
35402
+ } catch {
35403
+ return null;
35404
+ }
35405
+ }
35406
+ async _readWalObservations() {
35407
+ const results = [];
35408
+ for (const walPath of this.walPaths) {
35409
+ const info = await this.statFileFn(walPath);
35410
+ results.push({ walPath, sizeBytes: info?.size ?? null });
35411
+ }
35412
+ return results;
35413
+ }
35414
+ };
35415
+ }
35416
+ });
35417
+
35418
+ // packages/core/src/resources/monitor.ts
35419
+ import { EventEmitter as EventEmitter2 } from "node:events";
35420
+ function resolveThresholds(cfg) {
35421
+ return {
35422
+ holdSomeAvg10: cfg.psi?.holdSomeAvg10 ?? DEFAULTS.holdSomeAvg10,
35423
+ backoffSomeAvg10: cfg.psi?.backoffSomeAvg10 ?? DEFAULTS.backoffSomeAvg10,
35424
+ holdFullAvg10: cfg.psi?.holdFullAvg10 ?? DEFAULTS.holdFullAvg10,
35425
+ backoffFullAvg10: cfg.psi?.backoffFullAvg10 ?? DEFAULTS.backoffFullAvg10,
35426
+ hysteresisPoints: cfg.hysteresisPoints ?? DEFAULTS.hysteresisPoints,
35427
+ headroomBytes: cfg.headroomBytes ?? DEFAULTS.headroomBytes,
35428
+ walWarnThresholdBytes: cfg.walWarnThresholdBytes ?? DEFAULTS.walWarnThresholdBytes,
35429
+ pollIntervalMs: cfg.pollIntervalMs ?? DEFAULTS.pollIntervalMs
35430
+ };
35431
+ }
35432
+ function evaluateState(sample, thresholds, currentState) {
35433
+ if (!sample.pressureAvailable) {
35434
+ if (sample.memAvailableBytes !== null && sample.memAvailableBytes < thresholds.headroomBytes) {
35435
+ return { state: "hold", reason: "degraded: memAvailable below headroom" };
35436
+ }
35437
+ return { state: "ok", reason: "degraded: PSI unavailable, memAvailable sufficient" };
35438
+ }
35439
+ const somePressure = sample.globalPressure?.some ?? sample.slicePressure?.some;
35440
+ const fullPressure = sample.globalPressure?.full ?? sample.slicePressure?.full;
35441
+ const someAvg102 = somePressure?.avg10 ?? 0;
35442
+ const fullAvg10 = fullPressure?.avg10 ?? 0;
35443
+ if (someAvg102 > thresholds.backoffSomeAvg10 || fullAvg10 > thresholds.backoffFullAvg10) {
35444
+ return {
35445
+ state: "backoff",
35446
+ reason: `some avg10=${someAvg102.toFixed(2)} full avg10=${fullAvg10.toFixed(2)} \u2014 above backoff threshold`
35447
+ };
35448
+ }
35449
+ if (someAvg102 > thresholds.holdSomeAvg10 || fullAvg10 > thresholds.holdFullAvg10) {
35450
+ return {
35451
+ state: "hold",
35452
+ reason: `some avg10=${someAvg102.toFixed(2)} full avg10=${fullAvg10.toFixed(2)} \u2014 above hold threshold`
35453
+ };
35454
+ }
35455
+ if (currentState !== "ok") {
35456
+ const hysteresisFloor = thresholds.holdSomeAvg10 - thresholds.hysteresisPoints;
35457
+ const fullHysteresisFloor = thresholds.holdFullAvg10 - thresholds.hysteresisPoints;
35458
+ if (someAvg102 > hysteresisFloor || fullAvg10 > fullHysteresisFloor) {
35459
+ const clamped = currentState === "backoff" ? "hold" : currentState;
35460
+ return {
35461
+ state: clamped,
35462
+ reason: `some avg10=${someAvg102.toFixed(2)} full avg10=${fullAvg10.toFixed(2)} \u2014 hysteresis hold (floor: some ${hysteresisFloor}, full ${fullHysteresisFloor})`
35463
+ };
35464
+ }
35465
+ }
35466
+ return {
35467
+ state: "ok",
35468
+ reason: `some avg10=${someAvg102.toFixed(2)} full avg10=${fullAvg10.toFixed(2)} \u2014 below thresholds`
35469
+ };
35470
+ }
35471
+ var DEFAULTS, ResourceMonitor;
35472
+ var init_monitor = __esm({
35473
+ "packages/core/src/resources/monitor.ts"() {
35474
+ "use strict";
35475
+ init_linux_backend();
35476
+ DEFAULTS = {
35477
+ holdSomeAvg10: 10,
35478
+ backoffSomeAvg10: 20,
35479
+ holdFullAvg10: 5,
35480
+ backoffFullAvg10: 10,
35481
+ hysteresisPoints: 3,
35482
+ headroomBytes: 256 * 1024 * 1024,
35483
+ walWarnThresholdBytes: 256 * 1024 * 1024,
35484
+ pollIntervalMs: 1500
35485
+ };
35486
+ ResourceMonitor = class extends EventEmitter2 {
35487
+ thresholds;
35488
+ backend;
35489
+ _state = "ok";
35490
+ _timer = null;
35491
+ _running = false;
35492
+ constructor(cfg = {}) {
35493
+ super();
35494
+ this.thresholds = resolveThresholds(cfg);
35495
+ this.backend = cfg.backend ?? new LinuxResourceBackend();
35496
+ }
35497
+ // -------------------------------------------------------------------------
35498
+ // Public API
35499
+ // -------------------------------------------------------------------------
35500
+ /**
35501
+ * Current pressure state (only meaningful after at least one sample).
35502
+ */
35503
+ get state() {
35504
+ return this._state;
35505
+ }
35506
+ /**
35507
+ * `true` while the continuous loop is running.
35508
+ */
35509
+ get running() {
35510
+ return this._running;
35511
+ }
35512
+ /**
35513
+ * Take a single point-in-time resource sample.
35514
+ *
35515
+ * Safe to call with the daemon off (no child processes, bounded reads).
35516
+ * Does NOT update `this.state` — use {@link startContinuous} for that.
35517
+ */
35518
+ async sample() {
35519
+ return this.backend.sample();
35520
+ }
35521
+ /**
35522
+ * Start the continuous polling loop.
35523
+ *
35524
+ * Returns a `stop()` function. Calling `stop()` is idempotent.
35525
+ *
35526
+ * Emits:
35527
+ * - `'sample'` on every poll (even if state did not change)
35528
+ * - `'transition'` when `PressureState` changes
35529
+ * - `'error'` if the backend throws (loop continues regardless)
35530
+ */
35531
+ startContinuous() {
35532
+ if (this._running) {
35533
+ return () => this._stopLoop();
35534
+ }
35535
+ this._running = true;
35536
+ this._scheduleNext();
35537
+ return () => this._stopLoop();
35538
+ }
35539
+ /**
35540
+ * Stop the continuous polling loop. Idempotent.
35541
+ */
35542
+ stop() {
35543
+ this._stopLoop();
35544
+ }
35545
+ // -------------------------------------------------------------------------
35546
+ // Private loop machinery
35547
+ // -------------------------------------------------------------------------
35548
+ _scheduleNext() {
35549
+ this._timer = setTimeout(() => {
35550
+ void this._tick();
35551
+ }, this.thresholds.pollIntervalMs);
35552
+ if (typeof this._timer.unref === "function") {
35553
+ this._timer.unref();
35554
+ }
35555
+ }
35556
+ async _tick() {
35557
+ if (!this._running) return;
35558
+ try {
35559
+ const sample = await this.backend.sample();
35560
+ this.emit("sample", sample);
35561
+ const { state: newState, reason } = evaluateState(sample, this.thresholds, this._state);
35562
+ if (newState !== this._state) {
35563
+ const transition = {
35564
+ from: this._state,
35565
+ to: newState,
35566
+ sample,
35567
+ reason
35568
+ };
35569
+ this._state = newState;
35570
+ this.emit("transition", transition);
35571
+ }
35572
+ } catch (err) {
35573
+ this.emit("error", err instanceof Error ? err : new Error(String(err)));
35574
+ }
35575
+ if (this._running) {
35576
+ this._scheduleNext();
35577
+ }
35578
+ }
35579
+ _stopLoop() {
35580
+ this._running = false;
35581
+ if (this._timer !== null) {
35582
+ clearTimeout(this._timer);
35583
+ this._timer = null;
35584
+ }
35585
+ }
35586
+ };
35587
+ }
35588
+ });
35589
+
35590
+ // packages/core/src/resources/supervisor-admit.ts
35591
+ import { connect } from "node:net";
35592
+ import { join as join5 } from "node:path";
35593
+ import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
35594
+ function resolveSupervisorSocketPath() {
35595
+ return process.env.CLEO_SUPERVISOR_SOCKET ?? join5(getCleoHome2(), SUPERVISOR_SOCKET_NAME);
35596
+ }
35597
+ async function sendResourceAdmit(socketPath, cls, holderId, budget) {
35598
+ const result = await sendLeaseRequest(
35599
+ socketPath,
35600
+ { kind: "resource_admit", class: cls, holder_id: holderId, budget },
35601
+ "resource_admit_result"
35602
+ );
35603
+ if ("unavailable" in result) return result;
35604
+ if (result.kind === "resource_admit_result") return result;
35605
+ return { unavailable: true, reason: `unexpected response kind: ${result.kind}` };
35606
+ }
35607
+ async function sendResourceRelease(socketPath, cls, holderId) {
35608
+ const result = await sendLeaseRequest(
35609
+ socketPath,
35610
+ { kind: "resource_release", class: cls, holder_id: holderId },
35611
+ "resource_release_result"
35612
+ );
35613
+ if ("unavailable" in result) return result;
35614
+ if (result.kind === "resource_release_result") return result;
35615
+ return { unavailable: true, reason: `unexpected response kind: ${result.kind}` };
35616
+ }
35617
+ function sendLeaseRequest(socketPath, request, expectedKind) {
35618
+ return new Promise((resolve5) => {
35619
+ const id = `ra-${process.pid}-${request.kind}`;
35620
+ const envelope = LeaseIpcRequestEnvelopeSchema.parse({
35621
+ protocol_version: LEASE_IPC_PROTOCOL_VERSION,
35622
+ id,
35623
+ direction: "request",
35624
+ request
35625
+ });
35626
+ const line2 = `${JSON.stringify(envelope)}
35627
+ `;
35628
+ let settled = false;
35629
+ let buffer = "";
35630
+ const socket = connect(socketPath);
35631
+ const done = (value) => {
35632
+ if (settled) return;
35633
+ settled = true;
35634
+ socket.removeAllListeners();
35635
+ socket.destroy();
35636
+ resolve5(value);
35637
+ };
35638
+ const degrade = (reason) => done({ unavailable: true, reason });
35639
+ socket.setTimeout(REQUEST_TIMEOUT_MS);
35640
+ const connectTimer = setTimeout(
35641
+ () => degrade("supervisor connect timeout"),
35642
+ CONNECT_TIMEOUT_MS
35643
+ );
35644
+ socket.on("connect", () => {
35645
+ clearTimeout(connectTimer);
35646
+ socket.write(line2);
35647
+ });
35648
+ socket.on("timeout", () => degrade("supervisor request timeout"));
35649
+ socket.on("error", (err) => {
35650
+ clearTimeout(connectTimer);
35651
+ degrade(err.message);
35652
+ });
35653
+ socket.on("close", () => {
35654
+ if (!settled) degrade("supervisor closed the connection before responding");
35655
+ });
35656
+ socket.on("data", (chunk) => {
35657
+ buffer += chunk.toString("utf8");
35658
+ const nl = buffer.indexOf("\n");
35659
+ if (nl < 0) return;
35660
+ let json3;
35661
+ try {
35662
+ json3 = JSON.parse(buffer.slice(0, nl));
35663
+ } catch (cause) {
35664
+ degrade(`malformed lease-ipc frame: ${cause instanceof Error ? cause.message : cause}`);
35665
+ return;
35666
+ }
35667
+ const parsed = LeaseIpcResponseEnvelopeSchema.safeParse(json3);
35668
+ if (!parsed.success) {
35669
+ degrade(`off-contract lease-ipc response: ${parsed.error.message}`);
35670
+ return;
35671
+ }
35672
+ const { response } = parsed.data;
35673
+ if (response.kind === expectedKind) {
35674
+ done(response);
35675
+ return;
35676
+ }
35677
+ if (response.kind === "error") {
35678
+ degrade(`${response.code}: ${response.message}`);
35679
+ return;
35680
+ }
35681
+ degrade(`unexpected lease-ipc response kind for ${request.kind}: ${response.kind}`);
35682
+ });
35683
+ });
35684
+ }
35685
+ var SUPERVISOR_SOCKET_NAME, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS;
35686
+ var init_supervisor_admit = __esm({
35687
+ "packages/core/src/resources/supervisor-admit.ts"() {
35688
+ "use strict";
35689
+ init_src();
35690
+ SUPERVISOR_SOCKET_NAME = "cleo-supervisor.sock";
35691
+ CONNECT_TIMEOUT_MS = 250;
35692
+ REQUEST_TIMEOUT_MS = 2e3;
35693
+ }
35694
+ });
35695
+
35696
+ // packages/core/src/resources/governor.ts
35697
+ var governor_exports = {};
35698
+ __export(governor_exports, {
35699
+ ResourceGovernor: () => ResourceGovernor,
35700
+ _resetGovernorStateForTest: () => _resetGovernorStateForTest,
35701
+ computeClassBudget: () => computeClassBudget,
35702
+ governor: () => governor,
35703
+ governorSlotDir: () => governorSlotDir,
35704
+ resolveGovernorMode: () => resolveGovernorMode,
35705
+ slotFileCount: () => slotFileCount
35706
+ });
35707
+ import { existsSync as existsSync3, mkdirSync, readdirSync as readdirSync2, writeFileSync } from "node:fs";
35708
+ import { availableParallelism, totalmem } from "node:os";
35709
+ import { join as join6 } from "node:path";
35181
35710
  import lockfile from "proper-lockfile";
35711
+ function log2() {
35712
+ if (_log2 === null) _log2 = getLogger("resource-governor");
35713
+ return _log2;
35714
+ }
35715
+ function resolveGovernorMode() {
35716
+ if (_cachedMode2 !== null) return _cachedMode2;
35717
+ const raw = process.env.CLEO_RESOURCES_MODE;
35718
+ _cachedMode2 = raw === "supervisor" || raw === "local" || raw === "off" ? raw : "local";
35719
+ return _cachedMode2;
35720
+ }
35721
+ function logSupervisorDegradeOnce(reason) {
35722
+ if (_supervisorDegradeLogged) return;
35723
+ _supervisorDegradeLogged = true;
35724
+ log2().info(
35725
+ `CLEO_RESOURCES_MODE=supervisor but the arbiter is unreachable (${reason}); degrading to local-mode admission for the process lifetime.`
35726
+ );
35727
+ }
35728
+ function _resetGovernorStateForTest() {
35729
+ _cachedMode2 = null;
35730
+ _supervisorDegradeLogged = false;
35731
+ }
35732
+ function someAvg10(sample) {
35733
+ const some = sample.globalPressure?.some ?? sample.slicePressure?.some;
35734
+ return some?.avg10 ?? 0;
35735
+ }
35736
+ function computeClassBudget(cls, sample, opts = {}) {
35737
+ if (cls === "interactive-cli") return Number.POSITIVE_INFINITY;
35738
+ const cpus = Math.max(1, opts.cpuCount ?? availableParallelism());
35739
+ const totalBytes = opts.totalMemBytes ?? totalmem();
35740
+ const headroomBytes = (opts.headroomMb ?? 2048) * MB;
35741
+ const hold = opts.holdSomeAvg10 ?? 10;
35742
+ const floor = opts.floorSomeAvg10 ?? 25;
35743
+ const some = someAvg10(sample);
35744
+ const availBytes = sample.memAvailableBytes ?? totalBytes;
35745
+ const fullStall = sample.globalPressure?.full?.avg10 ?? sample.slicePressure?.full?.avg10 ?? 0;
35746
+ const backoff = some > floor || fullStall > 10;
35747
+ switch (cls) {
35748
+ case "full-build":
35749
+ return 1;
35750
+ case "agent-session": {
35751
+ const estRamBytes = (opts.agentEstRamMb ?? 4096) * MB;
35752
+ const byMem = Math.floor((availBytes - headroomBytes) / estRamBytes);
35753
+ return clamp(1, byMem, Math.max(1, cpus - 2));
35754
+ }
35755
+ case "llm-call":
35756
+ return Math.max(1, cpus - 2);
35757
+ case "test-run":
35758
+ case "scoped-build": {
35759
+ const base = Math.max(1, Math.floor(cpus / 4));
35760
+ if (some > floor) return 1;
35761
+ if (some > hold) return Math.max(1, Math.floor(base / 2));
35762
+ return base;
35763
+ }
35764
+ case "db-heavy":
35765
+ return backoff ? 0 : 1;
35766
+ case "background-autonomous":
35767
+ return some > hold || fullStall > 5 ? 0 : 1;
35768
+ default:
35769
+ return 1;
35770
+ }
35771
+ }
35772
+ function clamp(lo, v, hi) {
35773
+ return Math.max(lo, Math.min(v, hi));
35774
+ }
35775
+ function governorSlotDir(cls) {
35776
+ return join6(getCleoHome(), "locks", `resource-${cls}`);
35777
+ }
35778
+ function ensureSlotFiles(dir, count) {
35779
+ if (!existsSync3(dir)) mkdirSync(dir, { recursive: true });
35780
+ const paths = [];
35781
+ for (let i = 0; i < count; i++) {
35782
+ const p = join6(dir, `slot-${i}.lock`);
35783
+ if (!existsSync3(p)) writeFileSync(p, "", { flag: "a" });
35784
+ paths.push(p);
35785
+ }
35786
+ return paths;
35787
+ }
35788
+ function sleep(ms) {
35789
+ return new Promise((r) => setTimeout(r, ms));
35790
+ }
35791
+ function passThroughGrant(cls) {
35792
+ return {
35793
+ deferred: false,
35794
+ class: cls,
35795
+ slot: -1,
35796
+ acquiredAtMs: Date.now(),
35797
+ release: async () => {
35798
+ }
35799
+ };
35800
+ }
35801
+ function deferral(cls, reason, retryAfterMs) {
35802
+ return { deferred: true, class: cls, retryAfterMs, reason };
35803
+ }
35804
+ function supervisorHolderId(cls) {
35805
+ _supervisorHolderSeq += 1;
35806
+ return `${process.pid}:${cls}:${_supervisorHolderSeq}`;
35807
+ }
35808
+ function shuffledIndices(n) {
35809
+ const order = Array.from({ length: n }, (_, i) => i);
35810
+ for (let i = order.length - 1; i > 0; i--) {
35811
+ const j = Math.floor(Math.random() * (i + 1));
35812
+ const a = order[i];
35813
+ const b = order[j];
35814
+ if (a !== void 0 && b !== void 0) {
35815
+ order[i] = b;
35816
+ order[j] = a;
35817
+ }
35818
+ }
35819
+ return order;
35820
+ }
35821
+ async function countHeldSlots(cls, budget) {
35822
+ const dir = governorSlotDir(cls);
35823
+ if (!existsSync3(dir)) return 0;
35824
+ const slots = ensureSlotFiles(dir, budget);
35825
+ let held = 0;
35826
+ for (const path of slots) {
35827
+ try {
35828
+ const release = await lockfile.lock(path, { retries: 0, stale: STALE_MS, realpath: false });
35829
+ await release();
35830
+ } catch {
35831
+ held++;
35832
+ }
35833
+ }
35834
+ return held;
35835
+ }
35836
+ function slotFileCount(cls) {
35837
+ const dir = governorSlotDir(cls);
35838
+ if (!existsSync3(dir)) return 0;
35839
+ return readdirSync2(dir).filter((f) => f.startsWith("slot-") && f.endsWith(".lock")).length;
35840
+ }
35841
+ var _log2, _cachedMode2, _supervisorDegradeLogged, MB, STALE_MS, _supervisorHolderSeq, ResourceGovernor, governor;
35842
+ var init_governor = __esm({
35843
+ "packages/core/src/resources/governor.ts"() {
35844
+ "use strict";
35845
+ init_src();
35846
+ init_logger2();
35847
+ init_paths();
35848
+ init_monitor();
35849
+ init_supervisor_admit();
35850
+ _log2 = null;
35851
+ _cachedMode2 = null;
35852
+ _supervisorDegradeLogged = false;
35853
+ MB = 1024 * 1024;
35854
+ STALE_MS = 6e5;
35855
+ _supervisorHolderSeq = 0;
35856
+ ResourceGovernor = class {
35857
+ /**
35858
+ * Acquire one slot of `cls`. Returns a {@link ResourceGrant} on success or a
35859
+ * {@link ResourceDeferral} on denial. Never throws for admission control;
35860
+ * only genuinely unexpected I/O errors propagate.
35861
+ */
35862
+ async acquire(cls, opts = {}) {
35863
+ const mode = resolveGovernorMode();
35864
+ if (mode === "off" || cls === "interactive-cli") {
35865
+ return passThroughGrant(cls);
35866
+ }
35867
+ const sample = opts.sample ?? await (opts.monitor ?? new ResourceMonitor()).sample();
35868
+ const budget = computeClassBudget(cls, sample, opts);
35869
+ if (!Number.isFinite(budget)) return passThroughGrant(cls);
35870
+ if (budget <= 0) {
35871
+ return deferral(
35872
+ cls,
35873
+ `class '${cls}' budget is 0 under current pressure (some avg10=${someAvg10(sample).toFixed(1)})`,
35874
+ DEFAULT_RESOURCE_RETRY_AFTER_MS
35875
+ );
35876
+ }
35877
+ if (mode === "supervisor") {
35878
+ const viaSupervisor = await this.acquireViaSupervisor(cls, Math.floor(budget));
35879
+ if (viaSupervisor !== null) return viaSupervisor;
35880
+ }
35881
+ const dir = governorSlotDir(cls);
35882
+ const slots = ensureSlotFiles(dir, budget);
35883
+ const blocking = opts.blocking ?? true;
35884
+ const timeoutMs = opts.timeoutMs ?? 36e5;
35885
+ const pollMs = opts.pollMs ?? 200;
35886
+ const startedAt = Date.now();
35887
+ do {
35888
+ const order = shuffledIndices(slots.length);
35889
+ for (const idx of order) {
35890
+ const path = slots[idx];
35891
+ if (!path) continue;
35892
+ try {
35893
+ const release = await lockfile.lock(path, {
35894
+ retries: 0,
35895
+ stale: STALE_MS,
35896
+ realpath: false
35897
+ });
35898
+ let released = false;
35899
+ return {
35900
+ deferred: false,
35901
+ class: cls,
35902
+ slot: idx,
35903
+ acquiredAtMs: Date.now(),
35904
+ release: async () => {
35905
+ if (released) return;
35906
+ released = true;
35907
+ try {
35908
+ await release();
35909
+ } catch {
35910
+ }
35911
+ }
35912
+ };
35913
+ } catch {
35914
+ }
35915
+ }
35916
+ if (!blocking) break;
35917
+ await sleep(pollMs);
35918
+ } while (Date.now() - startedAt < timeoutMs);
35919
+ return deferral(
35920
+ cls,
35921
+ `class '${cls}' is at capacity (${budget} slot(s)); ` + (blocking ? `timed out after ${timeoutMs}ms` : "no slot free"),
35922
+ Math.min(pollMs * 4, DEFAULT_RESOURCE_RETRY_AFTER_MS)
35923
+ );
35924
+ }
35925
+ /**
35926
+ * Route an admission through the supervisor's central `resource_admit` verb.
35927
+ * Returns a grant (whose `release` calls `resource_release`) or a deferral, or
35928
+ * `null` when the supervisor is unreachable so the caller degrades to the
35929
+ * local slot engine. Never throws — a dead arbiter never deadlocks work.
35930
+ *
35931
+ * @task T12001
35932
+ */
35933
+ async acquireViaSupervisor(cls, budget) {
35934
+ const socketPath = resolveSupervisorSocketPath();
35935
+ const holderId = supervisorHolderId(cls);
35936
+ const reply = await sendResourceAdmit(socketPath, cls, holderId, budget);
35937
+ if ("unavailable" in reply) {
35938
+ logSupervisorDegradeOnce(reply.reason);
35939
+ return null;
35940
+ }
35941
+ if (reply.disposition === "deferred") {
35942
+ return deferral(
35943
+ cls,
35944
+ `class '${cls}' deferred by supervisor (budget ${budget})`,
35945
+ reply.retry_after_ms || DEFAULT_RESOURCE_RETRY_AFTER_MS
35946
+ );
35947
+ }
35948
+ let released = false;
35949
+ return {
35950
+ deferred: false,
35951
+ class: cls,
35952
+ slot: 0,
35953
+ acquiredAtMs: Date.now(),
35954
+ release: async () => {
35955
+ if (released) return;
35956
+ released = true;
35957
+ await sendResourceRelease(socketPath, cls, holderId).catch(() => {
35958
+ });
35959
+ }
35960
+ };
35961
+ }
35962
+ /** Non-blocking single-pass acquire (admission semantics). */
35963
+ async tryAcquire(cls, opts = {}) {
35964
+ return this.acquire(cls, { ...opts, blocking: false });
35965
+ }
35966
+ /**
35967
+ * Currently-grantable slot count for `cls` = budget − held. Held is the count
35968
+ * of slot files currently locked. `Infinity` for ungated classes.
35969
+ */
35970
+ async available(cls, opts = {}) {
35971
+ if (resolveGovernorMode() === "off" || cls === "interactive-cli") {
35972
+ return Number.POSITIVE_INFINITY;
35973
+ }
35974
+ const sample = opts.sample ?? await (opts.monitor ?? new ResourceMonitor()).sample();
35975
+ const budget = computeClassBudget(cls, sample, opts);
35976
+ if (!Number.isFinite(budget)) return Number.POSITIVE_INFINITY;
35977
+ if (budget <= 0) return 0;
35978
+ const held = await countHeldSlots(cls, budget);
35979
+ return Math.max(0, budget - held);
35980
+ }
35981
+ };
35982
+ governor = new ResourceGovernor();
35983
+ }
35984
+ });
35985
+
35986
+ // packages/core/src/store/lock.ts
35987
+ import lockfile2 from "proper-lockfile";
35182
35988
  async function acquireLock(filePath, options) {
35183
35989
  try {
35184
- const release = await lockfile.lock(filePath, {
35990
+ const release = await lockfile2.lock(filePath, {
35185
35991
  ...DEFAULT_LOCK_OPTIONS,
35186
35992
  ...options?.stale !== void 0 && { stale: options.stale },
35187
35993
  ...options?.retries !== void 0 && {
@@ -35227,7 +36033,7 @@ var init_lock = __esm({
35227
36033
  });
35228
36034
 
35229
36035
  // packages/core/src/store/atomic.ts
35230
- import { mkdir, readFile as readFile2, rename, unlink } from "node:fs/promises";
36036
+ import { mkdir, readFile as readFile3, rename, unlink } from "node:fs/promises";
35231
36037
  import { dirname as dirname3 } from "node:path";
35232
36038
  import writeFileAtomic from "write-file-atomic";
35233
36039
  async function atomicWrite(filePath, data, options) {
@@ -35243,7 +36049,7 @@ async function atomicWrite(filePath, data, options) {
35243
36049
  }
35244
36050
  async function safeReadFile(filePath) {
35245
36051
  try {
35246
- return await readFile2(filePath, "utf8");
36052
+ return await readFile3(filePath, "utf8");
35247
36053
  } catch (err) {
35248
36054
  if (err instanceof Error && "code" in err && err.code === "ENOENT") {
35249
36055
  return null;
@@ -35264,34 +36070,34 @@ var init_atomic = __esm({
35264
36070
  });
35265
36071
 
35266
36072
  // packages/core/src/store/backup.ts
35267
- import { copyFile, rename as fsRename, mkdir as mkdir2, readdir, stat, unlink as unlink2 } from "node:fs/promises";
35268
- import { basename, join as join5 } from "node:path";
36073
+ import { copyFile, rename as fsRename, mkdir as mkdir2, readdir, stat as stat2, unlink as unlink2 } from "node:fs/promises";
36074
+ import { basename, join as join7 } from "node:path";
35269
36075
  async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUPS) {
35270
36076
  try {
35271
36077
  await mkdir2(backupDir, { recursive: true });
35272
36078
  const fileName = basename(filePath);
35273
36079
  try {
35274
- await stat(filePath);
36080
+ await stat2(filePath);
35275
36081
  } catch {
35276
36082
  throw new CleoError(3 /* FILE_ERROR */, `Cannot backup: source file not found: ${filePath}`);
35277
36083
  }
35278
36084
  for (let i = maxBackups; i >= 1; i--) {
35279
- const current = join5(backupDir, `${fileName}.${i}`);
36085
+ const current = join7(backupDir, `${fileName}.${i}`);
35280
36086
  if (i === maxBackups) {
35281
36087
  try {
35282
36088
  await unlink2(current);
35283
36089
  } catch {
35284
36090
  }
35285
36091
  } else {
35286
- const next = join5(backupDir, `${fileName}.${i + 1}`);
36092
+ const next = join7(backupDir, `${fileName}.${i + 1}`);
35287
36093
  try {
35288
- await stat(current);
36094
+ await stat2(current);
35289
36095
  await fsRename(current, next);
35290
36096
  } catch {
35291
36097
  }
35292
36098
  }
35293
36099
  }
35294
- const backupPath = join5(backupDir, `${fileName}.1`);
36100
+ const backupPath = join7(backupDir, `${fileName}.1`);
35295
36101
  await copyFile(filePath, backupPath);
35296
36102
  return backupPath;
35297
36103
  } catch (err) {
@@ -35570,8 +36376,8 @@ var init_json2 = __esm({
35570
36376
  });
35571
36377
 
35572
36378
  // packages/core/src/scaffold/ensure-config.ts
35573
- import { existsSync as existsSync3, readFileSync } from "node:fs";
35574
- import { basename as basename2, dirname as dirname4, join as join6, resolve as resolve2 } from "node:path";
36379
+ import { existsSync as existsSync4, readFileSync } from "node:fs";
36380
+ import { basename as basename2, dirname as dirname4, join as join8, resolve as resolve2 } from "node:path";
35575
36381
  import { fileURLToPath as fileURLToPath2 } from "node:url";
35576
36382
  function getPackageRoot() {
35577
36383
  const thisFile = fileURLToPath2(import.meta.url);
@@ -35579,7 +36385,7 @@ function getPackageRoot() {
35579
36385
  }
35580
36386
  function getCleoVersion() {
35581
36387
  try {
35582
- const pkgPath = join6(getPackageRoot(), "package.json");
36388
+ const pkgPath = join8(getPackageRoot(), "package.json");
35583
36389
  const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
35584
36390
  return pkg.version ?? "0.0.0";
35585
36391
  } catch {
@@ -35598,25 +36404,25 @@ var init_ensure_config = __esm({
35598
36404
  // packages/core/src/store/exodus/archive.ts
35599
36405
  import {
35600
36406
  copyFileSync as copyFileSync2,
35601
- existsSync as existsSync4,
35602
- mkdirSync,
36407
+ existsSync as existsSync5,
36408
+ mkdirSync as mkdirSync2,
35603
36409
  renameSync,
35604
36410
  unlinkSync,
35605
- writeFileSync
36411
+ writeFileSync as writeFileSync2
35606
36412
  } from "node:fs";
35607
- import { basename as basename3, join as join7 } from "node:path";
36413
+ import { basename as basename3, join as join9 } from "node:path";
35608
36414
  function scopeBaseDir(scope, cwd) {
35609
36415
  return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
35610
36416
  }
35611
36417
  function exodusArchiveDir(scope, cwd) {
35612
- return join7(scopeBaseDir(scope, cwd), ARCHIVE_DIR_NAME);
36418
+ return join9(scopeBaseDir(scope, cwd), ARCHIVE_DIR_NAME);
35613
36419
  }
35614
36420
  function exodusMarkerPath(scope, cwd) {
35615
- return join7(scopeBaseDir(scope, cwd), MARKER_FILENAME_BY_SCOPE[scope]);
36421
+ return join9(scopeBaseDir(scope, cwd), MARKER_FILENAME_BY_SCOPE[scope]);
35616
36422
  }
35617
36423
  function hasExodusCompleteMarker(scope, cwd) {
35618
36424
  try {
35619
- return existsSync4(exodusMarkerPath(scope, cwd));
36425
+ return existsSync5(exodusMarkerPath(scope, cwd));
35620
36426
  } catch {
35621
36427
  return false;
35622
36428
  }
@@ -35624,7 +36430,7 @@ function hasExodusCompleteMarker(scope, cwd) {
35624
36430
  function writeExodusCompleteMarker(scope, archivedSources, cwd) {
35625
36431
  const markerPath = exodusMarkerPath(scope, cwd);
35626
36432
  const baseDir = scopeBaseDir(scope, cwd);
35627
- mkdirSync(baseDir, { recursive: true });
36433
+ mkdirSync2(baseDir, { recursive: true });
35628
36434
  const marker16 = {
35629
36435
  version: 1,
35630
36436
  scope,
@@ -35633,17 +36439,17 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd) {
35633
36439
  archivedSources: [...archivedSources]
35634
36440
  };
35635
36441
  const tmpPath = `${markerPath}.tmp`;
35636
- writeFileSync(tmpPath, JSON.stringify(marker16, null, 2) + "\n", "utf8");
36442
+ writeFileSync2(tmpPath, JSON.stringify(marker16, null, 2) + "\n", "utf8");
35637
36443
  renameSync(tmpPath, markerPath);
35638
- log2.info({ scope, markerPath, archivedSources }, "exodus: wrote completion marker");
36444
+ log3.info({ scope, markerPath, archivedSources }, "exodus: wrote completion marker");
35639
36445
  return markerPath;
35640
36446
  }
35641
36447
  function moveFileInto(srcPath, destDir) {
35642
- mkdirSync(destDir, { recursive: true });
35643
- let dest = join7(destDir, basename3(srcPath));
35644
- if (existsSync4(dest)) {
36448
+ mkdirSync2(destDir, { recursive: true });
36449
+ let dest = join9(destDir, basename3(srcPath));
36450
+ if (existsSync5(dest)) {
35645
36451
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
35646
- dest = join7(destDir, `${basename3(srcPath)}.${stamp}`);
36452
+ dest = join9(destDir, `${basename3(srcPath)}.${stamp}`);
35647
36453
  }
35648
36454
  try {
35649
36455
  renameSync(srcPath, dest);
@@ -35654,25 +36460,25 @@ function moveFileInto(srcPath, destDir) {
35654
36460
  return dest;
35655
36461
  }
35656
36462
  function archiveSourceDb(source, cwd) {
35657
- if (!existsSync4(source.path)) {
36463
+ if (!existsSync5(source.path)) {
35658
36464
  return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
35659
36465
  }
35660
36466
  const destDir = exodusArchiveDir(source.targetScope, cwd);
35661
36467
  const archivedTo = moveFileInto(source.path, destDir);
35662
36468
  for (const suffix of SIDECAR_SUFFIXES) {
35663
36469
  const sidecar = `${source.path}${suffix}`;
35664
- if (existsSync4(sidecar)) {
36470
+ if (existsSync5(sidecar)) {
35665
36471
  try {
35666
36472
  moveFileInto(sidecar, destDir);
35667
36473
  } catch (err) {
35668
- log2.warn(
36474
+ log3.warn(
35669
36475
  { err, sidecar, sourceName: source.name },
35670
36476
  "exodus-archive: failed to archive sidecar (non-fatal)"
35671
36477
  );
35672
36478
  }
35673
36479
  }
35674
36480
  }
35675
- log2.info(
36481
+ log3.info(
35676
36482
  { sourceName: source.name, sourcePath: source.path, archivedTo, scope: source.targetScope },
35677
36483
  "exodus-archive: archived legacy source DB"
35678
36484
  );
@@ -35707,7 +36513,7 @@ function detectStrandedResidue(sources, cwd) {
35707
36513
  const stranded = [];
35708
36514
  for (const source of sources) {
35709
36515
  if (!markedScopes.has(source.targetScope)) continue;
35710
- if (existsSync4(source.path)) {
36516
+ if (existsSync5(source.path)) {
35711
36517
  stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
35712
36518
  }
35713
36519
  }
@@ -35723,14 +36529,14 @@ function archiveStrandedResidue(stranded, sources, cwd) {
35723
36529
  }
35724
36530
  return results;
35725
36531
  }
35726
- var log2, ARCHIVE_DIR_NAME, MARKER_FILENAME_BY_SCOPE, SIDECAR_SUFFIXES;
36532
+ var log3, ARCHIVE_DIR_NAME, MARKER_FILENAME_BY_SCOPE, SIDECAR_SUFFIXES;
35727
36533
  var init_archive2 = __esm({
35728
36534
  "packages/core/src/store/exodus/archive.ts"() {
35729
36535
  "use strict";
35730
36536
  init_logger2();
35731
36537
  init_paths();
35732
36538
  init_ensure_config();
35733
- log2 = getLogger("exodus-archive");
36539
+ log3 = getLogger("exodus-archive");
35734
36540
  ARCHIVE_DIR_NAME = "_archive";
35735
36541
  MARKER_FILENAME_BY_SCOPE = {
35736
36542
  project: "exodus-complete",
@@ -36124,7 +36930,7 @@ var init_table_name_map = __esm({
36124
36930
  });
36125
36931
 
36126
36932
  // packages/core/src/store/exodus/count-parity.ts
36127
- import { existsSync as existsSync5 } from "node:fs";
36933
+ import { existsSync as existsSync6 } from "node:fs";
36128
36934
  function listTables(db) {
36129
36935
  return db.prepare(
36130
36936
  "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
@@ -36145,14 +36951,14 @@ function rowCount(db, tableName) {
36145
36951
  function computeCountParity(sources, projectDbPath, globalDbPath) {
36146
36952
  const entries = [];
36147
36953
  let skipped = 0;
36148
- if (!existsSync5(projectDbPath) || !existsSync5(globalDbPath)) {
36954
+ if (!existsSync6(projectDbPath) || !existsSync6(globalDbPath)) {
36149
36955
  return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
36150
36956
  }
36151
36957
  const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
36152
36958
  const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
36153
36959
  try {
36154
36960
  for (const src of sources) {
36155
- if (!existsSync5(src.path)) continue;
36961
+ if (!existsSync6(src.path)) continue;
36156
36962
  const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
36157
36963
  try {
36158
36964
  for (const legacyTable of listTables(srcSnap.db)) {
@@ -36191,27 +36997,27 @@ function computeCountParity(sources, projectDbPath, globalDbPath) {
36191
36997
  }
36192
36998
  const deficits = entries.filter((e) => e.deficit > 0);
36193
36999
  if (deficits.length > 0) {
36194
- log3.warn(
37000
+ log4.warn(
36195
37001
  { deficitCount: deficits.length, sample: deficits.slice(0, 5) },
36196
37002
  `exodus count-parity: ${deficits.length} table(s) have FEWER rows in the consolidated target than the legacy source`
36197
37003
  );
36198
37004
  }
36199
37005
  return { ok: deficits.length === 0, entries, deficits, checked: entries.length, skipped };
36200
37006
  }
36201
- var log3;
37007
+ var log4;
36202
37008
  var init_count_parity = __esm({
36203
37009
  "packages/core/src/store/exodus/count-parity.ts"() {
36204
37010
  "use strict";
36205
37011
  init_logger2();
36206
37012
  init_open_cleo_db();
36207
37013
  init_table_name_map();
36208
- log3 = getLogger("exodus-count-parity");
37014
+ log4 = getLogger("exodus-count-parity");
36209
37015
  }
36210
37016
  });
36211
37017
 
36212
37018
  // packages/core/src/store/exodus/plan.ts
36213
- import { existsSync as existsSync6, readdirSync as readdirSync2, statfsSync, statSync } from "node:fs";
36214
- import { join as join8 } from "node:path";
37019
+ import { existsSync as existsSync7, readdirSync as readdirSync3, statfsSync, statSync } from "node:fs";
37020
+ import { join as join10 } from "node:path";
36215
37021
  function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
36216
37022
  return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
36217
37023
  }
@@ -36222,33 +37028,33 @@ function buildSourceDescriptors(cwd) {
36222
37028
  // Project-tier — go into consolidated project-scope cleo.db
36223
37029
  {
36224
37030
  name: "tasks",
36225
- path: join8(cleoDir, "tasks.db"),
37031
+ path: join10(cleoDir, "tasks.db"),
36226
37032
  targetScope: "project"
36227
37033
  },
36228
37034
  {
36229
37035
  name: "brain (project)",
36230
- path: join8(cleoDir, "brain.db"),
37036
+ path: join10(cleoDir, "brain.db"),
36231
37037
  targetScope: "project"
36232
37038
  },
36233
37039
  {
36234
37040
  name: "conduit",
36235
- path: join8(cleoDir, "conduit.db"),
37041
+ path: join10(cleoDir, "conduit.db"),
36236
37042
  targetScope: "project"
36237
37043
  },
36238
37044
  // Global-tier — go into consolidated global-scope cleo.db
36239
37045
  {
36240
37046
  name: "nexus",
36241
- path: join8(cleoHome, "nexus.db"),
37047
+ path: join10(cleoHome, "nexus.db"),
36242
37048
  targetScope: "global"
36243
37049
  },
36244
37050
  {
36245
37051
  name: "signaldock",
36246
- path: join8(cleoHome, "signaldock.db"),
37052
+ path: join10(cleoHome, "signaldock.db"),
36247
37053
  targetScope: "global"
36248
37054
  },
36249
37055
  {
36250
37056
  name: "skills",
36251
- path: join8(cleoHome, "skills.db"),
37057
+ path: join10(cleoHome, "skills.db"),
36252
37058
  targetScope: "global"
36253
37059
  }
36254
37060
  ];
@@ -36274,10 +37080,10 @@ function deriveStagingDirName() {
36274
37080
  }
36275
37081
  function findExistingStaging(cleoDir) {
36276
37082
  try {
36277
- const entries = readdirSync2(cleoDir, { withFileTypes: true });
37083
+ const entries = readdirSync3(cleoDir, { withFileTypes: true });
36278
37084
  const stagingDirs = entries.filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => e.name).sort().reverse();
36279
37085
  if (stagingDirs.length > 0) {
36280
- return join8(cleoDir, stagingDirs[0]);
37086
+ return join10(cleoDir, stagingDirs[0]);
36281
37087
  }
36282
37088
  } catch {
36283
37089
  }
@@ -36293,7 +37099,7 @@ function buildExodusPlan(cwd) {
36293
37099
  const availableBytes = getAvailableBytes(cleoDir);
36294
37100
  const diskPreflight = totalSourceBytes === 0 || availableBytes >= requiredBytes;
36295
37101
  const existingStaging = findExistingStaging(cleoDir);
36296
- const stagingDir = existingStaging ?? join8(cleoDir, deriveStagingDirName());
37102
+ const stagingDir = existingStaging ?? join10(cleoDir, deriveStagingDirName());
36297
37103
  const resumeFromStaging = existingStaging !== null;
36298
37104
  const projectDbPath = resolveDualScopeDbPath("project", cwd);
36299
37105
  const globalDbPath = resolveDualScopeDbPath("global");
@@ -36312,7 +37118,7 @@ function buildExodusPlan(cwd) {
36312
37118
  };
36313
37119
  }
36314
37120
  function sourcesPresent(sources) {
36315
- return sources.some((s) => existsSync6(s.path));
37121
+ return sources.some((s) => existsSync7(s.path));
36316
37122
  }
36317
37123
  var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
36318
37124
  var init_plan2 = __esm({
@@ -36326,18 +37132,18 @@ var init_plan2 = __esm({
36326
37132
  });
36327
37133
 
36328
37134
  // packages/core/src/store/exodus/health.ts
36329
- import { existsSync as existsSync7, statSync as statSync2 } from "node:fs";
37135
+ import { existsSync as existsSync8, statSync as statSync2 } from "node:fs";
36330
37136
  function buildExodusHealth(cwd) {
36331
37137
  const plan = buildExodusPlan(cwd);
36332
- const anyLegacyPresent = plan.sources.some((s) => existsSync7(s.path));
37138
+ const anyLegacyPresent = plan.sources.some((s) => existsSync8(s.path));
36333
37139
  const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
36334
37140
  const consolidatedExistsByScope = {
36335
- project: existsSync7(plan.projectDbPath),
36336
- global: existsSync7(plan.globalDbPath)
37141
+ project: existsSync8(plan.projectDbPath),
37142
+ global: existsSync8(plan.globalDbPath)
36337
37143
  };
36338
37144
  const buildScope = (scope) => {
36339
37145
  const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
36340
- const present = existsSync7(s.path);
37146
+ const present = existsSync8(s.path);
36341
37147
  let bytes = 0;
36342
37148
  if (present) {
36343
37149
  try {
@@ -36604,15 +37410,15 @@ var init_types = __esm({
36604
37410
  // packages/core/src/store/exodus/migrate.ts
36605
37411
  import {
36606
37412
  copyFileSync as copyFileSync3,
36607
- existsSync as existsSync8,
36608
- mkdirSync as mkdirSync2,
37413
+ existsSync as existsSync9,
37414
+ mkdirSync as mkdirSync3,
36609
37415
  readFileSync as readFileSync2,
36610
37416
  renameSync as renameSync2,
36611
37417
  statSync as statSync3,
36612
37418
  unlinkSync as unlinkSync2,
36613
- writeFileSync as writeFileSync2
37419
+ writeFileSync as writeFileSync3
36614
37420
  } from "node:fs";
36615
- import { join as join9 } from "node:path";
37421
+ import { join as join11 } from "node:path";
36616
37422
  function getSqliteVersion(db) {
36617
37423
  try {
36618
37424
  const row = db.prepare("SELECT sqlite_version() AS v").get();
@@ -36628,14 +37434,14 @@ function listTables2(db) {
36628
37434
  return rows.map((r) => r.name);
36629
37435
  }
36630
37436
  function writeJournal(stagingDir, journal) {
36631
- const journalPath = join9(stagingDir, JOURNAL_FILENAME);
37437
+ const journalPath = join11(stagingDir, JOURNAL_FILENAME);
36632
37438
  const tmpPath = `${journalPath}.tmp`;
36633
- writeFileSync2(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
37439
+ writeFileSync3(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
36634
37440
  renameSync2(tmpPath, journalPath);
36635
37441
  }
36636
37442
  function readJournal(stagingDir) {
36637
- const journalPath = join9(stagingDir, JOURNAL_FILENAME);
36638
- if (!existsSync8(journalPath)) return null;
37443
+ const journalPath = join11(stagingDir, JOURNAL_FILENAME);
37444
+ if (!existsSync9(journalPath)) return null;
36639
37445
  try {
36640
37446
  return JSON.parse(readFileSync2(journalPath, "utf8"));
36641
37447
  } catch {
@@ -36643,17 +37449,17 @@ function readJournal(stagingDir) {
36643
37449
  }
36644
37450
  }
36645
37451
  function clearExodusJournal(stagingDir) {
36646
- const journalPath = join9(stagingDir, JOURNAL_FILENAME);
37452
+ const journalPath = join11(stagingDir, JOURNAL_FILENAME);
36647
37453
  try {
36648
- if (!existsSync8(journalPath)) return false;
37454
+ if (!existsSync9(journalPath)) return false;
36649
37455
  unlinkSync2(journalPath);
36650
- log4.info(
37456
+ log5.info(
36651
37457
  { stagingDir },
36652
37458
  "exodus: cleared migrate journal after abort/rollback \u2014 a retry will RE-COPY all tables"
36653
37459
  );
36654
37460
  return true;
36655
37461
  } catch (err) {
36656
- log4.warn(
37462
+ log5.warn(
36657
37463
  { err, stagingDir },
36658
37464
  'exodus: failed to clear migrate journal after rollback (a retry may skip already-"done" tables)'
36659
37465
  );
@@ -36678,7 +37484,7 @@ function lockPath(dbPath) {
36678
37484
  }
36679
37485
  function acquireAdvisoryLock(dbPath) {
36680
37486
  const lp = lockPath(dbPath);
36681
- writeFileSync2(lp, JSON.stringify({ pid: process.pid, ts: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
37487
+ writeFileSync3(lp, JSON.stringify({ pid: process.pid, ts: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
36682
37488
  }
36683
37489
  function releaseAdvisoryLock(dbPath) {
36684
37490
  try {
@@ -36741,7 +37547,7 @@ function buildSelectExpr(attachAlias, legacyTable, targetTableName, col, srcType
36741
37547
  function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyTableName, sourceName, targetSchema = "main") {
36742
37548
  const resolution = resolveConsolidatedTableName(sourceName, legacyTableName);
36743
37549
  if (resolution.kind === "skip") {
36744
- log4.warn(
37550
+ log5.warn(
36745
37551
  { legacyTableName, sourceName, reason: resolution.reason },
36746
37552
  `Exodus: explicitly skipping table \u2014 ${resolution.reason}`
36747
37553
  );
@@ -36760,7 +37566,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36760
37566
  ).get();
36761
37567
  if (!existsRow) {
36762
37568
  const reason = `consolidated target '${targetTableName}' not found (mapped from legacy '${legacyTableName}')`;
36763
- log4.warn(
37569
+ log5.warn(
36764
37570
  { legacyTableName, targetTableName, sourceName, attachAlias, targetSchema },
36765
37571
  `Exodus: ${reason}`
36766
37572
  );
@@ -36771,13 +37577,13 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36771
37577
  const sharedColumns = srcPragma.map((r) => r.name).filter((col) => tgtColMap.has(col));
36772
37578
  if (sharedColumns.length === 0) {
36773
37579
  const reason = `no overlapping columns between source '${legacyTableName}' and target '${targetTableName}'`;
36774
- log4.warn({ legacyTableName, targetTableName, sourceName }, `Exodus: ${reason}`);
37580
+ log5.warn({ legacyTableName, targetTableName, sourceName }, `Exodus: ${reason}`);
36775
37581
  return { rowsCopied: 0, skipped: true, reason };
36776
37582
  }
36777
37583
  const srcOnlyColumns = srcPragma.map((r) => r.name).filter((c) => !tgtColMap.has(c));
36778
37584
  const tgtOnlyColumns = tgtPragma.map((r) => r.name).filter((c) => !srcColumns.has(c));
36779
37585
  if (srcOnlyColumns.length > 0 || tgtOnlyColumns.length > 0) {
36780
- log4.info(
37586
+ log5.info(
36781
37587
  { legacyTableName, targetTableName, sourceName, srcOnlyColumns, tgtOnlyColumns },
36782
37588
  "Exodus: column drift detected \u2014 copying intersection, dropping src-only cols, using defaults for tgt-only cols"
36783
37589
  );
@@ -36792,7 +37598,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36792
37598
  return isoGlobCols.has(col) && (upper.includes("INT") || upper === "" || upper === "NUMERIC");
36793
37599
  });
36794
37600
  if (coercedCols.length > 0) {
36795
- log4.info(
37601
+ log5.info(
36796
37602
  {
36797
37603
  legacyTableName,
36798
37604
  targetTableName,
@@ -36808,7 +37614,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36808
37614
  (col) => ENUM_NORMALIZATIONS.has(`${targetTableName}.${col}`)
36809
37615
  );
36810
37616
  if (normalizedCols.length > 0) {
36811
- log4.info(
37617
+ log5.info(
36812
37618
  { legacyTableName, targetTableName, sourceName, normalizedCols },
36813
37619
  `Exodus: applying enum-value normalization for ${normalizedCols.length} column(s) (T11547)`
36814
37620
  );
@@ -36817,7 +37623,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36817
37623
  (col) => NUMERIC_CLAMPS.has(`${targetTableName}.${col}`)
36818
37624
  );
36819
37625
  if (clampedCols.length > 0) {
36820
- log4.info(
37626
+ log5.info(
36821
37627
  { legacyTableName, targetTableName, sourceName, clampedCols },
36822
37628
  `Exodus: applying non-finite numeric clamp for ${clampedCols.length} column(s) (T11782)`
36823
37629
  );
@@ -36859,7 +37665,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36859
37665
  if (rowsCopied < sourceCount) {
36860
37666
  const presentAccountedFor = existingBefore + rowsCopied;
36861
37667
  if (presentAccountedFor >= sourceCount) {
36862
- log4.info(
37668
+ log5.info(
36863
37669
  { legacyTableName, targetTableName, sourceName, sourceCount, rowsCopied, existingBefore },
36864
37670
  `Exodus: '${legacyTableName}'\u2192'${targetTableName}' \u2014 ${sourceCount - rowsCopied} of ${sourceCount} row(s) already present in target (idempotent PK dedup), ${rowsCopied} newly copied; no loss`
36865
37671
  );
@@ -36867,7 +37673,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36867
37673
  }
36868
37674
  const missing = sourceCount - presentAccountedFor;
36869
37675
  const reason = `INSERT OR IGNORE lost ${missing} of ${sourceCount} rows from '${legacyTableName}'\u2192'${targetTableName}' (rowsCopied=${rowsCopied}, existingBefore=${existingBefore}) \u2014 a CHECK/NOT NULL/type/enum constraint rejected them (NOT PK dedup); inspect epoch coercion + enum normalization. verify will confirm.`;
36870
- log4.error(
37676
+ log5.error(
36871
37677
  {
36872
37678
  legacyTableName,
36873
37679
  targetTableName,
@@ -36887,10 +37693,10 @@ function checkSchemaVersion(journal, forceCrossVersion) {
36887
37693
  if (journal.targetSchemaVersion !== EXODUS_TARGET_SCHEMA_VERSION) {
36888
37694
  const msg = `Schema version mismatch: journal=${journal.targetSchemaVersion}, expected=${EXODUS_TARGET_SCHEMA_VERSION}`;
36889
37695
  if (forceCrossVersion) {
36890
- log4.warn(msg + " (--force-cross-version: continuing anyway)");
37696
+ log5.warn(msg + " (--force-cross-version: continuing anyway)");
36891
37697
  return true;
36892
37698
  }
36893
- log4.error(msg + " \u2014 pass --force-cross-version to override");
37699
+ log5.error(msg + " \u2014 pass --force-cross-version to override");
36894
37700
  return false;
36895
37701
  }
36896
37702
  return true;
@@ -36907,10 +37713,10 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
36907
37713
  error: `Insufficient disk space for exodus: need \u2265${plan.requiredBytes} bytes (\u2248${STAGING_HEADROOM_FACTOR}\xD7 largest source ${plan.largestSourceBytes} + consolidated estimate ${plan.totalSourceBytes}), but only ${plan.availableBytes} bytes are free on the target filesystem \u2014 ${shortfall} bytes short. Free up at least ${shortfall} bytes (e.g. \`cleo backup prune\`, clear caches), or move the .cleo/ directory to a larger volume, then retry.`
36908
37714
  };
36909
37715
  }
36910
- mkdirSync2(stagingDir, { recursive: true });
37716
+ mkdirSync3(stagingDir, { recursive: true });
36911
37717
  let sqliteVersion = "unknown";
36912
37718
  for (const src of sources) {
36913
- if (existsSync8(src.path)) {
37719
+ if (existsSync9(src.path)) {
36914
37720
  const snap = openCleoDbSnapshot(src.path, { readOnly: true });
36915
37721
  sqliteVersion = getSqliteVersion(snap.db);
36916
37722
  snap.close();
@@ -36951,15 +37757,15 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
36951
37757
  };
36952
37758
  var extractNativeDb = extractNativeDb2;
36953
37759
  for (const src of sources) {
36954
- if (!existsSync8(src.path)) continue;
36955
- const backupDest = join9(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
37760
+ if (!existsSync9(src.path)) continue;
37761
+ const backupDest = join11(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
36956
37762
  const srcBytes = safeStatBytes(src.path);
36957
37763
  const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
36958
37764
  if (skipStagingCopy) {
36959
37765
  onProgress?.(
36960
37766
  `Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
36961
37767
  );
36962
- } else if (!existsSync8(backupDest)) {
37768
+ } else if (!existsSync9(backupDest)) {
36963
37769
  onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
36964
37770
  copyFileSync3(src.path, backupDest);
36965
37771
  backupPaths.push(backupDest);
@@ -36977,8 +37783,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
36977
37783
  });
36978
37784
  const projectNative = extractNativeDb2(projectHandle);
36979
37785
  const globalNative = extractNativeDb2(globalHandle);
36980
- const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync8(s.path));
36981
- const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync8(s.path));
37786
+ const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync9(s.path));
37787
+ const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync9(s.path));
36982
37788
  await migrateScope(
36983
37789
  "project",
36984
37790
  projectSources,
@@ -37003,7 +37809,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
37003
37809
  return { ok: true, tables: allTableResults, stagingDir, backupPaths };
37004
37810
  } catch (err) {
37005
37811
  const error48 = err instanceof Error ? err.message : String(err);
37006
- log4.error({ err }, "Exodus migration failed");
37812
+ log5.error({ err }, "Exodus migration failed");
37007
37813
  return { ok: false, tables: allTableResults, stagingDir, backupPaths, error: error48 };
37008
37814
  } finally {
37009
37815
  try {
@@ -37023,7 +37829,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37023
37829
  if (sources.length === 0) return;
37024
37830
  onProgress?.(`Migrating ${scope}-scope sources\u2026`);
37025
37831
  targetNativeDb.exec("PRAGMA foreign_keys = OFF");
37026
- log4.info({ scope }, "Exodus: foreign_keys=OFF for bulk copy (T11533 FK-defer)");
37832
+ log5.info({ scope }, "Exodus: foreign_keys=OFF for bulk copy (T11533 FK-defer)");
37027
37833
  try {
37028
37834
  for (let i = 0; i < sources.length; i++) {
37029
37835
  const src = sources[i];
@@ -37090,7 +37896,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37090
37896
  }
37091
37897
  } catch (err) {
37092
37898
  const msg = err instanceof Error ? err.message : String(err);
37093
- log4.warn({ tableName, sourceDb: src.name, err }, "Table copy failed \u2014 skipping");
37899
+ log5.warn({ tableName, sourceDb: src.name, err }, "Table copy failed \u2014 skipping");
37094
37900
  status = "skipped";
37095
37901
  errorMsg = msg;
37096
37902
  skipped = true;
@@ -37138,7 +37944,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37138
37944
  targetNativeDb.exec(`DETACH DATABASE "${attachAlias}"`);
37139
37945
  onProgress?.(` [${src.name}] Detached "${attachAlias}"`);
37140
37946
  } catch (detachErr) {
37141
- log4.warn(
37947
+ log5.warn(
37142
37948
  { attachAlias, sourceDb: src.name, err: detachErr },
37143
37949
  "DETACH failed \u2014 alias will be released on DB close"
37144
37950
  );
@@ -37148,7 +37954,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37148
37954
  targetNativeDb.exec(`DETACH DATABASE "${crossAlias}"`);
37149
37955
  onProgress?.(` [${src.name}] Cross-scope target detached "${crossAlias}"`);
37150
37956
  } catch (detachErr) {
37151
- log4.warn(
37957
+ log5.warn(
37152
37958
  { crossAlias, sourceDb: src.name, err: detachErr },
37153
37959
  "Cross-scope DETACH failed \u2014 alias will be released on DB close"
37154
37960
  );
@@ -37160,28 +37966,28 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37160
37966
  try {
37161
37967
  const orphans = targetNativeDb.prepare("PRAGMA foreign_key_check").all();
37162
37968
  if (orphans.length > 0) {
37163
- log4.warn(
37969
+ log5.warn(
37164
37970
  { scope, orphanCount: orphans.length, sample: orphans.slice(0, 5) },
37165
37971
  `Exodus: PRAGMA foreign_key_check found ${orphans.length} orphan row(s) after bulk copy \u2014 these are genuine data orphans (not ordering artifacts)`
37166
37972
  );
37167
37973
  } else {
37168
- log4.info({ scope }, "Exodus: PRAGMA foreign_key_check PASSED \u2014 no orphan rows");
37974
+ log5.info({ scope }, "Exodus: PRAGMA foreign_key_check PASSED \u2014 no orphan rows");
37169
37975
  }
37170
37976
  } catch (checkErr) {
37171
- log4.warn(
37977
+ log5.warn(
37172
37978
  { scope, err: checkErr },
37173
37979
  "Exodus: PRAGMA foreign_key_check failed (non-fatal) \u2014 target schema may not have FK constraints enabled"
37174
37980
  );
37175
37981
  }
37176
37982
  try {
37177
37983
  targetNativeDb.exec("PRAGMA foreign_keys = ON");
37178
- log4.info({ scope }, "Exodus: foreign_keys=ON restored after bulk copy");
37984
+ log5.info({ scope }, "Exodus: foreign_keys=ON restored after bulk copy");
37179
37985
  } catch (fkErr) {
37180
- log4.warn({ scope, err: fkErr }, "Exodus: could not restore foreign_keys=ON (non-fatal)");
37986
+ log5.warn({ scope, err: fkErr }, "Exodus: could not restore foreign_keys=ON (non-fatal)");
37181
37987
  }
37182
37988
  }
37183
37989
  }
37184
- var log4, LOCK_SENTINEL_SUFFIX, JOURNAL_FILENAME, SOURCE_EPOCH_UNITS;
37990
+ var log5, LOCK_SENTINEL_SUFFIX, JOURNAL_FILENAME, SOURCE_EPOCH_UNITS;
37185
37991
  var init_migrate = __esm({
37186
37992
  "packages/core/src/store/exodus/migrate.ts"() {
37187
37993
  "use strict";
@@ -37193,7 +37999,7 @@ var init_migrate = __esm({
37193
37999
  init_plan2();
37194
38000
  init_table_name_map();
37195
38001
  init_types();
37196
- log4 = getLogger("exodus-migrate");
38002
+ log5 = getLogger("exodus-migrate");
37197
38003
  LOCK_SENTINEL_SUFFIX = ".exodus-lock";
37198
38004
  JOURNAL_FILENAME = "exodus-journal.json";
37199
38005
  SOURCE_EPOCH_UNITS = /* @__PURE__ */ new Map([
@@ -37217,7 +38023,7 @@ function sealExodus(plan, scopeArg, cwd) {
37217
38023
  const parity = computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath);
37218
38024
  if (!parity.ok) {
37219
38025
  const refusedReason = `Refusing to seal: ${parity.deficits.length} table(s) have FEWER rows in the consolidated cleo.db than the legacy source \u2014 the data is NOT fully migrated. Run \`cleo exodus migrate\` first. Deficits: ${parity.deficits.map((d) => `${d.targetTable}(${d.sourceCount}\u2192${d.targetCount})`).join(", ")}`;
37220
- log5.error({ deficits: parity.deficits.length }, `exodus seal refused \u2014 ${refusedReason}`);
38026
+ log6.error({ deficits: parity.deficits.length }, `exodus seal refused \u2014 ${refusedReason}`);
37221
38027
  return { ok: false, refusedReason, parity, scopes: [] };
37222
38028
  }
37223
38029
  const outcomes = [];
@@ -37233,7 +38039,7 @@ function sealExodus(plan, scopeArg, cwd) {
37233
38039
  scopeSources.map((s) => s.name),
37234
38040
  cwd
37235
38041
  );
37236
- log5.info(
38042
+ log6.info(
37237
38043
  { scope, alreadySealed, archived: archived.filter((a) => a.action === "archived").length },
37238
38044
  `exodus seal: scope '${scope}' certified (count-parity verified, ${parity.checked} tables)`
37239
38045
  );
@@ -37241,23 +38047,23 @@ function sealExodus(plan, scopeArg, cwd) {
37241
38047
  }
37242
38048
  return { ok: true, parity, scopes: outcomes };
37243
38049
  }
37244
- var log5;
38050
+ var log6;
37245
38051
  var init_seal = __esm({
37246
38052
  "packages/core/src/store/exodus/seal.ts"() {
37247
38053
  "use strict";
37248
38054
  init_logger2();
37249
38055
  init_archive2();
37250
38056
  init_count_parity();
37251
- log5 = getLogger("exodus-seal");
38057
+ log6 = getLogger("exodus-seal");
37252
38058
  }
37253
38059
  });
37254
38060
 
37255
38061
  // packages/core/src/store/exodus/status.ts
37256
- import { existsSync as existsSync9, readdirSync as readdirSync3, readFileSync as readFileSync3, statSync as statSync4 } from "node:fs";
37257
- import { join as join10 } from "node:path";
38062
+ import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as readFileSync3, statSync as statSync4 } from "node:fs";
38063
+ import { join as join12 } from "node:path";
37258
38064
  function readJournal2(stagingDir) {
37259
- const p = join10(stagingDir, JOURNAL_FILENAME2);
37260
- if (!existsSync9(p)) return null;
38065
+ const p = join12(stagingDir, JOURNAL_FILENAME2);
38066
+ if (!existsSync10(p)) return null;
37261
38067
  try {
37262
38068
  return JSON.parse(readFileSync3(p, "utf8"));
37263
38069
  } catch {
@@ -37266,7 +38072,7 @@ function readJournal2(stagingDir) {
37266
38072
  }
37267
38073
  function findStagingDirs(cleoDir) {
37268
38074
  try {
37269
- return readdirSync3(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join10(cleoDir, e.name)).sort().reverse();
38075
+ return readdirSync4(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join12(cleoDir, e.name)).sort().reverse();
37270
38076
  } catch {
37271
38077
  return [];
37272
38078
  }
@@ -37289,15 +38095,15 @@ function runExodusStatus(cwd) {
37289
38095
  const sourcesInfo = plan.sources.map((s) => ({
37290
38096
  name: s.name,
37291
38097
  path: s.path,
37292
- exists: existsSync9(s.path),
38098
+ exists: existsSync10(s.path),
37293
38099
  bytes: safeBytes(s.path)
37294
38100
  }));
37295
38101
  return {
37296
38102
  hasStaging: latestStaging !== null,
37297
38103
  stagingDir: latestStaging,
37298
38104
  journal,
37299
- projectDbExists: existsSync9(projectDbPath),
37300
- globalDbExists: existsSync9(globalDbPath),
38105
+ projectDbExists: existsSync10(projectDbPath),
38106
+ globalDbExists: existsSync10(globalDbPath),
37301
38107
  sourcesPresent: sourcesInfo.some((s) => s.exists),
37302
38108
  sources: sourcesInfo
37303
38109
  };
@@ -37314,7 +38120,7 @@ var init_status = __esm({
37314
38120
  });
37315
38121
 
37316
38122
  // packages/core/src/store/exodus/verify-migration.ts
37317
- import { existsSync as existsSync10 } from "node:fs";
38123
+ import { existsSync as existsSync11 } from "node:fs";
37318
38124
  import { createRequire as createRequire3 } from "node:module";
37319
38125
  function orderByClause(db, tableName) {
37320
38126
  try {
@@ -37334,7 +38140,7 @@ function computeTableDigest(db, tableName, columns, transform2) {
37334
38140
  count = Number(row?.c ?? 0);
37335
38141
  } catch (err) {
37336
38142
  const msg = err instanceof Error ? err.message : String(err);
37337
- log6.warn(
38143
+ log7.warn(
37338
38144
  { tableName, err: msg },
37339
38145
  "computeTableDigest: COUNT(*) failed (possibly a virtual/FTS table) \u2014 treating as 0 rows"
37340
38146
  );
@@ -37369,7 +38175,7 @@ function computeTableDigest(db, tableName, columns, transform2) {
37369
38175
  }
37370
38176
  } catch (err) {
37371
38177
  const msg = err instanceof Error ? err.message : String(err);
37372
- log6.warn(
38178
+ log7.warn(
37373
38179
  { tableName, err: msg },
37374
38180
  "computeTableDigest: streamed SELECT failed (possibly a virtual/FTS table) \u2014 digest skipped (COUNT(*) parity still enforced)"
37375
38181
  );
@@ -37495,7 +38301,7 @@ function foreignKeyCheck(db, scope) {
37495
38301
  try {
37496
38302
  const rows = db.prepare("PRAGMA foreign_key_check").all();
37497
38303
  if (rows.length > 0) {
37498
- log6.warn(
38304
+ log7.warn(
37499
38305
  { scope, count: rows.length, sample: rows.slice(0, 5) },
37500
38306
  `verifyMigration: PRAGMA foreign_key_check found ${rows.length} orphan row(s)`
37501
38307
  );
@@ -37507,7 +38313,7 @@ function foreignKeyCheck(db, scope) {
37507
38313
  fkid: r.fkid
37508
38314
  }));
37509
38315
  } catch (err) {
37510
- log6.warn({ scope, err }, "verifyMigration: PRAGMA foreign_key_check failed (non-fatal)");
38316
+ log7.warn({ scope, err }, "verifyMigration: PRAGMA foreign_key_check failed (non-fatal)");
37511
38317
  return [];
37512
38318
  }
37513
38319
  }
@@ -37544,13 +38350,13 @@ function sourceOrphanSignatures(db, sourceName, scope) {
37544
38350
  const rows = db.prepare("PRAGMA foreign_key_check").all();
37545
38351
  for (const r of rows) sigs.add(orphanSignature(db, r, sourceName));
37546
38352
  if (rows.length > 0) {
37547
- log6.warn(
38353
+ log7.warn(
37548
38354
  { scope, count: rows.length, sample: rows.slice(0, 5) },
37549
38355
  `verifyMigration: source already has ${rows.length} pre-existing FK orphan(s) \u2014 these are tolerated (carried forward losslessly, flagged for data-hygiene)`
37550
38356
  );
37551
38357
  }
37552
38358
  } catch (err) {
37553
- log6.warn({ scope, err }, "verifyMigration: source PRAGMA foreign_key_check failed (non-fatal)");
38359
+ log7.warn({ scope, err }, "verifyMigration: source PRAGMA foreign_key_check failed (non-fatal)");
37554
38360
  }
37555
38361
  return sigs;
37556
38362
  }
@@ -37562,7 +38368,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37562
38368
  const preExistingForeignKeyViolations = [];
37563
38369
  const failureLines = [];
37564
38370
  const sourceOrphanSigs = /* @__PURE__ */ new Set();
37565
- if (!existsSync10(projectDbPath)) {
38371
+ if (!existsSync11(projectDbPath)) {
37566
38372
  return {
37567
38373
  ok: false,
37568
38374
  tables: [],
@@ -37573,7 +38379,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37573
38379
  error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
37574
38380
  };
37575
38381
  }
37576
- if (!existsSync10(globalDbPath)) {
38382
+ if (!existsSync11(globalDbPath)) {
37577
38383
  return {
37578
38384
  ok: false,
37579
38385
  tables: [],
@@ -37588,7 +38394,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37588
38394
  const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
37589
38395
  try {
37590
38396
  for (const src of sources) {
37591
- if (!existsSync10(src.path)) {
38397
+ if (!existsSync11(src.path)) {
37592
38398
  onProgress?.(`Skipping ${src.name} (not present)`);
37593
38399
  continue;
37594
38400
  }
@@ -37673,7 +38479,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37673
38479
  `[${scope}] ${src.name}.${legacyTableName} \u2192 ${targetTableName}: DEFICIT \u2014 source=${srcDigest.count} rows, target=${tgtDigest.count} rows (${srcDigest.count - tgtDigest.count} missing), hashMatch=${hashMatch}`
37674
38480
  );
37675
38481
  } else if (tgtDigest.count > srcDigest.count) {
37676
- log6.warn(
38482
+ log7.warn(
37677
38483
  {
37678
38484
  scope,
37679
38485
  source: src.name,
@@ -37723,7 +38529,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37723
38529
  }
37724
38530
  }
37725
38531
  if (preExistingForeignKeyViolations.length > 0) {
37726
- log6.warn(
38532
+ log7.warn(
37727
38533
  {
37728
38534
  count: preExistingForeignKeyViolations.length,
37729
38535
  sample: preExistingForeignKeyViolations.slice(0, 5)
@@ -37733,7 +38539,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37733
38539
  }
37734
38540
  } catch (err) {
37735
38541
  const error48 = err instanceof Error ? err.message : String(err);
37736
- log6.error({ err }, "verifyMigration failed");
38542
+ log7.error({ err }, "verifyMigration failed");
37737
38543
  return {
37738
38544
  ok: false,
37739
38545
  tables,
@@ -37750,7 +38556,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37750
38556
  if (failureLines.length > 0) {
37751
38557
  const error48 = `verifyMigration FAILED: ${failureLines.length} issue(s):
37752
38558
  ${failureLines.map((l) => ` \u2022 ${l}`).join("\n")}`;
37753
- log6.error({ failureCount: failureLines.length }, error48);
38559
+ log7.error({ failureCount: failureLines.length }, error48);
37754
38560
  return {
37755
38561
  ok: false,
37756
38562
  tables,
@@ -37770,7 +38576,7 @@ ${failureLines.map((l) => ` \u2022 ${l}`).join("\n")}`;
37770
38576
  enumDrift
37771
38577
  };
37772
38578
  }
37773
- var log6, _require, CHECK_ENUM_REGEX;
38579
+ var log7, _require, CHECK_ENUM_REGEX;
37774
38580
  var init_verify_migration = __esm({
37775
38581
  "packages/core/src/store/exodus/verify-migration.ts"() {
37776
38582
  "use strict";
@@ -37779,7 +38585,7 @@ var init_verify_migration = __esm({
37779
38585
  init_open_cleo_db();
37780
38586
  init_column_transforms();
37781
38587
  init_table_name_map();
37782
- log6 = getLogger("verify-migration");
38588
+ log7 = getLogger("verify-migration");
37783
38589
  _require = createRequire3(import.meta.url);
37784
38590
  CHECK_ENUM_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+(?:IS\s+NULL\s+OR\s+"[^"]+"\s+)?IN\s*\(([^)]*)\)\s*\)/gi;
37785
38591
  }
@@ -37871,7 +38677,7 @@ __export(on_open_exports, {
37871
38677
  isDataContinuityOk: () => isDataContinuityOk,
37872
38678
  maybeRunExodusOnOpen: () => maybeRunExodusOnOpen
37873
38679
  });
37874
- import { existsSync as existsSync11 } from "node:fs";
38680
+ import { existsSync as existsSync12 } from "node:fs";
37875
38681
  function isDisabledByEnv() {
37876
38682
  const v = process.env.CLEO_DISABLE_EXODUS_ON_OPEN;
37877
38683
  return v === "1" || v === "true";
@@ -37897,7 +38703,7 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
37897
38703
  "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%'"
37898
38704
  ).all().map((r) => r.name);
37899
38705
  } catch (err) {
37900
- log7.error({ err, scope }, "exodus-on-open: failed to enumerate tables for rollback");
38706
+ log8.error({ err, scope }, "exodus-on-open: failed to enumerate tables for rollback");
37901
38707
  return;
37902
38708
  }
37903
38709
  try {
@@ -37907,7 +38713,7 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
37907
38713
  try {
37908
38714
  nativeDb.exec(`DELETE FROM "${table}"`);
37909
38715
  } catch (err) {
37910
- log7.warn({ err, table, scope }, "exodus-on-open: failed to clear table during rollback");
38716
+ log8.warn({ err, table, scope }, "exodus-on-open: failed to clear table during rollback");
37911
38717
  }
37912
38718
  }
37913
38719
  nativeDb.exec("COMMIT");
@@ -37916,7 +38722,7 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
37916
38722
  nativeDb.exec("ROLLBACK");
37917
38723
  } catch {
37918
38724
  }
37919
- log7.error({ err, scope }, "exodus-on-open: rollback transaction failed");
38725
+ log8.error({ err, scope }, "exodus-on-open: rollback transaction failed");
37920
38726
  } finally {
37921
38727
  try {
37922
38728
  nativeDb.exec("PRAGMA foreign_keys = ON");
@@ -37936,7 +38742,7 @@ async function rollbackBothScopes(scope, projectDbPath, globalDbPath) {
37936
38742
  rollbackConsolidatedToEmpty(native, s);
37937
38743
  }
37938
38744
  } catch (err) {
37939
- log7.warn(
38745
+ log8.warn(
37940
38746
  { err, scope: s, openingScope: scope },
37941
38747
  "exodus-on-open: could not roll back scope (best-effort)"
37942
38748
  );
@@ -37952,7 +38758,7 @@ function isDataContinuityOk(result) {
37952
38758
  const deficits = result.tables.filter((t) => t.targetCount < t.sourceCount);
37953
38759
  const surpluses = result.tables.filter((t) => t.targetCount > t.sourceCount);
37954
38760
  if (surpluses.length > 0) {
37955
- log7.warn(
38761
+ log8.warn(
37956
38762
  {
37957
38763
  surpluses: surpluses.map((t) => ({
37958
38764
  table: t.targetTable,
@@ -37986,7 +38792,7 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
37986
38792
  const { buildExodusPlan: buildExodusPlan2, runExodusMigrate: runExodusMigrate2, verifyMigration: verifyMigration2, clearExodusJournal: clearExodusJournal2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
37987
38793
  const plan = buildExodusPlan2(cwd);
37988
38794
  const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
37989
- if (!scopeSources.some((s) => existsSync11(s.path))) {
38795
+ if (!scopeSources.some((s) => existsSync12(s.path))) {
37990
38796
  return {
37991
38797
  outcome: "skipped",
37992
38798
  reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
@@ -37999,11 +38805,11 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
37999
38805
  if (!consolidatedIsEmpty(nativeDb, scope)) {
38000
38806
  return { outcome: "skipped", reason: "migrated by a concurrent process (lock winner)" };
38001
38807
  }
38002
- log7.info(
38808
+ log8.info(
38003
38809
  {
38004
38810
  scope,
38005
38811
  dbPath,
38006
- sources: plan.sources.filter((s) => existsSync11(s.path)).map((s) => s.name)
38812
+ sources: plan.sources.filter((s) => existsSync12(s.path)).map((s) => s.name)
38007
38813
  },
38008
38814
  "exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
38009
38815
  );
@@ -38012,23 +38818,23 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38012
38818
  const migrateResult = await runExodusMigrate2(
38013
38819
  plan,
38014
38820
  false,
38015
- (msg) => log7.debug({ scope }, `exodus-on-open: ${msg}`)
38821
+ (msg) => log8.debug({ scope }, `exodus-on-open: ${msg}`)
38016
38822
  );
38017
38823
  if (!migrateResult.ok) {
38018
38824
  await rollbackBothScopes(scope, plan.projectDbPath, plan.globalDbPath);
38019
38825
  clearExodusJournal2(migrateResult.stagingDir);
38020
38826
  const reason = `migration failed: ${migrateResult.error ?? "unknown error"} \u2014 legacy DBs kept as source`;
38021
- log7.error({ scope, error: migrateResult.error }, `exodus-on-open: ${reason}`);
38827
+ log8.error({ scope, error: migrateResult.error }, `exodus-on-open: ${reason}`);
38022
38828
  return { outcome: "aborted", reason };
38023
38829
  }
38024
38830
  const verifyResult = verifyMigration2(
38025
38831
  plan.sources,
38026
38832
  plan.projectDbPath,
38027
38833
  plan.globalDbPath,
38028
- (msg) => log7.debug({ scope }, `exodus-on-open verify: ${msg}`)
38834
+ (msg) => log8.debug({ scope }, `exodus-on-open verify: ${msg}`)
38029
38835
  );
38030
38836
  if (!verifyResult.ok) {
38031
- log7.warn(
38837
+ log8.warn(
38032
38838
  {
38033
38839
  scope,
38034
38840
  enumDrift: verifyResult.enumDrift.length,
@@ -38042,7 +38848,7 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38042
38848
  clearExodusJournal2(plan.stagingDir);
38043
38849
  const deficits = verifyResult.tables.filter((t) => t.targetCount < t.sourceCount).map((t) => `${t.targetTable}(${t.sourceCount}\u2192${t.targetCount})`);
38044
38850
  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();
38045
- log7.error(
38851
+ log8.error(
38046
38852
  {
38047
38853
  scope,
38048
38854
  countDeficits: deficits,
@@ -38054,14 +38860,14 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38054
38860
  return { outcome: "aborted", reason };
38055
38861
  }
38056
38862
  const rowsCopied = migrateResult.tables.filter((t) => !t.skipped).reduce((n, t) => n + t.rowsCopied, 0);
38057
- log7.info(
38863
+ log8.info(
38058
38864
  { scope, rowsCopied, tables: migrateResult.tables.length },
38059
38865
  "exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
38060
38866
  );
38061
38867
  try {
38062
- const consumed = plan.sources.filter((s) => existsSync11(s.path));
38868
+ const consumed = plan.sources.filter((s) => existsSync12(s.path));
38063
38869
  const archiveResult = archiveMigratedSources(consumed, cwd);
38064
- log7.info(
38870
+ log8.info(
38065
38871
  {
38066
38872
  scope,
38067
38873
  archived: archiveResult.sources.filter((s) => s.action === "archived").length,
@@ -38070,7 +38876,7 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38070
38876
  "exodus-on-open: archived legacy sources + sealed completion marker(s)"
38071
38877
  );
38072
38878
  } catch (err) {
38073
- log7.error(
38879
+ log8.error(
38074
38880
  { err, scope },
38075
38881
  "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`)"
38076
38882
  );
@@ -38092,14 +38898,14 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38092
38898
  function _isExodusInProgress() {
38093
38899
  return _exodusInProgress;
38094
38900
  }
38095
- var log7, _exodusInProgress;
38901
+ var log8, _exodusInProgress;
38096
38902
  var init_on_open = __esm({
38097
38903
  "packages/core/src/store/exodus/on-open.ts"() {
38098
38904
  "use strict";
38099
38905
  init_logger2();
38100
38906
  init_lock();
38101
38907
  init_archive2();
38102
- log7 = getLogger("exodus-on-open");
38908
+ log8 = getLogger("exodus-on-open");
38103
38909
  _exodusInProgress = false;
38104
38910
  }
38105
38911
  });
@@ -38116,9 +38922,9 @@ __export(dual_scope_db_exports, {
38116
38922
  resolveDualScopeDbPath: () => resolveDualScopeDbPath,
38117
38923
  upsertIdempotent: () => upsertIdempotent
38118
38924
  });
38119
- import { existsSync as existsSync12, mkdirSync as mkdirSync3 } from "node:fs";
38925
+ import { existsSync as existsSync13, mkdirSync as mkdirSync4 } from "node:fs";
38120
38926
  import { createRequire as createRequire4 } from "node:module";
38121
- import { dirname as dirname5, join as join11 } from "node:path";
38927
+ import { dirname as dirname5, join as join13 } from "node:path";
38122
38928
  function assertWriteDurable(handle) {
38123
38929
  if (handle.exodusAbort) {
38124
38930
  throw new ExodusAbortWriteUnsafeError(handle.exodusAbort);
@@ -38135,9 +38941,9 @@ function cacheKey(scope, dbPath) {
38135
38941
  }
38136
38942
  function resolveDualScopeDbPath(scope, cwd) {
38137
38943
  if (scope === "project") {
38138
- return join11(resolveCleoDir(cwd), "cleo.db");
38944
+ return join13(resolveCleoDir(cwd), "cleo.db");
38139
38945
  }
38140
- return join11(getCleoHome(), "cleo.db");
38946
+ return join13(getCleoHome(), "cleo.db");
38141
38947
  }
38142
38948
  function migrationsSetName(scope) {
38143
38949
  return scope === "project" ? "drizzle-cleo-project" : "drizzle-cleo-global";
@@ -38180,11 +38986,11 @@ async function openDualScopeDb(scope, cwd) {
38180
38986
  const dbPath = resolveDualScopeDbPath(scope, cwd);
38181
38987
  return scope === "project" ? openDualScopeDbAtPath("project", dbPath, cwd) : openDualScopeDbAtPath("global", dbPath, cwd);
38182
38988
  }
38183
- async function openDedicatedDualScopeDb(scope, dbPath, log8) {
38184
- log8.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
38989
+ async function openDedicatedDualScopeDb(scope, dbPath, log9) {
38990
+ log9.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
38185
38991
  const dir = dirname5(dbPath);
38186
- if (!existsSync12(dir)) {
38187
- mkdirSync3(dir, { recursive: true });
38992
+ if (!existsSync13(dir)) {
38993
+ mkdirSync4(dir, { recursive: true });
38188
38994
  }
38189
38995
  const DatabaseSyncCtor = getDatabaseSyncCtor();
38190
38996
  const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
@@ -38207,7 +39013,7 @@ async function openDedicatedDualScopeDb(scope, dbPath, log8) {
38207
39013
  existenceTable(scope),
38208
39014
  `dual-scope-db[${scope}]`
38209
39015
  );
38210
- log8.debug({ scope, dbPath }, "DEDICATED dual-scope cleo.db ready (T11782 FIX D)");
39016
+ log9.debug({ scope, dbPath }, "DEDICATED dual-scope cleo.db ready (T11782 FIX D)");
38211
39017
  return {
38212
39018
  db,
38213
39019
  scope,
@@ -38232,15 +39038,15 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38232
39038
  return existing.handle;
38233
39039
  }
38234
39040
  }
38235
- const log8 = getLogger("dual-scope-db");
39041
+ const log9 = getLogger("dual-scope-db");
38236
39042
  if (dedicated) {
38237
- return openDedicatedDualScopeDb(scope, dbPath, log8);
39043
+ return openDedicatedDualScopeDb(scope, dbPath, log9);
38238
39044
  }
38239
39045
  const initPromise = (async () => {
38240
- log8.debug({ scope, dbPath }, "opening dual-scope cleo.db");
39046
+ log9.debug({ scope, dbPath }, "opening dual-scope cleo.db");
38241
39047
  const dir = dirname5(dbPath);
38242
- if (!existsSync12(dir)) {
38243
- mkdirSync3(dir, { recursive: true });
39048
+ if (!existsSync13(dir)) {
39049
+ mkdirSync4(dir, { recursive: true });
38244
39050
  }
38245
39051
  const DatabaseSyncCtor = getDatabaseSyncCtor();
38246
39052
  const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
@@ -38267,7 +39073,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38267
39073
  existenceTable(scope),
38268
39074
  `dual-scope-db[${scope}]`
38269
39075
  );
38270
- log8.debug({ scope, dbPath }, "dual-scope cleo.db ready");
39076
+ log9.debug({ scope, dbPath }, "dual-scope cleo.db ready");
38271
39077
  const built = {
38272
39078
  db,
38273
39079
  scope,
@@ -38293,6 +39099,25 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38293
39099
  { dbPath }
38294
39100
  );
38295
39101
  if (exodusCwd !== void 0 && dbPath === resolveDualScopeDbPath(scope, exodusCwd)) {
39102
+ let releaseDbHeavy = null;
39103
+ let dbHeavyDeferred = false;
39104
+ try {
39105
+ const { governor: governor2 } = await Promise.resolve().then(() => (init_governor(), governor_exports));
39106
+ const admit = await governor2.tryAcquire("db-heavy");
39107
+ if (admit.deferred) {
39108
+ dbHeavyDeferred = true;
39109
+ } else {
39110
+ releaseDbHeavy = admit.release;
39111
+ }
39112
+ } catch {
39113
+ }
39114
+ if (dbHeavyDeferred) {
39115
+ log9.debug(
39116
+ { scope, dbPath },
39117
+ "exodus-on-open skipped this open \u2014 db-heavy deferred under memory pressure (re-runs idempotently on a calmer open)"
39118
+ );
39119
+ return handle;
39120
+ }
38296
39121
  try {
38297
39122
  const { maybeRunExodusOnOpen: maybeRunExodusOnOpen2 } = await Promise.resolve().then(() => (init_on_open(), on_open_exports));
38298
39123
  const result = await maybeRunExodusOnOpen2(scope, dbPath, nativeDb, exodusCwd);
@@ -38305,7 +39130,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38305
39130
  reason: result.reason,
38306
39131
  at: Date.now()
38307
39132
  };
38308
- log8.warn(
39133
+ log9.warn(
38309
39134
  { scope, reason: result.reason },
38310
39135
  "exodus-on-open aborted; consolidated cleo.db left empty, legacy kept as source \u2014 mutating callers must check handle.exodusAbort / call assertWriteDurable (T11828)"
38311
39136
  );
@@ -38318,11 +39143,14 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38318
39143
  return reopened;
38319
39144
  }
38320
39145
  } catch (err) {
38321
- log8.warn(
39146
+ log9.warn(
38322
39147
  { err, scope },
38323
39148
  "exodus-on-open hook failed (non-fatal); re-opening consolidated handle"
38324
39149
  );
38325
39150
  return scope === "project" ? openDualScopeDbAtPath("project", dbPath) : openDualScopeDbAtPath("global", dbPath);
39151
+ } finally {
39152
+ if (releaseDbHeavy) await releaseDbHeavy().catch(() => {
39153
+ });
38326
39154
  }
38327
39155
  }
38328
39156
  return handle;
@@ -38945,8 +39773,8 @@ __export(nexus_sqlite_exports, {
38945
39773
  resetNexusDbState: () => resetNexusDbState,
38946
39774
  resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
38947
39775
  });
38948
- import { copyFileSync as copyFileSync4, existsSync as existsSync13 } from "node:fs";
38949
- import { join as join12 } from "node:path";
39776
+ import { copyFileSync as copyFileSync4, existsSync as existsSync14 } from "node:fs";
39777
+ import { join as join14 } from "node:path";
38950
39778
  function getNexusDbPath(cwd) {
38951
39779
  return resolveDualScopeDbPath("project", cwd);
38952
39780
  }
@@ -38978,7 +39806,7 @@ function resolveNexusMigrationsFolder() {
38978
39806
  return resolveCorePackageMigrationsFolder("drizzle-nexus");
38979
39807
  }
38980
39808
  function getNestedNexusSentinelPath() {
38981
- return join12(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
39809
+ return join14(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
38982
39810
  }
38983
39811
  function detectAndWarnOnNestedNexus() {
38984
39812
  let nestedPath;
@@ -38987,12 +39815,12 @@ function detectAndWarnOnNestedNexus() {
38987
39815
  } catch {
38988
39816
  return false;
38989
39817
  }
38990
- if (!existsSync13(nestedPath)) return false;
39818
+ if (!existsSync14(nestedPath)) return false;
38991
39819
  if (_warnedNestedPaths.has(nestedPath)) return false;
38992
39820
  _warnedNestedPaths.add(nestedPath);
38993
39821
  const canonicalPath = getNexusDbPath();
38994
- const log8 = getLogger("nexus-sqlite");
38995
- log8.warn(
39822
+ const log9 = getLogger("nexus-sqlite");
39823
+ log9.warn(
38996
39824
  {
38997
39825
  nestedPath,
38998
39826
  canonicalPath,
@@ -39146,7 +39974,7 @@ function runNexusMigrations(nativeDb, db) {
39146
39974
  const migrationsFolder = resolveNexusMigrationsFolder();
39147
39975
  if (tableExists4(nativeDb, "nexus_nodes") && _nexusDbPath) {
39148
39976
  const backupPath = _nexusDbPath.replace(/\.db$/, "-pre-cleo.db.bak");
39149
- if (!existsSync13(backupPath)) {
39977
+ if (!existsSync14(backupPath)) {
39150
39978
  try {
39151
39979
  copyFileSync4(_nexusDbPath, backupPath);
39152
39980
  } catch {
@@ -39284,10 +40112,10 @@ var init_nexus_sqlite = __esm({
39284
40112
 
39285
40113
  // packages/core/src/paths.ts
39286
40114
  import { AsyncLocalStorage } from "node:async_hooks";
39287
- import { existsSync as existsSync14, readFileSync as readFileSync4, statSync as statSync5 } from "node:fs";
40115
+ import { existsSync as existsSync15, readFileSync as readFileSync4, statSync as statSync5 } from "node:fs";
39288
40116
  import { createRequire as createRequire5 } from "node:module";
39289
40117
  import { homedir } from "node:os";
39290
- import { basename as basename4, dirname as dirname6, join as join13, resolve as resolve3 } from "node:path";
40118
+ import { basename as basename4, dirname as dirname6, join as join15, resolve as resolve3 } from "node:path";
39291
40119
  import {
39292
40120
  computeCanonicalProjectId as _computeCanonicalProjectId,
39293
40121
  getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath,
@@ -39377,8 +40205,8 @@ function getCleoDirAbsolute(cwd, opts) {
39377
40205
  function _resolveProjectByCwdFromNexus(cwd) {
39378
40206
  try {
39379
40207
  const cleoHome = getCleoHome();
39380
- const globalDbPath = join13(cleoHome, "cleo.db");
39381
- if (!existsSync14(globalDbPath)) return null;
40208
+ const globalDbPath = join15(cleoHome, "cleo.db");
40209
+ if (!existsSync15(globalDbPath)) return null;
39382
40210
  const start = resolve3(cwd ?? process.cwd());
39383
40211
  let current = start;
39384
40212
  const DatabaseSync2 = _getDatabaseSyncCtor();
@@ -39417,7 +40245,7 @@ function _findCleoDirRoot(cwd) {
39417
40245
  const isDangerousRoot = current === homeRoot || current === "/" || current === "";
39418
40246
  if (!isDangerousRoot) {
39419
40247
  try {
39420
- if (statSync5(join13(current, ".cleo")).isDirectory()) {
40248
+ if (statSync5(join15(current, ".cleo")).isDirectory()) {
39421
40249
  return current;
39422
40250
  }
39423
40251
  } catch {
@@ -39432,7 +40260,7 @@ function _findCleoDirRoot(cwd) {
39432
40260
  function resolveCleoDir(cwd) {
39433
40261
  const scope = worktreeScope.getStore();
39434
40262
  if (scope !== void 0) {
39435
- return join13(scope.worktreeRoot, ".cleo");
40263
+ return join15(scope.worktreeRoot, ".cleo");
39436
40264
  }
39437
40265
  const override = _cleoDirEnvOverride();
39438
40266
  if (override !== null) {
@@ -39440,14 +40268,14 @@ function resolveCleoDir(cwd) {
39440
40268
  }
39441
40269
  const root = _findCleoDirRoot(cwd);
39442
40270
  if (root !== null) {
39443
- return join13(root, ".cleo");
40271
+ return join15(root, ".cleo");
39444
40272
  }
39445
40273
  const start = resolve3(cwd ?? process.cwd());
39446
40274
  let current = start;
39447
40275
  while (true) {
39448
40276
  const mainRepo = _resolveMainRepoFromGitlink(current);
39449
40277
  if (mainRepo !== null) {
39450
- return join13(mainRepo, ".cleo");
40278
+ return join15(mainRepo, ".cleo");
39451
40279
  }
39452
40280
  const parent = dirname6(current);
39453
40281
  if (parent === current) {
@@ -39489,9 +40317,9 @@ function _cwdHasGitAncestor(cwd) {
39489
40317
  const start = resolve3(cwd ?? process.cwd());
39490
40318
  let current = start;
39491
40319
  while (true) {
39492
- const gitMarker = join13(current, ".git");
40320
+ const gitMarker = join15(current, ".git");
39493
40321
  try {
39494
- if (existsSync14(gitMarker)) {
40322
+ if (existsSync15(gitMarker)) {
39495
40323
  return true;
39496
40324
  }
39497
40325
  } catch {
@@ -39503,16 +40331,16 @@ function _cwdHasGitAncestor(cwd) {
39503
40331
  }
39504
40332
  function _resolveMainRepoFromGitlink(gitlinkDir) {
39505
40333
  try {
39506
- const gitLinkPath = join13(gitlinkDir, ".git");
39507
- if (!existsSync14(gitLinkPath)) return null;
39508
- const stat2 = statSync5(gitLinkPath);
39509
- if (!stat2.isFile()) return null;
40334
+ const gitLinkPath = join15(gitlinkDir, ".git");
40335
+ if (!existsSync15(gitLinkPath)) return null;
40336
+ const stat3 = statSync5(gitLinkPath);
40337
+ if (!stat3.isFile()) return null;
39510
40338
  const gitLinkContent = readFileSync4(gitLinkPath, "utf-8").trim();
39511
40339
  const match = gitLinkContent.match(/^gitdir:\s*(.+)$/m);
39512
40340
  if (!match) return null;
39513
40341
  const gitdir = match[1].trim();
39514
40342
  const mainRepo = dirname6(dirname6(dirname6(gitdir)));
39515
- if (existsSync14(join13(mainRepo, ".cleo")) && validateProjectRoot(mainRepo)) {
40343
+ if (existsSync15(join15(mainRepo, ".cleo")) && validateProjectRoot(mainRepo)) {
39516
40344
  return mainRepo;
39517
40345
  }
39518
40346
  } catch {
@@ -39520,18 +40348,18 @@ function _resolveMainRepoFromGitlink(gitlinkDir) {
39520
40348
  return null;
39521
40349
  }
39522
40350
  function validateProjectRoot(candidate) {
39523
- const cleoDir = join13(candidate, ".cleo");
39524
- if (!existsSync14(cleoDir)) {
40351
+ const cleoDir = join15(candidate, ".cleo");
40352
+ if (!existsSync15(cleoDir)) {
39525
40353
  return false;
39526
40354
  }
39527
- const projectInfoPath = join13(cleoDir, "project-info.json");
39528
- if (existsSync14(projectInfoPath)) {
40355
+ const projectInfoPath = join15(cleoDir, "project-info.json");
40356
+ if (existsSync15(projectInfoPath)) {
39529
40357
  try {
39530
40358
  const raw = readFileSync4(projectInfoPath, "utf-8");
39531
40359
  const parsed = JSON.parse(raw);
39532
40360
  if (typeof parsed === "object" && parsed !== null && "projectId" in parsed && typeof parsed["projectId"] === "string" && parsed["projectId"] !== "") {
39533
- const gitMarker = join13(candidate, ".git");
39534
- if (existsSync14(gitMarker)) {
40361
+ const gitMarker = join15(candidate, ".git");
40362
+ if (existsSync15(gitMarker)) {
39535
40363
  try {
39536
40364
  if (!statSync5(gitMarker).isDirectory()) {
39537
40365
  return false;
@@ -39545,12 +40373,12 @@ function validateProjectRoot(candidate) {
39545
40373
  } catch {
39546
40374
  }
39547
40375
  }
39548
- const gitDir = join13(candidate, ".git");
39549
- if (existsSync14(gitDir)) {
40376
+ const gitDir = join15(candidate, ".git");
40377
+ if (existsSync15(gitDir)) {
39550
40378
  let isRealGitDir = false;
39551
40379
  try {
39552
- const stat2 = statSync5(gitDir);
39553
- isRealGitDir = stat2.isDirectory();
40380
+ const stat3 = statSync5(gitDir);
40381
+ isRealGitDir = stat3.isDirectory();
39554
40382
  } catch {
39555
40383
  isRealGitDir = false;
39556
40384
  }
@@ -39593,16 +40421,16 @@ function getProjectRoot(cwd) {
39593
40421
  const homeRoot = homedir();
39594
40422
  const skippedCleoDirs = [];
39595
40423
  while (true) {
39596
- const cleoDir = join13(current, ".cleo");
39597
- const gitDir = join13(current, ".git");
40424
+ const cleoDir = join15(current, ".cleo");
40425
+ const gitDir = join15(current, ".git");
39598
40426
  const isDangerousRoot = current === homeRoot || current === "/" || current === "";
39599
- if (existsSync14(cleoDir) && !isDangerousRoot) {
40427
+ if (existsSync15(cleoDir) && !isDangerousRoot) {
39600
40428
  if (validateProjectRoot(current)) {
39601
40429
  return current;
39602
40430
  }
39603
40431
  skippedCleoDirs.push(current);
39604
40432
  }
39605
- if (existsSync14(gitDir) && !isDangerousRoot) {
40433
+ if (existsSync15(gitDir) && !isDangerousRoot) {
39606
40434
  let isRealGitDir = false;
39607
40435
  try {
39608
40436
  isRealGitDir = statSync5(gitDir).isDirectory();
@@ -39647,18 +40475,18 @@ function resolveOrCwd(maybeRoot) {
39647
40475
  return getProjectRoot();
39648
40476
  }
39649
40477
  function getConfigPath(cwd) {
39650
- return join13(_resolveCleoDir(cwd), "config.json");
40478
+ return join15(_resolveCleoDir(cwd), "config.json");
39651
40479
  }
39652
40480
  function getGlobalConfigPath() {
39653
- return join13(getCleoHome(), "config.json");
40481
+ return join15(getCleoHome(), "config.json");
39654
40482
  }
39655
40483
  function isAbsolutePath(path) {
39656
40484
  return _isAbsolutePath(path);
39657
40485
  }
39658
40486
  function _readProjectNameFromInfo(projectRoot) {
39659
40487
  try {
39660
- const infoPath = join13(projectRoot, ".cleo", "project-info.json");
39661
- if (!existsSync14(infoPath)) return void 0;
40488
+ const infoPath = join15(projectRoot, ".cleo", "project-info.json");
40489
+ if (!existsSync15(infoPath)) return void 0;
39662
40490
  const raw = readFileSync4(infoPath, "utf-8");
39663
40491
  const data = JSON.parse(raw);
39664
40492
  return typeof data.name === "string" && data.name.length > 0 ? data.name : void 0;
@@ -39684,8 +40512,8 @@ async function registerProjectOnEncounter(projectRoot, infoProjectId) {
39684
40512
  if (existingRows.length > 0) {
39685
40513
  const existingPath = existingRows[0].projectPath;
39686
40514
  if (existingPath !== resolvedPath) {
39687
- const newBrainDbPath = join13(resolvedPath, ".cleo", "brain.db");
39688
- const newTasksDbPath = join13(resolvedPath, ".cleo", "tasks.db");
40515
+ const newBrainDbPath = join15(resolvedPath, ".cleo", "brain.db");
40516
+ const newTasksDbPath = join15(resolvedPath, ".cleo", "tasks.db");
39689
40517
  await db.update(projectRegistry2).set({
39690
40518
  projectPath: resolvedPath,
39691
40519
  projectHash: generateProjectHash2(resolvedPath),
@@ -39716,8 +40544,8 @@ async function registerProjectOnEncounter(projectRoot, infoProjectId) {
39716
40544
  lastSync: now,
39717
40545
  taskCount: 0,
39718
40546
  labelsJson: "[]",
39719
- brainDbPath: join13(resolvedPath, ".cleo", "brain.db"),
39720
- tasksDbPath: join13(resolvedPath, ".cleo", "tasks.db"),
40547
+ brainDbPath: join15(resolvedPath, ".cleo", "brain.db"),
40548
+ tasksDbPath: join15(resolvedPath, ".cleo", "tasks.db"),
39721
40549
  statsJson: "{}"
39722
40550
  }).onConflictDoNothing();
39723
40551
  const aliases = canonicalResult.legacyAliases ?? [];
@@ -39750,46 +40578,46 @@ var init_paths = __esm({
39750
40578
  // packages/core/src/store/file-utils.ts
39751
40579
  import { randomBytes } from "node:crypto";
39752
40580
  import {
39753
- existsSync as existsSync15,
39754
- mkdirSync as mkdirSync4,
39755
- readdirSync as readdirSync4,
40581
+ existsSync as existsSync16,
40582
+ mkdirSync as mkdirSync5,
40583
+ readdirSync as readdirSync5,
39756
40584
  readFileSync as readFileSync5,
39757
40585
  renameSync as renameSync3,
39758
40586
  unlinkSync as unlinkSync3,
39759
- writeFileSync as writeFileSync3
40587
+ writeFileSync as writeFileSync4
39760
40588
  } from "node:fs";
39761
- import { basename as basename5, dirname as dirname7, join as join14 } from "node:path";
39762
- import * as lockfile2 from "proper-lockfile";
40589
+ import { basename as basename5, dirname as dirname7, join as join16 } from "node:path";
40590
+ import * as lockfile3 from "proper-lockfile";
39763
40591
  function rotateBackup(filePath, mode) {
39764
40592
  const dir = dirname7(filePath);
39765
40593
  const name15 = basename5(filePath);
39766
- const backupDir = join14(dir, ".backups");
40594
+ const backupDir = join16(dir, ".backups");
39767
40595
  const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
39768
- if (!existsSync15(backupDir)) {
39769
- mkdirSync4(backupDir, { recursive: true, mode: dirMode });
40596
+ if (!existsSync16(backupDir)) {
40597
+ mkdirSync5(backupDir, { recursive: true, mode: dirMode });
39770
40598
  }
39771
40599
  for (let i = MAX_BACKUPS; i >= 1; i--) {
39772
- const current = join14(backupDir, `${name15}.${i}`);
40600
+ const current = join16(backupDir, `${name15}.${i}`);
39773
40601
  if (i === MAX_BACKUPS) {
39774
40602
  try {
39775
40603
  unlinkSync3(current);
39776
40604
  } catch {
39777
40605
  }
39778
40606
  } else {
39779
- const next = join14(backupDir, `${name15}.${i + 1}`);
40607
+ const next = join16(backupDir, `${name15}.${i + 1}`);
39780
40608
  try {
39781
- if (existsSync15(current)) renameSync3(current, next);
40609
+ if (existsSync16(current)) renameSync3(current, next);
39782
40610
  } catch {
39783
40611
  }
39784
40612
  }
39785
40613
  }
39786
40614
  try {
39787
40615
  const content = readFileSync5(filePath, "utf-8");
39788
- const backupPath = join14(backupDir, `${name15}.1`);
40616
+ const backupPath = join16(backupDir, `${name15}.1`);
39789
40617
  if (typeof mode === "number") {
39790
- writeFileSync3(backupPath, content, { encoding: "utf-8", mode });
40618
+ writeFileSync4(backupPath, content, { encoding: "utf-8", mode });
39791
40619
  } else {
39792
- writeFileSync3(backupPath, content, "utf-8");
40620
+ writeFileSync4(backupPath, content, "utf-8");
39793
40621
  }
39794
40622
  } catch {
39795
40623
  }
@@ -39806,15 +40634,15 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
39806
40634
  const indent = opts.indent ?? 2;
39807
40635
  const mode = opts.mode;
39808
40636
  const dir = dirname7(filePath);
39809
- const tempPath = join14(dir, `.${basename5(filePath)}.${randomBytes(6).toString("hex")}.tmp`);
40637
+ const tempPath = join16(dir, `.${basename5(filePath)}.${randomBytes(6).toString("hex")}.tmp`);
39810
40638
  const content = JSON.stringify(data, null, indent) + "\n";
39811
40639
  if (typeof mode === "number") {
39812
- writeFileSync3(tempPath, content, { encoding: "utf-8", mode });
40640
+ writeFileSync4(tempPath, content, { encoding: "utf-8", mode });
39813
40641
  } else {
39814
- writeFileSync3(tempPath, content, "utf-8");
40642
+ writeFileSync4(tempPath, content, "utf-8");
39815
40643
  }
39816
40644
  try {
39817
- if (existsSync15(filePath)) {
40645
+ if (existsSync16(filePath)) {
39818
40646
  rotateBackup(filePath, mode);
39819
40647
  }
39820
40648
  renameSync3(tempPath, filePath);
@@ -39840,19 +40668,19 @@ function readJsonFile(filePath) {
39840
40668
  async function withLock2(filePath, transform2, opts = {}) {
39841
40669
  const dir = dirname7(filePath);
39842
40670
  const dirMode = typeof opts.mode === "number" ? modeToDirMode(opts.mode) : void 0;
39843
- if (!existsSync15(dir)) {
39844
- mkdirSync4(dir, { recursive: true, mode: dirMode });
40671
+ if (!existsSync16(dir)) {
40672
+ mkdirSync5(dir, { recursive: true, mode: dirMode });
39845
40673
  }
39846
- if (!existsSync15(filePath)) {
40674
+ if (!existsSync16(filePath)) {
39847
40675
  if (typeof opts.mode === "number") {
39848
- writeFileSync3(filePath, "", { encoding: "utf-8", mode: opts.mode });
40676
+ writeFileSync4(filePath, "", { encoding: "utf-8", mode: opts.mode });
39849
40677
  } else {
39850
- writeFileSync3(filePath, "", "utf-8");
40678
+ writeFileSync4(filePath, "", "utf-8");
39851
40679
  }
39852
40680
  }
39853
40681
  let release;
39854
40682
  try {
39855
- release = await lockfile2.lock(filePath, LOCK_OPTIONS);
40683
+ release = await lockfile3.lock(filePath, LOCK_OPTIONS);
39856
40684
  const current = readJsonFile(filePath);
39857
40685
  const updated = transform2(current);
39858
40686
  writeJsonFileAtomic(filePath, updated, { mode: opts.mode });
@@ -39865,15 +40693,15 @@ async function withLock2(filePath, transform2, opts = {}) {
39865
40693
  }
39866
40694
  async function withFileLock(filePath, operation) {
39867
40695
  const dir = dirname7(filePath);
39868
- if (!existsSync15(dir)) {
39869
- mkdirSync4(dir, { recursive: true });
40696
+ if (!existsSync16(dir)) {
40697
+ mkdirSync5(dir, { recursive: true });
39870
40698
  }
39871
- if (!existsSync15(filePath)) {
39872
- writeFileSync3(filePath, "", "utf-8");
40699
+ if (!existsSync16(filePath)) {
40700
+ writeFileSync4(filePath, "", "utf-8");
39873
40701
  }
39874
40702
  let release;
39875
40703
  try {
39876
- release = await lockfile2.lock(filePath, LOCK_OPTIONS);
40704
+ release = await lockfile3.lock(filePath, LOCK_OPTIONS);
39877
40705
  return await operation();
39878
40706
  } finally {
39879
40707
  if (release) {
@@ -39902,10 +40730,10 @@ var init_file_utils = __esm({
39902
40730
 
39903
40731
  // packages/core/src/llm/credential-removal.ts
39904
40732
  import { unlinkSync as unlinkSync4 } from "node:fs";
39905
- import { join as join15 } from "node:path";
39906
- import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
40733
+ import { join as join17 } from "node:path";
40734
+ import { getCleoHome as getCleoHome3 } from "@cleocode/paths";
39907
40735
  function suppressionStatePath() {
39908
- return join15(getCleoHome2(), SUPPRESSION_FILENAME);
40736
+ return join17(getCleoHome3(), SUPPRESSION_FILENAME);
39909
40737
  }
39910
40738
  function readSuppressionFile() {
39911
40739
  const data = readJsonFile(suppressionStatePath());
@@ -40009,7 +40837,7 @@ var init_credential_removal = __esm({
40009
40837
  sourceId: "cleo-pkce",
40010
40838
  description: "Delete CLEO-issued PKCE token at <CLEO_HOME>/anthropic-oauth.json",
40011
40839
  async remove() {
40012
- const path = join15(getCleoHome2(), "anthropic-oauth.json");
40840
+ const path = join17(getCleoHome3(), "anthropic-oauth.json");
40013
40841
  const cleaned = [];
40014
40842
  try {
40015
40843
  unlinkSync4(path);
@@ -40088,7 +40916,7 @@ __export(config_exports, {
40088
40916
  parseConfigValue: () => parseConfigValue,
40089
40917
  setConfigValue: () => setConfigValue
40090
40918
  });
40091
- import { existsSync as existsSync16 } from "node:fs";
40919
+ import { existsSync as existsSync17 } from "node:fs";
40092
40920
  function getNestedValue(obj, path) {
40093
40921
  const parts = path.split(".");
40094
40922
  let current = obj;
@@ -40136,7 +40964,7 @@ function parseEnvValue(value) {
40136
40964
  return value;
40137
40965
  }
40138
40966
  async function loadConfig(cwd) {
40139
- let merged = JSON.parse(JSON.stringify(DEFAULTS));
40967
+ let merged = JSON.parse(JSON.stringify(DEFAULTS2));
40140
40968
  const globalConfig2 = await readJson(getGlobalConfigPath());
40141
40969
  if (globalConfig2) {
40142
40970
  merged = deepMerge(merged, globalConfig2);
@@ -40182,7 +41010,7 @@ async function getConfigValue(path, cwd) {
40182
41010
  return { value: val, source: "global" };
40183
41011
  }
40184
41012
  }
40185
- const defaultVal = getNestedValue({ ...DEFAULTS }, path);
41013
+ const defaultVal = getNestedValue({ ...DEFAULTS2 }, path);
40186
41014
  return { value: defaultVal, source: "default" };
40187
41015
  }
40188
41016
  async function getRawConfigValue(key, cwd) {
@@ -40210,7 +41038,7 @@ function parseConfigValue(value) {
40210
41038
  }
40211
41039
  async function setConfigValue(key, value, cwd, opts) {
40212
41040
  const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
40213
- if (!existsSync16(configPath)) {
41041
+ if (!existsSync17(configPath)) {
40214
41042
  await atomicWriteJson(configPath, {});
40215
41043
  }
40216
41044
  const config2 = await readJson(configPath) ?? {};
@@ -40222,7 +41050,7 @@ async function setConfigValue(key, value, cwd, opts) {
40222
41050
  async function applyStrictnessPreset(preset, cwd, opts) {
40223
41051
  const definition = STRICTNESS_PRESETS[preset];
40224
41052
  const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
40225
- if (!existsSync16(configPath)) {
41053
+ if (!existsSync17(configPath)) {
40226
41054
  await atomicWriteJson(configPath, {});
40227
41055
  }
40228
41056
  const config2 = await readJson(configPath) ?? {};
@@ -40246,7 +41074,7 @@ function listStrictnessPresets() {
40246
41074
  })
40247
41075
  );
40248
41076
  }
40249
- var DEFAULTS, ENV_MAP, STRICTNESS_PRESETS;
41077
+ var DEFAULTS2, ENV_MAP, STRICTNESS_PRESETS;
40250
41078
  var init_config = __esm({
40251
41079
  "packages/core/src/config.ts"() {
40252
41080
  "use strict";
@@ -40254,7 +41082,7 @@ var init_config = __esm({
40254
41082
  init_paths();
40255
41083
  init_atomic();
40256
41084
  init_json2();
40257
- DEFAULTS = {
41085
+ DEFAULTS2 = {
40258
41086
  version: "2.10.0",
40259
41087
  output: {
40260
41088
  defaultFormat: "json",
@@ -40429,10 +41257,10 @@ var init_config = __esm({
40429
41257
  // packages/core/src/llm/credential-seeders/claude-code-seeder.ts
40430
41258
  import { readFileSync as readFileSync6 } from "node:fs";
40431
41259
  import { homedir as homedir2 } from "node:os";
40432
- import { join as join16 } from "node:path";
41260
+ import { join as join18 } from "node:path";
40433
41261
  function defaultReadCredentialFile() {
40434
41262
  try {
40435
- return readFileSync6(join16(homedir2(), ".claude", ".credentials.json"), "utf-8");
41263
+ return readFileSync6(join18(homedir2(), ".claude", ".credentials.json"), "utf-8");
40436
41264
  } catch {
40437
41265
  return null;
40438
41266
  }
@@ -40527,9 +41355,9 @@ var init_claude_code_seeder = __esm({
40527
41355
 
40528
41356
  // packages/core/src/llm/credential-seeders/cleo-pkce-seeder.ts
40529
41357
  import { readFileSync as readFileSync7 } from "node:fs";
40530
- import { join as join17 } from "node:path";
41358
+ import { join as join19 } from "node:path";
40531
41359
  function defaultCleoPkcePath() {
40532
- return join17(getCleoHome(), "anthropic-oauth.json");
41360
+ return join19(getCleoHome(), "anthropic-oauth.json");
40533
41361
  }
40534
41362
  function defaultReadCredentialFile2() {
40535
41363
  try {
@@ -40600,13 +41428,13 @@ var init_cleo_pkce_seeder = __esm({
40600
41428
  });
40601
41429
 
40602
41430
  // packages/core/src/llm/credential-seeders/codex-cli-seeder.ts
40603
- import { existsSync as existsSync17, readFileSync as readFileSync8 } from "node:fs";
41431
+ import { existsSync as existsSync18, readFileSync as readFileSync8 } from "node:fs";
40604
41432
  import { homedir as homedir3 } from "node:os";
40605
- import { join as join18 } from "node:path";
41433
+ import { join as join20 } from "node:path";
40606
41434
  function getCodexAuthPath() {
40607
41435
  const codexHome = (process.env["CODEX_HOME"] ?? "").trim();
40608
- const root = codexHome || join18(homedir3(), ".codex");
40609
- return join18(root, "auth.json");
41436
+ const root = codexHome || join20(homedir3(), ".codex");
41437
+ return join20(root, "auth.json");
40610
41438
  }
40611
41439
  var CodexCliSeeder, codexCliSeeder;
40612
41440
  var init_codex_cli_seeder = __esm({
@@ -40625,7 +41453,7 @@ var init_codex_cli_seeder = __esm({
40625
41453
  */
40626
41454
  async seed() {
40627
41455
  const authPath = getCodexAuthPath();
40628
- if (!existsSync17(authPath)) {
41456
+ if (!existsSync18(authPath)) {
40629
41457
  return { entries: [] };
40630
41458
  }
40631
41459
  let raw;
@@ -40820,11 +41648,11 @@ var init_google_pkce = __esm({
40820
41648
  });
40821
41649
 
40822
41650
  // packages/core/src/llm/credential-seeders/gemini-cli-seeder.ts
40823
- import { existsSync as existsSync18, readFileSync as readFileSync9 } from "node:fs";
40824
- import { join as join19 } from "node:path";
40825
- import { getCleoHome as getCleoHome3 } from "@cleocode/paths";
41651
+ import { existsSync as existsSync19, readFileSync as readFileSync9 } from "node:fs";
41652
+ import { join as join21 } from "node:path";
41653
+ import { getCleoHome as getCleoHome4 } from "@cleocode/paths";
40826
41654
  function getGoogleOauthPath() {
40827
- return join19(getCleoHome3(), "google_oauth.json");
41655
+ return join21(getCleoHome4(), "google_oauth.json");
40828
41656
  }
40829
41657
  function parseGoogleOauthFile(raw) {
40830
41658
  let json3;
@@ -40869,7 +41697,7 @@ var init_gemini_cli_seeder = __esm({
40869
41697
  */
40870
41698
  async seed() {
40871
41699
  const path = getGoogleOauthPath();
40872
- if (!existsSync18(path)) {
41700
+ if (!existsSync19(path)) {
40873
41701
  return { entries: [] };
40874
41702
  }
40875
41703
  let raw;
@@ -41094,23 +41922,23 @@ var init_credential_seeders = __esm({
41094
41922
 
41095
41923
  // packages/core/src/llm/global-config-migration.ts
41096
41924
  import {
41097
- existsSync as existsSync19,
41098
- mkdirSync as mkdirSync5,
41925
+ existsSync as existsSync20,
41926
+ mkdirSync as mkdirSync6,
41099
41927
  readFileSync as readFileSync10,
41100
41928
  renameSync as renameSync4,
41101
41929
  unlinkSync as unlinkSync5,
41102
- writeFileSync as writeFileSync4
41930
+ writeFileSync as writeFileSync5
41103
41931
  } from "node:fs";
41104
- import { join as join20 } from "node:path";
41105
- import { getCleoHome as getCleoHome4, getCleoPlatformPaths as getCleoPlatformPaths2 } from "@cleocode/paths";
41932
+ import { join as join22 } from "node:path";
41933
+ import { getCleoHome as getCleoHome5, getCleoPlatformPaths as getCleoPlatformPaths2 } from "@cleocode/paths";
41106
41934
  function configDirGlobalConfigPath() {
41107
- return join20(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
41935
+ return join22(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
41108
41936
  }
41109
41937
  function legacyGlobalConfigPath() {
41110
- return join20(getCleoHome4(), GLOBAL_CONFIG_FILENAME);
41938
+ return join22(getCleoHome5(), GLOBAL_CONFIG_FILENAME);
41111
41939
  }
41112
41940
  function migrationMarkerPath() {
41113
- return join20(getCleoHome4(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
41941
+ return join22(getCleoHome5(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
41114
41942
  }
41115
41943
  function tempTargetPath() {
41116
41944
  return `${configDirGlobalConfigPath()}.tmp`;
@@ -41120,12 +41948,12 @@ function migrateGlobalConfigToConfigDir() {
41120
41948
  const source = legacyGlobalConfigPath();
41121
41949
  const target = configDirGlobalConfigPath();
41122
41950
  const marker16 = migrationMarkerPath();
41123
- if (existsSync19(marker16)) return false;
41124
- if (!existsSync19(source)) {
41951
+ if (existsSync20(marker16)) return false;
41952
+ if (!existsSync20(source)) {
41125
41953
  stampMarker(marker16);
41126
41954
  return false;
41127
41955
  }
41128
- if (existsSync19(target)) {
41956
+ if (existsSync20(target)) {
41129
41957
  backupSourceQuiet(source);
41130
41958
  stampMarker(marker16);
41131
41959
  return false;
@@ -41139,9 +41967,9 @@ function migrateGlobalConfigToConfigDir() {
41139
41967
  );
41140
41968
  return false;
41141
41969
  }
41142
- mkdirSync5(getCleoPlatformPaths2().config, { recursive: true });
41970
+ mkdirSync6(getCleoPlatformPaths2().config, { recursive: true });
41143
41971
  const temp = tempTargetPath();
41144
- writeFileSync4(temp, raw, { mode: 420 });
41972
+ writeFileSync5(temp, raw, { mode: 420 });
41145
41973
  renameSync4(temp, target);
41146
41974
  stampMarker(marker16);
41147
41975
  try {
@@ -41158,7 +41986,7 @@ function migrateGlobalConfigToConfigDir() {
41158
41986
  } catch (err) {
41159
41987
  try {
41160
41988
  const temp = tempTargetPath();
41161
- if (existsSync19(temp)) unlinkSync5(temp);
41989
+ if (existsSync20(temp)) unlinkSync5(temp);
41162
41990
  } catch {
41163
41991
  }
41164
41992
  console.error(
@@ -41169,8 +41997,8 @@ function migrateGlobalConfigToConfigDir() {
41169
41997
  }
41170
41998
  function stampMarker(markerPath) {
41171
41999
  try {
41172
- mkdirSync5(join20(getCleoHome4(), MIGRATIONS_SUBDIR), { recursive: true });
41173
- writeFileSync4(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
42000
+ mkdirSync6(join22(getCleoHome5(), MIGRATIONS_SUBDIR), { recursive: true });
42001
+ writeFileSync5(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
41174
42002
  `, { mode: 420 });
41175
42003
  } catch {
41176
42004
  }
@@ -41178,7 +42006,7 @@ function stampMarker(markerPath) {
41178
42006
  function backupSourceQuiet(source) {
41179
42007
  try {
41180
42008
  const backup = `${source}${BACKUP_SUFFIX}`;
41181
- if (existsSync19(backup)) return;
42009
+ if (existsSync20(backup)) return;
41182
42010
  renameSync4(source, backup);
41183
42011
  } catch {
41184
42012
  }
@@ -41201,20 +42029,20 @@ var init_global_config_migration = __esm({
41201
42029
  });
41202
42030
 
41203
42031
  // packages/core/src/llm/legacy-flat-key-import.ts
41204
- import { existsSync as existsSync20, readFileSync as readFileSync11, renameSync as renameSync5, writeFileSync as writeFileSync5 } from "node:fs";
41205
- import { join as join21 } from "node:path";
41206
- import { getCleoHome as getCleoHome5 } from "@cleocode/paths";
42032
+ import { existsSync as existsSync21, readFileSync as readFileSync11, renameSync as renameSync5, writeFileSync as writeFileSync6 } from "node:fs";
42033
+ import { join as join23 } from "node:path";
42034
+ import { getCleoHome as getCleoHome6 } from "@cleocode/paths";
41207
42035
  function migrationPaths() {
41208
- const home = getCleoHome5();
42036
+ const home = getCleoHome6();
41209
42037
  return {
41210
- flatPath: join21(home, "anthropic-key"),
41211
- bakPath: join21(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
41212
- markerPath: join21(home, LEGACY_FLAT_KEY_MARKER)
42038
+ flatPath: join23(home, "anthropic-key"),
42039
+ bakPath: join23(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
42040
+ markerPath: join23(home, LEGACY_FLAT_KEY_MARKER)
41213
42041
  };
41214
42042
  }
41215
42043
  function writeMarker(markerPath) {
41216
42044
  try {
41217
- writeFileSync5(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
42045
+ writeFileSync6(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
41218
42046
  `, {
41219
42047
  encoding: "utf-8",
41220
42048
  flag: "wx",
@@ -41230,7 +42058,7 @@ function writeMarker(markerPath) {
41230
42058
  }
41231
42059
  function readFlatKey(flatPath) {
41232
42060
  try {
41233
- if (!existsSync20(flatPath)) return null;
42061
+ if (!existsSync21(flatPath)) return null;
41234
42062
  const raw = readFileSync11(flatPath, "utf-8").trim();
41235
42063
  return raw || null;
41236
42064
  } catch (err) {
@@ -41243,7 +42071,7 @@ function readFlatKey(flatPath) {
41243
42071
  }
41244
42072
  async function importLegacyFlatAnthropicKey() {
41245
42073
  const { flatPath, bakPath, markerPath } = migrationPaths();
41246
- if (existsSync20(markerPath)) {
42074
+ if (existsSync21(markerPath)) {
41247
42075
  return { status: "marker-present", flatPath, bakPath: null, markerPath };
41248
42076
  }
41249
42077
  let existing = null;
@@ -41260,7 +42088,7 @@ async function importLegacyFlatAnthropicKey() {
41260
42088
  writeMarker(markerPath);
41261
42089
  return { status: "already-imported", flatPath, bakPath: null, markerPath };
41262
42090
  }
41263
- if (!existsSync20(flatPath)) {
42091
+ if (!existsSync21(flatPath)) {
41264
42092
  writeMarker(markerPath);
41265
42093
  return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
41266
42094
  }
@@ -41337,15 +42165,15 @@ __export(credentials_exports, {
41337
42165
  resolveProviderStatus: () => resolveProviderStatus,
41338
42166
  storeAnthropicApiKey: () => storeAnthropicApiKey
41339
42167
  });
41340
- import { existsSync as existsSync21, mkdirSync as mkdirSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
41341
- import { join as join22 } from "node:path";
41342
- import { getCleoHome as getCleoHome6 } from "@cleocode/paths";
42168
+ import { existsSync as existsSync22, mkdirSync as mkdirSync7, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "node:fs";
42169
+ import { join as join24 } from "node:path";
42170
+ import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
41343
42171
  function globalConfigPath() {
41344
42172
  return configDirGlobalConfigPath();
41345
42173
  }
41346
42174
  function projectConfigPath(projectRoot) {
41347
42175
  const cleoDir = process.env["CLEO_DIR"] ?? ".cleo";
41348
- return join22(projectRoot, cleoDir, "config.json");
42176
+ return join24(projectRoot, cleoDir, "config.json");
41349
42177
  }
41350
42178
  function readGlobalProviderKey(provider) {
41351
42179
  ensureGlobalConfigMigrated();
@@ -41355,8 +42183,8 @@ function readGlobalProviderKey(provider) {
41355
42183
  }
41356
42184
  function readFlatAnthropicKey() {
41357
42185
  try {
41358
- const keyFile = join22(getCleoHome6(), "anthropic-key");
41359
- if (!existsSync21(keyFile)) return null;
42186
+ const keyFile = join24(getCleoHome7(), "anthropic-key");
42187
+ if (!existsSync22(keyFile)) return null;
41360
42188
  const stored = readFileSync12(keyFile, "utf-8").trim();
41361
42189
  return stored || null;
41362
42190
  } catch {
@@ -41365,7 +42193,7 @@ function readFlatAnthropicKey() {
41365
42193
  }
41366
42194
  function readProviderKeyFromConfig(configFile, provider) {
41367
42195
  try {
41368
- if (!existsSync21(configFile)) return null;
42196
+ if (!existsSync22(configFile)) return null;
41369
42197
  const raw = readFileSync12(configFile, "utf-8");
41370
42198
  const config2 = JSON.parse(raw);
41371
42199
  const llm = config2["llm"];
@@ -41537,12 +42365,12 @@ function resolveProviderStatus(provider) {
41537
42365
  return { provider, resolvedSource, hasCredential: true };
41538
42366
  }
41539
42367
  function storeAnthropicApiKey(apiKey) {
41540
- const dir = getCleoHome6();
41541
- if (!existsSync21(dir)) {
41542
- mkdirSync6(dir, { recursive: true });
42368
+ const dir = getCleoHome7();
42369
+ if (!existsSync22(dir)) {
42370
+ mkdirSync7(dir, { recursive: true });
41543
42371
  }
41544
- const keyFile = join22(dir, "anthropic-key");
41545
- writeFileSync6(keyFile, apiKey.trim(), { mode: 384 });
42372
+ const keyFile = join24(dir, "anthropic-key");
42373
+ writeFileSync7(keyFile, apiKey.trim(), { mode: 384 });
41546
42374
  }
41547
42375
  function clearAnthropicKeyCache() {
41548
42376
  }
@@ -41605,17 +42433,17 @@ __export(credentials_store_exports, {
41605
42433
  pickCredentialForProviderSync: () => pickCredentialForProviderSync,
41606
42434
  removeCredential: () => removeCredential
41607
42435
  });
41608
- import { chmodSync, existsSync as existsSync22, mkdirSync as mkdirSync7, readFileSync as readFileSync13, statSync as statSync6, writeFileSync as writeFileSync7 } from "node:fs";
41609
- import { dirname as dirname8, join as join23 } from "node:path";
41610
- import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
42436
+ import { chmodSync, existsSync as existsSync23, mkdirSync as mkdirSync8, readFileSync as readFileSync13, statSync as statSync6, writeFileSync as writeFileSync8 } from "node:fs";
42437
+ import { dirname as dirname8, join as join25 } from "node:path";
42438
+ import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
41611
42439
  function credentialsStorePath() {
41612
- return join23(getCleoHome7(), "llm-credentials.json");
42440
+ return join25(getCleoHome8(), "llm-credentials.json");
41613
42441
  }
41614
42442
  function ensureFileInitialized(path) {
41615
- if (existsSync22(path)) return;
42443
+ if (existsSync23(path)) return;
41616
42444
  const dir = dirname8(path);
41617
- if (!existsSync22(dir)) {
41618
- mkdirSync7(dir, { recursive: true, mode: 448 });
42445
+ if (!existsSync23(dir)) {
42446
+ mkdirSync8(dir, { recursive: true, mode: 448 });
41619
42447
  } else {
41620
42448
  try {
41621
42449
  chmodSync(dir, 448);
@@ -41623,7 +42451,7 @@ function ensureFileInitialized(path) {
41623
42451
  }
41624
42452
  }
41625
42453
  try {
41626
- writeFileSync7(path, `${JSON.stringify(emptyStore(), null, 2)}
42454
+ writeFileSync8(path, `${JSON.stringify(emptyStore(), null, 2)}
41627
42455
  `, {
41628
42456
  encoding: "utf-8",
41629
42457
  flag: "wx",
@@ -41966,13 +42794,13 @@ var init_gemini = __esm({
41966
42794
 
41967
42795
  // packages/core/src/llm/stable-device-id.ts
41968
42796
  import { randomUUID as randomUUID2 } from "node:crypto";
41969
- import { existsSync as existsSync23, mkdirSync as mkdirSync8, readFileSync as readFileSync14, renameSync as renameSync6, writeFileSync as writeFileSync8 } from "node:fs";
41970
- import { dirname as dirname9, join as join24 } from "node:path";
41971
- import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
42797
+ import { existsSync as existsSync24, mkdirSync as mkdirSync9, readFileSync as readFileSync14, renameSync as renameSync6, writeFileSync as writeFileSync9 } from "node:fs";
42798
+ import { dirname as dirname9, join as join26 } from "node:path";
42799
+ import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
41972
42800
  function getStableDeviceId() {
41973
42801
  if (_cachedDeviceId !== null) return _cachedDeviceId;
41974
- const path = join24(getCleoHome8(), DEVICE_ID_FILE);
41975
- if (existsSync23(path)) {
42802
+ const path = join26(getCleoHome9(), DEVICE_ID_FILE);
42803
+ if (existsSync24(path)) {
41976
42804
  try {
41977
42805
  const raw = readFileSync14(path, "utf-8").trim();
41978
42806
  if (raw.length > 0) {
@@ -41985,11 +42813,11 @@ function getStableDeviceId() {
41985
42813
  const fresh = randomUUID2();
41986
42814
  try {
41987
42815
  const dir = dirname9(path);
41988
- if (!existsSync23(dir)) {
41989
- mkdirSync8(dir, { recursive: true });
42816
+ if (!existsSync24(dir)) {
42817
+ mkdirSync9(dir, { recursive: true });
41990
42818
  }
41991
42819
  const tmpPath = `${path}.tmp.${process.pid}`;
41992
- writeFileSync8(tmpPath, fresh, { mode: 384 });
42820
+ writeFileSync9(tmpPath, fresh, { mode: 384 });
41993
42821
  renameSync6(tmpPath, path);
41994
42822
  } catch {
41995
42823
  }
@@ -42287,14 +43115,14 @@ var init_xai = __esm({
42287
43115
  });
42288
43116
 
42289
43117
  // packages/core/src/llm/provider-registry/loader.ts
42290
- import { readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
42291
- import { join as join25 } from "node:path";
43118
+ import { readdirSync as readdirSync6, statSync as statSync7 } from "node:fs";
43119
+ import { join as join27 } from "node:path";
42292
43120
  import { pathToFileURL } from "node:url";
42293
43121
  function isPluginFile(filename) {
42294
43122
  return PLUGIN_EXTENSIONS.some((ext) => filename.endsWith(ext));
42295
43123
  }
42296
43124
  function getPluginDir() {
42297
- return join25(getCleoHome(), "plugins", "model-providers");
43125
+ return join27(getCleoHome(), "plugins", "model-providers");
42298
43126
  }
42299
43127
  async function loadOnePlugin(absPath, api) {
42300
43128
  let mod;
@@ -42336,19 +43164,19 @@ async function loadOnePlugin(absPath, api) {
42336
43164
  async function scanAndLoadPlugins(pluginDir, api) {
42337
43165
  let entries;
42338
43166
  try {
42339
- entries = readdirSync5(pluginDir);
43167
+ entries = readdirSync6(pluginDir);
42340
43168
  } catch {
42341
43169
  return;
42342
43170
  }
42343
43171
  const pluginFiles = entries.filter((name15) => !name15.startsWith(".") && isPluginFile(name15)).filter((name15) => {
42344
43172
  try {
42345
- return statSync7(join25(pluginDir, name15)).isFile();
43173
+ return statSync7(join27(pluginDir, name15)).isFile();
42346
43174
  } catch {
42347
43175
  return false;
42348
43176
  }
42349
43177
  }).sort();
42350
43178
  for (const filename of pluginFiles) {
42351
- await loadOnePlugin(join25(pluginDir, filename), api);
43179
+ await loadOnePlugin(join27(pluginDir, filename), api);
42352
43180
  }
42353
43181
  }
42354
43182
  async function runDiscovery(registerProvider2, builtins) {
@@ -42451,15 +43279,15 @@ var init_provider_registry = __esm({
42451
43279
  });
42452
43280
 
42453
43281
  // packages/core/src/llm/rate-limit-guard.ts
42454
- import { existsSync as existsSync24, mkdirSync as mkdirSync9, unlinkSync as unlinkSync6 } from "node:fs";
42455
- import { join as join26 } from "node:path";
42456
- import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
43282
+ import { existsSync as existsSync25, mkdirSync as mkdirSync10, unlinkSync as unlinkSync6 } from "node:fs";
43283
+ import { join as join28 } from "node:path";
43284
+ import { getCleoHome as getCleoHome10 } from "@cleocode/paths";
42457
43285
  function sanitize(value) {
42458
43286
  return value.replace(/[^a-zA-Z0-9_-]/g, "_");
42459
43287
  }
42460
43288
  function rateLimitStatePath(provider, label) {
42461
- const dir = join26(getCleoHome9(), "rate-limit-state");
42462
- return join26(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
43289
+ const dir = join28(getCleoHome10(), "rate-limit-state");
43290
+ return join28(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
42463
43291
  }
42464
43292
  function parseResetFromHeaders(headers) {
42465
43293
  const get = (k) => {
@@ -42506,9 +43334,9 @@ async function recordRateLimit(provider, label, opts) {
42506
43334
  source = "default";
42507
43335
  }
42508
43336
  const filePath = rateLimitStatePath(provider, label);
42509
- const dir = join26(getCleoHome9(), "rate-limit-state");
42510
- if (!existsSync24(dir)) {
42511
- mkdirSync9(dir, { recursive: true });
43337
+ const dir = join28(getCleoHome10(), "rate-limit-state");
43338
+ if (!existsSync25(dir)) {
43339
+ mkdirSync10(dir, { recursive: true });
42512
43340
  }
42513
43341
  const state = { resetAt, recordedAt: now, source };
42514
43342
  await withFileLock(filePath, () => {
@@ -43408,28 +44236,28 @@ var init_error_classifier = __esm({
43408
44236
 
43409
44237
  // packages/core/src/llm/catalog-cache.ts
43410
44238
  import {
43411
- existsSync as existsSync25,
43412
- mkdirSync as mkdirSync10,
43413
- readdirSync as readdirSync6,
44239
+ existsSync as existsSync26,
44240
+ mkdirSync as mkdirSync11,
44241
+ readdirSync as readdirSync7,
43414
44242
  readFileSync as readFileSync15,
43415
44243
  statSync as statSync8,
43416
44244
  symlinkSync,
43417
44245
  unlinkSync as unlinkSync7,
43418
- writeFileSync as writeFileSync9
44246
+ writeFileSync as writeFileSync10
43419
44247
  } from "node:fs";
43420
44248
  import { homedir as homedir4 } from "node:os";
43421
- import { join as join27 } from "node:path";
44249
+ import { join as join29 } from "node:path";
43422
44250
  function getCatalogDir() {
43423
44251
  if (process.env["CLEO_DATA_DIR"]) {
43424
- return join27(process.env["CLEO_DATA_DIR"], "llm-catalog");
44252
+ return join29(process.env["CLEO_DATA_DIR"], "llm-catalog");
43425
44253
  }
43426
- const xdg = process.env["XDG_DATA_HOME"] ?? join27(homedir4(), ".local", "share");
43427
- return join27(xdg, "cleo", "llm-catalog");
44254
+ const xdg = process.env["XDG_DATA_HOME"] ?? join29(homedir4(), ".local", "share");
44255
+ return join29(xdg, "cleo", "llm-catalog");
43428
44256
  }
43429
44257
  function findLatestCacheFile(dir) {
43430
- if (!existsSync25(dir)) return null;
43431
- const files = readdirSync6(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync8(join27(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
43432
- return files.length > 0 ? join27(dir, files[0].name) : null;
44258
+ if (!existsSync26(dir)) return null;
44259
+ const files = readdirSync7(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync8(join29(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
44260
+ return files.length > 0 ? join29(dir, files[0].name) : null;
43433
44261
  }
43434
44262
  function readCacheFile(filePath) {
43435
44263
  try {
@@ -43447,14 +44275,14 @@ var init_catalog_cache = __esm({
43447
44275
 
43448
44276
  // packages/core/src/llm/model-metadata.ts
43449
44277
  import { readFileSync as readFileSync16 } from "node:fs";
43450
- import { dirname as dirname10, join as join28 } from "node:path";
44278
+ import { dirname as dirname10, join as join30 } from "node:path";
43451
44279
  import { fileURLToPath as fileURLToPath3 } from "node:url";
43452
44280
  function getCuratedTable() {
43453
44281
  if (_curated !== void 0) {
43454
44282
  return _curated;
43455
44283
  }
43456
44284
  const thisDir = dirname10(fileURLToPath3(import.meta.url));
43457
- const jsonPath = join28(thisDir, "curated-models.json");
44285
+ const jsonPath = join30(thisDir, "curated-models.json");
43458
44286
  const raw = JSON.parse(readFileSync16(jsonPath, "utf-8"));
43459
44287
  _curated = raw.models;
43460
44288
  return _curated;
@@ -43539,7 +44367,7 @@ function storedToResolved(stored) {
43539
44367
  awsProfile: stored.metadata?.["awsProfile"] ?? null
43540
44368
  };
43541
44369
  }
43542
- function sleep(ms) {
44370
+ function sleep2(ms) {
43543
44371
  return new Promise((resolve5) => setTimeout(resolve5, ms));
43544
44372
  }
43545
44373
  function backoffMs(policy, attempt) {
@@ -43677,7 +44505,7 @@ var init_concrete_session = __esm({
43677
44505
  throw err;
43678
44506
  }
43679
44507
  lastErr = err;
43680
- await sleep(backoffMs(policy, attempt));
44508
+ await sleep2(backoffMs(policy, attempt));
43681
44509
  }
43682
44510
  }
43683
44511
  throw lastErr;
@@ -47433,7 +48261,7 @@ function normalizeOllamaToolCall(tc) {
47433
48261
  arguments: JSON.stringify(tc.function.arguments ?? {})
47434
48262
  };
47435
48263
  }
47436
- function sleep2(ms) {
48264
+ function sleep3(ms) {
47437
48265
  return new Promise((resolve5) => setTimeout(resolve5, ms));
47438
48266
  }
47439
48267
  var OLLAMA_DEFAULT_BASE_URL, MAX_RETRIES, INITIAL_BACKOFF_MS, RETRYABLE_STATUS_CODES, OllamaTransport;
@@ -47642,7 +48470,7 @@ var init_ollama2 = __esm({
47642
48470
  for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
47643
48471
  if (attempt > 0) {
47644
48472
  const delay = INITIAL_BACKOFF_MS * 2 ** (attempt - 1);
47645
- await sleep2(delay);
48473
+ await sleep3(delay);
47646
48474
  }
47647
48475
  let response;
47648
48476
  try {
@@ -75655,7 +76483,7 @@ var init_catalog_model_resolver = __esm({
75655
76483
  });
75656
76484
 
75657
76485
  // packages/core/src/llm/cross-provider-selector.ts
75658
- import { totalmem } from "node:os";
76486
+ import { totalmem as totalmem2 } from "node:os";
75659
76487
  async function probeOllamaAlive(baseUrl) {
75660
76488
  const cached2 = _ollamaProbeCache.get(baseUrl);
75661
76489
  if (cached2 && Date.now() - cached2.checkedAt < OLLAMA_PROBE_TTL_MS) {
@@ -75678,7 +76506,7 @@ async function probeOllamaAlive(baseUrl) {
75678
76506
  return alive;
75679
76507
  }
75680
76508
  function ollamaDefaultModelForTier(tier, ramBytesOverride) {
75681
- const ramBytes = ramBytesOverride ?? totalmem();
76509
+ const ramBytes = ramBytesOverride ?? totalmem2();
75682
76510
  const gb = ramBytes / 1024 ** 3;
75683
76511
  if (gb >= 8) {
75684
76512
  return tier === "fast" || tier === "local" ? "gemma4:e2b" : "gemma4:e4b";
@@ -75802,7 +76630,7 @@ async function selectBestProvisioned(role, opts) {
75802
76630
  let model;
75803
76631
  if (winner.id === "ollama") {
75804
76632
  const ollamaProfile2 = await getProviderProfile2("ollama");
75805
- const ramBytes = totalmem();
76633
+ const ramBytes = totalmem2();
75806
76634
  const gb = ramBytes / 1024 ** 3;
75807
76635
  if (gb >= 8) {
75808
76636
  model = (winner.tier === "fast" || taskTier === "fast" ? ollamaProfile2?.defaultAuxModel : ollamaProfile2?.defaultModel) ?? ollamaDefaultModelForTier(winner.tier);