clay-server 2.47.0-beta.5 → 3.0.0-beta.1

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 (58) hide show
  1. package/lib/daemon.js +6 -27
  2. package/lib/project-connection.js +21 -8
  3. package/lib/project-http.js +5 -2
  4. package/lib/project-session-pair.js +312 -0
  5. package/lib/project-session-spawn.js +8 -4
  6. package/lib/project-sessions.js +108 -10
  7. package/lib/project-user-message.js +18 -8
  8. package/lib/project.js +33 -0
  9. package/lib/public/app.js +24 -1
  10. package/lib/public/css/icon-strip.css +0 -190
  11. package/lib/public/css/menus.css +83 -1
  12. package/lib/public/css/messages.css +14 -0
  13. package/lib/public/css/mobile-nav.css +4 -0
  14. package/lib/public/css/pane.css +420 -0
  15. package/lib/public/css/sidebar.css +40 -0
  16. package/lib/public/css/sticky-notes.css +2 -0
  17. package/lib/public/css/title-bar.css +169 -0
  18. package/lib/public/index.html +10 -0
  19. package/lib/public/modules/app-connection.js +6 -0
  20. package/lib/public/modules/app-favicon.js +6 -10
  21. package/lib/public/modules/app-header.js +101 -6
  22. package/lib/public/modules/app-home-hub.js +2 -0
  23. package/lib/public/modules/app-messages.js +63 -13
  24. package/lib/public/modules/app-panels.js +49 -27
  25. package/lib/public/modules/app-projects.js +43 -30
  26. package/lib/public/modules/app-rendering.js +11 -4
  27. package/lib/public/modules/branch-switcher.js +178 -0
  28. package/lib/public/modules/dom-refs.js +0 -1
  29. package/lib/public/modules/pane-bridge.js +41 -0
  30. package/lib/public/modules/pane-session.js +18 -0
  31. package/lib/public/modules/project-switcher.js +2 -1
  32. package/lib/public/modules/sidebar-mobile.js +19 -6
  33. package/lib/public/modules/sidebar-projects.js +63 -236
  34. package/lib/public/modules/sidebar-sessions.js +175 -1
  35. package/lib/public/modules/sidebar.js +2 -0
  36. package/lib/public/modules/split-group-helpers.js +18 -0
  37. package/lib/public/modules/split-pair-ui.js +324 -0
  38. package/lib/public/modules/split-view.js +499 -0
  39. package/lib/public/modules/sticky-notes.js +32 -91
  40. package/lib/public/modules/worktree-family.js +60 -0
  41. package/lib/public/style.css +1 -0
  42. package/lib/sdk-bridge.js +111 -20
  43. package/lib/sdk-message-processor.js +2 -2
  44. package/lib/server.js +24 -4
  45. package/lib/session-hygiene.js +100 -0
  46. package/lib/session-pair-mcp-server.js +28 -0
  47. package/lib/session-split-groups.js +298 -0
  48. package/lib/sessions.js +163 -34
  49. package/lib/ws-request.js +14 -0
  50. package/lib/ws-schema.js +13 -0
  51. package/lib/yoke/adapters/claude.js +32 -0
  52. package/lib/yoke/adapters/codex.js +100 -77
  53. package/lib/yoke/adapters/kiro.js +34 -35
  54. package/lib/yoke/codex-app-server.js +56 -6
  55. package/lib/yoke/index.js +1 -0
  56. package/lib/yoke/skill-discovery.js +196 -0
  57. package/lib/yoke/vendor-registry.js +34 -0
  58. package/package.json +1 -1
@@ -43,6 +43,27 @@
43
43
  #header-rename-btn:hover { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.04); border-color: var(--border); }
44
44
  #header-rename-btn .lucide { width: 13px; height: 13px; }
45
45
 
46
+ #header-add-worker-btn {
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ width: 24px;
51
+ height: 24px;
52
+ border: 1px solid transparent;
53
+ background: none;
54
+ color: var(--text-dimmer);
55
+ cursor: pointer;
56
+ border-radius: 8px;
57
+ flex-shrink: 0;
58
+ padding: 0;
59
+ margin-left: 4px;
60
+ transition: color 0.15s, background 0.15s, border-color 0.15s;
61
+ }
62
+ #header-add-worker-btn:hover { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.04); border-color: var(--border); }
63
+ #header-add-worker-btn .lucide { width: 13px; height: 13px; }
64
+ #header-add-worker-btn.hidden { display: none; }
65
+ body.dm-mode #header-add-worker-btn { display: none; }
66
+
46
67
  /* "Close terminal" button: sits just left of the rename pencil during a live
47
68
  TUI session. Matches the rename button's chrome; reds out on hover since it
48
69
  stops the running claude (the session stays resumable). */
