tmuxes 0.1.8 → 0.1.9

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.
Files changed (140) hide show
  1. package/.node-version +1 -0
  2. package/.nvmrc +1 -0
  3. package/.tmp-npm-cache/_cacache/content-v2/sha512/43/27/5e000b8b9c56a6ccc66f709485499f4304e2cb1982582ba571321c07b3ef56fcabd2c671898cc8003365a0485b6fd8e73e7b17b073cec0f7d1628c1a99df +0 -0
  4. package/.tmp-npm-cache/_cacache/content-v2/sha512/51/cf/4301295d74559ed494bae160d54d8741077f89faebb311882ac065019246951e7b53f3dcb913793c42b331e14c7070c4810c3cdc27a427d103a7db4614e0 +0 -0
  5. package/.tmp-npm-cache/_cacache/content-v2/sha512/c3/4d/d68a454a916e74c2617f586fbf770981b33811d667c2547eb0e9fc21938f4ee7e98f1ceee4bde8ad8815b5f6efe21b60eee798837d68f51a3340d7e5bb7a +0 -0
  6. package/.tmp-npm-cache/_cacache/content-v2/sha512/fe/40/2abfbefc96299e8bf714aa91d62607190ae299e102cf5933db2e2904640d65d25d67dbbb6fa2ddc92a17f00b9dbfdf2e37487f67d96ec36c64a285b59a7d +0 -0
  7. package/.tmp-npm-cache/_cacache/index-v5/27/fe/81a3de6ce7ae3d1e41a3421de20c5629998c4ee5d0ffe2037630f03b03b2 +4 -0
  8. package/.tmp-npm-cache/_cacache/index-v5/65/22/dd66711f62681fce09aabb2357a2907b4a0c778ac5227c4baf9603fd86e8 +4 -0
  9. package/.tmp-npm-cache/_update-notifier-last-checked +0 -0
  10. package/AGENTS.md +15 -0
  11. package/CLAUDE.md +3 -0
  12. package/LICENSE +21 -21
  13. package/README.en.md +304 -0
  14. package/README.md +299 -295
  15. package/SECURITY.md +31 -0
  16. package/{public → client}/index.html +12 -13
  17. package/client/package.json +29 -0
  18. package/client/src/App.tsx +123 -0
  19. package/client/src/activity.ts +5 -0
  20. package/client/src/api.ts +130 -0
  21. package/client/src/attention.tsx +157 -0
  22. package/client/src/components/FileExplorer.tsx +156 -0
  23. package/client/src/components/FileViewer.tsx +194 -0
  24. package/client/src/components/SessionRow.tsx +108 -0
  25. package/client/src/components/SessionTree.tsx +197 -0
  26. package/client/src/components/SettingsButton.tsx +122 -0
  27. package/client/src/components/Sidebar.tsx +96 -0
  28. package/client/src/components/StatusBanner.tsx +31 -0
  29. package/client/src/components/TargetGroup.tsx +275 -0
  30. package/client/src/components/TerminalPanel.tsx +192 -0
  31. package/client/src/folders.ts +245 -0
  32. package/client/src/hooks/useTerminal.ts +67 -0
  33. package/client/src/hooks/useTmuxSocket.ts +65 -0
  34. package/client/src/i18n.ts +213 -0
  35. package/client/src/main.tsx +17 -0
  36. package/client/src/settings.tsx +87 -0
  37. package/client/src/styles.css +723 -0
  38. package/client/src/types.ts +93 -0
  39. package/client/src/util.ts +65 -0
  40. package/client/tsconfig.json +13 -0
  41. package/client/vite.config.ts +15 -0
  42. package/fig/fig1.png +0 -0
  43. package/package.json +28 -61
  44. package/scripts/prepack.mjs +35 -0
  45. package/{bin → server/bin}/tmuxes.js +36 -36
  46. package/server/package.json +61 -0
  47. package/server/src/agentHooks.ts +120 -0
  48. package/server/src/agentOutput.ts +36 -0
  49. package/server/src/agentState.ts +70 -0
  50. package/server/src/config.ts +31 -0
  51. package/server/src/exe.ts +34 -0
  52. package/server/src/exec.ts +61 -0
  53. package/server/src/files.ts +330 -0
  54. package/server/src/foldersStore.ts +114 -0
  55. package/server/src/index.ts +114 -0
  56. package/server/src/logger.ts +16 -0
  57. package/{dist/monitor.js → server/src/monitor.ts} +10 -9
  58. package/server/src/openBrowser.ts +28 -0
  59. package/{dist/platform.js → server/src/platform.ts} +4 -5
  60. package/server/src/rest/router.ts +290 -0
  61. package/server/src/targetCommand.ts +79 -0
  62. package/server/src/targets.ts +152 -0
  63. package/server/src/tmux/builder.ts +198 -0
  64. package/server/src/tmux/formats.ts +95 -0
  65. package/server/src/tmux/sessions.ts +204 -0
  66. package/server/src/validate.ts +79 -0
  67. package/server/src/windowsSsh.ts +239 -0
  68. package/server/src/winshell/manager.ts +296 -0
  69. package/server/src/ws/protocol.ts +15 -0
  70. package/server/src/ws/sshState.ts +36 -0
  71. package/server/src/ws/terminalSession.ts +207 -0
  72. package/server/src/ws/wsServer.ts +153 -0
  73. package/server/src/wsl.ts +38 -0
  74. package/server/test/agentHooks.test.ts +66 -0
  75. package/server/test/agentOutput.test.ts +26 -0
  76. package/server/test/agentState.test.ts +24 -0
  77. package/server/test/builder.test.ts +162 -0
  78. package/server/test/files.test.ts +81 -0
  79. package/server/test/formats.test.ts +123 -0
  80. package/server/test/monitor.test.ts +25 -0
  81. package/server/test/validate.test.ts +71 -0
  82. package/server/test/wsl.test.ts +18 -0
  83. package/server/tsconfig.json +9 -0
  84. package/server/vitest.config.ts +12 -0
  85. package/start.cmd +30 -0
  86. package/start.command +20 -0
  87. package/start.sh +20 -0
  88. package/tsconfig.base.json +19 -0
  89. package/dist/agentHooks.js +0 -91
  90. package/dist/agentHooks.js.map +0 -1
  91. package/dist/agentOutput.js +0 -30
  92. package/dist/agentOutput.js.map +0 -1
  93. package/dist/agentState.js +0 -45
  94. package/dist/agentState.js.map +0 -1
  95. package/dist/config.js +0 -32
  96. package/dist/config.js.map +0 -1
  97. package/dist/exe.js +0 -37
  98. package/dist/exe.js.map +0 -1
  99. package/dist/exec.js +0 -43
  100. package/dist/exec.js.map +0 -1
  101. package/dist/files.js +0 -243
  102. package/dist/files.js.map +0 -1
  103. package/dist/foldersStore.js +0 -103
  104. package/dist/foldersStore.js.map +0 -1
  105. package/dist/index.js +0 -117
  106. package/dist/index.js.map +0 -1
  107. package/dist/logger.js +0 -16
  108. package/dist/logger.js.map +0 -1
  109. package/dist/monitor.js.map +0 -1
  110. package/dist/openBrowser.js +0 -31
  111. package/dist/openBrowser.js.map +0 -1
  112. package/dist/platform.js.map +0 -1
  113. package/dist/rest/router.js +0 -190
  114. package/dist/rest/router.js.map +0 -1
  115. package/dist/targetCommand.js +0 -41
  116. package/dist/targetCommand.js.map +0 -1
  117. package/dist/targets.js +0 -131
  118. package/dist/targets.js.map +0 -1
  119. package/dist/tmux/builder.js +0 -173
  120. package/dist/tmux/builder.js.map +0 -1
  121. package/dist/tmux/formats.js +0 -61
  122. package/dist/tmux/formats.js.map +0 -1
  123. package/dist/tmux/sessions.js +0 -157
  124. package/dist/tmux/sessions.js.map +0 -1
  125. package/dist/validate.js +0 -65
  126. package/dist/validate.js.map +0 -1
  127. package/dist/winshell/manager.js +0 -267
  128. package/dist/winshell/manager.js.map +0 -1
  129. package/dist/ws/protocol.js +0 -4
  130. package/dist/ws/protocol.js.map +0 -1
  131. package/dist/ws/sshState.js +0 -35
  132. package/dist/ws/sshState.js.map +0 -1
  133. package/dist/ws/terminalSession.js +0 -204
  134. package/dist/ws/terminalSession.js.map +0 -1
  135. package/dist/ws/wsServer.js +0 -151
  136. package/dist/ws/wsServer.js.map +0 -1
  137. package/dist/wsl.js +0 -35
  138. package/dist/wsl.js.map +0 -1
  139. package/public/assets/index-BpVrfoZw.js +0 -44
  140. package/public/assets/index-D_X5SnGx.css +0 -1
