clay-server 2.34.0-beta.8 → 2.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -285,8 +285,7 @@
285
285
  /* --- Tools section --- */
286
286
  #sidebar-tools {
287
287
  flex-shrink: 0;
288
- border-bottom: 1px solid var(--border-subtle);
289
- padding-bottom: 4px;
288
+ padding-bottom: 6px;
290
289
  }
291
290
 
292
291
  /* Section header: "Tools" label on the left, a dim keyboard-hint next
@@ -404,17 +403,24 @@
404
403
  padding: 6px 2px;
405
404
  border-radius: 10px;
406
405
  border: none;
407
- background: transparent;
406
+ background: rgba(var(--overlay-rgb), 0.025);
408
407
  color: var(--text-muted);
409
408
  font-family: inherit;
410
409
  font-size: 10px;
411
410
  font-weight: 500;
412
411
  cursor: pointer;
413
- transition: background 0.15s, color 0.15s;
412
+ transition: background 0.15s, color 0.15s, box-shadow 0.15s;
414
413
  }
415
414
  .palette-tile .lucide { width: 16px; height: 16px; flex-shrink: 0; }
416
- .palette-tile:hover { background: var(--sidebar-hover); color: var(--text-secondary); }
417
- .palette-tile.active { background: var(--sidebar-hover); color: var(--text); }
415
+ .palette-tile:hover {
416
+ background: rgba(var(--overlay-rgb), 0.08);
417
+ color: var(--text-secondary);
418
+ box-shadow: 0 2px 10px rgba(var(--shadow-rgb), 0.08);
419
+ }
420
+ .palette-tile.active {
421
+ background: rgba(var(--overlay-rgb), 0.08);
422
+ color: var(--text);
423
+ }
418
424
  .palette-tile .tool-btn-label {
419
425
  font-size: 10px;
420
426
  font-weight: 500;
@@ -585,78 +591,107 @@
585
591
  flex-shrink: 0;
586
592
  }
587
593
 
588
- .session-list-header {
594
+ .sidebar-sessions-header-row {
589
595
  display: flex;
590
596
  align-items: center;
591
- justify-content: space-between;
592
- padding: 8px 8px 4px 12px;
593
- font-size: 11px;
594
- font-weight: 600;
595
- color: var(--text-dimmer);
596
- text-transform: uppercase;
597
- letter-spacing: 0.5px;
597
+ padding: 4px 8px 2px 12px;
598
+ gap: 8px;
598
599
  }
599
600
 
600
- .session-list-header-actions {
601
- display: flex;
601
+ /* --- Session search --- */
602
+ .sidebar-sessions-search-inline {
603
+ position: relative;
604
+ margin-left: auto;
605
+ width: 150px;
606
+ }
607
+
608
+ .sidebar-sessions-search-inline.hidden {
609
+ display: none;
610
+ }
611
+
612
+ .sidebar-sessions-header-row .sidebar-section-label {
613
+ padding: 0;
614
+ }
615
+
616
+ .session-filter-count {
617
+ display: inline-flex;
602
618
  align-items: center;
603
- gap: 2px;
619
+ justify-content: center;
620
+ min-width: 18px;
621
+ height: 18px;
622
+ padding: 0 6px;
623
+ border-radius: 999px;
624
+ background: rgba(var(--overlay-rgb), 0.08);
625
+ color: var(--text-dimmer);
626
+ font-size: 10px;
627
+ font-weight: 600;
628
+ line-height: 1;
604
629
  }
605
630
 
606
- .session-list-header-actions button {
607
- display: flex;
631
+ .session-filter-count.hidden {
632
+ display: none;
633
+ }
634
+
635
+ .sidebar-sessions-header-row > #session-header-search-btn {
636
+ margin-left: auto;
637
+ display: inline-flex;
608
638
  align-items: center;
609
639
  justify-content: center;
610
640
  width: 22px;
611
641
  height: 22px;
612
- border-radius: 6px;
613
642
  border: none;
643
+ border-radius: 6px;
614
644
  background: transparent;
615
645
  color: var(--text-dimmer);
616
646
  cursor: pointer;
617
647
  padding: 0;
618
- transition: color 0.15s, background 0.15s;
648
+ opacity: 0.45;
649
+ transition: color 0.15s, background 0.15s, opacity 0.15s;
619
650
  }
