@triedotdev/mcp 1.0.136 → 1.0.138

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 (105) hide show
  1. package/README.md +6 -6
  2. package/dist/{autonomy-config-QA6ATWLJ.js → autonomy-config-TZ6HF4FA.js} +3 -3
  3. package/dist/{chat-store-HFOOWZYN.js → chat-store-OJLJCJFI.js} +3 -3
  4. package/dist/{chunk-DFPVUMVE.js → chunk-23RJT5WT.js} +5 -4
  5. package/dist/chunk-23RJT5WT.js.map +1 -0
  6. package/dist/{chunk-4YJ6KLGI.js → chunk-3MUCUZ46.js} +8 -8
  7. package/dist/chunk-3MUCUZ46.js.map +1 -0
  8. package/dist/{chunk-6VIMBFUZ.js → chunk-3RRXWX3V.js} +21 -17
  9. package/dist/chunk-3RRXWX3V.js.map +1 -0
  10. package/dist/{chunk-WHIQAGB7.js → chunk-4C67GV3O.js} +2 -2
  11. package/dist/{chunk-WS6OA7H6.js → chunk-4MJ52WBH.js} +2 -3
  12. package/dist/chunk-4MJ52WBH.js.map +1 -0
  13. package/dist/{chunk-AJ34GCMD.js → chunk-67GSG2ST.js} +41 -38
  14. package/dist/chunk-67GSG2ST.js.map +1 -0
  15. package/dist/{chunk-UHX4462X.js → chunk-6LLH3TBZ.js} +24 -25
  16. package/dist/chunk-6LLH3TBZ.js.map +1 -0
  17. package/dist/{chunk-DFHMB44X.js → chunk-D3AS5LY7.js} +6 -10
  18. package/dist/chunk-D3AS5LY7.js.map +1 -0
  19. package/dist/{chunk-6OUWNVLX.js → chunk-EDDT4ZIH.js} +8 -8
  20. package/dist/chunk-EDDT4ZIH.js.map +1 -0
  21. package/dist/{chunk-Z4DN527J.js → chunk-FG467PDD.js} +156 -39
  22. package/dist/chunk-FG467PDD.js.map +1 -0
  23. package/dist/{chunk-T4THB2OR.js → chunk-FOCXXIXY.js} +49 -28
  24. package/dist/chunk-FOCXXIXY.js.map +1 -0
  25. package/dist/{goal-validator-PDKYZSNP.js → chunk-GFFUDJMK.js} +97 -40
  26. package/dist/chunk-GFFUDJMK.js.map +1 -0
  27. package/dist/{chunk-ZEXMMTIQ.js → chunk-J5EMP4XW.js} +2 -2
  28. package/dist/{chunk-UHMMANC2.js → chunk-LT6VUZG2.js} +21 -18
  29. package/dist/chunk-LT6VUZG2.js.map +1 -0
  30. package/dist/{chunk-55CBWOEZ.js → chunk-QSWUPSLK.js} +2 -2
  31. package/dist/{chunk-45Y5TLQZ.js → chunk-SH7H3WRU.js} +3 -6
  32. package/dist/chunk-SH7H3WRU.js.map +1 -0
  33. package/dist/{chunk-VRLMTOB6.js → chunk-TIMIKBY2.js} +1 -1
  34. package/dist/chunk-TIMIKBY2.js.map +1 -0
  35. package/dist/{chunk-POHBQUG7.js → chunk-X3F5QDER.js} +1224 -448
  36. package/dist/chunk-X3F5QDER.js.map +1 -0
  37. package/dist/{chunk-O6OTJI3W.js → chunk-Y32FM3MR.js} +2 -2
  38. package/dist/{chunk-G5PRBQIQ.js → chunk-YOKQ25IW.js} +102 -82
  39. package/dist/chunk-YOKQ25IW.js.map +1 -0
  40. package/dist/{chunk-JAKMZI5S.js → chunk-Z2P4WST6.js} +291 -180
  41. package/dist/chunk-Z2P4WST6.js.map +1 -0
  42. package/dist/cli/create-agent.js +1 -1
  43. package/dist/cli/main.js +113 -86
  44. package/dist/cli/main.js.map +1 -1
  45. package/dist/cli/yolo-daemon.js +19 -19
  46. package/dist/cli/yolo-daemon.js.map +1 -1
  47. package/dist/{client-BZHI675W.js → client-JTU5TRLB.js} +3 -3
  48. package/dist/{codebase-index-CR6Q2HEI.js → codebase-index-FNJ4GCBE.js} +3 -3
  49. package/dist/{goal-manager-FAK7H4RR.js → goal-manager-6BJQ36AH.js} +7 -8
  50. package/dist/goal-validator-GISXYANK.js +22 -0
  51. package/dist/{graph-PAUZ5EMP.js → graph-X2FMRQLG.js} +3 -3
  52. package/dist/{hypothesis-L5446W36.js → hypothesis-K3KQJOXJ.js} +7 -8
  53. package/dist/{incident-index-ZCDSJ42L.js → incident-index-BWW2UEY7.js} +3 -3
  54. package/dist/index.js +343 -288
  55. package/dist/index.js.map +1 -1
  56. package/dist/{insight-store-F5KDBY5Y.js → insight-store-A5XXMFD6.js} +6 -6
  57. package/dist/issue-store-BO5OWLJW.js +32 -0
  58. package/dist/{output-manager-BOTMXSND.js → output-manager-DZO5LGSG.js} +2 -2
  59. package/dist/{tiered-storage-QW2G7GSG.js → tiered-storage-VZL7KK64.js} +3 -3
  60. package/dist/trie-agent-XMSGMD7E.js +26 -0
  61. package/dist/trie-agent-XMSGMD7E.js.map +1 -0
  62. package/dist/ui/chat.html +260 -67
  63. package/dist/ui/goals.html +246 -3
  64. package/dist/ui/hypotheses.html +248 -5
  65. package/dist/ui/ledger.html +252 -9
  66. package/dist/ui/nudges.html +244 -1
  67. package/package.json +1 -1
  68. package/dist/chunk-45Y5TLQZ.js.map +0 -1
  69. package/dist/chunk-4YJ6KLGI.js.map +0 -1
  70. package/dist/chunk-6OUWNVLX.js.map +0 -1
  71. package/dist/chunk-6VIMBFUZ.js.map +0 -1
  72. package/dist/chunk-AJ34GCMD.js.map +0 -1
  73. package/dist/chunk-DFHMB44X.js.map +0 -1
  74. package/dist/chunk-DFPVUMVE.js.map +0 -1
  75. package/dist/chunk-G5PRBQIQ.js.map +0 -1
  76. package/dist/chunk-JAKMZI5S.js.map +0 -1
  77. package/dist/chunk-PEJEYWVR.js +0 -135
  78. package/dist/chunk-PEJEYWVR.js.map +0 -1
  79. package/dist/chunk-POHBQUG7.js.map +0 -1
  80. package/dist/chunk-T4THB2OR.js.map +0 -1
  81. package/dist/chunk-UHMMANC2.js.map +0 -1
  82. package/dist/chunk-UHX4462X.js.map +0 -1
  83. package/dist/chunk-VRLMTOB6.js.map +0 -1
  84. package/dist/chunk-WS6OA7H6.js.map +0 -1
  85. package/dist/chunk-Z4DN527J.js.map +0 -1
  86. package/dist/goal-validator-PDKYZSNP.js.map +0 -1
  87. package/dist/guardian-agent-4RHGIXUD.js +0 -27
  88. package/dist/ledger-WKVJWHBX.js +0 -17
  89. /package/dist/{autonomy-config-QA6ATWLJ.js.map → autonomy-config-TZ6HF4FA.js.map} +0 -0
  90. /package/dist/{chat-store-HFOOWZYN.js.map → chat-store-OJLJCJFI.js.map} +0 -0
  91. /package/dist/{chunk-WHIQAGB7.js.map → chunk-4C67GV3O.js.map} +0 -0
  92. /package/dist/{chunk-ZEXMMTIQ.js.map → chunk-J5EMP4XW.js.map} +0 -0
  93. /package/dist/{chunk-55CBWOEZ.js.map → chunk-QSWUPSLK.js.map} +0 -0
  94. /package/dist/{chunk-O6OTJI3W.js.map → chunk-Y32FM3MR.js.map} +0 -0
  95. /package/dist/{client-BZHI675W.js.map → client-JTU5TRLB.js.map} +0 -0
  96. /package/dist/{codebase-index-CR6Q2HEI.js.map → codebase-index-FNJ4GCBE.js.map} +0 -0
  97. /package/dist/{goal-manager-FAK7H4RR.js.map → goal-manager-6BJQ36AH.js.map} +0 -0
  98. /package/dist/{graph-PAUZ5EMP.js.map → goal-validator-GISXYANK.js.map} +0 -0
  99. /package/dist/{guardian-agent-4RHGIXUD.js.map → graph-X2FMRQLG.js.map} +0 -0
  100. /package/dist/{hypothesis-L5446W36.js.map → hypothesis-K3KQJOXJ.js.map} +0 -0
  101. /package/dist/{incident-index-ZCDSJ42L.js.map → incident-index-BWW2UEY7.js.map} +0 -0
  102. /package/dist/{insight-store-F5KDBY5Y.js.map → insight-store-A5XXMFD6.js.map} +0 -0
  103. /package/dist/{ledger-WKVJWHBX.js.map → issue-store-BO5OWLJW.js.map} +0 -0
  104. /package/dist/{output-manager-BOTMXSND.js.map → output-manager-DZO5LGSG.js.map} +0 -0
  105. /package/dist/{tiered-storage-QW2G7GSG.js.map → tiered-storage-VZL7KK64.js.map} +0 -0
