@cleocode/core 2026.6.19 → 2026.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) 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/fix-gen.js +1209 -381
  27. package/dist/selfimprove/fix-gen.js.map +3 -3
  28. package/dist/sentient/tick.d.ts.map +1 -1
  29. package/dist/sentient/tick.js +29 -0
  30. package/dist/sentient/tick.js.map +1 -1
  31. package/dist/store/agent-registry-store.d.ts.map +1 -1
  32. package/dist/store/agent-registry-store.js +17 -2
  33. package/dist/store/agent-registry-store.js.map +1 -1
  34. package/dist/store/dual-scope-db.d.ts.map +1 -1
  35. package/dist/store/dual-scope-db.js +35 -0
  36. package/dist/store/dual-scope-db.js.map +1 -1
  37. package/dist/store/sqlite.d.ts.map +1 -1
  38. package/dist/store/sqlite.js +15 -0
  39. package/dist/store/sqlite.js.map +1 -1
  40. package/dist/tasks/tool-semaphore.d.ts +25 -0
  41. package/dist/tasks/tool-semaphore.d.ts.map +1 -1
  42. package/dist/tasks/tool-semaphore.js +68 -1
  43. package/dist/tasks/tool-semaphore.js.map +1 -1
  44. package/package.json +12 -12
@@ -12578,7 +12578,7 @@ var init_lafs = __esm({
12578
12578
 
12579
12579
  // packages/contracts/src/lease-ipc/messages.ts
12580
12580
  import { z as z11 } from "zod";
12581
- 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;
12581
+ 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;
12582
12582
  var init_messages2 = __esm({
12583
12583
  "packages/contracts/src/lease-ipc/messages.ts"() {
12584
12584
  "use strict";
@@ -12663,6 +12663,24 @@ var init_messages2 = __esm({
12663
12663
  /** The worker's own view of whether it is currently inside an LLM call. */
12664
12664
  in_flight_llm: z11.boolean()
12665
12665
  }).strict();
12666
+ ResourceAdmitRequestSchema = z11.object({
12667
+ /** Tag discriminating this request variant. */
12668
+ kind: z11.literal("resource_admit"),
12669
+ /** The resource class (e.g. `"db-heavy"`, `"full-build"`, `"test-run"`). */
12670
+ class: z11.string().min(1),
12671
+ /** The caller holding the slot — process/worktree-unique; the release key. */
12672
+ holder_id: z11.string().min(1),
12673
+ /** The client-computed budget: the max concurrent holders for this class. */
12674
+ budget: z11.number().int().nonnegative()
12675
+ }).strict();
12676
+ ResourceReleaseRequestSchema = z11.object({
12677
+ /** Tag discriminating this request variant. */
12678
+ kind: z11.literal("resource_release"),
12679
+ /** The resource class the slot belongs to. */
12680
+ class: z11.string().min(1),
12681
+ /** The holder that was admitted (matches the admit `holder_id`). */
12682
+ holder_id: z11.string().min(1)
12683
+ }).strict();
12666
12684
  LeaseIpcRequestSchema = z11.discriminatedUnion("kind", [
12667
12685
  LeaseAcquireRequestSchema,
12668
12686
  LeaseReleaseRequestSchema,
@@ -12670,7 +12688,9 @@ var init_messages2 = __esm({
12670
12688
  RateCheckRequestSchema,
12671
12689
  ToolGrantRequestSchema,
12672
12690
  QueueAdmitRequestSchema,
12673
- WorkerHeartbeatRequestSchema
12691
+ WorkerHeartbeatRequestSchema,
12692
+ ResourceAdmitRequestSchema,
12693
+ ResourceReleaseRequestSchema
12674
12694
  ]);
12675
12695
  LeaseGrantedResponseSchema = z11.object({
12676
12696
  /** Tag discriminating this response variant. */
@@ -12771,6 +12791,25 @@ var init_messages2 = __esm({
12771
12791
  /** Tag discriminating this response variant. */
12772
12792
  kind: z11.literal("heartbeat_ack")
12773
12793
  }).strict();
12794
+ ResourceAdmitDispositionSchema = z11.enum(["admitted", "deferred"]);
12795
+ ResourceAdmitResultResponseSchema = z11.object({
12796
+ /** Tag discriminating this response variant. */
12797
+ kind: z11.literal("resource_admit_result"),
12798
+ /** Whether the heavy op was admitted or deferred. */
12799
+ disposition: ResourceAdmitDispositionSchema,
12800
+ /** Back-off in ms before re-requesting (0 when admitted). */
12801
+ retry_after_ms: z11.number().int().nonnegative(),
12802
+ /** Remaining slots for the class after this decision. */
12803
+ slots_remaining: z11.number().int().nonnegative()
12804
+ }).strict();
12805
+ ResourceReleaseResultResponseSchema = z11.object({
12806
+ /** Tag discriminating this response variant. */
12807
+ kind: z11.literal("resource_release_result"),
12808
+ /** Whether a held slot was actually released (false = no such holder). */
12809
+ released: z11.boolean(),
12810
+ /** Remaining in-flight holders for the class after the release. */
12811
+ slots_remaining: z11.number().int().nonnegative()
12812
+ }).strict();
12774
12813
  LeaseErrorResponseSchema = z11.object({
12775
12814
  /** Tag discriminating this response variant. */
12776
12815
  kind: z11.literal("error"),
@@ -12789,6 +12828,8 @@ var init_messages2 = __esm({
12789
12828
  ChildKilledUnresponsiveResponseSchema,
12790
12829
  QueueAdmitResultResponseSchema,
12791
12830
  HeartbeatAckResponseSchema,
12831
+ ResourceAdmitResultResponseSchema,
12832
+ ResourceReleaseResultResponseSchema,
12792
12833
  LeaseErrorResponseSchema
12793
12834
  ]);
12794
12835
  LeaseIpcRequestEnvelopeSchema = z11.object({
@@ -12822,7 +12863,9 @@ var init_messages2 = __esm({
12822
12863
  "rate_check",
12823
12864
  "tool_grant",
12824
12865
  "queue_admit",
12825
- "worker_heartbeat"
12866
+ "worker_heartbeat",
12867
+ "resource_admit",
12868
+ "resource_release"
12826
12869
  ];
12827
12870
  LEASE_IPC_RESPONSE_KINDS = [
12828
12871
  "lease_granted",
@@ -12834,6 +12877,8 @@ var init_messages2 = __esm({
12834
12877
  "child_killed_unresponsive",
12835
12878
  "queue_admit_result",
12836
12879
  "heartbeat_ack",
12880
+ "resource_admit_result",
12881
+ "resource_release_result",
12837
12882
  "error"
12838
12883
  ];
12839
12884
  LEASE_IPC_MESSAGE_KINDS = [
@@ -12844,9 +12889,11 @@ var init_messages2 = __esm({
12844
12889
  });
12845
12890
 
12846
12891
  // packages/contracts/src/lease-ipc/version.ts
12892
+ var LEASE_IPC_PROTOCOL_VERSION;
12847
12893
  var init_version2 = __esm({
12848
12894
  "packages/contracts/src/lease-ipc/version.ts"() {
12849
12895
  "use strict";
12896
+ LEASE_IPC_PROTOCOL_VERSION = "1.2.0";
12850
12897
  }
12851
12898
  });
12852
12899
 
@@ -14045,6 +14092,25 @@ var init_render = __esm({
14045
14092
  }
14046
14093
  });
14047
14094
 
14095
+ // packages/contracts/src/resource-governor.ts
14096
+ var RESOURCE_CLASSES, DEFAULT_RESOURCE_RETRY_AFTER_MS;
14097
+ var init_resource_governor = __esm({
14098
+ "packages/contracts/src/resource-governor.ts"() {
14099
+ "use strict";
14100
+ RESOURCE_CLASSES = Object.freeze([
14101
+ "interactive-cli",
14102
+ "agent-session",
14103
+ "llm-call",
14104
+ "test-run",
14105
+ "scoped-build",
14106
+ "full-build",
14107
+ "db-heavy",
14108
+ "background-autonomous"
14109
+ ]);
14110
+ DEFAULT_RESOURCE_RETRY_AFTER_MS = 2e3;
14111
+ }
14112
+ });
14113
+
14048
14114
  // packages/contracts/src/session.ts
14049
14115
  var init_session2 = __esm({
14050
14116
  "packages/contracts/src/session.ts"() {
@@ -15795,6 +15861,7 @@ var init_src = __esm({
15795
15861
  init_evidence_atoms();
15796
15862
  init_plan();
15797
15863
  init_render();
15864
+ init_resource_governor();
15798
15865
  init_session2();
15799
15866
  init_session_journal();
15800
15867
  init_status_registry();
@@ -17825,7 +17892,7 @@ var init_sql = __esm({
17825
17892
  return new SQL([new StringChunk(str)]);
17826
17893
  }
17827
17894
  _sql.raw = raw;
17828
- function join32(chunks, separator) {
17895
+ function join34(chunks, separator) {
17829
17896
  const result = [];
17830
17897
  for (const [i, chunk] of chunks.entries()) {
17831
17898
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -17833,7 +17900,7 @@ var init_sql = __esm({
17833
17900
  }
17834
17901
  return new SQL(result);
17835
17902
  }
17836
- _sql.join = join32;
17903
+ _sql.join = join34;
17837
17904
  function identifier(value) {
17838
17905
  return new Name(value);
17839
17906
  }
@@ -20220,7 +20287,7 @@ var init_select2 = __esm({
20220
20287
  const baseTableName = this.tableName;
20221
20288
  const tableName = getTableLikeName(table);
20222
20289
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
20223
- if (typeof tableName === "string" && this.config.joins?.some((join32) => join32.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
20290
+ if (typeof tableName === "string" && this.config.joins?.some((join34) => join34.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
20224
20291
  if (!this.isPartialSelect) {
20225
20292
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
20226
20293
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -24030,7 +24097,7 @@ var init_dialect = __esm({
24030
24097
  if (!joins2) return;
24031
24098
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
24032
24099
  if (!withEntries.length) return;
24033
- return sql.join(withEntries.map(([k, join32]) => {
24100
+ return sql.join(withEntries.map(([k, join34]) => {
24034
24101
  const relation = tableConfig.relations[k];
24035
24102
  const isSingle2 = is(relation, One);
24036
24103
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -24041,7 +24108,7 @@ var init_dialect = __esm({
24041
24108
  table: targetTable,
24042
24109
  mode: isSingle2 ? "first" : "many",
24043
24110
  schema,
24044
- queryConfig: join32,
24111
+ queryConfig: join34,
24045
24112
  tableConfig: schema[relation.targetTableName],
24046
24113
  relationWhere: filter2,
24047
24114
  isNested: true,
@@ -24055,7 +24122,7 @@ var init_dialect = __esm({
24055
24122
  key: k,
24056
24123
  selection: innerQuery.selection,
24057
24124
  isArray: !isSingle2,
24058
- isOptional: (relation.optional ?? false) || join32 !== true && !!join32.where
24125
+ isOptional: (relation.optional ?? false) || join34 !== true && !!join34.where
24059
24126
  });
24060
24127
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
24061
24128
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb3}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -24876,7 +24943,7 @@ var init_update = __esm({
24876
24943
  createJoin(joinType) {
24877
24944
  return ((table, on) => {
24878
24945
  const tableName = getTableLikeName(table);
24879
- if (typeof tableName === "string" && this.config.joins.some((join32) => join32.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
24946
+ if (typeof tableName === "string" && this.config.joins.some((join34) => join34.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
24880
24947
  if (typeof on === "function") {
24881
24948
  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;
24882
24949
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -25951,8 +26018,8 @@ function probeAndMarkApplied(nativeDb, migration, logSubsystem, eliminatedTables
25951
26018
  });
25952
26019
  if (allAltersPresent && allTablesPresent && allIndexesPresent && allTriggersPresent) {
25953
26020
  insertJournalEntry(nativeDb, migration.hash, migration.folderMillis, migration.name ?? "");
25954
- const log8 = getLogger(logSubsystem);
25955
- log8.debug(
26021
+ const log9 = getLogger(logSubsystem);
26022
+ log9.debug(
25956
26023
  {
25957
26024
  migration: migration.name,
25958
26025
  alters: alterTargets.length,
@@ -26021,14 +26088,14 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
26021
26088
  if (hasOrphanedEntries) {
26022
26089
  const dbHashes = new Set(dbEntries.map((e) => e.hash));
26023
26090
  const allLocalHashesPresentInDb = localMigrations.every((m) => dbHashes.has(m.hash));
26024
- const log8 = getLogger(logSubsystem);
26091
+ const log9 = getLogger(logSubsystem);
26025
26092
  if (allLocalHashesPresentInDb) {
26026
- log8.debug(
26093
+ log9.debug(
26027
26094
  { extra: orphanedEntries.length },
26028
26095
  `Migration journal has ${orphanedEntries.length} entries for migrations not known to this install (DB is ahead). Skipping reconciliation.`
26029
26096
  );
26030
26097
  } else {
26031
- log8.warn(
26098
+ log9.warn(
26032
26099
  { orphaned: orphanedEntries.length },
26033
26100
  `Detected ${orphanedEntries.length} true-orphan journal entries from a previous CLEO lineage. Reconciling via DDL probe.`
26034
26101
  );
@@ -26064,8 +26131,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
26064
26131
  if (alterMatches.length === 0) {
26065
26132
  const stripped = stripSqlComments(fullSql).trim();
26066
26133
  if (stripped === "") {
26067
- const log8 = getLogger(logSubsystem);
26068
- log8.debug(
26134
+ const log9 = getLogger(logSubsystem);
26135
+ log9.debug(
26069
26136
  { migration: migration.name },
26070
26137
  `Migration ${migration.name} is a comment-only baseline marker \u2014 marking applied on existing DB.`
26071
26138
  );
@@ -26104,8 +26171,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
26104
26171
  }
26105
26172
  }
26106
26173
  if (missingColumns.length === 0) {
26107
- const log8 = getLogger(logSubsystem);
26108
- log8.warn(
26174
+ const log9 = getLogger(logSubsystem);
26175
+ log9.warn(
26109
26176
  { migration: migration.name, columns: alterMatches },
26110
26177
  `Detected partially-applied migration ${migration.name} \u2014 columns exist but journal entry missing. Auto-reconciling.`
26111
26178
  );
@@ -26113,8 +26180,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
26113
26180
  continue;
26114
26181
  }
26115
26182
  if (existingColumns.length > 0 && missingColumns.length > 0) {
26116
- const log8 = getLogger(logSubsystem);
26117
- log8.warn(
26183
+ const log9 = getLogger(logSubsystem);
26184
+ log9.warn(
26118
26185
  {
26119
26186
  migration: migration.name,
26120
26187
  existingColumns: existingColumns.map((c) => `${c.table}.${c.column}`),
@@ -26126,12 +26193,12 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
26126
26193
  if (!tableExists(nativeDb, table)) continue;
26127
26194
  try {
26128
26195
  nativeDb.exec(`ALTER TABLE ${table} ADD COLUMN ${column}${ddl ? ` ${ddl}` : ""}`);
26129
- log8.warn(
26196
+ log9.warn(
26130
26197
  { migration: migration.name, table, column },
26131
26198
  `T920: Added missing column ${table}.${column} to complete partial migration.`
26132
26199
  );
26133
26200
  } catch {
26134
- log8.warn(
26201
+ log9.warn(
26135
26202
  { migration: migration.name, table, column },
26136
26203
  `T920: Could not add missing column ${table}.${column} \u2014 will let Drizzle migrate() handle it.`
26137
26204
  );
@@ -26151,8 +26218,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
26151
26218
  for (const entry of unnamedEntries) {
26152
26219
  const migrationName = hashToName.get(entry.hash);
26153
26220
  if (!migrationName) continue;
26154
- const log8 = getLogger(logSubsystem);
26155
- log8.debug(
26221
+ const log9 = getLogger(logSubsystem);
26222
+ log9.debug(
26156
26223
  { id: entry.id, hash: entry.hash, name: migrationName },
26157
26224
  `Backfilling missing name on journal entry id=${entry.id} (Drizzle v1 beta legacy compat).`
26158
26225
  );
@@ -26236,13 +26303,13 @@ function ensureColumns(nativeDb, tableName, requiredColumns, logSubsystem, conte
26236
26303
  const existingCols = new Set(columns.map((c) => c.name));
26237
26304
  for (const req of requiredColumns) {
26238
26305
  if (!existingCols.has(req.name)) {
26239
- const log8 = getLogger(logSubsystem);
26306
+ const log9 = getLogger(logSubsystem);
26240
26307
  const message = `Adding missing column ${tableName}.${req.name} via ALTER TABLE`;
26241
26308
  const fields = { column: req.name, context };
26242
26309
  if (context === "fresh") {
26243
- log8.error(fields, `${message} \u2014 MIGRATION DEFECT (fresh DB should not need repair)`);
26310
+ log9.error(fields, `${message} \u2014 MIGRATION DEFECT (fresh DB should not need repair)`);
26244
26311
  } else {
26245
- log8.warn(fields, message);
26312
+ log9.warn(fields, message);
26246
26313
  }
26247
26314
  nativeDb.exec(`ALTER TABLE ${tableName} ADD COLUMN ${req.name} ${req.ddl}`);
26248
26315
  }
@@ -35323,11 +35390,750 @@ var init_cleo_global = __esm({
35323
35390
  }
35324
35391
  });
35325
35392
 
35326
- // packages/core/src/store/lock.ts
35393
+ // packages/core/src/resources/linux-backend.ts
35394
+ import { readFile as readFile2, stat } from "node:fs/promises";
35395
+ function parsePressureLine(line2) {
35396
+ const avg10Match = /avg10=([\d.]+)/.exec(line2);
35397
+ const avg60Match = /avg60=([\d.]+)/.exec(line2);
35398
+ const avg300Match = /avg300=([\d.]+)/.exec(line2);
35399
+ const totalMatch = /total=(\d+)/.exec(line2);
35400
+ if (!avg10Match?.[1] || !avg60Match?.[1] || !avg300Match?.[1] || !totalMatch?.[1]) {
35401
+ return null;
35402
+ }
35403
+ return {
35404
+ avg10: parseFloat(avg10Match[1]),
35405
+ avg60: parseFloat(avg60Match[1]),
35406
+ avg300: parseFloat(avg300Match[1]),
35407
+ totalUs: parseInt(totalMatch[1], 10)
35408
+ };
35409
+ }
35410
+ function parsePsiFile(content) {
35411
+ const lines = content.split("\n").map((l) => l.trim()).filter(Boolean);
35412
+ let some = null;
35413
+ let full = null;
35414
+ for (const line2 of lines) {
35415
+ if (line2.startsWith("some ")) {
35416
+ some = parsePressureLine(line2);
35417
+ } else if (line2.startsWith("full ")) {
35418
+ full = parsePressureLine(line2);
35419
+ }
35420
+ }
35421
+ if (!some) {
35422
+ return null;
35423
+ }
35424
+ return { some, full };
35425
+ }
35426
+ function parseMemAvailable(content) {
35427
+ for (const line2 of content.split("\n")) {
35428
+ if (line2.startsWith("MemAvailable:")) {
35429
+ const match = /MemAvailable:\s+(\d+)\s+kB/.exec(line2);
35430
+ if (match?.[1]) {
35431
+ return parseInt(match[1], 10) * 1024;
35432
+ }
35433
+ }
35434
+ }
35435
+ return null;
35436
+ }
35437
+ function parseSmapsRollup(content) {
35438
+ let rssKb = null;
35439
+ let pssKb = null;
35440
+ for (const line2 of content.split("\n")) {
35441
+ if (line2.startsWith("Rss:")) {
35442
+ const m = /Rss:\s+(\d+)\s+kB/.exec(line2);
35443
+ if (m?.[1]) rssKb = parseInt(m[1], 10);
35444
+ } else if (line2.startsWith("Pss:")) {
35445
+ const m = /Pss:\s+(\d+)\s+kB/.exec(line2);
35446
+ if (m?.[1]) pssKb = parseInt(m[1], 10);
35447
+ }
35448
+ }
35449
+ if (rssKb === null || pssKb === null) return null;
35450
+ return { rssBytes: rssKb * 1024, pssBytes: pssKb * 1024 };
35451
+ }
35452
+ var defaultReadFile, defaultStat, LinuxResourceBackend;
35453
+ var init_linux_backend = __esm({
35454
+ "packages/core/src/resources/linux-backend.ts"() {
35455
+ "use strict";
35456
+ defaultReadFile = (path, encoding) => readFile2(path, encoding);
35457
+ defaultStat = async (path) => {
35458
+ try {
35459
+ const s = await stat(path);
35460
+ return { size: s.size };
35461
+ } catch {
35462
+ return null;
35463
+ }
35464
+ };
35465
+ LinuxResourceBackend = class {
35466
+ globalPressurePath;
35467
+ cgroupSlicePressurePath;
35468
+ walPaths;
35469
+ readFileFn;
35470
+ statFileFn;
35471
+ constructor(opts = {}) {
35472
+ this.globalPressurePath = opts.globalPressurePath ?? "/proc/pressure/memory";
35473
+ this.cgroupSlicePressurePath = opts.cgroupSlicePressurePath ?? null;
35474
+ this.walPaths = opts.walPaths ?? [];
35475
+ this.readFileFn = opts.readFileFn ?? defaultReadFile;
35476
+ this.statFileFn = opts.statFileFn ?? defaultStat;
35477
+ }
35478
+ /**
35479
+ * Take a bounded point-in-time resource sample.
35480
+ *
35481
+ * Read-count (bounded by Amendment 1):
35482
+ * - 1 read: `/proc/pressure/memory`
35483
+ * - 0–1 reads: slice `memory.pressure` (if configured)
35484
+ * - 1 read: `/proc/meminfo`
35485
+ * - N stat calls: one per WAL path in `walPaths`
35486
+ *
35487
+ * Never spawns a child process.
35488
+ */
35489
+ async sample() {
35490
+ const sampledAtMs = Date.now();
35491
+ const globalPressure = await this._readPsi(this.globalPressurePath);
35492
+ const pressureAvailable = globalPressure !== null;
35493
+ let slicePressure = null;
35494
+ if (this.cgroupSlicePressurePath) {
35495
+ slicePressure = await this._readPsi(this.cgroupSlicePressurePath);
35496
+ }
35497
+ const memAvailableBytes = await this._readMemAvailable();
35498
+ const walObservations = await this._readWalObservations();
35499
+ return {
35500
+ sampledAtMs,
35501
+ pressureAvailable,
35502
+ memAvailableBytes,
35503
+ globalPressure,
35504
+ slicePressure,
35505
+ walObservations
35506
+ };
35507
+ }
35508
+ /**
35509
+ * Sweep per-child RSS via `/proc/<pid>/smaps_rollup`.
35510
+ *
35511
+ * **STRUCTURALLY SEPARATED from sample()** — smaps_rollup reads are
35512
+ * ms-scale per multi-GB process and must never appear in the hot path.
35513
+ * Call on a separate low-frequency cadence (e.g. every 60s or on
35514
+ * backoff→hold state transition).
35515
+ *
35516
+ * @param pids - PIDs to sweep. Dead/unknown PIDs are silently skipped.
35517
+ */
35518
+ async sweepChildRss(pids) {
35519
+ const sampledAtMs = Date.now();
35520
+ const entries = [];
35521
+ for (const pid of pids) {
35522
+ try {
35523
+ const content = await this.readFileFn(`/proc/${pid}/smaps_rollup`, "utf-8");
35524
+ const parsed = parseSmapsRollup(content);
35525
+ if (parsed) {
35526
+ entries.push({ pid, ...parsed });
35527
+ }
35528
+ } catch {
35529
+ }
35530
+ }
35531
+ return { sampledAtMs, entries };
35532
+ }
35533
+ // -------------------------------------------------------------------------
35534
+ // Private helpers
35535
+ // -------------------------------------------------------------------------
35536
+ async _readPsi(path) {
35537
+ try {
35538
+ const content = await this.readFileFn(path, "utf-8");
35539
+ return parsePsiFile(content);
35540
+ } catch {
35541
+ return null;
35542
+ }
35543
+ }
35544
+ async _readMemAvailable() {
35545
+ try {
35546
+ const content = await this.readFileFn("/proc/meminfo", "utf-8");
35547
+ return parseMemAvailable(content);
35548
+ } catch {
35549
+ return null;
35550
+ }
35551
+ }
35552
+ async _readWalObservations() {
35553
+ const results = [];
35554
+ for (const walPath of this.walPaths) {
35555
+ const info = await this.statFileFn(walPath);
35556
+ results.push({ walPath, sizeBytes: info?.size ?? null });
35557
+ }
35558
+ return results;
35559
+ }
35560
+ };
35561
+ }
35562
+ });
35563
+
35564
+ // packages/core/src/resources/monitor.ts
35565
+ import { EventEmitter as EventEmitter2 } from "node:events";
35566
+ function resolveThresholds(cfg) {
35567
+ return {
35568
+ holdSomeAvg10: cfg.psi?.holdSomeAvg10 ?? DEFAULTS.holdSomeAvg10,
35569
+ backoffSomeAvg10: cfg.psi?.backoffSomeAvg10 ?? DEFAULTS.backoffSomeAvg10,
35570
+ holdFullAvg10: cfg.psi?.holdFullAvg10 ?? DEFAULTS.holdFullAvg10,
35571
+ backoffFullAvg10: cfg.psi?.backoffFullAvg10 ?? DEFAULTS.backoffFullAvg10,
35572
+ hysteresisPoints: cfg.hysteresisPoints ?? DEFAULTS.hysteresisPoints,
35573
+ headroomBytes: cfg.headroomBytes ?? DEFAULTS.headroomBytes,
35574
+ walWarnThresholdBytes: cfg.walWarnThresholdBytes ?? DEFAULTS.walWarnThresholdBytes,
35575
+ pollIntervalMs: cfg.pollIntervalMs ?? DEFAULTS.pollIntervalMs
35576
+ };
35577
+ }
35578
+ function evaluateState(sample, thresholds, currentState) {
35579
+ if (!sample.pressureAvailable) {
35580
+ if (sample.memAvailableBytes !== null && sample.memAvailableBytes < thresholds.headroomBytes) {
35581
+ return { state: "hold", reason: "degraded: memAvailable below headroom" };
35582
+ }
35583
+ return { state: "ok", reason: "degraded: PSI unavailable, memAvailable sufficient" };
35584
+ }
35585
+ const somePressure = sample.globalPressure?.some ?? sample.slicePressure?.some;
35586
+ const fullPressure = sample.globalPressure?.full ?? sample.slicePressure?.full;
35587
+ const someAvg102 = somePressure?.avg10 ?? 0;
35588
+ const fullAvg10 = fullPressure?.avg10 ?? 0;
35589
+ if (someAvg102 > thresholds.backoffSomeAvg10 || fullAvg10 > thresholds.backoffFullAvg10) {
35590
+ return {
35591
+ state: "backoff",
35592
+ reason: `some avg10=${someAvg102.toFixed(2)} full avg10=${fullAvg10.toFixed(2)} \u2014 above backoff threshold`
35593
+ };
35594
+ }
35595
+ if (someAvg102 > thresholds.holdSomeAvg10 || fullAvg10 > thresholds.holdFullAvg10) {
35596
+ return {
35597
+ state: "hold",
35598
+ reason: `some avg10=${someAvg102.toFixed(2)} full avg10=${fullAvg10.toFixed(2)} \u2014 above hold threshold`
35599
+ };
35600
+ }
35601
+ if (currentState !== "ok") {
35602
+ const hysteresisFloor = thresholds.holdSomeAvg10 - thresholds.hysteresisPoints;
35603
+ const fullHysteresisFloor = thresholds.holdFullAvg10 - thresholds.hysteresisPoints;
35604
+ if (someAvg102 > hysteresisFloor || fullAvg10 > fullHysteresisFloor) {
35605
+ const clamped = currentState === "backoff" ? "hold" : currentState;
35606
+ return {
35607
+ state: clamped,
35608
+ reason: `some avg10=${someAvg102.toFixed(2)} full avg10=${fullAvg10.toFixed(2)} \u2014 hysteresis hold (floor: some ${hysteresisFloor}, full ${fullHysteresisFloor})`
35609
+ };
35610
+ }
35611
+ }
35612
+ return {
35613
+ state: "ok",
35614
+ reason: `some avg10=${someAvg102.toFixed(2)} full avg10=${fullAvg10.toFixed(2)} \u2014 below thresholds`
35615
+ };
35616
+ }
35617
+ var DEFAULTS, ResourceMonitor;
35618
+ var init_monitor = __esm({
35619
+ "packages/core/src/resources/monitor.ts"() {
35620
+ "use strict";
35621
+ init_linux_backend();
35622
+ DEFAULTS = {
35623
+ holdSomeAvg10: 10,
35624
+ backoffSomeAvg10: 20,
35625
+ holdFullAvg10: 5,
35626
+ backoffFullAvg10: 10,
35627
+ hysteresisPoints: 3,
35628
+ headroomBytes: 256 * 1024 * 1024,
35629
+ walWarnThresholdBytes: 256 * 1024 * 1024,
35630
+ pollIntervalMs: 1500
35631
+ };
35632
+ ResourceMonitor = class extends EventEmitter2 {
35633
+ thresholds;
35634
+ backend;
35635
+ _state = "ok";
35636
+ _timer = null;
35637
+ _running = false;
35638
+ constructor(cfg = {}) {
35639
+ super();
35640
+ this.thresholds = resolveThresholds(cfg);
35641
+ this.backend = cfg.backend ?? new LinuxResourceBackend();
35642
+ }
35643
+ // -------------------------------------------------------------------------
35644
+ // Public API
35645
+ // -------------------------------------------------------------------------
35646
+ /**
35647
+ * Current pressure state (only meaningful after at least one sample).
35648
+ */
35649
+ get state() {
35650
+ return this._state;
35651
+ }
35652
+ /**
35653
+ * `true` while the continuous loop is running.
35654
+ */
35655
+ get running() {
35656
+ return this._running;
35657
+ }
35658
+ /**
35659
+ * Take a single point-in-time resource sample.
35660
+ *
35661
+ * Safe to call with the daemon off (no child processes, bounded reads).
35662
+ * Does NOT update `this.state` — use {@link startContinuous} for that.
35663
+ */
35664
+ async sample() {
35665
+ return this.backend.sample();
35666
+ }
35667
+ /**
35668
+ * Start the continuous polling loop.
35669
+ *
35670
+ * Returns a `stop()` function. Calling `stop()` is idempotent.
35671
+ *
35672
+ * Emits:
35673
+ * - `'sample'` on every poll (even if state did not change)
35674
+ * - `'transition'` when `PressureState` changes
35675
+ * - `'error'` if the backend throws (loop continues regardless)
35676
+ */
35677
+ startContinuous() {
35678
+ if (this._running) {
35679
+ return () => this._stopLoop();
35680
+ }
35681
+ this._running = true;
35682
+ this._scheduleNext();
35683
+ return () => this._stopLoop();
35684
+ }
35685
+ /**
35686
+ * Stop the continuous polling loop. Idempotent.
35687
+ */
35688
+ stop() {
35689
+ this._stopLoop();
35690
+ }
35691
+ // -------------------------------------------------------------------------
35692
+ // Private loop machinery
35693
+ // -------------------------------------------------------------------------
35694
+ _scheduleNext() {
35695
+ this._timer = setTimeout(() => {
35696
+ void this._tick();
35697
+ }, this.thresholds.pollIntervalMs);
35698
+ if (typeof this._timer.unref === "function") {
35699
+ this._timer.unref();
35700
+ }
35701
+ }
35702
+ async _tick() {
35703
+ if (!this._running) return;
35704
+ try {
35705
+ const sample = await this.backend.sample();
35706
+ this.emit("sample", sample);
35707
+ const { state: newState, reason } = evaluateState(sample, this.thresholds, this._state);
35708
+ if (newState !== this._state) {
35709
+ const transition = {
35710
+ from: this._state,
35711
+ to: newState,
35712
+ sample,
35713
+ reason
35714
+ };
35715
+ this._state = newState;
35716
+ this.emit("transition", transition);
35717
+ }
35718
+ } catch (err) {
35719
+ this.emit("error", err instanceof Error ? err : new Error(String(err)));
35720
+ }
35721
+ if (this._running) {
35722
+ this._scheduleNext();
35723
+ }
35724
+ }
35725
+ _stopLoop() {
35726
+ this._running = false;
35727
+ if (this._timer !== null) {
35728
+ clearTimeout(this._timer);
35729
+ this._timer = null;
35730
+ }
35731
+ }
35732
+ };
35733
+ }
35734
+ });
35735
+
35736
+ // packages/core/src/resources/supervisor-admit.ts
35737
+ import { connect } from "node:net";
35738
+ import { join as join7 } from "node:path";
35739
+ import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
35740
+ function resolveSupervisorSocketPath() {
35741
+ return process.env.CLEO_SUPERVISOR_SOCKET ?? join7(getCleoHome2(), SUPERVISOR_SOCKET_NAME);
35742
+ }
35743
+ async function sendResourceAdmit(socketPath, cls, holderId, budget) {
35744
+ const result = await sendLeaseRequest(
35745
+ socketPath,
35746
+ { kind: "resource_admit", class: cls, holder_id: holderId, budget },
35747
+ "resource_admit_result"
35748
+ );
35749
+ if ("unavailable" in result) return result;
35750
+ if (result.kind === "resource_admit_result") return result;
35751
+ return { unavailable: true, reason: `unexpected response kind: ${result.kind}` };
35752
+ }
35753
+ async function sendResourceRelease(socketPath, cls, holderId) {
35754
+ const result = await sendLeaseRequest(
35755
+ socketPath,
35756
+ { kind: "resource_release", class: cls, holder_id: holderId },
35757
+ "resource_release_result"
35758
+ );
35759
+ if ("unavailable" in result) return result;
35760
+ if (result.kind === "resource_release_result") return result;
35761
+ return { unavailable: true, reason: `unexpected response kind: ${result.kind}` };
35762
+ }
35763
+ function sendLeaseRequest(socketPath, request, expectedKind) {
35764
+ return new Promise((resolve5) => {
35765
+ const id = `ra-${process.pid}-${request.kind}`;
35766
+ const envelope = LeaseIpcRequestEnvelopeSchema.parse({
35767
+ protocol_version: LEASE_IPC_PROTOCOL_VERSION,
35768
+ id,
35769
+ direction: "request",
35770
+ request
35771
+ });
35772
+ const line2 = `${JSON.stringify(envelope)}
35773
+ `;
35774
+ let settled = false;
35775
+ let buffer = "";
35776
+ const socket = connect(socketPath);
35777
+ const done = (value) => {
35778
+ if (settled) return;
35779
+ settled = true;
35780
+ socket.removeAllListeners();
35781
+ socket.destroy();
35782
+ resolve5(value);
35783
+ };
35784
+ const degrade = (reason) => done({ unavailable: true, reason });
35785
+ socket.setTimeout(REQUEST_TIMEOUT_MS);
35786
+ const connectTimer = setTimeout(
35787
+ () => degrade("supervisor connect timeout"),
35788
+ CONNECT_TIMEOUT_MS
35789
+ );
35790
+ socket.on("connect", () => {
35791
+ clearTimeout(connectTimer);
35792
+ socket.write(line2);
35793
+ });
35794
+ socket.on("timeout", () => degrade("supervisor request timeout"));
35795
+ socket.on("error", (err) => {
35796
+ clearTimeout(connectTimer);
35797
+ degrade(err.message);
35798
+ });
35799
+ socket.on("close", () => {
35800
+ if (!settled) degrade("supervisor closed the connection before responding");
35801
+ });
35802
+ socket.on("data", (chunk) => {
35803
+ buffer += chunk.toString("utf8");
35804
+ const nl = buffer.indexOf("\n");
35805
+ if (nl < 0) return;
35806
+ let json3;
35807
+ try {
35808
+ json3 = JSON.parse(buffer.slice(0, nl));
35809
+ } catch (cause) {
35810
+ degrade(`malformed lease-ipc frame: ${cause instanceof Error ? cause.message : cause}`);
35811
+ return;
35812
+ }
35813
+ const parsed = LeaseIpcResponseEnvelopeSchema.safeParse(json3);
35814
+ if (!parsed.success) {
35815
+ degrade(`off-contract lease-ipc response: ${parsed.error.message}`);
35816
+ return;
35817
+ }
35818
+ const { response } = parsed.data;
35819
+ if (response.kind === expectedKind) {
35820
+ done(response);
35821
+ return;
35822
+ }
35823
+ if (response.kind === "error") {
35824
+ degrade(`${response.code}: ${response.message}`);
35825
+ return;
35826
+ }
35827
+ degrade(`unexpected lease-ipc response kind for ${request.kind}: ${response.kind}`);
35828
+ });
35829
+ });
35830
+ }
35831
+ var SUPERVISOR_SOCKET_NAME, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS;
35832
+ var init_supervisor_admit = __esm({
35833
+ "packages/core/src/resources/supervisor-admit.ts"() {
35834
+ "use strict";
35835
+ init_src();
35836
+ SUPERVISOR_SOCKET_NAME = "cleo-supervisor.sock";
35837
+ CONNECT_TIMEOUT_MS = 250;
35838
+ REQUEST_TIMEOUT_MS = 2e3;
35839
+ }
35840
+ });
35841
+
35842
+ // packages/core/src/resources/governor.ts
35843
+ var governor_exports = {};
35844
+ __export(governor_exports, {
35845
+ ResourceGovernor: () => ResourceGovernor,
35846
+ _resetGovernorStateForTest: () => _resetGovernorStateForTest,
35847
+ computeClassBudget: () => computeClassBudget,
35848
+ governor: () => governor,
35849
+ governorSlotDir: () => governorSlotDir,
35850
+ resolveGovernorMode: () => resolveGovernorMode,
35851
+ slotFileCount: () => slotFileCount
35852
+ });
35853
+ import { existsSync as existsSync4, mkdirSync, readdirSync as readdirSync2, writeFileSync } from "node:fs";
35854
+ import { availableParallelism, totalmem } from "node:os";
35855
+ import { join as join8 } from "node:path";
35327
35856
  import lockfile from "proper-lockfile";
35857
+ function log2() {
35858
+ if (_log2 === null) _log2 = getLogger("resource-governor");
35859
+ return _log2;
35860
+ }
35861
+ function resolveGovernorMode() {
35862
+ if (_cachedMode2 !== null) return _cachedMode2;
35863
+ const raw = process.env.CLEO_RESOURCES_MODE;
35864
+ _cachedMode2 = raw === "supervisor" || raw === "local" || raw === "off" ? raw : "local";
35865
+ return _cachedMode2;
35866
+ }
35867
+ function logSupervisorDegradeOnce(reason) {
35868
+ if (_supervisorDegradeLogged) return;
35869
+ _supervisorDegradeLogged = true;
35870
+ log2().info(
35871
+ `CLEO_RESOURCES_MODE=supervisor but the arbiter is unreachable (${reason}); degrading to local-mode admission for the process lifetime.`
35872
+ );
35873
+ }
35874
+ function _resetGovernorStateForTest() {
35875
+ _cachedMode2 = null;
35876
+ _supervisorDegradeLogged = false;
35877
+ }
35878
+ function someAvg10(sample) {
35879
+ const some = sample.globalPressure?.some ?? sample.slicePressure?.some;
35880
+ return some?.avg10 ?? 0;
35881
+ }
35882
+ function computeClassBudget(cls, sample, opts = {}) {
35883
+ if (cls === "interactive-cli") return Number.POSITIVE_INFINITY;
35884
+ const cpus = Math.max(1, opts.cpuCount ?? availableParallelism());
35885
+ const totalBytes = opts.totalMemBytes ?? totalmem();
35886
+ const headroomBytes = (opts.headroomMb ?? 2048) * MB;
35887
+ const hold = opts.holdSomeAvg10 ?? 10;
35888
+ const floor = opts.floorSomeAvg10 ?? 25;
35889
+ const some = someAvg10(sample);
35890
+ const availBytes = sample.memAvailableBytes ?? totalBytes;
35891
+ const fullStall = sample.globalPressure?.full?.avg10 ?? sample.slicePressure?.full?.avg10 ?? 0;
35892
+ const backoff = some > floor || fullStall > 10;
35893
+ switch (cls) {
35894
+ case "full-build":
35895
+ return 1;
35896
+ case "agent-session": {
35897
+ const estRamBytes = (opts.agentEstRamMb ?? 4096) * MB;
35898
+ const byMem = Math.floor((availBytes - headroomBytes) / estRamBytes);
35899
+ return clamp2(1, byMem, Math.max(1, cpus - 2));
35900
+ }
35901
+ case "llm-call":
35902
+ return Math.max(1, cpus - 2);
35903
+ case "test-run":
35904
+ case "scoped-build": {
35905
+ const base = Math.max(1, Math.floor(cpus / 4));
35906
+ if (some > floor) return 1;
35907
+ if (some > hold) return Math.max(1, Math.floor(base / 2));
35908
+ return base;
35909
+ }
35910
+ case "db-heavy":
35911
+ return backoff ? 0 : 1;
35912
+ case "background-autonomous":
35913
+ return some > hold || fullStall > 5 ? 0 : 1;
35914
+ default:
35915
+ return 1;
35916
+ }
35917
+ }
35918
+ function clamp2(lo, v, hi) {
35919
+ return Math.max(lo, Math.min(v, hi));
35920
+ }
35921
+ function governorSlotDir(cls) {
35922
+ return join8(getCleoHome(), "locks", `resource-${cls}`);
35923
+ }
35924
+ function ensureSlotFiles(dir, count) {
35925
+ if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
35926
+ const paths = [];
35927
+ for (let i = 0; i < count; i++) {
35928
+ const p = join8(dir, `slot-${i}.lock`);
35929
+ if (!existsSync4(p)) writeFileSync(p, "", { flag: "a" });
35930
+ paths.push(p);
35931
+ }
35932
+ return paths;
35933
+ }
35934
+ function sleep(ms) {
35935
+ return new Promise((r) => setTimeout(r, ms));
35936
+ }
35937
+ function passThroughGrant(cls) {
35938
+ return {
35939
+ deferred: false,
35940
+ class: cls,
35941
+ slot: -1,
35942
+ acquiredAtMs: Date.now(),
35943
+ release: async () => {
35944
+ }
35945
+ };
35946
+ }
35947
+ function deferral(cls, reason, retryAfterMs) {
35948
+ return { deferred: true, class: cls, retryAfterMs, reason };
35949
+ }
35950
+ function supervisorHolderId(cls) {
35951
+ _supervisorHolderSeq += 1;
35952
+ return `${process.pid}:${cls}:${_supervisorHolderSeq}`;
35953
+ }
35954
+ function shuffledIndices(n) {
35955
+ const order = Array.from({ length: n }, (_, i) => i);
35956
+ for (let i = order.length - 1; i > 0; i--) {
35957
+ const j = Math.floor(Math.random() * (i + 1));
35958
+ const a = order[i];
35959
+ const b = order[j];
35960
+ if (a !== void 0 && b !== void 0) {
35961
+ order[i] = b;
35962
+ order[j] = a;
35963
+ }
35964
+ }
35965
+ return order;
35966
+ }
35967
+ async function countHeldSlots(cls, budget) {
35968
+ const dir = governorSlotDir(cls);
35969
+ if (!existsSync4(dir)) return 0;
35970
+ const slots = ensureSlotFiles(dir, budget);
35971
+ let held = 0;
35972
+ for (const path of slots) {
35973
+ try {
35974
+ const release = await lockfile.lock(path, { retries: 0, stale: STALE_MS, realpath: false });
35975
+ await release();
35976
+ } catch {
35977
+ held++;
35978
+ }
35979
+ }
35980
+ return held;
35981
+ }
35982
+ function slotFileCount(cls) {
35983
+ const dir = governorSlotDir(cls);
35984
+ if (!existsSync4(dir)) return 0;
35985
+ return readdirSync2(dir).filter((f) => f.startsWith("slot-") && f.endsWith(".lock")).length;
35986
+ }
35987
+ var _log2, _cachedMode2, _supervisorDegradeLogged, MB, STALE_MS, _supervisorHolderSeq, ResourceGovernor, governor;
35988
+ var init_governor = __esm({
35989
+ "packages/core/src/resources/governor.ts"() {
35990
+ "use strict";
35991
+ init_src();
35992
+ init_logger();
35993
+ init_paths();
35994
+ init_monitor();
35995
+ init_supervisor_admit();
35996
+ _log2 = null;
35997
+ _cachedMode2 = null;
35998
+ _supervisorDegradeLogged = false;
35999
+ MB = 1024 * 1024;
36000
+ STALE_MS = 6e5;
36001
+ _supervisorHolderSeq = 0;
36002
+ ResourceGovernor = class {
36003
+ /**
36004
+ * Acquire one slot of `cls`. Returns a {@link ResourceGrant} on success or a
36005
+ * {@link ResourceDeferral} on denial. Never throws for admission control;
36006
+ * only genuinely unexpected I/O errors propagate.
36007
+ */
36008
+ async acquire(cls, opts = {}) {
36009
+ const mode = resolveGovernorMode();
36010
+ if (mode === "off" || cls === "interactive-cli") {
36011
+ return passThroughGrant(cls);
36012
+ }
36013
+ const sample = opts.sample ?? await (opts.monitor ?? new ResourceMonitor()).sample();
36014
+ const budget = computeClassBudget(cls, sample, opts);
36015
+ if (!Number.isFinite(budget)) return passThroughGrant(cls);
36016
+ if (budget <= 0) {
36017
+ return deferral(
36018
+ cls,
36019
+ `class '${cls}' budget is 0 under current pressure (some avg10=${someAvg10(sample).toFixed(1)})`,
36020
+ DEFAULT_RESOURCE_RETRY_AFTER_MS
36021
+ );
36022
+ }
36023
+ if (mode === "supervisor") {
36024
+ const viaSupervisor = await this.acquireViaSupervisor(cls, Math.floor(budget));
36025
+ if (viaSupervisor !== null) return viaSupervisor;
36026
+ }
36027
+ const dir = governorSlotDir(cls);
36028
+ const slots = ensureSlotFiles(dir, budget);
36029
+ const blocking = opts.blocking ?? true;
36030
+ const timeoutMs = opts.timeoutMs ?? 36e5;
36031
+ const pollMs = opts.pollMs ?? 200;
36032
+ const startedAt = Date.now();
36033
+ do {
36034
+ const order = shuffledIndices(slots.length);
36035
+ for (const idx of order) {
36036
+ const path = slots[idx];
36037
+ if (!path) continue;
36038
+ try {
36039
+ const release = await lockfile.lock(path, {
36040
+ retries: 0,
36041
+ stale: STALE_MS,
36042
+ realpath: false
36043
+ });
36044
+ let released = false;
36045
+ return {
36046
+ deferred: false,
36047
+ class: cls,
36048
+ slot: idx,
36049
+ acquiredAtMs: Date.now(),
36050
+ release: async () => {
36051
+ if (released) return;
36052
+ released = true;
36053
+ try {
36054
+ await release();
36055
+ } catch {
36056
+ }
36057
+ }
36058
+ };
36059
+ } catch {
36060
+ }
36061
+ }
36062
+ if (!blocking) break;
36063
+ await sleep(pollMs);
36064
+ } while (Date.now() - startedAt < timeoutMs);
36065
+ return deferral(
36066
+ cls,
36067
+ `class '${cls}' is at capacity (${budget} slot(s)); ` + (blocking ? `timed out after ${timeoutMs}ms` : "no slot free"),
36068
+ Math.min(pollMs * 4, DEFAULT_RESOURCE_RETRY_AFTER_MS)
36069
+ );
36070
+ }
36071
+ /**
36072
+ * Route an admission through the supervisor's central `resource_admit` verb.
36073
+ * Returns a grant (whose `release` calls `resource_release`) or a deferral, or
36074
+ * `null` when the supervisor is unreachable so the caller degrades to the
36075
+ * local slot engine. Never throws — a dead arbiter never deadlocks work.
36076
+ *
36077
+ * @task T12001
36078
+ */
36079
+ async acquireViaSupervisor(cls, budget) {
36080
+ const socketPath = resolveSupervisorSocketPath();
36081
+ const holderId = supervisorHolderId(cls);
36082
+ const reply = await sendResourceAdmit(socketPath, cls, holderId, budget);
36083
+ if ("unavailable" in reply) {
36084
+ logSupervisorDegradeOnce(reply.reason);
36085
+ return null;
36086
+ }
36087
+ if (reply.disposition === "deferred") {
36088
+ return deferral(
36089
+ cls,
36090
+ `class '${cls}' deferred by supervisor (budget ${budget})`,
36091
+ reply.retry_after_ms || DEFAULT_RESOURCE_RETRY_AFTER_MS
36092
+ );
36093
+ }
36094
+ let released = false;
36095
+ return {
36096
+ deferred: false,
36097
+ class: cls,
36098
+ slot: 0,
36099
+ acquiredAtMs: Date.now(),
36100
+ release: async () => {
36101
+ if (released) return;
36102
+ released = true;
36103
+ await sendResourceRelease(socketPath, cls, holderId).catch(() => {
36104
+ });
36105
+ }
36106
+ };
36107
+ }
36108
+ /** Non-blocking single-pass acquire (admission semantics). */
36109
+ async tryAcquire(cls, opts = {}) {
36110
+ return this.acquire(cls, { ...opts, blocking: false });
36111
+ }
36112
+ /**
36113
+ * Currently-grantable slot count for `cls` = budget − held. Held is the count
36114
+ * of slot files currently locked. `Infinity` for ungated classes.
36115
+ */
36116
+ async available(cls, opts = {}) {
36117
+ if (resolveGovernorMode() === "off" || cls === "interactive-cli") {
36118
+ return Number.POSITIVE_INFINITY;
36119
+ }
36120
+ const sample = opts.sample ?? await (opts.monitor ?? new ResourceMonitor()).sample();
36121
+ const budget = computeClassBudget(cls, sample, opts);
36122
+ if (!Number.isFinite(budget)) return Number.POSITIVE_INFINITY;
36123
+ if (budget <= 0) return 0;
36124
+ const held = await countHeldSlots(cls, budget);
36125
+ return Math.max(0, budget - held);
36126
+ }
36127
+ };
36128
+ governor = new ResourceGovernor();
36129
+ }
36130
+ });
36131
+
36132
+ // packages/core/src/store/lock.ts
36133
+ import lockfile2 from "proper-lockfile";
35328
36134
  async function acquireLock(filePath, options) {
35329
36135
  try {
35330
- const release = await lockfile.lock(filePath, {
36136
+ const release = await lockfile2.lock(filePath, {
35331
36137
  ...DEFAULT_LOCK_OPTIONS,
35332
36138
  ...options?.stale !== void 0 && { stale: options.stale },
35333
36139
  ...options?.retries !== void 0 && {
@@ -35373,7 +36179,7 @@ var init_lock = __esm({
35373
36179
  });
35374
36180
 
35375
36181
  // packages/core/src/store/atomic.ts
35376
- import { mkdir, readFile as readFile2, rename, unlink } from "node:fs/promises";
36182
+ import { mkdir, readFile as readFile3, rename, unlink } from "node:fs/promises";
35377
36183
  import { dirname as dirname4 } from "node:path";
35378
36184
  import writeFileAtomic from "write-file-atomic";
35379
36185
  async function atomicWrite(filePath, data, options) {
@@ -35389,7 +36195,7 @@ async function atomicWrite(filePath, data, options) {
35389
36195
  }
35390
36196
  async function safeReadFile(filePath) {
35391
36197
  try {
35392
- return await readFile2(filePath, "utf8");
36198
+ return await readFile3(filePath, "utf8");
35393
36199
  } catch (err) {
35394
36200
  if (err instanceof Error && "code" in err && err.code === "ENOENT") {
35395
36201
  return null;
@@ -35410,34 +36216,34 @@ var init_atomic = __esm({
35410
36216
  });
35411
36217
 
35412
36218
  // packages/core/src/store/backup.ts
35413
- import { copyFile, rename as fsRename, mkdir as mkdir2, readdir, stat, unlink as unlink2 } from "node:fs/promises";
35414
- import { basename, join as join7 } from "node:path";
36219
+ import { copyFile, rename as fsRename, mkdir as mkdir2, readdir, stat as stat2, unlink as unlink2 } from "node:fs/promises";
36220
+ import { basename, join as join9 } from "node:path";
35415
36221
  async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUPS) {
35416
36222
  try {
35417
36223
  await mkdir2(backupDir, { recursive: true });
35418
36224
  const fileName = basename(filePath);
35419
36225
  try {
35420
- await stat(filePath);
36226
+ await stat2(filePath);
35421
36227
  } catch {
35422
36228
  throw new CleoError(3 /* FILE_ERROR */, `Cannot backup: source file not found: ${filePath}`);
35423
36229
  }
35424
36230
  for (let i = maxBackups; i >= 1; i--) {
35425
- const current = join7(backupDir, `${fileName}.${i}`);
36231
+ const current = join9(backupDir, `${fileName}.${i}`);
35426
36232
  if (i === maxBackups) {
35427
36233
  try {
35428
36234
  await unlink2(current);
35429
36235
  } catch {
35430
36236
  }
35431
36237
  } else {
35432
- const next = join7(backupDir, `${fileName}.${i + 1}`);
36238
+ const next = join9(backupDir, `${fileName}.${i + 1}`);
35433
36239
  try {
35434
- await stat(current);
36240
+ await stat2(current);
35435
36241
  await fsRename(current, next);
35436
36242
  } catch {
35437
36243
  }
35438
36244
  }
35439
36245
  }
35440
- const backupPath = join7(backupDir, `${fileName}.1`);
36246
+ const backupPath = join9(backupDir, `${fileName}.1`);
35441
36247
  await copyFile(filePath, backupPath);
35442
36248
  return backupPath;
35443
36249
  } catch (err) {
@@ -35716,8 +36522,8 @@ var init_json2 = __esm({
35716
36522
  });
35717
36523
 
35718
36524
  // packages/core/src/scaffold/ensure-config.ts
35719
- import { existsSync as existsSync4, readFileSync as readFileSync2 } from "node:fs";
35720
- import { basename as basename2, dirname as dirname5, join as join8, resolve as resolve2 } from "node:path";
36525
+ import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
36526
+ import { basename as basename2, dirname as dirname5, join as join10, resolve as resolve2 } from "node:path";
35721
36527
  import { fileURLToPath as fileURLToPath2 } from "node:url";
35722
36528
  function getPackageRoot() {
35723
36529
  const thisFile = fileURLToPath2(import.meta.url);
@@ -35725,7 +36531,7 @@ function getPackageRoot() {
35725
36531
  }
35726
36532
  function getCleoVersion() {
35727
36533
  try {
35728
- const pkgPath = join8(getPackageRoot(), "package.json");
36534
+ const pkgPath = join10(getPackageRoot(), "package.json");
35729
36535
  const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
35730
36536
  return pkg.version ?? "0.0.0";
35731
36537
  } catch {
@@ -35744,25 +36550,25 @@ var init_ensure_config = __esm({
35744
36550
  // packages/core/src/store/exodus/archive.ts
35745
36551
  import {
35746
36552
  copyFileSync as copyFileSync2,
35747
- existsSync as existsSync5,
35748
- mkdirSync,
36553
+ existsSync as existsSync6,
36554
+ mkdirSync as mkdirSync2,
35749
36555
  renameSync,
35750
36556
  unlinkSync,
35751
- writeFileSync
36557
+ writeFileSync as writeFileSync2
35752
36558
  } from "node:fs";
35753
- import { basename as basename3, join as join9 } from "node:path";
36559
+ import { basename as basename3, join as join11 } from "node:path";
35754
36560
  function scopeBaseDir(scope, cwd) {
35755
36561
  return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
35756
36562
  }
35757
36563
  function exodusArchiveDir(scope, cwd) {
35758
- return join9(scopeBaseDir(scope, cwd), ARCHIVE_DIR_NAME);
36564
+ return join11(scopeBaseDir(scope, cwd), ARCHIVE_DIR_NAME);
35759
36565
  }
35760
36566
  function exodusMarkerPath(scope, cwd) {
35761
- return join9(scopeBaseDir(scope, cwd), MARKER_FILENAME_BY_SCOPE[scope]);
36567
+ return join11(scopeBaseDir(scope, cwd), MARKER_FILENAME_BY_SCOPE[scope]);
35762
36568
  }
35763
36569
  function hasExodusCompleteMarker(scope, cwd) {
35764
36570
  try {
35765
- return existsSync5(exodusMarkerPath(scope, cwd));
36571
+ return existsSync6(exodusMarkerPath(scope, cwd));
35766
36572
  } catch {
35767
36573
  return false;
35768
36574
  }
@@ -35770,7 +36576,7 @@ function hasExodusCompleteMarker(scope, cwd) {
35770
36576
  function writeExodusCompleteMarker(scope, archivedSources, cwd) {
35771
36577
  const markerPath = exodusMarkerPath(scope, cwd);
35772
36578
  const baseDir = scopeBaseDir(scope, cwd);
35773
- mkdirSync(baseDir, { recursive: true });
36579
+ mkdirSync2(baseDir, { recursive: true });
35774
36580
  const marker16 = {
35775
36581
  version: 1,
35776
36582
  scope,
@@ -35779,17 +36585,17 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd) {
35779
36585
  archivedSources: [...archivedSources]
35780
36586
  };
35781
36587
  const tmpPath = `${markerPath}.tmp`;
35782
- writeFileSync(tmpPath, JSON.stringify(marker16, null, 2) + "\n", "utf8");
36588
+ writeFileSync2(tmpPath, JSON.stringify(marker16, null, 2) + "\n", "utf8");
35783
36589
  renameSync(tmpPath, markerPath);
35784
- log2.info({ scope, markerPath, archivedSources }, "exodus: wrote completion marker");
36590
+ log3.info({ scope, markerPath, archivedSources }, "exodus: wrote completion marker");
35785
36591
  return markerPath;
35786
36592
  }
35787
36593
  function moveFileInto(srcPath, destDir) {
35788
- mkdirSync(destDir, { recursive: true });
35789
- let dest = join9(destDir, basename3(srcPath));
35790
- if (existsSync5(dest)) {
36594
+ mkdirSync2(destDir, { recursive: true });
36595
+ let dest = join11(destDir, basename3(srcPath));
36596
+ if (existsSync6(dest)) {
35791
36597
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
35792
- dest = join9(destDir, `${basename3(srcPath)}.${stamp}`);
36598
+ dest = join11(destDir, `${basename3(srcPath)}.${stamp}`);
35793
36599
  }
35794
36600
  try {
35795
36601
  renameSync(srcPath, dest);
@@ -35800,25 +36606,25 @@ function moveFileInto(srcPath, destDir) {
35800
36606
  return dest;
35801
36607
  }
35802
36608
  function archiveSourceDb(source, cwd) {
35803
- if (!existsSync5(source.path)) {
36609
+ if (!existsSync6(source.path)) {
35804
36610
  return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
35805
36611
  }
35806
36612
  const destDir = exodusArchiveDir(source.targetScope, cwd);
35807
36613
  const archivedTo = moveFileInto(source.path, destDir);
35808
36614
  for (const suffix of SIDECAR_SUFFIXES) {
35809
36615
  const sidecar = `${source.path}${suffix}`;
35810
- if (existsSync5(sidecar)) {
36616
+ if (existsSync6(sidecar)) {
35811
36617
  try {
35812
36618
  moveFileInto(sidecar, destDir);
35813
36619
  } catch (err) {
35814
- log2.warn(
36620
+ log3.warn(
35815
36621
  { err, sidecar, sourceName: source.name },
35816
36622
  "exodus-archive: failed to archive sidecar (non-fatal)"
35817
36623
  );
35818
36624
  }
35819
36625
  }
35820
36626
  }
35821
- log2.info(
36627
+ log3.info(
35822
36628
  { sourceName: source.name, sourcePath: source.path, archivedTo, scope: source.targetScope },
35823
36629
  "exodus-archive: archived legacy source DB"
35824
36630
  );
@@ -35853,7 +36659,7 @@ function detectStrandedResidue(sources, cwd) {
35853
36659
  const stranded = [];
35854
36660
  for (const source of sources) {
35855
36661
  if (!markedScopes.has(source.targetScope)) continue;
35856
- if (existsSync5(source.path)) {
36662
+ if (existsSync6(source.path)) {
35857
36663
  stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
35858
36664
  }
35859
36665
  }
@@ -35869,14 +36675,14 @@ function archiveStrandedResidue(stranded, sources, cwd) {
35869
36675
  }
35870
36676
  return results;
35871
36677
  }
35872
- var log2, ARCHIVE_DIR_NAME, MARKER_FILENAME_BY_SCOPE, SIDECAR_SUFFIXES;
36678
+ var log3, ARCHIVE_DIR_NAME, MARKER_FILENAME_BY_SCOPE, SIDECAR_SUFFIXES;
35873
36679
  var init_archive2 = __esm({
35874
36680
  "packages/core/src/store/exodus/archive.ts"() {
35875
36681
  "use strict";
35876
36682
  init_logger();
35877
36683
  init_paths();
35878
36684
  init_ensure_config();
35879
- log2 = getLogger("exodus-archive");
36685
+ log3 = getLogger("exodus-archive");
35880
36686
  ARCHIVE_DIR_NAME = "_archive";
35881
36687
  MARKER_FILENAME_BY_SCOPE = {
35882
36688
  project: "exodus-complete",
@@ -36270,7 +37076,7 @@ var init_table_name_map = __esm({
36270
37076
  });
36271
37077
 
36272
37078
  // packages/core/src/store/exodus/count-parity.ts
36273
- import { existsSync as existsSync6 } from "node:fs";
37079
+ import { existsSync as existsSync7 } from "node:fs";
36274
37080
  function listTables(db) {
36275
37081
  return db.prepare(
36276
37082
  "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
@@ -36291,14 +37097,14 @@ function rowCount(db, tableName) {
36291
37097
  function computeCountParity(sources, projectDbPath, globalDbPath) {
36292
37098
  const entries = [];
36293
37099
  let skipped = 0;
36294
- if (!existsSync6(projectDbPath) || !existsSync6(globalDbPath)) {
37100
+ if (!existsSync7(projectDbPath) || !existsSync7(globalDbPath)) {
36295
37101
  return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
36296
37102
  }
36297
37103
  const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
36298
37104
  const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
36299
37105
  try {
36300
37106
  for (const src of sources) {
36301
- if (!existsSync6(src.path)) continue;
37107
+ if (!existsSync7(src.path)) continue;
36302
37108
  const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
36303
37109
  try {
36304
37110
  for (const legacyTable of listTables(srcSnap.db)) {
@@ -36337,27 +37143,27 @@ function computeCountParity(sources, projectDbPath, globalDbPath) {
36337
37143
  }
36338
37144
  const deficits = entries.filter((e) => e.deficit > 0);
36339
37145
  if (deficits.length > 0) {
36340
- log3.warn(
37146
+ log4.warn(
36341
37147
  { deficitCount: deficits.length, sample: deficits.slice(0, 5) },
36342
37148
  `exodus count-parity: ${deficits.length} table(s) have FEWER rows in the consolidated target than the legacy source`
36343
37149
  );
36344
37150
  }
36345
37151
  return { ok: deficits.length === 0, entries, deficits, checked: entries.length, skipped };
36346
37152
  }
36347
- var log3;
37153
+ var log4;
36348
37154
  var init_count_parity = __esm({
36349
37155
  "packages/core/src/store/exodus/count-parity.ts"() {
36350
37156
  "use strict";
36351
37157
  init_logger();
36352
37158
  init_open_cleo_db();
36353
37159
  init_table_name_map();
36354
- log3 = getLogger("exodus-count-parity");
37160
+ log4 = getLogger("exodus-count-parity");
36355
37161
  }
36356
37162
  });
36357
37163
 
36358
37164
  // packages/core/src/store/exodus/plan.ts
36359
- import { existsSync as existsSync7, readdirSync as readdirSync2, statfsSync, statSync } from "node:fs";
36360
- import { join as join10 } from "node:path";
37165
+ import { existsSync as existsSync8, readdirSync as readdirSync3, statfsSync, statSync } from "node:fs";
37166
+ import { join as join12 } from "node:path";
36361
37167
  function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
36362
37168
  return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
36363
37169
  }
@@ -36368,33 +37174,33 @@ function buildSourceDescriptors(cwd) {
36368
37174
  // Project-tier — go into consolidated project-scope cleo.db
36369
37175
  {
36370
37176
  name: "tasks",
36371
- path: join10(cleoDir, "tasks.db"),
37177
+ path: join12(cleoDir, "tasks.db"),
36372
37178
  targetScope: "project"
36373
37179
  },
36374
37180
  {
36375
37181
  name: "brain (project)",
36376
- path: join10(cleoDir, "brain.db"),
37182
+ path: join12(cleoDir, "brain.db"),
36377
37183
  targetScope: "project"
36378
37184
  },
36379
37185
  {
36380
37186
  name: "conduit",
36381
- path: join10(cleoDir, "conduit.db"),
37187
+ path: join12(cleoDir, "conduit.db"),
36382
37188
  targetScope: "project"
36383
37189
  },
36384
37190
  // Global-tier — go into consolidated global-scope cleo.db
36385
37191
  {
36386
37192
  name: "nexus",
36387
- path: join10(cleoHome, "nexus.db"),
37193
+ path: join12(cleoHome, "nexus.db"),
36388
37194
  targetScope: "global"
36389
37195
  },
36390
37196
  {
36391
37197
  name: "signaldock",
36392
- path: join10(cleoHome, "signaldock.db"),
37198
+ path: join12(cleoHome, "signaldock.db"),
36393
37199
  targetScope: "global"
36394
37200
  },
36395
37201
  {
36396
37202
  name: "skills",
36397
- path: join10(cleoHome, "skills.db"),
37203
+ path: join12(cleoHome, "skills.db"),
36398
37204
  targetScope: "global"
36399
37205
  }
36400
37206
  ];
@@ -36420,10 +37226,10 @@ function deriveStagingDirName() {
36420
37226
  }
36421
37227
  function findExistingStaging(cleoDir) {
36422
37228
  try {
36423
- const entries = readdirSync2(cleoDir, { withFileTypes: true });
37229
+ const entries = readdirSync3(cleoDir, { withFileTypes: true });
36424
37230
  const stagingDirs = entries.filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => e.name).sort().reverse();
36425
37231
  if (stagingDirs.length > 0) {
36426
- return join10(cleoDir, stagingDirs[0]);
37232
+ return join12(cleoDir, stagingDirs[0]);
36427
37233
  }
36428
37234
  } catch {
36429
37235
  }
@@ -36439,7 +37245,7 @@ function buildExodusPlan(cwd) {
36439
37245
  const availableBytes = getAvailableBytes(cleoDir);
36440
37246
  const diskPreflight = totalSourceBytes === 0 || availableBytes >= requiredBytes;
36441
37247
  const existingStaging = findExistingStaging(cleoDir);
36442
- const stagingDir = existingStaging ?? join10(cleoDir, deriveStagingDirName());
37248
+ const stagingDir = existingStaging ?? join12(cleoDir, deriveStagingDirName());
36443
37249
  const resumeFromStaging = existingStaging !== null;
36444
37250
  const projectDbPath = resolveDualScopeDbPath("project", cwd);
36445
37251
  const globalDbPath = resolveDualScopeDbPath("global");
@@ -36458,7 +37264,7 @@ function buildExodusPlan(cwd) {
36458
37264
  };
36459
37265
  }
36460
37266
  function sourcesPresent(sources) {
36461
- return sources.some((s) => existsSync7(s.path));
37267
+ return sources.some((s) => existsSync8(s.path));
36462
37268
  }
36463
37269
  var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
36464
37270
  var init_plan2 = __esm({
@@ -36472,18 +37278,18 @@ var init_plan2 = __esm({
36472
37278
  });
36473
37279
 
36474
37280
  // packages/core/src/store/exodus/health.ts
36475
- import { existsSync as existsSync8, statSync as statSync2 } from "node:fs";
37281
+ import { existsSync as existsSync9, statSync as statSync2 } from "node:fs";
36476
37282
  function buildExodusHealth(cwd) {
36477
37283
  const plan = buildExodusPlan(cwd);
36478
- const anyLegacyPresent = plan.sources.some((s) => existsSync8(s.path));
37284
+ const anyLegacyPresent = plan.sources.some((s) => existsSync9(s.path));
36479
37285
  const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
36480
37286
  const consolidatedExistsByScope = {
36481
- project: existsSync8(plan.projectDbPath),
36482
- global: existsSync8(plan.globalDbPath)
37287
+ project: existsSync9(plan.projectDbPath),
37288
+ global: existsSync9(plan.globalDbPath)
36483
37289
  };
36484
37290
  const buildScope = (scope) => {
36485
37291
  const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
36486
- const present = existsSync8(s.path);
37292
+ const present = existsSync9(s.path);
36487
37293
  let bytes = 0;
36488
37294
  if (present) {
36489
37295
  try {
@@ -36750,15 +37556,15 @@ var init_types = __esm({
36750
37556
  // packages/core/src/store/exodus/migrate.ts
36751
37557
  import {
36752
37558
  copyFileSync as copyFileSync3,
36753
- existsSync as existsSync9,
36754
- mkdirSync as mkdirSync2,
37559
+ existsSync as existsSync10,
37560
+ mkdirSync as mkdirSync3,
36755
37561
  readFileSync as readFileSync3,
36756
37562
  renameSync as renameSync2,
36757
37563
  statSync as statSync3,
36758
37564
  unlinkSync as unlinkSync2,
36759
- writeFileSync as writeFileSync2
37565
+ writeFileSync as writeFileSync3
36760
37566
  } from "node:fs";
36761
- import { join as join11 } from "node:path";
37567
+ import { join as join13 } from "node:path";
36762
37568
  function getSqliteVersion(db) {
36763
37569
  try {
36764
37570
  const row = db.prepare("SELECT sqlite_version() AS v").get();
@@ -36774,14 +37580,14 @@ function listTables2(db) {
36774
37580
  return rows.map((r) => r.name);
36775
37581
  }
36776
37582
  function writeJournal(stagingDir, journal) {
36777
- const journalPath = join11(stagingDir, JOURNAL_FILENAME);
37583
+ const journalPath = join13(stagingDir, JOURNAL_FILENAME);
36778
37584
  const tmpPath = `${journalPath}.tmp`;
36779
- writeFileSync2(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
37585
+ writeFileSync3(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
36780
37586
  renameSync2(tmpPath, journalPath);
36781
37587
  }
36782
37588
  function readJournal(stagingDir) {
36783
- const journalPath = join11(stagingDir, JOURNAL_FILENAME);
36784
- if (!existsSync9(journalPath)) return null;
37589
+ const journalPath = join13(stagingDir, JOURNAL_FILENAME);
37590
+ if (!existsSync10(journalPath)) return null;
36785
37591
  try {
36786
37592
  return JSON.parse(readFileSync3(journalPath, "utf8"));
36787
37593
  } catch {
@@ -36789,17 +37595,17 @@ function readJournal(stagingDir) {
36789
37595
  }
36790
37596
  }
36791
37597
  function clearExodusJournal(stagingDir) {
36792
- const journalPath = join11(stagingDir, JOURNAL_FILENAME);
37598
+ const journalPath = join13(stagingDir, JOURNAL_FILENAME);
36793
37599
  try {
36794
- if (!existsSync9(journalPath)) return false;
37600
+ if (!existsSync10(journalPath)) return false;
36795
37601
  unlinkSync2(journalPath);
36796
- log4.info(
37602
+ log5.info(
36797
37603
  { stagingDir },
36798
37604
  "exodus: cleared migrate journal after abort/rollback \u2014 a retry will RE-COPY all tables"
36799
37605
  );
36800
37606
  return true;
36801
37607
  } catch (err) {
36802
- log4.warn(
37608
+ log5.warn(
36803
37609
  { err, stagingDir },
36804
37610
  'exodus: failed to clear migrate journal after rollback (a retry may skip already-"done" tables)'
36805
37611
  );
@@ -36824,7 +37630,7 @@ function lockPath(dbPath) {
36824
37630
  }
36825
37631
  function acquireAdvisoryLock(dbPath) {
36826
37632
  const lp = lockPath(dbPath);
36827
- writeFileSync2(lp, JSON.stringify({ pid: process.pid, ts: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
37633
+ writeFileSync3(lp, JSON.stringify({ pid: process.pid, ts: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
36828
37634
  }
36829
37635
  function releaseAdvisoryLock(dbPath) {
36830
37636
  try {
@@ -36887,7 +37693,7 @@ function buildSelectExpr(attachAlias, legacyTable, targetTableName, col, srcType
36887
37693
  function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyTableName, sourceName, targetSchema = "main") {
36888
37694
  const resolution = resolveConsolidatedTableName(sourceName, legacyTableName);
36889
37695
  if (resolution.kind === "skip") {
36890
- log4.warn(
37696
+ log5.warn(
36891
37697
  { legacyTableName, sourceName, reason: resolution.reason },
36892
37698
  `Exodus: explicitly skipping table \u2014 ${resolution.reason}`
36893
37699
  );
@@ -36906,7 +37712,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36906
37712
  ).get();
36907
37713
  if (!existsRow) {
36908
37714
  const reason = `consolidated target '${targetTableName}' not found (mapped from legacy '${legacyTableName}')`;
36909
- log4.warn(
37715
+ log5.warn(
36910
37716
  { legacyTableName, targetTableName, sourceName, attachAlias, targetSchema },
36911
37717
  `Exodus: ${reason}`
36912
37718
  );
@@ -36917,13 +37723,13 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36917
37723
  const sharedColumns = srcPragma.map((r) => r.name).filter((col) => tgtColMap.has(col));
36918
37724
  if (sharedColumns.length === 0) {
36919
37725
  const reason = `no overlapping columns between source '${legacyTableName}' and target '${targetTableName}'`;
36920
- log4.warn({ legacyTableName, targetTableName, sourceName }, `Exodus: ${reason}`);
37726
+ log5.warn({ legacyTableName, targetTableName, sourceName }, `Exodus: ${reason}`);
36921
37727
  return { rowsCopied: 0, skipped: true, reason };
36922
37728
  }
36923
37729
  const srcOnlyColumns = srcPragma.map((r) => r.name).filter((c) => !tgtColMap.has(c));
36924
37730
  const tgtOnlyColumns = tgtPragma.map((r) => r.name).filter((c) => !srcColumns.has(c));
36925
37731
  if (srcOnlyColumns.length > 0 || tgtOnlyColumns.length > 0) {
36926
- log4.info(
37732
+ log5.info(
36927
37733
  { legacyTableName, targetTableName, sourceName, srcOnlyColumns, tgtOnlyColumns },
36928
37734
  "Exodus: column drift detected \u2014 copying intersection, dropping src-only cols, using defaults for tgt-only cols"
36929
37735
  );
@@ -36938,7 +37744,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36938
37744
  return isoGlobCols.has(col) && (upper.includes("INT") || upper === "" || upper === "NUMERIC");
36939
37745
  });
36940
37746
  if (coercedCols.length > 0) {
36941
- log4.info(
37747
+ log5.info(
36942
37748
  {
36943
37749
  legacyTableName,
36944
37750
  targetTableName,
@@ -36954,7 +37760,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36954
37760
  (col) => ENUM_NORMALIZATIONS.has(`${targetTableName}.${col}`)
36955
37761
  );
36956
37762
  if (normalizedCols.length > 0) {
36957
- log4.info(
37763
+ log5.info(
36958
37764
  { legacyTableName, targetTableName, sourceName, normalizedCols },
36959
37765
  `Exodus: applying enum-value normalization for ${normalizedCols.length} column(s) (T11547)`
36960
37766
  );
@@ -36963,7 +37769,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
36963
37769
  (col) => NUMERIC_CLAMPS.has(`${targetTableName}.${col}`)
36964
37770
  );
36965
37771
  if (clampedCols.length > 0) {
36966
- log4.info(
37772
+ log5.info(
36967
37773
  { legacyTableName, targetTableName, sourceName, clampedCols },
36968
37774
  `Exodus: applying non-finite numeric clamp for ${clampedCols.length} column(s) (T11782)`
36969
37775
  );
@@ -37005,7 +37811,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
37005
37811
  if (rowsCopied < sourceCount) {
37006
37812
  const presentAccountedFor = existingBefore + rowsCopied;
37007
37813
  if (presentAccountedFor >= sourceCount) {
37008
- log4.info(
37814
+ log5.info(
37009
37815
  { legacyTableName, targetTableName, sourceName, sourceCount, rowsCopied, existingBefore },
37010
37816
  `Exodus: '${legacyTableName}'\u2192'${targetTableName}' \u2014 ${sourceCount - rowsCopied} of ${sourceCount} row(s) already present in target (idempotent PK dedup), ${rowsCopied} newly copied; no loss`
37011
37817
  );
@@ -37013,7 +37819,7 @@ function copyTableFromAttached(targetNativeDb, srcNativeDb, attachAlias, legacyT
37013
37819
  }
37014
37820
  const missing = sourceCount - presentAccountedFor;
37015
37821
  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.`;
37016
- log4.error(
37822
+ log5.error(
37017
37823
  {
37018
37824
  legacyTableName,
37019
37825
  targetTableName,
@@ -37033,10 +37839,10 @@ function checkSchemaVersion(journal, forceCrossVersion) {
37033
37839
  if (journal.targetSchemaVersion !== EXODUS_TARGET_SCHEMA_VERSION) {
37034
37840
  const msg = `Schema version mismatch: journal=${journal.targetSchemaVersion}, expected=${EXODUS_TARGET_SCHEMA_VERSION}`;
37035
37841
  if (forceCrossVersion) {
37036
- log4.warn(msg + " (--force-cross-version: continuing anyway)");
37842
+ log5.warn(msg + " (--force-cross-version: continuing anyway)");
37037
37843
  return true;
37038
37844
  }
37039
- log4.error(msg + " \u2014 pass --force-cross-version to override");
37845
+ log5.error(msg + " \u2014 pass --force-cross-version to override");
37040
37846
  return false;
37041
37847
  }
37042
37848
  return true;
@@ -37053,10 +37859,10 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
37053
37859
  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.`
37054
37860
  };
37055
37861
  }
37056
- mkdirSync2(stagingDir, { recursive: true });
37862
+ mkdirSync3(stagingDir, { recursive: true });
37057
37863
  let sqliteVersion = "unknown";
37058
37864
  for (const src of sources) {
37059
- if (existsSync9(src.path)) {
37865
+ if (existsSync10(src.path)) {
37060
37866
  const snap = openCleoDbSnapshot(src.path, { readOnly: true });
37061
37867
  sqliteVersion = getSqliteVersion(snap.db);
37062
37868
  snap.close();
@@ -37097,15 +37903,15 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
37097
37903
  };
37098
37904
  var extractNativeDb = extractNativeDb2;
37099
37905
  for (const src of sources) {
37100
- if (!existsSync9(src.path)) continue;
37101
- const backupDest = join11(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
37906
+ if (!existsSync10(src.path)) continue;
37907
+ const backupDest = join13(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
37102
37908
  const srcBytes = safeStatBytes(src.path);
37103
37909
  const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
37104
37910
  if (skipStagingCopy) {
37105
37911
  onProgress?.(
37106
37912
  `Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
37107
37913
  );
37108
- } else if (!existsSync9(backupDest)) {
37914
+ } else if (!existsSync10(backupDest)) {
37109
37915
  onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
37110
37916
  copyFileSync3(src.path, backupDest);
37111
37917
  backupPaths.push(backupDest);
@@ -37123,8 +37929,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
37123
37929
  });
37124
37930
  const projectNative = extractNativeDb2(projectHandle);
37125
37931
  const globalNative = extractNativeDb2(globalHandle);
37126
- const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync9(s.path));
37127
- const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync9(s.path));
37932
+ const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync10(s.path));
37933
+ const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync10(s.path));
37128
37934
  await migrateScope(
37129
37935
  "project",
37130
37936
  projectSources,
@@ -37149,7 +37955,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress) {
37149
37955
  return { ok: true, tables: allTableResults, stagingDir, backupPaths };
37150
37956
  } catch (err) {
37151
37957
  const error48 = err instanceof Error ? err.message : String(err);
37152
- log4.error({ err }, "Exodus migration failed");
37958
+ log5.error({ err }, "Exodus migration failed");
37153
37959
  return { ok: false, tables: allTableResults, stagingDir, backupPaths, error: error48 };
37154
37960
  } finally {
37155
37961
  try {
@@ -37169,7 +37975,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37169
37975
  if (sources.length === 0) return;
37170
37976
  onProgress?.(`Migrating ${scope}-scope sources\u2026`);
37171
37977
  targetNativeDb.exec("PRAGMA foreign_keys = OFF");
37172
- log4.info({ scope }, "Exodus: foreign_keys=OFF for bulk copy (T11533 FK-defer)");
37978
+ log5.info({ scope }, "Exodus: foreign_keys=OFF for bulk copy (T11533 FK-defer)");
37173
37979
  try {
37174
37980
  for (let i = 0; i < sources.length; i++) {
37175
37981
  const src = sources[i];
@@ -37236,7 +38042,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37236
38042
  }
37237
38043
  } catch (err) {
37238
38044
  const msg = err instanceof Error ? err.message : String(err);
37239
- log4.warn({ tableName, sourceDb: src.name, err }, "Table copy failed \u2014 skipping");
38045
+ log5.warn({ tableName, sourceDb: src.name, err }, "Table copy failed \u2014 skipping");
37240
38046
  status = "skipped";
37241
38047
  errorMsg = msg;
37242
38048
  skipped = true;
@@ -37284,7 +38090,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37284
38090
  targetNativeDb.exec(`DETACH DATABASE "${attachAlias}"`);
37285
38091
  onProgress?.(` [${src.name}] Detached "${attachAlias}"`);
37286
38092
  } catch (detachErr) {
37287
- log4.warn(
38093
+ log5.warn(
37288
38094
  { attachAlias, sourceDb: src.name, err: detachErr },
37289
38095
  "DETACH failed \u2014 alias will be released on DB close"
37290
38096
  );
@@ -37294,7 +38100,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37294
38100
  targetNativeDb.exec(`DETACH DATABASE "${crossAlias}"`);
37295
38101
  onProgress?.(` [${src.name}] Cross-scope target detached "${crossAlias}"`);
37296
38102
  } catch (detachErr) {
37297
- log4.warn(
38103
+ log5.warn(
37298
38104
  { crossAlias, sourceDb: src.name, err: detachErr },
37299
38105
  "Cross-scope DETACH failed \u2014 alias will be released on DB close"
37300
38106
  );
@@ -37306,28 +38112,28 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
37306
38112
  try {
37307
38113
  const orphans = targetNativeDb.prepare("PRAGMA foreign_key_check").all();
37308
38114
  if (orphans.length > 0) {
37309
- log4.warn(
38115
+ log5.warn(
37310
38116
  { scope, orphanCount: orphans.length, sample: orphans.slice(0, 5) },
37311
38117
  `Exodus: PRAGMA foreign_key_check found ${orphans.length} orphan row(s) after bulk copy \u2014 these are genuine data orphans (not ordering artifacts)`
37312
38118
  );
37313
38119
  } else {
37314
- log4.info({ scope }, "Exodus: PRAGMA foreign_key_check PASSED \u2014 no orphan rows");
38120
+ log5.info({ scope }, "Exodus: PRAGMA foreign_key_check PASSED \u2014 no orphan rows");
37315
38121
  }
37316
38122
  } catch (checkErr) {
37317
- log4.warn(
38123
+ log5.warn(
37318
38124
  { scope, err: checkErr },
37319
38125
  "Exodus: PRAGMA foreign_key_check failed (non-fatal) \u2014 target schema may not have FK constraints enabled"
37320
38126
  );
37321
38127
  }
37322
38128
  try {
37323
38129
  targetNativeDb.exec("PRAGMA foreign_keys = ON");
37324
- log4.info({ scope }, "Exodus: foreign_keys=ON restored after bulk copy");
38130
+ log5.info({ scope }, "Exodus: foreign_keys=ON restored after bulk copy");
37325
38131
  } catch (fkErr) {
37326
- log4.warn({ scope, err: fkErr }, "Exodus: could not restore foreign_keys=ON (non-fatal)");
38132
+ log5.warn({ scope, err: fkErr }, "Exodus: could not restore foreign_keys=ON (non-fatal)");
37327
38133
  }
37328
38134
  }
37329
38135
  }
37330
- var log4, LOCK_SENTINEL_SUFFIX, JOURNAL_FILENAME, SOURCE_EPOCH_UNITS;
38136
+ var log5, LOCK_SENTINEL_SUFFIX, JOURNAL_FILENAME, SOURCE_EPOCH_UNITS;
37331
38137
  var init_migrate = __esm({
37332
38138
  "packages/core/src/store/exodus/migrate.ts"() {
37333
38139
  "use strict";
@@ -37339,7 +38145,7 @@ var init_migrate = __esm({
37339
38145
  init_plan2();
37340
38146
  init_table_name_map();
37341
38147
  init_types();
37342
- log4 = getLogger("exodus-migrate");
38148
+ log5 = getLogger("exodus-migrate");
37343
38149
  LOCK_SENTINEL_SUFFIX = ".exodus-lock";
37344
38150
  JOURNAL_FILENAME = "exodus-journal.json";
37345
38151
  SOURCE_EPOCH_UNITS = /* @__PURE__ */ new Map([
@@ -37363,7 +38169,7 @@ function sealExodus(plan, scopeArg, cwd) {
37363
38169
  const parity = computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath);
37364
38170
  if (!parity.ok) {
37365
38171
  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(", ")}`;
37366
- log5.error({ deficits: parity.deficits.length }, `exodus seal refused \u2014 ${refusedReason}`);
38172
+ log6.error({ deficits: parity.deficits.length }, `exodus seal refused \u2014 ${refusedReason}`);
37367
38173
  return { ok: false, refusedReason, parity, scopes: [] };
37368
38174
  }
37369
38175
  const outcomes = [];
@@ -37379,7 +38185,7 @@ function sealExodus(plan, scopeArg, cwd) {
37379
38185
  scopeSources.map((s) => s.name),
37380
38186
  cwd
37381
38187
  );
37382
- log5.info(
38188
+ log6.info(
37383
38189
  { scope, alreadySealed, archived: archived.filter((a) => a.action === "archived").length },
37384
38190
  `exodus seal: scope '${scope}' certified (count-parity verified, ${parity.checked} tables)`
37385
38191
  );
@@ -37387,23 +38193,23 @@ function sealExodus(plan, scopeArg, cwd) {
37387
38193
  }
37388
38194
  return { ok: true, parity, scopes: outcomes };
37389
38195
  }
37390
- var log5;
38196
+ var log6;
37391
38197
  var init_seal = __esm({
37392
38198
  "packages/core/src/store/exodus/seal.ts"() {
37393
38199
  "use strict";
37394
38200
  init_logger();
37395
38201
  init_archive2();
37396
38202
  init_count_parity();
37397
- log5 = getLogger("exodus-seal");
38203
+ log6 = getLogger("exodus-seal");
37398
38204
  }
37399
38205
  });
37400
38206
 
37401
38207
  // packages/core/src/store/exodus/status.ts
37402
- import { existsSync as existsSync10, readdirSync as readdirSync3, readFileSync as readFileSync4, statSync as statSync4 } from "node:fs";
37403
- import { join as join12 } from "node:path";
38208
+ import { existsSync as existsSync11, readdirSync as readdirSync4, readFileSync as readFileSync4, statSync as statSync4 } from "node:fs";
38209
+ import { join as join14 } from "node:path";
37404
38210
  function readJournal2(stagingDir) {
37405
- const p = join12(stagingDir, JOURNAL_FILENAME2);
37406
- if (!existsSync10(p)) return null;
38211
+ const p = join14(stagingDir, JOURNAL_FILENAME2);
38212
+ if (!existsSync11(p)) return null;
37407
38213
  try {
37408
38214
  return JSON.parse(readFileSync4(p, "utf8"));
37409
38215
  } catch {
@@ -37412,7 +38218,7 @@ function readJournal2(stagingDir) {
37412
38218
  }
37413
38219
  function findStagingDirs(cleoDir) {
37414
38220
  try {
37415
- return readdirSync3(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join12(cleoDir, e.name)).sort().reverse();
38221
+ return readdirSync4(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join14(cleoDir, e.name)).sort().reverse();
37416
38222
  } catch {
37417
38223
  return [];
37418
38224
  }
@@ -37435,15 +38241,15 @@ function runExodusStatus(cwd) {
37435
38241
  const sourcesInfo = plan.sources.map((s) => ({
37436
38242
  name: s.name,
37437
38243
  path: s.path,
37438
- exists: existsSync10(s.path),
38244
+ exists: existsSync11(s.path),
37439
38245
  bytes: safeBytes(s.path)
37440
38246
  }));
37441
38247
  return {
37442
38248
  hasStaging: latestStaging !== null,
37443
38249
  stagingDir: latestStaging,
37444
38250
  journal,
37445
- projectDbExists: existsSync10(projectDbPath),
37446
- globalDbExists: existsSync10(globalDbPath),
38251
+ projectDbExists: existsSync11(projectDbPath),
38252
+ globalDbExists: existsSync11(globalDbPath),
37447
38253
  sourcesPresent: sourcesInfo.some((s) => s.exists),
37448
38254
  sources: sourcesInfo
37449
38255
  };
@@ -37460,7 +38266,7 @@ var init_status = __esm({
37460
38266
  });
37461
38267
 
37462
38268
  // packages/core/src/store/exodus/verify-migration.ts
37463
- import { existsSync as existsSync11 } from "node:fs";
38269
+ import { existsSync as existsSync12 } from "node:fs";
37464
38270
  import { createRequire as createRequire3 } from "node:module";
37465
38271
  function orderByClause(db, tableName) {
37466
38272
  try {
@@ -37480,7 +38286,7 @@ function computeTableDigest(db, tableName, columns, transform2) {
37480
38286
  count = Number(row?.c ?? 0);
37481
38287
  } catch (err) {
37482
38288
  const msg = err instanceof Error ? err.message : String(err);
37483
- log6.warn(
38289
+ log7.warn(
37484
38290
  { tableName, err: msg },
37485
38291
  "computeTableDigest: COUNT(*) failed (possibly a virtual/FTS table) \u2014 treating as 0 rows"
37486
38292
  );
@@ -37515,7 +38321,7 @@ function computeTableDigest(db, tableName, columns, transform2) {
37515
38321
  }
37516
38322
  } catch (err) {
37517
38323
  const msg = err instanceof Error ? err.message : String(err);
37518
- log6.warn(
38324
+ log7.warn(
37519
38325
  { tableName, err: msg },
37520
38326
  "computeTableDigest: streamed SELECT failed (possibly a virtual/FTS table) \u2014 digest skipped (COUNT(*) parity still enforced)"
37521
38327
  );
@@ -37641,7 +38447,7 @@ function foreignKeyCheck(db, scope) {
37641
38447
  try {
37642
38448
  const rows = db.prepare("PRAGMA foreign_key_check").all();
37643
38449
  if (rows.length > 0) {
37644
- log6.warn(
38450
+ log7.warn(
37645
38451
  { scope, count: rows.length, sample: rows.slice(0, 5) },
37646
38452
  `verifyMigration: PRAGMA foreign_key_check found ${rows.length} orphan row(s)`
37647
38453
  );
@@ -37653,7 +38459,7 @@ function foreignKeyCheck(db, scope) {
37653
38459
  fkid: r.fkid
37654
38460
  }));
37655
38461
  } catch (err) {
37656
- log6.warn({ scope, err }, "verifyMigration: PRAGMA foreign_key_check failed (non-fatal)");
38462
+ log7.warn({ scope, err }, "verifyMigration: PRAGMA foreign_key_check failed (non-fatal)");
37657
38463
  return [];
37658
38464
  }
37659
38465
  }
@@ -37690,13 +38496,13 @@ function sourceOrphanSignatures(db, sourceName, scope) {
37690
38496
  const rows = db.prepare("PRAGMA foreign_key_check").all();
37691
38497
  for (const r of rows) sigs.add(orphanSignature(db, r, sourceName));
37692
38498
  if (rows.length > 0) {
37693
- log6.warn(
38499
+ log7.warn(
37694
38500
  { scope, count: rows.length, sample: rows.slice(0, 5) },
37695
38501
  `verifyMigration: source already has ${rows.length} pre-existing FK orphan(s) \u2014 these are tolerated (carried forward losslessly, flagged for data-hygiene)`
37696
38502
  );
37697
38503
  }
37698
38504
  } catch (err) {
37699
- log6.warn({ scope, err }, "verifyMigration: source PRAGMA foreign_key_check failed (non-fatal)");
38505
+ log7.warn({ scope, err }, "verifyMigration: source PRAGMA foreign_key_check failed (non-fatal)");
37700
38506
  }
37701
38507
  return sigs;
37702
38508
  }
@@ -37708,7 +38514,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37708
38514
  const preExistingForeignKeyViolations = [];
37709
38515
  const failureLines = [];
37710
38516
  const sourceOrphanSigs = /* @__PURE__ */ new Set();
37711
- if (!existsSync11(projectDbPath)) {
38517
+ if (!existsSync12(projectDbPath)) {
37712
38518
  return {
37713
38519
  ok: false,
37714
38520
  tables: [],
@@ -37719,7 +38525,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37719
38525
  error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
37720
38526
  };
37721
38527
  }
37722
- if (!existsSync11(globalDbPath)) {
38528
+ if (!existsSync12(globalDbPath)) {
37723
38529
  return {
37724
38530
  ok: false,
37725
38531
  tables: [],
@@ -37734,7 +38540,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37734
38540
  const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
37735
38541
  try {
37736
38542
  for (const src of sources) {
37737
- if (!existsSync11(src.path)) {
38543
+ if (!existsSync12(src.path)) {
37738
38544
  onProgress?.(`Skipping ${src.name} (not present)`);
37739
38545
  continue;
37740
38546
  }
@@ -37819,7 +38625,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37819
38625
  `[${scope}] ${src.name}.${legacyTableName} \u2192 ${targetTableName}: DEFICIT \u2014 source=${srcDigest.count} rows, target=${tgtDigest.count} rows (${srcDigest.count - tgtDigest.count} missing), hashMatch=${hashMatch}`
37820
38626
  );
37821
38627
  } else if (tgtDigest.count > srcDigest.count) {
37822
- log6.warn(
38628
+ log7.warn(
37823
38629
  {
37824
38630
  scope,
37825
38631
  source: src.name,
@@ -37869,7 +38675,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37869
38675
  }
37870
38676
  }
37871
38677
  if (preExistingForeignKeyViolations.length > 0) {
37872
- log6.warn(
38678
+ log7.warn(
37873
38679
  {
37874
38680
  count: preExistingForeignKeyViolations.length,
37875
38681
  sample: preExistingForeignKeyViolations.slice(0, 5)
@@ -37879,7 +38685,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37879
38685
  }
37880
38686
  } catch (err) {
37881
38687
  const error48 = err instanceof Error ? err.message : String(err);
37882
- log6.error({ err }, "verifyMigration failed");
38688
+ log7.error({ err }, "verifyMigration failed");
37883
38689
  return {
37884
38690
  ok: false,
37885
38691
  tables,
@@ -37896,7 +38702,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
37896
38702
  if (failureLines.length > 0) {
37897
38703
  const error48 = `verifyMigration FAILED: ${failureLines.length} issue(s):
37898
38704
  ${failureLines.map((l) => ` \u2022 ${l}`).join("\n")}`;
37899
- log6.error({ failureCount: failureLines.length }, error48);
38705
+ log7.error({ failureCount: failureLines.length }, error48);
37900
38706
  return {
37901
38707
  ok: false,
37902
38708
  tables,
@@ -37916,7 +38722,7 @@ ${failureLines.map((l) => ` \u2022 ${l}`).join("\n")}`;
37916
38722
  enumDrift
37917
38723
  };
37918
38724
  }
37919
- var log6, _require, CHECK_ENUM_REGEX;
38725
+ var log7, _require, CHECK_ENUM_REGEX;
37920
38726
  var init_verify_migration = __esm({
37921
38727
  "packages/core/src/store/exodus/verify-migration.ts"() {
37922
38728
  "use strict";
@@ -37925,7 +38731,7 @@ var init_verify_migration = __esm({
37925
38731
  init_open_cleo_db();
37926
38732
  init_column_transforms();
37927
38733
  init_table_name_map();
37928
- log6 = getLogger("verify-migration");
38734
+ log7 = getLogger("verify-migration");
37929
38735
  _require = createRequire3(import.meta.url);
37930
38736
  CHECK_ENUM_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+(?:IS\s+NULL\s+OR\s+"[^"]+"\s+)?IN\s*\(([^)]*)\)\s*\)/gi;
37931
38737
  }
@@ -38017,7 +38823,7 @@ __export(on_open_exports, {
38017
38823
  isDataContinuityOk: () => isDataContinuityOk,
38018
38824
  maybeRunExodusOnOpen: () => maybeRunExodusOnOpen
38019
38825
  });
38020
- import { existsSync as existsSync12 } from "node:fs";
38826
+ import { existsSync as existsSync13 } from "node:fs";
38021
38827
  function isDisabledByEnv() {
38022
38828
  const v = process.env.CLEO_DISABLE_EXODUS_ON_OPEN;
38023
38829
  return v === "1" || v === "true";
@@ -38043,7 +38849,7 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
38043
38849
  "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%'"
38044
38850
  ).all().map((r) => r.name);
38045
38851
  } catch (err) {
38046
- log7.error({ err, scope }, "exodus-on-open: failed to enumerate tables for rollback");
38852
+ log8.error({ err, scope }, "exodus-on-open: failed to enumerate tables for rollback");
38047
38853
  return;
38048
38854
  }
38049
38855
  try {
@@ -38053,7 +38859,7 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
38053
38859
  try {
38054
38860
  nativeDb.exec(`DELETE FROM "${table}"`);
38055
38861
  } catch (err) {
38056
- log7.warn({ err, table, scope }, "exodus-on-open: failed to clear table during rollback");
38862
+ log8.warn({ err, table, scope }, "exodus-on-open: failed to clear table during rollback");
38057
38863
  }
38058
38864
  }
38059
38865
  nativeDb.exec("COMMIT");
@@ -38062,7 +38868,7 @@ function rollbackConsolidatedToEmpty(nativeDb, scope) {
38062
38868
  nativeDb.exec("ROLLBACK");
38063
38869
  } catch {
38064
38870
  }
38065
- log7.error({ err, scope }, "exodus-on-open: rollback transaction failed");
38871
+ log8.error({ err, scope }, "exodus-on-open: rollback transaction failed");
38066
38872
  } finally {
38067
38873
  try {
38068
38874
  nativeDb.exec("PRAGMA foreign_keys = ON");
@@ -38082,7 +38888,7 @@ async function rollbackBothScopes(scope, projectDbPath, globalDbPath) {
38082
38888
  rollbackConsolidatedToEmpty(native, s);
38083
38889
  }
38084
38890
  } catch (err) {
38085
- log7.warn(
38891
+ log8.warn(
38086
38892
  { err, scope: s, openingScope: scope },
38087
38893
  "exodus-on-open: could not roll back scope (best-effort)"
38088
38894
  );
@@ -38098,7 +38904,7 @@ function isDataContinuityOk(result) {
38098
38904
  const deficits = result.tables.filter((t) => t.targetCount < t.sourceCount);
38099
38905
  const surpluses = result.tables.filter((t) => t.targetCount > t.sourceCount);
38100
38906
  if (surpluses.length > 0) {
38101
- log7.warn(
38907
+ log8.warn(
38102
38908
  {
38103
38909
  surpluses: surpluses.map((t) => ({
38104
38910
  table: t.targetTable,
@@ -38132,7 +38938,7 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38132
38938
  const { buildExodusPlan: buildExodusPlan2, runExodusMigrate: runExodusMigrate2, verifyMigration: verifyMigration2, clearExodusJournal: clearExodusJournal2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
38133
38939
  const plan = buildExodusPlan2(cwd);
38134
38940
  const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
38135
- if (!scopeSources.some((s) => existsSync12(s.path))) {
38941
+ if (!scopeSources.some((s) => existsSync13(s.path))) {
38136
38942
  return {
38137
38943
  outcome: "skipped",
38138
38944
  reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
@@ -38145,11 +38951,11 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38145
38951
  if (!consolidatedIsEmpty(nativeDb, scope)) {
38146
38952
  return { outcome: "skipped", reason: "migrated by a concurrent process (lock winner)" };
38147
38953
  }
38148
- log7.info(
38954
+ log8.info(
38149
38955
  {
38150
38956
  scope,
38151
38957
  dbPath,
38152
- sources: plan.sources.filter((s) => existsSync12(s.path)).map((s) => s.name)
38958
+ sources: plan.sources.filter((s) => existsSync13(s.path)).map((s) => s.name)
38153
38959
  },
38154
38960
  "exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
38155
38961
  );
@@ -38158,23 +38964,23 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38158
38964
  const migrateResult = await runExodusMigrate2(
38159
38965
  plan,
38160
38966
  false,
38161
- (msg) => log7.debug({ scope }, `exodus-on-open: ${msg}`)
38967
+ (msg) => log8.debug({ scope }, `exodus-on-open: ${msg}`)
38162
38968
  );
38163
38969
  if (!migrateResult.ok) {
38164
38970
  await rollbackBothScopes(scope, plan.projectDbPath, plan.globalDbPath);
38165
38971
  clearExodusJournal2(migrateResult.stagingDir);
38166
38972
  const reason = `migration failed: ${migrateResult.error ?? "unknown error"} \u2014 legacy DBs kept as source`;
38167
- log7.error({ scope, error: migrateResult.error }, `exodus-on-open: ${reason}`);
38973
+ log8.error({ scope, error: migrateResult.error }, `exodus-on-open: ${reason}`);
38168
38974
  return { outcome: "aborted", reason };
38169
38975
  }
38170
38976
  const verifyResult = verifyMigration2(
38171
38977
  plan.sources,
38172
38978
  plan.projectDbPath,
38173
38979
  plan.globalDbPath,
38174
- (msg) => log7.debug({ scope }, `exodus-on-open verify: ${msg}`)
38980
+ (msg) => log8.debug({ scope }, `exodus-on-open verify: ${msg}`)
38175
38981
  );
38176
38982
  if (!verifyResult.ok) {
38177
- log7.warn(
38983
+ log8.warn(
38178
38984
  {
38179
38985
  scope,
38180
38986
  enumDrift: verifyResult.enumDrift.length,
@@ -38188,7 +38994,7 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38188
38994
  clearExodusJournal2(plan.stagingDir);
38189
38995
  const deficits = verifyResult.tables.filter((t) => t.targetCount < t.sourceCount).map((t) => `${t.targetTable}(${t.sourceCount}\u2192${t.targetCount})`);
38190
38996
  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();
38191
- log7.error(
38997
+ log8.error(
38192
38998
  {
38193
38999
  scope,
38194
39000
  countDeficits: deficits,
@@ -38200,14 +39006,14 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38200
39006
  return { outcome: "aborted", reason };
38201
39007
  }
38202
39008
  const rowsCopied = migrateResult.tables.filter((t) => !t.skipped).reduce((n, t) => n + t.rowsCopied, 0);
38203
- log7.info(
39009
+ log8.info(
38204
39010
  { scope, rowsCopied, tables: migrateResult.tables.length },
38205
39011
  "exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
38206
39012
  );
38207
39013
  try {
38208
- const consumed = plan.sources.filter((s) => existsSync12(s.path));
39014
+ const consumed = plan.sources.filter((s) => existsSync13(s.path));
38209
39015
  const archiveResult = archiveMigratedSources(consumed, cwd);
38210
- log7.info(
39016
+ log8.info(
38211
39017
  {
38212
39018
  scope,
38213
39019
  archived: archiveResult.sources.filter((s) => s.action === "archived").length,
@@ -38216,7 +39022,7 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38216
39022
  "exodus-on-open: archived legacy sources + sealed completion marker(s)"
38217
39023
  );
38218
39024
  } catch (err) {
38219
- log7.error(
39025
+ log8.error(
38220
39026
  { err, scope },
38221
39027
  "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`)"
38222
39028
  );
@@ -38238,14 +39044,14 @@ async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
38238
39044
  function _isExodusInProgress() {
38239
39045
  return _exodusInProgress;
38240
39046
  }
38241
- var log7, _exodusInProgress;
39047
+ var log8, _exodusInProgress;
38242
39048
  var init_on_open = __esm({
38243
39049
  "packages/core/src/store/exodus/on-open.ts"() {
38244
39050
  "use strict";
38245
39051
  init_logger();
38246
39052
  init_lock();
38247
39053
  init_archive2();
38248
- log7 = getLogger("exodus-on-open");
39054
+ log8 = getLogger("exodus-on-open");
38249
39055
  _exodusInProgress = false;
38250
39056
  }
38251
39057
  });
@@ -38262,9 +39068,9 @@ __export(dual_scope_db_exports, {
38262
39068
  resolveDualScopeDbPath: () => resolveDualScopeDbPath,
38263
39069
  upsertIdempotent: () => upsertIdempotent
38264
39070
  });
38265
- import { existsSync as existsSync13, mkdirSync as mkdirSync3 } from "node:fs";
39071
+ import { existsSync as existsSync14, mkdirSync as mkdirSync4 } from "node:fs";
38266
39072
  import { createRequire as createRequire4 } from "node:module";
38267
- import { dirname as dirname6, join as join13 } from "node:path";
39073
+ import { dirname as dirname6, join as join15 } from "node:path";
38268
39074
  function assertWriteDurable(handle) {
38269
39075
  if (handle.exodusAbort) {
38270
39076
  throw new ExodusAbortWriteUnsafeError(handle.exodusAbort);
@@ -38281,9 +39087,9 @@ function cacheKey(scope, dbPath) {
38281
39087
  }
38282
39088
  function resolveDualScopeDbPath(scope, cwd) {
38283
39089
  if (scope === "project") {
38284
- return join13(resolveCleoDir(cwd), "cleo.db");
39090
+ return join15(resolveCleoDir(cwd), "cleo.db");
38285
39091
  }
38286
- return join13(getCleoHome(), "cleo.db");
39092
+ return join15(getCleoHome(), "cleo.db");
38287
39093
  }
38288
39094
  function migrationsSetName(scope) {
38289
39095
  return scope === "project" ? "drizzle-cleo-project" : "drizzle-cleo-global";
@@ -38326,11 +39132,11 @@ async function openDualScopeDb(scope, cwd) {
38326
39132
  const dbPath = resolveDualScopeDbPath(scope, cwd);
38327
39133
  return scope === "project" ? openDualScopeDbAtPath("project", dbPath, cwd) : openDualScopeDbAtPath("global", dbPath, cwd);
38328
39134
  }
38329
- async function openDedicatedDualScopeDb(scope, dbPath, log8) {
38330
- log8.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
39135
+ async function openDedicatedDualScopeDb(scope, dbPath, log9) {
39136
+ log9.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
38331
39137
  const dir = dirname6(dbPath);
38332
- if (!existsSync13(dir)) {
38333
- mkdirSync3(dir, { recursive: true });
39138
+ if (!existsSync14(dir)) {
39139
+ mkdirSync4(dir, { recursive: true });
38334
39140
  }
38335
39141
  const DatabaseSyncCtor = getDatabaseSyncCtor();
38336
39142
  const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
@@ -38353,7 +39159,7 @@ async function openDedicatedDualScopeDb(scope, dbPath, log8) {
38353
39159
  existenceTable(scope),
38354
39160
  `dual-scope-db[${scope}]`
38355
39161
  );
38356
- log8.debug({ scope, dbPath }, "DEDICATED dual-scope cleo.db ready (T11782 FIX D)");
39162
+ log9.debug({ scope, dbPath }, "DEDICATED dual-scope cleo.db ready (T11782 FIX D)");
38357
39163
  return {
38358
39164
  db,
38359
39165
  scope,
@@ -38378,15 +39184,15 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38378
39184
  return existing.handle;
38379
39185
  }
38380
39186
  }
38381
- const log8 = getLogger("dual-scope-db");
39187
+ const log9 = getLogger("dual-scope-db");
38382
39188
  if (dedicated) {
38383
- return openDedicatedDualScopeDb(scope, dbPath, log8);
39189
+ return openDedicatedDualScopeDb(scope, dbPath, log9);
38384
39190
  }
38385
39191
  const initPromise = (async () => {
38386
- log8.debug({ scope, dbPath }, "opening dual-scope cleo.db");
39192
+ log9.debug({ scope, dbPath }, "opening dual-scope cleo.db");
38387
39193
  const dir = dirname6(dbPath);
38388
- if (!existsSync13(dir)) {
38389
- mkdirSync3(dir, { recursive: true });
39194
+ if (!existsSync14(dir)) {
39195
+ mkdirSync4(dir, { recursive: true });
38390
39196
  }
38391
39197
  const DatabaseSyncCtor = getDatabaseSyncCtor();
38392
39198
  const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
@@ -38413,7 +39219,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38413
39219
  existenceTable(scope),
38414
39220
  `dual-scope-db[${scope}]`
38415
39221
  );
38416
- log8.debug({ scope, dbPath }, "dual-scope cleo.db ready");
39222
+ log9.debug({ scope, dbPath }, "dual-scope cleo.db ready");
38417
39223
  const built = {
38418
39224
  db,
38419
39225
  scope,
@@ -38439,6 +39245,25 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38439
39245
  { dbPath }
38440
39246
  );
38441
39247
  if (exodusCwd !== void 0 && dbPath === resolveDualScopeDbPath(scope, exodusCwd)) {
39248
+ let releaseDbHeavy = null;
39249
+ let dbHeavyDeferred = false;
39250
+ try {
39251
+ const { governor: governor2 } = await Promise.resolve().then(() => (init_governor(), governor_exports));
39252
+ const admit = await governor2.tryAcquire("db-heavy");
39253
+ if (admit.deferred) {
39254
+ dbHeavyDeferred = true;
39255
+ } else {
39256
+ releaseDbHeavy = admit.release;
39257
+ }
39258
+ } catch {
39259
+ }
39260
+ if (dbHeavyDeferred) {
39261
+ log9.debug(
39262
+ { scope, dbPath },
39263
+ "exodus-on-open skipped this open \u2014 db-heavy deferred under memory pressure (re-runs idempotently on a calmer open)"
39264
+ );
39265
+ return handle;
39266
+ }
38442
39267
  try {
38443
39268
  const { maybeRunExodusOnOpen: maybeRunExodusOnOpen2 } = await Promise.resolve().then(() => (init_on_open(), on_open_exports));
38444
39269
  const result = await maybeRunExodusOnOpen2(scope, dbPath, nativeDb, exodusCwd);
@@ -38451,7 +39276,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38451
39276
  reason: result.reason,
38452
39277
  at: Date.now()
38453
39278
  };
38454
- log8.warn(
39279
+ log9.warn(
38455
39280
  { scope, reason: result.reason },
38456
39281
  "exodus-on-open aborted; consolidated cleo.db left empty, legacy kept as source \u2014 mutating callers must check handle.exodusAbort / call assertWriteDurable (T11828)"
38457
39282
  );
@@ -38464,11 +39289,14 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
38464
39289
  return reopened;
38465
39290
  }
38466
39291
  } catch (err) {
38467
- log8.warn(
39292
+ log9.warn(
38468
39293
  { err, scope },
38469
39294
  "exodus-on-open hook failed (non-fatal); re-opening consolidated handle"
38470
39295
  );
38471
39296
  return scope === "project" ? openDualScopeDbAtPath("project", dbPath) : openDualScopeDbAtPath("global", dbPath);
39297
+ } finally {
39298
+ if (releaseDbHeavy) await releaseDbHeavy().catch(() => {
39299
+ });
38472
39300
  }
38473
39301
  }
38474
39302
  return handle;
@@ -39091,8 +39919,8 @@ __export(nexus_sqlite_exports, {
39091
39919
  resetNexusDbState: () => resetNexusDbState,
39092
39920
  resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
39093
39921
  });
39094
- import { copyFileSync as copyFileSync4, existsSync as existsSync14 } from "node:fs";
39095
- import { join as join14 } from "node:path";
39922
+ import { copyFileSync as copyFileSync4, existsSync as existsSync15 } from "node:fs";
39923
+ import { join as join16 } from "node:path";
39096
39924
  function getNexusDbPath(cwd) {
39097
39925
  return resolveDualScopeDbPath("project", cwd);
39098
39926
  }
@@ -39124,7 +39952,7 @@ function resolveNexusMigrationsFolder() {
39124
39952
  return resolveCorePackageMigrationsFolder("drizzle-nexus");
39125
39953
  }
39126
39954
  function getNestedNexusSentinelPath() {
39127
- return join14(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
39955
+ return join16(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
39128
39956
  }
39129
39957
  function detectAndWarnOnNestedNexus() {
39130
39958
  let nestedPath;
@@ -39133,12 +39961,12 @@ function detectAndWarnOnNestedNexus() {
39133
39961
  } catch {
39134
39962
  return false;
39135
39963
  }
39136
- if (!existsSync14(nestedPath)) return false;
39964
+ if (!existsSync15(nestedPath)) return false;
39137
39965
  if (_warnedNestedPaths.has(nestedPath)) return false;
39138
39966
  _warnedNestedPaths.add(nestedPath);
39139
39967
  const canonicalPath = getNexusDbPath();
39140
- const log8 = getLogger("nexus-sqlite");
39141
- log8.warn(
39968
+ const log9 = getLogger("nexus-sqlite");
39969
+ log9.warn(
39142
39970
  {
39143
39971
  nestedPath,
39144
39972
  canonicalPath,
@@ -39292,7 +40120,7 @@ function runNexusMigrations(nativeDb, db) {
39292
40120
  const migrationsFolder = resolveNexusMigrationsFolder();
39293
40121
  if (tableExists4(nativeDb, "nexus_nodes") && _nexusDbPath) {
39294
40122
  const backupPath = _nexusDbPath.replace(/\.db$/, "-pre-cleo.db.bak");
39295
- if (!existsSync14(backupPath)) {
40123
+ if (!existsSync15(backupPath)) {
39296
40124
  try {
39297
40125
  copyFileSync4(_nexusDbPath, backupPath);
39298
40126
  } catch {
@@ -39430,10 +40258,10 @@ var init_nexus_sqlite = __esm({
39430
40258
 
39431
40259
  // packages/core/src/paths.ts
39432
40260
  import { AsyncLocalStorage } from "node:async_hooks";
39433
- import { existsSync as existsSync15, readFileSync as readFileSync5, statSync as statSync5 } from "node:fs";
40261
+ import { existsSync as existsSync16, readFileSync as readFileSync5, statSync as statSync5 } from "node:fs";
39434
40262
  import { createRequire as createRequire5 } from "node:module";
39435
40263
  import { homedir } from "node:os";
39436
- import { basename as basename4, dirname as dirname7, join as join15, resolve as resolve3 } from "node:path";
40264
+ import { basename as basename4, dirname as dirname7, join as join17, resolve as resolve3 } from "node:path";
39437
40265
  import {
39438
40266
  computeCanonicalProjectId as _computeCanonicalProjectId,
39439
40267
  getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath,
@@ -39523,8 +40351,8 @@ function getCleoDirAbsolute(cwd, opts) {
39523
40351
  function _resolveProjectByCwdFromNexus(cwd) {
39524
40352
  try {
39525
40353
  const cleoHome = getCleoHome();
39526
- const globalDbPath = join15(cleoHome, "cleo.db");
39527
- if (!existsSync15(globalDbPath)) return null;
40354
+ const globalDbPath = join17(cleoHome, "cleo.db");
40355
+ if (!existsSync16(globalDbPath)) return null;
39528
40356
  const start = resolve3(cwd ?? process.cwd());
39529
40357
  let current = start;
39530
40358
  const DatabaseSync2 = _getDatabaseSyncCtor();
@@ -39563,7 +40391,7 @@ function _findCleoDirRoot(cwd) {
39563
40391
  const isDangerousRoot = current === homeRoot || current === "/" || current === "";
39564
40392
  if (!isDangerousRoot) {
39565
40393
  try {
39566
- if (statSync5(join15(current, ".cleo")).isDirectory()) {
40394
+ if (statSync5(join17(current, ".cleo")).isDirectory()) {
39567
40395
  return current;
39568
40396
  }
39569
40397
  } catch {
@@ -39578,7 +40406,7 @@ function _findCleoDirRoot(cwd) {
39578
40406
  function resolveCleoDir(cwd) {
39579
40407
  const scope = worktreeScope.getStore();
39580
40408
  if (scope !== void 0) {
39581
- return join15(scope.worktreeRoot, ".cleo");
40409
+ return join17(scope.worktreeRoot, ".cleo");
39582
40410
  }
39583
40411
  const override = _cleoDirEnvOverride();
39584
40412
  if (override !== null) {
@@ -39586,14 +40414,14 @@ function resolveCleoDir(cwd) {
39586
40414
  }
39587
40415
  const root = _findCleoDirRoot(cwd);
39588
40416
  if (root !== null) {
39589
- return join15(root, ".cleo");
40417
+ return join17(root, ".cleo");
39590
40418
  }
39591
40419
  const start = resolve3(cwd ?? process.cwd());
39592
40420
  let current = start;
39593
40421
  while (true) {
39594
40422
  const mainRepo = _resolveMainRepoFromGitlink(current);
39595
40423
  if (mainRepo !== null) {
39596
- return join15(mainRepo, ".cleo");
40424
+ return join17(mainRepo, ".cleo");
39597
40425
  }
39598
40426
  const parent = dirname7(current);
39599
40427
  if (parent === current) {
@@ -39635,9 +40463,9 @@ function _cwdHasGitAncestor(cwd) {
39635
40463
  const start = resolve3(cwd ?? process.cwd());
39636
40464
  let current = start;
39637
40465
  while (true) {
39638
- const gitMarker = join15(current, ".git");
40466
+ const gitMarker = join17(current, ".git");
39639
40467
  try {
39640
- if (existsSync15(gitMarker)) {
40468
+ if (existsSync16(gitMarker)) {
39641
40469
  return true;
39642
40470
  }
39643
40471
  } catch {
@@ -39649,16 +40477,16 @@ function _cwdHasGitAncestor(cwd) {
39649
40477
  }
39650
40478
  function _resolveMainRepoFromGitlink(gitlinkDir) {
39651
40479
  try {
39652
- const gitLinkPath = join15(gitlinkDir, ".git");
39653
- if (!existsSync15(gitLinkPath)) return null;
39654
- const stat2 = statSync5(gitLinkPath);
39655
- if (!stat2.isFile()) return null;
40480
+ const gitLinkPath = join17(gitlinkDir, ".git");
40481
+ if (!existsSync16(gitLinkPath)) return null;
40482
+ const stat3 = statSync5(gitLinkPath);
40483
+ if (!stat3.isFile()) return null;
39656
40484
  const gitLinkContent = readFileSync5(gitLinkPath, "utf-8").trim();
39657
40485
  const match = gitLinkContent.match(/^gitdir:\s*(.+)$/m);
39658
40486
  if (!match) return null;
39659
40487
  const gitdir = match[1].trim();
39660
40488
  const mainRepo = dirname7(dirname7(dirname7(gitdir)));
39661
- if (existsSync15(join15(mainRepo, ".cleo")) && validateProjectRoot(mainRepo)) {
40489
+ if (existsSync16(join17(mainRepo, ".cleo")) && validateProjectRoot(mainRepo)) {
39662
40490
  return mainRepo;
39663
40491
  }
39664
40492
  } catch {
@@ -39666,18 +40494,18 @@ function _resolveMainRepoFromGitlink(gitlinkDir) {
39666
40494
  return null;
39667
40495
  }
39668
40496
  function validateProjectRoot(candidate) {
39669
- const cleoDir = join15(candidate, ".cleo");
39670
- if (!existsSync15(cleoDir)) {
40497
+ const cleoDir = join17(candidate, ".cleo");
40498
+ if (!existsSync16(cleoDir)) {
39671
40499
  return false;
39672
40500
  }
39673
- const projectInfoPath = join15(cleoDir, "project-info.json");
39674
- if (existsSync15(projectInfoPath)) {
40501
+ const projectInfoPath = join17(cleoDir, "project-info.json");
40502
+ if (existsSync16(projectInfoPath)) {
39675
40503
  try {
39676
40504
  const raw = readFileSync5(projectInfoPath, "utf-8");
39677
40505
  const parsed = JSON.parse(raw);
39678
40506
  if (typeof parsed === "object" && parsed !== null && "projectId" in parsed && typeof parsed["projectId"] === "string" && parsed["projectId"] !== "") {
39679
- const gitMarker = join15(candidate, ".git");
39680
- if (existsSync15(gitMarker)) {
40507
+ const gitMarker = join17(candidate, ".git");
40508
+ if (existsSync16(gitMarker)) {
39681
40509
  try {
39682
40510
  if (!statSync5(gitMarker).isDirectory()) {
39683
40511
  return false;
@@ -39691,12 +40519,12 @@ function validateProjectRoot(candidate) {
39691
40519
  } catch {
39692
40520
  }
39693
40521
  }
39694
- const gitDir = join15(candidate, ".git");
39695
- if (existsSync15(gitDir)) {
40522
+ const gitDir = join17(candidate, ".git");
40523
+ if (existsSync16(gitDir)) {
39696
40524
  let isRealGitDir = false;
39697
40525
  try {
39698
- const stat2 = statSync5(gitDir);
39699
- isRealGitDir = stat2.isDirectory();
40526
+ const stat3 = statSync5(gitDir);
40527
+ isRealGitDir = stat3.isDirectory();
39700
40528
  } catch {
39701
40529
  isRealGitDir = false;
39702
40530
  }
@@ -39739,16 +40567,16 @@ function getProjectRoot(cwd) {
39739
40567
  const homeRoot = homedir();
39740
40568
  const skippedCleoDirs = [];
39741
40569
  while (true) {
39742
- const cleoDir = join15(current, ".cleo");
39743
- const gitDir = join15(current, ".git");
40570
+ const cleoDir = join17(current, ".cleo");
40571
+ const gitDir = join17(current, ".git");
39744
40572
  const isDangerousRoot = current === homeRoot || current === "/" || current === "";
39745
- if (existsSync15(cleoDir) && !isDangerousRoot) {
40573
+ if (existsSync16(cleoDir) && !isDangerousRoot) {
39746
40574
  if (validateProjectRoot(current)) {
39747
40575
  return current;
39748
40576
  }
39749
40577
  skippedCleoDirs.push(current);
39750
40578
  }
39751
- if (existsSync15(gitDir) && !isDangerousRoot) {
40579
+ if (existsSync16(gitDir) && !isDangerousRoot) {
39752
40580
  let isRealGitDir = false;
39753
40581
  try {
39754
40582
  isRealGitDir = statSync5(gitDir).isDirectory();
@@ -39793,18 +40621,18 @@ function resolveOrCwd(maybeRoot) {
39793
40621
  return getProjectRoot();
39794
40622
  }
39795
40623
  function getConfigPath(cwd) {
39796
- return join15(_resolveCleoDir(cwd), "config.json");
40624
+ return join17(_resolveCleoDir(cwd), "config.json");
39797
40625
  }
39798
40626
  function getGlobalConfigPath() {
39799
- return join15(getCleoHome(), "config.json");
40627
+ return join17(getCleoHome(), "config.json");
39800
40628
  }
39801
40629
  function isAbsolutePath(path) {
39802
40630
  return _isAbsolutePath(path);
39803
40631
  }
39804
40632
  function _readProjectNameFromInfo(projectRoot) {
39805
40633
  try {
39806
- const infoPath = join15(projectRoot, ".cleo", "project-info.json");
39807
- if (!existsSync15(infoPath)) return void 0;
40634
+ const infoPath = join17(projectRoot, ".cleo", "project-info.json");
40635
+ if (!existsSync16(infoPath)) return void 0;
39808
40636
  const raw = readFileSync5(infoPath, "utf-8");
39809
40637
  const data = JSON.parse(raw);
39810
40638
  return typeof data.name === "string" && data.name.length > 0 ? data.name : void 0;
@@ -39830,8 +40658,8 @@ async function registerProjectOnEncounter(projectRoot, infoProjectId) {
39830
40658
  if (existingRows.length > 0) {
39831
40659
  const existingPath = existingRows[0].projectPath;
39832
40660
  if (existingPath !== resolvedPath) {
39833
- const newBrainDbPath = join15(resolvedPath, ".cleo", "brain.db");
39834
- const newTasksDbPath = join15(resolvedPath, ".cleo", "tasks.db");
40661
+ const newBrainDbPath = join17(resolvedPath, ".cleo", "brain.db");
40662
+ const newTasksDbPath = join17(resolvedPath, ".cleo", "tasks.db");
39835
40663
  await db.update(projectRegistry2).set({
39836
40664
  projectPath: resolvedPath,
39837
40665
  projectHash: generateProjectHash2(resolvedPath),
@@ -39862,8 +40690,8 @@ async function registerProjectOnEncounter(projectRoot, infoProjectId) {
39862
40690
  lastSync: now,
39863
40691
  taskCount: 0,
39864
40692
  labelsJson: "[]",
39865
- brainDbPath: join15(resolvedPath, ".cleo", "brain.db"),
39866
- tasksDbPath: join15(resolvedPath, ".cleo", "tasks.db"),
40693
+ brainDbPath: join17(resolvedPath, ".cleo", "brain.db"),
40694
+ tasksDbPath: join17(resolvedPath, ".cleo", "tasks.db"),
39867
40695
  statsJson: "{}"
39868
40696
  }).onConflictDoNothing();
39869
40697
  const aliases = canonicalResult.legacyAliases ?? [];
@@ -39964,46 +40792,46 @@ var init_api_mode = __esm({
39964
40792
  // packages/core/src/store/file-utils.ts
39965
40793
  import { randomBytes } from "node:crypto";
39966
40794
  import {
39967
- existsSync as existsSync16,
39968
- mkdirSync as mkdirSync4,
39969
- readdirSync as readdirSync4,
40795
+ existsSync as existsSync17,
40796
+ mkdirSync as mkdirSync5,
40797
+ readdirSync as readdirSync5,
39970
40798
  readFileSync as readFileSync6,
39971
40799
  renameSync as renameSync3,
39972
40800
  unlinkSync as unlinkSync3,
39973
- writeFileSync as writeFileSync3
40801
+ writeFileSync as writeFileSync4
39974
40802
  } from "node:fs";
39975
- import { basename as basename5, dirname as dirname8, join as join16 } from "node:path";
39976
- import * as lockfile2 from "proper-lockfile";
40803
+ import { basename as basename5, dirname as dirname8, join as join18 } from "node:path";
40804
+ import * as lockfile3 from "proper-lockfile";
39977
40805
  function rotateBackup(filePath, mode) {
39978
40806
  const dir = dirname8(filePath);
39979
40807
  const name15 = basename5(filePath);
39980
- const backupDir = join16(dir, ".backups");
40808
+ const backupDir = join18(dir, ".backups");
39981
40809
  const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
39982
- if (!existsSync16(backupDir)) {
39983
- mkdirSync4(backupDir, { recursive: true, mode: dirMode });
40810
+ if (!existsSync17(backupDir)) {
40811
+ mkdirSync5(backupDir, { recursive: true, mode: dirMode });
39984
40812
  }
39985
40813
  for (let i = MAX_BACKUPS; i >= 1; i--) {
39986
- const current = join16(backupDir, `${name15}.${i}`);
40814
+ const current = join18(backupDir, `${name15}.${i}`);
39987
40815
  if (i === MAX_BACKUPS) {
39988
40816
  try {
39989
40817
  unlinkSync3(current);
39990
40818
  } catch {
39991
40819
  }
39992
40820
  } else {
39993
- const next = join16(backupDir, `${name15}.${i + 1}`);
40821
+ const next = join18(backupDir, `${name15}.${i + 1}`);
39994
40822
  try {
39995
- if (existsSync16(current)) renameSync3(current, next);
40823
+ if (existsSync17(current)) renameSync3(current, next);
39996
40824
  } catch {
39997
40825
  }
39998
40826
  }
39999
40827
  }
40000
40828
  try {
40001
40829
  const content = readFileSync6(filePath, "utf-8");
40002
- const backupPath = join16(backupDir, `${name15}.1`);
40830
+ const backupPath = join18(backupDir, `${name15}.1`);
40003
40831
  if (typeof mode === "number") {
40004
- writeFileSync3(backupPath, content, { encoding: "utf-8", mode });
40832
+ writeFileSync4(backupPath, content, { encoding: "utf-8", mode });
40005
40833
  } else {
40006
- writeFileSync3(backupPath, content, "utf-8");
40834
+ writeFileSync4(backupPath, content, "utf-8");
40007
40835
  }
40008
40836
  } catch {
40009
40837
  }
@@ -40020,15 +40848,15 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
40020
40848
  const indent = opts.indent ?? 2;
40021
40849
  const mode = opts.mode;
40022
40850
  const dir = dirname8(filePath);
40023
- const tempPath = join16(dir, `.${basename5(filePath)}.${randomBytes(6).toString("hex")}.tmp`);
40851
+ const tempPath = join18(dir, `.${basename5(filePath)}.${randomBytes(6).toString("hex")}.tmp`);
40024
40852
  const content = JSON.stringify(data, null, indent) + "\n";
40025
40853
  if (typeof mode === "number") {
40026
- writeFileSync3(tempPath, content, { encoding: "utf-8", mode });
40854
+ writeFileSync4(tempPath, content, { encoding: "utf-8", mode });
40027
40855
  } else {
40028
- writeFileSync3(tempPath, content, "utf-8");
40856
+ writeFileSync4(tempPath, content, "utf-8");
40029
40857
  }
40030
40858
  try {
40031
- if (existsSync16(filePath)) {
40859
+ if (existsSync17(filePath)) {
40032
40860
  rotateBackup(filePath, mode);
40033
40861
  }
40034
40862
  renameSync3(tempPath, filePath);
@@ -40054,19 +40882,19 @@ function readJsonFile(filePath) {
40054
40882
  async function withLock2(filePath, transform2, opts = {}) {
40055
40883
  const dir = dirname8(filePath);
40056
40884
  const dirMode = typeof opts.mode === "number" ? modeToDirMode(opts.mode) : void 0;
40057
- if (!existsSync16(dir)) {
40058
- mkdirSync4(dir, { recursive: true, mode: dirMode });
40885
+ if (!existsSync17(dir)) {
40886
+ mkdirSync5(dir, { recursive: true, mode: dirMode });
40059
40887
  }
40060
- if (!existsSync16(filePath)) {
40888
+ if (!existsSync17(filePath)) {
40061
40889
  if (typeof opts.mode === "number") {
40062
- writeFileSync3(filePath, "", { encoding: "utf-8", mode: opts.mode });
40890
+ writeFileSync4(filePath, "", { encoding: "utf-8", mode: opts.mode });
40063
40891
  } else {
40064
- writeFileSync3(filePath, "", "utf-8");
40892
+ writeFileSync4(filePath, "", "utf-8");
40065
40893
  }
40066
40894
  }
40067
40895
  let release;
40068
40896
  try {
40069
- release = await lockfile2.lock(filePath, LOCK_OPTIONS);
40897
+ release = await lockfile3.lock(filePath, LOCK_OPTIONS);
40070
40898
  const current = readJsonFile(filePath);
40071
40899
  const updated = transform2(current);
40072
40900
  writeJsonFileAtomic(filePath, updated, { mode: opts.mode });
@@ -40079,15 +40907,15 @@ async function withLock2(filePath, transform2, opts = {}) {
40079
40907
  }
40080
40908
  async function withFileLock(filePath, operation) {
40081
40909
  const dir = dirname8(filePath);
40082
- if (!existsSync16(dir)) {
40083
- mkdirSync4(dir, { recursive: true });
40910
+ if (!existsSync17(dir)) {
40911
+ mkdirSync5(dir, { recursive: true });
40084
40912
  }
40085
- if (!existsSync16(filePath)) {
40086
- writeFileSync3(filePath, "", "utf-8");
40913
+ if (!existsSync17(filePath)) {
40914
+ writeFileSync4(filePath, "", "utf-8");
40087
40915
  }
40088
40916
  let release;
40089
40917
  try {
40090
- release = await lockfile2.lock(filePath, LOCK_OPTIONS);
40918
+ release = await lockfile3.lock(filePath, LOCK_OPTIONS);
40091
40919
  return await operation();
40092
40920
  } finally {
40093
40921
  if (release) {
@@ -40116,8 +40944,8 @@ var init_file_utils = __esm({
40116
40944
 
40117
40945
  // packages/core/src/llm/credential-removal.ts
40118
40946
  import { unlinkSync as unlinkSync4 } from "node:fs";
40119
- import { join as join17 } from "node:path";
40120
- import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
40947
+ import { join as join19 } from "node:path";
40948
+ import { getCleoHome as getCleoHome3 } from "@cleocode/paths";
40121
40949
  function buildBuiltinRemovalRegistry() {
40122
40950
  const registry2 = new RemovalRegistry();
40123
40951
  registry2.register(MANUAL_REMOVAL_STEP);
@@ -40208,7 +41036,7 @@ var init_credential_removal = __esm({
40208
41036
  sourceId: "cleo-pkce",
40209
41037
  description: "Delete CLEO-issued PKCE token at <CLEO_HOME>/anthropic-oauth.json",
40210
41038
  async remove() {
40211
- const path = join17(getCleoHome2(), "anthropic-oauth.json");
41039
+ const path = join19(getCleoHome3(), "anthropic-oauth.json");
40212
41040
  const cleaned = [];
40213
41041
  try {
40214
41042
  unlinkSync4(path);
@@ -40287,7 +41115,7 @@ __export(config_exports, {
40287
41115
  parseConfigValue: () => parseConfigValue,
40288
41116
  setConfigValue: () => setConfigValue
40289
41117
  });
40290
- import { existsSync as existsSync17 } from "node:fs";
41118
+ import { existsSync as existsSync18 } from "node:fs";
40291
41119
  function getNestedValue(obj, path) {
40292
41120
  const parts = path.split(".");
40293
41121
  let current = obj;
@@ -40335,7 +41163,7 @@ function parseEnvValue(value) {
40335
41163
  return value;
40336
41164
  }
40337
41165
  async function loadConfig(cwd) {
40338
- let merged = JSON.parse(JSON.stringify(DEFAULTS));
41166
+ let merged = JSON.parse(JSON.stringify(DEFAULTS2));
40339
41167
  const globalConfig2 = await readJson(getGlobalConfigPath());
40340
41168
  if (globalConfig2) {
40341
41169
  merged = deepMerge(merged, globalConfig2);
@@ -40381,7 +41209,7 @@ async function getConfigValue(path, cwd) {
40381
41209
  return { value: val, source: "global" };
40382
41210
  }
40383
41211
  }
40384
- const defaultVal = getNestedValue({ ...DEFAULTS }, path);
41212
+ const defaultVal = getNestedValue({ ...DEFAULTS2 }, path);
40385
41213
  return { value: defaultVal, source: "default" };
40386
41214
  }
40387
41215
  async function getRawConfigValue(key, cwd) {
@@ -40409,7 +41237,7 @@ function parseConfigValue(value) {
40409
41237
  }
40410
41238
  async function setConfigValue(key, value, cwd, opts) {
40411
41239
  const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
40412
- if (!existsSync17(configPath)) {
41240
+ if (!existsSync18(configPath)) {
40413
41241
  await atomicWriteJson(configPath, {});
40414
41242
  }
40415
41243
  const config2 = await readJson(configPath) ?? {};
@@ -40421,7 +41249,7 @@ async function setConfigValue(key, value, cwd, opts) {
40421
41249
  async function applyStrictnessPreset(preset, cwd, opts) {
40422
41250
  const definition = STRICTNESS_PRESETS[preset];
40423
41251
  const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
40424
- if (!existsSync17(configPath)) {
41252
+ if (!existsSync18(configPath)) {
40425
41253
  await atomicWriteJson(configPath, {});
40426
41254
  }
40427
41255
  const config2 = await readJson(configPath) ?? {};
@@ -40445,7 +41273,7 @@ function listStrictnessPresets() {
40445
41273
  })
40446
41274
  );
40447
41275
  }
40448
- var DEFAULTS, ENV_MAP, STRICTNESS_PRESETS;
41276
+ var DEFAULTS2, ENV_MAP, STRICTNESS_PRESETS;
40449
41277
  var init_config = __esm({
40450
41278
  "packages/core/src/config.ts"() {
40451
41279
  "use strict";
@@ -40453,7 +41281,7 @@ var init_config = __esm({
40453
41281
  init_paths();
40454
41282
  init_atomic();
40455
41283
  init_json2();
40456
- DEFAULTS = {
41284
+ DEFAULTS2 = {
40457
41285
  version: "2.10.0",
40458
41286
  output: {
40459
41287
  defaultFormat: "json",
@@ -40628,10 +41456,10 @@ var init_config = __esm({
40628
41456
  // packages/core/src/llm/credential-seeders/claude-code-seeder.ts
40629
41457
  import { readFileSync as readFileSync7 } from "node:fs";
40630
41458
  import { homedir as homedir2 } from "node:os";
40631
- import { join as join18 } from "node:path";
41459
+ import { join as join20 } from "node:path";
40632
41460
  function defaultReadCredentialFile() {
40633
41461
  try {
40634
- return readFileSync7(join18(homedir2(), ".claude", ".credentials.json"), "utf-8");
41462
+ return readFileSync7(join20(homedir2(), ".claude", ".credentials.json"), "utf-8");
40635
41463
  } catch {
40636
41464
  return null;
40637
41465
  }
@@ -40726,9 +41554,9 @@ var init_claude_code_seeder = __esm({
40726
41554
 
40727
41555
  // packages/core/src/llm/credential-seeders/cleo-pkce-seeder.ts
40728
41556
  import { readFileSync as readFileSync8 } from "node:fs";
40729
- import { join as join19 } from "node:path";
41557
+ import { join as join21 } from "node:path";
40730
41558
  function defaultCleoPkcePath() {
40731
- return join19(getCleoHome(), "anthropic-oauth.json");
41559
+ return join21(getCleoHome(), "anthropic-oauth.json");
40732
41560
  }
40733
41561
  function defaultReadCredentialFile2() {
40734
41562
  try {
@@ -40799,13 +41627,13 @@ var init_cleo_pkce_seeder = __esm({
40799
41627
  });
40800
41628
 
40801
41629
  // packages/core/src/llm/credential-seeders/codex-cli-seeder.ts
40802
- import { existsSync as existsSync18, readFileSync as readFileSync9 } from "node:fs";
41630
+ import { existsSync as existsSync19, readFileSync as readFileSync9 } from "node:fs";
40803
41631
  import { homedir as homedir3 } from "node:os";
40804
- import { join as join20 } from "node:path";
41632
+ import { join as join22 } from "node:path";
40805
41633
  function getCodexAuthPath() {
40806
41634
  const codexHome = (process.env["CODEX_HOME"] ?? "").trim();
40807
- const root = codexHome || join20(homedir3(), ".codex");
40808
- return join20(root, "auth.json");
41635
+ const root = codexHome || join22(homedir3(), ".codex");
41636
+ return join22(root, "auth.json");
40809
41637
  }
40810
41638
  var CodexCliSeeder, codexCliSeeder;
40811
41639
  var init_codex_cli_seeder = __esm({
@@ -40824,7 +41652,7 @@ var init_codex_cli_seeder = __esm({
40824
41652
  */
40825
41653
  async seed() {
40826
41654
  const authPath = getCodexAuthPath();
40827
- if (!existsSync18(authPath)) {
41655
+ if (!existsSync19(authPath)) {
40828
41656
  return { entries: [] };
40829
41657
  }
40830
41658
  let raw;
@@ -41019,11 +41847,11 @@ var init_google_pkce = __esm({
41019
41847
  });
41020
41848
 
41021
41849
  // packages/core/src/llm/credential-seeders/gemini-cli-seeder.ts
41022
- import { existsSync as existsSync19, readFileSync as readFileSync10 } from "node:fs";
41023
- import { join as join21 } from "node:path";
41024
- import { getCleoHome as getCleoHome3 } from "@cleocode/paths";
41850
+ import { existsSync as existsSync20, readFileSync as readFileSync10 } from "node:fs";
41851
+ import { join as join23 } from "node:path";
41852
+ import { getCleoHome as getCleoHome4 } from "@cleocode/paths";
41025
41853
  function getGoogleOauthPath() {
41026
- return join21(getCleoHome3(), "google_oauth.json");
41854
+ return join23(getCleoHome4(), "google_oauth.json");
41027
41855
  }
41028
41856
  function parseGoogleOauthFile(raw) {
41029
41857
  let json3;
@@ -41068,7 +41896,7 @@ var init_gemini_cli_seeder = __esm({
41068
41896
  */
41069
41897
  async seed() {
41070
41898
  const path = getGoogleOauthPath();
41071
- if (!existsSync19(path)) {
41899
+ if (!existsSync20(path)) {
41072
41900
  return { entries: [] };
41073
41901
  }
41074
41902
  let raw;
@@ -41293,23 +42121,23 @@ var init_credential_seeders = __esm({
41293
42121
 
41294
42122
  // packages/core/src/llm/global-config-migration.ts
41295
42123
  import {
41296
- existsSync as existsSync20,
41297
- mkdirSync as mkdirSync5,
42124
+ existsSync as existsSync21,
42125
+ mkdirSync as mkdirSync6,
41298
42126
  readFileSync as readFileSync11,
41299
42127
  renameSync as renameSync4,
41300
42128
  unlinkSync as unlinkSync5,
41301
- writeFileSync as writeFileSync4
42129
+ writeFileSync as writeFileSync5
41302
42130
  } from "node:fs";
41303
- import { join as join22 } from "node:path";
41304
- import { getCleoHome as getCleoHome4, getCleoPlatformPaths as getCleoPlatformPaths2 } from "@cleocode/paths";
42131
+ import { join as join24 } from "node:path";
42132
+ import { getCleoHome as getCleoHome5, getCleoPlatformPaths as getCleoPlatformPaths2 } from "@cleocode/paths";
41305
42133
  function configDirGlobalConfigPath() {
41306
- return join22(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
42134
+ return join24(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
41307
42135
  }
41308
42136
  function legacyGlobalConfigPath() {
41309
- return join22(getCleoHome4(), GLOBAL_CONFIG_FILENAME);
42137
+ return join24(getCleoHome5(), GLOBAL_CONFIG_FILENAME);
41310
42138
  }
41311
42139
  function migrationMarkerPath() {
41312
- return join22(getCleoHome4(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
42140
+ return join24(getCleoHome5(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
41313
42141
  }
41314
42142
  function tempTargetPath() {
41315
42143
  return `${configDirGlobalConfigPath()}.tmp`;
@@ -41319,12 +42147,12 @@ function migrateGlobalConfigToConfigDir() {
41319
42147
  const source = legacyGlobalConfigPath();
41320
42148
  const target = configDirGlobalConfigPath();
41321
42149
  const marker16 = migrationMarkerPath();
41322
- if (existsSync20(marker16)) return false;
41323
- if (!existsSync20(source)) {
42150
+ if (existsSync21(marker16)) return false;
42151
+ if (!existsSync21(source)) {
41324
42152
  stampMarker(marker16);
41325
42153
  return false;
41326
42154
  }
41327
- if (existsSync20(target)) {
42155
+ if (existsSync21(target)) {
41328
42156
  backupSourceQuiet(source);
41329
42157
  stampMarker(marker16);
41330
42158
  return false;
@@ -41338,9 +42166,9 @@ function migrateGlobalConfigToConfigDir() {
41338
42166
  );
41339
42167
  return false;
41340
42168
  }
41341
- mkdirSync5(getCleoPlatformPaths2().config, { recursive: true });
42169
+ mkdirSync6(getCleoPlatformPaths2().config, { recursive: true });
41342
42170
  const temp = tempTargetPath();
41343
- writeFileSync4(temp, raw, { mode: 420 });
42171
+ writeFileSync5(temp, raw, { mode: 420 });
41344
42172
  renameSync4(temp, target);
41345
42173
  stampMarker(marker16);
41346
42174
  try {
@@ -41357,7 +42185,7 @@ function migrateGlobalConfigToConfigDir() {
41357
42185
  } catch (err) {
41358
42186
  try {
41359
42187
  const temp = tempTargetPath();
41360
- if (existsSync20(temp)) unlinkSync5(temp);
42188
+ if (existsSync21(temp)) unlinkSync5(temp);
41361
42189
  } catch {
41362
42190
  }
41363
42191
  console.error(
@@ -41368,8 +42196,8 @@ function migrateGlobalConfigToConfigDir() {
41368
42196
  }
41369
42197
  function stampMarker(markerPath) {
41370
42198
  try {
41371
- mkdirSync5(join22(getCleoHome4(), MIGRATIONS_SUBDIR), { recursive: true });
41372
- writeFileSync4(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
42199
+ mkdirSync6(join24(getCleoHome5(), MIGRATIONS_SUBDIR), { recursive: true });
42200
+ writeFileSync5(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
41373
42201
  `, { mode: 420 });
41374
42202
  } catch {
41375
42203
  }
@@ -41377,7 +42205,7 @@ function stampMarker(markerPath) {
41377
42205
  function backupSourceQuiet(source) {
41378
42206
  try {
41379
42207
  const backup = `${source}${BACKUP_SUFFIX}`;
41380
- if (existsSync20(backup)) return;
42208
+ if (existsSync21(backup)) return;
41381
42209
  renameSync4(source, backup);
41382
42210
  } catch {
41383
42211
  }
@@ -41400,20 +42228,20 @@ var init_global_config_migration = __esm({
41400
42228
  });
41401
42229
 
41402
42230
  // packages/core/src/llm/legacy-flat-key-import.ts
41403
- import { existsSync as existsSync21, readFileSync as readFileSync12, renameSync as renameSync5, writeFileSync as writeFileSync5 } from "node:fs";
41404
- import { join as join23 } from "node:path";
41405
- import { getCleoHome as getCleoHome5 } from "@cleocode/paths";
42231
+ import { existsSync as existsSync22, readFileSync as readFileSync12, renameSync as renameSync5, writeFileSync as writeFileSync6 } from "node:fs";
42232
+ import { join as join25 } from "node:path";
42233
+ import { getCleoHome as getCleoHome6 } from "@cleocode/paths";
41406
42234
  function migrationPaths() {
41407
- const home = getCleoHome5();
42235
+ const home = getCleoHome6();
41408
42236
  return {
41409
- flatPath: join23(home, "anthropic-key"),
41410
- bakPath: join23(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
41411
- markerPath: join23(home, LEGACY_FLAT_KEY_MARKER)
42237
+ flatPath: join25(home, "anthropic-key"),
42238
+ bakPath: join25(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
42239
+ markerPath: join25(home, LEGACY_FLAT_KEY_MARKER)
41412
42240
  };
41413
42241
  }
41414
42242
  function writeMarker(markerPath) {
41415
42243
  try {
41416
- writeFileSync5(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
42244
+ writeFileSync6(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
41417
42245
  `, {
41418
42246
  encoding: "utf-8",
41419
42247
  flag: "wx",
@@ -41429,7 +42257,7 @@ function writeMarker(markerPath) {
41429
42257
  }
41430
42258
  function readFlatKey(flatPath) {
41431
42259
  try {
41432
- if (!existsSync21(flatPath)) return null;
42260
+ if (!existsSync22(flatPath)) return null;
41433
42261
  const raw = readFileSync12(flatPath, "utf-8").trim();
41434
42262
  return raw || null;
41435
42263
  } catch (err) {
@@ -41442,7 +42270,7 @@ function readFlatKey(flatPath) {
41442
42270
  }
41443
42271
  async function importLegacyFlatAnthropicKey() {
41444
42272
  const { flatPath, bakPath, markerPath } = migrationPaths();
41445
- if (existsSync21(markerPath)) {
42273
+ if (existsSync22(markerPath)) {
41446
42274
  return { status: "marker-present", flatPath, bakPath: null, markerPath };
41447
42275
  }
41448
42276
  let existing = null;
@@ -41459,7 +42287,7 @@ async function importLegacyFlatAnthropicKey() {
41459
42287
  writeMarker(markerPath);
41460
42288
  return { status: "already-imported", flatPath, bakPath: null, markerPath };
41461
42289
  }
41462
- if (!existsSync21(flatPath)) {
42290
+ if (!existsSync22(flatPath)) {
41463
42291
  writeMarker(markerPath);
41464
42292
  return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
41465
42293
  }
@@ -41521,15 +42349,15 @@ var init_legacy_flat_key_import = __esm({
41521
42349
  });
41522
42350
 
41523
42351
  // packages/core/src/llm/credentials.ts
41524
- import { existsSync as existsSync22, mkdirSync as mkdirSync6, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "node:fs";
41525
- import { join as join24 } from "node:path";
41526
- import { getCleoHome as getCleoHome6 } from "@cleocode/paths";
42352
+ import { existsSync as existsSync23, mkdirSync as mkdirSync7, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "node:fs";
42353
+ import { join as join26 } from "node:path";
42354
+ import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
41527
42355
  function globalConfigPath() {
41528
42356
  return configDirGlobalConfigPath();
41529
42357
  }
41530
42358
  function projectConfigPath(projectRoot) {
41531
42359
  const cleoDir = process.env["CLEO_DIR"] ?? ".cleo";
41532
- return join24(projectRoot, cleoDir, "config.json");
42360
+ return join26(projectRoot, cleoDir, "config.json");
41533
42361
  }
41534
42362
  function readGlobalProviderKey(provider) {
41535
42363
  ensureGlobalConfigMigrated();
@@ -41539,8 +42367,8 @@ function readGlobalProviderKey(provider) {
41539
42367
  }
41540
42368
  function readFlatAnthropicKey() {
41541
42369
  try {
41542
- const keyFile = join24(getCleoHome6(), "anthropic-key");
41543
- if (!existsSync22(keyFile)) return null;
42370
+ const keyFile = join26(getCleoHome7(), "anthropic-key");
42371
+ if (!existsSync23(keyFile)) return null;
41544
42372
  const stored = readFileSync13(keyFile, "utf-8").trim();
41545
42373
  return stored || null;
41546
42374
  } catch {
@@ -41549,7 +42377,7 @@ function readFlatAnthropicKey() {
41549
42377
  }
41550
42378
  function readProviderKeyFromConfig(configFile, provider) {
41551
42379
  try {
41552
- if (!existsSync22(configFile)) return null;
42380
+ if (!existsSync23(configFile)) return null;
41553
42381
  const raw = readFileSync13(configFile, "utf-8");
41554
42382
  const config2 = JSON.parse(raw);
41555
42383
  const llm = config2["llm"];
@@ -41688,17 +42516,17 @@ __export(credentials_store_exports, {
41688
42516
  pickCredentialForProviderSync: () => pickCredentialForProviderSync,
41689
42517
  removeCredential: () => removeCredential
41690
42518
  });
41691
- import { chmodSync, existsSync as existsSync23, mkdirSync as mkdirSync7, readFileSync as readFileSync14, statSync as statSync6, writeFileSync as writeFileSync7 } from "node:fs";
41692
- import { dirname as dirname9, join as join25 } from "node:path";
41693
- import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
42519
+ import { chmodSync, existsSync as existsSync24, mkdirSync as mkdirSync8, readFileSync as readFileSync14, statSync as statSync6, writeFileSync as writeFileSync8 } from "node:fs";
42520
+ import { dirname as dirname9, join as join27 } from "node:path";
42521
+ import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
41694
42522
  function credentialsStorePath() {
41695
- return join25(getCleoHome7(), "llm-credentials.json");
42523
+ return join27(getCleoHome8(), "llm-credentials.json");
41696
42524
  }
41697
42525
  function ensureFileInitialized(path) {
41698
- if (existsSync23(path)) return;
42526
+ if (existsSync24(path)) return;
41699
42527
  const dir = dirname9(path);
41700
- if (!existsSync23(dir)) {
41701
- mkdirSync7(dir, { recursive: true, mode: 448 });
42528
+ if (!existsSync24(dir)) {
42529
+ mkdirSync8(dir, { recursive: true, mode: 448 });
41702
42530
  } else {
41703
42531
  try {
41704
42532
  chmodSync(dir, 448);
@@ -41706,7 +42534,7 @@ function ensureFileInitialized(path) {
41706
42534
  }
41707
42535
  }
41708
42536
  try {
41709
- writeFileSync7(path, `${JSON.stringify(emptyStore(), null, 2)}
42537
+ writeFileSync8(path, `${JSON.stringify(emptyStore(), null, 2)}
41710
42538
  `, {
41711
42539
  encoding: "utf-8",
41712
42540
  flag: "wx",
@@ -42049,13 +42877,13 @@ var init_gemini = __esm({
42049
42877
 
42050
42878
  // packages/core/src/llm/stable-device-id.ts
42051
42879
  import { randomUUID as randomUUID2 } from "node:crypto";
42052
- import { existsSync as existsSync24, mkdirSync as mkdirSync8, readFileSync as readFileSync15, renameSync as renameSync6, writeFileSync as writeFileSync8 } from "node:fs";
42053
- import { dirname as dirname10, join as join26 } from "node:path";
42054
- import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
42880
+ import { existsSync as existsSync25, mkdirSync as mkdirSync9, readFileSync as readFileSync15, renameSync as renameSync6, writeFileSync as writeFileSync9 } from "node:fs";
42881
+ import { dirname as dirname10, join as join28 } from "node:path";
42882
+ import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
42055
42883
  function getStableDeviceId() {
42056
42884
  if (_cachedDeviceId !== null) return _cachedDeviceId;
42057
- const path = join26(getCleoHome8(), DEVICE_ID_FILE);
42058
- if (existsSync24(path)) {
42885
+ const path = join28(getCleoHome9(), DEVICE_ID_FILE);
42886
+ if (existsSync25(path)) {
42059
42887
  try {
42060
42888
  const raw = readFileSync15(path, "utf-8").trim();
42061
42889
  if (raw.length > 0) {
@@ -42068,11 +42896,11 @@ function getStableDeviceId() {
42068
42896
  const fresh = randomUUID2();
42069
42897
  try {
42070
42898
  const dir = dirname10(path);
42071
- if (!existsSync24(dir)) {
42072
- mkdirSync8(dir, { recursive: true });
42899
+ if (!existsSync25(dir)) {
42900
+ mkdirSync9(dir, { recursive: true });
42073
42901
  }
42074
42902
  const tmpPath = `${path}.tmp.${process.pid}`;
42075
- writeFileSync8(tmpPath, fresh, { mode: 384 });
42903
+ writeFileSync9(tmpPath, fresh, { mode: 384 });
42076
42904
  renameSync6(tmpPath, path);
42077
42905
  } catch {
42078
42906
  }
@@ -42370,14 +43198,14 @@ var init_xai = __esm({
42370
43198
  });
42371
43199
 
42372
43200
  // packages/core/src/llm/provider-registry/loader.ts
42373
- import { readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
42374
- import { join as join27 } from "node:path";
43201
+ import { readdirSync as readdirSync6, statSync as statSync7 } from "node:fs";
43202
+ import { join as join29 } from "node:path";
42375
43203
  import { pathToFileURL } from "node:url";
42376
43204
  function isPluginFile(filename) {
42377
43205
  return PLUGIN_EXTENSIONS.some((ext) => filename.endsWith(ext));
42378
43206
  }
42379
43207
  function getPluginDir() {
42380
- return join27(getCleoHome(), "plugins", "model-providers");
43208
+ return join29(getCleoHome(), "plugins", "model-providers");
42381
43209
  }
42382
43210
  async function loadOnePlugin(absPath, api) {
42383
43211
  let mod;
@@ -42419,19 +43247,19 @@ async function loadOnePlugin(absPath, api) {
42419
43247
  async function scanAndLoadPlugins(pluginDir, api) {
42420
43248
  let entries;
42421
43249
  try {
42422
- entries = readdirSync5(pluginDir);
43250
+ entries = readdirSync6(pluginDir);
42423
43251
  } catch {
42424
43252
  return;
42425
43253
  }
42426
43254
  const pluginFiles = entries.filter((name15) => !name15.startsWith(".") && isPluginFile(name15)).filter((name15) => {
42427
43255
  try {
42428
- return statSync7(join27(pluginDir, name15)).isFile();
43256
+ return statSync7(join29(pluginDir, name15)).isFile();
42429
43257
  } catch {
42430
43258
  return false;
42431
43259
  }
42432
43260
  }).sort();
42433
43261
  for (const filename of pluginFiles) {
42434
- await loadOnePlugin(join27(pluginDir, filename), api);
43262
+ await loadOnePlugin(join29(pluginDir, filename), api);
42435
43263
  }
42436
43264
  }
42437
43265
  async function runDiscovery(registerProvider2, builtins) {
@@ -42534,15 +43362,15 @@ var init_provider_registry = __esm({
42534
43362
  });
42535
43363
 
42536
43364
  // packages/core/src/llm/rate-limit-guard.ts
42537
- import { existsSync as existsSync25, mkdirSync as mkdirSync9, unlinkSync as unlinkSync6 } from "node:fs";
42538
- import { join as join28 } from "node:path";
42539
- import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
43365
+ import { existsSync as existsSync26, mkdirSync as mkdirSync10, unlinkSync as unlinkSync6 } from "node:fs";
43366
+ import { join as join30 } from "node:path";
43367
+ import { getCleoHome as getCleoHome10 } from "@cleocode/paths";
42540
43368
  function sanitize(value) {
42541
43369
  return value.replace(/[^a-zA-Z0-9_-]/g, "_");
42542
43370
  }
42543
43371
  function rateLimitStatePath(provider, label) {
42544
- const dir = join28(getCleoHome9(), "rate-limit-state");
42545
- return join28(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
43372
+ const dir = join30(getCleoHome10(), "rate-limit-state");
43373
+ return join30(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
42546
43374
  }
42547
43375
  function parseResetFromHeaders(headers) {
42548
43376
  const get = (k) => {
@@ -42589,9 +43417,9 @@ async function recordRateLimit(provider, label, opts) {
42589
43417
  source = "default";
42590
43418
  }
42591
43419
  const filePath = rateLimitStatePath(provider, label);
42592
- const dir = join28(getCleoHome9(), "rate-limit-state");
42593
- if (!existsSync25(dir)) {
42594
- mkdirSync9(dir, { recursive: true });
43420
+ const dir = join30(getCleoHome10(), "rate-limit-state");
43421
+ if (!existsSync26(dir)) {
43422
+ mkdirSync10(dir, { recursive: true });
42595
43423
  }
42596
43424
  const state = { resetAt, recordedAt: now, source };
42597
43425
  await withFileLock(filePath, () => {
@@ -43105,28 +43933,28 @@ var init_credential_pool = __esm({
43105
43933
 
43106
43934
  // packages/core/src/llm/catalog-cache.ts
43107
43935
  import {
43108
- existsSync as existsSync26,
43109
- mkdirSync as mkdirSync10,
43110
- readdirSync as readdirSync6,
43936
+ existsSync as existsSync27,
43937
+ mkdirSync as mkdirSync11,
43938
+ readdirSync as readdirSync7,
43111
43939
  readFileSync as readFileSync16,
43112
43940
  statSync as statSync8,
43113
43941
  symlinkSync,
43114
43942
  unlinkSync as unlinkSync7,
43115
- writeFileSync as writeFileSync9
43943
+ writeFileSync as writeFileSync10
43116
43944
  } from "node:fs";
43117
43945
  import { homedir as homedir4 } from "node:os";
43118
- import { join as join29 } from "node:path";
43946
+ import { join as join31 } from "node:path";
43119
43947
  function getCatalogDir() {
43120
43948
  if (process.env["CLEO_DATA_DIR"]) {
43121
- return join29(process.env["CLEO_DATA_DIR"], "llm-catalog");
43949
+ return join31(process.env["CLEO_DATA_DIR"], "llm-catalog");
43122
43950
  }
43123
- const xdg = process.env["XDG_DATA_HOME"] ?? join29(homedir4(), ".local", "share");
43124
- return join29(xdg, "cleo", "llm-catalog");
43951
+ const xdg = process.env["XDG_DATA_HOME"] ?? join31(homedir4(), ".local", "share");
43952
+ return join31(xdg, "cleo", "llm-catalog");
43125
43953
  }
43126
43954
  function findLatestCacheFile(dir) {
43127
- if (!existsSync26(dir)) return null;
43128
- const files = readdirSync6(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync8(join29(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
43129
- return files.length > 0 ? join29(dir, files[0].name) : null;
43955
+ if (!existsSync27(dir)) return null;
43956
+ const files = readdirSync7(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync8(join31(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
43957
+ return files.length > 0 ? join31(dir, files[0].name) : null;
43130
43958
  }
43131
43959
  function readCacheFile(filePath) {
43132
43960
  try {
@@ -43224,7 +44052,7 @@ var init_catalog_model_resolver = __esm({
43224
44052
  });
43225
44053
 
43226
44054
  // packages/core/src/llm/cross-provider-selector.ts
43227
- import { totalmem } from "node:os";
44055
+ import { totalmem as totalmem2 } from "node:os";
43228
44056
  async function probeOllamaAlive(baseUrl) {
43229
44057
  const cached2 = _ollamaProbeCache.get(baseUrl);
43230
44058
  if (cached2 && Date.now() - cached2.checkedAt < OLLAMA_PROBE_TTL_MS) {
@@ -43247,7 +44075,7 @@ async function probeOllamaAlive(baseUrl) {
43247
44075
  return alive;
43248
44076
  }
43249
44077
  function ollamaDefaultModelForTier(tier, ramBytesOverride) {
43250
- const ramBytes = ramBytesOverride ?? totalmem();
44078
+ const ramBytes = ramBytesOverride ?? totalmem2();
43251
44079
  const gb = ramBytes / 1024 ** 3;
43252
44080
  if (gb >= 8) {
43253
44081
  return tier === "fast" || tier === "local" ? "gemma4:e2b" : "gemma4:e4b";
@@ -43371,7 +44199,7 @@ async function selectBestProvisioned(role, opts) {
43371
44199
  let model;
43372
44200
  if (winner.id === "ollama") {
43373
44201
  const ollamaProfile2 = await getProviderProfile2("ollama");
43374
- const ramBytes = totalmem();
44202
+ const ramBytes = totalmem2();
43375
44203
  const gb = ramBytes / 1024 ** 3;
43376
44204
  if (gb >= 8) {
43377
44205
  model = (winner.tier === "fast" || taskTier === "fast" ? ollamaProfile2?.defaultAuxModel : ollamaProfile2?.defaultModel) ?? ollamaDefaultModelForTier(winner.tier);
@@ -43773,7 +44601,7 @@ __export(catalog_resolver_exports, {
43773
44601
  resolveCatalogEntry: () => resolveCatalogEntry
43774
44602
  });
43775
44603
  import { readFileSync as readFileSync17 } from "node:fs";
43776
- import { dirname as dirname11, join as join30 } from "node:path";
44604
+ import { dirname as dirname11, join as join32 } from "node:path";
43777
44605
  import { fileURLToPath as fileURLToPath3 } from "node:url";
43778
44606
  async function openCatalogAtPath(dbPath) {
43779
44607
  const handle = await openDualScopeDbAtPath("global", dbPath);
@@ -43783,7 +44611,7 @@ function loadShippedSeed() {
43783
44611
  if (_seed !== void 0) return _seed;
43784
44612
  try {
43785
44613
  const thisDir = dirname11(fileURLToPath3(import.meta.url));
43786
- const jsonPath = join30(thisDir, "curated-catalog.json");
44614
+ const jsonPath = join32(thisDir, "curated-catalog.json");
43787
44615
  _seed = JSON.parse(readFileSync17(jsonPath, "utf-8"));
43788
44616
  } catch (err) {
43789
44617
  logger5.warn(
@@ -44173,14 +45001,14 @@ var init_message_utils = __esm({
44173
45001
 
44174
45002
  // packages/core/src/llm/model-metadata.ts
44175
45003
  import { readFileSync as readFileSync18 } from "node:fs";
44176
- import { dirname as dirname12, join as join31 } from "node:path";
45004
+ import { dirname as dirname12, join as join33 } from "node:path";
44177
45005
  import { fileURLToPath as fileURLToPath4 } from "node:url";
44178
45006
  function getCuratedTable() {
44179
45007
  if (_curated !== void 0) {
44180
45008
  return _curated;
44181
45009
  }
44182
45010
  const thisDir = dirname12(fileURLToPath4(import.meta.url));
44183
- const jsonPath = join31(thisDir, "curated-models.json");
45011
+ const jsonPath = join33(thisDir, "curated-models.json");
44184
45012
  const raw = JSON.parse(readFileSync18(jsonPath, "utf-8"));
44185
45013
  _curated = raw.models;
44186
45014
  return _curated;
@@ -44259,7 +45087,7 @@ function storedToResolved(stored) {
44259
45087
  awsProfile: stored.metadata?.["awsProfile"] ?? null
44260
45088
  };
44261
45089
  }
44262
- function sleep(ms) {
45090
+ function sleep2(ms) {
44263
45091
  return new Promise((resolve5) => setTimeout(resolve5, ms));
44264
45092
  }
44265
45093
  function backoffMs(policy, attempt) {
@@ -44397,7 +45225,7 @@ var init_concrete_session = __esm({
44397
45225
  throw err;
44398
45226
  }
44399
45227
  lastErr = err;
44400
- await sleep(backoffMs(policy, attempt));
45228
+ await sleep2(backoffMs(policy, attempt));
44401
45229
  }
44402
45230
  }
44403
45231
  throw lastErr;
@@ -48081,7 +48909,7 @@ function normalizeOllamaToolCall(tc) {
48081
48909
  arguments: JSON.stringify(tc.function.arguments ?? {})
48082
48910
  };
48083
48911
  }
48084
- function sleep2(ms) {
48912
+ function sleep3(ms) {
48085
48913
  return new Promise((resolve5) => setTimeout(resolve5, ms));
48086
48914
  }
48087
48915
  var OLLAMA_DEFAULT_BASE_URL, MAX_RETRIES, INITIAL_BACKOFF_MS, RETRYABLE_STATUS_CODES, OllamaTransport;
@@ -48290,7 +49118,7 @@ var init_ollama2 = __esm({
48290
49118
  for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
48291
49119
  if (attempt > 0) {
48292
49120
  const delay = INITIAL_BACKOFF_MS * 2 ** (attempt - 1);
48293
- await sleep2(delay);
49121
+ await sleep3(delay);
48294
49122
  }
48295
49123
  let response;
48296
49124
  try {
@@ -76222,7 +77050,7 @@ var init_model_runner = __esm({
76222
77050
  });
76223
77051
 
76224
77052
  // packages/core/src/selfimprove/fix-gen.ts
76225
- import { writeFileSync as writeFileSync10 } from "node:fs";
77053
+ import { writeFileSync as writeFileSync11 } from "node:fs";
76226
77054
  import { resolve as resolvePath } from "node:path";
76227
77055
  import { cwd as processCwd } from "node:process";
76228
77056
 
@@ -76570,7 +77398,7 @@ async function generateFixPatch(opts) {
76570
77398
  }
76571
77399
  const diff = output.diff.endsWith("\n") ? output.diff : `${output.diff}
76572
77400
  `;
76573
- writeFileSync10(patchPath, diff, "utf8");
77401
+ writeFileSync11(patchPath, diff, "utf8");
76574
77402
  const bytes = Buffer.byteLength(diff, "utf8");
76575
77403
  logger8.info(
76576
77404
  { dhqId: request.dhqId, scenario: request.scenario, patchPath, bytes, model: output.model },