tmux-weblink 2.0.13 → 2.0.15
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.
- package/README.md +3 -5
- package/dist/agent.js +1 -1
- package/dist/frontend.js +1 -1
- package/dist/index.js +3 -3
- package/dist/lib/build-app.js +6 -6
- package/dist/lib/cli.js +7 -11
- package/dist/lib/db.js +1 -1
- package/dist/lib/pages/federation.js +1 -1
- package/dist/lib/pages/files-index.js +20 -22
- package/dist/lib/pages/history-index.js +22 -24
- package/dist/lib/pages/notes-index.js +17 -19
- package/dist/lib/pages/notes-page.js +10 -13
- package/dist/lib/pages/quick-commands.js +25 -27
- package/dist/lib/pages/settings.js +17 -58
- package/dist/lib/pages/shell.js +17 -29
- package/dist/lib/setup-features.js +1 -1
- package/dist/lib/shared-layout.js +39 -41
- package/dist/lib/state-paths.js +1 -1
- package/package.json +1 -1
- package/dist/lib/commandbar.js +0 -555
- package/dist/lib/ext-loader.js +0 -1
- package/dist/lib/pages/schedule-index.js +0 -392
- package/dist/lib/plugins.js +0 -3
- package/dist/lib/schedule-delay.js +0 -9
- package/dist/lib/scheduler-drawer.js +0 -379
- package/dist/lib/scheduler.js +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{cssVarsStyle as b}from"../theme.js";import{
|
|
2
|
-
<div class="label ${
|
|
3
|
-
<div class="preview">${
|
|
4
|
-
<div class="meta"><span>${
|
|
1
|
+
import{cssVarsStyle as b}from"../theme.js";import{notesDrawerCSS as v,notesDrawerHTML as g,notesDrawerScript as x}from"../notes-drawer.js";import{sharedLayoutCSS as h,sharedHeader as f,sharedSidebar as u,newSessionModalHTML as w,newSessionModalScript as y}from"../shared-layout.js";function r(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function S(t){const a=new Date(t);return a.toLocaleDateString()+" "+a.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}function D(t,a){const n=[...t].sort((e,o)=>(o.updatedAt??0)-(e.updatedAt??0)),s=n.map(e=>{const o=e.scope==="__global__",c=o?"Global":e.scope.replace(/^session:/,""),p=o?"/notes/__global__":"/notes/"+encodeURIComponent(e.scope.replace(/^session:/,"")),d=r((e.content||"").slice(0,200).trim()||"No content"),m=r(S(e.updatedAt));return`<a class="note-card" href="${p}">
|
|
2
|
+
<div class="label ${o?"global":""}">${r(c)}</div>
|
|
3
|
+
<div class="preview">${d}</div>
|
|
4
|
+
<div class="meta"><span>${m}</span></div>
|
|
5
5
|
</a>`}).join(`
|
|
6
|
-
`),
|
|
6
|
+
`),l=n.length?s:'<p class="empty">No notes yet.</p>',i=`
|
|
7
7
|
.note-card {
|
|
8
8
|
display: block; padding: 16px 18px; border: 1px solid var(--panel-border); border-radius: 12px;
|
|
9
9
|
margin-bottom: 10px; text-decoration: none; color: var(--page-fg);
|
|
@@ -26,8 +26,8 @@ import{cssVarsStyle as b}from"../theme.js";import{commandbarCSS as x,commandbarH
|
|
|
26
26
|
display: flex; justify-content: space-between;
|
|
27
27
|
}
|
|
28
28
|
.empty { font-size: var(--text-sm); color: var(--panel-muted); line-height: 1.6; margin-top: 20px; }
|
|
29
|
-
|
|
30
|
-
${
|
|
29
|
+
|
|
30
|
+
${v()}`;return`<!DOCTYPE html>
|
|
31
31
|
<html lang="en">
|
|
32
32
|
<head>
|
|
33
33
|
<meta charset="UTF-8" />
|
|
@@ -35,31 +35,29 @@ import{cssVarsStyle as b}from"../theme.js";import{commandbarCSS as x,commandbarH
|
|
|
35
35
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
36
36
|
<title>Notes - tmux-web</title>
|
|
37
37
|
<style>
|
|
38
|
-
${b(
|
|
39
|
-
${
|
|
38
|
+
${b(a.shell)}
|
|
39
|
+
${h(i)}
|
|
40
40
|
</style>
|
|
41
41
|
</head>
|
|
42
42
|
<body>
|
|
43
43
|
|
|
44
|
-
${
|
|
44
|
+
${f({title:"All Notes",themeTemplate:a.template})}
|
|
45
45
|
|
|
46
46
|
<div class="page-wrap">
|
|
47
47
|
<div class="page-layout">
|
|
48
|
-
${
|
|
48
|
+
${u({activePage:"notes",refreshHref:"/notes"})}
|
|
49
49
|
<main class="main-panel">
|
|
50
|
-
<div id="notes-list">${
|
|
50
|
+
<div id="notes-list">${l}</div>
|
|
51
51
|
</main>
|
|
52
52
|
</div>
|
|
53
53
|
</div>
|
|
54
54
|
|
|
55
|
-
${
|
|
56
|
-
${
|
|
57
|
-
${w("Notes - Global")}
|
|
55
|
+
${w()}
|
|
56
|
+
${g("Notes - Global")}
|
|
58
57
|
|
|
59
58
|
<script type="module">
|
|
60
|
-
${
|
|
61
|
-
${
|
|
62
|
-
${D()}
|
|
59
|
+
${x("__global__")}
|
|
60
|
+
${y()}
|
|
63
61
|
</script>
|
|
64
62
|
</body>
|
|
65
|
-
</html>`}export{
|
|
63
|
+
</html>`}export{D as renderNotesIndex};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import{cssVarsStyle as
|
|
1
|
+
import{cssVarsStyle as c}from"../theme.js";import{escapeHtml as p}from"../html.js";import{notesDbScript as b}from"../notes-db.js";import{notesUtilsScript as m}from"../notes-utils.js";function f(t,n){const e=t==="__global__",a=e?"Global":t,r=e?"__global__":"session:"+t,i="/notes",s=e?"notes-global":"notes-session-"+t.replace(/[:\/\\]/g,"-"),d=JSON.stringify(r),l=JSON.stringify(`${s}.md`),o=p(a);return`<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
7
|
-
<title>Notes - ${
|
|
7
|
+
<title>Notes - ${o} - tmux-web</title>
|
|
8
8
|
<style>
|
|
9
|
-
${
|
|
9
|
+
${c(n.shell)}
|
|
10
10
|
html, body { background: var(--page-bg); color: var(--page-fg); min-height: 100%; font-family: var(--font-mono); }
|
|
11
11
|
.container { max-width: 720px; margin: 40px auto; padding: 0 20px; }
|
|
12
12
|
.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; }
|
|
@@ -53,16 +53,15 @@ import{cssVarsStyle as b}from"../theme.js";import{escapeHtml as m}from"../html.j
|
|
|
53
53
|
.container { margin: 20px auto; padding: 0 16px; }
|
|
54
54
|
#notes-editor { min-height: 300px; padding: 12px; }
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
</style>
|
|
58
58
|
</head>
|
|
59
59
|
<body>
|
|
60
60
|
<div class="container">
|
|
61
61
|
<div class="page-header">
|
|
62
62
|
<div class="breadcrumb">
|
|
63
|
-
<a href="${
|
|
63
|
+
<a href="${i}">Notes</a> <span>/</span> <span>${o}</span>
|
|
64
64
|
</div>
|
|
65
|
-
${e?y("Search"):""}
|
|
66
65
|
</div>
|
|
67
66
|
<div class="toolbar">
|
|
68
67
|
<button id="notes-copy">Copy</button>
|
|
@@ -73,9 +72,9 @@ import{cssVarsStyle as b}from"../theme.js";import{escapeHtml as m}from"../html.j
|
|
|
73
72
|
</div>
|
|
74
73
|
|
|
75
74
|
<script type="module">
|
|
76
|
-
const NOTES_SCOPE = ${
|
|
77
|
-
${
|
|
78
|
-
${
|
|
75
|
+
const NOTES_SCOPE = ${d};
|
|
76
|
+
${b()}
|
|
77
|
+
${m()}
|
|
79
78
|
|
|
80
79
|
const notesEditor = document.getElementById('notes-editor');
|
|
81
80
|
const copyBtn = document.getElementById('notes-copy');
|
|
@@ -143,16 +142,14 @@ exportBtn.addEventListener('click', () => {
|
|
|
143
142
|
const blob = new Blob([notePlain], { type: 'text/markdown' });
|
|
144
143
|
const a = document.createElement('a');
|
|
145
144
|
a.href = URL.createObjectURL(blob);
|
|
146
|
-
a.download = ${
|
|
145
|
+
a.download = ${l};
|
|
147
146
|
a.click();
|
|
148
147
|
URL.revokeObjectURL(a.href);
|
|
149
148
|
});
|
|
150
149
|
|
|
151
150
|
renderNote();
|
|
152
151
|
</script>
|
|
153
|
-
${e?f():""}
|
|
154
152
|
<script type="module">
|
|
155
|
-
${e?v(r,[]):""}
|
|
156
153
|
</script>
|
|
157
154
|
</body>
|
|
158
|
-
</html>`}export{
|
|
155
|
+
</html>`}export{f as renderNotesPage};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cssVarsStyle as
|
|
1
|
+
import{cssVarsStyle as n}from"../theme.js";import{sharedLayoutCSS as c,sharedHeader as s,sharedSidebar as d,newSessionModalHTML as l,newSessionModalScript as p}from"../shared-layout.js";import{icon as a}from"../icons.js";function t(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function u(e){return`<article class="quick-item" data-id="${t(e.id)}">
|
|
2
2
|
<div class="quick-card-head">
|
|
3
3
|
<div>
|
|
4
4
|
<div class="quick-title">${t(e.title)}</div>
|
|
@@ -6,16 +6,25 @@ import{cssVarsStyle as d}from"../theme.js";import{commandbarCSS as l,commandbarH
|
|
|
6
6
|
</div>
|
|
7
7
|
<div class="quick-icon-actions">
|
|
8
8
|
<button class="quick-icon-btn quick-edit" type="button" title="Edit command" aria-label="Edit ${t(e.title)}">
|
|
9
|
-
${
|
|
9
|
+
${a("edit")}
|
|
10
10
|
</button>
|
|
11
11
|
<button class="quick-icon-btn quick-delete" type="button" title="Delete command" aria-label="Delete ${t(e.title)}">
|
|
12
|
-
${
|
|
12
|
+
${a("delete")}
|
|
13
13
|
</button>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
<pre class="quick-command-preview"><code>${t(e.command)}</code></pre>
|
|
17
|
-
</article>`}function
|
|
18
|
-
`):'<p class="empty">No quick commands yet. Add one below
|
|
17
|
+
</article>`}function x(e,r){const o=JSON.stringify(e).replace(/</g,"\\u003c"),i=e.length?e.map(u).join(`
|
|
18
|
+
`):'<p class="empty">No quick commands yet. Add one below.</p>';return`<!DOCTYPE html>
|
|
19
|
+
<html lang="en">
|
|
20
|
+
<head>
|
|
21
|
+
<meta charset="UTF-8" />
|
|
22
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
23
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
24
|
+
<title>Quick Commands - tmux-web</title>
|
|
25
|
+
<style>
|
|
26
|
+
${n(r.shell)}
|
|
27
|
+
${c(`
|
|
19
28
|
.intro {
|
|
20
29
|
margin: 0 0 18px; color: var(--panel-muted); font-size: var(--text-sm); line-height: 1.6;
|
|
21
30
|
}
|
|
@@ -155,27 +164,18 @@ import{cssVarsStyle as d}from"../theme.js";import{commandbarCSS as l,commandbarH
|
|
|
155
164
|
.quick-card-head { flex-wrap: wrap; }
|
|
156
165
|
.quick-icon-actions { width: 100%; justify-content: flex-end; }
|
|
157
166
|
}
|
|
158
|
-
|
|
159
|
-
<html lang="en">
|
|
160
|
-
<head>
|
|
161
|
-
<meta charset="UTF-8" />
|
|
162
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
163
|
-
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
164
|
-
<title>Quick Commands - tmux-web</title>
|
|
165
|
-
<style>
|
|
166
|
-
${d(a.shell)}
|
|
167
|
-
${u(s)}
|
|
167
|
+
`)}
|
|
168
168
|
</style>
|
|
169
169
|
</head>
|
|
170
170
|
<body>
|
|
171
171
|
|
|
172
|
-
${
|
|
172
|
+
${s({title:"Quick Commands",themeTemplate:r.template})}
|
|
173
173
|
|
|
174
174
|
<div class="page-wrap">
|
|
175
175
|
<div class="page-layout">
|
|
176
|
-
${
|
|
176
|
+
${d({activePage:"quickCommands",refreshHref:"/quick-commands"})}
|
|
177
177
|
<main class="main-panel">
|
|
178
|
-
<p class="intro">Configure reusable snippets that can be pasted into the active tmux pane
|
|
178
|
+
<p class="intro">Configure reusable snippets that can be pasted into the active tmux pane.</p>
|
|
179
179
|
<p class="quick-error" id="quick-error"></p>
|
|
180
180
|
|
|
181
181
|
<h2 class="quick-section-title">Add Command</h2>
|
|
@@ -190,7 +190,7 @@ ${b({commandbarEnabled:r,title:"Quick Commands",themeTemplate:a.template})}
|
|
|
190
190
|
</label>
|
|
191
191
|
<label>
|
|
192
192
|
<span>Description</span>
|
|
193
|
-
<input name="description" type="text" placeholder="Optional
|
|
193
|
+
<input name="description" type="text" placeholder="Optional description" autocomplete="off" />
|
|
194
194
|
</label>
|
|
195
195
|
<div class="quick-actions">
|
|
196
196
|
<button class="quick-save" type="submit">Add Command</button>
|
|
@@ -198,18 +198,18 @@ ${b({commandbarEnabled:r,title:"Quick Commands",themeTemplate:a.template})}
|
|
|
198
198
|
</form>
|
|
199
199
|
|
|
200
200
|
<h2 class="quick-section-title">Configured</h2>
|
|
201
|
-
<div id="quick-list">${
|
|
201
|
+
<div id="quick-list">${i}</div>
|
|
202
202
|
</main>
|
|
203
203
|
</div>
|
|
204
204
|
</div>
|
|
205
205
|
|
|
206
|
-
${
|
|
206
|
+
${l()}
|
|
207
207
|
<div class="quick-drawer-backdrop" id="quick-edit-backdrop"></div>
|
|
208
208
|
<aside class="quick-drawer" id="quick-edit-drawer" aria-hidden="true" aria-label="Edit quick command">
|
|
209
209
|
<div class="quick-drawer-header">
|
|
210
210
|
<div>
|
|
211
211
|
<h2>Edit Command</h2>
|
|
212
|
-
|
|
212
|
+
|
|
213
213
|
</div>
|
|
214
214
|
<button class="quick-drawer-close" id="quick-edit-close" type="button" aria-label="Close edit drawer">×</button>
|
|
215
215
|
</div>
|
|
@@ -233,10 +233,9 @@ ${v()}
|
|
|
233
233
|
</div>
|
|
234
234
|
</form>
|
|
235
235
|
</aside>
|
|
236
|
-
${r?p():""}
|
|
237
236
|
|
|
238
237
|
<script type="module">
|
|
239
|
-
const commands = ${
|
|
238
|
+
const commands = ${o};
|
|
240
239
|
const errorEl = document.getElementById('quick-error');
|
|
241
240
|
const editBackdrop = document.getElementById('quick-edit-backdrop');
|
|
242
241
|
const editDrawer = document.getElementById('quick-edit-drawer');
|
|
@@ -354,8 +353,7 @@ document.addEventListener('keydown', (event) => {
|
|
|
354
353
|
if (event.key === 'Escape' && editDrawer.classList.contains('open')) closeEditDrawer();
|
|
355
354
|
});
|
|
356
355
|
|
|
357
|
-
${
|
|
358
|
-
${x()}
|
|
356
|
+
${p()}
|
|
359
357
|
</script>
|
|
360
358
|
</body>
|
|
361
|
-
</html>`}export{
|
|
359
|
+
</html>`}export{x as renderQuickCommandsPage};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import{cssVarsStyle as
|
|
1
|
+
import{cssVarsStyle as m}from"../theme.js";import{getThemeTemplates as g,THEME_TEMPLATE_IDS as v}from"../themes/index.js";function s(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function p(a,e){return`<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
7
|
-
<title>${
|
|
7
|
+
<title>${s(a)} - tmux-web</title>
|
|
8
8
|
<style>
|
|
9
|
-
${
|
|
9
|
+
${m(e.shell)}
|
|
10
10
|
html, body { background: var(--page-bg); color: var(--page-fg); min-height: 100%; font-family: var(--font-sans); }
|
|
11
11
|
.container { max-width: 680px; margin: 80px auto; padding: 0 24px; }
|
|
12
12
|
.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 28px; }
|
|
@@ -47,16 +47,6 @@ import{cssVarsStyle as h}from"../theme.js";import{getThemeTemplates as b,THEME_T
|
|
|
47
47
|
.btn:hover { border-color: var(--panel-accent); color: var(--panel-accent); }
|
|
48
48
|
.btn.primary { border-color: var(--panel-success); color: var(--panel-success); }
|
|
49
49
|
.btn.danger:hover { border-color: #e06c75; color: #e06c75; }
|
|
50
|
-
.plugin-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 8px 0; font-size: var(--text-sm); border-top: 1px solid var(--panel-border); }
|
|
51
|
-
.plugin-row:first-of-type { border-top: none; }
|
|
52
|
-
.plugin-row .pkg { word-break: break-all; }
|
|
53
|
-
.plugin-add { display: flex; gap: 10px; margin-top: 14px; }
|
|
54
|
-
.plugin-add input[type=text] {
|
|
55
|
-
flex: 1; font-size: var(--text-sm); font-family: inherit; color: var(--page-fg);
|
|
56
|
-
background: var(--page-bg); border: 1px solid var(--panel-border);
|
|
57
|
-
border-radius: 12px; padding: 9px 12px; outline: none; transition: border-color 0.15s, box-shadow 0.15s;
|
|
58
|
-
}
|
|
59
|
-
.plugin-add input[type=text]:focus { border-color: var(--panel-accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--panel-accent) 8%, transparent); }
|
|
60
50
|
.num-input {
|
|
61
51
|
width: 100px; font-size: var(--text-sm); font-family: inherit; color: var(--page-fg);
|
|
62
52
|
background: var(--page-bg); border: 1px solid var(--panel-border);
|
|
@@ -87,15 +77,7 @@ import{cssVarsStyle as h}from"../theme.js";import{getThemeTemplates as b,THEME_T
|
|
|
87
77
|
.num-input { width: 100%; }
|
|
88
78
|
}
|
|
89
79
|
</style>
|
|
90
|
-
</head>`}function
|
|
91
|
-
<span class="pkg">${n(p)}</span>
|
|
92
|
-
<form method="POST" action="/settings/plugins" onsubmit="return confirm('Remove ${n(p)}?');">
|
|
93
|
-
<input type="hidden" name="action" value="remove" />
|
|
94
|
-
<input type="hidden" name="pkg" value="${n(p)}" />
|
|
95
|
-
<button type="submit" class="btn danger">Remove</button>
|
|
96
|
-
</form>
|
|
97
|
-
</div>`).join(`
|
|
98
|
-
`):'<p class="desc" style="margin:0">No plugins enabled.</p>';return`${g("Settings",l)}
|
|
80
|
+
</head>`}function h(a,e){let t="";return a&&(t+='<div class="saved-flash">\u2713 Saved. Restart tmux-web to apply.</div>'),e&&(t+=`<div class="error-flash">${s(e)}</div>`),t}function y(a){const{settings:e,renderer:t,rendererOverridden:i,theme:l,saved:r=!1,error:c}=a,n=e.terminalRenderer??"xterm",o=e.defaultView??"default";return`${p("Settings",l)}
|
|
99
81
|
<body>
|
|
100
82
|
<div class="container">
|
|
101
83
|
<div class="page-header">
|
|
@@ -108,56 +90,33 @@ import{cssVarsStyle as h}from"../theme.js";import{getThemeTemplates as b,THEME_T
|
|
|
108
90
|
<strong>restart the tmux-web process</strong> after making changes for them to take effect.
|
|
109
91
|
</div>
|
|
110
92
|
|
|
111
|
-
${
|
|
93
|
+
${h(r,c)}
|
|
112
94
|
|
|
113
95
|
<form method="POST" action="/settings">
|
|
114
|
-
<div class="section">
|
|
115
|
-
<h2>Command bar</h2>
|
|
116
|
-
<p class="desc">\u2318K session search + quick actions.</p>
|
|
117
|
-
<label class="row"><input type="checkbox" name="commandbar" ${c?"checked":""} /> Enable command bar</label>
|
|
118
|
-
</div>
|
|
119
|
-
|
|
120
96
|
<div class="section">
|
|
121
97
|
<h2>Terminal library</h2>
|
|
122
98
|
<p class="desc">Rendering engine for the terminal view.</p>
|
|
123
99
|
<div class="radios">
|
|
124
|
-
<label class="row"><input type="radio" name="terminalRenderer" value="xterm" ${
|
|
125
|
-
<label class="row"><input type="radio" name="terminalRenderer" value="ghostty" ${
|
|
100
|
+
<label class="row"><input type="radio" name="terminalRenderer" value="xterm" ${n==="xterm"?"checked":""} /> xterm.js (default)</label>
|
|
101
|
+
<label class="row"><input type="radio" name="terminalRenderer" value="ghostty" ${n==="ghostty"?"checked":""} /> ghostty-web</label>
|
|
126
102
|
</div>
|
|
127
|
-
${i?`<p class="override-note">\u26A0 A CLI flag or <code>TMUX_WEB_TERMINAL_RENDERER</code> env var is currently forcing <strong>${
|
|
103
|
+
${i?`<p class="override-note">\u26A0 A CLI flag or <code>TMUX_WEB_TERMINAL_RENDERER</code> env var is currently forcing <strong>${t}</strong>, overriding this setting for the running process.</p>`:""}
|
|
128
104
|
</div>
|
|
129
105
|
|
|
130
106
|
<div class="section">
|
|
131
107
|
<h2>Default home tab</h2>
|
|
132
108
|
<p class="desc">Which tab the home page opens on.</p>
|
|
133
109
|
<div class="radios">
|
|
134
|
-
<label class="row"><input type="radio" name="defaultView" value="default" ${
|
|
135
|
-
<label class="row"><input type="radio" name="defaultView" value="recent" ${
|
|
110
|
+
<label class="row"><input type="radio" name="defaultView" value="default" ${o==="default"?"checked":""} /> Default</label>
|
|
111
|
+
<label class="row"><input type="radio" name="defaultView" value="recent" ${o==="recent"?"checked":""} /> Last Updated</label>
|
|
136
112
|
</div>
|
|
137
113
|
</div>
|
|
138
114
|
|
|
139
|
-
<div class="section">
|
|
140
|
-
<h2>Schedule history</h2>
|
|
141
|
-
<p class="desc">Days to keep the <code>/schedule</code> "Recently Triggered" history (fired & missed tasks). 1\u2013365, default 7.</p>
|
|
142
|
-
<label class="row"><input type="number" class="num-input" name="scheduleHistoryDays" min="1" max="365" value="${v}" /> days</label>
|
|
143
|
-
</div>
|
|
144
|
-
|
|
145
115
|
<div class="form-actions">
|
|
146
116
|
<button type="submit" class="btn primary">Save settings</button>
|
|
147
117
|
</div>
|
|
148
118
|
</form>
|
|
149
119
|
|
|
150
|
-
<div class="section" style="margin-top:16px">
|
|
151
|
-
<h2>Plugins</h2>
|
|
152
|
-
<p class="desc">Installed via npm into the tmux-web data dir. Add/remove runs npm and may take a few seconds.</p>
|
|
153
|
-
${u}
|
|
154
|
-
<form method="POST" action="/settings/plugins" class="plugin-add">
|
|
155
|
-
<input type="hidden" name="action" value="add" />
|
|
156
|
-
<input type="text" id="pkg-input" name="pkg" placeholder="npm package name" autocomplete="off" />
|
|
157
|
-
<button type="submit" class="btn">Add</button>
|
|
158
|
-
</form>
|
|
159
|
-
</div>
|
|
160
|
-
|
|
161
120
|
<div class="section">
|
|
162
121
|
<h2>Theme</h2>
|
|
163
122
|
<p class="desc">Shell chrome + terminal colors.</p>
|
|
@@ -171,14 +130,14 @@ import{cssVarsStyle as h}from"../theme.js";import{getThemeTemplates as b,THEME_T
|
|
|
171
130
|
</div>
|
|
172
131
|
</div>
|
|
173
132
|
</body>
|
|
174
|
-
</html>`}const
|
|
133
|
+
</html>`}const x={vscode:"VS Code",ghostty:"Ghostty","warm-clay":"Warm Clay","dark-cove":"Dark Cove"},b=["background","foreground","red","green","yellow","blue","magenta","cyan"];function w(a){const{theme:e,saved:t=!1}=a,i=g(),l=v.map(r=>{const c=i[r],n=e.template===r,o=b.map(d=>`<span class="swatch" style="background:${s(c.terminal[d])}" title="${d}"></span>`).join("");return`<label class="theme-card${n?" active":""}">
|
|
175
134
|
<div class="tname">
|
|
176
|
-
<input type="radio" name="template" value="${
|
|
177
|
-
${
|
|
135
|
+
<input type="radio" name="template" value="${r}" ${n?"checked":""} style="accent-color:var(--panel-success)" />
|
|
136
|
+
${s(x[r]??r)}
|
|
178
137
|
</div>
|
|
179
|
-
<div class="swatches">${
|
|
138
|
+
<div class="swatches">${o}</div>
|
|
180
139
|
</label>`}).join(`
|
|
181
|
-
`);return`${
|
|
140
|
+
`);return`${p("Theme",e)}
|
|
182
141
|
<body>
|
|
183
142
|
<div class="container">
|
|
184
143
|
<div class="page-header">
|
|
@@ -190,7 +149,7 @@ import{cssVarsStyle as h}from"../theme.js";import{getThemeTemplates as b,THEME_T
|
|
|
190
149
|
<strong>Note:</strong> the active theme is applied immediately to new page renders.
|
|
191
150
|
</div>
|
|
192
151
|
|
|
193
|
-
${
|
|
152
|
+
${t?'<div class="saved-flash">\u2713 Theme saved.</div>':""}
|
|
194
153
|
|
|
195
154
|
<form method="POST" action="/settings/theme">
|
|
196
155
|
<div class="theme-grid">
|
|
@@ -202,4 +161,4 @@ import{cssVarsStyle as h}from"../theme.js";import{getThemeTemplates as b,THEME_T
|
|
|
202
161
|
</form>
|
|
203
162
|
</div>
|
|
204
163
|
</body>
|
|
205
|
-
</html>`}export{
|
|
164
|
+
</html>`}export{y as renderSettings,w as renderThemeSettings};
|
package/dist/lib/pages/shell.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cssVarsStyle as
|
|
1
|
+
import{cssVarsStyle as c}from"../theme.js";import{newSessionModalCSS as f,newSessionModalHTML as g,newSessionModalScript as x,reducedMotion as b}from"../shared-layout.js";import{icon as i}from"../icons.js";function y(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function o(t="var(--panel-accent)"){return`box-shadow: 0 0 0 2px ${t}; outline: none;`}function k(t){const{theme:e,fsRoots:r,terminalCfg:a,renderer:n,scrollback:s,wsBase:p}=t,l=`
|
|
2
2
|
*, *::before, *::after { box-sizing: border-box; }
|
|
3
3
|
html, body {
|
|
4
4
|
background: var(--page-bg); color: var(--page-fg);
|
|
@@ -87,7 +87,7 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
87
87
|
}
|
|
88
88
|
.sidebar-footer .mode-btn:hover { color: var(--panel-accent); background: color-mix(in srgb, var(--panel-accent) 8%, transparent); }
|
|
89
89
|
.sidebar-footer .mode-btn.active { color: var(--panel-accent); background: color-mix(in srgb, var(--panel-accent) 10%, transparent); }
|
|
90
|
-
.sidebar-footer .mode-btn:focus-visible { ${
|
|
90
|
+
.sidebar-footer .mode-btn:focus-visible { ${o()} }
|
|
91
91
|
|
|
92
92
|
/* \u2500\u2500 Sidebar session mode \u2500\u2500 */
|
|
93
93
|
.session-item {
|
|
@@ -109,7 +109,7 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
109
109
|
}
|
|
110
110
|
.session-item:hover .session-edit-btn { display: flex; align-items: center; }
|
|
111
111
|
.session-edit-btn:hover { color: var(--panel-accent); background: color-mix(in srgb, var(--panel-accent) 8%, transparent); }
|
|
112
|
-
.session-edit-btn:focus-visible { ${
|
|
112
|
+
.session-edit-btn:focus-visible { ${o()} }
|
|
113
113
|
|
|
114
114
|
.sidebar-section-label {
|
|
115
115
|
font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.05em;
|
|
@@ -135,7 +135,7 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
135
135
|
color: var(--panel-accent); border-color: var(--panel-accent);
|
|
136
136
|
background: color-mix(in srgb, var(--panel-accent) 6%, transparent);
|
|
137
137
|
}
|
|
138
|
-
.new-session-sidebar-btn:focus-visible { ${
|
|
138
|
+
.new-session-sidebar-btn:focus-visible { ${o()} }
|
|
139
139
|
.new-session-sidebar-btn svg { width: 16px; height: 16px; fill: currentColor; }
|
|
140
140
|
|
|
141
141
|
/* \u2500\u2500 Sidebar files mode \u2500\u2500 */
|
|
@@ -409,7 +409,7 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
409
409
|
color: var(--page-fg); transition: opacity 0.15s; text-decoration: none;
|
|
410
410
|
}
|
|
411
411
|
.btn:hover { opacity: 0.85; }
|
|
412
|
-
.btn:focus-visible { ${
|
|
412
|
+
.btn:focus-visible { ${o()} }
|
|
413
413
|
.btn.primary { background: var(--panel-accent); border-color: var(--panel-accent); color: var(--panel-accent-on); font-weight: 500; }
|
|
414
414
|
.btn.primary:hover { opacity: 0.9; }
|
|
415
415
|
.btn.danger { color: #b91c1c; border-color: color-mix(in srgb, #b91c1c 30%, transparent); }
|
|
@@ -580,10 +580,8 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
580
580
|
.file-roots-list li:hover { border-color: var(--panel-accent); }
|
|
581
581
|
.file-roots-list li svg { width: 20px; height: 20px; flex-shrink: 0; fill: var(--panel-accent); }
|
|
582
582
|
|
|
583
|
-
|
|
584
|
-
${
|
|
585
|
-
${y()}
|
|
586
|
-
${v()}
|
|
583
|
+
${b()}
|
|
584
|
+
${f()}
|
|
587
585
|
@media (max-width: 640px) {
|
|
588
586
|
.app-layout { flex-direction: column; }
|
|
589
587
|
.sidebar { flex: 0 0 auto; border-right: none; border-bottom: 1px solid var(--panel-border); transition: max-height 0.2s; }
|
|
@@ -594,7 +592,7 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
594
592
|
.mobile-keys .mk-buttons { display: none; }
|
|
595
593
|
.mobile-keys.mk-focused .mk-buttons { display: flex; flex-wrap: wrap; gap: 4px; }
|
|
596
594
|
}
|
|
597
|
-
`,
|
|
595
|
+
`,m=JSON.stringify(e.terminal).replace(/</g,"\\u003c"),d=JSON.stringify({terminal:a,scrollback:s,theme:e.terminal,renderer:n,fsRoots:r,wsBase:p||""}).replace(/</g,"\\u003c");return`<!DOCTYPE html>
|
|
598
596
|
<html lang="en">
|
|
599
597
|
<head>
|
|
600
598
|
<meta charset="UTF-8" />
|
|
@@ -607,8 +605,8 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
607
605
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
608
606
|
<title>tmux-weblink</title>
|
|
609
607
|
<style>
|
|
610
|
-
${
|
|
611
|
-
${
|
|
608
|
+
${c(e.shell)}
|
|
609
|
+
${l}
|
|
612
610
|
</style>
|
|
613
611
|
</head>
|
|
614
612
|
<body>
|
|
@@ -633,7 +631,6 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
633
631
|
<header class="fixed-header">
|
|
634
632
|
<div class="brand" id="brand-toggle">tmux<span>-weblink</span></div>
|
|
635
633
|
<div class="header-actions">
|
|
636
|
-
${t?`<button class="header-btn" id="cmdbar-btn" title="Search" aria-label="Search">${i("search")}</button>`:""}
|
|
637
634
|
</div>
|
|
638
635
|
<div id="header-git" title="Click to browse repository"></div>
|
|
639
636
|
<span id="header-ram"></span>
|
|
@@ -703,16 +700,9 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
703
700
|
<!-- Settings popover -->
|
|
704
701
|
<div class="popover-backdrop" id="settings-backdrop"></div>
|
|
705
702
|
<div class="settings-popover" id="settings-popover">
|
|
706
|
-
<div class="settings-item">
|
|
707
|
-
<span>Command bar</span>
|
|
708
|
-
<button class="toggle${t?" on":""}" id="set-commandbar"></button>
|
|
709
|
-
</div>
|
|
710
|
-
<div class="settings-item">
|
|
711
|
-
</div>
|
|
712
|
-
<hr class="settings-divider" />
|
|
713
703
|
<div class="settings-item">
|
|
714
704
|
<span>Terminal renderer</span>
|
|
715
|
-
<span style="font-size:var(--text-xs);color:var(--panel-muted)">${
|
|
705
|
+
<span style="font-size:var(--text-xs);color:var(--panel-muted)">${n==="ghostty"?"Ghostty":"xterm.js"}</span>
|
|
716
706
|
</div>
|
|
717
707
|
<hr class="settings-divider" />
|
|
718
708
|
<div style="padding:4px 0">
|
|
@@ -722,8 +712,8 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
722
712
|
<button class="theme-option" data-theme="dark-cove" title="Dark Cove"><span class="theme-dot" style="background:#7aa2f7"></span>Dark Cove${e.template==="dark-cove"?'<span class="theme-check">\u2713</span>':""}</button>
|
|
723
713
|
</div>
|
|
724
714
|
<hr class="settings-divider" />
|
|
725
|
-
<a href="/settings" class="settings-item" id="set-
|
|
726
|
-
<span>
|
|
715
|
+
<a href="/settings" class="settings-item" id="set-settings-link" style="cursor:pointer;color:inherit;text-decoration:none">
|
|
716
|
+
<span>Settings</span>
|
|
727
717
|
<span style="font-size:var(--text-xs);color:var(--panel-muted)">\u2192</span>
|
|
728
718
|
</a>
|
|
729
719
|
</div>
|
|
@@ -760,21 +750,19 @@ import{cssVarsStyle as g}from"../theme.js";import{commandbarCSS as b,commandbarH
|
|
|
760
750
|
})();
|
|
761
751
|
</script>
|
|
762
752
|
|
|
763
|
-
${
|
|
764
|
-
${t?x():""}
|
|
753
|
+
${g()}
|
|
765
754
|
|
|
766
755
|
<script>
|
|
767
|
-
window.__TMUX_WEB_SHELL__ = ${
|
|
756
|
+
window.__TMUX_WEB_SHELL__ = ${d};
|
|
768
757
|
</script>
|
|
769
758
|
<script type="module">
|
|
770
759
|
await import('/assets/shell-client.js');
|
|
771
|
-
${t?m(a,[]):""}
|
|
772
760
|
// Wrapper: refresh sidebar list, then open session
|
|
773
761
|
window.__onSessionCreated = async function(name, agentId) {
|
|
774
762
|
await window.__refreshSidebar();
|
|
775
763
|
window.__openSession(name, agentId || undefined);
|
|
776
764
|
};
|
|
777
|
-
${
|
|
765
|
+
${x("__onSessionCreated")}
|
|
778
766
|
</script>
|
|
779
767
|
<script>
|
|
780
768
|
// Sync app-layout height to visual viewport so mobile keyboard doesn't overlap
|
|
@@ -841,4 +829,4 @@ if ('serviceWorker' in navigator) {
|
|
|
841
829
|
}
|
|
842
830
|
</script>
|
|
843
831
|
</body>
|
|
844
|
-
</html>`}export{
|
|
832
|
+
</html>`}export{k as renderShell};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readSettings as
|
|
1
|
+
import{readSettings as a,writeSettings as t}from"./settings.js";const s=[{id:"agents",label:"Agents page",description:"watch AI agents (Claude, Codex, OpenCode, Cursor) in recently-viewed panes",kind:"builtin",isEnabled:e=>e.agents===!0,async enable(){const e=await a();await t({...e,agents:!0}),console.log("\u2713 agents page enabled")},async disable(){const e=await a();await t({...e,agents:!1}),console.log("\u2713 agents page disabled")}}];export{s as SETUP_FEATURES};
|