blade-code 0.7.8 → 0.8.0
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.
- package/dist/blade.js +2 -2
- package/dist/{chunk-rnfd5ebv.js → chunk-06h100e2.js} +1 -1
- package/dist/chunk-07jvw0kn.js +1 -0
- package/dist/chunk-0dj326ms.js +5 -0
- package/dist/chunk-14erxdhd.js +1 -0
- package/dist/{chunk-48q9msfk.js → chunk-1pt090dg.js} +38 -38
- package/dist/{chunk-cjmxggke.js → chunk-1smf2dj3.js} +2 -2
- package/dist/chunk-34pdtz4q.js +3 -0
- package/dist/chunk-3gw66r7a.js +2 -0
- package/dist/chunk-49g067ek.js +41 -0
- package/dist/chunk-6es6av6j.js +2 -0
- package/dist/{chunk-g7caymjr.js → chunk-9ad7tt9s.js} +1 -1
- package/dist/{chunk-jm2xhnrv.js → chunk-9xkjb87h.js} +1 -1
- package/dist/chunk-a12tmmfr.js +1 -0
- package/dist/chunk-bggvft3z.js +1 -0
- package/dist/{chunk-0e0z8yc1.js → chunk-bm8vwfez.js} +2 -2
- package/dist/chunk-bxbagv76.js +9 -0
- package/dist/chunk-ctqf59q1.js +2 -0
- package/dist/chunk-d08wbxjr.js +1 -0
- package/dist/chunk-d4ex0qvs.js +2 -0
- package/dist/{chunk-f9ybv4ph.js → chunk-dr06x0cw.js} +1 -1
- package/dist/chunk-e4a240t7.js +34 -0
- package/dist/{chunk-4dmdn3a9.js → chunk-gsfkrr25.js} +1 -1
- package/dist/chunk-gytwh5y1.js +6 -0
- package/dist/chunk-hjx5n3dw.js +3 -0
- package/dist/chunk-hrnd3wjg.js +6 -0
- package/dist/chunk-j39q2kx7.js +1 -0
- package/dist/{chunk-4745ktjj.js → chunk-jakzknh3.js} +299 -299
- package/dist/chunk-jqr2pknb.js +151 -0
- package/dist/{chunk-t70aqrm4.js → chunk-jt62ctz7.js} +1 -1
- package/dist/{chunk-t2spryz0.js → chunk-kawv31m3.js} +1 -1
- package/dist/chunk-n8ymp6nd.js +1 -0
- package/dist/{chunk-s4mke0t6.js → chunk-nned222j.js} +1 -1
- package/dist/chunk-qwdbqjh7.js +22 -0
- package/dist/chunk-syj3anec.js +6 -0
- package/dist/chunk-tv4r86ez.js +24 -0
- package/dist/chunk-twem6p0g.js +2 -0
- package/dist/chunk-v3ctg84r.js +1 -0
- package/dist/chunk-v5rn5r1h.js +1 -0
- package/dist/{chunk-fb7amc2s.js → chunk-wmes2tt9.js} +1 -1
- package/dist/chunk-xhnyy54e.js +2 -0
- package/dist/{chunk-9kejtkey.js → chunk-ychj0e5q.js} +1 -1
- package/dist/{chunk-71n472hj.js → chunk-ydb9myhe.js} +1 -1
- package/dist/{chunk-6hn2jgw5.js → chunk-yhpm9azy.js} +1 -1
- package/dist/{chunk-g6ted982.js → chunk-yqxw7zz4.js} +1 -1
- package/dist/web/assets/{FilePreview-DRKRs8i2.js → FilePreview-DvgnEspB.js} +1 -1
- package/dist/web/assets/{MarkdownRenderer-DFqPpAnM.js → MarkdownRenderer-e1ZUy6jV.js} +1 -1
- package/dist/web/assets/{McpModal-CX5-hlNv.js → McpModal-Raois2g1.js} +1 -1
- package/dist/web/assets/SettingsModal-Dzuatoea.js +1 -0
- package/dist/web/assets/{SettingsStore-jup_Kikq.js → SettingsStore-BxDA0Usw.js} +1 -1
- package/dist/web/assets/{SkillsModal-DaAUrwXO.js → SkillsModal-Cg2-befH.js} +1 -1
- package/dist/web/assets/{TerminalPanel-DzlllDH7.js → TerminalPanel-CEoQI9Lu.js} +1 -1
- package/dist/web/assets/index-BvGeIa_-.js +16 -0
- package/dist/web/assets/index-DDJnZJcp.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +4 -11
- package/dist/chunk-1w6tqkxd.js +0 -34
- package/dist/chunk-2049tv49.js +0 -41
- package/dist/chunk-5be6qr2v.js +0 -2
- package/dist/chunk-67vzgcs5.js +0 -2
- package/dist/chunk-6811kbxn.js +0 -1
- package/dist/chunk-6js5wp6t.js +0 -1
- package/dist/chunk-6kp3z956.js +0 -9
- package/dist/chunk-78txnq4n.js +0 -151
- package/dist/chunk-7r1hm0qz.js +0 -6
- package/dist/chunk-a7yjnqhd.js +0 -3
- package/dist/chunk-bwaqaktn.js +0 -1
- package/dist/chunk-cb82rf5h.js +0 -1
- package/dist/chunk-ce11m8bq.js +0 -1
- package/dist/chunk-e4rhdg3h.js +0 -1
- package/dist/chunk-faq7ay4j.js +0 -24
- package/dist/chunk-ky8ctbdc.js +0 -1
- package/dist/chunk-mpskff34.js +0 -1
- package/dist/chunk-pd1yqxcv.js +0 -9
- package/dist/chunk-phhmmybg.js +0 -2
- package/dist/chunk-qnevwq1q.js +0 -2
- package/dist/chunk-r1spf93b.js +0 -26
- package/dist/chunk-z4c68ve0.js +0 -6
- package/dist/chunk-z9zbcenc.js +0 -6
- package/dist/web/assets/SettingsModal-CfR_q6N7.js +0 -1
- package/dist/web/assets/index-BJTSF3fc.js +0 -9
- package/dist/web/assets/index-CL6apjgo.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:JetBrains Mono,monospace;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:JetBrains Mono,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 100%;--foreground: 240 10% 3.9%;--sidebar-background: 240 4.8% 95.9%;--card: 0 0% 100%;--card-foreground: 240 10% 3.9%;--popover: 0 0% 100%;--popover-foreground: 240 10% 3.9%;--primary: 240 5.9% 10%;--primary-foreground: 0 0% 98%;--secondary: 240 4.8% 95.9%;--secondary-foreground: 240 5.9% 10%;--muted: 240 4.8% 95.9%;--muted-foreground: 240 3.8% 46.1%;--accent: 240 4.8% 95.9%;--accent-foreground: 240 5.9% 10%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 0 0% 98%;--border: 240 5.9% 90%;--input: 240 5.9% 90%;--ring: 240 10% 3.9%;--radius: .5rem;--success: 142 76% 36%;--success-foreground: 0 0% 100%;--warning: 38 92% 50%;--warning-foreground: 0 0% 0%;--info: 217 91% 60%;--info-foreground: 0 0% 100%;--panel: 240 4.8% 95.9%;--panel-foreground: 240 10% 3.9%;--panel-hover: 240 4.8% 90%;--panel-active: 240 4.8% 85%;--subtle: 240 3.8% 46.1%;--subtle-foreground: 240 5.9% 10%}.dark{--background: 0 0% 4.7%;--foreground: 0 0% 98%;--card: 240 10% 3.9%;--card-foreground: 0 0% 98%;--popover: 240 10% 3.9%;--popover-foreground: 0 0% 98%;--primary: 0 0% 98%;--primary-foreground: 240 5.9% 10%;--secondary: 240 3.7% 15.9%;--secondary-foreground: 0 0% 98%;--muted: 240 3.7% 15.9%;--muted-foreground: 240 5% 64.9%;--accent: 240 3.7% 15.9%;--accent-foreground: 0 0% 98%;--destructive: 0 62.8% 30.6%;--destructive-foreground: 0 0% 98%;--border: 240 3.7% 15.9%;--input: 240 3.7% 15.9%;--ring: 240 4.9% 83.9%;--sidebar-background: 240 10% 3.9%;--success: 142 71% 45%;--success-foreground: 0 0% 0%;--warning: 38 92% 50%;--warning-foreground: 0 0% 0%;--info: 217 91% 60%;--info-foreground: 0 0% 100%;--panel: 240 6% 10%;--panel-foreground: 0 0% 90%;--panel-hover: 240 5% 17%;--panel-active: 220 13% 13%;--subtle: 240 5% 65%;--subtle-foreground: 0 0% 98%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.\!visible{visibility:visible!important}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-0{bottom:0}.bottom-full{bottom:100%}.left-0{left:0}.left-\[50\%\]{left:50%}.right-0{right:0}.right-1{right:.25rem}.right-3{right:.75rem}.right-4{right:1rem}.top-1{top:.25rem}.top-1\/2{top:50%}.top-4{top:1rem}.top-\[50\%\]{top:50%}.top-full{top:100%}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-4{margin-left:1rem;margin-right:1rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-auto{margin-left:auto}.mr-2{margin-right:.5rem}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-auto{margin-top:auto}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-20{height:5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-72{height:18rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[220px\]{height:220px}.h-\[34px\]{height:34px}.h-\[600px\]{height:600px}.h-\[620px\]{height:620px}.h-\[680px\]{height:680px}.h-\[calc\(100\%-40px\)\]{height:calc(100% - 40px)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-64{max-height:16rem}.max-h-72{max-height:18rem}.max-h-\[120px\]{max-height:120px}.max-h-\[160px\]{max-height:160px}.max-h-\[200px\]{max-height:200px}.max-h-\[240px\]{max-height:240px}.max-h-\[310px\]{max-height:310px}.min-h-0{min-height:0px}.min-h-\[140px\]{min-height:140px}.min-h-\[260px\]{min-height:260px}.min-h-\[62px\]{min-height:62px}.min-h-\[80px\]{min-height:80px}.min-h-\[88px\]{min-height:88px}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-40{width:10rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-\[200px\]{width:200px}.w-\[220px\]{width:220px}.w-\[260px\]{width:260px}.w-\[45\%\]{width:45%}.w-\[55\%\]{width:55%}.w-\[62px\]{width:62px}.w-\[64px\]{width:64px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\[420px\]{min-width:420px}.max-w-4xl{max-width:56rem}.max-w-\[220px\]{max-width:220px}.max-w-\[420px\]{max-width:420px}.max-w-\[620px\]{max-width:620px}.max-w-\[85\%\]{max-width:85%}.max-w-\[860px\]{max-width:860px}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-\[--radix-popover-content-transform-origin\]{transform-origin:var(--radix-popover-content-transform-origin)}.origin-\[--radix-tooltip-content-transform-origin\]{transform-origin:var(--radix-tooltip-content-transform-origin)}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-5{--tw-translate-x: 1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize-y{resize:vertical}.resize{resize:both}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[1fr_180px_120px\]{grid-template-columns:1fr 180px 120px}.grid-cols-\[220px_1fr\]{grid-template-columns:220px 1fr}.grid-cols-\[40px_40px_1fr\]{grid-template-columns:40px 40px 1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.gap-y-2{row-gap:.5rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-\[\#E5E7EB\]>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(229 231 235 / var(--tw-divide-opacity, 1))}.self-end{align-self:flex-end}.\!overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-0{border-width:0px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-\[\#16A34A\]\/30{border-color:#16a34a4d}.border-\[\#22C55E\]{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.border-\[\#CFCFD6\]{--tw-border-opacity: 1;border-color:rgb(207 207 214 / var(--tw-border-opacity, 1))}.border-\[\#D1D5DB\]{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-\[\#D9DBE2\]{--tw-border-opacity: 1;border-color:rgb(217 219 226 / var(--tw-border-opacity, 1))}.border-\[\#DDD6FE\]{--tw-border-opacity: 1;border-color:rgb(221 214 254 / var(--tw-border-opacity, 1))}.border-\[\#E1E2E7\]{--tw-border-opacity: 1;border-color:rgb(225 226 231 / var(--tw-border-opacity, 1))}.border-\[\#E5E7EB\]{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-\[\#FCA5A5\]{--tw-border-opacity: 1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-input{border-color:hsl(var(--input))}.border-rose-200{--tw-border-opacity: 1;border-color:rgb(254 205 211 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-violet-200{--tw-border-opacity: 1;border-color:rgb(221 214 254 / var(--tw-border-opacity, 1))}.border-l-transparent{border-left-color:transparent}.border-t-transparent{border-top-color:transparent}.bg-\[\#111827\]{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-\[\#16A34A\]{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-\[\#16A34A\]\/10{background-color:#16a34a1a}.bg-\[\#16A34A\]\/20{background-color:#16a34a33}.bg-\[\#22C55E\]{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-\[\#22C55E\]\/10{background-color:#22c55e1a}.bg-\[\#22C55E\]\/20{background-color:#22c55e33}.bg-\[\#3B82F6\]{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-\[\#3b82f6\]\/20{background-color:#3b82f633}.bg-\[\#6366F1\]{--tw-bg-opacity: 1;background-color:rgb(99 102 241 / var(--tw-bg-opacity, 1))}.bg-\[\#7C3AED\]{--tw-bg-opacity: 1;background-color:rgb(124 58 237 / var(--tw-bg-opacity, 1))}.bg-\[\#DBEAFE\]{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-\[\#DCFCE7\]{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-\[\#E1E2E7\]{--tw-bg-opacity: 1;background-color:rgb(225 226 231 / var(--tw-bg-opacity, 1))}.bg-\[\#E5E7EB\]{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-\[\#EDE9FE\]{--tw-bg-opacity: 1;background-color:rgb(237 233 254 / var(--tw-bg-opacity, 1))}.bg-\[\#EF4444\]{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-\[\#EF4444\]\/10{background-color:#ef44441a}.bg-\[\#F0FDF4\]{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-\[\#F3F4F6\]{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-\[\#F5F3FF\]{--tw-bg-opacity: 1;background-color:rgb(245 243 255 / var(--tw-bg-opacity, 1))}.bg-\[\#F8F8FA\]{--tw-bg-opacity: 1;background-color:rgb(248 248 250 / var(--tw-bg-opacity, 1))}.bg-\[\#F9FAFB\]{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-\[\#FEE2E2\]{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-\[\#FEF3C7\]{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-accent{background-color:hsl(var(--accent))}.bg-amber-400{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-background{background-color:hsl(var(--background))}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/5{background-color:#0000000d}.bg-black\/70{background-color:#000000b3}.bg-black\/80{background-color:#000c}.bg-border{background-color:hsl(var(--border))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-muted{background-color:hsl(var(--muted))}.bg-orange-500{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-rose-50{--tw-bg-opacity: 1;background-color:rgb(255 241 242 / var(--tw-bg-opacity, 1))}.bg-rose-500{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity, 1))}.bg-rose-600{--tw-bg-opacity: 1;background-color:rgb(225 29 72 / var(--tw-bg-opacity, 1))}.bg-secondary{background-color:hsl(var(--secondary))}.bg-transparent{background-color:transparent}.bg-violet-400{--tw-bg-opacity: 1;background-color:rgb(167 139 250 / var(--tw-bg-opacity, 1))}.bg-violet-600{--tw-bg-opacity: 1;background-color:rgb(124 58 237 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/55{background-color:#ffffff8c}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-zinc-100{--tw-bg-opacity: 1;background-color:rgb(244 244 245 / var(--tw-bg-opacity, 1))}.bg-zinc-600{--tw-bg-opacity: 1;background-color:rgb(82 82 91 / var(--tw-bg-opacity, 1))}.stroke-\[3\]{stroke-width:3}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.p-\[1px\]{padding:1px}.px-0{padding-left:0;padding-right:0}.px-0\.5{padding-left:.125rem;padding-right:.125rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pr-1{padding-right:.25rem}.pr-10{padding-right:2.5rem}.pr-2{padding-right:.5rem}.pr-3{padding-right:.75rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:JetBrains Mono,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.leading-none{line-height:1}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.tracking-\[0\.14em\]{letter-spacing:.14em}.tracking-tight{letter-spacing:-.025em}.text-\[\#111827\]{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-\[\#15803D\]{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-\[\#166534\]{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-\[\#16A34A\]{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-\[\#1D4ED8\],.text-\[\#1d4ed8\]{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-\[\#22C55E\]{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-\[\#252932\]{--tw-text-opacity: 1;color:rgb(37 41 50 / var(--tw-text-opacity, 1))}.text-\[\#2563eb\]{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-\[\#272A31\]{--tw-text-opacity: 1;color:rgb(39 42 49 / var(--tw-text-opacity, 1))}.text-\[\#374151\]{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-\[\#3b82f6\]{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-\[\#4B5563\]{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-\[\#4F5561\]{--tw-text-opacity: 1;color:rgb(79 85 97 / var(--tw-text-opacity, 1))}.text-\[\#555B66\]{--tw-text-opacity: 1;color:rgb(85 91 102 / var(--tw-text-opacity, 1))}.text-\[\#5B21B6\]{--tw-text-opacity: 1;color:rgb(91 33 182 / var(--tw-text-opacity, 1))}.text-\[\#5F6470\]{--tw-text-opacity: 1;color:rgb(95 100 112 / var(--tw-text-opacity, 1))}.text-\[\#6B7280\]{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-\[\#6D28D9\]{--tw-text-opacity: 1;color:rgb(109 40 217 / var(--tw-text-opacity, 1))}.text-\[\#6F7480\]{--tw-text-opacity: 1;color:rgb(111 116 128 / var(--tw-text-opacity, 1))}.text-\[\#737986\]{--tw-text-opacity: 1;color:rgb(115 121 134 / var(--tw-text-opacity, 1))}.text-\[\#858A96\]{--tw-text-opacity: 1;color:rgb(133 138 150 / var(--tw-text-opacity, 1))}.text-\[\#8B909C\]{--tw-text-opacity: 1;color:rgb(139 144 156 / var(--tw-text-opacity, 1))}.text-\[\#92400E\]{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-\[\#9CA3AF\]{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-\[\#DC2626\]{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-\[\#b45309\]{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-\[\#b91c1c\]{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-\[\#ef4444\]{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-\[\#f59e0b\]{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-\[\#f87171\]{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-cyan-600{--tw-text-opacity: 1;color:rgb(8 145 178 / var(--tw-text-opacity, 1))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-emerald-500{--tw-text-opacity: 1;color:rgb(16 185 129 / var(--tw-text-opacity, 1))}.text-emerald-600{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-rose-600{--tw-text-opacity: 1;color:rgb(225 29 72 / var(--tw-text-opacity, 1))}.text-rose-700{--tw-text-opacity: 1;color:rgb(190 18 60 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-violet-500{--tw-text-opacity: 1;color:rgb(139 92 246 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-zinc-400{--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.text-zinc-500{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.underline-offset-4{text-underline-offset:4px}.accent-\[\#16A34A\]{accent-color:#16A34A}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-\[0_0_4px_rgba\(34\,197\,94\,0\.4\)\]{--tw-shadow: 0 0 4px rgba(34,197,94,.4);--tw-shadow-colored: 0 0 4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(167\,139\,250\,0\.65\)\]{--tw-shadow: 0 0 8px rgba(167,139,250,.65);--tw-shadow-colored: 0 0 8px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_1px_2px_rgba\(15\,23\,42\,0\.04\)\]{--tw-shadow: 0 1px 2px rgba(15,23,42,.04);--tw-shadow-colored: 0 1px 2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.delay-100{transition-delay:.1s}.delay-200{transition-delay:.2s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}@keyframes enter{0%{opacity:var(--tw-enter-opacity, 1);transform:translate3d(var(--tw-enter-translate-x, 0),var(--tw-enter-translate-y, 0),0) scale3d(var(--tw-enter-scale, 1),var(--tw-enter-scale, 1),var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity, 1);transform:translate3d(var(--tw-exit-translate-x, 0),var(--tw-exit-translate-y, 0),0) scale3d(var(--tw-exit-scale, 1),var(--tw-exit-scale, 1),var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))}}.animate-in{animation-name:enter;animation-duration:.15s;--tw-enter-opacity: initial;--tw-enter-scale: initial;--tw-enter-rotate: initial;--tw-enter-translate-x: initial;--tw-enter-translate-y: initial}.fade-in-0{--tw-enter-opacity: 0}.zoom-in-95{--tw-enter-scale: .95}.duration-200{animation-duration:.2s}.duration-300{animation-duration:.3s}.delay-100{animation-delay:.1s}.delay-200{animation-delay:.2s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.running{animation-play-state:running}.paused{animation-play-state:paused}.placeholder\:text-\[\#9CA3AF\]::-moz-placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.placeholder\:text-\[\#9CA3AF\]::placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.last\:mb-0:last-child{margin-bottom:0}.focus-within\:border-\[\#D1D5DB\]:focus-within{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.focus-within\:ring-1:focus-within{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-within\:ring-\[\#D1D5DB\]:focus-within{--tw-ring-opacity: 1;--tw-ring-color: rgb(209 213 219 / var(--tw-ring-opacity, 1))}.hover\:bg-\[\#0F172A\]:hover{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#15803D\]:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#16A34A\]:hover{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#2563EB\]:hover{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#4F46E5\]:hover{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#D1D5DB\]:hover{--tw-bg-opacity: 1;background-color:rgb(209 213 219 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#DC2626\]:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#E5E7EB\]:hover{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#E5E7EB\]\/60:hover{background-color:#e5e7eb99}.hover\:bg-\[\#F3F4F6\]:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#F4F4F6\]:hover{--tw-bg-opacity: 1;background-color:rgb(244 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-\[\#F9FAFB\]:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-black\/5:hover{background-color:#0000000d}.hover\:bg-black\/\[0\.025\]:hover{background-color:#00000006}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-red-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-rose-500:hover{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity, 1))}.hover\:bg-rose-500\/10:hover{background-color:#f43f5e1a}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:bg-violet-500:hover{--tw-bg-opacity: 1;background-color:rgb(139 92 246 / var(--tw-bg-opacity, 1))}.hover\:text-\[\#111827\]:hover{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.hover\:text-\[\#252932\]:hover{--tw-text-opacity: 1;color:rgb(37 41 50 / var(--tw-text-opacity, 1))}.hover\:text-\[\#7f1d1d\]:hover{--tw-text-opacity: 1;color:rgb(127 29 29 / var(--tw-text-opacity, 1))}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-red-500:hover{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.hover\:text-rose-600:hover{--tw-text-opacity: 1;color:rgb(225 29 72 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.focus\:border-\[\#22C55E\]:focus{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.focus\:border-\[\#8B5CF6\]:focus{--tw-border-opacity: 1;border-color:rgb(139 92 246 / var(--tw-border-opacity, 1))}.focus\:border-\[\#E5E7EB\]:focus{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.focus\:border-violet-400:focus{--tw-border-opacity: 1;border-color:rgb(167 139 250 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-\[\#22C55E\]:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(34 197 94 / var(--tw-ring-opacity, 1))}.focus\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus\:ring-violet-400\/20:focus{--tw-ring-color: rgb(167 139 250 / .2)}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-0:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-inset:focus-visible{--tw-ring-inset: inset}.focus-visible\:ring-\[\#22C55E\]:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(34 197 94 / var(--tw-ring-opacity, 1))}.focus-visible\:ring-red-500:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1))}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-violet-500\/50:focus-visible{--tw-ring-color: rgb(139 92 246 / .5)}.focus-visible\:ring-offset-0:focus-visible{--tw-ring-offset-width: 0px}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-\[\#E5E7EB\]:disabled{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.disabled\:text-\[\#9CA3AF\]:disabled{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.disabled\:opacity-35:disabled{opacity:.35}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.group:focus-within .group-focus-within\:opacity-100{opacity:1}.group:hover .group-hover\:opacity-100{opacity:1}.data-\[state\=active\]\:bg-\[\#E5E7EB\][data-state=active]{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:hsl(var(--accent))}.data-\[state\=active\]\:text-\[\#111827\][data-state=active]{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:hsl(var(--muted-foreground))}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\[state\=open\]\:animate-in[data-state=open]{animation-name:enter;animation-duration:.15s;--tw-enter-opacity: initial;--tw-enter-scale: initial;--tw-enter-rotate: initial;--tw-enter-translate-x: initial;--tw-enter-translate-y: initial}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation-name:exit;animation-duration:.15s;--tw-exit-opacity: initial;--tw-exit-scale: initial;--tw-exit-rotate: initial;--tw-exit-translate-x: initial;--tw-exit-translate-y: initial}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity: 0}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity: 0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale: .95}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale: .95}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y: -.5rem}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x: .5rem}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x: -.5rem}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y: .5rem}.data-\[state\=closed\]\:slide-out-to-left-1\/2[data-state=closed]{--tw-exit-translate-x: -50%}.data-\[state\=closed\]\:slide-out-to-top-\[48\%\][data-state=closed]{--tw-exit-translate-y: -48%}.data-\[state\=open\]\:slide-in-from-left-1\/2[data-state=open]{--tw-enter-translate-x: -50%}.data-\[state\=open\]\:slide-in-from-top-\[48\%\][data-state=open]{--tw-enter-translate-y: -48%}.dark\:divide-\[\#27272a\]:is(.dark *)>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(39 39 42 / var(--tw-divide-opacity, 1))}.dark\:border-\[\#1f2937\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(31 41 55 / var(--tw-border-opacity, 1))}.dark\:border-\[\#22C55E\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.dark\:border-\[\#22C55E\]\/30:is(.dark *){border-color:#22c55e4d}.dark\:border-\[\#27272a\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(39 39 42 / var(--tw-border-opacity, 1))}.dark\:border-\[\#30323A\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(48 50 58 / var(--tw-border-opacity, 1))}.dark\:border-\[\#3A3C45\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(58 60 69 / var(--tw-border-opacity, 1))}.dark\:border-\[\#3f3f46\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(63 63 70 / var(--tw-border-opacity, 1))}.dark\:border-\[\#4C1D95\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(76 29 149 / var(--tw-border-opacity, 1))}.dark\:border-\[\#52525b\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(82 82 91 / var(--tw-border-opacity, 1))}.dark\:border-\[\#7f1d1d\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(127 29 29 / var(--tw-border-opacity, 1))}.dark\:border-amber-400\/15:is(.dark *){border-color:#fbbf2426}.dark\:border-rose-900\/60:is(.dark *){border-color:#88133799}.dark\:border-violet-400\/20:is(.dark *){border-color:#a78bfa33}.dark\:border-zinc-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(63 63 70 / var(--tw-border-opacity, 1))}.dark\:border-zinc-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(39 39 42 / var(--tw-border-opacity, 1))}.dark\:bg-\[\#052E16\]\/50:is(.dark *){background-color:#052e1680}.dark\:bg-\[\#09090b\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(9 9 11 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#0C0C0C\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(12 12 12 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#0a0a0a\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(10 10 10 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#111113\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 17 19 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#111217\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 18 23 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#111827\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#17181D\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(23 24 29 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#18181b\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#1E1B4B\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 27 75 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#1e1e1e\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 30 30 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#1e3a8a\]\/30:is(.dark *){background-color:#1e3a8a4d}.dark\:bg-\[\#1f2937\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#22C55E\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#22C55E\]\/10:is(.dark *){background-color:#22c55e1a}.dark\:bg-\[\#22C55E\]\/20:is(.dark *){background-color:#22c55e33}.dark\:bg-\[\#27272a\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#272932\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 41 50 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#2E1065\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(46 16 101 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#30323A\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(48 50 58 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#3B82F6\]\/20:is(.dark *){background-color:#3b82f633}.dark\:bg-\[\#3f1d1d\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(63 29 29 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#E5E5E5\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(229 229 229 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#EF4444\]\/10:is(.dark *){background-color:#ef44441a}.dark\:bg-\[\#EF4444\]\/20:is(.dark *){background-color:#ef444433}.dark\:bg-\[\#F59E0B\]\/20:is(.dark *){background-color:#f59e0b33}.dark\:bg-\[\#a1a1aa\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(161 161 170 / var(--tw-bg-opacity, 1))}.dark\:bg-amber-400\/\[0\.06\]:is(.dark *){background-color:#fbbf240f}.dark\:bg-black\/10:is(.dark *){background-color:#0000001a}.dark\:bg-rose-950\/30:is(.dark *){background-color:#4c05194d}.dark\:bg-transparent:is(.dark *){background-color:transparent}.dark\:bg-white:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.dark\:bg-white\/\[0\.06\]:is(.dark *){background-color:#ffffff0f}.dark\:bg-zinc-100:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(244 244 245 / var(--tw-bg-opacity, 1))}.dark\:bg-zinc-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.dark\:bg-zinc-800\/50:is(.dark *){background-color:#27272a80}.dark\:bg-zinc-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.dark\:bg-zinc-900\/50:is(.dark *){background-color:#18181b80}.dark\:bg-zinc-950\/50:is(.dark *){background-color:#09090b80}.dark\:text-\[\#0C0C0C\]:is(.dark *){--tw-text-opacity: 1;color:rgb(12 12 12 / var(--tw-text-opacity, 1))}.dark\:text-\[\#22C55E\]:is(.dark *){--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.dark\:text-\[\#3b82f6\]:is(.dark *){--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.dark\:text-\[\#52525b\]:is(.dark *){--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.dark\:text-\[\#60A5FA\]:is(.dark *){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-\[\#71717a\]:is(.dark *){--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.dark\:text-\[\#777C89\]:is(.dark *){--tw-text-opacity: 1;color:rgb(119 124 137 / var(--tw-text-opacity, 1))}.dark\:text-\[\#86efac\]:is(.dark *){--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.dark\:text-\[\#93c5fd\]:is(.dark *){--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.dark\:text-\[\#94a3b8\]:is(.dark *){--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.dark\:text-\[\#A2A6B1\]:is(.dark *){--tw-text-opacity: 1;color:rgb(162 166 177 / var(--tw-text-opacity, 1))}.dark\:text-\[\#A5A9B3\]:is(.dark *){--tw-text-opacity: 1;color:rgb(165 169 179 / var(--tw-text-opacity, 1))}.dark\:text-\[\#A9ACB8\]:is(.dark *){--tw-text-opacity: 1;color:rgb(169 172 184 / var(--tw-text-opacity, 1))}.dark\:text-\[\#C1C4CC\]:is(.dark *){--tw-text-opacity: 1;color:rgb(193 196 204 / var(--tw-text-opacity, 1))}.dark\:text-\[\#C4B5FD\]:is(.dark *){--tw-text-opacity: 1;color:rgb(196 181 253 / var(--tw-text-opacity, 1))}.dark\:text-\[\#E3E4E8\]:is(.dark *){--tw-text-opacity: 1;color:rgb(227 228 232 / var(--tw-text-opacity, 1))}.dark\:text-\[\#E5E5E5\]:is(.dark *){--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.dark\:text-\[\#FBBF24\]:is(.dark *){--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.dark\:text-\[\#a1a1aa\]:is(.dark *){--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.dark\:text-\[\#d4d4d8\]:is(.dark *){--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.dark\:text-\[\#f4f4f5\]:is(.dark *){--tw-text-opacity: 1;color:rgb(244 244 245 / var(--tw-text-opacity, 1))}.dark\:text-\[\#facc15\]:is(.dark *){--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.dark\:text-\[\#fca5a5\]:is(.dark *){--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.dark\:text-amber-200:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.dark\:text-amber-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.dark\:text-blue-400:is(.dark *){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-cyan-400:is(.dark *){--tw-text-opacity: 1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.dark\:text-emerald-300:is(.dark *){--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.dark\:text-orange-300:is(.dark *){--tw-text-opacity: 1;color:rgb(253 186 116 / var(--tw-text-opacity, 1))}.dark\:text-rose-300:is(.dark *){--tw-text-opacity: 1;color:rgb(253 164 175 / var(--tw-text-opacity, 1))}.dark\:text-violet-300:is(.dark *){--tw-text-opacity: 1;color:rgb(196 181 253 / var(--tw-text-opacity, 1))}.dark\:text-white:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.dark\:text-zinc-100:is(.dark *){--tw-text-opacity: 1;color:rgb(244 244 245 / var(--tw-text-opacity, 1))}.dark\:text-zinc-200:is(.dark *){--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.dark\:text-zinc-300:is(.dark *){--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.dark\:text-zinc-400:is(.dark *){--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.dark\:text-zinc-500:is(.dark *){--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.dark\:text-zinc-600:is(.dark *){--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.dark\:text-zinc-800:is(.dark *){--tw-text-opacity: 1;color:rgb(39 39 42 / var(--tw-text-opacity, 1))}.dark\:text-zinc-900:is(.dark *){--tw-text-opacity: 1;color:rgb(24 24 27 / var(--tw-text-opacity, 1))}.dark\:shadow-\[0_1px_0_rgba\(255\,255\,255\,0\.025\)_inset\]:is(.dark *){--tw-shadow: 0 1px 0 rgba(255,255,255,.025) inset;--tw-shadow-colored: inset 0 1px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:placeholder\:text-\[\#71717a\]:is(.dark *)::-moz-placeholder{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.dark\:placeholder\:text-\[\#71717a\]:is(.dark *)::placeholder{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.dark\:placeholder\:text-zinc-600:is(.dark *)::-moz-placeholder{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.dark\:placeholder\:text-zinc-600:is(.dark *)::placeholder{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.dark\:focus-within\:border-zinc-600:focus-within:is(.dark *){--tw-border-opacity: 1;border-color:rgb(82 82 91 / var(--tw-border-opacity, 1))}.dark\:focus-within\:ring-zinc-600:focus-within:is(.dark *){--tw-ring-opacity: 1;--tw-ring-color: rgb(82 82 91 / var(--tw-ring-opacity, 1))}.dark\:hover\:bg-\[\#111113\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 17 19 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#16A34A\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#18181b\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#1ea34b\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 163 75 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#1f1f23\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 31 35 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#27272a\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#27272a\]\/50:hover:is(.dark *){background-color:#27272a80}.dark\:hover\:bg-\[\#32323a\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(50 50 58 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#3f3f46\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(63 63 70 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-white:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-white\/5:hover:is(.dark *){background-color:#ffffff0d}.dark\:hover\:bg-white\/\[0\.025\]:hover:is(.dark *){background-color:#ffffff06}.dark\:hover\:bg-white\/\[0\.06\]:hover:is(.dark *){background-color:#ffffff0f}.dark\:hover\:bg-zinc-800:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-zinc-800\/50:hover:is(.dark *){background-color:#27272a80}.dark\:hover\:bg-zinc-900:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.dark\:hover\:text-\[\#E5E5E5\]:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.dark\:hover\:text-\[\#fecaca\]:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity, 1))}.dark\:hover\:text-red-400:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:hover\:text-rose-300:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(253 164 175 / var(--tw-text-opacity, 1))}.dark\:hover\:text-white:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.dark\:hover\:text-zinc-200:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.dark\:hover\:text-zinc-300:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.dark\:focus\:border-\[\#27272a\]:focus:is(.dark *){--tw-border-opacity: 1;border-color:rgb(39 39 42 / var(--tw-border-opacity, 1))}.dark\:disabled\:bg-zinc-800:disabled:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.dark\:disabled\:text-zinc-600:disabled:is(.dark *){--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.dark\:data-\[state\=active\]\:bg-\[\#27272a\][data-state=active]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.dark\:data-\[state\=active\]\:text-white[data-state=active]:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.sm\:max-w-\[320px\]{max-width:320px}.sm\:max-w-\[480px\]{max-width:480px}.sm\:max-w-\[540px\]{max-width:540px}.sm\:max-w-\[800px\]{max-width:800px}.sm\:max-w-\[820px\]{max-width:820px}.sm\:max-w-\[900px\]{max-width:900px}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:text-left{text-align:left}}@media (min-width: 768px){.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:text-sm{font-size:.875rem;line-height:1.25rem}}.\[\&\>button\]\:hidden>button{display:none}.\[\&\>div\]\:\!block>div{display:block!important}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:1rem;height:1rem}.\[\&_svg\]\:h-\[18px\] svg{height:18px}.\[\&_svg\]\:w-\[18px\] svg{width:18px}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAASIABAAAAAACQQAAAQuAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoBmA/U1RBVF4AdBEICoRkhAALIAABNgIkAzoEIAWFAAeBFAwHG2oHKJ6DceNW4lJEFHn9tEOE37LNsvkjHr7f739rn3u+OSrSxLQytE91Dw2PYtNVq3Qaw/vJ7fUBMdOj/u2ImB98cT5WUx9F13ZKt06mU7tG1sAYcM26yCRX4f/0904bmwq8hwkUUMTRX61pa9C3xlpAGYw1vOu8C2SBZZFlld7DAW82RJWmwYMI1AJCKBNCIASqdZGFmtPSNQRhMpR0EKjWTwm6z6sJ+4jqhxjovTinVdRpZaQjaQzAYjI8NgAKDJCokgunCn9oUQE8VZd/F//+v6P4F1U9gLr58yNI/dJX9BAshEoJbTDogz7ocKoUsPvES8UK/aQIUQgpGgECBVLkOEV6iASTYgNAPKdNXayhDPL7IJuAZnEYSZ0eOLc9i5Rv5/+lEi3sW/kfnCf/+fTe0sxS7CKLx5erRJkKOixEqQaoqrvx5HN4iz4VhX0gS6DjFIWUzn/fIXJRVFY1NFRVNVeFt+SYmrK6vCU6eJsnKnJj5HTESMTQZOTI3Y/tzr3rUcOsiRy/ciP50s3Mycgxmhz9GMXhjzVH30ut796NHP0UUa31/Zoa6vCH6iPvdIM0IRANaT60FablmZlZd+UKNFy9NrvnFGxb5NC2CRxR0/rIyF/WNn+35sv9r+tHVhkseuWGKkCPPh96+GXt8Lc/Sh24ujfjf+tNw1lZWreiPuHb/PSpyjdv2rf/++ZE5TSKjFdZxYsBvr1sEHl5STuHZqYR7jGYGvGBBdjcaB5bODY1GAxMjsd0wDMIzXAXODRd74DxNMtO4YuYHclgLQRzp9KlUmxptCwv9bYgvWGD2xBW7r9413fdJu+mxzvzAUYeeONQvZP4kgfqZle4jhH/MWh+UbxgtJdrLdXLymNL53PRU0D3Q6FcXTfGqGcul6vrqhgLGAVSv+IVIfZOHpu+mlLqSlnj903j8mazXDsba/wbxhS/4Oubh1c5/uXDgt4j5KtnGEy5BIJHo0ur+jD+r2qCkuP1aRVM8EpUoRYSJyqNRA38uwDvHBNo0AejO2Z+ZYLLal1QiFyFh1EDQOgSCSCpjwwKU8yDbIjroEwne0G5Qca49cYp4AlqtQNZfWTQoFb1tRpFYAmRD+HXTkV4uQhG2bg4OKmyoypAsUGtWgQXyFxYrkpODeUxvGqIZA61erXo0sFG1UBGuPgpuon8RNUG2DhovAjZCBuZwtXrU3mQGki9+pm0eVZAXoWxLWTQoYHBPrJR4WunNxIFbCHfkTyPK+sqxjxDmGArZvf79JGJ3GwEqjwc7a7NIrl/7bJ7Nzu4+n1Ow6shEPnUrtVo7cnd5Wi5qCUbBIQbNKCP95FMCSZylEV5VCiiMqqiOmrKZ/I/C0gI1fyuulVcM2E1r4MhtcV/fbCD+HwEvVzH1dGNAzFE0FTbKzyQz3gootrNbN2a4PuG0j0JOgE=) format("woff2"),url(data:font/woff;base64,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) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2) format("woff2"),url(/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2) format("woff2"),url(/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff) format("woff");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(data:font/woff2;base64,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) format("woff2"),url(/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2) format("woff2"),url(/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2) format("woff2"),url(/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
package/dist/web/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>BladeCode</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-BvGeIa_-.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DDJnZJcp.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blade-code",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "🗡️ Blade Code - 智能代码助手命令行工具",
|
|
6
6
|
"type": "module",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"author": "echoVic",
|
|
58
58
|
"license": "MIT",
|
|
59
59
|
"engines": {
|
|
60
|
-
"node": ">=
|
|
60
|
+
"node": ">=22.19.0"
|
|
61
61
|
},
|
|
62
62
|
"optionalDependencies": {
|
|
63
63
|
"@vscode/ripgrep": "^1.17.0",
|
|
@@ -66,17 +66,11 @@
|
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
68
|
"@agentclientprotocol/sdk": "^0.12.0",
|
|
69
|
-
"@ai-sdk/anthropic": "^3.0.7",
|
|
70
|
-
"@ai-sdk/azure": "^3.0.5",
|
|
71
|
-
"@ai-sdk/deepseek": "^2.0.4",
|
|
72
|
-
"@ai-sdk/google": "^3.0.4",
|
|
73
|
-
"@ai-sdk/openai": "^3.0.26",
|
|
74
|
-
"@ai-sdk/openai-compatible": "^2.0.4",
|
|
75
69
|
"@anthropic-ai/sandbox-runtime": "0.0.67",
|
|
70
|
+
"@earendil-works/pi-ai": "0.83.0",
|
|
76
71
|
"@inkjs/ui": "^2.0.0",
|
|
77
72
|
"@modelcontextprotocol/sdk": "^1.17.4",
|
|
78
73
|
"ahooks": "^3.9.6",
|
|
79
|
-
"ai": "^6.0.39",
|
|
80
74
|
"ansi-escapes": "^7.2.0",
|
|
81
75
|
"async-mutex": "^0.5.0",
|
|
82
76
|
"axios": "^1.12.2",
|
|
@@ -109,8 +103,7 @@
|
|
|
109
103
|
"ws": "^8.18.0",
|
|
110
104
|
"yaml": "^2.8.1",
|
|
111
105
|
"yargs": "^18.0.0",
|
|
112
|
-
"
|
|
113
|
-
"zod-to-json-schema": "^3.24.6",
|
|
106
|
+
"typebox": "1.3.7",
|
|
114
107
|
"zustand": "^5.0.9"
|
|
115
108
|
},
|
|
116
109
|
"devDependencies": {
|
package/dist/chunk-1w6tqkxd.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import{Ja as S,Ka as h}from"./chunk-phhmmybg.js";import{qb as M}from"./chunk-jm2xhnrv.js";import{$b as c}from"./chunk-f9ybv4ph.js";import{EventEmitter as r}from"events";import{z as L}from"zod";import{isPlainObject as p}from"lodash-es";function J(B){if(B===void 0)return"undefined";if(typeof B==="string")return B;try{let G=JSON.stringify(B);return G===void 0?String(B):G}catch{return String(B)}}class R extends Error{issues;type;constructor(B,G,Q="validation_error"){super(B);this.issues=G;this.type=Q;this.name="ToolValidationError"}}function g(B){let{code:G}=B,Q=B,X=Q.received;switch(G){case"invalid_type":{let Y=Q.expected;return`类型错误:期望 ${J(Y)},实际收到 ${J(X)}`}case"too_small":{let{minimum:Y,inclusive:$}=Q,W=typeof Q.type==="string"?Q.type:void 0;if(W==="string"&&typeof Y==="number")return`长度不能少于 ${Y} 个字符`;if(W==="number"&&typeof Y==="number")return`不能小于${$?"等于":""} ${Y}`;if(W==="array"&&typeof Y==="number")return`数组长度不能少于 ${Y}`;return"值太小"}case"too_big":{let{maximum:Y,inclusive:$}=Q,W=typeof Q.type==="string"?Q.type:void 0;if(W==="string"&&typeof Y==="number")return`长度不能超过 ${Y} 个字符`;if(W==="number"&&typeof Y==="number")return`不能大于${$?"等于":""} ${Y}`;if(W==="array"&&typeof Y==="number")return`数组长度不能超过 ${Y}`;return"值太大"}case"invalid_string":{let Y=Q.validation;if(Y==="email")return"必须是有效的电子邮件地址";if(Y==="url")return"必须是有效的 URL";if(Y==="uuid")return"必须是有效的 UUID";if(p(Y)){let $=Y;if(typeof $.includes==="string")return`必须包含 "${$.includes}"`;if(typeof $.startsWith==="string")return`必须以 "${$.startsWith}" 开头`;if(typeof $.endsWith==="string")return`必须以 "${$.endsWith}" 结尾`}return"字符串格式不正确"}case"invalid_enum_value":{let Y=Q.options;if(Array.isArray(Y))return`必须是以下值之一:${Y.map(($)=>J($)).join(", ")}`;return"必须是枚举允许的值之一"}case"invalid_literal":{let Y=Q.expected;return`必须是字面量值:${J(Y)}`}case"unrecognized_keys":{let Y=Q.keys;if(Array.isArray(Y))return`包含未知的参数:${Y.map(($)=>J($)).join(", ")}`;return"包含未知的参数"}case"invalid_union":return"不符合任何有效的类型定义";case"invalid_date":return"必须是有效的日期";case"custom":return B.message||"自定义验证失败";default:return B.message||"验证失败"}}function u(B){let G=B.issues.map((X)=>{let Y=X.path.join("."),$=g(X),W=X.received;return{field:Y||"root",message:$,value:W}}),Q=G.length===1?`参数验证失败 [${G[0].field}]: ${G[0].message}`:`参数验证失败 (${G.length} 个错误):
|
|
2
|
-
${G.map((X)=>` - ${X.field}: ${X.message}`).join(`
|
|
3
|
-
`)}`;return new R(Q,G)}function y(B,G){let Q=B.safeParse(G);if(!Q.success)throw u(Q.error);return Q.data}import{zodToJsonSchema as l}from"zod-to-json-schema";function H(B){let G=l(B,{target:"jsonSchema7",$refStrategy:"none"});if(G.type==="object"&&G.properties&&!Array.isArray(G.required))G.required=[];return G}class w{toolName;params;executeFn;descriptionFn;affectedPathsFn;constructor(B,G,Q,X,Y){this.toolName=B;this.params=G;this.executeFn=Q;this.descriptionFn=X;this.affectedPathsFn=Y}getDescription(){if(this.descriptionFn)return this.descriptionFn(this.params);return`执行工具: ${this.toolName}`}getAffectedPaths(){if(this.affectedPathsFn)return this.affectedPathsFn(this.params);return[]}async execute(B,G,Q){let X={signal:B,updateOutput:G,...Q};return this.executeFn(this.params,X)}}function k(B){return{name:B.name,displayName:B.displayName,kind:B.kind,isReadOnly:B.isReadOnly??M(B.kind),isConcurrencySafe:B.isConcurrencySafe??!1,strict:B.strict??!1,description:B.description,version:B.version||"1.0.0",category:B.category,tags:B.tags||[],getFunctionDeclaration(){let G=H(B.schema),Q=B.description.short;if(B.description.long)Q+=`
|
|
4
|
-
|
|
5
|
-
${B.description.long}`;if(B.description.usageNotes&&B.description.usageNotes.length>0)Q+=`
|
|
6
|
-
|
|
7
|
-
Usage Notes:
|
|
8
|
-
${B.description.usageNotes.map((X)=>`- ${X}`).join(`
|
|
9
|
-
`)}`;if(B.description.important&&B.description.important.length>0)Q+=`
|
|
10
|
-
|
|
11
|
-
Important:
|
|
12
|
-
${B.description.important.map((X)=>`[WARN] ${X}`).join(`
|
|
13
|
-
`)}`;return{name:B.name,description:Q,parameters:G}},getMetadata(){return{name:B.name,displayName:B.displayName,kind:B.kind,version:B.version||"1.0.0",category:B.category,tags:B.tags||[],description:B.description,schema:H(B.schema)}},build(G){let Q=y(B.schema,G);return new w(B.name,Q,B.execute)},async execute(G,Q,X){return this.build(G).execute(Q||new AbortController().signal,void 0,X)},extractSignatureContent:B.extractSignatureContent?(G)=>B.extractSignatureContent(G):void 0,abstractPermissionRule:B.abstractPermissionRule?(G)=>B.abstractPermissionRule(G):void 0}}function U(B,G,Q,X){let Y;try{Y=V(Q.inputSchema)}catch(W){console.warn(`[createMcpTool] Schema 转换失败,使用降级 schema: ${Q.name}`,W),Y=L.any()}let $=X||Q.name;return k({name:$,displayName:`${G}: ${Q.name}`,kind:"execute",schema:Y,description:{short:Q.description||`MCP Tool: ${Q.name}`,important:[`From MCP server: ${G}`,"Executes external tools; user confirmation required"]},category:"MCP tool",tags:["mcp","external",G],async execute(W,q){try{let F=await B.callTool(Q.name,W),A="";if(F.content&&Array.isArray(F.content)){for(let K of F.content)if(K.type==="text"&&K.text)A+=K.text;else if(K.type==="image")A+=`[image: ${K.mimeType||"unknown"}]
|
|
14
|
-
`;else if(K.type==="resource")A+=`[resource: ${K.mimeType||"unknown"}]
|
|
15
|
-
`}if(F.isError)return{success:!1,llmContent:A||"MCP tool execution failed",error:{type:"execution_error",message:A||"MCP tool execution failed"},metadata:{summary:`MCP ${Q.name} 执行失败`,serverName:G,toolName:Q.name}};return{success:!0,llmContent:A||"Execution succeeded",metadata:{summary:`MCP ${Q.name} 执行成功`,serverName:G,toolName:Q.name,mcpResult:F}}}catch(F){return{success:!1,llmContent:`MCP tool execution failed: ${F.message}`,error:{type:"execution_error",message:F.message},metadata:{summary:`MCP ${Q.name} 执行失败`,serverName:G,toolName:Q.name}}}}})}function V(B){if(B.type==="object"||B.properties){let G={},Q=B.required||[];if(B.properties){for(let[X,Y]of Object.entries(B.properties))if(typeof Y==="object"&&Y!==null){let $=V(Y);if(!Q.includes(X))$=$.optional();G[X]=$}}return L.object(G)}if(B.type==="array"&&B.items){if(typeof B.items==="object"&&!Array.isArray(B.items)&&B.items!==null)return L.array(V(B.items));return L.array(L.any())}if(B.type==="string"){let G=L.string();if(B.minLength!==void 0)G=G.min(B.minLength);if(B.maxLength!==void 0)G=G.max(B.maxLength);if(B.pattern)G=G.regex(new RegExp(B.pattern));if(B.enum)return L.enum(B.enum);return G}if(B.type==="number"||B.type==="integer"){let G=L.number();if(B.minimum!==void 0)G=G.min(B.minimum);if(B.maximum!==void 0)G=G.max(B.maximum);return G}if(B.type==="boolean")return L.boolean();if(B.oneOf&&B.oneOf.length>0){let G=B.oneOf.filter((Q)=>typeof Q==="object"&&Q!==null).map((Q)=>V(Q));if(G.length>=2)return L.union(G)}if(B.anyOf&&B.anyOf.length>0){let G=B.anyOf.filter((Q)=>typeof Q==="object"&&Q!==null).map((Q)=>V(Q));if(G.length>=2)return L.union(G)}return L.any()}import{Client as t}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as a}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as s}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as n}from"events";import{spawn as m}from"child_process";import*as _ from"crypto";import*as T from"http";import{URL as C}from"url";import{promises as z}from"fs";import f from"os";import P from"path";class x{tokenFilePath;constructor(){let B=f.homedir(),G=P.join(B,".blade");this.tokenFilePath=P.join(G,"mcp-oauth-tokens.json")}async ensureConfigDir(){let B=P.dirname(this.tokenFilePath);try{await z.mkdir(B,{recursive:!0,mode:493})}catch{}}async loadAllCredentials(){let B=new Map;try{let G=await z.readFile(this.tokenFilePath,"utf-8"),Q=JSON.parse(G);for(let X of Q)B.set(X.serverName,X)}catch(G){if(G.code!=="ENOENT")console.warn("[OAuthTokenStorage] 加载令牌失败:",G)}return B}async saveAllCredentials(B){await this.ensureConfigDir();let G=Array.from(B.values());await z.writeFile(this.tokenFilePath,JSON.stringify(G,null,2),{mode:384})}async saveToken(B,G,Q,X){let Y=await this.loadAllCredentials(),$={serverName:B,token:G,clientId:Q,tokenUrl:X,updatedAt:Date.now()};Y.set(B,$),await this.saveAllCredentials(Y)}async getCredentials(B){return(await this.loadAllCredentials()).get(B)||null}async deleteCredentials(B){let G=await this.loadAllCredentials();G.delete(B),await this.saveAllCredentials(G)}async listServers(){let B=await this.loadAllCredentials();return Array.from(B.keys())}isTokenExpired(B){if(!B.expiresAt)return!1;let G=300000;return Date.now()>=B.expiresAt-G}}var Z=7777,D="/oauth/callback",I=200;class O{tokenStorage;constructor(B=new x){this.tokenStorage=B}generatePKCEParams(){let B=_.randomBytes(32).toString("base64url"),G=_.createHash("sha256").update(B).digest("base64url"),Q=_.randomBytes(16).toString("base64url");return{codeVerifier:B,codeChallenge:G,state:Q}}buildAuthorizationUrl(B,G){let Q=B.redirectUri||`http://localhost:${Z}${D}`,X=new URLSearchParams({client_id:B.clientId,response_type:"code",redirect_uri:Q,state:G.state,code_challenge:G.codeChallenge,code_challenge_method:"S256"});if(B.scopes&&B.scopes.length>0)X.append("scope",B.scopes.join(" "));let Y=new C(B.authorizationUrl);return X.forEach(($,W)=>{Y.searchParams.append(W,$)}),Y.toString()}async startCallbackServer(B){return new Promise((G,Q)=>{let X=T.createServer((Y,$)=>{try{let W=new C(Y.url,`http://localhost:${Z}`);if(W.pathname!==D){$.writeHead(404),$.end("Not found");return}let q=W.searchParams.get("code"),F=W.searchParams.get("state"),A=W.searchParams.get("error");if(A){$.writeHead(I,{"Content-Type":"text/html"}),$.end(`
|
|
16
|
-
<html>
|
|
17
|
-
<body>
|
|
18
|
-
<h1>Authentication Failed</h1>
|
|
19
|
-
<p>Error: ${A}</p>
|
|
20
|
-
<p>You can close this window.</p>
|
|
21
|
-
</body>
|
|
22
|
-
</html>
|
|
23
|
-
`),X.close(),Q(Error(`OAuth error: ${A}`));return}if(!q||!F){$.writeHead(400),$.end("Missing code or state parameter");return}if(F!==B){$.writeHead(400),$.end("Invalid state parameter"),X.close(),Q(Error("State mismatch - possible CSRF attack"));return}$.writeHead(I,{"Content-Type":"text/html"}),$.end(`
|
|
24
|
-
<html>
|
|
25
|
-
<body>
|
|
26
|
-
<h1>Authentication Successful!</h1>
|
|
27
|
-
<p>You can close this window and return to Blade.</p>
|
|
28
|
-
<script>window.close();</script>
|
|
29
|
-
</body>
|
|
30
|
-
</html>
|
|
31
|
-
`),X.close(),G(q)}catch(W){X.close(),Q(W)}});X.on("error",Q),X.listen(Z,()=>{console.log(`[OAuth] Callback server listening on port ${Z}`)}),setTimeout(()=>{X.close(),Q(Error("OAuth callback timeout"))},300000)})}async exchangeCodeForToken(B,G,Q){let X=B.redirectUri||`http://localhost:${Z}${D}`,Y=new URLSearchParams({grant_type:"authorization_code",code:G,redirect_uri:X,code_verifier:Q,client_id:B.clientId});if(B.clientSecret)Y.append("client_secret",B.clientSecret);let $=await fetch(B.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Y.toString()});if(!$.ok){let W=await $.text();throw Error(`Token exchange failed: ${$.status} - ${W}`)}return await $.json()}async refreshAccessToken(B,G){let Q=new URLSearchParams({grant_type:"refresh_token",refresh_token:G,client_id:B.clientId});if(B.clientSecret)Q.append("client_secret",B.clientSecret);if(B.scopes&&B.scopes.length>0)Q.append("scope",B.scopes.join(" "));let X=await fetch(B.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Q.toString()});if(!X.ok){let Y=await X.text();throw Error(`Token refresh failed: ${X.status} - ${Y}`)}return await X.json()}async authenticate(B,G){if(!G.clientId||!G.authorizationUrl||!G.tokenUrl)throw Error("Missing required OAuth configuration");let Q=this.generatePKCEParams(),X=this.buildAuthorizationUrl(G,Q);console.log(`
|
|
32
|
-
[OAuth] Opening browser for authentication...`),console.log(`
|
|
33
|
-
If the browser does not open automatically, copy and paste this URL:`),console.log(X),console.log("");let Y=this.startCallbackServer(Q.state);try{await this.openAuthorizationUrl(X)}catch(F){console.warn("[OAuth] Failed to open browser automatically:",F)}let $=await Y;console.log("[OAuth] Authorization code received, exchanging for tokens...");let W=await this.exchangeCodeForToken(G,$,Q.codeVerifier),q={accessToken:W.access_token,tokenType:W.token_type||"Bearer",refreshToken:W.refresh_token,scope:W.scope};if(W.expires_in)q.expiresAt=Date.now()+W.expires_in*1000;return await this.tokenStorage.saveToken(B,q,G.clientId,G.tokenUrl),console.log("[OAuth] Authentication successful! Token saved."),q}async openAuthorizationUrl(B){let{command:G,args:Q}=this.getBrowserCommand(B);await new Promise((X,Y)=>{let $=m(G,Q,{stdio:"ignore"});$.once("error",Y),$.once("close",(W)=>{if(W===0||W===null)X();else Y(Error(`Failed to open browser (exit code ${W})`))})})}getBrowserCommand(B){if(process.platform==="darwin")return{command:"open",args:[B]};if(process.platform==="win32")return{command:"cmd",args:["/c","start","",B]};return{command:"xdg-open",args:[B]}}async getValidToken(B,G){let Q=await this.tokenStorage.getCredentials(B);if(!Q)return null;let{token:X}=Q;if(!this.tokenStorage.isTokenExpired(X))return X.accessToken;if(X.refreshToken&&G.clientId&&Q.tokenUrl)try{console.log(`[OAuth] Refreshing expired token for server: ${B}`);let Y=await this.refreshAccessToken(G,X.refreshToken),$={accessToken:Y.access_token,tokenType:Y.token_type,refreshToken:Y.refresh_token||X.refreshToken,scope:Y.scope||X.scope};if(Y.expires_in)$.expiresAt=Date.now()+Y.expires_in*1000;return await this.tokenStorage.saveToken(B,$,G.clientId,Q.tokenUrl),$.accessToken}catch(Y){console.error("[OAuth] Failed to refresh token:",Y),await this.tokenStorage.deleteCredentials(B)}return null}}import{EventEmitter as i}from"events";class E extends i{client;config;checkTimer=null;isChecking=!1;consecutiveFailures=0;lastCheckTime=0;currentStatus="healthy";constructor(B,G={}){super();this.client=B,this.config={interval:G.interval??30000,timeout:G.timeout??1e4,enabled:G.enabled??!1,failureThreshold:G.failureThreshold??3}}start(){if(this.checkTimer){console.warn("[HealthMonitor] 健康监控已在运行");return}if(!this.config.enabled){console.log("[HealthMonitor] 健康监控未启用");return}console.log(`[HealthMonitor] 启动健康监控(间隔: ${this.config.interval}ms)`),this.scheduleNextCheck()}stop(){if(this.checkTimer)clearTimeout(this.checkTimer),this.checkTimer=null,console.log("[HealthMonitor] 停止健康监控")}scheduleNextCheck(){this.checkTimer=setTimeout(async()=>{await this.performHealthCheck(),this.scheduleNextCheck()},this.config.interval)}async performHealthCheck(){if(this.isChecking)return console.warn("[HealthMonitor] 上一次检查仍在进行中"),this.getLastResult();this.isChecking=!0,this.lastCheckTime=Date.now(),this.setStatus("checking");try{let B=this.client.connectionStatus;if(B==="connected"){await this.pingServer(),this.consecutiveFailures=0,this.setStatus("healthy");let G={status:"healthy",timestamp:Date.now(),consecutiveFailures:0};return this.emit("healthCheck",G),G}else throw Error(`连接状态异常: ${B}`)}catch(B){this.consecutiveFailures++;let G=B;console.warn(`[HealthMonitor] 健康检查失败(${this.consecutiveFailures}/${this.config.failureThreshold}):`,G.message);let Q;if(this.consecutiveFailures>=this.config.failureThreshold)Q="unhealthy",this.emit("unhealthy",this.consecutiveFailures,G),console.log("[HealthMonitor] 达到失败阈值,触发重连..."),this.triggerReconnection().catch((Y)=>{console.error("[HealthMonitor] 重连失败:",Y)});else Q="degraded";this.setStatus(Q);let X={status:Q,timestamp:Date.now(),consecutiveFailures:this.consecutiveFailures,lastError:G};return this.emit("healthCheck",X),X}finally{this.isChecking=!1}}async pingServer(){let B=new Promise((Q,X)=>{setTimeout(()=>X(Error("Health check timeout")),this.config.timeout)}),G=(async()=>{if(this.client.availableTools.length===0){if(!this.client.server)throw Error("Server info not available")}})();await Promise.race([G,B])}async triggerReconnection(){try{await this.client.disconnect(),await new Promise((B)=>setTimeout(B,1000)),await this.client.connect(),console.log("[HealthMonitor] 重连成功"),this.consecutiveFailures=0,this.setStatus("healthy"),this.emit("reconnected")}catch(B){throw console.error("[HealthMonitor] 重连失败:",B),B}}setStatus(B){if(this.currentStatus!==B){let G=this.currentStatus;this.currentStatus=B,this.emit("statusChanged",B,G)}}getStatus(){return this.currentStatus}getLastResult(){return{status:this.currentStatus,timestamp:this.lastCheckTime,consecutiveFailures:this.consecutiveFailures}}getStatistics(){return{status:this.currentStatus,consecutiveFailures:this.consecutiveFailures,lastCheckTime:this.lastCheckTime,isChecking:this.isChecking,config:this.config}}async checkNow(){return this.performHealthCheck()}resetFailureCount(){if(this.consecutiveFailures=0,this.currentStatus!=="checking")this.setStatus("healthy")}}function d(B){if(!(B instanceof Error))return{type:"unknown",isRetryable:!1,originalError:Error(String(B))};let G=B.message.toLowerCase();if(["command not found","no such file","permission denied","invalid configuration","malformed","syntax error"].some((Y)=>G.includes(Y)))return{type:"config_error",isRetryable:!1,originalError:B};if(G.includes("unauthorized")||G.includes("401")||G.includes("authentication failed"))return{type:"auth_error",isRetryable:!1,originalError:B};if(["timeout","connection refused","network error","temporary","try again","rate limit","too many requests","service unavailable","socket hang up","econnreset","enotfound","econnrefused","etimedout","503","429"].some((Y)=>G.includes(Y)))return{type:"network_temporary",isRetryable:!0,originalError:B};return{type:"unknown",isRetryable:!0,originalError:B}}class N extends n{config;status="disconnected";sdkClient=null;tools=new Map;serverInfo=null;reconnectAttempts=0;MAX_RECONNECT_ATTEMPTS=5;reconnectTimer=null;isManualDisconnect=!1;oauthProvider=null;serverName;healthMonitor=null;constructor(B,G,Q){super();this.config=B;if(this.serverName=G||"default",B.oauth?.enabled)this.oauthProvider=new O;if(Q?.enabled)this.healthMonitor=new E(this,Q),this.healthMonitor.on("unhealthy",(X,Y)=>{this.emit("unhealthy",X,Y)}),this.healthMonitor.on("reconnected",()=>{this.emit("healthMonitorReconnected")})}get connectionStatus(){return this.status}get availableTools(){return Array.from(this.tools.values())}get server(){return this.serverInfo}get healthCheck(){return this.healthMonitor}async connect(){return this.connectWithRetry(3,1000)}async connectWithRetry(B=3,G=1000){if(this.status!=="disconnected"&&this.status!=="error")throw Error("客户端已连接或正在连接中");if(this.status==="error"){if(this.sdkClient){try{await this.sdkClient.close()}catch{}this.sdkClient=null}this.setStatus("disconnected")}let Q=null;for(let X=1;X<=B;X++)try{await this.doConnect(),this.reconnectAttempts=0;return}catch(Y){Q=Y;let $=d(Y);if(!$.isRetryable)throw console.error("[McpClient] 检测到永久性错误,放弃重试:",$.type),Y;if(X<B){let W=G*Math.pow(2,X-1);console.warn(`[McpClient] 连接失败(${X}/${B}),${W}ms 后重试...`),await new Promise((q)=>setTimeout(q,W))}}throw Q||Error("连接失败")}async doConnect(){try{this.setStatus("connecting"),this.sdkClient=new t({name:h(),version:S()},{capabilities:{roots:{listChanged:!0},sampling:{}}}),this.sdkClient.onclose=()=>{this.handleUnexpectedClose()};let B=await this.createTransport();await this.sdkClient.connect(B);let G=this.sdkClient.getServerVersion();if(this.serverInfo={name:G?.name||"Unknown",version:G?.version||"0.0.0"},await this.loadTools(),this.setStatus("connected"),this.emit("connected",this.serverInfo),this.healthMonitor)this.healthMonitor.start()}catch(B){throw this.setStatus("error"),this.emit("error",B),B}}handleUnexpectedClose(){if(this.isManualDisconnect)return;if(this.status==="connected")console.warn("[McpClient] 检测到意外断连,准备重连..."),this.setStatus("error"),this.emit("error",Error("MCP服务器连接意外关闭")),this.scheduleReconnect()}scheduleReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.reconnectAttempts>=this.MAX_RECONNECT_ATTEMPTS){console.error("[McpClient] 达到最大重连次数,放弃重连"),this.emit("reconnectFailed");return}let B=Math.min(1000*Math.pow(2,this.reconnectAttempts),30000);this.reconnectAttempts++,console.log(`[McpClient] 将在 ${B}ms 后进行第 ${this.reconnectAttempts} 次重连...`),this.reconnectTimer=setTimeout(async()=>{try{if(this.sdkClient){try{await this.sdkClient.close()}catch{}this.sdkClient=null}this.setStatus("disconnected"),await this.doConnect(),console.log("[McpClient] 重连成功"),this.reconnectAttempts=0,this.emit("reconnected")}catch(G){if(console.error("[McpClient] 重连失败:",G),d(G).isRetryable)this.scheduleReconnect();else console.error("[McpClient] 检测到永久性错误,停止重连"),this.emit("reconnectFailed")}},B)}async disconnect(){if(this.isManualDisconnect=!0,this.healthMonitor)this.healthMonitor.stop();if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.sdkClient){try{await this.sdkClient.close()}catch(B){console.warn("[McpClient] 断开连接时出错:",B)}this.sdkClient=null}this.tools.clear(),this.serverInfo=null,this.reconnectAttempts=0,this.setStatus("disconnected"),this.emit("disconnected"),this.isManualDisconnect=!1}async callTool(B,G={}){if(!this.sdkClient)throw Error("客户端未连接到服务器");if(!this.tools.has(B))throw Error(`工具 "${B}" 不存在`);try{return await this.sdkClient.callTool({name:B,arguments:G})}catch(Q){throw console.error(`[McpClient] 调用工具 "${B}" 失败:`,Q),Q}}async createTransport(){let{type:B,command:G,args:Q,env:X,url:Y,headers:$,oauth:W}=this.config,q={...$};if(W?.enabled&&this.oauthProvider&&(B==="sse"||B==="http"))try{let F=await this.oauthProvider.getValidToken(this.serverName,W);if(!F){console.log(`[McpClient] 服务器 "${this.serverName}" 需要 OAuth 认证`);let A=await this.oauthProvider.authenticate(this.serverName,W);q.Authorization=`Bearer ${A.accessToken}`}else q.Authorization=`Bearer ${F}`}catch(F){throw console.error("[McpClient] OAuth 认证失败:",F),Error(`OAuth 认证失败: ${F instanceof Error?F.message:String(F)}`)}if(B==="stdio"){if(!G)throw Error("stdio 传输需要 command 参数");let F={};for(let[A,K]of Object.entries(process.env))if(K!==void 0)F[A]=K;return new s({command:G,args:Q||[],env:{...F,...X},stderr:"ignore"})}else if(B==="sse"){if(!Y)throw Error("sse 传输需要 url 参数");return new a(new URL(Y),{requestInit:{headers:q}})}else if(B==="http"){if(!Y)throw Error("http 传输需要 url 参数");let{StreamableHTTPClientTransport:F}=await import("@modelcontextprotocol/sdk/client/streamableHttp.js");return new F(new URL(Y),{requestInit:{headers:q}})}throw Error(`不支持的传输类型: ${B}`)}async loadTools(){if(!this.sdkClient)return;try{let B=await this.sdkClient.listTools();if(this.tools.clear(),B.tools)for(let G of B.tools)this.tools.set(G.name,G);this.emit("toolsUpdated",this.availableTools)}catch(B){throw console.error("[McpClient] 加载工具失败:",B),B}}setStatus(B){let G=this.status;this.status=B,this.emit("statusChanged",B,G)}async initialize(){return this.connect()}async destroy(){return this.disconnect()}async connectToServer(B){return this.connect()}async disconnectFromServer(B){return this.disconnect()}async listResources(B){if(!this.sdkClient)return[];try{return(await this.sdkClient.listResources()).resources||[]}catch{return[]}}async listTools(B){return this.availableTools}async readResource(B,G){if(!this.sdkClient)throw Error("客户端未连接");return(await this.sdkClient.readResource({uri:B})).contents?.[0]||{uri:B,text:""}}}class b extends r{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!b.instance)b.instance=new b;return b.instance}static createIsolated(){return new b}async registerServer(B,G){if(this.servers.has(B))throw Error(`MCP服务器 "${B}" 已经注册`);let Q=new N(G,B,G.healthCheck),X={config:G,client:Q,status:"disconnected",tools:[]};this.setupClientEventHandlers(Q,X,B),this.servers.set(B,X),this.emit("serverRegistered",B,X);try{await this.connectServer(B)}catch(Y){console.warn(`MCP服务器 "${B}" 连接失败:`,Y)}}async unregisterServer(B){let G=this.servers.get(B);if(!G)return;try{await G.client.disconnect()}catch(Q){console.warn(`断开MCP服务器 "${B}" 时出错:`,Q)}this.servers.delete(B),this.emit("serverUnregistered",B)}async connectServer(B){let G=this.servers.get(B);if(!G)throw Error(`MCP服务器 "${B}" 未注册`);if(G.status==="connected")return;try{G.status="connecting",await G.client.connect(),G.connectedAt=new Date,G.lastError=void 0,G.tools=G.client.availableTools}catch(Q){throw G.lastError=Q,G.status="error",Q}}async disconnectServer(B){let G=this.servers.get(B);if(!G)return;await G.client.disconnect(),G.connectedAt=void 0}async reconnectServer(B){let G=this.servers.get(B);if(!G)throw Error(`MCP服务器 "${B}" 未注册`);if(G.status==="connected")await G.client.disconnect();try{G.status="connecting",await G.client.connect(),G.connectedAt=new Date,G.lastError=void 0,G.tools=G.client.availableTools}catch(Q){throw G.lastError=Q,G.status="error",Q}}async getAvailableTools(){let B=[],G=new Map;for(let[Q,X]of this.servers)if(X.status==="connected")for(let Y of X.tools){let $=G.get(Y.name)||0;G.set(Y.name,$+1)}for(let[Q,X]of this.servers)if(X.status==="connected")for(let Y of X.tools){let W=(G.get(Y.name)||0)>1?`${Q}__${Y.name}`:Y.name,q=U(X.client,Q,Y,W);B.push(q)}return B}async findTool(B){for(let[G,Q]of this.servers)if(Q.status==="connected"){let X=Q.tools.find((Y)=>Y.name===B);if(X)return U(Q.client,G,X)}return null}getToolsByServer(B){let G=this.servers.get(B);if(!G||G.status!=="connected")return[];return G.tools.map((Q)=>U(G.client,B,Q))}getServerStatus(B){return this.servers.get(B)||null}getAllServers(){return new Map(this.servers)}async refreshAllTools(){let B=[];for(let[G,Q]of this.servers)if(Q.status==="connected")B.push(this.refreshServerTools(G));await Promise.allSettled(B)}async refreshServerTools(B){let G=this.servers.get(B);if(!G||G.status!=="connected")return;try{let Q=G.client.availableTools,X=G.tools.length;G.tools=Q,this.emit("toolsUpdated",B,Q,X)}catch(Q){console.warn(`刷新服务器 "${B}" 工具列表失败:`,Q)}}setupClientEventHandlers(B,G,Q){B.on("connected",(X)=>{G.status="connected",G.connectedAt=new Date,G.tools=B.availableTools,this.emit("serverConnected",Q,X)}),B.on("disconnected",()=>{G.status="disconnected",G.connectedAt=void 0,G.tools=[],this.emit("serverDisconnected",Q)}),B.on("error",(X)=>{G.status="error",G.lastError=X,this.emit("serverError",Q,X)}),B.on("toolsUpdated",(X)=>{let Y=G.tools.length;G.tools=X,this.emit("toolsUpdated",Q,X,Y)}),B.on("statusChanged",(X,Y)=>{G.status=X,this.emit("serverStatusChanged",Q,X,Y)})}async discoverServers(){if(this.isDiscovering)return Array.from(this.servers.values());this.isDiscovering=!0,this.emit("discoveryStarted");try{return Array.from(this.servers.values())}finally{this.isDiscovering=!1,this.emit("discoveryCompleted")}}async registerServers(B){let G=Object.entries(B).map(([Q,X])=>this.registerServer(Q,X).catch((Y)=>{return console.warn(`注册MCP服务器 "${Q}" 失败:`,Y),Y}));await Promise.allSettled(G)}getStatistics(){let B=0,G=0,Q=0;for(let X of this.servers.values())if(X.status==="connected")B++,G+=X.tools.length;else if(X.status==="error")Q++;return{totalServers:this.servers.size,connectedServers:B,errorServers:Q,totalTools:G,isDiscovering:this.isDiscovering}}async disconnectAll(){let B=[];for(let[G,Q]of this.servers)if(Q.status==="connected")B.push(Q.client.disconnect().catch((X)=>{console.warn(`断开 MCP 服务器 "${G}" 时出错:`,X)}));await Promise.allSettled(B),this.servers.clear()}}
|
|
34
|
-
export{k as ca,b as da};
|
package/dist/chunk-2049tv49.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import{Bb as n}from"./chunk-4dmdn3a9.js";import{Zb as r}from"./chunk-a7yjnqhd.js";import{$b as b}from"./chunk-f9ybv4ph.js";import{nanoid as A}from"nanoid";var N;((R)=>{R.PreToolUse="PreToolUse";R.PostToolUse="PostToolUse";R.PostToolUseFailure="PostToolUseFailure";R.PermissionRequest="PermissionRequest";R.UserPromptSubmit="UserPromptSubmit";R.SessionStart="SessionStart";R.SessionEnd="SessionEnd";R.Stop="Stop";R.SubagentStop="SubagentStop";R.Notification="Notification";R.Compaction="Compaction"})(N||={});var C;((W)=>{W.Approve="approve";W.Block="block";W.Async="async"})(C||={});var S;((W)=>{W.Allow="allow";W.Deny="deny";W.Ask="ask"})(S||={});var I={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,httpPolicy:{},PreToolUse:[],PostToolUse:[{name:"builtin:code-review-sensor",matcher:{tools:"Edit|Write"},hooks:[{type:"prompt",prompt:"审查此代码变更,重点检查:"+"1) 安全漏洞(命令注入、XSS、SQL 注入、硬编码密钥/密码)"+"2) 明显的逻辑错误(无限循环、off-by-one、空引用)"+"3) 类型安全问题。"+"如果发现严重问题,将问题描述放在 hookSpecificOutput.additionalContext 中。"+"如果没有严重问题,返回 approve。",model:void 0,timeout:15}]}],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]};function f(Q,Y){return{...Q,...Y,PreToolUse:Y.PreToolUse??Q.PreToolUse,PostToolUse:Y.PostToolUse??Q.PostToolUse,PostToolUseFailure:Y.PostToolUseFailure??Q.PostToolUseFailure,PermissionRequest:Y.PermissionRequest??Q.PermissionRequest,UserPromptSubmit:Y.UserPromptSubmit??Q.UserPromptSubmit,SessionStart:Y.SessionStart??Q.SessionStart,SessionEnd:Y.SessionEnd??Q.SessionEnd,Stop:Y.Stop??Q.Stop,SubagentStop:Y.SubagentStop??Q.SubagentStop,Notification:Y.Notification??Q.Notification,Compaction:Y.Compaction??Q.Compaction}}function x(){let Q={};if(process.env.BLADE_DISABLE_HOOKS==="true")Q.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Y=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Y)&&Y>0)Q.defaultTimeout=Y}return Q}class z{executedHooks=new Map;canExecute(Q,Y){if(!this.executedHooks.has(Q))this.executedHooks.set(Q,new Set);if(this.executedHooks.get(Q).has(Y))return console.warn(`[HookGuard] Hook ${Y} for tool ${Q} already executed, skipping`),!1;return!0}markExecuted(Q,Y){let Z=this.executedHooks.get(Q);if(Z)Z.add(Y)}cleanup(Q){this.executedHooks.delete(Q)}cleanupAll(){this.executedHooks.clear()}}import{z as q}from"zod";var j=q.object({hook_event_name:q.nativeEnum(N),hook_execution_id:q.string(),timestamp:q.string(),project_dir:q.string(),session_id:q.string(),permission_mode:q.enum(["default","autoEdit","yolo","plan"]),_metadata:q.object({blade_version:q.string(),hook_timeout_ms:q.number()}).optional()}),o=j.extend({hook_event_name:q.literal("PreToolUse"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown())}),e=j.extend({hook_event_name:q.literal("PostToolUse"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown()),tool_response:q.unknown()}),t=j.extend({hook_event_name:q.literal("Stop"),reason:q.string().optional()}),QQ=j.extend({hook_event_name:q.literal("PostToolUseFailure"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown()),error:q.string(),error_type:q.string().optional(),is_interrupt:q.boolean(),is_timeout:q.boolean()}),YQ=j.extend({hook_event_name:q.literal("PermissionRequest"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown())}),ZQ=j.extend({hook_event_name:q.literal("UserPromptSubmit"),user_prompt:q.string(),has_images:q.boolean(),image_count:q.number()}),WQ=j.extend({hook_event_name:q.literal("SessionStart"),is_resume:q.boolean(),resume_session_id:q.string().optional()}),$Q=j.extend({hook_event_name:q.literal("SessionEnd"),reason:q.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),qQ=j.extend({hook_event_name:q.literal("SubagentStop"),agent_type:q.string(),task_description:q.string().optional(),success:q.boolean(),result_summary:q.string().optional(),error:q.string().optional()}),XQ=j.extend({hook_event_name:q.literal("Notification"),notification_type:q.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:q.string().optional(),message:q.string()}),JQ=j.extend({hook_event_name:q.literal("Compaction"),trigger:q.enum(["manual","auto"]),messages_before:q.number(),tokens_before:q.number()}),dQ=q.discriminatedUnion("hook_event_name",[o,e,t,QQ,YQ,ZQ,WQ,$Q,qQ,XQ,JQ]),GQ=q.object({hookEventName:q.literal("PreToolUse"),permissionDecision:q.nativeEnum(S).optional(),permissionDecisionReason:q.string().optional(),updatedInput:q.record(q.unknown()).optional()}),KQ=q.object({hookEventName:q.literal("PostToolUse"),additionalContext:q.string().optional(),updatedOutput:q.unknown().optional()}),VQ=q.object({hookEventName:q.literal("Stop"),continue:q.boolean().optional(),continueReason:q.string().optional()}),FQ=q.object({hookEventName:q.literal("SubagentStop"),continue:q.boolean().optional(),continueReason:q.string().optional(),additionalContext:q.string().optional()}),RQ=q.object({hookEventName:q.literal("PermissionRequest"),permissionDecision:q.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:q.string().optional()}),DQ=q.object({hookEventName:q.literal("UserPromptSubmit"),updatedPrompt:q.string().optional(),contextInjection:q.string().optional()}),LQ=q.object({hookEventName:q.literal("SessionStart"),env:q.record(q.string()).optional()}),_Q=q.object({hookEventName:q.literal("Compaction"),blockCompaction:q.boolean().optional(),blockReason:q.string().optional()}),jQ=q.object({decision:q.object({behavior:q.nativeEnum(C)}).optional(),systemMessage:q.string().optional(),hookSpecificOutput:q.discriminatedUnion("hookEventName",[GQ,KQ,VQ,FQ,RQ,DQ,LQ,_Q]).optional(),suppressOutput:q.boolean().optional()}),AQ=q.object({type:q.literal("command"),command:q.string(),timeout:q.number().positive().optional(),statusMessage:q.string().optional()}),BQ=q.object({type:q.literal("prompt"),prompt:q.string(),model:q.string().optional(),timeout:q.number().positive().optional()}),OQ=q.discriminatedUnion("type",[AQ,BQ]),H=q.union([q.string(),q.array(q.string())]),UQ=q.object({tools:H.optional(),paths:H.optional(),commands:H.optional()}),_=q.object({name:q.string().optional(),matcher:UQ.optional(),hooks:q.array(OQ)}),mQ=q.object({enabled:q.boolean().optional(),defaultTimeout:q.number().positive().optional(),timeoutBehavior:q.enum(["ignore","deny","ask"]).optional(),failureBehavior:q.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:q.number().positive().optional(),PreToolUse:q.array(_).optional(),PostToolUse:q.array(_).optional(),PostToolUseFailure:q.array(_).optional(),PermissionRequest:q.array(_).optional(),UserPromptSubmit:q.array(_).optional(),SessionStart:q.array(_).optional(),SessionEnd:q.array(_).optional(),Stop:q.array(_).optional(),SubagentStop:q.array(_).optional(),Notification:q.array(_).optional(),Compaction:q.array(_).optional()});function p(Q){let Y=jQ.safeParse(Q);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}class v{parse(Q,Y,Z){if(Q.timedOut){let $=Z?.timeoutBehavior||"ignore",X="Hook timeout";if($==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if($==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let W=this.tryParseJSON(Q.stdout);if(W){let $=p(W);if(!$.success){let G="error"in $?$.error.message:"Unknown validation error",J=Z?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${G}`;if(J==="deny")return{success:!1,blocking:!0,error:K,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if(J==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:K,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let X=$.data;if(X.decision?.behavior==="block")return{success:!1,blocking:!0,error:X.systemMessage||"Hook blocked execution",output:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};if(X.decision?.behavior==="async")return{success:!0,output:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};return{success:!0,output:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}return this.parseByExitCode(Q,Y,Z)}parseByExitCode(Q,Y,Z){let W=Q.exitCode;switch(W){case 0:return{success:!0,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};case 2:return{success:!1,blocking:!0,error:Q.stderr||Q.stdout||"Hook returned exit code 2",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};case 124:{let $=Z?.timeoutBehavior||"ignore",X="Hook timeout";if($==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if($==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y}}default:{let $=Z?.failureBehavior||"ignore",X=Q.stderr||Q.stdout||`Hook failed with exit code ${W}`;if($==="deny")return{success:!1,blocking:!0,error:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if($==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${X}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y}}}}tryParseJSON(Q){try{let Y=Q.trim();if(!Y)return null;let Z=Y.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Z)return null;return JSON.parse(Z[1])}catch{return null}}}import{spawn as l}from"node:child_process";var PQ=500;function TQ(Q){return new Promise((Y)=>setTimeout(Y,Q))}function u(Q){return Q&&typeof Q==="object"&&"code"in Q?String(Q.code):void 0}function NQ(Q,Y){return new Promise((Z)=>{let W=["/PID",String(Q),"/T"];if(Y)W.push("/F");let $=l("taskkill",W,{stdio:"ignore",windowsHide:!0}),X=!1,G=(J)=>{if(X)return;X=!0,Z(J)};$.once("error",()=>G(!1)),$.once("close",(J)=>G(J===0))})}class a{child;state="owned";terminationPromise;terminationResult;platform;gracePeriodMs;killProcess;taskkill;wait;constructor(Q,Y={}){this.child=Q;this.platform=Y.platform??process.platform,this.gracePeriodMs=Y.gracePeriodMs??PQ,this.killProcess=Y.killProcess??process.kill.bind(process),this.taskkill=Y.taskkill??NQ,this.wait=Y.wait??TQ;let Z=()=>{if(this.state==="owned")this.state="released"};Q.once("close",Z),Q.once("error",Z)}release(){if(this.state==="owned")this.state="released"}terminate(){if(this.terminationPromise)return this.terminationPromise;if(this.terminationResult)return Promise.resolve(this.terminationResult);if(this.state==="released")return this.terminationResult={success:!0,alreadyExited:!0,forced:!1},Promise.resolve(this.terminationResult);return this.state="terminating",this.terminationPromise=this.terminateOwnedTree().then((Q)=>{return this.state="released",this.terminationResult=Q,Q}),this.terminationPromise}async terminateOwnedTree(){let Q=this.child.pid;if(!Q)return{success:!1,alreadyExited:!0,forced:!1};if(this.platform==="win32"){let W=await this.taskkill(Q,!1);await this.wait(this.gracePeriodMs);let $=await this.taskkill(Q,!0);if(!W&&!$)return{success:this.signalDirectChild("SIGKILL"),alreadyExited:!1,forced:!0};return{success:!0,alreadyExited:!1,forced:!0}}let Y=this.signalPosixTree(Q,"SIGTERM");await this.wait(this.gracePeriodMs);let Z=this.signalPosixTree(Q,"SIGKILL");return{success:Y||Z,alreadyExited:!1,forced:Z}}signalPosixTree(Q,Y){if(Q<=1||Q===process.pid)return this.signalDirectChild(Y);try{return this.killProcess(-Q,Y)}catch(Z){if(u(Z)==="ESRCH")return!0;return this.signalDirectChild(Y)}}signalDirectChild(Q){try{return this.child.kill(Q)}catch(Y){return u(Y)==="ESRCH"}}}function i(Q,Y,Z={}){let W=l(Q,Y,{...Z,detached:process.platform==="win32"?Z.detached:!0,windowsHide:Z.windowsHide??!0});return{child:W,processTree:new a(W)}}class g{content="";maxSize;constructor(Q){this.maxSize=Q}append(Q){if(this.content.length<this.maxSize){let Y=this.maxSize-this.content.length;this.content+=Q.substring(0,Y)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class d{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute(Q,Y,Z,W){let $=JSON.stringify(Y);if($.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${$.length} bytes (max ${this.MAX_INPUT_SIZE})`);let X=this.createSafeEnv(Y),{child:G,processTree:J}=i(Q,[],{shell:!0,env:X,cwd:Z.projectDir}),K=new g(this.MAX_STDOUT_SIZE),V=new g(this.MAX_STDERR_SIZE);G.stdout?.setEncoding("utf8"),G.stderr?.setEncoding("utf8"),G.stdout?.on("data",(D)=>{K.append(D)}),G.stderr?.on("data",(D)=>{V.append(D)});try{G.stdin?.write($),G.stdin?.end()}catch(D){throw await J.terminate(),Error(`Failed to write hook input: ${D}`)}return new Promise((D,R)=>{let L=!1,F=!1,B,O=()=>{return B??=J.terminate(),B},U=null,y=()=>{if(U&&Z.abortSignal)Z.abortSignal.removeEventListener("abort",U),U=null},M=setTimeout(()=>{L=!0,O()},W);if(G.on("close",async(w)=>{if(F)return;if(F=!0,clearTimeout(M),y(),L)await O();D({stdout:K.getContent(),stderr:V.getContent(),exitCode:L?124:w??1,timedOut:L})}),G.on("error",(w)=>{if(F)return;F=!0,clearTimeout(M),y(),R(w)}),Z.abortSignal){if(U=()=>{if(F)return;F=!0,clearTimeout(M),y(),O().then(()=>{D({stdout:K.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})})},Z.abortSignal.addEventListener("abort",U),Z.abortSignal.aborted)U()}})}createSafeEnv(Q){return{BLADE_PROJECT_DIR:Q.project_dir,BLADE_SESSION_ID:Q.session_id,BLADE_HOOK_EVENT:Q.hook_event_name,BLADE_TOOL_NAME:"tool_name"in Q?Q.tool_name:"",BLADE_TOOL_USE_ID:"tool_use_id"in Q?Q.tool_use_id:"",PATH:process.env.PATH||"",HOME:process.env.HOME||"",USER:process.env.USER||"",SHELL:process.env.SHELL||"/bin/sh"}}}class P extends Error{constructor(Q){super(Q);this.name="HttpHookSecurityError"}}function c(Q,Y={}){let Z;try{Z=new URL(Q)}catch{throw new P(`Invalid URL: ${Q}`)}if(Z.protocol!=="https:"&&Z.protocol!=="http:")throw new P(`Only http/https supported, got: ${Z.protocol}`);let W=Z.hostname.toLowerCase();if(bQ(W,Y.allowedHosts))return;if(Z.protocol==="http:"&&!Y.allowHttp)throw new P(`HTTP (non-TLS) blocked for ${W}; use https:// or add to allowedHosts`);if(yQ(W)&&!Y.allowLoopback)throw new P(`Loopback address blocked: ${W}; enable policy.allowLoopback or add to allowedHosts`);if(MQ(W)&&!Y.allowPrivateRanges)throw new P(`Private/link-local address blocked: ${W}; enable policy.allowPrivateRanges or add to allowedHosts`)}function bQ(Q,Y){if(!Y||Y.length===0)return!1;return Y.some((Z)=>{let W=Z.toLowerCase();if(W===Q)return!0;if(W.startsWith("*.")){let $=W.slice(1);return Q.endsWith($)&&Q.length>$.length}return!1})}function yQ(Q){if(Q==="localhost")return!0;if(Q==="::1"||Q==="[::1]")return!0;if(/^127\.\d+\.\d+\.\d+$/.test(Q))return!0;return!1}function MQ(Q){let Y=Q.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);if(!Y)return!1;let[Z,W]=Y.slice(1).map(Number);if(Z===10)return!0;if(Z===172&&W>=16&&W<=31)return!0;if(Z===192&&W===168)return!0;if(Z===169&&W===254)return!0;return!1}function s(Q){if(!Q)return{};let Y={};for(let[Z,W]of Object.entries(Q))Y[Z]=W.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,($,X)=>{return process.env[X]??`\${${X}}`});return Y}var wQ=r("Execution"),CQ={PreToolUse:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "...", "updatedInput": { ... } }',PostToolUse:'{ "additionalContext": "注入到工具结果的额外信息", "updatedOutput": "修改后的工具输出" }',Stop:'{ "continue": true, "continueReason": "继续执行的原因" } // continue: true 表示阻止停止',SubagentStop:'{ "continue": true, "continueReason": "...", "additionalContext": "..." }',PermissionRequest:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "..." }',UserPromptSubmit:'{ "updatedPrompt": "修改后的提示词", "contextInjection": "注入的上下文" }',Compaction:'{ "blockCompaction": true, "blockReason": "阻止压缩的原因" }'};class m{processExecutor=new d;outputParser=new v;chatServiceCache=new Map;async executePreToolHooks(Q,Y,Z){if(Q.length===0)return{decision:"allow"};let W="tool_input"in Y?Y.tool_input:{},$=[];for(let X of Q)try{let G={...Y,...W&&{tool_input:W}},J=await this.executeHook(X,G,Z);if(!J.success){if(J.blocking)return{decision:"deny",reason:J.error};if(J.needsConfirmation)return{decision:"ask",reason:J.warning||J.error};if(J.warning)$.push(J.warning);continue}let K=J.output?.hookSpecificOutput;if(K&&"permissionDecision"in K){switch(K.permissionDecision){case"deny":return{decision:"deny",reason:K.permissionDecisionReason};case"ask":return{decision:"ask",reason:K.permissionDecisionReason};case"allow":break}if("updatedInput"in K&&K.updatedInput)W={...W,...K.updatedInput}}}catch(G){let J=G instanceof Error?G.message:String(G);if($.push(`Hook failed: ${J}`),Z.config.failureBehavior==="deny")return{decision:"deny",reason:J};else if(Z.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${J}. Continue?`}}return{decision:"allow",modifiedInput:W,warning:$.length>0?$.join(`
|
|
2
|
-
`):void 0}}async executePostToolHooks(Q,Y,Z){if(Q.length===0)return{};let W=Z.config.maxConcurrentHooks||5,$=await this.executeHooksConcurrently(Q,Y,Z,W),X=[],G=void 0,J=[];for(let K of $){if(!K.success&&K.warning){J.push(K.warning);continue}let V=K.output?.hookSpecificOutput;if(V&&"additionalContext"in V){if(V.additionalContext)X.push(V.additionalContext);if("updatedOutput"in V&&V.updatedOutput!==void 0)G=V.updatedOutput}}return{additionalContext:X.length>0?X.join(`
|
|
3
|
-
|
|
4
|
-
`):void 0,modifiedOutput:G,warning:J.length>0?J.join(`
|
|
5
|
-
`):void 0}}async executeStopHooks(Q,Y,Z){if(Q.length===0)return{shouldStop:!0};let W=[];for(let $ of Q)try{let X=await this.executeHook($,Y,Z);if(!X.success){if(X.warning)W.push(X.warning);continue}let G=X.output?.hookSpecificOutput;if(G&&"continue"in G&&G.continue===!1)return{shouldStop:!1,continueReason:G.continueReason,warning:W.length>0?W.join(`
|
|
6
|
-
`):void 0}}catch(X){let G=X instanceof Error?X.message:String(X);W.push(`Hook failed: ${G}`)}return{shouldStop:!0,warning:W.length>0?W.join(`
|
|
7
|
-
`):void 0}}async executeSubagentStopHooks(Q,Y,Z){if(Q.length===0)return{shouldStop:!0};let W=[],$=[];for(let X of Q)try{let G=await this.executeHook(X,Y,Z);if(!G.success){if(G.warning)W.push(G.warning);continue}let J=G.output?.hookSpecificOutput;if(J&&"continue"in J){if(J.continue===!1)return{shouldStop:!1,continueReason:J.continueReason,warning:W.length>0?W.join(`
|
|
8
|
-
`):void 0};if("additionalContext"in J&&J.additionalContext)$.push(J.additionalContext)}}catch(G){let J=G instanceof Error?G.message:String(G);W.push(`Hook failed: ${J}`)}return{shouldStop:!0,additionalContext:$.length>0?$.join(`
|
|
9
|
-
|
|
10
|
-
`):void 0,warning:W.length>0?W.join(`
|
|
11
|
-
`):void 0}}async executePermissionRequestHooks(Q,Y,Z){if(Q.length===0)return{decision:"ask"};let W=[];for(let $ of Q)try{let X=await this.executeHook($,Y,Z);if(!X.success){if(X.warning)W.push(X.warning);continue}let G=X.output?.hookSpecificOutput;if(G&&"permissionDecision"in G){let J=G.permissionDecision;if(J==="approve"||J==="deny")return{decision:J,reason:G.permissionDecisionReason,warning:W.length>0?W.join(`
|
|
12
|
-
`):void 0}}}catch(X){let G=X instanceof Error?X.message:String(X);W.push(`Hook failed: ${G}`)}return{decision:"ask",warning:W.length>0?W.join(`
|
|
13
|
-
`):void 0}}async executeUserPromptSubmitHooks(Q,Y,Z){if(Q.length===0)return{proceed:!0};let W=[],$=[],X;for(let G of Q)try{let J=await this.executeHook(G,Y,Z);if(!J.success){if(J.blocking)return{proceed:!1,warning:J.error};if(J.warning)W.push(J.warning);continue}if(J.stdout&&J.stdout.trim())$.push(J.stdout.trim());let K=J.output?.hookSpecificOutput;if(K&&"updatedPrompt"in K){if(K.updatedPrompt)X=K.updatedPrompt;if(K.contextInjection)$.push(K.contextInjection)}}catch(J){let K=J instanceof Error?J.message:String(J);W.push(`Hook failed: ${K}`)}return{proceed:!0,updatedPrompt:X,contextInjection:$.length>0?$.join(`
|
|
14
|
-
|
|
15
|
-
`):void 0,warning:W.length>0?W.join(`
|
|
16
|
-
`):void 0}}async executeSessionStartHooks(Q,Y,Z){if(Q.length===0)return{proceed:!0};let W=[],$={};for(let X of Q)try{let G=await this.executeHook(X,Y,Z);if(!G.success){if(G.blocking)return{proceed:!1,warning:G.error};if(G.warning)W.push(G.warning);continue}let J=G.output?.hookSpecificOutput;if(J&&"env"in J&&J.env)Object.assign($,J.env)}catch(G){let J=G instanceof Error?G.message:String(G);W.push(`Hook failed: ${J}`)}return{proceed:!0,env:Object.keys($).length>0?$:void 0,warning:W.length>0?W.join(`
|
|
17
|
-
`):void 0}}async executeSessionEndHooks(Q,Y,Z){if(Q.length===0)return{};let W=[],$=Z.config.maxConcurrentHooks||5,X=await this.executeHooksConcurrently(Q,Y,Z,$);for(let G of X)if(!G.success&&G.warning)W.push(G.warning);return{warning:W.length>0?W.join(`
|
|
18
|
-
`):void 0}}async executePostToolUseFailureHooks(Q,Y,Z){if(Q.length===0)return{};let W=[],$=[],X=Z.config.maxConcurrentHooks||5,G=await this.executeHooksConcurrently(Q,Y,Z,X);for(let J of G){if(!J.success&&J.warning){W.push(J.warning);continue}if(J.stdout&&J.stdout.trim())$.push(J.stdout.trim())}return{additionalContext:$.length>0?$.join(`
|
|
19
|
-
|
|
20
|
-
`):void 0,warning:W.length>0?W.join(`
|
|
21
|
-
`):void 0}}async executeNotificationHooks(Q,Y,Z){let W="message"in Y?Y.message:"";if(Q.length===0)return{suppress:!1,message:W};let $=[],X=!1,G=W;for(let J of Q)try{let K=await this.executeHook(J,Y,Z);if(!K.success){if(K.warning)$.push(K.warning);continue}if(K.output?.suppressOutput){X=!0;break}if(K.stdout&&K.stdout.trim())G=K.stdout.trim()}catch(K){let V=K instanceof Error?K.message:String(K);$.push(`Hook failed: ${V}`)}return{suppress:X,message:G,warning:$.length>0?$.join(`
|
|
22
|
-
`):void 0}}async executeCompactionHooks(Q,Y,Z){if(Q.length===0)return{blockCompaction:!1};let W=[];for(let $ of Q)try{let X=await this.executeHook($,Y,Z);if(!X.success){if(X.warning)W.push(X.warning);continue}let G=X.output?.hookSpecificOutput;if(G&&"blockCompaction"in G&&G.blockCompaction)return{blockCompaction:!0,blockReason:G.blockReason,warning:W.length>0?W.join(`
|
|
23
|
-
`):void 0}}catch(X){let G=X instanceof Error?X.message:String(X);W.push(`Hook failed: ${G}`)}return{blockCompaction:!1,warning:W.length>0?W.join(`
|
|
24
|
-
`):void 0}}async executeHook(Q,Y,Z){if(Q.type==="command")return this.executeCommandHook(Q,Y,Z);if(Q.type==="prompt")return this.executePromptHook(Q,Y,Z);if(Q.type==="function")return this.executeFunctionHook(Q,Y,Z);if(Q.type==="http")return this.executeHttpHook(Q,Y,Z);throw Error(`Hook type ${Q.type} not supported`)}async executeCommandHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let $=await this.processExecutor.execute(Q.command,Y,Z,W);return this.outputParser.parse($,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch($){return{success:!1,blocking:!1,error:$ instanceof Error?$.message:String($),hook:Q}}}async executePromptHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let $=await this.getOrCreateChatService(Q.model),X="hook_event_name"in Y?String(Y.hook_event_name):"Unknown",G=this.buildPromptHookSystemMessage(Q,X),J=JSON.stringify(Y,null,2),K=new AbortController,V=setTimeout(()=>K.abort(),W),D;try{D=(await $.chat([{role:"system",content:G},{role:"user",content:J}],void 0,K.signal)).content}catch(L){if(K.signal.aborted||L instanceof Error&&L.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});throw L}finally{clearTimeout(V)}let R=this.extractJsonFromLLMResponse(D);return this.outputParser.parse({stdout:R,stderr:"",exitCode:0,timedOut:!1},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch($){return wQ.warn(`[PromptHook] 执行失败: ${$ instanceof Error?$.message:String($)}`),{success:!1,blocking:!1,error:$ instanceof Error?$.message:String($),hook:Q}}}async executeFunctionHook(Q,Y,Z){let W=(Q.timeout??10)*1000;try{let $=await this.runFunctionWithTimeout(Q.handler,Y,Z,W);if($===void 0||$===null)return{success:!0,hook:Q};let X={stdout:JSON.stringify($),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(X,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch($){if($.isTimeout){let X={stdout:"",stderr:`Function hook timeout after ${W}ms`,exitCode:124,timedOut:!0};return this.outputParser.parse(X,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}return{success:!1,blocking:!1,error:$ instanceof Error?$.message:String($),hook:Q}}}runFunctionWithTimeout(Q,Y,Z,W){return new Promise(($,X)=>{let G=!1,J=setTimeout(()=>{if(G)return;G=!0;let V=Object.assign(Error(`Function hook timed out after ${W}ms`),{isTimeout:!0});X(V)},W),K=()=>{if(G)return;G=!0,clearTimeout(J),X(Error("Function hook aborted"))};Z.abortSignal?.addEventListener("abort",K,{once:!0}),Promise.resolve().then(()=>Q(Y,Z)).then((V)=>{if(G)return;G=!0,clearTimeout(J),Z.abortSignal?.removeEventListener("abort",K),$(V)},(V)=>{if(G)return;G=!0,clearTimeout(J),Z.abortSignal?.removeEventListener("abort",K),X(V)})})}async executeHttpHook(Q,Y,Z){let W=(Q.timeout??10)*1000,$=Q.maxResponseBytes??262144,X=Math.max(1,(Q.retries??0)+1);try{c(Q.url,Z.config.httpPolicy)}catch(V){return{success:!1,blocking:!0,error:V instanceof Error?V.message:String(V),hook:Q}}let G={"Content-Type":"application/json",...s(Q.headers)},J=JSON.stringify(Y),K;for(let V=0;V<X;V++){if(V>0){let F=Math.min(2**V*200,5000);await new Promise((B)=>setTimeout(B,F))}let D=new AbortController,R=setTimeout(()=>D.abort(),W),L=()=>D.abort();Z.abortSignal?.addEventListener("abort",L,{once:!0});try{let F=await fetch(Q.url,{method:"POST",headers:G,body:J,redirect:"manual",signal:D.signal});if(F.status>=300&&F.status<400){K=Error(`HTTP hook received redirect (${F.status}); redirects are disabled`);continue}if(!F.ok){if(K=Error(`HTTP hook returned ${F.status} ${F.statusText}`),F.status>=400&&F.status<500)break;continue}let O={stdout:await SQ(F,$),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(O,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(F){let B=F.name==="AbortError"||F.code==="ABORT_ERR";if(B&&Z.abortSignal?.aborted){K=Error("HTTP hook aborted by caller");break}if(B){let O={stdout:"",stderr:`HTTP hook timeout after ${W}ms`,exitCode:124,timedOut:!0};if(V===X-1)return this.outputParser.parse(O,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});K=Error(`HTTP hook timeout attempt ${V+1}`);continue}K=F}finally{clearTimeout(R),Z.abortSignal?.removeEventListener("abort",L)}}return{success:!1,blocking:!1,error:K?.message??"HTTP hook failed",hook:Q}}async getOrCreateChatService(Q){let Y=Q||"__default__",Z=this.chatServiceCache.get(Y);if(Z)return Z;let{ensureStoreInitialized:W,getCurrentModel:$,getModelById:X}=await import("./chunk-mpskff34.js"),{createChatServiceAsync:G}=await import("./chunk-bwaqaktn.js");await W();let J=Q?X(Q)||$():$();if(!J)throw Error("PromptHook: 无法获取模型配置。请确保至少配置了一个模型。");let K=await G({provider:J.provider,apiKey:J.apiKey,baseUrl:J.baseUrl,model:J.model,temperature:J.temperature,maxContextTokens:J.maxContextTokens,maxOutputTokens:J.maxOutputTokens});return this.chatServiceCache.set(Y,K),K}buildPromptHookSystemMessage(Q,Y){let Z=CQ[Y]||"{ ... 根据事件类型返回相应字段 }";return`你是一个代码质量评估器,作为 Hook 在 ${Y} 事件中被触发。
|
|
25
|
-
|
|
26
|
-
`+`## 评估指令
|
|
27
|
-
${Q.prompt}
|
|
28
|
-
|
|
29
|
-
`+`## 输出格式
|
|
30
|
-
`+`必须返回一个 JSON 对象(不要包含任何其他文本):
|
|
31
|
-
`+`{
|
|
32
|
-
"decision": { "behavior": "approve" | "block" },
|
|
33
|
-
`+` "systemMessage": "可选的说明信息",
|
|
34
|
-
`+` "hookSpecificOutput": ${Z}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
`+`重要规则:
|
|
38
|
-
`+`- 只输出 JSON,不要包含 markdown 代码块或其他文本
|
|
39
|
-
`+`- 如果没有发现问题,使用 "approve"
|
|
40
|
-
`+'- 只在发现严重问题时使用 "block"'}extractJsonFromLLMResponse(Q){let Y=Q.trim(),Z=Y.match(/^```(?:json)?\s*\n?([\s\S]*?)\n?\s*```$/);if(Z)return Z[1].trim();return Y}async executeHooksConcurrently(Q,Y,Z,W){let $=[],X=new Set;for(let G of Q){if(X.size>=W)await Promise.race(X);let J=this.executeHook(G,Y,Z).catch((V)=>({success:!1,blocking:!1,error:V instanceof Error?V.message:String(V),hook:G})),K=J.then(()=>{X.delete(K)}).catch(()=>{X.delete(K)});X.add(K),$.push(J)}return Promise.all($)}}async function SQ(Q,Y){let Z=Q.body?.getReader();if(!Z)return"";let W=new TextDecoder,$=0,X="";while(!0){let{value:G,done:J}=await Z.read();if(J)break;if($+=G.byteLength,$>Y){try{Z.cancel()}catch{}X+=W.decode(G.slice(0,Y-($-G.byteLength)));break}X+=W.decode(G,{stream:!0})}return X+=W.decode(),X}import k from"picomatch";var EQ=/^([A-Za-z0-9_|]+)\((.+)\)$/;class h{matches(Q,Y){if(!Q)return!0;if(Q.tools&&Y.toolName){if(!this.matchTools(Q.tools,Y))return!1}if(Q.paths&&Y.filePath){if(!this.matchPaths(Q.paths,Y.filePath))return!1}if(Q.commands&&Y.command){if(!this.matchCommands(Q.commands,Y.command))return!1}return!0}matchTools(Q,Y){if(Array.isArray(Q))return Q.some((Z)=>this.matchToolWithParams(Z,Y));return this.matchToolWithParams(Q,Y)}matchPaths(Q,Y){if(Array.isArray(Q))return Q.some((W)=>{return k(W)(Y)});return k(Q)(Y)}matchCommands(Q,Y){if(Array.isArray(Q))return Q.some((Z)=>this.matchPattern(Y,Z));return this.matchPattern(Y,Q)}matchToolWithParams(Q,Y){let{toolName:Z,command:W,filePath:$}=Y,X=EQ.exec(Q);if(!X)return this.matchPattern(Z,Q);let[,G,J]=X;if(!this.matchPattern(Z,G))return!1;let K=this.getArgValue(Z,W,$);if(!K)return!1;return this.matchGlobOrPattern(K,J)}getArgValue(Q,Y,Z){if(Q==="Bash"||Q==="BashTool")return Y;if(["Read","Edit","Write","Glob","Grep"].includes(Q))return Z;return Y||Z}matchGlobOrPattern(Q,Y){if(/[*?[\]{}!]/.test(Y))try{return k(Y,{bash:!0,dot:!0})(Q)}catch{}if(Y.endsWith("*")){let Z=Y.slice(0,-1);return Q.startsWith(Z)}return Q===Y}matchPattern(Q,Y){if(Y==="*")return!0;if(!Y.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Y))return Q===Y;if(Y.includes("|"))return Y.split("|").map((W)=>W.trim()).includes(Q);try{return new RegExp(Y).test(Q)}catch{return Q===Y}}}class T{static instance=null;config=I;executor=new m;guard=new z;matcher=new h;sessionDisabled=!1;constructor(){}static getInstance(){if(!T.instance)T.instance=new T;return T.instance}loadConfig(Q){let Y=f(I,Q),Z=x();Y=f(Y,Z),this.config=Y}isEnabled(){if(!this.config.enabled)return!1;if(this.sessionDisabled)return!1;return!0}disable(){this.sessionDisabled=!0,console.log("[HookManager] Hooks disabled for this session")}enable(){this.sessionDisabled=!1,console.log("[HookManager] Hooks enabled for this session")}getConfig(){return this.config}registerFunction(Q,Y,Z,W){let $={type:"function",handler:Z,timeout:W?.timeout},X={name:W?.name??`inline-${Q}-${Date.now()}`,matcher:Y,hooks:[$]},G=this.config[Q]??[];return this.config[Q]=[...G,X],()=>{let J=this.config[Q];if(!J)return;this.config[Q]=J.filter((K)=>K!==X)}}async reloadConfig(){let Q=await import("node:fs/promises"),Y=await import("node:path");try{let Z=Y.join(n(),".blade","settings.local.json"),W=await Q.readFile(Z,"utf-8"),$=JSON.parse(W);if($.hooks)this.loadConfig($.hooks)}catch{}}async executePreToolHooks(Q,Y,Z,W){if(!this.isEnabled())return{decision:"allow"};if(W.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Y,"PreToolUse"))return{decision:"allow"};let $={hook_event_name:"PreToolUse",hook_execution_id:A(),timestamp:new Date().toISOString(),tool_name:Q,tool_use_id:Y,tool_input:Z,project_dir:W.projectDir,session_id:W.sessionId,permission_mode:W.permissionMode},X=this.getMatchingHooks("PreToolUse",{toolName:Q,filePath:this.extractFilePath(Z),command:this.extractCommand(Q,Z)});if(X.length===0)return{decision:"allow"};let G={projectDir:W.projectDir,sessionId:W.sessionId,permissionMode:W.permissionMode,config:this.config,abortSignal:W.abortSignal};try{let J=await this.executor.executePreToolHooks(X,$,G);if(this.guard.markExecuted(Y,"PreToolUse"),W.permissionMode==="yolo"){if(J.decision==="deny")return J;return{decision:"allow",modifiedInput:J.modifiedInput,warning:J.warning,reason:J.reason}}return J}catch(J){return console.error("[HookManager] Error executing PreToolUse hooks:",J),{decision:"allow",warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolHooks(Q,Y,Z,W,$){if(!this.isEnabled())return{};if($.permissionMode==="plan")return{};if(!this.guard.canExecute(Y,"PostToolUse"))return{};let X={hook_event_name:"PostToolUse",hook_execution_id:A(),timestamp:new Date().toISOString(),tool_name:Q,tool_use_id:Y,tool_input:Z,tool_response:W,project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode},G=this.getMatchingHooks("PostToolUse",{toolName:Q,filePath:this.extractFilePath(Z),command:this.extractCommand(Q,Z)});if(G.length===0)return{};let J={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{let K=await this.executor.executePostToolHooks(G,X,J);return this.guard.markExecuted(Y,"PostToolUse"),K}catch(K){return console.error("[HookManager] Error executing PostToolUse hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}finally{this.guard.cleanup(Y)}}async executeStopHooks(Q){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"Stop",hook_execution_id:A(),timestamp:new Date().toISOString(),project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode,reason:Q.reason},Z=this.getMatchingHooks("Stop",{});if(Z.length===0)return{shouldStop:!0};let W={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executeStopHooks(Z,Y,W)}catch($){return console.error("[HookManager] Error executing Stop hooks:",$),{shouldStop:!0,warning:`Hook execution failed: ${$ instanceof Error?$.message:String($)}`}}}async executeSubagentStopHooks(Q,Y){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"SubagentStop",hook_execution_id:A(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,agent_type:Q,task_description:Y.taskDescription,success:Y.success,result_summary:Y.resultSummary,error:Y.error},W=this.getMatchingHooks("SubagentStop",{});if(W.length===0)return{shouldStop:!0};let $={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeSubagentStopHooks(W,Z,$)}catch(X){return console.error("[HookManager] Error executing SubagentStop hooks:",X),{shouldStop:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executePermissionRequestHooks(Q,Y,Z,W){if(!this.isEnabled())return{decision:"ask"};let $={hook_event_name:"PermissionRequest",hook_execution_id:A(),timestamp:new Date().toISOString(),tool_name:Q,tool_use_id:Y,tool_input:Z,project_dir:W.projectDir,session_id:W.sessionId,permission_mode:W.permissionMode},X=this.getMatchingHooks("PermissionRequest",{toolName:Q,filePath:this.extractFilePath(Z),command:this.extractCommand(Q,Z)});if(X.length===0)return{decision:"ask"};let G={projectDir:W.projectDir,sessionId:W.sessionId,permissionMode:W.permissionMode,config:this.config,abortSignal:W.abortSignal};try{return await this.executor.executePermissionRequestHooks(X,$,G)}catch(J){return console.error("[HookManager] Error executing PermissionRequest hooks:",J),{decision:"ask",warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executeUserPromptSubmitHooks(Q,Y){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"UserPromptSubmit",hook_execution_id:A(),timestamp:new Date().toISOString(),user_prompt:Q,has_images:Y.hasImages,image_count:Y.imageCount,project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode},W=this.getMatchingHooks("UserPromptSubmit",{});if(W.length===0)return{proceed:!0};let $={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(W,Z,$)}catch(X){return console.error("[HookManager] Error executing UserPromptSubmit hooks:",X),{proceed:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSessionStartHooks(Q){if(!this.isEnabled())return{proceed:!0};let Y={hook_event_name:"SessionStart",hook_execution_id:A(),timestamp:new Date().toISOString(),project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode,is_resume:Q.isResume,resume_session_id:Q.resumeSessionId},Z=this.getMatchingHooks("SessionStart",{});if(Z.length===0)return{proceed:!0};let W={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executeSessionStartHooks(Z,Y,W)}catch($){return console.error("[HookManager] Error executing SessionStart hooks:",$),{proceed:!0,warning:`Hook execution failed: ${$ instanceof Error?$.message:String($)}`}}}async executeSessionEndHooks(Q,Y){if(!this.isEnabled())return{};let Z={hook_event_name:"SessionEnd",hook_execution_id:A(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,reason:Q},W=this.getMatchingHooks("SessionEnd",{});if(W.length===0)return{};let $={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeSessionEndHooks(W,Z,$),{}}catch(X){return console.error("[HookManager] Error executing SessionEnd hooks:",X),{warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executePostToolUseFailureHooks(Q,Y,Z,W,$){if(!this.isEnabled())return{};let X={hook_event_name:"PostToolUseFailure",hook_execution_id:A(),timestamp:new Date().toISOString(),tool_name:Q,tool_use_id:Y,tool_input:Z,error:W,error_type:$.errorType,is_interrupt:$.isInterrupt,is_timeout:$.isTimeout,project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode},G=this.getMatchingHooks("PostToolUseFailure",{toolName:Q,filePath:this.extractFilePath(Z),command:this.extractCommand(Q,Z)});if(G.length===0)return{};let J={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(G,X,J)}catch(K){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executeNotificationHooks(Q,Y,Z){if(!this.isEnabled())return{suppress:!1,message:Y};let W={hook_event_name:"Notification",hook_execution_id:A(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,notification_type:Q,title:Z.title,message:Y},$=this.getMatchingHooks("Notification",{});if($.length===0)return{suppress:!1,message:Y};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeNotificationHooks($,W,X)}catch(G){return console.error("[HookManager] Error executing Notification hooks:",G),{suppress:!1,message:Y,warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeCompactionHooks(Q,Y){if(!this.isEnabled())return{blockCompaction:!1};let Z={hook_event_name:"Compaction",hook_execution_id:A(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,trigger:Q,messages_before:Y.messagesBefore,tokens_before:Y.tokensBefore},W=this.getMatchingHooks("Compaction",{});if(W.length===0)return{blockCompaction:!1};let $={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeCompactionHooks(W,Z,$)}catch(X){return console.error("[HookManager] Error executing Compaction hooks:",X),{blockCompaction:!1,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}getMatchingHooks(Q,Y){let Z=this.config[Q]||[],W=[];for(let $ of Z)if(this.matcher.matches($.matcher,Y))W.push(...$.hooks);return W}extractFilePath(Q){let Y=["file_path","path","filePath","source","target"];for(let Z of Y){let W=Q[Z];if(typeof W==="string")return W}return}extractCommand(Q,Y){if(Q==="Bash"||Q==="BashTool"){let Z=Y.command;if(typeof Z==="string")return Z}return}cleanup(){this.guard.cleanupAll()}}
|
|
41
|
-
export{N as sb,i as tb,T as ub};
|
package/dist/chunk-5be6qr2v.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{Fb as Q,Gb as W,Hb as Y}from"./chunk-6kp3z956.js";import{Zb as X}from"./chunk-a7yjnqhd.js";var J=X("Service"),$="https://models.dev/api.json",j=3600000,G=null,Z=async()=>{if(G&&Date.now()-G.timestamp<j)return G.data;try{J.info("Fetching models.dev data...");let q=await fetch($,{headers:{"User-Agent":"Blade-CLI/1.0"}});if(!q.ok)throw Error(`HTTP ${q.status}: ${q.statusText}`);let x=await q.json();return G={data:x,timestamp:Date.now()},J.info(`Loaded ${Object.keys(x).length} providers from models.dev`),x}catch(q){throw J.error("Failed to fetch models.dev data:",q),q}},y=async()=>{let q=await Z(),x=[];for(let[w,k]of Object.entries(q)){let z=Object.keys(k.models||{}).length;if(z===0)continue;x.push({id:w,name:k.name||w,icon:W[w]||W.default,description:`${z} 个模型`,envVars:k.env||[],docUrl:k.doc,defaultBaseUrl:Y[w]})}return x.sort((w,k)=>{let z=Q.indexOf(w.id),K=Q.indexOf(k.id);if(z!==-1&&K!==-1)return z-K;if(z!==-1)return-1;if(K!==-1)return 1;return w.name.localeCompare(k.name)})},f=async(q)=>{let w=(await Z())[q];if(!w?.models)return J.warn(`No models found for provider: ${q}`),[];return Object.values(w.models).map((k)=>({id:k.id,name:k.name||k.id,contextWindow:k.limit?.context,maxOutput:k.limit?.output,inputCost:k.cost?.input,outputCost:k.cost?.output}))};
|
|
2
|
-
export{y as j,f as k};
|