blade-code 0.4.4 → 0.4.6
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-tf0m57f5.js → chunk-2e3pajfb.js} +1 -1
- package/dist/{chunk-kd1t45br.js → chunk-6yvqtcx0.js} +1 -1
- package/dist/{chunk-ehcjnwnr.js → chunk-9syksrkj.js} +1 -1
- package/dist/chunk-c6ts8bd9.js +26 -0
- package/dist/{chunk-420vamtq.js → chunk-cfbp6h36.js} +1 -1
- package/dist/{chunk-8pn5m426.js → chunk-ctacwg1h.js} +1 -1
- package/dist/{chunk-5xc0kzdt.js → chunk-cwafz1g3.js} +1 -1
- package/dist/{chunk-5zkcs06z.js → chunk-d1hwbcne.js} +1 -1
- package/dist/{chunk-9mrna4y3.js → chunk-e38t8r4f.js} +1 -1
- package/dist/{chunk-mvyxksrz.js → chunk-f35tdzfy.js} +1 -1
- package/dist/{chunk-jvbx3h56.js → chunk-gkd5eew1.js} +140 -114
- package/dist/chunk-hhgbhadg.js +76 -0
- package/dist/{chunk-7637p6w5.js → chunk-hpafbk1w.js} +1 -1
- package/dist/{chunk-q4hrt6r4.js → chunk-ksd0cxtf.js} +1 -1
- package/dist/{chunk-52k9k0w8.js → chunk-mjgch1nt.js} +1 -1
- package/dist/{chunk-zs7xeymy.js → chunk-n466beq9.js} +1 -1
- package/dist/{chunk-094ekgv6.js → chunk-nhp35rk0.js} +2 -2
- package/dist/chunk-pe6dnssd.js +1 -0
- package/dist/chunk-pkmw32r0.js +8 -0
- package/dist/chunk-pmtfesmc.js +1 -0
- package/dist/{chunk-jz59sjzb.js → chunk-r8wmg3fc.js} +1 -1
- package/dist/{chunk-7snnj126.js → chunk-tf74ehds.js} +1 -1
- package/dist/{chunk-8jwqy5d0.js → chunk-v1c9xwen.js} +1 -1
- package/dist/chunk-vs5a1443.js +157 -0
- package/dist/{chunk-tph4ngbj.js → chunk-x2jkbn5c.js} +1 -1
- package/dist/{chunk-vwn39c84.js → chunk-xcpjsrem.js} +1 -1
- package/dist/{chunk-n8na8c5h.js → chunk-xpbgzgfz.js} +1 -1
- package/dist/{chunk-vs2x9sxb.js → chunk-yf7cz40m.js} +1 -1
- package/dist/{chunk-4jh0h16z.js → chunk-yhwrv3qf.js} +1 -1
- package/dist/{chunk-z1qz8p1j.js → chunk-ze1tddc3.js} +1 -1
- package/package.json +2 -2
- package/dist/chunk-5mtjqqav.js +0 -8
- package/dist/chunk-76emdpxa.js +0 -76
- package/dist/chunk-92kjp66d.js +0 -1
- package/dist/chunk-a5b9fkp3.js +0 -157
- package/dist/chunk-h3ccyfqj.js +0 -1
- package/dist/chunk-y5g06jmk.js +0 -24
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import{Ia as q0,Ka as A}from"./chunk-c6ts8bd9.js";import{Bb as K0}from"./chunk-set7v1rf.js";import{nanoid as i0}from"nanoid";import{devtools as o0,subscribeWithSelector as n0}from"zustand/middleware";import{createStore as s0}from"zustand/vanilla";var x0={name:"ayu-dark",colors:{primary:"#ffcc66",secondary:"#bae67e",accent:"#73d0ff",success:"#bae67e",warning:"#ffcc66",error:"#ff3333",info:"#73d0ff",light:"#f0f0f0",dark:"#000000",muted:"#5c6773",highlight:"#2d323b",text:{primary:"#e6e1cf",secondary:"#bae67e",muted:"#5c6773",light:"#ffffff"},background:{primary:"#0f1419",secondary:"#14191f",dark:"#000000"},border:{light:"#2d323b",dark:"#000000"},syntax:{comment:"#5c6773",string:"#bae67e",number:"#ffcc66",keyword:"#ff8f40",function:"#73d0ff",variable:"#e6e1cf",operator:"#f29e74",type:"#73d0ff",tag:"#ff8f40",attr:"#ffd580",default:"#e6e1cf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.2)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2)"}},B0={name:"dracula",colors:{primary:"#bd93f9",secondary:"#ffb86c",accent:"#ff79c6",success:"#50fa7b",warning:"#f1fa8c",error:"#ff5555",info:"#8be9fd",light:"#f8f8f2",dark:"#282a36",muted:"#6272a4",highlight:"#44475a",text:{primary:"#f8f8f2",secondary:"#f1fa8c",muted:"#6272a4",light:"#ffffff"},background:{primary:"#282a36",secondary:"#44475a",dark:"#21222c"},border:{light:"#44475a",dark:"#000000"},syntax:{comment:"#6272a4",string:"#f1fa8c",number:"#bd93f9",keyword:"#ff79c6",function:"#50fa7b",variable:"#f8f8f2",operator:"#ff79c6",type:"#8be9fd",tag:"#ff79c6",attr:"#50fa7b",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 42, 54, 0.2)",base:"0 1px 3px 0 rgba(40, 42, 54, 0.3), 0 1px 2px 0 rgba(40, 42, 54, 0.2)",lg:"0 10px 15px -3px rgba(40, 42, 54, 0.3), 0 4px 6px -2px rgba(40, 42, 54, 0.2)"}},w0={name:"monokai",colors:{primary:"#66d9ef",secondary:"#a6e22e",accent:"#f92672",success:"#a6e22e",warning:"#e6db74",error:"#f92672",info:"#66d9ef",light:"#f8f8f2",dark:"#272822",muted:"#75715e",highlight:"#3e3d32",text:{primary:"#f8f8f2",secondary:"#e6db74",muted:"#75715e",light:"#ffffff"},background:{primary:"#272822",secondary:"#3e3d32",dark:"#1e1f1c"},border:{light:"#3e3d32",dark:"#000000"},syntax:{comment:"#75715e",string:"#e6db74",number:"#ae81ff",keyword:"#f92672",function:"#a6e22e",variable:"#f8f8f2",operator:"#f92672",type:"#66d9ef",tag:"#f92672",attr:"#a6e22e",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(39, 40, 34, 0.2)",base:"0 1px 3px 0 rgba(39, 40, 34, 0.3), 0 1px 2px 0 rgba(39, 40, 34, 0.2)",lg:"0 10px 15px -3px rgba(39, 40, 34, 0.3), 0 4px 6px -2px rgba(39, 40, 34, 0.2)"}},A0={name:"nord",colors:{primary:"#88c0d0",secondary:"#81a1c1",accent:"#b48ead",success:"#a3be8c",warning:"#ebcb8b",error:"#bf616a",info:"#88c0d0",light:"#eceff4",dark:"#2e3440",muted:"#4c566a",highlight:"#434c5e",text:{primary:"#eceff4",secondary:"#d8dee9",muted:"#4c566a",light:"#ffffff"},background:{primary:"#2e3440",secondary:"#3b4252",dark:"#242933"},border:{light:"#434c5e",dark:"#000000"},syntax:{comment:"#616e88",string:"#a3be8c",number:"#b48ead",keyword:"#81a1c1",function:"#88c0d0",variable:"#d8dee9",operator:"#81a1c1",type:"#8fbcbb",tag:"#81a1c1",attr:"#8fbcbb",default:"#eceff4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(46, 52, 64, 0.2)",base:"0 1px 3px 0 rgba(46, 52, 64, 0.3), 0 1px 2px 0 rgba(46, 52, 64, 0.2)",lg:"0 10px 15px -3px rgba(46, 52, 64, 0.3), 0 4px 6px -2px rgba(46, 52, 64, 0.2)"}},D0={name:"solarized-light",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#cb4b16",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#93a1a1",highlight:"#eee8d5",text:{primary:"#586e75",secondary:"#657b83",muted:"#93a1a1",light:"#002b36"},background:{primary:"#fdf6e3",secondary:"#eee8d5",dark:"#073642"},border:{light:"#eee8d5",dark:"#073642"},syntax:{comment:"#93a1a1",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#657b83",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#657b83"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(253, 246, 227, 0.2)",base:"0 1px 3px 0 rgba(253, 246, 227, 0.3), 0 1px 2px 0 rgba(253, 246, 227, 0.2)",lg:"0 10px 15px -3px rgba(253, 246, 227, 0.3), 0 4px 6px -2px rgba(253, 246, 227, 0.2)"}},L0={name:"solarized-dark",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#b58900",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#586e75",highlight:"#073642",text:{primary:"#839496",secondary:"#93a1a1",muted:"#586e75",light:"#fdf6e3"},background:{primary:"#002b36",secondary:"#073642",dark:"#001f29"},border:{light:"#073642",dark:"#000000"},syntax:{comment:"#586e75",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#839496",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#839496"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 43, 54, 0.2)",base:"0 1px 3px 0 rgba(0, 43, 54, 0.3), 0 1px 2px 0 rgba(0, 43, 54, 0.2)",lg:"0 10px 15px -3px rgba(0, 43, 54, 0.3), 0 4px 6px -2px rgba(0, 43, 54, 0.2)"}},v0={name:"tokyo-night",colors:{primary:"#7aa2f7",secondary:"#7dcfff",accent:"#bb9af7",success:"#9ece6a",warning:"#e0af68",error:"#f7768e",info:"#7aa2f7",light:"#c0caf5",dark:"#1a1b26",muted:"#565f89",highlight:"#292e42",text:{primary:"#a9b1d6",secondary:"#c0caf5",muted:"#565f89",light:"#ffffff"},background:{primary:"#1a1b26",secondary:"#292e42",dark:"#16161e"},border:{light:"#292e42",dark:"#000000"},syntax:{comment:"#565f89",string:"#9ece6a",number:"#ff9e64",keyword:"#bb9af7",function:"#7aa2f7",variable:"#c0caf5",operator:"#89ddff",type:"#7dcfff",tag:"#f7768e",attr:"#7aa2f7",default:"#a9b1d6"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(26, 27, 38, 0.2)",base:"0 1px 3px 0 rgba(26, 27, 38, 0.3), 0 1px 2px 0 rgba(26, 27, 38, 0.2)",lg:"0 10px 15px -3px rgba(26, 27, 38, 0.3), 0 4px 6px -2px rgba(26, 27, 38, 0.2)"}},E0={name:"github",colors:{primary:"#0969da",secondary:"#8250df",accent:"#bc4c00",success:"#1a7f37",warning:"#bc4c00",error:"#d1242f",info:"#0969da",light:"#f6f8fa",dark:"#24292f",muted:"#6e7781",highlight:"#ddf4ff",text:{primary:"#24292f",secondary:"#57606a",muted:"#6e7781",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f6f8fa",dark:"#24292f"},border:{light:"#d0d7de",dark:"#24292f"},syntax:{comment:"#6e7781",string:"#0a3069",number:"#0550ae",keyword:"#cf222e",function:"#8250df",variable:"#24292f",operator:"#cf222e",type:"#0550ae",tag:"#116329",attr:"#0550ae",default:"#24292f"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(255, 255, 255, 0.2)",base:"0 1px 3px 0 rgba(255, 255, 255, 0.3), 0 1px 2px 0 rgba(255, 255, 255, 0.2)",lg:"0 10px 15px -3px rgba(255, 255, 255, 0.3), 0 4px 6px -2px rgba(255, 255, 255, 0.2)"}},y0={name:"gruvbox",colors:{primary:"#83a598",secondary:"#8ec07c",accent:"#d3869b",success:"#b8bb26",warning:"#fabd2f",error:"#fb4934",info:"#83a598",light:"#fbf1c7",dark:"#282828",muted:"#928374",highlight:"#3c3836",text:{primary:"#ebdbb2",secondary:"#d5c4a1",muted:"#928374",light:"#ffffff"},background:{primary:"#282828",secondary:"#3c3836",dark:"#1d2021"},border:{light:"#3c3836",dark:"#000000"},syntax:{comment:"#928374",string:"#b8bb26",number:"#d3869b",keyword:"#fb4934",function:"#8ec07c",variable:"#ebdbb2",operator:"#fe8019",type:"#fabd2f",tag:"#fb4934",attr:"#b8bb26",default:"#ebdbb2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 40, 40, 0.2)",base:"0 1px 3px 0 rgba(40, 40, 40, 0.3), 0 1px 2px 0 rgba(40, 40, 40, 0.2)",lg:"0 10px 15px -3px rgba(40, 40, 40, 0.3), 0 4px 6px -2px rgba(40, 40, 40, 0.2)"}},R0={name:"one-dark",colors:{primary:"#61afef",secondary:"#c678dd",accent:"#e5c07b",success:"#98c379",warning:"#e5c07b",error:"#e06c75",info:"#56b6c2",light:"#abb2bf",dark:"#282c34",muted:"#5c6370",highlight:"#3e4451",text:{primary:"#abb2bf",secondary:"#c6c8d0",muted:"#5c6370",light:"#ffffff"},background:{primary:"#282c34",secondary:"#3e4451",dark:"#21252b"},border:{light:"#3e4451",dark:"#000000"},syntax:{comment:"#5c6370",string:"#98c379",number:"#d19a66",keyword:"#c678dd",function:"#61afef",variable:"#e06c75",operator:"#56b6c2",type:"#e5c07b",tag:"#e06c75",attr:"#d19a66",default:"#abb2bf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 44, 52, 0.2)",base:"0 1px 3px 0 rgba(40, 44, 52, 0.3), 0 1px 2px 0 rgba(40, 44, 52, 0.2)",lg:"0 10px 15px -3px rgba(40, 44, 52, 0.3), 0 4px 6px -2px rgba(40, 44, 52, 0.2)"}},P0={name:"catppuccin",colors:{primary:"#89b4fa",secondary:"#cba6f7",accent:"#f5c2e7",success:"#a6e3a1",warning:"#f9e2af",error:"#f38ba8",info:"#89dceb",light:"#cdd6f4",dark:"#11111b",muted:"#6c7086",highlight:"#181825",text:{primary:"#cdd6f4",secondary:"#bac2de",muted:"#6c7086",light:"#ffffff"},background:{primary:"#1e1e2e",secondary:"#181825",dark:"#11111b"},border:{light:"#181825",dark:"#000000"},syntax:{comment:"#6c7086",string:"#a6e3a1",number:"#fab387",keyword:"#cba6f7",function:"#89b4fa",variable:"#cdd6f4",operator:"#89dceb",type:"#f5c2e7",tag:"#f38ba8",attr:"#89b4fa",default:"#cdd6f4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(30, 30, 46, 0.2)",base:"0 1px 3px 0 rgba(30, 30, 46, 0.3), 0 1px 2px 0 rgba(30, 30, 46, 0.2)",lg:"0 10px 15px -3px rgba(30, 30, 46, 0.3), 0 4px 6px -2px rgba(30, 30, 46, 0.2)"}},C0={name:"rose-pine",colors:{primary:"#9ccfd8",secondary:"#c4a7e7",accent:"#f6c177",success:"#31748f",warning:"#f6c177",error:"#eb6f92",info:"#9ccfd8",light:"#e0def4",dark:"#191724",muted:"#6e6a86",highlight:"#1f1d2e",text:{primary:"#e0def4",secondary:"#cecacd",muted:"#6e6a86",light:"#ffffff"},background:{primary:"#191724",secondary:"#1f1d2e",dark:"#12101a"},border:{light:"#1f1d2e",dark:"#000000"},syntax:{comment:"#6e6a86",string:"#9ccfd8",number:"#ea9a97",keyword:"#c4a7e7",function:"#31748f",variable:"#e0def4",operator:"#f6c177",type:"#9ccfd8",tag:"#eb6f92",attr:"#f6c177",default:"#e0def4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(25, 23, 36, 0.2)",base:"0 1px 3px 0 rgba(25, 23, 36, 0.3), 0 1px 2px 0 rgba(25, 23, 36, 0.2)",lg:"0 10px 15px -3px rgba(25, 23, 36, 0.3), 0 4px 6px -2px rgba(25, 23, 36, 0.2)"}},I0={name:"kanagawa",colors:{primary:"#8ba4b0",secondary:"#a292a3",accent:"#c47fd5",success:"#76946a",warning:"#c0a36e",error:"#c34043",info:"#7e9cd8",light:"#dcd7ba",dark:"#1f1f28",muted:"#727169",highlight:"#2a2a37",text:{primary:"#dcd7ba",secondary:"#c8c093",muted:"#727169",light:"#ffffff"},background:{primary:"#1f1f28",secondary:"#2a2a37",dark:"#16161d"},border:{light:"#2a2a37",dark:"#000000"},syntax:{comment:"#727169",string:"#98bb6c",number:"#d27e99",keyword:"#957fb8",function:"#7e9cd8",variable:"#dcd7ba",operator:"#c0a36e",type:"#7aa89f",tag:"#c34043",attr:"#7fb4ca",default:"#dcd7ba"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(31, 31, 40, 0.2)",base:"0 1px 3px 0 rgba(31, 31, 40, 0.3), 0 1px 2px 0 rgba(31, 31, 40, 0.2)",lg:"0 10px 15px -3px rgba(31, 31, 40, 0.3), 0 4px 6px -2px rgba(31, 31, 40, 0.2)"}},t=[{id:"ayu-dark",label:"Ayu Dark",theme:x0,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:B0,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:w0,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:A0,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:D0,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:L0,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:v0,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:E0,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:y0,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:R0,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:P0,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:C0,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:I0,tags:["dark","japanese"]}];var e={primary:"#0066cc",secondary:"#6c757d",accent:"#e83e8c",success:"#28a745",warning:"#ffc107",error:"#dc3545",info:"#17a2b8",light:"#f8f9fa",dark:"#343a40",muted:"#6c757d",highlight:"#fff3cd",text:{primary:"#212529",secondary:"#6c757d",muted:"#6c757d",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f8f9fa",dark:"#343a40"},border:{light:"#dee2e6",dark:"#495057"},syntax:{comment:"#6c757d",string:"#28a745",number:"#e83e8c",keyword:"#007bff",function:"#17a2b8",variable:"#495057",operator:"#ffc107",type:"#007bff",tag:"#dc3545",attr:"#ffc107",default:"#212529"}},p={name:"default",colors:e,spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.05)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},b0={...p,name:"dark",colors:{...e,text:{primary:"#ffffff",secondary:"#e2e8f0",muted:"#94a3b8",light:"#000000"},background:{primary:"#1e293b",secondary:"#334155",dark:"#0f172a"},border:{light:"#475569",dark:"#64748b"},syntax:{comment:"#94a3b8",string:"#34d399",number:"#f472b6",keyword:"#60a5fa",function:"#06b6d4",variable:"#e2e8f0",operator:"#fbbf24",type:"#60a5fa",tag:"#fb7185",attr:"#fbbf24",default:"#ffffff"}}};class Q0{currentTheme=p;themes=new Map;constructor(){this.themes.set("default",p),this.themes.set("dark",b0);for(let X of t)this.themes.set(X.id,X.theme)}setTheme(X){let Z=this.themes.get(X);if(Z)this.currentTheme=Z;else throw Error(`Theme '${X}' not found`)}getTheme(){return this.currentTheme}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName(X){return this.themes.get(X)}hasTheme(X){return this.themes.has(X)}}var X0=new Q0;var M0={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,tasks:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null},g=(X)=>({...M0,actions:{setInitializationStatus:(Z)=>{X((Q)=>({app:{...Q.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{X((Q)=>({app:{...Q.app,initializationError:Z}}))},setActiveModal:(Z)=>{X((Q)=>({app:{...Q.app,activeModal:Z}}))},showSessionSelector:(Z)=>{X((Q)=>({app:{...Q.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{X((Q)=>({app:{...Q.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{X((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTasks:(Z)=>{X((Q)=>({app:{...Q.app,tasks:Z}}))},updateTask:(Z)=>{X((Q)=>({app:{...Q.app,tasks:Q.app.tasks.map(($)=>$.id===Z.id?Z:$)}}))},setAwaitingSecondCtrlC:(Z)=>{X((Q)=>({app:{...Q.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{X((Q)=>({app:{...Q.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{X((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))},startSubagentProgress:(Z,Q,$)=>{X((Y)=>({app:{...Y.app,subagentProgress:{id:Z,type:Q,description:$,status:"running",startTime:Date.now()}}}))},updateSubagentTool:(Z)=>{X((Q)=>{if(!Q.app.subagentProgress)return Q;return{app:{...Q.app,subagentProgress:{...Q.app.subagentProgress,currentTool:Z}}}})},completeSubagentProgress:(Z)=>{X((Q)=>{if(!Q.app.subagentProgress)return Q;return{app:{...Q.app,subagentProgress:{...Q.app.subagentProgress,status:Z?"completed":"failed",currentTool:void 0}}}}),setTimeout(()=>{X((Q)=>({app:{...Q.app,subagentProgress:null}}))},1500)}}});var T0={isProcessing:!1,abortController:null,pendingCommands:[]},d=(X,Z)=>({...T0,actions:{setProcessing:(Q)=>{X(($)=>({command:{...$.command,isProcessing:Q}}))},createAbortController:()=>{let Q=Z().command.abortController;if(Q&&!Q.signal.aborted)Q.abort("interrupted-by-new-command");let $=new AbortController;return X((Y)=>({command:{...Y.command,abortController:$}})),$},getAbortController:()=>{return Z().command.abortController},clearAbortController:(Q)=>{let $=Z().command.abortController;if(Q!==void 0&&$!==Q)return;X((Y)=>({command:{...Y.command,abortController:null}}))},abort:(Q)=>{let{abortController:$}=Z().command;if($&&!$.signal.aborted)$.abort(Q??"user-cancel");X((Y)=>({command:{...Y.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(Q)=>{X(($)=>({command:{...$.command,pendingCommands:[...$.command.pendingCommands,Q]}}))},dequeueCommand:()=>{let{pendingCommands:Q}=Z().command;if(Q.length===0)return;let[$,...Y]=Q;return X((V)=>({command:{...V.command,pendingCommands:Y}})),$},clearQueue:()=>{X((Q)=>({command:{...Q.command,pendingCommands:[]}}))}}});var N0={config:null},m=(X)=>({...N0,actions:{setConfig:(Z)=>{X((Q)=>({config:{...Q.config,config:Z}}))},updateConfig:(Z)=>{X((Q)=>{if(!Q.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Z)}`);return{config:{...Q.config,config:{...Q.config.config,...Z}}}})}}});var u0={currentFocus:"main-input",previousFocus:null},r=(X)=>({...u0,actions:{setFocus:(Z)=>{X((Q)=>({focus:{...Q.focus,currentFocus:Z,previousFocus:Q.focus.currentFocus}}))},restorePreviousFocus:()=>{X((Z)=>({focus:{...Z.focus,currentFocus:Z.focus.previousFocus||"main-input",previousFocus:null}}))}}});import{nanoid as p0}from"nanoid";var c={"deepseek-chat":{input:0.27,output:1.1},"deepseek-coder":{input:0.14,output:0.28},"deepseek-reasoner":{input:0.55,output:2.19},"deepseek-v3":{input:0.27,output:1.1},"deepseek-v4-pro":{input:0.27,output:1.1},"gpt-4o":{input:2.5,output:10},"gpt-4o-mini":{input:0.15,output:0.6},"gpt-4-turbo":{input:10,output:30},"gpt-4":{input:30,output:60},"gpt-3.5-turbo":{input:0.5,output:1.5},o1:{input:15,output:60},"o1-mini":{input:3,output:12},"o1-pro":{input:150,output:600},o3:{input:10,output:40},"o3-mini":{input:1.1,output:4.4},"claude-3.5-sonnet":{input:3,output:15,cacheRead:0.3,cacheWrite:3.75},"claude-3.5-haiku":{input:0.8,output:4,cacheRead:0.08,cacheWrite:1},"claude-sonnet-4":{input:3,output:15,cacheRead:0.3,cacheWrite:3.75},"claude-4-opus":{input:15,output:75,cacheRead:1.5,cacheWrite:18.75},"qwen-plus":{input:0.8,output:2},"qwen-max":{input:2,output:6},"qwen-turbo":{input:0.3,output:0.6}};function h0(X){let Z=X.toLowerCase();if(c[Z])return c[Z];for(let[Q,$]of Object.entries(c))if(Z.includes(Q)||Q.includes(Z))return $;return}function Z0(X,Z,Q,$,Y){let V=h0(X);if(!V)return 0;let J=Z/1e6*V.input+Q/1e6*V.output;if($&&V.cacheRead)J+=$/1e6*V.cacheRead;if(Y&&V.cacheWrite)J+=Y/1e6*V.cacheWrite;return Math.round(J*1e6)/1e6}var K={codeBlock:/^```(\w+)?\s*$/,heading:/^ *(#{1,4}) +(.+)/,blockquote:/^(>+)\s?(.*)/,ulItem:/^([ \t]*)([-*+]) +(.+)/,olItem:/^([ \t]*)(\d+)\. +(.+)/,hr:/^ *([-*_] *){3,} *$/,table:/^\|(.+)\|$/,tableSeparator:/^\|[\s]*:?-+:?[\s]*(\|[\s]*:?-+:?[\s]*)+\|?$/,diffStart:/^<<<DIFF>>>$/,diffEnd:/^<<<\/DIFF>>>$/,commandMessage:/<command-message>(.*?)<\/command-message>/};function G1(X){let Z=[],Q=X.split(/\r?\n/),$=!1,Y=[],V=null,J=0,G=!1,U=[],H=[],W=!1,D=[],v=!1,O=[],z=0,j=!0;for(let L=0;L<Q.length;L++){let _=Q[L];if(W){if(_.match(K.diffEnd)){try{let B=JSON.parse(D.join(`
|
|
2
|
+
`));Z.push({type:"diff",content:"",diffData:{patch:B.patch,startLine:B.startLine,matchLine:B.matchLine}})}catch(B){Z.push({type:"text",content:D.join(`
|
|
3
|
+
`)})}W=!1,D=[],j=!1;continue}D.push(_);continue}if(_.match(K.diffStart)){W=!0,D=[],j=!1;continue}if($){let B=_.match(K.codeBlock),E=_.trim()==="```";if(B&&B[1])J++,Y.push(_);else if(E)if(J>0)J--,Y.push(_);else{let _0=Y.join(`
|
|
4
|
+
`);Z.push({type:"code",content:_0,language:V||void 0}),$=!1,Y=[],V=null,J=0,j=!1}else Y.push(_);continue}let s=_.match(K.codeBlock);if(s){$=!0,V=s[1]||null,J=0,j=!1;continue}let b=_.match(K.table),O0=_.match(K.tableSeparator);if(b&&!G){if(L+1<Q.length){if(Q[L+1].match(K.tableSeparator)){G=!0,U=b[1].split("|").map((E)=>E.trim()).filter((E)=>E.length>0),H=[],j=!1;continue}}}if(G&&O0)continue;if(G&&b){let B=b[1].split("|").map((E)=>E.trim()).filter((E)=>E.length>0);while(B.length<U.length)B.push("");if(B.length>U.length)B.length=U.length;H.push(B);continue}if(G&&!b){if(U.length>0&&H.length>0)Z.push({type:"table",content:"",tableData:{headers:U,rows:H}});G=!1,U=[],H=[]}let f=_.match(K.blockquote);if(f){let B=f[1].length,E=f[2]||"";if(v&&B===z)O.push(E);else{if(v)Z.push({type:"blockquote",content:O.join(`
|
|
5
|
+
`),blockquoteLevel:z,blockquoteLines:[...O]});v=!0,z=B,O=[E]}j=!1;continue}if(v)Z.push({type:"blockquote",content:O.join(`
|
|
6
|
+
`),blockquoteLevel:z,blockquoteLines:[...O]}),v=!1,O=[],z=0;let S=_.match(K.heading);if(S){Z.push({type:"heading",content:S[2],level:S[1].length}),j=!1;continue}let u=_.match(K.ulItem);if(u){Z.push({type:"list",content:u[3],listType:"ul",marker:u[2],indentation:u[1].length}),j=!1;continue}let h=_.match(K.olItem);if(h){Z.push({type:"list",content:h[3],listType:"ol",marker:h[2],indentation:h[1].length}),j=!1;continue}if(_.match(K.hr)){Z.push({type:"hr",content:""}),j=!1;continue}if(_.trim().length===0){if(!j)Z.push({type:"empty",content:""}),j=!0;continue}let a=_.match(K.commandMessage);if(a){Z.push({type:"command-message",content:a[1]}),j=!1;continue}Z.push({type:"text",content:_}),j=!1}if($){let L=Y.join(`
|
|
7
|
+
`);Z.push({type:"code",content:L,language:V||void 0})}if(G&&U.length>0&&H.length>0)Z.push({type:"table",content:"",tableData:{headers:U,rows:H}});if(v&&O.length>0)Z.push({type:"blockquote",content:O.join(`
|
|
8
|
+
`),blockquoteLevel:z,blockquoteLines:[...O]});while(Z.length>0&&Z[Z.length-1].type==="empty")Z.pop();return Z}var R=new Map;function k0(){return{inCodeBlock:!1,codeBlockContent:[],codeBlockLang:null,codeBlockDepth:0,inTable:!1,tableHeaders:[],tableRows:[],inDiff:!1,diffContent:[],inBlockquote:!1,blockquoteLines:[],blockquoteLevel:0,lastLineEmpty:!0,pendingTableHeader:null}}function f0(X){let Z=R.get(X);if(Z)return Z;let Q={state:k0(),blocks:[],pendingLine:"",finalized:!1};return R.set(X,Q),Q}function $0(X){return X.endsWith("\r")?X.slice(0,-1):X}function Y0(X,Z){if(X.tableHeaders.length>0&&X.tableRows.length>0)Z.push({type:"table",content:"",tableData:{headers:X.tableHeaders,rows:X.tableRows}});X.inTable=!1,X.tableHeaders=[],X.tableRows=[]}function l(X,Z){if(X.blockquoteLines.length>0)Z.push({type:"blockquote",content:X.blockquoteLines.join(`
|
|
9
|
+
`),blockquoteLevel:X.blockquoteLevel,blockquoteLines:[...X.blockquoteLines]});X.inBlockquote=!1,X.blockquoteLines=[],X.blockquoteLevel=0}function V0(X,Z){let Q=X.codeBlockContent.join(`
|
|
10
|
+
`);Z.push({type:"code",content:Q,language:X.codeBlockLang||void 0}),X.inCodeBlock=!1,X.codeBlockContent=[],X.codeBlockLang=null,X.codeBlockDepth=0,X.lastLineEmpty=!1}function i(X,Z,Q=!0){let{state:$,blocks:Y}=Z;if($.pendingTableHeader!==null){if(X.match(K.tableSeparator)){$.inTable=!0,$.tableHeaders=$.pendingTableHeader.slice(1,-1).split("|").map((z)=>z.trim()).filter((z)=>z.length>0),$.tableRows=[],$.pendingTableHeader=null,$.lastLineEmpty=!1;return}Y.push({type:"text",content:$.pendingTableHeader}),$.pendingTableHeader=null,$.lastLineEmpty=!1}if($.inDiff){if(X.match(K.diffEnd)){try{let z=JSON.parse($.diffContent.join(`
|
|
11
|
+
`));Y.push({type:"diff",content:"",diffData:{patch:z.patch,startLine:z.startLine,matchLine:z.matchLine}})}catch(z){Y.push({type:"text",content:$.diffContent.join(`
|
|
12
|
+
`)})}$.inDiff=!1,$.diffContent=[],$.lastLineEmpty=!1;return}$.diffContent.push(X);return}if(X.match(K.diffStart)){$.inDiff=!0,$.diffContent=[],$.lastLineEmpty=!1;return}if($.inCodeBlock){let z=X.match(K.codeBlock),j=X.trim()==="```";if(z&&z[1])$.codeBlockDepth++,$.codeBlockContent.push(X);else if(j)if($.codeBlockDepth>0)$.codeBlockDepth--,$.codeBlockContent.push(X);else V0($,Y);else $.codeBlockContent.push(X);return}let V=X.match(K.codeBlock);if(V){$.inCodeBlock=!0,$.codeBlockLang=V[1]||null,$.codeBlockDepth=0,$.lastLineEmpty=!1;return}let J=X.match(K.table),G=X.match(K.tableSeparator);if(J&&!$.inTable){$.pendingTableHeader=X;return}if($.inTable&&G)return;if($.inTable&&J){let z=J[1].split("|").map((j)=>j.trim()).filter((j)=>j.length>0);while(z.length<$.tableHeaders.length)z.push("");if(z.length>$.tableHeaders.length)z.length=$.tableHeaders.length;$.tableRows.push(z);return}if($.inTable&&!J){if(Y0($,Y),Q){i(X,Z,!1);return}}let U=X.match(K.blockquote);if(U){let z=U[1].length,j=U[2]||"";if($.inBlockquote&&z===$.blockquoteLevel)$.blockquoteLines.push(j);else{if($.inBlockquote)l($,Y);$.inBlockquote=!0,$.blockquoteLevel=z,$.blockquoteLines=[j]}$.lastLineEmpty=!1;return}if($.inBlockquote)l($,Y);let H=X.match(K.heading);if(H){Y.push({type:"heading",content:H[2],level:H[1].length}),$.lastLineEmpty=!1;return}let W=X.match(K.ulItem);if(W){Y.push({type:"list",content:W[3],listType:"ul",marker:W[2],indentation:W[1].length}),$.lastLineEmpty=!1;return}let D=X.match(K.olItem);if(D){Y.push({type:"list",content:D[3],listType:"ol",marker:D[2],indentation:D[1].length}),$.lastLineEmpty=!1;return}if(X.match(K.hr)){Y.push({type:"hr",content:""}),$.lastLineEmpty=!1;return}if(X.trim().length===0){if(!$.lastLineEmpty)Y.push({type:"empty",content:""}),$.lastLineEmpty=!0;return}let O=X.match(K.commandMessage);if(O){Y.push({type:"command-message",content:O[1]}),$.lastLineEmpty=!1;return}Y.push({type:"text",content:X}),$.lastLineEmpty=!1}function H1(X,Z){if(!X||!Z)return;let Q=f0(X);if(Q.finalized)return;let $=Q.pendingLine+Z,Y=$.split(`
|
|
13
|
+
`),V=$.endsWith(`
|
|
14
|
+
`),J=V?Y:Y.slice(0,-1);Q.pendingLine=V?"":Y[Y.length-1]??"";for(let G of J)i($0(G),Q)}function z1(X){let Z=R.get(X);if(!Z||Z.finalized)return;if(Z.pendingLine)i($0(Z.pendingLine),Z),Z.pendingLine="";if(Z.state.pendingTableHeader!==null)Z.blocks.push({type:"text",content:Z.state.pendingTableHeader}),Z.state.pendingTableHeader=null;if(Z.state.inCodeBlock)V0(Z.state,Z.blocks);if(Z.state.inTable)Y0(Z.state,Z.blocks);if(Z.state.inBlockquote)l(Z.state,Z.blocks);if(Z.state.inDiff)Z.blocks.push({type:"text",content:Z.state.diffContent.join(`
|
|
15
|
+
`)}),Z.state.inDiff=!1,Z.state.diffContent=[];while(Z.blocks.length>0&&Z.blocks[Z.blocks.length-1].type==="empty")Z.blocks.pop();Z.finalized=!0}function W1(X){let Z=R.get(X);if(!Z||!Z.finalized)return null;return Z.blocks}function F1(X){let Z=R.get(X);if(!Z)return null;return Z.blocks}function S0(X){let Z=R.get(X);if(!Z)return null;let Q=[],$=Z.state;if($.inDiff)Q.push("<<<DIFF>>>"),Q.push(...$.diffContent);else if($.inCodeBlock){let Y=$.codeBlockLang?`\`\`\`${$.codeBlockLang}`:"```";Q.push(Y),Q.push(...$.codeBlockContent)}else if($.inTable){if($.tableHeaders.length>0){Q.push(`| ${$.tableHeaders.join(" | ")} |`),Q.push(`| ${$.tableHeaders.map(()=>"---").join(" | ")} |`);for(let Y of $.tableRows)Q.push(`| ${Y.join(" | ")} |`)}}else if($.inBlockquote){let Y=">".repeat($.blockquoteLevel)+" ";for(let V of $.blockquoteLines)Q.push(Y+V)}else if($.pendingTableHeader)Q.push($.pendingTableHeader);if(Z.pendingLine)Q.push(Z.pendingLine);return Q.length>0?Q:null}function K1(X){let Z=R.get(X);if(!Z)return null;let Q="text";if(Z.state.inDiff)Q="diff";else if(Z.state.inCodeBlock)Q="code";else if(Z.state.inTable||Z.state.pendingTableHeader)Q="table";let $=S0(X);if(!$||$.length===0)return null;return{lines:$,mode:Q}}function q1(X){R.delete(X)}function k(){R.clear()}var J0=2000,M=[];function g0(){let X=M;return M=[],X}var U0={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000,totalInputTokens:0,totalOutputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,turnCount:0,estimatedCostUsd:0},G0={sessionId:p0(),messages:[],restoredContextMessages:null,restoredVisibleMessageCount:0,isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...U0},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:100,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,finalizingStreamingMessageId:null},o=(X,Z)=>({...G0,actions:{addMessage:(Q)=>{X(($)=>({session:{...$.session,messages:[...$.session.messages,Q],error:null}}))},addUserMessage:(Q)=>{let $={id:`user-${Date.now()}-${Math.random()}`,role:"user",content:Q,timestamp:Date.now()};Z().session.actions.addMessage($)},addAssistantMessage:(Q,$)=>{let Y={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Q,timestamp:Date.now(),thinkingContent:$};Z().session.actions.addMessage(Y)},addAssistantMessageAndClearThinking:(Q)=>{let $=Z().session.currentThinkingContent,Y={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Q,timestamp:Date.now(),thinkingContent:$||void 0};X((V)=>({session:{...V.session,messages:[...V.session.messages,Y],currentThinkingContent:null,error:null}}))},addToolMessage:(Q,$)=>{let Y={id:`tool-${Date.now()}-${Math.random()}`,role:"tool",content:Q,timestamp:Date.now(),metadata:$};Z().session.actions.addMessage(Y)},setCompacting:(Q)=>{X(($)=>({session:{...$.session,isCompacting:Q}}))},setCommand:(Q)=>{X(($)=>({session:{...$.session,currentCommand:Q}}))},setError:(Q)=>{X(($)=>({session:{...$.session,error:Q}}))},clearMessages:()=>{k(),X((Q)=>({session:{...Q.session,messages:[],restoredContextMessages:null,restoredVisibleMessageCount:0,error:null,clearCount:Q.session.clearCount+1}}))},resetSession:()=>{k(),X((Q)=>({session:{...Q.session,...G0,sessionId:Q.session.sessionId,isActive:!0}}))},restoreSession:(Q,$,Y)=>{k(),X((V)=>({session:{...V.session,sessionId:Q,messages:$,restoredContextMessages:Y??null,restoredVisibleMessageCount:Y?$.length:0,error:null,isActive:!0}}))},updateTokenUsage:(Q)=>{X(($)=>{let Y=$.session.tokenUsage,V=(Q.inputTokens??0)-(Q.inputTokens!==void 0?Y.inputTokens:0),J=(Q.outputTokens??0)-(Q.outputTokens!==void 0?Y.outputTokens:0),G=Y.totalInputTokens+Math.max(0,V),U=Y.totalOutputTokens+Math.max(0,J),H=Y.cacheReadTokens+(Q.cacheReadTokens??0),W=Y.cacheWriteTokens+(Q.cacheWriteTokens??0),D=$.config?.config,O=D?.models?.find((j)=>j.id===D.currentModelId)?.model??"",z=Z0(O,G,U,H,W);return{session:{...$.session,tokenUsage:{...Y,...Q,totalInputTokens:G,totalOutputTokens:U,cacheReadTokens:H,cacheWriteTokens:W,estimatedCostUsd:z}}}})},resetTokenUsage:()=>{X((Q)=>({session:{...Q.session,tokenUsage:{...U0}}}))},setCurrentThinkingContent:(Q)=>{if(Z().session.currentThinkingContent===Q)return;X(($)=>({session:{...$.session,currentThinkingContent:Q}}))},appendThinkingContent:(Q)=>{X(($)=>({session:{...$.session,currentThinkingContent:($.session.currentThinkingContent||"")+Q}}))},setThinkingExpanded:(Q)=>{X(($)=>({session:{...$.session,thinkingExpanded:Q}}))},toggleThinkingExpanded:()=>{X((Q)=>({session:{...Q.session,thinkingExpanded:!Q.session.thinkingExpanded}}))},setHistoryExpanded:(Q)=>{X(($)=>({session:{...$.session,historyExpanded:Q}}))},toggleHistoryExpanded:()=>{X((Q)=>({session:{...Q.session,historyExpanded:!Q.session.historyExpanded}}))},setExpandedMessageCount:(Q)=>{X(($)=>({session:{...$.session,expandedMessageCount:Q}}))},incrementClearCount:()=>{X((Q)=>({session:{...Q.session,clearCount:Q.session.clearCount+1}}))},startStreamingAssistantMessage:()=>{let Q=`assistant-${Date.now()}-${Math.random()}`,$={id:Q,role:"assistant",content:"",timestamp:Date.now()};return M=[],X((Y)=>({session:{...Y.session,messages:[...Y.session.messages,$],currentStreamingMessageId:Q,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,error:null}})),Q},appendAssistantContent:(Q)=>{let $=Z().session.currentStreamingMessageId,Y=$??`assistant-${Date.now()}-${Math.random()}`;return M.push(Q),X((V)=>{let J=(L)=>L.endsWith("\r")?L.slice(0,-1):L,G=$?V.session.currentStreamingLines:[],U=$?V.session.currentStreamingTail:"",H=$?V.session.currentStreamingLineCount:0,W=$?V.session.currentStreamingVersion:0,v=(U+Q).split(`
|
|
16
|
+
`),O=v.slice(0,-1).map(J),z=J(v[v.length-1]??""),j=G;if(O.length>0){if(j=[...G,...O],j.length>J0){let L=j.length-J0;j=j.slice(L)}}return{session:{...V.session,currentStreamingMessageId:Y,currentStreamingLines:j,currentStreamingTail:z,currentStreamingLineCount:H+O.length,currentStreamingVersion:W+1,error:null}}}),Y},finalizeStreamingMessage:(Q,$)=>{let Y=g0();X((V)=>{let J=V.session.currentStreamingMessageId,U=Y.join("")+(Q||""),H=(V.session.currentThinkingContent||"")+($||"");if(U.length>0){let W={id:J||`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:U,timestamp:Date.now(),thinkingContent:H||void 0};return{session:{...V.session,messages:[...V.session.messages,W],currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:W.id}}}return{session:{...V.session,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:null}}})},clearFinalizingStreamingMessageId:()=>{X((Q)=>({session:{...Q.session,finalizingStreamingMessageId:null}}))},discardStreamingMessage:()=>{M=[],X((Q)=>({session:{...Q.session,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,finalizingStreamingMessageId:null}}))}}});import{nanoid as l0}from"nanoid";import{promises as w}from"node:fs";import*as F from"node:path";import{fileURLToPath as d0}from"node:url";import{nanoid as m0}from"nanoid";var j0={proposal:"proposal.md",spec:"spec.md",requirements:"requirements.md",design:"design.md",tasks:"tasks.md",meta:".meta.json"},P={SPECS:"specs",CHANGES:"changes",ARCHIVE:"archive",STEERING:"steering",SPEC_DELTA:"specs"},C={CONSTITUTION:"constitution.md",PRODUCT:"product.md",TECH:"tech.md",STRUCTURE:"structure.md"};var T={init:["requirements"],requirements:["design","tasks"],design:["tasks"],tasks:["implementation"],implementation:["done","tasks"],done:[]},A1={init:"初始化",requirements:"需求定义",design:"架构设计",tasks:"任务分解",implementation:"实现中",done:"已完成"},H0={init:"proposal",requirements:"requirements",design:"design",tasks:"tasks",implementation:"tasks",done:null};var r0=d0(import.meta.url),c0=F.dirname(r0),z0=F.join(c0,"templates");class N{workspaceRoot;bladeDir;constructor(X){this.workspaceRoot=X,this.bladeDir=F.join(X,".blade")}getSpecsDir(){return F.join(this.bladeDir,P.SPECS)}getChangesDir(){return F.join(this.bladeDir,P.CHANGES)}getArchiveDir(){return F.join(this.bladeDir,P.ARCHIVE)}getSteeringDir(){return F.join(this.bladeDir,P.STEERING)}getChangePath(X){return F.join(this.getChangesDir(),X)}getChangeFilePath(X,Z){return F.join(this.getChangePath(X),j0[Z])}async initializeDirectories(){await w.mkdir(this.getChangesDir(),{recursive:!0,mode:493})}async createChangeDir(X){let Z=this.getChangePath(X);return await w.mkdir(Z,{recursive:!0,mode:493}),await w.mkdir(F.join(Z,P.SPEC_DELTA),{recursive:!0,mode:493}),Z}async readFile(X){try{return await w.readFile(X,"utf-8")}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async writeFile(X,Z){let Q=F.dirname(X);await w.mkdir(Q,{recursive:!0,mode:493}),await w.writeFile(X,Z,"utf-8")}async fileExists(X){try{return await w.access(X),!0}catch{return!1}}async dirExists(X){try{return(await w.stat(X)).isDirectory()}catch{return!1}}createMetadata(X,Z){let Q=new Date().toISOString();return{id:m0(),name:X,description:Z,phase:"init",createdAt:Q,updatedAt:Q,tasks:[]}}async readMetadata(X){let Z=this.getChangeFilePath(X,"meta"),Q=await this.readFile(Z);if(!Q)return null;try{return JSON.parse(Q)}catch{return null}}async writeMetadata(X,Z){let Q=this.getChangeFilePath(X,"meta");Z.updatedAt=new Date().toISOString(),await this.writeFile(Q,JSON.stringify(Z,null,2))}async updatePhase(X,Z){let Q=await this.readMetadata(X);if(!Q)return null;return Q.phase=Z,await this.writeMetadata(X,Q),Q}async readSpecFile(X,Z){let Q=this.getChangeFilePath(X,Z);return this.readFile(Q)}async writeSpecFile(X,Z,Q){let $=this.getChangeFilePath(X,Z);await this.writeFile($,Q);let Y=await this.readMetadata(X);if(Y)await this.writeMetadata(X,Y)}async getPhaseContent(X,Z){let Q=H0[Z];if(!Q)return null;return this.readSpecFile(X,Q)}async readSteeringContext(){let X=this.getSteeringDir(),[Z,Q,$,Y]=await Promise.all([this.readFile(F.join(X,C.CONSTITUTION)),this.readFile(F.join(X,C.PRODUCT)),this.readFile(F.join(X,C.TECH)),this.readFile(F.join(X,C.STRUCTURE))]);return{constitution:Z||void 0,product:Q||void 0,tech:$||void 0,structure:Y||void 0}}async writeSteeringFile(X,Z){let Q=F.join(this.getSteeringDir(),C[X]);await this.writeFile(Q,Z)}async hasSteeringDocs(){let X=this.getSteeringDir();if(!await this.dirExists(X))return!1;return(await w.readdir(X)).length>0}async listActiveChanges(){let X=this.getChangesDir();if(!await this.dirExists(X))return[];return(await w.readdir(X,{withFileTypes:!0})).filter((Q)=>Q.isDirectory()).map((Q)=>Q.name)}async listArchivedChanges(){let X=this.getArchiveDir();if(!await this.dirExists(X))return[];return(await w.readdir(X,{withFileTypes:!0})).filter((Q)=>Q.isDirectory()).map((Q)=>Q.name)}async changeExists(X){return this.dirExists(this.getChangePath(X))}async archiveChange(X){let Z=this.getChangePath(X),Q=F.join(this.getArchiveDir(),X);await w.mkdir(F.dirname(Q),{recursive:!0,mode:493}),await w.rename(Z,Q)}async restoreChange(X){let Z=F.join(this.getArchiveDir(),X),Q=this.getChangePath(X);await w.rename(Z,Q)}async listSpecDomains(){let X=this.getSpecsDir();if(!await this.dirExists(X))return[];return(await w.readdir(X,{withFileTypes:!0})).filter((Q)=>Q.isDirectory()).map((Q)=>Q.name)}async readAuthorativeSpec(X){let Z=F.join(this.getSpecsDir(),X,"spec.md");return this.readFile(Z)}async writeAuthorativeSpec(X,Z){let Q=F.join(this.getSpecsDir(),X,"spec.md");await this.writeFile(Q,Z)}async mergeSpecDeltas(X){let Z=F.join(this.getChangePath(X),P.SPEC_DELTA);if(!await this.dirExists(Z))return[];let Q=[],$=await w.readdir(Z,{withFileTypes:!0});for(let Y of $){if(!Y.isDirectory())continue;let V=F.join(Z,Y.name,"spec.md"),J=await this.readFile(V);if(J){let G=await this.readAuthorativeSpec(Y.name),U=G?`${G}
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
<!-- Merged from ${X} -->
|
|
21
|
+
|
|
22
|
+
${J}`:J;await this.writeAuthorativeSpec(Y.name,U),Q.push(Y.name)}}return Q}static TEMPLATE_NAMES={proposal:"proposal.md.template",spec:"spec.md.template",requirements:"requirements.md.template",design:"design.md.template",tasks:"tasks.md.template",meta:""};static STEERING_TEMPLATE_NAMES={CONSTITUTION:"steering/constitution.md.template",PRODUCT:"steering/product.md.template",TECH:"steering/tech.md.template",STRUCTURE:"steering/structure.md.template"};async readTemplate(X){let Z=N.TEMPLATE_NAMES[X];if(!Z)return null;let Q=F.join(z0,Z);return this.readFile(Q)}async readSteeringTemplate(X){let Z=N.STEERING_TEMPLATE_NAMES[X],Q=F.join(z0,Z);return this.readFile(Q)}fillTemplate(X,Z){let Q=X;for(let[$,Y]of Object.entries(Z))Q=Q.replace(new RegExp(`\\{\\{${$}\\}\\}`,"g"),Y);return Q}async createFromTemplate(X,Z,Q){let $=await this.readTemplate(Z);if(!$)return null;let Y=this.fillTemplate($,{name:X,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),...Q});return await this.writeSpecFile(X,Z,Y),Y}async createSteeringFromTemplate(X,Z={}){let Q=await this.readSteeringTemplate(X);if(!Q)return null;let $=this.fillTemplate(Q,{createdAt:new Date().toISOString(),...Z});return await this.writeSteeringFile(X,$),$}async initializeSteeringDocs(){let X=[],Z=this.getSteeringDir();for(let[Q,$]of Object.entries(C)){let Y=F.join(Z,$);if(!await this.fileExists(Y))await this.createSteeringFromTemplate(Q),X.push($)}return X}}class x{static instance=null;fileManager=null;workspaceRoot=null;constructor(){}static getInstance(){if(!x.instance)x.instance=new x;return x.instance}static resetInstance(){x.instance=null}async initialize(X){if(this.workspaceRoot===X&&this.fileManager)return;this.workspaceRoot=X,this.fileManager=new N(X),await this.fileManager.initializeDirectories()}getFileManager(){if(!this.fileManager)throw Error("SpecService not initialized. Call initialize() first.");return this.fileManager}async readSteeringContext(){return this.getFileManager().readSteeringContext()}async readSpecMetadata(X){return this.getFileManager().readMetadata(X)}async specExists(X){return this.getFileManager().changeExists(X)}getSpecPath(X){return this.getFileManager().getChangePath(X)}async createSpec(X,Z){let Q=this.getFileManager();if(await Q.changeExists(X))return{success:!1,message:`Spec "${X}" already exists`,error:"SPEC_EXISTS"};let $=await Q.createChangeDir(X),Y=Q.createMetadata(X,Z);await Q.writeMetadata(X,Y);let V=this.generateProposalTemplate(X,Z);return await Q.writeSpecFile(X,"proposal",V),{success:!0,message:`Spec "${X}" created successfully`,data:{spec:Y,path:$}}}async loadSpec(X){let Z=this.getFileManager(),Q=await Z.readMetadata(X);if(!Q)return{success:!1,message:`Spec "${X}" not found`,error:"SPEC_NOT_FOUND"};let $=Z.getChangePath(X);return{success:!0,message:`Spec "${X}" loaded successfully`,data:{spec:Q,path:$}}}canTransitionPhase(X,Z){return T[X].includes(Z)}getAllowedTransitions(X){return T[X]}async updatePhase(X,Z){return this.getFileManager().updatePhase(X,Z)}createTask(X,Z,Q){return{id:l0(8),title:X,description:Z,status:"pending",dependencies:Q?.dependencies||[],affectedFiles:Q?.affectedFiles||[],complexity:Q?.complexity||"medium"}}async saveMetadata(X,Z){await this.getFileManager().writeMetadata(X,Z)}getNextTask(X){return X.find((Z)=>{if(Z.status!=="pending")return!1;return Z.dependencies.every((Q)=>{return X.find((Y)=>Y.id===Q)?.status==="completed"})})||null}getTaskProgress(X){if(X.length===0)return{total:0,completed:0,percentage:0};let Z=X.length,Q=X.filter((Y)=>Y.status==="completed").length,$=Math.round(Q/Z*100);return{total:Z,completed:Q,percentage:$}}async listActiveSpecs(){return this.getFileManager().listActiveChanges()}async listArchivedSpecs(){return this.getFileManager().listArchivedChanges()}async archiveSpec(X){let Z=this.getFileManager();return await Z.mergeSpecDeltas(X),await Z.updatePhase(X,"done"),await Z.archiveChange(X),{success:!0,message:`Spec "${X}" archived successfully`}}async validateSpec(X){let Z=this.getFileManager(),Q=[],$=[],[Y,V,J,G,U]=await Promise.all([Z.readSpecFile(X.name,"proposal"),Z.readSpecFile(X.name,"spec"),Z.readSpecFile(X.name,"requirements"),Z.readSpecFile(X.name,"design"),Z.readSpecFile(X.name,"tasks")]),H={proposal:!!Y,spec:!!V,requirements:!!J,design:!!G,tasks:!!U};if(X.phase==="requirements"&&!H.requirements)Q.push({severity:"warning",file:"requirements",message:"Requirements document is missing"}),$.push("Generate requirements using EARS format");if(X.phase==="design"&&!H.design)Q.push({severity:"warning",file:"design",message:"Design document is missing"}),$.push("Create architecture diagrams and API contracts");if(X.phase==="tasks"&&X.tasks.length===0)Q.push({severity:"warning",file:"tasks",message:"No tasks defined"}),$.push("Break down the spec into atomic tasks");if(X.phase==="implementation"){let W=this.getTaskProgress(X.tasks);if(W.completed<W.total)Q.push({severity:"info",file:"tasks",message:`${W.total-W.completed} tasks remaining`})}return{valid:Q.filter((W)=>W.severity==="error").length===0,phase:X.phase,completeness:H,issues:Q,suggestions:$}}generateProposalTemplate(X,Z){return`# ${X}
|
|
23
|
+
|
|
24
|
+
## Summary
|
|
25
|
+
|
|
26
|
+
${Z}
|
|
27
|
+
|
|
28
|
+
## Background
|
|
29
|
+
|
|
30
|
+
<!-- Why is this change needed? What problem does it solve? -->
|
|
31
|
+
|
|
32
|
+
## Goals
|
|
33
|
+
|
|
34
|
+
<!-- What are the specific objectives of this change? -->
|
|
35
|
+
|
|
36
|
+
- [ ] Goal 1
|
|
37
|
+
- [ ] Goal 2
|
|
38
|
+
|
|
39
|
+
## Non-Goals
|
|
40
|
+
|
|
41
|
+
<!-- What is explicitly out of scope? -->
|
|
42
|
+
|
|
43
|
+
## Risks and Mitigations
|
|
44
|
+
|
|
45
|
+
<!-- What could go wrong? How will you address it? -->
|
|
46
|
+
|
|
47
|
+
| Risk | Mitigation |
|
|
48
|
+
|------|------------|
|
|
49
|
+
| | |
|
|
50
|
+
|
|
51
|
+
## Open Questions
|
|
52
|
+
|
|
53
|
+
<!-- What needs to be clarified before proceeding? -->
|
|
54
|
+
|
|
55
|
+
1.
|
|
56
|
+
`}}var W0=K0("Spec"),F0={currentSpec:null,specPath:null,isActive:!1,steeringContext:null,recentSpecs:[],isLoading:!1,error:null,workspaceRoot:null},n=(X,Z)=>({...F0,actions:{initialize:async(Q)=>{let $=x.getInstance();await $.initialize(Q);let Y=await $.readSteeringContext();X((V)=>({spec:{...V.spec,workspaceRoot:Q,steeringContext:Y}}))},createSpec:async(Q,$)=>{let V=await x.getInstance().createSpec(Q,$);if(V.success&&V.data){let{spec:J,path:G}=V.data,U=Z().spec.recentSpecs.filter((H)=>H!==Q);U.unshift(Q),X((H)=>({spec:{...H.spec,currentSpec:J,specPath:G,isActive:!0,recentSpecs:U.slice(0,10)}}))}return V},loadSpec:async(Q)=>{let Y=await x.getInstance().loadSpec(Q);if(Y.success&&Y.data){let{spec:V,path:J}=Y.data,G=Z().spec.recentSpecs.filter((U)=>U!==Q);G.unshift(Q),X((U)=>({spec:{...U.spec,currentSpec:V,specPath:J,isActive:!0,recentSpecs:G.slice(0,10)}}))}return Y},closeSpec:()=>{X((Q)=>({spec:{...Q.spec,currentSpec:null,specPath:null,isActive:!1}}))},exitSpecMode:()=>{Z().spec.actions.closeSpec()},transitionPhase:async(Q)=>{let $=Z().spec.currentSpec;if(!$)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let Y=x.getInstance();if(!Y.canTransitionPhase($.phase,Q))return{success:!1,message:`Cannot transition from "${$.phase}" to "${Q}"`,error:"INVALID_TRANSITION"};let V=await Y.updatePhase($.name,Q);if(!V)return{success:!1,message:"Failed to update phase",error:"UPDATE_FAILED"};if(X((J)=>({spec:{...J.spec,currentSpec:V}})),Q==="done")try{let{config:J}=Z();if(J.actions)J.actions.updateConfig({permissionMode:"default"});W0.info("Spec 已完成,已自动退出 Spec 模式")}catch(J){W0.error("自动退出 Spec 模式失败:",J)}return{success:!0,message:`Transitioned to "${Q}" phase`,data:{spec:V,phase:Q}}},getAllowedTransitions:()=>{let Q=Z().spec.currentSpec;if(!Q)return[];return T[Q.phase]},addTask:async(Q,$,Y)=>{let V=Z().spec.currentSpec;if(!V)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let J=x.getInstance(),G=J.createTask(Q,$,Y),U={...V,tasks:[...V.tasks,G],updatedAt:new Date().toISOString()};return await J.saveMetadata(V.name,U),X((H)=>({spec:{...H.spec,currentSpec:U}})),{success:!0,message:`Task "${Q}" added`,data:{task:G}}},updateTaskStatus:async(Q,$)=>{let Y=Z().spec.currentSpec;if(!Y)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let V=Y.tasks.find((W)=>W.id===Q);if(!V)return{success:!1,message:`Task "${Q}" not found`,error:"TASK_NOT_FOUND"};let J={...V,status:$,completedAt:$==="completed"?new Date().toISOString():V.completedAt},G=Y.tasks.map((W)=>W.id===Q?J:W),U={...Y,tasks:G,currentTaskId:$==="in_progress"?Q:Y.currentTaskId===Q?void 0:Y.currentTaskId,updatedAt:new Date().toISOString()};return await x.getInstance().saveMetadata(Y.name,U),X((W)=>({spec:{...W.spec,currentSpec:U}})),{success:!0,message:`Task status updated to "${$}"`,data:{task:J}}},getNextTask:()=>{let Q=Z().spec.currentSpec;if(!Q)return null;return x.getInstance().getNextTask(Q.tasks)},getTaskProgress:()=>{let Q=Z().spec.currentSpec;if(!Q)return{total:0,completed:0,percentage:0};return x.getInstance().getTaskProgress(Q.tasks)},listSpecs:async(Q)=>{let $=x.getInstance(),Y=[],V=await $.listActiveSpecs();for(let J of V){let G=await $.readSpecMetadata(J);if(!G)continue;if(Q?.phase&&G.phase!==Q.phase)continue;if(Q?.tags&&!Q.tags.some((H)=>G.tags?.includes(H)))continue;if(Q?.query&&!G.name.toLowerCase().includes(Q.query.toLowerCase())&&!G.description.toLowerCase().includes(Q.query.toLowerCase()))continue;let U=$.getTaskProgress(G.tasks);Y.push({name:G.name,description:G.description,phase:G.phase,updatedAt:G.updatedAt,path:$.getSpecPath(J),isArchived:!1,taskProgress:{total:U.total,completed:U.completed}})}if(Q?.includeArchived){let J=await $.listArchivedSpecs();for(let G of J)Y.push({name:G,description:"(archived)",phase:"done",updatedAt:"",path:`archive/${G}`,isArchived:!0,taskProgress:{total:0,completed:0}})}return Y.sort((J,G)=>{if(J.isArchived!==G.isArchived)return J.isArchived?1:-1;return new Date(G.updatedAt).getTime()-new Date(J.updatedAt).getTime()}),Y},archiveCurrentSpec:async()=>{let Q=Z().spec.currentSpec;if(!Q)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let Y=await x.getInstance().archiveSpec(Q.name);if(Y.success)Z().spec.actions.closeSpec();return Y},validateCurrentSpec:async()=>{let Q=Z().spec.currentSpec;if(!Q)return{valid:!1,phase:"init",completeness:{proposal:!1,spec:!1,requirements:!1,design:!1,tasks:!1},issues:[{severity:"error",file:"meta",message:"No active spec"}],suggestions:["Create a new spec with /spec proposal <name>"]};return x.getInstance().validateSpec(Q)},getSteeringContextString:async()=>{let Q=Z().spec.steeringContext;if(!Q)return null;let $=[];if(Q.constitution)$.push(`## Constitution (Project Governance)
|
|
57
|
+
|
|
58
|
+
${Q.constitution}`);if(Q.product)$.push(`## Product Vision
|
|
59
|
+
|
|
60
|
+
${Q.product}`);if(Q.tech)$.push(`## Technology Stack
|
|
61
|
+
|
|
62
|
+
${Q.tech}`);if(Q.structure)$.push(`## Code Structure
|
|
63
|
+
|
|
64
|
+
${Q.structure}`);return $.length>0?$.join(`
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
`):null},setError:(Q)=>{X(($)=>({spec:{...$.spec,error:Q}}))},setLoading:(Q)=>{X(($)=>({spec:{...$.spec,isLoading:Q}}))},reset:()=>{X((Q)=>({spec:{...F0,actions:Q.spec.actions}}))}}});var a0=s0()(o0(n0((...X)=>({session:o(...X),app:g(...X),config:m(...X),focus:r(...X),command:d(...X),spec:n(...X)})),{name:"BladeStore",enabled:!0})),q=()=>a0.getState(),t1=()=>q().session.actions,e1=()=>q().app.actions,Q5=()=>q().session.messages,y=()=>q().config.config,I=null;async function X5(){if(y()!==null)return;if(I)return I;return I=(async()=>{try{let Q=await q0.getInstance().initialize();q().config.actions.setConfig(Q)}catch(Z){throw I=null,Error(`[FAIL] Store 未初始化且无法自动初始化
|
|
69
|
+
|
|
70
|
+
`+`原因: ${Z instanceof Error?Z.message:"未知错误"}
|
|
71
|
+
|
|
72
|
+
`+`请确保:
|
|
73
|
+
`+`1. 配置文件格式正确 (~/.blade/config.json)
|
|
74
|
+
`+`2. 运行 blade 进行首次配置
|
|
75
|
+
`+"3. 配置文件权限正确")}finally{I=null}})(),I}var Z5=()=>q().config.config?.models??[],$5=()=>{let X=y();if(!X)return;let Z=X.currentModelId;return X.models.find(($)=>$.id===Z)??X.models[0]},Y5=(X)=>{let Z=y();if(!Z)return;return Z.models.find((Q)=>Q.id===X)},V5=()=>q().config.config?.mcpServers??{},J5=()=>q().app.thinkingModeEnabled,G5=()=>({setPermissionMode:async(X)=>{q().config.actions.updateConfig({permissionMode:X})},setTheme:async(X,Z={})=>{try{X0.setTheme(X)}catch{return}q().config.actions.updateConfig({theme:X}),await A().save({theme:X},{scope:"global",...Z})},setLanguage:async(X,Z={})=>{q().config.actions.updateConfig({language:X}),await A().save({language:X},{scope:"global",...Z})},setDebug:async(X,Z={})=>{q().config.actions.updateConfig({debug:X}),await A().save({debug:X},{scope:"global",...Z})},setTemperature:async(X,Z={})=>{q().config.actions.updateConfig({temperature:X}),await A().save({temperature:X},{scope:"global",...Z})},updateConfig:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let $={...Q};q().config.actions.updateConfig(X);try{await A().save(X,Z)}catch(Y){throw q().config.actions.setConfig($),Y}},flush:async()=>{await A().flush()},appendPermissionAllowRule:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let $=Q.permissions?.allow||[];if(!$.includes(X)){let Y=[...$,X];q().config.actions.updateConfig({permissions:{...Q.permissions,allow:Y}})}await A().appendPermissionRule(X,Z)},appendLocalPermissionAllowRule:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let $=Q.permissions?.allow||[];if(!$.includes(X)){let Y=[...$,X];q().config.actions.updateConfig({permissions:{...Q.permissions,allow:Y}})}await A().appendLocalPermissionRule(X,Z)},setCurrentModel:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");if(!Q.models.find((Y)=>Y.id===X))throw Error(`Model not found: ${X}`);q().config.actions.updateConfig({currentModelId:X}),await A().save({currentModelId:X},{scope:"global",...Z})},addModel:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let $="id"in X?X:{id:i0(),...X},V={models:[...Q.models,$]};if(Q.models.length===0)V.currentModelId=$.id;return q().config.actions.updateConfig(V),await A().save(V,{scope:"global",...Z}),$},updateModel:async(X,Z,Q={})=>{let $=y();if(!$)throw Error("Config not initialized");let Y=$.models.findIndex((J)=>J.id===X);if(Y===-1)throw Error(`Model not found: ${X}`);let V=[...$.models];V[Y]={...V[Y],...Z},q().config.actions.updateConfig({models:V}),await A().save({models:V},{scope:"global",...Q})},removeModel:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");if(Q.models.length===1)throw Error("Cannot remove the only model");let $=Q.models.filter((V)=>V.id!==X),Y={models:$};if(Q.currentModelId===X)Y.currentModelId=$[0].id;q().config.actions.updateConfig(Y),await A().save(Y,{scope:"global",...Z})},addMcpServer:async(X,Z,Q={})=>{let $=y();if(!$)throw Error("Config not initialized");let V={...$.mcpServers??{},[X]:Z};q().config.actions.updateConfig({mcpServers:V}),await A().save({mcpServers:V},{scope:"project",...Q})},removeMcpServer:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let Y={...Q.mcpServers??{}};delete Y[X],q().config.actions.updateConfig({mcpServers:Y}),await A().save({mcpServers:Y},{scope:"project",...Z})}});
|
|
76
|
+
export{t as ha,X0 as ia,K as ja,G1 as ka,H1 as la,z1 as ma,W1 as na,F1 as oa,K1 as pa,q1 as qa,T as ra,A1 as sa,N as ta,a0 as ua,q as va,t1 as wa,e1 as xa,Q5 as ya,y as za,X5 as Aa,Z5 as Ba,$5 as Ca,Y5 as Da,V5 as Ea,J5 as Fa,G5 as Ga};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as V,G as f,J as N,K as L,M as T,S as h,U as P,V as R}from"./chunk-
|
|
1
|
+
import{A as V,G as f,J as N,K as L,M as T,S as h,U as P,V as R}from"./chunk-gkd5eew1.js";import{Y as M}from"./chunk-yhwrv3qf.js";import"./chunk-esnkk33h.js";import"./chunk-6yvqtcx0.js";import"./chunk-v1c9xwen.js";import{za as y}from"./chunk-hhgbhadg.js";import"./chunk-c6ts8bd9.js";import{Sa as O}from"./chunk-9syksrkj.js";import"./chunk-yddnm9n2.js";import"./chunk-nhp35rk0.js";import"./chunk-pkmw32r0.js";import{xb as D}from"./chunk-7ycmx7c2.js";import{Bb as W}from"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";import{Readable as K,Writable as k}from"node:stream";import*as _ from"@agentclientprotocol/sdk";import{PROTOCOL_VERSION as I}from"@agentclientprotocol/sdk";import{nanoid as S}from"nanoid";import{nanoid as x}from"nanoid";var X=W("Agent");class B{id;cwd;connection;clientCapabilities;agent=null;runtime=null;pendingPrompt=null;messages=[];mode="default";sessionApprovals=new Set;constructor(z,G,H,Q){this.id=z;this.cwd=G;this.connection=H;this.clientCapabilities=Q}async initialize(){X.debug(`[AcpSession ${this.id}] Initializing...`),V.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),X.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.runtime=await f.create({sessionId:this.id}),this.agent=await T.createWithRuntime(this.runtime,{sessionId:this.id}),X.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){X.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand(z,G){try{X.debug(`[AcpSession ${this.id}] Executing slash command: ${z}`);let H={cwd:this.cwd,signal:G,acp:{sendMessage:(U)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:U}})},sendToolStart:(U,Y,q)=>{let Z=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,E=this.mapToolKind(q);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:Z,status:"in_progress",title:`${U}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(Y,null,2)}}],kind:E})},sendToolResult:(U,Y)=>{if(Y.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Y.summary}})}}},Q=await P(z,H),J=Q.content||Q.message;if(J)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:J}});if(Q.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] ${Q.error}`}});return{stopReason:Q.success?"end_turn":"cancelled"}}catch(H){return X.error(`[AcpSession ${this.id}] Slash command error:`,H),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] 命令执行失败: ${H instanceof Error?H.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let z=R(),G=["model","permissions","theme","config","exit","ide"],Q=z.filter((J)=>!G.includes(J.name)).map((J)=>{let U;if(J.usage){let Y=J.usage.replace(/^\/\w+\s*/,"").trim();if(Y)U=Y}if(J.aliases?.length){let Y=`Aliases: ${J.aliases.join(", ")}`;U=U?`${U} | ${Y}`:Y}return{name:J.name,description:J.description,input:U?{hint:U}:void 0}});X.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Q.map((J)=>J.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Q}),X.info(`[AcpSession ${this.id}] Sent ${Q.length} available commands`)}catch(z){X.error(`[AcpSession ${this.id}] Failed to send available commands:`,z)}}async prompt(z){V.setCurrentSession(this.id),this.pendingPrompt?.abort();let G=new AbortController;if(this.pendingPrompt=G,!this.agent)throw Error("Session not initialized");try{let H=this.resolvePrompt(z.prompt);if(X.debug(`[AcpSession ${this.id}] Received prompt: ${H.slice(0,100)}...`),h(H))return await this.handleSlashCommand(H,G.signal);let Q={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:G.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(J)=>{return this.requestPermission(J)}}};if(await O(this.agent.chatStream(H,Q),async(J)=>{switch(J.kind){case"content_delta":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:J.delta}});break;case"thinking_delta":this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:J.delta}});break;case"tool_start":{let U=J.toolCall,Y="function"in U?U.function.name:U.type,q=this.mapToolKind(J.toolKind);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:U.id,status:"in_progress",title:`Executing ${Y}`,content:[],kind:q});break}case"tool_result":{let{toolCall:U,result:Y}=J,q=[],Z=Y.metadata;if(Z?.kind==="edit"&&typeof Z.file_path==="string"&&typeof Z.oldContent==="string"&&(typeof Z.newContent==="string"||Z.newContent===void 0))q.push({type:"diff",path:Z.file_path,oldText:Z.oldContent,newText:Z.newContent??null});else{let F="function"in U?U.function.name:U.type,j=L(N(F,Y));q.push({type:"content",content:{type:"text",text:j}})}let E=Y.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:U.id,status:E,content:q});break}case"task_update":this.sendPlanUpdate(J.tasks);break;default:break}}),this.messages=[...Q.messages],G.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(H){if(G.signal.aborted||H instanceof Error&&H.name==="AbortError")return{stopReason:"cancelled"};throw X.error(`[AcpSession ${this.id}] Prompt error:`,H),H}finally{if(this.pendingPrompt===G)this.pendingPrompt=null}}cancel(){if(X.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,X.info(`[AcpSession ${this.id}] Cancelled successfully`);else X.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode(z){let G=["default","auto-edit","yolo","plan"];this.mode=G.includes(z)?z:"default",X.info(`[AcpSession ${this.id}] Mode set to: ${this.mode}`),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})}mapModeToPermissionMode(){switch(this.mode){case"yolo":return"yolo";case"auto-edit":return"autoEdit";case"plan":return"plan";case"default":default:return"default"}}shouldAutoApprove(z){switch(this.mode){case"yolo":return!0;case"auto-edit":return z==="readonly"||z==="write";case"plan":return z==="readonly";case"default":default:return!1}}async setModel(z){if(X.info(`[AcpSession ${this.id}] Model set to: ${z}`),this.agent)X.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;if(this.runtime)await this.runtime.dispose(),this.runtime=null;V.destroySession(this.id),X.debug(`[AcpSession ${this.id}] Destroyed`)}resolvePrompt(z){let G=[];for(let H of z)if(H.type==="text")G.push(H.text);else if(H.type==="image")G.push(`[Image: ${H.mimeType}]`);else if(H.type==="resource"){let Q=H.resource;if("text"in Q)G.push(`<file path="${Q.uri}">
|
|
2
2
|
${Q.text}
|
|
3
3
|
</file>`)}else if(H.type==="resource_link")G.push(`[Resource: ${H.uri}]`);return G.join(`
|
|
4
4
|
`)}sendUpdate(z){let G={sessionId:this.id,update:z};this.connection.sessionUpdate(G).catch((H)=>{X.warn(`[AcpSession ${this.id}] Failed to send update:`,H)})}sendPlanUpdate(z){let G=z.map((H)=>({content:H.subject,priority:H.priority,status:H.status}));X.debug(`[AcpSession ${this.id}] Sending plan update with ${G.length} entries`),this.sendUpdate({sessionUpdate:"plan",entries:G})}async requestPermission(z){let G=z.kind?.toLowerCase()||"execute";if(this.shouldAutoApprove(G))return X.debug(`[AcpSession ${this.id}] Auto-approving ${G} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(G==="write"||G==="execute"))return X.debug(`[AcpSession ${this.id}] Rejecting ${G} in plan mode`),{approved:!1,reason:"Write and execute operations are not allowed in Plan mode"};let H=`${G}:${z.title||"unknown"}`;if(this.sessionApprovals.has(H))return X.debug(`[AcpSession ${this.id}] Using cached approval for: ${H}`),{approved:!0};try{let Q=x(),J=[];if(z.message)J.push({type:"content",content:{type:"text",text:z.message}});if(z.risks&&z.risks.length>0)J.push({type:"content",content:{type:"text",text:`Risks:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$a as l,Qa as a,Ra as b,Sa as c,Ta as d,Ua as e,Va as f,Wa as g,Xa as h,Ya as i,Za as j,_a as k,ab as m,bb as n,cb as o,fb as p,gb as q,hb as r}from"./chunk-
|
|
1
|
+
import{$a as l,Qa as a,Ra as b,Sa as c,Ta as d,Ua as e,Va as f,Wa as g,Xa as h,Ya as i,Za as j,_a as k,ab as m,bb as n,cb as o,fb as p,gb as q,hb as r}from"./chunk-9syksrkj.js";import"./chunk-yddnm9n2.js";import"./chunk-nhp35rk0.js";import"./chunk-pkmw32r0.js";import"./chunk-7ycmx7c2.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";export{g as saveUserMessage,i as saveToolUse,j as saveToolResult,k as saveCompaction,h as saveAssistantMessage,a as isRootSystemPrompt,l as handleTaskListUpdate,m as handleSkillActivation,n as extractModelSwitch,r as executeLoopGenerator,c as drainLoop,f as checkStopHook,d as checkOutputRecovery,e as checkIncompleteIntent,q as checkAndCompactInLoop,o as applyToolDomainEffects,p as StreamingToolExecutor,b as ConversationState};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{rb as a}from"./chunk-
|
|
1
|
+
import{rb as a}from"./chunk-pkmw32r0.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";export{a as createChatServiceAsync};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{v as a,w as b,x as c}from"./chunk-
|
|
1
|
+
import{v as a,w as b,x as c}from"./chunk-r8wmg3fc.js";import"./chunk-hhgbhadg.js";import"./chunk-c6ts8bd9.js";import"./chunk-7ycmx7c2.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";export{a as validatePermissions,c as validateOutput,b as loadConfiguration};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{xb as l}from"./chunk-7ycmx7c2.js";import{Bb as x}from"./chunk-set7v1rf.js";import{Db as N}from"./chunk-j2ag7hh6.js";import{nanoid as j}from"nanoid";var U;((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"})(U||={});var w;((W)=>{W.Approve="approve";W.Block="block";W.Async="async"})(w||={});var M;((W)=>{W.Allow="allow";W.Deny="deny";W.Ask="ask"})(M||={});var C={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,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 S(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 m(){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 E{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 $}from"zod";var L=$.object({hook_event_name:$.nativeEnum(U),hook_execution_id:$.string(),timestamp:$.string(),project_dir:$.string(),session_id:$.string(),permission_mode:$.enum(["default","autoEdit","yolo","plan"]),_metadata:$.object({blade_version:$.string(),hook_timeout_ms:$.number()}).optional()}),u=L.extend({hook_event_name:$.literal("PreToolUse"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown())}),i=L.extend({hook_event_name:$.literal("PostToolUse"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown()),tool_response:$.unknown()}),a=L.extend({hook_event_name:$.literal("Stop"),reason:$.string().optional()}),c=L.extend({hook_event_name:$.literal("PostToolUseFailure"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown()),error:$.string(),error_type:$.string().optional(),is_interrupt:$.boolean(),is_timeout:$.boolean()}),s=L.extend({hook_event_name:$.literal("PermissionRequest"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown())}),r=L.extend({hook_event_name:$.literal("UserPromptSubmit"),user_prompt:$.string(),has_images:$.boolean(),image_count:$.number()}),n=L.extend({hook_event_name:$.literal("SessionStart"),is_resume:$.boolean(),resume_session_id:$.string().optional()}),o=L.extend({hook_event_name:$.literal("SessionEnd"),reason:$.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),e=L.extend({hook_event_name:$.literal("SubagentStop"),agent_type:$.string(),task_description:$.string().optional(),success:$.boolean(),result_summary:$.string().optional(),error:$.string().optional()}),t=L.extend({hook_event_name:$.literal("Notification"),notification_type:$.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:$.string().optional(),message:$.string()}),QQ=L.extend({hook_event_name:$.literal("Compaction"),trigger:$.enum(["manual","auto"]),messages_before:$.number(),tokens_before:$.number()}),CQ=$.discriminatedUnion("hook_event_name",[u,i,a,c,s,r,n,o,e,t,QQ]),YQ=$.object({hookEventName:$.literal("PreToolUse"),permissionDecision:$.nativeEnum(M).optional(),permissionDecisionReason:$.string().optional(),updatedInput:$.record($.unknown()).optional()}),ZQ=$.object({hookEventName:$.literal("PostToolUse"),additionalContext:$.string().optional(),updatedOutput:$.unknown().optional()}),WQ=$.object({hookEventName:$.literal("Stop"),continue:$.boolean().optional(),continueReason:$.string().optional()}),XQ=$.object({hookEventName:$.literal("SubagentStop"),continue:$.boolean().optional(),continueReason:$.string().optional(),additionalContext:$.string().optional()}),$Q=$.object({hookEventName:$.literal("PermissionRequest"),permissionDecision:$.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:$.string().optional()}),qQ=$.object({hookEventName:$.literal("UserPromptSubmit"),updatedPrompt:$.string().optional(),contextInjection:$.string().optional()}),JQ=$.object({hookEventName:$.literal("SessionStart"),env:$.record($.string()).optional()}),GQ=$.object({hookEventName:$.literal("Compaction"),blockCompaction:$.boolean().optional(),blockReason:$.string().optional()}),FQ=$.object({decision:$.object({behavior:$.nativeEnum(w)}).optional(),systemMessage:$.string().optional(),hookSpecificOutput:$.discriminatedUnion("hookEventName",[YQ,ZQ,WQ,XQ,$Q,qQ,JQ,GQ]).optional(),suppressOutput:$.boolean().optional()}),KQ=$.object({type:$.literal("command"),command:$.string(),timeout:$.number().positive().optional(),statusMessage:$.string().optional()}),VQ=$.object({type:$.literal("prompt"),prompt:$.string(),model:$.string().optional(),timeout:$.number().positive().optional()}),RQ=$.discriminatedUnion("type",[KQ,VQ]),I=$.union([$.string(),$.array($.string())]),_Q=$.object({tools:I.optional(),paths:I.optional(),commands:I.optional()}),D=$.object({name:$.string().optional(),matcher:_Q.optional(),hooks:$.array(RQ)}),SQ=$.object({enabled:$.boolean().optional(),defaultTimeout:$.number().positive().optional(),timeoutBehavior:$.enum(["ignore","deny","ask"]).optional(),failureBehavior:$.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:$.number().positive().optional(),PreToolUse:$.array(D).optional(),PostToolUse:$.array(D).optional(),PostToolUseFailure:$.array(D).optional(),PermissionRequest:$.array(D).optional(),UserPromptSubmit:$.array(D).optional(),SessionStart:$.array(D).optional(),SessionEnd:$.array(D).optional(),Stop:$.array(D).optional(),SubagentStop:$.array(D).optional(),Notification:$.array(D).optional(),Compaction:$.array(D).optional()});function k(Q){let Y=FQ.safeParse(Q);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}class f{parse(Q,Y,Z){if(Q.timedOut){let X=Z?.timeoutBehavior||"ignore",q="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if(X==="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 X=k(W);if(!X.success){let J="error"in X?X.error.message:"Unknown validation error",G=Z?.failureBehavior||"ignore",F=`Invalid hook output JSON: ${J}`;if(G==="deny")return{success:!1,blocking:!0,error:F,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if(G==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${F}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:F,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let q=X.data;if(q.decision?.behavior==="block")return{success:!1,blocking:!0,error:q.systemMessage||"Hook blocked execution",output:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};if(q.decision?.behavior==="async")return{success:!0,output:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};return{success:!0,output:q,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 X=Z?.timeoutBehavior||"ignore",q="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if(X==="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 X=Z?.failureBehavior||"ignore",q=Q.stderr||Q.stdout||`Hook failed with exit code ${W}`;if(X==="deny")return{success:!1,blocking:!0,error:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${q}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:q,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 DQ}from"child_process";class z{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 H{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute(Q,Y,Z,W){let X=JSON.stringify(Y);if(X.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${X.length} bytes (max ${this.MAX_INPUT_SIZE})`);let q=this.createSafeEnv(Y),J=DQ(Q,[],{shell:!0,env:q,cwd:Z.projectDir,timeout:W}),G=new z(this.MAX_STDOUT_SIZE),F=new z(this.MAX_STDERR_SIZE);J.stdout.setEncoding("utf8"),J.stderr.setEncoding("utf8"),J.stdout.on("data",(K)=>{G.append(K)}),J.stderr.on("data",(K)=>{F.append(K)});try{J.stdin.write(X),J.stdin.end()}catch(K){throw J.kill("SIGTERM"),Error(`Failed to write hook input: ${K}`)}return new Promise((K,O)=>{let R=!1,_=!1,V=null,A=()=>{if(V&&Z.abortSignal)Z.abortSignal.removeEventListener("abort",V),V=null},B=setTimeout(()=>{R=!0,J.kill("SIGKILL")},W);if(J.on("close",(b)=>{if(_)return;_=!0,clearTimeout(B),A(),K({stdout:G.getContent(),stderr:F.getContent(),exitCode:R?124:b??1,timedOut:R})}),J.on("error",(b)=>{if(_)return;_=!0,clearTimeout(B),A(),O(b)}),Z.abortSignal)V=()=>{if(_)return;_=!0,clearTimeout(B),A(),J.kill("SIGTERM"),K({stdout:G.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Z.abortSignal.addEventListener("abort",V)})}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 h(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(LQ(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(jQ(W)&&!Y.allowLoopback)throw new P(`Loopback address blocked: ${W}; enable policy.allowLoopback or add to allowedHosts`);if(AQ(W)&&!Y.allowPrivateRanges)throw new P(`Private/link-local address blocked: ${W}; enable policy.allowPrivateRanges or add to allowedHosts`)}function LQ(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 X=W.slice(1);return Q.endsWith(X)&&Q.length>X.length}return!1})}function jQ(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 AQ(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 p(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,q)=>{return process.env[q]??`\${${q}}`});return Y}var OQ=x("Execution"),BQ={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 v{processExecutor=new H;outputParser=new f;chatServiceCache=new Map;async executePreToolHooks(Q,Y,Z){if(Q.length===0)return{decision:"allow"};let W="tool_input"in Y?Y.tool_input:{},X=[];for(let q of Q)try{let J={...Y,...W&&{tool_input:W}},G=await this.executeHook(q,J,Z);if(!G.success){if(G.blocking)return{decision:"deny",reason:G.error};if(G.needsConfirmation)return{decision:"ask",reason:G.warning||G.error};if(G.warning)X.push(G.warning);continue}let F=G.output?.hookSpecificOutput;if(F&&"permissionDecision"in F){switch(F.permissionDecision){case"deny":return{decision:"deny",reason:F.permissionDecisionReason};case"ask":return{decision:"ask",reason:F.permissionDecisionReason};case"allow":break}if("updatedInput"in F&&F.updatedInput)W={...W,...F.updatedInput}}}catch(J){let G=J instanceof Error?J.message:String(J);if(X.push(`Hook failed: ${G}`),Z.config.failureBehavior==="deny")return{decision:"deny",reason:G};else if(Z.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${G}. Continue?`}}return{decision:"allow",modifiedInput:W,warning:X.length>0?X.join(`
|
|
1
|
+
import{xb as l}from"./chunk-7ycmx7c2.js";import{Bb as x}from"./chunk-set7v1rf.js";import{Db as N}from"./chunk-j2ag7hh6.js";import{nanoid as j}from"nanoid";var U;((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"})(U||={});var w;((W)=>{W.Approve="approve";W.Block="block";W.Async="async"})(w||={});var M;((W)=>{W.Allow="allow";W.Deny="deny";W.Ask="ask"})(M||={});var C={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 S(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 m(){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 E{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 $}from"zod";var L=$.object({hook_event_name:$.nativeEnum(U),hook_execution_id:$.string(),timestamp:$.string(),project_dir:$.string(),session_id:$.string(),permission_mode:$.enum(["default","autoEdit","yolo","plan"]),_metadata:$.object({blade_version:$.string(),hook_timeout_ms:$.number()}).optional()}),u=L.extend({hook_event_name:$.literal("PreToolUse"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown())}),i=L.extend({hook_event_name:$.literal("PostToolUse"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown()),tool_response:$.unknown()}),a=L.extend({hook_event_name:$.literal("Stop"),reason:$.string().optional()}),c=L.extend({hook_event_name:$.literal("PostToolUseFailure"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown()),error:$.string(),error_type:$.string().optional(),is_interrupt:$.boolean(),is_timeout:$.boolean()}),s=L.extend({hook_event_name:$.literal("PermissionRequest"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown())}),r=L.extend({hook_event_name:$.literal("UserPromptSubmit"),user_prompt:$.string(),has_images:$.boolean(),image_count:$.number()}),n=L.extend({hook_event_name:$.literal("SessionStart"),is_resume:$.boolean(),resume_session_id:$.string().optional()}),o=L.extend({hook_event_name:$.literal("SessionEnd"),reason:$.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),e=L.extend({hook_event_name:$.literal("SubagentStop"),agent_type:$.string(),task_description:$.string().optional(),success:$.boolean(),result_summary:$.string().optional(),error:$.string().optional()}),t=L.extend({hook_event_name:$.literal("Notification"),notification_type:$.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:$.string().optional(),message:$.string()}),QQ=L.extend({hook_event_name:$.literal("Compaction"),trigger:$.enum(["manual","auto"]),messages_before:$.number(),tokens_before:$.number()}),CQ=$.discriminatedUnion("hook_event_name",[u,i,a,c,s,r,n,o,e,t,QQ]),YQ=$.object({hookEventName:$.literal("PreToolUse"),permissionDecision:$.nativeEnum(M).optional(),permissionDecisionReason:$.string().optional(),updatedInput:$.record($.unknown()).optional()}),ZQ=$.object({hookEventName:$.literal("PostToolUse"),additionalContext:$.string().optional(),updatedOutput:$.unknown().optional()}),WQ=$.object({hookEventName:$.literal("Stop"),continue:$.boolean().optional(),continueReason:$.string().optional()}),XQ=$.object({hookEventName:$.literal("SubagentStop"),continue:$.boolean().optional(),continueReason:$.string().optional(),additionalContext:$.string().optional()}),$Q=$.object({hookEventName:$.literal("PermissionRequest"),permissionDecision:$.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:$.string().optional()}),qQ=$.object({hookEventName:$.literal("UserPromptSubmit"),updatedPrompt:$.string().optional(),contextInjection:$.string().optional()}),JQ=$.object({hookEventName:$.literal("SessionStart"),env:$.record($.string()).optional()}),GQ=$.object({hookEventName:$.literal("Compaction"),blockCompaction:$.boolean().optional(),blockReason:$.string().optional()}),FQ=$.object({decision:$.object({behavior:$.nativeEnum(w)}).optional(),systemMessage:$.string().optional(),hookSpecificOutput:$.discriminatedUnion("hookEventName",[YQ,ZQ,WQ,XQ,$Q,qQ,JQ,GQ]).optional(),suppressOutput:$.boolean().optional()}),KQ=$.object({type:$.literal("command"),command:$.string(),timeout:$.number().positive().optional(),statusMessage:$.string().optional()}),VQ=$.object({type:$.literal("prompt"),prompt:$.string(),model:$.string().optional(),timeout:$.number().positive().optional()}),RQ=$.discriminatedUnion("type",[KQ,VQ]),I=$.union([$.string(),$.array($.string())]),_Q=$.object({tools:I.optional(),paths:I.optional(),commands:I.optional()}),D=$.object({name:$.string().optional(),matcher:_Q.optional(),hooks:$.array(RQ)}),SQ=$.object({enabled:$.boolean().optional(),defaultTimeout:$.number().positive().optional(),timeoutBehavior:$.enum(["ignore","deny","ask"]).optional(),failureBehavior:$.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:$.number().positive().optional(),PreToolUse:$.array(D).optional(),PostToolUse:$.array(D).optional(),PostToolUseFailure:$.array(D).optional(),PermissionRequest:$.array(D).optional(),UserPromptSubmit:$.array(D).optional(),SessionStart:$.array(D).optional(),SessionEnd:$.array(D).optional(),Stop:$.array(D).optional(),SubagentStop:$.array(D).optional(),Notification:$.array(D).optional(),Compaction:$.array(D).optional()});function k(Q){let Y=FQ.safeParse(Q);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}class f{parse(Q,Y,Z){if(Q.timedOut){let X=Z?.timeoutBehavior||"ignore",q="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if(X==="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 X=k(W);if(!X.success){let J="error"in X?X.error.message:"Unknown validation error",G=Z?.failureBehavior||"ignore",F=`Invalid hook output JSON: ${J}`;if(G==="deny")return{success:!1,blocking:!0,error:F,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if(G==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${F}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:F,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let q=X.data;if(q.decision?.behavior==="block")return{success:!1,blocking:!0,error:q.systemMessage||"Hook blocked execution",output:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};if(q.decision?.behavior==="async")return{success:!0,output:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};return{success:!0,output:q,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 X=Z?.timeoutBehavior||"ignore",q="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if(X==="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 X=Z?.failureBehavior||"ignore",q=Q.stderr||Q.stdout||`Hook failed with exit code ${W}`;if(X==="deny")return{success:!1,blocking:!0,error:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${q}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:q,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 DQ}from"child_process";class z{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 H{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute(Q,Y,Z,W){let X=JSON.stringify(Y);if(X.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${X.length} bytes (max ${this.MAX_INPUT_SIZE})`);let q=this.createSafeEnv(Y),J=DQ(Q,[],{shell:!0,env:q,cwd:Z.projectDir,timeout:W}),G=new z(this.MAX_STDOUT_SIZE),F=new z(this.MAX_STDERR_SIZE);J.stdout.setEncoding("utf8"),J.stderr.setEncoding("utf8"),J.stdout.on("data",(K)=>{G.append(K)}),J.stderr.on("data",(K)=>{F.append(K)});try{J.stdin.write(X),J.stdin.end()}catch(K){throw J.kill("SIGTERM"),Error(`Failed to write hook input: ${K}`)}return new Promise((K,O)=>{let R=!1,_=!1,V=null,A=()=>{if(V&&Z.abortSignal)Z.abortSignal.removeEventListener("abort",V),V=null},B=setTimeout(()=>{R=!0,J.kill("SIGKILL")},W);if(J.on("close",(b)=>{if(_)return;_=!0,clearTimeout(B),A(),K({stdout:G.getContent(),stderr:F.getContent(),exitCode:R?124:b??1,timedOut:R})}),J.on("error",(b)=>{if(_)return;_=!0,clearTimeout(B),A(),O(b)}),Z.abortSignal)V=()=>{if(_)return;_=!0,clearTimeout(B),A(),J.kill("SIGTERM"),K({stdout:G.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Z.abortSignal.addEventListener("abort",V)})}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 h(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(LQ(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(jQ(W)&&!Y.allowLoopback)throw new P(`Loopback address blocked: ${W}; enable policy.allowLoopback or add to allowedHosts`);if(AQ(W)&&!Y.allowPrivateRanges)throw new P(`Private/link-local address blocked: ${W}; enable policy.allowPrivateRanges or add to allowedHosts`)}function LQ(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 X=W.slice(1);return Q.endsWith(X)&&Q.length>X.length}return!1})}function jQ(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 AQ(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 p(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,q)=>{return process.env[q]??`\${${q}}`});return Y}var OQ=x("Execution"),BQ={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 v{processExecutor=new H;outputParser=new f;chatServiceCache=new Map;async executePreToolHooks(Q,Y,Z){if(Q.length===0)return{decision:"allow"};let W="tool_input"in Y?Y.tool_input:{},X=[];for(let q of Q)try{let J={...Y,...W&&{tool_input:W}},G=await this.executeHook(q,J,Z);if(!G.success){if(G.blocking)return{decision:"deny",reason:G.error};if(G.needsConfirmation)return{decision:"ask",reason:G.warning||G.error};if(G.warning)X.push(G.warning);continue}let F=G.output?.hookSpecificOutput;if(F&&"permissionDecision"in F){switch(F.permissionDecision){case"deny":return{decision:"deny",reason:F.permissionDecisionReason};case"ask":return{decision:"ask",reason:F.permissionDecisionReason};case"allow":break}if("updatedInput"in F&&F.updatedInput)W={...W,...F.updatedInput}}}catch(J){let G=J instanceof Error?J.message:String(J);if(X.push(`Hook failed: ${G}`),Z.config.failureBehavior==="deny")return{decision:"deny",reason:G};else if(Z.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${G}. Continue?`}}return{decision:"allow",modifiedInput:W,warning:X.length>0?X.join(`
|
|
2
2
|
`):void 0}}async executePostToolHooks(Q,Y,Z){if(Q.length===0)return{};let W=Z.config.maxConcurrentHooks||5,X=await this.executeHooksConcurrently(Q,Y,Z,W),q=[],J=void 0,G=[];for(let F of X){if(!F.success&&F.warning){G.push(F.warning);continue}let K=F.output?.hookSpecificOutput;if(K&&"additionalContext"in K){if(K.additionalContext)q.push(K.additionalContext);if("updatedOutput"in K&&K.updatedOutput!==void 0)J=K.updatedOutput}}return{additionalContext:q.length>0?q.join(`
|
|
3
3
|
|
|
4
4
|
`):void 0,modifiedOutput:J,warning:G.length>0?G.join(`
|
|
@@ -21,7 +21,7 @@ import{xb as l}from"./chunk-7ycmx7c2.js";import{Bb as x}from"./chunk-set7v1rf.js
|
|
|
21
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=[],q=!1,J=W;for(let G of Q)try{let F=await this.executeHook(G,Y,Z);if(!F.success){if(F.warning)X.push(F.warning);continue}if(F.output?.suppressOutput){q=!0;break}if(F.stdout&&F.stdout.trim())J=F.stdout.trim()}catch(F){let K=F instanceof Error?F.message:String(F);X.push(`Hook failed: ${K}`)}return{suppress:q,message:J,warning:X.length>0?X.join(`
|
|
22
22
|
`):void 0}}async executeCompactionHooks(Q,Y,Z){if(Q.length===0)return{blockCompaction:!1};let W=[];for(let X of Q)try{let q=await this.executeHook(X,Y,Z);if(!q.success){if(q.warning)W.push(q.warning);continue}let J=q.output?.hookSpecificOutput;if(J&&"blockCompaction"in J&&J.blockCompaction)return{blockCompaction:!0,blockReason:J.blockReason,warning:W.length>0?W.join(`
|
|
23
23
|
`):void 0}}catch(q){let J=q instanceof Error?q.message:String(q);W.push(`Hook failed: ${J}`)}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 X=await this.processExecutor.execute(Q.command,Y,Z,W);return this.outputParser.parse(X,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(X){return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:Q}}}async executePromptHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let X=await this.getOrCreateChatService(Q.model),q="hook_event_name"in Y?String(Y.hook_event_name):"Unknown",J=this.buildPromptHookSystemMessage(Q,q),G=JSON.stringify(Y,null,2),F=new AbortController,K=setTimeout(()=>F.abort(),W),O;try{O=(await X.chat([{role:"system",content:J},{role:"user",content:G}],void 0,F.signal)).content}catch(_){if(F.signal.aborted||_ instanceof Error&&_.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});throw _}finally{clearTimeout(K)}let R=this.extractJsonFromLLMResponse(O);return this.outputParser.parse({stdout:R,stderr:"",exitCode:0,timedOut:!1},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(X){return OQ.warn(`[PromptHook] 执行失败: ${X instanceof Error?X.message:String(X)}`),{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:Q}}}async executeFunctionHook(Q,Y,Z){let W=(Q.timeout??10)*1000;try{let X=await this.runFunctionWithTimeout(Q.handler,Y,Z,W);if(X===void 0||X===null)return{success:!0,hook:Q};let q={stdout:JSON.stringify(X),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(q,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(X){if(X.isTimeout){let q={stdout:"",stderr:`Function hook timeout after ${W}ms`,exitCode:124,timedOut:!0};return this.outputParser.parse(q,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:Q}}}runFunctionWithTimeout(Q,Y,Z,W){return new Promise((X,q)=>{let J=!1,G=setTimeout(()=>{if(J)return;J=!0;let K=Object.assign(Error(`Function hook timed out after ${W}ms`),{isTimeout:!0});q(K)},W),F=()=>{if(J)return;J=!0,clearTimeout(G),q(Error("Function hook aborted"))};Z.abortSignal?.addEventListener("abort",F,{once:!0}),Promise.resolve().then(()=>Q(Y,Z)).then((K)=>{if(J)return;J=!0,clearTimeout(G),Z.abortSignal?.removeEventListener("abort",F),X(K)},(K)=>{if(J)return;J=!0,clearTimeout(G),Z.abortSignal?.removeEventListener("abort",F),q(K)})})}async executeHttpHook(Q,Y,Z){let W=(Q.timeout??10)*1000,X=Q.maxResponseBytes??262144,q=Math.max(1,(Q.retries??0)+1);try{h(Q.url,Z.config.httpPolicy)}catch(K){return{success:!1,blocking:!0,error:K instanceof Error?K.message:String(K),hook:Q}}let J={"Content-Type":"application/json",...p(Q.headers)},G=JSON.stringify(Y),F;for(let K=0;K<q;K++){if(K>0){let V=Math.min(2**K*200,5000);await new Promise((A)=>setTimeout(A,V))}let O=new AbortController,R=setTimeout(()=>O.abort(),W),_=()=>O.abort();Z.abortSignal?.addEventListener("abort",_,{once:!0});try{let V=await fetch(Q.url,{method:"POST",headers:J,body:G,redirect:"manual",signal:O.signal});if(V.status>=300&&V.status<400){F=Error(`HTTP hook received redirect (${V.status}); redirects are disabled`);continue}if(!V.ok){if(F=Error(`HTTP hook returned ${V.status} ${V.statusText}`),V.status>=400&&V.status<500)break;continue}let B={stdout:await PQ(V,X),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(B,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(V){let A=V.name==="AbortError"||V.code==="ABORT_ERR";if(A&&Z.abortSignal?.aborted){F=Error("HTTP hook aborted by caller");break}if(A){let B={stdout:"",stderr:`HTTP hook timeout after ${W}ms`,exitCode:124,timedOut:!0};if(K===q-1)return this.outputParser.parse(B,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});F=Error(`HTTP hook timeout attempt ${K+1}`);continue}F=V}finally{clearTimeout(R),Z.abortSignal?.removeEventListener("abort",_)}}return{success:!1,blocking:!1,error:F?.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:X,getModelById:q}=await import("./chunk-
|
|
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 X=await this.processExecutor.execute(Q.command,Y,Z,W);return this.outputParser.parse(X,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(X){return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:Q}}}async executePromptHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let X=await this.getOrCreateChatService(Q.model),q="hook_event_name"in Y?String(Y.hook_event_name):"Unknown",J=this.buildPromptHookSystemMessage(Q,q),G=JSON.stringify(Y,null,2),F=new AbortController,K=setTimeout(()=>F.abort(),W),O;try{O=(await X.chat([{role:"system",content:J},{role:"user",content:G}],void 0,F.signal)).content}catch(_){if(F.signal.aborted||_ instanceof Error&&_.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});throw _}finally{clearTimeout(K)}let R=this.extractJsonFromLLMResponse(O);return this.outputParser.parse({stdout:R,stderr:"",exitCode:0,timedOut:!1},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(X){return OQ.warn(`[PromptHook] 执行失败: ${X instanceof Error?X.message:String(X)}`),{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:Q}}}async executeFunctionHook(Q,Y,Z){let W=(Q.timeout??10)*1000;try{let X=await this.runFunctionWithTimeout(Q.handler,Y,Z,W);if(X===void 0||X===null)return{success:!0,hook:Q};let q={stdout:JSON.stringify(X),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(q,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(X){if(X.isTimeout){let q={stdout:"",stderr:`Function hook timeout after ${W}ms`,exitCode:124,timedOut:!0};return this.outputParser.parse(q,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:Q}}}runFunctionWithTimeout(Q,Y,Z,W){return new Promise((X,q)=>{let J=!1,G=setTimeout(()=>{if(J)return;J=!0;let K=Object.assign(Error(`Function hook timed out after ${W}ms`),{isTimeout:!0});q(K)},W),F=()=>{if(J)return;J=!0,clearTimeout(G),q(Error("Function hook aborted"))};Z.abortSignal?.addEventListener("abort",F,{once:!0}),Promise.resolve().then(()=>Q(Y,Z)).then((K)=>{if(J)return;J=!0,clearTimeout(G),Z.abortSignal?.removeEventListener("abort",F),X(K)},(K)=>{if(J)return;J=!0,clearTimeout(G),Z.abortSignal?.removeEventListener("abort",F),q(K)})})}async executeHttpHook(Q,Y,Z){let W=(Q.timeout??10)*1000,X=Q.maxResponseBytes??262144,q=Math.max(1,(Q.retries??0)+1);try{h(Q.url,Z.config.httpPolicy)}catch(K){return{success:!1,blocking:!0,error:K instanceof Error?K.message:String(K),hook:Q}}let J={"Content-Type":"application/json",...p(Q.headers)},G=JSON.stringify(Y),F;for(let K=0;K<q;K++){if(K>0){let V=Math.min(2**K*200,5000);await new Promise((A)=>setTimeout(A,V))}let O=new AbortController,R=setTimeout(()=>O.abort(),W),_=()=>O.abort();Z.abortSignal?.addEventListener("abort",_,{once:!0});try{let V=await fetch(Q.url,{method:"POST",headers:J,body:G,redirect:"manual",signal:O.signal});if(V.status>=300&&V.status<400){F=Error(`HTTP hook received redirect (${V.status}); redirects are disabled`);continue}if(!V.ok){if(F=Error(`HTTP hook returned ${V.status} ${V.statusText}`),V.status>=400&&V.status<500)break;continue}let B={stdout:await PQ(V,X),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(B,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(V){let A=V.name==="AbortError"||V.code==="ABORT_ERR";if(A&&Z.abortSignal?.aborted){F=Error("HTTP hook aborted by caller");break}if(A){let B={stdout:"",stderr:`HTTP hook timeout after ${W}ms`,exitCode:124,timedOut:!0};if(K===q-1)return this.outputParser.parse(B,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});F=Error(`HTTP hook timeout attempt ${K+1}`);continue}F=V}finally{clearTimeout(R),Z.abortSignal?.removeEventListener("abort",_)}}return{success:!1,blocking:!1,error:F?.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:X,getModelById:q}=await import("./chunk-cfbp6h36.js"),{createChatServiceAsync:J}=await import("./chunk-mjgch1nt.js");await W();let G=Q?q(Q)||X():X();if(!G)throw Error("PromptHook: 无法获取模型配置。请确保至少配置了一个模型。");let F=await J({provider:G.provider,apiKey:G.apiKey,baseUrl:G.baseUrl,model:G.model,temperature:G.temperature,maxContextTokens:G.maxContextTokens,maxOutputTokens:G.maxOutputTokens});return this.chatServiceCache.set(Y,F),F}buildPromptHookSystemMessage(Q,Y){let Z=BQ[Y]||"{ ... 根据事件类型返回相应字段 }";return`你是一个代码质量评估器,作为 Hook 在 ${Y} 事件中被触发。
|
|
25
25
|
|
|
26
26
|
`+`## 评估指令
|
|
27
27
|
${Q.prompt}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as a,u as b}from"./chunk-e38t8r4f.js";import"./chunk-6yvqtcx0.js";import"./chunk-j2ag7hh6.js";export{a as globalOptions,b as cliConfig};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{Bb as P}from"./chunk-set7v1rf.js";var f=["anthropic","openai","deepseek","google-generative-ai","groq","openrouter"],u={anthropic:"",openai:"","google-generative-ai":"",deepseek:"",groq:"",openrouter:"",azure:"",ollama:"",together:"",fireworks:"",mistral:"",cohere:"",perplexity:"",xai:"",default:""},c={anthropic:"https://api.anthropic.com",openai:"https://api.openai.com/v1",google:"https://generativelanguage.googleapis.com/v1beta",deepseek:"https://api.deepseek.com/v1",groq:"https://api.groq.com/openai/v1",openrouter:"https://openrouter.ai/api/v1",togetherai:"https://api.together.xyz/v1","fireworks-ai":"https://api.fireworks.ai/inference/v1",mistral:"https://api.mistral.ai/v1",cohere:"https://api.cohere.ai/v1",perplexity:"https://api.perplexity.ai",xai:"https://api.x.ai/v1",cerebras:"https://api.cerebras.ai/v1","novita-ai":"https://api.novita.ai/v3/openai",nvidia:"https://integrate.api.nvidia.com/v1"},T={anthropic:{"anthropic-beta":"claude-code-20250219,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"},openrouter:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"Blade"},cerebras:{"X-Cerebras-3rd-Party-Integration":"blade"},vercel:{"http-referer":"https://github.com/anthropics/blade","x-title":"blade"},zenmux:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"blade"}},H=(Q)=>{return T[Q]||{}};import{createAnthropic as A}from"@ai-sdk/anthropic";import{createAzure as K}from"@ai-sdk/azure";import{createDeepSeek as I}from"@ai-sdk/deepseek";import{createGoogleGenerativeAI as E}from"@ai-sdk/google";import{createOpenAI as y}from"@ai-sdk/openai";import{createOpenAICompatible as V}from"@ai-sdk/openai-compatible";import{generateText as U,jsonSchema as x,streamText as M}from"ai";var j=P("Chat");function O(Q){let q=new Set;for(let Y of Q)if(Y.role==="assistant"&&Y.tool_calls)for(let W of Y.tool_calls)q.add(W.id);return Q.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return q.has(Y.tool_call_id)}return!0})}function L(Q){if(typeof Q==="string")return Q;return Q.filter((q)=>q.type==="text").map((q)=>q.text).join(`
|
|
2
|
+
`)}function h(Q){let q=Q;return q.text??q.textDelta??q.delta}function C(Q,q={}){try{return JSON.parse(Q)}catch{return j.warn("[VercelAIChatService] Failed to parse JSON, using fallback",{str:Q}),q}}class R{model;config;constructor(Q){this.config=Q,this.model=this.createModel(Q),j.debug("[VercelAIChatService] Initialized",{provider:Q.provider,model:Q.model})}createModel(Q){let{provider:q,apiKey:Y,baseUrl:W,model:X,customHeaders:Z,apiVersion:J}=Q;switch(q){case"openai":return y({apiKey:Y,baseURL:W||void 0,headers:Z})(X);case"anthropic":return A({apiKey:Y,baseURL:W||void 0,headers:Z})(X);case"gemini":{if(W&&!this.isGeminiOfficialUrl(W))return V({name:"gemini",apiKey:Y,baseURL:W,headers:Z})(X);return E({apiKey:Y,baseURL:W||void 0})(X)}case"google":case"google-generative-ai":case"google-vertex":{if(W&&!this.isGeminiOfficialUrl(W))return V({name:q,apiKey:Y,baseURL:W,headers:Z})(X);return E({apiKey:Y,baseURL:W||void 0})(X)}case"azure-openai":{let $=this.extractAzureResourceName(W);if($)return K({apiKey:Y,resourceName:$,apiVersion:J||"2024-08-01-preview"})(X);let _=this.buildAzureBaseUrl(W,X);return V({name:"azure-openai",apiKey:Y,baseURL:_,headers:{...Z,"api-key":Y},queryParams:{"api-version":J||"2024-08-01-preview"}})(X)}case"azure":{let $=this.extractAzureResourceName(W);if($)return K({apiKey:Y,resourceName:$,apiVersion:J||"2024-08-01-preview"})(X);let _=this.buildAzureBaseUrl(W,X);return V({name:"azure-openai",apiKey:Y,baseURL:_,headers:{...Z,"api-key":Y},queryParams:{"api-version":J||"2024-08-01-preview"}})(X)}case"deepseek":return I({apiKey:Y,baseURL:W||void 0,headers:Z})(X);default:return V({name:q,apiKey:Y,baseURL:W,headers:Z})(X)}}extractAzureResourceName(Q){if(!Q)return;let q=Q.match(/https:\/\/([^.]+)\.openai\.azure(?:\.com|\.us|\.cn|\.de)/);return q?q[1]:void 0}buildAzureBaseUrl(Q,q){if(!Q)return"";let Y=Q.replace(/\/$/,"").replace(/\?.*$/,"");if(Y.includes("/openai/deployments/"))return Y;return`${Y}/openai/deployments/${q}`}isGeminiOfficialUrl(Q){return Q.includes("generativelanguage.googleapis.com")||Q.includes("aiplatform.googleapis.com")}needsThinkingReplayMetadata(){return/deepseek/i.test([this.config.provider,this.config.model,this.config.baseUrl].join(" "))}getThinkingReplayProviderOptions(Q){let q=Q?.trim();if(!q||!this.needsThinkingReplayMetadata())return;return{openaiCompatible:{reasoning_content:q}}}shouldFlattenDeepSeekThinkingToolHistory(){return this.needsThinkingReplayMetadata()}flattenDeepSeekThinkingToolHistory(Q){let q=[],Y,W=()=>{if(!Y)return;q.push({role:"assistant",content:L(Y.content).trim()||"I will use the requested tool and continue from its result."}),Y=void 0};for(let X of Q){if(X.role==="system"){W(),q.push({role:"user",content:`<system>
|
|
3
|
+
${L(X.content)}
|
|
4
|
+
</system>`});continue}if(X.role==="assistant"&&X.tool_calls&&X.tool_calls.length>0&&X.reasoningContent?.trim()){W(),Y=X;continue}if(X.role==="tool"&&Y){let Z=Y.tool_calls?.find(($)=>$.id===X.tool_call_id),J=Z?.type==="function"?Z.function:void 0;q.push({role:"user",content:`Tool result for ${X.name||J?.name||"tool"}${J?.arguments?`(${J.arguments})`:""}:
|
|
5
|
+
${L(X.content)}
|
|
6
|
+
|
|
7
|
+
Continue from this tool result.`});continue}W(),q.push(X)}return W(),q}convertMessages(Q){let q=[],Y=this.shouldFlattenDeepSeekThinkingToolHistory()?this.flattenDeepSeekThinkingToolHistory(Q):Q;for(let W of Y)if(W.role==="system")if(Array.isArray(W.content)){let X=W.content.find((J)=>J.type==="text"),Z={role:"system",content:L(W.content)};if(X?.providerOptions)Z.providerOptions=X.providerOptions;q.push(Z)}else q.push({role:"system",content:W.content});else if(W.role==="user")if(Array.isArray(W.content)){let X=W.content.map((Z)=>{if(Z.type==="text"){let J={type:"text",text:Z.text};if(Z.providerOptions)J.providerOptions=Z.providerOptions;return J}return{type:"image",image:Z.image_url.url}});q.push({role:"user",content:X})}else q.push({role:"user",content:W.content});else if(W.role==="assistant")if(W.tool_calls&&W.tool_calls.length>0){let X=W.tool_calls.map((_)=>{let w=_.function;return{type:"tool-call",toolCallId:_.id,toolName:w?.name||"",input:C(w?.arguments||"{}",{})}}),Z=L(W.content),J=W.reasoningContent?.trim()?[{type:"reasoning",text:W.reasoningContent}]:[],$=this.getThinkingReplayProviderOptions(W.reasoningContent);if(Z){let _={role:"assistant",content:[...J,{type:"text",text:Z},...X]};if($)_.providerOptions=$;q.push(_)}else if(J.length>0){let _={role:"assistant",content:[...J,...X]};if($)_.providerOptions=$;q.push(_)}else q.push({role:"assistant",content:X})}else if(W.reasoningContent?.trim()){let X=L(W.content),Z=[{type:"reasoning",text:W.reasoningContent}];if(X)Z.push({type:"text",text:X});let J={role:"assistant",content:Z},$=this.getThinkingReplayProviderOptions(W.reasoningContent);if($)J.providerOptions=$;q.push(J)}else q.push({role:"assistant",content:L(W.content)});else if(W.role==="tool")q.push({role:"tool",content:[{type:"tool-result",toolCallId:W.tool_call_id,toolName:W.name||"unknown",output:{type:"text",value:L(W.content)}}]});if(this.config.enablePromptCaching&&this.config.provider==="anthropic"){let W=0;for(let X of q)if(X.role==="system"&&W<2)X.providerOptions={anthropic:{cacheControl:{type:"ephemeral"}}},W++;for(let X=q.length-1;X>=0;X--)if(q[X].role==="user"){q[X].providerOptions={anthropic:{cacheControl:{type:"ephemeral"}}};break}}return q}convertTools(Q){if(!Q||Q.length===0)return;let q={};for(let Y of Q)q[Y.name]={description:Y.description,inputSchema:x(Y.parameters)};return q}convertToolCalls(Q){return Q.map((q)=>({id:q.toolCallId,type:"function",function:{name:q.toolName,arguments:JSON.stringify(q.args??q.input??{})}}))}convertUsage(Q,q){if(!Q)return;let Y=Q.promptTokens??Q.inputTokens??0,W=Q.completionTokens??Q.outputTokens??0,X={promptTokens:Y,completionTokens:W,totalTokens:Q.totalTokens??Y+W};if(q?.anthropic){if(q.anthropic.cacheCreationInputTokens!==void 0)X.cacheCreationInputTokens=q.anthropic.cacheCreationInputTokens;if(q.anthropic.cacheReadInputTokens!==void 0)X.cacheReadInputTokens=q.anthropic.cacheReadInputTokens}return X}isFallbackableError(Q){if(!(Q instanceof Error))return!1;let q=Q.message.toLowerCase();if(q.includes("timeout")||q.includes("econnrefused")||q.includes("enotfound"))return!0;let Y=q.match(/status[:\s]*(\d{3})/),W=Y?parseInt(Y[1],10):Q.status;return W!==void 0&&[429,529,503,502,500].includes(W)}async retryWithBackoff(Q,q,Y=2,W=1000){let X;for(let Z=0;Z<=Y;Z++)try{return await Q()}catch(J){if(X=J,Z>=Y)break;if(!this.isFallbackableError(J))throw J;if(q?.aborted)throw J;let $=W*Math.pow(2,Z);j.debug(`[VercelAIChatService] Retry ${Z+1}/${Y} after ${$}ms`),await new Promise((_)=>setTimeout(_,$))}throw X}getFallbackModelIds(){let Q=[];if(this.config.fallbackModels&&this.config.fallbackModels.length>0)Q.push(...this.config.fallbackModels);else if(this.config.fallbackModel)Q.push(this.config.fallbackModel);return Q}getThinkingProviderOptions(){if(!this.config.supportsThinking)return;let Q=this.config.thinkingBudget??1e4;if(this.config.provider==="anthropic")return{anthropic:{thinking:{type:"enabled",budgetTokens:Q}}};if(this.config.provider==="deepseek"||/deepseek/i.test(this.config.model))return{deepseek:{thinking:{type:"enabled",budgetTokens:Q}}};return}getStreamTextOptions(Q,q,Y,W){let X=W;if(this.config.timeout&&this.config.timeout>0){let $=AbortSignal.timeout(this.config.timeout);if(W)X=AbortSignal.any([W,$]);else X=$}let Z={model:Q,messages:q,tools:Y,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:X,allowSystemInMessages:!0},J=this.getThinkingProviderOptions();if(J)Z.providerOptions=J;return Z}async chat(Q,q,Y){let W=Date.now();j.debug("[VercelAIChatService] Starting chat request");let X=O(Q),Z=this.convertMessages(X),J=this.convertTools(q),$=async(_)=>{let w=await U(this.getStreamTextOptions(_,Z,J,Y)),N=w.toolCalls&&w.toolCalls.length>0?this.convertToolCalls(w.toolCalls):void 0,z=Array.isArray(w.reasoning)?w.reasoning.map((B)=>B.text).join(""):void 0;return{content:w.text,reasoningContent:z,toolCalls:N,usage:this.convertUsage(w.usage,w.providerMetadata),finishReason:w.finishReason}};try{return await this.retryWithBackoff(()=>$(this.model),Y,this.config.maxRetries)}catch(_){let w=Date.now()-W;if(j.error("[VercelAIChatService] Chat failed after",w,"ms"),!this.isFallbackableError(_))throw _;let N=this.getFallbackModelIds();if(N.length===0)throw _;for(let z of N){j.warn(`[VercelAIChatService] Trying fallback model: ${z}`);let B=this.createModel({...this.config,model:z});try{return await $(B)}catch(F){if(j.warn(`[VercelAIChatService] Fallback ${z} failed: ${F instanceof Error?F.message:F}`),!this.isFallbackableError(F))throw F}}throw _}}async*streamChat(Q,q,Y){let W=Date.now();j.debug("[VercelAIChatService] Starting stream request");let X=O(Q),Z=this.convertMessages(X),J=this.convertTools(q),$=async function*(B,F){let D=M(B.getStreamTextOptions(F,Z,J,Y)),S=0;for await(let G of D.fullStream)switch(G.type){case"text-delta":yield{content:h(G)};break;case"reasoning-delta":yield{reasoningContent:h(G)};break;case"tool-call":yield{toolCalls:[{index:S++,id:G.toolCallId,type:"function",function:{name:G.toolName,arguments:JSON.stringify(G.args??G.input??{})}}]};break;case"finish":yield{finishReason:G.finishReason,usage:B.convertUsage(G.totalUsage,G.providerMetadata)};break}},_=this.config.maxRetries??2,w;for(let B=0;B<=_;B++)try{yield*$(this,this.model);let F=Date.now()-W;j.debug("[VercelAIChatService] Stream completed in",F,"ms");return}catch(F){if(w=F,!this.isFallbackableError(F))throw F;if(B<_){let D=1000*Math.pow(2,B);j.debug(`[VercelAIChatService] Stream retry ${B+1}/${_} after ${D}ms`),await new Promise((S)=>setTimeout(S,D));continue}}let N=Date.now()-W;j.error("[VercelAIChatService] Stream failed after",N,"ms");let z=this.getFallbackModelIds();if(z.length===0)throw w;for(let B of z){j.warn(`[VercelAIChatService] Stream fallback: ${B}`),yield{modelFallback:!0};let F=this.createModel({...this.config,model:B});try{yield*$(this,F);return}catch(D){if(j.warn(`[VercelAIChatService] Stream fallback ${B} failed`),!this.isFallbackableError(D))throw D}}throw w}getConfig(){return{...this.config}}updateConfig(Q){j.debug("[VercelAIChatService] Updating configuration"),this.config={...this.config,...Q},this.model=this.createModel(this.config),j.debug("[VercelAIChatService] Configuration updated")}}var v=P("Service");async function qq(Q){let q=Q;if(q.provider){let Y=H(q.provider);if(Object.keys(Y).length>0)q={...q,customHeaders:{...Y,...q.customHeaders}},v.debug(`Injected ${q.provider} specific headers:`,Object.keys(Y))}return b(q)}function b(Q){return new R(Q)}
|
|
8
|
+
export{f as ob,u as pb,c as qb,qq as rb};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ga as a}from"./chunk-v1c9xwen.js";import"./chunk-hhgbhadg.js";import"./chunk-c6ts8bd9.js";import"./chunk-7ycmx7c2.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";export{a as SpecManager};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{va as z}from"./chunk-
|
|
1
|
+
import{va as z}from"./chunk-hhgbhadg.js";import{Ia as w}from"./chunk-c6ts8bd9.js";import{Bb as u}from"./chunk-set7v1rf.js";var q=u("General"),F=(b)=>{if(b.yolo){if(b.permissionMode&&b.permissionMode!=="yolo")throw Error("Cannot use both --yolo and --permission-mode with different values");b.permissionMode="yolo"}if(Array.isArray(b.allowedTools))b.allowedTools=b.allowedTools.flatMap((h)=>h.split(",").map((k)=>k.trim()).filter((k)=>k.length>0));if(Array.isArray(b.disallowedTools))b.disallowedTools=b.disallowedTools.flatMap((h)=>h.split(",").map((k)=>k.trim()).filter((k)=>k.length>0));if(Array.isArray(b.allowedTools)&&Array.isArray(b.disallowedTools)){let h=b.allowedTools.filter((k)=>b.disallowedTools.includes(k));if(h.length>0)throw Error(`Tools cannot be both allowed and disallowed: ${h.join(", ")}`)}},G=async(b)=>{try{let k=await w.getInstance().initialize();if(z().config.actions.setConfig(k),b.debug)q.info("[CLI] 配置已加载到 Store")}catch(h){q.error("[CLI] [FAIL] 配置初始化失败",h instanceof Error?h.message:h),console.error(`
|
|
2
2
|
[FAIL] 配置初始化失败
|
|
3
3
|
`),console.error("原因:",h instanceof Error?h.message:"未知错误"),console.error(`
|
|
4
4
|
请检查:`),console.error(" 1. 配置文件格式是否正确 (~/.blade/config.json)"),console.error(" 2. 是否需要运行 blade 进行首次配置"),console.error(` 3. 配置文件权限是否正确
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as y,b as A,c as C,d as D}from"./chunk-
|
|
1
|
+
import{a as y,b as A,c as C,d as D}from"./chunk-x2jkbn5c.js";import"./chunk-xcpjsrem.js";import"./chunk-gkd5eew1.js";import"./chunk-yhwrv3qf.js";import"./chunk-esnkk33h.js";import"./chunk-6yvqtcx0.js";import"./chunk-v1c9xwen.js";import{Aa as q}from"./chunk-hhgbhadg.js";import"./chunk-c6ts8bd9.js";import"./chunk-9syksrkj.js";import"./chunk-yddnm9n2.js";import"./chunk-nhp35rk0.js";import"./chunk-pkmw32r0.js";import"./chunk-7ycmx7c2.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";import H from"chalk";var R={command:"serve",describe:"Start a headless Blade server (no browser)",builder:y,handler:async(E)=>{let f=A(E);if(await q(),!process.env.BLADE_SERVER_PASSWORD)console.log(H.yellow("Warning: BLADE_SERVER_PASSWORD is not set; server is unsecured."));let b=await D.listenAsync(f);if(console.log(`Blade server listening on http://${b.hostname}:${b.port}`),f.hostname==="0.0.0.0"){let F=C();for(let G of F)console.log(` Network: http://${G}:${b.port}`)}await new Promise(()=>{}),await b.stop()}};export{R as serveCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Ga as F,ra as $,ta as E,ua as q}from"./chunk-
|
|
1
|
+
import{Ga as F,ra as $,ta as E,ua as q}from"./chunk-hhgbhadg.js";import{Bb as w}from"./chunk-set7v1rf.js";import{nanoid as O}from"nanoid";var Z=w("Spec");class X{static instance=null;fileManager=null;constructor(){}static getInstance(){if(!X.instance)X.instance=new X;return X.instance}static resetInstance(){X.instance=null}getStoreState(){return q.getState().spec}updateStoreState(z){q.setState((B)=>({spec:{...B.spec,...z}}))}async initialize(z){if(this.fileManager){Z.debug("SpecManager already initialized, skipping...");return}this.fileManager=new E(z),await this.fileManager.initializeDirectories();let B=await this.fileManager.readSteeringContext();this.updateStoreState({steeringContext:B}),Z.debug("SpecManager initialized successfully")}getFileManager(){if(!this.fileManager)throw Error("SpecManager not initialized. Call initialize() first.");return this.fileManager}getState(){return{...this.getStoreState()}}getCurrentSpec(){return this.getStoreState().currentSpec}isActive(){return this.getStoreState().isActive}getSteeringContext(){return this.getStoreState().steeringContext}async getSteeringContextString(){let z=this.getStoreState().steeringContext;if(!z)return null;let B=[];if(z.constitution)B.push(`## Constitution (Project Governance)
|
|
2
2
|
|
|
3
3
|
${z.constitution}`);if(z.product)B.push(`## Product Vision
|
|
4
4
|
|