clay-server 4.6.1-beta.1 → 4.7.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.
- package/lib/project-ask-user.js +6 -0
- package/lib/project-connection.js +0 -14
- package/lib/project-sessions.js +0 -18
- package/lib/project-worker-permission.js +12 -8
- package/lib/project-worker-question.js +125 -0
- package/lib/project.js +4 -1
- package/lib/public/app.js +14 -14
- package/lib/public/css/pane.css +0 -1
- package/lib/public/css/projects-hub.css +75 -0
- package/lib/public/css/tui-attention.css +0 -407
- package/lib/public/index.html +3 -14
- package/lib/public/modules/app-home-hub.js +8 -3
- package/lib/public/modules/app-messages.js +0 -15
- package/lib/public/modules/app-projects.js +16 -11
- package/lib/public/modules/home-surface-boot.js +10 -3
- package/lib/public/modules/home-surface.js +13 -1
- package/lib/public/modules/projects-hub-view.js +62 -0
- package/lib/public/modules/projects-hub.js +105 -0
- package/lib/public/style.css +2 -0
- package/lib/sdk-bridge.js +2 -0
- package/lib/server.js +1 -1
- package/lib/users-home-surface-preferences.js +4 -2
- package/lib/users-preferences.js +0 -36
- package/lib/users.js +0 -4
- package/lib/ws-schema.js +0 -3
- package/package.json +1 -1
- package/lib/public/modules/whats-new-article.js +0 -70
- package/lib/public/modules/whats-new.js +0 -264
- package/lib/whats-new-content.js +0 -84
- package/lib/whats-new.js +0 -57
|
@@ -49,141 +49,6 @@ body.tui-suspended #tui-resume-bar {
|
|
|
49
49
|
.tui-resume-hint { display: none; }
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
/* Policy info modal. Themed via CSS vars so it follows light/dark.
|
|
53
|
-
The modal itself is gone; .tui-policy-modal-* rules stay because
|
|
54
|
-
What's New article bodies (lib/whats-new-content.js) still use the
|
|
55
|
-
-links class for their footer links. */
|
|
56
|
-
.tui-policy-modal-backdrop {
|
|
57
|
-
position: fixed;
|
|
58
|
-
inset: 0;
|
|
59
|
-
z-index: 9600;
|
|
60
|
-
background: rgba(0, 0, 0, 0.55);
|
|
61
|
-
display: flex;
|
|
62
|
-
align-items: center;
|
|
63
|
-
justify-content: center;
|
|
64
|
-
padding: 24px;
|
|
65
|
-
}
|
|
66
|
-
.tui-policy-modal-backdrop.hidden { display: none; }
|
|
67
|
-
.tui-policy-modal {
|
|
68
|
-
width: min(560px, 100%);
|
|
69
|
-
max-height: min(80vh, 720px);
|
|
70
|
-
background: var(--sidebar-bg);
|
|
71
|
-
border: 1px solid var(--border);
|
|
72
|
-
border-radius: 12px;
|
|
73
|
-
overflow: hidden;
|
|
74
|
-
display: flex;
|
|
75
|
-
flex-direction: column;
|
|
76
|
-
box-shadow: 0 12px 48px rgba(var(--shadow-rgb), 0.4);
|
|
77
|
-
color: var(--text);
|
|
78
|
-
}
|
|
79
|
-
.tui-policy-modal-header {
|
|
80
|
-
display: flex;
|
|
81
|
-
align-items: center;
|
|
82
|
-
justify-content: space-between;
|
|
83
|
-
padding: 14px 18px;
|
|
84
|
-
border-bottom: 1px solid var(--border);
|
|
85
|
-
flex-shrink: 0;
|
|
86
|
-
}
|
|
87
|
-
.tui-policy-modal-header h2 {
|
|
88
|
-
margin: 0;
|
|
89
|
-
font-size: 16px;
|
|
90
|
-
font-weight: 600;
|
|
91
|
-
color: var(--text);
|
|
92
|
-
}
|
|
93
|
-
.tui-policy-modal-close {
|
|
94
|
-
width: 28px;
|
|
95
|
-
height: 28px;
|
|
96
|
-
padding: 0;
|
|
97
|
-
border: none;
|
|
98
|
-
border-radius: 6px;
|
|
99
|
-
background: transparent;
|
|
100
|
-
color: var(--text-dimmer);
|
|
101
|
-
font-size: 20px;
|
|
102
|
-
cursor: pointer;
|
|
103
|
-
}
|
|
104
|
-
.tui-policy-modal-close:hover {
|
|
105
|
-
background: rgba(var(--overlay-rgb), 0.05);
|
|
106
|
-
color: var(--text);
|
|
107
|
-
}
|
|
108
|
-
.tui-policy-modal-body {
|
|
109
|
-
padding: 16px 18px 20px;
|
|
110
|
-
overflow-y: auto;
|
|
111
|
-
font-size: 13px;
|
|
112
|
-
line-height: 1.55;
|
|
113
|
-
color: var(--text-secondary);
|
|
114
|
-
}
|
|
115
|
-
.tui-policy-modal-body p {
|
|
116
|
-
margin: 0 0 12px;
|
|
117
|
-
}
|
|
118
|
-
.tui-policy-modal-body ul {
|
|
119
|
-
margin: 0 0 12px;
|
|
120
|
-
padding-left: 20px;
|
|
121
|
-
}
|
|
122
|
-
.tui-policy-modal-body li {
|
|
123
|
-
margin-bottom: 6px;
|
|
124
|
-
}
|
|
125
|
-
.tui-policy-modal-body code {
|
|
126
|
-
padding: 1px 5px;
|
|
127
|
-
border-radius: 4px;
|
|
128
|
-
background: var(--code-bg);
|
|
129
|
-
color: var(--accent);
|
|
130
|
-
font-size: 12px;
|
|
131
|
-
font-family: "Roboto Mono", monospace;
|
|
132
|
-
}
|
|
133
|
-
.tui-policy-modal-body strong {
|
|
134
|
-
color: var(--text);
|
|
135
|
-
}
|
|
136
|
-
.tui-policy-modal-body h3 {
|
|
137
|
-
margin: 18px 0 6px;
|
|
138
|
-
font-size: 13px;
|
|
139
|
-
font-weight: 600;
|
|
140
|
-
color: var(--text);
|
|
141
|
-
}
|
|
142
|
-
.tui-policy-modal-body ol {
|
|
143
|
-
margin: 0 0 12px;
|
|
144
|
-
padding-left: 20px;
|
|
145
|
-
}
|
|
146
|
-
.tui-policy-modal-body ol li {
|
|
147
|
-
margin-bottom: 6px;
|
|
148
|
-
}
|
|
149
|
-
.tui-policy-modal-body a {
|
|
150
|
-
color: var(--accent2);
|
|
151
|
-
}
|
|
152
|
-
.tui-policy-modal-body a:hover {
|
|
153
|
-
text-decoration: underline;
|
|
154
|
-
}
|
|
155
|
-
.tui-policy-modal-links {
|
|
156
|
-
margin-top: 16px;
|
|
157
|
-
font-size: 12px;
|
|
158
|
-
color: var(--text-dimmer);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/* Maintainer note: visually distinct from the technical explanation
|
|
162
|
-
above so it reads as a personal aside, not just more documentation. */
|
|
163
|
-
.tui-policy-maintainer-note {
|
|
164
|
-
margin-top: 18px;
|
|
165
|
-
padding: 14px 16px;
|
|
166
|
-
border-left: 3px solid var(--accent);
|
|
167
|
-
background: rgba(var(--overlay-rgb), 0.04);
|
|
168
|
-
border-radius: 0 8px 8px 0;
|
|
169
|
-
}
|
|
170
|
-
.tui-policy-maintainer-note h3 {
|
|
171
|
-
margin-top: 0;
|
|
172
|
-
}
|
|
173
|
-
.tui-policy-maintainer-note p {
|
|
174
|
-
margin-bottom: 10px;
|
|
175
|
-
color: var(--text-secondary);
|
|
176
|
-
}
|
|
177
|
-
.tui-policy-maintainer-note p:last-of-type {
|
|
178
|
-
margin-bottom: 0;
|
|
179
|
-
}
|
|
180
|
-
.tui-policy-signature {
|
|
181
|
-
margin-top: 12px !important;
|
|
182
|
-
color: var(--text-dimmer) !important;
|
|
183
|
-
font-style: italic;
|
|
184
|
-
font-size: 12px;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
52
|
/* tui-attention.css
|
|
188
53
|
Banner + modal for "claude TUI session needs your input" notifications.
|
|
189
54
|
The banner sits at the top of the viewport above any project content;
|
|
@@ -367,275 +232,3 @@ body.tui-suspended #tui-resume-bar {
|
|
|
367
232
|
padding: 4px;
|
|
368
233
|
background: #000;
|
|
369
234
|
}
|
|
370
|
-
|
|
371
|
-
/* ============================================================
|
|
372
|
-
What's New carousel
|
|
373
|
-
============================================================ */
|
|
374
|
-
.whats-new-backdrop {
|
|
375
|
-
position: fixed;
|
|
376
|
-
inset: 0;
|
|
377
|
-
z-index: 9600;
|
|
378
|
-
background: rgba(0, 0, 0, 0.55);
|
|
379
|
-
display: flex;
|
|
380
|
-
align-items: center;
|
|
381
|
-
justify-content: center;
|
|
382
|
-
padding: 24px;
|
|
383
|
-
opacity: 0;
|
|
384
|
-
transition: opacity 160ms ease;
|
|
385
|
-
}
|
|
386
|
-
.whats-new-backdrop.show { opacity: 1; }
|
|
387
|
-
.whats-new-card {
|
|
388
|
-
position: relative;
|
|
389
|
-
width: min(440px, 100%);
|
|
390
|
-
max-height: min(80vh, 640px);
|
|
391
|
-
background: var(--sidebar-bg);
|
|
392
|
-
border: 1px solid var(--border);
|
|
393
|
-
border-radius: 14px;
|
|
394
|
-
overflow: hidden;
|
|
395
|
-
display: flex;
|
|
396
|
-
flex-direction: column;
|
|
397
|
-
box-shadow: 0 12px 48px rgba(var(--shadow-rgb), 0.4);
|
|
398
|
-
color: var(--text);
|
|
399
|
-
}
|
|
400
|
-
.whats-new-close {
|
|
401
|
-
position: absolute;
|
|
402
|
-
top: 10px;
|
|
403
|
-
right: 10px;
|
|
404
|
-
width: 28px;
|
|
405
|
-
height: 28px;
|
|
406
|
-
padding: 0;
|
|
407
|
-
border: none;
|
|
408
|
-
border-radius: 6px;
|
|
409
|
-
background: rgba(var(--overlay-rgb), 0.08);
|
|
410
|
-
color: var(--text-dimmer);
|
|
411
|
-
cursor: pointer;
|
|
412
|
-
display: flex;
|
|
413
|
-
align-items: center;
|
|
414
|
-
justify-content: center;
|
|
415
|
-
z-index: 2;
|
|
416
|
-
}
|
|
417
|
-
.whats-new-close:hover {
|
|
418
|
-
background: rgba(var(--overlay-rgb), 0.15);
|
|
419
|
-
color: var(--text);
|
|
420
|
-
}
|
|
421
|
-
.whats-new-image-slot {
|
|
422
|
-
width: 100%;
|
|
423
|
-
aspect-ratio: 16 / 9;
|
|
424
|
-
background: linear-gradient(135deg, var(--accent) 0%, var(--accent2, var(--accent)) 100%);
|
|
425
|
-
flex-shrink: 0;
|
|
426
|
-
overflow: hidden;
|
|
427
|
-
display: block;
|
|
428
|
-
}
|
|
429
|
-
.whats-new-image-slot img {
|
|
430
|
-
width: 100%;
|
|
431
|
-
height: 100%;
|
|
432
|
-
object-fit: cover;
|
|
433
|
-
display: block;
|
|
434
|
-
}
|
|
435
|
-
.whats-new-image-slot.empty {
|
|
436
|
-
aspect-ratio: 16 / 6;
|
|
437
|
-
}
|
|
438
|
-
.whats-new-body {
|
|
439
|
-
padding: 18px 20px 14px;
|
|
440
|
-
display: flex;
|
|
441
|
-
flex-direction: column;
|
|
442
|
-
gap: 8px;
|
|
443
|
-
overflow-y: auto;
|
|
444
|
-
}
|
|
445
|
-
.whats-new-eyebrow {
|
|
446
|
-
font-size: 11px;
|
|
447
|
-
font-weight: 600;
|
|
448
|
-
letter-spacing: 0.06em;
|
|
449
|
-
text-transform: uppercase;
|
|
450
|
-
color: var(--text-dimmer);
|
|
451
|
-
}
|
|
452
|
-
.whats-new-title {
|
|
453
|
-
margin: 0;
|
|
454
|
-
font-size: 18px;
|
|
455
|
-
font-weight: 600;
|
|
456
|
-
line-height: 1.3;
|
|
457
|
-
color: var(--text);
|
|
458
|
-
}
|
|
459
|
-
.whats-new-summary {
|
|
460
|
-
margin: 0;
|
|
461
|
-
font-size: 13px;
|
|
462
|
-
line-height: 1.55;
|
|
463
|
-
color: var(--text-secondary);
|
|
464
|
-
}
|
|
465
|
-
.whats-new-read-more {
|
|
466
|
-
align-self: flex-start;
|
|
467
|
-
margin-top: 6px;
|
|
468
|
-
padding: 7px 14px;
|
|
469
|
-
font-size: 13px;
|
|
470
|
-
font-weight: 500;
|
|
471
|
-
border: none;
|
|
472
|
-
border-radius: 7px;
|
|
473
|
-
background: var(--accent);
|
|
474
|
-
color: var(--accent-contrast, #fff);
|
|
475
|
-
cursor: pointer;
|
|
476
|
-
display: inline-flex;
|
|
477
|
-
align-items: center;
|
|
478
|
-
}
|
|
479
|
-
.whats-new-read-more:hover {
|
|
480
|
-
filter: brightness(1.08);
|
|
481
|
-
}
|
|
482
|
-
.whats-new-nav {
|
|
483
|
-
display: flex;
|
|
484
|
-
align-items: center;
|
|
485
|
-
justify-content: space-between;
|
|
486
|
-
padding: 8px 16px 14px;
|
|
487
|
-
border-top: 1px solid var(--border);
|
|
488
|
-
flex-shrink: 0;
|
|
489
|
-
}
|
|
490
|
-
.whats-new-nav.hidden { display: none; }
|
|
491
|
-
.whats-new-prev,
|
|
492
|
-
.whats-new-next {
|
|
493
|
-
width: 30px;
|
|
494
|
-
height: 30px;
|
|
495
|
-
padding: 0;
|
|
496
|
-
border: none;
|
|
497
|
-
border-radius: 6px;
|
|
498
|
-
background: transparent;
|
|
499
|
-
color: var(--text-dimmer);
|
|
500
|
-
cursor: pointer;
|
|
501
|
-
display: flex;
|
|
502
|
-
align-items: center;
|
|
503
|
-
justify-content: center;
|
|
504
|
-
}
|
|
505
|
-
.whats-new-prev:hover,
|
|
506
|
-
.whats-new-next:hover {
|
|
507
|
-
background: rgba(var(--overlay-rgb), 0.08);
|
|
508
|
-
color: var(--text);
|
|
509
|
-
}
|
|
510
|
-
.whats-new-prev:disabled,
|
|
511
|
-
.whats-new-next:disabled {
|
|
512
|
-
opacity: 0.35;
|
|
513
|
-
cursor: default;
|
|
514
|
-
}
|
|
515
|
-
.whats-new-dots {
|
|
516
|
-
display: flex;
|
|
517
|
-
gap: 6px;
|
|
518
|
-
align-items: center;
|
|
519
|
-
}
|
|
520
|
-
.whats-new-dot {
|
|
521
|
-
width: 7px;
|
|
522
|
-
height: 7px;
|
|
523
|
-
padding: 0;
|
|
524
|
-
border: none;
|
|
525
|
-
border-radius: 50%;
|
|
526
|
-
background: var(--text-dimmer);
|
|
527
|
-
opacity: 0.35;
|
|
528
|
-
cursor: pointer;
|
|
529
|
-
transition: opacity 120ms ease, transform 120ms ease;
|
|
530
|
-
}
|
|
531
|
-
.whats-new-dot.active {
|
|
532
|
-
opacity: 1;
|
|
533
|
-
background: var(--accent);
|
|
534
|
-
transform: scale(1.2);
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
/* ============================================================
|
|
538
|
-
Whats New article (blog-style reading view)
|
|
539
|
-
============================================================
|
|
540
|
-
Mirrors #home-hub positioning: absolute inset:0 inside
|
|
541
|
-
#main-area so the icon strip, top bar, and any other chrome
|
|
542
|
-
outside #main-area stay visible. Sidebar-column (inside
|
|
543
|
-
main-area) is covered, same as home-hub. */
|
|
544
|
-
#whats-new-article {
|
|
545
|
-
position: absolute;
|
|
546
|
-
inset: 0;
|
|
547
|
-
z-index: 210;
|
|
548
|
-
background: var(--bg);
|
|
549
|
-
overflow-y: auto;
|
|
550
|
-
display: flex;
|
|
551
|
-
flex-direction: column;
|
|
552
|
-
border-top-left-radius: 8px;
|
|
553
|
-
}
|
|
554
|
-
#whats-new-article.hidden { display: none; }
|
|
555
|
-
.wna-toolbar {
|
|
556
|
-
position: sticky;
|
|
557
|
-
top: 0;
|
|
558
|
-
display: flex;
|
|
559
|
-
align-items: center;
|
|
560
|
-
padding: 12px 20px;
|
|
561
|
-
background: var(--bg);
|
|
562
|
-
border-bottom: 1px solid var(--border);
|
|
563
|
-
z-index: 1;
|
|
564
|
-
}
|
|
565
|
-
.wna-back {
|
|
566
|
-
display: inline-flex;
|
|
567
|
-
align-items: center;
|
|
568
|
-
gap: 8px;
|
|
569
|
-
padding: 6px 12px;
|
|
570
|
-
border: none;
|
|
571
|
-
border-radius: 6px;
|
|
572
|
-
background: transparent;
|
|
573
|
-
color: var(--text-secondary);
|
|
574
|
-
font-size: 13px;
|
|
575
|
-
cursor: pointer;
|
|
576
|
-
}
|
|
577
|
-
.wna-back:hover {
|
|
578
|
-
background: rgba(var(--overlay-rgb), 0.06);
|
|
579
|
-
color: var(--text);
|
|
580
|
-
}
|
|
581
|
-
.wna-content {
|
|
582
|
-
width: 100%;
|
|
583
|
-
max-width: 680px;
|
|
584
|
-
margin: 0 auto;
|
|
585
|
-
padding: 56px 32px 96px;
|
|
586
|
-
box-sizing: border-box;
|
|
587
|
-
}
|
|
588
|
-
.wna-date {
|
|
589
|
-
font-size: 12px;
|
|
590
|
-
color: var(--text-dimmer);
|
|
591
|
-
letter-spacing: 0.04em;
|
|
592
|
-
margin-bottom: 12px;
|
|
593
|
-
font-variant-numeric: tabular-nums;
|
|
594
|
-
}
|
|
595
|
-
.wna-title {
|
|
596
|
-
margin: 0 0 32px;
|
|
597
|
-
font-size: 32px;
|
|
598
|
-
font-weight: 700;
|
|
599
|
-
line-height: 1.2;
|
|
600
|
-
color: var(--text);
|
|
601
|
-
letter-spacing: -0.01em;
|
|
602
|
-
}
|
|
603
|
-
.wna-body {
|
|
604
|
-
font-size: 15px;
|
|
605
|
-
line-height: 1.7;
|
|
606
|
-
color: var(--text);
|
|
607
|
-
}
|
|
608
|
-
.wna-body p {
|
|
609
|
-
margin: 0 0 18px;
|
|
610
|
-
}
|
|
611
|
-
.wna-body p:last-child { margin-bottom: 0; }
|
|
612
|
-
.wna-body h3 {
|
|
613
|
-
margin: 36px 0 12px;
|
|
614
|
-
font-size: 18px;
|
|
615
|
-
font-weight: 600;
|
|
616
|
-
color: var(--text);
|
|
617
|
-
letter-spacing: -0.005em;
|
|
618
|
-
}
|
|
619
|
-
.wna-body ul, .wna-body ol {
|
|
620
|
-
margin: 0 0 18px;
|
|
621
|
-
padding-left: 22px;
|
|
622
|
-
}
|
|
623
|
-
.wna-body li {
|
|
624
|
-
margin-bottom: 8px;
|
|
625
|
-
}
|
|
626
|
-
.wna-body code {
|
|
627
|
-
padding: 2px 6px;
|
|
628
|
-
border-radius: 4px;
|
|
629
|
-
background: var(--code-bg);
|
|
630
|
-
color: var(--accent);
|
|
631
|
-
font-size: 13px;
|
|
632
|
-
font-family: "Roboto Mono", monospace;
|
|
633
|
-
}
|
|
634
|
-
.wna-body strong { color: var(--text); font-weight: 600; }
|
|
635
|
-
.wna-body em { color: var(--text-secondary); }
|
|
636
|
-
.wna-body a { color: var(--accent2); }
|
|
637
|
-
.wna-body a:hover { text-decoration: underline; }
|
|
638
|
-
@media (max-width: 640px) {
|
|
639
|
-
.wna-content { padding: 32px 20px 80px; }
|
|
640
|
-
.wna-title { font-size: 26px; }
|
|
641
|
-
}
|
package/lib/public/index.html
CHANGED
|
@@ -124,6 +124,7 @@
|
|
|
124
124
|
|
|
125
125
|
<!-- === Main Area (sidebar + resize-handle + main-column) === -->
|
|
126
126
|
<div id="main-area">
|
|
127
|
+
<section id="projects-hub" class="hidden" aria-label="Projects"></section>
|
|
127
128
|
<div id="home-hub" class="hidden">
|
|
128
129
|
<div class="home-hub-inner">
|
|
129
130
|
<button id="home-sidebar-backdrop" class="home-sidebar-backdrop" type="button" aria-label="Close Home navigation"></button>
|
|
@@ -136,6 +137,7 @@
|
|
|
136
137
|
</div>
|
|
137
138
|
</div>
|
|
138
139
|
<nav class="home-sidebar-primary-actions" aria-label="Home actions">
|
|
140
|
+
<button id="home-nav-projects" class="home-sidebar-action" type="button" title="Projects" aria-label="Projects"><span class="home-sidebar-action-icon" aria-hidden="true"><i data-lucide="folder"></i></span><span>Projects</span></button>
|
|
139
141
|
<button id="home-sidebar-new" class="home-sidebar-action home-sidebar-new" type="button" title="New Chat" aria-label="Start a new chat with the current Mate" disabled><span class="home-sidebar-action-icon" aria-hidden="true"><i data-lucide="message-square-plus"></i></span><span>New Chat</span></button>
|
|
140
142
|
<button id="home-sidebar-debate" class="home-sidebar-action" type="button" title="Browse debates" aria-label="Browse debates" aria-pressed="false"><span class="home-sidebar-action-icon" aria-hidden="true"><i data-lucide="messages-square"></i></span><span>Debates</span></button>
|
|
141
143
|
<button id="home-tools-btn" class="home-sidebar-action" type="button" title="Capsules" aria-label="Capsules" aria-expanded="false" aria-controls="home-tool-workbench"><span class="home-sidebar-action-icon" aria-hidden="true"><i data-lucide="box"></i></span><span id="home-tools-label">Capsules</span><span id="home-tools-activity" class="home-tools-activity" aria-hidden="true"></span></button>
|
|
@@ -157,7 +159,7 @@
|
|
|
157
159
|
</aside>
|
|
158
160
|
<div id="home-workspace" class="home-workspace">
|
|
159
161
|
<button id="home-sidebar-expand" class="home-sidebar-expand" type="button" title="Show sidebar" aria-label="Show Home sidebar" aria-describedby="home-sidebar-expand-brand-label"><i data-lucide="panel-left-open"></i><span id="home-sidebar-expand-brand-label" class="home-sidebar-brand-wordmark home-sidebar-expand-wordmark">Clay Studio</span></button>
|
|
160
|
-
<button id="home-close-control" class="home-close-control
|
|
162
|
+
<button id="home-close-control" class="home-close-control" type="button" title="Projects" aria-label="Projects"><i data-lucide="folder" aria-hidden="true"></i><span>Projects</span></button>
|
|
161
163
|
<div id="home-conversation-region" class="home-conversation-region">
|
|
162
164
|
<div id="home-mate-chat" class="home-mate-chat">
|
|
163
165
|
<div class="home-mate-chat-stage">
|
|
@@ -216,19 +218,6 @@
|
|
|
216
218
|
</div>
|
|
217
219
|
</div>
|
|
218
220
|
|
|
219
|
-
<div id="whats-new-article" class="hidden">
|
|
220
|
-
<header class="wna-toolbar">
|
|
221
|
-
<button type="button" class="wna-back" id="wna-back">
|
|
222
|
-
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>
|
|
223
|
-
<span>Back</span>
|
|
224
|
-
</button>
|
|
225
|
-
</header>
|
|
226
|
-
<article class="wna-content">
|
|
227
|
-
<div class="wna-date" id="wna-date"></div>
|
|
228
|
-
<h1 class="wna-title" id="wna-title"></h1>
|
|
229
|
-
<div class="wna-body" id="wna-body"></div>
|
|
230
|
-
</article>
|
|
231
|
-
</div>
|
|
232
221
|
<div id="sidebar-column">
|
|
233
222
|
<div class="title-bar-sidebar">
|
|
234
223
|
<button class="title-bar-project-dropdown" id="title-bar-project-dropdown">
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// app-home-hub.js - Home work hub navigation and first-depth Mate list.
|
|
2
2
|
|
|
3
|
+
import { showProjectsHub, hideProjectsHub } from './projects-hub.js';
|
|
3
4
|
import { store } from './store.js';
|
|
4
5
|
import { getWs } from './ws-ref.js';
|
|
5
6
|
import { getCachedProjects, switchProject } from './app-projects.js';
|
|
@@ -42,7 +43,7 @@ function syncHomePresentation() {
|
|
|
42
43
|
function syncHomeCloseControl() {
|
|
43
44
|
var close = document.getElementById("home-close-control");
|
|
44
45
|
if (!close) return;
|
|
45
|
-
close.classList.
|
|
46
|
+
close.classList.remove("hidden");
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
function getHomeReturnSlug() {
|
|
@@ -245,7 +246,8 @@ export function initHomeHub() {
|
|
|
245
246
|
initHomeDock();
|
|
246
247
|
initHomeDebatesArchive();
|
|
247
248
|
document.getElementById("home-mate-list").addEventListener("keydown", handleMateListKeydown);
|
|
248
|
-
document.getElementById("home-close-control").addEventListener("click",
|
|
249
|
+
document.getElementById("home-close-control").addEventListener("click", function () { showProjectsHub(); });
|
|
250
|
+
document.getElementById("home-nav-projects").addEventListener("click", function () { showProjectsHub(); });
|
|
249
251
|
window.addEventListener("clay:home-debate", function () { hideHomeHub(); });
|
|
250
252
|
document.addEventListener("visibilitychange", syncHomePresentation);
|
|
251
253
|
|
|
@@ -349,6 +351,8 @@ export function updateHomeIconBadge() {
|
|
|
349
351
|
}
|
|
350
352
|
|
|
351
353
|
export function showHomeHub(fromHistory) {
|
|
354
|
+
hideProjectsHub();
|
|
355
|
+
store.set({ pendingHomeProjectSlug: null });
|
|
352
356
|
if (store.get('dmMode')) exitDmMode();
|
|
353
357
|
var activeMateId = store.get('homeChatMateId');
|
|
354
358
|
var resume = homeHubSuspended || homeHubVisible;
|
|
@@ -399,7 +403,8 @@ export function hideHomeHub() {
|
|
|
399
403
|
|
|
400
404
|
export function minimizeHomeHub() {
|
|
401
405
|
var slug = getHomeReturnSlug();
|
|
402
|
-
if (!
|
|
406
|
+
if (!homeHubVisible) return;
|
|
407
|
+
if (!slug) { showProjectsHub(); return; }
|
|
403
408
|
switchProject(slug);
|
|
404
409
|
var projectInput = document.getElementById("input");
|
|
405
410
|
if (projectInput && !projectInput.disabled) projectInput.focus({ preventScroll: true });
|
|
@@ -69,8 +69,6 @@ import { clearPairResultStatus, handlePairResultStatus } from './pair-result-sta
|
|
|
69
69
|
import { scrollToBottom, addToMessages, addUserMessage, addSystemMessage, removeMatePreThinking, appendDelta, finalizeAssistantBlock, addConflictMessage, addContextOverflowMessage, showSuggestionChips, armStickyBottom, VENDOR_AVATARS, VENDOR_NAMES } from './app-rendering.js';
|
|
70
70
|
import { setActivity, startUrgentBlink, stopUrgentBlink, blinkSessionDot, updateCrossProjectBlink } from './app-favicon.js';
|
|
71
71
|
import { setStatus } from './app-connection.js';
|
|
72
|
-
import { handleWhatsNewState, handleWhatsNewSeenResult, setKnownEntries as setWhatsNewKnownEntries } from './whats-new.js';
|
|
73
|
-
import { closeArticle as closeWhatsNewArticle } from './whats-new-article.js';
|
|
74
72
|
import { resolvePaneSession, resolveSwitchedVendor } from './pane-session.js';
|
|
75
73
|
import { markProjectSessionListHydrated, applyProjectSplitGroups, clearProjectSplitState } from './split-session-boundary.js';
|
|
76
74
|
import { selectDefaultVendorForBlankSession } from './vendor-selection.js';
|
|
@@ -837,7 +835,6 @@ export function processMessage(msg) {
|
|
|
837
835
|
case "session_switched":
|
|
838
836
|
clearPairResultStatus();
|
|
839
837
|
syncAutonomousRunForSession(msg.autonomousRun || null);
|
|
840
|
-
closeWhatsNewArticle();
|
|
841
838
|
// Save draft from outgoing session
|
|
842
839
|
var _prevSid = store.get('activeSessionId');
|
|
843
840
|
if (_prevSid && inputEl.value) {
|
|
@@ -2127,18 +2124,6 @@ export function processMessage(msg) {
|
|
|
2127
2124
|
handleAutoContinueChanged(msg);
|
|
2128
2125
|
break;
|
|
2129
2126
|
|
|
2130
|
-
case "whats_new_state":
|
|
2131
|
-
// Keep a known-entries cache for the home page feed (which shows
|
|
2132
|
-
// both seen and unseen entries), then queue unseen ones for the
|
|
2133
|
-
// carousel.
|
|
2134
|
-
if (msg && Array.isArray(msg.entries)) setWhatsNewKnownEntries(msg.entries);
|
|
2135
|
-
handleWhatsNewState(msg);
|
|
2136
|
-
break;
|
|
2137
|
-
|
|
2138
|
-
case "whats_new_seen_result":
|
|
2139
|
-
handleWhatsNewSeenResult(msg);
|
|
2140
|
-
break;
|
|
2141
|
-
|
|
2142
2127
|
case "set_claude_open_mode_result":
|
|
2143
2128
|
case "claude_open_mode_changed":
|
|
2144
2129
|
if (msg.claudeOpenMode === "tui" || msg.claudeOpenMode === "gui") {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// app-projects.js - Project list, switching, add/remove project modals
|
|
2
2
|
// Extracted from app.js (PR-29)
|
|
3
3
|
|
|
4
|
+
import { showProjectsHub, hideProjectsHub, completeProjectsOnboarding } from './projects-hub.js';
|
|
4
5
|
import { escapeHtml, showToast } from './utils.js';
|
|
5
6
|
import { refreshIcons } from './icons.js';
|
|
6
7
|
import { parseEmojis } from './markdown.js';
|
|
@@ -17,7 +18,6 @@ import { spawnDustParticles } from './sidebar.js';
|
|
|
17
18
|
import { isSearchOpen, closeSearch } from './session-search.js';
|
|
18
19
|
import { exitDmMode } from './app-dm.js';
|
|
19
20
|
import { isHomeHubVisible, hideHomeHub, showHomeHub } from './app-home-hub.js';
|
|
20
|
-
import { closeArticle as closeWhatsNewArticle } from './whats-new-article.js';
|
|
21
21
|
import { resetFileBrowser } from './filebrowser.js';
|
|
22
22
|
import { closeNotesBrowser } from './sticky-notes-browser.js';
|
|
23
23
|
import { hideMemory } from './mate-memory.js';
|
|
@@ -203,7 +203,7 @@ export function initProjects() {
|
|
|
203
203
|
// --- State accessors ---
|
|
204
204
|
|
|
205
205
|
export function getCachedProjects() { return cachedProjects; }
|
|
206
|
-
export function setCachedProjects(v) { cachedProjects = v; }
|
|
206
|
+
export function setCachedProjects(v) { cachedProjects = v; store.set({ projectsHubList: v, projectListLoaded: true }); }
|
|
207
207
|
export function getCachedProjectCount() { return cachedProjectCount; }
|
|
208
208
|
export function setCachedProjectCount(v) { cachedProjectCount = v; }
|
|
209
209
|
export function getCachedRemovedProjects() { return cachedRemovedProjects; }
|
|
@@ -223,6 +223,7 @@ export function updateProjectList(msg) {
|
|
|
223
223
|
_lastProjectsJson = projectsJson;
|
|
224
224
|
}
|
|
225
225
|
cachedProjects = msg.projects;
|
|
226
|
+
store.set({ projectsHubList: cachedProjects, projectListLoaded: true });
|
|
226
227
|
}
|
|
227
228
|
if (msg.removedProjects) cachedRemovedProjects = msg.removedProjects;
|
|
228
229
|
else if (msg.removedProjects === undefined) { /* keep cached */ }
|
|
@@ -424,15 +425,16 @@ export function switchProject(slug) {
|
|
|
424
425
|
var st = store.snap();
|
|
425
426
|
var ws = getWs();
|
|
426
427
|
var targetWsPath = projectWsPath(slug);
|
|
427
|
-
var homeVisible = isHomeHubVisible();
|
|
428
|
+
var homeVisible = isHomeHubVisible() || store.get('projectsHubVisible');
|
|
428
429
|
var alreadyInProject = isProjectActivated(st, slug, ws);
|
|
429
430
|
var wasDm = st.dmMode;
|
|
430
431
|
var wasMate = st.dmMode && st.dmTargetUser && st.dmTargetUser.isMate;
|
|
431
432
|
if (st.dmMode) exitDmMode(wasMate);
|
|
432
|
-
closeWhatsNewArticle();
|
|
433
433
|
if (homeVisible && alreadyInProject) {
|
|
434
434
|
rememberHomePrimarySurface("project", slug);
|
|
435
435
|
hideHomeHub();
|
|
436
|
+
hideProjectsHub();
|
|
437
|
+
completeProjectsOnboarding();
|
|
436
438
|
if (document.documentElement.classList.contains("pwa-standalone")) {
|
|
437
439
|
history.replaceState(null, "", "/p/" + slug + "/");
|
|
438
440
|
} else {
|
|
@@ -473,6 +475,8 @@ export function completePendingProjectActivation() {
|
|
|
473
475
|
var slug = store.get('pendingHomeProjectSlug');
|
|
474
476
|
if (!slug || !isProjectActivated(store.snap(), slug, getWs())) return false;
|
|
475
477
|
store.set({ pendingHomeProjectSlug: null });
|
|
478
|
+
hideProjectsHub();
|
|
479
|
+
completeProjectsOnboarding();
|
|
476
480
|
rememberHomePrimarySurface("project", slug);
|
|
477
481
|
if (document.documentElement.classList.contains("pwa-standalone")) {
|
|
478
482
|
history.replaceState(null, "", "/p/" + slug + "/");
|
|
@@ -492,7 +496,7 @@ export function confirmCurrentProjectSessionActivation() {
|
|
|
492
496
|
export function finishProjectSessionActivation() {
|
|
493
497
|
var confirmed = confirmCurrentProjectSessionActivation();
|
|
494
498
|
if (!confirmed) return false;
|
|
495
|
-
if (!store.get('pendingHomeProjectSlug')) return
|
|
499
|
+
if (!store.get('pendingHomeProjectSlug')) return !isHomeHubVisible() && !store.get('projectsHubVisible');
|
|
496
500
|
return completePendingProjectActivation();
|
|
497
501
|
}
|
|
498
502
|
|
|
@@ -639,7 +643,7 @@ export function handleRemoveProjectResult(msg) {
|
|
|
639
643
|
});
|
|
640
644
|
}
|
|
641
645
|
}
|
|
642
|
-
cachedProjects
|
|
646
|
+
setCachedProjects(cachedProjects.filter(function (p) { return p.slug !== msg.slug; }));
|
|
643
647
|
cachedProjectCount = cachedProjects.length;
|
|
644
648
|
store.set({ currentSlug: null });
|
|
645
649
|
renderProjectList();
|
|
@@ -648,7 +652,9 @@ export function handleRemoveProjectResult(msg) {
|
|
|
648
652
|
if (targetSlug) {
|
|
649
653
|
switchProject(targetSlug);
|
|
650
654
|
} else {
|
|
651
|
-
|
|
655
|
+
store.set({ wsPath: "/ws", basePath: "/", activeProjectSlug: null });
|
|
656
|
+
showProjectsHub();
|
|
657
|
+
connect();
|
|
652
658
|
}
|
|
653
659
|
} else {
|
|
654
660
|
showToast(msg.slug.indexOf("--") !== -1 ? "Worktree removed" : "Project removed", "success");
|
|
@@ -698,7 +704,7 @@ function switchAddProjectMode(mode) {
|
|
|
698
704
|
}, 50);
|
|
699
705
|
}
|
|
700
706
|
|
|
701
|
-
export function openAddProjectModal() {
|
|
707
|
+
export function openAddProjectModal(mode) {
|
|
702
708
|
addProjectModal.classList.remove("hidden");
|
|
703
709
|
addProjectCreateInput.value = "";
|
|
704
710
|
addProjectCloneInput.value = "";
|
|
@@ -738,6 +744,7 @@ export function openAddProjectModal() {
|
|
|
738
744
|
existingBtn.disabled = false;
|
|
739
745
|
switchAddProjectMode("existing");
|
|
740
746
|
}
|
|
747
|
+
if (mode === "create" || mode === "clone") switchAddProjectMode(mode);
|
|
741
748
|
renderRemovedProjectsList();
|
|
742
749
|
}
|
|
743
750
|
|
|
@@ -855,10 +862,8 @@ export function handleAddProjectResult(msg) {
|
|
|
855
862
|
} else {
|
|
856
863
|
var toastMsg = addProjectMode === "create" ? "Project created" : addProjectMode === "clone" ? "Project cloned" : "Project added";
|
|
857
864
|
showToast(toastMsg, "success");
|
|
858
|
-
if (msg.slug) {
|
|
859
|
-
switchProject(msg.slug);
|
|
860
|
-
}
|
|
861
865
|
}
|
|
866
|
+
if (msg.slug) switchProject(msg.slug);
|
|
862
867
|
} else {
|
|
863
868
|
addProjectError.textContent = msg.error || "Failed to add project";
|
|
864
869
|
addProjectError.classList.remove("hidden");
|
|
@@ -12,13 +12,18 @@ function explicitProjectPath(pathname) {
|
|
|
12
12
|
export function resolveHomeBootDestination(options) {
|
|
13
13
|
if (!options) return "wait";
|
|
14
14
|
if (options.paneMode || explicitProjectPath(options.pathname)) return "project";
|
|
15
|
+
if (/^\/projects\/?$/.test(options.pathname || "")) return "projects";
|
|
15
16
|
// The server-selected project embedded in the root shell is authoritative.
|
|
16
17
|
// Home is entered only through an explicit in-app action; reloading `/`
|
|
17
18
|
// returns to the project workspace even if Home was the last open surface.
|
|
18
19
|
if (options.currentSlug) return "project";
|
|
19
20
|
if (options.surfaceLoaded !== true) return "wait";
|
|
20
|
-
if (options.
|
|
21
|
-
|
|
21
|
+
if (options.projectsLoaded !== true) return "wait";
|
|
22
|
+
if (options.surface === "home") {
|
|
23
|
+
if (options.dockLoaded !== true) return "wait";
|
|
24
|
+
return "home";
|
|
25
|
+
}
|
|
26
|
+
return "projects";
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
function finishPendingShell() {
|
|
@@ -35,6 +40,7 @@ function settleBoot(state) {
|
|
|
35
40
|
if (resolved) return;
|
|
36
41
|
var destination = resolveHomeBootDestination({
|
|
37
42
|
surfaceLoaded: state.homeSurfaceLoaded,
|
|
43
|
+
projectsLoaded: state.projectListLoaded,
|
|
38
44
|
dockLoaded: state.homeDockPreferenceLoaded,
|
|
39
45
|
surface: state.homePrimarySurface,
|
|
40
46
|
currentSlug: state.currentSlug,
|
|
@@ -55,7 +61,8 @@ function settleBoot(state) {
|
|
|
55
61
|
if (input && !input.disabled) input.focus({ preventScroll: true });
|
|
56
62
|
return;
|
|
57
63
|
}
|
|
58
|
-
store.set({ homeSurfaceBootResolved: true,
|
|
64
|
+
if (destination === "projects") store.set({ homeSurfaceBootResolved: true, projectsHubRestoreRequested: true });
|
|
65
|
+
else store.set({ homeSurfaceBootResolved: true, homeSurfaceRestoreRequested: true });
|
|
59
66
|
finishPendingShell();
|
|
60
67
|
}
|
|
61
68
|
|