claude-simple 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{app.0.2.2.min.js → app.0.2.3.min.js} +87 -84
- package/dist/index.html +2 -2
- package/dist/{style.0.2.2.min.css → style.0.2.3.min.css} +33 -7
- package/package.json +1 -1
- package/public/index.html +2 -2
- package/public/shell/dashboard.js +64 -1
- package/public/shell/templates.js +15 -12
- package/public/shell.js +28 -11
- package/public/style.css +32 -6
- package/public/sw.js +2 -2
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
var Rs=Object.defineProperty;var Aa=Object.getOwnPropertyDescriptor;var ja=Object.getOwnPropertyNames;var Da=Object.prototype.hasOwnProperty;var X=(e,t)=>()=>(e&&(t=e(e=0)),t);var Os=(e,t)=>{for(var s in t)Rs(e,s,{get:t[s],enumerable:!0})},Ns=(e,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ja(t))!Da.call(e,a)&&a!==s&&Rs(e,a,{get:()=>t[a],enumerable:!(o=Aa(t,a))||o.enumerable});return e},zn=(e,t,s)=>(Ns(e,t,"default"),s&&Ns(s,t,"default"));var n={};import*as tr from"https://cdn.jsdelivr.net/gh/forechoandlook/mini-react@v0.1.13/dist/mini-react.min.js";var C=X(()=>{zn(n,tr)});var Ws={};Os(Ws,{AGENT_DEFAULT_MODEL:()=>Bs,AGENT_LABELS:()=>R,AGENT_MODELS:()=>Jn,LOW_TURN_THRESHOLD:()=>Vn,activityHits:()=>ue,activityLoading:()=>Le,addCustomModel:()=>Tt,agentFilter:()=>Q,agentsMeta:()=>it,chatDensity:()=>Te,collapsedFolders:()=>at,ctx:()=>f,currentAgent:()=>S,currentEffort:()=>pe,currentModel:()=>$,currentPermission:()=>Lt,currentProject:()=>y,currentTab:()=>j,expandedFolders:()=>ot,favoritesOnly:()=>He,filesPath:()=>A,filesRoot:()=>F,filteredSessions:()=>Re,getCustomModels:()=>en,getDefaultModel:()=>re,getEffortsForModel:()=>Et,getModelsForAgent:()=>fe,getSessionMeta:()=>rt,gitRoot:()=>J,hubMachineReady:()=>Ee,hubMode:()=>k,isProcessing:()=>ie,machinesList:()=>D,metaKey:()=>O,projectGroups:()=>ze,removeCustomModel:()=>Qn,selectedMachineId:()=>T,sessionDisplayTitle:()=>Ge,sessionFilter:()=>U,sessionMetaMap:()=>v,sessionSearch:()=>N,sessionSort:()=>Us,sessionsData:()=>M,setAgent:()=>me,setChatDensity:()=>Yn,setSelectedMachine:()=>Z,showHiddenOnly:()=>Ne,sidebarView:()=>Se,timeRange:()=>te,viewingFile:()=>B,workspacesData:()=>H,wsStatus:()=>$e});function Z(e){let t=e||null;T.value=t,f.machineId=t,t?localStorage.setItem("machineId",t):localStorage.removeItem("machineId")}function O(e,t,s){let o=`${e||"claude"}:${t}`;return s||f?.machineId?`${s||f.machineId}:${o}`:o}function rt(e,t,s){return v.peek()?.[O(e,t,s)]||{favorite:!1,notes:"",title:"",hidden:!1}}function Ge(e,{preferSnippet:t=!1}={}){if(!e)return"Session";if(t&&e.snippet)return e.snippet;let o=(rt(e.agent,e.sessionId,e.machineId).title||"").trim();return o||e.display||e.sessionId?.slice(0,8)||"Session"}function Yn(e){let t=["clean","normal","full"].includes(e)?e:"normal";Te.value=t,localStorage.setItem("chatDensity",t),document.getElementById("messages")?.setAttribute("data-density",t)}function _a(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 Xn(){try{let e=localStorage.getItem(Fs);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function qs(e){localStorage.setItem(Fs,JSON.stringify(e))}function en(e){let t=(e||"claude").toLowerCase(),s=Xn()[t];return Array.isArray(s)?s.filter(Boolean).map(String):[]}function Tt(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim();if(!o)return!1;let a=Xn(),i=Array.isArray(a[s])?[...a[s]]:[];return i.includes(o)||i.push(o),a[s]=i,qs(a),!0}function Qn(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim(),a=Xn(),i=Array.isArray(a[s])?a[s].filter(r=>r!==o):[];return a[s]=i,qs(a),!0}function fe(e){let t=(e||"claude").toLowerCase(),s=it.peek()?.defaults?.[t],o=s?.models?.length?s.models.map(_a).filter(Boolean):(Jn[t]||Jn.claude).map(r=>({...r})),a=en(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 u=String(c.label||c.value);return{...c,custom:!0,label:u.includes("\u2605")?u:`${u} \u2605`}});continue}i.add(r),o.push({value:r,label:`${r} \u2605`,custom:!0})}return o}function re(e){let t=(e||"claude").toLowerCase(),s=it.peek()?.defaults?.[t];return s?.model?String(s.model):Bs[t]||fe(t)[0]?.value||"claude-sonnet-4-5"}function Et(e,t){let o=fe(e).find(i=>i.value===t);if(o?.efforts?.length)return o.efforts;let a=it.peek()?.defaults?.[(e||"claude").toLowerCase()];return a?.efforts?.length?a.efforts.map(String):["low","medium","high","xhigh","max"]}function me(e){let t=(e||"claude").toLowerCase();S.value=t,localStorage.setItem("agent",t);let s=fe(t),o=re(t);s.some(a=>a.value===$.peek())||($.value=o,localStorage.setItem("model",o))}function Pa(e,t){return!t||t==="all"?!0:(e.agent||"claude")===t}function Ha(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 Na(e,t){if(!t)return!0;let s=v.value?.[O(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 Kn(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}var M,H,U,N,Us,ot,at,A,B,y,j,ie,$e,S,$,pe,Lt,F,J,it,Se,Q,te,ue,Le,v,He,Ne,Vn,Te,k,D,T,Ee,f,R,Jn,Bs,Fs,Re,ze,I=X(()=>{C();M=(0,n.signal)([]),H=(0,n.signal)([]),U=(0,n.signal)(null),N=(0,n.signal)(""),Us=(0,n.signal)("time"),ot=(0,n.signal)(new Set),at=(0,n.signal)(new Set),A=(0,n.signal)(""),B=(0,n.signal)(null),y=(0,n.signal)(null),j=(0,n.signal)("chat"),ie=(0,n.signal)(!1),$e=(0,n.signal)("idle"),S=(0,n.signal)(localStorage.getItem("agent")||"claude"),$=(0,n.signal)(localStorage.getItem("model")||"claude-sonnet-4-5"),pe=(0,n.signal)(""),Lt=(0,n.signal)("default"),F=(0,n.signal)(""),J=(0,n.signal)(""),it=(0,n.signal)(null),Se=(0,n.signal)(localStorage.getItem("sidebarView")||"projects"),Q=(0,n.signal)(localStorage.getItem("agentFilter")||"all"),te=(0,n.signal)(localStorage.getItem("timeRange")||"14"),ue=(0,n.signal)(null),Le=(0,n.signal)(!1),v=(0,n.signal)({}),He=(0,n.signal)(localStorage.getItem("favoritesOnly")==="1"),Ne=(0,n.signal)(localStorage.getItem("showHiddenOnly")==="1"),Vn=2,Te=(0,n.signal)(localStorage.getItem("chatDensity")||"normal"),k=(0,n.signal)(!1),D=(0,n.signal)([]),T=(0,n.signal)(null),Ee=(0,n.signal)(!1),f={token:localStorage.getItem("token"),sessionId:null,agent:null,machineId:null,ws:null,shellBubble:null,configDir:null};R={claude:"Claude",codex:"Codex",grok:"Grok"},Jn={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"}]},Bs={claude:"claude-sonnet-4-5",codex:"gpt-5.4",grok:"grok-4.5"};Fs="customModelsByAgent";Re=(0,n.computed)(()=>{let e=U.value,t=N.value.toLowerCase().trim(),s=Us.value,o=Q.value,a=te.value,i=He.value,r=Ne.value,c=v.value,u=ue.value,l=u?.results?.length&&t?Kn(u.results):Kn(M.value);e&&(l=l.filter(p=>p&&(p.cwd===e||p.configDir===e)));let d=T.value;return k.value&&d&&(l=l.filter(p=>p&&(!p.machineId||p.machineId===d))),l=l.filter(p=>p&&Pa(p,o)&&Ha(p,a)),r?l=l.filter(p=>p&&c?.[O(p.agent,p.sessionId,p.machineId)]?.hidden):l=l.filter(p=>p&&!c?.[O(p.agent,p.sessionId,p.machineId)]?.hidden),i&&(l=l.filter(p=>p&&c?.[O(p.agent,p.sessionId,p.machineId)]?.favorite)),t&&!(u?.results&&u.q===t)&&(l=l.filter(p=>p&&Na(p,t))),l=[...l].sort((p,m)=>{let x=c?.[O(p.agent,p.sessionId,p.machineId)]?.favorite?1:0,g=c?.[O(m.agent,m.sessionId,m.machineId)]?.favorite?1:0;return x!==g?g-x:s==="project"&&(p.cwd||"").localeCompare(m.cwd||"")||m.updatedAt-p.updatedAt}),!e&&!t&&!i?l.slice(0,120):l}),ze=(0,n.computed)(()=>{let e=Kn(Re.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 Mt(e={}){return e.machineId!==void 0?e.machineId:f.machineId||T.peek()||null}function Oa(e){let t=e.split("?")[0];return t==="/api/hub"||t==="/api/machines"||t.startsWith("/api/auth/")}async function h(e,t,s,o,a={}){let i=Mt(a),r={"Content-Type":"application/json",...f.token?{Authorization:`Bearer ${f.token}`}:{}};k.peek()&&i&&!Oa(t)&&(r["X-Machine-Id"]=i);let c=a.etag===!0?`${f.token||""}:${i||""}:${t}`:a.etag||null;if(e.toUpperCase()==="GET"&&c){let d=Gs.get(c);d&&(r["If-None-Match"]=d)}let u=async()=>{let d=await fetch(t,{method:e,signal:o,headers:r,...s!==void 0?{body:JSON.stringify(s)}:{}});if(d.status===304)return Zn;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&&Gs.set(c,m)}return p};if(e.toUpperCase()!=="GET"||o||a.dedupe===!1)return u();let l=`${f.token||""}:${i||""}:${t}`;return Ra.get(l,u)}function It(e){return f.ws?.readyState===WebSocket.OPEN?(f.ws.send(JSON.stringify(e)),!0):(e?.type==="ping"||e?.type==="pong"||e?.type==="subscribe"||tn.push(e),!1)}function zs(){for(;tn.length&&f.ws?.readyState===WebSocket.OPEN;)f.ws.send(JSON.stringify(tn.shift()))}function Js(){tn.length=0}function Ks(e={}){let t=new URLSearchParams(e);f.token&&t.set("token",f.token);let s=Mt();return k.peek()&&s&&t.set("machine",s),t.toString()}function lt(e={}){let t={...e};f.token&&(t.Authorization=`Bearer ${f.token}`);let s=Mt();return k.peek()&&s&&(t["X-Machine-Id"]=s),t}async function ct(){try{let e=await fetch("/api/hub");if(!e.ok)return k.value=!1,!1;let t=await e.json();if(t?.hub)return k.value=!0,t}catch{}return k.value=!1,!1}var Ra,Gs,Zn,tn,K=X(()=>{I();C();Ra=(0,n.createFetch)({cache:!1,dedupe:!0,retry:0}),Gs=new Map,Zn=Symbol("not-modified");tn=[]});function Je(){try{let e=localStorage.getItem(Zs);return e?JSON.parse(e):null}catch{return null}}function es(e){try{let s={...Je()||{},...e,updatedAt:Date.now()};localStorage.setItem(Zs,JSON.stringify(s))}catch{}}var Zs,nn=X(()=>{Zs="lastSessionContext"});async function ts(){if(Ct&&!(typeof navigator>"u"||!navigator.wakeLock?.request)&&document.visibilityState==="visible"&&!Ke)try{Ke=await navigator.wakeLock.request("screen"),Ke.addEventListener("release",()=>{Ke=null,Ct&&document.visibilityState==="visible"&&setTimeout(()=>{ts().catch(()=>{})},500)})}catch{Ke=null}}async function eo(){let e=Ke;if(Ke=null,!!e)try{await e.release()}catch{}}function to(e){Ct=!!e,Ct?ts().catch(()=>{}):eo().catch(()=>{})}function no(){typeof document>"u"||document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&Ct?ts().catch(()=>{}):document.visibilityState==="hidden"&&eo().catch(()=>{})})}var Ke,Ct,so=X(()=>{Ke=null,Ct=!1});function _(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 _(Number(t));let s=Date.parse(t);return Number.isNaN(s)?null:s}return null}function pt(e){let t=_(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 Ve(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():R[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)(R[s]||s)}">${i}</span>`}function oo(e){return Object.entries(e||{}).filter(([,t])=>t>0).map(([t,s])=>`${Ve(t)}<span class="text-[9px] text-base-content/40 -ml-0.5">${s}</span>`).join("")}function Ye(e){if(!e)return"";let t="",s=e.split("/").filter(Boolean);return s.length<=3?e:"\u2026/"+s.slice(-2).join("/")}var At=X(()=>{C();I()});function Ua(){return R[S.peek()]||"Assistant"}function co(e){return e.scrollHeight-e.scrollTop-e.clientHeight<80}function se(e,t){e&&(t||co(e))&&(e.scrollTop=e.scrollHeight)}function Ba(){ao||(ao=!0,document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="visible"&&(ge=400,sn({probe:!0}),f.ws?.readyState===WebSocket.OPEN&&f.sessionId))try{f.ws.send(JSON.stringify({type:"subscribe",sessionId:f.sessionId}))}catch{}}),window.addEventListener("online",()=>{ge=400,sn({force:!0})}),window.addEventListener("pageshow",e=>{e.persisted?sn({force:!0}):sn({probe:!0})}))}function Nt(){let e=(0,n.$)("conn-dot");if(!e)return;let t=$e.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 sn(e={}){let t=f.ws?.readyState;if(e.force){ge=400,Ae({quiet:!0});return}if(t===WebSocket.OPEN){if(e.probe&&Ie&&Date.now()-Ie>45e3)try{f.ws.close()}catch{}else if(e.probe&&f.ws.readyState===WebSocket.OPEN)try{f.ws.send(JSON.stringify({type:"ping"}))}catch{}return}t!==WebSocket.CONNECTING&&(ge=Math.min(ge,800),Ae({quiet:!0}))}function Fa(){Ce||($e.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",Nt(),Ce=setTimeout(()=>{Ce=null,Ae({quiet:!0})},ge),ge=Math.min(Math.round(ge*1.8),15e3))}function po(){on&&(clearInterval(on),on=null)}function qa(e,t){po(),on=setInterval(()=>{if(!(t!==Dt||e.readyState!==WebSocket.OPEN)){if(Ie&&Date.now()-Ie>7e4){try{e.close()}catch{}return}if(!(typeof document<"u"&&document.visibilityState==="hidden")&&Ie&&Date.now()-Ie>4e4)try{e.send(JSON.stringify({type:"ping"}))}catch{}}},3e4)}function Xe(){let e=ie.peek()||!!y.peek()&&$e.peek()==="open";to(e)}function Wa(){ge=400,Ce&&(clearTimeout(Ce),Ce=null),rn=!1;let e=f.ws?.readyState;if(e===WebSocket.OPEN||e===WebSocket.CONNECTING)try{f.ws?.close()}catch{}Ae({quiet:!1}),b("\u6B63\u5728\u91CD\u65B0\u8FDE\u63A5\u5E76\u540C\u6B65\u2026")}function Ae(e={}){Ba(),Ce&&(clearTimeout(Ce),Ce=null),e.quiet&&(rn=!0);let t=f.machineId||(typeof localStorage<"u"?localStorage.getItem("machineId"):null);io!==t&&(Js(),io=t);let s=++Dt;try{f.ws?.close()}catch{}$e.value="connecting",Nt();let o=location.protocol==="https:"?"wss":"ws",a=new URLSearchParams;f.token&&a.set("token",f.token),t&&a.set("machine",t),f.sessionId&&a.set("sessionId",f.sessionId);let i=new WebSocket(`${o}://${location.host}/ws/chat?${a}`);f.ws=i,i.addEventListener("open",()=>{if(s===Dt){if(ge=1e3,Ie=Date.now(),$e.value="open",Nt(),f.sessionId)try{i.send(JSON.stringify({type:"subscribe",sessionId:f.sessionId}))}catch{}zs(),qa(i,s),Xe(),an&&!rn&&b(t?`\u5DF2\u91CD\u8FDE \xB7 ${t}`:"\u5DF2\u91CD\u8FDE"),an=!1,rn=!1}}),i.addEventListener("message",r=>{if(s!==Dt)return;let c;try{c=JSON.parse(r.data)}catch{return}if(c.type==="pong"){Ie=Date.now();return}if(c.type==="ping"){if(Ie=Date.now(),i.readyState===WebSocket.OPEN)try{i.send(JSON.stringify({type:"pong"}))}catch{}return}if(c.type==="run-status"){c.running?ie.value=!0:ie.peek()&&(ie.value=!1,uo()),Xe();return}fo(c)}),i.addEventListener("close",()=>{s===Dt&&(po(),an=!0,$e.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",Nt(),Fa())}),i.addEventListener("error",()=>{})}function uo(){if(!Ht||ie.peek())return;let e=Ht;Ht=null;let t=(0,n.$)("chat-input");t&&(t.value=e,dn(t)),setTimeout(()=>mn(),0)}function _t(){ie.value=!1,Xe(),uo()}function fo(e){if(e.type==="batch"&&Array.isArray(e.items)){for(let t of e.items)fo(t);return}if(e.type==="session-created"){f.sessionId=e.sessionId,e.agent&&me(e.agent),document.dispatchEvent(new CustomEvent("sessions-changed"));return}if(e.type==="result"){Pt(),jt(),le();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};f.lastUsage=s,f.sessionId&&(f.lastUsageSessionId=f.sessionId),ut(s)}e.is_error||b("\u2713 Done"),_t();return}if(e.type==="complete"){Pt(),jt(),le(),!e.aborted&&e.agent==="claude"?b("\u2713 Done"):!e.aborted&&e.agent&&e.agent!=="claude"&&!e.error||(!e.aborted&&!e.agent?b("\u2713 Done"):e.aborted&&b("\u5DF2\u505C\u6B62")),_t();return}if(e.type==="error"){Pt(),jt(),Qe("error","Error",e.message),_t();return}if(e.type==="shell-start"){f.shellBubble=null;return}if(e.type==="shell-output"){f.shellBubble||(f.shellBubble=si(e.stream==="stderr"?"shell-err":"shell")),oi(f.shellBubble,e.data);return}if(e.type==="shell-exit"){f.shellBubble=null,b(e.code===0?"\u2713 Exit 0":`\u2717 Exit ${e.code}${e.error?": "+e.error:""}`),_t();return}if(e.type==="assistant"){jt();for(let t of e.message?.content||[])t.type==="text"&&t.text?(le(),Qe("assistant",Ua(),t.text,{ts:e.ts||Date.now()})):t.type==="tool_use"&&os(t,{ts:e.ts||Date.now()});return}if(e.type==="assistant_stream_start"){mo(e.ts);return}if(e.type==="assistant_delta"){Ga(e.data||"");return}if(e.type==="assistant_stream_end"){jt();return}if(e.type==="thought_stream_start"){ho();return}if(e.type==="thought_delta"){za(e.data||"");return}if(e.type==="thought_stream_end"){Pt();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>`),se(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)&&ri(e)}function mo(e){let t=(0,n.$)("messages");if(!t||(le(),Pt(),be&&t.contains(be)))return;let s=pn(e||Date.now()),o=un(e||Date.now());t.insertAdjacentHTML("beforeend",`
|
|
1
|
+
var Bs=Object.defineProperty;var ja=Object.getOwnPropertyDescriptor;var Da=Object.getOwnPropertyNames;var _a=Object.prototype.hasOwnProperty;var X=(e,t)=>()=>(e&&(t=e(e=0)),t);var Os=(e,t)=>{for(var s in t)Bs(e,s,{get:t[s],enumerable:!0})},Rs=(e,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Da(t))!_a.call(e,a)&&a!==s&&Bs(e,a,{get:()=>t[a],enumerable:!(o=ja(t,a))||o.enumerable});return e},zn=(e,t,s)=>(Rs(e,t,"default"),s&&Rs(s,t,"default"));var n={};import*as or from"https://cdn.jsdelivr.net/gh/forechoandlook/mini-react@v0.1.13/dist/mini-react.min.js";var C=X(()=>{zn(n,or)});var Gs={};Os(Gs,{AGENT_DEFAULT_MODEL:()=>Fs,AGENT_LABELS:()=>R,AGENT_MODELS:()=>Jn,LOW_TURN_THRESHOLD:()=>Vn,activityHits:()=>ue,activityLoading:()=>Me,addCustomModel:()=>Tt,agentFilter:()=>Q,agentsMeta:()=>it,chatDensity:()=>Te,collapsedFolders:()=>at,ctx:()=>f,currentAgent:()=>S,currentEffort:()=>pe,currentModel:()=>$,currentPermission:()=>Mt,currentProject:()=>y,currentTab:()=>j,expandedFolders:()=>ot,favoritesOnly:()=>Pe,filesPath:()=>A,filesRoot:()=>F,filteredSessions:()=>Re,getCustomModels:()=>tn,getDefaultModel:()=>re,getEffortsForModel:()=>Et,getModelsForAgent:()=>fe,getSessionMeta:()=>rt,gitRoot:()=>J,hubMachineReady:()=>Ee,hubMode:()=>k,isProcessing:()=>ie,machinesList:()=>D,metaKey:()=>B,projectGroups:()=>ze,removeCustomModel:()=>Qn,selectedMachineId:()=>M,sessionDisplayTitle:()=>Ge,sessionFilter:()=>O,sessionMetaMap:()=>v,sessionSearch:()=>N,sessionSort:()=>Us,sessionsData:()=>E,setAgent:()=>me,setChatDensity:()=>Yn,setSelectedMachine:()=>Z,showHiddenOnly:()=>Ne,sidebarView:()=>Le,timeRange:()=>te,viewingFile:()=>U,workspacesData:()=>P,wsStatus:()=>Se});function Z(e){let t=e||null;M.value=t,f.machineId=t,t?localStorage.setItem("machineId",t):localStorage.removeItem("machineId")}function B(e,t,s){let o=`${e||"claude"}:${t}`;return s||f?.machineId?`${s||f.machineId}:${o}`:o}function rt(e,t,s){return v.peek()?.[B(e,t,s)]||{favorite:!1,notes:"",title:"",hidden:!1}}function Ge(e,{preferSnippet:t=!1}={}){if(!e)return"Session";if(t&&e.snippet)return e.snippet;let o=(rt(e.agent,e.sessionId,e.machineId).title||"").trim();return o||e.display||e.sessionId?.slice(0,8)||"Session"}function Yn(e){let t=["clean","normal","full"].includes(e)?e:"normal";Te.value=t,localStorage.setItem("chatDensity",t),document.getElementById("messages")?.setAttribute("data-density",t)}function Ha(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 Xn(){try{let e=localStorage.getItem(qs);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function Ws(e){localStorage.setItem(qs,JSON.stringify(e))}function tn(e){let t=(e||"claude").toLowerCase(),s=Xn()[t];return Array.isArray(s)?s.filter(Boolean).map(String):[]}function Tt(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim();if(!o)return!1;let a=Xn(),i=Array.isArray(a[s])?[...a[s]]:[];return i.includes(o)||i.push(o),a[s]=i,Ws(a),!0}function Qn(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim(),a=Xn(),i=Array.isArray(a[s])?a[s].filter(r=>r!==o):[];return a[s]=i,Ws(a),!0}function fe(e){let t=(e||"claude").toLowerCase(),s=it.peek()?.defaults?.[t],o=s?.models?.length?s.models.map(Ha).filter(Boolean):(Jn[t]||Jn.claude).map(r=>({...r})),a=tn(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 u=String(c.label||c.value);return{...c,custom:!0,label:u.includes("\u2605")?u:`${u} \u2605`}});continue}i.add(r),o.push({value:r,label:`${r} \u2605`,custom:!0})}return o}function re(e){let t=(e||"claude").toLowerCase(),s=it.peek()?.defaults?.[t];return s?.model?String(s.model):Fs[t]||fe(t)[0]?.value||"claude-sonnet-4-5"}function Et(e,t){let o=fe(e).find(i=>i.value===t);if(o?.efforts?.length)return o.efforts;let a=it.peek()?.defaults?.[(e||"claude").toLowerCase()];return a?.efforts?.length?a.efforts.map(String):["low","medium","high","xhigh","max"]}function me(e){let t=(e||"claude").toLowerCase();S.value=t,localStorage.setItem("agent",t);let s=fe(t),o=re(t);s.some(a=>a.value===$.peek())||($.value=o,localStorage.setItem("model",o))}function Pa(e,t){return!t||t==="all"?!0:(e.agent||"claude")===t}function Na(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 Ra(e,t){if(!t)return!0;let s=v.value?.[B(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 Kn(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}var E,P,O,N,Us,ot,at,A,U,y,j,ie,Se,S,$,pe,Mt,F,J,it,Le,Q,te,ue,Me,v,Pe,Ne,Vn,Te,k,D,M,Ee,f,R,Jn,Fs,qs,Re,ze,I=X(()=>{C();E=(0,n.signal)([]),P=(0,n.signal)([]),O=(0,n.signal)(null),N=(0,n.signal)(""),Us=(0,n.signal)("time"),ot=(0,n.signal)(new Set),at=(0,n.signal)(new Set),A=(0,n.signal)(""),U=(0,n.signal)(null),y=(0,n.signal)(null),j=(0,n.signal)("chat"),ie=(0,n.signal)(!1),Se=(0,n.signal)("idle"),S=(0,n.signal)(localStorage.getItem("agent")||"claude"),$=(0,n.signal)(localStorage.getItem("model")||"claude-sonnet-4-5"),pe=(0,n.signal)(""),Mt=(0,n.signal)("default"),F=(0,n.signal)(""),J=(0,n.signal)(""),it=(0,n.signal)(null),Le=(0,n.signal)(localStorage.getItem("sidebarView")||"projects"),Q=(0,n.signal)(localStorage.getItem("agentFilter")||"all"),te=(0,n.signal)(localStorage.getItem("timeRange")||"14"),ue=(0,n.signal)(null),Me=(0,n.signal)(!1),v=(0,n.signal)({}),Pe=(0,n.signal)(localStorage.getItem("favoritesOnly")==="1"),Ne=(0,n.signal)(localStorage.getItem("showHiddenOnly")==="1"),Vn=2,Te=(0,n.signal)(localStorage.getItem("chatDensity")||"normal"),k=(0,n.signal)(!1),D=(0,n.signal)([]),M=(0,n.signal)(null),Ee=(0,n.signal)(!1),f={token:localStorage.getItem("token"),sessionId:null,agent:null,machineId:null,ws:null,shellBubble:null,configDir:null};R={claude:"Claude",codex:"Codex",grok:"Grok"},Jn={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"}]},Fs={claude:"claude-sonnet-4-5",codex:"gpt-5.4",grok:"grok-4.5"};qs="customModelsByAgent";Re=(0,n.computed)(()=>{let e=O.value,t=N.value.toLowerCase().trim(),s=Us.value,o=Q.value,a=te.value,i=Pe.value,r=Ne.value,c=v.value,u=ue.value,l=u?.results?.length&&t?Kn(u.results):Kn(E.value);e&&(l=l.filter(p=>p&&(p.cwd===e||p.configDir===e)));let d=M.value;return k.value&&d&&(l=l.filter(p=>p&&(!p.machineId||p.machineId===d))),l=l.filter(p=>p&&Pa(p,o)&&Na(p,a)),r?l=l.filter(p=>p&&c?.[B(p.agent,p.sessionId,p.machineId)]?.hidden):l=l.filter(p=>p&&!c?.[B(p.agent,p.sessionId,p.machineId)]?.hidden),i&&(l=l.filter(p=>p&&c?.[B(p.agent,p.sessionId,p.machineId)]?.favorite)),t&&!(u?.results&&u.q===t)&&(l=l.filter(p=>p&&Ra(p,t))),l=[...l].sort((p,m)=>{let b=c?.[B(p.agent,p.sessionId,p.machineId)]?.favorite?1:0,g=c?.[B(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}),ze=(0,n.computed)(()=>{let e=Kn(Re.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 It(e={}){return e.machineId!==void 0?e.machineId:f.machineId||M.peek()||null}function Oa(e){let t=e.split("?")[0];return t==="/api/hub"||t==="/api/machines"||t.startsWith("/api/auth/")}async function h(e,t,s,o,a={}){let i=It(a),r={"Content-Type":"application/json",...f.token?{Authorization:`Bearer ${f.token}`}:{}};k.peek()&&i&&!Oa(t)&&(r["X-Machine-Id"]=i);let c=a.etag===!0?`${f.token||""}:${i||""}:${t}`:a.etag||null;if(e.toUpperCase()==="GET"&&c){let d=zs.get(c);d&&(r["If-None-Match"]=d)}let u=async()=>{let d=await fetch(t,{method:e,signal:o,headers:r,...s!==void 0?{body:JSON.stringify(s)}:{}});if(d.status===304)return Zn;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&&zs.set(c,m)}return p};if(e.toUpperCase()!=="GET"||o||a.dedupe===!1)return u();let l=`${f.token||""}:${i||""}:${t}`;return Ba.get(l,u)}function Ct(e){return f.ws?.readyState===WebSocket.OPEN?(f.ws.send(JSON.stringify(e)),!0):(e?.type==="ping"||e?.type==="pong"||e?.type==="subscribe"||nn.push(e),!1)}function Js(){for(;nn.length&&f.ws?.readyState===WebSocket.OPEN;)f.ws.send(JSON.stringify(nn.shift()))}function Ks(){nn.length=0}function Vs(e={}){let t=new URLSearchParams(e);f.token&&t.set("token",f.token);let s=It();return k.peek()&&s&&t.set("machine",s),t.toString()}function lt(e={}){let t={...e};f.token&&(t.Authorization=`Bearer ${f.token}`);let s=It();return k.peek()&&s&&(t["X-Machine-Id"]=s),t}async function ct(){try{let e=await fetch("/api/hub");if(!e.ok)return k.value=!1,!1;let t=await e.json();if(t?.hub)return k.value=!0,t}catch{}return k.value=!1,!1}var Ba,zs,Zn,nn,K=X(()=>{I();C();Ba=(0,n.createFetch)({cache:!1,dedupe:!0,retry:0}),zs=new Map,Zn=Symbol("not-modified");nn=[]});function Je(){try{let e=localStorage.getItem(eo);return e?JSON.parse(e):null}catch{return null}}function es(e){try{let s={...Je()||{},...e,updatedAt:Date.now()};localStorage.setItem(eo,JSON.stringify(s))}catch{}}var eo,sn=X(()=>{eo="lastSessionContext"});async function ts(){if(At&&!(typeof navigator>"u"||!navigator.wakeLock?.request)&&document.visibilityState==="visible"&&!Ke)try{Ke=await navigator.wakeLock.request("screen"),Ke.addEventListener("release",()=>{Ke=null,At&&document.visibilityState==="visible"&&setTimeout(()=>{ts().catch(()=>{})},500)})}catch{Ke=null}}async function to(){let e=Ke;if(Ke=null,!!e)try{await e.release()}catch{}}function no(e){At=!!e,At?ts().catch(()=>{}):to().catch(()=>{})}function so(){typeof document>"u"||document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&At?ts().catch(()=>{}):document.visibilityState==="hidden"&&to().catch(()=>{})})}var Ke,At,oo=X(()=>{Ke=null,At=!1});function _(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 _(Number(t));let s=Date.parse(t);return Number.isNaN(s)?null:s}return null}function pt(e){let t=_(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 Ve(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():R[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)(R[s]||s)}">${i}</span>`}function ao(e){return Object.entries(e||{}).filter(([,t])=>t>0).map(([t,s])=>`${Ve(t)}<span class="text-[9px] text-base-content/40 -ml-0.5">${s}</span>`).join("")}function Ye(e){if(!e)return"";let t="",s=e.split("/").filter(Boolean);return s.length<=3?e:"\u2026/"+s.slice(-2).join("/")}var jt=X(()=>{C();I()});function Ua(){return R[S.peek()]||"Assistant"}function po(e){return e.scrollHeight-e.scrollTop-e.clientHeight<80}function se(e,t){e&&(t||po(e))&&(e.scrollTop=e.scrollHeight)}function Fa(){io||(io=!0,document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="visible"&&(ge=400,on({probe:!0}),f.ws?.readyState===WebSocket.OPEN&&f.sessionId))try{f.ws.send(JSON.stringify({type:"subscribe",sessionId:f.sessionId}))}catch{}}),window.addEventListener("online",()=>{ge=400,on({force:!0})}),window.addEventListener("pageshow",e=>{e.persisted?on({force:!0}):on({probe:!0})}))}function Rt(){let e=(0,n.$)("conn-dot");if(!e)return;let t=Se.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 on(e={}){let t=f.ws?.readyState;if(e.force){ge=400,je({quiet:!0});return}if(t===WebSocket.OPEN){if(e.probe&&Ce&&Date.now()-Ce>45e3)try{f.ws.close()}catch{}else if(e.probe&&f.ws.readyState===WebSocket.OPEN)try{f.ws.send(JSON.stringify({type:"ping"}))}catch{}return}t!==WebSocket.CONNECTING&&(ge=Math.min(ge,800),je({quiet:!0}))}function qa(){Ae||(Se.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",Rt(),Ae=setTimeout(()=>{Ae=null,je({quiet:!0})},ge),ge=Math.min(Math.round(ge*1.8),15e3))}function uo(){an&&(clearInterval(an),an=null)}function Wa(e,t){uo(),an=setInterval(()=>{if(!(t!==_t||e.readyState!==WebSocket.OPEN)){if(Ce&&Date.now()-Ce>7e4){try{e.close()}catch{}return}if(!(typeof document<"u"&&document.visibilityState==="hidden")&&Ce&&Date.now()-Ce>4e4)try{e.send(JSON.stringify({type:"ping"}))}catch{}}},3e4)}function Xe(){let e=ie.peek()||!!y.peek()&&Se.peek()==="open";no(e)}function Ga(){ge=400,Ae&&(clearTimeout(Ae),Ae=null),ln=!1;let e=f.ws?.readyState;if(e===WebSocket.OPEN||e===WebSocket.CONNECTING)try{f.ws?.close()}catch{}je({quiet:!1}),x("\u6B63\u5728\u91CD\u65B0\u8FDE\u63A5\u5E76\u540C\u6B65\u2026")}function je(e={}){Fa(),Ae&&(clearTimeout(Ae),Ae=null),e.quiet&&(ln=!0);let t=f.machineId||(typeof localStorage<"u"?localStorage.getItem("machineId"):null);ro!==t&&(Ks(),ro=t);let s=++_t;try{f.ws?.close()}catch{}Se.value="connecting",Rt();let o=location.protocol==="https:"?"wss":"ws",a=new URLSearchParams;f.token&&a.set("token",f.token),t&&a.set("machine",t),f.sessionId&&a.set("sessionId",f.sessionId);let i=new WebSocket(`${o}://${location.host}/ws/chat?${a}`);f.ws=i,i.addEventListener("open",()=>{if(s===_t){if(ge=1e3,Ce=Date.now(),Se.value="open",Rt(),f.sessionId)try{i.send(JSON.stringify({type:"subscribe",sessionId:f.sessionId}))}catch{}Js(),Wa(i,s),Xe(),rn&&!ln&&x(t?`\u5DF2\u91CD\u8FDE \xB7 ${t}`:"\u5DF2\u91CD\u8FDE"),rn=!1,ln=!1}}),i.addEventListener("message",r=>{if(s!==_t)return;let c;try{c=JSON.parse(r.data)}catch{return}if(c.type==="pong"){Ce=Date.now();return}if(c.type==="ping"){if(Ce=Date.now(),i.readyState===WebSocket.OPEN)try{i.send(JSON.stringify({type:"pong"}))}catch{}return}if(c.type==="run-status"){c.running?ie.value=!0:ie.peek()&&(ie.value=!1,fo()),Xe();return}mo(c)}),i.addEventListener("close",()=>{s===_t&&(uo(),rn=!0,Se.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",Rt(),qa())}),i.addEventListener("error",()=>{})}function fo(){if(!Nt||ie.peek())return;let e=Nt;Nt=null;let t=(0,n.$)("chat-input");t&&(t.value=e,pn(t)),setTimeout(()=>hn(),0)}function Ht(){ie.value=!1,Xe(),fo()}function mo(e){if(e.type==="batch"&&Array.isArray(e.items)){for(let t of e.items)mo(t);return}if(e.type==="session-created"){f.sessionId=e.sessionId,e.agent&&me(e.agent),document.dispatchEvent(new CustomEvent("sessions-changed"));return}if(e.type==="result"){Pt(),Dt(),le();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};f.lastUsage=s,f.sessionId&&(f.lastUsageSessionId=f.sessionId),ut(s)}e.is_error||x("\u2713 Done"),Ht();return}if(e.type==="complete"){Pt(),Dt(),le(),!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")),Ht();return}if(e.type==="error"){Pt(),Dt(),Qe("error","Error",e.message),Ht();return}if(e.type==="shell-start"){f.shellBubble=null;return}if(e.type==="shell-output"){f.shellBubble||(f.shellBubble=oi(e.stream==="stderr"?"shell-err":"shell")),ai(f.shellBubble,e.data);return}if(e.type==="shell-exit"){f.shellBubble=null,x(e.code===0?"\u2713 Exit 0":`\u2717 Exit ${e.code}${e.error?": "+e.error:""}`),Ht();return}if(e.type==="assistant"){Dt();for(let t of e.message?.content||[])t.type==="text"&&t.text?(le(),Qe("assistant",Ua(),t.text,{ts:e.ts||Date.now()})):t.type==="tool_use"&&os(t,{ts:e.ts||Date.now()});return}if(e.type==="assistant_stream_start"){ho(e.ts);return}if(e.type==="assistant_delta"){za(e.data||"");return}if(e.type==="assistant_stream_end"){Dt();return}if(e.type==="thought_stream_start"){bo();return}if(e.type==="thought_delta"){Ja(e.data||"");return}if(e.type==="thought_stream_end"){Pt();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>`),se(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)&&li(e)}function ho(e){let t=(0,n.$)("messages");if(!t||(le(),Pt(),be&&t.contains(be)))return;let s=un(e||Date.now()),o=fn(e||Date.now());t.insertAdjacentHTML("beforeend",`
|
|
2
2
|
<div class="msg-row assistant px-2 live-stream" data-ts="${(0,n.esc)(o)}">
|
|
3
3
|
<div class="max-w-[88%] rounded-2xl rounded-tl-sm px-3 py-2 text-sm bg-base-200 break-words md">
|
|
4
4
|
<div class="msg-stream-body whitespace-pre-wrap"></div>
|
|
5
5
|
</div>
|
|
6
6
|
${s?`<div class="msg-ts" title="${(0,n.esc)(o)}">${(0,n.esc)(s)}</div>`:""}
|
|
7
|
-
</div>`),be=t.lastElementChild,ne=be.querySelector(".msg-stream-body"),(0,n.$)("stream-status")?.remove(),se(t,!0)}function
|
|
7
|
+
</div>`),be=t.lastElementChild,ne=be.querySelector(".msg-stream-body"),(0,n.$)("stream-status")?.remove(),se(t,!0)}function za(e){e&&(ne||ho(Date.now()),ne&&(ne.textContent+=e,se((0,n.$)("messages"),!0)))}function Dt(){if(!be||!ne){be=null,ne=null;return}let e=ne.textContent||"";e.trim()?(ne.classList.remove("whitespace-pre-wrap"),ne.classList.add("md"),ne.innerHTML=cn(e),vo(be)):be.remove(),be=null,ne=null,(0,n.$)("stream-status")?.remove()}function bo(){let e=(0,n.$)("messages");e&&(Be&&e.contains(Be)||(e.insertAdjacentHTML("beforeend",`
|
|
8
8
|
<div class="msg-row assistant px-2 thought-stream">
|
|
9
9
|
<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">
|
|
10
10
|
<div class="font-medium text-base-content/35 mb-0.5">thinking\u2026</div>
|
|
11
11
|
<div class="thought-body font-mono whitespace-pre-wrap max-h-24 overflow-y-auto opacity-80"></div>
|
|
12
12
|
</div>
|
|
13
|
-
</div>`),
|
|
14
|
-
<div class="text-[10px] text-base-content/30 px-1 select-none">\u{1F4AD} thought ${e?`(${e} chars)`:""}</div>`}
|
|
15
|
-
Available: ${u}`:""}`),!0}let a=
|
|
13
|
+
</div>`),Be=e.lastElementChild,xe=Be.querySelector(".thought-body"),se(e,!0)))}function Ja(e){e&&(xe||bo(),xe&&(xe.textContent+=e,xe.scrollTop=xe.scrollHeight,se((0,n.$)("messages"),!0)))}function Pt(){if(Be&&xe){let e=(xe.textContent||"").length;Be.innerHTML=`
|
|
14
|
+
<div class="text-[10px] text-base-content/30 px-1 select-none">\u{1F4AD} thought ${e?`(${e} chars)`:""}</div>`}Be=null,xe=null}function Va(e){let[t,...s]=e.slice(1).trim().split(/\s+/),o=s.join(" ");switch(t.toLowerCase()){case"agent":{if(!o)return x(`Current agent: ${S.peek()} \xB7 agents: claude | codex | grok`),!0;let a=o.toLowerCase();return["claude","codex","grok"].includes(a)?(a!==S.peek()?(f.sessionId=null,me(a),$.value=re(a),localStorage.setItem("model",$.peek()),document.dispatchEvent(new CustomEvent("agent-changed")),x(`Agent \u2192 ${R[a]} \xB7 model ${$.peek()} \xB7 new session`)):x(`Agent already ${R[a]}`),!0):(x(`Unknown agent "${o}" \xB7 valid: claude | codex | grok`),!0)}case"model":{if(!o){let c=S.peek(),u=fe(c).map(l=>l.value).join(" | ");return x(`Current model: ${$.peek()} (${c})${u?`
|
|
15
|
+
Available: ${u}`:""}`),!0}let a=Ka[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe(i).some(c=>c.value===a);return r||Tt(i,a),$.value=a,localStorage.setItem("model",a),x(`Model set to ${a}${r?"":" (saved as custom \u2605)"}`),document.dispatchEvent(new CustomEvent("agent-changed")),!0}case"effort":{let a=Et(S.peek(),$.peek());return o?a.includes(o.toLowerCase())?(pe.value=o.toLowerCase(),x(`Effort set to ${o.toLowerCase()}`),!0):(x(`Unknown effort level "${o}" \xB7 valid: ${a.join(" | ")}`),!0):(x(`Current effort: ${pe.peek()||"(default)"} \xB7 levels: ${a.join(" | ")}`),!0)}case"clear":return ft(),f.sessionId=null,f.lastUsage=null,x("Cleared \xB7 new session"),!0;case"usage":return Ya(),!0;case"help":return x(`Available slash commands:
|
|
16
16
|
/agent [claude|codex|grok]
|
|
17
17
|
/model [haiku|sonnet|opus|<model-id>]
|
|
18
18
|
/effort [low|medium|high|xhigh|max]
|
|
19
19
|
/usage
|
|
20
20
|
/clear
|
|
21
|
-
/help`),!0;default:return!1}}function V(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
|
|
22
|
-
`)),ns("\u25C8 /usage \xB7 no session yet");return}
|
|
23
|
-
`)),(r.tokensUsed!=null||r.windowTokens!=null)&&ss({tokensUsed:r.tokensUsed,windowTokens:r.windowTokens,usagePercent:r.usagePercent,model:r.model||t,turnCount:r.turnCount,toolCallCount:r.toolCallCount}),r.sessionTotals?ut(r.sessionTotals):r.lastTurn?ut(r.lastTurn):f.lastUsage&&ut(f.lastUsage)}catch(a){let i=(0,n.$)("messages");if(i){let r=[...i.children];for(let c=r.length-1;c>=0;c--)if(r[c].textContent==="Loading usage\u2026"){r[c].remove();break}}
|
|
21
|
+
/help`),!0;default:return!1}}function V(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 Ya(){let e=S.peek()||"claude",t=$.peek()||"\u2014",s=f.sessionId,o=[`Agent: ${R[e]||e}`,`Model: ${t}`,`Session: ${s?s.slice(0,8)+"\u2026":"(new \u2014 send a message first)"}`];if(f.lastUsage&&(!s||f.lastUsageSessionId===s)){let a=f.lastUsage;o.push(`Last turn: \u2191${V(a.input_tokens)} \u2193${V(a.output_tokens)}`+(a.cache_read_input_tokens?` \xB7 ${V(a.cache_read_input_tokens)} cached`:"")+(a.reasoning_tokens?` \xB7 ${V(a.reasoning_tokens)} reason`:"")+(a.total_tokens?` \xB7 \u03A3${V(a.total_tokens)}`:"")+(a.costUSD!=null?` \xB7 $${Number(a.costUSD).toFixed(4)}`:""))}if(!s){x(o.join(`
|
|
22
|
+
`)),ns("\u25C8 /usage \xB7 no session yet");return}x("Loading usage\u2026");try{let a=new URLSearchParams({sessionId:s,agent:e}),r=(await h("GET",`/api/usage?${a}`)).context||{};if(r.model&&(o[1]=`Model: ${r.model}`),r.title&&o.push(`Title: ${r.title}`),r.tokensUsed!=null||r.windowTokens!=null||r.usagePercent!=null){let u=r.tokensUsed!=null?V(r.tokensUsed):"\u2014",l=r.windowTokens!=null?V(r.windowTokens):"\u2014",d=r.usagePercent!=null?`${r.usagePercent}%`:"\u2014";o.push(`Context window: ${u} / ${l} (${d})`)}if(r.turnCount!=null&&o.push(`Turns: ${r.turnCount}`),r.toolCallCount!=null&&o.push(`Tools: ${r.toolCallCount}`),r.sessionDurationSeconds!=null){let u=Math.floor(r.sessionDurationSeconds/60),l=Math.round(r.sessionDurationSeconds%60);o.push(`Duration: ${u}m ${l}s`)}if(r.sessionTotals){let u=r.sessionTotals;o.push(`Session totals: \u2191${V(u.input_tokens)} \u2193${V(u.output_tokens)}`+(u.cache_read_input_tokens?` \xB7 ${V(u.cache_read_input_tokens)} cached`:"")+(u.total_tokens?` \xB7 \u03A3${V(u.total_tokens)}`:"")+(u.costUSD?` \xB7 $${Number(u.costUSD).toFixed(4)}`:""))}if(r.lastTurn&&!f.lastUsage){let u=r.lastTurn;o.push(`Last completed turn: \u2191${V(u.input_tokens)} \u2193${V(u.output_tokens)}`+(u.cache_read_input_tokens?` \xB7 ${V(u.cache_read_input_tokens)} cached`:"")+(u.costUSD!=null?` \xB7 $${Number(u.costUSD).toFixed(4)}`:""))}r.note&&o.push(r.note);let c=(0,n.$)("messages");if(c){let u=[...c.children];for(let l=u.length-1;l>=0;l--)if(u[l].textContent==="Loading usage\u2026"){u[l].remove();break}}x(o.join(`
|
|
23
|
+
`)),(r.tokensUsed!=null||r.windowTokens!=null)&&ss({tokensUsed:r.tokensUsed,windowTokens:r.windowTokens,usagePercent:r.usagePercent,model:r.model||t,turnCount:r.turnCount,toolCallCount:r.toolCallCount}),r.sessionTotals?ut(r.sessionTotals):r.lastTurn?ut(r.lastTurn):f.lastUsage&&ut(f.lastUsage)}catch(a){let i=(0,n.$)("messages");if(i){let r=[...i.children];for(let c=r.length-1;c>=0;c--)if(r[c].textContent==="Loading usage\u2026"){r[c].remove();break}}x(`${o.join(`
|
|
24
24
|
`)}
|
|
25
|
-
(usage fetch failed: ${a.message})`)}}function
|
|
25
|
+
(usage fetch failed: ${a.message})`)}}function hn(){let e=(0,n.$)("chat-input"),t=e?.value.trim();if(!t||!y.peek())return;if(ie.peek()){Nt=t,e.value="",pn(e),dn(""),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="",pn(e),dn(""),t.startsWith("/")&&Va(t))return;ie.value=!0,Xe();let s=Date.now();if(t.startsWith("!"))Qe("shell","$ Shell",t.slice(1).trim(),{ts:s}),Ct({type:"command",cmd:"shell.exec",command:t.slice(1).trim(),cwd:y.peek().path})||x("\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u547D\u4EE4\u5DF2\u5165\u961F\uFF0C\u91CD\u8FDE\u540E\u53D1\u9001");else{le(),Qe("user","You",t,{ts:s});let o=pe.peek(),a=Mt.peek(),i=S.peek()||"claude";Ct({type:"command",cmd:"turn.start",agent:i,command:t,sessionId:f.sessionId,options:{agent:i,cwd:y.peek().path,sessionId:f.sessionId,configDir:f.configDir,model:$.peek(),...o&&{effort:o},...a&&a!=="default"&&{permissionMode:a},...a==="bypassPermissions"&&{allowDangerouslySkipPermissions:!0}}})||x("\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u6D88\u606F\u5DF2\u5165\u961F\uFF0C\u91CD\u8FDE\u540E\u53D1\u9001")}}function xo(){f.sessionId&&Ct({type:"command",cmd:"turn.interrupt",sessionId:f.sessionId}),Nt=null,Ht()}function dn(e){let t=e.startsWith("!"),s=(0,n.$)("chat-input"),o=(0,n.$)("send-btn");if(!s||!o)return;s.classList.toggle("textarea-warning",t),s.style.fontFamily=t?"monospace":"",o.classList.toggle("btn-warning",t),o.classList.toggle("btn-primary",!t),o.textContent=t?"Run":"Send";let a=R[S.peek()]||"agent";s.placeholder=t?"Shell command (without !)\u2026":`Ask ${a}\u2026 or !cmd for shell`}function Xa(){return typeof window<"u"&&window.matchMedia("(max-width: 640px)").matches?96:140}function pn(e){e.style.height="auto",e.style.height=Math.min(e.scrollHeight,Xa())+"px"}function un(e){let t=_(e);if(t==null)return"";let s=new Date(t);if(Number.isNaN(s.getTime()))return"";let o=new Date,a=s.toDateString()===o.toDateString(),i=s.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1});return a?i:`${s.toLocaleDateString(void 0,{month:"numeric",day:"numeric"})} ${i}`}function fn(e){let t=_(e);return t==null?"":new Date(t).toISOString()}function ei(e,t,s){if(e==="system")return t;let o=un(s),a=fn(s),i=o?`<div class="msg-ts" title="${(0,n.esc)(a)}">${(0,n.esc)(o)}</div>`:"";return`<div class="msg-row ${e==="user"?"user":e==="shell"||e==="shell-err"?"assistant":e} px-2" data-ts="${(0,n.esc)(a)}">${t}${i}</div>`}function ti(e,t,s){let o='<button class="msg-expand-btn text-[10px] text-primary/70 mt-1.5 block cursor-pointer hover:text-primary">\u25BC Show more</button>',a;switch(e){case"user":{let r=/!\[.*?\]\(.*?\)/.test(t)?cn(t):null,c=t.length>Qa,u=c?`<div class="msg-body">${r??(0,n.esc)(t.trimEnd())}</div>${o}`:r??(0,n.esc)(t.trimEnd());a=`<div class="max-w-[80%] rounded-2xl rounded-tr-sm px-3 py-2 text-sm bg-primary/15 border border-primary/20 text-base-content break-words${c?" msg-card":""}${r?" md":""}"${r?"":' style="white-space:pre-wrap"'}>${u}</div>`;break}case"assistant":{let i=t.length>Za,r=i?`<div class="msg-body">${cn(t)}</div>${o}`:cn(t);a=`<div class="max-w-[min(92%,52rem)] rounded-2xl rounded-tl-sm px-3.5 py-2.5 text-sm bg-base-200 border border-base-300/40 break-words md leading-relaxed${i?" msg-card":""}">${r}</div>`;break}case"error":a=`<div class="max-w-[88%] rounded-2xl rounded-tl-sm px-3 py-2 text-sm bg-error/10 border border-error/20 text-error break-words" style="white-space:pre-wrap">${(0,n.esc)(t)}</div>`;break;case"shell":case"shell-err":a=`<div class="w-full max-w-[96%] rounded-lg code-surface px-3 py-2 text-sm font-mono ${e==="shell-err"?"text-error":""} break-words" style="white-space:pre-wrap">${(0,n.esc)(t)}</div>`;break;case"system":return`<div class="text-center text-[11px] text-base-content/30 py-0.5 select-none">${(0,n.esc)(t)}</div>`;default:a=`<div class="rounded-lg px-3 py-2 text-sm bg-base-300 break-words" style="white-space:pre-wrap">${(0,n.esc)(t)}</div>`}return ei(e,a,s)}function Qe(e,t,s,o={}){let a=(0,n.$)("messages");if(!a)return;let i=_(o.ts)??(e==="system"?null:Date.now());a.insertAdjacentHTML("beforeend",ti(e,s,i)),vo(a.lastElementChild),se(a,e==="user")}function x(e){Qe("system","",e)}async function ni(e,t){let s=await fetch("/api/upload-image",{method:"POST",headers:{Authorization:`Bearer ${f.token}`,"x-filename":t},body:e});if(!s.ok)throw new Error(`Upload failed: ${s.status}`);return(await s.json()).path}function si(e,t){let s=e.selectionStart,o=e.selectionEnd;e.value=e.value.slice(0,s)+t+e.value.slice(o),e.selectionStart=e.selectionEnd=s+t.length,e.dispatchEvent(new Event("input"))}function go(){document.addEventListener("paste",async e=>{let t=(0,n.$)("chat-input");if(!t||document.activeElement!==t)return;let o=[...e.clipboardData?.items||[]].find(c=>c.type.startsWith("image/"));if(!o)return;e.preventDefault();let a=o.getAsFile(),i=o.type.split("/")[1]||"png",r=`paste-${Date.now()}.${i}`;t.disabled=!0;try{let c=await ni(a,r);si(t,``)}catch(c){x(`Image paste failed: ${c.message}`)}finally{t.disabled=!1,t.focus()}})}function Ie(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function ns(e){let t=(0,n.$)("messages");t&&(t.insertAdjacentHTML("beforeend",`<div class="flex items-center gap-1.5 px-1 py-0.5 text-[10px] font-mono text-base-content/30 select-none">
|
|
26
26
|
<span class="text-base-content/20">\u25C8</span>${(0,n.esc)(e)}
|
|
27
|
-
</div>`),se(t))}function ut(e){if(!e)return;let t=e.input_tokens??e.inputTokens??0,s=e.output_tokens??e.outputTokens??0,o=e.total_tokens??e.totalTokens??t+s,a=e.cache_read_input_tokens??e.cachedReadTokens?` \xB7 ${
|
|
27
|
+
</div>`),se(t))}function ut(e){if(!e)return;let t=e.input_tokens??e.inputTokens??0,s=e.output_tokens??e.outputTokens??0,o=e.total_tokens??e.totalTokens??t+s,a=e.cache_read_input_tokens??e.cachedReadTokens?` \xB7 ${Ie(e.cache_read_input_tokens??e.cachedReadTokens)} cached`:"",i=e.cache_creation_input_tokens??e.cacheCreationInputTokens?` \xB7 ${Ie(e.cache_creation_input_tokens??e.cacheCreationInputTokens)} cache-write`:"",r=e.reasoning_tokens??e.reasoningTokens?` \xB7 ${Ie(e.reasoning_tokens??e.reasoningTokens)} reason`:"",c=e.costUSD??e.cost_usd,u=c!=null?` \xB7 $${Number(c).toFixed(4)}`:"",l=o?` \xB7 \u03A3${Ie(o)}`:"";ns(`\u2191${Ie(t)} \u2193${Ie(s)}${a}${i}${r}${l}${u}`)}function ss(e){if(!e)return;let t=e.tokensUsed??e.contextTokensUsed,s=e.windowTokens??e.contextWindowTokens,o=e.usagePercent??e.contextWindowUsage;if(t==null&&s==null&&o==null)return;let a=[];t!=null&&s!=null?a.push(`context ${Ie(t)} / ${Ie(s)}`):t!=null&&a.push(`context ${Ie(t)}`),o!=null&&a.push(`${o}%`),e.model&&a.push(e.model),e.turnCount!=null&&a.push(`${e.turnCount} turns`),e.toolCallCount!=null&&a.push(`${e.toolCallCount} tools`),ns(`\u25A3 ${a.join(" \xB7 ")}`)}function ft(){let e=(0,n.$)("messages"),t=(0,n.$)("permission-requests");e&&(e.innerHTML=""),t&&(t.innerHTML=""),f.shellBubble=null,he=null,be=ne=null,Be=xe=null}function oi(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>`),se(t),t.lastElementChild}function ai(e,t){e&&(e.textContent+=t,se(e.closest("#messages")))}function ii(e){let t=typeof e.input=="object"?JSON.stringify(e.input,null,2):String(e.input||""),o=((typeof e.input=="object"?Object.values(e.input).find(a=>typeof a=="string"&&a.trim()):t)||"").replace(/\n/g," ").slice(0,Te.peek()==="full"?120:80);return{inputStr:t,preview:o}}function lo(e,{inBatch:t=!1}={}){let{inputStr:s,preview:o}=ii(e);return`<div class="tool-card${t?" tool-batch-item":""} cursor-pointer select-none px-2 py-1">
|
|
28
28
|
<div class="flex items-center gap-1.5 text-xs font-mono">
|
|
29
29
|
<span class="text-warning">\u26A1</span>
|
|
30
30
|
<span class="text-warning font-semibold">${(0,n.esc)(e.name||"tool")}</span>
|
|
@@ -32,21 +32,21 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
32
32
|
<span class="tool-chevron text-[10px] text-base-content/40">\u25B6</span>
|
|
33
33
|
</div>
|
|
34
34
|
<div class="tool-detail">${(0,n.esc)(s)}</div>
|
|
35
|
-
</div>`}function
|
|
35
|
+
</div>`}function ri(e){let t=[...new Set(e.names)],s=t.slice(0,4).join(", ")+(t.length>4?"\u2026":""),o=e.el.querySelector(".tool-batch-summary");o&&(o.innerHTML=`<span class="text-warning">\u26A1</span>
|
|
36
36
|
<span class="font-semibold text-base-content/70">${e.count} tool${e.count===1?"":"s"}</span>
|
|
37
37
|
<span class="text-base-content/40 truncate flex-1">${(0,n.esc)(s)}</span>
|
|
38
|
-
<span class="tool-chevron text-[10px] text-base-content/40">\u25B6</span>`)}function le(){he=null}function os(e,t={}){let s=(0,n.$)("messages");if(!s)return;let o=Te.peek()||"normal",a=_(t.ts);if(o==="clean"){if(!he||!s.contains(he.el)){let u=
|
|
38
|
+
<span class="tool-chevron text-[10px] text-base-content/40">\u25B6</span>`)}function le(){he=null}function os(e,t={}){let s=(0,n.$)("messages");if(!s)return;let o=Te.peek()||"normal",a=_(t.ts);if(o==="clean"){if(!he||!s.contains(he.el)){let u=un(a),l=fn(a);s.insertAdjacentHTML("beforeend",`
|
|
39
39
|
<div class="msg-row assistant px-2" data-ts="${(0,n.esc)(l)}">
|
|
40
40
|
<div class="tool-batch w-full max-w-[96%] px-2 py-1.5">
|
|
41
41
|
<div class="tool-batch-summary flex items-center gap-1.5 text-xs font-mono"></div>
|
|
42
42
|
<div class="tool-batch-list"></div>
|
|
43
43
|
</div>
|
|
44
44
|
${u?`<div class="msg-ts" title="${(0,n.esc)(l)}">${(0,n.esc)(u)}</div>`:""}
|
|
45
|
-
</div>`),he={el:s.lastElementChild.querySelector(".tool-batch"),names:[],count:0}}he.names.push(e.name||"tool"),he.count++,he.el.querySelector(".tool-batch-list")?.insertAdjacentHTML("beforeend",
|
|
45
|
+
</div>`),he={el:s.lastElementChild.querySelector(".tool-batch"),names:[],count:0}}he.names.push(e.name||"tool"),he.count++,he.el.querySelector(".tool-batch-list")?.insertAdjacentHTML("beforeend",lo(e,{inBatch:!0})),ri(he),se(s);return}he=null;let i=un(a),r=fn(a);s.insertAdjacentHTML("beforeend",`
|
|
46
46
|
<div class="msg-row assistant px-2" data-ts="${(0,n.esc)(r)}">
|
|
47
|
-
<div class="w-full max-w-[96%]">${
|
|
47
|
+
<div class="w-full max-w-[96%]">${lo(e)}</div>
|
|
48
48
|
${i?`<div class="msg-ts" title="${(0,n.esc)(r)}">${(0,n.esc)(i)}</div>`:""}
|
|
49
|
-
</div>`),se(s)}function
|
|
49
|
+
</div>`),se(s)}function mn(){let e=(0,n.$)("messages");e&&e.setAttribute("data-density",Te.peek()||"normal")}function li(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",`
|
|
50
50
|
<div id="perm-${t}" class="perm-banner mx-3 mb-2 rounded-lg border border-warning/25 bg-warning/8 p-3">
|
|
51
51
|
<div class="text-xs text-warning font-semibold mb-1">\u26A0\uFE0F Permission Required</div>
|
|
52
52
|
<div class="font-mono text-xs text-base-content/60 break-all mb-2">
|
|
@@ -56,19 +56,19 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
56
56
|
<button class="btn btn-success btn-xs" data-perm-id="${t}" data-perm-allow="1">Allow</button>
|
|
57
57
|
<button class="btn btn-error btn-xs" data-perm-id="${t}" data-perm-allow="0">Deny</button>
|
|
58
58
|
</div>
|
|
59
|
-
</div>`),(0,n.$)("messages").scrollTop=999999}function
|
|
59
|
+
</div>`),(0,n.$)("messages").scrollTop=999999}function ci(){if(co||typeof marked>"u")return;let e=o=>String(o??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),t=(o,a)=>{let i=String(a||"").trim().split(/\s+/)[0]||"",r=i||"text",c=i?`language-${(0,n.esc)(i)}`:"";return`<div class="code-block">
|
|
60
60
|
<div class="code-block-header">
|
|
61
61
|
<span class="code-block-lang">${(0,n.esc)(r)}</span>
|
|
62
62
|
<button type="button" class="code-copy" data-copy="1" title="Copy code">Copy</button>
|
|
63
63
|
</div>
|
|
64
64
|
<pre><code class="hljs ${c}">${e(o)}</code></pre>
|
|
65
|
-
</div>`},s={code(o,a){return o&&typeof o=="object"&&o.text!=null?t(o.text,o.lang||a):t(o,a)},table(o,a){return o&&typeof o=="object"&&!Array.isArray(o)&&o.header?!1:`<div class="table-wrap"><table><thead>${o}</thead><tbody>${a}</tbody></table></div>`}};try{if(typeof marked.use=="function")marked.use({gfm:!0,breaks:!0,renderer:s});else if(typeof marked.setOptions=="function"){let o=new marked.Renderer;o.code=s.code,o.table=s.table,marked.setOptions({gfm:!0,breaks:!0,renderer:o})}}catch(o){console.warn("[md] marked setup failed",o)}
|
|
66
|
-
<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] ${de} ${qe} ${
|
|
65
|
+
</div>`},s={code(o,a){return o&&typeof o=="object"&&o.text!=null?t(o.text,o.lang||a):t(o,a)},table(o,a){return o&&typeof o=="object"&&!Array.isArray(o)&&o.header?!1:`<div class="table-wrap"><table><thead>${o}</thead><tbody>${a}</tbody></table></div>`}};try{if(typeof marked.use=="function")marked.use({gfm:!0,breaks:!0,renderer:s});else if(typeof marked.setOptions=="function"){let o=new marked.Renderer;o.code=s.code,o.table=s.table,marked.setOptions({gfm:!0,breaks:!0,renderer:o})}}catch(o){console.warn("[md] marked setup failed",o)}co=!0}function cn(e){if(typeof marked>"u")return(0,n.esc)(e);try{return ci(),marked.parse(String(e??""),{breaks:!0,gfm:!0})}catch{return(0,n.esc)(e)}}function vo(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 yo(){mn(),so(),(0,n.watch)(Se,o=>{Rt(),Xe();let a=(0,n.$)("ws-banner"),i=(0,n.$)("ws-banner-text");if(!a)return;if(o==="open"||o==="idle"){a.classList.add("hidden"),i&&(i.textContent="");return}if(o==="connecting"&&!rn){a.classList.add("hidden");return}a.classList.remove("hidden");let r=o==="offline"?"\u7F51\u7EDC\u5DF2\u65AD\u5F00\uFF0C\u6062\u590D\u540E\u4F1A\u81EA\u52A8\u91CD\u8FDE":o==="connecting"?"\u6B63\u5728\u8FDE\u63A5\u2026":"\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u6B63\u5728\u91CD\u8FDE\u2026\uFF08\u7184\u5C4F\u6216\u5207\u7F51\u65F6\u5E38\u89C1\uFF09";i?i.textContent=r:a.textContent=r}),(0,n.watch)(y,()=>Xe()),n.delegate.on("click","#btn-refresh-conn, #ws-banner-retry",o=>{o.preventDefault(),Ga()}),(0,n.watch)(ie,o=>{(0,n.$)("send-btn")?.classList.toggle("hidden",o),(0,n.$)("stop-btn")?.classList.toggle("hidden",!o);let a=(0,n.$)("chat-input");a&&(a.disabled=!1,o?a.placeholder="\u56DE\u590D\u4E2D\u2026 \u53EF\u5148\u5199\u597D\u4E0B\u4E00\u6761\uFF0C\u7ED3\u675F\u540E\u81EA\u52A8\u53D1\u9001 \xB7 \u6216\u70B9 \u25A0 \u505C\u6B62":dn(a.value||""));let i=(0,n.$)("messages");if(!i)return;let r=(0,n.$)("typing-indicator");o&&!r?(i.insertAdjacentHTML("beforeend",'<div id="typing-indicator" class="flex justify-start px-2"><div class="flex items-center gap-1.5 rounded-2xl rounded-tl-sm px-3 py-2 bg-base-200 text-xs text-base-content/40"><span class="dot"></span><span class="dot"></span><span class="dot"></span></div></div>'),se(i)):o||(r?.remove(),le()),Xe()}),(0,n.watch)(Te,()=>mn()),n.delegate.on("keydown","#chat-input",o=>{o.key==="Enter"&&(o.metaKey||o.ctrlKey)&&(o.preventDefault(),hn())}),n.delegate.on("input","#chat-input",(o,a)=>{pn(a),dn(a.value)}),n.delegate.on("click","[data-perm-id]",(o,a)=>{Ct({type:"command",cmd:"approval.respond",requestId:a.dataset.permId,allow:a.dataset.permAllow==="1",sessionId:f.sessionId}),a.closest(".perm-banner")?.remove()}),n.delegate.on("click",".tool-card",(o,a)=>{let i=a.closest(".tool-batch");if(i&&!i.classList.contains("open")&&!a.classList.contains("tool-batch-item"))return;o.stopPropagation();let r=(0,n.$)("messages"),c=a.getBoundingClientRect().top;if(a.classList.toggle("open"),r){let u=a.getBoundingClientRect().top;r.scrollTop+=u-c}}),n.delegate.on("click",".tool-batch",(o,a)=>{if(o.target.closest(".tool-card")&&a.classList.contains("open"))return;let i=(0,n.$)("messages"),r=a.getBoundingClientRect().top;if(a.classList.toggle("open"),i){let c=a.getBoundingClientRect().top;i.scrollTop+=c-r}});let e=(0,n.$)("messages"),t=(0,n.$)("scroll-top-btn"),s=(0,n.$)("scroll-bottom-btn");if(e&&t&&s){let o=()=>{let a=e.scrollHeight-e.clientHeight>200;t.classList.toggle("hidden",!a||e.scrollTop<200),s.classList.toggle("hidden",!a||po(e))};e.addEventListener("scroll",o,{passive:!0}),new ResizeObserver(o).observe(e),new MutationObserver(o).observe(e,{childList:!0,subtree:!0}),t.addEventListener("click",()=>e.scrollTo({top:0,behavior:"smooth"})),s.addEventListener("click",()=>e.scrollTo({top:e.scrollHeight,behavior:"smooth"})),o()}n.delegate.on("click",".msg-expand-btn",(o,a)=>{o.stopPropagation();let r=a.closest(".msg-card").classList.toggle("open");a.textContent=r?"\u25B2 Show less":"\u25BC Show more"}),n.delegate.on("click",".code-copy",async(o,a)=>{o.preventDefault(),o.stopPropagation();let c=a.closest(".code-block")?.querySelector("pre code")?.textContent??"";try{await navigator.clipboard.writeText(c),a.textContent="Copied",a.classList.add("copied"),setTimeout(()=>{a.textContent="Copy",a.classList.remove("copied")},1400)}catch{a.textContent="Failed",setTimeout(()=>{a.textContent="Copy"},1400)}})}var _t,Ae,ge,Ce,an,io,rn,ro,ln,Nt,be,ne,Be,xe,Ka,Qa,Za,he,co,mt=X(()=>{C();I();K();oo();jt();jt();_t=0,Ae=null,ge=1e3,Ce=0,an=null,io=!1,rn=!1,ro=null,ln=!1,Nt=null;be=null,ne=null,Be=null,xe=null;Ka={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"};Qa=200,Za=500;he=null;co=!1});function ko(e,t){wo=e,as=t,window.addEventListener("hashchange",()=>{if(is){is=!1;return}So(location.hash.slice(1)||"/")}),(0,n.watch)(j,s=>{f.sessionId&&bn(`/session/${f.sessionId}/${s}`)})}function rs(e){let t=(e||"").match(/^\/session\/([^/]+)(?:\/([^/]+))?$/);return t?{id:t[1],tab:t[2]||null}:null}function $o(){So(location.hash.slice(1)||"/")}function So(e){let t=rs(e);if(!t){document.dispatchEvent(new CustomEvent("router:home"));return}let{id:s,tab:o}=t;!wo||!as||(s!==f.sessionId?document.dispatchEvent(new CustomEvent("router:session",{detail:{id:s,tab:o}})):o&&o!==j.peek()&&as(o))}function bn(e){is=!0,location.hash=e}function xn(){f.sessionId&&bn(`/session/${f.sessionId}/${j.peek()}`)}var Lr,wo,as,is,gn=X(()=>{C();I();Lr=(0,n.createRouter)({"/":()=>{},"/session/*":()=>{},"/session/*/*":()=>{},"*":()=>{}}),wo=null,as=null,is=!1});async function yn(){try{return await vn.get("sessions")??null}catch{return null}}async function Lo(e){try{await vn.set("sessions",e,{ttl:di})}catch{}}async function Mo(){try{return await vn.get("workspaces")??null}catch{return null}}async function Bt(e){try{await vn.set("workspaces",e,{ttl:3600*1e3})}catch{}}var vn,di,wn=X(()=>{C();vn=(0,n.idb)("claude-ui"),di=300*1e3});function En(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}function ve(){let e=En(E.peek()),t=M.peek();k.peek()&&t&&(e=e.filter(o=>o&&(!o.machineId||o.machineId===t)));let s=Q.peek();return s&&s!=="all"&&(e=e.filter(o=>o&&(o.agent||"claude")===s)),e}function qo(e){let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),o=String(e.getDate()).padStart(2,"0");return`${t}-${s}-${o}`}function wi(e,t){let s=[],a=new Date(e,t,1).getDay(),r=new Date(e,t+1,0).getDate(),c=new Date(e,t,0).getDate();for(let l=a-1;l>=0;l--)s.push({date:new Date(e,t-1,c-l),isCurrentMonth:!1});for(let l=1;l<=r;l++)s.push({date:new Date(e,t,l),isCurrentMonth:!0});let u=7-s.length%7;if(u<7)for(let l=1;l<=u;l++)s.push({date:new Date(e,t+1,l),isCurrentMonth:!1});return s}function Wo(e,t){let s=new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime(),o=s+1440*60*1e3;return t.filter(a=>{let i=_(a.updatedAt);return i!=null&&i>=s&&i<o})}function Go(e){return e==null||isNaN(e)?"0":e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}K`:String(e)}function nt(e){let t=(0,n.$)("calendar-grid");if(!t)return;e=En(e??ve());let s=(0,n.$)("calendar-month-year");if(s){let d=new Date(Tn,tt,1);s.textContent=d.toLocaleDateString([],{month:"long",year:"numeric"})}let o=e.length,a=new Set(e.map(d=>d.cwd).filter(Boolean)).size,i=e.reduce((d,p)=>d+(Number(p.totalTokens)||0),0),r=(0,n.$)("stats-total-sessions"),c=(0,n.$)("stats-total-projects"),u=(0,n.$)("stats-total-tokens");r&&(r.textContent=String(o)),c&&(c.textContent=String(a)),u&&(u.textContent=Go(i));let l=wi(Tn,tt);qt||(qt=qo(new Date)),t.innerHTML=l.map(d=>{let p=d.date,m=qo(p),g=Wo(p,e).length,W=p.toDateString()===new Date().toDateString(),Fe=m===qt,de="",qe="text-base-content/65",$e="border border-transparent",w="cursor-default",G=d.isCurrentMonth?"":"opacity-25";g>0?(w="cursor-pointer",g<=2?(de="bg-primary/15",qe="text-primary font-bold",$e="border border-primary/30"):g<=5?(de="bg-primary/30",qe="text-primary font-bold",$e="border border-primary/50"):(de="bg-primary/60",qe="text-primary-content font-bold",$e="border border-primary/80")):(de="bg-base-300/25",d.isCurrentMonth&&(w="hover:bg-base-300/50")),W?$e="border-2 border-primary":Fe&&($e="border-2 border-accent");let We=p.getDate()===1?`<span class="absolute top-0.5 left-1 text-[8px] opacity-60 uppercase">${p.toLocaleDateString([],{month:"short"})}</span>`:"";return`
|
|
66
|
+
<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] ${de} ${qe} ${$e} ${w} ${G}"
|
|
67
67
|
data-cal-date="${m}" title="${p.toDateString()}: ${g} session(s)">
|
|
68
68
|
${We}
|
|
69
69
|
<span class="text-sm font-semibold">${p.getDate()}</span>
|
|
70
70
|
${g>0?`<span class="text-[10px] mt-0.5 opacity-80 font-medium whitespace-nowrap">${g}s</span>`:""}
|
|
71
|
-
</div>`}).join(""),
|
|
71
|
+
</div>`}).join(""),ki(e),Si(e)}function ki(e){let t=(0,n.$)("selected-day-title"),s=(0,n.$)("selected-day-sessions");if(!t||!s)return;let[o,a,i]=qt.split("-").map(Number),r=new Date(o,a-1,i);t.textContent=`Activity on ${r.toLocaleDateString([],{weekday:"short",month:"short",day:"numeric",year:"numeric"})}`,e=En(e);let c=Wo(r,e),u=c.reduce((d,p)=>d+(Number(p.totalTokens)||0),0),l=(0,n.$)("stats-selected-tokens");if(l&&(l.textContent=Go(u)),!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)=>(_(p.updatedAt)||0)-(_(d.updatedAt)||0)),s.innerHTML=c.map(d=>{let p=_(d.updatedAt),m=p!=null?new Date(p).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):"";return`
|
|
72
72
|
<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 ${f.sessionId===d.sessionId?"border-primary bg-primary/5":""}"
|
|
73
73
|
data-session-id="${(0,n.esc)(d.sessionId)}"
|
|
74
74
|
data-session-cwd="${(0,n.esc)(d.cwd||"")}"
|
|
@@ -81,7 +81,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
81
81
|
<div class="text-[10px] text-base-content/40 truncate mt-0.5">${(0,n.esc)(d.projectName||Ye(d.cwd)||"No workspace")}</div>
|
|
82
82
|
</div>
|
|
83
83
|
<div class="text-[9px] text-base-content/45 font-mono whitespace-nowrap bg-base-300 px-1.5 py-0.5 rounded">${m}</div>
|
|
84
|
-
</div>`}).join("")}function
|
|
84
|
+
</div>`}).join("")}function zo(e,t){return[...En(e)].filter(s=>s&&s.sessionId).sort((s,o)=>(_(o.updatedAt)||0)-(_(s.updatedAt)||0)).slice(0,t)}function Si(e){let t=(0,n.$)("recent-sessions-list");if(!t)return;let s=zo(e,6);if(!s.length){t.innerHTML='<div class="col-span-full text-center text-xs text-base-content/40 py-4">No recent sessions</div>';return}t.innerHTML=s.map(o=>{let a=pt(o.updatedAt);return`
|
|
85
85
|
<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 ${f.sessionId===o.sessionId?"border-primary bg-primary/5":""}"
|
|
86
86
|
data-session-id="${(0,n.esc)(o.sessionId)}"
|
|
87
87
|
data-session-cwd="${(0,n.esc)(o.cwd||"")}"
|
|
@@ -94,7 +94,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
94
94
|
<div class="text-[10px] text-base-content/40 truncate mt-1">${(0,n.esc)(o.projectName||Ye(o.cwd)||"No workspace")}</div>
|
|
95
95
|
</div>
|
|
96
96
|
<div class="text-[9px] text-base-content/40 whitespace-nowrap self-start mt-0.5">${a}</div>
|
|
97
|
-
</div>`}).join("")}function
|
|
97
|
+
</div>`}).join("")}function gt(){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 fs(){let e=(0,n.$)("recent-menu"),t=(0,n.$)("topbar");if(!e||!t)return;let s=t.getBoundingClientRect(),a=Math.round(s.bottom+6),i=window.matchMedia("(max-width: 640px)").matches?8:null;if(e.style.top=`${a}px`,i!=null)e.style.left=`${i}px`,e.style.right=`${i}px`;else{let u=(0,n.$)("btn-recent-sessions")?.getBoundingClientRect();if(u){let l=Math.min(320,window.innerWidth-16),d=u.left;d+l>window.innerWidth-8&&(d=window.innerWidth-l-8),d<8&&(d=8),e.style.left=`${Math.round(d)}px`,e.style.right="auto",e.style.width=`${l}px`}}let r=Math.max(160,window.innerHeight-a-12);e.style.maxHeight=`${Math.min(r,Math.round(window.innerHeight*.7))}px`}function Li(e){let t=(0,n.$)("recent-menu");t&&(Mi(e??ve()),t.classList.remove("hidden"),t.classList.add("recent-menu-open"),fs(),(0,n.$)("recent-menu-backdrop")?.classList.remove("hidden"))}function Jo(e){let t=(0,n.$)("recent-menu");t&&(t.classList.contains("hidden")?Li(e):gt())}function Mi(e){let t=(0,n.$)("recent-menu-list"),s=(0,n.$)("recent-menu-empty"),o=(0,n.$)("recent-menu-count");if(!t)return;let a=zo(e??ve(),$i);if(o&&(o.textContent=a.length?`${a.length}`:""),!a.length){t.innerHTML="",s?.classList.remove("hidden");return}s?.classList.add("hidden"),t.innerHTML=a.map(i=>{let r=pt(i.updatedAt),c=f.sessionId===i.sessionId&&(!i.machineId||!f.machineId||i.machineId===f.machineId),u=i.machineId?`<span class="text-[9px] font-mono text-base-content/35 truncate max-w-[4.5rem]" title="${(0,n.esc)(i.machineId)}">@${(0,n.esc)(i.machineId)}</span>`:"";return`
|
|
98
98
|
<button type="button"
|
|
99
99
|
class="recent-menu-item w-full text-left px-2 py-1.5 rounded-md flex items-start gap-2
|
|
100
100
|
${c?"bg-primary/15 text-primary":"hover:bg-base-200"}"
|
|
@@ -113,7 +113,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
113
113
|
${u}
|
|
114
114
|
${c?'<span class="text-[9px] opacity-70">\u5F53\u524D</span>':""}
|
|
115
115
|
</span>
|
|
116
|
-
</button>`}).join("")}function
|
|
116
|
+
</button>`}).join("")}function Ko(e){qt=e}function ms(e){tt+=e,tt<0?(tt=11,Tn--):tt>11&&(tt=0,Tn++)}var Tn,tt,qt,$i,hs=X(()=>{C();I();jt();Tn=new Date().getFullYear(),tt=new Date().getMonth(),qt=null;$i=15});function Vo(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}function Ti(){let e=parseInt(te.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 ye({waitFresh:e=!0}={}){let t=Vo(await yn());if(t.length){let o=M.peek();if(k.peek()&&o){let a=t.filter(i=>!i.machineId||i.machineId===o);E.value=a.length?a:t}else E.value=t}let s=async()=>{let o=Ti(),a=await h("GET",o,void 0,void 0,{etag:!0});if(a===Zn)return E.peek();let i=Vo(a);return E.value=i,Lo(i),i};if(e||!t.length)try{await s()}catch(o){if(!t.length){let a=(0,n.$)("session-list");a&&(a.innerHTML=`<div class="px-3 py-3 text-xs text-error">${(0,n.esc)(o.message)}</div>`)}}else s().catch(()=>{})}async function Wt({waitFresh:e=!0}={}){let t=await Mo();t&&(P.value=t);let s=async()=>{let o=await h("GET","/api/workspaces");P.value=o,Bt(o)};if(e||!t)try{await s()}catch{}else s().catch(()=>{})}function Qo(e,{showProject:t=!1}={}){let s=f.sessionId===e.sessionId&&(f.agent||S.peek())===(e.agent||"claude"),o=v.peek()?.[B(e.agent,e.sessionId,e.machineId)]||{},a=!!(o.title&&String(o.title).trim()),i=e.snippet&&N.peek()?e.snippet:Ge(e),r=!!o.favorite,c=!!o.hidden,u=!!(o.notes&&String(o.notes).trim()),l=Number(e.turnCount)||0,d=l>0&&l<=Vn,p=t?`<div class="text-[10px] text-base-content/40 font-mono truncate" title="${(0,n.esc)(e.cwd||"")}">${(0,n.esc)(e.projectName||Ye(e.cwd)||"\u2014")}</div>`:"",m=[d?`<span class="session-thin-badge" title="Only ${l} turn${l===1?"":"s"}">thin\xB7${l}</span>`:"",a?`<span class="session-renamed-badge" title="Custom name (original: ${(0,n.esc)(e.display||"")})">renamed</span>`:"",c?'<span class="session-hidden-badge" title="Hidden">hidden</span>':"",u?`<span class="session-note-dot" title="${(0,n.esc)(o.notes)}">\u{1F4DD}</span>`:""].filter(Boolean).join(""),b=e.machineId?`<span class="text-[9px] px-1 py-0.5 rounded bg-base-300 text-base-content/50 font-mono flex-shrink-0" title="Machine">${(0,n.esc)(e.machineId)}</span>`:"",g=a?`${i}
|
|
117
117
|
(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
|
|
118
118
|
${s?"border-primary bg-primary/5":"border-transparent"} ${r?"session-fav":""} ${c?"session-hidden-row":""} ${d?"session-thin":""}"
|
|
119
119
|
data-session-id="${(0,n.esc)(e.sessionId)}"
|
|
@@ -149,11 +149,11 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
149
149
|
title="${c?"Unhide session":"Hide session"}">${c?"\u{1F441}":"\u{1F648}"}</button>
|
|
150
150
|
</div>
|
|
151
151
|
${p}
|
|
152
|
-
${m||
|
|
152
|
+
${m||b?`<div class="flex items-center gap-1 mt-0.5 flex-wrap">${b}${m}</div>`:""}
|
|
153
153
|
</div>
|
|
154
154
|
<span class="text-[9px] text-base-content/30 flex-shrink-0 mt-0.5">${pt(e.updatedAt)}</span>
|
|
155
155
|
</div>
|
|
156
|
-
</div>`}async function
|
|
156
|
+
</div>`}async function Gt(){try{let e=await h("GET","/api/agents");it.value=e;let t=S.peek()||"claude",s=fe(t),o=$.peek();if(o&&!s.some(a=>a.value===o)){let a=re(t);$.value=a,localStorage.setItem("model",a)}return we(),e}catch(e){return console.warn("[agents] failed to load model list",e),null}}function bs(){let e=(0,n.$)("sel-effort");if(!e)return;let t=S.peek()||"claude",s=$.peek(),o=Et(t,s),a=pe.peek()||"",i=['<option value="">effort: off</option>'].concat(o.map(r=>`<option value="${(0,n.esc)(r)}" ${r===a?"selected":""}>${(0,n.esc)(r)}</option>`));e.innerHTML=i.join(""),a&&!o.includes(a)?(pe.value="",e.value=""):e.value=a}function we(){let e=(0,n.$)("sel-model");if(!e)return;let t=S.peek()||"claude",s=fe(t),o=$.peek();if(o&&!s.some(i=>i.value===o)&&(s=[{value:o,label:`${o} \u2605`,custom:!0},...s]),e.innerHTML=s.map(i=>`<option value="${(0,n.esc)(i.value)}" ${i.value===o?"selected":""}>${(0,n.esc)(i.label)}</option>`).join(""),s.some(i=>i.value===o))e.value=o;else{let i=re(t)||s[0]?.value;$.value=i,localStorage.setItem("model",i),e.value=i,o=i}let a=(0,n.$)("sel-agent");a&&(a.value=t),bs()}function xs({editCurrent:e=!1}={}){let t=S.peek()||"claude",s=e&&$.peek()||"",o=e?`Edit model id for ${t}:`:`Add model id for ${t} (saved in this browser):`,a=window.prompt(o,s);if(a==null)return;let i=a.trim();i&&(e&&s&&s!==i&&tn(t).includes(s)&&Qn(t,s),Tt(t,i),$.value=i,localStorage.setItem("model",i),we())}function Ei(e){if(!Array.isArray(e)||!e.length)return`<div class="px-3 py-6 text-center text-xs text-base-content/40">
|
|
157
157
|
No projects in this range.<br>
|
|
158
158
|
<span class="text-base-content/30">Try \u201CAll\u201D time or another agent.</span>
|
|
159
159
|
</div>`;let t=ot.value,s=at.value,o=!!N.value.trim(),a=e[0]?.cwd||"(no path)";return e.map(i=>{let r=i.cwd||"(no path)",c=!1;s.has(r)?c=!1:t.has(r)?c=!0:c=o||r===a||e.length<=3;let u=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=`
|
|
@@ -167,20 +167,20 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
167
167
|
</div>
|
|
168
168
|
<div class="flex items-center gap-1.5 mt-0.5 pl-4">
|
|
169
169
|
<span class="text-[10px] text-base-content/35 font-mono truncate flex-1" title="${(0,n.esc)(i.cwd||"")}">${(0,n.esc)(Ye(i.cwd))}</span>
|
|
170
|
-
<span class="flex items-center gap-0.5 flex-shrink-0">${
|
|
170
|
+
<span class="flex items-center gap-0.5 flex-shrink-0">${ao(i.agents)}</span>
|
|
171
171
|
</div>
|
|
172
172
|
${u&&!c?`<div class="pl-4 mt-0.5 text-[10px] text-base-content/45 truncate" title="${(0,n.esc)(u)}">\u21B3 ${(0,n.esc)(u)}</div>`:""}
|
|
173
|
-
</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>`:"",
|
|
173
|
+
</div>`,p=i.sessions.slice(0,40),m=i.sessions.length>40?`<div class="px-3 py-1 text-[10px] text-base-content/30">+${i.sessions.length-40} more</div>`:"",b=c?`<div class="pb-1 border-b border-base-300/30">${p.map(g=>Qo(g)).join("")}${m}</div>`:"";return d+b}).join("")}function Ii(e){if(!Array.isArray(e)||!e.length)return`<div class="px-3 py-6 text-center text-xs text-base-content/40">
|
|
174
174
|
No recent activity.<br>
|
|
175
175
|
<span class="text-base-content/30">Widen the time range or clear filters.</span>
|
|
176
176
|
</div>`;let t=new Map;for(let s of e){let a=(s.updatedAt?new Date(s.updatedAt):new Date).toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric"});t.has(a)||t.set(a,[]),t.get(a).push(s)}return[...t.entries()].map(([s,o])=>`
|
|
177
177
|
<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>
|
|
178
|
-
${o.map(a=>
|
|
179
|
-
`).join("")}function
|
|
180
|
-
<div class="md">${
|
|
178
|
+
${o.map(a=>Qo(a,{showProject:!0})).join("")}
|
|
179
|
+
`).join("")}function Zo(){let e=Le.value,t=Array.isArray(Re.value)?Re.value:[],s=Array.isArray(ze.value)?ze.value:[];return e==="timeline"?Ii(t):Ei(s)}function ea(){document.querySelectorAll("[data-view]").forEach(i=>{let r=i.dataset.view===Le.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===Q.peek())});let e=(0,n.$)("time-range");e&&e.value!==te.peek()&&(e.value=te.peek());let t=(0,n.$)("search-status");if(!t)return;let s=ue.peek(),o=Array.isArray(s?.results)?s.results:null,a=(N.peek()||"").trim();if(Me.peek())t.classList.remove("hidden"),t.textContent="Searching content\u2026";else if(a&&o)t.classList.remove("hidden"),t.textContent=`${o.length} hit${o.length===1?"":"s"} \xB7 ${te.peek()==="0"?"all time":te.peek()+"d"}${s.deep===!1?"":" (incl. content)"}`;else if(a)t.classList.remove("hidden"),t.textContent="Local filter only \u2014 type to deep-search";else{let i=Re.peek(),r=ze.peek(),c=Array.isArray(i)?i.length:0,u=Array.isArray(r)?r.length:0;t.classList.remove("hidden"),t.textContent=Le.peek()==="projects"?`${u} project${u===1?"":"s"} \xB7 ${c} session${c===1?"":"s"}`:`${c} recent session${c===1?"":"s"}`}}async function gs(e){let t=(e||"").trim();if(!t){ue.value=null,Me.value=!1;return}Me.value=!0;try{let s=new URLSearchParams({q:t,days:te.peek()||"14",limit:"50",deep:"1"});Q.peek()&&Q.peek()!=="all"&&s.set("agent",Q.peek());let o=await h("GET",`/api/activity?${s}`);N.peek().trim()===t&&(ue.value={q:t.toLowerCase(),results:o.results||[],deep:!0})}catch(s){N.peek().trim()===t&&(ue.value={q:t.toLowerCase(),results:[],error:s.message})}finally{Me.value=!1}}function In(e){clearTimeout(Yo);let t=(e||"").trim();if(!t){ue.value=null,Me.value=!1;return}Yo=setTimeout(()=>gs(t),350)}function Xo(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 vs(){let e=(0,n.$)("memory-area");if(e){if(!f.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=new URLSearchParams({agent:f.agent||S.peek()||"claude"}),s=await h("GET",`/api/sessions/${f.sessionId}/memory?${t}`),o=[];s.index&&o.push(`<div class="mb-4"><div class="text-[11px] uppercase tracking-wide text-base-content/40 mb-1">Index (MEMORY.md)</div>
|
|
180
|
+
<div class="md">${Xo(s.index)}</div></div>`);for(let a of s.files||[])o.push(`<div class="mb-3 border border-base-300 rounded-lg overflow-hidden">
|
|
181
181
|
<div class="px-3 py-1.5 bg-base-300/50 text-xs font-mono text-base-content/70">${(0,n.esc)(a.name)}</div>
|
|
182
|
-
<div class="px-3 py-2 md">${
|
|
183
|
-
</div>`);o.length||o.push('<div class="text-base-content/40 text-xs">No memory saved for this project yet.</div>'),e.innerHTML=`<div class="p-4">${o.join("")}</div>`}catch(t){e.innerHTML=`<div class="p-4 text-error text-xs">${(0,n.esc)(t?.message??String(t))}</div>`}}}var
|
|
182
|
+
<div class="px-3 py-2 md">${Xo(a.content)}</div>
|
|
183
|
+
</div>`);o.length||o.push('<div class="text-base-content/40 text-xs">No memory saved for this project yet.</div>'),e.innerHTML=`<div class="p-4">${o.join("")}</div>`}catch(t){e.innerHTML=`<div class="p-4 text-error text-xs">${(0,n.esc)(t?.message??String(t))}</div>`}}}var Yo,vt=X(()=>{C();I();K();wn();jt();Yo=null});function ta(e,t){Cn=e||"",An=t||""}async function na(e){let t=(0,n.$)("project-notes-bar");if(t)try{let s=await h("GET",`/api/projects/notes?root=${encodeURIComponent(e)}`);Cn=s.goal||"",An=s.notes||"",yt(),t.style.display="flex"}catch(s){console.error("Error fetching project notes:",s),t.style.display="none"}}function yt(){let e=(0,n.$)("project-notes-bar");if(!e)return;let t=Cn||"No goal yet \u2014 click Edit",s=An||"";e.innerHTML=`
|
|
184
184
|
<div class="flex items-start gap-2 w-full">
|
|
185
185
|
<div class="flex-1 min-w-0">
|
|
186
186
|
<div class="truncate">
|
|
@@ -191,7 +191,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
191
191
|
</div>
|
|
192
192
|
<button id="btn-edit-project-notes" class="btn btn-ghost btn-xs px-1.5 hover:bg-base-300 flex-shrink-0">Edit</button>
|
|
193
193
|
</div>
|
|
194
|
-
`}function
|
|
194
|
+
`}function sa(){let e=(0,n.$)("project-notes-bar");e&&(e.innerHTML=`
|
|
195
195
|
<div class="flex flex-col gap-1.5 w-full">
|
|
196
196
|
<div class="flex items-center gap-2">
|
|
197
197
|
<span class="text-[10px] font-bold text-base-content/40 uppercase w-12 flex-shrink-0">Goal</span>
|
|
@@ -208,7 +208,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
208
208
|
<button id="btn-cancel-project-notes" class="btn btn-ghost btn-xs px-2">Cancel</button>
|
|
209
209
|
</div>
|
|
210
210
|
</div>
|
|
211
|
-
`,(0,n.$)("project-goal-input")?.focus())}async function
|
|
211
|
+
`,(0,n.$)("project-goal-input")?.focus())}async function zt(){try{let e=await h("GET","/api/sessions/meta");v.value=e||{}}catch(e){console.warn("session meta load failed",e)}}function ce(){let e=(0,n.$)("session-notes-bar");if(!e)return;let t=f.sessionId,s=f.agent||S.peek()||"claude";if(!t){e.style.display="none",e.innerHTML="";return}if(e.querySelector(".session-rename-input"))return;let o=rt(s,t),a=(o.notes||"").trim(),i=!!o.favorite,r=!!o.hidden,u=(o.title||"").trim()||t.slice(0,8);e.style.display="flex",e.innerHTML=`
|
|
212
212
|
<div class="flex-1 min-w-0 flex items-center gap-2">
|
|
213
213
|
<button type="button" class="session-fav-btn ${i?"is-fav":""}" data-fav-toggle="1"
|
|
214
214
|
data-fav-session-id="${(0,n.esc)(t)}" data-fav-session-agent="${(0,n.esc)(s)}"
|
|
@@ -228,12 +228,12 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
228
228
|
id="session-notes-text" title="${(0,n.esc)(a||"Add a note for this session")}">${(0,n.esc)(a||"No session note")}</span>
|
|
229
229
|
</div>
|
|
230
230
|
<button id="btn-edit-session-notes" class="btn btn-ghost btn-xs px-1.5">Note</button>
|
|
231
|
-
`}function
|
|
231
|
+
`}function oa(){let e=(0,n.$)("session-notes-bar");if(!e||!f.sessionId)return;let t=f.agent||S.peek()||"claude",s=rt(t,f.sessionId);e.innerHTML=`
|
|
232
232
|
<input id="session-notes-input" type="text" class="input input-xs input-bordered flex-1 text-xs"
|
|
233
233
|
placeholder="Note for this session\u2026" value="${(0,n.esc)(s.notes||"")}">
|
|
234
234
|
<button id="btn-save-session-notes" class="btn btn-primary btn-xs px-2">Save</button>
|
|
235
235
|
<button id="btn-cancel-session-notes" class="btn btn-ghost btn-xs px-2">Cancel</button>
|
|
236
|
-
`;let o=(0,n.$)("session-notes-input");o?.focus(),o?.select()}function jn(){return{favorite:!1,notes:"",title:"",hidden:!1}}function Dn(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
|
|
236
|
+
`;let o=(0,n.$)("session-notes-input");o?.focus(),o?.select()}function jn(){return{favorite:!1,notes:"",title:"",hidden:!1}}function Dn(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 aa(e){return!e?.favorite&&!e?.hidden&&!(e?.notes||"").trim()&&!(e?.title||"").trim()}async function ia(e,t,{machineId:s}={}){let o=s||f.machineId||null,a=B(t,e,o),i=v.peek()?.[a]||jn(),r=!i.favorite;v.value={...v.peek(),[a]:{...i,favorite:r,updatedAt:Date.now()}};try{let c=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,favorite:r,machineId:o||void 0},void 0,{machineId:o||void 0});v.value={...v.peek(),[a]:Dn(i,{favorite:c.favorite??r,notes:c.notes,title:c.title,hidden:c.hidden})}}catch(c){v.value={...v.peek(),[a]:i},alert(`Favorite failed: ${c.message}`)}f.sessionId===e&&ce()}async function ra(e,t,{machineId:s}={}){if(!e)return!1;let o=s||f.machineId||null,a=B(t,e,o),i=v.peek()?.[a]||jn(),r=!i.hidden;v.value={...v.peek(),[a]:{...i,hidden:r,updatedAt:Date.now()}};try{let c=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,hidden:r,machineId:o||void 0},void 0,{machineId:o||void 0}),u=Dn(i,{favorite:c.favorite,notes:c.notes,title:c.title,hidden:c.hidden??r});if(aa(u)){let l={...v.peek()};delete l[a],v.value=l}else v.value={...v.peek(),[a]:u}}catch(c){return v.value={...v.peek(),[a]:i},alert(`Hide failed: ${c.message}`),!1}return f.sessionId===e&&ce(),!0}async function ys(e,t,s,{machineId:o}={}){let a=o||f.machineId||null,i=B(t,e,a),r=v.peek()?.[i]||jn();try{let c=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,notes:s,machineId:a||void 0},void 0,{machineId:a||void 0});v.value={...v.peek(),[i]:Dn(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 Ci(e,t,s,{machineId:o}={}){if(!e)return!1;let a=o||f.machineId||null,i=B(t,e,a),r=v.peek()?.[i]||jn(),c=String(s||"").trim().slice(0,200);v.value={...v.peek(),[i]:{...r,title:c,updatedAt:Date.now()}};try{let u=await h("PUT","/api/sessions/meta",{sessionId:e,agent:t,title:c,machineId:a||void 0},void 0,{machineId:a||void 0}),l=Dn(r,{favorite:u.favorite,notes:u.notes,title:u.title!==void 0?u.title:c,hidden:u.hidden});if(aa(l)){let d={...v.peek()};delete d[i],v.value=d}else v.value={...v.peek(),[i]:l}}catch(u){return v.value={...v.peek(),[i]:r},alert(`Rename failed: ${u.message}`),!1}return f.sessionId===e&&ce(),!0}function ws({sessionId:e,agent:t="claude",machineId:s=null,fallbackDisplay:o="",mountEl:a}={}){if(!e||!a)return;document.querySelectorAll(".session-rename-input").forEach(m=>{m.dispatchEvent(new CustomEvent("session-rename-cancel",{bubbles:!0}))});let r=(rt(t,e,s).title||"").trim()||o||e.slice(0,8),c=a.innerHTML,u=a.className;a.classList.add("session-rename-active"),a.innerHTML=`<input type="text" class="session-rename-input input input-xs input-bordered w-full min-w-0 text-xs font-mono"
|
|
237
237
|
value="${(0,n.esc)(r)}"
|
|
238
238
|
placeholder="Session name (empty = original)"
|
|
239
239
|
maxlength="200"
|
|
@@ -241,8 +241,8 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
241
241
|
data-rename-session-id="${(0,n.esc)(e)}"
|
|
242
242
|
data-rename-session-agent="${(0,n.esc)(t)}"
|
|
243
243
|
data-rename-session-machine="${(0,n.esc)(s||"")}"
|
|
244
|
-
autocomplete="off" spellcheck="false" />`;let l=a.querySelector(".session-rename-input");if(!l)return;let d=!1,p=async m=>{if(d)return;d=!0;let
|
|
245
|
-
`):String(L.content??"");
|
|
244
|
+
autocomplete="off" spellcheck="false" />`;let l=a.querySelector(".session-rename-input");if(!l)return;let d=!1,p=async m=>{if(d)return;d=!0;let b=m?l.value:r;if(a.className=u,!m){a.innerHTML=c;return}await Ci(e,t,b,{machineId:s}),document.querySelectorAll(".session-rename-input").forEach(g=>g.remove()),f.sessionId===e&&ce(),v.value={...v.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 Cn,An,Jt=X(()=>{C();I();K();Cn="",An=""});var ca={};Os(ca,{goHome:()=>Pn,openProject:()=>ks,resumeSession:()=>ke,switchTab:()=>He});function Hn(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 ks(e){let t=e?.path||"";(0,n.batch)(()=>{y.value=e,O.value=t,t&&(F.value=t,J.value=t,A.value="",U.value=null)}),f.sessionId=null,(0,n.$)("topbar-project").textContent=t||"Project";let s=(0,n.$)("files-root-input");s&&t&&(s.value=t);let o=(0,n.$)("git-root-input");o&&t&&(o.value=t),Hn(e?.machineId||M.peek()||f.machineId),(0,n.$)("welcome").classList.add("hidden");let a=(0,n.$)("project-view");a.classList.remove("hidden"),a.style.display="flex",ft(),je(),He("chat")}function Pn(){y.value=null,O.value=null,F.value="",J.value="",A.value="",U.value=null,f.sessionId=null,Hn(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="",nt(ve()));let s=(0,n.$)("project-view");s&&(s.classList.add("hidden"),s.style.display="none"),bn("/")}async function ke(e,t,s,o,a,i={}){let r=i.tab&&["chat","files","git","shell","memory"].includes(i.tab)?i.tab:"chat",c=i.skipHistory??(r!=="chat"&&r!=="memory"),u=E.peek().find(w=>w.sessionId===e&&(!a||w.machineId===a||!w.machineId)),l=Je(),d=l?.sessionId===e?l:null,p=o||u?.agent||d?.agent||"claude",m=a||u?.machineId||d?.machineId||M.peek()||null,b=t||u?.cwd||d?.cwd||null,g=s||u?.configDir||d?.configDir||null;if(m&&m!==f.machineId){Z(m);try{f.ws?.close()}catch{}f.ws=null}f.sessionId=e,f.configDir=g,f.agent=p,me(p),we();let W=b;la(W,m,e),je(),W&&h("POST","/api/resolve-path",{path:W},void 0,{machineId:m||void 0}).then(w=>{f.sessionId!==e||!w?.path||w.path===W||(W=w.path,la(W,m,e),es({sessionId:e,cwd:W}))}).catch(()=>{}),ft(),He(r);{let w=E.peek();E.value=Array.isArray(w)?[...w]:[]}es({sessionId:e,cwd:W||b,configDir:g,agent:p,machineId:m,tab:r});let Fe=R[p]||p,de=`${m||""}:${p}:${e}`,qe=(w,G,We={})=>{if(f.sessionId!==e)return;if((0,n.$)("messages").innerHTML="",!w.length){x(`${Fe} \xB7 ${e.slice(0,8)}\u2026 \u2014 no history`);return}le();let z=40,ae=0,$t=()=>{if(f.sessionId!==e)return;let en=Math.min(ae+z,w.length);for(;ae<en;ae++){let L=w[ae],Ps=_(L.ts??L.timestamp),Gn=L.type||(L.role?"text":null);if(Gn==="text"||L.role&&L.content!=null&&!L.name){(L.role==="assistant"||L.role==="user")&&le();let Ns=typeof L.content=="string"?L.content:Array.isArray(L.content)?L.content.map(Aa=>Aa?.text||"").filter(Boolean).join(`
|
|
245
|
+
`):String(L.content??"");Ns&&Qe(L.role==="user"?"user":"assistant",L.role==="user"?"You":Fe,Ns,{ts:Ps})}else Gn==="tool_use"||L.name?os({name:L.name||"tool",input:L.input??L.arguments??{}},{ts:Ps}):(Gn==="token_usage"||L.usage)&&(le(),ut(L.usage||L))}if(ae<w.length){requestAnimationFrame($t);return}le(),G&&ss(G);let St=w.filter(L=>L.type==="token_usage").length||w.filter(L=>L.role==="user").length,Lt=We.truncated?` (showing last ${w.length} of ${We.total||"?"})`:"";x(`\u2500\u2500 ${Fe} history \xB7 ${St} turn${St!==1?"s":""}${Lt} \u2500\u2500`)};$t()},$e=async()=>{let w=_n.get(de);if(w&&w.msgs?.length&&Date.now()-w.at<Ai){qe(w.msgs,w.context,w.meta);return}x(`Loading ${Fe} history\u2026`);try{let G=m||M.peek()||f.machineId||null;if(k.peek()&&!G)throw new Error("\u672A\u9009\u62E9\u673A\u5668\uFF0C\u65E0\u6CD5\u52A0\u8F7D\u5386\u53F2");G&&f.machineId!==G&&Z(G);let We=async St=>{let Lt=new URLSearchParams({tail:"0",compact:"1"});return St&&Lt.set("agent",St),G&&Lt.set("machine",G),h("GET",`/api/sessions/${e}/messages?${Lt}`,void 0,void 0,{machineId:G||void 0,dedupe:!1})},z=await We(p),ae=Array.isArray(z)?z:z?.messages||[];!ae.length&&p&&(z=await We(null),ae=Array.isArray(z)?z:z?.messages||[]);let $t=Array.isArray(z)?null:z?.context||null,en=Array.isArray(z)?{}:{truncated:z?.truncated,total:z?.total};ae.length?_n.set(de,{msgs:ae,context:$t,meta:en,at:Date.now()}):_n.delete(de),qe(ae,$t,en)}catch(G){if(f.sessionId!==e)return;_n.delete(de),(0,n.$)("messages").innerHTML="",x(`${Fe} \xB7 ${e.slice(0,8)}\u2026 (history unavailable: ${G.message})`)}};c?$e().catch(()=>{}):(await new Promise(w=>requestAnimationFrame(w)),$e().catch(()=>{})),xn(),ce()}function la(e,t,s){if(e){let o=e.split("/").filter(Boolean).pop()||e;(0,n.batch)(()=>{y.value={id:o,name:o,path:e,machineId:t},O.value=e,F.value=e,J.value=e,A.value="",U.value=null}),(0,n.$)("topbar-project").textContent=t?`${e} @${t}`:e;let a=(0,n.$)("files-root-input");a&&(a.value=e);let i=(0,n.$)("git-root-input");i&&(i.value=e),Hn(t),(0,n.$)("welcome")?.classList.add("hidden");let r=(0,n.$)("project-view");r&&(r.classList.remove("hidden"),r.style.display="flex",r.style.flexDirection="column",r.style.flex="1",r.style.minHeight="0",r.style.overflow="hidden")}else{(0,n.$)("welcome")?.classList.add("hidden");let o=(0,n.$)("project-view");o&&(o.classList.remove("hidden"),o.style.display="flex",o.style.flexDirection="column",o.style.flex="1",o.style.minHeight="0"),Hn(t)}}function He(e){j.value=e}var _n,Ai,Kt=X(()=>{C();I();K();sn();mt();gn();vt();Jt();hs();_n=new Map,Ai=180*1e3});I();K();C();I();K();var dt=null;function Ys(){return window.matchMedia("(display-mode: standalone)").matches||window.navigator.standalone===!0||document.referrer.includes("android-app://")}function Xs(){document.getElementById("btn-pwa-install")?.classList.remove("hidden")}function Qs(){Ys()&&document.documentElement.classList.add("pwa-standalone"),window.addEventListener("beforeinstallprompt",s=>{s.preventDefault(),dt=s,document.dispatchEvent(new CustomEvent("pwa-installable")),Xs()}),window.addEventListener("appinstalled",()=>{dt=null,document.getElementById("btn-pwa-install")?.classList.add("hidden")});let e=/iPad|iPhone|iPod/.test(navigator.userAgent)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1;if(!Ys()&&(e||/Android/i.test(navigator.userAgent))&&requestAnimationFrame(()=>Xs()),!("serviceWorker"in navigator))return;let t=()=>{navigator.serviceWorker.register("/sw.js",{scope:"/"}).then(s=>{s.addEventListener("updatefound",()=>{let o=s.installing;o&&o.addEventListener("statechange",()=>{o.state==="installed"&&navigator.serviceWorker.controller&&console.info("[pwa] New version ready \u2014 reload to apply")})})}).catch(s=>console.warn("[pwa] SW register failed",s))};document.readyState==="complete"?setTimeout(t,0):window.addEventListener("load",()=>setTimeout(t,0))}async function Zs(){if(!dt)return!1;dt.prompt();let e=await dt.userChoice.catch(()=>null);return dt=null,document.getElementById("btn-pwa-install")?.classList.add("hidden"),e?.outcome==="accepted"}sn();mt();gn();C();K();I();wn();function To(){document.getElementById("root").insertAdjacentHTML("beforeend",`
|
|
246
246
|
<dialog id="modal-settings" class="modal">
|
|
247
247
|
<div class="modal-box max-w-lg">
|
|
248
248
|
<h3 class="font-bold text-base mb-4">\u2699\uFE0F Settings \u2014 Workspaces</h3>
|
|
@@ -261,15 +261,15 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
261
261
|
</div>
|
|
262
262
|
</div>
|
|
263
263
|
<form method="dialog" class="modal-backdrop"><button>close</button></form>
|
|
264
|
-
</dialog>`),
|
|
264
|
+
</dialog>`),kn(),document.getElementById("ws-add-btn").addEventListener("click",ls),document.getElementById("ws-new-name").addEventListener("keydown",e=>{e.key==="Enter"&&ls()}),document.getElementById("ws-new-dir").addEventListener("keydown",e=>{e.key==="Enter"&&ls()})}function kn(){let e=(0,n.$)("ws-list");if(!e)return;let t=P.peek();if(!t.length){e.innerHTML='<div class="text-xs text-base-content/40">No workspaces configured</div>';return}e.innerHTML=t.map(s=>`
|
|
265
265
|
<div class="flex items-center gap-2 px-3 py-2 bg-base-200 rounded-lg">
|
|
266
266
|
<div class="flex-1 min-w-0">
|
|
267
267
|
<div class="text-sm font-medium">${(0,n.esc)(s.name)}</div>
|
|
268
268
|
<div class="text-xs font-mono text-base-content/50 truncate">${(0,n.esc)(s.configDir)}</div>
|
|
269
269
|
</div>
|
|
270
270
|
${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>'}
|
|
271
|
-
</div>`).join(""),e.querySelectorAll("[data-ws-delete]").forEach(s=>{s.addEventListener("click",()=>
|
|
272
|
-
`);c=p.pop()||"";for(let m of p)if(m.startsWith("event:"))u=m.slice(6).trim();else if(m.startsWith("data:")){let
|
|
271
|
+
</div>`).join(""),e.querySelectorAll("[data-ws-delete]").forEach(s=>{s.addEventListener("click",()=>pi(s.dataset.wsDelete))})}async function ls(){let e=(0,n.$)("ws-new-name").value.trim(),t=(0,n.$)("ws-new-dir").value.trim(),s=(0,n.$)("ws-error");if(s.classList.add("hidden"),!e||!t){s.textContent="Name and path are required",s.classList.remove("hidden");return}try{let o=await h("POST","/api/workspaces",{name:e,configDir:t});P.value=[...P.peek(),o],Bt(P.peek()),(0,n.$)("ws-new-name").value="",(0,n.$)("ws-new-dir").value="",kn()}catch(o){s.textContent=o.message,s.classList.remove("hidden")}}async function pi(e){try{await h("DELETE",`/api/workspaces/${e}`),P.value=P.peek().filter(t=>t.id!==e),Bt(P.peek()),kn()}catch(t){alert(t.message)}}function Eo(){kn(),(0,n.$)("modal-settings")?.showModal()}C();K();I();var Mn=!1,Oe="chat",ht=!1,q=null,ee=null,Ze=[],Io=0,$n=null,cs=localStorage.getItem("ai_last_auto_report")||"",Ln=[],Do="",Ue="ma_last_session_id";function bt(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 xt(e){!e||typeof hljs>"u"||e.querySelectorAll("pre code").forEach(t=>{try{hljs.highlightElement(t)}catch{}})}async function ds(e,t,s){let o=lt({"Content-Type":"application/json"}),a=await fetch(e,{method:"POST",headers:o,body:JSON.stringify(t||{})});if(!a.ok){let l=await a.json().catch(()=>({}));throw new Error(l.error||`HTTP ${a.status}`)}let i=a.body.getReader(),r=new TextDecoder,c="",u="message";for(;;){let{done:l,value:d}=await i.read();if(l)break;c+=r.decode(d,{stream:!0});let p=c.split(`
|
|
272
|
+
`);c=p.pop()||"";for(let m of p)if(m.startsWith("event:"))u=m.slice(6).trim();else if(m.startsWith("data:")){let b=m.slice(5).trim();if(!b)continue;let g;try{g=JSON.parse(b)}catch{continue}s[u]?.(g),s.any?.(u,g),u="message"}else m.trim()===""&&(u="message")}}function ui(){return`
|
|
273
273
|
<div id="meta-agent-panel" class="meta-agent-panel hidden" aria-hidden="true">
|
|
274
274
|
<div class="meta-agent-backdrop" data-ma-close="1"></div>
|
|
275
275
|
<div class="meta-agent-sheet">
|
|
@@ -398,17 +398,17 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
398
398
|
</div>
|
|
399
399
|
</div>
|
|
400
400
|
</div>
|
|
401
|
-
</div>`}function oe(e){
|
|
401
|
+
</div>`}function oe(e){Oe=e;let t=(0,n.$)("ma-mode-chat"),s=(0,n.$)("ma-mode-history"),o=(0,n.$)("ma-mode-report"),a=(0,n.$)("ma-mode-config");for(let[r,c]of[[t,"chat"],[s,"history"],[o,"report"],[a,"config"]]){if(!r)continue;let u=e===c;r.classList.toggle("hidden",!u),r.classList.toggle("flex",u)}let i=(r,c)=>{let u=(0,n.$)(r);u&&(u.classList.toggle("border-primary/40",c),u.classList.toggle("text-primary",c))};i("ma-btn-chat",e==="chat"),i("ma-btn-history",e==="history"),i("ma-btn-report",e==="report"),e==="history"&&et()}function Ot(){let e=(0,n.$)("ma-session-title"),t=(0,n.$)("ma-resume-bar"),s=(0,n.$)("ma-resume-text");if(!q){e&&(e.textContent="\u65B0\u5BF9\u8BDD"),t?.classList.add("hidden");return}let o=ee?.title||q.slice(0,8),a=No(ee?.updatedAt);if(e&&(e.textContent=a?`${o} \xB7 ${a}`:o),t&&s){t.classList.remove("hidden");let i=ee?.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 ps(e="chat"){let t=(0,n.$)("meta-agent-panel");if(t){if(t.classList.remove("hidden"),t.setAttribute("aria-hidden","false"),Mn=!0,oe(e),e==="chat"){De();let s=localStorage.getItem(Ue);!q&&s?_e(s,{silent:!0}).catch(()=>{localStorage.removeItem(Ue)}):Ot()}e==="history"&&De().then(()=>et()),e==="report"&&Ro(),e==="config"&&Bo(),setTimeout(()=>{Oe==="chat"&&(0,n.$)("ma-input")?.focus(),Oe==="history"&&(0,n.$)("ma-history-search")?.focus()},50)}}function _o(){let e=(0,n.$)("meta-agent-panel");e&&(e.classList.add("hidden"),e.setAttribute("aria-hidden","true"),Mn=!1)}function Ho(){Mn?_o():ps(Oe==="config"?"chat":Oe)}function H(e,t,s={}){let o=(0,n.$)("ma-messages");if(!o)return null;let a=document.createElement("div");return a.className=`ma-msg ma-msg-${e}`,e==="user"?a.innerHTML=`<div class="ma-bubble user">${(0,n.esc)(t)}</div>`:e==="assistant"?(a.innerHTML=`<div class="ma-bubble assistant md">${bt(t)}</div>`,xt(a)):e==="error"?a.innerHTML=`<div class="ma-bubble error">${(0,n.esc)(t)}</div>`:e==="system"?a.innerHTML=`<div class="ma-sys">${(0,n.esc)(t)}</div>`:e==="tool"&&(a.innerHTML=`<div class="ma-tool" data-tool-id="${(0,n.esc)(s.id||"")}">
|
|
402
402
|
<span class="ma-tool-name">${(0,n.esc)(s.name||"tool")}</span>
|
|
403
403
|
<span class="ma-tool-phase">${(0,n.esc)(s.phase||"")}</span>
|
|
404
404
|
<pre class="ma-tool-args">${(0,n.esc)(JSON.stringify(s.args||{},null,0).slice(0,200))}</pre>
|
|
405
|
-
</div>`),o.appendChild(a),o.scrollTop=o.scrollHeight,a}function
|
|
405
|
+
</div>`),o.appendChild(a),o.scrollTop=o.scrollHeight,a}function Co(e,t){let s=e?.querySelector(".ma-bubble");s&&(s.innerHTML=bt(t),xt(s),(0,n.$)("ma-messages").scrollTop=(0,n.$)("ma-messages").scrollHeight)}function Po(e,t,s){let o=(0,n.$)("ma-messages");if(!o)return;let a=o.querySelector(`[data-tool-id="${CSS.escape(e)}"]`);if(!a)return;a.classList.toggle("done",t==="done"),a.classList.toggle("error",t==="error");let i=a.querySelector(".ma-tool-phase");if(i&&(i.textContent=t),s&&t!=="start"){let r=a.querySelector(".ma-tool-result");r||(r=document.createElement("pre"),r.className="ma-tool-result",a.appendChild(r)),r.textContent=JSON.stringify(s,null,0).slice(0,500)}}function fi(e){let t=(0,n.$)("ma-messages");if(!t)return;let s=document.createElement("div");s.className="ma-approval",s.dataset.approvalId=e.id;let o=e.args?.command??"";s.innerHTML=`
|
|
406
406
|
<div class="ma-approval-label">\u26A0 Agent \u60F3\u8981\u6267\u884C\u547D\u4EE4\uFF0C\u662F\u5426\u5141\u8BB8\uFF1F</div>
|
|
407
407
|
<pre class="ma-approval-cmd">${(0,n.esc)(o)}</pre>
|
|
408
408
|
<div class="ma-approval-actions">
|
|
409
409
|
<button type="button" class="btn btn-xs btn-error" data-approve="0">\u62D2\u7EDD</button>
|
|
410
410
|
<button type="button" class="btn btn-xs btn-success" data-approve="1">\u5141\u8BB8\u6267\u884C</button>
|
|
411
|
-
</div>`,s.querySelectorAll("[data-approve]").forEach(a=>{a.addEventListener("click",async()=>{let i=a.dataset.approve==="1";s.querySelectorAll("button").forEach(r=>{r.disabled=!0}),s.querySelector(".ma-approval-label").textContent=i?"\u2713 \u5DF2\u5141\u8BB8\uFF0C\u6B63\u5728\u6267\u884C\u2026":"\u2717 \u5DF2\u62D2\u7EDD";try{await h("POST","/api/ai/approve",{id:e.id,approved:i})}catch(r){s.querySelector(".ma-approval-label").textContent=`\u786E\u8BA4\u5931\u8D25\uFF1A${r.message}`}})}),t.appendChild(s),t.scrollTop=t.scrollHeight}function
|
|
411
|
+
</div>`,s.querySelectorAll("[data-approve]").forEach(a=>{a.addEventListener("click",async()=>{let i=a.dataset.approve==="1";s.querySelectorAll("button").forEach(r=>{r.disabled=!0}),s.querySelector(".ma-approval-label").textContent=i?"\u2713 \u5DF2\u5141\u8BB8\uFF0C\u6B63\u5728\u6267\u884C\u2026":"\u2717 \u5DF2\u62D2\u7EDD";try{await h("POST","/api/ai/approve",{id:e.id,approved:i})}catch(r){s.querySelector(".ma-approval-label").textContent=`\u786E\u8BA4\u5931\u8D25\uFF1A${r.message}`}})}),t.appendChild(s),t.scrollTop=t.scrollHeight}function mi(){return Io+=1,`img${Io}`}function hi(e,t){if(!e)return;let s=e.selectionStart??e.value.length,o=e.selectionEnd??e.value.length;e.value=e.value.slice(0,s)+t+e.value.slice(o),e.selectionStart=e.selectionEnd=s+t.length,e.dispatchEvent(new Event("input"))}async function Ao(e,t){let s=lt({"x-filename":t||`paste-${Date.now()}.png`});delete s["Content-Type"];let o=await fetch("/api/upload-image",{method:"POST",headers:s,body:e});if(!o.ok){let l=await o.json().catch(()=>({}));throw new Error(l.error||`Upload failed: ${o.status}`)}let{path:a}=await o.json();if(!a)throw new Error("upload returned no path");let i=mi(),r=`[${i}](${a})`,c=(0,n.$)("ma-input");hi(c,(c?.value&&!c.value.endsWith(`
|
|
412
412
|
`)&&c.value.length?`
|
|
413
413
|
`:"")+r+`
|
|
414
414
|
`);let u="";try{u=URL.createObjectURL(e)}catch{}return Ze.push({path:a,previewUrl:u,label:i,ref:r}),us(),{path:a,ref:r,label:i}}function us(){let e=(0,n.$)("ma-attach-bar");if(e){if(!Ze.length){e.classList.add("hidden"),e.innerHTML="";return}e.classList.remove("hidden"),e.innerHTML=Ze.map((t,s)=>`
|
|
@@ -418,9 +418,9 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
418
418
|
<button type="button" class="ma-thumb-x" data-rm-img="${s}">\u2715</button>
|
|
419
419
|
</div>`).join(""),e.querySelectorAll("[data-rm-img]").forEach(t=>{t.addEventListener("click",()=>{let s=parseInt(t.dataset.rmImg,10),o=Ze[s];if(o?.previewUrl)try{URL.revokeObjectURL(o.previewUrl)}catch{}let a=(0,n.$)("ma-input");a&&o?.ref&&(a.value=a.value.split(o.ref).join("").replace(/\n{3,}/g,`
|
|
420
420
|
|
|
421
|
-
`),a.dispatchEvent(new Event("input"))),Ze.splice(s,1),us()})})}}function
|
|
421
|
+
`),a.dispatchEvent(new Event("input"))),Ze.splice(s,1),us()})})}}function No(e){if(!e)return"";let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let s=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),a=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${o} ${a}:${i}`}async function De(){try{Ln=(await h("GET","/api/ai/sessions")).sessions||[]}catch{Ln=[]}return Ln}function et(){let e=(0,n.$)("ma-history-list");if(!e)return;let t=(Do||"").trim().toLowerCase(),s=Ln;if(t&&(s=s.filter(o=>`${o.title||""} ${o.preview||""} ${o.id||""}`.toLowerCase().includes(t))),!s.length){e.innerHTML=`<div class="text-center text-xs text-base-content/40 py-10">
|
|
422
422
|
${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"}
|
|
423
|
-
</div>`;return}e.innerHTML=s.map(o=>{let a=o.id===q,i=
|
|
423
|
+
</div>`;return}e.innerHTML=s.map(o=>{let a=o.id===q,i=No(o.updatedAt)||"",r=o.messageCount||0;return`
|
|
424
424
|
<div class="ma-hist-item ${a?"active":""}" data-hist-id="${(0,n.esc)(o.id)}">
|
|
425
425
|
<div class="flex items-start gap-2">
|
|
426
426
|
<button type="button" class="ma-hist-open flex-1 min-w-0 text-left" data-hist-open="${(0,n.esc)(o.id)}">
|
|
@@ -433,17 +433,17 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
433
433
|
<button type="button" class="btn btn-ghost btn-xs px-1 text-error" data-hist-del="${(0,n.esc)(o.id)}" title="\u5220\u9664">\u2715</button>
|
|
434
434
|
</div>
|
|
435
435
|
</div>
|
|
436
|
-
</div>`}).join(""),e.querySelectorAll("[data-hist-open]").forEach(o=>{o.addEventListener("click",async()=>{await
|
|
437
|
-
`)||"[\u2026]"}function
|
|
436
|
+
</div>`}).join(""),e.querySelectorAll("[data-hist-open]").forEach(o=>{o.addEventListener("click",async()=>{await _e(o.dataset.histOpen),oe("chat"),(0,n.$)("ma-input")?.focus()})}),e.querySelectorAll("[data-hist-resume]").forEach(o=>{o.addEventListener("click",async a=>{a.stopPropagation(),await _e(o.dataset.histResume),oe("chat"),(0,n.$)("ma-input")?.focus()})}),e.querySelectorAll("[data-hist-del]").forEach(o=>{o.addEventListener("click",async a=>{a.stopPropagation();let i=o.dataset.histDel;if(confirm("\u5220\u9664\u8BE5\u5386\u53F2\u4F1A\u8BDD\uFF1F\u4E0D\u53EF\u6062\u590D\u3002"))try{await h("DELETE",`/api/ai/sessions/${i}`),q===i&&(q=null,ee=null,localStorage.removeItem(Ue),_e(null)),await De(),et()}catch(r){alert(r.message)}})})}function jo(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(`
|
|
437
|
+
`)||"[\u2026]"}function bi(e){let t=(0,n.$)("ma-messages");if(t){if(t.innerHTML="",!e?.length){H("system","\u6B64\u4F1A\u8BDD\u6682\u65E0\u6D88\u606F\u3002");return}for(let s of e){if(s.role==="user"){H("user",jo(s.content));continue}if(s.role==="assistant"){if(s.tool_calls?.length)for(let o of s.tool_calls){let a=o.function?.name||o.name||"tool",i={};try{i=JSON.parse(o.function?.arguments||o.arguments||"{}")}catch{}H("tool","",{name:a,args:i,phase:"history",id:o.id||a})}s.content&&H("assistant",typeof s.content=="string"?s.content:jo(s.content));continue}if(s.role==="tool"){let o=s.content;try{o=JSON.parse(s.content)}catch{}let a=s.tool_call_id||"";if(a)Po(a,"done",o);else{H("tool","",{name:"tool_result",args:{},phase:"done",id:`tr_${Math.random().toString(36).slice(2,8)}`});let i=t.querySelectorAll(".ma-tool"),r=i[i.length-1];if(r){r.classList.add("done");let c=r.querySelector(".ma-tool-result");c||(c=document.createElement("pre"),c.className="ma-tool-result",r.appendChild(c)),c.textContent=typeof o=="string"?o.slice(0,500):JSON.stringify(o,null,0).slice(0,500)}}}}t.scrollTop=t.scrollHeight}}async function xi(){if(!q){await _e(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/${q}`),q=null,ee=null,localStorage.removeItem(Ue),await De(),await _e(null),Oe==="history"&&et()}catch(e){H("error",e.message)}}async function _e(e,t={}){if(!e){q=null,ee=null,localStorage.removeItem(Ue);let s=(0,n.$)("ma-messages");return s&&(s.innerHTML=""),H("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"),Ot(),null}try{let s=await h("GET",`/api/ai/sessions/${e}`);return q=s.id,ee={id:s.id,title:s.title,updatedAt:s.updatedAt,messageCount:(s.messages||[]).length},localStorage.setItem(Ue,s.id),bi(s.messages||[]),t.silent||H("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"),Ot(),Oe==="history"&&et(),s}catch(s){throw t.silent||H("error",s.message),s}}async function Sn(){if(ht)return;let e=(0,n.$)("ma-input"),t=(e?.value||"").trim();if(!t)return;ht=!0,(0,n.$)("ma-send").disabled=!0,H("user",t),e.value="",e.style.height="";for(let a of Ze)if(a.previewUrl)try{URL.revokeObjectURL(a.previewUrl)}catch{}Ze=[],us();let s=null,o="";try{await ds("/api/ai/chat",{message:t,sessionId:q},{session:a=>{q=a.id,ee={...ee||{},id:a.id,title:a.title||ee?.title||t.slice(0,40),updatedAt:Date.now()},localStorage.setItem(Ue,a.id),Ot()},content:a=>{o=a.content||"",s||(s=H("assistant","")),Co(s,o)},tool:a=>{a.phase==="start"?H("tool","",{name:a.name,args:a.args,phase:"start",id:a.id}):Po(a.id,a.phase,a.result)},approval:a=>fi(a),done:a=>{a.sessionId&&(q=a.sessionId,localStorage.setItem(Ue,a.sessionId)),(a.title||a.sessionId)&&(ee={id:q,title:a.title||ee?.title||"\u5BF9\u8BDD",updatedAt:Date.now(),messageCount:(ee?.messageCount||0)+2}),a.content&&s&&Co(s,a.content),Ot(),De()},error:a=>{H("error",a.message||"error")}})}catch(a){H("error",a.message)}finally{ht=!1,(0,n.$)("ma-send").disabled=!1}}async function gi(){if(ht)return;ht=!0;let e=parseInt((0,n.$)("ma-report-days")?.value||"1",10),t=(0,n.$)("ma-report-body");t.innerHTML=`<div class="text-sm text-base-content/50 py-6 text-center">\u6B63\u5728\u6C47\u603B\u8FD1 ${e} \u5929\u6D3B\u52A8\u2026</div>`,(0,n.$)("ma-gen-report").disabled=!0;let s="",o=document.createElement("div");o.className="ma-report-tools flex flex-col gap-1 mb-3";try{await ds("/api/ai/report",{days:e},{content:a=>{s=a.content||"",t.innerHTML="",t.appendChild(o);let i=document.createElement("div");i.className="md ma-report-md",i.innerHTML=bt(s),xt(i),t.appendChild(i)},tool:a=>{if(a.phase==="start"){let i=document.createElement("div");i.className="ma-tool",i.dataset.toolId=a.id||a.name,i.innerHTML=`<span class="ma-tool-name">${(0,n.esc)(a.name)}</span> <span class="ma-tool-phase">start</span>`,o.appendChild(i)}else{let i=o.querySelector(`[data-tool-id="${CSS.escape(a.id||a.name)}"]`);i&&(i.classList.add(a.phase==="error"?"error":"done"),i.querySelector(".ma-tool-phase").textContent=a.phase)}},done:a=>{if(a.content){t.innerHTML="",t.appendChild(o);let i=document.createElement("div");i.className="md ma-report-md",i.innerHTML=bt(a.content),xt(i),t.appendChild(i)}},error:a=>{t.innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(a.message)}</div>`}})}catch(a){t.innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(a.message)}</div>`}finally{ht=!1,(0,n.$)("ma-gen-report").disabled=!1}}async function Ro(){try{let e=new Date,t=`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`,s=await h("GET",`/api/ai/reports/${t}`);if(s?.markdown){let o=(0,n.$)("ma-report-body");o.innerHTML=`
|
|
438
438
|
<div class="text-[10px] text-base-content/40 mb-2">${(0,n.esc)(s.title||t)} \xB7 ${(0,n.esc)(s.generatedAt||"")}</div>
|
|
439
|
-
<div class="md ma-report-md">${bt(s.markdown)}</div>`,xt(o)}}catch{}}async function
|
|
439
|
+
<div class="md ma-report-md">${bt(s.markdown)}</div>`,xt(o)}}catch{}}async function vi(){let e=(0,n.$)("ma-report-list");try{let t=await h("GET","/api/ai/reports");e.classList.remove("hidden");let s=t.reports||[];if(!s.length){e.innerHTML='<div class="text-xs text-base-content/40 px-2 py-1">\u6682\u65E0\u5386\u53F2\u62A5\u544A</div>';return}e.innerHTML=s.map(o=>`
|
|
440
440
|
<button type="button" class="ma-report-item w-full text-left px-2 py-1 rounded hover:bg-base-200 text-xs"
|
|
441
441
|
data-day="${(0,n.esc)(o.day)}">
|
|
442
442
|
<span class="font-semibold">${(0,n.esc)(o.day)}</span>
|
|
443
443
|
<span class="text-base-content/45 ml-1">${(0,n.esc)(o.title||"")}</span>
|
|
444
444
|
</button>`).join(""),e.querySelectorAll("[data-day]").forEach(o=>{o.addEventListener("click",async()=>{try{let a=await h("GET",`/api/ai/reports/${o.dataset.day}`),i=(0,n.$)("ma-report-body");i.innerHTML=`
|
|
445
445
|
<div class="text-[10px] text-base-content/40 mb-2">${(0,n.esc)(a.title||a.day)} \xB7 ${(0,n.esc)(a.generatedAt||"")}</div>
|
|
446
|
-
<div class="md ma-report-md">${bt(a.markdown)}</div>`,xt(i)}catch(a){(0,n.$)("ma-report-body").innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(a.message)}</div>`}})})}catch(t){e.classList.remove("hidden"),e.innerHTML=`<div class="text-xs text-error px-2">${(0,n.esc)(t.message)}</div>`}}async function
|
|
446
|
+
<div class="md ma-report-md">${bt(a.markdown)}</div>`,xt(i)}catch(a){(0,n.$)("ma-report-body").innerHTML=`<div class="alert alert-error text-sm">${(0,n.esc)(a.message)}</div>`}})})}catch(t){e.classList.remove("hidden"),e.innerHTML=`<div class="text-xs text-error px-2">${(0,n.esc)(t.message)}</div>`}}async function Bo(){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)),Ut(e)}catch(e){(0,n.$)("ma-cfg-status").textContent=e.message}}async function yi(){let e=(0,n.$)("ma-cfg-status");e.textContent="\u4FDD\u5B58\u4E2D\u2026";try{let t={url:(0,n.$)("ma-cfg-url").value.trim(),model:(0,n.$)("ma-cfg-model").value.trim(),vlm_url:(0,n.$)("ma-cfg-vlm-url").value.trim(),vlm_model:(0,n.$)("ma-cfg-vlm-model").value.trim(),system:(0,n.$)("ma-cfg-system").value,auto_report:!!(0,n.$)("ma-auto-report")?.checked,auto_report_hour:parseInt((0,n.$)("ma-auto-hour")?.value||"18",10)},s=(0,n.$)("ma-cfg-key").value.trim(),o=(0,n.$)("ma-cfg-vlm-key").value.trim();s&&(t.key=s),o&&(t.vlm_key=o);let a=await h("PUT","/api/ai/config",t);e.textContent=a.hasKey?"\u5DF2\u4FDD\u5B58 \u2713":"\u5DF2\u4FDD\u5B58\uFF08\u672A\u8BBE\u7F6E Key\uFF09",(0,n.$)("ma-cfg-key").value="",(0,n.$)("ma-cfg-vlm-key").value="",Ut(a)}catch(t){e.textContent=t.message}}function Ut(e){if($n&&(clearInterval($n),$n=null),!e?.auto_report)return;let t=e.auto_report_hour??18;$n=setInterval(async()=>{if(!f.token)return;let s=new Date;if(s.getHours()!==t)return;let o=`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-${String(s.getDate()).padStart(2,"0")}`;if(cs!==o&&!(s.getMinutes()>10))try{cs=o,localStorage.setItem("ai_last_auto_report",o),await ds("/api/ai/report",{days:e.auto_report_days||1},{done:()=>{console.info("[meta-agent] auto report saved for",o)},error:a=>console.warn("[meta-agent] auto report",a.message)})}catch(a){console.warn("[meta-agent] auto report failed",a),cs="",localStorage.removeItem("ai_last_auto_report")}},60*1e3)}function Oo(){(0,n.$)("meta-agent-panel")||(document.getElementById("root")?.insertAdjacentHTML("beforeend",ui()),document.querySelectorAll("[data-ma-close]").forEach(e=>{e.addEventListener("click",_o)}),(0,n.$)("ma-btn-chat")?.addEventListener("click",()=>oe("chat")),(0,n.$)("ma-btn-history")?.addEventListener("click",async()=>{await De(),oe("history")}),(0,n.$)("ma-open-history")?.addEventListener("click",async()=>{await De(),oe("history")}),(0,n.$)("ma-btn-report")?.addEventListener("click",()=>{oe("report"),Ro()}),(0,n.$)("ma-btn-config")?.addEventListener("click",()=>{oe("config"),Bo()}),(0,n.$)("ma-send")?.addEventListener("click",Sn),(0,n.$)("ma-input")?.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key==="Enter"&&(e.preventDefault(),Sn())}),(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",()=>{_e(null),oe("chat")}),(0,n.$)("ma-del-session")?.addEventListener("click",xi),(0,n.$)("ma-resume-focus")?.addEventListener("click",()=>{(0,n.$)("ma-input")?.focus()}),(0,n.$)("ma-history-refresh")?.addEventListener("click",async()=>{await De(),et()}),(0,n.$)("ma-history-new")?.addEventListener("click",()=>{_e(null),oe("chat")}),(0,n.$)("ma-history-search")?.addEventListener("input",e=>{Do=e.target.value||"",et()}),(0,n.$)("ma-quick-today")?.addEventListener("click",()=>{oe("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",Sn()}),(0,n.$)("ma-quick-projects")?.addEventListener("click",()=>{oe("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",Sn()}),(0,n.$)("ma-gen-report")?.addEventListener("click",gi),(0,n.$)("ma-load-reports")?.addEventListener("click",vi),(0,n.$)("ma-cfg-save")?.addEventListener("click",yi),(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)});Ut(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)});Ut(e)}catch{}}),(0,n.$)("ma-image-input")?.addEventListener("change",async e=>{let t=[...e.target.files||[]],s=(0,n.$)("ma-input");s&&(s.disabled=!0);try{for(let o of t)if(o.type.startsWith("image/")){if(o.size>12*1024*1024){H("error",`${o.name} \u8FC7\u5927 (>12MB)`);continue}await Ao(o,o.name||`upload-${Date.now()}.png`)}}catch(o){H("error",`\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${o.message}`)}finally{e.target.value="",s&&(s.disabled=!1,s.focus())}}),document.addEventListener("paste",async e=>{if(!Mn||Oe!=="chat")return;let t=(0,n.$)("ma-input"),s=(0,n.$)("meta-agent-panel"),o=document.activeElement;if(!s||!o||!s.contains(o))return;let i=[...e.clipboardData?.items||[]].filter(r=>r.type.startsWith("image/"));if(i.length){e.preventDefault(),t&&(t.disabled=!0);try{for(let r of i){let c=r.getAsFile();if(!c)continue;let u=(r.type.split("/")[1]||"png").replace(/[^a-z0-9]/gi,"")||"png";await Ao(c,`paste-${Date.now()}.${u}`)}}catch(r){H("error",`\u7C98\u8D34\u56FE\u7247\u5931\u8D25: ${r.message}`)}finally{t&&(t.disabled=!1,t.focus())}}}),_e(null,{silent:!0}))}function Ft(){f.token&&(k.peek()&&!It()||(De(),h("GET","/api/ai/config").then(Ut).catch(()=>{})))}I();var Uo=()=>`
|
|
447
447
|
<div id="auth-screen" class="${f.token?"hidden":""} flex items-center justify-center h-full p-4" ${f.token?'style="display:none"':""}>
|
|
448
448
|
<div class="card bg-base-200 border border-base-300 w-full max-w-sm shadow-xl">
|
|
449
449
|
<div class="card-body gap-3 p-8">
|
|
@@ -461,7 +461,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
461
461
|
<div id="auth-error" class="alert alert-error text-xs py-2 hidden"></div>
|
|
462
462
|
</div>
|
|
463
463
|
</div>
|
|
464
|
-
</div>`,
|
|
464
|
+
</div>`,Fo=(e={})=>{let t=!!e.restoreSession,s=f.token?"":"hidden",o=f.token?"display:flex":"display:none";return`
|
|
465
465
|
<div id="sidebar-overlay" class="hidden fixed inset-0 bg-black/50 z-[9]"></div>
|
|
466
466
|
<div id="app" class="${s} flex-col flex-1 overflow-hidden" style="${o}">
|
|
467
467
|
<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">
|
|
@@ -486,24 +486,15 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
486
486
|
</div>
|
|
487
487
|
</div>
|
|
488
488
|
<div id="recent-menu-wrap" class="relative flex-shrink-0">
|
|
489
|
-
<button type="button" id="btn-recent-sessions" class="btn btn-ghost btn-xs border border-base-300 gap-1"
|
|
490
|
-
title="\u6700\u8FD1\u4F1A\u8BDD / \u5FEB\u901F\u8DF3\u8F6C">
|
|
489
|
+
<button type="button" id="btn-recent-sessions" class="btn btn-ghost btn-xs border border-base-300 gap-1 min-h-8 px-2"
|
|
490
|
+
title="\u6700\u8FD1\u4F1A\u8BDD / \u5FEB\u901F\u8DF3\u8F6C" aria-haspopup="listbox" aria-expanded="false">
|
|
491
491
|
<span>\u6700\u8FD1</span>
|
|
492
492
|
<span class="text-[10px] opacity-50">\u25BE</span>
|
|
493
493
|
</button>
|
|
494
|
-
<div id="recent-menu" class="hidden absolute left-0 top-full mt-1 z-50 w-80 max-h-[min(24rem,70vh)] overflow-y-auto
|
|
495
|
-
rounded-lg border border-base-300 bg-base-100 shadow-xl p-2">
|
|
496
|
-
<div class="flex items-center justify-between px-1 pb-1.5 mb-1 border-b border-base-300 sticky top-0 bg-base-100 z-[1]">
|
|
497
|
-
<span class="text-[10px] uppercase tracking-wide text-base-content/45 font-semibold">Recent sessions</span>
|
|
498
|
-
<span id="recent-menu-count" class="text-[10px] text-base-content/35 font-mono"></span>
|
|
499
|
-
</div>
|
|
500
|
-
<div id="recent-menu-list" class="flex flex-col gap-0.5"></div>
|
|
501
|
-
<p id="recent-menu-empty" class="text-xs text-base-content/40 px-1 py-2 hidden">\u6682\u65E0\u6700\u8FD1\u4F1A\u8BDD</p>
|
|
502
|
-
</div>
|
|
503
494
|
</div>
|
|
504
495
|
<span id="topbar-project" class="text-sm text-base-content/50 flex-1 truncate min-w-0">Select a session</span>
|
|
505
496
|
<span id="conn-dot" class="w-2 h-2 rounded-full bg-base-content/30 flex-shrink-0" title="\u8FDE\u63A5\u72B6\u6001"></span>
|
|
506
|
-
<div class="flex gap-2">
|
|
497
|
+
<div class="flex gap-2 topbar-actions">
|
|
507
498
|
<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>
|
|
508
499
|
<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>
|
|
509
500
|
<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">\u2726 Agent</button>
|
|
@@ -513,6 +504,18 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
513
504
|
<button id="btn-logout" class="btn btn-ghost btn-xs border border-base-300">Sign out</button>
|
|
514
505
|
</div>
|
|
515
506
|
</div>
|
|
507
|
+
<!-- Fixed panel + backdrop: siblings of topbar so flex layout never clips them -->
|
|
508
|
+
<div id="recent-menu-backdrop" class="hidden fixed inset-0 z-[55] bg-black/40" aria-hidden="true"></div>
|
|
509
|
+
<div id="recent-menu" class="hidden fixed z-[60] w-80 max-h-[min(24rem,70vh)] overflow-y-auto
|
|
510
|
+
rounded-lg border border-base-300 bg-base-100 shadow-xl p-2"
|
|
511
|
+
role="listbox" aria-label="\u6700\u8FD1\u4F1A\u8BDD">
|
|
512
|
+
<div class="flex items-center justify-between px-1 pb-1.5 mb-1 border-b border-base-300 sticky top-0 bg-base-100 z-[1]">
|
|
513
|
+
<span class="text-[10px] uppercase tracking-wide text-base-content/45 font-semibold">\u6700\u8FD1\u4F1A\u8BDD</span>
|
|
514
|
+
<span id="recent-menu-count" class="text-[10px] text-base-content/35 font-mono"></span>
|
|
515
|
+
</div>
|
|
516
|
+
<div id="recent-menu-list" class="flex flex-col gap-0.5"></div>
|
|
517
|
+
<p id="recent-menu-empty" class="text-xs text-base-content/40 px-1 py-2 hidden">\u6682\u65E0\u6700\u8FD1\u4F1A\u8BDD</p>
|
|
518
|
+
</div>
|
|
516
519
|
<!-- Hub: only when no remembered machine (or last one offline) -->
|
|
517
520
|
<div id="machine-picker" class="hidden fixed inset-0 z-[60] bg-base-100 flex items-center justify-center p-4">
|
|
518
521
|
<div class="w-full max-w-md">
|
|
@@ -795,7 +798,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
795
798
|
</div>
|
|
796
799
|
</div>
|
|
797
800
|
<form method="dialog" class="modal-backdrop"><button>close</button></form>
|
|
798
|
-
</dialog>`};
|
|
801
|
+
</dialog>`};hs();vt();Kt();C();I();K();wn();sn();vt();Jt();Kt();C();I();K();vt();Jt();async function wt(){try{let e=await h("GET","/api/machines");D.value=Array.isArray(e)?e:[]}catch{try{let e=await ct();e?.machines&&(D.value=e.machines)}catch{}}return D.peek()||[]}function $s(){let e=(0,n.$)("machine-picker-list"),t=(0,n.$)("machine-picker-empty");if(!e)return;let s=D.peek()||[];if(!s.length){e.innerHTML="",t?.classList.remove("hidden");return}t?.classList.add("hidden"),e.innerHTML=s.map(o=>{let a=o.online!==!1,i=[o.hostname,o.platform].filter(Boolean).join(" \xB7 ");return`
|
|
799
802
|
<button type="button" class="machine-pick-card w-full text-left px-4 py-3 rounded-xl border border-base-300
|
|
800
803
|
hover:border-primary hover:bg-primary/5 transition-colors ${a?"":"opacity-50"}"
|
|
801
804
|
data-pick-machine="${(0,n.esc)(o.id)}" ${a?"":"disabled"}>
|
|
@@ -804,7 +807,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
804
807
|
<span class="font-semibold text-sm font-mono">${(0,n.esc)(o.id)}</span>
|
|
805
808
|
</div>
|
|
806
809
|
${i?`<div class="text-xs text-base-content/45 mt-1 pl-4">${(0,n.esc)(i)}</div>`:""}
|
|
807
|
-
</button>`}).join("")}function
|
|
810
|
+
</button>`}).join("")}function kt(){let e=(0,n.$)("machine-picker");if(!e)return;e.classList.remove("hidden"),Ee.value=!1,$s();let t=(0,n.$)("machine-picker-status");if(t){let s=(D.peek()||[]).filter(o=>o.online!==!1).length;t.textContent=`${s} online`}}function Ss(){(0,n.$)("machine-picker")?.classList.add("hidden"),Ee.value=!0}function Vt(){(0,n.$)("machine-menu")?.classList.add("hidden")}function Nn(){let e=(0,n.$)("machine-menu-list"),t=(0,n.$)("machine-menu-empty");if(!e)return;let s=D.peek()||[],o=M.peek()||"";if(!s.length){e.innerHTML="",t?.classList.remove("hidden");return}t?.classList.add("hidden"),e.innerHTML=s.map(a=>{let i=a.online!==!1,r=a.id===o,c=[a.hostname,a.platform].filter(Boolean).join(" \xB7 "),u=a.connectedAt?new Date(a.connectedAt).toLocaleTimeString():"";return`
|
|
808
811
|
<button type="button"
|
|
809
812
|
class="machine-menu-item w-full text-left px-2 py-1.5 rounded-md text-xs
|
|
810
813
|
${r?"bg-primary/15 text-primary":"hover:bg-base-200"}
|
|
@@ -818,7 +821,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
818
821
|
<span class="text-[9px] ${i?"text-success":"text-error"}">${i?"online":"offline"}</span>
|
|
819
822
|
</div>
|
|
820
823
|
${c||u?`<div class="text-[10px] text-base-content/40 pl-3.5 mt-0.5 truncate">${(0,n.esc)(c)}${u?" \xB7 "+(0,n.esc)(u):""}</div>`:""}
|
|
821
|
-
</button>`}).join("")}function st(){let e=(0,n.$)("machine-menu-wrap"),t=(0,n.$)("topbar-machine-label"),s=(0,n.$)("topbar-machine-dot");if(!k.peek()){e?.classList.add("hidden");return}e?.classList.remove("hidden");let o=
|
|
824
|
+
</button>`}).join("")}function st(){let e=(0,n.$)("machine-menu-wrap"),t=(0,n.$)("topbar-machine-label"),s=(0,n.$)("topbar-machine-dot");if(!k.peek()){e?.classList.add("hidden");return}e?.classList.remove("hidden");let o=M.peek()||"",i=(D.peek()||[]).find(c=>c.id===o),r=i?i.online!==!1:!1;t&&(t.textContent=o||"\u9009\u62E9\u673A\u5668"),s&&(s.classList.toggle("bg-success",!!o&&r),s.classList.toggle("bg-warning",!!o&&!r),s.classList.toggle("bg-base-content/30",!o)),Nn()}var da=null;function pa(){da||(da=setInterval(async()=>{if(!k.peek()||!f.token)return;await wt(),st();let e=M.peek();if(e){let t=(D.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 ua(e,{forceReload:t=!1}={}){if(!e)return;let s=M.peek(),o=s&&s!==e;if(Z(e),Ss(),Vt(),st(),o||t){try{f.ws?.close()}catch{}f.ws=null,f.sessionId=null,(0,n.batch)(()=>{y.value=null,O.value=null,U.value=null});try{let{filesRoot:i,gitRoot:r,filesPath:c}=await Promise.resolve().then(()=>(I(),Gs));i.value="",r.value="",c.value=""}catch{}if(o){let{goHome:i}=await Promise.resolve().then(()=>(Kt(),ca));i()}}let a=(0,n.$)("topbar-project");a&&!y.peek()&&(a.textContent=`Machine \xB7 ${e}`),Ft(),await Promise.all([ye(),Wt(),zt(),Gt().catch(()=>{})]),Ee.value=!0}async function Rn(e={}){(0,n.$)("auth-screen").style.display="none";let t=(0,n.$)("app");t.classList.remove("hidden"),t.style.display="flex";let s=e.hub;s===void 0?s=await ct():s?(k.value=!0,s.machines&&(D.value=s.machines)):k.value=!1;let o=e.deepLink||null,a=Je();if(!!(o?.id||(location.hash||"").startsWith("#/session/"))){let c=(0,n.$)("welcome");c&&(c.classList.add("hidden"),c.style.display="none");let u=(0,n.$)("project-view");u&&(u.classList.remove("hidden"),u.style.display="flex",u.style.flexDirection="column",u.style.flex="1",u.style.minHeight="0")}if(k.peek()){let c=localStorage.getItem("machineId")||a?.machineId||"";c&&(Z(c),Ss(),Ee.value=!0,Ft());let u=wt().then(p=>(st(),c&&!p.some(b=>b.id===c&&b.online!==!1)&&p.length&&(p.some(g=>g.id===c)||(Z(null),kt())),p));pa(),st();let l=Promise.all([ye({waitFresh:!1}),Wt({waitFresh:!1}),zt().catch(()=>{}),Gt().catch(()=>{})]);if(o?.id){let p=E.peek().find(m=>m.sessionId===o.id)||(a?.sessionId===o.id?a:null);await ke(o.id,p?.cwd||a?.cwd||null,p?.configDir||a?.configDir||null,p?.agent||a?.agent||null,p?.machineId||a?.machineId||c||null,{tab:o.tab||"chat"}),u.catch(()=>{}),l.catch(()=>{});return}if(!c){if(await u,!(D.peek()||[]).length){kt(),l.catch(()=>{});return}kt(),l.catch(()=>{});return}await l;let d=(0,n.$)("topbar-project");d&&d.textContent==="Select a session"&&(d.textContent=`Machine \xB7 ${c}`);return}Ft();let r=Promise.all([ye({waitFresh:!1}),Wt({waitFresh:!1}),zt().catch(()=>{}),Gt().catch(()=>{})]);if(o?.id){await yn().then(u=>{Array.isArray(u)?E.value=u:u&&Array.isArray(u.sessions)&&(E.value=u.sessions)}).catch(()=>{});let c=E.peek().find(u=>u.sessionId===o.id)||(a?.sessionId===o.id?a:null);await ke(o.id,c?.cwd||a?.cwd||null,c?.configDir||a?.configDir||null,c?.agent||a?.agent||null,null,{tab:o.tab||"chat"}),r.catch(()=>{});return}await r}Jt();C();I();K();mt();vt();Kt();function fa(){(0,n.$)("sidebar").classList.add("open"),(0,n.$)("sidebar-overlay").classList.remove("hidden")}function Bn(){(0,n.$)("sidebar").classList.remove("open"),(0,n.$)("sidebar-overlay").classList.add("hidden")}function ma(){window.innerWidth<=640&&Bn()}function ha(){let e=(0,n.$)("sidebar-toggle"),t=(0,n.$)("sidebar"),s=!1,o=t.style.width||"260px";e.addEventListener("click",()=>{s=!s,s?(o=t.style.width||"260px",t.style.width="0",t.style.minWidth="0",t.style.overflow="hidden"):(t.style.width=o,t.style.minWidth="",t.style.overflow=""),e.textContent=s?"\u25B6":"\u25C0"})}function ba(){let e=(0,n.$)("sidebar-resize"),t=(0,n.$)("sidebar"),s=!1;e.addEventListener("mousedown",o=>{s=!0,document.body.style.userSelect="none",document.body.style.cursor="col-resize",o.preventDefault()}),document.addEventListener("mousemove",o=>{if(!s)return;let a=Math.min(Math.max(o.clientX,160),520);t.style.width=a+"px",t.style.minWidth=""}),document.addEventListener("mouseup",()=>{s&&(s=!1,document.body.style.userSelect="",document.body.style.cursor="")})}function Ls(e){document.documentElement.setAttribute("data-theme",e),localStorage.setItem("theme",e);let t=(0,n.$)("btn-theme");t&&(t.textContent=e==="dark"||e==="night"||e==="black"?"\u{1F319}":"\u2600\uFE0F");let s=document.getElementById("hljs-theme");if(s||(s=document.querySelector('link[href*="highlight"][href*="styles"]'),s&&(s.id="hljs-theme")),s){let o=e==="dark"||e==="night"||e==="black";s.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 xa(){let e=document.documentElement.getAttribute("data-theme")||"dark";Ls(e==="dark"?"light":"dark")}function ga(){let e=(0,n.$)("new-session-agent");e&&(e.value=S.peek()||"claude");let t=(0,n.$)("new-session-workspace");if(t){let a=P.peek();t.innerHTML=a.map(i=>`<option value="${(0,n.esc)(i.configDir)}">${(0,n.esc)(i.name)} \u2014 ${(0,n.esc)(i.configDir)}</option>`).join(""),f.configDir&&(t.value=f.configDir)}let s=(0,n.$)("new-session-machine-wrap"),o=(0,n.$)("new-session-machine");if(s&&o)if(k.peek()){s.style.display="";let a=D.peek()||[],i=M.peek()||"";o.innerHTML=a.length?a.map(r=>`<option value="${(0,n.esc)(r.id)}">${(0,n.esc)(r.id)}${r.hostname?" \u2014 "+(0,n.esc)(r.hostname):""}</option>`).join(""):'<option value="">(no machines online)</option>',i&&(o.value=i),o.disabled=!0}else s.style.display="none",o&&(o.disabled=!1);Ms(),(0,n.$)("new-session-path").value=y.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 Ms(){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 Ts(){let e=(0,n.$)("new-session-path").value.trim(),t=(0,n.$)("new-session-agent")?.value||"claude",s=t==="claude"?(0,n.$)("new-session-workspace").value:null,o=(0,n.$)("new-session-error");if(o.classList.add("hidden"),!e){o.textContent="Working directory is required",o.classList.remove("hidden");return}if(k.peek()){let a=M.peek()||(0,n.$)("new-session-machine")?.value||D.peek()?.[0]?.id;if(!a){o.textContent="\u8BF7\u5148\u9009\u62E9\u4E00\u53F0\u673A\u5668",o.classList.remove("hidden"),kt();return}Z(a)}try{let a=await h("POST","/api/resolve-path",{path:e});if(!a.isDir)throw new Error("Path is not a directory");(0,n.$)("modal-new-session").close();let i=a.path.split("/").filter(Boolean).pop()||a.path;f.sessionId=null,f.configDir=s||null,f.agent=t,me(t),$.value=re(t)||$.peek(),localStorage.setItem("model",$.peek()),we(),(0,n.batch)(()=>{y.value={id:i,name:i,path:a.path,machineId:M.peek()||f.machineId},O.value=a.path,F.value=a.path,J.value=a.path,A.value="",U.value=null}),(0,n.$)("topbar-project").textContent=a.path;let r=(0,n.$)("files-root-input");r&&(r.value=a.path);let c=(0,n.$)("git-root-input");c&&(c.value=a.path),(0,n.$)("welcome").classList.add("hidden");let u=(0,n.$)("project-view");u.classList.remove("hidden"),u.style.display="flex",ft(),je(),He("chat"),x(`New ${R[t]||t} session \xB7 ${a.path}`)}catch(a){o.textContent=a.message,o.classList.remove("hidden")}}function ji(){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">
|
|
822
825
|
<li>\u70B9\u5E95\u90E8\u5206\u4EAB\u6309\u94AE <strong>\u5206\u4EAB</strong>\uFF08\u65B9\u6846+\u5411\u4E0A\u7BAD\u5934\uFF09</li>
|
|
823
826
|
<li>\u4E0B\u6ED1\u627E\u5230\u5E76\u70B9 <strong>\u6DFB\u52A0\u5230\u4E3B\u5C4F\u5E55</strong></li>
|
|
824
827
|
<li>\u786E\u8BA4\u540D\u79F0\u540E\u70B9 <strong>\u6DFB\u52A0</strong></li>
|
|
@@ -836,29 +839,29 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
836
839
|
<form method="dialog"><button class="btn btn-sm">\u77E5\u9053\u4E86</button></form>
|
|
837
840
|
</div>
|
|
838
841
|
</div>
|
|
839
|
-
<form method="dialog" class="modal-backdrop"><button>close</button></form>`,o.showModal()}async function Es(){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=await h("GET","/api/auth/status"),o=(0,n.$)("auth-btn");s.needsSetup?((0,n.$)("auth-subtitle").textContent="Create your account to get started",o.textContent="Create Account",o.dataset.mode="register"):o.dataset.mode="login"}async function
|
|
842
|
+
<form method="dialog" class="modal-backdrop"><button>close</button></form>`,o.showModal()}async function Es(){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=await h("GET","/api/auth/status"),o=(0,n.$)("auth-btn");s.needsSetup?((0,n.$)("auth-subtitle").textContent="Create your account to get started",o.textContent="Create Account",o.dataset.mode="register"):o.dataset.mode="login"}async function va(){let e=(0,n.$)("auth-username").value.trim(),t=(0,n.$)("auth-password").value,s=(0,n.$)("auth-error");s.classList.add("hidden");try{let o=await h("POST",`/api/auth/${(0,n.$)("auth-btn").dataset.mode||"login"}`,{username:e,password:t});f.token=o.token,localStorage.setItem("token",o.token),Rn()}catch(o){s.textContent=o.message,s.classList.remove("hidden")}}function Is(){return f.token?/^#\/session\//.test(location.hash||""):!1}function ya(e={}){if(Ls(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??Is(),s=document.getElementById("root");if(s.style.cssText="display:flex;flex-direction:column;flex:1;height:100%",s.innerHTML=Uo()+Fo({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=P.value,d=(0,n.$)("ws-tabs");if(!d)return;if(l.length<=1){d.innerHTML="";return}let p=O.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
|
|
840
843
|
${(m.id===null?!p:p===m.configDir)?"border-primary text-primary":"border-transparent text-base-content/50 hover:text-base-content"}"
|
|
841
844
|
data-ws-tab="${(0,n.esc)(m.configDir||"")}">
|
|
842
845
|
${(0,n.esc)(m.name)}
|
|
843
|
-
</button>`).join("")}),(0,n.effect)(()=>{Re.value,ze.value,Se.value,Le.value,ue.value,v.value;let l=(0,n.$)("session-list");l&&(l.querySelector(".session-rename-input")||(l.innerHTML=Qo(),Zo()))}),(0,n.effect)(()=>{M.value,Q.value,T.value,k.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"||nt())}),(0,n.watch)(U,l=>{let d=(0,n.$)("session-filter-badge");d&&(d.style.display=l?"inline":"none",d.title=l||"")}),(0,n.effect)(()=>{let l=y.value;if(l&&l.path)ta(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 x=p===l;m.classList.toggle("hidden",!x),x?(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"&&gs(),l==="shell"&&requestAnimationFrame(()=>{document.dispatchEvent(new CustomEvent("shell-tab-shown"))})}),ha(),ma();let o=null;document.addEventListener("sessions-changed",()=>{o&&clearTimeout(o),o=setTimeout(()=>{o=null,ve({waitFresh:!1})},1200)}),document.addEventListener("router:home",Hn),document.addEventListener("router:session",async({detail:{id:l,tab:d}})=>{let p=M.peek().find(x=>x.sessionId===l),m=Je();await we(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",Hn),n.delegate.on("click","#auth-btn",ga),n.delegate.on("keydown","#auth-username, #auth-password",l=>{l.key==="Enter"&&ga()}),n.delegate.on("click","#hamburger",()=>(0,n.$)("sidebar").classList.contains("open")?On():ua()),n.delegate.on("click","#sidebar-overlay",On),n.delegate.on("input","#session-search",(l,d)=>{N.value=d.value,In(d.value)}),n.delegate.on("click","#session-filter-badge",()=>{U.value=null}),n.delegate.on("click","[data-ws-tab]",(l,d)=>{U.value=d.dataset.wsTab||null}),n.delegate.on("click","#sidebar-refresh",()=>{ve(),N.peek().trim()&&xs(N.peek())}),n.delegate.on("click","[data-view]",(l,d)=>{Se.value=d.dataset.view,localStorage.setItem("sidebarView",d.dataset.view)}),n.delegate.on("click","[data-agent-filter]",(l,d)=>{Q.value=d.dataset.agentFilter,localStorage.setItem("agentFilter",d.dataset.agentFilter),N.peek().trim()&&In(N.peek())}),n.delegate.on("change","#time-range",(l,d)=>{te.value=d.value,localStorage.setItem("timeRange",d.value),ve({waitFresh:!0}),N.peek().trim()&&In(N.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;ws({id:m,name:m,path:p}),b(`Project \xB7 ${p}`)}),n.delegate.on("click","#btn-pwa-install",async()=>{await Qs()||Ii()}),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",()=>_o()),n.delegate.on("click","#btn-meta-agent-welcome",()=>ps("chat")),n.delegate.on("click","#btn-theme",ba),n.delegate.on("click","#btn-cal-prev",()=>{fs(-1),nt(_e())}),n.delegate.on("click","#btn-cal-next",()=>{fs(1),nt(_e())}),n.delegate.on("click","[data-cal-date]",(l,d)=>{Jo(d.dataset.calDate),nt(_e())}),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")||(we(d.dataset.sessionId,d.dataset.sessionCwd||null,d.dataset.sessionConfigDir||null,d.dataset.sessionAgent||"claude",d.dataset.sessionMachine||null),fa())}),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&&ys({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(),!f.sessionId)return;let p=document.getElementById("session-title-display")||d;ys({sessionId:f.sessionId,agent:f.agent||S.peek()||"claude",machineId:f.machineId||null,mountEl:p})}),n.delegate.on("click","[data-folder]",(l,d)=>{let p=d.dataset.folder,x=d.querySelector("span")?.textContent.trim()==="\u25BE",g=new Set(ot.peek()),W=new Set(at.peek());x?(g.delete(p),W.add(p)):(g.add(p),W.delete(p)),(0,n.batch)(()=>{ot.value=g,at.value=W})}),n.delegate.on("click","#memory-refresh",gs),n.delegate.on("click","[data-tab]",(l,d)=>Pe(d.dataset.tab));let a=async(l,d)=>{let p=(0,n.$)(l),m=p?.value.trim();if(!m){d.value="";return}try{let x=await h("POST","/api/resolve-path",{path:m});if(x.isDir===!1)throw new Error("Path is not a directory on the target machine");d.value=x.path,p.value=x.path;let g=y.peek();g&&(y.value={...g,path:x.path})}catch(x){p.style.color="oklch(var(--er))",p.title=x.message,setTimeout(()=>{p.style.color="",p.title=""},2e3)}};n.delegate.on("click","#files-root-btn",()=>a("files-root-input",F)),n.delegate.on("click","#git-root-btn",()=>a("git-root-input",J)),n.delegate.on("keydown","#files-root-input",l=>{l.key==="Enter"&&a("files-root-input",F)}),n.delegate.on("keydown","#git-root-input",l=>{l.key==="Enter"&&a("git-root-input",J)}),n.delegate.on("click","#btn-opts",()=>{(0,n.$)("chat-opts").classList.toggle("hidden")}),n.delegate.on("change","#sel-agent",(l,d)=>{let p=S.peek(),m=d.value;p!==m&&(f.sessionId=null,me(m),$.value=re(m)||$.peek(),localStorage.setItem("model",$.peek()),ye(),b(`Agent \u2192 ${R[m]||m} \xB7 model ${$.peek()} \xB7 new session`))}),n.delegate.on("change","#sel-convert-agent",async(l,d)=>{let p=d.value;if(!p)return;let m=f.sessionId;if(!m){alert("No active session to convert."),d.value="";return}let x=f.agent||S.peek()||"claude";if(x===p){alert("Cannot convert to the same agent."),d.value="";return}d.disabled=!0,b(`Converting session ${m.slice(0,8)} from ${x} to ${p}...`);try{let g=await h("POST",`/api/sessions/${m}/convert`,{targetAgent:p,sourceAgent:x});g&&g.success?(b(`\u2713 Converted successfully. New session: ${g.targetSessionId.slice(0,8)}`),await ve(),await we(g.targetSessionId,y.peek()?.path||null,null,g.targetAgent),bn()):b("Failed to convert session.")}catch(g){b(`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)=>{$.value=d.value,localStorage.setItem("model",d.value),hs()}),n.delegate.on("click","#btn-model-add",()=>bs({editCurrent:!1})),n.delegate.on("click","#btn-model-edit",()=>bs({editCurrent:!0})),n.delegate.on("change","#sel-effort",(l,d)=>{pe.value=d.value}),n.delegate.on("change","#sel-permission",(l,d)=>{Lt.value=d.value}),n.delegate.on("change","#sel-density",(l,d)=>{Yn(d.value),b(`Density \u2192 ${d.value} (applies to new tool calls; reload session to re-group history)`)}),document.addEventListener("agent-changed",ye),n.delegate.on("click","#btn-new-session, #btn-new-session-welcome",xa),n.delegate.on("click","#new-session-cancel",()=>(0,n.$)("modal-new-session").close()),n.delegate.on("click","#new-session-start",Ts),n.delegate.on("change","#new-session-agent",Ls),n.delegate.on("keydown","#new-session-path",l=>{l.key==="Enter"&&Ts()}),n.delegate.on("click","#send-btn",mn),n.delegate.on("click","#stop-btn",bo),n.delegate.on("click","#btn-logout",()=>{f.token=null,localStorage.removeItem("token"),Z(null),Ee.value=!1,location.reload()}),n.delegate.on("click","[data-pick-machine]",async(l,d)=>{let p=d.dataset.pickMachine;if(!p||p===T.peek()){Kt();return}await pa(p,{forceReload:!0})});let i=async()=>{let l=(0,n.$)("machine-picker-status");if(l&&(l.textContent="\u5237\u65B0\u4E2D\u2026"),await yt(),ks(),Nn(),st(),l){let d=(D.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(),Mn();let d=(0,n.$)("machine-menu");d&&(d.classList.contains("hidden")?(await yt(),Nn(),d.classList.remove("hidden")):d.classList.add("hidden"))}),n.delegate.on("click","#btn-recent-sessions",l=>{l.stopPropagation(),Kt();let d=(0,n.$)("recent-menu");d&&(d.classList.contains("hidden")?(zo(_e()),d.classList.remove("hidden")):d.classList.add("hidden"))}),document.addEventListener("click",l=>{let d=(0,n.$)("machine-menu-wrap");d&&!d.contains(l.target)&&Kt();let p=(0,n.$)("recent-menu-wrap");p&&!p.contains(l.target)&&Mn()}),n.delegate.on("click","#recent-menu [data-session-id]",()=>{Mn()}),n.delegate.on("click","#btn-edit-project-notes, #project-goal-text, #project-notes-text",()=>{na()}),n.delegate.on("click","#btn-cancel-project-notes",()=>{vt()});let r=async()=>{let l=(0,n.$)("project-goal-input")?.value?.trim()??"",d=(0,n.$)("project-notes-input")?.value?.trim()??"",p=y.peek();if(!(!p||!p.path))try{let m=await h("POST","/api/projects/notes",{root:p.path,goal:l,notes:d});ea(m.goal||"",m.notes||""),vt()}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"&&vt()}),n.delegate.on("keydown","#project-notes-input",l=>{l.key==="Escape"&&vt()}),n.delegate.on("click","[data-fav-toggle]",(l,d)=>{l.stopPropagation(),l.preventDefault();let p=d.dataset.favSessionMachine||f.machineId;p&&(f.machineId=p,localStorage.setItem("machineId",p)),aa(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||f.machineId;p&&(f.machineId=p,localStorage.setItem("machineId",p)),ia(d.dataset.hideSessionId,d.dataset.hideSessionAgent||"claude",{machineId:p||null})}),n.delegate.on("click","#btn-edit-session-notes, #session-notes-text",()=>{sa()}),n.delegate.on("click","#btn-cancel-session-notes",()=>ce()),n.delegate.on("click","#btn-save-session-notes",async()=>{let l=(0,n.$)("session-notes-input")?.value?.trim()||"";if(!f.sessionId)return;let d=f.agent||S.peek()||"claude";await vs(f.sessionId,d,l)&&ce()}),n.delegate.on("keydown","#session-notes-input",async l=>{if(l.key==="Escape"&&ce(),l.key==="Enter"){let d=l.target.value.trim();if(!f.sessionId)return;let p=f.agent||S.peek()||"claude";await vs(f.sessionId,p,d)&&ce()}}),n.delegate.on("click","#btn-fav-filter",()=>{let l=!He.peek();He.value=l,localStorage.setItem("favoritesOnly",l?"1":"0"),(0,n.$)("btn-fav-filter")?.classList.toggle("active",l),l&&Ne.peek()&&(Ne.value=!1,localStorage.setItem("showHiddenOnly","0"),(0,n.$)("btn-hidden-filter")?.classList.remove("active"))}),n.delegate.on("click","#btn-hidden-filter",()=>{let l=!Ne.peek();Ne.value=l,localStorage.setItem("showHiddenOnly",l?"1":"0"),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",l),l&&He.peek()&&(He.value=!1,localStorage.setItem("favoritesOnly","0"),(0,n.$)("btn-fav-filter")?.classList.remove("active"))}),ye(),fn();let c=(0,n.$)("sel-density");c&&(c.value=Te.peek()||"normal");let u=(0,n.$)("time-range");u&&(u.value=te.peek()||"14"),document.querySelectorAll("[data-agent-filter]").forEach(l=>{l.classList.toggle("active",l.dataset.agentFilter===Q.peek())}),(0,n.$)("btn-fav-filter")?.classList.toggle("active",He.peek()),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",Ne.peek()),document.querySelectorAll("[data-view]").forEach(l=>{let d=l.dataset.view===Se.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)})}mt();C();I();K();function Ci(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 Ai(e){let t=(e||"").split("/").pop()||"",s=t.lastIndexOf(".");return s>=0?t.slice(s+1).toLowerCase():""}function ya(e){let t=Ai(e);return t==="docx"||t==="pptx"||t==="xlsx"||t==="pdf"?t:null}function ji(e){return e==null?"":e>1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:e>1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function Di(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 Is=new Map;function Un(e){if(Is.has(e))return Is.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 Is.set(e,t),t}function _i(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 Pi(e){!e||typeof hljs>"u"||e.querySelectorAll("pre code.file-preview-code").forEach(t=>{try{delete t.dataset.highlighted,hljs.highlightElement(t)}catch{}})}function Vt(e,t,s){let o=ji(t);return`
|
|
846
|
+
</button>`).join("")}),(0,n.effect)(()=>{Re.value,ze.value,Le.value,Me.value,ue.value,v.value;let l=(0,n.$)("session-list");l&&(l.querySelector(".session-rename-input")||(l.innerHTML=Zo(),ea()))}),(0,n.effect)(()=>{E.value,Q.value,M.value,k.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"||nt())}),(0,n.watch)(O,l=>{let d=(0,n.$)("session-filter-badge");d&&(d.style.display=l?"inline":"none",d.title=l||"")}),(0,n.effect)(()=>{let l=y.value;if(l&&l.path)na(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 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"&&vs(),l==="shell"&&requestAnimationFrame(()=>{document.dispatchEvent(new CustomEvent("shell-tab-shown"))})}),ba(),ha();let o=null;document.addEventListener("sessions-changed",()=>{o&&clearTimeout(o),o=setTimeout(()=>{o=null,ye({waitFresh:!1})},1200)}),document.addEventListener("router:home",Pn),document.addEventListener("router:session",async({detail:{id:l,tab:d}})=>{let p=E.peek().find(b=>b.sessionId===l),m=Je();await ke(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",Pn),n.delegate.on("click","#auth-btn",va),n.delegate.on("keydown","#auth-username, #auth-password",l=>{l.key==="Enter"&&va()}),n.delegate.on("click","#hamburger",()=>(0,n.$)("sidebar").classList.contains("open")?Bn():fa()),n.delegate.on("click","#sidebar-overlay",Bn),n.delegate.on("input","#session-search",(l,d)=>{N.value=d.value,In(d.value)}),n.delegate.on("click","#session-filter-badge",()=>{O.value=null}),n.delegate.on("click","[data-ws-tab]",(l,d)=>{O.value=d.dataset.wsTab||null}),n.delegate.on("click","#sidebar-refresh",()=>{ye(),N.peek().trim()&&gs(N.peek())}),n.delegate.on("click","[data-view]",(l,d)=>{Le.value=d.dataset.view,localStorage.setItem("sidebarView",d.dataset.view)}),n.delegate.on("click","[data-agent-filter]",(l,d)=>{Q.value=d.dataset.agentFilter,localStorage.setItem("agentFilter",d.dataset.agentFilter),N.peek().trim()&&In(N.peek())}),n.delegate.on("change","#time-range",(l,d)=>{te.value=d.value,localStorage.setItem("timeRange",d.value),ye({waitFresh:!0}),N.peek().trim()&&In(N.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;ks({id:m,name:m,path:p}),x(`Project \xB7 ${p}`)}),n.delegate.on("click","#btn-pwa-install",async()=>{await Zs()||ji()}),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",()=>Ho()),n.delegate.on("click","#btn-meta-agent-welcome",()=>ps("chat")),n.delegate.on("click","#btn-theme",xa),n.delegate.on("click","#btn-cal-prev",()=>{ms(-1),nt(ve())}),n.delegate.on("click","#btn-cal-next",()=>{ms(1),nt(ve())}),n.delegate.on("click","[data-cal-date]",(l,d)=>{Ko(d.dataset.calDate),nt(ve())}),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")||(ke(d.dataset.sessionId,d.dataset.sessionCwd||null,d.dataset.sessionConfigDir||null,d.dataset.sessionAgent||"claude",d.dataset.sessionMachine||null),ma())}),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&&ws({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(),!f.sessionId)return;let p=document.getElementById("session-title-display")||d;ws({sessionId:f.sessionId,agent:f.agent||S.peek()||"claude",machineId:f.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(ot.peek()),W=new Set(at.peek());b?(g.delete(p),W.add(p)):(g.add(p),W.delete(p)),(0,n.batch)(()=>{ot.value=g,at.value=W})}),n.delegate.on("click","#memory-refresh",vs),n.delegate.on("click","[data-tab]",(l,d)=>He(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=y.peek();g&&(y.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",F)),n.delegate.on("click","#git-root-btn",()=>a("git-root-input",J)),n.delegate.on("keydown","#files-root-input",l=>{l.key==="Enter"&&a("files-root-input",F)}),n.delegate.on("keydown","#git-root-input",l=>{l.key==="Enter"&&a("git-root-input",J)}),n.delegate.on("click","#btn-opts",()=>{(0,n.$)("chat-opts").classList.toggle("hidden")}),n.delegate.on("change","#sel-agent",(l,d)=>{let p=S.peek(),m=d.value;p!==m&&(f.sessionId=null,me(m),$.value=re(m)||$.peek(),localStorage.setItem("model",$.peek()),we(),x(`Agent \u2192 ${R[m]||m} \xB7 model ${$.peek()} \xB7 new session`))}),n.delegate.on("change","#sel-convert-agent",async(l,d)=>{let p=d.value;if(!p)return;let m=f.sessionId;if(!m){alert("No active session to convert."),d.value="";return}let b=f.agent||S.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 ye(),await ke(g.targetSessionId,y.peek()?.path||null,null,g.targetAgent),xn()):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)=>{$.value=d.value,localStorage.setItem("model",d.value),bs()}),n.delegate.on("click","#btn-model-add",()=>xs({editCurrent:!1})),n.delegate.on("click","#btn-model-edit",()=>xs({editCurrent:!0})),n.delegate.on("change","#sel-effort",(l,d)=>{pe.value=d.value}),n.delegate.on("change","#sel-permission",(l,d)=>{Mt.value=d.value}),n.delegate.on("change","#sel-density",(l,d)=>{Yn(d.value),x(`Density \u2192 ${d.value} (applies to new tool calls; reload session to re-group history)`)}),document.addEventListener("agent-changed",we),n.delegate.on("click","#btn-new-session, #btn-new-session-welcome",ga),n.delegate.on("click","#new-session-cancel",()=>(0,n.$)("modal-new-session").close()),n.delegate.on("click","#new-session-start",Ts),n.delegate.on("change","#new-session-agent",Ms),n.delegate.on("keydown","#new-session-path",l=>{l.key==="Enter"&&Ts()}),n.delegate.on("click","#send-btn",hn),n.delegate.on("click","#stop-btn",xo),n.delegate.on("click","#btn-logout",()=>{f.token=null,localStorage.removeItem("token"),Z(null),Ee.value=!1,location.reload()}),n.delegate.on("click","[data-pick-machine]",async(l,d)=>{let p=d.dataset.pickMachine;if(!p||p===M.peek()){Vt();return}await ua(p,{forceReload:!0})});let i=async()=>{let l=(0,n.$)("machine-picker-status");if(l&&(l.textContent="\u5237\u65B0\u4E2D\u2026"),await wt(),$s(),Nn(),st(),l){let d=(D.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(),gt();let d=(0,n.$)("machine-menu");d&&(d.classList.contains("hidden")?(await wt(),Nn(),d.classList.remove("hidden")):d.classList.add("hidden"))}),n.delegate.on("click","#btn-recent-sessions",l=>{l.preventDefault(),l.stopPropagation(),Vt(),Jo(ve());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(),gt(),(0,n.$)("btn-recent-sessions")?.setAttribute("aria-expanded","false")}),document.addEventListener("click",l=>{let d=(0,n.$)("machine-menu-wrap");d&&!d.contains(l.target)&&Vt();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;gt(),m?.setAttribute("aria-expanded","false")}}),window.addEventListener("resize",()=>{(0,n.$)("recent-menu")&&!(0,n.$)("recent-menu").classList.contains("hidden")&&fs()}),n.delegate.on("click","#recent-menu [data-session-id]",()=>{gt(),(0,n.$)("btn-recent-sessions")?.setAttribute("aria-expanded","false")}),n.delegate.on("click","#btn-edit-project-notes, #project-goal-text, #project-notes-text",()=>{sa()}),n.delegate.on("click","#btn-cancel-project-notes",()=>{yt()});let r=async()=>{let l=(0,n.$)("project-goal-input")?.value?.trim()??"",d=(0,n.$)("project-notes-input")?.value?.trim()??"",p=y.peek();if(!(!p||!p.path))try{let m=await h("POST","/api/projects/notes",{root:p.path,goal:l,notes:d});ta(m.goal||"",m.notes||""),yt()}catch(m){alert(`Error saving project notes: ${m.message}`)}};n.delegate.on("click","#btn-save-project-notes",r),n.delegate.on("keydown","#project-goal-input",l=>{l.key==="Enter"&&r(),l.key==="Escape"&&yt()}),n.delegate.on("keydown","#project-notes-input",l=>{l.key==="Escape"&&yt()}),n.delegate.on("click","[data-fav-toggle]",(l,d)=>{l.stopPropagation(),l.preventDefault();let p=d.dataset.favSessionMachine||f.machineId;p&&(f.machineId=p,localStorage.setItem("machineId",p)),ia(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||f.machineId;p&&(f.machineId=p,localStorage.setItem("machineId",p)),ra(d.dataset.hideSessionId,d.dataset.hideSessionAgent||"claude",{machineId:p||null})}),n.delegate.on("click","#btn-edit-session-notes, #session-notes-text",()=>{oa()}),n.delegate.on("click","#btn-cancel-session-notes",()=>ce()),n.delegate.on("click","#btn-save-session-notes",async()=>{let l=(0,n.$)("session-notes-input")?.value?.trim()||"";if(!f.sessionId)return;let d=f.agent||S.peek()||"claude";await ys(f.sessionId,d,l)&&ce()}),n.delegate.on("keydown","#session-notes-input",async l=>{if(l.key==="Escape"&&ce(),l.key==="Enter"){let d=l.target.value.trim();if(!f.sessionId)return;let p=f.agent||S.peek()||"claude";await ys(f.sessionId,p,d)&&ce()}}),n.delegate.on("click","#btn-fav-filter",()=>{let l=!Pe.peek();Pe.value=l,localStorage.setItem("favoritesOnly",l?"1":"0"),(0,n.$)("btn-fav-filter")?.classList.toggle("active",l),l&&Ne.peek()&&(Ne.value=!1,localStorage.setItem("showHiddenOnly","0"),(0,n.$)("btn-hidden-filter")?.classList.remove("active"))}),n.delegate.on("click","#btn-hidden-filter",()=>{let l=!Ne.peek();Ne.value=l,localStorage.setItem("showHiddenOnly",l?"1":"0"),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",l),l&&Pe.peek()&&(Pe.value=!1,localStorage.setItem("favoritesOnly","0"),(0,n.$)("btn-fav-filter")?.classList.remove("active"))}),we(),mn();let c=(0,n.$)("sel-density");c&&(c.value=Te.peek()||"normal");let u=(0,n.$)("time-range");u&&(u.value=te.peek()||"14"),document.querySelectorAll("[data-agent-filter]").forEach(l=>{l.classList.toggle("active",l.dataset.agentFilter===Q.peek())}),(0,n.$)("btn-fav-filter")?.classList.toggle("active",Pe.peek()),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",Ne.peek()),document.querySelectorAll("[data-view]").forEach(l=>{let d=l.dataset.view===Le.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)})}mt();C();I();K();function Di(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 _i(e){let t=(e||"").split("/").pop()||"",s=t.lastIndexOf(".");return s>=0?t.slice(s+1).toLowerCase():""}function wa(e){let t=_i(e);return t==="docx"||t==="pptx"||t==="xlsx"||t==="pdf"?t:null}function Hi(e){return e==null?"":e>1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:e>1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function Pi(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 Cs=new Map;function On(e){if(Cs.has(e))return Cs.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 Cs.set(e,t),t}function Ni(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 Ri(e){!e||typeof hljs>"u"||e.querySelectorAll("pre code.file-preview-code").forEach(t=>{try{delete t.dataset.highlighted,hljs.highlightElement(t)}catch{}})}function Yt(e,t,s){let o=Hi(t);return`
|
|
844
847
|
<div class="flex items-center gap-2 px-4 py-1.5 border-b border-base-300 flex-shrink-0 bg-base-200">
|
|
845
848
|
<span class="text-xs text-base-content/40 flex-1 truncate">${(0,n.esc)(e)} \xB7 ${(0,n.esc)(o)}${s?` \xB7 <span class="text-primary/70">${(0,n.esc)(s)}</span>`:""}</span>
|
|
846
849
|
<button type="button" class="btn btn-ghost btn-xs" data-download-path="${(0,n.esc)(e)}">\u2193 Download</button>
|
|
847
|
-
</div>`}function
|
|
850
|
+
</div>`}function Bi(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=>`
|
|
848
851
|
<div class="flex items-center gap-2 px-4 py-1.5 hover:bg-base-300 group"
|
|
849
852
|
${t.isDir?`data-dir-path="${(0,n.esc)(t.path)}"`:`data-file-path="${(0,n.esc)(t.path)}"`}>
|
|
850
|
-
<span class="cursor-pointer flex-shrink-0">${t.isDir?"\u{1F4C1}":
|
|
853
|
+
<span class="cursor-pointer flex-shrink-0">${t.isDir?"\u{1F4C1}":Di(t.name)}</span>
|
|
851
854
|
<span class="text-sm flex-1 truncate cursor-pointer ${t.isDir?"text-primary":""}">${(0,n.esc)(t.name)}</span>
|
|
852
855
|
${t.isDir?"":`
|
|
853
856
|
<button type="button" class="file-row-action btn btn-ghost btn-xs px-1.5 text-base-content/50 hover:text-base-content"
|
|
854
857
|
data-download-path="${(0,n.esc)(t.path)}" title="Download" aria-label="Download">\u2193</button>
|
|
855
858
|
<button type="button" class="file-row-action btn btn-ghost btn-xs px-1.5 text-error/60 hover:text-error"
|
|
856
859
|
data-delete-path="${(0,n.esc)(t.path)}" title="Delete" aria-label="Delete">\u2715</button>`}
|
|
857
|
-
</div>`).join(""))}function
|
|
860
|
+
</div>`).join(""))}function Oi(e,t,s){let o=/[\x00-\x08\x0e-\x1f]/.test(t.slice(0,512)),a=Ni(e),i=a?`language-${(0,n.esc)(a)}`:"",r=o?`<div class="p-4 text-xs text-base-content/40">Binary file \u2014 <button class="text-primary hover:underline" data-download-path="${(0,n.esc)(e)}">Download</button></div>`:`<pre class="file-preview p-4 font-mono text-xs leading-relaxed overflow-auto flex-1 m-0"><code class="hljs file-preview-code ${i}">${(0,n.esc)(t)}</code></pre>`;return Yt(e,s,o?"binary":a||"text")+r}async function Ui(e){if(await On("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 Fi(e){if(await On("https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js"),typeof XLSX>"u")throw new Error("SheetJS failed to load");let t=XLSX.read(new Uint8Array(e),{type:"array"}),s=t.SheetNames||[];if(!s.length)return'<div class="p-4 text-xs text-base-content/40">Empty workbook</div>';let o=s.map((i,r)=>`<button type="button" class="office-sheet-tab${r===0?" active":""}" data-sheet-idx="${r}">${(0,n.esc)(i)}</button>`).join(""),a=s.map((i,r)=>{let c=t.Sheets[i],u;try{u=XLSX.utils.sheet_to_html(c,{id:`xlsx-sheet-${r}`,editable:!1})}catch{u='<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}">${u}</div>`}).join("");return`
|
|
858
861
|
<div class="office-preview office-xlsx flex flex-col flex-1 min-h-0 overflow-hidden">
|
|
859
862
|
<div class="office-sheet-tabs flex gap-1 px-2 py-1.5 border-b border-base-300 overflow-x-auto flex-shrink-0 bg-base-200">${o}</div>
|
|
860
863
|
<div class="office-sheet-body flex-1 overflow-auto p-2">${a}</div>
|
|
861
|
-
</div>`}function
|
|
864
|
+
</div>`}function qi(e){let t=[],s=/<a:p[\s>][\s\S]*?<\/a:p>/g,o=/<a:t(?:\s[^>]*)?>([\s\S]*?)<\/a:t>/g,a,i=e.match(s)||[e];for(let r of i){let c=[];for(o.lastIndex=0;(a=o.exec(r))!==null;){let u=a[1].replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&").replace(/"/g,'"').replace(/'/g,"'");u&&c.push(u)}c.length&&t.push(c.join(""))}return t}async function Wi(e){if(await On("https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"),typeof JSZip>"u")throw new Error("JSZip failed to load");let t=await JSZip.loadAsync(e),s=Object.keys(t.files).filter(a=>/^ppt\/slides\/slide\d+\.xml$/i.test(a)).sort((a,i)=>{let r=parseInt(a.match(/slide(\d+)/i)?.[1]||"0",10),c=parseInt(i.match(/slide(\d+)/i)?.[1]||"0",10);return r-c});if(!s.length)return'<div class="p-4 text-xs text-base-content/40">No slides found in this presentation</div>';let o=[];for(let a=0;a<s.length;a++){let i=await t.files[s[a]].async("string"),r=qi(i),c=r.length?r.map(u=>`<p>${(0,n.esc)(u)}</p>`).join(""):'<p class="text-base-content/40 italic">\uFF08\u6B64\u9875\u65E0\u53EF\u63D0\u53D6\u6587\u672C / \u53EF\u80FD\u4EE5\u56FE\u7247\u4E3A\u4E3B\uFF09</p>';o.push(`
|
|
862
865
|
<article class="office-slide-card">
|
|
863
866
|
<header class="office-slide-num">Slide ${a+1}</header>
|
|
864
867
|
<div class="office-slide-body">${c}</div>
|
|
@@ -866,7 +869,7 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
866
869
|
<div class="office-preview office-pptx overflow-auto flex-1 p-3 space-y-3">
|
|
867
870
|
<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>
|
|
868
871
|
${o.join("")}
|
|
869
|
-
</div>`}async function
|
|
872
|
+
</div>`}async function Gi(){if(await On("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 zi(e){let s=await(await Gi()).getDocument({data:e}).promise,o=s.numPages,a=Math.min(o,40),i=[];for(let c=1;c<=a;c++){let u=await s.getPage(c),l=u.getViewport({scale:1}),d=Math.min(1.5,820/l.width),p=u.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 u.render({canvasContext:m.getContext("2d"),viewport:p}).promise,i.push(`
|
|
870
873
|
<figure class="office-pdf-figure">
|
|
871
874
|
<figcaption class="office-pdf-cap">Page ${c} / ${o}</figcaption>
|
|
872
875
|
${m.outerHTML}
|
|
@@ -875,12 +878,12 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
875
878
|
<p class="text-xs text-base-content/50 px-1">PDF preview \xB7 ${o} page(s)</p>
|
|
876
879
|
${r}
|
|
877
880
|
${i.join("")}
|
|
878
|
-
</div>`}async function
|
|
879
|
-
${
|
|
881
|
+
</div>`}async function Ji(e,t,s){let o=wa(e),a={docx:"Word",pptx:"PowerPoint",xlsx:"Excel",pdf:"PDF"},i=Pi(t),r;if(o==="docx")r=await Ui(i);else if(o==="xlsx")r=await Fi(i);else if(o==="pptx")r=await Wi(i);else if(o==="pdf")r=await zi(i);else throw new Error("Unsupported office type");return Yt(e,s,a[o]||o)+r}function Ki(e,t){let s=e?e.split("/"):[],o=t?s.slice(0,-1):s,a='<span class="cursor-pointer text-primary hover:underline" data-dir-path="">root</span>',i="";for(let r of o)i=i?`${i}/${r}`:r,a+=` <span class="text-base-content/40">/</span> <span class="cursor-pointer text-primary hover:underline" data-dir-path="${(0,n.esc)(i)}">${(0,n.esc)(r)}</span>`;return t&&(a+=` <span class="text-base-content/40">/</span> <span>${(0,n.esc)(s.at(-1))}</span>`),a}function Vi(){let e=y.peek(),t=F.peek()||e?.path;if(!t)return;let s=document.createElement("input");s.type="file",s.multiple=!0,s.addEventListener("change",async()=>{let o=A.peek(),a=e?.id||"_",i=[...s.files],r=!1;for(let c of i){let u=o?`${o}/${c.name}`:c.name,l=`/api/projects/${a}/file?root=${encodeURIComponent(t)}&path=${encodeURIComponent(u)}`;try{let d=await fetch(l,{method:"POST",headers:lt(),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=A.peek();A.value=c+"\0",A.value=c}}),s.click()}async function Yi(e,t){let s=F.peek()||e?.path||"";if(!s){alert("No path selected \u2014 set root first");return}let o=e?.id||"_",a=(t||"").split("/").pop()||"download",i=new URLSearchParams({root:s,path:t,download:"true"}),r=`/api/projects/${o}/file?${i}`;try{let c=await fetch(r,{headers:lt(),credentials:"same-origin"});if(!c.ok){let p=await c.json().catch(()=>({}));throw new Error(p.error||`HTTP ${c.status}`)}let u=await c.blob(),l=URL.createObjectURL(u),d=document.createElement("a");d.href=l,d.download=a,d.rel="noopener",d.style.display="none",document.body.appendChild(d),d.click(),d.remove(),setTimeout(()=>URL.revokeObjectURL(l),6e4)}catch(c){try{let u=`/api/projects/${o}/file?${Vs({root:s,path:t,download:"true"})}`,l=document.createElement("a");l.href=u,l.download=a,l.rel="noopener",l.target="_blank",document.body.appendChild(l),l.click(),l.remove()}catch{alert(`Download failed: ${c.message}`)}}}async function Xi(e,t){if(!confirm(`Delete "${t.split("/").pop()}"?`))return;let s=F.peek()||e?.path||"",o=e?.id||"_";try{await h("DELETE",`/api/projects/${o}/file?root=${encodeURIComponent(s)}&path=${encodeURIComponent(t)}`),A.value=A.peek()+" ",A.value=A.peek().trimEnd()}catch(a){alert(`Delete failed: ${a.message}`)}}async function Qi(e,t,s,o){let a=s.size??(typeof s.content=="string"?s.content.length:0),i=wa(t);if(i&&s.encoding==="base64"){e.innerHTML=Yt(t,a,i)+`<div class="p-4 text-xs text-base-content/40">Parsing ${i.toUpperCase()}\u2026</div>`;try{let r=await Ji(t,s.content,a);if(o.aborted)return;e.innerHTML=r}catch(r){if(o.aborted)return;e.innerHTML=Yt(t,a,i)+`<div class="p-4 text-xs text-error">Preview failed: ${(0,n.esc)(r.message)} \u2014 <button class="text-primary hover:underline" data-download-path="${(0,n.esc)(t)}">Download</button></div>`}return}if(s.encoding==="base64"){e.innerHTML=Yt(t,a,"binary")+`<div class="p-4 text-xs text-base-content/40">Binary file \u2014 <button class="text-primary hover:underline" data-download-path="${(0,n.esc)(t)}">Download</button></div>`;return}e.innerHTML=Oi(t,s.content||"",a),Ri(e)}function ka(){(0,n.effect)(()=>{let e=(0,n.$)("files-breadcrumb");if(!e)return;let t=U.value!==null;e.innerHTML=`
|
|
882
|
+
${Ki(U.value??A.value,t)}
|
|
880
883
|
<div class="flex-1"></div>
|
|
881
|
-
${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=y.value,o=(F.value||s?.path||"").trim(),a=
|
|
884
|
+
${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=y.value,o=(F.value||s?.path||"").trim(),a=U.value,i=A.value,r=(0,n.$)("files-area");if(!r||t!=="files")return;if(!o){r.innerHTML='<div class="p-4 text-xs text-base-content/40">No path yet \u2014 open a session (uses that machine's cwd) or type an absolute path and press Go.</div>';return}let c=s?.id||"_";r.innerHTML='<div class="p-4 text-xs text-base-content/40">Loading\u2026</div>';try{if(a!==null){let d=await h("GET",`/api/projects/${c}/file?root=${encodeURIComponent(o)}&path=${encodeURIComponent(a)}`,void 0,e);e.aborted||await Qi(r,a,d,e);return}let u=await h("GET",`/api/projects/${c}/files?root=${encodeURIComponent(o)}&path=${encodeURIComponent(i)}`,void 0,e);if(e.aborted)return;let l=Array.isArray(u)?u:Array.isArray(u?.files)?u.files:null;if(!l){r.innerHTML=`<div class="p-4 text-xs text-error">${(0,n.esc)(u?.error||"Invalid directory listing")}</div>`;return}r.innerHTML=Bi(l)}catch(u){!e.aborted&&u?.name!=="AbortError"&&(r.innerHTML=`<div class="p-4 text-xs text-error">${(0,n.esc)(u.message)}</div>`)}}),n.delegate.on("click","[data-dir-path]",(e,t)=>{U.value=null,A.value=t.dataset.dirPath}),n.delegate.on("click","[data-file-path]",(e,t)=>{U.value=t.dataset.filePath}),n.delegate.on("click","#btn-upload",()=>Vi()),n.delegate.on("click","[data-download-path]",(e,t)=>{e.preventDefault(),e.stopPropagation();let s=t.dataset.downloadPath;s&&Yi(y.peek(),s)}),n.delegate.on("click","[data-delete-path]",(e,t)=>{e.preventDefault(),e.stopPropagation();let s=t.dataset.deletePath;s&&Xi(y.peek(),s)}),n.delegate.on("click",".office-sheet-tab",(e,t)=>{let s=t.closest(".office-xlsx");if(!s)return;let o=t.dataset.sheetIdx;s.querySelectorAll(".office-sheet-tab").forEach(a=>a.classList.toggle("active",a===t)),s.querySelectorAll(".office-sheet-pane").forEach(a=>{a.classList.toggle("hidden",a.dataset.sheetPane!==o)})})}C();I();K();var $a=(0,n.signal)(!1);function Zi(e){return e?e.split(`
|
|
882
885
|
`).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(`
|
|
883
|
-
`):'<span class="text-base-content/40">No commits</span>'}function
|
|
886
|
+
`):'<span class="text-base-content/40">No commits</span>'}function er(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`
|
|
884
887
|
<div class="px-4 py-2 text-xs text-base-content/50 border-b border-base-300">
|
|
885
888
|
Branch: <span class="text-success font-semibold">${(0,n.esc)(e.branch)}</span>
|
|
886
889
|
</div>
|
|
@@ -906,16 +909,16 @@ Available: ${u}`:""}`),!0}let a=Ja[o.toLowerCase()]||o,i=S.peek()||"claude",r=fe
|
|
|
906
909
|
<span class="text-base-content/40">Loading\u2026</span>
|
|
907
910
|
</div>
|
|
908
911
|
</div>
|
|
909
|
-
</div>`}function
|
|
912
|
+
</div>`}function tr(e){return e.split(`
|
|
910
913
|
`).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(`
|
|
911
|
-
`)}function
|
|
912
|
-
`),
|
|
914
|
+
`)}function Sa(){(0,n.asyncEffect)(async e=>{let t=j.value,s=y.value,o=J.value||s?.path,a=(0,n.$)("git-area");if(!a||t!=="git")return;if(!o){a.innerHTML='<div class="p-4 text-sm text-base-content/50">Enter a project root above, or open a session with a working directory.</div>';return}let i=s?.id||"_";a.innerHTML='<div class="p-4 text-xs text-base-content/40">Loading\u2026</div>';try{let r=await h("GET",`/api/projects/${i}/git/status?root=${encodeURIComponent(o)}`,void 0,e);e.aborted||(a.innerHTML=er(r))}catch(r){!e.aborted&&r?.name!=="AbortError"&&(a.innerHTML=`<div class="p-4 text-xs text-error">${(0,n.esc)(r?.message??String(r))}</div>`)}}),(0,n.asyncEffect)(async e=>{let t=y.value,s=J.value||t?.path,o=$a.value,a=(0,n.$)("diff-content");if(!a||!s)return;let i=t?.id||"_";try{let r=await h("GET",`/api/projects/${i}/git/diff?root=${encodeURIComponent(s)}${o?"&staged=true":""}`,void 0,e);e.aborted||(a.innerHTML=r?.diff?tr(r.diff):'<span class="text-base-content/40">No changes</span>')}catch(r){!e.aborted&&r?.name!=="AbortError"&&(a.innerHTML=`<span class="text-error">${(0,n.esc)(r?.message??String(r))}</span>`)}}),n.delegate.on("click","#diff-unstaged, #diff-staged",(e,t)=>{let s=t.id==="diff-staged";$a.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||nr()})}function nr(){let e=y.peek(),t=J.peek()||e?.path,s=(0,n.$)("git-graph-content");if(!t||!s)return;let o=e?.id||"_";s.innerHTML='<span class="text-base-content/40">Loading\u2026</span>',h("GET",`/api/projects/${o}/git/log?root=${encodeURIComponent(t)}`).then(a=>{s.innerHTML=a.graph?Zi(a.graph):'<span class="text-base-content/40">No commits</span>'}).catch(a=>{s.innerHTML=`<span class="text-error">${(0,n.esc)(a.message)}</span>`})}C();I();var Y=null,T=null,Un=null,Zt=!1,Fn=null,Ma=null,Xt=0,Qt=null,As=!1;function Ta(){if(T)return;let e=(0,n.$)("terminal-container");if(e){if(typeof Terminal>"u"){setTimeout(Ta,100);return}T=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"&&(Un=new FitAddon.FitAddon,T.loadAddon(Un)),T.open(e),js(),T.onData(t=>{Y&&Y.readyState===WebSocket.OPEN&&Y.send(JSON.stringify({type:"input",data:t}))}),window.addEventListener("resize",()=>{js(),Ds()})}}function js(){try{Un&&T&&Un.fit()}catch{}}function Ds(){Y&&Y.readyState===WebSocket.OPEN&&T&&Y.send(JSON.stringify({type:"resize",cols:T.cols,rows:T.rows}))}function Ea(){return f.machineId||M.peek()||null}function qn(e){Qt&&(clearTimeout(Qt),Qt=null),As=!0;let t=++Xt;if(Y){try{Y.close()}catch{}Y=null}Zt=!1;let s=location.protocol==="https:"?"wss":"ws",o=T?T.cols:80,a=T?T.rows:24,i=new URLSearchParams;f.token&&i.set("token",f.token),e&&i.set("cwd",e),i.set("cols",String(o)),i.set("rows",String(a));let r=Ea();k.peek()&&r&&i.set("machine",r),Fn=e||null,Ma=r,Y=new WebSocket(`${s}://${location.host}/ws/shell?${i}`),Y.addEventListener("open",()=>{t===Xt&&(Zt=!0,T?.write(`\x1B[32mConnected to interactive terminal\x1B[0m\r
|
|
915
|
+
`),Ds())}),Y.addEventListener("message",c=>{if(t!==Xt)return;let u;try{u=JSON.parse(c.data)}catch{return}u.type==="output"?T?.write(u.data):u.type==="exit"?T?.write(`\r
|
|
913
916
|
\x1B[33m[process exited: ${u.code}]\x1B[0m\r
|
|
914
|
-
`):u.type==="error"&&
|
|
917
|
+
`):u.type==="error"&&T?.write(`\r
|
|
915
918
|
\x1B[31m[error: ${u.data||u.message||""}]\x1B[0m\r
|
|
916
|
-
`)}),Y.addEventListener("close",()=>{t===
|
|
919
|
+
`)}),Y.addEventListener("close",()=>{t===Xt&&(Zt=!1,T?.write(`\r
|
|
917
920
|
\x1B[33m[disconnected]\x1B[0m\r
|
|
918
|
-
`),!(!
|
|
919
|
-
`),
|
|
921
|
+
`),!(!As||j.peek()!=="shell")&&(T?.write(`\x1B[33m[reconnecting\u2026]\x1B[0m\r
|
|
922
|
+
`),Qt=setTimeout(()=>{Qt=null,qn(Fn)},1500)))}),Y.addEventListener("error",()=>{t===Xt&&T?.write(`\r
|
|
920
923
|
\x1B[31m[WebSocket error]\x1B[0m\r
|
|
921
|
-
`)})}function
|
|
924
|
+
`)})}function La(){let e=y.peek()?.path,t=(0,n.$)("term-cwd");t&&(t.textContent=e||"~"),T||Ta(),requestAnimationFrame(()=>{requestAnimationFrame(()=>{js();let s=Ea();!Zt||Fn!==(e||null)||Ma!==s?(T?.clear(),qn(e)):Ds()})})}function Ia(){document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(j.peek()!=="shell"||!As||Zt||qn(Fn))}),(0,n.watch)(j,e=>{e==="shell"&&La()}),document.addEventListener("shell-tab-shown",()=>{j.peek()==="shell"&&La()}),document.getElementById("term-reconnect")?.addEventListener("click",()=>{T?.clear(),qn(y.peek()?.path)})}mt();gn();function _s(){let e=document.documentElement;e.classList.add("boot-ready"),e.classList.remove("boot-pending")}function Wn(){document.documentElement.classList.remove("boot-restore")}var Hs=rs(location.hash.slice(1)||"/"),Ca=Is()||!!(f.token&&Hs?.id);ya({restoreSession:Ca});yo();ka();Sa();To();Ia();go();Oo();ko(ke,He);(async()=>{let e=ct();if(f.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")),Ca){document.documentElement.classList.add("boot-restore");let a=document.getElementById("welcome"),i=document.getElementById("project-view");a&&(a.classList.add("hidden"),a.style.display="none"),i&&(i.classList.remove("hidden"),i.style.cssText="display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden")}let o=await e;await Rn({hub:o,deepLink:Hs}),Hs?.id||($o(),(location.hash||"").startsWith("#/session/")||Wn()),requestAnimationFrame(()=>{requestAnimationFrame(_s)})}catch(t){console.error("[boot]",t),f.token=null,localStorage.removeItem("token"),Wn(),await Es(),_s()}else Wn(),await Es(),_s()})();document.addEventListener("router:home",()=>{Wn()});Qs();
|