xtralab 0.4.0 → 0.6.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.
Files changed (96) hide show
  1. package/README.md +110 -73
  2. package/lib/agentSessions.d.ts +50 -0
  3. package/lib/agentSessions.js +45 -0
  4. package/lib/fileBrowser/index.js +5 -1
  5. package/lib/git/commands.d.ts +12 -13
  6. package/lib/git/commands.js +7 -28
  7. package/lib/git/diffProvider.d.ts +8 -0
  8. package/lib/git/diffProvider.js +314 -0
  9. package/lib/git/diffSurface.d.ts +115 -0
  10. package/lib/git/diffSurface.js +342 -0
  11. package/lib/git/diffWidget.d.ts +8 -13
  12. package/lib/git/diffWidget.js +65 -311
  13. package/lib/git/imageDiff.d.ts +23 -0
  14. package/lib/git/imageDiff.js +256 -0
  15. package/lib/git/index.d.ts +10 -8
  16. package/lib/git/index.js +37 -52
  17. package/lib/index.d.ts +4 -2
  18. package/lib/index.js +14 -8
  19. package/lib/launcher/agents.d.ts +1 -1
  20. package/lib/launcher/agents.js +22 -13
  21. package/lib/launcher/commands.d.ts +32 -6
  22. package/lib/launcher/commands.js +81 -57
  23. package/lib/launcher/dashboard.d.ts +15 -0
  24. package/lib/launcher/dashboard.js +119 -5
  25. package/lib/launcher/editorRegistry.d.ts +43 -0
  26. package/lib/launcher/editorRegistry.js +96 -0
  27. package/lib/launcher/editors.d.ts +78 -0
  28. package/lib/launcher/editors.js +110 -0
  29. package/lib/launcher/icons.d.ts +25 -6
  30. package/lib/launcher/icons.js +116 -19
  31. package/lib/launcher/index.d.ts +2 -22
  32. package/lib/launcher/index.js +48 -25
  33. package/lib/launcher/registry.d.ts +21 -0
  34. package/lib/launcher/registry.js +28 -0
  35. package/lib/launcher/tokens.d.ts +41 -0
  36. package/lib/launcher/tokens.js +17 -0
  37. package/lib/terminals/detection.d.ts +11 -0
  38. package/lib/terminals/detection.js +50 -0
  39. package/lib/terminals/index.d.ts +27 -0
  40. package/lib/terminals/index.js +194 -0
  41. package/lib/terminals/model.d.ts +191 -0
  42. package/lib/terminals/model.js +418 -0
  43. package/lib/terminals/widget.d.ts +72 -0
  44. package/lib/terminals/widget.js +93 -0
  45. package/lib/topBar/icons.d.ts +13 -0
  46. package/lib/topBar/icons.js +27 -0
  47. package/lib/topBar/index.d.ts +16 -0
  48. package/lib/topBar/index.js +86 -0
  49. package/package.json +52 -35
  50. package/schema/launcher.json +56 -1
  51. package/src/agentSessions.ts +94 -0
  52. package/src/fileBrowser/index.ts +5 -1
  53. package/src/git/commands.ts +12 -38
  54. package/src/git/diffProvider.tsx +462 -0
  55. package/src/git/diffSurface.tsx +588 -0
  56. package/src/git/diffWidget.tsx +105 -465
  57. package/src/git/imageDiff.tsx +469 -0
  58. package/src/git/index.ts +38 -68
  59. package/src/index.ts +14 -8
  60. package/src/launcher/agents.ts +23 -14
  61. package/src/launcher/commands.ts +98 -60
  62. package/src/launcher/dashboard.tsx +205 -3
  63. package/src/launcher/editorRegistry.ts +149 -0
  64. package/src/launcher/editors.ts +183 -0
  65. package/src/launcher/icons.ts +120 -20
  66. package/src/launcher/index.ts +62 -27
  67. package/src/launcher/registry.ts +33 -0
  68. package/src/launcher/tokens.ts +51 -0
  69. package/src/terminals/detection.ts +65 -0
  70. package/src/terminals/index.ts +222 -0
  71. package/src/terminals/model.ts +497 -0
  72. package/src/terminals/widget.tsx +240 -0
  73. package/src/topBar/icons.ts +30 -0
  74. package/src/topBar/index.ts +121 -0
  75. package/style/git.css +267 -266
  76. package/style/index.css +2 -1
  77. package/style/index.js +2 -1
  78. package/style/launcher.css +124 -2
  79. package/style/terminals.css +235 -0
  80. package/style/topBar.css +38 -0
  81. package/lib/git/icons.d.ts +0 -14
  82. package/lib/git/icons.js +0 -19
  83. package/lib/git/panel.d.ts +0 -29
  84. package/lib/git/panel.js +0 -42
  85. package/lib/git/panelComponent.d.ts +0 -28
  86. package/lib/git/panelComponent.js +0 -320
  87. package/lib/statusBar/index.d.ts +0 -14
  88. package/lib/statusBar/index.js +0 -89
  89. package/lib/statusBar/widget.d.ts +0 -121
  90. package/lib/statusBar/widget.js +0 -237
  91. package/src/git/icons.ts +0 -20
  92. package/src/git/panel.tsx +0 -56
  93. package/src/git/panelComponent.tsx +0 -575
  94. package/src/statusBar/index.ts +0 -115
  95. package/src/statusBar/widget.tsx +0 -318
  96. package/style/statusBar.css +0 -95
