tmux-weblink 2.0.24 → 2.0.25

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,11 +1,11 @@
1
1
  var Jt=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function je(e){return e.replace(/\x1b\[\?1049[hl]/g,"")}function ie(e){return e.replace(Jt,"")}var ke;function Zt(){return ke||(document.querySelector("link[data-tmux-web-xterm-css]")?ke=Promise.resolve():(ke=new Promise(e=>{let t=document.createElement("link");t.rel="stylesheet",t.href="/assets/xterm.css",t.setAttribute("data-tmux-web-xterm-css",""),t.addEventListener("load",()=>e(),{once:!0}),t.addEventListener("error",()=>e(),{once:!0}),document.head.appendChild(t)}),ke))}var Gt=class Ct{terminal;fitAddon;container;constructor(t,s,i){this.container=t,this.terminal=s,this.fitAddon=i,this.terminal.loadAddon(this.fitAddon),this.terminal.open(t)}static async create(t,s,i){let[{Terminal:o},{FitAddon:r}]=await Promise.all([import("./xterm-BXEES47M.js"),import("./addon-fit-D5N335P2.js"),Zt()]),d=new o({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:s,convertEol:!1,smoothScrollDuration:120,theme:i});return new Ct(t,d,new r)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(t){return new Promise(s=>this.terminal.write(t,s))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(t){this.terminal.scrollToLine(Math.max(0,t))}scrollLines(t){let s=this.terminal.buffer?.active;this.terminal.scrollLines(t)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}fit(){let t=Qt(this.container);return t.width<=0||t.height<=0?!1:(this.fitAddon.fit(),!0)}focus(){this.terminal.focus()}pasteText(t){this.terminal.paste(t)}input(t){this.terminal.input(t,!1)}onData(t){this.terminal.onData(t),this.terminal.onBinary(t)}onResize(t){this.terminal.onResize(t)}onScroll(t){this.terminal.onScroll(t)}attachCustomKeyEventHandler(t){this.terminal.attachCustomKeyEventHandler(t)}isFocused(){let t=document.activeElement;return t?t===this.container||t===this.terminal.textarea||this.container.contains(t)||!!t.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(t,s){let i=this.terminal.buffer.active,[o,r]=t<=s?[t,s]:[s,t],d=i.viewportY,l=[];for(let u=o;u<=r;u++){let v=i.getLine(d+u);l.push(v?v.translateToString(!0):"")}return l.join(`
2
2
  `)}selectRows(t,s){let i=this.terminal.buffer.active,[o,r]=t<=s?[t,s]:[s,t];this.terminal.selectLines(i.viewportY+o,i.viewportY+r)}selectCells(t,s,i,o){let r=this.terminal.buffer.active,d=Math.min(s,o),l=Math.max(s,o);if(d===l){let u=Math.min(t,i),v=Math.max(t,i);this.terminal.select(u,r.viewportY+d,v-u+1)}else this.terminal.selectLines(r.viewportY+d,r.viewportY+l)}getCellsText(t,s,i,o){let r=this.terminal.buffer.active,d=Math.min(s,o),l=Math.max(s,o),u=s<o?t:s>o?i:Math.min(t,i),v=s<o?i:s>o?t:Math.max(t,i),I=r.viewportY,X=[];for(let A=d;A<=l;A++){let fe=r.getLine(I+A);if(!fe){X.push("");continue}let Pe=A===d?u:0,U=A===l?v:this.terminal.cols-1,me="";for(let F=Pe;F<=U;F++){let T=fe.getCell(F);T&&(me+=T.getChars())}X.push(me.replace(/\s+$/,""))}return X.join(`
3
- `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function Qt(e){let t=e.getBoundingClientRect(),s=window.visualViewport;return s?{width:Math.min(t.width,s.width),height:Math.max(0,Math.min(t.height,s.height-Math.max(0,t.top)))}:t}function en(e,t,s){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let i=await Gt.create(e,s.scrollback,s.theme),o,r=0,d,l=null,u=0,v=0,I=0,X=.2,A=5,fe=.94,Pe=.04;function U(){u&&(cancelAnimationFrame(u),u=0),v=0,I=0}function me(n){if(U(),Math.abs(n)<X)return;v=Math.max(-A,Math.min(A,n));let a=()=>{if(R){u=0;return}let c=i.viewportY();tt(v*16);let p=i.viewportY();if(v*=fe,p===c){if(++I>=2){u=0;return}}else I=0;if(Math.abs(v)<Pe){u=0;return}u=requestAnimationFrame(a)};u=requestAnimationFrame(a)}let F=0,T="connecting",ve=0,he=!1,ge=[],O="",R=!1,J=1e3,Tt=location.protocol==="https:"?"wss:":"ws:",Mt=s.wsBase||"/ws",Bt=Tt+"//"+location.host+Mt+"/"+encodeURIComponent(t),It="/api/session/"+encodeURIComponent(t)+"/upload",St=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Dt(){return ge.join("")+O}async function Ht(n,a=0){let c=n?i.viewportY():0,p=n?i.baseY():0,L=ie(Dt());if(i.reset(),!L){n||i.scrollToBottom();return}await i.write(L),n?i.scrollToLine(p+c+a):i.scrollToBottom()}function z(n){o?.readyState===WebSocket.OPEN&&o.send(JSON.stringify(n))}function At(n){let a;try{a=JSON.parse(n)}catch{T==="live"&&(O+=n,i.write(ie(n)));return}if(a.type==="auth.required"){let c=localStorage.getItem("tmux-web-token");c?z({type:"auth.token",token:c}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(a.type==="attach_failed"&&typeof a.message=="string"){ye=!0,T="dead",i.reset(),i.write(`\r
3
+ `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function Qt(e){let t=e.getBoundingClientRect(),s=window.visualViewport;return s?{width:Math.min(t.width,s.width),height:Math.max(0,Math.min(t.height,s.height-Math.max(0,t.top)))}:t}function en(e,t,s){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let i=await Gt.create(e,s.scrollback,s.theme),o,r=0,d,l=null,u=0,v=0,I=0,X=.2,A=5,fe=.94,Pe=.04;function U(){u&&(cancelAnimationFrame(u),u=0),v=0,I=0}function me(n){if(U(),Math.abs(n)<X)return;v=Math.max(-A,Math.min(A,n));let a=()=>{if(R){u=0;return}let c=i.viewportY();tt(-v*16);let p=i.viewportY();if(v*=fe,p===c){if(++I>=2){u=0;return}}else I=0;if(Math.abs(v)<Pe){u=0;return}u=requestAnimationFrame(a)};u=requestAnimationFrame(a)}let F=0,T="connecting",ve=0,he=!1,ge=[],O="",R=!1,J=1e3,Tt=location.protocol==="https:"?"wss:":"ws:",Mt=s.wsBase||"/ws",Bt=Tt+"//"+location.host+Mt+"/"+encodeURIComponent(t),It="/api/session/"+encodeURIComponent(t)+"/upload",St=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Dt(){return ge.join("")+O}async function Ht(n,a=0){let c=n?i.viewportY():0,p=n?i.baseY():0,L=ie(Dt());if(i.reset(),!L){n||i.scrollToBottom();return}await i.write(L),n?i.scrollToLine(p+c+a):i.scrollToBottom()}function z(n){o?.readyState===WebSocket.OPEN&&o.send(JSON.stringify(n))}function At(n){let a;try{a=JSON.parse(n)}catch{T==="live"&&(O+=n,i.write(ie(n)));return}if(a.type==="auth.required"){let c=localStorage.getItem("tmux-web-token");c?z({type:"auth.token",token:c}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(a.type==="attach_failed"&&typeof a.message=="string"){ye=!0,T="dead",i.reset(),i.write(`\r
4
4
  \x1B[31m`+ie(a.message)+`\x1B[0m\r
5
5
  `).then(()=>{be();try{o?.close()}catch{}});return}if(a.type==="auth.ok"){a.token&&localStorage.setItem("tmux-web-token",a.token),J=1e3,j(),z({type:"resize",cols:i.cols,rows:i.rows}),k();return}if(a.type==="auth.failed"){if(a.permanentLock||a.retryAfterMs&&a.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(a.message);return}return}if(a.type==="snapshot"&&typeof a.data=="string"){let c=je(ie(a.data));ge=[c],O="",ve=typeof a.lines=="number"?a.lines:s.terminal.initialLines,T="live",i.reset(),j(),z({type:"resize",cols:i.cols,rows:i.rows}),i.write(c).then(()=>i.scrollToBottom());return}if(a.type==="window_changed"&&typeof a.activeIndex=="number"){let c=new URL(location.href);c.searchParams.get("window")!==String(a.activeIndex)&&(c.searchParams.set("window",String(a.activeIndex)),history.replaceState(history.state,"",c)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:a.windows}));return}if(a.type==="history"&&typeof a.data=="string"){he=!1,a.lines>0&&a.data&&(ge.unshift(je(a.data)),ve+=a.lines,Ht(!0,a.lines));return}if(a.type==="data"&&typeof a.data=="string"){let c=je(ie(a.data));if(T==="connecting"){T="live",O=c,i.write(c);return}T==="live"&&(O+=c,i.write(c))}}let ye=!1;function Ve(){if(ye)return;let n=Bt,a=localStorage.getItem("tmux-web-token");a&&(n+=(n.includes("?")?"&":"?")+"token="+encodeURIComponent(a)),n+=(n.includes("?")?"&":"?")+"cols="+i.cols+"&rows="+i.rows,o=new WebSocket(n),o.onopen=()=>{T="connecting",ve=0,he=!1,ge=[],O="",i.reset(),J=1e3},o.onmessage=c=>{typeof c.data=="string"&&At(c.data)},o.onclose=()=>{R||(T="connecting",!ye&&setTimeout(()=>{J=Math.min(J*2,1e4),!R&&!ye&&Ve()},J))},o.onerror=()=>o?.close()}function we(n){z({type:"input",data:n})}function j(){return i.fit()}function be(){e.classList.remove("terminal-pending")}function k(){r&&cancelAnimationFrame(r),d&&clearTimeout(d),j(),r=requestAnimationFrame(()=>{r=0,j()&&be()}),d=setTimeout(()=>{j()&&be()},120)}function Rt(){k(),setTimeout(k,50),setTimeout(k,150),setTimeout(k,300)}function Xe(n){return typeof n=="string"&&n.startsWith("image/")}function Je(n){return n?.files?.length?n.files[0]??null:null}function $t(n){if(!n?.items)return null;for(let a=0;a<n.items.length;a++){let c=n.items[a];if(c?.kind==="file"&&Xe(c.type))return c.getAsFile()}return null}async function Pt(n){let a=new FormData,c=n instanceof File&&n.name?n.name:"upload";a.append("file",n,c);let p=localStorage.getItem("tmux-web-token"),L={};p&&(L.Authorization="Bearer "+p);let $=await fetch(It,{method:"POST",body:a,headers:L});if(!$.ok){let st="upload failed";try{let at=await $.json();at.error&&(st=at.error)}catch{}throw new Error(st)}let ne=await $.json();if(!ne.path)throw new Error("no path in response");return ne.path}async function Ne(n){try{let a=await Pt(n);we(a)}catch{}}i.onData(n=>we(n)),i.onResize(({cols:n,rows:a})=>z({type:"resize",cols:n,rows:a})),i.onScroll(()=>{T!=="live"||he||!i.isNearScrollbackTop()||(he=!0,z({type:"load_history",before:ve}))});let Z=!1,G=!1,w=null,b=null,Q=document.createElement("div");Q.className="terminal-copy-banner",Q.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',Q.hidden=!0,e.appendChild(Q);let D=document.createElement("div");D.className="terminal-copy-banner terminal-copy-toast",D.textContent="Copied",D.hidden=!0,e.appendChild(D);function Ze(n,a){let c=e.querySelector(".xterm-screen, canvas"),p=(c&&c.getBoundingClientRect().width>0?c:e).getBoundingClientRect(),L=p.height>0&&i.rows>0?p.height/i.rows:18,$=p.width>0&&i.cols>0?p.width/i.cols:9;return{row:Math.max(0,Math.min(i.rows-1,Math.floor((a-p.top)/L))),col:Math.max(0,Math.min(i.cols-1,Math.floor((n-p.left)/$)))}}async function Le(n){if(!n)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(n);return}}catch{}let a=document.createElement("textarea");a.value=n,a.style.position="fixed",a.style.opacity="0",a.style.pointerEvents="none",document.body.appendChild(a),a.focus(),a.select();try{document.execCommand("copy")}catch{}a.remove()}let ee;function Ee(){D.hidden=!1,ee&&clearTimeout(ee),ee=setTimeout(()=>{D.hidden=!0},1e3)}function q(n){Z=n,Q.hidden=!n,e.classList.toggle("terminal-copy-mode-active",n),n&&i.focus()}function Ge(){q(!Z)}function Nt(n){R||n.button!==0||G||(Z||n.shiftKey)&&(n.preventDefault(),n.stopPropagation(),G=!0,w=Ze(n.clientX,n.clientY),b=w,i.selectCells(w.col,w.row,b.col,b.row),document.addEventListener("mousemove",Fe,!0),document.addEventListener("mouseup",ze,!0))}function Fe(n){R||!G||!w||(n.preventDefault(),n.stopPropagation(),b=Ze(n.clientX,n.clientY),i.selectCells(w.col,w.row,b.col,b.row))}function ze(n){if(R||!G||!w||!b)return;n.preventDefault(),n.stopPropagation(),document.removeEventListener("mousemove",Fe,!0),document.removeEventListener("mouseup",ze,!0),G=!1;let a=i.getCellsText(w.col,w.row,b.col,b.row);w=null,b=null,i.clearSelection(),q(!1),a&&(D.textContent="\u5DF2\u590D\u5236",Le(a).then(Ee)),i.focus()}e.addEventListener("mousedown",Nt,!0),document.addEventListener("keydown",Ft,!0);function Ft(n){if(!(R||!i.isFocused()||n.defaultPrevented||n.isComposing)){if(Z){if(n.key==="Escape"){n.preventDefault(),n.stopPropagation(),w=null,b=null,i.clearSelection(),q(!1);return}if(n.key==="Enter"||(n.ctrlKey||n.metaKey)&&n.code==="KeyC"){n.preventDefault(),n.stopPropagation(),Le(i.getScreenText()).then(Ee),q(!1);return}}if(n.altKey&&n.code==="KeyC"&&!n.ctrlKey&&!n.metaKey){if(n.preventDefault(),n.stopPropagation(),w&&b){let a=i.getCellsText(w.col,w.row,b.col,b.row);w=null,b=null,i.clearSelection(),q(!1),a&&(D.textContent="Copied",Le(a).then(Ee))}else{let a=i.getSelection();a?(i.clearSelection(),D.textContent="Copied",Le(a).then(Ee)):Ge()}return}if((n.ctrlKey||n.metaKey)&&n.code==="KeyV"){n.preventDefault(),n.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){let a=await navigator.clipboard.read();for(let c of a)for(let p of c.types)if(Xe(p)){let L=await c.getType(p);await Ne(L);return}}}catch{}try{let a=await navigator.clipboard?.readText();a&&i.pasteText(Qe(a))}catch{}})();return}}}let xe=0;function Qe(n){return n.split(`\r
6
6
  `).join(`
7
7
  `).split(`
8
- `).join("\r")}async function zt(n){let a=$t(n.clipboardData);if(a){n.preventDefault(),n.stopPropagation();let L=Date.now();if(L-xe<50)return;xe=L,await Ne(a);return}let c=n.clipboardData?.getData("text/plain");if(!c)return;n.preventDefault(),n.stopPropagation();let p=Date.now();p-xe<50||(xe=p,i.pasteText(Qe(c)))}let te=0;function jt(n){n.preventDefault(),te++,Je(n.dataTransfer)&&e.classList.add("terminal-drag-over")}function Yt(n){n.preventDefault(),n.dataTransfer&&(n.dataTransfer.dropEffect="copy")}function _t(n){n.preventDefault(),te--,te<=0&&(te=0,e.classList.remove("terminal-drag-over"))}async function Wt(n){n.preventDefault(),te=0,e.classList.remove("terminal-drag-over");let a=Je(n.dataTransfer);a&&await Ne(a)}function et(n){!St||n.key!=="Escape"||Z||n.defaultPrevented||n.repeat||n.metaKey||n.ctrlKey||n.altKey||i.isFocused()&&(n.preventDefault(),n.stopPropagation(),we("\x1B"))}e.addEventListener("paste",zt),e.addEventListener("dragenter",jt),e.addEventListener("dragover",Yt),e.addEventListener("dragleave",_t),e.addEventListener("drop",Wt),document.addEventListener("keydown",et,!0);function Ut(n){if(n.touches.length!==1){l=null;return}let a=n.touches[0];a&&(U(),l={startX:a.clientX,startY:a.clientY,lastX:a.clientX,lastY:a.clientY,lastT:performance.now(),velocity:0,scrolling:!1},n.stopPropagation())}function Ot(n){if(!l||n.touches.length!==1)return;let a=n.touches[0];if(!a)return;let c=a.clientY-l.startY,p=a.clientX-l.startX;if(!l.scrolling){if(Math.abs(c)<8||Math.abs(c)<Math.abs(p))return;l.scrolling=!0,F=Date.now()+500}n.preventDefault(),n.stopPropagation();let L=performance.now(),$=a.clientY-l.lastY,ne=L-l.lastT;ne>0&&(l.velocity=$/ne),tt($),l.lastX=a.clientX,l.lastY=a.clientY,l.lastT=L}function qt(n){if(!l)return;let a=l.scrolling,c=l.velocity;if(l=null,n.stopPropagation(),!a){i.focus();return}F=Date.now()+500,n.preventDefault(),c&&me(c)}function Kt(n){l=null,U(),n.stopPropagation()}function Vt(n){n.pointerType==="touch"&&Date.now()<F&&(n.preventDefault(),n.stopPropagation())}function tt(n){let a=e.querySelector(".xterm-rows > div"),c=a?a.getBoundingClientRect().height:16,p=c>0?Math.round(n/c):n>0?1:-1;p===0&&(p=n>0?1:-1),i.scrollLines(p)}e.addEventListener("touchstart",Ut,{passive:!0,capture:!0}),e.addEventListener("touchmove",Ot,{passive:!1,capture:!0}),e.addEventListener("touchend",qt,{passive:!1,capture:!0}),e.addEventListener("touchcancel",Kt,{passive:!0,capture:!0}),e.addEventListener("pointerup",Vt,!0);function nt(){k()}window.addEventListener("resize",nt),window.visualViewport?.addEventListener("resize",k),window.visualViewport?.addEventListener("scroll",k);let it=new ResizeObserver(()=>k());it.observe(e),document.fonts?.ready.then(()=>{k(),setTimeout(k,50),setTimeout(k,200)}),e.addEventListener("focusin",Rt,!0);async function Xt(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(n=>setTimeout(n,1e3))])}catch{}}return requestAnimationFrame(()=>{j()&&be(),(async()=>(await Xt(),j()&&z({type:"resize",cols:i.cols,rows:i.rows}),Ve(),k()))()}),{destroy(){if(R=!0,U(),q(!1),ee&&clearTimeout(ee),document.removeEventListener("mousemove",Fe,!0),document.removeEventListener("mouseup",ze,!0),o){try{o.close(1e3,"session switch")}catch{}o=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",nt),it.disconnect(),document.removeEventListener("keydown",et,!0)},focus(){i.focus()},sendInput(n){we(n)},toggleCopyMode(){Ge()}}})()}var se=window.__TMUX_WEB_SHELL__,h=null,y=null,ot=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,x=ot;window.__tmuxWebScopeAgent=ot;var Ye="sessions",P="",Ce="",Te="",lt="";function C(e){return x?"/a/"+encodeURIComponent(x)+e:e}var m=document.getElementById("sidebar-content"),Y=document.getElementById("main-placeholder"),M=document.getElementById("terminal-container"),ae=document.getElementById("file-editor"),tn=document.getElementById("fe-path"),B=document.getElementById("fe-status"),oe=document.getElementById("fe-content"),_=document.getElementById("fe-save"),nn=document.getElementById("fe-delete"),sn=document.getElementById("fe-back"),rt=document.getElementById("fe-new-name"),an=document.getElementById("fe-new-btn"),_e=document.getElementById("settings-backdrop"),ct=document.getElementById("settings-popover"),dt=document.querySelector(".sidebar");function on(){return window.matchMedia("(max-width: 640px)").matches}function We(){on()&&dt.classList.add("collapsed")}function ut(){dt.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{ut(),pt("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{ut(),pt("files")});function pt(e){Ye=e,document.querySelectorAll(".mode-btn").forEach(s=>s.classList.remove("active"));let t=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");t&&t.classList.add("active"),e==="sessions"?(Ue="",K()):hn()}var Ue="";async function K(){if(Ye!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents});if(s===Ue)return;Ue=s,ln(t)}catch{m.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}let e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>document.getElementById("new-session-modal")?.classList.add("open"))}function ln(e){m.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';let t=e.recent||[],s=document.createElement("div");s.className="sidebar-section-label"+(x?" clickable":""),s.textContent=x?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",x&&(s.title="Back to hub",s.addEventListener("click",()=>{window.location.href="/"})),m.appendChild(s);for(let o of t){let r=document.createElement("div");r.className="session-item"+(o.name===y&&!x?" active":""),r.setAttribute("data-session",o.name),r.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${o.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
8
+ `).join("\r")}async function zt(n){let a=$t(n.clipboardData);if(a){n.preventDefault(),n.stopPropagation();let L=Date.now();if(L-xe<50)return;xe=L,await Ne(a);return}let c=n.clipboardData?.getData("text/plain");if(!c)return;n.preventDefault(),n.stopPropagation();let p=Date.now();p-xe<50||(xe=p,i.pasteText(Qe(c)))}let te=0;function jt(n){n.preventDefault(),te++,Je(n.dataTransfer)&&e.classList.add("terminal-drag-over")}function Yt(n){n.preventDefault(),n.dataTransfer&&(n.dataTransfer.dropEffect="copy")}function _t(n){n.preventDefault(),te--,te<=0&&(te=0,e.classList.remove("terminal-drag-over"))}async function Wt(n){n.preventDefault(),te=0,e.classList.remove("terminal-drag-over");let a=Je(n.dataTransfer);a&&await Ne(a)}function et(n){!St||n.key!=="Escape"||Z||n.defaultPrevented||n.repeat||n.metaKey||n.ctrlKey||n.altKey||i.isFocused()&&(n.preventDefault(),n.stopPropagation(),we("\x1B"))}e.addEventListener("paste",zt),e.addEventListener("dragenter",jt),e.addEventListener("dragover",Yt),e.addEventListener("dragleave",_t),e.addEventListener("drop",Wt),document.addEventListener("keydown",et,!0);function Ut(n){if(n.touches.length!==1){l=null;return}let a=n.touches[0];a&&(U(),l={startX:a.clientX,startY:a.clientY,lastX:a.clientX,lastY:a.clientY,lastT:performance.now(),velocity:0,scrolling:!1},n.stopPropagation())}function Ot(n){if(!l||n.touches.length!==1)return;let a=n.touches[0];if(!a)return;let c=a.clientY-l.startY,p=a.clientX-l.startX;if(!l.scrolling){if(Math.abs(c)<8||Math.abs(c)<Math.abs(p))return;l.scrolling=!0,F=Date.now()+500}n.preventDefault(),n.stopPropagation();let L=performance.now(),$=a.clientY-l.lastY,ne=L-l.lastT;ne>0&&(l.velocity=$/ne),tt(-$),l.lastX=a.clientX,l.lastY=a.clientY,l.lastT=L}function qt(n){if(!l)return;let a=l.scrolling,c=l.velocity;if(l=null,n.stopPropagation(),!a){i.focus();return}F=Date.now()+500,n.preventDefault(),c&&me(c)}function Kt(n){l=null,U(),n.stopPropagation()}function Vt(n){n.pointerType==="touch"&&Date.now()<F&&(n.preventDefault(),n.stopPropagation())}function tt(n){let a=e.querySelector(".xterm-rows > div"),c=a?a.getBoundingClientRect().height:16,p=c>0?Math.round(n/c):n>0?1:-1;p===0&&(p=n>0?1:-1),i.scrollLines(p)}e.addEventListener("touchstart",Ut,{passive:!0,capture:!0}),e.addEventListener("touchmove",Ot,{passive:!1,capture:!0}),e.addEventListener("touchend",qt,{passive:!1,capture:!0}),e.addEventListener("touchcancel",Kt,{passive:!0,capture:!0}),e.addEventListener("pointerup",Vt,!0);function nt(){k()}window.addEventListener("resize",nt),window.visualViewport?.addEventListener("resize",k),window.visualViewport?.addEventListener("scroll",k);let it=new ResizeObserver(()=>k());it.observe(e),document.fonts?.ready.then(()=>{k(),setTimeout(k,50),setTimeout(k,200)}),e.addEventListener("focusin",Rt,!0);async function Xt(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(n=>setTimeout(n,1e3))])}catch{}}return requestAnimationFrame(()=>{j()&&be(),(async()=>(await Xt(),j()&&z({type:"resize",cols:i.cols,rows:i.rows}),Ve(),k()))()}),{destroy(){if(R=!0,U(),q(!1),ee&&clearTimeout(ee),document.removeEventListener("mousemove",Fe,!0),document.removeEventListener("mouseup",ze,!0),o){try{o.close(1e3,"session switch")}catch{}o=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",nt),it.disconnect(),document.removeEventListener("keydown",et,!0)},focus(){i.focus()},sendInput(n){we(n)},toggleCopyMode(){Ge()}}})()}var se=window.__TMUX_WEB_SHELL__,h=null,y=null,ot=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,x=ot;window.__tmuxWebScopeAgent=ot;var Ye="sessions",P="",Ce="",Te="",lt="";function C(e){return x?"/a/"+encodeURIComponent(x)+e:e}var m=document.getElementById("sidebar-content"),Y=document.getElementById("main-placeholder"),M=document.getElementById("terminal-container"),ae=document.getElementById("file-editor"),tn=document.getElementById("fe-path"),B=document.getElementById("fe-status"),oe=document.getElementById("fe-content"),_=document.getElementById("fe-save"),nn=document.getElementById("fe-delete"),sn=document.getElementById("fe-back"),rt=document.getElementById("fe-new-name"),an=document.getElementById("fe-new-btn"),_e=document.getElementById("settings-backdrop"),ct=document.getElementById("settings-popover"),dt=document.querySelector(".sidebar");function on(){return window.matchMedia("(max-width: 640px)").matches}function We(){on()&&dt.classList.add("collapsed")}function ut(){dt.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{ut(),pt("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{ut(),pt("files")});function pt(e){Ye=e,document.querySelectorAll(".mode-btn").forEach(s=>s.classList.remove("active"));let t=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");t&&t.classList.add("active"),e==="sessions"?(Ue="",K()):hn()}var Ue="";async function K(){if(Ye!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents});if(s===Ue)return;Ue=s,ln(t)}catch{m.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}let e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>document.getElementById("new-session-modal")?.classList.add("open"))}function ln(e){m.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';let t=e.recent||[],s=document.createElement("div");s.className="sidebar-section-label"+(x?" clickable":""),s.textContent=x?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",x&&(s.title="Back to hub",s.addEventListener("click",()=>{window.location.href="/"})),m.appendChild(s);for(let o of t){let r=document.createElement("div");r.className="session-item"+(o.name===y&&!x?" active":""),r.setAttribute("data-session",o.name),r.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${o.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>${f(o.name)}</span>
10
10
  <button class="session-edit-btn" data-session="${f(o.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
11
  `,r.addEventListener("click",l=>{l.target.closest(".session-edit-btn")||le(o.name)}),m.appendChild(r);let d=r.querySelector(".session-edit-btn");d&&d.addEventListener("click",l=>{l.stopPropagation(),Ln(o.name,d)})}let i=e.agents||[];for(let o of i){if(!o.sessions||o.sessions.length===0)continue;let r=o.agentId===x,d=document.createElement("div");d.className="sidebar-section-label machine-label"+(o.online?"":" agent-offline-label")+(!r&&o.online?" clickable":""),d.textContent=o.agentName+(o.online?"":" (offline)"),!r&&o.online&&(d.title="\u6253\u5F00 "+o.agentName,d.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(o.agentId)+"/"})),m.appendChild(d);for(let l of o.sessions){let u=document.createElement("div");u.className="session-item"+(l.name===y&&x===o.agentId?" active":"")+(o.online?"":" session-offline"),u.setAttribute("data-session",l.name),u.setAttribute("data-agent",o.agentId),u.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${l.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
@@ -1,8 +1,8 @@
1
1
  const Ne=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function te(s){return s.replace(/\x1b\[\?1049[hl]/g,"")}function O(s){return s.replace(Ne,"")}let N;function Xe(){return N||(document.querySelector("link[data-tmux-web-xterm-css]")?N=Promise.resolve():(N=new Promise(o=>{const i=document.createElement("link");i.rel="stylesheet",i.href="/assets/xterm.css",i.setAttribute("data-tmux-web-xterm-css",""),i.addEventListener("load",()=>o(),{once:!0}),i.addEventListener("error",()=>o(),{once:!0}),document.head.appendChild(i)}),N))}class ne{terminal;fitAddon;container;constructor(o,i,n){this.container=o,this.terminal=i,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(o)}static async create(o,i,n){const[{Terminal:a},{FitAddon:f}]=await Promise.all([import("@xterm/xterm"),import("@xterm/addon-fit"),Xe()]),h=new a({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:i,convertEol:!1,smoothScrollDuration:120,theme:n});return new ne(o,h,new f)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(o){return new Promise(i=>this.terminal.write(o,i))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(o){this.terminal.scrollToLine(Math.max(0,o))}scrollLines(o){const i=this.terminal.buffer?.active;this.terminal.scrollLines(o)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}fit(){const o=Re(this.container);return o.width<=0||o.height<=0?!1:(this.fitAddon.fit(),!0)}focus(){this.terminal.focus()}pasteText(o){this.terminal.paste(o)}input(o){this.terminal.input(o,!1)}onData(o){this.terminal.onData(o),this.terminal.onBinary(o)}onResize(o){this.terminal.onResize(o)}onScroll(o){this.terminal.onScroll(o)}attachCustomKeyEventHandler(o){this.terminal.attachCustomKeyEventHandler(o)}isFocused(){const o=document.activeElement;return o?o===this.container||o===this.terminal.textarea||this.container.contains(o)||!!o.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(o,i){const n=this.terminal.buffer.active,[a,f]=o<=i?[o,i]:[i,o],h=n.viewportY,l=[];for(let d=a;d<=f;d++){const g=n.getLine(h+d);l.push(g?g.translateToString(!0):"")}return l.join(`
2
2
  `)}selectRows(o,i){const n=this.terminal.buffer.active,[a,f]=o<=i?[o,i]:[i,o];this.terminal.selectLines(n.viewportY+a,n.viewportY+f)}selectCells(o,i,n,a){const f=this.terminal.buffer.active,h=Math.min(i,a),l=Math.max(i,a);if(h===l){const d=Math.min(o,n),g=Math.max(o,n);this.terminal.select(d,f.viewportY+h,g-d+1)}else this.terminal.selectLines(f.viewportY+h,f.viewportY+l)}getCellsText(o,i,n,a){const f=this.terminal.buffer.active,h=Math.min(i,a),l=Math.max(i,a),d=i<a?o:i>a?n:Math.min(o,n),g=i<a?n:i>a?o:Math.max(o,n),I=f.viewportY,k=[];for(let T=h;T<=l;T++){const X=f.getLine(I+T);if(!X){k.push("");continue}const $=T===h?d:0,M=T===l?g:this.terminal.cols-1;let R="";for(let E=$;E<=M;E++){const y=X.getCell(E);y&&(R+=y.getChars())}k.push(R.replace(/\s+$/,""))}return k.join(`
3
- `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}}function Re(s){const o=s.getBoundingClientRect(),i=window.visualViewport;return i?{width:Math.min(o.width,i.width),height:Math.max(0,Math.min(o.height,i.height-Math.max(0,o.top)))}:o}function Ue(s,o,i){return s.innerHTML="",s.classList.add("terminal-pending"),(async()=>{const n=await ne.create(s,i.scrollback,i.theme);let a,f=0,h,l=null,d=0,g=0,I=0;const k=.2,T=5,X=.94,$=.04;function M(){d&&(cancelAnimationFrame(d),d=0),g=0,I=0}function R(e){if(M(),Math.abs(e)<k)return;g=Math.max(-T,Math.min(T,e));const t=()=>{if(x){d=0;return}const r=n.viewportY();ue(g*16);const u=n.viewportY();if(g*=X,u===r){if(++I>=2){d=0;return}}else I=0;if(Math.abs(g)<$){d=0;return}d=requestAnimationFrame(t)};d=requestAnimationFrame(t)}let E=0,y="connecting",U=0,_=!1,q=[],D="",x=!1,Y=1e3;const he=location.protocol==="https:"?"wss:":"ws:",we=i.wsBase||"/ws",ge=he+"//"+location.host+we+"/"+encodeURIComponent(o),ye="/api/session/"+encodeURIComponent(o)+"/upload",ve=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Te(){return q.join("")+D}async function xe(e,t=0){const r=e?n.viewportY():0,u=e?n.baseY():0,c=O(Te());if(n.reset(),!c){e||n.scrollToBottom();return}await n.write(c),e?n.scrollToLine(u+r+t):n.scrollToBottom()}function L(e){a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(e))}function be(e){let t;try{t=JSON.parse(e)}catch{y==="live"&&(D+=e,n.write(O(e)));return}if(t.type==="auth.required"){const r=localStorage.getItem("tmux-web-token");r?L({type:"auth.token",token:r}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(t.type==="attach_failed"&&typeof t.message=="string"){j=!0,y="dead",n.reset(),n.write(`\r
3
+ `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}}function Re(s){const o=s.getBoundingClientRect(),i=window.visualViewport;return i?{width:Math.min(o.width,i.width),height:Math.max(0,Math.min(o.height,i.height-Math.max(0,o.top)))}:o}function Ue(s,o,i){return s.innerHTML="",s.classList.add("terminal-pending"),(async()=>{const n=await ne.create(s,i.scrollback,i.theme);let a,f=0,h,l=null,d=0,g=0,I=0;const k=.2,T=5,X=.94,$=.04;function M(){d&&(cancelAnimationFrame(d),d=0),g=0,I=0}function R(e){if(M(),Math.abs(e)<k)return;g=Math.max(-T,Math.min(T,e));const t=()=>{if(x){d=0;return}const r=n.viewportY();ue(-g*16);const u=n.viewportY();if(g*=X,u===r){if(++I>=2){d=0;return}}else I=0;if(Math.abs(g)<$){d=0;return}d=requestAnimationFrame(t)};d=requestAnimationFrame(t)}let E=0,y="connecting",U=0,_=!1,q=[],D="",x=!1,Y=1e3;const he=location.protocol==="https:"?"wss:":"ws:",we=i.wsBase||"/ws",ge=he+"//"+location.host+we+"/"+encodeURIComponent(o),ye="/api/session/"+encodeURIComponent(o)+"/upload",ve=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Te(){return q.join("")+D}async function xe(e,t=0){const r=e?n.viewportY():0,u=e?n.baseY():0,c=O(Te());if(n.reset(),!c){e||n.scrollToBottom();return}await n.write(c),e?n.scrollToLine(u+r+t):n.scrollToBottom()}function L(e){a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(e))}function be(e){let t;try{t=JSON.parse(e)}catch{y==="live"&&(D+=e,n.write(O(e)));return}if(t.type==="auth.required"){const r=localStorage.getItem("tmux-web-token");r?L({type:"auth.token",token:r}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(t.type==="attach_failed"&&typeof t.message=="string"){j=!0,y="dead",n.reset(),n.write(`\r
4
4
  \x1B[31m`+O(t.message)+`\x1B[0m\r
5
5
  `).then(()=>{H();try{a?.close()}catch{}});return}if(t.type==="auth.ok"){t.token&&localStorage.setItem("tmux-web-token",t.token),Y=1e3,C(),L({type:"resize",cols:n.cols,rows:n.rows}),w();return}if(t.type==="auth.failed"){if(t.permanentLock||t.retryAfterMs&&t.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(t.message);return}return}if(t.type==="snapshot"&&typeof t.data=="string"){const r=te(O(t.data));q=[r],D="",U=typeof t.lines=="number"?t.lines:i.terminal.initialLines,y="live",n.reset(),C(),L({type:"resize",cols:n.cols,rows:n.rows}),n.write(r).then(()=>n.scrollToBottom());return}if(t.type==="window_changed"&&typeof t.activeIndex=="number"){const r=new URL(location.href);r.searchParams.get("window")!==String(t.activeIndex)&&(r.searchParams.set("window",String(t.activeIndex)),history.replaceState(history.state,"",r)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:t.windows}));return}if(t.type==="history"&&typeof t.data=="string"){_=!1,t.lines>0&&t.data&&(q.unshift(te(t.data)),U+=t.lines,xe(!0,t.lines));return}if(t.type==="data"&&typeof t.data=="string"){const r=te(O(t.data));if(y==="connecting"){y="live",D=r,n.write(r);return}y==="live"&&(D+=r,n.write(r))}}let j=!1;function oe(){if(j)return;let e=ge;const t=localStorage.getItem("tmux-web-token");t&&(e+=(e.includes("?")?"&":"?")+"token="+encodeURIComponent(t)),e+=(e.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,a=new WebSocket(e),a.onopen=()=>{y="connecting",U=0,_=!1,q=[],D="",n.reset(),Y=1e3},a.onmessage=r=>{typeof r.data=="string"&&be(r.data)},a.onclose=()=>{x||(y="connecting",!j&&setTimeout(()=>{Y=Math.min(Y*2,1e4),!x&&!j&&oe()},Y))},a.onerror=()=>a?.close()}function V(e){L({type:"input",data:e})}function C(){return n.fit()}function H(){s.classList.remove("terminal-pending")}function w(){f&&cancelAnimationFrame(f),h&&clearTimeout(h),C(),f=requestAnimationFrame(()=>{f=0,C()&&H()}),h=setTimeout(()=>{C()&&H()},120)}function Ee(){w(),setTimeout(w,50),setTimeout(w,150),setTimeout(w,300)}function re(e){return typeof e=="string"&&e.startsWith("image/")}function ie(e){return e?.files?.length?e.files[0]??null:null}function Le(e){if(!e?.items)return null;for(let t=0;t<e.items.length;t++){const r=e.items[t];if(r?.kind==="file"&&re(r.type))return r.getAsFile()}return null}async function Ce(e){const t=new FormData,r=e instanceof File&&e.name?e.name:"upload";t.append("file",e,r);const u=localStorage.getItem("tmux-web-token"),c={};u&&(c.Authorization="Bearer "+u);const b=await fetch(ye,{method:"POST",body:t,headers:c});if(!b.ok){let me="upload failed";try{const pe=await b.json();pe.error&&(me=pe.error)}catch{}throw new Error(me)}const S=await b.json();if(!S.path)throw new Error("no path in response");return S.path}async function Q(e){try{const t=await Ce(e);V(t)}catch{}}n.onData(e=>V(e)),n.onResize(({cols:e,rows:t})=>L({type:"resize",cols:e,rows:t})),n.onScroll(()=>{y!=="live"||_||!n.isNearScrollbackTop()||(_=!0,L({type:"load_history",before:U}))});let F=!1,A=!1,m=null,p=null;const K=document.createElement("div");K.className="terminal-copy-banner",K.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',K.hidden=!0,s.appendChild(K);const v=document.createElement("div");v.className="terminal-copy-banner terminal-copy-toast",v.textContent="Copied",v.hidden=!0,s.appendChild(v);function se(e,t){const r=s.querySelector(".xterm-screen, canvas"),c=(r&&r.getBoundingClientRect().width>0?r:s).getBoundingClientRect(),b=c.height>0&&n.rows>0?c.height/n.rows:18,S=c.width>0&&n.cols>0?c.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((t-c.top)/b))),col:Math.max(0,Math.min(n.cols-1,Math.floor((e-c.left)/S)))}}async function J(e){if(!e)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(e);return}}catch{}const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",t.style.pointerEvents="none",document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy")}catch{}t.remove()}let B;function W(){v.hidden=!1,B&&clearTimeout(B),B=setTimeout(()=>{v.hidden=!0},1e3)}function P(e){F=e,K.hidden=!e,s.classList.toggle("terminal-copy-mode-active",e),e&&n.focus()}function ae(){P(!F)}function Se(e){x||e.button!==0||A||(F||e.shiftKey)&&(e.preventDefault(),e.stopPropagation(),A=!0,m=se(e.clientX,e.clientY),p=m,n.selectCells(m.col,m.row,p.col,p.row),document.addEventListener("mousemove",Z,!0),document.addEventListener("mouseup",ee,!0))}function Z(e){x||!A||!m||(e.preventDefault(),e.stopPropagation(),p=se(e.clientX,e.clientY),n.selectCells(m.col,m.row,p.col,p.row))}function ee(e){if(x||!A||!m||!p)return;e.preventDefault(),e.stopPropagation(),document.removeEventListener("mousemove",Z,!0),document.removeEventListener("mouseup",ee,!0),A=!1;const t=n.getCellsText(m.col,m.row,p.col,p.row);m=null,p=null,n.clearSelection(),P(!1),t&&(v.textContent="\u5DF2\u590D\u5236",J(t).then(W)),n.focus()}s.addEventListener("mousedown",Se,!0),document.addEventListener("keydown",Me,!0);function Me(e){if(!(x||!n.isFocused()||e.defaultPrevented||e.isComposing)){if(F){if(e.key==="Escape"){e.preventDefault(),e.stopPropagation(),m=null,p=null,n.clearSelection(),P(!1);return}if(e.key==="Enter"||(e.ctrlKey||e.metaKey)&&e.code==="KeyC"){e.preventDefault(),e.stopPropagation(),J(n.getScreenText()).then(W),P(!1);return}}if(e.altKey&&e.code==="KeyC"&&!e.ctrlKey&&!e.metaKey){if(e.preventDefault(),e.stopPropagation(),m&&p){const t=n.getCellsText(m.col,m.row,p.col,p.row);m=null,p=null,n.clearSelection(),P(!1),t&&(v.textContent="Copied",J(t).then(W))}else{const t=n.getSelection();t?(n.clearSelection(),v.textContent="Copied",J(t).then(W)):ae()}return}if((e.ctrlKey||e.metaKey)&&e.code==="KeyV"){e.preventDefault(),e.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){const t=await navigator.clipboard.read();for(const r of t)for(const u of r.types)if(re(u)){const c=await r.getType(u);await Q(c);return}}}catch{}try{const t=await navigator.clipboard?.readText();t&&n.pasteText(le(t))}catch{}})();return}}}let G=0;function le(e){return e.split(`\r
6
6
  `).join(`
7
7
  `).split(`
8
- `).join("\r")}async function De(e){const t=Le(e.clipboardData);if(t){e.preventDefault(),e.stopPropagation();const c=Date.now();if(c-G<50)return;G=c,await Q(t);return}const r=e.clipboardData?.getData("text/plain");if(!r)return;e.preventDefault(),e.stopPropagation();const u=Date.now();u-G<50||(G=u,n.pasteText(le(r)))}let z=0;function Pe(e){e.preventDefault(),z++,ie(e.dataTransfer)&&s.classList.add("terminal-drag-over")}function Ie(e){e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="copy")}function ke(e){e.preventDefault(),z--,z<=0&&(z=0,s.classList.remove("terminal-drag-over"))}async function Ye(e){e.preventDefault(),z=0,s.classList.remove("terminal-drag-over");const t=ie(e.dataTransfer);t&&await Q(t)}function ce(e){!ve||e.key!=="Escape"||F||e.defaultPrevented||e.repeat||e.metaKey||e.ctrlKey||e.altKey||n.isFocused()&&(e.preventDefault(),e.stopPropagation(),V("\x1B"))}s.addEventListener("paste",De),s.addEventListener("dragenter",Pe),s.addEventListener("dragover",Ie),s.addEventListener("dragleave",ke),s.addEventListener("drop",Ye),document.addEventListener("keydown",ce,!0);function Fe(e){if(e.touches.length!==1){l=null;return}const t=e.touches[0];t&&(M(),l={startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,lastT:performance.now(),velocity:0,scrolling:!1},e.stopPropagation())}function Ae(e){if(!l||e.touches.length!==1)return;const t=e.touches[0];if(!t)return;const r=t.clientY-l.startY,u=t.clientX-l.startX;if(!l.scrolling){if(Math.abs(r)<8||Math.abs(r)<Math.abs(u))return;l.scrolling=!0,E=Date.now()+500}e.preventDefault(),e.stopPropagation();const c=performance.now(),b=t.clientY-l.lastY,S=c-l.lastT;S>0&&(l.velocity=b/S),ue(b),l.lastX=t.clientX,l.lastY=t.clientY,l.lastT=c}function Ke(e){if(!l)return;const t=l.scrolling,r=l.velocity;if(l=null,e.stopPropagation(),!t){n.focus();return}E=Date.now()+500,e.preventDefault(),r&&R(r)}function Be(e){l=null,M(),e.stopPropagation()}function ze(e){e.pointerType==="touch"&&Date.now()<E&&(e.preventDefault(),e.stopPropagation())}function ue(e){const t=s.querySelector(".xterm-rows > div"),r=t?t.getBoundingClientRect().height:16;let u=r>0?Math.round(e/r):e>0?1:-1;u===0&&(u=e>0?1:-1),n.scrollLines(u)}s.addEventListener("touchstart",Fe,{passive:!0,capture:!0}),s.addEventListener("touchmove",Ae,{passive:!1,capture:!0}),s.addEventListener("touchend",Ke,{passive:!1,capture:!0}),s.addEventListener("touchcancel",Be,{passive:!0,capture:!0}),s.addEventListener("pointerup",ze,!0);function fe(){w()}window.addEventListener("resize",fe),window.visualViewport?.addEventListener("resize",w),window.visualViewport?.addEventListener("scroll",w);const de=new ResizeObserver(()=>w());de.observe(s),document.fonts?.ready.then(()=>{w(),setTimeout(w,50),setTimeout(w,200)}),s.addEventListener("focusin",Ee,!0);async function Oe(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(e=>setTimeout(e,1e3))])}catch{}}return requestAnimationFrame(()=>{C()&&H(),(async()=>(await Oe(),C()&&L({type:"resize",cols:n.cols,rows:n.rows}),oe(),w()))()}),{destroy(){if(x=!0,M(),P(!1),B&&clearTimeout(B),document.removeEventListener("mousemove",Z,!0),document.removeEventListener("mouseup",ee,!0),a){try{a.close(1e3,"session switch")}catch{}a=void 0}s.innerHTML="",s.classList.remove("terminal-pending"),window.removeEventListener("resize",fe),de.disconnect(),document.removeEventListener("keydown",ce,!0)},focus(){n.focus()},sendInput(e){V(e)},toggleCopyMode(){ae()}}})()}export{Ue as initTerminal,te as stripAltScreenSequences};
8
+ `).join("\r")}async function De(e){const t=Le(e.clipboardData);if(t){e.preventDefault(),e.stopPropagation();const c=Date.now();if(c-G<50)return;G=c,await Q(t);return}const r=e.clipboardData?.getData("text/plain");if(!r)return;e.preventDefault(),e.stopPropagation();const u=Date.now();u-G<50||(G=u,n.pasteText(le(r)))}let z=0;function Pe(e){e.preventDefault(),z++,ie(e.dataTransfer)&&s.classList.add("terminal-drag-over")}function Ie(e){e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="copy")}function ke(e){e.preventDefault(),z--,z<=0&&(z=0,s.classList.remove("terminal-drag-over"))}async function Ye(e){e.preventDefault(),z=0,s.classList.remove("terminal-drag-over");const t=ie(e.dataTransfer);t&&await Q(t)}function ce(e){!ve||e.key!=="Escape"||F||e.defaultPrevented||e.repeat||e.metaKey||e.ctrlKey||e.altKey||n.isFocused()&&(e.preventDefault(),e.stopPropagation(),V("\x1B"))}s.addEventListener("paste",De),s.addEventListener("dragenter",Pe),s.addEventListener("dragover",Ie),s.addEventListener("dragleave",ke),s.addEventListener("drop",Ye),document.addEventListener("keydown",ce,!0);function Fe(e){if(e.touches.length!==1){l=null;return}const t=e.touches[0];t&&(M(),l={startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,lastT:performance.now(),velocity:0,scrolling:!1},e.stopPropagation())}function Ae(e){if(!l||e.touches.length!==1)return;const t=e.touches[0];if(!t)return;const r=t.clientY-l.startY,u=t.clientX-l.startX;if(!l.scrolling){if(Math.abs(r)<8||Math.abs(r)<Math.abs(u))return;l.scrolling=!0,E=Date.now()+500}e.preventDefault(),e.stopPropagation();const c=performance.now(),b=t.clientY-l.lastY,S=c-l.lastT;S>0&&(l.velocity=b/S),ue(-b),l.lastX=t.clientX,l.lastY=t.clientY,l.lastT=c}function Ke(e){if(!l)return;const t=l.scrolling,r=l.velocity;if(l=null,e.stopPropagation(),!t){n.focus();return}E=Date.now()+500,e.preventDefault(),r&&R(r)}function Be(e){l=null,M(),e.stopPropagation()}function ze(e){e.pointerType==="touch"&&Date.now()<E&&(e.preventDefault(),e.stopPropagation())}function ue(e){const t=s.querySelector(".xterm-rows > div"),r=t?t.getBoundingClientRect().height:16;let u=r>0?Math.round(e/r):e>0?1:-1;u===0&&(u=e>0?1:-1),n.scrollLines(u)}s.addEventListener("touchstart",Fe,{passive:!0,capture:!0}),s.addEventListener("touchmove",Ae,{passive:!1,capture:!0}),s.addEventListener("touchend",Ke,{passive:!1,capture:!0}),s.addEventListener("touchcancel",Be,{passive:!0,capture:!0}),s.addEventListener("pointerup",ze,!0);function fe(){w()}window.addEventListener("resize",fe),window.visualViewport?.addEventListener("resize",w),window.visualViewport?.addEventListener("scroll",w);const de=new ResizeObserver(()=>w());de.observe(s),document.fonts?.ready.then(()=>{w(),setTimeout(w,50),setTimeout(w,200)}),s.addEventListener("focusin",Ee,!0);async function Oe(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(e=>setTimeout(e,1e3))])}catch{}}return requestAnimationFrame(()=>{C()&&H(),(async()=>(await Oe(),C()&&L({type:"resize",cols:n.cols,rows:n.rows}),oe(),w()))()}),{destroy(){if(x=!0,M(),P(!1),B&&clearTimeout(B),document.removeEventListener("mousemove",Z,!0),document.removeEventListener("mouseup",ee,!0),a){try{a.close(1e3,"session switch")}catch{}a=void 0}s.innerHTML="",s.classList.remove("terminal-pending"),window.removeEventListener("resize",fe),de.disconnect(),document.removeEventListener("keydown",ce,!0)},focus(){n.focus()},sendInput(e){V(e)},toggleCopyMode(){ae()}}})()}export{Ue as initTerminal,te as stripAltScreenSequences};
@@ -1,4 +1,4 @@
1
- import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSessionModalHTML as f,newSessionModalScript as g,reducedMotion as b}from"../shared-layout.js";import{icon as i}from"../icons.js";function h(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function o(t="var(--panel-accent)"){return`box-shadow: 0 0 0 2px ${t}; outline: none;`}function y(t){const{theme:e,fsRoots:n,terminalCfg:r,scrollback:a,wsBase:s}=t,p=`
1
+ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSessionModalHTML as f,newSessionModalScript as g,reducedMotion as b}from"../shared-layout.js";import{icon as i}from"../icons.js";function h(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function o(t="var(--panel-accent)"){return`box-shadow: 0 0 0 2px ${t}; outline: none;`}function y(t){const{theme:e,fsRoots:n,terminalCfg:r,scrollback:a,wsBase:s}=t,l=`
2
2
  *, *::before, *::after { box-sizing: border-box; }
3
3
  html, body {
4
4
  background: var(--page-bg); color: var(--page-fg);
@@ -497,6 +497,9 @@ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSes
497
497
  /* \u2500\u2500 Terminal container \u2500\u2500 */
498
498
  #terminal-container {
499
499
  flex: 1; overflow: hidden; position: relative;
500
+ /* Disable the browser's touch -> synthetic-wheel path so the custom
501
+ touch drag/inertia in terminal-core handles scrolling exclusively. */
502
+ touch-action: none;
500
503
  }
501
504
  #terminal-container.terminal-pending { visibility: hidden; }
502
505
  #terminal-container.terminal-pending::before {
@@ -602,7 +605,7 @@ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSes
602
605
  .mobile-keys .mk-buttons { display: none; }
603
606
  .mobile-keys.mk-focused .mk-buttons { display: flex; flex-wrap: wrap; gap: 4px; }
604
607
  }
605
- `,x=JSON.stringify(e.terminal).replace(/</g,"\\u003c"),l=JSON.stringify({terminal:r,scrollback:a,theme:e.terminal,fsRoots:n,wsBase:s||""}).replace(/</g,"\\u003c");return`<!DOCTYPE html>
608
+ `,x=JSON.stringify(e.terminal).replace(/</g,"\\u003c"),p=JSON.stringify({terminal:r,scrollback:a,theme:e.terminal,fsRoots:n,wsBase:s||""}).replace(/</g,"\\u003c");return`<!DOCTYPE html>
606
609
  <html lang="en">
607
610
  <head>
608
611
  <meta charset="UTF-8" />
@@ -616,7 +619,7 @@ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSes
616
619
  <title>tmux-weblink</title>
617
620
  <style>
618
621
  ${d(e.shell)}
619
- ${p}
622
+ ${l}
620
623
  </style>
621
624
  </head>
622
625
  <body>
@@ -760,7 +763,7 @@ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSes
760
763
  ${f()}
761
764
 
762
765
  <script>
763
- window.__TMUX_WEB_SHELL__ = ${l};
766
+ window.__TMUX_WEB_SHELL__ = ${p};
764
767
  </script>
765
768
  <script type="module">
766
769
  await import('/assets/shell-client.js');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tmux-weblink",
3
- "version": "2.0.24",
3
+ "version": "2.0.25",
4
4
  "description": "Access your tmux sessions from the browser. A continuation of tmux-web and persalink.",
5
5
  "type": "module",
6
6
  "bin": {