@@ -96,6 +117,52 @@
96
117
  stroke-width: 2.5;
97
118
  }
98
119
 
120
+ .session-full-access {
121
+ display: inline-flex;
122
+ align-items: center;
123
+ gap: 6px;
124
+ height: 22px;
125
+ margin-left: 7px;
126
+ padding: 0 6px 0 8px;
127
+ border: 1px solid var(--border);
128
+ border-radius: 999px;
129
+ background: rgba(var(--overlay-rgb), 0.025);
130
+ color: var(--text-dimmer);
131
+ font: inherit;
132
+ font-size: 10px;
133
+ font-weight: 650;
134
+ cursor: pointer;
135
+ flex-shrink: 0;
136
+ transition: color 0.15s, border-color 0.15s, background 0.15s;
137
+ }
138
+ .session-full-access:hover { color: var(--text-secondary); background: rgba(var(--overlay-rgb), 0.05); }
139
+ .session-full-access.hidden { display: none; }
140
+ .session-full-access.active {
141
+ color: var(--error);
142
+ border-color: color-mix(in srgb, var(--error) 38%, var(--border));
143
+ background: color-mix(in srgb, var(--error) 8%, transparent);
144
+ }
145
+ .session-full-access-track {
146
+ position: relative;
147
+ width: 22px;
148
+ height: 12px;
149
+ border-radius: 999px;
150
+ background: var(--border);
151
+ transition: background 0.15s;
152
+ }
153
+ .session-full-access-track > span {
154
+ position: absolute;
155
+ top: 2px;
156
+ left: 2px;
157
+ width: 8px;
158
+ height: 8px;
159
+ border-radius: 50%;
160
+ background: var(--text-dimmer);
161
+ transition: transform 0.15s, background 0.15s;
162
+ }
163
+ .session-full-access.active .session-full-access-track { background: var(--error); }
164
+ .session-full-access.active .session-full-access-track > span { background: var(--bg); transform: translateX(10px); }
165
+
99
166
  /* Session info popover */
100
167
  .session-info-popover {
101
168
  position: fixed;
@@ -110,6 +177,19 @@
110
177
  color: var(--text-secondary);
111
178
  line-height: 1.6;
112
179
  }
180
+ .session-info-popover .info-section-title {
181
+ font-weight: 700;
182
+ color: var(--text);
183
+ overflow: hidden;
184
+ text-overflow: ellipsis;
185
+ white-space: nowrap;
186
+ max-width: 320px;
187
+ }
188
+ .session-info-popover .info-section-title:not(:first-child) {
189
+ margin-top: 8px;
190
+ padding-top: 8px;
191
+ border-top: 1px solid var(--border-subtle);
192
+ }
113
193
  .session-info-popover .info-row {
114
194
  display: flex;
115
195
  align-items: center;
@@ -858,6 +938,9 @@
858
938
  }
859
939
  #context-mini:hover { opacity: 0.8; }
860
940
  #context-mini.hidden { display: none; }
941
+ /* Split view: per-pane chips replace the shell-level context gauge. */
942
+ #context-mini.split-hidden { display: none; }
943
+ .header-context.hidden { display: none; }
861
944
  .context-mini-bar {
862
945
  flex: 1;
863
946
  height: 4px;
@@ -898,4 +981,3 @@
898
981
  #config-chip-label { display: none; }
899
982
  }
900
983
 
901
-
@@ -165,6 +165,20 @@
165
165
  display: flex;
166
166
  }
167
167
 
168
+ .msg-user-delegated .bubble {
169
+ background: color-mix(in srgb, var(--accent) 11%, var(--bg-elevated, var(--bg-hover)));
170
+ border: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
171
+ }
172
+
173
+ .msg-user-delegated .dm-bubble-avatar-other {
174
+ border-radius: 7px;
175
+ }
176
+
177
+ .msg-user-delegated .dm-bubble-name {
178
+ color: var(--accent);
179
+ font-weight: 650;
180
+ }
181
+
168
182
  /* --- User message action bar --- */
