clay-server 3.0.0 → 3.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/lib/mates-prompts.js +3 -2
  2. package/lib/notes.js +6 -0
  3. package/lib/project-http.js +3 -6
  4. package/lib/project-session-notes.js +217 -0
  5. package/lib/project.js +84 -18
  6. package/lib/public/app.js +1 -4
  7. package/lib/public/css/icon-strip.css +190 -0
  8. package/lib/public/css/messages.css +104 -2
  9. package/lib/public/css/mobile-nav.css +0 -4
  10. package/lib/public/css/pane.css +27 -0
  11. package/lib/public/css/rewind.css +10 -0
  12. package/lib/public/css/sticky-notes.css +43 -0
  13. package/lib/public/css/title-bar.css +0 -169
  14. package/lib/public/index.html +0 -6
  15. package/lib/public/modules/app-favicon.js +10 -1
  16. package/lib/public/modules/app-home-hub.js +0 -2
  17. package/lib/public/modules/app-messages.js +18 -6
  18. package/lib/public/modules/app-projects.js +30 -43
  19. package/lib/public/modules/app-rendering.js +42 -3
  20. package/lib/public/modules/dom-refs.js +1 -0
  21. package/lib/public/modules/input.js +13 -0
  22. package/lib/public/modules/project-switcher.js +1 -2
  23. package/lib/public/modules/sidebar-mobile.js +6 -19
  24. package/lib/public/modules/sidebar-projects.js +232 -63
  25. package/lib/public/modules/split-pair-ui.js +30 -0
  26. package/lib/public/modules/sticky-note-markdown.js +89 -0
  27. package/lib/public/modules/sticky-notes.js +56 -103
  28. package/lib/sdk-bridge.js +25 -1
  29. package/lib/session-notes-mcp-server.js +39 -0
  30. package/lib/ws-schema.js +1 -0
  31. package/lib/yoke/adapters/codex.js +44 -8
  32. package/lib/yoke/mcp-bridge-server.js +7 -7
  33. package/package.json +1 -1
  34. package/lib/public/modules/branch-switcher.js +0 -178
  35. package/lib/public/modules/worktree-family.js +0 -60
@@ -223,6 +223,7 @@
223
223
 
224
224
  /* Show dot only on active item or when processing */
225
225
  .icon-strip-item.active .icon-strip-status,
226
+ .icon-strip-wt-item.active .icon-strip-status,
226
227
  .icon-strip-status.processing {
227
228
  opacity: 1;
228
229
  }
@@ -247,6 +248,7 @@
247
248
 
248
249
  /* Pending permission shake */
249
250
  .icon-strip-item.has-pending-perm,
251
+ .icon-strip-wt-item.has-pending-perm,
250
252
  .icon-strip-mate.has-pending-perm {
251
253
  animation: permShake 2s ease-in-out infinite;
252
254
  }
@@ -1144,6 +1146,155 @@
1144
1146
  opacity: 1;
1145
1147
  }
1146
1148
 
