tmux-weblink 2.2.25 → 2.2.27

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.
@@ -1,40 +1,41 @@
1
- var hn=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function Je(e){return e.replace(/\x1b\[\?1049[hl]/g,"")}function fe(e){return e.replace(hn,"")}var Ae;function vn(){return Ae||(document.querySelector("link[data-tmux-web-xterm-css]")?Ae=Promise.resolve():(Ae=new Promise(e=>{let t=document.createElement("link");t.rel="stylesheet",t.href="/assets/xterm.css",t.setAttribute("data-tmux-web-xterm-css",""),t.addEventListener("load",()=>e(),{once:!0}),t.addEventListener("error",()=>e(),{once:!0}),document.head.appendChild(t)}),Ae))}var gn=class _t{terminal;fitAddon;container;constructor(t,s,n){this.container=t,this.terminal=s,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(t)}static async create(t,s,n){let[{Terminal:l},{FitAddon:r}]=await Promise.all([import("./xterm-BXEES47M.js"),import("./addon-fit-D5N335P2.js"),vn()]),c=new l({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:s,convertEol:!1,smoothScrollDuration:120,theme:n});return new _t(t,c,new r)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(t){return new Promise(s=>this.terminal.write(t,s))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(t,s=!1){this.terminal.scrollToLine(Math.max(0,t),s)}scrollLines(t){let s=this.terminal.buffer?.active;this.terminal.scrollLines(t)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}fit(){let t=yn(this.container);if(t.width<=0||t.height<=0)return!1;let s=this.terminal._core?._renderService?.dimensions?.css?.cell;if(!s?.width||!s?.height)return this.fitAddon.fit(),!0;let n=s.width,l=s.height,r=this.terminal.element?.querySelector(".xterm-viewport"),c=r?Math.max(0,r.offsetWidth-r.clientWidth):0,i=Math.max(2,Math.floor((t.width-c-n/2)/n)),u=Math.max(2,Math.floor(t.height/l));return(i!==this.terminal.cols||u!==this.terminal.rows)&&this.terminal.resize(i,u),!0}focus(){this.terminal.focus()}pasteText(t){this.terminal.paste(t)}input(t){this.terminal.input(t,!1)}onData(t){this.terminal.onData(t),this.terminal.onBinary(t)}onResize(t){this.terminal.onResize(t)}onScroll(t){this.terminal.onScroll(t)}attachCustomKeyEventHandler(t){this.terminal.attachCustomKeyEventHandler(t)}isFocused(){let t=document.activeElement;return t?t===this.container||t===this.terminal.textarea||this.container.contains(t)||!!t.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(t,s){let n=this.terminal.buffer.active,[l,r]=t<=s?[t,s]:[s,t],c=n.viewportY,i=[];for(let u=l;u<=r;u++){let f=n.getLine(c+u);i.push(f?f.translateToString(!0):"")}return i.join(`
2
- `)}selectRows(t,s){let n=this.terminal.buffer.active,[l,r]=t<=s?[t,s]:[s,t];this.terminal.selectLines(n.viewportY+l,n.viewportY+r)}selectCells(t,s,n,l){let r=this.terminal.buffer.active,c=Math.min(s,l),i=Math.max(s,l);if(c===i){let u=Math.min(t,n),f=Math.max(t,n);this.terminal.select(u,r.viewportY+c,f-u+1)}else this.terminal.selectLines(r.viewportY+c,r.viewportY+i)}getCellsText(t,s,n,l){let r=this.terminal.buffer.active,c=Math.min(s,l),i=Math.max(s,l),u=s<l?t:s>l?n:Math.min(t,n),f=s<l?n:s>l?t:Math.max(t,n),S=r.viewportY,L=[];for(let F=c;F<=i;F++){let M=r.getLine(S+F);if(!M){L.push("");continue}let b=F===c?u:0,q=F===i?f:this.terminal.cols-1,ae="";for(let Ce=b;Ce<=q;Ce++){let O=M.getCell(Ce);O&&(ae+=O.getChars())}L.push(ae.replace(/\s+$/,""))}return L.join(`
3
- `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function yn(e){let t=e.getBoundingClientRect(),s=window.visualViewport;return s?{width:Math.min(t.width,s.width),height:Math.max(0,Math.min(t.height,s.height-Math.max(0,t.top)))}:t}function wn(e,t,s){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let n=await gn.create(e,s.scrollback,s.theme),l,r=0,c,i=null,u=0,f=0,S=.2,L=10,F=.95,M=.04,b=null,q=null;function ae(a){b||(b=document.createElement("div"),b.style.cssText=["position:absolute","left:0","width:40%","padding:10px 0","text-align:center","font:600 14px/1.4 system-ui, -apple-system, sans-serif","color:rgba(255,255,255,0.95)","background:rgba(20,30,50,0.55)","border:1px solid rgba(255,255,255,0.25)","border-radius:10px","pointer-events:none","opacity:0","transition:opacity 0.15s ease","z-index:6"].join(";"),e.appendChild(b)),b.textContent=a?"\u2191 \u4E0A\u7FFB\u4E00\u9875 (PgUp)":"\u2193 \u4E0B\u7FFB\u4E00\u9875 (PgDn)",b.style.top=a?"10%":"auto",b.style.bottom=a?"auto":"10%",b.style.opacity="1",q&&clearTimeout(q),q=setTimeout(()=>{b&&(b.style.opacity="0")},900)}function Ce(){q&&clearTimeout(q),b&&(b.style.opacity="0")}function O(){u&&(cancelAnimationFrame(u),u=0),f=0}function Yt(a){if(O(),Math.abs(a)<S)return;f=Math.max(-L,Math.min(L,a));let o=()=>{if(j){u=0;return}let d=e.querySelector(".xterm-rows > div"),p=d?d.getBoundingClientRect().height:16,v=p>0?Math.round(f*16/p):f>0?1:-1;v===0&&(v=f>0?1:-1);let A=n.viewportY()-v,V=n.baseY(),pe=Math.max(0,Math.min(A,V));if(n.scrollToLine(pe,!0),f*=F,pe!==A){u=0;return}if(Math.abs(f)<M){u=0;return}u=requestAnimationFrame(o)};u=requestAnimationFrame(o)}let ke=0,R="connecting",Se=0,ie=!1,Te=[],Z="",j=!1,oe=1e3,qt=location.protocol==="https:"?"wss:":"ws:",lt=s.wsBase||"/ws",Ot=qt+"//"+location.host+lt+"/"+encodeURIComponent(t),Wt=(lt.replace(/^\/ws/,"")||"")+"/api/session/"+encodeURIComponent(t)+"/upload",Kt=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Vt(){return Te.join("")+Z}async function Xt(a,o=0){let d=a?n.viewportY():0,p=fe(Vt());if(n.reset(),!p){a||n.scrollToBottom();return}await n.write(p),a?n.scrollToLine(o+d):n.scrollToBottom()}function W(a){l?.readyState===WebSocket.OPEN&&l.send(JSON.stringify(a))}function Jt(a){let o;try{o=JSON.parse(a)}catch{R==="live"&&(Z+=a,n.write(fe(a)));return}if(o.type==="auth.required"){let d=localStorage.getItem("tmux-web-token");d?W({type:"auth.token",token:d}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(o.type==="attach_failed"&&typeof o.message=="string"){Be=!0,R="dead",n.reset(),n.write(`\r
4
- \x1B[31m`+fe(o.message)+`\x1B[0m\r
5
- `).then(()=>{Me();try{l?.close()}catch{}});return}if(o.type==="auth.ok"){o.token&&localStorage.setItem("tmux-web-token",o.token),oe=1e3,K(),W({type:"resize",cols:n.cols,rows:n.rows}),T();return}if(o.type==="auth.failed"){if(o.permanentLock||o.retryAfterMs&&o.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(o.message);return}return}if(o.type==="snapshot"&&typeof o.data=="string"){let d=Je(fe(o.data));Te=[d],Z="",Se=typeof o.lines=="number"?o.lines:s.terminal.initialLines,R="live",n.reset(),K(),W({type:"resize",cols:n.cols,rows:n.rows}),n.write(d).then(()=>n.scrollToBottom());return}if(o.type==="window_changed"&&typeof o.activeIndex=="number"){let d=new URL(location.href);d.searchParams.get("window")!==String(o.activeIndex)&&(d.searchParams.set("window",String(o.activeIndex)),history.replaceState(history.state,"",d)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:o.windows}));return}if(o.type==="history"&&typeof o.data=="string"){o.lines>0&&o.data?(Te.unshift(Je(o.data)),Se+=o.lines,Xt(!0,o.lines).finally(()=>{ie=!1})):ie=!1;return}if(o.type==="data"&&typeof o.data=="string"){let d=Je(fe(o.data));if(R==="connecting"){R="live",Z=d,n.write(d);return}R==="live"&&(Z+=d,n.write(d))}}let Be=!1;function rt(){if(Be)return;let a=Ot,o=localStorage.getItem("tmux-web-token");o&&(a+=(a.includes("?")?"&":"?")+"token="+encodeURIComponent(o)),a+=(a.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,l=new WebSocket(a),l.onopen=()=>{R="connecting",Se=0,ie=!1,Te=[],Z="",n.reset(),oe=1e3},l.onmessage=d=>{typeof d.data=="string"&&Jt(d.data)},l.onclose=()=>{j||(R="connecting",!Be&&setTimeout(()=>{oe=Math.min(oe*2,1e4),!j&&!Be&&rt()},oe))},l.onerror=()=>l?.close()}function Q(a){W({type:"input",data:a})}function K(){return n.fit()}function Me(){e.classList.remove("terminal-pending")}function T(){r&&cancelAnimationFrame(r),c&&clearTimeout(c),K(),r=requestAnimationFrame(()=>{r=0,K()&&Me()}),c=setTimeout(()=>{K()&&Me()},120)}function Gt(){T(),setTimeout(T,50),setTimeout(T,150),setTimeout(T,300)}function ct(a){return typeof a=="string"&&a.startsWith("image/")}function dt(a){return a?.files?.length?a.files[0]??null:null}function Zt(a){if(!a?.items)return null;for(let o=0;o<a.items.length;o++){let d=a.items[o];if(d?.kind==="file"&&ct(d.type))return d.getAsFile()}return null}async function Qt(a){let o=new FormData,d=a instanceof File&&a.name?a.name:"upload";o.append("file",a,d);let p=localStorage.getItem("tmux-web-token"),v={};p&&(v.Authorization="Bearer "+p);let A=await fetch(Wt,{method:"POST",body:o,headers:v});if(!A.ok){let pe="upload failed";try{let gt=await A.json();gt.error&&(pe=gt.error)}catch{}throw new Error(pe)}let V=await A.json();if(!V.path)throw new Error("no path in response");return V.path}async function Ke(a){try{let o=await Qt(a);Q(o)}catch{}}n.onData(a=>Q(a)),n.onResize(({cols:a,rows:o})=>W({type:"resize",cols:a,rows:o})),n.onScroll(()=>{R!=="live"||ie||!n.isNearScrollbackTop()||(ie=!0,W({type:"load_history",before:Se}))});let le=!1,re=!1,E=null,x=null,ce=document.createElement("div");ce.className="terminal-copy-banner",ce.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',ce.hidden=!0,e.appendChild(ce);let $=document.createElement("div");$.className="terminal-copy-banner terminal-copy-toast",$.textContent="Copied",$.hidden=!0,e.appendChild($);function ut(a,o){let d=e.querySelector(".xterm-screen, canvas"),p=(d&&d.getBoundingClientRect().width>0?d:e).getBoundingClientRect(),v=p.height>0&&n.rows>0?p.height/n.rows:18,A=p.width>0&&n.cols>0?p.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((o-p.top)/v))),col:Math.max(0,Math.min(n.cols-1,Math.floor((a-p.left)/A)))}}async function Ie(a){if(!a)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(a);return}}catch{}let o=document.createElement("textarea");o.value=a,o.style.position="fixed",o.style.opacity="0",o.style.pointerEvents="none",document.body.appendChild(o),o.focus(),o.select();try{document.execCommand("copy")}catch{}o.remove()}let de;function De(){$.hidden=!1,de&&clearTimeout(de),de=setTimeout(()=>{$.hidden=!0},1e3)}function ee(a){le=a,ce.hidden=!a,e.classList.toggle("terminal-copy-mode-active",a),a&&n.focus()}function pt(){ee(!le)}function en(a){j||a.button!==0||re||(le||a.shiftKey)&&(a.preventDefault(),a.stopPropagation(),re=!0,E=ut(a.clientX,a.clientY),x=E,n.selectCells(E.col,E.row,x.col,x.row),document.addEventListener("mousemove",Ve,!0),document.addEventListener("mouseup",Xe,!0))}function Ve(a){j||!re||!E||(a.preventDefault(),a.stopPropagation(),x=ut(a.clientX,a.clientY),n.selectCells(E.col,E.row,x.col,x.row))}function Xe(a){if(j||!re||!E||!x)return;a.preventDefault(),a.stopPropagation(),document.removeEventListener("mousemove",Ve,!0),document.removeEventListener("mouseup",Xe,!0),re=!1;let o=n.getCellsText(E.col,E.row,x.col,x.row);E=null,x=null,n.clearSelection(),ee(!1),o&&($.textContent="\u5DF2\u590D\u5236",Ie(o).then(De)),n.focus()}e.addEventListener("mousedown",en,!0),document.addEventListener("keydown",tn,!0);function tn(a){if(!(j||!n.isFocused()||a.defaultPrevented||a.isComposing)){if(le){if(a.key==="Escape"){a.preventDefault(),a.stopPropagation(),E=null,x=null,n.clearSelection(),ee(!1);return}if(a.key==="Enter"||(a.ctrlKey||a.metaKey)&&a.code==="KeyC"){a.preventDefault(),a.stopPropagation(),Ie(n.getScreenText()).then(De),ee(!1);return}}if(a.altKey&&a.code==="KeyC"&&!a.ctrlKey&&!a.metaKey){if(a.preventDefault(),a.stopPropagation(),E&&x){let o=n.getCellsText(E.col,E.row,x.col,x.row);E=null,x=null,n.clearSelection(),ee(!1),o&&($.textContent="Copied",Ie(o).then(De))}else{let o=n.getSelection();o?(n.clearSelection(),$.textContent="Copied",Ie(o).then(De)):pt()}return}if((a.ctrlKey||a.metaKey)&&a.code==="KeyV"){a.preventDefault(),a.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){let o=await navigator.clipboard.read();for(let d of o)for(let p of d.types)if(ct(p)){let v=await d.getType(p);await Ke(v);return}}}catch{}try{let o=await navigator.clipboard?.readText();o&&n.pasteText(ft(o))}catch{}})();return}}}let Fe=0;function ft(a){return a.split(`\r
1
+ var hn=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function Ge(e){return e.replace(/\x1b\[\?1049[hl]/g,"")}function me(e){return e.replace(hn,"")}var He;function vn(){return He||(document.querySelector("link[data-tmux-web-xterm-css]")?He=Promise.resolve():(He=new Promise(e=>{let t=document.createElement("link");t.rel="stylesheet",t.href="/assets/xterm.css",t.setAttribute("data-tmux-web-xterm-css",""),t.addEventListener("load",()=>e(),{once:!0}),t.addEventListener("error",()=>e(),{once:!0}),document.head.appendChild(t)}),He))}var gn=class _t{terminal;fitAddon;container;constructor(t,s,n){this.container=t,this.terminal=s,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(t)}static async create(t,s,n){let[{Terminal:a},{FitAddon:r}]=await Promise.all([import("./xterm-BXEES47M.js"),import("./addon-fit-D5N335P2.js"),vn()]),c=new a({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:s,convertEol:!1,smoothScrollDuration:120,theme:n});return new _t(t,c,new r)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(t){return new Promise(s=>this.terminal.write(t,s))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(t,s=!1){this.terminal.scrollToLine(Math.max(0,t),s)}scrollLines(t){let s=this.terminal.buffer?.active;this.terminal.scrollLines(t)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}fit(){let t=yn(this.container);if(t.width<=0||t.height<=0)return!1;let s=this.terminal._core?._renderService?.dimensions?.css?.cell;if(!s?.width||!s?.height)return this.fitAddon.fit(),!0;let n=s.width,a=s.height,r=this.terminal.element?.querySelector(".xterm-viewport"),c=r?Math.max(0,r.offsetWidth-r.clientWidth):0,o=Math.max(2,Math.floor((t.width-c-n/2)/n)),u=Math.max(2,Math.floor(t.height/a));return(o!==this.terminal.cols||u!==this.terminal.rows)&&this.terminal.resize(o,u),!0}focus(){this.terminal.focus()}pasteText(t){this.terminal.paste(t)}input(t){this.terminal.input(t,!1)}onData(t){this.terminal.onData(t),this.terminal.onBinary(t)}onResize(t){this.terminal.onResize(t)}onScroll(t){this.terminal.onScroll(t)}attachCustomKeyEventHandler(t){this.terminal.attachCustomKeyEventHandler(t)}isFocused(){let t=document.activeElement;return t?t===this.container||t===this.terminal.textarea||this.container.contains(t)||!!t.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(t,s){let n=this.terminal.buffer.active,[a,r]=t<=s?[t,s]:[s,t],c=n.viewportY,o=[];for(let u=a;u<=r;u++){let f=n.getLine(c+u);o.push(f?f.translateToString(!0):"")}return o.join(`
2
+ `)}selectRows(t,s){let n=this.terminal.buffer.active,[a,r]=t<=s?[t,s]:[s,t];this.terminal.selectLines(n.viewportY+a,n.viewportY+r)}selectCells(t,s,n,a){let r=this.terminal.buffer.active,c=Math.min(s,a),o=Math.max(s,a);if(c===o){let u=Math.min(t,n),f=Math.max(t,n);this.terminal.select(u,r.viewportY+c,f-u+1)}else this.terminal.selectLines(r.viewportY+c,r.viewportY+o)}getCellsText(t,s,n,a){let r=this.terminal.buffer.active,c=Math.min(s,a),o=Math.max(s,a),u=s<a?t:s>a?n:Math.min(t,n),f=s<a?n:s>a?t:Math.max(t,n),B=r.viewportY,L=[];for(let F=c;F<=o;F++){let M=r.getLine(B+F);if(!M){L.push("");continue}let b=F===c?u:0,O=F===o?f:this.terminal.cols-1,ae="";for(let ke=b;ke<=O;ke++){let W=M.getCell(ke);W&&(ae+=W.getChars())}L.push(ae.replace(/\s+$/,""))}return L.join(`
3
+ `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function yn(e){let t=e.getBoundingClientRect(),s=window.visualViewport;return s?{width:Math.min(t.width,s.width),height:Math.max(0,Math.min(t.height,s.height-Math.max(0,t.top)))}:t}function wn(e,t,s){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let n=await gn.create(e,s.scrollback,s.theme),a,r=0,c,o=null,u=0,f=0,B=.2,L=10,F=.95,M=.04,b=null,O=null;function ae(i){b||(b=document.createElement("div"),b.style.cssText=["position:absolute","left:0","width:40%","padding:10px 0","text-align:center","font:600 14px/1.4 system-ui, -apple-system, sans-serif","color:rgba(255,255,255,0.95)","background:rgba(20,30,50,0.55)","border:1px solid rgba(255,255,255,0.25)","border-radius:10px","pointer-events:none","opacity:0","transition:opacity 0.15s ease","z-index:6"].join(";"),e.appendChild(b)),b.textContent=i?"\u2191 \u4E0A\u7FFB\u4E00\u9875 (PgUp)":"\u2193 \u4E0B\u7FFB\u4E00\u9875 (PgDn)",b.style.top=i?"10%":"auto",b.style.bottom=i?"auto":"10%",b.style.opacity="1",O&&clearTimeout(O),O=setTimeout(()=>{b&&(b.style.opacity="0")},900)}function ke(){O&&clearTimeout(O),b&&(b.style.opacity="0")}function W(){u&&(cancelAnimationFrame(u),u=0),f=0}function Yt(i){if(W(),Math.abs(i)<B)return;f=Math.max(-L,Math.min(L,i));let l=()=>{if(U){u=0;return}let d=e.querySelector(".xterm-rows > div"),p=d?d.getBoundingClientRect().height:16,v=p>0?Math.round(f*16/p):f>0?1:-1;v===0&&(v=f>0?1:-1);let A=n.viewportY()-v,X=n.baseY(),fe=Math.max(0,Math.min(A,X));if(n.scrollToLine(fe,!0),f*=F,fe!==A){u=0;return}if(Math.abs(f)<M){u=0;return}u=requestAnimationFrame(l)};u=requestAnimationFrame(l)}let Se=0,$="connecting",Be=0,oe=!1,Te=[],Q="",U=!1,le=1e3,qt=location.protocol==="https:"?"wss:":"ws:",rt=s.wsBase||"/ws",Ot=qt+"//"+location.host+rt+"/"+encodeURIComponent(t),Wt=(rt.replace(/^\/ws/,"")||"")+"/api/session/"+encodeURIComponent(t)+"/upload",Kt=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Vt(){return Te.join("")+Q}async function Xt(i,l=0){let d=i?n.viewportY():0,p=me(Vt());if(n.reset(),!p){i||n.scrollToBottom();return}await n.write(p),i?n.scrollToLine(l+d):n.scrollToBottom()}function K(i){a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(i))}function Jt(i){let l;try{l=JSON.parse(i)}catch{$==="live"&&(Q+=i,n.write(me(i)));return}if(l.type==="auth.required"){let d=localStorage.getItem("tmux-web-token");d?K({type:"auth.token",token:d}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(l.type==="attach_failed"&&typeof l.message=="string"){Me=!0,$="dead",n.reset(),n.write(`\r
4
+ \x1B[31m`+me(l.message)+`\x1B[0m\r
5
+ `).then(()=>{Ie();try{a?.close()}catch{}});return}if(l.type==="auth.ok"){l.token&&localStorage.setItem("tmux-web-token",l.token),le=1e3,V(),K({type:"resize",cols:n.cols,rows:n.rows}),T();return}if(l.type==="auth.failed"){if(l.permanentLock||l.retryAfterMs&&l.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(l.message);return}return}if(l.type==="snapshot"&&typeof l.data=="string"){let d=Ge(me(l.data));Te=[d],Q="",Be=typeof l.lines=="number"?l.lines:s.terminal.initialLines,$="live",n.reset(),V(),K({type:"resize",cols:n.cols,rows:n.rows}),n.write(d).then(()=>n.scrollToBottom());return}if(l.type==="window_changed"&&typeof l.activeIndex=="number"){let d=new URL(location.href);d.searchParams.get("window")!==String(l.activeIndex)&&(d.searchParams.set("window",String(l.activeIndex)),history.replaceState(history.state,"",d)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:l.windows}));return}if(l.type==="history"&&typeof l.data=="string"){l.lines>0&&l.data?(Te.unshift(Ge(l.data)),Be+=l.lines,Xt(!0,l.lines).finally(()=>{oe=!1})):oe=!1;return}if(l.type==="data"&&typeof l.data=="string"){let d=Ge(me(l.data));if($==="connecting"){$="live",Q=d,n.write(d);return}$==="live"&&(Q+=d,n.write(d))}}let Me=!1;function ct(){if(Me)return;let i=Ot,l=localStorage.getItem("tmux-web-token");l&&(i+=(i.includes("?")?"&":"?")+"token="+encodeURIComponent(l)),i+=(i.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,a=new WebSocket(i),a.onopen=()=>{$="connecting",Be=0,oe=!1,Te=[],Q="",n.reset(),le=1e3},a.onmessage=d=>{typeof d.data=="string"&&Jt(d.data)},a.onclose=()=>{U||($="connecting",!Me&&setTimeout(()=>{le=Math.min(le*2,1e4),!U&&!Me&&ct()},le))},a.onerror=()=>a?.close()}function ee(i){K({type:"input",data:i})}function V(){return n.fit()}function Ie(){e.classList.remove("terminal-pending")}function T(){r&&cancelAnimationFrame(r),c&&clearTimeout(c),V(),r=requestAnimationFrame(()=>{r=0,V()&&Ie()}),c=setTimeout(()=>{V()&&Ie()},120)}function Gt(){T(),setTimeout(T,50),setTimeout(T,150),setTimeout(T,300)}function dt(i){return typeof i=="string"&&i.startsWith("image/")}function ut(i){return i?.files?.length?i.files[0]??null:null}function Zt(i){if(!i?.items)return null;for(let l=0;l<i.items.length;l++){let d=i.items[l];if(d?.kind==="file"&&dt(d.type))return d.getAsFile()}return null}async function Qt(i){let l=new FormData,d=i instanceof File&&i.name?i.name:"upload";l.append("file",i,d);let p=localStorage.getItem("tmux-web-token"),v={};p&&(v.Authorization="Bearer "+p);let A=await fetch(Wt,{method:"POST",body:l,headers:v});if(!A.ok){let fe="upload failed";try{let yt=await A.json();yt.error&&(fe=yt.error)}catch{}throw new Error(fe)}let X=await A.json();if(!X.path)throw new Error("no path in response");return X.path}async function Ve(i){try{let l=await Qt(i);ee(l)}catch{}}n.onData(i=>ee(i)),n.onResize(({cols:i,rows:l})=>K({type:"resize",cols:i,rows:l})),n.onScroll(()=>{$!=="live"||oe||!n.isNearScrollbackTop()||(oe=!0,K({type:"load_history",before:Be}))});let re=!1,ce=!1,E=null,x=null,de=document.createElement("div");de.className="terminal-copy-banner",de.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',de.hidden=!0,e.appendChild(de);let z=document.createElement("div");z.className="terminal-copy-banner terminal-copy-toast",z.textContent="Copied",z.hidden=!0,e.appendChild(z);function pt(i,l){let d=e.querySelector(".xterm-screen, canvas"),p=(d&&d.getBoundingClientRect().width>0?d:e).getBoundingClientRect(),v=p.height>0&&n.rows>0?p.height/n.rows:18,A=p.width>0&&n.cols>0?p.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((l-p.top)/v))),col:Math.max(0,Math.min(n.cols-1,Math.floor((i-p.left)/A)))}}async function De(i){if(!i)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(i);return}}catch{}let l=document.createElement("textarea");l.value=i,l.style.position="fixed",l.style.opacity="0",l.style.pointerEvents="none",document.body.appendChild(l),l.focus(),l.select();try{document.execCommand("copy")}catch{}l.remove()}let ue;function Fe(){z.hidden=!1,ue&&clearTimeout(ue),ue=setTimeout(()=>{z.hidden=!0},1e3)}function te(i){re=i,de.hidden=!i,e.classList.toggle("terminal-copy-mode-active",i),i&&n.focus()}function ft(){te(!re)}function en(i){U||i.button!==0||ce||(re||i.shiftKey)&&(i.preventDefault(),i.stopPropagation(),ce=!0,E=pt(i.clientX,i.clientY),x=E,n.selectCells(E.col,E.row,x.col,x.row),document.addEventListener("mousemove",Xe,!0),document.addEventListener("mouseup",Je,!0))}function Xe(i){U||!ce||!E||(i.preventDefault(),i.stopPropagation(),x=pt(i.clientX,i.clientY),n.selectCells(E.col,E.row,x.col,x.row))}function Je(i){if(U||!ce||!E||!x)return;i.preventDefault(),i.stopPropagation(),document.removeEventListener("mousemove",Xe,!0),document.removeEventListener("mouseup",Je,!0),ce=!1;let l=n.getCellsText(E.col,E.row,x.col,x.row);E=null,x=null,n.clearSelection(),te(!1),l&&(z.textContent="\u5DF2\u590D\u5236",De(l).then(Fe)),n.focus()}e.addEventListener("mousedown",en,!0),document.addEventListener("keydown",tn,!0);function tn(i){if(!(U||!n.isFocused()||i.defaultPrevented||i.isComposing)){if(re){if(i.key==="Escape"){i.preventDefault(),i.stopPropagation(),E=null,x=null,n.clearSelection(),te(!1);return}if(i.key==="Enter"||(i.ctrlKey||i.metaKey)&&i.code==="KeyC"){i.preventDefault(),i.stopPropagation(),De(n.getScreenText()).then(Fe),te(!1);return}}if(i.altKey&&i.code==="KeyC"&&!i.ctrlKey&&!i.metaKey){if(i.preventDefault(),i.stopPropagation(),E&&x){let l=n.getCellsText(E.col,E.row,x.col,x.row);E=null,x=null,n.clearSelection(),te(!1),l&&(z.textContent="Copied",De(l).then(Fe))}else{let l=n.getSelection();l?(n.clearSelection(),z.textContent="Copied",De(l).then(Fe)):ft()}return}if((i.ctrlKey||i.metaKey)&&i.code==="KeyV"){i.preventDefault(),i.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){let l=await navigator.clipboard.read();for(let d of l)for(let p of d.types)if(dt(p)){let v=await d.getType(p);await Ve(v);return}}}catch{}try{let l=await navigator.clipboard?.readText();l&&n.pasteText(mt(l))}catch{}})();return}}}let Ae=0;function mt(i){return i.split(`\r
6
6
  `).join(`
7
7
  `).split(`
8
- `).join("\r")}async function nn(a){let o=Zt(a.clipboardData);if(o){a.preventDefault(),a.stopPropagation();let v=Date.now();if(v-Fe<50)return;Fe=v,await Ke(o);return}let d=a.clipboardData?.getData("text/plain");if(!d)return;a.preventDefault(),a.stopPropagation();let p=Date.now();p-Fe<50||(Fe=p,n.pasteText(ft(d)))}let ue=0;function sn(a){a.preventDefault(),ue++,dt(a.dataTransfer)&&e.classList.add("terminal-drag-over")}function an(a){a.preventDefault(),a.dataTransfer&&(a.dataTransfer.dropEffect="copy")}function on(a){a.preventDefault(),ue--,ue<=0&&(ue=0,e.classList.remove("terminal-drag-over"))}async function ln(a){a.preventDefault(),ue=0,e.classList.remove("terminal-drag-over");let o=dt(a.dataTransfer);o&&await Ke(o)}function mt(a){!Kt||a.key!=="Escape"||le||a.defaultPrevented||a.repeat||a.metaKey||a.ctrlKey||a.altKey||n.isFocused()&&(a.preventDefault(),a.stopPropagation(),Q("\x1B"))}e.addEventListener("paste",nn),e.addEventListener("dragenter",sn),e.addEventListener("dragover",an),e.addEventListener("dragleave",on),e.addEventListener("drop",ln),document.addEventListener("keydown",mt,!0);function rn(a){if(a.touches.length!==1){i=null;return}let o=a.touches[0];if(!o)return;O();let d=e.getBoundingClientRect(),p=o.clientX-d.left<d.width*.4?"tui":"history",v=o.clientY-d.top<d.height*.5;i={startX:o.clientX,startY:o.clientY,lastX:o.clientX,lastY:o.clientY,lastT:performance.now(),velocity:0,scrolling:!1,zone:p,tuiUp:v,sent:!1},a.stopPropagation()}function cn(a){if(!i||a.touches.length!==1)return;let o=a.touches[0];if(!o)return;let d=o.clientY-i.startY,p=o.clientX-i.startX;if(!i.scrolling){if(Math.abs(d)<8||Math.abs(d)<Math.abs(p))return;i.scrolling=!0,ke=Date.now()+500}a.preventDefault(),a.stopPropagation();let v=performance.now(),A=o.clientY-i.lastY;if(i.zone==="tui"){i.sent||(i.sent=!0,Q(i.tuiUp?"\x1B[5~":"\x1B[6~"),ae(i.tuiUp)),i.lastX=o.clientX,i.lastY=o.clientY,i.lastT=v;return}let V=v-i.lastT;V>0&&(i.velocity=A/V),fn(-A),i.lastX=o.clientX,i.lastY=o.clientY,i.lastT=v}function dn(a){if(!i)return;let o=i.scrolling,d=i.zone,p=i.tuiUp,v=i.velocity;if(i=null,a.stopPropagation(),d==="tui"){o||(Q(p?"\x1B[5~":"\x1B[6~"),ae(p),ke=Date.now()+500,a.preventDefault());return}if(!o){n.focus();return}ke=Date.now()+500,a.preventDefault(),v&&Yt(v)}function un(a){i=null,O(),a.stopPropagation()}function pn(a){a.pointerType==="touch"&&Date.now()<ke&&(a.preventDefault(),a.stopPropagation())}function fn(a){let o=e.querySelector(".xterm-rows > div"),d=o?o.getBoundingClientRect().height:16,p=d>0?Math.round(a/d):a>0?1:-1;p===0&&(p=a>0?1:-1),n.scrollLines(p)}e.addEventListener("touchstart",rn,{passive:!0,capture:!0}),e.addEventListener("touchmove",cn,{passive:!1,capture:!0}),e.addEventListener("touchend",dn,{passive:!1,capture:!0}),e.addEventListener("touchcancel",un,{passive:!0,capture:!0}),e.addEventListener("pointerup",pn,!0);function ht(){T()}window.addEventListener("resize",ht),window.visualViewport?.addEventListener("resize",T),window.visualViewport?.addEventListener("scroll",T);let vt=new ResizeObserver(()=>T());vt.observe(e),document.fonts?.ready.then(()=>{T(),setTimeout(T,50),setTimeout(T,200)}),e.addEventListener("focusin",Gt,!0);async function mn(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(a=>setTimeout(a,1e3))])}catch{}}return requestAnimationFrame(()=>{K()&&Me(),(async()=>(await mn(),K()&&W({type:"resize",cols:n.cols,rows:n.rows}),rt(),T()))()}),{destroy(){if(j=!0,O(),ee(!1),de&&clearTimeout(de),document.removeEventListener("mousemove",Ve,!0),document.removeEventListener("mouseup",Xe,!0),l){try{l.close(1e3,"session switch")}catch{}l=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",ht),vt.disconnect(),document.removeEventListener("keydown",mt,!0)},focus(){n.focus()},sendInput(a){Q(a)},toggleCopyMode(){pt()}}})()}var me=window.__TMUX_WEB_SHELL__,g=null,y=null,he=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,B=he;window.__tmuxWebScopeAgent=he;var Ge="sessions",U="",He="",Pe="",yt="";function C(e){return B?"/a/"+encodeURIComponent(B)+e:e}var m=document.getElementById("sidebar-content"),X=document.getElementById("main-placeholder"),I=document.getElementById("terminal-container"),ve=document.getElementById("file-editor"),bn=document.getElementById("fe-path"),H=document.getElementById("fe-status"),ge=document.getElementById("fe-content"),J=document.getElementById("fe-save"),En=document.getElementById("fe-delete"),Ln=document.getElementById("fe-back"),wt=document.getElementById("fe-new-name"),xn=document.getElementById("fe-new-btn"),Ze=document.getElementById("settings-backdrop"),bt=document.getElementById("settings-popover"),Et=document.querySelector(".sidebar");function Cn(){return window.matchMedia("(max-width: 640px)").matches}function Qe(){Cn()&&Et.classList.add("collapsed")}function Lt(){Et.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{Lt(),xt("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{Lt(),xt("files")});function xt(e){Ge=e,document.querySelectorAll(".mode-btn").forEach(s=>s.classList.remove("active"));let t=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");t&&t.classList.add("active"),e==="sessions"?(et="",_()):$n()}var et="";async function _(){if(Ge!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents,tombstones:t.tombstones});if(s===et)return;et=s,Mn(t)}catch{m.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}let e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>{let t=window.__openNewSessionModal;typeof t=="function"?t():document.getElementById("new-session-modal")?.classList.add("open")}),ot()}var Ct="tmux-web-sidebar-group-collapsed";function kt(){try{return new Set(JSON.parse(localStorage.getItem(Ct)||"[]"))}catch{return new Set}}function kn(e){try{localStorage.setItem(Ct,JSON.stringify([...e]))}catch{}}function Sn(e,t,s){if(!e)return"\u2026";let n=s&&(e===s||e.startsWith(s+"/"))?"~"+e.slice(s.length):e,l=n.split("/").filter(Boolean);if(l.length===0)return e;for(let r=1;r<=l.length;r++){let c=l.slice(-r).join("/");if(!t.some(i=>!i||i===e?!1:(s&&(i===s||i.startsWith(s+"/"))?"~"+i.slice(s.length):i).split("/").filter(Boolean).slice(-r).join("/")===c))return c}return n}function St(e,t,s,n=!0){let l=new Map;for(let i of e){let u=i.path||"";l.has(u)||l.set(u,[]),l.get(u).push(i)}let r=[...l.keys()],c=kt();for(let[i,u]of l){let f=Sn(i,r,t),S=c.has(i),L=document.createElement("div");L.className="session-group-header"+(S?" collapsed":""),L.title=i||"No working directory",L.innerHTML=`<span class="sg-folder">&#128193;</span><span class="sg-label">${h(f)}</span>`,L.addEventListener("click",()=>{let M=kt(),b=L.nextElementSibling;M.has(i)?(M.delete(i),L.classList.remove("collapsed"),b?.classList.remove("collapsed")):(M.add(i),L.classList.add("collapsed"),b?.classList.add("collapsed")),kn(M)});let F=document.createElement("div");F.className="session-group-body"+(S?" collapsed":"");for(let M of u)F.appendChild(s?Tn(M,s,n):Bn(M));m.appendChild(L),m.appendChild(F)}}function Tn(e,t,s){let n=document.createElement("div");return n.className="session-item"+(e.name===y&&B===t?" active":"")+(s?"":" session-offline"),n.setAttribute("data-session",e.name),n.setAttribute("data-agent",t),n.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${e.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
9
- <span>${h(e.name)}</span>${s?"":'<span class="meta">offline</span>'}`,s&&n.addEventListener("click",l=>{l.target.closest(".session-edit-btn")||ye(e.name,t)}),n}function Bn(e){let t=document.createElement("div");t.className="session-item"+(e.name===y&&!B?" active":""),t.setAttribute("data-session",e.name),t.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${e.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
8
+ `).join("\r")}async function nn(i){let l=Zt(i.clipboardData);if(l){i.preventDefault(),i.stopPropagation();let v=Date.now();if(v-Ae<50)return;Ae=v,await Ve(l);return}let d=i.clipboardData?.getData("text/plain");if(!d)return;i.preventDefault(),i.stopPropagation();let p=Date.now();p-Ae<50||(Ae=p,n.pasteText(mt(d)))}let pe=0;function sn(i){i.preventDefault(),pe++,ut(i.dataTransfer)&&e.classList.add("terminal-drag-over")}function an(i){i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="copy")}function on(i){i.preventDefault(),pe--,pe<=0&&(pe=0,e.classList.remove("terminal-drag-over"))}async function ln(i){i.preventDefault(),pe=0,e.classList.remove("terminal-drag-over");let l=ut(i.dataTransfer);l&&await Ve(l)}function ht(i){!Kt||i.key!=="Escape"||re||i.defaultPrevented||i.repeat||i.metaKey||i.ctrlKey||i.altKey||n.isFocused()&&(i.preventDefault(),i.stopPropagation(),ee("\x1B"))}e.addEventListener("paste",nn),e.addEventListener("dragenter",sn),e.addEventListener("dragover",an),e.addEventListener("dragleave",on),e.addEventListener("drop",ln),document.addEventListener("keydown",ht,!0);function rn(i){if(i.touches.length!==1){o=null;return}let l=i.touches[0];if(!l)return;W();let d=e.getBoundingClientRect(),p=l.clientX-d.left<d.width*.4?"tui":"history",v=l.clientY-d.top<d.height*.5;o={startX:l.clientX,startY:l.clientY,lastX:l.clientX,lastY:l.clientY,lastT:performance.now(),velocity:0,scrolling:!1,zone:p,tuiUp:v,sent:!1},i.stopPropagation()}function cn(i){if(!o||i.touches.length!==1)return;let l=i.touches[0];if(!l)return;let d=l.clientY-o.startY,p=l.clientX-o.startX;if(!o.scrolling){if(Math.abs(d)<8||Math.abs(d)<Math.abs(p))return;o.scrolling=!0,Se=Date.now()+500}i.preventDefault(),i.stopPropagation();let v=performance.now(),A=l.clientY-o.lastY;if(o.zone==="tui"){o.sent||(o.sent=!0,ee(o.tuiUp?"\x1B[5~":"\x1B[6~"),ae(o.tuiUp)),o.lastX=l.clientX,o.lastY=l.clientY,o.lastT=v;return}let X=v-o.lastT;X>0&&(o.velocity=A/X),fn(-A),o.lastX=l.clientX,o.lastY=l.clientY,o.lastT=v}function dn(i){if(!o)return;let l=o.scrolling,d=o.zone,p=o.tuiUp,v=o.velocity;if(o=null,i.stopPropagation(),d==="tui"){l||(ee(p?"\x1B[5~":"\x1B[6~"),ae(p),Se=Date.now()+500,i.preventDefault());return}if(!l){n.focus();return}Se=Date.now()+500,i.preventDefault(),v&&Yt(v)}function un(i){o=null,W(),i.stopPropagation()}function pn(i){i.pointerType==="touch"&&Date.now()<Se&&(i.preventDefault(),i.stopPropagation())}function fn(i){let l=e.querySelector(".xterm-rows > div"),d=l?l.getBoundingClientRect().height:16,p=d>0?Math.round(i/d):i>0?1:-1;p===0&&(p=i>0?1:-1),n.scrollLines(p)}e.addEventListener("touchstart",rn,{passive:!0,capture:!0}),e.addEventListener("touchmove",cn,{passive:!1,capture:!0}),e.addEventListener("touchend",dn,{passive:!1,capture:!0}),e.addEventListener("touchcancel",un,{passive:!0,capture:!0}),e.addEventListener("pointerup",pn,!0);function vt(){T()}window.addEventListener("resize",vt),window.visualViewport?.addEventListener("resize",T),window.visualViewport?.addEventListener("scroll",T);let gt=new ResizeObserver(()=>T());gt.observe(e),document.fonts?.ready.then(()=>{T(),setTimeout(T,50),setTimeout(T,200)}),e.addEventListener("focusin",Gt,!0);async function mn(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(i=>setTimeout(i,1e3))])}catch{}}return requestAnimationFrame(()=>{V()&&Ie(),(async()=>(await mn(),V()&&K({type:"resize",cols:n.cols,rows:n.rows}),ct(),T()))()}),{destroy(){if(U=!0,W(),te(!1),ue&&clearTimeout(ue),document.removeEventListener("mousemove",Xe,!0),document.removeEventListener("mouseup",Je,!0),a){try{a.close(1e3,"session switch")}catch{}a=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",vt),gt.disconnect(),document.removeEventListener("keydown",ht,!0)},focus(){n.focus()},sendInput(i){ee(i)},toggleCopyMode(){ft()}}})()}var he=window.__TMUX_WEB_SHELL__,g=null,y=null,ve=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,C=ve;window.__tmuxWebScopeAgent=ve;var Ze="sessions",_="",Ne="",Re="",wt="";function k(e){return C?"/a/"+encodeURIComponent(C)+e:e}var m=document.getElementById("sidebar-content"),J=document.getElementById("main-placeholder"),I=document.getElementById("terminal-container"),ge=document.getElementById("file-editor"),bn=document.getElementById("fe-path"),H=document.getElementById("fe-status"),ye=document.getElementById("fe-content"),G=document.getElementById("fe-save"),En=document.getElementById("fe-delete"),Ln=document.getElementById("fe-back"),bt=document.getElementById("fe-new-name"),xn=document.getElementById("fe-new-btn"),Qe=document.getElementById("settings-backdrop"),Et=document.getElementById("settings-popover"),Lt=document.querySelector(".sidebar");function Cn(){return window.matchMedia("(max-width: 640px)").matches}function et(){Cn()&&Lt.classList.add("collapsed")}function xt(){Lt.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{xt(),Ct("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{xt(),Ct("files")});function Ct(e){Ze=e,document.querySelectorAll(".mode-btn").forEach(s=>s.classList.remove("active"));let t=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");t&&t.classList.add("active"),e==="sessions"?(tt="",Y()):$n()}var tt="";async function Y(){if(Ze!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents,tombstones:t.tombstones});if(s===tt)return;tt=s,Mn(t)}catch{m.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}let e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>{let t=window.__openNewSessionModal;typeof t=="function"?t():document.getElementById("new-session-modal")?.classList.add("open")}),lt()}var kt="tmux-web-sidebar-group-collapsed";function St(){try{return new Set(JSON.parse(localStorage.getItem(kt)||"[]"))}catch{return new Set}}function kn(e){try{localStorage.setItem(kt,JSON.stringify([...e]))}catch{}}function Sn(e,t,s){if(!e)return"\u2026";let n=s&&(e===s||e.startsWith(s+"/"))?"~"+e.slice(s.length):e,a=n.split("/").filter(Boolean);if(a.length===0)return e;for(let r=1;r<=a.length;r++){let c=a.slice(-r).join("/");if(!t.some(o=>!o||o===e?!1:(s&&(o===s||o.startsWith(s+"/"))?"~"+o.slice(s.length):o).split("/").filter(Boolean).slice(-r).join("/")===c))return c}return n}function Bt(e,t,s,n=!0){let a=new Map;for(let o of e){let u=o.path||"";a.has(u)||a.set(u,[]),a.get(u).push(o)}let r=[...a.keys()],c=St();for(let[o,u]of a){let f=Sn(o,r,t),B=c.has(o),L=document.createElement("div");L.className="session-group-header"+(B?" collapsed":""),L.title=o||"No working directory",L.innerHTML=`<span class="sg-folder">&#128193;</span><span class="sg-label">${h(f)}</span>`,L.addEventListener("click",()=>{let M=St(),b=L.nextElementSibling;M.has(o)?(M.delete(o),L.classList.remove("collapsed"),b?.classList.remove("collapsed")):(M.add(o),L.classList.add("collapsed"),b?.classList.add("collapsed")),kn(M)});let F=document.createElement("div");F.className="session-group-body"+(B?" collapsed":"");for(let M of u)F.appendChild(s?Bn(M,s,n):Tn(M));m.appendChild(L),m.appendChild(F)}}function Bn(e,t,s){let n=document.createElement("div");n.className="session-item"+(e.name===y&&C===t?" active":"")+(s?"":" session-offline"),n.setAttribute("data-session",e.name),n.setAttribute("data-agent",t),n.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${e.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
9
+ <span>${h(e.name)}</span>${s?"":'<span class="meta">offline</span>'}
10
+ <button class="session-edit-btn" data-session="${h(e.name)}" title="Edit session"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>`,s&&n.addEventListener("click",r=>{r.target.closest(".session-edit-btn")||we(e.name,t)});let a=n.querySelector(".session-edit-btn");return a&&a.addEventListener("click",r=>{r.stopPropagation(),Oe(e.name,a,{agentId:t})}),n}function Tn(e){let t=document.createElement("div");t.className="session-item"+(e.name===y&&!C?" active":""),t.setAttribute("data-session",e.name),t.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${e.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
10
11
  <span>${h(e.name)}</span>
11
12
  <button class="session-edit-btn" data-session="${h(e.name)}" title="Edit session"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>
12
- `,t.addEventListener("click",n=>{n.target.closest(".session-edit-btn")||ye(e.name)});let s=t.querySelector(".session-edit-btn");return s&&s.addEventListener("click",n=>{n.stopPropagation(),Rt(e.name,s)}),t}function Mn(e){m.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';let t=e.recent||[],s=document.createElement("div");s.className="sidebar-section-label"+(he?" clickable":""),s.textContent=he?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",he&&(s.title="Back to hub",s.addEventListener("click",()=>{window.location.href="/"})),m.appendChild(s),St(t,e.home);let n=e.agents||[];for(let r of n){if(!r.sessions||r.sessions.length===0)continue;let c=r.agentId===B,i=document.createElement("div");i.className="sidebar-section-label machine-label"+(r.online?"":" agent-offline-label")+(!c&&r.online?" clickable":""),i.textContent=r.agentName+(r.online?"":" (offline)"),!c&&r.online&&(i.title="\u6253\u5F00 "+r.agentName,i.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(r.agentId)+"/"})),m.appendChild(i),St(r.sessions,e.home,r.agentId,r.online)}let l=e.tombstones||[];if(l.length>0){let r=document.createElement("div");r.className="sidebar-section-label tombstone-label",r.textContent="\u5931\u6548\u4F1A\u8BDD",m.appendChild(r);for(let c of l){let i=document.createElement("div");i.className="session-item session-tombstone",i.setAttribute("data-session",c.name),c.agentId&&i.setAttribute("data-agent",c.agentId);let u=c.agentId?c.agentOnline?" (agent)":" (agent \u79BB\u7EBF)":"";i.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"></svg>
13
+ `,t.addEventListener("click",n=>{n.target.closest(".session-edit-btn")||we(e.name)});let s=t.querySelector(".session-edit-btn");return s&&s.addEventListener("click",n=>{n.stopPropagation(),Oe(e.name,s)}),t}function Mn(e){m.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';let t=e.recent||[],s=document.createElement("div");s.className="sidebar-section-label"+(ve?" clickable":""),s.textContent=ve?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",ve&&(s.title="Back to hub",s.addEventListener("click",()=>{window.location.href="/"})),m.appendChild(s),Bt(t,e.home);let n=e.agents||[];for(let r of n){if(!r.sessions||r.sessions.length===0)continue;let c=r.agentId===C,o=document.createElement("div");o.className="sidebar-section-label machine-label"+(r.online?"":" agent-offline-label")+(!c&&r.online?" clickable":""),o.textContent=r.agentName+(r.online?"":" (offline)"),!c&&r.online&&(o.title="\u6253\u5F00 "+r.agentName,o.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(r.agentId)+"/"})),m.appendChild(o),Bt(r.sessions,e.home,r.agentId,r.online)}let a=e.tombstones||[];if(a.length>0){let r=document.createElement("div");r.className="sidebar-section-label tombstone-label",r.textContent="\u5931\u6548\u4F1A\u8BDD",m.appendChild(r);for(let c of a){let o=document.createElement("div");o.className="session-item session-tombstone",o.setAttribute("data-session",c.name),c.agentId&&o.setAttribute("data-agent",c.agentId);let u=c.agentId?c.agentOnline?" (agent)":" (agent \u79BB\u7EBF)":"";o.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"></svg>
13
14
  <span>${h(c.name)}</span><span class="meta">\u5931\u6548${u}</span>
14
- <button class="session-edit-btn" data-session="${h(c.name)}" title="\u6062\u590D\u4F1A\u8BDD"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>`;let f=i.querySelector(".session-edit-btn");f&&f.addEventListener("click",S=>{S.stopPropagation(),Rt(c.name,f,{tombstone:!0,agentId:c.agentId})}),m.appendChild(i)}}}function h(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function ye(e,t){if(y===e&&g&&B===(t||null))return;ve.style.display="none",X.style.display="none",I.style.display="",I.classList.add("terminal-pending"),Qe(),g&&(Ye(),g.destroy(),g=null),y=e,B=t||null,window.__tmuxWebScopeAgent=B,window.__tmuxWebCurrentSession=y,Gn(e,t);let s=it(e,t);jt.set(s,Date.now()+Xn);let n=se.get(s);if(n&&n.state==="working"){n.state="idle",n.doneUntil=void 0,n.unread=!1;let l=m.querySelector(t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])');l&&We(l,s,n)}for(let l of m.querySelectorAll(".session-item"))l.classList.toggle("active",l.getAttribute("data-session")===e&&(l.getAttribute("data-agent")||null)===B);try{g=await wn(I,e,{terminal:me.terminal,scrollback:me.scrollback,theme:me.theme,wsBase:B?"/ws/a/"+encodeURIComponent(B):me.wsBase||"/ws"}),Nt()}catch(l){console.error("[shell] terminal init failed:",l);let r=l&&typeof l=="object"&&"message"in l?l.message:String(l);I.textContent="Failed to open terminal for "+e+": "+r,I.classList.remove("terminal-pending")}}var Ne=[],w=null,Tt=!1;function In(e){if(!w||!w.files.length)return null;let t=w.repoRoot;if(!t||!e.startsWith(t))return null;let s=e.slice(t.length+1);for(let n of w.files)if(n.path===s)return n.status;return null}async function Dn(e){Tt=!0;try{let t=await fetch(C("/api/git/status?path="+encodeURIComponent(e)));t.ok?w=await t.json():w=null}catch{w=null}finally{Tt=!1}}function Fn(){if(!w||!w.branch)return"";let{branch:e,linesAdded:t,linesRemoved:s}=w,n=`<div class="sidebar-git"><div class="git-branch-badge">
15
+ <button class="session-edit-btn" data-session="${h(c.name)}" title="\u6062\u590D\u4F1A\u8BDD"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>`,o.title="\u5931\u6548\u4F1A\u8BDD\uFF1A\u70B9\u51FB\u7BA1\u7406\uFF08\u91CD\u5EFA/\u91CD\u547D\u540D/\u5220\u9664\uFF09",o.addEventListener("click",()=>{Oe(c.name,o,{tombstone:!0,agentId:c.agentId})});let f=o.querySelector(".session-edit-btn");f&&f.addEventListener("click",B=>{B.stopPropagation(),Oe(c.name,f,{tombstone:!0,agentId:c.agentId})}),m.appendChild(o)}}}function h(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function we(e,t){if(y===e&&g&&C===(t||null))return;ge.style.display="none",J.style.display="none",I.style.display="",I.classList.add("terminal-pending"),et(),g&&(qe(),g.destroy(),g=null),y=e,C=t||null,window.__tmuxWebScopeAgent=C,window.__tmuxWebCurrentSession=y,Gn(e,t);let s=ot(e,t);jt.set(s,Date.now()+Xn);let n=ie.get(s);if(n&&n.state==="working"){n.state="idle",n.doneUntil=void 0,n.unread=!1;let a=m.querySelector(t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])');a&&Ke(a,s,n)}for(let a of m.querySelectorAll(".session-item"))a.classList.toggle("active",a.getAttribute("data-session")===e&&(a.getAttribute("data-agent")||null)===C);try{g=await wn(I,e,{terminal:he.terminal,scrollback:he.scrollback,theme:he.theme,wsBase:C?"/ws/a/"+encodeURIComponent(C):he.wsBase||"/ws"}),Pt()}catch(a){console.error("[shell] terminal init failed:",a);let r=a&&typeof a=="object"&&"message"in a?a.message:String(a);I.textContent="Failed to open terminal for "+e+": "+r,I.classList.remove("terminal-pending")}}var Pe=[],w=null,Tt=!1;function In(e){if(!w||!w.files.length)return null;let t=w.repoRoot;if(!t||!e.startsWith(t))return null;let s=e.slice(t.length+1);for(let n of w.files)if(n.path===s)return n.status;return null}async function Dn(e){Tt=!0;try{let t=await fetch(k("/api/git/status?path="+encodeURIComponent(e)));t.ok?w=await t.json():w=null}catch{w=null}finally{Tt=!1}}function Fn(){if(!w||!w.branch)return"";let{branch:e,linesAdded:t,linesRemoved:s}=w,n=`<div class="sidebar-git"><div class="git-branch-badge">
15
16
  <svg viewBox="0 0 16 16" fill="currentColor"><path d="M11.63 1.22a.75.75 0 00-1.06 0L5.99 5.8 4.12 3.93a.75.75 0 10-1.06 1.06L4.93 6.87A3.5 3.5 0 003 10.09v3.16a.75.75 0 001 0v-3.16a2.5 2.5 0 012.5-2.5h.27l-1.06 1.06a.75.75 0 001.06 1.06l2.37-2.38a.75.75 0 000-1.06L7.59 5.27l4.04-4.05a.75.75 0 000-1.06L11.63 1.22zM3.25 13.94a.75.75 0 01-.75-.75v-.69a.75.75 0 011.5 0v.69c0 .414-.336.75-.75.75z"/></svg>
16
- ${h(e)}</div>`;return(t>0||s>0)&&(n+=`<div class="git-diff-stats">+<span class="add">${t}</span> <span class="del">-${s}</span></div>`),n+"</div>"}m.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&te&&w&&(e.stopPropagation(),Ft())});var we=document.getElementById("header-git"),Bt=document.getElementById("git-diff-view"),Mt=document.getElementById("gd-path"),Re=document.getElementById("gd-status"),$e=document.getElementById("gd-content"),An=document.getElementById("gd-back"),te=null;function be(e){if(!e||!e.branch){we.style.display="none",te=null;return}te=e.repoRoot;let{branch:t,linesAdded:s,linesRemoved:n}=e,l=`<span class="branch">${h(t)}</span>`;(s>0||n>0)&&(l+=`<span class="sep">\xB7</span>+<span class="diff-add">${s}</span> <span class="diff-del">-${n}</span>`),we.innerHTML=l,we.style.display="block"}we.addEventListener("click",e=>{te&&w&&(e.stopPropagation(),Ft())});var k=document.getElementById("git-popover"),ze=document.getElementById("git-popover-backdrop");function tt(){let e=we.getBoundingClientRect();k.style.top=e.bottom+4+"px",k.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function It(){let e=te,t=document.getElementById("git-popover-browse");t&&t.addEventListener("click",()=>{if(Ue(),e){Ge="files",document.querySelectorAll(".mode-btn").forEach(n=>n.classList.remove("active"));let s=document.getElementById("mode-files");s&&s.classList.add("active"),Y(e)}})}var Dt="";function Ft(){if(!w)return;let e=w.files||[];if(!e.length)k.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
17
- <div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>`;else{let t=`<div class="git-popover-header">${e.length} file${e.length>1?"s":""} changed</div>`;for(let s=0;s<e.length;s++){let n=e[s],l=n.additions||0,r=n.deletions||0,c="";switch(n.status){case"M":c='<span class="git-file-status M">M</span>';break;case"A":c='<span class="git-file-status A">A</span>';break;case"D":c='<span class="git-file-status D">D</span>';break;case"?":c='<span class="git-file-status ?">?</span>';break;case"R":c='<span class="git-file-status R">R</span>';break}t+=`<div class="git-popover-item" data-idx="${s}">
17
+ ${h(e)}</div>`;return(t>0||s>0)&&(n+=`<div class="git-diff-stats">+<span class="add">${t}</span> <span class="del">-${s}</span></div>`),n+"</div>"}m.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&ne&&w&&(e.stopPropagation(),At())});var be=document.getElementById("header-git"),Mt=document.getElementById("git-diff-view"),It=document.getElementById("gd-path"),$e=document.getElementById("gd-status"),ze=document.getElementById("gd-content"),An=document.getElementById("gd-back"),ne=null;function Ee(e){if(!e||!e.branch){be.style.display="none",ne=null;return}ne=e.repoRoot;let{branch:t,linesAdded:s,linesRemoved:n}=e,a=`<span class="branch">${h(t)}</span>`;(s>0||n>0)&&(a+=`<span class="sep">\xB7</span>+<span class="diff-add">${s}</span> <span class="diff-del">-${n}</span>`),be.innerHTML=a,be.style.display="block"}be.addEventListener("click",e=>{ne&&w&&(e.stopPropagation(),At())});var S=document.getElementById("git-popover"),je=document.getElementById("git-popover-backdrop");function nt(){let e=be.getBoundingClientRect();S.style.top=e.bottom+4+"px",S.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function Dt(){let e=ne,t=document.getElementById("git-popover-browse");t&&t.addEventListener("click",()=>{if(_e(),e){Ze="files",document.querySelectorAll(".mode-btn").forEach(n=>n.classList.remove("active"));let s=document.getElementById("mode-files");s&&s.classList.add("active"),q(e)}})}var Ft="";function At(){if(!w)return;let e=w.files||[];if(!e.length)S.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
18
+ <div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>`;else{let t=`<div class="git-popover-header">${e.length} file${e.length>1?"s":""} changed</div>`;for(let s=0;s<e.length;s++){let n=e[s],a=n.additions||0,r=n.deletions||0,c="";switch(n.status){case"M":c='<span class="git-file-status M">M</span>';break;case"A":c='<span class="git-file-status A">A</span>';break;case"D":c='<span class="git-file-status D">D</span>';break;case"?":c='<span class="git-file-status ?">?</span>';break;case"R":c='<span class="git-file-status R">R</span>';break}t+=`<div class="git-popover-item" data-idx="${s}">
18
19
  ${c}<span class="file-path">${h(n.path)}</span>
19
- <span class="file-add">${l>0?"+"+l:""}</span>
20
+ <span class="file-add">${a>0?"+"+a:""}</span>
20
21
  <span class="file-del">${r>0?"-"+r:""}</span>
21
- </div>`}t+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',Dt=t,k.innerHTML=t,k.querySelectorAll(".git-popover-item").forEach(s=>{let n=parseInt(s.dataset.idx||"0",10),l=e[n];!l||l.status==="D"||(s.classList.add("clickable"),s.style.cursor="pointer",s.addEventListener("click",()=>Ht(l.path)))})}tt(),k.classList.add("open"),ze.classList.add("open"),It()}function Hn(){return window.innerWidth>=1024}function At(e,t){let s=(e+(t&&e?`
22
+ </div>`}t+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',Ft=t,S.innerHTML=t,S.querySelectorAll(".git-popover-item").forEach(s=>{let n=parseInt(s.dataset.idx||"0",10),a=e[n];!a||a.status==="D"||(s.classList.add("clickable"),s.style.cursor="pointer",s.addEventListener("click",()=>Nt(a.path)))})}nt(),S.classList.add("open"),je.classList.add("open"),Dt()}function Hn(){return window.innerWidth>=1024}function Ht(e,t){let s=(e+(t&&e?`
22
23
  `:"")+t).split(`
23
- `),n="",l=0,r=0;for(let c of s){let i=c;if(i.startsWith("@@")){let u=i.match(/@@\s+-(\d+)[^+]*\+(\d+)/);u&&(l=parseInt(u[1],10)-1,r=parseInt(u[2],10)-1),n+=`<div class="diff-line hunk"><span class="ln-body">${h(i)}</span></div>`;continue}if(i.startsWith("diff --git")||i.startsWith("index ")||i.startsWith("--- ")||i.startsWith("+++ ")||i.startsWith("new file")||i.startsWith("deleted file")){i.startsWith("diff --git")&&(n+=`<div class="diff-line header"><span class="ln-body">${h(i)}</span></div>`);continue}if(i.startsWith("+"))r++,n+=`<div class="diff-line add"><span class="ln-no">${r}</span><span class="ln-body">${h(i)}</span></div>`;else if(i.startsWith("-"))l++,n+=`<div class="diff-line del"><span class="ln-no">${l}</span><span class="ln-body">${h(i)}</span></div>`;else if(i.startsWith("\\"))n+=`<div class="diff-line"><span class="ln-body">${h(i)}</span></div>`;else{if(!i&&!l&&!r)continue;l++,r++,n+=`<div class="diff-line"><span class="ln-no">${l}</span><span class="ln-no" style="margin-right:12px">${r}</span><span class="ln-body">${h(i)}</span></div>`}}return{html:n,lineCount:s.length}}var je=null;async function Ht(e){let t=te;if(t)if(Ue(),Hn()){I.style.display="none",g&&(Ye(),g.destroy(),g=null,je=y,y=null),be(null),ve.style.display="none",X.style.display="none",Bt.style.display="flex",Mt.textContent=e,Re.textContent="Loading\u2026",$e.innerHTML="";try{let s=await fetch(C("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let n=await s.json();Nn(e,n.diff,n.stagedDiff)}catch(s){let n=s instanceof Error?s.message:String(s);Re.textContent="Error",$e.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${h(n)}</div>`}}else{k.innerHTML=`<div class="git-diff-view"><div class="diff-header">
24
+ `),n="",a=0,r=0;for(let c of s){let o=c;if(o.startsWith("@@")){let u=o.match(/@@\s+-(\d+)[^+]*\+(\d+)/);u&&(a=parseInt(u[1],10)-1,r=parseInt(u[2],10)-1),n+=`<div class="diff-line hunk"><span class="ln-body">${h(o)}</span></div>`;continue}if(o.startsWith("diff --git")||o.startsWith("index ")||o.startsWith("--- ")||o.startsWith("+++ ")||o.startsWith("new file")||o.startsWith("deleted file")){o.startsWith("diff --git")&&(n+=`<div class="diff-line header"><span class="ln-body">${h(o)}</span></div>`);continue}if(o.startsWith("+"))r++,n+=`<div class="diff-line add"><span class="ln-no">${r}</span><span class="ln-body">${h(o)}</span></div>`;else if(o.startsWith("-"))a++,n+=`<div class="diff-line del"><span class="ln-no">${a}</span><span class="ln-body">${h(o)}</span></div>`;else if(o.startsWith("\\"))n+=`<div class="diff-line"><span class="ln-body">${h(o)}</span></div>`;else{if(!o&&!a&&!r)continue;a++,r++,n+=`<div class="diff-line"><span class="ln-no">${a}</span><span class="ln-no" style="margin-right:12px">${r}</span><span class="ln-body">${h(o)}</span></div>`}}return{html:n,lineCount:s.length}}var Ue=null;async function Nt(e){let t=ne;if(t)if(_e(),Hn()){I.style.display="none",g&&(qe(),g.destroy(),g=null,Ue=y,y=null),Ee(null),ge.style.display="none",J.style.display="none",Mt.style.display="flex",It.textContent=e,$e.textContent="Loading\u2026",ze.innerHTML="";try{let s=await fetch(k("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let n=await s.json();Rn(e,n.diff,n.stagedDiff)}catch(s){let n=s instanceof Error?s.message:String(s);$e.textContent="Error",ze.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${h(n)}</div>`}}else{S.innerHTML=`<div class="git-diff-view"><div class="diff-header">
24
25
  <button class="diff-back">\u2190 Back</button>
25
26
  <span class="diff-filename">${h(e)}</span>
26
27
  <span class="diff-loading">Loading\u2026</span>
27
- </div></div>`,tt(),k.classList.add("open"),ze.classList.add("open");try{let s=await fetch(C("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let n=await s.json();Pn(e,n.diff,n.stagedDiff)}catch(s){let n=s instanceof Error?s.message:String(s);k.innerHTML=`<div class="git-diff-view"><div class="diff-header">
28
+ </div></div>`,nt(),S.classList.add("open"),je.classList.add("open");try{let s=await fetch(k("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let n=await s.json();Nn(e,n.diff,n.stagedDiff)}catch(s){let n=s instanceof Error?s.message:String(s);S.innerHTML=`<div class="git-diff-view"><div class="diff-header">
28
29
  <button class="diff-back">\u2190 Back</button>
29
30
  <span class="diff-filename">${h(e)}</span>
30
- </div><div class="diff-empty">Error loading diff: ${h(n)}</div></div>`}}}function Pn(e,t,s){if(!t&&!s){k.innerHTML=`<div class="git-diff-view"><div class="diff-header">
31
+ </div><div class="diff-empty">Error loading diff: ${h(n)}</div></div>`}}}function Nn(e,t,s){if(!t&&!s){S.innerHTML=`<div class="git-diff-view"><div class="diff-header">
31
32
  <button class="diff-back">\u2190 Back</button>
32
33
  <span class="diff-filename">${h(e)}</span>
33
- </div><div class="diff-empty">No diff content available</div></div>`;return}let{html:n,lineCount:l}=At(t,s);k.innerHTML=`<div class="git-diff-view"><div class="diff-header">
34
+ </div><div class="diff-empty">No diff content available</div></div>`;return}let{html:n,lineCount:a}=Ht(t,s);S.innerHTML=`<div class="git-diff-view"><div class="diff-header">
34
35
  <button class="diff-back">\u2190 Back</button>
35
36
  <span class="diff-filename">${h(e)}</span>
36
- <span class="diff-filesize">${l} lines</span>
37
- </div><div class="diff-content">${n}</div></div>`,k.querySelector(".diff-back")?.addEventListener("click",()=>{k.innerHTML=Dt,tt(),w&&k.querySelectorAll(".git-popover-item").forEach(r=>{let c=parseInt(r.dataset.idx||"0",10),i=w.files[c];!i||i.status==="D"||(r.style.cursor="pointer",r.addEventListener("click",()=>Ht(i.path)))}),It()})}function Nn(e,t,s){if(!t&&!s){Re.textContent="No diff",$e.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}let{html:n,lineCount:l}=At(t,s);Mt.textContent=e,Re.textContent=l+" lines",$e.innerHTML=n}function Rn(){Bt.style.display="none",je?(I.style.display="",I.classList.add("terminal-pending"),ye(je),je=null):y?(I.style.display="",I.classList.add("terminal-pending"),Nt()):X.style.display="flex"}An.addEventListener("click",Rn);function Ue(){k.classList.remove("open"),ze.classList.remove("open")}ze.addEventListener("click",Ue),document.addEventListener("keydown",e=>{e.key==="Escape"&&(Ue(),Oe())});async function Pt(e){try{let t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){let s=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(s.ok){let n=await s.json();w=n,be(n);return}}}catch{}w=null,be(null)}var _e=null;function Nt(){Ye(),y&&(Pt(y),_e=setInterval(()=>{y&&Pt(y)},3e4))}function Ye(){_e&&(clearInterval(_e),_e=null)}function $n(){if(Ne=me.fsRoots||[],Ne.length===0){if(y){zn(y);return}m.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}m.innerHTML="";for(let e of Ne){let t=document.createElement("div");t.className="file-tree-item",t.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${h(e)}`,t.addEventListener("click",()=>Y(e)),m.appendChild(t)}}async function zn(e){m.innerHTML='<div class="file-tree-empty">Loading...</div>';try{let t=await(await fetch(C("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?Y(t.path):m.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{m.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function Y(e){U=e,m.innerHTML='<div class="file-tree-empty">Loading...</div>';let t=Dn(e);try{let s=await(await fetch(C("/api/fs/list?path="+encodeURIComponent(e)))).json();await t,m.innerHTML="",be(w),m.innerHTML+=Fn();let n=jn(e);if(n&&!Ne.some(r=>e===r)){let r=document.createElement("div");r.className="file-tree-item",r.innerHTML="..",r.addEventListener("click",()=>Y(n)),m.appendChild(r)}if(s.dirs)for(let r of s.dirs){let c=r.split("/").pop()||r.split("\\").pop(),i=document.createElement("div");i.className="file-tree-item",i.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${h(c)}`,i.addEventListener("click",()=>Y(r)),m.appendChild(i)}else m.innerHTML="";let l=s.files||[];for(let r of l){let c=r.split("/").pop()||r.split("\\").pop(),i=In(r),u="",f="";if(i)switch(i){case"M":u="git-mod",f='<span class="git-file-status M">M</span>';break;case"A":u="git-add",f='<span class="git-file-status A">A</span>';break;case"D":u="git-del",f='<span class="git-file-status D">D</span>';break;case"?":u="git-untracked",f='<span class="git-file-status ?">?</span>';break;case"R":u="git-mod",f='<span class="git-file-status R">R</span>';break}let S=document.createElement("div");S.className="file-tree-item file"+(u?" "+u:""),S.innerHTML=`<span class="file-icon">\u{1F4C4}</span> ${f}${h(c)}`,S.addEventListener("click",()=>Un(r)),m.appendChild(S)}}catch{m.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function jn(e){let t=e.lastIndexOf("/");return t<=0?null:e.substring(0,t)}async function Un(e){He=e,I.style.display="none",g&&(Ye(),g.destroy(),g=null,y=null),be(null),Qe(),X.style.display="none",ve.style.display="flex",bn.textContent=e,H.textContent="Loading...",J.style.display="none";try{let t=await fetch(C("/api/file?path="+encodeURIComponent(e)));if(!t.ok){let n=await t.json();H.textContent=n.error||"Failed to load",ge.value="";return}let s=await t.json();ge.value=s.content,Pe=s.content,yt=s.content,H.textContent=s.size+" bytes",J.style.display=""}catch{H.textContent="Failed to load",ge.value=""}}ge.addEventListener("input",()=>{Pe=ge.value}),J.addEventListener("click",async()=>{J.textContent="Saving...",J.disabled=!0;try{let e=await fetch(C("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:He,content:Pe})});if(!e.ok){let t=await e.json();H.textContent=t.error||"Save failed";return}yt=Pe,H.textContent="Saved"}catch{H.textContent="Save failed"}finally{J.disabled=!1,J.textContent="Save"}}),En.addEventListener("click",async()=>{if(confirm("Delete "+He+"?"))try{let e=await fetch(C("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:He})});if(!e.ok){let t=await e.json();H.textContent=t.error||"Delete failed";return}ve.style.display="none",X.style.display="flex",U&&Y(U)}catch{H.textContent="Delete failed"}}),Ln.addEventListener("click",()=>{ve.style.display="none",X.style.display="flex",U&&Y(U)}),xn.addEventListener("click",async()=>{let e=wt.value.trim();if(!e)return;let t=U+"/"+e;try{let s=await fetch(C("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})});if(!s.ok){let n=await s.json();H.textContent=n.error||"Create failed";return}wt.value="",U&&Y(U)}catch{H.textContent="Create failed"}}),document.getElementById("mode-settings").addEventListener("click",()=>{let e=bt.classList.toggle("open");Ze.classList.toggle("open",e)}),Ze.addEventListener("click",()=>{bt.classList.remove("open"),Ze.classList.remove("open")});var D="",z=!1,qe,Ee=document.createElement("div");Ee.className="session-popover-backdrop",document.body.appendChild(Ee);var P=document.createElement("div");P.id="session-popover",P.className="session-popover",P.style.display="none",P.innerHTML=`<div class="sp-field">
37
+ <span class="diff-filesize">${a} lines</span>
38
+ </div><div class="diff-content">${n}</div></div>`,S.querySelector(".diff-back")?.addEventListener("click",()=>{S.innerHTML=Ft,nt(),w&&S.querySelectorAll(".git-popover-item").forEach(r=>{let c=parseInt(r.dataset.idx||"0",10),o=w.files[c];!o||o.status==="D"||(r.style.cursor="pointer",r.addEventListener("click",()=>Nt(o.path)))}),Dt()})}function Rn(e,t,s){if(!t&&!s){$e.textContent="No diff",ze.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}let{html:n,lineCount:a}=Ht(t,s);It.textContent=e,$e.textContent=a+" lines",ze.innerHTML=n}function Pn(){Mt.style.display="none",Ue?(I.style.display="",I.classList.add("terminal-pending"),we(Ue),Ue=null):y?(I.style.display="",I.classList.add("terminal-pending"),Pt()):J.style.display="flex"}An.addEventListener("click",Pn);function _e(){S.classList.remove("open"),je.classList.remove("open")}je.addEventListener("click",_e),document.addEventListener("keydown",e=>{e.key==="Escape"&&(_e(),We())});async function Rt(e){try{let t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){let s=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(s.ok){let n=await s.json();w=n,Ee(n);return}}}catch{}w=null,Ee(null)}var Ye=null;function Pt(){qe(),y&&(Rt(y),Ye=setInterval(()=>{y&&Rt(y)},3e4))}function qe(){Ye&&(clearInterval(Ye),Ye=null)}function $n(){if(Pe=he.fsRoots||[],Pe.length===0){if(y){zn(y);return}m.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}m.innerHTML="";for(let e of Pe){let t=document.createElement("div");t.className="file-tree-item",t.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${h(e)}`,t.addEventListener("click",()=>q(e)),m.appendChild(t)}}async function zn(e){m.innerHTML='<div class="file-tree-empty">Loading...</div>';try{let t=await(await fetch(k("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?q(t.path):m.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{m.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function q(e){_=e,m.innerHTML='<div class="file-tree-empty">Loading...</div>';let t=Dn(e);try{let s=await(await fetch(k("/api/fs/list?path="+encodeURIComponent(e)))).json();await t,m.innerHTML="",Ee(w),m.innerHTML+=Fn();let n=jn(e);if(n&&!Pe.some(r=>e===r)){let r=document.createElement("div");r.className="file-tree-item",r.innerHTML="..",r.addEventListener("click",()=>q(n)),m.appendChild(r)}if(s.dirs)for(let r of s.dirs){let c=r.split("/").pop()||r.split("\\").pop(),o=document.createElement("div");o.className="file-tree-item",o.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${h(c)}`,o.addEventListener("click",()=>q(r)),m.appendChild(o)}else m.innerHTML="";let a=s.files||[];for(let r of a){let c=r.split("/").pop()||r.split("\\").pop(),o=In(r),u="",f="";if(o)switch(o){case"M":u="git-mod",f='<span class="git-file-status M">M</span>';break;case"A":u="git-add",f='<span class="git-file-status A">A</span>';break;case"D":u="git-del",f='<span class="git-file-status D">D</span>';break;case"?":u="git-untracked",f='<span class="git-file-status ?">?</span>';break;case"R":u="git-mod",f='<span class="git-file-status R">R</span>';break}let B=document.createElement("div");B.className="file-tree-item file"+(u?" "+u:""),B.innerHTML=`<span class="file-icon">\u{1F4C4}</span> ${f}${h(c)}`,B.addEventListener("click",()=>Un(r)),m.appendChild(B)}}catch{m.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function jn(e){let t=e.lastIndexOf("/");return t<=0?null:e.substring(0,t)}async function Un(e){Ne=e,I.style.display="none",g&&(qe(),g.destroy(),g=null,y=null),Ee(null),et(),J.style.display="none",ge.style.display="flex",bn.textContent=e,H.textContent="Loading...",G.style.display="none";try{let t=await fetch(k("/api/file?path="+encodeURIComponent(e)));if(!t.ok){let n=await t.json();H.textContent=n.error||"Failed to load",ye.value="";return}let s=await t.json();ye.value=s.content,Re=s.content,wt=s.content,H.textContent=s.size+" bytes",G.style.display=""}catch{H.textContent="Failed to load",ye.value=""}}ye.addEventListener("input",()=>{Re=ye.value}),G.addEventListener("click",async()=>{G.textContent="Saving...",G.disabled=!0;try{let e=await fetch(k("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:Ne,content:Re})});if(!e.ok){let t=await e.json();H.textContent=t.error||"Save failed";return}wt=Re,H.textContent="Saved"}catch{H.textContent="Save failed"}finally{G.disabled=!1,G.textContent="Save"}}),En.addEventListener("click",async()=>{if(confirm("Delete "+Ne+"?"))try{let e=await fetch(k("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:Ne})});if(!e.ok){let t=await e.json();H.textContent=t.error||"Delete failed";return}ge.style.display="none",J.style.display="flex",_&&q(_)}catch{H.textContent="Delete failed"}}),Ln.addEventListener("click",()=>{ge.style.display="none",J.style.display="flex",_&&q(_)}),xn.addEventListener("click",async()=>{let e=bt.value.trim();if(!e)return;let t=_+"/"+e;try{let s=await fetch(k("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})});if(!s.ok){let n=await s.json();H.textContent=n.error||"Create failed";return}bt.value="",_&&q(_)}catch{H.textContent="Create failed"}}),document.getElementById("mode-settings").addEventListener("click",()=>{let e=Et.classList.toggle("open");Qe.classList.toggle("open",e)}),Qe.addEventListener("click",()=>{Et.classList.remove("open"),Qe.classList.remove("open")});var D="",j=!1,N,Le=document.createElement("div");Le.className="session-popover-backdrop",document.body.appendChild(Le);var R=document.createElement("div");R.id="session-popover",R.className="session-popover",R.style.display="none",R.innerHTML=`<div class="sp-field">
38
39
  <label>Rename session</label>
39
40
  <input type="text" id="sp-name" />
40
41
  </div>
@@ -44,5 +45,5 @@ var hn=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function
44
45
  </div>
45
46
  <hr class="sp-divider" />
46
47
  <button class="btn primary" id="sp-rebuild" style="display:none">\u91CD\u5EFA\u540C\u540D\u540C\u8DEF\u5F84 session</button>
47
- <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(P);function _n(e){let t=e.getBoundingClientRect();P.style.top=t.bottom+4+"px",P.style.left=Math.max(8,Math.min(t.left,window.innerWidth-240))+"px"}function Rt(e,t,s){D=e,z=!!s?.tombstone,qe=s?.agentId;let n=document.getElementById("sp-name");n.value=e;let l=P.querySelector(".sp-field label");l.textContent=z?"\u91CD\u547D\u540D (\u4EC5\u8BB0\u5F55\uFF0C\u4E0D\u91CD\u5EFA)":"Rename session";let r=document.getElementById("sp-rebuild");r.style.display=z?"":"none";let c=document.getElementById("sp-delete");c.textContent=z?"\u5220\u9664\u5931\u6548\u8BB0\u5F55 (\u5893\u7891\u6D88\u5931)":"Delete session";let i=document.getElementById("sp-save");i.textContent=z?"\u91CD\u547D\u540D":"Save",Ee.classList.add("open"),P.style.display="block",_n(t),setTimeout(()=>n.focus(),50)}function G(){Ee.classList.remove("open"),P.style.display="none"}Ee.addEventListener("click",G),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===D){G();return}try{let t=z?{oldName:D,newName:e,agentId:qe}:{oldName:D,newName:e};if(!(await fetch(C(z?"/api/sessions/rename-tombstone":"/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).ok)return;G(),_(),!z&&y===D&&ye(e)}catch{}}),document.getElementById("sp-rebuild").addEventListener("click",async()=>{if(confirm('\u91CD\u5EFA\u4F1A\u8BDD "'+D+'" (\u540C\u540D\u540C\u8DEF\u5F84\uFF0C\u5185\u5BB9\u4E3A\u7A7A)\uFF1F'))try{let e=await fetch(C("/api/sessions/rebuild"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,agentId:qe})});if(!e.ok){let t=await e.json();alert(t.error||"\u91CD\u5EFA\u5931\u8D25");return}G(),_()}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(z){if(!confirm('\u5220\u9664\u5931\u6548\u8BB0\u5F55 "'+D+'"\uFF1F'))return;try{if(!(await fetch(C("/api/sessions/dismiss"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,agentId:qe})})).ok)return;G(),_()}catch{}return}if(confirm('Delete session "'+D+'"?'))try{if(!(await fetch(C("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D})})).ok)return;G(),y===D&&(g&&(g.destroy(),g=null),y=null,I.style.display="none",X.style.display="flex"),_()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",G);var Yn={esc:"\x1B",tab:" ","s-tab":"\x1B[Z",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",space:" ",enter:"\r","ctrl-r":"","ctrl-c":"",btw:"/btw ",yes:"yes\r"};document.getElementById("mobile-keys").addEventListener("click",e=>{let t=e.target.closest("button[data-key]");if(!t||!g)return;let s=Yn[t.dataset.key];s&&(g.sendInput(s),g.focus())});var N=document.getElementById("mk-input"),$t=document.getElementById("mk-send");function zt(){if(!N||!g)return;let e=N.value;e&&(g.sendInput(e+"\r"),N.value="",N.rows=1,g.focus())}if(N&&(N.addEventListener("input",()=>{N.rows=1;let e=N.value.split(`
48
- `).length;N.rows=Math.min(e,4)}),N.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),zt())})),$t&&$t.addEventListener("click",zt),window.visualViewport){let e=document.querySelector(".app-layout"),t=()=>{e&&(e.style.height=window.visualViewport.height+"px"),window.scrollTo(0,0),document.documentElement.scrollTop=0,document.body.scrollTop=0};window.visualViewport.addEventListener("resize",t),window.addEventListener("orientationchange",()=>setTimeout(t,100)),document.addEventListener("touchstart",()=>{(window.scrollY>0||document.documentElement.scrollTop>0)&&window.scrollTo(0,0)},{passive:!0})}var nt=document.getElementById("process-panel"),Le=document.getElementById("proc-list"),qn=document.getElementById("proc-close"),st=document.getElementById("proc-backdrop"),On=document.getElementById("header-ram");function Wn(){Le.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(C("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){Le.innerHTML='<div class="proc-empty">No processes</div>';return}let t="";for(let s of e){let n=s.rss,l=n<1048576?(n/1024).toFixed(0)+"K":(n/1048576).toFixed(1)+"M";t+='<div class="proc-row" data-pid="'+s.pid+'"><span class="proc-mem">'+s.mem+'%</span><span class="proc-rss">'+l+'</span><span class="proc-cmd" title="'+h(s.command)+'">'+h(s.command)+'</span><button class="proc-kill" title="Kill PID '+s.pid+'">&times;</button></div>'}Le.innerHTML=t;for(let s of Le.querySelectorAll(".proc-row")){let n=s.querySelector(".proc-kill");n&&n.addEventListener("click",l=>{let r=l.target.closest(".proc-row");!r||!confirm("Kill PID "+r.dataset.pid+"?")||fetch(C("/api/system/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pid:parseInt(r.dataset.pid,10)})}).then(c=>c.json()).then(c=>{c.ok?r.style.opacity="0.3":alert("Failed: "+(c.error||"unknown"))}).catch(()=>alert("Network error"))})}}).catch(()=>{Le.innerHTML='<div class="proc-empty">Failed to load</div>'})}function Kn(){nt.classList.add("open"),st.classList.add("open"),Wn()}function Oe(){nt.classList.remove("open"),st.classList.remove("open")}On.addEventListener("click",e=>{e.stopPropagation(),nt.classList.contains("open")?Oe():Kn()}),qn.addEventListener("click",Oe),st.addEventListener("click",Oe);var Vn=2e3,xe=null,at=null,ne=new Map,se=new Map,Xn=5e3,jt=new Map;function it(e,t){return(t?"a:"+t+":":"l:")+e}function Jn(e,t,s){let n=it(e,t);if(s==="working"){let f=jt.get(n);if(f&&Date.now()<f)return}let l=se.get(n),r=e===y&&(t??null)===B,c=s==="idle"&&l?.state==="working";se.set(n,{session:e,agentId:t,state:s,doneUntil:c?Date.now()+Vn:void 0,unread:c?!r:!1});let i=t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])',u=m.querySelector(i);u&&We(u,n,se.get(n))}function We(e,t,s){let n=ne.get(t);n&&(clearTimeout(n),ne.delete(t)),e.classList.remove("working","just-done");let l=s.session===y&&(s.agentId??null)===B;s.state==="working"?e.classList.add("working"):l&&s.doneUntil&&Date.now()<s.doneUntil?(e.classList.add("just-done"),ne.set(t,setTimeout(()=>{e.classList.remove("just-done"),ne.delete(t)},Math.max(0,s.doneUntil-Date.now())))):!l&&s.unread&&e.classList.add("just-done")}function ot(){for(let[e,t]of se){let s=t.agentId?'.session-item[data-agent="'+CSS.escape(t.agentId)+'"][data-session="'+CSS.escape(t.session)+'"]':'.session-item[data-session="'+CSS.escape(t.session)+'"]:not([data-agent])',n=m.querySelector(s);n&&We(n,e,t)}}function Gn(e,t){let s=it(e,t),n=se.get(s);if(!n)return;let l=ne.get(s);l&&(clearTimeout(l),ne.delete(s)),n.doneUntil=void 0,n.unread=!1;let r=t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])',c=m.querySelector(r);c&&We(c,s,n)}function Ut(){if(xe||at)return;let e=localStorage.getItem("tmux-web-token"),t=(location.protocol==="https:"?"wss:":"ws:")+"//"+location.host+"/ws/activity";e&&(t+="?token="+encodeURIComponent(e));try{let s=new WebSocket(t);xe=s,s.onmessage=n=>{try{let l=JSON.parse(String(n.data));l&&l.type==="session.activity"&&typeof l.session=="string"&&Jn(l.session,l.agentId||void 0,l.state==="working"?"working":"idle")}catch{}},s.onclose=()=>{xe===s&&(xe=null,at=setTimeout(()=>{at=null,Ut()},5e3))},s.onerror=()=>{try{s.close()}catch{}}}catch{xe=null}}window.__openSession=ye,window.__refreshSidebar=_,_(),Qe(),ot(),Ut(),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&ot()}),setInterval(()=>{document.visibilityState==="visible"&&_()},1e4);
48
+ <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(R);function _n(e){let t=e.getBoundingClientRect(),s=window.innerHeight,n=R.offsetHeight||240,a=t.bottom+4;a+n>s-8&&(a=Math.max(8,t.top-n-4)),R.style.top=a+"px",R.style.left=Math.max(8,Math.min(t.left,window.innerWidth-240))+"px"}function Oe(e,t,s){D=e,j=!!s?.tombstone,N=s?.agentId;let n=document.getElementById("sp-name");n.value=e;let a=R.querySelector(".sp-field label");a.textContent=j?"\u91CD\u547D\u540D (\u4EC5\u8BB0\u5F55\uFF0C\u4E0D\u91CD\u5EFA)":"Rename session";let r=document.getElementById("sp-rebuild");r.style.display=j?"":"none";let c=document.getElementById("sp-delete");c.textContent=j?"\u5220\u9664\u5931\u6548\u8BB0\u5F55 (\u5893\u7891\u6D88\u5931)":"Delete session";let o=document.getElementById("sp-save");o.textContent=j?"\u91CD\u547D\u540D":"Save",Le.classList.add("open"),R.style.display="block",_n(t),setTimeout(()=>n.focus(),50)}function Z(){Le.classList.remove("open"),R.style.display="none"}Le.addEventListener("click",Z),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===D){Z();return}try{let t=j?{oldName:D,newName:e,agentId:N}:{oldName:D,newName:e,...N?{agentId:N}:{}};if(!(await fetch(k(j?"/api/sessions/rename-tombstone":"/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).ok)return;Z(),Y(),!j&&y===D&&(N??null)===C&&we(e,N)}catch{}}),document.getElementById("sp-rebuild").addEventListener("click",async()=>{if(confirm('\u91CD\u5EFA\u4F1A\u8BDD "'+D+'" (\u540C\u540D\u540C\u8DEF\u5F84\uFF0C\u5185\u5BB9\u4E3A\u7A7A)\uFF1F'))try{let e=await fetch(k("/api/sessions/rebuild"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,agentId:N})});if(!e.ok){let t=await e.json();alert(t.error||"\u91CD\u5EFA\u5931\u8D25");return}Z(),Y()}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(j){if(!confirm('\u5220\u9664\u5931\u6548\u8BB0\u5F55 "'+D+'"\uFF1F'))return;try{if(!(await fetch(k("/api/sessions/dismiss"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,agentId:N})})).ok)return;Z(),Y()}catch{}return}if(confirm('Delete session "'+D+'"?'))try{if(!(await fetch(k("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,...N?{agentId:N}:{}})})).ok)return;Z(),y===D&&(N??null)===C&&(g&&(g.destroy(),g=null),y=null,I.style.display="none",J.style.display="flex"),Y()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",Z);var Yn={esc:"\x1B",tab:" ","s-tab":"\x1B[Z",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",space:" ",enter:"\r","ctrl-r":"","ctrl-c":"",btw:"/btw ",yes:"yes\r"};document.getElementById("mobile-keys").addEventListener("click",e=>{let t=e.target.closest("button[data-key]");if(!t||!g)return;let s=Yn[t.dataset.key];s&&(g.sendInput(s),g.focus())});var P=document.getElementById("mk-input"),$t=document.getElementById("mk-send");function zt(){if(!P||!g)return;let e=P.value;e&&(g.sendInput(e+"\r"),P.value="",P.rows=1,g.focus())}if(P&&(P.addEventListener("input",()=>{P.rows=1;let e=P.value.split(`
49
+ `).length;P.rows=Math.min(e,4)}),P.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),zt())})),$t&&$t.addEventListener("click",zt),window.visualViewport){let e=document.querySelector(".app-layout"),t=()=>{e&&(e.style.height=window.visualViewport.height+"px"),window.scrollTo(0,0),document.documentElement.scrollTop=0,document.body.scrollTop=0};window.visualViewport.addEventListener("resize",t),window.addEventListener("orientationchange",()=>setTimeout(t,100)),document.addEventListener("touchstart",()=>{(window.scrollY>0||document.documentElement.scrollTop>0)&&window.scrollTo(0,0)},{passive:!0})}var st=document.getElementById("process-panel"),xe=document.getElementById("proc-list"),qn=document.getElementById("proc-close"),it=document.getElementById("proc-backdrop"),On=document.getElementById("header-ram");function Wn(){xe.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(k("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){xe.innerHTML='<div class="proc-empty">No processes</div>';return}let t="";for(let s of e){let n=s.rss,a=n<1048576?(n/1024).toFixed(0)+"K":(n/1048576).toFixed(1)+"M";t+='<div class="proc-row" data-pid="'+s.pid+'"><span class="proc-mem">'+s.mem+'%</span><span class="proc-rss">'+a+'</span><span class="proc-cmd" title="'+h(s.command)+'">'+h(s.command)+'</span><button class="proc-kill" title="Kill PID '+s.pid+'">&times;</button></div>'}xe.innerHTML=t;for(let s of xe.querySelectorAll(".proc-row")){let n=s.querySelector(".proc-kill");n&&n.addEventListener("click",a=>{let r=a.target.closest(".proc-row");!r||!confirm("Kill PID "+r.dataset.pid+"?")||fetch(k("/api/system/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pid:parseInt(r.dataset.pid,10)})}).then(c=>c.json()).then(c=>{c.ok?r.style.opacity="0.3":alert("Failed: "+(c.error||"unknown"))}).catch(()=>alert("Network error"))})}}).catch(()=>{xe.innerHTML='<div class="proc-empty">Failed to load</div>'})}function Kn(){st.classList.add("open"),it.classList.add("open"),Wn()}function We(){st.classList.remove("open"),it.classList.remove("open")}On.addEventListener("click",e=>{e.stopPropagation(),st.classList.contains("open")?We():Kn()}),qn.addEventListener("click",We),it.addEventListener("click",We);var Vn=2e3,Ce=null,at=null,se=new Map,ie=new Map,Xn=5e3,jt=new Map;function ot(e,t){return(t?"a:"+t+":":"l:")+e}function Jn(e,t,s){let n=ot(e,t);if(s==="working"){let f=jt.get(n);if(f&&Date.now()<f)return}let a=ie.get(n),r=e===y&&(t??null)===C,c=s==="idle"&&a?.state==="working";ie.set(n,{session:e,agentId:t,state:s,doneUntil:c?Date.now()+Vn:void 0,unread:c?!r:!1});let o=t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])',u=m.querySelector(o);u&&Ke(u,n,ie.get(n))}function Ke(e,t,s){let n=se.get(t);n&&(clearTimeout(n),se.delete(t)),e.classList.remove("working","just-done");let a=s.session===y&&(s.agentId??null)===C;s.state==="working"?e.classList.add("working"):a&&s.doneUntil&&Date.now()<s.doneUntil?(e.classList.add("just-done"),se.set(t,setTimeout(()=>{e.classList.remove("just-done"),se.delete(t)},Math.max(0,s.doneUntil-Date.now())))):!a&&s.unread&&e.classList.add("just-done")}function lt(){for(let[e,t]of ie){let s=t.agentId?'.session-item[data-agent="'+CSS.escape(t.agentId)+'"][data-session="'+CSS.escape(t.session)+'"]':'.session-item[data-session="'+CSS.escape(t.session)+'"]:not([data-agent])',n=m.querySelector(s);n&&Ke(n,e,t)}}function Gn(e,t){let s=ot(e,t),n=ie.get(s);if(!n)return;let a=se.get(s);a&&(clearTimeout(a),se.delete(s)),n.doneUntil=void 0,n.unread=!1;let r=t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])',c=m.querySelector(r);c&&Ke(c,s,n)}function Ut(){if(Ce||at)return;let e=localStorage.getItem("tmux-web-token"),t=(location.protocol==="https:"?"wss:":"ws:")+"//"+location.host+"/ws/activity";e&&(t+="?token="+encodeURIComponent(e));try{let s=new WebSocket(t);Ce=s,s.onmessage=n=>{try{let a=JSON.parse(String(n.data));a&&a.type==="session.activity"&&typeof a.session=="string"&&Jn(a.session,a.agentId||void 0,a.state==="working"?"working":"idle")}catch{}},s.onclose=()=>{Ce===s&&(Ce=null,at=setTimeout(()=>{at=null,Ut()},5e3))},s.onerror=()=>{try{s.close()}catch{}}}catch{Ce=null}}window.__openSession=we,window.__refreshSidebar=Y,Y(),et(),lt(),Ut(),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&lt()}),setInterval(()=>{document.visibilityState==="visible"&&Y()},1e4);