@jonathanleelx/meddle 0.5.0-beta.20 → 0.5.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/core/config-diagnostics.d.ts.map +1 -1
  2. package/dist/core/config-diagnostics.js +6 -1
  3. package/dist/core/config-diagnostics.js.map +1 -1
  4. package/dist/core/mock-handler.d.ts +25 -0
  5. package/dist/core/mock-handler.d.ts.map +1 -1
  6. package/dist/core/mock-handler.js +79 -8
  7. package/dist/core/mock-handler.js.map +1 -1
  8. package/dist/server/config.d.ts.map +1 -1
  9. package/dist/server/config.js +41 -11
  10. package/dist/server/config.js.map +1 -1
  11. package/dist/server/mocks.d.ts +3 -0
  12. package/dist/server/mocks.d.ts.map +1 -1
  13. package/dist/server/mocks.js +3 -1
  14. package/dist/server/mocks.js.map +1 -1
  15. package/index.js +7 -0
  16. package/package.json +1 -1
  17. package/web/dist/assets/detail-panel-DK7pM43g.js +4 -0
  18. package/web/dist/assets/{global-panel-shell-dKKTLNpP.js → global-panel-shell-D32I98dR.js} +3 -3
  19. package/web/dist/assets/{health-panel-CUEWcU8g.js → health-panel-Dw7qdFVS.js} +1 -1
  20. package/web/dist/assets/index-CYUNdxqh.css +2 -0
  21. package/web/dist/assets/{index-B9-_OFNJ.js → index-CkoYwomI.js} +3 -3
  22. package/web/dist/assets/mobile-proxy-panel-DtiDkpAa.js +8 -0
  23. package/web/dist/assets/mock-config-C3jSpNNu.js +1 -0
  24. package/web/dist/assets/{mock-editor-panel-ttVorhGI.js → mock-editor-panel-ByCYWJjO.js} +2 -2
  25. package/web/dist/assets/{mocks-file-missing-note-DBYZjOpC.js → mocks-file-missing-note-DmrrCBYY.js} +1 -1
  26. package/web/dist/assets/{monaco-editor-DH2CE6FN.js → monaco-editor-6oLiu4W6.js} +1 -1
  27. package/web/dist/assets/{pane-split-40_YQZ0-.js → pane-split-DYB05onX.js} +1 -1
  28. package/web/dist/assets/panel-heading-BS8loc49.js +1 -0
  29. package/web/dist/assets/{plugin-code-editor-B2Sc5Ngy.js → plugin-code-editor-DGzCBEpg.js} +2 -2
  30. package/web/dist/assets/plugin-config-NVw234EF.js +2 -0
  31. package/web/dist/assets/{plugin-generator-B2CAEqPa.js → plugin-generator-Ba4hP5rg.js} +2 -2
  32. package/web/dist/assets/plugin-test-dialog-B4ojc2_9.js +7 -0
  33. package/web/dist/assets/{route-preview-Do3jsXLI.js → route-preview-BspvfNdW.js} +1 -1
  34. package/web/dist/assets/{rule-ai-assistant-panel-g-UkLb_B.js → rule-ai-assistant-panel-CQTsZMJu.js} +2 -2
  35. package/web/dist/assets/rule-config-DDOeMRXa.js +15 -0
  36. package/web/dist/assets/rule-overview-panel-CmWdMs4I.js +1 -0
  37. package/web/dist/assets/settings-panel-aB0ojA9D.js +1 -0
  38. package/web/dist/index.html +2 -2
  39. package/web/dist/assets/detail-panel-CO_7xRlW.js +0 -4
  40. package/web/dist/assets/index-D9jGD_NA.css +0 -2
  41. package/web/dist/assets/mobile-proxy-panel-smm4Pg7o.js +0 -8
  42. package/web/dist/assets/mock-config-BA0GNr6q.js +0 -1
  43. package/web/dist/assets/panel-heading-BaLG_KAE.js +0 -1
  44. package/web/dist/assets/plugin-config-nnVWs8jW.js +0 -2
  45. package/web/dist/assets/plugin-test-dialog-BU0As6z0.js +0 -7
  46. package/web/dist/assets/rule-config-Bzw8J0q1.js +0 -15
  47. package/web/dist/assets/rule-overview-panel-DIBRGnrb.js +0 -1
  48. package/web/dist/assets/settings-panel-CrvG4M_b.js +0 -1
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/plugin-generator-B2CAEqPa.js","assets/button-BFNlGZ5p.js","assets/index-B9-_OFNJ.js","assets/dist-DD7AvbXP.js","assets/dist-CFZ4xMSF.js","assets/dist-C-E2R2jk.js","assets/dist-BCvvYbmI.js","assets/dist-Bq2klZ3g.js","assets/dist-LiAcI8CK.js","assets/dist-UcOFuoN0.js","assets/dist-BNcjMpca.js","assets/es2015-CRmLuA2o.js","assets/dist-CRmX_NvH.js","assets/dist-YM3jbhT-.js","assets/check-BkfHQ6re.js","assets/chevron-down-DHwUtL4O.js","assets/ai-config-store-B_VpGvwx.js","assets/index-D9jGD_NA.css","assets/circle-x-BEkinhez.js","assets/code-DD-AYxxu.js","assets/copy-BRnscYy1.js","assets/wand-sparkles-DDGjzjnX.js","assets/editor-pane-actions-DN-pxFsl.js","assets/panel-heading-BaLG_KAE.js","assets/textarea-BjWF0pk4.js","assets/plugin-code-editor-B2Sc5Ngy.js","assets/monaco-editor-DH2CE6FN.js","assets/pencil-line-CEZ7D-de.js","assets/rotate-ccw-CRguJya4.js","assets/zap-CEVoVkAg.js","assets/plugin-test-dialog-BU0As6z0.js","assets/body-diff-view-ByCHr9bv.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{t as o}from"./zap-CEVoVkAg.js";import"./es2015-CRmLuA2o.js";import{t as s}from"./switch-DpLnRvOJ.js";import{$ as c,Dt as l,J as u,Q as d,X as ee,Y as te,Z as f,_t as p,dt as m,ft as h,gt as g,n as ne,nt as _,pt as re,rt as ie,wt as v,zt as y}from"./index-B9-_OFNJ.js";import{n as ae}from"./editor-pane-actions-DN-pxFsl.js";import{n as b,t as x}from"./pane-split-40_YQZ0-.js";var oe=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`}]]),S=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`}]]),C=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`}]]),w=n(t(),1),T=x({storageKey:`meddle-plugin-list-width`,defaultPx:360,minPx:280,maxPx:560,editorMinPx:420});T.storageKey,T.defaultPx;var E=e(),se=(0,w.lazy)(()=>y(()=>import(`./plugin-generator-B2CAEqPa.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]))),ce=(0,w.lazy)(()=>y(()=>import(`./plugin-code-editor-B2Sc5Ngy.js`).then(e=>({default:e.PluginCodeEditor})),__vite__mapDeps([25,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,26,27,28,29,22,23,24]))),le=(0,w.lazy)(()=>y(()=>import(`./plugin-test-dialog-BU0As6z0.js`).then(e=>({default:e.PluginTestDialog})),__vite__mapDeps([30,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,26,31,32,33,18,27,34,21,22,23,24])));function D(){return(0,E.jsxs)(`div`,{className:`flex h-full min-h-[160px] items-center justify-center gap-2 text-sm text-muted-foreground`,children:[(0,E.jsx)(l,{className:`size-4 animate-spin`}),`加载编辑器...`]})}function O({plugins:e,pluginMode:t,switchPluginMode:n,fetchPlugins:i,startPlugin:g,stopPlugin:v,togglePlugin:y,thirdPartyPlugins:x,thirdPartySecurity:O,fetchThirdPartyPlugins:j,loadThirdPartyPlugin:M,unloadThirdPartyPlugin:pe}){let[P,F]=(0,w.useState)(!1),[I,L]=(0,w.useState)(``),[R,z]=(0,w.useState)(!1),[B,me]=(0,w.useState)([]),[V,H]=(0,w.useState)(!1),[U,W]=(0,w.useState)({kind:`idle`}),[he,ge]=(0,w.useState)(null),G=(0,w.useRef)(null),_e=(0,w.useCallback)(e=>{G.current=e},[]),ve=(0,w.useCallback)(()=>{if(G.current){G.current();return}W({kind:`idle`})},[]);(0,w.useEffect)(()=>{i(),j(),K()},[i,j]),(0,w.useEffect)(()=>{let e=()=>{K()};return window.addEventListener(`plugins-custom-updated`,e),()=>window.removeEventListener(`plugins-custom-updated`,e)},[]);let K=async()=>{try{me((await(await fetch(`/api/plugins/custom`)).json()).plugins||[])}catch(e){console.error(`加载自定义插件失败:`,e)}},ye=async(e,t)=>{if(confirm(`确定要删除插件 ${e} 吗?`))try{let n=await fetch(`/api/plugins/custom/${encodeURIComponent(e)}`,{method:`DELETE`});if(n.ok)W(n=>n.kind===`code`&&n.filename===e||n.kind===`test`&&(n.filename===e||t!==void 0&&n.pluginId===t)?{kind:`idle`}:n),await K();else{let e=await n.json();alert(e.error||`删除失败`)}}catch(e){console.error(`删除插件失败:`,e),alert(`删除失败`)}},q=async(e,t)=>{if(confirm(`插件文件已删除,确定要从内存卸载 ${t} 吗?`))try{let t=await fetch(`/api/plugins/custom/loaded/${encodeURIComponent(e)}/unload`,{method:`POST`});if(t.ok)W(t=>(t.kind===`test`||t.kind===`builtin`)&&t.pluginId===e?{kind:`idle`}:t),await i(),await K();else{let e=await t.json().catch(()=>({}));alert(e.error||`卸载失败`)}}catch(e){console.error(`卸载插件失败:`,e),alert(`卸载失败`)}},be=async()=>{H(!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 K()}else{let t=await e.json();alert(t.error||`热加载失败`)}}catch(e){console.error(`热加载失败:`,e),alert(`热加载失败`)}finally{H(!1)}},xe=async e=>{F(!0);try{await g(e),await i()}finally{F(!1)}},Se=async e=>{F(!0);try{await v(e),await i()}finally{F(!1)}},J=async()=>{if(I.trim()){z(!0);try{await M(I),L(``),await j()}finally{z(!1)}}},Ce=async e=>{z(!0);try{await pe(e),await j(),U.kind===`third-party`&&U.pluginId===e&&W({kind:`idle`})}finally{z(!1)}},{builtinPlugins:Y,customRows:X}=ne(e,B,new Set(x.map(e=>e.id))),Z=U.kind===`builtin`?e.find(e=>e.id===U.pluginId):void 0,Q=Z?X.find(e=>e.fileDeleted&&e.pluginId===Z.id):void 0,$=U.kind===`third-party`?x.find(e=>e.id===U.pluginId):void 0,we=U.kind===`generate`?`编辑插件 · AI 生成`:U.kind===`code`?`编辑插件 · ${U.filename}`:U.kind===`test`?`编辑插件 · 测试 ${U.pluginName}`:U.kind===`builtin`?`编辑插件 · ${Z?.name||U.pluginId}`:U.kind===`third-party`?`编辑插件 · ${$?.name||U.pluginId}`:U.kind===`load-third-party`?`编辑插件 · 加载第三方`:`编辑插件`,Te=U.kind===`code`||U.kind===`generate`||U.kind===`test`;return(0,E.jsxs)(b,{testId:`plugin-config-layout`,layout:`list-edit`,widthAttr:`plugin-list-width`,split:T,listTestId:`plugin-config-list`,panelTestId:`plugin-config-edit`,separatorTestId:`plugin-panel-separator`,separatorLabel:`调整插件列表宽度`,list:(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`div`,{className:`shrink-0 border-b`,children:[(0,E.jsxs)(`div`,{className:`app-pane-bar flex items-center justify-between gap-2`,children:[(0,E.jsx)(`div`,{className:`text-[10px] font-medium uppercase tracking-wide text-muted-foreground`,children:`插件`}),(0,E.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,E.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void K(),disabled:P||V,"aria-label":`刷新列表`,children:(0,E.jsx)(a,{})}),(0,E.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void be(),disabled:P||V,"aria-label":`热加载插件`,children:V?(0,E.jsx)(l,{className:`animate-spin`}):(0,E.jsx)(o,{})}),(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:()=>W({kind:`generate`}),"data-testid":`plugin-config-generate`,children:[(0,E.jsx)(p,{"data-icon":`inline-start`}),`AI 生成`]})]})]}),(0,E.jsxs)(`div`,{className:`flex items-center gap-2 px-[var(--ui-section-gap)] pb-[var(--ui-section-gap)]`,children:[(0,E.jsxs)(u,{value:t,onValueChange:e=>n(e),children:[(0,E.jsx)(d,{className:`h-7 w-full text-xs`,"aria-label":`插件模式`,children:(0,E.jsx)(c,{})}),(0,E.jsx)(te,{children:(0,E.jsxs)(ee,{children:[(0,E.jsx)(f,{value:`off`,children:`关闭`}),(0,E.jsx)(f,{value:`on`,children:`开启`}),(0,E.jsx)(f,{value:`shadow`,children:`影子模式`})]})})]}),t===`off`?(0,E.jsx)(_,{variant:`destructive`,className:`shrink-0 text-xs`,children:`未生效`}):null]})]}),(0,E.jsxs)(`div`,{"data-plugin-row-list":``,className:`meddle-thin-scroll min-h-0 flex-1 overflow-x-hidden overflow-y-auto`,children:[(0,E.jsx)(k,{title:`内置插件`,children:Y.length===0?(0,E.jsx)(A,{children:`暂无内置插件`}):Y.map(e=>(0,E.jsx)(N,{testId:`plugin-config-row-builtin-${e.id}`,selected:U.kind===`builtin`&&U.pluginId===e.id,title:e.name,meta:e.version,onSelect:()=>W({kind:`builtin`,pluginId:e.id}),badge:(0,E.jsx)(_,{variant:e.state===`running`?`default`:`secondary`,children:e.state})},e.id))}),(0,E.jsx)(k,{title:`自定义插件`,children:X.length===0?(0,E.jsx)(A,{children:`暂无自定义插件,点击「AI 生成」`}):X.map(({filename:e,pluginId:t,loadedPlugin:n,fileDeleted:i})=>{let a=n?n.state!==`disabled`:!1,o=i?(U.kind===`builtin`||U.kind===`test`)&&U.pluginId===t:U.kind===`code`&&U.filename===e||U.kind===`test`&&(U.filename===e||U.pluginId===t),c=n?a?`已启用`:`已禁用`:`未加载`;return(0,E.jsx)(N,{testId:i?`plugin-config-row-custom-deleted-${t}`:`plugin-config-row-custom-${e}`,selected:o,title:e,meta:c,muted:!!n&&!a,onSelect:()=>W(i?{kind:`builtin`,pluginId:t}:{kind:`code`,filename:e}),badge:(0,E.jsxs)(E.Fragment,{children:[i?(0,E.jsxs)(`span`,{"data-testid":`plugin-file-deleted-label`,className:`mr-1 inline-flex items-center gap-1 text-xs text-muted-foreground`,children:[(0,E.jsx)(m,{"aria-hidden":`true`,className:`size-3.5 shrink-0`}),`文件已删除`]}):null,n?(0,E.jsx)(s,{checked:a,onCheckedChange:e=>y(n.id,e),"aria-label":`启用插件 ${e}`}):(0,E.jsx)(_,{variant:`outline`,children:`未加载`})]}),action:(0,E.jsxs)(`div`,{className:`flex items-center`,children:[n&&a&&!i&&(0,E.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>W({kind:`test`,pluginId:n.id,pluginName:n.name,hooks:n.hooks,filename:e}),"aria-label":`测试插件 ${n.name}`,children:(0,E.jsx)(re,{})}),i?(0,E.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void q(t,e),"aria-label":`卸载插件 ${e}`,"aria-description":`文件已删除,仅从内存移除`,title:`卸载`,children:(0,E.jsx)(C,{})}):(0,E.jsx)(r,{variant:`ghost`,size:`icon-sm`,onClick:()=>void ye(e,n?.id),className:`text-destructive`,"aria-label":`删除插件 ${e}`,children:(0,E.jsx)(h,{})})]})},i?`loaded:${t}`:e)})}),(0,E.jsx)(k,{title:`第三方插件`,extra:(0,E.jsxs)(`span`,{className:`inline-flex items-center gap-1 normal-case tracking-normal`,children:[O.allowAll?(0,E.jsx)(S,{className:`size-3.5 text-primary`}):(0,E.jsx)(oe,{className:`size-3.5`}),O.allowAll?`已信任所有插件`:`已信任 ${O.trusted.length} 个`]}),action:(0,E.jsx)(r,{variant:`ghost`,size:`xs`,onClick:()=>W({kind:`load-third-party`}),"data-testid":`plugin-config-load`,children:`加载`}),children:x.length===0?(0,E.jsx)(A,{children:`暂无第三方插件`}):x.map(e=>(0,E.jsx)(N,{testId:`plugin-config-row-third-${e.id}`,selected:U.kind===`third-party`&&U.pluginId===e.id,title:e.name,meta:e.version,onSelect:()=>W({kind:`third-party`,pluginId:e.id}),badge:(0,E.jsx)(_,{variant:e.state===`running`?`default`:`secondary`,children:e.state})},e.id))})]})]}),children:[(0,E.jsxs)(`div`,{className:`app-pane-bar flex shrink-0 flex-wrap items-center justify-between gap-x-3 gap-y-2 border-b`,children:[(0,E.jsx)(`div`,{className:`min-w-0 truncate text-[10px] font-medium uppercase tracking-wide text-muted-foreground`,children:we}),(0,E.jsxs)(`div`,{className:`ml-auto flex min-w-0 max-w-full flex-wrap items-center justify-end gap-2`,children:[U.kind===`idle`?null:(0,E.jsx)(r,{variant:`ghost`,size:`sm`,onClick:ve,children:`取消`}),(0,E.jsx)(`div`,{ref:ge,"data-testid":`editor-pane-actions`,className:`contents`})]})]}),(0,E.jsx)(ae,{host:he,registerDismiss:_e,children:(0,E.jsx)(`div`,{className:Te?`min-h-0 flex-1 overflow-hidden`:`min-h-0 flex-1 overflow-y-auto`,children:U.kind===`idle`?(0,E.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,E.jsx)(`p`,{children:`选择左侧插件进行编辑,或点击「AI 生成」`}),(0,E.jsx)(`p`,{className:`text-xs`,children:`自定义插件在右侧编辑代码;内置和第三方插件在右侧查看并操作`})]}):U.kind===`generate`?(0,E.jsx)(w.Suspense,{fallback:(0,E.jsx)(D,{}),children:(0,E.jsx)(se,{embedded:!0,plainHeading:!0,onOpenChange:e=>{e||W({kind:`idle`})},onPluginSaved:()=>{i(),K()}})}):U.kind===`code`?(0,E.jsx)(w.Suspense,{fallback:(0,E.jsx)(D,{}),children:(0,E.jsx)(ce,{embedded:!0,plainHeading:!0,filename:U.filename,onOpenChange:e=>{e||W({kind:`idle`})},onSaved:()=>{i()}},U.filename)}):U.kind===`test`?(0,E.jsx)(w.Suspense,{fallback:(0,E.jsx)(D,{}),children:(0,E.jsx)(le,{embedded:!0,plainHeading:!0,pluginId:U.pluginId,pluginName:U.pluginName,hooks:U.hooks,filename:U.filename,onOpenChange:e=>{e||W({kind:`idle`})},onPluginFixed:()=>{i()}},U.pluginId)}):U.kind===`builtin`&&Z?(0,E.jsx)(de,{plugin:Z,...Q?{note:ue,onUnload:()=>void q(Q.pluginId,Q.filename)}:{},loading:P,onStart:()=>void xe(Z.id),onStop:()=>void Se(Z.id)}):U.kind===`third-party`&&$?(0,E.jsx)(fe,{plugin:$,loading:R,onUnload:()=>void Ce($.id)}):U.kind===`load-third-party`?(0,E.jsxs)(`div`,{className:`flex flex-col gap-[var(--ui-section-gap)] p-[var(--ui-section-gap)]`,children:[(0,E.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`输入插件文件或目录路径后加载。`}),(0,E.jsxs)(`div`,{className:`flex gap-2`,children:[(0,E.jsx)(ie,{value:I,onChange:e=>L(e.target.value),placeholder:`输入插件路径...`,className:`flex-1`,"aria-label":`第三方插件路径`}),(0,E.jsx)(r,{onClick:()=>void J(),disabled:R||!I.trim(),children:R?(0,E.jsx)(l,{className:`animate-spin`}):`加载`})]})]}):null})})]})}function k({title:e,extra:t,action:n,children:r}){return(0,E.jsxs)(`section`,{children:[(0,E.jsxs)(`div`,{className:`flex items-center justify-between gap-2 border-b px-[var(--ui-section-gap)] py-1.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground`,children:[(0,E.jsx)(`span`,{className:`truncate`,children:e}),(0,E.jsxs)(`span`,{className:`flex shrink-0 items-center gap-2`,children:[t,n]})]}),r]})}function A({children:e}){return(0,E.jsx)(`div`,{className:`px-[var(--ui-section-gap)] py-6 text-center text-sm text-muted-foreground`,children:e})}function j(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 M=`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 N({testId:e,selected:t,title:n,meta:r,muted:i,badge:a,action:o,onSelect:s}){return(0,E.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 ${M} ${i?`opacity-60`:``}`,onClick:s,children:[(0,E.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:j,children:[(0,E.jsx)(`span`,{className:`block truncate text-sm font-medium`,children:n}),r?(0,E.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:r}):null]}),(0,E.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1`,onClick:e=>e.stopPropagation(),onKeyDown:e=>e.stopPropagation(),children:[a,o]})]})}var ue=`插件文件已删除,无法编辑或测试。可以卸载它,或者恢复文件后重新加载`;function de({plugin:e,note:t,loading:n,onStart:i,onStop:a,onUnload:o}){return(0,E.jsxs)(`div`,{className:`flex flex-col gap-[var(--ui-section-gap)] p-[var(--ui-section-gap)]`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`div`,{className:`text-sm font-medium`,children:e.name}),(0,E.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[e.id,` · `,e.version]})]}),t?(0,E.jsx)(`p`,{"data-testid":`plugin-detail-note`,className:`text-xs text-muted-foreground`,children:t}):null,(0,E.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:e.hooks.length===0?(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`无 hooks`}):e.hooks.map(e=>(0,E.jsx)(_,{variant:`secondary`,className:`text-xs`,children:e},e))}),(0,E.jsx)(`div`,{children:o?(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:o,disabled:n,"aria-label":`卸载插件 ${e.name}`,children:[(0,E.jsx)(C,{"data-icon":`inline-start`}),`卸载`]}):e.state===`running`?(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:a,disabled:n,"aria-label":`停止插件 ${e.name}`,children:[(0,E.jsx)(g,{"data-icon":`inline-start`}),`停止`]}):(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:i,disabled:n,"aria-label":`启动插件 ${e.name}`,children:[(0,E.jsx)(v,{"data-icon":`inline-start`}),`启动`]})})]})}function fe({plugin:e,loading:t,onUnload:n}){return(0,E.jsxs)(`div`,{className:`flex flex-col gap-[var(--ui-section-gap)] p-[var(--ui-section-gap)]`,children:[(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`div`,{className:`text-sm font-medium`,children:e.name}),(0,E.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[e.id,` · `,e.version,` · `,e.state]})]}),(0,E.jsx)(`div`,{children:(0,E.jsxs)(r,{variant:`outline`,size:`sm`,onClick:n,disabled:t,className:`text-destructive`,"aria-label":`卸载插件 ${e.name}`,children:[(0,E.jsx)(h,{"data-icon":`inline-start`}),`卸载`]})})]})}export{O as PluginConfig};
@@ -1,7 +0,0 @@
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-DDGjzjnX.js";import"./es2015-CRmLuA2o.js";import{i as re,o as ie,r as ae}from"./ai-config-store-B_VpGvwx.js";import{A as c,At as oe,Dt as l,E as se,Ft as u,I as d,L as f,Mt as ce,P as p,Pt as le,T as ue,mt as de,nt as m,rt as fe,t as pe,w as h}from"./index-B9-_OFNJ.js";import{t as g}from"./body-diff-view-ByCHr9bv.js";import{n as me,t as he}from"./monaco-editor-DH2CE6FN.js";import{i as ge,t as _e}from"./editor-pane-actions-DN-pxFsl.js";import{t as ve}from"./panel-heading-BaLG_KAE.js";import{t as ye}from"./textarea-BjWF0pk4.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)(m,{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 S({open:e=!1,onOpenChange:t,embedded:n=!1,plainHeading:i=!1,pluginId:y,pluginName:b,hooks:x,filename:S,onPluginFixed:Ce}){let[C,we]=(0,_.useState)(!1),[w,T]=(0,_.useState)(!1),[E,Te]=(0,_.useState)(`https://365.wps.cn/home`),[D,Ee]=(0,_.useState)(`GET`),[O,De]=(0,_.useState)(`standalone`),[k,A]=(0,_.useState)(null),[j,Oe]=(0,_.useState)(`split`),[M,ke]=(0,_.useState)(`inline`),[N,P]=(0,_.useState)(null),[F,I]=(0,_.useState)(``),[L,R]=(0,_.useState)(``),[z,Ae]=(0,_.useState)(!1),[B,V]=(0,_.useState)(null),[H,U]=(0,_.useState)(``),[je,W]=(0,_.useState)(`normal`),[G,Me]=(0,_.useState)(``),[K,q]=(0,_.useState)(`idle`),J=ae(),Y=re(J),Ne=Y?{provider:Y.provider,apiKey:Y.apiKey,baseUrl:Y.baseUrl,model:Y.model}:{provider:J.provider,apiKey:J.apiKey,baseUrl:J.baseUrl,model:J.model},X=ie(J),Z=S||pe({id:y}),Pe=n||e,Q=(0,_.useCallback)(async()=>{if(!Z||!Pe){I(``),R(``),V(null);return}Ae(!0),V(null);try{let e=await fetch(`/api/plugins/custom/${encodeURIComponent(Z)}/code`);if(!e.ok){let t=await e.json();throw Error(t.error||`读取插件源码失败`)}let t=await e.json();I(t.code||``),!w&&!H&&R(t.code||``)}catch(e){I(``),R(``),V(e instanceof Error?e.message:`读取插件源码失败`)}finally{Ae(!1)}},[Z,w,H,Pe]);(0,_.useEffect)(()=>{Q()},[Q]);let $=(0,_.useMemo)(()=>{let e=[];return k?.error&&e.push({hookName:`test`,message:k.error}),Object.entries(k?.hookResults||{}).forEach(([t,n])=>{n?.status===`error`&&e.push({hookName:t,message:n.error||`未知错误`,stack:n.stack})}),k?.realRequest?.fetchError&&e.push({hookName:`fetch`,message:k.realRequest.fetchError}),e},[k]),Fe=$.length>0&&!!Z,Ie=!!L&&!!(H||K===`idle`&&L&&F&&L!==F),Le=async(e,t,n)=>{q(`saving`);let r=await fetch(`/api/plugins/custom/${encodeURIComponent(Z)}/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||`保存修复后的代码失败`)}q(`reloading`);let i=await fetch(`/api/plugins/reload`,{method:`POST`});if(!i.ok){let e=await i.json().catch(()=>({error:`热加载失败`}));throw Error(e.error||`热加载失败`)}I(e),U(e),W(`diff`),window.dispatchEvent(new CustomEvent(`plugins-custom-updated`)),Ce?.(),n&&(q(`retesting`),await Re()),P({status:`success`,message:t}),q(`idle`)},Re=async()=>{we(!0),A(null),P(null);try{let e=await fetch(`/api/plugins/test`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pluginId:y,url:E,method:D,integrated:O===`integrated`})});if(!e.ok){let t=await e.json();throw Error(t.error||`测试失败`)}A((await e.json()).results)}catch(e){A({error:e instanceof Error?e.message:`测试失败`})}finally{we(!1)}},ze=async()=>{if(!(!Fe||!X)){T(!0),P(null),U(``),R(F);try{q(`generating`);let e={code:F};if(!e.code)throw Error(`插件源码为空,无法修复`);let t=$.map(e=>`Hook: ${e.hookName}\nError: ${e.message}${e.stack?`\nStack:\n${e.stack}`:``}`).join(`
2
-
3
- ---
4
-
5
- `),n=await fetch(`/api/plugins/fix-stream`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({originalCode:e.code,testError:t,requirement:{name:b,description:`修复插件 ${b} 在测试中的报错,并保持现有 hooks 行为正确。Hooks: ${x.join(`, `)}`,hooks:x},aiConfig:Ne})});if(!n.ok){let e=await n.json();throw Error(e.error||`AI 修复失败`)}let r=n.body?.getReader(),i=new TextDecoder;if(!r)throw Error(`无法读取 AI 修复流`);let a=``,o=``;for(;;){let{done:e,value:t}=await r.read();if(e)break;o+=i.decode(t,{stream:!0});let n=o.split(`
6
- `);o=n.pop()||``;for(let e of n){if(!e.startsWith(`data:`))continue;let t=e.slice(5).trim();if(t)try{let e=JSON.parse(t);if(e.status===`generating`)P({status:`success`,message:`AI 正在分析错误并生成修复代码...`});else if(e.chunk)a=e.accumulated||`${a}${e.chunk}`,U(a);else if(e.status===`success`)a=e.fixedCode||a,U(a);else if(e.error)throw Error(e.error)}catch(e){if(e instanceof Error&&e.message!==`Unexpected end of JSON input`)throw e}}}if(!a||typeof a!=`string`)throw Error(`AI 未返回有效代码`);P({status:`success`,message:`AI 已生成修复代码,正在保存、热加载并重新测试...`}),await Le(a,`AI 已修复插件代码并完成热加载,测试结果已刷新。`,!0)}catch(e){P({status:`error`,message:e instanceof Error?e.message:`AI 修复失败`})}finally{q(`idle`),T(!1)}}},Be=async()=>{if(!(!Z||!G.trim()||!X||w)){T(!0),P(null),U(``),R(F);try{q(`generating`);let e=await fetch(`/api/plugins/revise-stream`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({originalCode:F,instruction:G.trim(),requirement:{name:b,description:`根据额外要求更新插件 ${b},并保持 hooks 行为正确。Hooks: ${x.join(`, `)}`,hooks:x},aiConfig:Ne})});if(!e.ok){let t=await e.json();throw Error(t.error||`AI 更新代码失败`)}let t=e.body?.getReader(),n=new TextDecoder;if(!t)throw Error(`无法读取 AI 更新流`);let r=``,i=``;for(;;){let{done:e,value:a}=await t.read();if(e)break;i+=n.decode(a,{stream:!0});let o=i.split(`
7
- `);i=o.pop()||``;for(let e of o){if(!e.startsWith(`data:`))continue;let t=e.slice(5).trim();if(t)try{let e=JSON.parse(t);if(e.status===`generating`)P({status:`success`,message:`AI 正在根据额外要求更新插件代码...`});else if(e.chunk)r=e.accumulated||`${r}${e.chunk}`,U(r),W(`diff`);else if(e.status===`success`)r=e.revisedCode||r,U(r),W(`diff`);else if(e.error)throw Error(e.error)}catch(e){if(e instanceof Error&&e.message!==`Unexpected end of JSON input`)throw e}}}if(!r||typeof r!=`string`)throw Error(`AI 未返回有效代码`);P({status:`success`,message:`AI 已生成更新后的代码,正在保存并热加载...`}),await Le(r,`AI 已根据额外要求更新插件代码并完成热加载。`,!1),Me(``)}catch(e){P({status:`error`,message:e instanceof Error?e.message:`AI 更新代码失败`})}finally{q(`idle`),T(!1)}}},Ve=ge(),He=(0,v.jsxs)(v.Fragment,{children:[i?null:(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(ve,{className:`px-6 pt-6 pb-4`,title:(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(de,{className:`h-5 w-5`}),`测试插件: `,b]}),description:`发起真实 HTTP 请求,在请求/响应过程中运行插件代码`}),(0,v.jsx)(h,{})]}),(0,v.jsxs)(`div`,{className:`app-panel-content`,children:[(0,v.jsxs)(`div`,{className:`app-section`,children:[(0,v.jsxs)(`div`,{className:`app-field-group`,children:[(0,v.jsx)(c,{htmlFor:`testUrl`,children:`请求 URL`}),(0,v.jsx)(fe,{id:`testUrl`,value:E,onChange:e=>Te(e.target.value),placeholder:`https://example.com/page`,disabled:C})]}),(0,v.jsxs)(`div`,{className:`app-field-group`,children:[(0,v.jsx)(c,{children:`HTTP 方法`}),(0,v.jsx)(`div`,{className:`flex gap-2`,children:[`GET`,`POST`,`PUT`,`DELETE`].map(e=>(0,v.jsx)(r,{type:`button`,variant:D===e?`selected`:`outline`,size:`sm`,onClick:()=>Ee(e),disabled:C,children:e},e))})]}),(0,v.jsxs)(`div`,{className:`app-field-group`,children:[(0,v.jsx)(c,{children:`测试模式`}),(0,v.jsxs)(`div`,{className:`flex gap-2 flex-wrap`,children:[(0,v.jsx)(r,{type:`button`,variant:O===`standalone`?`selected`:`outline`,size:`sm`,onClick:()=>De(`standalone`),disabled:C,title:`直接请求 URL,不走路由与 Mock,便于排查插件自身逻辑`,children:`单独测试`}),(0,v.jsx)(r,{type:`button`,variant:O===`integrated`?`selected`:`outline`,size:`sm`,onClick:()=>De(`integrated`),disabled:C,title:`与真实代理一致:先路由解析、Mock 匹配,再请求,便于排查整体链路`,children:`集成测试`})]}),(0,v.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:O===`standalone`?`直接请求上述 URL,不经过路由规则和 Mock,适合验证插件逻辑。`:`先按路由规则解析目标、匹配 Mock,再请求,与经代理的真实请求一致,适合排查链路问题。`})]}),(0,v.jsx)(`div`,{className:`bg-blue-50 dark:bg-blue-950/20 border border-blue-200 dark:border-blue-900 rounded-md p-3`,children:(0,v.jsxs)(`p`,{className:`text-xs text-blue-700 dark:text-blue-300`,children:[(0,v.jsx)(`strong`,{children:`测试流程:`}),` 发起真实请求 → 获取服务器响应 → 运行插件 Hook(`,x.join(`, `),`)→ 展示对比结果`]})})]}),!!Z&&(0,v.jsxs)(`div`,{className:`space-y-3`,children:[(0,v.jsx)(h,{}),(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(le,{className:`h-4 w-4`}),`插件代码`]}),(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(p,{value:je,onValueChange:e=>W(e),children:(0,v.jsxs)(d,{className:`h-7`,children:[(0,v.jsx)(f,{value:`normal`,className:`px-2 text-xs`,children:`正常视图`}),(0,v.jsx)(f,{value:`diff`,className:`px-2 text-xs`,disabled:!Ie,children:`Diff 视图`})]})}),(0,v.jsx)(m,{variant:`outline`,className:`text-xs font-normal`,children:Z}),(0,v.jsx)(r,{size:`sm`,variant:`ghost`,onClick:Q,disabled:z||w,children:z?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(l,{className:`h-4 w-4 mr-1 animate-spin`}),`读取中`]}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(te,{className:`h-4 w-4 mr-1`}),`刷新代码`]})})]})]}),B?(0,v.jsx)(`div`,{className:`rounded-md border border-red-200 bg-red-50/80 p-3 text-sm text-red-700 dark:border-red-900 dark:bg-red-950/20 dark:text-red-300`,children:B}):je===`diff`&&Ie?(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`左侧是原代码,右侧是 AI 修复后的代码`}),K!==`idle`&&(0,v.jsx)(m,{variant:`outline`,className:`text-xs font-normal`,children:Se(K)})]}),(0,v.jsx)(he,{original:L||F,modified:H||F,language:`javascript`,minHeight:`320px`})]}):(0,v.jsx)(me,{value:w&&H?H:F,onChange:()=>{},language:`javascript`,readOnly:!0,minHeight:`260px`}),(0,v.jsxs)(`div`,{className:`space-y-2 pt-2`,children:[(0,v.jsx)(c,{htmlFor:`plugin-extra-instruction`,children:`额外信息`}),(0,v.jsx)(ye,{id:`plugin-extra-instruction`,value:G,onChange:e=>Me(e.target.value),placeholder:`例如:补充 onBeforeResponse 里对 JSON 响应的判空逻辑;保留现有 hooks 和 manifest,不要改插件 id。`,className:`min-h-[88px]`,disabled:w||z}),(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`输入额外要求后,AI 会基于当前插件代码直接更新并热加载。`}),(0,v.jsx)(r,{size:`sm`,variant:`outline`,onClick:Be,disabled:!Z||!G.trim()||!X||w||z||!!B,children:w&&K!==`retesting`?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(l,{className:`h-4 w-4 mr-1 animate-spin`}),`AI 更新中...`]}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(ee,{className:`h-4 w-4 mr-1`}),`根据额外信息更新代码`]})})]})]})]})]}),k&&(0,v.jsxs)(`div`,{className:`space-y-3`,children:[(0,v.jsx)(h,{}),k.error?(0,v.jsx)(`div`,{className:`bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900 rounded-md p-3`,children:(0,v.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,v.jsx)(s,{className:`h-4 w-4 text-red-600 mt-0.5 shrink-0`}),(0,v.jsx)(`span`,{className:`text-sm text-red-700 dark:text-red-300`,children:k.error})]})}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsxs)(`div`,{className:`flex flex-wrap gap-4 items-center rounded-md border bg-muted/20 px-3 py-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Header 对比`}),(0,v.jsx)(p,{value:j,onValueChange:e=>Oe(e),children:(0,v.jsxs)(d,{className:`h-7`,children:[(0,v.jsx)(f,{value:`split`,className:`px-2 text-xs`,children:`分栏`}),(0,v.jsx)(f,{value:`inline`,className:`px-2 text-xs`,children:`行内`})]})})]}),(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Body 对比`}),(0,v.jsx)(p,{value:M,onValueChange:e=>ke(e),children:(0,v.jsxs)(d,{className:`h-7`,children:[(0,v.jsx)(f,{value:`inline`,className:`px-2 text-xs`,children:`行内`}),(0,v.jsx)(f,{value:`split`,className:`px-2 text-xs`,children:`分栏`})]})})]})]}),k.realRequest&&(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(oe,{className:`h-4 w-4`}),`真实请求`,k.realRequest.testMode&&(0,v.jsx)(m,{variant:`outline`,className:`text-xs font-normal`,children:k.realRequest.testMode===`integrated`?`集成测试`:`单独测试`})]}),(0,v.jsxs)(`div`,{className:`bg-muted/50 rounded-md p-3 text-xs space-y-1`,children:[(0,v.jsxs)(`div`,{className:`flex gap-2`,children:[(0,v.jsx)(m,{variant:`outline`,className:`text-xs`,children:k.realRequest.method}),(0,v.jsx)(`span`,{className:`font-mono break-all`,children:k.realRequest.url})]}),k.realRequest.fetchError?(0,v.jsxs)(`div`,{className:`text-red-600 flex items-center gap-1 mt-1`,children:[(0,v.jsx)(s,{className:`h-3 w-3`}),`请求失败: `,k.realRequest.fetchError]}):(0,v.jsxs)(`div`,{className:`text-muted-foreground space-y-0.5`,children:[(0,v.jsxs)(`div`,{children:[`耗时: `,k.realRequest.fetchDuration,`ms`,k.originalResponse&&(0,v.jsxs)(v.Fragment,{children:[` · 状态码: `,(0,v.jsx)(m,{variant:`outline`,className:`text-xs`,children:k.originalResponse.statusCode}),` · 响应大小: `,k.originalResponse.bodyLength,` 字符`]})]}),(k.realRequest.targetResolved||k.realRequest.usedMock)&&(0,v.jsxs)(`div`,{className:`flex flex-wrap gap-1 mt-1`,children:[k.realRequest.targetResolved&&(0,v.jsx)(m,{variant:`outline`,className:`text-xs text-blue-600 border-blue-300`,children:`路由已改写`}),k.realRequest.usedMock&&(0,v.jsx)(m,{variant:`outline`,className:`text-xs text-orange-600 border-orange-300`,children:`已使用 Mock`})]})]})]})]}),(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(de,{className:`h-4 w-4`}),`Hook 执行结果`]}),Object.keys(k.hookResults||{}).length===0?(0,v.jsx)(`div`,{className:`text-xs text-muted-foreground bg-muted/50 rounded-md p-3`,children:`没有 Hook 被执行`}):(0,v.jsx)(`div`,{className:`space-y-2`,children:Object.entries(k.hookResults||{}).map(([e,t])=>(0,v.jsxs)(`div`,{className:`border rounded-md p-3 ${t.status===`success`?`bg-green-50 dark:bg-green-950/20 border-green-200 dark:border-green-900`:`bg-red-50 dark:bg-red-950/20 border-red-200 dark:border-red-900`}`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[t.status===`success`?(0,v.jsx)(u,{className:`h-4 w-4 text-green-600`}):(0,v.jsx)(s,{className:`h-4 w-4 text-red-600`}),(0,v.jsx)(`span`,{className:`font-medium text-sm`,children:e})]}),t.duration!==void 0&&(0,v.jsxs)(m,{variant:`outline`,className:`text-xs`,children:[t.duration,`ms`]})]}),t.status===`error`&&(0,v.jsxs)(`div`,{className:`mt-2 space-y-2`,children:[(0,v.jsxs)(`div`,{className:`rounded-md border border-red-200 bg-red-100/60 px-2 py-2 text-xs text-red-800 dark:border-red-900 dark:bg-red-950/20 dark:text-red-300`,children:[(0,v.jsx)(`div`,{className:`font-medium mb-1`,children:`错误原因`}),(0,v.jsx)(`pre`,{className:`font-mono whitespace-pre-wrap break-all`,children:t.error})]}),t.stack&&(0,v.jsxs)(`details`,{className:`rounded-md border border-red-200 bg-background/60 px-2 py-2 text-xs dark:border-red-900`,children:[(0,v.jsx)(`summary`,{className:`cursor-pointer text-red-700 dark:text-red-300`,children:`查看错误堆栈`}),(0,v.jsx)(`pre`,{className:`font-mono whitespace-pre-wrap break-all mt-2 text-muted-foreground`,children:t.stack})]})]}),t.targetChanged&&(0,v.jsxs)(`div`,{className:`text-xs text-blue-700 mt-1 flex items-center gap-1`,children:[(0,v.jsx)(a,{className:`h-3 w-3`}),`Target 已修改为: `,t.targetChanged]})]},e))})]}),$.length>0&&(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(o,{className:`h-4 w-4 text-red-500`}),`错误详情`]}),(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[!X&&(0,v.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`AI 未配置,无法自动修复`}),(0,v.jsx)(r,{size:`sm`,variant:`outline`,onClick:ze,disabled:!Fe||!X||w||C,children:w?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(l,{className:`h-4 w-4 mr-1 animate-spin`}),`AI 修复中...`]}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(ne,{className:`h-4 w-4 mr-1`}),`AI 修复并更新代码`]})})]})]}),(0,v.jsx)(`div`,{className:`space-y-2`,children:$.map((e,t)=>(0,v.jsxs)(`div`,{className:`rounded-md border border-red-200 bg-red-50/80 p-3 dark:border-red-900 dark:bg-red-950/20`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2 mb-2`,children:[(0,v.jsx)(m,{variant:`outline`,className:`text-xs`,children:e.hookName}),(0,v.jsx)(`span`,{className:`text-xs text-red-700 dark:text-red-300`,children:`错误原因`})]}),(0,v.jsx)(`pre`,{className:`text-xs font-mono whitespace-pre-wrap break-all text-red-800 dark:text-red-300`,children:e.message}),e.stack&&(0,v.jsxs)(`details`,{className:`mt-2 text-xs`,children:[(0,v.jsx)(`summary`,{className:`cursor-pointer text-muted-foreground`,children:`查看完整堆栈`}),(0,v.jsx)(`pre`,{className:`font-mono whitespace-pre-wrap break-all mt-2 text-muted-foreground`,children:e.stack})]})]},`${e.hookName}-${t}`))}),N&&(0,v.jsx)(`div`,{className:`rounded-md border px-3 py-2 text-sm ${N.status===`success`?`border-green-200 bg-green-50 text-green-700 dark:border-green-900 dark:bg-green-950/20 dark:text-green-300`:`border-red-200 bg-red-50 text-red-700 dark:border-red-900 dark:bg-red-950/20 dark:text-red-300`}`,children:(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[N.status===`success`?(0,v.jsx)(te,{className:`h-4 w-4`}):(0,v.jsx)(le,{className:`h-4 w-4`}),(0,v.jsx)(`span`,{children:N.message})]})})]}),(k.requestHeadersChanged||k.requestBodyChanged)&&k.originalRequest&&k.modifiedRequest&&(0,v.jsxs)(`div`,{className:`space-y-3`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(ce,{className:`h-4 w-4`}),`请求对比(已被插件修改)`]}),k.requestHeadersChanged&&(0,v.jsxs)(`div`,{className:`space-y-1`,children:[(0,v.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`Request Headers`}),(0,v.jsx)(xe,{original:k.originalRequest.headers,modified:k.modifiedRequest.headers,mode:j})]}),k.requestBodyChanged&&(0,v.jsxs)(`div`,{className:`space-y-1`,children:[(0,v.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`Request Body`}),(0,v.jsx)(g,{original:k.originalRequest.body||``,modified:k.modifiedRequest.body||``,mode:M,maxHeight:`180px`})]})]}),k.responseHeadersChanged&&k.originalResponse?.headers&&k.modifiedResponse?.headers&&(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(o,{className:`h-4 w-4 text-orange-500`}),`Response Headers 对比(已被插件修改)`]}),(0,v.jsx)(xe,{original:k.originalResponse.headers,modified:k.modifiedResponse.headers,mode:j})]}),k.modifiedResponse&&k.originalResponse&&(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[k.modifiedResponse.bodyChanged?(0,v.jsx)(o,{className:`h-4 w-4 text-orange-500`}):(0,v.jsx)(u,{className:`h-4 w-4 text-muted-foreground`}),`响应 Body`,k.modifiedResponse.bodyChanged?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(m,{className:`text-xs bg-orange-100 text-orange-700 border-orange-300`,children:`已修改`}),(0,v.jsxs)(`span`,{className:`text-[10px] text-muted-foreground`,children:[`(差异 `,k.modifiedResponse.bodyLength-k.originalResponse.bodyLength>0?`+`:``,k.modifiedResponse.bodyLength-k.originalResponse.bodyLength,` 字符)`]})]}):(0,v.jsx)(m,{variant:`outline`,className:`text-xs text-muted-foreground`,children:`未变化`})]}),k.modifiedResponse.bodyChanged?(0,v.jsxs)(`div`,{className:`space-y-1`,children:[(0,v.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`绿色=新增行,红色=删除行。仅对比前约 2500 字符以保障性能。`}),(0,v.jsx)(g,{original:k.originalResponse.bodyForDiff??k.originalResponse.bodyPreview??``,modified:k.modifiedResponse.bodyForDiff??k.modifiedResponse.bodyPreview??``,mode:M,maxHeight:`320px`})]}):(0,v.jsx)(`pre`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[200px] overflow-auto whitespace-pre-wrap break-all`,children:k.originalResponse.bodyPreview})]}),k.shortCircuited&&k.shortCircuitResponse&&(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(o,{className:`h-4 w-4 text-blue-500`}),`插件短路了请求(未发起真实请求)`]}),(0,v.jsx)(`div`,{className:`bg-blue-50 dark:bg-blue-950/20 border border-blue-200 dark:border-blue-900 rounded-md p-3`,children:(0,v.jsxs)(`div`,{className:`text-xs`,children:[(0,v.jsxs)(`div`,{children:[`状态码: `,k.shortCircuitResponse.statusCode]}),(0,v.jsx)(`pre`,{className:`mt-2 font-mono whitespace-pre-wrap break-all max-h-[200px] overflow-auto`,children:k.shortCircuitResponse.body})]})})]}),k.logs&&k.logs.length>0&&(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsx)(`h3`,{className:`text-sm font-medium`,children:`插件日志`}),(0,v.jsx)(`div`,{className:`bg-muted rounded-md p-3 max-h-[200px] overflow-auto`,children:(0,v.jsx)(`div`,{className:`space-y-1`,children:k.logs.map((e,t)=>(0,v.jsxs)(`div`,{className:`text-xs font-mono`,children:[(0,v.jsxs)(`span`,{className:`inline-block w-12 ${e.level===`error`?`text-red-600`:e.level===`warn`?`text-yellow-600`:e.level===`info`?`text-blue-600`:`text-muted-foreground`}`,children:[`[`,e.level,`]`]}),(0,v.jsx)(`span`,{className:`text-foreground`,children:e.message})]},t))})})]})]})]})]}),Ve?null:(0,v.jsx)(h,{}),(0,v.jsxs)(_e,{className:`px-6 py-4 flex justify-between gap-2`,children:[Ve?null:(0,v.jsx)(r,{variant:`outline`,size:`sm`,onClick:()=>t?.(!1),disabled:C,children:`关闭`}),(0,v.jsx)(r,{size:`sm`,onClick:Re,disabled:C,children:C?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(l,{className:`h-4 w-4 mr-1 animate-spin`}),`请求中...`]}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(be,{className:`h-4 w-4 mr-1`}),`发起测试请求`]})})]})]});return n?(0,v.jsx)(`div`,{className:`flex h-full min-h-0 flex-col`,children:He}):(0,v.jsx)(ue,{open:e,onOpenChange:e=>t?.(e),children:(0,v.jsx)(se,{className:`p-0 flex flex-col`,resizable:!0,defaultWidth:900,storageKey:`plugin-test`,children:He})})}export{S as PluginTestDialog};