169
183
  .msg-actions {
170
184
  display: flex;
@@ -160,6 +160,10 @@
160
160
  background: rgba(var(--overlay-rgb), 0.06);
161
161
  }
162
162
 
163
+ .mobile-project-item.has-pending-perm {
164
+ animation: permShake 2s ease-in-out infinite;
165
+ }
166
+
163
167
  .mobile-project-abbrev {
164
168
  width: 32px;
165
169
  height: 32px;
@@ -0,0 +1,420 @@
1
+ /* Pane-mode app instances and the parent split shell. */
2
+
3
+ body.pane-mode #top-bar,
4
+ body.pane-mode #icon-strip,
5
+ body.pane-mode #sidebar-column,
6
+ body.pane-mode #mate-sidebar-column,
7
+ body.pane-mode #sidebar-resize-handle,
8
+ body.pane-mode #mate-sidebar-resize-handle,
9
+ body.pane-mode #sidebar-overlay,
10
+ body.pane-mode #home-hub,
11
+ body.pane-mode #whats-new-article,
12
+ body.pane-mode .title-bar-content,
13
+ body.pane-mode .dm-header-bar,
14
+ body.pane-mode #mobile-tab-bar,
15
+ body.pane-mode #mobile-sheet,
16
+ body.pane-mode #user-island {
17
+ display: none !important;
18
+ }
19
+
20
+ /* Sticky notes are project-wide. The parent split shell renders one shared
21
+ canvas across the full group instead of duplicating it in each iframe. */
22
+ body.pane-mode #sticky-notes-container {
23
+ display: none !important;
24
+ }
25
+
26
+ body.pane-mode #main-area {
27
+ border: 0;
28
+ border-radius: 0;
29
+ }
30
+
31
+ body.pane-mode #main-column,
32
+ body.pane-mode #main-panels,
33
+ body.pane-mode #app {
34
+ width: 100%;
35
+ height: 100%;
36
+ }
37
+
38
+ /* Narrow panes cross the mobile breakpoint, but pane mode hides the mobile
39
+ tab bar. Keep the normal composer inset instead of reserving its 56px. */
40
+ body.pane-mode #input-area {
41
+ padding-bottom: calc(var(--safe-bottom) + 8px);
42
+ }
43
+
44
+ #main-panels {
45
+ position: relative;
46
+ }
47
+
48
+ #app.split-native-hidden {
49
+ display: none !important;
50
+ }
51
+
52
+ #split-host {
53
+ display: none;
54
+ flex: 1;
55
+ min-width: 0;
56
+ min-height: 0;
57
+ background: var(--bg);
58
+ }
59
+
60
+ #split-host.visible {
61
+ display: flex;
62
+ }
63
+
64
+ .split-pane {
65
+ flex: 1;
66
+ display: flex;
67
+ flex-direction: column;
68
+ min-width: 0;
69
+ min-height: 0;
70
+ border-left: 1px solid var(--border-subtle);
71
+ background: var(--bg);
72
+ }
73
+
74
+ .split-pane:first-child {
75
+ border-left: 0;
76
+ }
77
+
78
+ .split-pane-header {
79
+ height: 24px;
80
+ display: flex;
81
+ align-items: center;
82
+ gap: 6px;
83
+ padding: 0 5px 0 9px;
84
+ border-bottom: 1px solid var(--border-subtle);
85
+ background: var(--sidebar-bg);
86
+ color: var(--text-secondary);
87
+ flex-shrink: 0;
88
+ }
89
+
90
+ .split-pane-vendor {
91
+ width: 14px;
92
+ height: 14px;
93
+ border-radius: 4px;
94
+ flex-shrink: 0;
95
+ }
96
+
97
+ .split-pane-title {
98
+ flex: 1;
99
+ min-width: 0;
100
+ overflow: hidden;
101
+ text-overflow: ellipsis;
102
+ white-space: nowrap;
103
+ font-size: 11px;
104
+ font-weight: 600;
105
+ cursor: text;
106
+ border-radius: 4px;
107
+ padding: 1px 4px;
108
+ margin-left: -4px;
109
+ }
110
+
111
+ .split-pane-title:hover {
112
+ background: var(--bg-alt);
113
+ }
114
+
115
+ .split-pair-role,
116
+ .split-pair-live {
117
+ flex-shrink: 0;
118
+ border-radius: 999px;
119
+ padding: 1px 6px;
120
+ font-size: 8px;
121
+ font-weight: 700;
122
+ letter-spacing: 0.05em;
123
+ text-transform: uppercase;
124
+ }
125
+
126
+ .split-pair-role-driver { color: var(--accent); background: color-mix(in srgb, var(--accent) 13%, transparent); }
127
+ .split-pair-role-worker { color: var(--text-secondary); background: var(--bg-alt); }
128
+
129
+ /* Role badges are buttons: Driver click clears roles, Worker click takes over. */
130
+ button.split-pair-role {
131
+ border: 0;
132
+ cursor: pointer;
133
+ font-family: inherit;
134
+ }
135
+ button.split-pair-role:hover { filter: brightness(1.25); }
136
+
137
+ /* Ad-hoc splits: role assignment in each pane header. ALWAYS fully
138
+ visible; hover/opacity gating made the control undiscoverable. */
139
+ .split-pair-set-driver {
140
+ flex-shrink: 0;
141
+ display: inline-flex;
142
+ align-items: center;
143
+ border: 1px solid var(--border);
144
+ border-radius: 999px;
145
+ padding: 2px 9px;
146
+ font-size: 9px;
147
+ font-weight: 700;
148
+ letter-spacing: 0.05em;
149
+ text-transform: uppercase;
150
+ background: var(--bg-alt);
151
+ color: var(--text-secondary);
152
+ cursor: pointer;
153
+ transition: color 0.12s, border-color 0.12s, background 0.12s;
154
+ font-family: inherit;
155
+ }
156
+ .split-pair-set-driver:hover {
157
+ color: var(--accent);
158
+ border-color: var(--accent);
159
+ background: color-mix(in srgb, var(--accent) 10%, var(--bg));
160
+ }
161
+ .split-pair-live { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); animation: pair-status-pulse 1.5s ease-in-out infinite; }
162
+
163
+ #split-host.split-delegating::after {
164
+ content: "→";
165
+ position: absolute;
166
+ z-index: 4;
167
+ top: calc(50% - 10px);
168
+ left: calc(50% - 17px);
169
+ width: 34px;
170
+ height: 20px;
171
+ display: grid;
172
+ place-items: center;
173
+ border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
174
+ border-radius: 999px;
175
+ pointer-events: none;
176
+ background: var(--sidebar-bg);
177
+ color: var(--accent);
178
+ font-size: 14px;
179
+ font-weight: 800;
180
+ animation: pair-divider-flow 1.1s ease-in-out infinite;
181
+ filter: drop-shadow(0 0 4px color-mix(in srgb, var(--accent) 65%, transparent));
182
+ }
183
+
184
+ #split-host.split-direction-left::after { content: "←"; animation-name: pair-divider-flow-left; }
185
+
186
+ @keyframes pair-divider-flow { 0%, 100% { transform: translateX(-3px); opacity: 0.65; } 50% { transform: translateX(3px); opacity: 1; } }
187
+ @keyframes pair-divider-flow-left { 0%, 100% { transform: translateX(3px); opacity: 0.65; } 50% { transform: translateX(-3px); opacity: 1; } }
188
+ @keyframes pair-status-pulse { 50% { opacity: 0.55; } }
189
+
190
+ /* Pair dialog rides the standard wt-modal pattern; these classes only add
191
+ the two-column role layout on top of it. */
192
+ .pair-modal { min-width: 480px; max-width: 560px; }
193
+ .pair-modal-desc { font-size: 12px; color: var(--text-dimmer); margin: -10px 0 14px; }
194
+ .pair-modal-roles { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
195
+ .pair-modal-role { min-width: 0; }
196
+ .pair-modal-role-heading { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }
197
+ .pair-modal-role-heading div { display: grid; gap: 1px; }
198
+ .pair-modal-role-heading strong { color: var(--text); font-size: 12px; }
199
+ .pair-modal-role-heading span { color: var(--text-dimmer); font-size: 10px; }
200
+ @media (max-width: 560px) {
201
+ .pair-modal { min-width: 0; width: calc(100vw - 32px); }
202
+ .pair-modal-roles { grid-template-columns: 1fr; }
203
+ }
204
+ .pair-modal-current {
205
+ display: flex;
206
+ align-items: center;
207
+ gap: 8px;
208
+ padding: 8px 10px;
209
+ border: 1px solid var(--border-subtle);
210
+ border-radius: 8px;
211
+ background: var(--bg-alt);
212
+ font-size: 13px;
213
+ font-weight: 600;
214
+ overflow: hidden;
215
+ }
216
+ .pair-modal-current span {
217
+ overflow: hidden;
218
+ text-overflow: ellipsis;
219
+ white-space: nowrap;
220
+ }
221
+ .pair-role-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--text-dimmer); box-shadow: 0 0 0 4px color-mix(in srgb, var(--text-dimmer) 12%, transparent); flex-shrink: 0; }
222
+ .pair-role-driver { background: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 14%, transparent); }
223
+
224
+ .split-pane-rename-input {
225
+ flex: 1;
226
+ min-width: 0;
227
+ border: 1px solid var(--accent);
228
+ border-radius: 4px;
229
+ background: var(--bg);
230
+ color: var(--text);
231
+ font-size: 11px;
232
+ font-weight: 600;
233
+ padding: 1px 4px;
234
+ margin-left: -4px;
235
+ outline: none;
236
+ }
237
+
238
+ .split-pane-context {
239
+ display: none;
240
+ align-items: center;
241
+ gap: 4px;
242
+ border: 0;
243
+ padding: 2px 5px;
244
+ border-radius: 4px;
245
+ background: transparent;
246
+ color: var(--text-dimmer);
247
+ cursor: pointer;
248
+ flex-shrink: 0;
249
+ }
250
+
251
+ .split-pane-context.has-data {
252
+ display: inline-flex;
253
+ }
254
+
255
+ .split-pane-context:hover {
256
+ background: var(--bg-alt);
257
+ color: var(--text);
258
+ }
259
+
260
+ .split-pane-context-bar {
261
+ width: 36px;
262
+ height: 3px;
263
+ border-radius: 2px;
264
+ background: var(--border);
265
+ overflow: hidden;
266
+ }
267
+
268
+ .split-pane-context-fill {
269
+ display: block;
270
+ height: 100%;
271
+ width: 0%;
272
+ border-radius: 2px;
273
+ background: var(--accent);
274
+ transition: width 0.3s ease, background 0.3s ease;
275
+ }
276
+
277
+ .split-pane-context-fill.warn { background: var(--warning); }
278
+ .split-pane-context-fill.danger { background: var(--error); }
279
+
280
+ .split-pane-context-label {
281
+ font-family: "Roboto Mono", monospace;
282
+ font-size: 10px;
283
+ line-height: 1;
284
+ }
285
+
286
+ /* Header-scoped (two-class) selectors: pane.css loads BEFORE menus.css in
287
+ style.css, so the base .session-full-access rules would win a specificity
288
+ tie and keep the pill at its 22px title-bar size inside the 24px pane
289
+ header. Scope under .split-pane-header to outrank them. */
290
+ .split-pane-header .split-pane-full-access {
291
+ height: 15px;
292
+ align-self: center;
293
+ margin-left: 0;
294
+ padding: 0 3px 0 7px;
295
+ gap: 5px;
296
+ font-size: 8px;
297
+ letter-spacing: 0.02em;
298
+ }
299
+
300
+ .split-pane-header .session-full-access-track {
301
+ width: 16px;
302
+ height: 9px;
303
+ }
304
+
305
+ .split-pane-header .session-full-access-track > span {
306
+ top: 1.5px;
307
+ left: 1.5px;
308
+ width: 6px;
309
+ height: 6px;
310
+ }
311
+
312
+ .split-pane-header .split-pane-full-access.active .session-full-access-track > span { transform: translateX(7px); }
313
+
314
+ @media (max-width: 900px) {
315
+ .split-pane-header .session-full-access-label { display: none; }
316
+ .split-pane-header .split-pane-full-access { padding-left: 3px; }
317
+ }
318
+
319
+ .split-pane-close {
320
+ width: 20px;
321
+ height: 20px;
322
+ display: flex;
323
+ align-items: center;
324
+ justify-content: center;
325
+ border: 0;
326
+ border-radius: 4px;
327
+ background: transparent;
328
+ color: var(--text-dimmer);
329
+ cursor: pointer;
330
+ }
331
+
332
+ .split-pane-close:hover {
333
+ background: var(--bg-alt);
334
+ color: var(--text);
335
+ }
336
+
337
+ .split-pane-close svg {
338
+ width: 12px;
339
+ height: 12px;
340
+ }
341
+
342
+ .split-pane-frame {
343
+ flex: 1;
344
+ width: 100%;
345
+ min-height: 0;
346
+ border: 0;
347
+ background: var(--bg);
348
+ }
349
+
350
+ /* Prevent an iframe from taking the pointer midway through a note gesture. */
351
+ body.sticky-note-interacting .split-pane-frame {
352
+ pointer-events: none;
353
+ }
354
+
355
+ /* Arc-style drop preview: while a session is dragged over the app, hovering
356
+ one half folds the live app into the other half and a ghost pane marks
357
+ exactly where the dragged session will land. Drop keeps that layout, so
358
+ the preview and the result match 1:1. */
359
+
360
+ .split-drop-overlay {
361
+ position: absolute;
362
+ inset: 0;
363
+ z-index: 10050;
364
+ display: none;
365
+ background: rgba(var(--overlay-rgb), 0.05);
366
+ pointer-events: none;
367
+ }
368
+
369
+ .split-drop-overlay.visible {
370
+ display: block;
371
+ pointer-events: auto;
372
+ }
373
+
374
+ #main-panels.split-drag-active #app {
375
+ transition: margin 0.18s ease;
376
+ }
377
+
378
+ #main-panels.split-preview-left #app {
379
+ margin-left: 50%;
380
+ }
381
+
382
+ #main-panels.split-preview-right #app {
383
+ margin-right: 50%;
384
+ }
385
+
386
+ .split-drop-ghost {
387
+ position: absolute;
388
+ top: 10px;
389
+ bottom: 10px;
390
+ left: 10px;
391
+ width: calc(50% - 16px);
392
+ display: flex;
393
+ align-items: center;
394
+ justify-content: center;
395
+ border: 2px dashed var(--accent);
396
+ border-radius: 10px;
397
+ background: color-mix(in srgb, var(--accent) 10%, var(--bg));
398
+ color: var(--text);
399
+ opacity: 0;
400
+ pointer-events: none;
401
+ transition: left 0.18s ease, opacity 0.12s ease;
402
+ }
403
+
404
+ #main-panels.split-preview-left .split-drop-ghost {
405
+ opacity: 1;
406
+ }
407
+
408
+ #main-panels.split-preview-right .split-drop-ghost {
409
+ left: calc(50% + 6px);
410
+ opacity: 1;
411
+ }
412
+
413
+ .split-drop-ghost-title {
414
+ max-width: 80%;
415
+ overflow: hidden;
416
+ text-overflow: ellipsis;
417
+ white-space: nowrap;
418
+ font-size: 13px;
419
+ font-weight: 700;
420
+ }
@@ -873,6 +873,46 @@
873
873
  font-weight: 600;
