tmux-weblink 2.0.30 → 2.0.32

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,38 +1,38 @@
1
- var Zt=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function je(e){return e.replace(/\x1b\[\?1049[hl]/g,"")}function oe(e){return e.replace(Zt,"")}var ke;function Gt(){return ke||(document.querySelector("link[data-tmux-web-xterm-css]")?ke=Promise.resolve():(ke=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)}),ke))}var Qt=class Ct{terminal;fitAddon;container;constructor(t,n,a){this.container=t,this.terminal=n,this.fitAddon=a,this.terminal.loadAddon(this.fitAddon),this.terminal.open(t)}static async create(t,n,a){let[{Terminal:o},{FitAddon:r}]=await Promise.all([import("./xterm-BXEES47M.js"),import("./addon-fit-D5N335P2.js"),Gt()]),c=new o({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:n,convertEol:!1,smoothScrollDuration:120,theme:a});return new Ct(t,c,new r)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(t){return new Promise(n=>this.terminal.write(t,n))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(t,n=!1){this.terminal.scrollToLine(Math.max(0,t),n)}scrollLines(t){let n=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=en(this.container);return t.width<=0||t.height<=0?!1:(this.fitAddon.fit(),!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,n){let a=this.terminal.buffer.active,[o,r]=t<=n?[t,n]:[n,t],c=a.viewportY,l=[];for(let u=o;u<=r;u++){let p=a.getLine(c+u);l.push(p?p.translateToString(!0):"")}return l.join(`
2
- `)}selectRows(t,n){let a=this.terminal.buffer.active,[o,r]=t<=n?[t,n]:[n,t];this.terminal.selectLines(a.viewportY+o,a.viewportY+r)}selectCells(t,n,a,o){let r=this.terminal.buffer.active,c=Math.min(n,o),l=Math.max(n,o);if(c===l){let u=Math.min(t,a),p=Math.max(t,a);this.terminal.select(u,r.viewportY+c,p-u+1)}else this.terminal.selectLines(r.viewportY+c,r.viewportY+l)}getCellsText(t,n,a,o){let r=this.terminal.buffer.active,c=Math.min(n,o),l=Math.max(n,o),u=n<o?t:n>o?a:Math.min(t,a),p=n<o?a:n>o?t:Math.max(t,a),B=r.viewportY,k=[];for(let H=c;H<=l;H++){let ve=r.getLine(B+H);if(!ve){k.push("");continue}let O=H===c?u:0,Ne=H===l?p:this.terminal.cols-1,K="";for(let C=O;C<=Ne;C++){let _=ve.getCell(C);_&&(K+=_.getChars())}k.push(K.replace(/\s+$/,""))}return k.join(`
3
- `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function en(e){let t=e.getBoundingClientRect(),n=window.visualViewport;return n?{width:Math.min(t.width,n.width),height:Math.max(0,Math.min(t.height,n.height-Math.max(0,t.top)))}:t}function tn(e,t,n){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let a=await Qt.create(e,n.scrollback,n.theme),o,r=0,c,l=null,u=0,p=0,B=.2,k=10,H=.95,ve=.04;function O(){u&&(cancelAnimationFrame(u),u=0),p=0}function Ne(i){if(O(),Math.abs(i)<B)return;p=Math.max(-k,Math.min(k,i));let s=()=>{if(N){u=0;return}let d=e.querySelector(".xterm-rows > div"),f=d?d.getBoundingClientRect().height:16,b=f>0?Math.round(p*16/f):p>0?1:-1;b===0&&(b=p>0?1:-1);let I=a.viewportY()-b,Y=a.baseY(),se=Math.max(0,Math.min(I,Y));if(a.scrollToLine(se,!0),p*=H,se!==I){u=0;return}if(Math.abs(p)<ve){u=0;return}u=requestAnimationFrame(s)};u=requestAnimationFrame(s)}let K=0,C="connecting",_=0,G=!1,ge=[],V="",N=!1,Q=1e3,Tt=location.protocol==="https:"?"wss:":"ws:",Mt=n.wsBase||"/ws",Bt=Tt+"//"+location.host+Mt+"/"+encodeURIComponent(t),St="/api/session/"+encodeURIComponent(t)+"/upload",It=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Dt(){return ge.join("")+V}async function Ht(i,s=0){let d=i?a.viewportY():0,f=oe(Dt());if(a.reset(),!f){i||a.scrollToBottom();return}await a.write(f),i?a.scrollToLine(s+d):a.scrollToBottom()}function j(i){o?.readyState===WebSocket.OPEN&&o.send(JSON.stringify(i))}function At(i){let s;try{s=JSON.parse(i)}catch{C==="live"&&(V+=i,a.write(oe(i)));return}if(s.type==="auth.required"){let d=localStorage.getItem("tmux-web-token");d?j({type:"auth.token",token:d}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(s.type==="attach_failed"&&typeof s.message=="string"){ye=!0,C="dead",a.reset(),a.write(`\r
4
- \x1B[31m`+oe(s.message)+`\x1B[0m\r
5
- `).then(()=>{be();try{o?.close()}catch{}});return}if(s.type==="auth.ok"){s.token&&localStorage.setItem("tmux-web-token",s.token),Q=1e3,F(),j({type:"resize",cols:a.cols,rows:a.rows}),T();return}if(s.type==="auth.failed"){if(s.permanentLock||s.retryAfterMs&&s.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(s.message);return}return}if(s.type==="snapshot"&&typeof s.data=="string"){let d=je(oe(s.data));ge=[d],V="",_=typeof s.lines=="number"?s.lines:n.terminal.initialLines,C="live",a.reset(),F(),j({type:"resize",cols:a.cols,rows:a.rows}),a.write(d).then(()=>a.scrollToBottom());return}if(s.type==="window_changed"&&typeof s.activeIndex=="number"){let d=new URL(location.href);d.searchParams.get("window")!==String(s.activeIndex)&&(d.searchParams.set("window",String(s.activeIndex)),history.replaceState(history.state,"",d)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:s.windows}));return}if(s.type==="history"&&typeof s.data=="string"){s.lines>0&&s.data?(ge.unshift(je(s.data)),_+=s.lines,Ht(!0,s.lines).finally(()=>{G=!1})):G=!1;return}if(s.type==="data"&&typeof s.data=="string"){let d=je(oe(s.data));if(C==="connecting"){C="live",V=d,a.write(d);return}C==="live"&&(V+=d,a.write(d))}}let ye=!1;function Ve(){if(ye)return;let i=Bt,s=localStorage.getItem("tmux-web-token");s&&(i+=(i.includes("?")?"&":"?")+"token="+encodeURIComponent(s)),i+=(i.includes("?")?"&":"?")+"cols="+a.cols+"&rows="+a.rows,o=new WebSocket(i),o.onopen=()=>{C="connecting",_=0,G=!1,ge=[],V="",a.reset(),Q=1e3},o.onmessage=d=>{typeof d.data=="string"&&At(d.data)},o.onclose=()=>{N||(C="connecting",!ye&&setTimeout(()=>{Q=Math.min(Q*2,1e4),!N&&!ye&&Ve()},Q))},o.onerror=()=>o?.close()}function we(i){j({type:"input",data:i})}function F(){return a.fit()}function be(){e.classList.remove("terminal-pending")}function T(){r&&cancelAnimationFrame(r),c&&clearTimeout(c),F(),r=requestAnimationFrame(()=>{r=0,F()&&be()}),c=setTimeout(()=>{F()&&be()},120)}function Rt(){T(),setTimeout(T,50),setTimeout(T,150),setTimeout(T,300)}function Xe(i){return typeof i=="string"&&i.startsWith("image/")}function Je(i){return i?.files?.length?i.files[0]??null:null}function $t(i){if(!i?.items)return null;for(let s=0;s<i.items.length;s++){let d=i.items[s];if(d?.kind==="file"&&Xe(d.type))return d.getAsFile()}return null}async function Nt(i){let s=new FormData,d=i instanceof File&&i.name?i.name:"upload";s.append("file",i,d);let f=localStorage.getItem("tmux-web-token"),b={};f&&(b.Authorization="Bearer "+f);let I=await fetch(St,{method:"POST",body:s,headers:b});if(!I.ok){let se="upload failed";try{let it=await I.json();it.error&&(se=it.error)}catch{}throw new Error(se)}let Y=await I.json();if(!Y.path)throw new Error("no path in response");return Y.path}async function Pe(i){try{let s=await Nt(i);we(s)}catch{}}a.onData(i=>we(i)),a.onResize(({cols:i,rows:s})=>j({type:"resize",cols:i,rows:s})),a.onScroll(()=>{C!=="live"||G||!a.isNearScrollbackTop()||(G=!0,j({type:"load_history",before:_}))});let ee=!1,te=!1,w=null,L=null,ne=document.createElement("div");ne.className="terminal-copy-banner",ne.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',ne.hidden=!0,e.appendChild(ne);let R=document.createElement("div");R.className="terminal-copy-banner terminal-copy-toast",R.textContent="Copied",R.hidden=!0,e.appendChild(R);function Ze(i,s){let d=e.querySelector(".xterm-screen, canvas"),f=(d&&d.getBoundingClientRect().width>0?d:e).getBoundingClientRect(),b=f.height>0&&a.rows>0?f.height/a.rows:18,I=f.width>0&&a.cols>0?f.width/a.cols:9;return{row:Math.max(0,Math.min(a.rows-1,Math.floor((s-f.top)/b))),col:Math.max(0,Math.min(a.cols-1,Math.floor((i-f.left)/I)))}}async function Le(i){if(!i)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(i);return}}catch{}let s=document.createElement("textarea");s.value=i,s.style.position="fixed",s.style.opacity="0",s.style.pointerEvents="none",document.body.appendChild(s),s.focus(),s.select();try{document.execCommand("copy")}catch{}s.remove()}let ie;function Ee(){R.hidden=!1,ie&&clearTimeout(ie),ie=setTimeout(()=>{R.hidden=!0},1e3)}function X(i){ee=i,ne.hidden=!i,e.classList.toggle("terminal-copy-mode-active",i),i&&a.focus()}function Ge(){X(!ee)}function Pt(i){N||i.button!==0||te||(ee||i.shiftKey)&&(i.preventDefault(),i.stopPropagation(),te=!0,w=Ze(i.clientX,i.clientY),L=w,a.selectCells(w.col,w.row,L.col,L.row),document.addEventListener("mousemove",ze,!0),document.addEventListener("mouseup",_e,!0))}function ze(i){N||!te||!w||(i.preventDefault(),i.stopPropagation(),L=Ze(i.clientX,i.clientY),a.selectCells(w.col,w.row,L.col,L.row))}function _e(i){if(N||!te||!w||!L)return;i.preventDefault(),i.stopPropagation(),document.removeEventListener("mousemove",ze,!0),document.removeEventListener("mouseup",_e,!0),te=!1;let s=a.getCellsText(w.col,w.row,L.col,L.row);w=null,L=null,a.clearSelection(),X(!1),s&&(R.textContent="\u5DF2\u590D\u5236",Le(s).then(Ee)),a.focus()}e.addEventListener("mousedown",Pt,!0),document.addEventListener("keydown",zt,!0);function zt(i){if(!(N||!a.isFocused()||i.defaultPrevented||i.isComposing)){if(ee){if(i.key==="Escape"){i.preventDefault(),i.stopPropagation(),w=null,L=null,a.clearSelection(),X(!1);return}if(i.key==="Enter"||(i.ctrlKey||i.metaKey)&&i.code==="KeyC"){i.preventDefault(),i.stopPropagation(),Le(a.getScreenText()).then(Ee),X(!1);return}}if(i.altKey&&i.code==="KeyC"&&!i.ctrlKey&&!i.metaKey){if(i.preventDefault(),i.stopPropagation(),w&&L){let s=a.getCellsText(w.col,w.row,L.col,L.row);w=null,L=null,a.clearSelection(),X(!1),s&&(R.textContent="Copied",Le(s).then(Ee))}else{let s=a.getSelection();s?(a.clearSelection(),R.textContent="Copied",Le(s).then(Ee)):Ge()}return}if((i.ctrlKey||i.metaKey)&&i.code==="KeyV"){i.preventDefault(),i.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){let s=await navigator.clipboard.read();for(let d of s)for(let f of d.types)if(Xe(f)){let b=await d.getType(f);await Pe(b);return}}}catch{}try{let s=await navigator.clipboard?.readText();s&&a.pasteText(Qe(s))}catch{}})();return}}}let xe=0;function Qe(i){return i.split(`\r
1
+ var Zt=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function je(e){return e.replace(/\x1b\[\?1049[hl]/g,"")}function oe(e){return e.replace(Zt,"")}var ke;function Gt(){return ke||(document.querySelector("link[data-tmux-web-xterm-css]")?ke=Promise.resolve():(ke=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)}),ke))}var Qt=class Ct{terminal;fitAddon;container;constructor(t,n,s){this.container=t,this.terminal=n,this.fitAddon=s,this.terminal.loadAddon(this.fitAddon),this.terminal.open(t)}static async create(t,n,s){let[{Terminal:o},{FitAddon:r}]=await Promise.all([import("./xterm-BXEES47M.js"),import("./addon-fit-D5N335P2.js"),Gt()]),c=new o({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:n,convertEol:!1,smoothScrollDuration:120,theme:s});return new Ct(t,c,new r)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(t){return new Promise(n=>this.terminal.write(t,n))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(t,n=!1){this.terminal.scrollToLine(Math.max(0,t),n)}scrollLines(t){let n=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=en(this.container);if(t.width<=0||t.height<=0)return!1;let n=this.terminal._core?._renderService?.dimensions?.css?.cell;if(!n?.width||!n?.height)return this.fitAddon.fit(),!0;let s=n.width,o=n.height,r=this.terminal.element?.querySelector(".xterm-viewport"),c=r?Math.max(0,r.offsetWidth-r.clientWidth):0,l=Math.max(2,Math.floor((t.width-c)/s)),u=Math.max(2,Math.floor(t.height/o));return(l!==this.terminal.cols||u!==this.terminal.rows)&&this.terminal.resize(l,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,n){let s=this.terminal.buffer.active,[o,r]=t<=n?[t,n]:[n,t],c=s.viewportY,l=[];for(let u=o;u<=r;u++){let p=s.getLine(c+u);l.push(p?p.translateToString(!0):"")}return l.join(`
2
+ `)}selectRows(t,n){let s=this.terminal.buffer.active,[o,r]=t<=n?[t,n]:[n,t];this.terminal.selectLines(s.viewportY+o,s.viewportY+r)}selectCells(t,n,s,o){let r=this.terminal.buffer.active,c=Math.min(n,o),l=Math.max(n,o);if(c===l){let u=Math.min(t,s),p=Math.max(t,s);this.terminal.select(u,r.viewportY+c,p-u+1)}else this.terminal.selectLines(r.viewportY+c,r.viewportY+l)}getCellsText(t,n,s,o){let r=this.terminal.buffer.active,c=Math.min(n,o),l=Math.max(n,o),u=n<o?t:n>o?s:Math.min(t,s),p=n<o?s:n>o?t:Math.max(t,s),S=r.viewportY,k=[];for(let H=c;H<=l;H++){let ve=r.getLine(S+H);if(!ve){k.push("");continue}let O=H===c?u:0,Ne=H===l?p:this.terminal.cols-1,K="";for(let C=O;C<=Ne;C++){let z=ve.getCell(C);z&&(K+=z.getChars())}k.push(K.replace(/\s+$/,""))}return k.join(`
3
+ `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function en(e){let t=e.getBoundingClientRect(),n=window.visualViewport;return n?{width:Math.min(t.width,n.width),height:Math.max(0,Math.min(t.height,n.height-Math.max(0,t.top)))}:t}function tn(e,t,n){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let s=await Qt.create(e,n.scrollback,n.theme),o,r=0,c,l=null,u=0,p=0,S=.2,k=10,H=.95,ve=.04;function O(){u&&(cancelAnimationFrame(u),u=0),p=0}function Ne(i){if(O(),Math.abs(i)<S)return;p=Math.max(-k,Math.min(k,i));let a=()=>{if(N){u=0;return}let d=e.querySelector(".xterm-rows > div"),f=d?d.getBoundingClientRect().height:16,b=f>0?Math.round(p*16/f):p>0?1:-1;b===0&&(b=p>0?1:-1);let I=s.viewportY()-b,W=s.baseY(),ae=Math.max(0,Math.min(I,W));if(s.scrollToLine(ae,!0),p*=H,ae!==I){u=0;return}if(Math.abs(p)<ve){u=0;return}u=requestAnimationFrame(a)};u=requestAnimationFrame(a)}let K=0,C="connecting",z=0,G=!1,ge=[],V="",N=!1,Q=1e3,Mt=location.protocol==="https:"?"wss:":"ws:",Tt=n.wsBase||"/ws",St=Mt+"//"+location.host+Tt+"/"+encodeURIComponent(t),Bt="/api/session/"+encodeURIComponent(t)+"/upload",It=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Dt(){return ge.join("")+V}async function Ht(i,a=0){let d=i?s.viewportY():0,f=oe(Dt());if(s.reset(),!f){i||s.scrollToBottom();return}await s.write(f),i?s.scrollToLine(a+d):s.scrollToBottom()}function j(i){o?.readyState===WebSocket.OPEN&&o.send(JSON.stringify(i))}function At(i){let a;try{a=JSON.parse(i)}catch{C==="live"&&(V+=i,s.write(oe(i)));return}if(a.type==="auth.required"){let d=localStorage.getItem("tmux-web-token");d?j({type:"auth.token",token:d}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(a.type==="attach_failed"&&typeof a.message=="string"){ye=!0,C="dead",s.reset(),s.write(`\r
4
+ \x1B[31m`+oe(a.message)+`\x1B[0m\r
5
+ `).then(()=>{be();try{o?.close()}catch{}});return}if(a.type==="auth.ok"){a.token&&localStorage.setItem("tmux-web-token",a.token),Q=1e3,F(),j({type:"resize",cols:s.cols,rows:s.rows}),M();return}if(a.type==="auth.failed"){if(a.permanentLock||a.retryAfterMs&&a.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(a.message);return}return}if(a.type==="snapshot"&&typeof a.data=="string"){let d=je(oe(a.data));ge=[d],V="",z=typeof a.lines=="number"?a.lines:n.terminal.initialLines,C="live",s.reset(),F(),j({type:"resize",cols:s.cols,rows:s.rows}),s.write(d).then(()=>s.scrollToBottom());return}if(a.type==="window_changed"&&typeof a.activeIndex=="number"){let d=new URL(location.href);d.searchParams.get("window")!==String(a.activeIndex)&&(d.searchParams.set("window",String(a.activeIndex)),history.replaceState(history.state,"",d)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:a.windows}));return}if(a.type==="history"&&typeof a.data=="string"){a.lines>0&&a.data?(ge.unshift(je(a.data)),z+=a.lines,Ht(!0,a.lines).finally(()=>{G=!1})):G=!1;return}if(a.type==="data"&&typeof a.data=="string"){let d=je(oe(a.data));if(C==="connecting"){C="live",V=d,s.write(d);return}C==="live"&&(V+=d,s.write(d))}}let ye=!1;function Ve(){if(ye)return;let i=St,a=localStorage.getItem("tmux-web-token");a&&(i+=(i.includes("?")?"&":"?")+"token="+encodeURIComponent(a)),i+=(i.includes("?")?"&":"?")+"cols="+s.cols+"&rows="+s.rows,o=new WebSocket(i),o.onopen=()=>{C="connecting",z=0,G=!1,ge=[],V="",s.reset(),Q=1e3},o.onmessage=d=>{typeof d.data=="string"&&At(d.data)},o.onclose=()=>{N||(C="connecting",!ye&&setTimeout(()=>{Q=Math.min(Q*2,1e4),!N&&!ye&&Ve()},Q))},o.onerror=()=>o?.close()}function we(i){j({type:"input",data:i})}function F(){return s.fit()}function be(){e.classList.remove("terminal-pending")}function M(){r&&cancelAnimationFrame(r),c&&clearTimeout(c),F(),r=requestAnimationFrame(()=>{r=0,F()&&be()}),c=setTimeout(()=>{F()&&be()},120)}function Rt(){M(),setTimeout(M,50),setTimeout(M,150),setTimeout(M,300)}function Xe(i){return typeof i=="string"&&i.startsWith("image/")}function Je(i){return i?.files?.length?i.files[0]??null:null}function $t(i){if(!i?.items)return null;for(let a=0;a<i.items.length;a++){let d=i.items[a];if(d?.kind==="file"&&Xe(d.type))return d.getAsFile()}return null}async function Nt(i){let a=new FormData,d=i instanceof File&&i.name?i.name:"upload";a.append("file",i,d);let f=localStorage.getItem("tmux-web-token"),b={};f&&(b.Authorization="Bearer "+f);let I=await fetch(Bt,{method:"POST",body:a,headers:b});if(!I.ok){let ae="upload failed";try{let st=await I.json();st.error&&(ae=st.error)}catch{}throw new Error(ae)}let W=await I.json();if(!W.path)throw new Error("no path in response");return W.path}async function Pe(i){try{let a=await Nt(i);we(a)}catch{}}s.onData(i=>we(i)),s.onResize(({cols:i,rows:a})=>j({type:"resize",cols:i,rows:a})),s.onScroll(()=>{C!=="live"||G||!s.isNearScrollbackTop()||(G=!0,j({type:"load_history",before:z}))});let ee=!1,te=!1,w=null,L=null,ne=document.createElement("div");ne.className="terminal-copy-banner",ne.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',ne.hidden=!0,e.appendChild(ne);let R=document.createElement("div");R.className="terminal-copy-banner terminal-copy-toast",R.textContent="Copied",R.hidden=!0,e.appendChild(R);function Ze(i,a){let d=e.querySelector(".xterm-screen, canvas"),f=(d&&d.getBoundingClientRect().width>0?d:e).getBoundingClientRect(),b=f.height>0&&s.rows>0?f.height/s.rows:18,I=f.width>0&&s.cols>0?f.width/s.cols:9;return{row:Math.max(0,Math.min(s.rows-1,Math.floor((a-f.top)/b))),col:Math.max(0,Math.min(s.cols-1,Math.floor((i-f.left)/I)))}}async function Le(i){if(!i)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(i);return}}catch{}let a=document.createElement("textarea");a.value=i,a.style.position="fixed",a.style.opacity="0",a.style.pointerEvents="none",document.body.appendChild(a),a.focus(),a.select();try{document.execCommand("copy")}catch{}a.remove()}let se;function Ee(){R.hidden=!1,se&&clearTimeout(se),se=setTimeout(()=>{R.hidden=!0},1e3)}function X(i){ee=i,ne.hidden=!i,e.classList.toggle("terminal-copy-mode-active",i),i&&s.focus()}function Ge(){X(!ee)}function Pt(i){N||i.button!==0||te||(ee||i.shiftKey)&&(i.preventDefault(),i.stopPropagation(),te=!0,w=Ze(i.clientX,i.clientY),L=w,s.selectCells(w.col,w.row,L.col,L.row),document.addEventListener("mousemove",_e,!0),document.addEventListener("mouseup",ze,!0))}function _e(i){N||!te||!w||(i.preventDefault(),i.stopPropagation(),L=Ze(i.clientX,i.clientY),s.selectCells(w.col,w.row,L.col,L.row))}function ze(i){if(N||!te||!w||!L)return;i.preventDefault(),i.stopPropagation(),document.removeEventListener("mousemove",_e,!0),document.removeEventListener("mouseup",ze,!0),te=!1;let a=s.getCellsText(w.col,w.row,L.col,L.row);w=null,L=null,s.clearSelection(),X(!1),a&&(R.textContent="\u5DF2\u590D\u5236",Le(a).then(Ee)),s.focus()}e.addEventListener("mousedown",Pt,!0),document.addEventListener("keydown",_t,!0);function _t(i){if(!(N||!s.isFocused()||i.defaultPrevented||i.isComposing)){if(ee){if(i.key==="Escape"){i.preventDefault(),i.stopPropagation(),w=null,L=null,s.clearSelection(),X(!1);return}if(i.key==="Enter"||(i.ctrlKey||i.metaKey)&&i.code==="KeyC"){i.preventDefault(),i.stopPropagation(),Le(s.getScreenText()).then(Ee),X(!1);return}}if(i.altKey&&i.code==="KeyC"&&!i.ctrlKey&&!i.metaKey){if(i.preventDefault(),i.stopPropagation(),w&&L){let a=s.getCellsText(w.col,w.row,L.col,L.row);w=null,L=null,s.clearSelection(),X(!1),a&&(R.textContent="Copied",Le(a).then(Ee))}else{let a=s.getSelection();a?(s.clearSelection(),R.textContent="Copied",Le(a).then(Ee)):Ge()}return}if((i.ctrlKey||i.metaKey)&&i.code==="KeyV"){i.preventDefault(),i.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){let a=await navigator.clipboard.read();for(let d of a)for(let f of d.types)if(Xe(f)){let b=await d.getType(f);await Pe(b);return}}}catch{}try{let a=await navigator.clipboard?.readText();a&&s.pasteText(Qe(a))}catch{}})();return}}}let xe=0;function Qe(i){return i.split(`\r
6
6
  `).join(`
7
7
  `).split(`
8
- `).join("\r")}async function _t(i){let s=$t(i.clipboardData);if(s){i.preventDefault(),i.stopPropagation();let b=Date.now();if(b-xe<50)return;xe=b,await Pe(s);return}let d=i.clipboardData?.getData("text/plain");if(!d)return;i.preventDefault(),i.stopPropagation();let f=Date.now();f-xe<50||(xe=f,a.pasteText(Qe(d)))}let ae=0;function jt(i){i.preventDefault(),ae++,Je(i.dataTransfer)&&e.classList.add("terminal-drag-over")}function Ft(i){i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="copy")}function Yt(i){i.preventDefault(),ae--,ae<=0&&(ae=0,e.classList.remove("terminal-drag-over"))}async function Wt(i){i.preventDefault(),ae=0,e.classList.remove("terminal-drag-over");let s=Je(i.dataTransfer);s&&await Pe(s)}function et(i){!It||i.key!=="Escape"||ee||i.defaultPrevented||i.repeat||i.metaKey||i.ctrlKey||i.altKey||a.isFocused()&&(i.preventDefault(),i.stopPropagation(),we("\x1B"))}e.addEventListener("paste",_t),e.addEventListener("dragenter",jt),e.addEventListener("dragover",Ft),e.addEventListener("dragleave",Yt),e.addEventListener("drop",Wt),document.addEventListener("keydown",et,!0);function qt(i){if(i.touches.length!==1){l=null;return}let s=i.touches[0];s&&(O(),l={startX:s.clientX,startY:s.clientY,lastX:s.clientX,lastY:s.clientY,lastT:performance.now(),velocity:0,scrolling:!1},i.stopPropagation())}function Ut(i){if(!l||i.touches.length!==1)return;let s=i.touches[0];if(!s)return;let d=s.clientY-l.startY,f=s.clientX-l.startX;if(!l.scrolling){if(Math.abs(d)<8||Math.abs(d)<Math.abs(f))return;l.scrolling=!0,K=Date.now()+500}i.preventDefault(),i.stopPropagation();let b=performance.now(),I=s.clientY-l.lastY,Y=b-l.lastT;Y>0&&(l.velocity=I/Y),Xt(-I),l.lastX=s.clientX,l.lastY=s.clientY,l.lastT=b}function Ot(i){if(!l)return;let s=l.scrolling,d=l.velocity;if(l=null,i.stopPropagation(),!s){a.focus();return}K=Date.now()+500,i.preventDefault(),d&&Ne(d)}function Kt(i){l=null,O(),i.stopPropagation()}function Vt(i){i.pointerType==="touch"&&Date.now()<K&&(i.preventDefault(),i.stopPropagation())}function Xt(i){let s=e.querySelector(".xterm-rows > div"),d=s?s.getBoundingClientRect().height:16,f=d>0?Math.round(i/d):i>0?1:-1;f===0&&(f=i>0?1:-1),a.scrollLines(f)}e.addEventListener("touchstart",qt,{passive:!0,capture:!0}),e.addEventListener("touchmove",Ut,{passive:!1,capture:!0}),e.addEventListener("touchend",Ot,{passive:!1,capture:!0}),e.addEventListener("touchcancel",Kt,{passive:!0,capture:!0}),e.addEventListener("pointerup",Vt,!0);function tt(){T()}window.addEventListener("resize",tt),window.visualViewport?.addEventListener("resize",T),window.visualViewport?.addEventListener("scroll",T);let nt=new ResizeObserver(()=>T());nt.observe(e),document.fonts?.ready.then(()=>{T(),setTimeout(T,50),setTimeout(T,200)}),e.addEventListener("focusin",Rt,!0);async function Jt(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(i=>setTimeout(i,1e3))])}catch{}}return requestAnimationFrame(()=>{F()&&be(),(async()=>(await Jt(),F()&&j({type:"resize",cols:a.cols,rows:a.rows}),Ve(),T()))()}),{destroy(){if(N=!0,O(),X(!1),ie&&clearTimeout(ie),document.removeEventListener("mousemove",ze,!0),document.removeEventListener("mouseup",_e,!0),o){try{o.close(1e3,"session switch")}catch{}o=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",tt),nt.disconnect(),document.removeEventListener("keydown",et,!0)},focus(){a.focus()},sendInput(i){we(i)},toggleCopyMode(){Ge()}}})()}var le=window.__TMUX_WEB_SHELL__,v=null,y=null,at=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,x=at;window.__tmuxWebScopeAgent=at;var Fe="sessions",P="",Ce="",Te="",st="";function M(e){return x?"/a/"+encodeURIComponent(x)+e:e}var h=document.getElementById("sidebar-content"),W=document.getElementById("main-placeholder"),S=document.getElementById("terminal-container"),re=document.getElementById("file-editor"),nn=document.getElementById("fe-path"),D=document.getElementById("fe-status"),ce=document.getElementById("fe-content"),q=document.getElementById("fe-save"),an=document.getElementById("fe-delete"),sn=document.getElementById("fe-back"),ot=document.getElementById("fe-new-name"),on=document.getElementById("fe-new-btn"),Ye=document.getElementById("settings-backdrop"),lt=document.getElementById("settings-popover"),rt=document.querySelector(".sidebar");function ln(){return window.matchMedia("(max-width: 640px)").matches}function We(){ln()&&rt.classList.add("collapsed")}function ct(){rt.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{ct(),dt("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{ct(),dt("files")});function dt(e){Fe=e,document.querySelectorAll(".mode-btn").forEach(n=>n.classList.remove("active"));let t=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");t&&t.classList.add("active"),e==="sessions"?(qe="",J()):Ln()}var qe="";async function J(){if(Fe!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),n=JSON.stringify({recent:t.recent,agents:t.agents});if(n===qe)return;qe=n,pn(t)}catch{h.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")})}var ut="tmux-web-sidebar-group-collapsed";function pt(){try{return new Set(JSON.parse(localStorage.getItem(ut)||"[]"))}catch{return new Set}}function rn(e){try{localStorage.setItem(ut,JSON.stringify([...e]))}catch{}}function cn(e,t,n){if(!e)return"\u2026";let a=n&&(e===n||e.startsWith(n+"/"))?"~"+e.slice(n.length):e,o=a.split("/").filter(Boolean);if(o.length===0)return e;for(let r=2;r<=o.length;r++){let c=o.slice(-r).join("/");if(!t.some(l=>!l||l===e?!1:(n&&(l===n||l.startsWith(n+"/"))?"~"+l.slice(n.length):l).split("/").filter(Boolean).slice(-r).join("/")===c))return a.startsWith("~")?c:"\u2026/"+c}return a}function dn(e,t){let n=new Map;for(let r of e){let c=r.path||"";n.has(c)||n.set(c,[]),n.get(c).push(r)}let a=[...n.keys()],o=pt();for(let[r,c]of n){let l=cn(r,a,t),u=o.has(r),p=document.createElement("div");p.className="session-group-header"+(u?" collapsed":""),p.title=r||"No working directory",p.innerHTML=`<span class="sg-folder">&#128193;</span><span class="sg-label">${m(l)}</span><span class="sg-count">${c.length}</span><span class="sg-arrow">${u?"\u25B8":"\u25BE"}</span>`,p.addEventListener("click",()=>{let k=pt(),H=p.nextElementSibling;k.has(r)?(k.delete(r),p.classList.remove("collapsed"),H?.classList.remove("collapsed"),p.querySelector(".sg-arrow").textContent="\u25BE"):(k.add(r),p.classList.add("collapsed"),H?.classList.add("collapsed"),p.querySelector(".sg-arrow").textContent="\u25B8"),rn(k)});let B=document.createElement("div");B.className="session-group-body"+(u?" collapsed":"");for(let k of c)B.appendChild(un(k));h.appendChild(p),h.appendChild(B)}}function un(e){let t=document.createElement("div");t.className="session-item"+(e.name===y&&!x?" 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 zt(i){let a=$t(i.clipboardData);if(a){i.preventDefault(),i.stopPropagation();let b=Date.now();if(b-xe<50)return;xe=b,await Pe(a);return}let d=i.clipboardData?.getData("text/plain");if(!d)return;i.preventDefault(),i.stopPropagation();let f=Date.now();f-xe<50||(xe=f,s.pasteText(Qe(d)))}let ie=0;function jt(i){i.preventDefault(),ie++,Je(i.dataTransfer)&&e.classList.add("terminal-drag-over")}function Ft(i){i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="copy")}function Wt(i){i.preventDefault(),ie--,ie<=0&&(ie=0,e.classList.remove("terminal-drag-over"))}async function Yt(i){i.preventDefault(),ie=0,e.classList.remove("terminal-drag-over");let a=Je(i.dataTransfer);a&&await Pe(a)}function et(i){!It||i.key!=="Escape"||ee||i.defaultPrevented||i.repeat||i.metaKey||i.ctrlKey||i.altKey||s.isFocused()&&(i.preventDefault(),i.stopPropagation(),we("\x1B"))}e.addEventListener("paste",zt),e.addEventListener("dragenter",jt),e.addEventListener("dragover",Ft),e.addEventListener("dragleave",Wt),e.addEventListener("drop",Yt),document.addEventListener("keydown",et,!0);function Ut(i){if(i.touches.length!==1){l=null;return}let a=i.touches[0];a&&(O(),l={startX:a.clientX,startY:a.clientY,lastX:a.clientX,lastY:a.clientY,lastT:performance.now(),velocity:0,scrolling:!1},i.stopPropagation())}function qt(i){if(!l||i.touches.length!==1)return;let a=i.touches[0];if(!a)return;let d=a.clientY-l.startY,f=a.clientX-l.startX;if(!l.scrolling){if(Math.abs(d)<8||Math.abs(d)<Math.abs(f))return;l.scrolling=!0,K=Date.now()+500}i.preventDefault(),i.stopPropagation();let b=performance.now(),I=a.clientY-l.lastY,W=b-l.lastT;W>0&&(l.velocity=I/W),Xt(-I),l.lastX=a.clientX,l.lastY=a.clientY,l.lastT=b}function Ot(i){if(!l)return;let a=l.scrolling,d=l.velocity;if(l=null,i.stopPropagation(),!a){s.focus();return}K=Date.now()+500,i.preventDefault(),d&&Ne(d)}function Kt(i){l=null,O(),i.stopPropagation()}function Vt(i){i.pointerType==="touch"&&Date.now()<K&&(i.preventDefault(),i.stopPropagation())}function Xt(i){let a=e.querySelector(".xterm-rows > div"),d=a?a.getBoundingClientRect().height:16,f=d>0?Math.round(i/d):i>0?1:-1;f===0&&(f=i>0?1:-1),s.scrollLines(f)}e.addEventListener("touchstart",Ut,{passive:!0,capture:!0}),e.addEventListener("touchmove",qt,{passive:!1,capture:!0}),e.addEventListener("touchend",Ot,{passive:!1,capture:!0}),e.addEventListener("touchcancel",Kt,{passive:!0,capture:!0}),e.addEventListener("pointerup",Vt,!0);function tt(){M()}window.addEventListener("resize",tt),window.visualViewport?.addEventListener("resize",M),window.visualViewport?.addEventListener("scroll",M);let nt=new ResizeObserver(()=>M());nt.observe(e),document.fonts?.ready.then(()=>{M(),setTimeout(M,50),setTimeout(M,200)}),e.addEventListener("focusin",Rt,!0);async function Jt(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(i=>setTimeout(i,1e3))])}catch{}}return requestAnimationFrame(()=>{F()&&be(),(async()=>(await Jt(),F()&&j({type:"resize",cols:s.cols,rows:s.rows}),Ve(),M()))()}),{destroy(){if(N=!0,O(),X(!1),se&&clearTimeout(se),document.removeEventListener("mousemove",_e,!0),document.removeEventListener("mouseup",ze,!0),o){try{o.close(1e3,"session switch")}catch{}o=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",tt),nt.disconnect(),document.removeEventListener("keydown",et,!0)},focus(){s.focus()},sendInput(i){we(i)},toggleCopyMode(){Ge()}}})()}var le=window.__TMUX_WEB_SHELL__,v=null,y=null,it=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,x=it;window.__tmuxWebScopeAgent=it;var Fe="sessions",P="",Ce="",Me="",at="";function T(e){return x?"/a/"+encodeURIComponent(x)+e:e}var h=document.getElementById("sidebar-content"),Y=document.getElementById("main-placeholder"),B=document.getElementById("terminal-container"),re=document.getElementById("file-editor"),nn=document.getElementById("fe-path"),D=document.getElementById("fe-status"),ce=document.getElementById("fe-content"),U=document.getElementById("fe-save"),sn=document.getElementById("fe-delete"),an=document.getElementById("fe-back"),ot=document.getElementById("fe-new-name"),on=document.getElementById("fe-new-btn"),We=document.getElementById("settings-backdrop"),lt=document.getElementById("settings-popover"),rt=document.querySelector(".sidebar");function ln(){return window.matchMedia("(max-width: 640px)").matches}function Ye(){ln()&&rt.classList.add("collapsed")}function ct(){rt.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{ct(),dt("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{ct(),dt("files")});function dt(e){Fe=e,document.querySelectorAll(".mode-btn").forEach(n=>n.classList.remove("active"));let t=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");t&&t.classList.add("active"),e==="sessions"?(Ue="",J()):Ln()}var Ue="";async function J(){if(Fe!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),n=JSON.stringify({recent:t.recent,agents:t.agents});if(n===Ue)return;Ue=n,pn(t)}catch{h.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")})}var ut="tmux-web-sidebar-group-collapsed";function pt(){try{return new Set(JSON.parse(localStorage.getItem(ut)||"[]"))}catch{return new Set}}function rn(e){try{localStorage.setItem(ut,JSON.stringify([...e]))}catch{}}function cn(e,t,n){if(!e)return"\u2026";let s=n&&(e===n||e.startsWith(n+"/"))?"~"+e.slice(n.length):e,o=s.split("/").filter(Boolean);if(o.length===0)return e;for(let r=1;r<=o.length;r++){let c=o.slice(-r).join("/");if(!t.some(l=>!l||l===e?!1:(n&&(l===n||l.startsWith(n+"/"))?"~"+l.slice(n.length):l).split("/").filter(Boolean).slice(-r).join("/")===c))return c}return s}function dn(e,t){let n=new Map;for(let r of e){let c=r.path||"";n.has(c)||n.set(c,[]),n.get(c).push(r)}let s=[...n.keys()],o=pt();for(let[r,c]of n){let l=cn(r,s,t),u=o.has(r),p=document.createElement("div");p.className="session-group-header"+(u?" collapsed":""),p.title=r||"No working directory",p.innerHTML=`<span class="sg-folder">&#128193;</span><span class="sg-label">${m(l)}</span>`,p.addEventListener("click",()=>{let k=pt(),H=p.nextElementSibling;k.has(r)?(k.delete(r),p.classList.remove("collapsed"),H?.classList.remove("collapsed")):(k.add(r),p.classList.add("collapsed"),H?.classList.add("collapsed")),rn(k)});let S=document.createElement("div");S.className="session-group-body"+(u?" collapsed":"");for(let k of c)S.appendChild(un(k));h.appendChild(p),h.appendChild(S)}}function un(e){let t=document.createElement("div");t.className="session-item"+(e.name===y&&!x?" 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>
9
9
  <span>${m(e.name)}</span>
10
10
  <button class="session-edit-btn" data-session="${m(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>
11
- `,t.addEventListener("click",a=>{a.target.closest(".session-edit-btn")||de(e.name)});let n=t.querySelector(".session-edit-btn");return n&&n.addEventListener("click",a=>{a.stopPropagation(),Tn(e.name,n)}),t}function pn(e){h.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';let t=e.recent||[],n=document.createElement("div");n.className="sidebar-section-label"+(x?" clickable":""),n.textContent=x?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",x&&(n.title="Back to hub",n.addEventListener("click",()=>{window.location.href="/"})),h.appendChild(n),dn(t,e.home);let a=e.agents||[];for(let o of a){if(!o.sessions||o.sessions.length===0)continue;let r=o.agentId===x,c=document.createElement("div");c.className="sidebar-section-label machine-label"+(o.online?"":" agent-offline-label")+(!r&&o.online?" clickable":""),c.textContent=o.agentName+(o.online?"":" (offline)"),!r&&o.online&&(c.title="\u6253\u5F00 "+o.agentName,c.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(o.agentId)+"/"})),h.appendChild(c);for(let l of o.sessions){let u=document.createElement("div");u.className="session-item"+(l.name===y&&x===o.agentId?" active":"")+(o.online?"":" session-offline"),u.setAttribute("data-session",l.name),u.setAttribute("data-agent",o.agentId),u.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${l.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>
12
- <span>${m(l.name)}</span><span class="meta">${o.online?"":"offline"}</span>`,o.online&&u.addEventListener("click",p=>{p.target.closest(".session-edit-btn")||de(l.name,o.agentId)}),h.appendChild(u)}}}function m(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function de(e,t){if(!(y===e&&v&&x===(t||null))){re.style.display="none",W.style.display="none",S.style.display="",S.classList.add("terminal-pending"),We(),v&&(Re(),v.destroy(),v=null),y=e,x=t||null,window.__tmuxWebScopeAgent=x,window.__tmuxWebCurrentSession=y;for(let n of h.querySelectorAll(".session-item"))n.classList.toggle("active",n.getAttribute("data-session")===e&&(n.getAttribute("data-agent")||null)===x);try{v=await tn(S,e,{terminal:le.terminal,scrollback:le.scrollback,theme:le.theme,wsBase:x?"/ws/a/"+encodeURIComponent(x):le.wsBase||"/ws"}),Et()}catch(n){console.error("[shell] terminal init failed:",n);let a=n&&typeof n=="object"&&"message"in n?n.message:String(n);S.textContent="Failed to open terminal for "+e+": "+a,S.classList.remove("terminal-pending")}}}var Me=[],g=null,ft=!1;function fn(e){if(!g||!g.files.length)return null;let t=g.repoRoot;if(!t||!e.startsWith(t))return null;let n=e.slice(t.length+1);for(let a of g.files)if(a.path===n)return a.status;return null}async function mn(e){ft=!0;try{let t=await fetch(M("/api/git/status?path="+encodeURIComponent(e)));t.ok?g=await t.json():g=null}catch{g=null}finally{ft=!1}}function hn(){if(!g||!g.branch)return"";let{branch:e,linesAdded:t,linesRemoved:n}=g,a=`<div class="sidebar-git"><div class="git-branch-badge">
11
+ `,t.addEventListener("click",s=>{s.target.closest(".session-edit-btn")||de(e.name)});let n=t.querySelector(".session-edit-btn");return n&&n.addEventListener("click",s=>{s.stopPropagation(),Mn(e.name,n)}),t}function pn(e){h.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';let t=e.recent||[],n=document.createElement("div");n.className="sidebar-section-label"+(x?" clickable":""),n.textContent=x?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",x&&(n.title="Back to hub",n.addEventListener("click",()=>{window.location.href="/"})),h.appendChild(n),dn(t,e.home);let s=e.agents||[];for(let o of s){if(!o.sessions||o.sessions.length===0)continue;let r=o.agentId===x,c=document.createElement("div");c.className="sidebar-section-label machine-label"+(o.online?"":" agent-offline-label")+(!r&&o.online?" clickable":""),c.textContent=o.agentName+(o.online?"":" (offline)"),!r&&o.online&&(c.title="\u6253\u5F00 "+o.agentName,c.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(o.agentId)+"/"})),h.appendChild(c);for(let l of o.sessions){let u=document.createElement("div");u.className="session-item"+(l.name===y&&x===o.agentId?" active":"")+(o.online?"":" session-offline"),u.setAttribute("data-session",l.name),u.setAttribute("data-agent",o.agentId),u.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${l.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>
12
+ <span>${m(l.name)}</span><span class="meta">${o.online?"":"offline"}</span>`,o.online&&u.addEventListener("click",p=>{p.target.closest(".session-edit-btn")||de(l.name,o.agentId)}),h.appendChild(u)}}}function m(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function de(e,t){if(!(y===e&&v&&x===(t||null))){re.style.display="none",Y.style.display="none",B.style.display="",B.classList.add("terminal-pending"),Ye(),v&&(Re(),v.destroy(),v=null),y=e,x=t||null,window.__tmuxWebScopeAgent=x,window.__tmuxWebCurrentSession=y;for(let n of h.querySelectorAll(".session-item"))n.classList.toggle("active",n.getAttribute("data-session")===e&&(n.getAttribute("data-agent")||null)===x);try{v=await tn(B,e,{terminal:le.terminal,scrollback:le.scrollback,theme:le.theme,wsBase:x?"/ws/a/"+encodeURIComponent(x):le.wsBase||"/ws"}),Et()}catch(n){console.error("[shell] terminal init failed:",n);let s=n&&typeof n=="object"&&"message"in n?n.message:String(n);B.textContent="Failed to open terminal for "+e+": "+s,B.classList.remove("terminal-pending")}}}var Te=[],g=null,ft=!1;function fn(e){if(!g||!g.files.length)return null;let t=g.repoRoot;if(!t||!e.startsWith(t))return null;let n=e.slice(t.length+1);for(let s of g.files)if(s.path===n)return s.status;return null}async function mn(e){ft=!0;try{let t=await fetch(T("/api/git/status?path="+encodeURIComponent(e)));t.ok?g=await t.json():g=null}catch{g=null}finally{ft=!1}}function hn(){if(!g||!g.branch)return"";let{branch:e,linesAdded:t,linesRemoved:n}=g,s=`<div class="sidebar-git"><div class="git-branch-badge">
13
13
  <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>
14
- ${m(e)}</div>`;return(t>0||n>0)&&(a+=`<div class="git-diff-stats">+<span class="add">${t}</span> <span class="del">-${n}</span></div>`),a+"</div>"}h.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&Z&&g&&(e.stopPropagation(),yt())});var ue=document.getElementById("header-git"),mt=document.getElementById("git-diff-view"),ht=document.getElementById("gd-path"),Be=document.getElementById("gd-status"),Se=document.getElementById("gd-content"),vn=document.getElementById("gd-back"),Z=null;function pe(e){if(!e||!e.branch){ue.style.display="none",Z=null;return}Z=e.repoRoot;let{branch:t,linesAdded:n,linesRemoved:a}=e,o=`<span class="branch">${m(t)}</span>`;(n>0||a>0)&&(o+=`<span class="sep">\xB7</span>+<span class="diff-add">${n}</span> <span class="diff-del">-${a}</span>`),ue.innerHTML=o,ue.style.display="block"}ue.addEventListener("click",e=>{Z&&g&&(e.stopPropagation(),yt())});var E=document.getElementById("git-popover"),Ie=document.getElementById("git-popover-backdrop");function Ue(){let e=ue.getBoundingClientRect();E.style.top=e.bottom+4+"px",E.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function vt(){let e=Z,t=document.getElementById("git-popover-browse");t&&t.addEventListener("click",()=>{if(He(),e){Fe="files",document.querySelectorAll(".mode-btn").forEach(a=>a.classList.remove("active"));let n=document.getElementById("mode-files");n&&n.classList.add("active"),z(e)}})}var gt="";function yt(){if(!g)return;let e=g.files||[];if(!e.length)E.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
15
- <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 n=0;n<e.length;n++){let a=e[n],o=a.additions||0,r=a.deletions||0,c="";switch(a.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="${n}">
16
- ${c}<span class="file-path">${m(a.path)}</span>
14
+ ${m(e)}</div>`;return(t>0||n>0)&&(s+=`<div class="git-diff-stats">+<span class="add">${t}</span> <span class="del">-${n}</span></div>`),s+"</div>"}h.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&Z&&g&&(e.stopPropagation(),yt())});var ue=document.getElementById("header-git"),mt=document.getElementById("git-diff-view"),ht=document.getElementById("gd-path"),Se=document.getElementById("gd-status"),Be=document.getElementById("gd-content"),vn=document.getElementById("gd-back"),Z=null;function pe(e){if(!e||!e.branch){ue.style.display="none",Z=null;return}Z=e.repoRoot;let{branch:t,linesAdded:n,linesRemoved:s}=e,o=`<span class="branch">${m(t)}</span>`;(n>0||s>0)&&(o+=`<span class="sep">\xB7</span>+<span class="diff-add">${n}</span> <span class="diff-del">-${s}</span>`),ue.innerHTML=o,ue.style.display="block"}ue.addEventListener("click",e=>{Z&&g&&(e.stopPropagation(),yt())});var E=document.getElementById("git-popover"),Ie=document.getElementById("git-popover-backdrop");function qe(){let e=ue.getBoundingClientRect();E.style.top=e.bottom+4+"px",E.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function vt(){let e=Z,t=document.getElementById("git-popover-browse");t&&t.addEventListener("click",()=>{if(He(),e){Fe="files",document.querySelectorAll(".mode-btn").forEach(s=>s.classList.remove("active"));let n=document.getElementById("mode-files");n&&n.classList.add("active"),_(e)}})}var gt="";function yt(){if(!g)return;let e=g.files||[];if(!e.length)E.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
15
+ <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 n=0;n<e.length;n++){let s=e[n],o=s.additions||0,r=s.deletions||0,c="";switch(s.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="${n}">
16
+ ${c}<span class="file-path">${m(s.path)}</span>
17
17
  <span class="file-add">${o>0?"+"+o:""}</span>
18
18
  <span class="file-del">${r>0?"-"+r:""}</span>
19
- </div>`}t+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',gt=t,E.innerHTML=t,E.querySelectorAll(".git-popover-item").forEach(n=>{let a=parseInt(n.dataset.idx||"0",10),o=e[a];!o||o.status==="D"||(n.classList.add("clickable"),n.style.cursor="pointer",n.addEventListener("click",()=>bt(o.path)))})}Ue(),E.classList.add("open"),Ie.classList.add("open"),vt()}function gn(){return window.innerWidth>=1024}function wt(e,t){let n=(e+(t&&e?`
19
+ </div>`}t+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',gt=t,E.innerHTML=t,E.querySelectorAll(".git-popover-item").forEach(n=>{let s=parseInt(n.dataset.idx||"0",10),o=e[s];!o||o.status==="D"||(n.classList.add("clickable"),n.style.cursor="pointer",n.addEventListener("click",()=>bt(o.path)))})}qe(),E.classList.add("open"),Ie.classList.add("open"),vt()}function gn(){return window.innerWidth>=1024}function wt(e,t){let n=(e+(t&&e?`
20
20
  `:"")+t).split(`
21
- `),a="",o=0,r=0;for(let c of n){let l=c;if(l.startsWith("@@")){let u=l.match(/@@\s+-(\d+)[^+]*\+(\d+)/);u&&(o=parseInt(u[1],10)-1,r=parseInt(u[2],10)-1),a+=`<div class="diff-line hunk"><span class="ln-body">${m(l)}</span></div>`;continue}if(l.startsWith("diff --git")||l.startsWith("index ")||l.startsWith("--- ")||l.startsWith("+++ ")||l.startsWith("new file")||l.startsWith("deleted file")){l.startsWith("diff --git")&&(a+=`<div class="diff-line header"><span class="ln-body">${m(l)}</span></div>`);continue}if(l.startsWith("+"))r++,a+=`<div class="diff-line add"><span class="ln-no">${r}</span><span class="ln-body">${m(l)}</span></div>`;else if(l.startsWith("-"))o++,a+=`<div class="diff-line del"><span class="ln-no">${o}</span><span class="ln-body">${m(l)}</span></div>`;else if(l.startsWith("\\"))a+=`<div class="diff-line"><span class="ln-body">${m(l)}</span></div>`;else{if(!l&&!o&&!r)continue;o++,r++,a+=`<div class="diff-line"><span class="ln-no">${o}</span><span class="ln-no" style="margin-right:12px">${r}</span><span class="ln-body">${m(l)}</span></div>`}}return{html:a,lineCount:n.length}}var De=null;async function bt(e){let t=Z;if(t)if(He(),gn()){S.style.display="none",v&&(Re(),v.destroy(),v=null,De=y,y=null),pe(null),re.style.display="none",W.style.display="none",mt.style.display="flex",ht.textContent=e,Be.textContent="Loading\u2026",Se.innerHTML="";try{let n=await fetch(M("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!n.ok)throw new Error(await n.text());let a=await n.json();wn(e,a.diff,a.stagedDiff)}catch(n){let a=n instanceof Error?n.message:String(n);Be.textContent="Error",Se.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${m(a)}</div>`}}else{E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
21
+ `),s="",o=0,r=0;for(let c of n){let l=c;if(l.startsWith("@@")){let u=l.match(/@@\s+-(\d+)[^+]*\+(\d+)/);u&&(o=parseInt(u[1],10)-1,r=parseInt(u[2],10)-1),s+=`<div class="diff-line hunk"><span class="ln-body">${m(l)}</span></div>`;continue}if(l.startsWith("diff --git")||l.startsWith("index ")||l.startsWith("--- ")||l.startsWith("+++ ")||l.startsWith("new file")||l.startsWith("deleted file")){l.startsWith("diff --git")&&(s+=`<div class="diff-line header"><span class="ln-body">${m(l)}</span></div>`);continue}if(l.startsWith("+"))r++,s+=`<div class="diff-line add"><span class="ln-no">${r}</span><span class="ln-body">${m(l)}</span></div>`;else if(l.startsWith("-"))o++,s+=`<div class="diff-line del"><span class="ln-no">${o}</span><span class="ln-body">${m(l)}</span></div>`;else if(l.startsWith("\\"))s+=`<div class="diff-line"><span class="ln-body">${m(l)}</span></div>`;else{if(!l&&!o&&!r)continue;o++,r++,s+=`<div class="diff-line"><span class="ln-no">${o}</span><span class="ln-no" style="margin-right:12px">${r}</span><span class="ln-body">${m(l)}</span></div>`}}return{html:s,lineCount:n.length}}var De=null;async function bt(e){let t=Z;if(t)if(He(),gn()){B.style.display="none",v&&(Re(),v.destroy(),v=null,De=y,y=null),pe(null),re.style.display="none",Y.style.display="none",mt.style.display="flex",ht.textContent=e,Se.textContent="Loading\u2026",Be.innerHTML="";try{let n=await fetch(T("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!n.ok)throw new Error(await n.text());let s=await n.json();wn(e,s.diff,s.stagedDiff)}catch(n){let s=n instanceof Error?n.message:String(n);Se.textContent="Error",Be.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${m(s)}</div>`}}else{E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
22
22
  <button class="diff-back">\u2190 Back</button>
23
23
  <span class="diff-filename">${m(e)}</span>
24
24
  <span class="diff-loading">Loading\u2026</span>
25
- </div></div>`,Ue(),E.classList.add("open"),Ie.classList.add("open");try{let n=await fetch(M("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!n.ok)throw new Error(await n.text());let a=await n.json();yn(e,a.diff,a.stagedDiff)}catch(n){let a=n instanceof Error?n.message:String(n);E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
25
+ </div></div>`,qe(),E.classList.add("open"),Ie.classList.add("open");try{let n=await fetch(T("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!n.ok)throw new Error(await n.text());let s=await n.json();yn(e,s.diff,s.stagedDiff)}catch(n){let s=n instanceof Error?n.message:String(n);E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
26
26
  <button class="diff-back">\u2190 Back</button>
27
27
  <span class="diff-filename">${m(e)}</span>
28
- </div><div class="diff-empty">Error loading diff: ${m(a)}</div></div>`}}}function yn(e,t,n){if(!t&&!n){E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
28
+ </div><div class="diff-empty">Error loading diff: ${m(s)}</div></div>`}}}function yn(e,t,n){if(!t&&!n){E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
29
29
  <button class="diff-back">\u2190 Back</button>
30
30
  <span class="diff-filename">${m(e)}</span>
31
- </div><div class="diff-empty">No diff content available</div></div>`;return}let{html:a,lineCount:o}=wt(t,n);E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
31
+ </div><div class="diff-empty">No diff content available</div></div>`;return}let{html:s,lineCount:o}=wt(t,n);E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
32
32
  <button class="diff-back">\u2190 Back</button>
33
33
  <span class="diff-filename">${m(e)}</span>
34
34
  <span class="diff-filesize">${o} lines</span>
35
- </div><div class="diff-content">${a}</div></div>`,E.querySelector(".diff-back")?.addEventListener("click",()=>{E.innerHTML=gt,Ue(),g&&E.querySelectorAll(".git-popover-item").forEach(r=>{let c=parseInt(r.dataset.idx||"0",10),l=g.files[c];!l||l.status==="D"||(r.style.cursor="pointer",r.addEventListener("click",()=>bt(l.path)))}),vt()})}function wn(e,t,n){if(!t&&!n){Be.textContent="No diff",Se.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}let{html:a,lineCount:o}=wt(t,n);ht.textContent=e,Be.textContent=o+" lines",Se.innerHTML=a}function bn(){mt.style.display="none",De?(S.style.display="",S.classList.add("terminal-pending"),de(De),De=null):y?(S.style.display="",S.classList.add("terminal-pending"),Et()):W.style.display="flex"}vn.addEventListener("click",bn);function He(){E.classList.remove("open"),Ie.classList.remove("open")}Ie.addEventListener("click",He),document.addEventListener("keydown",e=>{e.key==="Escape"&&(He(),$e())});async function Lt(e){try{let t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){let n=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(n.ok){let a=await n.json();g=a,pe(a);return}}}catch{}g=null,pe(null)}var Ae=null;function Et(){Re(),y&&(Lt(y),Ae=setInterval(()=>{y&&Lt(y)},3e4))}function Re(){Ae&&(clearInterval(Ae),Ae=null)}function Ln(){if(Me=le.fsRoots||[],Me.length===0){if(y){En(y);return}h.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}h.innerHTML="";for(let e of Me){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> ${m(e)}`,t.addEventListener("click",()=>z(e)),h.appendChild(t)}}async function En(e){h.innerHTML='<div class="file-tree-empty">Loading...</div>';try{let t=await(await fetch(M("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?z(t.path):h.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{h.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function z(e){P=e,h.innerHTML='<div class="file-tree-empty">Loading...</div>';let t=mn(e);try{let n=await(await fetch(M("/api/fs/list?path="+encodeURIComponent(e)))).json();await t,h.innerHTML="",pe(g),h.innerHTML+=hn();let a=xn(e);if(a&&!Me.some(r=>e===r)){let r=document.createElement("div");r.className="file-tree-item",r.innerHTML="..",r.addEventListener("click",()=>z(a)),h.appendChild(r)}if(n.dirs)for(let r of n.dirs){let c=r.split("/").pop()||r.split("\\").pop(),l=document.createElement("div");l.className="file-tree-item",l.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> ${m(c)}`,l.addEventListener("click",()=>z(r)),h.appendChild(l)}else h.innerHTML="";let o=n.files||[];for(let r of o){let c=r.split("/").pop()||r.split("\\").pop(),l=fn(r),u="",p="";if(l)switch(l){case"M":u="git-mod",p='<span class="git-file-status M">M</span>';break;case"A":u="git-add",p='<span class="git-file-status A">A</span>';break;case"D":u="git-del",p='<span class="git-file-status D">D</span>';break;case"?":u="git-untracked",p='<span class="git-file-status ?">?</span>';break;case"R":u="git-mod",p='<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> ${p}${m(c)}`,B.addEventListener("click",()=>kn(r)),h.appendChild(B)}}catch{h.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function xn(e){let t=e.lastIndexOf("/");return t<=0?null:e.substring(0,t)}async function kn(e){Ce=e,S.style.display="none",v&&(Re(),v.destroy(),v=null,y=null),pe(null),We(),W.style.display="none",re.style.display="flex",nn.textContent=e,D.textContent="Loading...",q.style.display="none";try{let t=await fetch(M("/api/file?path="+encodeURIComponent(e)));if(!t.ok){let a=await t.json();D.textContent=a.error||"Failed to load",ce.value="";return}let n=await t.json();ce.value=n.content,Te=n.content,st=n.content,D.textContent=n.size+" bytes",q.style.display=""}catch{D.textContent="Failed to load",ce.value=""}}ce.addEventListener("input",()=>{Te=ce.value}),q.addEventListener("click",async()=>{q.textContent="Saving...",q.disabled=!0;try{let e=await fetch(M("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:Ce,content:Te})});if(!e.ok){let t=await e.json();D.textContent=t.error||"Save failed";return}st=Te,D.textContent="Saved"}catch{D.textContent="Save failed"}finally{q.disabled=!1,q.textContent="Save"}}),an.addEventListener("click",async()=>{if(confirm("Delete "+Ce+"?"))try{let e=await fetch(M("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:Ce})});if(!e.ok){let t=await e.json();D.textContent=t.error||"Delete failed";return}re.style.display="none",W.style.display="flex",P&&z(P)}catch{D.textContent="Delete failed"}}),sn.addEventListener("click",()=>{re.style.display="none",W.style.display="flex",P&&z(P)}),on.addEventListener("click",async()=>{let e=ot.value.trim();if(!e)return;let t=P+"/"+e;try{let n=await fetch(M("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})});if(!n.ok){let a=await n.json();D.textContent=a.error||"Create failed";return}ot.value="",P&&z(P)}catch{D.textContent="Create failed"}}),document.getElementById("mode-settings").addEventListener("click",()=>{let e=lt.classList.toggle("open");Ye.classList.toggle("open",e)}),Ye.addEventListener("click",()=>{lt.classList.remove("open"),Ye.classList.remove("open")});var U="",fe=document.createElement("div");fe.className="session-popover-backdrop",document.body.appendChild(fe);var $=document.createElement("div");$.id="session-popover",$.className="session-popover",$.style.display="none",$.innerHTML=`<div class="sp-field">
35
+ </div><div class="diff-content">${s}</div></div>`,E.querySelector(".diff-back")?.addEventListener("click",()=>{E.innerHTML=gt,qe(),g&&E.querySelectorAll(".git-popover-item").forEach(r=>{let c=parseInt(r.dataset.idx||"0",10),l=g.files[c];!l||l.status==="D"||(r.style.cursor="pointer",r.addEventListener("click",()=>bt(l.path)))}),vt()})}function wn(e,t,n){if(!t&&!n){Se.textContent="No diff",Be.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}let{html:s,lineCount:o}=wt(t,n);ht.textContent=e,Se.textContent=o+" lines",Be.innerHTML=s}function bn(){mt.style.display="none",De?(B.style.display="",B.classList.add("terminal-pending"),de(De),De=null):y?(B.style.display="",B.classList.add("terminal-pending"),Et()):Y.style.display="flex"}vn.addEventListener("click",bn);function He(){E.classList.remove("open"),Ie.classList.remove("open")}Ie.addEventListener("click",He),document.addEventListener("keydown",e=>{e.key==="Escape"&&(He(),$e())});async function Lt(e){try{let t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){let n=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(n.ok){let s=await n.json();g=s,pe(s);return}}}catch{}g=null,pe(null)}var Ae=null;function Et(){Re(),y&&(Lt(y),Ae=setInterval(()=>{y&&Lt(y)},3e4))}function Re(){Ae&&(clearInterval(Ae),Ae=null)}function Ln(){if(Te=le.fsRoots||[],Te.length===0){if(y){En(y);return}h.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}h.innerHTML="";for(let e of Te){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> ${m(e)}`,t.addEventListener("click",()=>_(e)),h.appendChild(t)}}async function En(e){h.innerHTML='<div class="file-tree-empty">Loading...</div>';try{let t=await(await fetch(T("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?_(t.path):h.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{h.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function _(e){P=e,h.innerHTML='<div class="file-tree-empty">Loading...</div>';let t=mn(e);try{let n=await(await fetch(T("/api/fs/list?path="+encodeURIComponent(e)))).json();await t,h.innerHTML="",pe(g),h.innerHTML+=hn();let s=xn(e);if(s&&!Te.some(r=>e===r)){let r=document.createElement("div");r.className="file-tree-item",r.innerHTML="..",r.addEventListener("click",()=>_(s)),h.appendChild(r)}if(n.dirs)for(let r of n.dirs){let c=r.split("/").pop()||r.split("\\").pop(),l=document.createElement("div");l.className="file-tree-item",l.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> ${m(c)}`,l.addEventListener("click",()=>_(r)),h.appendChild(l)}else h.innerHTML="";let o=n.files||[];for(let r of o){let c=r.split("/").pop()||r.split("\\").pop(),l=fn(r),u="",p="";if(l)switch(l){case"M":u="git-mod",p='<span class="git-file-status M">M</span>';break;case"A":u="git-add",p='<span class="git-file-status A">A</span>';break;case"D":u="git-del",p='<span class="git-file-status D">D</span>';break;case"?":u="git-untracked",p='<span class="git-file-status ?">?</span>';break;case"R":u="git-mod",p='<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> ${p}${m(c)}`,S.addEventListener("click",()=>kn(r)),h.appendChild(S)}}catch{h.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function xn(e){let t=e.lastIndexOf("/");return t<=0?null:e.substring(0,t)}async function kn(e){Ce=e,B.style.display="none",v&&(Re(),v.destroy(),v=null,y=null),pe(null),Ye(),Y.style.display="none",re.style.display="flex",nn.textContent=e,D.textContent="Loading...",U.style.display="none";try{let t=await fetch(T("/api/file?path="+encodeURIComponent(e)));if(!t.ok){let s=await t.json();D.textContent=s.error||"Failed to load",ce.value="";return}let n=await t.json();ce.value=n.content,Me=n.content,at=n.content,D.textContent=n.size+" bytes",U.style.display=""}catch{D.textContent="Failed to load",ce.value=""}}ce.addEventListener("input",()=>{Me=ce.value}),U.addEventListener("click",async()=>{U.textContent="Saving...",U.disabled=!0;try{let e=await fetch(T("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:Ce,content:Me})});if(!e.ok){let t=await e.json();D.textContent=t.error||"Save failed";return}at=Me,D.textContent="Saved"}catch{D.textContent="Save failed"}finally{U.disabled=!1,U.textContent="Save"}}),sn.addEventListener("click",async()=>{if(confirm("Delete "+Ce+"?"))try{let e=await fetch(T("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:Ce})});if(!e.ok){let t=await e.json();D.textContent=t.error||"Delete failed";return}re.style.display="none",Y.style.display="flex",P&&_(P)}catch{D.textContent="Delete failed"}}),an.addEventListener("click",()=>{re.style.display="none",Y.style.display="flex",P&&_(P)}),on.addEventListener("click",async()=>{let e=ot.value.trim();if(!e)return;let t=P+"/"+e;try{let n=await fetch(T("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})});if(!n.ok){let s=await n.json();D.textContent=s.error||"Create failed";return}ot.value="",P&&_(P)}catch{D.textContent="Create failed"}}),document.getElementById("mode-settings").addEventListener("click",()=>{let e=lt.classList.toggle("open");We.classList.toggle("open",e)}),We.addEventListener("click",()=>{lt.classList.remove("open"),We.classList.remove("open")});var q="",fe=document.createElement("div");fe.className="session-popover-backdrop",document.body.appendChild(fe);var $=document.createElement("div");$.id="session-popover",$.className="session-popover",$.style.display="none",$.innerHTML=`<div class="sp-field">
36
36
  <label>Rename session</label>
37
37
  <input type="text" id="sp-name" />
38
38
  </div>
@@ -41,5 +41,5 @@ var Zt=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function
41
41
  <button class="btn" id="sp-cancel">Cancel</button>
42
42
  </div>
43
43
  <hr class="sp-divider" />
44
- <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild($);function Cn(e){let t=e.getBoundingClientRect();$.style.top=t.bottom+4+"px",$.style.left=Math.max(8,Math.min(t.left,window.innerWidth-240))+"px"}function Tn(e,t){U=e;let n=document.getElementById("sp-name");n.value=e,fe.classList.add("open"),$.style.display="block",Cn(t),setTimeout(()=>n.focus(),50)}function me(){fe.classList.remove("open"),$.style.display="none"}fe.addEventListener("click",me),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===U){me();return}try{if(!(await fetch(M("/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldName:U,newName:e})})).ok)return;me(),J(),y===U&&de(e)}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(confirm('Delete session "'+U+'"?'))try{if(!(await fetch(M("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:U})})).ok)return;me(),y===U&&(v&&(v.destroy(),v=null),y=null,S.style.display="none",W.style.display="flex"),J()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",me);var Mn={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||!v)return;let n=Mn[t.dataset.key];n&&(v.sendInput(n),v.focus())});var A=document.getElementById("mk-input"),xt=document.getElementById("mk-send");function kt(){if(!A||!v)return;let e=A.value;e&&(v.sendInput(e+"\r"),A.value="",A.rows=1,v.focus())}if(A&&(A.addEventListener("input",()=>{A.rows=1;let e=A.value.split(`
45
- `).length;A.rows=Math.min(e,4)}),A.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),kt())})),xt&&xt.addEventListener("click",kt),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 Oe=document.getElementById("process-panel"),he=document.getElementById("proc-list"),Bn=document.getElementById("proc-close"),Ke=document.getElementById("proc-backdrop"),Sn=document.getElementById("header-ram");function In(){he.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(M("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){he.innerHTML='<div class="proc-empty">No processes</div>';return}let t="";for(let n of e){let a=n.rss,o=a<1048576?(a/1024).toFixed(0)+"K":(a/1048576).toFixed(1)+"M";t+='<div class="proc-row" data-pid="'+n.pid+'"><span class="proc-mem">'+n.mem+'%</span><span class="proc-rss">'+o+'</span><span class="proc-cmd" title="'+m(n.command)+'">'+m(n.command)+'</span><button class="proc-kill" title="Kill PID '+n.pid+'">&times;</button></div>'}he.innerHTML=t;for(let n of he.querySelectorAll(".proc-row")){let a=n.querySelector(".proc-kill");a&&a.addEventListener("click",o=>{let r=o.target.closest(".proc-row");!r||!confirm("Kill PID "+r.dataset.pid+"?")||fetch(M("/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(()=>{he.innerHTML='<div class="proc-empty">Failed to load</div>'})}function Dn(){Oe.classList.add("open"),Ke.classList.add("open"),In()}function $e(){Oe.classList.remove("open"),Ke.classList.remove("open")}Sn.addEventListener("click",e=>{e.stopPropagation(),Oe.classList.contains("open")?$e():Dn()}),Bn.addEventListener("click",$e),Ke.addEventListener("click",$e),window.__openSession=de,window.__refreshSidebar=J,J(),We(),setInterval(()=>{document.visibilityState==="visible"&&J()},1e4);
44
+ <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild($);function Cn(e){let t=e.getBoundingClientRect();$.style.top=t.bottom+4+"px",$.style.left=Math.max(8,Math.min(t.left,window.innerWidth-240))+"px"}function Mn(e,t){q=e;let n=document.getElementById("sp-name");n.value=e,fe.classList.add("open"),$.style.display="block",Cn(t),setTimeout(()=>n.focus(),50)}function me(){fe.classList.remove("open"),$.style.display="none"}fe.addEventListener("click",me),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===q){me();return}try{if(!(await fetch(T("/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldName:q,newName:e})})).ok)return;me(),J(),y===q&&de(e)}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(confirm('Delete session "'+q+'"?'))try{if(!(await fetch(T("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:q})})).ok)return;me(),y===q&&(v&&(v.destroy(),v=null),y=null,B.style.display="none",Y.style.display="flex"),J()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",me);var Tn={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||!v)return;let n=Tn[t.dataset.key];n&&(v.sendInput(n),v.focus())});var A=document.getElementById("mk-input"),xt=document.getElementById("mk-send");function kt(){if(!A||!v)return;let e=A.value;e&&(v.sendInput(e+"\r"),A.value="",A.rows=1,v.focus())}if(A&&(A.addEventListener("input",()=>{A.rows=1;let e=A.value.split(`
45
+ `).length;A.rows=Math.min(e,4)}),A.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),kt())})),xt&&xt.addEventListener("click",kt),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 Oe=document.getElementById("process-panel"),he=document.getElementById("proc-list"),Sn=document.getElementById("proc-close"),Ke=document.getElementById("proc-backdrop"),Bn=document.getElementById("header-ram");function In(){he.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(T("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){he.innerHTML='<div class="proc-empty">No processes</div>';return}let t="";for(let n of e){let s=n.rss,o=s<1048576?(s/1024).toFixed(0)+"K":(s/1048576).toFixed(1)+"M";t+='<div class="proc-row" data-pid="'+n.pid+'"><span class="proc-mem">'+n.mem+'%</span><span class="proc-rss">'+o+'</span><span class="proc-cmd" title="'+m(n.command)+'">'+m(n.command)+'</span><button class="proc-kill" title="Kill PID '+n.pid+'">&times;</button></div>'}he.innerHTML=t;for(let n of he.querySelectorAll(".proc-row")){let s=n.querySelector(".proc-kill");s&&s.addEventListener("click",o=>{let r=o.target.closest(".proc-row");!r||!confirm("Kill PID "+r.dataset.pid+"?")||fetch(T("/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(()=>{he.innerHTML='<div class="proc-empty">Failed to load</div>'})}function Dn(){Oe.classList.add("open"),Ke.classList.add("open"),In()}function $e(){Oe.classList.remove("open"),Ke.classList.remove("open")}Bn.addEventListener("click",e=>{e.stopPropagation(),Oe.classList.contains("open")?$e():Dn()}),Sn.addEventListener("click",$e),Ke.addEventListener("click",$e),window.__openSession=de,window.__refreshSidebar=J,J(),Ye(),setInterval(()=>{document.visibilityState==="visible"&&J()},1e4);
@@ -1,17 +1,17 @@
1
- import{initTerminal as Ie}from"./terminal-core.js";const H=window.__TMUX_WEB_SHELL__;let f=null,m=null;const oe=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null;let g=oe;window.__tmuxWebScopeAgent=oe;let Y="sessions",C="",j="",F="",ae="";function y(e){return g?"/a/"+encodeURIComponent(g)+e:e}const p=document.getElementById("sidebar-content"),I=document.getElementById("main-placeholder"),h=document.getElementById("terminal-container"),$=document.getElementById("file-editor"),xe=document.getElementById("fe-path"),w=document.getElementById("fe-status"),R=document.getElementById("fe-content"),x=document.getElementById("fe-save"),Se=document.getElementById("fe-delete"),Me=document.getElementById("fe-back"),le=document.getElementById("fe-new-name"),Te=document.getElementById("fe-new-btn"),Z=document.getElementById("settings-backdrop"),ce=document.getElementById("settings-popover"),re=document.querySelector(".sidebar");function He(){return window.matchMedia("(max-width: 640px)").matches}function Q(){He()&&re.classList.add("collapsed")}function de(){re.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{de(),pe("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{de(),pe("files")});function pe(e){Y=e,document.querySelectorAll(".mode-btn").forEach(t=>t.classList.remove("active"));const n=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");n&&n.classList.add("active"),e==="sessions"?(ee="",M()):Ue()}let ee="";async function M(){if(Y!=="sessions")return;try{const t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents});if(s===ee)return;ee=s,Pe(t)}catch{p.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}const e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>{const n=window.__openNewSessionModal;typeof n=="function"?n():document.getElementById("new-session-modal")?.classList.add("open")})}const fe="tmux-web-sidebar-group-collapsed";function ue(){try{return new Set(JSON.parse(localStorage.getItem(fe)||"[]"))}catch{return new Set}}function $e(e){try{localStorage.setItem(fe,JSON.stringify([...e]))}catch{}}function Re(e,n,t){if(!e)return"\u2026";const s=t&&(e===t||e.startsWith(t+"/"))?"~"+e.slice(t.length):e,i=s.split("/").filter(Boolean);if(i.length===0)return e;for(let l=2;l<=i.length;l++){const o=i.slice(-l).join("/");if(!n.some(a=>!a||a===e?!1:(t&&(a===t||a.startsWith(t+"/"))?"~"+a.slice(t.length):a).split("/").filter(Boolean).slice(-l).join("/")===o))return s.startsWith("~")?o:"\u2026/"+o}return s}function Ne(e,n){const t=new Map;for(const l of e){const o=l.path||"";t.has(o)||t.set(o,[]),t.get(o).push(l)}const s=[...t.keys()],i=ue();for(const[l,o]of t){const c=Re(l,s,n),a=i.has(l),r=document.createElement("div");r.className="session-group-header"+(a?" collapsed":""),r.title=l||"No working directory",r.innerHTML=`<span class="sg-folder">&#128193;</span><span class="sg-label">${d(c)}</span><span class="sg-count">${o.length}</span><span class="sg-arrow">${a?"\u25B8":"\u25BE"}</span>`,r.addEventListener("click",()=>{const b=ue(),ie=r.nextElementSibling;b.has(l)?(b.delete(l),r.classList.remove("collapsed"),ie?.classList.remove("collapsed"),r.querySelector(".sg-arrow").textContent="\u25BE"):(b.add(l),r.classList.add("collapsed"),ie?.classList.add("collapsed"),r.querySelector(".sg-arrow").textContent="\u25B8"),$e(b)});const L=document.createElement("div");L.className="session-group-body"+(a?" collapsed":"");for(const b of o)L.appendChild(_e(b));p.appendChild(r),p.appendChild(L)}}function _e(e){const n=document.createElement("div");n.className="session-item"+(e.name===m&&!g?" active":""),n.setAttribute("data-session",e.name),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>
1
+ import{initTerminal as Be}from"./terminal-core.js";const H=window.__TMUX_WEB_SHELL__;let f=null,m=null;const oe=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null;let g=oe;window.__tmuxWebScopeAgent=oe;let Y="sessions",C="",F="",W="",ae="";function y(e){return g?"/a/"+encodeURIComponent(g)+e:e}const p=document.getElementById("sidebar-content"),B=document.getElementById("main-placeholder"),h=document.getElementById("terminal-container"),$=document.getElementById("file-editor"),xe=document.getElementById("fe-path"),w=document.getElementById("fe-status"),R=document.getElementById("fe-content"),x=document.getElementById("fe-save"),Se=document.getElementById("fe-delete"),Me=document.getElementById("fe-back"),le=document.getElementById("fe-new-name"),Te=document.getElementById("fe-new-btn"),Z=document.getElementById("settings-backdrop"),ce=document.getElementById("settings-popover"),de=document.querySelector(".sidebar");function He(){return window.matchMedia("(max-width: 640px)").matches}function Q(){He()&&de.classList.add("collapsed")}function re(){de.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{re(),pe("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{re(),pe("files")});function pe(e){Y=e,document.querySelectorAll(".mode-btn").forEach(t=>t.classList.remove("active"));const n=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");n&&n.classList.add("active"),e==="sessions"?(ee="",M()):Ue()}let ee="";async function M(){if(Y!=="sessions")return;try{const t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents});if(s===ee)return;ee=s,Pe(t)}catch{p.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}const e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>{const n=window.__openNewSessionModal;typeof n=="function"?n():document.getElementById("new-session-modal")?.classList.add("open")})}const fe="tmux-web-sidebar-group-collapsed";function ue(){try{return new Set(JSON.parse(localStorage.getItem(fe)||"[]"))}catch{return new Set}}function $e(e){try{localStorage.setItem(fe,JSON.stringify([...e]))}catch{}}function Re(e,n,t){if(!e)return"\u2026";const s=t&&(e===t||e.startsWith(t+"/"))?"~"+e.slice(t.length):e,i=s.split("/").filter(Boolean);if(i.length===0)return e;for(let l=1;l<=i.length;l++){const o=i.slice(-l).join("/");if(!n.some(a=>!a||a===e?!1:(t&&(a===t||a.startsWith(t+"/"))?"~"+a.slice(t.length):a).split("/").filter(Boolean).slice(-l).join("/")===o))return o}return s}function Ne(e,n){const t=new Map;for(const l of e){const o=l.path||"";t.has(o)||t.set(o,[]),t.get(o).push(l)}const s=[...t.keys()],i=ue();for(const[l,o]of t){const c=Re(l,s,n),a=i.has(l),r=document.createElement("div");r.className="session-group-header"+(a?" collapsed":""),r.title=l||"No working directory",r.innerHTML=`<span class="sg-folder">&#128193;</span><span class="sg-label">${d(c)}</span>`,r.addEventListener("click",()=>{const b=ue(),ie=r.nextElementSibling;b.has(l)?(b.delete(l),r.classList.remove("collapsed"),ie?.classList.remove("collapsed")):(b.add(l),r.classList.add("collapsed"),ie?.classList.add("collapsed")),$e(b)});const L=document.createElement("div");L.className="session-group-body"+(a?" collapsed":"");for(const b of o)L.appendChild(_e(b));p.appendChild(r),p.appendChild(L)}}function _e(e){const n=document.createElement("div");n.className="session-item"+(e.name===m&&!g?" active":""),n.setAttribute("data-session",e.name),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>
2
2
  <span>${d(e.name)}</span>
3
3
  <button class="session-edit-btn" data-session="${d(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>
4
4
  `,n.addEventListener("click",s=>{s.target.closest(".session-edit-btn")||N(e.name)});const t=n.querySelector(".session-edit-btn");return t&&t.addEventListener("click",s=>{s.stopPropagation(),Xe(e.name,t)}),n}function Pe(e){p.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';const n=e.recent||[],t=document.createElement("div");t.className="sidebar-section-label"+(g?" clickable":""),t.textContent=g?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",g&&(t.title="Back to hub",t.addEventListener("click",()=>{window.location.href="/"})),p.appendChild(t),Ne(n,e.home);const s=e.agents||[];for(const i of s){if(!i.sessions||i.sessions.length===0)continue;const l=i.agentId===g,o=document.createElement("div");o.className="sidebar-section-label machine-label"+(i.online?"":" agent-offline-label")+(!l&&i.online?" clickable":""),o.textContent=i.agentName+(i.online?"":" (offline)"),!l&&i.online&&(o.title="\u6253\u5F00 "+i.agentName,o.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(i.agentId)+"/"})),p.appendChild(o);for(const c of i.sessions){const a=document.createElement("div");a.className="session-item"+(c.name===m&&g===i.agentId?" active":"")+(i.online?"":" session-offline"),a.setAttribute("data-session",c.name),a.setAttribute("data-agent",i.agentId),a.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${c.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>
5
- <span>${d(c.name)}</span><span class="meta">${i.online?"":"offline"}</span>`,i.online&&a.addEventListener("click",r=>{r.target.closest(".session-edit-btn")||N(c.name,i.agentId)}),p.appendChild(a)}}}function d(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function N(e,n){if(!(m===e&&f&&g===(n||null))){$.style.display="none",I.style.display="none",h.style.display="",h.classList.add("terminal-pending"),Q(),f&&(K(),f.destroy(),f=null),m=e,g=n||null,window.__tmuxWebScopeAgent=g,window.__tmuxWebCurrentSession=m;for(const t of p.querySelectorAll(".session-item"))t.classList.toggle("active",t.getAttribute("data-session")===e&&(t.getAttribute("data-agent")||null)===g);try{f=await Ie(h,e,{terminal:H.terminal,scrollback:H.scrollback,theme:H.theme,wsBase:g?"/ws/a/"+encodeURIComponent(g):H.wsBase||"/ws"}),ke()}catch(t){console.error("[shell] terminal init failed:",t);const s=t&&typeof t=="object"&&"message"in t?t.message:String(t);h.textContent="Failed to open terminal for "+e+": "+s,h.classList.remove("terminal-pending")}}}let G=[],u=null,me=!1;function Ae(e){if(!u||!u.files.length)return null;const n=u.repoRoot;if(!n||!e.startsWith(n))return null;const t=e.slice(n.length+1);for(const s of u.files)if(s.path===t)return s.status;return null}async function De(e){me=!0;try{const n=await fetch(y("/api/git/status?path="+encodeURIComponent(e)));n.ok?u=await n.json():u=null}catch{u=null}finally{me=!1}}function We(){if(!u||!u.branch)return"";const{branch:e,linesAdded:n,linesRemoved:t}=u;let s=`<div class="sidebar-git"><div class="git-branch-badge">
5
+ <span>${d(c.name)}</span><span class="meta">${i.online?"":"offline"}</span>`,i.online&&a.addEventListener("click",r=>{r.target.closest(".session-edit-btn")||N(c.name,i.agentId)}),p.appendChild(a)}}}function d(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function N(e,n){if(!(m===e&&f&&g===(n||null))){$.style.display="none",B.style.display="none",h.style.display="",h.classList.add("terminal-pending"),Q(),f&&(K(),f.destroy(),f=null),m=e,g=n||null,window.__tmuxWebScopeAgent=g,window.__tmuxWebCurrentSession=m;for(const t of p.querySelectorAll(".session-item"))t.classList.toggle("active",t.getAttribute("data-session")===e&&(t.getAttribute("data-agent")||null)===g);try{f=await Be(h,e,{terminal:H.terminal,scrollback:H.scrollback,theme:H.theme,wsBase:g?"/ws/a/"+encodeURIComponent(g):H.wsBase||"/ws"}),ke()}catch(t){console.error("[shell] terminal init failed:",t);const s=t&&typeof t=="object"&&"message"in t?t.message:String(t);h.textContent="Failed to open terminal for "+e+": "+s,h.classList.remove("terminal-pending")}}}let G=[],u=null,me=!1;function Ae(e){if(!u||!u.files.length)return null;const n=u.repoRoot;if(!n||!e.startsWith(n))return null;const t=e.slice(n.length+1);for(const s of u.files)if(s.path===t)return s.status;return null}async function De(e){me=!0;try{const n=await fetch(y("/api/git/status?path="+encodeURIComponent(e)));n.ok?u=await n.json():u=null}catch{u=null}finally{me=!1}}function je(){if(!u||!u.branch)return"";const{branch:e,linesAdded:n,linesRemoved:t}=u;let s=`<div class="sidebar-git"><div class="git-branch-badge">
6
6
  <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>
7
- ${d(e)}</div>`;return(n>0||t>0)&&(s+=`<div class="git-diff-stats">+<span class="add">${n}</span> <span class="del">-${t}</span></div>`),s+"</div>"}p.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&T&&u&&(e.stopPropagation(),be())});const _=document.getElementById("header-git"),ve=document.getElementById("git-diff-view"),ge=document.getElementById("gd-path"),O=document.getElementById("gd-status"),z=document.getElementById("gd-content"),je=document.getElementById("gd-back");let T=null;function P(e){if(!e||!e.branch){_.style.display="none",T=null;return}T=e.repoRoot;const{branch:n,linesAdded:t,linesRemoved:s}=e;let i=`<span class="branch">${d(n)}</span>`;(t>0||s>0)&&(i+=`<span class="sep">\xB7</span>+<span class="diff-add">${t}</span> <span class="diff-del">-${s}</span>`),_.innerHTML=i,_.style.display="block"}_.addEventListener("click",e=>{T&&u&&(e.stopPropagation(),be())});const v=document.getElementById("git-popover"),U=document.getElementById("git-popover-backdrop");function te(){const e=_.getBoundingClientRect();v.style.top=e.bottom+4+"px",v.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function ye(){const e=T,n=document.getElementById("git-popover-browse");n&&n.addEventListener("click",()=>{if(V(),e){Y="files",document.querySelectorAll(".mode-btn").forEach(s=>s.classList.remove("active"));const t=document.getElementById("mode-files");t&&t.classList.add("active"),B(e)}})}let he="";function be(){if(!u)return;const e=u.files||[];if(!e.length)v.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
7
+ ${d(e)}</div>`;return(n>0||t>0)&&(s+=`<div class="git-diff-stats">+<span class="add">${n}</span> <span class="del">-${t}</span></div>`),s+"</div>"}p.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&T&&u&&(e.stopPropagation(),be())});const _=document.getElementById("header-git"),ve=document.getElementById("git-diff-view"),ge=document.getElementById("gd-path"),O=document.getElementById("gd-status"),z=document.getElementById("gd-content"),Fe=document.getElementById("gd-back");let T=null;function P(e){if(!e||!e.branch){_.style.display="none",T=null;return}T=e.repoRoot;const{branch:n,linesAdded:t,linesRemoved:s}=e;let i=`<span class="branch">${d(n)}</span>`;(t>0||s>0)&&(i+=`<span class="sep">\xB7</span>+<span class="diff-add">${t}</span> <span class="diff-del">-${s}</span>`),_.innerHTML=i,_.style.display="block"}_.addEventListener("click",e=>{T&&u&&(e.stopPropagation(),be())});const v=document.getElementById("git-popover"),U=document.getElementById("git-popover-backdrop");function te(){const e=_.getBoundingClientRect();v.style.top=e.bottom+4+"px",v.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function ye(){const e=T,n=document.getElementById("git-popover-browse");n&&n.addEventListener("click",()=>{if(q(),e){Y="files",document.querySelectorAll(".mode-btn").forEach(s=>s.classList.remove("active"));const t=document.getElementById("mode-files");t&&t.classList.add("active"),I(e)}})}let he="";function be(){if(!u)return;const e=u.files||[];if(!e.length)v.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
8
8
  <div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>`;else{let n=`<div class="git-popover-header">${e.length} file${e.length>1?"s":""} changed</div>`;for(let t=0;t<e.length;t++){const s=e[t],i=s.additions||0,l=s.deletions||0;let o="";switch(s.status){case"M":o='<span class="git-file-status M">M</span>';break;case"A":o='<span class="git-file-status A">A</span>';break;case"D":o='<span class="git-file-status D">D</span>';break;case"?":o='<span class="git-file-status ?">?</span>';break;case"R":o='<span class="git-file-status R">R</span>';break}n+=`<div class="git-popover-item" data-idx="${t}">
9
9
  ${o}<span class="file-path">${d(s.path)}</span>
10
10
  <span class="file-add">${i>0?"+"+i:""}</span>
11
11
  <span class="file-del">${l>0?"-"+l:""}</span>
12
- </div>`}n+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',he=n,v.innerHTML=n,v.querySelectorAll(".git-popover-item").forEach(t=>{const s=parseInt(t.dataset.idx||"0",10),i=e[s];!i||i.status==="D"||(t.classList.add("clickable"),t.style.cursor="pointer",t.addEventListener("click",()=>Le(i.path)))})}te(),v.classList.add("open"),U.classList.add("open"),ye()}function Fe(){return window.innerWidth>=1024}function we(e,n){const s=(e+(n&&e?`
12
+ </div>`}n+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',he=n,v.innerHTML=n,v.querySelectorAll(".git-popover-item").forEach(t=>{const s=parseInt(t.dataset.idx||"0",10),i=e[s];!i||i.status==="D"||(t.classList.add("clickable"),t.style.cursor="pointer",t.addEventListener("click",()=>Le(i.path)))})}te(),v.classList.add("open"),U.classList.add("open"),ye()}function We(){return window.innerWidth>=1024}function we(e,n){const s=(e+(n&&e?`
13
13
  `:"")+n).split(`
14
- `);let i="",l=0,o=0;for(const c of s){const a=c;if(a.startsWith("@@")){const r=a.match(/@@\s+-(\d+)[^+]*\+(\d+)/);r&&(l=parseInt(r[1],10)-1,o=parseInt(r[2],10)-1),i+=`<div class="diff-line hunk"><span class="ln-body">${d(a)}</span></div>`;continue}if(a.startsWith("diff --git")||a.startsWith("index ")||a.startsWith("--- ")||a.startsWith("+++ ")||a.startsWith("new file")||a.startsWith("deleted file")){a.startsWith("diff --git")&&(i+=`<div class="diff-line header"><span class="ln-body">${d(a)}</span></div>`);continue}if(a.startsWith("+"))o++,i+=`<div class="diff-line add"><span class="ln-no">${o}</span><span class="ln-body">${d(a)}</span></div>`;else if(a.startsWith("-"))l++,i+=`<div class="diff-line del"><span class="ln-no">${l}</span><span class="ln-body">${d(a)}</span></div>`;else if(a.startsWith("\\"))i+=`<div class="diff-line"><span class="ln-body">${d(a)}</span></div>`;else{if(!a&&!l&&!o)continue;l++,o++,i+=`<div class="diff-line"><span class="ln-no">${l}</span><span class="ln-no" style="margin-right:12px">${o}</span><span class="ln-body">${d(a)}</span></div>`}}return{html:i,lineCount:s.length}}let q=null;async function Le(e){const n=T;if(n)if(V(),Fe()){h.style.display="none",f&&(K(),f.destroy(),f=null,q=m,m=null),P(null),$.style.display="none",I.style.display="none",ve.style.display="flex",ge.textContent=e,O.textContent="Loading\u2026",z.innerHTML="";try{const t=await fetch(y("/api/git/diff?path="+encodeURIComponent(n)+"&file="+encodeURIComponent(e)));if(!t.ok)throw new Error(await t.text());const s=await t.json();Oe(e,s.diff,s.stagedDiff)}catch(t){const s=t instanceof Error?t.message:String(t);O.textContent="Error",z.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${d(s)}</div>`}}else{v.innerHTML=`<div class="git-diff-view"><div class="diff-header">
14
+ `);let i="",l=0,o=0;for(const c of s){const a=c;if(a.startsWith("@@")){const r=a.match(/@@\s+-(\d+)[^+]*\+(\d+)/);r&&(l=parseInt(r[1],10)-1,o=parseInt(r[2],10)-1),i+=`<div class="diff-line hunk"><span class="ln-body">${d(a)}</span></div>`;continue}if(a.startsWith("diff --git")||a.startsWith("index ")||a.startsWith("--- ")||a.startsWith("+++ ")||a.startsWith("new file")||a.startsWith("deleted file")){a.startsWith("diff --git")&&(i+=`<div class="diff-line header"><span class="ln-body">${d(a)}</span></div>`);continue}if(a.startsWith("+"))o++,i+=`<div class="diff-line add"><span class="ln-no">${o}</span><span class="ln-body">${d(a)}</span></div>`;else if(a.startsWith("-"))l++,i+=`<div class="diff-line del"><span class="ln-no">${l}</span><span class="ln-body">${d(a)}</span></div>`;else if(a.startsWith("\\"))i+=`<div class="diff-line"><span class="ln-body">${d(a)}</span></div>`;else{if(!a&&!l&&!o)continue;l++,o++,i+=`<div class="diff-line"><span class="ln-no">${l}</span><span class="ln-no" style="margin-right:12px">${o}</span><span class="ln-body">${d(a)}</span></div>`}}return{html:i,lineCount:s.length}}let V=null;async function Le(e){const n=T;if(n)if(q(),We()){h.style.display="none",f&&(K(),f.destroy(),f=null,V=m,m=null),P(null),$.style.display="none",B.style.display="none",ve.style.display="flex",ge.textContent=e,O.textContent="Loading\u2026",z.innerHTML="";try{const t=await fetch(y("/api/git/diff?path="+encodeURIComponent(n)+"&file="+encodeURIComponent(e)));if(!t.ok)throw new Error(await t.text());const s=await t.json();Oe(e,s.diff,s.stagedDiff)}catch(t){const s=t instanceof Error?t.message:String(t);O.textContent="Error",z.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${d(s)}</div>`}}else{v.innerHTML=`<div class="git-diff-view"><div class="diff-header">
15
15
  <button class="diff-back">\u2190 Back</button>
16
16
  <span class="diff-filename">${d(e)}</span>
17
17
  <span class="diff-loading">Loading\u2026</span>
@@ -25,7 +25,7 @@ import{initTerminal as Ie}from"./terminal-core.js";const H=window.__TMUX_WEB_SHE
25
25
  <button class="diff-back">\u2190 Back</button>
26
26
  <span class="diff-filename">${d(e)}</span>
27
27
  <span class="diff-filesize">${i} lines</span>
28
- </div><div class="diff-content">${s}</div></div>`,v.querySelector(".diff-back")?.addEventListener("click",()=>{v.innerHTML=he,te(),u&&v.querySelectorAll(".git-popover-item").forEach(l=>{const o=parseInt(l.dataset.idx||"0",10),c=u.files[o];!c||c.status==="D"||(l.style.cursor="pointer",l.addEventListener("click",()=>Le(c.path)))}),ye()})}function Oe(e,n,t){if(!n&&!t){O.textContent="No diff",z.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}const{html:s,lineCount:i}=we(n,t);ge.textContent=e,O.textContent=i+" lines",z.innerHTML=s}function ze(){ve.style.display="none",q?(h.style.display="",h.classList.add("terminal-pending"),N(q),q=null):m?(h.style.display="",h.classList.add("terminal-pending"),ke()):I.style.display="flex"}je.addEventListener("click",ze);function V(){v.classList.remove("open"),U.classList.remove("open")}U.addEventListener("click",V),document.addEventListener("keydown",e=>{e.key==="Escape"&&(V(),X())});async function Ee(e){try{const t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){const s=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(s.ok){const i=await s.json();u=i,P(i);return}}}catch{}u=null,P(null)}let J=null;function ke(){K(),m&&(Ee(m),J=setInterval(()=>{m&&Ee(m)},3e4))}function K(){J&&(clearInterval(J),J=null)}function Ue(){if(G=H.fsRoots||[],G.length===0){if(m){qe(m);return}p.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}p.innerHTML="";for(const e of G){const n=document.createElement("div");n.className="file-tree-item",n.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> ${d(e)}`,n.addEventListener("click",()=>B(e)),p.appendChild(n)}}async function qe(e){p.innerHTML='<div class="file-tree-empty">Loading...</div>';try{const t=await(await fetch(y("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?B(t.path):p.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{p.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function B(e){C=e,p.innerHTML='<div class="file-tree-empty">Loading...</div>';const n=De(e);try{const s=await(await fetch(y("/api/fs/list?path="+encodeURIComponent(e)))).json();await n,p.innerHTML="",P(u),p.innerHTML+=We();const i=Ve(e);if(i&&!G.some(c=>e===c)){const c=document.createElement("div");c.className="file-tree-item",c.innerHTML="..",c.addEventListener("click",()=>B(i)),p.appendChild(c)}if(s.dirs)for(const o of s.dirs){const c=o.split("/").pop()||o.split("\\").pop(),a=document.createElement("div");a.className="file-tree-item",a.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> ${d(c)}`,a.addEventListener("click",()=>B(o)),p.appendChild(a)}else p.innerHTML="";const l=s.files||[];for(const o of l){const c=o.split("/").pop()||o.split("\\").pop(),a=Ae(o);let r="",L="";if(a)switch(a){case"M":r="git-mod",L='<span class="git-file-status M">M</span>';break;case"A":r="git-add",L='<span class="git-file-status A">A</span>';break;case"D":r="git-del",L='<span class="git-file-status D">D</span>';break;case"?":r="git-untracked",L='<span class="git-file-status ?">?</span>';break;case"R":r="git-mod",L='<span class="git-file-status R">R</span>';break}const b=document.createElement("div");b.className="file-tree-item file"+(r?" "+r:""),b.innerHTML=`<span class="file-icon">\u{1F4C4}</span> ${L}${d(c)}`,b.addEventListener("click",()=>Je(o)),p.appendChild(b)}}catch{p.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function Ve(e){const n=e.lastIndexOf("/");return n<=0?null:e.substring(0,n)}async function Je(e){j=e,h.style.display="none",f&&(K(),f.destroy(),f=null,m=null),P(null),Q(),I.style.display="none",$.style.display="flex",xe.textContent=e,w.textContent="Loading...",x.style.display="none";try{const n=await fetch(y("/api/file?path="+encodeURIComponent(e)));if(!n.ok){const s=await n.json();w.textContent=s.error||"Failed to load",R.value="";return}const t=await n.json();R.value=t.content,F=t.content,ae=t.content,w.textContent=t.size+" bytes",x.style.display=""}catch{w.textContent="Failed to load",R.value=""}}R.addEventListener("input",()=>{F=R.value}),x.addEventListener("click",async()=>{x.textContent="Saving...",x.disabled=!0;try{const e=await fetch(y("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:j,content:F})});if(!e.ok){const n=await e.json();w.textContent=n.error||"Save failed";return}ae=F,w.textContent="Saved"}catch{w.textContent="Save failed"}finally{x.disabled=!1,x.textContent="Save"}}),Se.addEventListener("click",async()=>{if(confirm("Delete "+j+"?"))try{const e=await fetch(y("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:j})});if(!e.ok){const n=await e.json();w.textContent=n.error||"Delete failed";return}$.style.display="none",I.style.display="flex",C&&B(C)}catch{w.textContent="Delete failed"}}),Me.addEventListener("click",()=>{$.style.display="none",I.style.display="flex",C&&B(C)}),Te.addEventListener("click",async()=>{const e=le.value.trim();if(!e)return;const n=C+"/"+e;try{const t=await fetch(y("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:n})});if(!t.ok){const s=await t.json();w.textContent=s.error||"Create failed";return}le.value="",C&&B(C)}catch{w.textContent="Create failed"}}),document.getElementById("mode-settings").addEventListener("click",()=>{const e=ce.classList.toggle("open");Z.classList.toggle("open",e)}),Z.addEventListener("click",()=>{ce.classList.remove("open"),Z.classList.remove("open")});let S="";const A=document.createElement("div");A.className="session-popover-backdrop",document.body.appendChild(A);const k=document.createElement("div");k.id="session-popover",k.className="session-popover",k.style.display="none",k.innerHTML=`<div class="sp-field">
28
+ </div><div class="diff-content">${s}</div></div>`,v.querySelector(".diff-back")?.addEventListener("click",()=>{v.innerHTML=he,te(),u&&v.querySelectorAll(".git-popover-item").forEach(l=>{const o=parseInt(l.dataset.idx||"0",10),c=u.files[o];!c||c.status==="D"||(l.style.cursor="pointer",l.addEventListener("click",()=>Le(c.path)))}),ye()})}function Oe(e,n,t){if(!n&&!t){O.textContent="No diff",z.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}const{html:s,lineCount:i}=we(n,t);ge.textContent=e,O.textContent=i+" lines",z.innerHTML=s}function ze(){ve.style.display="none",V?(h.style.display="",h.classList.add("terminal-pending"),N(V),V=null):m?(h.style.display="",h.classList.add("terminal-pending"),ke()):B.style.display="flex"}Fe.addEventListener("click",ze);function q(){v.classList.remove("open"),U.classList.remove("open")}U.addEventListener("click",q),document.addEventListener("keydown",e=>{e.key==="Escape"&&(q(),X())});async function Ee(e){try{const t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){const s=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(s.ok){const i=await s.json();u=i,P(i);return}}}catch{}u=null,P(null)}let J=null;function ke(){K(),m&&(Ee(m),J=setInterval(()=>{m&&Ee(m)},3e4))}function K(){J&&(clearInterval(J),J=null)}function Ue(){if(G=H.fsRoots||[],G.length===0){if(m){Ve(m);return}p.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}p.innerHTML="";for(const e of G){const n=document.createElement("div");n.className="file-tree-item",n.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> ${d(e)}`,n.addEventListener("click",()=>I(e)),p.appendChild(n)}}async function Ve(e){p.innerHTML='<div class="file-tree-empty">Loading...</div>';try{const t=await(await fetch(y("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?I(t.path):p.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{p.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function I(e){C=e,p.innerHTML='<div class="file-tree-empty">Loading...</div>';const n=De(e);try{const s=await(await fetch(y("/api/fs/list?path="+encodeURIComponent(e)))).json();await n,p.innerHTML="",P(u),p.innerHTML+=je();const i=qe(e);if(i&&!G.some(c=>e===c)){const c=document.createElement("div");c.className="file-tree-item",c.innerHTML="..",c.addEventListener("click",()=>I(i)),p.appendChild(c)}if(s.dirs)for(const o of s.dirs){const c=o.split("/").pop()||o.split("\\").pop(),a=document.createElement("div");a.className="file-tree-item",a.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> ${d(c)}`,a.addEventListener("click",()=>I(o)),p.appendChild(a)}else p.innerHTML="";const l=s.files||[];for(const o of l){const c=o.split("/").pop()||o.split("\\").pop(),a=Ae(o);let r="",L="";if(a)switch(a){case"M":r="git-mod",L='<span class="git-file-status M">M</span>';break;case"A":r="git-add",L='<span class="git-file-status A">A</span>';break;case"D":r="git-del",L='<span class="git-file-status D">D</span>';break;case"?":r="git-untracked",L='<span class="git-file-status ?">?</span>';break;case"R":r="git-mod",L='<span class="git-file-status R">R</span>';break}const b=document.createElement("div");b.className="file-tree-item file"+(r?" "+r:""),b.innerHTML=`<span class="file-icon">\u{1F4C4}</span> ${L}${d(c)}`,b.addEventListener("click",()=>Je(o)),p.appendChild(b)}}catch{p.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function qe(e){const n=e.lastIndexOf("/");return n<=0?null:e.substring(0,n)}async function Je(e){F=e,h.style.display="none",f&&(K(),f.destroy(),f=null,m=null),P(null),Q(),B.style.display="none",$.style.display="flex",xe.textContent=e,w.textContent="Loading...",x.style.display="none";try{const n=await fetch(y("/api/file?path="+encodeURIComponent(e)));if(!n.ok){const s=await n.json();w.textContent=s.error||"Failed to load",R.value="";return}const t=await n.json();R.value=t.content,W=t.content,ae=t.content,w.textContent=t.size+" bytes",x.style.display=""}catch{w.textContent="Failed to load",R.value=""}}R.addEventListener("input",()=>{W=R.value}),x.addEventListener("click",async()=>{x.textContent="Saving...",x.disabled=!0;try{const e=await fetch(y("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:F,content:W})});if(!e.ok){const n=await e.json();w.textContent=n.error||"Save failed";return}ae=W,w.textContent="Saved"}catch{w.textContent="Save failed"}finally{x.disabled=!1,x.textContent="Save"}}),Se.addEventListener("click",async()=>{if(confirm("Delete "+F+"?"))try{const e=await fetch(y("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:F})});if(!e.ok){const n=await e.json();w.textContent=n.error||"Delete failed";return}$.style.display="none",B.style.display="flex",C&&I(C)}catch{w.textContent="Delete failed"}}),Me.addEventListener("click",()=>{$.style.display="none",B.style.display="flex",C&&I(C)}),Te.addEventListener("click",async()=>{const e=le.value.trim();if(!e)return;const n=C+"/"+e;try{const t=await fetch(y("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:n})});if(!t.ok){const s=await t.json();w.textContent=s.error||"Create failed";return}le.value="",C&&I(C)}catch{w.textContent="Create failed"}}),document.getElementById("mode-settings").addEventListener("click",()=>{const e=ce.classList.toggle("open");Z.classList.toggle("open",e)}),Z.addEventListener("click",()=>{ce.classList.remove("open"),Z.classList.remove("open")});let S="";const A=document.createElement("div");A.className="session-popover-backdrop",document.body.appendChild(A);const k=document.createElement("div");k.id="session-popover",k.className="session-popover",k.style.display="none",k.innerHTML=`<div class="sp-field">
29
29
  <label>Rename session</label>
30
30
  <input type="text" id="sp-name" />
31
31
  </div>
@@ -34,5 +34,5 @@ import{initTerminal as Ie}from"./terminal-core.js";const H=window.__TMUX_WEB_SHE
34
34
  <button class="btn" id="sp-cancel">Cancel</button>
35
35
  </div>
36
36
  <hr class="sp-divider" />
37
- <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(k);function Ke(e){const n=e.getBoundingClientRect();k.style.top=n.bottom+4+"px",k.style.left=Math.max(8,Math.min(n.left,window.innerWidth-240))+"px"}function Xe(e,n){S=e;const t=document.getElementById("sp-name");t.value=e,A.classList.add("open"),k.style.display="block",Ke(n),setTimeout(()=>t.focus(),50)}function D(){A.classList.remove("open"),k.style.display="none"}A.addEventListener("click",D),document.getElementById("sp-save").addEventListener("click",async()=>{const e=document.getElementById("sp-name").value.trim();if(!e||e===S){D();return}try{if(!(await fetch(y("/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldName:S,newName:e})})).ok)return;D(),M(),m===S&&N(e)}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(confirm('Delete session "'+S+'"?'))try{if(!(await fetch(y("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:S})})).ok)return;D(),m===S&&(f&&(f.destroy(),f=null),m=null,h.style.display="none",I.style.display="flex"),M()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",D);const Ye={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=>{const n=e.target.closest("button[data-key]");if(!n||!f)return;const t=Ye[n.dataset.key];t&&(f.sendInput(t),f.focus())});const E=document.getElementById("mk-input"),Ce=document.getElementById("mk-send");function Be(){if(!E||!f)return;const e=E.value;e&&(f.sendInput(e+"\r"),E.value="",E.rows=1,f.focus())}if(E&&(E.addEventListener("input",()=>{E.rows=1;const e=E.value.split(`
38
- `).length;E.rows=Math.min(e,4)}),E.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Be())})),Ce&&Ce.addEventListener("click",Be),window.visualViewport){const e=document.querySelector(".app-layout"),n=()=>{e&&(e.style.height=window.visualViewport.height+"px"),window.scrollTo(0,0),document.documentElement.scrollTop=0,document.body.scrollTop=0};window.visualViewport.addEventListener("resize",n),window.addEventListener("orientationchange",()=>setTimeout(n,100)),document.addEventListener("touchstart",()=>{(window.scrollY>0||document.documentElement.scrollTop>0)&&window.scrollTo(0,0)},{passive:!0})}const ne=document.getElementById("process-panel"),W=document.getElementById("proc-list"),Ze=document.getElementById("proc-close"),se=document.getElementById("proc-backdrop"),Qe=document.getElementById("header-ram");function et(){W.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(y("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){W.innerHTML='<div class="proc-empty">No processes</div>';return}let n="";for(const t of e){const s=t.rss,i=s<1048576?(s/1024).toFixed(0)+"K":(s/1048576).toFixed(1)+"M";n+='<div class="proc-row" data-pid="'+t.pid+'"><span class="proc-mem">'+t.mem+'%</span><span class="proc-rss">'+i+'</span><span class="proc-cmd" title="'+d(t.command)+'">'+d(t.command)+'</span><button class="proc-kill" title="Kill PID '+t.pid+'">&times;</button></div>'}W.innerHTML=n;for(const t of W.querySelectorAll(".proc-row")){const s=t.querySelector(".proc-kill");s&&s.addEventListener("click",i=>{const l=i.target.closest(".proc-row");!l||!confirm("Kill PID "+l.dataset.pid+"?")||fetch(y("/api/system/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pid:parseInt(l.dataset.pid,10)})}).then(o=>o.json()).then(o=>{o.ok?l.style.opacity="0.3":alert("Failed: "+(o.error||"unknown"))}).catch(()=>alert("Network error"))})}}).catch(()=>{W.innerHTML='<div class="proc-empty">Failed to load</div>'})}function tt(){ne.classList.add("open"),se.classList.add("open"),et()}function X(){ne.classList.remove("open"),se.classList.remove("open")}Qe.addEventListener("click",e=>{e.stopPropagation(),ne.classList.contains("open")?X():tt()}),Ze.addEventListener("click",X),se.addEventListener("click",X),window.__openSession=N,window.__refreshSidebar=M,M(),Q(),setInterval(()=>{document.visibilityState==="visible"&&M()},1e4);
37
+ <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(k);function Ke(e){const n=e.getBoundingClientRect();k.style.top=n.bottom+4+"px",k.style.left=Math.max(8,Math.min(n.left,window.innerWidth-240))+"px"}function Xe(e,n){S=e;const t=document.getElementById("sp-name");t.value=e,A.classList.add("open"),k.style.display="block",Ke(n),setTimeout(()=>t.focus(),50)}function D(){A.classList.remove("open"),k.style.display="none"}A.addEventListener("click",D),document.getElementById("sp-save").addEventListener("click",async()=>{const e=document.getElementById("sp-name").value.trim();if(!e||e===S){D();return}try{if(!(await fetch(y("/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldName:S,newName:e})})).ok)return;D(),M(),m===S&&N(e)}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(confirm('Delete session "'+S+'"?'))try{if(!(await fetch(y("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:S})})).ok)return;D(),m===S&&(f&&(f.destroy(),f=null),m=null,h.style.display="none",B.style.display="flex"),M()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",D);const Ye={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=>{const n=e.target.closest("button[data-key]");if(!n||!f)return;const t=Ye[n.dataset.key];t&&(f.sendInput(t),f.focus())});const E=document.getElementById("mk-input"),Ce=document.getElementById("mk-send");function Ie(){if(!E||!f)return;const e=E.value;e&&(f.sendInput(e+"\r"),E.value="",E.rows=1,f.focus())}if(E&&(E.addEventListener("input",()=>{E.rows=1;const e=E.value.split(`
38
+ `).length;E.rows=Math.min(e,4)}),E.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Ie())})),Ce&&Ce.addEventListener("click",Ie),window.visualViewport){const e=document.querySelector(".app-layout"),n=()=>{e&&(e.style.height=window.visualViewport.height+"px"),window.scrollTo(0,0),document.documentElement.scrollTop=0,document.body.scrollTop=0};window.visualViewport.addEventListener("resize",n),window.addEventListener("orientationchange",()=>setTimeout(n,100)),document.addEventListener("touchstart",()=>{(window.scrollY>0||document.documentElement.scrollTop>0)&&window.scrollTo(0,0)},{passive:!0})}const ne=document.getElementById("process-panel"),j=document.getElementById("proc-list"),Ze=document.getElementById("proc-close"),se=document.getElementById("proc-backdrop"),Qe=document.getElementById("header-ram");function et(){j.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(y("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){j.innerHTML='<div class="proc-empty">No processes</div>';return}let n="";for(const t of e){const s=t.rss,i=s<1048576?(s/1024).toFixed(0)+"K":(s/1048576).toFixed(1)+"M";n+='<div class="proc-row" data-pid="'+t.pid+'"><span class="proc-mem">'+t.mem+'%</span><span class="proc-rss">'+i+'</span><span class="proc-cmd" title="'+d(t.command)+'">'+d(t.command)+'</span><button class="proc-kill" title="Kill PID '+t.pid+'">&times;</button></div>'}j.innerHTML=n;for(const t of j.querySelectorAll(".proc-row")){const s=t.querySelector(".proc-kill");s&&s.addEventListener("click",i=>{const l=i.target.closest(".proc-row");!l||!confirm("Kill PID "+l.dataset.pid+"?")||fetch(y("/api/system/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pid:parseInt(l.dataset.pid,10)})}).then(o=>o.json()).then(o=>{o.ok?l.style.opacity="0.3":alert("Failed: "+(o.error||"unknown"))}).catch(()=>alert("Network error"))})}}).catch(()=>{j.innerHTML='<div class="proc-empty">Failed to load</div>'})}function tt(){ne.classList.add("open"),se.classList.add("open"),et()}function X(){ne.classList.remove("open"),se.classList.remove("open")}Qe.addEventListener("click",e=>{e.stopPropagation(),ne.classList.contains("open")?X():tt()}),Ze.addEventListener("click",X),se.addEventListener("click",X),window.__openSession=N,window.__refreshSidebar=M,M(),Q(),setInterval(()=>{document.visibilityState==="visible"&&M()},1e4);
@@ -1,8 +1,8 @@
1
- const Oe=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function ne(s){return s.replace(/\x1b\[\?1049[hl]/g,"")}function R(s){return s.replace(Oe,"")}let X;function Ne(){return X||(document.querySelector("link[data-tmux-web-xterm-css]")?X=Promise.resolve():(X=new Promise(o=>{const i=document.createElement("link");i.rel="stylesheet",i.href="/assets/xterm.css",i.setAttribute("data-tmux-web-xterm-css",""),i.addEventListener("load",()=>o(),{once:!0}),i.addEventListener("error",()=>o(),{once:!0}),document.head.appendChild(i)}),X))}class oe{terminal;fitAddon;container;constructor(o,i,n){this.container=o,this.terminal=i,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(o)}static async create(o,i,n){const[{Terminal:a},{FitAddon:f}]=await Promise.all([import("@xterm/xterm"),import("@xterm/addon-fit"),Ne()]),h=new a({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:i,convertEol:!1,smoothScrollDuration:120,theme:n});return new oe(o,h,new f)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(o){return new Promise(i=>this.terminal.write(o,i))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(o,i=!1){this.terminal.scrollToLine(Math.max(0,o),i)}scrollLines(o){const i=this.terminal.buffer?.active;this.terminal.scrollLines(o)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}fit(){const o=Re(this.container);return o.width<=0||o.height<=0?!1:(this.fitAddon.fit(),!0)}focus(){this.terminal.focus()}pasteText(o){this.terminal.paste(o)}input(o){this.terminal.input(o,!1)}onData(o){this.terminal.onData(o),this.terminal.onBinary(o)}onResize(o){this.terminal.onResize(o)}onScroll(o){this.terminal.onScroll(o)}attachCustomKeyEventHandler(o){this.terminal.attachCustomKeyEventHandler(o)}isFocused(){const o=document.activeElement;return o?o===this.container||o===this.terminal.textarea||this.container.contains(o)||!!o.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(o,i){const n=this.terminal.buffer.active,[a,f]=o<=i?[o,i]:[i,o],h=n.viewportY,l=[];for(let d=a;d<=f;d++){const g=n.getLine(h+d);l.push(g?g.translateToString(!0):"")}return l.join(`
2
- `)}selectRows(o,i){const n=this.terminal.buffer.active,[a,f]=o<=i?[o,i]:[i,o];this.terminal.selectLines(n.viewportY+a,n.viewportY+f)}selectCells(o,i,n,a){const f=this.terminal.buffer.active,h=Math.min(i,a),l=Math.max(i,a);if(h===l){const d=Math.min(o,n),g=Math.max(o,n);this.terminal.select(d,f.viewportY+h,g-d+1)}else this.terminal.selectLines(f.viewportY+h,f.viewportY+l)}getCellsText(o,i,n,a){const f=this.terminal.buffer.active,h=Math.min(i,a),l=Math.max(i,a),d=i<a?o:i>a?n:Math.min(o,n),g=i<a?n:i>a?o:Math.max(o,n),$=f.viewportY,M=[];for(let E=h;E<=l;E++){const q=f.getLine($+E);if(!q){M.push("");continue}const D=E===h?d:0,Q=E===l?g:this.terminal.cols-1;let P="";for(let w=D;w<=Q;w++){const L=q.getCell(w);L&&(P+=L.getChars())}M.push(P.replace(/\s+$/,""))}return M.join(`
3
- `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}}function Re(s){const o=s.getBoundingClientRect(),i=window.visualViewport;return i?{width:Math.min(o.width,i.width),height:Math.max(0,Math.min(o.height,i.height-Math.max(0,o.top)))}:o}function Xe(s,o,i){return s.innerHTML="",s.classList.add("terminal-pending"),(async()=>{const n=await oe.create(s,i.scrollback,i.theme);let a,f=0,h,l=null,d=0,g=0;const $=.2,M=10,E=.95,q=.04;function D(){d&&(cancelAnimationFrame(d),d=0),g=0}function Q(e){if(D(),Math.abs(e)<$)return;g=Math.max(-M,Math.min(M,e));const t=()=>{if(b){d=0;return}const r=s.querySelector(".xterm-rows > div"),c=r?r.getBoundingClientRect().height:16;let u=c>0?Math.round(g*16/c):g>0?1:-1;u===0&&(u=g>0?1:-1);const v=n.viewportY()-u,G=n.baseY(),N=Math.max(0,Math.min(v,G));if(n.scrollToLine(N,!0),g*=E,N!==v){d=0;return}if(Math.abs(g)<q){d=0;return}d=requestAnimationFrame(t)};d=requestAnimationFrame(t)}let P=0,w="connecting",L=0,Y=!1,U=[],I="",b=!1,F=1e3;const me=location.protocol==="https:"?"wss:":"ws:",pe=i.wsBase||"/ws",he=me+"//"+location.host+pe+"/"+encodeURIComponent(o),ge="/api/session/"+encodeURIComponent(o)+"/upload",we=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function ye(){return U.join("")+I}async function ve(e,t=0){const r=e?n.viewportY():0,c=R(ye());if(n.reset(),!c){e||n.scrollToBottom();return}await n.write(c),e?n.scrollToLine(t+r):n.scrollToBottom()}function C(e){a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(e))}function Te(e){let t;try{t=JSON.parse(e)}catch{w==="live"&&(I+=e,n.write(R(e)));return}if(t.type==="auth.required"){const r=localStorage.getItem("tmux-web-token");r?C({type:"auth.token",token:r}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(t.type==="attach_failed"&&typeof t.message=="string"){_=!0,w="dead",n.reset(),n.write(`\r
1
+ const Oe=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function ne(s){return s.replace(/\x1b\[\?1049[hl]/g,"")}function R(s){return s.replace(Oe,"")}let X;function Ne(){return X||(document.querySelector("link[data-tmux-web-xterm-css]")?X=Promise.resolve():(X=new Promise(o=>{const i=document.createElement("link");i.rel="stylesheet",i.href="/assets/xterm.css",i.setAttribute("data-tmux-web-xterm-css",""),i.addEventListener("load",()=>o(),{once:!0}),i.addEventListener("error",()=>o(),{once:!0}),document.head.appendChild(i)}),X))}class oe{terminal;fitAddon;container;constructor(o,i,n){this.container=o,this.terminal=i,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(o)}static async create(o,i,n){const[{Terminal:a},{FitAddon:d}]=await Promise.all([import("@xterm/xterm"),import("@xterm/addon-fit"),Ne()]),m=new a({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:i,convertEol:!1,smoothScrollDuration:120,theme:n});return new oe(o,m,new d)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(o){return new Promise(i=>this.terminal.write(o,i))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(o,i=!1){this.terminal.scrollToLine(Math.max(0,o),i)}scrollLines(o){const i=this.terminal.buffer?.active;this.terminal.scrollLines(o)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}fit(){const o=Re(this.container);if(o.width<=0||o.height<=0)return!1;const n=this.terminal._core?._renderService?.dimensions?.css?.cell;if(!n?.width||!n?.height)return this.fitAddon.fit(),!0;const a=n.width,d=n.height,m=this.terminal.element?.querySelector(".xterm-viewport"),l=m?Math.max(0,m.offsetWidth-m.clientWidth):0,f=Math.max(2,Math.floor((o.width-l)/a)),h=Math.max(2,Math.floor(o.height/d));return(f!==this.terminal.cols||h!==this.terminal.rows)&&this.terminal.resize(f,h),!0}focus(){this.terminal.focus()}pasteText(o){this.terminal.paste(o)}input(o){this.terminal.input(o,!1)}onData(o){this.terminal.onData(o),this.terminal.onBinary(o)}onResize(o){this.terminal.onResize(o)}onScroll(o){this.terminal.onScroll(o)}attachCustomKeyEventHandler(o){this.terminal.attachCustomKeyEventHandler(o)}isFocused(){const o=document.activeElement;return o?o===this.container||o===this.terminal.textarea||this.container.contains(o)||!!o.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(o,i){const n=this.terminal.buffer.active,[a,d]=o<=i?[o,i]:[i,o],m=n.viewportY,l=[];for(let f=a;f<=d;f++){const h=n.getLine(m+f);l.push(h?h.translateToString(!0):"")}return l.join(`
2
+ `)}selectRows(o,i){const n=this.terminal.buffer.active,[a,d]=o<=i?[o,i]:[i,o];this.terminal.selectLines(n.viewportY+a,n.viewportY+d)}selectCells(o,i,n,a){const d=this.terminal.buffer.active,m=Math.min(i,a),l=Math.max(i,a);if(m===l){const f=Math.min(o,n),h=Math.max(o,n);this.terminal.select(f,d.viewportY+m,h-f+1)}else this.terminal.selectLines(d.viewportY+m,d.viewportY+l)}getCellsText(o,i,n,a){const d=this.terminal.buffer.active,m=Math.min(i,a),l=Math.max(i,a),f=i<a?o:i>a?n:Math.min(o,n),h=i<a?n:i>a?o:Math.max(o,n),$=d.viewportY,C=[];for(let E=m;E<=l;E++){const _=d.getLine($+E);if(!_){C.push("");continue}const D=E===m?f:0,Q=E===l?h:this.terminal.cols-1;let P="";for(let g=D;g<=Q;g++){const L=_.getCell(g);L&&(P+=L.getChars())}C.push(P.replace(/\s+$/,""))}return C.join(`
3
+ `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}}function Re(s){const o=s.getBoundingClientRect(),i=window.visualViewport;return i?{width:Math.min(o.width,i.width),height:Math.max(0,Math.min(o.height,i.height-Math.max(0,o.top)))}:o}function Xe(s,o,i){return s.innerHTML="",s.classList.add("terminal-pending"),(async()=>{const n=await oe.create(s,i.scrollback,i.theme);let a,d=0,m,l=null,f=0,h=0;const $=.2,C=10,E=.95,_=.04;function D(){f&&(cancelAnimationFrame(f),f=0),h=0}function Q(e){if(D(),Math.abs(e)<$)return;h=Math.max(-C,Math.min(C,e));const t=()=>{if(b){f=0;return}const r=s.querySelector(".xterm-rows > div"),c=r?r.getBoundingClientRect().height:16;let u=c>0?Math.round(h*16/c):h>0?1:-1;u===0&&(u=h>0?1:-1);const v=n.viewportY()-u,G=n.baseY(),N=Math.max(0,Math.min(v,G));if(n.scrollToLine(N,!0),h*=E,N!==v){f=0;return}if(Math.abs(h)<_){f=0;return}f=requestAnimationFrame(t)};f=requestAnimationFrame(t)}let P=0,g="connecting",L=0,Y=!1,q=[],I="",b=!1,F=1e3;const me=location.protocol==="https:"?"wss:":"ws:",he=i.wsBase||"/ws",pe=me+"//"+location.host+he+"/"+encodeURIComponent(o),we="/api/session/"+encodeURIComponent(o)+"/upload",ge=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function ye(){return q.join("")+I}async function ve(e,t=0){const r=e?n.viewportY():0,c=R(ye());if(n.reset(),!c){e||n.scrollToBottom();return}await n.write(c),e?n.scrollToLine(t+r):n.scrollToBottom()}function M(e){a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(e))}function Te(e){let t;try{t=JSON.parse(e)}catch{g==="live"&&(I+=e,n.write(R(e)));return}if(t.type==="auth.required"){const r=localStorage.getItem("tmux-web-token");r?M({type:"auth.token",token:r}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(t.type==="attach_failed"&&typeof t.message=="string"){U=!0,g="dead",n.reset(),n.write(`\r
4
4
  \x1B[31m`+R(t.message)+`\x1B[0m\r
5
- `).then(()=>{H();try{a?.close()}catch{}});return}if(t.type==="auth.ok"){t.token&&localStorage.setItem("tmux-web-token",t.token),F=1e3,S(),C({type:"resize",cols:n.cols,rows:n.rows}),y();return}if(t.type==="auth.failed"){if(t.permanentLock||t.retryAfterMs&&t.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(t.message);return}return}if(t.type==="snapshot"&&typeof t.data=="string"){const r=ne(R(t.data));U=[r],I="",L=typeof t.lines=="number"?t.lines:i.terminal.initialLines,w="live",n.reset(),S(),C({type:"resize",cols:n.cols,rows:n.rows}),n.write(r).then(()=>n.scrollToBottom());return}if(t.type==="window_changed"&&typeof t.activeIndex=="number"){const r=new URL(location.href);r.searchParams.get("window")!==String(t.activeIndex)&&(r.searchParams.set("window",String(t.activeIndex)),history.replaceState(history.state,"",r)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:t.windows}));return}if(t.type==="history"&&typeof t.data=="string"){t.lines>0&&t.data?(U.unshift(ne(t.data)),L+=t.lines,ve(!0,t.lines).finally(()=>{Y=!1})):Y=!1;return}if(t.type==="data"&&typeof t.data=="string"){const r=ne(R(t.data));if(w==="connecting"){w="live",I=r,n.write(r);return}w==="live"&&(I+=r,n.write(r))}}let _=!1;function re(){if(_)return;let e=he;const t=localStorage.getItem("tmux-web-token");t&&(e+=(e.includes("?")?"&":"?")+"token="+encodeURIComponent(t)),e+=(e.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,a=new WebSocket(e),a.onopen=()=>{w="connecting",L=0,Y=!1,U=[],I="",n.reset(),F=1e3},a.onmessage=r=>{typeof r.data=="string"&&Te(r.data)},a.onclose=()=>{b||(w="connecting",!_&&setTimeout(()=>{F=Math.min(F*2,1e4),!b&&!_&&re()},F))},a.onerror=()=>a?.close()}function j(e){C({type:"input",data:e})}function S(){return n.fit()}function H(){s.classList.remove("terminal-pending")}function y(){f&&cancelAnimationFrame(f),h&&clearTimeout(h),S(),f=requestAnimationFrame(()=>{f=0,S()&&H()}),h=setTimeout(()=>{S()&&H()},120)}function xe(){y(),setTimeout(y,50),setTimeout(y,150),setTimeout(y,300)}function ie(e){return typeof e=="string"&&e.startsWith("image/")}function se(e){return e?.files?.length?e.files[0]??null:null}function be(e){if(!e?.items)return null;for(let t=0;t<e.items.length;t++){const r=e.items[t];if(r?.kind==="file"&&ie(r.type))return r.getAsFile()}return null}async function Ee(e){const t=new FormData,r=e instanceof File&&e.name?e.name:"upload";t.append("file",e,r);const c=localStorage.getItem("tmux-web-token"),u={};c&&(u.Authorization="Bearer "+c);const x=await fetch(ge,{method:"POST",body:t,headers:u});if(!x.ok){let G="upload failed";try{const N=await x.json();N.error&&(G=N.error)}catch{}throw new Error(G)}const v=await x.json();if(!v.path)throw new Error("no path in response");return v.path}async function Z(e){try{const t=await Ee(e);j(t)}catch{}}n.onData(e=>j(e)),n.onResize(({cols:e,rows:t})=>C({type:"resize",cols:e,rows:t})),n.onScroll(()=>{w!=="live"||Y||!n.isNearScrollbackTop()||(Y=!0,C({type:"load_history",before:L}))});let A=!1,K=!1,m=null,p=null;const B=document.createElement("div");B.className="terminal-copy-banner",B.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',B.hidden=!0,s.appendChild(B);const T=document.createElement("div");T.className="terminal-copy-banner terminal-copy-toast",T.textContent="Copied",T.hidden=!0,s.appendChild(T);function ae(e,t){const r=s.querySelector(".xterm-screen, canvas"),u=(r&&r.getBoundingClientRect().width>0?r:s).getBoundingClientRect(),x=u.height>0&&n.rows>0?u.height/n.rows:18,v=u.width>0&&n.cols>0?u.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((t-u.top)/x))),col:Math.max(0,Math.min(n.cols-1,Math.floor((e-u.left)/v)))}}async function V(e){if(!e)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(e);return}}catch{}const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",t.style.pointerEvents="none",document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy")}catch{}t.remove()}let z;function J(){T.hidden=!1,z&&clearTimeout(z),z=setTimeout(()=>{T.hidden=!0},1e3)}function k(e){A=e,B.hidden=!e,s.classList.toggle("terminal-copy-mode-active",e),e&&n.focus()}function le(){k(!A)}function Le(e){b||e.button!==0||K||(A||e.shiftKey)&&(e.preventDefault(),e.stopPropagation(),K=!0,m=ae(e.clientX,e.clientY),p=m,n.selectCells(m.col,m.row,p.col,p.row),document.addEventListener("mousemove",ee,!0),document.addEventListener("mouseup",te,!0))}function ee(e){b||!K||!m||(e.preventDefault(),e.stopPropagation(),p=ae(e.clientX,e.clientY),n.selectCells(m.col,m.row,p.col,p.row))}function te(e){if(b||!K||!m||!p)return;e.preventDefault(),e.stopPropagation(),document.removeEventListener("mousemove",ee,!0),document.removeEventListener("mouseup",te,!0),K=!1;const t=n.getCellsText(m.col,m.row,p.col,p.row);m=null,p=null,n.clearSelection(),k(!1),t&&(T.textContent="\u5DF2\u590D\u5236",V(t).then(J)),n.focus()}s.addEventListener("mousedown",Le,!0),document.addEventListener("keydown",Ce,!0);function Ce(e){if(!(b||!n.isFocused()||e.defaultPrevented||e.isComposing)){if(A){if(e.key==="Escape"){e.preventDefault(),e.stopPropagation(),m=null,p=null,n.clearSelection(),k(!1);return}if(e.key==="Enter"||(e.ctrlKey||e.metaKey)&&e.code==="KeyC"){e.preventDefault(),e.stopPropagation(),V(n.getScreenText()).then(J),k(!1);return}}if(e.altKey&&e.code==="KeyC"&&!e.ctrlKey&&!e.metaKey){if(e.preventDefault(),e.stopPropagation(),m&&p){const t=n.getCellsText(m.col,m.row,p.col,p.row);m=null,p=null,n.clearSelection(),k(!1),t&&(T.textContent="Copied",V(t).then(J))}else{const t=n.getSelection();t?(n.clearSelection(),T.textContent="Copied",V(t).then(J)):le()}return}if((e.ctrlKey||e.metaKey)&&e.code==="KeyV"){e.preventDefault(),e.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){const t=await navigator.clipboard.read();for(const r of t)for(const c of r.types)if(ie(c)){const u=await r.getType(c);await Z(u);return}}}catch{}try{const t=await navigator.clipboard?.readText();t&&n.pasteText(ce(t))}catch{}})();return}}}let W=0;function ce(e){return e.split(`\r
5
+ `).then(()=>{H();try{a?.close()}catch{}});return}if(t.type==="auth.ok"){t.token&&localStorage.setItem("tmux-web-token",t.token),F=1e3,S(),M({type:"resize",cols:n.cols,rows:n.rows}),y();return}if(t.type==="auth.failed"){if(t.permanentLock||t.retryAfterMs&&t.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(t.message);return}return}if(t.type==="snapshot"&&typeof t.data=="string"){const r=ne(R(t.data));q=[r],I="",L=typeof t.lines=="number"?t.lines:i.terminal.initialLines,g="live",n.reset(),S(),M({type:"resize",cols:n.cols,rows:n.rows}),n.write(r).then(()=>n.scrollToBottom());return}if(t.type==="window_changed"&&typeof t.activeIndex=="number"){const r=new URL(location.href);r.searchParams.get("window")!==String(t.activeIndex)&&(r.searchParams.set("window",String(t.activeIndex)),history.replaceState(history.state,"",r)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:t.windows}));return}if(t.type==="history"&&typeof t.data=="string"){t.lines>0&&t.data?(q.unshift(ne(t.data)),L+=t.lines,ve(!0,t.lines).finally(()=>{Y=!1})):Y=!1;return}if(t.type==="data"&&typeof t.data=="string"){const r=ne(R(t.data));if(g==="connecting"){g="live",I=r,n.write(r);return}g==="live"&&(I+=r,n.write(r))}}let U=!1;function re(){if(U)return;let e=pe;const t=localStorage.getItem("tmux-web-token");t&&(e+=(e.includes("?")?"&":"?")+"token="+encodeURIComponent(t)),e+=(e.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,a=new WebSocket(e),a.onopen=()=>{g="connecting",L=0,Y=!1,q=[],I="",n.reset(),F=1e3},a.onmessage=r=>{typeof r.data=="string"&&Te(r.data)},a.onclose=()=>{b||(g="connecting",!U&&setTimeout(()=>{F=Math.min(F*2,1e4),!b&&!U&&re()},F))},a.onerror=()=>a?.close()}function j(e){M({type:"input",data:e})}function S(){return n.fit()}function H(){s.classList.remove("terminal-pending")}function y(){d&&cancelAnimationFrame(d),m&&clearTimeout(m),S(),d=requestAnimationFrame(()=>{d=0,S()&&H()}),m=setTimeout(()=>{S()&&H()},120)}function xe(){y(),setTimeout(y,50),setTimeout(y,150),setTimeout(y,300)}function ie(e){return typeof e=="string"&&e.startsWith("image/")}function se(e){return e?.files?.length?e.files[0]??null:null}function be(e){if(!e?.items)return null;for(let t=0;t<e.items.length;t++){const r=e.items[t];if(r?.kind==="file"&&ie(r.type))return r.getAsFile()}return null}async function Ee(e){const t=new FormData,r=e instanceof File&&e.name?e.name:"upload";t.append("file",e,r);const c=localStorage.getItem("tmux-web-token"),u={};c&&(u.Authorization="Bearer "+c);const x=await fetch(we,{method:"POST",body:t,headers:u});if(!x.ok){let G="upload failed";try{const N=await x.json();N.error&&(G=N.error)}catch{}throw new Error(G)}const v=await x.json();if(!v.path)throw new Error("no path in response");return v.path}async function Z(e){try{const t=await Ee(e);j(t)}catch{}}n.onData(e=>j(e)),n.onResize(({cols:e,rows:t})=>M({type:"resize",cols:e,rows:t})),n.onScroll(()=>{g!=="live"||Y||!n.isNearScrollbackTop()||(Y=!0,M({type:"load_history",before:L}))});let A=!1,K=!1,p=null,w=null;const B=document.createElement("div");B.className="terminal-copy-banner",B.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',B.hidden=!0,s.appendChild(B);const T=document.createElement("div");T.className="terminal-copy-banner terminal-copy-toast",T.textContent="Copied",T.hidden=!0,s.appendChild(T);function ae(e,t){const r=s.querySelector(".xterm-screen, canvas"),u=(r&&r.getBoundingClientRect().width>0?r:s).getBoundingClientRect(),x=u.height>0&&n.rows>0?u.height/n.rows:18,v=u.width>0&&n.cols>0?u.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((t-u.top)/x))),col:Math.max(0,Math.min(n.cols-1,Math.floor((e-u.left)/v)))}}async function V(e){if(!e)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(e);return}}catch{}const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",t.style.pointerEvents="none",document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy")}catch{}t.remove()}let z;function W(){T.hidden=!1,z&&clearTimeout(z),z=setTimeout(()=>{T.hidden=!0},1e3)}function k(e){A=e,B.hidden=!e,s.classList.toggle("terminal-copy-mode-active",e),e&&n.focus()}function le(){k(!A)}function Le(e){b||e.button!==0||K||(A||e.shiftKey)&&(e.preventDefault(),e.stopPropagation(),K=!0,p=ae(e.clientX,e.clientY),w=p,n.selectCells(p.col,p.row,w.col,w.row),document.addEventListener("mousemove",ee,!0),document.addEventListener("mouseup",te,!0))}function ee(e){b||!K||!p||(e.preventDefault(),e.stopPropagation(),w=ae(e.clientX,e.clientY),n.selectCells(p.col,p.row,w.col,w.row))}function te(e){if(b||!K||!p||!w)return;e.preventDefault(),e.stopPropagation(),document.removeEventListener("mousemove",ee,!0),document.removeEventListener("mouseup",te,!0),K=!1;const t=n.getCellsText(p.col,p.row,w.col,w.row);p=null,w=null,n.clearSelection(),k(!1),t&&(T.textContent="\u5DF2\u590D\u5236",V(t).then(W)),n.focus()}s.addEventListener("mousedown",Le,!0),document.addEventListener("keydown",Me,!0);function Me(e){if(!(b||!n.isFocused()||e.defaultPrevented||e.isComposing)){if(A){if(e.key==="Escape"){e.preventDefault(),e.stopPropagation(),p=null,w=null,n.clearSelection(),k(!1);return}if(e.key==="Enter"||(e.ctrlKey||e.metaKey)&&e.code==="KeyC"){e.preventDefault(),e.stopPropagation(),V(n.getScreenText()).then(W),k(!1);return}}if(e.altKey&&e.code==="KeyC"&&!e.ctrlKey&&!e.metaKey){if(e.preventDefault(),e.stopPropagation(),p&&w){const t=n.getCellsText(p.col,p.row,w.col,w.row);p=null,w=null,n.clearSelection(),k(!1),t&&(T.textContent="Copied",V(t).then(W))}else{const t=n.getSelection();t?(n.clearSelection(),T.textContent="Copied",V(t).then(W)):le()}return}if((e.ctrlKey||e.metaKey)&&e.code==="KeyV"){e.preventDefault(),e.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){const t=await navigator.clipboard.read();for(const r of t)for(const c of r.types)if(ie(c)){const u=await r.getType(c);await Z(u);return}}}catch{}try{const t=await navigator.clipboard?.readText();t&&n.pasteText(ce(t))}catch{}})();return}}}let J=0;function ce(e){return e.split(`\r
6
6
  `).join(`
7
7
  `).split(`
8
- `).join("\r")}async function Se(e){const t=be(e.clipboardData);if(t){e.preventDefault(),e.stopPropagation();const u=Date.now();if(u-W<50)return;W=u,await Z(t);return}const r=e.clipboardData?.getData("text/plain");if(!r)return;e.preventDefault(),e.stopPropagation();const c=Date.now();c-W<50||(W=c,n.pasteText(ce(r)))}let O=0;function Me(e){e.preventDefault(),O++,se(e.dataTransfer)&&s.classList.add("terminal-drag-over")}function De(e){e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="copy")}function Pe(e){e.preventDefault(),O--,O<=0&&(O=0,s.classList.remove("terminal-drag-over"))}async function Ie(e){e.preventDefault(),O=0,s.classList.remove("terminal-drag-over");const t=se(e.dataTransfer);t&&await Z(t)}function ue(e){!we||e.key!=="Escape"||A||e.defaultPrevented||e.repeat||e.metaKey||e.ctrlKey||e.altKey||n.isFocused()&&(e.preventDefault(),e.stopPropagation(),j("\x1B"))}s.addEventListener("paste",Se),s.addEventListener("dragenter",Me),s.addEventListener("dragover",De),s.addEventListener("dragleave",Pe),s.addEventListener("drop",Ie),document.addEventListener("keydown",ue,!0);function ke(e){if(e.touches.length!==1){l=null;return}const t=e.touches[0];t&&(D(),l={startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,lastT:performance.now(),velocity:0,scrolling:!1},e.stopPropagation())}function Ye(e){if(!l||e.touches.length!==1)return;const t=e.touches[0];if(!t)return;const r=t.clientY-l.startY,c=t.clientX-l.startX;if(!l.scrolling){if(Math.abs(r)<8||Math.abs(r)<Math.abs(c))return;l.scrolling=!0,P=Date.now()+500}e.preventDefault(),e.stopPropagation();const u=performance.now(),x=t.clientY-l.lastY,v=u-l.lastT;v>0&&(l.velocity=x/v),Be(-x),l.lastX=t.clientX,l.lastY=t.clientY,l.lastT=u}function Fe(e){if(!l)return;const t=l.scrolling,r=l.velocity;if(l=null,e.stopPropagation(),!t){n.focus();return}P=Date.now()+500,e.preventDefault(),r&&Q(r)}function Ae(e){l=null,D(),e.stopPropagation()}function Ke(e){e.pointerType==="touch"&&Date.now()<P&&(e.preventDefault(),e.stopPropagation())}function Be(e){const t=s.querySelector(".xterm-rows > div"),r=t?t.getBoundingClientRect().height:16;let c=r>0?Math.round(e/r):e>0?1:-1;c===0&&(c=e>0?1:-1),n.scrollLines(c)}s.addEventListener("touchstart",ke,{passive:!0,capture:!0}),s.addEventListener("touchmove",Ye,{passive:!1,capture:!0}),s.addEventListener("touchend",Fe,{passive:!1,capture:!0}),s.addEventListener("touchcancel",Ae,{passive:!0,capture:!0}),s.addEventListener("pointerup",Ke,!0);function fe(){y()}window.addEventListener("resize",fe),window.visualViewport?.addEventListener("resize",y),window.visualViewport?.addEventListener("scroll",y);const de=new ResizeObserver(()=>y());de.observe(s),document.fonts?.ready.then(()=>{y(),setTimeout(y,50),setTimeout(y,200)}),s.addEventListener("focusin",xe,!0);async function ze(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(e=>setTimeout(e,1e3))])}catch{}}return requestAnimationFrame(()=>{S()&&H(),(async()=>(await ze(),S()&&C({type:"resize",cols:n.cols,rows:n.rows}),re(),y()))()}),{destroy(){if(b=!0,D(),k(!1),z&&clearTimeout(z),document.removeEventListener("mousemove",ee,!0),document.removeEventListener("mouseup",te,!0),a){try{a.close(1e3,"session switch")}catch{}a=void 0}s.innerHTML="",s.classList.remove("terminal-pending"),window.removeEventListener("resize",fe),de.disconnect(),document.removeEventListener("keydown",ue,!0)},focus(){n.focus()},sendInput(e){j(e)},toggleCopyMode(){le()}}})()}export{Xe as initTerminal,ne as stripAltScreenSequences};
8
+ `).join("\r")}async function Se(e){const t=be(e.clipboardData);if(t){e.preventDefault(),e.stopPropagation();const u=Date.now();if(u-J<50)return;J=u,await Z(t);return}const r=e.clipboardData?.getData("text/plain");if(!r)return;e.preventDefault(),e.stopPropagation();const c=Date.now();c-J<50||(J=c,n.pasteText(ce(r)))}let O=0;function Ce(e){e.preventDefault(),O++,se(e.dataTransfer)&&s.classList.add("terminal-drag-over")}function De(e){e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="copy")}function Pe(e){e.preventDefault(),O--,O<=0&&(O=0,s.classList.remove("terminal-drag-over"))}async function Ie(e){e.preventDefault(),O=0,s.classList.remove("terminal-drag-over");const t=se(e.dataTransfer);t&&await Z(t)}function ue(e){!ge||e.key!=="Escape"||A||e.defaultPrevented||e.repeat||e.metaKey||e.ctrlKey||e.altKey||n.isFocused()&&(e.preventDefault(),e.stopPropagation(),j("\x1B"))}s.addEventListener("paste",Se),s.addEventListener("dragenter",Ce),s.addEventListener("dragover",De),s.addEventListener("dragleave",Pe),s.addEventListener("drop",Ie),document.addEventListener("keydown",ue,!0);function ke(e){if(e.touches.length!==1){l=null;return}const t=e.touches[0];t&&(D(),l={startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,lastT:performance.now(),velocity:0,scrolling:!1},e.stopPropagation())}function Ye(e){if(!l||e.touches.length!==1)return;const t=e.touches[0];if(!t)return;const r=t.clientY-l.startY,c=t.clientX-l.startX;if(!l.scrolling){if(Math.abs(r)<8||Math.abs(r)<Math.abs(c))return;l.scrolling=!0,P=Date.now()+500}e.preventDefault(),e.stopPropagation();const u=performance.now(),x=t.clientY-l.lastY,v=u-l.lastT;v>0&&(l.velocity=x/v),Be(-x),l.lastX=t.clientX,l.lastY=t.clientY,l.lastT=u}function Fe(e){if(!l)return;const t=l.scrolling,r=l.velocity;if(l=null,e.stopPropagation(),!t){n.focus();return}P=Date.now()+500,e.preventDefault(),r&&Q(r)}function Ae(e){l=null,D(),e.stopPropagation()}function Ke(e){e.pointerType==="touch"&&Date.now()<P&&(e.preventDefault(),e.stopPropagation())}function Be(e){const t=s.querySelector(".xterm-rows > div"),r=t?t.getBoundingClientRect().height:16;let c=r>0?Math.round(e/r):e>0?1:-1;c===0&&(c=e>0?1:-1),n.scrollLines(c)}s.addEventListener("touchstart",ke,{passive:!0,capture:!0}),s.addEventListener("touchmove",Ye,{passive:!1,capture:!0}),s.addEventListener("touchend",Fe,{passive:!1,capture:!0}),s.addEventListener("touchcancel",Ae,{passive:!0,capture:!0}),s.addEventListener("pointerup",Ke,!0);function fe(){y()}window.addEventListener("resize",fe),window.visualViewport?.addEventListener("resize",y),window.visualViewport?.addEventListener("scroll",y);const de=new ResizeObserver(()=>y());de.observe(s),document.fonts?.ready.then(()=>{y(),setTimeout(y,50),setTimeout(y,200)}),s.addEventListener("focusin",xe,!0);async function ze(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(e=>setTimeout(e,1e3))])}catch{}}return requestAnimationFrame(()=>{S()&&H(),(async()=>(await ze(),S()&&M({type:"resize",cols:n.cols,rows:n.rows}),re(),y()))()}),{destroy(){if(b=!0,D(),k(!1),z&&clearTimeout(z),document.removeEventListener("mousemove",ee,!0),document.removeEventListener("mouseup",te,!0),a){try{a.close(1e3,"session switch")}catch{}a=void 0}s.innerHTML="",s.classList.remove("terminal-pending"),window.removeEventListener("resize",fe),de.disconnect(),document.removeEventListener("keydown",ue,!0)},focus(){n.focus()},sendInput(e){j(e)},toggleCopyMode(){le()}}})()}export{Xe as initTerminal,ne as stripAltScreenSequences};
@@ -1,4 +1,4 @@
1
- import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSessionModalHTML as f,newSessionModalScript as g,reducedMotion as x}from"../shared-layout.js";import{icon as i}from"../icons.js";function h(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function o(t="var(--panel-accent)"){return`box-shadow: 0 0 0 2px ${t}; outline: none;`}function y(t){const{theme:e,fsRoots:n,terminalCfg:r,scrollback:a,wsBase:s}=t,l=`
1
+ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSessionModalHTML as f,newSessionModalScript as g,reducedMotion as b}from"../shared-layout.js";import{icon as i}from"../icons.js";function h(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function o(t="var(--panel-accent)"){return`box-shadow: 0 0 0 2px ${t}; outline: none;`}function y(t){const{theme:e,fsRoots:n,terminalCfg:r,scrollback:a,wsBase:s}=t,l=`
2
2
  *, *::before, *::after { box-sizing: border-box; }
3
3
  html, body {
4
4
  background: var(--page-bg); color: var(--page-fg);
@@ -135,14 +135,8 @@ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSes
135
135
  flex: 1; overflow: hidden; white-space: nowrap;
136
136
  direction: rtl; text-align: left; text-overflow: ellipsis;
137
137
  }
138
- .sg-count {
139
- flex-shrink: 0; font-size: 10px; font-weight: 600;
140
- color: color-mix(in srgb, var(--panel-muted) 80%, transparent);
141
- background: color-mix(in srgb, var(--panel-border) 55%, transparent);
142
- border-radius: 8px; padding: 1px 6px;
143
- }
144
- .sg-arrow { flex-shrink: 0; font-size: 9px; }
145
138
  .session-group-body.collapsed { display: none; }
139
+ .session-group-body .session-item { padding-left: 30px; }
146
140
  .session-item.session-offline { opacity: 0.5; cursor: default; }
147
141
  .session-item .meta { margin-left: auto; }
148
142
  .new-session-sidebar-btn {
@@ -614,7 +608,7 @@ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSes
614
608
  .file-roots-list li:hover { border-color: var(--panel-accent); }
615
609
  .file-roots-list li svg { width: 20px; height: 20px; flex-shrink: 0; fill: var(--panel-accent); }
616
610
 
617
- ${x()}
611
+ ${b()}
618
612
  ${c()}
619
613
  @media (max-width: 640px) {
620
614
  .app-layout { flex-direction: column; }
@@ -626,7 +620,7 @@ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSes
626
620
  .mobile-keys .mk-buttons { display: none; }
627
621
  .mobile-keys.mk-focused .mk-buttons { display: flex; flex-wrap: wrap; gap: 4px; }
628
622
  }
629
- `,b=JSON.stringify(e.terminal).replace(/</g,"\\u003c"),p=JSON.stringify({terminal:r,scrollback:a,theme:e.terminal,fsRoots:n,wsBase:s||""}).replace(/</g,"\\u003c");return`<!DOCTYPE html>
623
+ `,x=JSON.stringify(e.terminal).replace(/</g,"\\u003c"),p=JSON.stringify({terminal:r,scrollback:a,theme:e.terminal,fsRoots:n,wsBase:s||""}).replace(/</g,"\\u003c");return`<!DOCTYPE html>
630
624
  <html lang="en">
631
625
  <head>
632
626
  <meta charset="UTF-8" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tmux-weblink",
3
- "version": "2.0.30",
3
+ "version": "2.0.32",
4
4
  "description": "Access your tmux sessions from the browser. A continuation of tmux-web and persalink.",
5
5
  "type": "module",
6
6
  "bin": {