claude-simple 0.2.0 → 0.2.2
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/client.js +64 -3
- package/dist/{app.0.2.0.min.js → app.0.2.2.min.js} +150 -97
- package/dist/index.html +2 -2
- package/dist/{style.0.2.0.min.css → style.0.2.2.min.css} +103 -4
- package/gateway.js +7 -2
- package/package.json +1 -1
- package/public/agent-panel.js +10 -1
- package/public/chat.js +9 -1
- package/public/files.js +60 -21
- package/public/index.html +2 -2
- package/public/shell/dashboard.js +62 -4
- package/public/shell/notes.js +24 -9
- package/public/shell/session-nav.js +53 -21
- package/public/shell/templates.js +30 -6
- package/public/shell.js +25 -3
- package/public/style.css +102 -3
- package/public/sw.js +2 -2
- package/server.js +5 -1
- package/src/app.js +35 -9
- package/src/auto-update.js +215 -0
- package/src/runtime/protocol.js +2 -2
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
var Ds=Object.defineProperty;var La=Object.getOwnPropertyDescriptor;var Ta=Object.getOwnPropertyNames;var Ea=Object.prototype.hasOwnProperty;var Y=(e,t)=>()=>(e&&(t=e(e=0)),t);var _s=(e,t)=>{for(var s in t)Ds(e,s,{get:t[s],enumerable:!0})},js=(e,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Ta(t))!Ea.call(e,a)&&a!==s&&Ds(e,a,{get:()=>t[a],enumerable:!(o=La(t,a))||o.enumerable});return e},Un=(e,t,s)=>(js(e,t,"default"),s&&js(s,t,"default"));var n={};import*as Ji from"https://cdn.jsdelivr.net/gh/forechoandlook/mini-react@v0.1.13/dist/mini-react.min.js";var I=Y(()=>{Un(n,Ji)});var Os={};_s(Os,{AGENT_DEFAULT_MODEL:()=>Hs,AGENT_LABELS:()=>R,AGENT_MODELS:()=>qn,LOW_TURN_THRESHOLD:()=>Gn,activityHits:()=>ce,activityLoading:()=>ke,addCustomModel:()=>kt,agentFilter:()=>X,agentsMeta:()=>nt,chatDensity:()=>$e,collapsedFolders:()=>tt,ctx:()=>f,currentAgent:()=>$,currentEffort:()=>le,currentModel:()=>k,currentPermission:()=>wt,currentProject:()=>y,currentTab:()=>A,expandedFolders:()=>et,favoritesOnly:()=>De,filesPath:()=>C,filesRoot:()=>U,filteredSessions:()=>Pe,getCustomModels:()=>Xt,getDefaultModel:()=>ae,getEffortsForModel:()=>$t,getModelsForAgent:()=>de,getSessionMeta:()=>st,gitRoot:()=>z,hubMachineReady:()=>Se,hubMode:()=>S,isProcessing:()=>oe,machinesList:()=>j,metaKey:()=>O,projectGroups:()=>Ue,removeCustomModel:()=>Kn,selectedMachineId:()=>L,sessionDisplayTitle:()=>ot,sessionFilter:()=>B,sessionMetaMap:()=>v,sessionSearch:()=>N,sessionSort:()=>Ps,sessionsData:()=>E,setAgent:()=>pe,setChatDensity:()=>zn,setSelectedMachine:()=>ee,showHiddenOnly:()=>_e,sidebarView:()=>we,timeRange:()=>Z,viewingFile:()=>F,workspacesData:()=>H,wsStatus:()=>ye});function ee(e){let t=e||null;L.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 st(e,t,s){return v.peek()?.[O(e,t,s)]||{favorite:!1,notes:"",title:"",hidden:!1}}function ot(e,{preferSnippet:t=!1}={}){if(!e)return"Session";if(t&&e.snippet)return e.snippet;let o=(st(e.agent,e.sessionId,e.machineId).title||"").trim();return o||e.display||e.sessionId?.slice(0,8)||"Session"}function zn(e){let t=["clean","normal","full"].includes(e)?e:"normal";$e.value=t,localStorage.setItem("chatDensity",t),document.getElementById("messages")?.setAttribute("data-density",t)}function Ma(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 Jn(){try{let e=localStorage.getItem(Ns);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function Rs(e){localStorage.setItem(Ns,JSON.stringify(e))}function Xt(e){let t=(e||"claude").toLowerCase(),s=Jn()[t];return Array.isArray(s)?s.filter(Boolean).map(String):[]}function kt(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim();if(!o)return!1;let a=Jn(),i=Array.isArray(a[s])?[...a[s]]:[];return i.includes(o)||i.push(o),a[s]=i,Rs(a),!0}function Kn(e,t){let s=(e||"claude").toLowerCase(),o=String(t||"").trim(),a=Jn(),i=Array.isArray(a[s])?a[s].filter(r=>r!==o):[];return a[s]=i,Rs(a),!0}function de(e){let t=(e||"claude").toLowerCase(),s=nt.peek()?.defaults?.[t],o=s?.models?.length?s.models.map(Ma).filter(Boolean):(qn[t]||qn.claude).map(r=>({...r})),a=Xt(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 ae(e){let t=(e||"claude").toLowerCase(),s=nt.peek()?.defaults?.[t];return s?.model?String(s.model):Hs[t]||de(t)[0]?.value||"claude-sonnet-4-5"}function $t(e,t){let o=de(e).find(i=>i.value===t);if(o?.efforts?.length)return o.efforts;let a=nt.peek()?.defaults?.[(e||"claude").toLowerCase()];return a?.efforts?.length?a.efforts.map(String):["low","medium","high","xhigh","max"]}function pe(e){let t=(e||"claude").toLowerCase();$.value=t,localStorage.setItem("agent",t);let s=de(t),o=ae(t);s.some(a=>a.value===k.peek())||(k.value=o,localStorage.setItem("model",o))}function Ia(e,t){return!t||t==="all"?!0:(e.agent||"claude")===t}function Ca(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 Aa(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 Wn(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}var E,H,B,N,Ps,et,tt,C,F,y,A,oe,ye,$,k,le,wt,U,z,nt,we,X,Z,ce,ke,v,De,_e,Gn,$e,S,j,L,Se,f,R,qn,Hs,Ns,Pe,Ue,M=Y(()=>{I();E=(0,n.signal)([]),H=(0,n.signal)([]),B=(0,n.signal)(null),N=(0,n.signal)(""),Ps=(0,n.signal)("time"),et=(0,n.signal)(new Set),tt=(0,n.signal)(new Set),C=(0,n.signal)(""),F=(0,n.signal)(null),y=(0,n.signal)(null),A=(0,n.signal)("chat"),oe=(0,n.signal)(!1),ye=(0,n.signal)("idle"),$=(0,n.signal)(localStorage.getItem("agent")||"claude"),k=(0,n.signal)(localStorage.getItem("model")||"claude-sonnet-4-5"),le=(0,n.signal)(""),wt=(0,n.signal)("default"),U=(0,n.signal)(""),z=(0,n.signal)(""),nt=(0,n.signal)(null),we=(0,n.signal)(localStorage.getItem("sidebarView")||"projects"),X=(0,n.signal)(localStorage.getItem("agentFilter")||"all"),Z=(0,n.signal)(localStorage.getItem("timeRange")||"14"),ce=(0,n.signal)(null),ke=(0,n.signal)(!1),v=(0,n.signal)({}),De=(0,n.signal)(localStorage.getItem("favoritesOnly")==="1"),_e=(0,n.signal)(localStorage.getItem("showHiddenOnly")==="1"),Gn=2,$e=(0,n.signal)(localStorage.getItem("chatDensity")||"normal"),S=(0,n.signal)(!1),j=(0,n.signal)([]),L=(0,n.signal)(null),Se=(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"},qn={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"}]},Hs={claude:"claude-sonnet-4-5",codex:"gpt-5.4",grok:"grok-4.5"};Ns="customModelsByAgent";Pe=(0,n.computed)(()=>{let e=B.value,t=N.value.toLowerCase().trim(),s=Ps.value,o=X.value,a=Z.value,i=De.value,r=_e.value,c=v.value,u=ce.value,l=u?.results?.length&&t?Wn(u.results):Wn(E.value);e&&(l=l.filter(p=>p&&(p.cwd===e||p.configDir===e)));let d=L.value;return S.value&&d&&(l=l.filter(p=>p&&(!p.machineId||p.machineId===d))),l=l.filter(p=>p&&Ia(p,o)&&Ca(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&&Aa(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}),Ue=(0,n.computed)(()=>{let e=Wn(Pe.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 St(e={}){return e.machineId!==void 0?e.machineId:f.machineId||L.peek()||null}function Da(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=St(a),r={"Content-Type":"application/json",...f.token?{Authorization:`Bearer ${f.token}`}:{}};S.peek()&&i&&!Da(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=Bs.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 Vn;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&&Bs.set(c,m)}return p};if(e.toUpperCase()!=="GET"||o||a.dedupe===!1)return u();let l=`${f.token||""}:${i||""}:${t}`;return ja.get(l,u)}function Lt(e){return f.ws?.readyState===WebSocket.OPEN?(f.ws.send(JSON.stringify(e)),!0):(e?.type==="ping"||e?.type==="pong"||e?.type==="subscribe"||Qt.push(e),!1)}function Fs(){for(;Qt.length&&f.ws?.readyState===WebSocket.OPEN;)f.ws.send(JSON.stringify(Qt.shift()))}function Us(){Qt.length=0}function qs(e={}){let t=new URLSearchParams(e);f.token&&t.set("token",f.token);let s=St();return S.peek()&&s&&t.set("machine",s),t.toString()}function Tt(e={}){let t={...e};f.token&&(t.Authorization=`Bearer ${f.token}`);let s=St();return S.peek()&&s&&(t["X-Machine-Id"]=s),t}async function at(){try{let e=await fetch("/api/hub");if(!e.ok)return S.value=!1,!1;let t=await e.json();if(t?.hub)return S.value=!0,t}catch{}return S.value=!1,!1}var ja,Bs,Vn,Qt,J=Y(()=>{M();I();ja=(0,n.createFetch)({cache:!1,dedupe:!0,retry:0}),Bs=new Map,Vn=Symbol("not-modified");Qt=[]});function qe(){try{let e=localStorage.getItem(Ks);return e?JSON.parse(e):null}catch{return null}}function Yn(e){try{let s={...qe()||{},...e,updatedAt:Date.now()};localStorage.setItem(Ks,JSON.stringify(s))}catch{}}var Ks,Zt=Y(()=>{Ks="lastSessionContext"});async function Xn(){if(Et&&!(typeof navigator>"u"||!navigator.wakeLock?.request)&&document.visibilityState==="visible"&&!We)try{We=await navigator.wakeLock.request("screen"),We.addEventListener("release",()=>{We=null,Et&&document.visibilityState==="visible"&&setTimeout(()=>{Xn().catch(()=>{})},500)})}catch{We=null}}async function Vs(){let e=We;if(We=null,!!e)try{await e.release()}catch{}}function Ys(e){Et=!!e,Et?Xn().catch(()=>{}):Vs().catch(()=>{})}function Xs(){typeof document>"u"||document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&Et?Xn().catch(()=>{}):document.visibilityState==="hidden"&&Vs().catch(()=>{})})}var We,Et,Qs=Y(()=>{We=null,Et=!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 Mt(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 rt(e,t=!0){let s=e||"claude",a={claude:"bg-orange-500/15 text-orange-400",codex:"bg-emerald-500/15 text-emerald-400",grok:"bg-sky-500/15 text-sky-400"}[s]||"bg-base-300 text-base-content/50",i=t?s==="claude"?"CC":s==="codex"?"CX":s==="grok"?"GX":s.slice(0,2).toUpperCase():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 Zs(e){return Object.entries(e||{}).filter(([,t])=>t>0).map(([t,s])=>`${rt(t)}<span class="text-[9px] text-base-content/40 -ml-0.5">${s}</span>`).join("")}function lt(e){if(!e)return"";let t="",s=e.split("/").filter(Boolean);return s.length<=3?e:"\u2026/"+s.slice(-2).join("/")}var It=Y(()=>{I();M()});function _a(){return R[$.peek()]||"Assistant"}function oo(e){return e.scrollHeight-e.scrollTop-e.clientHeight<80}function ne(e,t){e&&(t||oo(e))&&(e.scrollTop=e.scrollHeight)}function Pa(){eo||(eo=!0,document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="visible"&&(he=400,en({probe:!0}),f.ws?.readyState===WebSocket.OPEN&&f.sessionId))try{f.ws.send(JSON.stringify({type:"subscribe",sessionId:f.sessionId}))}catch{}}),window.addEventListener("online",()=>{he=400,en({force:!0})}),window.addEventListener("pageshow",e=>{e.persisted?en({force:!0}):en({probe:!0})}))}function Pt(){let e=(0,n.$)("conn-dot");if(!e)return;let t=ye.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 en(e={}){let t=f.ws?.readyState;if(e.force){he=400,Me({quiet:!0});return}if(t===WebSocket.OPEN){if(e.probe&&Te&&Date.now()-Te>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&&(he=Math.min(he,800),Me({quiet:!0}))}function Ha(){Ee||(ye.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",Pt(),Ee=setTimeout(()=>{Ee=null,Me({quiet:!0})},he),he=Math.min(Math.round(he*1.8),15e3))}function ao(){tn&&(clearInterval(tn),tn=null)}function Na(e,t){ao(),tn=setInterval(()=>{if(!(t!==At||e.readyState!==WebSocket.OPEN)){if(Te&&Date.now()-Te>7e4){try{e.close()}catch{}return}if(!(typeof document<"u"&&document.visibilityState==="hidden")&&Te&&Date.now()-Te>4e4)try{e.send(JSON.stringify({type:"ping"}))}catch{}}},3e4)}function Ge(){let e=oe.peek()||!!y.peek()&&ye.peek()==="open";Ys(e)}function Ra(){he=400,Ee&&(clearTimeout(Ee),Ee=null),sn=!1;let e=f.ws?.readyState;if(e===WebSocket.OPEN||e===WebSocket.CONNECTING)try{f.ws?.close()}catch{}Me({quiet:!1}),b("\u6B63\u5728\u91CD\u65B0\u8FDE\u63A5\u5E76\u540C\u6B65\u2026")}function Me(e={}){Pa(),Ee&&(clearTimeout(Ee),Ee=null),e.quiet&&(sn=!0);let t=f.machineId||(typeof localStorage<"u"?localStorage.getItem("machineId"):null);to!==t&&(Us(),to=t);let s=++At;try{f.ws?.close()}catch{}ye.value="connecting",Pt();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===At){if(he=1e3,Te=Date.now(),ye.value="open",Pt(),f.sessionId)try{i.send(JSON.stringify({type:"subscribe",sessionId:f.sessionId}))}catch{}Fs(),Na(i,s),Ge(),nn&&!sn&&b(t?`\u5DF2\u91CD\u8FDE \xB7 ${t}`:"\u5DF2\u91CD\u8FDE"),nn=!1,sn=!1}}),i.addEventListener("message",r=>{if(s!==At)return;let c;try{c=JSON.parse(r.data)}catch{return}if(c.type==="pong"){Te=Date.now();return}if(c.type==="ping"){if(Te=Date.now(),i.readyState===WebSocket.OPEN)try{i.send(JSON.stringify({type:"pong"}))}catch{}return}if(c.type==="run-status"){c.running?oe.value=!0:oe.peek()&&(oe.value=!1,io()),Ge();return}ro(c)}),i.addEventListener("close",()=>{s===At&&(ao(),nn=!0,ye.value=typeof navigator<"u"&&navigator.onLine===!1?"offline":"reconnecting",Pt(),Ha())}),i.addEventListener("error",()=>{})}function io(){if(!_t||oe.peek())return;let e=_t;_t=null;let t=(0,n.$)("chat-input");t&&(t.value=e,rn(t)),setTimeout(()=>pn(),0)}function jt(){oe.value=!1,Ge(),io()}function ro(e){if(e.type==="batch"&&Array.isArray(e.items)){for(let t of e.items)ro(t);return}if(e.type==="session-created"){f.sessionId=e.sessionId,e.agent&&pe(e.agent),document.dispatchEvent(new CustomEvent("sessions-changed"));return}if(e.type==="result"){Dt(),Ct(),ie();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),ct(s)}e.is_error||b("\u2713 Done"),jt();return}if(e.type==="complete"){Dt(),Ct(),ie(),!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")),jt();return}if(e.type==="error"){Dt(),Ct(),ze("error","Error",e.message),jt();return}if(e.type==="shell-start"){f.shellBubble=null;return}if(e.type==="shell-output"){f.shellBubble||(f.shellBubble=Ya(e.stream==="stderr"?"shell-err":"shell")),Xa(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:""}`),jt();return}if(e.type==="assistant"){Ct();for(let t of e.message?.content||[])t.type==="text"&&t.text?(ie(),ze("assistant",_a(),t.text,{ts:e.ts||Date.now()})):t.type==="tool_use"&&es(t,{ts:e.ts||Date.now()});return}if(e.type==="assistant_stream_start"){lo(e.ts);return}if(e.type==="assistant_delta"){Oa(e.data||"");return}if(e.type==="assistant_stream_end"){Ct();return}if(e.type==="thought_stream_start"){co();return}if(e.type==="thought_delta"){Ba(e.data||"");return}if(e.type==="thought_stream_end"){Dt();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>`),ne(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)&&ei(e)}function lo(e){let t=(0,n.$)("messages");if(!t||(ie(),Dt(),fe&&t.contains(fe)))return;let s=ln(e||Date.now()),o=cn(e||Date.now());t.insertAdjacentHTML("beforeend",`
|
|
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",`
|
|
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>`),
|
|
7
|
+
</div>`),be=t.lastElementChild,ne=be.querySelector(".msg-stream-body"),(0,n.$)("stream-status")?.remove(),se(t,!0)}function Ga(e){e&&(ne||mo(Date.now()),ne&&(ne.textContent+=e,se((0,n.$)("messages"),!0)))}function jt(){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=ln(e),go(be)):be.remove(),be=null,ne=null,(0,n.$)("stream-status")?.remove()}function ho(){let e=(0,n.$)("messages");e&&(Oe&&e.contains(Oe)||(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>`),Oe=e.lastElementChild,xe=Oe.querySelector(".thought-body"),se(e,!0)))}function za(e){e&&(xe||ho(),xe&&(xe.textContent+=e,xe.scrollTop=xe.scrollHeight,se((0,n.$)("messages"),!0)))}function Pt(){if(Oe&&xe){let e=(xe.textContent||"").length;Oe.innerHTML=`
|
|
14
|
+
<div class="text-[10px] text-base-content/30 px-1 select-none">\u{1F4AD} thought ${e?`(${e} chars)`:""}</div>`}Oe=null,xe=null}function Ka(e){let[t,...s]=e.slice(1).trim().split(/\s+/),o=s.join(" ");switch(t.toLowerCase()){case"agent":{if(!o)return b(`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")),b(`Agent \u2192 ${R[a]} \xB7 model ${$.peek()} \xB7 new session`)):b(`Agent already ${R[a]}`),!0):(b(`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 b(`Current model: ${$.peek()} (${c})${u?`
|
|
15
|
+
Available: ${u}`:""}`),!0}let a=Ja[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),b(`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(),b(`Effort set to ${o.toLowerCase()}`),!0):(b(`Unknown effort level "${o}" \xB7 valid: ${a.join(" | ")}`),!0):(b(`Current effort: ${pe.peek()||"(default)"} \xB7 levels: ${a.join(" | ")}`),!0)}case"clear":return ft(),f.sessionId=null,f.lastUsage=null,b("Cleared \xB7 new session"),!0;case"usage":return Va(),!0;case"help":return b(`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
|
|
22
|
-
`)),
|
|
23
|
-
`)),(r.tokensUsed!=null||r.windowTokens!=null)&&
|
|
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 Va(){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){b(o.join(`
|
|
22
|
+
`)),ns("\u25C8 /usage \xB7 no session yet");return}b("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}}b(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}}b(`${o.join(`
|
|
24
24
|
`)}
|
|
25
|
-
(usage fetch failed: ${a.message})`)}}function
|
|
25
|
+
(usage fetch failed: ${a.message})`)}}function mn(){let e=(0,n.$)("chat-input"),t=e?.value.trim();if(!t||!y.peek())return;if(ie.peek()){Ht=t,e.value="",dn(e),cn(""),b(`\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="",dn(e),cn(""),t.startsWith("/")&&Ka(t))return;ie.value=!0,Xe();let s=Date.now();if(t.startsWith("!"))Qe("shell","$ Shell",t.slice(1).trim(),{ts:s}),It({type:"command",cmd:"shell.exec",command:t.slice(1).trim(),cwd:y.peek().path})||b("\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=Lt.peek(),i=S.peek()||"claude";It({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}}})||b("\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u6D88\u606F\u5DF2\u5165\u961F\uFF0C\u91CD\u8FDE\u540E\u53D1\u9001")}}function bo(){f.sessionId&&It({type:"command",cmd:"turn.interrupt",sessionId:f.sessionId}),Ht=null,_t()}function cn(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 Ya(){return typeof window<"u"&&window.matchMedia("(max-width: 640px)").matches?96:140}function dn(e){e.style.height="auto",e.style.height=Math.min(e.scrollHeight,Ya())+"px"}function pn(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 un(e){let t=_(e);return t==null?"":new Date(t).toISOString()}function Za(e,t,s){if(e==="system")return t;let o=pn(s),a=un(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 ei(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)?ln(t):null,c=t.length>Xa,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>Qa,r=i?`<div class="msg-body">${ln(t)}</div>${o}`:ln(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 Za(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",ei(e,s,i)),go(a.lastElementChild),se(a,e==="user")}function b(e){Qe("system","",e)}async function ti(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 ni(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 xo(){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 ti(a,r);ni(t,``)}catch(c){b(`Image paste failed: ${c.message}`)}finally{t.disabled=!1,t.focus()}})}function Me(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>`),
|
|
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 ${Me(e.cache_read_input_tokens??e.cachedReadTokens)} cached`:"",i=e.cache_creation_input_tokens??e.cacheCreationInputTokens?` \xB7 ${Me(e.cache_creation_input_tokens??e.cacheCreationInputTokens)} cache-write`:"",r=e.reasoning_tokens??e.reasoningTokens?` \xB7 ${Me(e.reasoning_tokens??e.reasoningTokens)} reason`:"",c=e.costUSD??e.cost_usd,u=c!=null?` \xB7 $${Number(c).toFixed(4)}`:"",l=o?` \xB7 \u03A3${Me(o)}`:"";ns(`\u2191${Me(t)} \u2193${Me(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 ${Me(t)} / ${Me(s)}`):t!=null&&a.push(`context ${Me(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,Oe=xe=null}function si(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 oi(e,t){e&&(e.textContent+=t,se(e.closest("#messages")))}function ai(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 ro(e,{inBatch:t=!1}={}){let{inputStr:s,preview:o}=ai(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=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
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 ii(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
|
|
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=pn(a),l=un(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>`),
|
|
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",ro(e,{inBatch:!0})),ii(he),se(s);return}he=null;let i=pn(a),r=un(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%]">${ro(e)}</div>
|
|
48
48
|
${i?`<div class="msg-ts" title="${(0,n.esc)(r)}">${(0,n.esc)(i)}</div>`:""}
|
|
49
|
-
</div>`),
|
|
49
|
+
</div>`),se(s)}function fn(){let e=(0,n.$)("messages");e&&e.setAttribute("data-density",Te.peek()||"normal")}function ri(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,45 +56,64 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
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 li(){if(lo||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] ${
|
|
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)}lo=!0}function ln(e){if(typeof marked>"u")return(0,n.esc)(e);try{return li(),marked.parse(String(e??""),{breaks:!0,gfm:!0})}catch{return(0,n.esc)(e)}}function go(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 vo(){fn(),no(),(0,n.watch)($e,o=>{Nt(),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"&&!an){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(),Wa()}),(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":cn(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,()=>fn()),n.delegate.on("keydown","#chat-input",o=>{o.key==="Enter"&&(o.metaKey||o.ctrlKey)&&(o.preventDefault(),mn())}),n.delegate.on("input","#chat-input",(o,a)=>{dn(a),cn(a.value)}),n.delegate.on("click","[data-perm-id]",(o,a)=>{It({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||co(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 Dt,Ce,ge,Ie,on,ao,an,io,rn,Ht,be,ne,Oe,xe,Ja,Xa,Qa,he,lo,mt=X(()=>{C();I();K();so();At();At();Dt=0,Ce=null,ge=1e3,Ie=0,on=null,ao=!1,an=!1,io=null,rn=!1,Ht=null;be=null,ne=null,Oe=null,xe=null;Ja={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"};Xa=200,Qa=500;he=null;lo=!1});function wo(e,t){yo=e,as=t,window.addEventListener("hashchange",()=>{if(is){is=!1;return}$o(location.hash.slice(1)||"/")}),(0,n.watch)(j,s=>{f.sessionId&&hn(`/session/${f.sessionId}/${s}`)})}function rs(e){let t=(e||"").match(/^\/session\/([^/]+)(?:\/([^/]+))?$/);return t?{id:t[1],tab:t[2]||null}:null}function ko(){$o(location.hash.slice(1)||"/")}function $o(e){let t=rs(e);if(!t){document.dispatchEvent(new CustomEvent("router:home"));return}let{id:s,tab:o}=t;!yo||!as||(s!==f.sessionId?document.dispatchEvent(new CustomEvent("router:session",{detail:{id:s,tab:o}})):o&&o!==j.peek()&&as(o))}function hn(e){is=!0,location.hash=e}function bn(){f.sessionId&&hn(`/session/${f.sessionId}/${j.peek()}`)}var kr,yo,as,is,xn=X(()=>{C();I();kr=(0,n.createRouter)({"/":()=>{},"/session/*":()=>{},"/session/*/*":()=>{},"*":()=>{}}),yo=null,as=null,is=!1});async function vn(){try{return await gn.get("sessions")??null}catch{return null}}async function So(e){try{await gn.set("sessions",e,{ttl:ci})}catch{}}async function Lo(){try{return await gn.get("workspaces")??null}catch{return null}}async function Rt(e){try{await gn.set("workspaces",e,{ttl:3600*1e3})}catch{}}var gn,ci,yn=X(()=>{C();gn=(0,n.idb)("claude-ui"),ci=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 _e(){let e=En(M.peek()),t=T.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 Fo(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 yi(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 qo(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 Wo(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??_e());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=Wo(i));let l=yi(Tn,tt);Ft||(Ft=Fo(new Date)),t.innerHTML=l.map(d=>{let p=d.date,m=Fo(p),g=qo(p,e).length,W=p.toDateString()===new Date().toDateString(),Fe=m===Ft,de="",qe="text-base-content/65",ke="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",ke="border border-primary/30"):g<=5?(de="bg-primary/30",qe="text-primary font-bold",ke="border border-primary/50"):(de="bg-primary/60",qe="text-primary-content font-bold",ke="border border-primary/80")):(de="bg-base-300/25",d.isCurrentMonth&&(w="hover:bg-base-300/50")),W?ke="border-2 border-primary":Fe&&(ke="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} ${ke} ${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(""),wi(e),$i(e)}function wi(e){let t=(0,n.$)("selected-day-title"),s=(0,n.$)("selected-day-sessions");if(!t||!s)return;let[o,a,i]=Ft.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=qo(r,e),u=c.reduce((d,p)=>d+(Number(p.totalTokens)||0),0),l=(0,n.$)("stats-selected-tokens");if(l&&(l.textContent=Wo(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||"")}"
|
|
75
75
|
data-session-config-dir="${(0,n.esc)(d.configDir||"")}"
|
|
76
76
|
data-session-agent="${(0,n.esc)(d.agent||"claude")}"
|
|
77
77
|
data-session-machine="${(0,n.esc)(d.machineId||"")}">
|
|
78
|
-
<div class="flex-shrink-0">${
|
|
78
|
+
<div class="flex-shrink-0">${Ve(d.agent)}</div>
|
|
79
79
|
<div class="flex-1 min-w-0">
|
|
80
|
-
<div class="text-xs font-semibold truncate text-base-content/90">${(0,n.esc)(
|
|
81
|
-
<div class="text-[10px] text-base-content/40 truncate mt-0.5">${(0,n.esc)(d.projectName||
|
|
80
|
+
<div class="text-xs font-semibold truncate text-base-content/90">${(0,n.esc)(Ge(d))}</div>
|
|
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 Go(e,t){return[...En(e)].filter(s=>s&&s.sessionId).sort((s,o)=>(_(o.updatedAt)||0)-(_(s.updatedAt)||0)).slice(0,t)}function $i(e){let t=(0,n.$)("recent-sessions-list");if(!t)return;let s=Go(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||"")}"
|
|
88
88
|
data-session-config-dir="${(0,n.esc)(o.configDir||"")}"
|
|
89
89
|
data-session-agent="${(0,n.esc)(o.agent||"claude")}"
|
|
90
90
|
data-session-machine="${(0,n.esc)(o.machineId||"")}">
|
|
91
|
-
<div class="flex-shrink-0">${
|
|
91
|
+
<div class="flex-shrink-0">${Ve(o.agent)}</div>
|
|
92
92
|
<div class="flex-1 min-w-0">
|
|
93
|
-
<div class="text-xs font-bold truncate text-base-content/95">${(0,n.esc)(
|
|
94
|
-
<div class="text-[10px] text-base-content/40 truncate mt-1">${(0,n.esc)(o.projectName||
|
|
93
|
+
<div class="text-xs font-bold truncate text-base-content/95">${(0,n.esc)(Ge(o))}</div>
|
|
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 Mn(){(0,n.$)("recent-menu")?.classList.add("hidden")}function zo(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=Go(e??_e(),ki);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
|
+
<button type="button"
|
|
99
|
+
class="recent-menu-item w-full text-left px-2 py-1.5 rounded-md flex items-start gap-2
|
|
100
|
+
${c?"bg-primary/15 text-primary":"hover:bg-base-200"}"
|
|
101
|
+
data-session-id="${(0,n.esc)(i.sessionId)}"
|
|
102
|
+
data-session-cwd="${(0,n.esc)(i.cwd||"")}"
|
|
103
|
+
data-session-config-dir="${(0,n.esc)(i.configDir||"")}"
|
|
104
|
+
data-session-agent="${(0,n.esc)(i.agent||"claude")}"
|
|
105
|
+
data-session-machine="${(0,n.esc)(i.machineId||"")}">
|
|
106
|
+
<span class="flex-shrink-0 mt-0.5">${Ve(i.agent)}</span>
|
|
107
|
+
<span class="flex-1 min-w-0">
|
|
108
|
+
<span class="block text-xs font-semibold truncate leading-snug">${(0,n.esc)(Ge(i))}</span>
|
|
109
|
+
<span class="block text-[10px] text-base-content/40 truncate mt-0.5">${(0,n.esc)(i.projectName||Ye(i.cwd)||"\u2014")}</span>
|
|
110
|
+
</span>
|
|
111
|
+
<span class="flex flex-col items-end gap-0.5 flex-shrink-0 self-start">
|
|
112
|
+
<span class="text-[9px] text-base-content/40 whitespace-nowrap">${(0,n.esc)(r)}</span>
|
|
113
|
+
${u}
|
|
114
|
+
${c?'<span class="text-[9px] opacity-70">\u5F53\u524D</span>':""}
|
|
115
|
+
</span>
|
|
116
|
+
</button>`}).join("")}function Jo(e){Ft=e}function fs(e){tt+=e,tt<0?(tt=11,Tn--):tt>11&&(tt=0,Tn++)}var Tn,tt,Ft,ki,ms=X(()=>{C();I();At();Tn=new Date().getFullYear(),tt=new Date().getMonth(),Ft=null;ki=15});function Ko(e){return Array.isArray(e)?e:e&&Array.isArray(e.results)?e.results:e&&Array.isArray(e.sessions)?e.sessions:[]}function Si(){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 ve({waitFresh:e=!0}={}){let t=Ko(await vn());if(t.length){let o=T.peek();if(k.peek()&&o){let a=t.filter(i=>!i.machineId||i.machineId===o);M.value=a.length?a:t}else M.value=t}let s=async()=>{let o=Si(),a=await h("GET",o,void 0,void 0,{etag:!0});if(a===Zn)return M.peek();let i=Ko(a);return M.value=i,So(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 qt({waitFresh:e=!0}={}){let t=await Lo();t&&(H.value=t);let s=async()=>{let o=await h("GET","/api/workspaces");H.value=o,Rt(o)};if(e||!t)try{await s()}catch{}else s().catch(()=>{})}function Xo(e,{showProject:t=!1}={}){let s=f.sessionId===e.sessionId&&(f.agent||S.peek())===(e.agent||"claude"),o=v.peek()?.[O(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(""),x=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}
|
|
98
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
|
|
99
118
|
${s?"border-primary bg-primary/5":"border-transparent"} ${r?"session-fav":""} ${c?"session-hidden-row":""} ${d?"session-thin":""}"
|
|
100
119
|
data-session-id="${(0,n.esc)(e.sessionId)}"
|
|
@@ -110,7 +129,7 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
110
129
|
data-fav-session-agent="${(0,n.esc)(e.agent||"claude")}"
|
|
111
130
|
data-fav-session-machine="${(0,n.esc)(e.machineId||"")}"
|
|
112
131
|
title="${r?"Unfavorite":"Favorite"}">${r?"\u2605":"\u2606"}</button>
|
|
113
|
-
${
|
|
132
|
+
${Ve(e.agent)}
|
|
114
133
|
<div class="min-w-0 flex-1">
|
|
115
134
|
<div class="session-title-wrap flex items-center gap-1 min-w-0"
|
|
116
135
|
data-rename-session-id="${(0,n.esc)(e.sessionId)}"
|
|
@@ -132,36 +151,36 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
132
151
|
${p}
|
|
133
152
|
${m||x?`<div class="flex items-center gap-1 mt-0.5 flex-wrap">${x}${m}</div>`:""}
|
|
134
153
|
</div>
|
|
135
|
-
<span class="text-[9px] text-base-content/30 flex-shrink-0 mt-0.5">${
|
|
154
|
+
<span class="text-[9px] text-base-content/30 flex-shrink-0 mt-0.5">${pt(e.updatedAt)}</span>
|
|
136
155
|
</div>
|
|
137
|
-
</div>`}async function
|
|
156
|
+
</div>`}async function Wt(){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 ye(),e}catch(e){return console.warn("[agents] failed to load model list",e),null}}function hs(){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 ye(){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),hs()}function bs({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&&en(t).includes(s)&&Qn(t,s),Tt(t,i),$.value=i,localStorage.setItem("model",i),ye())}function Li(e){if(!Array.isArray(e)||!e.length)return`<div class="px-3 py-6 text-center text-xs text-base-content/40">
|
|
138
157
|
No projects in this range.<br>
|
|
139
158
|
<span class="text-base-content/30">Try \u201CAll\u201D time or another agent.</span>
|
|
140
|
-
</div>`;let t=
|
|
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=`
|
|
141
160
|
<div class="project-header px-2.5 py-2 cursor-pointer hover:bg-base-300/80 select-none border-b border-base-300/40"
|
|
142
161
|
data-folder="${(0,n.esc)(r)}" data-project-cwd="${(0,n.esc)(i.cwd||"")}" data-project-machine="${(0,n.esc)(i.machineId||"")}">
|
|
143
162
|
<div class="flex items-center gap-1.5">
|
|
144
163
|
<span class="text-[10px] text-base-content/40 w-3 flex-shrink-0">${c?"\u25BE":"\u25B8"}</span>
|
|
145
164
|
<span class="text-[12px] font-semibold truncate flex-1" title="${(0,n.esc)(i.cwd||"")}">${(0,n.esc)(i.projectName)}</span>
|
|
146
165
|
${l}
|
|
147
|
-
<span class="text-[9px] text-base-content/30 flex-shrink-0">${
|
|
166
|
+
<span class="text-[9px] text-base-content/30 flex-shrink-0">${pt(i.updatedAt)}</span>
|
|
148
167
|
</div>
|
|
149
168
|
<div class="flex items-center gap-1.5 mt-0.5 pl-4">
|
|
150
|
-
<span class="text-[10px] text-base-content/35 font-mono truncate flex-1" title="${(0,n.esc)(i.cwd||"")}">${(0,n.esc)(
|
|
151
|
-
<span class="flex items-center gap-0.5 flex-shrink-0">${
|
|
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">${oo(i.agents)}</span>
|
|
152
171
|
</div>
|
|
153
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>`:""}
|
|
154
|
-
</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>`:"",x=c?`<div class="pb-1 border-b border-base-300/30">${p.map(g=>
|
|
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>`:"",x=c?`<div class="pb-1 border-b border-base-300/30">${p.map(g=>Xo(g)).join("")}${m}</div>`:"";return d+x}).join("")}function Ti(e){if(!Array.isArray(e)||!e.length)return`<div class="px-3 py-6 text-center text-xs text-base-content/40">
|
|
155
174
|
No recent activity.<br>
|
|
156
175
|
<span class="text-base-content/30">Widen the time range or clear filters.</span>
|
|
157
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])=>`
|
|
158
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>
|
|
159
|
-
${o.map(a=>
|
|
160
|
-
`).join("")}function
|
|
161
|
-
<div class="md">${
|
|
178
|
+
${o.map(a=>Xo(a,{showProject:!0})).join("")}
|
|
179
|
+
`).join("")}function Qo(){let e=Se.value,t=Array.isArray(Re.value)?Re.value:[],s=Array.isArray(ze.value)?ze.value:[];return e==="timeline"?Ti(t):Li(s)}function Zo(){document.querySelectorAll("[data-view]").forEach(i=>{let r=i.dataset.view===Se.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(Le.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=Se.peek()==="projects"?`${u} project${u===1?"":"s"} \xB7 ${c} session${c===1?"":"s"}`:`${c} recent session${c===1?"":"s"}`}}async function xs(e){let t=(e||"").trim();if(!t){ue.value=null,Le.value=!1;return}Le.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{Le.value=!1}}function In(e){clearTimeout(Vo);let t=(e||"").trim();if(!t){ue.value=null,Le.value=!1;return}Vo=setTimeout(()=>xs(t),350)}function Yo(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 gs(){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">${Yo(s.index)}</div></div>`);for(let a of s.files||[])o.push(`<div class="mb-3 border border-base-300 rounded-lg overflow-hidden">
|
|
162
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>
|
|
163
|
-
<div class="px-3 py-2 md">${
|
|
164
|
-
</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">${Yo(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 Vo,gt=X(()=>{C();I();K();yn();At();Vo=null});function ea(e,t){Cn=e||"",An=t||""}async function ta(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||"",vt(),t.style.display="flex"}catch(s){console.error("Error fetching project notes:",s),t.style.display="none"}}function vt(){let e=(0,n.$)("project-notes-bar");if(!e)return;let t=Cn||"No goal yet \u2014 click Edit",s=An||"";e.innerHTML=`
|
|
165
184
|
<div class="flex items-start gap-2 w-full">
|
|
166
185
|
<div class="flex-1 min-w-0">
|
|
167
186
|
<div class="truncate">
|
|
@@ -172,24 +191,24 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
172
191
|
</div>
|
|
173
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>
|
|
174
193
|
</div>
|
|
175
|
-
`}function
|
|
194
|
+
`}function na(){let e=(0,n.$)("project-notes-bar");e&&(e.innerHTML=`
|
|
176
195
|
<div class="flex flex-col gap-1.5 w-full">
|
|
177
196
|
<div class="flex items-center gap-2">
|
|
178
197
|
<span class="text-[10px] font-bold text-base-content/40 uppercase w-12 flex-shrink-0">Goal</span>
|
|
179
198
|
<input id="project-goal-input" type="text" class="input input-xs input-bordered flex-1 text-xs"
|
|
180
|
-
placeholder="One-line project goal\u2026" value="${(0,n.esc)(
|
|
199
|
+
placeholder="One-line project goal\u2026" value="${(0,n.esc)(Cn)}">
|
|
181
200
|
</div>
|
|
182
201
|
<div class="flex items-start gap-2">
|
|
183
202
|
<span class="text-[10px] font-bold text-base-content/40 uppercase w-12 flex-shrink-0 mt-1">Notes</span>
|
|
184
203
|
<textarea id="project-notes-input" rows="2" class="textarea textarea-xs textarea-bordered flex-1 text-xs leading-snug"
|
|
185
|
-
placeholder="Longer project notes (stack, links, status\u2026)">${(0,n.esc)(
|
|
204
|
+
placeholder="Longer project notes (stack, links, status\u2026)">${(0,n.esc)(An)}</textarea>
|
|
186
205
|
</div>
|
|
187
206
|
<div class="flex items-center gap-1 justify-end">
|
|
188
207
|
<button id="btn-save-project-notes" class="btn btn-primary btn-xs px-2">Save</button>
|
|
189
208
|
<button id="btn-cancel-project-notes" class="btn btn-ghost btn-xs px-2">Cancel</button>
|
|
190
209
|
</div>
|
|
191
210
|
</div>
|
|
192
|
-
`,(0,n.$)("project-goal-input")?.focus())}async function
|
|
211
|
+
`,(0,n.$)("project-goal-input")?.focus())}async function Gt(){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=`
|
|
193
212
|
<div class="flex-1 min-w-0 flex items-center gap-2">
|
|
194
213
|
<button type="button" class="session-fav-btn ${i?"is-fav":""}" data-fav-toggle="1"
|
|
195
214
|
data-fav-session-id="${(0,n.esc)(t)}" data-fav-session-agent="${(0,n.esc)(s)}"
|
|
@@ -209,12 +228,12 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
209
228
|
id="session-notes-text" title="${(0,n.esc)(a||"Add a note for this session")}">${(0,n.esc)(a||"No session note")}</span>
|
|
210
229
|
</div>
|
|
211
230
|
<button id="btn-edit-session-notes" class="btn btn-ghost btn-xs px-1.5">Note</button>
|
|
212
|
-
`}function
|
|
231
|
+
`}function sa(){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=`
|
|
213
232
|
<input id="session-notes-input" type="text" class="input input-xs input-bordered flex-1 text-xs"
|
|
214
233
|
placeholder="Note for this session\u2026" value="${(0,n.esc)(s.notes||"")}">
|
|
215
234
|
<button id="btn-save-session-notes" class="btn btn-primary btn-xs px-2">Save</button>
|
|
216
235
|
<button id="btn-cancel-session-notes" class="btn btn-ghost btn-xs px-2">Cancel</button>
|
|
217
|
-
`;let o=(0,n.$)("session-notes-input");o?.focus(),o?.select()}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 oa(e){return!e?.favorite&&!e?.hidden&&!(e?.notes||"").trim()&&!(e?.title||"").trim()}async function aa(e,t,{machineId:s}={}){let o=s||f.machineId||null,a=O(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 ia(e,t,{machineId:s}={}){if(!e)return!1;let o=s||f.machineId||null,a=O(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(oa(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 vs(e,t,s,{machineId:o}={}){let a=o||f.machineId||null,i=O(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 Ei(e,t,s,{machineId:o}={}){if(!e)return!1;let a=o||f.machineId||null,i=O(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(oa(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 ys({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"
|
|
218
237
|
value="${(0,n.esc)(r)}"
|
|
219
238
|
placeholder="Session name (empty = original)"
|
|
220
239
|
maxlength="200"
|
|
@@ -222,7 +241,8 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
222
241
|
data-rename-session-id="${(0,n.esc)(e)}"
|
|
223
242
|
data-rename-session-agent="${(0,n.esc)(t)}"
|
|
224
243
|
data-rename-session-machine="${(0,n.esc)(s||"")}"
|
|
225
|
-
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 x=m?l.value:r;if(a.className=u,!m){a.innerHTML=c;return}await
|
|
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 x=m?l.value:r;if(a.className=u,!m){a.innerHTML=c;return}await Ei(e,t,x,{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,zt=X(()=>{C();I();K();Cn="",An=""});var la={};Os(la,{goHome:()=>Hn,openProject:()=>ws,resumeSession:()=>we,switchTab:()=>Pe});function Pn(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 ws(e){let t=e?.path||"";(0,n.batch)(()=>{y.value=e,U.value=t,t&&(F.value=t,J.value=t,A.value="",B.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),Pn(e?.machineId||T.peek()||f.machineId),(0,n.$)("welcome").classList.add("hidden");let a=(0,n.$)("project-view");a.classList.remove("hidden"),a.style.display="flex",ft(),Ae(),Pe("chat")}function Hn(){y.value=null,U.value=null,F.value="",J.value="",A.value="",B.value=null,f.sessionId=null,Pn(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(_e()));let s=(0,n.$)("project-view");s&&(s.classList.add("hidden"),s.style.display="none"),hn("/")}async function we(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=M.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||T.peek()||null,x=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),ye();let W=x;ra(W,m,e),Ae(),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,ra(W,m,e),es({sessionId:e,cwd:W}))}).catch(()=>{}),ft(),Pe(r);{let w=M.peek();M.value=Array.isArray(w)?[...w]:[]}es({sessionId:e,cwd:W||x,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){b(`${Fe} \xB7 ${e.slice(0,8)}\u2026 \u2014 no history`);return}le();let z=40,ae=0,kt=()=>{if(f.sessionId!==e)return;let Zt=Math.min(ae+z,w.length);for(;ae<Zt;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 Hs=typeof L.content=="string"?L.content:Array.isArray(L.content)?L.content.map(Ca=>Ca?.text||"").filter(Boolean).join(`
|
|
245
|
+
`):String(L.content??"");Hs&&Qe(L.role==="user"?"user":"assistant",L.role==="user"?"You":Fe,Hs,{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(kt);return}le(),G&&ss(G);let $t=w.filter(L=>L.type==="token_usage").length||w.filter(L=>L.role==="user").length,St=We.truncated?` (showing last ${w.length} of ${We.total||"?"})`:"";b(`\u2500\u2500 ${Fe} history \xB7 ${$t} turn${$t!==1?"s":""}${St} \u2500\u2500`)};kt()},ke=async()=>{let w=_n.get(de);if(w&&w.msgs?.length&&Date.now()-w.at<Mi){qe(w.msgs,w.context,w.meta);return}b(`Loading ${Fe} history\u2026`);try{let G=m||T.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 $t=>{let St=new URLSearchParams({tail:"0",compact:"1"});return $t&&St.set("agent",$t),G&&St.set("machine",G),h("GET",`/api/sessions/${e}/messages?${St}`,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 kt=Array.isArray(z)?null:z?.context||null,Zt=Array.isArray(z)?{}:{truncated:z?.truncated,total:z?.total};ae.length?_n.set(de,{msgs:ae,context:kt,meta:Zt,at:Date.now()}):_n.delete(de),qe(ae,kt,Zt)}catch(G){if(f.sessionId!==e)return;_n.delete(de),(0,n.$)("messages").innerHTML="",b(`${Fe} \xB7 ${e.slice(0,8)}\u2026 (history unavailable: ${G.message})`)}};c?ke().catch(()=>{}):(await new Promise(w=>requestAnimationFrame(w)),ke().catch(()=>{})),bn(),ce()}function ra(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},U.value=e,F.value=e,J.value=e,A.value="",B.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),Pn(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"),Pn(t)}}function Pe(e){j.value=e}var _n,Mi,Jt=X(()=>{C();I();K();nn();mt();xn();gt();zt();ms();_n=new Map,Mi=180*1e3});I();K();C();I();K();var dt=null;function Vs(){return window.matchMedia("(display-mode: standalone)").matches||window.navigator.standalone===!0||document.referrer.includes("android-app://")}function Ys(){document.getElementById("btn-pwa-install")?.classList.remove("hidden")}function Xs(){Vs()&&document.documentElement.classList.add("pwa-standalone"),window.addEventListener("beforeinstallprompt",s=>{s.preventDefault(),dt=s,document.dispatchEvent(new CustomEvent("pwa-installable")),Ys()}),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(!Vs()&&(e||/Android/i.test(navigator.userAgent))&&requestAnimationFrame(()=>Ys()),!("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 Qs(){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"}nn();mt();xn();C();K();I();yn();function To(){document.getElementById("root").insertAdjacentHTML("beforeend",`
|
|
226
246
|
<dialog id="modal-settings" class="modal">
|
|
227
247
|
<div class="modal-box max-w-lg">
|
|
228
248
|
<h3 class="font-bold text-base mb-4">\u2699\uFE0F Settings \u2014 Workspaces</h3>
|
|
@@ -241,15 +261,15 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
241
261
|
</div>
|
|
242
262
|
</div>
|
|
243
263
|
<form method="dialog" class="modal-backdrop"><button>close</button></form>
|
|
244
|
-
</dialog>`),
|
|
264
|
+
</dialog>`),wn(),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 wn(){let e=(0,n.$)("ws-list");if(!e)return;let t=H.peek();if(!t.length){e.innerHTML='<div class="text-xs text-base-content/40">No workspaces configured</div>';return}e.innerHTML=t.map(s=>`
|
|
245
265
|
<div class="flex items-center gap-2 px-3 py-2 bg-base-200 rounded-lg">
|
|
246
266
|
<div class="flex-1 min-w-0">
|
|
247
267
|
<div class="text-sm font-medium">${(0,n.esc)(s.name)}</div>
|
|
248
268
|
<div class="text-xs font-mono text-base-content/50 truncate">${(0,n.esc)(s.configDir)}</div>
|
|
249
269
|
</div>
|
|
250
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>'}
|
|
251
|
-
</div>`).join(""),e.querySelectorAll("[data-ws-delete]").forEach(s=>{s.addEventListener("click",()=>
|
|
252
|
-
`);c=p.pop()||"";for(let m of p)if(m.startsWith("event:"))u=m.slice(6).trim();else if(m.startsWith("data:")){let x=m.slice(5).trim();if(!x)continue;let g;try{g=JSON.parse(x)}catch{continue}s[u]?.(g),s.any?.(u,g),u="message"}else m.trim()===""&&(u="message")}}function
|
|
271
|
+
</div>`).join(""),e.querySelectorAll("[data-ws-delete]").forEach(s=>{s.addEventListener("click",()=>di(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});H.value=[...H.peek(),o],Rt(H.peek()),(0,n.$)("ws-new-name").value="",(0,n.$)("ws-new-dir").value="",wn()}catch(o){s.textContent=o.message,s.classList.remove("hidden")}}async function di(e){try{await h("DELETE",`/api/workspaces/${e}`),H.value=H.peek().filter(t=>t.id!==e),Rt(H.peek()),wn()}catch(t){alert(t.message)}}function Eo(){wn(),(0,n.$)("modal-settings")?.showModal()}C();K();I();var Ln=!1,Ue="chat",ht=!1,q=null,ee=null,Ze=[],Mo=0,kn=null,cs=localStorage.getItem("ai_last_auto_report")||"",Sn=[],jo="",Be="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 x=m.slice(5).trim();if(!x)continue;let g;try{g=JSON.parse(x)}catch{continue}s[u]?.(g),s.any?.(u,g),u="message"}else m.trim()===""&&(u="message")}}function pi(){return`
|
|
253
273
|
<div id="meta-agent-panel" class="meta-agent-panel hidden" aria-hidden="true">
|
|
254
274
|
<div class="meta-agent-backdrop" data-ma-close="1"></div>
|
|
255
275
|
<div class="meta-agent-sheet">
|
|
@@ -289,7 +309,16 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
289
309
|
</label>
|
|
290
310
|
<textarea id="ma-input" rows="1" placeholder="\u7EE7\u7EED\u63D0\u95EE\u2026 (\u2318\u21B5 \u53D1\u9001) \xB7 \u5386\u53F2\u4F1A\u8BDD\u4F1A\u5E26\u7740\u4E0A\u4E0B\u6587"
|
|
291
311
|
class="textarea textarea-bordered flex-1 text-sm resize-none leading-relaxed"
|
|
292
|
-
style="min-height:40px;max-height:120px"
|
|
312
|
+
style="min-height:40px;max-height:120px"
|
|
313
|
+
name="meta-agent-message"
|
|
314
|
+
autocomplete="off"
|
|
315
|
+
autocorrect="off"
|
|
316
|
+
autocapitalize="off"
|
|
317
|
+
spellcheck="false"
|
|
318
|
+
data-1p-ignore="true"
|
|
319
|
+
data-lpignore="true"
|
|
320
|
+
data-form-type="other"
|
|
321
|
+
data-bwignore="true"></textarea>
|
|
293
322
|
<button type="button" id="ma-send" class="btn btn-primary btn-sm" style="height:40px">\u53D1\u9001</button>
|
|
294
323
|
</div>
|
|
295
324
|
</div>
|
|
@@ -369,29 +398,29 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
369
398
|
</div>
|
|
370
399
|
</div>
|
|
371
400
|
</div>
|
|
372
|
-
</div>`}function
|
|
401
|
+
</div>`}function oe(e){Ue=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=Ho(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"),Ln=!0,oe(e),e==="chat"){je();let s=localStorage.getItem(Be);!q&&s?De(s,{silent:!0}).catch(()=>{localStorage.removeItem(Be)}):Ot()}e==="history"&&je().then(()=>et()),e==="report"&&No(),e==="config"&&Ro(),setTimeout(()=>{Ue==="chat"&&(0,n.$)("ma-input")?.focus(),Ue==="history"&&(0,n.$)("ma-history-search")?.focus()},50)}}function Do(){let e=(0,n.$)("meta-agent-panel");e&&(e.classList.add("hidden"),e.setAttribute("aria-hidden","true"),Ln=!1)}function _o(){Ln?Do():ps(Ue==="config"?"chat":Ue)}function P(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||"")}">
|
|
373
402
|
<span class="ma-tool-name">${(0,n.esc)(s.name||"tool")}</span>
|
|
374
403
|
<span class="ma-tool-phase">${(0,n.esc)(s.phase||"")}</span>
|
|
375
404
|
<pre class="ma-tool-args">${(0,n.esc)(JSON.stringify(s.args||{},null,0).slice(0,200))}</pre>
|
|
376
|
-
</div>`),o.appendChild(a),o.scrollTop=o.scrollHeight,a}function
|
|
405
|
+
</div>`),o.appendChild(a),o.scrollTop=o.scrollHeight,a}function Io(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 ui(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=`
|
|
377
406
|
<div class="ma-approval-label">\u26A0 Agent \u60F3\u8981\u6267\u884C\u547D\u4EE4\uFF0C\u662F\u5426\u5141\u8BB8\uFF1F</div>
|
|
378
407
|
<pre class="ma-approval-cmd">${(0,n.esc)(o)}</pre>
|
|
379
408
|
<div class="ma-approval-actions">
|
|
380
409
|
<button type="button" class="btn btn-xs btn-error" data-approve="0">\u62D2\u7EDD</button>
|
|
381
410
|
<button type="button" class="btn btn-xs btn-success" data-approve="1">\u5141\u8BB8\u6267\u884C</button>
|
|
382
|
-
</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 fi(){return Mo+=1,`img${Mo}`}function mi(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 Co(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=fi(),r=`[${i}](${a})`,c=(0,n.$)("ma-input");mi(c,(c?.value&&!c.value.endsWith(`
|
|
383
412
|
`)&&c.value.length?`
|
|
384
413
|
`:"")+r+`
|
|
385
|
-
`);let u="";try{u=URL.createObjectURL(e)}catch{}return
|
|
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)=>`
|
|
386
415
|
<div class="ma-thumb relative" title="${(0,n.esc)(t.ref||t.path)}">
|
|
387
416
|
${t.previewUrl?`<img src="${t.previewUrl}" alt="${(0,n.esc)(t.label||"img")}">`:`<span class="ma-thumb-path">${(0,n.esc)(t.label||"img")}</span>`}
|
|
388
417
|
<span class="ma-thumb-label">${(0,n.esc)(t.label||"")}</span>
|
|
389
418
|
<button type="button" class="ma-thumb-x" data-rm-img="${s}">\u2715</button>
|
|
390
|
-
</div>`).join(""),e.querySelectorAll("[data-rm-img]").forEach(t=>{t.addEventListener("click",()=>{let s=parseInt(t.dataset.rmImg,10),o=
|
|
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,`
|
|
391
420
|
|
|
392
|
-
`),a.dispatchEvent(new Event("input"))),
|
|
421
|
+
`),a.dispatchEvent(new Event("input"))),Ze.splice(s,1),us()})})}}function Ho(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 je(){try{Sn=(await h("GET","/api/ai/sessions")).sessions||[]}catch{Sn=[]}return Sn}function et(){let e=(0,n.$)("ma-history-list");if(!e)return;let t=(jo||"").trim().toLowerCase(),s=Sn;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">
|
|
393
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"}
|
|
394
|
-
</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=Ho(o.updatedAt)||"",r=o.messageCount||0;return`
|
|
395
424
|
<div class="ma-hist-item ${a?"active":""}" data-hist-id="${(0,n.esc)(o.id)}">
|
|
396
425
|
<div class="flex items-start gap-2">
|
|
397
426
|
<button type="button" class="ma-hist-open flex-1 min-w-0 text-left" data-hist-open="${(0,n.esc)(o.id)}">
|
|
@@ -404,17 +433,17 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
404
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>
|
|
405
434
|
</div>
|
|
406
435
|
</div>
|
|
407
|
-
</div>`}).join(""),e.querySelectorAll("[data-hist-open]").forEach(o=>{o.addEventListener("click",async()=>{await
|
|
408
|
-
`)||"[\u2026]"}function
|
|
436
|
+
</div>`}).join(""),e.querySelectorAll("[data-hist-open]").forEach(o=>{o.addEventListener("click",async()=>{await De(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 De(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(Be),De(null)),await je(),et()}catch(r){alert(r.message)}})})}function Ao(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 hi(e){let t=(0,n.$)("ma-messages");if(t){if(t.innerHTML="",!e?.length){P("system","\u6B64\u4F1A\u8BDD\u6682\u65E0\u6D88\u606F\u3002");return}for(let s of e){if(s.role==="user"){P("user",Ao(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{}P("tool","",{name:a,args:i,phase:"history",id:o.id||a})}s.content&&P("assistant",typeof s.content=="string"?s.content:Ao(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{P("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 bi(){if(!q){await De(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(Be),await je(),await De(null),Ue==="history"&&et()}catch(e){P("error",e.message)}}async function De(e,t={}){if(!e){q=null,ee=null,localStorage.removeItem(Be);let s=(0,n.$)("ma-messages");return s&&(s.innerHTML=""),P("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(Be,s.id),hi(s.messages||[]),t.silent||P("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(),Ue==="history"&&et(),s}catch(s){throw t.silent||P("error",s.message),s}}async function $n(){if(ht)return;let e=(0,n.$)("ma-input"),t=(e?.value||"").trim();if(!t)return;ht=!0,(0,n.$)("ma-send").disabled=!0,P("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(Be,a.id),Ot()},content:a=>{o=a.content||"",s||(s=P("assistant","")),Io(s,o)},tool:a=>{a.phase==="start"?P("tool","",{name:a.name,args:a.args,phase:"start",id:a.id}):Po(a.id,a.phase,a.result)},approval:a=>ui(a),done:a=>{a.sessionId&&(q=a.sessionId,localStorage.setItem(Be,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&&Io(s,a.content),Ot(),je()},error:a=>{P("error",a.message||"error")}})}catch(a){P("error",a.message)}finally{ht=!1,(0,n.$)("ma-send").disabled=!1}}async function xi(){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 No(){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=`
|
|
409
438
|
<div class="text-[10px] text-base-content/40 mb-2">${(0,n.esc)(s.title||t)} \xB7 ${(0,n.esc)(s.generatedAt||"")}</div>
|
|
410
|
-
<div class="md ma-report-md">${
|
|
439
|
+
<div class="md ma-report-md">${bt(s.markdown)}</div>`,xt(o)}}catch{}}async function gi(){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=>`
|
|
411
440
|
<button type="button" class="ma-report-item w-full text-left px-2 py-1 rounded hover:bg-base-200 text-xs"
|
|
412
441
|
data-day="${(0,n.esc)(o.day)}">
|
|
413
442
|
<span class="font-semibold">${(0,n.esc)(o.day)}</span>
|
|
414
443
|
<span class="text-base-content/45 ml-1">${(0,n.esc)(o.title||"")}</span>
|
|
415
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=`
|
|
416
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>
|
|
417
|
-
<div class="md ma-report-md">${
|
|
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 Ro(){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 vi(){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(kn&&(clearInterval(kn),kn=null),!e?.auto_report)return;let t=e.auto_report_hour??18;kn=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",pi()),document.querySelectorAll("[data-ma-close]").forEach(e=>{e.addEventListener("click",Do)}),(0,n.$)("ma-btn-chat")?.addEventListener("click",()=>oe("chat")),(0,n.$)("ma-btn-history")?.addEventListener("click",async()=>{await je(),oe("history")}),(0,n.$)("ma-open-history")?.addEventListener("click",async()=>{await je(),oe("history")}),(0,n.$)("ma-btn-report")?.addEventListener("click",()=>{oe("report"),No()}),(0,n.$)("ma-btn-config")?.addEventListener("click",()=>{oe("config"),Ro()}),(0,n.$)("ma-send")?.addEventListener("click",$n),(0,n.$)("ma-input")?.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key==="Enter"&&(e.preventDefault(),$n())}),(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",()=>{De(null),oe("chat")}),(0,n.$)("ma-del-session")?.addEventListener("click",bi),(0,n.$)("ma-resume-focus")?.addEventListener("click",()=>{(0,n.$)("ma-input")?.focus()}),(0,n.$)("ma-history-refresh")?.addEventListener("click",async()=>{await je(),et()}),(0,n.$)("ma-history-new")?.addEventListener("click",()=>{De(null),oe("chat")}),(0,n.$)("ma-history-search")?.addEventListener("input",e=>{jo=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",$n()}),(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",$n()}),(0,n.$)("ma-gen-report")?.addEventListener("click",xi),(0,n.$)("ma-load-reports")?.addEventListener("click",gi),(0,n.$)("ma-cfg-save")?.addEventListener("click",vi),(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){P("error",`${o.name} \u8FC7\u5927 (>12MB)`);continue}await Co(o,o.name||`upload-${Date.now()}.png`)}}catch(o){P("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(!Ln||Ue!=="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 Co(c,`paste-${Date.now()}.${u}`)}}catch(r){P("error",`\u7C98\u8D34\u56FE\u7247\u5931\u8D25: ${r.message}`)}finally{t&&(t.disabled=!1,t.focus())}}}),De(null,{silent:!0}))}function Bt(){f.token&&(k.peek()&&!Mt()||(je(),h("GET","/api/ai/config").then(Ut).catch(()=>{})))}I();var Uo=()=>`
|
|
418
447
|
<div id="auth-screen" class="${f.token?"hidden":""} flex items-center justify-center h-full p-4" ${f.token?'style="display:none"':""}>
|
|
419
448
|
<div class="card bg-base-200 border border-base-300 w-full max-w-sm shadow-xl">
|
|
420
449
|
<div class="card-body gap-3 p-8">
|
|
@@ -432,7 +461,7 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
432
461
|
<div id="auth-error" class="alert alert-error text-xs py-2 hidden"></div>
|
|
433
462
|
</div>
|
|
434
463
|
</div>
|
|
435
|
-
</div>`,
|
|
464
|
+
</div>`,Bo=(e={})=>{let t=!!e.restoreSession,s=f.token?"":"hidden",o=f.token?"display:flex":"display:none";return`
|
|
436
465
|
<div id="sidebar-overlay" class="hidden fixed inset-0 bg-black/50 z-[9]"></div>
|
|
437
466
|
<div id="app" class="${s} flex-col flex-1 overflow-hidden" style="${o}">
|
|
438
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">
|
|
@@ -456,7 +485,23 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
456
485
|
<p id="machine-menu-empty" class="text-xs text-base-content/40 px-1 py-2 hidden">\u6682\u65E0\u673A\u5668\u5728\u7EBF</p>
|
|
457
486
|
</div>
|
|
458
487
|
</div>
|
|
459
|
-
<
|
|
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">
|
|
491
|
+
<span>\u6700\u8FD1</span>
|
|
492
|
+
<span class="text-[10px] opacity-50">\u25BE</span>
|
|
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
|
+
</div>
|
|
504
|
+
<span id="topbar-project" class="text-sm text-base-content/50 flex-1 truncate min-w-0">Select a session</span>
|
|
460
505
|
<span id="conn-dot" class="w-2 h-2 rounded-full bg-base-content/30 flex-shrink-0" title="\u8FDE\u63A5\u72B6\u6001"></span>
|
|
461
506
|
<div class="flex gap-2">
|
|
462
507
|
<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>
|
|
@@ -659,13 +704,21 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
659
704
|
<option value="full">density: full</option>
|
|
660
705
|
</select>
|
|
661
706
|
</div>
|
|
662
|
-
<div class="flex gap-2 items-end px-3 pt-2 pb-2">
|
|
663
|
-
<button id="btn-opts" class="btn btn-ghost btn-sm px-2 text-base-content/30 hover:text-base-content flex-shrink-0" title="Options"
|
|
707
|
+
<div id="composer-row" class="flex gap-2 items-end px-3 pt-2 pb-2">
|
|
708
|
+
<button id="btn-opts" class="btn btn-ghost btn-sm px-2 text-base-content/30 hover:text-base-content flex-shrink-0" title="Options">\u2699</button>
|
|
664
709
|
<textarea id="chat-input" rows="1" placeholder="Ask\u2026 (!cmd shell \xB7 \u2318\u21B5 send)"
|
|
665
710
|
class="chat-input flex-1 text-sm resize-none leading-relaxed"
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
711
|
+
name="agent-chat-message"
|
|
712
|
+
autocomplete="off"
|
|
713
|
+
autocorrect="off"
|
|
714
|
+
autocapitalize="off"
|
|
715
|
+
spellcheck="false"
|
|
716
|
+
data-1p-ignore="true"
|
|
717
|
+
data-lpignore="true"
|
|
718
|
+
data-form-type="other"
|
|
719
|
+
data-bwignore="true"></textarea>
|
|
720
|
+
<button id="send-btn" class="btn btn-primary btn-sm flex-shrink-0">Send</button>
|
|
721
|
+
<button id="stop-btn" class="btn btn-error btn-sm hidden flex-shrink-0">\u25A0</button>
|
|
669
722
|
</div>
|
|
670
723
|
</div>
|
|
671
724
|
</div>
|
|
@@ -742,7 +795,7 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
742
795
|
</div>
|
|
743
796
|
</div>
|
|
744
797
|
<form method="dialog" class="modal-backdrop"><button>close</button></form>
|
|
745
|
-
</dialog>`};
|
|
798
|
+
</dialog>`};ms();gt();Jt();C();I();K();yn();nn();gt();zt();Jt();C();I();K();gt();zt();async function yt(){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 ks(){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`
|
|
746
799
|
<button type="button" class="machine-pick-card w-full text-left px-4 py-3 rounded-xl border border-base-300
|
|
747
800
|
hover:border-primary hover:bg-primary/5 transition-colors ${a?"":"opacity-50"}"
|
|
748
801
|
data-pick-machine="${(0,n.esc)(o.id)}" ${a?"":"disabled"}>
|
|
@@ -751,7 +804,7 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
751
804
|
<span class="font-semibold text-sm font-mono">${(0,n.esc)(o.id)}</span>
|
|
752
805
|
</div>
|
|
753
806
|
${i?`<div class="text-xs text-base-content/45 mt-1 pl-4">${(0,n.esc)(i)}</div>`:""}
|
|
754
|
-
</button>`}).join("")}function
|
|
807
|
+
</button>`}).join("")}function wt(){let e=(0,n.$)("machine-picker");if(!e)return;e.classList.remove("hidden"),Ee.value=!1,ks();let t=(0,n.$)("machine-picker-status");if(t){let s=(D.peek()||[]).filter(o=>o.online!==!1).length;t.textContent=`${s} online`}}function $s(){(0,n.$)("machine-picker")?.classList.add("hidden"),Ee.value=!0}function Kt(){(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=T.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`
|
|
755
808
|
<button type="button"
|
|
756
809
|
class="machine-menu-item w-full text-left px-2 py-1.5 rounded-md text-xs
|
|
757
810
|
${r?"bg-primary/15 text-primary":"hover:bg-base-200"}
|
|
@@ -765,7 +818,7 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
765
818
|
<span class="text-[9px] ${i?"text-success":"text-error"}">${i?"online":"offline"}</span>
|
|
766
819
|
</div>
|
|
767
820
|
${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>`:""}
|
|
768
|
-
</button>`}).join("")}function
|
|
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=T.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 ca=null;function da(){ca||(ca=setInterval(async()=>{if(!k.peek()||!f.token)return;await yt(),st();let e=T.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 pa(e,{forceReload:t=!1}={}){if(!e)return;let s=T.peek(),o=s&&s!==e;if(Z(e),$s(),Kt(),st(),o||t){try{f.ws?.close()}catch{}f.ws=null,f.sessionId=null,(0,n.batch)(()=>{y.value=null,U.value=null,B.value=null});try{let{filesRoot:i,gitRoot:r,filesPath:c}=await Promise.resolve().then(()=>(I(),Ws));i.value="",r.value="",c.value=""}catch{}if(o){let{goHome:i}=await Promise.resolve().then(()=>(Jt(),la));i()}}let a=(0,n.$)("topbar-project");a&&!y.peek()&&(a.textContent=`Machine \xB7 ${e}`),Bt(),await Promise.all([ve(),qt(),Gt(),Wt().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),$s(),Ee.value=!0,Bt());let u=yt().then(p=>(st(),c&&!p.some(x=>x.id===c&&x.online!==!1)&&p.length&&(p.some(g=>g.id===c)||(Z(null),wt())),p));da(),st();let l=Promise.all([ve({waitFresh:!1}),qt({waitFresh:!1}),Gt().catch(()=>{}),Wt().catch(()=>{})]);if(o?.id){let p=M.peek().find(m=>m.sessionId===o.id)||(a?.sessionId===o.id?a:null);await we(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){wt(),l.catch(()=>{});return}wt(),l.catch(()=>{});return}await l;let d=(0,n.$)("topbar-project");d&&d.textContent==="Select a session"&&(d.textContent=`Machine \xB7 ${c}`);return}Bt();let r=Promise.all([ve({waitFresh:!1}),qt({waitFresh:!1}),Gt().catch(()=>{}),Wt().catch(()=>{})]);if(o?.id){await vn().then(u=>{Array.isArray(u)?M.value=u:u&&Array.isArray(u.sessions)&&(M.value=u.sessions)}).catch(()=>{});let c=M.peek().find(u=>u.sessionId===o.id)||(a?.sessionId===o.id?a:null);await we(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}zt();C();I();K();mt();gt();Jt();function ua(){(0,n.$)("sidebar").classList.add("open"),(0,n.$)("sidebar-overlay").classList.remove("hidden")}function On(){(0,n.$)("sidebar").classList.remove("open"),(0,n.$)("sidebar-overlay").classList.add("hidden")}function fa(){window.innerWidth<=640&&On()}function ma(){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 ha(){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 Ss(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 ba(){let e=document.documentElement.getAttribute("data-theme")||"dark";Ss(e==="dark"?"light":"dark")}function xa(){let e=(0,n.$)("new-session-agent");e&&(e.value=S.peek()||"claude");let t=(0,n.$)("new-session-workspace");if(t){let a=H.peek();t.innerHTML=a.map(i=>`<option value="${(0,n.esc)(i.configDir)}">${(0,n.esc)(i.name)} \u2014 ${(0,n.esc)(i.configDir)}</option>`).join(""),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=T.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);Ls(),(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 Ls(){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=T.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"),wt();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()),ye(),(0,n.batch)(()=>{y.value={id:i,name:i,path:a.path,machineId:T.peek()||f.machineId},U.value=a.path,F.value=a.path,J.value=a.path,A.value="",B.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(),Ae(),Pe("chat"),b(`New ${R[t]||t} session \xB7 ${a.path}`)}catch(a){o.textContent=a.message,o.classList.remove("hidden")}}function Ii(){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">
|
|
769
822
|
<li>\u70B9\u5E95\u90E8\u5206\u4EAB\u6309\u94AE <strong>\u5206\u4EAB</strong>\uFF08\u65B9\u6846+\u5411\u4E0A\u7BAD\u5934\uFF09</li>
|
|
770
823
|
<li>\u4E0B\u6ED1\u627E\u5230\u5E76\u70B9 <strong>\u6DFB\u52A0\u5230\u4E3B\u5C4F\u5E55</strong></li>
|
|
771
824
|
<li>\u786E\u8BA4\u540D\u79F0\u540E\u70B9 <strong>\u6DFB\u52A0</strong></li>
|
|
@@ -783,29 +836,29 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
783
836
|
<form method="dialog"><button class="btn btn-sm">\u77E5\u9053\u4E86</button></form>
|
|
784
837
|
</div>
|
|
785
838
|
</div>
|
|
786
|
-
<form method="dialog" class="modal-backdrop"><button>close</button></form>`,o.showModal()}async function
|
|
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 ga(){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 Ms(){return f.token?/^#\/session\//.test(location.hash||""):!1}function va(e={}){if(Ss(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??Ms(),s=document.getElementById("root");if(s.style.cssText="display:flex;flex-direction:column;flex:1;height:100%",s.innerHTML=Uo()+Bo({restoreSession:t}),t){let l=(0,n.$)("session-list");l&&(l.innerHTML='<div class="px-3 py-3 text-[10px] text-base-content/35">Loading sessions\u2026</div>')}(0,n.effect)(()=>{let l=H.value,d=(0,n.$)("ws-tabs");if(!d)return;if(l.length<=1){d.innerHTML="";return}let p=U.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
|
|
787
840
|
${(m.id===null?!p:p===m.configDir)?"border-primary text-primary":"border-transparent text-base-content/50 hover:text-base-content"}"
|
|
788
841
|
data-ws-tab="${(0,n.esc)(m.configDir||"")}">
|
|
789
842
|
${(0,n.esc)(m.name)}
|
|
790
|
-
</button>`).join("")}),(0,n.effect)(()=>{Pe.value,Ue.value,we.value,ke.value,ce.value,v.value;let l=(0,n.$)("session-list");l&&(l.querySelector(".session-rename-input")||(l.innerHTML=Go(),zo()))}),(0,n.effect)(()=>{E.value,X.value,L.value,S.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"||Xe())}),(0,n.watch)(B,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)Ko(l.path);else{let d=(0,n.$)("project-notes-bar");d&&(d.style.display="none")}}),(0,n.watch)(A,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"&&ms(),l==="shell"&&requestAnimationFrame(()=>{document.dispatchEvent(new CustomEvent("shell-tab-shown"))})}),ca(),la();let o=null;document.addEventListener("sessions-changed",()=>{o&&clearTimeout(o),o=setTimeout(()=>{o=null,be({waitFresh:!1})},1200)}),document.addEventListener("router:home",An),document.addEventListener("router:session",async({detail:{id:l,tab:d}})=>{let p=E.peek().find(x=>x.sessionId===l),m=qe();await ge(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",An),n.delegate.on("click","#auth-btn",ua),n.delegate.on("keydown","#auth-username, #auth-password",l=>{l.key==="Enter"&&ua()}),n.delegate.on("click","#hamburger",()=>(0,n.$)("sidebar").classList.contains("open")?Pn():ia()),n.delegate.on("click","#sidebar-overlay",Pn),n.delegate.on("input","#session-search",(l,d)=>{N.value=d.value,Ln(d.value)}),n.delegate.on("click","#session-filter-badge",()=>{B.value=null}),n.delegate.on("click","[data-ws-tab]",(l,d)=>{B.value=d.dataset.wsTab||null}),n.delegate.on("click","#sidebar-refresh",()=>{be(),N.peek().trim()&&fs(N.peek())}),n.delegate.on("click","[data-view]",(l,d)=>{we.value=d.dataset.view,localStorage.setItem("sidebarView",d.dataset.view)}),n.delegate.on("click","[data-agent-filter]",(l,d)=>{X.value=d.dataset.agentFilter,localStorage.setItem("agentFilter",d.dataset.agentFilter),N.peek().trim()&&Ln(N.peek())}),n.delegate.on("change","#time-range",(l,d)=>{Z.value=d.value,localStorage.setItem("timeRange",d.value),be({waitFresh:!0}),N.peek().trim()&&Ln(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;xs({id:m,name:m,path:p}),b(`Project \xB7 ${p}`)}),n.delegate.on("click","#btn-pwa-install",async()=>{await Js()||wi()}),document.addEventListener("pwa-installable",()=>{document.getElementById("btn-pwa-install")?.classList.remove("hidden")}),n.delegate.on("click","#btn-settings",ko),n.delegate.on("click","#btn-meta-agent",()=>Io()),n.delegate.on("click","#btn-meta-agent-welcome",()=>rs("chat")),n.delegate.on("click","#btn-theme",da),n.delegate.on("click","#btn-cal-prev",()=>{cs(-1),Xe(Ye())}),n.delegate.on("click","#btn-cal-next",()=>{cs(1),Xe(Ye())}),n.delegate.on("click","[data-cal-date]",(l,d)=>{Bo(d.dataset.calDate),Xe(Ye())}),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")||(ge(d.dataset.sessionId,d.dataset.sessionCwd||null,d.dataset.sessionConfigDir||null,d.dataset.sessionAgent||"claude",d.dataset.sessionMachine||null),ra())}),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&&bs({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;bs({sessionId:f.sessionId,agent:f.agent||$.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(et.peek()),W=new Set(tt.peek());x?(g.delete(p),W.add(p)):(g.add(p),W.delete(p)),(0,n.batch)(()=>{et.value=g,tt.value=W})}),n.delegate.on("click","#memory-refresh",ms),n.delegate.on("click","[data-tab]",(l,d)=>Ae(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",U)),n.delegate.on("click","#git-root-btn",()=>a("git-root-input",z)),n.delegate.on("keydown","#files-root-input",l=>{l.key==="Enter"&&a("files-root-input",U)}),n.delegate.on("keydown","#git-root-input",l=>{l.key==="Enter"&&a("git-root-input",z)}),n.delegate.on("click","#btn-opts",()=>{(0,n.$)("chat-opts").classList.toggle("hidden")}),n.delegate.on("change","#sel-agent",(l,d)=>{let p=$.peek(),m=d.value;p!==m&&(f.sessionId=null,pe(m),k.value=ae(m)||k.peek(),localStorage.setItem("model",k.peek()),xe(),b(`Agent \u2192 ${R[m]||m} \xB7 model ${k.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||$.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 be(),await ge(g.targetSessionId,y.peek()?.path||null,null,g.targetAgent),fn()):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)=>{k.value=d.value,localStorage.setItem("model",d.value),ps()}),n.delegate.on("click","#btn-model-add",()=>us({editCurrent:!1})),n.delegate.on("click","#btn-model-edit",()=>us({editCurrent:!0})),n.delegate.on("change","#sel-effort",(l,d)=>{le.value=d.value}),n.delegate.on("change","#sel-permission",(l,d)=>{wt.value=d.value}),n.delegate.on("change","#sel-density",(l,d)=>{zn(d.value),b(`Density \u2192 ${d.value} (applies to new tool calls; reload session to re-group history)`)}),document.addEventListener("agent-changed",xe),n.delegate.on("click","#btn-new-session, #btn-new-session-welcome",pa),n.delegate.on("click","#new-session-cancel",()=>(0,n.$)("modal-new-session").close()),n.delegate.on("click","#new-session-start",ks),n.delegate.on("change","#new-session-agent",ws),n.delegate.on("keydown","#new-session-path",l=>{l.key==="Enter"&&ks()}),n.delegate.on("click","#send-btn",pn),n.delegate.on("click","#stop-btn",po),n.delegate.on("click","#btn-logout",()=>{f.token=null,localStorage.removeItem("token"),ee(null),Se.value=!1,location.reload()}),n.delegate.on("click","[data-pick-machine]",async(l,d)=>{let p=d.dataset.pickMachine;if(!p||p===L.peek()){jn();return}await aa(p,{forceReload:!0})});let i=async()=>{let l=(0,n.$)("machine-picker-status");if(l&&(l.textContent="\u5237\u65B0\u4E2D\u2026"),await xt(),gs(),Dn(),Qe(),l){let d=(j.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();let d=(0,n.$)("machine-menu");d&&(d.classList.contains("hidden")?(await xt(),Dn(),d.classList.remove("hidden")):d.classList.add("hidden"))}),document.addEventListener("click",l=>{let d=(0,n.$)("machine-menu-wrap");d&&!d.contains(l.target)&&jn()}),n.delegate.on("click","#btn-edit-project-notes, #project-goal-text, #project-notes-text",()=>{Vo()}),n.delegate.on("click","#btn-cancel-project-notes",()=>{bt()});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});Jo(m.goal||"",m.notes||""),bt()}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"&&bt()}),n.delegate.on("keydown","#project-notes-input",l=>{l.key==="Escape"&&bt()}),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)),Qo(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)),Zo(d.dataset.hideSessionId,d.dataset.hideSessionAgent||"claude",{machineId:p||null})}),n.delegate.on("click","#btn-edit-session-notes, #session-notes-text",()=>{Yo()}),n.delegate.on("click","#btn-cancel-session-notes",()=>re()),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||$.peek()||"claude";await hs(f.sessionId,d,l)&&re()}),n.delegate.on("keydown","#session-notes-input",async l=>{if(l.key==="Escape"&&re(),l.key==="Enter"){let d=l.target.value.trim();if(!f.sessionId)return;let p=f.agent||$.peek()||"claude";await hs(f.sessionId,p,d)&&re()}}),n.delegate.on("click","#btn-fav-filter",()=>{let l=!De.peek();De.value=l,localStorage.setItem("favoritesOnly",l?"1":"0"),(0,n.$)("btn-fav-filter")?.classList.toggle("active",l),l&&_e.peek()&&(_e.value=!1,localStorage.setItem("showHiddenOnly","0"),(0,n.$)("btn-hidden-filter")?.classList.remove("active"))}),n.delegate.on("click","#btn-hidden-filter",()=>{let l=!_e.peek();_e.value=l,localStorage.setItem("showHiddenOnly",l?"1":"0"),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",l),l&&De.peek()&&(De.value=!1,localStorage.setItem("favoritesOnly","0"),(0,n.$)("btn-fav-filter")?.classList.remove("active"))}),xe(),dn();let c=(0,n.$)("sel-density");c&&(c.value=$e.peek()||"normal");let u=(0,n.$)("time-range");u&&(u.value=Z.peek()||"14"),document.querySelectorAll("[data-agent-filter]").forEach(l=>{l.classList.toggle("active",l.dataset.agentFilter===X.peek())}),(0,n.$)("btn-fav-filter")?.classList.toggle("active",De.peek()),(0,n.$)("btn-hidden-filter")?.classList.toggle("active",_e.peek()),document.querySelectorAll("[data-view]").forEach(l=>{let d=l.dataset.view===we.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)})}pt();I();M();J();function ki(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 ma(e){let t=$i(e);return t==="docx"||t==="pptx"||t==="xlsx"||t==="pdf"?t:null}function Si(e){return e==null?"":e>1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:e>1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function Li(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 Ls=new Map;function Hn(e){if(Ls.has(e))return Ls.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 Ls.set(e,t),t}function Ti(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 Ei(e){!e||typeof hljs>"u"||e.querySelectorAll("pre code.file-preview-code").forEach(t=>{try{delete t.dataset.highlighted,hljs.highlightElement(t)}catch{}})}function zt(e,t,s){let o=Si(t);return`
|
|
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`
|
|
791
844
|
<div class="flex items-center gap-2 px-4 py-1.5 border-b border-base-300 flex-shrink-0 bg-base-200">
|
|
792
845
|
<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>
|
|
793
|
-
<button class="btn btn-ghost btn-xs" data-download-path="${(0,n.esc)(e)}">\u2193 Download</button>
|
|
794
|
-
</div>`}function
|
|
846
|
+
<button type="button" class="btn btn-ghost btn-xs" data-download-path="${(0,n.esc)(e)}">\u2193 Download</button>
|
|
847
|
+
</div>`}function Hi(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=>`
|
|
795
848
|
<div class="flex items-center gap-2 px-4 py-1.5 hover:bg-base-300 group"
|
|
796
849
|
${t.isDir?`data-dir-path="${(0,n.esc)(t.path)}"`:`data-file-path="${(0,n.esc)(t.path)}"`}>
|
|
797
|
-
<span class="cursor-pointer flex-shrink-0">${t.isDir?"\u{1F4C1}":
|
|
850
|
+
<span class="cursor-pointer flex-shrink-0">${t.isDir?"\u{1F4C1}":Ci(t.name)}</span>
|
|
798
851
|
<span class="text-sm flex-1 truncate cursor-pointer ${t.isDir?"text-primary":""}">${(0,n.esc)(t.name)}</span>
|
|
799
852
|
${t.isDir?"":`
|
|
800
|
-
<button class="
|
|
801
|
-
data-download-path="${(0,n.esc)(t.path)}" title="Download">\u2193</button>
|
|
802
|
-
<button class="
|
|
803
|
-
data-delete-path="${(0,n.esc)(t.path)}" title="Delete">\u2715</button>`}
|
|
804
|
-
</div>`).join(""))}function
|
|
853
|
+
<button type="button" class="file-row-action btn btn-ghost btn-xs px-1.5 text-base-content/50 hover:text-base-content"
|
|
854
|
+
data-download-path="${(0,n.esc)(t.path)}" title="Download" aria-label="Download">\u2193</button>
|
|
855
|
+
<button type="button" class="file-row-action btn btn-ghost btn-xs px-1.5 text-error/60 hover:text-error"
|
|
856
|
+
data-delete-path="${(0,n.esc)(t.path)}" title="Delete" aria-label="Delete">\u2715</button>`}
|
|
857
|
+
</div>`).join(""))}function Ni(e,t,s){let o=/[\x00-\x08\x0e-\x1f]/.test(t.slice(0,512)),a=_i(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 Vt(e,s,o?"binary":a||"text")+r}async function Ri(e){if(await Un("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 Oi(e){if(await Un("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`
|
|
805
858
|
<div class="office-preview office-xlsx flex flex-col flex-1 min-h-0 overflow-hidden">
|
|
806
859
|
<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>
|
|
807
860
|
<div class="office-sheet-body flex-1 overflow-auto p-2">${a}</div>
|
|
808
|
-
</div>`}function
|
|
861
|
+
</div>`}function Ui(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 Bi(e){if(await Un("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=Ui(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(`
|
|
809
862
|
<article class="office-slide-card">
|
|
810
863
|
<header class="office-slide-num">Slide ${a+1}</header>
|
|
811
864
|
<div class="office-slide-body">${c}</div>
|
|
@@ -813,7 +866,7 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
813
866
|
<div class="office-preview office-pptx overflow-auto flex-1 p-3 space-y-3">
|
|
814
867
|
<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>
|
|
815
868
|
${o.join("")}
|
|
816
|
-
</div>`}async function
|
|
869
|
+
</div>`}async function Fi(){if(await Un("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 qi(e){let s=await(await Fi()).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(`
|
|
817
870
|
<figure class="office-pdf-figure">
|
|
818
871
|
<figcaption class="office-pdf-cap">Page ${c} / ${o}</figcaption>
|
|
819
872
|
${m.outerHTML}
|
|
@@ -822,12 +875,12 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
822
875
|
<p class="text-xs text-base-content/50 px-1">PDF preview \xB7 ${o} page(s)</p>
|
|
823
876
|
${r}
|
|
824
877
|
${i.join("")}
|
|
825
|
-
</div>`}async function
|
|
826
|
-
${
|
|
878
|
+
</div>`}async function Wi(e,t,s){let o=ya(e),a={docx:"Word",pptx:"PowerPoint",xlsx:"Excel",pdf:"PDF"},i=Di(t),r;if(o==="docx")r=await Ri(i);else if(o==="xlsx")r=await Oi(i);else if(o==="pptx")r=await Bi(i);else if(o==="pdf")r=await qi(i);else throw new Error("Unsupported office type");return Vt(e,s,a[o]||o)+r}function Gi(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 zi(){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 Ji(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?${Ks({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 Ki(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 Vi(e,t,s,o){let a=s.size??(typeof s.content=="string"?s.content.length:0),i=ya(t);if(i&&s.encoding==="base64"){e.innerHTML=Vt(t,a,i)+`<div class="p-4 text-xs text-base-content/40">Parsing ${i.toUpperCase()}\u2026</div>`;try{let r=await Wi(t,s.content,a);if(o.aborted)return;e.innerHTML=r}catch(r){if(o.aborted)return;e.innerHTML=Vt(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=Vt(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=Ni(t,s.content||"",a),Pi(e)}function wa(){(0,n.effect)(()=>{let e=(0,n.$)("files-breadcrumb");if(!e)return;let t=B.value!==null;e.innerHTML=`
|
|
879
|
+
${Gi(B.value??A.value,t)}
|
|
827
880
|
<div class="flex-1"></div>
|
|
828
|
-
${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=
|
|
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=B.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 Vi(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=Hi(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)=>{B.value=null,A.value=t.dataset.dirPath}),n.delegate.on("click","[data-file-path]",(e,t)=>{B.value=t.dataset.filePath}),n.delegate.on("click","#btn-upload",()=>zi()),n.delegate.on("click","[data-download-path]",(e,t)=>{e.preventDefault(),e.stopPropagation();let s=t.dataset.downloadPath;s&&Ji(y.peek(),s)}),n.delegate.on("click","[data-delete-path]",(e,t)=>{e.preventDefault(),e.stopPropagation();let s=t.dataset.deletePath;s&&Ki(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 ka=(0,n.signal)(!1);function Yi(e){return e?e.split(`
|
|
829
882
|
`).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(`
|
|
830
|
-
`):'<span class="text-base-content/40">No commits</span>'}function
|
|
883
|
+
`):'<span class="text-base-content/40">No commits</span>'}function Xi(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`
|
|
831
884
|
<div class="px-4 py-2 text-xs text-base-content/50 border-b border-base-300">
|
|
832
885
|
Branch: <span class="text-success font-semibold">${(0,n.esc)(e.branch)}</span>
|
|
833
886
|
</div>
|
|
@@ -853,16 +906,16 @@ Available: ${u}`:""}`),!0}let a=Fa[o.toLowerCase()]||o,i=$.peek()||"claude",r=de
|
|
|
853
906
|
<span class="text-base-content/40">Loading\u2026</span>
|
|
854
907
|
</div>
|
|
855
908
|
</div>
|
|
856
|
-
</div>`}function
|
|
909
|
+
</div>`}function Qi(e){return e.split(`
|
|
857
910
|
`).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(`
|
|
858
|
-
`)}function
|
|
859
|
-
`),
|
|
911
|
+
`)}function $a(){(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=Xi(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=ka.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?Qi(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";ka.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||Zi()})}function Zi(){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?Yi(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,E=null,Bn=null,Qt=!1,Fn=null,La=null,Yt=0,Xt=null,Cs=!1;function Ta(){if(E)return;let e=(0,n.$)("terminal-container");if(e){if(typeof Terminal>"u"){setTimeout(Ta,100);return}E=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"&&(Bn=new FitAddon.FitAddon,E.loadAddon(Bn)),E.open(e),As(),E.onData(t=>{Y&&Y.readyState===WebSocket.OPEN&&Y.send(JSON.stringify({type:"input",data:t}))}),window.addEventListener("resize",()=>{As(),js()})}}function As(){try{Bn&&E&&Bn.fit()}catch{}}function js(){Y&&Y.readyState===WebSocket.OPEN&&E&&Y.send(JSON.stringify({type:"resize",cols:E.cols,rows:E.rows}))}function Ea(){return f.machineId||T.peek()||null}function qn(e){Xt&&(clearTimeout(Xt),Xt=null),Cs=!0;let t=++Yt;if(Y){try{Y.close()}catch{}Y=null}Qt=!1;let s=location.protocol==="https:"?"wss":"ws",o=E?E.cols:80,a=E?E.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,La=r,Y=new WebSocket(`${s}://${location.host}/ws/shell?${i}`),Y.addEventListener("open",()=>{t===Yt&&(Qt=!0,E?.write(`\x1B[32mConnected to interactive terminal\x1B[0m\r
|
|
912
|
+
`),js())}),Y.addEventListener("message",c=>{if(t!==Yt)return;let u;try{u=JSON.parse(c.data)}catch{return}u.type==="output"?E?.write(u.data):u.type==="exit"?E?.write(`\r
|
|
860
913
|
\x1B[33m[process exited: ${u.code}]\x1B[0m\r
|
|
861
|
-
`):u.type==="error"&&
|
|
914
|
+
`):u.type==="error"&&E?.write(`\r
|
|
862
915
|
\x1B[31m[error: ${u.data||u.message||""}]\x1B[0m\r
|
|
863
|
-
`)}),
|
|
916
|
+
`)}),Y.addEventListener("close",()=>{t===Yt&&(Qt=!1,E?.write(`\r
|
|
864
917
|
\x1B[33m[disconnected]\x1B[0m\r
|
|
865
|
-
`),!(!
|
|
866
|
-
`),
|
|
918
|
+
`),!(!Cs||j.peek()!=="shell")&&(E?.write(`\x1B[33m[reconnecting\u2026]\x1B[0m\r
|
|
919
|
+
`),Xt=setTimeout(()=>{Xt=null,qn(Fn)},1500)))}),Y.addEventListener("error",()=>{t===Yt&&E?.write(`\r
|
|
867
920
|
\x1B[31m[WebSocket error]\x1B[0m\r
|
|
868
|
-
`)})}function
|
|
921
|
+
`)})}function Sa(){let e=y.peek()?.path,t=(0,n.$)("term-cwd");t&&(t.textContent=e||"~"),E||Ta(),requestAnimationFrame(()=>{requestAnimationFrame(()=>{As();let s=Ea();!Qt||Fn!==(e||null)||La!==s?(E?.clear(),qn(e)):js()})})}function Ma(){document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(j.peek()!=="shell"||!Cs||Qt||qn(Fn))}),(0,n.watch)(j,e=>{e==="shell"&&Sa()}),document.addEventListener("shell-tab-shown",()=>{j.peek()==="shell"&&Sa()}),document.getElementById("term-reconnect")?.addEventListener("click",()=>{E?.clear(),qn(y.peek()?.path)})}mt();xn();function Ds(){let e=document.documentElement;e.classList.add("boot-ready"),e.classList.remove("boot-pending")}function Wn(){document.documentElement.classList.remove("boot-restore")}var _s=rs(location.hash.slice(1)||"/"),Ia=Ms()||!!(f.token&&_s?.id);va({restoreSession:Ia});vo();wa();$a();To();Ma();xo();Oo();wo(we,Pe);(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")),Ia){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:_s}),_s?.id||(ko(),(location.hash||"").startsWith("#/session/")||Wn()),requestAnimationFrame(()=>{requestAnimationFrame(Ds)})}catch(t){console.error("[boot]",t),f.token=null,localStorage.removeItem("token"),Wn(),await Es(),Ds()}else Wn(),await Es(),Ds()})();document.addEventListener("router:home",()=>{Wn()});Xs();
|