tmux-weblink 2.2.2 → 2.2.3

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