620
651
 
621
- .session-list-header-actions button .lucide { width: 14px; height: 14px; }
622
- .session-list-header-actions button:hover { color: var(--text); background: var(--sidebar-hover); }
652
+ .sidebar-sessions-header-row > #session-header-search-btn.active,
653
+ .sidebar-sessions-header-row > #session-header-search-btn:hover {
654
+ color: var(--text);
655
+ background: var(--sidebar-hover);
656
+ opacity: 1;
657
+ }
623
658
 
624
- /* --- Session search --- */
625
- #session-search {
626
- padding: 0 12px 8px;
627
- position: relative;
659
+ .sidebar-sessions-header-row > #session-header-search-btn .lucide,
660
+ .sidebar-sessions-header-row > #session-header-search-btn svg {
661
+ width: 14px;
662
+ height: 14px;
628
663
  }
629
664
 
630
- #session-search.hidden {
631
- display: none;
665
+ .sidebar-sessions-search-inline:not(.hidden) + #session-header-search-btn {
666
+ margin-left: 0;
632
667
  }
633
668
 
634
- #session-search-input {
669
+ .sidebar-sessions-search-inline input {
635
670
  width: 100%;
636
- padding: 7px 28px 7px 10px;
671
+ padding: 6px 28px 6px 10px;
637
672
  border-radius: 8px;
638
673
  border: 1px solid var(--border);
639
674
  background: var(--input-bg);
640
675
  color: var(--text);
641
- font-size: 13px;
676
+ font-size: 12px;
642
677
  font-family: inherit;
643
678
  outline: none;
644
679
  transition: border-color 0.15s;
645
680
  box-sizing: border-box;
646
681
  }
647
682
 
648
- #session-search-input:focus {
683
+ .sidebar-sessions-search-inline input:focus {
649
684
  border-color: var(--accent);
650
685
  }
651
686
 
652
- #session-search-input::placeholder {
687
+ .sidebar-sessions-search-inline input::placeholder {
653
688
  color: var(--text-dimmer);
654
689
  }
655
690
 
656
- #session-search-clear {
691
+ .sidebar-sessions-search-inline button {
657
692
  position: absolute;
658
- right: 16px;
659
- top: calc(50% - 4px);
693
+ right: 6px;
694
+ top: 50%;
660
695
  transform: translateY(-50%);
661
696
  display: flex;
662
697
  align-items: center;
@@ -672,13 +707,13 @@
672
707
  transition: color 0.15s, background 0.15s;
673
708
  }
674
709
 
675
- #session-search-clear .lucide { width: 14px; height: 14px; }
676
- #session-search-clear:hover { color: var(--text); background: var(--sidebar-hover); }
677
-
678
- #search-session-btn.active {
679
- color: var(--accent);
710
+ .sidebar-sessions-search-inline button.hidden {
711
+ display: none;
680
712
  }
681
713
 
714
+ .sidebar-sessions-search-inline button .lucide { width: 14px; height: 14px; }
715
+ .sidebar-sessions-search-inline button:hover { color: var(--text); background: var(--sidebar-hover); }
716
+
682
717
  .session-item.search-match {
683
718
  background: var(--accent-12);
684
719
  color: var(--text);
@@ -688,10 +723,6 @@
688
723
  color: var(--accent);
689
724
  }
690
725
 
691
- .session-item.search-dimmed {
692
- opacity: 0.35;
693
- }
694
-
695
726
  .session-highlight {
696
727
  background: var(--accent-30);
697
728
  color: var(--text);
@@ -700,15 +731,46 @@
700
731
  }
701
732
 
702
733
  #session-list {
703
- padding: 2px 8px;
734
+ padding: 0 8px 2px;
704
735
  }
705
736
 