package/style/git.css CHANGED
@@ -1,272 +1,10 @@
1
1
  /*
2
- * Styles for the git changes panel and the diff viewer. The panel mirrors
3
- * the visual rhythm of the default JupyterLab side panels so it does not
4
- * stand out from the rest of the UI.
2
+ * Styles for xtralab's @pierre/diffs viewer. The same surface is used by
3
+ * the launcher dashboard's own diff tab and by the jupyterlab-git diff
4
+ * providers, so these rules cover both hosts. (xtralab no longer ships a
5
+ * git changes panel — the upstream jupyterlab-git panel is reused.)
5
6
  */
6
7
 
7
- .jp-xtralab-GitPanel {
8
- display: flex;
9
- flex-direction: column;
10
- min-width: 240px;
11
- background-color: var(--jp-layout-color1);
12
- color: var(--jp-ui-font-color1);
13
- font-family: var(--jp-ui-font-family);
14
- font-size: var(--jp-ui-font-size1);
15
- overflow: hidden;
16
- }
17
-
18
- .jp-xtralab-GitPanel-content {
19
- display: flex;
20
- flex-direction: column;
21
- flex: 1 1 auto;
22
- min-height: 0;
23
- overflow-y: auto;
24
- }
25
-
26
- .jp-xtralab-GitPanel-header {
27
- display: flex;
28
- align-items: flex-start;
29
- gap: 8px;
30
- padding: 8px 12px;
31
- border-bottom: 1px solid var(--jp-border-color2);
32
- }
33
-
34
- .jp-xtralab-GitPanel-headerInfo {
35
- display: flex;
36
- flex-direction: column;
37
- gap: 2px;
38
- flex: 1 1 auto;
39
- min-width: 0;
40
- }
41
-
42
- .jp-xtralab-GitPanel-repo {
43
- font-weight: 600;
44
- white-space: nowrap;
45
- overflow: hidden;
46
- text-overflow: ellipsis;
47
- }
48
-
49
- .jp-xtralab-GitPanel-branch {
50
- color: var(--jp-ui-font-color2);
51
- font-size: var(--jp-ui-font-size0);
52
- }
53
-
54
- .jp-xtralab-GitPanel-error {
55
- margin: 12px;
56
- padding: 8px;
57
- border-radius: 4px;
58
- background-color: var(
59
- --jp-error-color3,
60
- var(--jp-rendermime-error-background)
61
- );
62
- color: var(--jp-ui-font-color1);
63
- font-size: var(--jp-ui-font-size1);
64
- white-space: pre-wrap;
65
- }
66
-
67
- .jp-xtralab-GitPanel-empty {
68
- margin: 12px;
69
- color: var(--jp-ui-font-color2);
70
- font-style: italic;
71
- text-align: center;
72
- }
73
-
74
- .jp-xtralab-GitPanel-section {
75
- display: flex;
76
- flex-direction: column;
77
- }
78
-
79
- /*
80
- * Section headers and rows place their hover actions between the label
81
- * and the trailing count/badge, so the count stays pinned to the right
82
- * edge regardless of whether the section has any bulk actions. Reserving
83
- * the action width via `visibility: hidden` keeps the layout from
84
- * shifting when the cursor enters and leaves.
85
- */
86
- .jp-xtralab-GitPanel-sectionHeader {
87
- display: flex;
88
- align-items: center;
89
- gap: 4px;
90
- height: 28px;
91
- padding: 0 12px;
92
- cursor: pointer;
93
- user-select: none;
94
- text-transform: uppercase;
95
- font-size: var(--jp-ui-font-size0);
96
- font-weight: 600;
97
- letter-spacing: 0.04em;
98
- color: var(--jp-ui-font-color2);
99
- }
100
-
101
- .jp-xtralab-GitPanel-sectionHeader:hover {
102
- background-color: var(--jp-layout-color2);
103
- }
104
-
105
- .jp-xtralab-GitPanel-sectionChevron {
106
- width: 12px;
107
- text-align: center;
108
- font-size: 10px;
109
- }
110
-
111
- .jp-xtralab-GitPanel-sectionLabel {
112
- flex: 1 1 auto;
113
- }
114
-
115
- .jp-xtralab-GitPanel-sectionCount {
116
- display: inline-flex;
117
- align-items: center;
118
- justify-content: center;
119
- min-width: 18px;
120
- height: 16px;
121
- padding: 0 4px;
122
- background-color: var(--jp-layout-color3);
123
- color: var(--jp-ui-font-color1);
124
- border-radius: 8px;
125
- font-size: var(--jp-ui-font-size0);
126
- font-weight: 500;
127
- line-height: 1;
128
- }
129
-
130
- .jp-xtralab-GitPanel-sectionActions {
131
- display: inline-flex;
132
- align-items: center;
133
- gap: 4px;
134
- visibility: hidden;
135
- }
136
-
137
- .jp-xtralab-GitPanel-sectionHeader:hover .jp-xtralab-GitPanel-sectionActions {
138
- visibility: visible;
139
- }
140
-
141
- .jp-xtralab-GitPanel-sectionBody {
142
- display: flex;
143
- flex-direction: column;
144
- }
145
-
146
- /*
147
- * Three-column row layout: the label group on the left grows, the actions
148
- * column has a fixed reserved width that fits the worst-case button count,
149
- * and the badge column is auto-sized on the right edge. Reserving the
150
- * action column keeps the badge horizontally pinned regardless of the
151
- * row's hover state.
152
- */
153
- .jp-xtralab-GitPanel-row {
154
- display: flex;
155
- align-items: center;
156
- gap: 6px;
157
- height: 26px;
158
- padding: 0 12px;
159
- cursor: pointer;
160
- user-select: none;
161
- }
162
-
163
- .jp-xtralab-GitPanel-row:hover {
164
- background-color: var(--jp-layout-color2);
165
- }
166
-
167
- .jp-xtralab-GitPanel-rowLabel {
168
- display: flex;
169
- align-items: baseline;
170
- gap: 6px;
171
- flex: 1 1 auto;
172
- min-width: 0;
173
- overflow: hidden;
174
- }
175
-
176
- .jp-xtralab-GitPanel-rowName {
177
- white-space: nowrap;
178
- overflow: hidden;
179
- text-overflow: ellipsis;
180
- flex: 0 1 auto;
181
- }
182
-
183
- .jp-xtralab-GitPanel-rowPath {
184
- color: var(--jp-ui-font-color2);
185
- font-size: var(--jp-ui-font-size0);
186
- white-space: nowrap;
187
- overflow: hidden;
188
- text-overflow: ellipsis;
189
- flex: 0 1 auto;
190
- }
191
-
192
- .jp-xtralab-GitPanel-rowActions {
193
- /*
194
- * Reserved width matches the worst case of two 20px buttons + a 2px
195
- * gap. Staged rows only host the unstage button, but pinning the
196
- * column width keeps the trailing badge horizontally aligned across
197
- * the staged and unstaged sections.
198
- */
199
- display: inline-flex;
200
- align-items: center;
201
- justify-content: flex-end;
202
- gap: 2px;
203
- flex: 0 0 42px;
204
- visibility: hidden;
205
- }
206
-
207
- .jp-xtralab-GitPanel-row:hover .jp-xtralab-GitPanel-rowActions,
208
- .jp-xtralab-GitPanel-rowActions[data-pending='true'] {
209
- visibility: visible;
210
- }
211
-
212
- .jp-xtralab-GitPanel-rowBadge {
213
- display: inline-flex;
214
- align-items: center;
215
- justify-content: center;
216
- flex: 0 0 16px;
217
- width: 16px;
218
- height: 16px;
219
- border-radius: 2px;
220
- font-size: var(--jp-ui-font-size0);
221
- font-weight: 600;
222
- font-family: var(--jp-code-font-family);
223
- }
224
-
225
- .jp-xtralab-GitPanel-rowBadge[data-status='modified'] {
226
- color: var(--jp-warn-color1);
227
- }
228
-
229
- .jp-xtralab-GitPanel-rowBadge[data-status='added'],
230
- .jp-xtralab-GitPanel-rowBadge[data-status='untracked'] {
231
- color: var(--jp-success-color1);
232
- }
233
-
234
- .jp-xtralab-GitPanel-rowBadge[data-status='deleted'] {
235
- color: var(--jp-error-color1);
236
- }
237
-
238
- .jp-xtralab-GitPanel-rowBadge[data-status='renamed'] {
239
- color: var(--jp-info-color1, var(--jp-brand-color1));
240
- }
241
-
242
- .jp-xtralab-GitPanel-rowBadge[data-status='unmerged'] {
243
- color: var(--jp-error-color1);
244
- }
245
-
246
- .jp-xtralab-GitPanel-iconButton {
247
- display: inline-flex;
248
- align-items: center;
249
- justify-content: center;
250
- width: 20px;
251
- height: 20px;
252
- border: none;
253
- background: transparent;
254
- color: var(--jp-ui-font-color1);
255
- cursor: pointer;
256
- border-radius: 2px;
257
- font-size: var(--jp-ui-font-size1);
258
- line-height: 1;
259
- }
260
-
261
- .jp-xtralab-GitPanel-iconButton:hover {
262
- background-color: var(--jp-layout-color3);
263
- }
264
-
265
- .jp-xtralab-GitPanel-iconButton:disabled {
266
- opacity: 0.4;
267
- cursor: default;
268
- }
269
-
270
8
  /*
271
9
  * Diff viewer (main area). The `MainAreaWidget` holding the React content
272
10
  * gets sized by JupyterLab's box layout; the inner content div fills it
@@ -763,3 +501,266 @@
763
501
  white-space: pre-wrap;
764
502
  word-break: break-word;
765
503
  }
504
+
505
+ /*
506
+ * Image diff (raster files). xtralab's replacement for the upstream
507
+ * jupyterlab-git image diff: a sticky mode selector (reusing the diff
508
+ * segmented-control styling) over the 2-up / swipe / onion-skin views.
509
+ *
510
+ * Every mode is sized to *fit the widget*: the images are contained
511
+ * within the available area (never upscaled past their natural size, and
512
+ * scaled down to fit when larger) so nothing overflows. In particular the
513
+ * swipe/onion slider stays on screen even when the two revisions have very
514
+ * different dimensions. A neutral checkerboard sits behind each image so
515
+ * transparency reads clearly in both light and dark themes.
516
+ */
517
+ .jp-xtralab-ImageDiff {
518
+ display: flex;
519
+ flex-direction: column;
520
+ width: 100%;
521
+ height: 100%;
522
+ }
523
+
524
+ .jp-xtralab-ImageDiff-header {
525
+ flex: 0 0 auto;
526
+ display: flex;
527
+ justify-content: center;
528
+ padding: 8px;
529
+ background-color: var(--jp-layout-color1);
530
+ border-bottom: 1px solid var(--jp-border-color2);
531
+ }
532
+
533
+ /*
534
+ * The body fills the remaining height and never scrolls — each view is a
535
+ * flex child that fits inside it (`min-height: 0` lets the flex/grid
536
+ * children shrink below their intrinsic size so `max-height` on the
537
+ * images can take effect).
538
+ */
539
+ .jp-xtralab-ImageDiff-body {
540
+ flex: 1 1 auto;
541
+ min-height: 0;
542
+ display: flex;
543
+ overflow: hidden;
544
+ padding: 16px;
545
+ }
546
+
547
+ .jp-xtralab-ImageDiff-twoUp {
548
+ flex: 1 1 auto;
549
+ min-height: 0;
550
+ display: flex;
551
+ gap: 16px;
552
+ }
553
+
554
+ .jp-xtralab-ImageDiff-col {
555
+ flex: 1 1 0;
556
+ min-width: 0;
557
+ min-height: 0;
558
+ display: flex;
559
+ flex-direction: column;
560
+ align-items: center;
561
+ gap: 8px;
562
+ margin: 0;
563
+ }
564
+
565
+ .jp-xtralab-ImageDiff-frame,
566
+ .jp-xtralab-ImageDiff-stack {
567
+ /* Checkerboard so transparent regions are obvious; theme-neutral. */
568
+ background-color: #fff;
569
+ background-image:
570
+ linear-gradient(45deg, #c8c8c8 25%, transparent 25%),
571
+ linear-gradient(-45deg, #c8c8c8 25%, transparent 25%),
572
+ linear-gradient(45deg, transparent 75%, #c8c8c8 75%),
573
+ linear-gradient(-45deg, transparent 75%, #c8c8c8 75%);
574
+ background-size: 16px 16px;
575
+ background-position:
576
+ 0 0,
577
+ 0 8px,
578
+ 8px -8px,
579
+ -8px 0;
580
+ border: 1px solid var(--jp-border-color2);
581
+ }
582
+
583
+ .jp-xtralab-ImageDiff-frame {
584
+ flex: 1 1 auto;
585
+ min-height: 0;
586
+ width: 100%;
587
+ display: flex;
588
+ align-items: center;
589
+ justify-content: center;
590
+ padding: 4px;
591
+ }
592
+
593
+ .jp-xtralab-ImageDiff-img {
594
+ display: block;
595
+ max-width: 100%;
596
+ max-height: 100%;
597
+ width: auto;
598
+ height: auto;
599
+ object-fit: contain;
600
+ }
601
+
602
+ .jp-xtralab-ImageDiff-empty {
603
+ padding: 32px 24px;
604
+ color: var(--jp-ui-font-color2);
605
+ font-size: var(--jp-ui-font-size1);
606
+ font-style: italic;
607
+ }
608
+
609
+ .jp-xtralab-ImageDiff-caption {
610
+ flex: 0 0 auto;
611
+ color: var(--jp-ui-font-color2);
612
+ font-size: var(--jp-ui-font-size0);
613
+ font-family: var(--jp-code-font-family);
614
+ text-align: center;
615
+ word-break: break-word;
616
+ }
617
+
618
+ .jp-xtralab-ImageDiff-interactive {
619
+ flex: 1 1 auto;
620
+ min-height: 0;
621
+ display: flex;
622
+ flex-direction: column;
623
+ align-items: center;
624
+ gap: 12px;
625
+ }
626
+
627
+ /*
628
+ * Both revisions occupy the same grid cell so swipe/onion can overlay
629
+ * them. `place-items: center` keeps each image at its own size (no
630
+ * stretching the smaller revision up to the larger one's box) while
631
+ * `max-height/width` scale either one down to fit the available space.
632
+ */
633
+ .jp-xtralab-ImageDiff-stack {
634
+ flex: 1 1 auto;
635
+ min-height: 0;
636
+ min-width: 0;
637
+ width: 100%;
638
+ display: grid;
639
+ place-items: center;
640
+ padding: 4px;
641
+ }
642
+
643
+ .jp-xtralab-ImageDiff-stackImg {
644
+ grid-area: 1 / 1;
645
+ display: block;
646
+ max-width: 100%;
647
+ max-height: 100%;
648
+ width: auto;
649
+ height: auto;
650
+ object-fit: contain;
651
+ }
652
+
653
+ /*
654
+ * Swipe view wraps the stack in a positioning context so the divider
655
+ * can be overlaid without joining the grid. Keeping the divider as a
656
+ * sibling of `.jp-xtralab-ImageDiff-stack` (rather than a child)
657
+ * preserves the stack's existing flex sizing — it stays the only flex
658
+ * item the interactive column needs to shrink, so `max-height: 100%`
659
+ * on the image still keeps big revisions inside the available area.
660
+ *
661
+ * The whole frame is the drag target: pressing anywhere over the image
662
+ * sets the divider to that x position and drag-tracks the pointer. The
663
+ * dedicated bottom slider was removed because its thumb sat on a
664
+ * narrow centered track that drifted out of sync with the wide
665
+ * divider, which felt off. Dragging directly on the image (GitHub /
666
+ * Pierre style) keeps cursor and divider visually aligned.
667
+ */
668
+ .jp-xtralab-ImageDiff-swipeFrame {
669
+ flex: 1 1 auto;
670
+ min-height: 0;
671
+ min-width: 0;
672
+ width: 100%;
673
+ position: relative;
674
+ display: flex;
675
+ user-select: none;
676
+ touch-action: none;
677
+ }
678
+
679
+ /*
680
+ * Swipe divider: a vertical line marking the boundary between the two
681
+ * clipped revisions. The natural seam between two clipped images is
682
+ * barely visible — especially on light content where it disappears into
683
+ * the background — so an explicit divider with high-contrast styling is
684
+ * drawn on top. White core with dark outline + soft shadow keeps it
685
+ * legible against any image, light or dark.
686
+ *
687
+ * The divider and its handles are the only elements that show the
688
+ * `ew-resize` cursor — clicks anywhere over the image still bubble up
689
+ * to the frame's drag handler, but the cursor only signals "drag me"
690
+ * over the actual control affordances.
691
+ */
692
+ .jp-xtralab-ImageDiff-swipeDivider {
693
+ position: absolute;
694
+ top: 0;
695
+ bottom: 0;
696
+ width: 2px;
697
+ margin-left: -1px;
698
+ background-color: #fff;
699
+ box-shadow:
700
+ 0 0 0 1px rgb(0 0 0 / 55%),
701
+ 0 0 6px rgb(0 0 0 / 45%);
702
+ cursor: ew-resize;
703
+ outline: none;
704
+ }
705
+
706
+ .jp-xtralab-ImageDiff-swipeDivider:focus-visible {
707
+ box-shadow:
708
+ 0 0 0 1px var(--jp-brand-color1),
709
+ 0 0 0 3px rgb(33 150 243 / 35%),
710
+ 0 0 6px rgb(0 0 0 / 45%);
711
+ }
712
+
713
+ /*
714
+ * Handle pucks at the top and bottom of the divider. The two arrows
715
+ * inside (left + right chevrons) signal that the line can be dragged
716
+ * sideways — matching GitHub's image diff swipe affordance.
717
+ */
718
+ .jp-xtralab-ImageDiff-swipeDividerHandle {
719
+ position: absolute;
720
+ left: 50%;
721
+ width: 28px;
722
+ height: 28px;
723
+ margin-left: -14px;
724
+ border-radius: 50%;
725
+ background-color: #fff;
726
+ box-shadow:
727
+ 0 0 0 1px rgb(0 0 0 / 55%),
728
+ 0 2px 6px rgb(0 0 0 / 40%);
729
+ display: flex;
730
+ align-items: center;
731
+ justify-content: center;
732
+ gap: 3px;
733
+ cursor: ew-resize;
734
+ }
735
+
736
+ .jp-xtralab-ImageDiff-swipeDividerHandle.jp-mod-top {
737
+ top: -14px;
738
+ }
739
+
740
+ .jp-xtralab-ImageDiff-swipeDividerHandle.jp-mod-bottom {
741
+ bottom: -14px;
742
+ }
743
+
744
+ /* Chevron triangles drawn with borders so no asset is needed. */
745
+ .jp-xtralab-ImageDiff-swipeDividerArrow {
746
+ width: 0;
747
+ height: 0;
748
+ border-style: solid;
749
+ }
750
+
751
+ .jp-xtralab-ImageDiff-swipeDividerArrow.jp-mod-left {
752
+ border-width: 5px 5px 5px 0;
753
+ border-color: transparent #333 transparent transparent;
754
+ }
755
+
756
+ .jp-xtralab-ImageDiff-swipeDividerArrow.jp-mod-right {
757
+ border-width: 5px 0 5px 5px;
758
+ border-color: transparent transparent transparent #333;
759
+ }
760
+
761
+ .jp-xtralab-ImageDiff-slider {
762
+ flex: 0 0 auto;
763
+ width: min(480px, 100%);
764
+ accent-color: var(--jp-brand-color1);
765
+ cursor: ew-resize;
766
+ }
package/style/index.css CHANGED
@@ -2,5 +2,6 @@
2
2
  @import url('editorBreadcrumbs.css');
3
3
  @import url('git.css');
4
4
  @import url('launcher.css');
5
- @import url('statusBar.css');
6
5
  @import url('tabs.css');
6
+ @import url('terminals.css');
7
+ @import url('topBar.css');
package/style/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import './base.css';
2
2
  import './git.css';
3
3
  import './launcher.css';
4
- import './statusBar.css';
5
4
  import './tabs.css';
5
+ import './terminals.css';
6
+ import './topBar.css';
@@ -58,7 +58,8 @@
58
58
  * that hosts the title, count badge, and refresh action; the disclosure
59
59
  * triangle is the browser default — it rotates when the section opens.
60
60
  */
61
- .jp-xtralab-Launcher-changes-section {
61
+ .jp-xtralab-Launcher-changes-section,
62
+ .jp-xtralab-Launcher-mcp-section {
62
63
  /* Reset the default `<details>` block so its contents inherit the
63
64
  section's gap-aligned column layout instead of stacking flush. */
64
65
  display: flex;
@@ -70,7 +71,7 @@
70
71
  display: flex;
71
72
  align-items: center;
72
73
  gap: 8px;
73
- list-style-position: outside;
74
+ list-style: none;
74
75
  cursor: pointer;
75
76
  user-select: none;
76
77
  padding: 2px 0;
@@ -86,6 +87,31 @@
86
87
  outline-offset: 1px;
87
88
  }
88
89
 
90
+ /*
91
+ * Disclosure caret. `display: flex` on the `<summary>` drops the browser's
92
+ * native triangle, so draw one (a CSS border triangle in `currentColor`) and
93
+ * rotate it from pointing right to pointing down when the section is open.
94
+ */
95
+ .jp-xtralab-Launcher-section-summary::-webkit-details-marker {
96
+ display: none;
97
+ }
98
+
99
+ .jp-xtralab-Launcher-section-summary::before {
100
+ content: '';
101
+ flex: 0 0 auto;
102
+ width: 0;
103
+ height: 0;
104
+ border-style: solid;
105
+ border-width: 4px 0 4px 6px;
106
+ border-color: transparent transparent transparent currentcolor;
107
+ transition: transform 120ms ease;
108
+ }
109
+
110
+ .jp-xtralab-Launcher-section[open]
111
+ > .jp-xtralab-Launcher-section-summary::before {
112
+ transform: rotate(90deg);
113
+ }
114
+
89
115
  .jp-xtralab-Launcher-section-count {
90
116
  display: inline-flex;
91
117
  align-items: center;
@@ -316,3 +342,99 @@
316
342
  font-weight: 500;
317
343
  text-align: center;
318
344
  }
345
+
346
+ /*
347
+ * MCP registration hint. A collapsed-by-default `<details>` listing the
348
+ * one-line `mcp add` command for each installed agent that supports one,
349
+ * each paired with a Copy button. The command sits in a read-only `<code>`
350
+ * box — the user copies it and runs it in their own terminal — so the row
351
+ * is not itself a button.
352
+ */
353
+
354
+ /*
355
+ * The MCP hint is an optional helper, not a primary section, so its summary
356
+ * is rendered lighter and in sentence case rather than reusing the bold,
357
+ * uppercase treatment of the `START AN AGENT` / `OPEN` headers — otherwise a
358
+ * collapsed disclosure reads as a misplaced top-level section.
359
+ */
360
+ .jp-xtralab-Launcher-mcp-section .jp-xtralab-Launcher-section-title {
361
+ font-weight: 500;
362
+ text-transform: none;
363
+ letter-spacing: normal;
364
+ }
365
+
366
+ .jp-xtralab-Launcher-mcp-list {
367
+ list-style: none;
368
+ margin: 0;
369
+ padding: 0;
370
+ display: flex;
371
+ flex-direction: column;
372
+ gap: 6px;
373
+ }
374
+
375
+ .jp-xtralab-Launcher-mcp-item {
376
+ display: flex;
377
+ align-items: center;
378
+ gap: 8px;
379
+ }
380
+
381
+ .jp-xtralab-Launcher-mcp-command {
382
+ flex: 1 1 auto;
383
+ min-width: 0;
384
+ padding: 6px 10px;
385
+ background-color: var(--jp-layout-color2);
386
+ border: 1px solid var(--jp-border-color2);
387
+ border-radius: 4px;
388
+ font-family: var(--jp-code-font-family);
389
+ font-size: var(--jp-code-font-size);
390
+ white-space: pre;
391
+ overflow-x: auto;
392
+ }
393
+
394
+ /*
395
+ * Copy buttons are sized to the longest label ("Copied!") and centered, so
396
+ * swapping "Copy" ↔ "Copied!" never resizes the button or ragged-aligns the
397
+ * column.
398
+ */
399
+ .jp-xtralab-Launcher-mcp-copy {
400
+ flex: 0 0 auto;
401
+ min-width: 4.5rem;
402
+ padding: 4px 12px;
403
+ text-align: center;
404
+ background-color: var(--jp-layout-color1);
405
+ color: var(--jp-ui-font-color1);
406
+ border: 1px solid var(--jp-border-color2);
407
+ border-radius: 4px;
408
+ cursor: pointer;
409
+ font: inherit;
410
+ font-size: var(--jp-ui-font-size0);
411
+ }
412
+
413
+ .jp-xtralab-Launcher-mcp-copy:hover {
414
+ background-color: var(--jp-layout-color2);
415
+ border-color: var(--jp-border-color1);
416
+ }
417
+
418
+ .jp-xtralab-Launcher-mcp-copy:focus-visible {
419
+ outline: 1px solid var(--jp-brand-color1);
420
+ outline-offset: 1px;
421
+ }
422
+
423
+ /* Confirmation state after a successful copy — a clear color shift, paired
424
+ with the button's "Copied!" label, so the action is unmistakable. */
425
+ .jp-xtralab-Launcher-mcp-copy.jp-mod-copied {
426
+ color: var(--jp-success-color1, var(--jp-ui-font-color1));
427
+ border-color: var(--jp-success-color1, var(--jp-border-color1));
428
+ }
429
+
430
+ .jp-xtralab-Launcher-mcp-note {
431
+ margin: 4px 0 0;
432
+ color: var(--jp-ui-font-color3);
433
+ font-size: var(--jp-ui-font-size0);
434
+ line-height: 1.4;
435
+ }
436
+
437
+ .jp-xtralab-Launcher-mcp-note code {
438
+ font-family: var(--jp-code-font-family);
439
+ font-size: var(--jp-code-font-size);
440
+ }