clay-server 3.0.0 → 3.1.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.
- package/lib/notes.js +6 -0
- package/lib/project-http.js +3 -6
- package/lib/project-session-notes.js +217 -0
- package/lib/project.js +84 -18
- package/lib/public/app.js +1 -4
- package/lib/public/css/icon-strip.css +190 -0
- package/lib/public/css/messages.css +104 -2
- package/lib/public/css/mobile-nav.css +0 -4
- package/lib/public/css/pane.css +27 -0
- package/lib/public/css/rewind.css +10 -0
- package/lib/public/css/sticky-notes.css +18 -0
- package/lib/public/css/title-bar.css +0 -169
- package/lib/public/index.html +0 -6
- package/lib/public/modules/app-favicon.js +10 -1
- package/lib/public/modules/app-home-hub.js +0 -2
- package/lib/public/modules/app-messages.js +18 -6
- package/lib/public/modules/app-projects.js +30 -43
- package/lib/public/modules/app-rendering.js +42 -3
- package/lib/public/modules/dom-refs.js +1 -0
- package/lib/public/modules/input.js +13 -0
- package/lib/public/modules/project-switcher.js +1 -2
- package/lib/public/modules/sidebar-mobile.js +6 -19
- package/lib/public/modules/sidebar-projects.js +232 -63
- package/lib/public/modules/split-pair-ui.js +30 -0
- package/lib/public/modules/sticky-notes.js +21 -0
- package/lib/sdk-bridge.js +25 -1
- package/lib/session-notes-mcp-server.js +39 -0
- package/lib/ws-schema.js +1 -0
- package/lib/yoke/adapters/codex.js +44 -8
- package/lib/yoke/mcp-bridge-server.js +7 -7
- package/package.json +1 -1
- package/lib/public/modules/branch-switcher.js +0 -178
- package/lib/public/modules/worktree-family.js +0 -60
|
@@ -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
|
-
|
|
170
|
-
|
|
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 {
|
package/lib/public/css/pane.css
CHANGED
|
@@ -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;
|
|
@@ -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;
|
package/lib/public/index.html
CHANGED
|
@@ -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");
|
|
@@ -20,7 +20,7 @@ import { renderMemoryList } from './mate-memory.js';
|
|
|
20
20
|
import { handlePaletteSessionSwitch, setPaletteVersion } from './command-palette.js';
|
|
21
21
|
import { handleFindInSessionResults } from './session-search.js';
|
|
22
22
|
import { syncPaneTitles, maybeRestoreSplitGroup, openGroup } from './split-view.js';
|
|
23
|
-
import { showPairDialog, handlePairCreated, handleSplitDelegation } from './split-pair-ui.js';
|
|
23
|
+
import { showPairDialog, handlePairCreated, handleSplitDelegation, showWorkerDelegationNotice, hideWorkerDelegationNotice } from './split-pair-ui.js';
|
|
24
24
|
import { handleInputSync, autoResize, builtinCommands, setScheduleBtnDisabled } from './input.js';
|
|
25
25
|
import { startThinking, appendThinking, stopThinking, resetThinkingGroup, createToolItem, updateToolExecuting, updateToolResult, markAllToolsDone, closeToolGroup, removeToolFromGroup, resetToolState, getTools, getPlanContent, setPlanContent, renderPlanBanner, renderPlanCard, getTodoTools, handleTodoWrite, handleTaskCreate, handleTaskUpdate, applyDeadSessionTodoCompaction, isPlanFilePath, enableMainInput, addTurnMeta, updateSubagentActivity, addSubagentToolEntry, markSubagentDone, initSubagentStop, updateSubagentProgress, updateSubagentTaskStatus, renderAskUserQuestion, markAskUserAnswered, renderPermissionRequest, markPermissionCancelled, markPermissionResolved, renderElicitationRequest, markElicitationResolved, renderUserDialogRequest, markUserDialogResolved, updateThinkingTokens } from './tools.js';
|
|
26
26
|
import { showDoneNotification, playDoneSound, isNotifAlertEnabled, isNotifSoundEnabled } from './notifications.js';
|
|
@@ -33,7 +33,7 @@ import { handleTuiTranscriptState } from './tui-grab.js';
|
|
|
33
33
|
import { tuiModalHandleTermOutput, tuiModalHandleTermResized, tuiModalHandleTermExited, tuiModalHandleTermClosed, openTuiModal } from './tui-attention.js';
|
|
34
34
|
import { updateTerminalList, handleContextSourcesState, updateEmailAccountList, updateEmailUnreadCounts, handleEmailTestResult, handleEmailAddResult, handleEmailRemoveResult, handleEmailDefaults } from './context-sources.js';
|
|
35
35
|
import { refreshEmailSettings } from './user-settings.js';
|
|
36
|
-
import { handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted } from './sticky-notes.js';
|
|
36
|
+
import { handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted, handleNoteWritten } from './sticky-notes.js';
|
|
37
37
|
import { handleSkillInstalled, handleSkillUninstalled } from './skills.js';
|
|
38
38
|
import { showRewindModal, onRewindComplete, setRewindMode, onRewindError, clearPendingRewindUuid, addRewindButton } from './rewind.js';
|
|
39
39
|
import { checkAdminAccess } from './admin.js';
|
|
@@ -50,7 +50,7 @@ import { handleWhatsNewState, handleWhatsNewSeenResult, setKnownEntries as setWh
|
|
|
50
50
|
import { closeArticle as closeWhatsNewArticle } from './whats-new-article.js';
|
|
51
51
|
import { resolvePaneSession, resolveSwitchedVendor } from './pane-session.js';
|
|
52
52
|
import { getModelEffortLevels, accumulateUsage, updateUsagePanel, accumulateContext, updateContextPanel, renderCtxPopover, updateStatusPanel } from './app-panels.js';
|
|
53
|
-
import { updateProjectList,
|
|
53
|
+
import { updateProjectList, resetClientState, showUpdateAvailable, handleRemoveProjectCheckResult, handleRemoveProjectResult, handleBrowseDirResult, handleAddProjectResult, handleCloneProgress } from './app-projects.js';
|
|
54
54
|
import { updateHistorySentinel, prependOlderHistory } from './app-header.js';
|
|
55
55
|
import { hideHomeHub, handleHubSchedules } from './app-home-hub.js';
|
|
56
56
|
import { openDm, enterDmMode, exitDmMode, handleMateCreatedInApp, updateMateIconStatus, appendDmMessage, showDmTypingIndicator, buildMateInterviewPrompt } from './app-dm.js';
|
|
@@ -85,7 +85,8 @@ export function processMessage(msg) {
|
|
|
85
85
|
// Override title bar with mate name and re-apply color
|
|
86
86
|
var _mdn = (store.get('dmTargetUser').displayName || "New Mate");
|
|
87
87
|
if (headerTitleEl) headerTitleEl.textContent = _mdn;
|
|
88
|
-
|
|
88
|
+
var _tbpn = document.getElementById("title-bar-project-name");
|
|
89
|
+
if (_tbpn) _tbpn.textContent = _mdn;
|
|
89
90
|
var _mc2 = (store.get('dmTargetUser').profile && store.get('dmTargetUser').profile.avatarColor) || store.get('dmTargetUser').avatarColor || "#7c3aed";
|
|
90
91
|
var _tbc2 = document.querySelector(".title-bar-content");
|
|
91
92
|
if (_tbc2) { _tbc2.style.background = _mc2; _tbc2.classList.add("mate-dm-active"); }
|
|
@@ -298,7 +299,8 @@ export function processMessage(msg) {
|
|
|
298
299
|
if (store.get('dmMode') && store.get('dmTargetUser') && store.get('dmTargetUser').isMate) {
|
|
299
300
|
var _mateDN = store.get('dmTargetUser').displayName || "New Mate";
|
|
300
301
|
headerTitleEl.textContent = _mateDN;
|
|
301
|
-
|
|
302
|
+
var tbProjectName = document.getElementById("title-bar-project-name");
|
|
303
|
+
if (tbProjectName) tbProjectName.textContent = _mateDN;
|
|
302
304
|
// Re-apply mate title bar styling (may be lost during project switch)
|
|
303
305
|
var _mc = (store.get('dmTargetUser').profile && store.get('dmTargetUser').profile.avatarColor) || store.get('dmTargetUser').avatarColor || "#7c3aed";
|
|
304
306
|
var _tbc = document.querySelector(".title-bar-content");
|
|
@@ -306,7 +308,8 @@ export function processMessage(msg) {
|
|
|
306
308
|
document.body.classList.add("mate-dm-active");
|
|
307
309
|
} else {
|
|
308
310
|
headerTitleEl.textContent = store.get('projectName');
|
|
309
|
-
|
|
311
|
+
var tbProjectName = document.getElementById("title-bar-project-name");
|
|
312
|
+
if (tbProjectName) tbProjectName.textContent = msg.title || store.get('projectName');
|
|
310
313
|
}
|
|
311
314
|
updatePageTitle();
|
|
312
315
|
if (msg.version) {
|
|
@@ -788,6 +791,9 @@ export function processMessage(msg) {
|
|
|
788
791
|
} else {
|
|
789
792
|
addUserMessage(msg.text, msg.images || null, msg.pastes || null, msg.from, msg.fromName, msg.delegated ? msg : null);
|
|
790
793
|
}
|
|
794
|
+
// Worker pane: a delegated instruction starts (or replays into) a
|
|
795
|
+
// driven turn; surface the composer notice. Cleared on "done".
|
|
796
|
+
if (msg.delegated) showWorkerDelegationNotice(msg.delegatedByTitle || null);
|
|
791
797
|
break;
|
|
792
798
|
|
|
793
799
|
case "plan_content":
|
|
@@ -1108,6 +1114,7 @@ export function processMessage(msg) {
|
|
|
1108
1114
|
removeMatePreThinking();
|
|
1109
1115
|
setActivity(null);
|
|
1110
1116
|
stopThinking();
|
|
1117
|
+
hideWorkerDelegationNotice();
|
|
1111
1118
|
markAllToolsDone();
|
|
1112
1119
|
closeToolGroup();
|
|
1113
1120
|
finalizeAssistantBlock();
|
|
@@ -1441,6 +1448,11 @@ export function processMessage(msg) {
|
|
|
1441
1448
|
handleNoteUpdated(msg);
|
|
1442
1449
|
break;
|
|
1443
1450
|
|
|
1451
|
+
case "note_written":
|
|
1452
|
+
showToast((msg.byTitle || "Agent") + ' left a note: "' + (msg.preview || "") + '"');
|
|
1453
|
+
handleNoteWritten(msg);
|
|
1454
|
+
break;
|
|
1455
|
+
|
|
1444
1456
|
case "note_deleted":
|
|
1445
1457
|
handleNoteDeleted(msg);
|
|
1446
1458
|
break;
|
|
@@ -32,7 +32,6 @@ import { resetRateLimitState } from './app-rate-limit.js';
|
|
|
32
32
|
import { closeSessionInfoPopover } from './app-header.js';
|
|
33
33
|
import { resetDebateState } from './debate.js';
|
|
34
34
|
import { removeDebateBottomBar } from './app-debate-ui.js';
|
|
35
|
-
import { familyOf as deriveFamily, displayProject } from './worktree-family.js';
|
|
36
35
|
|
|
37
36
|
// --- Module-owned state ---
|
|
38
37
|
var cachedProjects = [];
|
|
@@ -202,32 +201,6 @@ export function setCachedProjectCount(v) { cachedProjectCount = v; }
|
|
|
202
201
|
export function getCachedRemovedProjects() { return cachedRemovedProjects; }
|
|
203
202
|
export function setCachedRemovedProjects(v) { cachedRemovedProjects = v; }
|
|
204
203
|
|
|
205
|
-
export function familyOf(slug) { return deriveFamily(cachedProjects, slug); }
|
|
206
|
-
export function currentFamily() { return familyOf(store.get('currentSlug')); }
|
|
207
|
-
|
|
208
|
-
export function updateTitleBarProjectIdentity(fallbackName, fallbackIcon) {
|
|
209
|
-
if (store.get('dmMode') || store.get('mateProjectSlug')) {
|
|
210
|
-
var dmNameEl = document.getElementById("title-bar-project-name");
|
|
211
|
-
if (dmNameEl && fallbackName) dmNameEl.textContent = fallbackName;
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
var identity = displayProject(cachedProjects, store.get('currentSlug'));
|
|
215
|
-
var name = identity ? (identity.title || identity.project || identity.slug) : fallbackName;
|
|
216
|
-
var icon = identity ? (identity.icon || null) : (fallbackIcon || null);
|
|
217
|
-
var nameEl = document.getElementById("title-bar-project-name");
|
|
218
|
-
if (nameEl && name) nameEl.textContent = name;
|
|
219
|
-
var iconEl = document.getElementById("title-bar-project-icon");
|
|
220
|
-
if (!iconEl) return;
|
|
221
|
-
if (icon) {
|
|
222
|
-
iconEl.textContent = icon;
|
|
223
|
-
parseEmojis(iconEl);
|
|
224
|
-
iconEl.classList.add("has-icon");
|
|
225
|
-
} else {
|
|
226
|
-
iconEl.textContent = "";
|
|
227
|
-
iconEl.classList.remove("has-icon");
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
204
|
// --- Functions ---
|
|
232
205
|
|
|
233
206
|
export function updateProjectList(msg) {
|
|
@@ -242,7 +215,6 @@ export function updateProjectList(msg) {
|
|
|
242
215
|
_lastProjectsJson = projectsJson;
|
|
243
216
|
}
|
|
244
217
|
cachedProjects = msg.projects;
|
|
245
|
-
store.set({ projects: cachedProjects });
|
|
246
218
|
}
|
|
247
219
|
if (msg.removedProjects) cachedRemovedProjects = msg.removedProjects;
|
|
248
220
|
else if (msg.removedProjects === undefined) { /* keep cached */ }
|
|
@@ -354,12 +326,31 @@ export function renderProjectList() {
|
|
|
354
326
|
});
|
|
355
327
|
var st = store.snap();
|
|
356
328
|
var iconStripActiveSlug = (st.mateProjectSlug && st.savedMainSlug) ? st.savedMainSlug : st.currentSlug;
|
|
357
|
-
var activeFamily = deriveFamily(cachedProjects, iconStripActiveSlug);
|
|
358
|
-
if (activeFamily.parent) iconStripActiveSlug = activeFamily.parent.slug;
|
|
359
329
|
renderIconStrip(iconStripProjects, iconStripActiveSlug);
|
|
360
330
|
// Update title bar project name and icon if it changed
|
|
361
331
|
if (!st.mateProjectSlug) {
|
|
362
|
-
|
|
332
|
+
for (var pi = 0; pi < cachedProjects.length; pi++) {
|
|
333
|
+
if (cachedProjects[pi].slug === st.currentSlug) {
|
|
334
|
+
var updatedName = cachedProjects[pi].title || cachedProjects[pi].project;
|
|
335
|
+
var tbName = document.getElementById("title-bar-project-name");
|
|
336
|
+
if (tbName && updatedName) tbName.textContent = updatedName;
|
|
337
|
+
var tbIcon = document.getElementById("title-bar-project-icon");
|
|
338
|
+
if (tbIcon) {
|
|
339
|
+
var pIcon = cachedProjects[pi].icon || null;
|
|
340
|
+
if (pIcon) {
|
|
341
|
+
tbIcon.textContent = pIcon;
|
|
342
|
+
parseEmojis(tbIcon);
|
|
343
|
+
tbIcon.classList.add("has-icon");
|
|
344
|
+
try { localStorage.setItem("clay-project-icon-" + (st.currentSlug || "default"), pIcon); } catch (e) {}
|
|
345
|
+
} else {
|
|
346
|
+
tbIcon.textContent = "";
|
|
347
|
+
tbIcon.classList.remove("has-icon");
|
|
348
|
+
try { localStorage.removeItem("clay-project-icon-" + (st.currentSlug || "default")); } catch (e) {}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
363
354
|
}
|
|
364
355
|
// Re-apply current socket status to the active icon's dot
|
|
365
356
|
var dot = getStatusDot();
|
|
@@ -566,13 +557,9 @@ function showRemoveProjectTaskDialog(slug, name, taskCount) {
|
|
|
566
557
|
export function handleRemoveProjectResult(msg) {
|
|
567
558
|
if (msg.ok) {
|
|
568
559
|
var currentSlug = store.get('currentSlug');
|
|
569
|
-
var removedProj = null;
|
|
570
|
-
for (var ri = 0; ri < cachedProjects.length; ri++) {
|
|
571
|
-
if (cachedProjects[ri].slug === msg.slug) { removedProj = cachedProjects[ri]; break; }
|
|
572
|
-
}
|
|
573
|
-
var isWorktree = removedProj ? !!removedProj.isWorktree : msg.slug.indexOf("--") !== -1;
|
|
574
560
|
if (msg.slug === currentSlug) {
|
|
575
|
-
var
|
|
561
|
+
var isWorktree = msg.slug.indexOf("--") !== -1;
|
|
562
|
+
var parentSlug = isWorktree ? msg.slug.split("--")[0] : null;
|
|
576
563
|
|
|
577
564
|
showToast(isWorktree ? "Worktree removed" : "Project removed", "success");
|
|
578
565
|
|
|
@@ -583,6 +570,10 @@ export function handleRemoveProjectResult(msg) {
|
|
|
583
570
|
store.set({ connected: false });
|
|
584
571
|
document.getElementById("connect-overlay").classList.add("hidden");
|
|
585
572
|
if (!isWorktree) {
|
|
573
|
+
var removedProj = null;
|
|
574
|
+
for (var ri = 0; ri < cachedProjects.length; ri++) {
|
|
575
|
+
if (cachedProjects[ri].slug === msg.slug) { removedProj = cachedProjects[ri]; break; }
|
|
576
|
+
}
|
|
586
577
|
if (removedProj) {
|
|
587
578
|
cachedRemovedProjects.push({
|
|
588
579
|
path: removedProj.path || "",
|
|
@@ -594,7 +585,7 @@ export function handleRemoveProjectResult(msg) {
|
|
|
594
585
|
}
|
|
595
586
|
cachedProjects = cachedProjects.filter(function (p) { return p.slug !== msg.slug; });
|
|
596
587
|
cachedProjectCount = cachedProjects.length;
|
|
597
|
-
store.set({ currentSlug: null
|
|
588
|
+
store.set({ currentSlug: null });
|
|
598
589
|
renderProjectList();
|
|
599
590
|
resetClientState();
|
|
600
591
|
|
|
@@ -604,11 +595,7 @@ export function handleRemoveProjectResult(msg) {
|
|
|
604
595
|
showHomeHub();
|
|
605
596
|
}
|
|
606
597
|
} else {
|
|
607
|
-
showToast(
|
|
608
|
-
cachedProjects = cachedProjects.filter(function (p) { return p.slug !== msg.slug; });
|
|
609
|
-
cachedProjectCount = cachedProjects.length;
|
|
610
|
-
store.set({ projects: cachedProjects });
|
|
611
|
-
renderProjectList();
|
|
598
|
+
showToast(msg.slug.indexOf("--") !== -1 ? "Worktree removed" : "Project removed", "success");
|
|
612
599
|
}
|
|
613
600
|
} else {
|
|
614
601
|
showToast(msg.error || "Failed to remove project", "error");
|