@xiaobuyu/nodesign 0.0.2 → 0.0.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.
Files changed (109) hide show
  1. package/package.json +1 -1
  2. package/server/api/assets/helpers.js +20 -0
  3. package/server/api/assets/notes.js +50 -0
  4. package/server/api/assets.js +6 -11
  5. package/server/api/board.js +78 -1
  6. package/server/engine/agent/events.js +1 -0
  7. package/server/engine/agent/hooks/user-prompt-submit.js +43 -0
  8. package/server/engine/agent/prompts/nodesign-prelude.md +53 -1
  9. package/server/engine/agent/session-loop.js +11 -0
  10. package/server/engine/mcp/index.js +12 -0
  11. package/server/engine/mcp/tools/arrange-on-board.js +4 -4
  12. package/server/engine/mcp/tools/create-on-board.js +9 -12
  13. package/server/engine/mcp/tools/edit-sketch.js +167 -0
  14. package/server/engine/mcp/tools/look-at-board.js +124 -0
  15. package/server/engine/mcp/tools/read-board.js +121 -34
  16. package/server/engine/mcp/tools/read-user-view.js +59 -0
  17. package/server/engine/mcp/tools/relate-on-board.js +5 -3
  18. package/server/engine/mcp/tools/sketch-on-board.js +337 -0
  19. package/server/engine/mcp/tools/write-on-board.js +130 -0
  20. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/SKILL.md +7 -0
  21. package/server/engine/plugins/nodesign/skills/docx-craft/SKILL.md +7 -0
  22. package/server/engine/plugins/nodesign/skills/rp-craft/SKILL.md +7 -0
  23. package/server/engine/plugins/nodesign/skills/site-craft/SKILL.md +7 -0
  24. package/server/engine/runs/board-tasklist.js +130 -0
  25. package/server/index.js +3 -0
  26. package/server/lib/binding-types.js +12 -0
  27. package/server/lib/board-graph-export.js +191 -0
  28. package/server/lib/board-groups.js +167 -0
  29. package/server/lib/board-hero.js +76 -0
  30. package/server/lib/board-kind-sizes.js +23 -0
  31. package/server/lib/board-relations.js +1 -1
  32. package/server/lib/chalk.js +121 -0
  33. package/server/lib/sketch-layout.js +277 -0
  34. package/server/projects/board-limits.js +12 -0
  35. package/server/projects/board-sanitize.js +252 -0
  36. package/server/projects/board-store.js +72 -205
  37. package/server/projects/ui-config.js +6 -0
  38. package/server/projects/viewpoint-store.js +78 -0
  39. package/server/ws/broker.js +3 -0
  40. package/web/dist/assets/{BrowserWindow-BYCgizHw.js → BrowserWindow-P_vIdh-G.js} +2 -2
  41. package/web/dist/assets/{DeckWindow-pNydEM4L.js → DeckWindow-BpLv5082.js} +3 -3
  42. package/web/dist/assets/{DocxWindow-PPgzh3Gq.js → DocxWindow-DSAU1-tD.js} +4 -4
  43. package/web/dist/assets/MermaidBlock-DR1GikCv.js +313 -0
  44. package/web/dist/assets/SiteWindow-92uBuRRR.js +18 -0
  45. package/web/dist/assets/abnfDiagram-VCTEODGH-uA8Esix4.js +1 -0
  46. package/web/dist/assets/arc-D_khH_xN.js +1 -0
  47. package/web/dist/assets/architectureDiagram-5GKGNRK7-DydJHqOt.js +36 -0
  48. package/web/dist/assets/blockDiagram-NRAW4CY4-B7wBbKiW.js +129 -0
  49. package/web/dist/assets/c4Diagram-UCG6FXSJ-6mrH0x7Y.js +38 -0
  50. package/web/dist/assets/channel-DGkccMO1.js +1 -0
  51. package/web/dist/assets/chunk-2Q5K7J3B-Cuikho5Q.js +1 -0
  52. package/web/dist/assets/chunk-5VM5RSS4-3-KZ5AUz.js +15 -0
  53. package/web/dist/assets/chunk-F27PBJKO-Bkwq2gGU.js +1 -0
  54. package/web/dist/assets/chunk-G27WJ6UU-BLyQzdGE.js +231 -0
  55. package/web/dist/assets/chunk-JWPE2WC7-B7HxxQds.js +1 -0
  56. package/web/dist/assets/chunk-LCL6LL3I-CtXrnUwF.js +206 -0
  57. package/web/dist/assets/chunk-POPQ4Y6H-dxddZlXt.js +1 -0
  58. package/web/dist/assets/chunk-SVP7TREG-DpkmrgHn.js +88 -0
  59. package/web/dist/assets/chunk-XXDRQBXY-BwZ7RbpQ.js +1 -0
  60. package/web/dist/assets/classDiagram-DTDB5LWJ-BGscw3OD.js +1 -0
  61. package/web/dist/assets/classDiagram-v2-JRS7N3AN-BGscw3OD.js +1 -0
  62. package/web/dist/assets/cose-bilkent-JH36ORCC-DGFOsMUt.js +1 -0
  63. package/web/dist/assets/cynefin-OW5HDTMX-DUwn3ehS.js +178 -0
  64. package/web/dist/assets/cynefinDiagram-5FMLGOSQ-DlLAOZ9x.js +62 -0
  65. package/web/dist/assets/cytoscape.esm-BjAbmLdb.js +331 -0
  66. package/web/dist/assets/dagre-3AP2YEHR-CyourLfz.js +4 -0
  67. package/web/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  68. package/web/dist/assets/diagram-S7CK7UJ4-BTMbx2np.js +30 -0
  69. package/web/dist/assets/diagram-UQ7AKVKN-UK94_1-P.js +41 -0
  70. package/web/dist/assets/diagram-VSXAHHWV-C7zS-v9v.js +3 -0
  71. package/web/dist/assets/diagram-VX7I27RA-DKJRa6CK.js +24 -0
  72. package/web/dist/assets/diagram-Z3DM3KII-kUbAfGAp.js +24 -0
  73. package/web/dist/assets/ebnfDiagram-PWID7BFC-CVW16_vb.js +1 -0
  74. package/web/dist/assets/erDiagram-SSCWMZ5O-BRQMFQ5y.js +99 -0
  75. package/web/dist/assets/flowDiagram-A5DVABFB-S34LpLtK.js +168 -0
  76. package/web/dist/assets/ganttDiagram-EL5Y4UJY-BFiqk1-G.js +292 -0
  77. package/web/dist/assets/gitGraphDiagram-WWUBYQGX-LZsrdyyv.js +106 -0
  78. package/web/dist/assets/index-GAamh1p4.js +2152 -0
  79. package/web/dist/assets/infoDiagram-RXCK75RN-0DvN6KIp.js +2 -0
  80. package/web/dist/assets/init-Gi6I4Gst.js +1 -0
  81. package/web/dist/assets/ishikawaDiagram-5VMMS53U-CaY3A-Bx.js +70 -0
  82. package/web/dist/assets/journeyDiagram-EYS64GPL-BBeiaCrj.js +139 -0
  83. package/web/dist/assets/kanban-definition-3QL26DDD-ux42DRXQ.js +89 -0
  84. package/web/dist/assets/layout-CnXiF_NB.js +1 -0
  85. package/web/dist/assets/linear-BMW0u6G6.js +1 -0
  86. package/web/dist/assets/mindmap-definition-FBJOCRG2-hUxSpdKn.js +96 -0
  87. package/web/dist/assets/ordinal-Cboi1Yqb.js +1 -0
  88. package/web/dist/assets/pegDiagram-XKGWAZYB-aCaQPH0w.js +1 -0
  89. package/web/dist/assets/{pending-edit-apply-C0I13CbD.js → pending-edit-apply-AcdOQ9Ij.js} +6 -6
  90. package/web/dist/assets/pieDiagram-E7YTZNPT-CmOEZ8zg.js +39 -0
  91. package/web/dist/assets/quadrantDiagram-AXDQQJYC-VW6fAhsV.js +7 -0
  92. package/web/dist/assets/railroadDiagram-O6MQD6OU-CKJ7Ba5K.js +1 -0
  93. package/web/dist/assets/requirementDiagram-EFPCY7ZU-pNGkq9Vw.js +84 -0
  94. package/web/dist/assets/{rotate-cw-B1UQ8Hld.js → rotate-cw-KAfChbGV.js} +1 -1
  95. package/web/dist/assets/sankeyDiagram-P5KCCOFB-BIMmDTfZ.js +40 -0
  96. package/web/dist/assets/sequenceDiagram-WJ2MYXX4-BBW7wzKY.js +162 -0
  97. package/web/dist/assets/sizeCapture-X5ZJPWSS-DdkXmLYR.js +1 -0
  98. package/web/dist/assets/{square-dashed-mouse-pointer-8lrgqmfv.js → square-dashed-mouse-pointer-CDUlhUP7.js} +1 -1
  99. package/web/dist/assets/stateDiagram-HBIQ2CUA-W313Uz16.js +1 -0
  100. package/web/dist/assets/stateDiagram-v2-4QOOHH4V-DDhJBZzf.js +1 -0
  101. package/web/dist/assets/swimlanes-XN3QIQJK-C29TL26K.js +1 -0
  102. package/web/dist/assets/swimlanesDiagram-VK2B7HYN-BfN-Xdmu.js +8 -0
  103. package/web/dist/assets/timeline-definition-24CTP7MA-CF0JMObX.js +120 -0
  104. package/web/dist/assets/vennDiagram-4TSXK5OY-DrDFsaH3.js +34 -0
  105. package/web/dist/assets/wardleyDiagram-VM6X3IG4-CVrnRIS_.js +78 -0
  106. package/web/dist/assets/xychartDiagram-S5SC5T6Z-BvkN1zsT.js +7 -0
  107. package/web/dist/index.html +1 -1
  108. package/web/dist/assets/SiteWindow-DM0LQPCO.js +0 -18
  109. package/web/dist/assets/index-BHTBJlpY.js +0 -2125
