pikiloom 0.4.30 → 0.4.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/assets/{AgentTab-B4EYK2m8.js → AgentTab-CYoIkNyL.js} +1 -1
- package/dashboard/dist/assets/{ConnectionModal-BktbmACQ.js → ConnectionModal-CbWtylsE.js} +1 -1
- package/dashboard/dist/assets/{DirBrowser-DPNjooga.js → DirBrowser-BsHjGC5A.js} +1 -1
- package/dashboard/dist/assets/ExtensionsTab-BYoLkIki.js +1 -0
- package/dashboard/dist/assets/{IMAccessTab-1HeNr-tg.js → IMAccessTab-B-SxDXft.js} +1 -1
- package/dashboard/dist/assets/{Modal-B4wc5184.js → Modal-CzQbFS5c.js} +1 -1
- package/dashboard/dist/assets/{Modals-C-2IImYO.js → Modals-V9ykx8c4.js} +1 -1
- package/dashboard/dist/assets/{Select-xEvJAcZi.js → Select-DE6cseW_.js} +1 -1
- package/dashboard/dist/assets/{SessionPanel-DRrCVpih.js → SessionPanel-CMu962uE.js} +1 -1
- package/dashboard/dist/assets/{SystemTab-DTggBzSg.js → SystemTab-Cx6DyiFf.js} +1 -1
- package/dashboard/dist/assets/{index-DVHryefY.js → index-Cjaly0tB.js} +3 -3
- package/dashboard/dist/assets/{index-CJm8YsKX.js → index-Dp_KlJM9.js} +2 -2
- package/dashboard/dist/assets/{shared-CDeMhM6X.js → shared-DQrcGYOc.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dist/agent/artifacts.js +11 -1
- package/dist/agent/index.js +1 -1
- package/dist/bot/bot.js +4 -1
- package/dist/catalog/mcp-servers.js +24 -0
- package/dist/core/utils.js +12 -6
- package/dist/dashboard/routes/sessions.js +7 -2
- package/package.json +1 -1
- package/dashboard/dist/assets/ExtensionsTab-Bv_23Acs.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as o,j as e}from"./react-vendor-C7Sl8SE7.js";import{u as D,H as ge,J as ve,c as H,a as $,K as X,S as U,m as I,I as O,B as be}from"./index-Dp_KlJM9.js";import{M as V,a as J}from"./Modal-CzQbFS5c.js";import"./router-DHISdpPk.js";function a(s,t,n){return s==="zh-CN"?t:n}function le(s,t){return t.type==="mcp-oauth"?a(s,"OAuth","OAuth"):t.type==="credentials"?a(s,"API Key","API Key"):a(s,"无需配置","No auth")}const je={github:{hex:"#24292f",letter:"GH"},atlassian:{hex:"#0052cc",letter:"A"},notion:{hex:"#111827",letter:"N"},linear:{hex:"#5e6ad2",letter:"L"},sentry:{hex:"#362d59",letter:"S"},cloudflare:{hex:"#f6821f",letter:"CF"},gamma:{hex:"#9f2eff",letter:"G"},huggingface:{hex:"#ff9d00",letter:"HF"},slack:{hex:"#4a154b",letter:"S"},lark:{hex:"#00d6b9",letter:"L"},feishu:{hex:"#00d6b9",letter:"F"},gmail:{hex:"#ea4335",letter:"G"},outlook:{hex:"#0078d4",letter:"O"},stripe:{hex:"#635bff",letter:"S"},perplexity:{hex:"#20b8cd",letter:"P"},brave:{hex:"#fb542b",letter:"B"},filesystem:{hex:"#64748b",letter:"FS"},fetch:{hex:"#0ea5e9",letter:"F"},memory:{hex:"#a855f7",letter:"M"},time:{hex:"#10b981",letter:"T"},sqlite:{hex:"#0369a1",letter:"SQ"},postgres:{hex:"#336791",letter:"PG"}},ye={hex:"#6b7280"};function ke(s,t){const n=(s||"").toLowerCase(),i=je[n]||ye,l=i.letter||(t||"").replace(/[^a-zA-Z0-9]/g,"").slice(0,2).toUpperCase()||"?";return{hex:i.hex,letter:l}}function q(s,t){const n=s.replace("#",""),i=n.length===3?n.split("").map(u=>u+u).join(""):n.padEnd(6,"0").slice(0,6),l=parseInt(i.slice(0,2),16),c=parseInt(i.slice(2,4),16),d=parseInt(i.slice(4,6),16);return`rgba(${l}, ${c}, ${d}, ${t})`}function ee(s,t,n=[]){const[i,l]=o.useState(()=>{try{const p=localStorage.getItem(s);return p?JSON.parse(p):null}catch{return null}}),[c,d]=o.useState(!1),u=o.useRef(!0);o.useEffect(()=>()=>{u.current=!1},[]);const h=o.useCallback(async()=>{d(!0);try{const p=await t();if(!u.current)return;l(p);try{localStorage.setItem(s,JSON.stringify(p))}catch{}}finally{u.current&&d(!1)}},[s,...n]);return o.useEffect(()=>{h()},[h]),{data:i,loading:c,refresh:h}}const G=()=>e.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}),e.jsx("polyline",{points:"15 3 21 3 21 9"}),e.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]}),K=({size:s=12})=>e.jsxs("svg",{width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14"}),e.jsx("polyline",{points:"22 4 12 14.01 9 11.01"})]}),Ne=({size:s=12})=>e.jsxs("svg",{width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18.36 6.64a9 9 0 1 1-12.73 0"}),e.jsx("line",{x1:"12",y1:"2",x2:"12",y2:"12"})]}),ie=({size:s=12})=>e.jsxs("svg",{width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),e.jsx("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"})]}),Ce=({size:s=12})=>e.jsxs("svg",{width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("circle",{cx:"12",cy:"12",r:"10"}),e.jsx("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),e.jsx("line",{x1:"12",y1:"16",x2:"12.01",y2:"16"})]}),Q=({size:s=12})=>e.jsxs("svg",{width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("polyline",{points:"23 4 23 10 17 10"}),e.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"})]}),oe=new Set(["claude","codex","gemini","telegram","feishu","weixin","playwright","vscode","cursor","windsurf","finder"]),we={github:"logos:github-icon",atlassian:"logos:atlassian",notion:"logos:notion-icon",linear:"logos:linear-icon",sentry:"logos:sentry-icon",cloudflare:"logos:cloudflare-icon","cloudflare-docs":"logos:cloudflare-icon","cloudflare-bindings":"logos:cloudflare-icon","cloudflare-observability":"logos:cloudflare-icon",slack:"logos:slack-icon",lark:"icon-park:lark",feishu:"icon-park:lark",gmail:"logos:google-gmail",outlook:"vscode-icons:file-type-outlook",stripe:"logos:stripe",perplexity:"logos:perplexity-icon",brave:"logos:brave","brave-search":"logos:brave",huggingface:"logos:hugging-face-icon",postgres:"logos:postgresql",postgresql:"logos:postgresql",sqlite:"logos:sqlite",vercel:"logos:vercel-icon",netlify:"logos:netlify-icon",supabase:"logos:supabase-icon",heroku:"logos:heroku-icon",docker:"logos:docker-icon",pnpm:"logos:pnpm",aws:"logos:aws","google-cloud":"logos:google-cloud",googlecloud:"logos:google-cloud",amazonwebservices:"logos:aws"},Se=new Set(["stripe"]);function Ie(s,t){if(t)return t;if(!s||oe.has(s))return;const n=we[s];if(n)return`https://api.iconify.design/${n}.svg`}function T({iconSlug:s,iconUrl:t,name:n,size:i=32,className:l}){const{hex:c,letter:d}=ke(s,n),[u,h]=o.useState(!1),p=Ie(s,t),b=s&&oe.has(s),x=b||!!p&&!u,v=!!s&&Se.has(s),f=Math.round(i*(v?.92:.76));return x?e.jsxs("div",{className:H("relative flex shrink-0 items-center justify-center overflow-hidden rounded-xl bg-white",l),style:{width:i,height:i,boxShadow:`0 0 0 1px ${q(c,.18)}, 0 4px 12px ${q(c,.14)}`},children:[e.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0",style:{background:`linear-gradient(135deg, ${q(c,.06)} 0%, transparent 70%)`}}),b?e.jsx(be,{brand:s,size:f}):e.jsx("img",{src:p,alt:"",width:f,height:f,loading:"lazy",decoding:"async",onError:()=>h(!0),className:"relative"})]}):e.jsxs("div",{className:H("relative flex shrink-0 items-center justify-center overflow-hidden rounded-xl font-semibold text-white",l),style:{width:i,height:i,background:`linear-gradient(135deg, ${q(c,1)} 0%, ${q(c,.82)} 100%)`,boxShadow:`0 1px 0 rgba(255,255,255,0.08) inset, 0 6px 14px ${q(c,.28)}`,fontSize:Math.max(10,Math.round(i*.36)),letterSpacing:d.length>1?"-0.02em":0},children:[e.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0",style:{background:"radial-gradient(circle at 30% 20%, rgba(255,255,255,0.22), transparent 55%)"}}),e.jsx("span",{className:"relative",children:d})]})}function ze({state:s,locale:t}){return s==="ready"?e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold text-[var(--th-ok)]",style:{background:"color-mix(in oklab, var(--th-ok) 12%, transparent)"},children:[e.jsx(K,{size:10}),a(t,"已连接","Connected")]}):s==="disabled"?e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border border-edge bg-inset/60 px-2 py-0.5 text-[10px] font-medium text-fg-5",children:[e.jsx(Ne,{size:10}),a(t,"已停用","Paused")]}):s==="needs_auth"?e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold text-[var(--th-warn)]",style:{background:"color-mix(in oklab, var(--th-warn) 12%, transparent)"},children:[e.jsx(ie,{size:10}),a(t,"待授权","Needs auth")]}):s==="unhealthy"?e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold text-[var(--th-err)]",style:{background:"color-mix(in oklab, var(--th-err) 12%, transparent)"},children:[e.jsx(Ce,{size:10}),a(t,"异常","Unhealthy")]}):null}function Le({open:s,onClose:t,locale:n,item:i,initial:l,onSubmit:c}){const[d,u]=o.useState({}),[h,p]=o.useState(!1);if(o.useEffect(()=>{if(s&&i&&i.auth.type==="credentials"){const x={};for(const v of i.auth.fields)x[v.key]=l?.[v.key]||"";u(x)}},[s,i,l]),!i||i.auth.type!=="credentials")return null;const b=i.auth.fields.some(x=>x.required&&!(d[x.key]||"").trim()),k=async()=>{p(!0);try{await c(d)}finally{p(!1)}};return e.jsxs(V,{open:s,onClose:t,children:[e.jsx(J,{title:a(n,`配置 ${i.name}`,`Configure ${i.name}`),description:n==="zh-CN"?i.descriptionZh:i.description,onClose:t}),e.jsxs("div",{className:"space-y-3",children:[i.auth.fields.map(x=>e.jsxs("div",{children:[e.jsxs("label",{className:"mb-1 flex items-center justify-between",children:[e.jsxs("span",{className:"text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:[n==="zh-CN"?x.labelZh:x.label,x.required&&e.jsx("span",{className:"ml-1 text-err",children:"*"})]}),x.helpUrl&&e.jsxs("a",{href:x.helpUrl,target:"_blank",rel:"noreferrer",className:"flex items-center gap-1 text-[11px] text-primary hover:text-primary/80",children:[a(n,"获取","Get one")," ",e.jsx(G,{})]})]}),e.jsx(O,{value:d[x.key]||"",onChange:v=>u({...d,[x.key]:v.target.value}),type:x.secret?"password":"text",placeholder:x.placeholder,className:"font-mono text-[12px]"})]},x.key)),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-edge pt-3",children:[e.jsx(I,{variant:"ghost",onClick:t,children:a(n,"取消","Cancel")}),e.jsx(I,{variant:"primary",disabled:h||b,onClick:k,children:h?e.jsx(U,{}):a(n,"保存并启用","Save & Enable")})]})]})]})}function Me({open:s,onClose:t,locale:n,scope:i,workdir:l,onAdded:c}){const d=D(j=>j.toast),[u,h]=o.useState(""),[p,b]=o.useState("stdio"),[k,x]=o.useState("npx"),[v,f]=o.useState(""),[C,A]=o.useState(""),[R,w]=o.useState([]),[z,E]=o.useState(!1);o.useEffect(()=>{s&&(h(""),b("stdio"),x("npx"),f(""),A(""),w([]))},[s]);const L=async()=>{if(u.trim()){E(!0);try{const j={};for(const{k:N,v:M}of R)N.trim()&&(j[N.trim()]=M);const y=p==="http"?{type:"http",url:C.trim(),enabled:!0,...Object.keys(j).length?{headers:j}:{}}:{type:"stdio",command:k.trim(),args:v.trim()?v.trim().split(/\s+/):[],enabled:!0,...Object.keys(j).length?{env:j}:{}};await $.addCustomMcp(u.trim(),y,i,l),d(a(n,`${u} 已添加`,`${u} added`),!0),c(),t()}catch(j){d(j?.message||"Failed",!1)}finally{E(!1)}}};return e.jsxs(V,{open:s,onClose:t,wide:!0,children:[e.jsx(J,{title:a(n,"添加自定义 MCP 服务","Add Custom MCP Server"),description:a(n,"不在推荐列表中的自定义服务。","For servers not in the recommended catalog."),onClose:t}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1.5 block text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:a(n,"名称","Name")}),e.jsx(O,{value:u,onChange:j=>h(j.target.value),placeholder:"my-server"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1.5 block text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:a(n,"传输","Transport")}),e.jsx("div",{className:"flex gap-1.5",children:["stdio","http"].map(j=>e.jsx("button",{onClick:()=>b(j),className:H("flex-1 rounded-md border px-3 py-1.5 text-[12px] font-medium transition-colors",p===j?"border-primary/40 bg-primary/10 text-primary":"border-edge bg-inset/50 text-fg-4 hover:bg-inset"),children:j},j))})]})]}),p==="stdio"?e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1.5 block text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:a(n,"命令","Command")}),e.jsx(O,{value:k,onChange:j=>x(j.target.value),className:"font-mono",placeholder:"npx"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1.5 block text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:a(n,"参数","Arguments")}),e.jsx(O,{value:v,onChange:j=>f(j.target.value),className:"font-mono",placeholder:"-y @example/server"})]})]}):e.jsxs("div",{children:[e.jsx("label",{className:"mb-1.5 block text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:"URL"}),e.jsx(O,{value:C,onChange:j=>A(j.target.value),className:"font-mono",placeholder:"https://example.com/mcp"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-1.5 flex items-center justify-between",children:[e.jsx("span",{className:"text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:p==="http"?a(n,"Headers","Headers"):a(n,"环境变量","Env")}),e.jsxs("button",{className:"text-[11px] font-medium text-primary hover:text-primary/80",onClick:()=>w([...R,{k:"",v:""}]),children:["+ ",a(n,"添加","Add")]})]}),R.length>0&&e.jsx("div",{className:"space-y-1 rounded-md border border-edge bg-inset/40 p-2",children:R.map((j,y)=>e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(O,{className:"w-2/5 !h-7 !text-[12px] font-mono",value:j.k,onChange:N=>{const M=[...R];M[y]={...M[y],k:N.target.value},w(M)},placeholder:"KEY"}),e.jsx(O,{className:"flex-1 !h-7 !text-[12px] font-mono",value:j.v,onChange:N=>{const M=[...R];M[y]={...M[y],v:N.target.value},w(M)},type:/token|secret|key|bearer/i.test(j.k)?"password":"text",placeholder:"value"}),e.jsx("button",{className:"shrink-0 rounded p-1 text-fg-5 hover:text-err",onClick:()=>w(R.filter((N,M)=>M!==y)),children:e.jsxs("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:[e.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),e.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]},y))})]}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-edge pt-3",children:[e.jsx(I,{variant:"ghost",onClick:t,children:a(n,"取消","Cancel")}),e.jsx(I,{variant:"primary",disabled:!u.trim()||z,onClick:L,children:z?e.jsx(U,{}):a(n,"添加","Add")})]})]})]})}function Ae({open:s,onClose:t,locale:n,scope:i,workdir:l,onInstalled:c}){const d=D(f=>f.toast),[u,h]=o.useState(""),[p,b]=o.useState(""),[k,x]=o.useState(!1);o.useEffect(()=>{s&&(h(""),b(""))},[s]);const v=async()=>{if(u.trim()){x(!0);try{const f=await $.installSkill(u.trim(),i==="global",p.trim()||void 0,l);f.ok?(d(a(n,"技能安装成功","Skill installed"),!0),c(),t()):d(f.error||"Failed",!1)}catch(f){d(f?.message||"Failed",!1)}finally{x(!1)}}};return e.jsxs(V,{open:s,onClose:t,children:[e.jsx(J,{title:a(n,"安装自定义技能","Install Custom Skill"),description:a(n,"通过 npx skills add 从 GitHub 仓库安装。","Installs via npx skills add from a GitHub repo."),onClose:t}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1.5 block text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:a(n,"GitHub 来源","GitHub Source")}),e.jsx(O,{value:u,onChange:f=>h(f.target.value),placeholder:"owner/repo",className:"font-mono"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1.5 block text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:a(n,"指定技能(可选)","Specific skill (optional)")}),e.jsx(O,{value:p,onChange:f=>b(f.target.value),placeholder:a(n,"留空安装全部","Leave empty for all")})]}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-edge pt-3",children:[e.jsx(I,{variant:"ghost",onClick:t,children:a(n,"取消","Cancel")}),e.jsx(I,{variant:"primary",disabled:!u.trim()||k,onClick:v,children:k?e.jsx(U,{}):a(n,"安装","Install")})]})]})]})}function $e(s,t){return new Promise(n=>{const i=window.open(s,"pikiloom_mcp_oauth","width=640,height=780,noopener=no");if(!i){n(!1);return}let l=!1;const c=h=>{l||(l=!0,window.removeEventListener("message",d),clearInterval(u),n(h))},d=h=>{const p=h.data;if(!(!p||p.type!=="mcp-oauth")&&!(t&&p.state!==t)){c(!!p.ok);try{i.close()}catch{}}};window.addEventListener("message",d);const u=setInterval(()=>{i.closed&&c(!1)},500)})}function ae({item:s,locale:t,busy:n,index:i,onPrimary:l,onRemove:c,onReauth:d,onReconfigure:u}){const h=(()=>{switch(s.state){case"ready":return a(t,"停用","Pause");case"unhealthy":return a(t,"停用","Pause");case"disabled":return a(t,"启用","Enable");case"needs_auth":return s.auth.type==="mcp-oauth"?a(t,"授权","Authorize"):a(t,"配置","Configure");default:return a(t,"启用","Enable")}})(),p={animationDelay:`${Math.min(i,8)*40}ms`};return e.jsxs("div",{className:H("group relative overflow-hidden rounded-lg border border-[var(--edge-subtle)] bg-[var(--surface-2)] p-4","transition-[background,border-color] duration-200","hover:border-[var(--edge-default)] hover:bg-[var(--surface-3)]","animate-in-up"),style:p,children:[e.jsxs("div",{className:"relative flex items-start gap-3",children:[e.jsx(T,{iconSlug:s.iconSlug,iconUrl:s.iconUrl,name:s.name,size:36}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"truncate text-[14px] font-semibold text-fg",children:s.name}),s.homepage&&e.jsx("a",{href:s.homepage,target:"_blank",rel:"noreferrer",className:"text-fg-5 hover:text-fg-3 transition-colors",children:e.jsx(G,{})})]}),e.jsx("div",{className:"mt-0.5 line-clamp-2 text-[12px] leading-snug text-fg-4",children:t==="zh-CN"?s.descriptionZh:s.description})]}),e.jsx(ze,{state:s.state,locale:t})]}),e.jsxs("div",{className:"relative mt-3 flex items-center justify-between border-t border-[var(--edge-subtle)] pt-3",children:[e.jsxs("span",{className:"inline-flex items-center gap-1 text-[11px] text-fg-5",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-fg-6"}),le(t,s.auth)]}),e.jsxs("div",{className:"flex items-center gap-1",children:[s.installed&&s.state!=="needs_auth"&&d&&e.jsx(I,{variant:"ghost",size:"sm",onClick:d,disabled:n,children:a(t,"重新授权","Re-auth")}),s.installed&&s.state!=="needs_auth"&&u&&e.jsx(I,{variant:"ghost",size:"sm",onClick:u,disabled:n,children:a(t,"编辑","Edit")}),e.jsx(I,{variant:s.state==="disabled"||s.state==="needs_auth"?"primary":"ghost",size:"sm",onClick:l,disabled:n,children:n?e.jsx(U,{}):h}),s.installed&&c&&e.jsx(I,{variant:"ghost",size:"sm",onClick:c,disabled:n,className:"hover:!text-err",children:a(t,"移除","Remove")})]})]})]})}function re({item:s,locale:t,busy:n,index:i,onPrimary:l}){const c=s.auth.type==="none"?a(t,"一键启用","One-click enable"):a(t,"授权并启用","Authorize & enable");return e.jsxs("div",{className:H("group relative flex flex-col gap-3 rounded-lg border border-[var(--edge-subtle)] bg-[var(--surface-2)] p-4","transition-[background,border-color] duration-200","hover:border-[var(--edge-default)] hover:bg-[var(--surface-3)]","animate-in-up"),style:{animationDelay:`${Math.min(i,12)*30}ms`},children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(T,{iconSlug:s.iconSlug,iconUrl:s.iconUrl,name:s.name,size:32}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"truncate text-[13.5px] font-semibold text-fg",children:s.name}),s.homepage&&e.jsx("a",{href:s.homepage,target:"_blank",rel:"noreferrer",className:"text-fg-5 hover:text-fg-3 transition-colors",children:e.jsx(G,{})})]}),e.jsx("div",{className:"mt-0.5 line-clamp-2 text-[12px] leading-snug text-fg-4",children:t==="zh-CN"?s.descriptionZh:s.description})]})]}),e.jsxs("div",{className:"mt-auto flex items-center justify-between",children:[e.jsx("span",{className:"inline-flex items-center gap-1 text-[11px] text-fg-5",children:le(t,s.auth)}),e.jsx(I,{variant:"outline",size:"sm",onClick:l,disabled:n,className:"group-hover:border-edge-h",children:n?e.jsx(U,{}):c})]})]})}function Ee(s,t){const n=s.installedNames.length;if(typeof s.totalCount=="number"){const i=s.partial?`${s.totalCount}+`:String(s.totalCount);return t==="zh-CN"?`${n} / ${i} 已安装`:`${n} / ${i} installed`}return n>0?t==="zh-CN"?`${n} 已安装`:`${n} installed`:a(t,"未安装","Not installed")}function Re({item:s,locale:t,animationDelay:n,onClick:i,onUpdate:l,updating:c}){return e.jsxs("button",{type:"button",onClick:i,className:"animate-in-up group relative flex min-h-[112px] w-full flex-col overflow-hidden rounded-lg border border-[var(--edge-subtle)] bg-[var(--surface-2)] p-4 text-left transition-[background,border-color] duration-200 hover:border-[var(--edge-default)] hover:bg-[var(--surface-3)] focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--brand-glow-a)]",style:{animationDelay:n},children:[e.jsxs("div",{className:"relative flex items-start gap-3",children:[e.jsx(T,{iconUrl:s.iconUrl,name:s.name,size:36}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[e.jsx("span",{className:"truncate text-[13px] font-semibold text-fg",children:s.name}),s.homepage&&e.jsx("a",{href:s.homepage,target:"_blank",rel:"noreferrer",onClick:d=>d.stopPropagation(),className:"text-fg-5 transition-colors hover:text-primary",children:e.jsx(G,{})})]}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[s.updateAvailable&&e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold text-[var(--th-warn)]",style:{background:"color-mix(in oklab, var(--th-warn) 14%, transparent)"},children:[e.jsx(Q,{size:10}),a(t,"可更新","Update")]}),e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold text-[var(--th-ok)]",style:{background:"color-mix(in oklab, var(--th-ok) 12%, transparent)"},children:[e.jsx(K,{size:10}),Ee(s,t)]})]})]}),e.jsx("div",{className:"mt-0.5 truncate text-[11.5px] text-fg-5",children:s.source}),e.jsx("div",{className:"mt-1 line-clamp-2 text-[11.5px] text-fg-4",children:t==="zh-CN"?s.descriptionZh:s.description})]})]}),e.jsxs("div",{className:"relative mt-auto pt-3 flex items-center justify-between text-[10.5px] text-fg-5",children:[e.jsxs("span",{className:"flex items-center gap-2",children:[s.stars!==void 0&&e.jsxs("span",{className:"inline-flex items-center gap-0.5 font-medium text-fg-4",children:[e.jsx(se,{size:10}),te(s.stars)]}),s.pushedAt&&e.jsx("span",{children:ce(s.pushedAt,t)})]}),e.jsxs("span",{className:"flex items-center gap-2.5",children:[s.updateAvailable&&l&&e.jsx("span",{role:"button",tabIndex:0,"aria-label":a(t,"更新到最新","Update to latest"),onClick:d=>{d.stopPropagation(),c||l()},onKeyDown:d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),d.stopPropagation(),c||l())},className:"inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-[10.5px] font-semibold text-[var(--th-warn)] transition hover:brightness-110",style:{background:"color-mix(in oklab, var(--th-warn) 14%, transparent)"},children:c?e.jsx(U,{className:"h-3 w-3"}):e.jsxs(e.Fragment,{children:[e.jsx(Q,{size:11}),a(t,"更新","Update")]})}),e.jsx("span",{className:"text-fg-5 group-hover:text-primary transition-colors",children:a(t,"管理 →","Manage →")})]})]})]})}function _e({item:s,locale:t,animationDelay:n,onClick:i}){return e.jsxs("button",{type:"button",onClick:i,className:"animate-in-up group relative flex min-h-[112px] w-full flex-col overflow-hidden rounded-lg border border-[var(--edge-subtle)] bg-[var(--surface-2)] p-4 text-left transition-[background,border-color] duration-200 hover:border-[var(--edge-default)] hover:bg-[var(--surface-3)] focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--brand-glow-a)]",style:{animationDelay:n},children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(T,{iconUrl:s.iconUrl,name:s.name,size:32}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate text-[13px] font-semibold text-fg",children:s.name}),s.homepage&&e.jsx("a",{href:s.homepage,target:"_blank",rel:"noreferrer",onClick:l=>l.stopPropagation(),className:"text-fg-5 transition-colors hover:text-primary",children:e.jsx(G,{})})]}),e.jsx("div",{className:"mt-0.5 line-clamp-2 text-[11.5px] text-fg-4",children:t==="zh-CN"?s.descriptionZh:s.description})]})]}),e.jsxs("div",{className:"mt-auto pt-3 flex items-center justify-between",children:[e.jsxs("span",{className:"flex items-center gap-2 text-[11px] text-fg-5",children:[s.stars!==void 0&&e.jsxs("span",{className:"inline-flex items-center gap-0.5 font-medium text-fg-4",children:[e.jsx(se,{size:10}),te(s.stars)]}),typeof s.totalCount=="number"&&e.jsxs("span",{children:["· ",s.partial?`${s.totalCount}+`:s.totalCount," skills"]})]}),e.jsx("span",{className:"inline-flex items-center gap-1 rounded-md border border-[var(--edge-subtle)] bg-transparent px-2.5 py-1 text-[11px] font-semibold text-fg-3 transition-colors group-hover:border-[var(--edge-default)] group-hover:text-fg",children:a(t,"查看 →","Browse →")})]})]})}function Ue({skill:s,locale:t,animationDelay:n,busy:i,onRemove:l}){const[c,d]=o.useState(!1);return e.jsxs("div",{className:"animate-in-up group relative flex min-h-[112px] w-full flex-col overflow-hidden rounded-lg border border-[var(--edge-subtle)] bg-[var(--surface-2)] p-4 text-left transition-[background,border-color] duration-200 hover:border-[var(--edge-default)] hover:bg-[var(--surface-3)]",style:{animationDelay:n},onMouseLeave:()=>d(!1),children:[e.jsxs("div",{className:"relative flex items-start gap-3",children:[e.jsx(T,{name:s.name,size:36}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"truncate text-[13px] font-semibold text-fg",children:s.label||s.name}),e.jsx("span",{className:"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold text-fg-4 shrink-0",style:{background:"color-mix(in oklab, var(--fg-5) 14%, transparent)"},children:a(t,"本地","Local")})]}),e.jsxs("div",{className:"mt-0.5 truncate font-mono text-[11.5px] text-fg-5",children:["/",s.name]}),s.description&&e.jsx("div",{className:"mt-1 line-clamp-2 text-[11.5px] text-fg-4",children:s.description})]})]}),e.jsxs("div",{className:"relative mt-auto pt-3 flex items-center justify-between text-[10.5px] text-fg-5",children:[e.jsx("span",{children:s.scope==="global"?a(t,"全局 · ~/.pikiloom/skills","Global · ~/.pikiloom/skills"):a(t,"项目 · .pikiloom/skills","Project · .pikiloom/skills")}),e.jsx(I,{variant:"ghost",size:"sm",disabled:i,onClick:()=>{c?(d(!1),l()):d(!0)},className:c?"!text-err":"hover:!text-err",children:i?e.jsx(U,{}):c?a(t,"确认移除?","Confirm remove?"):a(t,"移除","Remove")})]})]})}function Pe({item:s,open:t,onClose:n,onChanged:i,locale:l,scope:c,workdir:d,installedSkills:u}){const h=D(r=>r.toast),[p,b]=o.useState(null),[k,x]=o.useState(!1),[v,f]=o.useState(null),[C,A]=o.useState(!1),[R,w]=o.useState(null),[z,E]=o.useState(null),[L,j]=o.useState("");o.useEffect(()=>{if(!t||!s)return;let r=!1;return x(!0),f(null),j(""),(async()=>{try{const m=await $.listRepoSkills(s.source);if(r)return;m.ok?(b(m.skills),A(!!m.partial)):(f(m.error||"failed to list"),b([]))}catch(m){if(r)return;f(m?.message||"failed"),b([])}finally{r||x(!1)}})(),()=>{r=!0}},[t,s?.source]);const y=o.useMemo(()=>{const r=new Set,m=c==="global"?"global":"project";for(const _ of u)_.scope===m&&r.add(_.name.toLowerCase());return r},[u,c]),N=o.useMemo(()=>{const r=p||[],m=L.trim().toLowerCase();return m?r.filter(_=>_.name.toLowerCase().includes(m)):r},[p,L]),M=o.useMemo(()=>p?p.filter(r=>y.has(r.name.toLowerCase())).length:0,[p,y]),P=o.useCallback(async r=>{if(s){w(r);try{const m=await $.installSkill(s.source,c==="global",r,d);m.ok?(h(a(l,`${r} 已安装`,`${r} installed`),!0),i()):h(m.error||"Failed",!1)}catch(m){h(m?.message||"Failed",!1)}finally{w(null)}}},[s,c,d,l,h,i]),B=o.useCallback(async r=>{w(r);try{const m=await $.removeExtensionSkill(r,c==="global",d);m.ok?(h(a(l,`${r} 已移除`,`${r} removed`),!0),i()):h(m.error||"Failed",!1)}catch(m){h(m?.message||"Failed",!1)}finally{w(null)}},[c,d,l,h,i]),g=o.useCallback(async()=>{if(s){E("install");try{const r=await $.installSkill(s.source,c==="global",void 0,d);r.ok?(h(a(l,"全部安装完成","All skills installed"),!0),i()):h(r.error||"Failed",!1)}catch(r){h(r?.message||"Failed",!1)}finally{E(null)}}},[s,c,d,l,h,i]),S=o.useCallback(async()=>{if(s){E("update");try{const r=await $.updateSkill(s.source,c==="global",d);r.ok?(h(a(l,"已更新到最新版本","Updated to the latest version"),!0),i()):h(r.error||"Failed",!1)}catch(r){h(r?.message||"Failed",!1)}finally{E(null)}}},[s,c,d,l,h,i]),F=o.useCallback(async()=>{if(!(!s||!p)){E("remove");try{const r=p.map(m=>m.name).filter(m=>y.has(m.toLowerCase()));for(const m of r)await $.removeExtensionSkill(m,c==="global",d);h(a(l,"已移除该集合下的全部技能","Removed all skills from this collection"),!0),i()}catch(r){h(r?.message||"Failed",!1)}finally{E(null)}}},[s,p,y,c,d,l,h,i]);return s?e.jsxs(V,{open:t,onClose:n,wide:!0,children:[e.jsx(J,{title:s.name,description:l==="zh-CN"?s.descriptionZh:s.description,onClose:n}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(T,{iconUrl:s.iconUrl,name:s.name,size:44}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[13px] font-semibold text-fg",children:[s.name,s.homepage&&e.jsx("a",{href:s.homepage,target:"_blank",rel:"noreferrer",className:"text-fg-5 hover:text-primary",children:e.jsx(G,{})})]}),e.jsxs("div",{className:"mt-0.5 flex items-center gap-2 text-[11.5px] text-fg-4",children:[e.jsx("span",{className:"truncate text-fg-5",children:s.source}),s.stars!==void 0&&e.jsxs("span",{className:"inline-flex items-center gap-0.5 text-fg-5",children:[e.jsx(se,{size:10}),te(s.stars)]}),s.pushedAt&&e.jsxs("span",{className:"text-fg-5",children:["· ",ce(s.pushedAt,l)]})]})]})]}),s.updateAvailable&&e.jsxs("div",{className:"flex items-start gap-2 rounded-lg px-3 py-2 text-[12px] text-fg-2",style:{background:"color-mix(in oklab, var(--th-warn) 12%, transparent)",border:"1px solid color-mix(in oklab, var(--th-warn) 30%, transparent)"},children:[e.jsx("span",{className:"mt-0.5 text-[var(--th-warn)]",children:e.jsx(Q,{size:13})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-semibold text-[var(--th-warn)]",children:a(l,"检测到新版本","A newer version is available")}),e.jsxs("div",{className:"mt-0.5 text-fg-4",children:[a(l,"远端仓库有更新,点击「更新到最新」拉取最新内容。",'The remote repo has moved ahead. Click "Update to latest" to pull the newest content.'),s.installedSha&&s.latestSha&&e.jsxs("span",{className:"ml-1 font-mono text-[11px] text-fg-5",children:[s.installedSha.slice(0,7)," → ",s.latestSha.slice(0,7)]})]})]})]}),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"text-[12px] font-semibold text-fg-3",children:[a(l,"该集合下的技能","Skills in this collection"),p&&e.jsxs("span",{className:"ml-2 text-[11px] font-normal text-fg-5",children:[M," / ",C?`${p.length}+`:p.length," ",a(l,"已安装","installed")]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[s.installed&&e.jsx(I,{variant:s.updateAvailable?"primary":"outline",size:"sm",onClick:S,disabled:z!==null,children:z==="update"?e.jsx(U,{}):e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Q,{size:12}),s.updateAvailable?a(l,"更新到最新","Update to latest"):a(l,"重新拉取","Re-pull latest")]})}),e.jsx(I,{variant:"outline",size:"sm",onClick:g,disabled:z!==null||k,children:z==="install"?e.jsx(U,{}):a(l,"全部安装","Install all")}),M>0&&e.jsx(I,{variant:"ghost",size:"sm",onClick:F,disabled:z!==null,className:"hover:!text-err",children:z==="remove"?e.jsx(U,{}):a(l,"全部移除","Remove all")})]})]}),p&&p.length>6&&e.jsx(O,{type:"text",value:L,onChange:r=>j(r.target.value),placeholder:a(l,"搜索技能…","Search skills…"),className:"w-full"}),k?e.jsx("div",{className:"flex items-center justify-center py-10",children:e.jsx(U,{})}):v?e.jsxs("div",{className:"rounded-lg border border-edge/70 bg-panel/60 p-3 text-[12px] text-fg-4",children:[a(l,"无法从 GitHub 拉取技能列表(可能是网络或速率限制)。你仍可以使用上方的「全部安装」按钮一次性安装该集合。",'Could not list skills from GitHub (network or rate-limit). You can still use "Install all" to grab the whole collection.'),e.jsx("div",{className:"mt-1 truncate font-mono text-[11px] text-fg-5",children:v})]}):N.length===0?e.jsx("div",{className:"rounded-lg border border-edge/70 bg-panel/60 p-3 text-center text-[12px] text-fg-5",children:L?a(l,"没有匹配的技能","No matching skills"):a(l,"该集合暂无可识别的技能","No discoverable skills in this collection")}):e.jsx("div",{className:"max-h-[60vh] overflow-y-auto rounded-lg border border-edge/70 bg-panel/40",children:N.map((r,m)=>{const _=y.has(r.name.toLowerCase()),Z=R===r.name;return e.jsxs("div",{className:H("flex items-center justify-between gap-3 px-3 py-2 text-[12px]",m>0&&"border-t border-edge/40"),children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[_&&e.jsx(K,{size:12}),e.jsx("span",{className:H("truncate font-medium",_?"text-[var(--th-ok)]":"text-fg-2"),children:r.name})]}),r.description&&e.jsx("div",{className:"mt-0.5 line-clamp-1 text-[11px] text-fg-5",children:r.description})]}),_?e.jsx(I,{variant:"ghost",size:"sm",onClick:()=>{B(r.name)},disabled:Z||z!==null,className:"hover:!text-err",children:Z?e.jsx(U,{}):a(l,"移除","Remove")}):e.jsx(I,{variant:"outline",size:"sm",onClick:()=>{P(r.name)},disabled:Z||z!==null,children:Z?e.jsx(U,{}):a(l,"安装","Install")})]},r.name)})}),C&&e.jsx("div",{className:"text-[11px] text-fg-5",children:a(l,"仓库内技能数量较多,仅显示前 1000 个。可使用上方搜索或直接打开仓库浏览全部。","Showing the first 1000 skills. Use search or open the repo on GitHub for the full list.")})]})]})]}):null}const se=({size:s=12})=>e.jsx("svg",{width:s,height:s,viewBox:"0 0 24 24",fill:"currentColor",stroke:"none",children:e.jsx("polygon",{points:"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"})});function te(s){return s>=1e4?`${(s/1e3).toFixed(1).replace(/\.0$/,"")}k`:s>=1e3?`${(s/1e3).toFixed(1)}k`:String(s)}function ce(s,t){const n=Date.parse(s);if(!Number.isFinite(n))return"";const i=Date.now()-n,l=1440*60*1e3,c=Math.max(1,Math.floor(i/l));if(c<30)return t==="zh-CN"?`${c} 天前`:`${c}d ago`;const d=Math.floor(c/30);if(d<12)return t==="zh-CN"?`${d} 个月前`:`${d}mo ago`;const u=Math.floor(d/12);return t==="zh-CN"?`${u} 年前`:`${u}y ago`}const W={dev:{zh:"开发工具",en:"Development",order:0},productivity:{zh:"生产力",en:"Productivity",order:1},communication:{zh:"协作沟通",en:"Communication",order:2},data:{zh:"数据",en:"Data",order:3},search:{zh:"搜索",en:"Search",order:4},utility:{zh:"工具",en:"Utility",order:5},custom:{zh:"自定义",en:"Custom",order:6}};function Fe(s){const t=new Map;for(const n of s){const i=t.get(n.category)||[];i.push(n),t.set(n.category,i)}return[...t.entries()].sort((n,i)=>(W[n[0]]?.order??99)-(W[i[0]]?.order??99)).map(([n,i])=>({key:n,items:i}))}function de({scope:s,workdir:t,locale:n,onOpenBrowserSetup:i}){const l=D(r=>r.toast),c=`pikiloom.mcp.catalog.${s}.${t||""}`,{data:d,loading:u,refresh:h}=ee(c,async()=>(await $.getMcpCatalog(t,s)).items||[],[t,s]),[p,b]=o.useState(""),[k,x]=o.useState(null),[v,f]=o.useState(!1),[C,A]=o.useState(null),R=d||[],w=o.useMemo(()=>R.filter(r=>!r.installed||r.scope===s||!r.scope),[R,s]),z=o.useMemo(()=>{if(!p.trim())return w;const r=p.trim().toLowerCase();return w.filter(m=>m.name.toLowerCase().includes(r)||m.description.toLowerCase().includes(r)||m.descriptionZh.includes(r)||m.id.toLowerCase().includes(r))},[w,p]),E=o.useMemo(()=>z.filter(r=>r.isBuiltin),[z]),L=o.useMemo(()=>z.filter(r=>!r.isBuiltin&&(r.state==="ready"||r.state==="unhealthy")),[z]),j=o.useMemo(()=>Fe(z.filter(r=>!r.isBuiltin&&r.state!=="ready"&&r.state!=="unhealthy")),[z]),y=o.useCallback(async(r,m)=>{if(r.isRecommended){A(r.id);try{const _=await $.installMcp(r.id,s,m,t,!0);if(!_.ok)throw new Error(_.error||"install failed");return await h(),_.enabled??!1}catch(_){return l(_?.message||"Failed",!1),!1}finally{A(null)}}},[s,t,h,l]),N=o.useCallback(async r=>{A(r.id);try{if(!r.installed){const Z=await $.installMcp(r.id,s,void 0,t,!1);if(!Z.ok)throw new Error(Z.error||"install failed")}const m=await $.startMcpOAuth(r.id);if(!m.ok||!m.authUrl||!m.state)throw new Error(m.error||"oauth start failed");await $e(m.authUrl,m.state)?(await $.toggleMcp(r.id,!0,s,t),l(a(n,`${r.name} 授权成功`,`${r.name} authorized`),!0)):l(a(n,"授权未完成","Authorization not completed"),!1),await h()}catch(m){l(m?.message||"OAuth failed",!1)}finally{A(null)}},[s,t,n,l,h]),M=o.useCallback(async(r,m)=>{if(r.installedKey){A(r.id);try{await $.toggleMcp(r.installedKey,m,r.scope==="workspace"?"workspace":"global",t),await h()}catch(_){l(_?.message||"Failed",!1)}finally{A(null)}}},[t,h,l]),P=o.useCallback(async r=>{if(r.installedKey){A(r.id);try{await $.removeMcp(r.installedKey,r.scope==="workspace"?"workspace":"global",r.isRecommended?r.id:void 0,t),await h()}catch(m){l(m?.message||"Failed",!1)}finally{A(null)}}},[t,h,l]),B=o.useCallback(async r=>{if(!k)return;await y(k,r)!==!1&&x(null)},[k,y]),g=o.useCallback(r=>{if(r.state==="ready"||r.state==="unhealthy"){M(r,!1);return}if(r.state==="disabled"){M(r,!0);return}if(r.state==="needs_auth"){if(r.auth.type==="mcp-oauth"){N(r);return}if(r.auth.type==="credentials"){x(r);return}}},[M,N]),S=o.useCallback(r=>{if(r.state==="disabled"){M(r,!0);return}if(r.state==="needs_auth"){if(r.auth.type==="mcp-oauth"){N(r);return}if(r.auth.type==="credentials"){x(r);return}}if(r.auth.type==="mcp-oauth"){N(r);return}if(r.auth.type==="credentials"){x(r);return}y(r)},[N,y,M]),F=u&&!d;return e.jsxs("section",{children:[e.jsxs("div",{className:"mb-3 flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx(X,{children:"MCP Servers"}),!u&&e.jsxs("span",{className:"text-[11px] text-fg-5",children:[L.length," ",a(n,"在用","in use")," · ",w.length-L.length-E.length," ",a(n,"可添加","available")]}),u&&e.jsx(U,{className:"h-3 w-3"})]}),e.jsx("div",{className:"flex items-center gap-1.5",children:e.jsxs("div",{className:"relative",children:[e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",className:"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-fg-5",children:[e.jsx("circle",{cx:"11",cy:"11",r:"8"}),e.jsx("line",{x1:"21",y1:"21",x2:"16.65",y2:"16.65"})]}),e.jsx("input",{value:p,onChange:r=>b(r.target.value),placeholder:a(n,"搜索...","Search..."),className:"h-7 w-52 rounded-md border border-edge bg-inset/50 pl-7 pr-2.5 text-[12px] text-fg outline-none placeholder:text-fg-5/50 focus:border-primary/30 focus:bg-inset"})]})})]}),F?e.jsx("div",{className:"flex items-center justify-center py-10",children:e.jsx(U,{})}):e.jsxs("div",{className:"space-y-5",children:[E.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"mb-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[var(--th-accent,#7c3aed)]"}),a(n,"内置(pikiloom 优化)","Built-in (optimized by pikiloom)")]}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2",children:E.map((r,m)=>r.installed?e.jsx(ae,{item:r,locale:n,busy:C===r.id,index:m,onPrimary:()=>g(r),onReconfigure:r.id==="pikiloom-browser"?i:void 0},r.id):e.jsx(re,{item:r,locale:n,busy:C===r.id,index:m,onPrimary:()=>S(r)},r.id))})]}),L.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"mb-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[var(--th-ok)]"}),a(n,"在用","In use")]}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2",children:L.map((r,m)=>e.jsx(ae,{item:r,locale:n,busy:C===r.id,index:m,onPrimary:()=>g(r),onRemove:()=>{P(r)},onReauth:r.auth.type==="mcp-oauth"?()=>{N(r)}:void 0,onReconfigure:r.auth.type==="credentials"?()=>x(r):void 0},r.id))})]}),j.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"mb-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-fg-5"}),L.length===0?a(n,"推荐的服务","Recommended services"):a(n,"更多可选","More options")]}),e.jsx("div",{className:"space-y-4",children:j.map(r=>e.jsx(Oe,{groupKey:r.key,locale:n,children:e.jsx("div",{className:"grid gap-2 sm:grid-cols-2 lg:grid-cols-3",children:r.items.map((m,_)=>e.jsx(re,{item:m,locale:n,busy:C===m.id,index:_,onPrimary:()=>S(m)},m.id))})},r.key))})]}),E.length===0&&L.length===0&&j.length===0&&e.jsx(ne,{title:a(n,"没有匹配的服务","No matching services"),subtitle:a(n,"试试别的关键词","Try a different search term")})]}),e.jsx("div",{className:"mt-3 flex justify-end",children:e.jsxs("button",{className:"text-[12px] text-fg-4 hover:text-fg-2 transition-colors",onClick:()=>f(!0),children:["+ ",a(n,"添加自定义 MCP","Add custom MCP")]})}),e.jsx(Le,{open:!!k,onClose:()=>x(null),locale:n,item:k,initial:k?.config?.env||k?.config?.headers,onSubmit:B}),e.jsx(Me,{open:v,onClose:()=>f(!1),locale:n,scope:s,workdir:t,onAdded:h})]})}function Oe({groupKey:s,locale:t,children:n}){const i=W[s],l=i?a(t,i.zh,i.en):s;return e.jsxs("div",{children:[e.jsx("div",{className:"mb-1.5 text-[11px] font-medium text-fg-5",children:l}),n]})}function ne({title:s,subtitle:t}){return e.jsxs("div",{className:"rounded-xl border border-dashed border-edge py-10 text-center",children:[e.jsx("div",{className:"text-[13px] font-medium text-fg-3",children:s}),t&&e.jsx("div",{className:"mt-1 text-[12px] text-fg-5",children:t})]})}function xe({scope:s,workdir:t,locale:n}){const i=`pikiloom.skills.catalog.${s}.${t||""}`,{data:l,loading:c,refresh:d}=ee(i,async()=>{const g=await $.getSkillsCatalog(t,s);return{items:g.items||[],installed:g.installed||[]}},[t,s]),[u,h]=o.useState(!1),[p,b]=o.useState(null),[k,x]=o.useState(null),[v,f]=o.useState(null),C=D(g=>g.toast),A=l?.items||[],R=l?.installed||[],w=o.useMemo(()=>{const g=s==="global"?"global":"project";return R.filter(S=>S.scope===g)},[R,s]),z=o.useMemo(()=>A.filter(g=>g.installedNames.length>0),[A]),E=o.useMemo(()=>A.filter(g=>g.installedNames.length===0),[A]),L=o.useMemo(()=>{const g=new Set;for(const S of A)for(const F of S.installedNames)g.add(F.toLowerCase());return w.filter(S=>!g.has(S.name.toLowerCase()))},[A,w]),j=o.useCallback(async g=>{x(g);try{const S=await $.removeExtensionSkill(g,s==="global",t);S.ok?(C(a(n,`${g} 已移除`,`${g} removed`),!0),d()):C(S.error||"Failed",!1)}catch(S){C(S?.message||"Failed",!1)}finally{x(null)}},[s,t,n,C,d]),y=o.useCallback(async g=>{f(g.source);try{const S=await $.updateSkill(g.source,s==="global",t);S.ok?(C(a(n,`${g.name} 已更新到最新`,`${g.name} updated to latest`),!0),d()):C(S.error||"Failed",!1)}catch(S){C(S?.message||"Failed",!1)}finally{f(null)}},[s,t,n,C,d]),N=o.useMemo(()=>{const g=new Map;for(const S of E){const F=S.category;g.has(F)||g.set(F,[]),g.get(F).push(S)}return[...g.entries()].sort(([S],[F])=>(W[S]?.order??99)-(W[F]?.order??99))},[E]),M=p&&A.find(g=>g.id===p)||null,P=c&&!l,B=w.length;return e.jsxs("section",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx(X,{children:"Skills"}),!c&&e.jsxs("span",{className:"text-[11px] text-fg-5",children:[B," ",a(n,"已安装","installed")," · ",E.length," ",a(n,"可用","available")]}),c&&e.jsx(U,{className:"h-3 w-3"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(I,{variant:"ghost",size:"sm",onClick:()=>{d()},children:c?a(n,"刷新中…","Refreshing…"):a(n,"刷新","Refresh")}),e.jsxs(I,{variant:"outline",size:"sm",onClick:()=>h(!0),children:["+ ",a(n,"从 GitHub 安装","Install from GitHub")]})]})]}),P?e.jsx("div",{className:"flex items-center justify-center py-10",children:e.jsx(U,{})}):A.length===0&&L.length===0?e.jsx(ne,{title:a(n,"暂无可用的技能包","No skill packs available"),subtitle:a(n,"从 GitHub 导入一个开始使用","Import from GitHub to get started")}):e.jsxs(e.Fragment,{children:[(z.length>0||L.length>0)&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px] font-semibold text-fg-3",children:[e.jsx("span",{className:"inline-block h-1.5 w-1.5 rounded-full bg-[var(--th-ok)]"}),a(n,"已安装","Installed")]}),e.jsxs("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3",children:[z.map((g,S)=>e.jsx(Re,{item:g,locale:n,animationDelay:`${Math.min(S,12)*30}ms`,onClick:()=>b(g.id),onUpdate:()=>{y(g)},updating:v===g.source},g.id)),L.map((g,S)=>e.jsx(Ue,{skill:g,locale:n,animationDelay:`${Math.min(z.length+S,12)*30}ms`,busy:k===g.name,onRemove:()=>{j(g.name)}},`local-${g.name}`))]})]}),E.length>0&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px] font-semibold text-fg-3",children:[e.jsx("span",{className:"inline-block h-1.5 w-1.5 rounded-full bg-fg-5/50"}),a(n,"推荐","Available")]}),N.map(([g,S])=>e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-[10.5px] font-medium uppercase tracking-[0.06em] text-fg-5",children:n==="zh-CN"?W[g]?.zh||g:W[g]?.en||g}),e.jsx("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3",children:S.map((F,r)=>e.jsx(_e,{item:F,locale:n,animationDelay:`${Math.min(r,12)*30}ms`,onClick:()=>b(F.id)},F.id))})]},g))]})]}),e.jsx(Pe,{item:M,open:!!M,onClose:()=>b(null),onChanged:()=>{d()},locale:n,scope:s,workdir:t,installedSkills:R}),e.jsx(Ae,{open:u,onClose:()=>h(!1),locale:n,scope:s,workdir:t,onInstalled:d})]})}const Y={dev:{zh:"研发工具",en:"Developer",order:1},cloud:{zh:"云与部署",en:"Cloud",order:2},data:{zh:"数据后端",en:"Data",order:3},commerce:{zh:"商业支付",en:"Commerce",order:4},social:{zh:"社交通讯",en:"Social",order:5},content:{zh:"内容创作",en:"Content",order:6}};function ue({state:s,locale:t}){return s==="ready"?e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold text-[var(--th-ok)]",style:{background:"color-mix(in oklab, var(--th-ok) 12%, transparent)"},children:[e.jsx(K,{size:10}),a(t,"已登录","Signed in")]}):s==="installed_not_auth"?e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold text-amber-600 dark:text-amber-400",style:{background:"color-mix(in oklab, #f59e0b 14%, transparent)"},children:[e.jsx(ie,{size:10}),a(t,"待登录","Sign-in needed")]}):s==="not_installed"?e.jsx("span",{className:"inline-flex items-center gap-1 rounded-full border border-edge bg-inset/60 px-2 py-0.5 text-[10px] font-medium text-fg-5",children:a(t,"未安装","Not installed")}):e.jsx("span",{className:"inline-flex items-center gap-1 rounded-full border border-edge bg-inset/60 px-2 py-0.5 text-[10px] font-medium text-fg-5",children:"..."})}function he({chunks:s,running:t,emptyHint:n}){const i=o.useRef(null);o.useEffect(()=>{i.current&&(i.current.scrollTop=i.current.scrollHeight)},[s.length]);const l=s.join("");return e.jsx("div",{ref:i,className:"relative h-56 overflow-auto rounded-xl border border-edge/60 bg-[#0b0f16] p-3 font-mono text-[11.5px] leading-[1.55] text-[#cdd6f4] scrollbar-thin",style:{boxShadow:"0 1px 0 rgba(255,255,255,0.03) inset"},children:l?e.jsx("pre",{className:"whitespace-pre-wrap break-words",children:l}):e.jsx("div",{className:"flex h-full items-center justify-center text-[#6c7086]",children:t?e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(U,{})," ",n||"Starting…"]}):n||"No output yet"})})}function Be({cli:s,locale:t,onInstalled:n}){const[i,l]=o.useState([]),[c,d]=o.useState(!1),[u,h]=o.useState(null),[p,b]=o.useState(null),[k,x]=o.useState(null),v=o.useRef(null),f=o.useCallback(()=>{try{v.current?.close()}catch{}v.current=null},[]);o.useEffect(()=>f,[f]);const C=o.useCallback(async()=>{l([]),b(null),x(null),d(!0);try{const w=await $.startCliInstall(s.id);if(!w.ok||!w.sessionId)throw new Error(w.error||"start failed");h(w.sessionId);const z=new EventSource(`/api/extensions/cli/auth/stream?sessionId=${encodeURIComponent(w.sessionId)}`);v.current=z,z.onmessage=E=>{try{const L=JSON.parse(E.data);L.type==="output"?l(j=>j.length>400?[...j.slice(-400),L.chunk]:[...j,L.chunk]):L.type==="error"?b(L.message||"error"):L.type==="done"&&(d(!1),x(!!L.ok),f(),L.ok&&n())}catch{}},z.addEventListener("close",()=>{d(!1),f()}),z.onerror=()=>{c&&b(a(t,"连接中断","Stream disconnected"))}}catch(w){d(!1),b(w?.message||"failed to start install")}},[s.id,f,t,n,c]),A=o.useCallback(async()=>{if(u)try{await $.cancelCliAuth(u)}catch{}f(),d(!1)},[u,f]);if(!s.autoInstall)return null;const R=c||i.length>0||k!==null;return e.jsxs("div",{className:"space-y-3 rounded-lg border border-edge/70 bg-panel/60 p-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-[12px] text-fg-3",children:a(t,`通过 ${s.autoInstall.label} 直接在本机自动安装,无需复制命令。`,`Run the ${s.autoInstall.label} install locally — no copy-paste needed.`)}),c?e.jsx(I,{variant:"outline",size:"sm",onClick:A,children:a(t,"中止","Abort")}):e.jsx(I,{variant:"primary",size:"sm",onClick:C,disabled:k===!0,children:k===!0?a(t,"已安装","Installed"):k===!1?a(t,"重试安装","Retry install"):a(t,"一键安装","Auto-install")})]}),R&&e.jsx(he,{chunks:i,running:c,emptyHint:a(t,"安装进度将在此显示","Install output will appear here")}),p&&e.jsx("div",{className:"text-[12px] text-[var(--th-err)]",children:p}),k===!1&&!p&&e.jsx("div",{className:"text-[12px] text-[var(--th-err)]",children:a(t,"安装未成功,请查看上方输出排查。","Install did not complete — check the output above.")})]})}function Te({cliId:s,locale:t,hint:n,commands:i,onSignedIn:l,onCancel:c}){const[d,u]=o.useState(!1),[h,p]=o.useState(null),[b,k]=o.useState(null),x=o.useCallback(async()=>{u(!0),p(null),k(null);try{const v=await $.refreshCli(s);if(!v.ok){k(v.error||a(t,"检测失败","Detection failed"));return}if(v.status?.state==="ready"){l();return}const f=i.length;p(f>1?a(t,`尚未检测到登录。请依次完成上面 ${f} 步后再重试 —— 任一步漏掉都不会算授权成功。`,`Not signed in yet. Run all ${f} steps above in order — sign-in only counts as successful after every step completes.`):a(t,"尚未检测到登录,请先在终端完成上述命令。","Not signed in yet — finish the command above in your terminal first."))}catch(v){k(v?.message||"failed")}finally{u(!1)}},[s,t,l,i.length]);return e.jsxs("div",{className:"space-y-3",children:[n&&e.jsx("div",{className:"text-[12px] leading-relaxed text-fg-4",children:n}),e.jsx(pe,{commands:i,locale:t}),b&&e.jsx("div",{className:"text-[12px] text-[var(--th-err)]",children:b}),h&&!b&&e.jsx("div",{className:"text-[12px] text-fg-4",children:h}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(I,{variant:"primary",size:"sm",onClick:x,disabled:d,children:e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[d&&e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"animate-spin",style:{animationDuration:"0.9s"},"aria-hidden":"true",children:e.jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})}),e.jsx("span",{children:d?a(t,"检测中…","Checking…"):a(t,"重新检测状态","Re-check status")})]})}),e.jsx(I,{variant:"ghost",size:"sm",onClick:c,disabled:d,children:a(t,"关闭","Close")})]})]})}function De({cli:s,locale:t,onSignedIn:n,onCancel:i}){const[l,c]=o.useState([]),[d,u]=o.useState(!1),[h,p]=o.useState(null),[b,k]=o.useState(null),[x,v]=o.useState(null),f=o.useRef(null),C=o.useCallback(()=>{try{f.current?.close()}catch{}f.current=null},[]);o.useEffect(()=>C,[C]);const A=o.useCallback(async()=>{c([]),v(null),k(null),u(!0);try{const y=await $.startCliAuth(s.id);if(!y.ok||!y.sessionId)throw new Error(y.error||"start failed");p(y.sessionId);const N=new EventSource(`/api/extensions/cli/auth/stream?sessionId=${encodeURIComponent(y.sessionId)}`);f.current=N,N.onmessage=M=>{try{const P=JSON.parse(M.data);P.type==="output"?c(B=>B.length>400?[...B.slice(-400),P.chunk]:[...B,P.chunk]):P.type==="status"?k(P.status.state==="ready"?a(t,"已检测到登录成功","Sign-in detected"):a(t,"等待授权完成…","Waiting for authorization…")):P.type==="error"?v(P.message||"error"):P.type==="done"&&(u(!1),C(),P.ok&&n())}catch{}},N.addEventListener("close",()=>{u(!1),C()}),N.onerror=()=>{d&&v(a(t,"连接中断","Stream disconnected"))}}catch(y){u(!1),v(y?.message||"failed to start sign-in")}},[s.id,C,t,n,d]),R=o.useCallback(async()=>{if(h)try{await $.cancelCliAuth(h)}catch{}C(),u(!1),i()},[h,C,i]),[w,z]=o.useState({}),[E,L]=o.useState(!1),j=o.useCallback(async()=>{L(!0),v(null);try{const y=await $.applyCliToken(s.id,w);y.ok?n():v(y.error||a(t,"应用凭据失败","Failed to apply credentials"))}catch(y){v(y?.message||"failed")}finally{L(!1)}},[s.id,w,t,n]);if(s.auth.type==="oauth-web"){const y=t==="zh-CN"&&s.auth.loginHintZh||s.auth.loginHint,N=s.auth.manualLoginCommands;return N&&N.length>0?e.jsx(Te,{cliId:s.id,locale:t,hint:y,commands:N,onSignedIn:n,onCancel:i}):e.jsxs("div",{className:"space-y-3",children:[y&&e.jsx("div",{className:"text-[12px] leading-relaxed text-fg-4",children:y}),e.jsx(he,{chunks:l,running:d,emptyHint:a(t,"点击「开始登录」后将在此展示命令行输出",'Click "Start sign-in" to stream CLI output here')}),x&&e.jsx("div",{className:"text-[12px] text-[var(--th-err)]",children:x}),b&&!x&&e.jsx("div",{className:"text-[12px] text-[var(--th-ok)]",children:b}),e.jsx("div",{className:"flex items-center gap-2",children:d?e.jsx(I,{variant:"outline",size:"sm",onClick:R,children:a(t,"中止","Abort")}):e.jsxs(e.Fragment,{children:[e.jsx(I,{variant:"primary",size:"sm",onClick:A,children:a(t,"开始登录","Start sign-in")}),e.jsx(I,{variant:"ghost",size:"sm",onClick:i,children:a(t,"取消","Cancel")})]})})]})}if(s.auth.type==="token"){const y=t==="zh-CN"&&s.auth.loginHintZh||s.auth.loginHint;return e.jsxs("div",{className:"space-y-3",children:[y&&e.jsx("div",{className:"text-[12px] leading-relaxed text-fg-4",children:y}),e.jsx("div",{className:"space-y-2",children:(s.auth.tokenFields||[]).map(N=>e.jsxs("label",{className:"block text-[12px]",children:[e.jsxs("div",{className:"mb-1 text-fg-3",children:[t==="zh-CN"?N.labelZh:N.label,N.required&&e.jsx("span",{className:"ml-1 text-[var(--th-err)]",children:"*"})]}),e.jsx(O,{type:N.secret?"password":"text",value:w[N.key]||"",onChange:M=>z(P=>({...P,[N.key]:M.target.value})),placeholder:N.placeholder||"",className:"w-full"}),N.helpUrl&&e.jsxs("a",{className:"mt-1 inline-block text-[11px] text-primary hover:underline",href:N.helpUrl,target:"_blank",rel:"noreferrer",children:[a(t,"如何获取","How to get this")," ↗"]})]},N.key))}),x&&e.jsx("div",{className:"text-[12px] text-[var(--th-err)]",children:x}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(I,{variant:"primary",size:"sm",onClick:j,disabled:E,children:E?a(t,"验证中…","Verifying…"):a(t,"保存并验证","Save & verify")}),e.jsx(I,{variant:"ghost",size:"sm",onClick:i,children:a(t,"取消","Cancel")})]})]})}return null}function pe({commands:s,locale:t}){return e.jsx("div",{className:"space-y-2",children:s.map((n,i)=>e.jsxs("div",{className:"overflow-hidden rounded-lg border border-edge/70 bg-panel/60",children:[n.label&&e.jsx("div",{className:"flex items-center justify-between border-b border-edge/50 bg-panel-alt/40 px-3 py-1 text-[11px] font-medium text-fg-4",children:e.jsx("span",{children:n.label})}),e.jsxs("div",{className:"flex items-start gap-2 px-3 py-2 font-mono text-[12px] text-fg-2",children:[e.jsx("span",{className:"mt-[2px] select-none text-fg-5",children:"$"}),e.jsx("code",{className:"min-w-0 flex-1 break-all",children:n.cmd}),e.jsx("button",{type:"button",onClick:()=>{navigator.clipboard?.writeText(n.cmd)},className:"shrink-0 rounded px-2 py-0.5 text-[10.5px] text-fg-5 transition-colors hover:bg-panel-h hover:text-fg-2",title:a(t,"复制到剪贴板","Copy to clipboard"),children:a(t,"复制","Copy")})]})]},i))})}function He({cli:s,open:t,onClose:n,onChanged:i,locale:l}){const[c,d]=o.useState(!1),[u,h]=o.useState(!1),[p,b]=o.useState(null);o.useEffect(()=>{t||(d(!1),b(null))},[t]);const k=o.useMemo(()=>s?s.install[s.platform]||[]:[],[s]);if(!s)return null;const x=s.state!=="not_installed",v=s.state==="ready",f=async()=>{h(!0),b(null);try{const C=await $.logoutCli(s.id);C.ok||b(C.error||a(l,"登出失败","Logout failed")),i()}catch(C){b(C?.message||"failed")}finally{h(!1)}};return e.jsxs(V,{open:t,onClose:n,wide:!0,children:[e.jsx(J,{title:s.name,description:l==="zh-CN"?s.descriptionZh:s.description,onClose:n}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(T,{iconSlug:s.iconSlug,iconUrl:s.iconUrl,name:s.name,size:44}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[13px] font-semibold text-fg",children:[s.name,s.homepage&&e.jsx("a",{href:s.homepage,target:"_blank",rel:"noreferrer",className:"text-fg-5 hover:text-primary",children:e.jsx(G,{})})]}),e.jsxs("div",{className:"mt-0.5 flex items-center gap-2 text-[11.5px] text-fg-4",children:[ue({state:s.state,locale:l}),s.version&&e.jsxs("span",{className:"font-mono text-fg-5",children:["v",s.version]}),v&&s.authDetail&&e.jsxs("span",{className:"truncate text-fg-5",children:["· ",s.authDetail]})]})]})]}),!x&&e.jsxs("section",{className:"space-y-3",children:[e.jsx("div",{className:"text-[12px] font-semibold text-fg-3",children:a(l,"安装","Install")}),s.autoInstall&&e.jsx(Be,{cli:s,locale:l,onInstalled:i}),e.jsx("div",{className:"text-[11.5px] leading-relaxed text-fg-5",children:s.autoInstall?a(l,"或手动复制命令到终端执行。","Or copy a command below and run it in your terminal."):a(l,"复制下面的命令到终端运行。我们不自动代为安装 — 包管理器往往需要 sudo 或交互式确认。","Copy a command below and run it in your terminal. We don't auto-install — package managers often need sudo or interactive confirmation.")}),k.length>0?e.jsx(pe,{commands:k,locale:l}):e.jsx("div",{className:"text-[12px] text-fg-5",children:a(l,"请查看官方文档","Check the official installation docs")}),s.install.docs&&e.jsxs("a",{href:s.install.docs,target:"_blank",rel:"noreferrer",className:"inline-flex items-center gap-1 text-[11.5px] text-primary hover:underline",children:[a(l,"查看安装文档","Installation docs")," ↗"]}),e.jsx("div",{className:"pt-2",children:e.jsx(I,{variant:"outline",size:"sm",onClick:i,children:a(l,"我已安装,重新检测","I've installed, re-check")})})]}),x&&s.auth.type!=="none"&&e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-[12px] font-semibold text-fg-3",children:a(l,"登录","Sign in")}),v&&!c&&e.jsx(I,{variant:"ghost",size:"sm",onClick:f,disabled:u,children:u?a(l,"登出中…","Signing out…"):a(l,"登出","Sign out")})]}),p&&e.jsx("div",{className:"text-[11.5px] text-[var(--th-err)]",children:p}),v&&!c?e.jsxs("div",{className:"rounded-lg border border-edge/70 bg-panel/60 p-3 text-[12px] text-fg-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{size:12}),e.jsx("span",{children:a(l,"你已经登录,命令行工具可直接使用。","Already signed in — the CLI is ready to use.")})]}),e.jsx("div",{className:"mt-2",children:e.jsx(I,{variant:"outline",size:"sm",onClick:()=>d(!0),children:a(l,"重新登录","Re-authenticate")})})]}):e.jsx(De,{cli:s,locale:l,onSignedIn:()=>{d(!1),i()},onCancel:()=>d(!1)})]}),x&&s.auth.type==="none"&&e.jsx("section",{className:"rounded-lg border border-edge/70 bg-panel/60 p-3 text-[12px] text-fg-3",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{size:12}),e.jsx("span",{children:a(l,"无需授权 — 可直接使用。","No authentication required — ready to use.")})]})})]})]})}function Ge({item:s,onClick:t,locale:n,animationDelay:i}){return e.jsx("button",{type:"button",onClick:t,className:"animate-in-up group relative flex min-h-[112px] w-full flex-col overflow-hidden rounded-lg border border-[var(--edge-subtle)] bg-[var(--surface-2)] p-4 text-left transition-[background,border-color] duration-200 hover:border-[var(--edge-default)] hover:bg-[var(--surface-3)] focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--brand-glow-a)]",style:{animationDelay:i},children:e.jsxs("div",{className:"relative flex items-start gap-3",children:[e.jsx(T,{iconSlug:s.iconSlug,iconUrl:s.iconUrl,name:s.name,size:36}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("div",{className:"truncate text-[13px] font-semibold text-fg",children:s.name}),ue({state:s.state,locale:n})]}),e.jsxs("div",{className:"mt-0.5 truncate text-[11.5px] text-fg-5",children:[s.version?e.jsxs("span",{className:"font-mono",children:["v",s.version]}):null,s.version&&s.authDetail?" · ":null,s.authDetail]}),e.jsx("div",{className:"mt-1 truncate text-[11.5px] text-fg-4",children:n==="zh-CN"?s.descriptionZh:s.description})]})]})})}function Ze({item:s,onClick:t,locale:n,animationDelay:i}){const l=s.state==="not_installed"?a(n,"安装","Install"):s.state==="installed_not_auth"?a(n,"登录","Sign in"):a(n,"查看","Details");return e.jsxs("button",{type:"button",onClick:t,className:"animate-in-up group relative flex min-h-[112px] w-full flex-col overflow-hidden rounded-lg border border-[var(--edge-subtle)] bg-[var(--surface-2)] p-4 text-left transition-[background,border-color] duration-200 hover:border-[var(--edge-default)] hover:bg-[var(--surface-3)] focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--brand-glow-a)]",style:{animationDelay:i},children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(T,{iconSlug:s.iconSlug,iconUrl:s.iconUrl,name:s.name,size:32}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate text-[13px] font-semibold text-fg",children:s.name}),s.homepage&&e.jsx("a",{href:s.homepage,target:"_blank",rel:"noreferrer",onClick:c=>c.stopPropagation(),className:"text-fg-5 transition-colors hover:text-primary",children:e.jsx(G,{})})]}),e.jsx("div",{className:"mt-0.5 truncate text-[11.5px] text-fg-4",children:n==="zh-CN"?s.descriptionZh:s.description})]})]}),e.jsxs("div",{className:"mt-auto pt-3 flex items-center justify-between",children:[e.jsx("span",{className:"text-[11px] text-fg-5",children:s.auth.type==="oauth-web"?a(n,"浏览器授权","OAuth"):s.auth.type==="token"?a(n,"Token","Token"):a(n,"免配置","No auth")}),e.jsx("span",{className:"inline-flex items-center gap-1 rounded-md border border-[var(--edge-subtle)] bg-transparent px-2.5 py-1 text-[11px] font-semibold text-fg-3 transition-colors group-hover:border-[var(--edge-default)] group-hover:text-fg",children:l})]})]})}function me({locale:s,scope:t}){const{data:n,loading:i,refresh:l}=ee("pikiloom:cli:catalog",async()=>{const x=await $.getCliCatalog();if(!x.ok)throw new Error(x.error||"failed");return x.items||[]},[]),[c,d]=o.useState(null),u=o.useMemo(()=>{const x=n||[];return x},[n,t]),h=c&&u.find(x=>x.id===c)||null,p=u.filter(x=>x.state==="ready"),b=u.filter(x=>x.state!=="ready"),k=o.useMemo(()=>{const x=new Map;for(const v of b){const f=v.category;x.has(f)||x.set(f,[]),x.get(f).push(v)}return[...x.entries()].sort(([v],[f])=>(Y[v]?.order??99)-(Y[f]?.order??99))},[b]);return e.jsxs("section",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(X,{children:a(s,"CLI 工具","CLI Tools")}),e.jsxs("div",{className:"flex items-center gap-3 text-[11px] text-fg-5",children:[e.jsxs("span",{children:[p.length," ",a(s,"已登录","signed in")," · ",b.length," ",a(s,"可用","available")]}),e.jsx("button",{type:"button",onClick:()=>{l()},className:"rounded px-2 py-0.5 text-fg-5 transition-colors hover:bg-panel-h hover:text-fg-2",children:i?a(s,"刷新中…","Refreshing…"):a(s,"刷新","Refresh")})]})]}),t==="workspace"&&e.jsx("div",{className:"rounded-lg border border-edge/60 bg-inset/40 px-3 py-2 text-[11.5px] text-fg-4",children:a(s,"CLI 工具安装于机器层面,项目视图下同样可见。","CLI tools are installed machine-wide and are shown here for convenience.")}),p.length>0&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px] font-semibold text-fg-3",children:[e.jsx("span",{className:"inline-block h-1.5 w-1.5 rounded-full bg-[var(--th-ok)]"}),a(s,"已登录","Signed in")]}),e.jsx("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3",children:p.map((x,v)=>e.jsx(Ge,{item:x,locale:s,animationDelay:`${Math.min(v,12)*30}ms`,onClick:()=>d(x.id)},x.id))})]}),b.length>0&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px] font-semibold text-fg-3",children:[e.jsx("span",{className:"inline-block h-1.5 w-1.5 rounded-full bg-fg-5/50"}),a(s,"推荐工具","Available")]}),k.map(([x,v])=>e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-[10.5px] font-medium uppercase tracking-[0.06em] text-fg-5",children:s==="zh-CN"?Y[x]?.zh||x:Y[x]?.en||x}),e.jsx("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3",children:v.map((f,C)=>e.jsx(Ze,{item:f,locale:s,animationDelay:`${Math.min(C,12)*30}ms`,onClick:()=>d(f.id)},f.id))})]},x))]}),!i&&u.length===0&&e.jsx(ne,{title:a(s,"暂无可用 CLI","No CLI tools available"),subtitle:a(s,"稍后再试,或重启一下服务。","Try again later, or restart the service.")}),e.jsx(He,{cli:h,open:!!h,onClose:()=>d(null),onChanged:()=>{l()},locale:s})]})}function fe({active:s,onChange:t,locale:n,counts:i}){const l=[{id:"mcp",labelZh:"MCP 服务",labelEn:"MCP",icon:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("circle",{cx:"12",cy:"12",r:"3"}),e.jsx("circle",{cx:"4",cy:"5",r:"1.6"}),e.jsx("circle",{cx:"20",cy:"5",r:"1.6"}),e.jsx("circle",{cx:"4",cy:"19",r:"1.6"}),e.jsx("circle",{cx:"20",cy:"19",r:"1.6"}),e.jsx("path",{d:"M6 6 l4 4 M18 6 l-4 4 M6 18 l4 -4 M18 18 l-4 -4"})]})},{id:"cli",labelZh:"命令行",labelEn:"CLI",icon:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M4 17 l5 -5 -5 -5"}),e.jsx("path",{d:"M12 19 h8"})]})},{id:"skill",labelZh:"技能包",labelEn:"Skills",icon:e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:e.jsx("path",{d:"M12 2 l3 7 h7 l-5.5 4.5 2 7.5 L12 17 l-6.5 4 2 -7.5 L2 9 h7 z"})})}];return e.jsx(ge,{className:"w-fit bg-panel/80 backdrop-blur",children:l.map(c=>e.jsxs(ve,{active:s===c.id,onClick:()=>t(c.id),className:"gap-1.5 px-3.5",children:[e.jsx("span",{className:"shrink-0",children:c.icon}),e.jsx("span",{children:n==="zh-CN"?c.labelZh:c.labelEn}),i?.[c.id]!==void 0&&e.jsx("span",{className:H("ml-1 inline-flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-semibold",s===c.id?"bg-primary/12 text-primary":"bg-inset/70 text-fg-5"),children:i[c.id]})]},c.id))})}function Je({onOpenBrowserSetup:s}){const t=D(u=>u.locale),i=D(u=>u.state)?.config?.workdir||"",[l,c]=o.useState(()=>{try{const u=localStorage.getItem("pikiloom:extensions:tab");return u==="mcp"||u==="cli"||u==="skill"?u:"mcp"}catch{return"mcp"}}),d=o.useCallback(u=>{c(u);try{localStorage.setItem("pikiloom:extensions:tab",u)}catch{}},[]);return e.jsxs("div",{className:"animate-in space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-4",children:[e.jsx("div",{className:"space-y-1",children:e.jsx("div",{className:"text-[13px] leading-relaxed text-fg-4",children:a(t,"管理一次授权即可全局复用的服务与工具。项目专属的扩展请在工作台侧栏配置。","One-time authorization, use everywhere. Project-specific extensions live in the Workbench sidebar.")})}),e.jsx(fe,{active:l,onChange:d,locale:t})]}),e.jsxs("div",{className:"animate-in-fade",children:[l==="mcp"&&e.jsx("div",{className:"space-y-7",children:e.jsx(de,{scope:"global",workdir:i,locale:t,onOpenBrowserSetup:s})}),l==="cli"&&e.jsx(me,{locale:t,scope:"global"}),l==="skill"&&e.jsx(xe,{scope:"global",workdir:i,locale:t})]},l)]})}function Ye({workdir:s}){const t=D(c=>c.locale),[n,i]=o.useState(()=>{try{const c=localStorage.getItem("pikiloom:extensions-ws:tab");return c==="mcp"||c==="cli"||c==="skill"?c:"mcp"}catch{return"mcp"}}),l=o.useCallback(c=>{i(c);try{localStorage.setItem("pikiloom:extensions-ws:tab",c)}catch{}},[]);return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-3",children:[e.jsx("div",{className:"text-[13px] leading-relaxed text-fg-4",children:a(t,"仅对当前工作区生效 — 依赖项目目录的本地服务和专属技能包。","Scoped to this workspace — local services that depend on project context and project-specific skill packs.")}),e.jsx(fe,{active:n,onChange:l,locale:t})]}),e.jsxs("div",{className:"animate-in-fade",children:[n==="mcp"&&e.jsx(de,{scope:"workspace",workdir:s,locale:t}),n==="cli"&&e.jsx(me,{locale:t,scope:"workspace"}),n==="skill"&&e.jsx(xe,{scope:"workspace",workdir:s,locale:t})]},n)]})}export{Je as ExtensionsTab,Ye as WorkspaceExtensionsBody};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as f,j as l}from"./react-vendor-C7Sl8SE7.js";import{u as m,R as C,z as D,F as u,B as x,G as A,m as w,S as L}from"./index-
|
|
1
|
+
import{r as f,j as l}from"./react-vendor-C7Sl8SE7.js";import{u as m,R as C,z as D,F as u,B as x,G as A,m as w,S as L}from"./index-Dp_KlJM9.js";import"./router-DHISdpPk.js";function v(t){return t==="zh-CN"?{status:"状态",summary:"接入摘要",loading:"加载中",chats:"个 chat",notConnected:"未接入",configuring:"配置中",connected:"已接入",failed:"配置异常",configure:"去配置",continueSetup:"继续配置",viewSettings:"查看设置",noWeixin:"尚未登录微信账号",noTelegram:"未配置 Bot Token",noFeishu:"未配置 App ID 与应用凭证",noSlack:"未配置 Bot Token 与 App-Level Token",noDiscord:"未配置 Bot Token",noDingtalk:"未配置 AppKey/AppSecret",noWeCom:"未配置智能机器人 Bot ID 与 Secret",pendingValidation:"凭证已保存,等待验证。",connectedReady:"机器人已可正常接收消息。",validationFailed:"校验失败,请检查凭证或网络。",accountLinked:"已绑定账号",tokenSaved:"Token 已保存",appCredentialsSaved:"应用凭证已保存",allowedChats:"允许",notConnectedDetail:"尚未配置账号与接入凭证。"}:{status:"Status",summary:"Summary",loading:"Loading",chats:"chats",notConnected:"Not connected",configuring:"Configuring",connected:"Connected",failed:"Needs attention",configure:"Configure",continueSetup:"Continue setup",viewSettings:"View settings",noWeixin:"Weixin account not connected yet",noTelegram:"Bot token not configured",noFeishu:"App ID and credentials not configured",noSlack:"Bot Token and App-Level Token not configured",noDiscord:"Bot Token not configured",noDingtalk:"AppKey / AppSecret not configured",noWeCom:"Smart Bot ID and Secret not configured",pendingValidation:"Credentials are saved and waiting for validation.",connectedReady:"This channel can receive messages.",validationFailed:"Validation failed. Check credentials or network.",accountLinked:"Account linked",tokenSaved:"Token saved",appCredentialsSaved:"Credentials saved",allowedChats:"Allows",notConnectedDetail:"Account and access credentials have not been configured yet."}}function c(t,e=4,n=4){const a=t.trim();return a?a.length<=e+n+3?a:`${a.slice(0,e)}...${a.slice(-n)}`:""}function B(t){return String(t||"").split(/[\n,;]/).map(e=>e.trim()).filter(Boolean).length}function r(t,e){return String(t?.[e]||"").trim()}function T(t,e){if(!t)return e;try{return new URL(t).host||t}catch{return t}}function $(t,e,n){if(t==="weixin"){const i=r(e,"weixinAccountId"),o=r(e,"weixinBaseUrl");return i?o?`${c(i)} · ${T(o,o)}`:`${n.accountLinked} ${c(i)}`:n.noWeixin}if(t==="telegram"){const i=r(e,"telegramBotToken"),o=B(r(e,"telegramAllowedChatIds"));return i?o>0?`${n.tokenSaved} · ${n.allowedChats} ${o} ${n.chats}`:n.tokenSaved:n.noTelegram}if(t==="feishu"){const i=r(e,"feishuAppId"),o=r(e,"feishuAppSecret");return!i||!o?n.noFeishu:`App ID ${c(i)} · ${n.appCredentialsSaved}`}if(t==="slack"){const i=r(e,"slackBotToken"),o=r(e,"slackAppToken");return!i||!o?n.noSlack:`Bot ${c(i,6,4)} · App ${c(o,6,4)}`}if(t==="discord"){const i=r(e,"discordBotToken");return i?`${n.tokenSaved} · ${c(i,6,4)}`:n.noDiscord}if(t==="dingtalk"){const i=r(e,"dingtalkClientId"),o=r(e,"dingtalkClientSecret");return!i||!o?n.noDingtalk:`AppKey ${c(i,4,4)} · ${n.appCredentialsSaved}`}const a=r(e,"wecomBotId"),d=r(e,"wecomBotSecret");return!a||!d?n.noWeCom:`Bot ${c(a,4,4)} · ${n.appCredentialsSaved}`}function E(t,e){return!t||!t.configured?{statusLabel:e.notConnected,statusVariant:"muted",statusDescription:t?.detail||e.notConnectedDetail,actionLabel:e.configure}:t.ready?{statusLabel:e.connected,statusVariant:"ok",statusDescription:t.detail||e.connectedReady,actionLabel:e.viewSettings}:D(t)?{statusLabel:e.configuring,statusVariant:"accent",statusDescription:t.detail||e.pendingValidation,actionLabel:e.continueSetup}:{statusLabel:e.failed,statusVariant:"warn",statusDescription:t.detail||e.validationFailed,actionLabel:e.continueSetup}}function I(t,e){if(e)return"running";switch(t){case"ok":return"ok";case"warn":return"warn";case"accent":return"info";default:return"idle"}}function Z({meta:t}){return l.jsxs(u,{children:[l.jsx(u.Lead,{icon:l.jsx(x,{brand:t.key,size:32,className:"rounded-md"}),iconWrap:!1,title:t.title,subtitle:t.subtitle}),l.jsx(u.Status,{children:l.jsx(A,{state:I(t.statusVariant,t.loading),label:t.statusLabel})}),l.jsx(u.Field,{children:t.summary}),l.jsx(u.Action,{children:l.jsxs(w,{tone:t.channel?.ready?"secondary":"primary",size:"sm",onClick:t.onAction,disabled:t.actionDisabled,children:[t.loading&&l.jsx(L,{className:"h-3 w-3"}),t.actionLabel]})}),t.statusDescription&&t.statusDescription!==t.statusLabel&&l.jsx(u.Description,{children:t.statusDescription})]})}const j=[{key:"weixin",titleZh:"微信",titleEn:"Weixin",subtitleZh:"二维码登录与账号接入",subtitleEn:"QR login and account routing",actionProp:"onOpenWeixin"},{key:"telegram",titleZh:"Telegram",titleEn:"Telegram",subtitleZh:"Bot Token 与 chat allowlist",subtitleEn:"Bot token and chat allowlist",actionProp:"onOpenTelegram"},{key:"feishu",titleZh:"飞书",titleEn:"Lark / Feishu",subtitleZh:"应用凭证与机器人身份",subtitleEn:"App credentials and bot identity",actionProp:"onOpenFeishu"},{key:"slack",titleZh:"Slack",titleEn:"Slack",subtitleZh:"Socket Mode (xoxb / xapp)",subtitleEn:"Socket Mode (xoxb / xapp)",actionProp:"onOpenSlack"},{key:"discord",titleZh:"Discord",titleEn:"Discord",subtitleZh:"Gateway 长连接 (需开启 Message Content Intent)",subtitleEn:"Gateway WebSocket (requires Message Content Intent)",actionProp:"onOpenDiscord"},{key:"dingtalk",titleZh:"钉钉",titleEn:"DingTalk",subtitleZh:"Stream 长连接 (AppKey / AppSecret)",subtitleEn:"Stream Mode (AppKey / AppSecret)",actionProp:"onOpenDingtalk"},{key:"wecom",titleZh:"企业微信",titleEn:"WeCom",subtitleZh:"智能机器人 WebSocket (Bot ID / Secret)",subtitleEn:"Smart Bot WebSocket (Bot ID / Secret)",actionProp:"onOpenWeCom"}];function P(t){const e=m(s=>s.state),n=m(s=>s.locale),a=v(n),d=!e,i=e?.setupState?.channels||[],o=e?.config||{},S=f.useMemo(()=>j.map(s=>{const p=i.find(b=>b.channel===s.key)||null,k=n==="zh-CN"?s.titleZh:s.titleEn,g=n==="zh-CN"?s.subtitleZh:s.subtitleEn,h=t[s.actionProp];return d?{key:s.key,title:k,subtitle:g,channel:null,loading:!0,summary:a.loading,summaryLabel:a.summary,statusLabel:a.loading,statusVariant:"muted",statusDescription:a.loading,actionLabel:a.loading,actionDisabled:!0,onAction:h}:{key:s.key,title:k,subtitle:g,channel:p,summary:$(s.key,o,a),summaryLabel:a.summary,...E(p,a),actionDisabled:!1,onAction:h}}),[i,o,a,d,n,t]);return l.jsx("div",{className:"animate-in",children:l.jsx(C,{children:S.map(s=>l.jsx(Z,{meta:s},s.key))})})}export{P as IMAccessTab};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as c,a as x,j as e}from"./react-vendor-C7Sl8SE7.js";import{c as m,m as u}from"./index-
|
|
1
|
+
import{r as c,a as x,j as e}from"./react-vendor-C7Sl8SE7.js";import{c as m,m as u}from"./index-Dp_KlJM9.js";const f={sm:"max-w-[480px]",md:"max-w-[640px]",lg:"max-w-[840px]"};function p({open:s,onClose:t,size:r,wide:n,panelStyle:i,children:o}){if(c.useEffect(()=>{if(!s)return;const a=d=>{d.key==="Escape"&&t()};return document.addEventListener("keydown",a),()=>document.removeEventListener("keydown",a)},[s,t]),!s||typeof document>"u")return null;const l=r??(n?"lg":"sm");return x.createPortal(e.jsxs("div",{className:"fixed inset-0 z-100 flex items-center justify-center p-4",children:[e.jsx("div",{className:"absolute inset-0 backdrop-blur-[8px] backdrop-saturate-125",style:{background:"color-mix(in oklab, var(--th-overlay) 78%, transparent)"},onClick:t}),e.jsx("div",{role:"dialog","aria-modal":"true",className:m("relative max-h-[min(88vh,860px)] w-full overflow-hidden rounded-xl border","border-[var(--edge-strong)] bg-[var(--surface-elev)]","shadow-[0_24px_64px_rgba(2,6,23,0.32)] animate-scale",f[l]),style:i,children:e.jsx("div",{className:"max-h-[inherit] overflow-y-auto p-6",children:o})})]}),document.body)}function g({title:s,description:t,onClose:r}){return e.jsxs("div",{className:"mb-5 flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-base font-semibold tracking-tight text-fg",children:s}),t&&e.jsx("div",{className:"mt-1 text-sm leading-relaxed text-fg-4",children:t})]}),e.jsx(u,{tone:"ghost",shape:"icon",onClick:r,className:"-mr-1 -mt-1 shrink-0",children:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),e.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]})}export{p as M,g as a};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as a,j as e}from"./react-vendor-C7Sl8SE7.js";import{u as C,d as _,L,I as P,m as D,a as F,t as Q}from"./index-CJm8YsKX.js";import{M as O,a as H}from"./Modal-B4wc5184.js";import{D as se}from"./DirBrowser-DPNjooga.js";import"./router-DHISdpPk.js";const Y="https://ilinkai.weixin.qq.com";function V(i){return i instanceof Error&&(i.name==="AbortError"||/aborted/i.test(i.message))}function $(i,h){return i instanceof Error&&/timed out/i.test(i.message)?h("modal.requestTimeout"):h("modal.networkError")}function de({open:i,onClose:h}){const p=C(d=>d.state),o=C(d=>d.toast),r=C(d=>d.reloadUntil),s=C(d=>d.locale),t=a.useMemo(()=>_(s),[s]),[w,G]=a.useState(""),[j,v]=a.useState(""),[B,S]=a.useState(!1),[y,c]=a.useState(!1),[u,n]=a.useState(null),[m,N]=a.useState(!1),T=a.useRef(null),E=a.useRef(p);E.current=p,a.useEffect(()=>{i?(G(E.current?.config.telegramBotToken||""),v(E.current?.config.telegramAllowedChatIds||""),S(!1),n(null),N(!E.current?.config.telegramBotToken)):(T.current?.abort(),T.current=null,c(!1))},[i]),a.useEffect(()=>()=>{T.current?.abort(),T.current=null},[]);const k=async()=>{if(!w.trim()){o(t("modal.inputToken"),!1);return}T.current?.abort();const d=new AbortController;T.current=d,c(!0),n(null);let b=!1;try{const f=await F.validateTelegramConfig(w.trim(),j.trim(),{signal:d.signal,timeoutMs:12e3});if(!f.ok){n({ok:!1,text:"✗ "+(f.error||t("modal.validationFailed"))});return}const l=f.normalizedAllowedChatIds??j.trim();n({ok:!0,text:"✓ @"+(f.bot?.username||"bot")+(f.bot?.displayName?" ("+f.bot.displayName+")":"")});const U=new Set((p?.setupState?.channels||[]).filter(A=>(A.ready||A.configured)&&A.channel!=="telegram").map(A=>A.channel));if(U.add("telegram"),await F.saveConfig({telegramBotToken:w.trim(),telegramAllowedChatIds:l,channels:[...U]}),!await r(A=>{const z=A.setupState?.channels?.find(g=>g.channel==="telegram");return A.config.telegramBotToken===w.trim()&&(A.config.telegramAllowedChatIds||"")===l&&!!z?.ready},{attempts:10,intervalMs:350})){n({ok:!1,text:"✗ "+t("modal.refreshStateFailed")}),o(t("modal.refreshStateFailed"),!1);return}o(t("modal.tgSaved")),b=!0}catch(f){if(V(f))return;const l=$(f,t);n({ok:!1,text:"✗ "+l}),o(l,!1)}finally{T.current===d&&(T.current=null),c(!1),b&&h()}},x=()=>{T.current?.abort(),T.current=null,h()};return e.jsxs(O,{open:i,onClose:x,children:[e.jsx(H,{title:t("modal.configureTelegram"),onClose:x}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt",children:[e.jsxs("button",{type:"button",className:"flex w-full items-center justify-between px-3 py-2 text-xs font-medium text-fg-3 hover:text-fg-2 transition-colors",onClick:()=>N(!m),children:[e.jsx("span",{children:t("modal.tgGuideTitle")}),e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:`transition-transform ${m?"rotate-180":""}`,children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),m&&e.jsxs("div",{className:"space-y-1 border-t border-edge px-3 pb-3 pt-2 text-xs leading-relaxed text-fg-4",children:[e.jsx("p",{children:t("modal.tgGuideStep1")}),e.jsx("p",{children:t("modal.tgGuideStep2")}),e.jsx("p",{children:t("modal.tgGuideStep3")}),e.jsx("p",{children:t("modal.tgGuideStep4")}),e.jsx("p",{className:"mt-2 text-[11px] text-fg-5",children:t("modal.tgGuideIdTip")})]})]}),e.jsxs("div",{children:[e.jsx(L,{children:t("modal.botToken")}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(P,{type:B?"text":"password",className:"flex-1 font-mono text-xs",placeholder:t("modal.pasteToken"),value:w,onChange:d=>G(d.target.value)}),e.jsx(D,{variant:"ghost",size:"sm",className:"!w-[34px] !p-0",onClick:()=>S(!B),children:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",children:[e.jsx("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),e.jsx("circle",{cx:"12",cy:"12",r:"3"})]})})]})]}),u&&e.jsx("div",{className:"text-xs",style:{color:u.ok?"var(--th-ok)":"var(--th-err)"},children:u.text}),e.jsxs("div",{children:[e.jsxs(L,{children:[t("modal.allowedIds")," ",e.jsxs("span",{className:"text-fg-5",children:["(",t("modal.optional"),")"]})]}),e.jsx(P,{className:"font-mono text-xs",placeholder:t("modal.commaSep"),value:j,onChange:d=>v(d.target.value)})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[e.jsx(D,{variant:"ghost",onClick:x,children:t("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:y,onClick:k,children:t(y?"modal.validating":"modal.validateSave")})]})]})}const ee=JSON.stringify({scopes:{tenant:["im:message","im:message:send_as_bot","im:message.p2p_msg:readonly","im:message.group_at_msg:readonly","im:resource"],user:[]}},null,2);function ce({open:i,onClose:h}){const p=C(k=>k.state),o=C(k=>k.toast),r=C(k=>k.reloadUntil),s=C(k=>k.locale),t=a.useMemo(()=>_(s),[s]),[w,G]=a.useState(""),[j,v]=a.useState(""),[B,S]=a.useState(!1),[y,c]=a.useState(null),[u,n]=a.useState(!1),m=a.useRef(null),N=a.useRef(p);N.current=p,a.useEffect(()=>{i?(G(N.current?.config.feishuAppId||""),v(N.current?.config.feishuAppSecret||""),c(null),n(!N.current?.config.feishuAppId)):(m.current?.abort(),m.current=null,S(!1))},[i]),a.useEffect(()=>()=>{m.current?.abort(),m.current=null},[]);const T=async()=>{if(!w.trim()){o(t("modal.inputAppId"),!1);return}m.current?.abort();const k=new AbortController;m.current=k,S(!0),c(null);let x=!1;try{const d=await F.validateFeishuConfig(w.trim(),j.trim(),{signal:k.signal,timeoutMs:2e4});if(!d.ok){c({ok:!1,text:"✗ "+(d.error||t("modal.validationFailed"))});return}c({ok:!0,text:"✓ "+(d.app?.displayName||d.app?.appId||w.trim())});const b=new Set((p?.setupState?.channels||[]).filter(l=>(l.ready||l.configured)&&l.channel!=="feishu").map(l=>l.channel));if(b.add("feishu"),await F.saveConfig({feishuAppId:w.trim(),feishuAppSecret:j.trim(),channels:[...b]}),!await r(l=>{const U=l.setupState?.channels?.find(W=>W.channel==="feishu");return l.config.feishuAppId===w.trim()&&l.config.feishuAppSecret===j.trim()&&!!U?.ready},{attempts:10,intervalMs:350})){c({ok:!1,text:"✗ "+t("modal.refreshStateFailed")}),o(t("modal.refreshStateFailed"),!1);return}o(t("modal.feishuSaved")),x=!0}catch(d){if(V(d))return;const b=$(d,t);c({ok:!1,text:"✗ "+b}),o(b,!1)}finally{m.current===k&&(m.current=null),S(!1),x&&h()}},E=()=>{m.current?.abort(),m.current=null,h()};return e.jsxs(O,{open:i,onClose:E,children:[e.jsx(H,{title:t("modal.configureFeishu"),onClose:E}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt",children:[e.jsxs("button",{type:"button",className:"flex w-full items-center justify-between px-3 py-2 text-xs font-medium text-fg-3 hover:text-fg-2 transition-colors",onClick:()=>n(!u),children:[e.jsx("span",{children:t("modal.feishuGuideTitle")}),e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:`transition-transform ${u?"rotate-180":""}`,children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),u&&e.jsxs("div",{className:"space-y-1 border-t border-edge px-3 pb-3 pt-2 text-xs leading-relaxed text-fg-4",children:[e.jsx("p",{children:t("modal.feishuGuideStep1")}),e.jsx("p",{children:t("modal.feishuGuideStep2")}),e.jsx("p",{children:t("modal.feishuGuideStep3")}),e.jsx("p",{children:t("modal.feishuGuideStep4")}),e.jsxs("div",{className:"ml-3 mt-1",children:[e.jsxs("div",{className:"mb-1 flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-[11px] text-fg-5",children:t("modal.feishuGuidePerms")}),e.jsx(D,{variant:"outline",size:"sm",onClick:()=>{navigator.clipboard.writeText(ee),o(t("modal.feishuJsonCopied"))},children:t("modal.feishuCopyJson")})]}),e.jsx("pre",{className:"overflow-x-auto rounded-md border border-edge bg-inset p-2 font-mono text-[11px] leading-snug text-fg-3",children:ee}),e.jsx("p",{className:"mt-1 text-[11px] text-fg-5",children:t("modal.feishuJsonNote")})]}),e.jsx("p",{children:t("modal.feishuGuideStep5")}),e.jsx("p",{children:t("modal.feishuGuideStep6")}),e.jsx("p",{children:t("modal.feishuGuideStep7")}),e.jsx("p",{className:"mt-2 text-[11px] text-fg-5",children:t("modal.feishuGuideCardKitTip")})]})]}),e.jsxs("div",{children:[e.jsx(L,{children:t("modal.appId")}),e.jsx(P,{className:"font-mono text-xs",placeholder:t("modal.feishuPlaceholder"),value:w,onChange:k=>G(k.target.value)})]}),e.jsxs("div",{children:[e.jsx(L,{children:t("modal.appSecret")}),e.jsx(P,{type:"password",className:"font-mono text-xs",placeholder:t("modal.appSecret"),value:j,onChange:k=>v(k.target.value)})]}),y&&e.jsx("div",{className:"text-xs",style:{color:y.ok?"var(--th-ok)":"var(--th-err)"},children:y.text})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[e.jsx(D,{variant:"ghost",onClick:E,children:t("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:B,onClick:T,children:t(B?"modal.validating":"modal.validateSave")})]})]})}function ue({open:i,onClose:h}){const p=C(x=>x.state),o=C(x=>x.toast),r=C(x=>x.reloadUntil),s=C(x=>x.locale),t=a.useMemo(()=>_(s),[s]),[w,G]=a.useState(Y),[j,v]=a.useState(!1),[B,S]=a.useState(""),[y,c]=a.useState(""),[u,n]=a.useState(null),m=a.useRef(null),N=a.useRef(p);N.current=p,a.useEffect(()=>{i?(G(N.current?.config.weixinBaseUrl||Y),v(!1),S(""),c(""),n(null)):(m.current?.abort(),m.current=null,v(!1))},[i]),a.useEffect(()=>()=>{m.current?.abort(),m.current=null},[]);const T=()=>{m.current?.abort(),m.current=null,h()},E=a.useCallback(async(x,d,b)=>{for(;!x.signal.aborted;){const f=await F.waitWeixinLogin(d,b,{signal:x.signal,timeoutMs:45e3});if(!f.ok&&!f.connected)return n({ok:!1,text:"✗ "+(f.error||f.message||t("modal.validationFailed"))}),!1;if(f.qrcodeUrl&&S(f.qrcodeUrl),f.status==="scaned"?n({ok:!0,text:t("modal.weixinScanned")}):f.status==="expired"?n({ok:!0,text:t("modal.weixinQrRefreshed")}):f.connected||n({ok:!0,text:t("modal.weixinWaitingScan")}),!f.connected)continue;n({ok:!0,text:t("modal.weixinLoginSuccess")});const l=f.baseUrl||b,U=f.botToken||"",W=f.accountId||"",A=await F.validateWeixinConfig(l,U,W,{signal:x.signal,timeoutMs:12e3});if(!A.ok)return n({ok:!1,text:"✗ "+(A.error||t("modal.validationFailed"))}),!1;const z=A.normalizedBaseUrl||l,g=new Set((N.current?.setupState?.channels||[]).filter(R=>(R.ready||R.configured)&&R.channel!=="weixin").map(R=>R.channel));return g.add("weixin"),await F.saveConfig({weixinBaseUrl:z,weixinBotToken:U,weixinAccountId:W,channels:[...g]}),await r(R=>{const I=R.setupState?.channels?.find(M=>M.channel==="weixin");return R.config.weixinBaseUrl===z&&R.config.weixinBotToken===U&&R.config.weixinAccountId===W&&!!I?.ready},{attempts:12,intervalMs:350})?(o(t("modal.weixinSaved")),!0):(n({ok:!1,text:"✗ "+t("modal.refreshStateFailed")}),o(t("modal.refreshStateFailed"),!1),!1)}return!1},[r,t,o]),k=async()=>{if(!w.trim()){o(t("modal.inputWeixinBaseUrl"),!1);return}m.current?.abort();const x=new AbortController;m.current=x,v(!0),S(""),c(""),n(null);let d=!1;try{const b=await F.startWeixinLogin(w.trim(),{signal:x.signal,timeoutMs:12e3});if(!b.ok||!b.qrcodeUrl){n({ok:!1,text:"✗ "+(b.error||b.message||t("modal.validationFailed"))});return}S(b.qrcodeUrl),c(b.sessionKey),n({ok:!0,text:t("modal.weixinWaitingScan")}),d=await E(x,b.sessionKey,w.trim())}catch(b){if(V(b))return;const f=$(b,t);n({ok:!1,text:"✗ "+f}),o(f,!1)}finally{m.current===x&&(m.current=null),v(!1),d&&h()}};return e.jsxs(O,{open:i,onClose:T,children:[e.jsx(H,{title:t("modal.configureWeixin"),onClose:T}),e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"text-xs leading-relaxed text-fg-4",children:t("modal.weixinScanHint")}),e.jsxs("div",{children:[e.jsx(L,{children:t("modal.weixinBaseUrl")}),e.jsx(P,{className:"font-mono text-xs",value:w,onChange:x=>G(x.target.value),placeholder:Y}),e.jsx("div",{className:"mt-1 text-[11px] text-fg-5",children:t("modal.weixinDefaultBaseUrlHint")})]}),B&&e.jsxs("div",{className:"rounded-xl border border-edge bg-panel-alt p-4",children:[e.jsx("img",{src:B,alt:t("modal.weixinQrAlt"),className:"mx-auto h-56 w-56 rounded-lg bg-white p-3 object-contain"}),y&&e.jsx("div",{className:"mt-2 truncate text-center font-mono text-[10px] text-fg-5",children:y})]}),u&&e.jsx("div",{className:"text-xs",style:{color:u.ok?"var(--th-ok)":"var(--th-err)"},children:u.text})]}),e.jsxs("div",{className:"mt-6 flex justify-end gap-2",children:[e.jsx(D,{variant:"ghost",onClick:T,children:t("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:j,onClick:k,children:t(j?B?"modal.validating":"modal.weixinGeneratingQr":B?"modal.weixinRetry":"modal.weixinGenerateQr")})]})]})}function X({open:i,onClose:h,channel:p,titleKey:o,fields:r,validate:s,savedToastKey:t,guideTitleKey:w,guideStepKeys:G,guideOpenWhenEmpty:j=!0,validateTimeoutMs:v=12e3}){const B=C(g=>g.state),S=C(g=>g.toast),y=C(g=>g.reloadUntil),c=C(g=>g.locale),u=a.useMemo(()=>_(c),[c]),[n,m]=a.useState({}),[N,T]=a.useState({}),[E,k]=a.useState(!1),[x,d]=a.useState(null),[b,f]=a.useState(!1),l=a.useRef(null),U=a.useRef(B);U.current=B;const W=!!(G&&G.length);a.useEffect(()=>{if(i){const g=U.current?.config||{},K={};let R=!1;for(const I of r){const M=String(g[I.key]??"").trim();K[I.key]=M,!M&&I.required!==!1&&(R=!0)}m(K),T({}),d(null),f(W&&j&&R)}else l.current?.abort(),l.current=null,k(!1)},[i,r,W,j]),a.useEffect(()=>()=>{l.current?.abort(),l.current=null},[]);const A=()=>{l.current?.abort(),l.current=null,h()},z=async()=>{const g={};for(const I of r){const M=String(n[I.key]||"").trim();if(g[I.key]=M,I.required!==!1&&!M){S(u(I.labelKey)+": "+u("modal.fieldRequired"),!1);return}}l.current?.abort();const K=new AbortController;l.current=K,k(!0),d(null);let R=!1;try{const I=await s(g,{signal:K.signal,timeoutMs:v});if(!I.ok){d({ok:!1,text:"✗ "+(I.error||u("modal.validationFailed"))});return}d({ok:!0,text:"✓ "+(I.identity||u("modal.credentialsVerified"))});const M=new Set((B?.setupState?.channels||[]).filter(q=>(q.ready||q.configured)&&q.channel!==p).map(q=>q.channel));if(M.add(p),await F.saveConfig({...g,channels:[...M]}),!await y(q=>{const te=q.config||{};for(const J of r)if(String(te[J.key]||"").trim()!==g[J.key])return!1;return!!q.setupState?.channels?.find(J=>J.channel===p)?.ready},{attempts:10,intervalMs:350})){d({ok:!1,text:"✗ "+u("modal.refreshStateFailed")}),S(u("modal.refreshStateFailed"),!1);return}S(u(t)),R=!0}catch(I){if(V(I))return;const M=$(I,u);d({ok:!1,text:"✗ "+M}),S(M,!1)}finally{l.current===K&&(l.current=null),k(!1),R&&h()}};return e.jsxs(O,{open:i,onClose:A,children:[e.jsx(H,{title:u(o),onClose:A}),e.jsxs("div",{className:"space-y-4",children:[W&&w&&e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt",children:[e.jsxs("button",{type:"button",className:"flex w-full items-center justify-between px-3 py-2 text-xs font-medium text-fg-3 hover:text-fg-2 transition-colors",onClick:()=>f(!b),children:[e.jsx("span",{children:u(w)}),e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:`transition-transform ${b?"rotate-180":""}`,children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),b&&e.jsx("div",{className:"space-y-1 border-t border-edge px-3 pb-3 pt-2 text-xs leading-relaxed text-fg-4",children:G.map(g=>e.jsx("p",{children:u(g)},g))})]}),r.map(g=>{const K=g.key,R=!!N[K],I=g.password&&!R?"password":"text";return e.jsxs("div",{children:[e.jsxs(L,{children:[u(g.labelKey),g.required===!1&&e.jsxs(e.Fragment,{children:[" ",e.jsxs("span",{className:"text-fg-5",children:["(",u("modal.optional"),")"]})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(P,{type:I,className:"flex-1 font-mono text-xs",placeholder:g.placeholder?u(g.placeholder):"",value:n[K]||"",onChange:M=>m(Z=>({...Z,[K]:M.target.value}))}),g.password&&e.jsx(D,{variant:"ghost",size:"sm",className:"!w-[34px] !p-0",onClick:()=>T(M=>({...M,[K]:!M[K]})),children:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",children:[e.jsx("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),e.jsx("circle",{cx:"12",cy:"12",r:"3"})]})})]})]},K)}),x&&e.jsx("div",{className:"text-xs",style:{color:x.ok?"var(--th-ok)":"var(--th-err)"},children:x.text})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[e.jsx(D,{variant:"ghost",onClick:A,children:u("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:E,onClick:z,children:u(E?"modal.validating":"modal.validateSave")})]})]})}function me({open:i,onClose:h}){return e.jsx(X,{open:i,onClose:h,channel:"slack",titleKey:"modal.configureSlack",savedToastKey:"modal.slackSaved",guideTitleKey:"modal.slackGuideTitle",guideStepKeys:["modal.slackGuideStep1","modal.slackGuideStep2","modal.slackGuideStep3","modal.slackGuideStep4","modal.slackGuideStep5"],fields:[{key:"slackBotToken",labelKey:"modal.slackBotToken",password:!0,placeholder:"modal.slackBotTokenPlaceholder"},{key:"slackAppToken",labelKey:"modal.slackAppToken",password:!0,placeholder:"modal.slackAppTokenPlaceholder"}],validate:async(p,o)=>{const r=await F.validateSlackConfig(p.slackBotToken,p.slackAppToken,o),s=r.bot?.username?"@"+r.bot.username+(r.bot.team?" ("+r.bot.team+")":""):null;return{ok:r.ok,error:r.error,identity:s}}})}function xe({open:i,onClose:h}){return e.jsx(X,{open:i,onClose:h,channel:"discord",titleKey:"modal.configureDiscord",savedToastKey:"modal.discordSaved",guideTitleKey:"modal.discordGuideTitle",guideStepKeys:["modal.discordGuideStep1","modal.discordGuideStep2","modal.discordGuideStep3","modal.discordGuideStep4","modal.discordGuideStep5"],fields:[{key:"discordBotToken",labelKey:"modal.discordBotToken",password:!0,placeholder:"modal.discordBotTokenPlaceholder"}],validate:async(p,o)=>{const r=await F.validateDiscordConfig(p.discordBotToken,o),s=r.bot?.username?"@"+r.bot.username:null;return{ok:r.ok,error:r.error,identity:s}}})}function fe({open:i,onClose:h}){return e.jsx(X,{open:i,onClose:h,channel:"dingtalk",titleKey:"modal.configureDingtalk",savedToastKey:"modal.dingtalkSaved",guideTitleKey:"modal.dingtalkGuideTitle",guideStepKeys:["modal.dingtalkGuideStep1","modal.dingtalkGuideStep2","modal.dingtalkGuideStep3","modal.dingtalkGuideStep4","modal.dingtalkGuideStep5"],fields:[{key:"dingtalkClientId",labelKey:"modal.dingtalkClientId",placeholder:"modal.dingtalkClientIdPlaceholder"},{key:"dingtalkClientSecret",labelKey:"modal.dingtalkClientSecret",password:!0,placeholder:"modal.dingtalkClientSecretPlaceholder"}],validate:async(p,o)=>{const r=await F.validateDingtalkConfig(p.dingtalkClientId,p.dingtalkClientSecret,o),s=r.app?.clientId?r.app.clientId.length>12?r.app.clientId.slice(0,6)+"..."+r.app.clientId.slice(-4):r.app.clientId:null;return{ok:r.ok,error:r.error,identity:s}}})}function he({open:i,onClose:h}){return e.jsx(X,{open:i,onClose:h,channel:"wecom",titleKey:"modal.configureWeCom",savedToastKey:"modal.wecomSaved",guideTitleKey:"modal.wecomGuideTitle",guideStepKeys:["modal.wecomGuideStep1","modal.wecomGuideStep2","modal.wecomGuideStep3","modal.wecomGuideStep4","modal.wecomGuideNote"],fields:[{key:"wecomBotId",labelKey:"modal.wecomBotId",placeholder:"modal.wecomBotIdPlaceholder"},{key:"wecomBotSecret",labelKey:"modal.wecomBotSecret",password:!0,placeholder:"modal.wecomBotSecretPlaceholder"}],validate:async(p,o)=>{const r=await F.validateWecomConfig(p.wecomBotId,p.wecomBotSecret,o),s=r.bot?.botId?r.bot.botId:null;return{ok:r.ok,error:r.error,identity:s}}})}function pe({open:i,onClose:h}){const p=C(n=>n.state),o=C(n=>n.toast),r=C(n=>n.reload),s=C(n=>n.locale),t=a.useMemo(()=>_(s),[s]),w=p?.bot?.workdir||p?.runtimeWorkdir||"",[G,j]=a.useState(""),[v,B]=a.useState(!1),[S,y]=a.useState(0);a.useEffect(()=>{i&&(j(w),y(n=>n+1))},[i,w]);const c=a.useCallback(n=>{j(n)},[]),u=async()=>{const n=G.trim();if(!n){o(t("modal.selectDirFirst"),!1);return}B(!0);try{const m=await F.switchWorkdir(n);m.ok?(await r(),o(t("modal.switchedTo")+m.workdir),h()):o(m.error||t("modal.switchFailed"),!1)}catch{o(t("modal.switchFailed"),!1)}finally{B(!1)}};return e.jsx(O,{open:i,onClose:v?void 0:h,panelStyle:{width:"min(500px, calc(100vw - 2rem))",maxWidth:"min(500px, calc(100vw - 2rem))"},children:v?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 gap-4 animate-in",children:[e.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round",className:"animate-spin text-fg-3",style:{animationDuration:"1.2s"},children:[e.jsx("polyline",{points:"23 4 23 10 17 10"}),e.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"})]}),e.jsx("span",{className:"text-sm font-medium text-fg-3",children:t("modal.switching")}),e.jsx("span",{className:"text-xs text-fg-5 max-w-[280px] truncate",children:G})]}):e.jsxs(e.Fragment,{children:[e.jsx(H,{title:t("modal.switchWorkdir"),onClose:h}),e.jsx(se,{initialPath:w,onSelect:c,t},S),e.jsxs("div",{className:"flex justify-end gap-2 mt-4",children:[e.jsx(D,{variant:"ghost",onClick:h,children:t("modal.cancel")}),e.jsx(D,{variant:"primary",onClick:u,children:t("modal.selectDir")})]})]})})}function ge({open:i,onClose:h,onSaved:p}){const o=C(l=>l.toast),r=C(l=>l.locale),s=a.useMemo(()=>_(r),[r]),[t,w]=a.useState(null),[G,j]=a.useState(!1),[v,B]=a.useState(!1),[S,y]=a.useState(null);a.useEffect(()=>{i&&(j(!1),y(null),F.getBrowser().then(l=>{w(l),B(!!l.browser.enabled)}).catch(()=>w(null)))},[i]);const c=t?.browser,u=!!c?.enabled,n=!!c&&u!==v,m=c?.remoteCdpUrl||"",N=!!m&&v,T=c?.profileDir||"",E=s(N?"ext.browserRemote":"ext.profileDir"),k=N?m:T,x=!!c?.chromeInstalled&&!!c?.profileCreated,d=t?c?.enabled?N?s("ext.browserRemote"):x?s("ext.browserReady"):c?.chromeInstalled?s("ext.chromeInstalled"):s("ext.needsSetup"):s("ext.disabled"):s("status.loading"),b=t&&c?.enabled?N||x?"ok":c?.chromeInstalled?"warn":"err":"muted",f=async()=>{j(!0),y(null);let l=null;try{await F.saveConfig({browserEnabled:v}),l=await F.getBrowser(),w(l),p?.()}catch{y({ok:!1,text:"✗ "+s("ext.browserModeSaveFailed")}),o(s("ext.browserModeSaveFailed"),!1),j(!1);return}if(!v){y({ok:!0,text:"✓ "+s("ext.browserDisabledSaved")}),o(s("ext.browserDisabledSaved")),j(!1);return}if(l?.browser.remoteCdpUrl){y({ok:!0,text:"✓ "+s("ext.browserRemoteStep")}),o(s("ext.browserRemoteStep")),j(!1);return}try{const U=await F.setupBrowser();if(!U.ok){y({ok:!1,text:"✗ "+(U.error||s("ext.browserLaunchFailed"))}),o(U.error||s("ext.browserLaunchFailed"),!1);return}w(W=>W?{...W,browser:U.browser}:{browser:U.browser}),y({ok:!0,text:"✓ "+s("ext.browserEnabledLaunched")}),o(s("ext.browserEnabledLaunched")),p?.()}catch{y({ok:!1,text:"✗ "+s("ext.browserLaunchFailed")}),o(s("ext.browserLaunchFailed"),!1)}finally{j(!1)}};return e.jsxs(O,{open:i,onClose:h,children:[e.jsx(H,{title:s("ext.setupBrowser"),description:s("ext.setupBrowserDesc"),onClose:h}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Q,{variant:b,children:d}),c&&e.jsxs(e.Fragment,{children:[e.jsx(Q,{variant:u?"accent":"muted",children:s(u?"ext.enabled":"ext.disabled")}),n&&e.jsx(Q,{variant:"warn",children:s("ext.pendingModeChange")}),c.running&&e.jsxs(Q,{variant:"accent",children:[s("ext.browserOpen"),c.pid?` · PID ${c.pid}`:""]})]})]}),e.jsxs("div",{className:"mt-3",children:[e.jsx(L,{children:E}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(P,{className:"font-mono text-xs flex-1",value:k||"—",readOnly:!0,onClick:l=>l.target.select()}),e.jsx(D,{variant:"outline",size:"sm",disabled:!k,onClick:()=>{k&&(navigator.clipboard.writeText(k),o(s("ext.step2Copied")))},children:s("ext.copyPath")})]})]}),e.jsx("div",{className:"mt-3 text-xs text-fg-5",children:s(v?"ext.profileModeDesc":"ext.browserDescDisabled")}),c?.detail&&e.jsx("div",{className:"mt-2 text-xs text-fg-5",children:c.detail}),S&&e.jsx("div",{className:"mt-3 text-xs",style:{color:S.ok?"var(--th-ok)":"var(--th-err)"},children:S.text})]}),e.jsx("div",{className:"rounded-lg border border-edge bg-panel-alt p-4",children:e.jsxs("label",{className:"flex cursor-pointer items-start gap-3",children:[e.jsx("input",{type:"checkbox",checked:v,onChange:l=>B(l.target.checked),className:"mt-0.5 h-4 w-4 rounded border border-edge bg-inset"}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-fg-2 mb-1",children:s("ext.browserEnableToggle")}),e.jsx("div",{className:"text-xs text-fg-4",children:s("ext.browserEnableToggleDesc")})]})]})}),e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt p-4",children:[e.jsx("div",{className:"text-sm font-medium text-fg-2 mb-1",children:s(v?N?"ext.browserRemoteStep":"ext.step2Title":"ext.browserDisabledStepTitle")}),e.jsx("div",{className:"text-xs text-fg-4",children:s(v?N?"ext.browserRemoteStepDesc":"ext.step2Desc":"ext.browserDisabledHint")})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[e.jsx(D,{variant:"ghost",onClick:h,children:s("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:G,onClick:f,children:s(G?"ext.launching":v?N?"ext.saveBrowserRemote":"ext.enableAndLaunchBrowser":"ext.saveBrowserDisabled")})]})]})}export{ge as BrowserSetupModal,fe as DingtalkModal,xe as DiscordModal,ce as FeishuModal,me as SlackModal,de as TelegramModal,he as WeComModal,ue as WeixinModal,pe as WorkdirModal};
|
|
1
|
+
import{r as a,j as e}from"./react-vendor-C7Sl8SE7.js";import{u as C,d as _,L,I as P,m as D,a as F,t as Q}from"./index-Dp_KlJM9.js";import{M as O,a as H}from"./Modal-CzQbFS5c.js";import{D as se}from"./DirBrowser-BsHjGC5A.js";import"./router-DHISdpPk.js";const Y="https://ilinkai.weixin.qq.com";function V(i){return i instanceof Error&&(i.name==="AbortError"||/aborted/i.test(i.message))}function $(i,h){return i instanceof Error&&/timed out/i.test(i.message)?h("modal.requestTimeout"):h("modal.networkError")}function de({open:i,onClose:h}){const p=C(d=>d.state),o=C(d=>d.toast),r=C(d=>d.reloadUntil),s=C(d=>d.locale),t=a.useMemo(()=>_(s),[s]),[w,G]=a.useState(""),[j,v]=a.useState(""),[B,S]=a.useState(!1),[y,c]=a.useState(!1),[u,n]=a.useState(null),[m,N]=a.useState(!1),T=a.useRef(null),E=a.useRef(p);E.current=p,a.useEffect(()=>{i?(G(E.current?.config.telegramBotToken||""),v(E.current?.config.telegramAllowedChatIds||""),S(!1),n(null),N(!E.current?.config.telegramBotToken)):(T.current?.abort(),T.current=null,c(!1))},[i]),a.useEffect(()=>()=>{T.current?.abort(),T.current=null},[]);const k=async()=>{if(!w.trim()){o(t("modal.inputToken"),!1);return}T.current?.abort();const d=new AbortController;T.current=d,c(!0),n(null);let b=!1;try{const f=await F.validateTelegramConfig(w.trim(),j.trim(),{signal:d.signal,timeoutMs:12e3});if(!f.ok){n({ok:!1,text:"✗ "+(f.error||t("modal.validationFailed"))});return}const l=f.normalizedAllowedChatIds??j.trim();n({ok:!0,text:"✓ @"+(f.bot?.username||"bot")+(f.bot?.displayName?" ("+f.bot.displayName+")":"")});const U=new Set((p?.setupState?.channels||[]).filter(A=>(A.ready||A.configured)&&A.channel!=="telegram").map(A=>A.channel));if(U.add("telegram"),await F.saveConfig({telegramBotToken:w.trim(),telegramAllowedChatIds:l,channels:[...U]}),!await r(A=>{const z=A.setupState?.channels?.find(g=>g.channel==="telegram");return A.config.telegramBotToken===w.trim()&&(A.config.telegramAllowedChatIds||"")===l&&!!z?.ready},{attempts:10,intervalMs:350})){n({ok:!1,text:"✗ "+t("modal.refreshStateFailed")}),o(t("modal.refreshStateFailed"),!1);return}o(t("modal.tgSaved")),b=!0}catch(f){if(V(f))return;const l=$(f,t);n({ok:!1,text:"✗ "+l}),o(l,!1)}finally{T.current===d&&(T.current=null),c(!1),b&&h()}},x=()=>{T.current?.abort(),T.current=null,h()};return e.jsxs(O,{open:i,onClose:x,children:[e.jsx(H,{title:t("modal.configureTelegram"),onClose:x}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt",children:[e.jsxs("button",{type:"button",className:"flex w-full items-center justify-between px-3 py-2 text-xs font-medium text-fg-3 hover:text-fg-2 transition-colors",onClick:()=>N(!m),children:[e.jsx("span",{children:t("modal.tgGuideTitle")}),e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:`transition-transform ${m?"rotate-180":""}`,children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),m&&e.jsxs("div",{className:"space-y-1 border-t border-edge px-3 pb-3 pt-2 text-xs leading-relaxed text-fg-4",children:[e.jsx("p",{children:t("modal.tgGuideStep1")}),e.jsx("p",{children:t("modal.tgGuideStep2")}),e.jsx("p",{children:t("modal.tgGuideStep3")}),e.jsx("p",{children:t("modal.tgGuideStep4")}),e.jsx("p",{className:"mt-2 text-[11px] text-fg-5",children:t("modal.tgGuideIdTip")})]})]}),e.jsxs("div",{children:[e.jsx(L,{children:t("modal.botToken")}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(P,{type:B?"text":"password",className:"flex-1 font-mono text-xs",placeholder:t("modal.pasteToken"),value:w,onChange:d=>G(d.target.value)}),e.jsx(D,{variant:"ghost",size:"sm",className:"!w-[34px] !p-0",onClick:()=>S(!B),children:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",children:[e.jsx("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),e.jsx("circle",{cx:"12",cy:"12",r:"3"})]})})]})]}),u&&e.jsx("div",{className:"text-xs",style:{color:u.ok?"var(--th-ok)":"var(--th-err)"},children:u.text}),e.jsxs("div",{children:[e.jsxs(L,{children:[t("modal.allowedIds")," ",e.jsxs("span",{className:"text-fg-5",children:["(",t("modal.optional"),")"]})]}),e.jsx(P,{className:"font-mono text-xs",placeholder:t("modal.commaSep"),value:j,onChange:d=>v(d.target.value)})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[e.jsx(D,{variant:"ghost",onClick:x,children:t("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:y,onClick:k,children:t(y?"modal.validating":"modal.validateSave")})]})]})}const ee=JSON.stringify({scopes:{tenant:["im:message","im:message:send_as_bot","im:message.p2p_msg:readonly","im:message.group_at_msg:readonly","im:resource"],user:[]}},null,2);function ce({open:i,onClose:h}){const p=C(k=>k.state),o=C(k=>k.toast),r=C(k=>k.reloadUntil),s=C(k=>k.locale),t=a.useMemo(()=>_(s),[s]),[w,G]=a.useState(""),[j,v]=a.useState(""),[B,S]=a.useState(!1),[y,c]=a.useState(null),[u,n]=a.useState(!1),m=a.useRef(null),N=a.useRef(p);N.current=p,a.useEffect(()=>{i?(G(N.current?.config.feishuAppId||""),v(N.current?.config.feishuAppSecret||""),c(null),n(!N.current?.config.feishuAppId)):(m.current?.abort(),m.current=null,S(!1))},[i]),a.useEffect(()=>()=>{m.current?.abort(),m.current=null},[]);const T=async()=>{if(!w.trim()){o(t("modal.inputAppId"),!1);return}m.current?.abort();const k=new AbortController;m.current=k,S(!0),c(null);let x=!1;try{const d=await F.validateFeishuConfig(w.trim(),j.trim(),{signal:k.signal,timeoutMs:2e4});if(!d.ok){c({ok:!1,text:"✗ "+(d.error||t("modal.validationFailed"))});return}c({ok:!0,text:"✓ "+(d.app?.displayName||d.app?.appId||w.trim())});const b=new Set((p?.setupState?.channels||[]).filter(l=>(l.ready||l.configured)&&l.channel!=="feishu").map(l=>l.channel));if(b.add("feishu"),await F.saveConfig({feishuAppId:w.trim(),feishuAppSecret:j.trim(),channels:[...b]}),!await r(l=>{const U=l.setupState?.channels?.find(W=>W.channel==="feishu");return l.config.feishuAppId===w.trim()&&l.config.feishuAppSecret===j.trim()&&!!U?.ready},{attempts:10,intervalMs:350})){c({ok:!1,text:"✗ "+t("modal.refreshStateFailed")}),o(t("modal.refreshStateFailed"),!1);return}o(t("modal.feishuSaved")),x=!0}catch(d){if(V(d))return;const b=$(d,t);c({ok:!1,text:"✗ "+b}),o(b,!1)}finally{m.current===k&&(m.current=null),S(!1),x&&h()}},E=()=>{m.current?.abort(),m.current=null,h()};return e.jsxs(O,{open:i,onClose:E,children:[e.jsx(H,{title:t("modal.configureFeishu"),onClose:E}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt",children:[e.jsxs("button",{type:"button",className:"flex w-full items-center justify-between px-3 py-2 text-xs font-medium text-fg-3 hover:text-fg-2 transition-colors",onClick:()=>n(!u),children:[e.jsx("span",{children:t("modal.feishuGuideTitle")}),e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:`transition-transform ${u?"rotate-180":""}`,children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),u&&e.jsxs("div",{className:"space-y-1 border-t border-edge px-3 pb-3 pt-2 text-xs leading-relaxed text-fg-4",children:[e.jsx("p",{children:t("modal.feishuGuideStep1")}),e.jsx("p",{children:t("modal.feishuGuideStep2")}),e.jsx("p",{children:t("modal.feishuGuideStep3")}),e.jsx("p",{children:t("modal.feishuGuideStep4")}),e.jsxs("div",{className:"ml-3 mt-1",children:[e.jsxs("div",{className:"mb-1 flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-[11px] text-fg-5",children:t("modal.feishuGuidePerms")}),e.jsx(D,{variant:"outline",size:"sm",onClick:()=>{navigator.clipboard.writeText(ee),o(t("modal.feishuJsonCopied"))},children:t("modal.feishuCopyJson")})]}),e.jsx("pre",{className:"overflow-x-auto rounded-md border border-edge bg-inset p-2 font-mono text-[11px] leading-snug text-fg-3",children:ee}),e.jsx("p",{className:"mt-1 text-[11px] text-fg-5",children:t("modal.feishuJsonNote")})]}),e.jsx("p",{children:t("modal.feishuGuideStep5")}),e.jsx("p",{children:t("modal.feishuGuideStep6")}),e.jsx("p",{children:t("modal.feishuGuideStep7")}),e.jsx("p",{className:"mt-2 text-[11px] text-fg-5",children:t("modal.feishuGuideCardKitTip")})]})]}),e.jsxs("div",{children:[e.jsx(L,{children:t("modal.appId")}),e.jsx(P,{className:"font-mono text-xs",placeholder:t("modal.feishuPlaceholder"),value:w,onChange:k=>G(k.target.value)})]}),e.jsxs("div",{children:[e.jsx(L,{children:t("modal.appSecret")}),e.jsx(P,{type:"password",className:"font-mono text-xs",placeholder:t("modal.appSecret"),value:j,onChange:k=>v(k.target.value)})]}),y&&e.jsx("div",{className:"text-xs",style:{color:y.ok?"var(--th-ok)":"var(--th-err)"},children:y.text})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[e.jsx(D,{variant:"ghost",onClick:E,children:t("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:B,onClick:T,children:t(B?"modal.validating":"modal.validateSave")})]})]})}function ue({open:i,onClose:h}){const p=C(x=>x.state),o=C(x=>x.toast),r=C(x=>x.reloadUntil),s=C(x=>x.locale),t=a.useMemo(()=>_(s),[s]),[w,G]=a.useState(Y),[j,v]=a.useState(!1),[B,S]=a.useState(""),[y,c]=a.useState(""),[u,n]=a.useState(null),m=a.useRef(null),N=a.useRef(p);N.current=p,a.useEffect(()=>{i?(G(N.current?.config.weixinBaseUrl||Y),v(!1),S(""),c(""),n(null)):(m.current?.abort(),m.current=null,v(!1))},[i]),a.useEffect(()=>()=>{m.current?.abort(),m.current=null},[]);const T=()=>{m.current?.abort(),m.current=null,h()},E=a.useCallback(async(x,d,b)=>{for(;!x.signal.aborted;){const f=await F.waitWeixinLogin(d,b,{signal:x.signal,timeoutMs:45e3});if(!f.ok&&!f.connected)return n({ok:!1,text:"✗ "+(f.error||f.message||t("modal.validationFailed"))}),!1;if(f.qrcodeUrl&&S(f.qrcodeUrl),f.status==="scaned"?n({ok:!0,text:t("modal.weixinScanned")}):f.status==="expired"?n({ok:!0,text:t("modal.weixinQrRefreshed")}):f.connected||n({ok:!0,text:t("modal.weixinWaitingScan")}),!f.connected)continue;n({ok:!0,text:t("modal.weixinLoginSuccess")});const l=f.baseUrl||b,U=f.botToken||"",W=f.accountId||"",A=await F.validateWeixinConfig(l,U,W,{signal:x.signal,timeoutMs:12e3});if(!A.ok)return n({ok:!1,text:"✗ "+(A.error||t("modal.validationFailed"))}),!1;const z=A.normalizedBaseUrl||l,g=new Set((N.current?.setupState?.channels||[]).filter(R=>(R.ready||R.configured)&&R.channel!=="weixin").map(R=>R.channel));return g.add("weixin"),await F.saveConfig({weixinBaseUrl:z,weixinBotToken:U,weixinAccountId:W,channels:[...g]}),await r(R=>{const I=R.setupState?.channels?.find(M=>M.channel==="weixin");return R.config.weixinBaseUrl===z&&R.config.weixinBotToken===U&&R.config.weixinAccountId===W&&!!I?.ready},{attempts:12,intervalMs:350})?(o(t("modal.weixinSaved")),!0):(n({ok:!1,text:"✗ "+t("modal.refreshStateFailed")}),o(t("modal.refreshStateFailed"),!1),!1)}return!1},[r,t,o]),k=async()=>{if(!w.trim()){o(t("modal.inputWeixinBaseUrl"),!1);return}m.current?.abort();const x=new AbortController;m.current=x,v(!0),S(""),c(""),n(null);let d=!1;try{const b=await F.startWeixinLogin(w.trim(),{signal:x.signal,timeoutMs:12e3});if(!b.ok||!b.qrcodeUrl){n({ok:!1,text:"✗ "+(b.error||b.message||t("modal.validationFailed"))});return}S(b.qrcodeUrl),c(b.sessionKey),n({ok:!0,text:t("modal.weixinWaitingScan")}),d=await E(x,b.sessionKey,w.trim())}catch(b){if(V(b))return;const f=$(b,t);n({ok:!1,text:"✗ "+f}),o(f,!1)}finally{m.current===x&&(m.current=null),v(!1),d&&h()}};return e.jsxs(O,{open:i,onClose:T,children:[e.jsx(H,{title:t("modal.configureWeixin"),onClose:T}),e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"text-xs leading-relaxed text-fg-4",children:t("modal.weixinScanHint")}),e.jsxs("div",{children:[e.jsx(L,{children:t("modal.weixinBaseUrl")}),e.jsx(P,{className:"font-mono text-xs",value:w,onChange:x=>G(x.target.value),placeholder:Y}),e.jsx("div",{className:"mt-1 text-[11px] text-fg-5",children:t("modal.weixinDefaultBaseUrlHint")})]}),B&&e.jsxs("div",{className:"rounded-xl border border-edge bg-panel-alt p-4",children:[e.jsx("img",{src:B,alt:t("modal.weixinQrAlt"),className:"mx-auto h-56 w-56 rounded-lg bg-white p-3 object-contain"}),y&&e.jsx("div",{className:"mt-2 truncate text-center font-mono text-[10px] text-fg-5",children:y})]}),u&&e.jsx("div",{className:"text-xs",style:{color:u.ok?"var(--th-ok)":"var(--th-err)"},children:u.text})]}),e.jsxs("div",{className:"mt-6 flex justify-end gap-2",children:[e.jsx(D,{variant:"ghost",onClick:T,children:t("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:j,onClick:k,children:t(j?B?"modal.validating":"modal.weixinGeneratingQr":B?"modal.weixinRetry":"modal.weixinGenerateQr")})]})]})}function X({open:i,onClose:h,channel:p,titleKey:o,fields:r,validate:s,savedToastKey:t,guideTitleKey:w,guideStepKeys:G,guideOpenWhenEmpty:j=!0,validateTimeoutMs:v=12e3}){const B=C(g=>g.state),S=C(g=>g.toast),y=C(g=>g.reloadUntil),c=C(g=>g.locale),u=a.useMemo(()=>_(c),[c]),[n,m]=a.useState({}),[N,T]=a.useState({}),[E,k]=a.useState(!1),[x,d]=a.useState(null),[b,f]=a.useState(!1),l=a.useRef(null),U=a.useRef(B);U.current=B;const W=!!(G&&G.length);a.useEffect(()=>{if(i){const g=U.current?.config||{},K={};let R=!1;for(const I of r){const M=String(g[I.key]??"").trim();K[I.key]=M,!M&&I.required!==!1&&(R=!0)}m(K),T({}),d(null),f(W&&j&&R)}else l.current?.abort(),l.current=null,k(!1)},[i,r,W,j]),a.useEffect(()=>()=>{l.current?.abort(),l.current=null},[]);const A=()=>{l.current?.abort(),l.current=null,h()},z=async()=>{const g={};for(const I of r){const M=String(n[I.key]||"").trim();if(g[I.key]=M,I.required!==!1&&!M){S(u(I.labelKey)+": "+u("modal.fieldRequired"),!1);return}}l.current?.abort();const K=new AbortController;l.current=K,k(!0),d(null);let R=!1;try{const I=await s(g,{signal:K.signal,timeoutMs:v});if(!I.ok){d({ok:!1,text:"✗ "+(I.error||u("modal.validationFailed"))});return}d({ok:!0,text:"✓ "+(I.identity||u("modal.credentialsVerified"))});const M=new Set((B?.setupState?.channels||[]).filter(q=>(q.ready||q.configured)&&q.channel!==p).map(q=>q.channel));if(M.add(p),await F.saveConfig({...g,channels:[...M]}),!await y(q=>{const te=q.config||{};for(const J of r)if(String(te[J.key]||"").trim()!==g[J.key])return!1;return!!q.setupState?.channels?.find(J=>J.channel===p)?.ready},{attempts:10,intervalMs:350})){d({ok:!1,text:"✗ "+u("modal.refreshStateFailed")}),S(u("modal.refreshStateFailed"),!1);return}S(u(t)),R=!0}catch(I){if(V(I))return;const M=$(I,u);d({ok:!1,text:"✗ "+M}),S(M,!1)}finally{l.current===K&&(l.current=null),k(!1),R&&h()}};return e.jsxs(O,{open:i,onClose:A,children:[e.jsx(H,{title:u(o),onClose:A}),e.jsxs("div",{className:"space-y-4",children:[W&&w&&e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt",children:[e.jsxs("button",{type:"button",className:"flex w-full items-center justify-between px-3 py-2 text-xs font-medium text-fg-3 hover:text-fg-2 transition-colors",onClick:()=>f(!b),children:[e.jsx("span",{children:u(w)}),e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:`transition-transform ${b?"rotate-180":""}`,children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),b&&e.jsx("div",{className:"space-y-1 border-t border-edge px-3 pb-3 pt-2 text-xs leading-relaxed text-fg-4",children:G.map(g=>e.jsx("p",{children:u(g)},g))})]}),r.map(g=>{const K=g.key,R=!!N[K],I=g.password&&!R?"password":"text";return e.jsxs("div",{children:[e.jsxs(L,{children:[u(g.labelKey),g.required===!1&&e.jsxs(e.Fragment,{children:[" ",e.jsxs("span",{className:"text-fg-5",children:["(",u("modal.optional"),")"]})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(P,{type:I,className:"flex-1 font-mono text-xs",placeholder:g.placeholder?u(g.placeholder):"",value:n[K]||"",onChange:M=>m(Z=>({...Z,[K]:M.target.value}))}),g.password&&e.jsx(D,{variant:"ghost",size:"sm",className:"!w-[34px] !p-0",onClick:()=>T(M=>({...M,[K]:!M[K]})),children:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",children:[e.jsx("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),e.jsx("circle",{cx:"12",cy:"12",r:"3"})]})})]})]},K)}),x&&e.jsx("div",{className:"text-xs",style:{color:x.ok?"var(--th-ok)":"var(--th-err)"},children:x.text})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[e.jsx(D,{variant:"ghost",onClick:A,children:u("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:E,onClick:z,children:u(E?"modal.validating":"modal.validateSave")})]})]})}function me({open:i,onClose:h}){return e.jsx(X,{open:i,onClose:h,channel:"slack",titleKey:"modal.configureSlack",savedToastKey:"modal.slackSaved",guideTitleKey:"modal.slackGuideTitle",guideStepKeys:["modal.slackGuideStep1","modal.slackGuideStep2","modal.slackGuideStep3","modal.slackGuideStep4","modal.slackGuideStep5"],fields:[{key:"slackBotToken",labelKey:"modal.slackBotToken",password:!0,placeholder:"modal.slackBotTokenPlaceholder"},{key:"slackAppToken",labelKey:"modal.slackAppToken",password:!0,placeholder:"modal.slackAppTokenPlaceholder"}],validate:async(p,o)=>{const r=await F.validateSlackConfig(p.slackBotToken,p.slackAppToken,o),s=r.bot?.username?"@"+r.bot.username+(r.bot.team?" ("+r.bot.team+")":""):null;return{ok:r.ok,error:r.error,identity:s}}})}function xe({open:i,onClose:h}){return e.jsx(X,{open:i,onClose:h,channel:"discord",titleKey:"modal.configureDiscord",savedToastKey:"modal.discordSaved",guideTitleKey:"modal.discordGuideTitle",guideStepKeys:["modal.discordGuideStep1","modal.discordGuideStep2","modal.discordGuideStep3","modal.discordGuideStep4","modal.discordGuideStep5"],fields:[{key:"discordBotToken",labelKey:"modal.discordBotToken",password:!0,placeholder:"modal.discordBotTokenPlaceholder"}],validate:async(p,o)=>{const r=await F.validateDiscordConfig(p.discordBotToken,o),s=r.bot?.username?"@"+r.bot.username:null;return{ok:r.ok,error:r.error,identity:s}}})}function fe({open:i,onClose:h}){return e.jsx(X,{open:i,onClose:h,channel:"dingtalk",titleKey:"modal.configureDingtalk",savedToastKey:"modal.dingtalkSaved",guideTitleKey:"modal.dingtalkGuideTitle",guideStepKeys:["modal.dingtalkGuideStep1","modal.dingtalkGuideStep2","modal.dingtalkGuideStep3","modal.dingtalkGuideStep4","modal.dingtalkGuideStep5"],fields:[{key:"dingtalkClientId",labelKey:"modal.dingtalkClientId",placeholder:"modal.dingtalkClientIdPlaceholder"},{key:"dingtalkClientSecret",labelKey:"modal.dingtalkClientSecret",password:!0,placeholder:"modal.dingtalkClientSecretPlaceholder"}],validate:async(p,o)=>{const r=await F.validateDingtalkConfig(p.dingtalkClientId,p.dingtalkClientSecret,o),s=r.app?.clientId?r.app.clientId.length>12?r.app.clientId.slice(0,6)+"..."+r.app.clientId.slice(-4):r.app.clientId:null;return{ok:r.ok,error:r.error,identity:s}}})}function he({open:i,onClose:h}){return e.jsx(X,{open:i,onClose:h,channel:"wecom",titleKey:"modal.configureWeCom",savedToastKey:"modal.wecomSaved",guideTitleKey:"modal.wecomGuideTitle",guideStepKeys:["modal.wecomGuideStep1","modal.wecomGuideStep2","modal.wecomGuideStep3","modal.wecomGuideStep4","modal.wecomGuideNote"],fields:[{key:"wecomBotId",labelKey:"modal.wecomBotId",placeholder:"modal.wecomBotIdPlaceholder"},{key:"wecomBotSecret",labelKey:"modal.wecomBotSecret",password:!0,placeholder:"modal.wecomBotSecretPlaceholder"}],validate:async(p,o)=>{const r=await F.validateWecomConfig(p.wecomBotId,p.wecomBotSecret,o),s=r.bot?.botId?r.bot.botId:null;return{ok:r.ok,error:r.error,identity:s}}})}function pe({open:i,onClose:h}){const p=C(n=>n.state),o=C(n=>n.toast),r=C(n=>n.reload),s=C(n=>n.locale),t=a.useMemo(()=>_(s),[s]),w=p?.bot?.workdir||p?.runtimeWorkdir||"",[G,j]=a.useState(""),[v,B]=a.useState(!1),[S,y]=a.useState(0);a.useEffect(()=>{i&&(j(w),y(n=>n+1))},[i,w]);const c=a.useCallback(n=>{j(n)},[]),u=async()=>{const n=G.trim();if(!n){o(t("modal.selectDirFirst"),!1);return}B(!0);try{const m=await F.switchWorkdir(n);m.ok?(await r(),o(t("modal.switchedTo")+m.workdir),h()):o(m.error||t("modal.switchFailed"),!1)}catch{o(t("modal.switchFailed"),!1)}finally{B(!1)}};return e.jsx(O,{open:i,onClose:v?void 0:h,panelStyle:{width:"min(500px, calc(100vw - 2rem))",maxWidth:"min(500px, calc(100vw - 2rem))"},children:v?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 gap-4 animate-in",children:[e.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round",className:"animate-spin text-fg-3",style:{animationDuration:"1.2s"},children:[e.jsx("polyline",{points:"23 4 23 10 17 10"}),e.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"})]}),e.jsx("span",{className:"text-sm font-medium text-fg-3",children:t("modal.switching")}),e.jsx("span",{className:"text-xs text-fg-5 max-w-[280px] truncate",children:G})]}):e.jsxs(e.Fragment,{children:[e.jsx(H,{title:t("modal.switchWorkdir"),onClose:h}),e.jsx(se,{initialPath:w,onSelect:c,t},S),e.jsxs("div",{className:"flex justify-end gap-2 mt-4",children:[e.jsx(D,{variant:"ghost",onClick:h,children:t("modal.cancel")}),e.jsx(D,{variant:"primary",onClick:u,children:t("modal.selectDir")})]})]})})}function ge({open:i,onClose:h,onSaved:p}){const o=C(l=>l.toast),r=C(l=>l.locale),s=a.useMemo(()=>_(r),[r]),[t,w]=a.useState(null),[G,j]=a.useState(!1),[v,B]=a.useState(!1),[S,y]=a.useState(null);a.useEffect(()=>{i&&(j(!1),y(null),F.getBrowser().then(l=>{w(l),B(!!l.browser.enabled)}).catch(()=>w(null)))},[i]);const c=t?.browser,u=!!c?.enabled,n=!!c&&u!==v,m=c?.remoteCdpUrl||"",N=!!m&&v,T=c?.profileDir||"",E=s(N?"ext.browserRemote":"ext.profileDir"),k=N?m:T,x=!!c?.chromeInstalled&&!!c?.profileCreated,d=t?c?.enabled?N?s("ext.browserRemote"):x?s("ext.browserReady"):c?.chromeInstalled?s("ext.chromeInstalled"):s("ext.needsSetup"):s("ext.disabled"):s("status.loading"),b=t&&c?.enabled?N||x?"ok":c?.chromeInstalled?"warn":"err":"muted",f=async()=>{j(!0),y(null);let l=null;try{await F.saveConfig({browserEnabled:v}),l=await F.getBrowser(),w(l),p?.()}catch{y({ok:!1,text:"✗ "+s("ext.browserModeSaveFailed")}),o(s("ext.browserModeSaveFailed"),!1),j(!1);return}if(!v){y({ok:!0,text:"✓ "+s("ext.browserDisabledSaved")}),o(s("ext.browserDisabledSaved")),j(!1);return}if(l?.browser.remoteCdpUrl){y({ok:!0,text:"✓ "+s("ext.browserRemoteStep")}),o(s("ext.browserRemoteStep")),j(!1);return}try{const U=await F.setupBrowser();if(!U.ok){y({ok:!1,text:"✗ "+(U.error||s("ext.browserLaunchFailed"))}),o(U.error||s("ext.browserLaunchFailed"),!1);return}w(W=>W?{...W,browser:U.browser}:{browser:U.browser}),y({ok:!0,text:"✓ "+s("ext.browserEnabledLaunched")}),o(s("ext.browserEnabledLaunched")),p?.()}catch{y({ok:!1,text:"✗ "+s("ext.browserLaunchFailed")}),o(s("ext.browserLaunchFailed"),!1)}finally{j(!1)}};return e.jsxs(O,{open:i,onClose:h,children:[e.jsx(H,{title:s("ext.setupBrowser"),description:s("ext.setupBrowserDesc"),onClose:h}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Q,{variant:b,children:d}),c&&e.jsxs(e.Fragment,{children:[e.jsx(Q,{variant:u?"accent":"muted",children:s(u?"ext.enabled":"ext.disabled")}),n&&e.jsx(Q,{variant:"warn",children:s("ext.pendingModeChange")}),c.running&&e.jsxs(Q,{variant:"accent",children:[s("ext.browserOpen"),c.pid?` · PID ${c.pid}`:""]})]})]}),e.jsxs("div",{className:"mt-3",children:[e.jsx(L,{children:E}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(P,{className:"font-mono text-xs flex-1",value:k||"—",readOnly:!0,onClick:l=>l.target.select()}),e.jsx(D,{variant:"outline",size:"sm",disabled:!k,onClick:()=>{k&&(navigator.clipboard.writeText(k),o(s("ext.step2Copied")))},children:s("ext.copyPath")})]})]}),e.jsx("div",{className:"mt-3 text-xs text-fg-5",children:s(v?"ext.profileModeDesc":"ext.browserDescDisabled")}),c?.detail&&e.jsx("div",{className:"mt-2 text-xs text-fg-5",children:c.detail}),S&&e.jsx("div",{className:"mt-3 text-xs",style:{color:S.ok?"var(--th-ok)":"var(--th-err)"},children:S.text})]}),e.jsx("div",{className:"rounded-lg border border-edge bg-panel-alt p-4",children:e.jsxs("label",{className:"flex cursor-pointer items-start gap-3",children:[e.jsx("input",{type:"checkbox",checked:v,onChange:l=>B(l.target.checked),className:"mt-0.5 h-4 w-4 rounded border border-edge bg-inset"}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-fg-2 mb-1",children:s("ext.browserEnableToggle")}),e.jsx("div",{className:"text-xs text-fg-4",children:s("ext.browserEnableToggleDesc")})]})]})}),e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt p-4",children:[e.jsx("div",{className:"text-sm font-medium text-fg-2 mb-1",children:s(v?N?"ext.browserRemoteStep":"ext.step2Title":"ext.browserDisabledStepTitle")}),e.jsx("div",{className:"text-xs text-fg-4",children:s(v?N?"ext.browserRemoteStepDesc":"ext.step2Desc":"ext.browserDisabledHint")})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[e.jsx(D,{variant:"ghost",onClick:h,children:s("modal.cancel")}),e.jsx(D,{variant:"primary",disabled:G,onClick:f,children:s(G?"ext.launching":v?N?"ext.saveBrowserRemote":"ext.enableAndLaunchBrowser":"ext.saveBrowserDisabled")})]})]})}export{ge as BrowserSetupModal,fe as DingtalkModal,xe as DiscordModal,ce as FeishuModal,me as SlackModal,de as TelegramModal,he as WeComModal,ue as WeixinModal,pe as WorkdirModal};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as a,j as e,a as H}from"./react-vendor-C7Sl8SE7.js";import{c}from"./index-
|
|
1
|
+
import{r as a,j as e,a as H}from"./react-vendor-C7Sl8SE7.js";import{c}from"./index-Dp_KlJM9.js";function y(u,h){return!!(u&&h instanceof Node&&u.contains(h))}function M({value:u,options:h,onChange:j,className:g,placeholder:l="—",disabled:x=!1,readOnly:f=!1}){const p=h.find(t=>t.value===u),w=f||h.length<=1,[i,m]=a.useState(!1),[o,d]=a.useState(null),n=a.useRef(null),_=a.useRef(null);if(a.useEffect(()=>{if(!i)return;const t=s=>{y(n.current,s.target)||y(_.current,s.target)||m(!1)},r=s=>{s.key==="Escape"&&(s.stopPropagation(),m(!1))};return document.addEventListener("mousedown",t),document.addEventListener("keydown",r,!0),()=>{document.removeEventListener("mousedown",t),document.removeEventListener("keydown",r,!0)}},[i]),a.useLayoutEffect(()=>{if(!i)return;const t=()=>{const r=n.current;if(!r)return;const s=r.getBoundingClientRect(),k=window.innerHeight-s.bottom-12,E=s.top-12,N=k<220&&E>k,L=Math.max(140,Math.min(260,N?E:k));d({left:s.left,top:N?Math.max(12,s.top-L-8):s.bottom+8,width:s.width,maxHeight:L})};return t(),window.addEventListener("resize",t),window.addEventListener("scroll",t,!0),()=>{window.removeEventListener("resize",t),window.removeEventListener("scroll",t,!0)}},[i]),w)return e.jsx("div",{className:c("flex h-9 w-full items-center rounded-md border border-edge bg-panel-alt px-3 text-[13px] text-fg-5 shadow-none",x&&"cursor-not-allowed",g),children:e.jsx("span",{className:c("truncate",!p&&"text-fg-6"),children:p?.label||l})});const b=t=>{x||(j(t),m(!1))},v=i&&o?H.createPortal(e.jsx("div",{ref:_,role:"listbox",className:"fixed z-[220] overflow-hidden rounded-xl border border-edge-h bg-[var(--th-dropdown)] p-1.5 shadow-[0_24px_64px_rgba(2,6,23,0.22)] backdrop-blur-xl",style:{left:o.left,top:o.top,width:o.width},children:e.jsx("div",{className:"overflow-y-auto",style:{maxHeight:o.maxHeight},children:h.map(t=>{const r=t.value===u;return e.jsxs("button",{type:"button",role:"option","aria-selected":r,onClick:()=>b(t.value),className:c("flex w-full items-start gap-2 rounded-lg px-3 py-2 text-left text-[13px] transition-colors duration-200",r?"bg-panel text-fg shadow-[inset_0_1px_0_rgba(255,255,255,0.03)]":"text-fg-3 hover:bg-panel-alt hover:text-fg-2"),children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-baseline gap-2",children:[e.jsx("span",{className:"min-w-0 flex-1 truncate",children:t.label}),t.meta&&e.jsx("span",{className:"shrink-0 font-mono text-[10px] text-fg-5",children:t.meta})]}),t.description&&e.jsx("div",{className:"mt-0.5 truncate font-mono text-[10px] leading-relaxed text-fg-5",children:t.description})]}),r&&e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"mt-0.5 shrink-0 text-fg-4",children:e.jsx("polyline",{points:"20 6 9 17 4 12"})})]},t.value)})})}),document.body):null;return e.jsxs("div",{ref:n,className:c("relative",g),children:[e.jsxs("button",{type:"button",disabled:x,"aria-haspopup":"listbox","aria-expanded":i,onClick:()=>m(t=>!t),className:c("flex h-9 w-full items-center rounded-md border border-control-border bg-control px-3 pr-8 text-left text-[13px] text-fg shadow-sm","transition-[border-color,box-shadow,background] duration-200 outline-none","hover:border-control-border-h hover:bg-control-h","focus-visible:border-control-border-h focus-visible:shadow-[0_0_0_4px_var(--th-glow-a)]","disabled:cursor-not-allowed disabled:bg-panel-alt disabled:border-edge disabled:text-fg-5","disabled:shadow-none disabled:hover:border-edge disabled:hover:bg-panel-alt",i&&"border-control-border-h bg-control-h shadow-[0_0_0_4px_var(--th-glow-a)]"),children:[e.jsx("span",{className:c("min-w-0 flex-1 truncate",!p&&"text-fg-5"),children:p?.label||l}),e.jsx("span",{className:c("pointer-events-none absolute inset-y-0 right-3 flex items-center text-fg-4 transition-transform duration-200",i&&"rotate-180"),children:e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})})]}),v]})}function P({value:u,options:h,onChange:j,renderIcon:g}){const[l,x]=a.useState(!1),[f,p]=a.useState(null),w=a.useRef(null),i=a.useRef(null);a.useEffect(()=>{if(!l)return;const o=n=>{y(w.current,n.target)||y(i.current,n.target)||x(!1)},d=n=>{n.key==="Escape"&&(n.stopPropagation(),x(!1))};return document.addEventListener("mousedown",o),document.addEventListener("keydown",d,!0),()=>{document.removeEventListener("mousedown",o),document.removeEventListener("keydown",d,!0)}},[l]),a.useLayoutEffect(()=>{if(!l)return;const o=()=>{const d=w.current;if(!d)return;const n=d.getBoundingClientRect(),b=window.innerHeight-n.bottom-12,v=n.top-12,t=b<220&&v>b,r=Math.max(140,Math.min(260,t?v:b));p({left:n.left,top:t?Math.max(12,n.top-r-8):n.bottom+8,width:Math.max(n.width,160),maxHeight:r})};return o(),window.addEventListener("resize",o),window.addEventListener("scroll",o,!0),()=>{window.removeEventListener("resize",o),window.removeEventListener("scroll",o,!0)}},[l]);const m=l&&f?H.createPortal(e.jsx("div",{ref:i,role:"listbox",className:"fixed z-[220] overflow-hidden rounded-xl border border-edge-h bg-[var(--th-dropdown)] p-1.5 shadow-[0_24px_64px_rgba(2,6,23,0.22)] backdrop-blur-xl",style:{left:f.left,top:f.top,width:f.width},children:e.jsx("div",{className:"overflow-y-auto",style:{maxHeight:f.maxHeight},children:h.map(o=>{const d=o.value===u;return e.jsxs("button",{type:"button",role:"option","aria-selected":d,onClick:()=>{j(o.value),x(!1)},className:c("flex w-full items-center gap-2.5 rounded-lg px-2.5 py-2 text-left text-[13px] transition-colors duration-200",d?"bg-panel text-fg shadow-[inset_0_1px_0_rgba(255,255,255,0.03)]":"text-fg-3 hover:bg-panel-alt hover:text-fg-2"),children:[g(o.value),e.jsx("span",{className:"min-w-0 flex-1 truncate",children:o.label}),d&&e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"shrink-0 text-fg-4",children:e.jsx("polyline",{points:"20 6 9 17 4 12"})})]},o.value)})})}),document.body):null;return e.jsxs("div",{ref:w,className:"relative shrink-0",children:[e.jsxs("button",{type:"button","aria-haspopup":"listbox","aria-expanded":l,onClick:()=>x(o=>!o),className:c("inline-flex items-center gap-1.5 rounded-lg border border-edge bg-inset px-2 py-1.5","transition-[border-color,box-shadow,background] duration-200 outline-none","hover:border-edge-h hover:bg-panel","focus-visible:border-edge-h focus-visible:shadow-[0_0_0_4px_var(--th-glow-a)]",l&&"border-edge-h bg-panel shadow-[0_0_0_4px_var(--th-glow-a)]"),children:[g(u),e.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:c("text-fg-5 transition-transform duration-200",l&&"rotate-180"),children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),m]})}export{P as I,M as S};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t,j as n}from"./react-vendor-C7Sl8SE7.js";import{c as Mt,I as Et,S as Me,m as Ee,a as w,u as ut,d as Lt,g as Ct,l as Pt,e as qt,j as Ft,f as Ht,s as Ut,Y as Dt}from"./index-CJm8YsKX.js";import{s as Qt,l as _t,n as ct,m as $t,a as Bt,o as Kt,d as zt,b as Wt,p as Yt,c as Oe,T as Xt,R as Gt,U as it,e as Vt,f as dt,g as Jt,L as Zt,I as er}from"./index-DVHryefY.js";import{M as mt,a as gt}from"./Modal-B4wc5184.js";import"./router-DHISdpPk.js";import"./Select-xEvJAcZi.js";import"./DirBrowser-DPNjooga.js";import"./markdown-DxQYQFeH.js";import"./ExtensionsTab-Bv_23Acs.js";function tr({snapshot:l}){const[r,d]=t.useState(l.currentIndex??0),[O,v]=t.useState(""),[k,g]=t.useState(!1),[M,S]=t.useState(null);t.useEffect(()=>{d(l.currentIndex??0),v(""),S(null)},[l.promptId,l.currentIndex]);const E=l.questions||[],T=E[r]||null,se=E.length,L=!!(T?.options&&T.options.length),f=L?!!T?.allowFreeform:!0,K=a=>{a&&(d(h=>h+1),v(""))},ke=async a=>{if(!k){g(!0),S(null);try{const h=await w.interactionSelectOption(l.promptId,a);if(!h.ok){S(h.error||"Failed to submit selection.");return}K(h.advanced)}catch(h){S(h?.message||"Network error.")}finally{g(!1)}}},C=async()=>{if(k)return;const a=O.trim();if(!a&&!T?.allowEmpty){S("Please enter a response.");return}g(!0),S(null);try{const h=await w.interactionSubmitText(l.promptId,a);if(!h.ok){S(h.error||"Failed to submit answer.");return}K(h.advanced)}catch(h){S(h?.message||"Network error.")}finally{g(!1)}},p=async()=>{if(!k){g(!0),S(null);try{const a=await w.interactionSkip(l.promptId);if(!a.ok){S(a.error||"Failed to skip.");return}K(a.advanced)}catch(a){S(a?.message||"Network error.")}finally{g(!1)}}},z=async()=>{if(!k){g(!0);try{await w.interactionCancel(l.promptId)}catch{}}},le=t.useMemo(()=>{const a=[];return l.hint&&a.push(l.hint),se>1&&a.push(`Question ${r+1} of ${se}`),a.join(" · ")||void 0},[l.hint,r,se]);return n.jsxs(mt,{open:!0,onClose:z,wide:L&&(T?.options?.length||0)>3,children:[n.jsx(gt,{title:l.title||"Pikiloom needs your input",description:le,onClose:z}),T?n.jsxs("div",{className:"space-y-4",children:[n.jsxs("div",{children:[n.jsx("div",{className:"text-xs font-medium uppercase tracking-wide text-fg-5",children:T.header||"Question"}),n.jsx("div",{className:"mt-1 whitespace-pre-wrap text-sm leading-relaxed text-fg",children:T.prompt})]}),L&&n.jsx("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-2",children:(T.options||[]).map(a=>n.jsxs("button",{type:"button",disabled:k,onClick:()=>ke(a.value||a.label),className:Mt("group rounded-lg border border-edge bg-panel-alt px-3 py-2 text-left text-sm transition","hover:border-control-border-h hover:bg-control-h hover:shadow-sm","focus:outline-none focus:ring-2 focus:ring-[var(--th-glow-a)]","disabled:cursor-not-allowed disabled:opacity-50"),children:[n.jsx("div",{className:"font-medium text-fg group-hover:text-fg",children:a.label}),a.description&&n.jsx("div",{className:"mt-0.5 text-xs leading-snug text-fg-4",children:a.description})]},a.value||a.label))}),f&&n.jsx("div",{children:n.jsx(Et,{value:O,onChange:a=>v(a.target.value),onKeyDown:a=>{a.key==="Enter"&&!a.shiftKey&&!k&&(a.preventDefault(),C())},placeholder:L?"Or type a custom answer…":"Type your answer…",disabled:k,autoFocus:!L})}),M&&n.jsx("div",{className:"rounded-md border border-red-300/40 bg-red-500/10 px-3 py-2 text-xs text-red-600",children:M}),n.jsxs("div",{className:"flex items-center justify-between gap-3",children:[n.jsx("div",{className:"text-xs text-fg-5",children:k?n.jsxs("span",{className:"inline-flex items-center gap-2",children:[n.jsx(Me,{})," Submitting…"]}):n.jsxs("span",{children:["Press ",n.jsx("kbd",{className:"rounded border border-edge bg-panel-alt px-1.5 py-0.5 text-[10px] uppercase",children:"Enter"})," to send"]})}),n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(Ee,{variant:"ghost",size:"sm",onClick:p,disabled:k,children:"Skip"}),f&&n.jsx(Ee,{variant:"primary",size:"sm",onClick:C,disabled:k||!O.trim()&&!T.allowEmpty,children:"Submit"})]})]})]}):n.jsxs("div",{className:"py-6 text-center text-sm text-fg-5",children:[n.jsx(Me,{className:"mr-2 inline-block"})," Waiting for the agent…"]})]})}function rr(l){return l.isNull?l.localStreamPending||l.holdsActiveState?"reject-null":"apply":(typeof l.updatedAt=="number"?l.updatedAt:0)<l.lastAppliedUpdatedAt?"reject-stale":"apply"}function nr(l,r){return typeof r!="number"?l:r>l?r:l}function sr(l,r){return!l||!l.length?[]:r.size?l.filter(d=>!r.has(d)):l.slice()}function lr(l,r,d,O){if(!l.size)return l;const v=new Set(r);let k=!1;const g=new Map;for(const[M,S]of l){if(d-S>O||!v.has(M)){k=!0;continue}g.set(M,S)}return k?g:l}const Ge=12,ft=160,ar=96,or=[],ur=[],cr=[],ir=20,dr=6e4,ne=new Map;function fr(l,r){return`${l}:${r}`}function mr(l,r){for(ne.delete(l),ne.set(l,r);ne.size>ir;)ne.delete(ne.keys().next().value)}const vr=t.memo(function({session:r,workdir:d,active:O=!0,onSessionChange:v,initialPendingPrompt:k,initialPendingImageUrls:g,onPendingPromptConsumed:M}){const S=ut(e=>e.locale),E=ut(e=>e.agentStatus?.agents?.find(s=>s.agent===r.agent)??null),T=E?.selectedEffort??null,se=E?.selectedModel??null,L=E?.byokProviderName??null,f=t.useMemo(()=>Lt(S),[S]),K=Ct(r.agent||""),ke=Pt(r),C=!!k||!!(g&&g.length),[p,z]=t.useState(null),[le,a]=t.useState(!C),[h,Ve]=t.useState(!1),[i,F]=t.useState(null),[ae,oe]=t.useState(!1),[W,Le]=t.useState(null),[pt,Je]=t.useState(0),[ht,Ce]=t.useState(null),[Y,Se]=t.useState([]),[xt,Ie]=t.useState([]),[ue,Pe]=t.useState([]),[I,ce]=t.useState(k||null),[P,ie]=t.useState(g||[]),[kt,de]=t.useState(null),X=t.useRef(null);X.current=kt;const Ze=t.useRef(I);Ze.current=I;const[et,H]=t.useState([]),qe=t.useRef([]);qe.current=et;const fe=t.useRef(null),[St,tt]=t.useState(null),[be,me]=t.useState(null),[ge,Fe]=t.useState(""),[U,He]=t.useState(!1),It=!!E?.capabilities?.fork,Ue=t.useRef(null),q=t.useRef(g||[]),D=t.useRef(i),De=t.useRef(ae);D.current=i,De.current=ae;const Qe=t.useRef(Y);Qe.current=Y;const rt=t.useRef(W);rt.current=W;const Q=t.useRef(null),ye=t.useRef(null),G=t.useRef(!0),V=t.useRef(!1),ve=t.useRef(null),_e=t.useRef(!1),_=t.useRef(C),pe=t.useRef(!1),J=t.useRef(!1),$e=t.useRef(!1),Be=t.useRef(!1),$=t.useRef(null),Te=t.useRef(0),he=t.useRef(new Map),nt=t.useRef({model:null,effort:null}),bt=t.useCallback(e=>{nt.current=e},[]);t.useEffect(()=>{$e.current||!C||($e.current=!0,k&&!I&&ce(k),g&&g.length&&!P.length&&(ie(g),q.current=g),a(!1),Je(e=>e+1),M?.())},[C,M]);const N=t.useCallback(()=>{ce(null),ie(e=>{for(const s of e)URL.revokeObjectURL(s);return[]}),q.current=[],de(null)},[]),Z=t.useCallback(()=>{H(e=>{if(!e.length)return e;for(const s of e)for(const o of s.imageUrls)URL.revokeObjectURL(o);return[]}),fe.current=null},[]),st=t.useCallback((e,s)=>{const o=Qt({streaming:De.current,liveStreamPhase:D.current?.phase??null,streamPhase:rt.current,queuedTaskCount:Qe.current.length,pendingQueuedCount:qe.current.length}),u=s||[];if(o){const c=`local-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;fe.current=c,H(x=>[...x,{localId:c,taskId:null,prompt:e||"",imageUrls:u}]);return}D.current?.phase==="done"&&F(null);for(const c of q.current)URL.revokeObjectURL(c);fe.current=null,ce(e||null),ie(u),q.current=u,de(null)},[]),yt=t.useCallback(e=>{const s=fe.current;if(s){fe.current=null,H(o=>{const u=o.findIndex(x=>x.localId===s);if(u<0)return o;const c=o.slice();return c[u]={...c[u],taskId:e},c});return}de(e)},[]),vt=t.useCallback(async()=>{if(!be)return;const e=ge.trim();if(e){He(!0);try{const s=await w.forkSession(d,r.agent||"",r.sessionId,be.atTurn,e,{});if(!s.ok||!s.sessionKey){He(!1);return}const[o,u]=s.sessionKey.split(":");me(null),Fe(""),v?.({agent:o,sessionId:u,workdir:d})}finally{He(!1)}}},[be,ge,d,r.agent,r.sessionId,v]);Ue.current=vt;const Re=t.useCallback(async(e,s={})=>{try{const o=await _t({workdir:d,agent:r.agent||"",sessionId:r.sessionId,rich:!0,turnOffset:e.turnOffset,turnLimit:e.turnLimit,lastNTurns:e.lastNTurns},{force:s.force});return o.ok?ct(o):null}catch{return null}},[d,r.agent,r.sessionId]),A=t.useCallback(async({keepOlder:e,force:s=!1,scrollToBottom:o=!1})=>{const u=r.sessionId;if(ve.current===u)return!1;ve.current=u;try{const c=await Re({turnOffset:0,turnLimit:Ge},{force:s});if(!c||r.sessionId!==u)return!1;if(o&&(V.current=!0),z(x=>!x||!e?c:$t(x,c)),a(!1),pe.current&&(pe.current=!1,N()),J.current){const x=J.current;J.current=!1;const te=x!==!0?x.taskId:null;D.current&&(x===!0||D.current.taskId===te)&&F(null)}return!0}finally{ve.current===u&&(ve.current=null)}},[Re,N,r.sessionId]),je=t.useCallback(async()=>{if(!p?.hasOlder||_e.current)return;const e=Q.current;e&&(ye.current={scrollHeight:e.scrollHeight,scrollTop:e.scrollTop}),_e.current=!0,Ve(!0);try{const s=await Re({turnOffset:Math.max(0,p.totalTurns-p.startTurn),turnLimit:Ge});s?z(o=>o?Bt(o,s):s):ye.current=null}finally{_e.current=!1,Ve(!1)}},[Re,p]),we=t.useRef(null),ee=t.useCallback((e,s="ws")=>{if(rr({updatedAt:e?.updatedAt,isNull:!e,lastAppliedUpdatedAt:Te.current,localStreamPending:_.current,holdsActiveState:De.current||Qe.current.length>0})!=="apply")return;if(e&&(Te.current=nr(Te.current,e.updatedAt)),e?.sessionId&&e.sessionId!==r.sessionId&&(Be.current=!0,xe.current=`${r.agent}:${e.sessionId}`,v?.({agent:r.agent||"",sessionId:e.sessionId,workdir:d})),!e){const m=we.current;oe(!1),m==="streaming"?(pe.current=!0,J.current=!0,A({keepOlder:!0,force:!0,scrollToBottom:G.current})):F(null),_.current&&m!=="streaming"?A({keepOlder:!0,force:!0}):(m==="done"&&(N(),Z()),m!==null&&(_.current=!1)),Ce(null),Le(null),Se([]),Ie([]),Pe([]),we.current=null;return}Le(e.phase),Ce(e.taskId||null);const u=[];e.taskId&&u.push(e.taskId),Array.isArray(e.queuedTaskIds)&&u.push(...e.queuedTaskIds),he.current=lr(he.current,u,Date.now(),dr);const c=he.current,x=sr(e.queuedTaskIds,c),te=(Array.isArray(e.queuedTasks)?e.queuedTasks:[]).filter(m=>!c.has(m.taskId));if(Se(x.length?x:or),Ie(te.length?te:ur),Pe(Array.isArray(e.interactions)&&e.interactions.length?e.interactions:cr),Kt({pendingTaskId:X.current,streamTaskId:e.taskId||null,queuedTaskIds:e.queuedTaskIds})){const m=X.current,j=Ze.current||"",y=q.current;H(b=>b.some(re=>re.taskId===m)?b:[...b,{localId:`demote-${m}`,taskId:m,prompt:j,imageUrls:y}]),ce(null),ie([]),q.current=[],de(null),X.current=null}if(e.phase==="streaming"){if(F({taskId:e.taskId||null,phase:"streaming",text:e.text||"",thinking:e.thinking||"",activity:e.activity,plan:e.plan??null,model:e.model??null,effort:e.effort??null,previewMeta:e.previewMeta??null,subAgents:e.previewMeta?.subAgents??null,generatingImages:e.previewMeta?.generatingImages??0,artifacts:e.artifacts??null,startedAt:typeof e.startedAt=="number"?e.startedAt:null,error:null,question:e.question??null}),oe(!0),e.taskId&&e.taskId!==X.current){const m=qe.current,j=m.findIndex(y=>y.taskId===e.taskId);if(j>=0){const y=m[j];for(const b of q.current)URL.revokeObjectURL(b);ce(y.prompt||null),ie(y.imageUrls),q.current=y.imageUrls,de(e.taskId),H(b=>b.filter((re,B)=>B!==j))}}G.current&&(V.current=!0)}else if(e.phase==="queued")F(null),oe(!1);else if(e.phase==="done"){const m=zt(D.current?.taskId??null,e.taskId||null),j=x.length>0;if(m){oe(!1),F(B=>B?{...B,phase:"done",error:e.error??null}:e.error?{taskId:e.taskId||null,phase:"done",text:"",thinking:"",activity:"",plan:null,model:e.model??null,effort:e.effort??null,previewMeta:e.previewMeta??null,subAgents:e.previewMeta?.subAgents??null,generatingImages:e.previewMeta?.generatingImages??0,artifacts:e.artifacts??null,error:e.error}:B);const y=D.current,b=!!y&&Wt(y),re=!!e.incomplete&&b&&!j;if(we.current!=="done"){j||(pe.current=!0),J.current=re?!1:{taskId:e.taskId||null},A({keepOlder:!0,force:!0,scrollToBottom:G.current});const B=r.agent||"",Nt=r.sessionId,At=xe.current;$.current&&clearTimeout($.current),$.current=setTimeout(()=>{$.current=null,w.getSessionStreamState(B,Nt).then(Ot=>{xe.current===At&&Ke.current(Ot.state,"seed")}).catch(()=>{})},900)}}j||(_.current=!1)}const Ae=new Set;if(e.taskId&&Ae.add(e.taskId),Array.isArray(e.queuedTaskIds))for(const m of e.queuedTaskIds)Ae.add(m);H(m=>{let j=!1;const y=[];for(const b of m)if(!b.taskId||Ae.has(b.taskId))y.push(b);else{for(const re of b.imageUrls)URL.revokeObjectURL(re);j=!0}return j?y:m}),we.current=e.phase},[N,Z,A,r.sessionId,r.agent,v,d]),Ke=t.useRef(ee);Ke.current=ee;const lt=t.useCallback(()=>{_.current=!0,Je(e=>e+1)},[]);t.useEffect(()=>()=>{$.current&&(clearTimeout($.current),$.current=null)},[]);const Tt=t.useCallback(async e=>{try{he.current.set(e,Date.now()),await w.recallSessionMessage(e),X.current===e&&N(),H(s=>{let o=!1;const u=[];for(const c of s)if(c.taskId===e){for(const x of c.imageUrls)URL.revokeObjectURL(x);o=!0}else u.push(c);return o?u:s}),Se(s=>s.filter(o=>o!==e)),Ie(s=>s.filter(o=>o.taskId!==e)),Ce(s=>s===e?null:s)}catch{}},[N]),Rt=t.useCallback(async e=>{try{await w.steerSession(e)}catch{}},[]),jt=t.useCallback(async()=>{try{await w.stopSession(r.agent||"",r.sessionId)}catch{}},[r.agent,r.sessionId]),Ne=fr(r.agent||"",r.sessionId);t.useEffect(()=>{if(Be.current){Be.current=!1;let c=!1;return A({keepOlder:!0,force:!0}).finally(()=>{c||a(!1)}),()=>{c=!0}}let e=!1;const s=Yt({workdir:d,agent:r.agent||"",sessionId:r.sessionId,rich:!0,turnOffset:0,turnLimit:Ge},{allowStale:!0}),o=C&&!$e.current,u=s?.ok?ct(s):ne.get(Ne)||null;return a(o?!1:!u),z(u),F(null),oe(!1),Le(null),Se([]),Ie([]),Pe([]),Te.current=0,he.current=new Map,o||(N(),Z(),_.current=!1,pe.current=!1,J.current=!1),G.current=!0,V.current=!0,o||A({keepOlder:!1,force:!0}).finally(()=>{e||a(!1)}),()=>{e=!0}},[A,r.agent,r.sessionId,d,Ne,N,Z]),t.useEffect(()=>{p&&p.turns.length>0&&mr(Ne,p)},[Ne,p]),t.useEffect(()=>{O&&A({keepOlder:!0,force:!0})},[O,A]);const xe=t.useRef(`${r.agent}:${r.sessionId}`);xe.current=`${r.agent}:${r.sessionId}`,qt("stream-update",t.useCallback(e=>{e.key===xe.current&&ee(e.snapshot??null)},[ee])),t.useEffect(()=>{let e=!0;return w.getSessionStreamState(r.agent||"",r.sessionId).then(s=>{e&&Ke.current(s.state,"seed")}).catch(()=>{}),()=>{e=!1}},[r.agent,r.sessionId,pt]),Ft(t.useCallback(()=>{w.getSessionStreamState(r.agent||"",r.sessionId).then(e=>{ee(e.state,"seed")}).catch(()=>{}),A({keepOlder:!0,force:!0})},[ee,r.agent,r.sessionId,A])),t.useEffect(()=>{!_.current&&ke!=="running"&&!ae&&!i&&!W&&Y.length===0&&(N(),Z())},[ke,ae,i,W,Y.length,N,Z]),t.useLayoutEffect(()=>{const e=ye.current,s=Q.current;!e||!s||(ye.current=null,s.scrollTop=e.scrollTop+(s.scrollHeight-e.scrollHeight))},[p?.turns.length]),t.useLayoutEffect(()=>{if(!V.current)return;const e=Q.current;e&&(V.current=!1,e.scrollTop=e.scrollHeight,requestAnimationFrame(()=>{G.current&&(e.scrollTop=e.scrollHeight)}))},[p,i]),t.useLayoutEffect(()=>{if(!I)return;const e=Q.current;e&&(e.scrollTop=e.scrollHeight)},[I]),t.useEffect(()=>{if(!p?.hasOlder||le||h)return;const e=Q.current;e&&e.scrollHeight<=e.clientHeight+ft&&je()},[p?.hasOlder,p?.turns.length,je,le,h]);const wt=t.useCallback(()=>{const e=Q.current;if(!e)return;const s=e.scrollHeight-e.scrollTop-e.clientHeight;G.current=s<=ar,e.scrollTop<=ft&&je()},[je]),ze=i?.model||r.model||se||null,We=Ht(r.agent||"",i?.effort||r.thinkingEffort||T||null,r.workflowEnabled??E?.workflowEnabled)||null,at=ze?Ut(ze):null,Ye=Dt(r,{streaming:ae,hasLiveStream:!!i,streamPhase:W,queuedTaskCount:Y.length}),R=p?.turns||[],Xe=t.useMemo(()=>{if(!P.length||!R.length)return!1;const e=R[R.length-1];return!e.user||!Oe(e.user.text,I)?!1:e.user.blocks.filter(o=>o.type==="image").length<P.length},[R,I,P.length]),ot=t.useMemo(()=>{let e=R;if(Xe){const te=e[e.length-1];e=[...e.slice(0,-1),{...te,user:null}]}if(!i||!e.length)return e;const s=e[e.length-1];if(!s.assistant)return e;const o=I??(i.question||null),u=(i.text||"").trim(),c=s.assistant.text?.trim()||"";return(o!=null?Oe(s.user?.text,o):!!c&&!!u&&(u.startsWith(c)||c.startsWith(u)))?[...e.slice(0,-1),{...s,assistant:null}]:e},[R,i,I,Xe]);return n.jsxs("div",{className:"flex flex-col h-full overflow-hidden",children:[n.jsx("div",{ref:Q,onScroll:wt,className:"flex-1 overflow-y-auto overscroll-contain",children:le&&!I&&!P.length&&!i?n.jsx("div",{className:"flex items-center justify-center py-20",children:n.jsx(Me,{className:"h-5 w-5 text-fg-4"})}):ot.length===0&&!I&&!P.length&&!i&&!Ye?n.jsx("div",{className:"py-20 text-center text-[13px] text-fg-5",children:f("hub.noMessages")}):n.jsxs("div",{className:"max-w-[900px] mx-auto px-6 py-6 space-y-0",children:[(p?.hasOlder||h)&&n.jsxs("div",{className:"mb-4 flex items-center justify-center gap-2 text-[11px] text-fg-5",children:[h?n.jsx(Me,{className:"h-3 w-3 text-fg-5"}):n.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-fg-5/35"}),n.jsx("span",{children:f(h?"hub.loadingOlderTurns":"hub.loadOlderTurnsHint")})]}),r.migratedFrom?.kind==="fork"&&r.migratedFrom.sessionId&&n.jsxs("button",{type:"button",onClick:()=>v?.({agent:r.migratedFrom.agent||r.agent||"",sessionId:r.migratedFrom.sessionId,workdir:d}),className:"mb-4 inline-flex items-center gap-1.5 rounded-md border border-edge bg-panel-alt px-2.5 py-1 text-[11px] text-fg-5 transition hover:border-edge-h hover:text-fg-2",title:`#${r.migratedFrom.sessionId.slice(0,8)}`,children:[n.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[n.jsx("circle",{cx:"6",cy:"6",r:"2"}),n.jsx("circle",{cx:"18",cy:"6",r:"2"}),n.jsx("circle",{cx:"12",cy:"20",r:"2"}),n.jsx("path",{d:"M6 8v3a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3V8"}),n.jsx("path",{d:"M12 14v4"})]}),n.jsx("span",{children:f("hub.forkBadge")}),n.jsxs("span",{className:"font-mono",children:["#",r.migratedFrom.sessionId.slice(0,8)]}),typeof r.migratedFrom.forkedAtTurn=="number"&&n.jsxs("span",{className:"text-fg-5/70",children:["· ",f("hub.forkBadgeAt").replace("{turn}",String(r.migratedFrom.forkedAtTurn+1))]})]}),ot.map((e,s)=>{const o=(p?.startTurn||0)+s;return n.jsx(Xt,{turn:e,turnIndex:o,agent:r.agent||"",meta:K,model:at,effort:We,providerName:L,t:f,workdir:d,onResend:u=>{V.current=!0,st(u);const c=nt.current;w.sendSessionMessage(d,r.agent||"",r.sessionId,u,{model:c.model||ze||void 0,effort:c.effort||We||void 0}).then(x=>{x.ok&<()}).catch(()=>{N()})},onEdit:u=>tt(u),onFork:It?u=>{Fe(""),me({atTurn:u})}:void 0},`${p?.startTurn||0}:${s}`)}),Ye&&n.jsx("div",{className:"mb-5 animate-in",children:n.jsx(Gt,{detail:Ye,t:f})}),(I||P.length>0)&&(Xe||!(I&&R.length>0&&Oe(R[R.length-1]?.user?.text,I)))&&n.jsxs("div",{className:"session-turn",children:[n.jsx(it,{text:I||"",blocks:P.map(e=>({type:"image",content:e})),t:f}),!i&&n.jsx("div",{className:"mt-3 mb-5 animate-in",children:n.jsx(Vt,{className:"text-fg-5"})})]}),i&&dt(i)&&!I&&i.question&&!(R.length>0&&Oe(R[R.length-1]?.user?.text,i.question))&&n.jsx("div",{className:"session-turn",children:n.jsx(it,{text:i.question,t:f})}),i&&dt(i)&&n.jsxs("div",{className:"mb-6",children:[n.jsx(Jt,{agent:r.agent||"",meta:K,model:at,effort:We,providerName:L,previewMeta:i.previewMeta,liveStartedAt:i.phase==="streaming"?i.startedAt??null:null}),n.jsx(Zt,{stream:i,t:f,workdir:d})]}),n.jsx("div",{className:"h-4"})]})}),n.jsx(er,{session:r,workdir:d,onStreamQueued:lt,onSendStart:st,onSendTaskAssigned:yt,onSessionChange:v,t:f,streamPhase:W,streamTaskId:ht,queuedTaskIds:Y,queuedTasks:xt,pendingQueuedSends:et,onRecall:Tt,onSteer:Rt,onStopAll:jt,editDraft:St,onEditDraftConsumed:()=>tt(null),onSelectionChange:bt}),be&&n.jsxs(mt,{open:!0,onClose:()=>{U||me(null)},children:[n.jsx(gt,{title:f("hub.forkPromptTitle"),description:f("hub.forkPromptHint"),onClose:()=>{U||me(null)}}),n.jsx("textarea",{autoFocus:!0,value:ge,disabled:U,onChange:e=>Fe(e.target.value),onKeyDown:e=>{e.key==="Enter"&&(e.metaKey||e.ctrlKey)&&ge.trim()&&!U&&(e.preventDefault(),Ue.current?.())},placeholder:f("hub.forkPromptPlaceholder"),className:"w-full min-h-[120px] resize-y rounded-md border border-edge bg-panel-alt px-3 py-2 text-[13px] leading-relaxed text-fg outline-none focus:border-edge-h"}),n.jsxs("div",{className:"mt-4 flex items-center justify-end gap-2",children:[n.jsx(Ee,{variant:"ghost",disabled:U,onClick:()=>me(null),children:f("modal.cancel")}),n.jsx(Ee,{variant:"primary",disabled:U||!ge.trim(),onClick:()=>{Ue.current?.()},children:f(U?"hub.forkSubmitting":"hub.forkSubmit")})]})]}),O&&ue.length>0&&n.jsx(tr,{snapshot:ue[ue.length-1]},ue[ue.length-1].promptId)]})});export{vr as SessionPanel};
|
|
1
|
+
import{r as t,j as n}from"./react-vendor-C7Sl8SE7.js";import{c as Mt,I as Et,S as Me,m as Ee,a as w,u as ut,d as Lt,g as Ct,l as Pt,e as qt,j as Ft,f as Ht,s as Ut,Y as Dt}from"./index-Dp_KlJM9.js";import{s as Qt,l as _t,n as ct,m as $t,a as Bt,o as Kt,d as zt,b as Wt,p as Yt,c as Oe,T as Xt,R as Gt,U as it,e as Vt,f as dt,g as Jt,L as Zt,I as er}from"./index-Cjaly0tB.js";import{M as mt,a as gt}from"./Modal-CzQbFS5c.js";import"./router-DHISdpPk.js";import"./Select-DE6cseW_.js";import"./DirBrowser-BsHjGC5A.js";import"./markdown-DxQYQFeH.js";import"./ExtensionsTab-BYoLkIki.js";function tr({snapshot:l}){const[r,d]=t.useState(l.currentIndex??0),[O,v]=t.useState(""),[k,g]=t.useState(!1),[M,S]=t.useState(null);t.useEffect(()=>{d(l.currentIndex??0),v(""),S(null)},[l.promptId,l.currentIndex]);const E=l.questions||[],T=E[r]||null,se=E.length,L=!!(T?.options&&T.options.length),f=L?!!T?.allowFreeform:!0,K=a=>{a&&(d(h=>h+1),v(""))},ke=async a=>{if(!k){g(!0),S(null);try{const h=await w.interactionSelectOption(l.promptId,a);if(!h.ok){S(h.error||"Failed to submit selection.");return}K(h.advanced)}catch(h){S(h?.message||"Network error.")}finally{g(!1)}}},C=async()=>{if(k)return;const a=O.trim();if(!a&&!T?.allowEmpty){S("Please enter a response.");return}g(!0),S(null);try{const h=await w.interactionSubmitText(l.promptId,a);if(!h.ok){S(h.error||"Failed to submit answer.");return}K(h.advanced)}catch(h){S(h?.message||"Network error.")}finally{g(!1)}},p=async()=>{if(!k){g(!0),S(null);try{const a=await w.interactionSkip(l.promptId);if(!a.ok){S(a.error||"Failed to skip.");return}K(a.advanced)}catch(a){S(a?.message||"Network error.")}finally{g(!1)}}},z=async()=>{if(!k){g(!0);try{await w.interactionCancel(l.promptId)}catch{}}},le=t.useMemo(()=>{const a=[];return l.hint&&a.push(l.hint),se>1&&a.push(`Question ${r+1} of ${se}`),a.join(" · ")||void 0},[l.hint,r,se]);return n.jsxs(mt,{open:!0,onClose:z,wide:L&&(T?.options?.length||0)>3,children:[n.jsx(gt,{title:l.title||"Pikiloom needs your input",description:le,onClose:z}),T?n.jsxs("div",{className:"space-y-4",children:[n.jsxs("div",{children:[n.jsx("div",{className:"text-xs font-medium uppercase tracking-wide text-fg-5",children:T.header||"Question"}),n.jsx("div",{className:"mt-1 whitespace-pre-wrap text-sm leading-relaxed text-fg",children:T.prompt})]}),L&&n.jsx("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-2",children:(T.options||[]).map(a=>n.jsxs("button",{type:"button",disabled:k,onClick:()=>ke(a.value||a.label),className:Mt("group rounded-lg border border-edge bg-panel-alt px-3 py-2 text-left text-sm transition","hover:border-control-border-h hover:bg-control-h hover:shadow-sm","focus:outline-none focus:ring-2 focus:ring-[var(--th-glow-a)]","disabled:cursor-not-allowed disabled:opacity-50"),children:[n.jsx("div",{className:"font-medium text-fg group-hover:text-fg",children:a.label}),a.description&&n.jsx("div",{className:"mt-0.5 text-xs leading-snug text-fg-4",children:a.description})]},a.value||a.label))}),f&&n.jsx("div",{children:n.jsx(Et,{value:O,onChange:a=>v(a.target.value),onKeyDown:a=>{a.key==="Enter"&&!a.shiftKey&&!k&&(a.preventDefault(),C())},placeholder:L?"Or type a custom answer…":"Type your answer…",disabled:k,autoFocus:!L})}),M&&n.jsx("div",{className:"rounded-md border border-red-300/40 bg-red-500/10 px-3 py-2 text-xs text-red-600",children:M}),n.jsxs("div",{className:"flex items-center justify-between gap-3",children:[n.jsx("div",{className:"text-xs text-fg-5",children:k?n.jsxs("span",{className:"inline-flex items-center gap-2",children:[n.jsx(Me,{})," Submitting…"]}):n.jsxs("span",{children:["Press ",n.jsx("kbd",{className:"rounded border border-edge bg-panel-alt px-1.5 py-0.5 text-[10px] uppercase",children:"Enter"})," to send"]})}),n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(Ee,{variant:"ghost",size:"sm",onClick:p,disabled:k,children:"Skip"}),f&&n.jsx(Ee,{variant:"primary",size:"sm",onClick:C,disabled:k||!O.trim()&&!T.allowEmpty,children:"Submit"})]})]})]}):n.jsxs("div",{className:"py-6 text-center text-sm text-fg-5",children:[n.jsx(Me,{className:"mr-2 inline-block"})," Waiting for the agent…"]})]})}function rr(l){return l.isNull?l.localStreamPending||l.holdsActiveState?"reject-null":"apply":(typeof l.updatedAt=="number"?l.updatedAt:0)<l.lastAppliedUpdatedAt?"reject-stale":"apply"}function nr(l,r){return typeof r!="number"?l:r>l?r:l}function sr(l,r){return!l||!l.length?[]:r.size?l.filter(d=>!r.has(d)):l.slice()}function lr(l,r,d,O){if(!l.size)return l;const v=new Set(r);let k=!1;const g=new Map;for(const[M,S]of l){if(d-S>O||!v.has(M)){k=!0;continue}g.set(M,S)}return k?g:l}const Ge=12,ft=160,ar=96,or=[],ur=[],cr=[],ir=20,dr=6e4,ne=new Map;function fr(l,r){return`${l}:${r}`}function mr(l,r){for(ne.delete(l),ne.set(l,r);ne.size>ir;)ne.delete(ne.keys().next().value)}const vr=t.memo(function({session:r,workdir:d,active:O=!0,onSessionChange:v,initialPendingPrompt:k,initialPendingImageUrls:g,onPendingPromptConsumed:M}){const S=ut(e=>e.locale),E=ut(e=>e.agentStatus?.agents?.find(s=>s.agent===r.agent)??null),T=E?.selectedEffort??null,se=E?.selectedModel??null,L=E?.byokProviderName??null,f=t.useMemo(()=>Lt(S),[S]),K=Ct(r.agent||""),ke=Pt(r),C=!!k||!!(g&&g.length),[p,z]=t.useState(null),[le,a]=t.useState(!C),[h,Ve]=t.useState(!1),[i,F]=t.useState(null),[ae,oe]=t.useState(!1),[W,Le]=t.useState(null),[pt,Je]=t.useState(0),[ht,Ce]=t.useState(null),[Y,Se]=t.useState([]),[xt,Ie]=t.useState([]),[ue,Pe]=t.useState([]),[I,ce]=t.useState(k||null),[P,ie]=t.useState(g||[]),[kt,de]=t.useState(null),X=t.useRef(null);X.current=kt;const Ze=t.useRef(I);Ze.current=I;const[et,H]=t.useState([]),qe=t.useRef([]);qe.current=et;const fe=t.useRef(null),[St,tt]=t.useState(null),[be,me]=t.useState(null),[ge,Fe]=t.useState(""),[U,He]=t.useState(!1),It=!!E?.capabilities?.fork,Ue=t.useRef(null),q=t.useRef(g||[]),D=t.useRef(i),De=t.useRef(ae);D.current=i,De.current=ae;const Qe=t.useRef(Y);Qe.current=Y;const rt=t.useRef(W);rt.current=W;const Q=t.useRef(null),ye=t.useRef(null),G=t.useRef(!0),V=t.useRef(!1),ve=t.useRef(null),_e=t.useRef(!1),_=t.useRef(C),pe=t.useRef(!1),J=t.useRef(!1),$e=t.useRef(!1),Be=t.useRef(!1),$=t.useRef(null),Te=t.useRef(0),he=t.useRef(new Map),nt=t.useRef({model:null,effort:null}),bt=t.useCallback(e=>{nt.current=e},[]);t.useEffect(()=>{$e.current||!C||($e.current=!0,k&&!I&&ce(k),g&&g.length&&!P.length&&(ie(g),q.current=g),a(!1),Je(e=>e+1),M?.())},[C,M]);const N=t.useCallback(()=>{ce(null),ie(e=>{for(const s of e)URL.revokeObjectURL(s);return[]}),q.current=[],de(null)},[]),Z=t.useCallback(()=>{H(e=>{if(!e.length)return e;for(const s of e)for(const o of s.imageUrls)URL.revokeObjectURL(o);return[]}),fe.current=null},[]),st=t.useCallback((e,s)=>{const o=Qt({streaming:De.current,liveStreamPhase:D.current?.phase??null,streamPhase:rt.current,queuedTaskCount:Qe.current.length,pendingQueuedCount:qe.current.length}),u=s||[];if(o){const c=`local-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;fe.current=c,H(x=>[...x,{localId:c,taskId:null,prompt:e||"",imageUrls:u}]);return}D.current?.phase==="done"&&F(null);for(const c of q.current)URL.revokeObjectURL(c);fe.current=null,ce(e||null),ie(u),q.current=u,de(null)},[]),yt=t.useCallback(e=>{const s=fe.current;if(s){fe.current=null,H(o=>{const u=o.findIndex(x=>x.localId===s);if(u<0)return o;const c=o.slice();return c[u]={...c[u],taskId:e},c});return}de(e)},[]),vt=t.useCallback(async()=>{if(!be)return;const e=ge.trim();if(e){He(!0);try{const s=await w.forkSession(d,r.agent||"",r.sessionId,be.atTurn,e,{});if(!s.ok||!s.sessionKey){He(!1);return}const[o,u]=s.sessionKey.split(":");me(null),Fe(""),v?.({agent:o,sessionId:u,workdir:d})}finally{He(!1)}}},[be,ge,d,r.agent,r.sessionId,v]);Ue.current=vt;const Re=t.useCallback(async(e,s={})=>{try{const o=await _t({workdir:d,agent:r.agent||"",sessionId:r.sessionId,rich:!0,turnOffset:e.turnOffset,turnLimit:e.turnLimit,lastNTurns:e.lastNTurns},{force:s.force});return o.ok?ct(o):null}catch{return null}},[d,r.agent,r.sessionId]),A=t.useCallback(async({keepOlder:e,force:s=!1,scrollToBottom:o=!1})=>{const u=r.sessionId;if(ve.current===u)return!1;ve.current=u;try{const c=await Re({turnOffset:0,turnLimit:Ge},{force:s});if(!c||r.sessionId!==u)return!1;if(o&&(V.current=!0),z(x=>!x||!e?c:$t(x,c)),a(!1),pe.current&&(pe.current=!1,N()),J.current){const x=J.current;J.current=!1;const te=x!==!0?x.taskId:null;D.current&&(x===!0||D.current.taskId===te)&&F(null)}return!0}finally{ve.current===u&&(ve.current=null)}},[Re,N,r.sessionId]),je=t.useCallback(async()=>{if(!p?.hasOlder||_e.current)return;const e=Q.current;e&&(ye.current={scrollHeight:e.scrollHeight,scrollTop:e.scrollTop}),_e.current=!0,Ve(!0);try{const s=await Re({turnOffset:Math.max(0,p.totalTurns-p.startTurn),turnLimit:Ge});s?z(o=>o?Bt(o,s):s):ye.current=null}finally{_e.current=!1,Ve(!1)}},[Re,p]),we=t.useRef(null),ee=t.useCallback((e,s="ws")=>{if(rr({updatedAt:e?.updatedAt,isNull:!e,lastAppliedUpdatedAt:Te.current,localStreamPending:_.current,holdsActiveState:De.current||Qe.current.length>0})!=="apply")return;if(e&&(Te.current=nr(Te.current,e.updatedAt)),e?.sessionId&&e.sessionId!==r.sessionId&&(Be.current=!0,xe.current=`${r.agent}:${e.sessionId}`,v?.({agent:r.agent||"",sessionId:e.sessionId,workdir:d})),!e){const m=we.current;oe(!1),m==="streaming"?(pe.current=!0,J.current=!0,A({keepOlder:!0,force:!0,scrollToBottom:G.current})):F(null),_.current&&m!=="streaming"?A({keepOlder:!0,force:!0}):(m==="done"&&(N(),Z()),m!==null&&(_.current=!1)),Ce(null),Le(null),Se([]),Ie([]),Pe([]),we.current=null;return}Le(e.phase),Ce(e.taskId||null);const u=[];e.taskId&&u.push(e.taskId),Array.isArray(e.queuedTaskIds)&&u.push(...e.queuedTaskIds),he.current=lr(he.current,u,Date.now(),dr);const c=he.current,x=sr(e.queuedTaskIds,c),te=(Array.isArray(e.queuedTasks)?e.queuedTasks:[]).filter(m=>!c.has(m.taskId));if(Se(x.length?x:or),Ie(te.length?te:ur),Pe(Array.isArray(e.interactions)&&e.interactions.length?e.interactions:cr),Kt({pendingTaskId:X.current,streamTaskId:e.taskId||null,queuedTaskIds:e.queuedTaskIds})){const m=X.current,j=Ze.current||"",y=q.current;H(b=>b.some(re=>re.taskId===m)?b:[...b,{localId:`demote-${m}`,taskId:m,prompt:j,imageUrls:y}]),ce(null),ie([]),q.current=[],de(null),X.current=null}if(e.phase==="streaming"){if(F({taskId:e.taskId||null,phase:"streaming",text:e.text||"",thinking:e.thinking||"",activity:e.activity,plan:e.plan??null,model:e.model??null,effort:e.effort??null,previewMeta:e.previewMeta??null,subAgents:e.previewMeta?.subAgents??null,generatingImages:e.previewMeta?.generatingImages??0,artifacts:e.artifacts??null,startedAt:typeof e.startedAt=="number"?e.startedAt:null,error:null,question:e.question??null}),oe(!0),e.taskId&&e.taskId!==X.current){const m=qe.current,j=m.findIndex(y=>y.taskId===e.taskId);if(j>=0){const y=m[j];for(const b of q.current)URL.revokeObjectURL(b);ce(y.prompt||null),ie(y.imageUrls),q.current=y.imageUrls,de(e.taskId),H(b=>b.filter((re,B)=>B!==j))}}G.current&&(V.current=!0)}else if(e.phase==="queued")F(null),oe(!1);else if(e.phase==="done"){const m=zt(D.current?.taskId??null,e.taskId||null),j=x.length>0;if(m){oe(!1),F(B=>B?{...B,phase:"done",error:e.error??null}:e.error?{taskId:e.taskId||null,phase:"done",text:"",thinking:"",activity:"",plan:null,model:e.model??null,effort:e.effort??null,previewMeta:e.previewMeta??null,subAgents:e.previewMeta?.subAgents??null,generatingImages:e.previewMeta?.generatingImages??0,artifacts:e.artifacts??null,error:e.error}:B);const y=D.current,b=!!y&&Wt(y),re=!!e.incomplete&&b&&!j;if(we.current!=="done"){j||(pe.current=!0),J.current=re?!1:{taskId:e.taskId||null},A({keepOlder:!0,force:!0,scrollToBottom:G.current});const B=r.agent||"",Nt=r.sessionId,At=xe.current;$.current&&clearTimeout($.current),$.current=setTimeout(()=>{$.current=null,w.getSessionStreamState(B,Nt).then(Ot=>{xe.current===At&&Ke.current(Ot.state,"seed")}).catch(()=>{})},900)}}j||(_.current=!1)}const Ae=new Set;if(e.taskId&&Ae.add(e.taskId),Array.isArray(e.queuedTaskIds))for(const m of e.queuedTaskIds)Ae.add(m);H(m=>{let j=!1;const y=[];for(const b of m)if(!b.taskId||Ae.has(b.taskId))y.push(b);else{for(const re of b.imageUrls)URL.revokeObjectURL(re);j=!0}return j?y:m}),we.current=e.phase},[N,Z,A,r.sessionId,r.agent,v,d]),Ke=t.useRef(ee);Ke.current=ee;const lt=t.useCallback(()=>{_.current=!0,Je(e=>e+1)},[]);t.useEffect(()=>()=>{$.current&&(clearTimeout($.current),$.current=null)},[]);const Tt=t.useCallback(async e=>{try{he.current.set(e,Date.now()),await w.recallSessionMessage(e),X.current===e&&N(),H(s=>{let o=!1;const u=[];for(const c of s)if(c.taskId===e){for(const x of c.imageUrls)URL.revokeObjectURL(x);o=!0}else u.push(c);return o?u:s}),Se(s=>s.filter(o=>o!==e)),Ie(s=>s.filter(o=>o.taskId!==e)),Ce(s=>s===e?null:s)}catch{}},[N]),Rt=t.useCallback(async e=>{try{await w.steerSession(e)}catch{}},[]),jt=t.useCallback(async()=>{try{await w.stopSession(r.agent||"",r.sessionId)}catch{}},[r.agent,r.sessionId]),Ne=fr(r.agent||"",r.sessionId);t.useEffect(()=>{if(Be.current){Be.current=!1;let c=!1;return A({keepOlder:!0,force:!0}).finally(()=>{c||a(!1)}),()=>{c=!0}}let e=!1;const s=Yt({workdir:d,agent:r.agent||"",sessionId:r.sessionId,rich:!0,turnOffset:0,turnLimit:Ge},{allowStale:!0}),o=C&&!$e.current,u=s?.ok?ct(s):ne.get(Ne)||null;return a(o?!1:!u),z(u),F(null),oe(!1),Le(null),Se([]),Ie([]),Pe([]),Te.current=0,he.current=new Map,o||(N(),Z(),_.current=!1,pe.current=!1,J.current=!1),G.current=!0,V.current=!0,o||A({keepOlder:!1,force:!0}).finally(()=>{e||a(!1)}),()=>{e=!0}},[A,r.agent,r.sessionId,d,Ne,N,Z]),t.useEffect(()=>{p&&p.turns.length>0&&mr(Ne,p)},[Ne,p]),t.useEffect(()=>{O&&A({keepOlder:!0,force:!0})},[O,A]);const xe=t.useRef(`${r.agent}:${r.sessionId}`);xe.current=`${r.agent}:${r.sessionId}`,qt("stream-update",t.useCallback(e=>{e.key===xe.current&&ee(e.snapshot??null)},[ee])),t.useEffect(()=>{let e=!0;return w.getSessionStreamState(r.agent||"",r.sessionId).then(s=>{e&&Ke.current(s.state,"seed")}).catch(()=>{}),()=>{e=!1}},[r.agent,r.sessionId,pt]),Ft(t.useCallback(()=>{w.getSessionStreamState(r.agent||"",r.sessionId).then(e=>{ee(e.state,"seed")}).catch(()=>{}),A({keepOlder:!0,force:!0})},[ee,r.agent,r.sessionId,A])),t.useEffect(()=>{!_.current&&ke!=="running"&&!ae&&!i&&!W&&Y.length===0&&(N(),Z())},[ke,ae,i,W,Y.length,N,Z]),t.useLayoutEffect(()=>{const e=ye.current,s=Q.current;!e||!s||(ye.current=null,s.scrollTop=e.scrollTop+(s.scrollHeight-e.scrollHeight))},[p?.turns.length]),t.useLayoutEffect(()=>{if(!V.current)return;const e=Q.current;e&&(V.current=!1,e.scrollTop=e.scrollHeight,requestAnimationFrame(()=>{G.current&&(e.scrollTop=e.scrollHeight)}))},[p,i]),t.useLayoutEffect(()=>{if(!I)return;const e=Q.current;e&&(e.scrollTop=e.scrollHeight)},[I]),t.useEffect(()=>{if(!p?.hasOlder||le||h)return;const e=Q.current;e&&e.scrollHeight<=e.clientHeight+ft&&je()},[p?.hasOlder,p?.turns.length,je,le,h]);const wt=t.useCallback(()=>{const e=Q.current;if(!e)return;const s=e.scrollHeight-e.scrollTop-e.clientHeight;G.current=s<=ar,e.scrollTop<=ft&&je()},[je]),ze=i?.model||r.model||se||null,We=Ht(r.agent||"",i?.effort||r.thinkingEffort||T||null,r.workflowEnabled??E?.workflowEnabled)||null,at=ze?Ut(ze):null,Ye=Dt(r,{streaming:ae,hasLiveStream:!!i,streamPhase:W,queuedTaskCount:Y.length}),R=p?.turns||[],Xe=t.useMemo(()=>{if(!P.length||!R.length)return!1;const e=R[R.length-1];return!e.user||!Oe(e.user.text,I)?!1:e.user.blocks.filter(o=>o.type==="image").length<P.length},[R,I,P.length]),ot=t.useMemo(()=>{let e=R;if(Xe){const te=e[e.length-1];e=[...e.slice(0,-1),{...te,user:null}]}if(!i||!e.length)return e;const s=e[e.length-1];if(!s.assistant)return e;const o=I??(i.question||null),u=(i.text||"").trim(),c=s.assistant.text?.trim()||"";return(o!=null?Oe(s.user?.text,o):!!c&&!!u&&(u.startsWith(c)||c.startsWith(u)))?[...e.slice(0,-1),{...s,assistant:null}]:e},[R,i,I,Xe]);return n.jsxs("div",{className:"flex flex-col h-full overflow-hidden",children:[n.jsx("div",{ref:Q,onScroll:wt,className:"flex-1 overflow-y-auto overscroll-contain",children:le&&!I&&!P.length&&!i?n.jsx("div",{className:"flex items-center justify-center py-20",children:n.jsx(Me,{className:"h-5 w-5 text-fg-4"})}):ot.length===0&&!I&&!P.length&&!i&&!Ye?n.jsx("div",{className:"py-20 text-center text-[13px] text-fg-5",children:f("hub.noMessages")}):n.jsxs("div",{className:"max-w-[900px] mx-auto px-6 py-6 space-y-0",children:[(p?.hasOlder||h)&&n.jsxs("div",{className:"mb-4 flex items-center justify-center gap-2 text-[11px] text-fg-5",children:[h?n.jsx(Me,{className:"h-3 w-3 text-fg-5"}):n.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-fg-5/35"}),n.jsx("span",{children:f(h?"hub.loadingOlderTurns":"hub.loadOlderTurnsHint")})]}),r.migratedFrom?.kind==="fork"&&r.migratedFrom.sessionId&&n.jsxs("button",{type:"button",onClick:()=>v?.({agent:r.migratedFrom.agent||r.agent||"",sessionId:r.migratedFrom.sessionId,workdir:d}),className:"mb-4 inline-flex items-center gap-1.5 rounded-md border border-edge bg-panel-alt px-2.5 py-1 text-[11px] text-fg-5 transition hover:border-edge-h hover:text-fg-2",title:`#${r.migratedFrom.sessionId.slice(0,8)}`,children:[n.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[n.jsx("circle",{cx:"6",cy:"6",r:"2"}),n.jsx("circle",{cx:"18",cy:"6",r:"2"}),n.jsx("circle",{cx:"12",cy:"20",r:"2"}),n.jsx("path",{d:"M6 8v3a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3V8"}),n.jsx("path",{d:"M12 14v4"})]}),n.jsx("span",{children:f("hub.forkBadge")}),n.jsxs("span",{className:"font-mono",children:["#",r.migratedFrom.sessionId.slice(0,8)]}),typeof r.migratedFrom.forkedAtTurn=="number"&&n.jsxs("span",{className:"text-fg-5/70",children:["· ",f("hub.forkBadgeAt").replace("{turn}",String(r.migratedFrom.forkedAtTurn+1))]})]}),ot.map((e,s)=>{const o=(p?.startTurn||0)+s;return n.jsx(Xt,{turn:e,turnIndex:o,agent:r.agent||"",meta:K,model:at,effort:We,providerName:L,t:f,workdir:d,onResend:u=>{V.current=!0,st(u);const c=nt.current;w.sendSessionMessage(d,r.agent||"",r.sessionId,u,{model:c.model||ze||void 0,effort:c.effort||We||void 0}).then(x=>{x.ok&<()}).catch(()=>{N()})},onEdit:u=>tt(u),onFork:It?u=>{Fe(""),me({atTurn:u})}:void 0},`${p?.startTurn||0}:${s}`)}),Ye&&n.jsx("div",{className:"mb-5 animate-in",children:n.jsx(Gt,{detail:Ye,t:f})}),(I||P.length>0)&&(Xe||!(I&&R.length>0&&Oe(R[R.length-1]?.user?.text,I)))&&n.jsxs("div",{className:"session-turn",children:[n.jsx(it,{text:I||"",blocks:P.map(e=>({type:"image",content:e})),t:f}),!i&&n.jsx("div",{className:"mt-3 mb-5 animate-in",children:n.jsx(Vt,{className:"text-fg-5"})})]}),i&&dt(i)&&!I&&i.question&&!(R.length>0&&Oe(R[R.length-1]?.user?.text,i.question))&&n.jsx("div",{className:"session-turn",children:n.jsx(it,{text:i.question,t:f})}),i&&dt(i)&&n.jsxs("div",{className:"mb-6",children:[n.jsx(Jt,{agent:r.agent||"",meta:K,model:at,effort:We,providerName:L,previewMeta:i.previewMeta,liveStartedAt:i.phase==="streaming"?i.startedAt??null:null}),n.jsx(Zt,{stream:i,t:f,workdir:d})]}),n.jsx("div",{className:"h-4"})]})}),n.jsx(er,{session:r,workdir:d,onStreamQueued:lt,onSendStart:st,onSendTaskAssigned:yt,onSessionChange:v,t:f,streamPhase:W,streamTaskId:ht,queuedTaskIds:Y,queuedTasks:xt,pendingQueuedSends:et,onRecall:Tt,onSteer:Rt,onStopAll:jt,editDraft:St,onEditDraftConsumed:()=>tt(null),onSelectionChange:bt}),be&&n.jsxs(mt,{open:!0,onClose:()=>{U||me(null)},children:[n.jsx(gt,{title:f("hub.forkPromptTitle"),description:f("hub.forkPromptHint"),onClose:()=>{U||me(null)}}),n.jsx("textarea",{autoFocus:!0,value:ge,disabled:U,onChange:e=>Fe(e.target.value),onKeyDown:e=>{e.key==="Enter"&&(e.metaKey||e.ctrlKey)&&ge.trim()&&!U&&(e.preventDefault(),Ue.current?.())},placeholder:f("hub.forkPromptPlaceholder"),className:"w-full min-h-[120px] resize-y rounded-md border border-edge bg-panel-alt px-3 py-2 text-[13px] leading-relaxed text-fg outline-none focus:border-edge-h"}),n.jsxs("div",{className:"mt-4 flex items-center justify-end gap-2",children:[n.jsx(Ee,{variant:"ghost",disabled:U,onClick:()=>me(null),children:f("modal.cancel")}),n.jsx(Ee,{variant:"primary",disabled:U||!ge.trim(),onClick:()=>{Ue.current?.()},children:f(U?"hub.forkSubmitting":"hub.forkSubmit")})]})]}),O&&ue.length>0&&n.jsx(tr,{snapshot:ue[ue.length-1]},ue[ue.length-1].promptId)]})});export{vr as SessionPanel};
|