@cortexkit/opencode-magic-context 0.41.3 → 0.41.4

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 (119) hide show
  1. package/dist/config/index.d.ts +9 -0
  2. package/dist/config/index.d.ts.map +1 -1
  3. package/dist/{conflict-warning-hook-z5sd697e.js → conflict-warning-hook-ejkc9sjn.js} +2 -2
  4. package/dist/{derive-budgets-901a0pk0.js → derive-budgets-bc366cz8.js} +4 -2
  5. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  6. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +13 -0
  7. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  8. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  9. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +3 -0
  10. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  11. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  12. package/dist/features/magic-context/storage-meta-persisted.d.ts +2 -2
  13. package/dist/hooks/magic-context/command-handler.d.ts +5 -1
  14. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  15. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  16. package/dist/hooks/magic-context/compartment-runner-types.d.ts +4 -0
  17. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  18. package/dist/hooks/magic-context/derive-budgets.d.ts +1 -0
  19. package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -1
  20. package/dist/hooks/magic-context/emergency-drop.d.ts +3 -1
  21. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/execute-status.d.ts +7 -1
  23. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +4 -3
  25. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  26. package/dist/hooks/magic-context/hook-handlers.d.ts +2 -0
  27. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  28. package/dist/hooks/magic-context/hook.d.ts +5 -2
  29. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  30. package/dist/hooks/magic-context/issue-423-fixture.d.ts +37 -0
  31. package/dist/hooks/magic-context/issue-423-fixture.d.ts.map +1 -0
  32. package/dist/hooks/magic-context/issue-424-fixture.d.ts +11 -0
  33. package/dist/hooks/magic-context/issue-424-fixture.d.ts.map +1 -0
  34. package/dist/hooks/magic-context/producer-window-guard.d.ts +8 -0
  35. package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -0
  36. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +59 -0
  37. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  38. package/dist/hooks/magic-context/read-session-chunk.d.ts +2 -0
  39. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  40. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +4 -1
  41. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  42. package/dist/hooks/magic-context/recomp-orchestrator.d.ts +2 -0
  43. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  44. package/dist/hooks/magic-context/rust-mode-transform.d.ts +5 -2
  45. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/sentinel.d.ts +3 -3
  47. package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
  49. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  50. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +8 -3
  51. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  52. package/dist/hooks/magic-context/tool-drop-target.d.ts +1 -0
  53. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  54. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +2 -0
  55. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  56. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  57. package/dist/hooks/magic-context/transform.d.ts +4 -0
  58. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  60. package/dist/{index-vmmjdpc0.js → index-0y2mcg5y.js} +282 -41
  61. package/dist/{index-npx8vhmy.js → index-4avmwfp5.js} +1 -1
  62. package/dist/{index-kby1sng5.js → index-avwt563y.js} +8 -1
  63. package/dist/{index-0bycg0np.js → index-fz104x1j.js} +1 -1
  64. package/dist/{index-dn1rwpd8.js → index-mjv9je4e.js} +14 -10
  65. package/dist/index-sd3egckz.js +1583 -0
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +455 -1400
  68. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
  69. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  70. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  71. package/dist/{recomp-orchestrator-f5m2wk74.js → recomp-orchestrator-q98r6rga.js} +4 -4
  72. package/dist/shared/cache-ttl-display.d.ts +23 -0
  73. package/dist/shared/cache-ttl-display.d.ts.map +1 -0
  74. package/dist/shared/cache-ttl-seed.d.ts +10 -0
  75. package/dist/shared/cache-ttl-seed.d.ts.map +1 -0
  76. package/dist/shared/config-diagnostics.d.ts +30 -0
  77. package/dist/shared/config-diagnostics.d.ts.map +1 -0
  78. package/dist/shared/config-warning-surface.d.ts +3 -0
  79. package/dist/shared/config-warning-surface.d.ts.map +1 -0
  80. package/dist/shared/data-path.d.ts +10 -9
  81. package/dist/shared/data-path.d.ts.map +1 -1
  82. package/dist/shared/harness-provider-map.d.ts +7 -0
  83. package/dist/shared/harness-provider-map.d.ts.map +1 -1
  84. package/dist/shared/jsonc-parser.d.ts +12 -0
  85. package/dist/shared/jsonc-parser.d.ts.map +1 -1
  86. package/dist/shared/model-suggestion-retry.d.ts +14 -10
  87. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  88. package/dist/shared/pi-executable.d.ts +6 -0
  89. package/dist/shared/pi-executable.d.ts.map +1 -0
  90. package/dist/shared/rpc-types.d.ts +6 -0
  91. package/dist/shared/rpc-types.d.ts.map +1 -1
  92. package/dist/shared/rpc-utils.d.ts.map +1 -1
  93. package/dist/shared/status-detail-text.d.ts.map +1 -1
  94. package/dist/shared/tag-transcript.d.ts.map +1 -1
  95. package/dist/{storage-meta-session-3rxx9ekm.js → storage-meta-session-dvwfw778.js} +1 -1
  96. package/package.json +1 -1
  97. package/src/config/index.test.ts +44 -0
  98. package/src/config/index.ts +96 -15
  99. package/src/shared/cache-ttl-display.test.ts +84 -0
  100. package/src/shared/cache-ttl-display.ts +64 -0
  101. package/src/shared/cache-ttl-seed.ts +23 -0
  102. package/src/shared/config-diagnostics.test.ts +29 -0
  103. package/src/shared/config-diagnostics.ts +64 -0
  104. package/src/shared/config-warning-surface.ts +28 -0
  105. package/src/shared/data-path.ts +10 -9
  106. package/src/shared/harness-provider-map.test.ts +16 -0
  107. package/src/shared/harness-provider-map.ts +15 -0
  108. package/src/shared/jsonc-parser.test.ts +14 -1
  109. package/src/shared/jsonc-parser.ts +93 -0
  110. package/src/shared/model-suggestion-retry.ts +143 -28
  111. package/src/shared/pi-executable.ts +20 -0
  112. package/src/shared/rpc-types.ts +6 -0
  113. package/src/shared/rpc-utils.ts +2 -3
  114. package/src/shared/status-detail-text.test.ts +2 -1
  115. package/src/shared/status-detail-text.ts +5 -1
  116. package/src/shared/tag-transcript.ts +21 -2
  117. package/src/tui/index.tsx +15 -1
  118. package/src/tui-compiled/index.tsx +234 -222
  119. package/dist/index-jfpk81yt.js +0 -146
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import {
2
+ sanitizeDiagnosticText,
2
3
  hasShareabilitySensitiveText,
3
4
  log,
4
5
  sessionLog,
@@ -25,6 +26,7 @@ import {
25
26
  nextOccurrence,
26
27
  nextDueAtMs,
27
28
  promptSurfaceConfigIdentity,
29
+ resolveModelConfigValue,
28
30
  resolvePromptSurface,
29
31
  resolveModelConfigOrDefault,
30
32
  DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE,
@@ -340,6 +342,7 @@ import {
340
342
  resolveFallbackChain,
341
343
  modelBodyField,
342
344
  toModelEntry,
345
+ getPromptFailureDetail,
343
346
  promptSyncWithValidatedOutputRetry,
344
347
  normalizeSDKResponse,
345
348
  promptSurfaceHashMaterial,
@@ -496,6 +499,7 @@ import {
496
499
  trimMemoriesToBudgetV2,
497
500
  renderMemoryBlockV2,
498
501
  injectM0M1,
502
+ describeBoundaryDiagnostics,
499
503
  RECOVERY_NO_HEAD_LIMIT,
500
504
  resolveOpenCodeProtectedTailBoundary,
501
505
  resolveWrapupProtectedTailBoundary,
@@ -512,13 +516,20 @@ import {
512
516
  setRecompTerminal2,
513
517
  runManagedRecomp2,
514
518
  runManagedUpgrade2
515
- } from "./index-vmmjdpc0.js";
519
+ } from "./index-0y2mcg5y.js";
516
520
  import {
521
+ createScanner,
522
+ parseTree,
523
+ findNodeAtLocation,
524
+ getNodeValue,
525
+ modify,
526
+ applyEdits,
517
527
  stripJsonComments,
518
528
  isPrototypePollutionKey,
529
+ parseJsoncRecovering,
519
530
  parseJsonc,
520
531
  detectConfigFile
521
- } from "./index-jfpk81yt.js";
532
+ } from "./index-sd3egckz.js";
522
533
  import {
523
534
  setStoragePrivatePermissionEnforcement,
524
535
  shouldEnforcePrivateStoragePermissions,
@@ -533,8 +544,9 @@ import {
533
544
  getSdkContextLimit,
534
545
  deriveTriggerBudget2,
535
546
  deriveHistorianChunkTokens2,
547
+ resolveKnownHistorianContextLimit2,
536
548
  resolveHistorianContextLimit2
537
- } from "./index-dn1rwpd8.js";
549
+ } from "./index-mjv9je4e.js";
538
550
  import {
539
551
  Database,
540
552
  closeQuietly,
@@ -553,7 +565,7 @@ import {
553
565
  retryPendingSessionCleanups2,
554
566
  retryPendingRustSessionCleanupsForProject2,
555
567
  clearSession2
556
- } from "./index-0bycg0np.js";
568
+ } from "./index-fz104x1j.js";
557
569
  import {
558
570
  registerNotificationSink2,
559
571
  pushNotification2,
@@ -574,7 +586,7 @@ import {
574
586
  resolveCompactionForBoot,
575
587
  sendConflictWarning2,
576
588
  cleanupConflictWarnings2
577
- } from "./index-npx8vhmy.js";
589
+ } from "./index-4avmwfp5.js";
578
590
  import {
579
591
  resolveHistorianModel2,
580
592
  resolveOpenCodeAgentOverrides2,
@@ -604,9 +616,10 @@ import {
604
616
  resolvePromptContext2
605
617
  } from "./index-fmsr7v69.js";
606
618
  import {
619
+ canonicalModelIdentity,
607
620
  piModelRefToCanonical,
608
621
  modelRefLookupOrder
609
- } from "./index-kby1sng5.js";
622
+ } from "./index-avwt563y.js";
610
623
  import {
611
624
  getHarness,
612
625
  getDataDir,
@@ -8713,6 +8726,30 @@ function buildHiddenAgentConfig(prompt, allowedTools, maxSteps, overrides, agent
8713
8726
  // src/config/index.ts
8714
8727
  import { existsSync as existsSync3 } from "node:fs";
8715
8728
 
8729
+ // src/shared/config-diagnostics.ts
8730
+ var CONFIG_WARNING_CLASS = {
8731
+ FILE_PARSE: "file-parse",
8732
+ FILE_IO: "file-io",
8733
+ INVALID_LEAF: "invalid-leaf"
8734
+ };
8735
+ function formatConfigParseStatusLine(failure) {
8736
+ const disposition = failure.recovered ? "recovered values applied; fix the file" : "running on defaults";
8737
+ return `Config: PARSE FAILED (${failure.path}:${failure.line}:${failure.column}) — ${disposition}`;
8738
+ }
8739
+ var claimedFailures = new Set;
8740
+ function failureKey(surface, failure) {
8741
+ return `${surface}\x00${failure.path}\x00${failure.line}\x00${failure.column}\x00${failure.message}`;
8742
+ }
8743
+ function claimConfigParseFailuresOnce(surface, failures) {
8744
+ return failures.filter((failure) => {
8745
+ const key = failureKey(surface, failure);
8746
+ if (claimedFailures.has(key))
8747
+ return false;
8748
+ claimedFailures.add(key);
8749
+ return true;
8750
+ });
8751
+ }
8752
+
8716
8753
  // src/config/agent-disable.ts
8717
8754
  var COMPACTION_ENABLED_PATH = `compaction${"."}enabled`;
8718
8755
  function isDreamerRunnable(config) {
@@ -9617,1327 +9654,22 @@ import {
9617
9654
  } from "node:fs";
9618
9655
  import { basename, dirname, join } from "node:path";
9619
9656
 
9620
- // ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
9621
- function createScanner(text, ignoreTrivia = false) {
9622
- const len = text.length;
9623
- let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
9624
- function scanHexDigits(count, exact) {
9625
- let digits = 0;
9626
- let value = 0;
9627
- while (digits < count || !exact) {
9628
- let ch = text.charCodeAt(pos);
9629
- if (ch >= 48 && ch <= 57) {
9630
- value = value * 16 + ch - 48;
9631
- } else if (ch >= 65 && ch <= 70) {
9632
- value = value * 16 + ch - 65 + 10;
9633
- } else if (ch >= 97 && ch <= 102) {
9634
- value = value * 16 + ch - 97 + 10;
9635
- } else {
9636
- break;
9637
- }
9638
- pos++;
9639
- digits++;
9640
- }
9641
- if (digits < count) {
9642
- value = -1;
9643
- }
9644
- return value;
9645
- }
9646
- function setPosition(newPosition) {
9647
- pos = newPosition;
9648
- value = "";
9649
- tokenOffset = 0;
9650
- token = 16;
9651
- scanError = 0;
9652
- }
9653
- function scanNumber() {
9654
- let start = pos;
9655
- if (text.charCodeAt(pos) === 48) {
9656
- pos++;
9657
- } else {
9658
- pos++;
9659
- while (pos < text.length && isDigit(text.charCodeAt(pos))) {
9660
- pos++;
9661
- }
9662
- }
9663
- if (pos < text.length && text.charCodeAt(pos) === 46) {
9664
- pos++;
9665
- if (pos < text.length && isDigit(text.charCodeAt(pos))) {
9666
- pos++;
9667
- while (pos < text.length && isDigit(text.charCodeAt(pos))) {
9668
- pos++;
9669
- }
9670
- } else {
9671
- scanError = 3;
9672
- return text.substring(start, pos);
9673
- }
9674
- }
9675
- let end = pos;
9676
- if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
9677
- pos++;
9678
- if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) {
9679
- pos++;
9680
- }
9681
- if (pos < text.length && isDigit(text.charCodeAt(pos))) {
9682
- pos++;
9683
- while (pos < text.length && isDigit(text.charCodeAt(pos))) {
9684
- pos++;
9685
- }
9686
- end = pos;
9687
- } else {
9688
- scanError = 3;
9689
- }
9690
- }
9691
- return text.substring(start, end);
9692
- }
9693
- function scanString() {
9694
- let result = "", start = pos;
9695
- while (true) {
9696
- if (pos >= len) {
9697
- result += text.substring(start, pos);
9698
- scanError = 2;
9699
- break;
9700
- }
9701
- const ch = text.charCodeAt(pos);
9702
- if (ch === 34) {
9703
- result += text.substring(start, pos);
9704
- pos++;
9705
- break;
9706
- }
9707
- if (ch === 92) {
9708
- result += text.substring(start, pos);
9709
- pos++;
9710
- if (pos >= len) {
9711
- scanError = 2;
9712
- break;
9713
- }
9714
- const ch2 = text.charCodeAt(pos++);
9715
- switch (ch2) {
9716
- case 34:
9717
- result += '"';
9718
- break;
9719
- case 92:
9720
- result += "\\";
9721
- break;
9722
- case 47:
9723
- result += "/";
9724
- break;
9725
- case 98:
9726
- result += "\b";
9727
- break;
9728
- case 102:
9729
- result += "\f";
9730
- break;
9731
- case 110:
9732
- result += `
9733
- `;
9734
- break;
9735
- case 114:
9736
- result += "\r";
9737
- break;
9738
- case 116:
9739
- result += "\t";
9740
- break;
9741
- case 117:
9742
- const ch3 = scanHexDigits(4, true);
9743
- if (ch3 >= 0) {
9744
- result += String.fromCharCode(ch3);
9745
- } else {
9746
- scanError = 4;
9747
- }
9748
- break;
9749
- default:
9750
- scanError = 5;
9751
- }
9752
- start = pos;
9753
- continue;
9754
- }
9755
- if (ch >= 0 && ch <= 31) {
9756
- if (isLineBreak(ch)) {
9757
- result += text.substring(start, pos);
9758
- scanError = 2;
9759
- break;
9760
- } else {
9761
- scanError = 6;
9762
- }
9763
- }
9764
- pos++;
9765
- }
9766
- return result;
9767
- }
9768
- function scanNext() {
9769
- value = "";
9770
- scanError = 0;
9771
- tokenOffset = pos;
9772
- lineStartOffset = lineNumber;
9773
- prevTokenLineStartOffset = tokenLineStartOffset;
9774
- if (pos >= len) {
9775
- tokenOffset = len;
9776
- return token = 17;
9777
- }
9778
- let code = text.charCodeAt(pos);
9779
- if (isWhiteSpace(code)) {
9780
- do {
9781
- pos++;
9782
- value += String.fromCharCode(code);
9783
- code = text.charCodeAt(pos);
9784
- } while (isWhiteSpace(code));
9785
- return token = 15;
9786
- }
9787
- if (isLineBreak(code)) {
9788
- pos++;
9789
- value += String.fromCharCode(code);
9790
- if (code === 13 && text.charCodeAt(pos) === 10) {
9791
- pos++;
9792
- value += `
9793
- `;
9794
- }
9795
- lineNumber++;
9796
- tokenLineStartOffset = pos;
9797
- return token = 14;
9798
- }
9799
- switch (code) {
9800
- case 123:
9801
- pos++;
9802
- return token = 1;
9803
- case 125:
9804
- pos++;
9805
- return token = 2;
9806
- case 91:
9807
- pos++;
9808
- return token = 3;
9809
- case 93:
9810
- pos++;
9811
- return token = 4;
9812
- case 58:
9813
- pos++;
9814
- return token = 6;
9815
- case 44:
9816
- pos++;
9817
- return token = 5;
9818
- case 34:
9819
- pos++;
9820
- value = scanString();
9821
- return token = 10;
9822
- case 47:
9823
- const start = pos - 1;
9824
- if (text.charCodeAt(pos + 1) === 47) {
9825
- pos += 2;
9826
- while (pos < len) {
9827
- if (isLineBreak(text.charCodeAt(pos))) {
9828
- break;
9829
- }
9830
- pos++;
9831
- }
9832
- value = text.substring(start, pos);
9833
- return token = 12;
9834
- }
9835
- if (text.charCodeAt(pos + 1) === 42) {
9836
- pos += 2;
9837
- const safeLength = len - 1;
9838
- let commentClosed = false;
9839
- while (pos < safeLength) {
9840
- const ch = text.charCodeAt(pos);
9841
- if (ch === 42 && text.charCodeAt(pos + 1) === 47) {
9842
- pos += 2;
9843
- commentClosed = true;
9844
- break;
9845
- }
9846
- pos++;
9847
- if (isLineBreak(ch)) {
9848
- if (ch === 13 && text.charCodeAt(pos) === 10) {
9849
- pos++;
9850
- }
9851
- lineNumber++;
9852
- tokenLineStartOffset = pos;
9853
- }
9854
- }
9855
- if (!commentClosed) {
9856
- pos++;
9857
- scanError = 1;
9858
- }
9859
- value = text.substring(start, pos);
9860
- return token = 13;
9861
- }
9862
- value += String.fromCharCode(code);
9863
- pos++;
9864
- return token = 16;
9865
- case 45:
9866
- value += String.fromCharCode(code);
9867
- pos++;
9868
- if (pos === len || !isDigit(text.charCodeAt(pos))) {
9869
- return token = 16;
9870
- }
9871
- case 48:
9872
- case 49:
9873
- case 50:
9874
- case 51:
9875
- case 52:
9876
- case 53:
9877
- case 54:
9878
- case 55:
9879
- case 56:
9880
- case 57:
9881
- value += scanNumber();
9882
- return token = 11;
9883
- default:
9884
- while (pos < len && isUnknownContentCharacter(code)) {
9885
- pos++;
9886
- code = text.charCodeAt(pos);
9887
- }
9888
- if (tokenOffset !== pos) {
9889
- value = text.substring(tokenOffset, pos);
9890
- switch (value) {
9891
- case "true":
9892
- return token = 8;
9893
- case "false":
9894
- return token = 9;
9895
- case "null":
9896
- return token = 7;
9897
- }
9898
- return token = 16;
9899
- }
9900
- value += String.fromCharCode(code);
9901
- pos++;
9902
- return token = 16;
9903
- }
9904
- }
9905
- function isUnknownContentCharacter(code) {
9906
- if (isWhiteSpace(code) || isLineBreak(code)) {
9907
- return false;
9908
- }
9909
- switch (code) {
9910
- case 125:
9911
- case 93:
9912
- case 123:
9913
- case 91:
9914
- case 34:
9915
- case 58:
9916
- case 44:
9917
- case 47:
9918
- return false;
9919
- }
9920
- return true;
9921
- }
9922
- function scanNextNonTrivia() {
9923
- let result;
9924
- do {
9925
- result = scanNext();
9926
- } while (result >= 12 && result <= 15);
9927
- return result;
9928
- }
9929
- return {
9930
- setPosition,
9931
- getPosition: () => pos,
9932
- scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
9933
- getToken: () => token,
9934
- getTokenValue: () => value,
9935
- getTokenOffset: () => tokenOffset,
9936
- getTokenLength: () => pos - tokenOffset,
9937
- getTokenStartLine: () => lineStartOffset,
9938
- getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
9939
- getTokenError: () => scanError
9940
- };
9941
- }
9942
- function isWhiteSpace(ch) {
9943
- return ch === 32 || ch === 9;
9944
- }
9945
- function isLineBreak(ch) {
9946
- return ch === 10 || ch === 13;
9947
- }
9948
- function isDigit(ch) {
9949
- return ch >= 48 && ch <= 57;
9950
- }
9951
- var CharacterCodes;
9952
- (function(CharacterCodes) {
9953
- CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed";
9954
- CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn";
9955
- CharacterCodes[CharacterCodes["space"] = 32] = "space";
9956
- CharacterCodes[CharacterCodes["_0"] = 48] = "_0";
9957
- CharacterCodes[CharacterCodes["_1"] = 49] = "_1";
9958
- CharacterCodes[CharacterCodes["_2"] = 50] = "_2";
9959
- CharacterCodes[CharacterCodes["_3"] = 51] = "_3";
9960
- CharacterCodes[CharacterCodes["_4"] = 52] = "_4";
9961
- CharacterCodes[CharacterCodes["_5"] = 53] = "_5";
9962
- CharacterCodes[CharacterCodes["_6"] = 54] = "_6";
9963
- CharacterCodes[CharacterCodes["_7"] = 55] = "_7";
9964
- CharacterCodes[CharacterCodes["_8"] = 56] = "_8";
9965
- CharacterCodes[CharacterCodes["_9"] = 57] = "_9";
9966
- CharacterCodes[CharacterCodes["a"] = 97] = "a";
9967
- CharacterCodes[CharacterCodes["b"] = 98] = "b";
9968
- CharacterCodes[CharacterCodes["c"] = 99] = "c";
9969
- CharacterCodes[CharacterCodes["d"] = 100] = "d";
9970
- CharacterCodes[CharacterCodes["e"] = 101] = "e";
9971
- CharacterCodes[CharacterCodes["f"] = 102] = "f";
9972
- CharacterCodes[CharacterCodes["g"] = 103] = "g";
9973
- CharacterCodes[CharacterCodes["h"] = 104] = "h";
9974
- CharacterCodes[CharacterCodes["i"] = 105] = "i";
9975
- CharacterCodes[CharacterCodes["j"] = 106] = "j";
9976
- CharacterCodes[CharacterCodes["k"] = 107] = "k";
9977
- CharacterCodes[CharacterCodes["l"] = 108] = "l";
9978
- CharacterCodes[CharacterCodes["m"] = 109] = "m";
9979
- CharacterCodes[CharacterCodes["n"] = 110] = "n";
9980
- CharacterCodes[CharacterCodes["o"] = 111] = "o";
9981
- CharacterCodes[CharacterCodes["p"] = 112] = "p";
9982
- CharacterCodes[CharacterCodes["q"] = 113] = "q";
9983
- CharacterCodes[CharacterCodes["r"] = 114] = "r";
9984
- CharacterCodes[CharacterCodes["s"] = 115] = "s";
9985
- CharacterCodes[CharacterCodes["t"] = 116] = "t";
9986
- CharacterCodes[CharacterCodes["u"] = 117] = "u";
9987
- CharacterCodes[CharacterCodes["v"] = 118] = "v";
9988
- CharacterCodes[CharacterCodes["w"] = 119] = "w";
9989
- CharacterCodes[CharacterCodes["x"] = 120] = "x";
9990
- CharacterCodes[CharacterCodes["y"] = 121] = "y";
9991
- CharacterCodes[CharacterCodes["z"] = 122] = "z";
9992
- CharacterCodes[CharacterCodes["A"] = 65] = "A";
9993
- CharacterCodes[CharacterCodes["B"] = 66] = "B";
9994
- CharacterCodes[CharacterCodes["C"] = 67] = "C";
9995
- CharacterCodes[CharacterCodes["D"] = 68] = "D";
9996
- CharacterCodes[CharacterCodes["E"] = 69] = "E";
9997
- CharacterCodes[CharacterCodes["F"] = 70] = "F";
9998
- CharacterCodes[CharacterCodes["G"] = 71] = "G";
9999
- CharacterCodes[CharacterCodes["H"] = 72] = "H";
10000
- CharacterCodes[CharacterCodes["I"] = 73] = "I";
10001
- CharacterCodes[CharacterCodes["J"] = 74] = "J";
10002
- CharacterCodes[CharacterCodes["K"] = 75] = "K";
10003
- CharacterCodes[CharacterCodes["L"] = 76] = "L";
10004
- CharacterCodes[CharacterCodes["M"] = 77] = "M";
10005
- CharacterCodes[CharacterCodes["N"] = 78] = "N";
10006
- CharacterCodes[CharacterCodes["O"] = 79] = "O";
10007
- CharacterCodes[CharacterCodes["P"] = 80] = "P";
10008
- CharacterCodes[CharacterCodes["Q"] = 81] = "Q";
10009
- CharacterCodes[CharacterCodes["R"] = 82] = "R";
10010
- CharacterCodes[CharacterCodes["S"] = 83] = "S";
10011
- CharacterCodes[CharacterCodes["T"] = 84] = "T";
10012
- CharacterCodes[CharacterCodes["U"] = 85] = "U";
10013
- CharacterCodes[CharacterCodes["V"] = 86] = "V";
10014
- CharacterCodes[CharacterCodes["W"] = 87] = "W";
10015
- CharacterCodes[CharacterCodes["X"] = 88] = "X";
10016
- CharacterCodes[CharacterCodes["Y"] = 89] = "Y";
10017
- CharacterCodes[CharacterCodes["Z"] = 90] = "Z";
10018
- CharacterCodes[CharacterCodes["asterisk"] = 42] = "asterisk";
10019
- CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash";
10020
- CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace";
10021
- CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket";
10022
- CharacterCodes[CharacterCodes["colon"] = 58] = "colon";
10023
- CharacterCodes[CharacterCodes["comma"] = 44] = "comma";
10024
- CharacterCodes[CharacterCodes["dot"] = 46] = "dot";
10025
- CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote";
10026
- CharacterCodes[CharacterCodes["minus"] = 45] = "minus";
10027
- CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace";
10028
- CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket";
10029
- CharacterCodes[CharacterCodes["plus"] = 43] = "plus";
10030
- CharacterCodes[CharacterCodes["slash"] = 47] = "slash";
10031
- CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed";
10032
- CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
10033
- })(CharacterCodes || (CharacterCodes = {}));
10034
-
10035
- // ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/string-intern.js
10036
- var cachedSpaces = new Array(20).fill(0).map((_, index) => {
10037
- return " ".repeat(index);
10038
- });
10039
- var maxCachedValues = 200;
10040
- var cachedBreakLinesWithSpaces = {
10041
- " ": {
10042
- "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
10043
- return `
10044
- ` + " ".repeat(index);
10045
- }),
10046
- "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
10047
- return "\r" + " ".repeat(index);
10048
- }),
10049
- "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
10050
- return `\r
10051
- ` + " ".repeat(index);
10052
- })
10053
- },
10054
- "\t": {
10055
- "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
10056
- return `
10057
- ` + "\t".repeat(index);
10058
- }),
10059
- "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
10060
- return "\r" + "\t".repeat(index);
10061
- }),
10062
- "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
10063
- return `\r
10064
- ` + "\t".repeat(index);
10065
- })
10066
- }
10067
- };
10068
- var supportedEols = [`
10069
- `, "\r", `\r
10070
- `];
10071
-
10072
- // ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/format.js
10073
- function format(documentText, range, options) {
10074
- let initialIndentLevel;
10075
- let formatText;
10076
- let formatTextStart;
10077
- let rangeStart;
10078
- let rangeEnd;
10079
- if (range) {
10080
- rangeStart = range.offset;
10081
- rangeEnd = rangeStart + range.length;
10082
- formatTextStart = rangeStart;
10083
- while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {
10084
- formatTextStart--;
10085
- }
10086
- let endOffset = rangeEnd;
10087
- while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {
10088
- endOffset++;
10089
- }
10090
- formatText = documentText.substring(formatTextStart, endOffset);
10091
- initialIndentLevel = computeIndentLevel(formatText, options);
10092
- } else {
10093
- formatText = documentText;
10094
- initialIndentLevel = 0;
10095
- formatTextStart = 0;
10096
- rangeStart = 0;
10097
- rangeEnd = documentText.length;
10098
- }
10099
- const eol = getEOL(options, documentText);
10100
- const eolFastPathSupported = supportedEols.includes(eol);
10101
- let numberLineBreaks = 0;
10102
- let indentLevel = 0;
10103
- let indentValue;
10104
- if (options.insertSpaces) {
10105
- indentValue = cachedSpaces[options.tabSize || 4] ?? repeat(cachedSpaces[1], options.tabSize || 4);
10106
- } else {
10107
- indentValue = "\t";
10108
- }
10109
- const indentType = indentValue === "\t" ? "\t" : " ";
10110
- let scanner = createScanner(formatText, false);
10111
- let hasError = false;
10112
- function newLinesAndIndent() {
10113
- if (numberLineBreaks > 1) {
10114
- return repeat(eol, numberLineBreaks) + repeat(indentValue, initialIndentLevel + indentLevel);
10115
- }
10116
- const amountOfSpaces = indentValue.length * (initialIndentLevel + indentLevel);
10117
- if (!eolFastPathSupported || amountOfSpaces > cachedBreakLinesWithSpaces[indentType][eol].length) {
10118
- return eol + repeat(indentValue, initialIndentLevel + indentLevel);
10119
- }
10120
- if (amountOfSpaces <= 0) {
10121
- return eol;
10122
- }
10123
- return cachedBreakLinesWithSpaces[indentType][eol][amountOfSpaces];
10124
- }
10125
- function scanNext() {
10126
- let token = scanner.scan();
10127
- numberLineBreaks = 0;
10128
- while (token === 15 || token === 14) {
10129
- if (token === 14 && options.keepLines) {
10130
- numberLineBreaks += 1;
10131
- } else if (token === 14) {
10132
- numberLineBreaks = 1;
10133
- }
10134
- token = scanner.scan();
10135
- }
10136
- hasError = token === 16 || scanner.getTokenError() !== 0;
10137
- return token;
10138
- }
10139
- const editOperations = [];
10140
- function addEdit(text, startOffset, endOffset) {
10141
- if (!hasError && (!range || startOffset < rangeEnd && endOffset > rangeStart) && documentText.substring(startOffset, endOffset) !== text) {
10142
- editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
10143
- }
10144
- }
10145
- let firstToken = scanNext();
10146
- if (options.keepLines && numberLineBreaks > 0) {
10147
- addEdit(repeat(eol, numberLineBreaks), 0, 0);
10148
- }
10149
- if (firstToken !== 17) {
10150
- let firstTokenStart = scanner.getTokenOffset() + formatTextStart;
10151
- let initialIndent = indentValue.length * initialIndentLevel < 20 && options.insertSpaces ? cachedSpaces[indentValue.length * initialIndentLevel] : repeat(indentValue, initialIndentLevel);
10152
- addEdit(initialIndent, formatTextStart, firstTokenStart);
10153
- }
10154
- while (firstToken !== 17) {
10155
- let firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
10156
- let secondToken = scanNext();
10157
- let replaceContent = "";
10158
- let needsLineBreak = false;
10159
- while (numberLineBreaks === 0 && (secondToken === 12 || secondToken === 13)) {
10160
- let commentTokenStart = scanner.getTokenOffset() + formatTextStart;
10161
- addEdit(cachedSpaces[1], firstTokenEnd, commentTokenStart);
10162
- firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
10163
- needsLineBreak = secondToken === 12;
10164
- replaceContent = needsLineBreak ? newLinesAndIndent() : "";
10165
- secondToken = scanNext();
10166
- }
10167
- if (secondToken === 2) {
10168
- if (firstToken !== 1) {
10169
- indentLevel--;
10170
- }
10171
- if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 1) {
10172
- replaceContent = newLinesAndIndent();
10173
- } else if (options.keepLines) {
10174
- replaceContent = cachedSpaces[1];
10175
- }
10176
- } else if (secondToken === 4) {
10177
- if (firstToken !== 3) {
10178
- indentLevel--;
10179
- }
10180
- if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 3) {
10181
- replaceContent = newLinesAndIndent();
10182
- } else if (options.keepLines) {
10183
- replaceContent = cachedSpaces[1];
10184
- }
10185
- } else {
10186
- switch (firstToken) {
10187
- case 3:
10188
- case 1:
10189
- indentLevel++;
10190
- if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) {
10191
- replaceContent = newLinesAndIndent();
10192
- } else {
10193
- replaceContent = cachedSpaces[1];
10194
- }
10195
- break;
10196
- case 5:
10197
- if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) {
10198
- replaceContent = newLinesAndIndent();
10199
- } else {
10200
- replaceContent = cachedSpaces[1];
10201
- }
10202
- break;
10203
- case 12:
10204
- replaceContent = newLinesAndIndent();
10205
- break;
10206
- case 13:
10207
- if (numberLineBreaks > 0) {
10208
- replaceContent = newLinesAndIndent();
10209
- } else if (!needsLineBreak) {
10210
- replaceContent = cachedSpaces[1];
10211
- }
10212
- break;
10213
- case 6:
10214
- if (options.keepLines && numberLineBreaks > 0) {
10215
- replaceContent = newLinesAndIndent();
10216
- } else if (!needsLineBreak) {
10217
- replaceContent = cachedSpaces[1];
10218
- }
10219
- break;
10220
- case 10:
10221
- if (options.keepLines && numberLineBreaks > 0) {
10222
- replaceContent = newLinesAndIndent();
10223
- } else if (secondToken === 6 && !needsLineBreak) {
10224
- replaceContent = "";
10225
- }
10226
- break;
10227
- case 7:
10228
- case 8:
10229
- case 9:
10230
- case 11:
10231
- case 2:
10232
- case 4:
10233
- if (options.keepLines && numberLineBreaks > 0) {
10234
- replaceContent = newLinesAndIndent();
10235
- } else {
10236
- if ((secondToken === 12 || secondToken === 13) && !needsLineBreak) {
10237
- replaceContent = cachedSpaces[1];
10238
- } else if (secondToken !== 5 && secondToken !== 17) {
10239
- hasError = true;
10240
- }
10241
- }
10242
- break;
10243
- case 16:
10244
- hasError = true;
10245
- break;
10246
- }
10247
- if (numberLineBreaks > 0 && (secondToken === 12 || secondToken === 13)) {
10248
- replaceContent = newLinesAndIndent();
10249
- }
10250
- }
10251
- if (secondToken === 17) {
10252
- if (options.keepLines && numberLineBreaks > 0) {
10253
- replaceContent = newLinesAndIndent();
10254
- } else {
10255
- replaceContent = options.insertFinalNewline ? eol : "";
10256
- }
10257
- }
10258
- const secondTokenStart = scanner.getTokenOffset() + formatTextStart;
10259
- addEdit(replaceContent, firstTokenEnd, secondTokenStart);
10260
- firstToken = secondToken;
10261
- }
10262
- return editOperations;
10263
- }
10264
- function repeat(s, count) {
10265
- let result = "";
10266
- for (let i = 0;i < count; i++) {
10267
- result += s;
10268
- }
10269
- return result;
10270
- }
10271
- function computeIndentLevel(content, options) {
10272
- let i = 0;
10273
- let nChars = 0;
10274
- const tabSize = options.tabSize || 4;
10275
- while (i < content.length) {
10276
- let ch = content.charAt(i);
10277
- if (ch === cachedSpaces[1]) {
10278
- nChars++;
10279
- } else if (ch === "\t") {
10280
- nChars += tabSize;
10281
- } else {
10282
- break;
10283
- }
10284
- i++;
10285
- }
10286
- return Math.floor(nChars / tabSize);
10287
- }
10288
- function getEOL(options, text) {
10289
- for (let i = 0;i < text.length; i++) {
10290
- const ch = text.charAt(i);
10291
- if (ch === "\r") {
10292
- if (i + 1 < text.length && text.charAt(i + 1) === `
10293
- `) {
10294
- return `\r
10295
- `;
10296
- }
10297
- return "\r";
10298
- } else if (ch === `
10299
- `) {
10300
- return `
10301
- `;
10302
- }
10303
- }
10304
- return options && options.eol || `
10305
- `;
10306
- }
10307
- function isEOL(text, offset) {
10308
- return `\r
10309
- `.indexOf(text.charAt(offset)) !== -1;
10310
- }
10311
-
10312
- // ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/parser.js
10313
- var ParseOptions;
10314
- (function(ParseOptions) {
10315
- ParseOptions.DEFAULT = {
10316
- allowTrailingComma: false
10317
- };
10318
- })(ParseOptions || (ParseOptions = {}));
10319
- function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
10320
- let currentParent = { type: "array", offset: -1, length: -1, children: [], parent: undefined };
10321
- function ensurePropertyComplete(endOffset) {
10322
- if (currentParent.type === "property") {
10323
- currentParent.length = endOffset - currentParent.offset;
10324
- currentParent = currentParent.parent;
10325
- }
10326
- }
10327
- function onValue(valueNode) {
10328
- currentParent.children.push(valueNode);
10329
- return valueNode;
10330
- }
10331
- const visitor = {
10332
- onObjectBegin: (offset) => {
10333
- currentParent = onValue({ type: "object", offset, length: -1, parent: currentParent, children: [] });
10334
- },
10335
- onObjectProperty: (name, offset, length) => {
10336
- currentParent = onValue({ type: "property", offset, length: -1, parent: currentParent, children: [] });
10337
- currentParent.children.push({ type: "string", value: name, offset, length, parent: currentParent });
10338
- },
10339
- onObjectEnd: (offset, length) => {
10340
- ensurePropertyComplete(offset + length);
10341
- currentParent.length = offset + length - currentParent.offset;
10342
- currentParent = currentParent.parent;
10343
- ensurePropertyComplete(offset + length);
10344
- },
10345
- onArrayBegin: (offset, length) => {
10346
- currentParent = onValue({ type: "array", offset, length: -1, parent: currentParent, children: [] });
10347
- },
10348
- onArrayEnd: (offset, length) => {
10349
- currentParent.length = offset + length - currentParent.offset;
10350
- currentParent = currentParent.parent;
10351
- ensurePropertyComplete(offset + length);
10352
- },
10353
- onLiteralValue: (value, offset, length) => {
10354
- onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });
10355
- ensurePropertyComplete(offset + length);
10356
- },
10357
- onSeparator: (sep, offset, length) => {
10358
- if (currentParent.type === "property") {
10359
- if (sep === ":") {
10360
- currentParent.colonOffset = offset;
10361
- } else if (sep === ",") {
10362
- ensurePropertyComplete(offset);
10363
- }
10364
- }
10365
- },
10366
- onError: (error, offset, length) => {
10367
- errors.push({ error, offset, length });
10368
- }
10369
- };
10370
- visit(text, visitor, options);
10371
- const result = currentParent.children[0];
10372
- if (result) {
10373
- delete result.parent;
10374
- }
10375
- return result;
10376
- }
10377
- function findNodeAtLocation(root, path) {
10378
- if (!root) {
10379
- return;
10380
- }
10381
- let node = root;
10382
- for (let segment of path) {
10383
- if (typeof segment === "string") {
10384
- if (node.type !== "object" || !Array.isArray(node.children)) {
10385
- return;
10386
- }
10387
- let found = false;
10388
- for (const propertyNode of node.children) {
10389
- if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {
10390
- node = propertyNode.children[1];
10391
- found = true;
10392
- break;
10393
- }
10394
- }
10395
- if (!found) {
10396
- return;
10397
- }
10398
- } else {
10399
- const index = segment;
10400
- if (node.type !== "array" || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {
10401
- return;
10402
- }
10403
- node = node.children[index];
10404
- }
10405
- }
10406
- return node;
10407
- }
10408
- function getNodeValue(node) {
10409
- switch (node.type) {
10410
- case "array":
10411
- return node.children.map(getNodeValue);
10412
- case "object":
10413
- const obj = Object.create(null);
10414
- for (let prop of node.children) {
10415
- const valueNode = prop.children[1];
10416
- if (valueNode) {
10417
- obj[prop.children[0].value] = getNodeValue(valueNode);
10418
- }
10419
- }
10420
- return obj;
10421
- case "null":
10422
- case "string":
10423
- case "number":
10424
- case "boolean":
10425
- return node.value;
10426
- default:
10427
- return;
10428
- }
10429
- }
10430
- function visit(text, visitor, options = ParseOptions.DEFAULT) {
10431
- const _scanner = createScanner(text, false);
10432
- const _jsonPath = [];
10433
- let suppressedCallbacks = 0;
10434
- function toNoArgVisit(visitFunction) {
10435
- return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
10436
- }
10437
- function toOneArgVisit(visitFunction) {
10438
- return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
10439
- }
10440
- function toOneArgVisitWithPath(visitFunction) {
10441
- return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;
10442
- }
10443
- function toBeginVisit(visitFunction) {
10444
- return visitFunction ? () => {
10445
- if (suppressedCallbacks > 0) {
10446
- suppressedCallbacks++;
10447
- } else {
10448
- let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());
10449
- if (cbReturn === false) {
10450
- suppressedCallbacks = 1;
10451
- }
10452
- }
10453
- } : () => true;
10454
- }
10455
- function toEndVisit(visitFunction) {
10456
- return visitFunction ? () => {
10457
- if (suppressedCallbacks > 0) {
10458
- suppressedCallbacks--;
10459
- }
10460
- if (suppressedCallbacks === 0) {
10461
- visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());
10462
- }
10463
- } : () => true;
10464
- }
10465
- const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);
10466
- const disallowComments = options && options.disallowComments;
10467
- const allowTrailingComma = options && options.allowTrailingComma;
10468
- function scanNext() {
10469
- while (true) {
10470
- const token = _scanner.scan();
10471
- switch (_scanner.getTokenError()) {
10472
- case 4:
10473
- handleError(14);
10474
- break;
10475
- case 5:
10476
- handleError(15);
10477
- break;
10478
- case 3:
10479
- handleError(13);
10480
- break;
10481
- case 1:
10482
- if (!disallowComments) {
10483
- handleError(11);
10484
- }
10485
- break;
10486
- case 2:
10487
- handleError(12);
10488
- break;
10489
- case 6:
10490
- handleError(16);
10491
- break;
10492
- }
10493
- switch (token) {
10494
- case 12:
10495
- case 13:
10496
- if (disallowComments) {
10497
- handleError(10);
10498
- } else {
10499
- onComment();
10500
- }
10501
- break;
10502
- case 16:
10503
- handleError(1);
10504
- break;
10505
- case 15:
10506
- case 14:
10507
- break;
10508
- default:
10509
- return token;
10510
- }
10511
- }
10512
- }
10513
- function handleError(error, skipUntilAfter = [], skipUntil = []) {
10514
- onError(error);
10515
- if (skipUntilAfter.length + skipUntil.length > 0) {
10516
- let token = _scanner.getToken();
10517
- while (token !== 17) {
10518
- if (skipUntilAfter.indexOf(token) !== -1) {
10519
- scanNext();
10520
- break;
10521
- } else if (skipUntil.indexOf(token) !== -1) {
10522
- break;
10523
- }
10524
- token = scanNext();
10525
- }
10526
- }
10527
- }
10528
- function parseString(isValue) {
10529
- const value = _scanner.getTokenValue();
10530
- if (isValue) {
10531
- onLiteralValue(value);
10532
- } else {
10533
- onObjectProperty(value);
10534
- _jsonPath.push(value);
10535
- }
10536
- scanNext();
10537
- return true;
10538
- }
10539
- function parseLiteral() {
10540
- switch (_scanner.getToken()) {
10541
- case 11:
10542
- const tokenValue = _scanner.getTokenValue();
10543
- let value = Number(tokenValue);
10544
- if (isNaN(value)) {
10545
- handleError(2);
10546
- value = 0;
10547
- }
10548
- onLiteralValue(value);
10549
- break;
10550
- case 7:
10551
- onLiteralValue(null);
10552
- break;
10553
- case 8:
10554
- onLiteralValue(true);
10555
- break;
10556
- case 9:
10557
- onLiteralValue(false);
10558
- break;
10559
- default:
10560
- return false;
10561
- }
10562
- scanNext();
10563
- return true;
10564
- }
10565
- function parseProperty() {
10566
- if (_scanner.getToken() !== 10) {
10567
- handleError(3, [], [2, 5]);
10568
- return false;
10569
- }
10570
- parseString(false);
10571
- if (_scanner.getToken() === 6) {
10572
- onSeparator(":");
10573
- scanNext();
10574
- if (!parseValue()) {
10575
- handleError(4, [], [2, 5]);
10576
- }
10577
- } else {
10578
- handleError(5, [], [2, 5]);
10579
- }
10580
- _jsonPath.pop();
10581
- return true;
10582
- }
10583
- function parseObject() {
10584
- onObjectBegin();
10585
- scanNext();
10586
- let needsComma = false;
10587
- while (_scanner.getToken() !== 2 && _scanner.getToken() !== 17) {
10588
- if (_scanner.getToken() === 5) {
10589
- if (!needsComma) {
10590
- handleError(4, [], []);
10591
- }
10592
- onSeparator(",");
10593
- scanNext();
10594
- if (_scanner.getToken() === 2 && allowTrailingComma) {
10595
- break;
10596
- }
10597
- } else if (needsComma) {
10598
- handleError(6, [], []);
10599
- }
10600
- if (!parseProperty()) {
10601
- handleError(4, [], [2, 5]);
10602
- }
10603
- needsComma = true;
10604
- }
10605
- onObjectEnd();
10606
- if (_scanner.getToken() !== 2) {
10607
- handleError(7, [2], []);
10608
- } else {
10609
- scanNext();
10610
- }
10611
- return true;
10612
- }
10613
- function parseArray() {
10614
- onArrayBegin();
10615
- scanNext();
10616
- let isFirstElement = true;
10617
- let needsComma = false;
10618
- while (_scanner.getToken() !== 4 && _scanner.getToken() !== 17) {
10619
- if (_scanner.getToken() === 5) {
10620
- if (!needsComma) {
10621
- handleError(4, [], []);
10622
- }
10623
- onSeparator(",");
10624
- scanNext();
10625
- if (_scanner.getToken() === 4 && allowTrailingComma) {
10626
- break;
10627
- }
10628
- } else if (needsComma) {
10629
- handleError(6, [], []);
10630
- }
10631
- if (isFirstElement) {
10632
- _jsonPath.push(0);
10633
- isFirstElement = false;
10634
- } else {
10635
- _jsonPath[_jsonPath.length - 1]++;
10636
- }
10637
- if (!parseValue()) {
10638
- handleError(4, [], [4, 5]);
10639
- }
10640
- needsComma = true;
10641
- }
10642
- onArrayEnd();
10643
- if (!isFirstElement) {
10644
- _jsonPath.pop();
10645
- }
10646
- if (_scanner.getToken() !== 4) {
10647
- handleError(8, [4], []);
10648
- } else {
10649
- scanNext();
10650
- }
10651
- return true;
10652
- }
10653
- function parseValue() {
10654
- switch (_scanner.getToken()) {
10655
- case 3:
10656
- return parseArray();
10657
- case 1:
10658
- return parseObject();
10659
- case 10:
10660
- return parseString(true);
10661
- default:
10662
- return parseLiteral();
10663
- }
10664
- }
10665
- scanNext();
10666
- if (_scanner.getToken() === 17) {
10667
- if (options.allowEmptyContent) {
10668
- return true;
10669
- }
10670
- handleError(4, [], []);
10671
- return false;
10672
- }
10673
- if (!parseValue()) {
10674
- handleError(4, [], []);
10675
- return false;
10676
- }
10677
- if (_scanner.getToken() !== 17) {
10678
- handleError(9, [], []);
10679
- }
10680
- return true;
10681
- }
10682
- function getNodeType(value) {
10683
- switch (typeof value) {
10684
- case "boolean":
10685
- return "boolean";
10686
- case "number":
10687
- return "number";
10688
- case "string":
10689
- return "string";
10690
- case "object": {
10691
- if (!value) {
10692
- return "null";
10693
- } else if (Array.isArray(value)) {
10694
- return "array";
10695
- }
10696
- return "object";
10697
- }
10698
- default:
10699
- return "null";
10700
- }
10701
- }
10702
-
10703
- // ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/edit.js
10704
- function setProperty(text, originalPath, value, options) {
10705
- const path = originalPath.slice();
10706
- const errors = [];
10707
- const root = parseTree(text, errors);
10708
- let parent = undefined;
10709
- let lastSegment = undefined;
10710
- while (path.length > 0) {
10711
- lastSegment = path.pop();
10712
- parent = findNodeAtLocation(root, path);
10713
- if (parent === undefined && value !== undefined) {
10714
- if (typeof lastSegment === "string") {
10715
- value = { [lastSegment]: value };
10716
- } else {
10717
- value = [value];
10718
- }
10719
- } else {
10720
- break;
10721
- }
10722
- }
10723
- if (!parent) {
10724
- if (value === undefined) {
10725
- throw new Error("Can not delete in empty document");
10726
- }
10727
- return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, options);
10728
- } else if (parent.type === "object" && typeof lastSegment === "string" && Array.isArray(parent.children)) {
10729
- const existing = findNodeAtLocation(parent, [lastSegment]);
10730
- if (existing !== undefined) {
10731
- if (value === undefined) {
10732
- if (!existing.parent) {
10733
- throw new Error("Malformed AST");
10734
- }
10735
- const propertyIndex = parent.children.indexOf(existing.parent);
10736
- let removeBegin;
10737
- let removeEnd = existing.parent.offset + existing.parent.length;
10738
- if (propertyIndex > 0) {
10739
- let previous = parent.children[propertyIndex - 1];
10740
- removeBegin = previous.offset + previous.length;
10741
- } else {
10742
- removeBegin = parent.offset + 1;
10743
- if (parent.children.length > 1) {
10744
- let next = parent.children[1];
10745
- removeEnd = next.offset;
10746
- }
10747
- }
10748
- return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: "" }, options);
10749
- } else {
10750
- return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, options);
10751
- }
10752
- } else {
10753
- if (value === undefined) {
10754
- return [];
10755
- }
10756
- const newProperty = `${JSON.stringify(lastSegment)}: ${JSON.stringify(value)}`;
10757
- const index = options.getInsertionIndex ? options.getInsertionIndex(parent.children.map((p) => p.children[0].value)) : parent.children.length;
10758
- let edit;
10759
- if (index > 0) {
10760
- let previous = parent.children[index - 1];
10761
- edit = { offset: previous.offset + previous.length, length: 0, content: "," + newProperty };
10762
- } else if (parent.children.length === 0) {
10763
- edit = { offset: parent.offset + 1, length: 0, content: newProperty };
10764
- } else {
10765
- edit = { offset: parent.offset + 1, length: 0, content: newProperty + "," };
10766
- }
10767
- return withFormatting(text, edit, options);
10768
- }
10769
- } else if (parent.type === "array" && typeof lastSegment === "number" && Array.isArray(parent.children)) {
10770
- const insertIndex = lastSegment;
10771
- if (insertIndex === -1) {
10772
- const newProperty = `${JSON.stringify(value)}`;
10773
- let edit;
10774
- if (parent.children.length === 0) {
10775
- edit = { offset: parent.offset + 1, length: 0, content: newProperty };
10776
- } else {
10777
- const previous = parent.children[parent.children.length - 1];
10778
- edit = { offset: previous.offset + previous.length, length: 0, content: "," + newProperty };
10779
- }
10780
- return withFormatting(text, edit, options);
10781
- } else if (value === undefined && parent.children.length >= 0) {
10782
- const removalIndex = lastSegment;
10783
- const toRemove = parent.children[removalIndex];
10784
- let edit;
10785
- if (parent.children.length === 1) {
10786
- edit = { offset: parent.offset + 1, length: parent.length - 2, content: "" };
10787
- } else if (parent.children.length - 1 === removalIndex) {
10788
- let previous = parent.children[removalIndex - 1];
10789
- let offset = previous.offset + previous.length;
10790
- let parentEndOffset = parent.offset + parent.length;
10791
- edit = { offset, length: parentEndOffset - 2 - offset, content: "" };
10792
- } else {
10793
- edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: "" };
10794
- }
10795
- return withFormatting(text, edit, options);
10796
- } else if (value !== undefined) {
10797
- let edit;
10798
- const newProperty = `${JSON.stringify(value)}`;
10799
- if (!options.isArrayInsertion && parent.children.length > lastSegment) {
10800
- const toModify = parent.children[lastSegment];
10801
- edit = { offset: toModify.offset, length: toModify.length, content: newProperty };
10802
- } else if (parent.children.length === 0 || lastSegment === 0) {
10803
- edit = { offset: parent.offset + 1, length: 0, content: parent.children.length === 0 ? newProperty : newProperty + "," };
10804
- } else {
10805
- const index = lastSegment > parent.children.length ? parent.children.length : lastSegment;
10806
- const previous = parent.children[index - 1];
10807
- edit = { offset: previous.offset + previous.length, length: 0, content: "," + newProperty };
10808
- }
10809
- return withFormatting(text, edit, options);
10810
- } else {
10811
- throw new Error(`Can not ${value === undefined ? "remove" : options.isArrayInsertion ? "insert" : "modify"} Array index ${insertIndex} as length is not sufficient`);
10812
- }
10813
- } else {
10814
- throw new Error(`Can not add ${typeof lastSegment !== "number" ? "index" : "property"} to parent of type ${parent.type}`);
10815
- }
10816
- }
10817
- function withFormatting(text, edit, options) {
10818
- if (!options.formattingOptions) {
10819
- return [edit];
10820
- }
10821
- let newText = applyEdit(text, edit);
10822
- let begin = edit.offset;
10823
- let end = edit.offset + edit.content.length;
10824
- if (edit.length === 0 || edit.content.length === 0) {
10825
- while (begin > 0 && !isEOL(newText, begin - 1)) {
10826
- begin--;
10827
- }
10828
- while (end < newText.length && !isEOL(newText, end)) {
10829
- end++;
10830
- }
10831
- }
10832
- const edits = format(newText, { offset: begin, length: end - begin }, { ...options.formattingOptions, keepLines: false });
10833
- for (let i = edits.length - 1;i >= 0; i--) {
10834
- const edit = edits[i];
10835
- newText = applyEdit(newText, edit);
10836
- begin = Math.min(begin, edit.offset);
10837
- end = Math.max(end, edit.offset + edit.length);
10838
- end += edit.content.length - edit.length;
10839
- }
10840
- const editLength = text.length - (newText.length - end) - begin;
10841
- return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
10842
- }
10843
- function applyEdit(text, edit) {
10844
- return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
10845
- }
10846
-
10847
- // ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/main.js
10848
- var createScanner2 = createScanner;
10849
- var ScanError;
10850
- (function(ScanError) {
10851
- ScanError[ScanError["None"] = 0] = "None";
10852
- ScanError[ScanError["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
10853
- ScanError[ScanError["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
10854
- ScanError[ScanError["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
10855
- ScanError[ScanError["InvalidUnicode"] = 4] = "InvalidUnicode";
10856
- ScanError[ScanError["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
10857
- ScanError[ScanError["InvalidCharacter"] = 6] = "InvalidCharacter";
10858
- })(ScanError || (ScanError = {}));
10859
- var SyntaxKind;
10860
- (function(SyntaxKind) {
10861
- SyntaxKind[SyntaxKind["OpenBraceToken"] = 1] = "OpenBraceToken";
10862
- SyntaxKind[SyntaxKind["CloseBraceToken"] = 2] = "CloseBraceToken";
10863
- SyntaxKind[SyntaxKind["OpenBracketToken"] = 3] = "OpenBracketToken";
10864
- SyntaxKind[SyntaxKind["CloseBracketToken"] = 4] = "CloseBracketToken";
10865
- SyntaxKind[SyntaxKind["CommaToken"] = 5] = "CommaToken";
10866
- SyntaxKind[SyntaxKind["ColonToken"] = 6] = "ColonToken";
10867
- SyntaxKind[SyntaxKind["NullKeyword"] = 7] = "NullKeyword";
10868
- SyntaxKind[SyntaxKind["TrueKeyword"] = 8] = "TrueKeyword";
10869
- SyntaxKind[SyntaxKind["FalseKeyword"] = 9] = "FalseKeyword";
10870
- SyntaxKind[SyntaxKind["StringLiteral"] = 10] = "StringLiteral";
10871
- SyntaxKind[SyntaxKind["NumericLiteral"] = 11] = "NumericLiteral";
10872
- SyntaxKind[SyntaxKind["LineCommentTrivia"] = 12] = "LineCommentTrivia";
10873
- SyntaxKind[SyntaxKind["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
10874
- SyntaxKind[SyntaxKind["LineBreakTrivia"] = 14] = "LineBreakTrivia";
10875
- SyntaxKind[SyntaxKind["Trivia"] = 15] = "Trivia";
10876
- SyntaxKind[SyntaxKind["Unknown"] = 16] = "Unknown";
10877
- SyntaxKind[SyntaxKind["EOF"] = 17] = "EOF";
10878
- })(SyntaxKind || (SyntaxKind = {}));
10879
- var parseTree2 = parseTree;
10880
- var findNodeAtLocation2 = findNodeAtLocation;
10881
- var getNodeValue2 = getNodeValue;
10882
- var ParseErrorCode;
10883
- (function(ParseErrorCode) {
10884
- ParseErrorCode[ParseErrorCode["InvalidSymbol"] = 1] = "InvalidSymbol";
10885
- ParseErrorCode[ParseErrorCode["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
10886
- ParseErrorCode[ParseErrorCode["PropertyNameExpected"] = 3] = "PropertyNameExpected";
10887
- ParseErrorCode[ParseErrorCode["ValueExpected"] = 4] = "ValueExpected";
10888
- ParseErrorCode[ParseErrorCode["ColonExpected"] = 5] = "ColonExpected";
10889
- ParseErrorCode[ParseErrorCode["CommaExpected"] = 6] = "CommaExpected";
10890
- ParseErrorCode[ParseErrorCode["CloseBraceExpected"] = 7] = "CloseBraceExpected";
10891
- ParseErrorCode[ParseErrorCode["CloseBracketExpected"] = 8] = "CloseBracketExpected";
10892
- ParseErrorCode[ParseErrorCode["EndOfFileExpected"] = 9] = "EndOfFileExpected";
10893
- ParseErrorCode[ParseErrorCode["InvalidCommentToken"] = 10] = "InvalidCommentToken";
10894
- ParseErrorCode[ParseErrorCode["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
10895
- ParseErrorCode[ParseErrorCode["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
10896
- ParseErrorCode[ParseErrorCode["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
10897
- ParseErrorCode[ParseErrorCode["InvalidUnicode"] = 14] = "InvalidUnicode";
10898
- ParseErrorCode[ParseErrorCode["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
10899
- ParseErrorCode[ParseErrorCode["InvalidCharacter"] = 16] = "InvalidCharacter";
10900
- })(ParseErrorCode || (ParseErrorCode = {}));
10901
- function modify(text, path, value, options) {
10902
- return setProperty(text, path, value, options);
10903
- }
10904
- function applyEdits(text, edits) {
10905
- let sortedEdits = edits.slice(0).sort((a, b) => {
10906
- const diff = a.offset - b.offset;
10907
- if (diff === 0) {
10908
- return a.length - b.length;
10909
- }
10910
- return diff;
10911
- });
10912
- let lastModifiedOffset = text.length;
10913
- for (let i = sortedEdits.length - 1;i >= 0; i--) {
10914
- let e = sortedEdits[i];
10915
- if (e.offset + e.length <= lastModifiedOffset) {
10916
- text = applyEdit(text, e);
10917
- } else {
10918
- throw new Error("Overlapping edit");
10919
- }
10920
- lastModifiedOffset = e.offset;
10921
- }
10922
- return text;
10923
- }
10924
-
10925
9657
  // src/shared/jsonc-edit.ts
10926
9658
  var TOKEN_COMMA = 5;
10927
9659
  var TOKEN_EOF = 17;
10928
9660
  function parseDocument(text) {
10929
9661
  const errors = [];
10930
- const root = parseTree2(text, errors, { allowTrailingComma: true });
9662
+ const root = parseTree(text, errors, { allowTrailingComma: true });
10931
9663
  if (!root || errors.length > 0) {
10932
9664
  throw new Error("Cannot edit invalid JSONC");
10933
9665
  }
10934
9666
  return root;
10935
9667
  }
10936
9668
  function findNode(text, path) {
10937
- return findNodeAtLocation2(parseDocument(text), path);
9669
+ return findNodeAtLocation(parseDocument(text), path);
10938
9670
  }
10939
9671
  function findComma(text, start, end) {
10940
- const scanner = createScanner2(text, false);
9672
+ const scanner = createScanner(text, false);
10941
9673
  scanner.setPosition(start);
10942
9674
  for (;; ) {
10943
9675
  const kind = scanner.scan();
@@ -10956,7 +9688,7 @@ function findComma(text, start, end) {
10956
9688
  function setJsoncValue(text, path, value) {
10957
9689
  const node = findNode(text, path);
10958
9690
  if (node) {
10959
- if (Object.is(getNodeValue2(node), value))
9691
+ if (Object.is(getNodeValue(node), value))
10960
9692
  return text;
10961
9693
  const serialized = JSON.stringify(value);
10962
9694
  return text.slice(0, node.offset) + serialized + text.slice(node.offset + node.length);
@@ -10967,7 +9699,7 @@ function removeObjectProperty(text, object, key) {
10967
9699
  const properties = object.children ?? [];
10968
9700
  const index = properties.findIndex((property) => {
10969
9701
  const propertyKey = property.children?.[0];
10970
- return propertyKey !== undefined && getNodeValue2(propertyKey) === key;
9702
+ return propertyKey !== undefined && getNodeValue(propertyKey) === key;
10971
9703
  });
10972
9704
  if (index === -1)
10973
9705
  return text;
@@ -11486,10 +10218,13 @@ function loadConfigFileDetailed(configPath, source) {
11486
10218
  rawText = raw.text;
11487
10219
  rawWarnings = raw.warnings;
11488
10220
  } catch (error) {
10221
+ const message = `failed to read config: ${error instanceof Error ? error.message : String(error)}`;
11489
10222
  return {
11490
10223
  config: {},
11491
- warnings: [
11492
- `${configPath}: failed to read config: ${error instanceof Error ? error.message : String(error)}`
10224
+ warnings: [`${configPath}: ${message}`],
10225
+ parseFailures: [],
10226
+ warningDetails: [
10227
+ { warningClass: CONFIG_WARNING_CLASS.FILE_IO, source, path: configPath, message }
11493
10228
  ],
11494
10229
  outcome: "project-file-io-error",
11495
10230
  source
@@ -11502,22 +10237,56 @@ function loadConfigFileDetailed(configPath, source) {
11502
10237
  isProjectConfig: source === "project"
11503
10238
  });
11504
10239
  const rejectedKeyPaths = [];
11505
- const config = parseJsonc(substituted.text, {
10240
+ const parsed = parseJsoncRecovering(substituted.text, {
11506
10241
  onRejectedKey: (path) => rejectedKeyPaths.push(path.join("."))
11507
10242
  });
10243
+ const config = parsed.value && typeof parsed.value === "object" && !Array.isArray(parsed.value) ? parsed.value : {};
11508
10244
  const unsafeKeyWarnings = rejectedKeyPaths.map((path) => `Ignored unsafe config key "${path}" (security: prototype-pollution keys are not allowed).`);
10245
+ const firstIssue = parsed.issues[0];
10246
+ const recovered = firstIssue !== undefined && Object.keys(config).length > 0;
10247
+ const parseFailures = firstIssue ? [
10248
+ {
10249
+ warningClass: CONFIG_WARNING_CLASS.FILE_PARSE,
10250
+ source,
10251
+ path: configPath,
10252
+ line: firstIssue.line,
10253
+ column: firstIssue.column,
10254
+ message: firstIssue.message,
10255
+ recovered,
10256
+ warning: `${configPath}:${firstIssue.line}:${firstIssue.column}: ${firstIssue.message}; ${recovered ? "recovered values were applied, but the file must be fixed." : "using defaults for this file."}`
10257
+ }
10258
+ ] : [];
11509
10259
  return {
11510
10260
  config,
11511
- warnings: [...rawWarnings, ...substituted.warnings, ...unsafeKeyWarnings].map((warning) => `${configPath}: ${warning}`),
11512
- outcome: rejectedKeyPaths.length > 0 ? "schema-recovery" : substituted.warnings.length > 0 ? "substitution-failure" : "ok",
10261
+ warnings: [
10262
+ ...parseFailures.map((failure) => failure.warning),
10263
+ ...rawWarnings.map((warning) => `${configPath}: ${warning}`),
10264
+ ...substituted.warnings.map((warning) => `${configPath}: ${warning}`),
10265
+ ...unsafeKeyWarnings.map((warning) => `${configPath}: ${warning}`)
10266
+ ],
10267
+ parseFailures,
10268
+ warningDetails: parseFailures,
10269
+ outcome: parseFailures.length > 0 ? "project-file-parse-error" : rejectedKeyPaths.length > 0 ? "schema-recovery" : substituted.warnings.length > 0 ? "substitution-failure" : "ok",
11513
10270
  source
11514
10271
  };
11515
10272
  } catch (error) {
10273
+ const message = error instanceof Error ? error.message : String(error);
10274
+ const warning = `${configPath}:1:1: ${message}; using defaults for this file.`;
10275
+ const failure = {
10276
+ warningClass: CONFIG_WARNING_CLASS.FILE_PARSE,
10277
+ source,
10278
+ path: configPath,
10279
+ line: 1,
10280
+ column: 1,
10281
+ message,
10282
+ recovered: false,
10283
+ warning
10284
+ };
11516
10285
  return {
11517
10286
  config: {},
11518
- warnings: [
11519
- `${configPath}: failed to load config: ${error instanceof Error ? error.message : String(error)}`
11520
- ],
10287
+ warnings: [warning],
10288
+ parseFailures: [failure],
10289
+ warningDetails: [failure],
11521
10290
  outcome: "project-file-parse-error",
11522
10291
  source
11523
10292
  };
@@ -11776,11 +10545,13 @@ function loadPluginConfigDetailed(directory) {
11776
10545
  }
11777
10546
  }
11778
10547
  const recoveredTopLevelKeys = [];
10548
+ const cacheTtlConfigured = Object.hasOwn(mergedRaw, "cache_ttl");
11779
10549
  const config = parsePluginConfig(mergedRaw, recoveredTopLevelKeys);
11780
10550
  if (profileResolution.activeProfile)
11781
10551
  config.profile = profileResolution.activeProfile;
11782
10552
  setOutputReserveConfig(config.output_reserve);
11783
10553
  setWindowOverlayPath(config.models?.window_overlay_path);
10554
+ const leafValidationWarnings = [...config.configWarnings ?? []];
11784
10555
  if (config.configWarnings?.length) {
11785
10556
  allWarnings.push(...config.configWarnings.map((w) => {
11786
10557
  if (userLoaded && projectLoaded)
@@ -11806,6 +10577,21 @@ function loadPluginConfigDetailed(directory) {
11806
10577
  ...bindSubstitutionFailures(userLoaded),
11807
10578
  ...bindSubstitutionFailures(projectLoaded)
11808
10579
  ];
10580
+ const configParseFailures = [
10581
+ ...userLoaded?.parseFailures ?? [],
10582
+ ...projectLoaded?.parseFailures ?? []
10583
+ ];
10584
+ const warningDetails = [
10585
+ ...userLoaded?.warningDetails ?? [],
10586
+ ...projectLoaded?.warningDetails ?? [],
10587
+ ...leafValidationWarnings.map((message) => ({
10588
+ warningClass: CONFIG_WARNING_CLASS.INVALID_LEAF,
10589
+ message
10590
+ }))
10591
+ ];
10592
+ config.configParseFailures = configParseFailures;
10593
+ config.configWarningDetails = warningDetails;
10594
+ config.cacheTtlConfigured = cacheTtlConfigured;
11809
10595
  const sources = {
11810
10596
  userConfig: userLoaded?.outcome ?? (legacyUserUnmigrated ? "legacy-config-unmigrated" : "ok"),
11811
10597
  projectConfig: projectLoaded?.outcome ?? (legacyProjectUnmigrated ? "legacy-config-unmigrated" : "ok")
@@ -11816,7 +10602,10 @@ function loadPluginConfigDetailed(directory) {
11816
10602
  loadOutcome: combinedOutcome({ sources, substitutionFailures, recoveredTopLevelKeys }),
11817
10603
  sources,
11818
10604
  substitutionFailures,
11819
- recoveredTopLevelKeys
10605
+ recoveredTopLevelKeys,
10606
+ configParseFailures,
10607
+ warningDetails,
10608
+ cacheTtlConfigured
11820
10609
  };
11821
10610
  }
11822
10611
 
@@ -16035,7 +14824,7 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
16035
14824
  const desc = describeError(failure);
16036
14825
  log(`[dreamer] classify chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
16037
14826
  recordInvocation(args, startedAt, { status: "failed", error: failure });
16038
- if (moduleRoute || signal.aborted || failure instanceof DreamerProviderOutputFailureError)
14827
+ if (moduleRoute || signal.aborted || failure instanceof DreamerProviderOutputFailureError || getPromptFailureDetail(failure)?.failureClass !== "parse_failed" && getPromptFailureDetail(failure) !== null)
16039
14828
  throw failure;
16040
14829
  return { classified: 0, changed: 0 };
16041
14830
  } finally {
@@ -19333,6 +18122,16 @@ function unescapeXml2(value) {
19333
18122
  }
19334
18123
 
19335
18124
  // src/features/magic-context/dreamer/storage-dream-runs.ts
18125
+ function formatDreamRunFailure(failure) {
18126
+ const parts = [failure.failure_class];
18127
+ if (failure.model_attempted)
18128
+ parts.push(`model: ${failure.model_attempted}`);
18129
+ if (failure.provider_error)
18130
+ parts.push(failure.provider_error.split(/\r?\n/, 1)[0].trim());
18131
+ else if (failure.timeout_ms !== null)
18132
+ parts.push(`timeout: ${failure.timeout_ms}ms`);
18133
+ return parts.join(" · ");
18134
+ }
19336
18135
  var insertDreamRunStatements = new WeakMap;
19337
18136
  var getDreamRunsByProjectStatements = new Map;
19338
18137
  function getInsertDreamRunStatement(db) {
@@ -19942,9 +18741,10 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
19942
18741
  } catch (error) {
19943
18742
  const desc = describeError(error);
19944
18743
  const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
18744
+ const promptFailure = getPromptFailureDetail(error);
19945
18745
  log(`[dreamer] verify batch ${providerFailure ? "provider failure" : "failed"}: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
19946
18746
  recordInvocation4(args, startedAt, { status: "failed", error });
19947
- if (error instanceof DreamerModuleFailureError || signal.aborted)
18747
+ if (error instanceof DreamerModuleFailureError || signal.aborted || promptFailure !== null && promptFailure.failureClass !== "parse_failed" && !providerFailure)
19948
18748
  throw error;
19949
18749
  return {
19950
18750
  verified: 0,
@@ -20168,6 +18968,30 @@ function recordInvocation4(args, startedAt, params) {
20168
18968
  }
20169
18969
 
20170
18970
  // src/features/magic-context/dreamer/task-executor.ts
18971
+ function dreamRunFailureDetail(error) {
18972
+ const prompt = getPromptFailureDetail(error);
18973
+ if (prompt) {
18974
+ return {
18975
+ failure_class: prompt.failureClass,
18976
+ model_attempted: prompt.modelAttempted,
18977
+ models_tried: prompt.modelsTried,
18978
+ provider_error: prompt.providerError,
18979
+ timeout_ms: prompt.timeoutMs,
18980
+ child_session_id: prompt.childSessionId
18981
+ };
18982
+ }
18983
+ const described = describeError(error);
18984
+ const message = described.brief;
18985
+ const providerFailure = error instanceof Error && error.name === "DreamerProviderOutputFailureError";
18986
+ return {
18987
+ failure_class: providerFailure ? "provider_error" : /no models?|model chain is empty/i.test(message) ? "no_models" : "unknown",
18988
+ model_attempted: null,
18989
+ models_tried: [],
18990
+ provider_error: providerFailure ? sanitizeDiagnosticText(message).slice(0, 500) : null,
18991
+ timeout_ms: null,
18992
+ child_session_id: null
18993
+ };
18994
+ }
20171
18995
  function classifyFailure(error) {
20172
18996
  const described = describeError(error);
20173
18997
  const brief = described.brief;
@@ -20284,6 +19108,9 @@ function createDreamTaskExecutor(deps) {
20284
19108
  durationMs: Date.now() - startedAt,
20285
19109
  resultChars: 0,
20286
19110
  ...status === "failed" && error ? { error } : {},
19111
+ ...status === "failed" ? {
19112
+ failure: extra?.failure ?? dreamRunFailureDetail(error ?? "unknown dreamer failure")
19113
+ } : {},
20287
19114
  ...extra?.progress ? { progress: extra.progress } : {},
20288
19115
  backlog: (() => {
20289
19116
  const end = extra?.backlogAfter ?? getDreamTaskBacklog(db, projectIdentity, config.task);
@@ -20584,9 +19411,15 @@ function createDreamTaskExecutor(deps) {
20584
19411
  });
20585
19412
  } catch (error) {
20586
19413
  const { transient, brief } = classifyFailure(error);
20587
- recordRun("failed", brief);
19414
+ const failure = dreamRunFailureDetail(error);
19415
+ recordRun("failed", brief, { failure });
20588
19416
  log(`[dreamer] task ${config.task} failed (transient=${transient}): ${brief}`);
20589
- return { status: "failed", transient, error: brief };
19417
+ return {
19418
+ status: "failed",
19419
+ transient,
19420
+ error: brief,
19421
+ failureDetail: formatDreamRunFailure(failure)
19422
+ };
20590
19423
  } finally {
20591
19424
  deps.onProgress?.(null, config.task);
20592
19425
  }
@@ -21123,10 +19956,10 @@ async function runDomainGroup(deps, group, cb) {
21123
19956
  cb?.onRan?.(due.config.task);
21124
19957
  } else if (outcome.transient) {
21125
19958
  recordTransientFailure(db, projectIdentity, due, finishedAt, outcome.error ?? null);
21126
- cb?.onFailed?.(due.config.task, outcome.error);
19959
+ cb?.onFailed?.(due.config.task, outcome.failureDetail ?? outcome.error);
21127
19960
  } else {
21128
19961
  advanceAfterRun(db, projectIdentity, due, finishedAt, "failed", outcome.error ?? null);
21129
- cb?.onFailed?.(due.config.task, outcome.error);
19962
+ cb?.onFailed?.(due.config.task, outcome.failureDetail ?? outcome.error);
21130
19963
  }
21131
19964
  }
21132
19965
  } finally {
@@ -23272,6 +22105,16 @@ function clearSidebarSnapshotCache(sessionId) {
23272
22105
  cache.delete(sessionId);
23273
22106
  }
23274
22107
 
22108
+ // src/shared/cache-ttl-seed.ts
22109
+ function seedSessionCacheTtlIfUnsynced(args) {
22110
+ const meta = getOrCreateSessionMeta2(args.db, args.sessionId);
22111
+ if (meta.lastResponseTime !== 0 || meta.lastObservedModelKey !== null)
22112
+ return false;
22113
+ const cacheTtl = typeof args.configured === "string" ? args.configured : resolveModelConfigValue(args.configured, args.modelKey)?.value ?? args.configured.default ?? "5m";
22114
+ updateSessionMeta2(args.db, args.sessionId, { cacheTtl });
22115
+ return true;
22116
+ }
22117
+
23275
22118
  // src/features/magic-context/literal-probes.ts
23276
22119
  var MAX_PROBES = 5;
23277
22120
  var MIN_PROBE_LENGTH = 3;
@@ -25598,14 +24441,26 @@ var WHOLE_MESSAGE_PLACEHOLDER_TEXT = "[dropped]";
25598
24441
  function modelAcceptsEmptyContent(providerID) {
25599
24442
  return providerID === "anthropic";
25600
24443
  }
24444
+ var VARIANT_CACHE_PRESERVING_MODELS = {
24445
+ "anthropic/claude-fable-5-1": "2026-09-02",
24446
+ "openai/gpt-6-astra": "2026-09-05"
24447
+ };
24448
+ function canonicalVariantModelIdentity(providerID, modelID) {
24449
+ const normalizedProviderID = providerID.toLowerCase();
24450
+ const isAnthropicFamily = normalizedProviderID === "anthropic" || normalizedProviderID === "google-vertex-anthropic" || normalizedProviderID.includes("bedrock");
24451
+ if (isAnthropicFamily && isFable51ThinkingBindingModel("anthropic", modelID)) {
24452
+ return "anthropic/claude-fable-5-1";
24453
+ }
24454
+ return canonicalModelIdentity(`${providerID}/${modelID}`).toLowerCase();
24455
+ }
25601
24456
  function variantChangeBustsProviderCache(providerID, modelID) {
25602
24457
  if (!providerID || !modelID)
25603
24458
  return false;
25604
- const normalizedProviderID = providerID.toLowerCase();
25605
- const isAnthropicFamily = normalizedProviderID === "anthropic" || normalizedProviderID === "google-vertex-anthropic" || normalizedProviderID.includes("bedrock");
25606
- if (!isAnthropicFamily)
24459
+ const identity = canonicalVariantModelIdentity(providerID, modelID);
24460
+ if (Object.hasOwn(VARIANT_CACHE_PRESERVING_MODELS, identity))
25607
24461
  return false;
25608
- return !isFable51ThinkingBindingModel("anthropic", modelID);
24462
+ const normalizedProviderID = providerID.toLowerCase();
24463
+ return normalizedProviderID === "anthropic" || normalizedProviderID === "google-vertex-anthropic" || normalizedProviderID.includes("bedrock");
25609
24464
  }
25610
24465
  function makeSentinel(originalPart) {
25611
24466
  const sentinel = {
@@ -25669,6 +24524,41 @@ function replaySentinelByMessageIds(messages, ids, providerID, hiddenSeamIds = n
25669
24524
  // src/hooks/magic-context/command-handler.ts
25670
24525
  import { randomUUID as randomUUID2 } from "node:crypto";
25671
24526
 
24527
+ // src/shared/cache-ttl-display.ts
24528
+ function resolveCacheTtlDisplay(args) {
24529
+ if (args.sessionModelKey && (!args.modelKey || args.sessionModelKey === args.modelKey) || !args.modelKey && !args.sessionModelKey && args.sessionValue !== "5m") {
24530
+ return {
24531
+ value: args.sessionValue || "5m",
24532
+ source: "session",
24533
+ modelKey: args.modelKey ?? args.sessionModelKey ?? undefined
24534
+ };
24535
+ }
24536
+ if (typeof args.configured === "string") {
24537
+ return {
24538
+ value: args.configured,
24539
+ source: args.configuredExplicitly ? "config" : "default",
24540
+ modelKey: args.modelKey
24541
+ };
24542
+ }
24543
+ const matched = resolveModelConfigValue(args.configured, args.modelKey);
24544
+ if (matched) {
24545
+ return { value: matched.value, source: "config", modelKey: args.modelKey };
24546
+ }
24547
+ return {
24548
+ value: args.configured.default ?? "5m",
24549
+ source: "default",
24550
+ modelKey: args.modelKey
24551
+ };
24552
+ }
24553
+ function formatCacheTtlDisplay(display) {
24554
+ if (display.source === "session")
24555
+ return `Cache TTL: ${display.value} (session)`;
24556
+ if (display.source === "config") {
24557
+ return `Cache TTL: ${display.value} (config for ${display.modelKey ?? "current model"})`;
24558
+ }
24559
+ return `Cache TTL: ${display.value} (default — no cache_ttl for ${display.modelKey ?? "unknown model"})`;
24560
+ }
24561
+
25672
24562
  // src/shared/rust-mode-status.ts
25673
24563
  var RUST_MODE_HOST_PATHS_LINE = "Host backends → MODULE: ctx_memory, ctx_note; historian: module-side";
25674
24564
 
@@ -25694,12 +24584,14 @@ function formatStatusDetailMarkdown(detail) {
25694
24584
  ].filter((value) => value !== undefined);
25695
24585
  const mode = detail.compaction_enabled === false ? "native compaction (Magic Context history compaction disabled)" : "Magic Context compaction";
25696
24586
  const lines = [
24587
+ ...(detail.configParseFailures ?? []).map(formatConfigParseStatusLine),
24588
+ ...(detail.configParseFailures?.length ?? 0) > 0 ? [""] : [],
25697
24589
  "## Magic Context Status",
25698
24590
  "",
25699
24591
  `- **Mode:** ${mode}`,
25700
24592
  `- **Active profile:** ${detail.activeProfile ?? "none"}`,
25701
24593
  `- **Usage:** ${detail.usagePercentage.toFixed(1)}% (${formatCount(detail.inputTokens)} / ${usableLimit})`,
25702
- `- **Cache lane:** ${formatCacheLane(detail)}`,
24594
+ `- **${formatCacheTtlDisplay({ value: detail.cacheTtl, source: detail.cacheTtlSource ?? "session", modelKey: detail.cacheTtlModelKey })}**; ${formatCacheLane(detail)}`,
25703
24595
  `- **Historian:** ${[historianState, ...historianDetails].join("; ")}`,
25704
24596
  ...detail.hostBackendsModuleSide ? [`- ${RUST_MODE_HOST_PATHS_LINE}`] : [],
25705
24597
  `- **Memory:** ${formatCount(detail.memoryCount)} active; ${formatCount(detail.memoryBlockCount)} injected`,
@@ -26128,7 +25020,7 @@ function formatExecuteThreshold(detail, contextLimit) {
26128
25020
  }
26129
25021
  return `${percentage}%${clampNote}`;
26130
25022
  }
26131
- function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer, windowGeometry, tailHygiene, contextUsage, rustMode = false) {
25023
+ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer, windowGeometry, tailHygiene, contextUsage, rustMode = false, display) {
26132
25024
  const thresholdDetail = resolveExecuteThresholdDetail(executeThresholdPercentageConfig, liveModelKey, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, {
26133
25025
  tokensConfig: executeThresholdTokens,
26134
25026
  contextLimit,
@@ -26142,11 +25034,18 @@ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageC
26142
25034
  const activeTags = tags.filter((t) => t.status === "active");
26143
25035
  const droppedTags = tags.filter((t) => t.status === "dropped");
26144
25036
  const totalBytes = activeTags.reduce((sum, t) => sum + t.byteSize, 0);
25037
+ const ttlDisplay = resolveCacheTtlDisplay({
25038
+ configured: display?.cacheTtlConfig ?? "5m",
25039
+ configuredExplicitly: display?.cacheTtlConfigured === true,
25040
+ modelKey: liveModelKey,
25041
+ sessionValue: meta.cacheTtl,
25042
+ sessionModelKey: meta.lastObservedModelKey
25043
+ });
26145
25044
  let ttlMs;
26146
25045
  try {
26147
- ttlMs = parseCacheTtl(meta.cacheTtl);
25046
+ ttlMs = parseCacheTtl(ttlDisplay.value);
26148
25047
  } catch (error) {
26149
- sessionLog(sessionId, `invalid cache_ttl "${meta.cacheTtl}" in ctx-status; falling back to default 5m`, error);
25048
+ sessionLog(sessionId, `invalid cache_ttl "${ttlDisplay.value}" in ctx-status; falling back to default 5m`, error);
26150
25049
  ttlMs = parseCacheTtl("5m");
26151
25050
  }
26152
25051
  const elapsed = Date.now() - meta.lastResponseTime;
@@ -26156,7 +25055,10 @@ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageC
26156
25055
  const displayInputTokens = contextUsage?.inputTokens ?? meta.lastInputTokens;
26157
25056
  const displayPercentage = contextUsage?.percentage ?? meta.lastContextPercentage;
26158
25057
  const displayContextLimit = contextLimit && contextLimit > 0 ? contextLimit : displayPercentage > 0 ? Math.round(displayInputTokens / (displayPercentage / 100)) : 0;
25058
+ const parseFailureLines = (display?.configParseFailures ?? []).map(formatConfigParseStatusLine);
26159
25059
  const lines = [
25060
+ ...parseFailureLines,
25061
+ ...parseFailureLines.length > 0 ? [""] : [],
26160
25062
  "## Magic Status",
26161
25063
  "",
26162
25064
  `**Session:** ${sessionId}`,
@@ -26173,7 +25075,7 @@ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageC
26173
25075
  "",
26174
25076
  ...meta.lastTransformError ? ["### Last Transform Error", `- ${meta.lastTransformError}`, ""] : [],
26175
25077
  "### Cache TTL",
26176
- `- Configured: ${meta.cacheTtl}`,
25078
+ `- ${formatCacheTtlDisplay(ttlDisplay)}`,
26177
25079
  `- Last response: ${meta.lastResponseTime > 0 ? `${Math.round(elapsed / 1000)}s ago` : "never"}`,
26178
25080
  `- Remaining: ${cacheExpired ? "expired" : ttlMs === Number.POSITIVE_INFINITY ? "never (MC never assumes expiry — external cache-keep)" : `${Math.round(remainingMs / 1000)}s`}`,
26179
25081
  `- Queue will auto-execute: ${cacheExpired ? "yes (cache expired)" : ttlMs === Number.POSITIVE_INFINITY ? `when context >= ${executeThresholdPercentage}%` : `when TTL expires or context >= ${executeThresholdPercentage}%`}`,
@@ -26706,7 +25608,11 @@ Rust module status could not be read. Canonical session usage, tags, and compart
26706
25608
  const statusOutput = executeStatus(deps.db, sessionId, deps.protectedTags, deps.executeThresholdPercentage, liveModelKey, deps.historyBudgetPercentage, deps.commitClusterTrigger, deps.executeThresholdTokens, liveContextLimit, deps.dreamer ? {
26707
25609
  backlog: readDreamTaskBacklogsSafely(deps.db, deps.dreamer.projectPath, CANONICAL_DREAM_TASKS),
26708
25610
  progress: deps.getDreamerProgress?.() ?? null
26709
- } : undefined, windowGeometry, tailHygiene, undefined, Boolean(rustMode));
25611
+ } : undefined, windowGeometry, tailHygiene, undefined, Boolean(rustMode), {
25612
+ cacheTtlConfig: deps.cacheTtlConfig ?? "5m",
25613
+ cacheTtlConfigured: deps.cacheTtlConfigured === true,
25614
+ configParseFailures: deps.configParseFailures ?? []
25615
+ });
26710
25616
  const moduleStatus = rustStatus ? `
26711
25617
 
26712
25618
  ${formatRustStatusText(rustStatus)}` : "";
@@ -26956,6 +25862,14 @@ function createChatMessageHook(args) {
26956
25862
  providerID: input.model.providerID,
26957
25863
  modelID: input.model.modelID
26958
25864
  });
25865
+ if (args.cacheTtlConfig) {
25866
+ seedSessionCacheTtlIfUnsynced({
25867
+ db: args.db,
25868
+ sessionId,
25869
+ configured: args.cacheTtlConfig,
25870
+ modelKey: `${input.model.providerID}/${input.model.modelID}`
25871
+ });
25872
+ }
26959
25873
  }
26960
25874
  const previousVariant = args.variantBySession.get(sessionId);
26961
25875
  args.variantBySession.set(sessionId, input.variant);
@@ -27784,6 +26698,8 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
27784
26698
  cacheTtlMs: 0,
27785
26699
  cacheRemainingMs: 0,
27786
26700
  cacheExpired: false,
26701
+ cacheTtlSource: "default",
26702
+ configParseFailures: [],
27787
26703
  cacheNeverExpires: false,
27788
26704
  executeThreshold: 65,
27789
26705
  executeThresholdMode: "percentage",
@@ -27813,6 +26729,8 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
27813
26729
  ageMs: row ? Math.max(0, Date.now() - row.renderedAt) : null
27814
26730
  };
27815
26731
  }
26732
+ let persistedCacheTtl = "5m";
26733
+ let persistedModelKey = null;
27816
26734
  const meta = db.prepare("SELECT * FROM session_meta WHERE session_id = ?").get(sessionId);
27817
26735
  if (meta) {
27818
26736
  detail.tagCounter = Number(meta.counter ?? 0);
@@ -27820,6 +26738,8 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
27820
26738
  detail.lastNudgeTokens = Number(meta.last_nudge_tokens ?? 0);
27821
26739
  detail.lastTransformError = meta.last_transform_error ? String(meta.last_transform_error) : null;
27822
26740
  detail.isSubagent = Boolean(meta.is_subagent);
26741
+ persistedCacheTtl = typeof meta.cache_ttl === "string" && meta.cache_ttl.length > 0 ? meta.cache_ttl : "5m";
26742
+ persistedModelKey = typeof meta.last_observed_model_key === "string" && meta.last_observed_model_key.length > 0 ? meta.last_observed_model_key : null;
27823
26743
  }
27824
26744
  try {
27825
26745
  const activeRow = db.prepare("SELECT COUNT(*) as count, COALESCE(SUM(byte_size), 0) as bytes FROM tags WHERE session_id = ? AND status = 'active'").get(sessionId);
@@ -27856,8 +26776,17 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
27856
26776
  if (thresholdDetail.absoluteTokens !== undefined) {
27857
26777
  detail.executeThresholdTokens = thresholdDetail.absoluteTokens;
27858
26778
  }
27859
- const ct = resolveConfigValue(config, "cache_ttl", modelKey, "5m");
27860
- detail.cacheTtl = ct;
26779
+ const ttlDisplay = resolveCacheTtlDisplay({
26780
+ configured: config.cache_ttl ?? "5m",
26781
+ configuredExplicitly: config.cacheTtlConfigured === true,
26782
+ modelKey,
26783
+ sessionValue: persistedCacheTtl,
26784
+ sessionModelKey: persistedModelKey
26785
+ });
26786
+ detail.cacheTtl = ttlDisplay.value;
26787
+ detail.cacheTtlSource = ttlDisplay.source;
26788
+ detail.cacheTtlModelKey = ttlDisplay.modelKey;
26789
+ detail.configParseFailures = Array.isArray(config.configParseFailures) ? config.configParseFailures : [];
27861
26790
  if (typeof config.protected_tags === "number") {
27862
26791
  detail.protectedTagCount = config.protected_tags;
27863
26792
  }
@@ -27998,7 +26927,7 @@ function registerRpcHandlers(rpcServer, args) {
27998
26927
  return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
27999
26928
  });
28000
26929
  const buildManagedCtx = async (db) => {
28001
- const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await import("./derive-budgets-901a0pk0.js");
26930
+ const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await import("./derive-budgets-bc366cz8.js");
28002
26931
  const { resolveHistorianModel } = await import("./model-resolution-dxatzjde.js");
28003
26932
  const { userMemoryCollectionEnabled } = await import("./task-config-hnv93r7p.js");
28004
26933
  const DEFAULT_HISTORIAN_TIMEOUT_MS = 600000;
@@ -28031,7 +26960,7 @@ function registerRpcHandlers(rpcServer, args) {
28031
26960
  const db = getDb();
28032
26961
  if (!db)
28033
26962
  return { ok: false, error: "db unavailable" };
28034
- const { runManagedRecomp } = await import("./recomp-orchestrator-f5m2wk74.js");
26963
+ const { runManagedRecomp } = await import("./recomp-orchestrator-q98r6rga.js");
28035
26964
  const { sendIgnoredMessage } = await import("./send-session-notification-hdh02wy9.js");
28036
26965
  log(`[rpc] recomp requested for session ${sessionId}`);
28037
26966
  const ctx = await buildManagedCtx(db);
@@ -28050,7 +26979,7 @@ function registerRpcHandlers(rpcServer, args) {
28050
26979
  const db = getDb();
28051
26980
  if (!db)
28052
26981
  return { ok: false, error: "db unavailable" };
28053
- const { runManagedUpgrade } = await import("./recomp-orchestrator-f5m2wk74.js");
26982
+ const { runManagedUpgrade } = await import("./recomp-orchestrator-q98r6rga.js");
28054
26983
  const { sendIgnoredMessage } = await import("./send-session-notification-hdh02wy9.js");
28055
26984
  log(`[rpc] session-upgrade requested for session ${sessionId}`);
28056
26985
  const ctx = await buildManagedCtx(db);
@@ -28067,7 +26996,7 @@ function registerRpcHandlers(rpcServer, args) {
28067
26996
  if (!db)
28068
26997
  return { ok: false, error: "db unavailable" };
28069
26998
  try {
28070
- const { updateSessionMeta } = await import("./storage-meta-session-3rxx9ekm.js");
26999
+ const { updateSessionMeta } = await import("./storage-meta-session-dvwfw778.js");
28071
27000
  updateSessionMeta(db, sessionId, { upgradeRemindedAt: Date.now() });
28072
27001
  return { ok: true };
28073
27002
  } catch (error) {
@@ -32133,6 +31062,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
32133
31062
  protectedTags: config.protectedTags,
32134
31063
  currentTotalInputTokens: emergency.currentTotalInputTokens,
32135
31064
  ceilingTokens: emergency.ceilingTokens,
31065
+ usagePercentage: emergency.usagePercentage,
32136
31066
  priorInputSample,
32137
31067
  hasPriorDrop: priorInputSample > 0
32138
31068
  });
@@ -32146,11 +31076,13 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
32146
31076
  if (tag.status !== "active" || tag.type !== "tool")
32147
31077
  continue;
32148
31078
  const target = targets.get(tag.tagNumber);
32149
- const recent = newestEmergencyTags.has(tag.tagNumber);
32150
- const result = recent ? target?.truncate?.() ?? target?.drop?.() ?? "absent" : target?.drop?.() ?? "absent";
31079
+ const recent = (emergency.usagePercentage ?? 0) < 95 && newestEmergencyTags.has(tag.tagNumber);
31080
+ const reasoningSafeSkeleton = target?.requiresToolArcSkeleton === true;
31081
+ const skeleton = recent || reasoningSafeSkeleton;
31082
+ const result = reasoningSafeSkeleton ? target?.truncate?.() ?? "absent" : recent ? target?.truncate?.() ?? target?.drop?.() ?? "absent" : target?.drop?.() ?? "absent";
32151
31083
  if (result === "removed" || result === "truncated") {
32152
31084
  updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
32153
- updateTagDropMode(db, sessionId, tag.tagNumber, recent ? "truncated" : "full");
31085
+ updateTagDropMode(db, sessionId, tag.tagNumber, skeleton ? "truncated" : "full");
32154
31086
  droppedTools++;
32155
31087
  emergencyDroppedTools++;
32156
31088
  emergencyReclaimedTokens += estimateEmergencyDropReclaimTokens(tag);
@@ -32161,7 +31093,9 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
32161
31093
  } else {
32162
31094
  sessionLog(sessionId, `emergency tiered drop skipped: ${plan.reason}`);
32163
31095
  }
32164
- setEmergencyDropSample(db, sessionId, emergency.currentTotalInputTokens);
31096
+ if (emergencyDroppedTools > 0) {
31097
+ setEmergencyDropSample(db, sessionId, emergency.currentTotalInputTokens);
31098
+ }
32165
31099
  }
32166
31100
  if (config.routine !== false) {
32167
31101
  db.transaction(() => {
@@ -33781,7 +32715,8 @@ async function runPostTransformPhase(args) {
33781
32715
  protectedTags: args.protectedTags,
33782
32716
  emergency: emergencyDropEligible && args.emergencyCeilingTokens !== undefined && args.emergencyCeilingTokens > 0 ? {
33783
32717
  currentTotalInputTokens: args.contextUsage.inputTokens,
33784
- ceilingTokens: args.emergencyCeilingTokens
32718
+ ceilingTokens: args.emergencyCeilingTokens,
32719
+ usagePercentage: args.contextUsage.percentage
33785
32720
  } : undefined,
33786
32721
  routine: routineCleanupApplied,
33787
32722
  caveman: cavemanConfig
@@ -34506,11 +33441,21 @@ class MemoryAuthorityUnavailableError extends Error {
34506
33441
  this.name = "MemoryAuthorityUnavailableError";
34507
33442
  }
34508
33443
  }
33444
+
33445
+ class RustTransformProtocolError extends Error {
33446
+ code = "rust_transform_protocol_error";
33447
+ constructor(message) {
33448
+ super(message);
33449
+ this.name = "RustTransformProtocolError";
33450
+ }
33451
+ }
34509
33452
  var RUST_FAILURE_PARK_THRESHOLD = 3;
34510
33453
  var RUST_PARK_RETRY_INTERVAL = 5;
34511
33454
  var RUST_EMERGENCY_WALL_PCT = 95;
34512
33455
  var RUST_PARK_PROBE_PRESSURE_BYPASS_PCT = 90;
34513
33456
  var RUST_SEND_TIMEOUT_MS = 15000;
33457
+ var RUST_LKG_FROZEN_HEALTHY_PASS_LIMIT = 8;
33458
+ var RUST_LKG_FROZEN_RAW_TAIL_GROWTH_LIMIT = 16;
34514
33459
  function activeAgentFromMessages(messages) {
34515
33460
  for (let index = messages.length - 1;index >= 0; index -= 1) {
34516
33461
  const info = messages[index]?.info;
@@ -34924,7 +33869,9 @@ function ensureState(states, sessionId) {
34924
33869
  lkgCaptureSequence: 0,
34925
33870
  lkgLastCapturedRowVersion: 0,
34926
33871
  lkgSyncCaptureRequired: false,
34927
- lkgRepresentationFrozen: false
33872
+ lkgRepresentationFrozen: false,
33873
+ lkgFrozenHealthyPasses: 0,
33874
+ lkgFrozenAtInputCount: null
34928
33875
  };
34929
33876
  states.set(sessionId, state);
34930
33877
  }
@@ -35278,6 +34225,7 @@ function buildTransformBody(args) {
35278
34225
  render_config: [
35279
34226
  args.providerId ? `provider:${args.providerId}` : "",
35280
34227
  args.modelKey ? `model:${args.modelKey}` : "",
34228
+ args.variant ? `variant:${args.variant}` : "",
35281
34229
  args.systemPromptHash ? `system:${args.systemPromptHash}` : ""
35282
34230
  ].filter(Boolean).join("|"),
35283
34231
  system_prompt_hash: args.systemPromptHash,
@@ -35491,7 +34439,7 @@ function createRustModeTransform(deps, options) {
35491
34439
  captureSequence: state.lkgCaptureSequence
35492
34440
  };
35493
34441
  };
35494
- const commitRustCapture = (state, plan) => {
34442
+ const commitRustCapture = (state, plan, requireDurable = false) => {
35495
34443
  if (states.get(plan.sessionId) !== state || plan.captureSequence !== state.lkgCaptureSequence || plan.rowVersion < state.lkgLastCapturedRowVersion) {
35496
34444
  return "superseded";
35497
34445
  }
@@ -35521,7 +34469,10 @@ function createRustModeTransform(deps, options) {
35521
34469
  const captured = captureSlot(plan.sessionId, slot);
35522
34470
  if (!captured)
35523
34471
  throw new Error("LKG slot rejected the prepared snapshot");
35524
- saveLkgSlotToDb(deps.db, plan.sessionId, slot);
34472
+ const persisted = saveLkgSlotToDb(deps.db, plan.sessionId, slot);
34473
+ if (requireDurable && !persisted) {
34474
+ throw new Error("priced LKG snapshot did not reach durable storage");
34475
+ }
35525
34476
  state.lkgLastCapturedRowVersion = plan.rowVersion;
35526
34477
  state.lkgSyncCaptureRequired = false;
35527
34478
  return "captured";
@@ -35570,7 +34521,7 @@ function createRustModeTransform(deps, options) {
35570
34521
  preflightError = error;
35571
34522
  }
35572
34523
  }
35573
- const modelKey = model ? piModelRefToCanonical(resolveModelKey(model.providerID, model.modelID) ?? "") : null;
34524
+ const modelKey = model ? canonicalModelIdentity(resolveModelKey(model.providerID, model.modelID) ?? "") : null;
35574
34525
  let resolvedContextLimit;
35575
34526
  let resolvedWindowGeometry;
35576
34527
  if (model) {
@@ -35594,7 +34545,7 @@ function createRustModeTransform(deps, options) {
35594
34545
  const hasTrustedEmergencyWall = transformGeometry ? transformGeometry.usable_hard > 0 : resolvedContextLimit !== undefined && resolvedContextLimit > 0;
35595
34546
  emergencyFailClosed = isProviderOverflowFailClosedProven(sessionId) || hardWallUsagePercentage(passUsageSnapshot, transformGeometry) >= RUST_EMERGENCY_WALL_PCT && hasTrustedEmergencyWall;
35596
34547
  if (overflowState) {
35597
- const detectedLimitMatchesModel = overflowState.detectedContextLimitModelKey === null || piModelRefToCanonical(overflowState.detectedContextLimitModelKey) === piModelRefToCanonical(modelKey ?? "");
34548
+ const detectedLimitMatchesModel = overflowState.detectedContextLimitModelKey === null || canonicalModelIdentity(overflowState.detectedContextLimitModelKey) === canonicalModelIdentity(modelKey ?? "");
35598
34549
  const hasProviderProof = overflowState.detectedContextLimit > 0 && detectedLimitMatchesModel || isProviderOverflowReconfirmed(sessionId);
35599
34550
  emergencyFailClosed ||= overflowState.needsEmergencyRecovery && overflowState.emergencyRecoveryOrigin === "provider_overflow" && hasProviderProof;
35600
34551
  }
@@ -35992,6 +34943,7 @@ function createRustModeTransform(deps, options) {
35992
34943
  geometry: transformGeometry,
35993
34944
  modelKey: modelKey ?? null,
35994
34945
  providerId: model?.providerID ?? null,
34946
+ variant: deps.variantBySession?.get(sessionId),
35995
34947
  systemPromptHash: sessionMeta.systemPromptHash ?? "",
35996
34948
  upgradeState: String(passInputs.upgrade_state ?? ""),
35997
34949
  midTurn,
@@ -36079,6 +35031,32 @@ function createRustModeTransform(deps, options) {
36079
35031
  if (needFullSync || nativeContentOmitted) {
36080
35032
  if (needFullSync) {
36081
35033
  options.moduleClient.invalidateStateSyncCapabilities?.();
35034
+ const recoveryCachedCapabilities = options.moduleClient.getCachedStateSyncCapabilities;
35035
+ const recoveryStateSyncCapabilities = options.moduleClient.stateSyncCapabilities;
35036
+ const recoverySyncStartedAt = performance.now();
35037
+ try {
35038
+ const recoverySync = await syncModuleState({
35039
+ client: {
35040
+ call: callModule,
35041
+ getCachedStateSyncCapabilities: recoveryCachedCapabilities ? () => recoveryCachedCapabilities.call(options.moduleClient) : undefined,
35042
+ stateSyncCapabilities: recoveryStateSyncCapabilities ? (capabilityArgs) => recoveryStateSyncCapabilities.call(options.moduleClient, capabilityArgs) : undefined
35043
+ },
35044
+ state,
35045
+ pass: syncPass,
35046
+ projectRoot,
35047
+ force: true,
35048
+ options: {
35049
+ authority: true,
35050
+ authorityState: state.memoryAuthorityReady ? "MODULE" : undefined,
35051
+ authoritySeqAdoption
35052
+ }
35053
+ });
35054
+ stateSyncRetryBusy = recoverySync.status === "retry_busy";
35055
+ } catch (error) {
35056
+ sessionLog(sessionId, "restart state reconciliation failed; continuing with full transform retry:", error);
35057
+ } finally {
35058
+ logStage(sessionId, "stateSync", recoverySyncStartedAt, timings, "retry=full reason=need_full_sync");
35059
+ }
36082
35060
  } else {
36083
35061
  sessionLog(sessionId, "native_delta_fallback_reason=adapter_response_omitted_native_content retry=full");
36084
35062
  }
@@ -36188,20 +35166,35 @@ function createRustModeTransform(deps, options) {
36188
35166
  });
36189
35167
  }
36190
35168
  };
36191
- const explicitDecision = typeof response.decision === "string" || typeof response.action === "string" || typeof response.cache_bust === "boolean";
36192
- const decisionUpper = decision.toUpperCase();
36193
- const cacheBustingPass = response.cache_bust === true || decisionUpper === "HARD" || decisionUpper === "MIGRATE_HARD" || decisionUpper === "EXECUTE" || decisionUpper === "SOFT" || !explicitDecision;
35169
+ const explicitDecision = typeof response.decision === "string" && response.decision.length > 0 ? response.decision : typeof response.action === "string" && response.action.length > 0 ? response.action : undefined;
35170
+ if (!explicitDecision) {
35171
+ throw new RustTransformProtocolError("rust transform wire invariant failed: response omitted decision and action");
35172
+ }
35173
+ const decisionUpper = explicitDecision.toUpperCase();
35174
+ let cacheBustingPass = decisionUpper === "HARD" || decisionUpper === "MIGRATE_HARD" || decisionUpper === "EXECUTE" || decisionUpper === "SOFT";
35175
+ const deferredFirstDivergence = isRecord4(response.first_divergence) ? response.first_divergence : undefined;
35176
+ const deferredFrozenPrefixDivergence = !cacheBustingPass && [deferredFirstDivergence?.block_id_old, deferredFirstDivergence?.block_id_new].some((blockId) => blockId === "mc_m0#0" || blockId === "mc_m1#0");
35177
+ if (deferredFrozenPrefixDivergence) {
35178
+ state.lkgRepresentationFrozen = true;
35179
+ state.forceFullWire = true;
35180
+ sessionLog(sessionId, "deferred frozen-prefix divergence; replaying LKG");
35181
+ }
36194
35182
  const materializedBoundary = materializedCompactionBoundary(response);
36195
- let appliedMessages;
36196
35183
  let thinkingBindingRecovery = null;
35184
+ let frozenHealthyPassesAfterApply = null;
35185
+ let frozenReleaseReason = null;
36197
35186
  const applyStartedAt = performance.now();
36198
35187
  try {
36199
35188
  const moduleMessages = applyNativeMessagesVerbatim({ messages: [] }, response, previousWireCache?.nativeOutput ? {
36200
35189
  messages: previousWireCache.nativeOutput,
36201
35190
  fingerprint: previousWireCache.fingerprint
36202
35191
  } : undefined);
35192
+ let appliedMessages = moduleMessages;
36203
35193
  let replayedFrozenRepresentation = false;
36204
35194
  if (state.lkgRepresentationFrozen && !cacheBustingPass) {
35195
+ if (state.lkgFrozenAtInputCount === null) {
35196
+ state.lkgFrozenAtInputCount = inputCount;
35197
+ }
36205
35198
  const keys = resolveLkgModelKeys(messages);
36206
35199
  const frozen = replayLkg({
36207
35200
  sessionId,
@@ -36210,16 +35203,27 @@ function createRustModeTransform(deps, options) {
36210
35203
  providerKey: keys.providerKey
36211
35204
  });
36212
35205
  if (!frozen.ok) {
36213
- throw new Error(`frozen LKG representation cannot replay on a defer pass: ${frozen.reason}`);
35206
+ cacheBustingPass = true;
35207
+ frozenReleaseReason = frozen.reason;
35208
+ } else {
35209
+ frozenHealthyPassesAfterApply = state.lkgFrozenHealthyPasses + 1;
35210
+ const rawTailGrowth = Math.max(0, inputCount - state.lkgFrozenAtInputCount);
35211
+ const releaseReason = rawTailGrowth >= RUST_LKG_FROZEN_RAW_TAIL_GROWTH_LIMIT ? "raw_tail_growth_limit" : frozenHealthyPassesAfterApply >= RUST_LKG_FROZEN_HEALTHY_PASS_LIMIT ? "healthy_pass_limit" : null;
35212
+ if (releaseReason) {
35213
+ cacheBustingPass = true;
35214
+ frozenReleaseReason = releaseReason;
35215
+ } else {
35216
+ appliedMessages = frozen.messages;
35217
+ replayedFrozenRepresentation = true;
35218
+ servedFrom = "lkg_frozen";
35219
+ sessionLog(sessionId, "lkg_frozen_replay_served");
35220
+ }
36214
35221
  }
36215
- appliedMessages = frozen.messages;
36216
- replayedFrozenRepresentation = true;
36217
- servedFrom = "lkg_frozen";
36218
- sessionLog(sessionId, "lkg_frozen_replay_served");
36219
- } else {
36220
- appliedMessages = moduleMessages;
36221
35222
  }
36222
- pendingWireCache.nativeOutput = appliedMessages;
35223
+ if (!replayedFrozenRepresentation) {
35224
+ appliedMessages = structuredClone(moduleMessages);
35225
+ }
35226
+ pendingWireCache.nativeOutput = moduleMessages;
36223
35227
  if (!replayedFrozenRepresentation) {
36224
35228
  const postprocess = runRustModePostprocess({
36225
35229
  db: deps.db,
@@ -36287,13 +35291,18 @@ function createRustModeTransform(deps, options) {
36287
35291
  };
36288
35292
  if (!capturePlan) {
36289
35293
  captureMode = "declined";
36290
- captureFailed("async", new Error("LKG snapshot preparation was rejected"));
36291
- } else if (state.lkgSyncCaptureRequired) {
36292
- captureMode = "sync_recovery";
35294
+ const error = new Error("LKG snapshot preparation was rejected");
35295
+ captureFailed("async", error);
35296
+ if (cacheBustingPass)
35297
+ throw error;
35298
+ } else if (cacheBustingPass || state.lkgSyncCaptureRequired) {
35299
+ captureMode = cacheBustingPass ? "sync_priced" : "sync_recovery";
36293
35300
  try {
36294
- commitRustCapture(state, capturePlan);
35301
+ commitRustCapture(state, capturePlan, cacheBustingPass);
36295
35302
  } catch (error) {
36296
35303
  captureFailed("sync", error);
35304
+ if (cacheBustingPass)
35305
+ throw error;
36297
35306
  }
36298
35307
  } else {
36299
35308
  try {
@@ -36322,7 +35331,14 @@ function createRustModeTransform(deps, options) {
36322
35331
  throw error;
36323
35332
  }
36324
35333
  if (cacheBustingPass) {
35334
+ if (frozenReleaseReason) {
35335
+ sessionLog(sessionId, `lkg_frozen_replay_released reason=${frozenReleaseReason}`);
35336
+ }
36325
35337
  state.lkgRepresentationFrozen = false;
35338
+ state.lkgFrozenHealthyPasses = 0;
35339
+ state.lkgFrozenAtInputCount = null;
35340
+ } else if (frozenHealthyPassesAfterApply !== null) {
35341
+ state.lkgFrozenHealthyPasses = frozenHealthyPassesAfterApply;
36326
35342
  }
36327
35343
  try {
36328
35344
  mirrorRustRenderedMemoryIds({ db: deps.db, sessionId, response });
@@ -36435,9 +35451,18 @@ function createRustModeTransform(deps, options) {
36435
35451
  });
36436
35452
  }
36437
35453
  const replayed = replayLastGood(sessionId, messages, output, sessionMeta.systemPromptTokens);
36438
- state.lkgRepresentationFrozen = replayed;
36439
- if (replayed)
35454
+ if (replayed) {
35455
+ if (!state.lkgRepresentationFrozen) {
35456
+ state.lkgFrozenAtInputCount = inputCount;
35457
+ }
35458
+ state.lkgRepresentationFrozen = true;
35459
+ state.lkgFrozenHealthyPasses = 0;
36440
35460
  state.forceFullWire = true;
35461
+ } else {
35462
+ state.lkgRepresentationFrozen = false;
35463
+ state.lkgFrozenHealthyPasses = 0;
35464
+ state.lkgFrozenAtInputCount = null;
35465
+ }
36441
35466
  servedFrom = replayed ? "lkg" : "raw";
36442
35467
  if (decision.toLowerCase() !== "need_full_sync")
36443
35468
  decision = "error";
@@ -36615,6 +35640,8 @@ async function runCompartmentPhaseImpl(args) {
36615
35640
  historyBudgetTokens: args.historyBudgetTokens,
36616
35641
  historianTimeoutMs: args.historianTimeoutMs,
36617
35642
  model: args.historianModel,
35643
+ historianContextLimit: args.historianContextLimit,
35644
+ historianMaxOutputTokens: args.historianMaxOutputTokens,
36618
35645
  fallbackModels: args.fallbackModels,
36619
35646
  directory: args.compartmentDirectory,
36620
35647
  fallbackModelId: args.fallbackModelId,
@@ -36645,6 +35672,8 @@ async function runCompartmentPhaseImpl(args) {
36645
35672
  historyBudgetTokens: args.historyBudgetTokens,
36646
35673
  historianTimeoutMs: args.historianTimeoutMs,
36647
35674
  model: args.historianModel,
35675
+ historianContextLimit: args.historianContextLimit,
35676
+ historianMaxOutputTokens: args.historianMaxOutputTokens,
36648
35677
  fallbackModels: args.fallbackModels,
36649
35678
  directory: args.compartmentDirectory,
36650
35679
  fallbackModelId: args.fallbackModelId,
@@ -37454,6 +36483,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
37454
36483
  historyBudgetTokens,
37455
36484
  historianTimeoutMs: deps.historianTimeoutMs,
37456
36485
  historianModel: deps.historianModel,
36486
+ historianContextLimit: deps.historianContextLimit,
36487
+ historianMaxOutputTokens: deps.historianMaxOutputTokens,
37457
36488
  fallbackModels: deps.fallbackModels,
37458
36489
  compartmentDirectory,
37459
36490
  messages,
@@ -38527,7 +37558,7 @@ ${message}`;
38527
37558
  totalMessages: Math.max(0, plan.targetEligibleEndOrdinal - 1),
38528
37559
  passCount: chunkIndex - 1,
38529
37560
  compartmentsCreated: Math.max(0, getCompartments(ctx.db, sessionId).length - startCompartmentCount),
38530
- note: `Chunk ${chunkIndex}/${expectedChunks}: messages ${plan.snapshot.offset}-${plan.snapshot.eligibleEndOrdinal - 1}…`
37561
+ note: `Chunk ${chunkIndex}/${expectedChunks}: messages ${plan.snapshot.offset}-${plan.snapshot.eligibleEndOrdinal - 1}… ${describeBoundaryDiagnostics(plan.snapshot)}`
38531
37562
  });
38532
37563
  if (!renewWrapupMarker({
38533
37564
  lastCompartmentEnd: lastEnd,
@@ -39131,6 +38162,8 @@ function createMagicContextHook(deps) {
39131
38162
  const resolveHistorianAttempts = () => resolveHistorianModel2(deps.config, "opencode");
39132
38163
  const getHistorianChunkTokens = () => deriveHistorianChunkTokens2(resolveHistorianContextLimit2(resolveHistorianAttempts().primary?.model));
39133
38164
  const historianModel = resolveHistorianAttempts().primary;
38165
+ const historianContextLimit = resolveKnownHistorianContextLimit2(historianModel?.model);
38166
+ const historianMaxOutputTokens = deps.config.historian?.maxTokens ?? 32000;
39134
38167
  const historianFallbackModels = resolveHistorianAttempts().fallbacks;
39135
38168
  const historyRefreshSessions = deps.liveSessionState?.historyRefreshSessions ?? new Set;
39136
38169
  const deferredHistoryRefreshSessions = deps.liveSessionState?.deferredHistoryRefreshSessions ?? new Set;
@@ -39210,6 +38243,8 @@ function createMagicContextHook(deps) {
39210
38243
  memoryEnabled: deps.config.memory?.enabled ?? true,
39211
38244
  autoPromote: deps.config.memory?.auto_promote ?? true,
39212
38245
  historianModel,
38246
+ historianContextLimit,
38247
+ historianMaxOutputTokens,
39213
38248
  fallbackModels: historianFallbackModels,
39214
38249
  language: deps.config.language,
39215
38250
  fallbackModelId: (() => {
@@ -39635,6 +38670,7 @@ function createMagicContextHook(deps) {
39635
38670
  deferredHistoryRefreshSessions,
39636
38671
  pendingMaterializationSessions,
39637
38672
  deferredMaterializationSessions,
38673
+ variantBySession,
39638
38674
  lastHeuristicsTurnId,
39639
38675
  commitSeenLastPass,
39640
38676
  internalChildSessions,
@@ -39654,6 +38690,8 @@ function createMagicContextHook(deps) {
39654
38690
  executeThresholdTokens: deps.config.execute_threshold_tokens,
39655
38691
  historianTimeoutMs: deps.config.historian_timeout_ms ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
39656
38692
  historianModel,
38693
+ historianContextLimit,
38694
+ historianMaxOutputTokens,
39657
38695
  fallbackModels: historianFallbackModels,
39658
38696
  getNotificationParams: (sessionId) => getLiveNotificationParams(sessionId, liveModelBySession, variantBySession, agentBySession, deps.config.toast_duration_ms),
39659
38697
  getModelKey: (sessionId) => {
@@ -39807,6 +38845,9 @@ function createMagicContextHook(deps) {
39807
38845
  rustModeModuleClient,
39808
38846
  projectRoot: deps.directory,
39809
38847
  commitClusterTrigger: deps.config.commit_cluster_trigger,
38848
+ cacheTtlConfig: deps.config.cache_ttl,
38849
+ cacheTtlConfigured: deps.config.cacheTtlConfigured === true,
38850
+ configParseFailures: deps.config.configParseFailures ?? [],
39810
38851
  getLiveModelKey: (sessionId) => {
39811
38852
  const model = resolveLiveModel(sessionId);
39812
38853
  return model ? `${model.providerID}/${model.modelID}` : undefined;
@@ -39937,6 +38978,7 @@ function createMagicContextHook(deps) {
39937
38978
  pendingMaterializationSessions,
39938
38979
  lastHeuristicsTurnId,
39939
38980
  commandHandler,
38981
+ cacheTtlConfig: deps.config.cache_ttl,
39940
38982
  upgradeReminder: historianRunnable ? (sessionId) => maybeSendUpgradeReminder({
39941
38983
  client: deps.client,
39942
38984
  db,
@@ -42579,6 +41621,24 @@ function createToolRegistry(args) {
42579
41621
  return surfacedTools;
42580
41622
  }
42581
41623
 
41624
+ // src/shared/config-warning-surface.ts
41625
+ function buildOpenCodeConfigWarningBanner(warnings, parseFailures, allParseFailures = parseFailures) {
41626
+ const parseWarningStrings = new Set(allParseFailures.map((failure) => failure.warning));
41627
+ const ordinaryWarnings = warnings.filter((warning) => ![...parseWarningStrings].some((parseWarning) => warning.includes(parseWarning)));
41628
+ const entries = [
41629
+ ...parseFailures.map((failure) => `- **TOP SEVERITY:** ${formatConfigParseStatusLine(failure)} — ${failure.message}`),
41630
+ ...ordinaryWarnings.map((warning) => `- ${warning}`)
41631
+ ];
41632
+ return [
41633
+ "## ⚠️ Magic Context Config Warning",
41634
+ "",
41635
+ ...entries,
41636
+ "",
41637
+ "Fix the reported `magic-context.jsonc` file; Magic Context remains enabled."
41638
+ ].join(`
41639
+ `);
41640
+ }
41641
+
42582
41642
  // src/shared/exit-abort-registry.ts
42583
41643
  var controllers = new Set;
42584
41644
  var listenerRegistered = false;
@@ -42921,28 +41981,23 @@ var server = async (ctx) => {
42921
41981
  for (const w of pluginConfig.configWarnings) {
42922
41982
  log(`[magic-context] config warning: ${w}`);
42923
41983
  }
42924
- const warningText = [
42925
- "## ⚠️ Magic Context Config Warning",
42926
- "",
42927
- "Some configuration values are invalid and were replaced with defaults:",
42928
- "",
42929
- ...pluginConfig.configWarnings.map((w) => `- ${w}`),
42930
- "",
42931
- "Check your `magic-context.jsonc` to fix these values."
42932
- ].join(`
42933
- `);
42934
- setTimeout(async () => {
42935
- try {
42936
- const { sendIgnoredMessage } = await import("./send-session-notification-hdh02wy9.js");
42937
- const clientWithSessions = ctx.client;
42938
- const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
42939
- const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
42940
- const sessionId = sessionList?.[0]?.id;
42941
- if (sessionId) {
42942
- await sendIgnoredMessage(ctx.client, sessionId, warningText, {});
42943
- }
42944
- } catch {}
42945
- }, 3000);
41984
+ const allParseFailures = loadedPluginConfig.configParseFailures;
41985
+ const parseFailuresToShow = claimConfigParseFailuresOnce("opencode", allParseFailures);
41986
+ const warningText = buildOpenCodeConfigWarningBanner(pluginConfig.configWarnings, parseFailuresToShow, allParseFailures);
41987
+ const hasBannerEntries = parseFailuresToShow.length > 0 || pluginConfig.configWarnings.some((warning) => !allParseFailures.some((failure) => warning.includes(failure.warning)));
41988
+ if (hasBannerEntries)
41989
+ setTimeout(async () => {
41990
+ try {
41991
+ const { sendIgnoredMessage } = await import("./send-session-notification-hdh02wy9.js");
41992
+ const clientWithSessions = ctx.client;
41993
+ const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
41994
+ const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
41995
+ const sessionId = sessionList?.[0]?.id;
41996
+ if (sessionId) {
41997
+ await sendIgnoredMessage(ctx.client, sessionId, warningText, {});
41998
+ }
41999
+ } catch {}
42000
+ }, 3000);
42946
42001
  }
42947
42002
  configMs = performance.now() - configStartedAt;
42948
42003
  let conflictResult = null;
@@ -43162,7 +42217,7 @@ var server = async (ctx) => {
43162
42217
  {
43163
42218
  const fence = getSchemaFenceRejection();
43164
42219
  if (fence) {
43165
- import("./conflict-warning-hook-z5sd697e.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
42220
+ import("./conflict-warning-hook-ejkc9sjn.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
43166
42221
  }
43167
42222
  }
43168
42223
  const serverUrl = ctx.serverUrl;
@@ -43190,7 +42245,7 @@ var server = async (ctx) => {
43190
42245
  }) => {
43191
42246
  if (!shouldShowAnnouncement())
43192
42247
  return;
43193
- return import("./conflict-warning-hook-z5sd697e.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION, ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER, markAnnouncementSeen));
42248
+ return import("./conflict-warning-hook-ejkc9sjn.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION, ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER, markAnnouncementSeen));
43194
42249
  }).catch(() => {});
43195
42250
  }, 8000);
43196
42251
  }