tmux-weblink 1.1.1 → 1.1.2

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.
@@ -19,11 +19,33 @@ import{icon as e}from"./icons.js";function n(){return`
19
19
  #mobile-toolbar button:hover { color: var(--panel-accent); background: color-mix(in srgb, var(--panel-accent) 8%, transparent); }
20
20
  #mobile-toolbar button:focus-visible { box-shadow: 0 0 0 2px var(--panel-accent); outline: none; }
21
21
  #mobile-toolbar button svg { width: 22px; height: 22px; fill: currentColor; }
22
- #mobile-toolbar button.listening {
23
- color: var(--panel-success);
24
- animation: tmux-mic-pulse 1.2s ease-in-out infinite;
22
+
23
+ #mobile-toolbar .tb-input {
24
+ flex: 1; display: flex; align-items: stretch; gap: 6px; min-width: 0;
25
+ }
26
+ #mobile-toolbar .tb-input textarea {
27
+ flex: 1; resize: none; box-sizing: border-box;
28
+ min-height: 38px; max-height: 96px;
29
+ background: var(--terminal-bg, rgba(0,0,0,0.28));
30
+ color: var(--page-fg);
31
+ border: 1px solid var(--panel-border);
32
+ border-radius: 8px; padding: 6px 10px;
33
+ font-family: var(--font-mono); font-size: var(--text-base); line-height: 1.4;
34
+ outline: none;
25
35
  }
26
- @keyframes tmux-mic-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
36
+ #mobile-toolbar .tb-input textarea:focus {
37
+ border-color: var(--panel-accent);
38
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--panel-accent) 12%, transparent);
39
+ }
40
+ #mobile-toolbar .tb-input textarea::placeholder { color: var(--panel-muted); opacity: 0.6; }
41
+ #mobile-toolbar .tb-input button {
42
+ flex: 0 0 auto; min-width: 44px;
43
+ border: 1px solid var(--panel-success); color: var(--panel-success);
44
+ }
45
+ #mobile-toolbar .tb-input button:hover {
46
+ background: color-mix(in srgb, var(--panel-success) 12%, transparent);
47
+ }
48
+ #mobile-toolbar #tb-kb-btn { flex: 0 0 auto; min-width: 44px; }
27
49
 
28
50
  #type-backdrop {
29
51
  position: fixed; inset: 0; background: rgba(0,0,0,0.45); z-index: 1001;
@@ -128,62 +150,13 @@ import{icon as e}from"./icons.js";function n(){return`
128
150
  border-color: var(--panel-success); color: var(--panel-success);
129
151
  }
130
152
 
131
- /* \u2500\u2500 Floating input bar (narrow-screen voice-input helper) \u2500\u2500 */
132
- #float-bar { display: none; }
133
- @media (max-width: 767px) {
134
- #float-bar {
135
- display: flex; align-items: flex-end; gap: 6px;
136
- position: fixed; bottom: 0; left: 0; right: 0;
137
- z-index: 1000;
138
- padding: 8px 10px;
139
- padding-bottom: calc(8px + env(safe-area-inset-bottom));
140
- background: var(--panel-bg);
141
- border-top: 1px solid var(--panel-border);
142
- }
143
- #float-bar textarea {
144
- flex: 1; resize: none; box-sizing: border-box;
145
- min-height: 38px; max-height: 120px;
146
- background: var(--terminal-bg, rgba(0,0,0,0.28));
147
- color: var(--page-fg);
148
- border: 1px solid var(--panel-border);
149
- border-radius: 8px; padding: 8px 10px;
150
- font-family: var(--font-mono); font-size: var(--text-base); line-height: 1.4;
151
- outline: none;
152
- }
153
- #float-bar textarea:focus {
154
- border-color: var(--panel-accent);
155
- box-shadow: 0 0 0 2px color-mix(in srgb, var(--panel-accent) 12%, transparent);
156
- }
157
- #float-bar textarea::placeholder { color: var(--panel-muted); opacity: 0.6; }
158
- #float-bar .float-bar-actions {
159
- display: flex; flex-direction: column; gap: 4px; flex-shrink: 0;
160
- }
161
- #float-bar .float-bar-actions button {
162
- display: flex; align-items: center; justify-content: center;
163
- min-width: 38px; min-height: 38px;
164
- background: none; border: 1px solid var(--panel-border);
165
- border-radius: 8px; color: var(--panel-muted); cursor: pointer;
166
- font-size: var(--text-sm); font-family: var(--font-mono);
167
- transition: color 0.15s, background 0.15s, border-color 0.15s;
168
- }
169
- #float-bar .float-bar-actions button:hover,
170
- #float-bar .float-bar-actions button:focus-visible {
171
- color: var(--panel-accent); border-color: var(--panel-accent);
172
- background: color-mix(in srgb, var(--panel-accent) 8%, transparent);
173
- }
174
- #float-bar .float-bar-actions #float-send {
175
- color: var(--panel-success); border-color: var(--panel-success);
176
- }
177
- #float-bar .float-bar-actions #float-send:hover {
178
- background: color-mix(in srgb, var(--panel-success) 12%, transparent);
179
- }
180
- }
181
153
  `}function a(){return`