1149
+ /* --- Worktree folder groups --- */
1150
+ .icon-strip-group {
1151
+ display: flex;
1152
+ flex-direction: column;
1153
+ align-items: center;
1154
+ position: relative;
1155
+ }
1156
+
1157
+ .icon-strip-group .folder-header {
1158
+ position: relative;
1159
+ }
1160
+
1161
+ .icon-strip-group-chevron {
1162
+ position: absolute;
1163
+ bottom: 2px;
1164
+ right: 2px;
1165
+ width: 16px;
1166
+ height: 16px;
1167
+ border-radius: 50%;
1168
+ background: var(--bg-alt);
1169
+ border: 1px solid var(--border);
1170
+ display: flex;
1171
+ align-items: center;
1172
+ justify-content: center;
1173
+ color: var(--text-dimmer);
1174
+ pointer-events: auto;
1175
+ cursor: pointer;
1176
+ transition: transform 0.15s ease, background 0.15s, border-color 0.15s;
1177
+ z-index: 2;
1178
+ line-height: 1;
1179
+ }
1180
+
1181
+ .icon-strip-group-chevron i,
1182
+ .icon-strip-group-chevron svg {
1183
+ width: 10px;
1184
+ height: 10px;
1185
+ }
1186
+
1187
+ .icon-strip-group-chevron:hover {
1188
+ background: var(--bg-hover, var(--bg-alt));
1189
+ border-color: var(--text-dimmer);
1190
+ color: var(--text-secondary);
1191
+ }
1192
+
1193
+ .icon-strip-group.collapsed .icon-strip-group-chevron {
1194
+ background: var(--border);
1195
+ }
1196
+
1197
+ .icon-strip-group-items {
1198
+ display: flex;
1199
+ flex-direction: column;
1200
+ align-items: center;
1201
+ overflow: hidden;
1202
+ transition: max-height 0.2s ease;
1203
+ max-height: 500px;
1204
+ border-left: 2px solid var(--border);
1205
+ margin-left: 0;
1206
+ padding-left: 0;
1207
+ }
1208
+
1209
+ .icon-strip-group.collapsed .icon-strip-group-items {
1210
+ max-height: 0;
1211
+ }
1212
+
1213
+ /* Worktree items (smaller than regular project icons) */
1214
+ .icon-strip-wt-item {
1215
+ width: 48px;
1216
+ height: 40px;
1217
+ display: flex;
1218
+ align-items: center;
1219
+ justify-content: center;
1220
+ cursor: pointer;
1221
+ position: relative;
1222
+ text-decoration: none;
1223
+ color: var(--text-secondary);
1224
+ transition: background 0.15s;
1225
+ }
1226
+
1227
+ .icon-strip-wt-item::before {
1228
+ content: "";
1229
+ position: absolute;
1230
+ width: 30px;
1231
+ height: 30px;
1232
+ border-radius: 8px;
1233
+ background: var(--bg-alt);
1234
+ opacity: 0.7;
1235
+ transition: opacity 0.15s, background 0.15s;
1236
+ }
1237
+
1238
+ .icon-strip-wt-item:hover::before {
1239
+ opacity: 1;
1240
+ }
1241
+
1242
+ .icon-strip-wt-item.active::before {
1243
+ background: var(--accent);
1244
+ opacity: 1;
1245
+ }
1246
+
1247
+ .icon-strip-wt-item.active {
1248
+ color: #fff;
1249
+ }
1250
+
1251
+ .icon-strip-wt-item .wt-branch-abbrev {
1252
+ font-size: 11px;
1253
+ font-weight: 600;
1254
+ letter-spacing: -0.5px;
1255
+ pointer-events: none;
1256
+ position: relative;
1257
+ z-index: 1;
1258
+ }
1259
+
1260
+ /* Disabled/inaccessible worktree */
1261
+ .icon-strip-wt-item.wt-disabled {
1262
+ opacity: 0.35;
1263
+ cursor: not-allowed;
1264
+ }
1265
+
1266
+ .icon-strip-wt-item.wt-disabled::after {
1267
+ content: "\1F6AB";
1268
+ position: absolute;
1269
+ font-size: 14px;
1270
+ z-index: 3;
1271
+ filter: grayscale(0.3);
1272
+ }
1273
+
1274
+ /* Group add button */
1275
+ .icon-strip-group-add {
1276
+ width: 30px;
1277
+ height: 30px;
1278
+ border-radius: 8px;
1279
+ border: 1.5px dashed var(--border);
1280
+ background: transparent;
1281
+ color: var(--text-dimmer);
1282
+ font-size: 16px;
1283
+ font-weight: 400;
1284
+ cursor: pointer;
1285
+ display: flex;
1286
+ align-items: center;
1287
+ justify-content: center;
1288
+ margin: 2px 0 4px 0;
1289
+ transition: border-color 0.15s, color 0.15s, background 0.15s;
1290
+ }
1291
+
1292
+ .icon-strip-group-add:hover {
1293
+ border-color: var(--accent);
1294
+ color: var(--accent);
1295
+ background: rgba(var(--accent-rgb, 124, 58, 237), 0.08);
1296
+ }
1297
+
1147
1298
  /* --- Worktree creation modal --- */
