@aalis/plugin-webui-client 0.12.1 → 0.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AuthorityPage-BQDYg1E1.js → AuthorityPage-BqbTbZGl.js} +1 -1
- package/dist/assets/{DynamicPage-DO0WnqVF.js → DynamicPage-BLL0Jjj-.js} +6 -6
- package/dist/assets/FilesPage-CPzzHEJs.js +16 -0
- package/dist/assets/MarketplacePage-BnFRPE6h.js +6 -0
- package/dist/assets/{PlatformPage-DEnexgD7.js → PlatformPage-DfR5EkvP.js} +1 -1
- package/dist/assets/PluginConfigPage-BgARQZaR.js +23 -0
- package/dist/assets/SessionsPage-B2xpCNug.js +1 -0
- package/dist/assets/{arc-DnVU9gDd.js → arc-CQe2nGSx.js} +1 -1
- package/dist/assets/{architectureDiagram-3BPJPVTR-D8geOE_F.js → architectureDiagram-3BPJPVTR-Cvkrufdn.js} +1 -1
- package/dist/assets/{blockDiagram-GPEHLZMM-BFbUkYo9.js → blockDiagram-GPEHLZMM-BzO74F_v.js} +1 -1
- package/dist/assets/{c4Diagram-AAUBKEIU-D-508PnY.js → c4Diagram-AAUBKEIU-BlOYmvpJ.js} +1 -1
- package/dist/assets/channel-DxFgDxL2.js +1 -0
- package/dist/assets/{chunk-2J33WTMH-BBSHca43.js → chunk-2J33WTMH-DFwRx-nE.js} +1 -1
- package/dist/assets/{chunk-4BX2VUAB-CYpAo1Fy.js → chunk-4BX2VUAB-CduB1PNc.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-CT9vDGm-.js → chunk-55IACEB6-21xZxRLc.js} +1 -1
- package/dist/assets/{chunk-727SXJPM-Qbj03s5s.js → chunk-727SXJPM-BzmUekfP.js} +1 -1
- package/dist/assets/{chunk-AQP2D5EJ-D7h7VPGB.js → chunk-AQP2D5EJ-CdlRaCrQ.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-B-8aZQXh.js → chunk-FMBD7UC4-CJRlGDhE.js} +1 -1
- package/dist/assets/{chunk-ND2GUHAM-aY4Jm31a.js → chunk-ND2GUHAM-DnSWO3aS.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-Bf1fE05f.js → chunk-QZHKN3VN-Dj5n19FW.js} +1 -1
- package/dist/assets/classDiagram-4FO5ZUOK-bnDp8shu.js +1 -0
- package/dist/assets/classDiagram-v2-Q7XG4LA2-bnDp8shu.js +1 -0
- package/dist/assets/{clock-CHmqRkfK.js → clock-W2ha6TRb.js} +1 -1
- package/dist/assets/{cose-bilkent-S5V4N54A-CLhPrA-X.js → cose-bilkent-S5V4N54A-ClfKZKqe.js} +1 -1
- package/dist/assets/{dagre-BM42HDAG-ldqthtLi.js → dagre-BM42HDAG-jazTBzPR.js} +1 -1
- package/dist/assets/{diagram-2AECGRRQ-gVpyidoY.js → diagram-2AECGRRQ-DyxWZPwj.js} +1 -1
- package/dist/assets/{diagram-5GNKFQAL-DZO2z7Tj.js → diagram-5GNKFQAL-DqCbPzXj.js} +1 -1
- package/dist/assets/{diagram-KO2AKTUF-CdJUd5dD.js → diagram-KO2AKTUF-CmZvNtBG.js} +1 -1
- package/dist/assets/{diagram-LMA3HP47-ShvNokM1.js → diagram-LMA3HP47-6T2L5BXp.js} +1 -1
- package/dist/assets/{diagram-OG6HWLK6-BAYrIDPL.js → diagram-OG6HWLK6-4sYw9ZQs.js} +1 -1
- package/dist/assets/{erDiagram-TEJ5UH35--6H9xqgq.js → erDiagram-TEJ5UH35-D0ob0KXX.js} +1 -1
- package/dist/assets/{flowDiagram-I6XJVG4X-jsKUH1HR.js → flowDiagram-I6XJVG4X--eCEup-R.js} +1 -1
- package/dist/assets/{ganttDiagram-6RSMTGT7-DFYCrHNq.js → ganttDiagram-6RSMTGT7-m3TQjkjn.js} +1 -1
- package/dist/assets/{gitGraphDiagram-PVQCEYII-DuOMKvRu.js → gitGraphDiagram-PVQCEYII-CPGaB1tr.js} +1 -1
- package/dist/assets/{globe-BfItFm6P.js → globe-DBjh8D_x.js} +1 -1
- package/dist/assets/index-CP1eHYpM.js +212 -0
- package/dist/assets/{infoDiagram-5YYISTIA-CFc4L9CY.js → infoDiagram-5YYISTIA-BVnSCwcT.js} +1 -1
- package/dist/assets/{ishikawaDiagram-YF4QCWOH-Cpv8QGG-.js → ishikawaDiagram-YF4QCWOH-85DqNeCY.js} +1 -1
- package/dist/assets/{journeyDiagram-JHISSGLW-D_ZYi-l_.js → journeyDiagram-JHISSGLW-Cky18vs0.js} +1 -1
- package/dist/assets/{kanban-definition-UN3LZRKU-BAu1Iapx.js → kanban-definition-UN3LZRKU-D84piZkn.js} +1 -1
- package/dist/assets/{linear-CWbLakH9.js → linear-TNUZDVve.js} +1 -1
- package/dist/assets/{mermaid.core-DCKNrwR3.js → mermaid.core-CiVUCO-O.js} +4 -4
- package/dist/assets/{mindmap-definition-RKZ34NQL-CwjfqD6z.js → mindmap-definition-RKZ34NQL-BFFaTXUp.js} +1 -1
- package/dist/assets/{pieDiagram-4H26LBE5-iBQqAGdJ.js → pieDiagram-4H26LBE5-BPNYmIiO.js} +1 -1
- package/dist/assets/{quadrantDiagram-W4KKPZXB-Bj5J8IjM.js → quadrantDiagram-W4KKPZXB-OVTXENUG.js} +1 -1
- package/dist/assets/{requirementDiagram-4Y6WPE33-X-8ktpsm.js → requirementDiagram-4Y6WPE33-CGWBxus5.js} +1 -1
- package/dist/assets/{sankeyDiagram-5OEKKPKP-DIkb4KbP.js → sankeyDiagram-5OEKKPKP-C0MTZuTr.js} +1 -1
- package/dist/assets/{sequenceDiagram-3UESZ5HK-Hlda4VPB.js → sequenceDiagram-3UESZ5HK-DT4KwDYb.js} +1 -1
- package/dist/assets/{stateDiagram-AJRCARHV-NOKt-PZ_.js → stateDiagram-AJRCARHV-BBNJwMVt.js} +1 -1
- package/dist/assets/{stateDiagram-v2-BHNVJYJU-BF5REMmu.js → stateDiagram-v2-BHNVJYJU-B4Inm8LB.js} +1 -1
- package/dist/assets/{timeline-definition-PNZ67QCA-CbG_bPsY.js → timeline-definition-PNZ67QCA-DuhrqPcq.js} +1 -1
- package/dist/assets/{vennDiagram-CIIHVFJN-BVLsgOPX.js → vennDiagram-CIIHVFJN-DrwNTuSP.js} +1 -1
- package/dist/assets/{wardley-L42UT6IY-nRiwVAku.js → wardley-L42UT6IY-CYF_y2Eu.js} +1 -1
- package/dist/assets/{wardleyDiagram-YWT4CUSO-jStW0NJa.js → wardleyDiagram-YWT4CUSO-I6e0MQ-e.js} +1 -1
- package/dist/assets/{xychartDiagram-2RQKCTM6-bJC2yQYV.js → xychartDiagram-2RQKCTM6-Df7YUsb2.js} +1 -1
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/dist/assets/FilesPage-BNn0PjPx.js +0 -16
- package/dist/assets/MarketplacePage-HbYZZCz_.js +0 -6
- package/dist/assets/PluginConfigPage-D_MBDTbB.js +0 -23
- package/dist/assets/SessionsPage-BmA9dlNT.js +0 -1
- package/dist/assets/channel-BugX_IAn.js +0 -1
- package/dist/assets/classDiagram-4FO5ZUOK-A8yISGxg.js +0 -1
- package/dist/assets/classDiagram-v2-Q7XG4LA2-A8yISGxg.js +0 -1
- package/dist/assets/index-pGwN5S79.js +0 -212
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as o,j as e}from"./react-vendor-BPQixOLZ.js";import{c as _,p as B,W as xe}from"./index-
|
|
1
|
+
import{r as o,j as e}from"./react-vendor-BPQixOLZ.js";import{c as _,p as B,W as xe}from"./index-CP1eHYpM.js";import{C as ve}from"./clock-W2ha6TRb.js";import"./highlight-DJvvuuwd.js";import"./katex-Bq6vt64r.js";import"./markdown-B2G8c9k5.js";/**
|
|
2
2
|
* @license lucide-react v1.7.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import{r as l,j as e,R as U,a as
|
|
1
|
+
import{r as l,j as e,R as U,a as ot}from"./react-vendor-BPQixOLZ.js";import{c as ke,a as me,p as _,S as it,W as lt,f as Se}from"./index-CP1eHYpM.js";import{S as dt}from"./SchemaForm-BcYxH5r1.js";import{c as _e}from"./cytoscape.esm-LDYqcvCF.js";import{f as ct}from"./cytoscape-fcose-DXAQNCkb.js";import{G as ut}from"./globe-DBjh8D_x.js";import{C as ht}from"./clock-W2ha6TRb.js";import{M as pt,r as gt,a as ft}from"./markdown-B2G8c9k5.js";import"./highlight-DJvvuuwd.js";import"./katex-Bq6vt64r.js";/**
|
|
2
2
|
* @license lucide-react v1.7.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const
|
|
6
|
+
*/const yt=[["path",{d:"M12 18V5",key:"adv99a"}],["path",{d:"M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4",key:"1e3is1"}],["path",{d:"M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5",key:"1gqd8o"}],["path",{d:"M17.997 5.125a4 4 0 0 1 2.526 5.77",key:"iwvgf7"}],["path",{d:"M18 18a4 4 0 0 0 2-7.464",key:"efp6ie"}],["path",{d:"M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517",key:"1gq6am"}],["path",{d:"M6 18a4 4 0 0 1-2-7.464",key:"k1g0md"}],["path",{d:"M6.003 5.125a4 4 0 0 0-2.526 5.77",key:"q97ue3"}]],xt=ke("brain",yt);/**
|
|
7
7
|
* @license lucide-react v1.7.0 - ISC
|
|
8
8
|
*
|
|
9
9
|
* This source code is licensed under the ISC license.
|
|
10
10
|
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
-
*/const
|
|
11
|
+
*/const mt=[["path",{d:"M5 21v-6",key:"1hz6c0"}],["path",{d:"M12 21V3",key:"1lcnhd"}],["path",{d:"M19 21V9",key:"unv183"}]],bt=ke("chart-no-axes-column",mt);/**
|
|
12
12
|
* @license lucide-react v1.7.0 - ISC
|
|
13
13
|
*
|
|
14
14
|
* This source code is licensed under the ISC license.
|
|
15
15
|
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
-
*/const bt=[["path",{d:"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z",key:"w46dr5"}]],vt=ke("puzzle",bt);let Ae=!1;function jt(){Ae||(Be.use(dt),Ae=!0)}function be(t){if(!Number.isFinite(t)||t===0)return"0";if(Math.abs(t)<.01)return t.toExponential(2);const i=t.toPrecision(3);return i.includes("e")||i.includes("E")?i:i.includes(".")?i.replace(/0+$/,"").replace(/\.$/,""):i}const ve="#60a5fa",_e="#fb923c",ee="#ef4444",le="#e4e4ef",je="#0f0f14",$e="#6b7280",kt="#1c1c28",W={topic:"#34d399",place:"#a78bfa",thing:"#fbbf24",work:"#f472b6"},St="#9ca3af",wt=99,Oe={"person-event":"人 → 事件","person-entity":"人 → 物","person-person":"人 → 人","event-event":"事件 → 事件","event-entity":"事件 → 物","entity-entity":"物 → 物"},Ge={initiator:"发起者",participant:"参与者",witness:"旁观者",target:"被指向",reporter:"转述者"},He={enthusiast:"深度卷入",participant:"参与/使用",owner:"拥有",creator:"创作者",critic:"行为性批评",visitor:"到访",mentioned:"仅被提及"},We={friend:"朋友",cp:"CP",rival:"对手",mentor:"师徒",colleague:"同事",familiar:"熟人",antagonist:"敌对",admirer:"仰慕者","is-alias-of":"是…的别名","alt-account-of":"是…的小号"},Ke={positive:"积极",negative:"消极",neutral:"中性",mixed:"复杂"},Nt={superior:"高位(from 高于 to)",peer:"平级",subordinate:"低位(from 低于 to)",unknown:"未知"};function ne(t,s){if(!t)return"";const i=s[t];return i?`${i}(${t})`:t}function Rt(t,s){return s?t==="person-event"?ne(s,Ge):t==="person-entity"?ne(s,He):s:""}const ze=[{selector:"node",style:{label:"data(label)","background-color":ve,color:le,"font-size":11,"text-valign":"bottom","text-margin-y":4,"text-outline-color":je,"text-outline-width":2,width:"mapData(pageRankScale, 0, 1, 20, 56)",height:"mapData(pageRankScale, 0, 1, 20, 56)","border-width":1,"border-color":"#1e3a8a"}},{selector:'node[kind = "event"]',style:{"background-color":_e,shape:"round-rectangle","border-color":"#9a3412",width:"mapData(pageRankScale, 0, 1, 24, 64)",height:"mapData(pageRankScale, 0, 1, 16, 40)"}},{selector:'node[kind = "entity"]',style:{shape:"diamond","background-color":St,"border-color":"#374151",width:"mapData(pageRankScale, 0, 1, 22, 60)",height:"mapData(pageRankScale, 0, 1, 22, 60)"}},{selector:'node[entityKind = "topic"]',style:{"background-color":W.topic}},{selector:'node[entityKind = "place"]',style:{"background-color":W.place}},{selector:'node[entityKind = "thing"]',style:{"background-color":W.thing}},{selector:'node[entityKind = "work"]',style:{"background-color":W.work}},{selector:'node[focused = "1"]',style:{"background-color":ee,"border-color":"#7f1d1d","border-width":3,width:36,height:36}},{selector:"node:selected",style:{"border-width":3,"border-color":"#0ea5e9"}},{selector:"edge",style:{width:"mapData(weightScale, 0, 1, 1, 6)","line-color":$e,"curve-style":"bezier",label:"data(label)","font-size":9,color:le,"text-rotation":"autorotate","text-background-color":kt,"text-background-opacity":.85,"text-background-padding":1,"target-arrow-shape":"triangle","target-arrow-color":$e}},{selector:'edge[kind = "person-event"]',style:{"line-color":"#fbbf24","target-arrow-color":"#fbbf24","line-style":"dashed"}},{selector:'edge[kind = "person-entity"]',style:{"line-color":"#34d399","target-arrow-color":"#34d399","line-style":"dashed"}},{selector:'edge[kind = "event-event"]',style:{"line-color":"#f472b6","target-arrow-color":"#f472b6"}},{selector:'edge[kind = "event-entity"]',style:{"line-color":"#06b6d4","target-arrow-color":"#06b6d4","line-style":"dashed"}},{selector:'edge[kind = "entity-entity"]',style:{"line-color":"#a855f7","target-arrow-color":"#a855f7"}},{selector:'edge[kind = "person-person"]',style:{"line-color":"#f87171","target-arrow-color":"#f87171"}},{selector:'edge[focused = "1"]',style:{"line-color":"#facc15","target-arrow-color":"#facc15",width:4,"overlay-color":"#facc15","overlay-opacity":.25,"overlay-padding":5,"z-index":9999}},{selector:"edge.dimmed",style:{opacity:.15}},{selector:"node.dimmed",style:{opacity:.2,"text-opacity":0}}];function Ct(t,s){if(!(t!=null&&t.length)&&!(s!=null&&s.length))return ze;const i=[];for(const c of t??[]){const u={};c.color&&(u["background-color"]=c.color,u["border-color"]=c.color),c.shape&&(u.shape=c.shape==="circle"?"ellipse":c.shape==="round-rect"?"round-rectangle":"diamond"),i.push({selector:`node[kind = "${c.kind}"]`,style:u})}for(const c of s??[]){const u={};c.color&&(u["line-color"]=c.color,u["target-arrow-color"]=c.color),c.dashed&&(u["line-style"]="dashed"),i.push({selector:`edge[kind = "${c.kind}"]`,style:u})}return[...ze,...i]}function Et({comp:t,pluginName:s,refreshTick:i,onRefresh:c}){var Me,Le;jt();const u=l.useRef(null),o=l.useRef(null),a=l.useRef(null),y=l.useRef(!1),[r,j]=l.useState(null),[z,I]=l.useState(!1),[$,P]=l.useState(null),[C,p]=l.useState(),[k,m]=l.useState(t.defaultMaxDepth??2),[D,_]=l.useState(t.defaultMaxBreadth??10),[se,de]=l.useState(""),[T,re]=l.useState(null),[qe,ce]=l.useState(null),[Ve,Se]=l.useState(!1),[O,we]=l.useState(!1),[ae,ue]=l.useState(null),he="aalis.relgraph.spacing",q=60,pe=1e3,oe=5e3,Ne=120,Re=()=>{if(typeof window>"u")return;const n=window.localStorage.getItem(he);if(n==null)return;const d=Number(n);return Number.isFinite(d)&&d>=q&&d<=oe?d:void 0},[te,Ce]=l.useState(()=>Re()??Ne),[ge,ie]=l.useState(te);l.useEffect(()=>{if(Re()!==void 0)return;let n=!1;return me("/api/plugins/@aalis/plugin-webui-server/config").then(d=>{var S;if(n)return;const b=Number((S=d==null?void 0:d.config)==null?void 0:S.relationGraphDefaultSpacing);Number.isFinite(b)&&b>=q&&b<=oe&&(Ce(b),ie(b))}).catch(()=>{}),()=>{n=!0}},[]);const V=l.useCallback(n=>{if(!Number.isFinite(n))return;const d=Math.max(q,Math.min(oe,Math.round(n)));Ce(d),ie(d);try{window.localStorage.setItem(he,String(d))}catch{}},[]),fe=`relation-graph-h:${s}:${t.source}`,[K,Qe]=l.useState(()=>{if(typeof window>"u")return 520;const n=Number(window.localStorage.getItem(fe));return Number.isFinite(n)&&n>=200?n:520}),Q=l.useRef(null),Xe=l.useCallback(n=>{n.target.setPointerCapture(n.pointerId),Q.current={y:n.clientY,h:K}},[K]),Je=l.useCallback(n=>{if(!Q.current)return;const d=Math.max(200,Math.min(1600,Q.current.h+(n.clientY-Q.current.y)));Qe(d)},[]),Ee=l.useCallback(n=>{if(Q.current){n.target.releasePointerCapture(n.pointerId),Q.current=null;try{window.localStorage.setItem(fe,String(K))}catch{}}},[fe,K]);l.useEffect(()=>{var n;(n=o.current)==null||n.resize()},[K]);const X=l.useCallback(async()=>{I(!0),P(null);try{const n={focusId:C,maxDepth:k<=0?wt:k,maxBreadth:D},d=await B(s,t.source,n);j(d?{nodes:Array.isArray(d.nodes)?d.nodes:[],edges:Array.isArray(d.edges)?d.edges:[],focusId:d.focusId,focusEdge:d.focusEdge,stats:d.stats,globalPrRanks:d.globalPrRanks}:{nodes:[],edges:[]})}catch(n){P(n.message||String(n)),j({nodes:[],edges:[]})}finally{I(!1)}},[s,t.source,C,k,D]);l.useEffect(()=>{X()},[X,i]),l.useEffect(()=>{if(!t.refresh||t.refresh<=0)return;const n=setInterval(X,t.refresh);return()=>clearInterval(n)},[t.refresh,X]),l.useEffect(()=>{if(!u.current)return;const n=Be({container:u.current,elements:[],style:Ct(t.nodeKinds,t.edgeKinds),minZoom:.2,maxZoom:3,wheelSensitivity:.2});o.current=n,n.on("tap","node",S=>{const x=S.target.data();re({data:x}),p(String(x.id))}),n.on("tap","edge",S=>{const x=S.target.id();typeof x=="string"&&x&&(re(null),p(x))});const d=(S,x)=>{const N=[],g=w=>{const f=S[w];return f==null?"":String(f)};if(x){const w=g("label"),f=g("role"),v=g("relationType");w?N.push(w):f?N.push(f):v&&N.push(v);const F=g("description");F&&N.push(F);const A=S.weight;typeof A=="number"&&N.push(`合并强度 ${A.toFixed(2)}`)}else{const w=g("kind"),f=g("title")||g("name")||g("displayName")||g("label");f&&N.push(f);const v=g("category")||g("entityKind");if(v&&N.push(`类型:${v}`),w==="event"){const A=g("sessionScope");A&&N.push(`会话:${A}`)}const F=g("summary");F&&N.push(F)}return N},b=(S,x)=>{var F,A,h;const N=(F=u.current)==null?void 0:F.getBoundingClientRect(),g=S.target.data(),w=d(g,x);if(w.length===0||!N)return;const f=((A=S.renderedPosition)==null?void 0:A.x)??0,v=((h=S.renderedPosition)==null?void 0:h.y)??0;ue({x:f+12,y:v+12,lines:w})};return n.on("mouseover","node",S=>b(S,!1)),n.on("mouseover","edge",S=>b(S,!0)),n.on("mouseout","node",()=>ue(null)),n.on("mouseout","edge",()=>ue(null)),()=>{n.destroy(),o.current=null}},[]),l.useEffect(()=>{const n=o.current;if(!n||!r)return;const d=r.focusId??C,b=new Map;for(const h of r.nodes){if(h.data.kind!=="person")continue;const R=typeof h.data.label=="string"?h.data.label:"";R&&b.set(R,(b.get(R)??0)+1)}const S=h=>{if(h.kind!=="person")return;const R=typeof h.label=="string"?h.label:"";if(!R||(b.get(R)??0)<2)return;const E=typeof h.platform=="string"?h.platform:"?",L=typeof h.userId=="string"?h.userId:"",H=L?`…${L.slice(-4)}`:typeof h.id=="string"?`…${h.id.slice(-4)}`:"?";return`${R} · ${E}:${H}`},x=new Map;for(const h of r.nodes){const R=String(h.data.kind??"person"),E=typeof h.data.lastPageRank=="number"?h.data.lastPageRank:0;let L=x.get(R);L||(L=new Map,x.set(R,L)),L.set(String(h.data.id),E)}const N=new Map;for(const[,h]of x){const R=[...h.entries()].sort((L,H)=>L[1]-H[1]),E=R.length;for(let L=0;L<E;L++){const H=E>1?L/(E-1):.5;N.set(R[L][0],H)}}const g=new Map;{const h=r.edges.map(E=>({id:E.data.id,w:typeof E.data.weight=="number"?E.data.weight:0})).sort((E,L)=>E.w-L.w),R=h.length;for(let E=0;E<R;E++)g.set(h[E].id,R>1?E/(R-1):.5)}const w=[...r.nodes.map(h=>{const R=S(h.data),E=N.get(String(h.data.id))??0;return{data:{...h.data,...R?{label:R}:{},pageRankScale:E,focused:d&&h.data.id===d?"1":void 0},group:"nodes"}}),...r.edges.map(h=>{const R=typeof h.data.label=="string"?h.data.label:"",E=g.get(h.data.id)??0;return{data:{...h.data,label:R,kind:h.data.kind??(h.data.relationType?"person-person":"person-event"),weightScale:E,focused:d&&h.data.id===d?"1":void 0},group:"edges"}})],f=a.current===r;a.current=r;const v=!y.current;let F=1;if(!f){const h=new Map;n.nodes().forEach(L=>{h.set(L.id(),{...L.position()})}),n.elements().remove(),n.add(w);let R=0;n.nodes().forEach(L=>{const H=h.get(L.id());H&&(L.position(H),R++)});const E=n.nodes().length;F=E>0?R/E:0}const A=(v||F<.5)&&!f;n.layout({name:"fcose",animate:f,animationDuration:400,randomize:A&&r.nodes.length>20,nodeRepulsion:(h=>{const R=Math.round(te*117),E=Number(h.data("pageRankScale"))||0;return Math.round(R*(1+3*E))}),idealEdgeLength:(h=>{const R=Number(h.data("weightScale"))||0;return Math.round(te*(1.4-.8*R))}),nodeSeparation:Math.round(te*.67),gravity:.1,gravityRange:3,padding:40,quality:r.nodes.length>300?"default":"proof",uniformNodeDimensions:!1}).run(),r.nodes.length>0&&(y.current=!0)},[r,C,te]),l.useEffect(()=>{const n=o.current;if(!n)return;const d=se.toLowerCase().split(/\s+/).filter(Boolean);if(n.elements().removeClass("dimmed"),d.length===0)return;const b=n.nodes().filter(x=>{const N=[String(x.data("label")??""),String(x.data("kind")??""),String(x.data("entityKind")??""),String(x.data("category")??""),String(x.data("title")??""),String(x.data("name")??""),String(x.data("displayName")??""),String(x.data("summary")??""),String(x.data("sessionScope")??"")].map(g=>g.toLowerCase());return d.every(g=>N.some(w=>w.includes(g)))});if(b.length===0)return;const S=new Set(b.map(x=>x.id()));n.nodes().forEach(x=>{S.has(x.id())||x.addClass("dimmed")}),n.edges().forEach(x=>{S.has(x.source().id())||S.has(x.target().id())||x.addClass("dimmed")})},[se,r]),l.useEffect(()=>{if(!T||!t.detailSource){ce(null);return}Se(!0),B(s,t.detailSource,{nodeId:T.data.id,kind:T.data.kind}).then(n=>ce(n??null)).catch(n=>ce({error:n.message})).finally(()=>Se(!1))},[T,s,t.detailSource]),l.useEffect(()=>{const n=o.current;if(!n)return;const d=requestAnimationFrame(()=>{n.resize(),n.fit(void 0,30)});return()=>cancelAnimationFrame(d)},[C,T]);const et=l.useCallback(()=>{const n=o.current;if(!n||n.elements().length===0)return;const d=n.png({full:!0,scale:2,bg:je,maxWidth:1/0});if(!d||d==="data:,")return;const b=document.createElement("a");b.href=d,b.download=`relation-graph-${Date.now()}.png`,document.body.appendChild(b),b.click(),document.body.removeChild(b)},[]),ye=l.useCallback(()=>{c?c():X()},[c,X]),tt=l.useCallback(async(n,d)=>{if(!(d&&!window.confirm(d)))try{await B(s,n,{focusId:C}),ye()}catch(b){alert(`操作失败: ${b.message}`)}},[s,C,ye]),Ie=(r==null?void 0:r.stats)??{},nt=l.useMemo(()=>{if(!r)return"";const n={persons:"人物",events:"事件",entities:"实体"},d=[`节点 ${r.nodes.length}`,`边 ${r.edges.length}`],b=[];for(const[x,N]of Object.entries(Ie))x!=="edges"&&b.push(`${n[x]??x} ${N}`);const S=b.length?`全库: ${b.join(" · ")}`:"";return[...d,...S?[S]:[]].join(" | ")},[r,Ie]),Pe=l.useMemo(()=>{const n=new Map;if(!r)return n;const d=[];for(const g of r.nodes){const w=g.data.lastPageRank;typeof w!="number"||!Number.isFinite(w)||d.push({id:String(g.data.id),kind:String(g.data.kind??"person"),pr:w})}const b=[...d].sort((g,w)=>w.pr-g.pr),S=b.length,x=new Map;for(let g=0;g<b.length;g++)x.set(b[g].id,g+1);const N=new Map;for(const g of d)N.has(g.kind)||N.set(g.kind,[]),N.get(g.kind).push(g);for(const[,g]of N){g.sort((w,f)=>f.pr-w.pr);for(let w=0;w<g.length;w++)n.set(g[w].id,{kindRank:w+1,kindTotal:g.length,globalRank:x.get(g[w].id)??0,globalTotal:S})}return n},[r]),Fe=l.useMemo(()=>{const n=new Map;if(!(r!=null&&r.globalPrRanks))return n;for(const[d,b]of Object.entries(r.globalPrRanks))n.set(d,b);return n},[r]),st={display:"flex",flexWrap:"wrap",gap:8,alignItems:"center",padding:"8px 10px",background:"var(--bg-secondary)",borderBottom:"1px solid var(--border-color, #2a2a42)",fontSize:12,color:"var(--text)"},rt={width:"100%",height:K,background:je,position:"relative"};return e.jsxs("div",{className:"relation-graph-wrap",style:{border:"1px solid var(--border-color, #e5e7eb)",borderRadius:6,overflow:"hidden"},children:[t.label?e.jsx("div",{style:{padding:"8px 12px",fontWeight:600},children:t.label}):null,e.jsxs("div",{style:st,children:[e.jsxs("div",{style:{position:"relative",flex:"1 1 200px",minWidth:160},children:[e.jsx("input",{type:"text",placeholder:"搜索 (label / kind / entityKind / category,空格分多关键词)",value:se,onChange:n=>de(n.target.value),onCompositionEnd:n=>de(n.target.value),style:{width:"100%",padding:"4px 24px 4px 8px"}}),se?e.jsx("button",{type:"button",onClick:()=>de(""),title:"清除搜索",style:{position:"absolute",right:4,top:"50%",transform:"translateY(-50%)",background:"transparent",border:"none",color:"var(--text-muted, #888)",cursor:"pointer",fontSize:14,padding:"0 4px",lineHeight:1},children:"✕"}):null]}),e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:4,opacity:C?1:.45},title:C?"从焦点节点出发的 BFS 跳数(0 = 不限)":"深度仅在选定焦点后生效:点击节点 → 详情面板 → 「以此为焦点」",children:["深度",e.jsx("input",{type:"range",min:0,max:10,value:k,onChange:n=>m(Number(n.target.value)),disabled:!C}),e.jsx("input",{type:"number",min:0,value:k,onChange:n=>{const d=Number(n.target.value);Number.isFinite(d)&&d>=0&&m(d)},disabled:!C,style:{width:56,padding:"2px 4px",background:"var(--surface)",color:"var(--text)",border:"1px solid var(--surface-active)"}}),e.jsx("span",{style:{width:32,color:"var(--text-secondary)"},children:k===0?"∞":k})]}),e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:4,opacity:C?1:.45},title:C?"焦点模式:每个节点向外展开的邻居数上限(按边权重降序截断;0 = 不限)":"宽度仅在选定焦点后生效:点击图中任一节点即可设为焦点",children:["宽度",e.jsx("input",{type:"range",min:0,max:30,value:D,onChange:n=>_(Number(n.target.value)),disabled:!C}),e.jsx("input",{type:"number",min:0,value:D,onChange:n=>{const d=Number(n.target.value);Number.isFinite(d)&&d>=0&&_(d)},disabled:!C,style:{width:56,padding:"2px 4px",background:"var(--surface)",color:"var(--text)",border:"1px solid var(--surface-active)"}}),e.jsx("span",{style:{width:32,color:"var(--text-secondary)"},children:D===0?"∞":D})]}),e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:4},title:`布局密度(≈ 理想边长 px)。当前 ${ge}。
|
|
16
|
+
*/const vt=[["path",{d:"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z",key:"w46dr5"}]],jt=ke("puzzle",vt);let $e=!1;function kt(){$e||(_e.use(ct),$e=!0)}function be(t){if(!Number.isFinite(t)||t===0)return"0";if(Math.abs(t)<.01)return t.toExponential(2);const i=t.toPrecision(3);return i.includes("e")||i.includes("E")?i:i.includes(".")?i.replace(/0+$/,"").replace(/\.$/,""):i}const ve="#60a5fa",Oe="#fb923c",ee="#ef4444",le="#e4e4ef",je="#0f0f14",ze="#6b7280",St="#1c1c28",W={topic:"#34d399",place:"#a78bfa",thing:"#fbbf24",work:"#f472b6"},wt="#9ca3af",Nt=99,Ge={"person-event":"人 → 事件","person-entity":"人 → 物","person-person":"人 → 人","event-event":"事件 → 事件","event-entity":"事件 → 物","entity-entity":"物 → 物"},He={initiator:"发起者",participant:"参与者",witness:"旁观者",target:"被指向",reporter:"转述者"},We={enthusiast:"深度卷入",participant:"参与/使用",owner:"拥有",creator:"创作者",critic:"行为性批评",visitor:"到访",mentioned:"仅被提及"},Ke={friend:"朋友",cp:"CP",rival:"对手",mentor:"师徒",colleague:"同事",familiar:"熟人",antagonist:"敌对",admirer:"仰慕者","is-alias-of":"是…的别名","alt-account-of":"是…的小号"},Ye={positive:"积极",negative:"消极",neutral:"中性",mixed:"复杂"},Rt={superior:"高位(from 高于 to)",peer:"平级",subordinate:"低位(from 低于 to)",unknown:"未知"};function ne(t,s){if(!t)return"";const i=s[t];return i?`${i}(${t})`:t}function Ct(t,s){return s?t==="person-event"?ne(s,He):t==="person-entity"?ne(s,We):s:""}const De=[{selector:"node",style:{label:"data(label)","background-color":ve,color:le,"font-size":11,"text-valign":"bottom","text-margin-y":4,"text-outline-color":je,"text-outline-width":2,width:"mapData(pageRankScale, 0, 1, 20, 56)",height:"mapData(pageRankScale, 0, 1, 20, 56)","border-width":1,"border-color":"#1e3a8a"}},{selector:'node[kind = "event"]',style:{"background-color":Oe,shape:"round-rectangle","border-color":"#9a3412",width:"mapData(pageRankScale, 0, 1, 24, 64)",height:"mapData(pageRankScale, 0, 1, 16, 40)"}},{selector:'node[kind = "entity"]',style:{shape:"diamond","background-color":wt,"border-color":"#374151",width:"mapData(pageRankScale, 0, 1, 22, 60)",height:"mapData(pageRankScale, 0, 1, 22, 60)"}},{selector:'node[entityKind = "topic"]',style:{"background-color":W.topic}},{selector:'node[entityKind = "place"]',style:{"background-color":W.place}},{selector:'node[entityKind = "thing"]',style:{"background-color":W.thing}},{selector:'node[entityKind = "work"]',style:{"background-color":W.work}},{selector:'node[focused = "1"]',style:{"background-color":ee,"border-color":"#7f1d1d","border-width":3,width:36,height:36}},{selector:"node:selected",style:{"border-width":3,"border-color":"#0ea5e9"}},{selector:"edge",style:{width:"mapData(weightScale, 0, 1, 1, 6)","line-color":ze,"curve-style":"bezier",label:"data(label)","font-size":9,color:le,"text-rotation":"autorotate","text-background-color":St,"text-background-opacity":.85,"text-background-padding":1,"target-arrow-shape":"triangle","target-arrow-color":ze}},{selector:'edge[kind = "person-event"]',style:{"line-color":"#fbbf24","target-arrow-color":"#fbbf24","line-style":"dashed"}},{selector:'edge[kind = "person-entity"]',style:{"line-color":"#34d399","target-arrow-color":"#34d399","line-style":"dashed"}},{selector:'edge[kind = "event-event"]',style:{"line-color":"#f472b6","target-arrow-color":"#f472b6"}},{selector:'edge[kind = "event-entity"]',style:{"line-color":"#06b6d4","target-arrow-color":"#06b6d4","line-style":"dashed"}},{selector:'edge[kind = "entity-entity"]',style:{"line-color":"#a855f7","target-arrow-color":"#a855f7"}},{selector:'edge[kind = "person-person"]',style:{"line-color":"#f87171","target-arrow-color":"#f87171"}},{selector:'edge[focused = "1"]',style:{"line-color":"#facc15","target-arrow-color":"#facc15",width:4,"overlay-color":"#facc15","overlay-opacity":.25,"overlay-padding":5,"z-index":9999}},{selector:"edge.dimmed",style:{opacity:.15}},{selector:"node.dimmed",style:{opacity:.2,"text-opacity":0}}];function Et(t,s){if(!(t!=null&&t.length)&&!(s!=null&&s.length))return De;const i=[];for(const c of t??[]){const u={};c.color&&(u["background-color"]=c.color,u["border-color"]=c.color),c.shape&&(u.shape=c.shape==="circle"?"ellipse":c.shape==="round-rect"?"round-rectangle":"diamond"),i.push({selector:`node[kind = "${c.kind}"]`,style:u})}for(const c of s??[]){const u={};c.color&&(u["line-color"]=c.color,u["target-arrow-color"]=c.color),c.dashed&&(u["line-style"]="dashed"),i.push({selector:`edge[kind = "${c.kind}"]`,style:u})}return[...De,...i]}function It({comp:t,pluginName:s,refreshTick:i,onRefresh:c}){var Le,Ae;kt();const u=l.useRef(null),o=l.useRef(null),a=l.useRef(null),f=l.useRef(!1),[r,j]=l.useState(null),[z,I]=l.useState(!1),[$,P]=l.useState(null),[C,p]=l.useState(),[b,y]=l.useState(t.defaultMaxDepth??2),[D,B]=l.useState(t.defaultMaxBreadth??10),[se,de]=l.useState(""),[T,re]=l.useState(null),[Ve,ce]=l.useState(null),[Qe,we]=l.useState(!1),[O,Ne]=l.useState(!1),[ae,ue]=l.useState(null),he="aalis.relgraph.spacing",q=60,pe=1e3,oe=5e3,Re=120,Ce=()=>{if(typeof window>"u")return;const n=window.localStorage.getItem(he);if(n==null)return;const d=Number(n);return Number.isFinite(d)&&d>=q&&d<=oe?d:void 0},[te,Ee]=l.useState(()=>Ce()??Re),[ge,ie]=l.useState(te);l.useEffect(()=>{if(Ce()!==void 0)return;let n=!1;return me("/api/plugins/@aalis/plugin-webui-server/config").then(d=>{var S;if(n)return;const v=Number((S=d==null?void 0:d.config)==null?void 0:S.relationGraphDefaultSpacing);Number.isFinite(v)&&v>=q&&v<=oe&&(Ee(v),ie(v))}).catch(()=>{}),()=>{n=!0}},[]);const V=l.useCallback(n=>{if(!Number.isFinite(n))return;const d=Math.max(q,Math.min(oe,Math.round(n)));Ee(d),ie(d);try{window.localStorage.setItem(he,String(d))}catch{}},[]),fe=`relation-graph-h:${s}:${t.source}`,[K,Xe]=l.useState(()=>{if(typeof window>"u")return 520;const n=Number(window.localStorage.getItem(fe));return Number.isFinite(n)&&n>=200?n:520}),Q=l.useRef(null),Je=l.useCallback(n=>{n.target.setPointerCapture(n.pointerId),Q.current={y:n.clientY,h:K}},[K]),et=l.useCallback(n=>{if(!Q.current)return;const d=Math.max(200,Math.min(1600,Q.current.h+(n.clientY-Q.current.y)));Xe(d)},[]),Ie=l.useCallback(n=>{if(Q.current){n.target.releasePointerCapture(n.pointerId),Q.current=null;try{window.localStorage.setItem(fe,String(K))}catch{}}},[fe,K]);l.useEffect(()=>{var n;(n=o.current)==null||n.resize()},[K]);const X=l.useCallback(async()=>{I(!0),P(null);try{const n={focusId:C,maxDepth:b<=0?Nt:b,maxBreadth:D},d=await _(s,t.source,n);j(d?{nodes:Array.isArray(d.nodes)?d.nodes:[],edges:Array.isArray(d.edges)?d.edges:[],focusId:d.focusId,focusEdge:d.focusEdge,stats:d.stats,globalPrRanks:d.globalPrRanks}:{nodes:[],edges:[]})}catch(n){P(n.message||String(n)),j({nodes:[],edges:[]})}finally{I(!1)}},[s,t.source,C,b,D]);l.useEffect(()=>{X()},[X,i]),l.useEffect(()=>{if(!t.refresh||t.refresh<=0)return;const n=setInterval(X,t.refresh);return()=>clearInterval(n)},[t.refresh,X]),l.useEffect(()=>{if(!u.current)return;const n=_e({container:u.current,elements:[],style:Et(t.nodeKinds,t.edgeKinds),minZoom:.2,maxZoom:3,wheelSensitivity:.2});o.current=n,n.on("tap","node",S=>{const m=S.target.data();re({data:m}),p(String(m.id))}),n.on("tap","edge",S=>{const m=S.target.id();typeof m=="string"&&m&&(re(null),p(m))});const d=(S,m)=>{const N=[],g=w=>{const x=S[w];return x==null?"":String(x)};if(m){const w=g("label"),x=g("role"),k=g("relationType");w?N.push(w):x?N.push(x):k&&N.push(k);const F=g("description");F&&N.push(F);const A=S.weight;typeof A=="number"&&N.push(`合并强度 ${A.toFixed(2)}`)}else{const w=g("kind"),x=g("title")||g("name")||g("displayName")||g("label");x&&N.push(x);const k=g("category")||g("entityKind");if(k&&N.push(`类型:${k}`),w==="event"){const A=g("sessionScope");A&&N.push(`会话:${A}`)}const F=g("summary");F&&N.push(F)}return N},v=(S,m)=>{var F,A,h;const N=(F=u.current)==null?void 0:F.getBoundingClientRect(),g=S.target.data(),w=d(g,m);if(w.length===0||!N)return;const x=((A=S.renderedPosition)==null?void 0:A.x)??0,k=((h=S.renderedPosition)==null?void 0:h.y)??0;ue({x:x+12,y:k+12,lines:w})};return n.on("mouseover","node",S=>v(S,!1)),n.on("mouseover","edge",S=>v(S,!0)),n.on("mouseout","node",()=>ue(null)),n.on("mouseout","edge",()=>ue(null)),()=>{n.destroy(),o.current=null}},[]),l.useEffect(()=>{const n=o.current;if(!n||!r)return;const d=r.focusId??C,v=new Map;for(const h of r.nodes){if(h.data.kind!=="person")continue;const R=typeof h.data.label=="string"?h.data.label:"";R&&v.set(R,(v.get(R)??0)+1)}const S=h=>{if(h.kind!=="person")return;const R=typeof h.label=="string"?h.label:"";if(!R||(v.get(R)??0)<2)return;const E=typeof h.platform=="string"?h.platform:"?",L=typeof h.userId=="string"?h.userId:"",H=L?`…${L.slice(-4)}`:typeof h.id=="string"?`…${h.id.slice(-4)}`:"?";return`${R} · ${E}:${H}`},m=new Map;for(const h of r.nodes){const R=String(h.data.kind??"person"),E=typeof h.data.lastPageRank=="number"?h.data.lastPageRank:0;let L=m.get(R);L||(L=new Map,m.set(R,L)),L.set(String(h.data.id),E)}const N=new Map;for(const[,h]of m){const R=[...h.entries()].sort((L,H)=>L[1]-H[1]),E=R.length;for(let L=0;L<E;L++){const H=E>1?L/(E-1):.5;N.set(R[L][0],H)}}const g=new Map;{const h=r.edges.map(E=>({id:E.data.id,w:typeof E.data.weight=="number"?E.data.weight:0})).sort((E,L)=>E.w-L.w),R=h.length;for(let E=0;E<R;E++)g.set(h[E].id,R>1?E/(R-1):.5)}const w=[...r.nodes.map(h=>{const R=S(h.data),E=N.get(String(h.data.id))??0;return{data:{...h.data,...R?{label:R}:{},pageRankScale:E,focused:d&&h.data.id===d?"1":void 0},group:"nodes"}}),...r.edges.map(h=>{const R=typeof h.data.label=="string"?h.data.label:"",E=g.get(h.data.id)??0;return{data:{...h.data,label:R,kind:h.data.kind??(h.data.relationType?"person-person":"person-event"),weightScale:E,focused:d&&h.data.id===d?"1":void 0},group:"edges"}})],x=a.current===r;a.current=r;const k=!f.current;let F=1;if(!x){const h=new Map;n.nodes().forEach(L=>{h.set(L.id(),{...L.position()})}),n.elements().remove(),n.add(w);let R=0;n.nodes().forEach(L=>{const H=h.get(L.id());H&&(L.position(H),R++)});const E=n.nodes().length;F=E>0?R/E:0}const A=(k||F<.5)&&!x;n.layout({name:"fcose",animate:x,animationDuration:400,randomize:A&&r.nodes.length>20,nodeRepulsion:(h=>{const R=Math.round(te*117),E=Number(h.data("pageRankScale"))||0;return Math.round(R*(1+3*E))}),idealEdgeLength:(h=>{const R=Number(h.data("weightScale"))||0;return Math.round(te*(1.4-.8*R))}),nodeSeparation:Math.round(te*.67),gravity:.1,gravityRange:3,padding:40,quality:r.nodes.length>300?"default":"proof",uniformNodeDimensions:!1}).run(),r.nodes.length>0&&(f.current=!0)},[r,C,te]),l.useEffect(()=>{const n=o.current;if(!n)return;const d=se.toLowerCase().split(/\s+/).filter(Boolean);if(n.elements().removeClass("dimmed"),d.length===0)return;const v=n.nodes().filter(m=>{const N=[String(m.data("label")??""),String(m.data("kind")??""),String(m.data("entityKind")??""),String(m.data("category")??""),String(m.data("title")??""),String(m.data("name")??""),String(m.data("displayName")??""),String(m.data("summary")??""),String(m.data("sessionScope")??"")].map(g=>g.toLowerCase());return d.every(g=>N.some(w=>w.includes(g)))});if(v.length===0)return;const S=new Set(v.map(m=>m.id()));n.nodes().forEach(m=>{S.has(m.id())||m.addClass("dimmed")}),n.edges().forEach(m=>{S.has(m.source().id())||S.has(m.target().id())||m.addClass("dimmed")})},[se,r]),l.useEffect(()=>{if(!T||!t.detailSource){ce(null);return}we(!0),_(s,t.detailSource,{nodeId:T.data.id,kind:T.data.kind}).then(n=>ce(n??null)).catch(n=>ce({error:n.message})).finally(()=>we(!1))},[T,s,t.detailSource]),l.useEffect(()=>{const n=o.current;if(!n)return;const d=requestAnimationFrame(()=>{n.resize(),n.fit(void 0,30)});return()=>cancelAnimationFrame(d)},[C,T]);const tt=l.useCallback(()=>{const n=o.current;if(!n||n.elements().length===0)return;const d=n.png({full:!0,scale:2,bg:je,maxWidth:1/0});if(!d||d==="data:,")return;const v=document.createElement("a");v.href=d,v.download=`relation-graph-${Date.now()}.png`,document.body.appendChild(v),v.click(),document.body.removeChild(v)},[]),ye=l.useCallback(()=>{c?c():X()},[c,X]),nt=l.useCallback(async(n,d)=>{if(!(d&&!window.confirm(d)))try{await _(s,n,{focusId:C}),ye()}catch(v){alert(`操作失败: ${v.message}`)}},[s,C,ye]),Pe=(r==null?void 0:r.stats)??{},st=l.useMemo(()=>{if(!r)return"";const n={persons:"人物",events:"事件",entities:"实体"},d=[`节点 ${r.nodes.length}`,`边 ${r.edges.length}`],v=[];for(const[m,N]of Object.entries(Pe))m!=="edges"&&v.push(`${n[m]??m} ${N}`);const S=v.length?`全库: ${v.join(" · ")}`:"";return[...d,...S?[S]:[]].join(" | ")},[r,Pe]),Fe=l.useMemo(()=>{const n=new Map;if(!r)return n;const d=[];for(const g of r.nodes){const w=g.data.lastPageRank;typeof w!="number"||!Number.isFinite(w)||d.push({id:String(g.data.id),kind:String(g.data.kind??"person"),pr:w})}const v=[...d].sort((g,w)=>w.pr-g.pr),S=v.length,m=new Map;for(let g=0;g<v.length;g++)m.set(v[g].id,g+1);const N=new Map;for(const g of d)N.has(g.kind)||N.set(g.kind,[]),N.get(g.kind).push(g);for(const[,g]of N){g.sort((w,x)=>x.pr-w.pr);for(let w=0;w<g.length;w++)n.set(g[w].id,{kindRank:w+1,kindTotal:g.length,globalRank:m.get(g[w].id)??0,globalTotal:S})}return n},[r]),Me=l.useMemo(()=>{const n=new Map;if(!(r!=null&&r.globalPrRanks))return n;for(const[d,v]of Object.entries(r.globalPrRanks))n.set(d,v);return n},[r]),rt={display:"flex",flexWrap:"wrap",gap:8,alignItems:"center",padding:"8px 10px",background:"var(--bg-secondary)",borderBottom:"1px solid var(--border-color, #2a2a42)",fontSize:12,color:"var(--text)"},at={width:"100%",height:K,background:je,position:"relative"};return e.jsxs("div",{className:"relation-graph-wrap",style:{border:"1px solid var(--border-color, #e5e7eb)",borderRadius:6,overflow:"hidden"},children:[t.label?e.jsx("div",{style:{padding:"8px 12px",fontWeight:600},children:t.label}):null,e.jsxs("div",{style:rt,children:[e.jsxs("div",{style:{position:"relative",flex:"1 1 200px",minWidth:160},children:[e.jsx("input",{type:"text",placeholder:"搜索 (label / kind / entityKind / category,空格分多关键词)",value:se,onChange:n=>de(n.target.value),onCompositionEnd:n=>de(n.target.value),style:{width:"100%",padding:"4px 24px 4px 8px"}}),se?e.jsx("button",{type:"button",onClick:()=>de(""),title:"清除搜索",style:{position:"absolute",right:4,top:"50%",transform:"translateY(-50%)",background:"transparent",border:"none",color:"var(--text-muted, #888)",cursor:"pointer",fontSize:14,padding:"0 4px",lineHeight:1},children:"✕"}):null]}),e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:4,opacity:C?1:.45},title:C?"从焦点节点出发的 BFS 跳数(0 = 不限)":"深度仅在选定焦点后生效:点击节点 → 详情面板 → 「以此为焦点」",children:["深度",e.jsx("input",{type:"range",min:0,max:10,value:b,onChange:n=>y(Number(n.target.value)),disabled:!C}),e.jsx("input",{type:"number",min:0,value:b,onChange:n=>{const d=Number(n.target.value);Number.isFinite(d)&&d>=0&&y(d)},disabled:!C,style:{width:56,padding:"2px 4px",background:"var(--surface)",color:"var(--text)",border:"1px solid var(--surface-active)"}}),e.jsx("span",{style:{width:32,color:"var(--text-secondary)"},children:b===0?"∞":b})]}),e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:4,opacity:C?1:.45},title:C?"焦点模式:每个节点向外展开的邻居数上限(按边权重降序截断;0 = 不限)":"宽度仅在选定焦点后生效:点击图中任一节点即可设为焦点",children:["宽度",e.jsx("input",{type:"range",min:0,max:30,value:D,onChange:n=>B(Number(n.target.value)),disabled:!C}),e.jsx("input",{type:"number",min:0,value:D,onChange:n=>{const d=Number(n.target.value);Number.isFinite(d)&&d>=0&&B(d)},disabled:!C,style:{width:56,padding:"2px 4px",background:"var(--surface)",color:"var(--text)",border:"1px solid var(--surface-active)"}}),e.jsx("span",{style:{width:32,color:"var(--text-secondary)"},children:D===0?"∞":D})]}),e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:4},title:`布局密度(≈ 理想边长 px)。当前 ${ge}。
|
|
17
17
|
slider 范围 ${q}–${pe};数字框可手动输入更大值(上限 ${oe})。
|
|
18
|
-
松开鼠标 / Enter / 失焦后才重排(动画过渡),同时写入本地存储。`,children:["密度",e.jsx("input",{type:"range",min:q,max:pe,step:5,value:Math.min(ge,pe),onChange:n=>ie(Number(n.target.value)),onMouseUp:n=>V(Number(n.target.value)),onTouchEnd:n=>V(Number(n.target.value)),onKeyUp:n=>V(Number(n.target.value))}),e.jsx("input",{type:"number",min:q,value:ge,onChange:n=>{const d=Number(n.target.value);Number.isFinite(d)&&ie(d)},onBlur:n=>V(Number(n.target.value)),onKeyDown:n=>{n.key==="Enter"&&V(Number(n.target.value))},style:{width:64,padding:"2px 4px",background:"var(--surface)",color:"var(--text)",border:"1px solid var(--surface-active)"}})]}),e.jsx("button",{type:"button",onClick:()=>{try{window.localStorage.removeItem(he)}catch{}V(Ne)},title:"重置密度为默认值(同时清除本地覆盖)",style:{padding:"2px 6px",fontSize:11},children:"↺"}),C?e.jsx("button",{type:"button",onClick:()=>{p(void 0),re(null)},style:{padding:"4px 8px"},title:"清除焦点,返回全图视图",children:"✕ 清除焦点"}):null,e.jsx("button",{type:"button",onClick:ye,disabled:z,style:{padding:"4px 8px"},children:z?"加载中…":"刷新"}),e.jsx("button",{type:"button",onClick:et,style:{padding:"4px 8px"},children:"导出 PNG"}),(t.actions??[]).map(n=>e.jsx("button",{type:"button",onClick:()=>tt(n.method,n.confirm),style:{padding:"4px 8px",color:n.danger?"#dc2626":void 0},children:n.label},n.method))]}),$?e.jsxs("div",{style:{padding:8,color:"#dc2626",fontSize:12},children:["错误: ",$]}):null,e.jsx("div",{style:{display:"flex"},children:e.jsxs("div",{style:{position:"relative",flex:1},children:[e.jsx("div",{ref:u,style:rt}),ae?e.jsx("div",{style:{position:"absolute",left:Math.min(ae.x,600),top:ae.y,maxWidth:320,padding:"6px 8px",background:"rgba(28, 28, 40, 0.96)",color:le,border:"1px solid rgba(120,140,200,0.5)",borderRadius:4,fontSize:11,lineHeight:1.5,pointerEvents:"none",zIndex:6,boxShadow:"0 2px 6px rgba(0,0,0,0.4)",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:ae.lines.map((n,d)=>e.jsx("div",{style:d===0?{fontWeight:600}:{color:"var(--text-muted)"},children:n},d))}):null,T||C&&(r!=null&&r.focusEdge)?e.jsxs("div",{style:{position:"absolute",top:10,left:10,width:O?"auto":360,maxWidth:"calc(100% - 20px)",maxHeight:O?void 0:K-20,overflowY:O?"visible":"auto",padding:O?"4px 8px":"10px 12px",background:"rgba(28, 28, 40, 0.94)",color:le,border:`1px solid ${ee}`,borderRadius:6,fontSize:11,boxShadow:"0 2px 8px rgba(0,0,0,0.4)",pointerEvents:"auto",zIndex:5},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"flex-start",alignItems:"center",gap:8,marginBottom:O?0:6},children:[e.jsx("button",{type:"button",onClick:()=>we(n=>!n),style:{background:"none",border:0,color:"var(--text-secondary)",cursor:"pointer",fontSize:12,padding:0,lineHeight:1,width:16},title:O?"展开详情":"收起详情(保留焦点)","aria-label":O?"展开":"收起",children:O?"▸":"▾"}),e.jsx("button",{type:"button",onClick:()=>{p(void 0),re(null),we(!1)},style:{background:"none",border:0,color:"var(--text-secondary)",cursor:"pointer",fontSize:14,padding:0,lineHeight:1},title:"关闭(清焦点)","aria-label":"关闭",children:"✕"}),e.jsx("strong",{style:{color:ee},children:T?`${T.data.kind??"节点"}:${T.data.label??T.data.id}`:"焦点(边)"}),e.jsx("span",{style:{marginLeft:"auto"},children:e.jsx(It,{})})]}),O?null:T?e.jsx(Ft,{node:T,detail:qe,loading:Ve,hasDetailSource:!!t.detailSource,isFocus:C===T.data.id,prRank:{sub:Pe.get(String(T.data.id)),global:Fe.get(String(T.data.id))}}):r!=null&&r.focusEdge?(()=>{var w;const n=r.focusEdge,d=f=>{if(!f||!Number.isFinite(f))return"—";try{return new Date(f).toLocaleString("zh-CN",{hour12:!1})}catch{return String(f)}},b=f=>{const v=r.nodes.find(A=>A.data.id===f);if(!v)return;const F=v.data.lastPageRank;return{label:typeof v.data.label=="string"?v.data.label:void 0,kind:typeof v.data.kind=="string"?v.data.kind:void 0,lastPageRank:typeof F=="number"&&Number.isFinite(F)?F:void 0}},S=n.endpoints??[],x=S.map(f=>{var v;return(v=b(f))==null?void 0:v.lastPageRank}).filter(f=>typeof f=="number"),N=x.length>0?x.reduce((f,v)=>f+v,0)/x.length:void 0,g=typeof n.weight=="number"&&typeof N=="number"?n.weight*N:void 0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{marginBottom:6,fontSize:10,color:"var(--text-secondary)"},children:["id=",n.id]}),e.jsx("div",{style:{marginBottom:6},children:n.description??"(无描述)"}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",columnGap:8,rowGap:3,color:"var(--text-secondary)",marginBottom:8},children:[e.jsx("span",{children:"kind"}),e.jsxs("span",{children:[ne(n.kind,Oe),n.directed===!0?" · 有向":n.directed===!1?" · 无向":""]}),n.relation?e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"relation"}),e.jsx("span",{children:ne(n.relation,We)})]}):null,n.role?e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"role"}),e.jsx("span",{children:Rt(n.kind,n.role)})]}):null,n.sentiment?e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"sentiment"}),e.jsx("span",{children:ne(n.sentiment,Ke)})]}):null,typeof n.weight=="number"?e.jsxs(e.Fragment,{children:[e.jsx("span",{title:"边按 (kind, source, target[, role/relation]) 重复合并的累计强度:0.5 起步,每次合并 +(1−prev)·delta(默认 delta=0.1,由 LLM/工具调用传入)→ 0.55 → 0.595 → 0.636 → … (clamp 1.0)。语义=被强化次数,不是重要性。",style:{cursor:"help"},children:"合并强度"}),e.jsx("span",{children:n.weight.toFixed(2)})]}):null,typeof g=="number"?e.jsxs(e.Fragment,{children:[e.jsx("span",{title:"边淘汰分 = 合并强度 × 端点 PR 平均。配额淘汰时按此升序删——分越低越先删。让「弱权但连接重要节点」的边受保护。",style:{cursor:"help"},children:"边淘汰分"}),e.jsxs("span",{children:[g.toFixed(5)," ",e.jsxs("span",{style:{opacity:.6},children:["= ",n.weight.toFixed(2)," × ",be(N)]})]})]}):null,e.jsx("span",{children:"first"}),e.jsx("span",{children:d(n.firstSeenAt)}),e.jsx("span",{children:"last"}),e.jsx("span",{children:d(n.lastReinforcedAt)})]}),S.length>0?e.jsxs("div",{style:{marginBottom:8},children:[e.jsx("div",{style:{color:"var(--text-muted)",marginBottom:2},children:"端点"}),S.map(f=>{const v=b(f),F=Pe.get(f),A=Fe.get(f),h=typeof(v==null?void 0:v.lastPageRank)=="number";return e.jsxs("div",{style:{fontFamily:"monospace",fontSize:10,color:"var(--text-secondary)",marginBottom:3},children:[e.jsxs("div",{children:[(v==null?void 0:v.label)??f," ",e.jsxs("span",{style:{opacity:.6},children:["[",String((v==null?void 0:v.kind)??"?"),"]",h?` · PR ${be(v.lastPageRank)}`:""]})]}),h&&F?e.jsxs("div",{style:{opacity:.6,paddingLeft:8},children:["子图 #",F.kindRank,"/",F.kindTotal," 同类 · #",F.globalRank,"/",F.globalTotal," 全部"]}):null,h&&A?e.jsxs("div",{style:{opacity:.6,paddingLeft:8},children:["全库 #",A.kindRank,"/",A.kindTotal," 同类 · #",A.globalRank,"/",A.globalTotal," 全部"]}):null]},f)})]}):null,e.jsxs("div",{style:{color:"var(--text-muted)",marginBottom:2},children:["证据 ",((w=n.evidence)==null?void 0:w.length)??0," 条"]}),(n.evidence??[]).map((f,v)=>{var F,A;return e.jsxs("div",{style:{borderLeft:"2px solid var(--border-color, #2a2a42)",padding:"2px 6px",marginBottom:4,color:"var(--text-secondary)",lineHeight:1.4},children:[e.jsxs("div",{children:["「",f.quote??"(无摘录)","」"]}),e.jsxs("div",{style:{fontSize:10,opacity:.7},children:[f.extractedAt?d(f.extractedAt):"—",f.sessionId?` · ${f.sessionId}`:"",(F=f.messageIds)!=null&&F.length?` · ${f.messageIds.length} msg`:""]})]},`${((A=f.messageIds)==null?void 0:A.join(","))??v}-${f.extractedAt??v}`)}),e.jsxs("div",{style:{color:"var(--text-muted)",marginTop:6},children:["子图 节点 ",r.nodes.length," · 边 ",r.edges.length]})]})})():null]}):null]})}),e.jsx("div",{role:"separator","aria-orientation":"horizontal",title:"拖拽调整画布高度",onPointerDown:Xe,onPointerMove:Je,onPointerUp:Ee,onPointerCancel:Ee,style:{height:8,cursor:"ns-resize",background:"var(--bg-secondary)",borderTop:"1px solid var(--border-color, #2a2a42)",borderBottom:"1px solid var(--border-color, #2a2a42)",display:"flex",alignItems:"center",justifyContent:"center",userSelect:"none",touchAction:"none"},children:e.jsx("div",{style:{width:40,height:3,borderRadius:2,background:"var(--text-muted, #6b7280)",opacity:.6}})}),e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:12,padding:"4px 10px",fontSize:11,color:"var(--text-secondary)",background:"var(--bg-secondary)",borderTop:"1px solid var(--border-color, #2a2a42)"},children:[(Me=t.nodeKinds)!=null&&Me.length?e.jsxs(e.Fragment,{children:[t.nodeKinds.map(n=>e.jsx(G,{shape:n.shape??"circle",color:n.color??ve,label:n.label},n.kind)),e.jsx(G,{shape:"circle",color:ee,label:"焦点"}),(Le=t.edgeKinds)!=null&&Le.length?e.jsx("span",{style:{width:1,height:12,background:"var(--border-color, #2a2a42)",margin:"0 4px"}}):null,(t.edgeKinds??[]).map(n=>e.jsx(Y,{color:n.color??"#6b7280",dashStyle:n.dashed?"dashed":"solid",label:n.label},n.kind))]}):e.jsxs(e.Fragment,{children:[e.jsx(G,{shape:"circle",color:ve,label:"人物"}),e.jsx(G,{shape:"round-rect",color:_e,label:"事件"}),e.jsx(G,{shape:"diamond",color:W.topic,label:"话题"}),e.jsx(G,{shape:"diamond",color:W.place,label:"地点"}),e.jsx(G,{shape:"diamond",color:W.thing,label:"事物"}),e.jsx(G,{shape:"diamond",color:W.work,label:"作品"}),e.jsx(G,{shape:"circle",color:ee,label:"焦点"}),e.jsx("span",{style:{width:1,height:12,background:"var(--border-color, #2a2a42)",margin:"0 4px"}}),e.jsx(Y,{color:"#f87171",dashStyle:"solid",label:"人↔人"}),e.jsx(Y,{color:"#34d399",dashStyle:"dashed",label:"人→实体"}),e.jsx(Y,{color:"#fbbf24",dashStyle:"dashed",label:"人→事"}),e.jsx(Y,{color:"#a855f7",dashStyle:"solid",label:"实体↔实体"}),e.jsx(Y,{color:"#06b6d4",dashStyle:"dashed",label:"事→实体"}),e.jsx(Y,{color:"#f472b6",dashStyle:"solid",label:"事→事"})]}),e.jsx("span",{style:{marginLeft:"auto",opacity:.7},children:"点击节点 = 设为焦点 + 显示左上详情卡片;清除焦点请点工具栏「✕ 清除焦点」按钮"})]}),e.jsx("div",{style:{padding:"4px 10px",fontSize:11,color:"var(--text-secondary)",background:"var(--bg-secondary)"},children:nt||"—"})]})}function G({shape:t,color:s,label:i}){const c={width:12,height:12,background:s,display:"inline-block",verticalAlign:"middle"};let u;return t==="circle"?u={...c,borderRadius:"50%"}:t==="round-rect"?u={...c,width:16,height:10,borderRadius:3}:u={...c,transform:"rotate(45deg)"},e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4},children:[e.jsx("span",{style:u}),i]})}function Y({color:t,dashStyle:s,label:i}){const c=s==="solid"?"solid":s==="dashed"?"dashed":"dotted";return e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4},children:[e.jsx("span",{style:{width:18,height:0,borderTop:`2px ${c} ${t}`,display:"inline-block"}}),i]})}function Ye(t){if(typeof t!="number"||!Number.isFinite(t))return"—";try{return new Date(t).toLocaleString("zh-CN",{hour12:!1})}catch{return String(t)}}function Z(t,s){const i=t[`${s}Text`]??t[s];if(typeof i=="string"&&i)return i;if(typeof i=="number")return Ye(i)}function M(t){if(typeof t=="string"&&t)return t;if(typeof t=="number")return String(t)}function J(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function xe({rows:t}){const s=t.filter(([,i])=>i!=null&&i!=="");return s.length===0?e.jsx(e.Fragment,{}):e.jsx("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",columnGap:8,rowGap:3,color:"var(--text-secondary)",marginBottom:8},children:s.map(i=>{const[c,u,o]=i,a=typeof u=="string"||typeof u=="number"?String(u):u;return e.jsxs(U.Fragment,{children:[e.jsx("span",{style:{color:"var(--text-muted)",cursor:o?"help":void 0},title:o,children:c}),e.jsx("span",{style:{color:"var(--text)",wordBreak:"break-word"},children:a})]},c)})})}function De({list:t}){return!t||t.length===0?e.jsx(e.Fragment,{}):e.jsxs("div",{style:{marginTop:6},children:[e.jsxs("div",{style:{color:"var(--text-muted)",marginBottom:2},children:["证据 ",t.length," 条"]}),t.map((s,i)=>{var c,u;return e.jsxs("div",{style:{borderLeft:"2px solid var(--border-color, #2a2a42)",padding:"2px 6px",marginBottom:4,color:"var(--text-secondary)",lineHeight:1.4},children:[e.jsxs("div",{children:["「",s.quote??"(无摘录)","」"]}),e.jsxs("div",{style:{fontSize:10,opacity:.7},children:[s.extractedAtText??Ye(s.extractedAt),s.sessionId?` · ${s.sessionId}`:"",(c=s.messageIds)!=null&&c.length?` · ${s.messageIds.length} msg`:""]})]},`${((u=s.messageIds)==null?void 0:u.join(","))??i}-${s.extractedAt??i}`)})]})}function It(){const[t,s]=l.useState(!1);return e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",onClick:()=>s(!0),style:{background:"none",border:0,padding:0,cursor:"help",color:"var(--text-muted)",fontSize:11,textDecoration:"underline dotted"},title:"字段含义说明",children:"ⓘ 字段含义"}),t?e.jsx(Pt,{onClose:()=>s(!1)}):null]})}function Pt({onClose:t}){l.useEffect(()=>{const o=a=>{a.key==="Escape"&&t()};return window.addEventListener("keydown",o),()=>window.removeEventListener("keydown",o)},[t]);const s={display:"grid",gridTemplateColumns:"120px 1fr",columnGap:12,rowGap:4,fontSize:12},i={margin:"12px 0 4px",fontSize:13,color:"var(--text-primary, #e4e4ef)"},u=e.jsx("div",{onClick:t,style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.55)",zIndex:9999,display:"flex",alignItems:"flex-start",justifyContent:"center",overflowY:"auto",padding:"4vh 16px"},children:e.jsxs("div",{onClick:o=>o.stopPropagation(),style:{background:"var(--bg-primary, #0f0f14)",color:"var(--text-primary, #e4e4ef)",border:"1px solid var(--border-color, #2a2a42)",borderRadius:8,padding:"16px 20px",width:"min(680px, 92vw)",boxShadow:"0 8px 32px rgba(0,0,0,0.5)",lineHeight:1.55},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",marginBottom:6},children:[e.jsx("strong",{style:{fontSize:14},children:"关系图字段含义"}),e.jsx("button",{type:"button",onClick:t,style:{marginLeft:"auto",background:"none",border:0,color:"var(--text-secondary)",cursor:"pointer",fontSize:16},"aria-label":"关闭",title:"关闭 (Esc)",children:"✕"})]}),e.jsx("div",{style:i,children:"三个数值指标"}),e.jsxs("div",{style:{fontSize:12,color:"var(--text-secondary)"},children:[e.jsxs("div",{children:[e.jsx("b",{children:"合并强度"}),"(weight, 0~1):节点 / 边被重复合并的累计程度。0.5 起步,每次合并 ",e.jsx("code",{children:"+(1−prev)·delta"}),"(默认 delta=0.1,可由 LLM/工具调用传入;person 别名合并是直接 ",e.jsx("code",{children:"+0.3"})," 的特殊情况)→ 0.55 → 0.595 → 0.636 → … (clamp 1.0)。",e.jsxs("u",{children:["语义 = 被强化次数,",e.jsx("b",{children:"不是"}),"重要性"]}),"。"]}),e.jsxs("div",{style:{marginTop:3},children:[e.jsx("b",{children:"图重要性"}),"(lastPageRank):最近一次 ",e.jsx("code",{children:"/relation compress | maintain"}),' 计算的全图 PageRank。个性化种子按 kind 加权(人 2 · 物 1.5 · 事 1,可配置)。越高越靠近"核心人物 · 热门事件"。未跑过压缩则为空。注:节点越多,每个 PR 值越小(PR 是归一化概率分布,总和为 1),UI 在 |n| < 0.01 时切换科学计数法(如 ',e.jsx("code",{children:"2.07e-3"}),"),否则保留 3 位有效数字小数;同时附「子图同类/全部 + 全库同类/全部」四档排名(子图=当前 focusId/depth/breadth 限定的可见视图;全库=fullSnap 全体节点)便于判读位置。"]}),e.jsxs("div",{style:{marginTop:3},children:[e.jsx("b",{children:"边淘汰分"}),"(仅边详情):",e.jsx("code",{children:"合并强度 × ((PR_from + PR_to) / 2)"}),"。配额淘汰时按此",e.jsx("u",{children:"升序"}),'删——分越低越先删,让"弱权但连接重要节点"的边受保护。']})]}),e.jsx("div",{style:i,children:"边 kind(六类)"}),e.jsx("div",{style:s,children:Object.entries(Oe).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:i,children:"role · 人 → 事件"}),e.jsx("div",{style:s,children:Object.entries(Ge).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:i,children:"role · 人 → 物"}),e.jsx("div",{style:s,children:Object.entries(He).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:{fontSize:11,color:"var(--text-muted)",marginTop:4},children:'注:单句态度声明("我喜欢 X")不在关系图记录,归 user-profile 画像层。'}),e.jsx("div",{style:i,children:"relation · 人 → 人"}),e.jsx("div",{style:s,children:Object.entries(We).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:i,children:"sentiment"}),e.jsx("div",{style:s,children:Object.entries(Ke).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:i,children:"hierarchy(人 → 人,与 directed 正交)"}),e.jsx("div",{style:s,children:Object.entries(Nt).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsxs("div",{style:{marginTop:14,fontSize:11,color:"var(--text-muted)"},children:["完整文档:",e.jsx("a",{href:"/docs/plugins/user-relation-graph.md",target:"_blank",rel:"noopener noreferrer",style:{color:"var(--text-link, #8ab4f8)",marginLeft:4},title:"在新标签页打开文档",children:"docs/plugins/user-relation-graph.md ↗"})]})]})});return typeof document>"u"?u:at.createPortal(u,document.body)}function Ft({node:t,detail:s,loading:i,hasDetailSource:c,isFocus:u,prRank:o}){const a=t.data.kind,y=j=>{if(typeof j!="number"||!Number.isFinite(j))return e.jsxs("span",{style:{opacity:.6},children:["— ",e.jsx("span",{style:{fontSize:10},children:"(未跑过压缩,下次 evictByQuota 时计算)"})]});const z=be(j),I=o==null?void 0:o.sub,$=o==null?void 0:o.global;return!I&&!$?z:e.jsxs("span",{style:{display:"inline-flex",flexDirection:"column",gap:1},children:[e.jsx("span",{children:z}),I?e.jsxs(e.Fragment,{children:[e.jsxs("span",{style:{opacity:.75},children:["子图 #",I.kindRank,"/",I.kindTotal," 同类"]}),e.jsxs("span",{style:{opacity:.75},children:["子图 #",I.globalRank,"/",I.globalTotal," 全部"]})]}):null,$?e.jsxs(e.Fragment,{children:[e.jsxs("span",{style:{opacity:.75},children:["全库 #",$.kindRank,"/",$.kindTotal," 同类"]}),e.jsxs("span",{style:{opacity:.75},children:["全库 #",$.globalRank,"/",$.globalTotal," 全部"]})]}):e.jsx("span",{style:{opacity:.6,fontSize:10},children:"(全库排名暂缺:服务端未返回 globalPrRanks,可能需重启 aalis)"})]})},r=e.jsxs("div",{style:{color:"var(--text-secondary)",marginBottom:8,fontSize:10},children:["id=",t.data.id,u?e.jsx("span",{style:{marginLeft:6,color:ee},children:"· 当前焦点"}):null]});if(i)return e.jsxs(e.Fragment,{children:[r,e.jsx("div",{style:{color:"var(--text-muted)"},children:"加载详情中…"})]});if(!c)return e.jsxs(e.Fragment,{children:[r,e.jsx("div",{style:{color:"var(--text-muted)"},children:"无详情(detailSource 未配置)"})]});if(!s)return e.jsxs(e.Fragment,{children:[r,e.jsx("div",{style:{color:"var(--text-muted)"},children:"无数据"})]});if(typeof s.error=="string")return e.jsxs(e.Fragment,{children:[r,e.jsxs("div",{style:{color:"#dc2626"},children:["错误: ",s.error]})]});if(a==="person"&&s.person&&typeof s.person=="object"){const j=s.person,z=[["昵称",M(j.displayName)],["平台",M(j.platform)],["用户 ID",M(j.userId)],["提及次数",J(j.mentionCount)],["图重要性",y(typeof j.lastPageRank=="number"?j.lastPageRank:void 0),"最近一次 evictByQuota 计算的全图 PageRank 分数。人/物/事 个性化种子 2:1.5:1(默认,可配置);该节点越靠近「核心人物 · 热门事件」越高。下方附「子图同类/全部 + 全库同类/全部」四档排名便于判读位置。未跑过压缩时为空。"],["首次出现",Z(j,"firstSeenAt")],["最近出现",Z(j,"lastSeenAt")],["最近提及",Z(j,"lastMentionedAt")],["关联事件",J(s.eventCount)],["关联边数",J(s.edgeCount)]],I=Array.isArray(s.recentEvents)?s.recentEvents:[],$=Array.isArray(s.edges)?s.edges:[];return e.jsxs(e.Fragment,{children:[r,e.jsx(xe,{rows:z}),I.length>0?e.jsxs("div",{style:{marginBottom:8},children:[e.jsxs("div",{style:{color:"var(--text-muted)",marginBottom:2},children:["近期事件 ",I.length]}),I.slice(0,8).map((P,C)=>e.jsxs("div",{style:{color:"var(--text-secondary)",lineHeight:1.4},children:["· ",M(P.title)??"(无标题)",M(P.category)?e.jsxs("span",{style:{opacity:.6},children:[" [",M(P.category),"]"]}):null]},M(P.id)??C))]}):null,$.length>0?e.jsxs("div",{children:[e.jsxs("div",{style:{color:"var(--text-muted)",marginBottom:2},children:["边 ",$.length]}),$.slice(0,12).map((P,C)=>{const p=typeof P.weight=="number"?` w=${P.weight.toFixed(1)}`:"",k=M(P.relationZh)??M(P.roleZh)??M(P.relationType)??M(P.role)??M(P.kind)??"?",m=M(P.targetLabel)??M(P.toEntityId)??M(P.toEventId)??M(P.toPersonId)??"";return e.jsxs("div",{style:{fontFamily:"monospace",fontSize:10,color:"var(--text-secondary)"},children:[k,p," → ",m]},M(P.id)??C)})]}):null]})}if(a==="event"){const j=[["标题",M(s.title)],["类别",M(s.category)],["摘要",M(s.summary)],["提及次数",J(s.mentionCount)],["合并强度",typeof s.weight=="number"?s.weight.toFixed(2):void 0,"按 title 重复合并的累计强度:0.5 起步,每次合并 +(1−prev)·delta(默认 delta=0.1)。语义 = 被强化次数,不是重要性。"],["图重要性",y(typeof s.lastPageRank=="number"?s.lastPageRank:void 0),'最近一次 evictByQuota 计算的全图 PageRank 分数。反映"被重要节点引用"的结构性重要性;与合并强度独立。下方附「子图同类/全部 + 全库同类/全部」四档排名便于判读位置。'],["首次出现",Z(s,"firstSeenAt")],["最近强化",Z(s,"lastReinforcedAt")],["证据数",J(s.evidenceCount)]],z=Array.isArray(s.evidence)?s.evidence:[];return e.jsxs(e.Fragment,{children:[r,e.jsx(xe,{rows:j}),e.jsx(De,{list:z})]})}if(a==="entity"){const j=Array.isArray(s.aliases)?s.aliases.filter($=>typeof $=="string").join(" / "):void 0,z=[["名称",M(s.name)],["类型",M(s.entityKind)],["别名",j||void 0],["摘要",M(s.summary)],["合并强度",typeof s.weight=="number"?s.weight.toFixed(2):void 0,"按 (kind, name) 重复合并的累计强度:0.5 起步,每次合并 +(1−prev)·delta(默认 delta=0.1)。语义 = 被强化次数,不是重要性。"],["图重要性",y(typeof s.lastPageRank=="number"?s.lastPageRank:void 0),"最近一次 evictByQuota 计算的全图 PageRank 分数。多人共同指向的实体一般分数更高。下方附「子图同类/全部 + 全库同类/全部」四档排名便于判读位置。"],["首次出现",Z(s,"firstSeenAt")],["最近强化",Z(s,"lastReinforcedAt")],["证据数",J(s.evidenceCount)]],I=Array.isArray(s.evidence)?s.evidence:[];return e.jsxs(e.Fragment,{children:[r,e.jsx(xe,{rows:z}),e.jsx(De,{list:I})]})}return e.jsxs(e.Fragment,{children:[r,e.jsx("pre",{style:{whiteSpace:"pre-wrap",wordBreak:"break-word",fontSize:11,margin:0,color:"var(--text)"},children:JSON.stringify(s,null,2)})]})}const Te={skills:e.jsx(vt,{size:18}),scheduler:e.jsx(ut,{size:18}),browser:e.jsx(ct,{size:18}),memory:e.jsx(yt,{size:18}),tools:e.jsx(it,{size:18}),agent:e.jsx(ot,{size:18}),default:e.jsx(mt,{size:18})};function Ze({comp:t,pluginName:s,refreshTick:i}){const[c,u]=l.useState("—"),[o,a]=l.useState(!0);l.useEffect(()=>{a(!0),B(s,t.source).then(r=>{r&&u(r.value)}).catch(()=>{}).finally(()=>a(!1))},[s,t.source,i]);const y=Te[t.icon??""]??Te.default;return e.jsxs("div",{className:"dyn-stat-card",children:[e.jsx("div",{className:"dyn-stat-icon",children:y}),e.jsxs("div",{className:"dyn-stat-body",children:[e.jsx("div",{className:"dyn-stat-label",children:t.label}),e.jsx("div",{className:"dyn-stat-value",children:o?"...":c})]})]})}function Mt({target:t,onZero:s}){const[i,c]=l.useState(Date.now()),u=l.useRef(!1);if(l.useEffect(()=>{u.current=!1;const y=setInterval(()=>c(Date.now()),1e3);return()=>clearInterval(y)},[t]),!t||t<=0)return e.jsx("span",{children:"-"});const o=Math.max(0,Math.round((t-i)/1e3));if(o===0&&!u.current)return u.current=!0,s&&setTimeout(s,3e3),e.jsx("span",{className:"countdown-fired",children:"⏳ 执行中"});if(o===0)return e.jsx("span",{className:"countdown-fired",children:"⏳ 执行中"});let a;if(o<60)a=`${o}秒`;else if(o<3600){const y=Math.floor(o/60),r=o%60;a=r>0?`${y}分${r}秒`:`${y}分`}else{const y=Math.floor(o/3600),r=Math.floor(o%3600/60);a=r>0?`${y}时${r}分`:`${y}时`}return e.jsx("span",{className:o<=5?"countdown-imminent":"",children:a})}function Lt({text:t}){const[s,i]=l.useState(!1);return t?e.jsxs("div",{className:`dyn-cell-expandable${s?" expanded":""}`,children:[e.jsx("span",{className:"dyn-cell-expandable-text",children:t}),e.jsx("button",{type:"button",className:"dyn-cell-expandable-toggle",onClick:()=>i(c=>!c),title:s?"收起":"展开",children:s?"收起":"展开"})]}):null}function At({comp:t,pluginName:s,refreshTick:i}){const[c,u]=l.useState([]),[o,a]=l.useState(!0),[y,r]=l.useState(null),[j,z]=l.useState(""),I=l.useCallback(()=>{a(!0),B(s,t.source).then(p=>{Array.isArray(p)&&u(p)}).catch(()=>{}).finally(()=>a(!1))},[s,t.source]);l.useEffect(()=>{if(I(),t.refresh&&t.refresh>0){const p=setInterval(I,t.refresh*1e3);return()=>clearInterval(p)}},[I,t.refresh,i]);const $=async(p,k)=>{if(p.confirm&&!confirm(p.confirm))return;const m=await B(s,p.method,k);p.danger||p.confirm?I():m&&typeof m=="object"&&!Array.isArray(m)?r(m):I()},P=p=>{if(!p.minWidth&&!p.maxWidth)return;const k={};return p.minWidth&&(k.minWidth=`${p.minWidth}px`),p.maxWidth&&(k.maxWidth=`${p.maxWidth}px`),k},C=(()=>{if(!t.searchable)return c;const p=j.toLowerCase().split(/\s+/).filter(Boolean);return p.length===0?c:c.filter(k=>{const m=t.columns.map(D=>String(k[D.key]??"")).join(" ").toLowerCase();return p.every(D=>m.includes(D))})})();return e.jsxs("div",{className:"dyn-table-block",children:[t.label&&e.jsx("h3",{className:"dyn-section-title",children:t.label}),t.searchable?e.jsxs("div",{style:{marginBottom:6},children:[e.jsx("input",{type:"text",value:j,onChange:p=>z(p.target.value),placeholder:t.searchPlaceholder??"搜索(空格分隔多个关键词,AND 语义)",style:{width:"100%",maxWidth:360,padding:"4px 8px",fontSize:12,border:"1px solid var(--border-color, #ddd)",borderRadius:4,background:"transparent",color:"inherit"}}),j?e.jsxs("span",{style:{marginLeft:8,fontSize:11,color:"var(--text-muted)"},children:[C.length,"/",c.length]}):null]}):null,o&&c.length===0?e.jsx("div",{className:"empty-hint",children:"加载中..."}):C.length===0?e.jsx("div",{className:"empty-hint",children:j?"无匹配":"暂无数据"}):e.jsx("div",{className:"dyn-table-scroll",children:e.jsxs("table",{className:"dyn-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[t.columns.map(p=>e.jsx("th",{className:p.nowrap?"dyn-cell-nowrap":void 0,style:P(p),children:p.label},p.key)),t.actions&&t.actions.length>0&&e.jsx("th",{children:"操作"})]})}),e.jsx("tbody",{children:C.map((p,k)=>e.jsxs("tr",{children:[t.columns.map(m=>e.jsx("td",{className:m.nowrap?"dyn-cell-nowrap":void 0,style:P(m),children:m.render==="countdown"?e.jsx(Mt,{target:Number(p[m.key])||0,onZero:I}):m.render==="status-badge"?e.jsx("span",{className:`dyn-badge dyn-badge-${String(p[m.key])}`,children:String(p[m.key]??"")}):m.render==="code"?e.jsx("code",{children:String(p[m.key]??"")}):m.render==="expandable-text"?e.jsx(Lt,{text:String(p[m.key]??"")}):String(p[m.key]??"")},m.key)),t.actions&&t.actions.length>0&&e.jsx("td",{className:"dyn-table-actions",children:t.actions.map((m,D)=>e.jsx("button",{className:`btn btn-sm${m.danger?" btn-danger":""}`,onClick:()=>$(m,p),children:m.label},D))})]},k))})]})}),y&&e.jsx("div",{className:"dyn-detail-overlay",onClick:()=>r(null),children:e.jsxs("div",{className:"dyn-detail-modal",onClick:p=>p.stopPropagation(),children:[e.jsxs("div",{className:"dyn-detail-header",children:[e.jsx("span",{className:"dyn-detail-title",children:String(y.name||y.title||"详情")}),e.jsx("button",{className:"dyn-detail-close",onClick:()=>r(null),children:"×"})]}),e.jsx("div",{className:"dyn-detail-body",children:Object.entries(y).map(([p,k])=>{const m=k==null?"":typeof k=="object"?JSON.stringify(k,null,2):String(k),D=m.length>120||m.includes(`
|
|
19
|
-
`);return e.jsxs("div",{className:"dyn-detail-field",children:[e.jsx("div",{className:"dyn-detail-key",children:p}),D?e.jsx("pre",{className:"dyn-detail-pre",children:
|
|
18
|
+
松开鼠标 / Enter / 失焦后才重排(动画过渡),同时写入本地存储。`,children:["密度",e.jsx("input",{type:"range",min:q,max:pe,step:5,value:Math.min(ge,pe),onChange:n=>ie(Number(n.target.value)),onMouseUp:n=>V(Number(n.target.value)),onTouchEnd:n=>V(Number(n.target.value)),onKeyUp:n=>V(Number(n.target.value))}),e.jsx("input",{type:"number",min:q,value:ge,onChange:n=>{const d=Number(n.target.value);Number.isFinite(d)&&ie(d)},onBlur:n=>V(Number(n.target.value)),onKeyDown:n=>{n.key==="Enter"&&V(Number(n.target.value))},style:{width:64,padding:"2px 4px",background:"var(--surface)",color:"var(--text)",border:"1px solid var(--surface-active)"}})]}),e.jsx("button",{type:"button",onClick:()=>{try{window.localStorage.removeItem(he)}catch{}V(Re)},title:"重置密度为默认值(同时清除本地覆盖)",style:{padding:"2px 6px",fontSize:11},children:"↺"}),C?e.jsx("button",{type:"button",onClick:()=>{p(void 0),re(null)},style:{padding:"4px 8px"},title:"清除焦点,返回全图视图",children:"✕ 清除焦点"}):null,e.jsx("button",{type:"button",onClick:ye,disabled:z,style:{padding:"4px 8px"},children:z?"加载中…":"刷新"}),e.jsx("button",{type:"button",onClick:tt,style:{padding:"4px 8px"},children:"导出 PNG"}),(t.actions??[]).map(n=>e.jsx("button",{type:"button",onClick:()=>nt(n.method,n.confirm),style:{padding:"4px 8px",color:n.danger?"#dc2626":void 0},children:n.label},n.method))]}),$?e.jsxs("div",{style:{padding:8,color:"#dc2626",fontSize:12},children:["错误: ",$]}):null,e.jsx("div",{style:{display:"flex"},children:e.jsxs("div",{style:{position:"relative",flex:1},children:[e.jsx("div",{ref:u,style:at}),ae?e.jsx("div",{style:{position:"absolute",left:Math.min(ae.x,600),top:ae.y,maxWidth:320,padding:"6px 8px",background:"rgba(28, 28, 40, 0.96)",color:le,border:"1px solid rgba(120,140,200,0.5)",borderRadius:4,fontSize:11,lineHeight:1.5,pointerEvents:"none",zIndex:6,boxShadow:"0 2px 6px rgba(0,0,0,0.4)",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:ae.lines.map((n,d)=>e.jsx("div",{style:d===0?{fontWeight:600}:{color:"var(--text-muted)"},children:n},d))}):null,T||C&&(r!=null&&r.focusEdge)?e.jsxs("div",{style:{position:"absolute",top:10,left:10,width:O?"auto":360,maxWidth:"calc(100% - 20px)",maxHeight:O?void 0:K-20,overflowY:O?"visible":"auto",padding:O?"4px 8px":"10px 12px",background:"rgba(28, 28, 40, 0.94)",color:le,border:`1px solid ${ee}`,borderRadius:6,fontSize:11,boxShadow:"0 2px 8px rgba(0,0,0,0.4)",pointerEvents:"auto",zIndex:5},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"flex-start",alignItems:"center",gap:8,marginBottom:O?0:6},children:[e.jsx("button",{type:"button",onClick:()=>Ne(n=>!n),style:{background:"none",border:0,color:"var(--text-secondary)",cursor:"pointer",fontSize:12,padding:0,lineHeight:1,width:16},title:O?"展开详情":"收起详情(保留焦点)","aria-label":O?"展开":"收起",children:O?"▸":"▾"}),e.jsx("button",{type:"button",onClick:()=>{p(void 0),re(null),Ne(!1)},style:{background:"none",border:0,color:"var(--text-secondary)",cursor:"pointer",fontSize:14,padding:0,lineHeight:1},title:"关闭(清焦点)","aria-label":"关闭",children:"✕"}),e.jsx("strong",{style:{color:ee},children:T?`${T.data.kind??"节点"}:${T.data.label??T.data.id}`:"焦点(边)"}),e.jsx("span",{style:{marginLeft:"auto"},children:e.jsx(Pt,{})})]}),O?null:T?e.jsx(Mt,{node:T,detail:Ve,loading:Qe,hasDetailSource:!!t.detailSource,isFocus:C===T.data.id,prRank:{sub:Fe.get(String(T.data.id)),global:Me.get(String(T.data.id))}}):r!=null&&r.focusEdge?(()=>{var w;const n=r.focusEdge,d=x=>{if(!x||!Number.isFinite(x))return"—";try{return new Date(x).toLocaleString("zh-CN",{hour12:!1})}catch{return String(x)}},v=x=>{const k=r.nodes.find(A=>A.data.id===x);if(!k)return;const F=k.data.lastPageRank;return{label:typeof k.data.label=="string"?k.data.label:void 0,kind:typeof k.data.kind=="string"?k.data.kind:void 0,lastPageRank:typeof F=="number"&&Number.isFinite(F)?F:void 0}},S=n.endpoints??[],m=S.map(x=>{var k;return(k=v(x))==null?void 0:k.lastPageRank}).filter(x=>typeof x=="number"),N=m.length>0?m.reduce((x,k)=>x+k,0)/m.length:void 0,g=typeof n.weight=="number"&&typeof N=="number"?n.weight*N:void 0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{marginBottom:6,fontSize:10,color:"var(--text-secondary)"},children:["id=",n.id]}),e.jsx("div",{style:{marginBottom:6},children:n.description??"(无描述)"}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",columnGap:8,rowGap:3,color:"var(--text-secondary)",marginBottom:8},children:[e.jsx("span",{children:"kind"}),e.jsxs("span",{children:[ne(n.kind,Ge),n.directed===!0?" · 有向":n.directed===!1?" · 无向":""]}),n.relation?e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"relation"}),e.jsx("span",{children:ne(n.relation,Ke)})]}):null,n.role?e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"role"}),e.jsx("span",{children:Ct(n.kind,n.role)})]}):null,n.sentiment?e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"sentiment"}),e.jsx("span",{children:ne(n.sentiment,Ye)})]}):null,typeof n.weight=="number"?e.jsxs(e.Fragment,{children:[e.jsx("span",{title:"边按 (kind, source, target[, role/relation]) 重复合并的累计强度:0.5 起步,每次合并 +(1−prev)·delta(默认 delta=0.1,由 LLM/工具调用传入)→ 0.55 → 0.595 → 0.636 → … (clamp 1.0)。语义=被强化次数,不是重要性。",style:{cursor:"help"},children:"合并强度"}),e.jsx("span",{children:n.weight.toFixed(2)})]}):null,typeof g=="number"?e.jsxs(e.Fragment,{children:[e.jsx("span",{title:"边淘汰分 = 合并强度 × 端点 PR 平均。配额淘汰时按此升序删——分越低越先删。让「弱权但连接重要节点」的边受保护。",style:{cursor:"help"},children:"边淘汰分"}),e.jsxs("span",{children:[g.toFixed(5)," ",e.jsxs("span",{style:{opacity:.6},children:["= ",n.weight.toFixed(2)," × ",be(N)]})]})]}):null,e.jsx("span",{children:"first"}),e.jsx("span",{children:d(n.firstSeenAt)}),e.jsx("span",{children:"last"}),e.jsx("span",{children:d(n.lastReinforcedAt)})]}),S.length>0?e.jsxs("div",{style:{marginBottom:8},children:[e.jsx("div",{style:{color:"var(--text-muted)",marginBottom:2},children:"端点"}),S.map(x=>{const k=v(x),F=Fe.get(x),A=Me.get(x),h=typeof(k==null?void 0:k.lastPageRank)=="number";return e.jsxs("div",{style:{fontFamily:"monospace",fontSize:10,color:"var(--text-secondary)",marginBottom:3},children:[e.jsxs("div",{children:[(k==null?void 0:k.label)??x," ",e.jsxs("span",{style:{opacity:.6},children:["[",String((k==null?void 0:k.kind)??"?"),"]",h?` · PR ${be(k.lastPageRank)}`:""]})]}),h&&F?e.jsxs("div",{style:{opacity:.6,paddingLeft:8},children:["子图 #",F.kindRank,"/",F.kindTotal," 同类 · #",F.globalRank,"/",F.globalTotal," 全部"]}):null,h&&A?e.jsxs("div",{style:{opacity:.6,paddingLeft:8},children:["全库 #",A.kindRank,"/",A.kindTotal," 同类 · #",A.globalRank,"/",A.globalTotal," 全部"]}):null]},x)})]}):null,e.jsxs("div",{style:{color:"var(--text-muted)",marginBottom:2},children:["证据 ",((w=n.evidence)==null?void 0:w.length)??0," 条"]}),(n.evidence??[]).map((x,k)=>{var F,A;return e.jsxs("div",{style:{borderLeft:"2px solid var(--border-color, #2a2a42)",padding:"2px 6px",marginBottom:4,color:"var(--text-secondary)",lineHeight:1.4},children:[e.jsxs("div",{children:["「",x.quote??"(无摘录)","」"]}),e.jsxs("div",{style:{fontSize:10,opacity:.7},children:[x.extractedAt?d(x.extractedAt):"—",x.sessionId?` · ${x.sessionId}`:"",(F=x.messageIds)!=null&&F.length?` · ${x.messageIds.length} msg`:""]})]},`${((A=x.messageIds)==null?void 0:A.join(","))??k}-${x.extractedAt??k}`)}),e.jsxs("div",{style:{color:"var(--text-muted)",marginTop:6},children:["子图 节点 ",r.nodes.length," · 边 ",r.edges.length]})]})})():null]}):null]})}),e.jsx("div",{role:"separator","aria-orientation":"horizontal",title:"拖拽调整画布高度",onPointerDown:Je,onPointerMove:et,onPointerUp:Ie,onPointerCancel:Ie,style:{height:8,cursor:"ns-resize",background:"var(--bg-secondary)",borderTop:"1px solid var(--border-color, #2a2a42)",borderBottom:"1px solid var(--border-color, #2a2a42)",display:"flex",alignItems:"center",justifyContent:"center",userSelect:"none",touchAction:"none"},children:e.jsx("div",{style:{width:40,height:3,borderRadius:2,background:"var(--text-muted, #6b7280)",opacity:.6}})}),e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:12,padding:"4px 10px",fontSize:11,color:"var(--text-secondary)",background:"var(--bg-secondary)",borderTop:"1px solid var(--border-color, #2a2a42)"},children:[(Le=t.nodeKinds)!=null&&Le.length?e.jsxs(e.Fragment,{children:[t.nodeKinds.map(n=>e.jsx(G,{shape:n.shape??"circle",color:n.color??ve,label:n.label},n.kind)),e.jsx(G,{shape:"circle",color:ee,label:"焦点"}),(Ae=t.edgeKinds)!=null&&Ae.length?e.jsx("span",{style:{width:1,height:12,background:"var(--border-color, #2a2a42)",margin:"0 4px"}}):null,(t.edgeKinds??[]).map(n=>e.jsx(Y,{color:n.color??"#6b7280",dashStyle:n.dashed?"dashed":"solid",label:n.label},n.kind))]}):e.jsxs(e.Fragment,{children:[e.jsx(G,{shape:"circle",color:ve,label:"人物"}),e.jsx(G,{shape:"round-rect",color:Oe,label:"事件"}),e.jsx(G,{shape:"diamond",color:W.topic,label:"话题"}),e.jsx(G,{shape:"diamond",color:W.place,label:"地点"}),e.jsx(G,{shape:"diamond",color:W.thing,label:"事物"}),e.jsx(G,{shape:"diamond",color:W.work,label:"作品"}),e.jsx(G,{shape:"circle",color:ee,label:"焦点"}),e.jsx("span",{style:{width:1,height:12,background:"var(--border-color, #2a2a42)",margin:"0 4px"}}),e.jsx(Y,{color:"#f87171",dashStyle:"solid",label:"人↔人"}),e.jsx(Y,{color:"#34d399",dashStyle:"dashed",label:"人→实体"}),e.jsx(Y,{color:"#fbbf24",dashStyle:"dashed",label:"人→事"}),e.jsx(Y,{color:"#a855f7",dashStyle:"solid",label:"实体↔实体"}),e.jsx(Y,{color:"#06b6d4",dashStyle:"dashed",label:"事→实体"}),e.jsx(Y,{color:"#f472b6",dashStyle:"solid",label:"事→事"})]}),e.jsx("span",{style:{marginLeft:"auto",opacity:.7},children:"点击节点 = 设为焦点 + 显示左上详情卡片;清除焦点请点工具栏「✕ 清除焦点」按钮"})]}),e.jsx("div",{style:{padding:"4px 10px",fontSize:11,color:"var(--text-secondary)",background:"var(--bg-secondary)"},children:st||"—"})]})}function G({shape:t,color:s,label:i}){const c={width:12,height:12,background:s,display:"inline-block",verticalAlign:"middle"};let u;return t==="circle"?u={...c,borderRadius:"50%"}:t==="round-rect"?u={...c,width:16,height:10,borderRadius:3}:u={...c,transform:"rotate(45deg)"},e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4},children:[e.jsx("span",{style:u}),i]})}function Y({color:t,dashStyle:s,label:i}){const c=s==="solid"?"solid":s==="dashed"?"dashed":"dotted";return e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4},children:[e.jsx("span",{style:{width:18,height:0,borderTop:`2px ${c} ${t}`,display:"inline-block"}}),i]})}function Ze(t){if(typeof t!="number"||!Number.isFinite(t))return"—";try{return new Date(t).toLocaleString("zh-CN",{hour12:!1})}catch{return String(t)}}function Z(t,s){const i=t[`${s}Text`]??t[s];if(typeof i=="string"&&i)return i;if(typeof i=="number")return Ze(i)}function M(t){if(typeof t=="string"&&t)return t;if(typeof t=="number")return String(t)}function J(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function xe({rows:t}){const s=t.filter(([,i])=>i!=null&&i!=="");return s.length===0?e.jsx(e.Fragment,{}):e.jsx("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",columnGap:8,rowGap:3,color:"var(--text-secondary)",marginBottom:8},children:s.map(i=>{const[c,u,o]=i,a=typeof u=="string"||typeof u=="number"?String(u):u;return e.jsxs(U.Fragment,{children:[e.jsx("span",{style:{color:"var(--text-muted)",cursor:o?"help":void 0},title:o,children:c}),e.jsx("span",{style:{color:"var(--text)",wordBreak:"break-word"},children:a})]},c)})})}function Te({list:t}){return!t||t.length===0?e.jsx(e.Fragment,{}):e.jsxs("div",{style:{marginTop:6},children:[e.jsxs("div",{style:{color:"var(--text-muted)",marginBottom:2},children:["证据 ",t.length," 条"]}),t.map((s,i)=>{var c,u;return e.jsxs("div",{style:{borderLeft:"2px solid var(--border-color, #2a2a42)",padding:"2px 6px",marginBottom:4,color:"var(--text-secondary)",lineHeight:1.4},children:[e.jsxs("div",{children:["「",s.quote??"(无摘录)","」"]}),e.jsxs("div",{style:{fontSize:10,opacity:.7},children:[s.extractedAtText??Ze(s.extractedAt),s.sessionId?` · ${s.sessionId}`:"",(c=s.messageIds)!=null&&c.length?` · ${s.messageIds.length} msg`:""]})]},`${((u=s.messageIds)==null?void 0:u.join(","))??i}-${s.extractedAt??i}`)})]})}function Pt(){const[t,s]=l.useState(!1);return e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",onClick:()=>s(!0),style:{background:"none",border:0,padding:0,cursor:"help",color:"var(--text-muted)",fontSize:11,textDecoration:"underline dotted"},title:"字段含义说明",children:"ⓘ 字段含义"}),t?e.jsx(Ft,{onClose:()=>s(!1)}):null]})}function Ft({onClose:t}){l.useEffect(()=>{const o=a=>{a.key==="Escape"&&t()};return window.addEventListener("keydown",o),()=>window.removeEventListener("keydown",o)},[t]);const s={display:"grid",gridTemplateColumns:"120px 1fr",columnGap:12,rowGap:4,fontSize:12},i={margin:"12px 0 4px",fontSize:13,color:"var(--text-primary, #e4e4ef)"},u=e.jsx("div",{onClick:t,style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.55)",zIndex:9999,display:"flex",alignItems:"flex-start",justifyContent:"center",overflowY:"auto",padding:"4vh 16px"},children:e.jsxs("div",{onClick:o=>o.stopPropagation(),style:{background:"var(--bg-primary, #0f0f14)",color:"var(--text-primary, #e4e4ef)",border:"1px solid var(--border-color, #2a2a42)",borderRadius:8,padding:"16px 20px",width:"min(680px, 92vw)",boxShadow:"0 8px 32px rgba(0,0,0,0.5)",lineHeight:1.55},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",marginBottom:6},children:[e.jsx("strong",{style:{fontSize:14},children:"关系图字段含义"}),e.jsx("button",{type:"button",onClick:t,style:{marginLeft:"auto",background:"none",border:0,color:"var(--text-secondary)",cursor:"pointer",fontSize:16},"aria-label":"关闭",title:"关闭 (Esc)",children:"✕"})]}),e.jsx("div",{style:i,children:"三个数值指标"}),e.jsxs("div",{style:{fontSize:12,color:"var(--text-secondary)"},children:[e.jsxs("div",{children:[e.jsx("b",{children:"合并强度"}),"(weight, 0~1):节点 / 边被重复合并的累计程度。0.5 起步,每次合并 ",e.jsx("code",{children:"+(1−prev)·delta"}),"(默认 delta=0.1,可由 LLM/工具调用传入;person 别名合并是直接 ",e.jsx("code",{children:"+0.3"})," 的特殊情况)→ 0.55 → 0.595 → 0.636 → … (clamp 1.0)。",e.jsxs("u",{children:["语义 = 被强化次数,",e.jsx("b",{children:"不是"}),"重要性"]}),"。"]}),e.jsxs("div",{style:{marginTop:3},children:[e.jsx("b",{children:"图重要性"}),"(lastPageRank):最近一次 ",e.jsx("code",{children:"/relation compress | maintain"}),' 计算的全图 PageRank。个性化种子按 kind 加权(人 2 · 物 1.5 · 事 1,可配置)。越高越靠近"核心人物 · 热门事件"。未跑过压缩则为空。注:节点越多,每个 PR 值越小(PR 是归一化概率分布,总和为 1),UI 在 |n| < 0.01 时切换科学计数法(如 ',e.jsx("code",{children:"2.07e-3"}),"),否则保留 3 位有效数字小数;同时附「子图同类/全部 + 全库同类/全部」四档排名(子图=当前 focusId/depth/breadth 限定的可见视图;全库=fullSnap 全体节点)便于判读位置。"]}),e.jsxs("div",{style:{marginTop:3},children:[e.jsx("b",{children:"边淘汰分"}),"(仅边详情):",e.jsx("code",{children:"合并强度 × ((PR_from + PR_to) / 2)"}),"。配额淘汰时按此",e.jsx("u",{children:"升序"}),'删——分越低越先删,让"弱权但连接重要节点"的边受保护。']})]}),e.jsx("div",{style:i,children:"边 kind(六类)"}),e.jsx("div",{style:s,children:Object.entries(Ge).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:i,children:"role · 人 → 事件"}),e.jsx("div",{style:s,children:Object.entries(He).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:i,children:"role · 人 → 物"}),e.jsx("div",{style:s,children:Object.entries(We).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:{fontSize:11,color:"var(--text-muted)",marginTop:4},children:'注:单句态度声明("我喜欢 X")不在关系图记录,归 user-profile 画像层。'}),e.jsx("div",{style:i,children:"relation · 人 → 人"}),e.jsx("div",{style:s,children:Object.entries(Ke).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:i,children:"sentiment"}),e.jsx("div",{style:s,children:Object.entries(Ye).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsx("div",{style:i,children:"hierarchy(人 → 人,与 directed 正交)"}),e.jsx("div",{style:s,children:Object.entries(Rt).map(([o,a])=>e.jsxs(U.Fragment,{children:[e.jsx("code",{style:{color:"var(--text-muted)"},children:o}),e.jsx("span",{children:a})]},o))}),e.jsxs("div",{style:{marginTop:14,fontSize:11,color:"var(--text-muted)"},children:["完整文档:",e.jsx("a",{href:"/docs/plugins/user-relation-graph.md",target:"_blank",rel:"noopener noreferrer",style:{color:"var(--text-link, #8ab4f8)",marginLeft:4},title:"在新标签页打开文档",children:"docs/plugins/user-relation-graph.md ↗"})]})]})});return typeof document>"u"?u:ot.createPortal(u,document.body)}function Mt({node:t,detail:s,loading:i,hasDetailSource:c,isFocus:u,prRank:o}){const a=t.data.kind,f=j=>{if(typeof j!="number"||!Number.isFinite(j))return e.jsxs("span",{style:{opacity:.6},children:["— ",e.jsx("span",{style:{fontSize:10},children:"(未跑过压缩,下次 evictByQuota 时计算)"})]});const z=be(j),I=o==null?void 0:o.sub,$=o==null?void 0:o.global;return!I&&!$?z:e.jsxs("span",{style:{display:"inline-flex",flexDirection:"column",gap:1},children:[e.jsx("span",{children:z}),I?e.jsxs(e.Fragment,{children:[e.jsxs("span",{style:{opacity:.75},children:["子图 #",I.kindRank,"/",I.kindTotal," 同类"]}),e.jsxs("span",{style:{opacity:.75},children:["子图 #",I.globalRank,"/",I.globalTotal," 全部"]})]}):null,$?e.jsxs(e.Fragment,{children:[e.jsxs("span",{style:{opacity:.75},children:["全库 #",$.kindRank,"/",$.kindTotal," 同类"]}),e.jsxs("span",{style:{opacity:.75},children:["全库 #",$.globalRank,"/",$.globalTotal," 全部"]})]}):e.jsx("span",{style:{opacity:.6,fontSize:10},children:"(全库排名暂缺:服务端未返回 globalPrRanks,可能需重启 aalis)"})]})},r=e.jsxs("div",{style:{color:"var(--text-secondary)",marginBottom:8,fontSize:10},children:["id=",t.data.id,u?e.jsx("span",{style:{marginLeft:6,color:ee},children:"· 当前焦点"}):null]});if(i)return e.jsxs(e.Fragment,{children:[r,e.jsx("div",{style:{color:"var(--text-muted)"},children:"加载详情中…"})]});if(!c)return e.jsxs(e.Fragment,{children:[r,e.jsx("div",{style:{color:"var(--text-muted)"},children:"无详情(detailSource 未配置)"})]});if(!s)return e.jsxs(e.Fragment,{children:[r,e.jsx("div",{style:{color:"var(--text-muted)"},children:"无数据"})]});if(typeof s.error=="string")return e.jsxs(e.Fragment,{children:[r,e.jsxs("div",{style:{color:"#dc2626"},children:["错误: ",s.error]})]});if(a==="person"&&s.person&&typeof s.person=="object"){const j=s.person,z=[["昵称",M(j.displayName)],["平台",M(j.platform)],["用户 ID",M(j.userId)],["提及次数",J(j.mentionCount)],["图重要性",f(typeof j.lastPageRank=="number"?j.lastPageRank:void 0),"最近一次 evictByQuota 计算的全图 PageRank 分数。人/物/事 个性化种子 2:1.5:1(默认,可配置);该节点越靠近「核心人物 · 热门事件」越高。下方附「子图同类/全部 + 全库同类/全部」四档排名便于判读位置。未跑过压缩时为空。"],["首次出现",Z(j,"firstSeenAt")],["最近出现",Z(j,"lastSeenAt")],["最近提及",Z(j,"lastMentionedAt")],["关联事件",J(s.eventCount)],["关联边数",J(s.edgeCount)]],I=Array.isArray(s.recentEvents)?s.recentEvents:[],$=Array.isArray(s.edges)?s.edges:[];return e.jsxs(e.Fragment,{children:[r,e.jsx(xe,{rows:z}),I.length>0?e.jsxs("div",{style:{marginBottom:8},children:[e.jsxs("div",{style:{color:"var(--text-muted)",marginBottom:2},children:["近期事件 ",I.length]}),I.slice(0,8).map((P,C)=>e.jsxs("div",{style:{color:"var(--text-secondary)",lineHeight:1.4},children:["· ",M(P.title)??"(无标题)",M(P.category)?e.jsxs("span",{style:{opacity:.6},children:[" [",M(P.category),"]"]}):null]},M(P.id)??C))]}):null,$.length>0?e.jsxs("div",{children:[e.jsxs("div",{style:{color:"var(--text-muted)",marginBottom:2},children:["边 ",$.length]}),$.slice(0,12).map((P,C)=>{const p=typeof P.weight=="number"?` w=${P.weight.toFixed(1)}`:"",b=M(P.relationZh)??M(P.roleZh)??M(P.relationType)??M(P.role)??M(P.kind)??"?",y=M(P.targetLabel)??M(P.toEntityId)??M(P.toEventId)??M(P.toPersonId)??"";return e.jsxs("div",{style:{fontFamily:"monospace",fontSize:10,color:"var(--text-secondary)"},children:[b,p," → ",y]},M(P.id)??C)})]}):null]})}if(a==="event"){const j=[["标题",M(s.title)],["类别",M(s.category)],["摘要",M(s.summary)],["提及次数",J(s.mentionCount)],["合并强度",typeof s.weight=="number"?s.weight.toFixed(2):void 0,"按 title 重复合并的累计强度:0.5 起步,每次合并 +(1−prev)·delta(默认 delta=0.1)。语义 = 被强化次数,不是重要性。"],["图重要性",f(typeof s.lastPageRank=="number"?s.lastPageRank:void 0),'最近一次 evictByQuota 计算的全图 PageRank 分数。反映"被重要节点引用"的结构性重要性;与合并强度独立。下方附「子图同类/全部 + 全库同类/全部」四档排名便于判读位置。'],["首次出现",Z(s,"firstSeenAt")],["最近强化",Z(s,"lastReinforcedAt")],["证据数",J(s.evidenceCount)]],z=Array.isArray(s.evidence)?s.evidence:[];return e.jsxs(e.Fragment,{children:[r,e.jsx(xe,{rows:j}),e.jsx(Te,{list:z})]})}if(a==="entity"){const j=Array.isArray(s.aliases)?s.aliases.filter($=>typeof $=="string").join(" / "):void 0,z=[["名称",M(s.name)],["类型",M(s.entityKind)],["别名",j||void 0],["摘要",M(s.summary)],["合并强度",typeof s.weight=="number"?s.weight.toFixed(2):void 0,"按 (kind, name) 重复合并的累计强度:0.5 起步,每次合并 +(1−prev)·delta(默认 delta=0.1)。语义 = 被强化次数,不是重要性。"],["图重要性",f(typeof s.lastPageRank=="number"?s.lastPageRank:void 0),"最近一次 evictByQuota 计算的全图 PageRank 分数。多人共同指向的实体一般分数更高。下方附「子图同类/全部 + 全库同类/全部」四档排名便于判读位置。"],["首次出现",Z(s,"firstSeenAt")],["最近强化",Z(s,"lastReinforcedAt")],["证据数",J(s.evidenceCount)]],I=Array.isArray(s.evidence)?s.evidence:[];return e.jsxs(e.Fragment,{children:[r,e.jsx(xe,{rows:z}),e.jsx(Te,{list:I})]})}return e.jsxs(e.Fragment,{children:[r,e.jsx("pre",{style:{whiteSpace:"pre-wrap",wordBreak:"break-word",fontSize:11,margin:0,color:"var(--text)"},children:JSON.stringify(s,null,2)})]})}const Be={skills:e.jsx(jt,{size:18}),scheduler:e.jsx(ht,{size:18}),browser:e.jsx(ut,{size:18}),memory:e.jsx(xt,{size:18}),tools:e.jsx(lt,{size:18}),agent:e.jsx(it,{size:18}),default:e.jsx(bt,{size:18})};function Ue({comp:t,pluginName:s,refreshTick:i}){const[c,u]=l.useState("—"),[o,a]=l.useState(!0);l.useEffect(()=>{a(!0),_(s,t.source).then(r=>{r&&u(r.value)}).catch(()=>{}).finally(()=>a(!1))},[s,t.source,i]);const f=Be[t.icon??""]??Be.default;return e.jsxs("div",{className:"dyn-stat-card",children:[e.jsx("div",{className:"dyn-stat-icon",children:f}),e.jsxs("div",{className:"dyn-stat-body",children:[e.jsx("div",{className:"dyn-stat-label",children:t.label}),e.jsx("div",{className:"dyn-stat-value",children:o?"...":c})]})]})}function Lt({target:t,onZero:s}){const[i,c]=l.useState(Date.now()),u=l.useRef(!1);if(l.useEffect(()=>{u.current=!1;const f=setInterval(()=>c(Date.now()),1e3);return()=>clearInterval(f)},[t]),!t||t<=0)return e.jsx("span",{children:"-"});const o=Math.max(0,Math.round((t-i)/1e3));if(o===0&&!u.current)return u.current=!0,s&&setTimeout(s,3e3),e.jsx("span",{className:"countdown-fired",children:"⏳ 执行中"});if(o===0)return e.jsx("span",{className:"countdown-fired",children:"⏳ 执行中"});let a;if(o<60)a=`${o}秒`;else if(o<3600){const f=Math.floor(o/60),r=o%60;a=r>0?`${f}分${r}秒`:`${f}分`}else{const f=Math.floor(o/3600),r=Math.floor(o%3600/60);a=r>0?`${f}时${r}分`:`${f}时`}return e.jsx("span",{className:o<=5?"countdown-imminent":"",children:a})}function At({text:t}){const[s,i]=l.useState(!1);return t?e.jsxs("div",{className:`dyn-cell-expandable${s?" expanded":""}`,children:[e.jsx("span",{className:"dyn-cell-expandable-text",children:t}),e.jsx("button",{type:"button",className:"dyn-cell-expandable-toggle",onClick:()=>i(c=>!c),title:s?"收起":"展开",children:s?"收起":"展开"})]}):null}function $t({comp:t,pluginName:s,refreshTick:i}){const[c,u]=l.useState([]),[o,a]=l.useState(!0),[f,r]=l.useState(null),[j,z]=l.useState(""),I=l.useCallback(()=>{a(!0),_(s,t.source).then(p=>{Array.isArray(p)&&u(p)}).catch(()=>{}).finally(()=>a(!1))},[s,t.source]);l.useEffect(()=>{if(I(),t.refresh&&t.refresh>0){const p=setInterval(I,t.refresh*1e3);return()=>clearInterval(p)}},[I,t.refresh,i]);const $=async(p,b)=>{if(p.confirm&&!confirm(p.confirm))return;let y;try{y=await _(s,p.method,b)}catch(B){window.alert(Se(B,"操作失败"));return}if(y&&y.ok===!1){window.alert(typeof y.error=="string"?y.error:"操作失败"),I();return}!p.danger&&!p.confirm&&!!y&&typeof y=="object"&&!Array.isArray(y)&&y.ok===void 0?r(y):I()},P=p=>{if(!p.minWidth&&!p.maxWidth)return;const b={};return p.minWidth&&(b.minWidth=`${p.minWidth}px`),p.maxWidth&&(b.maxWidth=`${p.maxWidth}px`),b},C=(()=>{if(!t.searchable)return c;const p=j.toLowerCase().split(/\s+/).filter(Boolean);return p.length===0?c:c.filter(b=>{const y=t.columns.map(D=>String(b[D.key]??"")).join(" ").toLowerCase();return p.every(D=>y.includes(D))})})();return e.jsxs("div",{className:"dyn-table-block",children:[t.label&&e.jsx("h3",{className:"dyn-section-title",children:t.label}),t.searchable?e.jsxs("div",{style:{marginBottom:6},children:[e.jsx("input",{type:"text",value:j,onChange:p=>z(p.target.value),placeholder:t.searchPlaceholder??"搜索(空格分隔多个关键词,AND 语义)",style:{width:"100%",maxWidth:360,padding:"4px 8px",fontSize:12,border:"1px solid var(--border-color, #ddd)",borderRadius:4,background:"transparent",color:"inherit"}}),j?e.jsxs("span",{style:{marginLeft:8,fontSize:11,color:"var(--text-muted)"},children:[C.length,"/",c.length]}):null]}):null,o&&c.length===0?e.jsx("div",{className:"empty-hint",children:"加载中..."}):C.length===0?e.jsx("div",{className:"empty-hint",children:j?"无匹配":"暂无数据"}):e.jsx("div",{className:"dyn-table-scroll",children:e.jsxs("table",{className:"dyn-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[t.columns.map(p=>e.jsx("th",{className:p.nowrap?"dyn-cell-nowrap":void 0,style:P(p),children:p.label},p.key)),t.actions&&t.actions.length>0&&e.jsx("th",{children:"操作"})]})}),e.jsx("tbody",{children:C.map((p,b)=>e.jsxs("tr",{children:[t.columns.map(y=>e.jsx("td",{className:y.nowrap?"dyn-cell-nowrap":void 0,style:P(y),children:y.render==="countdown"?e.jsx(Lt,{target:Number(p[y.key])||0,onZero:I}):y.render==="status-badge"?e.jsx("span",{className:`dyn-badge dyn-badge-${String(p[y.key])}`,children:String(p[y.key]??"")}):y.render==="code"?e.jsx("code",{children:String(p[y.key]??"")}):y.render==="expandable-text"?e.jsx(At,{text:String(p[y.key]??"")}):String(p[y.key]??"")},y.key)),t.actions&&t.actions.length>0&&e.jsx("td",{className:"dyn-table-actions",children:t.actions.map((y,D)=>e.jsx("button",{className:`btn btn-sm${y.danger?" btn-danger":""}`,onClick:()=>$(y,p),children:y.label},D))})]},b))})]})}),f&&e.jsx("div",{className:"dyn-detail-overlay",onClick:()=>r(null),children:e.jsxs("div",{className:"dyn-detail-modal",onClick:p=>p.stopPropagation(),children:[e.jsxs("div",{className:"dyn-detail-header",children:[e.jsx("span",{className:"dyn-detail-title",children:String(f.name||f.title||"详情")}),e.jsx("button",{className:"dyn-detail-close",onClick:()=>r(null),children:"×"})]}),e.jsx("div",{className:"dyn-detail-body",children:Object.entries(f).map(([p,b])=>{const y=b==null?"":typeof b=="object"?JSON.stringify(b,null,2):String(b),D=y.length>120||y.includes(`
|
|
19
|
+
`);return e.jsxs("div",{className:"dyn-detail-field",children:[e.jsx("div",{className:"dyn-detail-key",children:p}),D?e.jsx("pre",{className:"dyn-detail-pre",children:y}):e.jsx("div",{className:"dyn-detail-val",children:y})]},p)})})]})})]})}function zt({comp:t,pluginName:s}){const[i,c]=l.useState({}),[u,o]=l.useState(!0),[a,f]=l.useState(!1),[r,j]=l.useState(""),z=l.useRef({}),[I,$]=l.useState(void 0);l.useEffect(()=>{o(!0),_(s,t.source).then(b=>{b&&c(b)}).catch(()=>{}).finally(()=>o(!1))},[s,t.source]);const P=async()=>{f(!0),j("");try{const b=await _(s,t.save,i);b&&b.ok===!1?j(b.error??"保存失败"):j("已保存")}catch(b){j(Se(b,"保存失败"))}f(!1)},C=b=>{me(`/api/models/${b}`).then(y=>{const D=y.providers&&y.providers.length>0?y.providers.map(B=>({label:`${B.provider} / ${B.model}`,value:B.value})):(y.models??[]).map(B=>({label:B,value:B}));z.current={...z.current,[b]:D}}).catch(()=>{})},p=()=>{I||me("/api/llm-providers").then(b=>$(b.providers??[])).catch(()=>$([]))};return u?e.jsx("div",{className:"empty-hint",children:"加载中..."}):e.jsxs("div",{className:"dyn-form-block",children:[t.label&&e.jsx("h3",{className:"dyn-section-title",children:t.label}),e.jsx(dt,{schema:t.schema,draft:i,onChange:c,modelCache:z.current,onFetchModels:C,llmProviders:I,onFetchLLMProviders:p}),e.jsxs("div",{style:{display:"flex",gap:8,marginTop:12,alignItems:"center"},children:[e.jsx("button",{className:"btn btn-sm btn-primary",onClick:P,disabled:a,children:a?"保存中...":"保存"}),r&&e.jsx("span",{style:{fontSize:13,color:r==="已保存"?"#22c55e":"#ef4444"},children:r})]})]})}function Dt({comp:t,pluginName:s,onRefresh:i}){const[c,u]=l.useState({}),o=async a=>{if(!(a.confirm&&!confirm(a.confirm))){u(f=>({...f,[a.method]:"执行中..."}));try{const f=await _(s,a.method);if(f&&f.ok===!1){u(r=>({...r,[a.method]:f.error??"失败"}));return}u(r=>({...r,[a.method]:"完成"})),i()}catch(f){u(r=>({...r,[a.method]:Se(f,"失败")}))}}};return e.jsxs("div",{className:"dyn-actions-block",children:[t.label&&e.jsx("div",{className:"dyn-section-title",children:t.label}),e.jsx("div",{style:{display:"flex",gap:8,flexWrap:"wrap",alignItems:"center"},children:t.items.map((a,f)=>e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[e.jsx("button",{className:`btn btn-sm${a.danger?" btn-danger":a.variant==="primary"?" btn-primary":""}`,onClick:()=>o(a),children:a.label}),c[a.method]&&e.jsx("span",{className:"dyn-action-msg",children:c[a.method]})]},f))})]})}function Tt({comp:t,pluginName:s,refreshTick:i}){const[c,u]=l.useState(null);return l.useEffect(()=>{_(s,t.source).then(o=>{o&&u(o)}).catch(()=>{})},[s,t.source,i]),e.jsxs("div",{className:"dyn-info-block",children:[t.label&&e.jsx("h3",{className:"dyn-section-title",children:t.label}),c?e.jsx("div",{className:"dyn-info-grid",children:Object.entries(c).map(([o,a])=>e.jsxs("div",{className:"dyn-info-item",children:[e.jsx("span",{className:"dyn-info-key",children:o}),e.jsx("span",{className:"dyn-info-val",children:typeof a=="object"?JSON.stringify(a):String(a??"")})]},o))}):e.jsx("div",{className:"empty-hint",children:"加载中..."})]})}function Bt({comp:t,pluginName:s,refreshTick:i}){const[c,u]=l.useState("");return l.useEffect(()=>{_(s,t.source).then(o=>{o&&u(o.content)}).catch(()=>{})},[s,t.source,i]),e.jsxs("div",{className:"dyn-markdown-block",children:[t.label&&e.jsx("h3",{className:"dyn-section-title",children:t.label}),e.jsx(pt,{remarkPlugins:[ft],rehypePlugins:[gt],children:c})]})}function _t({comp:t,pluginName:s,refreshTick:i,onRefresh:c}){var f;const[u,o]=l.useState(((f=t.items[0])==null?void 0:f.key)??""),a=t.items.find(r=>r.key===u);return e.jsxs("div",{className:"dyn-tabs-block",children:[t.label&&e.jsx("h3",{className:"dyn-section-title",children:t.label}),e.jsx("div",{className:"dyn-tabs-header",children:t.items.map(r=>e.jsx("button",{className:`dyn-tab-btn${u===r.key?" active":""}`,onClick:()=>o(r.key),children:r.label},r.key))}),e.jsx("div",{className:"dyn-tabs-body",children:a&&a.content.map((r,j)=>e.jsx(qe,{component:r,pluginName:s,refreshTick:i,onRefresh:c},j))})]})}function qe({component:t,pluginName:s,refreshTick:i,onRefresh:c}){switch(t.type){case"stat":return e.jsx(Ue,{comp:t,pluginName:s,refreshTick:i});case"table":return e.jsx($t,{comp:t,pluginName:s,refreshTick:i});case"form":return e.jsx(zt,{comp:t,pluginName:s});case"actions":return e.jsx(Dt,{comp:t,pluginName:s,onRefresh:c});case"info":return e.jsx(Tt,{comp:t,pluginName:s,refreshTick:i});case"markdown":return e.jsx(Bt,{comp:t,pluginName:s,refreshTick:i});case"tabs":return e.jsx(_t,{comp:t,pluginName:s,refreshTick:i,onRefresh:c});case"graph":return e.jsx(It,{comp:t,pluginName:s,refreshTick:i,onRefresh:c});default:return null}}function Qt({page:t}){const[s,i]=l.useState(0),c=l.useCallback(()=>i(a=>a+1),[]);if(l.useEffect(()=>{const a=f=>{const r=f.detail;(!r.pluginName||r.pluginName===t.plugin)&&c()};return window.addEventListener("aalis:page-refresh",a),()=>window.removeEventListener("aalis:page-refresh",a)},[t.plugin,c]),!t.content||t.content.length===0)return e.jsx("div",{className:"empty-hint",style:{padding:24},children:"此页面未提供内容"});const u=[];for(const a of t.content)if(a.type==="stat"){const f=u[u.length-1];f&&f.type==="stat-grid"?f.items.push(a):u.push({type:"stat-grid",items:[a]})}else u.push({type:"component",item:a});const o=u.some(a=>a.type==="component"&&a.item.type==="graph");return e.jsx("div",{className:`page-content dynamic-page${o?" has-graph":""}`,children:u.map((a,f)=>{const r=o&&a.type==="component"&&a.item.type==="tabs";return a.type==="stat-grid"?e.jsx("div",{className:"dyn-stat-grid",children:a.items.map((j,z)=>e.jsx(Ue,{comp:j,pluginName:t.plugin,refreshTick:s},z))},f):e.jsx("div",{className:r?"dyn-scroll-region":void 0,children:e.jsx(qe,{component:a.item,pluginName:t.plugin,refreshTick:s,onRefresh:c})},f)})})}export{Qt as DynamicPage};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import{r as i,j as e}from"./react-vendor-BPQixOLZ.js";import{c as k,a as j,C as O,g as U,F as A,h as J,D as K,i as V,X as G}from"./index-CP1eHYpM.js";import"./highlight-DJvvuuwd.js";import"./katex-Bq6vt64r.js";import"./markdown-B2G8c9k5.js";/**
|
|
2
|
+
* @license lucide-react v1.7.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const H=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],X=k("arrow-left",H);/**
|
|
7
|
+
* @license lucide-react v1.7.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const q=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],Q=k("info",q);/**
|
|
12
|
+
* @license lucide-react v1.7.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const W=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],Y=k("pencil",W);function T(l){if(l===0)return"—";const o=["B","KB","MB","GB"];let n=0,r=l;for(;r>=1024&&n<o.length-1;)r/=1024,n++;return`${r.toFixed(n===0?0:1)} ${o[n]}`}function v(l){return new Date(l).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"})}function ie(){const[l,o]=i.useState(""),[n,r]=i.useState([]),[C,y]=i.useState(!1),[w,z]=i.useState(""),[N,d]=i.useState(null),[b,D]=i.useState(""),S=i.useRef(null),[t,x]=i.useState(null),[m,f]=i.useState(null),[R,E]=i.useState(null),h=s=>{E(s),setTimeout(()=>E(null),2500)},[g,P]=i.useState(!0),u=i.useRef(null),c=i.useCallback(async s=>{y(!0),z("");try{const a=await j(`/api/files?path=${encodeURIComponent(s)}`);r(a.entries??[]),o(a.path)}catch(a){z(a.message||"加载失败"),r([])}finally{y(!1)}},[]);i.useEffect(()=>{c(l)},[]),i.useEffect(()=>(u.current&&clearInterval(u.current),g&&(u.current=setInterval(()=>c(l),5e3)),()=>{u.current&&clearInterval(u.current)}),[g,l,c]);const p=s=>{d(null),x(null),c(s)},F=()=>{if(!l)return;const s=l.split("/");s.pop(),p(s.join("/"))},$=l?l.split("/"):[],_=s=>{d(s.path),D(s.name),setTimeout(()=>{var a;return(a=S.current)==null?void 0:a.select()},50)},I=async()=>{if(!N||!b.trim()){d(null);return}try{await j("/api/files/rename",{method:"POST",body:JSON.stringify({path:N,newName:b.trim()})}),h("重命名成功"),c(l)}catch(s){h(`重命名失败: ${s.message}`)}d(null)},B=async()=>{if(m)try{await j("/api/files/delete",{method:"POST",body:JSON.stringify({path:m.path})}),h("已删除"),f(null),c(l)}catch(s){h(`删除失败: ${s.message}`)}},L=s=>{const a=document.createElement("a");a.href=`/api/files/download?path=${encodeURIComponent(s.path)}`,a.download=s.name,a.click()},M=async s=>{try{const a=await j(`/api/files/info?path=${encodeURIComponent(s.path)}`);x(a)}catch(a){h(`获取详情失败: ${a.message}`)}};return e.jsxs("div",{className:"page-files",children:[e.jsxs("div",{className:"files-toolbar",children:[e.jsxs("div",{className:"files-breadcrumb",children:[e.jsx("button",{className:"files-nav-btn",onClick:F,disabled:!l,title:"返回上级",children:e.jsx(X,{size:16})}),e.jsx("span",{className:"breadcrumb-item",onClick:()=>p(""),children:"workspace"}),$.map((s,a)=>e.jsxs("span",{children:[e.jsx(O,{size:12,className:"breadcrumb-sep"}),e.jsx("span",{className:"breadcrumb-item",onClick:()=>p($.slice(0,a+1).join("/")),children:s})]},a))]}),e.jsxs("div",{className:"files-toolbar-actions",children:[e.jsxs("label",{className:"files-auto-refresh",title:"自动刷新 (5s)",children:[e.jsx("input",{type:"checkbox",checked:g,onChange:s=>P(s.target.checked)}),e.jsx("span",{children:"自动刷新"})]}),e.jsx("button",{className:"files-refresh-btn",onClick:()=>c(l),title:"刷新",children:e.jsx(U,{size:14,className:C?"spin":""})})]})]}),w?e.jsx("div",{className:"files-error",children:w}):e.jsx("div",{className:"files-table-wrapper",children:e.jsxs("table",{className:"files-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{className:"col-name",children:"名称"}),e.jsx("th",{className:"col-size",children:"大小"}),e.jsx("th",{className:"col-mtime",children:"修改时间"}),e.jsx("th",{className:"col-actions",children:"操作"})]})}),e.jsxs("tbody",{children:[n.length===0&&!C&&e.jsx("tr",{children:e.jsx("td",{colSpan:4,className:"files-empty",children:"空目录"})}),n.map(s=>e.jsxs("tr",{className:"files-row",onDoubleClick:()=>s.isDirectory&&p(s.path),children:[e.jsx("td",{className:"col-name",children:e.jsxs("div",{className:"col-name-inner",children:[e.jsx("span",{className:"file-icon",children:s.isDirectory?e.jsx(A,{size:16}):e.jsx(J,{size:16})}),N===s.path?e.jsx("input",{ref:S,className:"rename-input",value:b,onChange:a=>D(a.target.value),onBlur:I,onKeyDown:a=>{a.key==="Enter"&&I(),a.key==="Escape"&&d(null)}}):e.jsx("span",{className:`file-name ${s.isDirectory?"is-dir":""}`,onClick:()=>s.isDirectory?p(s.path):void 0,children:s.name})]})}),e.jsx("td",{className:"col-size",children:s.isDirectory?"—":T(s.size)}),e.jsx("td",{className:"col-mtime",children:v(s.mtime)}),e.jsxs("td",{className:"col-actions",children:[e.jsx("button",{className:"file-action-btn",title:"重命名",onClick:()=>_(s),children:e.jsx(Y,{size:14})}),!s.isDirectory&&e.jsx("button",{className:"file-action-btn",title:"下载",onClick:()=>L(s),children:e.jsx(K,{size:14})}),e.jsx("button",{className:"file-action-btn",title:"详情",onClick:()=>M(s),children:e.jsx(Q,{size:14})}),e.jsx("button",{className:"file-action-btn danger",title:"删除",onClick:()=>f(s),children:e.jsx(V,{size:14})})]})]},s.path))]})]})}),m&&e.jsx("div",{className:"files-modal-overlay",onClick:()=>f(null),children:e.jsxs("div",{className:"files-modal",onClick:s=>s.stopPropagation(),children:[e.jsx("div",{className:"files-modal-title",children:"确认删除"}),e.jsxs("p",{children:["确定要删除 ",e.jsx("strong",{children:m.name})," 吗?",m.isDirectory?"(将递归删除目录下所有内容)":""]}),e.jsxs("div",{className:"files-modal-actions",children:[e.jsx("button",{className:"btn-secondary",onClick:()=>f(null),children:"取消"}),e.jsx("button",{className:"btn-danger",onClick:B,children:"删除"})]})]})}),t&&e.jsx("div",{className:"files-modal-overlay",onClick:()=>x(null),children:e.jsxs("div",{className:"files-modal files-detail-modal",onClick:s=>s.stopPropagation(),children:[e.jsxs("div",{className:"files-modal-header",children:[e.jsx("div",{className:"files-modal-title",children:"文件详情"}),e.jsx("button",{className:"files-modal-close",onClick:()=>x(null),children:e.jsx(G,{size:16})})]}),e.jsxs("div",{className:"files-detail-grid",children:[e.jsx("span",{className:"detail-label",children:"名称"}),e.jsx("span",{className:"detail-value",children:t.name}),e.jsx("span",{className:"detail-label",children:"路径"}),e.jsx("span",{className:"detail-value",children:t.path}),e.jsx("span",{className:"detail-label",children:"类型"}),e.jsx("span",{className:"detail-value",children:t.isDirectory?"目录":t.ext||"文件"}),e.jsx("span",{className:"detail-label",children:"大小"}),e.jsx("span",{className:"detail-value",children:t.isDirectory?"—":T(t.size)}),e.jsx("span",{className:"detail-label",children:"修改时间"}),e.jsx("span",{className:"detail-value",children:v(t.mtime)}),e.jsx("span",{className:"detail-label",children:"创建时间"}),e.jsx("span",{className:"detail-value",children:v(t.birthtime)})]})]})}),R&&e.jsx("div",{className:"files-toast",children:R})]})}export{ie as FilesPage};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{j as s,r}from"./react-vendor-BPQixOLZ.js";import{c as ue,a as y,T as H,D as he,f as K}from"./index-CP1eHYpM.js";import{u as pe}from"./ConfirmDialog-DbV-E1Nd.js";import{C as fe}from"./clock-W2ha6TRb.js";import"./highlight-DJvvuuwd.js";import"./katex-Bq6vt64r.js";import"./markdown-B2G8c9k5.js";/**
|
|
2
|
+
* @license lucide-react v1.7.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const xe=[["path",{d:"M12 3v18",key:"108xh3"}],["path",{d:"m19 8 3 8a5 5 0 0 1-6 0zV7",key:"zcdpyk"}],["path",{d:"M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1",key:"1yorad"}],["path",{d:"m5 8 3 8a5 5 0 0 1-6 0zV7",key:"eua70x"}],["path",{d:"M7 21h10",key:"1b0cd5"}]],je=ue("scale",xe);function ee(t){return!t.present||t.children.some(ee)}function se(t){return t.children.reduce((o,d)=>o+1+se(d),0)}function _({node:t,mode:o,depth:d=0}){var S,p;const u=((S=t.services)==null?void 0:S.requires)??[],h=((p=t.services)==null?void 0:p.provides)??[],n=t.children.length>0,[f,L]=r.useState(()=>o==="view"||ee(t));return s.jsxs("div",{className:"dep-tree-node",style:d>0?{marginLeft:14}:void 0,children:[s.jsxs("div",{className:`dep-tree-row${n?" dep-tree-toggle":""}`,onClick:n?()=>L(N=>!N):void 0,children:[s.jsx("span",{className:"dep-tree-caret",children:n?f?"▾":"▸":""}),s.jsx("span",{className:"dep-tree-name",children:t.name}),!t.present&&s.jsx("span",{className:"dep-tree-tag dep-tag-missing",children:o==="install"?"将引入":"未装"}),u.length>0&&s.jsxs("span",{className:"dep-tree-tag dep-tag-req",children:["需 ",u.join("、")]}),h.length>0&&s.jsxs("span",{className:"dep-tree-tag dep-tag-prov",children:["供 ",h.join("、")]}),n&&!f&&s.jsxs("span",{className:"dep-tree-tag dep-tag-count",children:[se(t)," 项已装"]})]}),f&&t.children.map(N=>s.jsx(_,{node:N,mode:o,depth:d+1},N.name))]})}function ve({graph:t}){const o=t.upstream.children,{required:d,provides:u}=t.services,h=t.downstream.children.map(n=>n.name);return s.jsxs("div",{className:"dep-disclosure",children:[s.jsx("div",{className:"dep-section-label",children:"依赖关系"}),o.length>0?o.map(n=>s.jsx(_,{node:n,mode:"install"},n.name)):s.jsx("div",{className:"dep-empty",children:"无 import 依赖"}),d.length>0&&s.jsxs("div",{className:"dep-line",children:["需要服务:",d.map(n=>s.jsxs("span",{className:`dep-svc ${n.providedBy?"ok":"warn"}`,children:[n.service,n.providedBy?`(✓ ${n.providedBy})`:"(⚠ 无提供者)"]},n.service))]}),u.length>0&&s.jsxs("div",{className:"dep-line",children:["提供服务:",u.join("、")]}),h.length>0&&s.jsxs("div",{className:"dep-line",children:["已装插件中依赖它的:",h.join("、")]})]})}function ge({graph:t}){const o=t.downstream.children;return o.length===0&&t.serviceDependents.length===0?null:s.jsxs("div",{className:"dep-uninstall-warn",children:[t.serviceDependents.length>0&&s.jsxs("div",{className:"dep-line dep-warn-block",children:["⛔ 依赖它提供的服务且无替代:",t.serviceDependents.join("、"),s.jsx("br",{}),"(卸载会被拒绝,请先卸载它们或装替代提供者)"]}),o.length>0&&s.jsxs("div",{className:"dep-warn-block",children:[s.jsx("div",{children:"⚠️ 这些已装插件 import 了它(删除后可能无法启动,需重新安装恢复):"}),o.map(d=>s.jsx(_,{node:d,mode:"view"},d.name))]})]})}const Y={workspace:{label:"工作区",hint:"源码在本仓库内,改代码即生效,不经市场更新"},link:{label:"本地链接",hint:"由 file: / link: 指向本地目录,更新请改那份源码"},git:{label:"外部源",hint:"由 git / URL / user-repo 简写安装,更新请改依赖声明"},alias:{label:"别名",hint:"由 npm: 别名指向另一个包,市场更新会拆掉别名,故不提供"},transitive:{label:"依赖引入",hint:"由其它包引入,版本随父包的范围,不单独更新"}},Q={relevance:"默认排序",downloads:"下载量",updated:"最近更新",score:"综合评分"},X={all:"全部来源",official:"仅官方",community:"仅社区"},Z={all:"全部状态",installed:"已安装",available:"未安装"},B={all:"全部类型",plugin:"功能插件",interface:"前端界面",core:"内核",runtime:"宿主",api:"API 契约",schema:"数据规范",util:"工具库"},U=new Set(["plugin","interface"]);function ye(t){return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${(t/1e3).toFixed(1)}k`:String(t)}function Ne(t){if(!t)return"";const o=Date.parse(t);if(Number.isNaN(o))return"";const d=Math.max(0,(Date.now()-o)/1e3),u=[[31536e3,"年"],[2592e3,"个月"],[86400,"天"],[3600,"小时"],[60,"分钟"]];for(const[h,n]of u)if(d>=h)return`${Math.floor(d/h)} ${n}前`;return"刚刚"}function De({plugins:t,onRefresh:o,onRestart:d}){const{confirm:u,dialog:h}=pe(),[n,f]=r.useState(null),[L,S]=r.useState(null),[p,N]=r.useState([]),[T,P]=r.useState(!1),[A,ae]=r.useState(!1),[I,F]=r.useState(null),[M,W]=r.useState(""),[b,te]=r.useState("relevance"),[D,ne]=r.useState("all"),[O,le]=r.useState("all"),[E,ie]=r.useState("plugin"),[G,R]=r.useState(new Set),[$,J]=r.useState(!1),[x,q]=r.useState(null),k=r.useRef(0),j=e=>{S(e),setTimeout(()=>S(null),2500)},C=r.useCallback(async()=>{const e=++k.current;P(!0),F(null);try{const[l,a]=await Promise.all([y("/api/marketplace?q="),y("/api/system-components").catch(()=>({components:[]}))]),i=l.packages??[],g=new Set(i.map(c=>c.name)),m=(a.components??[]).filter(c=>!g.has(c.name)).map(c=>({name:c.name,description:c.description??"",version:c.latest??c.version??"",resolved:c.version,request:c.request,origin:c.origin,updatable:c.updatable??!1,installed:!0,official:c.name.startsWith("@aalis/"),category:c.kind}));if(e!==k.current)return;N([...i,...m]),l.warning&&F(l.warning)}catch{if(e!==k.current)return;j("无法加载插件市场")}e===k.current&&(P(!1),ae(!0))},[]);r.useEffect(()=>{C()},[C]);const V=r.useMemo(()=>new Set(t.map(e=>e.name)),[t]),w=r.useMemo(()=>p.filter(e=>e.updatable),[p]);r.useEffect(()=>{R(e=>{const l=new Set(w.map(i=>i.name)),a=new Set([...e].filter(i=>l.has(i)));return a.size===e.size?e:a})},[w]);const v=w.filter(e=>G.has(e.name)),re=v.some(e=>e.category==="core"||e.category==="runtime"),ce=e=>R(l=>{const a=new Set(l);return a.has(e)?a.delete(e):a.add(e),a}),oe=async()=>{if(!(v.length===0||$)){J(!0),q(null);try{const e=await y("/api/marketplace/update",{method:"POST",body:JSON.stringify({targets:v.map(l=>({name:l.name,version:l.version}))})});q(e),e.ok&&e.restarting&&(d==null||d(`正在应用 ${v.length} 项更新并重启…`))}catch(e){q({ok:!1,message:e instanceof Error?e.message:String(e)})}J(!1)}},z=r.useMemo(()=>{const e=M.trim().toLowerCase().split(/\s+/).filter(Boolean),l=p.map(a=>({...a,installed:a.installed||V.has(a.name)})).filter(a=>{if(E!=="all"&&(a.category??"plugin")!==E||D==="official"&&!a.official||D==="community"&&a.official||O==="installed"&&!a.installed||O==="available"&&a.installed)return!1;if(e.length){const i=`${a.name} ${a.description} ${(a.keywords??[]).join(" ")} ${a.author??""}`.toLowerCase();if(!e.every(g=>i.includes(g)))return!1}return!0});return b==="relevance"?l:l.sort((a,i)=>b==="downloads"?(i.downloads??0)-(a.downloads??0):b==="score"?(i.score??0)-(a.score??0):b==="updated"?Date.parse(i.updated??"0")-Date.parse(a.updated??"0"):0)},[p,V,M,b,D,O,E]),de=async(e,l)=>{let a=null;try{a=await y(`/api/marketplace/depgraph?name=${encodeURIComponent(e)}`)}catch{}if(await u({title:`安装${l?"官方插件":"第三方社区插件"}「${e}」`,body:s.jsxs(s.Fragment,{children:[a&&s.jsx(ve,{graph:a}),s.jsx("div",{className:"dep-note",children:"将从 npm 安装。安装后它以你授予的能力运行(可在权限页查看依赖与权限)。请确认来源可信。"})]}),confirmLabel:"安装"})){f(e);try{const m=await y("/api/marketplace/install",{method:"POST",body:JSON.stringify({name:e})});m.ok?(j(m.message??`${e} 已安装`),o(),C()):j(m.error??m.message??"安装失败")}catch(m){j(K(m,"安装失败"))}f(null)}},me=async e=>{let l=null;try{l=await y(`/api/marketplace/depgraph?name=${encodeURIComponent(e)}`)}catch{}if(await u({title:`卸载「${e}」`,body:s.jsxs(s.Fragment,{children:[l&&s.jsx(ge,{graph:l}),s.jsx("div",{className:"dep-note",children:"将删除其代码目录并清除残留配置。不可恢复,但可从市场重新安装。"})]}),confirmLabel:"卸载",danger:!0})){f(e);try{const i=await y("/api/marketplace/uninstall",{method:"POST",body:JSON.stringify({name:e})});i.ok?(j(i.message??`${e} 已卸载`),o(),C()):j(i.error??i.message??"卸载失败")}catch(i){j(K(i,"卸载失败"))}f(null)}};return s.jsxs("div",{className:"page-content page-marketplace",children:[h,L&&s.jsx("div",{className:"toast",children:L}),s.jsxs("div",{className:"section-label",children:["插件市场",A&&s.jsxs("span",{className:"market-count",children:["显示 ",z.length," / 共 ",p.length]})]}),w.length>0&&s.jsxs("div",{className:"update-panel",children:[s.jsxs("div",{className:"update-panel-head",children:[s.jsxs("span",{children:["可更新 ",w.length," 项,已选 ",v.length]}),s.jsxs("div",{className:"update-panel-actions",children:[s.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>R(new Set(w.map(e=>e.name))),disabled:$,children:"全选"}),s.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:oe,disabled:$||v.length===0,children:$?"正在更新…":`更新所选(${v.length})`})]})]}),re&&s.jsxs("div",{className:"update-panel-warn",children:[s.jsx(H,{size:14})," 所选包含内核或宿主,更新后将重启整个应用;新版本起不来会自动回滚。"]}),s.jsx("div",{className:"update-panel-note",children:"所选项**一次性提交**:先整组做依赖预检,通过后一次安装、一次重启。任一项的 peer 版本不兼容则整批不执行且不改动任何文件——此时把它要求的包(如内核)一并勾选再试。"})]}),x&&s.jsxs("div",{className:x.ok?"update-result ok":"update-result err",children:[s.jsx("div",{children:x.error??x.message??"更新失败"}),x.conflicts&&x.conflicts.length>0&&s.jsx("ul",{className:"update-conflicts",children:x.conflicts.map(e=>s.jsx("li",{children:e},e))})]}),s.jsxs("div",{className:"market-filter-row",children:[s.jsx("input",{className:"config-edit-input",style:{flex:1,minWidth:180},placeholder:"搜索插件(名称 / 描述 / 关键词 / 作者)",value:M,onChange:e=>W(e.target.value)}),s.jsx("select",{className:"config-edit-input",value:E,onChange:e=>ie(e.target.value),title:"组件类型",children:Object.keys(B).map(e=>s.jsx("option",{value:e,children:B[e]},e))}),s.jsx("select",{className:"config-edit-input",value:D,onChange:e=>ne(e.target.value),children:Object.keys(X).map(e=>s.jsx("option",{value:e,children:X[e]},e))}),s.jsx("select",{className:"config-edit-input",value:O,onChange:e=>le(e.target.value),children:Object.keys(Z).map(e=>s.jsx("option",{value:e,children:Z[e]},e))}),s.jsx("select",{className:"config-edit-input",value:b,onChange:e=>te(e.target.value),title:"排序",children:Object.keys(Q).map(e=>s.jsx("option",{value:e,children:Q[e]},e))}),s.jsx("button",{className:"btn-sm",onClick:()=>C(),disabled:T,children:T?"加载中...":"刷新"})]}),!A&&T&&s.jsxs("div",{className:"empty-hint",style:{padding:16},children:["正在从 npm 加载带 ",s.jsx("code",{children:"aalis-plugin"})," 标签的插件…"]}),I&&s.jsx("div",{className:"empty-hint",style:{padding:12,color:"var(--warning, #ffb300)"},children:I}),A&&z.length===0&&!T&&!I&&s.jsx("div",{className:"empty-hint",style:{padding:16},children:p.length===0?"未找到任何插件":"无匹配项 —— 试试调整搜索词或筛选条件"}),s.jsx("div",{className:"marketplace-grid",children:z.map(e=>{var i,g,m;const l=((i=e.links)==null?void 0:i.homepage)||((g=e.links)==null?void 0:g.repository)||((m=e.links)==null?void 0:m.npm),a=l&&/^https?:\/\//i.test(l)?l:void 0;return s.jsxs("div",{className:"marketplace-card",children:[s.jsxs("div",{className:"marketplace-card-info",children:[a?s.jsx("a",{className:"marketplace-card-name",href:a,target:"_blank",rel:"noreferrer",children:e.name}):s.jsx("span",{className:"marketplace-card-name",children:e.name}),s.jsx("span",{className:"marketplace-card-version",children:e.installed?e.resolved?`v${e.resolved}`:"版本未知":`v${e.version}`}),s.jsx("span",{className:`badge ${e.official?"official":"community"}`,children:e.official?"官方":"社区"}),e.category&&e.category!=="plugin"&&s.jsx("span",{className:"badge",title:"组件类别",children:B[e.category]}),e.insecure&&s.jsxs("span",{className:"badge",style:{background:"var(--danger)",color:"#fff",display:"inline-flex",alignItems:"center",gap:3},title:"npm 标记为不安全包,谨慎安装",children:[s.jsx(H,{size:11})," 不安全"]}),e.author&&s.jsxs("span",{className:"marketplace-card-author",children:["by ",e.author]}),e.installed&&s.jsx("span",{className:"badge active",children:"已安装"}),e.installed&&e.origin&&e.origin!=="registry"&&s.jsx("span",{className:"badge",title:Y[e.origin].hint,children:Y[e.origin].label}),e.updatable&&s.jsxs("label",{className:"badge",style:{background:"var(--warning)",color:"#1a1a1a",cursor:"pointer"},title:`本地 v${e.resolved}(声明 ${e.request??"?"}),npm 最新 v${e.version}。勾选后用顶部「更新所选」批量提交`,children:[s.jsx("input",{type:"checkbox",checked:G.has(e.name),onChange:()=>ce(e.name),disabled:$,style:{marginRight:4}}),"可更新 v",e.version]})]}),s.jsx("div",{className:"marketplace-card-desc",children:e.description||"(无描述)"}),e.keywords&&e.keywords.length>0&&s.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:4,marginTop:4},children:e.keywords.slice(0,6).map(c=>s.jsx("button",{type:"button",className:"market-kw",title:`按 “${c}” 筛选`,onClick:()=>W(c),children:c},c))}),s.jsxs("div",{className:"market-meta",children:[e.downloads!=null&&s.jsxs("span",{className:"market-meta-item",title:"近一月下载量",children:[s.jsx(he,{size:12})," ",ye(e.downloads),"/月"]}),e.updated&&s.jsxs("span",{className:"market-meta-item",title:new Date(e.updated).toLocaleString(),children:[s.jsx(fe,{size:12})," ",Ne(e.updated)]}),e.license&&s.jsxs("span",{className:"market-meta-item",title:"许可证",children:[s.jsx(je,{size:12})," ",e.license]})]}),s.jsxs("div",{style:{marginTop:8},children:[!U.has(e.category??"plugin")&&s.jsx("span",{className:"market-meta-item",title:"随脚手架就位或作为插件依赖自动安装/卸载,无需也无法单独装卸",children:"随依赖管理"}),U.has(e.category??"plugin")&&!e.installed&&s.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>de(e.name,e.official),disabled:n!==null,title:n&&n!==e.name?`请等待 ${n} 处理完成`:void 0,children:n===e.name?"安装中...":"安装"}),U.has(e.category??"plugin")&&e.installed&&s.jsx("button",{className:"btn btn-sm",style:{color:"var(--danger)"},onClick:()=>me(e.name),disabled:n!==null,title:n&&n!==e.name?`请等待 ${n} 处理完成`:"卸载插件(删包 + 清配置)",children:n===e.name?"处理中...":"卸载"})]})]},e.name)})})]})}export{De as MarketplacePage};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as c,j as e}from"./react-vendor-BPQixOLZ.js";import{c as p,a as h}from"./index-
|
|
1
|
+
import{r as c,j as e}from"./react-vendor-BPQixOLZ.js";import{c as p,a as h}from"./index-CP1eHYpM.js";import{G as x}from"./globe-DBjh8D_x.js";import"./highlight-DJvvuuwd.js";import"./katex-Bq6vt64r.js";import"./markdown-B2G8c9k5.js";/**
|
|
2
2
|
* @license lucide-react v1.7.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import{r as d,j as e}from"./react-vendor-BPQixOLZ.js";import{c as B,a as k,T as Re,f as M}from"./index-CP1eHYpM.js";import{b as W,S as ke,f as Ce,u as Je}from"./SchemaForm-BcYxH5r1.js";import{u as Ge}from"./ConfirmDialog-DbV-E1Nd.js";import"./highlight-DJvvuuwd.js";import"./katex-Bq6vt64r.js";import"./markdown-B2G8c9k5.js";/**
|
|
2
|
+
* @license lucide-react v1.7.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const Ke=[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2",key:"8i5ue5"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2",key:"1b9ql8"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12",key:"1jonct"}]],Ze=B("link-2",Ke);/**
|
|
7
|
+
* @license lucide-react v1.7.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const He=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],We=B("loader-circle",He);/**
|
|
12
|
+
* @license lucide-react v1.7.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const Qe=[["path",{d:"M16.247 7.761a6 6 0 0 1 0 8.478",key:"1fwjs5"}],["path",{d:"M19.075 4.933a10 10 0 0 1 0 14.134",key:"ehdyv1"}],["path",{d:"M4.925 19.067a10 10 0 0 1 0-14.134",key:"1q22gi"}],["path",{d:"M7.753 16.239a6 6 0 0 1 0-8.478",key:"r2q7qm"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}]],Xe=B("radio",Qe);/**
|
|
17
|
+
* @license lucide-react v1.7.0 - ISC
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the ISC license.
|
|
20
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/const Ye=[["rect",{width:"8",height:"8",x:"3",y:"3",rx:"2",key:"by2w9f"}],["path",{d:"M7 11v4a2 2 0 0 0 2 2h4",key:"xkn7yn"}],["rect",{width:"8",height:"8",x:"13",y:"13",rx:"2",key:"1cgmvn"}]],Ve=B("workflow",Ye);function Q({label:u,value:r,depth:x=0,secret:T,description:N,defaultValue:v}){const[L,O]=d.useState(x<1);if(Array.isArray(r))return r.length===0?e.jsxs("div",{className:"config-item",style:{paddingLeft:x*12},children:[e.jsxs("span",{className:"key",children:[e.jsx("code",{className:"field-key",children:u}),N&&e.jsxs("span",{className:"field-hint",children:[" / ",N]})]}),e.jsx("span",{className:"val",children:"(空)"})]}):e.jsxs("div",{className:"config-nested",style:{paddingLeft:x*12},children:[e.jsxs("div",{className:"config-nested-header",onClick:()=>O(g=>!g),children:[e.jsx("span",{className:`config-block-toggle ${L?"open":""}`,children:"▶"}),e.jsxs("span",{className:"key",children:[e.jsx("code",{className:"field-key",children:u}),N&&e.jsxs("span",{className:"field-hint",children:[" / ",N]})]}),e.jsxs("span",{className:"config-nested-count",children:[r.length," 项"]})]}),L&&e.jsx("div",{className:"config-nested-body",children:r.map((g,j)=>e.jsx(Q,{label:`#${j+1}`,value:g,depth:x+1,secret:T},j))})]});if(r==null||typeof r!="object"){const g=T||typeof r=="string"&&/(apiKey|password|secret|token)(?![a-zA-Z])/i.test(u),j=r==null,C=j&&v!==void 0&&v!==null,S=j?C?typeof v=="object"?JSON.stringify(v):String(v):"-":String(r),E=g&&S.length>4?S.slice(0,4)+"••••••":S;return e.jsxs("div",{className:"config-item",style:{paddingLeft:x*12},children:[e.jsxs("span",{className:"key",children:[e.jsx("code",{className:"field-key",children:u}),N&&e.jsxs("span",{className:"field-hint",children:[" / ",N]})]}),e.jsxs("span",{className:"val",title:g?"••••••":S,children:[E,C&&e.jsx("span",{className:"field-hint",children:" (默认)"})]})]})}const b=Object.entries(r);return e.jsxs("div",{className:"config-nested",style:{paddingLeft:x*12},children:[e.jsxs("div",{className:"config-nested-header",onClick:()=>O(g=>!g),children:[e.jsx("span",{className:`config-block-toggle ${L?"open":""}`,children:"▶"}),e.jsx("span",{className:"key",children:u}),e.jsxs("span",{className:"config-nested-count",children:[b.length," 项"]})]}),L&&e.jsx("div",{className:"config-nested-body",children:b.map(([g,j])=>e.jsx(Q,{label:g,value:j,depth:x+1,secret:T},g))})]})}function ls({plugins:u,config:r,onRefresh:x,onConfigSaved:T,onRestart:N}){const{confirm:v,dialog:L}=Ge(),[O,b]=d.useState(new Set),g=d.useRef(u),[j,C]=d.useState(null),[S,E]=d.useState({}),[X,U]=d.useState({}),[F,Y]=d.useState({}),[_,V]=d.useState(void 0),[ee,se]=d.useState(null),[ne,te]=d.useState(!1),[we,$e]=d.useState(new Set),[A,ae]=d.useState(""),[Le,Oe]=d.useState(new Set),[ie,R]=d.useState(null),[J,G]=d.useState("");d.useEffect(()=>{g.current!==u&&O.size>0&&b(new Set),g.current=u},[u,O]);const P=s=>b(a=>new Set(a).add(s)),w=s=>O.has(s),p=s=>{se(s),setTimeout(()=>se(null),2500)},Ie=async s=>{if(s.core)return;P(s.instanceId);const a=s.state==="disabled"?"enable":"disable";try{await k(`/api/plugins/${encodeURIComponent(s.instanceId)}/${a}`,{method:"POST"}),p(`${s.instanceId} 已${a==="enable"?"启用":"禁用"}`),x()}catch(i){p(M(i,"未知错误")),b(l=>{const m=new Set(l);return m.delete(s.instanceId),m})}},Me=s=>{const a=s.config??{};s.configSchema?U(W(s.configSchema,a)):E(Ce(a)),C(s.instanceId)},ce=d.useCallback(async s=>{if(!F[s])try{const a=await k(`/api/models/${encodeURIComponent(s)}`),i=a.providers&&a.providers.length>0?a.providers.map(l=>({label:`${l.provider} / ${l.model}`,value:l.value})):(a.models??[]).map(l=>({label:l,value:l}));Y(l=>({...l,[s]:i}))}catch{Y(a=>({...a,[s]:[]}))}},[F]),le=d.useCallback(async()=>{if(!_)try{const s=await k("/api/llm-providers");V(s.providers??[])}catch{V([])}},[_]),oe=s=>{const a=s.defaultConfig??{};s.configSchema?U(W(s.configSchema,a)):E(Ce(a))},re=async(s,a)=>{const i=a?X:Je(S);P(s);try{await k(`/api/plugins/${encodeURIComponent(s)}/config`,{method:"PUT",body:JSON.stringify({config:i})})}catch(l){p(M(l,"未知错误")),b(m=>{const q=new Set(m);return q.delete(s),q});return}p(`${s} 配置已更新,正在重载…`),C(null),x()},de=async s=>{const a=J.trim();if(a){P(s);try{const i=await k(`/api/plugins/${encodeURIComponent(s)}/instances`,{method:"POST",body:JSON.stringify({suffix:a})});p(`已创建实例 ${i.instanceId}`),R(null),G(""),x()}catch(i){p(M(i,"创建失败")),b(l=>{const m=new Set(l);return m.delete(s),m})}}},Te=async s=>{if(await v({title:`删除实例「${s}」`,body:"该实例的配置将一并移除。",confirmLabel:"删除",danger:!0})){P(s);try{await k(`/api/plugins/${encodeURIComponent(s)}/instance`,{method:"DELETE"}),p(`已删除实例 ${s}`),x()}catch(i){p(M(i,"删除失败")),b(l=>{const m=new Set(l);return m.delete(s),m})}}},Ee=async s=>{if(await v({title:`卸载插件「${s.displayName??s.name}」`,body:`${s.name}
|
|
22
|
+
|
|
23
|
+
将删除其代码目录并清除残留配置。不可恢复,但可从插件市场重新安装。`,confirmLabel:"卸载",danger:!0})){P(s.instanceId);try{const i=await k("/api/marketplace/uninstall",{method:"POST",body:JSON.stringify({name:s.name})});if(!i.ok)throw new Error(i.error??i.message??"卸载失败");p(i.message??`${s.name} 已卸载`),x()}catch(i){p(M(i,"卸载失败")),b(l=>{const m=new Set(l);return m.delete(s.instanceId),m})}}},Pe=s=>s.instanceId!==s.name,ze={active:"运行中",disabled:"已禁用",pending:"等待中",disposed:"已释放",error:"运行错误"},De={active:"active",disabled:"disposed",pending:"pending",error:"error"},Fe=s=>{$e(a=>{const i=new Set(a);return i.has(s)?i.delete(s):i.add(s),i})},[me,K]=d.useState(!1),[he,ge]=d.useState({}),$=r&&r._schema?r._schema:void 0;d.useEffect(()=>{r&&$&&ge(W($,r))},[r,$]);const _e=async()=>{te(!0);const s=Object.fromEntries(Object.keys($??{}).map(a=>[a,he[a]]));try{const a=await k("/api/config",{method:"PUT",body:JSON.stringify(s)});K(!1),T(),a.restart?N():p(a.message??"全局配置已保存")}catch(a){p(M(a,"未知错误"))}te(!1)};return e.jsxs("div",{className:"page-content page-plugin-config",children:[L,ee&&e.jsx("div",{className:"toast",children:ee}),e.jsxs("div",{className:"config-header-row",children:[e.jsx("div",{className:"section-label",style:{marginBottom:0},children:"全局配置"}),e.jsx("div",{style:{display:"flex",gap:6},children:me?e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"btn btn-primary btn-sm",onClick:_e,disabled:ne,children:ne?"保存中...":"保存"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>K(!1),children:"取消"})]}):e.jsx("button",{className:"btn btn-sm",onClick:()=>K(!0),children:"编辑"})})]}),r&&$&&e.jsx("div",{className:"config-block",style:{marginTop:8,marginBottom:20},children:e.jsx("div",{className:"config-block-body",style:{paddingTop:10},children:me?e.jsx(ke,{schema:$,draft:he,onChange:ge,modelCache:F,onFetchModels:ce,llmProviders:_,onFetchLLMProviders:le}):e.jsx(e.Fragment,{children:Object.entries($).map(([s,a])=>{const i=r[s],l=a,m=l.description||l.label;return e.jsxs("div",{className:"config-item",children:[e.jsxs("span",{className:"key",children:[e.jsx("code",{className:"field-key",children:s}),m&&e.jsxs("span",{className:"field-hint",children:[" / ",m]})]}),e.jsx("span",{className:"val",children:l.type==="boolean"?i?"✓ 开启":"✗ 关闭":i===""||i==null?"(空)":String(i)})]},s)})})})}),e.jsx("div",{className:"section-label",style:{marginBottom:0},children:"插件管理"}),e.jsxs("div",{className:"plugin-search-row",children:[e.jsx("input",{className:"plugin-search-input",placeholder:"搜索插件 / 工具名 / 指令名...",value:A,onChange:s=>ae(s.target.value)}),A&&e.jsx("button",{className:"plugin-search-clear",onClick:()=>ae(""),children:"✕"})]}),u.length===0&&e.jsx("div",{className:"empty-hint",children:"无插件"}),(()=>{const s=A.toLowerCase(),a=s?u.filter(c=>c.name.toLowerCase().includes(s)||c.instanceId.toLowerCase().includes(s)||c.displayName&&c.displayName.toLowerCase().includes(s)||c.provides.some(o=>o.toLowerCase().includes(s))||(c.tools??[]).some(o=>o.toLowerCase().includes(s))||(c.commands??[]).some(o=>o.toLowerCase().includes(s))):u,i={},l=["系统","LLM 模型","智能体","存储","嵌入模型","向量存储","工具","界面","适配器","自动化","其他"];for(const c of a){const o=c.name,y=c.core?"系统":/^(@aalis\/)?plugin-(openai|deepseek|ollama)$/.test(o)?"LLM 模型":/^(@aalis\/)?plugin-agent/.test(o)||/^(@aalis\/)?plugin-persona$/.test(o)?"智能体":/^(@aalis\/)?plugin-memory-/.test(o)?"存储":/^(@aalis\/)?plugin-embedding-/.test(o)?"嵌入模型":/^(@aalis\/)?plugin-vectorstore-/.test(o)?"向量存储":/^(@aalis\/)?plugin-(tool-|tools-|websearch-)/.test(o)?"工具":/^(@aalis\/)?plugin-(webui-|cli)/.test(o)?"界面":/^(@aalis\/)?plugin-adapter-/.test(o)?"适配器":/^(@aalis\/)?plugin-(scheduler|skills)$/.test(o)?"自动化":/^(@aalis\/)?plugin-(commands|authority)$/.test(o)?"系统":"其他";i[c.instanceId]=y}const m=new Map;for(const c of l)m.set(c,[]);for(const c of a){const o=i[c.instanceId]||"其他";m.get(o).push(c)}const q=c=>{Oe(o=>{const y=new Set(o);return y.has(c)?y.delete(c):y.add(c),y})};return Array.from(m.entries()).filter(([,c])=>c.length>0).map(([c,o])=>{const y=Le.has(c);return e.jsxs("div",{className:"plugin-category",children:[e.jsxs("div",{className:"plugin-category-header",onClick:()=>q(c),children:[e.jsx("span",{className:`config-block-toggle ${y?"":"open"}`,children:"▶"}),e.jsx("span",{className:"plugin-category-name",children:c}),e.jsx("span",{className:"plugin-category-count",children:o.length})]}),!y&&o.map(n=>{var xe,pe,be,je,ye,Ne,ve;const f=n.instanceId,qe=j===f,z=we.has(f),I=Pe(n),fe=I?f.slice(n.name.length+1):void 0,ue=n.extends&&(((xe=n.extends.events)==null?void 0:xe.length)||((pe=n.extends.hooks)==null?void 0:pe.length)||n.extends.mixins&&Object.keys(n.extends.mixins).length),Z=ue||n.config&&Object.keys(n.config).length>0||!!n.configSchema,H=!!n.configSchema;return e.jsxs("div",{className:`plugin-card ${n.state==="disabled"?"disabled":""} ${n.state==="error"?"errored":""}`,style:{position:"relative"},children:[w(f)&&e.jsxs("div",{className:"plugin-reload-overlay",children:[e.jsx(We,{size:20,className:"plugin-reload-spinner"}),e.jsx("span",{children:"重载中…"})]}),e.jsxs("div",{className:"plugin-card-header",children:[e.jsxs("div",{className:"plugin-card-info",style:{cursor:Z?"pointer":"default"},onClick:()=>Z&&Fe(f),children:[Z&&e.jsx("span",{className:`config-block-toggle ${z?"open":""}`,children:"▶"}),e.jsxs("span",{className:"plugin-card-name",children:[n.displayName??n.name,n.displayName&&e.jsx("span",{className:"plugin-card-module-name",children:n.name}),fe&&e.jsxs("span",{className:"plugin-instance-suffix",children:[":",fe]})]}),e.jsx("span",{className:`badge ${De[n.state]??"pending"}`,children:ze[n.state]??n.state}),n.core&&e.jsx("span",{className:"badge core-badge",children:"核心"}),n.reusable&&!I&&e.jsx("span",{className:"badge",style:{background:"#7c5cfc",color:"#fff",fontSize:10},children:"多实例"}),n.provides.length>0&&e.jsx("span",{className:"plugin-provides-inline",children:n.provides.map(t=>e.jsx("span",{className:"provides-chip",children:t},t))})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[I&&e.jsx("button",{className:"btn btn-sm",style:{color:"#e55",fontSize:11},onClick:()=>Te(f),disabled:w(f),children:"删除"}),!I&&e.jsx("button",{className:"btn btn-sm",style:{color:"#e55",fontSize:11},onClick:()=>Ee(n),disabled:w(f),title:"卸载插件(删包 + 清配置)",children:"卸载"}),n.reusable&&!I&&e.jsx("button",{className:"btn btn-sm",style:{fontSize:11},onClick:()=>{R(ie===n.name?null:n.name),G("")},children:"+ 实例"}),e.jsxs("label",{className:`toggle-switch ${n.core?"core-locked":""}`,children:[e.jsx("input",{type:"checkbox",checked:n.state!=="disabled",onChange:()=>Ie(n),disabled:n.core||w(f)}),e.jsx("span",{className:"toggle-slider"})]})]})]}),ie===n.name&&!I&&e.jsxs("div",{className:"plugin-new-instance-row",style:{display:"flex",gap:6,padding:"6px 12px",alignItems:"center"},children:[e.jsxs("span",{style:{fontSize:12,opacity:.7},children:[n.name,":"]}),e.jsx("input",{style:{flex:1,fontSize:12},className:"plugin-search-input",placeholder:"输入实例后缀(如 vision)",value:J,onChange:t=>G(t.target.value),onKeyDown:t=>t.key==="Enter"&&de(n.name)}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>de(n.name),disabled:!J.trim()||w(n.name),children:"创建"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>R(null),children:"取消"})]}),n.state==="error"&&n.error&&e.jsxs("div",{className:"plugin-error-msg",children:[e.jsx(Re,{size:14})," ",n.error]}),z&&n.provides.length>0&&e.jsx("div",{className:"plugin-card-provides",children:n.provides.map(t=>e.jsx("span",{className:"tool-chip",children:t},t))}),z&&((((be=n.requiredServices)==null?void 0:be.length)??0)>0||(((je=n.optionalServices)==null?void 0:je.length)??0)>0||(((ye=n.capabilities)==null?void 0:ye.length)??0)>0)&&e.jsxs("div",{className:"plugin-card-caps",children:[(n.requiredServices??[]).map(t=>e.jsxs("span",{className:"cap-chip dep-required",title:"必需依赖的服务",children:["需 ",t]},`req-${t}`)),(n.optionalServices??[]).map(t=>e.jsxs("span",{className:"cap-chip dep-optional",title:"可选依赖的服务",children:["可选 ",t]},`opt-${t}`)),(n.capabilities??[]).map(t=>e.jsx("span",{className:`cap-chip ${t==="safety:dangerous"?"cap-danger":"cap-sensitive"}`,title:"触达的敏感能力",children:t==="safety:dangerous"?"⚠ 高危操作":t},`cap-${t}`))]}),z&&ue&&e.jsxs("div",{className:"plugin-card-extends",children:[e.jsx("span",{className:"extends-label",children:"扩展 Core:"}),(Ne=n.extends.events)==null?void 0:Ne.map(t=>e.jsxs("span",{className:"extends-chip event",children:[e.jsx(Xe,{size:12})," ",t]},`e-${t}`)),(ve=n.extends.hooks)==null?void 0:ve.map(t=>e.jsxs("span",{className:"extends-chip hook",children:[e.jsx(Ve,{size:12})," ",t]},`h-${t}`)),n.extends.mixins&&Object.entries(n.extends.mixins).map(([t,D])=>D.map(h=>e.jsxs("span",{className:"extends-chip mixin",children:[e.jsx(Ze,{size:12})," ctx.",h,"()"]},`m-${t}-${h}`)))]}),z&&(n.config&&Object.keys(n.config).length>0||H)&&e.jsx("div",{className:"plugin-card-config",children:qe?H?e.jsxs(e.Fragment,{children:[e.jsx(ke,{schema:n.configSchema,draft:X,onChange:U,modelCache:F,onFetchModels:ce,llmProviders:_,onFetchLLMProviders:le}),e.jsxs("div",{className:"config-edit-actions",children:[e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>re(f,!0),disabled:w(f),children:"保存"}),n.defaultConfig&&Object.keys(n.defaultConfig).length>0&&e.jsx("button",{className:"btn btn-warn btn-sm",onClick:()=>oe(n),children:"恢复默认"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>C(null),children:"取消"})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"config-edit-form",children:Object.keys(S).map(t=>e.jsxs("div",{className:"config-edit-row",children:[e.jsx("label",{className:"config-edit-label",children:t}),e.jsx("input",{className:"config-edit-input",type:/(apiKey|password|secret|token)(?![a-zA-Z])/i.test(t)?"password":"text",value:S[t],onChange:D=>E(h=>({...h,[t]:D.target.value}))})]},t))}),e.jsxs("div",{className:"config-edit-actions",children:[e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>re(f,!1),disabled:w(f),children:"保存"}),n.defaultConfig&&Object.keys(n.defaultConfig).length>0&&e.jsx("button",{className:"btn btn-warn btn-sm",onClick:()=>oe(n),children:"恢复默认"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>C(null),children:"取消"})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"config-block-body",style:{paddingTop:6},children:(H?Object.keys(n.configSchema).map(t=>[t,n.config[t]]):Object.entries(n.config)).map(([t,D])=>{var Se;const h=(Se=n.configSchema)==null?void 0:Se[t],Be=h&&"secret"in h?h.secret:void 0,Ue=h&&"description"in h?h.description:h&&"label"in h?h.label:void 0,Ae=h&&"default"in h?h.default:void 0;return e.jsx(Q,{label:t,value:D,secret:Be,description:Ue,defaultValue:Ae},t)})}),e.jsx("button",{className:"btn btn-sm",onClick:()=>Me(n),children:"编辑配置"})]})})]},f)})]},c)})})()]})}export{ls as PluginConfigPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as g,j as e}from"./react-vendor-BPQixOLZ.js";import{p as D,b as me,B as K,M as O,R as _,d as z,e as B,W as ue}from"./index-CP1eHYpM.js";import{M as R}from"./markdown-B2G8c9k5.js";import"./highlight-DJvvuuwd.js";import"./katex-Bq6vt64r.js";function xe(s,u){const[h,l]=g.useState({segments:[],isStreaming:!1,done:!1}),m=g.useRef(null),n=!!(s&&(u==="active"||u==="waiting"));g.useEffect(()=>{if(!n||!s){l({segments:[],isStreaming:!1,done:!1});return}const d=location.protocol==="https:"?"wss:":"ws:",r=new WebSocket(`${d}//${location.host}/ws`);return m.current=r,r.onopen=()=>{r.send(JSON.stringify({type:"subscribe_session",sessionId:s}))},r.onmessage=S=>{try{const i=JSON.parse(S.data);if(i.type==="stream_resume"){let j=[];if(Array.isArray(i.segments)&&i.segments.length>0)j=i.segments;else{const p=i.reasoningContent??"",N=i.content??"";p&&j.push({type:"reasoning_text",content:p}),N&&j.push({type:"text",content:N})}l({segments:j,isStreaming:!i.done,done:!!i.done})}else i.type==="stream"?i.done?l(j=>({...j,isStreaming:!1,done:!0})):l(j=>{const p=[...j.segments],N=(k,w)=>{const C=p[p.length-1];C&&C.type===k?p[p.length-1]={type:k,content:C.content+w}:p.push({type:k,content:w})};return i.reasoningDelta&&N("reasoning_text",i.reasoningDelta),i.contentDelta&&N("text",i.contentDelta),{...j,segments:p,isStreaming:!0}}):i.type==="tool_call"?l(j=>{const p=[...j.segments];if(i.toolPhase==="start")p.push({type:"tool_call",name:i.toolName,args:i.toolArgs??{},startTime:Date.now()});else if(i.toolPhase==="end"&&i.toolResult!==void 0){const N=p.findLastIndex(k=>k.type==="tool_call"&&k.name===i.toolName&&k.result==null);if(N>=0){const k=p[N];p[N]={...k,result:i.toolResult,endTime:Date.now()}}}return{...j,segments:p,isStreaming:!0}}):i.type==="message"&&l(j=>({...j,done:!0,isStreaming:!1}))}catch{}},r.onclose=()=>{m.current=null},()=>{r.close(),m.current=null}},[s,n]);const y=g.useCallback(()=>{l({segments:[],isStreaming:!1,done:!1})},[]);return[h,y]}const V={active:"进行中",waiting:"等待中",completed:"已完成",error:"错误",archived:"已归档"},H={active:"#4caf50",waiting:"#ff9800",completed:"#2196f3",error:"#f44336",archived:"#888"};function U(s,u){return s?s.length>u?s.slice(0,u)+"…":s:""}function F(s){return new Date(s).toLocaleString("zh-CN",{month:"numeric",day:"numeric",hour:"2-digit",minute:"2-digit"})}function X(s){const u=[];for(const h of s)u.push(h.session.id),u.push(...X(h.children));return u}function ge(s,u){const h={...s};for(const l of Object.keys(u))h[l]===void 0&&(h[l]=null);return h}function pe({config:s,inheritedConfig:u,options:h,onSave:l,onCancel:m}){var P,I;const[n,y]=g.useState({...s}),d=u||{},r=(t,x)=>{y(v=>({...v,[t]:x}))},S=(t,x)=>!!t&&(t.includes("*")||t.includes(x)),i=t=>t.includes("*")?((h==null?void 0:h.toolGroups)??[]).map(x=>x.name):t,j=t=>S(n.enabledToolGroups,t)?"explicit":S(d.enabledToolGroups,t)&&!n.enabledToolGroups?"inherited":"off",p=t=>{if(j(t)==="inherited"){const v=i(d.enabledToolGroups||[]);r("enabledToolGroups",v.filter(T=>T!==t))}else{const v=i(n.enabledToolGroups||d.enabledToolGroups||[]),T=v.includes(t)?v.filter(E=>E!==t):[...v,t];r("enabledToolGroups",T)}},N=()=>{y(t=>{const{enabledToolGroups:x,...v}=t;return v})};if(!h)return e.jsx("div",{className:"session-config-editor",children:e.jsx("span",{className:"session-config-loading",children:"加载配置选项…"})});const k=(t,x)=>!n[t]&&x?` (继承: ${x})`:"",w=(P=n.llm)!=null&&P.provider&&((I=n.llm)!=null&&I.model)?`${n.llm.provider}/${n.llm.model}`:"",C=h.models.filter(t=>!!t.provider).map(t=>({key:`${t.provider}/${t.id}`,provider:t.provider,model:t.id,label:`${t.provider} / ${t.id}${t.capabilities.length>0?` [${t.capabilities.join(",")}]`:""}`}));w&&!C.some(t=>t.key===w)&&C.unshift({key:w,provider:n.llm.provider,model:n.llm.model,label:`${n.llm.provider} / ${n.llm.model} (已离线)`});const f=d.llm?`${d.llm.provider} / ${d.llm.model}`:void 0;return e.jsxs("div",{className:"session-config-editor",onClick:t=>t.stopPropagation(),children:[e.jsxs("label",{className:"session-config-field",children:[e.jsxs("span",{children:["模型",!n.llm&&f?` (继承: ${f})`:""]}),e.jsxs("select",{value:w,onChange:t=>{const x=t.target.value;if(!x){r("llm",void 0);return}const v=C.find(T=>T.key===x);v&&r("llm",{provider:v.provider,model:v.model})},children:[e.jsx("option",{value:"",children:f?`继承 (${f})`:"继承默认"}),C.map(t=>e.jsx("option",{value:t.key,children:t.label},t.key))]})]}),e.jsxs("label",{className:"session-config-field",children:[e.jsxs("span",{children:["人设",k("persona",d.persona)]}),e.jsxs("select",{value:n.persona||"",onChange:t=>r("persona",t.target.value||void 0),children:[e.jsx("option",{value:"",children:d.persona?`继承 (${d.persona})`:"继承默认"}),h.personas.map(t=>e.jsx("option",{value:t,children:t},t))]})]}),h.toolGroups.length>0&&e.jsxs("div",{className:"session-config-field",children:[e.jsxs("span",{children:["工具分组",n.enabledToolGroups?"":" (继承)"]}),e.jsxs("div",{className:"session-config-chips",children:[h.toolGroups.map(t=>{const x=j(t.name);return e.jsx("button",{className:`session-config-chip ${x==="explicit"?"active":x==="inherited"?"active inherited":""}`,onClick:()=>p(t.name),title:`${t.name}${x==="inherited"?" (继承)":x==="explicit"?" (已覆盖)":""}`,children:t.label||t.name},t.name)}),n.enabledToolGroups&&e.jsx("button",{className:"session-config-chip reset",onClick:N,title:"恢复为继承",children:"↺ 重置"})]})]}),e.jsxs("label",{className:"session-config-field",children:[e.jsx("span",{children:"额外提示"}),e.jsx("textarea",{rows:2,value:n.systemPromptExtra||"",onChange:t=>r("systemPromptExtra",t.target.value||void 0),placeholder:"追加到系统提示之后…"})]}),e.jsxs("label",{className:"session-config-field",children:[e.jsx("span",{children:"工具迭代上限"}),e.jsx("input",{type:"number",min:0,max:50,value:n.maxToolIterations??"",onChange:t=>r("maxToolIterations",t.target.value?Number(t.target.value):void 0),placeholder:d.maxToolIterations?`继承 (${d.maxToolIterations})`:"默认"})]}),e.jsxs("div",{className:"session-config-toggles",children:[e.jsxs("label",{children:[e.jsx("input",{type:"checkbox",checked:n.disableOutputFormat??d.disableOutputFormat??!1,onChange:t=>r("disableOutputFormat",t.target.checked)}),e.jsxs("span",{children:["禁用结构化输出",n.disableOutputFormat===void 0&&d.disableOutputFormat?" (继承)":""]})]}),e.jsxs("label",{children:[e.jsx("input",{type:"checkbox",checked:n.clientSideJsonRendering??d.clientSideJsonRendering??!1,onChange:t=>r("clientSideJsonRendering",t.target.checked)}),e.jsxs("span",{children:["客户端 JSON 渲染",n.clientSideJsonRendering===void 0&&d.clientSideJsonRendering?" (继承)":""]})]})]}),e.jsxs("div",{className:"session-config-actions",children:[e.jsx("button",{className:"session-config-btn save",onClick:()=>l(ge(n,s)),children:"保存"}),e.jsx("button",{className:"session-config-btn cancel",onClick:m,children:"取消"})]})]})}function Ce({pluginName:s,activeSessionId:u,onSwitchSession:h,onStartNewChat:l,refreshSignal:m}){const[n,y]=g.useState([]),[d,r]=g.useState(null),[S,i]=g.useState(null),[j,p]=g.useState(!1),[N,k]=g.useState(null),[w,C]=g.useState(!1),[f,P]=g.useState(new Set),[I,t]=g.useState(null),[x,v]=g.useState(""),[T,E]=g.useState(null),[c,G]=g.useState(null),[A,J]=g.useState(null),[M,L]=g.useState(null),o=g.useCallback(()=>{D(s,"getSessionTree").then(a=>{Array.isArray(a)&&y(a)}).catch(()=>k("无法加载会话树"))},[s]);g.useEffect(()=>{o();const a=setInterval(o,3e4);return()=>clearInterval(a)},[o]),g.useEffect(()=>{m&&(o(),c&&D(s,"getInheritedDefaults",{sessionId:c,platform:"webui"}).then(a=>{a&&L(a)}).catch(()=>{}))},[m]);const W=g.useCallback(a=>{r(a),p(!0),D(s,"getSessionDetail",{id:a}).then(b=>i(b)).catch(()=>i(null)).finally(()=>p(!1))},[s]),Q=async()=>{try{await D(s,"createSession",{}),o()}catch{}},Z=async a=>{try{await D(s,"createSession",{parentId:a}),o()}catch{}},ee=async a=>{if(!x.trim()){t(null);return}try{await D(s,"renameSession",{id:a,title:x.trim()}),o()}catch{}t(null)},se=async a=>{try{await D(s,"archiveSession",{id:a}),o()}catch(b){alert(`归档会话失败:${b instanceof Error?b.message:String(b)}`)}},te=async a=>{try{const b=a===u;await D(s,"deleteSession",{id:a}),o(),d===a&&(r(null),i(null)),b&&l&&l()}catch{}E(null)},ne=async a=>{if(c===a){G(null),L(null);return}G(a),L(null);try{const[b,$]=await Promise.all([A?Promise.resolve(A):D(s,"getConfigOptions"),D(s,"getInheritedDefaults",{sessionId:a,platform:"webui"})]);b&&!A&&J(b),$&&L($)}catch{}},le=async(a,b)=>{try{await D(s,"updateSessionConfig",{id:a,config:b}),o(),G(null)}catch($){const he=$ instanceof Error?$.message:String($);alert(`保存会话配置失败:${he}`)}},ie=a=>{P(b=>{const $=new Set(b);return $.has(a)?$.delete(a):$.add(a),$})},ae=()=>{const a=X(n);P(new Set(a))},re=()=>P(new Set),ce=async()=>{if(f.size!==0)try{await D(s,"batchArchive",{ids:[...f]}),P(new Set),o()}catch{}},oe=async()=>{if(f.size!==0&&confirm(`确认删除选中的 ${f.size} 个会话?此操作不可恢复。`))try{await D(s,"batchDelete",{ids:[...f]}),P(new Set),d&&f.has(d)&&(r(null),i(null)),o()}catch{}},de=()=>{C(!1),P(new Set)};return N?e.jsx("div",{className:"tree-page-error",children:N}):e.jsxs("div",{className:"session-tree-page",children:[e.jsxs("div",{className:"tree-visual-panel",children:[e.jsxs("div",{className:"tree-visual-header",children:[e.jsx("h3",{children:"会话"}),e.jsx("div",{className:"tree-header-actions",children:w?e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"tree-batch-btn",onClick:ae,title:"全选",children:"全选"}),e.jsx("button",{className:"tree-batch-btn",onClick:re,title:"取消全选",children:"取消"}),e.jsxs("button",{className:"tree-batch-btn archive",onClick:ce,disabled:f.size===0,children:["归档 (",f.size,")"]}),e.jsxs("button",{className:"tree-batch-btn danger",onClick:oe,disabled:f.size===0,children:["删除 (",f.size,")"]}),e.jsx("button",{className:"tree-batch-btn",onClick:de,children:"退出批量"})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"tree-action-btn",onClick:Q,title:"新建会话",children:"+"}),e.jsx("button",{className:"tree-action-btn",onClick:()=>C(!0),title:"批量管理",children:"☐"}),e.jsx("button",{className:"tree-refresh-btn",onClick:o,children:"⟳"})]})})]}),e.jsx("div",{className:"tree-visual-body",children:n.length===0?e.jsx("div",{className:"tree-empty",children:"暂无会话"}):n.map(a=>e.jsx(Y,{node:a,selectedId:d,activeSessionId:u,onSelect:W,depth:0,batchMode:w,selected:f,onToggleSelect:ie,onCreateChild:Z,onRename:(b,$)=>{t(b),v($)},onArchive:se,onDelete:b=>E(b),onOpenConfig:ne,editingId:I,editTitle:x,onEditTitleChange:v,onCommitRename:ee,onCancelEdit:()=>t(null),configEditingId:c,configOptions:A,inheritedConfig:M,onSaveConfig:le,onCancelConfig:()=>G(null)},a.session.id))})]}),e.jsx("div",{className:"tree-detail-panel",children:d?j?e.jsx("div",{className:"tree-detail-placeholder",children:"加载中…"}):S?e.jsx(je,{detail:S,onSwitchSession:h,onRefresh:()=>W(S.session.id)}):e.jsx("div",{className:"tree-detail-placeholder",children:"无法加载会话信息"}):e.jsx("div",{className:"tree-detail-placeholder tree-detail-placeholder-idle",children:"点击会话节点查看详情"})}),T&&e.jsx("div",{className:"delete-confirm-overlay",onClick:()=>E(null),children:e.jsxs("div",{className:"delete-confirm-dialog",onClick:a=>a.stopPropagation(),children:[e.jsx("p",{children:"确定要删除此会话吗?子会话也会被一并删除,此操作无法撤销。"}),e.jsxs("div",{className:"delete-confirm-actions",children:[e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>te(T),children:"删除"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>E(null),children:"取消"})]})]})})]})}function Y({node:s,selectedId:u,activeSessionId:h,onSelect:l,depth:m,batchMode:n,selected:y,onToggleSelect:d,onCreateChild:r,onRename:S,onArchive:i,onDelete:j,onOpenConfig:p,editingId:N,editTitle:k,onEditTitleChange:w,onCommitRename:C,onCancelEdit:f,configEditingId:P,configOptions:I,inheritedConfig:t,onSaveConfig:x,onCancelConfig:v}){const[T,E]=g.useState(!0),c=s.session,G=s.children.length>0,A=c.id===u,J=c.id===h,M=N===c.id,L=y.has(c.id);return e.jsxs("div",{className:"tree-node-group",children:[e.jsxs("div",{className:`tree-node ${A?"selected":""} ${J?"active-chat":""} status-${c.status}`,style:{marginLeft:m*24},onClick:()=>n?d(c.id):l(c.id),children:[n&&e.jsx("input",{type:"checkbox",className:"tree-node-checkbox",checked:L,onChange:()=>d(c.id),onClick:o=>o.stopPropagation()}),e.jsx("button",{className:"tree-node-toggle",onClick:o=>{o.stopPropagation(),E(!T)},style:{visibility:G?"visible":"hidden"},children:T?"▾":"▸"}),e.jsx("span",{className:"tree-node-status",style:{background:H[c.status]||"#888"}}),e.jsx("div",{className:"tree-node-info",children:M?e.jsx("input",{className:"tree-node-rename-input",value:k,onChange:o=>w(o.target.value),onBlur:()=>C(c.id),onKeyDown:o=>{o.key==="Enter"&&C(c.id),o.key==="Escape"&&f()},onClick:o=>o.stopPropagation(),autoFocus:!0}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"tree-node-title",children:c.title||c.name}),e.jsxs("span",{className:"tree-node-meta",children:[V[c.status]||c.status,c.createdBy&&c.createdBy!=="user"&&` · ${c.createdBy}`,` · ${F(c.createdAt)}`]})]})}),G&&e.jsx("span",{className:"tree-node-badge",children:s.children.length}),!n&&e.jsxs("div",{className:"tree-node-actions",onClick:o=>o.stopPropagation(),children:[e.jsx("button",{className:"tree-node-action-btn",title:"新建子会话",onClick:()=>r(c.id),children:"➕"}),e.jsx("button",{className:"tree-node-action-btn",title:"配置",onClick:()=>p(c.id),children:"⚙"}),e.jsx("button",{className:"tree-node-action-btn",title:"重命名",onClick:()=>S(c.id,c.title||c.name),children:"✎"}),c.status==="active"&&e.jsx("button",{className:"tree-node-action-btn",title:"归档",onClick:()=>i(c.id),children:"▪"}),e.jsx("button",{className:"tree-node-action-btn danger",title:"删除",onClick:()=>j(c.id),children:"✕"})]})]}),P===c.id&&e.jsx("div",{style:{marginLeft:m*24+24},children:e.jsx(pe,{config:c.config||{},inheritedConfig:t,options:I,onSave:o=>x(c.id,o),onCancel:v})}),G&&T&&e.jsx("div",{className:"tree-node-children",children:s.children.map(o=>e.jsxs("div",{className:"tree-child-wrapper",children:[o.session.inputContext&&e.jsxs("div",{className:"tree-flow-label",style:{marginLeft:(m+1)*24},children:[e.jsx("span",{className:"tree-flow-arrow",children:"↓"}),e.jsx("span",{className:"tree-flow-text",children:U(o.session.inputContext,80)})]}),e.jsx(Y,{node:o,selectedId:u,activeSessionId:h,onSelect:l,depth:m+1,batchMode:n,selected:y,onToggleSelect:d,onCreateChild:r,onRename:S,onArchive:i,onDelete:j,onOpenConfig:p,editingId:N,editTitle:k,onEditTitleChange:w,onCommitRename:C,onCancelEdit:f,configEditingId:P,configOptions:I,inheritedConfig:t,onSaveConfig:x,onCancelConfig:v}),o.session.result&&e.jsxs("div",{className:"tree-flow-label result",style:{marginLeft:(m+1)*24},children:[e.jsx("span",{className:"tree-flow-arrow",children:"↑"}),e.jsx("span",{className:"tree-flow-text",children:U(o.session.result,80)})]})]},o.session.id))})]})}function je({detail:s,onSwitchSession:u,onRefresh:h}){const l=s.session,m=me(s.messages),[n,y]=xe(l.id,l.status);return g.useEffect(()=>{n.done&&(y(),h==null||h())},[n.done,y,h]),e.jsxs("div",{className:"session-detail",children:[e.jsxs("div",{className:"session-detail-header",children:[e.jsx("h3",{children:l.title||l.name}),e.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[u&&e.jsx("button",{className:"btn btn-sm btn-primary",onClick:()=>u(l.id),children:"进入对话"}),e.jsx("span",{className:"session-detail-status",style:{color:H[l.status]},children:V[l.status]})]})]}),e.jsxs("div",{className:"session-detail-meta",children:[e.jsxs("div",{children:[e.jsx("strong",{children:"ID:"})," ",l.id]}),e.jsxs("div",{children:[e.jsx("strong",{children:"创建时间:"})," ",new Date(l.createdAt).toLocaleString("zh-CN")]}),l.parentId&&e.jsxs("div",{children:[e.jsx("strong",{children:"父会话:"})," ",l.parentId]}),l.createdBy&&e.jsxs("div",{children:[e.jsx("strong",{children:"创建者:"})," ",l.createdBy]}),l.children.length>0&&e.jsxs("div",{children:[e.jsx("strong",{children:"子会话数:"})," ",l.children.length]})]}),l.inputContext&&e.jsxs("div",{className:"session-detail-context",children:[e.jsx("div",{className:"context-label",children:"来自父会话的指令"}),e.jsx("div",{className:"context-content",children:l.inputContext})]}),l.result&&e.jsxs("div",{className:"session-detail-result",children:[e.jsx("div",{className:"context-label",children:"给父会话的结果"}),e.jsx("div",{className:"context-content",children:l.result})]}),e.jsxs("div",{className:"session-detail-messages",children:[e.jsxs("h4",{children:["消息记录 (",s.messages.length,")"]}),m.length===0&&!n.isStreaming?e.jsx("div",{className:"no-messages",children:"暂无消息记录"}):e.jsxs("div",{className:"message-list",children:[m.map((d,r)=>e.jsx(fe,{msg:d},r)),n.isStreaming&&n.segments.length>0&&e.jsxs("div",{className:"detail-message assistant streaming",children:[e.jsxs("div",{className:"detail-msg-role",children:["助手 ",e.jsx("span",{className:"streaming-indicator",children:"●"})]}),e.jsx("div",{className:"detail-msg-content detail-msg-md",children:(()=>{const d=[];let r=0;for(;r<n.segments.length;){const S=n.segments[r];if(S.type==="reasoning_text"){let i="";for(;r<n.segments.length&&n.segments[r].type==="reasoning_text";)i+=n.segments[r].content,r++;i&&d.push(e.jsxs("details",{className:"thinking-block",open:!0,children:[e.jsxs("summary",{className:"thinking-summary",children:[e.jsx(K,{size:14})," 思考过程"]}),e.jsx("div",{className:"thinking-content",children:e.jsx(R,{remarkPlugins:z,rehypePlugins:_,components:O,children:B(i)})})]},`r-${r}`));continue}d.push(e.jsx(q,{seg:S},r)),r++}return d})()})]})]})]})]})}function q({seg:s}){return s.type==="text"||s.type==="reasoning_text"?s.content?e.jsx("div",{className:"detail-text-segment",children:e.jsx(R,{remarkPlugins:z,rehypePlugins:_,components:O,children:B(s.content)})}):null:e.jsxs("details",{className:"tool-call-block",children:[e.jsxs("summary",{className:"tool-call-summary",children:[e.jsx(ue,{size:14})," ",s.name,s.result==null?" …":""]}),e.jsxs("div",{className:"tool-call-content",children:[e.jsxs("div",{className:"tool-call-args",children:[e.jsx("strong",{children:"参数"}),e.jsx("pre",{children:JSON.stringify(s.args,null,2)})]}),s.result!=null&&e.jsxs("div",{className:"tool-call-result",children:[e.jsx("strong",{children:"结果"}),e.jsx("pre",{children:s.result})]})]})]})}function fe({msg:s}){const u=s.role==="user"?"用户":"助手";if(s.role==="user")return e.jsxs("div",{className:`detail-message ${s.role}`,children:[e.jsx("div",{className:"detail-msg-role",children:u}),e.jsx("div",{className:"detail-msg-content",children:s.content}),s.timestamp>0&&e.jsx("div",{className:"detail-msg-time",children:F(s.timestamp)})]});if(s.role==="assistant"&&s.segments&&s.segments.length>0){const l=[];let m=0;for(;m<s.segments.length;){const n=s.segments[m];if(n.type==="reasoning_text"){let y="";for(;m<s.segments.length&&s.segments[m].type==="reasoning_text";)y+=s.segments[m].content,m++;y&&l.push(e.jsxs("details",{className:"thinking-block",children:[e.jsxs("summary",{className:"thinking-summary",children:[e.jsx(K,{size:14})," 思考过程"]}),e.jsx("div",{className:"thinking-content",children:e.jsx(R,{remarkPlugins:z,rehypePlugins:_,components:O,children:B(y)})})]},`r-${m}`));continue}l.push(e.jsx(q,{seg:n},m)),m++}return e.jsxs("div",{className:`detail-message ${s.role}`,children:[e.jsx("div",{className:"detail-msg-role",children:u}),e.jsx("div",{className:"detail-msg-content detail-msg-md",children:l}),s.timestamp>0&&e.jsx("div",{className:"detail-msg-time",children:F(s.timestamp)})]})}const h=s.role==="assistant"&&s.reasoningContent?e.jsxs("details",{className:"thinking-block",children:[e.jsxs("summary",{className:"thinking-summary",children:[e.jsx(K,{size:14})," 思考过程"]}),e.jsx("div",{className:"thinking-content",children:e.jsx(R,{remarkPlugins:z,rehypePlugins:_,components:O,children:B(s.reasoningContent)})})]}):null;return e.jsxs("div",{className:`detail-message ${s.role}`,children:[e.jsx("div",{className:"detail-msg-role",children:u}),h,e.jsx("div",{className:"detail-msg-content detail-msg-md",children:e.jsx(R,{remarkPlugins:z,rehypePlugins:_,components:O,children:B(s.content)})}),s.timestamp>0&&e.jsx("div",{className:"detail-msg-time",children:F(s.timestamp)})]})}export{Ce as SessionsPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a0 as ln,a1 as an,a2 as H,a3 as q,a4 as B,a5 as un,a6 as y,a7 as tn,a8 as L,a9 as _,aa as rn,ab as o,ac as on,ad as sn,ae as fn}from"./mermaid.core-
|
|
1
|
+
import{a0 as ln,a1 as an,a2 as H,a3 as q,a4 as B,a5 as un,a6 as y,a7 as tn,a8 as L,a9 as _,aa as rn,ab as o,ac as on,ad as sn,ae as fn}from"./mermaid.core-CiVUCO-O.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,C,a){var O=I-l,i=D-h,n=C-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*L(on(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,F=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<an)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(fn((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|