@jonathanleelx/meddle 0.5.0 → 0.5.1
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/bin/commands/mock/add.js +22 -0
- package/bin/commands/mock/index.js +51 -21
- package/bin/commands/route/add.js +2 -2
- package/bin/commands/route/delete.js +2 -2
- package/bin/commands/route/index.js +60 -30
- package/bin/commands/route/preview.js +2 -2
- package/bin/commands/route/show.js +2 -2
- package/bin/commands/route/update.js +2 -2
- package/bin/commands/status.js +27 -11
- package/bin/doctor.js +8 -4
- package/bin/index.js +4 -4
- package/bin/lib/file-access.js +28 -11
- package/bin/lib/meddle-home.js +14 -1
- package/bin/lib/output.js +8 -3
- package/bin/lib/proxy-or-file.js +4 -1
- package/dist/cert.d.ts +2 -0
- package/dist/cert.d.ts.map +1 -1
- package/dist/cert.js +10 -1
- package/dist/cert.js.map +1 -1
- package/dist/core/browser.d.ts +2 -0
- package/dist/core/browser.d.ts.map +1 -1
- package/dist/core/browser.js +21 -8
- package/dist/core/browser.js.map +1 -1
- package/dist/core/mock-handler.d.ts +5 -1
- package/dist/core/mock-handler.d.ts.map +1 -1
- package/dist/core/mock-handler.js +17 -3
- package/dist/core/mock-handler.js.map +1 -1
- package/dist/core/proxy-record.d.ts +14 -0
- package/dist/core/proxy-record.d.ts.map +1 -1
- package/dist/core/proxy-record.js +39 -0
- package/dist/core/proxy-record.js.map +1 -1
- package/dist/core/types.d.ts +2 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/config.js +15 -9
- package/dist/server/config.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +7 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/json-parse-error.d.ts +7 -0
- package/dist/server/json-parse-error.d.ts.map +1 -0
- package/dist/server/json-parse-error.js +28 -0
- package/dist/server/json-parse-error.js.map +1 -0
- package/dist/server/mocks.d.ts +1 -1
- package/dist/server/mocks.d.ts.map +1 -1
- package/dist/server/rule-files.d.ts.map +1 -1
- package/dist/server/rule-files.js +2 -9
- package/dist/server/rule-files.js.map +1 -1
- package/index.js +92 -9
- package/mcp-server.js +18 -5
- package/package.json +1 -1
- package/web/dist/assets/detail-panel-DZRKJG2W.js +4 -0
- package/web/dist/assets/global-panel-shell-Iir-c_pQ.js +6 -0
- package/web/dist/assets/{health-panel-DhXLqcOU.js → health-panel-Dmf-EhJz.js} +1 -1
- package/web/dist/assets/{index-B-6nUrqW.js → index-C4dIj1nT.js} +5 -5
- package/web/dist/assets/index-CdYMl1M7.css +2 -0
- package/web/dist/assets/{mobile-proxy-panel-BY8Oi-qC.js → mobile-proxy-panel-CFcwa11A.js} +5 -5
- package/web/dist/assets/{mock-config-TPmfJwAt.js → mock-config-CGl50MIr.js} +1 -1
- package/web/dist/assets/mock-editor-panel-xcCk23oH.js +20 -0
- package/web/dist/assets/{mocks-file-missing-note-BR5oWFLh.js → mocks-file-missing-note-CW_ONVLA.js} +1 -1
- package/web/dist/assets/{monaco-editor-BGLPrb0C.js → monaco-editor-BkP7envQ.js} +1 -1
- package/web/dist/assets/{pane-bar-gFRISZLD.js → pane-bar-5j9Nf7W_.js} +1 -1
- package/web/dist/assets/{pane-split-B6aLmY7G.js → pane-split-C0OSe365.js} +1 -1
- package/web/dist/assets/panel-heading-izT5q0ZN.js +1 -0
- package/web/dist/assets/plugin-code-editor-DKE9dFEE.js +2 -0
- package/web/dist/assets/plugin-config-Cg09TsuV.js +2 -0
- package/web/dist/assets/{plugin-generator-Bj4f6dxo.js → plugin-generator-CT1f1tu0.js} +2 -2
- package/web/dist/assets/plugin-test-dialog-BbLIMnkJ.js +7 -0
- package/web/dist/assets/route-preview-CKO7nF4W.js +1 -0
- package/web/dist/assets/{rule-ai-assistant-panel-BEfPNBbx.js → rule-ai-assistant-panel-CtfUqdYG.js} +2 -2
- package/web/dist/assets/rule-config-Cb4ejIXI.js +15 -0
- package/web/dist/assets/rule-overview-panel-xtHTS27O.js +1 -0
- package/web/dist/assets/settings-panel-CpQuE6nr.js +1 -0
- package/web/dist/index.html +2 -2
- package/web/dist/assets/detail-panel-BtgWWeu3.js +0 -4
- package/web/dist/assets/global-panel-shell-NaUhzX7J.js +0 -6
- package/web/dist/assets/index-EWNlAdFB.css +0 -2
- package/web/dist/assets/mock-editor-panel-WQwcHSTD.js +0 -20
- package/web/dist/assets/panel-heading-DT_nXayM.js +0 -1
- package/web/dist/assets/plugin-code-editor--Gf4ZwGb.js +0 -2
- package/web/dist/assets/plugin-config-DsX9xCW_.js +0 -2
- package/web/dist/assets/plugin-test-dialog-DICuykBK.js +0 -7
- package/web/dist/assets/route-preview-C-LzS1lT.js +0 -1
- package/web/dist/assets/rule-config-Dw9pcuah.js +0 -15
- package/web/dist/assets/rule-overview-panel-C4QQ7U3S.js +0 -1
- package/web/dist/assets/settings-panel-D8DEH8aH.js +0 -1
|
@@ -0,0 +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"./check-BkfHQ6re.js";import{t as s}from"./chevron-down-DHwUtL4O.js";import{t as c}from"./circle-x-BEkinhez.js";import{n as l,t as u}from"./server-eYXq3PbE.js";import{t as d}from"./copy-BRnscYy1.js";import{t as f}from"./shield-check-hQXjdfZ7.js";import{t as ee}from"./wand-sparkles-Bmt4dDOf.js";import"./es2015-DPJTBYa9.js";import{n as p}from"./toast-9yeTf7d9.js";import{$ as m,C as te,Ct as h,E as ne,I as g,L as _,M as v,N as y,Nt as b,P as x,Pt as S,R as C,S as re,St as w,T as ie,_t as T,j as E,kt as D,x as O}from"./index-C4dIj1nT.js";import{n as k,t as A}from"./body-diff-view-SfLCLzs9.js";import{n as j,t as M}from"./syntax-highlight-BFgN_C0Y.js";import{t as N}from"./clipboard-Bt1qY01V.js";var P=i(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),ae=i(`corner-down-right`,[[`path`,{d:`m15 10 5 5-5 5`,key:`qqa56n`}],[`path`,{d:`M4 4v7a4 4 0 0 0 4 4h12`,key:`z08zvw`}]]),oe=i(`flag`,[[`path`,{d:`M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528`,key:`1jaruq`}]]),F=i(`route`,[[`circle`,{cx:`6`,cy:`19`,r:`3`,key:`1kj8tv`}],[`path`,{d:`M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15`,key:`1d8sl`}],[`circle`,{cx:`18`,cy:`5`,r:`3`,key:`gq8acd`}]]),I=n(t(),1);function L(e){return Object.entries(e||{}).map(([e,t])=>`${e}: ${t}`).join(`
|
|
2
|
+
`)}var R=e(),z=2e3;function B({text:e,label:t}){let[n,i]=(0,I.useState)(!1),a=(0,I.useRef)(null);async function s(){try{await N(e),i(!0),a.current&&clearTimeout(a.current),a.current=setTimeout(()=>i(!1),z),p.success(`已复制${t}`)}catch{p.error(`复制${t}失败,请手动选择复制`)}}return(0,R.jsxs)(r,{variant:`ghost`,size:`xs`,className:`text-[11px] text-muted-foreground hover:text-foreground`,"aria-label":n?`复制${t}成功`:`复制${t}`,onClick:()=>void s(),children:[n?(0,R.jsx)(o,{className:`h-3 w-3 mr-1 text-green-600`}):(0,R.jsx)(d,{className:`h-3 w-3 mr-1`}),n?`已复制`:`复制`]})}function V({body:e}){let[t,n]=(0,I.useState)(`source`),r=(0,I.useMemo)(()=>M(e||``)===`json`,[e]),i=(0,I.useMemo)(()=>{if(!r)return e;try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}},[e,r]),a=(0,I.useMemo)(()=>j(t===`formatted`?i:e,r?`json`:void 0),[e,i,t,r]);return e?(0,R.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between`,children:[r?(0,R.jsx)(E,{value:t,onValueChange:e=>n(e),className:`w-fit`,children:(0,R.jsxs)(y,{className:`h-6 px-1`,children:[(0,R.jsx)(x,{value:`source`,className:`h-6 px-2 text-[11px]`,children:`源数据`}),(0,R.jsx)(x,{value:`formatted`,className:`h-6 px-2 text-[11px]`,children:`格式化`})]})}):(0,R.jsx)(`span`,{}),(0,R.jsx)(B,{text:e,label:`Body`})]}),(0,R.jsx)(`div`,{className:`font-mono text-xs bg-muted/30 rounded p-2 overflow-x-auto`,children:(0,R.jsx)(`pre`,{className:`whitespace-pre`,children:a})})]}):(0,R.jsx)(`p`,{className:`text-sm text-muted-foreground py-2`,children:`无内容`})}function H({headers:e}){let t=Object.entries(e||{});return t.length===0?(0,R.jsx)(`p`,{className:`text-sm text-muted-foreground py-2`,children:`无头部信息`}):(0,R.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,R.jsx)(`div`,{className:`flex justify-end`,children:(0,R.jsx)(B,{text:L(e),label:`Headers`})}),(0,R.jsx)(`div`,{className:`font-mono text-xs space-y-0.5`,children:t.map(([e,t])=>(0,R.jsxs)(`div`,{className:`flex gap-2 py-0.5 hover:bg-muted/50 px-1 rounded`,children:[(0,R.jsxs)(`span`,{className:`text-purple-600 shrink-0 font-semibold`,children:[e,`:`]}),(0,R.jsx)(`span`,{className:`text-foreground/80 break-all`,children:t})]},e))})]})}function U(e){return e>=200&&e<300?`bg-green-100 text-green-800`:e>=300&&e<400?`bg-blue-100 text-blue-800`:e>=400&&e<500?`bg-amber-100 text-amber-800`:e>=500?`bg-red-100 text-red-800`:``}function W(e){switch(e){case`ok`:return`bg-green-100 text-green-800 border-green-200`;case`error`:return`bg-red-100 text-red-800 border-red-200`;case`skipped`:return`bg-amber-100 text-amber-800 border-amber-200`;case`short-circuited`:return`bg-blue-100 text-blue-800 border-blue-200`;default:return``}}function G(e){switch(e){case`ok`:return`通过`;case`error`:return`异常`;case`skipped`:return`跳过`;case`short-circuited`:return`已短路返回`;default:return e}}function K(e){switch(e){case`builtin`:return`内置`;case`custom`:return`自定义`;case`system`:return`系统`;default:return e}}function q(e){return e.replace(/^builtin\./,``).replace(/^custom\./,``)}function se(e,t){return`${t}-${e.hook}-${e.name}`}function J(e){return e===`onBeforeResponse`||e===`onAfterResponse`?`response`:`request`}function ce(e,t){return Array.from(new Set([...Object.keys(e),...Object.keys(t)])).sort().map(n=>({key:n,before:e[n]??``,after:t[n]??``})).filter(e=>e.before!==e.after)}function Y({lines:e,className:t}){return e.length===0?(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`无变更`}):(0,R.jsx)(`div`,{className:`rounded-lg border bg-muted/20 p-2 text-xs font-mono space-y-1 ${t||``}`,children:e.map((e,t)=>(0,R.jsxs)(`div`,{className:`whitespace-pre-wrap break-all px-2 py-1 rounded ${e.type===`added`?`bg-green-500/10 text-green-700 dark:text-green-300`:`bg-red-500/10 text-red-700 dark:text-red-300`}`,children:[(0,R.jsx)(`span`,{className:`mr-1`,children:e.type===`added`?`+ `:`- `}),e.text]},`${e.type}-${t}-${e.text}`))})}function X(e,t,n){let r=[];return t!==void 0&&t!==``&&r.push({type:`removed`,text:`${e} ${t}`}),n!==void 0&&n!==``&&r.push({type:`added`,text:`${e} ${n}`}),r}function le(e,t){let n=[];return e!==void 0&&e!==``&&n.push({type:`removed`,text:e}),t!==void 0&&t!==``&&n.push({type:`added`,text:t}),n}function ue(e){let t=e.replace(/\r\n/g,`
|
|
3
|
+
`).split(`
|
|
4
|
+
`);return t[t.length-1]===``&&t.pop(),t.length>0?t:[``]}function Z(e){if(!e)return!1;if(/^\(binary(?:,\s*\d+\s+bytes)?\)$/i.test(e.trim()))return!0;let t=0;for(let n=0;n<e.length;n+=1){let r=e.charCodeAt(n);r===9||r===10||r===13||(r<32||r===65533)&&(t+=1)}return t>0&&t/Math.max(e.length,1)>.15}function Q({before:e,after:t}){let[n,i]=(0,I.useState)(!1),a=(0,I.useMemo)(()=>ce(e,t),[e,t]),o=(0,I.useMemo)(()=>a.flatMap(e=>X(e.key,e.before,e.after)),[a]);return o.length===0?(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`无变更`}):(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(0,R.jsx)(Y,{lines:o}),(0,R.jsxs)(r,{variant:`ghost`,size:`xs`,onClick:()=>i(e=>!e),children:[n?(0,R.jsx)(s,{className:`h-3.5 w-3.5 mr-1`}):(0,R.jsx)(P,{className:`h-3.5 w-3.5 mr-1`}),n?`收起完整头部`:`展开完整头部`]}),n&&(0,R.jsxs)(`div`,{className:`grid gap-2 md:grid-cols-2`,children:[(0,R.jsxs)(`div`,{className:`rounded-lg bg-muted/50 p-2 text-xs font-mono`,children:[(0,R.jsx)(`div`,{className:`text-[11px] text-muted-foreground mb-1`,children:`变更前`}),(0,R.jsx)(H,{headers:e})]}),(0,R.jsxs)(`div`,{className:`rounded-lg bg-muted/50 p-2 text-xs font-mono`,children:[(0,R.jsx)(`div`,{className:`text-[11px] text-muted-foreground mb-1`,children:`变更后`}),(0,R.jsx)(H,{headers:t})]})]})]})}function de({before:e,after:t}){let[n,i]=(0,I.useState)(!1),a=(0,I.useMemo)(()=>k(e||``,t||``).filter(e=>e.added||e.removed),[e,t]),o=(0,I.useMemo)(()=>Z(e||``)||Z(t||``),[e,t]),c=(0,I.useMemo)(()=>o?le(e||``,t||``):a.flatMap(e=>ue(e.value).map(t=>({type:e.added?`added`:`removed`,text:t}))),[e,t,a,o]);return c.length===0?(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`无变更`}):(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,R.jsx)(B,{text:e,label:`变更前 Body`}),(0,R.jsx)(B,{text:t,label:`变更后 Body`})]}),(0,R.jsx)(Y,{lines:c,className:`meddle-thin-scroll max-h-40 overflow-auto`}),!o&&(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(r,{variant:`ghost`,size:`xs`,onClick:()=>i(e=>!e),children:[n?(0,R.jsx)(s,{className:`h-3.5 w-3.5 mr-1`}):(0,R.jsx)(P,{className:`h-3.5 w-3.5 mr-1`}),n?`收起完整 Diff`:`展开完整 Diff`]}),n&&(0,R.jsx)(A,{original:e,modified:t,mode:`inline`,maxHeight:`220px`})]})]})}function fe({stage:e}){let t=e.changes;return t?(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(t.targetBefore||t.targetAfter)&&(0,R.jsxs)(`div`,{className:`rounded-lg bg-muted/50 p-2`,children:[(0,R.jsx)(`div`,{className:`text-[11px] text-muted-foreground mb-2`,children:`Request URL diff`}),(0,R.jsx)(Y,{lines:X(`Request URL`,t.targetBefore,t.targetAfter||t.target)})]}),(t.requestHeadersBefore||t.requestHeadersAfter)&&(0,R.jsxs)(`div`,{className:`rounded-lg bg-muted/50 p-2`,children:[(0,R.jsx)(`div`,{className:`text-[11px] text-muted-foreground mb-2`,children:`Request header diff`}),(0,R.jsx)(Q,{before:t.requestHeadersBefore||{},after:t.requestHeadersAfter||{}})]}),(t.responseStatusCodeBefore!==void 0||t.responseStatusCodeAfter!==void 0)&&(0,R.jsxs)(`div`,{className:`rounded-lg bg-muted/50 p-2`,children:[(0,R.jsx)(`div`,{className:`text-[11px] text-muted-foreground mb-2`,children:`Response status diff`}),(0,R.jsx)(Y,{lines:X(`Response Status`,t.responseStatusCodeBefore,t.responseStatusCodeAfter??t.responseStatusCode)})]}),(t.responseHeadersBefore||t.responseHeadersAfter)&&(0,R.jsxs)(`div`,{className:`rounded-lg bg-muted/50 p-2`,children:[(0,R.jsx)(`div`,{className:`text-[11px] text-muted-foreground mb-2`,children:`Response header diff`}),(0,R.jsx)(Q,{before:t.responseHeadersBefore||{},after:t.responseHeadersAfter||{}})]}),(t.responseBodyBefore!==void 0||t.responseBodyAfter!==void 0)&&(0,R.jsxs)(`div`,{className:`rounded-lg bg-muted/50 p-2`,children:[(0,R.jsx)(`div`,{className:`text-[11px] text-muted-foreground mb-2`,children:`Response body diff`}),(0,R.jsx)(de,{before:t.responseBodyBefore||``,after:t.responseBodyAfter||t.responseBody||``})]})]}):null}function pe({stage:e,index:t,isLast:n,accentClass:i}){let[a,o]=(0,I.useState)(e.status!==`skipped`);return(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(0,R.jsxs)(`div`,{className:`rounded-xl border bg-background/90 p-3 space-y-3`,children:[(0,R.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,R.jsxs)(`div`,{className:`space-y-1 min-w-0`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,R.jsx)(r,{variant:`ghost`,size:`icon-xs`,onClick:()=>o(e=>!e),title:a?`收起`:`展开`,"aria-label":a?`收起`:`展开`,children:a?(0,R.jsx)(s,{className:`h-3.5 w-3.5`}):(0,R.jsx)(P,{className:`h-3.5 w-3.5`})}),(0,R.jsxs)(`span`,{className:`font-medium text-sm`,children:[t+1,`. `,q(e.name)]}),(0,R.jsx)(m,{variant:`outline`,className:`text-xs font-normal`,children:e.hook}),(0,R.jsx)(m,{variant:`outline`,className:`text-xs font-normal`,children:K(e.type)})]}),(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e.status===`short-circuited`?`这一阶段直接生成了响应,请求不会继续往后转发。`:e.status===`error`?`这一阶段执行失败,影响了后续处理流程。`:`这一阶段执行完成,请求继续进入下一步。`})]}),(0,R.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,R.jsx)(m,{className:`text-xs border ${W(e.status)}`,children:G(e.status)}),(0,R.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.duration,`ms`]})]})]}),a&&(0,R.jsxs)(R.Fragment,{children:[e.target&&(0,R.jsxs)(`div`,{className:`rounded-lg bg-muted/50 p-2`,children:[(0,R.jsx)(`div`,{className:`text-[11px] text-muted-foreground mb-1`,children:`当前 target`}),(0,R.jsx)(`div`,{className:`font-mono text-xs break-all`,children:e.target})]}),(0,R.jsx)(fe,{stage:e}),e.error&&(0,R.jsxs)(`div`,{className:`rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700`,children:[`Error: `,e.error]})]})]}),!n&&(0,R.jsx)(`div`,{className:`flex justify-center py-1`,children:(0,R.jsxs)(`div`,{className:`flex flex-col items-center gap-1`,children:[(0,R.jsx)(`div`,{className:`h-2.5 w-2.5 rounded-full ${i} animate-pulse`}),(0,R.jsx)(b,{className:`h-4 w-4 ${i} animate-bounce`})]})})]})}function $({title:e,description:t,stages:n,icon:r,roleLabel:i,roleIcon:a,accentClass:o}){return(0,R.jsxs)(`div`,{className:`rounded-xl border bg-card p-4`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`flex items-center gap-2 mb-2`,children:(0,R.jsxs)(m,{variant:`outline`,className:`text-[11px] font-normal`,children:[(0,R.jsx)(`span`,{className:`mr-1`,children:a}),i]})}),(0,R.jsxs)(`h4`,{className:`text-sm font-semibold flex items-center gap-2`,children:[(0,R.jsx)(`span`,{className:o,children:r}),e]}),(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground mt-1`,children:t})]}),(0,R.jsxs)(m,{variant:`outline`,className:`text-xs`,children:[n.length,` 个阶段`]})]}),n.length===0?(0,R.jsx)(`p`,{className:`text-sm text-muted-foreground py-4 text-center`,children:`无阶段信息`}):(0,R.jsx)(`div`,{className:`space-y-3`,children:n.map(({stage:e,index:t},r)=>(0,R.jsx)(pe,{stage:e,index:t,isLast:r===n.length-1,accentClass:o},se(e,t)))})]})}function me(e){let t=[...e.stages].reverse().find(e=>e.status===`short-circuited`);if(t)return{label:`提前返回响应`,description:`在 ${q(t.name)} 阶段直接生成响应`,icon:(0,R.jsx)(ae,{className:`h-4 w-4 text-blue-500`})};let n=[...e.stages].reverse().find(e=>e.status===`error`);return n?{label:`处理过程中出现异常`,description:`${q(n.name)} 执行失败`,icon:(0,R.jsx)(c,{className:`h-4 w-4 text-red-500`})}:{label:`进入正常代理流程`,description:`请求经过检查后继续转发到目标服务`,icon:(0,R.jsx)(a,{className:`h-4 w-4 text-emerald-500`})}}function he({inspection:e}){let t=me(e),n=e.stages.map((e,t)=>({stage:e,index:t})),r=n.filter(({stage:e})=>J(e.hook)===`request`),i=n.filter(({stage:e})=>J(e.hook)===`response`);return(0,R.jsxs)(`div`,{className:`space-y-4 pt-3`,children:[(0,R.jsxs)(`div`,{className:`rounded-xl border bg-gradient-to-br from-muted/20 via-background to-muted/10 p-4 space-y-4`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-4 text-sm`,children:[(0,R.jsx)(m,{variant:`outline`,className:`font-mono`,children:e.method}),(0,R.jsx)(`span`,{className:`font-mono text-muted-foreground truncate flex-1`,children:e.url}),(0,R.jsxs)(`div`,{className:`flex items-center gap-1 text-muted-foreground`,children:[(0,R.jsx)(l,{className:`h-3.5 w-3.5`}),(0,R.jsxs)(`span`,{className:`text-xs`,children:[e.totalDuration,`ms`]})]})]}),(0,R.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-3`,children:[(0,R.jsxs)(`div`,{className:`rounded-lg border bg-background/80 p-3`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground mb-1`,children:[(0,R.jsx)(F,{className:`h-3.5 w-3.5`}),`请求入口`]}),(0,R.jsx)(`div`,{className:`text-sm font-medium`,children:`请求进入代理`}),(0,R.jsx)(`div`,{className:`text-xs text-muted-foreground mt-1`,children:`从浏览器或客户端发起,进入 Meddle 的处理流水线`})]}),(0,R.jsxs)(`div`,{className:`rounded-lg border bg-background/80 p-3`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground mb-1`,children:[(0,R.jsx)(f,{className:`h-3.5 w-3.5`}),`处理阶段`]}),(0,R.jsxs)(`div`,{className:`text-sm font-medium`,children:[e.stages.length,` 个阶段`]}),(0,R.jsx)(`div`,{className:`text-xs text-muted-foreground mt-1`,children:`按实际执行顺序记录插件和系统模块对请求的处理`})]}),(0,R.jsxs)(`div`,{className:`rounded-lg border bg-background/80 p-3`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground mb-1`,children:[t.icon,`最终结果`]}),(0,R.jsx)(`div`,{className:`text-sm font-medium`,children:t.label}),(0,R.jsx)(`div`,{className:`text-xs text-muted-foreground mt-1`,children:t.description})]})]})]}),e.stages.length===0?(0,R.jsx)(`p`,{className:`text-sm text-muted-foreground py-4 text-center`,children:`无处理阶段信息(插件模式可能未开启)`}):(0,R.jsxs)(`div`,{className:`space-y-4`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,R.jsx)(oe,{className:`h-3.5 w-3.5`}),(0,R.jsx)(`span`,{children:`默认仅展示改动内容;跳过阶段默认折叠,可单独展开查看更多。`})]}),(0,R.jsxs)(`div`,{className:`grid gap-4 xl:grid-cols-2`,children:[(0,R.jsx)($,{title:`请求阶段`,description:`客户端请求进入代理后,按顺序执行请求侧处理阶段`,stages:r,icon:(0,R.jsx)(F,{className:`h-4 w-4 text-blue-500`}),roleLabel:`客户端`,roleIcon:(0,R.jsx)(w,{className:`h-3 w-3 text-blue-500`}),accentClass:`text-blue-500`}),(0,R.jsx)($,{title:`响应阶段`,description:`服务器响应返回代理后,按顺序执行响应侧处理阶段`,stages:i,icon:(0,R.jsx)(S,{className:`h-4 w-4 text-emerald-500`}),roleLabel:`服务器`,roleIcon:(0,R.jsx)(u,{className:`h-3 w-3 text-emerald-500`}),accentClass:`text-emerald-500`})]}),(0,R.jsxs)(`div`,{className:`flex items-center justify-center gap-2 text-xs text-muted-foreground`,children:[(0,R.jsx)(`span`,{children:`请求进入`}),(0,R.jsx)(a,{className:`h-4 w-4 animate-pulse text-blue-500`}),(0,R.jsx)(`span`,{children:`请求阶段`}),(0,R.jsx)(a,{className:`h-4 w-4 animate-pulse text-violet-500`}),(0,R.jsx)(`span`,{children:`响应阶段`}),(0,R.jsx)(a,{className:`h-4 w-4 animate-pulse text-emerald-500`}),(0,R.jsx)(`span`,{children:`最终返回`})]})]})]})}function ge(e){return e==null?`—`:e<1e3?`${e} ms`:`${(e/1e3).toFixed(1)} s`}function _e({record:e,detail:t}){let n=g(e),r=Object.entries(t.requestHeaders||{}).slice(0,6),i=n.kind===`rule`?`source: ${e.source}\ntarget: ${e.target}`:n.kind===`mock`?`mock: true · ${e.source}`:`pass · ${e.source}`;return(0,R.jsxs)(`div`,{className:`space-y-3 pt-3`,"data-testid":`detail-overview-hit`,children:[(0,R.jsxs)(`div`,{className:`grid grid-cols-[72px_1fr] gap-x-3 gap-y-1.5 text-xs`,children:[(0,R.jsx)(`div`,{className:`text-muted-foreground`,children:`方法`}),(0,R.jsx)(`div`,{className:`font-mono font-medium`,children:e.method}),(0,R.jsx)(`div`,{className:`text-muted-foreground`,children:`URL`}),(0,R.jsx)(`div`,{className:`break-all font-mono`,children:e.source}),(0,R.jsx)(`div`,{className:`text-muted-foreground`,children:`状态`}),(0,R.jsxs)(`div`,{className:`font-mono`,children:[t.statusCode,` `,t.statusMessage]}),t.error&&(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`div`,{className:`text-muted-foreground`,children:`出错原因`}),(0,R.jsx)(`div`,{className:`break-all font-mono text-destructive`,"data-testid":`detail-upstream-error`,children:t.error})]}),(0,R.jsx)(`div`,{className:`text-muted-foreground`,children:`延迟`}),(0,R.jsx)(`div`,{className:`font-mono tabular-nums`,children:ge(e.duration)})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h4`,{className:`mb-1.5 text-xs font-semibold text-muted-foreground`,children:`命中规则 / Mock`}),(0,R.jsx)(`div`,{className:`mb-1 text-sm font-semibold`,children:n.title}),(0,R.jsx)(`p`,{className:`mb-2 text-xs text-muted-foreground`,children:n.description}),(0,R.jsx)(`pre`,{className:`meddle-thin-scroll w-full overflow-x-auto rounded border bg-muted/30 px-2 py-1.5 font-mono text-[11px] leading-relaxed whitespace-pre-wrap break-all`,"data-testid":`detail-hit-box`,"data-hit-kind":n.kind,children:i})]}),r.length>0&&(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h4`,{className:`mb-1.5 text-xs font-semibold text-muted-foreground`,children:`请求 headers(节选)`}),(0,R.jsx)(`div`,{className:`grid grid-cols-[minmax(72px,90px)_1fr] gap-x-3 gap-y-1 text-xs`,children:r.map(([e,t])=>(0,R.jsxs)(I.Fragment,{children:[(0,R.jsx)(`div`,{className:`truncate text-muted-foreground`,title:e,children:e}),(0,R.jsx)(`div`,{className:`truncate font-mono`,title:t,children:t})]},e))})]})]})}function ve({open:e=!1,onClose:t,embedded:n=!1,detail:i,loading:a,error:o,selectedRecord:s,onCreateMock:c,onReplay:l,onJumpToRule:u,showTitle:d=!0}){let[f,p]=(0,I.useState)(!1),g=()=>{i&&s&&c&&c({source:s.source,responseBody:i.responseBody,statusCode:i.statusCode,responseHeaders:i.responseHeaders})},[b,w]=(0,I.useState)(null),k=(0,R.jsxs)(R.Fragment,{children:[i&&l&&s?.id!=null&&(0,R.jsxs)(r,{variant:`outline`,size:`xs`,onClick:async()=>{if(s?.id!=null&&l){p(!0),w(null);try{await l(s.id)}catch(e){w(e.message||`重放失败`)}finally{p(!1)}}},disabled:f,title:`使用相同的请求参数重新发送请求`,children:[(0,R.jsx)(T,{className:`h-3.5 w-3.5 mr-1 ${f?`animate-spin`:``}`}),f?`重放中…`:`重放`]}),s&&u&&s.source!==s.target&&!s.mock&&(0,R.jsxs)(r,{variant:`outline`,size:`xs`,onClick:()=>u(s),title:`跳转到路由规则配置`,"data-testid":`detail-jump-to-rule`,children:[(0,R.jsx)(D,{className:`h-3.5 w-3.5 mr-1`}),`查看规则`]}),i&&c&&!s?.mock&&(0,R.jsxs)(r,{variant:`outline`,size:`xs`,onClick:g,"data-testid":`detail-create-mock`,children:[(0,R.jsx)(ee,{className:`h-3.5 w-3.5 mr-1`}),`创建 Mock`]})]}),A=(0,R.jsx)(`div`,{"data-testid":`detail-panel-actions`,className:`ml-auto flex shrink-0 flex-nowrap items-center justify-end gap-1.5`,children:k}),j=(0,R.jsxs)(R.Fragment,{children:[d&&(0,R.jsx)(`span`,{"data-testid":`detail-panel-title`,className:`shrink-0 whitespace-nowrap`,children:`请求详情`}),i&&(0,R.jsxs)(m,{className:`${U(i.statusCode)} max-w-full min-w-0 shrink truncate border-0`,children:[i.statusCode,` `,i.statusMessage]}),s?.clientType&&(0,R.jsxs)(m,{variant:`outline`,className:`max-w-48 text-[10px] font-mono`,title:[s.clientName,s.clientIp].filter(Boolean).join(` · `),children:[s.clientName||(s.clientType===`local`?`本机`:s.clientType===`plugin`?`插件测试`:`远程设备`),s.clientIp?` · ${s.clientIp}`:``]}),s?.applicationName&&(0,R.jsxs)(m,{variant:`outline`,className:`max-w-56 gap-1.5 text-[10px]`,title:[s.applicationIdentitySource===`local-process`?`识别方式: 本机进程`:s.applicationIdentitySource===`user-agent`?`识别方式: User-Agent 推断`:s.applicationIdentitySource===`client-reported`?`识别方式: 客户端上报`:void 0,s.applicationIdentityConfidence?`可信度: ${s.applicationIdentityConfidence===`high`?`高`:s.applicationIdentityConfidence===`medium`?`中`:`低`}`:void 0,s.applicationProcess,s.applicationPid?`PID ${s.applicationPid}`:void 0,s.applicationBundleId,s.applicationPath].filter(Boolean).join(` · `),children:[(0,R.jsx)(_,{record:s,compact:!0}),(0,R.jsx)(`span`,{className:`truncate`,children:s.applicationName}),s.applicationIdentitySource===`user-agent`&&(0,R.jsx)(`span`,{className:`shrink-0 text-[9px] text-muted-foreground`,children:`推断`})]}),d?A:null]}),M=d?null:(0,R.jsx)(`div`,{"data-testid":`detail-panel-actions`,className:`flex max-w-full shrink-0 flex-wrap items-center gap-1.5 border-t px-3 py-2`,children:k}),N=`flex min-w-0 flex-nowrap items-center gap-2 text-sm font-semibold text-foreground`,P=(0,R.jsxs)(R.Fragment,{children:[n?(0,R.jsx)(`div`,{className:`min-w-0 px-3 pt-2.5 pb-1.5`,"data-testid":`detail-panel-header`,children:d?(0,R.jsx)(`h2`,{className:N,children:j}):(0,R.jsx)(`div`,{className:N,children:j})}):(0,R.jsx)(ie,{className:`min-w-0 px-4 pt-4 pb-2`,children:(0,R.jsx)(ne,{className:`flex min-w-0 flex-nowrap items-center gap-2 text-base`,children:j})}),(0,R.jsx)(O,{}),b&&(0,R.jsx)(`div`,{className:`mx-4 mt-2 px-3 py-2 rounded-md bg-red-50 border border-red-200 text-red-700 text-xs`,children:b}),o&&!a&&!i&&(0,R.jsx)(`div`,{className:`mx-4 mt-2 px-3 py-2 rounded-md bg-amber-50 border border-amber-200 text-amber-800 text-xs`,children:o}),a?(0,R.jsx)(`div`,{className:`flex-1 flex items-center justify-center`,children:(0,R.jsx)(h,{className:`h-6 w-6 animate-spin text-muted-foreground`})}):i&&s?(0,R.jsxs)(E,{defaultValue:`overview`,className:`flex-1 flex flex-col min-h-0`,children:[(0,R.jsxs)(y,{className:`mx-4 mt-2 w-fit`,children:[(0,R.jsx)(x,{value:`overview`,"data-testid":`detail-tab-overview`,children:`概览`}),(0,R.jsx)(x,{value:`request`,children:`请求`}),(0,R.jsx)(x,{value:`response`,children:`响应`}),(0,R.jsxs)(x,{value:`inspect`,children:[(0,R.jsx)(S,{className:`h-3.5 w-3.5 mr-1`}),`Inspect`]})]}),(0,R.jsx)(v,{value:`overview`,className:`flex-1 min-h-0 mt-0`,children:(0,R.jsx)(C,{className:`h-full px-4 pb-4`,children:(0,R.jsx)(_e,{record:s,detail:i})})}),(0,R.jsx)(v,{value:`request`,className:`flex-1 min-h-0 mt-0`,children:(0,R.jsx)(C,{className:`h-full px-4 pb-4`,children:(0,R.jsxs)(`div`,{className:`space-y-3 pt-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h4`,{className:`text-xs font-semibold text-muted-foreground mb-1.5`,children:`Request headers`}),(0,R.jsx)(H,{headers:i.requestHeaders})]}),(0,R.jsx)(O,{}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h4`,{className:`text-xs font-semibold text-muted-foreground mb-1.5`,children:`Request body`}),(0,R.jsx)(V,{body:i.requestBody})]})]})})}),(0,R.jsx)(v,{value:`response`,className:`flex-1 min-h-0 mt-0`,children:(0,R.jsx)(C,{className:`h-full px-4 pb-4`,children:(0,R.jsxs)(`div`,{className:`space-y-3 pt-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h4`,{className:`text-xs font-semibold text-muted-foreground mb-1.5`,children:`Response headers`}),(0,R.jsx)(H,{headers:i.responseHeaders})]}),(0,R.jsx)(O,{}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h4`,{className:`text-xs font-semibold text-muted-foreground mb-1.5`,children:`Response body`}),(0,R.jsx)(V,{body:i.responseBody})]})]})})}),(0,R.jsx)(v,{value:`inspect`,className:`flex-1 min-h-0 mt-0`,children:(0,R.jsx)(C,{className:`h-full px-4 pb-4`,children:i.inspection?(0,R.jsx)(he,{inspection:i.inspection}):(0,R.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full py-12 text-muted-foreground`,children:[(0,R.jsx)(S,{className:`h-12 w-12 mb-4 opacity-50`}),(0,R.jsx)(`p`,{className:`text-sm`,children:`无 Inspect 信息`}),(0,R.jsx)(`p`,{className:`text-xs mt-1`,children:`需要开启插件模式(on/shadow)才能查看请求生命周期`})]})})})]}):s?(0,R.jsx)(`div`,{className:`flex-1 flex items-center justify-center text-muted-foreground text-sm px-6 text-center`,children:(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(0,R.jsx)(`div`,{children:`详情数据暂不可用`}),(0,R.jsxs)(`div`,{className:`text-xs font-mono break-all`,children:[s.method,` `,s.source]})]})}):(0,R.jsx)(`div`,{"data-testid":`detail-empty-state`,className:`flex flex-1 items-center justify-center px-6 text-center text-sm text-muted-foreground`,children:`选择左侧一条流量以查看详情 / 命中信息`}),M]});return n?(0,R.jsx)(`div`,{className:`flex h-full min-h-0 min-w-0 flex-col`,children:P}):(0,R.jsx)(re,{open:e,onOpenChange:e=>!e&&t?.(),children:(0,R.jsx)(te,{className:`p-0 flex flex-col`,resizable:!0,defaultWidth:640,storageKey:`detail-panel`,children:P})})}export{ve as DetailPanel};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as e,d as t,l as n,p as r,t as i,u as a}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as o}from"./circle-alert-zMagrFuI.js";import{a as s,c,i as l,n as u,o as d,r as f,s as p}from"./dist-DLQKRjuW.js";import"./es2015-DPJTBYa9.js";import{i as m,o as h,r as g}from"./ai-config-store-C8D_PUGV.js";import{$ as _,Ct as v,Mt as y,et as b,ht as x,jt as S,r as C,y as w}from"./index-C4dIj1nT.js";var T=a(`arrow-left`,[[`path`,{d:`m12 19-7-7 7-7`,key:`1l729n`}],[`path`,{d:`M19 12H5`,key:`x3x0zl`}]]),E=a(`command`,[[`path`,{d:`M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3`,key:`11bfej`}]]),D=a(`maximize-2`,[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`m21 3-7 7`,key:`1l2asr`}],[`path`,{d:`m3 21 7-7`,key:`tjx5ai`}],[`path`,{d:`M9 21H3v-6`,key:`wtvkvv`}]]),O=a(`minimize-2`,[[`path`,{d:`m14 10 7-7`,key:`oa77jy`}],[`path`,{d:`M20 10h-6V4`,key:`mjg0md`}],[`path`,{d:`m3 21 7-7`,key:`tjx5ai`}],[`path`,{d:`M4 14h6v6`,key:`rmj7iw`}]]),k=r(t(),1);function A(){let e=g(),t=m(e);return t?{...e,provider:t.provider,apiKey:t.apiKey,baseUrl:t.baseUrl,model:t.model}:e}async function j(e){let t=await e.json();if(!e.ok)throw Error(t.error||`请求失败: ${e.status}`);return t}function M(e){let t=e.split(`
|
|
2
|
+
`);return{event:t.find(e=>e.startsWith(`event:`))?.slice(6).trim()||`message`,data:t.filter(e=>e.startsWith(`data:`)).map(e=>e.slice(5).trimStart()).join(`
|
|
3
|
+
`)}}async function N(e,t={},n){let r=A();if(!h(r))throw Error(`请先在系统设置中启用并填写可用的 AI 配置。`);let i=await fetch(`/api/agent/chat-stream`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({message:e,aiConfig:r,...n?{conversationId:n}:{}})});if(!i.ok||!i.body)return j(i);let a=i.body.getReader(),o=new TextDecoder,s=``,c=e=>{let{event:n,data:r}=M(e);if(!r)return null;let i=JSON.parse(r);if(n===`start`)return t.onStart?.(),null;if(n===`delta`){let e=typeof i.delta==`string`?i.delta:``;return e&&t.onDelta?.(e),null}if(n===`error`)throw Error(typeof i.error==`string`?i.error:`AI 请求失败`);return n===`done`?i:null};for(;;){let{value:e,done:t}=await a.read();s+=o.decode(e||new Uint8Array,{stream:!t});let n=s.split(/\n\n/);s=n.pop()||``;for(let e of n){let t=c(e);if(t)return t}if(t)break}if(s.trim()){let e=c(s);if(e)return e}throw Error(`AI 流式响应未返回完成事件`)}async function ee(e,t){return j(await fetch(`/api/agent/confirm`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({confirmationId:e,approved:t})}))}function P(e){return e===`request.detail`?`bottom-12 right-1`:`bottom-0 right-0`}function F(e){return e.trim().toLowerCase()}function I(e,t){if(!e)return 1;let n=F(e),r=F(t);if(!n)return 1;if(!r)return 0;if(r===n)return 120;if(r.startsWith(n))return 100-Math.min(r.length-n.length,30);if(r.includes(n))return 80-Math.min(r.indexOf(n),30);let i=0,a=0;for(let e=0;e<r.length&&i<n.length;e++)n[i]===r[e]&&(i+=1,a+=4);return i===n.length?a:0}function L(e,t){let n=[t.title,t.description||``,t.section,...t.keywords||[]];return Math.max(...n.map(t=>I(e,t)))}function R(e,t){return(0,k.useMemo)(()=>{let n=e.map(e=>({command:e,score:L(t,e)})).filter(e=>e.score>0);return n.sort((e,t)=>e.command.disabled===t.command.disabled?t.score===e.score?e.command.title.localeCompare(t.command.title,`zh-Hans-CN`):t.score-e.score:e.command.disabled?1:-1),n.map(e=>e.command)},[e,t])}function z(){let e=(0,k.useContext)(C);if(!e)throw Error(`useGlobalPanel must be used inside GlobalPanelProvider`);return e}var B=e(),V={command:`w-[min(760px,calc(100vw-32px))] h-[min(760px,calc(100vh-48px))]`,md:`w-[min(760px,calc(100vw-32px))] h-[min(720px,calc(100vh-48px))]`,lg:`w-[min(1040px,calc(100vw-32px))] h-[min(780px,calc(100vh-48px))]`,xl:`w-[min(1240px,calc(100vw-32px))] h-[min(860px,calc(100vh-32px))]`,fullscreen:`w-[calc(100vw-32px)] h-[calc(100vh-32px)]`},H={md:{width:760,height:720},lg:{width:1040,height:780},xl:{width:1240,height:860},fullscreen:{width:1/0,height:1/0}};function U(){let e=typeof window>`u`?1280:window.innerWidth,t=typeof window>`u`?900:window.innerHeight,n=Math.max(320,e-32),r=Math.max(360,t-32);return{minWidth:Math.min(560,n),minHeight:Math.min(420,r),maxWidth:n,maxHeight:r}}function W(e){let t=U();return{width:Math.min(t.maxWidth,Math.max(t.minWidth,e.width)),height:Math.min(t.maxHeight,Math.max(t.minHeight,e.height))}}function G(e){let t=U(),n=H[e]||H.lg;return e===`fullscreen`?{width:t.maxWidth,height:t.maxHeight}:W(n)}function K(e){if(typeof window>`u`)return null;try{let t=window.localStorage.getItem(`global-panel-size:${e}`);if(!t)return null;let n=JSON.parse(t);return typeof n.width!=`number`||typeof n.height!=`number`?null:W({width:n.width,height:n.height})}catch{return null}}function q(e){let t=[],n=/(`[^`]+`|\*\*[^*]+\*\*)/g,r=0,i;for(;i=n.exec(e);){i.index>r&&t.push(e.slice(r,i.index));let n=i[0];n.startsWith("`")?t.push((0,B.jsx)(`code`,{className:`rounded bg-muted/70 px-1 py-0.5 font-mono text-[0.92em]`,children:n.slice(1,-1)},`${i.index}-code`)):t.push((0,B.jsx)(`strong`,{children:n.slice(2,-2)},`${i.index}-strong`)),r=i.index+n.length}return r<e.length&&t.push(e.slice(r)),t}function J(e){return/^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(e)}function Y(e){return e.trim().replace(/^\|/,``).replace(/\|$/,``).split(`|`).map(e=>e.trim())}function X({content:e}){let t=e.replace(/\r\n/g,`
|
|
4
|
+
`).split(`
|
|
5
|
+
`),r=[],i=0;for(;i<t.length;){let e=t[i].trim();if(!e){i+=1;continue}let a=e.match(/^```(\w+)?/);if(a){let e=a[1],n=[];for(i+=1;i<t.length&&!t[i].trim().startsWith("```");)n.push(t[i]),i+=1;i+=1,r.push((0,B.jsxs)(`div`,{className:`overflow-hidden rounded-md border bg-muted/45`,children:[e&&(0,B.jsx)(`div`,{className:`border-b bg-background/45 px-3 py-1 text-[11px] uppercase tracking-wide text-muted-foreground`,children:e}),(0,B.jsx)(`pre`,{className:`max-h-64 overflow-auto p-3 text-xs leading-5`,children:(0,B.jsx)(`code`,{children:n.join(`
|
|
6
|
+
`)})})]},`code-${i}`));continue}let o=e.match(/^(#{1,4})\s+(.+)$/);if(o){let e=o[1].length,t=n(`font-semibold leading-6 text-foreground`,e<=2?`mt-2 text-sm`:`text-[13px]`),a=q(o[2]);r.push(e===1?(0,B.jsx)(`h3`,{className:t,children:a},`heading-${i}`):e===2?(0,B.jsx)(`h4`,{className:t,children:a},`heading-${i}`):(0,B.jsx)(`h5`,{className:t,children:a},`heading-${i}`)),i+=1;continue}if(/^---+$/.test(e)){r.push((0,B.jsx)(`div`,{className:`h-px bg-border/70`},`hr-${i}`)),i+=1;continue}if(e.includes(`|`)&&i+1<t.length&&J(t[i+1])){let n=Y(e),a=[];for(i+=2;i<t.length&&t[i].trim().includes(`|`);)a.push(Y(t[i])),i+=1;r.push((0,B.jsx)(`div`,{className:`overflow-auto rounded-md border`,children:(0,B.jsxs)(`table`,{className:`w-full min-w-max border-collapse text-xs`,children:[(0,B.jsx)(`thead`,{className:`bg-muted/50 text-muted-foreground`,children:(0,B.jsx)(`tr`,{children:n.map((e,t)=>(0,B.jsx)(`th`,{className:`border-b px-2 py-1.5 text-left font-medium`,children:q(e)},`${e}-${t}`))})}),(0,B.jsx)(`tbody`,{children:a.map((e,t)=>(0,B.jsx)(`tr`,{className:`border-b last:border-0`,children:e.map((e,n)=>(0,B.jsx)(`td`,{className:`px-2 py-1.5 align-top`,children:q(e)},`${t}-${n}`))},t))})]})},`table-${i}`));continue}if(/^[-*]\s+/.test(e)||/^\d+\.\s+/.test(e)){let a=/^\d+\.\s+/.test(e),o=[];for(;i<t.length;){let e=t[i].trim(),n=a?e.match(/^\d+\.\s+(.+)$/):e.match(/^[-*]\s+(.+)$/);if(!n)break;o.push(n[1]),i+=1}let s=a?`ol`:`ul`;r.push((0,B.jsx)(s,{className:n(`space-y-1 pl-5`,a?`list-decimal`:`list-disc`),children:o.map((e,t)=>(0,B.jsx)(`li`,{children:q(e)},t))},`list-${i}`));continue}let s=[e];for(i+=1;i<t.length;){let e=t[i].trim();if(!e||e.startsWith("```")||/^#{1,4}\s+/.test(e)||/^[-*]\s+/.test(e)||/^\d+\.\s+/.test(e)||/^---+$/.test(e)||e.includes(`|`)&&i+1<t.length&&J(t[i+1]))break;s.push(e),i+=1}r.push((0,B.jsx)(`p`,{className:`leading-6 text-foreground/90`,children:q(s.join(` `))},`p-${i}`))}return(0,B.jsx)(`div`,{className:`agent-markdown-content space-y-3 text-sm`,children:r})}function Z({commands:e}){let t=z(),[r,a]=(0,k.useState)(``),[s,c]=(0,k.useState)(0),[l,u]=(0,k.useState)(null),[d,f]=(0,k.useState)(null),[p,m]=(0,k.useState)(null),[h,g]=(0,k.useState)(!1),[C,T]=(0,k.useState)(null),[D,O]=(0,k.useState)(null),[A,j]=(0,k.useState)([]),[M,P]=(0,k.useState)(``),[F,I]=(0,k.useState)(null),L=(0,k.useRef)(null),V=(0,k.useRef)(null),H=(0,k.useRef)(null),U=(0,k.useRef)(null),W=R(e,r),G=r.trim(),K=!!(p||d||h||A.length>0);(0,k.useEffect)(()=>{let e=requestAnimationFrame(()=>L.current?.focus());return()=>cancelAnimationFrame(e)},[]),(0,k.useEffect)(()=>{c(0)},[r]),(0,k.useEffect)(()=>{let e=V.current;!e||!K||(e.scrollTop=e.scrollHeight)},[p,h,d?.message,A,K]);let q=W[s];(0,k.useLayoutEffect)(()=>{let e=H.current,t=U.current;if(!e||!t)return;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect();n.top<r.top+12?t.scrollTop-=r.top+12-n.top:n.bottom>r.bottom-12&&(t.scrollTop+=n.bottom-(r.bottom-12))},[s,W]);let J=(0,k.useMemo)(()=>{let e=new Map;return W.forEach(t=>{e.has(t.section)||e.set(t.section,[]),e.get(t.section)?.push(t)}),Array.from(e.entries())},[W]),Y=async e=>{if(!(!e||e.disabled)&&!(e.confirm&&!window.confirm(e.confirm))){u(e.id);try{await e.run(),e.closeOnRun!==!1&&t.close()}finally{u(null)}}},Z=async(e,t)=>{if(!e||h)return;g(!0),m(null),f(null),I(e),t||(O(null),j([]));let n=``;try{let r=await N(e,{onDelta:e=>{n+=e,f({runId:`streaming`,message:n,pendingConfirmations:[],toolResults:[],conversationId:t||``})}},t);f(r),O(r.conversationId),j(t=>[...t,{userMessage:e,aiMessage:r.message}])}catch(e){m(e.message)}finally{g(!1),I(null)}},Q=async()=>{let e=M.trim();!e||h||!D||(P(``),await Z(e,D))},$=async(e,t)=>{T(e),m(null);try{let n=await ee(e,t),r=(n.result&&typeof n.result==`object`?n.result:null)?.message||n.message;f(t=>({runId:t?.runId||e,message:r,pendingConfirmations:[],toolResults:n.result?[n.result]:[],conversationId:t?.conversationId||``})),j(e=>e.length===0?e:e.map((t,n)=>n===e.length-1?{...t,aiMessage:r}:t))}catch(e){m(e.message)}finally{T(null)}};return(0,B.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,B.jsxs)(`div`,{className:`global-panel-topbar flex items-center gap-3 border-b px-4 py-3`,children:[(0,B.jsx)(x,{className:`h-4 w-4 text-muted-foreground`}),(0,B.jsx)(b,{ref:L,value:r,onChange:e=>a(e.target.value),onKeyDown:e=>{e.key===`ArrowDown`?(e.preventDefault(),c(e=>Math.min(e+1,Math.max(W.length-1,0)))):e.key===`ArrowUp`?(e.preventDefault(),c(e=>Math.max(e-1,0))):e.key===`Enter`?(e.preventDefault(),q?Y(q):G&&Z(G)):e.key===`Escape`&&!r&&t.close()},placeholder:`搜索命令,或直接描述你想让 AI 完成的操作…`,className:`h-9 border-0 bg-transparent px-0 shadow-none focus-visible:ring-0 dark:bg-transparent`}),(0,B.jsx)(_,{variant:`outline`,className:`hidden shrink-0 text-[11px] font-normal sm:inline-flex`,children:w()})]}),(0,B.jsxs)(`div`,{ref:U,className:`min-h-0 flex-1 overflow-y-auto`,children:[G&&(0,B.jsx)(`div`,{className:`p-3 pb-0`,children:(0,B.jsxs)(`button`,{type:`button`,className:`global-command-action flex w-full items-center gap-3 rounded-md border px-3 py-2 text-left text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-60`,disabled:h,onClick:()=>void Z(G),children:[(0,B.jsx)(`div`,{className:`flex h-8 w-8 shrink-0 items-center justify-center rounded-md border bg-background/55 backdrop-blur`,children:h?(0,B.jsx)(v,{className:`h-4 w-4 animate-spin`}):(0,B.jsx)(y,{className:`h-4 w-4`})}),(0,B.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,B.jsx)(`div`,{className:`font-medium`,children:`让 AI 处理`}),(0,B.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,children:G})]})]})}),(p||d||h||A.length>0)&&(0,B.jsx)(`div`,{className:`p-3 pb-0`,children:(0,B.jsxs)(`div`,{className:n(`overflow-hidden rounded-md border text-sm`,p?`border-destructive/40 bg-destructive/5`:`bg-background/35 backdrop-blur`),children:[(0,B.jsxs)(`div`,{className:`flex items-center gap-2 border-b bg-background/35 px-3 py-2`,children:[p?(0,B.jsx)(o,{className:`h-4 w-4 shrink-0 text-destructive`}):h?(0,B.jsx)(v,{className:`h-4 w-4 shrink-0 animate-spin text-muted-foreground`}):(0,B.jsx)(S,{className:`h-4 w-4 shrink-0 text-emerald-500`}),(0,B.jsx)(`div`,{className:`min-w-0 flex-1 font-medium`,children:p?`AI 请求失败`:h?`AI 正在处理`:`AI 响应`})]}),(0,B.jsx)(`div`,{ref:V,className:`max-h-[min(520px,calc(100vh-220px))] overflow-y-auto overscroll-contain`,children:(0,B.jsxs)(`div`,{className:`px-3 py-3`,children:[p&&A.length===0?(0,B.jsx)(`div`,{className:`whitespace-pre-wrap break-words leading-6 text-destructive`,children:p}):null,A.map((e,t)=>(0,B.jsxs)(`div`,{className:n(t>0&&`mt-4 border-t pt-4`),children:[(0,B.jsx)(`div`,{className:`mb-1 text-xs font-medium text-muted-foreground`,children:`你`}),(0,B.jsx)(`div`,{className:`mb-3 whitespace-pre-wrap break-words leading-6 text-foreground/90`,children:e.userMessage}),(0,B.jsx)(`div`,{className:`mb-1 text-xs font-medium text-muted-foreground`,children:`AI`}),(0,B.jsx)(X,{content:e.aiMessage})]},t)),F&&(0,B.jsxs)(`div`,{className:n(A.length>0&&`mt-4 border-t pt-4`),children:[(0,B.jsx)(`div`,{className:`mb-1 text-xs font-medium text-muted-foreground`,children:`你`}),(0,B.jsx)(`div`,{className:`mb-3 whitespace-pre-wrap break-words leading-6 text-foreground/90`,children:F}),(0,B.jsx)(`div`,{className:`mb-1 text-xs font-medium text-muted-foreground`,children:`AI`}),h&&!d?.message?(0,B.jsx)(`div`,{className:`leading-6 text-muted-foreground`,children:`正在分析你的请求并调用可用工具…`}):d?.message?(0,B.jsx)(X,{content:d.message}):null,p?(0,B.jsx)(`div`,{className:`whitespace-pre-wrap break-words leading-6 text-destructive`,children:p}):null]}),d?.pendingConfirmations.map(e=>(0,B.jsxs)(`div`,{className:`mt-3 rounded-md border bg-background/55 p-3 backdrop-blur`,children:[(0,B.jsx)(`div`,{className:`font-medium`,children:e.summary}),e.diff&&(0,B.jsx)(`pre`,{className:`mt-2 max-h-40 overflow-auto rounded border bg-muted/40 p-2 text-xs leading-5 text-muted-foreground`,children:e.diff}),(0,B.jsxs)(`div`,{className:`mt-3 flex justify-end gap-2`,children:[(0,B.jsx)(i,{variant:`ghost`,size:`sm`,disabled:C===e.id,onClick:()=>void $(e.id,!1),children:`取消`}),(0,B.jsxs)(i,{size:`sm`,disabled:C===e.id,onClick:()=>void $(e.id,!0),children:[C===e.id?(0,B.jsx)(v,{className:`mr-1 h-3.5 w-3.5 animate-spin`}):null,`确认执行`]})]})]},e.id))]})}),D&&!h&&d&&d.pendingConfirmations.length===0&&(0,B.jsx)(`div`,{className:`border-t px-3 py-2`,children:(0,B.jsxs)(`div`,{className:`flex gap-2`,children:[(0,B.jsx)(b,{value:M,onChange:e=>P(e.target.value),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),Q())},placeholder:`继续对话…`,className:`h-8 text-sm`}),(0,B.jsx)(i,{size:`sm`,disabled:!M.trim()||h,onClick:()=>void Q(),children:`发送`})]})})]})}),W.length===0&&!K?(0,B.jsxs)(`div`,{className:`flex h-64 flex-col items-center justify-center gap-2 px-6 text-center text-muted-foreground`,children:[(0,B.jsx)(E,{className:`h-8 w-8 opacity-50`}),(0,B.jsx)(`div`,{className:`text-sm`,children:`没有找到匹配的操作`})]}):W.length>0?(0,B.jsx)(`div`,{className:`space-y-4 p-3`,children:J.map(([e,t])=>(0,B.jsxs)(`div`,{className:`space-y-1`,children:[(0,B.jsx)(`div`,{className:`px-2 py-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground`,children:e}),t.map(e=>{let t=W.findIndex(t=>t.id===e.id),r=e.icon,i=t===s,a=l===e.id;return(0,B.jsxs)(`button`,{ref:i?H:void 0,type:`button`,"data-selected":i?`true`:void 0,className:n(`flex w-full items-center gap-3 rounded-md px-2 py-2 text-left text-sm transition-colors`,i?`bg-accent/70 text-accent-foreground shadow-sm`:`hover:bg-accent/45`,e.disabled&&`cursor-not-allowed opacity-50`,e.danger&&!e.disabled&&`text-destructive`),onMouseEnter:()=>c(t),onClick:()=>void Y(e),disabled:a,children:[(0,B.jsx)(`div`,{className:`flex h-8 w-8 shrink-0 items-center justify-center rounded-md border bg-background/55 backdrop-blur`,children:a?(0,B.jsx)(v,{className:`h-4 w-4 animate-spin`}):r?(0,B.jsx)(r,{className:`h-4 w-4`}):(0,B.jsx)(E,{className:`h-4 w-4`})}),(0,B.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,B.jsx)(`div`,{className:`truncate font-medium`,children:e.title}),(e.description||e.disabledReason)&&(0,B.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,children:e.disabled&&e.disabledReason||e.description})]}),e.shortcut&&(0,B.jsx)(_,{variant:`secondary`,className:`shrink-0 text-[10px] font-normal`,children:e.shortcut})]},e.id)})]},e))}):null]})]})}function Q({commands:e,renderPanel:t}){let r=z(),a=r.currentRoute,o=a?.size||`command`,m=a?.id,h=a?.size,[g,_]=(0,k.useState)(null),[v,y]=(0,k.useState)(!1),[b,x]=(0,k.useState)(!1),S=(0,k.useRef)(null);(0,k.useEffect)(()=>{let e=window.requestAnimationFrame(()=>{if(!m){_(null),y(!1),x(!1);return}_(K(m)||G(h||`lg`)),y(h===`fullscreen`),x(!1)});return()=>window.cancelAnimationFrame(e)},[m,h]),(0,k.useEffect)(()=>{if(!m)return;let e=()=>{_(e=>e&&W(e))};return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[m]);let C=e=>{!a||v||typeof window>`u`||window.localStorage.setItem(`global-panel-size:${a.id}`,JSON.stringify(e))},w=e=>{if(!a||!g||v)return;e.preventDefault(),x(!0);let t=e.pointerId,n=e.clientX,r=e.clientY,i=g,o=e.currentTarget;o.setPointerCapture(t);let s=e=>{_(W({width:i.width+(e.clientX-n)*2,height:i.height+(e.clientY-r)}))},c=()=>{o.hasPointerCapture(t)&&o.releasePointerCapture(t),window.removeEventListener(`pointermove`,s),window.removeEventListener(`pointerup`,c),window.removeEventListener(`pointercancel`,c),x(!1),_(e=>(e&&C(e),e))};window.addEventListener(`pointermove`,s),window.addEventListener(`pointerup`,c),window.addEventListener(`pointercancel`,c)},E=()=>{if(!(!a||!g)){if(v){_(W(S.current||K(a.id)||G(a.size||`lg`))),y(!1);return}S.current=g,_(G(`fullscreen`)),y(!0)}},A=a&&g?{width:`${g.width}px`,height:`${g.height}px`}:void 0;return(0,B.jsx)(d,{open:r.open,onOpenChange:e=>{e||r.close()},children:(0,B.jsxs)(s,{children:[(0,B.jsx)(l,{className:`global-panel-overlay fixed inset-0 z-[80]`}),(0,B.jsx)(u,{style:A,className:n(`global-panel-content global-panel-surface fixed left-1/2 top-4 z-[81] flex flex-col overflow-hidden rounded-lg border outline-none`,a&&!b&&`transition-[width,height] duration-200 ease-out`,!a&&V[o]),children:a?(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`div`,{className:`global-panel-topbar flex items-center gap-2 border-b px-4 py-3`,children:[r.stack.length>1&&(0,B.jsx)(i,{variant:`ghost`,size:`icon`,className:`h-8 w-8`,onClick:r.back,title:`返回上一级`,children:(0,B.jsx)(T,{className:`h-4 w-4`})}),(0,B.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,B.jsx)(p,{className:`truncate text-sm font-semibold`,children:a.title}),a.description&&(0,B.jsx)(f,{className:`truncate text-xs text-muted-foreground`,children:a.description})]}),(0,B.jsx)(i,{variant:`ghost`,size:`icon`,className:`h-8 w-8`,onClick:E,title:v?`还原尺寸`:`最大化`,children:v?(0,B.jsx)(O,{className:`h-4 w-4`}):(0,B.jsx)(D,{className:`h-4 w-4`})}),(0,B.jsx)(i,{variant:`ghost`,size:`icon`,className:`h-8 w-8`,onClick:r.close,title:`关闭`,children:(0,B.jsx)(c,{className:`h-4 w-4`})})]}),(0,B.jsx)(`div`,{className:`min-h-0 flex-1 overflow-hidden`,children:t(a)}),!v&&(0,B.jsx)(`button`,{type:`button`,"aria-label":`调整面板尺寸`,title:`拖拽调整面板尺寸`,"data-testid":`global-panel-resize`,className:n(`absolute h-6 w-6 cursor-nwse-resize rounded-tl-md text-muted-foreground/70 transition-colors hover:bg-accent hover:text-foreground`,P(a.id)),onPointerDown:w,children:(0,B.jsx)(`span`,{className:`pointer-events-none absolute bottom-1 right-1 h-3 w-3 border-b border-r border-current`})})]}):(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(p,{className:`sr-only`,children:`全局操作面板`}),(0,B.jsx)(f,{className:`sr-only`,children:`搜索并执行 Meddle 的页面、设置和功能操作。`}),(0,B.jsx)(Z,{commands:e})]})})]})})}export{Q as GlobalPanelShell};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e,d as t,l as n,p as r,t as i,u as a}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as o}from"./circle-x-BEkinhez.js";import{n as s,t as c}from"./server-eYXq3PbE.js";import{t as l}from"./refresh-cw-BfLoHqg5.js";import{t as ee}from"./shield-check-hQXjdfZ7.js";import{t as u}from"./wifi-Cjj_Br1u.js";import{t as d}from"./switch-94vgsMHm.js";import{At as f,B as p,H as m,Q as h,R as g,U as _,V as v,at as y,et as b,it as x,lt as te,nt as ne,ot as S,rt as C,st as w,tt as T,wt as re}from"./index-B-6nUrqW.js";import{n as E,r as D,t as O}from"./alert-B514Frte.js";import{a as k,i as A,n as j,o as M,r as N,t as P}from"./table-DaXD6jJv.js";var F=a(`cpu`,[[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M17 20v2`,key:`1rnc9c`}],[`path`,{d:`M17 2v2`,key:`11trls`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M2 17h2`,key:`7oei6x`}],[`path`,{d:`M2 7h2`,key:`asdhe0`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`M20 17h2`,key:`1fpfkl`}],[`path`,{d:`M20 7h2`,key:`1o8tra`}],[`path`,{d:`M7 20v2`,key:`4gnj0m`}],[`path`,{d:`M7 2v2`,key:`1i4yhu`}],[`rect`,{x:`4`,y:`4`,width:`16`,height:`16`,rx:`2`,key:`1vbyd7`}],[`rect`,{x:`8`,y:`8`,width:`8`,height:`8`,rx:`1`,key:`z9xiuo`}]]),I=a(`gauge`,[[`path`,{d:`m12 14 4-4`,key:`9kzdfg`}],[`path`,{d:`M3.34 19a10 10 0 1 1 17.32 0`,key:`19p75a`}]]),L=a(`hard-drive`,[[`line`,{x1:`22`,x2:`2`,y1:`12`,y2:`12`,key:`1y58io`}],[`path`,{d:`M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`oot6mr`}],[`line`,{x1:`6`,x2:`6.01`,y1:`16`,y2:`16`,key:`sgf278`}],[`line`,{x1:`10`,x2:`10.01`,y1:`16`,y2:`16`,key:`1l4acy`}]]),R=a(`network`,[[`rect`,{x:`16`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`4q2zg0`}],[`rect`,{x:`2`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`8cvhb9`}],[`rect`,{x:`9`,y:`2`,width:`6`,height:`6`,rx:`1`,key:`1egb70`}],[`path`,{d:`M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3`,key:`1jsf9p`}],[`path`,{d:`M12 12V8`,key:`2874zd`}]]),z=r(t(),1),B=e(),V={ok:`正常`,degraded:`降级`,critical:`严重`},ie={cpu:`CPU`,rss:`RSS 内存`,connections:`连接数`,mitmServers:`MITM 服务`,eventLoopDelay:`事件循环延迟`,fds:`文件描述符`};function H(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.generatedAt==`number`&&typeof t.status==`string`&&typeof t.pid==`number`&&typeof t.uptimeSec==`number`&&!!t.memory&&!!t.cpu&&!!t.connections&&!!t.mitmServers&&Array.isArray(t.checks)}async function U(){let e=await fetch(`/api/health`,{cache:`no-store`});if(!e.ok)throw Error(`健康接口返回 ${e.status}`);let t=await e.json();if(!H(t))throw Error(`健康接口返回格式不正确`);return t}function W(e){if(!Number.isFinite(e))return`-`;if(e<1024)return`${e} B`;let t=[`KB`,`MB`,`GB`,`TB`],n=e/1024,r=t[0];for(let e=1;e<t.length&&n>=1024;e+=1)n/=1024,r=t[e];return`${n>=10?n.toFixed(0):n.toFixed(1)} ${r}`}function G(e){if(!Number.isFinite(e)||e<0)return`-`;let t=Math.floor(e/86400),n=Math.floor(e%86400/3600),r=Math.floor(e%3600/60),i=Math.floor(e%60);return t>0?`${t}天 ${n}小时`:n>0?`${n}小时 ${r}分钟`:r>0?`${r}分钟 ${i}秒`:`${i}秒`}function K(e){return e?new Intl.DateTimeFormat(`zh-CN`,{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).format(new Date(e)):`-`}function q(e,t){return t===`bytes`?W(e):t===`%`?`${e.toFixed(1)}%`:t===`ms`?`${e.toFixed(1)} ms`:String(e)}function J(e,t){return t===`bytes`?W(e):t===`%`?`${e}%`:t===`ms`?`${e} ms`:String(e)}function ae(e){if(!e||typeof e!=`object`)return null;let t=e;return Array.isArray(t.keys)?{windowMs:Number(t.windowMs)||0,maxPerWindow:Number(t.maxPerWindow)||0,keys:t.keys,suppressedTotal:Number(t.suppressedTotal)||0}:null}function Y({status:e}){return(0,B.jsxs)(h,{variant:e===`critical`?`destructive`:e===`degraded`?`secondary`:`default`,children:[e===`ok`?(0,B.jsx)(f,{}):e===`degraded`?(0,B.jsx)(w,{}):(0,B.jsx)(o,{}),V[e]]})}function oe({icon:e,label:t,value:n,detail:r}){return(0,B.jsxs)(T,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsx)(y,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:(0,B.jsxs)(S,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,B.jsx)(e,{}),t]})}),(0,B.jsxs)(C,{className:`flex flex-col gap-1 p-[var(--ui-page-padding)]`,children:[(0,B.jsx)(`div`,{className:`text-2xl font-semibold tracking-tight`,children:n}),(0,B.jsx)(`div`,{className:`min-h-4 truncate text-xs text-muted-foreground`,title:r,children:r})]})]})}function X({label:e,value:t}){return(0,B.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1 rounded-lg border bg-background p-[var(--ui-section-gap)]`,children:[(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e}),(0,B.jsx)(`span`,{className:`truncate text-sm font-medium`,title:t,children:t})]})}function se(){return(0,B.jsxs)(`div`,{className:`app-workspace-content`,"aria-label":`正在读取健康状态`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,B.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,B.jsx)(b,{className:`h-7 w-40`}),(0,B.jsx)(b,{className:`h-4 w-64`})]}),(0,B.jsx)(b,{className:`h-8 w-28`})]}),(0,B.jsx)(`div`,{className:`grid gap-[var(--ui-section-gap)] md:grid-cols-2 xl:grid-cols-6`,children:Array.from({length:6}).map((e,t)=>(0,B.jsx)(b,{className:`h-32 w-full`},t))}),(0,B.jsx)(b,{className:`h-80 w-full`})]})}function Z(){let[e,t]=(0,z.useState)(null),[r,a]=(0,z.useState)(!0),[o,f]=(0,z.useState)(!1),[b,V]=(0,z.useState)(``),[H,Z]=(0,z.useState)(!0),Q=(0,z.useCallback)(async(e=!1)=>{e?f(!0):a(!0),V(``);try{t(await U())}catch(e){V(e instanceof Error?e.message:`无法读取健康状态`)}finally{a(!1),f(!1)}},[]);(0,z.useEffect)(()=>{Q()},[Q]),(0,z.useEffect)(()=>{if(!H)return;let e=window.setInterval(()=>{Q(!0)},5e3);return()=>window.clearInterval(e)},[H,Q]);let $=(0,z.useMemo)(()=>ae(e?.logs),[e]);if(r&&!e)return(0,B.jsx)(se,{});if(!e)return(0,B.jsxs)(`div`,{className:`app-workspace-content`,children:[(0,B.jsxs)(O,{variant:`destructive`,children:[(0,B.jsx)(D,{children:`加载失败`}),(0,B.jsx)(E,{children:b||`无法读取健康状态`})]}),(0,B.jsxs)(i,{variant:`outline`,size:`sm`,onClick:()=>void Q(),children:[(0,B.jsx)(l,{"data-icon":`inline-start`}),`重新检测`]})]});let ce=[{icon:F,label:`CPU`,value:`${e.cpu.percent.toFixed(1)}%`,detail:`${e.cpu.cores} 核 · load ${e.cpu.loadAverage.map(e=>e.toFixed(2)).join(` / `)}`},{icon:L,label:`RSS 内存`,value:W(e.memory.rss),detail:`Heap ${W(e.memory.heapUsed)} / ${W(e.memory.heapTotal)}`},{icon:R,label:`TCP 连接`,value:String(e.connections.total),detail:`代理 ${e.connections.proxySockets} · TLS ${e.connections.mitmTlsSockets} · WS ${e.connections.webSockets}`},{icon:c,label:`MITM 服务`,value:String(e.mitmServers.count),detail:`${e.mitmServers.activeSockets} 个活跃 socket`},{icon:te,label:`文件描述符`,value:e.process.fdCount==null?`-`:String(e.process.fdCount),detail:`handles ${e.process.activeHandles??`-`} · requests ${e.process.activeRequests??`-`}`},{icon:I,label:`事件循环`,value:`${e.eventLoop.maxMs.toFixed(1)} ms`,detail:`mean ${e.eventLoop.meanMs.toFixed(1)} ms`}];return(0,B.jsxs)(`div`,{className:`meddle-thin-scroll app-workspace-content overflow-y-auto`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,B.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-2`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,B.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight`,children:`运行健康`}),(0,B.jsx)(Y,{status:e.status})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-3 text-xs text-muted-foreground`,children:[(0,B.jsxs)(`span`,{children:[`PID `,e.pid]}),(0,B.jsxs)(`span`,{children:[`运行 `,G(e.uptimeSec)]}),(0,B.jsx)(`span`,{children:e.platform}),(0,B.jsxs)(`span`,{children:[`更新 `,K(e.generatedAt)]})]})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,B.jsxs)(`div`,{className:`flex h-8 items-center gap-2 rounded-md border bg-background px-3 text-sm`,children:[(0,B.jsx)(d,{checked:H,onCheckedChange:Z,"aria-label":`自动刷新健康信息`}),(0,B.jsx)(`span`,{children:`自动刷新`})]}),(0,B.jsxs)(i,{variant:`outline`,size:`sm`,onClick:()=>void Q(!0),disabled:o,children:[(0,B.jsx)(l,{"data-icon":`inline-start`,className:n(o&&`animate-spin`)}),`刷新`]})]})]}),b&&(0,B.jsxs)(O,{variant:`destructive`,children:[(0,B.jsx)(D,{children:`刷新失败`}),(0,B.jsx)(E,{children:b})]}),(0,B.jsx)(`div`,{className:`grid gap-[var(--ui-section-gap)] md:grid-cols-2 xl:grid-cols-6`,children:ce.map(e=>(0,B.jsx)(oe,{...e},e.label))}),(0,B.jsxs)(`div`,{className:`grid gap-[var(--ui-section-gap)] xl:grid-cols-[minmax(0,1.3fr)_minmax(360px,0.7fr)]`,children:[(0,B.jsxs)(T,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsxs)(y,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:[(0,B.jsxs)(S,{className:`flex items-center gap-2`,children:[(0,B.jsx)(re,{}),`健康检查`]}),(0,B.jsx)(x,{children:`阈值来自当前进程的 MEDDLE_WATCHDOG 配置。`})]}),(0,B.jsx)(C,{className:`p-0`,children:(0,B.jsxs)(P,{children:[(0,B.jsx)(k,{children:(0,B.jsxs)(M,{children:[(0,B.jsx)(A,{children:`项目`}),(0,B.jsx)(A,{children:`状态`}),(0,B.jsx)(A,{children:`当前值`}),(0,B.jsx)(A,{children:`阈值`})]})}),(0,B.jsx)(j,{children:e.checks.map(e=>(0,B.jsxs)(M,{children:[(0,B.jsx)(N,{className:`font-medium`,children:ie[e.name]||e.name}),(0,B.jsx)(N,{children:(0,B.jsx)(Y,{status:e.status})}),(0,B.jsx)(N,{children:q(e.value,e.unit)}),(0,B.jsx)(N,{className:`text-muted-foreground`,children:J(e.limit,e.unit)})]},e.name))})]})})]}),(0,B.jsxs)(T,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsxs)(y,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:[(0,B.jsxs)(S,{className:`flex items-center gap-2`,children:[(0,B.jsx)(ee,{}),`守护策略`]}),(0,B.jsx)(x,{children:`连续命中严重阈值后按策略处理。`}),(0,B.jsx)(ne,{children:(0,B.jsx)(h,{variant:e.watchdog.config.enabled?`default`:`secondary`,children:e.watchdog.config.enabled?`已启用`:`已关闭`})})]}),(0,B.jsxs)(C,{className:`grid gap-[var(--ui-section-gap)] p-[var(--ui-page-padding)] sm:grid-cols-2`,children:[(0,B.jsx)(X,{label:`动作`,value:e.watchdog.config.action===`exit`?`退出重启`:`仅告警`}),(0,B.jsx)(X,{label:`检测间隔`,value:G(e.watchdog.config.intervalMs/1e3)}),(0,B.jsx)(X,{label:`最小运行时间`,value:G(e.watchdog.config.minUptimeMs/1e3)}),(0,B.jsx)(X,{label:`失败阈值`,value:`${e.watchdog.consecutiveFailures}/${e.watchdog.config.failureThreshold}`}),(0,B.jsx)(X,{label:`CPU 阈值`,value:`${e.watchdog.config.cpuPercent}%`}),(0,B.jsx)(X,{label:`RSS 阈值`,value:W(e.watchdog.config.rssBytes)}),(0,B.jsx)(X,{label:`连接阈值`,value:String(e.watchdog.config.connectionCount)}),(0,B.jsx)(X,{label:`FD 阈值`,value:String(e.watchdog.config.fdCount)}),e.watchdog.lastReason&&(0,B.jsx)(`div`,{className:`sm:col-span-2`,children:(0,B.jsxs)(O,{children:[(0,B.jsx)(w,{}),(0,B.jsx)(D,{children:`最近命中`}),(0,B.jsx)(E,{children:e.watchdog.lastReason})]})})]})]})]}),(0,B.jsxs)(`div`,{className:`grid gap-[var(--ui-section-gap)] xl:grid-cols-2`,children:[(0,B.jsxs)(T,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsxs)(y,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:[(0,B.jsxs)(S,{className:`flex items-center gap-2`,children:[(0,B.jsx)(u,{}),`MITM 服务池`]}),(0,B.jsxs)(x,{children:[e.mitmServers.count,` 个动态 HTTPS 服务。`]})]}),(0,B.jsx)(C,{className:`p-0`,children:e.mitmServers.items.length>0?(0,B.jsxs)(P,{children:[(0,B.jsx)(k,{children:(0,B.jsxs)(M,{children:[(0,B.jsx)(A,{children:`Host`}),(0,B.jsx)(A,{children:`端口`}),(0,B.jsx)(A,{children:`Socket`}),(0,B.jsx)(A,{children:`空闲`})]})}),(0,B.jsx)(j,{children:e.mitmServers.items.map(e=>(0,B.jsxs)(M,{children:[(0,B.jsx)(N,{className:`max-w-[260px] truncate font-medium`,title:e.host,children:e.host}),(0,B.jsx)(N,{children:e.port??`-`}),(0,B.jsxs)(N,{children:[e.activeSockets,` / `,e.webSockets,` WS`]}),(0,B.jsx)(N,{className:`text-muted-foreground`,children:e.idleForMs==null?`-`:G(e.idleForMs/1e3)})]},`${e.host}:${e.port??`dynamic`}`))})]}):(0,B.jsx)(g,{className:`border-0 py-10`,children:(0,B.jsxs)(v,{children:[(0,B.jsx)(m,{variant:`icon`,children:(0,B.jsx)(c,{})}),(0,B.jsx)(_,{children:`暂无动态 HTTPS 服务`}),(0,B.jsx)(p,{children:`当前没有活跃的 MITM 目标。`})]})})})]}),(0,B.jsxs)(T,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsxs)(y,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:[(0,B.jsxs)(S,{className:`flex items-center gap-2`,children:[(0,B.jsx)(s,{}),`日志限流`]}),(0,B.jsxs)(x,{children:[`已抑制 `,$?.suppressedTotal??0,` 条重复日志。`]})]}),(0,B.jsx)(C,{className:`p-0`,children:$&&$.keys.length>0?(0,B.jsxs)(P,{children:[(0,B.jsx)(k,{children:(0,B.jsxs)(M,{children:[(0,B.jsx)(A,{children:`Key`}),(0,B.jsx)(A,{children:`级别`}),(0,B.jsx)(A,{children:`输出 / 抑制`}),(0,B.jsx)(A,{children:`最近`})]})}),(0,B.jsx)(j,{children:$.keys.map(e=>(0,B.jsxs)(M,{children:[(0,B.jsx)(N,{className:`max-w-[260px] truncate font-medium`,title:e.key,children:e.key}),(0,B.jsx)(N,{children:(0,B.jsx)(h,{variant:e.level===`error`?`destructive`:e.level===`warn`?`secondary`:`outline`,children:e.level})}),(0,B.jsxs)(N,{children:[e.emitted,` / `,e.suppressed]}),(0,B.jsx)(N,{className:`text-muted-foreground`,children:K(e.lastSeenAt)})]},e.key))})]}):(0,B.jsx)(g,{className:`border-0 py-10`,children:(0,B.jsxs)(v,{children:[(0,B.jsx)(m,{variant:`icon`,children:(0,B.jsx)(s,{})}),(0,B.jsx)(_,{children:`暂无限流记录`}),(0,B.jsx)(p,{children:`当前没有被抑制的重复日志。`})]})})})]})]})]})}export{Z as HealthPanel};
|
|
1
|
+
import{c as e,d as t,l as n,p as r,t as i,u as a}from"./button-BFNlGZ5p.js";import"./dist-CFZ4xMSF.js";import{t as o}from"./circle-x-BEkinhez.js";import{n as s,t as c}from"./server-eYXq3PbE.js";import{t as l}from"./refresh-cw-BfLoHqg5.js";import{t as ee}from"./shield-check-hQXjdfZ7.js";import{t as u}from"./wifi-Cjj_Br1u.js";import{t as d}from"./switch-94vgsMHm.js";import{$ as f,H as p,Tt as te,U as m,V as h,W as g,at as _,ct as v,it as y,jt as b,nt as x,ot as S,rt as ne,st as C,tt as w,ut as re,z as T}from"./index-C4dIj1nT.js";import{n as E,r as D,t as O}from"./alert-B514Frte.js";import{a as k,i as A,n as j,o as M,r as N,t as P}from"./table-DaXD6jJv.js";var F=a(`cpu`,[[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M17 20v2`,key:`1rnc9c`}],[`path`,{d:`M17 2v2`,key:`11trls`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M2 17h2`,key:`7oei6x`}],[`path`,{d:`M2 7h2`,key:`asdhe0`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`M20 17h2`,key:`1fpfkl`}],[`path`,{d:`M20 7h2`,key:`1o8tra`}],[`path`,{d:`M7 20v2`,key:`4gnj0m`}],[`path`,{d:`M7 2v2`,key:`1i4yhu`}],[`rect`,{x:`4`,y:`4`,width:`16`,height:`16`,rx:`2`,key:`1vbyd7`}],[`rect`,{x:`8`,y:`8`,width:`8`,height:`8`,rx:`1`,key:`z9xiuo`}]]),I=a(`gauge`,[[`path`,{d:`m12 14 4-4`,key:`9kzdfg`}],[`path`,{d:`M3.34 19a10 10 0 1 1 17.32 0`,key:`19p75a`}]]),L=a(`hard-drive`,[[`line`,{x1:`22`,x2:`2`,y1:`12`,y2:`12`,key:`1y58io`}],[`path`,{d:`M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`oot6mr`}],[`line`,{x1:`6`,x2:`6.01`,y1:`16`,y2:`16`,key:`sgf278`}],[`line`,{x1:`10`,x2:`10.01`,y1:`16`,y2:`16`,key:`1l4acy`}]]),R=a(`network`,[[`rect`,{x:`16`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`4q2zg0`}],[`rect`,{x:`2`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`8cvhb9`}],[`rect`,{x:`9`,y:`2`,width:`6`,height:`6`,rx:`1`,key:`1egb70`}],[`path`,{d:`M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3`,key:`1jsf9p`}],[`path`,{d:`M12 12V8`,key:`2874zd`}]]),z=r(t(),1),B=e(),V={ok:`正常`,degraded:`降级`,critical:`严重`},ie={cpu:`CPU`,rss:`RSS 内存`,connections:`连接数`,mitmServers:`MITM 服务`,eventLoopDelay:`事件循环延迟`,fds:`文件描述符`};function H(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.generatedAt==`number`&&typeof t.status==`string`&&typeof t.pid==`number`&&typeof t.uptimeSec==`number`&&!!t.memory&&!!t.cpu&&!!t.connections&&!!t.mitmServers&&Array.isArray(t.checks)}async function U(){let e=await fetch(`/api/health`,{cache:`no-store`});if(!e.ok)throw Error(`健康接口返回 ${e.status}`);let t=await e.json();if(!H(t))throw Error(`健康接口返回格式不正确`);return t}function W(e){if(!Number.isFinite(e))return`-`;if(e<1024)return`${e} B`;let t=[`KB`,`MB`,`GB`,`TB`],n=e/1024,r=t[0];for(let e=1;e<t.length&&n>=1024;e+=1)n/=1024,r=t[e];return`${n>=10?n.toFixed(0):n.toFixed(1)} ${r}`}function G(e){if(!Number.isFinite(e)||e<0)return`-`;let t=Math.floor(e/86400),n=Math.floor(e%86400/3600),r=Math.floor(e%3600/60),i=Math.floor(e%60);return t>0?`${t}天 ${n}小时`:n>0?`${n}小时 ${r}分钟`:r>0?`${r}分钟 ${i}秒`:`${i}秒`}function K(e){return e?new Intl.DateTimeFormat(`zh-CN`,{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).format(new Date(e)):`-`}function q(e,t){return t===`bytes`?W(e):t===`%`?`${e.toFixed(1)}%`:t===`ms`?`${e.toFixed(1)} ms`:String(e)}function J(e,t){return t===`bytes`?W(e):t===`%`?`${e}%`:t===`ms`?`${e} ms`:String(e)}function ae(e){if(!e||typeof e!=`object`)return null;let t=e;return Array.isArray(t.keys)?{windowMs:Number(t.windowMs)||0,maxPerWindow:Number(t.maxPerWindow)||0,keys:t.keys,suppressedTotal:Number(t.suppressedTotal)||0}:null}function Y({status:e}){return(0,B.jsxs)(f,{variant:e===`critical`?`destructive`:e===`degraded`?`secondary`:`default`,children:[e===`ok`?(0,B.jsx)(b,{}):e===`degraded`?(0,B.jsx)(v,{}):(0,B.jsx)(o,{}),V[e]]})}function oe({icon:e,label:t,value:n,detail:r}){return(0,B.jsxs)(x,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsx)(S,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:(0,B.jsxs)(C,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,B.jsx)(e,{}),t]})}),(0,B.jsxs)(y,{className:`flex flex-col gap-1 p-[var(--ui-page-padding)]`,children:[(0,B.jsx)(`div`,{className:`text-2xl font-semibold tracking-tight`,children:n}),(0,B.jsx)(`div`,{className:`min-h-4 truncate text-xs text-muted-foreground`,title:r,children:r})]})]})}function X({label:e,value:t}){return(0,B.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1 rounded-lg border bg-background p-[var(--ui-section-gap)]`,children:[(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e}),(0,B.jsx)(`span`,{className:`truncate text-sm font-medium`,title:t,children:t})]})}function se(){return(0,B.jsxs)(`div`,{className:`app-workspace-content`,"aria-label":`正在读取健康状态`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,B.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,B.jsx)(w,{className:`h-7 w-40`}),(0,B.jsx)(w,{className:`h-4 w-64`})]}),(0,B.jsx)(w,{className:`h-8 w-28`})]}),(0,B.jsx)(`div`,{className:`grid gap-[var(--ui-section-gap)] md:grid-cols-2 xl:grid-cols-6`,children:Array.from({length:6}).map((e,t)=>(0,B.jsx)(w,{className:`h-32 w-full`},t))}),(0,B.jsx)(w,{className:`h-80 w-full`})]})}function Z(){let[e,t]=(0,z.useState)(null),[r,a]=(0,z.useState)(!0),[o,b]=(0,z.useState)(!1),[w,V]=(0,z.useState)(``),[H,Z]=(0,z.useState)(!0),Q=(0,z.useCallback)(async(e=!1)=>{e?b(!0):a(!0),V(``);try{t(await U())}catch(e){V(e instanceof Error?e.message:`无法读取健康状态`)}finally{a(!1),b(!1)}},[]);(0,z.useEffect)(()=>{Q()},[Q]),(0,z.useEffect)(()=>{if(!H)return;let e=window.setInterval(()=>{Q(!0)},5e3);return()=>window.clearInterval(e)},[H,Q]);let $=(0,z.useMemo)(()=>ae(e?.logs),[e]);if(r&&!e)return(0,B.jsx)(se,{});if(!e)return(0,B.jsxs)(`div`,{className:`app-workspace-content`,children:[(0,B.jsxs)(O,{variant:`destructive`,children:[(0,B.jsx)(D,{children:`加载失败`}),(0,B.jsx)(E,{children:w||`无法读取健康状态`})]}),(0,B.jsxs)(i,{variant:`outline`,size:`sm`,onClick:()=>void Q(),children:[(0,B.jsx)(l,{"data-icon":`inline-start`}),`重新检测`]})]});let ce=[{icon:F,label:`CPU`,value:`${e.cpu.percent.toFixed(1)}%`,detail:`${e.cpu.cores} 核 · load ${e.cpu.loadAverage.map(e=>e.toFixed(2)).join(` / `)}`},{icon:L,label:`RSS 内存`,value:W(e.memory.rss),detail:`Heap ${W(e.memory.heapUsed)} / ${W(e.memory.heapTotal)}`},{icon:R,label:`TCP 连接`,value:String(e.connections.total),detail:`代理 ${e.connections.proxySockets} · TLS ${e.connections.mitmTlsSockets} · WS ${e.connections.webSockets}`},{icon:c,label:`MITM 服务`,value:String(e.mitmServers.count),detail:`${e.mitmServers.activeSockets} 个活跃 socket`},{icon:re,label:`文件描述符`,value:e.process.fdCount==null?`-`:String(e.process.fdCount),detail:`handles ${e.process.activeHandles??`-`} · requests ${e.process.activeRequests??`-`}`},{icon:I,label:`事件循环`,value:`${e.eventLoop.maxMs.toFixed(1)} ms`,detail:`mean ${e.eventLoop.meanMs.toFixed(1)} ms`}];return(0,B.jsxs)(`div`,{className:`meddle-thin-scroll app-workspace-content overflow-y-auto`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,B.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-2`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,B.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight`,children:`运行健康`}),(0,B.jsx)(Y,{status:e.status})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-3 text-xs text-muted-foreground`,children:[(0,B.jsxs)(`span`,{children:[`PID `,e.pid]}),(0,B.jsxs)(`span`,{children:[`运行 `,G(e.uptimeSec)]}),(0,B.jsx)(`span`,{children:e.platform}),(0,B.jsxs)(`span`,{children:[`更新 `,K(e.generatedAt)]})]})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,B.jsxs)(`div`,{className:`flex h-8 items-center gap-2 rounded-md border bg-background px-3 text-sm`,children:[(0,B.jsx)(d,{checked:H,onCheckedChange:Z,"aria-label":`自动刷新健康信息`}),(0,B.jsx)(`span`,{children:`自动刷新`})]}),(0,B.jsxs)(i,{variant:`outline`,size:`sm`,onClick:()=>void Q(!0),disabled:o,children:[(0,B.jsx)(l,{"data-icon":`inline-start`,className:n(o&&`animate-spin`)}),`刷新`]})]})]}),w&&(0,B.jsxs)(O,{variant:`destructive`,children:[(0,B.jsx)(D,{children:`刷新失败`}),(0,B.jsx)(E,{children:w})]}),(0,B.jsx)(`div`,{className:`grid gap-[var(--ui-section-gap)] md:grid-cols-2 xl:grid-cols-6`,children:ce.map(e=>(0,B.jsx)(oe,{...e},e.label))}),(0,B.jsxs)(`div`,{className:`grid gap-[var(--ui-section-gap)] xl:grid-cols-[minmax(0,1.3fr)_minmax(360px,0.7fr)]`,children:[(0,B.jsxs)(x,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsxs)(S,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:[(0,B.jsxs)(C,{className:`flex items-center gap-2`,children:[(0,B.jsx)(te,{}),`健康检查`]}),(0,B.jsx)(_,{children:`阈值来自当前进程的 MEDDLE_WATCHDOG 配置。`})]}),(0,B.jsx)(y,{className:`p-0`,children:(0,B.jsxs)(P,{children:[(0,B.jsx)(k,{children:(0,B.jsxs)(M,{children:[(0,B.jsx)(A,{children:`项目`}),(0,B.jsx)(A,{children:`状态`}),(0,B.jsx)(A,{children:`当前值`}),(0,B.jsx)(A,{children:`阈值`})]})}),(0,B.jsx)(j,{children:e.checks.map(e=>(0,B.jsxs)(M,{children:[(0,B.jsx)(N,{className:`font-medium`,children:ie[e.name]||e.name}),(0,B.jsx)(N,{children:(0,B.jsx)(Y,{status:e.status})}),(0,B.jsx)(N,{children:q(e.value,e.unit)}),(0,B.jsx)(N,{className:`text-muted-foreground`,children:J(e.limit,e.unit)})]},e.name))})]})})]}),(0,B.jsxs)(x,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsxs)(S,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:[(0,B.jsxs)(C,{className:`flex items-center gap-2`,children:[(0,B.jsx)(ee,{}),`守护策略`]}),(0,B.jsx)(_,{children:`连续命中严重阈值后按策略处理。`}),(0,B.jsx)(ne,{children:(0,B.jsx)(f,{variant:e.watchdog.config.enabled?`default`:`secondary`,children:e.watchdog.config.enabled?`已启用`:`已关闭`})})]}),(0,B.jsxs)(y,{className:`grid gap-[var(--ui-section-gap)] p-[var(--ui-page-padding)] sm:grid-cols-2`,children:[(0,B.jsx)(X,{label:`动作`,value:e.watchdog.config.action===`exit`?`退出重启`:`仅告警`}),(0,B.jsx)(X,{label:`检测间隔`,value:G(e.watchdog.config.intervalMs/1e3)}),(0,B.jsx)(X,{label:`最小运行时间`,value:G(e.watchdog.config.minUptimeMs/1e3)}),(0,B.jsx)(X,{label:`失败阈值`,value:`${e.watchdog.consecutiveFailures}/${e.watchdog.config.failureThreshold}`}),(0,B.jsx)(X,{label:`CPU 阈值`,value:`${e.watchdog.config.cpuPercent}%`}),(0,B.jsx)(X,{label:`RSS 阈值`,value:W(e.watchdog.config.rssBytes)}),(0,B.jsx)(X,{label:`连接阈值`,value:String(e.watchdog.config.connectionCount)}),(0,B.jsx)(X,{label:`FD 阈值`,value:String(e.watchdog.config.fdCount)}),e.watchdog.lastReason&&(0,B.jsx)(`div`,{className:`sm:col-span-2`,children:(0,B.jsxs)(O,{children:[(0,B.jsx)(v,{}),(0,B.jsx)(D,{children:`最近命中`}),(0,B.jsx)(E,{children:e.watchdog.lastReason})]})})]})]})]}),(0,B.jsxs)(`div`,{className:`grid gap-[var(--ui-section-gap)] xl:grid-cols-2`,children:[(0,B.jsxs)(x,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsxs)(S,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:[(0,B.jsxs)(C,{className:`flex items-center gap-2`,children:[(0,B.jsx)(u,{}),`MITM 服务池`]}),(0,B.jsxs)(_,{children:[e.mitmServers.count,` 个动态 HTTPS 服务。`]})]}),(0,B.jsx)(y,{className:`p-0`,children:e.mitmServers.items.length>0?(0,B.jsxs)(P,{children:[(0,B.jsx)(k,{children:(0,B.jsxs)(M,{children:[(0,B.jsx)(A,{children:`Host`}),(0,B.jsx)(A,{children:`端口`}),(0,B.jsx)(A,{children:`Socket`}),(0,B.jsx)(A,{children:`空闲`})]})}),(0,B.jsx)(j,{children:e.mitmServers.items.map(e=>(0,B.jsxs)(M,{children:[(0,B.jsx)(N,{className:`max-w-[260px] truncate font-medium`,title:e.host,children:e.host}),(0,B.jsx)(N,{children:e.port??`-`}),(0,B.jsxs)(N,{children:[e.activeSockets,` / `,e.webSockets,` WS`]}),(0,B.jsx)(N,{className:`text-muted-foreground`,children:e.idleForMs==null?`-`:G(e.idleForMs/1e3)})]},`${e.host}:${e.port??`dynamic`}`))})]}):(0,B.jsx)(T,{className:`border-0 py-10`,children:(0,B.jsxs)(p,{children:[(0,B.jsx)(m,{variant:`icon`,children:(0,B.jsx)(c,{})}),(0,B.jsx)(g,{children:`暂无动态 HTTPS 服务`}),(0,B.jsx)(h,{children:`当前没有活跃的 MITM 目标。`})]})})})]}),(0,B.jsxs)(x,{className:`gap-0 py-0 shadow-none`,children:[(0,B.jsxs)(S,{className:`border-b px-[var(--ui-section-gap)] py-[var(--ui-section-gap)] [.border-b]:pb-[var(--ui-section-gap)]`,children:[(0,B.jsxs)(C,{className:`flex items-center gap-2`,children:[(0,B.jsx)(s,{}),`日志限流`]}),(0,B.jsxs)(_,{children:[`已抑制 `,$?.suppressedTotal??0,` 条重复日志。`]})]}),(0,B.jsx)(y,{className:`p-0`,children:$&&$.keys.length>0?(0,B.jsxs)(P,{children:[(0,B.jsx)(k,{children:(0,B.jsxs)(M,{children:[(0,B.jsx)(A,{children:`Key`}),(0,B.jsx)(A,{children:`级别`}),(0,B.jsx)(A,{children:`输出 / 抑制`}),(0,B.jsx)(A,{children:`最近`})]})}),(0,B.jsx)(j,{children:$.keys.map(e=>(0,B.jsxs)(M,{children:[(0,B.jsx)(N,{className:`max-w-[260px] truncate font-medium`,title:e.key,children:e.key}),(0,B.jsx)(N,{children:(0,B.jsx)(f,{variant:e.level===`error`?`destructive`:e.level===`warn`?`secondary`:`outline`,children:e.level})}),(0,B.jsxs)(N,{children:[e.emitted,` / `,e.suppressed]}),(0,B.jsx)(N,{className:`text-muted-foreground`,children:K(e.lastSeenAt)})]},e.key))})]}):(0,B.jsx)(T,{className:`border-0 py-10`,children:(0,B.jsxs)(p,{children:[(0,B.jsx)(m,{variant:`icon`,children:(0,B.jsx)(s,{})}),(0,B.jsx)(g,{children:`暂无限流记录`}),(0,B.jsx)(h,{children:`当前没有被抑制的重复日志。`})]})})})]})]})]})}export{Z as HealthPanel};
|