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