claude-simple 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{app.0.2.8.min.js → app.0.2.9.min.js} +101 -101
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/public/chat.js +9 -6
- package/public/shell/session-list.js +17 -4
- package/public/state.js +15 -0
- package/src/agents/grok.js +300 -37
- package/src/agents/models.js +2 -1
- package/src/app.js +12 -2
- /package/dist/{style.0.2.8.min.css → style.0.2.9.min.css} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var Ho=Object.defineProperty;var Ki=Object.getOwnPropertyDescriptor;var Vi=Object.getOwnPropertyNames;var Yi=Object.prototype.hasOwnProperty;var P=(e,t,s)=>()=>{if(s)throw s[0];try{return e&&(t=e(e=0)),t}catch(o){throw s=[o],o}};var jn=(e,t)=>{for(var s in t)Ho(e,s,{get:t[s],enumerable:!0})},_o=(e,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Vi(t))!Yi.call(e,a)&&a!==s&&Ho(e,a,{get:()=>t[a],enumerable:!(o=Ki(t,a))||o.enumerable});return e},js=(e,t,s)=>(_o(e,t,"default"),s&&_o(s,t,"default"));var n={};import*as Tl from"https://cdn.jsdelivr.net/gh/forechoandlook/mini-react@v0.1.13/dist/mini-react.min.js";var I=P(()=>{js(n,Tl)});var zo={};jn(zo,{AGENT_DEFAULT_MODEL:()=>qo,AGENT_LABELS:()=>B,AGENT_MODELS:()=>Ds,LOW_TURN_THRESHOLD:()=>Ps,activityHits:()=>ge,activityLoading:()=>Te,addCustomModel:()=>en,agentFilter:()=>se,agentsMeta:()=>Lt,chatDensity:()=>Ce,collapsedFolders:()=>St,ctx:()=>p,currentAgent:()=>w,currentEffort:()=>re,currentModel:()=>T,currentPermission:()=>ie,currentProject:()=>v,currentTab:()=>D,expandedFolders:()=>$t,favoritesOnly:()=>Fe,filesPath:()=>j,filesRoot:()=>G,filteredSessions:()=>qe,getCustomModels:()=>Dn,getDefaultModel:()=>ye,getEffortsForModel:()=>tn,getModelsForAgent:()=>Oe,getSavedModel:()=>Oo,getSessionMeta:()=>Et,gitRoot:()=>X,hubMachineReady:()=>ve,hubMode:()=>$,isProcessing:()=>Y,machinesList:()=>N,metaKey:()=>U,projectGroups:()=>tt,removeCustomModel:()=>Rs,selectedMachineId:()=>S,sessionDisplayTitle:()=>Ae,sessionFilter:()=>O,sessionMetaMap:()=>y,sessionSearch:()=>R,sessionSort:()=>Ro,sessionsData:()=>M,setAgent:()=>we,setChatDensity:()=>_s,setCurrentModel:()=>W,setSelectedMachine:()=>Q,showHiddenOnly:()=>Ue,sidebarView:()=>Me,timeRange:()=>le,viewingFile:()=>q,workspacesData:()=>H,wsStatus:()=>Ie});function Fo(){try{let e=JSON.parse(localStorage.getItem(Bo)||"{}");return e&&typeof e=="object"?e:{}}catch{return{}}}function Uo(e,t=p.sessionId,s=p.machineId){if(!t)return"";let o=(e||"claude").toLowerCase();return`${s||""}:${o}:${t}`}function Oo(e,t=p.sessionId,s=p.machineId){let o=Uo(e,t,s);if(!o)return null;let a=Fo()[o];return typeof a=="string"&&a.trim()?a:null}function W(e,t=w.peek(),s=p.sessionId,o=p.machineId){let a=String(e||"").trim();if(!a)return;let i=Uo(t,s,o);if(i){let r=Fo();r[i]=a,localStorage.setItem(Bo,JSON.stringify(r))}T.value=a}function Q(e){let t=e||null;S.value=t,p.machineId=t,t?localStorage.setItem("machineId",t):localStorage.removeItem("machineId")}function U(e,t,s){let o=`${e||"claude"}:${t}`;return s||p?.machineId?`${s||p.machineId}:${o}`:o}function Et(e,t,s){return y.peek()?.[U(e,t,s)]||{favorite:!1,notes:"",title:"",hidden:!1}}function Ae(e,{preferSnippet:t=!1}={}){if(!e)return"Session";if(t&&e.snippet)return e.snippet;let o=(Et(e.agent,e.sessionId,e.machineId).title||"").trim();return o||e.display||e.sessionId?.slice(0,8)||"Session"}function _s(e){let t=["clean","normal","full"].includes(e)?e:"normal";Ce.value=t,localStorage.setItem("chatDensity",t),document.getElementById("messages")?.setAttribute("data-density",t)}function Qi(e){return e?typeof e=="string"?{value:e,label:e}:e.value?{value:String(e.value),label:e.label||e.value,...Array.isArray(e.efforts)&&e.efforts.length?{efforts:e.efforts.map(String)}:{},...e.defaultEffort?{defaultEffort:String(e.defaultEffort)}:{}}:null:null}function Hs(){try{let e=localStorage.getItem(Wo);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function Go(e){localStorage.setItem(Wo,JSON.stringify(e))}function Dn(e){let t=(e||"claude").toLowerCase(),s=Hs()[t];return Array.isArray(s)?s.filter(Boolean).map(String):[]}function en(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim();if(!o)return!1;let a=Hs(),i=Array.isArray(a[s])?[...a[s]]:[];return i.includes(o)||i.push(o),a[s]=i,Go(a),!0}function Rs(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim(),a=Hs(),i=Array.isArray(a[s])?a[s].filter(r=>r!==o):[];return a[s]=i,Go(a),!0}function Oe(e){let t=(e||"claude").toLowerCase(),s=Lt.peek()?.defaults?.[t],o=s?.models?.length?s.models.map(Qi).filter(Boolean):(Ds[t]||Ds.claude).map(r=>({...r})),a=Dn(t),i=new Set(o.map(r=>r.value));for(let r of a){if(i.has(r)){o=o.map(c=>{if(c.value!==r)return c;let f=String(c.label||c.value);return{...c,custom:!0,label:f.includes("\u2605")?f:`${f} \u2605`}});continue}i.add(r),o.push({value:r,label:`${r} \u2605`,custom:!0})}return o}function ye(e){let t=(e||"claude").toLowerCase(),s=Lt.peek()?.defaults?.[t];return s?.model?String(s.model):qo[t]||Oe(t)[0]?.value||"claude-sonnet-4-5"}function tn(e,t){let o=Oe(e).find(i=>i.value===t);if(o?.efforts?.length)return o.efforts;let a=Lt.peek()?.defaults?.[(e||"claude").toLowerCase()];return a?.efforts?.length?a.efforts.map(String):["low","medium","high","xhigh","max"]}function we(e){let t=(e||"claude").toLowerCase();w.value=t,localStorage.setItem("agent",t),ie.value="bypassPermissions";let s=typeof document>"u"?null:document.getElementById("sel-permission");s&&(s.value=ie.peek());let o=Oo(t);o?T.value=o:W(ye(t),t)}function Zi(e,t){return!t||t==="all"?!0:(e.agent||"claude")===t}function er(e,t){let s=parseInt(t||"0",10)||0;if(s<=0)return!0;let o=e.updatedAt||0;if(typeof o=="string"){let a=Number(o);o=Number.isFinite(a)&&a>0?a<1e12?a*1e3:a:Date.parse(o)||0}else typeof o=="number"&&o>0&&o<1e12&&(o=o*1e3);return o>=Date.now()-s*864e5}function tr(e,t){if(!t)return!0;let s=y.value?.[U(e.agent,e.sessionId,e.machineId)];return[e.display,e.cwd,e.projectName,e.agent,e.sessionId,e.snippet,e.machineId,s?.notes,s?.title].filter(Boolean).join(" ").toLowerCase().includes(t)}function Ns(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}var M,H,O,R,Ro,$t,St,j,q,v,D,Y,Ie,Bo,Xi,w,T,re,ie,G,X,Lt,Me,se,le,ge,Te,y,Fe,Ue,Ps,Ce,$,N,S,ve,p,B,Ds,qo,Wo,qe,tt,C=P(()=>{I();M=(0,n.signal)([]),H=(0,n.signal)([]),O=(0,n.signal)(null),R=(0,n.signal)(""),Ro=(0,n.signal)("time"),$t=(0,n.signal)(new Set),St=(0,n.signal)(new Set),j=(0,n.signal)(""),q=(0,n.signal)(null),v=(0,n.signal)(null),D=(0,n.signal)("chat"),Y=(0,n.signal)(!1),Ie=(0,n.signal)("idle"),Bo="modelBySession",Xi=localStorage.getItem("agent")||"claude";w=(0,n.signal)(Xi),T=(0,n.signal)("claude-sonnet-4-5"),re=(0,n.signal)(""),ie=(0,n.signal)("bypassPermissions"),G=(0,n.signal)(""),X=(0,n.signal)(""),Lt=(0,n.signal)(null),Me=(0,n.signal)(localStorage.getItem("sidebarView")||"projects"),se=(0,n.signal)(localStorage.getItem("agentFilter")||"all"),le=(0,n.signal)(localStorage.getItem("timeRange")||"14"),ge=(0,n.signal)(null),Te=(0,n.signal)(!1),y=(0,n.signal)({}),Fe=(0,n.signal)(localStorage.getItem("favoritesOnly")==="1"),Ue=(0,n.signal)(localStorage.getItem("showHiddenOnly")==="1"),Ps=2,Ce=(0,n.signal)(localStorage.getItem("chatDensity")||"normal"),$=(0,n.signal)(!1),N=(0,n.signal)([]),S=(0,n.signal)(null),ve=(0,n.signal)(!1),p={token:localStorage.getItem("token"),sessionId:null,agent:null,machineId:null,ws:null,shellBubble:null,configDir:null};B={claude:"Claude",codex:"Codex",grok:"Grok"},Ds={claude:[{value:"claude-sonnet-4-5",label:"sonnet-4-5"},{value:"claude-sonnet-4-6",label:"sonnet-4-6"},{value:"claude-opus-4-5",label:"opus-4-5"},{value:"claude-haiku-4-5",label:"haiku-4-5"}],codex:[{value:"gpt-5.4",label:"gpt-5.4"},{value:"gpt-5.3",label:"gpt-5.3"},{value:"gpt-5.2",label:"gpt-5.2"},{value:"o3",label:"o3"},{value:"o4-mini",label:"o4-mini"},{value:"codex-mini-latest",label:"codex-mini"}],grok:[{value:"grok-4.5",label:"grok-4.5"},{value:"grok-4",label:"grok-4"},{value:"grok-3",label:"grok-3"},{value:"grok-3-mini",label:"grok-3-mini"}]},qo={claude:"claude-sonnet-4-5",codex:"gpt-5.4",grok:"grok-4.5"};Wo="customModelsByAgent";qe=(0,n.computed)(()=>{let e=O.value,t=R.value.toLowerCase().trim(),s=Ro.value,o=se.value,a=le.value,i=Fe.value,r=Ue.value,c=y.value,f=ge.value,l=f?.results?.length&&t?Ns(f.results):Ns(M.value);e&&(l=l.filter(u=>u&&(u.cwd===e||u.configDir===e)));let d=S.value;return $.value&&d&&(l=l.filter(u=>u&&(!u.machineId||u.machineId===d))),l=l.filter(u=>u&&Zi(u,o)&&er(u,a)),r?l=l.filter(u=>u&&c?.[U(u.agent,u.sessionId,u.machineId)]?.hidden):l=l.filter(u=>u&&!c?.[U(u.agent,u.sessionId,u.machineId)]?.hidden),i&&(l=l.filter(u=>u&&c?.[U(u.agent,u.sessionId,u.machineId)]?.favorite)),t&&!(f?.results&&f.q===t)&&(l=l.filter(u=>u&&tr(u,t))),l=[...l].sort((u,m)=>{let b=c?.[U(u.agent,u.sessionId,u.machineId)]?.favorite?1:0,g=c?.[U(m.agent,m.sessionId,m.machineId)]?.favorite?1:0;return b!==g?g-b:s==="project"&&(u.cwd||"").localeCompare(m.cwd||"")||m.updatedAt-u.updatedAt}),!e&&!t&&!i?l.slice(0,120):l}),tt=(0,n.computed)(()=>{let e=Ns(qe.value),t=new Map;for(let s of e){if(!s)continue;let o=s.machineId?`${s.machineId}::${s.cwd||"(no path)"}`:s.cwd||"(no path)";t.has(o)||t.set(o,{cwd:s.cwd||null,machineId:s.machineId||null,projectName:s.projectName||(s.cwd?s.cwd.split("/").filter(Boolean).pop():"(no path)"),updatedAt:0,agents:{},sessions:[],latest:null});let a=t.get(o);a.sessions.push(s),a.agents[s.agent||"claude"]=(a.agents[s.agent||"claude"]||0)+1,(s.updatedAt||0)>a.updatedAt&&(a.updatedAt=s.updatedAt,a.latest=s)}return[...t.values()].sort((s,o)=>o.updatedAt-s.updatedAt)})});function nn(e={}){return e.machineId!==void 0?e.machineId:p.machineId||S.peek()||null}function sr(e){let t=e.split("?")[0];return t==="/api/hub"||t==="/api/machines"||t==="/api/notifications"||t==="/api/notifications/read"||t==="/api/ai/notes"||t.startsWith("/api/ai/notes/")||t.startsWith("/api/auth/")}async function h(e,t,s,o,a={}){let i=nn(a),r={"Content-Type":"application/json",...p.token?{Authorization:`Bearer ${p.token}`}:{}};$.peek()&&i&&!sr(t)&&(r["X-Machine-Id"]=i);let c=a.etag===!0?`${p.token||""}:${i||""}:${t}`:a.etag||null;if(e.toUpperCase()==="GET"&&c){let d=Jo.get(c);d&&(r["If-None-Match"]=d)}let f=async()=>{let d=await fetch(t,{method:e,signal:o,headers:r,...s!==void 0?{body:JSON.stringify(s)}:{}});if(d.status===304)return Bs;let u=await d.json().catch(()=>({}));if(!d.ok)throw new Error(u.error||`HTTP ${d.status}`);if(c){let m=d.headers.get("ETag");m&&Jo.set(c,m)}return u};if(e.toUpperCase()!=="GET"||o||a.dedupe===!1)return f();let l=`${p.token||""}:${i||""}:${t}`;return nr.get(l,f)}function It(e){return p.ws?.readyState===WebSocket.OPEN?(p.ws.send(JSON.stringify(e)),!0):(e?.type==="ping"||e?.type==="pong"||e?.type==="subscribe"||Nn.push(e),!1)}function Ko(){for(;Nn.length&&p.ws?.readyState===WebSocket.OPEN;)p.ws.send(JSON.stringify(Nn.shift()))}function Vo(){Nn.length=0}function Yo(e={}){let t=new URLSearchParams(e);p.token&&t.set("token",p.token);let s=nn();return $.peek()&&s&&t.set("machine",s),t.toString()}function We(e={}){let t={...e};p.token&&(t.Authorization=`Bearer ${p.token}`);let s=nn();return $.peek()&&s&&(t["X-Machine-Id"]=s),t}async function Mt(){try{let e=await fetch("/api/hub");if(!e.ok)return $.value=!1,!1;let t=await e.json();if(t?.hub)return $.value=!0,t}catch{}return $.value=!1,!1}var nr,Jo,Bs,Nn,z=P(()=>{C();I();nr=(0,n.createFetch)({cache:!1,dedupe:!0,retry:0}),Jo=new Map,Bs=Symbol("not-modified");Nn=[]});function nt(e,t){e&&(t?e.setAttribute("inert",""):e.removeAttribute("inert"))}function Ct(e){return!e||e.classList.contains("hidden")?!0:e.style.display==="none"}function Z(){let e=typeof window<"u"&&window.matchMedia("(max-width: 640px)").matches,t=document.getElementById("sidebar");if(t){let o=!e||t.classList.contains("open");nt(t,!o)}nt(document.getElementById("welcome"),Ct(document.getElementById("welcome"))),nt(document.getElementById("auth-screen"),Ct(document.getElementById("auth-screen"))),nt(document.getElementById("chat-opts"),Ct(document.getElementById("chat-opts"))),nt(document.getElementById("machine-picker"),Ct(document.getElementById("machine-picker")));for(let o of["files","git","shell","memory"]){let a=document.getElementById(`tab-${o}`);nt(a,Ct(a))}let s=document.getElementById("tab-chat");s&&nt(s,Ct(s))}function sn(){let e=window.visualViewport,t=document.documentElement;if(!e)return;let s=e.height<window.innerHeight-80;t.classList.toggle("vv-keyboard",s),t.style.setProperty("--vvh",`${Math.round(e.height)}px`),t.style.setProperty("--vv-top",`${Math.round(e.offsetTop)}px`)}function ta(){Z(),sn();let e=window.visualViewport;e&&(e.addEventListener("resize",sn),e.addEventListener("scroll",sn)),window.addEventListener("resize",()=>{sn(),Z()}),window.addEventListener("orientationchange",()=>{setTimeout(()=>{sn(),Z()},250)})}var At=P(()=>{});function st(){try{let e=localStorage.getItem(na);return e?JSON.parse(e):null}catch{return null}}function Fs(e){try{let s={...st()||{},...e,updatedAt:Date.now()};localStorage.setItem(na,JSON.stringify(s))}catch{}}var na,Pn=P(()=>{na="lastSessionContext"});async function Us(){if(on&&!(typeof navigator>"u"||!navigator.wakeLock?.request)&&document.visibilityState==="visible"&&!ot)try{ot=await navigator.wakeLock.request("screen"),ot.addEventListener("release",()=>{ot=null,on&&document.visibilityState==="visible"&&setTimeout(()=>{Us().catch(()=>{})},500)})}catch{ot=null}}async function sa(){let e=ot;if(ot=null,!!e)try{await e.release()}catch{}}function oa(e){on=!!e,on?Us().catch(()=>{}):sa().catch(()=>{})}function aa(){typeof document>"u"||document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&on?Us().catch(()=>{}):document.visibilityState==="hidden"&&sa().catch(()=>{})})}var ot,on,ia=P(()=>{ot=null,on=!1});function A(e){if(e==null||e==="")return null;if(typeof e=="number")return!Number.isFinite(e)||e<=0?null:e<1e12?Math.round(e*1e3):Math.round(e);if(typeof e=="string"){let t=e.trim();if(/^\d+(\.\d+)?$/.test(t))return A(Number(t));let s=Date.parse(t);return Number.isNaN(s)?null:s}return null}function jt(e){let t=A(e);if(t==null)return"";let s=Date.now()-t;return s<0?new Date(t).toLocaleDateString():s<6e4?"just now":s<36e5?`${Math.floor(s/6e4)}m ago`:s<864e5?`${Math.floor(s/36e5)}h ago`:s<7*864e5?`${Math.floor(s/864e5)}d ago`:new Date(t).toLocaleDateString()}function at(e,t=!0){let s=e||"claude",a={claude:"bg-orange-500/15 text-orange-400",codex:"bg-emerald-500/15 text-emerald-400",grok:"bg-sky-500/15 text-sky-400"}[s]||"bg-base-300 text-base-content/50",i=t?s==="claude"?"CC":s==="codex"?"CX":s==="grok"?"GX":s.slice(0,2).toUpperCase():B[s]||s;return`<span class="text-[9px] px-1 py-0.5 rounded font-mono font-semibold flex-shrink-0 ${a}" title="${(0,n.esc)(B[s]||s)}">${i}</span>`}function ra(e){return Object.entries(e||{}).filter(([,t])=>t>0).map(([t,s])=>`${at(t)}<span class="text-[9px] text-base-content/40 -ml-0.5">${s}</span>`).join("")}function it(e){if(!e)return"";let t="",s=e.split("/").filter(Boolean);return s.length<=3?e:"\u2026/"+s.slice(-2).join("/")}var Dt=P(()=>{I();C()});function ir(e){let t=A(e);if(t==null)return"";let s=new Date(t);return Number.isNaN(s.getTime())?"":s.toLocaleString()}function la(){let e=(0,n.$)("notifications-badge");if(e){if(!rt){e.classList.add("hidden"),e.textContent="0";return}e.classList.remove("hidden"),e.textContent=rt>99?"99+":String(rt)}}function pa(){let e=(0,n.$)("notifications-menu"),t=(0,n.$)("btn-notifications"),s=(0,n.$)("topbar");if(!e||!t||!s)return;let o=t.getBoundingClientRect(),a=s.getBoundingClientRect(),i=Math.min(416,window.innerWidth-16),r=Math.max(8,Math.min(window.innerWidth-i-8,o.right-i));e.style.top=`${Math.round(a.bottom+8)}px`,e.style.left=`${Math.round(r)}px`,e.style.width=`${Math.round(i)}px`}function an(){let e=(0,n.$)("notifications-menu-list"),t=(0,n.$)("notifications-menu-empty");if(!(!e||!t)){if(!oe.length){e.innerHTML="",t.classList.remove("hidden"),la();return}t.classList.add("hidden"),e.innerHTML=oe.map(s=>`
|
|
1
|
+
var Ro=Object.defineProperty;var Vi=Object.getOwnPropertyDescriptor;var Yi=Object.getOwnPropertyNames;var Xi=Object.prototype.hasOwnProperty;var P=(e,t,s)=>()=>{if(s)throw s[0];try{return e&&(t=e(e=0)),t}catch(o){throw s=[o],o}};var Dn=(e,t)=>{for(var s in t)Ro(e,s,{get:t[s],enumerable:!0})},Ho=(e,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Yi(t))!Xi.call(e,a)&&a!==s&&Ro(e,a,{get:()=>t[a],enumerable:!(o=Vi(t,a))||o.enumerable});return e},Ds=(e,t,s)=>(Ho(e,t,"default"),s&&Ho(s,t,"default"));var n={};import*as Cl from"https://cdn.jsdelivr.net/gh/forechoandlook/mini-react@v0.1.13/dist/mini-react.min.js";var M=P(()=>{Ds(n,Cl)});var Jo={};Dn(Jo,{AGENT_DEFAULT_MODEL:()=>Wo,AGENT_LABELS:()=>B,AGENT_MODELS:()=>Ns,LOW_TURN_THRESHOLD:()=>_s,activityHits:()=>ge,activityLoading:()=>Te,addCustomModel:()=>tn,agentFilter:()=>oe,agentsMeta:()=>nt,chatDensity:()=>Ce,collapsedFolders:()=>Et,ctx:()=>u,currentAgent:()=>w,currentEffort:()=>O,currentModel:()=>E,currentPermission:()=>re,currentProject:()=>v,currentTab:()=>D,expandedFolders:()=>Lt,favoritesOnly:()=>Ue,filesPath:()=>j,filesRoot:()=>z,filteredSessions:()=>We,getCustomModels:()=>Nn,getDefaultEffort:()=>qe,getDefaultModel:()=>ye,getEffortsForModel:()=>nn,getModelsForAgent:()=>je,getSavedModel:()=>qo,getSessionMeta:()=>It,gitRoot:()=>Q,hubMachineReady:()=>ve,hubMode:()=>$,isProcessing:()=>X,machinesList:()=>N,metaKey:()=>U,projectGroups:()=>st,removeCustomModel:()=>Bs,selectedMachineId:()=>S,sessionDisplayTitle:()=>Ae,sessionFilter:()=>q,sessionMetaMap:()=>y,sessionSearch:()=>R,sessionSort:()=>Bo,sessionsData:()=>T,setAgent:()=>we,setChatDensity:()=>Hs,setCurrentModel:()=>G,setSelectedMachine:()=>Z,showHiddenOnly:()=>Oe,sidebarView:()=>Me,timeRange:()=>le,viewingFile:()=>W,workspacesData:()=>H,wsStatus:()=>Ie});function Uo(){try{let e=JSON.parse(localStorage.getItem(Fo)||"{}");return e&&typeof e=="object"?e:{}}catch{return{}}}function Oo(e,t=u.sessionId,s=u.machineId){if(!t)return"";let o=(e||"claude").toLowerCase();return`${s||""}:${o}:${t}`}function qo(e,t=u.sessionId,s=u.machineId){let o=Oo(e,t,s);if(!o)return null;let a=Uo()[o];return typeof a=="string"&&a.trim()?a:null}function G(e,t=w.peek(),s=u.sessionId,o=u.machineId){let a=String(e||"").trim();if(!a)return;let i=Oo(t,s,o);if(i){let r=Uo();r[i]=a,localStorage.setItem(Fo,JSON.stringify(r))}E.value=a}function Z(e){let t=e||null;S.value=t,u.machineId=t,t?localStorage.setItem("machineId",t):localStorage.removeItem("machineId")}function U(e,t,s){let o=`${e||"claude"}:${t}`;return s||u?.machineId?`${s||u.machineId}:${o}`:o}function It(e,t,s){return y.peek()?.[U(e,t,s)]||{favorite:!1,notes:"",title:"",hidden:!1}}function Ae(e,{preferSnippet:t=!1}={}){if(!e)return"Session";if(t&&e.snippet)return e.snippet;let o=(It(e.agent,e.sessionId,e.machineId).title||"").trim();return o||e.display||e.sessionId?.slice(0,8)||"Session"}function Hs(e){let t=["clean","normal","full"].includes(e)?e:"normal";Ce.value=t,localStorage.setItem("chatDensity",t),document.getElementById("messages")?.setAttribute("data-density",t)}function Zi(e){return e?typeof e=="string"?{value:e,label:e}:e.value?{value:String(e.value),label:e.label||e.value,...Array.isArray(e.efforts)&&e.efforts.length?{efforts:e.efforts.map(String)}:{},...e.defaultEffort?{defaultEffort:String(e.defaultEffort)}:{}}:null:null}function Rs(){try{let e=localStorage.getItem(Go);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function zo(e){localStorage.setItem(Go,JSON.stringify(e))}function Nn(e){let t=(e||"claude").toLowerCase(),s=Rs()[t];return Array.isArray(s)?s.filter(Boolean).map(String):[]}function tn(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim();if(!o)return!1;let a=Rs(),i=Array.isArray(a[s])?[...a[s]]:[];return i.includes(o)||i.push(o),a[s]=i,zo(a),!0}function Bs(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim(),a=Rs(),i=Array.isArray(a[s])?a[s].filter(r=>r!==o):[];return a[s]=i,zo(a),!0}function je(e){let t=(e||"claude").toLowerCase(),s=nt.peek()?.defaults?.[t],o=s?.models?.length?s.models.map(Zi).filter(Boolean):(Ns[t]||Ns.claude).map(r=>({...r})),a=Nn(t),i=new Set(o.map(r=>r.value));for(let r of a){if(i.has(r)){o=o.map(c=>{if(c.value!==r)return c;let f=String(c.label||c.value);return{...c,custom:!0,label:f.includes("\u2605")?f:`${f} \u2605`}});continue}i.add(r),o.push({value:r,label:`${r} \u2605`,custom:!0})}return o}function ye(e){let t=(e||"claude").toLowerCase(),s=nt.peek()?.defaults?.[t];return s?.model?String(s.model):Wo[t]||je(t)[0]?.value||"claude-sonnet-4-5"}function nn(e,t){let o=je(e).find(i=>i.value===t);if(o?.efforts?.length)return o.efforts;let a=nt.peek()?.defaults?.[(e||"claude").toLowerCase()];return a?.efforts?.length?a.efforts.map(String):["low","medium","high","xhigh","max"]}function qe(e,t){let s=(e||"claude").toLowerCase(),o=nt.peek()?.defaults?.[s];if(o?.effortDefault)return String(o.effortDefault);let i=je(s).find(r=>r.value===t);return i?.defaultEffort?String(i.defaultEffort):s==="grok"?"low":""}function we(e){let t=(e||"claude").toLowerCase();w.value=t,localStorage.setItem("agent",t),re.value="bypassPermissions";let s=typeof document>"u"?null:document.getElementById("sel-permission");s&&(s.value=re.peek());let o=qo(t);o?E.value=o:G(ye(t),t);let a=qe(t,E.peek());a?O.value=a:t!=="grok"&&(O.value="")}function er(e,t){return!t||t==="all"?!0:(e.agent||"claude")===t}function tr(e,t){let s=parseInt(t||"0",10)||0;if(s<=0)return!0;let o=e.updatedAt||0;if(typeof o=="string"){let a=Number(o);o=Number.isFinite(a)&&a>0?a<1e12?a*1e3:a:Date.parse(o)||0}else typeof o=="number"&&o>0&&o<1e12&&(o=o*1e3);return o>=Date.now()-s*864e5}function nr(e,t){if(!t)return!0;let s=y.value?.[U(e.agent,e.sessionId,e.machineId)];return[e.display,e.cwd,e.projectName,e.agent,e.sessionId,e.snippet,e.machineId,s?.notes,s?.title].filter(Boolean).join(" ").toLowerCase().includes(t)}function Ps(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}var T,H,q,R,Bo,Lt,Et,j,W,v,D,X,Ie,Fo,Qi,w,E,O,re,z,Q,nt,Me,oe,le,ge,Te,y,Ue,Oe,_s,Ce,$,N,S,ve,u,B,Ns,Wo,Go,We,st,C=P(()=>{M();T=(0,n.signal)([]),H=(0,n.signal)([]),q=(0,n.signal)(null),R=(0,n.signal)(""),Bo=(0,n.signal)("time"),Lt=(0,n.signal)(new Set),Et=(0,n.signal)(new Set),j=(0,n.signal)(""),W=(0,n.signal)(null),v=(0,n.signal)(null),D=(0,n.signal)("chat"),X=(0,n.signal)(!1),Ie=(0,n.signal)("idle"),Fo="modelBySession",Qi=localStorage.getItem("agent")||"claude";w=(0,n.signal)(Qi),E=(0,n.signal)("claude-sonnet-4-5"),O=(0,n.signal)(""),re=(0,n.signal)("bypassPermissions"),z=(0,n.signal)(""),Q=(0,n.signal)(""),nt=(0,n.signal)(null),Me=(0,n.signal)(localStorage.getItem("sidebarView")||"projects"),oe=(0,n.signal)(localStorage.getItem("agentFilter")||"all"),le=(0,n.signal)(localStorage.getItem("timeRange")||"14"),ge=(0,n.signal)(null),Te=(0,n.signal)(!1),y=(0,n.signal)({}),Ue=(0,n.signal)(localStorage.getItem("favoritesOnly")==="1"),Oe=(0,n.signal)(localStorage.getItem("showHiddenOnly")==="1"),_s=2,Ce=(0,n.signal)(localStorage.getItem("chatDensity")||"normal"),$=(0,n.signal)(!1),N=(0,n.signal)([]),S=(0,n.signal)(null),ve=(0,n.signal)(!1),u={token:localStorage.getItem("token"),sessionId:null,agent:null,machineId:null,ws:null,shellBubble:null,configDir:null};B={claude:"Claude",codex:"Codex",grok:"Grok"},Ns={claude:[{value:"claude-sonnet-4-5",label:"sonnet-4-5"},{value:"claude-sonnet-4-6",label:"sonnet-4-6"},{value:"claude-opus-4-5",label:"opus-4-5"},{value:"claude-haiku-4-5",label:"haiku-4-5"}],codex:[{value:"gpt-5.4",label:"gpt-5.4"},{value:"gpt-5.3",label:"gpt-5.3"},{value:"gpt-5.2",label:"gpt-5.2"},{value:"o3",label:"o3"},{value:"o4-mini",label:"o4-mini"},{value:"codex-mini-latest",label:"codex-mini"}],grok:[{value:"grok-4.5",label:"grok-4.5"},{value:"grok-4",label:"grok-4"},{value:"grok-3",label:"grok-3"},{value:"grok-3-mini",label:"grok-3-mini"}]},Wo={claude:"claude-sonnet-4-5",codex:"gpt-5.4",grok:"grok-4.5"};Go="customModelsByAgent";We=(0,n.computed)(()=>{let e=q.value,t=R.value.toLowerCase().trim(),s=Bo.value,o=oe.value,a=le.value,i=Ue.value,r=Oe.value,c=y.value,f=ge.value,l=f?.results?.length&&t?Ps(f.results):Ps(T.value);e&&(l=l.filter(p=>p&&(p.cwd===e||p.configDir===e)));let d=S.value;return $.value&&d&&(l=l.filter(p=>p&&(!p.machineId||p.machineId===d))),l=l.filter(p=>p&&er(p,o)&&tr(p,a)),r?l=l.filter(p=>p&&c?.[U(p.agent,p.sessionId,p.machineId)]?.hidden):l=l.filter(p=>p&&!c?.[U(p.agent,p.sessionId,p.machineId)]?.hidden),i&&(l=l.filter(p=>p&&c?.[U(p.agent,p.sessionId,p.machineId)]?.favorite)),t&&!(f?.results&&f.q===t)&&(l=l.filter(p=>p&&nr(p,t))),l=[...l].sort((p,m)=>{let b=c?.[U(p.agent,p.sessionId,p.machineId)]?.favorite?1:0,g=c?.[U(m.agent,m.sessionId,m.machineId)]?.favorite?1:0;return b!==g?g-b:s==="project"&&(p.cwd||"").localeCompare(m.cwd||"")||m.updatedAt-p.updatedAt}),!e&&!t&&!i?l.slice(0,120):l}),st=(0,n.computed)(()=>{let e=Ps(We.value),t=new Map;for(let s of e){if(!s)continue;let o=s.machineId?`${s.machineId}::${s.cwd||"(no path)"}`:s.cwd||"(no path)";t.has(o)||t.set(o,{cwd:s.cwd||null,machineId:s.machineId||null,projectName:s.projectName||(s.cwd?s.cwd.split("/").filter(Boolean).pop():"(no path)"),updatedAt:0,agents:{},sessions:[],latest:null});let a=t.get(o);a.sessions.push(s),a.agents[s.agent||"claude"]=(a.agents[s.agent||"claude"]||0)+1,(s.updatedAt||0)>a.updatedAt&&(a.updatedAt=s.updatedAt,a.latest=s)}return[...t.values()].sort((s,o)=>o.updatedAt-s.updatedAt)})});function sn(e={}){return e.machineId!==void 0?e.machineId:u.machineId||S.peek()||null}function or(e){let t=e.split("?")[0];return t==="/api/hub"||t==="/api/machines"||t==="/api/notifications"||t==="/api/notifications/read"||t==="/api/ai/notes"||t.startsWith("/api/ai/notes/")||t.startsWith("/api/auth/")}async function h(e,t,s,o,a={}){let i=sn(a),r={"Content-Type":"application/json",...u.token?{Authorization:`Bearer ${u.token}`}:{}};$.peek()&&i&&!or(t)&&(r["X-Machine-Id"]=i);let c=a.etag===!0?`${u.token||""}:${i||""}:${t}`:a.etag||null;if(e.toUpperCase()==="GET"&&c){let d=Ko.get(c);d&&(r["If-None-Match"]=d)}let f=async()=>{let d=await fetch(t,{method:e,signal:o,headers:r,...s!==void 0?{body:JSON.stringify(s)}:{}});if(d.status===304)return Fs;let p=await d.json().catch(()=>({}));if(!d.ok)throw new Error(p.error||`HTTP ${d.status}`);if(c){let m=d.headers.get("ETag");m&&Ko.set(c,m)}return p};if(e.toUpperCase()!=="GET"||o||a.dedupe===!1)return f();let l=`${u.token||""}:${i||""}:${t}`;return sr.get(l,f)}function Mt(e){return u.ws?.readyState===WebSocket.OPEN?(u.ws.send(JSON.stringify(e)),!0):(e?.type==="ping"||e?.type==="pong"||e?.type==="subscribe"||Pn.push(e),!1)}function Vo(){for(;Pn.length&&u.ws?.readyState===WebSocket.OPEN;)u.ws.send(JSON.stringify(Pn.shift()))}function Yo(){Pn.length=0}function Xo(e={}){let t=new URLSearchParams(e);u.token&&t.set("token",u.token);let s=sn();return $.peek()&&s&&t.set("machine",s),t.toString()}function Ge(e={}){let t={...e};u.token&&(t.Authorization=`Bearer ${u.token}`);let s=sn();return $.peek()&&s&&(t["X-Machine-Id"]=s),t}async function Tt(){try{let e=await fetch("/api/hub");if(!e.ok)return $.value=!1,!1;let t=await e.json();if(t?.hub)return $.value=!0,t}catch{}return $.value=!1,!1}var sr,Ko,Fs,Pn,J=P(()=>{C();M();sr=(0,n.createFetch)({cache:!1,dedupe:!0,retry:0}),Ko=new Map,Fs=Symbol("not-modified");Pn=[]});function ot(e,t){e&&(t?e.setAttribute("inert",""):e.removeAttribute("inert"))}function At(e){return!e||e.classList.contains("hidden")?!0:e.style.display==="none"}function ee(){let e=typeof window<"u"&&window.matchMedia("(max-width: 640px)").matches,t=document.getElementById("sidebar");if(t){let o=!e||t.classList.contains("open");ot(t,!o)}ot(document.getElementById("welcome"),At(document.getElementById("welcome"))),ot(document.getElementById("auth-screen"),At(document.getElementById("auth-screen"))),ot(document.getElementById("chat-opts"),At(document.getElementById("chat-opts"))),ot(document.getElementById("machine-picker"),At(document.getElementById("machine-picker")));for(let o of["files","git","shell","memory"]){let a=document.getElementById(`tab-${o}`);ot(a,At(a))}let s=document.getElementById("tab-chat");s&&ot(s,At(s))}function on(){let e=window.visualViewport,t=document.documentElement;if(!e)return;let s=e.height<window.innerHeight-80;t.classList.toggle("vv-keyboard",s),t.style.setProperty("--vvh",`${Math.round(e.height)}px`),t.style.setProperty("--vv-top",`${Math.round(e.offsetTop)}px`)}function na(){ee(),on();let e=window.visualViewport;e&&(e.addEventListener("resize",on),e.addEventListener("scroll",on)),window.addEventListener("resize",()=>{on(),ee()}),window.addEventListener("orientationchange",()=>{setTimeout(()=>{on(),ee()},250)})}var jt=P(()=>{});function at(){try{let e=localStorage.getItem(sa);return e?JSON.parse(e):null}catch{return null}}function Us(e){try{let s={...at()||{},...e,updatedAt:Date.now()};localStorage.setItem(sa,JSON.stringify(s))}catch{}}var sa,_n=P(()=>{sa="lastSessionContext"});async function Os(){if(an&&!(typeof navigator>"u"||!navigator.wakeLock?.request)&&document.visibilityState==="visible"&&!it)try{it=await navigator.wakeLock.request("screen"),it.addEventListener("release",()=>{it=null,an&&document.visibilityState==="visible"&&setTimeout(()=>{Os().catch(()=>{})},500)})}catch{it=null}}async function oa(){let e=it;if(it=null,!!e)try{await e.release()}catch{}}function aa(e){an=!!e,an?Os().catch(()=>{}):oa().catch(()=>{})}function ia(){typeof document>"u"||document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&an?Os().catch(()=>{}):document.visibilityState==="hidden"&&oa().catch(()=>{})})}var it,an,ra=P(()=>{it=null,an=!1});function A(e){if(e==null||e==="")return null;if(typeof e=="number")return!Number.isFinite(e)||e<=0?null:e<1e12?Math.round(e*1e3):Math.round(e);if(typeof e=="string"){let t=e.trim();if(/^\d+(\.\d+)?$/.test(t))return A(Number(t));let s=Date.parse(t);return Number.isNaN(s)?null:s}return null}function Dt(e){let t=A(e);if(t==null)return"";let s=Date.now()-t;return s<0?new Date(t).toLocaleDateString():s<6e4?"just now":s<36e5?`${Math.floor(s/6e4)}m ago`:s<864e5?`${Math.floor(s/36e5)}h ago`:s<7*864e5?`${Math.floor(s/864e5)}d ago`:new Date(t).toLocaleDateString()}function rt(e,t=!0){let s=e||"claude",a={claude:"bg-orange-500/15 text-orange-400",codex:"bg-emerald-500/15 text-emerald-400",grok:"bg-sky-500/15 text-sky-400"}[s]||"bg-base-300 text-base-content/50",i=t?s==="claude"?"CC":s==="codex"?"CX":s==="grok"?"GX":s.slice(0,2).toUpperCase():B[s]||s;return`<span class="text-[9px] px-1 py-0.5 rounded font-mono font-semibold flex-shrink-0 ${a}" title="${(0,n.esc)(B[s]||s)}">${i}</span>`}function la(e){return Object.entries(e||{}).filter(([,t])=>t>0).map(([t,s])=>`${rt(t)}<span class="text-[9px] text-base-content/40 -ml-0.5">${s}</span>`).join("")}function lt(e){if(!e)return"";let t="",s=e.split("/").filter(Boolean);return s.length<=3?e:"\u2026/"+s.slice(-2).join("/")}var Nt=P(()=>{M();C()});function rr(e){let t=A(e);if(t==null)return"";let s=new Date(t);return Number.isNaN(s.getTime())?"":s.toLocaleString()}function ca(){let e=(0,n.$)("notifications-badge");if(e){if(!ct){e.classList.add("hidden"),e.textContent="0";return}e.classList.remove("hidden"),e.textContent=ct>99?"99+":String(ct)}}function pa(){let e=(0,n.$)("notifications-menu"),t=(0,n.$)("btn-notifications"),s=(0,n.$)("topbar");if(!e||!t||!s)return;let o=t.getBoundingClientRect(),a=s.getBoundingClientRect(),i=Math.min(416,window.innerWidth-16),r=Math.max(8,Math.min(window.innerWidth-i-8,o.right-i));e.style.top=`${Math.round(a.bottom+8)}px`,e.style.left=`${Math.round(r)}px`,e.style.width=`${Math.round(i)}px`}function rn(){let e=(0,n.$)("notifications-menu-list"),t=(0,n.$)("notifications-menu-empty");if(!(!e||!t)){if(!ae.length){e.innerHTML="",t.classList.remove("hidden"),ca();return}t.classList.add("hidden"),e.innerHTML=ae.map(s=>`
|
|
2
2
|
<button type="button"
|
|
3
3
|
class="w-full text-left rounded-lg border px-3 py-2 transition-colors hover:bg-base-200/70 ${s.unread?"border-primary/35 bg-primary/5":"border-base-300 bg-base-100"}"
|
|
4
4
|
data-notification-id="${(0,n.esc)(s.id)}"
|
|
@@ -17,47 +17,47 @@ var Ho=Object.defineProperty;var Ki=Object.getOwnPropertyDescriptor;var Vi=Objec
|
|
|
17
17
|
<div class="flex items-center gap-2 mt-1 text-[10px] text-base-content/35">
|
|
18
18
|
${s.projectName?`<span class="font-mono truncate">${(0,n.esc)(s.projectName)}</span>`:""}
|
|
19
19
|
${s.machineId?`<span class="px-1 py-0.5 rounded bg-base-300 text-base-content/55 font-mono">${(0,n.esc)(s.machineId)}</span>`:""}
|
|
20
|
-
<span>${(0,n.esc)(
|
|
20
|
+
<span>${(0,n.esc)(rr(s.createdAt))}</span>
|
|
21
21
|
</div>
|
|
22
22
|
</div>
|
|
23
23
|
</div>
|
|
24
|
-
</button>`).join(""),
|
|
24
|
+
</button>`).join(""),ca()}}function dt(){(0,n.$)("notifications-menu")?.classList.add("hidden"),(0,n.$)("notifications-backdrop")?.classList.add("hidden"),(0,n.$)("btn-notifications")?.setAttribute("aria-expanded","false")}function lr(){pa(),(0,n.$)("notifications-menu")?.classList.remove("hidden"),(0,n.$)("notifications-backdrop")?.classList.remove("hidden"),(0,n.$)("btn-notifications")?.setAttribute("aria-expanded","true")}function fa(){let e=(0,n.$)("notifications-menu");e&&(e.classList.contains("hidden")?lr():dt())}function da(e){let t=new Map;for(let s of e||[])s?.id&&t.set(String(s.id),s);ae=[...t.values()].sort((s,o)=>(A(o.createdAt)||0)-(A(s.createdAt)||0)),ct=ae.reduce((s,o)=>s+(o.unread?1:0),0),rn()}async function Hn(){try{let e=await h("GET","/api/notifications?limit=80");ae=Array.isArray(e?.notifications)?e.notifications:[],ct=Number(e?.unreadCount)||ae.reduce((t,s)=>t+(s.unread?1:0),0),rn()}catch{ae=[],ct=0,rn()}}async function ua(e=null){let t=await h("POST","/api/notifications/read",e?.length?{ids:e}:{});ae=Array.isArray(t?.notifications)?t.notifications:ae.map(s=>!e||e.includes(s.id)?{...s,unread:!1}:s),ct=Number(t?.unreadCount)||ae.reduce((s,o)=>s+(o.unread?1:0),0),rn()}function cr(e){if(!(typeof Notification>"u")&&document.visibilityState!=="visible"&&Notification.permission==="granted")try{let t=new Notification(e.title||"Session done",{body:e.body||e.projectName||e.sessionId||"",tag:e.id});t.onclick=()=>{window.focus(),t.close()}}catch{}}function ma(e){if(!e?.id)return;if(ae.find(s=>s.id===e.id)){da([e,...ae.filter(s=>s.id!==e.id)]);return}da([e,...ae]),cr(e)}function ha(e={}){qs=typeof e.openSession=="function"?e.openSession:null,rn(),Hn(),typeof Notification<"u"&&Notification.permission==="default"&&document.addEventListener("click",()=>{try{Notification.requestPermission().catch(()=>{})}catch{}},{once:!0}),n.delegate.on("click","#notifications-backdrop",t=>{t.preventDefault(),t.stopPropagation(),dt()}),n.delegate.on("click","#btn-notifications-read-all",async t=>{t.preventDefault(),t.stopPropagation(),await ua()}),n.delegate.on("click","[data-notification-id]",async(t,s)=>{let o=s.dataset.notificationId;o&&(await ua([o]),dt(),!(!qs||!s.dataset.notificationSession)&&qs(s.dataset.notificationSession,s.dataset.notificationCwd||null,null,s.dataset.notificationAgent||"claude",s.dataset.notificationMachine||null))}),document.addEventListener("click",t=>{let s=(0,n.$)("notifications-menu"),o=(0,n.$)("btn-notifications"),a=t.target;!s||s.classList.contains("hidden")||s.contains(a)||o?.contains(a)||dt()}),window.addEventListener("resize",()=>{(0,n.$)("notifications-menu")&&!(0,n.$)("notifications-menu").classList.contains("hidden")&&pa()})}var ae,ct,qs,Ws=P(()=>{M();J();Nt();ae=[],ct=0,qs=null});function dr(){return B[w.peek()]||"Assistant"}function wa(e){return e.scrollHeight-e.scrollTop-e.clientHeight<80}function de(e,t){e&&(t||wa(e))&&(e.scrollTop=e.scrollHeight)}function Ve({sessionId:e=u.sessionId,agent:t=u.agent,machineId:s=u.machineId}={}){return e?`${s||""}:${t||"claude"}:${e}`:null}function Rt(e){let t=Ve(e),s=(0,n.$)("chat-input");!t||!s||(s.value?ut.set(t,s.value):ut.delete(t))}function Bt(e){let t=(0,n.$)("chat-input");t&&(t.value=ut.get(Ve(e))||"",_t(t),Pt(t.value))}function Ft(e){let t=Ve(e);if(!t)return;let s=_e.filter(a=>a.key===t);if(!s.length)return;_e=_e.filter(a=>a.key!==t);let o=ut.get(t)||"";ut.set(t,[o,...s.map(a=>a.text)].filter(Boolean).join(`
|
|
25
25
|
|
|
26
|
-
`))}function
|
|
26
|
+
`))}function Ut(){X.peek()&&(X.value=!1,Je())}function ur(){ba||(ba=!0,document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="visible"&&(Le=400,Rn({probe:!0}),u.ws?.readyState===WebSocket.OPEN&&u.sessionId))try{u.ws.send(JSON.stringify({type:"subscribe",sessionId:u.sessionId}))}catch{}}),window.addEventListener("online",()=>{Le=400,Rn({force:!0})}),window.addEventListener("pageshow",e=>{e.persisted?Rn({force:!0}):Rn({probe:!0})}))}function pn(){let e=(0,n.$)("conn-dot");if(!e)return;let t=Ie.peek();e.classList.remove("bg-success","bg-warning","bg-error","bg-base-content/30","animate-pulse"),t==="open"?(e.classList.add("bg-success"),e.title="\u5DF2\u8FDE\u63A5"):t==="connecting"||t==="reconnecting"?(e.classList.add("bg-warning","animate-pulse"),e.title=t==="connecting"?"\u8FDE\u63A5\u4E2D\u2026":"\u91CD\u8FDE\u4E2D\u2026"):t==="offline"?(e.classList.add("bg-error"),e.title="\u79BB\u7EBF"):(e.classList.add("bg-base-content/30"),e.title="\u672A\u8FDE\u63A5")}function Rn(e={}){let t=u.ws?.readyState;if(e.force){Le=400,He({quiet:!0});return}if(t===WebSocket.OPEN){if(e.probe&&Ne&&Date.now()-Ne>45e3)try{u.ws.close()}catch{}else if(e.probe&&u.ws.readyState===WebSocket.OPEN)try{u.ws.send(JSON.stringify({type:"ping"}))}catch{}return}t!==WebSocket.CONNECTING&&(Le=Math.min(Le,800),He({quiet:!0}))}function pr(){Pe||(Ie.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",pn(),Pe=setTimeout(()=>{Pe=null,He({quiet:!0})},Le),Le=Math.min(Math.round(Le*1.8),15e3))}function ka(){Fn&&(clearInterval(Fn),Fn=null)}function fr(e,t){ka(),Fn=setInterval(()=>{if(!(t!==cn||e.readyState!==WebSocket.OPEN)){if(Ne&&Date.now()-Ne>7e4){try{e.close()}catch{}return}if(!(typeof document<"u"&&document.visibilityState==="hidden")&&Ne&&Date.now()-Ne>4e4)try{e.send(JSON.stringify({type:"ping"}))}catch{}}},3e4)}function Je(){let e=X.peek()||!!v.peek()&&Ie.peek()==="open";aa(e)}function mr(){Le=400,Pe&&(clearTimeout(Pe),Pe=null),On=!1;let e=u.ws?.readyState;if(e===WebSocket.OPEN||e===WebSocket.CONNECTING)try{u.ws?.close()}catch{}He({quiet:!1}),x("\u6B63\u5728\u91CD\u65B0\u8FDE\u63A5\u5E76\u540C\u6B65\u2026")}function He(e={}){ur(),Pe&&(clearTimeout(Pe),Pe=null),e.quiet&&(On=!0);let t=u.machineId||(typeof localStorage<"u"?localStorage.getItem("machineId"):null);xa!==t&&(Yo(),xa=t);let s=++cn;try{u.ws?.close()}catch{}Ie.value="connecting",pn();let o=location.protocol==="https:"?"wss":"ws",a=new URLSearchParams;u.token&&a.set("token",u.token),t&&a.set("machine",t),u.sessionId&&a.set("sessionId",u.sessionId);let i=new WebSocket(`${o}://${location.host}/ws/chat?${a}`);u.ws=i,i.addEventListener("open",()=>{if(s===cn){if(Le=1e3,Ne=Date.now(),Ie.value="open",pn(),u.sessionId)try{i.send(JSON.stringify({type:"subscribe",sessionId:u.sessionId}))}catch{}Vo(),fr(i,s),Je(),Un&&!On&&x(t?`\u5DF2\u91CD\u8FDE \xB7 ${t}`:"\u5DF2\u91CD\u8FDE"),Un=!1,On=!1}}),i.addEventListener("message",r=>{if(s!==cn)return;let c;try{c=JSON.parse(r.data)}catch{return}if(c.type==="pong"){Ne=Date.now();return}if(c.type==="ping"){if(Ne=Date.now(),i.readyState===WebSocket.OPEN)try{i.send(JSON.stringify({type:"pong"}))}catch{}return}if(c.type==="run-status"){c.running?X.value=!0:X.peek()&&(X.value=!1,$a()),Je();return}Sa(c)}),i.addEventListener("close",()=>{s===cn&&(ka(),Un=!0,Ie.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",pn(),pr())}),i.addEventListener("error",()=>{})}function $a(){if(!_e.length||X.peek())return;let e=Ve(),t=_e.findIndex(a=>a.key===e);if(t<0)return;let[s]=_e.splice(t,1),o=(0,n.$)("chat-input");o&&(o.value=s.text,_t(o)),setTimeout(()=>{if(s.key!==Ve()||X.peek()){ut.set(s.key,s.text);return}fn()},0)}function dn(){X.value=!1,Je(),$a()}function Sa(e){if(!(e?.sessionId&&u.sessionId&&e.sessionId!==u.sessionId)){if(e.type==="batch"&&Array.isArray(e.items)){for(let t of e.items)Sa(t);return}if(e.type==="session-created"){let t=E.peek();u.sessionId=e.sessionId,e.agent&&e.agent!==w.peek()&&we(e.agent),G(t,e.agent||w.peek(),e.sessionId),document.dispatchEvent(new CustomEvent("sessions-changed"));return}if(e.type==="notification"&&e.notification){ma(e.notification);return}if(e.type==="result"){un(),ln(),pe();let t=e.usage;if(t){let s={input_tokens:t.inputTokens??t.input_tokens,output_tokens:t.outputTokens??t.output_tokens,cache_read_input_tokens:t.cacheReadInputTokens??t.cache_read_input_tokens,cache_creation_input_tokens:t.cacheCreationInputTokens??t.cache_creation_input_tokens,total_tokens:t.totalTokens??t.total_tokens,reasoning_tokens:t.reasoningTokens??t.reasoning_tokens,costUSD:t.costUSD??t.cost_usd};u.lastUsage=s,u.sessionId&&(u.lastUsageSessionId=u.sessionId),Ht(s)}e.is_error||x("\u2713 Done"),dn();return}if(e.type==="complete"){un(),ln(),pe(),!e.aborted&&e.agent==="claude"?x("\u2713 Done"):!e.aborted&&e.agent&&e.agent!=="claude"&&!e.error||(!e.aborted&&!e.agent?x("\u2713 Done"):e.aborted&&x("\u5DF2\u505C\u6B62")),dn();return}if(e.type==="error"){un(),ln(),pt("error","Error",e.message),dn();return}if(e.type==="shell-start"){u.shellBubble=null;return}if(e.type==="shell-output"){u.shellBubble||(u.shellBubble=Ar(e.stream==="stderr"?"shell-err":"shell")),jr(u.shellBubble,e.data);return}if(e.type==="shell-exit"){u.shellBubble=null,x(e.code===0?"\u2713 Exit 0":`\u2717 Exit ${e.code}${e.error?": "+e.error:""}`),dn();return}if(e.type==="assistant"){ln();for(let t of e.message?.content||[])t.type==="text"&&t.text?(pe(),pt("assistant",dr(),t.text,{ts:e.ts||Date.now()})):t.type==="tool_use"&&Vs(t,{ts:e.ts||Date.now()});return}if(e.type==="assistant_stream_start"){La(e.ts);return}if(e.type==="assistant_delta"){hr(e.data||"");return}if(e.type==="assistant_stream_end"){ln();return}if(e.type==="thought_stream_start"){Ea();return}if(e.type==="thought_delta"){br(e.data||"");return}if(e.type==="thought_stream_end"){un();return}if(e.type==="status"){let t=(0,n.$)("stream-status");if(t)t.textContent=e.message||"";else{let s=(0,n.$)("messages");s&&e.message&&(s.insertAdjacentHTML("beforeend",`<div id="stream-status" class="text-center text-[10px] text-base-content/35 py-0.5">${(0,n.esc)(e.message)}</div>`),de(s))}return}if(e.type==="permission_resolved"){let t=e.requestId||e.request_id;t&&(0,n.$)(`perm-${t}`)?.remove();return}(e.type==="permission_request"||e.request_id&&e.tool_name)&&Pr(e)}}function La(e){let t=(0,n.$)("messages");if(!t||(pe(),un(),$e&&t.contains($e)))return;let s=Gn(e||Date.now()),o=zn(e||Date.now());t.insertAdjacentHTML("beforeend",`
|
|
27
27
|
<div class="msg-row assistant px-2 live-stream" data-ts="${(0,n.esc)(o)}">
|
|
28
28
|
<div class="max-w-[88%] rounded-2xl rounded-tl-sm px-3 py-2 text-sm bg-base-200 break-words md">
|
|
29
29
|
<div class="msg-stream-body whitespace-pre-wrap"></div>
|
|
30
30
|
</div>
|
|
31
31
|
${s?`<div class="msg-ts" title="${(0,n.esc)(o)}">${(0,n.esc)(s)}</div>`:""}
|
|
32
|
-
</div>`),$e=t.lastElementChild,ce=$e.querySelector(".msg-stream-body"),(0,n.$)("stream-status")?.remove(),de(t,!0)}function
|
|
32
|
+
</div>`),$e=t.lastElementChild,ce=$e.querySelector(".msg-stream-body"),(0,n.$)("stream-status")?.remove(),de(t,!0)}function hr(e){e&&(ce||La(Date.now()),ce&&(ce.textContent+=e,de((0,n.$)("messages"),!0)))}function ln(){if(!$e||!ce){$e=null,ce=null;return}let e=ce.textContent||"";e.trim()?(ce.classList.remove("whitespace-pre-wrap"),ce.classList.add("md"),ce.innerHTML=Wn(e),Aa($e)):$e.remove(),$e=null,ce=null,(0,n.$)("stream-status")?.remove()}function Ea(){let e=(0,n.$)("messages");e&&(ze&&e.contains(ze)||(e.insertAdjacentHTML("beforeend",`
|
|
33
33
|
<div class="msg-row assistant px-2 thought-stream">
|
|
34
34
|
<div class="max-w-[88%] rounded-lg border border-base-300/60 bg-base-200/50 px-2.5 py-1.5 text-[11px] text-base-content/45">
|
|
35
35
|
<div class="font-medium text-base-content/35 mb-0.5">thinking\u2026</div>
|
|
36
36
|
<div class="thought-body font-mono whitespace-pre-wrap max-h-24 overflow-y-auto opacity-80"></div>
|
|
37
37
|
</div>
|
|
38
|
-
</div>`),
|
|
39
|
-
<div class="text-[10px] text-base-content/30 px-1 select-none">\u{1F4AD} thought ${e?`(${e} chars)`:""}</div>`}
|
|
40
|
-
Available: ${f}`:""}`),!0}let a=
|
|
38
|
+
</div>`),ze=e.lastElementChild,Se=ze.querySelector(".thought-body"),de(e,!0)))}function br(e){e&&(Se||Ea(),Se&&(Se.textContent+=e,Se.scrollTop=Se.scrollHeight,de((0,n.$)("messages"),!0)))}function un(){if(ze&&Se){let e=(Se.textContent||"").length;ze.innerHTML=`
|
|
39
|
+
<div class="text-[10px] text-base-content/30 px-1 select-none">\u{1F4AD} thought ${e?`(${e} chars)`:""}</div>`}ze=null,Se=null}function gr(e){let[t,...s]=e.slice(1).trim().split(/\s+/),o=s.join(" ");switch(t.toLowerCase()){case"agent":{if(!o)return x(`Current agent: ${w.peek()} \xB7 agents: claude | codex | grok`),!0;let a=o.toLowerCase();return["claude","codex","grok"].includes(a)?(a!==w.peek()?(u.sessionId=null,we(a),G(ye(a)),document.dispatchEvent(new CustomEvent("agent-changed")),x(`Agent \u2192 ${B[a]} \xB7 model ${E.peek()} \xB7 new session`)):x(`Agent already ${B[a]}`),!0):(x(`Unknown agent "${o}" \xB7 valid: claude | codex | grok`),!0)}case"model":{if(!o){let c=w.peek(),f=je(c).map(l=>l.value).join(" | ");return x(`Current model: ${E.peek()} (${c})${f?`
|
|
40
|
+
Available: ${f}`:""}`),!0}let a=xr[o.toLowerCase()]||o,i=w.peek()||"claude",r=je(i).some(c=>c.value===a);return r||tn(i,a),G(a),x(`Model set to ${a}${r?"":" (saved as custom \u2605)"}`),document.dispatchEvent(new CustomEvent("agent-changed")),!0}case"effort":{let a=nn(w.peek(),E.peek());return o?a.includes(o.toLowerCase())?(O.value=o.toLowerCase(),x(`Effort set to ${o.toLowerCase()}`),!0):(x(`Unknown effort level "${o}" \xB7 valid: ${a.join(" | ")}`),!0):(x(`Current effort: ${O.peek()||"(default)"} \xB7 levels: ${a.join(" | ")}`),!0)}case"clear":return qt(),u.sessionId=null,u.lastUsage=null,x("Cleared \xB7 new session"),!0;case"usage":return vr(),!0;case"help":return x(`Available slash commands:
|
|
41
41
|
/agent [claude|codex|grok]
|
|
42
42
|
/model [haiku|sonnet|opus|<model-id>]
|
|
43
43
|
/effort [low|medium|high|xhigh|max]
|
|
44
44
|
/usage
|
|
45
45
|
/clear
|
|
46
|
-
/help`),!0;default:return!1}}function
|
|
47
|
-
`)),
|
|
48
|
-
`)),(r.tokensUsed!=null||r.windowTokens!=null)&&
|
|
46
|
+
/help`),!0;default:return!1}}function te(e){if(e==null||Number.isNaN(Number(e)))return"\u2014";let t=Number(e);return t>=1e6?`${(t/1e6).toFixed(2)}M`:t>=1e3?`${(t/1e3).toFixed(1)}k`:String(Math.round(t))}async function vr(){let e=w.peek()||"claude",t=E.peek()||"\u2014",s=u.sessionId,o=[`Agent: ${B[e]||e}`,`Model: ${t}`,`Session: ${s?s.slice(0,8)+"\u2026":"(new \u2014 send a message first)"}`];if(u.lastUsage&&(!s||u.lastUsageSessionId===s)){let a=u.lastUsage;o.push(`Last turn: \u2191${te(a.input_tokens)} \u2193${te(a.output_tokens)}`+(a.cache_read_input_tokens?` \xB7 ${te(a.cache_read_input_tokens)} cached`:"")+(a.reasoning_tokens?` \xB7 ${te(a.reasoning_tokens)} reason`:"")+(a.total_tokens?` \xB7 \u03A3${te(a.total_tokens)}`:"")+(a.costUSD!=null?` \xB7 $${Number(a.costUSD).toFixed(4)}`:""))}if(!s){x(o.join(`
|
|
47
|
+
`)),Js("\u25C8 /usage \xB7 no session yet");return}x("Loading usage\u2026");try{let a=new URLSearchParams({sessionId:s,agent:e}),r=(await h("GET",`/api/usage?${a}`)).context||{};if(r.model&&(o[1]=`Model: ${r.model}`),r.title&&o.push(`Title: ${r.title}`),r.tokensUsed!=null||r.windowTokens!=null||r.usagePercent!=null){let f=r.tokensUsed!=null?te(r.tokensUsed):"\u2014",l=r.windowTokens!=null?te(r.windowTokens):"\u2014",d=r.usagePercent!=null?`${r.usagePercent}%`:"\u2014";o.push(`Context window: ${f} / ${l} (${d})`)}if(r.turnCount!=null&&o.push(`Turns: ${r.turnCount}`),r.toolCallCount!=null&&o.push(`Tools: ${r.toolCallCount}`),r.sessionDurationSeconds!=null){let f=Math.floor(r.sessionDurationSeconds/60),l=Math.round(r.sessionDurationSeconds%60);o.push(`Duration: ${f}m ${l}s`)}if(r.sessionTotals){let f=r.sessionTotals;o.push(`Session totals: \u2191${te(f.input_tokens)} \u2193${te(f.output_tokens)}`+(f.cache_read_input_tokens?` \xB7 ${te(f.cache_read_input_tokens)} cached`:"")+(f.total_tokens?` \xB7 \u03A3${te(f.total_tokens)}`:"")+(f.costUSD?` \xB7 $${Number(f.costUSD).toFixed(4)}`:""))}if(r.lastTurn&&!u.lastUsage){let f=r.lastTurn;o.push(`Last completed turn: \u2191${te(f.input_tokens)} \u2193${te(f.output_tokens)}`+(f.cache_read_input_tokens?` \xB7 ${te(f.cache_read_input_tokens)} cached`:"")+(f.costUSD!=null?` \xB7 $${Number(f.costUSD).toFixed(4)}`:""))}r.note&&o.push(r.note);let c=(0,n.$)("messages");if(c){let f=[...c.children];for(let l=f.length-1;l>=0;l--)if(f[l].textContent==="Loading usage\u2026"){f[l].remove();break}}x(o.join(`
|
|
48
|
+
`)),(r.tokensUsed!=null||r.windowTokens!=null)&&Ks({tokensUsed:r.tokensUsed,windowTokens:r.windowTokens,usagePercent:r.usagePercent,model:r.model||t,turnCount:r.turnCount,toolCallCount:r.toolCallCount}),r.sessionTotals?Ht(r.sessionTotals):r.lastTurn?Ht(r.lastTurn):u.lastUsage&&Ht(u.lastUsage)}catch(a){let i=(0,n.$)("messages");if(i){let r=[...i.children];for(let c=r.length-1;c>=0;c--)if(r[c].textContent==="Loading usage\u2026"){r[c].remove();break}}x(`${o.join(`
|
|
49
49
|
`)}
|
|
50
|
-
(usage fetch failed: ${a.message})`)}}function
|
|
50
|
+
(usage fetch failed: ${a.message})`)}}function fn(){let e=(0,n.$)("chat-input"),t=e?.value.trim();if(!t||!v.peek())return;if(X.peek()){if(w.peek()==="grok"&&u.sessionId){let o="grok",a=O.peek()||qe(o,E.peek())||"low",i=Mt({type:"command",cmd:"turn.start",agent:o,command:t,sessionId:u.sessionId,options:{agent:o,cwd:v.peek().path,sessionId:u.sessionId,configDir:u.configDir,model:E.peek(),effort:a,...re.peek()&&{permissionMode:re.peek()},...re.peek()==="bypassPermissions"&&{allowDangerouslySkipPermissions:!0}}});e.value="",_t(e),Pt(""),qn(),x(i?"\u5DF2\u52A0\u5165 Grok \u670D\u52A1\u7AEF\u961F\u5217\uFF0C\u5237\u65B0\u9875\u9762\u4E0D\u4F1A\u4E22\u5931":"\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u6D88\u606F\u5C06\u5728\u91CD\u8FDE\u540E\u53D1\u9001");return}_e.push({key:Ve(),text:t}),e.value="",_t(e),Pt(""),qn(),x(`\u5DF2\u6392\u961F\u4E0B\u4E00\u6761\uFF0C\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u540E\u53D1\u9001\uFF1A${t.length>80?t.slice(0,80)+"\u2026":t}`);return}if(e.value="",ut.delete(Ve()),_t(e),Pt(""),qn(),t.startsWith("/")&&gr(t))return;X.value=!0,Je();let s=Date.now();if(Ma(t))pt("shell","$ Shell",t.slice(1).trim(),{ts:s}),Mt({type:"command",cmd:"shell.exec",command:t.slice(1).trim(),cwd:v.peek().path})||x("\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u547D\u4EE4\u5DF2\u5165\u961F\uFF0C\u91CD\u8FDE\u540E\u53D1\u9001");else{pe(),pt("user","You",t,{ts:s});let o=w.peek()||"claude",a=O.peek()||qe(o,E.peek())||(o==="grok"?"low":""),i=re.peek();u.sessionId&&G(E.peek(),o,u.sessionId),Mt({type:"command",cmd:"turn.start",agent:o,command:t,sessionId:u.sessionId,options:{agent:o,cwd:v.peek().path,sessionId:u.sessionId,configDir:u.configDir,model:E.peek(),...a&&{effort:a},...i&&{permissionMode:i},...i==="bypassPermissions"&&{allowDangerouslySkipPermissions:!0}}})||x("\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u6D88\u606F\u5DF2\u5165\u961F\uFF0C\u91CD\u8FDE\u540E\u53D1\u9001")}}function Ia(){u.sessionId&&Mt({type:"command",cmd:"turn.interrupt",sessionId:u.sessionId}),_e=_e.filter(e=>e.key!==Ve()),dn()}function Pt(e){let t=Ma(e),s=(0,n.$)("chat-input"),o=(0,n.$)("send-btn");if(!s||!o)return;s.classList.toggle("textarea-warning",t),s.style.fontFamily=t?"monospace":"",o.classList.toggle("btn-warning",t),o.classList.toggle("btn-primary",!t),o.textContent=t?"Run":"Send";let a=B[w.peek()]||"agent",i=typeof window<"u"&&window.matchMedia("(max-width: 640px)").matches;t?s.placeholder=i?"Shell \u547D\u4EE4\u2026":"Shell command (without !)\u2026":s.placeholder=i?`\u95EE ${a}\u2026`:`Ask ${a}\u2026 or !cmd for shell`}function Ma(e){let t=String(e||"").trimStart();return t.startsWith("!")&&!/^!\[[^\]]*\]\([^)]+\)/.test(t)}function yr(){return typeof window<"u"&&window.matchMedia("(max-width: 640px)").matches,72}function _t(e){e.style.height="auto",e.style.height=Math.min(e.scrollHeight,yr())+"px"}function Gn(e){let t=A(e);if(t==null)return"";let s=new Date(t);if(Number.isNaN(s.getTime()))return"";let o=new Date,a=s.toDateString()===o.toDateString(),i=s.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1});return a?i:`${s.toLocaleDateString(void 0,{month:"numeric",day:"numeric"})} ${i}`}function zn(e){let t=A(e);return t==null?"":new Date(t).toISOString()}function $r(e,t,s){if(e==="system")return t;let o=Gn(s),a=zn(s),i=o?`<div class="msg-ts" title="${(0,n.esc)(a)}">${(0,n.esc)(o)}</div>`:"";return`<div class="msg-row ${e==="user"?"user":e==="shell"||e==="shell-err"?"assistant":e} px-2" data-ts="${(0,n.esc)(a)}">${t}${i}</div>`}function Sr(e,t,s){let o='<button class="msg-expand-btn text-[10px] text-primary/70 mt-1.5 block cursor-pointer hover:text-primary">\u25BC Show more</button>',a;switch(e){case"user":{let r=/!\[.*?\]\(.*?\)/.test(t)?Wn(t):null,c=t.length>wr,f=c?`<div class="msg-body">${r??(0,n.esc)(t.trimEnd())}</div>${o}`:r??(0,n.esc)(t.trimEnd());a=`<div class="max-w-[80%] rounded-2xl rounded-tr-sm px-3 py-2 text-sm bg-primary/15 border border-primary/20 text-base-content break-words${c?" msg-card":""}${r?" md":""}"${r?"":' style="white-space:pre-wrap"'}>${f}</div>`;break}case"assistant":{let i=t.length>kr,r=i?`<div class="msg-body">${Wn(t)}</div>${o}`:Wn(t);a=`<div class="max-w-[min(92%,52rem)] rounded-2xl rounded-tl-sm px-3.5 py-2.5 text-sm bg-base-200 border border-base-300/40 break-words md leading-relaxed${i?" msg-card":""}">${r}</div>`;break}case"error":a=`<div class="max-w-[88%] rounded-2xl rounded-tl-sm px-3 py-2 text-sm bg-error/10 border border-error/20 text-error break-words" style="white-space:pre-wrap">${(0,n.esc)(t)}</div>`;break;case"shell":case"shell-err":a=`<div class="w-full max-w-[96%] rounded-lg code-surface px-3 py-2 text-sm font-mono ${e==="shell-err"?"text-error":""} break-words" style="white-space:pre-wrap">${(0,n.esc)(t)}</div>`;break;case"system":return`<div class="text-center text-[11px] text-base-content/30 py-0.5 select-none">${(0,n.esc)(t)}</div>`;default:a=`<div class="rounded-lg px-3 py-2 text-sm bg-base-300 break-words" style="white-space:pre-wrap">${(0,n.esc)(t)}</div>`}return $r(e,a,s)}function pt(e,t,s,o={}){let a=(0,n.$)("messages");if(!a)return;let i=A(o.ts)??(e==="system"?null:Date.now());a.insertAdjacentHTML("beforeend",Sr(e,s,i)),Aa(a.lastElementChild),de(a,e==="user")}function x(e){pt("system","",e)}async function Lr(e,t){let s=t||`upload-${Date.now()}`,o=await Ta(e,s),a=Ge({"x-filename":s});delete a["Content-Type"],o?.type&&!a["Content-Type"]&&!a["content-type"]&&(a["Content-Type"]=o.type);let i=await fetch("/api/upload-image",{method:"POST",headers:a,body:o});if(!i.ok){let c=await i.json().catch(()=>({}));throw new Error(c.error||`Upload failed: ${i.status}`)}let r=await i.json();if(!r?.path)throw new Error("upload returned no path");return r.path}function Er(e,t){return e.length>=8&&e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71?"image/png":e.length>=3&&e[0]===255&&e[1]===216&&e[2]===255?"image/jpeg":e.length>=6&&String.fromCharCode(...e.slice(0,6))==="GIF87a"?"image/gif":e.length>=12&&String.fromCharCode(...e.slice(8,12))==="WEBP"?"image/webp":t||"image/png"}async function Ta(e,t){if(!e||!Gs({type:e.type,name:t}))return e;let s;try{s=(await e.slice(0,80).text()).trim()}catch{return e}if(!/^(?:data:image\/[a-z0-9.+-]+;base64,|iVBORw0KGgo|\/9j\/|R0lGOD|UklGR)/i.test(s))return e;let o;try{o=(await e.text()).trim()}catch{return e}let i=/^data:image\/[a-z0-9.+-]+;base64,([a-z0-9+/=\s]+)$/i.exec(o)?.[1]||o;if(!i||!/^[a-z0-9+/=\s]+$/i.test(i)||i.length%4===1)return e;try{let r=atob(i.replace(/\s/g,"")),c=Uint8Array.from(r,d=>d.charCodeAt(0)),f=Er(c,e.type);return f===(e.type||"image/png")&&!/^(image\/png|image\/jpeg|image\/gif|image\/webp)$/.test(f)?e:c.length>=3&&(c[0]===137&&c[1]===80&&c[2]===78||c[0]===255&&c[1]===216&&c[2]===255||String.fromCharCode(...c.slice(0,6))==="GIF87a"||String.fromCharCode(...c.slice(8,12))==="WEBP")?new Blob([c],{type:f}):e}catch{return e}}function Ir(e,t){if(!e)return;let s=e.selectionStart??e.value.length,o=e.selectionEnd??e.value.length,i=(s>0&&e.value[s-1]!==`
|
|
51
51
|
`?`
|
|
52
52
|
`:"")+t+`
|
|
53
|
-
`;e.value=e.value.slice(0,s)+i+e.value.slice(o),e.selectionStart=e.selectionEnd=s+i.length,e.dispatchEvent(new Event("input"))}function
|
|
53
|
+
`;e.value=e.value.slice(0,s)+i+e.value.slice(o),e.selectionStart=e.selectionEnd=s+i.length,e.dispatchEvent(new Event("input"))}function Gs(e){return e?e.type&&e.type.startsWith("image/")?!0:/\.(png|jpe?g|gif|webp|bmp|svg|heic|heif|avif)$/i.test(e.name||""):!1}function Mr(e,t){let s=e?.name||t.split("/").pop()||"file";if(Gs(e)){Bn+=1;let a=`img${Bn}`;return{ref:``,label:a,kind:"image"}}Bn+=1;let o=`file${Bn}`;return{ref:`[${o}](${t})`,label:o,kind:"file"}}function qn(){for(let e of Ke)if(e.previewUrl)try{URL.revokeObjectURL(e.previewUrl)}catch{}Ke.length=0,zs()}function Ot(){qn()}function zs(){let e=(0,n.$)("chat-attach-bar");if(e){if(!Ke.length){e.classList.add("hidden"),e.innerHTML="";return}e.classList.remove("hidden"),e.innerHTML=Ke.map((t,s)=>`
|
|
54
54
|
<div class="chat-thumb relative" title="${(0,n.esc)(t.ref||t.path)}">
|
|
55
55
|
${t.previewUrl?`<img src="${t.previewUrl}" alt="${(0,n.esc)(t.label||"img")}">`:`<span class="chat-thumb-path">${(0,n.esc)(t.label||t.name||"file")}</span>`}
|
|
56
56
|
<span class="chat-thumb-label">${(0,n.esc)(t.label||t.kind||"")}</span>
|
|
57
57
|
<button type="button" class="chat-thumb-x" data-rm-attach="${s}" aria-label="remove">\u2715</button>
|
|
58
|
-
</div>`).join("")}}async function
|
|
58
|
+
</div>`).join("")}}async function Tr(e){if(!e)return;let t=e.name||`upload-${Date.now()}`,s=await Ta(e,t),o=await Lr(s,t),{ref:a,label:i,kind:r}=Mr(e,o),c="";if(r==="image")try{c=URL.createObjectURL(s)}catch{}return Ke.push({path:o,ref:a,label:i,kind:r,name:t,previewUrl:c}),zs(),Ir((0,n.$)("chat-input"),a),o}async function Jn(e){let t=[...e||[]].filter(Boolean);if(!t.length)return;let s=(0,n.$)("chat-input");s&&(s.disabled=!0);try{for(let o of t)try{await Tr(o)}catch(a){x(`\u4E0A\u4F20\u5931\u8D25 ${o.name||"file"}: ${a.message}`)}}finally{s&&(s.disabled=!1,s.focus())}}function Cr(){let e=(0,n.$)("chat-file-input");if(e){e.value="",e.click();return}let t=document.createElement("input");t.type="file",t.accept="image/*,*/*",t.multiple=!0,t.addEventListener("change",()=>Jn(t.files)),t.click()}function Ca(){document.addEventListener("paste",async e=>{let t=(0,n.$)("chat-input");if(!t)return;let s=(0,n.$)("chat-composer");if(!(s&&(s.contains(document.activeElement)||document.activeElement===t))&&document.activeElement!==t)return;let a=[...e.clipboardData?.items||[]],i=[];for(let f of a)if(f.kind==="file"){let l=f.getAsFile();l&&i.push(l)}let r=i.filter(f=>Gs(f)),c=r.length?r:i;c.length&&(e.preventDefault(),await Jn(c))}),!ga&&(ga=!0,document.addEventListener("dragover",e=>{let t=(0,n.$)("chat-composer");!t||!e.dataTransfer?.types?.includes("Files")||!t.contains(e.target)&&e.target!==t||(e.preventDefault(),t.classList.add("chat-drop-active"))}),document.addEventListener("dragleave",e=>{let t=(0,n.$)("chat-composer");t&&(e.target===t||t.contains(e.target))&&(t.contains(e.relatedTarget)||t.classList.remove("chat-drop-active"))}),document.addEventListener("drop",async e=>{let t=(0,n.$)("chat-composer");if(!t||(t.classList.remove("chat-drop-active"),!t.contains(e.target)&&e.target!==t))return;let s=[...e.dataTransfer?.files||[]];s.length&&(e.preventDefault(),await Jn(s))}))}function De(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function Js(e){let t=(0,n.$)("messages");t&&(t.insertAdjacentHTML("beforeend",`<div class="token-bar select-none">
|
|
59
59
|
<span class="token-bar-mark">\u25C8</span><span class="token-bar-text">${(0,n.esc)(e)}</span>
|
|
60
|
-
</div>`),de(t))}function
|
|
60
|
+
</div>`),de(t))}function Ht(e){if(!e)return;let t=e.input_tokens??e.inputTokens??0,s=e.output_tokens??e.outputTokens??0,o=e.total_tokens??e.totalTokens??t+s,a=e.cache_read_input_tokens??e.cachedReadTokens?` \xB7 ${De(e.cache_read_input_tokens??e.cachedReadTokens)} cached`:"",i=e.cache_creation_input_tokens??e.cacheCreationInputTokens?` \xB7 ${De(e.cache_creation_input_tokens??e.cacheCreationInputTokens)} cache-write`:"",r=e.reasoning_tokens??e.reasoningTokens?` \xB7 ${De(e.reasoning_tokens??e.reasoningTokens)} reason`:"",c=e.costUSD??e.cost_usd,f=c!=null?` \xB7 $${Number(c).toFixed(4)}`:"",l=o?` \xB7 \u03A3${De(o)}`:"";Js(`\u2191${De(t)} \u2193${De(s)}${a}${i}${r}${l}${f}`)}function Ks(e){if(!e)return;let t=e.tokensUsed??e.contextTokensUsed,s=e.windowTokens??e.contextWindowTokens,o=e.usagePercent??e.contextWindowUsage;if(t==null&&s==null&&o==null)return;let a=[];t!=null&&s!=null?a.push(`context ${De(t)} / ${De(s)}`):t!=null&&a.push(`context ${De(t)}`),o!=null&&a.push(`${o}%`),e.model&&a.push(e.model),e.turnCount!=null&&a.push(`${e.turnCount} turns`),e.toolCallCount!=null&&a.push(`${e.toolCallCount} tools`),Js(`\u25A3 ${a.join(" \xB7 ")}`)}function qt(){let e=(0,n.$)("messages"),t=(0,n.$)("permission-requests");e&&(e.innerHTML=""),t&&(t.innerHTML=""),u.shellBubble=null,ke=null,$e=ce=null,ze=Se=null}function Ar(e){let t=(0,n.$)("messages");if(!t)return null;let s=e==="shell-err"?" text-error":"";return t.insertAdjacentHTML("beforeend",`<div class="mx-2 rounded-lg code-surface px-3 py-2 text-sm font-mono${s} whitespace-pre-wrap break-words"></div>`),de(t),t.lastElementChild}function jr(e,t){e&&(e.textContent+=t,de(e.closest("#messages")))}function Dr(e){let t=typeof e.input=="object"?JSON.stringify(e.input,null,2):String(e.input||""),o=((typeof e.input=="object"?Object.values(e.input).find(a=>typeof a=="string"&&a.trim()):t)||"").replace(/\n/g," ").slice(0,Ce.peek()==="full"?120:80);return{inputStr:t,preview:o}}function va(e,{inBatch:t=!1}={}){let{inputStr:s,preview:o}=Dr(e);return`<div class="tool-card${t?" tool-batch-item":""} cursor-pointer select-none px-2 py-1">
|
|
61
61
|
<div class="flex items-center gap-1.5 text-xs font-mono">
|
|
62
62
|
<span class="text-warning">\u26A1</span>
|
|
63
63
|
<span class="text-warning font-semibold">${(0,n.esc)(e.name||"tool")}</span>
|
|
@@ -65,21 +65,21 @@ Available: ${f}`:""}`),!0}let a=br[o.toLowerCase()]||o,i=w.peek()||"claude",r=Oe
|
|
|
65
65
|
<span class="tool-chevron text-[10px] text-base-content/40">\u25B6</span>
|
|
66
66
|
</div>
|
|
67
67
|
<div class="tool-detail">${(0,n.esc)(s)}</div>
|
|
68
|
-
</div>`}function
|
|
68
|
+
</div>`}function Nr(e){let t=[...new Set(e.names)],s=t.slice(0,4).join(", ")+(t.length>4?"\u2026":""),o=e.el.querySelector(".tool-batch-summary");o&&(o.innerHTML=`<span class="text-warning">\u26A1</span>
|
|
69
69
|
<span class="font-semibold text-base-content/70">${e.count} tool${e.count===1?"":"s"}</span>
|
|
70
70
|
<span class="text-base-content/40 truncate flex-1">${(0,n.esc)(s)}</span>
|
|
71
|
-
<span class="tool-chevron text-[10px] text-base-content/40">\u25B6</span>`)}function
|
|
71
|
+
<span class="tool-chevron text-[10px] text-base-content/40">\u25B6</span>`)}function pe(){ke=null}function Vs(e,t={}){let s=(0,n.$)("messages");if(!s)return;let o=Ce.peek()||"normal",a=A(t.ts);if(o==="clean"){if(!ke||!s.contains(ke.el)){let f=Gn(a),l=zn(a);s.insertAdjacentHTML("beforeend",`
|
|
72
72
|
<div class="msg-row assistant px-2" data-ts="${(0,n.esc)(l)}">
|
|
73
73
|
<div class="tool-batch w-full max-w-[96%] px-2 py-1.5">
|
|
74
74
|
<div class="tool-batch-summary flex items-center gap-1.5 text-xs font-mono"></div>
|
|
75
75
|
<div class="tool-batch-list"></div>
|
|
76
76
|
</div>
|
|
77
77
|
${f?`<div class="msg-ts" title="${(0,n.esc)(l)}">${(0,n.esc)(f)}</div>`:""}
|
|
78
|
-
</div>`),ke={el:s.lastElementChild.querySelector(".tool-batch"),names:[],count:0}}ke.names.push(e.name||"tool"),ke.count++,ke.el.querySelector(".tool-batch-list")?.insertAdjacentHTML("beforeend",
|
|
78
|
+
</div>`),ke={el:s.lastElementChild.querySelector(".tool-batch"),names:[],count:0}}ke.names.push(e.name||"tool"),ke.count++,ke.el.querySelector(".tool-batch-list")?.insertAdjacentHTML("beforeend",va(e,{inBatch:!0})),Nr(ke),de(s);return}ke=null;let i=Gn(a),r=zn(a);s.insertAdjacentHTML("beforeend",`
|
|
79
79
|
<div class="msg-row assistant px-2" data-ts="${(0,n.esc)(r)}">
|
|
80
|
-
<div class="w-full max-w-[96%]">${
|
|
80
|
+
<div class="w-full max-w-[96%]">${va(e)}</div>
|
|
81
81
|
${i?`<div class="msg-ts" title="${(0,n.esc)(r)}">${(0,n.esc)(i)}</div>`:""}
|
|
82
|
-
</div>`),de(s)}function
|
|
82
|
+
</div>`),de(s)}function Kn(){let e=(0,n.$)("messages");e&&e.setAttribute("data-density",Ce.peek()||"normal")}function Pr(e){let t=e.request_id||e.requestId;if(!t||(0,n.$)(`perm-${t}`))return;let s=e.tool_input?JSON.stringify(e.tool_input).slice(0,200):"";(0,n.$)("permission-requests")?.insertAdjacentHTML("beforeend",`
|
|
83
83
|
<div id="perm-${t}" class="perm-banner mx-3 mb-2 rounded-lg border border-warning/25 bg-warning/8 p-3">
|
|
84
84
|
<div class="text-xs text-warning font-semibold mb-1">\u26A0\uFE0F Permission Required</div>
|
|
85
85
|
<div class="font-mono text-xs text-base-content/60 break-all mb-2">
|
|
@@ -89,16 +89,16 @@ Available: ${f}`:""}`),!0}let a=br[o.toLowerCase()]||o,i=w.peek()||"claude",r=Oe
|
|
|
89
89
|
<button class="btn btn-success btn-xs" data-perm-id="${t}" data-perm-allow="1">Allow</button>
|
|
90
90
|
<button class="btn btn-error btn-xs" data-perm-id="${t}" data-perm-allow="0">Deny</button>
|
|
91
91
|
</div>
|
|
92
|
-
</div>`),(0,n.$)("messages").scrollTop=999999}function
|
|
92
|
+
</div>`),(0,n.$)("messages").scrollTop=999999}function _r(){if(ya||typeof marked>"u")return;let e=o=>String(o??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),t=(o,a)=>{let i=String(a||"").trim().split(/\s+/)[0]||"",r=i||"text",c=i?`language-${(0,n.esc)(i)}`:"";return`<div class="code-block">
|
|
93
93
|
<div class="code-block-header">
|
|
94
94
|
<span class="code-block-lang">${(0,n.esc)(r)}</span>
|
|
95
95
|
<button type="button" class="code-copy" data-copy="1" title="Copy code">Copy</button>
|
|
96
96
|
</div>
|
|
97
97
|
<pre><code class="hljs ${c}">${e(o)}</code></pre>
|
|
98
|
-
</div>`},s={code(o,a){return o&&typeof o=="object"&&o.text!=null?t(o.text,o.lang||a):t(o,a)},table(o,a){return o&&typeof o=="object"&&!Array.isArray(o)&&o.header?!1:`<div class="table-wrap"><table><thead>${o}</thead><tbody>${a}</tbody></table></div>`}};try{if(typeof marked.use=="function")marked.use({gfm:!0,breaks:!0,renderer:s});else if(typeof marked.setOptions=="function"){let o=new marked.Renderer;o.code=s.code,o.table=s.table,marked.setOptions({gfm:!0,breaks:!0,renderer:o})}}catch(o){console.warn("[md] marked setup failed",o)}
|
|
98
|
+
</div>`},s={code(o,a){return o&&typeof o=="object"&&o.text!=null?t(o.text,o.lang||a):t(o,a)},table(o,a){return o&&typeof o=="object"&&!Array.isArray(o)&&o.header?!1:`<div class="table-wrap"><table><thead>${o}</thead><tbody>${a}</tbody></table></div>`}};try{if(typeof marked.use=="function")marked.use({gfm:!0,breaks:!0,renderer:s});else if(typeof marked.setOptions=="function"){let o=new marked.Renderer;o.code=s.code,o.table=s.table,marked.setOptions({gfm:!0,breaks:!0,renderer:o})}}catch(o){console.warn("[md] marked setup failed",o)}ya=!0}function Wn(e){if(typeof marked>"u")return(0,n.esc)(e);try{return _r(),marked.parse(String(e??""),{breaks:!0,gfm:!0})}catch{return(0,n.esc)(e)}}function Aa(e){!e||typeof hljs>"u"||(e.querySelectorAll("pre code:not(.hljs)").forEach(t=>{try{hljs.highlightElement(t)}catch{}}),e.querySelectorAll("pre code.hljs").forEach(t=>{t.classList.add("hljs")}))}function ja(){Kn(),ia(),(0,n.watch)(Ie,o=>{pn(),Je();let a=(0,n.$)("ws-banner"),i=(0,n.$)("ws-banner-text");if(!a)return;if(o==="open"||o==="idle"){a.classList.add("hidden"),i&&(i.textContent="");return}if(o==="connecting"&&!Un){a.classList.add("hidden");return}a.classList.remove("hidden");let r=o==="offline"?"\u7F51\u7EDC\u5DF2\u65AD\u5F00\uFF0C\u6062\u590D\u540E\u4F1A\u81EA\u52A8\u91CD\u8FDE":o==="connecting"?"\u6B63\u5728\u8FDE\u63A5\u2026":"\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u6B63\u5728\u91CD\u8FDE\u2026\uFF08\u7184\u5C4F\u6216\u5207\u7F51\u65F6\u5E38\u89C1\uFF09";i?i.textContent=r:a.textContent=r}),(0,n.watch)(v,()=>Je()),n.delegate.on("click","#btn-refresh-conn, #ws-banner-retry",o=>{o.preventDefault(),mr()}),(0,n.watch)(X,o=>{(0,n.$)("send-btn")?.classList.toggle("hidden",o),(0,n.$)("stop-btn")?.classList.toggle("hidden",!o);let a=(0,n.$)("chat-input");a&&(a.disabled=!1,o?a.placeholder="\u56DE\u590D\u4E2D\u2026 \u53EF\u5148\u5199\u597D\u4E0B\u4E00\u6761\uFF0C\u7ED3\u675F\u540E\u81EA\u52A8\u53D1\u9001 \xB7 \u6216\u70B9 \u25A0 \u505C\u6B62":Pt(a.value||""));let i=(0,n.$)("messages");if(!i)return;let r=(0,n.$)("typing-indicator");o&&!r?(i.insertAdjacentHTML("beforeend",'<div id="typing-indicator" class="flex justify-start px-2"><div class="flex items-center gap-1.5 rounded-2xl rounded-tl-sm px-3 py-2 bg-base-200 text-xs text-base-content/40"><span class="dot"></span><span class="dot"></span><span class="dot"></span></div></div>'),de(i)):o||(r?.remove(),pe()),Je()}),(0,n.watch)(Ce,()=>Kn()),n.delegate.on("keydown","#chat-input",o=>{if(o.key!=="Enter")return;let a=o.metaKey||o.ctrlKey,i=window.matchMedia("(max-width: 640px)").matches&&!o.shiftKey&&!a;(a||i)&&(o.preventDefault(),fn())}),n.delegate.on("submit","#chat-form",o=>{o.preventDefault(),fn()}),n.delegate.on("input","#chat-input",(o,a)=>{_t(a),Pt(a.value)}),n.delegate.on("click","#btn-attach",o=>{o.preventDefault(),Cr()}),n.delegate.on("change","#chat-file-input",(o,a)=>{let i=a?.files;i?.length&&Jn(i),a&&(a.value="")}),n.delegate.on("click","[data-rm-attach]",(o,a)=>{o.preventDefault(),o.stopPropagation();let i=parseInt(a.dataset.rmAttach,10);if(Number.isNaN(i)||i<0||i>=Ke.length)return;let r=Ke[i];if(r?.previewUrl)try{URL.revokeObjectURL(r.previewUrl)}catch{}let c=(0,n.$)("chat-input");c&&r?.ref&&(c.value=c.value.split(r.ref).join("").replace(/\n{3,}/g,`
|
|
99
99
|
|
|
100
|
-
`),c.dispatchEvent(new Event("input"))),
|
|
101
|
-
`);c=
|
|
100
|
+
`),c.dispatchEvent(new Event("input"))),Ke.splice(i,1),zs()}),n.delegate.on("click","[data-perm-id]",(o,a)=>{Mt({type:"command",cmd:"approval.respond",requestId:a.dataset.permId,allow:a.dataset.permAllow==="1",sessionId:u.sessionId}),a.closest(".perm-banner")?.remove()}),n.delegate.on("click",".tool-card",(o,a)=>{let i=a.closest(".tool-batch");if(i&&!i.classList.contains("open")&&!a.classList.contains("tool-batch-item"))return;o.stopPropagation();let r=(0,n.$)("messages"),c=a.getBoundingClientRect().top;if(a.classList.toggle("open"),r){let f=a.getBoundingClientRect().top;r.scrollTop+=f-c}}),n.delegate.on("click",".tool-batch",(o,a)=>{if(o.target.closest(".tool-card")&&a.classList.contains("open"))return;let i=(0,n.$)("messages"),r=a.getBoundingClientRect().top;if(a.classList.toggle("open"),i){let c=a.getBoundingClientRect().top;i.scrollTop+=c-r}});let e=(0,n.$)("messages"),t=(0,n.$)("scroll-top-btn"),s=(0,n.$)("scroll-bottom-btn");if(e&&t&&s){let o=()=>{let a=e.scrollHeight-e.clientHeight>200;t.classList.toggle("hidden",!a||e.scrollTop<200),s.classList.toggle("hidden",!a||wa(e))};e.addEventListener("scroll",o,{passive:!0}),new ResizeObserver(o).observe(e),new MutationObserver(o).observe(e,{childList:!0,subtree:!0}),t.addEventListener("click",()=>e.scrollTo({top:0,behavior:"smooth"})),s.addEventListener("click",()=>e.scrollTo({top:e.scrollHeight,behavior:"smooth"})),o()}n.delegate.on("click",".msg-expand-btn",(o,a)=>{o.stopPropagation();let r=a.closest(".msg-card").classList.toggle("open");a.textContent=r?"\u25B2 Show less":"\u25BC Show more"}),n.delegate.on("click",".code-copy",async(o,a)=>{o.preventDefault(),o.stopPropagation();let c=a.closest(".code-block")?.querySelector("pre code")?.textContent??"";try{await navigator.clipboard.writeText(c),a.textContent="Copied",a.classList.add("copied"),setTimeout(()=>{a.textContent="Copy",a.classList.remove("copied")},1400)}catch{a.textContent="Failed",setTimeout(()=>{a.textContent="Copy"},1400)}})}var cn,Pe,Le,Ne,Fn,ba,Un,xa,On,_e,ut,$e,ce,ze,Se,xr,wr,kr,Ke,Bn,ga,ke,ya,Wt=P(()=>{M();C();J();ra();Ws();Nt();Nt();cn=0,Pe=null,Le=1e3,Ne=0,Fn=null,ba=!1,Un=!1,xa=null,On=!1,_e=[],ut=new Map;$e=null,ce=null,ze=null,Se=null;xr={haiku:"claude-haiku-4-5",sonnet:"claude-sonnet-4-6",opus:"claude-opus-4-5",sonnet4:"claude-sonnet-4-6",haiku4:"claude-haiku-4-5"};wr=200,kr=500;Ke=[],Bn=0,ga=!1;ke=null;ya=!1});function Na(e,t){Da=e,Ys=t,window.addEventListener("hashchange",()=>{if(Xs){Xs=!1;return}_a(location.hash.slice(1)||"/")}),(0,n.watch)(D,s=>{u.sessionId&&Vn(`/session/${u.sessionId}/${s}`)})}function Qs(e){let t=(e||"").match(/^\/session\/([^/]+)(?:\/([^/]+))?$/);return t?{id:t[1],tab:t[2]||null}:null}function Pa(){_a(location.hash.slice(1)||"/")}function _a(e){let t=Qs(e);if(!t){document.dispatchEvent(new CustomEvent("router:home"));return}let{id:s,tab:o}=t;!Da||!Ys||(s!==u.sessionId?document.dispatchEvent(new CustomEvent("router:session",{detail:{id:s,tab:o}})):o&&o!==D.peek()&&Ys(o))}function Vn(e){Xs=!0,location.hash=e}function Yn(){u.sessionId&&Vn(`/session/${u.sessionId}/${D.peek()}`)}var sc,Da,Ys,Xs,Xn=P(()=>{M();C();sc=(0,n.createRouter)({"/":()=>{},"/session/*":()=>{},"/session/*/*":()=>{},"*":()=>{}}),Da=null,Ys=null,Xs=!1});async function Zn(){try{return await Qn.get("sessions")??null}catch{return null}}async function Ha(e){try{await Qn.set("sessions",e,{ttl:Hr})}catch{}}async function Ra(){try{return await Qn.get("workspaces")??null}catch{return null}}async function mn(e){try{await Qn.set("workspaces",e,{ttl:3600*1e3})}catch{}}var Qn,Hr,es=P(()=>{M();Qn=(0,n.idb)("claude-ui"),Hr=300*1e3});function Jt(e){if(typeof marked<"u")try{return marked.parse(String(e??""),{breaks:!0,gfm:!0})}catch{}return(0,n.esc)(e).replace(/\n/g,"<br>")}function Kt(e){!e||typeof hljs>"u"||e.querySelectorAll("pre code").forEach(t=>{try{hljs.highlightElement(t)}catch{}})}async function no(e,t,s){let o=Ge({"Content-Type":"application/json"}),a=await fetch(e,{method:"POST",headers:o,body:JSON.stringify(t||{})});if(!a.ok){let l=await a.json().catch(()=>({}));throw new Error(l.error||`HTTP ${a.status}`)}let i=a.body.getReader(),r=new TextDecoder,c="",f="message";for(;;){let{done:l,value:d}=await i.read();if(l)break;c+=r.decode(d,{stream:!0});let p=c.split(`
|
|
101
|
+
`);c=p.pop()||"";for(let m of p)if(m.startsWith("event:"))f=m.slice(6).trim();else if(m.startsWith("data:")){let b=m.slice(5).trim();if(!b)continue;let g;try{g=JSON.parse(b)}catch{continue}s[f]?.(g),s.any?.(f,g),f="message"}else m.trim()===""&&(f="message")}}function Br(){return`
|
|
102
102
|
<div id="meta-agent-panel" class="meta-agent-panel hidden" aria-hidden="true">
|
|
103
103
|
<div class="meta-agent-backdrop" data-ma-close="1"></div>
|
|
104
104
|
<div class="meta-agent-sheet">
|
|
@@ -278,39 +278,39 @@ Available: ${f}`:""}`),!0}let a=br[o.toLowerCase()]||o,i=w.peek()||"claude",r=Oe
|
|
|
278
278
|
</div>
|
|
279
279
|
</div>
|
|
280
280
|
</div>
|
|
281
|
-
</div>`}function
|
|
281
|
+
</div>`}function ne(e){Ye=e;let t=(0,n.$)("ma-mode-chat"),s=(0,n.$)("ma-mode-history"),o=(0,n.$)("ma-mode-notes"),a=(0,n.$)("ma-mode-report"),i=(0,n.$)("ma-mode-config");for(let[c,f]of[[t,"chat"],[s,"history"],[o,"notes"],[a,"report"],[i,"config"]]){if(!c)continue;let l=e===f;c.classList.toggle("hidden",!l),c.classList.toggle("flex",l)}let r=(c,f)=>{let l=(0,n.$)(c);l&&(l.classList.toggle("border-primary/40",f),l.classList.toggle("text-primary",f))};r("ma-btn-chat",e==="chat"),r("ma-btn-history",e==="history"),r("ma-btn-notes",e==="notes"),r("ma-btn-report",e==="report"),e==="history"&&bt(),e==="notes"&&mt()}function bn(){let e=(0,n.$)("ma-session-title"),t=(0,n.$)("ma-resume-bar"),s=(0,n.$)("ma-resume-text");if(!K){e&&(e.textContent="\u65B0\u5BF9\u8BDD"),t?.classList.add("hidden");return}let o=ie?.title||K.slice(0,8),a=rs(ie?.updatedAt);if(e&&(e.textContent=a?`${o} \xB7 ${a}`:o),t&&s){t.classList.remove("hidden");let i=ie?.messageCount;s.textContent=i?`\u5DF2\u52A0\u8F7D\u5386\u53F2 \xB7 ${i} \u6761\u6D88\u606F \xB7 \u53D1\u9001\u5373\u53EF\u7EE7\u7EED`:"\u5DF2\u52A0\u8F7D\u5386\u53F2\u4F1A\u8BDD \xB7 \u53D1\u9001\u5373\u53EF\u7EE7\u7EED"}}function so(e="chat"){let t=(0,n.$)("meta-agent-panel");if(t){if(t.classList.remove("hidden"),t.setAttribute("aria-hidden","false"),is=!0,ne(e),e==="chat"){Re();let s=localStorage.getItem(Xe);!K&&s?Be(s,{silent:!0}).catch(()=>{localStorage.removeItem(Xe)}):bn()}e==="history"&&Re().then(()=>bt()),e==="report"&&Qa(),e==="config"&&Za(),setTimeout(()=>{Ye==="chat"&&(0,n.$)("ma-input")?.focus(),Ye==="history"&&(0,n.$)("ma-history-search")?.focus()},50)}}function Ja(){let e=(0,n.$)("meta-agent-panel");e&&(e.classList.add("hidden"),e.setAttribute("aria-hidden","true"),is=!1)}function Ka(){is?Ja():so(Ye==="config"?"chat":Ye)}function _(e,t,s={}){let o=(0,n.$)("ma-messages");if(!o)return null;let a=document.createElement("div");return a.className=`ma-msg ma-msg-${e}`,e==="user"?a.innerHTML=`<div class="ma-bubble user">${(0,n.esc)(t)}</div>`:e==="assistant"?(a.innerHTML=`<div class="ma-bubble assistant md">${Jt(t)}</div>`,Kt(a)):e==="error"?a.innerHTML=`<div class="ma-bubble error">${(0,n.esc)(t)}</div>`:e==="system"?a.innerHTML=`<div class="ma-sys">${(0,n.esc)(t)}</div>`:e==="tool"&&(a.innerHTML=`<div class="ma-tool" data-tool-id="${(0,n.esc)(s.id||"")}">
|
|
282
282
|
<span class="ma-tool-name">${(0,n.esc)(s.name||"tool")}</span>
|
|
283
283
|
<span class="ma-tool-phase">${(0,n.esc)(s.phase||"")}</span>
|
|
284
284
|
<pre class="ma-tool-args">${(0,n.esc)(JSON.stringify(s.args||{},null,0).slice(0,200))}</pre>
|
|
285
|
-
</div>`),o.appendChild(a),o.scrollTop=o.scrollHeight,a}function
|
|
285
|
+
</div>`),o.appendChild(a),o.scrollTop=o.scrollHeight,a}function Ua(e,t){let s=e?.querySelector(".ma-bubble");s&&(s.innerHTML=Jt(t),Kt(s),(0,n.$)("ma-messages").scrollTop=(0,n.$)("ma-messages").scrollHeight)}function Va(e,t,s){let o=(0,n.$)("ma-messages");if(!o)return;let a=o.querySelector(`[data-tool-id="${CSS.escape(e)}"]`);if(!a)return;a.classList.toggle("done",t==="done"),a.classList.toggle("error",t==="error");let i=a.querySelector(".ma-tool-phase");if(i&&(i.textContent=t),s&&t!=="start"){let r=a.querySelector(".ma-tool-result");r||(r=document.createElement("pre"),r.className="ma-tool-result",a.appendChild(r)),r.textContent=JSON.stringify(s,null,0).slice(0,500)}}function Fr(e){let t=(0,n.$)("ma-messages");if(!t)return;let s=document.createElement("div");s.className="ma-approval",s.dataset.approvalId=e.id;let o=e.args?.command??"";s.innerHTML=`
|
|
286
286
|
<div class="ma-approval-label">\u26A0 Agent \u60F3\u8981\u6267\u884C\u547D\u4EE4\uFF0C\u662F\u5426\u5141\u8BB8\uFF1F</div>
|
|
287
287
|
<pre class="ma-approval-cmd">${(0,n.esc)(o)}</pre>
|
|
288
288
|
<div class="ma-approval-actions">
|
|
289
289
|
<button type="button" class="btn btn-xs btn-error" data-approve="0">\u62D2\u7EDD</button>
|
|
290
290
|
<button type="button" class="btn btn-xs btn-success" data-approve="1">\u5141\u8BB8\u6267\u884C</button>
|
|
291
|
-
</div>`,s.querySelectorAll("[data-approve]").forEach(a=>{a.addEventListener("click",async()=>{let i=a.dataset.approve==="1";s.querySelectorAll("button").forEach(r=>{r.disabled=!0}),s.querySelector(".ma-approval-label").textContent=i?"\u2713 \u5DF2\u5141\u8BB8\uFF0C\u6B63\u5728\u6267\u884C\u2026":"\u2717 \u5DF2\u62D2\u7EDD";try{await h("POST","/api/ai/approve",{id:e.id,approved:i})}catch(r){s.querySelector(".ma-approval-label").textContent=`\u786E\u8BA4\u5931\u8D25\uFF1A${r.message}`}})}),t.appendChild(s),t.scrollTop=t.scrollHeight}function
|
|
291
|
+
</div>`,s.querySelectorAll("[data-approve]").forEach(a=>{a.addEventListener("click",async()=>{let i=a.dataset.approve==="1";s.querySelectorAll("button").forEach(r=>{r.disabled=!0}),s.querySelector(".ma-approval-label").textContent=i?"\u2713 \u5DF2\u5141\u8BB8\uFF0C\u6B63\u5728\u6267\u884C\u2026":"\u2717 \u5DF2\u62D2\u7EDD";try{await h("POST","/api/ai/approve",{id:e.id,approved:i})}catch(r){s.querySelector(".ma-approval-label").textContent=`\u786E\u8BA4\u5931\u8D25\uFF1A${r.message}`}})}),t.appendChild(s),t.scrollTop=t.scrollHeight}function Ur(){return Fa+=1,`img${Fa}`}function Or(e,t){if(!e)return;let s=e.selectionStart??e.value.length,o=e.selectionEnd??e.value.length;e.value=e.value.slice(0,s)+t+e.value.slice(o),e.selectionStart=e.selectionEnd=s+t.length,e.dispatchEvent(new Event("input"))}async function Oa(e,t){let s=Ge({"x-filename":t||`paste-${Date.now()}.png`});delete s["Content-Type"];let o=await fetch("/api/upload-image",{method:"POST",headers:s,body:e});if(!o.ok){let l=await o.json().catch(()=>({}));throw new Error(l.error||`Upload failed: ${o.status}`)}let{path:a}=await o.json();if(!a)throw new Error("upload returned no path");let i=Ur(),r=`[${i}](${a})`,c=(0,n.$)("ma-input");Or(c,(c?.value&&!c.value.endsWith(`
|
|
292
292
|
`)&&c.value.length?`
|
|
293
293
|
`:"")+r+`
|
|
294
|
-
`);let f="";try{f=URL.createObjectURL(e)}catch{}return
|
|
294
|
+
`);let f="";try{f=URL.createObjectURL(e)}catch{}return ft.push({path:a,previewUrl:f,label:i,ref:r}),oo(),{path:a,ref:r,label:i}}function oo(){let e=(0,n.$)("ma-attach-bar");if(e){if(!ft.length){e.classList.add("hidden"),e.innerHTML="";return}e.classList.remove("hidden"),e.innerHTML=ft.map((t,s)=>`
|
|
295
295
|
<div class="ma-thumb relative" title="${(0,n.esc)(t.ref||t.path)}">
|
|
296
296
|
${t.previewUrl?`<img src="${t.previewUrl}" alt="${(0,n.esc)(t.label||"img")}">`:`<span class="ma-thumb-path">${(0,n.esc)(t.label||"img")}</span>`}
|
|
297
297
|
<span class="ma-thumb-label">${(0,n.esc)(t.label||"")}</span>
|
|
298
298
|
<button type="button" class="ma-thumb-x" data-rm-img="${s}">\u2715</button>
|
|
299
|
-
</div>`).join(""),e.querySelectorAll("[data-rm-img]").forEach(t=>{t.addEventListener("click",()=>{let s=parseInt(t.dataset.rmImg,10),o=
|
|
299
|
+
</div>`).join(""),e.querySelectorAll("[data-rm-img]").forEach(t=>{t.addEventListener("click",()=>{let s=parseInt(t.dataset.rmImg,10),o=ft[s];if(o?.previewUrl)try{URL.revokeObjectURL(o.previewUrl)}catch{}let a=(0,n.$)("ma-input");a&&o?.ref&&(a.value=a.value.split(o.ref).join("").replace(/\n{3,}/g,`
|
|
300
300
|
|
|
301
|
-
`),a.dispatchEvent(new Event("input"))),
|
|
301
|
+
`),a.dispatchEvent(new Event("input"))),ft.splice(s,1),oo()})})}}function rs(e){if(!e)return"";let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let s=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),a=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${o} ${a}:${i}`}async function Re(){try{os=(await h("GET","/api/ai/sessions")).sessions||[]}catch{os=[]}return os}function Ya(){let e=v.peek(),t=u.sessionId?`${u.agent||w.peek()||"claude"}:${u.sessionId.slice(0,8)}`:"";return{project:e?.path||"",sessionId:u.sessionId||"",agent:u.agent||w.peek()||"claude",summary:[e?.name?`\u9879\u76EE ${e.name}`:"",t?`\u4F1A\u8BDD ${t}`:""].filter(Boolean).join(" \xB7 ")}}function hn(){ht=null,za=null,(0,n.$)("ma-note-title").value="",(0,n.$)("ma-note-content").value="",(0,n.$)("ma-note-pin").checked=!1,(0,n.$)("ma-note-link-project").checked=!!v.peek()?.path,(0,n.$)("ma-note-link-session").checked=!!u.sessionId,(0,n.$)("ma-note-status").textContent="\u65B0\u8BB0\u4E8B",(0,n.$)("ma-note-delete").disabled=!0,(0,n.$)("ma-note-links").textContent=Ya().summary||"\u672A\u5173\u8054\u4E0A\u4E0B\u6587"}function Xa(e){ht=e?.id||null,za=e||null,(0,n.$)("ma-note-title").value=e?.title||"",(0,n.$)("ma-note-content").value=e?.content||"",(0,n.$)("ma-note-pin").checked=!!e?.pinned,(0,n.$)("ma-note-link-project").checked=!!e?.cwd,(0,n.$)("ma-note-link-session").checked=!!e?.sessionId,(0,n.$)("ma-note-status").textContent=e?.updatedAt?`\u4E0A\u6B21\u66F4\u65B0 ${rs(e.updatedAt)}`:"",(0,n.$)("ma-note-delete").disabled=!e?.id;let t=[];e?.cwd&&t.push(`\u9879\u76EE ${e.cwd.split("/").pop()}`),e?.sessionId&&t.push(`\u4F1A\u8BDD ${e.agent||"claude"}:${e.sessionId.slice(0,8)}`),(0,n.$)("ma-note-links").textContent=t.join(" \xB7 ")||"\u672A\u5173\u8054\u4E0A\u4E0B\u6587"}function qr(){let e=(0,n.$)("ma-note-title")?.value?.trim()||"",t=(0,n.$)("ma-note-content")?.value?.trim()||"";if(!e&&!t){(0,n.$)("ma-note-status").textContent="\u5148\u9009\u4E00\u6761\u8BB0\u4E8B\u6216\u8F93\u5165\u5185\u5BB9";return}let s=[];(0,n.$)("ma-note-link-project")?.checked&&v.peek()?.path&&s.push(`\u9879\u76EE\u8DEF\u5F84\uFF1A${v.peek().path}`),(0,n.$)("ma-note-link-session")?.checked&&u.sessionId&&s.push(`\u5173\u8054\u4F1A\u8BDD\uFF1A${u.agent||w.peek()||"claude"} / ${u.sessionId}`);let o=["\u57FA\u4E8E\u4E0B\u9762\u8FD9\u6761\u5DE5\u4F5C\u8BB0\u4E8B\u56DE\u7B54\uFF0C\u5E76\u7ED3\u5408\u76F8\u5173\u4F1A\u8BDD\u4E0E\u9879\u76EE\u4E0A\u4E0B\u6587\uFF1A",`\u6807\u9898\uFF1A${e||"\u672A\u547D\u540D"}`,t?`\u5185\u5BB9\uFF1A
|
|
302
302
|
${t}`:"",s.length?s.join(`
|
|
303
303
|
`):"","","\u8BF7\u5148\u603B\u7ED3\u8FD9\u6761\u8BB0\u4E8B\u7684\u6838\u5FC3\uFF0C\u518D\u7ED9\u51FA\u4E0B\u4E00\u6B65\u5EFA\u8BAE\u548C\u53EF\u80FD\u98CE\u9669\u3002"].filter(Boolean).join(`
|
|
304
|
-
`);
|
|
304
|
+
`);ne("chat"),(0,n.$)("ma-input").value=o,(0,n.$)("ma-input").dispatchEvent(new Event("input")),(0,n.$)("ma-input").focus()}async function zt(){let e=(Ga||"").trim();return as=(await h("GET",`/api/ai/notes?limit=80${e?`&q=${encodeURIComponent(e)}`:""}`)).notes||[],as}function mt(){let e=(0,n.$)("ma-notes-list");if(e){if(!as.length){e.innerHTML='<div class="text-center text-xs text-base-content/40 py-10">\u8FD8\u6CA1\u6709\u8BB0\u4E8B\u3002</div>';return}e.innerHTML=as.map(t=>{let s=t.id===ht,o=[t.scope==="project"?"\u9879\u76EE":t.scope==="session"?"\u4F1A\u8BDD":"\u901A\u7528",t.pinned?"\u7F6E\u9876":""].filter(Boolean).join(" \xB7 ");return`
|
|
305
305
|
<button type="button" class="ma-note-item ${s?"active":""}" data-note-id="${(0,n.esc)(t.id)}">
|
|
306
306
|
<div class="text-left">
|
|
307
307
|
<div class="font-medium text-xs truncate">${(0,n.esc)(t.title||"\u672A\u547D\u540D")}</div>
|
|
308
308
|
<div class="text-[10px] text-base-content/45 mt-0.5 line-clamp-2">${(0,n.esc)(t.content||"")}</div>
|
|
309
|
-
<div class="text-[10px] text-base-content/35 mt-1">${(0,n.esc)(o)}${o?" \xB7 ":""}${(0,n.esc)(
|
|
309
|
+
<div class="text-[10px] text-base-content/35 mt-1">${(0,n.esc)(o)}${o?" \xB7 ":""}${(0,n.esc)(rs(t.updatedAt)||"")}</div>
|
|
310
310
|
</div>
|
|
311
|
-
</button>`}).join(""),e.querySelectorAll("[data-note-id]").forEach(t=>{t.addEventListener("click",async()=>{try{let s=await h("GET",`/api/ai/notes/${t.dataset.noteId}`);
|
|
311
|
+
</button>`}).join(""),e.querySelectorAll("[data-note-id]").forEach(t=>{t.addEventListener("click",async()=>{try{let s=await h("GET",`/api/ai/notes/${t.dataset.noteId}`);Xa(s),mt()}catch(s){(0,n.$)("ma-note-status").textContent=s.message}})})}}async function Wr(){let e=(0,n.$)("ma-note-title")?.value?.trim()||"",t=(0,n.$)("ma-note-content")?.value?.trim()||"";if(!e||!t){(0,n.$)("ma-note-status").textContent="\u6807\u9898\u548C\u5185\u5BB9\u90FD\u4E0D\u80FD\u4E3A\u7A7A";return}let s=Ya(),o={id:ht||void 0,title:e,content:t,pinned:!!(0,n.$)("ma-note-pin")?.checked,cwd:(0,n.$)("ma-note-link-project")?.checked?s.project:"",sessionId:(0,n.$)("ma-note-link-session")?.checked?s.sessionId:"",agent:(0,n.$)("ma-note-link-session")?.checked?s.agent:""};(0,n.$)("ma-note-status").textContent="\u4FDD\u5B58\u4E2D\u2026";let a=await h("POST","/api/ai/notes",o);Xa(a),await zt(),mt()}async function Gr(){if(!ht){hn();return}confirm("\u5220\u9664\u8FD9\u6761\u8BB0\u4E8B\uFF1F\u4E0D\u53EF\u6062\u590D\u3002")&&(await h("DELETE",`/api/ai/notes/${ht}`),hn(),await zt(),mt())}function bt(){let e=(0,n.$)("ma-history-list");if(!e)return;let t=(Wa||"").trim().toLowerCase(),s=os;if(t&&(s=s.filter(o=>`${o.title||""} ${o.preview||""} ${o.id||""}`.toLowerCase().includes(t))),!s.length){e.innerHTML=`<div class="text-center text-xs text-base-content/40 py-10">
|
|
312
312
|
${t?"\u6CA1\u6709\u5339\u914D\u7684\u4F1A\u8BDD":"\u8FD8\u6CA1\u6709\u5386\u53F2\u5BF9\u8BDD\u3002\u53D1\u4E00\u6761\u6D88\u606F\u540E\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002"}
|
|
313
|
-
</div>`;return}e.innerHTML=s.map(o=>{let a=o.id===
|
|
313
|
+
</div>`;return}e.innerHTML=s.map(o=>{let a=o.id===K,i=rs(o.updatedAt)||"",r=o.messageCount||0;return`
|
|
314
314
|
<div class="ma-hist-item ${a?"active":""}" data-hist-id="${(0,n.esc)(o.id)}">
|
|
315
315
|
<div class="flex items-start gap-2">
|
|
316
316
|
<button type="button" class="ma-hist-open flex-1 min-w-0 text-left" data-hist-open="${(0,n.esc)(o.id)}">
|
|
@@ -323,49 +323,49 @@ ${t}`:"",s.length?s.join(`
|
|
|
323
323
|
<button type="button" class="btn btn-ghost btn-xs px-1 text-error" data-hist-del="${(0,n.esc)(o.id)}" title="\u5220\u9664">\u2715</button>
|
|
324
324
|
</div>
|
|
325
325
|
</div>
|
|
326
|
-
</div>`}).join(""),e.querySelectorAll("[data-hist-open]").forEach(o=>{o.addEventListener("click",async()=>{await
|
|
327
|
-
`)||"[\u2026]"}function
|
|
326
|
+
</div>`}).join(""),e.querySelectorAll("[data-hist-open]").forEach(o=>{o.addEventListener("click",async()=>{await Be(o.dataset.histOpen),ne("chat"),(0,n.$)("ma-input")?.focus()})}),e.querySelectorAll("[data-hist-resume]").forEach(o=>{o.addEventListener("click",async a=>{a.stopPropagation(),await Be(o.dataset.histResume),ne("chat"),(0,n.$)("ma-input")?.focus()})}),e.querySelectorAll("[data-hist-del]").forEach(o=>{o.addEventListener("click",async a=>{a.stopPropagation();let i=o.dataset.histDel;if(confirm("\u5220\u9664\u8BE5\u5386\u53F2\u4F1A\u8BDD\uFF1F\u4E0D\u53EF\u6062\u590D\u3002"))try{await h("DELETE",`/api/ai/sessions/${i}`),K===i&&(K=null,ie=null,localStorage.removeItem(Xe),Be(null)),await Re(),bt()}catch(r){alert(r.message)}})})}function qa(e){return typeof e=="string"?e:Array.isArray(e)&&e.map(t=>typeof t=="string"?t:t?.type==="text"?t.text||"":t?.type==="image_url"?"[\u56FE\u7247]":"").filter(Boolean).join(`
|
|
327
|
+
`)||"[\u2026]"}function zr(e){let t=(0,n.$)("ma-messages");if(t){if(t.innerHTML="",!e?.length){_("system","\u6B64\u4F1A\u8BDD\u6682\u65E0\u6D88\u606F\u3002");return}for(let s of e){if(s.role==="user"){_("user",qa(s.content));continue}if(s.role==="assistant"){if(s.tool_calls?.length)for(let o of s.tool_calls){let a=o.function?.name||o.name||"tool",i={};try{i=JSON.parse(o.function?.arguments||o.arguments||"{}")}catch{}_("tool","",{name:a,args:i,phase:"history",id:o.id||a})}s.content&&_("assistant",typeof s.content=="string"?s.content:qa(s.content));continue}if(s.role==="tool"){let o=s.content;try{o=JSON.parse(s.content)}catch{}let a=s.tool_call_id||"";if(a)Va(a,"done",o);else{_("tool","",{name:"tool_result",args:{},phase:"done",id:`tr_${Math.random().toString(36).slice(2,8)}`});let i=t.querySelectorAll(".ma-tool"),r=i[i.length-1];if(r){r.classList.add("done");let c=r.querySelector(".ma-tool-result");c||(c=document.createElement("pre"),c.className="ma-tool-result",r.appendChild(c)),c.textContent=typeof o=="string"?o.slice(0,500):JSON.stringify(o,null,0).slice(0,500)}}}}t.scrollTop=t.scrollHeight}}async function Jr(){if(!K){await Be(null);return}if(confirm("\u5220\u9664\u5F53\u524D Meta Agent \u4F1A\u8BDD\uFF1F\u6B64\u64CD\u4F5C\u4E0D\u53EF\u6062\u590D\u3002"))try{await h("DELETE",`/api/ai/sessions/${K}`),K=null,ie=null,localStorage.removeItem(Xe),await Re(),await Be(null),Ye==="history"&&bt()}catch(e){_("error",e.message)}}async function Be(e,t={}){if(!e){K=null,ie=null,localStorage.removeItem(Xe);let s=(0,n.$)("ma-messages");return s&&(s.innerHTML=""),_("system","\u65B0\u5BF9\u8BDD \u2014 \u8D34\u56FE \u2192 [imgN](\u8DEF\u5F84)\uFF1B\u9700\u8981\u770B\u56FE\u65F6\u8C03\u7528 VLM\u3002\u5386\u53F2\u5728\u300C\u5386\u53F2\u300D\u9875\uFF0C\u53EF\u968F\u65F6 resume\u3002"),bn(),null}try{let s=await h("GET",`/api/ai/sessions/${e}`);return K=s.id,ie={id:s.id,title:s.title,updatedAt:s.updatedAt,messageCount:(s.messages||[]).length},localStorage.setItem(Xe,s.id),zr(s.messages||[]),t.silent||_("system","\u2191 \u5386\u53F2\u5DF2\u52A0\u8F7D\u3002\u5728\u4E0B\u65B9\u7EE7\u7EED\u8F93\u5165\u5373\u53EF resume\uFF08\u670D\u52A1\u7AEF\u4FDD\u7559\u5B8C\u6574 tool / VLM \u4E0A\u4E0B\u6587\uFF09\u3002"),bn(),Ye==="history"&&bt(),s}catch(s){throw t.silent||_("error",s.message),s}}async function ss(){if(Gt)return;let e=(0,n.$)("ma-input"),t=(e?.value||"").trim();if(!t)return;Gt=!0,(0,n.$)("ma-send").disabled=!0,_("user",t),e.value="",e.style.height="";for(let a of ft)if(a.previewUrl)try{URL.revokeObjectURL(a.previewUrl)}catch{}ft=[],oo();let s=null,o="";try{await no("/api/ai/chat",{message:t,sessionId:K},{session:a=>{K=a.id,ie={...ie||{},id:a.id,title:a.title||ie?.title||t.slice(0,40),updatedAt:Date.now()},localStorage.setItem(Xe,a.id),bn()},content:a=>{o=a.content||"",s||(s=_("assistant","")),Ua(s,o)},tool:a=>{a.phase==="start"?_("tool","",{name:a.name,args:a.args,phase:"start",id:a.id}):Va(a.id,a.phase,a.result)},approval:a=>Fr(a),done:a=>{a.sessionId&&(K=a.sessionId,localStorage.setItem(Xe,a.sessionId)),(a.title||a.sessionId)&&(ie={id:K,title:a.title||ie?.title||"\u5BF9\u8BDD",updatedAt:Date.now(),messageCount:(ie?.messageCount||0)+2}),a.content&&s&&Ua(s,a.content),bn(),Re()},error:a=>{_("error",a.message||"error")}})}catch(a){_("error",a.message)}finally{Gt=!1,(0,n.$)("ma-send").disabled=!1}}async function Kr(){if(Gt)return;Gt=!0;let e=parseInt((0,n.$)("ma-report-days")?.value||"1",10),t=(0,n.$)("ma-report-body");t.innerHTML=`<div class="text-sm text-base-content/50 py-6 text-center">\u6B63\u5728\u6C47\u603B\u8FD1 ${e} \u5929\u6D3B\u52A8\u2026</div>`,(0,n.$)("ma-gen-report").disabled=!0;let s="",o=document.createElement("div");o.className="ma-report-tools flex flex-col gap-1 mb-3";try{await no("/api/ai/report",{days:e},{content:a=>{s=a.content||"",t.innerHTML="",t.appendChild(o);let i=document.createElement("div");i.className="md ma-report-md",i.innerHTML=Jt(s),Kt(i),t.appendChild(i)},tool:a=>{if(a.phase==="start"){let i=document.createElement("div");i.className="ma-tool",i.dataset.toolId=a.id||a.name,i.innerHTML=`<span class="ma-tool-name">${(0,n.esc)(a.name)}</span> <span class="ma-tool-phase">start</span>`,o.appendChild(i)}else{let i=o.querySelector(`[data-tool-id="${CSS.escape(a.id||a.name)}"]`);i&&(i.classList.add(a.phase==="error"?"error":"done"),i.querySelector(".ma-tool-phase").textContent=a.phase)}},done:a=>{if(a.content){t.innerHTML="",t.appendChild(o);let i=document.createElement("div");i.className="md ma-report-md",i.innerHTML=Jt(a.content),Kt(i),t.appendChild(i)}},error:a=>{t.innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(a.message)}</div>`}})}catch(a){t.innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(a.message)}</div>`}finally{Gt=!1,(0,n.$)("ma-gen-report").disabled=!1}}async function Qa(){try{let e=new Date,t=`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`,s=await h("GET",`/api/ai/reports/${t}`);if(s?.markdown){let o=(0,n.$)("ma-report-body");o.innerHTML=`
|
|
328
328
|
<div class="text-[10px] text-base-content/40 mb-2">${(0,n.esc)(s.title||t)} \xB7 ${(0,n.esc)(s.generatedAt||"")}</div>
|
|
329
|
-
<div class="md ma-report-md">${
|
|
329
|
+
<div class="md ma-report-md">${Jt(s.markdown)}</div>`,Kt(o)}}catch{}}async function Vr(){let e=(0,n.$)("ma-report-list");try{let t=await h("GET","/api/ai/reports");e.classList.remove("hidden");let s=t.reports||[];if(!s.length){e.innerHTML='<div class="text-xs text-base-content/40 px-2 py-1">\u6682\u65E0\u5386\u53F2\u62A5\u544A</div>';return}e.innerHTML=s.map(o=>`
|
|
330
330
|
<button type="button" class="ma-report-item w-full text-left px-2 py-1 rounded hover:bg-base-200 text-xs"
|
|
331
331
|
data-day="${(0,n.esc)(o.day)}">
|
|
332
332
|
<span class="font-semibold">${(0,n.esc)(o.day)}</span>
|
|
333
333
|
<span class="text-base-content/45 ml-1">${(0,n.esc)(o.title||"")}</span>
|
|
334
334
|
</button>`).join(""),e.querySelectorAll("[data-day]").forEach(o=>{o.addEventListener("click",async()=>{try{let a=await h("GET",`/api/ai/reports/${o.dataset.day}`),i=(0,n.$)("ma-report-body");i.innerHTML=`
|
|
335
335
|
<div class="text-[10px] text-base-content/40 mb-2">${(0,n.esc)(a.title||a.day)} \xB7 ${(0,n.esc)(a.generatedAt||"")}</div>
|
|
336
|
-
<div class="md ma-report-md">${
|
|
337
|
-
<div class="aspect-square rounded-xl flex flex-col items-center justify-center p-2 relative transition-all min-h-[50px] md:min-h-[60px] ${xe} ${
|
|
338
|
-
data-cal-date="${m}" title="${
|
|
339
|
-
${
|
|
340
|
-
<span class="text-sm font-semibold">${
|
|
336
|
+
<div class="md ma-report-md">${Jt(a.markdown)}</div>`,Kt(i)}catch(a){(0,n.$)("ma-report-body").innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(a.message)}</div>`}})})}catch(t){e.classList.remove("hidden"),e.innerHTML=`<div class="text-xs text-error px-2">${(0,n.esc)(t.message)}</div>`}}async function Za(){try{let e=await h("GET","/api/ai/config");(0,n.$)("ma-cfg-url").value=e.url||"",(0,n.$)("ma-cfg-model").value=e.model||"",(0,n.$)("ma-cfg-key").placeholder=e.hasKey?"\u5DF2\u914D\u7F6E \xB7 \u7559\u7A7A\u4E0D\u4FEE\u6539":"API Key",(0,n.$)("ma-cfg-key").value="",(0,n.$)("ma-cfg-vlm-url").value=e.vlm_url||"",(0,n.$)("ma-cfg-vlm-model").value=e.vlm_model||"",(0,n.$)("ma-cfg-vlm-key").value="",(0,n.$)("ma-cfg-vlm-key").placeholder=e.hasVlmKey?"\u5DF2\u914D\u7F6E \xB7 \u7559\u7A7A\u4E0D\u4FEE\u6539":"\u53EF\u9009",(0,n.$)("ma-cfg-system").value=e.system||"",(0,n.$)("ma-auto-report")&&((0,n.$)("ma-auto-report").checked=!!e.auto_report),(0,n.$)("ma-auto-hour")&&((0,n.$)("ma-auto-hour").value=String(e.auto_report_hour??18)),xn(e)}catch(e){(0,n.$)("ma-cfg-status").textContent=e.message}}async function Yr(){let e=(0,n.$)("ma-cfg-status");e.textContent="\u4FDD\u5B58\u4E2D\u2026";try{let t={url:(0,n.$)("ma-cfg-url").value.trim(),model:(0,n.$)("ma-cfg-model").value.trim(),vlm_url:(0,n.$)("ma-cfg-vlm-url").value.trim(),vlm_model:(0,n.$)("ma-cfg-vlm-model").value.trim(),system:(0,n.$)("ma-cfg-system").value,auto_report:!!(0,n.$)("ma-auto-report")?.checked,auto_report_hour:parseInt((0,n.$)("ma-auto-hour")?.value||"18",10)},s=(0,n.$)("ma-cfg-key").value.trim(),o=(0,n.$)("ma-cfg-vlm-key").value.trim();s&&(t.key=s),o&&(t.vlm_key=o);let a=await h("PUT","/api/ai/config",t);e.textContent=a.hasKey?"\u5DF2\u4FDD\u5B58 \u2713":"\u5DF2\u4FDD\u5B58\uFF08\u672A\u8BBE\u7F6E Key\uFF09",(0,n.$)("ma-cfg-key").value="",(0,n.$)("ma-cfg-vlm-key").value="",xn(a)}catch(t){e.textContent=t.message}}function xn(e){if(ns&&(clearInterval(ns),ns=null),!e?.auto_report)return;let t=e.auto_report_hour??18;ns=setInterval(async()=>{if(!u.token)return;let s=new Date;if(s.getHours()!==t)return;let o=`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-${String(s.getDate()).padStart(2,"0")}`;if(to!==o&&!(s.getMinutes()>10))try{to=o,localStorage.setItem("ai_last_auto_report",o),await no("/api/ai/report",{days:e.auto_report_days||1},{done:()=>{console.info("[meta-agent] auto report saved for",o)},error:a=>console.warn("[meta-agent] auto report",a.message)})}catch(a){console.warn("[meta-agent] auto report failed",a),to="",localStorage.removeItem("ai_last_auto_report")}},60*1e3)}function ei(){(0,n.$)("meta-agent-panel")||(document.getElementById("root")?.insertAdjacentHTML("beforeend",Br()),document.querySelectorAll("[data-ma-close]").forEach(e=>{e.addEventListener("click",Ja)}),(0,n.$)("ma-btn-chat")?.addEventListener("click",()=>ne("chat")),(0,n.$)("ma-btn-history")?.addEventListener("click",async()=>{await Re(),ne("history")}),(0,n.$)("ma-btn-notes")?.addEventListener("click",async()=>{await zt(),ht||hn(),ne("notes")}),(0,n.$)("ma-open-history")?.addEventListener("click",async()=>{await Re(),ne("history")}),(0,n.$)("ma-btn-report")?.addEventListener("click",()=>{ne("report"),Qa()}),(0,n.$)("ma-btn-config")?.addEventListener("click",()=>{ne("config"),Za()}),(0,n.$)("ma-send")?.addEventListener("click",ss),(0,n.$)("ma-input")?.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key==="Enter"&&(e.preventDefault(),ss())}),(0,n.$)("ma-input")?.addEventListener("input",()=>{let e=(0,n.$)("ma-input");e.style.height="auto",e.style.height=Math.min(e.scrollHeight,120)+"px"}),(0,n.$)("ma-new-chat")?.addEventListener("click",()=>{Be(null),ne("chat")}),(0,n.$)("ma-del-session")?.addEventListener("click",Jr),(0,n.$)("ma-resume-focus")?.addEventListener("click",()=>{(0,n.$)("ma-input")?.focus()}),(0,n.$)("ma-history-refresh")?.addEventListener("click",async()=>{await Re(),bt()}),(0,n.$)("ma-history-new")?.addEventListener("click",()=>{Be(null),ne("chat")}),(0,n.$)("ma-history-search")?.addEventListener("input",e=>{Wa=e.target.value||"",bt()}),(0,n.$)("ma-quick-today")?.addEventListener("click",()=>{ne("chat"),(0,n.$)("ma-input").value="\u6839\u636E\u6211\u6700\u8FD1\u7684\u4F1A\u8BDD\uFF0C\u603B\u7ED3\u4ECA\u5929\u6211\u505A\u4E86\u4EC0\u4E48\uFF1F\u6309\u9879\u76EE\u5217\u51FA\u4EAE\u70B9\u4E0E\u672A\u5B8C\u6210\u4E8B\u9879\u3002",ss()}),(0,n.$)("ma-quick-projects")?.addEventListener("click",()=>{ne("chat"),(0,n.$)("ma-input").value="\u5217\u51FA\u6700\u8FD1 14 \u5929\u6D3B\u8DC3\u7684\u9879\u76EE\uFF0C\u6BCF\u4E2A\u9879\u76EE\u4E00\u53E5\u8BDD\u8BF4\u660E\u6700\u8FD1\u5728\u505A\u4EC0\u4E48\u3002",ss()}),(0,n.$)("ma-gen-report")?.addEventListener("click",Kr),(0,n.$)("ma-load-reports")?.addEventListener("click",Vr),(0,n.$)("ma-notes-refresh")?.addEventListener("click",async()=>{await zt(),mt()}),(0,n.$)("ma-notes-new")?.addEventListener("click",()=>{hn(),mt(),(0,n.$)("ma-note-title")?.focus()}),(0,n.$)("ma-notes-search")?.addEventListener("input",async e=>{Ga=e.target.value||"",await zt(),mt()}),(0,n.$)("ma-note-save")?.addEventListener("click",async()=>{try{await Wr()}catch(e){(0,n.$)("ma-note-status").textContent=e.message}}),(0,n.$)("ma-note-delete")?.addEventListener("click",async()=>{try{await Gr()}catch(e){(0,n.$)("ma-note-status").textContent=e.message}}),(0,n.$)("ma-note-ask")?.addEventListener("click",qr),(0,n.$)("ma-cfg-save")?.addEventListener("click",Yr),(0,n.$)("ma-auto-report")?.addEventListener("change",async()=>{try{let e=await h("PUT","/api/ai/config",{auto_report:!!(0,n.$)("ma-auto-report").checked,auto_report_hour:parseInt((0,n.$)("ma-auto-hour")?.value||"18",10)});xn(e)}catch{}}),(0,n.$)("ma-auto-hour")?.addEventListener("change",async()=>{try{let e=await h("PUT","/api/ai/config",{auto_report:!!(0,n.$)("ma-auto-report")?.checked,auto_report_hour:parseInt((0,n.$)("ma-auto-hour").value||"18",10)});xn(e)}catch{}}),(0,n.$)("ma-image-input")?.addEventListener("change",async e=>{let t=[...e.target.files||[]],s=(0,n.$)("ma-input");s&&(s.disabled=!0);try{for(let o of t)if(o.type.startsWith("image/")){if(o.size>12*1024*1024){_("error",`${o.name} \u8FC7\u5927 (>12MB)`);continue}await Oa(o,o.name||`upload-${Date.now()}.png`)}}catch(o){_("error",`\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${o.message}`)}finally{e.target.value="",s&&(s.disabled=!1,s.focus())}}),document.addEventListener("paste",async e=>{if(!is||Ye!=="chat")return;let t=(0,n.$)("ma-input"),s=(0,n.$)("meta-agent-panel"),o=document.activeElement;if(!s||!o||!s.contains(o))return;let i=[...e.clipboardData?.items||[]].filter(r=>r.type.startsWith("image/"));if(i.length){e.preventDefault(),t&&(t.disabled=!0);try{for(let r of i){let c=r.getAsFile();if(!c)continue;let f=(r.type.split("/")[1]||"png").replace(/[^a-z0-9]/gi,"")||"png";await Oa(c,`paste-${Date.now()}.${f}`)}}catch(r){_("error",`\u7C98\u8D34\u56FE\u7247\u5931\u8D25: ${r.message}`)}finally{t&&(t.disabled=!1,t.focus())}}}),Be(null,{silent:!0}),hn())}function gn(){u.token&&($.peek()&&!sn()||(Re(),zt().catch(()=>{}),h("GET","/api/ai/config").then(xn).catch(()=>{})))}var is,Ye,Gt,K,ie,ft,Fa,ns,to,os,Wa,as,Ga,ht,za,Xe,vn=P(()=>{M();J();C();is=!1,Ye="chat",Gt=!1,K=null,ie=null,ft=[],Fa=0,ns=null,to=localStorage.getItem("ai_last_auto_report")||"",os=[],Wa="",as=[],Ga="",ht=null,za=null,Xe="ma_last_session_id"});function ao(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}function gt(){let e=ao(T.peek()),t=S.peek();$.peek()&&t&&(e=e.filter(o=>o&&(!o.machineId||o.machineId===t)));let s=oe.peek();return s&&s!=="all"&&(e=e.filter(o=>o&&(o.agent||"claude")===s)),e}function si(e){let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),o=String(e.getDate()).padStart(2,"0");return`${t}-${s}-${o}`}function Xr(e,t){let s=[],a=new Date(e,t,1).getDay(),r=new Date(e,t+1,0).getDate(),c=new Date(e,t,0).getDate();for(let l=a-1;l>=0;l--)s.push({date:new Date(e,t-1,c-l),isCurrentMonth:!1});for(let l=1;l<=r;l++)s.push({date:new Date(e,t,l),isCurrentMonth:!0});let f=7-s.length%7;if(f<7)for(let l=1;l<=f;l++)s.push({date:new Date(e,t+1,l),isCurrentMonth:!1});return s}function oi(e,t){let s=new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime(),o=s+1440*60*1e3;return t.filter(a=>{let i=A(a.updatedAt);return i!=null&&i>=s&&i<o})}function ai(e){return e==null||isNaN(e)?"0":e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}K`:String(e)}function vt(e){let t=(0,n.$)("calendar-grid");if(!t)return;e=ao(e??gt());let s=(0,n.$)("calendar-month-year");if(s){let d=new Date(ls,xt,1);s.textContent=d.toLocaleDateString([],{month:"long",year:"numeric"})}let o=e.length,a=new Set(e.map(d=>d.cwd).filter(Boolean)).size,i=e.reduce((d,p)=>d+(Number(p.totalTokens)||0),0),r=(0,n.$)("stats-total-sessions"),c=(0,n.$)("stats-total-projects"),f=(0,n.$)("stats-total-tokens");r&&(r.textContent=String(o)),c&&(c.textContent=String(a)),f&&(f.textContent=ai(i));let l=Xr(ls,xt);yn||(yn=si(new Date)),t.innerHTML=l.map(d=>{let p=d.date,m=si(p),g=oi(p,e).length,F=p.toDateString()===new Date().toDateString(),Ze=m===yn,xe="",et="text-base-content/65",Ee="border border-transparent",k="cursor-default",V=d.isCurrentMonth?"":"opacity-25";g>0?(k="cursor-pointer",g<=2?(xe="bg-primary/15",et="text-primary font-bold",Ee="border border-primary/30"):g<=5?(xe="bg-primary/30",et="text-primary font-bold",Ee="border border-primary/50"):(xe="bg-primary/60",et="text-primary-content font-bold",Ee="border border-primary/80")):(xe="bg-base-300/25",d.isCurrentMonth&&(k="hover:bg-base-300/50")),F?Ee="border-2 border-primary":Ze&&(Ee="border-2 border-accent");let tt=p.getDate()===1?`<span class="absolute top-0.5 left-1 text-[8px] opacity-60 uppercase">${p.toLocaleDateString([],{month:"short"})}</span>`:"";return`
|
|
337
|
+
<div class="aspect-square rounded-xl flex flex-col items-center justify-center p-2 relative transition-all min-h-[50px] md:min-h-[60px] ${xe} ${et} ${Ee} ${k} ${V}"
|
|
338
|
+
data-cal-date="${m}" title="${p.toDateString()}: ${g} session(s)">
|
|
339
|
+
${tt}
|
|
340
|
+
<span class="text-sm font-semibold">${p.getDate()}</span>
|
|
341
341
|
${g>0?`<span class="text-[10px] mt-0.5 opacity-80 font-medium whitespace-nowrap">${g}s</span>`:""}
|
|
342
|
-
</div>`}).join(""),
|
|
343
|
-
<div class="flex items-center gap-2.5 p-2.5 rounded-lg bg-base-300/40 hover:bg-base-300 border border-base-300/50 cursor-pointer text-left transition-all ${
|
|
342
|
+
</div>`}).join(""),Qr(e),ro()}function Qr(e){let t=(0,n.$)("selected-day-title"),s=(0,n.$)("selected-day-sessions");if(!t||!s)return;let[o,a,i]=yn.split("-").map(Number),r=new Date(o,a-1,i);t.textContent=`Activity on ${r.toLocaleDateString([],{weekday:"short",month:"short",day:"numeric",year:"numeric"})}`,e=ao(e);let c=oi(r,e),f=c.reduce((d,p)=>d+(Number(p.totalTokens)||0),0),l=(0,n.$)("stats-selected-tokens");if(l&&(l.textContent=ai(f)),!c.length){s.innerHTML='<div class="text-center text-xs text-base-content/40 my-auto py-6">No sessions active on this day</div>';return}c.sort((d,p)=>(A(p.updatedAt)||0)-(A(d.updatedAt)||0)),s.innerHTML=c.map(d=>{let p=A(d.updatedAt),m=p!=null?new Date(p).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):"";return`
|
|
343
|
+
<div class="flex items-center gap-2.5 p-2.5 rounded-lg bg-base-300/40 hover:bg-base-300 border border-base-300/50 cursor-pointer text-left transition-all ${u.sessionId===d.sessionId?"border-primary bg-primary/5":""}"
|
|
344
344
|
data-session-id="${(0,n.esc)(d.sessionId)}"
|
|
345
345
|
data-session-cwd="${(0,n.esc)(d.cwd||"")}"
|
|
346
346
|
data-session-config-dir="${(0,n.esc)(d.configDir||"")}"
|
|
347
347
|
data-session-agent="${(0,n.esc)(d.agent||"claude")}"
|
|
348
348
|
data-session-machine="${(0,n.esc)(d.machineId||"")}">
|
|
349
|
-
<div class="flex-shrink-0">${
|
|
349
|
+
<div class="flex-shrink-0">${rt(d.agent)}</div>
|
|
350
350
|
<div class="flex-1 min-w-0">
|
|
351
351
|
<div class="text-xs font-semibold truncate text-base-content/90">${(0,n.esc)(Ae(d))}</div>
|
|
352
|
-
<div class="text-[10px] text-base-content/40 truncate mt-0.5">${(0,n.esc)(d.projectName||
|
|
352
|
+
<div class="text-[10px] text-base-content/40 truncate mt-0.5">${(0,n.esc)(d.projectName||lt(d.cwd)||"No workspace")}</div>
|
|
353
353
|
</div>
|
|
354
354
|
<div class="text-[9px] text-base-content/45 font-mono whitespace-nowrap bg-base-300 px-1.5 py-0.5 rounded">${m}</div>
|
|
355
|
-
</div>`}).join("")}function
|
|
356
|
-
<div class="flex items-center gap-2.5 p-3 rounded-xl bg-base-200 hover:bg-base-300 border border-base-300/80 cursor-pointer text-left transition-all ${
|
|
355
|
+
</div>`}).join("")}function cs(e){return`${e.machineId||""}:${e.agent||"claude"}:${e.sessionId}`}function io(){try{let e=JSON.parse(localStorage.getItem(ri)||"[]");return Array.isArray(e)?e.filter(t=>t&&t.sessionId):[]}catch{return[]}}function li(e){try{localStorage.setItem(ri,JSON.stringify(e))}catch{}}function ci(e){if(!e?.sessionId)return;let t=cs(e),s={...e,lastOpenedAt:Date.now()},o=io().filter(a=>cs(a)!==t);o.unshift(s),li(o.slice(0,ii)),ro(),co()}function di(e){if(!e?.sessionId)return;let t=cs(e);li(io().filter(s=>cs(s)!==t)),ro(),co()}function ui(e){return io().sort((t,s)=>(A(s.lastOpenedAt)||0)-(A(t.lastOpenedAt)||0)).slice(0,e)}function ro(){let e=(0,n.$)("recent-sessions-list");if(!e)return;let t=ui(6);if(!t.length){e.innerHTML='<div class="col-span-full text-center text-xs text-base-content/40 py-4">No recent sessions</div>';return}e.innerHTML=t.map(s=>{let o=Dt(s.updatedAt);return`
|
|
356
|
+
<div class="flex items-center gap-2.5 p-3 rounded-xl bg-base-200 hover:bg-base-300 border border-base-300/80 cursor-pointer text-left transition-all ${u.sessionId===s.sessionId?"border-primary bg-primary/5":""}"
|
|
357
357
|
data-session-id="${(0,n.esc)(s.sessionId)}"
|
|
358
358
|
data-session-cwd="${(0,n.esc)(s.cwd||"")}"
|
|
359
359
|
data-session-config-dir="${(0,n.esc)(s.configDir||"")}"
|
|
360
360
|
data-session-agent="${(0,n.esc)(s.agent||"claude")}"
|
|
361
361
|
data-session-machine="${(0,n.esc)(s.machineId||"")}">
|
|
362
|
-
<div class="flex-shrink-0">${
|
|
362
|
+
<div class="flex-shrink-0">${rt(s.agent)}</div>
|
|
363
363
|
<div class="flex-1 min-w-0">
|
|
364
364
|
<div class="text-xs font-bold truncate text-base-content/95">${(0,n.esc)(Ae(s))}</div>
|
|
365
|
-
<div class="text-[10px] text-base-content/40 truncate mt-1">${(0,n.esc)(s.projectName||
|
|
365
|
+
<div class="text-[10px] text-base-content/40 truncate mt-1">${(0,n.esc)(s.projectName||lt(s.cwd)||"No workspace")}</div>
|
|
366
366
|
</div>
|
|
367
367
|
<div class="text-[9px] text-base-content/40 whitespace-nowrap self-start mt-0.5">${o}</div>
|
|
368
|
-
</div>`}).join("")}function
|
|
368
|
+
</div>`}).join("")}function yt(){let e=(0,n.$)("recent-menu");e&&(e.classList.add("hidden"),e.classList.remove("recent-menu-open"),e.style.top="",e.style.left="",e.style.right="",e.style.width="",e.style.maxHeight=""),(0,n.$)("recent-menu-backdrop")?.classList.add("hidden")}function lo(){let e=(0,n.$)("recent-menu"),t=(0,n.$)("topbar");if(!e||!t)return;let s=t.getBoundingClientRect(),a=Math.round(s.bottom+6),i=window.matchMedia("(max-width: 640px)").matches?8:null;if(e.style.top=`${a}px`,i!=null)e.style.left=`${i}px`,e.style.right=`${i}px`;else{let f=(0,n.$)("btn-recent-sessions")?.getBoundingClientRect();if(f){let l=Math.min(320,window.innerWidth-16),d=f.left;d+l>window.innerWidth-8&&(d=window.innerWidth-l-8),d<8&&(d=8),e.style.left=`${Math.round(d)}px`,e.style.right="auto",e.style.width=`${l}px`}}let r=Math.max(160,window.innerHeight-a-12);e.style.maxHeight=`${Math.min(r,Math.round(window.innerHeight*.7))}px`}function Zr(){let e=(0,n.$)("recent-menu");e&&(co(),e.classList.remove("hidden"),e.classList.add("recent-menu-open"),lo(),(0,n.$)("recent-menu-backdrop")?.classList.remove("hidden"))}function pi(){let e=(0,n.$)("recent-menu");e&&(e.classList.contains("hidden")?Zr():yt())}function co(){let e=(0,n.$)("recent-menu-list"),t=(0,n.$)("recent-menu-empty"),s=(0,n.$)("recent-menu-count");if(!e)return;let o=ui(ii);if(s&&(s.textContent=o.length?`${o.length}`:""),!o.length){e.innerHTML="",t?.classList.remove("hidden");return}t?.classList.add("hidden"),e.innerHTML=o.map(a=>{let i=Dt(a.updatedAt),r=u.sessionId===a.sessionId&&(!a.machineId||!u.machineId||a.machineId===u.machineId),c=a.machineId?`<span class="text-[9px] font-mono text-base-content/35 truncate max-w-[4.5rem]" title="${(0,n.esc)(a.machineId)}">@${(0,n.esc)(a.machineId)}</span>`:"";return`
|
|
369
369
|
<div class="recent-menu-item w-full text-left px-2 py-1.5 rounded-md flex items-start gap-2
|
|
370
370
|
${r?"bg-primary/15 text-primary":"hover:bg-base-200"}">
|
|
371
371
|
<button type="button" class="flex min-w-0 flex-1 items-start gap-2 text-left" aria-label="\u6253\u5F00 ${(0,n.esc)(Ae(a))}"
|
|
@@ -374,10 +374,10 @@ ${t}`:"",s.length?s.join(`
|
|
|
374
374
|
data-session-config-dir="${(0,n.esc)(a.configDir||"")}"
|
|
375
375
|
data-session-agent="${(0,n.esc)(a.agent||"claude")}"
|
|
376
376
|
data-session-machine="${(0,n.esc)(a.machineId||"")}">
|
|
377
|
-
<span class="flex-shrink-0 mt-0.5">${
|
|
377
|
+
<span class="flex-shrink-0 mt-0.5">${rt(a.agent)}</span>
|
|
378
378
|
<span class="flex-1 min-w-0">
|
|
379
379
|
<span class="block text-xs font-semibold truncate leading-snug">${(0,n.esc)(Ae(a))}</span>
|
|
380
|
-
<span class="block text-[10px] text-base-content/40 truncate mt-0.5">${(0,n.esc)(a.projectName||
|
|
380
|
+
<span class="block text-[10px] text-base-content/40 truncate mt-0.5">${(0,n.esc)(a.projectName||lt(a.cwd)||"\u2014")}</span>
|
|
381
381
|
</span>
|
|
382
382
|
<span class="flex flex-col items-end gap-0.5 flex-shrink-0 self-start">
|
|
383
383
|
<span class="text-[9px] text-base-content/40 whitespace-nowrap">${(0,n.esc)(i)}</span>
|
|
@@ -390,7 +390,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
390
390
|
data-dismiss-recent-session="${(0,n.esc)(a.sessionId)}"
|
|
391
391
|
data-dismiss-recent-agent="${(0,n.esc)(a.agent||"claude")}"
|
|
392
392
|
data-dismiss-recent-machine="${(0,n.esc)(a.machineId||"")}">\xD7</button>
|
|
393
|
-
</div>`}).join("")}function
|
|
393
|
+
</div>`}).join("")}function fi(e){yn=e}function uo(e){xt+=e,xt<0?(xt=11,ls--):xt>11&&(xt=0,ls++)}var ls,xt,yn,ii,ri,po=P(()=>{M();C();Nt();ls=new Date().getFullYear(),xt=new Date().getMonth(),yn=null;ii=15,ri="recentSessionsV1"});var vi={};Dn(vi,{loadAgentsMeta:()=>Yt,loadAllSessions:()=>fe,loadMemoryTab:()=>fs,loadWorkspaces:()=>Vt,mdToHtml:()=>gi,openMemoryFile:()=>bo,promptCustomModel:()=>us,refreshEffortSelect:()=>ds,refreshModelSelect:()=>me,renderProjectGroups:()=>bi,renderSessionList:()=>mo,renderTimeline:()=>xi,runActivitySearch:()=>ps,scheduleActivitySearch:()=>wn,sessionItemHtml:()=>fo,syncSidebarChrome:()=>ho});function mi(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}function el(){let e=parseInt(le.peek()||"14",10),t=new URLSearchParams;e>0&&t.set("days",String(e)),t.set("limit","400");let s=t.toString();return s?`/api/sessions?${s}`:"/api/sessions"}async function fe({waitFresh:e=!0}={}){let t=mi(await Zn());if(t.length){let o=S.peek();if($.peek()&&o){let a=t.filter(i=>!i.machineId||i.machineId===o);T.value=a.length?a:t}else T.value=t}let s=async()=>{let o=el(),a=await h("GET",o,void 0,void 0,{etag:!0});if(a===Fs)return T.peek();let i=mi(a);return T.value=i,Ha(i),i};if(e||!t.length)try{await s()}catch(o){if(!t.length){let a=(0,n.$)("session-list");a&&(a.innerHTML=`<div class="px-3 py-3 text-xs text-error">${(0,n.esc)(o.message)}</div>`)}}else s().catch(()=>{})}async function Vt({waitFresh:e=!0}={}){let t=await Ra();t&&(H.value=t);let s=async()=>{let o=await h("GET","/api/workspaces");H.value=o,mn(o)};if(e||!t)try{await s()}catch{}else s().catch(()=>{})}function fo(e,{showProject:t=!1}={}){let s=u.sessionId===e.sessionId&&(u.agent||w.peek())===(e.agent||"claude"),o=y.peek()?.[U(e.agent,e.sessionId,e.machineId)]||{},a=!!(o.title&&String(o.title).trim()),i=e.snippet&&R.peek()?e.snippet:Ae(e),r=!!o.favorite,c=!!o.hidden,f=!!(o.notes&&String(o.notes).trim()),l=Number(e.turnCount)||0,d=l>0&&l<=_s,p=t?`<div class="text-[10px] text-base-content/40 font-mono truncate" title="${(0,n.esc)(e.cwd||"")}">${(0,n.esc)(e.projectName||lt(e.cwd)||"\u2014")}</div>`:"",m=[d?`<span class="session-thin-badge" title="Only ${l} turn${l===1?"":"s"}">thin\xB7${l}</span>`:"",a?`<span class="session-renamed-badge" title="Custom name (original: ${(0,n.esc)(e.display||"")})">renamed</span>`:"",c?'<span class="session-hidden-badge" title="Hidden">hidden</span>':"",f?`<span class="session-note-dot" title="${(0,n.esc)(o.notes)}">\u{1F4DD}</span>`:""].filter(Boolean).join(""),b=e.machineId?`<span class="text-[9px] px-1 py-0.5 rounded bg-base-300 text-base-content/50 font-mono flex-shrink-0" title="Machine">${(0,n.esc)(e.machineId)}</span>`:"",g=a?`${i}
|
|
394
394
|
(original: ${e.display||e.sessionId})`:e.display||"";return`<div class="session-row px-2.5 py-1.5 cursor-pointer hover:bg-base-300 border-l-2
|
|
395
395
|
${s?"border-primary bg-primary/5":"border-transparent"} ${r?"session-fav":""} ${c?"session-hidden-row":""} ${d?"session-thin":""}"
|
|
396
396
|
data-session-id="${(0,n.esc)(e.sessionId)}"
|
|
@@ -406,7 +406,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
406
406
|
data-fav-session-agent="${(0,n.esc)(e.agent||"claude")}"
|
|
407
407
|
data-fav-session-machine="${(0,n.esc)(e.machineId||"")}"
|
|
408
408
|
title="${r?"Unfavorite":"Favorite"}">${r?"\u2605":"\u2606"}</button>
|
|
409
|
-
${
|
|
409
|
+
${rt(e.agent)}
|
|
410
410
|
<div class="min-w-0 flex-1">
|
|
411
411
|
<div class="session-title-wrap flex items-center gap-1 min-w-0"
|
|
412
412
|
data-rename-session-id="${(0,n.esc)(e.sessionId)}"
|
|
@@ -425,36 +425,36 @@ ${t}`:"",s.length?s.join(`
|
|
|
425
425
|
data-hide-session-machine="${(0,n.esc)(e.machineId||"")}"
|
|
426
426
|
title="${c?"Unhide session":"Hide session"}">${c?"\u{1F441}":"\u{1F648}"}</button>
|
|
427
427
|
</div>
|
|
428
|
-
${
|
|
428
|
+
${p}
|
|
429
429
|
${m||b?`<div class="flex items-center gap-1 mt-0.5 flex-wrap">${b}${m}</div>`:""}
|
|
430
430
|
</div>
|
|
431
|
-
<span class="text-[9px] text-base-content/30 flex-shrink-0 mt-0.5">${
|
|
431
|
+
<span class="text-[9px] text-base-content/30 flex-shrink-0 mt-0.5">${Dt(e.updatedAt)}</span>
|
|
432
432
|
</div>
|
|
433
|
-
</div>`}async function
|
|
433
|
+
</div>`}async function Yt(){try{let e=await h("GET","/api/agents");return nt.value=e,me(),e}catch(e){return console.warn("[agents] failed to load model list",e),null}}function ds(){let e=(0,n.$)("sel-effort");if(!e)return;let t=w.peek()||"claude",s=E.peek(),o=nn(t,s),a=O.peek()||"";if(!a){let r=qe(t,s);r&&o.includes(r)&&(a=r,O.value=r)}let i=['<option value="">effort: off</option>'].concat(o.map(r=>`<option value="${(0,n.esc)(r)}" ${r===a?"selected":""}>${(0,n.esc)(r)}</option>`));if(e.innerHTML=i.join(""),a&&!o.includes(a)){let r=qe(t,s);r&&o.includes(r)?(O.value=r,e.value=r):(O.value="",e.value="")}else e.value=a}function me(){let e=(0,n.$)("sel-model");if(!e)return;let t=w.peek()||"claude",s=je(t),o=E.peek();if(o&&!s.some(i=>i.value===o)&&(s=[{value:o,label:`${o} \u2605`,custom:!0},...s]),e.innerHTML=s.map(i=>`<option value="${(0,n.esc)(i.value)}" ${i.value===o?"selected":""}>${(0,n.esc)(i.label)}</option>`).join(""),s.some(i=>i.value===o))e.value=o;else{let i=ye(t)||s[0]?.value;G(i),e.value=i,o=i}let a=(0,n.$)("sel-agent");a&&(a.value=t),ds()}function us({editCurrent:e=!1}={}){let t=w.peek()||"claude",s=e&&E.peek()||"",o=e?`Edit model id for ${t}:`:`Add model id for ${t} (saved in this browser):`,a=window.prompt(o,s);if(a==null)return;let i=a.trim();i&&(e&&s&&s!==i&&Nn(t).includes(s)&&Bs(t,s),tn(t,i),G(i),me())}function bi(e){if(!Array.isArray(e)||!e.length)return`<div class="px-3 py-6 text-center text-xs text-base-content/40">
|
|
434
434
|
No projects in this range.<br>
|
|
435
435
|
<span class="text-base-content/30">Try \u201CAll\u201D time or another agent.</span>
|
|
436
|
-
</div>`;let t
|
|
436
|
+
</div>`;let t=Lt.value,s=Et.value,o=!!R.value.trim(),a=e[0]?.cwd||"(no path)";return e.map(i=>{let r=i.cwd||"(no path)",c=!1;s.has(r)?c=!1:t.has(r)?c=!0:c=o||r===a||e.length<=3;let f=i.latest?.display||i.latest?.snippet||"",l=i.machineId?`<span class="text-[9px] font-mono text-base-content/40 flex-shrink-0">@${(0,n.esc)(i.machineId)}</span>`:"",d=`
|
|
437
437
|
<div class="project-header px-2.5 py-2 cursor-pointer hover:bg-base-300/80 select-none border-b border-base-300/40"
|
|
438
438
|
data-folder="${(0,n.esc)(r)}" data-project-cwd="${(0,n.esc)(i.cwd||"")}" data-project-machine="${(0,n.esc)(i.machineId||"")}">
|
|
439
439
|
<div class="flex items-center gap-1.5">
|
|
440
440
|
<span class="text-[10px] text-base-content/40 w-3 flex-shrink-0">${c?"\u25BE":"\u25B8"}</span>
|
|
441
441
|
<span class="text-[12px] font-semibold truncate flex-1" title="${(0,n.esc)(i.cwd||"")}">${(0,n.esc)(i.projectName)}</span>
|
|
442
442
|
${l}
|
|
443
|
-
<span class="text-[9px] text-base-content/30 flex-shrink-0">${
|
|
443
|
+
<span class="text-[9px] text-base-content/30 flex-shrink-0">${Dt(i.updatedAt)}</span>
|
|
444
444
|
</div>
|
|
445
445
|
<div class="flex items-center gap-1.5 mt-0.5 pl-4">
|
|
446
|
-
<span class="text-[10px] text-base-content/35 font-mono truncate flex-1" title="${(0,n.esc)(i.cwd||"")}">${(0,n.esc)(
|
|
447
|
-
<span class="flex items-center gap-0.5 flex-shrink-0">${
|
|
446
|
+
<span class="text-[10px] text-base-content/35 font-mono truncate flex-1" title="${(0,n.esc)(i.cwd||"")}">${(0,n.esc)(lt(i.cwd))}</span>
|
|
447
|
+
<span class="flex items-center gap-0.5 flex-shrink-0">${la(i.agents)}</span>
|
|
448
448
|
</div>
|
|
449
449
|
${f&&!c?`<div class="pl-4 mt-0.5 text-[10px] text-base-content/45 truncate" title="${(0,n.esc)(f)}">\u21B3 ${(0,n.esc)(f)}</div>`:""}
|
|
450
|
-
</div>`,
|
|
450
|
+
</div>`,p=i.sessions.slice(0,40),m=i.sessions.length>40?`<div class="px-3 py-1 text-[10px] text-base-content/30">+${i.sessions.length-40} more</div>`:"",b=c?`<div class="pb-1 border-b border-base-300/30">${p.map(g=>fo(g)).join("")}${m}</div>`:"";return d+b}).join("")}function xi(e){if(!Array.isArray(e)||!e.length)return`<div class="px-3 py-6 text-center text-xs text-base-content/40">
|
|
451
451
|
No recent activity.<br>
|
|
452
452
|
<span class="text-base-content/30">Widen the time range or clear filters.</span>
|
|
453
453
|
</div>`;let t=new Map;for(let s of e){let a=(s.updatedAt?new Date(s.updatedAt):new Date).toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric"});t.has(a)||t.set(a,[]),t.get(a).push(s)}return[...t.entries()].map(([s,o])=>`
|
|
454
454
|
<div class="px-2.5 pt-2.5 pb-1 text-[10px] uppercase tracking-wide text-base-content/35 font-medium sticky top-0 bg-base-200/95 backdrop-blur-sm z-[1]">${(0,n.esc)(s)}</div>
|
|
455
|
-
${o.map(a=>
|
|
456
|
-
`).join("")}function
|
|
457
|
-
<div class="px-3 pb-4 flex flex-col gap-1">${a.map(i=>`<button type="button" class="memory-file text-left px-3 py-2 rounded-lg border border-base-300 hover:border-primary hover:bg-primary/5" data-memory-file="${(0,n.esc)(i.id)}" data-memory-agent="${(0,n.esc)(t)}"><span class="font-mono text-xs">${(0,n.esc)(i.name)}</span><span class="ml-2 text-[10px] text-base-content/40">${(0,n.esc)(i.scope||"")}</span></button>`).join("")}<div id="memory-file-content"></div></div>`}catch(t){e.innerHTML=`<div class="p-4 text-error text-xs">${(0,n.esc)(t?.message??String(t))}</div>`}}}async function
|
|
455
|
+
${o.map(a=>fo(a,{showProject:!0})).join("")}
|
|
456
|
+
`).join("")}function mo(){let e=Me.value,t=Array.isArray(We.value)?We.value:[],s=Array.isArray(st.value)?st.value:[];return e==="timeline"?xi(t):bi(s)}function ho(){document.querySelectorAll("[data-view]").forEach(i=>{let r=i.dataset.view===Me.peek();i.classList.toggle("bg-primary/15",r),i.classList.toggle("text-primary",r),i.classList.toggle("font-medium",r),i.classList.toggle("text-base-content/50",!r)}),document.querySelectorAll("[data-agent-filter]").forEach(i=>{i.classList.toggle("active",i.dataset.agentFilter===oe.peek())});let e=(0,n.$)("time-range");e&&e.value!==le.peek()&&(e.value=le.peek());let t=(0,n.$)("search-status");if(!t)return;let s=ge.peek(),o=Array.isArray(s?.results)?s.results:null,a=(R.peek()||"").trim();if(Te.peek())t.classList.remove("hidden"),t.textContent="Searching content\u2026";else if(a&&o)t.classList.remove("hidden"),t.textContent=`${o.length} hit${o.length===1?"":"s"} \xB7 ${le.peek()==="0"?"all time":le.peek()+"d"}${s.deep===!1?"":" (incl. content)"}`;else if(a)t.classList.remove("hidden"),t.textContent="Local filter only \u2014 type to deep-search";else{let i=We.peek(),r=st.peek(),c=Array.isArray(i)?i.length:0,f=Array.isArray(r)?r.length:0;t.classList.remove("hidden"),t.textContent=Me.peek()==="projects"?`${f} project${f===1?"":"s"} \xB7 ${c} session${c===1?"":"s"}`:`${c} recent session${c===1?"":"s"}`}}async function ps(e){let t=(e||"").trim();if(!t){ge.value=null,Te.value=!1;return}Te.value=!0;try{let s=new URLSearchParams({q:t,days:le.peek()||"14",limit:"50",deep:"1"});oe.peek()&&oe.peek()!=="all"&&s.set("agent",oe.peek());let o=await h("GET",`/api/activity?${s}`);R.peek().trim()===t&&(ge.value={q:t.toLowerCase(),results:o.results||[],deep:!0})}catch(s){R.peek().trim()===t&&(ge.value={q:t.toLowerCase(),results:[],error:s.message})}finally{Te.value=!1}}function wn(e){clearTimeout(hi);let t=(e||"").trim();if(!t){ge.value=null,Te.value=!1;return}hi=setTimeout(()=>ps(t),350)}function gi(e){if(!e)return"";if(typeof marked>"u")return`<pre class="whitespace-pre-wrap text-xs">${(0,n.esc)(e)}</pre>`;try{return marked.parse(String(e),{breaks:!0,gfm:!0})}catch{return`<pre class="whitespace-pre-wrap text-xs">${(0,n.esc)(e)}</pre>`}}async function fs(){let e=(0,n.$)("memory-area");if(e){if(!u.sessionId){e.innerHTML='<div class="p-4 text-xs text-base-content/40">Open or resume a session to view its memory.</div>';return}e.innerHTML='<div class="p-4 text-xs text-base-content/40">Loading\u2026</div>';try{let t=u.agent||w.peek()||"claude",s=new URLSearchParams({agent:t}),a=(await h("GET",`/api/sessions/${u.sessionId}/memory?${s}`)).files||[];if(!a.length){e.innerHTML='<div class="p-4 text-base-content/40 text-xs">No memory files available for this agent/session.</div>';return}e.innerHTML=`<div class="p-3 text-[11px] text-base-content/45">${(0,n.esc)(t)} \xB7 ${a.length} memory file${a.length===1?"":"s"} \xB7 click to open</div>
|
|
457
|
+
<div class="px-3 pb-4 flex flex-col gap-1">${a.map(i=>`<button type="button" class="memory-file text-left px-3 py-2 rounded-lg border border-base-300 hover:border-primary hover:bg-primary/5" data-memory-file="${(0,n.esc)(i.id)}" data-memory-agent="${(0,n.esc)(t)}"><span class="font-mono text-xs">${(0,n.esc)(i.name)}</span><span class="ml-2 text-[10px] text-base-content/40">${(0,n.esc)(i.scope||"")}</span></button>`).join("")}<div id="memory-file-content"></div></div>`}catch(t){e.innerHTML=`<div class="p-4 text-error text-xs">${(0,n.esc)(t?.message??String(t))}</div>`}}}async function bo(e,t){let s=(0,n.$)("memory-file-content");if(!(!s||!u.sessionId||!e)){s.innerHTML='<div class="p-3 text-xs text-base-content/40">Loading file\u2026</div>';try{let o=new URLSearchParams({agent:t||u.agent||w.peek()||"claude",file:e}),a=await h("GET",`/api/sessions/${u.sessionId}/memory/file?${o}`);s.innerHTML=`<div class="mt-2 border border-base-300 rounded-lg overflow-hidden"><div class="px-3 py-1.5 bg-base-300/50 text-xs font-mono">${(0,n.esc)(a.name)}</div><div class="px-3 py-2 md">${gi(a.content)}</div></div>`}catch(o){s.innerHTML=`<div class="mt-2 p-3 text-error text-xs">${(0,n.esc)(o?.message??String(o))}</div>`}}}var hi,wt=P(()=>{M();C();J();es();Nt();hi=null});function yi(e,t){ms=e||"",hs=t||""}async function wi(e){let t=(0,n.$)("project-notes-bar");if(t)try{let s=await h("GET",`/api/projects/notes?root=${encodeURIComponent(e)}`);ms=s.goal||"",hs=s.notes||"",Xt(),t.style.display="flex"}catch(s){console.error("Error fetching project notes:",s),t.style.display="none"}}function Xt(){let e=(0,n.$)("project-notes-bar");if(!e)return;let t=ms||"No goal yet \u2014 click Edit",s=hs||"";e.innerHTML=`
|
|
458
458
|
<div class="flex items-start gap-2 w-full">
|
|
459
459
|
<div class="flex-1 min-w-0">
|
|
460
460
|
<div class="truncate">
|
|
@@ -465,24 +465,24 @@ ${t}`:"",s.length?s.join(`
|
|
|
465
465
|
</div>
|
|
466
466
|
<button id="btn-edit-project-notes" class="btn btn-ghost btn-xs px-1.5 hover:bg-base-300 flex-shrink-0">Edit</button>
|
|
467
467
|
</div>
|
|
468
|
-
`}function
|
|
468
|
+
`}function ki(){let e=(0,n.$)("project-notes-bar");e&&(e.innerHTML=`
|
|
469
469
|
<div class="flex flex-col gap-1.5 w-full">
|
|
470
470
|
<div class="flex items-center gap-2">
|
|
471
471
|
<span class="text-[10px] font-bold text-base-content/40 uppercase w-12 flex-shrink-0">Goal</span>
|
|
472
472
|
<input id="project-goal-input" type="text" class="input input-xs input-bordered flex-1 text-xs"
|
|
473
|
-
placeholder="One-line project goal\u2026" value="${(0,n.esc)(
|
|
473
|
+
placeholder="One-line project goal\u2026" value="${(0,n.esc)(ms)}">
|
|
474
474
|
</div>
|
|
475
475
|
<div class="flex items-start gap-2">
|
|
476
476
|
<span class="text-[10px] font-bold text-base-content/40 uppercase w-12 flex-shrink-0 mt-1">Notes</span>
|
|
477
477
|
<textarea id="project-notes-input" rows="2" class="textarea textarea-xs textarea-bordered flex-1 text-xs leading-snug"
|
|
478
|
-
placeholder="Longer project notes (stack, links, status\u2026)">${(0,n.esc)(
|
|
478
|
+
placeholder="Longer project notes (stack, links, status\u2026)">${(0,n.esc)(hs)}</textarea>
|
|
479
479
|
</div>
|
|
480
480
|
<div class="flex items-center gap-1 justify-end">
|
|
481
481
|
<button id="btn-save-project-notes" class="btn btn-primary btn-xs px-2">Save</button>
|
|
482
482
|
<button id="btn-cancel-project-notes" class="btn btn-ghost btn-xs px-2">Cancel</button>
|
|
483
483
|
</div>
|
|
484
484
|
</div>
|
|
485
|
-
`,(0,n.$)("project-goal-input")?.focus())}async function
|
|
485
|
+
`,(0,n.$)("project-goal-input")?.focus())}async function kn(){try{let e=await h("GET","/api/sessions/meta");y.value=e||{}}catch(e){console.warn("session meta load failed",e)}}function he(){let e=(0,n.$)("session-notes-bar");if(!e)return;let t=u.sessionId,s=u.agent||w.peek()||"claude";if(!t){e.style.display="none",e.innerHTML="";return}if(e.querySelector(".session-rename-input"))return;let o=It(s,t),a=(o.notes||"").trim(),i=!!o.favorite,r=!!o.hidden,f=(o.title||"").trim()||t.slice(0,8);e.style.display="flex",e.innerHTML=`
|
|
486
486
|
<div class="flex-1 min-w-0 flex items-center gap-2">
|
|
487
487
|
<button type="button" class="session-fav-btn ${i?"is-fav":""}" data-fav-toggle="1"
|
|
488
488
|
data-fav-session-id="${(0,n.esc)(t)}" data-fav-session-agent="${(0,n.esc)(s)}"
|
|
@@ -502,12 +502,12 @@ ${t}`:"",s.length?s.join(`
|
|
|
502
502
|
id="session-notes-text" title="${(0,n.esc)(a||"Add a note for this session")}">${(0,n.esc)(a||"No session note")}</span>
|
|
503
503
|
</div>
|
|
504
504
|
<button id="btn-edit-session-notes" class="btn btn-ghost btn-xs px-1.5">Note</button>
|
|
505
|
-
`}function
|
|
505
|
+
`}function $i(){let e=(0,n.$)("session-notes-bar");if(!e||!u.sessionId)return;let t=u.agent||w.peek()||"claude",s=It(t,u.sessionId);e.innerHTML=`
|
|
506
506
|
<input id="session-notes-input" type="text" class="input input-xs input-bordered flex-1 text-xs"
|
|
507
507
|
placeholder="Note for this session\u2026" value="${(0,n.esc)(s.notes||"")}">
|
|
508
508
|
<button id="btn-save-session-notes" class="btn btn-primary btn-xs px-2">Save</button>
|
|
509
509
|
<button id="btn-cancel-session-notes" class="btn btn-ghost btn-xs px-2">Cancel</button>
|
|
510
|
-
`;let o=(0,n.$)("session-notes-input");o?.focus(),o?.select()}function
|
|
510
|
+
`;let o=(0,n.$)("session-notes-input");o?.focus(),o?.select()}function bs(){return{favorite:!1,notes:"",title:"",hidden:!1}}function xs(e,t){return{favorite:t.favorite!==void 0?!!t.favorite:!!e.favorite,notes:t.notes!==void 0?String(t.notes||""):String(e.notes||""),title:t.title!==void 0?String(t.title||"").trim():String(e.title||"").trim(),hidden:t.hidden!==void 0?!!t.hidden:!!e.hidden,updatedAt:Date.now()}}function Si(e){return!e?.favorite&&!e?.hidden&&!(e?.notes||"").trim()&&!(e?.title||"").trim()}async function Li(e,t,{machineId:s}={}){let o=s||u.machineId||null,a=U(t,e,o),i=y.peek()?.[a]||bs(),r=!i.favorite;y.value={...y.peek(),[a]:{...i,favorite:r,updatedAt:Date.now()}};try{let c=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,favorite:r,machineId:o||void 0},void 0,{machineId:o||void 0});y.value={...y.peek(),[a]:xs(i,{favorite:c.favorite??r,notes:c.notes,title:c.title,hidden:c.hidden})}}catch(c){y.value={...y.peek(),[a]:i},alert(`Favorite failed: ${c.message}`)}u.sessionId===e&&he()}async function Ei(e,t,{machineId:s}={}){if(!e)return!1;let o=s||u.machineId||null,a=U(t,e,o),i=y.peek()?.[a]||bs(),r=!i.hidden;y.value={...y.peek(),[a]:{...i,hidden:r,updatedAt:Date.now()}};try{let c=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,hidden:r,machineId:o||void 0},void 0,{machineId:o||void 0}),f=xs(i,{favorite:c.favorite,notes:c.notes,title:c.title,hidden:c.hidden??r});if(Si(f)){let l={...y.peek()};delete l[a],y.value=l}else y.value={...y.peek(),[a]:f}}catch(c){return y.value={...y.peek(),[a]:i},alert(`Hide failed: ${c.message}`),!1}return u.sessionId===e&&he(),!0}async function xo(e,t,s,{machineId:o}={}){let a=o||u.machineId||null,i=U(t,e,a),r=y.peek()?.[i]||bs();try{let c=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,notes:s,machineId:a||void 0},void 0,{machineId:a||void 0});y.value={...y.peek(),[i]:xs(r,{favorite:c.favorite,notes:c.notes??s,title:c.title,hidden:c.hidden})}}catch(c){return alert(`Save note failed: ${c.message}`),!1}return!0}async function tl(e,t,s,{machineId:o}={}){if(!e)return!1;let a=o||u.machineId||null,i=U(t,e,a),r=y.peek()?.[i]||bs(),c=String(s||"").trim().slice(0,200);y.value={...y.peek(),[i]:{...r,title:c,updatedAt:Date.now()}};try{let f=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,title:c,machineId:a||void 0},void 0,{machineId:a||void 0}),l=xs(r,{favorite:f.favorite,notes:f.notes,title:f.title!==void 0?f.title:c,hidden:f.hidden});if(Si(l)){let d={...y.peek()};delete d[i],y.value=d}else y.value={...y.peek(),[i]:l}}catch(f){return y.value={...y.peek(),[i]:r},alert(`Rename failed: ${f.message}`),!1}return u.sessionId===e&&he(),!0}function go({sessionId:e,agent:t="claude",machineId:s=null,fallbackDisplay:o="",mountEl:a}={}){if(!e||!a)return;document.querySelectorAll(".session-rename-input").forEach(m=>{m.dispatchEvent(new CustomEvent("session-rename-cancel",{bubbles:!0}))});let r=(It(t,e,s).title||"").trim()||o||e.slice(0,8),c=a.innerHTML,f=a.className;a.classList.add("session-rename-active"),a.innerHTML=`<input type="text" class="session-rename-input input input-xs input-bordered w-full min-w-0 text-xs font-mono"
|
|
511
511
|
value="${(0,n.esc)(r)}"
|
|
512
512
|
placeholder="Session name (empty = original)"
|
|
513
513
|
maxlength="200"
|
|
@@ -515,7 +515,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
515
515
|
data-rename-session-id="${(0,n.esc)(e)}"
|
|
516
516
|
data-rename-session-agent="${(0,n.esc)(t)}"
|
|
517
517
|
data-rename-session-machine="${(0,n.esc)(s||"")}"
|
|
518
|
-
autocomplete="off" spellcheck="false" />`;let l=a.querySelector(".session-rename-input");if(!l)return;let d=!1,
|
|
518
|
+
autocomplete="off" spellcheck="false" />`;let l=a.querySelector(".session-rename-input");if(!l)return;let d=!1,p=async m=>{if(d)return;d=!0;let b=m?l.value:r;if(a.className=f,!m){a.innerHTML=c;return}await tl(e,t,b,{machineId:s}),document.querySelectorAll(".session-rename-input").forEach(g=>g.remove()),u.sessionId===e&&he(),y.value={...y.peek()}};l.addEventListener("keydown",m=>{m.stopPropagation(),m.key==="Enter"?(m.preventDefault(),p(!0)):m.key==="Escape"&&(m.preventDefault(),p(!1))}),l.addEventListener("click",m=>m.stopPropagation()),l.addEventListener("mousedown",m=>m.stopPropagation()),l.addEventListener("session-rename-cancel",()=>p(!1)),l.addEventListener("blur",()=>{setTimeout(()=>p(!0),0)}),requestAnimationFrame(()=>{l.focus(),l.select()})}var ms,hs,$n=P(()=>{M();C();J();ms="",hs=""});var Mi={};Dn(Mi,{closeMachineMenu:()=>St,enterMachine:()=>yo,hideMachinePicker:()=>vs,refreshMachinesList:()=>kt,renderMachineMenuList:()=>Sn,renderMachinePickerList:()=>gs,showMachinePicker:()=>$t,startMachinePolling:()=>vo,syncTopbarMachine:()=>Qe});async function kt(){try{let e=await h("GET","/api/machines");N.value=Array.isArray(e)?e:[]}catch{try{let e=await Tt();e?.machines&&(N.value=e.machines)}catch{}}return N.peek()||[]}function gs(){let e=(0,n.$)("machine-picker-list"),t=(0,n.$)("machine-picker-empty");if(!e)return;let s=N.peek()||[];if(!s.length){e.innerHTML="",t?.classList.remove("hidden");return}t?.classList.add("hidden"),e.innerHTML=s.map(o=>{let a=o.online!==!1,i=[o.hostname,o.platform].filter(Boolean).join(" \xB7 ");return`
|
|
519
519
|
<button type="button" class="machine-pick-card w-full text-left px-4 py-3 rounded-xl border border-base-300
|
|
520
520
|
hover:border-primary hover:bg-primary/5 transition-colors ${a?"":"opacity-50"}"
|
|
521
521
|
data-pick-machine="${(0,n.esc)(o.id)}" ${a?"":"disabled"}>
|
|
@@ -524,7 +524,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
524
524
|
<span class="font-semibold text-sm font-mono">${(0,n.esc)(o.id)}</span>
|
|
525
525
|
</div>
|
|
526
526
|
${i?`<div class="text-xs text-base-content/45 mt-1 pl-4">${(0,n.esc)(i)}</div>`:""}
|
|
527
|
-
</button>`}).join("")}function
|
|
527
|
+
</button>`}).join("")}function $t(){let e=(0,n.$)("machine-picker");if(!e)return;e.classList.remove("hidden"),ee(),ve.value=!1,gs();let t=(0,n.$)("machine-picker-status");if(t){let s=(N.peek()||[]).filter(o=>o.online!==!1).length;t.textContent=`${s} online`}}function vs(){(0,n.$)("machine-picker")?.classList.add("hidden"),ee(),ve.value=!0}function St(){(0,n.$)("machine-menu")?.classList.add("hidden")}function Sn(){let e=(0,n.$)("machine-menu-list"),t=(0,n.$)("machine-menu-empty");if(!e)return;let s=N.peek()||[],o=S.peek()||"";if(!s.length){e.innerHTML="",t?.classList.remove("hidden");return}t?.classList.add("hidden"),e.innerHTML=s.map(a=>{let i=a.online!==!1,r=a.id===o,c=[a.hostname,a.platform].filter(Boolean).join(" \xB7 "),f=a.connectedAt?new Date(a.connectedAt).toLocaleTimeString():"";return`
|
|
528
528
|
<button type="button"
|
|
529
529
|
class="machine-menu-item w-full text-left px-2 py-1.5 rounded-md text-xs
|
|
530
530
|
${r?"bg-primary/15 text-primary":"hover:bg-base-200"}
|
|
@@ -538,8 +538,8 @@ ${t}`:"",s.length?s.join(`
|
|
|
538
538
|
<span class="text-[9px] ${i?"text-success":"text-error"}">${i?"online":"offline"}</span>
|
|
539
539
|
</div>
|
|
540
540
|
${c||f?`<div class="text-[10px] text-base-content/40 pl-3.5 mt-0.5 truncate">${(0,n.esc)(c)}${f?" \xB7 "+(0,n.esc)(f):""}</div>`:""}
|
|
541
|
-
</button>`}).join("")}function
|
|
542
|
-
`):String(L.content??"");
|
|
541
|
+
</button>`}).join("")}function Qe(){let e=(0,n.$)("machine-menu-wrap"),t=(0,n.$)("topbar-machine-label"),s=(0,n.$)("topbar-machine-dot");if(!$.peek()){e?.classList.add("hidden");return}e?.classList.remove("hidden");let o=S.peek()||"",i=(N.peek()||[]).find(c=>c.id===o),r=i?i.online!==!1:!1;t&&(t.textContent=o||"\u9009\u62E9\u673A\u5668"),s&&(s.classList.toggle("bg-success",!!o&&r),s.classList.toggle("bg-warning",!!o&&!r),s.classList.toggle("bg-base-content/30",!o)),Sn()}function vo(){Ii||(Ii=setInterval(async()=>{if(!$.peek()||!u.token)return;await kt(),Qe();let e=S.peek();if(e){let t=(N.peek()||[]).find(s=>s.id===e);if(t&&t.online===!1){let s=(0,n.$)("topbar-machine-label");s&&(s.textContent=`${e} (offline)`)}}},15e3))}async function yo(e,{forceReload:t=!1}={}){if(!e)return;let s=S.peek(),o=s&&s!==e;if(Z(e),vs(),St(),Qe(),o||t){try{u.ws?.close()}catch{}u.ws=null,u.sessionId=null,(0,n.batch)(()=>{v.value=null,q.value=null,W.value=null});try{let{filesRoot:i,gitRoot:r,filesPath:c}=await Promise.resolve().then(()=>(C(),Jo));i.value="",r.value="",c.value=""}catch{}if(o){let{goHome:i}=await Promise.resolve().then(()=>(En(),Ti));i()}}let a=(0,n.$)("topbar-project");a&&!v.peek()&&(a.textContent=`Machine \xB7 ${e}`),gn(),await Promise.all([fe(),Vt(),kn(),Yt().catch(()=>{})]),ve.value=!0}var Ii,Ln=P(()=>{M();C();J();wt();$n();vn();jt();Ii=null});var Ti={};Dn(Ti,{goHome:()=>ks,openProject:()=>wo,resumeSession:()=>be,switchTab:()=>Fe});function ws(e){for(let t of["files-machine-hint","git-machine-hint"]){let s=(0,n.$)(t);s&&(e?(s.textContent=`@${e}`,s.classList.remove("hidden"),s.title=`Paths are on machine ${e}`):(s.textContent="",s.classList.add("hidden"),s.title=""))}}function wo(e){Rt(),Ft(),Ot(),Ut();let t=e?.path||"";(0,n.batch)(()=>{v.value=e,q.value=t,t&&(z.value=t,Q.value=t,j.value="",W.value=null)}),u.sessionId=null,(0,n.$)("topbar-project").textContent=t||"Project";let s=(0,n.$)("files-root-input");s&&t&&(s.value=t);let o=(0,n.$)("git-root-input");o&&t&&(o.value=t),ws(e?.machineId||S.peek()||u.machineId),(0,n.$)("welcome").classList.add("hidden");let a=(0,n.$)("project-view");a.classList.remove("hidden"),a.style.display="flex",qt(),Bt({sessionId:null}),He(),Fe("chat")}function ks(){Rt(),Ft(),Ot(),Ut(),v.value=null,q.value=null,z.value="",Q.value="",j.value="",W.value=null,u.sessionId=null,Bt({sessionId:null}),ws(null),document.documentElement.classList.remove("boot-restore");let e=(0,n.$)("topbar-project");e&&(e.textContent="Select a session");let t=(0,n.$)("welcome");t&&(t.classList.remove("hidden"),t.style.display="",vt(gt()));let s=(0,n.$)("project-view");s&&(s.classList.add("hidden"),s.style.display="none"),Vn("/")}async function be(e,t,s,o,a,i={}){let r=i.tab&&["chat","files","git","shell","memory"].includes(i.tab)?i.tab:"chat",c=i.skipHistory??(r!=="chat"&&r!=="memory"),f=T.peek().find(k=>k.sessionId===e&&(!a||k.machineId===a||!k.machineId)),l=at(),d=l?.sessionId===e?l:null,p=o||f?.agent||d?.agent||"claude",m=a||f?.machineId||d?.machineId||S.peek()||null,b=t||f?.cwd||d?.cwd||null,g=s||f?.configDir||d?.configDir||null;if(Rt(),Ft(),Ot(),Ut(),m&&m!==u.machineId){Z(m);try{u.ws?.close()}catch{}u.ws=null,Promise.resolve().then(()=>(Ln(),Mi)).then(({syncTopbarMachine:k})=>k()).catch(()=>{}),Promise.resolve().then(()=>(wt(),vi)).then(({loadAllSessions:k})=>k()).catch(()=>{})}u.sessionId=e,u.configDir=g,u.agent=p,we(p),me(),Bt({sessionId:e,agent:p,machineId:m});let F=b;Ci(F,m,e),He(),F&&h("POST","/api/resolve-path",{path:F},void 0,{machineId:m||void 0}).then(k=>{u.sessionId!==e||!k?.path||k.path===F||(F=k.path,Ci(F,m,e),Us({sessionId:e,cwd:F}))}).catch(()=>{}),qt(),Fe(r);{let k=T.peek();T.value=Array.isArray(k)?[...k]:[]}Us({sessionId:e,cwd:F||b,configDir:g,agent:p,machineId:m,tab:r}),ci({sessionId:e,cwd:F||b,configDir:g,agent:p,machineId:m,display:f?.display||d?.display||"",projectName:f?.projectName||d?.projectName||"",updatedAt:f?.updatedAt||d?.updatedAt||null});let Ze=B[p]||p,xe=`${m||""}:${p}:${e}`,et=(k,V,tt={})=>{if(u.sessionId!==e)return;if((0,n.$)("messages").innerHTML="",!k.length){x(`${Ze} \xB7 ${e.slice(0,8)}\u2026 \u2014 no history`);return}pe();let Y=40,ue=0,Qt=()=>{if(u.sessionId!==e)return;let jn=Math.min(ue+Y,k.length);for(;ue<jn;ue++){let L=k[ue],Po=A(L.ts??L.timestamp),js=L.type||(L.role?"text":null);if(js==="text"||L.role&&L.content!=null&&!L.name){(L.role==="assistant"||L.role==="user")&&pe();let _o=typeof L.content=="string"?L.content:Array.isArray(L.content)?L.content.map(Ki=>Ki?.text||"").filter(Boolean).join(`
|
|
542
|
+
`):String(L.content??"");_o&&pt(L.role==="user"?"user":"assistant",L.role==="user"?"You":Ze,_o,{ts:Po})}else js==="tool_use"||L.name?Vs({name:L.name||"tool",input:L.input??L.arguments??{}},{ts:Po}):(js==="token_usage"||L.usage)&&(pe(),Ht(L.usage||L))}if(ue<k.length){requestAnimationFrame(Qt);return}pe(),V&&Ks(V);let Zt=k.filter(L=>L.type==="token_usage").length||k.filter(L=>L.role==="user").length,en=tt.truncated?` (showing last ${k.length} of ${tt.total||"?"})`:"";x(`\u2500\u2500 ${Ze} history \xB7 ${Zt} turn${Zt!==1?"s":""}${en} \u2500\u2500`)};Qt()},Ee=async()=>{let k=ys.get(xe);if(k&&k.msgs?.length&&Date.now()-k.at<nl){et(k.msgs,k.context,k.meta);return}x(`Loading ${Ze} history\u2026`);try{let V=m||S.peek()||u.machineId||null;if($.peek()&&!V)throw new Error("\u672A\u9009\u62E9\u673A\u5668\uFF0C\u65E0\u6CD5\u52A0\u8F7D\u5386\u53F2");V&&u.machineId!==V&&Z(V);let tt=async Zt=>{let en=new URLSearchParams({tail:"0",compact:"1"});return Zt&&en.set("agent",Zt),V&&en.set("machine",V),h("GET",`/api/sessions/${e}/messages?${en}`,void 0,void 0,{machineId:V||void 0,dedupe:!1})},Y=await tt(p),ue=Array.isArray(Y)?Y:Y?.messages||[];!ue.length&&p&&(Y=await tt(null),ue=Array.isArray(Y)?Y:Y?.messages||[]);let Qt=Array.isArray(Y)?null:Y?.context||null,jn=Array.isArray(Y)?{}:{truncated:Y?.truncated,total:Y?.total};ue.length?ys.set(xe,{msgs:ue,context:Qt,meta:jn,at:Date.now()}):ys.delete(xe),et(ue,Qt,jn)}catch(V){if(u.sessionId!==e)return;ys.delete(xe),(0,n.$)("messages").innerHTML="",x(`${Ze} \xB7 ${e.slice(0,8)}\u2026 (history unavailable: ${V.message})`)}};c?Ee().catch(()=>{}):(await new Promise(k=>requestAnimationFrame(k)),Ee().catch(()=>{})),Yn(),he()}function Ci(e,t,s){if(e){let o=e.split("/").filter(Boolean).pop()||e;(0,n.batch)(()=>{v.value={id:o,name:o,path:e,machineId:t},q.value=e,z.value=e,Q.value=e,j.value="",W.value=null}),(0,n.$)("topbar-project").textContent=t?`${e} @${t}`:e;let a=(0,n.$)("files-root-input");a&&(a.value=e);let i=(0,n.$)("git-root-input");i&&(i.value=e),ws(t),(0,n.$)("welcome")?.classList.add("hidden");let r=(0,n.$)("project-view");r&&(r.classList.remove("hidden"),r.style.display="flex",r.style.flexDirection="column",r.style.flex="1",r.style.minHeight="0",r.style.overflow="hidden")}else{(0,n.$)("welcome")?.classList.add("hidden");let o=(0,n.$)("project-view");o&&(o.classList.remove("hidden"),o.style.display="flex",o.style.flexDirection="column",o.style.flex="1",o.style.minHeight="0"),ws(t)}}function Fe(e){D.value=e}var ys,nl,En=P(()=>{M();C();J();_n();Wt();Xn();wt();$n();po();ys=new Map,nl=180*1e3});C();J();M();C();J();var Ct=null;function Qo(){return window.matchMedia("(display-mode: standalone)").matches||window.navigator.standalone===!0||document.referrer.includes("android-app://")}function ar(e){let t=String(e||"").replace(/^\[|\]$/g,"");return!!(/^\d{1,3}(\.\d{1,3}){3}$/.test(t)||t.includes(":")&&/^[0-9a-f:]+$/i.test(t))}function ir(){if(!("serviceWorker"in navigator)||!window.isSecureContext)return!1;let e=location.hostname;return e==="localhost"||e==="127.0.0.1"||e==="::1"?!0:ar(e)?!1:location.protocol==="https:"}function Zo(){document.getElementById("btn-pwa-install")?.classList.remove("hidden")}function ea(){Qo()&&document.documentElement.classList.add("pwa-standalone"),window.addEventListener("beforeinstallprompt",s=>{s.preventDefault(),Ct=s,document.dispatchEvent(new CustomEvent("pwa-installable")),Zo()}),window.addEventListener("appinstalled",()=>{Ct=null,document.getElementById("btn-pwa-install")?.classList.add("hidden")});let e=/iPad|iPhone|iPod/.test(navigator.userAgent)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1;if(!Qo()&&(e||/Android/i.test(navigator.userAgent))&&requestAnimationFrame(()=>Zo()),!ir()){"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then(s=>s.forEach(o=>o.unregister())).catch(()=>{});return}let t=()=>{navigator.serviceWorker.register("/sw.js",{scope:"/"}).then(s=>{s.addEventListener("updatefound",()=>{let o=s.installing;o&&o.addEventListener("statechange",()=>{o.state==="installed"&&navigator.serviceWorker.controller&&console.info("[pwa] New version ready \u2014 reload to apply")})})}).catch(()=>{navigator.serviceWorker.getRegistrations().then(s=>s.forEach(o=>o.unregister())).catch(()=>{})})};document.readyState==="complete"?setTimeout(t,0):window.addEventListener("load",()=>setTimeout(t,0))}async function ta(){if(!Ct)return!1;Ct.prompt();let e=await Ct.userChoice.catch(()=>null);return Ct=null,document.getElementById("btn-pwa-install")?.classList.add("hidden"),e?.outcome==="accepted"}jt();_n();Wt();Xn();M();J();C();es();function Ba(){document.getElementById("root").insertAdjacentHTML("beforeend",`
|
|
543
543
|
<dialog id="modal-settings" class="modal">
|
|
544
544
|
<div class="modal-box max-w-lg">
|
|
545
545
|
<h3 class="font-bold text-base mb-4">\u2699\uFE0F Settings \u2014 Workspaces</h3>
|
|
@@ -558,15 +558,15 @@ ${t}`:"",s.length?s.join(`
|
|
|
558
558
|
</div>
|
|
559
559
|
</div>
|
|
560
560
|
<form method="dialog" class="modal-backdrop"><button>close</button></form>
|
|
561
|
-
</dialog>`),
|
|
561
|
+
</dialog>`),ts(),document.getElementById("ws-add-btn").addEventListener("click",Zs),document.getElementById("ws-new-name").addEventListener("keydown",e=>{e.key==="Enter"&&Zs()}),document.getElementById("ws-new-dir").addEventListener("keydown",e=>{e.key==="Enter"&&Zs()})}function ts(){let e=(0,n.$)("ws-list");if(!e)return;let t=H.peek();if(!t.length){e.innerHTML='<div class="text-xs text-base-content/40">No workspaces configured</div>';return}e.innerHTML=t.map(s=>`
|
|
562
562
|
<div class="flex items-center gap-2 px-3 py-2 bg-base-200 rounded-lg">
|
|
563
563
|
<div class="flex-1 min-w-0">
|
|
564
564
|
<div class="text-sm font-medium">${(0,n.esc)(s.name)}</div>
|
|
565
565
|
<div class="text-xs font-mono text-base-content/50 truncate">${(0,n.esc)(s.configDir)}</div>
|
|
566
566
|
</div>
|
|
567
567
|
${t.length>1?`<button class="btn btn-ghost btn-xs text-error" data-ws-delete="${(0,n.esc)(s.id)}">\u2715</button>`:'<span class="text-[10px] text-base-content/30">default</span>'}
|
|
568
|
-
</div>`).join(""),e.querySelectorAll("[data-ws-delete]").forEach(s=>{s.addEventListener("click",()=>
|
|
569
|
-
<div id="auth-screen" class="${
|
|
568
|
+
</div>`).join(""),e.querySelectorAll("[data-ws-delete]").forEach(s=>{s.addEventListener("click",()=>Rr(s.dataset.wsDelete))})}async function Zs(){let e=(0,n.$)("ws-new-name").value.trim(),t=(0,n.$)("ws-new-dir").value.trim(),s=(0,n.$)("ws-error");if(s.classList.add("hidden"),!e||!t){s.textContent="Name and path are required",s.classList.remove("hidden");return}try{let o=await h("POST","/api/workspaces",{name:e,configDir:t});H.value=[...H.peek(),o],mn(H.peek()),(0,n.$)("ws-new-name").value="",(0,n.$)("ws-new-dir").value="",ts()}catch(o){s.textContent=o.message,s.classList.remove("hidden")}}async function Rr(e){try{await h("DELETE",`/api/workspaces/${e}`),H.value=H.peek().filter(t=>t.id!==e),mn(H.peek()),ts()}catch(t){alert(t.message)}}function eo(){ts(),(0,n.$)("modal-settings")?.showModal()}vn();Ws();C();var ti=()=>`
|
|
569
|
+
<div id="auth-screen" class="${u.token?"hidden":""} flex items-center justify-center h-full p-4" ${u.token?'style="display:none"':""}>
|
|
570
570
|
<div class="card bg-base-200 border border-base-300 w-full max-w-sm shadow-xl">
|
|
571
571
|
<div class="card-body gap-3 p-8">
|
|
572
572
|
<h1 class="text-xl font-bold">\u{1F916} Agent UI</h1>
|
|
@@ -585,7 +585,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
585
585
|
<div id="auth-error" class="alert alert-error text-xs py-2 hidden"></div>
|
|
586
586
|
</div>
|
|
587
587
|
</div>
|
|
588
|
-
</div>`,
|
|
588
|
+
</div>`,ni=(e={})=>{let t=!!e.restoreSession,s=u.token?"":"hidden",o=u.token?"display:flex":"display:none";return`
|
|
589
589
|
<div id="sidebar-overlay" class="hidden fixed inset-0 bg-black/50 z-[9]" aria-hidden="true"></div>
|
|
590
590
|
<div id="app" class="${s} flex-col flex-1 overflow-hidden" style="${o}">
|
|
591
591
|
<div id="topbar" class="flex items-center gap-2 px-3 bg-base-200 border-b border-base-300 flex-shrink-0" style="height:44px">
|
|
@@ -976,7 +976,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
976
976
|
</div>
|
|
977
977
|
</div>
|
|
978
978
|
<form method="dialog" class="modal-backdrop"><button>close</button></form>
|
|
979
|
-
</dialog>`};po();
|
|
979
|
+
</dialog>`};po();wt();En();M();C();J();es();_n();wt();$n();vn();En();Ln();jt();async function $s(e={}){(0,n.$)("auth-screen").style.display="none";let t=(0,n.$)("app");t.classList.remove("hidden"),t.style.display="flex",queueMicrotask(ee);let s=e.hub;s===void 0?s=await Tt():s?($.value=!0,s.machines&&(N.value=s.machines)):$.value=!1;let o=e.deepLink||null,a=at();if(!!(o?.id||(location.hash||"").startsWith("#/session/"))){let c=(0,n.$)("welcome");c&&(c.classList.add("hidden"),c.style.display="none");let f=(0,n.$)("project-view");f&&(f.classList.remove("hidden"),f.style.display="flex",f.style.flexDirection="column",f.style.flex="1",f.style.minHeight="0")}if($.peek()){let c=localStorage.getItem("machineId")||a?.machineId||"";c&&(Z(c),vs(),ve.value=!0,gn());let f=kt().then(p=>(Qe(),c&&!p.some(b=>b.id===c&&b.online!==!1)&&p.length&&(p.some(g=>g.id===c)||(Z(null),$t())),p));vo(),Qe();let l=Promise.all([fe({waitFresh:!1}),Vt({waitFresh:!1}),kn().catch(()=>{}),Yt().catch(()=>{})]);if(o?.id){let p=T.peek().find(m=>m.sessionId===o.id)||(a?.sessionId===o.id?a:null);await be(o.id,p?.cwd||a?.cwd||null,p?.configDir||a?.configDir||null,p?.agent||a?.agent||null,p?.machineId||a?.machineId||c||null,{tab:o.tab||"chat"}),f.catch(()=>{}),l.catch(()=>{});return}if(!c){if(await f,!(N.peek()||[]).length){$t(),l.catch(()=>{});return}$t(),l.catch(()=>{});return}await l;let d=(0,n.$)("topbar-project");d&&d.textContent==="Select a session"&&(d.textContent=`Machine \xB7 ${c}`);return}gn();let r=Promise.all([fe({waitFresh:!1}),Vt({waitFresh:!1}),kn().catch(()=>{}),Yt().catch(()=>{})]);if(o?.id){await Zn().then(f=>{Array.isArray(f)?T.value=f:f&&Array.isArray(f.sessions)&&(T.value=f.sessions)}).catch(()=>{});let c=T.peek().find(f=>f.sessionId===o.id)||(a?.sessionId===o.id?a:null);await be(o.id,c?.cwd||a?.cwd||null,c?.configDir||a?.configDir||null,c?.agent||a?.agent||null,null,{tab:o.tab||"chat"}),r.catch(()=>{});return}await r}$n();Ln();M();C();J();Wt();wt();En();Ln();jt();function Ai(){let e=(0,n.$)("sidebar");e&&(e.classList.add("open"),(0,n.$)("sidebar-overlay").classList.remove("hidden"),(0,n.$)("hamburger")?.setAttribute("aria-expanded","true"),ee(),setTimeout(()=>(0,n.$)("session-search")?.focus({preventScroll:!0}),180))}function In(){let e=(0,n.$)("sidebar");e&&(e.classList.remove("open"),(0,n.$)("sidebar-overlay").classList.add("hidden"),(0,n.$)("hamburger")?.setAttribute("aria-expanded","false"),ee(),(0,n.$)("hamburger")?.focus({preventScroll:!0}))}function ji(){window.innerWidth<=640&&In()}function Di(){let e=(0,n.$)("sidebar-toggle"),t=(0,n.$)("sidebar");if(!e||!t)return;let s=localStorage.getItem("sidebarCollapsed")==="1",o=localStorage.getItem("sidebarWidth")||t.style.width||"280px",a=()=>{t.classList.toggle("desktop-collapsed",s),s?(t.style.width="0",t.style.minWidth="0",t.style.overflow="hidden"):(t.style.width=o,t.style.minWidth="",t.style.overflow=""),e.textContent=s?"\u25B6":"\u25C0",e.title=s?"\u5C55\u5F00\u4FA7\u680F":"\u6536\u8D77\u4FA7\u680F",e.setAttribute("aria-label",e.title),e.setAttribute("aria-expanded",s?"false":"true")};a(),e.addEventListener("click",()=>{s=!s,s&&(o=t.style.width||o),localStorage.setItem("sidebarCollapsed",s?"1":"0"),a()})}function Ni(){let e=(0,n.$)("sidebar-resize"),t=(0,n.$)("sidebar"),s=!1;e.addEventListener("mousedown",o=>{s=!0,document.body.style.userSelect="none",document.body.style.cursor="col-resize",o.preventDefault()}),document.addEventListener("mousemove",o=>{if(!s)return;let a=Math.min(Math.max(o.clientX,160),520);t.style.width=a+"px",t.style.minWidth=""}),document.addEventListener("mouseup",()=>{if(!s)return;s=!1,document.body.style.userSelect="",document.body.style.cursor="";let o=Math.round(t.getBoundingClientRect().width);o>=160&&localStorage.setItem("sidebarWidth",`${o}px`)})}function ko(e){document.documentElement.setAttribute("data-theme",e),localStorage.setItem("theme",e);let t=(0,n.$)("btn-theme"),s=e==="dark"||e==="night"||e==="black"?"\u{1F319}":"\u2600\uFE0F";t&&(t.textContent=s),document.querySelectorAll('[data-sidebar-action="theme"]').forEach(a=>{a.textContent=s});let o=document.getElementById("hljs-theme");if(o||(o=document.querySelector('link[href*="highlight"][href*="styles"]'),o&&(o.id="hljs-theme")),o){let a=e==="dark"||e==="night"||e==="black";o.href=a?"https://cdn.jsdelivr.net/npm/@highlightjs/cdn-assets@11/styles/github-dark.min.css":"https://cdn.jsdelivr.net/npm/@highlightjs/cdn-assets@11/styles/github.min.css"}}function $o(){let e=document.documentElement.getAttribute("data-theme")||"dark";ko(e==="dark"?"light":"dark")}function So(){let e=(0,n.$)("new-session-agent");e&&(e.value=w.peek()||"claude");let t=(0,n.$)("new-session-workspace");if(t){let a=H.peek();t.innerHTML=a.map(i=>`<option value="${(0,n.esc)(i.configDir)}">${(0,n.esc)(i.name)} \u2014 ${(0,n.esc)(i.configDir)}</option>`).join(""),u.configDir&&(t.value=u.configDir)}let s=(0,n.$)("new-session-machine-wrap"),o=(0,n.$)("new-session-machine");if(s&&o)if($.peek()){s.style.display="";let a=N.peek()||[],i=S.peek()||"";o.innerHTML=a.length?a.map(r=>`<option value="${(0,n.esc)(r.id)}">${(0,n.esc)(r.id)}${r.hostname?" \u2014 "+(0,n.esc)(r.hostname):""}</option>`).join(""):'<option value="">(no machines online)</option>',i&&(o.value=i),o.disabled=!0}else s.style.display="none",o&&(o.disabled=!1);Lo(),(0,n.$)("new-session-path").value=v.peek()?.path||"",(0,n.$)("new-session-error").classList.add("hidden"),(0,n.$)("modal-new-session").showModal(),setTimeout(()=>(0,n.$)("new-session-path").focus(),50)}function Lo(){let e=(0,n.$)("new-session-agent")?.value||"claude",t=(0,n.$)("new-session-ws-wrap");t&&(t.style.display=e==="claude"?"":"none")}async function Eo(){let e=(0,n.$)("new-session-path").value.trim(),t=(0,n.$)("new-session-agent")?.value||"claude",s=t==="claude"?(0,n.$)("new-session-workspace").value:null,o=(0,n.$)("new-session-error");if(o.classList.add("hidden"),!e){o.textContent="Working directory is required",o.classList.remove("hidden");return}if($.peek()){let a=S.peek()||(0,n.$)("new-session-machine")?.value||N.peek()?.[0]?.id;if(!a){o.textContent="\u8BF7\u5148\u9009\u62E9\u4E00\u53F0\u673A\u5668",o.classList.remove("hidden"),$t();return}Z(a)}try{let a=await h("POST","/api/resolve-path",{path:e});if(!a.isDir)throw new Error("Path is not a directory");(0,n.$)("modal-new-session").close();let i=a.path.split("/").filter(Boolean).pop()||a.path;Rt(),Ft(),Ot(),Ut(),u.sessionId=null,u.configDir=s||null,u.agent=t,we(t),G(ye(t)||E.peek()),me(),(0,n.batch)(()=>{v.value={id:i,name:i,path:a.path,machineId:S.peek()||u.machineId},q.value=a.path,z.value=a.path,Q.value=a.path,j.value="",W.value=null}),(0,n.$)("topbar-project").textContent=a.path;let r=(0,n.$)("files-root-input");r&&(r.value=a.path);let c=(0,n.$)("git-root-input");c&&(c.value=a.path),(0,n.$)("welcome").classList.add("hidden");let f=(0,n.$)("project-view");f.classList.remove("hidden"),f.style.display="flex",qt(),Bt({sessionId:null}),He(),Fe("chat"),x(`New ${B[t]||t} session \xB7 ${a.path}`)}catch(a){o.textContent=a.message,o.classList.remove("hidden")}}function sl(){let e=/iPad|iPhone|iPod/.test(navigator.userAgent)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1,t=/Android/i.test(navigator.userAgent),s;e?s=`<ol class="list-decimal pl-4 space-y-2 text-sm text-base-content/80">
|
|
980
980
|
<li>\u70B9\u5E95\u90E8\u5206\u4EAB\u6309\u94AE <strong>\u5206\u4EAB</strong>\uFF08\u65B9\u6846+\u5411\u4E0A\u7BAD\u5934\uFF09</li>
|
|
981
981
|
<li>\u4E0B\u6ED1\u627E\u5230\u5E76\u70B9 <strong>\u6DFB\u52A0\u5230\u4E3B\u5C4F\u5E55</strong></li>
|
|
982
982
|
<li>\u786E\u8BA4\u540D\u79F0\u540E\u70B9 <strong>\u6DFB\u52A0</strong></li>
|
|
@@ -995,29 +995,29 @@ ${t}`:"",s.length?s.join(`
|
|
|
995
995
|
<form method="dialog"><button class="btn btn-sm">\u77E5\u9053\u4E86</button></form>
|
|
996
996
|
</div>
|
|
997
997
|
</div>
|
|
998
|
-
<form method="dialog" class="modal-backdrop"><button>close</button></form>`,o.showModal()}async function
|
|
999
|
-
${(m.id===null?!
|
|
998
|
+
<form method="dialog" class="modal-backdrop"><button>close</button></form>`,o.showModal()}async function Mo(){let e=(0,n.$)("auth-screen");e&&(e.classList.remove("hidden"),e.style.display="flex");let t=(0,n.$)("app");t&&(t.classList.add("hidden"),t.style.display="none");let s=(0,n.$)("auth-btn"),o,a=new AbortController,i=setTimeout(()=>a.abort(),8e3);try{o=await h("GET","/api/auth/status",void 0,a.signal)}catch(r){console.warn("[auth status]",r);let c=(0,n.$)("auth-error");c&&(c.textContent="\u65E0\u6CD5\u8FDE\u63A5\u670D\u52A1\u5668\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u6216\u670D\u52A1\u5730\u5740\u540E\u91CD\u8BD5\u3002",c.classList.remove("hidden")),s&&(s.dataset.mode="login");return}finally{clearTimeout(i)}o.needsSetup?((0,n.$)("auth-subtitle").textContent="Create your account to get started",s.textContent="Create Account",s.dataset.mode="register"):s.dataset.mode="login"}async function Io(){let e=(0,n.$)("auth-username").value.trim(),t=(0,n.$)("auth-password").value,s=(0,n.$)("auth-error");s.classList.add("hidden");try{let o=await h("POST",`/api/auth/${(0,n.$)("auth-btn").dataset.mode||"login"}`,{username:e,password:t});u.token=o.token,localStorage.setItem("token",o.token),$s()}catch(o){s.textContent=o.message,s.classList.remove("hidden")}}function To(){return u.token?/^#\/session\//.test(location.hash||""):!1}function Pi(e={}){if(ko(localStorage.getItem("theme")||"dark"),!document.getElementById("xterm-css")){let l=document.createElement("link");l.id="xterm-css",l.rel="stylesheet",l.href="/xterm.min.css",document.head.appendChild(l)}if(!document.getElementById("xterm-js")){let l=document.createElement("script");l.id="xterm-js",l.src="/xterm.min.js",document.head.appendChild(l)}if(!document.getElementById("xterm-fit-js")){let l=document.createElement("script");l.id="xterm-fit-js",l.src="/addon-fit.min.js",document.head.appendChild(l)}let t=e.restoreSession??To(),s=document.getElementById("root");if(s.style.cssText="display:flex;flex-direction:column;flex:1;height:100%",s.innerHTML=ti()+ni({restoreSession:t}),t){let l=(0,n.$)("session-list");l&&(l.innerHTML='<div class="px-3 py-3 text-[10px] text-base-content/35">Loading sessions\u2026</div>')}(0,n.effect)(()=>{let l=H.value,d=(0,n.$)("ws-tabs");if(!d)return;if(l.length<=1){d.innerHTML="";return}let p=q.peek();d.innerHTML=[{id:null,name:"All"},...l].map(m=>`<button class="px-3 py-1.5 text-[11px] flex-shrink-0 border-b-2 whitespace-nowrap
|
|
999
|
+
${(m.id===null?!p:p===m.configDir)?"border-primary text-primary":"border-transparent text-base-content/50 hover:text-base-content"}"
|
|
1000
1000
|
data-ws-tab="${(0,n.esc)(m.configDir||"")}">
|
|
1001
1001
|
${(0,n.esc)(m.name)}
|
|
1002
|
-
</button>`).join("")}),(0,n.effect)(()=>{qe.value,tt.value,Me.value,Te.value,ge.value,y.value;let l=(0,n.$)("session-list");l&&(l.querySelector(".session-rename-input")||(l.innerHTML=fo(),mo()))}),(0,n.effect)(()=>{M.value,se.value,S.value,$.value;let l=(0,n.$)("welcome");l&&(document.documentElement.classList.contains("boot-restore")||document.documentElement.classList.contains("boot-pending")||l.classList.contains("hidden")||l.style.display==="none"||xt())}),(0,n.watch)(O,l=>{let d=(0,n.$)("session-filter-badge");d&&(d.style.display=l?"inline":"none",d.title=l||"")}),(0,n.effect)(()=>{let l=v.value;if(l&&l.path)yi(l.path);else{let d=(0,n.$)("project-notes-bar");d&&(d.style.display="none")}}),(0,n.watch)(D,l=>{document.querySelectorAll("[data-tab]").forEach(u=>{let m=u.dataset.tab===l;u.classList.toggle("text-primary",m),u.classList.toggle("border-primary",m),u.classList.toggle("text-base-content/50",!m),u.classList.toggle("border-transparent",!m)});let d=(0,n.$)("project-view");d&&!d.classList.contains("hidden")&&(d.style.display="flex",d.style.flexDirection="column",d.style.minHeight="0",d.style.flex="1"),["chat","files","git","shell","memory"].forEach(u=>{let m=(0,n.$)(`tab-${u}`);if(!m)return;let b=u===l;m.classList.toggle("hidden",!b),b?(m.style.display="flex",m.style.flexDirection="column",m.style.flex="1 1 0",m.style.minHeight="0",m.style.overflow="hidden"):m.style.display="none"}),l==="memory"&&us(),l==="shell"&&requestAnimationFrame(()=>{document.dispatchEvent(new CustomEvent("shell-tab-shown"))}),Z()}),Di(),ji(),ma({openSession:be});let o=null;document.addEventListener("sessions-changed",()=>{o&&clearTimeout(o),o=setTimeout(()=>{o=null,fe({waitFresh:!1})},1200)}),document.addEventListener("router:home",ws),document.addEventListener("router:session",async({detail:{id:l,tab:d}})=>{let u=M.peek().find(b=>b.sessionId===l),m=st();await be(l,u?.cwd||(m?.sessionId===l?m.cwd:null)||null,u?.configDir||(m?.sessionId===l?m.configDir:null)||null,u?.agent||(m?.sessionId===l?m.agent:null)||null,u?.machineId||(m?.sessionId===l?m.machineId:null)||null,{tab:d||"chat"})}),n.delegate.on("click","#btn-home",ws),n.delegate.on("click","#auth-btn",Eo),n.delegate.on("submit","#auth-form",l=>{l.preventDefault(),Eo()}),n.delegate.on("keydown","#auth-username, #auth-password",l=>{l.key==="Enter"&&Eo()}),n.delegate.on("click","#hamburger",()=>(0,n.$)("sidebar").classList.contains("open")?En():Ci()),n.delegate.on("click","#sidebar-overlay",En),document.addEventListener("keydown",l=>{l.key==="Escape"&&window.innerWidth<=640&&(0,n.$)("sidebar")?.classList.contains("open")&&(l.preventDefault(),En())}),n.delegate.on("input","#session-search",(l,d)=>{R.value=d.value,yn(d.value)}),n.delegate.on("click","#session-filter-badge",()=>{O.value=null}),n.delegate.on("click","[data-ws-tab]",(l,d)=>{O.value=d.dataset.wsTab||null}),n.delegate.on("click","#sidebar-refresh",()=>{fe(),R.peek().trim()&&ps(R.peek())}),n.delegate.on("click","[data-view]",(l,d)=>{Me.value=d.dataset.view,localStorage.setItem("sidebarView",d.dataset.view)}),n.delegate.on("click","[data-agent-filter]",(l,d)=>{se.value=d.dataset.agentFilter,localStorage.setItem("agentFilter",d.dataset.agentFilter),R.peek().trim()&&yn(R.peek())}),n.delegate.on("change","#time-range",(l,d)=>{le.value=d.value,localStorage.setItem("timeRange",d.value),fe({waitFresh:!0}),R.peek().trim()&&yn(R.peek())}),n.delegate.on("dblclick","[data-project-cwd]",(l,d)=>{let u=d.dataset.projectCwd;if(!u)return;let m=u.split("/").filter(Boolean).pop()||u;yo({id:m,name:m,path:u}),x(`Project \xB7 ${u}`)}),n.delegate.on("click","#btn-pwa-install",async()=>{await ea()||nl()}),document.addEventListener("pwa-installable",()=>{document.getElementById("btn-pwa-install")?.classList.remove("hidden")}),n.delegate.on("click","#btn-settings",Zs),n.delegate.on("click","#btn-meta-agent",()=>Ja()),n.delegate.on("click","#btn-meta-agent-welcome",()=>no("chat")),n.delegate.on("click","#btn-theme",ko),n.delegate.on("click","[data-sidebar-action]",(l,d)=>{let u=d.dataset.sidebarAction;u==="new"&&$o(),u==="theme"&&ko(),u==="settings"&&Zs(),u==="logout"&&(p.token=null,localStorage.removeItem("token"),Q(null),ve.value=!1,location.reload())}),n.delegate.on("click","#btn-cal-prev",()=>{co(-1),xt(bt())}),n.delegate.on("click","#btn-cal-next",()=>{co(1),xt(bt())}),n.delegate.on("click","[data-cal-date]",(l,d)=>{ui(d.dataset.calDate),xt(bt())}),n.delegate.on("click","[data-session-id]",(l,d)=>{l.target.closest("[data-fav-toggle]")||l.target.closest("[data-hide-toggle]")||l.target.closest("[data-rename-session]")||l.target.closest(".session-rename-input")||l.target.closest(".session-title-wrap.session-rename-active")||(be(d.dataset.sessionId,d.dataset.sessionCwd||null,d.dataset.sessionConfigDir||null,d.dataset.sessionAgent||"claude",d.dataset.sessionMachine||null),Ai())}),n.delegate.on("click","[data-rename-session]",(l,d)=>{l.preventDefault(),l.stopPropagation();let u=d.closest(".session-title-wrap")||d,m=u.dataset.renameSessionId||u.dataset.sessionId;m&&xo({sessionId:m,agent:u.dataset.renameSessionAgent||"claude",machineId:u.dataset.renameSessionMachine||null,fallbackDisplay:u.dataset.renameSessionDisplay||"",mountEl:u})}),n.delegate.on("click","[data-rename-bar]",(l,d)=>{if(l.preventDefault(),l.stopPropagation(),!p.sessionId)return;let u=document.getElementById("session-title-display")||d;xo({sessionId:p.sessionId,agent:p.agent||w.peek()||"claude",machineId:p.machineId||null,mountEl:u})}),n.delegate.on("click","[data-folder]",(l,d)=>{let u=d.dataset.folder,b=d.querySelector("span")?.textContent.trim()==="\u25BE",g=new Set($t.peek()),F=new Set(St.peek());b?(g.delete(u),F.add(u)):(g.add(u),F.delete(u)),(0,n.batch)(()=>{$t.value=g,St.value=F})}),n.delegate.on("click","#memory-refresh",us),n.delegate.on("click","[data-memory-file]",l=>ho(l.dataset.memoryFile,l.dataset.memoryAgent)),n.delegate.on("click","[data-tab]",(l,d)=>Be(d.dataset.tab));let a=async(l,d)=>{let u=(0,n.$)(l),m=u?.value.trim();if(!m){d.value="";return}try{let b=await h("POST","/api/resolve-path",{path:m});if(b.isDir===!1)throw new Error("Path is not a directory on the target machine");d.value=b.path,u.value=b.path;let g=v.peek();g&&(v.value={...g,path:b.path})}catch(b){u.style.color="oklch(var(--er))",u.title=b.message,setTimeout(()=>{u.style.color="",u.title=""},2e3)}};n.delegate.on("click","#files-root-btn",()=>a("files-root-input",G)),n.delegate.on("click","#git-root-btn",()=>a("git-root-input",X)),n.delegate.on("keydown","#files-root-input",l=>{l.key==="Enter"&&a("files-root-input",G)}),n.delegate.on("keydown","#git-root-input",l=>{l.key==="Enter"&&a("git-root-input",X)}),n.delegate.on("click","#btn-opts",()=>{(0,n.$)("chat-opts").classList.toggle("hidden"),Z()}),n.delegate.on("change","#sel-agent",(l,d)=>{let u=w.peek(),m=d.value;u!==m&&(p.sessionId=null,we(m),W(ye(m)||T.peek()),(0,n.$)("sel-permission").value=ie.peek(),me(),x(`Agent \u2192 ${B[m]||m} \xB7 model ${T.peek()} \xB7 new session`))}),n.delegate.on("change","#sel-convert-agent",async(l,d)=>{let u=d.value;if(!u)return;let m=p.sessionId;if(!m){alert("No active session to convert."),d.value="";return}let b=p.agent||w.peek()||"claude";if(b===u){alert("Cannot convert to the same agent."),d.value="";return}d.disabled=!0,x(`Converting session ${m.slice(0,8)} from ${b} to ${u}...`);try{let g=await h("POST",`/api/sessions/${m}/convert`,{targetAgent:u,sourceAgent:b});g&&g.success?(x(`\u2713 Converted successfully. New session: ${g.targetSessionId.slice(0,8)}`),await fe(),await be(g.targetSessionId,v.peek()?.path||null,null,g.targetAgent),Vn()):x("Failed to convert session.")}catch(g){x(`Error converting session: ${g.message}`),alert(`Error converting session: ${g.message}`)}finally{d.disabled=!1,d.value=""}}),n.delegate.on("change","#sel-model",(l,d)=>{W(d.value),cs()}),n.delegate.on("click","#btn-model-add",()=>ds({editCurrent:!1})),n.delegate.on("click","#btn-model-edit",()=>ds({editCurrent:!0})),n.delegate.on("change","#sel-effort",(l,d)=>{re.value=d.value}),n.delegate.on("change","#sel-permission",(l,d)=>{ie.value=d.value}),n.delegate.on("change","#sel-density",(l,d)=>{_s(d.value),x(`Density \u2192 ${d.value} (applies to new tool calls; reload session to re-group history)`)}),document.addEventListener("agent-changed",me),n.delegate.on("click","#btn-new-session, #btn-new-session-welcome",$o),n.delegate.on("click","#new-session-cancel",()=>(0,n.$)("modal-new-session").close()),n.delegate.on("click","#new-session-start",Lo),n.delegate.on("change","#new-session-agent",So),n.delegate.on("keydown","#new-session-path",l=>{l.key==="Enter"&&Lo()}),n.delegate.on("click","#send-btn",un),n.delegate.on("click","#stop-btn",Ea),n.delegate.on("click","#btn-logout",()=>{p.token=null,localStorage.removeItem("token"),Q(null),ve.value=!1,location.reload()}),n.delegate.on("click","[data-pick-machine]",async(l,d)=>{let u=d.dataset.pickMachine;if(!u||u===S.peek()){kt();return}await vo(u,{forceReload:!0}),_n()});let i=async()=>{let l=(0,n.$)("machine-picker-status");if(l&&(l.textContent="\u5237\u65B0\u4E2D\u2026"),await yt(),xs(),$n(),Xe(),l){let d=(N.peek()||[]).filter(u=>u.online!==!1).length;l.textContent=`${d} online`}};n.delegate.on("click","#btn-refresh-machines",i),n.delegate.on("click","#btn-refresh-machines-menu",async l=>{l.stopPropagation(),await i()}),n.delegate.on("click","#btn-machine-menu",async l=>{l.stopPropagation(),gt(),lt();let d=(0,n.$)("machine-menu");d&&(d.classList.contains("hidden")?(await yt(),$n(),d.classList.remove("hidden")):d.classList.add("hidden"))}),n.delegate.on("click","#btn-recent-sessions",l=>{l.preventDefault(),l.stopPropagation(),kt(),lt(),pi();let d=!(0,n.$)("recent-menu")?.classList.contains("hidden"),u=(0,n.$)("btn-recent-sessions");u&&u.setAttribute("aria-expanded",d?"true":"false")}),n.delegate.on("click","#recent-menu-backdrop",l=>{l.preventDefault(),l.stopPropagation(),gt(),(0,n.$)("btn-recent-sessions")?.setAttribute("aria-expanded","false")}),document.addEventListener("click",l=>{let d=(0,n.$)("machine-menu-wrap");d&&!d.contains(l.target)&&kt();let u=(0,n.$)("recent-menu"),m=(0,n.$)("btn-recent-sessions"),b=l.target;if(u&&!u.classList.contains("hidden")){if(u.contains(b)||m?.contains(b))return;gt(),m?.setAttribute("aria-expanded","false")}}),n.delegate.on("click","#btn-notifications",l=>{l.preventDefault(),l.stopPropagation(),kt(),gt(),ua()}),window.addEventListener("resize",()=>{(0,n.$)("recent-menu")&&!(0,n.$)("recent-menu").classList.contains("hidden")&&ro()}),n.delegate.on("click","#recent-menu [data-session-id]",()=>{gt(),(0,n.$)("btn-recent-sessions")?.setAttribute("aria-expanded","false")}),n.delegate.on("click","[data-dismiss-recent-session]",(l,d)=>{l.preventDefault(),l.stopPropagation(),ci({sessionId:d.dataset.dismissRecentSession,agent:d.dataset.dismissRecentAgent||"claude",machineId:d.dataset.dismissRecentMachine||null})}),n.delegate.on("click","#btn-edit-project-notes, #project-goal-text, #project-notes-text",()=>{wi()}),n.delegate.on("click","#btn-cancel-project-notes",()=>{Yt()});let r=async()=>{let l=(0,n.$)("project-goal-input")?.value?.trim()??"",d=(0,n.$)("project-notes-input")?.value?.trim()??"",u=v.peek();if(!(!u||!u.path))try{let m=await h("POST","/api/projects/notes",{root:u.path,goal:l,notes:d});vi(m.goal||"",m.notes||""),Yt()}catch(m){alert(`Error saving project notes: ${m.message}`)}};n.delegate.on("click","#btn-save-project-notes",r),n.delegate.on("keydown","#project-goal-input",l=>{l.key==="Enter"&&r(),l.key==="Escape"&&Yt()}),n.delegate.on("keydown","#project-notes-input",l=>{l.key==="Escape"&&Yt()}),n.delegate.on("click","[data-fav-toggle]",(l,d)=>{l.stopPropagation(),l.preventDefault();let u=d.dataset.favSessionMachine||p.machineId;u&&(p.machineId=u,localStorage.setItem("machineId",u)),Si(d.dataset.favSessionId,d.dataset.favSessionAgent||"claude",{machineId:u||null})}),n.delegate.on("click","[data-hide-toggle]",(l,d)=>{l.stopPropagation(),l.preventDefault();let u=d.dataset.hideSessionMachine||p.machineId;u&&(p.machineId=u,localStorage.setItem("machineId",u)),Li(d.dataset.hideSessionId,d.dataset.hideSessionAgent||"claude",{machineId:u||null})}),n.delegate.on("click","#btn-edit-session-notes, #session-notes-text",()=>{ki()}),n.delegate.on("click","#btn-cancel-session-notes",()=>he()),n.delegate.on("click","#btn-save-session-notes",async()=>{let l=(0,n.$)("session-notes-input")?.value?.trim()||"";if(!p.sessionId)return;let d=p.agent||w.peek()||"claude";await bo(p.sessionId,d,l)&&he()}),n.delegate.on("keydown","#session-notes-input",async l=>{if(l.key==="Escape"&&he(),l.key==="Enter"){let d=l.target.value.trim();if(!p.sessionId)return;let u=p.agent||w.peek()||"claude";await bo(p.sessionId,u,d)&&he()}}),n.delegate.on("click","#btn-fav-filter",()=>{let l=!Fe.peek();Fe.value=l,localStorage.setItem("favoritesOnly",l?"1":"0"),(0,n.$)("btn-fav-filter")?.classList.toggle("active",l),l&&Ue.peek()&&(Ue.value=!1,localStorage.setItem("showHiddenOnly","0"),(0,n.$)("btn-hidden-filter")?.classList.remove("active"))}),n.delegate.on("click","#btn-hidden-filter",()=>{let l=!Ue.peek();Ue.value=l,localStorage.setItem("showHiddenOnly",l?"1":"0"),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",l),l&&Fe.peek()&&(Fe.value=!1,localStorage.setItem("favoritesOnly","0"),(0,n.$)("btn-fav-filter")?.classList.remove("active"))}),me(),(0,n.effect)(()=>{$.value,S.value,p.token&&_n()}),(0,n.$)("sel-permission").value=ie.peek(),Jn();let c=(0,n.$)("sel-density");c&&(c.value=Ce.peek()||"normal");let f=(0,n.$)("time-range");f&&(f.value=le.peek()||"14"),document.querySelectorAll("[data-agent-filter]").forEach(l=>{l.classList.toggle("active",l.dataset.agentFilter===se.peek())}),(0,n.$)("btn-fav-filter")?.classList.toggle("active",Fe.peek()),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",Ue.peek()),document.querySelectorAll("[data-view]").forEach(l=>{let d=l.dataset.view===Me.peek();l.classList.toggle("bg-primary/15",d),l.classList.toggle("text-primary",d),l.classList.toggle("font-medium",d),l.classList.toggle("text-base-content/50",!d)})}qt();I();C();z();function sl(e){let t=e.split(".").pop()?.toLowerCase();return{js:"\u{1F4C4}",ts:"\u{1F4C4}",jsx:"\u{1F4C4}",tsx:"\u{1F4C4}",py:"\u{1F40D}",md:"\u{1F4DD}",json:"\u2699\uFE0F",html:"\u{1F310}",css:"\u{1F3A8}",sh:"\u26A1",env:"\u{1F511}",docx:"\u{1F4D8}",pptx:"\u{1F4D9}",xlsx:"\u{1F4D7}",pdf:"\u{1F4D5}"}[t]||"\u{1F4C4}"}function ol(e){let t=(e||"").split("/").pop()||"",s=t.lastIndexOf(".");return s>=0?t.slice(s+1).toLowerCase():""}function Pi(e){let t=ol(e);return t==="docx"||t==="pptx"||t==="xlsx"||t==="pdf"?t:null}function al(e){return e==null?"":e>1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:e>1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function il(e){let t=atob(e),s=new Uint8Array(t.length);for(let o=0;o<t.length;o++)s[o]=t.charCodeAt(o);return s.buffer}var To=new Map;function $s(e){if(To.has(e))return To.get(e);let t=new Promise((s,o)=>{let a=document.querySelector(`script[data-src="${e}"]`);if(a){if(a.dataset.loaded==="1")return s();a.addEventListener("load",()=>s()),a.addEventListener("error",()=>o(new Error(`Failed to load ${e}`)));return}let i=document.createElement("script");i.src=e,i.async=!0,i.dataset.src=e,i.onload=()=>{i.dataset.loaded="1",s()},i.onerror=()=>o(new Error(`Failed to load ${e}`)),document.head.appendChild(i)});return To.set(e,t),t}function rl(e){let s=((e||"").split("/").pop()||"").toLowerCase(),o={dockerfile:"dockerfile",makefile:"makefile",gemfile:"ruby",rakefile:"ruby",procfile:"yaml","cmakelists.txt":"cmake"};if(o[s])return o[s];let a=s.includes(".")?s.split(".").pop():"";return{js:"javascript",mjs:"javascript",cjs:"javascript",jsx:"javascript",ts:"typescript",tsx:"typescript",mts:"typescript",cts:"typescript",py:"python",pyw:"python",pyi:"python",rb:"ruby",go:"go",rs:"rust",java:"java",kt:"kotlin",kts:"kotlin",c:"c",h:"c",cpp:"cpp",cc:"cpp",cxx:"cpp",hpp:"cpp",hh:"cpp",cs:"csharp",swift:"swift",php:"php",scala:"scala",sh:"bash",bash:"bash",zsh:"bash",fish:"bash",ps1:"powershell",psm1:"powershell",html:"xml",htm:"xml",xhtml:"xml",xml:"xml",svg:"xml",css:"css",scss:"scss",less:"less",json:"json",jsonc:"json",json5:"json",yml:"yaml",yaml:"yaml",toml:"ini",ini:"ini",conf:"ini",env:"bash",md:"markdown",mdx:"markdown",markdown:"markdown",sql:"sql",graphql:"graphql",gql:"graphql",vue:"xml",svelte:"xml",r:"r",lua:"lua",pl:"perl",pm:"perl",dart:"dart",ex:"elixir",exs:"elixir",erl:"erlang",zig:"zig",nim:"nim",clj:"clojure",cljs:"clojure",diff:"diff",patch:"diff",dockerfile:"dockerfile"}[a]||""}function ll(e){!e||typeof hljs>"u"||e.querySelectorAll("pre code.file-preview-code").forEach(t=>{try{delete t.dataset.highlighted,hljs.highlightElement(t)}catch{}})}function In(e,t,s){let o=al(t);return`
|
|
1002
|
+
</button>`).join("")}),(0,n.effect)(()=>{We.value,st.value,Me.value,Te.value,ge.value,y.value;let l=(0,n.$)("session-list");l&&(l.querySelector(".session-rename-input")||(l.innerHTML=mo(),ho()))}),(0,n.effect)(()=>{T.value,oe.value,S.value,$.value;let l=(0,n.$)("welcome");l&&(document.documentElement.classList.contains("boot-restore")||document.documentElement.classList.contains("boot-pending")||l.classList.contains("hidden")||l.style.display==="none"||vt())}),(0,n.watch)(q,l=>{let d=(0,n.$)("session-filter-badge");d&&(d.style.display=l?"inline":"none",d.title=l||"")}),(0,n.effect)(()=>{let l=v.value;if(l&&l.path)wi(l.path);else{let d=(0,n.$)("project-notes-bar");d&&(d.style.display="none")}}),(0,n.watch)(D,l=>{document.querySelectorAll("[data-tab]").forEach(p=>{let m=p.dataset.tab===l;p.classList.toggle("text-primary",m),p.classList.toggle("border-primary",m),p.classList.toggle("text-base-content/50",!m),p.classList.toggle("border-transparent",!m)});let d=(0,n.$)("project-view");d&&!d.classList.contains("hidden")&&(d.style.display="flex",d.style.flexDirection="column",d.style.minHeight="0",d.style.flex="1"),["chat","files","git","shell","memory"].forEach(p=>{let m=(0,n.$)(`tab-${p}`);if(!m)return;let b=p===l;m.classList.toggle("hidden",!b),b?(m.style.display="flex",m.style.flexDirection="column",m.style.flex="1 1 0",m.style.minHeight="0",m.style.overflow="hidden"):m.style.display="none"}),l==="memory"&&fs(),l==="shell"&&requestAnimationFrame(()=>{document.dispatchEvent(new CustomEvent("shell-tab-shown"))}),ee()}),Ni(),Di(),ha({openSession:be});let o=null;document.addEventListener("sessions-changed",()=>{o&&clearTimeout(o),o=setTimeout(()=>{o=null,fe({waitFresh:!1})},1200)}),document.addEventListener("router:home",ks),document.addEventListener("router:session",async({detail:{id:l,tab:d}})=>{let p=T.peek().find(b=>b.sessionId===l),m=at();await be(l,p?.cwd||(m?.sessionId===l?m.cwd:null)||null,p?.configDir||(m?.sessionId===l?m.configDir:null)||null,p?.agent||(m?.sessionId===l?m.agent:null)||null,p?.machineId||(m?.sessionId===l?m.machineId:null)||null,{tab:d||"chat"})}),n.delegate.on("click","#btn-home",ks),n.delegate.on("click","#auth-btn",Io),n.delegate.on("submit","#auth-form",l=>{l.preventDefault(),Io()}),n.delegate.on("keydown","#auth-username, #auth-password",l=>{l.key==="Enter"&&Io()}),n.delegate.on("click","#hamburger",()=>(0,n.$)("sidebar").classList.contains("open")?In():Ai()),n.delegate.on("click","#sidebar-overlay",In),document.addEventListener("keydown",l=>{l.key==="Escape"&&window.innerWidth<=640&&(0,n.$)("sidebar")?.classList.contains("open")&&(l.preventDefault(),In())}),n.delegate.on("input","#session-search",(l,d)=>{R.value=d.value,wn(d.value)}),n.delegate.on("click","#session-filter-badge",()=>{q.value=null}),n.delegate.on("click","[data-ws-tab]",(l,d)=>{q.value=d.dataset.wsTab||null}),n.delegate.on("click","#sidebar-refresh",()=>{fe(),R.peek().trim()&&ps(R.peek())}),n.delegate.on("click","[data-view]",(l,d)=>{Me.value=d.dataset.view,localStorage.setItem("sidebarView",d.dataset.view)}),n.delegate.on("click","[data-agent-filter]",(l,d)=>{oe.value=d.dataset.agentFilter,localStorage.setItem("agentFilter",d.dataset.agentFilter),R.peek().trim()&&wn(R.peek())}),n.delegate.on("change","#time-range",(l,d)=>{le.value=d.value,localStorage.setItem("timeRange",d.value),fe({waitFresh:!0}),R.peek().trim()&&wn(R.peek())}),n.delegate.on("dblclick","[data-project-cwd]",(l,d)=>{let p=d.dataset.projectCwd;if(!p)return;let m=p.split("/").filter(Boolean).pop()||p;wo({id:m,name:m,path:p}),x(`Project \xB7 ${p}`)}),n.delegate.on("click","#btn-pwa-install",async()=>{await ta()||sl()}),document.addEventListener("pwa-installable",()=>{document.getElementById("btn-pwa-install")?.classList.remove("hidden")}),n.delegate.on("click","#btn-settings",eo),n.delegate.on("click","#btn-meta-agent",()=>Ka()),n.delegate.on("click","#btn-meta-agent-welcome",()=>so("chat")),n.delegate.on("click","#btn-theme",$o),n.delegate.on("click","[data-sidebar-action]",(l,d)=>{let p=d.dataset.sidebarAction;p==="new"&&So(),p==="theme"&&$o(),p==="settings"&&eo(),p==="logout"&&(u.token=null,localStorage.removeItem("token"),Z(null),ve.value=!1,location.reload())}),n.delegate.on("click","#btn-cal-prev",()=>{uo(-1),vt(gt())}),n.delegate.on("click","#btn-cal-next",()=>{uo(1),vt(gt())}),n.delegate.on("click","[data-cal-date]",(l,d)=>{fi(d.dataset.calDate),vt(gt())}),n.delegate.on("click","[data-session-id]",(l,d)=>{l.target.closest("[data-fav-toggle]")||l.target.closest("[data-hide-toggle]")||l.target.closest("[data-rename-session]")||l.target.closest(".session-rename-input")||l.target.closest(".session-title-wrap.session-rename-active")||(be(d.dataset.sessionId,d.dataset.sessionCwd||null,d.dataset.sessionConfigDir||null,d.dataset.sessionAgent||"claude",d.dataset.sessionMachine||null),ji())}),n.delegate.on("click","[data-rename-session]",(l,d)=>{l.preventDefault(),l.stopPropagation();let p=d.closest(".session-title-wrap")||d,m=p.dataset.renameSessionId||p.dataset.sessionId;m&&go({sessionId:m,agent:p.dataset.renameSessionAgent||"claude",machineId:p.dataset.renameSessionMachine||null,fallbackDisplay:p.dataset.renameSessionDisplay||"",mountEl:p})}),n.delegate.on("click","[data-rename-bar]",(l,d)=>{if(l.preventDefault(),l.stopPropagation(),!u.sessionId)return;let p=document.getElementById("session-title-display")||d;go({sessionId:u.sessionId,agent:u.agent||w.peek()||"claude",machineId:u.machineId||null,mountEl:p})}),n.delegate.on("click","[data-folder]",(l,d)=>{let p=d.dataset.folder,b=d.querySelector("span")?.textContent.trim()==="\u25BE",g=new Set(Lt.peek()),F=new Set(Et.peek());b?(g.delete(p),F.add(p)):(g.add(p),F.delete(p)),(0,n.batch)(()=>{Lt.value=g,Et.value=F})}),n.delegate.on("click","#memory-refresh",fs),n.delegate.on("click","[data-memory-file]",l=>bo(l.dataset.memoryFile,l.dataset.memoryAgent)),n.delegate.on("click","[data-tab]",(l,d)=>Fe(d.dataset.tab));let a=async(l,d)=>{let p=(0,n.$)(l),m=p?.value.trim();if(!m){d.value="";return}try{let b=await h("POST","/api/resolve-path",{path:m});if(b.isDir===!1)throw new Error("Path is not a directory on the target machine");d.value=b.path,p.value=b.path;let g=v.peek();g&&(v.value={...g,path:b.path})}catch(b){p.style.color="oklch(var(--er))",p.title=b.message,setTimeout(()=>{p.style.color="",p.title=""},2e3)}};n.delegate.on("click","#files-root-btn",()=>a("files-root-input",z)),n.delegate.on("click","#git-root-btn",()=>a("git-root-input",Q)),n.delegate.on("keydown","#files-root-input",l=>{l.key==="Enter"&&a("files-root-input",z)}),n.delegate.on("keydown","#git-root-input",l=>{l.key==="Enter"&&a("git-root-input",Q)}),n.delegate.on("click","#btn-opts",()=>{(0,n.$)("chat-opts").classList.toggle("hidden"),ee()}),n.delegate.on("change","#sel-agent",(l,d)=>{let p=w.peek(),m=d.value;p!==m&&(u.sessionId=null,we(m),G(ye(m)||E.peek()),(0,n.$)("sel-permission").value=re.peek(),me(),x(`Agent \u2192 ${B[m]||m} \xB7 model ${E.peek()} \xB7 new session`))}),n.delegate.on("change","#sel-convert-agent",async(l,d)=>{let p=d.value;if(!p)return;let m=u.sessionId;if(!m){alert("No active session to convert."),d.value="";return}let b=u.agent||w.peek()||"claude";if(b===p){alert("Cannot convert to the same agent."),d.value="";return}d.disabled=!0,x(`Converting session ${m.slice(0,8)} from ${b} to ${p}...`);try{let g=await h("POST",`/api/sessions/${m}/convert`,{targetAgent:p,sourceAgent:b});g&&g.success?(x(`\u2713 Converted successfully. New session: ${g.targetSessionId.slice(0,8)}`),await fe(),await be(g.targetSessionId,v.peek()?.path||null,null,g.targetAgent),Yn()):x("Failed to convert session.")}catch(g){x(`Error converting session: ${g.message}`),alert(`Error converting session: ${g.message}`)}finally{d.disabled=!1,d.value=""}}),n.delegate.on("change","#sel-model",(l,d)=>{G(d.value),ds()}),n.delegate.on("click","#btn-model-add",()=>us({editCurrent:!1})),n.delegate.on("click","#btn-model-edit",()=>us({editCurrent:!0})),n.delegate.on("change","#sel-effort",(l,d)=>{O.value=d.value}),n.delegate.on("change","#sel-permission",(l,d)=>{re.value=d.value}),n.delegate.on("change","#sel-density",(l,d)=>{Hs(d.value),x(`Density \u2192 ${d.value} (applies to new tool calls; reload session to re-group history)`)}),document.addEventListener("agent-changed",me),n.delegate.on("click","#btn-new-session, #btn-new-session-welcome",So),n.delegate.on("click","#new-session-cancel",()=>(0,n.$)("modal-new-session").close()),n.delegate.on("click","#new-session-start",Eo),n.delegate.on("change","#new-session-agent",Lo),n.delegate.on("keydown","#new-session-path",l=>{l.key==="Enter"&&Eo()}),n.delegate.on("click","#send-btn",fn),n.delegate.on("click","#stop-btn",Ia),n.delegate.on("click","#btn-logout",()=>{u.token=null,localStorage.removeItem("token"),Z(null),ve.value=!1,location.reload()}),n.delegate.on("click","[data-pick-machine]",async(l,d)=>{let p=d.dataset.pickMachine;if(!p||p===S.peek()){St();return}await yo(p,{forceReload:!0}),Hn()});let i=async()=>{let l=(0,n.$)("machine-picker-status");if(l&&(l.textContent="\u5237\u65B0\u4E2D\u2026"),await kt(),gs(),Sn(),Qe(),l){let d=(N.peek()||[]).filter(p=>p.online!==!1).length;l.textContent=`${d} online`}};n.delegate.on("click","#btn-refresh-machines",i),n.delegate.on("click","#btn-refresh-machines-menu",async l=>{l.stopPropagation(),await i()}),n.delegate.on("click","#btn-machine-menu",async l=>{l.stopPropagation(),yt(),dt();let d=(0,n.$)("machine-menu");d&&(d.classList.contains("hidden")?(await kt(),Sn(),d.classList.remove("hidden")):d.classList.add("hidden"))}),n.delegate.on("click","#btn-recent-sessions",l=>{l.preventDefault(),l.stopPropagation(),St(),dt(),pi();let d=!(0,n.$)("recent-menu")?.classList.contains("hidden"),p=(0,n.$)("btn-recent-sessions");p&&p.setAttribute("aria-expanded",d?"true":"false")}),n.delegate.on("click","#recent-menu-backdrop",l=>{l.preventDefault(),l.stopPropagation(),yt(),(0,n.$)("btn-recent-sessions")?.setAttribute("aria-expanded","false")}),document.addEventListener("click",l=>{let d=(0,n.$)("machine-menu-wrap");d&&!d.contains(l.target)&&St();let p=(0,n.$)("recent-menu"),m=(0,n.$)("btn-recent-sessions"),b=l.target;if(p&&!p.classList.contains("hidden")){if(p.contains(b)||m?.contains(b))return;yt(),m?.setAttribute("aria-expanded","false")}}),n.delegate.on("click","#btn-notifications",l=>{l.preventDefault(),l.stopPropagation(),St(),yt(),fa()}),window.addEventListener("resize",()=>{(0,n.$)("recent-menu")&&!(0,n.$)("recent-menu").classList.contains("hidden")&&lo()}),n.delegate.on("click","#recent-menu [data-session-id]",()=>{yt(),(0,n.$)("btn-recent-sessions")?.setAttribute("aria-expanded","false")}),n.delegate.on("click","[data-dismiss-recent-session]",(l,d)=>{l.preventDefault(),l.stopPropagation(),di({sessionId:d.dataset.dismissRecentSession,agent:d.dataset.dismissRecentAgent||"claude",machineId:d.dataset.dismissRecentMachine||null})}),n.delegate.on("click","#btn-edit-project-notes, #project-goal-text, #project-notes-text",()=>{ki()}),n.delegate.on("click","#btn-cancel-project-notes",()=>{Xt()});let r=async()=>{let l=(0,n.$)("project-goal-input")?.value?.trim()??"",d=(0,n.$)("project-notes-input")?.value?.trim()??"",p=v.peek();if(!(!p||!p.path))try{let m=await h("POST","/api/projects/notes",{root:p.path,goal:l,notes:d});yi(m.goal||"",m.notes||""),Xt()}catch(m){alert(`Error saving project notes: ${m.message}`)}};n.delegate.on("click","#btn-save-project-notes",r),n.delegate.on("keydown","#project-goal-input",l=>{l.key==="Enter"&&r(),l.key==="Escape"&&Xt()}),n.delegate.on("keydown","#project-notes-input",l=>{l.key==="Escape"&&Xt()}),n.delegate.on("click","[data-fav-toggle]",(l,d)=>{l.stopPropagation(),l.preventDefault();let p=d.dataset.favSessionMachine||u.machineId;p&&(u.machineId=p,localStorage.setItem("machineId",p)),Li(d.dataset.favSessionId,d.dataset.favSessionAgent||"claude",{machineId:p||null})}),n.delegate.on("click","[data-hide-toggle]",(l,d)=>{l.stopPropagation(),l.preventDefault();let p=d.dataset.hideSessionMachine||u.machineId;p&&(u.machineId=p,localStorage.setItem("machineId",p)),Ei(d.dataset.hideSessionId,d.dataset.hideSessionAgent||"claude",{machineId:p||null})}),n.delegate.on("click","#btn-edit-session-notes, #session-notes-text",()=>{$i()}),n.delegate.on("click","#btn-cancel-session-notes",()=>he()),n.delegate.on("click","#btn-save-session-notes",async()=>{let l=(0,n.$)("session-notes-input")?.value?.trim()||"";if(!u.sessionId)return;let d=u.agent||w.peek()||"claude";await xo(u.sessionId,d,l)&&he()}),n.delegate.on("keydown","#session-notes-input",async l=>{if(l.key==="Escape"&&he(),l.key==="Enter"){let d=l.target.value.trim();if(!u.sessionId)return;let p=u.agent||w.peek()||"claude";await xo(u.sessionId,p,d)&&he()}}),n.delegate.on("click","#btn-fav-filter",()=>{let l=!Ue.peek();Ue.value=l,localStorage.setItem("favoritesOnly",l?"1":"0"),(0,n.$)("btn-fav-filter")?.classList.toggle("active",l),l&&Oe.peek()&&(Oe.value=!1,localStorage.setItem("showHiddenOnly","0"),(0,n.$)("btn-hidden-filter")?.classList.remove("active"))}),n.delegate.on("click","#btn-hidden-filter",()=>{let l=!Oe.peek();Oe.value=l,localStorage.setItem("showHiddenOnly",l?"1":"0"),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",l),l&&Ue.peek()&&(Ue.value=!1,localStorage.setItem("favoritesOnly","0"),(0,n.$)("btn-fav-filter")?.classList.remove("active"))}),me(),(0,n.effect)(()=>{$.value,S.value,u.token&&Hn()}),(0,n.$)("sel-permission").value=re.peek(),Kn();let c=(0,n.$)("sel-density");c&&(c.value=Ce.peek()||"normal");let f=(0,n.$)("time-range");f&&(f.value=le.peek()||"14"),document.querySelectorAll("[data-agent-filter]").forEach(l=>{l.classList.toggle("active",l.dataset.agentFilter===oe.peek())}),(0,n.$)("btn-fav-filter")?.classList.toggle("active",Ue.peek()),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",Oe.peek()),document.querySelectorAll("[data-view]").forEach(l=>{let d=l.dataset.view===Me.peek();l.classList.toggle("bg-primary/15",d),l.classList.toggle("text-primary",d),l.classList.toggle("font-medium",d),l.classList.toggle("text-base-content/50",!d)})}Wt();M();C();J();function ol(e){let t=e.split(".").pop()?.toLowerCase();return{js:"\u{1F4C4}",ts:"\u{1F4C4}",jsx:"\u{1F4C4}",tsx:"\u{1F4C4}",py:"\u{1F40D}",md:"\u{1F4DD}",json:"\u2699\uFE0F",html:"\u{1F310}",css:"\u{1F3A8}",sh:"\u26A1",env:"\u{1F511}",docx:"\u{1F4D8}",pptx:"\u{1F4D9}",xlsx:"\u{1F4D7}",pdf:"\u{1F4D5}"}[t]||"\u{1F4C4}"}function al(e){let t=(e||"").split("/").pop()||"",s=t.lastIndexOf(".");return s>=0?t.slice(s+1).toLowerCase():""}function _i(e){let t=al(e);return t==="docx"||t==="pptx"||t==="xlsx"||t==="pdf"?t:null}function il(e){return e==null?"":e>1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:e>1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function rl(e){let t=atob(e),s=new Uint8Array(t.length);for(let o=0;o<t.length;o++)s[o]=t.charCodeAt(o);return s.buffer}var Co=new Map;function Ss(e){if(Co.has(e))return Co.get(e);let t=new Promise((s,o)=>{let a=document.querySelector(`script[data-src="${e}"]`);if(a){if(a.dataset.loaded==="1")return s();a.addEventListener("load",()=>s()),a.addEventListener("error",()=>o(new Error(`Failed to load ${e}`)));return}let i=document.createElement("script");i.src=e,i.async=!0,i.dataset.src=e,i.onload=()=>{i.dataset.loaded="1",s()},i.onerror=()=>o(new Error(`Failed to load ${e}`)),document.head.appendChild(i)});return Co.set(e,t),t}function ll(e){let s=((e||"").split("/").pop()||"").toLowerCase(),o={dockerfile:"dockerfile",makefile:"makefile",gemfile:"ruby",rakefile:"ruby",procfile:"yaml","cmakelists.txt":"cmake"};if(o[s])return o[s];let a=s.includes(".")?s.split(".").pop():"";return{js:"javascript",mjs:"javascript",cjs:"javascript",jsx:"javascript",ts:"typescript",tsx:"typescript",mts:"typescript",cts:"typescript",py:"python",pyw:"python",pyi:"python",rb:"ruby",go:"go",rs:"rust",java:"java",kt:"kotlin",kts:"kotlin",c:"c",h:"c",cpp:"cpp",cc:"cpp",cxx:"cpp",hpp:"cpp",hh:"cpp",cs:"csharp",swift:"swift",php:"php",scala:"scala",sh:"bash",bash:"bash",zsh:"bash",fish:"bash",ps1:"powershell",psm1:"powershell",html:"xml",htm:"xml",xhtml:"xml",xml:"xml",svg:"xml",css:"css",scss:"scss",less:"less",json:"json",jsonc:"json",json5:"json",yml:"yaml",yaml:"yaml",toml:"ini",ini:"ini",conf:"ini",env:"bash",md:"markdown",mdx:"markdown",markdown:"markdown",sql:"sql",graphql:"graphql",gql:"graphql",vue:"xml",svelte:"xml",r:"r",lua:"lua",pl:"perl",pm:"perl",dart:"dart",ex:"elixir",exs:"elixir",erl:"erlang",zig:"zig",nim:"nim",clj:"clojure",cljs:"clojure",diff:"diff",patch:"diff",dockerfile:"dockerfile"}[a]||""}function cl(e){!e||typeof hljs>"u"||e.querySelectorAll("pre code.file-preview-code").forEach(t=>{try{delete t.dataset.highlighted,hljs.highlightElement(t)}catch{}})}function Mn(e,t,s){let o=il(t);return`
|
|
1003
1003
|
<div class="flex items-center gap-2 px-4 py-1.5 border-b border-base-300 flex-shrink-0 bg-base-200">
|
|
1004
1004
|
<span class="text-xs text-base-content/40 flex-1 truncate">${(0,n.esc)(e)} \xB7 ${(0,n.esc)(o)}${s?` \xB7 <span class="text-primary/70">${(0,n.esc)(s)}</span>`:""}</span>
|
|
1005
1005
|
<button type="button" class="btn btn-ghost btn-xs" data-download-path="${(0,n.esc)(e)}">\u2193 Download</button>
|
|
1006
|
-
</div>`}function
|
|
1006
|
+
</div>`}function dl(e){return!Array.isArray(e)||!e.length?'<div class="p-4 text-xs text-base-content/40">Empty directory</div>':(e.sort((t,s)=>s.isDir-t.isDir||t.name.localeCompare(s.name)),e.map(t=>`
|
|
1007
1007
|
<div class="flex items-center gap-2 px-4 py-1.5 hover:bg-base-300 group"
|
|
1008
1008
|
${t.isDir?`data-dir-path="${(0,n.esc)(t.path)}"`:`data-file-path="${(0,n.esc)(t.path)}"`}>
|
|
1009
|
-
<span class="cursor-pointer flex-shrink-0">${t.isDir?"\u{1F4C1}":
|
|
1009
|
+
<span class="cursor-pointer flex-shrink-0">${t.isDir?"\u{1F4C1}":ol(t.name)}</span>
|
|
1010
1010
|
<span class="text-sm flex-1 truncate cursor-pointer ${t.isDir?"text-primary":""}">${(0,n.esc)(t.name)}</span>
|
|
1011
1011
|
${t.isDir?"":`
|
|
1012
1012
|
<button type="button" class="file-row-action btn btn-ghost btn-xs px-1.5 text-base-content/50 hover:text-base-content"
|
|
1013
1013
|
data-download-path="${(0,n.esc)(t.path)}" title="Download" aria-label="Download">\u2193</button>
|
|
1014
1014
|
<button type="button" class="file-row-action btn btn-ghost btn-xs px-1.5 text-error/60 hover:text-error"
|
|
1015
1015
|
data-delete-path="${(0,n.esc)(t.path)}" title="Delete" aria-label="Delete">\u2715</button>`}
|
|
1016
|
-
</div>`).join(""))}function
|
|
1016
|
+
</div>`).join(""))}function ul(e,t,s){let o=/[\x00-\x08\x0e-\x1f]/.test(t.slice(0,512)),a=ll(e),i=a?`language-${(0,n.esc)(a)}`:"",r=o?`<div class="p-4 text-xs text-base-content/40">Binary file \u2014 <button class="text-primary hover:underline" data-download-path="${(0,n.esc)(e)}">Download</button></div>`:`<pre class="file-preview p-4 font-mono text-xs leading-relaxed overflow-auto flex-1 m-0"><code class="hljs file-preview-code ${i}">${(0,n.esc)(t)}</code></pre>`;return Mn(e,s,o?"binary":a||"text")+r}async function pl(e){if(await Ss("https://cdn.jsdelivr.net/npm/mammoth@1.8.0/mammoth.browser.min.js"),typeof mammoth>"u")throw new Error("mammoth failed to load");let t=await mammoth.convertToHtml({arrayBuffer:e});return`<div class="office-preview office-docx overflow-auto flex-1 p-4 md">${t.messages?.length?`<div class="office-warn text-xs text-warning/80 px-3 py-1">${t.messages.length} conversion note(s)</div>`:""}<div class="office-docx-body">${t.value||'<p class="text-base-content/40">Empty document</p>'}</div></div>`}async function fl(e){if(await Ss("https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js"),typeof XLSX>"u")throw new Error("SheetJS failed to load");let t=XLSX.read(new Uint8Array(e),{type:"array"}),s=t.SheetNames||[];if(!s.length)return'<div class="p-4 text-xs text-base-content/40">Empty workbook</div>';let o=s.map((i,r)=>`<button type="button" class="office-sheet-tab${r===0?" active":""}" data-sheet-idx="${r}">${(0,n.esc)(i)}</button>`).join(""),a=s.map((i,r)=>{let c=t.Sheets[i],f;try{f=XLSX.utils.sheet_to_html(c,{id:`xlsx-sheet-${r}`,editable:!1})}catch{f='<p class="text-base-content/40 text-xs p-2">Unable to render this sheet</p>'}return`<div class="office-sheet-pane${r===0?"":" hidden"}" data-sheet-pane="${r}">${f}</div>`}).join("");return`
|
|
1017
1017
|
<div class="office-preview office-xlsx flex flex-col flex-1 min-h-0 overflow-hidden">
|
|
1018
1018
|
<div class="office-sheet-tabs flex gap-1 px-2 py-1.5 border-b border-base-300 overflow-x-auto flex-shrink-0 bg-base-200">${o}</div>
|
|
1019
1019
|
<div class="office-sheet-body flex-1 overflow-auto p-2">${a}</div>
|
|
1020
|
-
</div>`}function
|
|
1020
|
+
</div>`}function ml(e){let t=[],s=/<a:p[\s>][\s\S]*?<\/a:p>/g,o=/<a:t(?:\s[^>]*)?>([\s\S]*?)<\/a:t>/g,a,i=e.match(s)||[e];for(let r of i){let c=[];for(o.lastIndex=0;(a=o.exec(r))!==null;){let f=a[1].replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&").replace(/"/g,'"').replace(/'/g,"'");f&&c.push(f)}c.length&&t.push(c.join(""))}return t}async function hl(e){if(await Ss("https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"),typeof JSZip>"u")throw new Error("JSZip failed to load");let t=await JSZip.loadAsync(e),s=Object.keys(t.files).filter(a=>/^ppt\/slides\/slide\d+\.xml$/i.test(a)).sort((a,i)=>{let r=parseInt(a.match(/slide(\d+)/i)?.[1]||"0",10),c=parseInt(i.match(/slide(\d+)/i)?.[1]||"0",10);return r-c});if(!s.length)return'<div class="p-4 text-xs text-base-content/40">No slides found in this presentation</div>';let o=[];for(let a=0;a<s.length;a++){let i=await t.files[s[a]].async("string"),r=ml(i),c=r.length?r.map(f=>`<p>${(0,n.esc)(f)}</p>`).join(""):'<p class="text-base-content/40 italic">\uFF08\u6B64\u9875\u65E0\u53EF\u63D0\u53D6\u6587\u672C / \u53EF\u80FD\u4EE5\u56FE\u7247\u4E3A\u4E3B\uFF09</p>';o.push(`
|
|
1021
1021
|
<article class="office-slide-card">
|
|
1022
1022
|
<header class="office-slide-num">Slide ${a+1}</header>
|
|
1023
1023
|
<div class="office-slide-body">${c}</div>
|
|
@@ -1025,7 +1025,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
1025
1025
|
<div class="office-preview office-pptx overflow-auto flex-1 p-3 space-y-3">
|
|
1026
1026
|
<p class="text-xs text-base-content/50 px-1">\u6587\u672C\u9884\u89C8\uFF08\u7248\u5F0F/\u56FE\u7247\u4E0D\u8FD8\u539F\uFF09\xB7 ${s.length} slide(s)</p>
|
|
1027
1027
|
${o.join("")}
|
|
1028
|
-
</div>`}async function
|
|
1028
|
+
</div>`}async function bl(){if(await Ss("https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"),typeof pdfjsLib>"u")throw new Error("pdf.js failed to load");return pdfjsLib.GlobalWorkerOptions.workerSrc="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js",pdfjsLib}async function xl(e){let s=await(await bl()).getDocument({data:e}).promise,o=s.numPages,a=Math.min(o,40),i=[];for(let c=1;c<=a;c++){let f=await s.getPage(c),l=f.getViewport({scale:1}),d=Math.min(1.5,820/l.width),p=f.getViewport({scale:d}),m=document.createElement("canvas");m.width=Math.floor(p.width),m.height=Math.floor(p.height),m.className="office-pdf-page",m.dataset.page=String(c),await f.render({canvasContext:m.getContext("2d"),viewport:p}).promise,i.push(`
|
|
1029
1029
|
<figure class="office-pdf-figure">
|
|
1030
1030
|
<figcaption class="office-pdf-cap">Page ${c} / ${o}</figcaption>
|
|
1031
1031
|
${m.outerHTML}
|
|
@@ -1034,12 +1034,12 @@ ${t}`:"",s.length?s.join(`
|
|
|
1034
1034
|
<p class="text-xs text-base-content/50 px-1">PDF preview \xB7 ${o} page(s)</p>
|
|
1035
1035
|
${r}
|
|
1036
1036
|
${i.join("")}
|
|
1037
|
-
</div>`}async function
|
|
1038
|
-
${
|
|
1037
|
+
</div>`}async function gl(e,t,s){let o=_i(e),a={docx:"Word",pptx:"PowerPoint",xlsx:"Excel",pdf:"PDF"},i=rl(t),r;if(o==="docx")r=await pl(i);else if(o==="xlsx")r=await fl(i);else if(o==="pptx")r=await hl(i);else if(o==="pdf")r=await xl(i);else throw new Error("Unsupported office type");return Mn(e,s,a[o]||o)+r}function vl(e,t){let s=e?e.split("/"):[],o=t?s.slice(0,-1):s,a='<span class="cursor-pointer text-primary hover:underline" data-dir-path="">root</span>',i="";for(let r of o)i=i?`${i}/${r}`:r,a+=` <span class="text-base-content/40">/</span> <span class="cursor-pointer text-primary hover:underline" data-dir-path="${(0,n.esc)(i)}">${(0,n.esc)(r)}</span>`;return t&&(a+=` <span class="text-base-content/40">/</span> <span>${(0,n.esc)(s.at(-1))}</span>`),a}function yl(){let e=v.peek(),t=z.peek()||e?.path;if(!t)return;let s=document.createElement("input");s.type="file",s.multiple=!0,s.addEventListener("change",async()=>{let o=j.peek(),a=e?.id||"_",i=[...s.files],r=!1;for(let c of i){let f=o?`${o}/${c.name}`:c.name,l=`/api/projects/${a}/file?root=${encodeURIComponent(t)}&path=${encodeURIComponent(f)}`;try{let d=await fetch(l,{method:"POST",headers:Ge(),body:c,duplex:"half"});if(!d.ok){let p=await d.json().catch(()=>({}));throw new Error(p.error||`HTTP ${d.status}`)}}catch(d){alert(`Upload failed (${c.name}): ${d.message}`),r=!0;break}}if(!r){let c=j.peek();j.value=c+"\0",j.value=c}}),s.click()}async function wl(e,t){let s=z.peek()||e?.path||"";if(!s){alert("No path selected \u2014 set root first");return}let o=e?.id||"_",a=(t||"").split("/").pop()||"download",i=new URLSearchParams({root:s,path:t,download:"true"}),r=`/api/projects/${o}/file?${i}`;try{let c=await fetch(r,{headers:Ge(),credentials:"same-origin"});if(!c.ok){let p=await c.json().catch(()=>({}));throw new Error(p.error||`HTTP ${c.status}`)}let f=await c.blob(),l=URL.createObjectURL(f),d=document.createElement("a");d.href=l,d.download=a,d.rel="noopener",d.style.display="none",document.body.appendChild(d),d.click(),d.remove(),setTimeout(()=>URL.revokeObjectURL(l),6e4)}catch(c){try{let f=`/api/projects/${o}/file?${Xo({root:s,path:t,download:"true"})}`,l=document.createElement("a");l.href=f,l.download=a,l.rel="noopener",l.target="_blank",document.body.appendChild(l),l.click(),l.remove()}catch{alert(`Download failed: ${c.message}`)}}}async function kl(e,t){if(!confirm(`Delete "${t.split("/").pop()}"?`))return;let s=z.peek()||e?.path||"",o=e?.id||"_";try{await h("DELETE",`/api/projects/${o}/file?root=${encodeURIComponent(s)}&path=${encodeURIComponent(t)}`),j.value=j.peek()+" ",j.value=j.peek().trimEnd()}catch(a){alert(`Delete failed: ${a.message}`)}}async function $l(e,t,s,o){let a=s.size??(typeof s.content=="string"?s.content.length:0),i=_i(t);if(i&&s.encoding==="base64"){e.innerHTML=Mn(t,a,i)+`<div class="p-4 text-xs text-base-content/40">Parsing ${i.toUpperCase()}\u2026</div>`;try{let r=await gl(t,s.content,a);if(o.aborted)return;e.innerHTML=r}catch(r){if(o.aborted)return;e.innerHTML=Mn(t,a,i)+`<div class="p-4 text-xs text-error">Preview failed: ${(0,n.esc)(r.message)} \u2014 <button class="text-primary hover:underline" data-download-path="${(0,n.esc)(t)}">Download</button></div>`}return}if(s.encoding==="base64"){e.innerHTML=Mn(t,a,"binary")+`<div class="p-4 text-xs text-base-content/40">Binary file \u2014 <button class="text-primary hover:underline" data-download-path="${(0,n.esc)(t)}">Download</button></div>`;return}e.innerHTML=ul(t,s.content||"",a),cl(e)}function Hi(){(0,n.effect)(()=>{let e=(0,n.$)("files-breadcrumb");if(!e)return;let t=W.value!==null;e.innerHTML=`
|
|
1038
|
+
${vl(W.value??j.value,t)}
|
|
1039
1039
|
<div class="flex-1"></div>
|
|
1040
|
-
${t?"":'<button id="btn-upload" class="btn btn-ghost btn-xs text-base-content/50 hover:text-base-content">\u2191 Upload</button>'}`}),(0,n.asyncEffect)(async e=>{let t=D.value,s=v.value,o=(
|
|
1040
|
+
${t?"":'<button id="btn-upload" class="btn btn-ghost btn-xs text-base-content/50 hover:text-base-content">\u2191 Upload</button>'}`}),(0,n.asyncEffect)(async e=>{let t=D.value,s=v.value,o=(z.value||s?.path||"").trim(),a=W.value,i=j.value,r=(0,n.$)("files-area");if(!r||t!=="files")return;if(!o){r.innerHTML='<div class="p-4 text-xs text-base-content/40">No path yet \u2014 open a session (uses that machine's cwd) or type an absolute path and press Go.</div>';return}let c=s?.id||"_";r.innerHTML='<div class="p-4 text-xs text-base-content/40">Loading\u2026</div>';try{if(a!==null){let d=await h("GET",`/api/projects/${c}/file?root=${encodeURIComponent(o)}&path=${encodeURIComponent(a)}`,void 0,e);e.aborted||await $l(r,a,d,e);return}let f=await h("GET",`/api/projects/${c}/files?root=${encodeURIComponent(o)}&path=${encodeURIComponent(i)}`,void 0,e);if(e.aborted)return;let l=Array.isArray(f)?f:Array.isArray(f?.files)?f.files:null;if(!l){r.innerHTML=`<div class="p-4 text-xs text-error">${(0,n.esc)(f?.error||"Invalid directory listing")}</div>`;return}r.innerHTML=dl(l)}catch(f){!e.aborted&&f?.name!=="AbortError"&&(r.innerHTML=`<div class="p-4 text-xs text-error">${(0,n.esc)(f.message)}</div>`)}}),n.delegate.on("click","[data-dir-path]",(e,t)=>{W.value=null,j.value=t.dataset.dirPath}),n.delegate.on("click","[data-file-path]",(e,t)=>{W.value=t.dataset.filePath}),n.delegate.on("click","#btn-upload",()=>yl()),n.delegate.on("click","[data-download-path]",(e,t)=>{e.preventDefault(),e.stopPropagation();let s=t.dataset.downloadPath;s&&wl(v.peek(),s)}),n.delegate.on("click","[data-delete-path]",(e,t)=>{e.preventDefault(),e.stopPropagation();let s=t.dataset.deletePath;s&&kl(v.peek(),s)}),n.delegate.on("click",".office-sheet-tab",(e,t)=>{let s=t.closest(".office-xlsx");if(!s)return;let o=t.dataset.sheetIdx;s.querySelectorAll(".office-sheet-tab").forEach(a=>a.classList.toggle("active",a===t)),s.querySelectorAll(".office-sheet-pane").forEach(a=>{a.classList.toggle("hidden",a.dataset.sheetPane!==o)})})}M();C();J();var Ri=(0,n.signal)(!1);function Sl(e){return e?e.split(`
|
|
1041
1041
|
`).map(t=>(0,n.esc)(t).replace(/\b([0-9a-f]{7})\b/,'<span class="gh">$1</span>').replace(/\(([^)]*)\)/,'<span style="color:oklch(var(--wa))">($1)</span>')).join(`
|
|
1042
|
-
`):'<span class="text-base-content/40">No commits</span>'}function
|
|
1042
|
+
`):'<span class="text-base-content/40">No commits</span>'}function Ll(e){if(!e)return"";if(!e.isGit)return'<div class="p-4 text-sm text-base-content/50">Not a git repository</div>';let t={M:"text-warning",D:"text-error"};return`
|
|
1043
1043
|
<div class="px-4 py-2 text-xs text-base-content/50 border-b border-base-300">
|
|
1044
1044
|
Branch: <span class="text-success font-semibold">${(0,n.esc)(e.branch)}</span>
|
|
1045
1045
|
</div>
|
|
@@ -1065,16 +1065,16 @@ ${t}`:"",s.length?s.join(`
|
|
|
1065
1065
|
<span class="text-base-content/40">Loading\u2026</span>
|
|
1066
1066
|
</div>
|
|
1067
1067
|
</div>
|
|
1068
|
-
</div>`}function
|
|
1068
|
+
</div>`}function El(e){return e.split(`
|
|
1069
1069
|
`).map(t=>t.startsWith("+")&&!t.startsWith("+++")?`<span class="diff-add">${(0,n.esc)(t)}</span>`:t.startsWith("-")&&!t.startsWith("---")?`<span class="diff-del">${(0,n.esc)(t)}</span>`:t.startsWith("@@")?`<span class="diff-hunk">${(0,n.esc)(t)}</span>`:/^(diff |index |---|[+]{3})/.test(t)?`<span class="diff-head">${(0,n.esc)(t)}</span>`:`<span>${(0,n.esc)(t)}</span>`).join(`
|
|
1070
|
-
`)}function
|
|
1071
|
-
`),
|
|
1070
|
+
`)}function Bi(){(0,n.asyncEffect)(async e=>{let t=D.value,s=v.value,o=Q.value||s?.path,a=(0,n.$)("git-area");if(!a||t!=="git")return;if(!o){a.innerHTML='<div class="p-4 text-sm text-base-content/50">Enter a project root above, or open a session with a working directory.</div>';return}let i=s?.id||"_";a.innerHTML='<div class="p-4 text-xs text-base-content/40">Loading\u2026</div>';try{let r=await h("GET",`/api/projects/${i}/git/status?root=${encodeURIComponent(o)}`,void 0,e);e.aborted||(a.innerHTML=Ll(r))}catch(r){!e.aborted&&r?.name!=="AbortError"&&(a.innerHTML=`<div class="p-4 text-xs text-error">${(0,n.esc)(r?.message??String(r))}</div>`)}}),(0,n.asyncEffect)(async e=>{let t=v.value,s=Q.value||t?.path,o=Ri.value,a=(0,n.$)("diff-content");if(!a||!s)return;let i=t?.id||"_";try{let r=await h("GET",`/api/projects/${i}/git/diff?root=${encodeURIComponent(s)}${o?"&staged=true":""}`,void 0,e);e.aborted||(a.innerHTML=r?.diff?El(r.diff):'<span class="text-base-content/40">No changes</span>')}catch(r){!e.aborted&&r?.name!=="AbortError"&&(a.innerHTML=`<span class="text-error">${(0,n.esc)(r?.message??String(r))}</span>`)}}),n.delegate.on("click","#diff-unstaged, #diff-staged",(e,t)=>{let s=t.id==="diff-staged";Ri.value=s,(0,n.$)("diff-unstaged").className=`cursor-pointer ${s?"text-base-content/50":"text-primary"}`,(0,n.$)("diff-staged").className=`cursor-pointer ${s?"text-primary":"text-base-content/50"}`}),n.delegate.on("click","#git-graph-toggle",()=>{let e=(0,n.$)("git-graph-panel"),t=(0,n.$)("git-graph-chevron"),s=e.classList.toggle("hidden");t.textContent=s?"\u25B6":"\u25BC",s||Il()})}function Il(){let e=v.peek(),t=Q.peek()||e?.path,s=(0,n.$)("git-graph-content");if(!t||!s)return;let o=e?.id||"_";s.innerHTML='<span class="text-base-content/40">Loading\u2026</span>',h("GET",`/api/projects/${o}/git/log?root=${encodeURIComponent(t)}`).then(a=>{s.innerHTML=a.graph?Sl(a.graph):'<span class="text-base-content/40">No commits</span>'}).catch(a=>{s.innerHTML=`<span class="text-error">${(0,n.esc)(a.message)}</span>`})}M();C();var se=null,I=null,Es=null,An=!1,Is=null,qi=null,Tn=0,Cn=null,Ao=!1,Fi=!1,Ui={"ctrl-c":"",escape:"\x1B",tab:" ",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C"};function jo(e){se&&se.readyState===WebSocket.OPEN&&se.send(JSON.stringify({type:"input",data:e}))}function Ml(){return window.matchMedia("(max-width: 640px), (hover: none) and (pointer: coarse)").matches}function Ms(){if(Ml()){document.getElementById("term-mobile-input")?.focus({preventScroll:!0});return}I?.focus();let e=document.querySelector("#terminal-container .xterm-helper-textarea");e&&(e.focus({preventScroll:!0}),requestAnimationFrame(()=>e.focus({preventScroll:!0})))}function Wi(){if(I)return;let e=(0,n.$)("terminal-container");if(!e)return;if(typeof Terminal>"u"){setTimeout(Wi,100);return}I=new Terminal({cursorBlink:!0,fontFamily:"Fira Code, Courier New, monospace",fontSize:12,theme:{background:"#0d1117",foreground:"#c9d1d9",cursor:"#58a6ff",black:"#0d1117",red:"#ff7b72",green:"#3fb950",yellow:"#d29922",blue:"#58a6ff",magenta:"#bc8cff",cyan:"#39c5cf",white:"#b1bac4",brightBlack:"#484f58",brightRed:"#ffa198",brightGreen:"#56d364",brightYellow:"#e3b341",brightBlue:"#79c0ff",brightMagenta:"#d8b9ff",brightCyan:"#56d4dd",brightWhite:"#ffffff"}}),typeof FitAddon<"u"&&(Es=new FitAddon.FitAddon,I.loadAddon(Es)),I.open(e),Ls(),I.onData(s=>{jo(s)}),e.addEventListener("pointerdown",()=>Ms(),{passive:!0}),e.addEventListener("touchend",()=>Ms(),{passive:!0}),window.addEventListener("resize",()=>{Ls(),Ts()});let t=window.visualViewport;if(t){let s=0,o=()=>{s&&cancelAnimationFrame(s),s=requestAnimationFrame(()=>{s=0,D.peek()==="shell"&&(Ls(),Ts())})};t.addEventListener("resize",o),t.addEventListener("scroll",o)}}function Ls(){try{Es&&I&&Es.fit()}catch{}}function Ts(){se&&se.readyState===WebSocket.OPEN&&I&&se.send(JSON.stringify({type:"resize",cols:I.cols,rows:I.rows}))}function Gi(){return u.machineId||S.peek()||null}function Cs(e){Cn&&(clearTimeout(Cn),Cn=null),Ao=!0;let t=++Tn;if(se){try{se.close()}catch{}se=null}An=!1;let s=location.protocol==="https:"?"wss":"ws",o=I?I.cols:80,a=I?I.rows:24,i=new URLSearchParams;u.token&&i.set("token",u.token),e&&i.set("cwd",e),i.set("cols",String(o)),i.set("rows",String(a));let r=Gi();$.peek()&&r&&i.set("machine",r),Is=e||null,qi=r,se=new WebSocket(`${s}://${location.host}/ws/shell?${i}`),se.addEventListener("open",()=>{t===Tn&&(An=!0,I?.write(`\x1B[32mConnected to interactive terminal\x1B[0m\r
|
|
1071
|
+
`),Ts())}),se.addEventListener("message",c=>{if(t!==Tn)return;let f;try{f=JSON.parse(c.data)}catch{return}f.type==="output"?I?.write(f.data):f.type==="exit"?I?.write(`\r
|
|
1072
1072
|
\x1B[33m[process exited: ${f.code}]\x1B[0m\r
|
|
1073
|
-
`):f.type==="error"&&
|
|
1073
|
+
`):f.type==="error"&&I?.write(`\r
|
|
1074
1074
|
\x1B[31m[error: ${f.data||f.message||""}]\x1B[0m\r
|
|
1075
|
-
`)}),
|
|
1075
|
+
`)}),se.addEventListener("close",()=>{t===Tn&&(An=!1,I?.write(`\r
|
|
1076
1076
|
\x1B[33m[disconnected]\x1B[0m\r
|
|
1077
|
-
`),!(!
|
|
1078
|
-
`),
|
|
1077
|
+
`),!(!Ao||D.peek()!=="shell")&&(I?.write(`\x1B[33m[reconnecting\u2026]\x1B[0m\r
|
|
1078
|
+
`),Cn=setTimeout(()=>{Cn=null,Cs(Is)},1500)))}),se.addEventListener("error",()=>{t===Tn&&I?.write(`\r
|
|
1079
1079
|
\x1B[31m[WebSocket error]\x1B[0m\r
|
|
1080
|
-
`)})}function
|
|
1080
|
+
`)})}function Oi(){let e=v.peek()?.path,t=(0,n.$)("term-cwd");t&&(t.textContent=e||"~"),I||Wi(),requestAnimationFrame(()=>{requestAnimationFrame(()=>{Ls();let s=Gi();!An||Is!==(e||null)||qi!==s?(I?.clear(),Cs(e)):Ts()})})}function zi(){Fi||(Fi=!0,document.getElementById("term-keyboard")?.addEventListener("click",Ms),document.getElementById("term-mobile-composer")?.addEventListener("submit",e=>{e.preventDefault();let t=document.getElementById("term-mobile-input");t&&(jo(`${t.value}\r`),t.value="",t.focus({preventScroll:!0}))}),document.getElementById("term-mobile-keys")?.addEventListener("pointerdown",e=>{e.target.closest("[data-term-key]")&&e.preventDefault()}),document.getElementById("term-mobile-keys")?.addEventListener("click",e=>{let t=e.target.closest("[data-term-key]")?.dataset.termKey;!t||!Ui[t]||(jo(Ui[t]),Ms())})),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(D.peek()!=="shell"||!Ao||An||Cs(Is))}),(0,n.watch)(D,e=>{e==="shell"&&Oi()}),document.addEventListener("shell-tab-shown",()=>{D.peek()==="shell"&&Oi()}),document.getElementById("term-reconnect")?.addEventListener("click",()=>{I?.clear(),Cs(v.peek()?.path)})}Wt();vn();Xn();jt();function Do(){let e=document.documentElement;e.classList.add("boot-ready"),e.classList.remove("boot-pending")}function As(){document.documentElement.classList.remove("boot-restore")}var No=Qs(location.hash.slice(1)||"/"),Ji=To()||!!(u.token&&No?.id);Pi({restoreSession:Ji});na();ja();Hi();Bi();Ba();zi();Ca();ei();Na(be,Fe);(async()=>{let e=Tt();if(u.token)try{let t=document.getElementById("auth-screen"),s=document.getElementById("app");if(t&&(t.style.display="none",t.classList.add("hidden")),s&&(s.style.display="flex",s.classList.remove("hidden")),Ji){document.documentElement.classList.add("boot-restore");let a=document.getElementById("welcome"),i=document.getElementById("project-view");a&&(a.classList.add("hidden"),a.style.display="none"),i&&(i.classList.remove("hidden"),i.style.cssText="display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden")}let o=await e;await $s({hub:o,deepLink:No}),No?.id||(Pa(),(location.hash||"").startsWith("#/session/")||As()),requestAnimationFrame(()=>{requestAnimationFrame(Do)})}catch(t){console.error("[boot]",t),u.token=null,localStorage.removeItem("token"),As(),await Mo(),Do()}else{As();try{await Mo()}catch(t){console.error("[boot auth]",t)}finally{Do()}}})();document.addEventListener("router:home",()=>{As()});ea();
|