1148
1299
  .wt-modal-overlay {
1149
1300
  position: fixed;
@@ -1258,6 +1409,45 @@ select.wt-modal-input {
1258
1409
  cursor: not-allowed;
1259
1410
  }
1260
1411
 
1412
+ /* --- Mobile worktree folder --- */
1413
+ .mobile-project-folder {
1414
+ display: flex;
1415
+ flex-direction: column;
1416
+ }
1417
+
1418
+ .mobile-project-item.wt-item {
1419
+ padding-left: 28px;
1420
+ opacity: 0.85;
1421
+ }
1422
+
1423
+ .mobile-project-item.wt-disabled {
1424
+ opacity: 0.35;
1425
+ cursor: not-allowed;
1426
+ }
1427
+
1428
+ .mobile-folder-chevron {
1429
+ font-size: 8px;
1430
+ color: var(--text-dimmer);
1431
+ margin-left: auto;
1432
+ cursor: pointer;
1433
+ transition: transform 0.15s ease;
1434
+ padding: 4px;
1435
+ }
1436
+
1437
+ .mobile-project-folder.collapsed .mobile-folder-chevron {
1438
+ transform: rotate(-90deg);
1439
+ }
1440
+
1441
+ .mobile-folder-items {
1442
+ overflow: hidden;
1443
+ transition: max-height 0.2s ease;
1444
+ max-height: 500px;
1445
+ }
1446
+
1447
+ .mobile-project-folder.collapsed .mobile-folder-items {
1448
+ max-height: 0;
1449
+ }
1450
+
1261
1451
  /* --- Per-project presence avatars --- */
1262
1452
  /* --- Mobile: hide icon strip --- */
1263
1453
  /* --- Skeleton loading placeholders --- */
@@ -165,9 +165,111 @@
165
165
  display: flex;
166
166
  }
167
167
 
168
+ /* --- Delegated work-order card ------------------------------------- */
169
+ /* Self-contained: the generic bubble avatar/name/time are hidden and the
170
+ identity lives in the card's own header strip. The body stays on a
171
+ NEUTRAL background -- accent only touches the header and the top rule,
172
+ so long technical briefs read like a document, not a tinted bubble. */
173
+ .msg-user-delegated .dm-bubble-avatar,
174
+ .msg-user-delegated .dm-bubble-header {
175
+ display: none;
176
+ }
177
+
168
178
  .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);
179
+ padding: 0;
180
+ overflow: hidden;
181
+ background: var(--bg);
182
+ border: 1px solid var(--border);
183
+ border-top: 2px solid var(--accent);
184
+ border-radius: 12px;
185
+ max-width: min(720px, 100%);
186
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.14), 0 4px 14px rgba(0, 0, 0, 0.08);
187
+ }
188
+
189
+ .delegated-card-head {
190
+ display: flex;
191
+ align-items: center;
192
+ gap: 10px;
193
+ padding: 10px 14px;
194
+ background: linear-gradient(to bottom,
195
+ color-mix(in srgb, var(--accent) 7%, var(--bg-alt)),
196
+ var(--bg-alt));
197
+ border-bottom: 1px solid var(--border-subtle);
198
+ }
199
+
200
+ .delegated-card-avatar {
201
+ width: 24px;
202
+ height: 24px;
203
+ border-radius: 7px;
204
+ flex-shrink: 0;
205
+ }
206
+
207
+ .delegated-card-headtext {
208
+ display: grid;
209
+ gap: 1px;
210
+ min-width: 0;
211
+ flex: 1;
212
+ }
213
+
214
+ .delegated-card-eyebrow {
215
+ font-size: 9px;
216
+ font-weight: 700;
217
+ letter-spacing: 0.09em;
218
+ text-transform: uppercase;
219
+ color: var(--accent);
220
+ line-height: 1;
221
+ }
222
+
223
+ .delegated-card-from {
224
+ font-size: 12.5px;
225
+ font-weight: 650;
226
+ color: var(--text);
227
+ overflow: hidden;
228
+ text-overflow: ellipsis;
229
+ white-space: nowrap;
230
+ }
231
+
232
+ .delegated-card-time {
233
+ font-size: 10px;
234
+ color: var(--text-dimmer);
235
+ flex-shrink: 0;
236
+ align-self: flex-start;
237
+ margin-top: 2px;
238
+ }
239
+
240
+ .msg-user-delegated .delegated-brief {
241
+ padding: 13px 16px 15px;
242
+ font-size: 13px;
243
+ line-height: 1.7;
244
+ }
245
+ .msg-user-delegated .delegated-brief > :first-child { margin-top: 0; }
246
+ .msg-user-delegated .delegated-brief > :last-child { margin-bottom: 0; }
247
+ .msg-user-delegated .delegated-brief p { margin: 8px 0; }
248
+ .msg-user-delegated .delegated-brief pre {
249
+ max-width: 100%;
250
+ overflow-x: auto;
251
+ border: 1px solid var(--border-subtle);
252
+ border-radius: 8px;
253
+ }
254
+ .msg-user-delegated .delegated-brief code {
255
+ font-size: 12px;
256
+ }
257
+ .msg-user-delegated .delegated-brief h1,
258
+ .msg-user-delegated .delegated-brief h2,
259
+ .msg-user-delegated .delegated-brief h3 {
260
+ font-size: 13px;
261
+ font-weight: 700;
262
+ margin: 14px 0 4px;
263
+ }
264
+ .msg-user-delegated .delegated-brief ol,
265
+ .msg-user-delegated .delegated-brief ul {
266
+ padding-left: 20px;
267
+ margin: 6px 0;
268
+ }
269
+ .msg-user-delegated .delegated-brief li { margin: 3px 0; }
270
+ .msg-user-delegated .delegated-brief li::marker {
271
+ color: var(--accent);
272
+ font-weight: 650;
171
273
  }
