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
@@ -0,0 +1,235 @@
1
+ /*
2
+ * Left-sidebar panel listing running terminal sessions. Each row shows
3
+ * the session's real (program-published) title and an inline shutdown
4
+ * button that fades in on hover; the header carries the panel title and
5
+ * a "new terminal" button. Colors and spacing pull from `--jp-*` custom
6
+ * properties so the panel tracks the active JupyterLab theme.
7
+ */
8
+
9
+ .jp-xtralab-Terminals {
10
+ display: flex;
11
+ flex-direction: column;
12
+ min-width: 200px;
13
+ overflow: hidden;
14
+ background-color: var(--jp-layout-color1);
15
+ color: var(--jp-ui-font-color1);
16
+ font-size: var(--jp-ui-font-size1);
17
+ }
18
+
19
+ .jp-xtralab-Terminals-body {
20
+ display: flex;
21
+ flex: 1 1 auto;
22
+ flex-direction: column;
23
+ min-height: 0;
24
+ }
25
+
26
+ .jp-xtralab-Terminals-header {
27
+ display: flex;
28
+ flex: 0 0 auto;
29
+ align-items: center;
30
+ justify-content: space-between;
31
+ padding: 8px 12px;
32
+ border-bottom: var(--jp-border-width) solid var(--jp-border-color2);
33
+ }
34
+
35
+ .jp-xtralab-Terminals-title {
36
+ margin: 0;
37
+ font-size: var(--jp-ui-font-size0);
38
+ font-weight: 600;
39
+ letter-spacing: 1px;
40
+ text-transform: uppercase;
41
+ color: var(--jp-ui-font-color1);
42
+ }
43
+
44
+ .jp-xtralab-Terminals-actions {
45
+ display: flex;
46
+ flex: 0 0 auto;
47
+ align-items: center;
48
+ gap: 2px;
49
+ }
50
+
51
+ .jp-xtralab-Terminals-action {
52
+ display: flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ width: 20px;
56
+ height: 20px;
57
+ padding: 0;
58
+ background: transparent;
59
+ border: none;
60
+ border-radius: 2px;
61
+ color: var(--jp-ui-font-color2);
62
+ cursor: pointer;
63
+ }
64
+
65
+ .jp-xtralab-Terminals-action:hover {
66
+ background-color: var(--jp-layout-color2);
67
+ color: var(--jp-ui-font-color1);
68
+ }
69
+
70
+ .jp-xtralab-Terminals-action:focus-visible {
71
+ outline: var(--jp-border-width) solid var(--jp-brand-color1);
72
+ outline-offset: -1px;
73
+ }
74
+
75
+ /*
76
+ * "Shut down all" is disabled when there are no running terminals. Dim the
77
+ * whole control with opacity rather than `color`: the stop glyph is an SVG
78
+ * whose fill comes from its own `jp-icon3` class (not `currentColor`), so a
79
+ * `color` change alone leaves the icon looking fully active — which is why the
80
+ * button did not read as disabled.
81
+ */
82
+ .jp-xtralab-Terminals-action:disabled {
83
+ cursor: default;
84
+ opacity: 0.4;
85
+ }
86
+
87
+ .jp-xtralab-Terminals-action:disabled:hover {
88
+ background: transparent;
89
+ }
90
+
91
+ .jp-xtralab-Terminals-empty {
92
+ margin: 0;
93
+ padding: 12px;
94
+ color: var(--jp-ui-font-color2);
95
+ }
96
+
97
+ .jp-xtralab-Terminals-list {
98
+ flex: 1 1 auto;
99
+ margin: 0;
100
+ padding: 4px 0;
101
+ overflow-y: auto;
102
+ list-style: none;
103
+ }
104
+
105
+ .jp-xtralab-Terminals-item {
106
+ display: flex;
107
+ align-items: stretch;
108
+ height: 28px;
109
+ }
110
+
111
+ .jp-xtralab-Terminals-item:hover {
112
+ background-color: var(--jp-layout-color2);
113
+ }
114
+
115
+ /*
116
+ * The main click target: terminal icon + label, filling the row so the
117
+ * whole strip activates the session. The close button sits to its right
118
+ * and intercepts its own clicks via the React handler.
119
+ */
120
+ .jp-xtralab-Terminals-item-activate {
121
+ display: flex;
122
+ flex: 1 1 auto;
123
+ align-items: center;
124
+ gap: 6px;
125
+ min-width: 0;
126
+ padding: 0 4px 0 12px;
127
+ background: transparent;
128
+ border: none;
129
+ color: inherit;
130
+ font: inherit;
131
+ text-align: left;
132
+ cursor: pointer;
133
+ }
134
+
135
+ .jp-xtralab-Terminals-item-activate:focus-visible {
136
+ outline: var(--jp-border-width) solid var(--jp-brand-color1);
137
+ outline-offset: -2px;
138
+ }
139
+
140
+ .jp-xtralab-Terminals-item-label {
141
+ overflow: hidden;
142
+ text-overflow: ellipsis;
143
+ white-space: nowrap;
144
+ }
145
+
146
+ /*
147
+ * Close button. Hidden by default so the row reads as plain text; fades
148
+ * in when the row is hovered or the button itself takes focus.
149
+ */
150
+ .jp-xtralab-Terminals-item-close {
151
+ display: flex;
152
+ flex: 0 0 auto;
153
+ align-items: center;
154
+ justify-content: center;
155
+ width: 24px;
156
+ margin-right: 4px;
157
+ background: transparent;
158
+ border: none;
159
+ color: var(--jp-ui-font-color2);
160
+ cursor: pointer;
161
+ opacity: 0;
162
+ transition: opacity 80ms linear;
163
+ }
164
+
165
+ .jp-xtralab-Terminals-item-close:hover {
166
+ color: var(--jp-ui-font-color1);
167
+ }
168
+
169
+ .jp-xtralab-Terminals-item-close:focus-visible {
170
+ opacity: 1;
171
+ outline: var(--jp-border-width) solid var(--jp-brand-color1);
172
+ outline-offset: -2px;
173
+ }
174
+
175
+ /* Higher specificity than the bare-button rules above, so it comes
176
+ * last to keep stylelint's no-descending-specificity rule happy. */
177
+ .jp-xtralab-Terminals-item:hover .jp-xtralab-Terminals-item-close {
178
+ opacity: 1;
179
+ }
180
+
181
+ /* Keep the row/header icons at the standard 16px sidebar size. */
182
+ .jp-xtralab-Terminals-item svg,
183
+ .jp-xtralab-Terminals-action svg {
184
+ width: 16px;
185
+ height: 16px;
186
+ }
187
+
188
+ /*
189
+ * The terminal that is currently the active widget in the main area — the
190
+ * running-session counterpart of the file browser highlighting the open
191
+ * document. It reuses the file listing's brand-color treatment so "this is
192
+ * the focused terminal" reads at a glance, and the panel highlights nothing
193
+ * while a notebook (or any non-terminal widget) holds the focus instead.
194
+ * Driven from `widget.tsx` via the terminal tracker + the shell's current
195
+ * widget.
196
+ */
197
+ .jp-xtralab-Terminals-item.jp-mod-current {
198
+ color: var(--jp-ui-inverse-font-color1);
199
+ background-color: var(--jp-brand-color1);
200
+ }
201
+
202
+ /* Hovering the current row keeps the highlight rather than falling back to
203
+ * the neutral hover background. */
204
+ .jp-xtralab-Terminals-item.jp-mod-current:hover {
205
+ background-color: var(--jp-brand-color1);
206
+ }
207
+
208
+ /*
209
+ * Invert the monochrome terminal glyph against the brand background, exactly
210
+ * as the file listing does for its selected rows. Colored agent logos carry
211
+ * no selectable classes, so they keep their own colors.
212
+ */
213
+ .jp-xtralab-Terminals-item.jp-mod-current .jp-icon-selectable[fill] {
214
+ fill: #fff;
215
+ }
216
+
217
+ .jp-xtralab-Terminals-item.jp-mod-current .jp-icon-selectable-inverse[fill] {
218
+ fill: var(--jp-brand-color1);
219
+ }
220
+
221
+ /* Keep the inline shutdown button legible on the brand background, including
222
+ * while it is itself hovered. */
223
+ .jp-xtralab-Terminals-item.jp-mod-current .jp-xtralab-Terminals-item-close,
224
+ .jp-xtralab-Terminals-item.jp-mod-current
225
+ .jp-xtralab-Terminals-item-close:hover {
226
+ color: var(--jp-ui-inverse-font-color1);
227
+ }
228
+
229
+ /* Focus rings need a color that contrasts with the brand background. */
230
+ .jp-xtralab-Terminals-item.jp-mod-current
231
+ .jp-xtralab-Terminals-item-activate:focus-visible,
232
+ .jp-xtralab-Terminals-item.jp-mod-current
233
+ .jp-xtralab-Terminals-item-close:focus-visible {
234
+ outline-color: var(--jp-layout-color1);
235
+ }
@@ -0,0 +1,38 @@
1
+ /* Sidebar toggle buttons in the top bar (xtralab:top-bar). */
2
+
3
+ .xtralab-TopBarButton {
4
+ display: flex;
5
+ align-items: center;
6
+ }
7
+
8
+ /*
9
+ * The right-area button is added to the flex container `#jp-top-panel` after
10
+ * the main menu (a high rank). `margin-left: auto` consumes the free space to
11
+ * its left so it floats to the far right, mirroring the left button at the
12
+ * leading edge.
13
+ */
14
+ .xtralab-TopBarButton-right {
15
+ margin-left: auto;
16
+ }
17
+
18
+ /*
19
+ * The buttons are FAST `<jp-button appearance="stealth">` elements. The design
20
+ * system paints state chrome directly on the button host that reads as an
21
+ * unwanted box/border in the top bar (see
22
+ * `@jupyter/web-components/.../styles/patterns/button.js`):
23
+ * - `:host([aria-pressed='true'])` (the matching sidebar is open) adds an
24
+ * inset `box-shadow`;
25
+ * - `:host([disabled])` (e.g. the right area is empty) fills the host with
26
+ * `neutralFillRest`.
27
+ * Neutralize both so the control stays a flat icon like the menu.
28
+ * The hover/active stealth fills are left untouched as a normal affordance.
29
+ * `!important` is needed to override the (non-important) `:host(...)` rules
30
+ * defined inside the component's shadow DOM.
31
+ */
32
+ .xtralab-TopBarButton .jp-ToolbarButtonComponent {
33
+ box-shadow: none !important;
34
+ }
35
+
36
+ .xtralab-TopBarButton .jp-ToolbarButtonComponent[disabled] {
37
+ background: transparent !important;
38
+ }
@@ -1,14 +0,0 @@
1
- import { LabIcon } from '@jupyterlab/ui-components';
2
- /**
3
- * The branch glyph used as the git panel's sidebar tab icon. Defined as a
4
- * `LabIcon` (rather than a CSS-only mask) so it picks up JupyterLab's icon
5
- * recoloring and inverse-color sidebar painting automatically.
6
- *
7
- * Source: `git-branch` from SVG Repo (https://www.svgrepo.com/svg/377352/git-branch),
8
- * part of the same Pixelarticons family as the xtralab file browser's `file-tree`
9
- * icon, so the two sidebar tab glyphs read as a matched set. The original
10
- * `fill="#000000"` is replaced with `fill="currentColor"` and the root element
11
- * is given the `jp-icon3` class so the icon picks up JupyterLab's theme color
12
- * and the sidebar's inverse-color painting automatically.
13
- */
14
- export declare const gitIcon: LabIcon;
package/lib/git/icons.js DELETED
@@ -1,19 +0,0 @@
1
- import { LabIcon } from '@jupyterlab/ui-components';
2
- /**
3
- * The branch glyph used as the git panel's sidebar tab icon. Defined as a
4
- * `LabIcon` (rather than a CSS-only mask) so it picks up JupyterLab's icon
5
- * recoloring and inverse-color sidebar painting automatically.
6
- *
7
- * Source: `git-branch` from SVG Repo (https://www.svgrepo.com/svg/377352/git-branch),
8
- * part of the same Pixelarticons family as the xtralab file browser's `file-tree`
9
- * icon, so the two sidebar tab glyphs read as a matched set. The original
10
- * `fill="#000000"` is replaced with `fill="currentColor"` and the root element
11
- * is given the `jp-icon3` class so the icon picks up JupyterLab's theme color
12
- * and the sidebar's inverse-color painting automatically.
13
- */
14
- export const gitIcon = new LabIcon({
15
- name: 'xtralab:git',
16
- svgstr: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="jp-icon3" fill="currentColor">
17
- <path d="M5 2h2v12h3v3h7v-7h-3V2h8v8h-3v9h-9v3H2v-8h3V2zm15 6V4h-4v4h4zM8 19v-3H4v4h4v-1z"/>
18
- </svg>`
19
- });
@@ -1,29 +0,0 @@
1
- import * as React from 'react';
2
- import { ReactWidget } from '@jupyterlab/ui-components';
3
- import { ISignal } from '@lumino/signaling';
4
- import { IGitPanelHandlers } from './panelComponent';
5
- /**
6
- * The id and CSS class used for the git panel widget. The id ends up as the
7
- * sidebar tab id (so layout restoration can find the widget) and the CSS
8
- * class lets per-panel styles attach without leaking to other widgets.
9
- */
10
- export declare const GIT_PANEL_ID = "xtralab:git-panel";
11
- export declare const GIT_PANEL_CSS_CLASS = "jp-xtralab-GitPanel";
12
- /**
13
- * The lumino host widget for the git changes panel. Owns the `refresh`
14
- * signal that the React component listens to, and exposes a typed callback
15
- * surface (`handlers`) the React component uses to react to user actions.
16
- */
17
- export declare class GitPanel extends ReactWidget {
18
- constructor(handlers: IGitPanelHandlers);
19
- /**
20
- * Public refresh hook called by the plugin when something happened that
21
- * invalidates the current view (the user clicked the toolbar refresh, the
22
- * file browser refreshed, a focused notebook saved, …).
23
- */
24
- refresh(): void;
25
- get refreshRequested(): ISignal<this, void>;
26
- protected render(): React.ReactElement;
27
- private _handlers;
28
- private _refreshRequested;
29
- }
package/lib/git/panel.js DELETED
@@ -1,42 +0,0 @@
1
- import * as React from 'react';
2
- import { ReactWidget } from '@jupyterlab/ui-components';
3
- import { Signal } from '@lumino/signaling';
4
- import { gitIcon } from './icons';
5
- import { GitPanelComponent } from './panelComponent';
6
- /**
7
- * The id and CSS class used for the git panel widget. The id ends up as the
8
- * sidebar tab id (so layout restoration can find the widget) and the CSS
9
- * class lets per-panel styles attach without leaking to other widgets.
10
- */
11
- export const GIT_PANEL_ID = 'xtralab:git-panel';
12
- export const GIT_PANEL_CSS_CLASS = 'jp-xtralab-GitPanel';
13
- /**
14
- * The lumino host widget for the git changes panel. Owns the `refresh`
15
- * signal that the React component listens to, and exposes a typed callback
16
- * surface (`handlers`) the React component uses to react to user actions.
17
- */
18
- export class GitPanel extends ReactWidget {
19
- constructor(handlers) {
20
- super();
21
- this._refreshRequested = new Signal(this);
22
- this.id = GIT_PANEL_ID;
23
- this.title.icon = gitIcon;
24
- this.title.caption = 'Git Changes';
25
- this.addClass(GIT_PANEL_CSS_CLASS);
26
- this._handlers = handlers;
27
- }
28
- /**
29
- * Public refresh hook called by the plugin when something happened that
30
- * invalidates the current view (the user clicked the toolbar refresh, the
31
- * file browser refreshed, a focused notebook saved, …).
32
- */
33
- refresh() {
34
- this._refreshRequested.emit();
35
- }
36
- get refreshRequested() {
37
- return this._refreshRequested;
38
- }
39
- render() {
40
- return (React.createElement(GitPanelComponent, { handlers: this._handlers, refreshSignal: this._refreshRequested }));
41
- }
42
- }
@@ -1,28 +0,0 @@
1
- import * as React from 'react';
2
- import { ISignal } from '@lumino/signaling';
3
- import { IFileChange } from './tokens';
4
- /**
5
- * Callbacks the panel needs to delegate to (so the React component stays
6
- * free of any JupyterLab application coupling). The plugin wires these up
7
- * with the actual `JupyterFrontEnd` reference.
8
- */
9
- export interface IGitPanelHandlers {
10
- /** Open a diff viewer for the given file in the main area. */
11
- openDiff(change: IFileChange, options?: {
12
- pin?: boolean;
13
- }): void;
14
- /** Show a confirmation dialog. Returns true when the user accepted. */
15
- confirm(title: string, body: string, accept: string): Promise<boolean>;
16
- /** Show an error dialog. */
17
- showError(title: string, error: Error): Promise<void>;
18
- }
19
- /**
20
- * Top-level React component rendered inside the {@link GitPanel} widget.
21
- * Owns the polling + refresh wiring around the `/git/status` endpoint and
22
- * the small bit of UI state that controls section collapse and the
23
- * in-flight per-file action spinners.
24
- */
25
- export declare function GitPanelComponent(props: {
26
- handlers: IGitPanelHandlers;
27
- refreshSignal: ISignal<unknown, void>;
28
- }): React.ReactElement;