874
874
  }
875
875
 
876
+ .split-group-text {
877
+ display: flex;
878
+ align-items: center;
879
+ }
880
+
881
+ .split-group-glyph {
882
+ width: 14px;
883
+ margin-right: 4px;
884
+ display: inline-flex;
885
+ align-items: center;
886
+ color: var(--text-dimmer);
887
+ flex-shrink: 0;
888
+ }
889
+
890
+ .split-group-glyph svg {
891
+ width: 13px;
892
+ height: 13px;
893
+ }
894
+
895
+ .split-group-vendors {
896
+ display: inline-flex;
897
+ align-items: center;
898
+ margin-right: 6px;
899
+ flex-shrink: 0;
900
+ }
901
+
902
+ .split-group-vendors .session-vendor-icon {
903
+ margin-right: 0;
904
+ }
905
+
906
+ .split-group-vendors .session-vendor-icon + .session-vendor-icon {
907
+ margin-left: -3px;
908
+ }
909
+
910
+ .split-group-name {
911
+ overflow: hidden;
912
+ text-overflow: ellipsis;
913
+ white-space: nowrap;
914
+ }
915
+
876
916
  .session-item.drag-over-above::before,
877
917
  .session-item.drag-over-below::after {
878
918
  content: "";
@@ -122,6 +122,7 @@
122
122
  white-space: nowrap;
123
123
  color: transparent;
124
124
  pointer-events: auto;
125
+ touch-action: none;
125
126
  }
126
127
 
127
128
  .sticky-note-spacer:active { cursor: grabbing; }
@@ -335,6 +336,7 @@
335
336
  cursor: nwse-resize;
336
337
  opacity: 0;
337
338
  transition: opacity 0.15s;
339
+ touch-action: none;
338
340
  }
339
341
 
340
342
  .sticky-note:hover .sticky-note-resize { opacity: 0.3; }