@ian2018cs/agenthub 0.1.83 → 0.1.85

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.
@@ -151,7 +151,7 @@ ${ue}`:ue:je.push({type:"assistant",content:ue,timestamp:new Date,isStreaming:!0
151
151
  .xterm-screen:focus {
152
152
  outline: none !important;
153
153
  }
154
- `;if(typeof document<"u"){const r=document.createElement("style");r.type="text/css",r.innerText=Nc,document.head.appendChild(r)}function Tc({selectedProject:r,selectedSession:o,initialCommand:c,isPlainShell:u=!1,onProcessComplete:l,minimal:m=!1,autoConnect:d=!1}){const s=n.useRef(null),p=n.useRef(null),t=n.useRef(null),x=n.useRef(null),[h,a]=n.useState(!1),[i,y]=n.useState(!1),[j,w]=n.useState(!1),[b,k]=n.useState(null),[f,N]=n.useState(!1),S=n.useRef(r),I=n.useRef(o),D=n.useRef(c),T=n.useRef(u),R=n.useRef(l);n.useEffect(()=>{S.current=r,I.current=o,D.current=c,T.current=u,R.current=l});const M=n.useCallback(async()=>{if(!(f||h))try{const ne=localStorage.getItem("auth-token");if(!ne){console.error("No authentication token found for Shell WebSocket connection");return}const ie=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/shell?token=${encodeURIComponent(ne)}`;x.current=new WebSocket(ie),x.current.onopen=()=>{a(!0),N(!1),setTimeout(()=>{t.current&&p.current&&(t.current.fit(),x.current.send(JSON.stringify({type:"init",projectPath:S.current.fullPath||S.current.path,sessionId:T.current?null:I.current?.id,hasSession:T.current?!1:!!I.current,provider:T.current?"plain-shell":I.current?.__provider||"claude",cols:p.current.cols,rows:p.current.rows,initialCommand:D.current,isPlainShell:T.current})))},100)},x.current.onmessage=le=>{try{const xe=JSON.parse(le.data);if(xe.type==="output"){let Ce=xe.data;if(T.current&&R.current){const be=Ce.replace(/\x1b\[[0-9;]*m/g,"");if(be.includes("Process exited with code 0"))R.current(0);else if(be.match(/Process exited with code (\d+)/)){const Se=parseInt(be.match(/Process exited with code (\d+)/)[1]);Se!==0&&R.current(Se)}}p.current&&p.current.write(Ce)}else xe.type==="url_open"&&window.open(xe.url,"_blank")}catch(xe){console.error("[Shell] Error handling WebSocket message:",xe,le.data)}},x.current.onclose=le=>{a(!1),N(!1),p.current&&(p.current.clear(),p.current.write("\x1B[2J\x1B[H"))},x.current.onerror=le=>{a(!1),N(!1)}}catch{a(!1),N(!1)}},[f,h]),E=n.useCallback(()=>{!i||h||f||(N(!0),M())},[i,h,f,M]),W=n.useCallback(()=>{x.current&&(x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"terminate"})),x.current.close(),x.current=null),p.current&&(p.current.clear(),p.current.write("\x1B[2J\x1B[H")),a(!1),N(!1)},[]),X=n.useMemo(()=>o?o.summary||"New Session":null,[o]),C=n.useMemo(()=>X?X.slice(0,30):null,[X]),$=n.useMemo(()=>X?X.slice(0,50):null,[X]),te=()=>{w(!0),x.current&&(x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"terminate"})),x.current.close(),x.current=null),p.current&&(p.current.dispose(),p.current=null,t.current=null),a(!1),y(!1),setTimeout(()=>{w(!1)},200)};return n.useEffect(()=>{const ne=o?.id||null;b!==null&&b!==ne&&i&&W(),k(ne)},[o?.id,i,W]),n.useEffect(()=>{if(!s.current||!r||j||p.current)return;p.current=new Kn.Terminal({cursorBlink:!0,fontSize:14,fontFamily:'Menlo, Monaco, "Courier New", monospace',allowProposedApi:!0,allowTransparency:!1,convertEol:!0,scrollback:1e4,tabStopWidth:4,windowsMode:!1,macOptionIsMeta:!0,macOptionClickForcesSelection:!1,theme:{background:"#1e1e1e",foreground:"#d4d4d4",cursor:"#ffffff",cursorAccent:"#1e1e1e",selection:"#264f78",selectionForeground:"#ffffff",black:"#000000",red:"#cd3131",green:"#0dbc79",yellow:"#e5e510",blue:"#2472c8",magenta:"#bc3fbc",cyan:"#11a8cd",white:"#e5e5e5",brightBlack:"#666666",brightRed:"#f14c4c",brightGreen:"#23d18b",brightYellow:"#f5f543",brightBlue:"#3b8eea",brightMagenta:"#d670d6",brightCyan:"#29b8db",brightWhite:"#ffffff",extendedAnsi:["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff"]}}),t.current=new Vn.FitAddon;const ne=new Zn.WebglAddon,G=new Qn.WebLinksAddon;p.current.loadAddon(t.current),p.current.loadAddon(G);try{p.current.loadAddon(ne)}catch{console.warn("[Shell] WebGL renderer unavailable, using Canvas fallback")}p.current.open(s.current),p.current.attachCustomKeyEventHandler(le=>(le.ctrlKey||le.metaKey)&&le.key==="c"&&p.current.hasSelection()?(document.execCommand("copy"),!1):(le.ctrlKey||le.metaKey)&&le.key==="v"?(navigator.clipboard.readText().then(xe=>{x.current&&x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"input",data:xe}))}).catch(()=>{}),!1):!0),setTimeout(()=>{t.current&&(t.current.fit(),p.current&&x.current&&x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"resize",cols:p.current.cols,rows:p.current.rows})))},100),y(!0),p.current.onData(le=>{x.current&&x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"input",data:le}))});const ie=new ResizeObserver(()=>{t.current&&p.current&&setTimeout(()=>{t.current.fit(),x.current&&x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"resize",cols:p.current.cols,rows:p.current.rows}))},50)});return s.current&&ie.observe(s.current),()=>{ie.disconnect(),x.current&&(x.current.readyState===WebSocket.OPEN||x.current.readyState===WebSocket.CONNECTING)&&x.current.close(),x.current=null,p.current&&(p.current.dispose(),p.current=null)}},[r?.path||r?.fullPath,j]),n.useEffect(()=>{!d||!i||f||h||E()},[d,i,f,h,E]),r?m?e.jsx("div",{className:"h-full w-full bg-gray-900",children:e.jsx("div",{ref:s,className:"h-full w-full focus:outline-none",style:{outline:"none"}})}):e.jsxs("div",{className:"h-full flex flex-col bg-gray-900 w-full",children:[e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx("div",{className:`w-2 h-2 rounded-full ${h?"bg-green-500":"bg-red-500"}`}),o&&e.jsxs("span",{className:"text-xs text-blue-300",children:["(",C,"...)"]}),!o&&e.jsx("span",{className:"text-xs text-gray-400",children:"(新会话)"}),!i&&e.jsx("span",{className:"text-xs text-yellow-400",children:"(正在初始化...)"}),j&&e.jsx("span",{className:"text-xs text-blue-400",children:"(正在重启...)"})]}),e.jsxs("div",{className:"flex items-center space-x-3",children:[h&&e.jsxs("button",{onClick:W,className:"px-3 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700 flex items-center space-x-1",title:"断开 Shell 连接",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})}),e.jsx("span",{children:"断开连接"})]}),e.jsxs("button",{onClick:te,disabled:j||h,className:"text-xs text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed flex items-center space-x-1",title:"重启 Shell(先断开连接)",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),e.jsx("span",{children:"重启"})]})]})]})}),e.jsxs("div",{className:"flex-1 p-2 overflow-hidden relative",children:[e.jsx("div",{ref:s,className:"h-full w-full focus:outline-none",style:{outline:"none"}}),!i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90",children:e.jsx("div",{className:"text-white",children:"加载终端中..."})}),i&&!h&&!f&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("button",{onClick:E,className:"px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors flex items-center justify-center space-x-2 text-base font-medium w-full sm:w-auto",title:"Connect to shell",children:[e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),e.jsx("span",{children:"在 Shell 中继续"})]}),e.jsx("p",{className:"text-gray-400 text-sm mt-3 px-2",children:u?`Run ${c||"command"} in ${r.displayName}`:o?`Resume session: ${$}...`:"Start a new Claude session"})]})}),f&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("div",{className:"flex items-center justify-center space-x-3 text-yellow-400",children:[e.jsx("div",{className:"w-6 h-6 animate-spin rounded-full border-2 border-yellow-400 border-t-transparent"}),e.jsx("span",{className:"text-base font-medium",children:"连接到 Shell..."})]}),e.jsx("p",{className:"text-gray-400 text-sm mt-3 px-2",children:u?`Running ${c||"command"} in ${r.displayName}`:`Starting Claude CLI in ${r.displayName}`})]})})]})]}):e.jsx("div",{className:"h-full flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"选择项目"}),e.jsx("p",{children:"选择一个项目以在该目录中打开交互式 Shell"})]})})}function Sc({project:r,session:o=null,command:c=null,isPlainShell:u=null,autoConnect:l=!0,onComplete:m=null,onClose:d=null,title:s=null,className:p="",showHeader:t=!0,compact:x=!1,minimal:h=!1}){const[a,i]=n.useState(!1),y=u!==null?u:c!==null,j=n.useCallback(w=>{i(!0),m&&m(w)},[m]);return r?e.jsxs("div",{className:`h-full w-full flex flex-col ${p}`,children:[!h&&t&&s&&e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx("h3",{className:"text-sm font-medium text-gray-200",children:s}),a&&e.jsx("span",{className:"text-xs text-green-400",children:"(已完成)"})]}),d&&e.jsx("button",{onClick:d,className:"text-gray-400 hover:text-white",title:"关闭",children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),e.jsx("div",{className:"flex-1 w-full min-h-0",children:e.jsx(Tc,{selectedProject:r,selectedSession:o,initialCommand:c,isPlainShell:y,onProcessComplete:j,minimal:h,autoConnect:h?!0:l})})]}):e.jsx("div",{className:`h-full flex items-center justify-center ${p}`,children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"未选择项目"}),e.jsx("p",{children:"打开 Shell 需要一个项目"})]})})}function Xc({selectedProject:r,minimal:o=!1,autoConnect:c=!1}){const u=n.useRef(null),l=n.useRef(null),m=n.useRef(null),d=n.useRef(null),[s,p]=n.useState(!1),[t,x]=n.useState(!1),[h,a]=n.useState(!1),[i,y]=n.useState(!1),j=n.useRef(r);n.useEffect(()=>{j.current=r});const w=n.useCallback(async()=>{if(!(i||s))try{const N=localStorage.getItem("auth-token");if(!N){console.error("No authentication token found for Codex WebSocket connection");return}const I=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/codex?token=${encodeURIComponent(N)}`;d.current=new WebSocket(I),d.current.onopen=()=>{p(!0),y(!1),setTimeout(()=>{m.current&&l.current&&(m.current.fit(),d.current.send(JSON.stringify({type:"init",projectPath:j.current.fullPath||j.current.path,cols:l.current.cols,rows:l.current.rows})))},100)},d.current.onmessage=D=>{try{const T=JSON.parse(D.data);T.type==="output"?l.current&&l.current.write(T.data):T.type==="url_open"&&window.open(T.url,"_blank")}catch(T){console.error("[CodexShell] Error handling WebSocket message:",T)}},d.current.onclose=()=>{p(!1),y(!1),l.current&&(l.current.clear(),l.current.write("\x1B[2J\x1B[H"))},d.current.onerror=()=>{p(!1),y(!1)}}catch{p(!1),y(!1)}},[i,s]),b=n.useCallback(()=>{!t||s||i||(y(!0),w())},[t,s,i,w]),k=n.useCallback(()=>{d.current&&(d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"terminate"})),d.current.close(),d.current=null),l.current&&(l.current.clear(),l.current.write("\x1B[2J\x1B[H")),p(!1),y(!1)},[]),f=()=>{a(!0),d.current&&(d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"terminate"})),d.current.close(),d.current=null),l.current&&(l.current.dispose(),l.current=null,m.current=null),p(!1),x(!1),setTimeout(()=>a(!1),200)};return n.useEffect(()=>{if(!u.current||!r||h||l.current)return;l.current=new Kn.Terminal({cursorBlink:!0,fontSize:14,fontFamily:'Menlo, Monaco, "Courier New", monospace',allowProposedApi:!0,allowTransparency:!1,convertEol:!0,scrollback:1e4,tabStopWidth:4,windowsMode:!1,macOptionIsMeta:!0,macOptionClickForcesSelection:!1,theme:{background:"#1e1e1e",foreground:"#d4d4d4",cursor:"#ffffff",cursorAccent:"#1e1e1e",selection:"#264f78",selectionForeground:"#ffffff",black:"#000000",red:"#cd3131",green:"#0dbc79",yellow:"#e5e510",blue:"#2472c8",magenta:"#bc3fbc",cyan:"#11a8cd",white:"#e5e5e5",brightBlack:"#666666",brightRed:"#f14c4c",brightGreen:"#23d18b",brightYellow:"#f5f543",brightBlue:"#3b8eea",brightMagenta:"#d670d6",brightCyan:"#29b8db",brightWhite:"#ffffff"}}),m.current=new Vn.FitAddon;const N=new Zn.WebglAddon,S=new Qn.WebLinksAddon;l.current.loadAddon(m.current),l.current.loadAddon(S);try{l.current.loadAddon(N)}catch{console.warn("[CodexShell] WebGL renderer unavailable, using Canvas fallback")}l.current.open(u.current),l.current.attachCustomKeyEventHandler(D=>(D.ctrlKey||D.metaKey)&&D.key==="c"&&l.current.hasSelection()?(document.execCommand("copy"),!1):(D.ctrlKey||D.metaKey)&&D.key==="v"?(navigator.clipboard.readText().then(T=>{d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"input",data:T}))}).catch(()=>{}),!1):!0),setTimeout(()=>{m.current&&(m.current.fit(),l.current&&d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"resize",cols:l.current.cols,rows:l.current.rows})))},100),x(!0),l.current.onData(D=>{d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"input",data:D}))});const I=new ResizeObserver(()=>{m.current&&l.current&&setTimeout(()=>{m.current.fit(),d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"resize",cols:l.current.cols,rows:l.current.rows}))},50)});return u.current&&I.observe(u.current),()=>{I.disconnect(),d.current&&(d.current.readyState===WebSocket.OPEN||d.current.readyState===WebSocket.CONNECTING)&&d.current.close(),d.current=null,l.current&&(l.current.dispose(),l.current=null)}},[r?.path||r?.fullPath,h]),n.useEffect(()=>{!c||!t||i||s||b()},[c,t,i,s,b]),r?o?e.jsx("div",{className:"h-full w-full bg-gray-900",children:e.jsx("div",{ref:u,className:"h-full w-full focus:outline-none",style:{outline:"none"}})}):e.jsxs("div",{className:"h-full flex flex-col bg-gray-900 w-full",children:[e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx("div",{className:`w-2 h-2 rounded-full ${s?"bg-green-500":"bg-red-500"}`}),e.jsx("span",{className:"text-xs text-gray-300 font-medium",children:"Codex"}),!t&&e.jsx("span",{className:"text-xs text-yellow-400",children:"(正在初始化...)"}),h&&e.jsx("span",{className:"text-xs text-blue-400",children:"(正在重启...)"})]}),e.jsxs("div",{className:"flex items-center space-x-3",children:[s&&e.jsxs("button",{onClick:k,className:"px-3 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700 flex items-center space-x-1",title:"断开 Codex 连接",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})}),e.jsx("span",{children:"断开连接"})]}),e.jsxs("button",{onClick:f,disabled:h||s,className:"text-xs text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed flex items-center space-x-1",title:"重启 Codex(先断开连接)",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),e.jsx("span",{children:"重启"})]})]})]})}),e.jsxs("div",{className:"flex-1 p-2 overflow-hidden relative",children:[e.jsx("div",{ref:u,className:"h-full w-full focus:outline-none",style:{outline:"none"}}),!t&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90",children:e.jsx("div",{className:"text-white",children:"加载终端中..."})}),t&&!s&&!i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("button",{onClick:b,className:"px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors flex items-center justify-center space-x-2 text-base font-medium w-full sm:w-auto",children:[e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),e.jsx("span",{children:"启动 Codex"})]}),e.jsxs("p",{className:"text-gray-400 text-sm mt-3 px-2",children:["在 ",r.displayName," 中启动 Codex CLI"]})]})}),i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("div",{className:"flex items-center justify-center space-x-3 text-yellow-400",children:[e.jsx("div",{className:"w-6 h-6 animate-spin rounded-full border-2 border-yellow-400 border-t-transparent"}),e.jsx("span",{className:"text-base font-medium",children:"连接到 Codex..."})]}),e.jsxs("p",{className:"text-gray-400 text-sm mt-3 px-2",children:["正在 ",r.displayName," 中启动 Codex CLI"]})]})})]})]}):e.jsx("div",{className:"h-full flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"选择项目"}),e.jsx("p",{children:"选择一个项目以在该目录中打开 Codex"})]})})}function Mc({project:r,autoConnect:o=!0,onClose:c=null,className:u="",showHeader:l=!0,minimal:m=!1}){return r?e.jsxs("div",{className:`h-full w-full flex flex-col ${u}`,children:[!m&&l&&c&&e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-medium text-gray-200",children:"Codex"}),e.jsx("button",{onClick:c,className:"text-gray-400 hover:text-white",title:"关闭",children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),e.jsx("div",{className:"flex-1 w-full min-h-0",children:e.jsx(Xc,{selectedProject:r,minimal:m,autoConnect:m?!0:o})})]}):e.jsx("div",{className:`h-full flex items-center justify-center ${u}`,children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"未选择项目"}),e.jsx("p",{children:"打开 Codex 需要一个项目"})]})})}function Oc({selectedProject:r,minimal:o=!1,autoConnect:c=!1}){const u=n.useRef(null),l=n.useRef(null),m=n.useRef(null),d=n.useRef(null),[s,p]=n.useState(!1),[t,x]=n.useState(!1),[h,a]=n.useState(!1),[i,y]=n.useState(!1),j=n.useRef(r);n.useEffect(()=>{j.current=r});const w=n.useCallback(async()=>{if(!(i||s))try{const N=localStorage.getItem("auth-token");if(!N){console.error("No authentication token found for Gemini WebSocket connection");return}const I=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/gemini?token=${encodeURIComponent(N)}`;d.current=new WebSocket(I),d.current.onopen=()=>{p(!0),y(!1),setTimeout(()=>{m.current&&l.current&&(m.current.fit(),d.current.send(JSON.stringify({type:"init",projectPath:j.current.fullPath||j.current.path,cols:l.current.cols,rows:l.current.rows})))},100)},d.current.onmessage=D=>{try{const T=JSON.parse(D.data);T.type==="output"?l.current&&l.current.write(T.data):T.type==="url_open"&&window.open(T.url,"_blank")}catch(T){console.error("[GeminiShell] Error handling WebSocket message:",T)}},d.current.onclose=()=>{p(!1),y(!1),l.current&&(l.current.clear(),l.current.write("\x1B[2J\x1B[H"))},d.current.onerror=()=>{p(!1),y(!1)}}catch{p(!1),y(!1)}},[i,s]),b=n.useCallback(()=>{!t||s||i||(y(!0),w())},[t,s,i,w]),k=n.useCallback(()=>{d.current&&(d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"terminate"})),d.current.close(),d.current=null),l.current&&(l.current.clear(),l.current.write("\x1B[2J\x1B[H")),p(!1),y(!1)},[]),f=()=>{a(!0),d.current&&(d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"terminate"})),d.current.close(),d.current=null),l.current&&(l.current.dispose(),l.current=null,m.current=null),p(!1),x(!1),setTimeout(()=>a(!1),200)};return n.useEffect(()=>{if(!u.current||!r||h||l.current)return;l.current=new Kn.Terminal({cursorBlink:!0,fontSize:14,fontFamily:'Menlo, Monaco, "Courier New", monospace',allowProposedApi:!0,allowTransparency:!1,convertEol:!0,scrollback:1e4,tabStopWidth:4,windowsMode:!1,macOptionIsMeta:!0,macOptionClickForcesSelection:!1,theme:{background:"#1e1e1e",foreground:"#d4d4d4",cursor:"#ffffff",cursorAccent:"#1e1e1e",selection:"#264f78",selectionForeground:"#ffffff",black:"#000000",red:"#cd3131",green:"#0dbc79",yellow:"#e5e510",blue:"#2472c8",magenta:"#bc3fbc",cyan:"#11a8cd",white:"#e5e5e5",brightBlack:"#666666",brightRed:"#f14c4c",brightGreen:"#23d18b",brightYellow:"#f5f543",brightBlue:"#3b8eea",brightMagenta:"#d670d6",brightCyan:"#29b8db",brightWhite:"#ffffff"}}),m.current=new Vn.FitAddon;const N=new Zn.WebglAddon,S=new Qn.WebLinksAddon;l.current.loadAddon(m.current),l.current.loadAddon(S);try{l.current.loadAddon(N)}catch{console.warn("[GeminiShell] WebGL renderer unavailable, using Canvas fallback")}l.current.open(u.current),l.current.attachCustomKeyEventHandler(D=>(D.ctrlKey||D.metaKey)&&D.key==="c"&&l.current.hasSelection()?(document.execCommand("copy"),!1):(D.ctrlKey||D.metaKey)&&D.key==="v"?(navigator.clipboard.readText().then(T=>{d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"input",data:T}))}).catch(()=>{}),!1):!0),setTimeout(()=>{m.current&&(m.current.fit(),l.current&&d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"resize",cols:l.current.cols,rows:l.current.rows})))},100),x(!0),l.current.onData(D=>{d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"input",data:D}))});const I=new ResizeObserver(()=>{m.current&&l.current&&setTimeout(()=>{m.current.fit(),d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"resize",cols:l.current.cols,rows:l.current.rows}))},50)});return u.current&&I.observe(u.current),()=>{I.disconnect(),d.current&&(d.current.readyState===WebSocket.OPEN||d.current.readyState===WebSocket.CONNECTING)&&d.current.close(),d.current=null,l.current&&(l.current.dispose(),l.current=null)}},[r?.path||r?.fullPath,h]),n.useEffect(()=>{!c||!t||i||s||b()},[c,t,i,s,b]),r?o?e.jsx("div",{className:"h-full w-full bg-gray-900",children:e.jsx("div",{ref:u,className:"h-full w-full focus:outline-none",style:{outline:"none"}})}):e.jsxs("div",{className:"h-full flex flex-col bg-gray-900 w-full",children:[e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx("div",{className:`w-2 h-2 rounded-full ${s?"bg-green-500":"bg-red-500"}`}),e.jsx("span",{className:"text-xs text-gray-300 font-medium",children:"Gemini"}),!t&&e.jsx("span",{className:"text-xs text-yellow-400",children:"(正在初始化...)"}),h&&e.jsx("span",{className:"text-xs text-blue-400",children:"(正在重启...)"})]}),e.jsxs("div",{className:"flex items-center space-x-3",children:[s&&e.jsxs("button",{onClick:k,className:"px-3 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700 flex items-center space-x-1",title:"断开 Gemini 连接",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})}),e.jsx("span",{children:"断开连接"})]}),e.jsxs("button",{onClick:f,disabled:h||s,className:"text-xs text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed flex items-center space-x-1",title:"重启 Gemini(先断开连接)",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),e.jsx("span",{children:"重启"})]})]})]})}),e.jsxs("div",{className:"flex-1 p-2 overflow-hidden relative",children:[e.jsx("div",{ref:u,className:"h-full w-full focus:outline-none",style:{outline:"none"}}),!t&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90",children:e.jsx("div",{className:"text-white",children:"加载终端中..."})}),t&&!s&&!i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("button",{onClick:b,className:"px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center justify-center space-x-2 text-base font-medium w-full sm:w-auto",children:[e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),e.jsx("span",{children:"启动 Gemini"})]}),e.jsxs("p",{className:"text-gray-400 text-sm mt-3 px-2",children:["在 ",r.displayName," 中启动 Gemini CLI"]})]})}),i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("div",{className:"flex items-center justify-center space-x-3 text-yellow-400",children:[e.jsx("div",{className:"w-6 h-6 animate-spin rounded-full border-2 border-yellow-400 border-t-transparent"}),e.jsx("span",{className:"text-base font-medium",children:"连接到 Gemini..."})]}),e.jsxs("p",{className:"text-gray-400 text-sm mt-3 px-2",children:["正在 ",r.displayName," 中启动 Gemini CLI"]})]})})]})]}):e.jsx("div",{className:"h-full flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"选择项目"}),e.jsx("p",{children:"选择一个项目以在该目录中打开 Gemini"})]})})}function Cc({project:r,autoConnect:o=!0,onClose:c=null,className:u="",showHeader:l=!0,minimal:m=!1}){return r?e.jsxs("div",{className:`h-full w-full flex flex-col ${u}`,children:[!m&&l&&c&&e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-medium text-gray-200",children:"Gemini"}),e.jsx("button",{onClick:c,className:"text-gray-400 hover:text-white",title:"关闭",children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),e.jsx("div",{className:"flex-1 w-full min-h-0",children:e.jsx(Oc,{selectedProject:r,minimal:m,autoConnect:m?!0:o})})]}):e.jsx("div",{className:`h-full flex items-center justify-center ${u}`,children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"未选择项目"}),e.jsx("p",{children:"打开 Gemini 需要一个项目"})]})})}class Ec extends lt.Component{constructor(o){super(o),this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(o){return{hasError:!0}}componentDidCatch(o,c){console.error("ErrorBoundary caught an error:",o,c),this.setState({error:o,errorInfo:c})}render(){return this.state.hasError?e.jsx("div",{className:"flex flex-col items-center justify-center p-8 text-center",children:e.jsxs("div",{className:"bg-red-50 border border-red-200 rounded-lg p-6 max-w-md",children:[e.jsxs("div",{className:"flex items-center mb-4",children:[e.jsx("div",{className:"flex-shrink-0",children:e.jsx("svg",{className:"h-5 w-5 text-red-400",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})})}),e.jsx("h3",{className:"ml-3 text-sm font-medium text-red-800",children:"出现问题"})]}),e.jsxs("div",{className:"text-sm text-red-700",children:[e.jsx("p",{className:"mb-2",children:"加载聊天界面时出现错误。"}),this.props.showDetails&&this.state.error&&e.jsxs("details",{className:"mt-4",children:[e.jsx("summary",{className:"cursor-pointer text-xs font-mono",children:"错误详情"}),e.jsxs("pre",{className:"mt-2 text-xs bg-red-100 p-2 rounded overflow-auto max-h-40",children:[this.state.error.toString(),this.state.errorInfo&&this.state.errorInfo.componentStack]})]})]}),e.jsx("div",{className:"mt-4",children:e.jsx("button",{onClick:()=>{this.setState({hasError:!1,error:null,errorInfo:null}),this.props.onRetry&&this.props.onRetry()},className:"bg-red-600 text-white px-4 py-2 rounded text-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500",children:"重试"})})]})}):this.props.children}}const jr=({children:r,content:o,position:c="top",className:u="",delay:l=500})=>{const[m,d]=n.useState(!1),[s,p]=n.useState(null),t=()=>{const i=setTimeout(()=>{d(!0)},l);p(i)},x=()=>{s&&(clearTimeout(s),p(null)),d(!1)},h=()=>{switch(c){case"top":return"bottom-full left-1/2 transform -translate-x-1/2 mb-2";case"bottom":return"top-full left-1/2 transform -translate-x-1/2 mt-2";case"left":return"right-full top-1/2 transform -translate-y-1/2 mr-2";case"right":return"left-full top-1/2 transform -translate-y-1/2 ml-2";default:return"bottom-full left-1/2 transform -translate-x-1/2 mb-2"}},a=()=>{switch(c){case"top":return"top-full left-1/2 transform -translate-x-1/2 border-t-gray-900 dark:border-t-gray-100";case"bottom":return"bottom-full left-1/2 transform -translate-x-1/2 border-b-gray-900 dark:border-b-gray-100";case"left":return"left-full top-1/2 transform -translate-y-1/2 border-l-gray-900 dark:border-l-gray-100";case"right":return"right-full top-1/2 transform -translate-y-1/2 border-r-gray-900 dark:border-r-gray-100";default:return"top-full left-1/2 transform -translate-x-1/2 border-t-gray-900 dark:border-t-gray-100"}};return o?e.jsxs("div",{className:"relative inline-block",onMouseEnter:t,onMouseLeave:x,children:[r,m&&e.jsxs("div",{className:nt("absolute z-50 px-2 py-1 text-xs font-medium text-white bg-gray-900 dark:bg-gray-100 dark:text-gray-900 rounded shadow-lg whitespace-nowrap pointer-events-none","animate-in fade-in-0 zoom-in-95 duration-200",h(),u),children:[o,e.jsx("div",{className:nt("absolute w-0 h-0 border-4 border-transparent",a())})]})]}):r};function Dc(){const[r,o]=n.useState(null),[c,u]=n.useState([]),[l,m]=n.useState(!1),d=n.useRef(null),s=n.useRef(null),p=n.useRef(0),{token:t}=Xt();n.useEffect(()=>{d.current&&(clearTimeout(d.current),d.current=null),s.current&&(s.current.close(),s.current=null),t?(p.current=0,x()):(m(!1),o(null));const a=()=>{if(document.visibilityState==="visible"){const i=s.current?.readyState;(i===void 0||i===3||i===2)&&(d.current&&(clearTimeout(d.current),d.current=null),p.current=0,x())}};return document.addEventListener("visibilitychange",a),()=>{document.removeEventListener("visibilitychange",a),d.current&&clearTimeout(d.current),s.current&&s.current.close()}},[t]);const x=()=>{try{const a=t||localStorage.getItem("auth-token");if(!a){console.warn("No authentication token found for WebSocket connection");return}const y=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws?token=${encodeURIComponent(a)}`,j=new WebSocket(y);s.current=j,j.onopen=()=>{p.current=0,m(!0),o(j)},j.onmessage=w=>{try{const b=JSON.parse(w.data);u(k=>[...k,b])}catch(b){console.error("Error parsing WebSocket message:",b)}},j.onclose=()=>{if(m(!1),o(null),s.current=null,localStorage.getItem("auth-token")){const b=Math.min(1e3*Math.pow(2,p.current),15e3);p.current+=1,d.current=setTimeout(()=>{x()},b)}},j.onerror=w=>{console.error("WebSocket error:",w)}}catch(a){console.error("Error creating WebSocket connection:",a)}};return{ws:r,sendMessage:a=>{r&&l?r.send(JSON.stringify(a)):console.warn("WebSocket not connected")},messages:c,isConnected:l}}const ws=n.createContext({ws:null,sendMessage:()=>{},messages:[],isConnected:!1}),Ns=()=>{const r=n.useContext(ws);if(!r)throw new Error("useWebSocketContext must be used within a WebSocketProvider");return r},Pc=({children:r})=>{const o=Dc();return e.jsx(ws.Provider,{value:o,children:r})};function Ac({selectedProject:r,selectedSession:o,activeTab:c,setActiveTab:u,ws:l,sendMessage:m,messages:d,isMobile:s,isPWA:p,onMenuClick:t,isLoading:x,onInputFocusChange:h,onSessionActive:a,onSessionInactive:i,onSessionProcessing:y,onSessionNotProcessing:j,processingSessions:w,onReplaceTemporarySession:b,onNavigateToSession:k,onShowSettings:f,autoScrollToBottom:N,sendByCtrlEnter:S,externalMessageUpdate:I,limitStatus:D,onLimitBlocked:T,checkLimitStatus:R}){const{showConfirm:M}=it(),{hasPermission:E}=Xt(),{isConnected:W}=Ns(),[X,C]=n.useState(null),[$,te]=n.useState(null),[ne,G]=n.useState(600),[ie,le]=n.useState(!1),[xe,Ce]=n.useState(!1),be=n.useRef(null),Se=async ye=>{const Xe="previewTabAcknowledged";if(!localStorage.getItem(Xe)){const Ee=await M("此功能的对话记录不会显示在当前网页的会话列表中,与 Chat 是两套独立的系统,请注意区分。",{title:"预览功能提示",subtitle:ye==="codex"?"Codex":"Gemini CLI",variant:"warning",confirmText:"我知道了,继续",cancelText:"取消",checkboxLabel:"不再提醒"});if(!Ee?.confirmed)return;Ee.checked&&localStorage.setItem(Xe,"1")}u(ye)};n.useEffect(()=>{c==="shell"&&R&&R()},[c,R]);const Re=["png","jpg","jpeg","gif","svg","webp","ico","bmp"],se=(ye,Xe=null)=>{const Ee=ye.split(".").pop()?.toLowerCase();if(Re.includes(Ee)){te({name:ye.split("/").pop(),path:ye,projectName:r?.name,projectPath:r?.path});return}const Fe={name:ye.split("/").pop(),path:ye,projectName:r?.name,diffInfo:Xe};C(Fe)},we=()=>{C(null),Ce(!1)},$e=()=>{Ce(!xe)},We=ye=>{s||(le(!0),ye.preventDefault())};return n.useEffect(()=>{const ye=Ee=>{if(!ie)return;const Fe=be.current?.parentElement;if(!Fe)return;const Ne=Fe.getBoundingClientRect(),Be=Ne.right-Ee.clientX,Pe=300,Ae=Ne.width*.8;Be>=Pe&&Be<=Ae&&G(Be)},Xe=()=>{le(!1)};return ie&&(document.addEventListener("mousemove",ye),document.addEventListener("mouseup",Xe),document.body.style.cursor="col-resize",document.body.style.userSelect="none"),()=>{document.removeEventListener("mousemove",ye),document.removeEventListener("mouseup",Xe),document.body.style.cursor="",document.body.style.userSelect=""}},[ie]),x?e.jsxs("div",{className:"h-full flex flex-col",children:[s&&e.jsx("div",{className:"bg-background border-b border-border p-2 sm:p-3 pwa-header-safe flex-shrink-0",children:e.jsx("button",{onClick:t,className:"p-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 pwa-menu-button",children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})})}),e.jsx("div",{className:"flex-1 flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-12 h-12 mx-auto mb-4",children:e.jsx("div",{className:"w-full h-full rounded-full border-4 border-gray-200 border-t-blue-500",style:{animation:"spin 1s linear infinite",WebkitAnimation:"spin 1s linear infinite",MozAnimation:"spin 1s linear infinite"}})}),e.jsxs("h2",{className:"text-xl font-semibold mb-2",children:["正在加载 ",et]}),e.jsx("p",{children:"正在设置您的工作区..."})]})})]}):r?e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsx("div",{className:"bg-background border-b border-border p-2 sm:p-3 pwa-header-safe flex-shrink-0",children:e.jsxs("div",{className:"flex items-center justify-between relative",children:[e.jsxs("div",{className:"flex items-center space-x-2 min-w-0 flex-1",children:[s&&e.jsx("button",{onClick:t,onTouchStart:ye=>{ye.preventDefault(),t()},className:"p-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 touch-manipulation active:scale-95 pwa-menu-button flex-shrink-0",children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),e.jsx("div",{className:"min-w-0 flex items-center gap-2 flex-1 overflow-x-auto scrollbar-hide",children:e.jsx("div",{className:"min-w-0 flex-1",children:c==="chat"&&o?e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"text-sm sm:text-base font-semibold text-gray-900 dark:text-white whitespace-nowrap overflow-x-auto scrollbar-hide",children:o.summary||"新会话"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-gray-500 dark:text-gray-400 truncate",children:r.displayName}),e.jsxs("span",{className:`inline-flex items-center gap-1 text-xs ${W?"text-green-600 dark:text-green-400":"text-red-500 dark:text-red-400 animate-pulse"}`,children:[W?e.jsx("svg",{className:"w-2.5 h-2.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8.288 15.038a5.25 5.25 0 017.424 0M5.106 11.856c3.807-3.808 9.98-3.808 13.788 0M1.924 8.674c5.565-5.565 14.587-5.565 20.152 0M12.53 18.22l-.53.53-.53-.53a.75.75 0 011.06 0z"})}):e.jsx("svg",{className:"w-2.5 h-2.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11.412 15.655L9.75 21.75l3.745-4.012M9.257 13.5H3.75l2.659-2.849m2.048-2.194L14.25 2.25 12 10.5h8.25l-4.707 5.043M6.53 9.345A3.778 3.778 0 0112 8.25c1.372 0 2.585.59 3.43 1.53M3 3l18 18"})}),e.jsx("span",{className:"hidden sm:inline",children:W?"连接正常":"连接异常"})]})]})]}):c==="chat"&&!o?e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"text-sm sm:text-base font-semibold text-gray-900 dark:text-white",children:"新会话"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-gray-500 dark:text-gray-400 truncate",children:r.displayName}),e.jsxs("span",{className:`inline-flex items-center gap-1 text-xs ${W?"text-green-600 dark:text-green-400":"text-red-500 dark:text-red-400 animate-pulse"}`,children:[W?e.jsx("svg",{className:"w-2.5 h-2.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8.288 15.038a5.25 5.25 0 017.424 0M5.106 11.856c3.807-3.808 9.98-3.808 13.788 0M1.924 8.674c5.565-5.565 14.587-5.565 20.152 0M12.53 18.22l-.53.53-.53-.53a.75.75 0 011.06 0z"})}):e.jsx("svg",{className:"w-2.5 h-2.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11.412 15.655L9.75 21.75l3.745-4.012M9.257 13.5H3.75l2.659-2.849m2.048-2.194L14.25 2.25 12 10.5h8.25l-4.707 5.043M6.53 9.345A3.778 3.778 0 0112 8.25c1.372 0 2.585.59 3.43 1.53M3 3l18 18"})}),e.jsx("span",{className:"hidden sm:inline",children:W?"连接正常":"连接异常"})]})]})]}):e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"text-sm sm:text-base font-semibold text-gray-900 dark:text-white",children:c==="files"?"项目文件":"项目"}),e.jsx("div",{className:"text-xs text-gray-500 dark:text-gray-400 truncate",children:r.displayName})]})})})]}),e.jsx("div",{className:"flex-shrink-0 hidden sm:block",children:e.jsxs("div",{className:"relative flex bg-gray-100 dark:bg-gray-800 rounded-lg p-1",children:[e.jsx(jr,{content:"Chat",position:"bottom",children:e.jsx("button",{onClick:()=>u("chat"),className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md ${c==="chat"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsx("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"})}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Chat"})]})})}),e.jsx(jr,{content:"Files",position:"bottom",children:e.jsx("button",{onClick:()=>u("files"),className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md transition-all duration-200 ${c==="files"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsx("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-5l-2-2H5a2 2 0 00-2 2z"})}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Files"})]})})}),E("claude_shell")&&e.jsx(jr,{content:D&&!D.allowed?"使用已达上限":"Claude Code",position:"bottom",children:e.jsx("button",{onClick:()=>{if(D&&!D.allowed){T?.(D.reason);return}u("shell")},className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md transition-all duration-200 ${D&&!D.allowed?"opacity-50 cursor-not-allowed text-gray-400 dark:text-gray-500":c==="shell"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsx("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z",fill:"#D97757",fillRule:"nonzero"})}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Claude Code"})]})})}),E("codex_shell")&&e.jsx(jr,{content:"Codex",position:"bottom",children:e.jsx("button",{onClick:()=>Se("codex"),className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md transition-all duration-200 ${c==="codex"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsx("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",fill:"currentColor",fillRule:"evenodd",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"})}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Codex"})]})})}),E("gemini_shell")&&e.jsx(jr,{content:"Gemini CLI",position:"bottom",children:e.jsx("button",{onClick:()=>Se("gemini"),className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md transition-all duration-200 ${c==="gemini"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsxs("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"#3186FF"}),e.jsx("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#gemini-tab-fill-0)"}),e.jsx("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#gemini-tab-fill-1)"}),e.jsx("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#gemini-tab-fill-2)"}),e.jsxs("defs",{children:[e.jsxs("linearGradient",{gradientUnits:"userSpaceOnUse",id:"gemini-tab-fill-0",x1:"7",x2:"11",y1:"15.5",y2:"12",children:[e.jsx("stop",{stopColor:"#08B962"}),e.jsx("stop",{offset:"1",stopColor:"#08B962",stopOpacity:"0"})]}),e.jsxs("linearGradient",{gradientUnits:"userSpaceOnUse",id:"gemini-tab-fill-1",x1:"8",x2:"11.5",y1:"5.5",y2:"11",children:[e.jsx("stop",{stopColor:"#F94543"}),e.jsx("stop",{offset:"1",stopColor:"#F94543",stopOpacity:"0"})]}),e.jsxs("linearGradient",{gradientUnits:"userSpaceOnUse",id:"gemini-tab-fill-2",x1:"3.5",x2:"17.5",y1:"13.5",y2:"12",children:[e.jsx("stop",{stopColor:"#FABC12"}),e.jsx("stop",{offset:".46",stopColor:"#FABC12",stopOpacity:"0"})]})]})]}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Gemini CLI"})]})})})]})})]})}),e.jsxs("div",{className:"flex-1 flex min-h-0 overflow-hidden",children:[e.jsxs("div",{className:`flex-1 flex flex-col min-h-0 overflow-hidden ${X?"mr-0":""} ${xe?"hidden":""}`,children:[e.jsx("div",{className:`h-full ${c==="chat"?"block":"hidden"}`,children:e.jsx(Ec,{showDetails:!0,children:e.jsx(kc,{selectedProject:r,selectedSession:o,ws:l,sendMessage:m,messages:d,onFileOpen:se,onInputFocusChange:h,onSessionActive:a,onSessionInactive:i,onSessionProcessing:y,onSessionNotProcessing:j,processingSessions:w,onReplaceTemporarySession:b,onNavigateToSession:k,onShowSettings:f,autoScrollToBottom:N,sendByCtrlEnter:S,externalMessageUpdate:I,limitStatus:D,onLimitExceeded:T,checkLimitStatus:R})})}),c==="files"&&e.jsx("div",{className:"h-full overflow-hidden",children:e.jsx(wc,{selectedProject:r})}),c==="shell"&&e.jsxs("div",{className:"h-full w-full overflow-hidden relative",children:[e.jsx(Sc,{project:r,session:o,showHeader:!1}),D&&!D.allowed&&e.jsx("div",{className:"absolute inset-0 bg-black/60 z-50 flex items-center justify-center",children:e.jsxs("div",{className:"bg-card border border-border rounded-lg shadow-xl p-6 mx-4 max-w-md text-center",children:[e.jsx("div",{className:"w-12 h-12 mx-auto mb-4 bg-red-100 dark:bg-red-900/30 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-6 h-6 text-red-600 dark:text-red-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),e.jsx("h3",{className:"text-lg font-semibold text-foreground mb-2",children:D.reason==="total_limit_exceeded"?"使用上限已达到":"今日使用上限已达到"}),e.jsx("p",{className:"text-muted-foreground mb-4",children:D.reason==="total_limit_exceeded"?"您已达到使用上限,请联系管理员提升额度。":"您已达到今日使用上限,请明日再来或联系管理员提升额度。"}),e.jsx("button",{onClick:()=>u("chat"),className:"px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors",children:"返回 Chat"})]})})]}),c==="codex"&&e.jsx("div",{className:"h-full w-full overflow-hidden relative",children:e.jsx(Mc,{project:r,showHeader:!1})}),c==="gemini"&&e.jsx("div",{className:"h-full w-full overflow-hidden relative",children:e.jsx(Cc,{project:r,showHeader:!1})}),e.jsx("div",{className:`h-full overflow-hidden ${c==="preview"?"block":"hidden"}`})]}),X&&!s&&e.jsxs(e.Fragment,{children:[!xe&&e.jsx("div",{ref:be,onMouseDown:We,className:"flex-shrink-0 w-1 bg-gray-200 dark:bg-gray-700 hover:bg-blue-500 dark:hover:bg-blue-600 cursor-col-resize transition-colors relative group",title:"Drag to resize",children:e.jsx("div",{className:"absolute inset-y-0 left-1/2 -translate-x-1/2 w-1 bg-blue-500 dark:bg-blue-600 opacity-0 group-hover:opacity-100 transition-opacity"})}),e.jsx("div",{className:`flex-shrink-0 border-l border-gray-200 dark:border-gray-700 h-full overflow-hidden ${xe?"flex-1":""}`,style:xe?{}:{width:`${ne}px`},children:e.jsx($n,{file:X,onClose:we,projectPath:r?.path,isSidebar:!0,isExpanded:xe,onToggleExpand:$e})})]})]}),X&&s&&e.jsx($n,{file:X,onClose:we,projectPath:r?.path,isSidebar:!1}),$&&e.jsx(ks,{file:$,onClose:()=>te(null)})]}):e.jsxs("div",{className:"h-full flex flex-col",children:[s&&e.jsx("div",{className:"bg-background border-b border-border p-2 sm:p-3 pwa-header-safe flex-shrink-0",children:e.jsx("button",{onClick:t,className:"p-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 pwa-menu-button",children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})})}),e.jsx("div",{className:"flex-1 flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400 max-w-md mx-auto px-6",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-6 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-5l-2-2H5a2 2 0 00-2 2z"})})}),e.jsx("h2",{className:"text-2xl font-semibold mb-3 text-gray-900 dark:text-white",children:"选择您的项目"}),e.jsxs("p",{className:"text-gray-600 dark:text-gray-300 mb-6 leading-relaxed",children:["从侧边栏选择一个项目,开始与 ",et," 进行交流。每个项目包含您的聊天会话和文件历史。"]}),e.jsx("div",{className:"bg-blue-50 dark:bg-blue-900/20 rounded-lg p-4 border border-blue-200 dark:border-blue-800",children:e.jsxs("p",{className:"text-sm text-blue-700 dark:text-blue-300",children:["💡 ",e.jsx("strong",{children:"提示:"})," ",s?"点击上方菜单按钮访问项目":E("create_project")?"点击侧边栏中的文件夹图标创建新项目":"点击侧边栏中的「使用项目模板」按钮来创建项目"]})})]})})]})}const Lc=lt.memo(Ac);function Ic({activeTab:r,setActiveTab:o,isInputFocused:c}){const u=[{id:"chat",icon:Cr,onClick:()=>o("chat")},{id:"shell",icon:Fn,onClick:()=>o("shell")},{id:"files",icon:Qt,onClick:()=>o("files")}];return e.jsx("div",{className:`fixed bottom-0 left-0 right-0 bg-background border-t border-border z-50 ios-bottom-safe transform transition-transform duration-300 ease-in-out shadow-lg ${c?"translate-y-full":"translate-y-0"}`,children:e.jsx("div",{className:"flex items-center justify-around py-1",children:u.map(l=>{const m=l.icon,d=r===l.id;return e.jsxs("button",{onClick:l.onClick,onTouchStart:s=>{s.preventDefault(),l.onClick()},className:`flex items-center justify-center p-2 rounded-lg min-h-[40px] min-w-[40px] relative touch-manipulation ${d?"text-blue-600 dark:text-blue-400":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white"}`,"aria-label":l.id,children:[e.jsx(m,{className:"w-5 h-5"}),d&&e.jsx("div",{className:"absolute top-0 left-1/2 transform -translate-x-1/2 w-6 h-0.5 bg-blue-600 dark:bg-blue-400 rounded-full"})]},l.id)})})})}const Ts=n.createContext(),eo=()=>{const r=n.useContext(Ts);if(!r)throw new Error("useTheme must be used within a ThemeProvider");return r},_c=({children:r})=>{const[o,c]=n.useState(()=>{const m=localStorage.getItem("theme");return m?m==="dark":window.matchMedia?window.matchMedia("(prefers-color-scheme: dark)").matches:!1});n.useEffect(()=>{if(o){document.documentElement.classList.add("dark"),localStorage.setItem("theme","dark");const m=document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');m&&m.setAttribute("content","black-translucent");const d=document.querySelector('meta[name="theme-color"]');d&&d.setAttribute("content","#0c1117")}else{document.documentElement.classList.remove("dark"),localStorage.setItem("theme","light");const m=document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');m&&m.setAttribute("content","default");const d=document.querySelector('meta[name="theme-color"]');d&&d.setAttribute("content","#ffffff")}},[o]),n.useEffect(()=>{if(!window.matchMedia)return;const m=window.matchMedia("(prefers-color-scheme: dark)"),d=s=>{localStorage.getItem("theme")||c(s.matches)};return m.addEventListener("change",d),()=>m.removeEventListener("change",d)},[]);const l={isDarkMode:o,toggleDarkMode:()=>{c(m=>!m)}};return e.jsx(Ts.Provider,{value:l,children:r})},zc=["Bash(git log:*)","Bash(git diff:*)","Bash(git status:*)","Write","Read","Edit","Glob","Grep","MultiEdit","Task","TodoWrite","TodoRead","WebFetch","WebSearch"];function Rc({skipPermissions:r,setSkipPermissions:o,allowedTools:c,setAllowedTools:u,disallowedTools:l,setDisallowedTools:m,newAllowedTool:d,setNewAllowedTool:s,newDisallowedTool:p,setNewDisallowedTool:t}){const x=y=>{y&&!c.includes(y)&&(u([...c,y]),s(""))},h=y=>{u(c.filter(j=>j!==y))},a=y=>{y&&!l.includes(y)&&(m([...l,y]),t(""))},i=y=>{m(l.filter(j=>j!==y))};return e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"bg-sky-50 dark:bg-sky-900/20 border border-sky-200 dark:border-sky-800 rounded-lg p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Qr,{className:"w-5 h-5 text-sky-500 flex-shrink-0 mt-0.5"}),e.jsxs("div",{className:"text-sm text-sky-800 dark:text-sky-200",children:[e.jsx("span",{className:"font-medium",children:"提示:"}),"此权限设置仅对 ",e.jsx("span",{className:"font-medium",children:"Chat(聊天)"})," 生效,对 ",e.jsx("span",{className:"font-medium",children:"Shell(终端)"})," 无效。Shell 是直接的系统终端,不受此权限控制。"]})]})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Wt,{className:"w-5 h-5 text-orange-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"权限设置"})]}),e.jsx("div",{className:"bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 rounded-lg p-4",children:e.jsxs("label",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"checkbox",checked:r,onChange:y=>o(y.target.checked),className:"w-4 h-4 text-blue-600 bg-gray-100 dark:bg-gray-700 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 focus:ring-2"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-orange-900 dark:text-orange-100",children:"跳过权限提示(请谨慎使用)"}),e.jsx("div",{className:"text-sm text-orange-700 dark:text-orange-300",children:"等同于 --dangerously-skip-permissions 标志"})]})]})})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ft,{className:"w-5 h-5 text-green-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"允许的工具"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"自动允许而不提示权限的工具"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsx(at,{value:d,onChange:y=>s(y.target.value),placeholder:'e.g., "Bash(git log:*)" or "Write"',onKeyPress:y=>{y.key==="Enter"&&(y.preventDefault(),x(d))},className:"flex-1 h-10"}),e.jsxs(B,{onClick:()=>x(d),disabled:!d,size:"sm",className:"h-10 px-4",children:[e.jsx(_t,{className:"w-4 h-4 mr-2 sm:mr-0"}),e.jsx("span",{className:"sm:hidden",children:"添加"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"快速添加常用工具:"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:zc.map(y=>e.jsx(B,{variant:"outline",size:"sm",onClick:()=>x(y),disabled:c.includes(y),className:"text-xs h-8",children:y},y))})]}),e.jsxs("div",{className:"space-y-2",children:[c.map(y=>e.jsxs("div",{className:"flex items-center justify-between bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-3",children:[e.jsx("span",{className:"font-mono text-sm text-green-800 dark:text-green-200",children:y}),e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>h(y),className:"text-green-600 hover:text-green-700",children:e.jsx(Ue,{className:"w-4 h-4"})})]},y)),c.length===0&&e.jsx("div",{className:"text-center py-6 text-gray-500 dark:text-gray-400",children:"未配置允许的工具"})]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Wt,{className:"w-5 h-5 text-red-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"阻止的工具"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"自动阻止而不提示权限的工具"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsx(at,{value:p,onChange:y=>t(y.target.value),placeholder:'e.g., "Bash(rm:*)"',onKeyPress:y=>{y.key==="Enter"&&(y.preventDefault(),a(p))},className:"flex-1 h-10"}),e.jsxs(B,{onClick:()=>a(p),disabled:!p,size:"sm",className:"h-10 px-4",children:[e.jsx(_t,{className:"w-4 h-4 mr-2 sm:mr-0"}),e.jsx("span",{className:"sm:hidden",children:"添加"})]})]}),e.jsxs("div",{className:"space-y-2",children:[l.map(y=>e.jsxs("div",{className:"flex items-center justify-between bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-3",children:[e.jsx("span",{className:"font-mono text-sm text-red-800 dark:text-red-200",children:y}),e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>i(y),className:"text-red-600 hover:text-red-700",children:e.jsx(Ue,{className:"w-4 h-4"})})]},y)),l.length===0&&e.jsx("div",{className:"text-center py-6 text-gray-500 dark:text-gray-400",children:"未配置阻止的工具"})]})]}),e.jsxs("div",{className:"bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4",children:[e.jsx("h4",{className:"font-medium text-blue-900 dark:text-blue-100 mb-2",children:"工具模式示例:"}),e.jsxs("ul",{className:"text-sm text-blue-800 dark:text-blue-200 space-y-1",children:[e.jsxs("li",{children:[e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:'"Bash(git log:*)"'})," - 允许所有 git log 命令"]}),e.jsxs("li",{children:[e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:'"Bash(git diff:*)"'})," - 允许所有 git diff 命令"]}),e.jsxs("li",{children:[e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:'"Write"'})," - 允许所有 Write 工具使用"]}),e.jsxs("li",{children:[e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:'"Bash(rm:*)"'})," - 阻止所有 rm 命令(危险)"]})]})]})]})}function $c({permissionMode:r,setPermissionMode:o}){return e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ft,{className:"w-5 h-5 text-green-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"权限模式"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"控制 Codex 如何处理文件修改和命令执行"}),e.jsx("div",{className:`border rounded-lg p-4 cursor-pointer transition-all ${r==="default"?"bg-gray-100 dark:bg-gray-800 border-gray-400 dark:border-gray-500":"bg-gray-50 dark:bg-gray-900/50 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600"}`,onClick:()=>o("default"),children:e.jsxs("label",{className:"flex items-start gap-3 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"codexPermissionMode",checked:r==="default",onChange:()=>o("default"),className:"mt-1 w-4 h-4 text-green-600"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-foreground",children:"默认"}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"仅受信任的命令(ls、cat、grep、git status 等)会自动运行。其他命令将被跳过。可以写入工作区。"})]})]})}),e.jsx("div",{className:`border rounded-lg p-4 cursor-pointer transition-all ${r==="acceptEdits"?"bg-green-50 dark:bg-green-900/20 border-green-400 dark:border-green-600":"bg-gray-50 dark:bg-gray-900/50 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600"}`,onClick:()=>o("acceptEdits"),children:e.jsxs("label",{className:"flex items-start gap-3 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"codexPermissionMode",checked:r==="acceptEdits",onChange:()=>o("acceptEdits"),className:"mt-1 w-4 h-4 text-green-600"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-green-900 dark:text-green-100",children:"接受编辑"}),e.jsx("div",{className:"text-sm text-green-700 dark:text-green-300",children:"所有命令在工作区内自动运行。沙盒执行的完全自动模式。"})]})]})}),e.jsx("div",{className:`border rounded-lg p-4 cursor-pointer transition-all ${r==="bypassPermissions"?"bg-orange-50 dark:bg-orange-900/20 border-orange-400 dark:border-orange-600":"bg-gray-50 dark:bg-gray-900/50 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600"}`,onClick:()=>o("bypassPermissions"),children:e.jsxs("label",{className:"flex items-start gap-3 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"codexPermissionMode",checked:r==="bypassPermissions",onChange:()=>o("bypassPermissions"),className:"mt-1 w-4 h-4 text-orange-600"}),e.jsxs("div",{children:[e.jsxs("div",{className:"font-medium text-orange-900 dark:text-orange-100 flex items-center gap-2",children:["跳过权限",e.jsx(Wt,{className:"w-4 h-4"})]}),e.jsx("div",{className:"text-sm text-orange-700 dark:text-orange-300",children:"无限制的完全系统访问。所有命令自动运行,具有完全的磁盘和网络访问权限。请谨慎使用。"})]})]})}),e.jsxs("details",{className:"text-sm",children:[e.jsx("summary",{className:"cursor-pointer text-muted-foreground hover:text-foreground",children:"技术详情"}),e.jsxs("div",{className:"mt-2 p-3 bg-gray-50 dark:bg-gray-900/50 rounded-lg text-xs text-muted-foreground space-y-2",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Default:"})," sandboxMode=workspace-write, approvalPolicy=untrusted. Trusted commands: cat, cd, grep, head, ls, pwd, tail, git status/log/diff/show, find (without -exec), etc."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Accept Edits:"})," sandboxMode=workspace-write, approvalPolicy=never. All commands auto-execute within project directory."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Bypass Permissions:"})," sandboxMode=danger-full-access, approvalPolicy=never. Full system access, use only in trusted environments."]}),e.jsx("p",{className:"text-xs opacity-75",children:"您可以在聊天界面中使用模式按钮为每个会话覆盖此设置。"})]})]})]})})}function Wc({agent:r,...o}){return r==="claude"?e.jsx(Rc,{...o}):r==="codex"?e.jsx($c,{...o}):null}const Hc=r=>{switch(r){case"stdio":return e.jsx(Fn,{className:"w-4 h-4"});case"sse":return e.jsx(Or,{className:"w-4 h-4"});case"http":return e.jsx(lr,{className:"w-4 h-4"});default:return e.jsx(en,{className:"w-4 h-4"})}};function Fc({servers:r,onAdd:o,onEdit:c,onDelete:u,testResults:l,serverTools:m,onDiscoverRepo:d}){return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(en,{className:"w-5 h-5 text-purple-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"MCP 服务器"})]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Model Context Protocol 服务器为 ",et," 提供额外的工具和数据源"]}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs(B,{onClick:o,className:"bg-purple-600 hover:bg-purple-700 text-white",size:"sm",children:[e.jsx(_t,{className:"w-4 h-4 mr-2"}),"添加 MCP 服务器"]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs(B,{onClick:d,variant:"outline",size:"sm",children:[e.jsx(tn,{className:"w-4 h-4 mr-2"}),"MCP 商店"]})})]}),e.jsxs("div",{className:"space-y-2",children:[r.map(s=>e.jsx("div",{className:"bg-gray-50 dark:bg-gray-900/50 border border-gray-200 dark:border-gray-700 rounded-lg p-4",children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[Hc(s.type),e.jsx("span",{className:"font-medium text-foreground",children:s.name}),e.jsx(tt,{variant:"outline",className:"text-xs",children:s.type}),e.jsx(tt,{variant:"outline",className:"text-xs",title:s.scope==="local"&&s.projectPath?s.projectPath:void 0,children:s.scope==="local"?`local${s.projectPath?` · ${s.projectPath.split("/").filter(Boolean).pop()}`:""}`:s.scope==="user"?"user":s.scope})]}),e.jsxs("div",{className:"text-sm text-muted-foreground space-y-1",children:[s.type==="stdio"&&s.config?.command&&e.jsxs("div",{children:["命令:",e.jsx("code",{className:"bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs",children:s.config.command})]}),(s.type==="sse"||s.type==="http")&&s.config?.url&&e.jsxs("div",{children:["URL:",e.jsx("code",{className:"bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs",children:s.config.url})]}),s.config?.args&&s.config.args.length>0&&e.jsxs("div",{children:["参数:",e.jsx("code",{className:"bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs",children:s.config.args.join(" ")})]})]}),l?.[s.id]&&e.jsx("div",{className:`mt-2 p-2 rounded text-xs ${l[s.id].success?"bg-green-50 dark:bg-green-900/20 text-green-800 dark:text-green-200":"bg-red-50 dark:bg-red-900/20 text-red-800 dark:text-red-200"}`,children:e.jsx("div",{className:"font-medium",children:l[s.id].message})}),m?.[s.id]&&m[s.id].tools?.length>0&&e.jsxs("div",{className:"mt-2 p-2 rounded text-xs bg-blue-50 dark:bg-blue-900/20 text-blue-800 dark:text-blue-200",children:[e.jsxs("div",{className:"font-medium",children:["工具(",m[s.id].tools.length,"):"]}),e.jsxs("div",{className:"flex flex-wrap gap-1 mt-1",children:[m[s.id].tools.slice(0,5).map((p,t)=>e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:p.name},t)),m[s.id].tools.length>5&&e.jsxs("span",{className:"text-xs opacity-75",children:["+",m[s.id].tools.length-5," 更多"]})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 ml-4",children:[e.jsx(B,{onClick:()=>c(s),variant:"ghost",size:"sm",className:"text-gray-600 hover:text-gray-700",title:"编辑服务器",children:e.jsx(On,{className:"w-4 h-4"})}),e.jsx(B,{onClick:()=>u(s.id,s.scope,s.projectPath),variant:"ghost",size:"sm",className:"text-red-600 hover:text-red-700",title:"删除服务器",children:e.jsx(xt,{className:"w-4 h-4"})})]})]})},s.id)),r.length===0&&e.jsx("div",{className:"text-center py-8 text-gray-500 dark:text-gray-400",children:"未配置 MCP 服务器"})]})]})}function Bc(r){return e.jsx(Fc,{...r})}const Uc=[{key:"ANTHROPIC_DEFAULT_OPUS_MODEL",label:"Opus 模型",placeholder:"例如: claude-opus-4-6",description:"覆盖 opus 别名使用的模型,Plan Mode 激活时也用于 opusplan"},{key:"ANTHROPIC_DEFAULT_SONNET_MODEL",label:"Sonnet 模型",placeholder:"例如: claude-sonnet-4-5-20250929",description:"覆盖 sonnet 别名使用的模型,Plan Mode 未激活时也用于 opusplan"},{key:"ANTHROPIC_DEFAULT_HAIKU_MODEL",label:"Haiku 模型",placeholder:"例如: claude-haiku-4-5-20251001",description:"覆盖 haiku 别名使用的模型,也用于后台功能"},{key:"CLAUDE_CODE_SUBAGENT_MODEL",label:"Subagent 模型",placeholder:"例如: claude-haiku-4-5-20251001",description:"覆盖子代理(subagents)使用的模型"}],Gc=n.forwardRef(function({onStatusChange:o},c){const[u,l]=n.useState({}),[m,d]=n.useState({}),[s,p]=n.useState(!0),[t,x]=n.useState(!1),[h,a]=n.useState(null),[i,y]=n.useState(null),j=JSON.stringify(u)!==JSON.stringify(m);n.useEffect(()=>{o?.({saving:t,hasChanges:j})},[t,j,o]),n.useEffect(()=>{w()},[]),n.useEffect(()=>{if(h){const f=setTimeout(()=>a(null),3e3);return()=>clearTimeout(f)}},[h]);const w=async()=>{try{p(!0),y(null);const f=await Y("/api/settings/models");if(f.ok){const N=await f.json();l(N.models||{}),d(N.models||{})}else{const N=await f.json();y(N.error||"加载模型配置失败")}}catch(f){y(f.message)}finally{p(!1)}},b=async()=>{try{x(!0),a(null);const f=await Y("/api/settings/models",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({models:u})});if(f.ok)return a("success"),d({...u}),!0;{const N=await f.json();return a("error"),y(N.error||"保存失败"),!1}}catch(f){return a("error"),y(f.message),!1}finally{x(!1)}},k=()=>{l({...m}),a(null)};return n.useImperativeHandle(c,()=>({save:b,reset:k,get hasChanges(){return j},get saving(){return t}}),[j,t,u,m]),s?e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx("div",{className:"animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500"}),e.jsx("span",{className:"ml-3 text-sm text-muted-foreground",children:"加载模型配置..."})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-start gap-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-3",children:[e.jsx(Qr,{className:"w-4 h-4 text-blue-500 mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"text-sm text-blue-700 dark:text-blue-300",children:[e.jsxs("p",{children:["自定义模型 ID 来覆盖 ",et," 和 Claude Code 使用的默认模型。留空表示使用默认模型。"]}),e.jsx("p",{className:"mt-1 text-blue-600 dark:text-blue-400",children:"非 Claude 模型将按 Sonnet 定价计费,但统计中会记录实际模型 ID。"})]})]}),i&&e.jsx("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-3 text-sm text-red-600 dark:text-red-400",children:i}),h==="success"&&e.jsx("div",{className:"bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-3 text-sm text-green-600 dark:text-green-400",children:"模型配置已保存"}),Uc.map(f=>e.jsx("div",{className:"bg-gray-50 dark:bg-gray-900/50 border border-gray-200 dark:border-gray-700 rounded-lg p-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"font-medium text-sm text-foreground",children:f.label}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:f.description})]}),e.jsx("input",{type:"text",value:u[f.key]||"",onChange:N=>l(S=>({...S,[f.key]:N.target.value})),placeholder:f.placeholder,className:"w-full text-sm bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 rounded-lg focus:ring-blue-500 focus:border-blue-500 px-3 py-2"}),e.jsx("p",{className:"text-xs text-muted-foreground font-mono",children:f.key})]})},f.key))]})});function Yc({onClose:r,onInstalled:o,onOpenRepoManager:c,projects:u=[]}){const{showAlert:l}=it(),[m,d]=n.useState([]),[s,p]=n.useState([]),[t,x]=n.useState(!0),[h,a]=n.useState(null),[i,y]=n.useState(""),[j,w]=n.useState("all"),[b,k]=n.useState(null),[f,N]=n.useState(null),[S,I]=n.useState("user"),[D,T]=n.useState("");n.useEffect(()=>{R()},[]);const R=async(C=!1)=>{try{x(!0),a(null),C&&await Y("/api/skills/repos/refresh",{method:"POST"});const[$,te]=await Promise.all([Y("/api/skills/available"),Y("/api/skills/repos")]);if($.ok){const ne=await $.json();d(ne.skills||[])}if(te.ok){const ne=await te.json();p(ne.repos||[])}}catch($){a($.message)}finally{x(!1)}},M=C=>{N(C),I("user"),T("")},E=()=>{N(null),I("user"),T("")},W=async()=>{const C=f;if(C){if(S==="local"&&!D){l("请选择要安装到的项目",{variant:"warning"});return}try{N(null),k(C.name);const $={skillPath:C.path};S==="local"&&D&&($.projectPath=D);const te=await Y(`/api/skills/install/${C.name}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify($)});if(te.ok)d(ne=>ne.map(G=>G.name===C.name?{...G,installed:!0}:G)),o?.();else{const ne=await te.json();l(ne.error||"安装技能失败",{variant:"error"})}}catch($){l($.message,{variant:"error"})}finally{k(null),I("user"),T("")}}},X=m.filter(C=>{if(i){const $=i.toLowerCase();if(!C.name.toLowerCase().includes($)&&!C.title?.toLowerCase().includes($)&&!C.description?.toLowerCase().includes($))return!1}return!(j!=="all"&&C.repository!==j)});return e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4",children:e.jsxs("div",{className:"bg-background rounded-xl shadow-xl w-full max-w-4xl max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-border",children:[e.jsx("h2",{className:"text-lg font-semibold text-foreground",children:"Skills 管理"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(B,{variant:"ghost",size:"sm",onClick:()=>R(!0),disabled:t,children:[e.jsx(st,{className:`w-4 h-4 ${t?"animate-spin":""}`}),e.jsx("span",{className:"ml-1 hidden sm:inline",children:"刷新"})]}),e.jsxs(B,{variant:"ghost",size:"sm",onClick:c,children:[e.jsx(Ht,{className:"w-4 h-4"}),e.jsx("span",{className:"ml-1 hidden sm:inline",children:"仓库管理"})]}),e.jsx(B,{variant:"ghost",size:"icon",onClick:r,children:e.jsx(Ue,{className:"w-5 h-5"})})]})]}),e.jsx("div",{className:"px-4 pt-4 pb-2"}),e.jsxs("div",{className:"px-4 pb-4 flex flex-wrap gap-3",children:[e.jsx("div",{className:"flex-1 min-w-[200px]",children:e.jsxs("div",{className:"relative",children:[e.jsx(St,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground"}),e.jsx(at,{type:"text",placeholder:"搜索技能名称或描述...",value:i,onChange:C=>y(C.target.value),className:"pl-10"})]})}),e.jsxs("select",{value:j,onChange:C=>w(C.target.value),className:"px-3 py-2 rounded-md border border-border bg-background text-foreground text-sm min-w-[120px]",children:[e.jsx("option",{value:"all",children:"全部"}),s.map(C=>e.jsxs("option",{value:`${C.owner}/${C.repo}`,children:[C.owner,"/",C.repo]},`${C.owner}/${C.repo}`))]})]}),e.jsxs("div",{className:"flex-1 overflow-auto px-4 pb-4",children:[h&&e.jsx("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 text-red-800 dark:text-red-200 text-sm mb-4",children:h}),t?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"加载中..."}):X.length===0?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:m.length===0?e.jsxs(e.Fragment,{children:[e.jsx("p",{children:"没有可用的技能"}),e.jsx("p",{className:"text-xs mt-2",children:"请先添加技能仓库"}),e.jsxs(B,{variant:"outline",size:"sm",className:"mt-4",onClick:c,children:[e.jsx(Ht,{className:"w-4 h-4 mr-2"}),"管理仓库"]})]}):e.jsx("p",{children:"没有找到匹配的技能"})}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:X.map(C=>{const $=b===C.name,te=f?.name===C.name;return e.jsx("div",{className:"border border-border rounded-lg p-4 hover:border-amber-500/50 transition-colors",children:e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"mb-2",children:[e.jsx("h4",{className:"font-medium text-foreground",children:C.title||C.name}),e.jsxs("div",{className:"flex items-center gap-1 mt-1",children:[e.jsxs("span",{className:"text-xs text-muted-foreground",children:["skills/",C.name]}),e.jsx(tt,{variant:"outline",className:"text-xs ml-2",children:C.repository})]})]}),C.description&&e.jsx("p",{className:"text-sm text-muted-foreground flex-1 line-clamp-3 mb-3",children:C.description}),te&&e.jsxs("div",{className:"mt-2 mb-3 p-3 rounded-lg bg-muted/50 border border-border text-sm",children:[e.jsx("p",{className:"font-medium text-foreground mb-2",children:"选择安装位置"}),e.jsxs("label",{className:"flex items-center gap-2 mb-1 cursor-pointer",children:[e.jsx("input",{type:"radio",name:`scope-${C.name}`,value:"user",checked:S==="user",onChange:()=>{I("user"),T("")},className:"accent-amber-600"}),e.jsx("span",{className:"text-foreground",children:"全局(所有项目可用)"})]}),e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:`scope-${C.name}`,value:"local",checked:S==="local",onChange:()=>I("local"),className:"accent-amber-600"}),e.jsx("span",{className:"text-foreground",children:"安装到指定项目"})]}),S==="local"&&e.jsxs("select",{value:D,onChange:ne=>T(ne.target.value),className:"mt-2 w-full px-2 py-1.5 rounded-md border border-border bg-background text-foreground text-xs",children:[e.jsx("option",{value:"",children:"选择项目..."}),u.map(ne=>e.jsx("option",{value:ne.path||ne.fullPath,children:ne.displayName||ne.name},ne.name))]}),e.jsxs("div",{className:"flex gap-2 mt-3",children:[e.jsx(B,{size:"sm",variant:"outline",onClick:E,className:"flex-1",children:"取消"}),e.jsx(B,{size:"sm",className:"bg-amber-600 hover:bg-amber-700 text-white flex-1",onClick:W,children:"确认安装"})]})]}),e.jsxs("div",{className:"flex items-center gap-2 mt-auto pt-2",children:[e.jsxs(B,{variant:"ghost",size:"sm",onClick:()=>window.open(`https://github.com/${C.repository}`,"_blank"),children:[e.jsx(Vo,{className:"w-4 h-4 mr-1"}),"查看"]}),C.installed?e.jsx(B,{size:"sm",disabled:!0,variant:"outline",className:"ml-auto",children:"已安装"}):!te&&e.jsxs(B,{size:"sm",className:"bg-amber-600 hover:bg-amber-700 text-white ml-auto",onClick:()=>M(C),disabled:$||!!f,children:[e.jsx(It,{className:"w-4 h-4 mr-1"}),$?"安装中...":"安装"]})]})]})},`${C.repository}-${C.name}`)})})]})]})})}function Jc({onClose:r,onChanged:o}){const{showAlert:c,showConfirm:u}=it(),[l,m]=n.useState([]),[d,s]=n.useState(!0),[p,t]=n.useState(null),[x,h]=n.useState(""),[a,i]=n.useState("main"),[y,j]=n.useState(!1),[w,b]=n.useState(null);n.useEffect(()=>{k()},[]);const k=async()=>{try{s(!0),t(null);const S=await Y("/api/skills/repos");if(S.ok){const I=await S.json();m(I.repos||[])}else{const I=await S.json();t(I.error||"Failed to fetch repos")}}catch(S){t(S.message)}finally{s(!1)}},f=async S=>{if(S.preventDefault(),!x.trim()){t("请输入仓库 URL");return}try{j(!0),t(null);const I=await Y("/api/skills/repos",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:x.trim(),branch:a.trim()||"main"})});if(I.ok)h(""),i("main"),k(),o?.();else{const D=await I.json();t(D.error||"Failed to add repo")}}catch(I){t(I.message)}finally{j(!1)}},N=async(S,I)=>{if(await u(`确定要移除仓库 "${S}/${I}" 吗?`,{title:"移除仓库",variant:"danger",confirmText:"确认移除"}))try{b(`${S}/${I}`);const D=await Y(`/api/skills/repos/${S}/${I}`,{method:"DELETE"});if(D.ok)k(),o?.();else{const T=await D.json();c(T.error||"移除仓库失败",{variant:"error"})}}catch(D){c(D.message,{variant:"error"})}finally{b(null)}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4",children:e.jsxs("div",{className:"bg-background rounded-xl shadow-xl w-full max-w-2xl max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"flex items-center gap-3 p-4 border-b border-border",children:[e.jsx(B,{variant:"ghost",size:"icon",onClick:r,children:e.jsx(er,{className:"w-5 h-5"})}),e.jsx("h2",{className:"text-lg font-semibold text-foreground",children:"管理技能仓库"})]}),e.jsxs("div",{className:"flex-1 overflow-auto p-4 space-y-6",children:[e.jsxs("div",{className:"bg-gray-50 dark:bg-gray-900/50 rounded-lg p-4 space-y-4",children:[e.jsx("h3",{className:"font-medium text-foreground",children:"添加技能仓库"}),e.jsxs("form",{onSubmit:f,className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm text-muted-foreground mb-1",children:"仓库 URL"}),e.jsx(at,{type:"text",placeholder:"owner/name 或 https://github.com/owner/name",value:x,onChange:S=>h(S.target.value),disabled:y})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm text-muted-foreground mb-1",children:"分支"}),e.jsx(at,{type:"text",placeholder:"main",value:a,onChange:S=>i(S.target.value),disabled:y})]}),e.jsxs(B,{type:"submit",disabled:y||!x.trim(),className:"bg-amber-600 hover:bg-amber-700 text-white",children:[e.jsx(_t,{className:"w-4 h-4 mr-2"}),y?"添加中...":"添加仓库"]})]})]}),p&&e.jsx("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 text-red-800 dark:text-red-200 text-sm",children:p}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("h3",{className:"font-medium text-foreground",children:"已添加的仓库"}),d?e.jsx("div",{className:"text-center py-4 text-muted-foreground",children:"加载中..."}):l.length===0?e.jsxs("div",{className:"text-center py-8 text-muted-foreground",children:[e.jsx(Zo,{className:"w-12 h-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"还没有添加任何仓库"})]}):l.map(S=>e.jsx("div",{className:"bg-gray-50 dark:bg-gray-900/50 border border-gray-200 dark:border-gray-700 rounded-lg p-4",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"font-medium text-foreground",children:[S.owner,"/",S.repo]}),S.isSystem&&e.jsx(tt,{variant:"outline",className:"text-xs bg-amber-50 dark:bg-amber-900/20 text-amber-700 dark:text-amber-300",children:"内置"})]}),e.jsxs("div",{className:"flex items-center gap-3 mt-1 text-sm text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(tn,{className:"w-3 h-3"}),"分支: main"]}),e.jsxs(tt,{variant:"outline",className:"text-xs",children:["识别到 ",S.skillCount," 个技能"]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 ml-4",children:[!S.isSystem&&S.url&&e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>window.open(S.url,"_blank"),children:e.jsx(Vo,{className:"w-4 h-4"})}),!S.isSystem&&e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>N(S.owner,S.repo),disabled:w===`${S.owner}/${S.repo}`,className:"text-red-500 hover:text-red-600",children:e.jsx(xt,{className:"w-4 h-4"})})]})]})},`${S.owner}/${S.repo}`))]})]})]})})}function qc({projects:r=[]}){const{showAlert:o,showConfirm:c}=it(),[u,l]=n.useState([]),[m,d]=n.useState(!0),[s,p]=n.useState(null),[t,x]=n.useState(!1),[h,a]=n.useState(!1),[i,y]=n.useState(!1),[j,w]=n.useState(null),b=n.useRef(null);n.useEffect(()=>{k()},[]);const k=async()=>{try{d(!0),p(null);const M=await Y("/api/skills");if(M.ok){const E=await M.json();l(E.skills||[])}else{const E=await M.json();p(E.error||"Failed to fetch skills")}}catch(M){p(M.message)}finally{d(!1)}},f=async()=>{try{const M=await Y("/api/skills");if(M.ok){const E=await M.json();l(E.skills||[])}}catch{}},N=async M=>{try{const E=await Y(`/api/skills/${M}/download`);if(!E.ok){const $=await E.json();o($.error||"下载技能失败",{variant:"error"});return}const W=await E.blob(),X=URL.createObjectURL(W),C=document.createElement("a");C.href=X,C.download=`${M}.zip`,C.click(),URL.revokeObjectURL(X)}catch(E){o(E.message,{variant:"error"})}},S=async M=>{if(await c(`确定要删除技能 "${M.name}" 吗?`,{title:"删除技能",variant:"danger",confirmText:"确认删除"}))try{const E=M.projectPath?`/api/skills/${M.name}?projectPath=${encodeURIComponent(M.projectPath)}`:`/api/skills/${M.name}`,W=await Y(E,{method:"DELETE"});if(W.ok)k();else{const X=await W.json();o(X.error||"删除技能失败",{variant:"error"})}}catch(E){o(E.message,{variant:"error"})}},I=async M=>{let E,W;if(M.syncType==="builtin"?(W="同步修改到云端",E=`确定要将技能 "${M.name}" 的本地修改推送到共享仓库吗?
154
+ `;if(typeof document<"u"){const r=document.createElement("style");r.type="text/css",r.innerText=Nc,document.head.appendChild(r)}function Tc({selectedProject:r,selectedSession:o,initialCommand:c,isPlainShell:u=!1,onProcessComplete:l,minimal:m=!1,autoConnect:d=!1}){const s=n.useRef(null),p=n.useRef(null),t=n.useRef(null),x=n.useRef(null),[h,a]=n.useState(!1),[i,y]=n.useState(!1),[j,w]=n.useState(!1),[b,k]=n.useState(null),[f,N]=n.useState(!1),S=n.useRef(r),I=n.useRef(o),D=n.useRef(c),T=n.useRef(u),R=n.useRef(l);n.useEffect(()=>{S.current=r,I.current=o,D.current=c,T.current=u,R.current=l});const M=n.useCallback(async()=>{if(!(f||h))try{const ne=localStorage.getItem("auth-token");if(!ne){console.error("No authentication token found for Shell WebSocket connection");return}const ie=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/shell?token=${encodeURIComponent(ne)}`;x.current=new WebSocket(ie),x.current.onopen=()=>{a(!0),N(!1),setTimeout(()=>{t.current&&p.current&&(t.current.fit(),x.current.send(JSON.stringify({type:"init",projectPath:S.current.fullPath||S.current.path,sessionId:T.current?null:I.current?.id,hasSession:T.current?!1:!!I.current,provider:T.current?"plain-shell":I.current?.__provider||"claude",cols:p.current.cols,rows:p.current.rows,initialCommand:D.current,isPlainShell:T.current})))},100)},x.current.onmessage=le=>{try{const xe=JSON.parse(le.data);if(xe.type==="output"){let Ce=xe.data;if(T.current&&R.current){const be=Ce.replace(/\x1b\[[0-9;]*m/g,"");if(be.includes("Process exited with code 0"))R.current(0);else if(be.match(/Process exited with code (\d+)/)){const Se=parseInt(be.match(/Process exited with code (\d+)/)[1]);Se!==0&&R.current(Se)}}p.current&&p.current.write(Ce)}else xe.type==="url_open"&&window.open(xe.url,"_blank")}catch(xe){console.error("[Shell] Error handling WebSocket message:",xe,le.data)}},x.current.onclose=le=>{a(!1),N(!1),p.current&&(p.current.clear(),p.current.write("\x1B[2J\x1B[H"))},x.current.onerror=le=>{a(!1),N(!1)}}catch{a(!1),N(!1)}},[f,h]),E=n.useCallback(()=>{!i||h||f||(N(!0),M())},[i,h,f,M]),W=n.useCallback(()=>{x.current&&(x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"terminate"})),x.current.close(),x.current=null),p.current&&(p.current.clear(),p.current.write("\x1B[2J\x1B[H")),a(!1),N(!1)},[]),X=n.useMemo(()=>o?o.summary||"New Session":null,[o]),C=n.useMemo(()=>X?X.slice(0,30):null,[X]),$=n.useMemo(()=>X?X.slice(0,50):null,[X]),te=()=>{w(!0),x.current&&(x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"terminate"})),x.current.close(),x.current=null),p.current&&(p.current.dispose(),p.current=null,t.current=null),a(!1),y(!1),setTimeout(()=>{w(!1)},200)};return n.useEffect(()=>{const ne=o?.id||null;b!==null&&b!==ne&&i&&W(),k(ne)},[o?.id,i,W]),n.useEffect(()=>{if(!s.current||!r||j||p.current)return;p.current=new Kn.Terminal({cursorBlink:!0,fontSize:14,fontFamily:'Menlo, Monaco, "Courier New", monospace',allowProposedApi:!0,allowTransparency:!1,convertEol:!0,scrollback:1e4,tabStopWidth:4,windowsMode:!1,macOptionIsMeta:!0,macOptionClickForcesSelection:!1,theme:{background:"#1e1e1e",foreground:"#d4d4d4",cursor:"#ffffff",cursorAccent:"#1e1e1e",selection:"#264f78",selectionForeground:"#ffffff",black:"#000000",red:"#cd3131",green:"#0dbc79",yellow:"#e5e510",blue:"#2472c8",magenta:"#bc3fbc",cyan:"#11a8cd",white:"#e5e5e5",brightBlack:"#666666",brightRed:"#f14c4c",brightGreen:"#23d18b",brightYellow:"#f5f543",brightBlue:"#3b8eea",brightMagenta:"#d670d6",brightCyan:"#29b8db",brightWhite:"#ffffff",extendedAnsi:["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff"]}}),t.current=new Vn.FitAddon;const ne=new Zn.WebglAddon,G=new Qn.WebLinksAddon;p.current.loadAddon(t.current),p.current.loadAddon(G);try{p.current.loadAddon(ne)}catch{console.warn("[Shell] WebGL renderer unavailable, using Canvas fallback")}p.current.open(s.current),p.current.attachCustomKeyEventHandler(le=>(le.ctrlKey||le.metaKey)&&le.key==="c"&&p.current.hasSelection()?(document.execCommand("copy"),!1):(le.ctrlKey||le.metaKey)&&le.key==="v"?(navigator.clipboard.readText().then(xe=>{x.current&&x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"input",data:xe}))}).catch(()=>{}),!1):!0),setTimeout(()=>{t.current&&(t.current.fit(),p.current&&x.current&&x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"resize",cols:p.current.cols,rows:p.current.rows})))},100),y(!0),p.current.onData(le=>{x.current&&x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"input",data:le}))});const ie=new ResizeObserver(()=>{t.current&&p.current&&setTimeout(()=>{t.current.fit(),x.current&&x.current.readyState===WebSocket.OPEN&&x.current.send(JSON.stringify({type:"resize",cols:p.current.cols,rows:p.current.rows}))},50)});return s.current&&ie.observe(s.current),()=>{ie.disconnect(),x.current&&(x.current.readyState===WebSocket.OPEN||x.current.readyState===WebSocket.CONNECTING)&&x.current.close(),x.current=null,p.current&&(p.current.dispose(),p.current=null)}},[r?.path||r?.fullPath,j]),n.useEffect(()=>{!d||!i||f||h||E()},[d,i,f,h,E]),r?m?e.jsx("div",{className:"h-full w-full bg-gray-900",children:e.jsx("div",{ref:s,className:"h-full w-full focus:outline-none",style:{outline:"none"}})}):e.jsxs("div",{className:"h-full flex flex-col bg-gray-900 w-full",children:[e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx("div",{className:`w-2 h-2 rounded-full ${h?"bg-green-500":"bg-red-500"}`}),o&&e.jsxs("span",{className:"text-xs text-blue-300",children:["(",C,"...)"]}),!o&&e.jsx("span",{className:"text-xs text-gray-400",children:"(新会话)"}),!i&&e.jsx("span",{className:"text-xs text-yellow-400",children:"(正在初始化...)"}),j&&e.jsx("span",{className:"text-xs text-blue-400",children:"(正在重启...)"})]}),e.jsxs("div",{className:"flex items-center space-x-3",children:[h&&e.jsxs("button",{onClick:W,className:"px-3 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700 flex items-center space-x-1",title:"断开 Shell 连接",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})}),e.jsx("span",{children:"断开连接"})]}),e.jsxs("button",{onClick:te,disabled:j||h,className:"text-xs text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed flex items-center space-x-1",title:"重启 Shell(先断开连接)",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),e.jsx("span",{children:"重启"})]})]})]})}),e.jsxs("div",{className:"flex-1 p-2 overflow-hidden relative",children:[e.jsx("div",{ref:s,className:"h-full w-full focus:outline-none",style:{outline:"none"}}),!i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90",children:e.jsx("div",{className:"text-white",children:"加载终端中..."})}),i&&!h&&!f&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("button",{onClick:E,className:"px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors flex items-center justify-center space-x-2 text-base font-medium w-full sm:w-auto",title:"Connect to shell",children:[e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),e.jsx("span",{children:"在 Shell 中继续"})]}),e.jsx("p",{className:"text-gray-400 text-sm mt-3 px-2",children:u?`Run ${c||"command"} in ${r.displayName}`:o?`Resume session: ${$}...`:"Start a new Claude session"})]})}),f&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("div",{className:"flex items-center justify-center space-x-3 text-yellow-400",children:[e.jsx("div",{className:"w-6 h-6 animate-spin rounded-full border-2 border-yellow-400 border-t-transparent"}),e.jsx("span",{className:"text-base font-medium",children:"连接到 Shell..."})]}),e.jsx("p",{className:"text-gray-400 text-sm mt-3 px-2",children:u?`Running ${c||"command"} in ${r.displayName}`:`Starting Claude CLI in ${r.displayName}`})]})})]})]}):e.jsx("div",{className:"h-full flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"选择项目"}),e.jsx("p",{children:"选择一个项目以在该目录中打开交互式 Shell"})]})})}function Sc({project:r,session:o=null,command:c=null,isPlainShell:u=null,autoConnect:l=!0,onComplete:m=null,onClose:d=null,title:s=null,className:p="",showHeader:t=!0,compact:x=!1,minimal:h=!1}){const[a,i]=n.useState(!1),y=u!==null?u:c!==null,j=n.useCallback(w=>{i(!0),m&&m(w)},[m]);return r?e.jsxs("div",{className:`h-full w-full flex flex-col ${p}`,children:[!h&&t&&s&&e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx("h3",{className:"text-sm font-medium text-gray-200",children:s}),a&&e.jsx("span",{className:"text-xs text-green-400",children:"(已完成)"})]}),d&&e.jsx("button",{onClick:d,className:"text-gray-400 hover:text-white",title:"关闭",children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),e.jsx("div",{className:"flex-1 w-full min-h-0",children:e.jsx(Tc,{selectedProject:r,selectedSession:o,initialCommand:c,isPlainShell:y,onProcessComplete:j,minimal:h,autoConnect:h?!0:l})})]}):e.jsx("div",{className:`h-full flex items-center justify-center ${p}`,children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"未选择项目"}),e.jsx("p",{children:"打开 Shell 需要一个项目"})]})})}function Xc({selectedProject:r,minimal:o=!1,autoConnect:c=!1}){const u=n.useRef(null),l=n.useRef(null),m=n.useRef(null),d=n.useRef(null),[s,p]=n.useState(!1),[t,x]=n.useState(!1),[h,a]=n.useState(!1),[i,y]=n.useState(!1),j=n.useRef(r);n.useEffect(()=>{j.current=r});const w=n.useCallback(async()=>{if(!(i||s))try{const N=localStorage.getItem("auth-token");if(!N){console.error("No authentication token found for Codex WebSocket connection");return}const I=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/codex?token=${encodeURIComponent(N)}`;d.current=new WebSocket(I),d.current.onopen=()=>{p(!0),y(!1),setTimeout(()=>{m.current&&l.current&&(m.current.fit(),d.current.send(JSON.stringify({type:"init",projectPath:j.current.fullPath||j.current.path,cols:l.current.cols,rows:l.current.rows})))},100)},d.current.onmessage=D=>{try{const T=JSON.parse(D.data);T.type==="output"?l.current&&l.current.write(T.data):T.type==="url_open"&&window.open(T.url,"_blank")}catch(T){console.error("[CodexShell] Error handling WebSocket message:",T)}},d.current.onclose=()=>{p(!1),y(!1),l.current&&(l.current.clear(),l.current.write("\x1B[2J\x1B[H"))},d.current.onerror=()=>{p(!1),y(!1)}}catch{p(!1),y(!1)}},[i,s]),b=n.useCallback(()=>{!t||s||i||(y(!0),w())},[t,s,i,w]),k=n.useCallback(()=>{d.current&&(d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"terminate"})),d.current.close(),d.current=null),l.current&&(l.current.clear(),l.current.write("\x1B[2J\x1B[H")),p(!1),y(!1)},[]),f=()=>{a(!0),d.current&&(d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"terminate"})),d.current.close(),d.current=null),l.current&&(l.current.dispose(),l.current=null,m.current=null),p(!1),x(!1),setTimeout(()=>a(!1),200)};return n.useEffect(()=>{if(!u.current||!r||h||l.current)return;l.current=new Kn.Terminal({cursorBlink:!0,fontSize:14,fontFamily:'Menlo, Monaco, "Courier New", monospace',allowProposedApi:!0,allowTransparency:!1,convertEol:!0,scrollback:1e4,tabStopWidth:4,windowsMode:!1,macOptionIsMeta:!0,macOptionClickForcesSelection:!1,theme:{background:"#1e1e1e",foreground:"#d4d4d4",cursor:"#ffffff",cursorAccent:"#1e1e1e",selection:"#264f78",selectionForeground:"#ffffff",black:"#000000",red:"#cd3131",green:"#0dbc79",yellow:"#e5e510",blue:"#2472c8",magenta:"#bc3fbc",cyan:"#11a8cd",white:"#e5e5e5",brightBlack:"#666666",brightRed:"#f14c4c",brightGreen:"#23d18b",brightYellow:"#f5f543",brightBlue:"#3b8eea",brightMagenta:"#d670d6",brightCyan:"#29b8db",brightWhite:"#ffffff"}}),m.current=new Vn.FitAddon;const N=new Zn.WebglAddon,S=new Qn.WebLinksAddon;l.current.loadAddon(m.current),l.current.loadAddon(S);try{l.current.loadAddon(N)}catch{console.warn("[CodexShell] WebGL renderer unavailable, using Canvas fallback")}l.current.open(u.current),l.current.attachCustomKeyEventHandler(D=>(D.ctrlKey||D.metaKey)&&D.key==="c"&&l.current.hasSelection()?(document.execCommand("copy"),!1):(D.ctrlKey||D.metaKey)&&D.key==="v"?(navigator.clipboard.readText().then(T=>{d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"input",data:T}))}).catch(()=>{}),!1):!0),setTimeout(()=>{m.current&&(m.current.fit(),l.current&&d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"resize",cols:l.current.cols,rows:l.current.rows})))},100),x(!0),l.current.onData(D=>{d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"input",data:D}))});const I=new ResizeObserver(()=>{m.current&&l.current&&setTimeout(()=>{m.current.fit(),d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"resize",cols:l.current.cols,rows:l.current.rows}))},50)});return u.current&&I.observe(u.current),()=>{I.disconnect(),d.current&&(d.current.readyState===WebSocket.OPEN||d.current.readyState===WebSocket.CONNECTING)&&d.current.close(),d.current=null,l.current&&(l.current.dispose(),l.current=null)}},[r?.path||r?.fullPath,h]),n.useEffect(()=>{!c||!t||i||s||b()},[c,t,i,s,b]),r?o?e.jsx("div",{className:"h-full w-full bg-gray-900",children:e.jsx("div",{ref:u,className:"h-full w-full focus:outline-none",style:{outline:"none"}})}):e.jsxs("div",{className:"h-full flex flex-col bg-gray-900 w-full",children:[e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx("div",{className:`w-2 h-2 rounded-full ${s?"bg-green-500":"bg-red-500"}`}),e.jsx("span",{className:"text-xs text-gray-300 font-medium",children:"Codex"}),!t&&e.jsx("span",{className:"text-xs text-yellow-400",children:"(正在初始化...)"}),h&&e.jsx("span",{className:"text-xs text-blue-400",children:"(正在重启...)"})]}),e.jsxs("div",{className:"flex items-center space-x-3",children:[s&&e.jsxs("button",{onClick:k,className:"px-3 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700 flex items-center space-x-1",title:"断开 Codex 连接",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})}),e.jsx("span",{children:"断开连接"})]}),e.jsxs("button",{onClick:f,disabled:h||s,className:"text-xs text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed flex items-center space-x-1",title:"重启 Codex(先断开连接)",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),e.jsx("span",{children:"重启"})]})]})]})}),e.jsxs("div",{className:"flex-1 p-2 overflow-hidden relative",children:[e.jsx("div",{ref:u,className:"h-full w-full focus:outline-none",style:{outline:"none"}}),!t&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90",children:e.jsx("div",{className:"text-white",children:"加载终端中..."})}),t&&!s&&!i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("button",{onClick:b,className:"px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors flex items-center justify-center space-x-2 text-base font-medium w-full sm:w-auto",children:[e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),e.jsx("span",{children:"启动 Codex"})]}),e.jsxs("p",{className:"text-gray-400 text-sm mt-3 px-2",children:["在 ",r.displayName," 中启动 Codex CLI"]})]})}),i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("div",{className:"flex items-center justify-center space-x-3 text-yellow-400",children:[e.jsx("div",{className:"w-6 h-6 animate-spin rounded-full border-2 border-yellow-400 border-t-transparent"}),e.jsx("span",{className:"text-base font-medium",children:"连接到 Codex..."})]}),e.jsxs("p",{className:"text-gray-400 text-sm mt-3 px-2",children:["正在 ",r.displayName," 中启动 Codex CLI"]})]})})]})]}):e.jsx("div",{className:"h-full flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"选择项目"}),e.jsx("p",{children:"选择一个项目以在该目录中打开 Codex"})]})})}function Mc({project:r,autoConnect:o=!0,onClose:c=null,className:u="",showHeader:l=!0,minimal:m=!1}){return r?e.jsxs("div",{className:`h-full w-full flex flex-col ${u}`,children:[!m&&l&&c&&e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-medium text-gray-200",children:"Codex"}),e.jsx("button",{onClick:c,className:"text-gray-400 hover:text-white",title:"关闭",children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),e.jsx("div",{className:"flex-1 w-full min-h-0",children:e.jsx(Xc,{selectedProject:r,minimal:m,autoConnect:m?!0:o})})]}):e.jsx("div",{className:`h-full flex items-center justify-center ${u}`,children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"未选择项目"}),e.jsx("p",{children:"打开 Codex 需要一个项目"})]})})}function Oc({selectedProject:r,minimal:o=!1,autoConnect:c=!1}){const u=n.useRef(null),l=n.useRef(null),m=n.useRef(null),d=n.useRef(null),[s,p]=n.useState(!1),[t,x]=n.useState(!1),[h,a]=n.useState(!1),[i,y]=n.useState(!1),j=n.useRef(r);n.useEffect(()=>{j.current=r});const w=n.useCallback(async()=>{if(!(i||s))try{const N=localStorage.getItem("auth-token");if(!N){console.error("No authentication token found for Gemini WebSocket connection");return}const I=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/gemini?token=${encodeURIComponent(N)}`;d.current=new WebSocket(I),d.current.onopen=()=>{p(!0),y(!1),setTimeout(()=>{m.current&&l.current&&(m.current.fit(),d.current.send(JSON.stringify({type:"init",projectPath:j.current.fullPath||j.current.path,cols:l.current.cols,rows:l.current.rows})))},100)},d.current.onmessage=D=>{try{const T=JSON.parse(D.data);T.type==="output"?l.current&&l.current.write(T.data):T.type==="url_open"&&window.open(T.url,"_blank")}catch(T){console.error("[GeminiShell] Error handling WebSocket message:",T)}},d.current.onclose=()=>{p(!1),y(!1),l.current&&(l.current.clear(),l.current.write("\x1B[2J\x1B[H"))},d.current.onerror=()=>{p(!1),y(!1)}}catch{p(!1),y(!1)}},[i,s]),b=n.useCallback(()=>{!t||s||i||(y(!0),w())},[t,s,i,w]),k=n.useCallback(()=>{d.current&&(d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"terminate"})),d.current.close(),d.current=null),l.current&&(l.current.clear(),l.current.write("\x1B[2J\x1B[H")),p(!1),y(!1)},[]),f=()=>{a(!0),d.current&&(d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"terminate"})),d.current.close(),d.current=null),l.current&&(l.current.dispose(),l.current=null,m.current=null),p(!1),x(!1),setTimeout(()=>a(!1),200)};return n.useEffect(()=>{if(!u.current||!r||h||l.current)return;l.current=new Kn.Terminal({cursorBlink:!0,fontSize:14,fontFamily:'Menlo, Monaco, "Courier New", monospace',allowProposedApi:!0,allowTransparency:!1,convertEol:!0,scrollback:1e4,tabStopWidth:4,windowsMode:!1,macOptionIsMeta:!0,macOptionClickForcesSelection:!1,theme:{background:"#1e1e1e",foreground:"#d4d4d4",cursor:"#ffffff",cursorAccent:"#1e1e1e",selection:"#264f78",selectionForeground:"#ffffff",black:"#000000",red:"#cd3131",green:"#0dbc79",yellow:"#e5e510",blue:"#2472c8",magenta:"#bc3fbc",cyan:"#11a8cd",white:"#e5e5e5",brightBlack:"#666666",brightRed:"#f14c4c",brightGreen:"#23d18b",brightYellow:"#f5f543",brightBlue:"#3b8eea",brightMagenta:"#d670d6",brightCyan:"#29b8db",brightWhite:"#ffffff"}}),m.current=new Vn.FitAddon;const N=new Zn.WebglAddon,S=new Qn.WebLinksAddon;l.current.loadAddon(m.current),l.current.loadAddon(S);try{l.current.loadAddon(N)}catch{console.warn("[GeminiShell] WebGL renderer unavailable, using Canvas fallback")}l.current.open(u.current),l.current.attachCustomKeyEventHandler(D=>(D.ctrlKey||D.metaKey)&&D.key==="c"&&l.current.hasSelection()?(document.execCommand("copy"),!1):(D.ctrlKey||D.metaKey)&&D.key==="v"?(navigator.clipboard.readText().then(T=>{d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"input",data:T}))}).catch(()=>{}),!1):!0),setTimeout(()=>{m.current&&(m.current.fit(),l.current&&d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"resize",cols:l.current.cols,rows:l.current.rows})))},100),x(!0),l.current.onData(D=>{d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"input",data:D}))});const I=new ResizeObserver(()=>{m.current&&l.current&&setTimeout(()=>{m.current.fit(),d.current&&d.current.readyState===WebSocket.OPEN&&d.current.send(JSON.stringify({type:"resize",cols:l.current.cols,rows:l.current.rows}))},50)});return u.current&&I.observe(u.current),()=>{I.disconnect(),d.current&&(d.current.readyState===WebSocket.OPEN||d.current.readyState===WebSocket.CONNECTING)&&d.current.close(),d.current=null,l.current&&(l.current.dispose(),l.current=null)}},[r?.path||r?.fullPath,h]),n.useEffect(()=>{!c||!t||i||s||b()},[c,t,i,s,b]),r?o?e.jsx("div",{className:"h-full w-full bg-gray-900",children:e.jsx("div",{ref:u,className:"h-full w-full focus:outline-none",style:{outline:"none"}})}):e.jsxs("div",{className:"h-full flex flex-col bg-gray-900 w-full",children:[e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx("div",{className:`w-2 h-2 rounded-full ${s?"bg-green-500":"bg-red-500"}`}),e.jsx("span",{className:"text-xs text-gray-300 font-medium",children:"Gemini"}),!t&&e.jsx("span",{className:"text-xs text-yellow-400",children:"(正在初始化...)"}),h&&e.jsx("span",{className:"text-xs text-blue-400",children:"(正在重启...)"})]}),e.jsxs("div",{className:"flex items-center space-x-3",children:[s&&e.jsxs("button",{onClick:k,className:"px-3 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700 flex items-center space-x-1",title:"断开 Gemini 连接",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})}),e.jsx("span",{children:"断开连接"})]}),e.jsxs("button",{onClick:f,disabled:h||s,className:"text-xs text-gray-400 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed flex items-center space-x-1",title:"重启 Gemini(先断开连接)",children:[e.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),e.jsx("span",{children:"重启"})]})]})]})}),e.jsxs("div",{className:"flex-1 p-2 overflow-hidden relative",children:[e.jsx("div",{ref:u,className:"h-full w-full focus:outline-none",style:{outline:"none"}}),!t&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90",children:e.jsx("div",{className:"text-white",children:"加载终端中..."})}),t&&!s&&!i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("button",{onClick:b,className:"px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center justify-center space-x-2 text-base font-medium w-full sm:w-auto",children:[e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),e.jsx("span",{children:"启动 Gemini"})]}),e.jsxs("p",{className:"text-gray-400 text-sm mt-3 px-2",children:["在 ",r.displayName," 中启动 Gemini CLI"]})]})}),i&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900 bg-opacity-90 p-4",children:e.jsxs("div",{className:"text-center max-w-sm w-full",children:[e.jsxs("div",{className:"flex items-center justify-center space-x-3 text-yellow-400",children:[e.jsx("div",{className:"w-6 h-6 animate-spin rounded-full border-2 border-yellow-400 border-t-transparent"}),e.jsx("span",{className:"text-base font-medium",children:"连接到 Gemini..."})]}),e.jsxs("p",{className:"text-gray-400 text-sm mt-3 px-2",children:["正在 ",r.displayName," 中启动 Gemini CLI"]})]})})]})]}):e.jsx("div",{className:"h-full flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"选择项目"}),e.jsx("p",{children:"选择一个项目以在该目录中打开 Gemini"})]})})}function Cc({project:r,autoConnect:o=!0,onClose:c=null,className:u="",showHeader:l=!0,minimal:m=!1}){return r?e.jsxs("div",{className:`h-full w-full flex flex-col ${u}`,children:[!m&&l&&c&&e.jsx("div",{className:"flex-shrink-0 bg-gray-800 border-b border-gray-700 px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-medium text-gray-200",children:"Gemini"}),e.jsx("button",{onClick:c,className:"text-gray-400 hover:text-white",title:"关闭",children:e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),e.jsx("div",{className:"flex-1 w-full min-h-0",children:e.jsx(Oc,{selectedProject:r,minimal:m,autoConnect:m?!0:o})})]}):e.jsx("div",{className:`h-full flex items-center justify-center ${u}`,children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-4 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2z"})})}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"未选择项目"}),e.jsx("p",{children:"打开 Gemini 需要一个项目"})]})})}class Ec extends lt.Component{constructor(o){super(o),this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(o){return{hasError:!0}}componentDidCatch(o,c){console.error("ErrorBoundary caught an error:",o,c),this.setState({error:o,errorInfo:c})}render(){return this.state.hasError?e.jsx("div",{className:"flex flex-col items-center justify-center p-8 text-center",children:e.jsxs("div",{className:"bg-red-50 border border-red-200 rounded-lg p-6 max-w-md",children:[e.jsxs("div",{className:"flex items-center mb-4",children:[e.jsx("div",{className:"flex-shrink-0",children:e.jsx("svg",{className:"h-5 w-5 text-red-400",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})})}),e.jsx("h3",{className:"ml-3 text-sm font-medium text-red-800",children:"出现问题"})]}),e.jsxs("div",{className:"text-sm text-red-700",children:[e.jsx("p",{className:"mb-2",children:"加载聊天界面时出现错误。"}),this.props.showDetails&&this.state.error&&e.jsxs("details",{className:"mt-4",children:[e.jsx("summary",{className:"cursor-pointer text-xs font-mono",children:"错误详情"}),e.jsxs("pre",{className:"mt-2 text-xs bg-red-100 p-2 rounded overflow-auto max-h-40",children:[this.state.error.toString(),this.state.errorInfo&&this.state.errorInfo.componentStack]})]})]}),e.jsx("div",{className:"mt-4",children:e.jsx("button",{onClick:()=>{this.setState({hasError:!1,error:null,errorInfo:null}),this.props.onRetry&&this.props.onRetry()},className:"bg-red-600 text-white px-4 py-2 rounded text-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500",children:"重试"})})]})}):this.props.children}}const jr=({children:r,content:o,position:c="top",className:u="",delay:l=500})=>{const[m,d]=n.useState(!1),[s,p]=n.useState(null),t=()=>{const i=setTimeout(()=>{d(!0)},l);p(i)},x=()=>{s&&(clearTimeout(s),p(null)),d(!1)},h=()=>{switch(c){case"top":return"bottom-full left-1/2 transform -translate-x-1/2 mb-2";case"bottom":return"top-full left-1/2 transform -translate-x-1/2 mt-2";case"left":return"right-full top-1/2 transform -translate-y-1/2 mr-2";case"right":return"left-full top-1/2 transform -translate-y-1/2 ml-2";default:return"bottom-full left-1/2 transform -translate-x-1/2 mb-2"}},a=()=>{switch(c){case"top":return"top-full left-1/2 transform -translate-x-1/2 border-t-gray-900 dark:border-t-gray-100";case"bottom":return"bottom-full left-1/2 transform -translate-x-1/2 border-b-gray-900 dark:border-b-gray-100";case"left":return"left-full top-1/2 transform -translate-y-1/2 border-l-gray-900 dark:border-l-gray-100";case"right":return"right-full top-1/2 transform -translate-y-1/2 border-r-gray-900 dark:border-r-gray-100";default:return"top-full left-1/2 transform -translate-x-1/2 border-t-gray-900 dark:border-t-gray-100"}};return o?e.jsxs("div",{className:"relative inline-block",onMouseEnter:t,onMouseLeave:x,children:[r,m&&e.jsxs("div",{className:nt("absolute z-50 px-2 py-1 text-xs font-medium text-white bg-gray-900 dark:bg-gray-100 dark:text-gray-900 rounded shadow-lg whitespace-nowrap pointer-events-none","animate-in fade-in-0 zoom-in-95 duration-200",h(),u),children:[o,e.jsx("div",{className:nt("absolute w-0 h-0 border-4 border-transparent",a())})]})]}):r};function Dc(){const[r,o]=n.useState(null),[c,u]=n.useState([]),[l,m]=n.useState(!1),d=n.useRef(null),s=n.useRef(null),p=n.useRef(0),{token:t}=Xt();n.useEffect(()=>{d.current&&(clearTimeout(d.current),d.current=null),s.current&&(s.current.close(),s.current=null),t?(p.current=0,x()):(m(!1),o(null));const a=()=>{if(document.visibilityState==="visible"){const i=s.current?.readyState;(i===void 0||i===3||i===2)&&(d.current&&(clearTimeout(d.current),d.current=null),p.current=0,x())}};return document.addEventListener("visibilitychange",a),()=>{document.removeEventListener("visibilitychange",a),d.current&&clearTimeout(d.current),s.current&&s.current.close()}},[t]);const x=()=>{try{const a=t||localStorage.getItem("auth-token");if(!a){console.warn("No authentication token found for WebSocket connection");return}const y=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws?token=${encodeURIComponent(a)}`,j=new WebSocket(y);s.current=j,j.onopen=()=>{p.current=0,m(!0),o(j)},j.onmessage=w=>{try{const b=JSON.parse(w.data);u(k=>[...k,b])}catch(b){console.error("Error parsing WebSocket message:",b)}},j.onclose=()=>{if(m(!1),o(null),s.current=null,localStorage.getItem("auth-token")){const b=Math.min(1e3*Math.pow(2,p.current),15e3);p.current+=1,d.current=setTimeout(()=>{x()},b)}},j.onerror=w=>{console.error("WebSocket error:",w)}}catch(a){console.error("Error creating WebSocket connection:",a)}};return{ws:r,sendMessage:a=>{r&&l?r.send(JSON.stringify(a)):console.warn("WebSocket not connected")},messages:c,isConnected:l}}const ws=n.createContext({ws:null,sendMessage:()=>{},messages:[],isConnected:!1}),Ns=()=>{const r=n.useContext(ws);if(!r)throw new Error("useWebSocketContext must be used within a WebSocketProvider");return r},Pc=({children:r})=>{const o=Dc();return e.jsx(ws.Provider,{value:o,children:r})};function Ac({selectedProject:r,selectedSession:o,activeTab:c,setActiveTab:u,ws:l,sendMessage:m,messages:d,isMobile:s,isPWA:p,onMenuClick:t,isLoading:x,onInputFocusChange:h,onSessionActive:a,onSessionInactive:i,onSessionProcessing:y,onSessionNotProcessing:j,processingSessions:w,onReplaceTemporarySession:b,onNavigateToSession:k,onShowSettings:f,autoScrollToBottom:N,sendByCtrlEnter:S,externalMessageUpdate:I,limitStatus:D,onLimitBlocked:T,checkLimitStatus:R}){const{showConfirm:M}=it(),{hasPermission:E}=Xt(),{isConnected:W}=Ns(),[X,C]=n.useState(null),[$,te]=n.useState(null),[ne,G]=n.useState(600),[ie,le]=n.useState(!1),[xe,Ce]=n.useState(!1),be=n.useRef(null),Se=async ye=>{const Xe="previewTabAcknowledged";if(!localStorage.getItem(Xe)){const Ee=await M("此功能的对话记录不会显示在当前网页的会话列表中,与 Chat 是两套独立的系统,请注意区分。",{title:"预览功能提示",subtitle:ye==="codex"?"Codex":"Gemini CLI",variant:"warning",confirmText:"我知道了,继续",cancelText:"取消",checkboxLabel:"不再提醒"});if(!Ee?.confirmed)return;Ee.checked&&localStorage.setItem(Xe,"1")}u(ye)};n.useEffect(()=>{c==="shell"&&R&&R()},[c,R]);const Re=["png","jpg","jpeg","gif","svg","webp","ico","bmp"],se=(ye,Xe=null)=>{const Ee=ye.split(".").pop()?.toLowerCase();if(Re.includes(Ee)){te({name:ye.split("/").pop(),path:ye,projectName:r?.name,projectPath:r?.path});return}const Fe={name:ye.split("/").pop(),path:ye,projectName:r?.name,diffInfo:Xe};C(Fe)},we=()=>{C(null),Ce(!1)},$e=()=>{Ce(!xe)},We=ye=>{s||(le(!0),ye.preventDefault())};return n.useEffect(()=>{const ye=Ee=>{if(!ie)return;const Fe=be.current?.parentElement;if(!Fe)return;const Ne=Fe.getBoundingClientRect(),Be=Ne.right-Ee.clientX,Pe=300,Ae=Ne.width*.8;Be>=Pe&&Be<=Ae&&G(Be)},Xe=()=>{le(!1)};return ie&&(document.addEventListener("mousemove",ye),document.addEventListener("mouseup",Xe),document.body.style.cursor="col-resize",document.body.style.userSelect="none"),()=>{document.removeEventListener("mousemove",ye),document.removeEventListener("mouseup",Xe),document.body.style.cursor="",document.body.style.userSelect=""}},[ie]),x?e.jsxs("div",{className:"h-full flex flex-col",children:[s&&e.jsx("div",{className:"bg-background border-b border-border p-2 sm:p-3 pwa-header-safe flex-shrink-0",children:e.jsx("button",{onClick:t,className:"p-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 pwa-menu-button",children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})})}),e.jsx("div",{className:"flex-1 flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("div",{className:"w-12 h-12 mx-auto mb-4",children:e.jsx("div",{className:"w-full h-full rounded-full border-4 border-gray-200 border-t-blue-500",style:{animation:"spin 1s linear infinite",WebkitAnimation:"spin 1s linear infinite",MozAnimation:"spin 1s linear infinite"}})}),e.jsxs("h2",{className:"text-xl font-semibold mb-2",children:["正在加载 ",et]}),e.jsx("p",{children:"正在设置您的工作区..."})]})})]}):r?e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsx("div",{className:"bg-background border-b border-border p-2 sm:p-3 pwa-header-safe flex-shrink-0",children:e.jsxs("div",{className:"flex items-center justify-between relative",children:[e.jsxs("div",{className:"flex items-center space-x-2 min-w-0 flex-1",children:[s&&e.jsx("button",{onClick:t,onTouchStart:ye=>{ye.preventDefault(),t()},className:"p-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 touch-manipulation active:scale-95 pwa-menu-button flex-shrink-0",children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),e.jsx("div",{className:"min-w-0 flex items-center gap-2 flex-1 overflow-x-auto scrollbar-hide",children:e.jsx("div",{className:"min-w-0 flex-1",children:c==="chat"&&o?e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"text-sm sm:text-base font-semibold text-gray-900 dark:text-white whitespace-nowrap overflow-x-auto scrollbar-hide",children:o.summary||"新会话"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-gray-500 dark:text-gray-400 truncate",children:r.displayName}),e.jsxs("span",{className:`inline-flex items-center gap-1 text-xs ${W?"text-green-600 dark:text-green-400":"text-red-500 dark:text-red-400 animate-pulse"}`,children:[W?e.jsx("svg",{className:"w-2.5 h-2.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8.288 15.038a5.25 5.25 0 017.424 0M5.106 11.856c3.807-3.808 9.98-3.808 13.788 0M1.924 8.674c5.565-5.565 14.587-5.565 20.152 0M12.53 18.22l-.53.53-.53-.53a.75.75 0 011.06 0z"})}):e.jsx("svg",{className:"w-2.5 h-2.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11.412 15.655L9.75 21.75l3.745-4.012M9.257 13.5H3.75l2.659-2.849m2.048-2.194L14.25 2.25 12 10.5h8.25l-4.707 5.043M6.53 9.345A3.778 3.778 0 0112 8.25c1.372 0 2.585.59 3.43 1.53M3 3l18 18"})}),e.jsx("span",{className:"hidden sm:inline",children:W?"连接正常":"连接异常"})]})]})]}):c==="chat"&&!o?e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"text-sm sm:text-base font-semibold text-gray-900 dark:text-white",children:"新会话"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-gray-500 dark:text-gray-400 truncate",children:r.displayName}),e.jsxs("span",{className:`inline-flex items-center gap-1 text-xs ${W?"text-green-600 dark:text-green-400":"text-red-500 dark:text-red-400 animate-pulse"}`,children:[W?e.jsx("svg",{className:"w-2.5 h-2.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8.288 15.038a5.25 5.25 0 017.424 0M5.106 11.856c3.807-3.808 9.98-3.808 13.788 0M1.924 8.674c5.565-5.565 14.587-5.565 20.152 0M12.53 18.22l-.53.53-.53-.53a.75.75 0 011.06 0z"})}):e.jsx("svg",{className:"w-2.5 h-2.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11.412 15.655L9.75 21.75l3.745-4.012M9.257 13.5H3.75l2.659-2.849m2.048-2.194L14.25 2.25 12 10.5h8.25l-4.707 5.043M6.53 9.345A3.778 3.778 0 0112 8.25c1.372 0 2.585.59 3.43 1.53M3 3l18 18"})}),e.jsx("span",{className:"hidden sm:inline",children:W?"连接正常":"连接异常"})]})]})]}):e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"text-sm sm:text-base font-semibold text-gray-900 dark:text-white",children:c==="files"?"项目文件":"项目"}),e.jsx("div",{className:"text-xs text-gray-500 dark:text-gray-400 truncate",children:r.displayName})]})})})]}),e.jsx("div",{className:"flex-shrink-0 hidden sm:block",children:e.jsxs("div",{className:"relative flex bg-gray-100 dark:bg-gray-800 rounded-lg p-1",children:[e.jsx(jr,{content:"Chat",position:"bottom",children:e.jsx("button",{onClick:()=>u("chat"),className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md ${c==="chat"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsx("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"})}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Chat"})]})})}),e.jsx(jr,{content:"Files",position:"bottom",children:e.jsx("button",{onClick:()=>u("files"),className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md transition-all duration-200 ${c==="files"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsx("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-5l-2-2H5a2 2 0 00-2 2z"})}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Files"})]})})}),E("claude_shell")&&e.jsx(jr,{content:D&&!D.allowed?"使用已达上限":"Claude Code",position:"bottom",children:e.jsx("button",{onClick:()=>{if(D&&!D.allowed){T?.(D.reason);return}u("shell")},className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md transition-all duration-200 ${D&&!D.allowed?"opacity-50 cursor-not-allowed text-gray-400 dark:text-gray-500":c==="shell"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsx("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z",fill:"#D97757",fillRule:"nonzero"})}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Claude Code"})]})})}),E("codex_shell")&&e.jsx(jr,{content:"Codex",position:"bottom",children:e.jsx("button",{onClick:()=>Se("codex"),className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md transition-all duration-200 ${c==="codex"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsx("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",fill:"currentColor",fillRule:"evenodd",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"})}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Codex"})]})})}),E("gemini_shell")&&e.jsx(jr,{content:"Gemini CLI",position:"bottom",children:e.jsx("button",{onClick:()=>Se("gemini"),className:`relative px-2 sm:px-3 py-1.5 text-xs sm:text-sm font-medium rounded-md transition-all duration-200 ${c==="gemini"?"bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-700"}`,children:e.jsxs("span",{className:"flex items-center gap-1 sm:gap-1.5",children:[e.jsxs("svg",{className:"w-3 sm:w-3.5 h-3 sm:h-3.5",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"#3186FF"}),e.jsx("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#gemini-tab-fill-0)"}),e.jsx("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#gemini-tab-fill-1)"}),e.jsx("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#gemini-tab-fill-2)"}),e.jsxs("defs",{children:[e.jsxs("linearGradient",{gradientUnits:"userSpaceOnUse",id:"gemini-tab-fill-0",x1:"7",x2:"11",y1:"15.5",y2:"12",children:[e.jsx("stop",{stopColor:"#08B962"}),e.jsx("stop",{offset:"1",stopColor:"#08B962",stopOpacity:"0"})]}),e.jsxs("linearGradient",{gradientUnits:"userSpaceOnUse",id:"gemini-tab-fill-1",x1:"8",x2:"11.5",y1:"5.5",y2:"11",children:[e.jsx("stop",{stopColor:"#F94543"}),e.jsx("stop",{offset:"1",stopColor:"#F94543",stopOpacity:"0"})]}),e.jsxs("linearGradient",{gradientUnits:"userSpaceOnUse",id:"gemini-tab-fill-2",x1:"3.5",x2:"17.5",y1:"13.5",y2:"12",children:[e.jsx("stop",{stopColor:"#FABC12"}),e.jsx("stop",{offset:".46",stopColor:"#FABC12",stopOpacity:"0"})]})]})]}),e.jsx("span",{className:"hidden md:hidden lg:inline",children:"Gemini CLI"})]})})})]})})]})}),e.jsxs("div",{className:"flex-1 flex min-h-0 overflow-hidden",children:[e.jsxs("div",{className:`flex-1 flex flex-col min-h-0 overflow-hidden ${X?"mr-0":""} ${xe?"hidden":""}`,children:[e.jsx("div",{className:`h-full ${c==="chat"?"block":"hidden"}`,children:e.jsx(Ec,{showDetails:!0,children:e.jsx(kc,{selectedProject:r,selectedSession:o,ws:l,sendMessage:m,messages:d,onFileOpen:se,onInputFocusChange:h,onSessionActive:a,onSessionInactive:i,onSessionProcessing:y,onSessionNotProcessing:j,processingSessions:w,onReplaceTemporarySession:b,onNavigateToSession:k,onShowSettings:f,autoScrollToBottom:N,sendByCtrlEnter:S,externalMessageUpdate:I,limitStatus:D,onLimitExceeded:T,checkLimitStatus:R})})}),c==="files"&&e.jsx("div",{className:"h-full overflow-hidden",children:e.jsx(wc,{selectedProject:r})}),c==="shell"&&e.jsxs("div",{className:"h-full w-full overflow-hidden relative",children:[e.jsx(Sc,{project:r,session:o,showHeader:!1}),D&&!D.allowed&&e.jsx("div",{className:"absolute inset-0 bg-black/60 z-50 flex items-center justify-center",children:e.jsxs("div",{className:"bg-card border border-border rounded-lg shadow-xl p-6 mx-4 max-w-md text-center",children:[e.jsx("div",{className:"w-12 h-12 mx-auto mb-4 bg-red-100 dark:bg-red-900/30 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-6 h-6 text-red-600 dark:text-red-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),e.jsx("h3",{className:"text-lg font-semibold text-foreground mb-2",children:D.reason==="total_limit_exceeded"?"使用上限已达到":"今日使用上限已达到"}),e.jsx("p",{className:"text-muted-foreground mb-4",children:D.reason==="total_limit_exceeded"?"您已达到使用上限,请联系管理员提升额度。":"您已达到今日使用上限,请明日再来或联系管理员提升额度。"}),e.jsx("button",{onClick:()=>u("chat"),className:"px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors",children:"返回 Chat"})]})})]}),c==="codex"&&e.jsx("div",{className:"h-full w-full overflow-hidden relative",children:e.jsx(Mc,{project:r,showHeader:!1})}),c==="gemini"&&e.jsx("div",{className:"h-full w-full overflow-hidden relative",children:e.jsx(Cc,{project:r,showHeader:!1})}),e.jsx("div",{className:`h-full overflow-hidden ${c==="preview"?"block":"hidden"}`})]}),X&&!s&&e.jsxs(e.Fragment,{children:[!xe&&e.jsx("div",{ref:be,onMouseDown:We,className:"flex-shrink-0 w-1 bg-gray-200 dark:bg-gray-700 hover:bg-blue-500 dark:hover:bg-blue-600 cursor-col-resize transition-colors relative group",title:"Drag to resize",children:e.jsx("div",{className:"absolute inset-y-0 left-1/2 -translate-x-1/2 w-1 bg-blue-500 dark:bg-blue-600 opacity-0 group-hover:opacity-100 transition-opacity"})}),e.jsx("div",{className:`flex-shrink-0 border-l border-gray-200 dark:border-gray-700 h-full overflow-hidden ${xe?"flex-1":""}`,style:xe?{}:{width:`${ne}px`},children:e.jsx($n,{file:X,onClose:we,projectPath:r?.path,isSidebar:!0,isExpanded:xe,onToggleExpand:$e})})]})]}),X&&s&&e.jsx($n,{file:X,onClose:we,projectPath:r?.path,isSidebar:!1}),$&&e.jsx(ks,{file:$,onClose:()=>te(null)})]}):e.jsxs("div",{className:"h-full flex flex-col",children:[s&&e.jsx("div",{className:"bg-background border-b border-border p-2 sm:p-3 pwa-header-safe flex-shrink-0",children:e.jsx("button",{onClick:t,className:"p-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 pwa-menu-button",children:e.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})})}),e.jsx("div",{className:"flex-1 flex items-center justify-center",children:e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400 max-w-md mx-auto px-6",children:[e.jsx("div",{className:"w-16 h-16 mx-auto mb-6 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center",children:e.jsx("svg",{className:"w-8 h-8 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-5l-2-2H5a2 2 0 00-2 2z"})})}),e.jsx("h2",{className:"text-2xl font-semibold mb-3 text-gray-900 dark:text-white",children:"选择您的项目"}),e.jsxs("p",{className:"text-gray-600 dark:text-gray-300 mb-6 leading-relaxed",children:["从侧边栏选择一个项目,开始与 ",et," 进行交流。每个项目包含您的聊天会话和文件历史。"]}),e.jsx("div",{className:"bg-blue-50 dark:bg-blue-900/20 rounded-lg p-4 border border-blue-200 dark:border-blue-800",children:e.jsxs("p",{className:"text-sm text-blue-700 dark:text-blue-300",children:["💡 ",e.jsx("strong",{children:"提示:"})," ",s?"点击上方菜单按钮访问项目":E("create_project")?"点击侧边栏中的文件夹图标创建新项目":"点击侧边栏中的「使用项目模板」按钮来创建项目"]})})]})})]})}const Lc=lt.memo(Ac);function Ic({activeTab:r,setActiveTab:o,isInputFocused:c}){const u=[{id:"chat",icon:Cr,onClick:()=>o("chat")},{id:"shell",icon:Fn,onClick:()=>o("shell")},{id:"files",icon:Qt,onClick:()=>o("files")}];return e.jsx("div",{className:`fixed bottom-0 left-0 right-0 bg-background border-t border-border z-50 ios-bottom-safe transform transition-transform duration-300 ease-in-out shadow-lg ${c?"translate-y-full":"translate-y-0"}`,children:e.jsx("div",{className:"flex items-center justify-around py-1",children:u.map(l=>{const m=l.icon,d=r===l.id;return e.jsxs("button",{onClick:l.onClick,onTouchStart:s=>{s.preventDefault(),l.onClick()},className:`flex items-center justify-center p-2 rounded-lg min-h-[40px] min-w-[40px] relative touch-manipulation ${d?"text-blue-600 dark:text-blue-400":"text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white"}`,"aria-label":l.id,children:[e.jsx(m,{className:"w-5 h-5"}),d&&e.jsx("div",{className:"absolute top-0 left-1/2 transform -translate-x-1/2 w-6 h-0.5 bg-blue-600 dark:bg-blue-400 rounded-full"})]},l.id)})})})}const Ts=n.createContext(),eo=()=>{const r=n.useContext(Ts);if(!r)throw new Error("useTheme must be used within a ThemeProvider");return r},_c=({children:r})=>{const[o,c]=n.useState(()=>{const m=localStorage.getItem("theme");return m?m==="dark":window.matchMedia?window.matchMedia("(prefers-color-scheme: dark)").matches:!1});n.useEffect(()=>{if(o){document.documentElement.classList.add("dark"),localStorage.setItem("theme","dark");const m=document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');m&&m.setAttribute("content","black-translucent");const d=document.querySelector('meta[name="theme-color"]');d&&d.setAttribute("content","#0c1117")}else{document.documentElement.classList.remove("dark"),localStorage.setItem("theme","light");const m=document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');m&&m.setAttribute("content","default");const d=document.querySelector('meta[name="theme-color"]');d&&d.setAttribute("content","#ffffff")}},[o]),n.useEffect(()=>{if(!window.matchMedia)return;const m=window.matchMedia("(prefers-color-scheme: dark)"),d=s=>{localStorage.getItem("theme")||c(s.matches)};return m.addEventListener("change",d),()=>m.removeEventListener("change",d)},[]);const l={isDarkMode:o,toggleDarkMode:()=>{c(m=>!m)}};return e.jsx(Ts.Provider,{value:l,children:r})},zc=["Bash(git log:*)","Bash(git diff:*)","Bash(git status:*)","Write","Read","Edit","Glob","Grep","MultiEdit","Task","TodoWrite","TodoRead","WebFetch","WebSearch"];function Rc({skipPermissions:r,setSkipPermissions:o,allowedTools:c,setAllowedTools:u,disallowedTools:l,setDisallowedTools:m,newAllowedTool:d,setNewAllowedTool:s,newDisallowedTool:p,setNewDisallowedTool:t}){const x=y=>{y&&!c.includes(y)&&(u([...c,y]),s(""))},h=y=>{u(c.filter(j=>j!==y))},a=y=>{y&&!l.includes(y)&&(m([...l,y]),t(""))},i=y=>{m(l.filter(j=>j!==y))};return e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"bg-sky-50 dark:bg-sky-900/20 border border-sky-200 dark:border-sky-800 rounded-lg p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Qr,{className:"w-5 h-5 text-sky-500 flex-shrink-0 mt-0.5"}),e.jsxs("div",{className:"text-sm text-sky-800 dark:text-sky-200",children:[e.jsx("span",{className:"font-medium",children:"提示:"}),"此权限设置仅对 ",e.jsx("span",{className:"font-medium",children:"Chat(聊天)"})," 生效,对 ",e.jsx("span",{className:"font-medium",children:"Shell(终端)"})," 无效。Shell 是直接的系统终端,不受此权限控制。"]})]})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Wt,{className:"w-5 h-5 text-orange-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"权限设置"})]}),e.jsx("div",{className:"bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 rounded-lg p-4",children:e.jsxs("label",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"checkbox",checked:r,onChange:y=>o(y.target.checked),className:"w-4 h-4 text-blue-600 bg-gray-100 dark:bg-gray-700 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 focus:ring-2"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-orange-900 dark:text-orange-100",children:"跳过权限提示(请谨慎使用)"}),e.jsx("div",{className:"text-sm text-orange-700 dark:text-orange-300",children:"等同于 --dangerously-skip-permissions 标志"})]})]})})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ft,{className:"w-5 h-5 text-green-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"允许的工具"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"自动允许而不提示权限的工具"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsx(at,{value:d,onChange:y=>s(y.target.value),placeholder:'e.g., "Bash(git log:*)" or "Write"',onKeyPress:y=>{y.key==="Enter"&&(y.preventDefault(),x(d))},className:"flex-1 h-10"}),e.jsxs(B,{onClick:()=>x(d),disabled:!d,size:"sm",className:"h-10 px-4",children:[e.jsx(_t,{className:"w-4 h-4 mr-2 sm:mr-0"}),e.jsx("span",{className:"sm:hidden",children:"添加"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"快速添加常用工具:"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:zc.map(y=>e.jsx(B,{variant:"outline",size:"sm",onClick:()=>x(y),disabled:c.includes(y),className:"text-xs h-8",children:y},y))})]}),e.jsxs("div",{className:"space-y-2",children:[c.map(y=>e.jsxs("div",{className:"flex items-center justify-between bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-3",children:[e.jsx("span",{className:"font-mono text-sm text-green-800 dark:text-green-200",children:y}),e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>h(y),className:"text-green-600 hover:text-green-700",children:e.jsx(Ue,{className:"w-4 h-4"})})]},y)),c.length===0&&e.jsx("div",{className:"text-center py-6 text-gray-500 dark:text-gray-400",children:"未配置允许的工具"})]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Wt,{className:"w-5 h-5 text-red-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"阻止的工具"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"自动阻止而不提示权限的工具"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsx(at,{value:p,onChange:y=>t(y.target.value),placeholder:'e.g., "Bash(rm:*)"',onKeyPress:y=>{y.key==="Enter"&&(y.preventDefault(),a(p))},className:"flex-1 h-10"}),e.jsxs(B,{onClick:()=>a(p),disabled:!p,size:"sm",className:"h-10 px-4",children:[e.jsx(_t,{className:"w-4 h-4 mr-2 sm:mr-0"}),e.jsx("span",{className:"sm:hidden",children:"添加"})]})]}),e.jsxs("div",{className:"space-y-2",children:[l.map(y=>e.jsxs("div",{className:"flex items-center justify-between bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-3",children:[e.jsx("span",{className:"font-mono text-sm text-red-800 dark:text-red-200",children:y}),e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>i(y),className:"text-red-600 hover:text-red-700",children:e.jsx(Ue,{className:"w-4 h-4"})})]},y)),l.length===0&&e.jsx("div",{className:"text-center py-6 text-gray-500 dark:text-gray-400",children:"未配置阻止的工具"})]})]}),e.jsxs("div",{className:"bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4",children:[e.jsx("h4",{className:"font-medium text-blue-900 dark:text-blue-100 mb-2",children:"工具模式示例:"}),e.jsxs("ul",{className:"text-sm text-blue-800 dark:text-blue-200 space-y-1",children:[e.jsxs("li",{children:[e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:'"Bash(git log:*)"'})," - 允许所有 git log 命令"]}),e.jsxs("li",{children:[e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:'"Bash(git diff:*)"'})," - 允许所有 git diff 命令"]}),e.jsxs("li",{children:[e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:'"Write"'})," - 允许所有 Write 工具使用"]}),e.jsxs("li",{children:[e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:'"Bash(rm:*)"'})," - 阻止所有 rm 命令(危险)"]})]})]})]})}function $c({permissionMode:r,setPermissionMode:o}){return e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ft,{className:"w-5 h-5 text-green-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"权限模式"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"控制 Codex 如何处理文件修改和命令执行"}),e.jsx("div",{className:`border rounded-lg p-4 cursor-pointer transition-all ${r==="default"?"bg-gray-100 dark:bg-gray-800 border-gray-400 dark:border-gray-500":"bg-gray-50 dark:bg-gray-900/50 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600"}`,onClick:()=>o("default"),children:e.jsxs("label",{className:"flex items-start gap-3 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"codexPermissionMode",checked:r==="default",onChange:()=>o("default"),className:"mt-1 w-4 h-4 text-green-600"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-foreground",children:"默认"}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"仅受信任的命令(ls、cat、grep、git status 等)会自动运行。其他命令将被跳过。可以写入工作区。"})]})]})}),e.jsx("div",{className:`border rounded-lg p-4 cursor-pointer transition-all ${r==="acceptEdits"?"bg-green-50 dark:bg-green-900/20 border-green-400 dark:border-green-600":"bg-gray-50 dark:bg-gray-900/50 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600"}`,onClick:()=>o("acceptEdits"),children:e.jsxs("label",{className:"flex items-start gap-3 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"codexPermissionMode",checked:r==="acceptEdits",onChange:()=>o("acceptEdits"),className:"mt-1 w-4 h-4 text-green-600"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-green-900 dark:text-green-100",children:"接受编辑"}),e.jsx("div",{className:"text-sm text-green-700 dark:text-green-300",children:"所有命令在工作区内自动运行。沙盒执行的完全自动模式。"})]})]})}),e.jsx("div",{className:`border rounded-lg p-4 cursor-pointer transition-all ${r==="bypassPermissions"?"bg-orange-50 dark:bg-orange-900/20 border-orange-400 dark:border-orange-600":"bg-gray-50 dark:bg-gray-900/50 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600"}`,onClick:()=>o("bypassPermissions"),children:e.jsxs("label",{className:"flex items-start gap-3 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"codexPermissionMode",checked:r==="bypassPermissions",onChange:()=>o("bypassPermissions"),className:"mt-1 w-4 h-4 text-orange-600"}),e.jsxs("div",{children:[e.jsxs("div",{className:"font-medium text-orange-900 dark:text-orange-100 flex items-center gap-2",children:["跳过权限",e.jsx(Wt,{className:"w-4 h-4"})]}),e.jsx("div",{className:"text-sm text-orange-700 dark:text-orange-300",children:"无限制的完全系统访问。所有命令自动运行,具有完全的磁盘和网络访问权限。请谨慎使用。"})]})]})}),e.jsxs("details",{className:"text-sm",children:[e.jsx("summary",{className:"cursor-pointer text-muted-foreground hover:text-foreground",children:"技术详情"}),e.jsxs("div",{className:"mt-2 p-3 bg-gray-50 dark:bg-gray-900/50 rounded-lg text-xs text-muted-foreground space-y-2",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Default:"})," sandboxMode=workspace-write, approvalPolicy=untrusted. Trusted commands: cat, cd, grep, head, ls, pwd, tail, git status/log/diff/show, find (without -exec), etc."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Accept Edits:"})," sandboxMode=workspace-write, approvalPolicy=never. All commands auto-execute within project directory."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Bypass Permissions:"})," sandboxMode=danger-full-access, approvalPolicy=never. Full system access, use only in trusted environments."]}),e.jsx("p",{className:"text-xs opacity-75",children:"您可以在聊天界面中使用模式按钮为每个会话覆盖此设置。"})]})]})]})})}function Wc({agent:r,...o}){return r==="claude"?e.jsx(Rc,{...o}):r==="codex"?e.jsx($c,{...o}):null}const Hc=r=>{switch(r){case"stdio":return e.jsx(Fn,{className:"w-4 h-4"});case"sse":return e.jsx(Or,{className:"w-4 h-4"});case"http":return e.jsx(lr,{className:"w-4 h-4"});default:return e.jsx(en,{className:"w-4 h-4"})}};function Fc({servers:r,onAdd:o,onEdit:c,onDelete:u,testResults:l,serverTools:m,onDiscoverRepo:d}){return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(en,{className:"w-5 h-5 text-purple-500"}),e.jsx("h3",{className:"text-lg font-medium text-foreground",children:"MCP 服务器"})]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Model Context Protocol 服务器为 ",et," 提供额外的工具和数据源"]}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs(B,{onClick:o,className:"bg-purple-600 hover:bg-purple-700 text-white",size:"sm",children:[e.jsx(_t,{className:"w-4 h-4 mr-2"}),"添加 MCP 服务器"]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs(B,{onClick:d,variant:"outline",size:"sm",children:[e.jsx(tn,{className:"w-4 h-4 mr-2"}),"MCP 商店"]})})]}),e.jsxs("div",{className:"space-y-2",children:[r.map(s=>e.jsx("div",{className:"bg-gray-50 dark:bg-gray-900/50 border border-gray-200 dark:border-gray-700 rounded-lg p-4",children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[Hc(s.type),e.jsx("span",{className:"font-medium text-foreground",children:s.name}),e.jsx(tt,{variant:"outline",className:"text-xs",children:s.type}),e.jsx(tt,{variant:"outline",className:"text-xs",title:s.scope==="local"&&s.projectPath?s.projectPath:void 0,children:s.scope==="local"?`local${s.projectPath?` · ${s.projectPath.split("/").filter(Boolean).pop()}`:""}`:s.scope==="user"?"user":s.scope})]}),e.jsxs("div",{className:"text-sm text-muted-foreground space-y-1",children:[s.type==="stdio"&&s.config?.command&&e.jsxs("div",{children:["命令:",e.jsx("code",{className:"bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs",children:s.config.command})]}),(s.type==="sse"||s.type==="http")&&s.config?.url&&e.jsxs("div",{children:["URL:",e.jsx("code",{className:"bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs",children:s.config.url})]}),s.config?.args&&s.config.args.length>0&&e.jsxs("div",{children:["参数:",e.jsx("code",{className:"bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs",children:s.config.args.join(" ")})]})]}),l?.[s.id]&&e.jsx("div",{className:`mt-2 p-2 rounded text-xs ${l[s.id].success?"bg-green-50 dark:bg-green-900/20 text-green-800 dark:text-green-200":"bg-red-50 dark:bg-red-900/20 text-red-800 dark:text-red-200"}`,children:e.jsx("div",{className:"font-medium",children:l[s.id].message})}),m?.[s.id]&&m[s.id].tools?.length>0&&e.jsxs("div",{className:"mt-2 p-2 rounded text-xs bg-blue-50 dark:bg-blue-900/20 text-blue-800 dark:text-blue-200",children:[e.jsxs("div",{className:"font-medium",children:["工具(",m[s.id].tools.length,"):"]}),e.jsxs("div",{className:"flex flex-wrap gap-1 mt-1",children:[m[s.id].tools.slice(0,5).map((p,t)=>e.jsx("code",{className:"bg-blue-100 dark:bg-blue-800 px-1 rounded",children:p.name},t)),m[s.id].tools.length>5&&e.jsxs("span",{className:"text-xs opacity-75",children:["+",m[s.id].tools.length-5," 更多"]})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 ml-4",children:[e.jsx(B,{onClick:()=>c(s),variant:"ghost",size:"sm",className:"text-gray-600 hover:text-gray-700",title:"编辑服务器",children:e.jsx(On,{className:"w-4 h-4"})}),e.jsx(B,{onClick:()=>u(s.id,s.scope,s.projectPath),variant:"ghost",size:"sm",className:"text-red-600 hover:text-red-700",title:"删除服务器",children:e.jsx(xt,{className:"w-4 h-4"})})]})]})},`${s.scope}:${s.projectPath||""}:${s.id}`)),r.length===0&&e.jsx("div",{className:"text-center py-8 text-gray-500 dark:text-gray-400",children:"未配置 MCP 服务器"})]})]})}function Bc(r){return e.jsx(Fc,{...r})}const Uc=[{key:"ANTHROPIC_DEFAULT_OPUS_MODEL",label:"Opus 模型",placeholder:"例如: claude-opus-4-6",description:"覆盖 opus 别名使用的模型,Plan Mode 激活时也用于 opusplan"},{key:"ANTHROPIC_DEFAULT_SONNET_MODEL",label:"Sonnet 模型",placeholder:"例如: claude-sonnet-4-5-20250929",description:"覆盖 sonnet 别名使用的模型,Plan Mode 未激活时也用于 opusplan"},{key:"ANTHROPIC_DEFAULT_HAIKU_MODEL",label:"Haiku 模型",placeholder:"例如: claude-haiku-4-5-20251001",description:"覆盖 haiku 别名使用的模型,也用于后台功能"},{key:"CLAUDE_CODE_SUBAGENT_MODEL",label:"Subagent 模型",placeholder:"例如: claude-haiku-4-5-20251001",description:"覆盖子代理(subagents)使用的模型"}],Gc=n.forwardRef(function({onStatusChange:o},c){const[u,l]=n.useState({}),[m,d]=n.useState({}),[s,p]=n.useState(!0),[t,x]=n.useState(!1),[h,a]=n.useState(null),[i,y]=n.useState(null),j=JSON.stringify(u)!==JSON.stringify(m);n.useEffect(()=>{o?.({saving:t,hasChanges:j})},[t,j,o]),n.useEffect(()=>{w()},[]),n.useEffect(()=>{if(h){const f=setTimeout(()=>a(null),3e3);return()=>clearTimeout(f)}},[h]);const w=async()=>{try{p(!0),y(null);const f=await Y("/api/settings/models");if(f.ok){const N=await f.json();l(N.models||{}),d(N.models||{})}else{const N=await f.json();y(N.error||"加载模型配置失败")}}catch(f){y(f.message)}finally{p(!1)}},b=async()=>{try{x(!0),a(null);const f=await Y("/api/settings/models",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({models:u})});if(f.ok)return a("success"),d({...u}),!0;{const N=await f.json();return a("error"),y(N.error||"保存失败"),!1}}catch(f){return a("error"),y(f.message),!1}finally{x(!1)}},k=()=>{l({...m}),a(null)};return n.useImperativeHandle(c,()=>({save:b,reset:k,get hasChanges(){return j},get saving(){return t}}),[j,t,u,m]),s?e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx("div",{className:"animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500"}),e.jsx("span",{className:"ml-3 text-sm text-muted-foreground",children:"加载模型配置..."})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-start gap-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-3",children:[e.jsx(Qr,{className:"w-4 h-4 text-blue-500 mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"text-sm text-blue-700 dark:text-blue-300",children:[e.jsxs("p",{children:["自定义模型 ID 来覆盖 ",et," 和 Claude Code 使用的默认模型。留空表示使用默认模型。"]}),e.jsx("p",{className:"mt-1 text-blue-600 dark:text-blue-400",children:"非 Claude 模型将按 Sonnet 定价计费,但统计中会记录实际模型 ID。"})]})]}),i&&e.jsx("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-3 text-sm text-red-600 dark:text-red-400",children:i}),h==="success"&&e.jsx("div",{className:"bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-3 text-sm text-green-600 dark:text-green-400",children:"模型配置已保存"}),Uc.map(f=>e.jsx("div",{className:"bg-gray-50 dark:bg-gray-900/50 border border-gray-200 dark:border-gray-700 rounded-lg p-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"font-medium text-sm text-foreground",children:f.label}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:f.description})]}),e.jsx("input",{type:"text",value:u[f.key]||"",onChange:N=>l(S=>({...S,[f.key]:N.target.value})),placeholder:f.placeholder,className:"w-full text-sm bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 rounded-lg focus:ring-blue-500 focus:border-blue-500 px-3 py-2"}),e.jsx("p",{className:"text-xs text-muted-foreground font-mono",children:f.key})]})},f.key))]})});function Yc({onClose:r,onInstalled:o,onOpenRepoManager:c,projects:u=[]}){const{showAlert:l}=it(),[m,d]=n.useState([]),[s,p]=n.useState([]),[t,x]=n.useState(!0),[h,a]=n.useState(null),[i,y]=n.useState(""),[j,w]=n.useState("all"),[b,k]=n.useState(null),[f,N]=n.useState(null),[S,I]=n.useState("user"),[D,T]=n.useState("");n.useEffect(()=>{R()},[]);const R=async(C=!1)=>{try{x(!0),a(null),C&&await Y("/api/skills/repos/refresh",{method:"POST"});const[$,te]=await Promise.all([Y("/api/skills/available"),Y("/api/skills/repos")]);if($.ok){const ne=await $.json();d(ne.skills||[])}if(te.ok){const ne=await te.json();p(ne.repos||[])}}catch($){a($.message)}finally{x(!1)}},M=C=>{N(C),I("user"),T("")},E=()=>{N(null),I("user"),T("")},W=async()=>{const C=f;if(C){if(S==="local"&&!D){l("请选择要安装到的项目",{variant:"warning"});return}try{N(null),k(C.name);const $={skillPath:C.path};S==="local"&&D&&($.projectPath=D);const te=await Y(`/api/skills/install/${C.name}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify($)});if(te.ok)d(ne=>ne.map(G=>G.name===C.name?{...G,installed:!0}:G)),o?.();else{const ne=await te.json();l(ne.error||"安装技能失败",{variant:"error"})}}catch($){l($.message,{variant:"error"})}finally{k(null),I("user"),T("")}}},X=m.filter(C=>{if(i){const $=i.toLowerCase();if(!C.name.toLowerCase().includes($)&&!C.title?.toLowerCase().includes($)&&!C.description?.toLowerCase().includes($))return!1}return!(j!=="all"&&C.repository!==j)});return e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4",children:e.jsxs("div",{className:"bg-background rounded-xl shadow-xl w-full max-w-4xl max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-border",children:[e.jsx("h2",{className:"text-lg font-semibold text-foreground",children:"Skills 管理"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(B,{variant:"ghost",size:"sm",onClick:()=>R(!0),disabled:t,children:[e.jsx(st,{className:`w-4 h-4 ${t?"animate-spin":""}`}),e.jsx("span",{className:"ml-1 hidden sm:inline",children:"刷新"})]}),e.jsxs(B,{variant:"ghost",size:"sm",onClick:c,children:[e.jsx(Ht,{className:"w-4 h-4"}),e.jsx("span",{className:"ml-1 hidden sm:inline",children:"仓库管理"})]}),e.jsx(B,{variant:"ghost",size:"icon",onClick:r,children:e.jsx(Ue,{className:"w-5 h-5"})})]})]}),e.jsx("div",{className:"px-4 pt-4 pb-2"}),e.jsxs("div",{className:"px-4 pb-4 flex flex-wrap gap-3",children:[e.jsx("div",{className:"flex-1 min-w-[200px]",children:e.jsxs("div",{className:"relative",children:[e.jsx(St,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground"}),e.jsx(at,{type:"text",placeholder:"搜索技能名称或描述...",value:i,onChange:C=>y(C.target.value),className:"pl-10"})]})}),e.jsxs("select",{value:j,onChange:C=>w(C.target.value),className:"px-3 py-2 rounded-md border border-border bg-background text-foreground text-sm min-w-[120px]",children:[e.jsx("option",{value:"all",children:"全部"}),s.map(C=>e.jsxs("option",{value:`${C.owner}/${C.repo}`,children:[C.owner,"/",C.repo]},`${C.owner}/${C.repo}`))]})]}),e.jsxs("div",{className:"flex-1 overflow-auto px-4 pb-4",children:[h&&e.jsx("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 text-red-800 dark:text-red-200 text-sm mb-4",children:h}),t?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"加载中..."}):X.length===0?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:m.length===0?e.jsxs(e.Fragment,{children:[e.jsx("p",{children:"没有可用的技能"}),e.jsx("p",{className:"text-xs mt-2",children:"请先添加技能仓库"}),e.jsxs(B,{variant:"outline",size:"sm",className:"mt-4",onClick:c,children:[e.jsx(Ht,{className:"w-4 h-4 mr-2"}),"管理仓库"]})]}):e.jsx("p",{children:"没有找到匹配的技能"})}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:X.map(C=>{const $=b===C.name,te=f?.name===C.name;return e.jsx("div",{className:"border border-border rounded-lg p-4 hover:border-amber-500/50 transition-colors",children:e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"mb-2",children:[e.jsx("h4",{className:"font-medium text-foreground",children:C.title||C.name}),e.jsxs("div",{className:"flex items-center gap-1 mt-1",children:[e.jsxs("span",{className:"text-xs text-muted-foreground",children:["skills/",C.name]}),e.jsx(tt,{variant:"outline",className:"text-xs ml-2",children:C.repository})]})]}),C.description&&e.jsx("p",{className:"text-sm text-muted-foreground flex-1 line-clamp-3 mb-3",children:C.description}),te&&e.jsxs("div",{className:"mt-2 mb-3 p-3 rounded-lg bg-muted/50 border border-border text-sm",children:[e.jsx("p",{className:"font-medium text-foreground mb-2",children:"选择安装位置"}),e.jsxs("label",{className:"flex items-center gap-2 mb-1 cursor-pointer",children:[e.jsx("input",{type:"radio",name:`scope-${C.name}`,value:"user",checked:S==="user",onChange:()=>{I("user"),T("")},className:"accent-amber-600"}),e.jsx("span",{className:"text-foreground",children:"全局(所有项目可用)"})]}),e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:`scope-${C.name}`,value:"local",checked:S==="local",onChange:()=>I("local"),className:"accent-amber-600"}),e.jsx("span",{className:"text-foreground",children:"安装到指定项目"})]}),S==="local"&&e.jsxs("select",{value:D,onChange:ne=>T(ne.target.value),className:"mt-2 w-full px-2 py-1.5 rounded-md border border-border bg-background text-foreground text-xs",children:[e.jsx("option",{value:"",children:"选择项目..."}),u.map(ne=>e.jsx("option",{value:ne.path||ne.fullPath,children:ne.displayName||ne.name},ne.name))]}),e.jsxs("div",{className:"flex gap-2 mt-3",children:[e.jsx(B,{size:"sm",variant:"outline",onClick:E,className:"flex-1",children:"取消"}),e.jsx(B,{size:"sm",className:"bg-amber-600 hover:bg-amber-700 text-white flex-1",onClick:W,children:"确认安装"})]})]}),e.jsxs("div",{className:"flex items-center gap-2 mt-auto pt-2",children:[e.jsxs(B,{variant:"ghost",size:"sm",onClick:()=>window.open(`https://github.com/${C.repository}`,"_blank"),children:[e.jsx(Vo,{className:"w-4 h-4 mr-1"}),"查看"]}),C.installed?e.jsx(B,{size:"sm",disabled:!0,variant:"outline",className:"ml-auto",children:"已安装"}):!te&&e.jsxs(B,{size:"sm",className:"bg-amber-600 hover:bg-amber-700 text-white ml-auto",onClick:()=>M(C),disabled:$||!!f,children:[e.jsx(It,{className:"w-4 h-4 mr-1"}),$?"安装中...":"安装"]})]})]})},`${C.repository}-${C.name}`)})})]})]})})}function Jc({onClose:r,onChanged:o}){const{showAlert:c,showConfirm:u}=it(),[l,m]=n.useState([]),[d,s]=n.useState(!0),[p,t]=n.useState(null),[x,h]=n.useState(""),[a,i]=n.useState("main"),[y,j]=n.useState(!1),[w,b]=n.useState(null);n.useEffect(()=>{k()},[]);const k=async()=>{try{s(!0),t(null);const S=await Y("/api/skills/repos");if(S.ok){const I=await S.json();m(I.repos||[])}else{const I=await S.json();t(I.error||"Failed to fetch repos")}}catch(S){t(S.message)}finally{s(!1)}},f=async S=>{if(S.preventDefault(),!x.trim()){t("请输入仓库 URL");return}try{j(!0),t(null);const I=await Y("/api/skills/repos",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:x.trim(),branch:a.trim()||"main"})});if(I.ok)h(""),i("main"),k(),o?.();else{const D=await I.json();t(D.error||"Failed to add repo")}}catch(I){t(I.message)}finally{j(!1)}},N=async(S,I)=>{if(await u(`确定要移除仓库 "${S}/${I}" 吗?`,{title:"移除仓库",variant:"danger",confirmText:"确认移除"}))try{b(`${S}/${I}`);const D=await Y(`/api/skills/repos/${S}/${I}`,{method:"DELETE"});if(D.ok)k(),o?.();else{const T=await D.json();c(T.error||"移除仓库失败",{variant:"error"})}}catch(D){c(D.message,{variant:"error"})}finally{b(null)}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4",children:e.jsxs("div",{className:"bg-background rounded-xl shadow-xl w-full max-w-2xl max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"flex items-center gap-3 p-4 border-b border-border",children:[e.jsx(B,{variant:"ghost",size:"icon",onClick:r,children:e.jsx(er,{className:"w-5 h-5"})}),e.jsx("h2",{className:"text-lg font-semibold text-foreground",children:"管理技能仓库"})]}),e.jsxs("div",{className:"flex-1 overflow-auto p-4 space-y-6",children:[e.jsxs("div",{className:"bg-gray-50 dark:bg-gray-900/50 rounded-lg p-4 space-y-4",children:[e.jsx("h3",{className:"font-medium text-foreground",children:"添加技能仓库"}),e.jsxs("form",{onSubmit:f,className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm text-muted-foreground mb-1",children:"仓库 URL"}),e.jsx(at,{type:"text",placeholder:"owner/name 或 https://github.com/owner/name",value:x,onChange:S=>h(S.target.value),disabled:y})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm text-muted-foreground mb-1",children:"分支"}),e.jsx(at,{type:"text",placeholder:"main",value:a,onChange:S=>i(S.target.value),disabled:y})]}),e.jsxs(B,{type:"submit",disabled:y||!x.trim(),className:"bg-amber-600 hover:bg-amber-700 text-white",children:[e.jsx(_t,{className:"w-4 h-4 mr-2"}),y?"添加中...":"添加仓库"]})]})]}),p&&e.jsx("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 text-red-800 dark:text-red-200 text-sm",children:p}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("h3",{className:"font-medium text-foreground",children:"已添加的仓库"}),d?e.jsx("div",{className:"text-center py-4 text-muted-foreground",children:"加载中..."}):l.length===0?e.jsxs("div",{className:"text-center py-8 text-muted-foreground",children:[e.jsx(Zo,{className:"w-12 h-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"还没有添加任何仓库"})]}):l.map(S=>e.jsx("div",{className:"bg-gray-50 dark:bg-gray-900/50 border border-gray-200 dark:border-gray-700 rounded-lg p-4",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"font-medium text-foreground",children:[S.owner,"/",S.repo]}),S.isSystem&&e.jsx(tt,{variant:"outline",className:"text-xs bg-amber-50 dark:bg-amber-900/20 text-amber-700 dark:text-amber-300",children:"内置"})]}),e.jsxs("div",{className:"flex items-center gap-3 mt-1 text-sm text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(tn,{className:"w-3 h-3"}),"分支: main"]}),e.jsxs(tt,{variant:"outline",className:"text-xs",children:["识别到 ",S.skillCount," 个技能"]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 ml-4",children:[!S.isSystem&&S.url&&e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>window.open(S.url,"_blank"),children:e.jsx(Vo,{className:"w-4 h-4"})}),!S.isSystem&&e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>N(S.owner,S.repo),disabled:w===`${S.owner}/${S.repo}`,className:"text-red-500 hover:text-red-600",children:e.jsx(xt,{className:"w-4 h-4"})})]})]})},`${S.owner}/${S.repo}`))]})]})]})})}function qc({projects:r=[]}){const{showAlert:o,showConfirm:c}=it(),[u,l]=n.useState([]),[m,d]=n.useState(!0),[s,p]=n.useState(null),[t,x]=n.useState(!1),[h,a]=n.useState(!1),[i,y]=n.useState(!1),[j,w]=n.useState(null),b=n.useRef(null);n.useEffect(()=>{k()},[]);const k=async()=>{try{d(!0),p(null);const M=await Y("/api/skills");if(M.ok){const E=await M.json();l(E.skills||[])}else{const E=await M.json();p(E.error||"Failed to fetch skills")}}catch(M){p(M.message)}finally{d(!1)}},f=async()=>{try{const M=await Y("/api/skills");if(M.ok){const E=await M.json();l(E.skills||[])}}catch{}},N=async M=>{try{const E=await Y(`/api/skills/${M}/download`);if(!E.ok){const $=await E.json();o($.error||"下载技能失败",{variant:"error"});return}const W=await E.blob(),X=URL.createObjectURL(W),C=document.createElement("a");C.href=X,C.download=`${M}.zip`,C.click(),URL.revokeObjectURL(X)}catch(E){o(E.message,{variant:"error"})}},S=async M=>{if(await c(`确定要删除技能 "${M.name}" 吗?`,{title:"删除技能",variant:"danger",confirmText:"确认删除"}))try{const E=M.projectPath?`/api/skills/${M.name}?projectPath=${encodeURIComponent(M.projectPath)}`:`/api/skills/${M.name}`,W=await Y(E,{method:"DELETE"});if(W.ok)k();else{const X=await W.json();o(X.error||"删除技能失败",{variant:"error"})}}catch(E){o(E.message,{variant:"error"})}},I=async M=>{let E,W;if(M.syncType==="builtin"?(W="同步修改到云端",E=`确定要将技能 "${M.name}" 的本地修改推送到共享仓库吗?
155
155
 
156
156
  这会把你在本地对该技能所做的修改同步到公司的共享 Git 仓库,其他用户拉取更新后即可获得最新版本。`):M.syncType==="external"?(W="迁移技能到共享仓库",E=`确定要将技能 "${M.name}" 迁移到公司共享仓库吗?
157
157
 
package/dist/index.html CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
  <!-- Prevent zoom on iOS -->
27
27
  <meta name="format-detection" content="telephone=no" />
28
- <script type="module" crossorigin src="/assets/index-BFd2fqw2.js"></script>
28
+ <script type="module" crossorigin src="/assets/index-C1nCVxE_.js"></script>
29
29
  <link rel="modulepreload" crossorigin href="/assets/vendor-react-Bv0Nkan8.js">
30
30
  <link rel="modulepreload" crossorigin href="/assets/vendor-codemirror-sVRjxPVQ.js">
31
31
  <link rel="modulepreload" crossorigin href="/assets/vendor-utils-00TdZexr.js">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ian2018cs/agenthub",
3
- "version": "0.1.83",
3
+ "version": "0.1.85",
4
4
  "description": "A web-based UI for AI Agents",
5
5
  "type": "module",
6
6
  "main": "server/index.js",
@@ -654,7 +654,55 @@ async function installMcp(mcpName, repoUrl, userUuid, projectPath) {
654
654
  }
655
655
 
656
656
  await fs.writeFile(claudeJsonPath, JSON.stringify(claudeConfig, null, 2), 'utf-8');
657
- return true;
657
+ // Return the server keys that were written, so callers can track them for later removal
658
+ return { success: true, keys: Object.keys(mcpJson) };
659
+ }
660
+
661
+ /**
662
+ * Uninstall a single MCP server by removing its keys from .claude.json.
663
+ * `installedKeys` are the server key names that were written during install.
664
+ */
665
+ async function uninstallMcp(installedKeys, userUuid, projectPath) {
666
+ if (!installedKeys?.length) return;
667
+ const userPaths = getUserPaths(userUuid);
668
+ const claudeJsonPath = path.join(userPaths.claudeDir, '.claude.json');
669
+ let claudeConfig = {};
670
+ try {
671
+ claudeConfig = JSON.parse(await fs.readFile(claudeJsonPath, 'utf-8'));
672
+ } catch {
673
+ return; // Nothing to remove
674
+ }
675
+
676
+ let changed = false;
677
+ if (projectPath) {
678
+ const mcpServers = claudeConfig.projects?.[projectPath]?.mcpServers;
679
+ if (mcpServers) {
680
+ for (const key of installedKeys) {
681
+ if (key in mcpServers) { delete mcpServers[key]; changed = true; }
682
+ }
683
+ }
684
+ } else {
685
+ if (claudeConfig.mcpServers) {
686
+ for (const key of installedKeys) {
687
+ if (key in claudeConfig.mcpServers) { delete claudeConfig.mcpServers[key]; changed = true; }
688
+ }
689
+ }
690
+ }
691
+
692
+ if (changed) {
693
+ await fs.writeFile(claudeJsonPath, JSON.stringify(claudeConfig, null, 2), 'utf-8');
694
+ }
695
+ }
696
+
697
+ /**
698
+ * Uninstall a single skill by removing its symlink.
699
+ */
700
+ async function uninstallSkill(skillName, userUuid, projectPath) {
701
+ const userPaths = getUserPaths(userUuid);
702
+ const linkPath = projectPath
703
+ ? path.join(projectPath, '.claude', 'skills', skillName)
704
+ : path.join(userPaths.skillsDir, skillName);
705
+ try { await fs.unlink(linkPath); } catch {}
658
706
  }
659
707
 
660
708
  // ─── Routes ──────────────────────────────────────────────────────────────────
@@ -813,13 +861,46 @@ router.post('/install', async (req, res) => {
813
861
  console.error('[AgentInstall] Failed to copy agent files:', err.message);
814
862
  }
815
863
 
864
+ // Load existing agentInfo to perform diff-based uninstall of removed skills/MCPs
865
+ const prevConfig = await loadProjectConfig(userUuid);
866
+ const prevKey = projectDir.replace(/\//g, '-');
867
+ const prevAgentInfo = prevConfig[prevKey]?.agentInfo;
868
+
869
+ // Remove skills that existed in old version but are no longer in new version
870
+ const newSkillNames = new Set((agent.skills || []).filter(s => s.name).map(s => s.name));
871
+ for (const old of prevAgentInfo?.installedSkills || []) {
872
+ if (!newSkillNames.has(old.name)) {
873
+ try {
874
+ await uninstallSkill(old.name, userUuid, projectDir);
875
+ console.log(`[AgentInstall] Removed old skill "${old.name}" (no longer in agent)`);
876
+ } catch (e) {
877
+ console.warn(`[AgentInstall] Could not remove old skill "${old.name}":`, e.message);
878
+ }
879
+ }
880
+ }
881
+
882
+ // Remove MCPs that existed in old version but are no longer in new version
883
+ const newMcpNames = new Set((agent.mcps || []).filter(m => m.name).map(m => m.name));
884
+ for (const old of prevAgentInfo?.installedMcps || []) {
885
+ if (!newMcpNames.has(old.name)) {
886
+ try {
887
+ await uninstallMcp(old.keys, userUuid, projectDir);
888
+ console.log(`[AgentInstall] Removed old MCP "${old.name}" (no longer in agent)`);
889
+ } catch (e) {
890
+ console.warn(`[AgentInstall] Could not remove old MCP "${old.name}":`, e.message);
891
+ }
892
+ }
893
+ }
894
+
816
895
  // Install skills
817
896
  const skillResults = [];
897
+ const installedSkills = [];
818
898
  for (const skill of agent.skills || []) {
819
899
  if (!skill.name || !skill.repo) continue;
820
900
  try {
821
901
  const ok = await installSkill(skill.name, skill.repo, userUuid, projectDir);
822
902
  skillResults.push({ name: skill.name, success: ok });
903
+ if (ok) installedSkills.push({ name: skill.name, repo: skill.repo });
823
904
  } catch (err) {
824
905
  console.error(`[AgentInstall] Failed to install skill "${skill.name}":`, err.message);
825
906
  skillResults.push({ name: skill.name, success: false, error: err.message });
@@ -828,11 +909,13 @@ router.post('/install', async (req, res) => {
828
909
 
829
910
  // Install MCPs (project-scoped to the newly created project directory)
830
911
  const mcpResults = [];
912
+ const installedMcps = [];
831
913
  for (const mcp of agent.mcps || []) {
832
914
  if (!mcp.name || !mcp.repo) continue;
833
915
  try {
834
- const ok = await installMcp(mcp.name, mcp.repo, userUuid, projectDir);
835
- mcpResults.push({ name: mcp.name, success: ok });
916
+ const result = await installMcp(mcp.name, mcp.repo, userUuid, projectDir);
917
+ mcpResults.push({ name: mcp.name, success: result.success });
918
+ if (result.success) installedMcps.push({ name: mcp.name, repo: mcp.repo, keys: result.keys });
836
919
  } catch (err) {
837
920
  console.error(`[AgentInstall] Failed to install MCP "${mcp.name}":`, err.message);
838
921
  mcpResults.push({ name: mcp.name, success: false, error: err.message });
@@ -865,6 +948,8 @@ router.post('/install', async (req, res) => {
865
948
  isAgent: true,
866
949
  claudeMdHash,
867
950
  installedFiles,
951
+ installedSkills,
952
+ installedMcps,
868
953
  gitRepos: (agent.git_repos || []).filter(g => g.name && g.repo).map(g => ({
869
954
  name: g.name, repo: g.repo, branch: g.branch || 'main'
870
955
  }))
@@ -1727,18 +1812,15 @@ router.post('/submissions/:id/approve', async (req, res) => {
1727
1812
  entry.agentInfo.claudeMdHash = newClaudeMdHash;
1728
1813
  entry.agentInfo.installedFiles = newInstalledFiles;
1729
1814
 
1730
- // Update git repo dependencies
1731
1815
  if (publishedAgent) {
1816
+ // Update git repo dependencies
1732
1817
  const newGitRepos = (publishedAgent.git_repos || []).filter(g => g.name && g.repo);
1733
1818
  const oldGitRepos = entry.agentInfo.gitRepos || [];
1819
+ const oldGitByName = new Map(oldGitRepos.map(g => [g.name, g]));
1820
+ const newGitByName = new Map(newGitRepos.map(g => [g.name, g]));
1734
1821
 
1735
- // Build lookup maps
1736
- const oldByName = new Map(oldGitRepos.map(g => [g.name, g]));
1737
- const newByName = new Map(newGitRepos.map(g => [g.name, g]));
1738
-
1739
- // Remove symlinks for deleted git repos
1740
1822
  for (const old of oldGitRepos) {
1741
- if (!newByName.has(old.name)) {
1823
+ if (!newGitByName.has(old.name)) {
1742
1824
  try {
1743
1825
  const linkPath = path.join(projectDir, old.name);
1744
1826
  await fs.unlink(linkPath).catch(() => {});
@@ -1747,9 +1829,8 @@ router.post('/submissions/:id/approve', async (req, res) => {
1747
1829
  }
1748
1830
  }
1749
1831
 
1750
- // Add/update git repos
1751
1832
  for (const gitRepo of newGitRepos) {
1752
- const old = oldByName.get(gitRepo.name);
1833
+ const old = oldGitByName.get(gitRepo.name);
1753
1834
  const branchChanged = !old || old.branch !== gitRepo.branch;
1754
1835
  const repoChanged = !old || old.repo !== gitRepo.repo;
1755
1836
 
@@ -1762,16 +1843,67 @@ router.post('/submissions/:id/approve', async (req, res) => {
1762
1843
  console.warn(`[AgentApprove] Failed to update git repo "${gitRepo.name}" for user ${user.uuid}:`, e.message);
1763
1844
  }
1764
1845
  } else {
1765
- // Same repo + branch just ensure shared repo is up to date
1766
- try {
1767
- await ensureSharedGitRepo(gitRepo.repo, gitRepo.branch || 'main');
1768
- } catch {}
1846
+ try { await ensureSharedGitRepo(gitRepo.repo, gitRepo.branch || 'main'); } catch {}
1769
1847
  }
1770
1848
  }
1771
1849
 
1772
1850
  entry.agentInfo.gitRepos = newGitRepos.map(g => ({
1773
1851
  name: g.name, repo: g.repo, branch: g.branch || 'main'
1774
1852
  }));
1853
+
1854
+ // Update skill dependencies
1855
+ const newSkills = (publishedAgent.skills || []).filter(s => s.name && s.repo);
1856
+ const oldSkills = entry.agentInfo.installedSkills || [];
1857
+ const newSkillNames = new Set(newSkills.map(s => s.name));
1858
+
1859
+ for (const old of oldSkills) {
1860
+ if (!newSkillNames.has(old.name)) {
1861
+ try {
1862
+ await uninstallSkill(old.name, user.uuid, projectDir);
1863
+ console.log(`[AgentApprove] Removed old skill "${old.name}" for user ${user.uuid}`);
1864
+ } catch (e) {
1865
+ console.warn(`[AgentApprove] Could not remove old skill "${old.name}" for user ${user.uuid}:`, e.message);
1866
+ }
1867
+ }
1868
+ }
1869
+
1870
+ const newInstalledSkills = [];
1871
+ for (const skill of newSkills) {
1872
+ try {
1873
+ const ok = await installSkill(skill.name, skill.repo, user.uuid, projectDir);
1874
+ if (ok) newInstalledSkills.push({ name: skill.name, repo: skill.repo });
1875
+ } catch (e) {
1876
+ console.warn(`[AgentApprove] Could not install skill "${skill.name}" for user ${user.uuid}:`, e.message);
1877
+ }
1878
+ }
1879
+ entry.agentInfo.installedSkills = newInstalledSkills;
1880
+
1881
+ // Update MCP dependencies
1882
+ const newMcps = (publishedAgent.mcps || []).filter(m => m.name && m.repo);
1883
+ const oldMcps = entry.agentInfo.installedMcps || [];
1884
+ const newMcpNames = new Set(newMcps.map(m => m.name));
1885
+
1886
+ for (const old of oldMcps) {
1887
+ if (!newMcpNames.has(old.name)) {
1888
+ try {
1889
+ await uninstallMcp(old.keys, user.uuid, projectDir);
1890
+ console.log(`[AgentApprove] Removed old MCP "${old.name}" for user ${user.uuid}`);
1891
+ } catch (e) {
1892
+ console.warn(`[AgentApprove] Could not remove old MCP "${old.name}" for user ${user.uuid}:`, e.message);
1893
+ }
1894
+ }
1895
+ }
1896
+
1897
+ const newInstalledMcps = [];
1898
+ for (const mcp of newMcps) {
1899
+ try {
1900
+ const result = await installMcp(mcp.name, mcp.repo, user.uuid, projectDir);
1901
+ if (result.success) newInstalledMcps.push({ name: mcp.name, repo: mcp.repo, keys: result.keys });
1902
+ } catch (e) {
1903
+ console.warn(`[AgentApprove] Could not install MCP "${mcp.name}" for user ${user.uuid}:`, e.message);
1904
+ }
1905
+ }
1906
+ entry.agentInfo.installedMcps = newInstalledMcps;
1775
1907
  }
1776
1908
 
1777
1909
  userUpdated = true;
@@ -7,11 +7,14 @@ const MAX_PER_USER = 10;
7
7
 
8
8
  /**
9
9
  * 剥离参数字符串两端的引号(支持直引号和 curly quotes)并解析 JSON
10
+ * 同时将 AI 错误写入的 \' 还原为单引号(\' 在 JSON 中非法,但单引号本身在 JSON 字符串值里合法)
10
11
  */
11
12
  function parseJsonArg(raw) {
12
13
  let s = raw.trim();
13
14
  // 直引号 ' " 和 curly quotes \u2018\u2019\u201C\u201D
14
15
  s = s.replace(/^[\s\u2018\u201C'"]|[\s\u2019\u201D'"]+$/g, '').trim();
16
+ // 修复 AI 错误转义:\' → '(JSON 不支持 \',但单引号本身合法)
17
+ s = s.replace(/\\'/g, "'");
15
18
  return JSON.parse(s);
16
19
  }
17
20