@@ -644,20 +644,263 @@ h4 { font-size: 14px; }
644
644
  flex: 1;
645
645
  }
646
646
 
647
+ /* Chat App Styles */
648
+ .chat-container {
649
+ display: flex;
650
+ flex-direction: column;
651
+ height: calc(100vh - 120px);
652
+ max-height: 800px;
653
+ margin-top: 16px;
654
+ }
655
+
656
+ .messages-container {
657
+ flex: 1;
658
+ overflow-y: auto;
659
+ padding: 16px;
660
+ border: 1px solid var(--trie-border);
661
+ border-radius: var(--radius) var(--radius) 0 0;
662
+ background: var(--trie-surface);
663
+ min-height: 400px;
664
+ }
665
+
666
+ .message {
667
+ margin-bottom: 16px;
668
+ padding: 12px 16px;
669
+ border-radius: var(--radius);
670
+ background: var(--trie-bg);
671
+ border: 1px solid var(--trie-border);
672
+ }
673
+
674
+ .message.user-message {
675
+ margin-left: 20%;
676
+ background: rgba(88, 166, 255, 0.1);
677
+ border-color: rgba(88, 166, 255, 0.3);
678
+ }
679
+
680
+ .message.assistant-message {
681
+ margin-right: 20%;
682
+ }
683
+
684
+ .message-header {
685
+ display: flex;
686
+ justify-content: space-between;
687
+ margin-bottom: 8px;
688
+ font-size: 12px;
689
+ color: var(--trie-text-muted);
690
+ }
691
+
692
+ .message-author {
693
+ font-weight: 600;
694
+ }
695
+
696
+ .message-content {
697
+ line-height: 1.6;
698
+ white-space: pre-wrap;
699
+ word-wrap: break-word;
700
+ }
701
+
702
+ .message-content pre {
703
+ background: var(--trie-surface);
704
+ border: 1px solid var(--trie-border);
705
+ border-radius: var(--radius);
706
+ padding: 12px;
707
+ margin: 8px 0;
708
+ overflow-x: auto;
709
+ font-family: var(--font-mono);
710
+ font-size: 12px;
711
+ }
712
+
713
+ .message-content code {
714
+ font-family: var(--font-mono);
715
+ font-size: 12px;
716
+ background: rgba(110, 118, 129, 0.2);
717
+ padding: 2px 6px;
718
+ border-radius: 4px;
719
+ }
720
+
721
+ .message-content pre code {
722
+ background: none;
723
+ padding: 0;
724
+ }
725
+
726
+ .typing-indicator {
727
+ display: flex;
728
+ gap: 4px;
729
+ align-items: center;
730
+ }
731
+
732
+ .typing-indicator span {
733
+ width: 8px;
734
+ height: 8px;
735
+ border-radius: 50%;
736
+ background: var(--trie-text-muted);
737
+ animation: typing 1.4s infinite ease-in-out;
738
+ }
739
+
740
+ .typing-indicator span:nth-child(1) { animation-delay: 0s; }
741
+ .typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
742
+ .typing-indicator span:nth-child(3) { animation-delay: 0.4s; }
743
+
744
+ @keyframes typing {
745
+ 0%, 80%, 100% {
746
+ opacity: 0.3;
747
+ transform: scale(0.8);
748
+ }
749
+ 40% {
750
+ opacity: 1;
751
+ transform: scale(1);
752
+ }
753
+ }
754
+
755
+ .tool-calls {
756
+ margin-bottom: 12px;
757
+ padding: 12px;
758
+ background: var(--trie-surface);
759
+ border: 1px solid var(--trie-border);
760
+ border-radius: var(--radius);
761
+ font-family: var(--font-mono);
762
+ font-size: 12px;
763
+ }
764
+
765
+ .tool-call {
766
+ display: flex;
767
+ gap: 8px;
768
+ margin-bottom: 4px;
769
+ }
770
+
771
+ .tool-call:last-child {
772
+ margin-bottom: 0;
773
+ }
774
+
775
+ .tool-name {
776
+ color: var(--trie-primary);
777
+ font-weight: 600;
778
+ }
779
+
780
+ .tool-input {
781
+ color: var(--trie-text-muted);
782
+ }
783
+
784
+ .pending-fix {
785
+ margin-top: 12px;
786
+ padding: 16px;
787
+ background: rgba(210, 153, 34, 0.1);
788
+ border: 1px solid rgba(210, 153, 34, 0.3);
789
+ border-radius: var(--radius);
790
+ }
791
+
792
+ .fix-header {
793
+ margin-bottom: 12px;
794
+ color: var(--trie-warning);
795
+ }
796
+
797
+ .fix-details p {
798
+ margin-bottom: 8px;
799
+ font-size: 14px;
800
+ }
801
+
802
+ .fix-actions {
803
+ display: flex;
804
+ gap: 8px;
805
+ margin-top: 12px;
806
+ }
807
+
808
+ .chat-input-container {
809
+ background: var(--trie-surface);
810
+ border: 1px solid var(--trie-border);
811
+ border-top: none;
812
+ border-radius: 0 0 var(--radius) var(--radius);
813
+ padding: 16px;
814
+ flex-shrink: 0;
815
+ }
816
+
817
+ .input-wrapper {
818
+ display: flex;
819
+ gap: 12px;
820
+ align-items: flex-end;
821
+ }
822
+
823
+ .chat-input {
824
+ flex: 1;
825
+ min-height: 60px;
826
+ max-height: 120px;
827
+ padding: 12px;
828
+ font-size: 14px;
829
+ line-height: 1.5;
830
+ border: 1px solid var(--trie-border);
831
+ border-radius: var(--radius);
832
+ background: var(--trie-bg);
833
+ color: var(--trie-text);
834
+ resize: none;
835
+ font-family: var(--font-sans);
836
+ }
837
+
838
+ .chat-input:focus {
839
+ outline: none;
840
+ border-color: var(--trie-primary);
841
+ }
842
+
843
+ .chat-input::placeholder {
844
+ color: var(--trie-text-muted);
845
+ }
846
+
847
+ .send-button {
848
+ padding: 12px 24px;
849
+ font-size: 14px;
850
+ font-weight: 600;
851
+ border: none;
852
+ border-radius: var(--radius);
853
+ background: var(--trie-primary);
854
+ color: #fff;
855
+ cursor: pointer;
856
+ transition: all 0.15s ease;
857
+ flex-shrink: 0;
858
+ height: fit-content;
859
+ }
860
+
861
+ .send-button:hover:not(:disabled) {
862
+ background: rgba(88, 166, 255, 0.9);
863
+ }
864
+
865
+ .send-button:disabled {
866
+ opacity: 0.5;
867
+ cursor: not-allowed;
868
+ }
869
+
870
+ .input-help {
871
+ margin-top: 8px;
872
+ font-size: 12px;
873
+ color: var(--trie-text-muted);
874
+ text-align: center;
875
+ }
876
+
877
+ .app-header {
878
+ margin-bottom: 0;
879
+ }
880
+
881
+ .app-header h1 {
882
+ margin-bottom: 4px;
883
+ }
884
+
885
+ .app-header p {
886
+ color: var(--trie-text-muted);
887
+ margin-bottom: 0;
888
+ }
889
+
647
890
  </style>
648
891
  </head>
649
892
  <body>
650
893
  <div id="app" class="container"></div>
651
894
  <script type="module">