@@ -0,0 +1,723 @@
1
+ :root {
2
+ --bg: #1a1b26;
3
+ --bg-alt: #16161e;
4
+ --panel: #1f2233;
5
+ --border: #2a2e42;
6
+ --fg: #c0caf5;
7
+ --fg-dim: #7a82a8;
8
+ --accent: #7aa2f7;
9
+ --green: #9ece6a;
10
+ --red: #f7768e;
11
+ --yellow: #e0af68;
12
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
+ }
14
+
15
+ * {
16
+ box-sizing: border-box;
17
+ }
18
+
19
+ html,
20
+ body,
21
+ #root {
22
+ height: 100%;
23
+ margin: 0;
24
+ /* The page itself never scrolls — only the sidebar list and xterm's own
25
+ viewport do. This breaks the FitAddon <-> scrollbar resize feedback loop
26
+ that caused flickering scrollbars when the window was maximized. */
27
+ overflow: hidden;
28
+ }
29
+
30
+ body {
31
+ background: var(--bg);
32
+ color: var(--fg);
33
+ font-size: 14px;
34
+ }
35
+
36
+ button {
37
+ font: inherit;
38
+ color: var(--fg);
39
+ background: var(--panel);
40
+ border: 1px solid var(--border);
41
+ border-radius: 5px;
42
+ padding: 3px 8px;
43
+ cursor: pointer;
44
+ }
45
+ button:hover:not(:disabled) {
46
+ border-color: var(--accent);
47
+ }
48
+ button:disabled {
49
+ opacity: 0.5;
50
+ cursor: default;
51
+ }
52
+ button.primary {
53
+ background: var(--accent);
54
+ color: #11121a;
55
+ border-color: var(--accent);
56
+ font-weight: 600;
57
+ }
58
+ button.danger:hover:not(:disabled) {
59
+ border-color: var(--red);
60
+ color: var(--red);
61
+ }
62
+
63
+ input {
64
+ font: inherit;
65
+ color: var(--fg);
66
+ background: var(--bg-alt);
67
+ border: 1px solid var(--border);
68
+ border-radius: 5px;
69
+ padding: 4px 7px;
70
+ }
71
+ input:focus {
72
+ outline: none;
73
+ border-color: var(--accent);
74
+ }
75
+
76
+ /* ---------- layout ---------- */
77
+ .app {
78
+ display: flex;
79
+ height: 100%;
80
+ overflow: hidden;
81
+ }
82
+
83
+ .sidebar {
84
+ width: 320px;
85
+ min-width: 320px;
86
+ background: var(--bg-alt);
87
+ border-right: 1px solid var(--border);
88
+ display: flex;
89
+ flex-direction: column;
90
+ overflow: hidden;
91
+ }
92
+
93
+ .sidebar-header {
94
+ display: flex;
95
+ align-items: center;
96
+ justify-content: space-between;
97
+ padding: 12px 14px;
98
+ border-bottom: 1px solid var(--border);
99
+ }
100
+ .sidebar-header h1 {
101
+ font-size: 15px;
102
+ margin: 0;
103
+ letter-spacing: 0.5px;
104
+ }
105
+ .sidebar-top {
106
+ overflow-y: auto;
107
+ flex: 1;
108
+ min-height: 80px;
109
+ padding: 6px;
110
+ }
111
+ .sidebar-vdivider {
112
+ height: 6px;
113
+ flex: none;
114
+ cursor: row-resize;
115
+ background: var(--border);
116
+ }
117
+ .sidebar-vdivider:hover {
118
+ background: var(--accent);
119
+ }
120
+ .sidebar-bottom {
121
+ flex: none;
122
+ display: flex;
123
+ flex-direction: column;
124
+ overflow: hidden;
125
+ border-top: 1px solid var(--border);
126
+ }
127
+ .sidebar-footer {
128
+ flex: none;
129
+ border-top: 1px solid var(--border);
130
+ padding: 6px 8px;
131
+ }
132
+ .section-label {
133
+ font-size: 11px;
134
+ text-transform: uppercase;
135
+ letter-spacing: 0.5px;
136
+ color: var(--fg-dim);
137
+ padding: 5px 8px 3px;
138
+ flex: none;
139
+ }
140
+
141
+ /* ---------- workspace (right side: terminal + optional file viewer) ---------- */
142
+ .workspace {
143
+ flex: 1;
144
+ display: flex;
145
+ flex-direction: column;
146
+ min-width: 0;
147
+ overflow: hidden;
148
+ }
149
+ .term-region {
150
+ flex: 1;
151
+ display: flex;
152
+ min-height: 0;
153
+ position: relative;
154
+ }
155
+ .hdivider {
156
+ height: 6px;
157
+ flex: none;
158
+ cursor: row-resize;
159
+ background: var(--border);
160
+ }
161
+ .hdivider:hover {
162
+ background: var(--accent);
163
+ }
164
+ .viewer-region {
165
+ flex: none;
166
+ overflow: hidden;
167
+ display: flex;
168
+ flex-direction: column;
169
+ background: var(--bg-alt);
170
+ }
171
+
172
+ .panel {
173
+ flex: 1;
174
+ position: relative;
175
+ background: #000;
176
+ min-width: 0;
177
+ overflow: hidden;
178
+ }
179
+
180
+ /* ---------- target group ---------- */
181
+ .target-group {
182
+ margin-bottom: 6px;
183
+ }
184
+ .target-head {
185
+ display: flex;
186
+ align-items: center;
187
+ gap: 6px;
188
+ padding: 6px 8px;
189
+ border-radius: 6px;
190
+ cursor: pointer;
191
+ user-select: none;
192
+ }
193
+ .target-head:hover {
194
+ background: var(--panel);
195
+ }
196
+ .target-head .label {
197
+ font-weight: 600;
198
+ flex: 1;
199
+ overflow: hidden;
200
+ text-overflow: ellipsis;
201
+ white-space: nowrap;
202
+ }
203
+ .target-head .kind {
204
+ font-size: 11px;
205
+ color: var(--fg-dim);
206
+ border: 1px solid var(--border);
207
+ border-radius: 4px;
208
+ padding: 0 5px;
209
+ }
210
+ .caret {
211
+ width: 12px;
212
+ color: var(--fg-dim);
213
+ }
214
+
215
+ .badge {
216
+ font-size: 11px;
217
+ padding: 0 5px;
218
+ border-radius: 4px;
219
+ }
220
+ .badge.err {
221
+ color: var(--red);
222
+ }
223
+ .badge.loading {
224
+ color: var(--yellow);
225
+ }
226
+
227
+ .session-list {
228
+ padding: 2px 0 6px 14px;
229
+ }
230
+ .empty {
231
+ color: var(--fg-dim);
232
+ font-size: 12px;
233
+ padding: 4px 8px;
234
+ }
235
+ .error-line {
236
+ color: var(--red);
237
+ font-size: 12px;
238
+ padding: 4px 8px;
239
+ display: flex;
240
+ align-items: center;
241
+ gap: 8px;
242
+ }
243
+ .error-line span {
244
+ min-width: 0;
245
+ flex: 1;
246
+ overflow: hidden;
247
+ text-overflow: ellipsis;
248
+ }
249
+ .error-line button {
250
+ flex: none;
251
+ padding: 2px 6px;
252
+ font-size: 12px;
253
+ }
254
+
255
+ /* ---------- session row ---------- */
256
+ .session-row {
257
+ display: flex;
258
+ align-items: center;
259
+ gap: 6px;
260
+ padding: 5px 8px;
261
+ border-radius: 6px;
262
+ cursor: pointer;
263
+ }
264
+ .session-row:hover {
265
+ background: var(--panel);
266
+ }
267
+ .session-row.selected {
268
+ background: var(--panel);
269
+ box-shadow: inset 2px 0 0 var(--accent);
270
+ }
271
+ .session-row .name {
272
+ flex: 1;
273
+ overflow: hidden;
274
+ text-overflow: ellipsis;
275
+ white-space: nowrap;
276
+ }
277
+ .dot {
278
+ width: 8px;
279
+ height: 8px;
280
+ border-radius: 50%;
281
+ flex: none;
282
+ }
283
+ .dot.inactive {
284
+ background: var(--green);
285
+ }
286
+ .dot.active {
287
+ background: var(--red);
288
+ box-shadow: 0 0 0 2px rgba(247, 118, 142, 0.24);
289
+ }
290
+ .session-row.attention .name {
291
+ font-weight: 600;
292
+ }
293
+ .attn-badge {
294
+ flex: none;
295
+ padding: 1px 5px;
296
+ border: 1px solid var(--border);
297
+ border-radius: 5px;
298
+ font-size: 11px;
299
+ line-height: 1.35;
300
+ white-space: nowrap;
301
+ }
302
+ .attn-badge.decision {
303
+ border-color: var(--red);
304
+ color: var(--red);
305
+ }
306
+ .attn-badge.done {
307
+ border-color: var(--green);
308
+ color: var(--green);
309
+ }
310
+ .attn-badge.error {
311
+ border-color: var(--red);
312
+ color: var(--red);
313
+ }
314
+ .meta {
315
+ font-size: 11px;
316
+ color: var(--fg-dim);
317
+ }
318
+ .row-actions {
319
+ display: flex;
320
+ gap: 4px;
321
+ opacity: 0;
322
+ }
323
+ .session-row:hover .row-actions {
324
+ opacity: 1;
325
+ }
326
+ .row-actions button {
327
+ padding: 1px 6px;
328
+ font-size: 12px;
329
+ }
330
+
331
+ /* ---------- create form ---------- */
332
+ .create-form {
333
+ display: flex;
334
+ flex-direction: column;
335
+ gap: 5px;
336
+ padding: 6px 8px;
337
+ }
338
+ .create-form .row {
339
+ display: flex;
340
+ gap: 5px;
341
+ }
342
+ .create-form input {
343
+ flex: 1;
344
+ min-width: 0;
345
+ }
346
+ .create-form select {
347
+ font: inherit;
348
+ color: var(--fg);
349
+ background: var(--bg-alt);
350
+ border: 1px solid var(--border);
351
+ border-radius: 5px;
352
+ padding: 4px 7px;
353
+ }
354
+ .field-error {
355
+ color: var(--red);
356
+ font-size: 11px;
357
+ }
358
+
359
+ /* ---------- terminal panel ---------- */
360
+ .agent-toolbar {
361
+ position: absolute;
362
+ top: 8px;
363
+ right: 10px;
364
+ z-index: 4;
365
+ display: flex;
366
+ align-items: center;
367
+ gap: 5px;
368
+ padding: 3px;
369
+ border: 1px solid var(--border);
370
+ border-radius: 6px;
371
+ background: rgba(17, 24, 39, 0.88);
372
+ backdrop-filter: blur(4px);
373
+ }
374
+ .agent-toolbar button {
375
+ padding: 2px 7px;
376
+ min-width: 0;
377
+ height: 22px;
378
+ font-size: 12px;
379
+ line-height: 1;
380
+ }
381
+ .agent-error {
382
+ color: var(--red);
383
+ font-size: 12px;
384
+ padding: 0 4px;
385
+ }
386
+ .term-host {
387
+ position: absolute;
388
+ inset: 0;
389
+ padding: 4px;
390
+ overflow: hidden;
391
+ }
392
+ .term-host .xterm {
393
+ height: 100%;
394
+ width: 100%;
395
+ }
396
+ .panel-placeholder {
397
+ position: absolute;
398
+ inset: 0;
399
+ display: flex;
400
+ align-items: center;
401
+ justify-content: center;
402
+ color: var(--fg-dim);
403
+ flex-direction: column;
404
+ gap: 6px;
405
+ }
406
+
407
+ /* ---------- status banner ---------- */
408
+ .status-banner {
409
+ position: absolute;
410
+ top: 12px;
411
+ left: 50%;
412
+ transform: translateX(-50%);
413
+ background: var(--panel);
414
+ border: 1px solid var(--border);
415
+ border-radius: 8px;
416
+ padding: 8px 14px;
417
+ display: flex;
418
+ align-items: center;
419
+ gap: 12px;
420
+ box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
421
+ max-width: 80%;
422
+ z-index: 5;
423
+ }
424
+ .status-banner.error {
425
+ border-color: var(--red);
426
+ }
427
+ .status-banner .msg {
428
+ font-size: 13px;
429
+ }
430
+ .spinner {
431
+ width: 14px;
432
+ height: 14px;
433
+ border: 2px solid var(--border);
434
+ border-top-color: var(--accent);
435
+ border-radius: 50%;
436
+ animation: spin 0.8s linear infinite;
437
+ }
438
+ @keyframes spin {
439
+ to {
440
+ transform: rotate(360deg);
441
+ }
442
+ }
443
+
444
+ /* ---------- folder tree ---------- */
445
+ .tree.drop-root {
446
+ outline: 1px dashed var(--accent);
447
+ outline-offset: -2px;
448
+ border-radius: 6px;
449
+ }
450
+ .folder.drop {
451
+ background: rgba(122, 162, 247, 0.12);
452
+ border-radius: 6px;
453
+ }
454
+ .folder-head {
455
+ display: flex;
456
+ align-items: center;
457
+ gap: 4px;
458
+ padding: 4px 8px;
459
+ border-radius: 6px;
460
+ cursor: pointer;
461
+ user-select: none;
462
+ }
463
+ .folder-head:hover {
464
+ background: var(--panel);
465
+ }
466
+ .folder-name {
467
+ flex: 1;
468
+ overflow: hidden;
469
+ text-overflow: ellipsis;
470
+ white-space: nowrap;
471
+ }
472
+ .folder-actions {
473
+ display: flex;
474
+ gap: 3px;
475
+ opacity: 0;
476
+ }
477
+ .folder-head:hover .folder-actions {
478
+ opacity: 1;
479
+ }
480
+ .folder-actions button {
481
+ padding: 0 5px;
482
+ font-size: 12px;
483
+ }
484
+ .folder-head input {
485
+ flex: 1;
486
+ min-width: 0;
487
+ }
488
+
489
+ .list-toolbar {
490
+ display: flex;
491
+ gap: 6px;
492
+ padding: 6px 8px 2px;
493
+ }
494
+ .list-toolbar button {
495
+ font-size: 12px;
496
+ padding: 2px 8px;
497
+ }
498
+
499
+ /* ---------- file explorer (sidebar bottom) ---------- */
500
+ .explorer {
501
+ display: flex;
502
+ flex-direction: column;
503
+ overflow: hidden;
504
+ flex: 1;
505
+ }
506
+ .explorer-empty {
507
+ color: var(--fg-dim);
508
+ padding: 8px;
509
+ font-size: 12px;
510
+ }
511
+ .explorer-head {
512
+ display: flex;
513
+ align-items: center;
514
+ gap: 6px;
515
+ padding: 2px 8px 4px;
516
+ flex: none;
517
+ }
518
+ .explorer-path {
519
+ flex: 1;
520
+ overflow: hidden;
521
+ text-overflow: ellipsis;
522
+ white-space: nowrap;
523
+ color: var(--accent);
524
+ font-weight: 600;
525
+ }
526
+ .explorer-actions {
527
+ display: flex;
528
+ gap: 4px;
529
+ }
530
+ .explorer-actions button {
531
+ padding: 1px 7px;
532
+ }
533
+ .explorer-list {
534
+ overflow-y: auto;
535
+ flex: 1;
536
+ }
537
+ .file-row {
538
+ display: flex;
539
+ align-items: center;
540
+ gap: 6px;
541
+ padding: 3px 8px;
542
+ border-radius: 5px;
543
+ cursor: pointer;
544
+ }
545
+ .file-row:hover {
546
+ background: var(--panel);
547
+ }
548
+ .file-row.disabled {
549
+ cursor: default;
550
+ color: var(--fg-dim);
551
+ }
552
+ .file-row.disabled:hover {
553
+ background: transparent;
554
+ }
555
+ .file-row.open {
556
+ background: var(--panel);
557
+ box-shadow: inset 2px 0 0 var(--accent);
558
+ }
559
+ .file-icon {
560
+ flex: none;
561
+ }
562
+ .file-name {
563
+ overflow: hidden;
564
+ text-overflow: ellipsis;
565
+ white-space: nowrap;
566
+ }
567
+
568
+ /* ---------- settings ---------- */
569
+ .settings {
570
+ position: relative;
571
+ }
572
+ .settings-gear {
573
+ width: 100%;
574
+ text-align: left;
575
+ }
576
+ .settings-backdrop {
577
+ position: fixed;
578
+ inset: 0;
579
+ z-index: 19;
580
+ }
581
+ .settings-panel {
582
+ position: absolute;
583
+ bottom: 40px;
584
+ left: 0;
585
+ width: 250px;
586
+ background: var(--panel);
587
+ border: 1px solid var(--border);
588
+ border-radius: 8px;
589
+ padding: 10px;
590
+ z-index: 20;
591
+ box-shadow: 0 8px 28px rgba(0, 0, 0, 0.5);
592
+ }
593
+ .settings-title {
594
+ font-size: 12px;
595
+ color: var(--fg-dim);
596
+ margin-bottom: 8px;
597
+ }
598
+ .stepper {
599
+ display: flex;
600
+ align-items: center;
601
+ justify-content: space-between;
602
+ margin-bottom: 6px;
603
+ }
604
+ .stepper-label {
605
+ font-size: 13px;
606
+ }
607
+ .stepper-controls {
608
+ display: flex;
609
+ align-items: center;
610
+ gap: 6px;
611
+ }
612
+ .stepper-value {
613
+ min-width: 36px;
614
+ text-align: center;
615
+ font-variant-numeric: tabular-nums;
616
+ font-size: 12px;
617
+ }
618
+ .toggle {
619
+ display: flex;
620
+ align-items: center;
621
+ gap: 8px;
622
+ margin-bottom: 6px;
623
+ cursor: pointer;
624
+ }
625
+ .toggle input {
626
+ cursor: pointer;
627
+ }
628
+ .toggle-label {
629
+ font-size: 13px;
630
+ }
631
+ .settings-panel .settings-title + .stepper,
632
+ .settings-panel .settings-title:not(:first-child) {
633
+ margin-top: 2px;
634
+ }
635
+ .settings-panel .settings-title:not(:first-of-type) {
636
+ margin-top: 12px;
637
+ }
638
+ .settings-actions {
639
+ display: flex;
640
+ justify-content: flex-end;
641
+ gap: 6px;
642
+ margin-top: 10px;
643
+ }
644
+
645
+ /* ---------- file viewer (workspace bottom) ---------- */
646
+ .viewer {
647
+ display: flex;
648
+ flex-direction: column;
649
+ height: 100%;
650
+ overflow: hidden;
651
+ }
652
+ .viewer-head {
653
+ display: flex;
654
+ align-items: center;
655
+ gap: 8px;
656
+ padding: 5px 10px;
657
+ border-bottom: 1px solid var(--border);
658
+ flex: none;
659
+ }
660
+ .viewer-name {
661
+ font-weight: 600;
662
+ }
663
+ .viewer-path {
664
+ color: var(--fg-dim);
665
+ font-size: 12px;
666
+ overflow: hidden;
667
+ text-overflow: ellipsis;
668
+ white-space: nowrap;
669
+ }
670
+ .viewer-head-spacer {
671
+ flex: 1;
672
+ }
673
+ .viewer-note {
674
+ color: var(--yellow);
675
+ font-size: 12px;
676
+ }
677
+ .viewer-body {
678
+ flex: 1;
679
+ overflow: auto;
680
+ }
681
+ .viewer-pre {
682
+ margin: 0;
683
+ padding: 8px 10px;
684
+ font-family: Menlo, Consolas, 'DejaVu Sans Mono', monospace;
685
+ line-height: 1.45;
686
+ white-space: pre;
687
+ tab-size: 4;
688
+ }
689
+ .viewer-editor {
690
+ display: block;
691
+ width: 100%;
692
+ height: 100%;
693
+ box-sizing: border-box;
694
+ margin: 0;
695
+ padding: 8px 10px;
696
+ border: 0;
697
+ outline: none;
698
+ resize: none;
699
+ background: transparent;
700
+ color: var(--fg);
701
+ font-family: Menlo, Consolas, 'DejaVu Sans Mono', monospace;
702
+ line-height: 1.45;
703
+ tab-size: 2;
704
+ white-space: pre;
705
+ overflow: auto;
706
+ }
707
+ .viewer-head button {
708
+ padding: 2px 8px;
709
+ font-size: 12px;
710
+ }
711
+ .dirty-dot {
712
+ color: var(--yellow);
713
+ margin-right: 5px;
714
+ font-size: 11px;
715
+ vertical-align: middle;
716
+ }
717
+ .viewer-msg {
718
+ padding: 12px;
719
+ color: var(--fg-dim);
720
+ }
721
+ .viewer-msg.error {
722
+ color: var(--red);
723
+ }