182
154
  <div id="mobile-toolbar">
183
- <button id="mic-toggle" type="button" title="Voice input" aria-label="Voice input">
184
- ${e("microphone")}
185
- </button>
186
- <button id="type-toggle" type="button" title="Type to send" aria-label="Type to send">
155
+ <div class="tb-input">
156
+ <textarea id="tb-input" placeholder="Type or voice input\u2026" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false" rows="1"></textarea>
157
+ <button id="tb-send" type="button" title="Send (Enter)">&#9166;</button>
158
+ </div>
159
+ <button id="type-toggle" type="button" title="Advanced keys" aria-label="Advanced keys">
187
160
  ${e("keyboard")}
188
161
  </button>
189
162
  </div>
@@ -199,20 +172,13 @@ import{icon as e}from"./icons.js";function n(){return`
199
172
  <label><input type="radio" name="type-modifier" value="Tab" /><span class="type-modal-modifier-label">Tab</span></label>
200
173
  <label><input type="radio" name="type-modifier" value="Ctrl" /><span class="type-modal-modifier-label">Ctrl</span></label>
201
174
  </div>
202
- <textarea id="type-input" placeholder="Type a command or tap the mic\u2026" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false"></textarea>
175
+ <textarea id="type-input" placeholder="Type a command\u2026" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false"></textarea>
203
176
  <div id="type-status"></div>
204
177
  <div class="type-modal-footer">
205
178
  <button id="type-send" type="button">Send</button>
206
179
  <button id="type-send-enter" type="button">Send &#9166;</button>
207
180
  </div>
208
- </div>`}function r(){return`
209
- <div id="float-bar">
210
- <textarea id="float-input" placeholder="Type or voice input\u2026" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false" rows="1"></textarea>
211
- <div class="float-bar-actions">
212
- <button id="float-send" type="button" title="Send (Enter)">&#9166;</button>
213
- </div>
214
- </div>`}function i(t){return`(function() {
215
- const micBtn = document.getElementById('mic-toggle');
181
+ </div>`}function r(t){return`(function() {
216
182
  const typeBtn = document.getElementById('type-toggle');
217
183
  const modal = document.getElementById('type-modal');
218
184
  const backdrop = document.getElementById('type-backdrop');
@@ -241,7 +207,6 @@ import{icon as e}from"./icons.js";function n(){return`
241
207
  function closeModal() {
242
208
  modal.classList.remove('open');
243
209
  backdrop.classList.remove('open');
244
- stopRecognition();
245
210
  }
246
211
 
247
212
  function getActiveModifier() {
@@ -299,113 +264,35 @@ import{icon as e}from"./icons.js";function n(){return`
299
264
  sendBtn.addEventListener('click', () => send(false));
300
265
  sendEnterBtn.addEventListener('click', () => send(true));
301
266
 
302
- // \u2500\u2500 Speech-to-text (browser Web Speech API) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
303
- const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
304
- let recognition = null;
305
- let listening = false;
306
-
307
- if (!SR) {
308
- // Unsupported browser \u2014 hide the mic entirely.
309
- micBtn.style.display = 'none';
310
- } else {
311
- micBtn.addEventListener('click', () => {
312
- if (listening) { stopRecognition(); return; }
313
- startRecognition();
314
- });
315
- }
316
-
317
- function startRecognition() {
318
- if (!SR) return;
319
- recognition = new SR();
320
- recognition.lang = navigator.language || 'en-US';
321
- recognition.interimResults = true;
322
- recognition.continuous = false;
323
- const baseText = input.value ? input.value + ' ' : '';
324
-
325
- recognition.onstart = () => {
326
- listening = true;
327
- micBtn.classList.add('listening');
328
- openModal();
329
- setStatus('Listening\u2026');
330
- };
331
- recognition.onresult = (event) => {
332
- let transcript = '';
333
- for (let i = 0; i < event.results.length; i++) {
334
- transcript += event.results[i][0].transcript;
335
- }
336
- input.value = baseText + transcript;
337
- };
338
- recognition.onerror = (event) => {
339
- const code = event && event.error;
340
- if (code === 'not-allowed' || code === 'service-not-allowed') {
341
- setStatus('Microphone permission denied', true);
342
- } else if (code === 'no-speech') {
343
- setStatus('No speech detected', true);
344
- } else {
345
- setStatus('Voice input error', true);
346
- }
347
- };
348
- recognition.onend = () => {
349
- listening = false;
350
- micBtn.classList.remove('listening');
351
- if (!status.textContent || status.textContent === 'Listening\u2026') {
352
- setStatus(input.value ? 'Review and send' : '');
353
- }
354
- recognition = null;
355
- };
356
-
357
- try {
358
- recognition.start();
359
- } catch (e) {
360
- setStatus('Voice input unavailable', true);
361
- listening = false;
362
- micBtn.classList.remove('listening');
363
- }
364
- }
365
-
366
- function stopRecognition() {
367
- if (recognition) {
368
- try { recognition.stop(); } catch (e) { /* ignore */ }
369
- }
370
- }
371
-
372
- // \u2500\u2500 Floating input bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
373
- const floatInput = document.getElementById('float-input');
374
- const floatSend = document.getElementById('float-send');
267
+ // \u2500\u2500 Inline toolbar input \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
268
+ const tbInput = document.getElementById('tb-input');
269
+ const tbSend = document.getElementById('tb-send');
375
270
 
376
- if (floatInput && floatSend) {
377
- function sendFloat() {
378
- const text = floatInput.value;
271
+ if (tbInput && tbSend) {
272
+ function sendTb() {
273
+ const text = tbInput.value;
379
274
  if (text && window.tmuxWeb && window.tmuxWeb.sendInput) {
380
275
  window.tmuxWeb.sendInput(text + '\r');
381
276
  }
382
- floatInput.value = '';
383
- floatInput.rows = 1;
277
+ tbInput.value = '';
278
+ tbInput.rows = 1;
384
279
  if (window.tmuxWeb && window.tmuxWeb.focusTerminal) window.tmuxWeb.focusTerminal();
385
280
  }
386
281
 
387
- // Auto-resize: grow rows up to 4 as content grows
388
- floatInput.addEventListener('input', () => {
389
- floatInput.rows = 1;
390
- const lines = floatInput.value.split('
282
+ tbInput.addEventListener('input', () => {
283
+ tbInput.rows = 1;
284
+ const lines = tbInput.value.split('
391
285
  ').length;
392
- floatInput.rows = Math.min(lines, 4);
286
+ tbInput.rows = Math.min(lines, 4);
393
287
  });
394
288
 
395
- // Enter sends, Shift+Enter inserts newline
396
- floatInput.addEventListener('keydown', (e) => {
289
+ tbInput.addEventListener('keydown', (e) => {
397
290
  if (e.key === 'Enter' && !e.shiftKey) {
398
291
  e.preventDefault();
399
- sendFloat();
292
+ sendTb();
400
293
  }
401
294
  });
402
295
 
403
- floatSend.addEventListener('click', sendFloat);
404
-
405
- // Focus the float input when bar becomes visible (narrow screen)
406
- const narrowMq = window.matchMedia('(max-width: 767px)');
407
- narrowMq.addEventListener('change', (e) => {
408
- if (e.matches) setTimeout(() => floatInput.focus(), 100);
409
- });
296
+ tbSend.addEventListener('click', sendTb);
410
297
  }
411
- })();`}export{r as floatBarHTML,n as mobileToolbarCSS,a as mobileToolbarHTML,i as mobileToolbarScript};
298
+ })();`}export{n as mobileToolbarCSS,a as mobileToolbarHTML,r as mobileToolbarScript};
@@ -1,4 +1,4 @@
1
- import{cssVarsStyle as w}from"../theme.js";import{escapeHtml as i,escapeAttr as c}from"../html.js";import{notesDrawerCSS as v,notesDrawerHTML as y,notesDrawerScript as $}from"../notes-drawer.js";import{schedulerDrawerCSS as k,schedulerDrawerHTML as S,schedulerDrawerScript as L}from"../scheduler-drawer.js";import{windowsDrawerCSS as D,windowsDrawerHTML as E,windowsDrawerScript as F}from"../windows-drawer.js";import{sessionsDrawerCSS as M,sessionsDrawerHTML as I,sessionsDrawerScript as T}from"../sessions-drawer.js";import{mobileToolbarCSS as B,mobileToolbarHTML as C,mobileToolbarScript as O}from"../mobile-toolbar.js";import{floatBarHTML as W}from"../mobile-toolbar.js";import{icon as m,extIcon as z}from"../icons.js";import{commandbarButtonHTML as H,commandbarCSS as P,commandbarHTML as R,commandbarScript as A}from"../commandbar.js";import{drawerResizeCSS as j,drawerResizeHandleHTML as h,drawerResizeScript as x}from"../drawer-resize.js";import{themeSwitcherButtonHTML as J,themeSwitcherScript as _}from"../shared-layout.js";function U(){return`
1
+ import{cssVarsStyle as w}from"../theme.js";import{escapeHtml as i,escapeAttr as c}from"../html.js";import{notesDrawerCSS as v,notesDrawerHTML as y,notesDrawerScript as $}from"../notes-drawer.js";import{schedulerDrawerCSS as k,schedulerDrawerHTML as S,schedulerDrawerScript as L}from"../scheduler-drawer.js";import{windowsDrawerCSS as D,windowsDrawerHTML as E,windowsDrawerScript as F}from"../windows-drawer.js";import{sessionsDrawerCSS as M,sessionsDrawerHTML as I,sessionsDrawerScript as T}from"../sessions-drawer.js";import{mobileToolbarCSS as C,mobileToolbarHTML as B,mobileToolbarScript as O}from"../mobile-toolbar.js";import{icon as m,extIcon as W}from"../icons.js";import{commandbarButtonHTML as z,commandbarCSS as H,commandbarHTML as P,commandbarScript as R}from"../commandbar.js";import{drawerResizeCSS as A,drawerResizeHandleHTML as h,drawerResizeScript as x}from"../drawer-resize.js";import{themeSwitcherButtonHTML as j,themeSwitcherScript as J}from"../shared-layout.js";function _(){return`
2
2
  .ext-backdrop {
3
3
  position: fixed; inset: 0; background: rgba(0,0,0,0.45); z-index: 999;
4
4
  opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
@@ -18,7 +18,7 @@ import{cssVarsStyle as w}from"../theme.js";import{escapeHtml as i,escapeAttr as
18
18
  transform: translateX(100%); transition: transform 0.25s ease;
19
19
  }
20
20
  .ext-panel.open { transform: translateX(0); }
21
- ${j()}
21
+ ${A()}
22
22
  .ext-drawer .drawer-header,
23
23
  .ext-panel .drawer-header {
24
24
  display: flex; justify-content: space-between; align-items: center;
@@ -35,25 +35,25 @@ import{cssVarsStyle as w}from"../theme.js";import{escapeHtml as i,escapeAttr as
35
35
  .ext-panel .drawer-header button:hover { color: var(--panel-accent); }
36
36
  .ext-drawer iframe { flex: 1; border: none; width: 100%; height: 0; }
37
37
  .ext-panel iframe { flex: 1; border: none; width: 100%; height: 100%; }
38
- `}function X(e){const a=e.id;return`
39
- <div id="ext-${a}-backdrop" class="ext-backdrop"></div>
40
- <div id="ext-${a}-drawer" class="ext-drawer resizable-drawer">
38
+ `}function U(e){const n=e.id;return`
39
+ <div id="ext-${n}-backdrop" class="ext-backdrop"></div>
40
+ <div id="ext-${n}-drawer" class="ext-drawer resizable-drawer">
41
41
  ${h()}
42
42
  <div class="drawer-header">
43
43
  <span>${i(e.icon)} ${i(e.name)}</span>
44
- <button id="ext-${a}-close">&times;</button>
44
+ <button id="ext-${n}-close">&times;</button>
45
45
  </div>
46
- <iframe id="ext-${a}-frame" src="/ext/${a}/ui/index.html"></iframe>
47
- </div>`}function V(e){const a=e.id,t=e.panel;if(!t)return"";const r=t.title??e.name;return`
48
- <div id="ext-${a}-panel-backdrop" class="ext-backdrop"></div>
49
- <div id="ext-${a}-panel" class="ext-panel resizable-drawer">
46
+ <iframe id="ext-${n}-frame" src="/ext/${n}/ui/index.html"></iframe>
47
+ </div>`}function X(e){const n=e.id,t=e.panel;if(!t)return"";const r=t.title??e.name;return`
48
+ <div id="ext-${n}-panel-backdrop" class="ext-backdrop"></div>
49
+ <div id="ext-${n}-panel" class="ext-panel resizable-drawer">
50
50
  ${h()}
51
51
  <div class="drawer-header">
52
52
  <span>${i(e.icon)} ${i(r)}</span>
53
- <button id="ext-${a}-panel-close">&times;</button>
53
+ <button id="ext-${n}-panel-close">&times;</button>
54
54
  </div>
55
- <iframe id="ext-${a}-panel-frame" src="/ext/${a}/ui/${c(t.entry)}"></iframe>
56
- </div>`}function N(e,a){const t=e.id,r=JSON.stringify(e.config),o=e.panel?.entry??null,d=e.panel?.defaultWidth??960;return`
55
+ <iframe id="ext-${n}-panel-frame" src="/ext/${n}/ui/${c(t.entry)}"></iframe>
56
+ </div>`}function V(e,n){const t=e.id,r=JSON.stringify(e.config),o=e.panel?.entry??null,d=e.panel?.defaultWidth??960;return`
57
57
  ${x(`ext-${t}-drawer`,`tmux-web:drawer-width:ext:${t}`,360)}
58
58
  ${o?x(`ext-${t}-panel`,`tmux-web:panel-width:ext:${t}`,d):""}
59
59
  (function() {
@@ -113,7 +113,7 @@ ${o?x(`ext-${t}-panel`,`tmux-web:panel-width:ext:${t}`,d):""}
113
113
 
114
114
  function sendMessages(targetFrame) {
115
115
  if (!targetFrame || !targetFrame.contentWindow) return;
116
- targetFrame.contentWindow.postMessage({ type: 'ext:context', context: { session: ${JSON.stringify(a)}, host: location.origin } }, '*');
116
+ targetFrame.contentWindow.postMessage({ type: 'ext:context', context: { session: ${JSON.stringify(n)}, host: location.origin } }, '*');
117
117
  targetFrame.contentWindow.postMessage({ type: 'ext:config', config: cfg }, '*');
118
118
  }
119
119
 
@@ -150,7 +150,7 @@ ${o?x(`ext-${t}-panel`,`tmux-web:panel-width:ext:${t}`,d):""}
150
150
  sendMessages(panelFrame);
151
151
  }
152
152
  });
153
- }());`}function ie(e,a=[],t){const r=a.filter(n=>n.slot==="sidebar"),{commandbarEnabled:o=!1,commandbarSessions:d=[],quickCommands:g=[],agentsEnabled:b=!1,theme:s,renderer:f="xterm"}=t,l=t.terminal??{initialLines:1e3,historyChunk:500,syncIdleMs:200,syncMaxMs:3e3},u=l.initialLines+2*l.historyChunk,p=[{label:"Switch window",meta:`Windows in ${e}`,subView:"windows"},{label:"Quick Commands",meta:"Paste configured command",subView:"quickCommands"},{label:"Send Command",meta:"Send input to active window",clickTargetId:"type-toggle"},{label:"Open sessions sidebar",meta:"Recent and pinned sessions",clickTargetId:"sessions-toggle"},{label:"Open notes",meta:`Notes for ${e}`,clickTargetId:"notes-toggle"},{label:"Open scheduler",meta:`Schedule command in ${e}`,clickTargetId:"sched-toggle"}];return b&&p.push({label:"View All Agents",meta:"Running agents",href:"/agents"}),`<!DOCTYPE html>
153
+ }());`}function re(e,n=[],t){const r=n.filter(a=>a.slot==="sidebar"),{commandbarEnabled:o=!1,commandbarSessions:d=[],quickCommands:g=[],agentsEnabled:b=!1,theme:s,renderer:f="xterm"}=t,l=t.terminal??{initialLines:1e3,historyChunk:500,syncIdleMs:200,syncMaxMs:3e3},u=l.initialLines+2*l.historyChunk,p=[{label:"Switch window",meta:`Windows in ${e}`,subView:"windows"},{label:"Quick Commands",meta:"Paste configured command",subView:"quickCommands"},{label:"Send Command",meta:"Send input to active window",clickTargetId:"type-toggle"},{label:"Open sessions sidebar",meta:"Recent and pinned sessions",clickTargetId:"sessions-toggle"},{label:"Open notes",meta:`Notes for ${e}`,clickTargetId:"notes-toggle"},{label:"Open scheduler",meta:`Schedule command in ${e}`,clickTargetId:"sched-toggle"}];return b&&p.push({label:"View All Agents",meta:"Running agents",href:"/agents"}),`<!DOCTYPE html>
154
154
  <html lang="en">
155
155
  <head>
156
156
  <meta charset="UTF-8" />
@@ -266,13 +266,13 @@ ${o?x(`ext-${t}-panel`,`tmux-web:panel-width:ext:${t}`,d):""}
266
266
  @media (max-width: 380px) {
267
267
  header .status { display: none; }
268
268
  }
269
- ${o?P():""}
269
+ ${o?H():""}
270
270
  ${v()}
271
271
  ${k()}
272
272
  ${D()}
273
273
  ${M()}
274
- ${B()}
275
- ${U()}
274
+ ${C()}
275
+ ${_()}
276
276
  @media (prefers-reduced-motion: reduce) {
277
277
  *, *::before, *::after {
278
278
  animation-duration: 0.01ms !important;
@@ -287,33 +287,32 @@ ${o?x(`ext-${t}-panel`,`tmux-web:panel-width:ext:${t}`,d):""}
287
287
  <header>
288
288
  <div class="brand"><a href="/" aria-label="Go to home">tmux<span>-weblink</span></a></div>
289
289
  <span class="session">${i(e)}</span>
290
- ${o?H("Sessions"):""}
290
+ ${o?z("Sessions"):""}
291
291
  <button class="notes-btn" id="notes-toggle" title="Session notes" aria-label="Session notes">
292
292
  ${m("notes")}
293
293
  </button>
294
294
  <button class="sched-btn" id="sched-toggle" title="Schedule command" aria-label="Schedule command">
295
295
  ${m("schedule")}
296
296
  </button>
297
- ${r.map(n=>`<button class="ext-btn" id="ext-${n.id}-toggle" title="${c(n.name)}" aria-label="${c(n.name)}">${z(n.id,n.icon)}</button>`).join(`
297
+ ${r.map(a=>`<button class="ext-btn" id="ext-${a.id}-toggle" title="${c(a.name)}" aria-label="${c(a.name)}">${W(a.id,a.icon)}</button>`).join(`
298
298
  `)}
299
- ${J(s.template)}
299
+ ${j(s.template)}
300
300
  <div class="status">
301
301
  <div class="dot" id="status-dot"></div>
302
302
  <span id="status-text">connecting</span>
303
303
  </div>
304
304
  </header>
305
- <script>${_()}</script>
305
+ <script>${J()}</script>
306
306
  <div id="terminal-container" class="terminal-pending"></div>
307
- ${C()}
308
- ${W()}
309
- ${o?R():""}
307
+ ${B()}
308
+ ${o?P():""}
310
309
  ${y(`Notes - ${e}`)}
311
310
  ${S(`Scheduler - ${e}`)}
312
311
  ${E(`Windows - ${e}`)}
313
312
  ${I()}
314
- ${r.map(n=>X(n)).join(`
313
+ ${r.map(a=>U(a)).join(`
315
314
  `)}
316
- ${r.map(n=>V(n)).join(`
315
+ ${r.map(a=>X(a)).join(`
317
316
  `)}
318
317
 
319
318
  <script type="module">
@@ -349,7 +348,7 @@ ${T(e)}
349
348
  ${O(e)}
350
349
 
351
350
  // ========== COMMANDBAR ==========
352
- ${o?A(d,p,{sessionName:e},g):""}
351
+ ${o?R(d,p,{sessionName:e},g):""}
353
352
 
354
353
  // ========== NOTES ==========
355
354
  // (notes and scheduler scripts already included above; extensions below)
@@ -358,8 +357,8 @@ ${o?A(d,p,{sessionName:e},g):""}
358
357
  ${r.length>0?`<script>
359
358
  // Extension bootstrap: plain script (not module) so it runs before the module
360
359
  // awaits terminal-client import, avoiding a race where iframes load during that await.
361
- ${r.map(n=>N(n,e)).join(`
360
+ ${r.map(a=>V(a,e)).join(`
362
361
  `)}
363
362
  </script>`:""}
364
363
  </body>
365
- </html>`}export{ie as renderTerminal};
364
+ </html>`}export{re as renderTerminal};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tmux-weblink",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Access your tmux sessions from the browser. A continuation of tmux-web and persalink.",
5
5
  "type": "module",
6
6
  "bin": {