@jonathanleelx/meddle 0.5.0-beta.24 → 0.5.0-beta.25
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/README.md +1 -1
- package/bin/commands/route/add.js +98 -86
- package/bin/commands/route/delete.js +48 -25
- package/bin/commands/route/index.js +16 -2
- package/bin/commands/route/update.js +118 -87
- package/bin/index.js +3 -1
- package/bin/lib/route-write-args.js +150 -0
- package/dist/server/agent/tools.d.ts.map +1 -1
- package/dist/server/agent/tools.js +2 -1
- package/dist/server/agent/tools.js.map +1 -1
- package/package.json +1 -1
- package/web/dist/assets/{detail-panel-D56nCma2.js → detail-panel-CyOc7gn8.js} +1 -1
- package/web/dist/assets/{global-panel-shell-SKPshqTf.js → global-panel-shell-jXQTb9nw.js} +1 -1
- package/web/dist/assets/{health-panel-CvI-VsvG.js → health-panel-CSV7OqBv.js} +1 -1
- package/web/dist/assets/{index-Dcm171u1.js → index-CSXxaYkG.js} +2 -2
- package/web/dist/assets/{mobile-proxy-panel-cpkvsdBT.js → mobile-proxy-panel-a09S-R79.js} +1 -1
- package/web/dist/assets/{mock-config-CtZ866iI.js → mock-config-D_E5YOE_.js} +1 -1
- package/web/dist/assets/{mock-editor-panel-CweYBdeM.js → mock-editor-panel-t4TDXeaR.js} +1 -1
- package/web/dist/assets/{mocks-file-missing-note-C-QJ8Bpm.js → mocks-file-missing-note-Ddy1TdMX.js} +1 -1
- package/web/dist/assets/{monaco-editor-Cge8h-Ca.js → monaco-editor-GpPLOKA5.js} +1 -1
- package/web/dist/assets/{pane-bar-Dvi-MHuB.js → pane-bar-zJmE3xI5.js} +1 -1
- package/web/dist/assets/{pane-split-ChCHxR7K.js → pane-split-CJ1VXJDy.js} +1 -1
- package/web/dist/assets/{panel-heading-Crmy9fo0.js → panel-heading-DlFWoYAR.js} +1 -1
- package/web/dist/assets/{plugin-code-editor-VaL2lVyD.js → plugin-code-editor-CtaamKWJ.js} +1 -1
- package/web/dist/assets/{plugin-config-DSiOk77l.js → plugin-config-Dg_FCb-L.js} +2 -2
- package/web/dist/assets/{plugin-generator-iAksMY2Q.js → plugin-generator-CVREuZs7.js} +1 -1
- package/web/dist/assets/{plugin-test-dialog-Cx6ifDnm.js → plugin-test-dialog-B-iV8ocm.js} +1 -1
- package/web/dist/assets/{route-preview-T0s6si4V.js → route-preview-CLJeg_9v.js} +1 -1
- package/web/dist/assets/{rule-ai-assistant-panel-DzfobTWM.js → rule-ai-assistant-panel-BvTqm4zV.js} +1 -1
- package/web/dist/assets/{rule-config-ESpfkJg6.js → rule-config-DmNPaKxc.js} +1 -1
- package/web/dist/assets/{rule-overview-panel-BswSByar.js → rule-overview-panel-CB9b-b0t.js} +1 -1
- package/web/dist/assets/{settings-panel-Cj-1Z8Ow.js → settings-panel-DLdeJ8ox.js} +1 -1
- package/web/dist/index.html +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/plugin-generator-
|
|
2
|
-
import{c as e,d as t,p as n,t as r,u as i}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as a}from"./refresh-cw-BfLoHqg5.js";import{c as o}from"./dist-BQN0rzUS.js";import{t as s}from"./zap-BuOtogAv.js";import"./es2015-DPJTBYa9.js";import{t as c}from"./switch-94vgsMHm.js";import{G as l,J as ee,K as u,Nt as d,Q as te,U as ne,W as f,Z as p,dt as re,n as ie,ot as ae,q as oe,st as se,ut as m,vt as h,xt as g}from"./index-Dcm171u1.js";import{n as ce}from"./editor-pane-actions-_ckwcCII.js";import{a as _,i as le,r as ue}from"./pane-bar-Dvi-MHuB.js";import{n as de,r as fe,t as v}from"./pane-split-ChCHxR7K.js";var pe=i(`shield-alert`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M12 16h.01`,key:`1drbdi`}]]),me=i(`shield`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}]]),y=i(`unplug`,[[`path`,{d:`m19 5 3-3`,key:`yk6iyv`}],[`path`,{d:`m2 22 3-3`,key:`19mgm9`}],[`path`,{d:`M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z`,key:`goz73y`}],[`path`,{d:`M7.5 13.5 10 11`,key:`7xgeeb`}],[`path`,{d:`M10.5 16.5 13 14`,key:`10btkg`}],[`path`,{d:`m12 6 6 6 2.3-2.3a2.4 2.4 0 0 0 0-3.4l-2.6-2.6a2.4 2.4 0 0 0-3.4 0Z`,key:`1snsnr`}]]),b=n(t(),1),x=v({storageKey:`meddle-plugin-list-width`,defaultPx:360,minPx:280,maxPx:560,editorMinPx:420});x.storageKey,x.defaultPx;var S=e(),he=(0,b.lazy)(()=>d(()=>import(`./plugin-generator-iAksMY2Q.js`).then(e=>({default:e.PluginGenerator})),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]))),ge=(0,b.lazy)(()=>d(()=>import(`./plugin-code-editor-VaL2lVyD.js`).then(e=>({default:e.PluginCodeEditor})),__vite__mapDeps([27,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,28,29,30,31,23,24,25,26]))),_e=(0,b.lazy)(()=>d(()=>import(`./plugin-test-dialog-Cx6ifDnm.js`).then(e=>({default:e.PluginTestDialog})),__vite__mapDeps([32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,28,33,34,35,19,29,36,22,23,25,26])));function C(){return(0,S.jsxs)(`div`,{className:`flex h-full min-h-[160px] items-center justify-center gap-2 text-sm text-muted-foreground`,children:[(0,S.jsx)(g,{className:`size-4 animate-spin`}),`加载编辑器…`]})}function w({plugins:e,pluginMode:t,switchPluginMode:n,fetchPlugins:i,startPlugin:d,stopPlugin:m,togglePlugin:h,thirdPartyPlugins:v,thirdPartySecurity:w,fetchThirdPartyPlugins:D,loadThirdPartyPlugin:O,unloadThirdPartyPlugin:M}){let[N,P]=(0,b.useState)(!1),[F,I]=(0,b.useState)(``),[L,R]=(0,b.useState)(!1),[ye,be]=(0,b.useState)([]),[z,B]=(0,b.useState)(!1),[V,H]=(0,b.useState)({kind:`idle`}),[xe,Se]=(0,b.useState)(null),U=(0,b.useRef)(null),Ce=(0,b.useCallback)(e=>{U.current=e},[]),we=(0,b.useCallback)(()=>{if(U.current){U.current();return}H({kind:`idle`})},[]);(0,b.useEffect)(()=>{i(),D(),W()},[i,D]),(0,b.useEffect)(()=>{let e=()=>{W()};return window.addEventListener(`plugins-custom-updated`,e),()=>window.removeEventListener(`plugins-custom-updated`,e)},[]);let W=async()=>{try{be((await(await fetch(`/api/plugins/custom`)).json()).plugins||[])}catch(e){console.error(`加载自定义插件失败:`,e)}},Te=async(e,t)=>{if(confirm(`确定要删除插件 ${e} 吗?`))try{let n=await fetch(`/api/plugins/custom/${encodeURIComponent(e)}`,{method:`DELETE`});if(n.ok)H(n=>n.kind===`code`&&n.filename===e||n.kind===`test`&&(n.filename===e||t!==void 0&&n.pluginId===t)?{kind:`idle`}:n),await W();else{let e=await n.json();alert(e.error||`删除失败`)}}catch(e){console.error(`删除插件失败:`,e),alert(`删除失败`)}},G=async(e,t)=>{if(confirm(`插件文件已删除,确定要从内存卸载 ${t} 吗?`))try{let t=await fetch(`/api/plugins/custom/loaded/${encodeURIComponent(e)}/unload`,{method:`POST`});if(t.ok)H(t=>(t.kind===`test`||t.kind===`builtin`)&&t.pluginId===e?{kind:`idle`}:t),await i(),await W();else{let e=await t.json().catch(()=>({}));alert(e.error||`卸载失败`)}}catch(e){console.error(`卸载插件失败:`,e),alert(`卸载失败`)}},K=async()=>{B(!0);try{let e=await fetch(`/api/plugins/reload`,{method:`POST`});if(e.ok){let t=await e.json();alert(`成功热加载 ${t.count} 个插件!`),await i(),await W()}else{let t=await e.json();alert(t.error||`热加载失败`)}}catch(e){console.error(`热加载失败:`,e),alert(`热加载失败`)}finally{B(!1)}},Ee=async e=>{P(!0);try{await d(e),await i()}finally{P(!1)}},De=async e=>{P(!0);try{await m(e),await i()}finally{P(!1)}},Oe=async()=>{if(F.trim()){R(!0);try{await O(F),I(``),await D()}finally{R(!1)}}},ke=async e=>{R(!0);try{await M(e),await D(),V.kind===`third-party`&&V.pluginId===e&&H({kind:`idle`})}finally{R(!1)}},{builtinPlugins:q,customRows:J}=ie(e,ye,new Set(v.map(e=>e.id))),Y=V.kind===`builtin`?e.find(e=>e.id===V.pluginId):void 0,X=Y?J.find(e=>e.fileDeleted&&e.pluginId===Y.id):void 0,Z=V.kind===`third-party`?v.find(e=>e.id===V.pluginId):void 0,Q=V.kind===`generate`?`编辑插件 · AI 生成`:V.kind===`code`?`编辑插件 · ${V.filename}`:V.kind===`test`?`编辑插件 · 测试 ${V.pluginName}`:V.kind===`builtin`?`编辑插件 · ${Y?.name||V.pluginId}`:V.kind===`third-party`?`编辑插件 · ${Z?.name||V.pluginId}`:V.kind===`load-third-party`?`编辑插件 · 加载第三方`:`编辑插件`,Ae=V.kind===`code`||V.kind===`generate`||V.kind===`test`,$=de(Q);return(0,S.jsxs)(fe,{testId:`plugin-config-layout`,layout:`list-edit`,widthAttr:`plugin-list-width`,split:x,listTestId:`plugin-config-list`,panelTestId:`plugin-config-edit`,separatorTestId:`plugin-panel-separator`,separatorLabel:`调整插件列表宽度`,list:(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`div`,{className:`shrink-0`,children:[(0,S.jsxs)(le,{children:[(0,S.jsx)(_,{children:`插件`}),(0,S.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void W(),disabled:N||z,"aria-label":`刷新列表`,children:(0,S.jsx)(a,{})}),(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void K(),disabled:N||z,"aria-label":`热加载插件`,children:z?(0,S.jsx)(g,{className:`animate-spin`}):(0,S.jsx)(s,{})}),(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:()=>H({kind:`generate`}),"data-testid":`plugin-config-generate`,children:[(0,S.jsx)(re,{"data-icon":`inline-start`}),`AI 生成`]})]})]}),(0,S.jsxs)(`div`,{className:`flex items-center gap-2 border-b p-[var(--ui-section-gap)]`,children:[(0,S.jsxs)(ne,{value:t,onValueChange:e=>n(e),children:[(0,S.jsx)(oe,{className:`h-7 w-full text-xs`,"aria-label":`插件模式`,children:(0,S.jsx)(ee,{})}),(0,S.jsx)(f,{children:(0,S.jsxs)(l,{children:[(0,S.jsx)(u,{value:`off`,children:`关闭`}),(0,S.jsx)(u,{value:`on`,children:`开启`}),(0,S.jsx)(u,{value:`shadow`,children:`影子模式`})]})})]}),t===`off`?(0,S.jsx)(p,{variant:`destructive`,className:`shrink-0 text-xs`,children:`未生效`}):null]})]}),(0,S.jsxs)(`div`,{"data-plugin-row-list":``,className:`meddle-thin-scroll min-h-0 flex-1 overflow-x-hidden overflow-y-auto`,children:[(0,S.jsx)(T,{title:`内置插件`,children:q.length===0?(0,S.jsx)(E,{children:`暂无内置插件`}):q.map(e=>(0,S.jsx)(k,{testId:`plugin-config-row-builtin-${e.id}`,selected:V.kind===`builtin`&&V.pluginId===e.id,title:e.name,meta:e.version,onSelect:()=>H({kind:`builtin`,pluginId:e.id}),badge:(0,S.jsx)(p,{variant:e.state===`running`?`default`:`secondary`,children:e.state})},e.id))}),(0,S.jsx)(T,{title:`自定义插件`,children:J.length===0?(0,S.jsx)(E,{children:`暂无自定义插件,点击「AI 生成」`}):J.map(({filename:e,pluginId:t,loadedPlugin:n,fileDeleted:i})=>{let a=n?n.state!==`disabled`:!1,s=i?(V.kind===`builtin`||V.kind===`test`)&&V.pluginId===t:V.kind===`code`&&V.filename===e||V.kind===`test`&&(V.filename===e||V.pluginId===t),l=n?a?`已启用`:`已禁用`:`未加载`;return(0,S.jsx)(k,{testId:i?`plugin-config-row-custom-deleted-${t}`:`plugin-config-row-custom-${e}`,selected:s,title:e,meta:l,muted:!!n&&!a,onSelect:()=>H(i?{kind:`builtin`,pluginId:t}:{kind:`code`,filename:e}),badge:(0,S.jsxs)(S.Fragment,{children:[i?(0,S.jsxs)(`span`,{"data-testid":`plugin-file-deleted-label`,className:`mr-1 inline-flex items-center gap-1 text-xs text-muted-foreground`,children:[(0,S.jsx)(ae,{"aria-hidden":`true`,className:`size-3.5 shrink-0`}),`文件已删除`]}):null,n?(0,S.jsx)(c,{checked:a,onCheckedChange:e=>h(n.id,e),"aria-label":`启用插件 ${e}`}):(0,S.jsx)(p,{variant:`outline`,children:`未加载`})]}),action:(0,S.jsxs)(`div`,{className:`flex items-center`,children:[n&&a&&!i&&(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>H({kind:`test`,pluginId:n.id,pluginName:n.name,hooks:n.hooks,filename:e}),"aria-label":`测试插件 ${n.name}`,children:(0,S.jsx)(se,{})}),i?(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void G(t,e),"aria-label":`卸载插件 ${e}`,"aria-description":`文件已删除,仅从内存移除`,title:`卸载`,children:(0,S.jsx)(y,{})}):(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void Te(e,n?.id),className:`text-destructive`,"aria-label":`删除插件 ${e}`,children:(0,S.jsx)(o,{})})]})},i?`loaded:${t}`:e)})}),(0,S.jsx)(T,{title:`第三方插件`,extra:(0,S.jsxs)(`span`,{className:`inline-flex items-center gap-1 normal-case tracking-normal`,children:[w.allowAll?(0,S.jsx)(me,{className:`size-3.5 text-primary`}):(0,S.jsx)(pe,{className:`size-3.5`}),w.allowAll?`已信任所有插件`:`已信任 ${w.trusted.length} 个`]}),action:(0,S.jsx)(r,{variant:`ghost`,size:`xs`,onClick:()=>H({kind:`load-third-party`}),"data-testid":`plugin-config-load`,children:`加载`}),children:v.length===0?(0,S.jsx)(E,{children:`暂无第三方插件`}):v.map(e=>(0,S.jsx)(k,{testId:`plugin-config-row-third-${e.id}`,selected:V.kind===`third-party`&&V.pluginId===e.id,title:e.name,meta:e.version,onSelect:()=>H({kind:`third-party`,pluginId:e.id}),badge:(0,S.jsx)(p,{variant:e.state===`running`?`default`:`secondary`,children:e.state})},e.id))})]})]}),children:[(0,S.jsx)(ue,{"data-testid":`plugin-editor-title-bar`,scrolled:$.scrolled,title:Q,actions:(0,S.jsxs)(S.Fragment,{children:[V.kind===`idle`?null:(0,S.jsx)(r,{variant:`ghost`,size:`sm`,onClick:we,children:`取消`}),(0,S.jsx)(`div`,{ref:Se,"data-testid":`editor-pane-actions`,className:`contents`})]})}),(0,S.jsx)(ce,{host:xe,registerDismiss:Ce,children:(0,S.jsx)(`div`,{className:Ae?`min-h-0 flex-1 overflow-hidden`:`min-h-0 flex-1 overflow-y-auto`,onScroll:$.onScroll,"data-slot":`plugin-editor-scroll`,children:V.kind===`idle`?(0,S.jsxs)(`div`,{className:`flex h-full min-h-[240px] flex-col items-center justify-center gap-2 p-6 text-center text-sm text-muted-foreground`,children:[(0,S.jsx)(`p`,{children:`选择左侧插件进行编辑,或点击「AI 生成」`}),(0,S.jsx)(`p`,{className:`text-xs`,children:`自定义插件在右侧编辑代码;内置和第三方插件在右侧查看并操作`})]}):V.kind===`generate`?(0,S.jsx)(b.Suspense,{fallback:(0,S.jsx)(C,{}),children:(0,S.jsx)(he,{embedded:!0,plainHeading:!0,onOpenChange:e=>{e||H({kind:`idle`})},onPluginSaved:()=>{i(),W()}})}):V.kind===`code`?(0,S.jsx)(b.Suspense,{fallback:(0,S.jsx)(C,{}),children:(0,S.jsx)(ge,{embedded:!0,plainHeading:!0,filename:V.filename,onOpenChange:e=>{e||H({kind:`idle`})},onSaved:()=>{i()}},V.filename)}):V.kind===`test`?(0,S.jsx)(b.Suspense,{fallback:(0,S.jsx)(C,{}),children:(0,S.jsx)(_e,{embedded:!0,plainHeading:!0,pluginId:V.pluginId,pluginName:V.pluginName,hooks:V.hooks,filename:V.filename,onOpenChange:e=>{e||H({kind:`idle`})},onPluginFixed:()=>{i()}},V.pluginId)}):V.kind===`builtin`&&Y?(0,S.jsx)(A,{plugin:Y,...X?{note:ve,onUnload:()=>void G(X.pluginId,X.filename)}:{},loading:N,onStart:()=>void Ee(Y.id),onStop:()=>void De(Y.id)}):V.kind===`third-party`&&Z?(0,S.jsx)(j,{plugin:Z,loading:L,onUnload:()=>void ke(Z.id)}):V.kind===`load-third-party`?(0,S.jsxs)(`div`,{className:`flex flex-col gap-[var(--ui-section-gap)] p-[var(--ui-section-gap)]`,children:[(0,S.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`输入插件文件或目录路径后加载。`}),(0,S.jsxs)(`div`,{className:`flex gap-2`,children:[(0,S.jsx)(te,{value:F,onChange:e=>I(e.target.value),placeholder:`输入插件路径…`,className:`flex-1`,"aria-label":`第三方插件路径`}),(0,S.jsx)(r,{onClick:()=>void Oe(),disabled:L||!F.trim(),children:L?(0,S.jsx)(g,{className:`animate-spin`}):`加载`})]})]}):null})})]})}function T({title:e,extra:t,action:n,children:r}){return(0,S.jsxs)(`section`,{children:[(0,S.jsxs)(`div`,{className:`flex items-center justify-between gap-2 border-b px-[var(--ui-section-gap)] py-1.5 text-xs font-medium text-muted-foreground`,children:[(0,S.jsx)(`span`,{className:`truncate`,children:e}),(0,S.jsxs)(`span`,{className:`flex shrink-0 items-center gap-2`,children:[t,n]})]}),r]})}function E({children:e}){return(0,S.jsx)(`div`,{className:`px-[var(--ui-section-gap)] py-6 text-center text-sm text-muted-foreground`,children:e})}function D(e){let{key:t}=e;if(t!==`ArrowDown`&&t!==`ArrowUp`&&t!==`Home`&&t!==`End`)return;let n=e.currentTarget.closest(`[data-plugin-row-list]`);if(!n)return;let r=Array.from(n.querySelectorAll(`[data-plugin-row-trigger]`)),i=r.indexOf(e.currentTarget);if(i===-1||r.length===0)return;let a=t===`Home`?0:t===`End`?r.length-1:t===`ArrowDown`?Math.min(i+1,r.length-1):Math.max(i-1,0);e.preventDefault(),r[a]?.focus()}var O=`has-[[data-plugin-row-trigger]:focus-visible]:ring-[3px] has-[[data-plugin-row-trigger]:focus-visible]:ring-inset has-[[data-plugin-row-trigger]:focus-visible]:ring-ring/50`;function k({testId:e,selected:t,title:n,meta:r,muted:i,badge:a,action:o,onSelect:s}){return(0,S.jsxs)(`div`,{"data-testid":e,"data-state":t?`selected`:void 0,className:`flex w-full cursor-pointer items-center gap-2 border-b border-border/40 px-[var(--ui-section-gap)] py-2 text-left transition-colors outline-none hover:bg-muted/50 data-[state=selected]:bg-accent ${O} ${i?`opacity-60`:``}`,onClick:s,children:[(0,S.jsxs)(`button`,{type:`button`,"data-plugin-row-trigger":``,"data-testid":`${e}-trigger`,"aria-current":t?`true`:void 0,className:`min-w-0 flex-1 cursor-pointer text-left outline-none`,onKeyDown:D,children:[(0,S.jsx)(`span`,{className:`block truncate text-sm font-medium`,children:n}),r?(0,S.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:r}):null]}),(0,S.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1`,onClick:e=>e.stopPropagation(),onKeyDown:e=>e.stopPropagation(),children:[a,o]})]})}var ve=`插件文件已删除,无法编辑或测试。可以卸载它,或者恢复文件后重新加载`;function A({plugin:e,note:t,loading:n,onStart:i,onStop:a,onUnload:o}){return(0,S.jsxs)(`div`,{className:`flex flex-col gap-[var(--ui-section-gap)] p-[var(--ui-section-gap)]`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`div`,{className:`text-sm font-medium`,children:e.name}),(0,S.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[e.id,` · `,e.version]})]}),t?(0,S.jsx)(`p`,{"data-testid":`plugin-detail-note`,className:`text-xs text-muted-foreground`,children:t}):null,(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:e.hooks.length===0?(0,S.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`无 hooks`}):e.hooks.map(e=>(0,S.jsx)(p,{variant:`secondary`,className:`text-xs`,children:e},e))}),(0,S.jsx)(`div`,{children:o?(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:o,disabled:n,"aria-label":`卸载插件 ${e.name}`,children:[(0,S.jsx)(y,{"data-icon":`inline-start`}),`卸载`]}):e.state===`running`?(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:a,disabled:n,"aria-label":`停止插件 ${e.name}`,children:[(0,S.jsx)(m,{"data-icon":`inline-start`}),`停止`]}):(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:i,disabled:n,"aria-label":`启动插件 ${e.name}`,children:[(0,S.jsx)(h,{"data-icon":`inline-start`}),`启动`]})})]})}function j({plugin:e,loading:t,onUnload:n}){return(0,S.jsxs)(`div`,{className:`flex flex-col gap-[var(--ui-section-gap)] p-[var(--ui-section-gap)]`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`div`,{className:`text-sm font-medium`,children:e.name}),(0,S.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[e.id,` · `,e.version,` · `,e.state]})]}),(0,S.jsx)(`div`,{children:(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:n,disabled:t,className:`text-destructive`,"aria-label":`卸载插件 ${e.name}`,children:[(0,S.jsx)(o,{"data-icon":`inline-start`}),`卸载`]})})]})}export{w as PluginConfig};
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/plugin-generator-CVREuZs7.js","assets/button-BFNlGZ5p.js","assets/index-CSXxaYkG.js","assets/dist-BQN0rzUS.js","assets/dist-CFZ4xMSF.js","assets/dist-C-E2R2jk.js","assets/dist-fzPL-8F9.js","assets/dist-Bsv9ad5F.js","assets/dist-LiAcI8CK.js","assets/dist-DLQKRjuW.js","assets/es2015-DPJTBYa9.js","assets/dist-CRmX_NvH.js","assets/dist-wv9ebJK_.js","assets/check-BkfHQ6re.js","assets/chevron-down-DHwUtL4O.js","assets/toast-9yeTf7d9.js","assets/use-mocks-file-status-BUIUJ4oQ.js","assets/ai-config-store-C8D_PUGV.js","assets/index-C6dPxxT3.css","assets/circle-x-BEkinhez.js","assets/code-DD-AYxxu.js","assets/copy-BRnscYy1.js","assets/wand-sparkles-Bmt4dDOf.js","assets/editor-pane-actions-_ckwcCII.js","assets/pane-bar-zJmE3xI5.js","assets/panel-heading-DlFWoYAR.js","assets/textarea-9wB8Hsz-.js","assets/plugin-code-editor-CtaamKWJ.js","assets/monaco-editor-GpPLOKA5.js","assets/pencil-line-CEZ7D-de.js","assets/rotate-ccw-CRguJya4.js","assets/zap-BuOtogAv.js","assets/plugin-test-dialog-B-iV8ocm.js","assets/body-diff-view-SfLCLzs9.js","assets/arrow-right-BNum_060.js","assets/circle-alert-zMagrFuI.js","assets/refresh-cw-BfLoHqg5.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{c as e,d as t,p as n,t as r,u as i}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as a}from"./refresh-cw-BfLoHqg5.js";import{c as o}from"./dist-BQN0rzUS.js";import{t as s}from"./zap-BuOtogAv.js";import"./es2015-DPJTBYa9.js";import{t as c}from"./switch-94vgsMHm.js";import{G as l,J as ee,K as u,Nt as d,Q as te,U as ne,W as f,Z as p,dt as re,n as ie,ot as ae,q as oe,st as se,ut as m,vt as h,xt as g}from"./index-CSXxaYkG.js";import{n as ce}from"./editor-pane-actions-_ckwcCII.js";import{a as _,i as le,r as ue}from"./pane-bar-zJmE3xI5.js";import{n as de,r as fe,t as v}from"./pane-split-CJ1VXJDy.js";var pe=i(`shield-alert`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M12 16h.01`,key:`1drbdi`}]]),me=i(`shield`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}]]),y=i(`unplug`,[[`path`,{d:`m19 5 3-3`,key:`yk6iyv`}],[`path`,{d:`m2 22 3-3`,key:`19mgm9`}],[`path`,{d:`M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z`,key:`goz73y`}],[`path`,{d:`M7.5 13.5 10 11`,key:`7xgeeb`}],[`path`,{d:`M10.5 16.5 13 14`,key:`10btkg`}],[`path`,{d:`m12 6 6 6 2.3-2.3a2.4 2.4 0 0 0 0-3.4l-2.6-2.6a2.4 2.4 0 0 0-3.4 0Z`,key:`1snsnr`}]]),b=n(t(),1),x=v({storageKey:`meddle-plugin-list-width`,defaultPx:360,minPx:280,maxPx:560,editorMinPx:420});x.storageKey,x.defaultPx;var S=e(),he=(0,b.lazy)(()=>d(()=>import(`./plugin-generator-CVREuZs7.js`).then(e=>({default:e.PluginGenerator})),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]))),ge=(0,b.lazy)(()=>d(()=>import(`./plugin-code-editor-CtaamKWJ.js`).then(e=>({default:e.PluginCodeEditor})),__vite__mapDeps([27,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,28,29,30,31,23,24,25,26]))),_e=(0,b.lazy)(()=>d(()=>import(`./plugin-test-dialog-B-iV8ocm.js`).then(e=>({default:e.PluginTestDialog})),__vite__mapDeps([32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,28,33,34,35,19,29,36,22,23,25,26])));function C(){return(0,S.jsxs)(`div`,{className:`flex h-full min-h-[160px] items-center justify-center gap-2 text-sm text-muted-foreground`,children:[(0,S.jsx)(g,{className:`size-4 animate-spin`}),`加载编辑器…`]})}function w({plugins:e,pluginMode:t,switchPluginMode:n,fetchPlugins:i,startPlugin:d,stopPlugin:m,togglePlugin:h,thirdPartyPlugins:v,thirdPartySecurity:w,fetchThirdPartyPlugins:D,loadThirdPartyPlugin:O,unloadThirdPartyPlugin:M}){let[N,P]=(0,b.useState)(!1),[F,I]=(0,b.useState)(``),[L,R]=(0,b.useState)(!1),[ye,be]=(0,b.useState)([]),[z,B]=(0,b.useState)(!1),[V,H]=(0,b.useState)({kind:`idle`}),[xe,Se]=(0,b.useState)(null),U=(0,b.useRef)(null),Ce=(0,b.useCallback)(e=>{U.current=e},[]),we=(0,b.useCallback)(()=>{if(U.current){U.current();return}H({kind:`idle`})},[]);(0,b.useEffect)(()=>{i(),D(),W()},[i,D]),(0,b.useEffect)(()=>{let e=()=>{W()};return window.addEventListener(`plugins-custom-updated`,e),()=>window.removeEventListener(`plugins-custom-updated`,e)},[]);let W=async()=>{try{be((await(await fetch(`/api/plugins/custom`)).json()).plugins||[])}catch(e){console.error(`加载自定义插件失败:`,e)}},Te=async(e,t)=>{if(confirm(`确定要删除插件 ${e} 吗?`))try{let n=await fetch(`/api/plugins/custom/${encodeURIComponent(e)}`,{method:`DELETE`});if(n.ok)H(n=>n.kind===`code`&&n.filename===e||n.kind===`test`&&(n.filename===e||t!==void 0&&n.pluginId===t)?{kind:`idle`}:n),await W();else{let e=await n.json();alert(e.error||`删除失败`)}}catch(e){console.error(`删除插件失败:`,e),alert(`删除失败`)}},G=async(e,t)=>{if(confirm(`插件文件已删除,确定要从内存卸载 ${t} 吗?`))try{let t=await fetch(`/api/plugins/custom/loaded/${encodeURIComponent(e)}/unload`,{method:`POST`});if(t.ok)H(t=>(t.kind===`test`||t.kind===`builtin`)&&t.pluginId===e?{kind:`idle`}:t),await i(),await W();else{let e=await t.json().catch(()=>({}));alert(e.error||`卸载失败`)}}catch(e){console.error(`卸载插件失败:`,e),alert(`卸载失败`)}},K=async()=>{B(!0);try{let e=await fetch(`/api/plugins/reload`,{method:`POST`});if(e.ok){let t=await e.json();alert(`成功热加载 ${t.count} 个插件!`),await i(),await W()}else{let t=await e.json();alert(t.error||`热加载失败`)}}catch(e){console.error(`热加载失败:`,e),alert(`热加载失败`)}finally{B(!1)}},Ee=async e=>{P(!0);try{await d(e),await i()}finally{P(!1)}},De=async e=>{P(!0);try{await m(e),await i()}finally{P(!1)}},Oe=async()=>{if(F.trim()){R(!0);try{await O(F),I(``),await D()}finally{R(!1)}}},ke=async e=>{R(!0);try{await M(e),await D(),V.kind===`third-party`&&V.pluginId===e&&H({kind:`idle`})}finally{R(!1)}},{builtinPlugins:q,customRows:J}=ie(e,ye,new Set(v.map(e=>e.id))),Y=V.kind===`builtin`?e.find(e=>e.id===V.pluginId):void 0,X=Y?J.find(e=>e.fileDeleted&&e.pluginId===Y.id):void 0,Z=V.kind===`third-party`?v.find(e=>e.id===V.pluginId):void 0,Q=V.kind===`generate`?`编辑插件 · AI 生成`:V.kind===`code`?`编辑插件 · ${V.filename}`:V.kind===`test`?`编辑插件 · 测试 ${V.pluginName}`:V.kind===`builtin`?`编辑插件 · ${Y?.name||V.pluginId}`:V.kind===`third-party`?`编辑插件 · ${Z?.name||V.pluginId}`:V.kind===`load-third-party`?`编辑插件 · 加载第三方`:`编辑插件`,Ae=V.kind===`code`||V.kind===`generate`||V.kind===`test`,$=de(Q);return(0,S.jsxs)(fe,{testId:`plugin-config-layout`,layout:`list-edit`,widthAttr:`plugin-list-width`,split:x,listTestId:`plugin-config-list`,panelTestId:`plugin-config-edit`,separatorTestId:`plugin-panel-separator`,separatorLabel:`调整插件列表宽度`,list:(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`div`,{className:`shrink-0`,children:[(0,S.jsxs)(le,{children:[(0,S.jsx)(_,{children:`插件`}),(0,S.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void W(),disabled:N||z,"aria-label":`刷新列表`,children:(0,S.jsx)(a,{})}),(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void K(),disabled:N||z,"aria-label":`热加载插件`,children:z?(0,S.jsx)(g,{className:`animate-spin`}):(0,S.jsx)(s,{})}),(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:()=>H({kind:`generate`}),"data-testid":`plugin-config-generate`,children:[(0,S.jsx)(re,{"data-icon":`inline-start`}),`AI 生成`]})]})]}),(0,S.jsxs)(`div`,{className:`flex items-center gap-2 border-b p-[var(--ui-section-gap)]`,children:[(0,S.jsxs)(ne,{value:t,onValueChange:e=>n(e),children:[(0,S.jsx)(oe,{className:`h-7 w-full text-xs`,"aria-label":`插件模式`,children:(0,S.jsx)(ee,{})}),(0,S.jsx)(f,{children:(0,S.jsxs)(l,{children:[(0,S.jsx)(u,{value:`off`,children:`关闭`}),(0,S.jsx)(u,{value:`on`,children:`开启`}),(0,S.jsx)(u,{value:`shadow`,children:`影子模式`})]})})]}),t===`off`?(0,S.jsx)(p,{variant:`destructive`,className:`shrink-0 text-xs`,children:`未生效`}):null]})]}),(0,S.jsxs)(`div`,{"data-plugin-row-list":``,className:`meddle-thin-scroll min-h-0 flex-1 overflow-x-hidden overflow-y-auto`,children:[(0,S.jsx)(T,{title:`内置插件`,children:q.length===0?(0,S.jsx)(E,{children:`暂无内置插件`}):q.map(e=>(0,S.jsx)(k,{testId:`plugin-config-row-builtin-${e.id}`,selected:V.kind===`builtin`&&V.pluginId===e.id,title:e.name,meta:e.version,onSelect:()=>H({kind:`builtin`,pluginId:e.id}),badge:(0,S.jsx)(p,{variant:e.state===`running`?`default`:`secondary`,children:e.state})},e.id))}),(0,S.jsx)(T,{title:`自定义插件`,children:J.length===0?(0,S.jsx)(E,{children:`暂无自定义插件,点击「AI 生成」`}):J.map(({filename:e,pluginId:t,loadedPlugin:n,fileDeleted:i})=>{let a=n?n.state!==`disabled`:!1,s=i?(V.kind===`builtin`||V.kind===`test`)&&V.pluginId===t:V.kind===`code`&&V.filename===e||V.kind===`test`&&(V.filename===e||V.pluginId===t),l=n?a?`已启用`:`已禁用`:`未加载`;return(0,S.jsx)(k,{testId:i?`plugin-config-row-custom-deleted-${t}`:`plugin-config-row-custom-${e}`,selected:s,title:e,meta:l,muted:!!n&&!a,onSelect:()=>H(i?{kind:`builtin`,pluginId:t}:{kind:`code`,filename:e}),badge:(0,S.jsxs)(S.Fragment,{children:[i?(0,S.jsxs)(`span`,{"data-testid":`plugin-file-deleted-label`,className:`mr-1 inline-flex items-center gap-1 text-xs text-muted-foreground`,children:[(0,S.jsx)(ae,{"aria-hidden":`true`,className:`size-3.5 shrink-0`}),`文件已删除`]}):null,n?(0,S.jsx)(c,{checked:a,onCheckedChange:e=>h(n.id,e),"aria-label":`启用插件 ${e}`}):(0,S.jsx)(p,{variant:`outline`,children:`未加载`})]}),action:(0,S.jsxs)(`div`,{className:`flex items-center`,children:[n&&a&&!i&&(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>H({kind:`test`,pluginId:n.id,pluginName:n.name,hooks:n.hooks,filename:e}),"aria-label":`测试插件 ${n.name}`,children:(0,S.jsx)(se,{})}),i?(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void G(t,e),"aria-label":`卸载插件 ${e}`,"aria-description":`文件已删除,仅从内存移除`,title:`卸载`,children:(0,S.jsx)(y,{})}):(0,S.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void Te(e,n?.id),className:`text-destructive`,"aria-label":`删除插件 ${e}`,children:(0,S.jsx)(o,{})})]})},i?`loaded:${t}`:e)})}),(0,S.jsx)(T,{title:`第三方插件`,extra:(0,S.jsxs)(`span`,{className:`inline-flex items-center gap-1 normal-case tracking-normal`,children:[w.allowAll?(0,S.jsx)(me,{className:`size-3.5 text-primary`}):(0,S.jsx)(pe,{className:`size-3.5`}),w.allowAll?`已信任所有插件`:`已信任 ${w.trusted.length} 个`]}),action:(0,S.jsx)(r,{variant:`ghost`,size:`xs`,onClick:()=>H({kind:`load-third-party`}),"data-testid":`plugin-config-load`,children:`加载`}),children:v.length===0?(0,S.jsx)(E,{children:`暂无第三方插件`}):v.map(e=>(0,S.jsx)(k,{testId:`plugin-config-row-third-${e.id}`,selected:V.kind===`third-party`&&V.pluginId===e.id,title:e.name,meta:e.version,onSelect:()=>H({kind:`third-party`,pluginId:e.id}),badge:(0,S.jsx)(p,{variant:e.state===`running`?`default`:`secondary`,children:e.state})},e.id))})]})]}),children:[(0,S.jsx)(ue,{"data-testid":`plugin-editor-title-bar`,scrolled:$.scrolled,title:Q,actions:(0,S.jsxs)(S.Fragment,{children:[V.kind===`idle`?null:(0,S.jsx)(r,{variant:`ghost`,size:`sm`,onClick:we,children:`取消`}),(0,S.jsx)(`div`,{ref:Se,"data-testid":`editor-pane-actions`,className:`contents`})]})}),(0,S.jsx)(ce,{host:xe,registerDismiss:Ce,children:(0,S.jsx)(`div`,{className:Ae?`min-h-0 flex-1 overflow-hidden`:`min-h-0 flex-1 overflow-y-auto`,onScroll:$.onScroll,"data-slot":`plugin-editor-scroll`,children:V.kind===`idle`?(0,S.jsxs)(`div`,{className:`flex h-full min-h-[240px] flex-col items-center justify-center gap-2 p-6 text-center text-sm text-muted-foreground`,children:[(0,S.jsx)(`p`,{children:`选择左侧插件进行编辑,或点击「AI 生成」`}),(0,S.jsx)(`p`,{className:`text-xs`,children:`自定义插件在右侧编辑代码;内置和第三方插件在右侧查看并操作`})]}):V.kind===`generate`?(0,S.jsx)(b.Suspense,{fallback:(0,S.jsx)(C,{}),children:(0,S.jsx)(he,{embedded:!0,plainHeading:!0,onOpenChange:e=>{e||H({kind:`idle`})},onPluginSaved:()=>{i(),W()}})}):V.kind===`code`?(0,S.jsx)(b.Suspense,{fallback:(0,S.jsx)(C,{}),children:(0,S.jsx)(ge,{embedded:!0,plainHeading:!0,filename:V.filename,onOpenChange:e=>{e||H({kind:`idle`})},onSaved:()=>{i()}},V.filename)}):V.kind===`test`?(0,S.jsx)(b.Suspense,{fallback:(0,S.jsx)(C,{}),children:(0,S.jsx)(_e,{embedded:!0,plainHeading:!0,pluginId:V.pluginId,pluginName:V.pluginName,hooks:V.hooks,filename:V.filename,onOpenChange:e=>{e||H({kind:`idle`})},onPluginFixed:()=>{i()}},V.pluginId)}):V.kind===`builtin`&&Y?(0,S.jsx)(A,{plugin:Y,...X?{note:ve,onUnload:()=>void G(X.pluginId,X.filename)}:{},loading:N,onStart:()=>void Ee(Y.id),onStop:()=>void De(Y.id)}):V.kind===`third-party`&&Z?(0,S.jsx)(j,{plugin:Z,loading:L,onUnload:()=>void ke(Z.id)}):V.kind===`load-third-party`?(0,S.jsxs)(`div`,{className:`flex flex-col gap-[var(--ui-section-gap)] p-[var(--ui-section-gap)]`,children:[(0,S.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`输入插件文件或目录路径后加载。`}),(0,S.jsxs)(`div`,{className:`flex gap-2`,children:[(0,S.jsx)(te,{value:F,onChange:e=>I(e.target.value),placeholder:`输入插件路径…`,className:`flex-1`,"aria-label":`第三方插件路径`}),(0,S.jsx)(r,{onClick:()=>void Oe(),disabled:L||!F.trim(),children:L?(0,S.jsx)(g,{className:`animate-spin`}):`加载`})]})]}):null})})]})}function T({title:e,extra:t,action:n,children:r}){return(0,S.jsxs)(`section`,{children:[(0,S.jsxs)(`div`,{className:`flex items-center justify-between gap-2 border-b px-[var(--ui-section-gap)] py-1.5 text-xs font-medium text-muted-foreground`,children:[(0,S.jsx)(`span`,{className:`truncate`,children:e}),(0,S.jsxs)(`span`,{className:`flex shrink-0 items-center gap-2`,children:[t,n]})]}),r]})}function E({children:e}){return(0,S.jsx)(`div`,{className:`px-[var(--ui-section-gap)] py-6 text-center text-sm text-muted-foreground`,children:e})}function D(e){let{key:t}=e;if(t!==`ArrowDown`&&t!==`ArrowUp`&&t!==`Home`&&t!==`End`)return;let n=e.currentTarget.closest(`[data-plugin-row-list]`);if(!n)return;let r=Array.from(n.querySelectorAll(`[data-plugin-row-trigger]`)),i=r.indexOf(e.currentTarget);if(i===-1||r.length===0)return;let a=t===`Home`?0:t===`End`?r.length-1:t===`ArrowDown`?Math.min(i+1,r.length-1):Math.max(i-1,0);e.preventDefault(),r[a]?.focus()}var O=`has-[[data-plugin-row-trigger]:focus-visible]:ring-[3px] has-[[data-plugin-row-trigger]:focus-visible]:ring-inset has-[[data-plugin-row-trigger]:focus-visible]:ring-ring/50`;function k({testId:e,selected:t,title:n,meta:r,muted:i,badge:a,action:o,onSelect:s}){return(0,S.jsxs)(`div`,{"data-testid":e,"data-state":t?`selected`:void 0,className:`flex w-full cursor-pointer items-center gap-2 border-b border-border/40 px-[var(--ui-section-gap)] py-2 text-left transition-colors outline-none hover:bg-muted/50 data-[state=selected]:bg-accent ${O} ${i?`opacity-60`:``}`,onClick:s,children:[(0,S.jsxs)(`button`,{type:`button`,"data-plugin-row-trigger":``,"data-testid":`${e}-trigger`,"aria-current":t?`true`:void 0,className:`min-w-0 flex-1 cursor-pointer text-left outline-none`,onKeyDown:D,children:[(0,S.jsx)(`span`,{className:`block truncate text-sm font-medium`,children:n}),r?(0,S.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:r}):null]}),(0,S.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1`,onClick:e=>e.stopPropagation(),onKeyDown:e=>e.stopPropagation(),children:[a,o]})]})}var ve=`插件文件已删除,无法编辑或测试。可以卸载它,或者恢复文件后重新加载`;function A({plugin:e,note:t,loading:n,onStart:i,onStop:a,onUnload:o}){return(0,S.jsxs)(`div`,{className:`flex flex-col gap-[var(--ui-section-gap)] p-[var(--ui-section-gap)]`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`div`,{className:`text-sm font-medium`,children:e.name}),(0,S.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[e.id,` · `,e.version]})]}),t?(0,S.jsx)(`p`,{"data-testid":`plugin-detail-note`,className:`text-xs text-muted-foreground`,children:t}):null,(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:e.hooks.length===0?(0,S.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`无 hooks`}):e.hooks.map(e=>(0,S.jsx)(p,{variant:`secondary`,className:`text-xs`,children:e},e))}),(0,S.jsx)(`div`,{children:o?(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:o,disabled:n,"aria-label":`卸载插件 ${e.name}`,children:[(0,S.jsx)(y,{"data-icon":`inline-start`}),`卸载`]}):e.state===`running`?(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:a,disabled:n,"aria-label":`停止插件 ${e.name}`,children:[(0,S.jsx)(m,{"data-icon":`inline-start`}),`停止`]}):(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:i,disabled:n,"aria-label":`启动插件 ${e.name}`,children:[(0,S.jsx)(h,{"data-icon":`inline-start`}),`启动`]})})]})}function j({plugin:e,loading:t,onUnload:n}){return(0,S.jsxs)(`div`,{className:`flex flex-col gap-[var(--ui-section-gap)] p-[var(--ui-section-gap)]`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`div`,{className:`text-sm font-medium`,children:e.name}),(0,S.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[e.id,` · `,e.version,` · `,e.state]})]}),(0,S.jsx)(`div`,{children:(0,S.jsxs)(r,{variant:`outline`,size:`sm`,onClick:n,disabled:t,className:`text-destructive`,"aria-label":`卸载插件 ${e.name}`,children:[(0,S.jsx)(o,{"data-icon":`inline-start`}),`卸载`]})})]})}export{w as PluginConfig};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as e,d as t,p as n,t as r}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as i}from"./check-BkfHQ6re.js";import{t as a}from"./circle-x-BEkinhez.js";import{t as o}from"./code-DD-AYxxu.js";import{t as s}from"./copy-BRnscYy1.js";import{t as ee}from"./wand-sparkles-Bmt4dDOf.js";import"./es2015-DPJTBYa9.js";import{o as te,r as ne}from"./ai-config-store-C8D_PUGV.js";import{n as c}from"./toast-9yeTf7d9.js";import{Q as l,T as u,Z as d,b as re,dt as f,g as ie,h as ae,kt as oe,x as se,xt as p,y as m}from"./index-
|
|
1
|
+
import{c as e,d as t,p as n,t as r}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as i}from"./check-BkfHQ6re.js";import{t as a}from"./circle-x-BEkinhez.js";import{t as o}from"./code-DD-AYxxu.js";import{t as s}from"./copy-BRnscYy1.js";import{t as ee}from"./wand-sparkles-Bmt4dDOf.js";import"./es2015-DPJTBYa9.js";import{o as te,r as ne}from"./ai-config-store-C8D_PUGV.js";import{n as c}from"./toast-9yeTf7d9.js";import{Q as l,T as u,Z as d,b as re,dt as f,g as ie,h as ae,kt as oe,x as se,xt as p,y as m}from"./index-CSXxaYkG.js";import{i as ce,t as le}from"./editor-pane-actions-_ckwcCII.js";import{n as ue}from"./pane-bar-zJmE3xI5.js";import{t as de}from"./panel-heading-DlFWoYAR.js";import{t as fe}from"./textarea-9wB8Hsz-.js";var h=n(t(),1),g=e();function _({open:e=!1,onOpenChange:t,embedded:n=!1,plainHeading:_=!1,onPluginSaved:v}){let[y,b]=(0,h.useState)(``),[x,S]=(0,h.useState)(``),[C,w]=(0,h.useState)(``),[pe,T]=(0,h.useState)(``),[E,D]=(0,h.useState)(!1),[O,k]=(0,h.useState)(!1),[A,j]=(0,h.useState)(``),[M,N]=(0,h.useState)(``),[P,F]=(0,h.useState)(null),[I,L]=(0,h.useState)(null),[R,z]=(0,h.useState)(``),[me,B]=(0,h.useState)(!1),[V,H]=(0,h.useState)(0),[U,W]=(0,h.useState)(0),[G,K]=(0,h.useState)(!1),[q,J]=(0,h.useState)(!1),Y=ne(),X=te(Y),he=async()=>{if(!y.trim()||!x.trim()){L(`error`),z(`请填写插件名称和描述`);return}if(!X){L(`error`),z(`AI 配置未完成,请先配置 AI 服务`);return}D(!0),L(null),z(`正在连接 AI 服务…`),j(``),H(0),W(0);let e=Date.now(),t=0;try{let n={name:y,description:x,hooks:C.split(`,`).map(e=>e.trim()).filter(Boolean),permissions:pe.split(`,`).map(e=>e.trim()).filter(Boolean)},r=await fetch(`/api/plugins/generate-stream`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({requirement:n,aiConfig:{provider:Y.provider,apiKey:Y.apiKey,baseUrl:Y.baseUrl,model:Y.model}})});if(!r.ok)throw Error(`请求失败: ${r.status}`);let i=r.body?.getReader(),a=new TextDecoder;if(!i)throw Error(`无法读取响应流`);let o=``;for(;;){let{done:n,value:r}=await i.read();if(n)break;o+=a.decode(r,{stream:!0});let s=o.split(`
|
|
2
2
|
`);o=s.pop()||``;for(let n of s)if(!n.startsWith(`event:`)&&n.startsWith(`data:`)){let r=n.slice(5).trim();try{let n=JSON.parse(r);if(n.status===`generating`)z(`AI 正在生成代码…`),W(10);else if(n.chunk){t++;let r=n.accumulated||n.chunk;j(r),H(r.length),W(Math.min(90,10+t*2));let i=((Date.now()-e)/1e3).toFixed(1);z(`生成中… (${r.length} 字符, ${i}s)`)}else if(n.status===`success`){j(n.plugin.code),N(n.plugin.filename),F(n.plugin.manifest),H(n.plugin.code.length),W(100),L(`success`);let t=((Date.now()-e)/1e3).toFixed(1);z(`插件代码生成成功!(${n.plugin.code.length} 字符, ${t}s)`)}else if(n.error)throw Error(n.error)}catch(e){if(e instanceof Error&&e.message!==`Unexpected end of JSON input`)throw e}}}}catch(e){L(`error`),z(e instanceof Error?e.message:`生成失败`),W(0)}finally{D(!1)}},Z=async()=>{if(!A||!M){L(`error`),z(`没有可保存的插件代码`);return}k(!0),L(null),z(`正在保存插件…`);try{let e=await fetch(`/api/plugins/save`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({filename:M,code:A})});if(!e.ok){let t=await e.json();throw Error(t.error||`保存失败`)}await e.json(),L(`success`),z(`插件已保存!现在可以热加载并测试。`),K(!0),window.dispatchEvent(new CustomEvent(`plugins-custom-updated`)),c.success(`插件保存成功`),v&&v(),window.dispatchEvent(new CustomEvent(`plugins-custom-updated`))}catch(e){let t=e instanceof Error?e.message:`保存失败`;L(`error`),z(t),c.error(t)}finally{k(!1)}};ae({active:(e||n)&&!!A&&!G,enabled:!O&&!E&&!!M,priority:ie.panel,onSave:Z});let ge=async()=>{A&&(await navigator.clipboard.writeText(A),B(!0),setTimeout(()=>B(!1),2e3))},_e=async()=>{J(!0);try{let e=await fetch(`/api/plugins/reload`,{method:`POST`});if(!e.ok){let t=await e.json();throw Error(t.error||`热加载失败`)}let n=await e.json();L(`success`),z(`成功热加载 ${n.count} 个插件!插件已激活,可以使用了。`),v&&v(),setTimeout(()=>{t?.(!1),Q()},3e3)}catch(e){L(`error`),z(e instanceof Error?e.message:`热加载失败`)}finally{J(!1)}},Q=()=>{b(``),S(``),w(``),T(``),j(``),N(``),F(null),L(null),z(``),B(!1),H(0),W(0),K(!1),J(!1)},$=ce(),ve=(0,g.jsxs)(g.Fragment,{children:[_?null:(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(de,{className:`px-6 pt-6 pb-4`,title:(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(f,{className:`h-5 w-5`}),`AI 插件生成器`]}),description:`使用 AI 根据插件系统设计和您的需求自动生成自定义插件代码`}),(0,g.jsx)(m,{})]}),(0,g.jsxs)(`div`,{className:`app-panel-content`,children:[!X&&(0,g.jsx)(`div`,{className:`bg-yellow-50 dark:bg-yellow-950/20 border border-yellow-200 dark:border-yellow-900 rounded-md p-3`,children:(0,g.jsx)(`p`,{className:`text-sm text-yellow-700 dark:text-yellow-300`,children:`AI 功能未配置或未启用,请先在设置中配置 AI 服务`})}),(0,g.jsxs)(`div`,{className:`app-section`,children:[(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsxs)(u,{htmlFor:`pluginName`,children:[`插件名称 `,(0,g.jsx)(`span`,{className:`text-red-500`,children:`*`})]}),(0,g.jsx)(l,{id:`pluginName`,value:y,onChange:e=>b(e.target.value),placeholder:`例如:请求日志分析器`,disabled:E||O})]}),(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsxs)(u,{htmlFor:`pluginDescription`,children:[`插件描述 `,(0,g.jsx)(`span`,{className:`text-red-500`,children:`*`})]}),(0,g.jsx)(fe,{id:`pluginDescription`,value:x,onChange:e=>S(e.target.value),placeholder:`详细描述插件的功能,例如:分析HTTP请求日志,统计各个API的调用次数、响应时间等信息,并在控制台输出统计报告`,rows:4,disabled:E||O})]}),(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsx)(u,{htmlFor:`hooks`,children:`需要的 Hooks(可选,用逗号分隔)`}),(0,g.jsx)(l,{id:`hooks`,value:C,onChange:e=>w(e.target.value),placeholder:`例如:onRequestStart, onAfterResponse`,disabled:E||O}),(0,g.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`可选:onRequestStart, onBeforeProxy, onBeforeResponse, onAfterResponse, onError`})]}),(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsx)(u,{htmlFor:`permissions`,children:`需要的权限(可选,用逗号分隔)`}),(0,g.jsx)(l,{id:`permissions`,value:pe,onChange:e=>T(e.target.value),placeholder:`例如:proxy:read, storage:write`,disabled:E||O}),(0,g.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`可选:proxy:read, proxy:write, response:shortcircuit, storage:read, storage:write`})]})]}),E&&U>0&&(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between text-sm`,children:[(0,g.jsx)(`span`,{className:`text-muted-foreground`,children:`生成进度`}),(0,g.jsxs)(`span`,{className:`font-medium`,children:[U,`%`]})]}),(0,g.jsx)(`div`,{className:`w-full bg-muted rounded-full h-2 overflow-hidden`,children:(0,g.jsx)(`div`,{className:`bg-primary h-full transition-all duration-300 ease-out`,style:{width:`${U}%`}})})]}),(A||E)&&(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,g.jsxs)(u,{className:`flex items-center gap-2`,children:[(0,g.jsx)(o,{className:`h-4 w-4`}),E?`正在生成插件代码`:`生成的插件代码`]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2`,children:[V>0&&(0,g.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[V,` 字符`]}),!E&&A&&(0,g.jsx)(r,{variant:`ghost`,size:`sm`,onClick:ge,className:`h-8`,children:me?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(i,{className:`h-4 w-4 mr-1`}),`已复制`]}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(s,{className:`h-4 w-4 mr-1`}),`复制`]})})]})]}),(0,g.jsxs)(`div`,{className:`bg-muted rounded-md p-4 max-h-[400px] overflow-auto relative`,children:[E&&(0,g.jsx)(`div`,{className:`absolute top-2 right-2`,children:(0,g.jsx)(p,{className:`h-4 w-4 animate-spin text-muted-foreground`})}),(0,g.jsx)(`pre`,{className:`text-xs font-mono whitespace-pre-wrap break-all`,children:A||`等待 AI 响应…`})]}),P&&(0,g.jsxs)(`div`,{className:`bg-blue-50 dark:bg-blue-950/20 border border-blue-200 dark:border-blue-900 rounded-md p-3 space-y-2`,children:[(0,g.jsx)(`p`,{className:`text-sm font-medium text-blue-900 dark:text-blue-100`,children:`插件信息`}),(0,g.jsxs)(`div`,{className:`text-xs space-y-1 text-blue-700 dark:text-blue-300`,children:[(0,g.jsxs)(`div`,{children:[(0,g.jsx)(`strong`,{children:`ID:`}),` `,P.id]}),(0,g.jsxs)(`div`,{children:[(0,g.jsx)(`strong`,{children:`名称:`}),` `,P.name]}),(0,g.jsxs)(`div`,{children:[(0,g.jsx)(`strong`,{children:`版本:`}),` `,P.version]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,g.jsx)(`strong`,{children:`Hooks:`}),(0,g.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:P.hooks.map(e=>(0,g.jsx)(d,{variant:`secondary`,className:`text-xs`,children:e},e))})]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,g.jsx)(`strong`,{children:`权限:`}),(0,g.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:P.permissions.map(e=>(0,g.jsx)(d,{variant:`outline`,className:`text-xs`,children:e},e))})]})]})]})]}),R&&(0,g.jsxs)(`div`,{className:`flex items-start gap-2 p-3 rounded-md border ${I===`success`?`bg-green-50 dark:bg-green-950/20 border-green-200 dark:border-green-900`:I===`error`?`bg-red-50 dark:bg-red-950/20 border-red-200 dark:border-red-900`:`bg-blue-50 dark:bg-blue-950/20 border-blue-200 dark:border-blue-900`}`,children:[I===`success`&&(0,g.jsx)(oe,{className:`h-4 w-4 text-green-600 dark:text-green-400 mt-0.5`}),I===`error`&&(0,g.jsx)(a,{className:`h-4 w-4 text-red-600 dark:text-red-400 mt-0.5`}),E&&(0,g.jsx)(p,{className:`h-4 w-4 text-blue-600 dark:text-blue-400 mt-0.5 animate-spin`}),(0,g.jsx)(`span`,{className:`text-xs flex-1 ${I===`success`?`text-green-700 dark:text-green-300`:I===`error`?`text-red-700 dark:text-red-300`:`text-blue-700 dark:text-blue-300`}`,children:R})]})]}),$?null:(0,g.jsx)(m,{}),(0,g.jsxs)(le,{className:`px-6 py-4 flex justify-between gap-2`,children:[$?null:(0,g.jsx)(r,{variant:`outline`,size:`sm`,onClick:()=>{t?.(!1),Q()},disabled:E||O||q,children:G?`完成`:`取消`}),(0,g.jsx)(`div`,{className:$?`contents`:`flex gap-2`,children:A?G?(0,g.jsx)(r,{variant:`outline`,size:`sm`,onClick:_e,disabled:q,"data-testid":`plugin-generator-hot-reload`,children:q?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(p,{className:`h-4 w-4 mr-1 animate-spin`}),`加载中…`]}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(f,{className:`h-4 w-4 mr-1`}),`热加载并测试`]})}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(r,{variant:`outline`,size:`sm`,onClick:()=>{j(``),N(``),F(null),L(null),z(``)},disabled:E||O,children:`重新生成`}),(0,g.jsx)(ue,{onClick:Z,saving:O,label:`保存插件`})]}):(0,g.jsx)(r,{size:`sm`,onClick:he,disabled:!X||E||O||!y.trim()||!x.trim(),children:E?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(p,{className:`h-4 w-4 mr-1 animate-spin`}),`生成中…`]}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(ee,{className:`h-4 w-4 mr-1`}),`生成插件`]})})})]})]});return n?(0,g.jsx)(`div`,{className:`flex h-full min-h-0 flex-col`,children:ve}):(0,g.jsx)(re,{open:e,onOpenChange:e=>{t?.(e),e||Q()},children:(0,g.jsx)(se,{className:`p-0 flex flex-col`,resizable:!0,defaultWidth:900,storageKey:`plugin-generator`,children:ve})})}export{_ as PluginGenerator};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as e,d as t,p as n,t as r,u as i}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as a}from"./arrow-right-BNum_060.js";import{t as o}from"./circle-alert-zMagrFuI.js";import{t as s}from"./circle-x-BEkinhez.js";import{t as ee}from"./pencil-line-CEZ7D-de.js";import{t as te}from"./refresh-cw-BfLoHqg5.js";import{t as ne}from"./wand-sparkles-Bmt4dDOf.js";import"./es2015-DPJTBYa9.js";import{i as re,o as ie,r as ae}from"./ai-config-store-C8D_PUGV.js";import{Et as oe,M as c,Ot as se,Q as ce,T as l,Z as u,b as le,ct as d,j as f,k as p,kt as ue,t as de,wt as fe,x as pe,xt as m,y as h}from"./index-
|
|
1
|
+
import{c as e,d as t,p as n,t as r,u as i}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as a}from"./arrow-right-BNum_060.js";import{t as o}from"./circle-alert-zMagrFuI.js";import{t as s}from"./circle-x-BEkinhez.js";import{t as ee}from"./pencil-line-CEZ7D-de.js";import{t as te}from"./refresh-cw-BfLoHqg5.js";import{t as ne}from"./wand-sparkles-Bmt4dDOf.js";import"./es2015-DPJTBYa9.js";import{i as re,o as ie,r as ae}from"./ai-config-store-C8D_PUGV.js";import{Et as oe,M as c,Ot as se,Q as ce,T as l,Z as u,b as le,ct as d,j as f,k as p,kt as ue,t as de,wt as fe,x as pe,xt as m,y as h}from"./index-CSXxaYkG.js";import{t as g}from"./body-diff-view-SfLCLzs9.js";import{n as me,t as he}from"./monaco-editor-GpPLOKA5.js";import{i as ge,t as _e}from"./editor-pane-actions-_ckwcCII.js";import{t as ve}from"./panel-heading-DlFWoYAR.js";import{t as ye}from"./textarea-9wB8Hsz-.js";var be=i(`circle-play`,[[`path`,{d:`M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z`,key:`kmsa83`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]),_=n(t(),1),v=e();function y(e){let t=new Map;return!e||typeof e!=`object`||Object.entries(e).forEach(([e,n])=>{t.set(e.toLowerCase(),{displayKey:e,value:n==null?``:String(n)})}),t}function b(e,t){let n=y(e),r=y(t);return Array.from(new Set([...n.keys(),...r.keys()])).sort().map(e=>{let t=n.get(e),i=r.get(e),a=t?.value??``,o=i?.value??``,s=`unchanged`;return!t&&i?s=`added`:t&&!i?s=`removed`:a!==o&&(s=`changed`),{key:e,displayKey:i?.displayKey??t?.displayKey??e,originalValue:a,modifiedValue:o,status:s}})}function x(e,t){let n=`rounded-md border px-2 py-1.5`;return e===`unchanged`?`${n} border-transparent`:e===`changed`?`${n} border-orange-300 bg-orange-500/10`:e===`added`?t===`modified`?`${n} border-green-300 bg-green-500/10`:`${n} border-transparent opacity-50`:e===`removed`?t===`original`?`${n} border-red-300 bg-red-500/10`:`${n} border-transparent opacity-50`:n}function xe({original:e,modified:t,mode:n=`split`}){let r=b(e,t);return n===`inline`?(0,v.jsx)(`div`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[220px] overflow-auto space-y-1`,children:r.map(e=>(0,v.jsxs)(`div`,{className:`rounded-md border px-2 py-1.5 ${e.status===`unchanged`?`border-transparent`:e.status===`changed`?`border-orange-300 bg-orange-500/10`:e.status===`added`?`border-green-300 bg-green-500/10`:`border-red-300 bg-red-500/10`}`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,v.jsx)(`span`,{className:`text-muted-foreground`,children:e.displayKey}),(0,v.jsx)(u,{variant:`outline`,className:`h-5 px-1.5 text-[10px] font-normal`,children:e.status===`unchanged`?`未变`:e.status===`changed`?`修改`:e.status===`added`?`新增`:`删除`})]}),e.status===`changed`&&(0,v.jsxs)(`div`,{className:`mt-1 space-y-1`,children:[(0,v.jsxs)(`div`,{className:`text-red-700 dark:text-red-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`-`}),e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]}),(0,v.jsxs)(`div`,{className:`text-green-700 dark:text-green-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`+`}),e.modifiedValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]})]}),e.status===`added`&&(0,v.jsxs)(`div`,{className:`mt-1 text-green-700 dark:text-green-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`+`}),e.modifiedValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]}),e.status===`removed`&&(0,v.jsxs)(`div`,{className:`mt-1 text-red-700 dark:text-red-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`-`}),e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]}),e.status===`unchanged`&&(0,v.jsx)(`div`,{className:`mt-1`,children:e.modifiedValue||e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})})]},e.key))}):(0,v.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`div`,{className:`text-[10px] text-muted-foreground mb-0.5`,children:`原始`}),(0,v.jsx)(`div`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[220px] overflow-auto space-y-1`,children:r.map(e=>(0,v.jsxs)(`div`,{className:x(e.status,`original`),children:[(0,v.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.displayKey,`:`]}),` `,e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]},`original-${e.key}`))})]}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`div`,{className:`text-[10px] text-muted-foreground mb-0.5`,children:`修改后`}),(0,v.jsx)(`div`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[220px] overflow-auto space-y-1`,children:r.map(e=>(0,v.jsxs)(`div`,{className:x(e.status,`modified`),children:[(0,v.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.displayKey,`:`]}),` `,e.modifiedValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]},`modified-${e.key}`))})]})]})}function Se(e){switch(e){case`generating`:return`AI 正在流式生成修复代码`;case`saving`:return`正在保存修复后的插件代码`;case`reloading`:return`正在热加载插件`;case`retesting`:return`正在重新执行插件测试`;default:return``}}function Ce({open:e=!1,onOpenChange:t,embedded:n=!1,plainHeading:i=!1,pluginId:y,pluginName:b,hooks:x,filename:Ce,onPluginFixed:we}){let[S,Te]=(0,_.useState)(!1),[C,w]=(0,_.useState)(!1),[T,Ee]=(0,_.useState)(`https://365.wps.cn/home`),[E,De]=(0,_.useState)(`GET`),[D,Oe]=(0,_.useState)(`standalone`),[O,k]=(0,_.useState)(null),[A,ke]=(0,_.useState)(`split`),[j,Ae]=(0,_.useState)(`inline`),[M,N]=(0,_.useState)(null),[P,F]=(0,_.useState)(``),[I,L]=(0,_.useState)(``),[R,je]=(0,_.useState)(!1),[z,B]=(0,_.useState)(null),[V,H]=(0,_.useState)(``),[Me,U]=(0,_.useState)(`normal`),[W,Ne]=(0,_.useState)(``),[G,K]=(0,_.useState)(`idle`),q=ae(),J=re(q),Pe=J?{provider:J.provider,apiKey:J.apiKey,baseUrl:J.baseUrl,model:J.model}:{provider:q.provider,apiKey:q.apiKey,baseUrl:q.baseUrl,model:q.model},Y=ie(q),X=Ce||de({id:y}),Z=n||e,Q=(0,_.useCallback)(async()=>{if(!X||!Z){F(``),L(``),B(null);return}je(!0),B(null);try{let e=await fetch(`/api/plugins/custom/${encodeURIComponent(X)}/code`);if(!e.ok){let t=await e.json();throw Error(t.error||`读取插件源码失败`)}let t=await e.json();F(t.code||``),!C&&!V&&L(t.code||``)}catch(e){F(``),L(``),B(e instanceof Error?e.message:`读取插件源码失败`)}finally{je(!1)}},[X,C,V,Z]);(0,_.useEffect)(()=>{Q()},[Q]);let $=(0,_.useMemo)(()=>{let e=[];return O?.error&&e.push({hookName:`test`,message:O.error}),Object.entries(O?.hookResults||{}).forEach(([t,n])=>{n?.status===`error`&&e.push({hookName:t,message:n.error||`未知错误`,stack:n.stack})}),O?.realRequest?.fetchError&&e.push({hookName:`fetch`,message:O.realRequest.fetchError}),e},[O]),Fe=$.length>0&&!!X,Ie=!!I&&!!(V||G===`idle`&&I&&P&&I!==P),Le=async(e,t,n)=>{K(`saving`);let r=await fetch(`/api/plugins/custom/${encodeURIComponent(X)}/code`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:e})});if(!r.ok){let e=await r.json();throw Error(e.error||`保存修复后的代码失败`)}K(`reloading`);let i=await fetch(`/api/plugins/reload`,{method:`POST`});if(!i.ok){let e=await i.json().catch(()=>({error:`热加载失败`}));throw Error(e.error||`热加载失败`)}F(e),H(e),U(`diff`),window.dispatchEvent(new CustomEvent(`plugins-custom-updated`)),we?.(),n&&(K(`retesting`),await Re()),N({status:`success`,message:t}),K(`idle`)},Re=async()=>{Te(!0),k(null),N(null);try{let e=await fetch(`/api/plugins/test`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pluginId:y,url:T,method:E,integrated:D===`integrated`})});if(!e.ok){let t=await e.json();throw Error(t.error||`测试失败`)}k((await e.json()).results)}catch(e){k({error:e instanceof Error?e.message:`测试失败`})}finally{Te(!1)}},ze=async()=>{if(!(!Fe||!Y)){w(!0),N(null),H(``),L(P);try{K(`generating`);let e={code:P};if(!e.code)throw Error(`插件源码为空,无法修复`);let t=$.map(e=>`Hook: ${e.hookName}\nError: ${e.message}${e.stack?`\nStack:\n${e.stack}`:``}`).join(`
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e,d as t,p as n,t as r,u as i}from"./button-BFNlGZ5p.js";import{t as a}from"./arrow-right-BNum_060.js";import{Et as o,Q as s,Z as c,l,ot as u,pt as d,xt as f}from"./index-
|
|
1
|
+
import{c as e,d as t,p as n,t as r,u as i}from"./button-BFNlGZ5p.js";import{t as a}from"./arrow-right-BNum_060.js";import{Et as o,Q as s,Z as c,l,ot as u,pt as d,xt as f}from"./index-CSXxaYkG.js";var p=i(`locate-fixed`,[[`line`,{x1:`2`,x2:`5`,y1:`12`,y2:`12`,key:`bvdh0s`}],[`line`,{x1:`19`,x2:`22`,y1:`12`,y2:`12`,key:`1tbv5k`}],[`line`,{x1:`12`,x2:`12`,y1:`2`,y2:`5`,key:`11lu5j`}],[`line`,{x1:`12`,x2:`12`,y1:`19`,y2:`22`,key:`x3vr5v`}],[`circle`,{cx:`12`,cy:`12`,r:`7`,key:`fim9np`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),m=n(t(),1),h=e();function g({rules:e,activeFileName:t,embedded:n=!1,onRevealRule:i}){let[g,_]=(0,m.useState)(``),[v,y]=(0,m.useState)(!1),[b,x]=(0,m.useState)(null),[S,C]=(0,m.useState)(null),w=(0,m.useMemo)(()=>l(e),[e]),T=n?`global-route-preview-url`:`route-preview-url`;(0,m.useEffect)(()=>{if(!n)return;let e=window.requestAnimationFrame(()=>{document.getElementById(T)?.focus()});return()=>window.cancelAnimationFrame(e)},[n,T]);let E=(0,m.useCallback)(async()=>{let e=g.trim();if(!e){C(`请输入待预览的 URL`),x(null);return}y(!0),C(null);try{let t=await fetch(`/api/rules/preview`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({url:e,rulesText:w})}),n=await t.json();if(!t.ok)throw Error(n?.error||`预览失败`);x(n)}catch(e){x(null),C(e instanceof Error?e.message:`预览失败`)}finally{y(!1)}},[g,w]),D=(0,m.useCallback)(e=>{e.key===`Enter`&&E()},[E]);return(0,h.jsxs)(`div`,{className:n?`app-panel-content h-full`:`rounded-lg border bg-card p-4 space-y-3`,children:[(0,h.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(d,{className:`h-4 w-4 text-primary`}),(0,h.jsx)(`h3`,{className:`text-sm font-semibold`,children:`URL 预览`})]}),(0,h.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`输入一个请求 URL,后端会用当前编辑中的规则直接计算真实转发地址。`})]}),t&&(0,h.jsxs)(c,{variant:`outline`,className:`text-[11px] font-normal`,children:[(0,h.jsx)(o,{className:`h-3 w-3 mr-1`}),t]})]}),(0,h.jsxs)(`div`,{className:`flex gap-2`,children:[(0,h.jsx)(s,{id:T,value:g,onChange:e=>_(e.target.value),onKeyDown:D,placeholder:`https://solution.wps.cn/docs/price/detail.html?source=navbar`,className:`h-9 font-mono text-xs`}),(0,h.jsx)(r,{onClick:E,disabled:v,className:`h-9 shrink-0`,children:v?(0,h.jsx)(f,{className:`h-4 w-4 animate-spin`}):`预览`})]}),n&&(0,h.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`使用当前编辑区内尚未保存的规则进行计算,结果会与路由规则页的预览保持一致。`}),S&&(0,h.jsx)(`div`,{className:`rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800`,children:(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(u,{className:`h-3.5 w-3.5 shrink-0`}),(0,h.jsx)(`span`,{children:S})]})}),b&&(0,h.jsxs)(`div`,{className:n?`min-h-0 flex-1 space-y-3 overflow-auto rounded-md border bg-muted/20 p-3`:`space-y-3 rounded-md border bg-muted/20 p-3`,children:[(0,h.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,h.jsx)(c,{className:b.matched?`bg-green-100 text-green-800 border-green-200`:`bg-blue-100 text-blue-800 border-blue-200`,children:b.matched?`已命中规则`:`未命中规则`}),b.matchedRule&&(0,h.jsx)(c,{variant:`outline`,className:`text-[11px] font-normal`,children:b.matchedRule.kind})]}),(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:`真实 URL`}),(0,h.jsx)(`div`,{className:`rounded-md border bg-background px-3 py-2 font-mono text-xs break-all`,children:b.resolvedUrl})]}),b.matchedRule&&(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:`命中规则`}),(0,h.jsxs)(`div`,{className:`flex items-stretch gap-2`,children:[(0,h.jsxs)(`div`,{className:`min-w-0 flex-1 rounded-md border bg-background px-3 py-2 font-mono text-xs break-all`,children:[b.matchedRule.pattern,(0,h.jsx)(`span`,{className:`text-muted-foreground`,children:` → `}),b.matchedRule.target]}),i&&(0,h.jsxs)(r,{type:`button`,variant:`outline`,size:`sm`,className:`h-auto shrink-0 gap-1.5 px-3 text-xs`,onClick:()=>b.matchedRule&&i(b.matchedRule),title:`在路由规则页面定位这条规则`,children:[(0,h.jsx)(p,{className:`h-3.5 w-3.5`}),`定位`]})]})]}),(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:`说明`}),(0,h.jsx)(`div`,{className:`space-y-1 rounded-md border bg-background px-3 py-2 text-xs`,children:b.notes.length>0?b.notes.map(e=>(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(a,{className:`h-3 w-3 text-muted-foreground shrink-0`}),(0,h.jsx)(`span`,{children:e})]},e)):(0,h.jsx)(`span`,{className:`text-muted-foreground`,children:`无`})})]})]})]})}export{g as RoutePreview};
|
package/web/dist/assets/{rule-ai-assistant-panel-DzfobTWM.js → rule-ai-assistant-panel-BvTqm4zV.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as e,d as t,p as n,t as r}from"./button-BFNlGZ5p.js";import{t as i}from"./wand-sparkles-Bmt4dDOf.js";import{i as a,o,r as s}from"./ai-config-store-C8D_PUGV.js";import{Z as c,c as l,dt as u,l as d,xt as f}from"./index-
|
|
1
|
+
import{c as e,d as t,p as n,t as r}from"./button-BFNlGZ5p.js";import{t as i}from"./wand-sparkles-Bmt4dDOf.js";import{i as a,o,r as s}from"./ai-config-store-C8D_PUGV.js";import{Z as c,c as l,dt as u,l as d,xt as f}from"./index-CSXxaYkG.js";import{n as p,t as m}from"./alert-B514Frte.js";import{t as h}from"./textarea-9wB8Hsz-.js";var g=n(t(),1);function _(e){return e.replace(/^```[a-z]*\n?/i,``).replace(/\n?```$/i,``).trim()}function v(){let e=s(),t=a(e);return t?{enabled:e.enabled,provider:t.provider,apiKey:t.apiKey,baseUrl:t.baseUrl,model:t.model}:e}function y(e,t){return{system:`你是 Meddle 的路由规则整理助手。你的任务是合并和精简用户的路由规则,在不改变语义的前提下尽量减少规则数量。
|
|
2
2
|
|
|
3
3
|
请严格遵守以下要求:
|
|
4
4
|
1. 只输出最终规则文本,不要输出解释、标题、Markdown 代码块或额外说明。
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as e,d as t,f as n,l as r,p as i,t as a,u as o}from"./button-BFNlGZ5p.js";import{c as s}from"./dist-CFZ4xMSF.js";import{t as c}from"./check-BkfHQ6re.js";import{n as l,t as u}from"./checkbox-CQyFsZzS.js";import{t as d}from"./plus-ixZQRprm.js";import{t as f}from"./table-2-DvGHhMm4.js";import{c as p}from"./dist-BQN0rzUS.js";import{a as m,c as h,i as g,n as _,o as v,r as y,s as b,t as x}from"./dist-DLQKRjuW.js";import"./es2015-DPJTBYa9.js";import{n as S}from"./toast-9yeTf7d9.js";import{Ct as C,D as w,E as T,I as E,M as D,O,Q as k,Tt as A,X as j,Y as M,Z as N,c as P,g as ee,h as F,j as te,k as I,l as ne,o as L,s as re,u as R,v as ie,xt as z}from"./index-
|
|
1
|
+
import{c as e,d as t,f as n,l as r,p as i,t as a,u as o}from"./button-BFNlGZ5p.js";import{c as s}from"./dist-CFZ4xMSF.js";import{t as c}from"./check-BkfHQ6re.js";import{n as l,t as u}from"./checkbox-CQyFsZzS.js";import{t as d}from"./plus-ixZQRprm.js";import{t as f}from"./table-2-DvGHhMm4.js";import{c as p}from"./dist-BQN0rzUS.js";import{a as m,c as h,i as g,n as _,o as v,r as y,s as b,t as x}from"./dist-DLQKRjuW.js";import"./es2015-DPJTBYa9.js";import{n as S}from"./toast-9yeTf7d9.js";import{Ct as C,D as w,E as T,I as E,M as D,O,Q as k,Tt as A,X as j,Y as M,Z as N,c as P,g as ee,h as F,j as te,k as I,l as ne,o as L,s as re,u as R,v as ie,xt as z}from"./index-CSXxaYkG.js";import{r as B}from"./syntax-highlight-BFgN_C0Y.js";import{a as ae,i as oe,n as se,o as ce,r as V,t as le}from"./table-DaXD6jJv.js";import{a as ue,i as de,n as fe,r as pe,t as me}from"./pane-bar-zJmE3xI5.js";import{n as he,r as ge,t as _e}from"./pane-split-CJ1VXJDy.js";var ve=o(`arrow-up-to-line`,[[`path`,{d:`M5 3h14`,key:`7usisc`}],[`path`,{d:`m18 13-6-6-6 6`,key:`1kf1n9`}],[`path`,{d:`M12 7v14`,key:`1akyts`}]]),ye=o(`clipboard-paste`,[[`path`,{d:`M11 14h10`,key:`1w8e9d`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v1.344`,key:`1e62lh`}],[`path`,{d:`m17 18 4-4-4-4`,key:`z2g111`}],[`path`,{d:`M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113`,key:`bjbb7m`}],[`rect`,{x:`8`,y:`2`,width:`8`,height:`4`,rx:`1`,key:`ublpy`}]]),be=o(`file-code-corner`,[[`path`,{d:`M4 12.15V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2h-3.35`,key:`1wthlu`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`m5 16-3 3 3 3`,key:`331omg`}],[`path`,{d:`m9 22 3-3-3-3`,key:`lsp7cz`}]]),xe=o(`folder-open`,[[`path`,{d:`m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2`,key:`usdka0`}]]),Se=o(`git-branch`,[[`line`,{x1:`6`,x2:`6`,y1:`3`,y2:`15`,key:`17qcm7`}],[`circle`,{cx:`18`,cy:`6`,r:`3`,key:`1h7g24`}],[`circle`,{cx:`6`,cy:`18`,r:`3`,key:`fqmcym`}],[`path`,{d:`M18 9a9 9 0 0 1-9 9`,key:`n2h4wq`}]]),Ce=o(`lock-open`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 9.9-1`,key:`1mm8w8`}]]),we=o(`lock`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`,key:`fwvmzm`}]]),Te=o(`toggle-left`,[[`circle`,{cx:`9`,cy:`12`,r:`3`,key:`u3jwor`}],[`rect`,{width:`20`,height:`14`,x:`2`,y:`5`,rx:`7`,key:`g7kal2`}]]),H=o(`toggle-right`,[[`circle`,{cx:`15`,cy:`12`,r:`3`,key:`1afu0r`}],[`rect`,{width:`20`,height:`14`,x:`2`,y:`5`,rx:`7`,key:`g7kal2`}]]),Ee=n((e=>{var n=t();function r(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var i=typeof Object.is==`function`?Object.is:r,a=n.useState,o=n.useEffect,s=n.useLayoutEffect,c=n.useDebugValue;function l(e,t){var n=t(),r=a({inst:{value:n,getSnapshot:t}}),i=r[0].inst,l=r[1];return s(function(){i.value=n,i.getSnapshot=t,u(i)&&l({inst:i})},[e,n,t]),o(function(){return u(i)&&l({inst:i}),e(function(){u(i)&&l({inst:i})})},[e]),c(n),n}function u(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!i(e,n)}catch{return!0}}function d(e,t){return t()}var f=typeof window>`u`||window.document===void 0||window.document.createElement===void 0?d:l;e.useSyncExternalStore=n.useSyncExternalStore===void 0?f:n.useSyncExternalStore})),De=n(((e,t)=>{t.exports=Ee()})),U=i(t()),W=e();function Oe({className:e,...t}){return(0,W.jsx)(z,{role:`status`,"aria-label":`Loading`,className:r(`size-4 animate-spin`,e),...t})}var ke=i(s());function Ae(){var e=[...arguments];return(0,U.useMemo)(()=>t=>{e.forEach(e=>e(t))},e)}var je=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0;function Me(e){let t=Object.prototype.toString.call(e);return t===`[object Window]`||t===`[object global]`}function Ne(e){return`nodeType`in e}function G(e){return e?Me(e)?e:Ne(e)?e.ownerDocument?.defaultView??window:window:window}function Pe(e){let{Document:t}=G(e);return e instanceof t}function Fe(e){return Me(e)?!1:e instanceof G(e).HTMLElement}function Ie(e){return e instanceof G(e).SVGElement}function Le(e){return e?Me(e)?e.document:Ne(e)?Pe(e)?e:Fe(e)||Ie(e)?e.ownerDocument:document:document:document}var Re=je?U.useLayoutEffect:U.useEffect;function ze(e){let t=(0,U.useRef)(e);return Re(()=>{t.current=e}),(0,U.useCallback)(function(){var e=[...arguments];return t.current==null?void 0:t.current(...e)},[])}function Be(){let e=(0,U.useRef)(null);return[(0,U.useCallback)((t,n)=>{e.current=setInterval(t,n)},[]),(0,U.useCallback)(()=>{e.current!==null&&(clearInterval(e.current),e.current=null)},[])]}function Ve(e,t){t===void 0&&(t=[e]);let n=(0,U.useRef)(e);return Re(()=>{n.current!==e&&(n.current=e)},t),n}function He(e,t){let n=(0,U.useRef)();return(0,U.useMemo)(()=>{let t=e(n.current);return n.current=t,t},[...t])}function Ue(e){let t=ze(e),n=(0,U.useRef)(null);return[n,(0,U.useCallback)(e=>{e!==n.current&&t?.(e,n.current),n.current=e},[])]}function We(e){let t=(0,U.useRef)();return(0,U.useEffect)(()=>{t.current=e},[e]),t.current}var Ge={};function Ke(e,t){return(0,U.useMemo)(()=>{if(t)return t;let n=Ge[e]==null?0:Ge[e]+1;return Ge[e]=n,e+`-`+n},[e,t])}function qe(e){return function(t){return[...arguments].slice(1).reduce((t,n)=>{let r=Object.entries(n);for(let[n,i]of r){let r=t[n];r!=null&&(t[n]=r+e*i)}return t},{...t})}}var Je=qe(1),Ye=qe(-1);function Xe(e){return`clientX`in e&&`clientY`in e}function Ze(e){if(!e)return!1;let{KeyboardEvent:t}=G(e.target);return t&&e instanceof t}function Qe(e){if(!e)return!1;let{TouchEvent:t}=G(e.target);return t&&e instanceof t}function $e(e){if(Qe(e)){if(e.touches&&e.touches.length){let{clientX:t,clientY:n}=e.touches[0];return{x:t,y:n}}else if(e.changedTouches&&e.changedTouches.length){let{clientX:t,clientY:n}=e.changedTouches[0];return{x:t,y:n}}}return Xe(e)?{x:e.clientX,y:e.clientY}:null}var et=Object.freeze({Translate:{toString(e){if(!e)return;let{x:t,y:n}=e;return`translate3d(`+(t?Math.round(t):0)+`px, `+(n?Math.round(n):0)+`px, 0)`}},Scale:{toString(e){if(!e)return;let{scaleX:t,scaleY:n}=e;return`scaleX(`+t+`) scaleY(`+n+`)`}},Transform:{toString(e){if(e)return[et.Translate.toString(e),et.Scale.toString(e)].join(` `)}},Transition:{toString(e){let{property:t,duration:n,easing:r}=e;return t+` `+n+`ms `+r}}}),tt=`a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]`;function nt(e){return e.matches(tt)?e:e.querySelector(tt)}var rt={display:`none`};function it(e){let{id:t,value:n}=e;return U.createElement(`div`,{id:t,style:rt},n)}function at(e){let{id:t,announcement:n,ariaLiveType:r=`assertive`}=e;return U.createElement(`div`,{id:t,style:{position:`fixed`,top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:`hidden`,clip:`rect(0 0 0 0)`,clipPath:`inset(100%)`,whiteSpace:`nowrap`},role:`status`,"aria-live":r,"aria-atomic":!0},n)}function ot(){let[e,t]=(0,U.useState)(``);return{announce:(0,U.useCallback)(e=>{e!=null&&t(e)},[]),announcement:e}}var st=(0,U.createContext)(null);function ct(e){let t=(0,U.useContext)(st);(0,U.useEffect)(()=>{if(!t)throw Error(`useDndMonitor must be used within a children of <DndContext>`);return t(e)},[e,t])}function lt(){let[e]=(0,U.useState)(()=>new Set),t=(0,U.useCallback)(t=>(e.add(t),()=>e.delete(t)),[e]);return[(0,U.useCallback)(t=>{let{type:n,event:r}=t;e.forEach(e=>e[n]?.call(e,r))},[e]),t]}var ut={draggable:`
|
|
2
2
|
To pick up a draggable item, press the space bar.
|
|
3
3
|
While dragging, use the arrow keys to move the item.
|
|
4
4
|
Press space again to drop the item in its new position, or press escape to cancel.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e,d as t,p as n,t as r}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as i}from"./refresh-cw-BfLoHqg5.js";import{t as ee}from"./table-2-DvGHhMm4.js";import{$ as a,B as o,H as s,I as c,L as l,Q as u,R as d,St as f,V as p,X as m,Y as te,Z as h,_t as g,l as _,ot as v,pt as y,z as b}from"./index-Dcm171u1.js";import{a as x,i as S,n as C,o as w,r as T,t as E}from"./table-DaXD6jJv.js";var D=n(t(),1),O=e(),k=`border-l-2 border-l-transparent`,A=`text-muted-foreground opacity-75`;function j(e){return e.length>0?e.map(e=>`!${e}`).join(` `):`—`}function M({rules:e,activeFileName:t,onLocateRule:n,onSelectFile:M}){let[N,ne]=(0,D.useState)(null),[P,F]=(0,D.useState)(!0),[I,L]=(0,D.useState)(null),[R,z]=(0,D.useState)(`merged`),[B,V]=(0,D.useState)(``),H=(0,D.useDeferredValue)(B),U=(0,D.useCallback)(async()=>{F(!0),L(null);try{let e=await fetch(`/api/rule-files/overview`);if(!e.ok)throw Error(`加载失败(${e.status})`);ne(await e.json())}catch(e){L(e instanceof Error?e.message:`加载失败`)}finally{F(!1)}},[]);(0,D.useEffect)(()=>{U()},[U]);let W=(0,D.useMemo)(()=>N?.perFileRules.find(e=>e.name===t)??null,[N,t]),G=(0,D.useMemo)(()=>{if(!W||W.error)return!1;let t=W.rules.map(e=>({rule:e.rawRule,target:e.rawTarget,enabled:e.enabled,exclusions:e.exclusions}));return _(e)!==_(t)},[W,e]),K=(0,D.useMemo)(()=>{let e=new Map;for(let t of N?.conflicts??[])e.set(t.pattern,t);return e},[N]),q=(0,D.useCallback)(e=>{let t=H.trim().toLowerCase();return t?e.some(e=>e&&e.toLowerCase().includes(t)):!0},[H]),J=(0,D.useMemo)(()=>(N?.mergedRules??[]).map(e=>({winner:e,shadowed:K.get(e.pattern)?.shadowed??[]})).filter(({winner:e,shadowed:t})=>q([e.rawRule,e.rawTarget,e.file])||t.some(e=>q([e.rawRule,e.rawTarget,e.file]))),[N,K,q]),Y=N?.mergedRules.length??0,X=N?.conflicts.reduce((e,t)=>e+t.shadowed.length,0)??0,Z=(0,D.useMemo)(()=>(N?.perFileRules??[]).map(e=>({...e,matched:e.rules.filter(t=>q([t.rawRule,t.rawTarget,e.name]))})).filter(e=>e.error!=null||q([e.name])||e.matched.length>0),[N,q]),re=N?.perFileRules.reduce((e,t)=>e+t.rules.length,0)??0,ie=Z.reduce((e,t)=>e+t.matched.length,0),Q=(0,D.useCallback)((e,t,r)=>{n(e,t,r)},[n]),ae=(0,D.useCallback)((e,t)=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),M(t))},[M]),oe=()=>{if(P)return(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-2 p-2`,children:[(0,O.jsx)(a,{className:`h-8 w-full`}),(0,O.jsx)(a,{className:`h-8 w-full`}),(0,O.jsx)(a,{className:`h-8 w-3/4`})]});if(I)return(0,O.jsxs)(l,{className:`min-h-0 flex-1`,children:[(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(v,{})}),(0,O.jsx)(s,{children:`加载失败`}),(0,O.jsx)(b,{children:I})]}),(0,O.jsx)(d,{children:(0,O.jsxs)(r,{variant:`outline`,onClick:()=>void U(),children:[(0,O.jsx)(i,{"data-icon":`inline-start`}),`重试`]})})]});let e=(N?.files.length??0)>0,t=N?.perFileRules.some(e=>e.rules.length>0||e.error!=null)??!1,n=H.trim().length>0;return e?t?R===`merged`&&!n&&(N?.mergedRules.length??0)===0?(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(g,{})}),(0,O.jsx)(s,{children:`没有生效中的规则`}),(0,O.jsx)(b,{children:`规则全部被禁用,或没有启用任何规则文件;切换到「按文件」查看全部规则`})]})}):n&&R===`merged`&&J.length===0||n&&R===`files`&&Z.every(e=>e.matched.length===0&&e.error==null)?$():R===`merged`?se():ce():(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(f,{})}),(0,O.jsx)(s,{children:`所有规则文件都是空的`}),(0,O.jsx)(b,{children:`还没有任何路由规则,先去路由规则页添加一条吧`})]})}):(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(ee,{})}),(0,O.jsx)(s,{children:`还没有规则文件`}),(0,O.jsx)(b,{children:`在路由规则页点击「+」创建第一个规则文件`})]})})},$=()=>(0,O.jsxs)(l,{className:`min-h-0 flex-1`,children:[(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(y,{})}),(0,O.jsx)(s,{children:`无匹配结果`}),(0,O.jsxs)(b,{children:[`没有找到符合「`,H.trim(),`」的规则`]})]}),(0,O.jsx)(d,{children:(0,O.jsx)(r,{variant:`outline`,onClick:()=>V(``),children:`清空筛选`})})]}),se=()=>(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border`,children:[(0,O.jsx)(`div`,{className:`meddle-thin-scroll shrink-0 overflow-x-auto bg-card`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`6rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(x,{children:(0,O.jsxs)(w,{children:[(0,O.jsx)(S,{children:`来源`}),(0,O.jsx)(S,{children:`规则`}),(0,O.jsx)(S,{className:`hidden md:table-cell`,children:`排除`}),(0,O.jsx)(S,{children:`目标`})]})})]})}),(0,O.jsx)(c,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`6rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(C,{children:J.map(({winner:e,shadowed:t})=>(0,O.jsxs)(D.Fragment,{children:[(0,O.jsxs)(w,{className:`${k} cursor-pointer`,onClick:()=>Q(e.file,e.rawRule,e.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{className:`truncate text-xs text-muted-foreground`,children:e.file}),(0,O.jsxs)(T,{className:`break-all font-mono text-xs`,children:[e.rawRule,t.length>0&&(0,O.jsx)(h,{variant:`default`,className:`ml-2 px-1 py-0 text-[10px]`,title:`同名规则最终生效的定义`,children:`生效`})]}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs text-muted-foreground md:table-cell`,children:j(e.exclusions)}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:e.rawTarget})]}),t.map((t,n)=>(0,O.jsxs)(w,{className:`${k} cursor-pointer ${A}`,onClick:()=>Q(t.file,t.rawRule,t.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{className:`truncate text-xs`,children:t.file}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:(0,O.jsxs)(`span`,{className:`inline-flex flex-wrap items-center gap-1.5`,children:[t.rawRule,(0,O.jsx)(h,{variant:`destructive`,className:`px-1 py-0 text-[10px]`,title:`已被 ${e.file} 中的同名规则覆盖,实际不生效`,children:`已被覆盖`})]})}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs md:table-cell`,children:`—`}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:t.rawTarget})]},`merged-shadowed-${n}`))]},`merged-group-${e.pattern}`))})]})})]}),ce=()=>(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border`,children:[(0,O.jsx)(`div`,{className:`meddle-thin-scroll shrink-0 overflow-x-auto bg-card`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`3.5rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(x,{children:(0,O.jsxs)(w,{children:[(0,O.jsx)(S,{children:`状态`}),(0,O.jsx)(S,{children:`规则`}),(0,O.jsx)(S,{className:`hidden md:table-cell`,children:`排除`}),(0,O.jsx)(S,{children:`目标`})]})})]})}),(0,O.jsx)(c,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`3.5rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(C,{children:Z.map(e=>(0,O.jsxs)(D.Fragment,{children:[(0,O.jsx)(w,{className:`hover:bg-accent/60`,children:(0,O.jsx)(T,{colSpan:4,className:`cursor-pointer bg-muted/50 p-2 align-middle`,role:`button`,tabIndex:0,onClick:()=>M(e.name),onKeyDown:t=>ae(t,e.name),title:`点击切换到该规则文件`,children:(0,O.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 font-medium`,children:[e.name,(0,O.jsx)(h,{variant:e.enabled?`default`:`secondary`,className:`px-1 py-0 text-[10px]`,children:e.enabled?`启用`:`禁用`}),(0,O.jsx)(h,{variant:`secondary`,className:`px-1 py-0 text-[10px]`,children:e.rules.length})]})})}),e.error&&(0,O.jsx)(w,{className:`text-destructive`,children:(0,O.jsx)(T,{colSpan:4,className:`p-2 text-xs`,children:(0,O.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,O.jsx)(v,{className:`h-3.5 w-3.5 shrink-0`}),`读取失败:`,e.error]})})}),e.matched.map((t,n)=>(0,O.jsxs)(w,{className:`cursor-pointer ${t.enabled?``:`opacity-60`}`,onClick:()=>Q(e.name,t.rawRule,t.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{children:(0,O.jsx)(h,{variant:t.enabled?`default`:`secondary`,className:`px-1 py-0 text-[10px]`,children:t.enabled?`启用`:`禁用`})}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:t.rawRule}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs text-muted-foreground md:table-cell`,children:j(t.exclusions)}),(0,O.jsx)(T,{className:`break-all font-mono text-xs ${t.enabled?``:`line-through`}`,children:t.rawTarget})]},`file-rule-${n}`))]},`file-group-${e.name}`))})]})})]}),le=R===`merged`?Y+X:re,ue=R===`merged`?J.reduce((e,t)=>e+1+t.shadowed.length,0):ie;return(0,O.jsxs)(`div`,{className:`app-panel-content flex h-full flex-col gap-3`,children:[(0,O.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,O.jsxs)(te,{type:`single`,value:R,onValueChange:e=>{e&&z(e)},variant:`outline`,size:`sm`,className:`bg-background`,"aria-label":`总览视图`,children:[(0,O.jsx)(m,{value:`merged`,children:`生效规则`}),(0,O.jsx)(m,{value:`files`,children:`按文件`})]}),(0,O.jsxs)(`div`,{className:`relative min-w-40 flex-1`,children:[(0,O.jsx)(y,{className:`pointer-events-none absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2 text-muted-foreground`}),(0,O.jsx)(u,{value:B,onChange:e=>V(e.target.value),placeholder:`搜索规则 / 目标 / 文件名`,className:`h-8 pl-8`,"aria-label":`搜索规则`})]}),(0,O.jsx)(r,{type:`button`,variant:`ghost`,size:`icon-sm`,onClick:()=>void U(),disabled:P,"aria-label":`刷新总览`,title:`刷新`,children:(0,O.jsx)(i,{})})]}),G&&(0,O.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800`,children:[(0,O.jsx)(v,{className:`h-3.5 w-3.5 shrink-0`}),(0,O.jsxs)(`span`,{children:[`「`,t,`」有未保存修改,此处展示的是代理当前使用的`,(0,O.jsx)(`b`,{children:`已保存内容`})]})]}),!P&&!I&&(N?.files.length??0)>0&&(0,O.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 text-xs text-muted-foreground`,children:[(0,O.jsxs)(`span`,{children:[ue,` / `,le,` 条`,R===`merged`&&H.trim()===``&&X>0?`,其中 ${X} 条被同名规则覆盖`:``]}),R===`merged`&&(0,O.jsx)(`span`,{children:`按代理实际生效顺序排列(后定义覆盖先定义)`}),R===`files`&&(0,O.jsx)(`span`,{children:`点击文件名切换到该文件`})]}),oe()]})}export{M as RuleOverviewPanel};
|
|
1
|
+
import{c as e,d as t,p as n,t as r}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as i}from"./refresh-cw-BfLoHqg5.js";import{t as ee}from"./table-2-DvGHhMm4.js";import{$ as a,B as o,H as s,I as c,L as l,Q as u,R as d,St as f,V as p,X as m,Y as te,Z as h,_t as g,l as _,ot as v,pt as y,z as b}from"./index-CSXxaYkG.js";import{a as x,i as S,n as C,o as w,r as T,t as E}from"./table-DaXD6jJv.js";var D=n(t(),1),O=e(),k=`border-l-2 border-l-transparent`,A=`text-muted-foreground opacity-75`;function j(e){return e.length>0?e.map(e=>`!${e}`).join(` `):`—`}function M({rules:e,activeFileName:t,onLocateRule:n,onSelectFile:M}){let[N,ne]=(0,D.useState)(null),[P,F]=(0,D.useState)(!0),[I,L]=(0,D.useState)(null),[R,z]=(0,D.useState)(`merged`),[B,V]=(0,D.useState)(``),H=(0,D.useDeferredValue)(B),U=(0,D.useCallback)(async()=>{F(!0),L(null);try{let e=await fetch(`/api/rule-files/overview`);if(!e.ok)throw Error(`加载失败(${e.status})`);ne(await e.json())}catch(e){L(e instanceof Error?e.message:`加载失败`)}finally{F(!1)}},[]);(0,D.useEffect)(()=>{U()},[U]);let W=(0,D.useMemo)(()=>N?.perFileRules.find(e=>e.name===t)??null,[N,t]),G=(0,D.useMemo)(()=>{if(!W||W.error)return!1;let t=W.rules.map(e=>({rule:e.rawRule,target:e.rawTarget,enabled:e.enabled,exclusions:e.exclusions}));return _(e)!==_(t)},[W,e]),K=(0,D.useMemo)(()=>{let e=new Map;for(let t of N?.conflicts??[])e.set(t.pattern,t);return e},[N]),q=(0,D.useCallback)(e=>{let t=H.trim().toLowerCase();return t?e.some(e=>e&&e.toLowerCase().includes(t)):!0},[H]),J=(0,D.useMemo)(()=>(N?.mergedRules??[]).map(e=>({winner:e,shadowed:K.get(e.pattern)?.shadowed??[]})).filter(({winner:e,shadowed:t})=>q([e.rawRule,e.rawTarget,e.file])||t.some(e=>q([e.rawRule,e.rawTarget,e.file]))),[N,K,q]),Y=N?.mergedRules.length??0,X=N?.conflicts.reduce((e,t)=>e+t.shadowed.length,0)??0,Z=(0,D.useMemo)(()=>(N?.perFileRules??[]).map(e=>({...e,matched:e.rules.filter(t=>q([t.rawRule,t.rawTarget,e.name]))})).filter(e=>e.error!=null||q([e.name])||e.matched.length>0),[N,q]),re=N?.perFileRules.reduce((e,t)=>e+t.rules.length,0)??0,ie=Z.reduce((e,t)=>e+t.matched.length,0),Q=(0,D.useCallback)((e,t,r)=>{n(e,t,r)},[n]),ae=(0,D.useCallback)((e,t)=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),M(t))},[M]),oe=()=>{if(P)return(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-2 p-2`,children:[(0,O.jsx)(a,{className:`h-8 w-full`}),(0,O.jsx)(a,{className:`h-8 w-full`}),(0,O.jsx)(a,{className:`h-8 w-3/4`})]});if(I)return(0,O.jsxs)(l,{className:`min-h-0 flex-1`,children:[(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(v,{})}),(0,O.jsx)(s,{children:`加载失败`}),(0,O.jsx)(b,{children:I})]}),(0,O.jsx)(d,{children:(0,O.jsxs)(r,{variant:`outline`,onClick:()=>void U(),children:[(0,O.jsx)(i,{"data-icon":`inline-start`}),`重试`]})})]});let e=(N?.files.length??0)>0,t=N?.perFileRules.some(e=>e.rules.length>0||e.error!=null)??!1,n=H.trim().length>0;return e?t?R===`merged`&&!n&&(N?.mergedRules.length??0)===0?(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(g,{})}),(0,O.jsx)(s,{children:`没有生效中的规则`}),(0,O.jsx)(b,{children:`规则全部被禁用,或没有启用任何规则文件;切换到「按文件」查看全部规则`})]})}):n&&R===`merged`&&J.length===0||n&&R===`files`&&Z.every(e=>e.matched.length===0&&e.error==null)?$():R===`merged`?se():ce():(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(f,{})}),(0,O.jsx)(s,{children:`所有规则文件都是空的`}),(0,O.jsx)(b,{children:`还没有任何路由规则,先去路由规则页添加一条吧`})]})}):(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(ee,{})}),(0,O.jsx)(s,{children:`还没有规则文件`}),(0,O.jsx)(b,{children:`在路由规则页点击「+」创建第一个规则文件`})]})})},$=()=>(0,O.jsxs)(l,{className:`min-h-0 flex-1`,children:[(0,O.jsxs)(o,{children:[(0,O.jsx)(p,{variant:`icon`,children:(0,O.jsx)(y,{})}),(0,O.jsx)(s,{children:`无匹配结果`}),(0,O.jsxs)(b,{children:[`没有找到符合「`,H.trim(),`」的规则`]})]}),(0,O.jsx)(d,{children:(0,O.jsx)(r,{variant:`outline`,onClick:()=>V(``),children:`清空筛选`})})]}),se=()=>(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border`,children:[(0,O.jsx)(`div`,{className:`meddle-thin-scroll shrink-0 overflow-x-auto bg-card`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`6rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(x,{children:(0,O.jsxs)(w,{children:[(0,O.jsx)(S,{children:`来源`}),(0,O.jsx)(S,{children:`规则`}),(0,O.jsx)(S,{className:`hidden md:table-cell`,children:`排除`}),(0,O.jsx)(S,{children:`目标`})]})})]})}),(0,O.jsx)(c,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`6rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(C,{children:J.map(({winner:e,shadowed:t})=>(0,O.jsxs)(D.Fragment,{children:[(0,O.jsxs)(w,{className:`${k} cursor-pointer`,onClick:()=>Q(e.file,e.rawRule,e.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{className:`truncate text-xs text-muted-foreground`,children:e.file}),(0,O.jsxs)(T,{className:`break-all font-mono text-xs`,children:[e.rawRule,t.length>0&&(0,O.jsx)(h,{variant:`default`,className:`ml-2 px-1 py-0 text-[10px]`,title:`同名规则最终生效的定义`,children:`生效`})]}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs text-muted-foreground md:table-cell`,children:j(e.exclusions)}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:e.rawTarget})]}),t.map((t,n)=>(0,O.jsxs)(w,{className:`${k} cursor-pointer ${A}`,onClick:()=>Q(t.file,t.rawRule,t.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{className:`truncate text-xs`,children:t.file}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:(0,O.jsxs)(`span`,{className:`inline-flex flex-wrap items-center gap-1.5`,children:[t.rawRule,(0,O.jsx)(h,{variant:`destructive`,className:`px-1 py-0 text-[10px]`,title:`已被 ${e.file} 中的同名规则覆盖,实际不生效`,children:`已被覆盖`})]})}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs md:table-cell`,children:`—`}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:t.rawTarget})]},`merged-shadowed-${n}`))]},`merged-group-${e.pattern}`))})]})})]}),ce=()=>(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border`,children:[(0,O.jsx)(`div`,{className:`meddle-thin-scroll shrink-0 overflow-x-auto bg-card`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`3.5rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(x,{children:(0,O.jsxs)(w,{children:[(0,O.jsx)(S,{children:`状态`}),(0,O.jsx)(S,{children:`规则`}),(0,O.jsx)(S,{className:`hidden md:table-cell`,children:`排除`}),(0,O.jsx)(S,{children:`目标`})]})})]})}),(0,O.jsx)(c,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`3.5rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(C,{children:Z.map(e=>(0,O.jsxs)(D.Fragment,{children:[(0,O.jsx)(w,{className:`hover:bg-accent/60`,children:(0,O.jsx)(T,{colSpan:4,className:`cursor-pointer bg-muted/50 p-2 align-middle`,role:`button`,tabIndex:0,onClick:()=>M(e.name),onKeyDown:t=>ae(t,e.name),title:`点击切换到该规则文件`,children:(0,O.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 font-medium`,children:[e.name,(0,O.jsx)(h,{variant:e.enabled?`default`:`secondary`,className:`px-1 py-0 text-[10px]`,children:e.enabled?`启用`:`禁用`}),(0,O.jsx)(h,{variant:`secondary`,className:`px-1 py-0 text-[10px]`,children:e.rules.length})]})})}),e.error&&(0,O.jsx)(w,{className:`text-destructive`,children:(0,O.jsx)(T,{colSpan:4,className:`p-2 text-xs`,children:(0,O.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,O.jsx)(v,{className:`h-3.5 w-3.5 shrink-0`}),`读取失败:`,e.error]})})}),e.matched.map((t,n)=>(0,O.jsxs)(w,{className:`cursor-pointer ${t.enabled?``:`opacity-60`}`,onClick:()=>Q(e.name,t.rawRule,t.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{children:(0,O.jsx)(h,{variant:t.enabled?`default`:`secondary`,className:`px-1 py-0 text-[10px]`,children:t.enabled?`启用`:`禁用`})}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:t.rawRule}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs text-muted-foreground md:table-cell`,children:j(t.exclusions)}),(0,O.jsx)(T,{className:`break-all font-mono text-xs ${t.enabled?``:`line-through`}`,children:t.rawTarget})]},`file-rule-${n}`))]},`file-group-${e.name}`))})]})})]}),le=R===`merged`?Y+X:re,ue=R===`merged`?J.reduce((e,t)=>e+1+t.shadowed.length,0):ie;return(0,O.jsxs)(`div`,{className:`app-panel-content flex h-full flex-col gap-3`,children:[(0,O.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,O.jsxs)(te,{type:`single`,value:R,onValueChange:e=>{e&&z(e)},variant:`outline`,size:`sm`,className:`bg-background`,"aria-label":`总览视图`,children:[(0,O.jsx)(m,{value:`merged`,children:`生效规则`}),(0,O.jsx)(m,{value:`files`,children:`按文件`})]}),(0,O.jsxs)(`div`,{className:`relative min-w-40 flex-1`,children:[(0,O.jsx)(y,{className:`pointer-events-none absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2 text-muted-foreground`}),(0,O.jsx)(u,{value:B,onChange:e=>V(e.target.value),placeholder:`搜索规则 / 目标 / 文件名`,className:`h-8 pl-8`,"aria-label":`搜索规则`})]}),(0,O.jsx)(r,{type:`button`,variant:`ghost`,size:`icon-sm`,onClick:()=>void U(),disabled:P,"aria-label":`刷新总览`,title:`刷新`,children:(0,O.jsx)(i,{})})]}),G&&(0,O.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800`,children:[(0,O.jsx)(v,{className:`h-3.5 w-3.5 shrink-0`}),(0,O.jsxs)(`span`,{children:[`「`,t,`」有未保存修改,此处展示的是代理当前使用的`,(0,O.jsx)(`b`,{children:`已保存内容`})]})]}),!P&&!I&&(N?.files.length??0)>0&&(0,O.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 text-xs text-muted-foreground`,children:[(0,O.jsxs)(`span`,{children:[ue,` / `,le,` 条`,R===`merged`&&H.trim()===``&&X>0?`,其中 ${X} 条被同名规则覆盖`:``]}),R===`merged`&&(0,O.jsx)(`span`,{children:`按代理实际生效顺序排列(后定义覆盖先定义)`}),R===`files`&&(0,O.jsx)(`span`,{children:`点击文件名切换到该文件`})]}),oe()]})}export{M as RuleOverviewPanel};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e,d as t,p as n,t as r,u as i}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as ee}from"./check-BkfHQ6re.js";import{t as a}from"./circle-alert-zMagrFuI.js";import{t as o}from"./circle-x-BEkinhez.js";import{t as s}from"./plus-ixZQRprm.js";import{t as te}from"./refresh-cw-BfLoHqg5.js";import{t as ne}from"./rotate-ccw-CRguJya4.js";import{t as re}from"./smartphone-D4Q7cQfm.js";import{c as ie}from"./dist-BQN0rzUS.js";import"./es2015-DPJTBYa9.js";import{t as ae}from"./switch-94vgsMHm.js";import{a as c,c as oe,l as se,n as ce,o as l,r as u,s as le,t as ue}from"./ai-config-store-C8D_PUGV.js";import{n as d}from"./toast-9yeTf7d9.js";import{a as de,i as fe,n as pe,o as me,r as he}from"./use-mocks-file-status-BUIUJ4oQ.js";import{A as f,C as ge,Et as p,G as _e,J as ve,K as m,M as h,Q as g,S as ye,T as _,U as be,W as xe,X as v,Y as y,Z as Se,_ as Ce,b as we,bt as Te,d as Ee,dt as De,f as Oe,ft as ke,g as Ae,h as je,j as Me,k as Ne,kt as b,lt as Pe,m as x,mt as Fe,p as Ie,q as Le,w as Re,x as ze,y as S,yt as Be}from"./index-Dcm171u1.js";import{n as Ve,r as He,t as Ue}from"./alert-B514Frte.js";import{n as We}from"./pane-bar-Dvi-MHuB.js";import{i as Ge,o as Ke,r as qe,t as Je}from"./mocks-file-missing-note-C-QJ8Bpm.js";var Ye=i(`eye-off`,[[`path`,{d:`M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49`,key:`ct8e1f`}],[`path`,{d:`M14.084 14.158a3 3 0 0 1-4.242-4.242`,key:`151rxh`}],[`path`,{d:`M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143`,key:`13bj9a`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]),Xe=i(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),Ze=i(`stethoscope`,[[`path`,{d:`M11 2v2`,key:`1539x4`}],[`path`,{d:`M5 2v2`,key:`1yf1q8`}],[`path`,{d:`M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1`,key:`rb5t3r`}],[`path`,{d:`M8 15a6 6 0 0 0 12 0v-3`,key:`x18d4x`}],[`circle`,{cx:`20`,cy:`10`,r:`2`,key:`ts1r5v`}]]),C=n(t(),1),w={version:null,routeRulesDir:null,routeRulesDirDisplay:null};function T(e){return typeof e==`string`&&e.trim()||null}function Qe(e){if(!e||typeof e!=`object`||Array.isArray(e))return{...w};let t=e;return{version:T(t.version),routeRulesDir:T(t.routeRulesDir),routeRulesDirDisplay:T(t.routeRulesDirDisplay)}}async function $e(){try{let e=await fetch(`/api/version`);return e.ok?Qe(await e.json()):{...w}}catch{return{...w}}}var E=e(),et=[{value:`75`,label:`75%`,scale:.75},{value:`90`,label:`90%`,scale:.9},{value:`100`,label:`100%`,scale:1},{value:`110`,label:`110%`,scale:1.1},{value:`125`,label:`125%`,scale:1.25},{value:`150`,label:`150%`,scale:1.5}],tt=[{value:`auto`,label:`自动`,color:`linear-gradient(135deg, oklch(0.623 0.214 259.815), oklch(0.606 0.25 292.717))`},{value:`neutral`,label:`中性`,color:`oklch(0.556 0 0)`},{value:`blue`,label:`蓝色`,color:`oklch(0.623 0.214 259.815)`},{value:`violet`,label:`紫色`,color:`oklch(0.606 0.25 292.717)`},{value:`green`,label:`绿色`,color:`oklch(0.627 0.194 149.214)`},{value:`orange`,label:`橙色`,color:`oklch(0.646 0.222 41.116)`},{value:`rose`,label:`玫红`,color:`oklch(0.645 0.246 16.439)`}],D=`app-panel-content mt-0`,O=`app-field-group`,k=`app-section`,nt=`$MEDDLE_HOME/route-rules/`,A=e=>{if(!e)return`100`;let t={small:`90`,medium:`100`,large:`110`};return e in t?t[e]:et.some(t=>t.value===e)?e:`100`};function j({open:e=!1,onOpenChange:t,embedded:n=!1}){let{theme:i,accentColor:w,setTheme:T,setAccentColor:Qe,setZoom:j}=Ee(),[M,rt]=(0,C.useState)(`preferences`),[N,P]=(0,C.useState)(()=>u()),[F,it]=(0,C.useState)(!1),[I,L]=(0,C.useState)(!1),[R,z]=(0,C.useState)(null),[at,B]=(0,C.useState)(``),[V,H]=(0,C.useState)(null),[U,W]=(0,C.useState)(``),{status:G,refresh:K}=me(),[ot,st]=(0,C.useState)([]),[q,J]=(0,C.useState)({}),[Y,ct]=(0,C.useState)(``),[X,lt]=(0,C.useState)(``),[Z,ut]=(0,C.useState)(null),[dt,ft]=(0,C.useState)(!1),[pt,mt]=(0,C.useState)(null),[ht,gt]=(0,C.useState)(null);(0,C.useEffect)(()=>{let e=!1;return $e().then(t=>{if(e)return;mt(t.version);let n=t.routeRulesDirDisplay||t.routeRulesDir;n&>({display:n,path:t.routeRulesDir})}),()=>{e=!0}},[]);let _t=ht?.display??nt,[Q,vt]=(0,C.useState)(()=>A(Oe().fontSize)),[yt,bt]=(0,C.useState)(!1);(0,C.useEffect)(()=>{Ie().then(e=>{let t=A(e.fontSize);vt(t),j(parseInt(t,10)/100),bt(!0)}).catch(()=>{bt(!0)})},[j]),(0,C.useEffect)(()=>{if(!yt)return;let e=A(Q);j(parseInt(e,10)/100),x({fontSize:e}).catch(console.error)},[j,yt,Q]),(0,C.useEffect)(()=>{(e||n)&&(Ie().then(e=>{P(e.aiConfig),W(e.mocksFilePath||``),J(e.clientAliases||{})}).catch(()=>{P(u())}),z(null),B(``),fetch(`/api/rule-files`).then(e=>e.json()).then(e=>{Array.isArray(e)&&st(e)}).catch(()=>{}))},[e,n]);let xt=e=>{let t=c(e);P({...N,provider:e,baseUrl:t.baseUrl,model:t.model})},$=async()=>{L(!0);try{await x({aiConfig:N}),oe(N),z(`success`),B(`AI 配置保存成功`),d.success(`AI 配置保存成功`)}catch(e){let t=e instanceof Error?e.message:`保存失败`;z(`error`),B(t),d.error(t)}finally{L(!1)}},St=()=>{le(),P(u()),z(null),B(``)},Ct=async()=>{if(!l(N)){z(`error`),B(`请填写完整的配置信息`);return}L(!0),z(null),B(`测试中…`);try{let e=N.baseUrl,t={"Content-Type":`application/json`},n;N.provider===`anthropic`?(t[`x-api-key`]=N.apiKey,t[`anthropic-version`]=`2023-06-01`,n={model:N.model,max_tokens:100,system:`You are a helpful assistant.`,messages:[{role:`user`,content:`Say "test successful"`}],temperature:.3}):(t.Authorization=`Bearer ${N.apiKey}`,n={model:N.model,messages:[{role:`system`,content:`You are a helpful assistant.`},{role:`user`,content:`Say "test successful"`}],temperature:.3,max_tokens:100});let r=await fetch(e,{method:`POST`,headers:t,body:JSON.stringify(n)});if(!r.ok){let e=await r.text();throw Error(`API错误 (${r.status}): ${e}`)}let i=await r.json();if(N.provider===`anthropic`){if(!i.content?.[0]?.text)throw Error(`API响应格式不正确`)}else if(!i.choices?.[0]?.message?.content)throw Error(`API响应格式不正确`);z(`success`),B(`连接测试成功! API配置正常`)}catch(e){z(`error`),B(e instanceof Error?e.message:`测试失败`)}finally{L(!1)}},wt=(0,C.useCallback)(async()=>{try{let e=await fetch(`/api/refresh-config`,{method:`POST`});if(e.ok){let t=await e.json();K(),z(`success`),B(t.message||`配置已刷新`),setTimeout(()=>{z(null),B(``)},2e3)}else{let t=await e.json();z(`error`),B(t.error||`刷新配置失败`),setTimeout(()=>{z(null),B(``)},2e3)}}catch(e){console.error(`刷新配置失败:`,e),z(`error`),B(`刷新配置失败`),setTimeout(()=>{z(null),B(``)},2e3)}},[K]),Tt=(0,C.useCallback)(async()=>{ft(!0),ut(null);try{let e=await fetch(`/api/config-doctor`);e.ok?ut(await e.json()):(z(`error`),B(`诊断失败`),setTimeout(()=>{z(null),B(``)},2e3))}catch(e){console.error(`诊断失败:`,e),z(`error`),B(`诊断失败`),setTimeout(()=>{z(null),B(``)},2e3)}finally{ft(!1)}},[]),Et=()=>{let e=Y.trim(),t=X.trim();!e||!t||(J(n=>({...n,[e]:t})),ct(``),lt(``))},Dt=async()=>{L(!0);try{await x({clientAliases:q}),z(`success`),B(`客户端名称已保存,新请求立即生效`),d.success(`客户端名称保存成功`)}catch(e){let t=e instanceof Error?e.message:`保存失败`;z(`error`),B(t),d.error(t)}finally{L(!1)}},Ot=async()=>{L(!0);try{await x({mocksFilePath:U}),K(),z(`success`),B(`Mock 文件路径已更新,已切换到新文件`),d.success(`Mock 文件路径保存成功`),setTimeout(()=>{z(null),B(``)},3e3)}catch(e){let t=e instanceof Error?e.message:`保存失败`;z(`error`),B(t),d.error(t)}finally{L(!1)}};je({active:(e||n)&&M!==`preferences`,enabled:!I,priority:Ae.panel,onSave:()=>{if(M===`config`)return Ot();if(M===`clients`)return Dt();if(M===`ai`)return $()}});let kt=(0,E.jsxs)(E.Fragment,{children:[!n&&(0,E.jsxs)(ge,{className:`px-6 pt-6 pb-4`,children:[(0,E.jsxs)(Re,{className:`flex items-center gap-2`,children:[(0,E.jsx)(ke,{className:`h-5 w-5`}),`系统设置`]}),(0,E.jsx)(ye,{children:`管理系统偏好、配置和 AI 功能`})]}),(0,E.jsxs)(Ne,{value:M,onValueChange:e=>rt(e),orientation:`vertical`,className:`min-h-0 flex-1 gap-0`,children:[(0,E.jsxs)(Me,{"aria-label":`设置分类`,className:`h-full w-14 shrink-0 self-stretch justify-start gap-1 rounded-none border-r bg-muted/25 p-2 group-data-[orientation=vertical]/tabs:!h-full sm:w-44 sm:p-3`,children:[(0,E.jsxs)(h,{value:`preferences`,className:`h-9 w-full flex-none justify-start px-2.5 sm:px-3`,children:[(0,E.jsx)(ke,{}),(0,E.jsx)(`span`,{className:`hidden sm:inline`,children:`偏好设置`})]}),(0,E.jsxs)(h,{value:`config`,className:`h-9 w-full flex-none justify-start px-2.5 sm:px-3`,children:[(0,E.jsx)(p,{}),(0,E.jsx)(`span`,{className:`hidden sm:inline`,children:`配置文件`})]}),(0,E.jsxs)(h,{value:`clients`,className:`h-9 w-full flex-none justify-start px-2.5 sm:px-3`,children:[(0,E.jsx)(re,{}),(0,E.jsx)(`span`,{className:`hidden sm:inline`,children:`客户端`})]}),(0,E.jsxs)(h,{value:`ai`,className:`h-9 w-full flex-none justify-start px-2.5 sm:px-3`,children:[(0,E.jsx)(De,{}),(0,E.jsx)(`span`,{className:`hidden sm:inline`,children:`AI 配置`})]})]}),(0,E.jsxs)(f,{value:`preferences`,className:D,children:[(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-sm`,children:`主题`}),(0,E.jsxs)(be,{value:i,onValueChange:e=>T(e),children:[(0,E.jsx)(Le,{children:(0,E.jsx)(ve,{placeholder:`选择主题`})}),(0,E.jsx)(xe,{children:(0,E.jsxs)(_e,{children:[(0,E.jsx)(m,{value:`system`,children:(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(Te,{className:`size-4`}),`跟随系统`]})}),(0,E.jsx)(m,{value:`light`,children:(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(Pe,{className:`size-4`}),`浅色模式`]})}),(0,E.jsx)(m,{value:`dark`,children:(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(Be,{className:`size-4`}),`深色模式`]})})]})})]})]}),(0,E.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,E.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,E.jsx)(_,{className:`text-sm`,children:`强调色`}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`统一按钮、状态、选中项和焦点样式。自动模式会根据明暗主题选择合适的颜色。`})]}),(0,E.jsx)(y,{type:`single`,value:w,onValueChange:e=>{e&&Qe(e)},variant:`outline`,spacing:1,className:`flex-wrap justify-start`,"aria-label":`强调色`,children:tt.map(e=>(0,E.jsxs)(v,{value:e.value,"aria-label":e.label,children:[e.value===`auto`?(0,E.jsx)(De,{"data-icon":`inline-start`}):(0,E.jsx)(`span`,{className:`size-3 rounded-full border border-foreground/10`,style:{background:e.color}}),e.label]},e.value))})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-sm`,children:`缩放比例`}),(0,E.jsxs)(be,{value:Q,onValueChange:vt,children:[(0,E.jsx)(Le,{children:(0,E.jsx)(ve,{placeholder:`选择缩放比例`})}),(0,E.jsx)(xe,{children:(0,E.jsx)(_e,{children:et.map(e=>(0,E.jsx)(m,{value:e.value,children:e.label},e.value))})})]})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(`h3`,{className:`text-sm font-medium`,children:`关于`}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Meddle - HTTP 调试代理工具`}),(0,E.jsxs)(`p`,{className:`text-xs text-muted-foreground`,"data-testid":`settings-app-version`,children:[`版本: `,pt??`—`]})]})]}),(0,E.jsxs)(f,{value:`config`,className:D,children:[(0,E.jsxs)(`div`,{className:k,children:[(0,E.jsx)(_,{className:`text-sm font-medium`,children:`路由规则文件`}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsxs)(`div`,{className:`flex items-center gap-2 p-3 bg-muted rounded-md`,children:[(0,E.jsx)(p,{className:`h-4 w-4 text-muted-foreground shrink-0`}),(0,E.jsx)(`span`,{"data-testid":`settings-route-rules-dir`,className:`text-xs font-mono flex-1 wrap-anywhere`,title:ht?.path??void 0,children:(0,E.jsx)(Je,{path:_t})})]}),ot.length>0?(0,E.jsx)(`div`,{className:`space-y-2`,children:ot.map(e=>(0,E.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border px-3 py-2.5 text-sm`,children:[(0,E.jsx)(Se,{variant:e.enabled?`default`:`secondary`,className:`text-[10px]`,children:e.enabled?`已启用`:`未启用`}),(0,E.jsxs)(`span`,{className:`flex-1 truncate text-xs`,children:[e.name,`.txt`]}),(0,E.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.ruleCount,` 条规则`]})]},e.name))}):(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无规则文件`}),(0,E.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`规则文件存放于 `,_t,` 目录,纯文本格式。在"路由规则"页面管理。`]})]})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:k,children:[(0,E.jsx)(_,{className:`text-sm font-medium`,children:`Mock 规则文件`}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(`span`,{"data-testid":`settings-mocks-file-current-label`,className:`text-xs text-muted-foreground`,children:`当前使用`}),(0,E.jsxs)(`div`,{className:`flex items-center gap-2 p-3 bg-muted rounded-md`,children:[(0,E.jsx)(p,{className:`h-4 w-4 text-muted-foreground shrink-0`}),(0,E.jsx)(`span`,{"data-testid":`settings-mocks-file-resolved`,className:`text-xs font-mono flex-1 wrap-anywhere`,title:G?.path,children:G?.path?(0,E.jsx)(Je,{path:G.path}):U||`默认: ~/.meddle/mocks.json`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`mocksPath`,className:`text-xs text-muted-foreground`,children:`自定义 Mock 规则文件路径(留空使用默认)`}),(0,E.jsxs)(`div`,{className:`flex gap-2`,children:[(0,E.jsx)(g,{id:`mocksPath`,value:U,onChange:e=>W(e.target.value),placeholder:`如: /path/to/my-mocks.json`,className:`flex-1 h-8 text-sm font-mono`}),(0,E.jsx)(We,{onClick:Ot,saving:I,label:`应用`,savingLabel:`应用中…`,"data-testid":`settings-mocks-file-apply`,className:`h-8`})]}),G?.legacyMocksPath?(0,E.jsx)(Ge,{oldPath:G.legacyMocksPath.oldPath,newPath:G.legacyMocksPath.newPath,visible:fe(U),onUseOldPath:()=>W(G.legacyMocksPath.oldPath)}):null,(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`必须是 JSON 格式的 Mock 规则文件。支持 ~ 表示用户主目录;相对路径相对于 Meddle 配置目录。`}),he(G)?(0,E.jsx)(qe,{testId:`settings-mocks-file-invalid`,location:pe(G.parseError)}):de(G)&&!G.legacyMocksPath?(0,E.jsx)(Ke,{testId:`settings-mocks-file-missing`}):null]})]})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(`h3`,{className:`text-sm font-medium`,children:`操作`}),(0,E.jsxs)(`div`,{className:`flex gap-2`,children:[(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:wt,children:[(0,E.jsx)(te,{className:`h-4 w-4 mr-1`}),`重新加载配置`]}),(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:Tt,disabled:dt,children:[(0,E.jsx)(Ze,{className:`h-4 w-4 mr-1`}),dt?`诊断中…`:`诊断配置`]})]}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`点击重新加载可应用修改后的配置文件,点击诊断配置可检查配置有效性`})]}),Z&&(0,E.jsxs)(`div`,{className:k,children:[(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{children:[(0,E.jsxs)(`h3`,{className:`mb-4 flex items-center gap-2 text-sm font-medium`,children:[(0,E.jsx)(Ze,{className:`h-4 w-4`}),`诊断结果`]}),(0,E.jsxs)(`div`,{className:`mb-3 p-3 rounded-md border ${Z.status===`ok`?`bg-green-50 dark:bg-green-950/20 border-green-200 dark:border-green-900`:Z.status===`warning`?`bg-yellow-50 dark:bg-yellow-950/20 border-yellow-200 dark:border-yellow-900`:`bg-red-50 dark:bg-red-950/20 border-red-200 dark:border-red-900`}`,children:[Z.status===`ok`&&(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(b,{className:`h-5 w-5 text-green-600 dark:text-green-400`}),(0,E.jsx)(`span`,{className:`text-sm font-medium text-green-700 dark:text-green-300`,children:`所有检查通过!配置正常。`})]}),Z.status===`warning`&&(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(a,{className:`h-5 w-5 text-yellow-600 dark:text-yellow-400`}),(0,E.jsxs)(`span`,{className:`text-sm font-medium text-yellow-700 dark:text-yellow-300`,children:[`发现 `,Z.warnings.length,` 个警告`]})]}),Z.status===`error`&&(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(o,{className:`h-5 w-5 text-red-600 dark:text-red-400`}),(0,E.jsxs)(`span`,{className:`text-sm font-medium text-red-700 dark:text-red-300`,children:[`发现 `,Z.errors.length,` 个错误`]})]})]}),(0,E.jsx)(`div`,{className:O,children:Z.checks.map((e,t)=>(0,E.jsx)(`div`,{className:`p-2 rounded border bg-card`,children:(0,E.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,E.jsx)(b,{className:`h-4 w-4 text-green-600 dark:text-green-400 mt-0.5 shrink-0`}),(0,E.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,E.jsx)(`div`,{className:`text-sm font-medium`,children:e.name}),(0,E.jsx)(`div`,{className:`text-xs text-muted-foreground font-mono truncate`,children:e.path}),e.details&&(0,E.jsxs)(`div`,{className:`text-xs text-muted-foreground mt-1`,children:[e.details.totalFiles!==void 0&&`${e.details.enabledFiles}/${e.details.totalFiles} 个文件已启用`,e.details.totalRules!==void 0&&` · ${e.details.totalRules} 条规则`,e.details.rules!==void 0&&`${e.details.rules} 条规则`,e.details.total!==void 0&&`${e.details.total} 条规则 (${e.details.enabled} 已启用)`,e.details.size!==void 0&&` · ${e.details.size} bytes`]})]})]})},t))}),Z.warnings&&Z.warnings.length>0&&(0,E.jsxs)(`div`,{className:`mt-3 space-y-1`,children:[(0,E.jsx)(`div`,{className:`text-xs font-medium text-yellow-700 dark:text-yellow-300`,children:`警告:`}),Z.warnings.map((e,t)=>(0,E.jsxs)(`div`,{className:`flex items-start gap-2 text-xs text-yellow-600 dark:text-yellow-400`,children:[(0,E.jsx)(a,{className:`h-3 w-3 mt-0.5 shrink-0`}),(0,E.jsx)(`span`,{children:e})]},t))]}),Z.errors&&Z.errors.length>0&&(0,E.jsxs)(`div`,{className:`mt-3 space-y-1`,children:[(0,E.jsx)(`div`,{className:`text-xs font-medium text-red-700 dark:text-red-300`,children:`错误:`}),Z.errors.map((e,t)=>(0,E.jsxs)(`div`,{className:`flex items-start gap-2 text-xs text-red-600 dark:text-red-400`,children:[(0,E.jsx)(o,{className:`h-3 w-3 mt-0.5 shrink-0`}),(0,E.jsx)(`span`,{children:e})]},t))]})]})]})]}),(0,E.jsxs)(f,{value:`clients`,className:D,children:[(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,E.jsx)(re,{className:`h-4 w-4`}),`远程客户端名称`]}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`将日志中的客户端 IP 映射为设备名称。保存后新请求立即生效,无需重启代理。`})]}),(0,E.jsx)(`div`,{className:O,children:Object.entries(q).length===0?(0,E.jsx)(`div`,{className:`rounded-md border border-dashed p-4 text-center text-xs text-muted-foreground`,children:`尚未配置设备名称`}):Object.entries(q).map(([e,t])=>(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(g,{value:e,readOnly:!0,className:`h-8 flex-1 font-mono text-xs bg-muted/40`,"aria-label":`客户端 IP ${e}`}),(0,E.jsx)(g,{value:t,onChange:t=>{let n=t.target.value;J(t=>({...t,[e]:n}))},className:`h-8 flex-1 text-sm`,"aria-label":`${e} 的设备名称`}),(0,E.jsx)(r,{variant:`ghost`,size:`icon-sm`,className:`text-muted-foreground hover:text-destructive`,onClick:()=>{J(t=>{let n={...t};return delete n[e],n})},title:`删除设备名称`,"aria-label":`删除设备名称`,children:(0,E.jsx)(ie,{className:`h-4 w-4`})})]},e))}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-sm`,children:`添加设备`}),(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(g,{value:Y,onChange:e=>ct(e.target.value),placeholder:`客户端 IP,例如 10.13.232.187`,className:`h-8 flex-1 font-mono text-xs`}),(0,E.jsx)(g,{value:X,onChange:e=>lt(e.target.value),onKeyDown:e=>{e.key===`Enter`&&Et()},placeholder:`设备名称,例如 iPhone`,className:`h-8 flex-1 text-sm`}),(0,E.jsxs)(r,{variant:`outline`,size:`sm`,className:`h-8`,onClick:Et,disabled:!Y.trim()||!X.trim(),children:[(0,E.jsx)(s,{className:`h-4 w-4 mr-1`}),`添加`]})]})]}),(0,E.jsxs)(Ce,{onClick:Dt,disabled:I,children:[(0,E.jsx)(Fe,{"data-icon":`inline-start`,className:`h-4 w-4`}),I?`保存中…`:`保存客户端名称`]})]}),(0,E.jsxs)(f,{value:`ai`,className:D,children:[(0,E.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(_,{className:`text-sm`,children:`启用 AI 功能`}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`启用智能代码修复功能`})]}),(0,E.jsx)(ae,{checked:N.enabled,onCheckedChange:e=>P({...N,enabled:e}),"aria-label":`启用 AI 功能`})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:k,children:[(0,E.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,E.jsx)(_,{className:`text-sm`,children:`AI 模型配置`}),(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:()=>{H({name:``,provider:`openai`,apiKey:``,baseUrl:`https://api.openai.com/v1/chat/completions`,model:`gpt-4o-mini`})},children:[(0,E.jsx)(s,{className:`h-4 w-4 mr-1`}),`添加模型`]})]}),(0,E.jsx)(`div`,{className:O,children:N.models&&N.models.length>0?N.models.map(e=>(0,E.jsx)(`div`,{className:`p-3 rounded-md border ${N.activeModelId===e.id?`border-primary bg-primary/5`:`border-border`}`,children:(0,E.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,E.jsxs)(`div`,{className:`flex-1`,children:[(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(`span`,{className:`font-medium text-sm`,children:e.name}),N.activeModelId===e.id&&(0,E.jsx)(Se,{variant:`default`,className:`text-xs`,children:`当前使用`})]}),(0,E.jsxs)(`p`,{className:`text-xs text-muted-foreground mt-1`,children:[e.provider===`openai`?`OpenAI`:`Anthropic`,` - `,e.model]})]}),(0,E.jsxs)(`div`,{className:`flex gap-1`,children:[N.activeModelId!==e.id&&(0,E.jsxs)(r,{variant:`ghost`,size:`xs`,onClick:()=>P(se(N,e.id)),children:[(0,E.jsx)(ee,{className:`h-3 w-3 mr-1`}),`使用`]}),(0,E.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>P(ce(N,e.id)),className:`text-destructive`,"aria-label":`删除模型`,children:(0,E.jsx)(ie,{className:`h-3 w-3`})})]})]})},e.id)):(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground italic py-4 text-center`,children:`暂无模型配置,点击"添加模型"创建`})}),V&&(0,E.jsxs)(`div`,{className:`space-y-5 rounded-md border border-primary bg-primary/5 p-4`,children:[(0,E.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,E.jsx)(_,{className:`text-sm font-medium`,children:`新增模型`}),(0,E.jsx)(r,{variant:`ghost`,size:`icon-xs`,onClick:()=>H(null),"aria-label":`关闭新增模型表单`,children:(0,E.jsx)(o,{className:`h-4 w-4`})})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`newModelName`,className:`text-xs`,children:`模型名称`}),(0,E.jsx)(g,{id:`newModelName`,value:V.name||``,onChange:e=>H({...V,name:e.target.value}),placeholder:`如:GPT-4o Mini`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-xs`,children:`服务商`}),(0,E.jsxs)(y,{type:`single`,value:V.provider,onValueChange:e=>{if(e===`openai`){let e=c(`openai`);H({...V,provider:`openai`,baseUrl:e.baseUrl,model:e.model})}else if(e===`anthropic`){let e=c(`anthropic`);H({...V,provider:`anthropic`,baseUrl:e.baseUrl,model:e.model})}},variant:`outline`,size:`sm`,spacing:0,children:[(0,E.jsx)(v,{value:`openai`,children:`OpenAI`}),(0,E.jsx)(v,{value:`anthropic`,children:`Anthropic`})]})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`newModelApiKey`,className:`text-xs`,children:`API Key`}),(0,E.jsx)(g,{id:`newModelApiKey`,type:F?`text`:`password`,value:V.apiKey||``,onChange:e=>H({...V,apiKey:e.target.value}),placeholder:`输入 API Key`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`newModelModel`,className:`text-xs`,children:`模型`}),(0,E.jsx)(g,{id:`newModelModel`,value:V.model||``,onChange:e=>H({...V,model:e.target.value}),placeholder:`模型名称`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`newModelBaseUrl`,className:`text-xs`,children:`API 端点`}),(0,E.jsx)(g,{id:`newModelBaseUrl`,value:V.baseUrl||``,onChange:e=>H({...V,baseUrl:e.target.value}),placeholder:`API 端点`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:`flex justify-end gap-2 pt-2`,children:[(0,E.jsx)(r,{variant:`outline`,size:`xs`,onClick:()=>H(null),children:`取消`}),(0,E.jsxs)(r,{size:`xs`,onClick:()=>{V.name&&V.apiKey&&V.model&&V.baseUrl&&(P(ue(N,V)),H(null))},disabled:!V.name||!V.apiKey||!V.model||!V.baseUrl,children:[(0,E.jsx)(s,{className:`h-3 w-3 mr-1`}),`添加`]})]})]})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(_,{className:`text-sm`,children:`传统配置(向后兼容)`}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`如果未配置多模型,将使用此配置`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-xs`,children:`AI 服务商`}),(0,E.jsxs)(y,{type:`single`,value:N.provider,onValueChange:e=>{(e===`openai`||e===`anthropic`)&&xt(e)},variant:`outline`,size:`sm`,spacing:0,children:[(0,E.jsx)(v,{value:`openai`,children:`OpenAI`}),(0,E.jsx)(v,{value:`anthropic`,children:`Anthropic`})]})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`apiKey`,className:`text-xs`,children:`API Key`}),(0,E.jsxs)(`div`,{className:`flex gap-2`,children:[(0,E.jsx)(g,{id:`apiKey`,type:F?`text`:`password`,value:N.apiKey,onChange:e=>P({...N,apiKey:e.target.value}),placeholder:`输入 API Key`,className:`flex-1 h-8 text-sm`}),(0,E.jsx)(r,{variant:`outline`,size:`icon-sm`,onClick:()=>it(!F),"aria-label":F?`隐藏 API Key`:`显示 API Key`,children:F?(0,E.jsx)(Ye,{className:`h-4 w-4`}):(0,E.jsx)(Xe,{className:`h-4 w-4`})})]})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`model`,className:`text-xs`,children:`模型`}),(0,E.jsx)(g,{id:`model`,value:N.model,onChange:e=>P({...N,model:e.target.value}),placeholder:`模型名称`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`baseUrl`,className:`text-xs`,children:`API 端点`}),(0,E.jsx)(g,{id:`baseUrl`,value:N.baseUrl,onChange:e=>P({...N,baseUrl:e.target.value}),placeholder:N.provider===`openai`?`https://api.openai.com/v1/chat/completions`:`https://api.anthropic.com/v1/messages`,className:`h-8 text-sm`})]}),at&&(0,E.jsxs)(Ue,{variant:R===`error`?`destructive`:`default`,children:[R===`success`?(0,E.jsx)(b,{}):R===`error`?(0,E.jsx)(o,{}):(0,E.jsx)(a,{}),(0,E.jsx)(He,{children:R===`success`?`操作成功`:R===`error`?`操作失败`:`处理中`}),(0,E.jsx)(Ve,{children:at})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:`flex justify-between`,children:[(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:St,children:[(0,E.jsx)(ne,{className:`h-4 w-4 mr-1`}),`重置`]}),(0,E.jsxs)(`div`,{className:`flex gap-2`,children:[(0,E.jsx)(r,{variant:`outline`,size:`sm`,onClick:Ct,disabled:!l(N)||I,children:`测试连接`}),(0,E.jsxs)(Ce,{size:`sm`,onClick:$,disabled:I,children:[(0,E.jsx)(Fe,{"data-icon":`inline-start`,className:`h-4 w-4`}),I?`保存中…`:`保存`]})]})]})]})]})]});return n?(0,E.jsx)(`div`,{"data-testid":`settings-fullwidth`,className:`app-workspace-content flex h-full min-h-0 w-full flex-col overflow-hidden p-0`,children:(0,E.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border bg-card`,children:kt})}):(0,E.jsx)(we,{open:e,onOpenChange:t,children:(0,E.jsx)(ze,{className:`p-0 flex flex-col`,resizable:!0,defaultWidth:600,storageKey:`settings-panel`,children:kt})})}export{j as SettingsPanel};
|
|
1
|
+
import{c as e,d as t,p as n,t as r,u as i}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as ee}from"./check-BkfHQ6re.js";import{t as a}from"./circle-alert-zMagrFuI.js";import{t as o}from"./circle-x-BEkinhez.js";import{t as s}from"./plus-ixZQRprm.js";import{t as te}from"./refresh-cw-BfLoHqg5.js";import{t as ne}from"./rotate-ccw-CRguJya4.js";import{t as re}from"./smartphone-D4Q7cQfm.js";import{c as ie}from"./dist-BQN0rzUS.js";import"./es2015-DPJTBYa9.js";import{t as ae}from"./switch-94vgsMHm.js";import{a as c,c as oe,l as se,n as ce,o as l,r as u,s as le,t as ue}from"./ai-config-store-C8D_PUGV.js";import{n as d}from"./toast-9yeTf7d9.js";import{a as de,i as fe,n as pe,o as me,r as he}from"./use-mocks-file-status-BUIUJ4oQ.js";import{A as f,C as ge,Et as p,G as _e,J as ve,K as m,M as h,Q as g,S as ye,T as _,U as be,W as xe,X as v,Y as y,Z as Se,_ as Ce,b as we,bt as Te,d as Ee,dt as De,f as Oe,ft as ke,g as Ae,h as je,j as Me,k as Ne,kt as b,lt as Pe,m as x,mt as Fe,p as Ie,q as Le,w as Re,x as ze,y as S,yt as Be}from"./index-CSXxaYkG.js";import{n as Ve,r as He,t as Ue}from"./alert-B514Frte.js";import{n as We}from"./pane-bar-zJmE3xI5.js";import{i as Ge,o as Ke,r as qe,t as Je}from"./mocks-file-missing-note-Ddy1TdMX.js";var Ye=i(`eye-off`,[[`path`,{d:`M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49`,key:`ct8e1f`}],[`path`,{d:`M14.084 14.158a3 3 0 0 1-4.242-4.242`,key:`151rxh`}],[`path`,{d:`M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143`,key:`13bj9a`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]),Xe=i(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),Ze=i(`stethoscope`,[[`path`,{d:`M11 2v2`,key:`1539x4`}],[`path`,{d:`M5 2v2`,key:`1yf1q8`}],[`path`,{d:`M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1`,key:`rb5t3r`}],[`path`,{d:`M8 15a6 6 0 0 0 12 0v-3`,key:`x18d4x`}],[`circle`,{cx:`20`,cy:`10`,r:`2`,key:`ts1r5v`}]]),C=n(t(),1),w={version:null,routeRulesDir:null,routeRulesDirDisplay:null};function T(e){return typeof e==`string`&&e.trim()||null}function Qe(e){if(!e||typeof e!=`object`||Array.isArray(e))return{...w};let t=e;return{version:T(t.version),routeRulesDir:T(t.routeRulesDir),routeRulesDirDisplay:T(t.routeRulesDirDisplay)}}async function $e(){try{let e=await fetch(`/api/version`);return e.ok?Qe(await e.json()):{...w}}catch{return{...w}}}var E=e(),et=[{value:`75`,label:`75%`,scale:.75},{value:`90`,label:`90%`,scale:.9},{value:`100`,label:`100%`,scale:1},{value:`110`,label:`110%`,scale:1.1},{value:`125`,label:`125%`,scale:1.25},{value:`150`,label:`150%`,scale:1.5}],tt=[{value:`auto`,label:`自动`,color:`linear-gradient(135deg, oklch(0.623 0.214 259.815), oklch(0.606 0.25 292.717))`},{value:`neutral`,label:`中性`,color:`oklch(0.556 0 0)`},{value:`blue`,label:`蓝色`,color:`oklch(0.623 0.214 259.815)`},{value:`violet`,label:`紫色`,color:`oklch(0.606 0.25 292.717)`},{value:`green`,label:`绿色`,color:`oklch(0.627 0.194 149.214)`},{value:`orange`,label:`橙色`,color:`oklch(0.646 0.222 41.116)`},{value:`rose`,label:`玫红`,color:`oklch(0.645 0.246 16.439)`}],D=`app-panel-content mt-0`,O=`app-field-group`,k=`app-section`,nt=`$MEDDLE_HOME/route-rules/`,A=e=>{if(!e)return`100`;let t={small:`90`,medium:`100`,large:`110`};return e in t?t[e]:et.some(t=>t.value===e)?e:`100`};function j({open:e=!1,onOpenChange:t,embedded:n=!1}){let{theme:i,accentColor:w,setTheme:T,setAccentColor:Qe,setZoom:j}=Ee(),[M,rt]=(0,C.useState)(`preferences`),[N,P]=(0,C.useState)(()=>u()),[F,it]=(0,C.useState)(!1),[I,L]=(0,C.useState)(!1),[R,z]=(0,C.useState)(null),[at,B]=(0,C.useState)(``),[V,H]=(0,C.useState)(null),[U,W]=(0,C.useState)(``),{status:G,refresh:K}=me(),[ot,st]=(0,C.useState)([]),[q,J]=(0,C.useState)({}),[Y,ct]=(0,C.useState)(``),[X,lt]=(0,C.useState)(``),[Z,ut]=(0,C.useState)(null),[dt,ft]=(0,C.useState)(!1),[pt,mt]=(0,C.useState)(null),[ht,gt]=(0,C.useState)(null);(0,C.useEffect)(()=>{let e=!1;return $e().then(t=>{if(e)return;mt(t.version);let n=t.routeRulesDirDisplay||t.routeRulesDir;n&>({display:n,path:t.routeRulesDir})}),()=>{e=!0}},[]);let _t=ht?.display??nt,[Q,vt]=(0,C.useState)(()=>A(Oe().fontSize)),[yt,bt]=(0,C.useState)(!1);(0,C.useEffect)(()=>{Ie().then(e=>{let t=A(e.fontSize);vt(t),j(parseInt(t,10)/100),bt(!0)}).catch(()=>{bt(!0)})},[j]),(0,C.useEffect)(()=>{if(!yt)return;let e=A(Q);j(parseInt(e,10)/100),x({fontSize:e}).catch(console.error)},[j,yt,Q]),(0,C.useEffect)(()=>{(e||n)&&(Ie().then(e=>{P(e.aiConfig),W(e.mocksFilePath||``),J(e.clientAliases||{})}).catch(()=>{P(u())}),z(null),B(``),fetch(`/api/rule-files`).then(e=>e.json()).then(e=>{Array.isArray(e)&&st(e)}).catch(()=>{}))},[e,n]);let xt=e=>{let t=c(e);P({...N,provider:e,baseUrl:t.baseUrl,model:t.model})},$=async()=>{L(!0);try{await x({aiConfig:N}),oe(N),z(`success`),B(`AI 配置保存成功`),d.success(`AI 配置保存成功`)}catch(e){let t=e instanceof Error?e.message:`保存失败`;z(`error`),B(t),d.error(t)}finally{L(!1)}},St=()=>{le(),P(u()),z(null),B(``)},Ct=async()=>{if(!l(N)){z(`error`),B(`请填写完整的配置信息`);return}L(!0),z(null),B(`测试中…`);try{let e=N.baseUrl,t={"Content-Type":`application/json`},n;N.provider===`anthropic`?(t[`x-api-key`]=N.apiKey,t[`anthropic-version`]=`2023-06-01`,n={model:N.model,max_tokens:100,system:`You are a helpful assistant.`,messages:[{role:`user`,content:`Say "test successful"`}],temperature:.3}):(t.Authorization=`Bearer ${N.apiKey}`,n={model:N.model,messages:[{role:`system`,content:`You are a helpful assistant.`},{role:`user`,content:`Say "test successful"`}],temperature:.3,max_tokens:100});let r=await fetch(e,{method:`POST`,headers:t,body:JSON.stringify(n)});if(!r.ok){let e=await r.text();throw Error(`API错误 (${r.status}): ${e}`)}let i=await r.json();if(N.provider===`anthropic`){if(!i.content?.[0]?.text)throw Error(`API响应格式不正确`)}else if(!i.choices?.[0]?.message?.content)throw Error(`API响应格式不正确`);z(`success`),B(`连接测试成功! API配置正常`)}catch(e){z(`error`),B(e instanceof Error?e.message:`测试失败`)}finally{L(!1)}},wt=(0,C.useCallback)(async()=>{try{let e=await fetch(`/api/refresh-config`,{method:`POST`});if(e.ok){let t=await e.json();K(),z(`success`),B(t.message||`配置已刷新`),setTimeout(()=>{z(null),B(``)},2e3)}else{let t=await e.json();z(`error`),B(t.error||`刷新配置失败`),setTimeout(()=>{z(null),B(``)},2e3)}}catch(e){console.error(`刷新配置失败:`,e),z(`error`),B(`刷新配置失败`),setTimeout(()=>{z(null),B(``)},2e3)}},[K]),Tt=(0,C.useCallback)(async()=>{ft(!0),ut(null);try{let e=await fetch(`/api/config-doctor`);e.ok?ut(await e.json()):(z(`error`),B(`诊断失败`),setTimeout(()=>{z(null),B(``)},2e3))}catch(e){console.error(`诊断失败:`,e),z(`error`),B(`诊断失败`),setTimeout(()=>{z(null),B(``)},2e3)}finally{ft(!1)}},[]),Et=()=>{let e=Y.trim(),t=X.trim();!e||!t||(J(n=>({...n,[e]:t})),ct(``),lt(``))},Dt=async()=>{L(!0);try{await x({clientAliases:q}),z(`success`),B(`客户端名称已保存,新请求立即生效`),d.success(`客户端名称保存成功`)}catch(e){let t=e instanceof Error?e.message:`保存失败`;z(`error`),B(t),d.error(t)}finally{L(!1)}},Ot=async()=>{L(!0);try{await x({mocksFilePath:U}),K(),z(`success`),B(`Mock 文件路径已更新,已切换到新文件`),d.success(`Mock 文件路径保存成功`),setTimeout(()=>{z(null),B(``)},3e3)}catch(e){let t=e instanceof Error?e.message:`保存失败`;z(`error`),B(t),d.error(t)}finally{L(!1)}};je({active:(e||n)&&M!==`preferences`,enabled:!I,priority:Ae.panel,onSave:()=>{if(M===`config`)return Ot();if(M===`clients`)return Dt();if(M===`ai`)return $()}});let kt=(0,E.jsxs)(E.Fragment,{children:[!n&&(0,E.jsxs)(ge,{className:`px-6 pt-6 pb-4`,children:[(0,E.jsxs)(Re,{className:`flex items-center gap-2`,children:[(0,E.jsx)(ke,{className:`h-5 w-5`}),`系统设置`]}),(0,E.jsx)(ye,{children:`管理系统偏好、配置和 AI 功能`})]}),(0,E.jsxs)(Ne,{value:M,onValueChange:e=>rt(e),orientation:`vertical`,className:`min-h-0 flex-1 gap-0`,children:[(0,E.jsxs)(Me,{"aria-label":`设置分类`,className:`h-full w-14 shrink-0 self-stretch justify-start gap-1 rounded-none border-r bg-muted/25 p-2 group-data-[orientation=vertical]/tabs:!h-full sm:w-44 sm:p-3`,children:[(0,E.jsxs)(h,{value:`preferences`,className:`h-9 w-full flex-none justify-start px-2.5 sm:px-3`,children:[(0,E.jsx)(ke,{}),(0,E.jsx)(`span`,{className:`hidden sm:inline`,children:`偏好设置`})]}),(0,E.jsxs)(h,{value:`config`,className:`h-9 w-full flex-none justify-start px-2.5 sm:px-3`,children:[(0,E.jsx)(p,{}),(0,E.jsx)(`span`,{className:`hidden sm:inline`,children:`配置文件`})]}),(0,E.jsxs)(h,{value:`clients`,className:`h-9 w-full flex-none justify-start px-2.5 sm:px-3`,children:[(0,E.jsx)(re,{}),(0,E.jsx)(`span`,{className:`hidden sm:inline`,children:`客户端`})]}),(0,E.jsxs)(h,{value:`ai`,className:`h-9 w-full flex-none justify-start px-2.5 sm:px-3`,children:[(0,E.jsx)(De,{}),(0,E.jsx)(`span`,{className:`hidden sm:inline`,children:`AI 配置`})]})]}),(0,E.jsxs)(f,{value:`preferences`,className:D,children:[(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-sm`,children:`主题`}),(0,E.jsxs)(be,{value:i,onValueChange:e=>T(e),children:[(0,E.jsx)(Le,{children:(0,E.jsx)(ve,{placeholder:`选择主题`})}),(0,E.jsx)(xe,{children:(0,E.jsxs)(_e,{children:[(0,E.jsx)(m,{value:`system`,children:(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(Te,{className:`size-4`}),`跟随系统`]})}),(0,E.jsx)(m,{value:`light`,children:(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(Pe,{className:`size-4`}),`浅色模式`]})}),(0,E.jsx)(m,{value:`dark`,children:(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(Be,{className:`size-4`}),`深色模式`]})})]})})]})]}),(0,E.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,E.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,E.jsx)(_,{className:`text-sm`,children:`强调色`}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`统一按钮、状态、选中项和焦点样式。自动模式会根据明暗主题选择合适的颜色。`})]}),(0,E.jsx)(y,{type:`single`,value:w,onValueChange:e=>{e&&Qe(e)},variant:`outline`,spacing:1,className:`flex-wrap justify-start`,"aria-label":`强调色`,children:tt.map(e=>(0,E.jsxs)(v,{value:e.value,"aria-label":e.label,children:[e.value===`auto`?(0,E.jsx)(De,{"data-icon":`inline-start`}):(0,E.jsx)(`span`,{className:`size-3 rounded-full border border-foreground/10`,style:{background:e.color}}),e.label]},e.value))})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-sm`,children:`缩放比例`}),(0,E.jsxs)(be,{value:Q,onValueChange:vt,children:[(0,E.jsx)(Le,{children:(0,E.jsx)(ve,{placeholder:`选择缩放比例`})}),(0,E.jsx)(xe,{children:(0,E.jsx)(_e,{children:et.map(e=>(0,E.jsx)(m,{value:e.value,children:e.label},e.value))})})]})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(`h3`,{className:`text-sm font-medium`,children:`关于`}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Meddle - HTTP 调试代理工具`}),(0,E.jsxs)(`p`,{className:`text-xs text-muted-foreground`,"data-testid":`settings-app-version`,children:[`版本: `,pt??`—`]})]})]}),(0,E.jsxs)(f,{value:`config`,className:D,children:[(0,E.jsxs)(`div`,{className:k,children:[(0,E.jsx)(_,{className:`text-sm font-medium`,children:`路由规则文件`}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsxs)(`div`,{className:`flex items-center gap-2 p-3 bg-muted rounded-md`,children:[(0,E.jsx)(p,{className:`h-4 w-4 text-muted-foreground shrink-0`}),(0,E.jsx)(`span`,{"data-testid":`settings-route-rules-dir`,className:`text-xs font-mono flex-1 wrap-anywhere`,title:ht?.path??void 0,children:(0,E.jsx)(Je,{path:_t})})]}),ot.length>0?(0,E.jsx)(`div`,{className:`space-y-2`,children:ot.map(e=>(0,E.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border px-3 py-2.5 text-sm`,children:[(0,E.jsx)(Se,{variant:e.enabled?`default`:`secondary`,className:`text-[10px]`,children:e.enabled?`已启用`:`未启用`}),(0,E.jsxs)(`span`,{className:`flex-1 truncate text-xs`,children:[e.name,`.txt`]}),(0,E.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.ruleCount,` 条规则`]})]},e.name))}):(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无规则文件`}),(0,E.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`规则文件存放于 `,_t,` 目录,纯文本格式。在"路由规则"页面管理。`]})]})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:k,children:[(0,E.jsx)(_,{className:`text-sm font-medium`,children:`Mock 规则文件`}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(`span`,{"data-testid":`settings-mocks-file-current-label`,className:`text-xs text-muted-foreground`,children:`当前使用`}),(0,E.jsxs)(`div`,{className:`flex items-center gap-2 p-3 bg-muted rounded-md`,children:[(0,E.jsx)(p,{className:`h-4 w-4 text-muted-foreground shrink-0`}),(0,E.jsx)(`span`,{"data-testid":`settings-mocks-file-resolved`,className:`text-xs font-mono flex-1 wrap-anywhere`,title:G?.path,children:G?.path?(0,E.jsx)(Je,{path:G.path}):U||`默认: ~/.meddle/mocks.json`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`mocksPath`,className:`text-xs text-muted-foreground`,children:`自定义 Mock 规则文件路径(留空使用默认)`}),(0,E.jsxs)(`div`,{className:`flex gap-2`,children:[(0,E.jsx)(g,{id:`mocksPath`,value:U,onChange:e=>W(e.target.value),placeholder:`如: /path/to/my-mocks.json`,className:`flex-1 h-8 text-sm font-mono`}),(0,E.jsx)(We,{onClick:Ot,saving:I,label:`应用`,savingLabel:`应用中…`,"data-testid":`settings-mocks-file-apply`,className:`h-8`})]}),G?.legacyMocksPath?(0,E.jsx)(Ge,{oldPath:G.legacyMocksPath.oldPath,newPath:G.legacyMocksPath.newPath,visible:fe(U),onUseOldPath:()=>W(G.legacyMocksPath.oldPath)}):null,(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`必须是 JSON 格式的 Mock 规则文件。支持 ~ 表示用户主目录;相对路径相对于 Meddle 配置目录。`}),he(G)?(0,E.jsx)(qe,{testId:`settings-mocks-file-invalid`,location:pe(G.parseError)}):de(G)&&!G.legacyMocksPath?(0,E.jsx)(Ke,{testId:`settings-mocks-file-missing`}):null]})]})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(`h3`,{className:`text-sm font-medium`,children:`操作`}),(0,E.jsxs)(`div`,{className:`flex gap-2`,children:[(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:wt,children:[(0,E.jsx)(te,{className:`h-4 w-4 mr-1`}),`重新加载配置`]}),(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:Tt,disabled:dt,children:[(0,E.jsx)(Ze,{className:`h-4 w-4 mr-1`}),dt?`诊断中…`:`诊断配置`]})]}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`点击重新加载可应用修改后的配置文件,点击诊断配置可检查配置有效性`})]}),Z&&(0,E.jsxs)(`div`,{className:k,children:[(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{children:[(0,E.jsxs)(`h3`,{className:`mb-4 flex items-center gap-2 text-sm font-medium`,children:[(0,E.jsx)(Ze,{className:`h-4 w-4`}),`诊断结果`]}),(0,E.jsxs)(`div`,{className:`mb-3 p-3 rounded-md border ${Z.status===`ok`?`bg-green-50 dark:bg-green-950/20 border-green-200 dark:border-green-900`:Z.status===`warning`?`bg-yellow-50 dark:bg-yellow-950/20 border-yellow-200 dark:border-yellow-900`:`bg-red-50 dark:bg-red-950/20 border-red-200 dark:border-red-900`}`,children:[Z.status===`ok`&&(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(b,{className:`h-5 w-5 text-green-600 dark:text-green-400`}),(0,E.jsx)(`span`,{className:`text-sm font-medium text-green-700 dark:text-green-300`,children:`所有检查通过!配置正常。`})]}),Z.status===`warning`&&(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(a,{className:`h-5 w-5 text-yellow-600 dark:text-yellow-400`}),(0,E.jsxs)(`span`,{className:`text-sm font-medium text-yellow-700 dark:text-yellow-300`,children:[`发现 `,Z.warnings.length,` 个警告`]})]}),Z.status===`error`&&(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(o,{className:`h-5 w-5 text-red-600 dark:text-red-400`}),(0,E.jsxs)(`span`,{className:`text-sm font-medium text-red-700 dark:text-red-300`,children:[`发现 `,Z.errors.length,` 个错误`]})]})]}),(0,E.jsx)(`div`,{className:O,children:Z.checks.map((e,t)=>(0,E.jsx)(`div`,{className:`p-2 rounded border bg-card`,children:(0,E.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,E.jsx)(b,{className:`h-4 w-4 text-green-600 dark:text-green-400 mt-0.5 shrink-0`}),(0,E.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,E.jsx)(`div`,{className:`text-sm font-medium`,children:e.name}),(0,E.jsx)(`div`,{className:`text-xs text-muted-foreground font-mono truncate`,children:e.path}),e.details&&(0,E.jsxs)(`div`,{className:`text-xs text-muted-foreground mt-1`,children:[e.details.totalFiles!==void 0&&`${e.details.enabledFiles}/${e.details.totalFiles} 个文件已启用`,e.details.totalRules!==void 0&&` · ${e.details.totalRules} 条规则`,e.details.rules!==void 0&&`${e.details.rules} 条规则`,e.details.total!==void 0&&`${e.details.total} 条规则 (${e.details.enabled} 已启用)`,e.details.size!==void 0&&` · ${e.details.size} bytes`]})]})]})},t))}),Z.warnings&&Z.warnings.length>0&&(0,E.jsxs)(`div`,{className:`mt-3 space-y-1`,children:[(0,E.jsx)(`div`,{className:`text-xs font-medium text-yellow-700 dark:text-yellow-300`,children:`警告:`}),Z.warnings.map((e,t)=>(0,E.jsxs)(`div`,{className:`flex items-start gap-2 text-xs text-yellow-600 dark:text-yellow-400`,children:[(0,E.jsx)(a,{className:`h-3 w-3 mt-0.5 shrink-0`}),(0,E.jsx)(`span`,{children:e})]},t))]}),Z.errors&&Z.errors.length>0&&(0,E.jsxs)(`div`,{className:`mt-3 space-y-1`,children:[(0,E.jsx)(`div`,{className:`text-xs font-medium text-red-700 dark:text-red-300`,children:`错误:`}),Z.errors.map((e,t)=>(0,E.jsxs)(`div`,{className:`flex items-start gap-2 text-xs text-red-600 dark:text-red-400`,children:[(0,E.jsx)(o,{className:`h-3 w-3 mt-0.5 shrink-0`}),(0,E.jsx)(`span`,{children:e})]},t))]})]})]})]}),(0,E.jsxs)(f,{value:`clients`,className:D,children:[(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,E.jsx)(re,{className:`h-4 w-4`}),`远程客户端名称`]}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`将日志中的客户端 IP 映射为设备名称。保存后新请求立即生效,无需重启代理。`})]}),(0,E.jsx)(`div`,{className:O,children:Object.entries(q).length===0?(0,E.jsx)(`div`,{className:`rounded-md border border-dashed p-4 text-center text-xs text-muted-foreground`,children:`尚未配置设备名称`}):Object.entries(q).map(([e,t])=>(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(g,{value:e,readOnly:!0,className:`h-8 flex-1 font-mono text-xs bg-muted/40`,"aria-label":`客户端 IP ${e}`}),(0,E.jsx)(g,{value:t,onChange:t=>{let n=t.target.value;J(t=>({...t,[e]:n}))},className:`h-8 flex-1 text-sm`,"aria-label":`${e} 的设备名称`}),(0,E.jsx)(r,{variant:`ghost`,size:`icon-sm`,className:`text-muted-foreground hover:text-destructive`,onClick:()=>{J(t=>{let n={...t};return delete n[e],n})},title:`删除设备名称`,"aria-label":`删除设备名称`,children:(0,E.jsx)(ie,{className:`h-4 w-4`})})]},e))}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-sm`,children:`添加设备`}),(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(g,{value:Y,onChange:e=>ct(e.target.value),placeholder:`客户端 IP,例如 10.13.232.187`,className:`h-8 flex-1 font-mono text-xs`}),(0,E.jsx)(g,{value:X,onChange:e=>lt(e.target.value),onKeyDown:e=>{e.key===`Enter`&&Et()},placeholder:`设备名称,例如 iPhone`,className:`h-8 flex-1 text-sm`}),(0,E.jsxs)(r,{variant:`outline`,size:`sm`,className:`h-8`,onClick:Et,disabled:!Y.trim()||!X.trim(),children:[(0,E.jsx)(s,{className:`h-4 w-4 mr-1`}),`添加`]})]})]}),(0,E.jsxs)(Ce,{onClick:Dt,disabled:I,children:[(0,E.jsx)(Fe,{"data-icon":`inline-start`,className:`h-4 w-4`}),I?`保存中…`:`保存客户端名称`]})]}),(0,E.jsxs)(f,{value:`ai`,className:D,children:[(0,E.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(_,{className:`text-sm`,children:`启用 AI 功能`}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`启用智能代码修复功能`})]}),(0,E.jsx)(ae,{checked:N.enabled,onCheckedChange:e=>P({...N,enabled:e}),"aria-label":`启用 AI 功能`})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:k,children:[(0,E.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,E.jsx)(_,{className:`text-sm`,children:`AI 模型配置`}),(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:()=>{H({name:``,provider:`openai`,apiKey:``,baseUrl:`https://api.openai.com/v1/chat/completions`,model:`gpt-4o-mini`})},children:[(0,E.jsx)(s,{className:`h-4 w-4 mr-1`}),`添加模型`]})]}),(0,E.jsx)(`div`,{className:O,children:N.models&&N.models.length>0?N.models.map(e=>(0,E.jsx)(`div`,{className:`p-3 rounded-md border ${N.activeModelId===e.id?`border-primary bg-primary/5`:`border-border`}`,children:(0,E.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,E.jsxs)(`div`,{className:`flex-1`,children:[(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(`span`,{className:`font-medium text-sm`,children:e.name}),N.activeModelId===e.id&&(0,E.jsx)(Se,{variant:`default`,className:`text-xs`,children:`当前使用`})]}),(0,E.jsxs)(`p`,{className:`text-xs text-muted-foreground mt-1`,children:[e.provider===`openai`?`OpenAI`:`Anthropic`,` - `,e.model]})]}),(0,E.jsxs)(`div`,{className:`flex gap-1`,children:[N.activeModelId!==e.id&&(0,E.jsxs)(r,{variant:`ghost`,size:`xs`,onClick:()=>P(se(N,e.id)),children:[(0,E.jsx)(ee,{className:`h-3 w-3 mr-1`}),`使用`]}),(0,E.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>P(ce(N,e.id)),className:`text-destructive`,"aria-label":`删除模型`,children:(0,E.jsx)(ie,{className:`h-3 w-3`})})]})]})},e.id)):(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground italic py-4 text-center`,children:`暂无模型配置,点击"添加模型"创建`})}),V&&(0,E.jsxs)(`div`,{className:`space-y-5 rounded-md border border-primary bg-primary/5 p-4`,children:[(0,E.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,E.jsx)(_,{className:`text-sm font-medium`,children:`新增模型`}),(0,E.jsx)(r,{variant:`ghost`,size:`icon-xs`,onClick:()=>H(null),"aria-label":`关闭新增模型表单`,children:(0,E.jsx)(o,{className:`h-4 w-4`})})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`newModelName`,className:`text-xs`,children:`模型名称`}),(0,E.jsx)(g,{id:`newModelName`,value:V.name||``,onChange:e=>H({...V,name:e.target.value}),placeholder:`如:GPT-4o Mini`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-xs`,children:`服务商`}),(0,E.jsxs)(y,{type:`single`,value:V.provider,onValueChange:e=>{if(e===`openai`){let e=c(`openai`);H({...V,provider:`openai`,baseUrl:e.baseUrl,model:e.model})}else if(e===`anthropic`){let e=c(`anthropic`);H({...V,provider:`anthropic`,baseUrl:e.baseUrl,model:e.model})}},variant:`outline`,size:`sm`,spacing:0,children:[(0,E.jsx)(v,{value:`openai`,children:`OpenAI`}),(0,E.jsx)(v,{value:`anthropic`,children:`Anthropic`})]})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`newModelApiKey`,className:`text-xs`,children:`API Key`}),(0,E.jsx)(g,{id:`newModelApiKey`,type:F?`text`:`password`,value:V.apiKey||``,onChange:e=>H({...V,apiKey:e.target.value}),placeholder:`输入 API Key`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`newModelModel`,className:`text-xs`,children:`模型`}),(0,E.jsx)(g,{id:`newModelModel`,value:V.model||``,onChange:e=>H({...V,model:e.target.value}),placeholder:`模型名称`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`newModelBaseUrl`,className:`text-xs`,children:`API 端点`}),(0,E.jsx)(g,{id:`newModelBaseUrl`,value:V.baseUrl||``,onChange:e=>H({...V,baseUrl:e.target.value}),placeholder:`API 端点`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:`flex justify-end gap-2 pt-2`,children:[(0,E.jsx)(r,{variant:`outline`,size:`xs`,onClick:()=>H(null),children:`取消`}),(0,E.jsxs)(r,{size:`xs`,onClick:()=>{V.name&&V.apiKey&&V.model&&V.baseUrl&&(P(ue(N,V)),H(null))},disabled:!V.name||!V.apiKey||!V.model||!V.baseUrl,children:[(0,E.jsx)(s,{className:`h-3 w-3 mr-1`}),`添加`]})]})]})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(_,{className:`text-sm`,children:`传统配置(向后兼容)`}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`如果未配置多模型,将使用此配置`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{className:`text-xs`,children:`AI 服务商`}),(0,E.jsxs)(y,{type:`single`,value:N.provider,onValueChange:e=>{(e===`openai`||e===`anthropic`)&&xt(e)},variant:`outline`,size:`sm`,spacing:0,children:[(0,E.jsx)(v,{value:`openai`,children:`OpenAI`}),(0,E.jsx)(v,{value:`anthropic`,children:`Anthropic`})]})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`apiKey`,className:`text-xs`,children:`API Key`}),(0,E.jsxs)(`div`,{className:`flex gap-2`,children:[(0,E.jsx)(g,{id:`apiKey`,type:F?`text`:`password`,value:N.apiKey,onChange:e=>P({...N,apiKey:e.target.value}),placeholder:`输入 API Key`,className:`flex-1 h-8 text-sm`}),(0,E.jsx)(r,{variant:`outline`,size:`icon-sm`,onClick:()=>it(!F),"aria-label":F?`隐藏 API Key`:`显示 API Key`,children:F?(0,E.jsx)(Ye,{className:`h-4 w-4`}):(0,E.jsx)(Xe,{className:`h-4 w-4`})})]})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`model`,className:`text-xs`,children:`模型`}),(0,E.jsx)(g,{id:`model`,value:N.model,onChange:e=>P({...N,model:e.target.value}),placeholder:`模型名称`,className:`h-8 text-sm`})]}),(0,E.jsxs)(`div`,{className:O,children:[(0,E.jsx)(_,{htmlFor:`baseUrl`,className:`text-xs`,children:`API 端点`}),(0,E.jsx)(g,{id:`baseUrl`,value:N.baseUrl,onChange:e=>P({...N,baseUrl:e.target.value}),placeholder:N.provider===`openai`?`https://api.openai.com/v1/chat/completions`:`https://api.anthropic.com/v1/messages`,className:`h-8 text-sm`})]}),at&&(0,E.jsxs)(Ue,{variant:R===`error`?`destructive`:`default`,children:[R===`success`?(0,E.jsx)(b,{}):R===`error`?(0,E.jsx)(o,{}):(0,E.jsx)(a,{}),(0,E.jsx)(He,{children:R===`success`?`操作成功`:R===`error`?`操作失败`:`处理中`}),(0,E.jsx)(Ve,{children:at})]}),(0,E.jsx)(S,{}),(0,E.jsxs)(`div`,{className:`flex justify-between`,children:[(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:St,children:[(0,E.jsx)(ne,{className:`h-4 w-4 mr-1`}),`重置`]}),(0,E.jsxs)(`div`,{className:`flex gap-2`,children:[(0,E.jsx)(r,{variant:`outline`,size:`sm`,onClick:Ct,disabled:!l(N)||I,children:`测试连接`}),(0,E.jsxs)(Ce,{size:`sm`,onClick:$,disabled:I,children:[(0,E.jsx)(Fe,{"data-icon":`inline-start`,className:`h-4 w-4`}),I?`保存中…`:`保存`]})]})]})]})]})]});return n?(0,E.jsx)(`div`,{"data-testid":`settings-fullwidth`,className:`app-workspace-content flex h-full min-h-0 w-full flex-col overflow-hidden p-0`,children:(0,E.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border bg-card`,children:kt})}):(0,E.jsx)(we,{open:e,onOpenChange:t,children:(0,E.jsx)(ze,{className:`p-0 flex flex-col`,resizable:!0,defaultWidth:600,storageKey:`settings-panel`,children:kt})})}export{j as SettingsPanel};
|
package/web/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>web</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CSXxaYkG.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/button-BFNlGZ5p.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/dist-CFZ4xMSF.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/dist-C-E2R2jk.js">
|