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
@@ -26583,7 +26583,8 @@ var STATE_MIGRATION_SAFETY_BY_ID = Object.freeze({
26583
26583
  "025-task-history-vocabulary-backfill": "data-preserving-rebuild",
26584
26584
  "026-proposals-strip-legacy-fragment-refs": "data-preserving-rebuild",
26585
26585
  "027-extract-sessions-seen-harness-rename": "data-preserving-rebuild",
26586
- "028-improve-ledger": "historical-destructive"
26586
+ "028-improve-ledger": "historical-destructive",
26587
+ "029-improve-ledger-content-hash": "additive"
26587
26588
  });
26588
26589
  var STATE_MIGRATIONS = [
26589
26590
  {
@@ -27321,6 +27322,12 @@ var STATE_MIGRATIONS = [
27321
27322
  DROP TABLE IF EXISTS improve_cycle_metrics;
27322
27323
  DROP TABLE IF EXISTS canary_queries;
27323
27324
  `
27325
+ },
27326
+ {
27327
+ id: "029-improve-ledger-content-hash",
27328
+ up: `
27329
+ ALTER TABLE improve_ledger ADD COLUMN content_hash TEXT DEFAULT NULL;
27330
+ `
27324
27331
  }
27325
27332
  ];
27326
27333
  assertMigrationRegistry(STATE_MIGRATIONS);
@@ -27552,7 +27559,6 @@ var BUILTIN_IMPROVE_STRATEGY_NAMES = [
27552
27559
  "default",
27553
27560
  "quick",
27554
27561
  "thorough",
27555
- "graph-refresh",
27556
27562
  "consolidate",
27557
27563
  "catchup",
27558
27564
  "reflect-distill",
@@ -27563,7 +27569,6 @@ var IMPROVE_PROCESS_ENGINE_CAPABILITIES = {
27563
27569
  distill: "llm",
27564
27570
  consolidate: "llm",
27565
27571
  memoryInference: "llm",
27566
- graphExtraction: "llm",
27567
27572
  extract: "llm",
27568
27573
  validation: "llm",
27569
27574
  triage: "runner",
@@ -27650,7 +27655,6 @@ var INTERESTING_DELTA_PATHS = [
27650
27655
  "improve.memoryInference.written",
27651
27656
  "improve.memoryInference.yieldRate",
27652
27657
  "improve.memoryInference.skippedNoFacts",
27653
- "improve.graphExtraction.failures",
27654
27658
  "improve.autoAccept.promoted",
27655
27659
  "improve.autoAccept.validationFailed",
27656
27660
  "improve.coverage.acceptedProposals",
@@ -27697,13 +27701,12 @@ function renderRunsDetailMd(runs) {
27697
27701
  "distill_q/llm-fail/judge/validator/cfg/skip",
27698
27702
  "cons_proc/promo/merge/del",
27699
27703
  "mem_cons/written/skip",
27700
- "graph_f/e/r",
27701
27704
  "orphans",
27702
27705
  "lint_f/fl",
27703
27706
  "result_status"
27704
27707
  ];
27705
27708
  const rows = runs.map((r) => {
27706
- 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;
27709
+ 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;
27707
27710
  return [
27708
27711
  r.startedAt,
27709
27712
  String(r.ok),
@@ -27713,7 +27716,6 @@ function renderRunsDetailMd(runs) {
27713
27716
  `${r.actions.distill.queued}/${r.actions.distill.llmFailed}/${r.actions.distill.judgeRejected}/${r.actions.distill.validatorRejected}/${r.actions.distill.configDisabled}/${r.actions.distill.skipped}`,
27714
27717
  `${r.consolidation.processed}/${r.consolidation.promoted}/${r.consolidation.merged}/${r.consolidation.deleted}`,
27715
27718
  `${r.memoryInference.considered}/${r.memoryInference.written}/${r.memoryInference.skippedNoFacts}`,
27716
- `${r.graphExtraction.extractedFiles}/${r.graphExtraction.entities}/${r.graphExtraction.relations}`,
27717
27719
  String(r.orphansPurged),
27718
27720
  `${r.lintFixed}/${r.lintFlagged}`,
27719
27721
  r.resultStatus ?? "valid"
@@ -27728,8 +27730,6 @@ function renderWindowCompareMd(windows, deltas) {
27728
27730
  const badIfPositive = new Set([
27729
27731
  "improve.actions.reflect.failed",
27730
27732
  "improve.actions.distill.llmFailed",
27731
- "improve.graphExtraction.failures",
27732
- "improve.graphExtraction.nonArrayBatchFailures",
27733
27733
  "improve.wallTime.medianMs",
27734
27734
  "improve.wallTime.p95Ms",
27735
27735
  "improve.memoryInference.skippedNoFacts"
@@ -27850,7 +27850,11 @@ function shapeProposalProducerOutput(result, detail) {
27850
27850
  }
27851
27851
  function shapeProposalEntry(entry, detail) {
27852
27852
  if (detail === "brief") {
27853
- return pickFields(entry, ["id", "ref", "status", "source", "createdAt"]);
27853
+ const retirement = entry.retirement;
27854
+ return {
27855
+ ...pickFields(entry, ["id", "ref", "status", "source", "createdAt"]),
27856
+ ...retirement?.continuityRisk ? { continuityRisk: true } : {}
27857
+ };
27854
27858
  }
27855
27859
  if (detail === "normal") {
27856
27860
  return pickFields(entry, [
@@ -27863,7 +27867,8 @@ function shapeProposalEntry(entry, detail) {
27863
27867
  "updatedAt",
27864
27868
  "confidence",
27865
27869
  "gateDecision",
27866
- "review"
27870
+ "review",
27871
+ "retirement"
27867
27872
  ]);
27868
27873
  }
27869
27874
  return pickFields(entry, [
@@ -27877,7 +27882,11 @@ function shapeProposalEntry(entry, detail) {
27877
27882
  "confidence",
27878
27883
  "gateDecision",
27879
27884
  "payload",
27880
- "review"
27885
+ "review",
27886
+ "retirement",
27887
+ "retiredArchive",
27888
+ "promotionSource",
27889
+ "promotionSourceHash"
27881
27890
  ]);
27882
27891
  }
27883
27892
  function shapeProposalListOutput(result, detail) {
@@ -28124,7 +28133,6 @@ function shapeShowOutput(result, detail, shape = "human") {
28124
28133
  "workflowParameters",
28125
28134
  "steps",
28126
28135
  "keys",
28127
- "related",
28128
28136
  "links",
28129
28137
  ...FRAGMENT_PROVENANCE_FIELDS,
28130
28138
  ...FRAGMENT_CONTEXT_FIELDS
@@ -28146,7 +28154,6 @@ function shapeShowOutput(result, detail, shape = "human") {
28146
28154
  "run",
28147
28155
  "origin",
28148
28156
  "keys",
28149
- "related",
28150
28157
  "links",
28151
28158
  ...FRAGMENT_PROVENANCE_FIELDS,
28152
28159
  ...FRAGMENT_CONTEXT_FIELDS
@@ -28175,7 +28182,6 @@ function shapeShowOutput(result, detail, shape = "human") {
28175
28182
  "cwd",
28176
28183
  "activeRun",
28177
28184
  "keys",
28178
- "related",
28179
28185
  "links",
28180
28186
  ...FRAGMENT_PROVENANCE_FIELDS,
28181
28187
  ...FRAGMENT_CONTEXT_FIELDS,
@@ -29317,13 +29323,6 @@ Warnings (${warnings.length}):`;
29317
29323
  out += `
29318
29324
  - ${String(message)}`;
29319
29325
  }
29320
- const notices = Array.isArray(indexResult.notices) ? indexResult.notices : [];
29321
- for (const notice of notices) {
29322
- const severity = notice.severity === "info" ? "info" : "warning";
29323
- const field = typeof notice.field === "string" ? ` field=${notice.field}` : "";
29324
- out += `
29325
- notice[${severity}] ${notice.code} adapter=${notice.adapter}${field}` + (notice.message ? `: ${notice.message}` : "");
29326
- }
29327
29326
  const verification = indexResult.verification;
29328
29327
  if (verification?.ok === false && verification.message) {
29329
29328
  out += `
@@ -29738,7 +29737,10 @@ Generate one with \`akm improve <ref>\` or \`akm proposal new <type> <name> --ta
29738
29737
  const created = String(p.createdAt);
29739
29738
  const gate = formatGateDecisionSummary(p.gateDecision);
29740
29739
  const gateSuffix = gate ? ` ${gate}` : "";
29741
- lines.push(`${id} [${status}] ${ref} source=${source} ${created}${gateSuffix}`);
29740
+ const retirement = p.retirement;
29741
+ const flagged = p.continuityRisk === true || Boolean(retirement?.continuityRisk);
29742
+ const continuitySuffix = flagged ? " \u26A0 continuity-risk" : "";
29743
+ lines.push(`${id} [${status}] ${ref} source=${source} ${created}${gateSuffix}${continuitySuffix}`);
29742
29744
  }
29743
29745
  return lines.join(`
29744
29746
  `).trimEnd();
@@ -29778,6 +29780,30 @@ function formatProposalShowPlain(r) {
29778
29780
  if (review.decidedAt)
29779
29781
  lines.push(`review.decidedAt: ${String(review.decidedAt)}`);
29780
29782
  }
29783
+ const retirement = p.retirement;
29784
+ if (retirement) {
29785
+ lines.push(`retire: ${String(retirement.retiredRef)} -> ${String(retirement.successorRef)}`);
29786
+ lines.push(`retire.label: ${String(retirement.judgeLabel)} (cosine=${String(retirement.cosine)})`);
29787
+ lines.push(`retire.reason: ${String(retirement.judgeReason)}`);
29788
+ const continuityRisk = retirement.continuityRisk;
29789
+ if (continuityRisk) {
29790
+ const failingQueries = typeof continuityRisk.failingQueries === "number" ? continuityRisk.failingQueries : 0;
29791
+ const unverifiedQueries = typeof continuityRisk.unverifiedQueries === "number" ? continuityRisk.unverifiedQueries : 0;
29792
+ const summary = [];
29793
+ if (failingQueries > 0) {
29794
+ summary.push(`${failingQueries} of the retired asset's own quer${failingQueries === 1 ? "y" : "ies"} would not have found the successor top 10`);
29795
+ }
29796
+ if (unverifiedQueries > 0) {
29797
+ summary.push(`${unverifiedQueries} quer${unverifiedQueries === 1 ? "y" : "ies"} unverified (search failed or used the keyword-only fallback)`);
29798
+ }
29799
+ lines.push(`retire.continuityRisk: ${summary.join("; ")} \u2014 excluded from bulk accept`);
29800
+ const ranks = Array.isArray(continuityRisk.ranks) ? continuityRisk.ranks : [];
29801
+ for (const rank of ranks) {
29802
+ const successorRank = rank.successorRank === null || rank.successorRank === undefined ? "absent from top 10" : `#${String(rank.successorRank)}`;
29803
+ lines.push(` - "${String(rank.query)}": retired #${String(rank.retiredRank)}, successor ${successorRank}`);
29804
+ }
29805
+ }
29806
+ }
29781
29807
  const validation = r.validation;