172
274
 
173
275
  .msg-user-delegated .dm-bubble-avatar-other {
@@ -160,10 +160,6 @@
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
-
167
163
  .mobile-project-abbrev {
168
164
  width: 32px;
169
165
  height: 32px;
@@ -187,6 +187,33 @@ button.split-pair-role:hover { filter: brightness(1.25); }
187
187
  @keyframes pair-divider-flow-left { 0%, 100% { transform: translateX(3px); opacity: 0.65; } 50% { transform: translateX(-3px); opacity: 1; } }
188
188
  @keyframes pair-status-pulse { 50% { opacity: 0.55; } }
189
189
 
190
+ /* Worker-pane composer notice: shown while this pane's session processes a
191
+ delegated turn. Informational only -- the composer stays enabled. */
192
+ .pane-delegation-notice {
193
+ display: none;
194
+ align-items: center;
195
+ gap: 6px;
196
+ margin: 0 12px;
197
+ padding: 4px 10px;
198
+ border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
199
+ border-bottom: 0;
200
+ border-radius: 8px 8px 0 0;
201
+ background: color-mix(in srgb, var(--accent) 8%, var(--bg));
202
+ color: var(--text-secondary);
203
+ font-size: 11px;
204
+ line-height: 1.4;
205
+ }
206
+ .pane-delegation-notice.visible { display: flex; }
207
+ .pane-delegation-notice::before {
208
+ content: "";
209
+ width: 6px;
210
+ height: 6px;
211
+ border-radius: 50%;
212
+ background: var(--accent);
213
+ flex-shrink: 0;
214
+ animation: pair-status-pulse 1.5s ease-in-out infinite;
215
+ }
216
+
190
217
  /* Pair dialog rides the standard wt-modal pattern; these classes only add
191
218
  the two-column role layout on top of it. */
192
219
  .pair-modal { min-width: 480px; max-width: 560px; }
@@ -677,3 +677,13 @@
677
677
  border: 1px dashed var(--border, #444);
678
678
  }
679
679
 
680
+
681
+ /* Attention pulse: shown when the user sends a message while a permission
682
+ request is still unanswered (the turn is blocked on it). */
683
+ .permission-container.permission-attention {
684
+ animation: permission-attention-pulse 0.65s ease-in-out 3;
685
+ }
686
+ @keyframes permission-attention-pulse {
687
+ 0%, 100% { box-shadow: none; }
688
+ 50% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent); }
689
+ }
@@ -72,6 +72,15 @@
72
72
  box-shadow: 0 4px 20px rgba(var(--shadow-rgb), 0.2);
