claude-simple 0.2.9 → 0.2.10
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/README.md +13 -5
- package/dist/app.0.2.9.min.js +143 -139
- package/dist/style.0.2.9.min.css +1 -1
- package/package.json +11 -3
- package/public/chat.js +5 -5
- package/public/files.js +5 -5
- package/public/index.html +4 -5
- package/public/lib.js +1 -1
- package/public/router.js +36 -8
- package/public/settings.js +54 -2
- package/public/shell/boot.js +7 -7
- package/public/shell/layout.js +2 -3
- package/public/shell/session-list.js +5 -12
- package/public/shell/templates.js +26 -24
- package/public/shell/util.js +3 -1
- package/public/shell.js +54 -13
- package/public/state.js +36 -5
- package/public/sw.js +6 -2
- package/public/ui.min.css +2 -0
- package/public/vendor/highlight-dark.min.css +10 -0
- package/public/vendor/highlight.min.js +1262 -0
- package/public/vendor/jszip.min.js +13 -0
- package/public/vendor/mammoth.browser.min.js +21 -0
- package/public/vendor/marked.min.js +6 -0
- package/public/vendor/mini-react.min.js +4 -0
- package/public/vendor/pdf.min.js +22 -0
- package/public/vendor/pdf.worker.min.js +22 -0
- package/public/vendor/xlsx.full.min.js +22 -0
- package/src/agents/cursor.js +189 -0
- package/src/agents/gemini.js +182 -0
- package/src/agents/meta-agent.js +9 -5
- package/src/agents/models.js +112 -2
- package/src/agents/sessions.js +258 -14
- package/src/app.js +119 -7
- package/src/mcp.js +275 -0
package/dist/app.0.2.9.min.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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=>`
|
|
1
|
+
var _a=Object.defineProperty;var Yi=Object.getOwnPropertyDescriptor;var Xi=Object.getOwnPropertyNames;var Qi=Object.prototype.hasOwnProperty;var H=(e,t,s)=>()=>{if(s)throw s[0];try{return e&&(t=e(e=0)),t}catch(a){throw s=[a],a}};var Nn=(e,t)=>{for(var s in t)_a(e,s,{get:t[s],enumerable:!0})},Ha=(e,t,s,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Xi(t))!Qi.call(e,o)&&o!==s&&_a(e,o,{get:()=>t[o],enumerable:!(a=Yi(t,o))||a.enumerable});return e},js=(e,t,s)=>(Ha(e,t,"default"),s&&Ha(s,t,"default"));var n={};import*as Al from"https://cdn.jsdelivr.net/gh/forechoandlook/mini-react@v0.1.13/dist/mini-react.min.js";var M=H(()=>{js(n,Al)});var za={};Nn(za,{AGENT_DEFAULT_MODEL:()=>qa,AGENT_LABELS:()=>F,AGENT_MODELS:()=>Ds,LOW_TURN_THRESHOLD:()=>Ps,activityHits:()=>xe,activityLoading:()=>Te,addCustomModel:()=>tn,agentFilter:()=>ae,agentsMeta:()=>nt,chatDensity:()=>Ce,collapsedFolders:()=>Et,ctx:()=>u,currentAgent:()=>w,currentEffort:()=>O,currentModel:()=>E,currentPermission:()=>re,currentProject:()=>v,currentTab:()=>j,expandedFolders:()=>Lt,favoritesOnly:()=>Ue,filesPath:()=>D,filesRoot:()=>z,filteredSessions:()=>We,getCustomModels:()=>Pn,getDefaultEffort:()=>qe,getDefaultModel:()=>ye,getEffortsForModel:()=>nn,getModelsForAgent:()=>je,getSavedModel:()=>Oa,getSessionMeta:()=>It,gitRoot:()=>Q,hubMachineReady:()=>ve,hubMode:()=>$,isProcessing:()=>X,machinesList:()=>N,metaKey:()=>U,projectGroups:()=>st,removeCustomModel:()=>Rs,selectedMachineId:()=>S,sessionDisplayTitle:()=>Ae,sessionFilter:()=>q,sessionMetaMap:()=>y,sessionSearch:()=>B,sessionSort:()=>Ra,sessionsData:()=>T,setAgent:()=>we,setChatDensity:()=>Hs,setCurrentModel:()=>G,setSelectedMachine:()=>Z,showHiddenOnly:()=>Oe,sidebarView:()=>Me,timeRange:()=>le,viewingFile:()=>W,workspacesData:()=>R,wsStatus:()=>Ie});function Fa(){try{let e=JSON.parse(localStorage.getItem(Ba)||"{}");return e&&typeof e=="object"?e:{}}catch{return{}}}function Ua(e,t=u.sessionId,s=u.machineId){if(!t)return"";let a=(e||"claude").toLowerCase();return`${s||""}:${a}:${t}`}function Oa(e,t=u.sessionId,s=u.machineId){let a=Ua(e,t,s);if(!a)return null;let o=Fa()[a];return typeof o=="string"&&o.trim()?o:null}function G(e,t=w.peek(),s=u.sessionId,a=u.machineId){let o=String(e||"").trim();if(!o)return;let i=Ua(t,s,a);if(i){let r=Fa();r[i]=o,localStorage.setItem(Ba,JSON.stringify(r))}E.value=o}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 a=`${e||"claude"}:${t}`;return s||u?.machineId?`${s||u.machineId}:${a}`:a}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 a=(It(e.agent,e.sessionId,e.machineId).title||"").trim();return a||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 er(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 _s(){try{let e=localStorage.getItem(Wa);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function Ga(e){localStorage.setItem(Wa,JSON.stringify(e))}function Pn(e){let t=(e||"claude").toLowerCase(),s=_s()[t];return Array.isArray(s)?s.filter(Boolean).map(String):[]}function tn(e,t){let s=(e||"claude").toLowerCase(),a=String(t||"").trim();if(!a)return!1;let o=_s(),i=Array.isArray(o[s])?[...o[s]]:[];return i.includes(a)||i.push(a),o[s]=i,Ga(o),!0}function Rs(e,t){let s=(e||"claude").toLowerCase(),a=String(t||"").trim(),o=_s(),i=Array.isArray(o[s])?o[s].filter(r=>r!==a):[];return o[s]=i,Ga(o),!0}function je(e){let t=(e||"claude").toLowerCase(),s=nt.peek()?.defaults?.[t],a=s?.models?.length?s.models.map(er).filter(Boolean):(Ds[t]||Ds.claude).map(r=>({...r})),o=Pn(t),i=new Set(a.map(r=>r.value));for(let r of o){if(i.has(r)){a=a.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),a.push({value:r,label:`${r} \u2605`,custom:!0})}return a}function ye(e){let t=(e||"claude").toLowerCase(),s=nt.peek()?.defaults?.[t];return s?.model?String(s.model):qa[t]||je(t)[0]?.value||"claude-sonnet-4-5"}function nn(e,t){let a=je(e).find(i=>i.value===t);if(a?.efforts?.length)return a.efforts;let o=nt.peek()?.defaults?.[(e||"claude").toLowerCase()];return o?.efforts?.length?o.efforts.map(String):["low","medium","high","xhigh","max"]}function qe(e,t){let s=(e||"claude").toLowerCase(),a=nt.peek()?.defaults?.[s];if(a?.effortDefault)return String(a.effortDefault);let i=je(s).find(r=>r.value===t);return i?.defaultEffort?String(i.defaultEffort):s==="grok"?"low":s==="gemini"&&String(t||"").match(/-(low|medium|high)$/i)?.[1]?.toLowerCase()||""}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 a=Oa(t);a?E.value=a:G(ye(t),t);let o=qe(t,E.peek());o?O.value=o:t!=="grok"&&t!=="gemini"&&(O.value="")}function tr(e,t){return!t||t==="all"?!0:(e.agent||"claude")===t}function nr(e,t){let s=parseInt(t||"0",10)||0;if(s<=0)return!0;let a=e.updatedAt||0;if(typeof a=="string"){let o=Number(a);a=Number.isFinite(o)&&o>0?o<1e12?o*1e3:o:Date.parse(a)||0}else typeof a=="number"&&a>0&&a<1e12&&(a=a*1e3);return a>=Date.now()-s*864e5}function sr(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 T,R,q,B,Ra,Lt,Et,D,W,v,j,X,Ie,Ba,Zi,w,E,O,re,z,Q,nt,Me,ae,le,xe,Te,y,Ue,Oe,Ps,Ce,$,N,S,ve,u,F,Ds,qa,Wa,We,st,C=H(()=>{M();T=(0,n.signal)([]),R=(0,n.signal)([]),q=(0,n.signal)(null),B=(0,n.signal)(""),Ra=(0,n.signal)("time"),Lt=(0,n.signal)(new Set),Et=(0,n.signal)(new Set),D=(0,n.signal)(""),W=(0,n.signal)(null),v=(0,n.signal)(null),j=(0,n.signal)("chat"),X=(0,n.signal)(!1),Ie=(0,n.signal)("idle"),Ba="modelBySession",Zi=localStorage.getItem("agent")||"claude";w=(0,n.signal)(Zi),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"),ae=(0,n.signal)(localStorage.getItem("agentFilter")||"all"),le=(0,n.signal)(localStorage.getItem("timeRange")||"14"),xe=(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"),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),u={token:localStorage.getItem("token"),sessionId:null,agent:null,machineId:null,ws:null,shellBubble:null,configDir:null};F={claude:"Claude",codex:"Codex",grok:"Grok",gemini:"Gemini"},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"}],gemini:[{value:"gemini-3.7-flash-high",label:"Gemini 3.7 Flash (High)"},{value:"gemini-3.7-flash-medium",label:"Gemini 3.7 Flash (Medium)"},{value:"gemini-3.7-flash-low",label:"Gemini 3.7 Flash (Low)"},{value:"gemini-3.6-flash-high",label:"Gemini 3.6 Flash (High)"},{value:"gemini-3.6-flash-medium",label:"Gemini 3.6 Flash (Medium)"},{value:"gemini-3.6-flash-low",label:"Gemini 3.6 Flash (Low)"},{value:"gemini-3.5-flash-high",label:"Gemini 3.5 Flash (High)"},{value:"gemini-3.5-flash-medium",label:"Gemini 3.5 Flash (Medium)"},{value:"gemini-3.5-flash-low",label:"Gemini 3.5 Flash (Low)"},{value:"gemini-3.1-pro-high",label:"Gemini 3.1 Pro (High)"},{value:"gemini-3.1-pro-low",label:"Gemini 3.1 Pro (Low)"}]},qa={claude:"claude-sonnet-4-5",codex:"gpt-5.4",grok:"grok-4.5",gemini:"gemini-3.7-flash-high"};Wa="customModelsByAgent";We=(0,n.computed)(()=>{let e=q.value,t=B.value.toLowerCase().trim(),s=Ra.value,a=ae.value,o=le.value,i=Ue.value,r=Oe.value,c=y.value,f=xe.value,l=f?.results?.length&&t?Ns(f.results):Ns(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&&tr(p,a)&&nr(p,o)),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&&sr(p,t))),l=[...l].sort((p,m)=>{let g=c?.[U(p.agent,p.sessionId,p.machineId)]?.favorite?1:0,b=c?.[U(m.agent,m.sessionId,m.machineId)]?.favorite?1:0;return g!==b?b-g: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=Ns(We.value),t=new Map;for(let s of e){if(!s)continue;let a=s.machineId?`${s.machineId}::${s.cwd||"(no path)"}`:s.cwd||"(no path)";t.has(a)||t.set(a,{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 o=t.get(a);o.sessions.push(s),o.agents[s.agent||"claude"]=(o.agents[s.agent||"claude"]||0)+1,(s.updatedAt||0)>o.updatedAt&&(o.updatedAt=s.updatedAt,o.latest=s)}return[...t.values()].sort((s,a)=>a.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,a,o={}){let i=sn(o),r={"Content-Type":"application/json",...u.token?{Authorization:`Bearer ${u.token}`}:{}};$.peek()&&i&&!or(t)&&(r["X-Machine-Id"]=i);let c=o.etag===!0?`${u.token||""}:${i||""}:${t}`:o.etag||null;if(e.toUpperCase()==="GET"&&c){let d=Ja.get(c);d&&(r["If-None-Match"]=d)}let f=async()=>{let d=await fetch(t,{method:e,signal:a,headers:r,...s!==void 0?{body:JSON.stringify(s)}:{}});if(d.status===304)return Bs;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&&Ja.set(c,m)}return p};if(e.toUpperCase()!=="GET"||a||o.dedupe===!1)return f();let l=`${u.token||""}:${i||""}:${t}`;return ar.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"||Hn.push(e),!1)}function Ka(){for(;Hn.length&&u.ws?.readyState===WebSocket.OPEN;)u.ws.send(JSON.stringify(Hn.shift()))}function Va(){Hn.length=0}function Ya(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 ar,Ja,Bs,Hn,J=H(()=>{C();M();ar=(0,n.createFetch)({cache:!1,dedupe:!0,retry:0}),Ja=new Map,Bs=Symbol("not-modified");Hn=[]});function at(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 a=!e||t.classList.contains("open");at(t,!a)}at(document.getElementById("welcome"),At(document.getElementById("welcome"))),at(document.getElementById("auth-screen"),At(document.getElementById("auth-screen"))),at(document.getElementById("chat-opts"),At(document.getElementById("chat-opts"))),at(document.getElementById("machine-picker"),At(document.getElementById("machine-picker")));for(let a of["files","git","shell","memory"]){let o=document.getElementById(`tab-${a}`);at(o,At(o))}let s=document.getElementById("tab-chat");s&&at(s,At(s))}function an(){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 to(){ee(),an();let e=window.visualViewport;e&&(e.addEventListener("resize",an),e.addEventListener("scroll",an)),window.addEventListener("resize",()=>{an(),ee()}),window.addEventListener("orientationchange",()=>{setTimeout(()=>{an(),ee()},250)})}var jt=H(()=>{});function ot(){try{let e=localStorage.getItem(no);return e?JSON.parse(e):null}catch{return null}}function Fs(e){try{let s={...ot()||{},...e,updatedAt:Date.now()};localStorage.setItem(no,JSON.stringify(s))}catch{}}var no,_n=H(()=>{no="lastSessionContext"});async function Us(){if(on&&!(typeof navigator>"u"||!navigator.wakeLock?.request)&&document.visibilityState==="visible"&&!it)try{it=await navigator.wakeLock.request("screen"),it.addEventListener("release",()=>{it=null,on&&document.visibilityState==="visible"&&setTimeout(()=>{Us().catch(()=>{})},500)})}catch{it=null}}async function so(){let e=it;if(it=null,!!e)try{await e.release()}catch{}}function ao(e){on=!!e,on?Us().catch(()=>{}):so().catch(()=>{})}function oo(){typeof document>"u"||document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&on?Us().catch(()=>{}):document.visibilityState==="hidden"&&so().catch(()=>{})})}var it,on,io=H(()=>{it=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 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",o={claude:"bg-orange-500/15 text-orange-400",codex:"bg-emerald-500/15 text-emerald-400",grok:"bg-sky-500/15 text-sky-400",gemini:"bg-violet-500/15 text-violet-400"}[s]||"bg-base-300 text-base-content/50",i=t?s==="claude"?"CC":s==="codex"?"CX":s==="grok"?"GX":s==="gemini"?"GM":s.slice(0,2).toUpperCase():F[s]||s;return`<span class="text-[9px] px-1 py-0.5 rounded font-mono font-semibold flex-shrink-0 ${o}" title="${(0,n.esc)(F[s]||s)}">${i}</span>`}function ro(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=H(()=>{M();C()});function lr(e){let t=A(e);if(t==null)return"";let s=new Date(t);return Number.isNaN(s.getTime())?"":s.toLocaleString()}function lo(){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 po(){let e=(0,n.$)("notifications-menu"),t=(0,n.$)("btn-notifications"),s=(0,n.$)("topbar");if(!e||!t||!s)return;let a=t.getBoundingClientRect(),o=s.getBoundingClientRect(),i=Math.min(416,window.innerWidth-16),r=Math.max(8,Math.min(window.innerWidth-i-8,a.right-i));e.style.top=`${Math.round(o.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(!oe.length){e.innerHTML="",t.classList.remove("hidden"),lo();return}t.classList.add("hidden"),e.innerHTML=oe.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,69 +17,69 @@ var Ro=Object.defineProperty;var Vi=Object.getOwnPropertyDescriptor;var Yi=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)(lr(s.createdAt))}</span>
|
|
21
21
|
</div>
|
|
22
22
|
</div>
|
|
23
23
|
</div>
|
|
24
|
-
</button>`).join(""),
|
|
24
|
+
</button>`).join(""),lo()}}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 cr(){po(),(0,n.$)("notifications-menu")?.classList.remove("hidden"),(0,n.$)("notifications-backdrop")?.classList.remove("hidden"),(0,n.$)("btn-notifications")?.setAttribute("aria-expanded","true")}function fo(){let e=(0,n.$)("notifications-menu");e&&(e.classList.contains("hidden")?cr():dt())}function co(e){let t=new Map;for(let s of e||[])s?.id&&t.set(String(s.id),s);oe=[...t.values()].sort((s,a)=>(A(a.createdAt)||0)-(A(s.createdAt)||0)),ct=oe.reduce((s,a)=>s+(a.unread?1:0),0),rn()}async function Rn(){try{let e=await h("GET","/api/notifications?limit=80");oe=Array.isArray(e?.notifications)?e.notifications:[],ct=Number(e?.unreadCount)||oe.reduce((t,s)=>t+(s.unread?1:0),0),rn()}catch{oe=[],ct=0,rn()}}async function uo(e=null){let t=await h("POST","/api/notifications/read",e?.length?{ids:e}:{});oe=Array.isArray(t?.notifications)?t.notifications:oe.map(s=>!e||e.includes(s.id)?{...s,unread:!1}:s),ct=Number(t?.unreadCount)||oe.reduce((s,a)=>s+(a.unread?1:0),0),rn()}function dr(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 mo(e){if(!e?.id)return;if(oe.find(s=>s.id===e.id)){co([e,...oe.filter(s=>s.id!==e.id)]);return}co([e,...oe]),dr(e)}function ho(e={}){Os=typeof e.openSession=="function"?e.openSession:null,rn(),Rn(),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 uo()}),n.delegate.on("click","[data-notification-id]",async(t,s)=>{let a=s.dataset.notificationId;a&&(await uo([a]),dt(),!(!Os||!s.dataset.notificationSession)&&Os(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"),a=(0,n.$)("btn-notifications"),o=t.target;!s||s.classList.contains("hidden")||s.contains(o)||a?.contains(o)||dt()}),window.addEventListener("resize",()=>{(0,n.$)("notifications-menu")&&!(0,n.$)("notifications-menu").classList.contains("hidden")&&po()})}var oe,ct,Os,qs=H(()=>{M();J();Nt();oe=[],ct=0,Os=null});function ur(){return F[w.peek()]||"Assistant"}function wo(e){return e.scrollHeight-e.scrollTop-e.clientHeight<80}function de(e,t){e&&(t||wo(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))||"",Ht(t),Pt(t.value))}function Ft(e){let t=Ve(e);if(!t)return;let s=He.filter(o=>o.key===t);if(!s.length)return;He=He.filter(o=>o.key!==t);let a=ut.get(t)||"";ut.set(t,[a,...s.map(o=>o.text)].filter(Boolean).join(`
|
|
25
25
|
|
|
26
|
-
`))}function Ut(){X.peek()&&(X.value=!1,Je())}function
|
|
27
|
-
<div class="msg-row assistant px-2 live-stream" data-ts="${(0,n.esc)(
|
|
26
|
+
`))}function Ut(){X.peek()&&(X.value=!1,Je())}function pr(){bo||(bo=!0,document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="visible"&&(Le=400,Bn({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,Bn({force:!0})}),window.addEventListener("pageshow",e=>{e.persisted?Bn({force:!0}):Bn({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 Bn(e={}){let t=u.ws?.readyState;if(e.force){Le=400,_e({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),_e({quiet:!0}))}function fr(){Pe||(Ie.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",pn(),Pe=setTimeout(()=>{Pe=null,_e({quiet:!0})},Le),Le=Math.min(Math.round(Le*1.8),15e3))}function ko(){Un&&(clearInterval(Un),Un=null)}function mr(e,t){ko(),Un=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";ao(e)}function hr(){Le=400,Pe&&(clearTimeout(Pe),Pe=null),qn=!1;let e=u.ws?.readyState;if(e===WebSocket.OPEN||e===WebSocket.CONNECTING)try{u.ws?.close()}catch{}_e({quiet:!1}),x("\u6B63\u5728\u91CD\u65B0\u8FDE\u63A5\u5E76\u540C\u6B65\u2026")}function _e(e={}){pr(),Pe&&(clearTimeout(Pe),Pe=null),e.quiet&&(qn=!0);let t=u.machineId||(typeof localStorage<"u"?localStorage.getItem("machineId"):null);go!==t&&(Va(),go=t);let s=++cn;try{u.ws?.close()}catch{}Ie.value="connecting",pn();let a=location.protocol==="https:"?"wss":"ws",o=new URLSearchParams;u.token&&o.set("token",u.token),t&&o.set("machine",t),u.sessionId&&o.set("sessionId",u.sessionId);let i=new WebSocket(`${a}://${location.host}/ws/chat?${o}`);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{}Ka(),mr(i,s),Je(),On&&!qn&&x(t?`\u5DF2\u91CD\u8FDE \xB7 ${t}`:"\u5DF2\u91CD\u8FDE"),On=!1,qn=!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,$o()),Je();return}So(c)}),i.addEventListener("close",()=>{s===cn&&(ko(),On=!0,Ie.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",pn(),fr())}),i.addEventListener("error",()=>{})}function $o(){if(!He.length||X.peek())return;let e=Ve(),t=He.findIndex(o=>o.key===e);if(t<0)return;let[s]=He.splice(t,1),a=(0,n.$)("chat-input");a&&(a.value=s.text,Ht(a)),setTimeout(()=>{if(s.key!==Ve()||X.peek()){ut.set(s.key,s.text);return}fn()},0)}function dn(){X.value=!1,Je(),$o()}function So(e){if(!(e?.sessionId&&u.sessionId&&e.sessionId!==u.sessionId)){if(e.type==="batch"&&Array.isArray(e.items)){for(let t of e.items)So(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){mo(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),_t(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=jr(e.stream==="stderr"?"shell-err":"shell")),Dr(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",ur(),t.text,{ts:e.ts||Date.now()})):t.type==="tool_use"&&Ks(t,{ts:e.ts||Date.now()});return}if(e.type==="assistant_stream_start"){Lo(e.ts);return}if(e.type==="assistant_delta"){br(e.data||"");return}if(e.type==="assistant_stream_end"){ln();return}if(e.type==="thought_stream_start"){Eo();return}if(e.type==="thought_delta"){gr(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)&&Hr(e)}}function Lo(e){let t=(0,n.$)("messages");if(!t||(pe(),un(),$e&&t.contains($e)))return;let s=zn(e||Date.now()),a=Jn(e||Date.now());t.insertAdjacentHTML("beforeend",`
|
|
27
|
+
<div class="msg-row assistant px-2 live-stream" data-ts="${(0,n.esc)(a)}">
|
|
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
|
-
${s?`<div class="msg-ts" title="${(0,n.esc)(
|
|
32
|
-
</div>`),$e=t.lastElementChild,ce=$e.querySelector(".msg-stream-body"),(0,n.$)("stream-status")?.remove(),de(t,!0)}function
|
|
31
|
+
${s?`<div class="msg-ts" title="${(0,n.esc)(a)}">${(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 br(e){e&&(ce||Lo(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=Gn(e),Ao($e)):$e.remove(),$e=null,ce=null,(0,n.$)("stream-status")?.remove()}function Eo(){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>`),ze=e.lastElementChild,Se=ze.querySelector(".thought-body"),de(e,!0)))}function
|
|
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
|
|
40
|
-
Available: ${f}`:""}`),!0}let
|
|
41
|
-
/agent [claude|codex|grok]
|
|
38
|
+
</div>`),ze=e.lastElementChild,Se=ze.querySelector(".thought-body"),de(e,!0)))}function gr(e){e&&(Se||Eo(),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 vr(e){let[t,...s]=e.slice(1).trim().split(/\s+/),a=s.join(" ");switch(t.toLowerCase()){case"agent":{if(!a)return x(`Current agent: ${w.peek()} \xB7 agents: claude | codex | grok | gemini`),!0;let o=a.toLowerCase();return["claude","codex","grok","gemini"].includes(o)?(o!==w.peek()?(u.sessionId=null,we(o),G(ye(o)),document.dispatchEvent(new CustomEvent("agent-changed")),x(`Agent \u2192 ${F[o]} \xB7 model ${E.peek()} \xB7 new session`)):x(`Agent already ${F[o]}`),!0):(x(`Unknown agent "${a}" \xB7 valid: claude | codex | grok | gemini`),!0)}case"model":{if(!a){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 o=xr[a.toLowerCase()]||a,i=w.peek()||"claude",r=je(i).some(c=>c.value===o);return r||tn(i,o),G(o),x(`Model set to ${o}${r?"":" (saved as custom \u2605)"}`),document.dispatchEvent(new CustomEvent("agent-changed")),!0}case"effort":{let o=nn(w.peek(),E.peek());return a?o.includes(a.toLowerCase())?(O.value=a.toLowerCase(),x(`Effort set to ${a.toLowerCase()}`),!0):(x(`Unknown effort level "${a}" \xB7 valid: ${o.join(" | ")}`),!0):(x(`Current effort: ${O.peek()||"(default)"} \xB7 levels: ${o.join(" | ")}`),!0)}case"clear":return qt(),u.sessionId=null,u.lastUsage=null,x("Cleared \xB7 new session"),!0;case"usage":return yr(),!0;case"help":return x(`Available slash commands:
|
|
41
|
+
/agent [claude|codex|grok|gemini]
|
|
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 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
|
|
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 yr(){let e=w.peek()||"claude",t=E.peek()||"\u2014",s=u.sessionId,a=[`Agent: ${F[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 o=u.lastUsage;a.push(`Last turn: \u2191${te(o.input_tokens)} \u2193${te(o.output_tokens)}`+(o.cache_read_input_tokens?` \xB7 ${te(o.cache_read_input_tokens)} cached`:"")+(o.reasoning_tokens?` \xB7 ${te(o.reasoning_tokens)} reason`:"")+(o.total_tokens?` \xB7 \u03A3${te(o.total_tokens)}`:"")+(o.costUSD!=null?` \xB7 $${Number(o.costUSD).toFixed(4)}`:""))}if(!s){x(a.join(`
|
|
47
|
+
`)),zs("\u25C8 /usage \xB7 no session yet");return}x("Loading usage\u2026");try{let o=new URLSearchParams({sessionId:s,agent:e}),r=(await h("GET",`/api/usage?${o}`)).context||{};if(r.model&&(a[1]=`Model: ${r.model}`),r.title&&a.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";a.push(`Context window: ${f} / ${l} (${d})`)}if(r.turnCount!=null&&a.push(`Turns: ${r.turnCount}`),r.toolCallCount!=null&&a.push(`Tools: ${r.toolCallCount}`),r.sessionDurationSeconds!=null){let f=Math.floor(r.sessionDurationSeconds/60),l=Math.round(r.sessionDurationSeconds%60);a.push(`Duration: ${f}m ${l}s`)}if(r.sessionTotals){let f=r.sessionTotals;a.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;a.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&&a.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(a.join(`
|
|
48
|
+
`)),(r.tokensUsed!=null||r.windowTokens!=null)&&Js({tokensUsed:r.tokensUsed,windowTokens:r.windowTokens,usagePercent:r.usagePercent,model:r.model||t,turnCount:r.turnCount,toolCallCount:r.toolCallCount}),r.sessionTotals?_t(r.sessionTotals):r.lastTurn?_t(r.lastTurn):u.lastUsage&&_t(u.lastUsage)}catch(o){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(`${a.join(`
|
|
49
49
|
`)}
|
|
50
|
-
(usage fetch failed: ${
|
|
50
|
+
(usage fetch failed: ${o.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 a="grok",o=O.peek()||qe(a,E.peek())||"low",i=Mt({type:"command",cmd:"turn.start",agent:a,command:t,sessionId:u.sessionId,options:{agent:a,cwd:v.peek().path,sessionId:u.sessionId,configDir:u.configDir,model:E.peek(),effort:o,...re.peek()&&{permissionMode:re.peek()},...re.peek()==="bypassPermissions"&&{allowDangerouslySkipPermissions:!0}}});e.value="",Ht(e),Pt(""),Wn(),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}He.push({key:Ve(),text:t}),e.value="",Ht(e),Pt(""),Wn(),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()),Ht(e),Pt(""),Wn(),t.startsWith("/")&&vr(t))return;X.value=!0,Je();let s=Date.now();if(Mo(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 a=w.peek()||"claude",o=O.peek()||qe(a,E.peek())||(a==="grok"?"low":""),i=re.peek();u.sessionId&&G(E.peek(),a,u.sessionId),Mt({type:"command",cmd:"turn.start",agent:a,command:t,sessionId:u.sessionId,options:{agent:a,cwd:v.peek().path,sessionId:u.sessionId,configDir:u.configDir,model:E.peek(),...o&&{effort:o},...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 Io(){u.sessionId&&Mt({type:"command",cmd:"turn.interrupt",sessionId:u.sessionId}),He=He.filter(e=>e.key!==Ve()),dn()}function Pt(e){let t=Mo(e),s=(0,n.$)("chat-input"),a=(0,n.$)("send-btn");if(!s||!a)return;s.classList.toggle("textarea-warning",t),s.style.fontFamily=t?"monospace":"",a.classList.toggle("btn-warning",t),a.classList.toggle("btn-primary",!t),a.textContent=t?"Run":"Send";let o=F[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 ${o}\u2026`:`Ask ${o}\u2026 or !cmd for shell`}function Mo(e){let t=String(e||"").trimStart();return t.startsWith("!")&&!/^!\[[^\]]*\]\([^)]+\)/.test(t)}function wr(){return typeof window<"u"&&window.matchMedia("(max-width: 640px)").matches,72}function Ht(e){e.style.height="auto",e.style.height=Math.min(e.scrollHeight,wr())+"px"}function zn(e){let t=A(e);if(t==null)return"";let s=new Date(t);if(Number.isNaN(s.getTime()))return"";let a=new Date,o=s.toDateString()===a.toDateString(),i=s.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1});return o?i:`${s.toLocaleDateString(void 0,{month:"numeric",day:"numeric"})} ${i}`}function Jn(e){let t=A(e);return t==null?"":new Date(t).toISOString()}function Sr(e,t,s){if(e==="system")return t;let a=zn(s),o=Jn(s),i=a?`<div class="msg-ts" title="${(0,n.esc)(o)}">${(0,n.esc)(a)}</div>`:"";return`<div class="msg-row ${e==="user"?"user":e==="shell"||e==="shell-err"?"assistant":e} px-2" data-ts="${(0,n.esc)(o)}">${t}${i}</div>`}function Lr(e,t,s){let a='<button class="msg-expand-btn text-[10px] text-primary/70 mt-1.5 block cursor-pointer hover:text-primary">\u25BC Show more</button>',o;switch(e){case"user":{let r=/!\[.*?\]\(.*?\)/.test(t)?Gn(t):null,c=t.length>kr,f=c?`<div class="msg-body">${r??(0,n.esc)(t.trimEnd())}</div>${a}`:r??(0,n.esc)(t.trimEnd());o=`<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>$r,r=i?`<div class="msg-body">${Gn(t)}</div>${a}`:Gn(t);o=`<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":o=`<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":o=`<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:o=`<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 Sr(e,o,s)}function pt(e,t,s,a={}){let o=(0,n.$)("messages");if(!o)return;let i=A(a.ts)??(e==="system"?null:Date.now());o.insertAdjacentHTML("beforeend",Lr(e,s,i)),Ao(o.lastElementChild),de(o,e==="user")}function x(e){pt("system","",e)}async function Er(e,t){let s=t||`upload-${Date.now()}`,a=await To(e,s),o=Ge({"x-filename":s});delete o["Content-Type"],a?.type&&!o["Content-Type"]&&!o["content-type"]&&(o["Content-Type"]=a.type);let i=await fetch("/api/upload-image",{method:"POST",headers:o,body:a});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 Ir(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 To(e,t){if(!e||!Ws({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 a;try{a=(await e.text()).trim()}catch{return e}let i=/^data:image\/[a-z0-9.+-]+;base64,([a-z0-9+/=\s]+)$/i.exec(a)?.[1]||a;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=Ir(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 Mr(e,t){if(!e)return;let s=e.selectionStart??e.value.length,a=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(
|
|
53
|
+
`;e.value=e.value.slice(0,s)+i+e.value.slice(a),e.selectionStart=e.selectionEnd=s+i.length,e.dispatchEvent(new Event("input"))}function Ws(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 Tr(e,t){let s=e?.name||t.split("/").pop()||"file";if(Ws(e)){Fn+=1;let o=`img${Fn}`;return{ref:``,label:o,kind:"image"}}Fn+=1;let a=`file${Fn}`;return{ref:`[${a}](${t})`,label:a,kind:"file"}}function Wn(){for(let e of Ke)if(e.previewUrl)try{URL.revokeObjectURL(e.previewUrl)}catch{}Ke.length=0,Gs()}function Ot(){Wn()}function Gs(){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 Cr(e){if(!e)return;let t=e.name||`upload-${Date.now()}`,s=await To(e,t),a=await Er(s,t),{ref:o,label:i,kind:r}=Tr(e,a),c="";if(r==="image")try{c=URL.createObjectURL(s)}catch{}return Ke.push({path:a,ref:o,label:i,kind:r,name:t,previewUrl:c}),Gs(),Mr((0,n.$)("chat-input"),o),a}async function Kn(e){let t=[...e||[]].filter(Boolean);if(!t.length)return;let s=(0,n.$)("chat-input");s&&(s.disabled=!0);try{for(let a of t)try{await Cr(a)}catch(o){x(`\u4E0A\u4F20\u5931\u8D25 ${a.name||"file"}: ${o.message}`)}}finally{s&&(s.disabled=!1,s.focus())}}function Ar(){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",()=>Kn(t.files)),t.click()}function Co(){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 o=[...e.clipboardData?.items||[]],i=[];for(let f of o)if(f.kind==="file"){let l=f.getAsFile();l&&i.push(l)}let r=i.filter(f=>Ws(f)),c=r.length?r:i;c.length&&(e.preventDefault(),await Kn(c))}),!xo&&(xo=!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 Kn(s))}))}function De(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function zs(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 _t(e){if(!e)return;let t=e.input_tokens??e.inputTokens??0,s=e.output_tokens??e.outputTokens??0,a=e.total_tokens??e.totalTokens??t+s,o=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=a?` \xB7 \u03A3${De(a)}`:"";zs(`\u2191${De(t)} \u2193${De(s)}${o}${i}${r}${l}${f}`)}function Js(e){if(!e)return;let t=e.tokensUsed??e.contextTokensUsed,s=e.windowTokens??e.contextWindowTokens,a=e.usagePercent??e.contextWindowUsage;if(t==null&&s==null&&a==null)return;let o=[];t!=null&&s!=null?o.push(`context ${De(t)} / ${De(s)}`):t!=null&&o.push(`context ${De(t)}`),a!=null&&o.push(`${a}%`),e.model&&o.push(e.model),e.turnCount!=null&&o.push(`${e.turnCount} turns`),e.toolCallCount!=null&&o.push(`${e.toolCallCount} tools`),zs(`\u25A3 ${o.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 jr(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 Dr(e,t){e&&(e.textContent+=t,de(e.closest("#messages")))}function Nr(e){let t=typeof e.input=="object"?JSON.stringify(e.input,null,2):String(e.input||""),a=((typeof e.input=="object"?Object.values(e.input).find(o=>typeof o=="string"&&o.trim()):t)||"").replace(/\n/g," ").slice(0,Ce.peek()==="full"?120:80);return{inputStr:t,preview:a}}function vo(e,{inBatch:t=!1}={}){let{inputStr:s,preview:a}=Nr(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>
|
|
64
|
-
<span class="text-base-content/50 truncate flex-1">${(0,n.esc)(
|
|
64
|
+
<span class="text-base-content/50 truncate flex-1">${(0,n.esc)(a)}</span>
|
|
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 Pr(e){let t=[...new Set(e.names)],s=t.slice(0,4).join(", ")+(t.length>4?"\u2026":""),a=e.el.querySelector(".tool-batch-summary");a&&(a.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 pe(){ke=null}function
|
|
71
|
+
<span class="tool-chevron text-[10px] text-base-content/40">\u25B6</span>`)}function pe(){ke=null}function Ks(e,t={}){let s=(0,n.$)("messages");if(!s)return;let a=Ce.peek()||"normal",o=A(t.ts);if(a==="clean"){if(!ke||!s.contains(ke.el)){let f=zn(o),l=Jn(o);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",vo(e,{inBatch:!0})),Pr(ke),de(s);return}ke=null;let i=zn(o),r=Jn(o);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%]">${vo(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 Vn(){let e=(0,n.$)("messages");e&&e.setAttribute("data-density",Ce.peek()||"normal")}function Hr(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=xr[o.toLowerCase()]||o,i=w.peek()||"claude",r=je
|
|
|
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 _r(){if(
|
|
92
|
+
</div>`),(0,n.$)("messages").scrollTop=999999}function _r(){if(yo||typeof marked>"u")return;let e=a=>String(a??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),t=(a,o)=>{let i=String(o||"").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
|
-
<pre><code class="hljs ${c}">${e(
|
|
98
|
-
</div>`},s={code(o
|
|
97
|
+
<pre><code class="hljs ${c}">${e(a)}</code></pre>
|
|
98
|
+
</div>`},s={code(a,o){return a&&typeof a=="object"&&a.text!=null?t(a.text,a.lang||o):t(a,o)},table(a,o){return a&&typeof a=="object"&&!Array.isArray(a)&&a.header?!1:`<div class="table-wrap"><table><thead>${a}</thead><tbody>${o}</tbody></table></div>`}};try{if(typeof marked.use=="function")marked.use({gfm:!0,breaks:!0,renderer:s});else if(typeof marked.setOptions=="function"){let a=new marked.Renderer;a.code=s.code,a.table=s.table,marked.setOptions({gfm:!0,breaks:!0,renderer:a})}}catch(a){console.warn("[md] marked setup failed",a)}yo=!0}function Gn(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 Ao(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 jo(){Vn(),oo(),(0,n.watch)(Ie,a=>{pn(),Je();let o=(0,n.$)("ws-banner"),i=(0,n.$)("ws-banner-text");if(!o)return;if(a==="open"||a==="idle"){o.classList.add("hidden"),i&&(i.textContent="");return}if(a==="connecting"&&!On){o.classList.add("hidden");return}o.classList.remove("hidden");let r=a==="offline"?"\u7F51\u7EDC\u5DF2\u65AD\u5F00\uFF0C\u6062\u590D\u540E\u4F1A\u81EA\u52A8\u91CD\u8FDE":a==="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:o.textContent=r}),(0,n.watch)(v,()=>Je()),n.delegate.on("click","#btn-refresh-conn, #ws-banner-retry",a=>{a.preventDefault(),hr()}),(0,n.watch)(X,a=>{(0,n.$)("send-btn")?.classList.toggle("hidden",a),(0,n.$)("stop-btn")?.classList.toggle("hidden",!a);let o=(0,n.$)("chat-input");o&&(o.disabled=!1,a?o.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(o.value||""));let i=(0,n.$)("messages");if(!i)return;let r=(0,n.$)("typing-indicator");a&&!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)):a||(r?.remove(),pe()),Je()}),(0,n.watch)(Ce,()=>Vn()),n.delegate.on("keydown","#chat-input",a=>{if(a.key!=="Enter")return;let o=a.metaKey||a.ctrlKey,i=window.matchMedia("(max-width: 640px)").matches&&!a.shiftKey&&!o;(o||i)&&(a.preventDefault(),fn())}),n.delegate.on("submit","#chat-form",a=>{a.preventDefault(),fn()}),n.delegate.on("input","#chat-input",(a,o)=>{Ht(o),Pt(o.value)}),n.delegate.on("click","#btn-attach",a=>{a.preventDefault(),Ar()}),n.delegate.on("change","#chat-file-input",(a,o)=>{let i=o?.files;i?.length&&Kn(i),o&&(o.value="")}),n.delegate.on("click","[data-rm-attach]",(a,o)=>{a.preventDefault(),a.stopPropagation();let i=parseInt(o.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"))),Ke.splice(i,1),
|
|
101
|
-
`);c=p.pop()||"";for(let m of p)if(m.startsWith("event:"))f=m.slice(6).trim();else if(m.startsWith("data:")){let
|
|
100
|
+
`),c.dispatchEvent(new Event("input"))),Ke.splice(i,1),Gs()}),n.delegate.on("click","[data-perm-id]",(a,o)=>{Mt({type:"command",cmd:"approval.respond",requestId:o.dataset.permId,allow:o.dataset.permAllow==="1",sessionId:u.sessionId}),o.closest(".perm-banner")?.remove()}),n.delegate.on("click",".tool-card",(a,o)=>{let i=o.closest(".tool-batch");if(i&&!i.classList.contains("open")&&!o.classList.contains("tool-batch-item"))return;a.stopPropagation();let r=(0,n.$)("messages"),c=o.getBoundingClientRect().top;if(o.classList.toggle("open"),r){let f=o.getBoundingClientRect().top;r.scrollTop+=f-c}}),n.delegate.on("click",".tool-batch",(a,o)=>{if(a.target.closest(".tool-card")&&o.classList.contains("open"))return;let i=(0,n.$)("messages"),r=o.getBoundingClientRect().top;if(o.classList.toggle("open"),i){let c=o.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 a=()=>{let o=e.scrollHeight-e.clientHeight>200;t.classList.toggle("hidden",!o||e.scrollTop<200),s.classList.toggle("hidden",!o||wo(e))};e.addEventListener("scroll",a,{passive:!0}),new ResizeObserver(a).observe(e),new MutationObserver(a).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"})),a()}n.delegate.on("click",".msg-expand-btn",(a,o)=>{a.stopPropagation();let r=o.closest(".msg-card").classList.toggle("open");o.textContent=r?"\u25B2 Show less":"\u25BC Show more"}),n.delegate.on("click",".code-copy",async(a,o)=>{a.preventDefault(),a.stopPropagation();let c=o.closest(".code-block")?.querySelector("pre code")?.textContent??"";try{await navigator.clipboard.writeText(c),o.textContent="Copied",o.classList.add("copied"),setTimeout(()=>{o.textContent="Copy",o.classList.remove("copied")},1400)}catch{o.textContent="Failed",setTimeout(()=>{o.textContent="Copy"},1400)}})}var cn,Pe,Le,Ne,Un,bo,On,go,qn,He,ut,$e,ce,ze,Se,xr,kr,$r,Ke,Fn,xo,ke,yo,Wt=H(()=>{M();C();J();io();qs();Nt();Nt();cn=0,Pe=null,Le=1e3,Ne=0,Un=null,bo=!1,On=!1,go=null,qn=!1,He=[],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"};kr=200,$r=500;Ke=[],Fn=0,xo=!1;ke=null;yo=!1});function No(e,t){Do=e,Vs=t,window.addEventListener("hashchange",()=>{if(Ys){Ys=!1;return}Ho(location.hash.slice(1)||"/")}),(0,n.watch)(j,s=>{u.sessionId&&mn()})}function Xs(e){let[t,s=""]=String(e||"").split("?",2),a=t.match(/^\/session\/([^/]+)(?:\/([^/]+))?$/);if(!a)return null;let o=new URLSearchParams(s);try{return{id:decodeURIComponent(a[1]),tab:a[2]?decodeURIComponent(a[2]):null,machineId:o.get("machine")||null,agent:o.get("agent")||null}}catch{return null}}function Po(){Ho(location.hash.slice(1)||"/")}function Ho(e){let t=Xs(e);if(!t){document.dispatchEvent(new CustomEvent("router:home"));return}let{id:s,tab:a,machineId:o,agent:i}=t;!Do||!Vs||(s!==u.sessionId?document.dispatchEvent(new CustomEvent("router:session",{detail:{id:s,tab:a,machineId:o,agent:i}})):a&&a!==j.peek()&&Vs(a))}function Qs(e){Ys=!0,location.hash=e}function mn(){if(!u.sessionId)return;let e=new URLSearchParams;u.machineId&&e.set("machine",u.machineId),u.agent&&e.set("agent",u.agent);let t=e.size?`?${e}`:"";Qs(`/session/${encodeURIComponent(u.sessionId)}/${encodeURIComponent(j.peek())}${t}`)}function _o(){if(!u.sessionId)return null;let e=new URL(location.href),t=new URLSearchParams;u.machineId&&t.set("machine",u.machineId),u.agent&&t.set("agent",u.agent);let s=t.size?`?${t}`:"";return e.hash=`/session/${encodeURIComponent(u.sessionId)}/${encodeURIComponent(j.peek())}${s}`,e.toString()}var ac,Do,Vs,Ys,Yn=H(()=>{M();C();ac=(0,n.createRouter)({"/":()=>{},"/session/*":()=>{},"/session/*/*":()=>{},"*":()=>{}}),Do=null,Vs=null,Ys=!1});async function Qn(){try{return await Xn.get("sessions")??null}catch{return null}}async function Ro(e){try{await Xn.set("sessions",e,{ttl:Rr})}catch{}}async function Bo(){try{return await Xn.get("workspaces")??null}catch{return null}}async function hn(e){try{await Xn.set("workspaces",e,{ttl:3600*1e3})}catch{}}var Xn,Rr,Zn=H(()=>{M();Xn=(0,n.idb)("claude-ui"),Rr=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 na(e,t,s){let a=Ge({"Content-Type":"application/json"}),o=await fetch(e,{method:"POST",headers:a,body:JSON.stringify(t||{})});if(!o.ok){let l=await o.json().catch(()=>({}));throw new Error(l.error||`HTTP ${o.status}`)}let i=o.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 g=m.slice(5).trim();if(!g)continue;let b;try{b=JSON.parse(g)}catch{continue}s[f]?.(b),s.any?.(f,b),f="message"}else m.trim()===""&&(f="message")}}function Fr(){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,68 +278,68 @@ Available: ${f}`:""}`),!0}let a=xr[o.toLowerCase()]||o,i=w.peek()||"claude",r=je
|
|
|
278
278
|
</div>
|
|
279
279
|
</div>
|
|
280
280
|
</div>
|
|
281
|
-
</div>`}function ne(e){Ye=e;let t=(0,n.$)("ma-mode-chat"),s=(0,n.$)("ma-mode-history"),
|
|
281
|
+
</div>`}function ne(e){Ye=e;let t=(0,n.$)("ma-mode-chat"),s=(0,n.$)("ma-mode-history"),a=(0,n.$)("ma-mode-notes"),o=(0,n.$)("ma-mode-report"),i=(0,n.$)("ma-mode-config");for(let[c,f]of[[t,"chat"],[s,"history"],[a,"notes"],[o,"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 gn(){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 a=ie?.title||K.slice(0,8),o=is(ie?.updatedAt);if(e&&(e.textContent=o?`${a} \xB7 ${o}`:a),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 sa(e="chat"){let t=(0,n.$)("meta-agent-panel");if(t){if(t.classList.remove("hidden"),t.setAttribute("aria-hidden","false"),os=!0,ne(e),e==="chat"){Re();let s=localStorage.getItem(Xe);!K&&s?Be(s,{silent:!0}).catch(()=>{localStorage.removeItem(Xe)}):gn()}e==="history"&&Re().then(()=>bt()),e==="report"&&Zo(),e==="config"&&ei(),setTimeout(()=>{Ye==="chat"&&(0,n.$)("ma-input")?.focus(),Ye==="history"&&(0,n.$)("ma-history-search")?.focus()},50)}}function Ko(){let e=(0,n.$)("meta-agent-panel");e&&(e.classList.add("hidden"),e.setAttribute("aria-hidden","true"),os=!1)}function Vo(){os?Ko():sa(Ye==="config"?"chat":Ye)}function _(e,t,s={}){let a=(0,n.$)("ma-messages");if(!a)return null;let o=document.createElement("div");return o.className=`ma-msg ma-msg-${e}`,e==="user"?o.innerHTML=`<div class="ma-bubble user">${(0,n.esc)(t)}</div>`:e==="assistant"?(o.innerHTML=`<div class="ma-bubble assistant md">${Jt(t)}</div>`,Kt(o)):e==="error"?o.innerHTML=`<div class="ma-bubble error">${(0,n.esc)(t)}</div>`:e==="system"?o.innerHTML=`<div class="ma-sys">${(0,n.esc)(t)}</div>`:e==="tool"&&(o.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>`),
|
|
285
|
+
</div>`),a.appendChild(o),a.scrollTop=a.scrollHeight,o}function Oo(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 Yo(e,t,s){let a=(0,n.$)("ma-messages");if(!a)return;let o=a.querySelector(`[data-tool-id="${CSS.escape(e)}"]`);if(!o)return;o.classList.toggle("done",t==="done"),o.classList.toggle("error",t==="error");let i=o.querySelector(".ma-tool-phase");if(i&&(i.textContent=t),s&&t!=="start"){let r=o.querySelector(".ma-tool-result");r||(r=document.createElement("pre"),r.className="ma-tool-result",o.appendChild(r)),r.textContent=JSON.stringify(s,null,0).slice(0,500)}}function Ur(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 a=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
|
-
<pre class="ma-approval-cmd">${(0,n.esc)(
|
|
287
|
+
<pre class="ma-approval-cmd">${(0,n.esc)(a)}</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(
|
|
291
|
+
</div>`,s.querySelectorAll("[data-approve]").forEach(o=>{o.addEventListener("click",async()=>{let i=o.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 Or(){return Uo+=1,`img${Uo}`}function qr(e,t){if(!e)return;let s=e.selectionStart??e.value.length,a=e.selectionEnd??e.value.length;e.value=e.value.slice(0,s)+t+e.value.slice(a),e.selectionStart=e.selectionEnd=s+t.length,e.dispatchEvent(new Event("input"))}async function qo(e,t){let s=Ge({"x-filename":t||`paste-${Date.now()}.png`});delete s["Content-Type"];let a=await fetch("/api/upload-image",{method:"POST",headers:s,body:e});if(!a.ok){let l=await a.json().catch(()=>({}));throw new Error(l.error||`Upload failed: ${a.status}`)}let{path:o}=await a.json();if(!o)throw new Error("upload returned no path");let i=Or(),r=`[${i}](${o})`,c=(0,n.$)("ma-input");qr(c,(c?.value&&!c.value.endsWith(`
|
|
292
292
|
`)&&c.value.length?`
|
|
293
293
|
`:"")+r+`
|
|
294
|
-
`);let f="";try{f=URL.createObjectURL(e)}catch{}return ft.push({path:
|
|
294
|
+
`);let f="";try{f=URL.createObjectURL(e)}catch{}return ft.push({path:o,previewUrl:f,label:i,ref:r}),aa(),{path:o,ref:r,label:i}}function aa(){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),
|
|
299
|
+
</div>`).join(""),e.querySelectorAll("[data-rm-img]").forEach(t=>{t.addEventListener("click",()=>{let s=parseInt(t.dataset.rmImg,10),a=ft[s];if(a?.previewUrl)try{URL.revokeObjectURL(a.previewUrl)}catch{}let o=(0,n.$)("ma-input");o&&a?.ref&&(o.value=o.value.split(a.ref).join("").replace(/\n{3,}/g,`
|
|
300
300
|
|
|
301
|
-
`),
|
|
301
|
+
`),o.dispatchEvent(new Event("input"))),ft.splice(s,1),aa()})})}}function is(e){if(!e)return"";let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let s=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0"),o=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${a} ${o}:${i}`}async function Re(){try{ss=(await h("GET","/api/ai/sessions")).sessions||[]}catch{ss=[]}return ss}function Xo(){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 bn(){ht=null,Jo=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=Xo().summary||"\u672A\u5173\u8054\u4E0A\u4E0B\u6587"}function Qo(e){ht=e?.id||null,Jo=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 ${is(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 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="\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 a=["\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
|
-
`);ne("chat"),(0,n.$)("ma-input").value=
|
|
304
|
+
`);ne("chat"),(0,n.$)("ma-input").value=a,(0,n.$)("ma-input").dispatchEvent(new Event("input")),(0,n.$)("ma-input").focus()}async function zt(){let e=(zo||"").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,a=[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)(
|
|
309
|
+
<div class="text-[10px] text-base-content/35 mt-1">${(0,n.esc)(a)}${a?" \xB7 ":""}${(0,n.esc)(is(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}`);Qo(s),mt()}catch(s){(0,n.$)("ma-note-status").textContent=s.message}})})}}async function Gr(){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=Xo(),a={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 o=await h("POST","/api/ai/notes",a);Qo(o),await zt(),mt()}async function zr(){if(!ht){bn();return}confirm("\u5220\u9664\u8FD9\u6761\u8BB0\u4E8B\uFF1F\u4E0D\u53EF\u6062\u590D\u3002")&&(await h("DELETE",`/api/ai/notes/${ht}`),bn(),await zt(),mt())}function bt(){let e=(0,n.$)("ma-history-list");if(!e)return;let t=(Go||"").trim().toLowerCase(),s=ss;if(t&&(s=s.filter(a=>`${a.title||""} ${a.preview||""} ${a.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(
|
|
314
|
-
<div class="ma-hist-item ${
|
|
313
|
+
</div>`;return}e.innerHTML=s.map(a=>{let o=a.id===K,i=is(a.updatedAt)||"",r=a.messageCount||0;return`
|
|
314
|
+
<div class="ma-hist-item ${o?"active":""}" data-hist-id="${(0,n.esc)(a.id)}">
|
|
315
315
|
<div class="flex items-start gap-2">
|
|
316
|
-
<button type="button" class="ma-hist-open flex-1 min-w-0 text-left" data-hist-open="${(0,n.esc)(
|
|
317
|
-
<div class="font-medium text-xs truncate">${(0,n.esc)(
|
|
318
|
-
<div class="text-[10px] text-base-content/45 mt-0.5 line-clamp-2">${(0,n.esc)(
|
|
319
|
-
<div class="text-[10px] text-base-content/35 mt-1">${(0,n.esc)(i)}${r?` \xB7 ${r} \u6761`:""}${
|
|
316
|
+
<button type="button" class="ma-hist-open flex-1 min-w-0 text-left" data-hist-open="${(0,n.esc)(a.id)}">
|
|
317
|
+
<div class="font-medium text-xs truncate">${(0,n.esc)(a.title||a.id.slice(0,8))}</div>
|
|
318
|
+
<div class="text-[10px] text-base-content/45 mt-0.5 line-clamp-2">${(0,n.esc)(a.preview||"\uFF08\u65E0\u9884\u89C8\uFF09")}</div>
|
|
319
|
+
<div class="text-[10px] text-base-content/35 mt-1">${(0,n.esc)(i)}${r?` \xB7 ${r} \u6761`:""}${o?" \xB7 \u5F53\u524D":""}</div>
|
|
320
320
|
</button>
|
|
321
321
|
<div class="flex flex-col gap-0.5 flex-shrink-0">
|
|
322
|
-
<button type="button" class="btn btn-ghost btn-xs px-1" data-hist-resume="${(0,n.esc)(
|
|
323
|
-
<button type="button" class="btn btn-ghost btn-xs px-1 text-error" data-hist-del="${(0,n.esc)(
|
|
322
|
+
<button type="button" class="btn btn-ghost btn-xs px-1" data-hist-resume="${(0,n.esc)(a.id)}" title="\u6253\u5F00\u5E76\u7EE7\u7EED">\u21B5</button>
|
|
323
|
+
<button type="button" class="btn btn-ghost btn-xs px-1 text-error" data-hist-del="${(0,n.esc)(a.id)}" title="\u5220\u9664">\u2715</button>
|
|
324
324
|
</div>
|
|
325
325
|
</div>
|
|
326
|
-
</div>`}).join(""),e.querySelectorAll("[data-hist-open]").forEach(
|
|
327
|
-
`)||"[\u2026]"}function
|
|
326
|
+
</div>`}).join(""),e.querySelectorAll("[data-hist-open]").forEach(a=>{a.addEventListener("click",async()=>{await Be(a.dataset.histOpen),ne("chat"),(0,n.$)("ma-input")?.focus()})}),e.querySelectorAll("[data-hist-resume]").forEach(a=>{a.addEventListener("click",async o=>{o.stopPropagation(),await Be(a.dataset.histResume),ne("chat"),(0,n.$)("ma-input")?.focus()})}),e.querySelectorAll("[data-hist-del]").forEach(a=>{a.addEventListener("click",async o=>{o.stopPropagation();let i=a.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 Wo(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 Jr(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",Wo(s.content));continue}if(s.role==="assistant"){if(s.tool_calls?.length)for(let a of s.tool_calls){let o=a.function?.name||a.name||"tool",i={};try{i=JSON.parse(a.function?.arguments||a.arguments||"{}")}catch{}_("tool","",{name:o,args:i,phase:"history",id:a.id||o})}s.content&&_("assistant",typeof s.content=="string"?s.content:Wo(s.content));continue}if(s.role==="tool"){let a=s.content;try{a=JSON.parse(s.content)}catch{}let o=s.tool_call_id||"";if(o)Yo(o,"done",a);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 a=="string"?a.slice(0,500):JSON.stringify(a,null,0).slice(0,500)}}}}t.scrollTop=t.scrollHeight}}async function Kr(){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"),gn(),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),Jr(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"),gn(),Ye==="history"&&bt(),s}catch(s){throw t.silent||_("error",s.message),s}}async function ns(){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 o of ft)if(o.previewUrl)try{URL.revokeObjectURL(o.previewUrl)}catch{}ft=[],aa();let s=null,a="";try{await na("/api/ai/chat",{message:t,sessionId:K},{session:o=>{K=o.id,ie={...ie||{},id:o.id,title:o.title||ie?.title||t.slice(0,40),updatedAt:Date.now()},localStorage.setItem(Xe,o.id),gn()},content:o=>{a=o.content||"",s||(s=_("assistant","")),Oo(s,a)},tool:o=>{o.phase==="start"?_("tool","",{name:o.name,args:o.args,phase:"start",id:o.id}):Yo(o.id,o.phase,o.result)},approval:o=>Ur(o),done:o=>{o.sessionId&&(K=o.sessionId,localStorage.setItem(Xe,o.sessionId)),(o.title||o.sessionId)&&(ie={id:K,title:o.title||ie?.title||"\u5BF9\u8BDD",updatedAt:Date.now(),messageCount:(ie?.messageCount||0)+2}),o.content&&s&&Oo(s,o.content),gn(),Re()},error:o=>{_("error",o.message||"error")}})}catch(o){_("error",o.message)}finally{Gt=!1,(0,n.$)("ma-send").disabled=!1}}async function Vr(){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="",a=document.createElement("div");a.className="ma-report-tools flex flex-col gap-1 mb-3";try{await na("/api/ai/report",{days:e},{content:o=>{s=o.content||"",t.innerHTML="",t.appendChild(a);let i=document.createElement("div");i.className="md ma-report-md",i.innerHTML=Jt(s),Kt(i),t.appendChild(i)},tool:o=>{if(o.phase==="start"){let i=document.createElement("div");i.className="ma-tool",i.dataset.toolId=o.id||o.name,i.innerHTML=`<span class="ma-tool-name">${(0,n.esc)(o.name)}</span> <span class="ma-tool-phase">start</span>`,a.appendChild(i)}else{let i=a.querySelector(`[data-tool-id="${CSS.escape(o.id||o.name)}"]`);i&&(i.classList.add(o.phase==="error"?"error":"done"),i.querySelector(".ma-tool-phase").textContent=o.phase)}},done:o=>{if(o.content){t.innerHTML="",t.appendChild(a);let i=document.createElement("div");i.className="md ma-report-md",i.innerHTML=Jt(o.content),Kt(i),t.appendChild(i)}},error:o=>{t.innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(o.message)}</div>`}})}catch(o){t.innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(o.message)}</div>`}finally{Gt=!1,(0,n.$)("ma-gen-report").disabled=!1}}async function Zo(){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 a=(0,n.$)("ma-report-body");a.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">${Jt(s.markdown)}</div>`,Kt(
|
|
329
|
+
<div class="md ma-report-md">${Jt(s.markdown)}</div>`,Kt(a)}}catch{}}async function Yr(){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(a=>`
|
|
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
|
-
data-day="${(0,n.esc)(
|
|
332
|
-
<span class="font-semibold">${(0,n.esc)(
|
|
333
|
-
<span class="text-base-content/45 ml-1">${(0,n.esc)(
|
|
334
|
-
</button>`).join(""),e.querySelectorAll("[data-day]").forEach(
|
|
335
|
-
<div class="text-[10px] text-base-content/40 mb-2">${(0,n.esc)(
|
|
336
|
-
<div class="md ma-report-md">${Jt(
|
|
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] ${
|
|
338
|
-
data-cal-date="${m}" title="${p.toDateString()}: ${
|
|
331
|
+
data-day="${(0,n.esc)(a.day)}">
|
|
332
|
+
<span class="font-semibold">${(0,n.esc)(a.day)}</span>
|
|
333
|
+
<span class="text-base-content/45 ml-1">${(0,n.esc)(a.title||"")}</span>
|
|
334
|
+
</button>`).join(""),e.querySelectorAll("[data-day]").forEach(a=>{a.addEventListener("click",async()=>{try{let o=await h("GET",`/api/ai/reports/${a.dataset.day}`),i=(0,n.$)("ma-report-body");i.innerHTML=`
|
|
335
|
+
<div class="text-[10px] text-base-content/40 mb-2">${(0,n.esc)(o.title||o.day)} \xB7 ${(0,n.esc)(o.generatedAt||"")}</div>
|
|
336
|
+
<div class="md ma-report-md">${Jt(o.markdown)}</div>`,Kt(i)}catch(o){(0,n.$)("ma-report-body").innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(o.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 ei(){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 Xr(){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(),a=(0,n.$)("ma-cfg-vlm-key").value.trim();s&&(t.key=s),a&&(t.vlm_key=a);let o=await h("PUT","/api/ai/config",t);e.textContent=o.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(o)}catch(t){e.textContent=t.message}}function xn(e){if(ts&&(clearInterval(ts),ts=null),!e?.auto_report)return;let t=e.auto_report_hour??18;ts=setInterval(async()=>{if(!u.token)return;let s=new Date;if(s.getHours()!==t)return;let a=`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-${String(s.getDate()).padStart(2,"0")}`;if(ta!==a&&!(s.getMinutes()>10))try{ta=a,localStorage.setItem("ai_last_auto_report",a),await na("/api/ai/report",{days:e.auto_report_days||1},{done:()=>{console.info("[meta-agent] auto report saved for",a)},error:o=>console.warn("[meta-agent] auto report",o.message)})}catch(o){console.warn("[meta-agent] auto report failed",o),ta="",localStorage.removeItem("ai_last_auto_report")}},60*1e3)}function ti(){(0,n.$)("meta-agent-panel")||(document.getElementById("root")?.insertAdjacentHTML("beforeend",Fr()),document.querySelectorAll("[data-ma-close]").forEach(e=>{e.addEventListener("click",Ko)}),(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||bn(),ne("notes")}),(0,n.$)("ma-open-history")?.addEventListener("click",async()=>{await Re(),ne("history")}),(0,n.$)("ma-btn-report")?.addEventListener("click",()=>{ne("report"),Zo()}),(0,n.$)("ma-btn-config")?.addEventListener("click",()=>{ne("config"),ei()}),(0,n.$)("ma-send")?.addEventListener("click",ns),(0,n.$)("ma-input")?.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key==="Enter"&&(e.preventDefault(),ns())}),(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",Kr),(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=>{Go=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",ns()}),(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",ns()}),(0,n.$)("ma-gen-report")?.addEventListener("click",Vr),(0,n.$)("ma-load-reports")?.addEventListener("click",Yr),(0,n.$)("ma-notes-refresh")?.addEventListener("click",async()=>{await zt(),mt()}),(0,n.$)("ma-notes-new")?.addEventListener("click",()=>{bn(),mt(),(0,n.$)("ma-note-title")?.focus()}),(0,n.$)("ma-notes-search")?.addEventListener("input",async e=>{zo=e.target.value||"",await zt(),mt()}),(0,n.$)("ma-note-save")?.addEventListener("click",async()=>{try{await Gr()}catch(e){(0,n.$)("ma-note-status").textContent=e.message}}),(0,n.$)("ma-note-delete")?.addEventListener("click",async()=>{try{await zr()}catch(e){(0,n.$)("ma-note-status").textContent=e.message}}),(0,n.$)("ma-note-ask")?.addEventListener("click",Wr),(0,n.$)("ma-cfg-save")?.addEventListener("click",Xr),(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 a of t)if(a.type.startsWith("image/")){if(a.size>12*1024*1024){_("error",`${a.name} \u8FC7\u5927 (>12MB)`);continue}await qo(a,a.name||`upload-${Date.now()}.png`)}}catch(a){_("error",`\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${a.message}`)}finally{e.target.value="",s&&(s.disabled=!1,s.focus())}}),document.addEventListener("paste",async e=>{if(!os||Ye!=="chat")return;let t=(0,n.$)("ma-input"),s=(0,n.$)("meta-agent-panel"),a=document.activeElement;if(!s||!a||!s.contains(a))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 qo(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}),bn())}function vn(){u.token&&($.peek()&&!sn()||(Re(),zt().catch(()=>{}),h("GET","/api/ai/config").then(xn).catch(()=>{})))}var os,Ye,Gt,K,ie,ft,Uo,ts,ta,ss,Go,as,zo,ht,Jo,Xe,yn=H(()=>{M();J();C();os=!1,Ye="chat",Gt=!1,K=null,ie=null,ft=[],Uo=0,ts=null,ta=localStorage.getItem("ai_last_auto_report")||"",ss=[],Go="",as=[],zo="",ht=null,Jo=null,Xe="ma_last_session_id"});function oa(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}function xt(){let e=oa(T.peek()),t=S.peek();$.peek()&&t&&(e=e.filter(a=>a&&(!a.machineId||a.machineId===t)));let s=ae.peek();return s&&s!=="all"&&(e=e.filter(a=>a&&(a.agent||"claude")===s)),e}function ai(e){let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),a=String(e.getDate()).padStart(2,"0");return`${t}-${s}-${a}`}function Qr(e,t){let s=[],o=new Date(e,t,1).getDay(),r=new Date(e,t+1,0).getDate(),c=new Date(e,t,0).getDate();for(let l=o-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(),a=s+1440*60*1e3;return t.filter(o=>{let i=A(o.updatedAt);return i!=null&&i>=s&&i<a})}function ii(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=oa(e??xt());let s=(0,n.$)("calendar-month-year");if(s){let d=new Date(rs,gt,1);s.textContent=d.toLocaleDateString([],{month:"long",year:"numeric"})}let a=e.length,o=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(a)),c&&(c.textContent=String(o)),f&&(f.textContent=ii(i));let l=Qr(rs,gt);wn||(wn=ai(new Date)),t.innerHTML=l.map(d=>{let p=d.date,m=ai(p),b=oi(p,e).length,P=p.toDateString()===new Date().toDateString(),Ze=m===wn,ge="",et="text-base-content/65",Ee="border border-transparent",k="cursor-default",V=d.isCurrentMonth?"":"opacity-25";b>0?(k="cursor-pointer",b<=2?(ge="bg-primary/15",et="text-primary font-bold",Ee="border border-primary/30"):b<=5?(ge="bg-primary/30",et="text-primary font-bold",Ee="border border-primary/50"):(ge="bg-primary/60",et="text-primary-content font-bold",Ee="border border-primary/80")):(ge="bg-base-300/25",d.isCurrentMonth&&(k="hover:bg-base-300/50")),P?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] ${ge} ${et} ${Ee} ${k} ${V}"
|
|
338
|
+
data-cal-date="${m}" title="${p.toDateString()}: ${b} session(s)">
|
|
339
339
|
${tt}
|
|
340
340
|
<span class="text-sm font-semibold">${p.getDate()}</span>
|
|
341
|
-
${
|
|
342
|
-
</div>`}).join(""),
|
|
341
|
+
${b>0?`<span class="text-[10px] mt-0.5 opacity-80 font-medium whitespace-nowrap">${b}s</span>`:""}
|
|
342
|
+
</div>`}).join(""),Zr(e),ra()}function Zr(e){let t=(0,n.$)("selected-day-title"),s=(0,n.$)("selected-day-sessions");if(!t||!s)return;let[a,o,i]=wn.split("-").map(Number),r=new Date(a,o-1,i);t.textContent=`Activity on ${r.toLocaleDateString([],{weekday:"short",month:"short",day:"numeric",year:"numeric"})}`,e=oa(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=ii(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
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||"")}"
|
|
@@ -352,7 +352,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
352
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
|
|
355
|
+
</div>`}).join("")}function ls(e){return`${e.machineId||""}:${e.agent||"claude"}:${e.sessionId}`}function ia(){try{let e=JSON.parse(localStorage.getItem(li)||"[]");return Array.isArray(e)?e.filter(t=>t&&t.sessionId):[]}catch{return[]}}function ci(e){try{localStorage.setItem(li,JSON.stringify(e))}catch{}}function di(e){if(!e?.sessionId)return;let t=ls(e),s={...e,lastOpenedAt:Date.now()},a=ia().filter(o=>ls(o)!==t);a.unshift(s),ci(a.slice(0,ri)),ra(),ca()}function ui(e){if(!e?.sessionId)return;let t=ls(e);ci(ia().filter(s=>ls(s)!==t)),ra(),ca()}function pi(e){return ia().sort((t,s)=>(A(s.lastOpenedAt)||0)-(A(t.lastOpenedAt)||0)).slice(0,e)}function ra(){let e=(0,n.$)("recent-sessions-list");if(!e)return;let t=pi(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 a=Dt(s.updatedAt);return`
|
|
356
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||"")}"
|
|
@@ -364,20 +364,20 @@ ${t}`:"",s.length?s.join(`
|
|
|
364
364
|
<div class="text-xs font-bold truncate text-base-content/95">${(0,n.esc)(Ae(s))}</div>
|
|
365
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
|
-
<div class="text-[9px] text-base-content/40 whitespace-nowrap self-start mt-0.5">${
|
|
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
|
|
367
|
+
<div class="text-[9px] text-base-content/40 whitespace-nowrap self-start mt-0.5">${a}</div>
|
|
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 la(){let e=(0,n.$)("recent-menu"),t=(0,n.$)("topbar");if(!e||!t)return;let s=t.getBoundingClientRect(),o=Math.round(s.bottom+6),i=window.matchMedia("(max-width: 640px)").matches?8:null;if(e.style.top=`${o}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-o-12);e.style.maxHeight=`${Math.min(r,Math.round(window.innerHeight*.7))}px`}function el(){let e=(0,n.$)("recent-menu");e&&(ca(),e.classList.remove("hidden"),e.classList.add("recent-menu-open"),la(),(0,n.$)("recent-menu-backdrop")?.classList.remove("hidden"))}function fi(){let e=(0,n.$)("recent-menu");e&&(e.classList.contains("hidden")?el():yt())}function ca(){let e=(0,n.$)("recent-menu-list"),t=(0,n.$)("recent-menu-empty"),s=(0,n.$)("recent-menu-count");if(!e)return;let a=pi(ri);if(s&&(s.textContent=a.length?`${a.length}`:""),!a.length){e.innerHTML="",t?.classList.remove("hidden");return}t?.classList.add("hidden"),e.innerHTML=a.map(o=>{let i=Dt(o.updatedAt),r=u.sessionId===o.sessionId&&(!o.machineId||!u.machineId||o.machineId===u.machineId),c=o.machineId?`<span class="text-[9px] font-mono text-base-content/35 truncate max-w-[4.5rem]" title="${(0,n.esc)(o.machineId)}">@${(0,n.esc)(o.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
|
-
<button type="button" class="flex min-w-0 flex-1 items-start gap-2 text-left" aria-label="\u6253\u5F00 ${(0,n.esc)(Ae(
|
|
372
|
-
data-session-id="${(0,n.esc)(
|
|
373
|
-
data-session-cwd="${(0,n.esc)(
|
|
374
|
-
data-session-config-dir="${(0,n.esc)(
|
|
375
|
-
data-session-agent="${(0,n.esc)(
|
|
376
|
-
data-session-machine="${(0,n.esc)(
|
|
377
|
-
<span class="flex-shrink-0 mt-0.5">${rt(
|
|
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(o))}"
|
|
372
|
+
data-session-id="${(0,n.esc)(o.sessionId)}"
|
|
373
|
+
data-session-cwd="${(0,n.esc)(o.cwd||"")}"
|
|
374
|
+
data-session-config-dir="${(0,n.esc)(o.configDir||"")}"
|
|
375
|
+
data-session-agent="${(0,n.esc)(o.agent||"claude")}"
|
|
376
|
+
data-session-machine="${(0,n.esc)(o.machineId||"")}">
|
|
377
|
+
<span class="flex-shrink-0 mt-0.5">${rt(o.agent)}</span>
|
|
378
378
|
<span class="flex-1 min-w-0">
|
|
379
|
-
<span class="block text-xs font-semibold truncate leading-snug">${(0,n.esc)(Ae(
|
|
380
|
-
<span class="block text-[10px] text-base-content/40 truncate mt-0.5">${(0,n.esc)(
|
|
379
|
+
<span class="block text-xs font-semibold truncate leading-snug">${(0,n.esc)(Ae(o))}</span>
|
|
380
|
+
<span class="block text-[10px] text-base-content/40 truncate mt-0.5">${(0,n.esc)(o.projectName||lt(o.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>
|
|
@@ -386,11 +386,11 @@ ${t}`:"",s.length?s.join(`
|
|
|
386
386
|
</span>
|
|
387
387
|
</button>
|
|
388
388
|
<button type="button" class="recent-remove btn btn-ghost btn-xs min-h-7 h-7 w-7 px-0 flex-shrink-0 text-base-content/45 hover:text-error"
|
|
389
|
-
title="\u4ECE\u6700\u8FD1\u4F1A\u8BDD\u79FB\u9664" aria-label="\u4ECE\u6700\u8FD1\u4F1A\u8BDD\u79FB\u9664 ${(0,n.esc)(Ae(
|
|
390
|
-
data-dismiss-recent-session="${(0,n.esc)(
|
|
391
|
-
data-dismiss-recent-agent="${(0,n.esc)(
|
|
392
|
-
data-dismiss-recent-machine="${(0,n.esc)(
|
|
393
|
-
</div>`}).join("")}function
|
|
389
|
+
title="\u4ECE\u6700\u8FD1\u4F1A\u8BDD\u79FB\u9664" aria-label="\u4ECE\u6700\u8FD1\u4F1A\u8BDD\u79FB\u9664 ${(0,n.esc)(Ae(o))}"
|
|
390
|
+
data-dismiss-recent-session="${(0,n.esc)(o.sessionId)}"
|
|
391
|
+
data-dismiss-recent-agent="${(0,n.esc)(o.agent||"claude")}"
|
|
392
|
+
data-dismiss-recent-machine="${(0,n.esc)(o.machineId||"")}">\xD7</button>
|
|
393
|
+
</div>`}).join("")}function mi(e){wn=e}function da(e){gt+=e,gt<0?(gt=11,rs--):gt>11&&(gt=0,rs++)}var rs,gt,wn,ri,li,ua=H(()=>{M();C();Nt();rs=new Date().getFullYear(),gt=new Date().getMonth(),wn=null;ri=15,li="recentSessionsV1"});var yi={};Nn(yi,{loadAgentsMeta:()=>Yt,loadAllSessions:()=>fe,loadMemoryTab:()=>ps,loadWorkspaces:()=>Vt,mdToHtml:()=>vi,openMemoryFile:()=>ha,promptCustomModel:()=>ds,refreshEffortSelect:()=>cs,refreshModelSelect:()=>me,renderProjectGroups:()=>gi,renderSessionList:()=>fa,renderTimeline:()=>xi,runActivitySearch:()=>us,scheduleActivitySearch:()=>kn,sessionItemHtml:()=>pa,syncSidebarChrome:()=>ma});function hi(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}function tl(){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=hi(await Qn());if(t.length){let a=S.peek();if($.peek()&&a){let o=t.filter(i=>!i.machineId||i.machineId===a);T.value=o.length?o:t}else T.value=t}let s=async()=>{let a=tl(),o=await h("GET",a,void 0,void 0,{etag:!0});if(o===Bs)return T.peek();let i=hi(o);return T.value=i,Ro(i),i};if(e||!t.length)try{await s()}catch(a){if(!t.length){let o=(0,n.$)("session-list");o&&(o.innerHTML=`<div class="px-3 py-3 text-xs text-error">${(0,n.esc)(a.message)}</div>`)}}else s().catch(()=>{})}async function Vt({waitFresh:e=!0}={}){let t=await Bo();t&&(R.value=t);let s=async()=>{let a=await h("GET","/api/workspaces");R.value=a,hn(a)};if(e||!t)try{await s()}catch{}else s().catch(()=>{})}function pa(e,{showProject:t=!1}={}){let s=u.sessionId===e.sessionId&&(u.agent||w.peek())===(e.agent||"claude"),a=y.peek()?.[U(e.agent,e.sessionId,e.machineId)]||{},o=!!(a.title&&String(a.title).trim()),i=e.snippet&&B.peek()?e.snippet:Ae(e),r=!!a.favorite,c=!!a.hidden,f=!!(a.notes&&String(a.notes).trim()),l=Number(e.turnCount)||0,d=l>0&&l<=Ps,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>`:"",o?`<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)(a.notes)}">\u{1F4DD}</span>`:""].filter(Boolean).join(""),g=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>`:"",b=o?`${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)}"
|
|
@@ -413,8 +413,8 @@ ${t}`:"",s.length?s.join(`
|
|
|
413
413
|
data-rename-session-agent="${(0,n.esc)(e.agent||"claude")}"
|
|
414
414
|
data-rename-session-machine="${(0,n.esc)(e.machineId||"")}"
|
|
415
415
|
data-rename-session-display="${(0,n.esc)(e.display||"")}">
|
|
416
|
-
<div class="session-title-text text-[11px] leading-snug truncate flex-1 min-w-0 ${s?"text-primary font-medium":"text-base-content/85"} ${
|
|
417
|
-
title="${(0,n.esc)(
|
|
416
|
+
<div class="session-title-text text-[11px] leading-snug truncate flex-1 min-w-0 ${s?"text-primary font-medium":"text-base-content/85"} ${o?"session-title-renamed":""}"
|
|
417
|
+
title="${(0,n.esc)(b)}">${(0,n.esc)(i)}</div>
|
|
418
418
|
<button type="button" class="session-rename-btn flex-shrink-0"
|
|
419
419
|
data-rename-session="1"
|
|
420
420
|
title="Rename session">\u270E</button>
|
|
@@ -426,14 +426,14 @@ ${t}`:"",s.length?s.join(`
|
|
|
426
426
|
title="${c?"Unhide session":"Hide session"}">${c?"\u{1F441}":"\u{1F648}"}</button>
|
|
427
427
|
</div>
|
|
428
428
|
${p}
|
|
429
|
-
${m||
|
|
429
|
+
${m||g?`<div class="flex items-center gap-1 mt-0.5 flex-wrap">${g}${m}</div>`:""}
|
|
430
430
|
</div>
|
|
431
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 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
|
|
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 cs(){let e=(0,n.$)("sel-effort");if(!e)return;let t=w.peek()||"claude",s=E.peek(),a=nn(t,s),o=O.peek()||"";if(!o){let r=qe(t,s);r&&a.includes(r)&&(o=r,O.value=r)}let i=['<option value="">effort: off</option>'].concat(a.map(r=>`<option value="${(0,n.esc)(r)}" ${r===o?"selected":""}>${(0,n.esc)(r)}</option>`));if(e.innerHTML=i.join(""),o&&!a.includes(o)){let r=qe(t,s);r&&a.includes(r)?(O.value=r,e.value=r):(O.value="",e.value="")}else e.value=o}function me(){let e=(0,n.$)("sel-model");if(!e)return;let t=w.peek()||"claude",s=je(t),a=E.peek();if(a&&!s.some(i=>i.value===a)&&(s=[{value:a,label:`${a} \u2605`,custom:!0},...s]),e.innerHTML=s.map(i=>`<option value="${(0,n.esc)(i.value)}" ${i.value===a?"selected":""}>${(0,n.esc)(i.label)}</option>`).join(""),s.some(i=>i.value===a))e.value=a;else{let i=ye(t)||s[0]?.value;G(i),e.value=i,a=i}let o=(0,n.$)("sel-agent");o&&(o.value=t),cs()}function ds({editCurrent:e=!1}={}){let t=w.peek()||"claude",s=e&&E.peek()||"",a=e?`Edit model id for ${t}:`:`Add model id for ${t} (saved in this browser):`,o=window.prompt(a,s);if(o==null)return;let i=o.trim();i&&(e&&s&&s!==i&&Pn(t).includes(s)&&Rs(t,s),tn(t,i),G(i),me())}function gi(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=Lt.value,s=Et.value,
|
|
436
|
+
</div>`;let t=Lt.value,s=Et.value,a=!!B.value.trim(),o=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=a||r===o||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">
|
|
@@ -444,17 +444,17 @@ ${t}`:"",s.length?s.join(`
|
|
|
444
444
|
</div>
|
|
445
445
|
<div class="flex items-center gap-1.5 mt-0.5 pl-4">
|
|
446
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">${
|
|
447
|
+
<span class="flex items-center gap-0.5 flex-shrink-0">${ro(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>`,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>`:"",
|
|
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>`:"",g=c?`<div class="pb-1 border-b border-base-300/30">${p.map(b=>pa(b)).join("")}${m}</div>`:"";return d+g}).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
|
-
</div>`;let t=new Map;for(let s of e){let
|
|
453
|
+
</div>`;let t=new Map;for(let s of e){let o=(s.updatedAt?new Date(s.updatedAt):new Date).toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric"});t.has(o)||t.set(o,[]),t.get(o).push(s)}return[...t.entries()].map(([s,a])=>`
|
|
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
|
-
${
|
|
456
|
-
`).join("")}function
|
|
457
|
-
<div class="px-3 pb-4 flex flex-col gap-1">${
|
|
455
|
+
${a.map(o=>pa(o,{showProject:!0})).join("")}
|
|
456
|
+
`).join("")}function fa(){let e=Me.value,t=Array.isArray(We.value)?We.value:[],s=Array.isArray(st.value)?st.value:[];return e==="timeline"?xi(t):gi(s)}function ma(){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===ae.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=xe.peek(),a=Array.isArray(s?.results)?s.results:null,o=(B.peek()||"").trim();if(Te.peek())t.classList.remove("hidden"),t.textContent="Searching content\u2026";else if(o&&a)t.classList.remove("hidden"),t.textContent=`${a.length} hit${a.length===1?"":"s"} \xB7 ${le.peek()==="0"?"all time":le.peek()+"d"}${s.deep===!1?"":" (incl. content)"}`;else if(o)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 us(e){let t=(e||"").trim();if(!t){xe.value=null,Te.value=!1;return}Te.value=!0;try{let s=new URLSearchParams({q:t,days:le.peek()||"14",limit:"50",deep:"1"});ae.peek()&&ae.peek()!=="all"&&s.set("agent",ae.peek());let a=await h("GET",`/api/activity?${s}`);B.peek().trim()===t&&(xe.value={q:t.toLowerCase(),results:a.results||[],deep:!0})}catch(s){B.peek().trim()===t&&(xe.value={q:t.toLowerCase(),results:[],error:s.message})}finally{Te.value=!1}}function kn(e){clearTimeout(bi);let t=(e||"").trim();if(!t){xe.value=null,Te.value=!1;return}bi=setTimeout(()=>us(t),350)}function vi(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 ps(){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}),o=(await h("GET",`/api/sessions/${u.sessionId}/memory?${s}`)).files||[];if(!o.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 ${o.length} memory file${o.length===1?"":"s"} \xB7 click to open</div>
|
|
457
|
+
<div class="px-3 pb-4 flex flex-col gap-1">${o.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 ha(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 a=new URLSearchParams({agent:t||u.agent||w.peek()||"claude",file:e}),o=await h("GET",`/api/sessions/${u.sessionId}/memory/file?${a}`);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)(o.name)}</div><div class="px-3 py-2 md">${vi(o.content)}</div></div>`}catch(a){s.innerHTML=`<div class="mt-2 p-3 text-error text-xs">${(0,n.esc)(a?.message??String(a))}</div>`}}}var bi,wt=H(()=>{M();C();J();Zn();Nt();bi=null});function wi(e,t){fs=e||"",ms=t||""}async function ki(e){let t=(0,n.$)("project-notes-bar");if(t)try{let s=await h("GET",`/api/projects/notes?root=${encodeURIComponent(e)}`);fs=s.goal||"",ms=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=fs||"No goal yet \u2014 click Edit",s=ms||"";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 $i(){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)(fs)}">
|
|
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)(ms)}</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 $n(){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 a=It(s,t),o=(a.notes||"").trim(),i=!!a.favorite,r=!!a.hidden,f=(a.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)}"
|
|
@@ -498,16 +498,16 @@ ${t}`:"",s.length?s.join(`
|
|
|
498
498
|
data-hide-session-agent="${(0,n.esc)(s)}"
|
|
499
499
|
title="${r?"Unhide session":"Hide session"}">${r?"\u{1F441}":"\u{1F648}"}</button>
|
|
500
500
|
<span class="font-bold text-base-content/40 uppercase flex-shrink-0">Note:</span>
|
|
501
|
-
<span class="truncate text-base-content/70 ${
|
|
502
|
-
id="session-notes-text" title="${(0,n.esc)(
|
|
501
|
+
<span class="truncate text-base-content/70 ${o?"":"italic text-base-content/40"}"
|
|
502
|
+
id="session-notes-text" title="${(0,n.esc)(o||"Add a note for this session")}">${(0,n.esc)(o||"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 Si(){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
|
|
510
|
+
`;let a=(0,n.$)("session-notes-input");a?.focus(),a?.select()}function hs(){return{favorite:!1,notes:"",title:"",hidden:!1}}function bs(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 Li(e){return!e?.favorite&&!e?.hidden&&!(e?.notes||"").trim()&&!(e?.title||"").trim()}async function Ei(e,t,{machineId:s}={}){let a=s||u.machineId||null,o=U(t,e,a),i=y.peek()?.[o]||hs(),r=!i.favorite;y.value={...y.peek(),[o]:{...i,favorite:r,updatedAt:Date.now()}};try{let c=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,favorite:r,machineId:a||void 0},void 0,{machineId:a||void 0});y.value={...y.peek(),[o]:bs(i,{favorite:c.favorite??r,notes:c.notes,title:c.title,hidden:c.hidden})}}catch(c){y.value={...y.peek(),[o]:i},alert(`Favorite failed: ${c.message}`)}u.sessionId===e&&he()}async function Ii(e,t,{machineId:s}={}){if(!e)return!1;let a=s||u.machineId||null,o=U(t,e,a),i=y.peek()?.[o]||hs(),r=!i.hidden;y.value={...y.peek(),[o]:{...i,hidden:r,updatedAt:Date.now()}};try{let c=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,hidden:r,machineId:a||void 0},void 0,{machineId:a||void 0}),f=bs(i,{favorite:c.favorite,notes:c.notes,title:c.title,hidden:c.hidden??r});if(Li(f)){let l={...y.peek()};delete l[o],y.value=l}else y.value={...y.peek(),[o]:f}}catch(c){return y.value={...y.peek(),[o]:i},alert(`Hide failed: ${c.message}`),!1}return u.sessionId===e&&he(),!0}async function ba(e,t,s,{machineId:a}={}){let o=a||u.machineId||null,i=U(t,e,o),r=y.peek()?.[i]||hs();try{let c=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,notes:s,machineId:o||void 0},void 0,{machineId:o||void 0});y.value={...y.peek(),[i]:bs(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 nl(e,t,s,{machineId:a}={}){if(!e)return!1;let o=a||u.machineId||null,i=U(t,e,o),r=y.peek()?.[i]||hs(),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:o||void 0},void 0,{machineId:o||void 0}),l=bs(r,{favorite:f.favorite,notes:f.notes,title:f.title!==void 0?f.title:c,hidden:f.hidden});if(Li(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 ga({sessionId:e,agent:t="claude",machineId:s=null,fallbackDisplay:a="",mountEl:o}={}){if(!e||!o)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()||a||e.slice(0,8),c=o.innerHTML,f=o.className;o.classList.add("session-rename-active"),o.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,31 +515,31 @@ ${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=
|
|
518
|
+
autocomplete="off" spellcheck="false" />`;let l=o.querySelector(".session-rename-input");if(!l)return;let d=!1,p=async m=>{if(d)return;d=!0;let g=m?l.value:r;if(o.className=f,!m){o.innerHTML=c;return}await nl(e,t,g,{machineId:s}),document.querySelectorAll(".session-rename-input").forEach(b=>b.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 fs,ms,Sn=H(()=>{M();C();J();fs="",ms=""});var Ti={};Nn(Ti,{closeMachineMenu:()=>St,enterMachine:()=>va,hideMachinePicker:()=>xs,refreshMachinesList:()=>kt,renderMachineMenuList:()=>Ln,renderMachinePickerList:()=>gs,showMachinePicker:()=>$t,startMachinePolling:()=>xa,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(a=>{let o=a.online!==!1,i=[a.hostname,a.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
|
-
hover:border-primary hover:bg-primary/5 transition-colors ${
|
|
521
|
-
data-pick-machine="${(0,n.esc)(
|
|
520
|
+
hover:border-primary hover:bg-primary/5 transition-colors ${o?"":"opacity-50"}"
|
|
521
|
+
data-pick-machine="${(0,n.esc)(a.id)}" ${o?"":"disabled"}>
|
|
522
522
|
<div class="flex items-center gap-2">
|
|
523
|
-
<span class="w-2 h-2 rounded-full flex-shrink-0 ${
|
|
524
|
-
<span class="font-semibold text-sm font-mono">${(0,n.esc)(
|
|
523
|
+
<span class="w-2 h-2 rounded-full flex-shrink-0 ${o?"bg-success":"bg-error"}"></span>
|
|
524
|
+
<span class="font-semibold text-sm font-mono">${(0,n.esc)(a.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 $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(
|
|
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(a=>a.online!==!1).length;t.textContent=`${s} online`}}function xs(){(0,n.$)("machine-picker")?.classList.add("hidden"),ee(),ve.value=!0}function St(){(0,n.$)("machine-menu")?.classList.add("hidden")}function Ln(){let e=(0,n.$)("machine-menu-list"),t=(0,n.$)("machine-menu-empty");if(!e)return;let s=N.peek()||[],a=S.peek()||"";if(!s.length){e.innerHTML="",t?.classList.remove("hidden");return}t?.classList.add("hidden"),e.innerHTML=s.map(o=>{let i=o.online!==!1,r=o.id===a,c=[o.hostname,o.platform].filter(Boolean).join(" \xB7 "),f=o.connectedAt?new Date(o.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"}
|
|
531
531
|
${i?"":"opacity-50"}"
|
|
532
|
-
data-pick-machine="${(0,n.esc)(
|
|
532
|
+
data-pick-machine="${(0,n.esc)(o.id)}"
|
|
533
533
|
${i?"":"disabled"}>
|
|
534
534
|
<div class="flex items-center gap-1.5">
|
|
535
535
|
<span class="w-1.5 h-1.5 rounded-full flex-shrink-0 ${i?"bg-success":"bg-error"}"></span>
|
|
536
|
-
<span class="font-mono font-semibold truncate flex-1">${(0,n.esc)(
|
|
536
|
+
<span class="font-mono font-semibold truncate flex-1">${(0,n.esc)(o.id)}</span>
|
|
537
537
|
${r?'<span class="text-[9px] opacity-70">\u5F53\u524D</span>':""}
|
|
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 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
|
|
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 a=S.peek()||"",i=(N.peek()||[]).find(c=>c.id===a),r=i?i.online!==!1:!1;t&&(t.textContent=a||"\u9009\u62E9\u673A\u5668"),s&&(s.classList.toggle("bg-success",!!a&&r),s.classList.toggle("bg-warning",!!a&&!r),s.classList.toggle("bg-base-content/30",!a)),Ln()}function xa(){Mi||(Mi=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 va(e,{forceReload:t=!1}={}){if(!e)return;let s=S.peek(),a=s&&s!==e;if(Z(e),xs(),St(),Qe(),a||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(),za));i.value="",r.value="",c.value=""}catch{}if(a){let{goHome:i}=await Promise.resolve().then(()=>(In(),Ci));i()}}let o=(0,n.$)("topbar-project");o&&!v.peek()&&(o.textContent=`Machine \xB7 ${e}`),vn(),await Promise.all([fe(),Vt(),$n(),Yt().catch(()=>{})]),ve.value=!0}var Mi,En=H(()=>{M();C();J();wt();Sn();yn();jt();Mi=null});var Ci={};Nn(Ci,{goHome:()=>ws,openProject:()=>ya,resumeSession:()=>be,switchTab:()=>Fe});function ys(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 ya(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,D.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 a=(0,n.$)("git-root-input");a&&t&&(a.value=t),ys(e?.machineId||S.peek()||u.machineId),(0,n.$)("welcome").classList.add("hidden");let o=(0,n.$)("project-view");o.classList.remove("hidden"),o.style.display="flex",qt(),Bt({sessionId:null}),_e(),Fe("chat")}function ws(){Rt(),Ft(),Ot(),Ut(),v.value=null,q.value=null,z.value="",Q.value="",D.value="",W.value=null,u.sessionId=null,Bt({sessionId:null}),ys(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(xt()));let s=(0,n.$)("project-view");s&&(s.classList.add("hidden"),s.style.display="none"),Qs("/")}async function be(e,t,s,a,o,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&&(!o||k.machineId===o||!k.machineId)),l=ot(),d=l?.sessionId===e?l:null,p=a||f?.agent||d?.agent||"claude",m=o||f?.machineId||d?.machineId||S.peek()||null,g=t||f?.cwd||d?.cwd||null,b=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(()=>(En(),Ti)).then(({syncTopbarMachine:k})=>k()).catch(()=>{}),Promise.resolve().then(()=>(wt(),yi)).then(({loadAllSessions:k})=>k()).catch(()=>{})}u.sessionId=e,u.configDir=b,u.agent=p,we(p),me(),Bt({sessionId:e,agent:p,machineId:m});let P=g;Ai(P,m,e),_e(),P&&h("POST","/api/resolve-path",{path:P},void 0,{machineId:m||void 0}).then(k=>{u.sessionId!==e||!k?.path||k.path===P||(P=k.path,Ai(P,m,e),Fs({sessionId:e,cwd:P}))}).catch(()=>{}),qt(),Fe(r);{let k=T.peek();T.value=Array.isArray(k)?[...k]:[]}Fs({sessionId:e,cwd:P||g,configDir:b,agent:p,machineId:m,tab:r}),di({sessionId:e,cwd:P||g,configDir:b,agent:p,machineId:m,display:f?.display||d?.display||"",projectName:f?.projectName||d?.projectName||"",updatedAt:f?.updatedAt||d?.updatedAt||null});let Ze=F[p]||p,ge=`${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 Dn=Math.min(ue+Y,k.length);for(;ue<Dn;ue++){let L=k[ue],Na=A(L.ts??L.timestamp),As=L.type||(L.role?"text":null);if(As==="text"||L.role&&L.content!=null&&!L.name){(L.role==="assistant"||L.role==="user")&&pe();let Pa=typeof L.content=="string"?L.content:Array.isArray(L.content)?L.content.map(Vi=>Vi?.text||"").filter(Boolean).join(`
|
|
542
|
+
`):String(L.content??"");Pa&&pt(L.role==="user"?"user":"assistant",L.role==="user"?"You":Ze,Pa,{ts:Na})}else As==="tool_use"||L.name?Ks({name:L.name||"tool",input:L.input??L.arguments??{}},{ts:Na}):(As==="token_usage"||L.usage)&&(pe(),_t(L.usage||L))}if(ue<k.length){requestAnimationFrame(Qt);return}pe(),V&&Js(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=vs.get(ge);if(k&&k.msgs?.length&&Date.now()-k.at<sl){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,Dn=Array.isArray(Y)?{}:{truncated:Y?.truncated,total:Y?.total};ue.length?vs.set(ge,{msgs:ue,context:Qt,meta:Dn,at:Date.now()}):vs.delete(ge),et(ue,Qt,Dn)}catch(V){if(u.sessionId!==e)return;vs.delete(ge),(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(()=>{})),mn(),he()}function Ai(e,t,s){if(e){let a=e.split("/").filter(Boolean).pop()||e;(0,n.batch)(()=>{v.value={id:a,name:a,path:e,machineId:t},q.value=e,z.value=e,Q.value=e,D.value="",W.value=null}),(0,n.$)("topbar-project").textContent=t?`${e} @${t}`:e;let o=(0,n.$)("files-root-input");o&&(o.value=e);let i=(0,n.$)("git-root-input");i&&(i.value=e),ys(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 a=(0,n.$)("project-view");a&&(a.classList.remove("hidden"),a.style.display="flex",a.style.flexDirection="column",a.style.flex="1",a.style.minHeight="0"),ys(t)}}function Fe(e){j.value=e}var vs,sl,In=H(()=>{M();C();J();_n();Wt();Yn();wt();Sn();ua();vs=new Map,sl=180*1e3});C();J();M();C();J();var Ct=null;function Xa(){return window.matchMedia("(display-mode: standalone)").matches||window.navigator.standalone===!0||document.referrer.includes("android-app://")}function ir(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 rr(){if(!("serviceWorker"in navigator)||!window.isSecureContext)return!1;let e=location.hostname;return e==="localhost"||e==="127.0.0.1"||e==="::1"?!0:ir(e)?!1:location.protocol==="https:"}function Qa(){document.getElementById("btn-pwa-install")?.classList.remove("hidden")}function Za(){Xa()&&document.documentElement.classList.add("pwa-standalone"),window.addEventListener("beforeinstallprompt",s=>{s.preventDefault(),Ct=s,document.dispatchEvent(new CustomEvent("pwa-installable")),Qa()}),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(!Xa()&&(e||/Android/i.test(navigator.userAgent))&&requestAnimationFrame(()=>Qa()),!rr()){"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then(s=>s.forEach(a=>a.unregister())).catch(()=>{});return}let t=()=>{navigator.serviceWorker.register("/sw.js",{scope:"/"}).then(s=>{s.addEventListener("updatefound",()=>{let a=s.installing;a&&a.addEventListener("statechange",()=>{a.state==="installed"&&navigator.serviceWorker.controller&&console.info("[pwa] New version ready \u2014 reload to apply")})})}).catch(()=>{navigator.serviceWorker.getRegistrations().then(s=>s.forEach(a=>a.unregister())).catch(()=>{})})};document.readyState==="complete"?setTimeout(t,0):window.addEventListener("load",()=>setTimeout(t,0))}async function eo(){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();Yn();M();J();C();Zn();function Fo(){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,19 +558,19 @@ ${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>`),es(),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 es(){let e=(0,n.$)("ws-list");if(!e)return;let t=R.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",()=>
|
|
568
|
+
</div>`).join(""),e.querySelectorAll("[data-ws-delete]").forEach(s=>{s.addEventListener("click",()=>Br(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 a=await h("POST","/api/workspaces",{name:e,configDir:t});R.value=[...R.peek(),a],hn(R.peek()),(0,n.$)("ws-new-name").value="",(0,n.$)("ws-new-dir").value="",es()}catch(a){s.textContent=a.message,s.classList.remove("hidden")}}async function Br(e){try{await h("DELETE",`/api/workspaces/${e}`),R.value=R.peek().filter(t=>t.id!==e),hn(R.peek()),es()}catch(t){alert(t.message)}}function ea(){es(),(0,n.$)("modal-settings")?.showModal()}yn();qs();C();var ni=()=>`
|
|
569
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>
|
|
573
|
-
<p id="auth-subtitle" class="text-sm text-base-content/60 mb-1">Claude \xB7 Codex \xB7 Grok</p>
|
|
573
|
+
<p id="auth-subtitle" class="text-sm text-base-content/60 mb-1">Claude \xB7 Codex \xB7 Grok \xB7 Gemini</p>
|
|
574
574
|
<form id="auth-form" class="flex flex-col gap-3" autocomplete="on" action="#">
|
|
575
575
|
<label class="form-control">
|
|
576
576
|
<div class="label py-1"><span class="label-text text-xs uppercase tracking-wide">Username</span></div>
|
|
@@ -585,9 +585,9 @@ ${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>`,si=(e={})=>{let t=!!e.restoreSession,s=u.token?"":"hidden",a=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
|
-
<div id="app" class="${s} flex-col flex-1 overflow-hidden" style="${
|
|
590
|
+
<div id="app" class="${s} flex-col flex-1 overflow-hidden" style="${a}">
|
|
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">
|
|
592
592
|
<button id="hamburger" class="btn btn-ghost btn-sm px-2 text-lg" aria-label="\u6253\u5F00\u9879\u76EE\u4E0E\u4F1A\u8BDD\u4FA7\u680F" aria-controls="sidebar" aria-expanded="false">\u2630</button>
|
|
593
593
|
<span id="btn-home" class="font-semibold text-sm hidden sm:inline cursor-pointer hover:text-primary transition-colors select-none">\u{1F916} Agent UI</span>
|
|
@@ -626,6 +626,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
626
626
|
<span id="topbar-project" class="text-sm text-base-content/50 flex-1 truncate min-w-0">Select a session</span>
|
|
627
627
|
<span id="conn-dot" class="w-2 h-2 rounded-full bg-base-content/30 flex-shrink-0" title="\u8FDE\u63A5\u72B6\u6001"></span>
|
|
628
628
|
<div class="flex gap-2 topbar-actions">
|
|
629
|
+
<button id="btn-share-session" class="btn btn-ghost btn-xs border border-base-300" title="\u590D\u5236\u5F53\u524D\u4F1A\u8BDD\u5206\u4EAB\u94FE\u63A5">\u5206\u4EAB</button>
|
|
629
630
|
<button id="btn-refresh-conn" class="btn btn-ghost btn-xs border border-base-300" title="\u91CD\u65B0\u8FDE\u63A5\u5E76\u540C\u6B65">\u21BB</button>
|
|
630
631
|
<button id="btn-pwa-install" class="btn btn-ghost btn-xs border border-base-300 hidden" title="\u5B89\u88C5\u5230\u4E3B\u5C4F\u5E55">\u5B89\u88C5</button>
|
|
631
632
|
<button id="btn-meta-agent" class="btn btn-ghost btn-xs border border-primary/40 text-primary" title="Meta Agent \u2014 \u62A5\u544A / \u95EE\u7B54 / VLM"><span class="hidden sm:inline">\u2726 Agent</span><span class="sm:hidden">\u2726</span></button>
|
|
@@ -702,6 +703,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
702
703
|
<button data-agent-filter="claude" class="agent-pill">Claude</button>
|
|
703
704
|
<button data-agent-filter="codex" class="agent-pill">Codex</button>
|
|
704
705
|
<button data-agent-filter="grok" class="agent-pill">Grok</button>
|
|
706
|
+
<button data-agent-filter="gemini" class="agent-pill">Gemini</button>
|
|
705
707
|
<button id="btn-fav-filter" class="agent-pill" title="Show only favorites">\u2605 Fav</button>
|
|
706
708
|
<button id="btn-hidden-filter" class="agent-pill" title="Show only hidden sessions">\u{1F648} Hidden</button>
|
|
707
709
|
</div>
|
|
@@ -725,7 +727,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
725
727
|
<div id="welcome" class="${t?"hidden flex-1 flex-col items-center justify-start overflow-y-auto p-4 md:p-6 gap-5":"flex-1 flex flex-col items-center justify-start overflow-y-auto p-4 md:p-6 gap-5"}">
|
|
726
728
|
<div class="max-w-4xl w-full text-center flex flex-col items-center gap-2 mt-2 md:mt-4">
|
|
727
729
|
<h2 class="text-3xl font-extrabold tracking-tight bg-gradient-to-r from-primary to-accent bg-clip-text text-transparent select-none">\u{1F916} Agent UI</h2>
|
|
728
|
-
<p class="text-sm text-base-content/65 max-w-md">Claude \xB7 Codex \xB7 Grok \u2014 Select a session from the sidebar or click a day on the calendar to view activity.</p>
|
|
730
|
+
<p class="text-sm text-base-content/65 max-w-md">Claude \xB7 Codex \xB7 Grok \xB7 Gemini \u2014 Select a session from the sidebar or click a day on the calendar to view activity.</p>
|
|
729
731
|
<div class="flex gap-2 mt-0.5">
|
|
730
732
|
<button id="btn-new-session-welcome" class="btn btn-primary btn-sm shadow-md">\uFF0B New Session</button>
|
|
731
733
|
<button id="btn-meta-agent-welcome" class="btn btn-outline btn-primary btn-sm">\u2726 Meta Agent</button>
|
|
@@ -819,6 +821,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
819
821
|
<option value="claude">Claude</option>
|
|
820
822
|
<option value="codex">Codex</option>
|
|
821
823
|
<option value="grok">Grok</option>
|
|
824
|
+
<option value="gemini">Gemini</option>
|
|
822
825
|
</select>
|
|
823
826
|
<select id="sel-convert-agent" class="select select-xs select-bordered text-xs font-semibold" title="Convert session to another agent">
|
|
824
827
|
<option value="" disabled selected>Convert to...</option>
|
|
@@ -953,6 +956,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
953
956
|
<option value="claude">Claude Code</option>
|
|
954
957
|
<option value="codex">OpenAI Codex</option>
|
|
955
958
|
<option value="grok">Grok</option>
|
|
959
|
+
<option value="gemini">Google Gemini (agy)</option>
|
|
956
960
|
</select>
|
|
957
961
|
</label>
|
|
958
962
|
<label class="form-control" id="new-session-machine-wrap" style="display:none">
|
|
@@ -976,7 +980,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
976
980
|
</div>
|
|
977
981
|
</div>
|
|
978
982
|
<form method="dialog" class="modal-backdrop"><button>close</button></form>
|
|
979
|
-
</dialog>`};
|
|
983
|
+
</dialog>`};ua();wt();In();M();C();J();Zn();_n();wt();Sn();yn();In();En();jt();async function ks(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 a=e.deepLink||null,o=ot();if(!!(a?.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")||o?.machineId||"";c&&(Z(c),xs(),ve.value=!0,vn());let f=kt().then(p=>(Qe(),c&&!p.some(g=>g.id===c&&g.online!==!1)&&p.length&&(p.some(b=>b.id===c)||(Z(null),$t())),p));xa(),Qe();let l=Promise.all([fe({waitFresh:!1}),Vt({waitFresh:!1}),$n().catch(()=>{}),Yt().catch(()=>{})]);if(a?.id){let p=T.peek().find(m=>m.sessionId===a.id)||(o?.sessionId===a.id?o:null);await be(a.id,p?.cwd||null,p?.configDir||null,a.agent||p?.agent||null,a.machineId||p?.machineId||c||null,{tab:a.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}vn();let r=Promise.all([fe({waitFresh:!1}),Vt({waitFresh:!1}),$n().catch(()=>{}),Yt().catch(()=>{})]);if(a?.id){await Qn().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===a.id)||(o?.sessionId===a.id?o:null);await be(a.id,c?.cwd||null,c?.configDir||null,a.agent||c?.agent||null,null,{tab:a.tab||"chat"}),r.catch(()=>{});return}await r}Sn();En();M();C();J();Wt();wt();In();En();jt();function ji(){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 Mn(){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 Di(){window.innerWidth<=640&&Mn()}function Ni(){let e=(0,n.$)("sidebar-toggle"),t=(0,n.$)("sidebar");if(!e||!t)return;let s=localStorage.getItem("sidebarCollapsed")==="1",a=localStorage.getItem("sidebarWidth")||t.style.width||"280px",o=()=>{t.classList.toggle("desktop-collapsed",s),s?(t.style.width="0",t.style.minWidth="0",t.style.overflow="hidden"):(t.style.width=a,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")};o(),e.addEventListener("click",()=>{s=!s,s&&(a=t.style.width||a),localStorage.setItem("sidebarCollapsed",s?"1":"0"),o()})}function Pi(){let e=(0,n.$)("sidebar-resize"),t=(0,n.$)("sidebar"),s=!1;e.addEventListener("mousedown",a=>{s=!0,document.body.style.userSelect="none",document.body.style.cursor="col-resize",a.preventDefault()}),document.addEventListener("mousemove",a=>{if(!s)return;let o=Math.min(Math.max(a.clientX,160),520);t.style.width=o+"px",t.style.minWidth=""}),document.addEventListener("mouseup",()=>{if(!s)return;s=!1,document.body.style.userSelect="",document.body.style.cursor="";let a=Math.round(t.getBoundingClientRect().width);a>=160&&localStorage.setItem("sidebarWidth",`${a}px`)})}function wa(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(o=>{o.textContent=s});let a=document.getElementById("hljs-theme");if(a||(a=document.querySelector('link[href*="highlight"][href*="styles"]'),a&&(a.id="hljs-theme")),a){let o=e==="dark"||e==="night"||e==="black";a.href=o?"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 ka(){let e=document.documentElement.getAttribute("data-theme")||"dark";wa(e==="dark"?"light":"dark")}function $a(){let e=(0,n.$)("new-session-agent");e&&(e.value=w.peek()||"claude");let t=(0,n.$)("new-session-workspace");if(t){let o=R.peek();t.innerHTML=o.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"),a=(0,n.$)("new-session-machine");if(s&&a)if($.peek()){s.style.display="";let o=N.peek()||[],i=S.peek()||"";a.innerHTML=o.length?o.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&&(a.value=i),a.disabled=!0}else s.style.display="none",a&&(a.disabled=!1);Sa(),(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 Sa(){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 La(){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,a=(0,n.$)("new-session-error");if(a.classList.add("hidden"),!e){a.textContent="Working directory is required",a.classList.remove("hidden");return}if($.peek()){let o=S.peek()||(0,n.$)("new-session-machine")?.value||N.peek()?.[0]?.id;if(!o){a.textContent="\u8BF7\u5148\u9009\u62E9\u4E00\u53F0\u673A\u5668",a.classList.remove("hidden"),$t();return}Z(o)}try{let o=await h("POST","/api/resolve-path",{path:e});if(!o.isDir)throw new Error("Path is not a directory");(0,n.$)("modal-new-session").close();let i=o.path.split("/").filter(Boolean).pop()||o.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:o.path,machineId:S.peek()||u.machineId},q.value=o.path,z.value=o.path,Q.value=o.path,D.value="",W.value=null}),(0,n.$)("topbar-project").textContent=o.path;let r=(0,n.$)("files-root-input");r&&(r.value=o.path);let c=(0,n.$)("git-root-input");c&&(c.value=o.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}),_e(),Fe("chat"),x(`New ${F[t]||t} session \xB7 ${o.path}`)}catch(o){a.textContent=o.message,a.classList.remove("hidden")}}function al(){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
984
|
<li>\u70B9\u5E95\u90E8\u5206\u4EAB\u6309\u94AE <strong>\u5206\u4EAB</strong>\uFF08\u65B9\u6846+\u5411\u4E0A\u7BAD\u5934\uFF09</li>
|
|
981
985
|
<li>\u4E0B\u6ED1\u627E\u5230\u5E76\u70B9 <strong>\u6DFB\u52A0\u5230\u4E3B\u5C4F\u5E55</strong></li>
|
|
982
986
|
<li>\u786E\u8BA4\u540D\u79F0\u540E\u70B9 <strong>\u6DFB\u52A0</strong></li>
|
|
@@ -987,7 +991,7 @@ ${t}`:"",s.length?s.join(`
|
|
|
987
991
|
<li>\u9009\u62E9 <strong>\u5B89\u88C5\u5E94\u7528</strong> \u6216 <strong>\u6DFB\u52A0\u5230\u4E3B\u5C4F\u5E55</strong></li>
|
|
988
992
|
</ol>
|
|
989
993
|
<p class="text-xs text-base-content/50 mt-3">\u82E5\u83DC\u5355\u91CC\u6CA1\u6709\u8BE5\u9879\uFF1A\u8BF7\u7528 <strong>Chrome</strong> \u6253\u5F00\uFF0C\u5E76\u5148\u63A5\u53D7\u672C\u7AD9\u8BC1\u4E66\u63D0\u793A\u3002\u81EA\u7B7E HTTPS \u4E0B\u90E8\u5206\u673A\u578B\u4E0D\u5F39\u51FA\u4E00\u952E\u5B89\u88C5\u3002</p>`:s=`<p class="text-sm text-base-content/80">\u8BF7\u5728\u6D4F\u89C8\u5668\u83DC\u5355\u4E2D\u9009\u62E9 <strong>\u5B89\u88C5\u5E94\u7528 / \u5B89\u88C5\u7F51\u9875\u5E94\u7528 / \u6DFB\u52A0\u5230\u4E3B\u5C4F\u5E55</strong>\u3002</p>
|
|
990
|
-
<p class="text-xs text-base-content/50 mt-3">Chrome / Edge \u5730\u5740\u680F\u53F3\u4FA7\u6709\u65F6\u4E5F\u4F1A\u51FA\u73B0\u5B89\u88C5\u56FE\u6807\u3002</p>`;let
|
|
994
|
+
<p class="text-xs text-base-content/50 mt-3">Chrome / Edge \u5730\u5740\u680F\u53F3\u4FA7\u6709\u65F6\u4E5F\u4F1A\u51FA\u73B0\u5B89\u88C5\u56FE\u6807\u3002</p>`;let a=document.getElementById("modal-pwa-install");a||(a=document.createElement("dialog"),a.id="modal-pwa-install",a.className="modal",document.body.appendChild(a)),a.innerHTML=`
|
|
991
995
|
<div class="modal-box max-w-sm">
|
|
992
996
|
<h3 class="font-bold text-base mb-3">\u5B89\u88C5\u5230\u4E3B\u5C4F\u5E55</h3>
|
|
993
997
|
${s}
|
|
@@ -995,15 +999,15 @@ ${t}`:"",s.length?s.join(`
|
|
|
995
999
|
<form method="dialog"><button class="btn btn-sm">\u77E5\u9053\u4E86</button></form>
|
|
996
1000
|
</div>
|
|
997
1001
|
</div>
|
|
998
|
-
<form method="dialog" class="modal-backdrop"><button>close</button></form>`,
|
|
1002
|
+
<form method="dialog" class="modal-backdrop"><button>close</button></form>`,a.showModal()}async function Ia(){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"),a,o=new AbortController,i=setTimeout(()=>o.abort(),8e3);try{a=await h("GET","/api/auth/status",void 0,o.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)}a.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 Ea(){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 a=await h("POST",`/api/auth/${(0,n.$)("auth-btn").dataset.mode||"login"}`,{username:e,password:t});u.token=a.token,localStorage.setItem("token",a.token),ks()}catch(a){s.textContent=a.message,s.classList.remove("hidden")}}function Ma(){return u.token?/^#\/session\//.test(location.hash||""):!1}function Hi(e={}){if(wa(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??Ma(),s=document.getElementById("root");if(s.style.cssText="display:flex;flex-direction:column;flex:1;height:100%",s.innerHTML=ni()+si({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=R.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
1003
|
${(m.id===null?!p:p===m.configDir)?"border-primary text-primary":"border-transparent text-base-content/50 hover:text-base-content"}"
|
|
1000
1004
|
data-ws-tab="${(0,n.esc)(m.configDir||"")}">
|
|
1001
1005
|
${(0,n.esc)(m.name)}
|
|
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`
|
|
1006
|
+
</button>`).join("")}),(0,n.effect)(()=>{We.value,st.value,Me.value,Te.value,xe.value,y.value;let l=(0,n.$)("session-list");l&&(l.querySelector(".session-rename-input")||(l.innerHTML=fa(),ma()))}),(0,n.effect)(()=>{T.value,ae.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)ki(l.path);else{let d=(0,n.$)("project-notes-bar");d&&(d.style.display="none")}}),(0,n.watch)(j,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 g=p===l;m.classList.toggle("hidden",!g),g?(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"&&ps(),l==="shell"&&requestAnimationFrame(()=>{document.dispatchEvent(new CustomEvent("shell-tab-shown"))}),ee()}),Pi(),Ni(),ho({openSession:be});let a=null;document.addEventListener("sessions-changed",()=>{a&&clearTimeout(a),a=setTimeout(()=>{a=null,fe({waitFresh:!1})},1200)}),document.addEventListener("router:home",ws),document.addEventListener("router:session",async({detail:{id:l,tab:d,machineId:p,agent:m}})=>{let g=T.peek().find(P=>P.sessionId===l),b=ot();await be(l,g?.cwd||(b?.sessionId===l?b.cwd:null)||null,g?.configDir||(b?.sessionId===l?b.configDir:null)||null,m||g?.agent||(b?.sessionId===l?b.agent:null)||null,p||g?.machineId||(b?.sessionId===l?b.machineId:null)||null,{tab:d||"chat"})}),n.delegate.on("click","#btn-home",ws),n.delegate.on("click","#btn-share-session",async(l,d)=>{let p=_o();if(p)try{await navigator.clipboard.writeText(p),d.textContent="\u5DF2\u590D\u5236",setTimeout(()=>{d.textContent="\u5206\u4EAB"},1400)}catch{window.prompt("\u590D\u5236\u4F1A\u8BDD\u94FE\u63A5\uFF1A",p)}}),n.delegate.on("click","#auth-btn",Ea),n.delegate.on("submit","#auth-form",l=>{l.preventDefault(),Ea()}),n.delegate.on("keydown","#auth-username, #auth-password",l=>{l.key==="Enter"&&Ea()}),n.delegate.on("click","#hamburger",()=>(0,n.$)("sidebar").classList.contains("open")?Mn():ji()),n.delegate.on("click","#sidebar-overlay",Mn),document.addEventListener("keydown",l=>{l.key==="Escape"&&window.innerWidth<=640&&(0,n.$)("sidebar")?.classList.contains("open")&&(l.preventDefault(),Mn())}),n.delegate.on("input","#session-search",(l,d)=>{B.value=d.value,kn(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(),B.peek().trim()&&us(B.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)=>{ae.value=d.dataset.agentFilter,localStorage.setItem("agentFilter",d.dataset.agentFilter),B.peek().trim()&&kn(B.peek())}),n.delegate.on("change","#time-range",(l,d)=>{le.value=d.value,localStorage.setItem("timeRange",d.value),fe({waitFresh:!0}),B.peek().trim()&&kn(B.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;ya({id:m,name:m,path:p}),x(`Project \xB7 ${p}`)}),n.delegate.on("click","#btn-pwa-install",async()=>{await eo()||al()}),document.addEventListener("pwa-installable",()=>{document.getElementById("btn-pwa-install")?.classList.remove("hidden")}),n.delegate.on("click","#btn-settings",ea),n.delegate.on("click","#btn-meta-agent",()=>Vo()),n.delegate.on("click","#btn-meta-agent-welcome",()=>sa("chat")),n.delegate.on("click","#btn-theme",ka),n.delegate.on("click","[data-sidebar-action]",(l,d)=>{let p=d.dataset.sidebarAction;p==="new"&&$a(),p==="theme"&&ka(),p==="settings"&&ea(),p==="logout"&&(u.token=null,localStorage.removeItem("token"),Z(null),ve.value=!1,location.reload())}),n.delegate.on("click","#btn-cal-prev",()=>{da(-1),vt(xt())}),n.delegate.on("click","#btn-cal-next",()=>{da(1),vt(xt())}),n.delegate.on("click","[data-cal-date]",(l,d)=>{mi(d.dataset.calDate),vt(xt())}),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),Di())}),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&&ga({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;ga({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,g=d.querySelector("span")?.textContent.trim()==="\u25BE",b=new Set(Lt.peek()),P=new Set(Et.peek());g?(b.delete(p),P.add(p)):(b.add(p),P.delete(p)),(0,n.batch)(()=>{Lt.value=b,Et.value=P})}),n.delegate.on("click","#memory-refresh",ps),n.delegate.on("click","[data-memory-file]",l=>ha(l.dataset.memoryFile,l.dataset.memoryAgent)),n.delegate.on("click","[data-tab]",(l,d)=>Fe(d.dataset.tab));let o=async(l,d)=>{let p=(0,n.$)(l),m=p?.value.trim();if(!m){d.value="";return}try{let g=await h("POST","/api/resolve-path",{path:m});if(g.isDir===!1)throw new Error("Path is not a directory on the target machine");d.value=g.path,p.value=g.path;let b=v.peek();b&&(v.value={...b,path:g.path})}catch(g){p.style.color="oklch(var(--er))",p.title=g.message,setTimeout(()=>{p.style.color="",p.title=""},2e3)}};n.delegate.on("click","#files-root-btn",()=>o("files-root-input",z)),n.delegate.on("click","#git-root-btn",()=>o("git-root-input",Q)),n.delegate.on("keydown","#files-root-input",l=>{l.key==="Enter"&&o("files-root-input",z)}),n.delegate.on("keydown","#git-root-input",l=>{l.key==="Enter"&&o("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 ${F[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 g=u.agent||w.peek()||"claude";if(g===p){alert("Cannot convert to the same agent."),d.value="";return}d.disabled=!0,x(`Converting session ${m.slice(0,8)} from ${g} to ${p}...`);try{let b=await h("POST",`/api/sessions/${m}/convert`,{targetAgent:p,sourceAgent:g});b&&b.success?(x(`\u2713 Converted successfully. New session: ${b.targetSessionId.slice(0,8)}`),await fe(),await be(b.targetSessionId,v.peek()?.path||null,null,b.targetAgent),mn()):x("Failed to convert session.")}catch(b){x(`Error converting session: ${b.message}`),alert(`Error converting session: ${b.message}`)}finally{d.disabled=!1,d.value=""}}),n.delegate.on("change","#sel-model",(l,d)=>{G(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)=>{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",$a),n.delegate.on("click","#new-session-cancel",()=>(0,n.$)("modal-new-session").close()),n.delegate.on("click","#new-session-start",La),n.delegate.on("change","#new-session-agent",Sa),n.delegate.on("keydown","#new-session-path",l=>{l.key==="Enter"&&La()}),n.delegate.on("click","#send-btn",fn),n.delegate.on("click","#stop-btn",Io),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 va(p,{forceReload:!0}),Rn()});let i=async()=>{let l=(0,n.$)("machine-picker-status");if(l&&(l.textContent="\u5237\u65B0\u4E2D\u2026"),await kt(),gs(),Ln(),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(),Ln(),d.classList.remove("hidden")):d.classList.add("hidden"))}),n.delegate.on("click","#btn-recent-sessions",l=>{l.preventDefault(),l.stopPropagation(),St(),dt(),fi();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"),g=l.target;if(p&&!p.classList.contains("hidden")){if(p.contains(g)||m?.contains(g))return;yt(),m?.setAttribute("aria-expanded","false")}}),n.delegate.on("click","#btn-notifications",l=>{l.preventDefault(),l.stopPropagation(),St(),yt(),fo()}),window.addEventListener("resize",()=>{(0,n.$)("recent-menu")&&!(0,n.$)("recent-menu").classList.contains("hidden")&&la()}),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(),ui({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",()=>{$i()}),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});wi(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)),Ei(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)),Ii(d.dataset.hideSessionId,d.dataset.hideSessionAgent||"claude",{machineId:p||null})}),n.delegate.on("click","#btn-edit-session-notes, #session-notes-text",()=>{Si()}),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 ba(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 ba(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&&Rn()}),(0,n.$)("sel-permission").value=re.peek(),Vn();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===ae.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 il(e){let t=(e||"").split("/").pop()||"",s=t.lastIndexOf(".");return s>=0?t.slice(s+1).toLowerCase():""}function _i(e){let t=il(e);return t==="docx"||t==="pptx"||t==="xlsx"||t==="pdf"?t:null}function rl(e){return e==null?"":e>1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:e>1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function ll(e){let t=atob(e),s=new Uint8Array(t.length);for(let a=0;a<t.length;a++)s[a]=t.charCodeAt(a);return s.buffer}var Ta=new Map;function $s(e){if(Ta.has(e))return Ta.get(e);let t=new Promise((s,a)=>{let o=document.querySelector(`script[data-src="${e}"]`);if(o){if(o.dataset.loaded==="1")return s();o.addEventListener("load",()=>s()),o.addEventListener("error",()=>a(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=()=>a(new Error(`Failed to load ${e}`)),document.head.appendChild(i)});return Ta.set(e,t),t}function cl(e){let s=((e||"").split("/").pop()||"").toLowerCase(),a={dockerfile:"dockerfile",makefile:"makefile",gemfile:"ruby",rakefile:"ruby",procfile:"yaml","cmakelists.txt":"cmake"};if(a[s])return a[s];let o=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"}[o]||""}function dl(e){!e||typeof hljs>"u"||e.querySelectorAll("pre code.file-preview-code").forEach(t=>{try{delete t.dataset.highlighted,hljs.highlightElement(t)}catch{}})}function Tn(e,t,s){let a=rl(t);return`
|
|
1003
1007
|
<div class="flex items-center gap-2 px-4 py-1.5 border-b border-base-300 flex-shrink-0 bg-base-200">
|
|
1004
|
-
<span class="text-xs text-base-content/40 flex-1 truncate">${(0,n.esc)(e)} \xB7 ${(0,n.esc)(
|
|
1008
|
+
<span class="text-xs text-base-content/40 flex-1 truncate">${(0,n.esc)(e)} \xB7 ${(0,n.esc)(a)}${s?` \xB7 <span class="text-primary/70">${(0,n.esc)(s)}</span>`:""}</span>
|
|
1005
1009
|
<button type="button" class="btn btn-ghost btn-xs" data-download-path="${(0,n.esc)(e)}">\u2193 Download</button>
|
|
1006
|
-
</div>`}function
|
|
1010
|
+
</div>`}function ul(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
1011
|
<div class="flex items-center gap-2 px-4 py-1.5 hover:bg-base-300 group"
|
|
1008
1012
|
${t.isDir?`data-dir-path="${(0,n.esc)(t.path)}"`:`data-file-path="${(0,n.esc)(t.path)}"`}>
|
|
1009
1013
|
<span class="cursor-pointer flex-shrink-0">${t.isDir?"\u{1F4C1}":ol(t.name)}</span>
|
|
@@ -1013,33 +1017,33 @@ ${t}`:"",s.length?s.join(`
|
|
|
1013
1017
|
data-download-path="${(0,n.esc)(t.path)}" title="Download" aria-label="Download">\u2193</button>
|
|
1014
1018
|
<button type="button" class="file-row-action btn btn-ghost btn-xs px-1.5 text-error/60 hover:text-error"
|
|
1015
1019
|
data-delete-path="${(0,n.esc)(t.path)}" title="Delete" aria-label="Delete">\u2715</button>`}
|
|
1016
|
-
</div>`).join(""))}function
|
|
1020
|
+
</div>`).join(""))}function pl(e,t,s){let a=/[\x00-\x08\x0e-\x1f]/.test(t.slice(0,512)),o=cl(e),i=o?`language-${(0,n.esc)(o)}`:"",r=a?`<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 Tn(e,s,a?"binary":o||"text")+r}async function fl(e){if(await $s("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 ml(e){if(await $s("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 a=s.map((i,r)=>`<button type="button" class="office-sheet-tab${r===0?" active":""}" data-sheet-idx="${r}">${(0,n.esc)(i)}</button>`).join(""),o=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
1021
|
<div class="office-preview office-xlsx flex flex-col flex-1 min-h-0 overflow-hidden">
|
|
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">${
|
|
1019
|
-
<div class="office-sheet-body flex-1 overflow-auto p-2">${
|
|
1020
|
-
</div>`}function
|
|
1022
|
+
<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">${a}</div>
|
|
1023
|
+
<div class="office-sheet-body flex-1 overflow-auto p-2">${o}</div>
|
|
1024
|
+
</div>`}function hl(e){let t=[],s=/<a:p[\s>][\s\S]*?<\/a:p>/g,a=/<a:t(?:\s[^>]*)?>([\s\S]*?)<\/a:t>/g,o,i=e.match(s)||[e];for(let r of i){let c=[];for(a.lastIndex=0;(o=a.exec(r))!==null;){let f=o[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 bl(e){if(await $s("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(o=>/^ppt\/slides\/slide\d+\.xml$/i.test(o)).sort((o,i)=>{let r=parseInt(o.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 a=[];for(let o=0;o<s.length;o++){let i=await t.files[s[o]].async("string"),r=hl(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>';a.push(`
|
|
1021
1025
|
<article class="office-slide-card">
|
|
1022
|
-
<header class="office-slide-num">Slide ${
|
|
1026
|
+
<header class="office-slide-num">Slide ${o+1}</header>
|
|
1023
1027
|
<div class="office-slide-body">${c}</div>
|
|
1024
1028
|
</article>`)}return`
|
|
1025
1029
|
<div class="office-preview office-pptx overflow-auto flex-1 p-3 space-y-3">
|
|
1026
1030
|
<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
|
-
${
|
|
1028
|
-
</div>`}async function
|
|
1031
|
+
${a.join("")}
|
|
1032
|
+
</div>`}async function gl(){if(await $s("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 gl()).getDocument({data:e}).promise,a=s.numPages,o=Math.min(a,40),i=[];for(let c=1;c<=o;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
1033
|
<figure class="office-pdf-figure">
|
|
1030
|
-
<figcaption class="office-pdf-cap">Page ${c} / ${
|
|
1034
|
+
<figcaption class="office-pdf-cap">Page ${c} / ${a}</figcaption>
|
|
1031
1035
|
${m.outerHTML}
|
|
1032
|
-
</figure>`)}let r=o
|
|
1036
|
+
</figure>`)}let r=a>o?`<p class="text-xs text-base-content/50 px-2">Showing first ${o} of ${a} pages \u2014 download for full file.</p>`:"";return`
|
|
1033
1037
|
<div class="office-preview office-pdf overflow-auto flex-1 p-3 space-y-3">
|
|
1034
|
-
<p class="text-xs text-base-content/50 px-1">PDF preview \xB7 ${
|
|
1038
|
+
<p class="text-xs text-base-content/50 px-1">PDF preview \xB7 ${a} page(s)</p>
|
|
1035
1039
|
${r}
|
|
1036
1040
|
${i.join("")}
|
|
1037
|
-
</div>`}async function
|
|
1038
|
-
${
|
|
1041
|
+
</div>`}async function vl(e,t,s){let a=_i(e),o={docx:"Word",pptx:"PowerPoint",xlsx:"Excel",pdf:"PDF"},i=ll(t),r;if(a==="docx")r=await fl(i);else if(a==="xlsx")r=await ml(i);else if(a==="pptx")r=await bl(i);else if(a==="pdf")r=await xl(i);else throw new Error("Unsupported office type");return Tn(e,s,o[a]||a)+r}function yl(e,t){let s=e?e.split("/"):[],a=t?s.slice(0,-1):s,o='<span class="cursor-pointer text-primary hover:underline" data-dir-path="">root</span>',i="";for(let r of a)i=i?`${i}/${r}`:r,o+=` <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&&(o+=` <span class="text-base-content/40">/</span> <span>${(0,n.esc)(s.at(-1))}</span>`),o}function wl(){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 a=D.peek(),o=e?.id||"_",i=[...s.files],r=!1;for(let c of i){let f=a?`${a}/${c.name}`:c.name,l=`/api/projects/${o}/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=D.peek();D.value=c+"\0",D.value=c}}),s.click()}async function kl(e,t){let s=z.peek()||e?.path||"";if(!s){alert("No path selected \u2014 set root first");return}let a=e?.id||"_",o=(t||"").split("/").pop()||"download",i=new URLSearchParams({root:s,path:t,download:"true"}),r=`/api/projects/${a}/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=o,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/${a}/file?${Ya({root:s,path:t,download:"true"})}`,l=document.createElement("a");l.href=f,l.download=o,l.rel="noopener",l.target="_blank",document.body.appendChild(l),l.click(),l.remove()}catch{alert(`Download failed: ${c.message}`)}}}async function $l(e,t){if(!confirm(`Delete "${t.split("/").pop()}"?`))return;let s=z.peek()||e?.path||"",a=e?.id||"_";try{await h("DELETE",`/api/projects/${a}/file?root=${encodeURIComponent(s)}&path=${encodeURIComponent(t)}`),D.value=D.peek()+" ",D.value=D.peek().trimEnd()}catch(o){alert(`Delete failed: ${o.message}`)}}async function Sl(e,t,s,a){let o=s.size??(typeof s.content=="string"?s.content.length:0),i=_i(t);if(i&&s.encoding==="base64"){e.innerHTML=Tn(t,o,i)+`<div class="p-4 text-xs text-base-content/40">Parsing ${i.toUpperCase()}\u2026</div>`;try{let r=await vl(t,s.content,o);if(a.aborted)return;e.innerHTML=r}catch(r){if(a.aborted)return;e.innerHTML=Tn(t,o,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=Tn(t,o,"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=pl(t,s.content||"",o),dl(e)}function Ri(){(0,n.effect)(()=>{let e=(0,n.$)("files-breadcrumb");if(!e)return;let t=W.value!==null;e.innerHTML=`
|
|
1042
|
+
${yl(W.value??D.value,t)}
|
|
1039
1043
|
<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=
|
|
1044
|
+
${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=j.value,s=v.value,a=(z.value||s?.path||"").trim(),o=W.value,i=D.value,r=(0,n.$)("files-area");if(!r||t!=="files")return;if(!a){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(o!==null){let d=await h("GET",`/api/projects/${c}/file?root=${encodeURIComponent(a)}&path=${encodeURIComponent(o)}`,void 0,e);e.aborted||await Sl(r,o,d,e);return}let f=await h("GET",`/api/projects/${c}/files?root=${encodeURIComponent(a)}&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=ul(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,D.value=t.dataset.dirPath}),n.delegate.on("click","[data-file-path]",(e,t)=>{W.value=t.dataset.filePath}),n.delegate.on("click","#btn-upload",()=>wl()),n.delegate.on("click","[data-download-path]",(e,t)=>{e.preventDefault(),e.stopPropagation();let s=t.dataset.downloadPath;s&&kl(v.peek(),s)}),n.delegate.on("click","[data-delete-path]",(e,t)=>{e.preventDefault(),e.stopPropagation();let s=t.dataset.deletePath;s&&$l(v.peek(),s)}),n.delegate.on("click",".office-sheet-tab",(e,t)=>{let s=t.closest(".office-xlsx");if(!s)return;let a=t.dataset.sheetIdx;s.querySelectorAll(".office-sheet-tab").forEach(o=>o.classList.toggle("active",o===t)),s.querySelectorAll(".office-sheet-pane").forEach(o=>{o.classList.toggle("hidden",o.dataset.sheetPane!==a)})})}M();C();J();var Bi=(0,n.signal)(!1);function Ll(e){return e?e.split(`
|
|
1041
1045
|
`).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
|
|
1046
|
+
`):'<span class="text-base-content/40">No commits</span>'}function El(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
1047
|
<div class="px-4 py-2 text-xs text-base-content/50 border-b border-base-300">
|
|
1044
1048
|
Branch: <span class="text-success font-semibold">${(0,n.esc)(e.branch)}</span>
|
|
1045
1049
|
</div>
|
|
@@ -1065,16 +1069,16 @@ ${t}`:"",s.length?s.join(`
|
|
|
1065
1069
|
<span class="text-base-content/40">Loading\u2026</span>
|
|
1066
1070
|
</div>
|
|
1067
1071
|
</div>
|
|
1068
|
-
</div>`}function
|
|
1072
|
+
</div>`}function Il(e){return e.split(`
|
|
1069
1073
|
`).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
|
-
`),
|
|
1074
|
+
`)}function Fi(){(0,n.asyncEffect)(async e=>{let t=j.value,s=v.value,a=Q.value||s?.path,o=(0,n.$)("git-area");if(!o||t!=="git")return;if(!a){o.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||"_";o.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(a)}`,void 0,e);e.aborted||(o.innerHTML=El(r))}catch(r){!e.aborted&&r?.name!=="AbortError"&&(o.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,a=Bi.value,o=(0,n.$)("diff-content");if(!o||!s)return;let i=t?.id||"_";try{let r=await h("GET",`/api/projects/${i}/git/diff?root=${encodeURIComponent(s)}${a?"&staged=true":""}`,void 0,e);e.aborted||(o.innerHTML=r?.diff?Il(r.diff):'<span class="text-base-content/40">No changes</span>')}catch(r){!e.aborted&&r?.name!=="AbortError"&&(o.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";Bi.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||Ml()})}function Ml(){let e=v.peek(),t=Q.peek()||e?.path,s=(0,n.$)("git-graph-content");if(!t||!s)return;let a=e?.id||"_";s.innerHTML='<span class="text-base-content/40">Loading\u2026</span>',h("GET",`/api/projects/${a}/git/log?root=${encodeURIComponent(t)}`).then(o=>{s.innerHTML=o.graph?Ll(o.graph):'<span class="text-base-content/40">No commits</span>'}).catch(o=>{s.innerHTML=`<span class="text-error">${(0,n.esc)(o.message)}</span>`})}M();C();var se=null,I=null,Ls=null,jn=!1,Es=null,Wi=null,Cn=0,An=null,Ca=!1,Ui=!1,Oi={"ctrl-c":"",escape:"\x1B",tab:" ",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C"};function Aa(e){se&&se.readyState===WebSocket.OPEN&&se.send(JSON.stringify({type:"input",data:e}))}function Tl(){return window.matchMedia("(max-width: 640px), (hover: none) and (pointer: coarse)").matches}function Is(){if(Tl()){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 Gi(){if(I)return;let e=(0,n.$)("terminal-container");if(!e)return;if(typeof Terminal>"u"){setTimeout(Gi,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"&&(Ls=new FitAddon.FitAddon,I.loadAddon(Ls)),I.open(e),Ss(),I.onData(s=>{Aa(s)}),e.addEventListener("pointerdown",()=>Is(),{passive:!0}),e.addEventListener("touchend",()=>Is(),{passive:!0}),window.addEventListener("resize",()=>{Ss(),Ms()});let t=window.visualViewport;if(t){let s=0,a=()=>{s&&cancelAnimationFrame(s),s=requestAnimationFrame(()=>{s=0,j.peek()==="shell"&&(Ss(),Ms())})};t.addEventListener("resize",a),t.addEventListener("scroll",a)}}function Ss(){try{Ls&&I&&Ls.fit()}catch{}}function Ms(){se&&se.readyState===WebSocket.OPEN&&I&&se.send(JSON.stringify({type:"resize",cols:I.cols,rows:I.rows}))}function zi(){return u.machineId||S.peek()||null}function Ts(e){An&&(clearTimeout(An),An=null),Ca=!0;let t=++Cn;if(se){try{se.close()}catch{}se=null}jn=!1;let s=location.protocol==="https:"?"wss":"ws",a=I?I.cols:80,o=I?I.rows:24,i=new URLSearchParams;u.token&&i.set("token",u.token),e&&i.set("cwd",e),i.set("cols",String(a)),i.set("rows",String(o));let r=zi();$.peek()&&r&&i.set("machine",r),Es=e||null,Wi=r,se=new WebSocket(`${s}://${location.host}/ws/shell?${i}`),se.addEventListener("open",()=>{t===Cn&&(jn=!0,I?.write(`\x1B[32mConnected to interactive terminal\x1B[0m\r
|
|
1075
|
+
`),Ms())}),se.addEventListener("message",c=>{if(t!==Cn)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
1076
|
\x1B[33m[process exited: ${f.code}]\x1B[0m\r
|
|
1073
1077
|
`):f.type==="error"&&I?.write(`\r
|
|
1074
1078
|
\x1B[31m[error: ${f.data||f.message||""}]\x1B[0m\r
|
|
1075
|
-
`)}),se.addEventListener("close",()=>{t===
|
|
1079
|
+
`)}),se.addEventListener("close",()=>{t===Cn&&(jn=!1,I?.write(`\r
|
|
1076
1080
|
\x1B[33m[disconnected]\x1B[0m\r
|
|
1077
|
-
`),!(!
|
|
1078
|
-
`),
|
|
1081
|
+
`),!(!Ca||j.peek()!=="shell")&&(I?.write(`\x1B[33m[reconnecting\u2026]\x1B[0m\r
|
|
1082
|
+
`),An=setTimeout(()=>{An=null,Ts(Es)},1500)))}),se.addEventListener("error",()=>{t===Cn&&I?.write(`\r
|
|
1079
1083
|
\x1B[31m[WebSocket error]\x1B[0m\r
|
|
1080
|
-
`)})}function
|
|
1084
|
+
`)})}function qi(){let e=v.peek()?.path,t=(0,n.$)("term-cwd");t&&(t.textContent=e||"~"),I||Gi(),requestAnimationFrame(()=>{requestAnimationFrame(()=>{Ss();let s=zi();!jn||Es!==(e||null)||Wi!==s?(I?.clear(),Ts(e)):Ms()})})}function Ji(){Ui||(Ui=!0,document.getElementById("term-keyboard")?.addEventListener("click",Is),document.getElementById("term-mobile-composer")?.addEventListener("submit",e=>{e.preventDefault();let t=document.getElementById("term-mobile-input");t&&(Aa(`${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||!Oi[t]||(Aa(Oi[t]),Is())})),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(j.peek()!=="shell"||!Ca||jn||Ts(Es))}),(0,n.watch)(j,e=>{e==="shell"&&qi()}),document.addEventListener("shell-tab-shown",()=>{j.peek()==="shell"&&qi()}),document.getElementById("term-reconnect")?.addEventListener("click",()=>{I?.clear(),Ts(v.peek()?.path)})}Wt();yn();Yn();jt();function ja(){let e=document.documentElement;e.classList.add("boot-ready"),e.classList.remove("boot-pending")}function Cs(){document.documentElement.classList.remove("boot-restore")}var Da=Xs(location.hash.slice(1)||"/"),Ki=Ma()||!!(u.token&&Da?.id);Hi({restoreSession:Ki});to();jo();Ri();Fi();Fo();Ji();Co();ti();No(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")),Ki){document.documentElement.classList.add("boot-restore");let o=document.getElementById("welcome"),i=document.getElementById("project-view");o&&(o.classList.add("hidden"),o.style.display="none"),i&&(i.classList.remove("hidden"),i.style.cssText="display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden")}let a=await e;await ks({hub:a,deepLink:Da}),Da?.id||(Po(),(location.hash||"").startsWith("#/session/")||Cs()),requestAnimationFrame(()=>{requestAnimationFrame(ja)})}catch(t){console.error("[boot]",t),u.token=null,localStorage.removeItem("token"),Cs(),await Ia(),ja()}else{Cs();try{await Ia()}catch(t){console.error("[boot auth]",t)}finally{ja()}}})();document.addEventListener("router:home",()=>{Cs()});Za();
|