@bakapiano/ccsm 0.13.0 → 0.15.0
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/CLAUDE.md +474 -475
- package/README.md +189 -190
- package/bin/ccsm.js +194 -194
- package/lib/cliActivity.js +118 -0
- package/lib/codexSeed.js +147 -0
- package/lib/config.js +211 -188
- package/lib/folders.js +105 -105
- package/lib/localCliSessions.js +489 -489
- package/lib/persistedSessions.js +144 -142
- package/lib/webTerminal.js +224 -224
- package/lib/workspace.js +230 -230
- package/package.json +57 -57
- package/public/css/base.css +99 -99
- package/public/css/cards.css +183 -183
- package/public/css/feedback.css +303 -303
- package/public/css/forms.css +405 -405
- package/public/css/layout.css +160 -160
- package/public/css/modal.css +190 -190
- package/public/css/responsive.css +10 -10
- package/public/css/sidebar.css +613 -608
- package/public/css/terminals.css +294 -294
- package/public/css/tokens.css +81 -81
- package/public/css/wco.css +98 -98
- package/public/css/widgets.css +1628 -1628
- package/public/index.html +111 -105
- package/public/js/api.js +296 -280
- package/public/js/components/AdoptModal.js +343 -343
- package/public/js/components/App.js +35 -35
- package/public/js/components/DirectoryPicker.js +203 -203
- package/public/js/components/EntityFormModal.js +141 -141
- package/public/js/components/Modal.js +51 -51
- package/public/js/components/OfflineBanner.js +93 -93
- package/public/js/components/PageTitleBar.js +13 -13
- package/public/js/components/Picker.js +179 -179
- package/public/js/components/Popover.js +55 -55
- package/public/js/components/Sidebar.js +299 -299
- package/public/js/components/TerminalView.js +314 -314
- package/public/js/components/useDragSort.js +67 -67
- package/public/js/dialog.js +67 -67
- package/public/js/icons.js +177 -177
- package/public/js/main.js +132 -132
- package/public/js/pages/AboutPage.js +165 -165
- package/public/js/pages/ConfigurePage.js +505 -475
- package/public/js/pages/LaunchPage.js +369 -369
- package/public/js/pages/SessionsPage.js +101 -97
- package/public/js/state.js +231 -231
- package/scripts/dev.js +44 -11
- package/scripts/install.js +158 -137
- package/scripts/restart-helper.js +91 -0
- package/scripts/upgrade-helper.js +155 -0
- package/server.js +1278 -1232
- package/lib/cliSessionWatcher.js +0 -249
- package/public/manifest.webmanifest +0 -15
package/public/css/terminals.css
CHANGED
|
@@ -1,294 +1,294 @@
|
|
|
1
|
-
/* Terminals tab · left rail (active sessions) + right pane (xterm host) */
|
|
2
|
-
|
|
3
|
-
.terminals-layout {
|
|
4
|
-
display: grid;
|
|
5
|
-
grid-template-columns: 240px 1fr;
|
|
6
|
-
gap: var(--s-4);
|
|
7
|
-
/* viewport minus page header + footer + padding; lets xterm fill height */
|
|
8
|
-
height: calc(100vh - 220px);
|
|
9
|
-
min-height: 480px;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.terminals-rail {
|
|
13
|
-
background: var(--bg-elev);
|
|
14
|
-
border: 1px solid var(--border);
|
|
15
|
-
border-radius: var(--r-md);
|
|
16
|
-
padding: var(--s-2);
|
|
17
|
-
display: flex;
|
|
18
|
-
flex-direction: column;
|
|
19
|
-
gap: 2px;
|
|
20
|
-
overflow-y: auto;
|
|
21
|
-
}
|
|
22
|
-
.terminals-rail-head {
|
|
23
|
-
display: flex;
|
|
24
|
-
justify-content: space-between;
|
|
25
|
-
align-items: center;
|
|
26
|
-
padding: var(--s-2) var(--s-3);
|
|
27
|
-
font-size: 11px;
|
|
28
|
-
text-transform: uppercase;
|
|
29
|
-
letter-spacing: 0.06em;
|
|
30
|
-
color: var(--ink-muted);
|
|
31
|
-
border-bottom: 1px solid var(--border-soft);
|
|
32
|
-
margin-bottom: var(--s-2);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/* button row showing one terminal in the rail */
|
|
36
|
-
.terminal-row {
|
|
37
|
-
appearance: none;
|
|
38
|
-
background: transparent;
|
|
39
|
-
border: 0;
|
|
40
|
-
width: 100%;
|
|
41
|
-
text-align: left;
|
|
42
|
-
padding: 8px 10px;
|
|
43
|
-
border-radius: var(--r-sm);
|
|
44
|
-
cursor: pointer;
|
|
45
|
-
display: grid;
|
|
46
|
-
grid-template-columns: 10px 1fr auto auto;
|
|
47
|
-
align-items: center;
|
|
48
|
-
gap: 8px;
|
|
49
|
-
color: var(--ink-mid);
|
|
50
|
-
font-family: var(--body);
|
|
51
|
-
font-size: 13px;
|
|
52
|
-
transition: background .12s ease, color .12s ease;
|
|
53
|
-
}
|
|
54
|
-
.terminal-row:hover { background: var(--bg); color: var(--ink); }
|
|
55
|
-
.terminal-row.is-active {
|
|
56
|
-
background: var(--sidebar-active);
|
|
57
|
-
color: var(--ink);
|
|
58
|
-
}
|
|
59
|
-
.terminal-row-title {
|
|
60
|
-
white-space: nowrap;
|
|
61
|
-
overflow: hidden;
|
|
62
|
-
text-overflow: ellipsis;
|
|
63
|
-
min-width: 0;
|
|
64
|
-
font-weight: 500;
|
|
65
|
-
}
|
|
66
|
-
.terminal-row-meta {
|
|
67
|
-
font-family: var(--mono);
|
|
68
|
-
font-size: 10.5px;
|
|
69
|
-
color: var(--ink-muted);
|
|
70
|
-
font-variant-numeric: tabular-nums;
|
|
71
|
-
}
|
|
72
|
-
.terminal-row-actions { display: inline-flex; }
|
|
73
|
-
.terminal-row .action.tiny.danger {
|
|
74
|
-
padding: 1px 7px;
|
|
75
|
-
font-size: 11px;
|
|
76
|
-
min-width: 0;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/* right pane — full-height xterm host */
|
|
80
|
-
.terminals-main {
|
|
81
|
-
background: var(--bg);
|
|
82
|
-
border: 1px solid var(--border);
|
|
83
|
-
border-radius: var(--r-md);
|
|
84
|
-
padding: var(--s-3);
|
|
85
|
-
overflow: hidden;
|
|
86
|
-
min-width: 0;
|
|
87
|
-
display: flex;
|
|
88
|
-
flex-direction: column;
|
|
89
|
-
}
|
|
90
|
-
.terminal-host {
|
|
91
|
-
flex: 1;
|
|
92
|
-
min-height: 0;
|
|
93
|
-
width: 100%;
|
|
94
|
-
/* IME composition (Chinese/Japanese pinyin) lives in absolutely-positioned
|
|
95
|
-
.xterm-helper-textarea + .composition-view that grow with the composed
|
|
96
|
-
string. Near the right edge they overflow the viewport and trigger a
|
|
97
|
-
horizontal scrollbar that visually "pushes" the layout. Clip here so
|
|
98
|
-
the overflow is silently absorbed instead of expanding the page.
|
|
99
|
-
Do NOT touch the textarea/composition-view's own text properties —
|
|
100
|
-
xterm relies on their single-line behaviour to keep IME events firing
|
|
101
|
-
correctly (forcing pre-wrap / break-all eats compositionupdate events
|
|
102
|
-
in Chromium and Chinese input stops working entirely). */
|
|
103
|
-
overflow: hidden;
|
|
104
|
-
contain: layout;
|
|
105
|
-
}
|
|
106
|
-
/* While the user is composing (IME), pin the helper textarea to the right
|
|
107
|
-
edge of the terminal so it grows leftward instead of pushing the layout
|
|
108
|
-
rightward. Only touches positioning — NOT width / wrap / max-width, which
|
|
109
|
-
would break Chromium's compositionupdate event flow and stop Chinese
|
|
110
|
-
input from working. The class is toggled by TerminalView.js. */
|
|
111
|
-
.terminal-host.is-composing .xterm-helper-textarea {
|
|
112
|
-
left: auto !important;
|
|
113
|
-
right: 0 !important;
|
|
114
|
-
text-align: right;
|
|
115
|
-
/* xterm un-hides the textarea during composition so the user can see the
|
|
116
|
-
composed string inline. We've moved it to the right edge to stop it
|
|
117
|
-
pushing layout — but that means the composed pinyin would now visibly
|
|
118
|
-
appear on the right. Hide its glyphs (caret + text) so the user only
|
|
119
|
-
sees the OS-native IME candidate popup, which floats independently
|
|
120
|
-
and is unaffected. */
|
|
121
|
-
color: transparent !important;
|
|
122
|
-
caret-color: transparent !important;
|
|
123
|
-
background: transparent !important;
|
|
124
|
-
text-shadow: none !important;
|
|
125
|
-
}
|
|
126
|
-
/* xterm also overlays a .composition-view (a small box at the cursor with
|
|
127
|
-
the in-progress string + a gold caret using THEME.cursor). We can't
|
|
128
|
-
display:none it — Chromium needs it in the layout tree to keep the IME
|
|
129
|
-
compositionupdate events flowing — but we can make it visually invisible
|
|
130
|
-
while leaving it laid out. */
|
|
131
|
-
.terminal-host .composition-view {
|
|
132
|
-
opacity: 0 !important;
|
|
133
|
-
color: transparent !important;
|
|
134
|
-
background: transparent !important;
|
|
135
|
-
border-color: transparent !important;
|
|
136
|
-
box-shadow: none !important;
|
|
137
|
-
pointer-events: none;
|
|
138
|
-
}
|
|
139
|
-
/* Don't override xterm's background — its renderer (canvas/WebGL) assumes
|
|
140
|
-
an opaque surface and ghosts on scroll if we force transparent. The
|
|
141
|
-
theme object in TerminalView.js already paints #faf9f5 to match the
|
|
142
|
-
surrounding card. */
|
|
143
|
-
.terminal-host .xterm-viewport {
|
|
144
|
-
scrollbar-width: thin;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.terminal-empty {
|
|
148
|
-
height: 100%;
|
|
149
|
-
display: flex;
|
|
150
|
-
align-items: center;
|
|
151
|
-
justify-content: center;
|
|
152
|
-
font-size: 13px;
|
|
153
|
-
color: var(--ink-muted);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.terminal-empty-page { width: 100%; }
|
|
157
|
-
|
|
158
|
-
/* === v1.0 session pane === */
|
|
159
|
-
|
|
160
|
-
.sessions-empty {
|
|
161
|
-
display: flex;
|
|
162
|
-
align-items: center;
|
|
163
|
-
justify-content: center;
|
|
164
|
-
min-height: 60vh;
|
|
165
|
-
/* Decorative faint hairline grid, only in this empty state — adds
|
|
166
|
-
editorial atmosphere without affecting any real content view. */
|
|
167
|
-
background-image:
|
|
168
|
-
linear-gradient(to right, rgba(216, 212, 198, 0.5) 1px, transparent 1px),
|
|
169
|
-
linear-gradient(to bottom, rgba(216, 212, 198, 0.5) 1px, transparent 1px);
|
|
170
|
-
background-size: 56px 56px;
|
|
171
|
-
background-position: center;
|
|
172
|
-
position: relative;
|
|
173
|
-
}
|
|
174
|
-
.sessions-empty::before,
|
|
175
|
-
.sessions-empty::after {
|
|
176
|
-
content: "";
|
|
177
|
-
position: absolute;
|
|
178
|
-
inset: 0;
|
|
179
|
-
pointer-events: none;
|
|
180
|
-
}
|
|
181
|
-
.sessions-empty::before {
|
|
182
|
-
background: radial-gradient(ellipse at center, transparent 0%, var(--bg) 75%);
|
|
183
|
-
}
|
|
184
|
-
.sessions-empty-card {
|
|
185
|
-
text-align: center;
|
|
186
|
-
padding: var(--s-12) var(--s-10);
|
|
187
|
-
background: var(--bg-elev);
|
|
188
|
-
border: 1px solid var(--border-soft);
|
|
189
|
-
border-radius: 6px;
|
|
190
|
-
max-width: 440px;
|
|
191
|
-
position: relative;
|
|
192
|
-
z-index: 1;
|
|
193
|
-
box-shadow: var(--shadow-lg);
|
|
194
|
-
}
|
|
195
|
-
.sessions-empty-card::before {
|
|
196
|
-
content: "· EMPTY ·";
|
|
197
|
-
display: block;
|
|
198
|
-
font-family: var(--mono);
|
|
199
|
-
font-size: 10px;
|
|
200
|
-
letter-spacing: 0.28em;
|
|
201
|
-
color: var(--ink-faint);
|
|
202
|
-
margin-bottom: var(--s-4);
|
|
203
|
-
}
|
|
204
|
-
.sessions-empty-card h2 {
|
|
205
|
-
margin: 0 0 var(--s-3);
|
|
206
|
-
font-size: 20px;
|
|
207
|
-
font-weight: 600;
|
|
208
|
-
letter-spacing: -0.015em;
|
|
209
|
-
line-height: 1.2;
|
|
210
|
-
color: var(--ink);
|
|
211
|
-
}
|
|
212
|
-
.sessions-empty-card p {
|
|
213
|
-
margin: 0 0 var(--s-5);
|
|
214
|
-
color: var(--ink-mid);
|
|
215
|
-
font-size: 13.5px;
|
|
216
|
-
line-height: 1.55;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.session-pane {
|
|
220
|
-
display: flex;
|
|
221
|
-
flex-direction: column;
|
|
222
|
-
/* Fill the entire content area edge-to-edge — negative horizontal margin
|
|
223
|
-
cancels .main's horizontal padding so the terminal touches the window
|
|
224
|
-
edges (and the sidebar border) with no surrounding chrome. */
|
|
225
|
-
flex: 1;
|
|
226
|
-
min-height: 0;
|
|
227
|
-
height: 100%;
|
|
228
|
-
margin: 0 calc(-1 * var(--s-4));
|
|
229
|
-
/* Cancel the tab-panel gap above so the terminal sits flush under the
|
|
230
|
-
title bar with no white band. */
|
|
231
|
-
margin-top: calc(-1 * var(--s-4));
|
|
232
|
-
background: var(--bg-elev);
|
|
233
|
-
overflow: hidden;
|
|
234
|
-
}
|
|
235
|
-
.session-pane-head {
|
|
236
|
-
display: flex;
|
|
237
|
-
align-items: center;
|
|
238
|
-
gap: var(--s-3);
|
|
239
|
-
padding: var(--s-3) var(--s-4);
|
|
240
|
-
border-bottom: 1px solid var(--border);
|
|
241
|
-
background: var(--bg);
|
|
242
|
-
flex-wrap: wrap;
|
|
243
|
-
}
|
|
244
|
-
.session-pane-title {
|
|
245
|
-
display: flex;
|
|
246
|
-
align-items: center;
|
|
247
|
-
gap: var(--s-2);
|
|
248
|
-
}
|
|
249
|
-
.session-pane-title h2 {
|
|
250
|
-
margin: 0;
|
|
251
|
-
font-size: 14.5px;
|
|
252
|
-
font-weight: 600;
|
|
253
|
-
}
|
|
254
|
-
.session-pane-meta {
|
|
255
|
-
display: flex;
|
|
256
|
-
gap: var(--s-3);
|
|
257
|
-
align-items: center;
|
|
258
|
-
font-size: 11.5px;
|
|
259
|
-
flex: 1;
|
|
260
|
-
overflow: hidden;
|
|
261
|
-
}
|
|
262
|
-
.session-pane-meta .mono {
|
|
263
|
-
font-family: var(--mono);
|
|
264
|
-
color: var(--ink-mid);
|
|
265
|
-
white-space: nowrap;
|
|
266
|
-
overflow: hidden;
|
|
267
|
-
text-overflow: ellipsis;
|
|
268
|
-
max-width: 50%;
|
|
269
|
-
}
|
|
270
|
-
.session-pane-meta .muted {
|
|
271
|
-
color: var(--ink-muted);
|
|
272
|
-
}
|
|
273
|
-
.session-pane-actions {
|
|
274
|
-
display: flex;
|
|
275
|
-
gap: var(--s-2);
|
|
276
|
-
flex-shrink: 0;
|
|
277
|
-
}
|
|
278
|
-
.session-pane-body {
|
|
279
|
-
flex: 1;
|
|
280
|
-
min-height: 0;
|
|
281
|
-
background: #1a1815;
|
|
282
|
-
}
|
|
283
|
-
.session-pane-body .terminal-host {
|
|
284
|
-
height: 100%;
|
|
285
|
-
}
|
|
286
|
-
.session-pane-body .terminal-empty {
|
|
287
|
-
background: var(--bg);
|
|
288
|
-
display: flex;
|
|
289
|
-
flex-direction: column;
|
|
290
|
-
align-items: center;
|
|
291
|
-
justify-content: center;
|
|
292
|
-
gap: var(--s-3);
|
|
293
|
-
height: 100%;
|
|
294
|
-
}
|
|
1
|
+
/* Terminals tab · left rail (active sessions) + right pane (xterm host) */
|
|
2
|
+
|
|
3
|
+
.terminals-layout {
|
|
4
|
+
display: grid;
|
|
5
|
+
grid-template-columns: 240px 1fr;
|
|
6
|
+
gap: var(--s-4);
|
|
7
|
+
/* viewport minus page header + footer + padding; lets xterm fill height */
|
|
8
|
+
height: calc(100vh - 220px);
|
|
9
|
+
min-height: 480px;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.terminals-rail {
|
|
13
|
+
background: var(--bg-elev);
|
|
14
|
+
border: 1px solid var(--border);
|
|
15
|
+
border-radius: var(--r-md);
|
|
16
|
+
padding: var(--s-2);
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
gap: 2px;
|
|
20
|
+
overflow-y: auto;
|
|
21
|
+
}
|
|
22
|
+
.terminals-rail-head {
|
|
23
|
+
display: flex;
|
|
24
|
+
justify-content: space-between;
|
|
25
|
+
align-items: center;
|
|
26
|
+
padding: var(--s-2) var(--s-3);
|
|
27
|
+
font-size: 11px;
|
|
28
|
+
text-transform: uppercase;
|
|
29
|
+
letter-spacing: 0.06em;
|
|
30
|
+
color: var(--ink-muted);
|
|
31
|
+
border-bottom: 1px solid var(--border-soft);
|
|
32
|
+
margin-bottom: var(--s-2);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* button row showing one terminal in the rail */
|
|
36
|
+
.terminal-row {
|
|
37
|
+
appearance: none;
|
|
38
|
+
background: transparent;
|
|
39
|
+
border: 0;
|
|
40
|
+
width: 100%;
|
|
41
|
+
text-align: left;
|
|
42
|
+
padding: 8px 10px;
|
|
43
|
+
border-radius: var(--r-sm);
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
display: grid;
|
|
46
|
+
grid-template-columns: 10px 1fr auto auto;
|
|
47
|
+
align-items: center;
|
|
48
|
+
gap: 8px;
|
|
49
|
+
color: var(--ink-mid);
|
|
50
|
+
font-family: var(--body);
|
|
51
|
+
font-size: 13px;
|
|
52
|
+
transition: background .12s ease, color .12s ease;
|
|
53
|
+
}
|
|
54
|
+
.terminal-row:hover { background: var(--bg); color: var(--ink); }
|
|
55
|
+
.terminal-row.is-active {
|
|
56
|
+
background: var(--sidebar-active);
|
|
57
|
+
color: var(--ink);
|
|
58
|
+
}
|
|
59
|
+
.terminal-row-title {
|
|
60
|
+
white-space: nowrap;
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
text-overflow: ellipsis;
|
|
63
|
+
min-width: 0;
|
|
64
|
+
font-weight: 500;
|
|
65
|
+
}
|
|
66
|
+
.terminal-row-meta {
|
|
67
|
+
font-family: var(--mono);
|
|
68
|
+
font-size: 10.5px;
|
|
69
|
+
color: var(--ink-muted);
|
|
70
|
+
font-variant-numeric: tabular-nums;
|
|
71
|
+
}
|
|
72
|
+
.terminal-row-actions { display: inline-flex; }
|
|
73
|
+
.terminal-row .action.tiny.danger {
|
|
74
|
+
padding: 1px 7px;
|
|
75
|
+
font-size: 11px;
|
|
76
|
+
min-width: 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* right pane — full-height xterm host */
|
|
80
|
+
.terminals-main {
|
|
81
|
+
background: var(--bg);
|
|
82
|
+
border: 1px solid var(--border);
|
|
83
|
+
border-radius: var(--r-md);
|
|
84
|
+
padding: var(--s-3);
|
|
85
|
+
overflow: hidden;
|
|
86
|
+
min-width: 0;
|
|
87
|
+
display: flex;
|
|
88
|
+
flex-direction: column;
|
|
89
|
+
}
|
|
90
|
+
.terminal-host {
|
|
91
|
+
flex: 1;
|
|
92
|
+
min-height: 0;
|
|
93
|
+
width: 100%;
|
|
94
|
+
/* IME composition (Chinese/Japanese pinyin) lives in absolutely-positioned
|
|
95
|
+
.xterm-helper-textarea + .composition-view that grow with the composed
|
|
96
|
+
string. Near the right edge they overflow the viewport and trigger a
|
|
97
|
+
horizontal scrollbar that visually "pushes" the layout. Clip here so
|
|
98
|
+
the overflow is silently absorbed instead of expanding the page.
|
|
99
|
+
Do NOT touch the textarea/composition-view's own text properties —
|
|
100
|
+
xterm relies on their single-line behaviour to keep IME events firing
|
|
101
|
+
correctly (forcing pre-wrap / break-all eats compositionupdate events
|
|
102
|
+
in Chromium and Chinese input stops working entirely). */
|
|
103
|
+
overflow: hidden;
|
|
104
|
+
contain: layout;
|
|
105
|
+
}
|
|
106
|
+
/* While the user is composing (IME), pin the helper textarea to the right
|
|
107
|
+
edge of the terminal so it grows leftward instead of pushing the layout
|
|
108
|
+
rightward. Only touches positioning — NOT width / wrap / max-width, which
|
|
109
|
+
would break Chromium's compositionupdate event flow and stop Chinese
|
|
110
|
+
input from working. The class is toggled by TerminalView.js. */
|
|
111
|
+
.terminal-host.is-composing .xterm-helper-textarea {
|
|
112
|
+
left: auto !important;
|
|
113
|
+
right: 0 !important;
|
|
114
|
+
text-align: right;
|
|
115
|
+
/* xterm un-hides the textarea during composition so the user can see the
|
|
116
|
+
composed string inline. We've moved it to the right edge to stop it
|
|
117
|
+
pushing layout — but that means the composed pinyin would now visibly
|
|
118
|
+
appear on the right. Hide its glyphs (caret + text) so the user only
|
|
119
|
+
sees the OS-native IME candidate popup, which floats independently
|
|
120
|
+
and is unaffected. */
|
|
121
|
+
color: transparent !important;
|
|
122
|
+
caret-color: transparent !important;
|
|
123
|
+
background: transparent !important;
|
|
124
|
+
text-shadow: none !important;
|
|
125
|
+
}
|
|
126
|
+
/* xterm also overlays a .composition-view (a small box at the cursor with
|
|
127
|
+
the in-progress string + a gold caret using THEME.cursor). We can't
|
|
128
|
+
display:none it — Chromium needs it in the layout tree to keep the IME
|
|
129
|
+
compositionupdate events flowing — but we can make it visually invisible
|
|
130
|
+
while leaving it laid out. */
|
|
131
|
+
.terminal-host .composition-view {
|
|
132
|
+
opacity: 0 !important;
|
|
133
|
+
color: transparent !important;
|
|
134
|
+
background: transparent !important;
|
|
135
|
+
border-color: transparent !important;
|
|
136
|
+
box-shadow: none !important;
|
|
137
|
+
pointer-events: none;
|
|
138
|
+
}
|
|
139
|
+
/* Don't override xterm's background — its renderer (canvas/WebGL) assumes
|
|
140
|
+
an opaque surface and ghosts on scroll if we force transparent. The
|
|
141
|
+
theme object in TerminalView.js already paints #faf9f5 to match the
|
|
142
|
+
surrounding card. */
|
|
143
|
+
.terminal-host .xterm-viewport {
|
|
144
|
+
scrollbar-width: thin;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.terminal-empty {
|
|
148
|
+
height: 100%;
|
|
149
|
+
display: flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
justify-content: center;
|
|
152
|
+
font-size: 13px;
|
|
153
|
+
color: var(--ink-muted);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.terminal-empty-page { width: 100%; }
|
|
157
|
+
|
|
158
|
+
/* === v1.0 session pane === */
|
|
159
|
+
|
|
160
|
+
.sessions-empty {
|
|
161
|
+
display: flex;
|
|
162
|
+
align-items: center;
|
|
163
|
+
justify-content: center;
|
|
164
|
+
min-height: 60vh;
|
|
165
|
+
/* Decorative faint hairline grid, only in this empty state — adds
|
|
166
|
+
editorial atmosphere without affecting any real content view. */
|
|
167
|
+
background-image:
|
|
168
|
+
linear-gradient(to right, rgba(216, 212, 198, 0.5) 1px, transparent 1px),
|
|
169
|
+
linear-gradient(to bottom, rgba(216, 212, 198, 0.5) 1px, transparent 1px);
|
|
170
|
+
background-size: 56px 56px;
|
|
171
|
+
background-position: center;
|
|
172
|
+
position: relative;
|
|
173
|
+
}
|
|
174
|
+
.sessions-empty::before,
|
|
175
|
+
.sessions-empty::after {
|
|
176
|
+
content: "";
|
|
177
|
+
position: absolute;
|
|
178
|
+
inset: 0;
|
|
179
|
+
pointer-events: none;
|
|
180
|
+
}
|
|
181
|
+
.sessions-empty::before {
|
|
182
|
+
background: radial-gradient(ellipse at center, transparent 0%, var(--bg) 75%);
|
|
183
|
+
}
|
|
184
|
+
.sessions-empty-card {
|
|
185
|
+
text-align: center;
|
|
186
|
+
padding: var(--s-12) var(--s-10);
|
|
187
|
+
background: var(--bg-elev);
|
|
188
|
+
border: 1px solid var(--border-soft);
|
|
189
|
+
border-radius: 6px;
|
|
190
|
+
max-width: 440px;
|
|
191
|
+
position: relative;
|
|
192
|
+
z-index: 1;
|
|
193
|
+
box-shadow: var(--shadow-lg);
|
|
194
|
+
}
|
|
195
|
+
.sessions-empty-card::before {
|
|
196
|
+
content: "· EMPTY ·";
|
|
197
|
+
display: block;
|
|
198
|
+
font-family: var(--mono);
|
|
199
|
+
font-size: 10px;
|
|
200
|
+
letter-spacing: 0.28em;
|
|
201
|
+
color: var(--ink-faint);
|
|
202
|
+
margin-bottom: var(--s-4);
|
|
203
|
+
}
|
|
204
|
+
.sessions-empty-card h2 {
|
|
205
|
+
margin: 0 0 var(--s-3);
|
|
206
|
+
font-size: 20px;
|
|
207
|
+
font-weight: 600;
|
|
208
|
+
letter-spacing: -0.015em;
|
|
209
|
+
line-height: 1.2;
|
|
210
|
+
color: var(--ink);
|
|
211
|
+
}
|
|
212
|
+
.sessions-empty-card p {
|
|
213
|
+
margin: 0 0 var(--s-5);
|
|
214
|
+
color: var(--ink-mid);
|
|
215
|
+
font-size: 13.5px;
|
|
216
|
+
line-height: 1.55;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.session-pane {
|
|
220
|
+
display: flex;
|
|
221
|
+
flex-direction: column;
|
|
222
|
+
/* Fill the entire content area edge-to-edge — negative horizontal margin
|
|
223
|
+
cancels .main's horizontal padding so the terminal touches the window
|
|
224
|
+
edges (and the sidebar border) with no surrounding chrome. */
|
|
225
|
+
flex: 1;
|
|
226
|
+
min-height: 0;
|
|
227
|
+
height: 100%;
|
|
228
|
+
margin: 0 calc(-1 * var(--s-4));
|
|
229
|
+
/* Cancel the tab-panel gap above so the terminal sits flush under the
|
|
230
|
+
title bar with no white band. */
|
|
231
|
+
margin-top: calc(-1 * var(--s-4));
|
|
232
|
+
background: var(--bg-elev);
|
|
233
|
+
overflow: hidden;
|
|
234
|
+
}
|
|
235
|
+
.session-pane-head {
|
|
236
|
+
display: flex;
|
|
237
|
+
align-items: center;
|
|
238
|
+
gap: var(--s-3);
|
|
239
|
+
padding: var(--s-3) var(--s-4);
|
|
240
|
+
border-bottom: 1px solid var(--border);
|
|
241
|
+
background: var(--bg);
|
|
242
|
+
flex-wrap: wrap;
|
|
243
|
+
}
|
|
244
|
+
.session-pane-title {
|
|
245
|
+
display: flex;
|
|
246
|
+
align-items: center;
|
|
247
|
+
gap: var(--s-2);
|
|
248
|
+
}
|
|
249
|
+
.session-pane-title h2 {
|
|
250
|
+
margin: 0;
|
|
251
|
+
font-size: 14.5px;
|
|
252
|
+
font-weight: 600;
|
|
253
|
+
}
|
|
254
|
+
.session-pane-meta {
|
|
255
|
+
display: flex;
|
|
256
|
+
gap: var(--s-3);
|
|
257
|
+
align-items: center;
|
|
258
|
+
font-size: 11.5px;
|
|
259
|
+
flex: 1;
|
|
260
|
+
overflow: hidden;
|
|
261
|
+
}
|
|
262
|
+
.session-pane-meta .mono {
|
|
263
|
+
font-family: var(--mono);
|
|
264
|
+
color: var(--ink-mid);
|
|
265
|
+
white-space: nowrap;
|
|
266
|
+
overflow: hidden;
|
|
267
|
+
text-overflow: ellipsis;
|
|
268
|
+
max-width: 50%;
|
|
269
|
+
}
|
|
270
|
+
.session-pane-meta .muted {
|
|
271
|
+
color: var(--ink-muted);
|
|
272
|
+
}
|
|
273
|
+
.session-pane-actions {
|
|
274
|
+
display: flex;
|
|
275
|
+
gap: var(--s-2);
|
|
276
|
+
flex-shrink: 0;
|
|
277
|
+
}
|
|
278
|
+
.session-pane-body {
|
|
279
|
+
flex: 1;
|
|
280
|
+
min-height: 0;
|
|
281
|
+
background: #1a1815;
|
|
282
|
+
}
|
|
283
|
+
.session-pane-body .terminal-host {
|
|
284
|
+
height: 100%;
|
|
285
|
+
}
|
|
286
|
+
.session-pane-body .terminal-empty {
|
|
287
|
+
background: var(--bg);
|
|
288
|
+
display: flex;
|
|
289
|
+
flex-direction: column;
|
|
290
|
+
align-items: center;
|
|
291
|
+
justify-content: center;
|
|
292
|
+
gap: var(--s-3);
|
|
293
|
+
height: 100%;
|
|
294
|
+
}
|