706
737
  .session-group-header {
707
- padding: 10px 12px 4px;
708
- font-size: 11px;
738
+ display: flex;
739
+ align-items: center;
740
+ justify-content: space-between;
741
+ margin: 12px 8px 4px;
742
+ padding: 0;
743
+ min-height: 22px;
744
+ font-size: 10px;
709
745
  font-weight: 600;
710
746
  color: var(--text-dimmer);
711
- letter-spacing: 0.3px;
747
+ letter-spacing: 0.2px;
748
+ }
749
+
750
+ .session-group-header-label {
751
+ min-width: 0;
752
+ color: var(--text-dimmer);
753
+ }
754
+
755
+ .session-group-clear-btn {
756
+ border: none;
757
+ background: rgba(var(--overlay-rgb), 0.04);
758
+ color: var(--text-dimmer);
759
+ font-family: inherit;
760
+ font-size: 10px;
761
+ font-weight: 600;
762
+ cursor: pointer;
763
+ padding: 0 8px;
764
+ height: 20px;
765
+ border-radius: 999px;
766
+ letter-spacing: 0.2px;
767
+ opacity: 0.82;
768
+ transition: color 0.15s ease, background 0.15s ease;
769
+ }
770
+
771
+ .session-group-clear-btn:hover {
772
+ color: var(--text);
773
+ background: rgba(var(--overlay-rgb), 0.08);
712
774
  }
713
775
 
714
776
  /* --- Schedule countdown items --- */
@@ -792,6 +854,26 @@
792
854
  font-weight: 600;
793
855
  }
794
856
 
857
+ .session-item.drag-over-above::before,
858
+ .session-item.drag-over-below::after {
859
+ content: "";
860
+ position: absolute;
861
+ left: 10px;
862
+ right: 10px;
863
+ height: 2px;
864
+ border-radius: 999px;
865
+ background: var(--accent);
866
+ pointer-events: none;
867
+ }
868
+
869
+ .session-item.drag-over-above::before {
870
+ top: -1px;
871
+ }
872
+
873
+ .session-item.drag-over-below::after {
874
+ bottom: -1px;
875
+ }
876
+
795
877
  .session-item .session-processing,
796
878
  .mate-session-item .session-processing {
797
879
  display: inline-block;
@@ -810,92 +892,226 @@
810
892
  box-shadow: 0 0 4px var(--success);
811
893
  }
812
894
 