73
73
  }
74
74
 
75
+ .sticky-note.sticky-note-attention {
76
+ animation: sticky-note-attention-pulse 0.65s ease-in-out 3;
77
+ }
78
+
79
+ @keyframes sticky-note-attention-pulse {
80
+ 0%, 100% { box-shadow: 0 2px 12px rgba(var(--shadow-rgb), 0.12); }
81
+ 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 55%, transparent), 0 4px 20px rgba(var(--shadow-rgb), 0.2); }
82
+ }
83
+
75
84
  .sticky-note.dragging,
76
85
  .sticky-note.resizing {
77
86
  opacity: 0.92;
@@ -109,6 +118,15 @@
109
118
  /* On hover, header stays fully visible */
110
119
  .sticky-note:hover .sticky-note-header { opacity: 1; }
111
120
 
121
+ .sticky-note-agent-badge {
122
+ width: 16px;
123
+ height: 16px;
124
+ border-radius: 4px;
125
+ object-fit: cover;
126
+ flex: 0 0 auto;
127
+ opacity: 0.8;
128
+ }
129
+
112
130
  .sticky-note-spacer {
113
131
  flex: 1;
114
132
  min-width: 0;
@@ -317,15 +335,37 @@
317
335
  }
318
336
 
319
337
  .sticky-note-rendered .sn-check {
338
+ display: inline-flex;
339
+ align-items: center;
340
+ justify-content: center;
341
+ width: 14px;
342
+ height: 14px;
320
343
  font-size: 12px;
321
344
  margin-right: 4px;
322
345
  opacity: 0.6;
346
+ cursor: pointer;
347
+ user-select: none;
348
+ border-radius: 3px;
349
+ transition: opacity 0.15s, background 0.15s, transform 0.15s;
350
+ }
351
+
352
+ .sticky-note-rendered .sn-check:hover,
353
+ .sticky-note-rendered .sn-check:focus-visible {
354
+ opacity: 1;
355
+ background: rgba(0,0,0,0.07);
356
+ outline: none;
357
+ transform: scale(1.08);
323
358
  }
324
359
 
325
360
  .sticky-note-rendered .sn-check.checked {
326
361
  opacity: 0.9;
327
362
  }
328
363
 
364
+ .dark-theme .sticky-note-rendered .sn-check:hover,
365
+ .dark-theme .sticky-note-rendered .sn-check:focus-visible {
366
+ background: rgba(255,255,255,0.1);
367
+ }
368
+
329
369
  /* --- Resize handle (bottom-right corner) --- */
330
370
  .sticky-note-resize {
331
371
  position: absolute;
@@ -631,9 +671,12 @@
631
671
  font-weight: 400 !important;
632
672
  color: var(--text-dimmer) !important;
633
673
  margin-top: 6px !important;
674
+ max-width: 520px;
634
675
  display: flex;
635
676
  align-items: center;
677
+ justify-content: center;
636
678
  gap: 4px;
679
+ line-height: 1.55;
637
680
  }
638
681
 
639
682
  .notes-archive-empty-sub .lucide {
@@ -272,175 +272,6 @@
272
272
  transform: rotate(180deg);
273
273
  }
274
274
 
275
- .branch-chip {
276
- display: inline-flex;
277
- align-items: center;
278
- gap: 4px;
279
- min-width: 0;
280
- max-width: 132px;
281
- /* Optical alignment: the pill reads slightly high next to the 17px/800
282
- project name, so nudge it down within the centered flex row. */
283
- margin-top: 2px;
284
- padding: 4px 7px;
285
- border: 1px solid var(--border);
286
- border-radius: 999px;
287
- background: var(--bg-alt);
288
- color: var(--text-secondary);
289
- font: 600 11px/1.2 "Pretendard", system-ui, sans-serif;
290
- cursor: pointer;
291
- flex-shrink: 1;
292
- }
293
-
294
- .branch-chip.hidden,
295
- .branch-chip-menu.hidden {
296
- display: none;
297
- }
298
-
299
- .branch-chip:hover,
300
- .branch-chip.open {
301
- border-color: var(--text-dimmer);
302
- color: var(--text);
303
- }
304
-
305
- .branch-chip > svg {
306
- width: 12px;
307
- height: 12px;
308
- flex-shrink: 0;
309
- }
310
-
311
- #branch-chip-label {
312
- overflow: hidden;
313
- text-overflow: ellipsis;
314
- white-space: nowrap;
315
- }
316
-
317
- .branch-chip-chevron {
318
- transition: transform 0.15s;
319
- }
320
-
321
- .branch-chip.open .branch-chip-chevron {
322
- transform: rotate(180deg);
323
- }
324
-
325
- .branch-chip-menu {
326
- position: fixed;
327
- z-index: 10020;
328
- width: 250px;
329
- padding: 6px;
330
- border: 1px solid var(--border);
331
- border-radius: 10px;
332
- background: var(--bg);
333
- box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
334
- }
335
-
336
- .branch-chip-row {
337
- display: flex;
338
- align-items: center;
339
- border-radius: 7px;
340
- }
341
-
342
- .branch-chip-row:hover {
343
- background: var(--bg-alt);
344
- }
345
-
346
- .branch-chip-row-main,
347
- .branch-chip-row-action,
348
- .branch-chip-new {
349
- border: 0;
350
- background: transparent;
351
- color: var(--text-secondary);
352
- font-family: inherit;
353
- cursor: pointer;
354
- }
355
-
356
- .branch-chip-row-main {
357
- min-width: 0;
358
- flex: 1;
359
- display: flex;
360
- align-items: center;
361
- gap: 7px;
362
- padding: 8px;
363
- text-align: left;
364
- }
365
-
366
- .branch-chip-row-main:disabled {
367
- opacity: 0.38;
368
- cursor: not-allowed;
369
- }
370
-
371
- .branch-chip-row-main svg,
372
- .branch-chip-row-action svg,
373
- .branch-chip-new svg {
374
- width: 14px;
375
- height: 14px;
376
- flex-shrink: 0;
377
- }
378
-
379
- .branch-chip-row-label {
380
- overflow: hidden;
381
- text-overflow: ellipsis;
382
- white-space: nowrap;
383
- }
384
-
385
- .branch-chip-row.current .branch-chip-row-label {
386
- color: var(--text);
387
- font-weight: 700;
388
- }
389
-
390
- .branch-chip-row-main > .lucide-check {
391
- margin-left: auto;
392
- color: var(--accent);
393
- }
394
-
395
- .branch-chip-processing {
396
- width: 7px;
397
- height: 7px;
398
- border-radius: 50%;
399
- background: var(--success, #23a55a);
400
- flex-shrink: 0;
401
- }
402
-
403
- .branch-chip-pending {
404
- min-width: 17px;
405
- padding: 1px 4px;
406
- border-radius: 8px;
407
- background: var(--danger, #e74c3c);
408
- color: #fff;
409
- font-size: 9px;
410
- text-align: center;
411
- }
412
-
413
- .branch-chip-row-action {
414
- display: flex;
415
- padding: 7px;
416
- opacity: 0;
417
- }
418
-
419
- .branch-chip-row:hover .branch-chip-row-action,
420
- .branch-chip-row-action:focus-visible {
421
- opacity: 0.7;
422
- }
423
-
424
- .branch-chip-row-action:hover {
425
- color: var(--danger, #e74c3c);
426
- opacity: 1;
427
- }
428
-
429
- .branch-chip-new {
430
- width: 100%;
431
- display: flex;
432
- align-items: center;
433
- gap: 7px;
434
- margin-top: 5px;
435
- padding: 9px 8px 7px;
436
- border-top: 1px solid var(--border-subtle);
437
- text-align: left;
438
- }
439
-
440
- .branch-chip-new:hover {
441
- color: var(--text);
442
- }
443
-
444
275
  .project-rename-input {
445
276
  width: 100%;
446
277
  font-family: "Pretendard", system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
@@ -210,12 +210,6 @@
210
210
  <span class="title-bar-project-name" id="title-bar-project-name"></span>
211
211
  <i data-lucide="chevron-down" class="title-bar-chevron"></i>
212
212
  </button>
213
- <button id="branch-chip" class="branch-chip hidden" type="button" aria-label="Switch branch" aria-expanded="false" aria-haspopup="menu">
214
- <i data-lucide="git-branch"></i>
215
- <span id="branch-chip-label"></span>
216
- <i data-lucide="chevron-down" class="branch-chip-chevron"></i>
217
- </button>
218
- <div id="branch-chip-menu" class="branch-chip-menu hidden"></div>
219
213
  <span id="sidebar-presence" class="sidebar-presence"></span>
220
214
  <button id="sidebar-toggle-btn" class="sidebar-collapse-btn" title="Collapse sidebar"><i data-lucide="panel-left-close"></i></button>
221
215
  </div>
@@ -109,6 +109,14 @@ export function blinkIO() {
109
109
  var sessionDot = document.querySelector(".session-item.active .session-processing") ||
110
110
  document.querySelector(".mate-session-item.active .session-processing");
111
111
  if (sessionDot) sessionDot.classList.add("io");
112
+ // If active project is a worktree, also blink the parent project dot
113
+ var activeWt = document.querySelector("#icon-strip-projects .icon-strip-wt-item.active");
114
+ var parentDot = null;
115
+ if (activeWt) {
116
+ var group = activeWt.closest(".icon-strip-group");
117
+ if (group) parentDot = group.querySelector(".folder-header .icon-strip-status");
118
+ if (parentDot) parentDot.classList.add("io");
119
+ }
112
120
  // Mobile chat chip dot + mobile session dot
113
121
  var mobileChipDot = null;
114
122
  var _s = store.snap();
@@ -127,6 +135,7 @@ export function blinkIO() {
127
135
  var sd = document.querySelector(".session-item.active .session-processing.io") ||
128
136
  document.querySelector(".mate-session-item.active .session-processing.io");
129
137
  if (sd) sd.classList.remove("io");
138
+ if (parentDot) parentDot.classList.remove("io");
130
139
  if (mobileChipDot) mobileChipDot.classList.remove("io");
131
140
  if (mobileSessionDot) mobileSessionDot.classList.remove("io");
132
141
  }, 80);
@@ -146,7 +155,7 @@ export function blinkSessionDot(sessionId) {
146
155
  export function updateCrossProjectBlink() {
147
156
  if (crossProjectBlinkTimer) { clearTimeout(crossProjectBlinkTimer); crossProjectBlinkTimer = null; }
148
157
  function doBlink() {
149
- var dots = document.querySelectorAll("#icon-strip-projects .icon-strip-item:not(.active) .icon-strip-status.processing, #icon-strip-users .icon-strip-mate:not(.active) .icon-strip-status.processing");
158
+ var dots = document.querySelectorAll("#icon-strip-projects .icon-strip-item:not(.active) .icon-strip-status.processing, #icon-strip-projects .icon-strip-wt-item:not(.active) .icon-strip-status.processing, #icon-strip-users .icon-strip-mate:not(.active) .icon-strip-status.processing");
150
159
  // Also blink mobile chat chip dots (same icon-strip-status class inside chips)
151
160
  var mobileDots = document.querySelectorAll(".mobile-chat-chip .icon-strip-status.processing");
152
161
  var allDots = [];
@@ -619,7 +619,6 @@ export function showHomeHub() {
619
619
  // anywhere via the persistent FAB (#clay-fab), not embedded here.
620
620
  if (store.get('dmMode')) exitDmMode();
621
621
  homeHubVisible = true;
622
- store.set({ homeHubVisible: true });
623
622
  homeHub.classList.remove("hidden");
624
623
  // Show close button only if there's a project to return to
625
624
  if (hubCloseBtn) {
@@ -653,7 +652,6 @@ export function showHomeHub() {
653
652
  export function hideHomeHub() {
654
653
  if (!homeHubVisible) return;
655
654
  homeHubVisible = false;
656
- store.set({ homeHubVisible: false });
657
655
  homeHub.classList.add("hidden");
658
656
  stopTipRotation();
659
657
  var mobileHome = document.getElementById("mobile-home-btn");