akm-cli 0.9.17-alpha.8 → 0.9.17-alpha.9

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 (104) hide show
  1. package/CHANGELOG.md +334 -0
  2. package/STABILITY.md +9 -8
  3. package/dist/assets/hints/cli-hints-full.md +6 -7
  4. package/dist/assets/improve-strategies/catchup.json +0 -3
  5. package/dist/assets/improve-strategies/consolidate.json +0 -1
  6. package/dist/assets/improve-strategies/default.json +1 -2
  7. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
  8. package/dist/assets/improve-strategies/quick.json +1 -2
  9. package/dist/assets/improve-strategies/reflect-distill.json +1 -2
  10. package/dist/assets/improve-strategies/thorough.json +0 -3
  11. package/dist/assets/prompts/consolidate-pair.md +20 -0
  12. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +17 -19
  13. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
  14. package/dist/assets/templates/html/health.html +3 -5
  15. package/dist/cli/retired-commands.js +1 -1
  16. package/dist/commands/health/archive-usage.js +98 -0
  17. package/dist/commands/health/data-dir-usage.js +25 -13
  18. package/dist/commands/health/html-report.js +1 -4
  19. package/dist/commands/health/improve-metrics.js +0 -25
  20. package/dist/commands/health/md-report.js +1 -6
  21. package/dist/commands/health/report-view-model.js +4 -14
  22. package/dist/commands/health/windows.js +0 -1
  23. package/dist/commands/health.js +13 -0
  24. package/dist/commands/improve/consolidate/continuity-check.js +137 -0
  25. package/dist/commands/improve/consolidate/pair-pass.js +791 -0
  26. package/dist/commands/improve/consolidate.js +38 -63
  27. package/dist/commands/improve/extract-prompt.js +1 -2
  28. package/dist/commands/improve/improve-cli.js +1 -1
  29. package/dist/commands/improve/improve-strategies.js +23 -5
  30. package/dist/commands/improve/improve.js +19 -30
  31. package/dist/commands/improve/ledger.js +3 -2
  32. package/dist/commands/improve/loop-stages.js +5 -85
  33. package/dist/commands/improve/memory/memory-belief.js +3 -1
  34. package/dist/commands/improve/memory/memory-improve.js +269 -11
  35. package/dist/commands/improve/planner.js +0 -5
  36. package/dist/commands/improve/preparation.js +20 -135
  37. package/dist/commands/improve/retrieval-scope.js +19 -4
  38. package/dist/commands/improve/salience.js +1 -14
  39. package/dist/commands/improve/stage.js +0 -1
  40. package/dist/commands/lint/base-linter.js +19 -11
  41. package/dist/commands/proposal/drain.js +8 -1
  42. package/dist/commands/proposal/proposal-cli.js +16 -2
  43. package/dist/commands/proposal/proposal-types.js +7 -0
  44. package/dist/commands/proposal/proposal.js +37 -6
  45. package/dist/commands/proposal/repository.js +613 -4
  46. package/dist/commands/proposal/validators/proposals.js +9 -0
  47. package/dist/commands/read/knowledge.js +3 -2
  48. package/dist/commands/read/show.js +0 -14
  49. package/dist/commands/sources/stash-cli.js +2 -2
  50. package/dist/core/bundle-rename.js +1 -7
  51. package/dist/core/config/config-schema.js +8 -1
  52. package/dist/core/config/config.js +23 -48
  53. package/dist/core/config/engine-semantics.js +0 -2
  54. package/dist/core/config/schema/improve-processes.js +17 -42
  55. package/dist/core/config/schema/index-config.js +5 -25
  56. package/dist/core/file-change.js +13 -5
  57. package/dist/core/improve-result.js +16 -5
  58. package/dist/core/improve-types.js +0 -1
  59. package/dist/core/loopback.js +7 -12
  60. package/dist/core/parse.js +13 -16
  61. package/dist/core/state/migrations.js +15 -0
  62. package/dist/core/time.js +0 -20
  63. package/dist/indexer/db/llm-cache.js +2 -2
  64. package/dist/indexer/ensure-index.js +2 -2
  65. package/dist/indexer/index-written-assets.js +2 -3
  66. package/dist/indexer/indexer.js +18 -418
  67. package/dist/indexer/passes/metadata.js +0 -19
  68. package/dist/indexer/walk/walker.js +3 -4
  69. package/dist/llm/client.js +8 -10
  70. package/dist/llm/embedders/remote.js +1 -2
  71. package/dist/llm/feature-gate.js +0 -5
  72. package/dist/output/shapes/helpers.js +20 -4
  73. package/dist/output/text/command-format.js +0 -8
  74. package/dist/output/text/proposal-format.js +47 -1
  75. package/dist/output/text/show-format.js +0 -20
  76. package/dist/scripts/akm-migrate-node.js +917 -950
  77. package/dist/scripts/akm-migrate.js +917 -950
  78. package/dist/setup/steps/connection.js +5 -6
  79. package/dist/setup/steps/platforms.js +2 -2
  80. package/dist/sources/providers/git-stash.js +55 -4
  81. package/dist/storage/repositories/improve-ledger-repository.js +48 -7
  82. package/dist/storage/repositories/index-entries-repository.js +4 -7
  83. package/dist/storage/repositories/index-entry-schema.js +4 -2
  84. package/dist/storage/repositories/index-llm-cache-repository.js +7 -26
  85. package/dist/storage/repositories/index-schema.js +55 -104
  86. package/dist/storage/repositories/proposals-repository.js +61 -0
  87. package/dist/storage/repositories/salience-repository.js +1 -19
  88. package/docs/reference/cli.md +16 -19
  89. package/docs/reference/configuration.md +21 -12
  90. package/docs/reference/data-and-telemetry.md +0 -1
  91. package/package.json +1 -1
  92. package/schemas/akm-config.json +0 -342
  93. package/dist/assets/improve-strategies/graph-refresh.json +0 -15
  94. package/dist/assets/prompts/contradiction-judge.md +0 -33
  95. package/dist/assets/prompts/graph-extract-system.md +0 -1
  96. package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
  97. package/dist/assets/prompts/metadata-enhance-system.md +0 -1
  98. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
  99. package/dist/indexer/db/graph-db.js +0 -399
  100. package/dist/indexer/graph/graph-extraction.js +0 -809
  101. package/dist/indexer/graph/graph-related.js +0 -131
  102. package/dist/indexer/graph/graph-types.js +0 -4
  103. package/dist/llm/graph-extract.js +0 -892
  104. package/dist/llm/metadata-enhance.js +0 -95
@@ -27255,7 +27255,8 @@ var STATE_MIGRATION_SAFETY_BY_ID = Object.freeze({
27255
27255
  "025-task-history-vocabulary-backfill": "data-preserving-rebuild",
27256
27256
  "026-proposals-strip-legacy-fragment-refs": "data-preserving-rebuild",
27257
27257
  "027-extract-sessions-seen-harness-rename": "data-preserving-rebuild",
27258
- "028-improve-ledger": "historical-destructive"
27258
+ "028-improve-ledger": "historical-destructive",
27259
+ "029-improve-ledger-content-hash": "additive"
27259
27260
  });
27260
27261
  var STATE_MIGRATIONS = [
27261
27262
  {
@@ -27993,6 +27994,12 @@ var STATE_MIGRATIONS = [
27993
27994
  DROP TABLE IF EXISTS improve_cycle_metrics;
27994
27995
  DROP TABLE IF EXISTS canary_queries;
27995
27996
  `
27997
+ },
27998
+ {
27999
+ id: "029-improve-ledger-content-hash",
28000
+ up: `
28001
+ ALTER TABLE improve_ledger ADD COLUMN content_hash TEXT DEFAULT NULL;
28002
+ `
27996
28003
  }
27997
28004
  ];
27998
28005
  assertMigrationRegistry(STATE_MIGRATIONS);
@@ -28224,7 +28231,6 @@ var BUILTIN_IMPROVE_STRATEGY_NAMES = [
28224
28231
  "default",
28225
28232
  "quick",
28226
28233
  "thorough",
28227
- "graph-refresh",
28228
28234
  "consolidate",
28229
28235
  "catchup",
28230
28236
  "reflect-distill",
@@ -28235,7 +28241,6 @@ var IMPROVE_PROCESS_ENGINE_CAPABILITIES = {
28235
28241
  distill: "llm",
28236
28242
  consolidate: "llm",
28237
28243
  memoryInference: "llm",
28238
- graphExtraction: "llm",
28239
28244
  extract: "llm",
28240
28245
  validation: "llm",
28241
28246
  triage: "runner",
@@ -28322,7 +28327,6 @@ var INTERESTING_DELTA_PATHS = [
28322
28327
  "improve.memoryInference.written",
28323
28328
  "improve.memoryInference.yieldRate",
28324
28329
  "improve.memoryInference.skippedNoFacts",
28325
- "improve.graphExtraction.failures",
28326
28330
  "improve.autoAccept.promoted",
28327
28331
  "improve.autoAccept.validationFailed",
28328
28332
  "improve.coverage.acceptedProposals",
@@ -28369,13 +28373,12 @@ function renderRunsDetailMd(runs) {
28369
28373
  "distill_q/llm-fail/judge/validator/cfg/skip",
28370
28374
  "cons_proc/promo/merge/del",
28371
28375
  "mem_cons/written/skip",
28372
- "graph_f/e/r",
28373
28376
  "orphans",
28374
28377
  "lint_f/fl",
28375
28378
  "result_status"
28376
28379
  ];
28377
28380
  const rows = runs.map((r) => {
28378
- const totalActions = r.actions.reflect.ok + r.actions.reflect.failed + r.actions.reflect.cooldown + r.actions.reflect.skipped + r.actions.distill.queued + r.actions.distill.llmFailed + r.actions.distill.judgeRejected + r.actions.distill.validatorRejected + r.actions.distill.configDisabled + r.actions.distill.skipped + r.actions.memoryPrune + r.actions.memoryInference + r.actions.graphExtraction + r.actions.error;
28381
+ const totalActions = r.actions.reflect.ok + r.actions.reflect.failed + r.actions.reflect.cooldown + r.actions.reflect.skipped + r.actions.distill.queued + r.actions.distill.llmFailed + r.actions.distill.judgeRejected + r.actions.distill.validatorRejected + r.actions.distill.configDisabled + r.actions.distill.skipped + r.actions.memoryPrune + r.actions.memoryInference + r.actions.error;
28379
28382
  return [
28380
28383
  r.startedAt,
28381
28384
  String(r.ok),
@@ -28385,7 +28388,6 @@ function renderRunsDetailMd(runs) {
28385
28388
  `${r.actions.distill.queued}/${r.actions.distill.llmFailed}/${r.actions.distill.judgeRejected}/${r.actions.distill.validatorRejected}/${r.actions.distill.configDisabled}/${r.actions.distill.skipped}`,
28386
28389
  `${r.consolidation.processed}/${r.consolidation.promoted}/${r.consolidation.merged}/${r.consolidation.deleted}`,
28387
28390
  `${r.memoryInference.considered}/${r.memoryInference.written}/${r.memoryInference.skippedNoFacts}`,
28388
- `${r.graphExtraction.extractedFiles}/${r.graphExtraction.entities}/${r.graphExtraction.relations}`,
28389
28391
  String(r.orphansPurged),
28390
28392
  `${r.lintFixed}/${r.lintFlagged}`,
28391
28393
  r.resultStatus ?? "valid"
@@ -28400,8 +28402,6 @@ function renderWindowCompareMd(windows, deltas) {
28400
28402
  const badIfPositive = new Set([
28401
28403
  "improve.actions.reflect.failed",
28402
28404
  "improve.actions.distill.llmFailed",
28403
- "improve.graphExtraction.failures",
28404
- "improve.graphExtraction.nonArrayBatchFailures",
28405
28405
  "improve.wallTime.medianMs",
28406
28406
  "improve.wallTime.p95Ms",
28407
28407
  "improve.memoryInference.skippedNoFacts"
@@ -28522,7 +28522,11 @@ function shapeProposalProducerOutput(result, detail) {
28522
28522
  }
28523
28523
  function shapeProposalEntry(entry, detail) {
28524
28524
  if (detail === "brief") {
28525
- return pickFields(entry, ["id", "ref", "status", "source", "createdAt"]);
28525
+ const retirement = entry.retirement;
28526
+ return {
28527
+ ...pickFields(entry, ["id", "ref", "status", "source", "createdAt"]),
28528
+ ...retirement?.continuityRisk ? { continuityRisk: true } : {}
28529
+ };
28526
28530
  }
28527
28531
  if (detail === "normal") {
28528
28532
  return pickFields(entry, [
@@ -28535,7 +28539,8 @@ function shapeProposalEntry(entry, detail) {
28535
28539
  "updatedAt",
28536
28540
  "confidence",
28537
28541
  "gateDecision",
28538
- "review"
28542
+ "review",
28543
+ "retirement"
28539
28544
  ]);
28540
28545
  }
28541
28546
  return pickFields(entry, [
@@ -28549,7 +28554,11 @@ function shapeProposalEntry(entry, detail) {
28549
28554
  "confidence",
28550
28555
  "gateDecision",
28551
28556
  "payload",
28552
- "review"
28557
+ "review",
28558
+ "retirement",
28559
+ "retiredArchive",
28560
+ "promotionSource",
28561
+ "promotionSourceHash"
28553
28562
  ]);
28554
28563
  }
28555
28564
  function shapeProposalListOutput(result, detail) {
@@ -28796,7 +28805,6 @@ function shapeShowOutput(result, detail, shape = "human") {
28796
28805
  "workflowParameters",
28797
28806
  "steps",
28798
28807
  "keys",
28799
- "related",
28800
28808
  "links",
28801
28809
  ...FRAGMENT_PROVENANCE_FIELDS,
28802
28810
  ...FRAGMENT_CONTEXT_FIELDS
@@ -28818,7 +28826,6 @@ function shapeShowOutput(result, detail, shape = "human") {
28818
28826
  "run",
28819
28827
  "origin",
28820
28828
  "keys",
28821
- "related",
28822
28829
  "links",
28823
28830
  ...FRAGMENT_PROVENANCE_FIELDS,
28824
28831
  ...FRAGMENT_CONTEXT_FIELDS
@@ -28847,7 +28854,6 @@ function shapeShowOutput(result, detail, shape = "human") {
28847
28854
  "cwd",
28848
28855
  "activeRun",
28849
28856
  "keys",
28850
- "related",
28851
28857
  "links",
28852
28858
  ...FRAGMENT_PROVENANCE_FIELDS,
28853
28859
  ...FRAGMENT_CONTEXT_FIELDS,
@@ -29989,13 +29995,6 @@ Warnings (${warnings.length}):`;
29989
29995
  out += `
29990
29996
  - ${String(message)}`;
29991
29997
  }
29992
- const notices = Array.isArray(indexResult.notices) ? indexResult.notices : [];
29993
- for (const notice of notices) {
29994
- const severity = notice.severity === "info" ? "info" : "warning";
29995
- const field = typeof notice.field === "string" ? ` field=${notice.field}` : "";
29996
- out += `
29997
- notice[${severity}] ${notice.code} adapter=${notice.adapter}${field}` + (notice.message ? `: ${notice.message}` : "");
29998
- }
29999
29998
  const verification = indexResult.verification;
30000
29999
  if (verification?.ok === false && verification.message) {
30001
30000
  out += `
@@ -30410,7 +30409,10 @@ Generate one with \`akm improve <ref>\` or \`akm proposal new <type> <name> --ta
30410
30409
  const created = String(p.createdAt);
30411
30410
  const gate = formatGateDecisionSummary(p.gateDecision);
30412
30411
  const gateSuffix = gate ? ` ${gate}` : "";
30413
- lines.push(`${id} [${status}] ${ref} source=${source} ${created}${gateSuffix}`);
30412
+ const retirement = p.retirement;
30413
+ const flagged = p.continuityRisk === true || Boolean(retirement?.continuityRisk);
30414
+ const continuitySuffix = flagged ? " ⚠ continuity-risk" : "";
30415
+ lines.push(`${id} [${status}] ${ref} source=${source} ${created}${gateSuffix}${continuitySuffix}`);
30414
30416
  }
30415
30417
  return lines.join(`
30416
30418
  `).trimEnd();
@@ -30450,6 +30452,30 @@ function formatProposalShowPlain(r) {
30450
30452
  if (review.decidedAt)
30451
30453
  lines.push(`review.decidedAt: ${String(review.decidedAt)}`);
30452
30454
  }
30455
+ const retirement = p.retirement;
30456
+ if (retirement) {
30457
+ lines.push(`retire: ${String(retirement.retiredRef)} -> ${String(retirement.successorRef)}`);
30458
+ lines.push(`retire.label: ${String(retirement.judgeLabel)} (cosine=${String(retirement.cosine)})`);
30459
+ lines.push(`retire.reason: ${String(retirement.judgeReason)}`);
30460
+ const continuityRisk = retirement.continuityRisk;
30461
+ if (continuityRisk) {
30462
+ const failingQueries = typeof continuityRisk.failingQueries === "number" ? continuityRisk.failingQueries : 0;
30463
+ const unverifiedQueries = typeof continuityRisk.unverifiedQueries === "number" ? continuityRisk.unverifiedQueries : 0;
30464
+ const summary = [];
30465
+ if (failingQueries > 0) {
30466
+ summary.push(`${failingQueries} of the retired asset's own quer${failingQueries === 1 ? "y" : "ies"} would not have found the successor top 10`);
30467
+ }
30468
+ if (unverifiedQueries > 0) {
30469
+ summary.push(`${unverifiedQueries} quer${unverifiedQueries === 1 ? "y" : "ies"} unverified (search failed or used the keyword-only fallback)`);
30470
+ }
30471
+ lines.push(`retire.continuityRisk: ${summary.join("; ")} — excluded from bulk accept`);
30472
+ const ranks = Array.isArray(continuityRisk.ranks) ? continuityRisk.ranks : [];
30473
+ for (const rank of ranks) {
30474
+ const successorRank = rank.successorRank === null || rank.successorRank === undefined ? "absent from top 10" : `#${String(rank.successorRank)}`;
30475
+ lines.push(` - "${String(rank.query)}": retired #${String(rank.retiredRank)}, successor ${successorRank}`);
30476
+ }
30477
+ }
30478
+ }
30453
30479
  const validation = r.validation;