29782
29808
  if (validation) {
29783
29809
  const findings = Array.isArray(validation.findings) ? validation.findings : [];
@@ -30171,19 +30197,6 @@ function formatShowPlain(r, detail) {
30171
30197
  if (r.schemaVersion !== undefined)
30172
30198
  lines.push(`schemaVersion: ${String(r.schemaVersion)}`);
30173
30199
  }
30174
- const related = typeof r.related === "object" && r.related !== null ? r.related : undefined;
30175
- const relatedHits = related && Array.isArray(related.hits) ? related.hits : [];
30176
- if (related) {
30177
- lines.push("");
30178
- lines.push(`related: ${String(related.total ?? relatedHits.length)}`);
30179
- for (const hit of relatedHits) {
30180
- lines.push(` - ${String(hit.type ?? "?")}: ${formatRelatedLabel(hit)}`);
30181
- const shared = Array.isArray(hit.sharedEntities) ? hit.sharedEntities.map(String) : [];
30182
- if (shared.length > 0)
30183
- lines.push(` shared: ${shared.join(", ")}`);
30184
- lines.push(` relationCount: ${String(hit.relationCount ?? 0)}`);
30185
- }
30186
- }
30187
30200
  const links = typeof r.links === "object" && r.links !== null ? r.links : undefined;
30188
30201
  if (links) {
30189
30202
  lines.push("");
@@ -30233,13 +30246,6 @@ function formatShowPlain(r, detail) {
30233
30246
  return lines.length > 0 ? lines.join(`
30234
30247
  `) : null;
30235
30248
  }
30236
- function formatRelatedLabel(hit) {
30237
- const ref = typeof hit.ref === "string" ? hit.ref : undefined;
30238
- if (ref)
30239
- return ref;
30240
- const pathValue = typeof hit.path === "string" ? hit.path : "?";
30241
- return pathValue.split("/").pop() ?? pathValue;
30242
- }
30243
30249
  // src/output/text/workflow-format.ts
30244
30250
  function formatWorkflowListPlain(result) {
30245
30251
  const runs = Array.isArray(result.runs) ? result.runs : [];
@@ -30561,9 +30567,6 @@ var catchup_default = {
30561
30567
  memoryInference: {
30562
30568
  enabled: false
30563
30569
  },
30564
- graphExtraction: {
30565
- enabled: false
30566
- },
30567
30570
  extract: {
30568
30571
  enabled: false
30569
30572
  },
@@ -30595,7 +30598,6 @@ var consolidate_default = {
30595
30598
  distill: { enabled: false },
30596
30599
  consolidate: { enabled: true, allowedTypes: ["memory"], maxChunkSize: 25 },
30597
30600
  memoryInference: { enabled: false },
30598
- graphExtraction: { enabled: false },
30599
30601
  extract: { enabled: false },
30600
30602
  triage: { enabled: false },
30601
30603
  validation: { enabled: false },
@@ -30605,7 +30607,7 @@ var consolidate_default = {
30605
30607
  };
30606
30608
  // src/assets/improve-strategies/default.json
30607
30609
  var default_default = {
30608
- description: "Standard improve pass \u2014 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.",
30610
+ description: "Standard improve pass \u2014 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.",
30609
30611
  processes: {
30610
30612
  reflect: {
30611
30613
  enabled: true,
@@ -30615,7 +30617,6 @@ var default_default = {
30615
30617
  distill: { enabled: true, allowedTypes: ["memory"], requirePlannedRefs: true },
30616
30618
  consolidate: { enabled: true, allowedTypes: ["memory"] },
30617
30619
  memoryInference: { enabled: true },
30618
- graphExtraction: { enabled: true },
30619
30620
  extract: { enabled: false, triage: { enabled: true, minScore: 2 } },
30620
30621
  validation: { enabled: true },
30621
30622
  proactiveMaintenance: { enabled: false, dueDays: 30, maxPerRun: 15 },
@@ -30623,25 +30624,9 @@ var default_default = {
30623
30624
  },
30624
30625
  sync: { enabled: true, push: true }
30625
30626
  };
30626
- // src/assets/improve-strategies/graph-refresh.json
30627
- var graph_refresh_default = {
30628
- description: "Full-corpus graph extraction pass \u2014 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.",
30629
- processes: {
30630
- reflect: { enabled: false },
30631
- distill: { enabled: false },
30632
- consolidate: { enabled: false },
30633
- memoryInference: { enabled: false },
30634
- graphExtraction: { enabled: true, fullScan: true },
30635
- extract: { enabled: false },
30636
- triage: { enabled: false },
30637
- validation: { enabled: false },
30638
- proactiveMaintenance: { enabled: false }
30639
- },
30640
- sync: { enabled: true, push: true }
30641
- };
30642
30627
  // src/assets/improve-strategies/proactive-maintenance.json
30643
30628
  var proactive_maintenance_default = {
30644
- description: "Opt-in proactive-maintenance pass \u2014 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.",
30629
+ description: "Opt-in proactive-maintenance pass \u2014 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.",
30645
30630
  processes: {
30646
30631
  reflect: {
30647
30632
  enabled: true,
@@ -30650,7 +30635,6 @@ var proactive_maintenance_default = {
30650
30635
  distill: { enabled: true, allowedTypes: ["memory"] },
30651
30636
  consolidate: { enabled: false },
30652
30637
  memoryInference: { enabled: false },
30653
- graphExtraction: { enabled: false },
30654
30638
  extract: { enabled: false },
30655
30639
  validation: { enabled: false },
30656
30640
  triage: {
@@ -30667,7 +30651,7 @@ var proactive_maintenance_default = {
30667
30651
  };
30668
30652
  // src/assets/improve-strategies/quick.json
30669
30653
  var quick_default = {
30670
- description: "Reflect-only pass \u2014 no extract, distill, consolidate, memoryInference, or graphExtraction.",
30654
+ description: "Reflect-only pass \u2014 no extract, distill, consolidate, or memoryInference.",
30671
30655
  processes: {
30672
30656
  reflect: {
30673
30657
  enabled: true,
@@ -30677,7 +30661,6 @@ var quick_default = {
30677
30661
  distill: { enabled: false },
30678
30662
  consolidate: { enabled: false },
30679
30663
  memoryInference: { enabled: false },
30680
- graphExtraction: { enabled: false },
30681
30664
  triage: { enabled: false },
30682
30665
  validation: { enabled: false },
30683
30666
  proactiveMaintenance: { enabled: false }
@@ -30686,7 +30669,7 @@ var quick_default = {
30686
30669
  };
30687
30670
  // src/assets/improve-strategies/reflect-distill.json
30688
30671
  var reflect_distill_default = {
30689
- description: "Reflect + distill pass \u2014 reflect, distill, memoryInference, and proposal triage (promote); proactiveMaintenance/consolidate/graphExtraction/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
30672
+ description: "Reflect + distill pass \u2014 reflect, distill, memoryInference, and proposal triage (promote); proactiveMaintenance/consolidate/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
30690
30673
  processes: {
30691
30674
  reflect: {
30692
30675
  enabled: true,
@@ -30695,7 +30678,6 @@ var reflect_distill_default = {
30695
30678
  distill: { enabled: true, allowedTypes: ["memory"], requirePlannedRefs: false },
30696
30679
  consolidate: { enabled: false },
30697
30680
  memoryInference: { enabled: true },
30698
- graphExtraction: { enabled: false },
30699
30681
  extract: {
30700
30682
  enabled: false,
30701
30683
  timeoutMs: 300000,
@@ -30736,9 +30718,6 @@ var thorough_default = {
30736
30718
  memoryInference: {
30737
30719
  enabled: true
30738
30720
  },
30739
- graphExtraction: {
30740
- enabled: true
30741
- },
30742
30721
  extract: {
30743
30722
  enabled: false,
30744
30723
  triage: {
@@ -30769,607 +30748,134 @@ var thorough_default = {
30769
30748
  }
30770
30749
  };
30771
30750
 
30772
- // src/core/config/config.ts
30773
- import fs10 from "fs";
30774
- import os2 from "os";
30775
- import path14 from "path";
30776
- import { isDeepStrictEqual } from "util";
30751
+ // node_modules/zod/v3/external.js
30752
+ var exports_external = {};
30753
+ __export(exports_external, {
30754
+ void: () => voidType,
30755
+ util: () => util,
30756
+ unknown: () => unknownType,
30757
+ union: () => unionType,
30758
+ undefined: () => undefinedType,
30759
+ tuple: () => tupleType,
30760
+ transformer: () => effectsType,
30761
+ symbol: () => symbolType,
30762
+ string: () => stringType,
30763
+ strictObject: () => strictObjectType,
30764
+ setErrorMap: () => setErrorMap,
30765
+ set: () => setType,
30766
+ record: () => recordType,
30767
+ quotelessJson: () => quotelessJson,
30768
+ promise: () => promiseType,
30769
+ preprocess: () => preprocessType,
30770
+ pipeline: () => pipelineType,
30771
+ ostring: () => ostring,
30772
+ optional: () => optionalType,
30773
+ onumber: () => onumber,
30774
+ oboolean: () => oboolean,
30775
+ objectUtil: () => objectUtil,
30776
+ object: () => objectType,
30777
+ number: () => numberType,
30778
+ nullable: () => nullableType,
30779
+ null: () => nullType,
30780
+ never: () => neverType,
30781
+ nativeEnum: () => nativeEnumType,
30782
+ nan: () => nanType,
30783
+ map: () => mapType,
30784
+ makeIssue: () => makeIssue,
30785
+ literal: () => literalType,
30786
+ lazy: () => lazyType,
30787
+ late: () => late,
30788
+ isValid: () => isValid,
30789
+ isDirty: () => isDirty,
30790
+ isAsync: () => isAsync,
30791
+ isAborted: () => isAborted,
30792
+ intersection: () => intersectionType,
30793
+ instanceof: () => instanceOfType,
30794
+ getParsedType: () => getParsedType,
30795
+ getErrorMap: () => getErrorMap,
30796
+ function: () => functionType,
30797
+ enum: () => enumType,
30798
+ effect: () => effectsType,
30799
+ discriminatedUnion: () => discriminatedUnionType,
30800
+ defaultErrorMap: () => en_default,
30801
+ datetimeRegex: () => datetimeRegex,
30802
+ date: () => dateType,
30803
+ custom: () => custom,
30804
+ coerce: () => coerce,
30805
+ boolean: () => booleanType,
30806
+ bigint: () => bigIntType,
30807
+ array: () => arrayType,
30808
+ any: () => anyType,
30809
+ addIssueToContext: () => addIssueToContext,
30810
+ ZodVoid: () => ZodVoid,
30811
+ ZodUnknown: () => ZodUnknown,
30812
+ ZodUnion: () => ZodUnion,
30813
+ ZodUndefined: () => ZodUndefined,
30814
+ ZodType: () => ZodType,
30815
+ ZodTuple: () => ZodTuple,
30816
+ ZodTransformer: () => ZodEffects,
30817
+ ZodSymbol: () => ZodSymbol,
30818
+ ZodString: () => ZodString,
30819
+ ZodSet: () => ZodSet,
30820
+ ZodSchema: () => ZodType,
30821
+ ZodRecord: () => ZodRecord,
30822
+ ZodReadonly: () => ZodReadonly,
30823
+ ZodPromise: () => ZodPromise,
30824
+ ZodPipeline: () => ZodPipeline,
30825
+ ZodParsedType: () => ZodParsedType,
30826
+ ZodOptional: () => ZodOptional,
30827
+ ZodObject: () => ZodObject,
30828
+ ZodNumber: () => ZodNumber,
30829
+ ZodNullable: () => ZodNullable,
30830
+ ZodNull: () => ZodNull,
30831
+ ZodNever: () => ZodNever,
30832
+ ZodNativeEnum: () => ZodNativeEnum,
30833
+ ZodNaN: () => ZodNaN,
30834
+ ZodMap: () => ZodMap,
30835
+ ZodLiteral: () => ZodLiteral,
30836
+ ZodLazy: () => ZodLazy,
30837
+ ZodIssueCode: () => ZodIssueCode,
30838
+ ZodIntersection: () => ZodIntersection,
30839
+ ZodFunction: () => ZodFunction,
30840
+ ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
30841
+ ZodError: () => ZodError,
30842
+ ZodEnum: () => ZodEnum,
30843
+ ZodEffects: () => ZodEffects,
30844
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
30845
+ ZodDefault: () => ZodDefault,
30846
+ ZodDate: () => ZodDate,
30847
+ ZodCatch: () => ZodCatch,
30848
+ ZodBranded: () => ZodBranded,
30849
+ ZodBoolean: () => ZodBoolean,
30850
+ ZodBigInt: () => ZodBigInt,
30851
+ ZodArray: () => ZodArray,
30852
+ ZodAny: () => ZodAny,
30853
+ Schema: () => ZodType,
30854
+ ParseStatus: () => ParseStatus,
30855
+ OK: () => OK,
30856
+ NEVER: () => NEVER,
30857
+ INVALID: () => INVALID,
30858
+ EMPTY_PATH: () => EMPTY_PATH,
30859
+ DIRTY: () => DIRTY,
30860
+ BRAND: () => BRAND
30861
+ });
30777
30862
 
30778
- // src/core/extra-params.ts
30779
- var EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS = [
30780
- "model",
30781
- "messages",
30782
- "temperature",
30783
- "maxtokens",
30784
- "responseformat",
30785
- "stream",
30786
- "streamoptions",
30787
- "enablethinking",
30788
- "reasoningeffort",
30789
- "chattemplatekwargs"
30790
- ];
30791
- var EXTRA_PARAMS_CREDENTIAL_KEYS = [
30792
- "authorization",
30793
- "headers",
30794
- "apikey",
30795
- "token",
30796
- "password",
30797
- "secret",
30798
- "cookie",
30799
- "setcookie"
30800
- ];
30801
- var PROTECTED_TOP_LEVEL_KEYS = new Set(EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS);
30802
- var CREDENTIAL_KEYS = new Set(EXTRA_PARAMS_CREDENTIAL_KEYS);
30803
- var LEGACY_EXTRA_PARAMS_FIELD = {
30804
- model: "model",
30805
- temperature: "temperature",
30806
- maxtokens: "maxTokens",
30807
- enablethinking: "enableThinking",
30808
- reasoningeffort: "reasoningEffort"
30809
- };
30810
- var LIFTABLE_EXTRA_PARAMS_KEYS = new Set(["temperature", "maxtokens", "enablethinking", "reasoningeffort"]);
30811
- var EXTRA_PARAMS_NO_FIELD_REMEDY = {
30812
- messages: "AKM builds the request messages internally \u2014 remove it from extraParams",
30813
- responseformat: "AKM controls the response format internally \u2014 remove it from extraParams",
30814
- stream: "AKM controls streaming internally \u2014 remove it from extraParams",
30815
- streamoptions: "AKM controls streaming internally \u2014 remove it from extraParams",
30816
- chattemplatekwargs: "set engines.<name>.enableThinking instead of chat_template_kwargs.enable_thinking"
30817
- };
30818
- function protectedKeyRemedy(normalized) {
30819
- const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
30820
- if (field) {
30821
- const note = normalized === "reasoningeffort" ? " (moved to a first-class field in 0.9.2)" : "";
30822
- return `set engines.<name>.${field} instead${note}`;
30823
- }
30824
- return EXTRA_PARAMS_NO_FIELD_REMEDY[normalized];
30825
- }
30826
- function normalizeExtraParamKey(key) {
30827
- return key.toLowerCase().replace(/[^a-z0-9]/g, "");
30828
- }
30829
- function validateExtraParams(value) {
30830
- if (!value || typeof value !== "object" || Array.isArray(value)) {
30831
- return [{ path: [], message: "must be an object" }];
30863
+ // node_modules/zod/v3/helpers/util.js
30864
+ var util;
30865
+ (function(util2) {
30866
+ util2.assertEqual = (_) => {};
30867
+ function assertIs(_arg) {}
30868
+ util2.assertIs = assertIs;
30869
+ function assertNever2(_x) {
30870
+ throw new Error;
30832
30871
  }
30833
- const issues = [];
30834
- const seen = new WeakSet;
30835
- const visit2 = (entry, path12) => {
30836
- if (Array.isArray(entry)) {
30837
- if (seen.has(entry))
30838
- return;
30839
- seen.add(entry);
30840
- entry.forEach((child, index) => {
30841
- visit2(child, [...path12, index]);
30842
- });
30843
- return;
30844
- }
30845
- if (!entry || typeof entry !== "object")
30846
- return;
30847
- if (seen.has(entry))
30848
- return;
30849
- seen.add(entry);
30850
- for (const [key, child] of Object.entries(entry)) {
30851
- const normalized = normalizeExtraParamKey(key);
30852
- if (path12.length === 0 && PROTECTED_TOP_LEVEL_KEYS.has(normalized)) {
30853
- const remedy = protectedKeyRemedy(normalized);
30854
- issues.push({
30855
- path: [key],
30856
- message: remedy ? `${key} is protected by AKM \u2014 ${remedy}.` : `${key} is protected by AKM`
30857
- });
30858
- }
30859
- if (CREDENTIAL_KEYS.has(normalized)) {
30860
- issues.push({ path: [...path12, key], message: `${key} cannot carry credentials` });
30861
- }
30862
- visit2(child, [...path12, key]);
30872
+ util2.assertNever = assertNever2;
30873
+ util2.arrayToEnum = (items) => {
30874
+ const obj = {};
30875
+ for (const item of items) {
30876
+ obj[item] = item;
30863
30877
  }
30864
- };
30865
- visit2(value, []);
30866
- return issues;
30867
- }
30868
- function formatExtraParamsIssue(label, issue) {
30869
- const suffix = issue.path.map((part) => typeof part === "number" ? `[${part}]` : `.${part}`).join("");
30870
- return `${label}${suffix} ${issue.message}`;
30871
- }
30872
- function liftLegacyEngineExtraParams(raw) {
30873
- const lifted = [];
30874
- const conflicts = [];
30875
- const rawEngines = raw.engines;
30876
- if (!isRecord(rawEngines)) {
30877
- return { config: raw, lifted, conflicts };
30878
- }
30879
- const engines = {};
30880
- let anyEngineChanged = false;
30881
- for (const [name, engineValue] of Object.entries(rawEngines)) {
30882
- if (!isRecord(engineValue) || !isRecord(engineValue.extraParams)) {
30883
- engines[name] = engineValue;
30884
- continue;
30885
- }
30886
- const engine = { ...engineValue };
30887
- const extraParams = { ...engineValue.extraParams };
30888
- let engineChanged = false;
30889
- for (const [rawKey, value] of Object.entries(engineValue.extraParams)) {
30890
- const normalized = normalizeExtraParamKey(rawKey);
30891
- if (!LIFTABLE_EXTRA_PARAMS_KEYS.has(normalized))
30892
- continue;
30893
- const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
30894
- if (!field)
30895
- continue;
30896
- const existing = engine[field];
30897
- if (existing !== undefined && existing !== value) {
30898
- conflicts.push({ engine: name, key: rawKey, field, extraParamsValue: value, fieldValue: existing });
30899
- continue;
30900
- }
30901
- delete extraParams[rawKey];
30902
- engineChanged = true;
30903
- if (existing === value) {
30904
- lifted.push(`engines.${name}.extraParams.${rawKey} is redundant \u2014 engines.${name}.${field} is already set to the same value; dropped the extraParams entry`);
30905
- continue;
30906
- }
30907
- engine[field] = value;
30908
- lifted.push(`engines.${name}.extraParams.${rawKey} -> engines.${name}.${field}`);
30909
- }
30910
- if (!engineChanged) {
30911
- engines[name] = engineValue;
30912
- continue;
30913
- }
30914
- anyEngineChanged = true;
30915
- if (Object.keys(extraParams).length > 0) {
30916
- engine.extraParams = extraParams;
30917
- } else {
30918
- delete engine.extraParams;
30919
- }
30920
- engines[name] = engine;
30921
- }
30922
- if (!anyEngineChanged) {
30923
- return { config: raw, lifted, conflicts };
30924
- }
30925
- return { config: { ...raw, engines }, lifted, conflicts };
30926
- }
30927
-
30928
- // src/core/config/config-io.ts
30929
- import fs8 from "fs";
30930
- import path12 from "path";
30931
-
30932
- // src/core/file-lock.ts
30933
- import { randomUUID } from "crypto";
30934
- import fs7 from "fs";
30935
- function readLockSnapshot(lockPath) {
30936
- let fd;
30937
- try {
30938
- fd = fs7.openSync(lockPath, "r");
30939
- } catch (err) {
30940
- if (err.code === "ENOENT")
30941
- return;
30942
- throw err;
30943
- }
30944
- try {
30945
- const rawContent = readTextFileDescriptorWithLimit(fd, MAX_LOCK_METADATA_BYTES, "Lock metadata", lockPath);
30946
- const stat = fs7.fstatSync(fd);
30947
- return {
30948
- rawContent,
30949
- identity: { dev: stat.dev, ino: stat.ino, size: stat.size, mtimeMs: stat.mtimeMs }
30950
- };
30951
- } finally {
30952
- fs7.closeSync(fd);
30953
- }
30954
- }
30955
- function sameIdentity(left, right) {
30956
- return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs;
30957
- }
30958
- function releaseLockRaw(lockPath) {
30959
- try {
30960
- fs7.unlinkSync(lockPath);
30961
- } catch {}
30962
- }
30963
- function tryAcquireLockSync(lockPath, payload) {
30964
- try {
30965
- fs7.writeFileSync(lockPath, payload, { flag: "wx" });
30966
- } catch (err) {
30967
- if (err.code === "EEXIST")
30968
- return;
30969
- throw err;
30970
- }
30971
- let snapshot;
30972
- try {
30973
- snapshot = readLockSnapshot(lockPath);
30974
- } catch (error2) {
30975
- releaseLockRaw(lockPath);
30976
- throw error2;
30977
- }
30978
- if (!snapshot) {
30979
- releaseLockRaw(lockPath);
30980
- throw new Error(`Could not read newly acquired lock at ${lockPath}.`);
30981
- }
30982
- return { lockPath, ...snapshot };
30983
- }
30984
- function launcherPidFromEnv() {
30985
- const raw = process.env.AKM_LAUNCHER_PID;
30986
- if (!raw)
30987
- return;
30988
- const pid = Number.parseInt(raw, 10);
30989
- return Number.isInteger(pid) && pid > 0 ? pid : undefined;
30990
- }
30991
- function createLockPayload(metadata = {}) {
30992
- const launcherPid = launcherPidFromEnv();
30993
- return JSON.stringify({
30994
- ...metadata,
30995
- pid: process.pid,
30996
- ...launcherPid !== undefined ? { launcherPid } : {},
30997
- lockId: randomUUID()
30998
- });
30999
- }
31000
- function probeLock(lockPath, opts) {
31001
- let snapshot;
31002
- try {
31003
- snapshot = readLockSnapshot(lockPath);
31004
- } catch (error2) {
31005
- const code = error2?.code;
31006
- if (code === "EACCES" || code === "EPERM")
31007
- return { state: "inaccessible", code };
31008
- return { state: "stale", reason: "unreadable" };
31009
- }
31010
- if (!snapshot)
31011
- return { state: "absent" };
31012
- const { rawContent, identity: identity3 } = snapshot;
31013
- const ageMs = Date.now() - identity3.mtimeMs;
31014
- const { holderPid, launcherPid } = extractLockIdentity(rawContent);
31015
- if (holderPid === undefined) {
31016
- return { state: "stale", reason: "invalid_pid", ageMs, rawContent, identity: identity3 };
31017
- }
31018
- if (!isProcessAlive(holderPid)) {
31019
- return { state: "stale", reason: "pid_dead", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
31020
- }
31021
- if (opts?.staleAfterMs !== undefined && ageMs > opts.staleAfterMs) {
31022
- return { state: "stale", reason: "age_exceeded", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
31023
- }
31024
- return { state: "held", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
31025
- }
31026
- function reclaimStaleLock(lockPath, probe, options) {
31027
- if (probe.rawContent === undefined || probe.identity === undefined)
31028
- return false;
31029
- const expectedContent = probe.rawContent;
31030
- const expectedIdentity = probe.identity;
31031
- let current;
31032
- try {
31033
- current = readLockSnapshot(lockPath);
31034
- } catch {
31035
- return false;
31036
- }
31037
- if (!current || current.rawContent !== expectedContent || !sameIdentity(current.identity, expectedIdentity)) {
31038
- return false;
31039
- }
31040
- const quarantinePath = `${lockPath}.stale-${process.pid}-${randomUUID()}`;
31041
- try {
31042
- fs7.renameSync(lockPath, quarantinePath);
31043
- } catch (err) {
31044
- if (err.code === "ENOENT")
31045
- return false;
31046
- throw err;
31047
- }
31048
- let quarantined;
31049
- try {
31050
- quarantined = readLockSnapshot(quarantinePath);
31051
- } catch {
31052
- quarantined = undefined;
31053
- }
31054
- if (!quarantined || quarantined.rawContent !== expectedContent || !sameIdentity(quarantined.identity, expectedIdentity)) {
31055
- try {
31056
- fs7.linkSync(quarantinePath, lockPath);
31057
- } catch (err) {
31058
- if (err.code !== "EEXIST")
31059
- throw err;
31060
- }
31061
- releaseLockRaw(quarantinePath);
31062
- return false;
31063
- }
31064
- options?.afterQuarantineVerified?.();
31065
- try {
31066
- fs7.unlinkSync(quarantinePath);
31067
- return true;
31068
- } catch (err) {
31069
- if (err.code === "ENOENT")
31070
- return false;
31071
- throw err;
31072
- }
31073
- }
31074
- function releaseLock(ownership) {
31075
- const { lockPath } = ownership;
31076
- let current;
31077
- try {
31078
- current = readLockSnapshot(lockPath);
31079
- } catch {
31080
- return;
31081
- }
31082
- if (current && current.rawContent === ownership.rawContent && sameIdentity(current.identity, ownership.identity)) {
31083
- releaseLockRaw(lockPath);
31084
- }
31085
- }
31086
- function extractLockIdentity(content) {
31087
- const trimmed = content.trim();
31088
- if (!trimmed)
31089
- return {};
31090
- if (trimmed.startsWith("{")) {
31091
- try {
31092
- const parsed = JSON.parse(trimmed);
31093
- const pid2 = typeof parsed.pid === "number" ? parsed.pid : Number.NaN;
31094
- const rawLauncherPid = typeof parsed.launcherPid === "number" ? parsed.launcherPid : Number.NaN;
31095
- return {
31096
- holderPid: Number.isInteger(pid2) && pid2 > 0 ? pid2 : undefined,
31097
- launcherPid: Number.isInteger(rawLauncherPid) && rawLauncherPid > 0 ? rawLauncherPid : undefined
31098
- };
31099
- } catch {
31100
- return {};
31101
- }
31102
- }
31103
- const pid = Number.parseInt(trimmed, 10);
31104
- return { holderPid: Number.isInteger(pid) && pid > 0 ? pid : undefined };
31105
- }
31106
-
31107
- // src/core/config/config-io.ts
31108
- function readConfigText(configPath) {
31109
- try {
31110
- return readTextFile(configPath, "Config file");
31111
- } catch (err) {
31112
- if (err.code === "ENOENT")
31113
- return;
31114
- throw err;
31115
- }
31116
- }
31117
- function parseConfigText(text, sourcePath) {
31118
- const stripped = stripJsonComments(text);
31119
- const where = sourcePath ? ` at ${sourcePath}` : "";
31120
- let parsed;
31121
- try {
31122
- parsed = JSON.parse(stripped);
31123
- } catch (err) {
31124
- const detail = err instanceof Error ? err.message : String(err);
31125
- 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.");
31126
- }
31127
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
31128
- throw new ConfigError(`Config file${where} must contain a JSON object at the root, got ${describeJsonRoot(parsed)}.`, "INVALID_CONFIG_FILE");
31129
- }
31130
- return parsed;
31131
- }
31132
- function describeJsonRoot(value) {
31133
- if (value === null)
31134
- return "null";
31135
- if (Array.isArray(value))
31136
- return "an array";
31137
- if (typeof value === "string")
31138
- return "a string";
31139
- if (typeof value === "number")
31140
- return "a number";
31141
- if (typeof value === "boolean")
31142
- return "a boolean";
31143
- return typeof value;
31144
- }
31145
- function writeConfigAtomic(configPath, config) {
31146
- writeFileAtomic(configPath, `${JSON.stringify(config, null, 2)}
31147
- `);
31148
- }
31149
- var MAX_CONFIG_BACKUPS = 5;
31150
- function backupExistingConfig(configPath, now = new Date) {
31151
- if (!fs8.existsSync(configPath))
31152
- return;
31153
- const backupDir = path12.join(getCacheDir(), "config-backups");
31154
- fs8.mkdirSync(backupDir, { recursive: true, mode: 448 });
31155
- fs8.chmodSync(backupDir, 448);
31156
- const timestamp = now.toISOString().replace(/[.:]/g, "-");
31157
- let sequence = 0;
31158
- let timestamped;
31159
- while (true) {
31160
- timestamped = path12.join(backupDir, `config-${timestamp}${sequence === 0 ? "" : `-${sequence}`}.json`);
31161
- try {
31162
- fs8.copyFileSync(configPath, timestamped, fs8.constants.COPYFILE_EXCL);
31163
- break;
31164
- } catch (error2) {
31165
- if (error2.code !== "EEXIST")
31166
- throw error2;
31167
- sequence++;
31168
- }
31169
- }
31170
- const latest = path12.join(backupDir, "config.latest.json");
31171
- fs8.copyFileSync(configPath, latest);
31172
- fs8.chmodSync(timestamped, 384);
31173
- fs8.chmodSync(latest, 384);
31174
- pruneOldBackups(backupDir);
31175
- return { timestamped, latest };
31176
- }
31177
- function pruneOldBackups(backupDir) {
31178
- pruneToNewest(backupDir, MAX_CONFIG_BACKUPS, (entry) => entry.isFile() && isTimestampedConfigBackup(entry.name));
31179
- }
31180
- function isTimestampedConfigBackup(name) {
31181
- return name.startsWith("config-") && name.endsWith(".json") && name !== "config.latest.json";
31182
- }
31183
- function pruneToNewest(dir, keep, select) {
31184
- let entries;
31185
- try {
31186
- entries = fs8.readdirSync(dir, { withFileTypes: true });
31187
- } catch {
31188
- return;
31189
- }
31190
- const candidates = entries.filter(select).map((entry) => {
31191
- const full = path12.join(dir, entry.name);
31192
- let mtime = 0;
31193
- try {
31194
- mtime = fs8.statSync(full).mtimeMs;
31195
- } catch {}
31196
- return { path: full, mtime };
31197
- }).sort((a, b) => b.mtime - a.mtime);
31198
- for (const stale of candidates.slice(keep)) {
31199
- try {
31200
- fs8.rmSync(stale.path, { recursive: true, force: true });
31201
- } catch {}
31202
- }
31203
- }
31204
- function getConfigLockPath() {
31205
- return path12.join(getConfigDir(), "config.json.lck");
31206
- }
31207
- var CONFIG_LOCK_MAX_RETRIES = 40;
31208
- var CONFIG_LOCK_RETRY_DELAY_MS = 50;
31209
- function sleepSyncMs(ms) {
31210
- sleepSync(ms);
31211
- }
31212
- function acquireConfigLock() {
31213
- const lockPath = getConfigLockPath();
31214
- try {
31215
- fs8.mkdirSync(path12.dirname(lockPath), { recursive: true });
31216
- } catch {}
31217
- for (let attempt = 0;attempt < CONFIG_LOCK_MAX_RETRIES; attempt++) {
31218
- try {
31219
- const ownership = tryAcquireLockSync(lockPath, createLockPayload());
31220
- if (ownership) {
31221
- return () => releaseLock(ownership);
31222
- }
31223
- } catch (error2) {
31224
- throw new ConfigError(`Unable to acquire config lock at ${lockPath}: ${error2 instanceof Error ? error2.message : String(error2)}`, "INVALID_CONFIG_FILE");
31225
- }
31226
- const probe = probeLock(lockPath);
31227
- if (probe.state === "stale" && reclaimStaleLock(lockPath, probe)) {
31228
- continue;
31229
- }
31230
- if (attempt < CONFIG_LOCK_MAX_RETRIES - 1) {
31231
- sleepSyncMs(CONFIG_LOCK_RETRY_DELAY_MS);
31232
- }
31233
- }
31234
- throw new ConfigError(`Timed out waiting for config lock at ${lockPath}. Another AKM process may be updating config.`, "INVALID_CONFIG_FILE");
31235
- }
31236
- function withConfigLock(fn) {
31237
- const release = acquireConfigLock();
31238
- try {
31239
- return fn();
31240
- } finally {
31241
- release();
31242
- }
31243
- }
31244
-
31245
- // node_modules/zod/v3/external.js
31246
- var exports_external = {};
31247
- __export(exports_external, {
31248
- void: () => voidType,
31249
- util: () => util,
31250
- unknown: () => unknownType,
31251
- union: () => unionType,
31252
- undefined: () => undefinedType,
31253
- tuple: () => tupleType,
31254
- transformer: () => effectsType,
31255
- symbol: () => symbolType,
31256
- string: () => stringType,
31257
- strictObject: () => strictObjectType,
31258
- setErrorMap: () => setErrorMap,
31259
- set: () => setType,
31260
- record: () => recordType,
31261
- quotelessJson: () => quotelessJson,
31262
- promise: () => promiseType,
31263
- preprocess: () => preprocessType,
31264
- pipeline: () => pipelineType,
31265
- ostring: () => ostring,
31266
- optional: () => optionalType,
31267
- onumber: () => onumber,
31268
- oboolean: () => oboolean,
31269
- objectUtil: () => objectUtil,
31270
- object: () => objectType,
31271
- number: () => numberType,
31272
- nullable: () => nullableType,
31273
- null: () => nullType,
31274
- never: () => neverType,
31275
- nativeEnum: () => nativeEnumType,
31276
- nan: () => nanType,
31277
- map: () => mapType,
31278
- makeIssue: () => makeIssue,
31279
- literal: () => literalType,
31280
- lazy: () => lazyType,
31281
- late: () => late,
31282
- isValid: () => isValid,
31283
- isDirty: () => isDirty,
31284
- isAsync: () => isAsync,
31285
- isAborted: () => isAborted,
31286
- intersection: () => intersectionType,
31287
- instanceof: () => instanceOfType,
31288
- getParsedType: () => getParsedType,
31289
- getErrorMap: () => getErrorMap,
31290
- function: () => functionType,
31291
- enum: () => enumType,
31292
- effect: () => effectsType,
31293
- discriminatedUnion: () => discriminatedUnionType,
31294
- defaultErrorMap: () => en_default,
31295
- datetimeRegex: () => datetimeRegex,
31296
- date: () => dateType,
31297
- custom: () => custom,
31298
- coerce: () => coerce,
31299
- boolean: () => booleanType,
31300
- bigint: () => bigIntType,
31301
- array: () => arrayType,
31302
- any: () => anyType,
31303
- addIssueToContext: () => addIssueToContext,
31304
- ZodVoid: () => ZodVoid,
31305
- ZodUnknown: () => ZodUnknown,
31306
- ZodUnion: () => ZodUnion,
31307
- ZodUndefined: () => ZodUndefined,
31308
- ZodType: () => ZodType,
31309
- ZodTuple: () => ZodTuple,
31310
- ZodTransformer: () => ZodEffects,
31311
- ZodSymbol: () => ZodSymbol,
31312
- ZodString: () => ZodString,
31313
- ZodSet: () => ZodSet,
31314
- ZodSchema: () => ZodType,
31315
- ZodRecord: () => ZodRecord,
31316
- ZodReadonly: () => ZodReadonly,
31317
- ZodPromise: () => ZodPromise,
31318
- ZodPipeline: () => ZodPipeline,
31319
- ZodParsedType: () => ZodParsedType,
31320
- ZodOptional: () => ZodOptional,
31321
- ZodObject: () => ZodObject,
31322
- ZodNumber: () => ZodNumber,
31323
- ZodNullable: () => ZodNullable,
31324
- ZodNull: () => ZodNull,
31325
- ZodNever: () => ZodNever,
31326
- ZodNativeEnum: () => ZodNativeEnum,
31327
- ZodNaN: () => ZodNaN,
31328
- ZodMap: () => ZodMap,
31329
- ZodLiteral: () => ZodLiteral,
31330
- ZodLazy: () => ZodLazy,
31331
- ZodIssueCode: () => ZodIssueCode,
31332
- ZodIntersection: () => ZodIntersection,
31333
- ZodFunction: () => ZodFunction,
31334
- ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
31335
- ZodError: () => ZodError,
31336
- ZodEnum: () => ZodEnum,
31337
- ZodEffects: () => ZodEffects,
31338
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
31339
- ZodDefault: () => ZodDefault,
31340
- ZodDate: () => ZodDate,
31341
- ZodCatch: () => ZodCatch,
31342
- ZodBranded: () => ZodBranded,
31343
- ZodBoolean: () => ZodBoolean,
31344
- ZodBigInt: () => ZodBigInt,
31345
- ZodArray: () => ZodArray,
31346
- ZodAny: () => ZodAny,
31347
- Schema: () => ZodType,
31348
- ParseStatus: () => ParseStatus,
31349
- OK: () => OK,
31350
- NEVER: () => NEVER,
31351
- INVALID: () => INVALID,
31352
- EMPTY_PATH: () => EMPTY_PATH,
31353
- DIRTY: () => DIRTY,
31354
- BRAND: () => BRAND
31355
- });
31356
-
31357
- // node_modules/zod/v3/helpers/util.js
31358
- var util;
31359
- (function(util2) {
31360
- util2.assertEqual = (_) => {};
31361
- function assertIs(_arg) {}
31362
- util2.assertIs = assertIs;
31363
- function assertNever2(_x) {
31364
- throw new Error;
31365
- }
31366
- util2.assertNever = assertNever2;
31367
- util2.arrayToEnum = (items) => {
31368
- const obj = {};
31369
- for (const item of items) {
31370
- obj[item] = item;
31371
- }
31372
- return obj;
30878
+ return obj;
31373
30879
  };
31374
30880
  util2.getValidEnumValues = (obj) => {
31375
30881
  const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
@@ -31717,8 +31223,8 @@ function getErrorMap() {
31717
31223
  }
31718
31224
  // node_modules/zod/v3/helpers/parseUtil.js
31719
31225
  var makeIssue = (params) => {
31720
- const { data, path: path13, errorMaps, issueData } = params;
31721
- const fullPath = [...path13, ...issueData.path || []];
31226
+ const { data, path: path12, errorMaps, issueData } = params;
31227
+ const fullPath = [...path12, ...issueData.path || []];
31722
31228
  const fullIssue = {
31723
31229
  ...issueData,
31724
31230
  path: fullPath
@@ -31830,11 +31336,11 @@ var errorUtil;
31830
31336
 
31831
31337
  // node_modules/zod/v3/types.js
31832
31338
  class ParseInputLazyPath {
31833
- constructor(parent, value, path13, key) {
31339
+ constructor(parent, value, path12, key) {
31834
31340
  this._cachedPath = [];
31835
31341
  this.parent = parent;
31836
31342
  this.data = value;
31837
- this._path = path13;
31343
+ this._path = path12;
31838
31344
  this._key = key;
31839
31345
  }
31840
31346
  get path() {
@@ -35113,108 +34619,258 @@ function custom(check, _params = {}, fatal) {
35113
34619
  }
35114
34620
  });
35115
34621
  }
35116
- if (!r) {
35117
- const params = cleanParams(_params, data);
35118
- const _fatal = params.fatal ?? fatal ?? true;
35119
- ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
34622
+ if (!r) {
34623
+ const params = cleanParams(_params, data);
34624
+ const _fatal = params.fatal ?? fatal ?? true;
34625
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
34626
+ }
34627
+ return;
34628
+ });
34629
+ return ZodAny.create();
34630
+ }
34631
+ var late = {
34632
+ object: ZodObject.lazycreate
34633
+ };
34634
+ var ZodFirstPartyTypeKind;
34635
+ (function(ZodFirstPartyTypeKind2) {
34636
+ ZodFirstPartyTypeKind2["ZodString"] = "ZodString";
34637
+ ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";
34638
+ ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";
34639
+ ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";
34640
+ ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";
34641
+ ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";
34642
+ ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";
34643
+ ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";
34644
+ ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";
34645
+ ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";
34646
+ ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";
34647
+ ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";
34648
+ ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";
34649
+ ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";
34650
+ ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";
34651
+ ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";
34652
+ ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
34653
+ ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";
34654
+ ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";
34655
+ ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";
34656
+ ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";
34657
+ ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";
34658
+ ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";
34659
+ ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";
34660
+ ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";
34661
+ ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";
34662
+ ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";
34663
+ ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";
34664
+ ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";
34665
+ ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";
34666
+ ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";
34667
+ ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";
34668
+ ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";
34669
+ ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";
34670
+ ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";
34671
+ ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";
34672
+ })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
34673
+ var instanceOfType = (cls, params = {
34674
+ message: `Input not instance of ${cls.name}`
34675
+ }) => custom((data) => data instanceof cls, params);
34676
+ var stringType = ZodString.create;
34677
+ var numberType = ZodNumber.create;
34678
+ var nanType = ZodNaN.create;
34679
+ var bigIntType = ZodBigInt.create;
34680
+ var booleanType = ZodBoolean.create;
34681
+ var dateType = ZodDate.create;
34682
+ var symbolType = ZodSymbol.create;
34683
+ var undefinedType = ZodUndefined.create;
34684
+ var nullType = ZodNull.create;
34685
+ var anyType = ZodAny.create;
34686
+ var unknownType = ZodUnknown.create;
34687
+ var neverType = ZodNever.create;
34688
+ var voidType = ZodVoid.create;
34689
+ var arrayType = ZodArray.create;
34690
+ var objectType = ZodObject.create;
34691
+ var strictObjectType = ZodObject.strictCreate;
34692
+ var unionType = ZodUnion.create;
34693
+ var discriminatedUnionType = ZodDiscriminatedUnion.create;
34694
+ var intersectionType = ZodIntersection.create;
34695
+ var tupleType = ZodTuple.create;
34696
+ var recordType = ZodRecord.create;
34697
+ var mapType = ZodMap.create;
34698
+ var setType = ZodSet.create;
34699
+ var functionType = ZodFunction.create;
34700
+ var lazyType = ZodLazy.create;
34701
+ var literalType = ZodLiteral.create;
34702
+ var enumType = ZodEnum.create;
34703
+ var nativeEnumType = ZodNativeEnum.create;
34704
+ var promiseType = ZodPromise.create;
34705
+ var effectsType = ZodEffects.create;
34706
+ var optionalType = ZodOptional.create;
34707
+ var nullableType = ZodNullable.create;
34708
+ var preprocessType = ZodEffects.createWithPreprocess;
34709
+ var pipelineType = ZodPipeline.create;
34710
+ var ostring = () => stringType().optional();
34711
+ var onumber = () => numberType().optional();
34712
+ var oboolean = () => booleanType().optional();
34713
+ var coerce = {
34714
+ string: (arg) => ZodString.create({ ...arg, coerce: true }),
34715
+ number: (arg) => ZodNumber.create({ ...arg, coerce: true }),
34716
+ boolean: (arg) => ZodBoolean.create({
34717
+ ...arg,
34718
+ coerce: true
34719
+ }),
34720
+ bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }),
34721
+ date: (arg) => ZodDate.create({ ...arg, coerce: true })
34722
+ };
34723
+ var NEVER = INVALID;
34724
+ // src/core/extra-params.ts
34725
+ var EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS = [
34726
+ "model",
34727
+ "messages",
34728
+ "temperature",
34729
+ "maxtokens",
34730
+ "responseformat",
34731
+ "stream",
34732
+ "streamoptions",
34733
+ "enablethinking",
34734
+ "reasoningeffort",
34735
+ "chattemplatekwargs"
34736
+ ];
34737
+ var EXTRA_PARAMS_CREDENTIAL_KEYS = [
34738
+ "authorization",
34739
+ "headers",
34740
+ "apikey",
34741
+ "token",
34742
+ "password",
34743
+ "secret",
34744
+ "cookie",
34745
+ "setcookie"
34746
+ ];
34747
+ var PROTECTED_TOP_LEVEL_KEYS = new Set(EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS);
34748
+ var CREDENTIAL_KEYS = new Set(EXTRA_PARAMS_CREDENTIAL_KEYS);
34749
+ var LEGACY_EXTRA_PARAMS_FIELD = {
34750
+ model: "model",
34751
+ temperature: "temperature",
34752
+ maxtokens: "maxTokens",
34753
+ enablethinking: "enableThinking",
34754
+ reasoningeffort: "reasoningEffort"
34755
+ };
34756
+ var LIFTABLE_EXTRA_PARAMS_KEYS = new Set(["temperature", "maxtokens", "enablethinking", "reasoningeffort"]);
34757
+ var EXTRA_PARAMS_NO_FIELD_REMEDY = {
34758
+ messages: "AKM builds the request messages internally \u2014 remove it from extraParams",
34759
+ responseformat: "AKM controls the response format internally \u2014 remove it from extraParams",
34760
+ stream: "AKM controls streaming internally \u2014 remove it from extraParams",
34761
+ streamoptions: "AKM controls streaming internally \u2014 remove it from extraParams",
34762
+ chattemplatekwargs: "set engines.<name>.enableThinking instead of chat_template_kwargs.enable_thinking"
34763
+ };
34764
+ function protectedKeyRemedy(normalized) {
34765
+ const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
34766
+ if (field) {
34767
+ const note = normalized === "reasoningeffort" ? " (moved to a first-class field in 0.9.2)" : "";
34768
+ return `set engines.<name>.${field} instead${note}`;
34769
+ }
34770
+ return EXTRA_PARAMS_NO_FIELD_REMEDY[normalized];
34771
+ }
34772
+ function normalizeExtraParamKey(key) {
34773
+ return key.toLowerCase().replace(/[^a-z0-9]/g, "");
34774
+ }
34775
+ function validateExtraParams(value) {
34776
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
34777
+ return [{ path: [], message: "must be an object" }];
34778
+ }
34779
+ const issues = [];
34780
+ const seen = new WeakSet;
34781
+ const visit2 = (entry, path12) => {
34782
+ if (Array.isArray(entry)) {
34783
+ if (seen.has(entry))
34784
+ return;
34785
+ seen.add(entry);
34786
+ entry.forEach((child, index) => {
34787
+ visit2(child, [...path12, index]);
34788
+ });
34789
+ return;
34790
+ }
34791
+ if (!entry || typeof entry !== "object")
34792
+ return;
34793
+ if (seen.has(entry))
34794
+ return;
34795
+ seen.add(entry);
34796
+ for (const [key, child] of Object.entries(entry)) {
34797
+ const normalized = normalizeExtraParamKey(key);
34798
+ if (path12.length === 0 && PROTECTED_TOP_LEVEL_KEYS.has(normalized)) {
34799
+ const remedy = protectedKeyRemedy(normalized);
34800
+ issues.push({
34801
+ path: [key],
34802
+ message: remedy ? `${key} is protected by AKM \u2014 ${remedy}.` : `${key} is protected by AKM`
34803
+ });
34804
+ }
34805
+ if (CREDENTIAL_KEYS.has(normalized)) {
34806
+ issues.push({ path: [...path12, key], message: `${key} cannot carry credentials` });
34807
+ }
34808
+ visit2(child, [...path12, key]);
34809
+ }
34810
+ };
34811
+ visit2(value, []);
34812
+ return issues;
34813
+ }
34814
+ function formatExtraParamsIssue(label, issue) {
34815
+ const suffix = issue.path.map((part) => typeof part === "number" ? `[${part}]` : `.${part}`).join("");
34816
+ return `${label}${suffix} ${issue.message}`;
34817
+ }
34818
+ function liftLegacyEngineExtraParams(raw) {
34819
+ const lifted = [];
34820
+ const conflicts = [];
34821
+ const rawEngines = raw.engines;
34822
+ if (!isRecord(rawEngines)) {
34823
+ return { config: raw, lifted, conflicts };
34824
+ }
34825
+ const engines = {};
34826
+ let anyEngineChanged = false;
34827
+ for (const [name, engineValue] of Object.entries(rawEngines)) {
34828
+ if (!isRecord(engineValue) || !isRecord(engineValue.extraParams)) {
34829
+ engines[name] = engineValue;
34830
+ continue;
34831
+ }
34832
+ const engine = { ...engineValue };
34833
+ const extraParams = { ...engineValue.extraParams };
34834
+ let engineChanged = false;
34835
+ for (const [rawKey, value] of Object.entries(engineValue.extraParams)) {
34836
+ const normalized = normalizeExtraParamKey(rawKey);
34837
+ if (!LIFTABLE_EXTRA_PARAMS_KEYS.has(normalized))
34838
+ continue;
34839
+ const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
34840
+ if (!field)
34841
+ continue;
34842
+ const existing = engine[field];
34843
+ if (existing !== undefined && existing !== value) {
34844
+ conflicts.push({ engine: name, key: rawKey, field, extraParamsValue: value, fieldValue: existing });
34845
+ continue;
34846
+ }
34847
+ delete extraParams[rawKey];
34848
+ engineChanged = true;
34849
+ if (existing === value) {
34850
+ lifted.push(`engines.${name}.extraParams.${rawKey} is redundant \u2014 engines.${name}.${field} is already set to the same value; dropped the extraParams entry`);
34851
+ continue;
35120
34852
  }
35121
- return;
35122
- });
35123
- return ZodAny.create();
34853
+ engine[field] = value;
34854
+ lifted.push(`engines.${name}.extraParams.${rawKey} -> engines.${name}.${field}`);
34855
+ }
34856
+ if (!engineChanged) {
34857
+ engines[name] = engineValue;
34858
+ continue;
34859
+ }
34860
+ anyEngineChanged = true;
34861
+ if (Object.keys(extraParams).length > 0) {
34862
+ engine.extraParams = extraParams;
34863
+ } else {
34864
+ delete engine.extraParams;
34865
+ }
34866
+ engines[name] = engine;
34867
+ }
34868
+ if (!anyEngineChanged) {
34869
+ return { config: raw, lifted, conflicts };
34870
+ }
34871
+ return { config: { ...raw, engines }, lifted, conflicts };
35124
34872
  }
35125
- var late = {
35126
- object: ZodObject.lazycreate
35127
- };
35128
- var ZodFirstPartyTypeKind;
35129
- (function(ZodFirstPartyTypeKind2) {
35130
- ZodFirstPartyTypeKind2["ZodString"] = "ZodString";
35131
- ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";
35132
- ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";
35133
- ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";
35134
- ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";
35135
- ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";
35136
- ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";
35137
- ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";
35138
- ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";
35139
- ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";
35140
- ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";
35141
- ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";
35142
- ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";
35143
- ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";
35144
- ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";
35145
- ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";
35146
- ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
35147
- ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";
35148
- ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";
35149
- ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";
35150
- ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";
35151
- ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";
35152
- ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";
35153
- ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";
35154
- ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";
35155
- ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";
35156
- ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";
35157
- ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";
35158
- ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";
35159
- ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";
35160
- ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";
35161
- ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";
35162
- ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";
35163
- ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";
35164
- ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";
35165
- ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";
35166
- })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
35167
- var instanceOfType = (cls, params = {
35168
- message: `Input not instance of ${cls.name}`
35169
- }) => custom((data) => data instanceof cls, params);
35170
- var stringType = ZodString.create;
35171
- var numberType = ZodNumber.create;
35172
- var nanType = ZodNaN.create;
35173
- var bigIntType = ZodBigInt.create;
35174
- var booleanType = ZodBoolean.create;
35175
- var dateType = ZodDate.create;
35176
- var symbolType = ZodSymbol.create;
35177
- var undefinedType = ZodUndefined.create;
35178
- var nullType = ZodNull.create;
35179
- var anyType = ZodAny.create;
35180
- var unknownType = ZodUnknown.create;
35181
- var neverType = ZodNever.create;
35182
- var voidType = ZodVoid.create;
35183
- var arrayType = ZodArray.create;
35184
- var objectType = ZodObject.create;
35185
- var strictObjectType = ZodObject.strictCreate;
35186
- var unionType = ZodUnion.create;
35187
- var discriminatedUnionType = ZodDiscriminatedUnion.create;
35188
- var intersectionType = ZodIntersection.create;
35189
- var tupleType = ZodTuple.create;
35190
- var recordType = ZodRecord.create;
35191
- var mapType = ZodMap.create;
35192
- var setType = ZodSet.create;
35193
- var functionType = ZodFunction.create;
35194
- var lazyType = ZodLazy.create;
35195
- var literalType = ZodLiteral.create;
35196
- var enumType = ZodEnum.create;
35197
- var nativeEnumType = ZodNativeEnum.create;
35198
- var promiseType = ZodPromise.create;
35199
- var effectsType = ZodEffects.create;
35200
- var optionalType = ZodOptional.create;
35201
- var nullableType = ZodNullable.create;
35202
- var preprocessType = ZodEffects.createWithPreprocess;
35203
- var pipelineType = ZodPipeline.create;
35204
- var ostring = () => stringType().optional();
35205
- var onumber = () => numberType().optional();
35206
- var oboolean = () => booleanType().optional();
35207
- var coerce = {
35208
- string: (arg) => ZodString.create({ ...arg, coerce: true }),
35209
- number: (arg) => ZodNumber.create({ ...arg, coerce: true }),
35210
- boolean: (arg) => ZodBoolean.create({
35211
- ...arg,
35212
- coerce: true
35213
- }),
35214
- bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }),
35215
- date: (arg) => ZodDate.create({ ...arg, coerce: true })
35216
- };
35217
- var NEVER = INVALID;
34873
+
35218
34874
  // src/core/config/schema/primitives.ts
35219
34875
  var CURRENT_CONFIG_VERSION = "0.9.0";
35220
34876
  var positiveInt = exports_external.number().int().positive();
@@ -35507,8 +35163,6 @@ var CONSOLIDATE_PROCESS_FIELDS = {
35507
35163
  limit: processLimitField,
35508
35164
  minPoolSize: exports_external.number().int().min(0).optional(),
35509
35165
  maxChunkSize: exports_external.number().int().min(1).max(50).optional(),
35510
- incrementalSince: exports_external.string().optional(),
35511
- neighborsPerChanged: exports_external.number().int().min(1).optional(),
35512
35166
  p90ChunkSecondsDefault: exports_external.number().finite().positive().optional(),
35513
35167
  antiCollapse: antiCollapseField
35514
35168
  };
@@ -35516,13 +35170,6 @@ var MEMORY_INFERENCE_PROCESS_FIELDS = {
35516
35170
  minPendingCount: exports_external.number().int().min(0).optional(),
35517
35171
  cls: clsField
35518
35172
  };
35519
- var GRAPH_EXTRACTION_PROCESS_FIELDS = {
35520
- topN: positiveInt.optional(),
35521
- includeTypes: exports_external.array(exports_external.string().min(1)).min(1).optional(),
35522
- batchSize: positiveInt.optional(),
35523
- fullScan: exports_external.boolean().optional(),
35524
- maxChunksPerAsset: positiveInt.optional()
35525
- };
35526
35173
  var EXTRACT_PROCESS_FIELDS = {
35527
35174
  defaultSince: exports_external.string().min(1).optional(),
35528
35175
  maxTotalChars: positiveInt.optional(),
@@ -35558,7 +35205,6 @@ var ImproveProcessConfigSchema = exports_external.object({
35558
35205
  ...DISTILL_PROCESS_FIELDS,
35559
35206
  ...CONSOLIDATE_PROCESS_FIELDS,
35560
35207
  ...MEMORY_INFERENCE_PROCESS_FIELDS,
35561
- ...GRAPH_EXTRACTION_PROCESS_FIELDS,
35562
35208
  ...EXTRACT_PROCESS_FIELDS,
35563
35209
  ...TRIAGE_PROCESS_FIELDS,
35564
35210
  ...PROACTIVE_MAINTENANCE_PROCESS_FIELDS
@@ -35567,17 +35213,16 @@ var ReflectProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BA
35567
35213
  var DistillProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...DISTILL_PROCESS_FIELDS }).passthrough().superRefine(rejectExcludeRefPrefixesOutsideReflect);
35568
35214
  var ConsolidateProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...CONSOLIDATE_PROCESS_FIELDS }).passthrough().superRefine(rejectExcludeRefPrefixesOutsideReflect);
35569
35215
  var MemoryInferenceProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...MEMORY_INFERENCE_PROCESS_FIELDS }).passthrough();
35570
- var GraphExtractionProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...GRAPH_EXTRACTION_PROCESS_FIELDS }).passthrough();
35571
35216
  var ExtractProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...EXTRACT_PROCESS_FIELDS }).passthrough();
35572
35217
  var ValidationProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS }).passthrough();
35573
35218
  var TriageProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...TRIAGE_PROCESS_FIELDS }).passthrough();
35574
35219
  var ProactiveMaintenanceProcessConfigSchema = exports_external.object({ ...IMPROVE_PROCESS_BASE_FIELDS, ...PROACTIVE_MAINTENANCE_PROCESS_FIELDS }).passthrough();
35220
+ var RETIRED_PROCESS_NAMES = new Set(["graphExtraction"]);
35575
35221
  var ImproveProfileProcessesSchema = exports_external.object({
35576
35222
  reflect: ReflectProcessConfigSchema.optional(),
35577
35223
  distill: DistillProcessConfigSchema.optional(),
35578
35224
  consolidate: ConsolidateProcessConfigSchema.optional(),
35579
35225
  memoryInference: MemoryInferenceProcessConfigSchema.optional(),
35580
- graphExtraction: GraphExtractionProcessConfigSchema.optional(),
35581
35226
  extract: ExtractProcessConfigSchema.optional(),
35582
35227
  validation: ValidationProcessConfigSchema.optional(),
35583
35228
  triage: TriageProcessConfigSchema.optional(),
@@ -35590,7 +35235,7 @@ var ImproveProfileProcessesSchema = exports_external.object({
35590
35235
  });
35591
35236
  }
35592
35237
  for (const [name, process2] of Object.entries(val)) {
35593
- if (!(name in IMPROVE_PROCESS_ENGINE_CAPABILITIES) && process2 !== null && typeof process2 === "object" && process2.enabled === true) {
35238
+ if (!(name in IMPROVE_PROCESS_ENGINE_CAPABILITIES) && !RETIRED_PROCESS_NAMES.has(name) && process2 !== null && typeof process2 === "object" && process2.enabled === true) {
35594
35239
  ctx.addIssue({
35595
35240
  code: exports_external.ZodIssueCode.custom,
35596
35241
  path: [name],
@@ -35659,11 +35304,8 @@ var IndexPassConfigSchema = exports_external.preprocess((raw, ctx) => {
35659
35304
  model: nonEmptyString.optional(),
35660
35305
  timeoutMs: exports_external.union([positiveInt, exports_external.null()]).optional(),
35661
35306
  enabled: exports_external.boolean().optional(),
35662
- llm: LlmInvocationOverridesSchema.optional(),
35663
- graphExtractionBatchSize: positiveInt.optional(),
35664
- graphExtractionIncludeTypes: exports_external.array(exports_external.string().min(1)).nonempty().optional()
35307
+ llm: LlmInvocationOverridesSchema.optional()
35665
35308
  }).passthrough());
35666
- var MetadataEnhanceSchema = exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough();
35667
35309
  var IndexDefaultsSchema = exports_external.object({
35668
35310
  engine: engineName.optional(),
35669
35311
  model: nonEmptyString.optional(),
@@ -35676,7 +35318,7 @@ var IndexConfigRuntimeSchema = exports_external.preprocess((raw, ctx) => {
35676
35318
  if (Array.isArray(raw)) {
35677
35319
  ctx.addIssue({
35678
35320
  code: exports_external.ZodIssueCode.custom,
35679
- message: 'Invalid `index` config: expected an object keyed by pass name (e.g. `{ "enrichment": { "enabled": false } }`).'
35321
+ message: 'Invalid `index` config: expected an object keyed by pass name (e.g. `{ "memory": { "enabled": false } }`).'
35680
35322
  });
35681
35323
  return raw;
35682
35324
  }
@@ -35700,8 +35342,7 @@ var IndexConfigRuntimeSchema = exports_external.preprocess((raw, ctx) => {
35700
35342
  }
35701
35343
  return cleaned ?? raw;
35702
35344
  }, exports_external.object({
35703
- defaults: IndexDefaultsSchema.optional(),
35704
- metadataEnhance: MetadataEnhanceSchema.optional()
35345
+ defaults: IndexDefaultsSchema.optional()
35705
35346
  }).catchall(IndexPassConfigSchema));
35706
35347
  var IndexConfigSchema = IndexConfigRuntimeSchema;
35707
35348
 
@@ -35976,144 +35617,502 @@ var AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) => {
35976
35617
  }
35977
35618
  }
35978
35619
  if (config.defaultWriteTarget !== undefined) {
35979
- const target = config.bundles?.[config.defaultWriteTarget];
35980
- if (!target) {
35620
+ const target = config.bundles?.[config.defaultWriteTarget];
35621
+ if (!target) {
35622
+ ctx.addIssue({
35623
+ code: exports_external.ZodIssueCode.custom,
35624
+ path: ["defaultWriteTarget"],
35625
+ message: `defaultWriteTarget "${config.defaultWriteTarget}" does not name a configured bundle`
35626
+ });
35627
+ } else if (target.enabled === false) {
35628
+ ctx.addIssue({
35629
+ code: exports_external.ZodIssueCode.custom,
35630
+ path: ["defaultWriteTarget"],
35631
+ message: `defaultWriteTarget "${config.defaultWriteTarget}" is disabled`
35632
+ });
35633
+ }
35634
+ }
35635
+ for (const key of ["llm", "agent", "improve"]) {
35636
+ if (config.defaults && key in config.defaults) {
35637
+ ctx.addIssue({
35638
+ code: exports_external.ZodIssueCode.custom,
35639
+ path: ["defaults", key],
35640
+ message: `defaults.${key} is retired in 0.9`
35641
+ });
35642
+ }
35643
+ }
35644
+ for (const [name, engine] of Object.entries(config.engines ?? {})) {
35645
+ if (engine.kind === "agent" && engine.llmEngine) {
35646
+ const fallback = config.engines?.[engine.llmEngine];
35647
+ if (!fallback || fallback.kind !== "llm") {
35648
+ ctx.addIssue({
35649
+ code: exports_external.ZodIssueCode.custom,
35650
+ path: ["engines", name, "llmEngine"],
35651
+ message: "llmEngine must name an LLM engine"
35652
+ });
35653
+ }
35654
+ }
35655
+ }
35656
+ const defaultEngine = config.defaults?.engine;
35657
+ if (defaultEngine && !config.engines?.[defaultEngine]) {
35658
+ ctx.addIssue({
35659
+ code: exports_external.ZodIssueCode.custom,
35660
+ path: ["defaults", "engine"],
35661
+ message: "engine does not name a configured engine"
35662
+ });
35663
+ }
35664
+ const defaultLlm = config.defaults?.llmEngine;
35665
+ if (defaultLlm && config.engines?.[defaultLlm]?.kind !== "llm") {
35666
+ ctx.addIssue({
35667
+ code: exports_external.ZodIssueCode.custom,
35668
+ path: ["defaults", "llmEngine"],
35669
+ message: "llmEngine must name an LLM engine"
35670
+ });
35671
+ }
35672
+ const workflowJudge = config.workflow?.judgeEngine;
35673
+ if (workflowJudge && !config.engines?.[workflowJudge]) {
35674
+ ctx.addIssue({
35675
+ code: exports_external.ZodIssueCode.custom,
35676
+ path: ["workflow", "judgeEngine"],
35677
+ message: "judgeEngine does not name a configured engine"
35678
+ });
35679
+ }
35680
+ const defaultStrategy = config.defaults?.improveStrategy;
35681
+ if (defaultStrategy && defaultStrategy !== "graph-refresh" && !BUILTIN_IMPROVE_STRATEGY_NAMES.includes(defaultStrategy) && !config.improve?.strategies?.[defaultStrategy]) {
35682
+ ctx.addIssue({
35683
+ code: exports_external.ZodIssueCode.custom,
35684
+ path: ["defaults", "improveStrategy"],
35685
+ message: "improveStrategy does not name a built-in or configured strategy"
35686
+ });
35687
+ }
35688
+ for (const [strategyName, strategy] of Object.entries(config.improve?.strategies ?? {})) {
35689
+ const strategyEngine = strategy.engine;
35690
+ if (strategyEngine) {
35691
+ const engine = config.engines?.[strategyEngine];
35692
+ if (!engine || engine.kind !== "llm") {
35693
+ ctx.addIssue({
35694
+ code: exports_external.ZodIssueCode.custom,
35695
+ path: ["improve", "strategies", strategyName, "engine"],
35696
+ message: engine ? "strategy engine must be an LLM engine" : "engine does not name a configured engine"
35697
+ });
35698
+ }
35699
+ }
35700
+ for (const [processName, process2] of Object.entries(strategy.processes ?? {})) {
35701
+ const processConfig = process2;
35702
+ const capability = IMPROVE_PROCESS_ENGINE_CAPABILITIES[processName];
35703
+ if (processConfig.engine && capability === null) {
35704
+ ctx.addIssue({
35705
+ code: exports_external.ZodIssueCode.custom,
35706
+ path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
35707
+ message: `${processName} does not dispatch an engine`
35708
+ });
35709
+ } else {
35710
+ const processEngine = processConfig.engine ?? strategyEngine;
35711
+ if (processEngine && capability === "llm") {
35712
+ const engine = config.engines?.[processEngine];
35713
+ if (!engine || engine.kind !== "llm") {
35714
+ ctx.addIssue({
35715
+ code: exports_external.ZodIssueCode.custom,
35716
+ path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
35717
+ message: engine ? `${processName} requires an LLM engine` : "engine does not name a configured engine"
35718
+ });
35719
+ }
35720
+ } else if (processConfig.engine && capability === "runner" && !config.engines?.[processConfig.engine]) {
35721
+ ctx.addIssue({
35722
+ code: exports_external.ZodIssueCode.custom,
35723
+ path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
35724
+ message: "engine does not name a configured engine"
35725
+ });
35726
+ }
35727
+ }
35728
+ const judgmentEngine = processConfig.judgment?.engine;
35729
+ if (processConfig.judgment?.enabled === true && judgmentEngine) {
35730
+ const engine = config.engines?.[judgmentEngine];
35731
+ if (!engine) {
35732
+ ctx.addIssue({
35733
+ code: exports_external.ZodIssueCode.custom,
35734
+ path: ["improve", "strategies", strategyName, "processes", processName, "judgment", "engine"],
35735
+ message: "engine does not name a configured engine"
35736
+ });
35737
+ }
35738
+ }
35739
+ }
35740
+ }
35741
+ if (config.defaultWriteTarget !== undefined) {
35742
+ const knownNames = Object.keys(config.bundles ?? {});
35743
+ if (knownNames.length === 0) {
35981
35744
  ctx.addIssue({
35982
35745
  code: exports_external.ZodIssueCode.custom,
35983
35746
  path: ["defaultWriteTarget"],
35984
- message: `defaultWriteTarget "${config.defaultWriteTarget}" does not name a configured bundle`
35747
+ message: `defaultWriteTarget "${config.defaultWriteTarget}" cannot be resolved: no bundles configured. ` + "Add at least one entry to `bundles` first."
35985
35748
  });
35986
- } else if (target.enabled === false) {
35749
+ } else if (!knownNames.includes(config.defaultWriteTarget)) {
35987
35750
  ctx.addIssue({
35988
35751
  code: exports_external.ZodIssueCode.custom,
35989
35752
  path: ["defaultWriteTarget"],
35990
- message: `defaultWriteTarget "${config.defaultWriteTarget}" is disabled`
35753
+ message: `defaultWriteTarget "${config.defaultWriteTarget}" does not match any configured bundle: ${knownNames.map((n) => `"${n}"`).join(", ")}.`
35991
35754
  });
35992
35755
  }
35993
35756
  }
35994
- for (const key of ["llm", "agent", "improve"]) {
35995
- if (config.defaults && key in config.defaults) {
35996
- ctx.addIssue({
35997
- code: exports_external.ZodIssueCode.custom,
35998
- path: ["defaults", key],
35999
- message: `defaults.${key} is retired in 0.9`
36000
- });
35757
+ });
35758
+
35759
+ // src/core/config/deep-merge.ts
35760
+ var UNSAFE_KEYS = new Set(["__proto__", "constructor", "prototype"]);
35761
+ function isPlainObject(value) {
35762
+ if (value === null || typeof value !== "object" || Array.isArray(value))
35763
+ return false;
35764
+ const prototype = Object.getPrototypeOf(value);
35765
+ return prototype === Object.prototype || prototype === null;
35766
+ }
35767
+ function copyConfigValue(value) {
35768
+ if (Array.isArray(value))
35769
+ return value.map(copyConfigValue);
35770
+ if (!isPlainObject(value))
35771
+ return value;
35772
+ const copy = {};
35773
+ for (const key of Object.keys(value)) {
35774
+ if (UNSAFE_KEYS.has(key))
35775
+ throw new TypeError(`Unsafe configuration key: ${key}`);
35776
+ copy[key] = copyConfigValue(value[key]);
35777
+ }
35778
+ return copy;
35779
+ }
35780
+ function deepMergeConfig(base, override) {
35781
+ const result = copyConfigValue(base);
35782
+ for (const key of Object.keys(override)) {
35783
+ if (UNSAFE_KEYS.has(key))
35784
+ throw new TypeError(`Unsafe configuration key: ${key}`);
35785
+ const next = override[key];
35786
+ if (next === undefined)
35787
+ continue;
35788
+ const current = result[key];
35789
+ result[key] = isPlainObject(current) && isPlainObject(next) ? deepMergeConfig(current, next) : copyConfigValue(next);
35790
+ }
35791
+ return result;
35792
+ }
35793
+
35794
+ // src/core/config/config.ts
35795
+ import fs10 from "fs";
35796
+ import os2 from "os";
35797
+ import path14 from "path";
35798
+ import { isDeepStrictEqual } from "util";
35799
+
35800
+ // src/core/config/config-io.ts
35801
+ import fs8 from "fs";
35802
+ import path12 from "path";
35803
+
35804
+ // src/core/file-lock.ts
35805
+ import { randomUUID } from "crypto";
35806
+ import fs7 from "fs";
35807
+ function readLockSnapshot(lockPath) {
35808
+ let fd;
35809
+ try {
35810
+ fd = fs7.openSync(lockPath, "r");
35811
+ } catch (err) {
35812
+ if (err.code === "ENOENT")
35813
+ return;
35814
+ throw err;
35815
+ }
35816
+ try {
35817
+ const rawContent = readTextFileDescriptorWithLimit(fd, MAX_LOCK_METADATA_BYTES, "Lock metadata", lockPath);
35818
+ const stat = fs7.fstatSync(fd);
35819
+ return {
35820
+ rawContent,
35821
+ identity: { dev: stat.dev, ino: stat.ino, size: stat.size, mtimeMs: stat.mtimeMs }
35822
+ };
35823
+ } finally {
35824
+ fs7.closeSync(fd);
35825
+ }
35826
+ }
35827
+ function sameIdentity(left, right) {
35828
+ return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs;
35829
+ }
35830
+ function releaseLockRaw(lockPath) {
35831
+ try {
35832
+ fs7.unlinkSync(lockPath);
35833
+ } catch {}
35834
+ }
35835
+ function tryAcquireLockSync(lockPath, payload) {
35836
+ try {
35837
+ fs7.writeFileSync(lockPath, payload, { flag: "wx" });
35838
+ } catch (err) {
35839
+ if (err.code === "EEXIST")
35840
+ return;
35841
+ throw err;
35842
+ }
35843
+ let snapshot;
35844
+ try {
35845
+ snapshot = readLockSnapshot(lockPath);
35846
+ } catch (error2) {
35847
+ releaseLockRaw(lockPath);
35848
+ throw error2;
35849
+ }
35850
+ if (!snapshot) {
35851
+ releaseLockRaw(lockPath);
35852
+ throw new Error(`Could not read newly acquired lock at ${lockPath}.`);
35853
+ }
35854
+ return { lockPath, ...snapshot };
35855
+ }
35856
+ function launcherPidFromEnv() {
35857
+ const raw = process.env.AKM_LAUNCHER_PID;
35858
+ if (!raw)
35859
+ return;
35860
+ const pid = Number.parseInt(raw, 10);
35861
+ return Number.isInteger(pid) && pid > 0 ? pid : undefined;
35862
+ }
35863
+ function createLockPayload(metadata = {}) {
35864
+ const launcherPid = launcherPidFromEnv();
35865
+ return JSON.stringify({
35866
+ ...metadata,
35867
+ pid: process.pid,
35868
+ ...launcherPid !== undefined ? { launcherPid } : {},
35869
+ lockId: randomUUID()
35870
+ });
35871
+ }
35872
+ function probeLock(lockPath, opts) {
35873
+ let snapshot;
35874
+ try {
35875
+ snapshot = readLockSnapshot(lockPath);
35876
+ } catch (error2) {
35877
+ const code = error2?.code;
35878
+ if (code === "EACCES" || code === "EPERM")
35879
+ return { state: "inaccessible", code };
35880
+ return { state: "stale", reason: "unreadable" };
35881
+ }
35882
+ if (!snapshot)
35883
+ return { state: "absent" };
35884
+ const { rawContent, identity: identity3 } = snapshot;
35885
+ const ageMs = Date.now() - identity3.mtimeMs;
35886
+ const { holderPid, launcherPid } = extractLockIdentity(rawContent);
35887
+ if (holderPid === undefined) {
35888
+ return { state: "stale", reason: "invalid_pid", ageMs, rawContent, identity: identity3 };
35889
+ }
35890
+ if (!isProcessAlive(holderPid)) {
35891
+ return { state: "stale", reason: "pid_dead", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
35892
+ }
35893
+ if (opts?.staleAfterMs !== undefined && ageMs > opts.staleAfterMs) {
35894
+ return { state: "stale", reason: "age_exceeded", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
35895
+ }
35896
+ return { state: "held", holderPid, launcherPid, ageMs, rawContent, identity: identity3 };
35897
+ }
35898
+ function reclaimStaleLock(lockPath, probe, options) {
35899
+ if (probe.rawContent === undefined || probe.identity === undefined)
35900
+ return false;
35901
+ const expectedContent = probe.rawContent;
35902
+ const expectedIdentity = probe.identity;
35903
+ let current;
35904
+ try {
35905
+ current = readLockSnapshot(lockPath);
35906
+ } catch {
35907
+ return false;
35908
+ }
35909
+ if (!current || current.rawContent !== expectedContent || !sameIdentity(current.identity, expectedIdentity)) {
35910
+ return false;
35911
+ }
35912
+ const quarantinePath = `${lockPath}.stale-${process.pid}-${randomUUID()}`;
35913
+ try {
35914
+ fs7.renameSync(lockPath, quarantinePath);
35915
+ } catch (err) {
35916
+ if (err.code === "ENOENT")
35917
+ return false;
35918
+ throw err;
35919
+ }
35920
+ let quarantined;
35921
+ try {
35922
+ quarantined = readLockSnapshot(quarantinePath);
35923
+ } catch {
35924
+ quarantined = undefined;
35925
+ }
35926
+ if (!quarantined || quarantined.rawContent !== expectedContent || !sameIdentity(quarantined.identity, expectedIdentity)) {
35927
+ try {
35928
+ fs7.linkSync(quarantinePath, lockPath);
35929
+ } catch (err) {
35930
+ if (err.code !== "EEXIST")
35931
+ throw err;
35932
+ }
35933
+ releaseLockRaw(quarantinePath);
35934
+ return false;
35935
+ }
35936
+ options?.afterQuarantineVerified?.();
35937
+ try {
35938
+ fs7.unlinkSync(quarantinePath);
35939
+ return true;
35940
+ } catch (err) {
35941
+ if (err.code === "ENOENT")
35942
+ return false;
35943
+ throw err;
35944
+ }
35945
+ }
35946
+ function releaseLock(ownership) {
35947
+ const { lockPath } = ownership;
35948
+ let current;
35949
+ try {
35950
+ current = readLockSnapshot(lockPath);
35951
+ } catch {
35952
+ return;
35953
+ }
35954
+ if (current && current.rawContent === ownership.rawContent && sameIdentity(current.identity, ownership.identity)) {
35955
+ releaseLockRaw(lockPath);
35956
+ }
35957
+ }
35958
+ function extractLockIdentity(content) {
35959
+ const trimmed = content.trim();
35960
+ if (!trimmed)
35961
+ return {};
35962
+ if (trimmed.startsWith("{")) {
35963
+ try {
35964
+ const parsed = JSON.parse(trimmed);
35965
+ const pid2 = typeof parsed.pid === "number" ? parsed.pid : Number.NaN;
35966
+ const rawLauncherPid = typeof parsed.launcherPid === "number" ? parsed.launcherPid : Number.NaN;
35967
+ return {
35968
+ holderPid: Number.isInteger(pid2) && pid2 > 0 ? pid2 : undefined,
35969
+ launcherPid: Number.isInteger(rawLauncherPid) && rawLauncherPid > 0 ? rawLauncherPid : undefined
35970
+ };
35971
+ } catch {
35972
+ return {};
36001
35973
  }
36002
35974
  }
36003
- for (const [name, engine] of Object.entries(config.engines ?? {})) {
36004
- if (engine.kind === "agent" && engine.llmEngine) {
36005
- const fallback = config.engines?.[engine.llmEngine];
36006
- if (!fallback || fallback.kind !== "llm") {
36007
- ctx.addIssue({
36008
- code: exports_external.ZodIssueCode.custom,
36009
- path: ["engines", name, "llmEngine"],
36010
- message: "llmEngine must name an LLM engine"
36011
- });
36012
- }
36013
- }
35975
+ const pid = Number.parseInt(trimmed, 10);
35976
+ return { holderPid: Number.isInteger(pid) && pid > 0 ? pid : undefined };
35977
+ }
35978
+
35979
+ // src/core/config/config-io.ts
35980
+ function readConfigText(configPath) {
35981
+ try {
35982
+ return readTextFile(configPath, "Config file");
35983
+ } catch (err) {
35984
+ if (err.code === "ENOENT")
35985
+ return;
35986
+ throw err;
35987
+ }
35988
+ }
35989
+ function parseConfigText(text, sourcePath) {
35990
+ const stripped = stripJsonComments(text);
35991
+ const where = sourcePath ? ` at ${sourcePath}` : "";
35992
+ let parsed;
35993
+ try {
35994
+ parsed = JSON.parse(stripped);
35995
+ } catch (err) {
35996
+ const detail = err instanceof Error ? err.message : String(err);
35997
+ 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.");
36014
35998
  }
36015
- const defaultEngine = config.defaults?.engine;
36016
- if (defaultEngine && !config.engines?.[defaultEngine]) {
36017
- ctx.addIssue({
36018
- code: exports_external.ZodIssueCode.custom,
36019
- path: ["defaults", "engine"],
36020
- message: "engine does not name a configured engine"
36021
- });
35999
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
36000
+ throw new ConfigError(`Config file${where} must contain a JSON object at the root, got ${describeJsonRoot(parsed)}.`, "INVALID_CONFIG_FILE");
36022
36001
  }
36023
- const defaultLlm = config.defaults?.llmEngine;
36024
- if (defaultLlm && config.engines?.[defaultLlm]?.kind !== "llm") {
36025
- ctx.addIssue({
36026
- code: exports_external.ZodIssueCode.custom,
36027
- path: ["defaults", "llmEngine"],
36028
- message: "llmEngine must name an LLM engine"
36029
- });
36002
+ return parsed;
36003
+ }
36004
+ function describeJsonRoot(value) {
36005
+ if (value === null)
36006
+ return "null";
36007
+ if (Array.isArray(value))
36008
+ return "an array";
36009
+ if (typeof value === "string")
36010
+ return "a string";
36011
+ if (typeof value === "number")
36012
+ return "a number";
36013
+ if (typeof value === "boolean")
36014
+ return "a boolean";
36015
+ return typeof value;
36016
+ }
36017
+ function writeConfigAtomic(configPath, config) {
36018
+ writeFileAtomic(configPath, `${JSON.stringify(config, null, 2)}
36019
+ `);
36020
+ }
36021
+ var MAX_CONFIG_BACKUPS = 5;
36022
+ function backupExistingConfig(configPath, now = new Date) {
36023
+ if (!fs8.existsSync(configPath))
36024
+ return;
36025
+ const backupDir = path12.join(getCacheDir(), "config-backups");
36026
+ fs8.mkdirSync(backupDir, { recursive: true, mode: 448 });
36027
+ fs8.chmodSync(backupDir, 448);
36028
+ const timestamp = now.toISOString().replace(/[.:]/g, "-");
36029
+ let sequence = 0;
36030
+ let timestamped;
36031
+ while (true) {
36032
+ timestamped = path12.join(backupDir, `config-${timestamp}${sequence === 0 ? "" : `-${sequence}`}.json`);
36033
+ try {
36034
+ fs8.copyFileSync(configPath, timestamped, fs8.constants.COPYFILE_EXCL);
36035
+ break;
36036
+ } catch (error2) {
36037
+ if (error2.code !== "EEXIST")
36038
+ throw error2;
36039
+ sequence++;
36040
+ }
36030
36041
  }
36031
- const workflowJudge = config.workflow?.judgeEngine;
36032
- if (workflowJudge && !config.engines?.[workflowJudge]) {
36033
- ctx.addIssue({
36034
- code: exports_external.ZodIssueCode.custom,
36035
- path: ["workflow", "judgeEngine"],
36036
- message: "judgeEngine does not name a configured engine"
36037
- });
36042
+ const latest = path12.join(backupDir, "config.latest.json");
36043
+ fs8.copyFileSync(configPath, latest);
36044
+ fs8.chmodSync(timestamped, 384);
36045
+ fs8.chmodSync(latest, 384);
36046
+ pruneOldBackups(backupDir);
36047
+ return { timestamped, latest };
36048
+ }
36049
+ function pruneOldBackups(backupDir) {
36050
+ pruneToNewest(backupDir, MAX_CONFIG_BACKUPS, (entry) => entry.isFile() && isTimestampedConfigBackup(entry.name));
36051
+ }
36052
+ function isTimestampedConfigBackup(name) {
36053
+ return name.startsWith("config-") && name.endsWith(".json") && name !== "config.latest.json";
36054
+ }
36055
+ function pruneToNewest(dir, keep, select) {
36056
+ let entries;
36057
+ try {
36058
+ entries = fs8.readdirSync(dir, { withFileTypes: true });
36059
+ } catch {
36060
+ return;
36038
36061
  }
36039
- const defaultStrategy = config.defaults?.improveStrategy;
36040
- if (defaultStrategy && !BUILTIN_IMPROVE_STRATEGY_NAMES.includes(defaultStrategy) && !config.improve?.strategies?.[defaultStrategy]) {
36041
- ctx.addIssue({
36042
- code: exports_external.ZodIssueCode.custom,
36043
- path: ["defaults", "improveStrategy"],
36044
- message: "improveStrategy does not name a built-in or configured strategy"
36045
- });
36062
+ const candidates = entries.filter(select).map((entry) => {
36063
+ const full = path12.join(dir, entry.name);
36064
+ let mtime = 0;
36065
+ try {
36066
+ mtime = fs8.statSync(full).mtimeMs;
36067
+ } catch {}
36068
+ return { path: full, mtime };
36069
+ }).sort((a, b) => b.mtime - a.mtime);
36070
+ for (const stale of candidates.slice(keep)) {
36071
+ try {
36072
+ fs8.rmSync(stale.path, { recursive: true, force: true });
36073
+ } catch {}
36046
36074
  }
36047
- for (const [strategyName, strategy] of Object.entries(config.improve?.strategies ?? {})) {
36048
- const strategyEngine = strategy.engine;
36049
- if (strategyEngine) {
36050
- const engine = config.engines?.[strategyEngine];
36051
- if (!engine || engine.kind !== "llm") {
36052
- ctx.addIssue({
36053
- code: exports_external.ZodIssueCode.custom,
36054
- path: ["improve", "strategies", strategyName, "engine"],
36055
- message: engine ? "strategy engine must be an LLM engine" : "engine does not name a configured engine"
36056
- });
36075
+ }
36076
+ function getConfigLockPath() {
36077
+ return path12.join(getConfigDir(), "config.json.lck");
36078
+ }
36079
+ var CONFIG_LOCK_MAX_RETRIES = 40;
36080
+ var CONFIG_LOCK_RETRY_DELAY_MS = 50;
36081
+ function sleepSyncMs(ms) {
36082
+ sleepSync(ms);
36083
+ }
36084
+ function acquireConfigLock() {
36085
+ const lockPath = getConfigLockPath();
36086
+ try {
36087
+ fs8.mkdirSync(path12.dirname(lockPath), { recursive: true });
36088
+ } catch {}
36089
+ for (let attempt = 0;attempt < CONFIG_LOCK_MAX_RETRIES; attempt++) {
36090
+ try {
36091
+ const ownership = tryAcquireLockSync(lockPath, createLockPayload());
36092
+ if (ownership) {
36093
+ return () => releaseLock(ownership);
36057
36094
  }
36095
+ } catch (error2) {
36096
+ throw new ConfigError(`Unable to acquire config lock at ${lockPath}: ${error2 instanceof Error ? error2.message : String(error2)}`, "INVALID_CONFIG_FILE");
36058
36097
  }
36059
- for (const [processName, process2] of Object.entries(strategy.processes ?? {})) {
36060
- const processConfig = process2;
36061
- const capability = IMPROVE_PROCESS_ENGINE_CAPABILITIES[processName];
36062
- if (processConfig.engine && capability === null) {
36063
- ctx.addIssue({
36064
- code: exports_external.ZodIssueCode.custom,
36065
- path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
36066
- message: `${processName} does not dispatch an engine`
36067
- });
36068
- } else {
36069
- const processEngine = processConfig.engine ?? strategyEngine;
36070
- if (processEngine && capability === "llm") {
36071
- const engine = config.engines?.[processEngine];
36072
- if (!engine || engine.kind !== "llm") {
36073
- ctx.addIssue({
36074
- code: exports_external.ZodIssueCode.custom,
36075
- path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
36076
- message: engine ? `${processName} requires an LLM engine` : "engine does not name a configured engine"
36077
- });
36078
- }
36079
- } else if (processConfig.engine && capability === "runner" && !config.engines?.[processConfig.engine]) {
36080
- ctx.addIssue({
36081
- code: exports_external.ZodIssueCode.custom,
36082
- path: ["improve", "strategies", strategyName, "processes", processName, "engine"],
36083
- message: "engine does not name a configured engine"
36084
- });
36085
- }
36086
- }
36087
- const judgmentEngine = processConfig.judgment?.engine;
36088
- if (processConfig.judgment?.enabled === true && judgmentEngine) {
36089
- const engine = config.engines?.[judgmentEngine];
36090
- if (!engine) {
36091
- ctx.addIssue({
36092
- code: exports_external.ZodIssueCode.custom,
36093
- path: ["improve", "strategies", strategyName, "processes", processName, "judgment", "engine"],
36094
- message: "engine does not name a configured engine"
36095
- });
36096
- }
36097
- }
36098
+ const probe = probeLock(lockPath);
36099
+ if (probe.state === "stale" && reclaimStaleLock(lockPath, probe)) {
36100
+ continue;
36098
36101
  }
36099
- }
36100
- if (config.defaultWriteTarget !== undefined) {
36101
- const knownNames = Object.keys(config.bundles ?? {});
36102
- if (knownNames.length === 0) {
36103
- ctx.addIssue({
36104
- code: exports_external.ZodIssueCode.custom,
36105
- path: ["defaultWriteTarget"],
36106
- message: `defaultWriteTarget "${config.defaultWriteTarget}" cannot be resolved: no bundles configured. ` + "Add at least one entry to `bundles` first."
36107
- });
36108
- } else if (!knownNames.includes(config.defaultWriteTarget)) {
36109
- ctx.addIssue({
36110
- code: exports_external.ZodIssueCode.custom,
36111
- path: ["defaultWriteTarget"],
36112
- message: `defaultWriteTarget "${config.defaultWriteTarget}" does not match any configured bundle: ${knownNames.map((n) => `"${n}"`).join(", ")}.`
36113
- });
36102
+ if (attempt < CONFIG_LOCK_MAX_RETRIES - 1) {
36103
+ sleepSyncMs(CONFIG_LOCK_RETRY_DELAY_MS);
36114
36104
  }
36115
36105
  }
36116
- });
36106
+ throw new ConfigError(`Timed out waiting for config lock at ${lockPath}. Another AKM process may be updating config.`, "INVALID_CONFIG_FILE");
36107
+ }
36108
+ function withConfigLock(fn) {
36109
+ const release = acquireConfigLock();
36110
+ try {
36111
+ return fn();
36112
+ } finally {
36113
+ release();
36114
+ }
36115
+ }
36117
36116
 
36118
36117
  // src/core/config/config-sources.ts
36119
36118
  import { createHash } from "crypto";
@@ -36248,41 +36247,6 @@ function normalizeInstalledGitRef(source, ref) {
36248
36247
  return requestedRef ? `${cloneUrl}/tree/${requestedRef}` : cloneUrl;
36249
36248
  }
36250
36249
 
36251
- // src/core/config/deep-merge.ts
36252
- var UNSAFE_KEYS = new Set(["__proto__", "constructor", "prototype"]);
36253
- function isPlainObject(value) {
36254
- if (value === null || typeof value !== "object" || Array.isArray(value))
36255
- return false;
36256
- const prototype = Object.getPrototypeOf(value);
36257
- return prototype === Object.prototype || prototype === null;
36258
- }
36259
- function copyConfigValue(value) {
36260
- if (Array.isArray(value))
36261
- return value.map(copyConfigValue);
36262
- if (!isPlainObject(value))
36263
- return value;
36264
- const copy = {};
36265
- for (const key of Object.keys(value)) {
36266
- if (UNSAFE_KEYS.has(key))
36267
- throw new TypeError(`Unsafe configuration key: ${key}`);
36268
- copy[key] = copyConfigValue(value[key]);
36269
- }
36270
- return copy;
36271
- }
36272
- function deepMergeConfig(base, override) {
36273
- const result = copyConfigValue(base);
36274
- for (const key of Object.keys(override)) {
36275
- if (UNSAFE_KEYS.has(key))
36276
- throw new TypeError(`Unsafe configuration key: ${key}`);
36277
- const next = override[key];
36278
- if (next === undefined)
36279
- continue;
36280
- const current = result[key];
36281
- result[key] = isPlainObject(current) && isPlainObject(next) ? deepMergeConfig(current, next) : copyConfigValue(next);
36282
- }
36283
- return result;
36284
- }
36285
-
36286
36250
  // src/core/config/config-walker.ts
36287
36251
  function unwrap(schema) {
36288
36252
  let current = schema;
@@ -36531,11 +36495,12 @@ ${lines}`, "INVALID_CONFIG_FILE");
36531
36495
  assertUniquePhysicalBundleRoots(finalResult.data, sourcePath);
36532
36496
  return finalResult.data;
36533
36497
  }
36498
+ var RETIRED_CATCHALL_KEY_PATHS = new Set(["index.graph", "index.metadataEnhance"]);
36534
36499
  function unknownConfigKeyPaths(root, node = root, prefix = []) {
36535
36500
  const found = [];
36536
36501
  for (const key of Object.keys(node).sort()) {
36537
36502
  const keyPath = [...prefix, key];
36538
- if (resolveSchemaAt(keyPath, root) === undefined) {
36503
+ if (RETIRED_CATCHALL_KEY_PATHS.has(keyPath.join(".")) || resolveSchemaAt(keyPath, root) === undefined) {
36539
36504
  found.push(keyPath);
36540
36505
  continue;
36541
36506
  }
@@ -36826,6 +36791,9 @@ function normalizeConfigFile(configPath, options) {
36826
36791
  const body = withSchedulerOnDisk(configWriteBody(localRaw, current, next), next);
36827
36792
  for (const keyPath of unknownConfigKeyPaths(body))
36828
36793
  deleteConfigPath(body, keyPath);
36794
+ const strategies = body.improve?.strategies;
36795
+ if (strategies && Object.hasOwn(strategies, "graph-refresh"))
36796
+ delete strategies["graph-refresh"];
36829
36797
  const keys = [...new Set([...Object.keys(raw), ...Object.keys(body)])].filter((key) => JSON.stringify(raw[key]) !== JSON.stringify(body[key])).sort();
36830
36798
  if (keys.length === 0 || !options.apply)
36831
36799
  return { keys, changed: keys.length > 0, applied: false };
@@ -36900,7 +36868,6 @@ function resolveSecret(value, resolveFromStore) {
36900
36868
  return resolved ?? "";
36901
36869
  });
36902
36870
  }
36903
- var INDEX_RESERVED_KEYS = new Set(["metadataEnhance"]);
36904
36871
 
36905
36872
  // src/core/redaction.ts
36906
36873
  var ENV_PASSTHROUGH_REDACTION_POLICY = {
@@ -52772,6 +52739,7 @@ var LEDGER_HARD_OUTCOMES = new Set([
52772
52739
  "quality_rejected",
52773
52740
  "expired"
52774
52741
  ]);
52742
+ var hasContentHashColumnCache = new WeakMap;
52775
52743
 
52776
52744
  // src/commands/improve/improve-strategies.ts
52777
52745
  var REF_SCOPED_PROCESSES = new Set(["reflect", "distill", "consolidate"]);
@@ -52779,7 +52747,6 @@ var BUILTIN_STRATEGIES = {
52779
52747
  default: default_default,
52780
52748
  quick: quick_default,
52781
52749
  thorough: thorough_default,
52782
- "graph-refresh": graph_refresh_default,
52783
52750
  consolidate: consolidate_default,
52784
52751
  catchup: catchup_default,
52785
52752
  "reflect-distill": reflect_distill_default,