652
- var u=Object.defineProperty;var g=(t,e,i)=>e in t?u(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i;var o=(t,e,i)=>g(t,typeof e!="symbol"?e+"":e,i);function v(t,e,i){let n=document.createElement(t);if(e)for(let[s,a]of Object.entries(e))s==="className"?n.className=String(a):typeof a=="boolean"?a&&n.setAttribute(s,""):n.setAttribute(s,String(a));if(i)for(let s of i)typeof s=="string"?n.appendChild(document.createTextNode(s)):n.appendChild(s);return n}var r=v;function f(t){return r("div",{className:"loading"},[r("div",{className:"spinner"}),t?r("span",{className:"ml-2"},[t]):document.createTextNode("")])}function p(t,e="Loading..."){t.innerHTML="",t.appendChild(f(e))}function d(t,e){t.innerHTML="",t.appendChild(r("div",{className:"error-state"},[r("div",{className:"error-icon"},["\u26A0\uFE0F"]),r("p",{className:"error-message"},[e])]))}function m(t){document.addEventListener("DOMContentLoaded",()=>{let e=document.getElementById("app");if(!e){console.error("App container not found");return}try{new t(e)}catch(i){d(e,`Failed to initialize app: ${i}`)}})}var l=class{constructor(e){o(this,"container");o(this,"data",{decisions:[],blockers:[],facts:[],questions:[]});o(this,"activeTab","decisions");this.container=e,this.init()}async init(){await this.loadData(),this.render(),this.setupEventListeners()}async loadData(){try{p(this.container,"Loading ledger data..."),this.data={decisions:[{id:"dec-1",decision:"Switch to TypeScript for new components",context:"Increasing type safety needs",timestamp:new Date().toISOString(),outcome:"success",reasoning:"Better dev experience and fewer runtime errors"},{id:"dec-2",decision:"Implement goal-based validation system",context:"Need systematic way to track code quality",timestamp:new Date(Date.now()-864e5).toISOString(),outcome:"active"}],blockers:[{id:"block-1",blocker:"Missing test coverage for validation logic",impact:"high",description:"Core validation functions lack comprehensive tests",timestamp:new Date().toISOString()}],facts:[],questions:[]}}catch(e){d(this.container,`Failed to load ledger data: ${e}`)}}render(){let e=`
895
+ var g=Object.defineProperty;var v=(t,e,n)=>e in t?g(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var o=(t,e,n)=>v(t,typeof e!="symbol"?e+"":e,n);function u(t,e,n){let i=document.createElement(t);if(e)for(let[a,s]of Object.entries(e))a==="className"?i.className=String(s):typeof s=="boolean"?s&&i.setAttribute(a,""):i.setAttribute(a,String(s));if(n)for(let a of n)typeof a=="string"?i.appendChild(document.createTextNode(a)):i.appendChild(a);return i}var r=u;function f(t){return r("div",{className:"loading"},[r("div",{className:"spinner"}),t?r("span",{className:"ml-2"},[t]):document.createTextNode("")])}function p(t,e="Loading..."){t.innerHTML="",t.appendChild(f(e))}function d(t,e){t.innerHTML="",t.appendChild(r("div",{className:"error-state"},[r("div",{className:"error-icon"},["\u26A0\uFE0F"]),r("p",{className:"error-message"},[e])]))}function m(t){document.addEventListener("DOMContentLoaded",()=>{let e=document.getElementById("app");if(!e){console.error("App container not found");return}try{new t(e)}catch(n){d(e,`Failed to initialize app: ${n}`)}})}var l=class{constructor(e){o(this,"container");o(this,"data",{governance:[],blockers:[],facts:[],questions:[]});o(this,"activeTab","governance");this.container=e,this.init()}async init(){await this.loadData(),this.render(),this.setupEventListeners()}async loadData(){try{p(this.container,"Loading ledger data..."),this.data={governance:[{id:"dec-1",decision:"Switch to TypeScript for new components",context:"Increasing type safety needs",timestamp:new Date().toISOString(),outcome:"success",reasoning:"Better dev experience and fewer runtime errors"},{id:"dec-2",decision:"Implement goal-based validation system",context:"Need systematic way to track code quality",timestamp:new Date(Date.now()-864e5).toISOString(),outcome:"active"}],blockers:[{id:"block-1",blocker:"Missing test coverage for validation logic",impact:"high",description:"Core validation functions lack comprehensive tests",timestamp:new Date().toISOString()}],facts:[],questions:[]}}catch(e){d(this.container,`Failed to load ledger data: ${e}`)}}render(){let e=`
653
896
  <div class="app-header">
654
- <h1>Decision Ledger</h1>
655
- <p>Track decisions, blockers, facts, and questions across your project</p>
897
+ <h1>Governance Ledger</h1>
898
+ <p>Track governance, blockers, facts, and questions across your project</p>
656
899
  </div>
657
900
 
658
901
  <div class="tab-nav">
659
- <button class="tab-btn ${this.activeTab==="decisions"?"active":""}" data-tab="decisions">
660
- Decisions (${this.data.decisions.length})
902
+ <button class="tab-btn ${this.activeTab==="governance"?"active":""}" data-tab="governance">
903
+ Governance (${this.data.governance.length})
661
904
  </button>
662
905
  <button class="tab-btn ${this.activeTab==="blockers"?"active":""}" data-tab="blockers">
663
906
  Blockers (${this.data.blockers.length})
@@ -673,10 +916,10 @@ var u=Object.defineProperty;var g=(t,e,i)=>e in t?u(t,e,{enumerable:!0,configura
673
916
  <div class="tab-content">
674
917
  ${this.renderTabContent()}
675
918
  </div>
676
- `;this.container.innerHTML=e}renderTabContent(){switch(this.activeTab){case"decisions":return this.renderDecisions();case"blockers":return this.renderBlockers();case"facts":return this.renderFacts();case"questions":return this.renderQuestions();default:return""}}renderDecisions(){return this.data.decisions.length===0?'<div class="empty-state">No decisions recorded yet</div>':`
919
+ `;this.container.innerHTML=e}renderTabContent(){switch(this.activeTab){case"governance":return this.renderGovernance();case"blockers":return this.renderBlockers();case"facts":return this.renderFacts();case"questions":return this.renderQuestions();default:return""}}renderGovernance(){return this.data.governance.length===0?'<div class="empty-state">No governance recorded yet</div>':`
677
920
  <div class="items-list">
678
- ${this.data.decisions.map(e=>`
679
- <div class="item-card decision-card">
921
+ ${this.data.governance.map(e=>`
922
+ <div class="item-card governance-card">
680
923
  <div class="item-header">
681
924
  <span class="item-title">${e.decision}</span>
682
925
  <span class="item-meta">${this.formatTimeAgo(e.timestamp)}</span>
@@ -704,7 +947,7 @@ var u=Object.defineProperty;var g=(t,e,i)=>e in t?u(t,e,{enumerable:!0,configura
704
947
  </div>
705
948
  `).join("")}
706
949
  </div>
707
- `}renderFacts(){return'<div class="empty-state">No facts recorded yet</div>'}renderQuestions(){return'<div class="empty-state">No questions recorded yet</div>'}formatTimeAgo(e){let i=Date.now(),n=new Date(e).getTime(),s=i-n,a=Math.floor(s/(1e3*60));if(a<60)return`${a}m ago`;let c=Math.floor(a/60);return c<24?`${c}h ago`:`${Math.floor(c/24)}d ago`}setupEventListeners(){this.container.addEventListener("click",e=>{let i=e.target;if(i.classList.contains("tab-btn")){let n=i.getAttribute("data-tab");n&&(this.activeTab=n,this.render(),this.setupEventListeners())}})}};m(l);
950
+ `}renderFacts(){return'<div class="empty-state">No facts recorded yet</div>'}renderQuestions(){return'<div class="empty-state">No questions recorded yet</div>'}formatTimeAgo(e){let n=Date.now(),i=new Date(e).getTime(),a=n-i,s=Math.floor(a/(1e3*60));if(s<60)return`${s}m ago`;let c=Math.floor(s/60);return c<24?`${c}h ago`:`${Math.floor(c/24)}d ago`}setupEventListeners(){this.container.addEventListener("click",e=>{let n=e.target;if(n.classList.contains("tab-btn")){let i=n.getAttribute("data-tab");i&&(this.activeTab=i,this.render(),this.setupEventListeners())}})}};m(l);
708
951
 
709
952
  </script>
710
953
  </body>
@@ -644,6 +644,249 @@ h4 { font-size: 14px; }
644
644
  flex: 1;
645
645
  }
646
646
 
647
+ /* Chat App Styles */
648
+ .chat-container {
649
+ display: flex;
650
+ flex-direction: column;
651
+ height: calc(100vh - 120px);
652
+ max-height: 800px;
653
+ margin-top: 16px;
654
+ }
655
+
656
+ .messages-container {
657
+ flex: 1;
658
+ overflow-y: auto;
659
+ padding: 16px;
660
+ border: 1px solid var(--trie-border);
661
+ border-radius: var(--radius) var(--radius) 0 0;
662
+ background: var(--trie-surface);
663
+ min-height: 400px;
664
+ }
665
+
666
+ .message {
667
+ margin-bottom: 16px;
668
+ padding: 12px 16px;
669
+ border-radius: var(--radius);
670
+ background: var(--trie-bg);
671
+ border: 1px solid var(--trie-border);
672
+ }
673
+
674
+ .message.user-message {
675
+ margin-left: 20%;
676
+ background: rgba(88, 166, 255, 0.1);
677
+ border-color: rgba(88, 166, 255, 0.3);
678
+ }
679
+
680
+ .message.assistant-message {
681
+ margin-right: 20%;
682
+ }
683
+
684
+ .message-header {
685
+ display: flex;
686
+ justify-content: space-between;
687
+ margin-bottom: 8px;
688
+ font-size: 12px;
689
+ color: var(--trie-text-muted);
690
+ }
691
+
692
+ .message-author {
693
+ font-weight: 600;
694
+ }
695
+
696
+ .message-content {
697
+ line-height: 1.6;
698
+ white-space: pre-wrap;
699
+ word-wrap: break-word;
700
+ }
701
+
702
+ .message-content pre {
703
+ background: var(--trie-surface);
704
+ border: 1px solid var(--trie-border);
705
+ border-radius: var(--radius);
706
+ padding: 12px;
707
+ margin: 8px 0;
708
+ overflow-x: auto;
709
+ font-family: var(--font-mono);
710
+ font-size: 12px;
711
+ }
712
+
713
+ .message-content code {
714
+ font-family: var(--font-mono);
715
+ font-size: 12px;
716
+ background: rgba(110, 118, 129, 0.2);
717
+ padding: 2px 6px;
718
+ border-radius: 4px;
719
+ }
720
+
721
+ .message-content pre code {
722
+ background: none;
723
+ padding: 0;
724
+ }
725
+
726
+ .typing-indicator {
727
+ display: flex;
728
+ gap: 4px;
729
+ align-items: center;
730
+ }
731
+
732
+ .typing-indicator span {
733
+ width: 8px;
734
+ height: 8px;
735
+ border-radius: 50%;
736
+ background: var(--trie-text-muted);
737
+ animation: typing 1.4s infinite ease-in-out;
738
+ }
739
+
740
+ .typing-indicator span:nth-child(1) { animation-delay: 0s; }
741
+ .typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
742
+ .typing-indicator span:nth-child(3) { animation-delay: 0.4s; }
743
+
744
+ @keyframes typing {
745
+ 0%, 80%, 100% {
746
+ opacity: 0.3;
747
+ transform: scale(0.8);
748
+ }
749
+ 40% {
750
+ opacity: 1;
751
+ transform: scale(1);
752
+ }
753
+ }
754
+
755
+ .tool-calls {
756
+ margin-bottom: 12px;
757
+ padding: 12px;
758
+ background: var(--trie-surface);
759
+ border: 1px solid var(--trie-border);
760
+ border-radius: var(--radius);
761
+ font-family: var(--font-mono);
762
+ font-size: 12px;
763
+ }
764
+
765
+ .tool-call {
766
+ display: flex;
767
+ gap: 8px;
768
+ margin-bottom: 4px;
769
+ }
770
+
771
+ .tool-call:last-child {
772
+ margin-bottom: 0;
773
+ }
774
+
775
+ .tool-name {
776
+ color: var(--trie-primary);
777
+ font-weight: 600;
778
+ }
779
+
780
+ .tool-input {
781
+ color: var(--trie-text-muted);
782
+ }
783
+
784
+ .pending-fix {
785
+ margin-top: 12px;
786
+ padding: 16px;
787
+ background: rgba(210, 153, 34, 0.1);
788
+ border: 1px solid rgba(210, 153, 34, 0.3);
789
+ border-radius: var(--radius);
790
+ }
791
+
792
+ .fix-header {
793
+ margin-bottom: 12px;
794
+ color: var(--trie-warning);
795
+ }
796
+
797
+ .fix-details p {
798
+ margin-bottom: 8px;
799
+ font-size: 14px;
800
+ }
801
+
802
+ .fix-actions {
803
+ display: flex;
804
+ gap: 8px;
805
+ margin-top: 12px;
806
+ }
807
+
808
+ .chat-input-container {
809
+ background: var(--trie-surface);
810
+ border: 1px solid var(--trie-border);
811
+ border-top: none;
812
+ border-radius: 0 0 var(--radius) var(--radius);
813
+ padding: 16px;
814
+ flex-shrink: 0;
815
+ }
816
+
817
+ .input-wrapper {
818
+ display: flex;
819
+ gap: 12px;
820
+ align-items: flex-end;
821
+ }
822
+
823
+ .chat-input {
824
+ flex: 1;
825
+ min-height: 60px;
826
+ max-height: 120px;
827
+ padding: 12px;
828
+ font-size: 14px;
829
+ line-height: 1.5;
830
+ border: 1px solid var(--trie-border);
831
+ border-radius: var(--radius);
832
+ background: var(--trie-bg);
833
+ color: var(--trie-text);
834
+ resize: none;
835
+ font-family: var(--font-sans);
836
+ }
837
+
838
+ .chat-input:focus {
839
+ outline: none;
840
+ border-color: var(--trie-primary);
841
+ }
842
+
843
+ .chat-input::placeholder {
844
+ color: var(--trie-text-muted);
845
+ }
846
+
847
+ .send-button {
848
+ padding: 12px 24px;
849
+ font-size: 14px;
850
+ font-weight: 600;
851
+ border: none;
852
+ border-radius: var(--radius);
853
+ background: var(--trie-primary);
854
+ color: #fff;
855
+ cursor: pointer;
856
+ transition: all 0.15s ease;
857
+ flex-shrink: 0;
858
+ height: fit-content;
859
+ }
860
+
861
+ .send-button:hover:not(:disabled) {
862
+ background: rgba(88, 166, 255, 0.9);
863
+ }
864
+
865
+ .send-button:disabled {
866
+ opacity: 0.5;
867
+ cursor: not-allowed;
868
+ }
869
+
870
+ .input-help {
871
+ margin-top: 8px;
872
+ font-size: 12px;
873
+ color: var(--trie-text-muted);
874
+ text-align: center;
875
+ }
876
+
877
+ .app-header {
878
+ margin-bottom: 0;
879
+ }
880
+
881
+ .app-header h1 {
882
+ margin-bottom: 4px;
883
+ }
884
+
885
+ .app-header p {
886
+ color: var(--trie-text-muted);
887
+ margin-bottom: 0;
888
+ }
889
+
647
890
  </style>
648
891
  </head>
649
892
  <body>
@@ -745,7 +988,7 @@ var u=Object.defineProperty;var f=(s,e,t)=>e in s?u(s,e,{enumerable:!0,configura
745
988
  `:""}
746
989
  </div>
747
990
  </div>
748
- `}getFilteredInsights(){return this.insights.filter(e=>!(this.filter==="active"&&e.dismissed||this.filter==="dismissed"&&!e.dismissed||this.categoryFilter!=="all"&&e.category!==this.categoryFilter)).sort((e,t)=>e.priority!==t.priority?t.priority-e.priority:t.timestamp-e.timestamp)}getTypeIcon(e){switch(e){case"warning":return"\u26A0\uFE0F";case"celebration":return"\u{1F389}";case"suggestion":return"\u{1F4A1}";default:return"\u2139\uFE0F"}}formatTimeAgo(e){let n=Date.now()-e,i=Math.floor(n/(1e3*60));if(i<60)return`${i}m ago`;let r=Math.floor(i/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}setupEventListeners(){this.container.addEventListener("change",e=>{let t=e.target;if(t.classList.contains("filter-select")){let n=t.getAttribute("data-filter"),i=t.value;n==="status"?this.filter=i:n==="category"&&(this.categoryFilter=i),this.render(),this.setupEventListeners()}}),window.dismissInsight=async e=>{let t=this.insights.find(n=>n.id===e);t&&(t.dismissed=!0,this.render(),this.setupEventListeners())},window.openFile=e=>{console.log("Opening file:",e)}}};m(d);
991
+ `}getFilteredInsights(){return this.insights.filter(e=>!(this.filter==="active"&&e.dismissed||this.filter==="dismissed"&&!e.dismissed||this.categoryFilter!=="all"&&e.category!==this.categoryFilter)).sort((e,t)=>e.priority!==t.priority?t.priority-e.priority:t.timestamp-e.timestamp)}getTypeIcon(e){switch(e){case"warning":return"[!]";case"celebration":return"[*]";case"suggestion":return"[?]";default:return"[i]"}}formatTimeAgo(e){let n=Date.now()-e,i=Math.floor(n/(1e3*60));if(i<60)return`${i}m ago`;let r=Math.floor(i/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}setupEventListeners(){this.container.addEventListener("change",e=>{let t=e.target;if(t.classList.contains("filter-select")){let n=t.getAttribute("data-filter"),i=t.value;n==="status"?this.filter=i:n==="category"&&(this.categoryFilter=i),this.render(),this.setupEventListeners()}}),window.dismissInsight=async e=>{let t=this.insights.find(n=>n.id===e);t&&(t.dismissed=!0,this.render(),this.setupEventListeners())},window.openFile=e=>{console.log("Opening file:",e)}}};m(d);
749
992
 
750
993
  </script>
751
994
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@triedotdev/mcp",
3
- "version": "1.0.136",
3
+ "version": "1.0.138",
4
4
  "description": "Trainable AI Agent for Maintaining AI-Generated Codebases",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/workspace.ts"],"sourcesContent":["/**\n * Workspace detection utilities\n * \n * MCP servers run as separate processes where process.cwd() may not be\n * the user's workspace. These utilities detect the actual project root\n * by looking for common project indicators.\n */\n\nimport { execSync } from 'node:child_process';\nimport { existsSync } from 'fs';\nimport { basename, dirname, join, resolve } from 'path';\nimport { isInteractiveMode } from './progress.js';\n\n// Project root indicators - files/directories that indicate a project root\n// Ordered by strength: primary indicators first\nconst PROJECT_ROOT_INDICATORS = [\n 'package.json', // Node.js/npm projects\n '.git', // Git repository root\n 'Cargo.toml', // Rust projects\n 'go.mod', // Go modules\n 'pyproject.toml', // Python projects (modern)\n 'pom.xml', // Maven (Java)\n 'build.gradle', // Gradle (Java/Kotlin)\n 'deno.json', // Deno projects\n // Note: .trie/config.json would be a better indicator, but empty .trie dirs exist\n // tsconfig.json is secondary as it can exist in subdirectories\n];\n\n// Directories that indicate we're in an npm package, not a user workspace\nconst NPM_PACKAGE_INDICATORS = [\n 'node_modules/@', // Scoped packages\n 'node_modules/', // Regular packages\n '.npm/', // npm cache\n '.nvm/', // nvm\n 'lib/node_modules/', // Global npm\n];\n\nfunction getGitCommonDir(startDir: string): string | null {\n try {\n const output = execSync('git rev-parse --git-common-dir', {\n cwd: startDir,\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString()\n .trim();\n if (!output) return null;\n return resolve(startDir, output);\n } catch {\n return null;\n }\n}\n\nfunction getSharedWorktreeRoot(startDir: string): string | null {\n const commonDir = getGitCommonDir(startDir);\n if (!commonDir) return null;\n if (basename(commonDir) !== '.git') return null;\n return dirname(commonDir);\n}\n\nexport function getTrieDirectory(workDir: string): string {\n const mode = process.env.TRIE_WORKTREE_MODE?.toLowerCase();\n if (mode === 'isolated') {\n return join(workDir, '.trie');\n }\n const sharedRoot = getSharedWorktreeRoot(workDir);\n if (sharedRoot) {\n return join(sharedRoot, '.trie');\n }\n return join(workDir, '.trie');\n}\n\n/**\n * Find the nearest project root by walking up from a starting directory\n * Returns the directory containing a project root indicator, or null if none found\n */\nexport function findProjectRoot(startDir: string, maxLevels: number = 10): string | null {\n let currentDir = resolve(startDir);\n let levels = 0;\n \n while (levels < maxLevels) {\n // Check if any project root indicator exists in this directory\n for (const indicator of PROJECT_ROOT_INDICATORS) {\n const indicatorPath = join(currentDir, indicator);\n if (existsSync(indicatorPath)) {\n return currentDir;\n }\n }\n \n // Move up one directory\n const parentDir = dirname(currentDir);\n if (parentDir === currentDir) {\n // Reached filesystem root\n break;\n }\n currentDir = parentDir;\n levels++;\n }\n \n return null;\n}\n\n/**\n * Check if a path looks like it's inside an npm package installation\n */\nfunction isInsideNpmPackage(dir: string): boolean {\n const normalizedPath = dir.replace(/\\\\/g, '/');\n return NPM_PACKAGE_INDICATORS.some(indicator => normalizedPath.includes(indicator));\n}\n\n/**\n * Try to get workspace from environment variables\n * Various tools set these when invoking MCP servers\n */\nfunction getWorkspaceFromEnv(): string | null {\n // Common environment variables that might contain workspace path\n const envVars = [\n 'CURSOR_WORKSPACE', // Cursor IDE\n 'CURSOR_WORKSPACE_ROOT', // Alternative Cursor env var\n 'VSCODE_WORKSPACE', // VS Code\n 'VSCODE_CWD', // VS Code working directory\n 'WORKSPACE_FOLDER', // Generic workspace\n 'PROJECT_ROOT', // Generic project root\n 'INIT_CWD', // npm's original directory\n 'PWD', // Original shell directory\n ];\n \n for (const envVar of envVars) {\n const value = process.env[envVar];\n if (value && existsSync(value)) {\n // Verify it looks like a project\n const hasProjectIndicator = PROJECT_ROOT_INDICATORS.some(\n indicator => existsSync(join(value, indicator))\n );\n if (hasProjectIndicator) {\n return value;\n }\n }\n }\n \n return null;\n}\n\n/**\n * Get the best working directory for scanning/operations\n * Priority: \n * 1. Explicit directory arg\n * 2. Environment variable (CURSOR_WORKSPACE, etc.)\n * 3. Detected project root from cwd (if not inside npm package)\n * 4. process.cwd() with warning\n * \n * @param explicitDir - Optional explicit directory from user\n * @param silent - If true, don't log warnings when falling back to cwd\n */\nexport function getWorkingDirectory(explicitDir?: string, silent: boolean = false): string {\n // If explicitly provided, use it\n if (explicitDir) {\n return resolve(explicitDir);\n }\n\n // Suppress all logs in interactive mode (TUI handles its own display)\n const shouldLog = !silent && !isInteractiveMode();\n\n // Debug: Log all relevant environment variables\n if (shouldLog && process.env.DEBUG_TRIE_WORKSPACE) {\n console.error('Debug: Environment variables:');\n console.error(` CURSOR_WORKSPACE: ${process.env.CURSOR_WORKSPACE || 'not set'}`);\n console.error(` CURSOR_WORKSPACE_ROOT: ${process.env.CURSOR_WORKSPACE_ROOT || 'not set'}`);\n console.error(` VSCODE_CWD: ${process.env.VSCODE_CWD || 'not set'}`);\n console.error(` INIT_CWD: ${process.env.INIT_CWD || 'not set'}`);\n console.error(` PWD: ${process.env.PWD || 'not set'}`);\n console.error(` process.cwd(): ${process.cwd()}`);\n }\n\n // Try environment variables first\n const envWorkspace = getWorkspaceFromEnv();\n if (envWorkspace) {\n if (shouldLog) {\n console.error(`Using workspace from environment: ${envWorkspace}`);\n }\n return envWorkspace;\n }\n \n // Try to find a project root from cwd\n const cwd = process.cwd();\n \n // Check if we're running from inside an npm package (common for MCP servers)\n if (isInsideNpmPackage(cwd)) {\n if (shouldLog) {\n console.error('Warning: MCP server running from npm package directory.');\n console.error(' Please pass the \"directory\" parameter with your project path.');\n console.error(` Current directory: ${cwd}`);\n }\n // Still return cwd, but we've warned\n return cwd;\n }\n \n const projectRoot = findProjectRoot(cwd);\n \n if (projectRoot) {\n // Extra check: make sure we're not returning the Trie package itself\n const packageJsonPath = join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const pkg = JSON.parse(require('fs').readFileSync(packageJsonPath, 'utf-8'));\n if (pkg.name === '@triedotdev/mcp' || pkg.name === 'trie-mcp-agent') {\n if (shouldLog) {\n console.error('Warning: Detected Trie package directory, not user workspace.');\n console.error(' Please pass the \"directory\" parameter with your project path.');\n }\n return cwd;\n }\n } catch {\n // Ignore parse errors\n }\n }\n return projectRoot;\n }\n \n // Fallback to cwd, but warn\n if (shouldLog) {\n console.error('Warning: Could not detect project root. Operating from:', cwd);\n console.error(' Tip: Pass directory parameter or run from a directory with package.json/.git');\n console.error(' Or set DEBUG_TRIE_WORKSPACE=1 to debug workspace detection');\n console.error(` Current working directory: ${cwd}`);\n\n // Show how to properly call with directory\n console.error(' Examples:');\n console.error(' Use trie_security with directory: \"/path/to/your/project\"');\n console.error(' Use trie_scan with directory: \"./your-project\"');\n }\n\n return cwd;\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/guardian/insight-store.ts"],"sourcesContent":["/**\n * Insight Store - Persistent storage for Guardian insights\n * \n * Phase 1 of Guardian Agency Plan: Fix critical persistence gaps\n * \n * Persists to: .trie/memory/guardian-insights.json\n * \n * Features:\n * - Insight persistence across restarts\n * - Cooldown state persistence (prevents duplicate insights)\n * - Dismissed insight tracking\n * - Atomic writes with backup rotation\n * - Zod validation for data integrity\n */\n\nimport { mkdir, readFile } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { getTrieDirectory } from '../utils/workspace.js';\nimport { z } from 'zod';\nimport { atomicWriteJSON } from '../utils/atomic-write.js';\nimport { BackupManager } from '../utils/backup-manager.js';\nimport { safeParseAndValidate } from '../memory/validation.js';\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\n/**\n * Schema for insight details\n */\nexport const InsightDetailsSchema = z.object({\n affectedFiles: z.array(z.string()).optional(),\n issueBreakdown: z.record(z.string(), z.number()).optional(),\n examples: z.array(z.string()).optional(),\n trend: z.enum(['improving', 'stable', 'worsening']).optional(),\n comparison: z.string().optional(),\n resolvedCount: z.number().optional(),\n resolvedIssues: z.array(z.object({\n file: z.string(),\n line: z.number().optional(),\n issue: z.string(),\n agent: z.string(),\n resolvedAt: z.string().optional(),\n })).optional(),\n summary: z.string().optional(),\n // Hypothesis-related fields\n hypothesis: z.string().optional(),\n testCriteria: z.string().optional(),\n confidence: z.number().optional(),\n // Pattern-related fields\n patternsCount: z.number().optional(),\n topPattern: z.string().optional(),\n});\n\n/**\n * Schema for a Guardian insight\n */\nexport const GuardianInsightSchema = z.object({\n id: z.string(),\n type: z.enum(['observation', 'warning', 'suggestion', 'celebration', 'question']),\n message: z.string(),\n context: z.string().optional(),\n suggestedAction: z.string().optional(),\n actionCommand: z.string().optional(),\n relatedIssues: z.array(z.string()),\n priority: z.number().min(1).max(10),\n timestamp: z.number(),\n dismissed: z.boolean(),\n category: z.enum(['security', 'quality', 'performance', 'pattern', 'progress', 'general']),\n details: InsightDetailsSchema.optional(),\n});\n\nexport type GuardianInsight = z.infer<typeof GuardianInsightSchema>;\n\n/**\n * Schema for the entire insight store file\n */\nexport const InsightStoreDataSchema = z.object({\n version: z.literal(1),\n insights: z.array(GuardianInsightSchema),\n cooldowns: z.record(z.string(), z.number()), // insightKey -> timestamp\n dismissedIds: z.array(z.string()), // Track dismissed insight IDs permanently\n lastUpdated: z.string(),\n});\n\nexport type InsightStoreData = z.infer<typeof InsightStoreDataSchema>;\n\n// ============================================================================\n// InsightStore Class\n// ============================================================================\n\n/**\n * Persistent store for Guardian insights\n * \n * Usage:\n * ```typescript\n * const store = new InsightStore(projectPath);\n * await store.load();\n * \n * await store.addInsight(insight);\n * const active = store.getActiveInsights();\n * await store.dismissInsight(insightId);\n * ```\n */\nexport class InsightStore {\n private projectPath: string;\n private data: InsightStoreData;\n private loaded: boolean = false;\n private dirty: boolean = false;\n \n // Default cooldown periods (in ms)\n static readonly COOLDOWNS: Record<string, number> = {\n 'pre-push-warning': 60000, // 1 min between pre-push warnings\n 'security-warning': 30000, // 30s between security warnings\n 'new-issues': 30000, // 30s between new issue observations\n 'celebration': 60000, // 1 min between celebrations\n 'pattern-suggestion': 120000, // 2 min between pattern suggestions\n 'accessibility-visual-qa': 300000, // 5 min between visual QA suggestions\n 'goal-suggestion': 300000, // 5 min between goal suggestions\n 'risk-prediction': 180000, // 3 min between risk predictions\n 'hypothesis-update': 600000, // 10 min between hypothesis updates\n 'auto-escalation': 300000, // 5 min between auto-escalations\n };\n \n constructor(projectPath: string) {\n this.projectPath = projectPath;\n this.data = this.createEmptyData();\n }\n \n /**\n * Get the storage file path\n */\n private getStorePath(): string {\n return join(getTrieDirectory(this.projectPath), 'memory', 'guardian-insights.json');\n }\n \n /**\n * Create empty data structure\n */\n private createEmptyData(): InsightStoreData {\n return {\n version: 1,\n insights: [],\n cooldowns: {},\n dismissedIds: [],\n lastUpdated: new Date().toISOString(),\n };\n }\n \n /**\n * Load insights from disk\n * \n * If the file is corrupted, attempts recovery from backup.\n * Returns empty data if no valid file/backup exists.\n */\n async load(): Promise<InsightStoreData> {\n if (this.loaded) {\n return this.data;\n }\n \n const storePath = this.getStorePath();\n \n try {\n if (existsSync(storePath)) {\n const content = await readFile(storePath, 'utf-8');\n const result = safeParseAndValidate(content, InsightStoreDataSchema);\n \n if (result.success) {\n this.data = result.data;\n this.loaded = true;\n // Deduplicate any existing duplicate insights\n this.deduplicateInsights();\n return this.data;\n }\n \n // Validation failed - attempt recovery from backup\n console.error(` Insight store corrupted: ${result.error}`);\n const backupManager = new BackupManager(storePath);\n \n if (await backupManager.recoverFromBackup()) {\n console.error(' Recovered from backup');\n const recovered = await readFile(storePath, 'utf-8');\n const recoveredResult = safeParseAndValidate(recovered, InsightStoreDataSchema);\n if (recoveredResult.success) {\n this.data = recoveredResult.data;\n this.loaded = true;\n // Deduplicate any existing duplicate insights\n this.deduplicateInsights();\n return this.data;\n }\n }\n \n console.error(' No valid backup found, starting fresh');\n }\n } catch (error) {\n // File doesn't exist or recovery failed - start fresh\n console.error(` Could not load insight store: ${error}`);\n }\n \n this.data = this.createEmptyData();\n this.loaded = true;\n return this.data;\n }\n \n /**\n * Deduplicate existing insights on load\n * Keeps the most recent instance of each unique insight\n */\n private deduplicateInsights(): void {\n const seen = new Map<string, number>(); // contentKey -> index of first occurrence\n const toRemove: number[] = [];\n \n // Process from newest to oldest (insights are sorted by recency)\n for (let i = 0; i < this.data.insights.length; i++) {\n const insight = this.data.insights[i];\n if (!insight) continue;\n \n const contentKey = this.getContentKey(insight);\n \n if (seen.has(contentKey)) {\n // This is a duplicate - mark for removal\n toRemove.push(i);\n } else {\n seen.set(contentKey, i);\n }\n }\n \n // Remove duplicates (reverse order to preserve indices)\n if (toRemove.length > 0) {\n for (let i = toRemove.length - 1; i >= 0; i--) {\n const idx = toRemove[i];\n if (idx !== undefined) {\n this.data.insights.splice(idx, 1);\n }\n }\n this.dirty = true;\n }\n }\n \n /**\n * Save insights to disk\n * \n * Creates backup before writing, uses atomic write.\n */\n async save(): Promise<void> {\n if (!this.dirty && this.loaded) {\n return; // No changes to save\n }\n \n const storePath = this.getStorePath();\n const memoryDir = join(getTrieDirectory(this.projectPath), 'memory');\n \n // Ensure directory exists\n await mkdir(memoryDir, { recursive: true });\n \n // Create backup before writing\n const backupManager = new BackupManager(storePath);\n await backupManager.createBackup();\n \n // Update timestamp\n this.data.lastUpdated = new Date().toISOString();\n \n // Atomic write\n await atomicWriteJSON(storePath, this.data);\n \n this.dirty = false;\n }\n \n /**\n * Generate a content-based key for deduplication\n * Insights with the same content key are considered duplicates\n */\n private getContentKey(insight: GuardianInsight): string {\n // Normalize the message by removing specific numbers/counts that might vary slightly\n // e.g., \"Found 30 security issues\" and \"Found 31 security issues\" are the same insight\n const normalizedMessage = insight.message\n .replace(/\\d+/g, 'N') // Replace all numbers with N\n .toLowerCase()\n .trim();\n \n return `${insight.type}:${insight.category}:${normalizedMessage}`;\n }\n \n /**\n * Add an insight to the store\n * \n * Checks for duplicates using both insight ID and content similarity.\n * If a similar insight already exists (same type, category, and normalized message),\n * updates its timestamp instead of creating a duplicate.\n * Respects cooldowns to prevent insight spam.\n */\n async addInsight(insight: GuardianInsight): Promise<boolean> {\n await this.load();\n \n // Check if already exists by ID\n if (this.data.insights.some(i => i.id === insight.id)) {\n return false;\n }\n \n // Check if ID was previously dismissed (don't re-add)\n if (this.data.dismissedIds.includes(insight.id)) {\n return false;\n }\n \n // Check for content-based duplicates (same type, category, similar message)\n const contentKey = this.getContentKey(insight);\n const existingIndex = this.data.insights.findIndex(i => \n !i.dismissed && this.getContentKey(i) === contentKey\n );\n \n if (existingIndex >= 0) {\n // Update existing insight instead of adding duplicate\n const existing = this.data.insights[existingIndex];\n if (existing) {\n // Update with new data but keep the original ID\n existing.timestamp = insight.timestamp;\n existing.message = insight.message; // Update with current counts\n existing.details = insight.details; // Update details\n existing.relatedIssues = insight.relatedIssues;\n existing.suggestedAction = insight.suggestedAction;\n \n // Move to front of list\n this.data.insights.splice(existingIndex, 1);\n this.data.insights.unshift(existing);\n \n this.dirty = true;\n await this.save();\n }\n return false; // Return false to indicate no new insight was created\n }\n \n // Add to front of list\n this.data.insights.unshift(insight);\n \n // Keep only last 100 insights\n if (this.data.insights.length > 100) {\n this.data.insights = this.data.insights.slice(0, 100);\n }\n \n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Check if a cooldown has expired for an insight type\n */\n canCreateInsight(insightKey: string): boolean {\n const lastTime = this.data.cooldowns[insightKey];\n const cooldown = InsightStore.COOLDOWNS[insightKey] || 30000;\n \n if (!lastTime) return true;\n return Date.now() - lastTime > cooldown;\n }\n \n /**\n * Mark that an insight type was created (set cooldown)\n */\n async markInsightCreated(insightKey: string): Promise<void> {\n await this.load();\n this.data.cooldowns[insightKey] = Date.now();\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Get active (non-dismissed) insights\n * \n * Returns insights sorted by priority (highest first),\n * limited to the specified count.\n */\n getActiveInsights(limit: number = 5): GuardianInsight[] {\n return this.data.insights\n .filter(i => !i.dismissed)\n .sort((a, b) => b.priority - a.priority)\n .slice(0, limit);\n }\n \n /**\n * Get all insights (including dismissed)\n */\n getAllInsights(): GuardianInsight[] {\n return [...this.data.insights];\n }\n \n /**\n * Dismiss an insight by ID\n */\n async dismissInsight(insightId: string): Promise<boolean> {\n await this.load();\n \n const insight = this.data.insights.find(i => i.id === insightId);\n if (!insight) {\n return false;\n }\n \n insight.dismissed = true;\n \n // Track permanently dismissed IDs\n if (!this.data.dismissedIds.includes(insightId)) {\n this.data.dismissedIds.push(insightId);\n \n // Keep only last 500 dismissed IDs\n if (this.data.dismissedIds.length > 500) {\n this.data.dismissedIds = this.data.dismissedIds.slice(-500);\n }\n }\n \n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Remove an insight entirely\n */\n async removeInsight(insightId: string): Promise<boolean> {\n await this.load();\n \n const index = this.data.insights.findIndex(i => i.id === insightId);\n if (index === -1) {\n return false;\n }\n \n this.data.insights.splice(index, 1);\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Clear all cooldowns\n */\n async clearCooldowns(): Promise<void> {\n await this.load();\n this.data.cooldowns = {};\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Get insight by ID\n */\n getInsight(insightId: string): GuardianInsight | undefined {\n return this.data.insights.find(i => i.id === insightId);\n }\n \n /**\n * Update an existing insight\n */\n async updateInsight(insightId: string, updates: Partial<GuardianInsight>): Promise<boolean> {\n await this.load();\n \n const insight = this.data.insights.find(i => i.id === insightId);\n if (!insight) {\n return false;\n }\n \n Object.assign(insight, updates);\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Get insights by category\n */\n getInsightsByCategory(category: GuardianInsight['category']): GuardianInsight[] {\n return this.data.insights.filter(i => i.category === category && !i.dismissed);\n }\n \n /**\n * Get insights by type\n */\n getInsightsByType(type: GuardianInsight['type']): GuardianInsight[] {\n return this.data.insights.filter(i => i.type === type && !i.dismissed);\n }\n \n /**\n * Get insights from the last N hours\n */\n getRecentInsights(hours: number = 24): GuardianInsight[] {\n const cutoff = Date.now() - (hours * 60 * 60 * 1000);\n return this.data.insights.filter(i => i.timestamp >= cutoff);\n }\n \n /**\n * Get statistics about insights\n */\n getStats(): {\n total: number;\n active: number;\n dismissed: number;\n byCategory: Record<string, number>;\n byType: Record<string, number>;\n } {\n const stats = {\n total: this.data.insights.length,\n active: 0,\n dismissed: 0,\n byCategory: {} as Record<string, number>,\n byType: {} as Record<string, number>,\n };\n \n for (const insight of this.data.insights) {\n if (insight.dismissed) {\n stats.dismissed++;\n } else {\n stats.active++;\n }\n \n stats.byCategory[insight.category] = (stats.byCategory[insight.category] || 0) + 1;\n stats.byType[insight.type] = (stats.byType[insight.type] || 0) + 1;\n }\n \n return stats;\n }\n \n /**\n * Prune old insights (older than N days)\n */\n async pruneOldInsights(daysToKeep: number = 30): Promise<number> {\n await this.load();\n \n const cutoff = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000);\n const originalCount = this.data.insights.length;\n \n this.data.insights = this.data.insights.filter(i => i.timestamp >= cutoff);\n \n const pruned = originalCount - this.data.insights.length;\n if (pruned > 0) {\n this.dirty = true;\n await this.save();\n }\n \n return pruned;\n }\n \n /**\n * Check if the store has been loaded\n */\n isLoaded(): boolean {\n return this.loaded;\n }\n \n /**\n * Force reload from disk\n */\n async reload(): Promise<InsightStoreData> {\n this.loaded = false;\n this.dirty = false;\n return this.load();\n }\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst insightStores: Map<string, InsightStore> = new Map();\n\n/**\n * Get the InsightStore for a project (singleton per project)\n */\nexport function getInsightStore(projectPath: string): InsightStore {\n let store = insightStores.get(projectPath);\n if (!store) {\n store = new InsightStore(projectPath);\n insightStores.set(projectPath, store);\n }\n return store;\n}\n\n/**\n * Clear all InsightStore instances (for testing)\n */\nexport function clearInsightStores(): void {\n insightStores.clear();\n}\n"],"mappings":";;;;;;;;;;;;AAeA,SAAS,OAAO,gBAAgB;AAChC,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AAErB,SAAS,SAAS;AAYX,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC5C,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC1D,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACvC,OAAO,EAAE,KAAK,CAAC,aAAa,UAAU,WAAW,CAAC,EAAE,SAAS;AAAA,EAC7D,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,gBAAgB,EAAE,MAAM,EAAE,OAAO;AAAA,IAC/B,MAAM,EAAE,OAAO;AAAA,IACf,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,OAAO,EAAE,OAAO;AAAA,IAChB,OAAO,EAAE,OAAO;AAAA,IAChB,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC,CAAC,EAAE,SAAS;AAAA,EACb,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAE7B,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEhC,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,YAAY,EAAE,OAAO,EAAE,SAAS;AAClC,CAAC;AAKM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,IAAI,EAAE,OAAO;AAAA,EACb,MAAM,EAAE,KAAK,CAAC,eAAe,WAAW,cAAc,eAAe,UAAU,CAAC;AAAA,EAChF,SAAS,EAAE,OAAO;AAAA,EAClB,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,EACjC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,EAClC,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,QAAQ;AAAA,EACrB,UAAU,EAAE,KAAK,CAAC,YAAY,WAAW,eAAe,WAAW,YAAY,SAAS,CAAC;AAAA,EACzF,SAAS,qBAAqB,SAAS;AACzC,CAAC;AAOM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,SAAS,EAAE,QAAQ,CAAC;AAAA,EACpB,UAAU,EAAE,MAAM,qBAAqB;AAAA,EACvC,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC;AAAA;AAAA,EAC1C,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA;AAAA,EAChC,aAAa,EAAE,OAAO;AACxB,CAAC;AAqBM,IAAM,eAAN,MAAM,cAAa;AAAA,EAChB;AAAA,EACA;AAAA,EACA,SAAkB;AAAA,EAClB,QAAiB;AAAA;AAAA,EAGzB,OAAgB,YAAoC;AAAA,IAClD,oBAAoB;AAAA;AAAA,IACpB,oBAAoB;AAAA;AAAA,IACpB,cAAc;AAAA;AAAA,IACd,eAAe;AAAA;AAAA,IACf,sBAAsB;AAAA;AAAA,IACtB,2BAA2B;AAAA;AAAA,IAC3B,mBAAmB;AAAA;AAAA,IACnB,mBAAmB;AAAA;AAAA,IACnB,qBAAqB;AAAA;AAAA,IACrB,mBAAmB;AAAA;AAAA,EACrB;AAAA,EAEA,YAAY,aAAqB;AAC/B,SAAK,cAAc;AACnB,SAAK,OAAO,KAAK,gBAAgB;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAuB;AAC7B,WAAO,KAAK,iBAAiB,KAAK,WAAW,GAAG,UAAU,wBAAwB;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAoC;AAC1C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,CAAC;AAAA,MACX,WAAW,CAAC;AAAA,MACZ,cAAc,CAAC;AAAA,MACf,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAkC;AACtC,QAAI,KAAK,QAAQ;AACf,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,YAAY,KAAK,aAAa;AAEpC,QAAI;AACF,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,UAAU,MAAM,SAAS,WAAW,OAAO;AACjD,cAAM,SAAS,qBAAqB,SAAS,sBAAsB;AAEnE,YAAI,OAAO,SAAS;AAClB,eAAK,OAAO,OAAO;AACnB,eAAK,SAAS;AAEd,eAAK,oBAAoB;AACzB,iBAAO,KAAK;AAAA,QACd;AAGA,gBAAQ,MAAM,+BAA+B,OAAO,KAAK,EAAE;AAC3D,cAAM,gBAAgB,IAAI,cAAc,SAAS;AAEjD,YAAI,MAAM,cAAc,kBAAkB,GAAG;AAC3C,kBAAQ,MAAM,0BAA0B;AACxC,gBAAM,YAAY,MAAM,SAAS,WAAW,OAAO;AACnD,gBAAM,kBAAkB,qBAAqB,WAAW,sBAAsB;AAC9E,cAAI,gBAAgB,SAAS;AAC3B,iBAAK,OAAO,gBAAgB;AAC5B,iBAAK,SAAS;AAEd,iBAAK,oBAAoB;AACzB,mBAAO,KAAK;AAAA,UACd;AAAA,QACF;AAEA,gBAAQ,MAAM,0CAA0C;AAAA,MAC1D;AAAA,IACF,SAAS,OAAO;AAEd,cAAQ,MAAM,oCAAoC,KAAK,EAAE;AAAA,IAC3D;AAEA,SAAK,OAAO,KAAK,gBAAgB;AACjC,SAAK,SAAS;AACd,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,sBAA4B;AAClC,UAAM,OAAO,oBAAI,IAAoB;AACrC,UAAM,WAAqB,CAAC;AAG5B,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK,SAAS,QAAQ,KAAK;AAClD,YAAM,UAAU,KAAK,KAAK,SAAS,CAAC;AACpC,UAAI,CAAC,QAAS;AAEd,YAAM,aAAa,KAAK,cAAc,OAAO;AAE7C,UAAI,KAAK,IAAI,UAAU,GAAG;AAExB,iBAAS,KAAK,CAAC;AAAA,MACjB,OAAO;AACL,aAAK,IAAI,YAAY,CAAC;AAAA,MACxB;AAAA,IACF;AAGA,QAAI,SAAS,SAAS,GAAG;AACvB,eAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,cAAM,MAAM,SAAS,CAAC;AACtB,YAAI,QAAQ,QAAW;AACrB,eAAK,KAAK,SAAS,OAAO,KAAK,CAAC;AAAA,QAClC;AAAA,MACF;AACA,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAsB;AAC1B,QAAI,CAAC,KAAK,SAAS,KAAK,QAAQ;AAC9B;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,YAAY,KAAK,iBAAiB,KAAK,WAAW,GAAG,QAAQ;AAGnE,UAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAG1C,UAAM,gBAAgB,IAAI,cAAc,SAAS;AACjD,UAAM,cAAc,aAAa;AAGjC,SAAK,KAAK,eAAc,oBAAI,KAAK,GAAE,YAAY;AAG/C,UAAM,gBAAgB,WAAW,KAAK,IAAI;AAE1C,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,SAAkC;AAGtD,UAAM,oBAAoB,QAAQ,QAC/B,QAAQ,QAAQ,GAAG,EACnB,YAAY,EACZ,KAAK;AAER,WAAO,GAAG,QAAQ,IAAI,IAAI,QAAQ,QAAQ,IAAI,iBAAiB;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WAAW,SAA4C;AAC3D,UAAM,KAAK,KAAK;AAGhB,QAAI,KAAK,KAAK,SAAS,KAAK,OAAK,EAAE,OAAO,QAAQ,EAAE,GAAG;AACrD,aAAO;AAAA,IACT;AAGA,QAAI,KAAK,KAAK,aAAa,SAAS,QAAQ,EAAE,GAAG;AAC/C,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,KAAK,cAAc,OAAO;AAC7C,UAAM,gBAAgB,KAAK,KAAK,SAAS;AAAA,MAAU,OACjD,CAAC,EAAE,aAAa,KAAK,cAAc,CAAC,MAAM;AAAA,IAC5C;AAEA,QAAI,iBAAiB,GAAG;AAEtB,YAAM,WAAW,KAAK,KAAK,SAAS,aAAa;AACjD,UAAI,UAAU;AAEZ,iBAAS,YAAY,QAAQ;AAC7B,iBAAS,UAAU,QAAQ;AAC3B,iBAAS,UAAU,QAAQ;AAC3B,iBAAS,gBAAgB,QAAQ;AACjC,iBAAS,kBAAkB,QAAQ;AAGnC,aAAK,KAAK,SAAS,OAAO,eAAe,CAAC;AAC1C,aAAK,KAAK,SAAS,QAAQ,QAAQ;AAEnC,aAAK,QAAQ;AACb,cAAM,KAAK,KAAK;AAAA,MAClB;AACA,aAAO;AAAA,IACT;AAGA,SAAK,KAAK,SAAS,QAAQ,OAAO;AAGlC,QAAI,KAAK,KAAK,SAAS,SAAS,KAAK;AACnC,WAAK,KAAK,WAAW,KAAK,KAAK,SAAS,MAAM,GAAG,GAAG;AAAA,IACtD;AAEA,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAEhB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,YAA6B;AAC5C,UAAM,WAAW,KAAK,KAAK,UAAU,UAAU;AAC/C,UAAM,WAAW,cAAa,UAAU,UAAU,KAAK;AAEvD,QAAI,CAAC,SAAU,QAAO;AACtB,WAAO,KAAK,IAAI,IAAI,WAAW;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAmB,YAAmC;AAC1D,UAAM,KAAK,KAAK;AAChB,SAAK,KAAK,UAAU,UAAU,IAAI,KAAK,IAAI;AAC3C,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBAAkB,QAAgB,GAAsB;AACtD,WAAO,KAAK,KAAK,SACd,OAAO,OAAK,CAAC,EAAE,SAAS,EACxB,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EACtC,MAAM,GAAG,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAoC;AAClC,WAAO,CAAC,GAAG,KAAK,KAAK,QAAQ;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,WAAqC;AACxD,UAAM,KAAK,KAAK;AAEhB,UAAM,UAAU,KAAK,KAAK,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AAC/D,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,YAAQ,YAAY;AAGpB,QAAI,CAAC,KAAK,KAAK,aAAa,SAAS,SAAS,GAAG;AAC/C,WAAK,KAAK,aAAa,KAAK,SAAS;AAGrC,UAAI,KAAK,KAAK,aAAa,SAAS,KAAK;AACvC,aAAK,KAAK,eAAe,KAAK,KAAK,aAAa,MAAM,IAAI;AAAA,MAC5D;AAAA,IACF;AAEA,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAEhB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,WAAqC;AACvD,UAAM,KAAK,KAAK;AAEhB,UAAM,QAAQ,KAAK,KAAK,SAAS,UAAU,OAAK,EAAE,OAAO,SAAS;AAClE,QAAI,UAAU,IAAI;AAChB,aAAO;AAAA,IACT;AAEA,SAAK,KAAK,SAAS,OAAO,OAAO,CAAC;AAClC,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAEhB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAgC;AACpC,UAAM,KAAK,KAAK;AAChB,SAAK,KAAK,YAAY,CAAC;AACvB,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,WAAgD;AACzD,WAAO,KAAK,KAAK,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,WAAmB,SAAqD;AAC1F,UAAM,KAAK,KAAK;AAEhB,UAAM,UAAU,KAAK,KAAK,SAAS,KAAK,OAAK,EAAE,OAAO,SAAS;AAC/D,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,WAAO,OAAO,SAAS,OAAO;AAC9B,SAAK,QAAQ;AACb,UAAM,KAAK,KAAK;AAEhB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,UAA0D;AAC9E,WAAO,KAAK,KAAK,SAAS,OAAO,OAAK,EAAE,aAAa,YAAY,CAAC,EAAE,SAAS;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,MAAkD;AAClE,WAAO,KAAK,KAAK,SAAS,OAAO,OAAK,EAAE,SAAS,QAAQ,CAAC,EAAE,SAAS;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,QAAgB,IAAuB;AACvD,UAAM,SAAS,KAAK,IAAI,IAAK,QAAQ,KAAK,KAAK;AAC/C,WAAO,KAAK,KAAK,SAAS,OAAO,OAAK,EAAE,aAAa,MAAM;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,WAME;AACA,UAAM,QAAQ;AAAA,MACZ,OAAO,KAAK,KAAK,SAAS;AAAA,MAC1B,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,YAAY,CAAC;AAAA,MACb,QAAQ,CAAC;AAAA,IACX;AAEA,eAAW,WAAW,KAAK,KAAK,UAAU;AACxC,UAAI,QAAQ,WAAW;AACrB,cAAM;AAAA,MACR,OAAO;AACL,cAAM;AAAA,MACR;AAEA,YAAM,WAAW,QAAQ,QAAQ,KAAK,MAAM,WAAW,QAAQ,QAAQ,KAAK,KAAK;AACjF,YAAM,OAAO,QAAQ,IAAI,KAAK,MAAM,OAAO,QAAQ,IAAI,KAAK,KAAK;AAAA,IACnE;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAiB,aAAqB,IAAqB;AAC/D,UAAM,KAAK,KAAK;AAEhB,UAAM,SAAS,KAAK,IAAI,IAAK,aAAa,KAAK,KAAK,KAAK;AACzD,UAAM,gBAAgB,KAAK,KAAK,SAAS;AAEzC,SAAK,KAAK,WAAW,KAAK,KAAK,SAAS,OAAO,OAAK,EAAE,aAAa,MAAM;AAEzE,UAAM,SAAS,gBAAgB,KAAK,KAAK,SAAS;AAClD,QAAI,SAAS,GAAG;AACd,WAAK,QAAQ;AACb,YAAM,KAAK,KAAK;AAAA,IAClB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,WAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAoC;AACxC,SAAK,SAAS;AACd,SAAK,QAAQ;AACb,WAAO,KAAK,KAAK;AAAA,EACnB;AACF;AAMA,IAAM,gBAA2C,oBAAI,IAAI;AAKlD,SAAS,gBAAgB,aAAmC;AACjE,MAAI,QAAQ,cAAc,IAAI,WAAW;AACzC,MAAI,CAAC,OAAO;AACV,YAAQ,IAAI,aAAa,WAAW;AACpC,kBAAc,IAAI,aAAa,KAAK;AAAA,EACtC;AACA,SAAO;AACT;AAKO,SAAS,qBAA2B;AACzC,gBAAc,MAAM;AACtB;","names":[]}