30454
30480
  if (validation) {
30455
30481
  const findings = Array.isArray(validation.findings) ? validation.findings : [];
@@ -30843,19 +30869,6 @@ function formatShowPlain(r, detail) {
30843
30869
  if (r.schemaVersion !== undefined)
30844
30870
  lines.push(`schemaVersion: ${String(r.schemaVersion)}`);
30845
30871
  }
30846
- const related = typeof r.related === "object" && r.related !== null ? r.related : undefined;
30847
- const relatedHits = related && Array.isArray(related.hits) ? related.hits : [];
30848
- if (related) {
30849
- lines.push("");
30850
- lines.push(`related: ${String(related.total ?? relatedHits.length)}`);
30851
- for (const hit of relatedHits) {
30852
- lines.push(` - ${String(hit.type ?? "?")}: ${formatRelatedLabel(hit)}`);
30853
- const shared = Array.isArray(hit.sharedEntities) ? hit.sharedEntities.map(String) : [];
30854
- if (shared.length > 0)
30855
- lines.push(` shared: ${shared.join(", ")}`);
30856
- lines.push(` relationCount: ${String(hit.relationCount ?? 0)}`);
30857
- }
30858
- }
30859
30872
  const links = typeof r.links === "object" && r.links !== null ? r.links : undefined;
30860
30873
  if (links) {
30861
30874
  lines.push("");
@@ -30905,13 +30918,6 @@ function formatShowPlain(r, detail) {
30905
30918
  return lines.length > 0 ? lines.join(`
30906
30919
  `) : null;
30907
30920
  }
30908
- function formatRelatedLabel(hit) {
30909
- const ref = typeof hit.ref === "string" ? hit.ref : undefined;
30910
- if (ref)
30911
- return ref;
30912
- const pathValue = typeof hit.path === "string" ? hit.path : "?";
30913
- return pathValue.split("/").pop() ?? pathValue;
30914
- }
30915
30921
  // src/output/text/workflow-format.ts
30916
30922
  function formatWorkflowListPlain(result) {
30917
30923
  const runs = Array.isArray(result.runs) ? result.runs : [];
@@ -31233,9 +31239,6 @@ var catchup_default = {
31233
31239
  memoryInference: {
31234
31240
  enabled: false
31235
31241
  },
31236
- graphExtraction: {
31237
- enabled: false
31238
- },
31239
31242
  extract: {
31240
31243
  enabled: false
31241
31244
  },
@@ -31267,7 +31270,6 @@ var consolidate_default = {
31267
31270
  distill: { enabled: false },
31268
31271
  consolidate: { enabled: true, allowedTypes: ["memory"], maxChunkSize: 25 },
31269
31272
  memoryInference: { enabled: false },
31270
- graphExtraction: { enabled: false },
31271
31273
  extract: { enabled: false },
31272
31274
  triage: { enabled: false },
31273
31275
  validation: { enabled: false },
@@ -31277,7 +31279,7 @@ var consolidate_default = {
31277
31279
  };
31278
31280
  // src/assets/improve-strategies/default.json
31279
31281
  var default_default = {
31280
- description: "Standard improve pass — reflect, distill, advisory consolidation, graph extraction, and validation. Memory inference is listed below but only runs when experimental.improveAutonomy is set; improve-stage extract and proactive maintenance off.",
31282
+ description: "Standard improve pass — reflect, distill, consolidation (promotion plus the reviewed pair-pass retire/supersede proposals), and validation. Memory inference is listed below but only runs when experimental.improveAutonomy is set; improve-stage extract and proactive maintenance off.",
31281
31283
  processes: {
31282
31284
  reflect: {
31283
31285
  enabled: true,
@@ -31287,7 +31289,6 @@ var default_default = {
31287
31289
  distill: { enabled: true, allowedTypes: ["memory"], requirePlannedRefs: true },
31288
31290
  consolidate: { enabled: true, allowedTypes: ["memory"] },
31289
31291
  memoryInference: { enabled: true },
31290
- graphExtraction: { enabled: true },
31291
31292
  extract: { enabled: false, triage: { enabled: true, minScore: 2 } },
31292
31293
  validation: { enabled: true },
31293
31294
  proactiveMaintenance: { enabled: false, dueDays: 30, maxPerRun: 15 },
@@ -31295,25 +31296,9 @@ var default_default = {
31295
31296
  },
31296
31297
  sync: { enabled: true, push: true }
31297
31298
  };
31298
- // src/assets/improve-strategies/graph-refresh.json
31299
- var graph_refresh_default = {
31300
- description: "Full-corpus graph extraction pass — rebuilds graph relationships across all stash files. Disables all other sub-processes. Use via `akm improve --strategy graph-refresh` or the embedded `graph-refresh-weekly` task.",
31301
- processes: {
31302
- reflect: { enabled: false },
31303
- distill: { enabled: false },
31304
- consolidate: { enabled: false },
31305
- memoryInference: { enabled: false },
31306
- graphExtraction: { enabled: true, fullScan: true },
31307
- extract: { enabled: false },
31308
- triage: { enabled: false },
31309
- validation: { enabled: false },
31310
- proactiveMaintenance: { enabled: false }
31311
- },
31312
- sync: { enabled: true, push: true }
31313
- };
31314
31299
  // src/assets/improve-strategies/proactive-maintenance.json
31315
31300
  var proactive_maintenance_default = {
31316
- description: "Opt-in proactive-maintenance pass — reflect, distill, proposal triage (promote, high budget), and the proactive-maintenance lane (maxPerRun 100); consolidate/memoryInference/graphExtraction/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
31301
+ description: "Opt-in proactive-maintenance pass — reflect, distill, proposal triage (promote, high budget), and the proactive-maintenance lane (maxPerRun 100); consolidate/memoryInference/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
31317
31302
  processes: {
31318
31303
  reflect: {
31319
31304
  enabled: true,
@@ -31322,7 +31307,6 @@ var proactive_maintenance_default = {
31322
31307
  distill: { enabled: true, allowedTypes: ["memory"] },
31323
31308
  consolidate: { enabled: false },
31324
31309
  memoryInference: { enabled: false },
31325
- graphExtraction: { enabled: false },
31326
31310
  extract: { enabled: false },
31327
31311
  validation: { enabled: false },
31328
31312
  triage: {
@@ -31339,7 +31323,7 @@ var proactive_maintenance_default = {
31339
31323
  };
31340
31324
  // src/assets/improve-strategies/quick.json
31341
31325
  var quick_default = {
31342
- description: "Reflect-only pass — no extract, distill, consolidate, memoryInference, or graphExtraction.",
31326
+ description: "Reflect-only pass — no extract, distill, consolidate, or memoryInference.",
31343
31327
  processes: {
31344
31328
  reflect: {
31345
31329
  enabled: true,
@@ -31349,7 +31333,6 @@ var quick_default = {
31349
31333
  distill: { enabled: false },
31350
31334
  consolidate: { enabled: false },
31351
31335
  memoryInference: { enabled: false },
31352
- graphExtraction: { enabled: false },
31353
31336
  triage: { enabled: false },
31354
31337
  validation: { enabled: false },
31355
31338
  proactiveMaintenance: { enabled: false }
@@ -31358,7 +31341,7 @@ var quick_default = {
31358
31341
  };
31359
31342
  // src/assets/improve-strategies/reflect-distill.json
31360
31343
  var reflect_distill_default = {
31361
- description: "Reflect + distill pass — reflect, distill, memoryInference, and proposal triage (promote); proactiveMaintenance/consolidate/graphExtraction/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
31344
+ description: "Reflect + distill pass — reflect, distill, memoryInference, and proposal triage (promote); proactiveMaintenance/consolidate/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
31362
31345
  processes: {
31363
31346
  reflect: {
31364
31347
  enabled: true,
@@ -31367,7 +31350,6 @@ var reflect_distill_default = {
31367
31350
  distill: { enabled: true, allowedTypes: ["memory"], requirePlannedRefs: false },
31368
31351
  consolidate: { enabled: false },
31369
31352
  memoryInference: { enabled: true },
31370
- graphExtraction: { enabled: false },
31371
31353
  extract: {
31372
31354
  enabled: false,
31373
31355
  timeoutMs: 300000,
@@ -31408,9 +31390,6 @@ var thorough_default = {
31408
31390
  memoryInference: {
31409
31391
  enabled: true
31410
31392
  },
31411
- graphExtraction: {
31412
- enabled: true
31413
- },
31414
31393
  extract: {
31415
31394
  enabled: false,
31416
31395
  triage: {
@@ -31441,607 +31420,134 @@ var thorough_default = {
31441
31420
  }
31442
31421
  };
31443
31422
 
31444
- // src/core/config/config.ts
31445
- import fs10 from "node:fs";
31446
- import os2 from "node:os";
31447
- import path14 from "node:path";
31448
- import { isDeepStrictEqual } from "node:util";
31423
+ // node_modules/zod/v3/external.js
31424
+ var exports_external = {};
31425
+ __export(exports_external, {
31426
+ void: () => voidType,
31427
+ util: () => util,
31428
+ unknown: () => unknownType,
31429
+ union: () => unionType,
31430
+ undefined: () => undefinedType,
31431
+ tuple: () => tupleType,
31432
+ transformer: () => effectsType,
31433
+ symbol: () => symbolType,
31434
+ string: () => stringType,
31435
+ strictObject: () => strictObjectType,
31436
+ setErrorMap: () => setErrorMap,
31437
+ set: () => setType,
31438
+ record: () => recordType,
31439
+ quotelessJson: () => quotelessJson,
31440
+ promise: () => promiseType,
31441
+ preprocess: () => preprocessType,
31442
+ pipeline: () => pipelineType,
31443
+ ostring: () => ostring,
31444
+ optional: () => optionalType,
31445
+ onumber: () => onumber,
31446
+ oboolean: () => oboolean,
31447
+ objectUtil: () => objectUtil,
31448
+ object: () => objectType,
31449
+ number: () => numberType,
31450
+ nullable: () => nullableType,
31451
+ null: () => nullType,
31452
+ never: () => neverType,
31453
+ nativeEnum: () => nativeEnumType,
31454
+ nan: () => nanType,
31455
+ map: () => mapType,
31456
+ makeIssue: () => makeIssue,
31457
+ literal: () => literalType,
31458
+ lazy: () => lazyType,
31459
+ late: () => late,
31460
+ isValid: () => isValid,
31461
+ isDirty: () => isDirty,
31462
+ isAsync: () => isAsync,
31463
+ isAborted: () => isAborted,
31464
+ intersection: () => intersectionType,
31465
+ instanceof: () => instanceOfType,
31466
+ getParsedType: () => getParsedType,
31467
+ getErrorMap: () => getErrorMap,
31468
+ function: () => functionType,
31469
+ enum: () => enumType,
31470
+ effect: () => effectsType,
31471
+ discriminatedUnion: () => discriminatedUnionType,
31472
+ defaultErrorMap: () => en_default,
31473
+ datetimeRegex: () => datetimeRegex,
31474
+ date: () => dateType,
31475
+ custom: () => custom,
31476
+ coerce: () => coerce,
31477
+ boolean: () => booleanType,
31478
+ bigint: () => bigIntType,
31479
+ array: () => arrayType,
31480
+ any: () => anyType,
31481
+ addIssueToContext: () => addIssueToContext,
31482
+ ZodVoid: () => ZodVoid,
31483
+ ZodUnknown: () => ZodUnknown,
31484
+ ZodUnion: () => ZodUnion,
31485
+ ZodUndefined: () => ZodUndefined,
31486
+ ZodType: () => ZodType,
31487
+ ZodTuple: () => ZodTuple,
31488
+ ZodTransformer: () => ZodEffects,
31489
+ ZodSymbol: () => ZodSymbol,
31490
+ ZodString: () => ZodString,
31491
+ ZodSet: () => ZodSet,
31492
+ ZodSchema: () => ZodType,
31493
+ ZodRecord: () => ZodRecord,
31494
+ ZodReadonly: () => ZodReadonly,
31495
+ ZodPromise: () => ZodPromise,
31496
+ ZodPipeline: () => ZodPipeline,
31497
+ ZodParsedType: () => ZodParsedType,
31498
+ ZodOptional: () => ZodOptional,
31499
+ ZodObject: () => ZodObject,
31500
+ ZodNumber: () => ZodNumber,
31501
+ ZodNullable: () => ZodNullable,
31502
+ ZodNull: () => ZodNull,
31503
+ ZodNever: () => ZodNever,
31504
+ ZodNativeEnum: () => ZodNativeEnum,
31505
+ ZodNaN: () => ZodNaN,
31506
+ ZodMap: () => ZodMap,
31507
+ ZodLiteral: () => ZodLiteral,
31508
+ ZodLazy: () => ZodLazy,
31509
+ ZodIssueCode: () => ZodIssueCode,
31510
+ ZodIntersection: () => ZodIntersection,
31511
+ ZodFunction: () => ZodFunction,
31512
+ ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
31513
+ ZodError: () => ZodError,
31514
+ ZodEnum: () => ZodEnum,
31515
+ ZodEffects: () => ZodEffects,
31516
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
31517
+ ZodDefault: () => ZodDefault,
31518
+ ZodDate: () => ZodDate,
31519
+ ZodCatch: () => ZodCatch,
31520
+ ZodBranded: () => ZodBranded,
31521
+ ZodBoolean: () => ZodBoolean,
31522
+ ZodBigInt: () => ZodBigInt,
31523
+ ZodArray: () => ZodArray,
31524
+ ZodAny: () => ZodAny,
31525
+ Schema: () => ZodType,
31526
+ ParseStatus: () => ParseStatus,
31527
+ OK: () => OK,
31528
+ NEVER: () => NEVER,
31529
+ INVALID: () => INVALID,
31530
+ EMPTY_PATH: () => EMPTY_PATH,
31531
+ DIRTY: () => DIRTY,
31532
+ BRAND: () => BRAND
31533
+ });
31449
31534
 
31450
- // src/core/extra-params.ts
31451
- var EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS = [
31452
- "model",
31453
- "messages",
31454
- "temperature",
31455
- "maxtokens",
31456
- "responseformat",
31457
- "stream",
31458
- "streamoptions",
31459
- "enablethinking",
31460
- "reasoningeffort",
31461
- "chattemplatekwargs"
31462
- ];
31463
- var EXTRA_PARAMS_CREDENTIAL_KEYS = [
31464
- "authorization",
31465
- "headers",
31466
- "apikey",
31467
- "token",
31468
- "password",
31469
- "secret",
31470
- "cookie",
31471
- "setcookie"
31472
- ];
31473
- var PROTECTED_TOP_LEVEL_KEYS = new Set(EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS);
31474
- var CREDENTIAL_KEYS = new Set(EXTRA_PARAMS_CREDENTIAL_KEYS);
31475
- var LEGACY_EXTRA_PARAMS_FIELD = {
31476
- model: "model",
31477
- temperature: "temperature",
31478
- maxtokens: "maxTokens",
31479
- enablethinking: "enableThinking",
31480
- reasoningeffort: "reasoningEffort"
31481
- };
31482
- var LIFTABLE_EXTRA_PARAMS_KEYS = new Set(["temperature", "maxtokens", "enablethinking", "reasoningeffort"]);
31483
- var EXTRA_PARAMS_NO_FIELD_REMEDY = {
31484
- messages: "AKM builds the request messages internally — remove it from extraParams",
31485
- responseformat: "AKM controls the response format internally — remove it from extraParams",
31486
- stream: "AKM controls streaming internally — remove it from extraParams",
31487
- streamoptions: "AKM controls streaming internally — remove it from extraParams",
31488
- chattemplatekwargs: "set engines.<name>.enableThinking instead of chat_template_kwargs.enable_thinking"
31489
- };
31490
- function protectedKeyRemedy(normalized) {
31491
- const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
31492
- if (field) {
31493
- const note = normalized === "reasoningeffort" ? " (moved to a first-class field in 0.9.2)" : "";
31494
- return `set engines.<name>.${field} instead${note}`;
31495
- }
31496
- return EXTRA_PARAMS_NO_FIELD_REMEDY[normalized];
31497
- }
31498
- function normalizeExtraParamKey(key) {
31499
- return key.toLowerCase().replace(/[^a-z0-9]/g, "");
31500
- }
31501
- function validateExtraParams(value) {
31502
- if (!value || typeof value !== "object" || Array.isArray(value)) {
31503
- return [{ path: [], message: "must be an object" }];
31535
+ // node_modules/zod/v3/helpers/util.js
31536
+ var util;
31537
+ (function(util2) {
31538
+ util2.assertEqual = (_) => {};
31539
+ function assertIs(_arg) {}
31540
+ util2.assertIs = assertIs;
31541
+ function assertNever2(_x) {
31542
+ throw new Error;
31504
31543
  }
31505
- const issues = [];
31506
- const seen = new WeakSet;
31507
- const visit2 = (entry, path12) => {
31508
- if (Array.isArray(entry)) {
31509
- if (seen.has(entry))
31510
- return;
31511
- seen.add(entry);
31512
- entry.forEach((child, index) => {
31513
- visit2(child, [...path12, index]);
31514
- });
31515
- return;
31516
- }
31517
- if (!entry || typeof entry !== "object")
31518
- return;
31519
- if (seen.has(entry))
31520
- return;
31521
- seen.add(entry);
31522
- for (const [key, child] of Object.entries(entry)) {
31523
- const normalized = normalizeExtraParamKey(key);
31524
- if (path12.length === 0 && PROTECTED_TOP_LEVEL_KEYS.has(normalized)) {
31525
- const remedy = protectedKeyRemedy(normalized);
31526
- issues.push({
31527
- path: [key],
31528
- message: remedy ? `${key} is protected by AKM — ${remedy}.` : `${key} is protected by AKM`
31529
- });
31530
- }
31531
- if (CREDENTIAL_KEYS.has(normalized)) {
31532
- issues.push({ path: [...path12, key], message: `${key} cannot carry credentials` });
31533
- }
31534
- visit2(child, [...path12, key]);
31544
+ util2.assertNever = assertNever2;
31545
+ util2.arrayToEnum = (items) => {
31546
+ const obj = {};
31547
+ for (const item of items) {
31548
+ obj[item] = item;
31535
31549
  }
31536
- };
31537
- visit2(value, []);
31538
- return issues;
31539
- }
31540
- function formatExtraParamsIssue(label, issue) {
31541
- const suffix = issue.path.map((part) => typeof part === "number" ? `[${part}]` : `.${part}`).join("");
31542
- return `${label}${suffix} ${issue.message}`;
31543
- }
31544
- function liftLegacyEngineExtraParams(raw) {
31545
- const lifted = [];
31546
- const conflicts = [];
31547
- const rawEngines = raw.engines;
31548
- if (!isRecord(rawEngines)) {
31549
- return { config: raw, lifted, conflicts };
31550
- }
31551
- const engines = {};
31552
- let anyEngineChanged = false;
31553
- for (const [name, engineValue] of Object.entries(rawEngines)) {
31554
- if (!isRecord(engineValue) || !isRecord(engineValue.extraParams)) {
31555
- engines[name] = engineValue;
31556
- continue;
31557
- }
31558
- const engine = { ...engineValue };
31559
- const extraParams = { ...engineValue.extraParams };
31560
- let engineChanged = false;
31561
- for (const [rawKey, value] of Object.entries(engineValue.extraParams)) {
31562
- const normalized = normalizeExtraParamKey(rawKey);
31563
- if (!LIFTABLE_EXTRA_PARAMS_KEYS.has(normalized))
31564
- continue;
31565
- const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
31566
- if (!field)
31567
- continue;
31568
- const existing = engine[field];
31569
- if (existing !== undefined && existing !== value) {
31570
- conflicts.push({ engine: name, key: rawKey, field, extraParamsValue: value, fieldValue: existing });
31571
- continue;
31572
- }
31573
- delete extraParams[rawKey];
31574
- engineChanged = true;
31575
- if (existing === value) {
31576
- lifted.push(`engines.${name}.extraParams.${rawKey} is redundant — engines.${name}.${field} is already set to the same value; dropped the extraParams entry`);
31577
- continue;
31578
- }
31579
- engine[field] = value;
31580
- lifted.push(`engines.${name}.extraParams.${rawKey} -> engines.${name}.${field}`);
31581
- }
31582
- if (!engineChanged) {
31583
- engines[name] = engineValue;
31584
- continue;
31585
- }
31586
- anyEngineChanged = true;
31587
- if (Object.keys(extraParams).length > 0) {
31588
- engine.extraParams = extraParams;
31589
- } else {
31590
- delete engine.extraParams;
31591
- }
31592
- engines[name] = engine;
31593
- }
31594
- if (!anyEngineChanged) {
31595
- return { config: raw, lifted, conflicts };
31596
- }
31597
- return { config: { ...raw, engines }, lifted, conflicts };
31598
- }
31599
-
31600
- // src/core/config/config-io.ts
31601
- import fs8 from "node:fs";
31602
- import path12 from "node:path";
31603
-
31604
- // src/core/file-lock.ts
31605
- import { randomUUID } from "node:crypto";
31606
- import fs7 from "node:fs";
31607
- function readLockSnapshot(lockPath) {
31608
- let fd;
31609
- try {
31610
- fd = fs7.openSync(lockPath, "r");
31611
- } catch (err) {
31612
- if (err.code === "ENOENT")
31613
- return;
31614
- throw err;
31615
- }
31616
- try {
31617
- const rawContent = readTextFileDescriptorWithLimit(fd, MAX_LOCK_METADATA_BYTES, "Lock metadata", lockPath);
31618
- const stat = fs7.fstatSync(fd);
31619
- return {
31620
- rawContent,
31621
- identity: { dev: stat.dev, ino: stat.ino, size: stat.size, mtimeMs: stat.mtimeMs }
31622
- };
31623
- } finally {
31624
- fs7.closeSync(fd);
31625
- }
31626
- }
31627
- function sameIdentity(left, right) {
31628
- return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs;
31629
- }
31630
- function releaseLockRaw(lockPath) {
31631
- try {
31632
- fs7.unlinkSync(lockPath);
31633
- } catch {}
31634
- }
31635
- function tryAcquireLockSync(lockPath, payload) {
31636
- try {
31637
- fs7.writeFileSync(lockPath, payload, { flag: "wx" });
31638
- } catch (err) {
31639
- if (err.code === "EEXIST")
31640
- return;
31641
- throw err;
31642
- }
31643
- let snapshot;
31644
- try {
31645
- snapshot = readLockSnapshot(lockPath);
31646
- } catch (error2) {
31647
- releaseLockRaw(lockPath);
31648
- throw error2;
31649
- }
31650
- if (!snapshot) {
31651
- releaseLockRaw(lockPath);
31652
- throw new Error(`Could not read newly acquired lock at ${lockPath}.`);
31653
- }
31654
- return { lockPath, ...snapshot };
31655
- }
31656
- function launcherPidFromEnv() {
31657
- const raw = process.env.AKM_LAUNCHER_PID;
31658
- if (!raw)
31659
- return;
31660
- const pid = Number.parseInt(raw, 10);
31661
- return Number.isInteger(pid) && pid > 0 ? pid : undefined;
31662
- }
31663
- function createLockPayload(metadata = {}) {
31664
- const launcherPid = launcherPidFromEnv();
31665
- return JSON.stringify({
31666
- ...metadata,
31667
- pid: process.pid,
31668
- ...launcherPid !== undefined ? { launcherPid } : {},
31669
- lockId: randomUUID()
31670
- });
31671
- }
31672
- function probeLock(lockPath, opts) {
31673
- let snapshot;
31674
- try {
31675
- snapshot = readLockSnapshot(lockPath);
31676
- } catch (error2) {
31677
- const code = error2?.code;
31678
- if (code === "EACCES" || code === "EPERM")
31679
- return { state: "inaccessible", code };
31680
- return { state: "stale", reason: "unreadable" };
31681
- }
31682
- if (!snapshot)
31683
- return { state: "absent" };
31684
- const { rawContent, identity: identity3 } = snapshot;
31685
- const ageMs = Date.now() - identity3.mtimeMs;
31686
- const { holderPid, launcherPid } = extractLockIdentity(rawContent);
31687
- if (holderPid === undefined) {
31688
- return { state: "stale", reason: "invalid_pid", ageMs, rawContent, identity: identity3 };
31689
- }
31690
- if (!isProcessAlive(holderPid)) {
31691
- return { state: "stale", reason: "pid_dead", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
31692
- }
31693
- if (opts?.staleAfterMs !== undefined && ageMs > opts.staleAfterMs) {
31694
- return { state: "stale", reason: "age_exceeded", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
31695
- }
31696
- return { state: "held", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
31697
- }
31698
- function reclaimStaleLock(lockPath, probe, options) {
31699
- if (probe.rawContent === undefined || probe.identity === undefined)
31700
- return false;
31701
- const expectedContent = probe.rawContent;
31702
- const expectedIdentity = probe.identity;
31703
- let current;
31704
- try {
31705
- current = readLockSnapshot(lockPath);
31706
- } catch {
31707
- return false;
31708
- }
31709
- if (!current || current.rawContent !== expectedContent || !sameIdentity(current.identity, expectedIdentity)) {
31710
- return false;
31711
- }
31712
- const quarantinePath = `${lockPath}.stale-${process.pid}-${randomUUID()}`;
31713
- try {
31714
- fs7.renameSync(lockPath, quarantinePath);
31715
- } catch (err) {
31716
- if (err.code === "ENOENT")
31717
- return false;
31718
- throw err;
31719
- }
31720
- let quarantined;
31721
- try {
31722
- quarantined = readLockSnapshot(quarantinePath);
31723
- } catch {
31724
- quarantined = undefined;
31725
- }
31726
- if (!quarantined || quarantined.rawContent !== expectedContent || !sameIdentity(quarantined.identity, expectedIdentity)) {
31727
- try {
31728
- fs7.linkSync(quarantinePath, lockPath);
31729
- } catch (err) {
31730
- if (err.code !== "EEXIST")
31731
- throw err;
31732
- }
31733
- releaseLockRaw(quarantinePath);
31734
- return false;
31735
- }
31736
- options?.afterQuarantineVerified?.();
31737
- try {
31738
- fs7.unlinkSync(quarantinePath);
31739
- return true;
31740
- } catch (err) {
31741
- if (err.code === "ENOENT")
31742
- return false;
31743
- throw err;
31744
- }
31745
- }
31746
- function releaseLock(ownership) {
31747
- const { lockPath } = ownership;
31748
- let current;
31749
- try {
31750
- current = readLockSnapshot(lockPath);
31751
- } catch {
31752
- return;
31753
- }
31754
- if (current && current.rawContent === ownership.rawContent && sameIdentity(current.identity, ownership.identity)) {
31755
- releaseLockRaw(lockPath);
31756
- }
31757
- }
31758
- function extractLockIdentity(content) {
31759
- const trimmed = content.trim();
31760
- if (!trimmed)
31761
- return {};
31762
- if (trimmed.startsWith("{")) {
31763
- try {
31764
- const parsed = JSON.parse(trimmed);
31765
- const pid2 = typeof parsed.pid === "number" ? parsed.pid : Number.NaN;
31766
- const rawLauncherPid = typeof parsed.launcherPid === "number" ? parsed.launcherPid : Number.NaN;
31767
- return {
31768
- holderPid: Number.isInteger(pid2) && pid2 > 0 ? pid2 : undefined,
31769
- launcherPid: Number.isInteger(rawLauncherPid) && rawLauncherPid > 0 ? rawLauncherPid : undefined
31770
- };
31771
- } catch {
31772
- return {};
31773
- }
31774
- }
31775
- const pid = Number.parseInt(trimmed, 10);
31776
- return { holderPid: Number.isInteger(pid) && pid > 0 ? pid : undefined };
31777
- }
31778
-
31779
- // src/core/config/config-io.ts
31780
- function readConfigText(configPath) {
31781
- try {
31782
- return readTextFile(configPath, "Config file");
31783
- } catch (err) {
31784
- if (err.code === "ENOENT")
31785
- return;
31786
- throw err;
31787
- }
31788
- }
31789
- function parseConfigText(text, sourcePath) {
31790
- const stripped = stripJsonComments(text);
31791
- const where = sourcePath ? ` at ${sourcePath}` : "";
31792
- let parsed;
31793
- try {
31794
- parsed = JSON.parse(stripped);
31795
- } catch (err) {
31796
- const detail = err instanceof Error ? err.message : String(err);
31797
- throw new ConfigError(`Failed to parse config JSON${where}: ${detail}`, "INVALID_CONFIG_FILE", "Edit the file to fix the JSON syntax error. Comments (// and /* */) are allowed; trailing commas are not.");
31798
- }
31799
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
31800
- throw new ConfigError(`Config file${where} must contain a JSON object at the root, got ${describeJsonRoot(parsed)}.`, "INVALID_CONFIG_FILE");
31801
- }
31802
- return parsed;
31803
- }
31804
- function describeJsonRoot(value) {
31805
- if (value === null)
31806
- return "null";
31807
- if (Array.isArray(value))
31808
- return "an array";
31809
- if (typeof value === "string")
31810
- return "a string";
31811
- if (typeof value === "number")
31812
- return "a number";
31813
- if (typeof value === "boolean")
31814
- return "a boolean";
31815
- return typeof value;
31816
- }
31817
- function writeConfigAtomic(configPath, config) {
31818
- writeFileAtomic(configPath, `${JSON.stringify(config, null, 2)}
31819
- `);
31820
- }
31821
- var MAX_CONFIG_BACKUPS = 5;
31822
- function backupExistingConfig(configPath, now = new Date) {
31823
- if (!fs8.existsSync(configPath))
31824
- return;
31825
- const backupDir = path12.join(getCacheDir(), "config-backups");
31826
- fs8.mkdirSync(backupDir, { recursive: true, mode: 448 });
31827
- fs8.chmodSync(backupDir, 448);
31828
- const timestamp = now.toISOString().replace(/[.:]/g, "-");
31829
- let sequence = 0;
31830
- let timestamped;
31831
- while (true) {
31832
- timestamped = path12.join(backupDir, `config-${timestamp}${sequence === 0 ? "" : `-${sequence}`}.json`);
31833
- try {
31834
- fs8.copyFileSync(configPath, timestamped, fs8.constants.COPYFILE_EXCL);
31835
- break;
31836
- } catch (error2) {
31837
- if (error2.code !== "EEXIST")
31838
- throw error2;
31839
- sequence++;
31840
- }
31841
- }
31842
- const latest = path12.join(backupDir, "config.latest.json");
31843
- fs8.copyFileSync(configPath, latest);
31844
- fs8.chmodSync(timestamped, 384);
31845
- fs8.chmodSync(latest, 384);
31846
- pruneOldBackups(backupDir);
31847
- return { timestamped, latest };
31848
- }
31849
- function pruneOldBackups(backupDir) {
31850
- pruneToNewest(backupDir, MAX_CONFIG_BACKUPS, (entry) => entry.isFile() && isTimestampedConfigBackup(entry.name));
31851
- }
31852
- function isTimestampedConfigBackup(name) {
31853
- return name.startsWith("config-") && name.endsWith(".json") && name !== "config.latest.json";
31854
- }
31855
- function pruneToNewest(dir, keep, select) {
31856
- let entries;
31857
- try {
31858
- entries = fs8.readdirSync(dir, { withFileTypes: true });
31859
- } catch {
31860
- return;
31861
- }
31862
- const candidates = entries.filter(select).map((entry) => {
31863
- const full = path12.join(dir, entry.name);
31864
- let mtime = 0;
31865
- try {
31866
- mtime = fs8.statSync(full).mtimeMs;
31867
- } catch {}
31868
- return { path: full, mtime };
31869
- }).sort((a, b) => b.mtime - a.mtime);
31870
- for (const stale of candidates.slice(keep)) {
31871
- try {
31872
- fs8.rmSync(stale.path, { recursive: true, force: true });
31873
- } catch {}
31874
- }
31875
- }
31876
- function getConfigLockPath() {
31877
- return path12.join(getConfigDir(), "config.json.lck");
31878
- }
31879
- var CONFIG_LOCK_MAX_RETRIES = 40;
31880
- var CONFIG_LOCK_RETRY_DELAY_MS = 50;
31881
- function sleepSyncMs(ms) {
31882
- sleepSync(ms);
31883
- }
31884
- function acquireConfigLock() {
31885
- const lockPath = getConfigLockPath();
31886
- try {
31887
- fs8.mkdirSync(path12.dirname(lockPath), { recursive: true });
31888
- } catch {}
31889
- for (let attempt = 0;attempt < CONFIG_LOCK_MAX_RETRIES; attempt++) {
31890
- try {
31891
- const ownership = tryAcquireLockSync(lockPath, createLockPayload());
31892
- if (ownership) {
31893
- return () => releaseLock(ownership);
31894
- }
31895
- } catch (error2) {
31896
- throw new ConfigError(`Unable to acquire config lock at ${lockPath}: ${error2 instanceof Error ? error2.message : String(error2)}`, "INVALID_CONFIG_FILE");
31897
- }
31898
- const probe = probeLock(lockPath);
31899
- if (probe.state === "stale" && reclaimStaleLock(lockPath, probe)) {
31900
- continue;
31901
- }
31902
- if (attempt < CONFIG_LOCK_MAX_RETRIES - 1) {
31903
- sleepSyncMs(CONFIG_LOCK_RETRY_DELAY_MS);
31904
- }
31905
- }
31906
- throw new ConfigError(`Timed out waiting for config lock at ${lockPath}. Another AKM process may be updating config.`, "INVALID_CONFIG_FILE");
31907
- }
31908
- function withConfigLock(fn) {
31909
- const release = acquireConfigLock();
31910
- try {
31911
- return fn();
31912
- } finally {
31913
- release();
31914
- }
31915
- }
31916
-
31917
- // node_modules/zod/v3/external.js
31918
- var exports_external = {};
31919
- __export(exports_external, {
31920
- void: () => voidType,
31921
- util: () => util,
31922
- unknown: () => unknownType,
31923
- union: () => unionType,
31924
- undefined: () => undefinedType,
31925
- tuple: () => tupleType,
31926
- transformer: () => effectsType,
31927
- symbol: () => symbolType,
31928
- string: () => stringType,
31929
- strictObject: () => strictObjectType,
31930
- setErrorMap: () => setErrorMap,
31931
- set: () => setType,
31932
- record: () => recordType,
31933
- quotelessJson: () => quotelessJson,
31934
- promise: () => promiseType,
31935
- preprocess: () => preprocessType,
31936
- pipeline: () => pipelineType,
31937
- ostring: () => ostring,
31938
- optional: () => optionalType,
31939
- onumber: () => onumber,
31940
- oboolean: () => oboolean,
31941
- objectUtil: () => objectUtil,
31942
- object: () => objectType,
31943
- number: () => numberType,
31944
- nullable: () => nullableType,
31945
- null: () => nullType,
31946
- never: () => neverType,
31947
- nativeEnum: () => nativeEnumType,
31948
- nan: () => nanType,
31949
- map: () => mapType,
31950
- makeIssue: () => makeIssue,
31951
- literal: () => literalType,
31952
- lazy: () => lazyType,
31953
- late: () => late,
31954
- isValid: () => isValid,
31955
- isDirty: () => isDirty,
31956
- isAsync: () => isAsync,
31957
- isAborted: () => isAborted,
31958
- intersection: () => intersectionType,
31959
- instanceof: () => instanceOfType,
31960
- getParsedType: () => getParsedType,
31961
- getErrorMap: () => getErrorMap,
31962
- function: () => functionType,
31963
- enum: () => enumType,
31964
- effect: () => effectsType,
31965
- discriminatedUnion: () => discriminatedUnionType,
31966
- defaultErrorMap: () => en_default,
31967
- datetimeRegex: () => datetimeRegex,
31968
- date: () => dateType,
31969
- custom: () => custom,
31970
- coerce: () => coerce,
31971
- boolean: () => booleanType,
31972
- bigint: () => bigIntType,
31973
- array: () => arrayType,
31974
- any: () => anyType,
31975
- addIssueToContext: () => addIssueToContext,
31976
- ZodVoid: () => ZodVoid,
31977
- ZodUnknown: () => ZodUnknown,
31978
- ZodUnion: () => ZodUnion,
31979
- ZodUndefined: () => ZodUndefined,
31980
- ZodType: () => ZodType,
31981
- ZodTuple: () => ZodTuple,
31982
- ZodTransformer: () => ZodEffects,
31983
- ZodSymbol: () => ZodSymbol,
31984
- ZodString: () => ZodString,
31985
- ZodSet: () => ZodSet,
31986
- ZodSchema: () => ZodType,
31987
- ZodRecord: () => ZodRecord,
31988
- ZodReadonly: () => ZodReadonly,
31989
- ZodPromise: () => ZodPromise,
31990
- ZodPipeline: () => ZodPipeline,
31991
- ZodParsedType: () => ZodParsedType,
31992
- ZodOptional: () => ZodOptional,
31993
- ZodObject: () => ZodObject,
31994
- ZodNumber: () => ZodNumber,
31995
- ZodNullable: () => ZodNullable,
31996
- ZodNull: () => ZodNull,
31997
- ZodNever: () => ZodNever,
31998
- ZodNativeEnum: () => ZodNativeEnum,
31999
- ZodNaN: () => ZodNaN,
32000
- ZodMap: () => ZodMap,
32001
- ZodLiteral: () => ZodLiteral,
32002
- ZodLazy: () => ZodLazy,
32003
- ZodIssueCode: () => ZodIssueCode,
32004
- ZodIntersection: () => ZodIntersection,
32005
- ZodFunction: () => ZodFunction,
32006
- ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
32007
- ZodError: () => ZodError,
32008
- ZodEnum: () => ZodEnum,
32009
- ZodEffects: () => ZodEffects,
32010
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
32011
- ZodDefault: () => ZodDefault,
32012
- ZodDate: () => ZodDate,
32013
- ZodCatch: () => ZodCatch,
32014
- ZodBranded: () => ZodBranded,
32015
- ZodBoolean: () => ZodBoolean,
32016
- ZodBigInt: () => ZodBigInt,
32017
- ZodArray: () => ZodArray,
32018
- ZodAny: () => ZodAny,
32019
- Schema: () => ZodType,
32020
- ParseStatus: () => ParseStatus,
32021
- OK: () => OK,
32022
- NEVER: () => NEVER,
32023
- INVALID: () => INVALID,
32024
- EMPTY_PATH: () => EMPTY_PATH,
32025
- DIRTY: () => DIRTY,
32026
- BRAND: () => BRAND
32027
- });
32028
-
32029
- // node_modules/zod/v3/helpers/util.js
32030
- var util;
32031
- (function(util2) {
32032
- util2.assertEqual = (_) => {};
32033
- function assertIs(_arg) {}
32034
- util2.assertIs = assertIs;
32035
- function assertNever2(_x) {
32036
- throw new Error;
32037
- }
32038
- util2.assertNever = assertNever2;
32039
- util2.arrayToEnum = (items) => {
32040
- const obj = {};
32041
- for (const item of items) {
32042
- obj[item] = item;
32043
- }
32044
- return obj;
31550
+ return obj;
32045
31551
  };
32046
31552
  util2.getValidEnumValues = (obj) => {
32047
31553
  const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
@@ -32389,8 +31895,8 @@ function getErrorMap() {
32389
31895
  }
32390
31896
  // node_modules/zod/v3/helpers/parseUtil.js
32391
31897
  var makeIssue = (params) => {
32392
- const { data, path: path13, errorMaps, issueData } = params;
32393
- const fullPath = [...path13, ...issueData.path || []];
31898
+ const { data, path: path12, errorMaps, issueData } = params;
31899
+ const fullPath = [...path12, ...issueData.path || []];
32394
31900
  const fullIssue = {
32395
31901
  ...issueData,
32396
31902
  path: fullPath
@@ -32502,11 +32008,11 @@ var errorUtil;
32502
32008
 
32503
32009
  // node_modules/zod/v3/types.js
32504
32010
  class ParseInputLazyPath {
32505
- constructor(parent, value, path13, key) {
32011
+ constructor(parent, value, path12, key) {
32506
32012
  this._cachedPath = [];
32507
32013
  this.parent = parent;
32508
32014
  this.data = value;
32509
- this._path = path13;
32015
+ this._path = path12;
32510
32016
  this._key = key;
32511
32017
  }
32512
32018
  get path() {
@@ -35785,108 +35291,258 @@ function custom(check, _params = {}, fatal) {
35785
35291
  }
35786
35292
  });
35787
35293
  }
35788
- if (!r) {
35789
- const params = cleanParams(_params, data);
35790
- const _fatal = params.fatal ?? fatal ?? true;
35791
- ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
35294
+ if (!r) {
35295
+ const params = cleanParams(_params, data);
35296
+ const _fatal = params.fatal ?? fatal ?? true;
35297
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
35298
+ }
35299
+ return;
35300
+ });
35301
+ return ZodAny.create();
35302
+ }
35303
+ var late = {
35304
+ object: ZodObject.lazycreate
35305
+ };
35306
+ var ZodFirstPartyTypeKind;
35307
+ (function(ZodFirstPartyTypeKind2) {
35308
+ ZodFirstPartyTypeKind2["ZodString"] = "ZodString";
35309
+ ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";
35310
+ ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";
35311
+ ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";
35312
+ ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";
35313
+ ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";
35314
+ ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";
35315
+ ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";
35316
+ ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";
35317
+ ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";
35318
+ ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";
35319
+ ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";
35320
+ ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";
35321
+ ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";
35322
+ ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";
35323
+ ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";
35324
+ ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
35325
+ ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";
35326
+ ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";
35327
+ ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";
35328
+ ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";
35329
+ ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";
35330
+ ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";
35331
+ ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";
35332
+ ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";
35333
+ ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";
35334
+ ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";
35335
+ ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";
35336
+ ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";
35337
+ ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";
35338
+ ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";
35339
+ ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";
35340
+ ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";
35341
+ ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";
35342
+ ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";
35343
+ ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";
35344
+ })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
35345
+ var instanceOfType = (cls, params = {
35346
+ message: `Input not instance of ${cls.name}`
35347
+ }) => custom((data) => data instanceof cls, params);
35348
+ var stringType = ZodString.create;
35349
+ var numberType = ZodNumber.create;
35350
+ var nanType = ZodNaN.create;
35351
+ var bigIntType = ZodBigInt.create;
35352
+ var booleanType = ZodBoolean.create;
35353
+ var dateType = ZodDate.create;
35354
+ var symbolType = ZodSymbol.create;
35355
+ var undefinedType = ZodUndefined.create;
35356
+ var nullType = ZodNull.create;
35357
+ var anyType = ZodAny.create;
35358
+ var unknownType = ZodUnknown.create;
35359
+ var neverType = ZodNever.create;
35360
+ var voidType = ZodVoid.create;
35361
+ var arrayType = ZodArray.create;
35362
+ var objectType = ZodObject.create;
35363
+ var strictObjectType = ZodObject.strictCreate;
35364
+ var unionType = ZodUnion.create;
35365
+ var discriminatedUnionType = ZodDiscriminatedUnion.create;
35366
+ var intersectionType = ZodIntersection.create;
35367
+ var tupleType = ZodTuple.create;
35368
+ var recordType = ZodRecord.create;
35369
+ var mapType = ZodMap.create;
35370
+ var setType = ZodSet.create;
35371
+ var functionType = ZodFunction.create;
35372
+ var lazyType = ZodLazy.create;
35373
+ var literalType = ZodLiteral.create;
35374
+ var enumType = ZodEnum.create;
35375
+ var nativeEnumType = ZodNativeEnum.create;
35376
+ var promiseType = ZodPromise.create;
35377
+ var effectsType = ZodEffects.create;
35378
+ var optionalType = ZodOptional.create;
35379
+ var nullableType = ZodNullable.create;
35380
+ var preprocessType = ZodEffects.createWithPreprocess;
35381
+ var pipelineType = ZodPipeline.create;
35382
+ var ostring = () => stringType().optional();
35383
+ var onumber = () => numberType().optional();
35384
+ var oboolean = () => booleanType().optional();
35385
+ var coerce = {
35386
+ string: (arg) => ZodString.create({ ...arg, coerce: true }),
35387
+ number: (arg) => ZodNumber.create({ ...arg, coerce: true }),
35388
+ boolean: (arg) => ZodBoolean.create({
35389
+ ...arg,
35390
+ coerce: true
35391
+ }),
35392
+ bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }),
35393
+ date: (arg) => ZodDate.create({ ...arg, coerce: true })
35394
+ };
35395
+ var NEVER = INVALID;
35396
+ // src/core/extra-params.ts
35397
+ var EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS = [
35398
+ "model",
35399
+ "messages",
35400
+ "temperature",
35401
+ "maxtokens",
35402
+ "responseformat",
35403
+ "stream",
35404
+ "streamoptions",
35405
+ "enablethinking",
35406
+ "reasoningeffort",
35407
+ "chattemplatekwargs"
35408
+ ];
35409
+ var EXTRA_PARAMS_CREDENTIAL_KEYS = [
35410
+ "authorization",
35411
+ "headers",
35412
+ "apikey",
35413
+ "token",
35414
+ "password",
35415
+ "secret",
35416
+ "cookie",
35417
+ "setcookie"
35418
+ ];
35419
+ var PROTECTED_TOP_LEVEL_KEYS = new Set(EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS);
35420
+ var CREDENTIAL_KEYS = new Set(EXTRA_PARAMS_CREDENTIAL_KEYS);
35421
+ var LEGACY_EXTRA_PARAMS_FIELD = {
35422
+ model: "model",
35423
+ temperature: "temperature",
35424
+ maxtokens: "maxTokens",
35425
+ enablethinking: "enableThinking",
35426
+ reasoningeffort: "reasoningEffort"
35427
+ };
35428
+ var LIFTABLE_EXTRA_PARAMS_KEYS = new Set(["temperature", "maxtokens", "enablethinking", "reasoningeffort"]);
35429
+ var EXTRA_PARAMS_NO_FIELD_REMEDY = {
35430
+ messages: "AKM builds the request messages internally — remove it from extraParams",
35431
+ responseformat: "AKM controls the response format internally — remove it from extraParams",
35432
+ stream: "AKM controls streaming internally — remove it from extraParams",
35433
+ streamoptions: "AKM controls streaming internally — remove it from extraParams",
35434
+ chattemplatekwargs: "set engines.<name>.enableThinking instead of chat_template_kwargs.enable_thinking"
35435
+ };
35436
+ function protectedKeyRemedy(normalized) {
35437
+ const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
35438
+ if (field) {
35439
+ const note = normalized === "reasoningeffort" ? " (moved to a first-class field in 0.9.2)" : "";
35440
+ return `set engines.<name>.${field} instead${note}`;
35441
+ }
35442
+ return EXTRA_PARAMS_NO_FIELD_REMEDY[normalized];
35443
+ }
35444
+ function normalizeExtraParamKey(key) {
35445
+ return key.toLowerCase().replace(/[^a-z0-9]/g, "");
35446
+ }
35447
+ function validateExtraParams(value) {
35448
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
35449
+ return [{ path: [], message: "must be an object" }];
35450
+ }
35451
+ const issues = [];
35452
+ const seen = new WeakSet;
35453
+ const visit2 = (entry, path12) => {
35454
+ if (Array.isArray(entry)) {
35455
+ if (seen.has(entry))
35456
+ return;
35457
+ seen.add(entry);
35458
+ entry.forEach((child, index) => {
35459
+ visit2(child, [...path12, index]);
35460
+ });
35461
+ return;
35462
+ }
35463
+ if (!entry || typeof entry !== "object")
35464
+ return;
35465
+ if (seen.has(entry))
35466
+ return;
35467
+ seen.add(entry);
35468
+ for (const [key, child] of Object.entries(entry)) {
35469
+ const normalized = normalizeExtraParamKey(key);
35470
+ if (path12.length === 0 && PROTECTED_TOP_LEVEL_KEYS.has(normalized)) {
35471
+ const remedy = protectedKeyRemedy(normalized);
35472
+ issues.push({
35473
+ path: [key],
35474
+ message: remedy ? `${key} is protected by AKM — ${remedy}.` : `${key} is protected by AKM`
35475
+ });
35476
+ }
35477
+ if (CREDENTIAL_KEYS.has(normalized)) {
35478
+ issues.push({ path: [...path12, key], message: `${key} cannot carry credentials` });
35479
+ }
35480
+ visit2(child, [...path12, key]);
35481
+ }
35482
+ };
35483
+ visit2(value, []);
35484
+ return issues;
35485
+ }
35486
+ function formatExtraParamsIssue(label, issue) {
35487
+ const suffix = issue.path.map((part) => typeof part === "number" ? `[${part}]` : `.${part}`).join("");
35488
+ return `${label}${suffix} ${issue.message}`;
35489
+ }
35490
+ function liftLegacyEngineExtraParams(raw) {
35491
+ const lifted = [];
35492
+ const conflicts = [];
35493
+ const rawEngines = raw.engines;
35494
+ if (!isRecord(rawEngines)) {
35495
+ return { config: raw, lifted, conflicts };
35496
+ }
35497
+ const engines = {};
35498
+ let anyEngineChanged = false;
35499
+ for (const [name, engineValue] of Object.entries(rawEngines)) {
35500
+ if (!isRecord(engineValue) || !isRecord(engineValue.extraParams)) {
35501
+ engines[name] = engineValue;
35502
+ continue;
35503
+ }
35504
+ const engine = { ...engineValue };
35505
+ const extraParams = { ...engineValue.extraParams };
35506
+ let engineChanged = false;
35507
+ for (const [rawKey, value] of Object.entries(engineValue.extraParams)) {
35508
+ const normalized = normalizeExtraParamKey(rawKey);
35509
+ if (!LIFTABLE_EXTRA_PARAMS_KEYS.has(normalized))
35510
+ continue;
35511
+ const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
35512
+ if (!field)
35513
+ continue;
35514
+ const existing = engine[field];
35515
+ if (existing !== undefined && existing !== value) {
35516
+ conflicts.push({ engine: name, key: rawKey, field, extraParamsValue: value, fieldValue: existing });
35517
+ continue;
35518
+ }
35519
+ delete extraParams[rawKey];
35520
+ engineChanged = true;
35521
+ if (existing === value) {
35522
+ lifted.push(`engines.${name}.extraParams.${rawKey} is redundant — engines.${name}.${field} is already set to the same value; dropped the extraParams entry`);
35523
+ continue;
35792
35524
  }
35793
- return;
35794
- });
35795
- return ZodAny.create();
35525
+ engine[field] = value;
35526
+ lifted.push(`engines.${name}.extraParams.${rawKey} -> engines.${name}.${field}`);
35527
+ }
35528
+ if (!engineChanged) {
35529
+ engines[name] = engineValue;
35530
+ continue;
35531
+ }
35532
+ anyEngineChanged = true;
35533
+ if (Object.keys(extraParams).length > 0) {
35534
+ engine.extraParams = extraParams;
35535
+ } else {
35536
+ delete engine.extraParams;
35537
+ }
35538
+ engines[name] = engine;
35539
+ }
35540
+ if (!anyEngineChanged) {
35541
+ return { config: raw, lifted, conflicts };
35542
+ }
35543
+ return { config: { ...raw, engines }, lifted, conflicts };
35796
35544
  }
35797
- var late = {
35798
- object: ZodObject.lazycreate
35799
- };
35800
- var ZodFirstPartyTypeKind;
35801
- (function(ZodFirstPartyTypeKind2) {
35802
- ZodFirstPartyTypeKind2["ZodString"] = "ZodString";
35803
- ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";
35804
- ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";
35805
- ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";
35806
- ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";
35807
- ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";
35808
- ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";
35809
- ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";
35810
- ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";
35811
- ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";
35812
- ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";
35813
- ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";
35814
- ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";
35815
- ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";
35816
- ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";
35817
- ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";
35818
- ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
35819
- ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";
35820
- ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";
35821
- ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";
35822
- ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";
35823
- ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";
35824
- ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";
35825
- ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";
35826
- ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";
35827
- ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";
35828
- ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";
35829
- ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";
35830
- ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";
35831
- ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";
35832
- ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";
35833
- ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";
35834
- ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";
35835
- ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";
35836
- ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";
35837
- ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";
35838
- })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
35839
- var instanceOfType = (cls, params = {
35840
- message: `Input not instance of ${cls.name}`
35841
- }) => custom((data) => data instanceof cls, params);
35842
- var stringType = ZodString.create;
35843
- var numberType = ZodNumber.create;
35844
- var nanType = ZodNaN.create;
35845
- var bigIntType = ZodBigInt.create;
35846
- var booleanType = ZodBoolean.create;
35847
- var dateType = ZodDate.create;
35848
- var symbolType = ZodSymbol.create;
35849
- var undefinedType = ZodUndefined.create;
35850
- var nullType = ZodNull.create;
35851
- var anyType = ZodAny.create;
35852
- var unknownType = ZodUnknown.create;
35853
- var neverType = ZodNever.create;
35854
- var voidType = ZodVoid.create;
35855
- var arrayType = ZodArray.create;
35856
- var objectType = ZodObject.create;
35857
- var strictObjectType = ZodObject.strictCreate;
35858
- var unionType = ZodUnion.create;
35859
- var discriminatedUnionType = ZodDiscriminatedUnion.create;
35860
- var intersectionType = ZodIntersection.create;
35861
- var tupleType = ZodTuple.create;
35862
- var recordType = ZodRecord.create;
35863
- var mapType = ZodMap.create;
35864
- var setType = ZodSet.create;
35865
- var functionType = ZodFunction.create;
35866
- var lazyType = ZodLazy.create;
35867
- var literalType = ZodLiteral.create;
35868
- var enumType = ZodEnum.create;
35869
- var nativeEnumType = ZodNativeEnum.create;
35870
- var promiseType = ZodPromise.create;
35871
- var effectsType = ZodEffects.create;
35872
- var optionalType = ZodOptional.create;
35873
- var nullableType = ZodNullable.create;
35874
- var preprocessType = ZodEffects.createWithPreprocess;
35875
- var pipelineType = ZodPipeline.create;
35876
- var ostring = () => stringType().optional();
35877
- var onumber = () => numberType().optional();
35878
- var oboolean = () => booleanType().optional();
35879
- var coerce = {
35880
- string: (arg) => ZodString.create({ ...arg, coerce: true }),
35881
- number: (arg) => ZodNumber.create({ ...arg, coerce: true }),
35882
- boolean: (arg) => ZodBoolean.create({
35883
- ...arg,
35884
- coerce: true
35885
- }),
35886
- bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }),
35887
- date: (arg) => ZodDate.create({ ...arg, coerce: true })
35888
- };
35889
- var NEVER = INVALID;
35545
+
35890
35546
  // src/core/config/schema/primitives.ts
35891
35547
  var CURRENT_CONFIG_VERSION = "0.9.0";
35892
35548
  var positiveInt = exports_external.number().int().positive();
@@ -36179,8 +35835,6 @@ var CONSOLIDATE_PROCESS_FIELDS = {
36179
35835
  limit: processLimitField,
36180
35836
  minPoolSize: exports_external.number().int().min(0).optional(),
36181
35837
  maxChunkSize: exports_external.number().int().min(1).max(50).optional(),
36182
- incrementalSince: exports_external.string().optional(),
36183
- neighborsPerChanged: exports_external.number().int().min(1).optional(),
36184
35838
  p90ChunkSecondsDefault: exports_external.number().finite().positive().optional(),
36185
35839
  antiCollapse: antiCollapseField
36186
35840
  };
@@ -36188,13 +35842,6 @@ var MEMORY_INFERENCE_PROCESS_FIELDS = {
36188
35842
  minPendingCount: exports_external.number().int().min(0).optional(),
36189
35843
  cls: clsField
36190
35844
  };
36191
- var GRAPH_EXTRACTION_PROCESS_FIELDS = {
36192
- topN: positiveInt.optional(),
36193
- includeTypes: exports_external.array(exports_external.string().min(1)).min(1).optional(),
36194
- batchSize: positiveInt.optional(),
36195
- fullScan: exports_external.boolean().optional(),
36196
- maxChunksPerAsset: positiveInt.optional()
36197
- };
36198
35845
  var EXTRACT_PROCESS_FIELDS = {
36199
35846
  defaultSince: exports_external.string().min(1).optional(),
36200
35847
  maxTotalChars: positiveInt.optional(),
@@ -36230,7 +35877,6 @@ var ImproveProcessConfigSchema = exports_external.object({
36230
35877
  ...DISTILL_PROCESS_FIELDS,
36231
35878
  ...CONSOLIDATE_PROCESS_FIELDS,
36232
35879
  ...MEMORY_INFERENCE_PROCESS_FIELDS,
36233
- ...GRAPH_EXTRACTION_PROCESS_FIELDS,
36234
35880
  ...EXTRACT_PROCESS_FIELDS,
36235
35881
  ...TRIAGE_PROCESS_FIELDS,
36236
35882
  ...PROACTIVE_MAINTENANCE_PROCESS_FIELDS
@@ -36239,17 +35885,16 @@ var ReflectProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BA
36239
35885
  var DistillProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...DISTILL_PROCESS_FIELDS }).passthrough().superRefine(rejectExcludeRefPrefixesOutsideReflect);
36240
35886
  var ConsolidateProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...CONSOLIDATE_PROCESS_FIELDS }).passthrough().superRefine(rejectExcludeRefPrefixesOutsideReflect);
36241
35887
  var MemoryInferenceProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...MEMORY_INFERENCE_PROCESS_FIELDS }).passthrough();
36242
- var GraphExtractionProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...GRAPH_EXTRACTION_PROCESS_FIELDS }).passthrough();
36243
35888
  var ExtractProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...EXTRACT_PROCESS_FIELDS }).passthrough();
36244
35889
  var ValidationProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS }).passthrough();
36245
35890
  var TriageProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...TRIAGE_PROCESS_FIELDS }).passthrough();
36246
35891
  var ProactiveMaintenanceProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...PROACTIVE_MAINTENANCE_PROCESS_FIELDS }).passthrough();
35892
+ var RETIRED_PROCESS_NAMES = new Set(["graphExtraction"]);
36247
35893
  var ImproveProfileProcessesSchema = exports_external.object({
36248
35894
  reflect: ReflectProcessConfigSchema.optional(),
36249
35895
  distill: DistillProcessConfigSchema.optional(),
36250
35896
  consolidate: ConsolidateProcessConfigSchema.optional(),
36251
35897
  memoryInference: MemoryInferenceProcessConfigSchema.optional(),
36252
- graphExtraction: GraphExtractionProcessConfigSchema.optional(),
36253
35898
  extract: ExtractProcessConfigSchema.optional(),
36254
35899
  validation: ValidationProcessConfigSchema.optional(),
36255
35900
  triage: TriageProcessConfigSchema.optional(),
@@ -36262,7 +35907,7 @@ var ImproveProfileProcessesSchema = exports_external.object({
36262
35907
  });
36263
35908
  }
36264
35909
  for (const [name, process2] of Object.entries(val)) {
36265
- if (!(name in IMPROVE_PROCESS_ENGINE_CAPABILITIES) && process2 !== null && typeof process2 === "object" && process2.enabled === true) {
35910
+ if (!(name in IMPROVE_PROCESS_ENGINE_CAPABILITIES) && !RETIRED_PROCESS_NAMES.has(name) && process2 !== null && typeof process2 === "object" && process2.enabled === true) {
36266
35911
  ctx.addIssue({
36267
35912
  code: exports_external.ZodIssueCode.custom,
36268
35913
  path: [name],
@@ -36331,11 +35976,8 @@ var IndexPassConfigSchema = exports_external.preprocess((raw, ctx) => {
36331
35976
  model: nonEmptyString.optional(),
36332
35977
  timeoutMs: exports_external.union([positiveInt, exports_external.null()]).optional(),
36333
35978
  enabled: exports_external.boolean().optional(),
36334
- llm: LlmInvocationOverridesSchema.optional(),
36335
- graphExtractionBatchSize: positiveInt.optional(),
36336
- graphExtractionIncludeTypes: exports_external.array(exports_external.string().min(1)).nonempty().optional()
35979
+ llm: LlmInvocationOverridesSchema.optional()
36337
35980
  }).passthrough());
36338
- var MetadataEnhanceSchema = exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough();
36339
35981
  var IndexDefaultsSchema = exports_external.object({
36340
35982
  engine: engineName.optional(),
36341
35983
  model: nonEmptyString.optional(),
@@ -36348,7 +35990,7 @@ var IndexConfigRuntimeSchema = exports_external.preprocess((raw, ctx) => {
36348
35990
  if (Array.isArray(raw)) {
36349
35991
  ctx.addIssue({
36350
35992
  code: exports_external.ZodIssueCode.custom,
36351
- message: 'Invalid `index` config: expected an object keyed by pass name (e.g. `{ "enrichment": { "enabled": false } }`).'
35993
+ message: 'Invalid `index` config: expected an object keyed by pass name (e.g. `{ "memory": { "enabled": false } }`).'
36352
35994
  });
36353
35995
  return raw;
36354
35996
  }
@@ -36372,8 +36014,7 @@ var IndexConfigRuntimeSchema = exports_external.preprocess((raw, ctx) => {
36372
36014
  }
36373
36015
  return cleaned ?? raw;
36374
36016
  }, exports_external.object({
36375
- defaults: IndexDefaultsSchema.optional(),
36376
- metadataEnhance: MetadataEnhanceSchema.optional()
36017
+ defaults: IndexDefaultsSchema.optional()
36377
36018
  }).catchall(IndexPassConfigSchema));
36378
36019
  var IndexConfigSchema = IndexConfigRuntimeSchema;
36379
36020
 
@@ -36648,144 +36289,502 @@ var AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) => {
36648
36289
  }
36649
36290
  }
36650
36291
  if (config.defaultWriteTarget !== undefined) {
36651
- const target = config.bundles?.[config.defaultWriteTarget];
36652
- if (!target) {
36292
+ const target = config.bundles?.[config.defaultWriteTarget];
36293
+ if (!target) {
36294
+ ctx.addIssue({
36295
+ code: exports_external.ZodIssueCode.custom,
36296
+ path: ["defaultWriteTarget"],
36297
+ message: `defaultWriteTarget "${config.defaultWriteTarget}" does not name a configured bundle`
36298
+ });
36299
+ } else if (target.enabled === false) {
36300
+ ctx.addIssue({
36301
+ code: exports_external.ZodIssueCode.custom,
36302
+ path: ["defaultWriteTarget"],
36303
+ message: `defaultWriteTarget "${config.defaultWriteTarget}" is disabled`
36304
+ });
36305
+ }
36306
+ }
36307
+ for (const key of ["llm", "agent", "improve"]) {
36308
+ if (config.defaults && key in config.defaults) {
36309
+ ctx.addIssue({
36310
+ code: exports_external.ZodIssueCode.custom,
36311
+ path: ["defaults", key],
36312
+ message: `defaults.${key} is retired in 0.9`
36313
+ });
36314
+ }
36315
+ }
36316
+ for (const [name, engine] of Object.entries(config.engines ?? {})) {
36317
+ if (engine.kind === "agent" && engine.llmEngine) {
36318
+ const fallback = config.engines?.[engine.llmEngine];
36319
+ if (!fallback || fallback.kind !== "llm") {
36320
+ ctx.addIssue({
36321
+ code: exports_external.ZodIssueCode.custom,
36322
+ path: ["engines", name, "llmEngine"],
36323
+ message: "llmEngine must name an LLM engine"
36324
+ });
36325
+ }
36326
+ }
36327
+ }
36328
+ const defaultEngine = config.defaults?.engine;
36329
+ if (defaultEngine && !config.engines?.[defaultEngine]) {
36330
+ ctx.addIssue({
36331
+ code: exports_external.ZodIssueCode.custom,
36332
+ path: ["defaults", "engine"],
36333
+ message: "engine does not name a configured engine"
36334
+ });
36335
+ }
36336
+ const defaultLlm = config.defaults?.llmEngine;
36337
+ if (defaultLlm && config.engines?.[defaultLlm]?.kind !== "llm") {
36338
+ ctx.addIssue({
36339
+ code: exports_external.ZodIssueCode.custom,
36340
+ path: ["defaults", "llmEngine"],
36341
+ message: "llmEngine must name an LLM engine"
36342
+ });
36343
+ }
36344
+ const workflowJudge = config.workflow?.judgeEngine;
36345
+ if (workflowJudge && !config.engines?.[workflowJudge]) {
36346
+ ctx.addIssue({
36347
+ code: exports_external.ZodIssueCode.custom,
36348
+ path: ["workflow", "judgeEngine"],
36349
+ message: "judgeEngine does not name a configured engine"
36350
+ });
36351
+ }
36352
+ const defaultStrategy = config.defaults?.improveStrategy;
36353
+ if (defaultStrategy && defaultStrategy !== "graph-refresh" && !BUILTIN_IMPROVE_STRATEGY_NAMES.includes(defaultStrategy) && !config.improve?.strategies?.[defaultStrategy]) {
36354
+ ctx.addIssue({
36355
+ code: exports_external.ZodIssueCode.custom,
36356
+ path: ["defaults", "improveStrategy"],
36357
+ message: "improveStrategy does not name a built-in or configured strategy"
36358
+ });
36359
+ }
36360
+ for (const [strategyName, strategy] of Object.entries(config.improve?.strategies ?? {})) {
36361
+ const strategyEngine = strategy.engine;
36362
+ if (strategyEngine) {
36363
+ const engine = config.engines?.[strategyEngine];
36364
+ if (!engine || engine.kind !== "llm") {
36365
+ ctx.addIssue({
36366
+ code: exports_external.ZodIssueCode.custom,
36367
+ path: ["improve", "strategies", strategyName, "engine"],
36368
+ message: engine ? "strategy engine must be an LLM engine" : "engine does not name a configured engine"
36369
+ });
36370
+ }
36371
+ }
36372
+ for (const [processName, process2] of Object.entries(strategy.processes ?? {})) {
36373
+ const processConfig = process2;
36374
+ const capability = IMPROVE_PROCESS_ENGINE_CAPABILITIES[processName];
36375
+ if (processConfig.engine && capability === null) {
36376
+ ctx.addIssue({
36377
+ code: exports_external.ZodIssueCode.custom,
36378
+ path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
36379
+ message: `${processName} does not dispatch an engine`
36380
+ });
36381
+ } else {
36382
+ const processEngine = processConfig.engine ?? strategyEngine;
36383
+ if (processEngine && capability === "llm") {
36384
+ const engine = config.engines?.[processEngine];
36385
+ if (!engine || engine.kind !== "llm") {
36386
+ ctx.addIssue({
36387
+ code: exports_external.ZodIssueCode.custom,
36388
+ path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
36389
+ message: engine ? `${processName} requires an LLM engine` : "engine does not name a configured engine"
36390
+ });
36391
+ }
36392
+ } else if (processConfig.engine && capability === "runner" && !config.engines?.[processConfig.engine]) {
36393
+ ctx.addIssue({
36394
+ code: exports_external.ZodIssueCode.custom,
36395
+ path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
36396
+ message: "engine does not name a configured engine"
36397
+ });
36398
+ }
36399
+ }
36400
+ const judgmentEngine = processConfig.judgment?.engine;
36401
+ if (processConfig.judgment?.enabled === true && judgmentEngine) {
36402
+ const engine = config.engines?.[judgmentEngine];
36403
+ if (!engine) {
36404
+ ctx.addIssue({
36405
+ code: exports_external.ZodIssueCode.custom,
36406
+ path: ["improve", "strategies", strategyName, "processes", processName, "judgment", "engine"],
36407
+ message: "engine does not name a configured engine"
36408
+ });
36409
+ }
36410
+ }
36411
+ }
36412
+ }
36413
+ if (config.defaultWriteTarget !== undefined) {
36414
+ const knownNames = Object.keys(config.bundles ?? {});
36415
+ if (knownNames.length === 0) {
36653
36416
  ctx.addIssue({
36654
36417
  code: exports_external.ZodIssueCode.custom,
36655
36418
  path: ["defaultWriteTarget"],
36656
- message: `defaultWriteTarget "${config.defaultWriteTarget}" does not name a configured bundle`
36419
+ message: `defaultWriteTarget "${config.defaultWriteTarget}" cannot be resolved: no bundles configured. ` + "Add at least one entry to `bundles` first."
36657
36420
  });
36658
- } else if (target.enabled === false) {
36421
+ } else if (!knownNames.includes(config.defaultWriteTarget)) {
36659
36422
  ctx.addIssue({
36660
36423
  code: exports_external.ZodIssueCode.custom,
36661
36424
  path: ["defaultWriteTarget"],
36662
- message: `defaultWriteTarget "${config.defaultWriteTarget}" is disabled`
36425
+ message: `defaultWriteTarget "${config.defaultWriteTarget}" does not match any configured bundle: ${knownNames.map((n) => `"${n}"`).join(", ")}.`
36663
36426
  });
36664
36427
  }
36665
36428
  }
36666
- for (const key of ["llm", "agent", "improve"]) {
36667
- if (config.defaults && key in config.defaults) {
36668
- ctx.addIssue({
36669
- code: exports_external.ZodIssueCode.custom,
36670
- path: ["defaults", key],
36671
- message: `defaults.${key} is retired in 0.9`
36672
- });
36429
+ });
36430
+
36431
+ // src/core/config/deep-merge.ts
36432
+ var UNSAFE_KEYS = new Set(["__proto__", "constructor", "prototype"]);
36433
+ function isPlainObject(value) {
36434
+ if (value === null || typeof value !== "object" || Array.isArray(value))
36435
+ return false;
36436
+ const prototype = Object.getPrototypeOf(value);
36437
+ return prototype === Object.prototype || prototype === null;
36438
+ }
36439
+ function copyConfigValue(value) {
36440
+ if (Array.isArray(value))
36441
+ return value.map(copyConfigValue);
36442
+ if (!isPlainObject(value))
36443
+ return value;
36444
+ const copy = {};
36445
+ for (const key of Object.keys(value)) {
36446
+ if (UNSAFE_KEYS.has(key))
36447
+ throw new TypeError(`Unsafe configuration key: ${key}`);
36448
+ copy[key] = copyConfigValue(value[key]);
36449
+ }
36450
+ return copy;
36451
+ }
36452
+ function deepMergeConfig(base, override) {
36453
+ const result = copyConfigValue(base);
36454
+ for (const key of Object.keys(override)) {
36455
+ if (UNSAFE_KEYS.has(key))
36456
+ throw new TypeError(`Unsafe configuration key: ${key}`);
36457
+ const next = override[key];
36458
+ if (next === undefined)
36459
+ continue;
36460
+ const current = result[key];
36461
+ result[key] = isPlainObject(current) && isPlainObject(next) ? deepMergeConfig(current, next) : copyConfigValue(next);
36462
+ }
36463
+ return result;
36464
+ }
36465
+
36466
+ // src/core/config/config.ts
36467
+ import fs10 from "node:fs";
36468
+ import os2 from "node:os";
36469
+ import path14 from "node:path";
36470
+ import { isDeepStrictEqual } from "node:util";
36471
+
36472
+ // src/core/config/config-io.ts
36473
+ import fs8 from "node:fs";
36474
+ import path12 from "node:path";
36475
+
36476
+ // src/core/file-lock.ts
36477
+ import { randomUUID } from "node:crypto";
36478
+ import fs7 from "node:fs";
36479
+ function readLockSnapshot(lockPath) {
36480
+ let fd;
36481
+ try {
36482
+ fd = fs7.openSync(lockPath, "r");
36483
+ } catch (err) {
36484
+ if (err.code === "ENOENT")
36485
+ return;
36486
+ throw err;
36487
+ }
36488
+ try {
36489
+ const rawContent = readTextFileDescriptorWithLimit(fd, MAX_LOCK_METADATA_BYTES, "Lock metadata", lockPath);
36490
+ const stat = fs7.fstatSync(fd);
36491
+ return {
36492
+ rawContent,
36493
+ identity: { dev: stat.dev, ino: stat.ino, size: stat.size, mtimeMs: stat.mtimeMs }
36494
+ };
36495
+ } finally {
36496
+ fs7.closeSync(fd);
36497
+ }
36498
+ }
36499
+ function sameIdentity(left, right) {
36500
+ return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs;
36501
+ }
36502
+ function releaseLockRaw(lockPath) {
36503
+ try {
36504
+ fs7.unlinkSync(lockPath);
36505
+ } catch {}
36506
+ }
36507
+ function tryAcquireLockSync(lockPath, payload) {
36508
+ try {
36509
+ fs7.writeFileSync(lockPath, payload, { flag: "wx" });
36510
+ } catch (err) {
36511
+ if (err.code === "EEXIST")
36512
+ return;
36513
+ throw err;
36514
+ }
36515
+ let snapshot;
36516
+ try {
36517
+ snapshot = readLockSnapshot(lockPath);
36518
+ } catch (error2) {
36519
+ releaseLockRaw(lockPath);
36520
+ throw error2;
36521
+ }
36522
+ if (!snapshot) {
36523
+ releaseLockRaw(lockPath);
36524
+ throw new Error(`Could not read newly acquired lock at ${lockPath}.`);
36525
+ }
36526
+ return { lockPath, ...snapshot };
36527
+ }
36528
+ function launcherPidFromEnv() {
36529
+ const raw = process.env.AKM_LAUNCHER_PID;
36530
+ if (!raw)
36531
+ return;
36532
+ const pid = Number.parseInt(raw, 10);
36533
+ return Number.isInteger(pid) && pid > 0 ? pid : undefined;
36534
+ }
36535
+ function createLockPayload(metadata = {}) {
36536
+ const launcherPid = launcherPidFromEnv();
36537
+ return JSON.stringify({
36538
+ ...metadata,
36539
+ pid: process.pid,
36540
+ ...launcherPid !== undefined ? { launcherPid } : {},
36541
+ lockId: randomUUID()
36542
+ });
36543
+ }
36544
+ function probeLock(lockPath, opts) {
36545
+ let snapshot;
36546
+ try {
36547
+ snapshot = readLockSnapshot(lockPath);
36548
+ } catch (error2) {
36549
+ const code = error2?.code;
36550
+ if (code === "EACCES" || code === "EPERM")
36551
+ return { state: "inaccessible", code };
36552
+ return { state: "stale", reason: "unreadable" };
36553
+ }
36554
+ if (!snapshot)
36555
+ return { state: "absent" };
36556
+ const { rawContent, identity: identity3 } = snapshot;
36557
+ const ageMs = Date.now() - identity3.mtimeMs;
36558
+ const { holderPid, launcherPid } = extractLockIdentity(rawContent);
36559
+ if (holderPid === undefined) {
36560
+ return { state: "stale", reason: "invalid_pid", ageMs, rawContent, identity: identity3 };
36561
+ }
36562
+ if (!isProcessAlive(holderPid)) {
36563
+ return { state: "stale", reason: "pid_dead", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
36564
+ }
36565
+ if (opts?.staleAfterMs !== undefined && ageMs > opts.staleAfterMs) {
36566
+ return { state: "stale", reason: "age_exceeded", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
36567
+ }
36568
+ return { state: "held", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
36569
+ }
36570
+ function reclaimStaleLock(lockPath, probe, options) {
36571
+ if (probe.rawContent === undefined || probe.identity === undefined)
36572
+ return false;
36573
+ const expectedContent = probe.rawContent;
36574
+ const expectedIdentity = probe.identity;
36575
+ let current;
36576
+ try {
36577
+ current = readLockSnapshot(lockPath);
36578
+ } catch {
36579
+ return false;
36580
+ }
36581
+ if (!current || current.rawContent !== expectedContent || !sameIdentity(current.identity, expectedIdentity)) {
36582
+ return false;
36583
+ }
36584
+ const quarantinePath = `${lockPath}.stale-${process.pid}-${randomUUID()}`;
36585
+ try {
36586
+ fs7.renameSync(lockPath, quarantinePath);
36587
+ } catch (err) {
36588
+ if (err.code === "ENOENT")
36589
+ return false;
36590
+ throw err;
36591
+ }
36592
+ let quarantined;
36593
+ try {
36594
+ quarantined = readLockSnapshot(quarantinePath);
36595
+ } catch {
36596
+ quarantined = undefined;
36597
+ }
36598
+ if (!quarantined || quarantined.rawContent !== expectedContent || !sameIdentity(quarantined.identity, expectedIdentity)) {
36599
+ try {
36600
+ fs7.linkSync(quarantinePath, lockPath);
36601
+ } catch (err) {
36602
+ if (err.code !== "EEXIST")
36603
+ throw err;
36604
+ }
36605
+ releaseLockRaw(quarantinePath);
36606
+ return false;
36607
+ }
36608
+ options?.afterQuarantineVerified?.();
36609
+ try {
36610
+ fs7.unlinkSync(quarantinePath);
36611
+ return true;
36612
+ } catch (err) {
36613
+ if (err.code === "ENOENT")
36614
+ return false;
36615
+ throw err;
36616
+ }
36617
+ }
36618
+ function releaseLock(ownership) {
36619
+ const { lockPath } = ownership;
36620
+ let current;
36621
+ try {
36622
+ current = readLockSnapshot(lockPath);
36623
+ } catch {
36624
+ return;
36625
+ }
36626
+ if (current && current.rawContent === ownership.rawContent && sameIdentity(current.identity, ownership.identity)) {
36627
+ releaseLockRaw(lockPath);
36628
+ }
36629
+ }
36630
+ function extractLockIdentity(content) {
36631
+ const trimmed = content.trim();
36632
+ if (!trimmed)
36633
+ return {};
36634
+ if (trimmed.startsWith("{")) {
36635
+ try {
36636
+ const parsed = JSON.parse(trimmed);
36637
+ const pid2 = typeof parsed.pid === "number" ? parsed.pid : Number.NaN;
36638
+ const rawLauncherPid = typeof parsed.launcherPid === "number" ? parsed.launcherPid : Number.NaN;
36639
+ return {
36640
+ holderPid: Number.isInteger(pid2) && pid2 > 0 ? pid2 : undefined,
36641
+ launcherPid: Number.isInteger(rawLauncherPid) && rawLauncherPid > 0 ? rawLauncherPid : undefined
36642
+ };
36643
+ } catch {
36644
+ return {};
36673
36645
  }
36674
36646
  }
36675
- for (const [name, engine] of Object.entries(config.engines ?? {})) {
36676
- if (engine.kind === "agent" && engine.llmEngine) {
36677
- const fallback = config.engines?.[engine.llmEngine];
36678
- if (!fallback || fallback.kind !== "llm") {
36679
- ctx.addIssue({
36680
- code: exports_external.ZodIssueCode.custom,
36681
- path: ["engines", name, "llmEngine"],
36682
- message: "llmEngine must name an LLM engine"
36683
- });
36684
- }
36685
- }
36647
+ const pid = Number.parseInt(trimmed, 10);
36648
+ return { holderPid: Number.isInteger(pid) && pid > 0 ? pid : undefined };
36649
+ }
36650
+
36651
+ // src/core/config/config-io.ts
36652
+ function readConfigText(configPath) {
36653
+ try {
36654
+ return readTextFile(configPath, "Config file");
36655
+ } catch (err) {
36656
+ if (err.code === "ENOENT")
36657
+ return;
36658
+ throw err;
36659
+ }
36660
+ }
36661
+ function parseConfigText(text, sourcePath) {
36662
+ const stripped = stripJsonComments(text);
36663
+ const where = sourcePath ? ` at ${sourcePath}` : "";
36664
+ let parsed;
36665
+ try {
36666
+ parsed = JSON.parse(stripped);
36667
+ } catch (err) {
36668
+ const detail = err instanceof Error ? err.message : String(err);
36669
+ throw new ConfigError(`Failed to parse config JSON${where}: ${detail}`, "INVALID_CONFIG_FILE", "Edit the file to fix the JSON syntax error. Comments (// and /* */) are allowed; trailing commas are not.");
36686
36670
  }
36687
- const defaultEngine = config.defaults?.engine;
36688
- if (defaultEngine && !config.engines?.[defaultEngine]) {
36689
- ctx.addIssue({
36690
- code: exports_external.ZodIssueCode.custom,
36691
- path: ["defaults", "engine"],
36692
- message: "engine does not name a configured engine"
36693
- });
36671
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
36672
+ throw new ConfigError(`Config file${where} must contain a JSON object at the root, got ${describeJsonRoot(parsed)}.`, "INVALID_CONFIG_FILE");
36694
36673
  }
36695
- const defaultLlm = config.defaults?.llmEngine;
36696
- if (defaultLlm && config.engines?.[defaultLlm]?.kind !== "llm") {
36697
- ctx.addIssue({
36698
- code: exports_external.ZodIssueCode.custom,
36699
- path: ["defaults", "llmEngine"],
36700
- message: "llmEngine must name an LLM engine"
36701
- });
36674
+ return parsed;
36675
+ }
36676
+ function describeJsonRoot(value) {
36677
+ if (value === null)
36678
+ return "null";
36679
+ if (Array.isArray(value))
36680
+ return "an array";
36681
+ if (typeof value === "string")
36682
+ return "a string";
36683
+ if (typeof value === "number")
36684
+ return "a number";
36685
+ if (typeof value === "boolean")
36686
+ return "a boolean";
36687
+ return typeof value;
36688
+ }
36689
+ function writeConfigAtomic(configPath, config) {
36690
+ writeFileAtomic(configPath, `${JSON.stringify(config, null, 2)}
36691
+ `);
36692
+ }
36693
+ var MAX_CONFIG_BACKUPS = 5;
36694
+ function backupExistingConfig(configPath, now = new Date) {
36695
+ if (!fs8.existsSync(configPath))
36696
+ return;
36697
+ const backupDir = path12.join(getCacheDir(), "config-backups");
36698
+ fs8.mkdirSync(backupDir, { recursive: true, mode: 448 });
36699
+ fs8.chmodSync(backupDir, 448);
36700
+ const timestamp = now.toISOString().replace(/[.:]/g, "-");
36701
+ let sequence = 0;
36702
+ let timestamped;
36703
+ while (true) {
36704
+ timestamped = path12.join(backupDir, `config-${timestamp}${sequence === 0 ? "" : `-${sequence}`}.json`);
36705
+ try {
36706
+ fs8.copyFileSync(configPath, timestamped, fs8.constants.COPYFILE_EXCL);
36707
+ break;
36708
+ } catch (error2) {
36709
+ if (error2.code !== "EEXIST")
36710
+ throw error2;
36711
+ sequence++;
36712
+ }
36702
36713
  }
36703
- const workflowJudge = config.workflow?.judgeEngine;
36704
- if (workflowJudge && !config.engines?.[workflowJudge]) {
36705
- ctx.addIssue({
36706
- code: exports_external.ZodIssueCode.custom,
36707
- path: ["workflow", "judgeEngine"],
36708
- message: "judgeEngine does not name a configured engine"
36709
- });
36714
+ const latest = path12.join(backupDir, "config.latest.json");
36715
+ fs8.copyFileSync(configPath, latest);
36716
+ fs8.chmodSync(timestamped, 384);
36717
+ fs8.chmodSync(latest, 384);
36718
+ pruneOldBackups(backupDir);
36719
+ return { timestamped, latest };
36720
+ }
36721
+ function pruneOldBackups(backupDir) {
36722
+ pruneToNewest(backupDir, MAX_CONFIG_BACKUPS, (entry) => entry.isFile() && isTimestampedConfigBackup(entry.name));
36723
+ }
36724
+ function isTimestampedConfigBackup(name) {
36725
+ return name.startsWith("config-") && name.endsWith(".json") && name !== "config.latest.json";
36726
+ }
36727
+ function pruneToNewest(dir, keep, select) {
36728
+ let entries;
36729
+ try {
36730
+ entries = fs8.readdirSync(dir, { withFileTypes: true });
36731
+ } catch {
36732
+ return;
36710
36733
  }
36711
- const defaultStrategy = config.defaults?.improveStrategy;
36712
- if (defaultStrategy && !BUILTIN_IMPROVE_STRATEGY_NAMES.includes(defaultStrategy) && !config.improve?.strategies?.[defaultStrategy]) {
36713
- ctx.addIssue({
36714
- code: exports_external.ZodIssueCode.custom,
36715
- path: ["defaults", "improveStrategy"],
36716
- message: "improveStrategy does not name a built-in or configured strategy"
36717
- });
36734
+ const candidates = entries.filter(select).map((entry) => {
36735
+ const full = path12.join(dir, entry.name);
36736
+ let mtime = 0;
36737
+ try {
36738
+ mtime = fs8.statSync(full).mtimeMs;
36739
+ } catch {}
36740
+ return { path: full, mtime };
36741
+ }).sort((a, b) => b.mtime - a.mtime);
36742
+ for (const stale of candidates.slice(keep)) {
36743
+ try {
36744
+ fs8.rmSync(stale.path, { recursive: true, force: true });
36745
+ } catch {}
36718
36746
  }
36719
- for (const [strategyName, strategy] of Object.entries(config.improve?.strategies ?? {})) {
36720
- const strategyEngine = strategy.engine;
36721
- if (strategyEngine) {
36722
- const engine = config.engines?.[strategyEngine];
36723
- if (!engine || engine.kind !== "llm") {
36724
- ctx.addIssue({
36725
- code: exports_external.ZodIssueCode.custom,
36726
- path: ["improve", "strategies", strategyName, "engine"],
36727
- message: engine ? "strategy engine must be an LLM engine" : "engine does not name a configured engine"
36728
- });
36747
+ }
36748
+ function getConfigLockPath() {
36749
+ return path12.join(getConfigDir(), "config.json.lck");
36750
+ }
36751
+ var CONFIG_LOCK_MAX_RETRIES = 40;
36752
+ var CONFIG_LOCK_RETRY_DELAY_MS = 50;
36753
+ function sleepSyncMs(ms) {
36754
+ sleepSync(ms);
36755
+ }
36756
+ function acquireConfigLock() {
36757
+ const lockPath = getConfigLockPath();
36758
+ try {
36759
+ fs8.mkdirSync(path12.dirname(lockPath), { recursive: true });
36760
+ } catch {}
36761
+ for (let attempt = 0;attempt < CONFIG_LOCK_MAX_RETRIES; attempt++) {
36762
+ try {
36763
+ const ownership = tryAcquireLockSync(lockPath, createLockPayload());
36764
+ if (ownership) {
36765
+ return () => releaseLock(ownership);
36729
36766
  }
36767
+ } catch (error2) {
36768
+ throw new ConfigError(`Unable to acquire config lock at ${lockPath}: ${error2 instanceof Error ? error2.message : String(error2)}`, "INVALID_CONFIG_FILE");
36730
36769
  }
36731
- for (const [processName, process2] of Object.entries(strategy.processes ?? {})) {
36732
- const processConfig = process2;
36733
- const capability = IMPROVE_PROCESS_ENGINE_CAPABILITIES[processName];
36734
- if (processConfig.engine && capability === null) {
36735
- ctx.addIssue({
36736
- code: exports_external.ZodIssueCode.custom,
36737
- path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
36738
- message: `${processName} does not dispatch an engine`
36739
- });
36740
- } else {
36741
- const processEngine = processConfig.engine ?? strategyEngine;
36742
- if (processEngine && capability === "llm") {
36743
- const engine = config.engines?.[processEngine];
36744
- if (!engine || engine.kind !== "llm") {
36745
- ctx.addIssue({
36746
- code: exports_external.ZodIssueCode.custom,
36747
- path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
36748
- message: engine ? `${processName} requires an LLM engine` : "engine does not name a configured engine"
36749
- });
36750
- }
36751
- } else if (processConfig.engine && capability === "runner" && !config.engines?.[processConfig.engine]) {
36752
- ctx.addIssue({
36753
- code: exports_external.ZodIssueCode.custom,
36754
- path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
36755
- message: "engine does not name a configured engine"
36756
- });
36757
- }
36758
- }
36759
- const judgmentEngine = processConfig.judgment?.engine;
36760
- if (processConfig.judgment?.enabled === true && judgmentEngine) {
36761
- const engine = config.engines?.[judgmentEngine];
36762
- if (!engine) {
36763
- ctx.addIssue({
36764
- code: exports_external.ZodIssueCode.custom,
36765
- path: ["improve", "strategies", strategyName, "processes", processName, "judgment", "engine"],
36766
- message: "engine does not name a configured engine"
36767
- });
36768
- }
36769
- }
36770
+ const probe = probeLock(lockPath);
36771
+ if (probe.state === "stale" && reclaimStaleLock(lockPath, probe)) {
36772
+ continue;
36770
36773
  }
36771
- }
36772
- if (config.defaultWriteTarget !== undefined) {
36773
- const knownNames = Object.keys(config.bundles ?? {});
36774
- if (knownNames.length === 0) {
36775
- ctx.addIssue({
36776
- code: exports_external.ZodIssueCode.custom,
36777
- path: ["defaultWriteTarget"],
36778
- message: `defaultWriteTarget "${config.defaultWriteTarget}" cannot be resolved: no bundles configured. ` + "Add at least one entry to `bundles` first."
36779
- });
36780
- } else if (!knownNames.includes(config.defaultWriteTarget)) {
36781
- ctx.addIssue({
36782
- code: exports_external.ZodIssueCode.custom,
36783
- path: ["defaultWriteTarget"],
36784
- message: `defaultWriteTarget "${config.defaultWriteTarget}" does not match any configured bundle: ${knownNames.map((n) => `"${n}"`).join(", ")}.`
36785
- });
36774
+ if (attempt < CONFIG_LOCK_MAX_RETRIES - 1) {
36775
+ sleepSyncMs(CONFIG_LOCK_RETRY_DELAY_MS);
36786
36776
  }
36787
36777
  }
36788
- });
36778
+ throw new ConfigError(`Timed out waiting for config lock at ${lockPath}. Another AKM process may be updating config.`, "INVALID_CONFIG_FILE");
36779
+ }
36780
+ function withConfigLock(fn) {
36781
+ const release = acquireConfigLock();
36782
+ try {
36783
+ return fn();
36784
+ } finally {
36785
+ release();
36786
+ }
36787
+ }
36789
36788
 
36790
36789
  // src/core/config/config-sources.ts
36791
36790
  import { createHash } from "node:crypto";
@@ -36920,41 +36919,6 @@ function normalizeInstalledGitRef(source, ref) {
36920
36919
  return requestedRef ? `${cloneUrl}/tree/${requestedRef}` : cloneUrl;
36921
36920
  }
36922
36921
 
36923
- // src/core/config/deep-merge.ts
36924
- var UNSAFE_KEYS = new Set(["__proto__", "constructor", "prototype"]);
36925
- function isPlainObject(value) {
36926
- if (value === null || typeof value !== "object" || Array.isArray(value))
36927
- return false;
36928
- const prototype = Object.getPrototypeOf(value);
36929
- return prototype === Object.prototype || prototype === null;
36930
- }
36931
- function copyConfigValue(value) {
36932
- if (Array.isArray(value))
36933
- return value.map(copyConfigValue);
36934
- if (!isPlainObject(value))
36935
- return value;
36936
- const copy = {};
36937
- for (const key of Object.keys(value)) {
36938
- if (UNSAFE_KEYS.has(key))
36939
- throw new TypeError(`Unsafe configuration key: ${key}`);
36940
- copy[key] = copyConfigValue(value[key]);
36941
- }
36942
- return copy;
36943
- }
36944
- function deepMergeConfig(base, override) {
36945
- const result = copyConfigValue(base);
36946
- for (const key of Object.keys(override)) {
36947
- if (UNSAFE_KEYS.has(key))
36948
- throw new TypeError(`Unsafe configuration key: ${key}`);
36949
- const next = override[key];
36950
- if (next === undefined)
36951
- continue;
36952
- const current = result[key];
36953
- result[key] = isPlainObject(current) && isPlainObject(next) ? deepMergeConfig(current, next) : copyConfigValue(next);
36954
- }
36955
- return result;
36956
- }
36957
-
36958
36922
  // src/core/config/config-walker.ts
36959
36923
  function unwrap(schema) {
36960
36924
  let current = schema;
@@ -37203,11 +37167,12 @@ ${lines}`, "INVALID_CONFIG_FILE");
37203
37167
  assertUniquePhysicalBundleRoots(finalResult.data, sourcePath);
37204
37168
  return finalResult.data;
37205
37169
  }
37170
+ var RETIRED_CATCHALL_KEY_PATHS = new Set(["index.graph", "index.metadataEnhance"]);
37206
37171
  function unknownConfigKeyPaths(root, node = root, prefix = []) {
37207
37172
  const found = [];
37208
37173
  for (const key of Object.keys(node).sort()) {
37209
37174
  const keyPath = [...prefix, key];
37210
- if (resolveSchemaAt(keyPath, root) === undefined) {
37175
+ if (RETIRED_CATCHALL_KEY_PATHS.has(keyPath.join(".")) || resolveSchemaAt(keyPath, root) === undefined) {
37211
37176
  found.push(keyPath);
37212
37177
  continue;
37213
37178
  }
@@ -37498,6 +37463,9 @@ function normalizeConfigFile(configPath, options) {
37498
37463
  const body = withSchedulerOnDisk(configWriteBody(localRaw, current, next), next);
37499
37464
  for (const keyPath of unknownConfigKeyPaths(body))
37500
37465
  deleteConfigPath(body, keyPath);
37466
+ const strategies = body.improve?.strategies;
37467
+ if (strategies && Object.hasOwn(strategies, "graph-refresh"))
37468
+ delete strategies["graph-refresh"];
37501
37469
  const keys = [...new Set([...Object.keys(raw), ...Object.keys(body)])].filter((key) => JSON.stringify(raw[key]) !== JSON.stringify(body[key])).sort();
37502
37470
  if (keys.length === 0 || !options.apply)
37503
37471
  return { keys, changed: keys.length > 0, applied: false };
@@ -37572,7 +37540,6 @@ function resolveSecret(value, resolveFromStore) {
37572
37540
  return resolved ?? "";
37573
37541
  });
37574
37542
  }
37575
- var INDEX_RESERVED_KEYS = new Set(["metadataEnhance"]);
37576
37543
 
37577
37544
  // src/core/redaction.ts
37578
37545
  var ENV_PASSTHROUGH_REDACTION_POLICY = {
@@ -52777,6 +52744,7 @@ var LEDGER_HARD_OUTCOMES = new Set([
52777
52744
  "quality_rejected",
52778
52745
  "expired"
52779
52746
  ]);
52747
+ var hasContentHashColumnCache = new WeakMap;
52780
52748
 
52781
52749
  // src/commands/improve/improve-strategies.ts
52782
52750
  var REF_SCOPED_PROCESSES = new Set(["reflect", "distill", "consolidate"]);
@@ -52784,7 +52752,6 @@ var BUILTIN_STRATEGIES = {
52784
52752
  default: default_default,
52785
52753
  quick: quick_default,
52786
52754
  thorough: thorough_default,
52787
- "graph-refresh": graph_refresh_default,
52788
52755
  consolidate: consolidate_default,
52789
52756
  catchup: catchup_default,
52790
52757
  "reflect-distill": reflect_distill_default,