@@ -1,4 +1,4 @@
1
- import{c as et,r as o,j as e,C as r,G as t,a as Ht,R as $,F as p,b as E,P as tt,u as N,X as ue,d as nt,e as z,f as st,T as Dt,g as _t,h as ke,B as It,i as rt,k as ze,U as Nt,l as it,S as qt,H as Ut,m as Gt,n as lt,o as Kt,p as Vt,q as Xt,s as ot,t as at,v as dt,w as Yt,x as Zt,y as ct,z as Ct,A as Jt,E as ut,D as Qt,I as en,J as Ke,K as tn,M as nn,L as sn,N as rn,O as ln,Q as on,V as an,W as dn,Y as cn,Z as un}from"./index-BHTBJlpY.js";import{d as Ve,a as Xe,M as xn,o as pn,t as gn,E as fn,C as hn,G as mn,p as yn,D as bn,b as wn,c as vn,P as kn,I as jn,R as Sn,e as zn}from"./pending-edit-apply-C0I13CbD.js";import{E as $n,S as En}from"./square-dashed-mouse-pointer-8lrgqmfv.js";/**
1
+ import{c as et,r as o,j as e,d as r,G as t,_ as Ht,R as $,F as p,a as E,$ as tt,u as q,X as ue,w as nt,e as z,a0 as st,a1 as _t,a2 as Dt,a3 as ke,a4 as It,a5 as rt,P as ze,a6 as qt,a7 as it,a8 as Nt,a9 as Ut,aa as Gt,ab as lt,ac as Xt,ad as Kt,ae as Vt,m as ot,af as at,o as dt,ag as Yt,k as Zt,ah as ct,ai as Ct,S as Qt,aj as ut,ak as Jt,al as en,am as Xe,an as tn,Q as nn,ao as sn,ap as rn,aq as ln,M as on,ar as an,as as dn,n as cn,A as un}from"./index-GAamh1p4.js";import{d as Ke,c as Ve,M as xn,o as pn,t as gn,E as fn,C as hn,G as mn,p as yn,D as bn,b as wn,a as vn,P as kn,I as jn,R as Sn,e as zn}from"./pending-edit-apply-AcdOQ9Ij.js";import{E as $n,S as En}from"./square-dashed-mouse-pointer-CDUlhUP7.js";/**
2
2
  * @license lucide-react v0.468.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -8,9 +8,9 @@ import{c as et,r as o,j as e,C as r,G as t,a as Ht,R as $,F as p,b as E,P as tt,
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 Ln=et("ShieldCheck",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]),Fn=1920,An=1080;function Tn({src:n,srcDoc:s,mode:i="edit",onSelect:l,onTextEdit:d,onIframeReady:f,zoom:m=1,deckW:c=Fn,deckH:y=An}){const u=o.useRef(null),a=o.useRef(!1),w=o.useRef(0),[x,v]=o.useState(!1);o.useEffect(()=>{v(!0)},[n,s]),o.useEffect(()=>{const b=u.current;if(!(!b||!a.current))return Ve(b),i==="edit"&&Xe(b,{onSelect:l,onTextEdit:d}),()=>Ve(b)},[i,l,d]),o.useEffect(()=>()=>{var b;try{const F=(b=u.current)==null?void 0:b.contentWindow;F&&typeof F.scrollY=="number"&&(w.current=F.scrollY)}catch{}},[n,s]);const k=()=>{a.current=!0;const b=u.current;if(b){if(f==null||f(b),i==="edit"&&Xe(b,{onSelect:l,onTextEdit:d}),w.current>0)try{requestAnimationFrame(()=>{var F;try{(F=b.contentWindow)==null||F.scrollTo(0,w.current)}catch{}})}catch{}requestAnimationFrame(()=>{requestAnimationFrame(()=>v(!1))})}};return e.jsx("div",{style:{flex:1,minHeight:0,overflow:"hidden",background:r.bgWhite,position:"relative",display:"flex",alignItems:"center",justifyContent:"center"},children:e.jsx("iframe",{ref:u,src:n,srcDoc:s,onLoad:k,sandbox:"allow-scripts allow-same-origin",style:{width:`${c}px`,height:`${y}px`,flexShrink:0,border:0,background:r.bgWhite,transform:m===1?"none":`scale(${m})`,transformOrigin:"center center",opacity:x?.5:1,transition:"opacity 180ms ease-out"}})})}function Pn({candidates:n,activeId:s,onSelect:i,onAdd:l,onRemove:d,onRename:f}){if(!n||n.length===0)return null;const m=n.length===1;return e.jsxs("div",{style:{flexShrink:0,height:36,borderBottom:`1px solid ${r.border}`,background:r.bgWhite,padding:`0 ${t.lg}px`,display:"flex",alignItems:"center",gap:t.xs,overflowX:"auto",overflowY:"hidden"},children:[e.jsx(Ht,{size:11,color:r.sub,style:{flexShrink:0,marginRight:t.xs}}),n.map(c=>{const y=c.id===s;return e.jsx(Wn,{candidate:c,active:y,onSelect:()=>i==null?void 0:i(c.id),onRemove:m?null:()=>d==null?void 0:d(c.id),onRename:f},c.id)}),e.jsxs("button",{onClick:l,title:"新建候选(mock 复制当前)",style:{flexShrink:0,padding:`${t.xs}px ${t.md}px`,display:"inline-flex",alignItems:"center",gap:t.xs,fontFamily:E,fontSize:p.xs,color:r.sub,background:"transparent",border:`1px dashed ${r.borderMd}`,borderRadius:$.sm,cursor:"pointer"},onMouseEnter:c=>{c.currentTarget.style.color=r.text2,c.currentTarget.style.background="rgba(0,0,0,0.03)"},onMouseLeave:c=>{c.currentTarget.style.color=r.sub,c.currentTarget.style.background="transparent"},children:[e.jsx(tt,{size:11})," 新候选"]}),e.jsx("div",{style:{flex:1}}),e.jsxs("span",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,opacity:m?0:.7,flexShrink:0},children:[n.length," 个候选"]})]})}function Wn({candidate:n,active:s,onSelect:i,onRemove:l,onRename:d}){const[f,m]=o.useState(!1),c=N(w=>w.prompt),y=N(w=>w.confirm),u=async w=>{if(w.stopPropagation(),!d)return;const x=await c({title:"重命名候选",initialValue:n.label,placeholder:"候选名"});x&&x.trim()&&x!==n.label&&d(n.id,x.trim())},a=async w=>{w.stopPropagation(),await y({title:"删除候选",message:`删除候选「${n.label}」?`,confirmLabel:"删除",danger:!0})&&l()};return e.jsxs("div",{onMouseEnter:()=>m(!0),onMouseLeave:()=>m(!1),style:{flexShrink:0,position:"relative",display:"inline-flex",alignItems:"center",background:s?"rgba(45,36,24,0.06)":"transparent",borderRadius:$.sm,transition:"background 0.15s"},children:[e.jsx("button",{onClick:i,onDoubleClick:u,title:"双击重命名",style:{padding:`${t.xs}px ${l&&f?t.lg:t.md}px ${t.xs}px ${t.md}px`,fontFamily:E,fontSize:p.xs,fontWeight:s?500:400,color:s?r.text:r.text4,background:"transparent",borderRadius:$.sm,cursor:"pointer",transition:"all 0.15s"},children:n.label}),l&&f&&e.jsx("button",{onClick:a,style:{position:"absolute",right:2,top:"50%",transform:"translateY(-50%)",width:14,height:14,borderRadius:$.xs,background:"rgba(0,0,0,0.06)",color:r.sub,display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"},onMouseEnter:w=>{w.currentTarget.style.background="rgba(184,58,42,0.15)",w.currentTarget.style.color=r.error},onMouseLeave:w=>{w.currentTarget.style.background="rgba(0,0,0,0.06)",w.currentTarget.style.color=r.sub},title:"删除候选",children:e.jsx(ue,{size:9})})]})}const de=12,Bn=8;function $e(n,s){const[i,l]=o.useState(null);return o.useLayoutEffect(()=>{const d=n==null?void 0:n.current;if(!d){l(null);return}const f=()=>{const m=d.getBoundingClientRect();if(!m.width&&!m.height){l(null);return}const c=window.innerWidth,y=window.innerHeight,u=Math.max(de,Math.min(m.left,c-s-de)),a=Math.min(m.bottom+Bn,y-de-120);l({position:"fixed",left:u,top:a,maxHeight:y-a-de})};return f(),window.addEventListener("resize",f),()=>window.removeEventListener("resize",f)},[n,s]),i||{position:"absolute",top:78,right:16}}function Mn({anchorRef:n,onClose:s,iframeDoc:i}){const l=o.useRef(null),d=$e(n,320),[f,m]=o.useState(!1),[c,y]=o.useState(null);o.useEffect(()=>{i&&u()},[i]),o.useEffect(()=>{const a=w=>{var x;l.current&&!l.current.contains(w.target)&&!((x=n==null?void 0:n.current)!=null&&x.contains(w.target))&&(s==null||s())};return window.addEventListener("mousedown",a),()=>window.removeEventListener("mousedown",a)},[s,n]);const u=()=>{i&&(m(!0),setTimeout(()=>{y(On(i)),m(!1)},400))};return e.jsxs("div",{ref:l,style:{...d,width:320,background:r.bgWhite,borderRadius:2,boxShadow:"0 2px 4px rgba(0,0,0,0.04), 0 8px 20px rgba(0,0,0,0.08), 0 24px 48px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.8)",zIndex:60,overflow:"hidden"},children:[e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,display:"flex",alignItems:"center",justifyContent:"space-between",borderBottom:`1px solid ${r.borderLt}`},children:[e.jsx("span",{style:{fontFamily:E,fontSize:p.sm,fontWeight:500,color:r.text},children:"Accessibility Review"}),e.jsx("button",{onClick:u,disabled:f,style:{padding:t.xs,color:r.sub,borderRadius:$.xs,opacity:f?.5:1},title:"重新扫描",children:e.jsx(nt,{size:11,className:f?"spin":""})})]}),e.jsxs("div",{style:{padding:t.lg,maxHeight:360,overflowY:"auto"},children:[f&&e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.sub,textAlign:"center",padding:t.lg},children:"扫描中…"}),!f&&c&&e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.sm},children:c.map((a,w)=>e.jsx(Rn,{...a},w))})]}),e.jsx("div",{style:{padding:`${t.sm}px ${t.lg}px`,background:r.bgCard,borderTop:`1px solid ${r.borderLt}`,fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.5},children:"P5 接 LLM 真做 contrast / hierarchy / usability 审查;当前是启发式扫描。"})]})}function Rn({kind:n,label:s,hint:i,count:l}){const d=n==="ok",f=n==="warn",m=d?st:f?Dt:ue,c=d?r.success:f?r.warn:r.error;return e.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:t.sm,padding:`${t.xs}px ${t.sm}px`,background:d?"transparent":"rgba(0,0,0,0.02)",borderRadius:$.sm},children:[e.jsx(m,{size:12,color:c,style:{marginTop:t.xxs,flexShrink:0}}),e.jsxs("div",{style:{flex:1},children:[e.jsxs("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text2,lineHeight:1.4},children:[s," ",l!=null&&e.jsxs("span",{style:{color:r.sub,fontSize:p.xs},children:["(",l,")"]})]}),i&&e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,marginTop:1,lineHeight:1.4},children:i})]})]})}function On(n){const s=[],i=Array.from(n.querySelectorAll("img")),l=i.filter(u=>!u.hasAttribute("alt"));i.length===0?s.push({kind:"ok",label:"无图片元素需要 alt",hint:"没有 <img> 标签"}):l.length===0?s.push({kind:"ok",label:"图片 alt 完整",count:i.length}):s.push({kind:"warn",label:"部分图片缺 alt",count:l.length,hint:"加 alt 才能让屏幕阅读器识别"});const d=n.querySelectorAll("h1").length,f=n.querySelectorAll("h2").length;d===0&&f===0?s.push({kind:"warn",label:"没有 h1/h2 标题",hint:"层级缺失,screen reader 难导航"}):d>5?s.push({kind:"warn",label:"h1 过多",count:d,hint:"一般每页只 1 个 h1(每 section 1 个也可)"}):s.push({kind:"ok",label:"标题层级合理",hint:`h1 × ${d}, h2 × ${f}`});const m=Array.from(n.querySelectorAll("button")),c=m.filter(u=>!(u.textContent||"").trim()&&!u.getAttribute("aria-label"));m.length===0?s.push({kind:"ok",label:"无 button 需要文本",hint:"页面没有 <button>"}):c.length===0?s.push({kind:"ok",label:"按钮文本完整",count:m.length}):s.push({kind:"warn",label:"部分按钮缺文本/aria-label",count:c.length});const y=n.documentElement;return y.hasAttribute("lang")?s.push({kind:"ok",label:`<html> 标记了 lang="${y.getAttribute("lang")}"`}):s.push({kind:"warn",label:"<html> 缺 lang 属性",hint:"影响 screen reader 发音"}),s.push({kind:"ok",label:"色彩对比度(抽样)",hint:"主色块 WCAG AA pass(mock)"}),s.push({kind:"ok",label:"焦点顺序(mock)",hint:"Tab 键 traversal — P5 真模拟"}),s}function Hn({project:n,deckSpec:s,projectId:i}){var j,T,H;const l=_t(h=>{var P;return((P=h.contextByProject[i])==null?void 0:P.systemInfo)||null}),d=N(h=>h.showToast),f=N(h=>h.confirm),[m,c]=o.useState([]),[y,u]=o.useState(!1),[a,w]=o.useState(!1),x=o.useRef(null),v=o.useCallback(async()=>{if(i){u(!0);try{const{plugins:h}=await ke.listProject(i);c(h||[])}catch(h){console.error("[SystemTab] listProject plugins failed:",h)}finally{u(!1)}}},[i]);o.useEffect(()=>{v()},[v]);const k=o.useCallback(async(h,P=!1)=>{var D,_,ee,K,V;if(!(!h||!i)){w(!0);try{const L=await ke.installProject(i,h,{force:P}),q=(D=L==null?void 0:L.installed)==null?void 0:D.name;d(`已装 plugin \`${q}\`(新会话生效)`,"success"),(_=L==null?void 0:L.warnings)!=null&&_.length&&d(`警告:${L.warnings.join(";")}`,"warn"),await v()}catch(L){if(L.status===409&&((ee=L.body)!=null&&ee.existing)){await f({title:"覆盖已装 plugin?",message:`已装 \`${L.body.existing.name}@${L.body.existing.version}\`,将覆盖为 \`${L.body.incoming.name}@${L.body.incoming.version}\`。`,confirmLabel:"覆盖",cancelLabel:"取消",danger:!0})&&await k(h,!0);return}const q=(V=(K=L.body)==null?void 0:K.errors)!=null&&V.length?`:${L.body.errors.join(";")}`:"";d(`安装失败${q||`:${L.message}`}`,"error")}finally{w(!1),x.current&&(x.current.value="")}}},[i,v,d,f]),b=o.useCallback(async h=>{if(await f({title:"卸载 plugin?",message:`从 project 移除 \`${h}\`(新会话生效)。文件会被删除。`,confirmLabel:"卸载",cancelLabel:"取消",danger:!0}))try{await ke.removeProject(i,h),d(`已卸载 \`${h}\``,"success"),await v()}catch(D){d(`卸载失败:${D.message}`,"error")}},[i,v,d,f]),F=Array.isArray(l==null?void 0:l.skills)?l.skills.map(h=>typeof h=="string"?h:h.name||h.id).filter(Boolean):[],W=Array.isArray(l==null?void 0:l.plugins)?l.plugins.map(h=>typeof h=="string"?h:h.name||h.id).filter(Boolean):[];return e.jsxs("div",{style:{padding:t.lg,display:"flex",flexDirection:"column",gap:t.xl},children:[e.jsx(Q,{label:"本会话的 Skills",children:F.length===0?e.jsx("span",{style:{fontFamily:z,fontSize:p.sm,color:r.sub},children:"(等会话起动后从 SDK system_init 拉取)"}):e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:t.xs},children:F.map(h=>e.jsx(Ye,{icon:It,label:h},h))})}),e.jsx(Q,{label:"本会话的 Plugins",children:W.length===0?e.jsx("span",{style:{fontFamily:z,fontSize:p.sm,color:r.sub},children:"—"}):e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:t.xs},children:W.map(h=>e.jsx(Ye,{icon:rt,label:h},h))})}),e.jsxs(Q,{label:"Project 级 Plugins",children:[e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.xs,marginBottom:t.sm},children:y&&m.length===0?e.jsx("span",{style:{fontFamily:z,fontSize:p.sm,color:r.sub},children:"加载中…"}):m.length===0?e.jsx("span",{style:{fontFamily:z,fontSize:p.sm,color:r.sub},children:"暂无(上传 zip 安装到本 project)"}):m.map(h=>e.jsx(Dn,{plugin:h,onUninstall:()=>b(h.name)},h.name))}),e.jsx("input",{ref:x,type:"file",accept:".md,.zip,application/zip,text/markdown,text/plain",style:{display:"none"},onChange:h=>{var D;const P=(D=h.target.files)==null?void 0:D[0];P&&k(P)}}),e.jsxs("button",{onClick:()=>{var h;return(h=x.current)==null?void 0:h.click()},disabled:a,style:{display:"inline-flex",alignItems:"center",gap:t.xs,padding:`${t.xs+1}px ${t.md}px`,fontFamily:z,fontSize:p.xs,color:r.text2,background:r.bgWhite,boxShadow:ze.far,borderRadius:$.md,cursor:a?"not-allowed":"pointer",opacity:a?.6:1},children:[e.jsx(Nt,{size:11})," ",a?"安装中…":"上传 skill / plugin"]}),e.jsx("div",{style:{marginTop:t.xs,fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.5},children:"支持单 .md / skill zip / 完整 plugin zip。仅装到本 project;全局可见的走右上角 Skill 页面。新会话生效。"})]}),e.jsxs(Q,{label:"模型",children:[e.jsx(ce,{k:"LLM",v:(l==null?void 0:l.model)||"—"}),(l==null?void 0:l.cwd)&&e.jsx(ce,{k:"cwd",v:l.cwd})]}),s&&e.jsxs(Q,{label:"设计意图(spec)",children:[e.jsx(ce,{k:"metaphor",v:((j=s.meta)==null?void 0:j.metaphor)||"—"}),e.jsx(ce,{k:"audience",v:((T=s.meta)==null?void 0:T.audience)||"—"}),((H=s.meta)==null?void 0:H.intent)&&e.jsx("div",{style:{marginTop:t.sm,padding:t.md,background:r.bgCard,border:`1px solid ${r.borderLt}`,borderRadius:$.md,fontFamily:z,fontSize:p.xs,color:r.text2,lineHeight:1.6},children:s.meta.intent}),s.outline&&s.outline.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{marginTop:t.lg,fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:t.sm},children:["页面 outline (",s.outline.length,")"]}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.xs},children:s.outline.map(h=>e.jsxs("div",{style:{padding:`${t.xs+1}px ${t.md}px`,fontFamily:z,fontSize:p.xs,background:"rgba(43,33,23,0.025)",borderRadius:$.sm,display:"flex",gap:t.sm,alignItems:"baseline"},children:[e.jsx("span",{style:{fontFamily:E,color:r.sub,minWidth:24},children:String(h.index).padStart(2,"0")}),e.jsx("span",{style:{color:r.text3,minWidth:64,fontFamily:E,fontSize:p.xs,textTransform:"uppercase"},children:h.layout}),e.jsx("span",{style:{color:r.text2,flex:1,lineHeight:1.4},children:h.intent})]},h.id))})]})]})]})}function Dn({plugin:n,onUninstall:s}){var i;return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:t.sm,padding:`${t.xs+1}px ${t.sm}px`,background:"rgba(43,33,23,0.025)",borderRadius:$.sm},children:[e.jsx(rt,{size:11,color:r.text4}),e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:t.xs},children:[e.jsx("span",{style:{fontFamily:E,fontSize:p.sm,color:r.text2},children:n.name}),e.jsx("span",{style:{fontFamily:E,fontSize:p.xs,color:r.sub},children:n.version}),e.jsxs("span",{style:{fontFamily:z,fontSize:p.xs,color:r.sub},children:["· ",((i=n.skills)==null?void 0:i.length)||0," skill"]})]}),n.description&&e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.4,marginTop:t.xxs,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:n.description,children:n.description})]}),e.jsx("button",{onClick:s,title:"卸载",style:{background:"transparent",border:"none",color:r.sub,cursor:"pointer",padding:t.xxs},children:e.jsx(it,{size:11})})]})}function Ye({icon:n,label:s}){return e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.xs,padding:`${t.xxs}px ${t.sm}px`,fontFamily:E,fontSize:p.xs,color:r.text2,background:"rgba(43,33,23,0.04)",borderRadius:$.pill},children:[e.jsx(n,{size:10,color:r.text4}),s]})}function Q({label:n,children:s}){return e.jsxs("div",{children:[e.jsx("div",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:t.sm},children:n}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.xs},children:s})]})}function ce({k:n,v:s}){return e.jsxs("div",{style:{display:"flex",gap:t.md,fontFamily:z,fontSize:p.sm},children:[e.jsx("span",{style:{color:r.sub,minWidth:70},children:n}),e.jsx("span",{style:{color:r.text2,flex:1,wordBreak:"break-word"},children:s})]})}function _n({projectId:n,sessionId:s,reloadKey:i=0}){const[l,d]=o.useState(null),[f,m]=o.useState(!1),[c,y]=o.useState(null),u=o.useCallback(async()=>{if(!n||!s){d({});return}m(!0),y(null);try{const x=await qt.read(n);d((x==null?void 0:x.spec)||{})}catch(x){y(x)}finally{m(!1)}},[n,s]);o.useEffect(()=>{u()},[u,i]);const a=Array.isArray(l==null?void 0:l.decisions)?l.decisions:[],w=Array.isArray(l==null?void 0:l.history)?l.history:[];return e.jsxs("div",{style:{padding:t.lg},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:t.md},children:[e.jsxs("div",{style:{fontFamily:E,fontSize:p.sm,fontWeight:500,color:r.text},children:["DECISIONS",e.jsxs("span",{style:{color:r.sub,fontWeight:400,marginLeft:t.sm},children:["(",a.length,")"]})]}),e.jsxs("button",{onClick:u,disabled:f,title:"刷新(agent 调用 record_decision 后会自动刷新;手动按这个也行)",style:{display:"inline-flex",alignItems:"center",gap:t.xs,padding:`${t.xs}px ${t.sm}px`,background:"rgba(43,33,23,0.04)",border:"none",borderRadius:$.sm,cursor:f?"wait":"pointer",fontFamily:z,fontSize:p.sm,color:r.sub},children:[e.jsx(nt,{size:11,style:{animation:f?"rcw-spin 1s linear infinite":"none"}}),f?"...":"刷新"]})]}),c&&e.jsxs("div",{style:{padding:t.md,background:"rgba(220, 53, 69, 0.06)",border:`1px solid ${r.error}33`,borderRadius:$.md,fontFamily:z,fontSize:p.xs,color:r.error,marginBottom:t.md},children:["读取失败:",c.message]}),a.length===0&&!f&&e.jsxs("div",{style:{padding:t.lg,textAlign:"center",fontFamily:z,fontSize:p.sm,color:r.sub,lineHeight:1.6},children:["设计决策现在记在画布的任务便利贴上",e.jsx("br",{}),"(",e.jsx("code",{style:{background:"rgba(43,33,23,0.06)",padding:`1px ${t.xs}px`,borderRadius:$.xs},children:"notes/决策.md"}),", 任务区里那张黄贴纸)。",e.jsx("br",{}),"这里只显示旧会话的存量决策和压缩历史。"]}),a.map((x,v)=>e.jsx(In,{decision:x,index:a.length-v},v)).reverse(),w.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{marginTop:t.xl,marginBottom:t.sm,fontFamily:E,fontSize:p.xs,fontWeight:500,color:r.sub,display:"flex",alignItems:"center",gap:t.xs,letterSpacing:"0.04em"},children:[e.jsx(Ut,{size:11})," COMPACT HISTORY (",w.length,")"]}),w.map((x,v)=>e.jsx(Nn,{entry:x},v)).reverse()]}),e.jsx("style",{children:`
11
+ */const Fn=et("ShieldCheck",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]),Ln=1920,An=1080;function Tn({src:n,srcDoc:s,mode:i="edit",onSelect:l,onTextEdit:d,onIframeReady:f,zoom:m=1,deckW:c=Ln,deckH:y=An}){const u=o.useRef(null),a=o.useRef(!1),w=o.useRef(0),[x,v]=o.useState(!1);o.useEffect(()=>{v(!0)},[n,s]),o.useEffect(()=>{const b=u.current;if(!(!b||!a.current))return Ke(b),i==="edit"&&Ve(b,{onSelect:l,onTextEdit:d}),()=>Ke(b)},[i,l,d]),o.useEffect(()=>()=>{var b;try{const L=(b=u.current)==null?void 0:b.contentWindow;L&&typeof L.scrollY=="number"&&(w.current=L.scrollY)}catch{}},[n,s]);const k=()=>{a.current=!0;const b=u.current;if(b){if(f==null||f(b),i==="edit"&&Ve(b,{onSelect:l,onTextEdit:d}),w.current>0)try{requestAnimationFrame(()=>{var L;try{(L=b.contentWindow)==null||L.scrollTo(0,w.current)}catch{}})}catch{}requestAnimationFrame(()=>{requestAnimationFrame(()=>v(!1))})}};return e.jsx("div",{style:{flex:1,minHeight:0,overflow:"hidden",background:r.bgWhite,position:"relative",display:"flex",alignItems:"center",justifyContent:"center"},children:e.jsx("iframe",{ref:u,src:n,srcDoc:s,onLoad:k,sandbox:"allow-scripts allow-same-origin",style:{width:`${c}px`,height:`${y}px`,flexShrink:0,border:0,background:r.bgWhite,transform:m===1?"none":`scale(${m})`,transformOrigin:"center center",opacity:x?.5:1,transition:"opacity 180ms ease-out"}})})}function Pn({candidates:n,activeId:s,onSelect:i,onAdd:l,onRemove:d,onRename:f}){if(!n||n.length===0)return null;const m=n.length===1;return e.jsxs("div",{style:{flexShrink:0,height:36,borderBottom:`1px solid ${r.border}`,background:r.bgWhite,padding:`0 ${t.lg}px`,display:"flex",alignItems:"center",gap:t.xs,overflowX:"auto",overflowY:"hidden"},children:[e.jsx(Ht,{size:11,color:r.sub,style:{flexShrink:0,marginRight:t.xs}}),n.map(c=>{const y=c.id===s;return e.jsx(Wn,{candidate:c,active:y,onSelect:()=>i==null?void 0:i(c.id),onRemove:m?null:()=>d==null?void 0:d(c.id),onRename:f},c.id)}),e.jsxs("button",{onClick:l,title:"新建候选(mock 复制当前)",style:{flexShrink:0,padding:`${t.xs}px ${t.md}px`,display:"inline-flex",alignItems:"center",gap:t.xs,fontFamily:E,fontSize:p.xs,color:r.sub,background:"transparent",border:`1px dashed ${r.borderMd}`,borderRadius:$.sm,cursor:"pointer"},onMouseEnter:c=>{c.currentTarget.style.color=r.text2,c.currentTarget.style.background="rgba(0,0,0,0.03)"},onMouseLeave:c=>{c.currentTarget.style.color=r.sub,c.currentTarget.style.background="transparent"},children:[e.jsx(tt,{size:11})," 新候选"]}),e.jsx("div",{style:{flex:1}}),e.jsxs("span",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,opacity:m?0:.7,flexShrink:0},children:[n.length," 个候选"]})]})}function Wn({candidate:n,active:s,onSelect:i,onRemove:l,onRename:d}){const[f,m]=o.useState(!1),c=q(w=>w.prompt),y=q(w=>w.confirm),u=async w=>{if(w.stopPropagation(),!d)return;const x=await c({title:"重命名候选",initialValue:n.label,placeholder:"候选名"});x&&x.trim()&&x!==n.label&&d(n.id,x.trim())},a=async w=>{w.stopPropagation(),await y({title:"删除候选",message:`删除候选「${n.label}」?`,confirmLabel:"删除",danger:!0})&&l()};return e.jsxs("div",{onMouseEnter:()=>m(!0),onMouseLeave:()=>m(!1),style:{flexShrink:0,position:"relative",display:"inline-flex",alignItems:"center",background:s?"rgba(45,36,24,0.06)":"transparent",borderRadius:$.sm,transition:"background 0.15s"},children:[e.jsx("button",{onClick:i,onDoubleClick:u,title:"双击重命名",style:{padding:`${t.xs}px ${l&&f?t.lg:t.md}px ${t.xs}px ${t.md}px`,fontFamily:E,fontSize:p.xs,fontWeight:s?500:400,color:s?r.text:r.text4,background:"transparent",borderRadius:$.sm,cursor:"pointer",transition:"all 0.15s"},children:n.label}),l&&f&&e.jsx("button",{onClick:a,style:{position:"absolute",right:2,top:"50%",transform:"translateY(-50%)",width:14,height:14,borderRadius:$.xs,background:"rgba(0,0,0,0.06)",color:r.sub,display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"},onMouseEnter:w=>{w.currentTarget.style.background="rgba(184,58,42,0.15)",w.currentTarget.style.color=r.error},onMouseLeave:w=>{w.currentTarget.style.background="rgba(0,0,0,0.06)",w.currentTarget.style.color=r.sub},title:"删除候选",children:e.jsx(ue,{size:9})})]})}const de=12,Bn=8;function $e(n,s){const[i,l]=o.useState(null);return o.useLayoutEffect(()=>{const d=n==null?void 0:n.current;if(!d){l(null);return}const f=()=>{const m=d.getBoundingClientRect();if(!m.width&&!m.height){l(null);return}const c=window.innerWidth,y=window.innerHeight,u=Math.max(de,Math.min(m.left,c-s-de)),a=Math.min(m.bottom+Bn,y-de-120);l({position:"fixed",left:u,top:a,maxHeight:y-a-de})};return f(),window.addEventListener("resize",f),()=>window.removeEventListener("resize",f)},[n,s]),i||{position:"absolute",top:78,right:16}}function Mn({anchorRef:n,onClose:s,iframeDoc:i}){const l=o.useRef(null),d=$e(n,320),[f,m]=o.useState(!1),[c,y]=o.useState(null);o.useEffect(()=>{i&&u()},[i]),o.useEffect(()=>{const a=w=>{var x;l.current&&!l.current.contains(w.target)&&!((x=n==null?void 0:n.current)!=null&&x.contains(w.target))&&(s==null||s())};return window.addEventListener("mousedown",a),()=>window.removeEventListener("mousedown",a)},[s,n]);const u=()=>{i&&(m(!0),setTimeout(()=>{y(On(i)),m(!1)},400))};return e.jsxs("div",{ref:l,style:{...d,width:320,background:r.bgWhite,borderRadius:2,boxShadow:"0 2px 4px rgba(0,0,0,0.04), 0 8px 20px rgba(0,0,0,0.08), 0 24px 48px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.8)",zIndex:60,overflow:"hidden"},children:[e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,display:"flex",alignItems:"center",justifyContent:"space-between",borderBottom:`1px solid ${r.borderLt}`},children:[e.jsx("span",{style:{fontFamily:E,fontSize:p.sm,fontWeight:500,color:r.text},children:"Accessibility Review"}),e.jsx("button",{onClick:u,disabled:f,style:{padding:t.xs,color:r.sub,borderRadius:$.xs,opacity:f?.5:1},title:"重新扫描",children:e.jsx(nt,{size:11,className:f?"spin":""})})]}),e.jsxs("div",{style:{padding:t.lg,maxHeight:360,overflowY:"auto"},children:[f&&e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.sub,textAlign:"center",padding:t.lg},children:"扫描中…"}),!f&&c&&e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.sm},children:c.map((a,w)=>e.jsx(Rn,{...a},w))})]}),e.jsx("div",{style:{padding:`${t.sm}px ${t.lg}px`,background:r.bgCard,borderTop:`1px solid ${r.borderLt}`,fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.5},children:"P5 接 LLM 真做 contrast / hierarchy / usability 审查;当前是启发式扫描。"})]})}function Rn({kind:n,label:s,hint:i,count:l}){const d=n==="ok",f=n==="warn",m=d?st:f?_t:ue,c=d?r.success:f?r.warn:r.error;return e.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:t.sm,padding:`${t.xs}px ${t.sm}px`,background:d?"transparent":"rgba(0,0,0,0.02)",borderRadius:$.sm},children:[e.jsx(m,{size:12,color:c,style:{marginTop:t.xxs,flexShrink:0}}),e.jsxs("div",{style:{flex:1},children:[e.jsxs("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text2,lineHeight:1.4},children:[s," ",l!=null&&e.jsxs("span",{style:{color:r.sub,fontSize:p.xs},children:["(",l,")"]})]}),i&&e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,marginTop:1,lineHeight:1.4},children:i})]})]})}function On(n){const s=[],i=Array.from(n.querySelectorAll("img")),l=i.filter(u=>!u.hasAttribute("alt"));i.length===0?s.push({kind:"ok",label:"无图片元素需要 alt",hint:"没有 <img> 标签"}):l.length===0?s.push({kind:"ok",label:"图片 alt 完整",count:i.length}):s.push({kind:"warn",label:"部分图片缺 alt",count:l.length,hint:"加 alt 才能让屏幕阅读器识别"});const d=n.querySelectorAll("h1").length,f=n.querySelectorAll("h2").length;d===0&&f===0?s.push({kind:"warn",label:"没有 h1/h2 标题",hint:"层级缺失,screen reader 难导航"}):d>5?s.push({kind:"warn",label:"h1 过多",count:d,hint:"一般每页只 1 个 h1(每 section 1 个也可)"}):s.push({kind:"ok",label:"标题层级合理",hint:`h1 × ${d}, h2 × ${f}`});const m=Array.from(n.querySelectorAll("button")),c=m.filter(u=>!(u.textContent||"").trim()&&!u.getAttribute("aria-label"));m.length===0?s.push({kind:"ok",label:"无 button 需要文本",hint:"页面没有 <button>"}):c.length===0?s.push({kind:"ok",label:"按钮文本完整",count:m.length}):s.push({kind:"warn",label:"部分按钮缺文本/aria-label",count:c.length});const y=n.documentElement;return y.hasAttribute("lang")?s.push({kind:"ok",label:`<html> 标记了 lang="${y.getAttribute("lang")}"`}):s.push({kind:"warn",label:"<html> 缺 lang 属性",hint:"影响 screen reader 发音"}),s.push({kind:"ok",label:"色彩对比度(抽样)",hint:"主色块 WCAG AA pass(mock)"}),s.push({kind:"ok",label:"焦点顺序(mock)",hint:"Tab 键 traversal — P5 真模拟"}),s}function Hn({project:n,deckSpec:s,projectId:i}){var j,T,H;const l=Dt(h=>{var P;return((P=h.contextByProject[i])==null?void 0:P.systemInfo)||null}),d=q(h=>h.showToast),f=q(h=>h.confirm),[m,c]=o.useState([]),[y,u]=o.useState(!1),[a,w]=o.useState(!1),x=o.useRef(null),v=o.useCallback(async()=>{if(i){u(!0);try{const{plugins:h}=await ke.listProject(i);c(h||[])}catch(h){console.error("[SystemTab] listProject plugins failed:",h)}finally{u(!1)}}},[i]);o.useEffect(()=>{v()},[v]);const k=o.useCallback(async(h,P=!1)=>{var _,D,ee,X,K;if(!(!h||!i)){w(!0);try{const F=await ke.installProject(i,h,{force:P}),N=(_=F==null?void 0:F.installed)==null?void 0:_.name;d(`已装 plugin \`${N}\`(新会话生效)`,"success"),(D=F==null?void 0:F.warnings)!=null&&D.length&&d(`警告:${F.warnings.join(";")}`,"warn"),await v()}catch(F){if(F.status===409&&((ee=F.body)!=null&&ee.existing)){await f({title:"覆盖已装 plugin?",message:`已装 \`${F.body.existing.name}@${F.body.existing.version}\`,将覆盖为 \`${F.body.incoming.name}@${F.body.incoming.version}\`。`,confirmLabel:"覆盖",cancelLabel:"取消",danger:!0})&&await k(h,!0);return}const N=(K=(X=F.body)==null?void 0:X.errors)!=null&&K.length?`:${F.body.errors.join(";")}`:"";d(`安装失败${N||`:${F.message}`}`,"error")}finally{w(!1),x.current&&(x.current.value="")}}},[i,v,d,f]),b=o.useCallback(async h=>{if(await f({title:"卸载 plugin?",message:`从 project 移除 \`${h}\`(新会话生效)。文件会被删除。`,confirmLabel:"卸载",cancelLabel:"取消",danger:!0}))try{await ke.removeProject(i,h),d(`已卸载 \`${h}\``,"success"),await v()}catch(_){d(`卸载失败:${_.message}`,"error")}},[i,v,d,f]),L=Array.isArray(l==null?void 0:l.skills)?l.skills.map(h=>typeof h=="string"?h:h.name||h.id).filter(Boolean):[],W=Array.isArray(l==null?void 0:l.plugins)?l.plugins.map(h=>typeof h=="string"?h:h.name||h.id).filter(Boolean):[];return e.jsxs("div",{style:{padding:t.lg,display:"flex",flexDirection:"column",gap:t.xl},children:[e.jsx(J,{label:"本会话的 Skills",children:L.length===0?e.jsx("span",{style:{fontFamily:z,fontSize:p.sm,color:r.sub},children:"(等会话起动后从 SDK system_init 拉取)"}):e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:t.xs},children:L.map(h=>e.jsx(Ye,{icon:It,label:h},h))})}),e.jsx(J,{label:"本会话的 Plugins",children:W.length===0?e.jsx("span",{style:{fontFamily:z,fontSize:p.sm,color:r.sub},children:"—"}):e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:t.xs},children:W.map(h=>e.jsx(Ye,{icon:rt,label:h},h))})}),e.jsxs(J,{label:"Project 级 Plugins",children:[e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.xs,marginBottom:t.sm},children:y&&m.length===0?e.jsx("span",{style:{fontFamily:z,fontSize:p.sm,color:r.sub},children:"加载中…"}):m.length===0?e.jsx("span",{style:{fontFamily:z,fontSize:p.sm,color:r.sub},children:"暂无(上传 zip 安装到本 project)"}):m.map(h=>e.jsx(_n,{plugin:h,onUninstall:()=>b(h.name)},h.name))}),e.jsx("input",{ref:x,type:"file",accept:".md,.zip,application/zip,text/markdown,text/plain",style:{display:"none"},onChange:h=>{var _;const P=(_=h.target.files)==null?void 0:_[0];P&&k(P)}}),e.jsxs("button",{onClick:()=>{var h;return(h=x.current)==null?void 0:h.click()},disabled:a,style:{display:"inline-flex",alignItems:"center",gap:t.xs,padding:`${t.xs+1}px ${t.md}px`,fontFamily:z,fontSize:p.xs,color:r.text2,background:r.bgWhite,boxShadow:ze.far,borderRadius:$.md,cursor:a?"not-allowed":"pointer",opacity:a?.6:1},children:[e.jsx(qt,{size:11})," ",a?"安装中…":"上传 skill / plugin"]}),e.jsx("div",{style:{marginTop:t.xs,fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.5},children:"支持单 .md / skill zip / 完整 plugin zip。仅装到本 project;全局可见的走右上角 Skill 页面。新会话生效。"})]}),e.jsxs(J,{label:"模型",children:[e.jsx(ce,{k:"LLM",v:(l==null?void 0:l.model)||"—"}),(l==null?void 0:l.cwd)&&e.jsx(ce,{k:"cwd",v:l.cwd})]}),s&&e.jsxs(J,{label:"设计意图(spec)",children:[e.jsx(ce,{k:"metaphor",v:((j=s.meta)==null?void 0:j.metaphor)||"—"}),e.jsx(ce,{k:"audience",v:((T=s.meta)==null?void 0:T.audience)||"—"}),((H=s.meta)==null?void 0:H.intent)&&e.jsx("div",{style:{marginTop:t.sm,padding:t.md,background:r.bgCard,border:`1px solid ${r.borderLt}`,borderRadius:$.md,fontFamily:z,fontSize:p.xs,color:r.text2,lineHeight:1.6},children:s.meta.intent}),s.outline&&s.outline.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{marginTop:t.lg,fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:t.sm},children:["页面 outline (",s.outline.length,")"]}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.xs},children:s.outline.map(h=>e.jsxs("div",{style:{padding:`${t.xs+1}px ${t.md}px`,fontFamily:z,fontSize:p.xs,background:"rgba(43,33,23,0.025)",borderRadius:$.sm,display:"flex",gap:t.sm,alignItems:"baseline"},children:[e.jsx("span",{style:{fontFamily:E,color:r.sub,minWidth:24},children:String(h.index).padStart(2,"0")}),e.jsx("span",{style:{color:r.text3,minWidth:64,fontFamily:E,fontSize:p.xs,textTransform:"uppercase"},children:h.layout}),e.jsx("span",{style:{color:r.text2,flex:1,lineHeight:1.4},children:h.intent})]},h.id))})]})]})]})}function _n({plugin:n,onUninstall:s}){var i;return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:t.sm,padding:`${t.xs+1}px ${t.sm}px`,background:"rgba(43,33,23,0.025)",borderRadius:$.sm},children:[e.jsx(rt,{size:11,color:r.text4}),e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:t.xs},children:[e.jsx("span",{style:{fontFamily:E,fontSize:p.sm,color:r.text2},children:n.name}),e.jsx("span",{style:{fontFamily:E,fontSize:p.xs,color:r.sub},children:n.version}),e.jsxs("span",{style:{fontFamily:z,fontSize:p.xs,color:r.sub},children:["· ",((i=n.skills)==null?void 0:i.length)||0," skill"]})]}),n.description&&e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.4,marginTop:t.xxs,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:n.description,children:n.description})]}),e.jsx("button",{onClick:s,title:"卸载",style:{background:"transparent",border:"none",color:r.sub,cursor:"pointer",padding:t.xxs},children:e.jsx(it,{size:11})})]})}function Ye({icon:n,label:s}){return e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:t.xs,padding:`${t.xxs}px ${t.sm}px`,fontFamily:E,fontSize:p.xs,color:r.text2,background:"rgba(43,33,23,0.04)",borderRadius:$.pill},children:[e.jsx(n,{size:10,color:r.text4}),s]})}function J({label:n,children:s}){return e.jsxs("div",{children:[e.jsx("div",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:t.sm},children:n}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.xs},children:s})]})}function ce({k:n,v:s}){return e.jsxs("div",{style:{display:"flex",gap:t.md,fontFamily:z,fontSize:p.sm},children:[e.jsx("span",{style:{color:r.sub,minWidth:70},children:n}),e.jsx("span",{style:{color:r.text2,flex:1,wordBreak:"break-word"},children:s})]})}function Dn({projectId:n,sessionId:s,reloadKey:i=0}){const[l,d]=o.useState(null),[f,m]=o.useState(!1),[c,y]=o.useState(null),u=o.useCallback(async()=>{if(!n||!s){d({});return}m(!0),y(null);try{const x=await Nt.read(n);d((x==null?void 0:x.spec)||{})}catch(x){y(x)}finally{m(!1)}},[n,s]);o.useEffect(()=>{u()},[u,i]);const a=Array.isArray(l==null?void 0:l.decisions)?l.decisions:[],w=Array.isArray(l==null?void 0:l.history)?l.history:[];return e.jsxs("div",{style:{padding:t.lg},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:t.md},children:[e.jsxs("div",{style:{fontFamily:E,fontSize:p.sm,fontWeight:500,color:r.text},children:["DECISIONS",e.jsxs("span",{style:{color:r.sub,fontWeight:400,marginLeft:t.sm},children:["(",a.length,")"]})]}),e.jsxs("button",{onClick:u,disabled:f,title:"刷新(agent 调用 record_decision 后会自动刷新;手动按这个也行)",style:{display:"inline-flex",alignItems:"center",gap:t.xs,padding:`${t.xs}px ${t.sm}px`,background:"rgba(43,33,23,0.04)",border:"none",borderRadius:$.sm,cursor:f?"wait":"pointer",fontFamily:z,fontSize:p.sm,color:r.sub},children:[e.jsx(nt,{size:11,style:{animation:f?"rcw-spin 1s linear infinite":"none"}}),f?"...":"刷新"]})]}),c&&e.jsxs("div",{style:{padding:t.md,background:"rgba(220, 53, 69, 0.06)",border:`1px solid ${r.error}33`,borderRadius:$.md,fontFamily:z,fontSize:p.xs,color:r.error,marginBottom:t.md},children:["读取失败:",c.message]}),a.length===0&&!f&&e.jsxs("div",{style:{padding:t.lg,textAlign:"center",fontFamily:z,fontSize:p.sm,color:r.sub,lineHeight:1.6},children:["设计决策现在记在画布的任务便利贴上",e.jsx("br",{}),"(",e.jsx("code",{style:{background:"rgba(43,33,23,0.06)",padding:`1px ${t.xs}px`,borderRadius:$.xs},children:"notes/决策.md"}),", 任务区里那张黄贴纸)。",e.jsx("br",{}),"这里只显示旧会话的存量决策和压缩历史。"]}),a.map((x,v)=>e.jsx(In,{decision:x,index:a.length-v},v)).reverse(),w.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{marginTop:t.xl,marginBottom:t.sm,fontFamily:E,fontSize:p.xs,fontWeight:500,color:r.sub,display:"flex",alignItems:"center",gap:t.xs,letterSpacing:"0.04em"},children:[e.jsx(Ut,{size:11})," COMPACT HISTORY (",w.length,")"]}),w.map((x,v)=>e.jsx(qn,{entry:x},v)).reverse()]}),e.jsx("style",{children:`
12
12
  @keyframes rcw-spin {
13
13
  from { transform: rotate(0deg); }
14
14
  to { transform: rotate(360deg); }
15
15
  }
16
- `})]})}function In({decision:n}){return e.jsxs("div",{style:{padding:t.md,marginBottom:t.sm,borderRadius:2,background:r.bgWhite,boxShadow:ze.far},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:t.xs,marginBottom:t.xs},children:[e.jsx(Gt,{size:11,color:r.text4}),e.jsx("div",{style:{flex:1,fontFamily:z,fontSize:p.sm,fontWeight:500,color:r.text,lineHeight:1.4},children:n.title||"(no title)"})]}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.text4,lineHeight:1.5,marginBottom:t.xs,whiteSpace:"pre-wrap",wordBreak:"break-word"},children:n.rationale}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:t.sm,fontFamily:E,fontSize:p.xs,color:r.sub},children:[n.scope&&e.jsxs("span",{children:["scope: ",n.scope]}),e.jsx("span",{children:pt(n.ts)})]}),Array.isArray(n.alternatives)&&n.alternatives.length>0&&e.jsxs("details",{style:{marginTop:t.xs},children:[e.jsxs("summary",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,cursor:"pointer"},children:["考虑过的替代 (",n.alternatives.length,")"]}),e.jsx("ul",{style:{margin:`${t.xs}px 0 0 0`,paddingLeft:t.xl,fontFamily:z,fontSize:p.xs,color:r.text4,lineHeight:1.5},children:n.alternatives.map((s,i)=>e.jsx("li",{children:s},i))})]})]})}function Nn({entry:n}){var s;return e.jsxs("div",{style:{padding:t.md,marginBottom:t.sm,borderLeft:`2px solid ${r.borderMd}`,paddingLeft:t.md},children:[e.jsxs("div",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,marginBottom:t.xs,letterSpacing:"0.04em"},children:[((s=n.source)==null?void 0:s.toUpperCase())||"COMPACT"," · ",pt(n.ts),n.trigger&&n.trigger!=="auto"&&` · ${n.trigger}`]}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.text4,lineHeight:1.5,whiteSpace:"pre-wrap"},children:n.summary})]})}function pt(n){if(!n)return"";try{return new Date(n).toLocaleString("zh-CN",{month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"})}catch{return n}}function qn({anchorRef:n,onClose:s,project:i,deckSpec:l,projectId:d,sessionId:f,decisionsReloadKey:m=0,onA11yClick:c,tweaksEnabled:y=null,onTweaksEnabledChange:u=null}){const a=N(j=>j.canvasFont),w=N(j=>j.followAgent),x=N(j=>j.setFollowAgent),v=N(j=>j.setCanvasFont),k=o.useRef(null),[b,F]=o.useState(!1),W=$e(n,360);return o.useEffect(()=>{const j=T=>{var H;k.current&&!k.current.contains(T.target)&&!((H=n==null?void 0:n.current)!=null&&H.contains(T.target))&&(s==null||s())};return window.addEventListener("mousedown",j),()=>window.removeEventListener("mousedown",j)},[s,n]),o.useEffect(()=>{const j=T=>{T.key==="Escape"&&(s==null||s())};return window.addEventListener("keydown",j),()=>window.removeEventListener("keydown",j)},[s]),e.jsxs("div",{ref:k,style:{...W,width:360,background:r.bgWhite,borderRadius:2,boxShadow:"0 2px 4px rgba(0,0,0,0.04), 0 8px 20px rgba(0,0,0,0.08), 0 24px 48px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.8)",zIndex:60,display:"flex",flexDirection:"column",overflow:"hidden"},children:[e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,display:"flex",alignItems:"center",gap:t.sm,borderBottom:`1px solid ${r.borderLt}`,flexShrink:0},children:[e.jsx(lt,{size:12,color:r.text4}),e.jsx("span",{style:{fontFamily:E,fontSize:p.sm,fontWeight:500,color:r.text},children:"System"})]}),e.jsxs("div",{style:{flex:1,minHeight:0,overflowY:"auto"},children:[c&&e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`,display:"flex",flexDirection:"column",gap:t.sm},children:[e.jsx("div",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em"},children:"Canvas 工具"}),e.jsx("div",{style:{display:"flex",gap:t.sm},children:e.jsxs("button",{onClick:()=>{c(),s==null||s()},style:Un,title:"无障碍审查(mock)",children:[e.jsx(Ln,{size:11})," A11y"]})})]}),u&&e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`,display:"flex",alignItems:"center",gap:t.sm},children:[e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text},children:"Tweaks 模式"}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,marginTop:2,lineHeight:1.5},children:y?"开:agent 会主动把核心参数做成控件让你拖":"关:不暴露控件,改样式走对话"})]}),e.jsx(Ze,{checked:!!y,onChange:u})]}),e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`,display:"flex",alignItems:"center",gap:t.sm},children:[e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text},children:"镜头跟随 agent"}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,marginTop:2,lineHeight:1.5},children:w?"开:agent 换到哪个产物,镜头就飞过去(你操作后 8 秒内不抢)":"关:镜头只听你的;agent 在动什么看光圈"})]}),e.jsx(Ze,{checked:w,onChange:x})]}),e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`},children:[e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text},children:"画布手写字体"}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,marginTop:2,marginBottom:t.sm},children:"用「文字」工具(T)在画布上写字时用这个"}),e.jsx("div",{style:{display:"flex",gap:t.xs,flexWrap:"wrap"},children:Object.entries(Kt).map(([j,T])=>e.jsx("button",{onClick:()=>v({...a,font:j}),style:{padding:`${t.xs}px ${t.sm}px`,borderRadius:$.md,cursor:"pointer",fontFamily:Vt[j],fontSize:p.sm,border:`1px solid ${a.font===j?r.text:r.borderLt}`,background:a.font===j?r.text:"transparent",color:a.font===j?r.bg:r.text2},children:T},j))}),e.jsx("div",{style:{display:"flex",gap:t.xs,marginTop:t.sm},children:Object.entries(Xt).map(([j,T])=>e.jsx("button",{onClick:()=>v({...a,size:j}),style:{padding:`${t.xs}px ${t.sm}px`,borderRadius:$.md,cursor:"pointer",fontFamily:z,fontSize:p.xs,border:`1px solid ${a.size===j?r.text:r.borderLt}`,background:a.size===j?r.text:"transparent",color:a.size===j?r.bg:r.text2},children:T},j))})]}),e.jsx(Hn,{project:i,deckSpec:l,projectId:d}),e.jsxs("div",{style:{borderTop:`1px solid ${r.borderLt}`,padding:`${t.md}px ${t.lg}px 0`},children:[e.jsxs("button",{onClick:()=>F(j=>!j),style:{display:"flex",alignItems:"center",gap:t.xs,width:"100%",padding:`${t.xs}px 0`,background:"transparent",border:"none",fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em",cursor:"pointer"},children:[e.jsx(ot,{size:11,style:{transform:b?"rotate(90deg)":"rotate(0deg)",transition:"transform 0.12s ease"}}),"项目档案 — Decisions / History"]}),!b&&e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,padding:`${t.xs}px 0 ${t.md}px ${t.lg}px`,lineHeight:1.5},children:"展开看 agent 记录的设计决策 + compact 摘要历史。"})]}),b&&e.jsx("div",{style:{background:"rgba(0,0,0,0.015)",margin:`0 ${t.lg}px ${t.md}px`,border:`1px solid ${r.borderLt}`,borderRadius:$.md},children:e.jsx(_n,{projectId:d,sessionId:f,reloadKey:m})})]}),e.jsx("div",{style:{padding:`${t.sm}px ${t.lg}px`,background:r.bgCard,borderTop:`1px solid ${r.borderLt}`,fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.5,flexShrink:0},children:"spec 不可在此编辑 — 改 spec 跟 agent 说,触发新 run。"})]})}function Ze({checked:n,onChange:s,title:i}){return e.jsx("button",{onClick:()=>s==null?void 0:s(!n),title:i,style:{width:28,height:16,padding:0,border:"none",borderRadius:$.lg,background:n?r.text:"rgba(0,0,0,0.18)",position:"relative",cursor:"pointer",transition:"background 0.15s",flexShrink:0},children:e.jsx("span",{style:{position:"absolute",top:2,left:n?14:2,width:12,height:12,borderRadius:$.round,background:r.bgWhite,boxShadow:at.crispSm,transition:"left 0.15s"}})})}const Un={padding:`${t.xs+1}px ${t.md}px`,fontFamily:E,fontSize:p.xs,color:r.text4,background:"rgba(0,0,0,0.04)",border:"none",borderRadius:$.sm,display:"inline-flex",alignItems:"center",gap:t.xs,cursor:"pointer"};function Gn({comments:n=[],iframeDoc:s,iframeRef:i,anchorRef:l,onClose:d,onResolveComment:f,onDeleteComment:m,onSelectAnchor:c}){const y=o.useRef(null),u=$e(l,380);o.useEffect(()=>{const x=v=>{var k;y.current&&!y.current.contains(v.target)&&!((k=l==null?void 0:l.current)!=null&&k.contains(v.target))&&(d==null||d())};return window.addEventListener("mousedown",x),()=>window.removeEventListener("mousedown",x)},[d,l]),o.useEffect(()=>{const x=v=>{v.key==="Escape"&&(d==null||d())};return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[d]);const a=o.useMemo(()=>{const x=new Map;for(const k of n){const b=s&&k.anchor?dt(k.anchor,s.body):null,F=b?Yt(b):null,W=(F==null?void 0:F.index)??null;x.has(W)||x.set(W,[]),x.get(W).push({comment:k,el:b})}return[...x.entries()].sort((k,b)=>k[0]===null?1:b[0]===null?-1:k[0]-b[0])},[n,s]),w=x=>{if(x.el)try{x.el.scrollIntoView({behavior:"smooth",block:"center"})}catch{}c&&c(x.comment.anchor)};return e.jsxs("div",{ref:y,style:{...u,width:380,background:r.bgWhite,borderRadius:2,boxShadow:"0 2px 4px rgba(0,0,0,0.04), 0 8px 20px rgba(0,0,0,0.08), 0 24px 48px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.8)",zIndex:60,display:"flex",flexDirection:"column",overflow:"hidden"},children:[e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,display:"flex",alignItems:"center",gap:t.sm,borderBottom:`1px solid ${r.borderLt}`,flexShrink:0},children:[e.jsx(xt,{size:12,color:r.text4}),e.jsxs("span",{style:{fontFamily:E,fontSize:p.sm,fontWeight:500,color:r.text,flex:1},children:["全部评论 ",n.length>0&&`(${n.length})`]}),e.jsx("button",{onClick:d,title:"关闭",style:{padding:t.xs,color:r.text5,borderRadius:$.xs,background:"transparent",border:"none",cursor:"pointer"},children:e.jsx(ue,{size:12})})]}),e.jsx("div",{style:{flex:1,minHeight:0,overflowY:"auto"},children:n.length===0?e.jsxs("div",{style:{padding:`${t.lg+t.md}px ${t.lg}px`,fontFamily:z,fontSize:p.sm,color:r.sub,textAlign:"center",lineHeight:1.6},children:["还没有评论。",e.jsx("br",{}),"点击画布上任意元素 → 在弹出的浮卡里写评论。"]}):a.map(([x,v])=>e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`},children:[e.jsxs("div",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:t.sm},children:[x===null?"未定位":`第 ${x+1} 页`," · ",v.length," 条"]}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.xs},children:v.map(({comment:k,el:b})=>e.jsx(Kn,{comment:k,available:!!b,onClick:()=>w({comment:k,el:b}),onResolve:()=>f==null?void 0:f(k.id),onDelete:()=>m==null?void 0:m(k.id)},k.id))})]},x??"orphan"))}),e.jsx("div",{style:{padding:`${t.sm}px ${t.lg}px`,background:r.bgCard,borderTop:`1px solid ${r.borderLt}`,fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.5,flexShrink:0},children:"点击评论 → 跳到对应元素;evaluator 切到 edit 模式后可在浮卡续写。"})]})}function Kn({comment:n,available:s,onClick:i,onResolve:l,onDelete:d}){var m,c,y;const f=n.status==="resolved";return e.jsxs("div",{style:{padding:`${t.sm}px ${t.md}px`,background:r.bgWhite,boxShadow:ze.far,borderRadius:$.md,display:"flex",flexDirection:"column",gap:t.xs,opacity:f?.5:1,cursor:s?"pointer":"default",transition:"background 0.1s"},onClick:s?i:void 0,onMouseEnter:u=>{s&&(u.currentTarget.style.background="rgba(0,0,0,0.02)")},onMouseLeave:u=>{u.currentTarget.style.background=r.bgWhite},children:[e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text2,lineHeight:1.5,textDecoration:f?"line-through":"none",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:n.text}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:t.xs,fontFamily:E,fontSize:p.xs,color:r.sub},children:[s?e.jsxs(e.Fragment,{children:[e.jsx(xn,{size:9}),e.jsx("span",{children:((m=n.anchor)==null?void 0:m.dataId)||((y=(c=n.anchor)==null?void 0:c.path)==null?void 0:y.split(">").pop())||"元素"})]}):e.jsx("span",{style:{fontStyle:"italic"},children:"元素已不在"}),e.jsx("span",{style:{flex:1}}),e.jsx("button",{onClick:u=>{u.stopPropagation(),l()},title:f?"取消解决":"标记解决",style:{padding:t.xxs,color:r.sub,borderRadius:$.xs,background:"transparent",border:"none",cursor:"pointer"},children:e.jsx(st,{size:11})}),e.jsx("button",{onClick:u=>{u.stopPropagation(),d()},title:"删除",style:{padding:t.xxs,color:r.sub,borderRadius:$.xs,background:"transparent",border:"none",cursor:"pointer"},children:e.jsx(it,{size:11})})]})]})}function Vn({iframeDoc:n,active:s}){const[i,l]=o.useState([]),[d,f]=o.useState(0);o.useEffect(()=>{if(!s||!n){l([]);return}let c=null;const y=()=>{const a=Array.from(n.querySelectorAll("section[data-page]"));if(l(a),c&&c.disconnect(),!!a.length)try{c=new(n.defaultView||window).IntersectionObserver(w=>{const x=w.filter(k=>k.isIntersecting).sort((k,b)=>b.intersectionRatio-k.intersectionRatio)[0];if(!x)return;const v=a.indexOf(x.target);v>=0&&f(v)},{threshold:[.35,.6]}),a.forEach(w=>c.observe(w))}catch{}};y();let u=null;try{u=new(n.defaultView||window).MutationObserver(()=>y()),n.body&&u.observe(n.body,{childList:!0,subtree:!0})}catch{}return()=>{c==null||c.disconnect(),u==null||u.disconnect()}},[n,s]);const m=o.useCallback(c=>{f(y=>{const u=Math.max(0,Math.min(i.length-1,y+c)),a=i[u];if(a)try{a.scrollIntoView({behavior:"smooth",block:"start"})}catch{}return u})},[i]);return o.useEffect(()=>{if(!s||i.length<2)return;const c=u=>{if(u.key!=="ArrowLeft"&&u.key!=="ArrowRight")return;const a=u.target;a&&(a.tagName==="INPUT"||a.tagName==="TEXTAREA"||a.isContentEditable)||(u.preventDefault(),m(u.key==="ArrowRight"?1:-1))};window.addEventListener("keydown",c);let y=null;try{y=n,y==null||y.addEventListener("keydown",c)}catch{}return()=>{window.removeEventListener("keydown",c);try{y==null||y.removeEventListener("keydown",c)}catch{}}},[s,i.length,m,n]),!s||i.length<2?null:e.jsxs("div",{style:{position:"absolute",bottom:16,left:"50%",transform:"translateX(-50%)",display:"flex",alignItems:"center",gap:t.xxs,background:"rgba(28,24,18,0.86)",borderRadius:$.pill,padding:t.xs,boxShadow:"0 6px 22px rgba(0,0,0,0.22)",zIndex:30,backdropFilter:"blur(6px)"},children:[e.jsx(Ce,{onClick:()=>m(-1),disabled:d===0,icon:Zt,title:"上一页(←)"}),e.jsxs("span",{style:{fontFamily:E,fontSize:p.sm,color:ct.ink,padding:`0 ${t.md}px`,minWidth:52,textAlign:"center",userSelect:"none"},children:[d+1," / ",i.length]}),e.jsx(Ce,{onClick:()=>m(1),disabled:d===i.length-1,icon:ot,title:"下一页(→)"})]})}function Ce({onClick:n,disabled:s,icon:i,title:l}){return e.jsx("button",{onClick:n,disabled:s,title:l,style:{display:"flex",alignItems:"center",justifyContent:"center",width:26,height:26,borderRadius:$.round,border:"none",background:"transparent",color:s?"rgba(232,226,210,0.3)":ct.ink,cursor:s?"default":"pointer",transition:"background 0.15s"},onMouseEnter:d=>{s||(d.currentTarget.style.background="rgba(255,255,255,0.12)")},onMouseLeave:d=>{d.currentTarget.style.background="transparent"},children:e.jsx(i,{size:15})})}function Xn({edits:n=[],onApply:s,onUndo:i,onClearAll:l,canUndo:d=!1,isRunning:f=!1}){const m=n.length;if(m===0)return null;const c=Yn(n);return e.jsxs("div",{style:{position:"absolute",bottom:16,left:"50%",transform:"translateX(-50%)",background:"rgba(45, 36, 24, 0.94)",color:r.btnText,borderRadius:$.lg,padding:`${t.sm}px ${t.lg}px`,display:"flex",alignItems:"center",gap:t.md,fontFamily:E,fontSize:p.xs,boxShadow:"0 8px 32px rgba(0,0,0,0.25), 0 2px 8px rgba(0,0,0,0.18)",zIndex:50,backdropFilter:"blur(8px)",WebkitBackdropFilter:"blur(8px)"},children:[e.jsx("span",{style:{padding:`${t.xxs}px ${t.md}px`,background:"rgba(245, 240, 232, 0.15)",borderRadius:$.xl,fontWeight:600,minWidth:22,textAlign:"center"},children:m}),e.jsxs("span",{style:{color:"#dfd6c6"},children:[c," 待应用"]}),e.jsx("div",{style:{width:1,height:18,background:"rgba(245,240,232,0.2)"}}),e.jsxs("button",{onClick:i,disabled:!d,title:d?"撤销最近一次 (Cmd+Z)":"无可撤销操作",style:{...Je,opacity:d?1:.4,cursor:d?"pointer":"not-allowed"},children:[e.jsx(Ct,{size:11})," 撤销"]}),e.jsxs("button",{onClick:l,title:"全部撤销 — 把所有 pending 编辑清掉",style:Je,children:[e.jsx(ue,{size:11})," 全部撤销"]}),e.jsxs("button",{onClick:s,disabled:f,title:f?"agent 正在跑,等当前 run 结束":"让 agent 把这些调整落到源代码",style:{...Zn,opacity:f?.6:1,cursor:f?"wait":"pointer"},children:[e.jsx(Jt,{size:11})," 应用"]})]})}function Yn(n){const s={move:0,style:0,dup:0,del:0};for(const l of n)l.kind==="pending-move"?s.move++:l.kind==="pending-style"?s.style++:l.kind==="pending-duplicate"?s.dup++:l.kind==="pending-delete"&&s.del++;const i=[];return s.move&&i.push(`${s.move} 拖动`),s.dup&&i.push(`${s.dup} 复制`),s.style&&i.push(`${s.style} 样式`),s.del&&i.push(`${s.del} 删除`),i.join(" · ")||"调整"}const Je={display:"inline-flex",alignItems:"center",gap:t.xs,padding:`${t.xs}px ${t.base}px`,fontFamily:"inherit",fontSize:p.xs,color:r.btnText,background:"transparent",border:"1px solid rgba(245,240,232,0.25)",borderRadius:$.sm},Zn={display:"inline-flex",alignItems:"center",gap:t.xs,padding:"5px 14px",fontFamily:"inherit",fontSize:p.xs,fontWeight:600,color:r.btn,background:r.btnText,border:"none",borderRadius:$.sm,boxShadow:"0 1px 2px rgba(0,0,0,0.15)"},Qe=ut.purple,Cn=Qt(ut.purple,.18);function Jn({edits:n=[],iframeRef:s,zoom:i=1}){const[,l]=o.useState(0);o.useEffect(()=>{if(n.length===0)return;const x=s==null?void 0:s.current;if(!x)return;const v=x.contentWindow;if(!v)return;let k=null;const b=()=>{k||(k=requestAnimationFrame(()=>{k=null,l(F=>F+1)}))};try{v.addEventListener("scroll",b,{passive:!0,capture:!0}),v.addEventListener("resize",b),window.addEventListener("resize",b)}catch{}return()=>{try{v.removeEventListener("scroll",b,{capture:!0}),v.removeEventListener("resize",b),window.removeEventListener("resize",b)}catch{}k&&cancelAnimationFrame(k)}},[n.length,s]);const d=o.useMemo(()=>n.filter(x=>(x.kind==="pending-move"||x.kind==="pending-duplicate")&&x.reactMount===!0),[n]);if(d.length===0||!(s!=null&&s.current))return null;const f=s.current,m=f.contentDocument;if(!m)return null;const c=f.getBoundingClientRect(),y=pn(f);if(!y)return null;const u=f.contentWindow,a=(u==null?void 0:u.innerWidth)??c.width/i,w=(u==null?void 0:u.innerHeight)??c.height/i;return e.jsx(e.Fragment,{children:d.map((x,v)=>{var h;const k=dt(x.anchor,m.body);if(!k)return null;const b=k.getBoundingClientRect();if(b.bottom<=0||b.top>=w||b.right<=0||b.left>=a)return null;const{top:F,left:W}=gn(y,b.left,b.top,i),j=b.width*i,T=b.height*i,H=(h=x.aiContext)!=null&&h.targetContainerTag?`${x.aiContext.targetContainerTag}`:"目标容器";return e.jsxs("div",{style:{position:"absolute",top:0,left:0,pointerEvents:"none"},children:[e.jsx("div",{style:{position:"absolute",pointerEvents:"none",top:F-3,left:W-3,width:j+6,height:T+6,border:`2px dashed ${Qe}`,borderRadius:$.sm,boxShadow:`0 0 0 3px ${Cn}`,zIndex:9}}),e.jsxs("div",{style:{position:"absolute",pointerEvents:"none",top:F-12,left:W+j-8,transform:"translateX(-100%)",padding:`${t.xxs}px ${t.sm}px`,fontFamily:E,fontSize:p.xs,lineHeight:"14px",fontWeight:500,color:r.bgWhite,background:Qe,borderRadius:$.xs,whiteSpace:"nowrap",boxShadow:at.crisp,zIndex:11,maxWidth:Math.max(120,j),overflow:"hidden",textOverflow:"ellipsis"},children:[x.kind==="pending-duplicate"?"复制到":"移到"," <",H,">"]})]},v)})})}const je={"16:9":{w:1920,h:1080},"16:10":{w:1920,h:1200},"9:16":{w:1080,h:1920},"4:3":{w:1440,h:1080}},Se="16:9";function Qn(n){if(!n||typeof n!="string")return Se;const s=n.match(/<div\b[^>]*class\s*=\s*['"][^'"]*__nd-deck-wrap[^'"]*['"][^>]*data-deck-aspect\s*=\s*['"]([^'"]+)['"]/i)||n.match(/<div\b[^>]*data-deck-aspect\s*=\s*['"]([^'"]+)['"][^>]*class\s*=\s*['"][^'"]*__nd-deck-wrap[^'"]*['"]/i);return s&&je[s[1]]?s[1]:Se}function ss({tab:n,onTabChange:s,onClose:i,artifactExports:l=null,onExport:d=null,onToolbarGroups:f=null,title:m="幻灯",htmlSrc:c,htmlContent:y,selectedAnchor:u,onSelectChange:a,onTextEdit:w,onIframeReady:x,candidates:v,activeCandidateId:k,onSelectCandidate:b,onAddCandidate:F,onRemoveCandidate:W,onRenameCandidate:j,project:T,deckSpec:H,projectId:h,sessionId:P,decisionsReloadKey:D,comments:_=[],onAddComment:ee,onResolveComment:K,onDeleteComment:V,onRegionComment:L=null,tweaksAvailable:q=!1,pendingEdits:xe=[],onCommitMove:U,onCommitFreePosition:pe,onSubmitDragNote:gt,lastPendingEditId:ft=null,onApplyPendingEdits:ht,onUndoPending:mt,onClearAllPending:yt,canUndoPending:bt=!1,isStreaming:G=!1}){var Me,Re,Oe,He,De,_e,Ie,Ne,qe,Ue;const{panels:ge,setPanelVisible:wt}=en(),fe=!!((Me=ge==null?void 0:ge.tweaks)!=null&&Me.visible),vt=()=>wt("tweaks",!fe),[X,Ee]=o.useState(!1);o.useEffect(()=>{G&&n==="drag"&&(s==null||s("edit"))},[G,n,s]);const kt=o.useRef(null),[he,jt]=o.useState(!1),[Le,St]=o.useState(null),[zt,Fe]=o.useState(!1),[Y,te]=o.useState("fit"),[Z,$t]=o.useState({width:0,height:0}),[Ae,Et]=o.useState(0),[me,ne]=o.useState(""),[ye,se]=o.useState(!1),[I,Te]=o.useState(null),[be,re]=o.useState(!1),[C,ie]=o.useState(!1),[J,le]=o.useState(!1),[oe,Pe]=o.useState(!0),O=o.useRef(null),we=o.useRef(null),We=o.useRef(null);o.useEffect(()=>{if(!h||!P)return;let g=!1;return Ke.read(h).then(({config:S})=>{g||S&&typeof S.tweaks_mode_enabled=="boolean"&&Pe(S.tweaks_mode_enabled)}).catch(()=>{}),()=>{g=!0}},[h,P]);const Lt=o.useCallback(g=>{Pe(g),!(!h||!P)&&Ke.patch(h,{tweaks_mode_enabled:g}).catch(()=>{})},[h,P]);o.useEffect(()=>{const g=O.current;if(!g)return;const S=()=>{const M=g.getBoundingClientRect();$t(R=>R.width===M.width&&R.height===M.height?R:{width:M.width,height:M.height})};S();let A=null;try{A=new ResizeObserver(S),A.observe(g)}catch{}return window.addEventListener("resize",S),()=>{A&&A.disconnect(),window.removeEventListener("resize",S)}},[n]);const Be=Qn(me),ae=je[Be]||je[Se],B=Y==="fit"?Z.width>0&&Z.height>0?Math.min(Z.width/ae.w,Z.height/ae.h):1:Y,Ft=v&&v.length>=1;o.useEffect(()=>{se(!1),Te(null)},[k]),o.useEffect(()=>{const g=A=>{var R;if(A.key!=="Escape")return;const M=A.target;((R=M==null?void 0:M.getAttribute)==null?void 0:R.call(M,"contenteditable"))!=="true"&&(C||be||J||(u?a==null||a(null):i==null||i()))};window.addEventListener("keydown",g);let S=null;try{S=I,S==null||S.addEventListener("keydown",g)}catch{}return()=>{window.removeEventListener("keydown",g);try{S==null||S.removeEventListener("keydown",g)}catch{}}},[u,I,a,i,C,be,J]),o.useEffect(()=>{const g=S=>{const A=S==null?void 0:S.data;if(!(!A||typeof A!="object")&&A.type==="canvas-page-change"&&Number.isFinite(A.page))try{window.dispatchEvent(new CustomEvent("nd-canvas-page-change",{detail:{page:A.page}}))}catch{}};return window.addEventListener("message",g),()=>window.removeEventListener("message",g)},[]),o.useEffect(()=>{if(!c){ne(y||""),se(!1);return}fetch(c).then(g=>g.text()).then(g=>{ne(g),se(!1)}).catch(()=>ne("<!-- 无法加载源码 -->"))},[c,y,Ae]);const At=g=>{a==null||a((g==null?void 0:g.anchor)||null)},Tt=g=>{w==null||w(g),console.log("[direct edit]",g)},Pt=o.useCallback(g=>{ne(g),se(!0)},[]),Wt=o.useCallback(g=>{try{Te(g.contentDocument)}catch{}x==null||x(g)},[x]),Bt=()=>{Et(g=>g+1),a==null||a(null)},Mt=()=>{re(!1),ie(!1),le(g=>!g)},Rt=()=>{re(!1),le(!1),ie(g=>!g)},ve=Array.isArray(_)?_.filter(g=>g.status!=="resolved").length:0,Ot=o.useMemo(()=>[cn({kind:"deck",exports:l,onExport:d}),{id:"mode",type:"mode",value:n,onChange:g=>{s==null||s(g),a==null||a(null)},items:[{id:"preview",icon:$n,label:"预览",title:"看成品(左右键翻页)"},{id:"edit",icon:tn,label:"编辑",title:"双击文字直接改 · 单击元素弹评论卡"},{id:"drag",icon:nn,label:"拖拽",disabled:G,title:G?"agent 正在跑,拖拽暂停以免和它抢同一份源码":"拖动元素调布局"},{id:"region",icon:En,label:"圈选",disabled:!L,title:L?"框一块地方说事 —— 框住谁、当时长什么样、你想说什么,一起交给 agent":"要先开一个会话才能把圈选交给 agent"},{id:"code",icon:sn,label:"源码",title:"看/改这一份 HTML"}]},n==="drag"&&{id:"dragmode",items:[{id:"free",icon:rn,label:X?"自由":"嵌入",active:X,title:X?"自由摆放 · 松手落到像素位置(P 切回嵌入)":"嵌入 · 松手按 DOM 树插进容器(P 切自由摆放)",onClick:()=>Ee(g=>!g)}]},n!=="code"&&{id:"zoom",items:[{id:"zoomOut",icon:ln,title:"缩小",onClick:()=>te(Math.max(.25,B-.1))},{id:"zoomLevel",label:`${Math.round(B*100)}%`,active:Y==="fit",title:Y==="fit"?"当前自适应窗口":"点一下自适应窗口",onClick:()=>te("fit")},{id:"zoomIn",icon:tt,title:"放大",onClick:()=>te(Math.min(3,B+.1))},{id:"fit",icon:on,title:"自适应窗口",onClick:()=>te("fit")}]},{id:"actions",items:[{id:"tweaks",icon:an,active:fe,disabled:!oe,title:oe?q?"Tweaks:拖控件实时改样式":"Tweaks(agent 还没暴露参数 — 跟它说一句让它 expose_tweaks)":"Tweaks 模式已关(在 System 里开)",onClick:vt},{id:"comment",icon:xt,label:ve>0?String(ve):void 0,active:J,btnRef:We,title:"这一份上已有的评论",onClick:Mt},{id:"reload",icon:dn,title:"重载(agent 改完没刷新时用)",onClick:Bt},{id:"system",icon:lt,active:C,btnRef:we,title:"System:项目档案 / Tweaks 模式 / A11y",onClick:Rt}]}].filter(Boolean),[n,G,X,Y,B,fe,oe,q,J,C,ve,L,l,d]);return e.jsxs(un,{kind:"deck",title:m,subtitle:Be,onClose:i,escToClose:!1,groups:Ot,onToolbarGroups:f,headerExtra:Ft?e.jsx(Pn,{candidates:v,activeId:k,onSelect:b,onAdd:F,onRemove:W,onRename:j}):null,children:[(n==="edit"||n==="preview"||n==="drag"||n==="region")&&e.jsxs("div",{ref:O,style:{flex:1,minHeight:0,position:"relative",display:"flex",flexDirection:"column"},children:[e.jsx(Tn,{src:ye?void 0:c,srcDoc:ye?me:c?void 0:y,mode:n==="drag"||n==="region"?"preview":n,onSelect:At,onTextEdit:Tt,onIframeReady:Wt,zoom:B,deckW:ae.w,deckH:ae.h},`${k||"default"}-${Ae}-${ye?"doc":"src"}`),n==="edit"&&u&&e.jsx(fn,{selectedAnchor:u,iframeRef:{current:(Re=O.current)==null?void 0:Re.querySelector("iframe")},zoom:B}),e.jsx(hn,{comments:_,iframeRef:{current:(Oe=O.current)==null?void 0:Oe.querySelector("iframe")},zoom:B,onSelectAnchor:g=>{n!=="edit"&&(s==null||s("edit")),a==null||a(g)}}),e.jsx(Jn,{edits:xe,iframeRef:{current:(He=O.current)==null?void 0:He.querySelector("iframe")},zoom:B}),e.jsx(Vn,{iframeDoc:I,active:n==="preview"}),e.jsx(mn,{active:n==="drag"&&!he,iframeRef:{current:(De=O.current)==null?void 0:De.querySelector("iframe")},zoom:B,pickDragSource:yn,isDragging:he}),e.jsx(bn,{active:n==="drag",iframeRef:{current:(_e=O.current)==null?void 0:_e.querySelector("iframe")},zoom:B,freeMode:X,onFreeModeChange:Ee,apiRef:kt,onDraggingChange:jt,onSelectionChange:g=>{St(g),g&&Fe(!0)},onCommitMove:(g,S)=>{var M;if(S.duplicate){const R=(M=S.sourceEl)==null?void 0:M.cloneNode(!0);let Ge=()=>{};if(R&&S.targetContainer){try{R.removeAttribute("data-anchor")}catch{}S.beforeEl&&S.beforeEl.parentNode===S.targetContainer?S.targetContainer.insertBefore(R,S.beforeEl):S.targetContainer.appendChild(R),Ge=()=>{try{R.remove()}catch{}}}U==null||U(g,Ge);return}const A=vn({iframeDoc:I,sourceEl:S.sourceEl,targetContainer:S.targetContainer,beforeEl:S.beforeEl});U==null||U(g,A==null?void 0:A.revert)},onCommitFreePosition:(g,S)=>{const A=wn({sourceEl:S.sourceEl,parentEl:S.parentEl,styleDelta:g.styleDelta,runtimeLocks:g.runtimeLocks,parentNeedsRelative:g.parentNeedsRelative});pe==null||pe(g,A==null?void 0:A.revert)}}),e.jsx(kn,{active:n==="drag"&&zt&&!he&&!!Le,iframeRef:{current:(Ie=O.current)==null?void 0:Ie.querySelector("iframe")},zoom:B,sourceEl:Le,hasPendingEditId:!!ft,onSubmit:gt,onDismiss:()=>Fe(!1)}),n==="edit"&&u&&I&&e.jsx(jn,{selectedAnchor:u,iframeDoc:I,iframeRef:{current:(Ne=O.current)==null?void 0:Ne.querySelector("iframe")},iframeRect:Z,zoom:B,comments:_,onClose:()=>a==null?void 0:a(null),onAddComment:ee,onResolveComment:K,onDeleteComment:V}),e.jsx(Sn,{active:n==="region"&&!!L,iframeRef:{current:(qe=O.current)==null?void 0:qe.querySelector("iframe")},zoom:B,onSubmit:g=>L==null?void 0:L(g),onExit:()=>s==null?void 0:s("preview")}),e.jsx(Xn,{edits:xe,onApply:ht,onUndo:mt,onClearAll:yt,canUndo:bt,isRunning:G})]}),n==="code"&&e.jsx(zn,{value:me,onChange:Pt,readOnly:!1}),be&&e.jsx(Mn,{anchorRef:we,onClose:()=>re(!1),iframeDoc:I}),C&&e.jsx(qn,{anchorRef:we,onClose:()=>ie(!1),project:T,deckSpec:H,projectId:h,sessionId:P,decisionsReloadKey:D,onA11yClick:()=>{ie(!1),re(!0)},tweaksEnabled:oe,onTweaksEnabledChange:Lt}),J&&e.jsx(Gn,{comments:_,iframeDoc:I,iframeRef:{current:(Ue=O.current)==null?void 0:Ue.querySelector("iframe")},anchorRef:We,onClose:()=>le(!1),onResolveComment:K,onDeleteComment:V,onSelectAnchor:g=>{le(!1),n!=="edit"&&(s==null||s("edit")),a==null||a(g)}})]})}export{ss as default};
16
+ `})]})}function In({decision:n}){return e.jsxs("div",{style:{padding:t.md,marginBottom:t.sm,borderRadius:2,background:r.bgWhite,boxShadow:ze.far},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:t.xs,marginBottom:t.xs},children:[e.jsx(Gt,{size:11,color:r.text4}),e.jsx("div",{style:{flex:1,fontFamily:z,fontSize:p.sm,fontWeight:500,color:r.text,lineHeight:1.4},children:n.title||"(no title)"})]}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.text4,lineHeight:1.5,marginBottom:t.xs,whiteSpace:"pre-wrap",wordBreak:"break-word"},children:n.rationale}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:t.sm,fontFamily:E,fontSize:p.xs,color:r.sub},children:[n.scope&&e.jsxs("span",{children:["scope: ",n.scope]}),e.jsx("span",{children:pt(n.ts)})]}),Array.isArray(n.alternatives)&&n.alternatives.length>0&&e.jsxs("details",{style:{marginTop:t.xs},children:[e.jsxs("summary",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,cursor:"pointer"},children:["考虑过的替代 (",n.alternatives.length,")"]}),e.jsx("ul",{style:{margin:`${t.xs}px 0 0 0`,paddingLeft:t.xl,fontFamily:z,fontSize:p.xs,color:r.text4,lineHeight:1.5},children:n.alternatives.map((s,i)=>e.jsx("li",{children:s},i))})]})]})}function qn({entry:n}){var s;return e.jsxs("div",{style:{padding:t.md,marginBottom:t.sm,borderLeft:`2px solid ${r.borderMd}`,paddingLeft:t.md},children:[e.jsxs("div",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,marginBottom:t.xs,letterSpacing:"0.04em"},children:[((s=n.source)==null?void 0:s.toUpperCase())||"COMPACT"," · ",pt(n.ts),n.trigger&&n.trigger!=="auto"&&` · ${n.trigger}`]}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.text4,lineHeight:1.5,whiteSpace:"pre-wrap"},children:n.summary})]})}function pt(n){if(!n)return"";try{return new Date(n).toLocaleString("zh-CN",{month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"})}catch{return n}}function Nn({anchorRef:n,onClose:s,project:i,deckSpec:l,projectId:d,sessionId:f,decisionsReloadKey:m=0,onA11yClick:c,tweaksEnabled:y=null,onTweaksEnabledChange:u=null}){const a=q(j=>j.canvasFont),w=q(j=>j.followAgent),x=q(j=>j.setFollowAgent),v=q(j=>j.setCanvasFont),k=o.useRef(null),[b,L]=o.useState(!1),W=$e(n,360);return o.useEffect(()=>{const j=T=>{var H;k.current&&!k.current.contains(T.target)&&!((H=n==null?void 0:n.current)!=null&&H.contains(T.target))&&(s==null||s())};return window.addEventListener("mousedown",j),()=>window.removeEventListener("mousedown",j)},[s,n]),o.useEffect(()=>{const j=T=>{T.key==="Escape"&&(s==null||s())};return window.addEventListener("keydown",j),()=>window.removeEventListener("keydown",j)},[s]),e.jsxs("div",{ref:k,style:{...W,width:360,background:r.bgWhite,borderRadius:2,boxShadow:"0 2px 4px rgba(0,0,0,0.04), 0 8px 20px rgba(0,0,0,0.08), 0 24px 48px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.8)",zIndex:60,display:"flex",flexDirection:"column",overflow:"hidden"},children:[e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,display:"flex",alignItems:"center",gap:t.sm,borderBottom:`1px solid ${r.borderLt}`,flexShrink:0},children:[e.jsx(lt,{size:12,color:r.text4}),e.jsx("span",{style:{fontFamily:E,fontSize:p.sm,fontWeight:500,color:r.text},children:"System"})]}),e.jsxs("div",{style:{flex:1,minHeight:0,overflowY:"auto"},children:[c&&e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`,display:"flex",flexDirection:"column",gap:t.sm},children:[e.jsx("div",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em"},children:"Canvas 工具"}),e.jsx("div",{style:{display:"flex",gap:t.sm},children:e.jsxs("button",{onClick:()=>{c(),s==null||s()},style:Un,title:"无障碍审查(mock)",children:[e.jsx(Fn,{size:11})," A11y"]})})]}),u&&e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`,display:"flex",alignItems:"center",gap:t.sm},children:[e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text},children:"Tweaks 模式"}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,marginTop:2,lineHeight:1.5},children:y?"开:agent 会主动把核心参数做成控件让你拖":"关:不暴露控件,改样式走对话"})]}),e.jsx(Ze,{checked:!!y,onChange:u})]}),e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`,display:"flex",alignItems:"center",gap:t.sm},children:[e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text},children:"镜头跟随 agent"}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,marginTop:2,lineHeight:1.5},children:w?"开:agent 换到哪个产物,镜头就飞过去(你操作后 8 秒内不抢)":"关:镜头只听你的;agent 在动什么看光圈"})]}),e.jsx(Ze,{checked:w,onChange:x})]}),e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`},children:[e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text},children:"画布手写字体"}),e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,marginTop:2,marginBottom:t.sm},children:"用「文字」工具(T)在画布上写字时用这个"}),e.jsx("div",{style:{display:"flex",gap:t.xs,flexWrap:"wrap"},children:Object.entries(Xt).map(([j,T])=>e.jsx("button",{onClick:()=>v({...a,font:j}),style:{padding:`${t.xs}px ${t.sm}px`,borderRadius:$.md,cursor:"pointer",fontFamily:Kt[j],fontSize:p.sm,border:`1px solid ${a.font===j?r.text:r.borderLt}`,background:a.font===j?r.text:"transparent",color:a.font===j?r.bg:r.text2},children:T},j))}),e.jsx("div",{style:{display:"flex",gap:t.xs,marginTop:t.sm},children:Object.entries(Vt).map(([j,T])=>e.jsx("button",{onClick:()=>v({...a,size:j}),style:{padding:`${t.xs}px ${t.sm}px`,borderRadius:$.md,cursor:"pointer",fontFamily:z,fontSize:p.xs,border:`1px solid ${a.size===j?r.text:r.borderLt}`,background:a.size===j?r.text:"transparent",color:a.size===j?r.bg:r.text2},children:T},j))})]}),e.jsx(Hn,{project:i,deckSpec:l,projectId:d}),e.jsxs("div",{style:{borderTop:`1px solid ${r.borderLt}`,padding:`${t.md}px ${t.lg}px 0`},children:[e.jsxs("button",{onClick:()=>L(j=>!j),style:{display:"flex",alignItems:"center",gap:t.xs,width:"100%",padding:`${t.xs}px 0`,background:"transparent",border:"none",fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em",cursor:"pointer"},children:[e.jsx(ot,{size:11,style:{transform:b?"rotate(90deg)":"rotate(0deg)",transition:"transform 0.12s ease"}}),"项目档案 — Decisions / History"]}),!b&&e.jsx("div",{style:{fontFamily:z,fontSize:p.xs,color:r.sub,padding:`${t.xs}px 0 ${t.md}px ${t.lg}px`,lineHeight:1.5},children:"展开看 agent 记录的设计决策 + compact 摘要历史。"})]}),b&&e.jsx("div",{style:{background:"rgba(0,0,0,0.015)",margin:`0 ${t.lg}px ${t.md}px`,border:`1px solid ${r.borderLt}`,borderRadius:$.md},children:e.jsx(Dn,{projectId:d,sessionId:f,reloadKey:m})})]}),e.jsx("div",{style:{padding:`${t.sm}px ${t.lg}px`,background:r.bgCard,borderTop:`1px solid ${r.borderLt}`,fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.5,flexShrink:0},children:"spec 不可在此编辑 — 改 spec 跟 agent 说,触发新 run。"})]})}function Ze({checked:n,onChange:s,title:i}){return e.jsx("button",{onClick:()=>s==null?void 0:s(!n),title:i,style:{width:28,height:16,padding:0,border:"none",borderRadius:$.lg,background:n?r.text:"rgba(0,0,0,0.18)",position:"relative",cursor:"pointer",transition:"background 0.15s",flexShrink:0},children:e.jsx("span",{style:{position:"absolute",top:2,left:n?14:2,width:12,height:12,borderRadius:$.round,background:r.bgWhite,boxShadow:at.crispSm,transition:"left 0.15s"}})})}const Un={padding:`${t.xs+1}px ${t.md}px`,fontFamily:E,fontSize:p.xs,color:r.text4,background:"rgba(0,0,0,0.04)",border:"none",borderRadius:$.sm,display:"inline-flex",alignItems:"center",gap:t.xs,cursor:"pointer"};function Gn({comments:n=[],iframeDoc:s,iframeRef:i,anchorRef:l,onClose:d,onResolveComment:f,onDeleteComment:m,onSelectAnchor:c}){const y=o.useRef(null),u=$e(l,380);o.useEffect(()=>{const x=v=>{var k;y.current&&!y.current.contains(v.target)&&!((k=l==null?void 0:l.current)!=null&&k.contains(v.target))&&(d==null||d())};return window.addEventListener("mousedown",x),()=>window.removeEventListener("mousedown",x)},[d,l]),o.useEffect(()=>{const x=v=>{v.key==="Escape"&&(d==null||d())};return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[d]);const a=o.useMemo(()=>{const x=new Map;for(const k of n){const b=s&&k.anchor?dt(k.anchor,s.body):null,L=b?Yt(b):null,W=(L==null?void 0:L.index)??null;x.has(W)||x.set(W,[]),x.get(W).push({comment:k,el:b})}return[...x.entries()].sort((k,b)=>k[0]===null?1:b[0]===null?-1:k[0]-b[0])},[n,s]),w=x=>{if(x.el)try{x.el.scrollIntoView({behavior:"smooth",block:"center"})}catch{}c&&c(x.comment.anchor)};return e.jsxs("div",{ref:y,style:{...u,width:380,background:r.bgWhite,borderRadius:2,boxShadow:"0 2px 4px rgba(0,0,0,0.04), 0 8px 20px rgba(0,0,0,0.08), 0 24px 48px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.8)",zIndex:60,display:"flex",flexDirection:"column",overflow:"hidden"},children:[e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,display:"flex",alignItems:"center",gap:t.sm,borderBottom:`1px solid ${r.borderLt}`,flexShrink:0},children:[e.jsx(xt,{size:12,color:r.text4}),e.jsxs("span",{style:{fontFamily:E,fontSize:p.sm,fontWeight:500,color:r.text,flex:1},children:["全部评论 ",n.length>0&&`(${n.length})`]}),e.jsx("button",{onClick:d,title:"关闭",style:{padding:t.xs,color:r.text5,borderRadius:$.xs,background:"transparent",border:"none",cursor:"pointer"},children:e.jsx(ue,{size:12})})]}),e.jsx("div",{style:{flex:1,minHeight:0,overflowY:"auto"},children:n.length===0?e.jsxs("div",{style:{padding:`${t.lg+t.md}px ${t.lg}px`,fontFamily:z,fontSize:p.sm,color:r.sub,textAlign:"center",lineHeight:1.6},children:["还没有评论。",e.jsx("br",{}),"点击画布上任意元素 → 在弹出的浮卡里写评论。"]}):a.map(([x,v])=>e.jsxs("div",{style:{padding:`${t.md}px ${t.lg}px`,borderBottom:`1px solid ${r.borderLt}`},children:[e.jsxs("div",{style:{fontFamily:E,fontSize:p.xs,color:r.sub,textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:t.sm},children:[x===null?"未定位":`第 ${x+1} 页`," · ",v.length," 条"]}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:t.xs},children:v.map(({comment:k,el:b})=>e.jsx(Xn,{comment:k,available:!!b,onClick:()=>w({comment:k,el:b}),onResolve:()=>f==null?void 0:f(k.id),onDelete:()=>m==null?void 0:m(k.id)},k.id))})]},x??"orphan"))}),e.jsx("div",{style:{padding:`${t.sm}px ${t.lg}px`,background:r.bgCard,borderTop:`1px solid ${r.borderLt}`,fontFamily:z,fontSize:p.xs,color:r.sub,lineHeight:1.5,flexShrink:0},children:"点击评论 → 跳到对应元素;evaluator 切到 edit 模式后可在浮卡续写。"})]})}function Xn({comment:n,available:s,onClick:i,onResolve:l,onDelete:d}){var m,c,y;const f=n.status==="resolved";return e.jsxs("div",{style:{padding:`${t.sm}px ${t.md}px`,background:r.bgWhite,boxShadow:ze.far,borderRadius:$.md,display:"flex",flexDirection:"column",gap:t.xs,opacity:f?.5:1,cursor:s?"pointer":"default",transition:"background 0.1s"},onClick:s?i:void 0,onMouseEnter:u=>{s&&(u.currentTarget.style.background="rgba(0,0,0,0.02)")},onMouseLeave:u=>{u.currentTarget.style.background=r.bgWhite},children:[e.jsx("div",{style:{fontFamily:z,fontSize:p.sm,color:r.text2,lineHeight:1.5,textDecoration:f?"line-through":"none",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:n.text}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:t.xs,fontFamily:E,fontSize:p.xs,color:r.sub},children:[s?e.jsxs(e.Fragment,{children:[e.jsx(xn,{size:9}),e.jsx("span",{children:((m=n.anchor)==null?void 0:m.dataId)||((y=(c=n.anchor)==null?void 0:c.path)==null?void 0:y.split(">").pop())||"元素"})]}):e.jsx("span",{style:{fontStyle:"italic"},children:"元素已不在"}),e.jsx("span",{style:{flex:1}}),e.jsx("button",{onClick:u=>{u.stopPropagation(),l()},title:f?"取消解决":"标记解决",style:{padding:t.xxs,color:r.sub,borderRadius:$.xs,background:"transparent",border:"none",cursor:"pointer"},children:e.jsx(st,{size:11})}),e.jsx("button",{onClick:u=>{u.stopPropagation(),d()},title:"删除",style:{padding:t.xxs,color:r.sub,borderRadius:$.xs,background:"transparent",border:"none",cursor:"pointer"},children:e.jsx(it,{size:11})})]})]})}function Kn({iframeDoc:n,active:s}){const[i,l]=o.useState([]),[d,f]=o.useState(0);o.useEffect(()=>{if(!s||!n){l([]);return}let c=null;const y=()=>{const a=Array.from(n.querySelectorAll("section[data-page]"));if(l(a),c&&c.disconnect(),!!a.length)try{c=new(n.defaultView||window).IntersectionObserver(w=>{const x=w.filter(k=>k.isIntersecting).sort((k,b)=>b.intersectionRatio-k.intersectionRatio)[0];if(!x)return;const v=a.indexOf(x.target);v>=0&&f(v)},{threshold:[.35,.6]}),a.forEach(w=>c.observe(w))}catch{}};y();let u=null;try{u=new(n.defaultView||window).MutationObserver(()=>y()),n.body&&u.observe(n.body,{childList:!0,subtree:!0})}catch{}return()=>{c==null||c.disconnect(),u==null||u.disconnect()}},[n,s]);const m=o.useCallback(c=>{f(y=>{const u=Math.max(0,Math.min(i.length-1,y+c)),a=i[u];if(a)try{a.scrollIntoView({behavior:"smooth",block:"start"})}catch{}return u})},[i]);return o.useEffect(()=>{if(!s||i.length<2)return;const c=u=>{if(u.key!=="ArrowLeft"&&u.key!=="ArrowRight")return;const a=u.target;a&&(a.tagName==="INPUT"||a.tagName==="TEXTAREA"||a.isContentEditable)||(u.preventDefault(),m(u.key==="ArrowRight"?1:-1))};window.addEventListener("keydown",c);let y=null;try{y=n,y==null||y.addEventListener("keydown",c)}catch{}return()=>{window.removeEventListener("keydown",c);try{y==null||y.removeEventListener("keydown",c)}catch{}}},[s,i.length,m,n]),!s||i.length<2?null:e.jsxs("div",{style:{position:"absolute",bottom:16,left:"50%",transform:"translateX(-50%)",display:"flex",alignItems:"center",gap:t.xxs,background:"rgba(28,24,18,0.86)",borderRadius:$.pill,padding:t.xs,boxShadow:"0 6px 22px rgba(0,0,0,0.22)",zIndex:30,backdropFilter:"blur(6px)"},children:[e.jsx(Ce,{onClick:()=>m(-1),disabled:d===0,icon:Zt,title:"上一页(←)"}),e.jsxs("span",{style:{fontFamily:E,fontSize:p.sm,color:ct.ink,padding:`0 ${t.md}px`,minWidth:52,textAlign:"center",userSelect:"none"},children:[d+1," / ",i.length]}),e.jsx(Ce,{onClick:()=>m(1),disabled:d===i.length-1,icon:ot,title:"下一页(→)"})]})}function Ce({onClick:n,disabled:s,icon:i,title:l}){return e.jsx("button",{onClick:n,disabled:s,title:l,style:{display:"flex",alignItems:"center",justifyContent:"center",width:26,height:26,borderRadius:$.round,border:"none",background:"transparent",color:s?"rgba(232,226,210,0.3)":ct.ink,cursor:s?"default":"pointer",transition:"background 0.15s"},onMouseEnter:d=>{s||(d.currentTarget.style.background="rgba(255,255,255,0.12)")},onMouseLeave:d=>{d.currentTarget.style.background="transparent"},children:e.jsx(i,{size:15})})}function Vn({edits:n=[],onApply:s,onUndo:i,onClearAll:l,canUndo:d=!1,isRunning:f=!1}){const m=n.length;if(m===0)return null;const c=Yn(n);return e.jsxs("div",{style:{position:"absolute",bottom:16,left:"50%",transform:"translateX(-50%)",background:"rgba(45, 36, 24, 0.94)",color:r.btnText,borderRadius:$.lg,padding:`${t.sm}px ${t.lg}px`,display:"flex",alignItems:"center",gap:t.md,fontFamily:E,fontSize:p.xs,boxShadow:"0 8px 32px rgba(0,0,0,0.25), 0 2px 8px rgba(0,0,0,0.18)",zIndex:50,backdropFilter:"blur(8px)",WebkitBackdropFilter:"blur(8px)"},children:[e.jsx("span",{style:{padding:`${t.xxs}px ${t.md}px`,background:"rgba(245, 240, 232, 0.15)",borderRadius:$.xl,fontWeight:600,minWidth:22,textAlign:"center"},children:m}),e.jsxs("span",{style:{color:"#dfd6c6"},children:[c," 待应用"]}),e.jsx("div",{style:{width:1,height:18,background:"rgba(245,240,232,0.2)"}}),e.jsxs("button",{onClick:i,disabled:!d,title:d?"撤销最近一次 (Cmd+Z)":"无可撤销操作",style:{...Qe,opacity:d?1:.4,cursor:d?"pointer":"not-allowed"},children:[e.jsx(Ct,{size:11})," 撤销"]}),e.jsxs("button",{onClick:l,title:"全部撤销 — 把所有 pending 编辑清掉",style:Qe,children:[e.jsx(ue,{size:11})," 全部撤销"]}),e.jsxs("button",{onClick:s,disabled:f,title:f?"agent 正在跑,等当前 run 结束":"让 agent 把这些调整落到源代码",style:{...Zn,opacity:f?.6:1,cursor:f?"wait":"pointer"},children:[e.jsx(Qt,{size:11})," 应用"]})]})}function Yn(n){const s={move:0,style:0,dup:0,del:0};for(const l of n)l.kind==="pending-move"?s.move++:l.kind==="pending-style"?s.style++:l.kind==="pending-duplicate"?s.dup++:l.kind==="pending-delete"&&s.del++;const i=[];return s.move&&i.push(`${s.move} 拖动`),s.dup&&i.push(`${s.dup} 复制`),s.style&&i.push(`${s.style} 样式`),s.del&&i.push(`${s.del} 删除`),i.join(" · ")||"调整"}const Qe={display:"inline-flex",alignItems:"center",gap:t.xs,padding:`${t.xs}px ${t.base}px`,fontFamily:"inherit",fontSize:p.xs,color:r.btnText,background:"transparent",border:"1px solid rgba(245,240,232,0.25)",borderRadius:$.sm},Zn={display:"inline-flex",alignItems:"center",gap:t.xs,padding:"5px 14px",fontFamily:"inherit",fontSize:p.xs,fontWeight:600,color:r.btn,background:r.btnText,border:"none",borderRadius:$.sm,boxShadow:"0 1px 2px rgba(0,0,0,0.15)"},Je=ut.purple,Cn=Jt(ut.purple,.18);function Qn({edits:n=[],iframeRef:s,zoom:i=1}){const[,l]=o.useState(0);o.useEffect(()=>{if(n.length===0)return;const x=s==null?void 0:s.current;if(!x)return;const v=x.contentWindow;if(!v)return;let k=null;const b=()=>{k||(k=requestAnimationFrame(()=>{k=null,l(L=>L+1)}))};try{v.addEventListener("scroll",b,{passive:!0,capture:!0}),v.addEventListener("resize",b),window.addEventListener("resize",b)}catch{}return()=>{try{v.removeEventListener("scroll",b,{capture:!0}),v.removeEventListener("resize",b),window.removeEventListener("resize",b)}catch{}k&&cancelAnimationFrame(k)}},[n.length,s]);const d=o.useMemo(()=>n.filter(x=>(x.kind==="pending-move"||x.kind==="pending-duplicate")&&x.reactMount===!0),[n]);if(d.length===0||!(s!=null&&s.current))return null;const f=s.current,m=f.contentDocument;if(!m)return null;const c=f.getBoundingClientRect(),y=pn(f);if(!y)return null;const u=f.contentWindow,a=(u==null?void 0:u.innerWidth)??c.width/i,w=(u==null?void 0:u.innerHeight)??c.height/i;return e.jsx(e.Fragment,{children:d.map((x,v)=>{var h;const k=dt(x.anchor,m.body);if(!k)return null;const b=k.getBoundingClientRect();if(b.bottom<=0||b.top>=w||b.right<=0||b.left>=a)return null;const{top:L,left:W}=gn(y,b.left,b.top,i),j=b.width*i,T=b.height*i,H=(h=x.aiContext)!=null&&h.targetContainerTag?`${x.aiContext.targetContainerTag}`:"目标容器";return e.jsxs("div",{style:{position:"absolute",top:0,left:0,pointerEvents:"none"},children:[e.jsx("div",{style:{position:"absolute",pointerEvents:"none",top:L-3,left:W-3,width:j+6,height:T+6,border:`2px dashed ${Je}`,borderRadius:$.sm,boxShadow:`0 0 0 3px ${Cn}`,zIndex:9}}),e.jsxs("div",{style:{position:"absolute",pointerEvents:"none",top:L-12,left:W+j-8,transform:"translateX(-100%)",padding:`${t.xxs}px ${t.sm}px`,fontFamily:E,fontSize:p.xs,lineHeight:"14px",fontWeight:500,color:r.bgWhite,background:Je,borderRadius:$.xs,whiteSpace:"nowrap",boxShadow:at.crisp,zIndex:11,maxWidth:Math.max(120,j),overflow:"hidden",textOverflow:"ellipsis"},children:[x.kind==="pending-duplicate"?"复制到":"移到"," <",H,">"]})]},v)})})}const je={"16:9":{w:1920,h:1080},"16:10":{w:1920,h:1200},"9:16":{w:1080,h:1920},"4:3":{w:1440,h:1080}},Se="16:9";function Jn(n){if(!n||typeof n!="string")return Se;const s=n.match(/<div\b[^>]*class\s*=\s*['"][^'"]*__nd-deck-wrap[^'"]*['"][^>]*data-deck-aspect\s*=\s*['"]([^'"]+)['"]/i)||n.match(/<div\b[^>]*data-deck-aspect\s*=\s*['"]([^'"]+)['"][^>]*class\s*=\s*['"][^'"]*__nd-deck-wrap[^'"]*['"]/i);return s&&je[s[1]]?s[1]:Se}function ss({tab:n,onTabChange:s,onClose:i,artifactExports:l=null,onExport:d=null,onToolbarGroups:f=null,title:m="幻灯",htmlSrc:c,htmlContent:y,selectedAnchor:u,onSelectChange:a,onTextEdit:w,onIframeReady:x,candidates:v,activeCandidateId:k,onSelectCandidate:b,onAddCandidate:L,onRemoveCandidate:W,onRenameCandidate:j,project:T,deckSpec:H,projectId:h,sessionId:P,decisionsReloadKey:_,comments:D=[],onAddComment:ee,onResolveComment:X,onDeleteComment:K,onRegionComment:F=null,tweaksAvailable:N=!1,pendingEdits:xe=[],onCommitMove:U,onCommitFreePosition:pe,onSubmitDragNote:gt,lastPendingEditId:ft=null,onApplyPendingEdits:ht,onUndoPending:mt,onClearAllPending:yt,canUndoPending:bt=!1,isStreaming:G=!1}){var Me,Re,Oe,He,_e,De,Ie,qe,Ne,Ue;const{panels:ge,setPanelVisible:wt}=en(),fe=!!((Me=ge==null?void 0:ge.tweaks)!=null&&Me.visible),vt=()=>wt("tweaks",!fe),[V,Ee]=o.useState(!1);o.useEffect(()=>{G&&n==="drag"&&(s==null||s("edit"))},[G,n,s]);const kt=o.useRef(null),[he,jt]=o.useState(!1),[Fe,St]=o.useState(null),[zt,Le]=o.useState(!1),[Y,te]=o.useState("fit"),[Z,$t]=o.useState({width:0,height:0}),[Ae,Et]=o.useState(0),[me,ne]=o.useState(""),[ye,se]=o.useState(!1),[I,Te]=o.useState(null),[be,re]=o.useState(!1),[C,ie]=o.useState(!1),[Q,le]=o.useState(!1),[oe,Pe]=o.useState(!0),O=o.useRef(null),we=o.useRef(null),We=o.useRef(null);o.useEffect(()=>{if(!h||!P)return;let g=!1;return Xe.read(h).then(({config:S})=>{g||S&&typeof S.tweaks_mode_enabled=="boolean"&&Pe(S.tweaks_mode_enabled)}).catch(()=>{}),()=>{g=!0}},[h,P]);const Ft=o.useCallback(g=>{Pe(g),!(!h||!P)&&Xe.patch(h,{tweaks_mode_enabled:g}).catch(()=>{})},[h,P]);o.useEffect(()=>{const g=O.current;if(!g)return;const S=()=>{const M=g.getBoundingClientRect();$t(R=>R.width===M.width&&R.height===M.height?R:{width:M.width,height:M.height})};S();let A=null;try{A=new ResizeObserver(S),A.observe(g)}catch{}return window.addEventListener("resize",S),()=>{A&&A.disconnect(),window.removeEventListener("resize",S)}},[n]);const Be=Jn(me),ae=je[Be]||je[Se],B=Y==="fit"?Z.width>0&&Z.height>0?Math.min(Z.width/ae.w,Z.height/ae.h):1:Y,Lt=v&&v.length>=1;o.useEffect(()=>{se(!1),Te(null)},[k]),o.useEffect(()=>{const g=A=>{var R;if(A.key!=="Escape")return;const M=A.target;((R=M==null?void 0:M.getAttribute)==null?void 0:R.call(M,"contenteditable"))!=="true"&&(C||be||Q||(u?a==null||a(null):i==null||i()))};window.addEventListener("keydown",g);let S=null;try{S=I,S==null||S.addEventListener("keydown",g)}catch{}return()=>{window.removeEventListener("keydown",g);try{S==null||S.removeEventListener("keydown",g)}catch{}}},[u,I,a,i,C,be,Q]),o.useEffect(()=>{const g=S=>{const A=S==null?void 0:S.data;if(!(!A||typeof A!="object")&&A.type==="canvas-page-change"&&Number.isFinite(A.page))try{window.dispatchEvent(new CustomEvent("nd-canvas-page-change",{detail:{page:A.page}}))}catch{}};return window.addEventListener("message",g),()=>window.removeEventListener("message",g)},[]),o.useEffect(()=>{if(!c){ne(y||""),se(!1);return}fetch(c).then(g=>g.text()).then(g=>{ne(g),se(!1)}).catch(()=>ne("<!-- 无法加载源码 -->"))},[c,y,Ae]);const At=g=>{a==null||a((g==null?void 0:g.anchor)||null)},Tt=g=>{w==null||w(g),console.log("[direct edit]",g)},Pt=o.useCallback(g=>{ne(g),se(!0)},[]),Wt=o.useCallback(g=>{try{Te(g.contentDocument)}catch{}x==null||x(g)},[x]),Bt=()=>{Et(g=>g+1),a==null||a(null)},Mt=()=>{re(!1),ie(!1),le(g=>!g)},Rt=()=>{re(!1),le(!1),ie(g=>!g)},ve=Array.isArray(D)?D.filter(g=>g.status!=="resolved").length:0,Ot=o.useMemo(()=>[cn({kind:"deck",exports:l,onExport:d}),{id:"mode",type:"mode",value:n,onChange:g=>{s==null||s(g),a==null||a(null)},items:[{id:"preview",icon:$n,label:"预览",title:"看成品(左右键翻页)"},{id:"edit",icon:tn,label:"编辑",title:"双击文字直接改 · 单击元素弹评论卡"},{id:"drag",icon:nn,label:"拖拽",disabled:G,title:G?"agent 正在跑,拖拽暂停以免和它抢同一份源码":"拖动元素调布局"},{id:"region",icon:En,label:"圈选",disabled:!F,title:F?"框一块地方说事 —— 框住谁、当时长什么样、你想说什么,一起交给 agent":"要先开一个会话才能把圈选交给 agent"},{id:"code",icon:sn,label:"源码",title:"看/改这一份 HTML"}]},n==="drag"&&{id:"dragmode",items:[{id:"free",icon:rn,label:V?"自由":"嵌入",active:V,title:V?"自由摆放 · 松手落到像素位置(P 切回嵌入)":"嵌入 · 松手按 DOM 树插进容器(P 切自由摆放)",onClick:()=>Ee(g=>!g)}]},n!=="code"&&{id:"zoom",items:[{id:"zoomOut",icon:ln,title:"缩小",onClick:()=>te(Math.max(.25,B-.1))},{id:"zoomLevel",label:`${Math.round(B*100)}%`,active:Y==="fit",title:Y==="fit"?"当前自适应窗口":"点一下自适应窗口",onClick:()=>te("fit")},{id:"zoomIn",icon:tt,title:"放大",onClick:()=>te(Math.min(3,B+.1))},{id:"fit",icon:on,title:"自适应窗口",onClick:()=>te("fit")}]},{id:"actions",items:[{id:"tweaks",icon:an,active:fe,disabled:!oe,title:oe?N?"Tweaks:拖控件实时改样式":"Tweaks(agent 还没暴露参数 — 跟它说一句让它 expose_tweaks)":"Tweaks 模式已关(在 System 里开)",onClick:vt},{id:"comment",icon:xt,label:ve>0?String(ve):void 0,active:Q,btnRef:We,title:"这一份上已有的评论",onClick:Mt},{id:"reload",icon:dn,title:"重载(agent 改完没刷新时用)",onClick:Bt},{id:"system",icon:lt,active:C,btnRef:we,title:"System:项目档案 / Tweaks 模式 / A11y",onClick:Rt}]}].filter(Boolean),[n,G,V,Y,B,fe,oe,N,Q,C,ve,F,l,d]);return e.jsxs(un,{kind:"deck",title:m,subtitle:Be,onClose:i,escToClose:!1,groups:Ot,onToolbarGroups:f,headerExtra:Lt?e.jsx(Pn,{candidates:v,activeId:k,onSelect:b,onAdd:L,onRemove:W,onRename:j}):null,children:[(n==="edit"||n==="preview"||n==="drag"||n==="region")&&e.jsxs("div",{ref:O,style:{flex:1,minHeight:0,position:"relative",display:"flex",flexDirection:"column"},children:[e.jsx(Tn,{src:ye?void 0:c,srcDoc:ye?me:c?void 0:y,mode:n==="drag"||n==="region"?"preview":n,onSelect:At,onTextEdit:Tt,onIframeReady:Wt,zoom:B,deckW:ae.w,deckH:ae.h},`${k||"default"}-${Ae}-${ye?"doc":"src"}`),n==="edit"&&u&&e.jsx(fn,{selectedAnchor:u,iframeRef:{current:(Re=O.current)==null?void 0:Re.querySelector("iframe")},zoom:B}),e.jsx(hn,{comments:D,iframeRef:{current:(Oe=O.current)==null?void 0:Oe.querySelector("iframe")},zoom:B,onSelectAnchor:g=>{n!=="edit"&&(s==null||s("edit")),a==null||a(g)}}),e.jsx(Qn,{edits:xe,iframeRef:{current:(He=O.current)==null?void 0:He.querySelector("iframe")},zoom:B}),e.jsx(Kn,{iframeDoc:I,active:n==="preview"}),e.jsx(mn,{active:n==="drag"&&!he,iframeRef:{current:(_e=O.current)==null?void 0:_e.querySelector("iframe")},zoom:B,pickDragSource:yn,isDragging:he}),e.jsx(bn,{active:n==="drag",iframeRef:{current:(De=O.current)==null?void 0:De.querySelector("iframe")},zoom:B,freeMode:V,onFreeModeChange:Ee,apiRef:kt,onDraggingChange:jt,onSelectionChange:g=>{St(g),g&&Le(!0)},onCommitMove:(g,S)=>{var M;if(S.duplicate){const R=(M=S.sourceEl)==null?void 0:M.cloneNode(!0);let Ge=()=>{};if(R&&S.targetContainer){try{R.removeAttribute("data-anchor")}catch{}S.beforeEl&&S.beforeEl.parentNode===S.targetContainer?S.targetContainer.insertBefore(R,S.beforeEl):S.targetContainer.appendChild(R),Ge=()=>{try{R.remove()}catch{}}}U==null||U(g,Ge);return}const A=vn({iframeDoc:I,sourceEl:S.sourceEl,targetContainer:S.targetContainer,beforeEl:S.beforeEl});U==null||U(g,A==null?void 0:A.revert)},onCommitFreePosition:(g,S)=>{const A=wn({sourceEl:S.sourceEl,parentEl:S.parentEl,styleDelta:g.styleDelta,runtimeLocks:g.runtimeLocks,parentNeedsRelative:g.parentNeedsRelative});pe==null||pe(g,A==null?void 0:A.revert)}}),e.jsx(kn,{active:n==="drag"&&zt&&!he&&!!Fe,iframeRef:{current:(Ie=O.current)==null?void 0:Ie.querySelector("iframe")},zoom:B,sourceEl:Fe,hasPendingEditId:!!ft,onSubmit:gt,onDismiss:()=>Le(!1)}),n==="edit"&&u&&I&&e.jsx(jn,{selectedAnchor:u,iframeDoc:I,iframeRef:{current:(qe=O.current)==null?void 0:qe.querySelector("iframe")},iframeRect:Z,zoom:B,comments:D,onClose:()=>a==null?void 0:a(null),onAddComment:ee,onResolveComment:X,onDeleteComment:K}),e.jsx(Sn,{active:n==="region"&&!!F,iframeRef:{current:(Ne=O.current)==null?void 0:Ne.querySelector("iframe")},zoom:B,onSubmit:g=>F==null?void 0:F(g),onExit:()=>s==null?void 0:s("preview")}),e.jsx(Vn,{edits:xe,onApply:ht,onUndo:mt,onClearAll:yt,canUndo:bt,isRunning:G})]}),n==="code"&&e.jsx(zn,{value:me,onChange:Pt,readOnly:!1}),be&&e.jsx(Mn,{anchorRef:we,onClose:()=>re(!1),iframeDoc:I}),C&&e.jsx(Nn,{anchorRef:we,onClose:()=>ie(!1),project:T,deckSpec:H,projectId:h,sessionId:P,decisionsReloadKey:_,onA11yClick:()=>{ie(!1),re(!0)},tweaksEnabled:oe,onTweaksEnabledChange:Ft}),Q&&e.jsx(Gn,{comments:D,iframeDoc:I,iframeRef:{current:(Ue=O.current)==null?void 0:Ue.querySelector("iframe")},anchorRef:We,onClose:()=>le(!1),onResolveComment:X,onDeleteComment:K,onSelectAnchor:g=>{le(!1),n!=="edit"&&(s==null||s("edit")),a==null||a(g)}})]})}export{ss as default};
@@ -1,16 +1,16 @@
1
- import{c as K,r as n,j as e,R as N,C as c,G as g,k as Q,F as k,e as W,a2 as tt,A as ct,X as dt,b as q,aq as ut,a7 as _,Q as ht,a0 as G,ar as pt,a3 as Z,x as ft,as as xt,s as gt,Y as yt,Z as bt,at as vt}from"./index-BHTBJlpY.js";import{S as wt,E as kt}from"./square-dashed-mouse-pointer-8lrgqmfv.js";/**
1
+ import{c as q,r as n,j as e,R as N,d as c,G as g,P as Q,F as k,e as L,L as tt,S as ct,X as dt,a as K,v as ut,h as _,M as ht,I as G,T as pt,i as J,k as ft,l as xt,m as gt,n as yt,A as bt,C as vt}from"./index-GAamh1p4.js";import{S as wt,E as kt}from"./square-dashed-mouse-pointer-CDUlhUP7.js";/**
2
2
  * @license lucide-react v0.468.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 mt=K("FileJson",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1",key:"1oajmo"}],["path",{d:"M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1",key:"mpwhp6"}]]);/**
6
+ */const mt=q("FileJson",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1",key:"1oajmo"}],["path",{d:"M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1",key:"mpwhp6"}]]);/**
7
7
  * @license lucide-react v0.468.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 St=K("FileType2",[["path",{d:"M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4",key:"1pf5j1"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M2 13v-1h6v1",key:"1dh9dg"}],["path",{d:"M5 12v6",key:"150t9c"}],["path",{d:"M4 18h2",key:"1xrofg"}]]);/**
11
+ */const St=q("FileType2",[["path",{d:"M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4",key:"1pf5j1"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M2 13v-1h6v1",key:"1dh9dg"}],["path",{d:"M5 12v6",key:"150t9c"}],["path",{d:"M4 18h2",key:"1xrofg"}]]);/**
12
12
  * @license lucide-react v0.468.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 jt=K("Scan",[["path",{d:"M3 7V5a2 2 0 0 1 2-2h2",key:"aa7l1z"}],["path",{d:"M17 3h2a2 2 0 0 1 2 2v2",key:"4qcy5o"}],["path",{d:"M21 17v2a2 2 0 0 1-2 2h-2",key:"6vwrx8"}],["path",{d:"M7 21H5a2 2 0 0 1-2-2v-2",key:"ioqczr"}]]),J=8,Y=280;function Mt({active:y,imgRef:h,onSubmit:m,onExit:b}){const[s,S]=n.useState(null),[r,U]=n.useState(null),[O,v]=n.useState(""),[P,u]=n.useState(!1),w=n.useCallback(()=>{S(null),U(null),v("")},[]);if(n.useEffect(()=>{y||w()},[y,w]),n.useEffect(()=>{if(!y)return;const t=a=>{a.key==="Escape"&&(a.stopPropagation(),r||s?w():b==null||b())};return window.addEventListener("keydown",t,!0),()=>window.removeEventListener("keydown",t,!0)},[y,r,s,w,b]),!y)return null;const f=t=>{const a=t.currentTarget.getBoundingClientRect();return{x:Math.min(Math.max(0,t.clientX-a.left),a.width),y:Math.min(Math.max(0,t.clientY-a.top),a.height)}},z=(t,a)=>({x:Math.min(t.x,a.x),y:Math.min(t.y,a.y),w:Math.abs(t.x-a.x),h:Math.abs(t.y-a.y)}),R=t=>{var l,C;if(t.button!==0||r)return;t.preventDefault(),t.stopPropagation(),(C=(l=t.currentTarget).setPointerCapture)==null||C.call(l,t.pointerId);const a=f(t);S({from:a,to:a})},L=t=>{if(!s)return;t.stopPropagation();const a=f(t);S(l=>l&&{...l,to:a})},H=()=>{if(!s)return;const t=z(s.from,s.to);S(null),!(t.w<J||t.h<J)&&U({box:t})},T=async()=>{if(!r||P)return;const t=h==null?void 0:h.current;if(!t||!t.naturalWidth||!t.clientWidth)return;const a=t.naturalWidth/t.clientWidth,l=r.box;u(!0);try{await(m==null?void 0:m({region:{x:Math.round(l.x*a),y:Math.round(l.y*a),w:Math.round(l.w*a),h:Math.round(l.h*a)},viewport:{width:t.naturalWidth,height:t.naturalHeight},text:O.trim()})),w(),b==null||b()}finally{u(!1)}},j=s?z(s.from,s.to):null,M=(r==null?void 0:r.box)||j;let p=0,$=0;if(r&&(h!=null&&h.current)){const t=r.box,a=h.current.clientHeight,l=h.current.clientWidth;p=t.y+t.h+10,p+170>a&&(p=Math.max(8,t.y-170-10)),$=Math.min(Math.max(8,t.x),Math.max(8,l-Y-8))}return e.jsxs("div",{onPointerDown:R,onPointerMove:L,onPointerUp:H,onPointerCancel:()=>S(null),style:{position:"absolute",inset:0,cursor:r?"default":"crosshair",background:r?"transparent":"rgba(32,26,14,0.10)",touchAction:"none",borderRadius:2},children:[M&&e.jsx("div",{style:{position:"absolute",left:M.x,top:M.y,width:M.w,height:M.h,border:`2px solid ${c.btn}`,borderRadius:N.sm,background:"rgba(255,255,255,0.06)",boxShadow:"0 0 0 9999px rgba(32,26,14,0.18)",pointerEvents:"none"}}),r&&e.jsxs("div",{onPointerDown:t=>t.stopPropagation(),style:{position:"absolute",left:$,top:p,width:Y,background:c.bgWhite,borderRadius:N.lg,boxShadow:Q.far,padding:g.md,display:"flex",flexDirection:"column",gap:g.sm},children:[e.jsx("textarea",{value:O,autoFocus:!0,onChange:t=>v(t.target.value),onKeyDown:t=>{t.key==="Enter"&&(t.metaKey||t.ctrlKey)&&(t.preventDefault(),T())},placeholder:"这一块想说什么…(可以不写,框本身就是话)",style:{width:"100%",boxSizing:"border-box",minHeight:56,resize:"vertical",fontFamily:W,fontSize:k.sm,color:c.text,lineHeight:1.6,border:`1px solid ${c.borderLt}`,borderRadius:N.md,padding:g.sm,outline:"none",background:c.bg}}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:g.sm},children:[e.jsxs("button",{onClick:T,disabled:P,style:{display:"inline-flex",alignItems:"center",gap:g.xs,padding:`5px ${g.lg}px`,borderRadius:N.pill,border:"none",background:c.btn,color:c.btnText,fontFamily:W,fontSize:k.sm,fontWeight:600,cursor:P?"default":"pointer",opacity:P?.7:1},children:[P?e.jsxs(e.Fragment,{children:[e.jsx(tt,{size:12,style:{animation:"spin 1s linear infinite"}})," 发送中…"]}):e.jsxs(e.Fragment,{children:[e.jsx(ct,{size:12})," 发给 agent"]}),e.jsx("style",{children:"@keyframes spin{to{transform:rotate(360deg)}}"})]}),e.jsxs("button",{onClick:w,style:{display:"inline-flex",alignItems:"center",gap:g.xs,padding:`5px ${g.md}px`,borderRadius:N.pill,border:`1px solid ${c.borderLt}`,background:"transparent",color:c.sub,fontFamily:W,fontSize:k.xs,cursor:"pointer"},children:[e.jsx(dt,{size:11})," 重画"]}),e.jsx("span",{style:{marginLeft:"auto",fontFamily:q,fontSize:k.xxs,color:c.dim},children:"⌘↵"})]})]})]})}const Pt=24;function Ct({projectId:y,file:h,title:m,sourceFile:b=null,members:s=null,exports:S,onExport:r,onClose:U,onToolbarGroups:O,onRegionComment:v=null,fileVersions:P=null}){const[u,w]=n.useState(1),[f,z]=n.useState(null),[R,L]=n.useState(!0),[H,T]=n.useState(null),[j,M]=n.useState("height"),[p,$]=n.useState("preview"),[t,a]=n.useState(!1),[l,C]=n.useState(null),[et,nt]=n.useState(null),at=n.useRef(null),B=n.useRef(null),[d,V]=n.useState(h);n.useEffect(()=>{V(h)},[h]);const A=(s==null?void 0:s.find(i=>i.file===d))||null,F=A?A.sourceFile:b,I=ut(P,d),X=n.useMemo(()=>_.docxPageUrl(y,d,u,{v:I}),[y,d,u,I]);n.useEffect(()=>{w(1),z(null),C(null)},[d]),n.useEffect(()=>{let i=!1,o=null;return L(!0),T(null),fetch(X).then(async x=>{if(!x.ok){const lt=await x.json().catch(()=>({}));throw new Error(lt.error||`渲染失败(${x.status})`)}const E=Number(x.headers.get("X-Docx-Pages")),rt=await x.blob();i||(E>0&&z(E),o=URL.createObjectURL(rt),nt(o),L(!1))}).catch(x=>{i||(T(x.message),L(!1))}),()=>{i=!0,o&&URL.revokeObjectURL(o)}},[X]),n.useEffect(()=>{p!=="source"||!F||l!=null||fetch(_.artifactFileUrl(y,F)).then(i=>i.text()).then(C).catch(()=>C("(读不到源文件)"))},[p,F,y,l]);const D=n.useCallback(i=>{w(o=>Math.min(Math.max(1,o+i),f||o+i))},[f]);n.useEffect(()=>{const i=o=>{var x,E;((x=o.target)==null?void 0:x.tagName)==="INPUT"||((E=o.target)==null?void 0:E.tagName)==="TEXTAREA"||((o.key==="ArrowRight"||o.key==="PageDown")&&(o.preventDefault(),D(1)),(o.key==="ArrowLeft"||o.key==="PageUp")&&(o.preventDefault(),D(-1)))};return window.addEventListener("keydown",i),()=>window.removeEventListener("keydown",i)},[D]);const it=n.useMemo(()=>[s&&s.length>1?{id:"member",value:d,node:e.jsx("select",{value:d,onChange:i=>V(i.target.value),title:"这个文件夹里的文档(多版本并排放,选一份看)",style:{maxWidth:180,height:24,padding:"0 4px",border:`1px solid ${G.hair}`,borderRadius:pt.radius,background:"transparent",color:G.text,fontFamily:W,fontSize:k.xs,cursor:"pointer"},children:s.map(i=>e.jsx("option",{value:i.file,style:{background:c.bgWhite,color:c.text},children:i.title||i.file},i.file))})}:null,{id:"pager",value:`${u}/${f??""}`,node:e.jsxs(e.Fragment,{children:[e.jsx(Z,{dataId:"prev",icon:ft,title:"上一页(← / PageUp)",disabled:u<=1,onClick:()=>D(-1)}),e.jsx("span",{style:{...xt,fontFamily:q,fontVariantNumeric:"tabular-nums",padding:`0 ${g.xs}px`,minWidth:40,textAlign:"center",whiteSpace:"nowrap",userSelect:"none"},children:f?`${u} / ${f}`:u}),e.jsx(Z,{dataId:"next",icon:gt,title:"下一页(→ / PageDown)",disabled:!!f&&u>=f,onClick:()=>D(1)})]})},v&&p==="preview"?{id:"regionmode",items:[{id:"region",icon:wt,label:"圈选",title:"在页面上框一块发给 agent",active:t,onClick:()=>a(i=>!i)}]}:null,{id:"fit",items:[{id:"fitH",icon:ht,title:"整页(铺满高度)",active:j==="height",onClick:()=>M("height")},{id:"fitW",icon:jt,title:"铺满宽度(看细节)",active:j==="width",onClick:()=>M("width")}]},{id:"tab",items:[{id:"preview",icon:kt,title:"看页面",active:p==="preview",onClick:()=>$("preview")},{id:"pdf",icon:St,title:"连续阅读(浏览器 PDF 视图,可搜索选字)",active:p==="pdf",onClick:()=>$("pdf")},...F?[{id:"source",icon:mt,title:`看源码(${F})—— 改这份再 build,别改 .docx`,active:p==="source",onClick:()=>$("source")}]:[]]},yt({kind:"docx",exports:S,onExport:r?i=>r(i,d):null})].filter(Boolean),[u,f,j,p,F,S,r,D,s,d,v,t]),ot=n.useCallback(async({region:i,viewport:o,text:x})=>{await(v==null?void 0:v({region:i,viewport:o,elements:[],container:null,text:x,path:d,docxPage:u}))},[v,d,u]),st=j==="height"?{height:"100%",width:"auto",maxWidth:"100%"}:{width:"100%",height:"auto"};return e.jsx(bt,{kind:"docx",title:A!=null&&A.title?`${m||h} · ${A.title}`:m||h,subtitle:f?`${f} 页`:null,onClose:U,groups:it,onToolbarGroups:O,banner:F?null:e.jsxs("span",{children:["这是一份",e.jsx("b",{children:"外来文档"}),"(没有 token 源)。现在能看、能导出,",e.jsx("b",{children:"改它要等编辑道上线"}),"—— 想现在就要一个改过的版本,让 agent 基于它的内容重做一份。"]}),contentStyle:{background:vt.paper},children:p==="pdf"?e.jsx("iframe",{title:`${m||d} PDF`,src:_.docxPdfUrl(y,d,{v:I}),style:{width:"100%",height:"100%",border:0,display:"block"}},`${d}?v=${I}`):p==="source"?e.jsx("pre",{style:{margin:0,padding:g.lg,height:"100%",overflow:"auto",fontFamily:q,fontSize:k.sm,lineHeight:1.6,color:c.text,background:c.bgWhite,whiteSpace:"pre-wrap"},children:l??"读取中…"}):e.jsx("div",{ref:at,style:{height:"100%",width:"100%",overflow:"auto",display:"flex",alignItems:j==="height"?"center":"flex-start",justifyContent:"center",padding:Pt,boxSizing:"border-box"},children:H?e.jsxs("div",{style:{fontFamily:W,fontSize:k.sm,color:c.text2,textAlign:"center",maxWidth:420,lineHeight:1.7},children:[H,e.jsx("div",{style:{marginTop:g.sm,color:c.sub,fontSize:k.xs},children:"渲染链路的问题跟文档本身无关。文档还在,导出照常能用。"})]}):e.jsxs("div",{style:{position:"relative",height:j==="height"?"100%":"auto",maxWidth:"100%"},children:[e.jsx("img",{ref:B,alt:`${m||d} 第 ${u} 页`,src:et||void 0,style:{...st,display:"block",background:"#fff",boxShadow:Q.mid,borderRadius:2}}),e.jsx(Mt,{active:t&&!R,imgRef:B,onSubmit:ot,onExit:()=>a(!1)},`${d}#${u}`),R&&e.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(255,255,255,0.65)",gap:g.sm,fontFamily:W,fontSize:k.sm,color:c.text2,borderRadius:2},children:[e.jsx("style",{children:"@keyframes spin{to{transform:rotate(360deg)}}"}),e.jsx(tt,{size:14,style:{animation:"spin 1s linear infinite"}}),"加载中"]})]})})})}export{Ct as default};
16
+ */const jt=q("Scan",[["path",{d:"M3 7V5a2 2 0 0 1 2-2h2",key:"aa7l1z"}],["path",{d:"M17 3h2a2 2 0 0 1 2 2v2",key:"4qcy5o"}],["path",{d:"M21 17v2a2 2 0 0 1-2 2h-2",key:"6vwrx8"}],["path",{d:"M7 21H5a2 2 0 0 1-2-2v-2",key:"ioqczr"}]]),Z=8,Y=280;function Mt({active:y,imgRef:h,onSubmit:m,onExit:b}){const[s,S]=n.useState(null),[r,U]=n.useState(null),[O,v]=n.useState(""),[P,u]=n.useState(!1),w=n.useCallback(()=>{S(null),U(null),v("")},[]);if(n.useEffect(()=>{y||w()},[y,w]),n.useEffect(()=>{if(!y)return;const t=a=>{a.key==="Escape"&&(a.stopPropagation(),r||s?w():b==null||b())};return window.addEventListener("keydown",t,!0),()=>window.removeEventListener("keydown",t,!0)},[y,r,s,w,b]),!y)return null;const f=t=>{const a=t.currentTarget.getBoundingClientRect();return{x:Math.min(Math.max(0,t.clientX-a.left),a.width),y:Math.min(Math.max(0,t.clientY-a.top),a.height)}},T=(t,a)=>({x:Math.min(t.x,a.x),y:Math.min(t.y,a.y),w:Math.abs(t.x-a.x),h:Math.abs(t.y-a.y)}),I=t=>{var l,C;if(t.button!==0||r)return;t.preventDefault(),t.stopPropagation(),(C=(l=t.currentTarget).setPointerCapture)==null||C.call(l,t.pointerId);const a=f(t);S({from:a,to:a})},W=t=>{if(!s)return;t.stopPropagation();const a=f(t);S(l=>l&&{...l,to:a})},R=()=>{if(!s)return;const t=T(s.from,s.to);S(null),!(t.w<Z||t.h<Z)&&U({box:t})},z=async()=>{if(!r||P)return;const t=h==null?void 0:h.current;if(!t||!t.naturalWidth||!t.clientWidth)return;const a=t.naturalWidth/t.clientWidth,l=r.box;u(!0);try{await(m==null?void 0:m({region:{x:Math.round(l.x*a),y:Math.round(l.y*a),w:Math.round(l.w*a),h:Math.round(l.h*a)},viewport:{width:t.naturalWidth,height:t.naturalHeight},text:O.trim()})),w(),b==null||b()}finally{u(!1)}},j=s?T(s.from,s.to):null,M=(r==null?void 0:r.box)||j;let p=0,$=0;if(r&&(h!=null&&h.current)){const t=r.box,a=h.current.clientHeight,l=h.current.clientWidth;p=t.y+t.h+10,p+170>a&&(p=Math.max(8,t.y-170-10)),$=Math.min(Math.max(8,t.x),Math.max(8,l-Y-8))}return e.jsxs("div",{onPointerDown:I,onPointerMove:W,onPointerUp:R,onPointerCancel:()=>S(null),style:{position:"absolute",inset:0,cursor:r?"default":"crosshair",background:r?"transparent":"rgba(32,26,14,0.10)",touchAction:"none",borderRadius:2},children:[M&&e.jsx("div",{style:{position:"absolute",left:M.x,top:M.y,width:M.w,height:M.h,border:`2px solid ${c.btn}`,borderRadius:N.sm,background:"rgba(255,255,255,0.06)",boxShadow:"0 0 0 9999px rgba(32,26,14,0.18)",pointerEvents:"none"}}),r&&e.jsxs("div",{onPointerDown:t=>t.stopPropagation(),style:{position:"absolute",left:$,top:p,width:Y,background:c.bgWhite,borderRadius:N.lg,boxShadow:Q.far,padding:g.md,display:"flex",flexDirection:"column",gap:g.sm},children:[e.jsx("textarea",{value:O,autoFocus:!0,onChange:t=>v(t.target.value),onKeyDown:t=>{t.key==="Enter"&&(t.metaKey||t.ctrlKey)&&(t.preventDefault(),z())},placeholder:"这一块想说什么…(可以不写,框本身就是话)",style:{width:"100%",boxSizing:"border-box",minHeight:56,resize:"vertical",fontFamily:L,fontSize:k.sm,color:c.text,lineHeight:1.6,border:`1px solid ${c.borderLt}`,borderRadius:N.md,padding:g.sm,outline:"none",background:c.bg}}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:g.sm},children:[e.jsxs("button",{onClick:z,disabled:P,style:{display:"inline-flex",alignItems:"center",gap:g.xs,padding:`5px ${g.lg}px`,borderRadius:N.pill,border:"none",background:c.btn,color:c.btnText,fontFamily:L,fontSize:k.sm,fontWeight:600,cursor:P?"default":"pointer",opacity:P?.7:1},children:[P?e.jsxs(e.Fragment,{children:[e.jsx(tt,{size:12,style:{animation:"spin 1s linear infinite"}})," 发送中…"]}):e.jsxs(e.Fragment,{children:[e.jsx(ct,{size:12})," 发给 agent"]}),e.jsx("style",{children:"@keyframes spin{to{transform:rotate(360deg)}}"})]}),e.jsxs("button",{onClick:w,style:{display:"inline-flex",alignItems:"center",gap:g.xs,padding:`5px ${g.md}px`,borderRadius:N.pill,border:`1px solid ${c.borderLt}`,background:"transparent",color:c.sub,fontFamily:L,fontSize:k.xs,cursor:"pointer"},children:[e.jsx(dt,{size:11})," 重画"]}),e.jsx("span",{style:{marginLeft:"auto",fontFamily:K,fontSize:k.xxs,color:c.dim},children:"⌘↵"})]})]})]})}const Pt=24;function Ct({projectId:y,file:h,title:m,sourceFile:b=null,members:s=null,exports:S,onExport:r,onClose:U,onToolbarGroups:O,onRegionComment:v=null,fileVersions:P=null}){const[u,w]=n.useState(1),[f,T]=n.useState(null),[I,W]=n.useState(!0),[R,z]=n.useState(null),[j,M]=n.useState("height"),[p,$]=n.useState("preview"),[t,a]=n.useState(!1),[l,C]=n.useState(null),[et,nt]=n.useState(null),at=n.useRef(null),B=n.useRef(null),[d,V]=n.useState(h);n.useEffect(()=>{V(h)},[h]);const A=(s==null?void 0:s.find(i=>i.file===d))||null,F=A?A.sourceFile:b,H=ut(P,d),X=n.useMemo(()=>_.docxPageUrl(y,d,u,{v:H}),[y,d,u,H]);n.useEffect(()=>{w(1),T(null),C(null)},[d]),n.useEffect(()=>{let i=!1,o=null;return W(!0),z(null),fetch(X).then(async x=>{if(!x.ok){const lt=await x.json().catch(()=>({}));throw new Error(lt.error||`渲染失败(${x.status})`)}const E=Number(x.headers.get("X-Docx-Pages")),rt=await x.blob();i||(E>0&&T(E),o=URL.createObjectURL(rt),nt(o),W(!1))}).catch(x=>{i||(z(x.message),W(!1))}),()=>{i=!0,o&&URL.revokeObjectURL(o)}},[X]),n.useEffect(()=>{p!=="source"||!F||l!=null||fetch(_.artifactFileUrl(y,F)).then(i=>i.text()).then(C).catch(()=>C("(读不到源文件)"))},[p,F,y,l]);const D=n.useCallback(i=>{w(o=>Math.min(Math.max(1,o+i),f||o+i))},[f]);n.useEffect(()=>{const i=o=>{var x,E;((x=o.target)==null?void 0:x.tagName)==="INPUT"||((E=o.target)==null?void 0:E.tagName)==="TEXTAREA"||((o.key==="ArrowRight"||o.key==="PageDown")&&(o.preventDefault(),D(1)),(o.key==="ArrowLeft"||o.key==="PageUp")&&(o.preventDefault(),D(-1)))};return window.addEventListener("keydown",i),()=>window.removeEventListener("keydown",i)},[D]);const it=n.useMemo(()=>[s&&s.length>1?{id:"member",value:d,node:e.jsx("select",{value:d,onChange:i=>V(i.target.value),title:"这个文件夹里的文档(多版本并排放,选一份看)",style:{maxWidth:180,height:24,padding:"0 4px",border:`1px solid ${G.hair}`,borderRadius:pt.radius,background:"transparent",color:G.text,fontFamily:L,fontSize:k.xs,cursor:"pointer"},children:s.map(i=>e.jsx("option",{value:i.file,style:{background:c.bgWhite,color:c.text},children:i.title||i.file},i.file))})}:null,{id:"pager",value:`${u}/${f??""}`,node:e.jsxs(e.Fragment,{children:[e.jsx(J,{dataId:"prev",icon:ft,title:"上一页(← / PageUp)",disabled:u<=1,onClick:()=>D(-1)}),e.jsx("span",{style:{...xt,fontFamily:K,fontVariantNumeric:"tabular-nums",padding:`0 ${g.xs}px`,minWidth:40,textAlign:"center",whiteSpace:"nowrap",userSelect:"none"},children:f?`${u} / ${f}`:u}),e.jsx(J,{dataId:"next",icon:gt,title:"下一页(→ / PageDown)",disabled:!!f&&u>=f,onClick:()=>D(1)})]})},v&&p==="preview"?{id:"regionmode",items:[{id:"region",icon:wt,label:"圈选",title:"在页面上框一块发给 agent",active:t,onClick:()=>a(i=>!i)}]}:null,{id:"fit",items:[{id:"fitH",icon:ht,title:"整页(铺满高度)",active:j==="height",onClick:()=>M("height")},{id:"fitW",icon:jt,title:"铺满宽度(看细节)",active:j==="width",onClick:()=>M("width")}]},{id:"tab",items:[{id:"preview",icon:kt,title:"看页面",active:p==="preview",onClick:()=>$("preview")},{id:"pdf",icon:St,title:"连续阅读(浏览器 PDF 视图,可搜索选字)",active:p==="pdf",onClick:()=>$("pdf")},...F?[{id:"source",icon:mt,title:`看源码(${F})—— 改这份再 build,别改 .docx`,active:p==="source",onClick:()=>$("source")}]:[]]},yt({kind:"docx",exports:S,onExport:r?i=>r(i,d):null})].filter(Boolean),[u,f,j,p,F,S,r,D,s,d,v,t]),ot=n.useCallback(async({region:i,viewport:o,text:x})=>{await(v==null?void 0:v({region:i,viewport:o,elements:[],container:null,text:x,path:d,docxPage:u}))},[v,d,u]),st=j==="height"?{height:"100%",width:"auto",maxWidth:"100%"}:{width:"100%",height:"auto"};return e.jsx(bt,{kind:"docx",title:A!=null&&A.title?`${m||h} · ${A.title}`:m||h,subtitle:f?`${f} 页`:null,onClose:U,groups:it,onToolbarGroups:O,banner:F?null:e.jsxs("span",{children:["这是一份",e.jsx("b",{children:"外来文档"}),"(没有 token 源)。现在能看、能导出,",e.jsx("b",{children:"改它要等编辑道上线"}),"—— 想现在就要一个改过的版本,让 agent 基于它的内容重做一份。"]}),contentStyle:{background:vt.paper},children:p==="pdf"?e.jsx("iframe",{title:`${m||d} PDF`,src:_.docxPdfUrl(y,d,{v:H}),style:{width:"100%",height:"100%",border:0,display:"block"}},`${d}?v=${H}`):p==="source"?e.jsx("pre",{style:{margin:0,padding:g.lg,height:"100%",overflow:"auto",fontFamily:K,fontSize:k.sm,lineHeight:1.6,color:c.text,background:c.bgWhite,whiteSpace:"pre-wrap"},children:l??"读取中…"}):e.jsx("div",{ref:at,style:{height:"100%",width:"100%",overflow:"auto",display:"flex",alignItems:j==="height"?"center":"flex-start",justifyContent:"center",padding:Pt,boxSizing:"border-box"},children:R?e.jsxs("div",{style:{fontFamily:L,fontSize:k.sm,color:c.text2,textAlign:"center",maxWidth:420,lineHeight:1.7},children:[R,e.jsx("div",{style:{marginTop:g.sm,color:c.sub,fontSize:k.xs},children:"渲染链路的问题跟文档本身无关。文档还在,导出照常能用。"})]}):e.jsxs("div",{style:{position:"relative",height:j==="height"?"100%":"auto",maxWidth:"100%"},children:[e.jsx("img",{ref:B,alt:`${m||d} 第 ${u} 页`,src:et||void 0,style:{...st,display:"block",background:"#fff",boxShadow:Q.mid,borderRadius:2}}),e.jsx(Mt,{active:t&&!I,imgRef:B,onSubmit:ot,onExit:()=>a(!1)},`${d}#${u}`),I&&e.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(255,255,255,0.65)",gap:g.sm,fontFamily:L,fontSize:k.sm,color:c.text2,borderRadius:2},children:[e.jsx("style",{children:"@keyframes spin{to{transform:rotate(360deg)}}"}),e.jsx(tt,{size:14,style:{animation:"spin 1s linear infinite"}}),"加载中"]})]})})})}export{Ct as default};