813
- .session-bookmark-btn {
895
+ /* Session unread badge */
896
+ .session-unread-badge {
897
+ position: absolute;
898
+ right: 8px;
899
+ top: 50%;
900
+ transform: translateY(-50%);
901
+ min-width: 18px;
902
+ height: 18px;
903
+ border-radius: 9px;
904
+ background: #e74c3c;
905
+ color: #fff;
906
+ font-size: 11px;
907
+ font-weight: 700;
908
+ display: none;
909
+ align-items: center;
910
+ justify-content: center;
911
+ padding: 0 5px;
912
+ line-height: 18px;
913
+ text-align: center;
914
+ z-index: 2;
915
+ }
916
+
917
+ .session-item .session-item-text {
918
+ padding-right: 28px;
919
+ }
920
+
921
+ .session-item:has(.session-presence) .session-item-text {
922
+ padding-right: 54px;
923
+ }
924
+
925
+ .session-close-btn {
926
+ position: absolute;
927
+ right: 8px;
928
+ top: 50%;
929
+ transform: translateY(-50%);
814
930
  display: flex;
815
- width: 20px;
816
- height: 20px;
817
- border-radius: 6px;
931
+ align-items: center;
932
+ justify-content: center;
933
+ width: 18px;
934
+ height: 18px;
818
935
  border: none;
936
+ border-radius: 999px;
819
937
  background: transparent;
820
938
  color: var(--text-dimmer);
821
939
  cursor: pointer;
822
- align-items: center;
823
- justify-content: center;
824
940
  padding: 0;
825
- margin-right: 2px;
826
- flex-shrink: 0;
827
941
  opacity: 0;
828
- transition: opacity 0.2s ease, color 0.15s, background 0.15s;
942
+ pointer-events: none;
943
+ transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
829
944
  }
830
945
 
831
- .session-bookmark-btn.hover {
832
- position: absolute;
833
- right: 30px;
834
- top: 50%;
835
- transform: translateY(-50%);
946
+ .session-close-btn .lucide,
947
+ .session-close-btn svg {
948
+ width: 12px;
949
+ height: 12px;
950
+ display: block;
836
951
  }
837
952
 
838
- .session-bookmark-btn.inline {
839
- margin-right: 2px;
840
- flex-shrink: 0;
953
+ .session-item:hover .session-close-btn,
954
+ .session-loop-child:hover .session-close-btn,
955
+ .session-item:focus-within .session-close-btn,
956
+ .session-loop-child:focus-within .session-close-btn {
957
+ opacity: 0.82;
958
+ pointer-events: auto;
959
+ }
960
+
961
+ .session-close-btn:hover {
962
+ opacity: 1;
963
+ color: var(--text);
964
+ background: rgba(var(--overlay-rgb), 0.08);
965
+ }
966
+
967
+ .session-close-btn.armed {
968
+ opacity: 1;
969
+ pointer-events: auto;
970
+ width: 20px;
971
+ height: 20px;
972
+ color: #fff;
973
+ background: rgba(220, 38, 38, 0.92);
974
+ box-shadow: 0 2px 8px rgba(var(--shadow-rgb), 0.18);
841
975
  }
842
976
 
843
- .session-bookmark-btn .lucide,
844
- .session-bookmark-btn svg {
977
+ .session-close-btn.armed:hover {
978
+ color: #fff;
979
+ background: rgba(220, 38, 38, 1);
980
+ }
981
+
982
+ .session-close-btn.armed .lucide,
983
+ .session-close-btn.armed svg {
845
984
  width: 13px;
846
985
  height: 13px;
847
- display: block;
848
986
  }
849
987
 
850
- .session-item:hover .session-bookmark-btn.hover,
851
- .session-item:focus-within .session-bookmark-btn.hover,
852
- .session-bookmark-btn.bookmarked {
988
+ .session-item:hover .session-unread-badge,
989
+ .session-item:focus-within .session-unread-badge {
990
+ opacity: 0;
991
+ pointer-events: none;
992
+ }
993
+
994
+ .session-top-actions {
995
+ display: grid;
996
+ grid-template-columns: repeat(2, minmax(0, 1fr));
997
+ gap: 2px;
998
+ padding: 0 0 2px;
999
+ }
1000
+
1001
+ .session-top-action {
1002
+ display: flex;
1003
+ align-items: center;
1004
+ gap: 10px;
1005
+ width: 100%;
1006
+ min-height: 34px;
1007
+ padding: 0 12px;
1008
+ border: none;
1009
+ border-radius: 10px;
1010
+ background: transparent;
1011
+ color: var(--text-muted);
1012
+ font-family: inherit;
1013
+ font-size: 13px;
1014
+ font-weight: 500;
1015
+ cursor: pointer;
1016
+ text-align: left;
1017
+ min-width: 0;
1018
+ opacity: 0.62;
1019
+ transition: background 0.15s, color 0.15s, opacity 0.15s;
1020
+ }
1021
+
1022
+ .session-top-action .lucide,
1023
+ .session-top-action svg {
1024
+ width: 14px;
1025
+ height: 14px;
1026
+ flex-shrink: 0;
1027
+ }
1028
+
1029
+ .session-top-action:hover {
1030
+ background: var(--sidebar-hover);
1031
+ color: var(--text);
853
1032
  opacity: 1;
854
1033
  }
855
1034
 
856
- .session-bookmark-btn:hover {
857
- color: var(--accent);
858
- background: rgba(var(--overlay-rgb), 0.06);
1035
+ .session-favorites-section {
1036
+ min-height: 6px;
1037
+ margin: 0 8px;
1038
+ border-radius: 12px;
1039
+ transition: background 0.15s ease, box-shadow 0.15s ease;
859
1040
  }
860
1041
 
861
- .session-bookmark-btn.bookmarked {
862
- color: var(--accent);
1042
+ .session-favorites-empty {
1043
+ margin: 2px 0 0;
1044
+ padding: 6px 2px 2px;
1045
+ border: none;
1046
+ border-radius: 0;
1047
+ background: transparent;
1048
+ font-size: 11px;
1049
+ line-height: 1.4;
1050
+ color: color-mix(in srgb, var(--text-dimmer) 88%, transparent);
1051
+ text-align: center;
1052
+ text-shadow: 0 0 10px rgba(var(--shadow-rgb), 0.08);
863
1053
  }
864
1054
 
865
- .session-bookmark-btn.bookmarked .lucide,
866
- .session-bookmark-btn.bookmarked svg {
867
- fill: currentColor;
868
- stroke: currentColor;
1055
+ .session-list-sticky-top {
1056
+ position: sticky;
1057
+ top: 0;
1058
+ z-index: 3;
1059
+ background: var(--sidebar-bg);
869
1060
  }
870
1061
 
871
- /* Session unread badge */
872
- .session-unread-badge {
1062
+ .session-favorites-divider {
1063
+ position: relative;
1064
+ margin: 0 12px 2px;
1065
+ height: 18px;
1066
+ border-radius: 999px;
1067
+ }
1068
+
1069
+ .session-favorites-divider::before {
1070
+ content: "";
873
1071
  position: absolute;
874
- right: 8px;
1072
+ left: 0;
1073
+ right: 0;
875
1074
  top: 50%;
1075
+ height: 1px;
1076
+ background: var(--border-subtle, var(--border));
876
1077
  transform: translateY(-50%);
877
- min-width: 18px;
878
- height: 18px;
879
- border-radius: 9px;
880
- background: #e74c3c;
881
- color: #fff;
882
- font-size: 11px;
883
- font-weight: 700;
884
- display: none;
885
- align-items: center;
886
- justify-content: center;
887
- padding: 0 5px;
888
- line-height: 18px;
889
- text-align: center;
890
- z-index: 2;
891
1078
  }
892
1079
 
893
- .session-item .session-item-text {
894
- padding-right: 28px;
1080
+ .session-favorites-section.drag-hover,
1081
+ .session-regular-drop.drag-hover {
1082
+ background: color-mix(in srgb, var(--accent) 10%, transparent);
1083
+ }
1084
+
1085
+ .session-favorites-section.drag-hover {
1086
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
1087
+ }
1088
+
1089
+ .session-favorites-section.drag-hover .session-favorites-empty {
1090
+ background: transparent;
1091
+ color: var(--text);
1092
+ }
1093
+
1094
+ .session-favorites-divider.drag-hover::before {
1095
+ background: var(--accent);
1096
+ height: 2px;
1097
+ }
1098
+
1099
+ .session-regular-drop {
1100
+ min-height: 12px;
1101
+ border-radius: 12px;
1102
+ }
1103
+
1104
+ .session-item[draggable="true"] {
1105
+ -webkit-user-drag: element;
1106
+ }
1107
+
1108
+ .session-item.dragging {
1109
+ opacity: 0.45;
895
1110
  }
896
1111
 
897
1112
  .session-unread-badge.has-unread {
898
1113
  display: flex;
1114
+ transition: opacity 0.15s ease;
899
1115
  }
900
1116
 
901
1117
  .session-more-btn {
@@ -932,6 +1148,14 @@
932
1148
  margin-right: 2px;
933
1149
  }
934
1150
 
1151
+ .session-item .session-presence {
1152
+ position: absolute;
1153
+ right: 30px;
1154
+ top: 50%;
1155
+ transform: translateY(-50%);
1156
+ margin-right: 0;
1157
+ }
1158
+
935
1159
  .session-presence-avatar {
936
1160
  width: 18px;
937
1161
  height: 18px;
@@ -1155,6 +1379,7 @@
1155
1379
  display: flex;
1156
1380
  align-items: center;
1157
1381
  gap: 4px;
1382
+ padding-right: 22px;
1158
1383
  }
1159
1384
 
1160
1385
  .session-loop-child .session-processing {
@@ -197,17 +197,14 @@
197
197
  </div>
198
198
  <div id="sidebar-sessions-header">
199
199
  <div id="sessions-header-content">
200
- <div class="session-list-header">
201
- <span>Sessions</span>
202
- <div class="session-list-header-actions">
203
- <button id="new-session-btn" type="button" data-tip="New session"><i data-lucide="plus"></i></button>
204
- <button id="resume-session-btn" type="button" data-tip="Import CLI session"><i data-lucide="import"></i></button>
205
- <button id="search-session-btn" type="button" data-tip="Search sessions"><i data-lucide="search"></i></button>
200
+ <div class="sidebar-sessions-header-row">
201
+ <span class="sidebar-section-label">Sessions</span>
202
+ <span id="session-filter-count" class="session-filter-count hidden"></span>
203
+ <div id="session-header-search-inline" class="sidebar-sessions-search-inline hidden">
204
+ <input id="session-header-search-input" type="text" placeholder="Search sessions..." autocomplete="off" spellcheck="false" />
205
+ <button id="session-header-search-clear" type="button" aria-label="Clear search"><i data-lucide="x"></i></button>
206
206
  </div>
207
- </div>
208
- <div id="session-search" class="hidden">
209
- <input id="session-search-input" type="text" placeholder="Search sessions..." autocomplete="off" spellcheck="false" />
210
- <button id="session-search-clear" type="button" aria-label="Clear search"><i data-lucide="x"></i></button>
207
+ <button id="session-header-search-btn" type="button" aria-label="Search sessions" title="Search sessions"><i data-lucide="search"></i></button>
211
208
  </div>
212
209
  </div>
213
210
  <div id="files-header-content" class="hidden"></div>
@@ -238,25 +238,39 @@ export function renderSplitDiff(oldStr, newStr, lang) {
238
238
  * Parses hunk headers for line numbers. Optional lang for syntax highlighting.
239
239
  * Returns a DOM element.
240
240
  */
241
- export function renderPatchDiff(text, lang) {
241
+ /**
242
+ * Reconstruct old and new source text from a unified patch string.
243
+ * Skips file headers, "diff --git" lines, index lines, and hunk headers.
244
+ * Returns { oldStr, newStr }.
245
+ */
246
+ export function reconstructPatchSources(text) {
242
247
  var lines = text.split("\n");
243
-
244
- // Reconstruct old and new source for highlighting
245
248
  var oldSrc = [];
246
249
  var newSrc = [];
247
250
  for (var p = 0; p < lines.length; p++) {
248
251
  var pl = lines[p];
249
- if (pl.startsWith("-") && !pl.startsWith("---")) {
252
+ if (pl.startsWith("---") || pl.startsWith("+++")) continue;
253
+ if (pl.startsWith("diff ") || pl.startsWith("index ")) continue;
254
+ if (pl.startsWith("@@")) continue;
255
+ if (pl.startsWith("-")) {
250
256
  oldSrc.push(pl.substring(1));
251
- } else if (pl.startsWith("+") && !pl.startsWith("+++")) {
257
+ } else if (pl.startsWith("+")) {
252
258
  newSrc.push(pl.substring(1));
253
259
  } else if (pl.startsWith(" ")) {
254
260
  oldSrc.push(pl.substring(1));
255
261
  newSrc.push(pl.substring(1));
256
262
  }
257
263
  }
258
- var oldHL = highlightLines(oldSrc.join("\n"), lang);
259
- var newHL = highlightLines(newSrc.join("\n"), lang);
264
+ return { oldStr: oldSrc.join("\n"), newStr: newSrc.join("\n") };
265
+ }
266
+
267
+ export function renderPatchDiff(text, lang) {
268
+ var lines = text.split("\n");
269
+
270
+ // Reconstruct old and new source for highlighting
271
+ var sources = reconstructPatchSources(text);
272
+ var oldHL = highlightLines(sources.oldStr, lang);
273
+ var newHL = highlightLines(sources.newStr, lang);
260
274
  var oldHLIdx = 0;
261
275
  var newHLIdx = 0;
262
276