tmux-weblink 2.0.19 → 2.0.20
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.
|
@@ -41,5 +41,5 @@ var Yt=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function
|
|
|
41
41
|
<button class="btn" id="sp-cancel">Cancel</button>
|
|
42
42
|
</div>
|
|
43
43
|
<hr class="sp-divider" />
|
|
44
|
-
<button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(P);function dn(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 pn(e,t){W=e;let s=document.getElementById("sp-name");s.value=e,le.classList.add("open"),P.style.display="block",dn(t),setTimeout(()=>s.focus(),50)}function re(){le.classList.remove("open"),P.style.display="none"}le.addEventListener("click",re),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===W){re();return}try{if(!(await fetch(k("/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldName:W,newName:e})})).ok)return;re(),O(),g===W&&se(e)}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(confirm('Delete session "'+W+'"?'))try{if(!(await fetch(k("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:W})})).ok)return;re(),g===W&&(v&&(v.destroy(),v=null),g=null,T.style.display="none",j.style.display="flex"),O()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",re);var un={esc:"\x1B",tab:" ","s-tab":"\x1B[Z",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",space:" ",enter:"\r",exit:"exit\r",yes:"yes\r"};document.getElementById("mobile-keys").addEventListener("click",e=>{let t=e.target.closest("button[data-key]");if(!t||!v)return;let s=un[t.dataset.key];s&&(v.sendInput(s),v.focus())});var S=document.getElementById("mk-input"),vt=document.getElementById("mk-send");function ht(){if(!S||!v)return;let e=S.value;e&&(v.sendInput(e+"\r"),S.value="",S.rows=1,v.focus())}if(S&&(S.addEventListener("input",()=>{S.rows=1;let e=S.value.split(`
|
|
44
|
+
<button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(P);function dn(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 pn(e,t){W=e;let s=document.getElementById("sp-name");s.value=e,le.classList.add("open"),P.style.display="block",dn(t),setTimeout(()=>s.focus(),50)}function re(){le.classList.remove("open"),P.style.display="none"}le.addEventListener("click",re),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===W){re();return}try{if(!(await fetch(k("/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldName:W,newName:e})})).ok)return;re(),O(),g===W&&se(e)}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(confirm('Delete session "'+W+'"?'))try{if(!(await fetch(k("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:W})})).ok)return;re(),g===W&&(v&&(v.destroy(),v=null),g=null,T.style.display="none",j.style.display="flex"),O()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",re);var un={esc:"\x1B",tab:" ","s-tab":"\x1B[Z",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",space:" ",enter:"\r",exit:"exit\r","ctrl-c":"",yes:"yes\r"};document.getElementById("mobile-keys").addEventListener("click",e=>{let t=e.target.closest("button[data-key]");if(!t||!v)return;let s=un[t.dataset.key];s&&(v.sendInput(s),v.focus())});var S=document.getElementById("mk-input"),vt=document.getElementById("mk-send");function ht(){if(!S||!v)return;let e=S.value;e&&(v.sendInput(e+"\r"),S.value="",S.rows=1,v.focus())}if(S&&(S.addEventListener("input",()=>{S.rows=1;let e=S.value.split(`
|
|
45
45
|
`).length;S.rows=Math.min(e,4)}),S.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),ht())})),vt&&vt.addEventListener("click",ht),window.visualViewport){let e=document.querySelector(".app-layout"),t=()=>{e&&(e.style.height=window.visualViewport.height+"px"),window.scrollTo(0,0),document.documentElement.scrollTop=0,document.body.scrollTop=0};window.visualViewport.addEventListener("resize",t),window.addEventListener("orientationchange",()=>setTimeout(t,100)),document.addEventListener("touchstart",()=>{(window.scrollY>0||document.documentElement.scrollTop>0)&&window.scrollTo(0,0)},{passive:!0})}var ze=document.getElementById("process-panel"),ce=document.getElementById("proc-list"),fn=document.getElementById("proc-close"),_e=document.getElementById("proc-backdrop"),mn=document.getElementById("header-ram");function vn(){ce.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(k("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){ce.innerHTML='<div class="proc-empty">No processes</div>';return}let t="";for(let s of e){let i=s.rss,o=i<1048576?(i/1024).toFixed(0)+"K":(i/1048576).toFixed(1)+"M";t+='<div class="proc-row" data-pid="'+s.pid+'"><span class="proc-mem">'+s.mem+'%</span><span class="proc-rss">'+o+'</span><span class="proc-cmd" title="'+f(s.command)+'">'+f(s.command)+'</span><button class="proc-kill" title="Kill PID '+s.pid+'">×</button></div>'}ce.innerHTML=t;for(let s of ce.querySelectorAll(".proc-row")){let i=s.querySelector(".proc-kill");i&&i.addEventListener("click",o=>{let r=o.target.closest(".proc-row");!r||!confirm("Kill PID "+r.dataset.pid+"?")||fetch(k("/api/system/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pid:parseInt(r.dataset.pid,10)})}).then(c=>c.json()).then(c=>{c.ok?r.style.opacity="0.3":alert("Failed: "+(c.error||"unknown"))}).catch(()=>alert("Network error"))})}}).catch(()=>{ce.innerHTML='<div class="proc-empty">Failed to load</div>'})}function hn(){ze.classList.add("open"),_e.classList.add("open"),vn()}function Be(){ze.classList.remove("open"),_e.classList.remove("open")}mn.addEventListener("click",e=>{e.stopPropagation(),ze.classList.contains("open")?Be():hn()}),fn.addEventListener("click",Be),_e.addEventListener("click",Be),window.__openSession=se,window.__refreshSidebar=O,O(),Re(),setInterval(()=>{document.visibilityState==="visible"&&O()},1e4);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{initTerminal as ke}from"./terminal-core.js";const T=window.__TMUX_WEB_SHELL__;let p=null,u=null;const ie=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null;let v=ie;window.__tmuxWebScopeAgent=ie;let Y="sessions",E="",j="",W="",oe="";function y(e){return v?"/a/"+encodeURIComponent(v)+e:e}const r=document.getElementById("sidebar-content"),C=document.getElementById("main-placeholder"),h=document.getElementById("terminal-container"),H=document.getElementById("file-editor"),Ce=document.getElementById("fe-path"),b=document.getElementById("fe-status"),$=document.getElementById("fe-content"),I=document.getElementById("fe-save"),Ie=document.getElementById("fe-delete"),
|
|
1
|
+
import{initTerminal as ke}from"./terminal-core.js";const T=window.__TMUX_WEB_SHELL__;let p=null,u=null;const ie=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null;let v=ie;window.__tmuxWebScopeAgent=ie;let Y="sessions",E="",j="",W="",oe="";function y(e){return v?"/a/"+encodeURIComponent(v)+e:e}const r=document.getElementById("sidebar-content"),C=document.getElementById("main-placeholder"),h=document.getElementById("terminal-container"),H=document.getElementById("file-editor"),Ce=document.getElementById("fe-path"),b=document.getElementById("fe-status"),$=document.getElementById("fe-content"),I=document.getElementById("fe-save"),Ie=document.getElementById("fe-delete"),xe=document.getElementById("fe-back"),ae=document.getElementById("fe-new-name"),Be=document.getElementById("fe-new-btn"),Z=document.getElementById("settings-backdrop"),le=document.getElementById("settings-popover"),ce=document.querySelector(".sidebar");function Me(){return window.matchMedia("(max-width: 640px)").matches}function Q(){Me()&&ce.classList.add("collapsed")}function de(){ce.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{de(),re("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{de(),re("files")});function re(e){Y=e,document.querySelectorAll(".mode-btn").forEach(t=>t.classList.remove("active"));const n=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");n&&n.classList.add("active"),e==="sessions"?(ee="",M()):_e()}let ee="";async function M(){if(Y!=="sessions")return;try{const t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents});if(s===ee)return;ee=s,Se(t)}catch{r.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}const e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>document.getElementById("new-session-modal")?.classList.add("open"))}function Se(e){r.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';const n=e.recent||[],t=document.createElement("div");t.className="sidebar-section-label"+(v?" clickable":""),t.textContent=v?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",v&&(t.title="Back to hub",t.addEventListener("click",()=>{window.location.href="/"})),r.appendChild(t);for(const i of n){const l=document.createElement("div");l.className="session-item"+(i.name===u&&!v?" active":""),l.setAttribute("data-session",i.name),l.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${i.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
|
|
2
2
|
<span>${d(i.name)}</span>
|
|
3
3
|
<button class="session-edit-btn" data-session="${d(i.name)}" title="Edit session"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>
|
|
4
4
|
`,l.addEventListener("click",c=>{c.target.closest(".session-edit-btn")||R(i.name)}),r.appendChild(l);const o=l.querySelector(".session-edit-btn");o&&o.addEventListener("click",c=>{c.stopPropagation(),Oe(i.name,o)})}const s=e.agents||[];for(const i of s){if(!i.sessions||i.sessions.length===0)continue;const l=i.agentId===v,o=document.createElement("div");o.className="sidebar-section-label machine-label"+(i.online?"":" agent-offline-label")+(!l&&i.online?" clickable":""),o.textContent=i.agentName+(i.online?"":" (offline)"),!l&&i.online&&(o.title="\u6253\u5F00 "+i.agentName,o.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(i.agentId)+"/"})),r.appendChild(o);for(const c of i.sessions){const a=document.createElement("div");a.className="session-item"+(c.name===u&&v===i.agentId?" active":"")+(i.online?"":" session-offline"),a.setAttribute("data-session",c.name),a.setAttribute("data-agent",i.agentId),a.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${c.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
|
|
@@ -25,7 +25,7 @@ import{initTerminal as ke}from"./terminal-core.js";const T=window.__TMUX_WEB_SHE
|
|
|
25
25
|
<button class="diff-back">\u2190 Back</button>
|
|
26
26
|
<span class="diff-filename">${d(e)}</span>
|
|
27
27
|
<span class="diff-filesize">${i} lines</span>
|
|
28
|
-
</div><div class="diff-content">${s}</div></div>`,m.querySelector(".diff-back")?.addEventListener("click",()=>{m.innerHTML=ve,te(),f&&m.querySelectorAll(".git-popover-item").forEach(l=>{const o=parseInt(l.dataset.idx||"0",10),c=f.files[o];!c||c.status==="D"||(l.style.cursor="pointer",l.addEventListener("click",()=>he(c.path)))}),me()})}function Pe(e,n,t){if(!n&&!t){O.textContent="No diff",U.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}const{html:s,lineCount:i}=ye(n,t);ue.textContent=e,O.textContent=i+" lines",U.innerHTML=s}function Ae(){fe.style.display="none",V?(h.style.display="",h.classList.add("terminal-pending"),R(V),V=null):u?(h.style.display="",h.classList.add("terminal-pending"),we()):C.style.display="flex"}Re.addEventListener("click",Ae);function q(){m.classList.remove("open"),G.classList.remove("open")}G.addEventListener("click",q),document.addEventListener("keydown",e=>{e.key==="Escape"&&(q(),X())});async function be(e){try{const t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){const s=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(s.ok){const i=await s.json();f=i,D(i);return}}}catch{}f=null,D(null)}let J=null;function we(){K(),u&&(be(u),J=setInterval(()=>{u&&be(u)},3e4))}function K(){J&&(clearInterval(J),J=null)}function _e(){if(z=T.fsRoots||[],z.length===0){if(u){Fe(u);return}r.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}r.innerHTML="";for(const e of z){const n=document.createElement("div");n.className="file-tree-item",n.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${d(e)}`,n.addEventListener("click",()=>k(e)),r.appendChild(n)}}async function Fe(e){r.innerHTML='<div class="file-tree-empty">Loading...</div>';try{const t=await(await fetch(y("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?k(t.path):r.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{r.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function k(e){E=e,r.innerHTML='<div class="file-tree-empty">Loading...</div>';const n=He(e);try{const s=await(await fetch(y("/api/fs/list?path="+encodeURIComponent(e)))).json();await n,r.innerHTML="",D(f),r.innerHTML+=$e();const i=je(e);if(i&&!z.some(c=>e===c)){const c=document.createElement("div");c.className="file-tree-item",c.innerHTML="..",c.addEventListener("click",()=>k(i)),r.appendChild(c)}if(s.dirs)for(const o of s.dirs){const c=o.split("/").pop()||o.split("\\").pop(),a=document.createElement("div");a.className="file-tree-item",a.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${d(c)}`,a.addEventListener("click",()=>k(o)),r.appendChild(a)}else r.innerHTML="";const l=s.files||[];for(const o of l){const c=o.split("/").pop()||o.split("\\").pop(),a=Te(o);let g="",
|
|
28
|
+
</div><div class="diff-content">${s}</div></div>`,m.querySelector(".diff-back")?.addEventListener("click",()=>{m.innerHTML=ve,te(),f&&m.querySelectorAll(".git-popover-item").forEach(l=>{const o=parseInt(l.dataset.idx||"0",10),c=f.files[o];!c||c.status==="D"||(l.style.cursor="pointer",l.addEventListener("click",()=>he(c.path)))}),me()})}function Pe(e,n,t){if(!n&&!t){O.textContent="No diff",U.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}const{html:s,lineCount:i}=ye(n,t);ue.textContent=e,O.textContent=i+" lines",U.innerHTML=s}function Ae(){fe.style.display="none",V?(h.style.display="",h.classList.add("terminal-pending"),R(V),V=null):u?(h.style.display="",h.classList.add("terminal-pending"),we()):C.style.display="flex"}Re.addEventListener("click",Ae);function q(){m.classList.remove("open"),G.classList.remove("open")}G.addEventListener("click",q),document.addEventListener("keydown",e=>{e.key==="Escape"&&(q(),X())});async function be(e){try{const t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){const s=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(s.ok){const i=await s.json();f=i,D(i);return}}}catch{}f=null,D(null)}let J=null;function we(){K(),u&&(be(u),J=setInterval(()=>{u&&be(u)},3e4))}function K(){J&&(clearInterval(J),J=null)}function _e(){if(z=T.fsRoots||[],z.length===0){if(u){Fe(u);return}r.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}r.innerHTML="";for(const e of z){const n=document.createElement("div");n.className="file-tree-item",n.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${d(e)}`,n.addEventListener("click",()=>k(e)),r.appendChild(n)}}async function Fe(e){r.innerHTML='<div class="file-tree-empty">Loading...</div>';try{const t=await(await fetch(y("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?k(t.path):r.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{r.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function k(e){E=e,r.innerHTML='<div class="file-tree-empty">Loading...</div>';const n=He(e);try{const s=await(await fetch(y("/api/fs/list?path="+encodeURIComponent(e)))).json();await n,r.innerHTML="",D(f),r.innerHTML+=$e();const i=je(e);if(i&&!z.some(c=>e===c)){const c=document.createElement("div");c.className="file-tree-item",c.innerHTML="..",c.addEventListener("click",()=>k(i)),r.appendChild(c)}if(s.dirs)for(const o of s.dirs){const c=o.split("/").pop()||o.split("\\").pop(),a=document.createElement("div");a.className="file-tree-item",a.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${d(c)}`,a.addEventListener("click",()=>k(o)),r.appendChild(a)}else r.innerHTML="";const l=s.files||[];for(const o of l){const c=o.split("/").pop()||o.split("\\").pop(),a=Te(o);let g="",B="";if(a)switch(a){case"M":g="git-mod",B='<span class="git-file-status M">M</span>';break;case"A":g="git-add",B='<span class="git-file-status A">A</span>';break;case"D":g="git-del",B='<span class="git-file-status D">D</span>';break;case"?":g="git-untracked",B='<span class="git-file-status ?">?</span>';break;case"R":g="git-mod",B='<span class="git-file-status R">R</span>';break}const F=document.createElement("div");F.className="file-tree-item file"+(g?" "+g:""),F.innerHTML=`<span class="file-icon">\u{1F4C4}</span> ${B}${d(c)}`,F.addEventListener("click",()=>We(o)),r.appendChild(F)}}catch{r.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function je(e){const n=e.lastIndexOf("/");return n<=0?null:e.substring(0,n)}async function We(e){j=e,h.style.display="none",p&&(K(),p.destroy(),p=null,u=null),D(null),Q(),C.style.display="none",H.style.display="flex",Ce.textContent=e,b.textContent="Loading...",I.style.display="none";try{const n=await fetch(y("/api/file?path="+encodeURIComponent(e)));if(!n.ok){const s=await n.json();b.textContent=s.error||"Failed to load",$.value="";return}const t=await n.json();$.value=t.content,W=t.content,oe=t.content,b.textContent=t.size+" bytes",I.style.display=""}catch{b.textContent="Failed to load",$.value=""}}$.addEventListener("input",()=>{W=$.value}),I.addEventListener("click",async()=>{I.textContent="Saving...",I.disabled=!0;try{const e=await fetch(y("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:j,content:W})});if(!e.ok){const n=await e.json();b.textContent=n.error||"Save failed";return}oe=W,b.textContent="Saved"}catch{b.textContent="Save failed"}finally{I.disabled=!1,I.textContent="Save"}}),Ie.addEventListener("click",async()=>{if(confirm("Delete "+j+"?"))try{const e=await fetch(y("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:j})});if(!e.ok){const n=await e.json();b.textContent=n.error||"Delete failed";return}H.style.display="none",C.style.display="flex",E&&k(E)}catch{b.textContent="Delete failed"}}),xe.addEventListener("click",()=>{H.style.display="none",C.style.display="flex",E&&k(E)}),Be.addEventListener("click",async()=>{const e=ae.value.trim();if(!e)return;const n=E+"/"+e;try{const t=await fetch(y("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:n})});if(!t.ok){const s=await t.json();b.textContent=s.error||"Create failed";return}ae.value="",E&&k(E)}catch{b.textContent="Create failed"}}),document.getElementById("mode-settings").addEventListener("click",()=>{const e=le.classList.toggle("open");Z.classList.toggle("open",e)}),Z.addEventListener("click",()=>{le.classList.remove("open"),Z.classList.remove("open")});let x="";const P=document.createElement("div");P.className="session-popover-backdrop",document.body.appendChild(P);const L=document.createElement("div");L.id="session-popover",L.className="session-popover",L.style.display="none",L.innerHTML=`<div class="sp-field">
|
|
29
29
|
<label>Rename session</label>
|
|
30
30
|
<input type="text" id="sp-name" />
|
|
31
31
|
</div>
|
|
@@ -34,5 +34,5 @@ import{initTerminal as ke}from"./terminal-core.js";const T=window.__TMUX_WEB_SHE
|
|
|
34
34
|
<button class="btn" id="sp-cancel">Cancel</button>
|
|
35
35
|
</div>
|
|
36
36
|
<hr class="sp-divider" />
|
|
37
|
-
<button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(L);function ze(e){const n=e.getBoundingClientRect();L.style.top=n.bottom+4+"px",L.style.left=Math.max(8,Math.min(n.left,window.innerWidth-240))+"px"}function Oe(e,n){
|
|
37
|
+
<button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(L);function ze(e){const n=e.getBoundingClientRect();L.style.top=n.bottom+4+"px",L.style.left=Math.max(8,Math.min(n.left,window.innerWidth-240))+"px"}function Oe(e,n){x=e;const t=document.getElementById("sp-name");t.value=e,P.classList.add("open"),L.style.display="block",ze(n),setTimeout(()=>t.focus(),50)}function A(){P.classList.remove("open"),L.style.display="none"}P.addEventListener("click",A),document.getElementById("sp-save").addEventListener("click",async()=>{const e=document.getElementById("sp-name").value.trim();if(!e||e===x){A();return}try{if(!(await fetch(y("/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldName:x,newName:e})})).ok)return;A(),M(),u===x&&R(e)}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(confirm('Delete session "'+x+'"?'))try{if(!(await fetch(y("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:x})})).ok)return;A(),u===x&&(p&&(p.destroy(),p=null),u=null,h.style.display="none",C.style.display="flex"),M()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",A);const Ue={esc:"\x1B",tab:" ","s-tab":"\x1B[Z",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",space:" ",enter:"\r",exit:"exit\r","ctrl-c":"",yes:"yes\r"};document.getElementById("mobile-keys").addEventListener("click",e=>{const n=e.target.closest("button[data-key]");if(!n||!p)return;const t=Ue[n.dataset.key];t&&(p.sendInput(t),p.focus())});const w=document.getElementById("mk-input"),Le=document.getElementById("mk-send");function Ee(){if(!w||!p)return;const e=w.value;e&&(p.sendInput(e+"\r"),w.value="",w.rows=1,p.focus())}if(w&&(w.addEventListener("input",()=>{w.rows=1;const e=w.value.split(`
|
|
38
38
|
`).length;w.rows=Math.min(e,4)}),w.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Ee())})),Le&&Le.addEventListener("click",Ee),window.visualViewport){const e=document.querySelector(".app-layout"),n=()=>{e&&(e.style.height=window.visualViewport.height+"px"),window.scrollTo(0,0),document.documentElement.scrollTop=0,document.body.scrollTop=0};window.visualViewport.addEventListener("resize",n),window.addEventListener("orientationchange",()=>setTimeout(n,100)),document.addEventListener("touchstart",()=>{(window.scrollY>0||document.documentElement.scrollTop>0)&&window.scrollTo(0,0)},{passive:!0})}const ne=document.getElementById("process-panel"),_=document.getElementById("proc-list"),Ge=document.getElementById("proc-close"),se=document.getElementById("proc-backdrop"),Ve=document.getElementById("header-ram");function qe(){_.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(y("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){_.innerHTML='<div class="proc-empty">No processes</div>';return}let n="";for(const t of e){const s=t.rss,i=s<1048576?(s/1024).toFixed(0)+"K":(s/1048576).toFixed(1)+"M";n+='<div class="proc-row" data-pid="'+t.pid+'"><span class="proc-mem">'+t.mem+'%</span><span class="proc-rss">'+i+'</span><span class="proc-cmd" title="'+d(t.command)+'">'+d(t.command)+'</span><button class="proc-kill" title="Kill PID '+t.pid+'">×</button></div>'}_.innerHTML=n;for(const t of _.querySelectorAll(".proc-row")){const s=t.querySelector(".proc-kill");s&&s.addEventListener("click",i=>{const l=i.target.closest(".proc-row");!l||!confirm("Kill PID "+l.dataset.pid+"?")||fetch(y("/api/system/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pid:parseInt(l.dataset.pid,10)})}).then(o=>o.json()).then(o=>{o.ok?l.style.opacity="0.3":alert("Failed: "+(o.error||"unknown"))}).catch(()=>alert("Network error"))})}}).catch(()=>{_.innerHTML='<div class="proc-empty">Failed to load</div>'})}function Je(){ne.classList.add("open"),se.classList.add("open"),qe()}function X(){ne.classList.remove("open"),se.classList.remove("open")}Ve.addEventListener("click",e=>{e.stopPropagation(),ne.classList.contains("open")?X():Je()}),Ge.addEventListener("click",X),se.addEventListener("click",X),window.__openSession=R,window.__refreshSidebar=M,M(),Q(),setInterval(()=>{document.visibilityState==="visible"&&M()},1e4);
|
package/dist/lib/pages/shell.js
CHANGED
|
@@ -701,6 +701,7 @@ import{cssVarsStyle as d}from"../theme.js";import{newSessionModalCSS as c,newSes
|
|
|
701
701
|
<button data-key="space">\u2423</button>
|
|
702
702
|
<button data-key="enter">\u21B5 Enter</button>
|
|
703
703
|
<button data-key="exit">Exit</button>
|
|
704
|
+
<button data-key="ctrl-c">Ctrl+C</button>
|
|
704
705
|
<button data-key="yes">Yes</button>
|
|
705
706
|
</div>
|
|
706
707
|
</div>
|