xtralab 0.15.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/README.md +10 -0
  2. package/lib/about/icons.d.ts +0 -5
  3. package/lib/about/icons.js +0 -5
  4. package/lib/about/index.d.ts +4 -8
  5. package/lib/about/index.js +6 -17
  6. package/lib/agentSessions.d.ts +9 -29
  7. package/lib/agentSessions.js +2 -7
  8. package/lib/askAgent/editorSelection.d.ts +20 -26
  9. package/lib/askAgent/editorSelection.js +11 -26
  10. package/lib/askAgent/icons.d.ts +2 -3
  11. package/lib/askAgent/icons.js +2 -3
  12. package/lib/askAgent/index.d.ts +4 -26
  13. package/lib/askAgent/index.js +54 -158
  14. package/lib/askAgent/popup.d.ts +12 -16
  15. package/lib/askAgent/popup.js +18 -37
  16. package/lib/askAgent/prompt.d.ts +3 -5
  17. package/lib/askAgent/prompt.js +6 -19
  18. package/lib/askAgent/queue.d.ts +11 -21
  19. package/lib/askAgent/queue.js +9 -19
  20. package/lib/askAgent/queuePanel.d.ts +13 -18
  21. package/lib/askAgent/queuePanel.js +15 -37
  22. package/lib/askAgent/targetPicker.d.ts +2 -9
  23. package/lib/askAgent/targetPicker.js +6 -11
  24. package/lib/askAgent/tokens.d.ts +32 -46
  25. package/lib/askAgent/tokens.js +4 -6
  26. package/lib/commandBar/index.d.ts +4 -13
  27. package/lib/commandBar/index.js +21 -39
  28. package/lib/customPanel/index.js +15 -0
  29. package/lib/editorBreadcrumbs/index.d.ts +3 -6
  30. package/lib/editorBreadcrumbs/index.js +10 -6
  31. package/lib/editorBreadcrumbs/widget.d.ts +17 -4
  32. package/lib/editorBreadcrumbs/widget.js +11 -17
  33. package/lib/editorIndent/index.d.ts +4 -12
  34. package/lib/editorIndent/index.js +8 -23
  35. package/lib/fileBrowser/commands.d.ts +28 -19
  36. package/lib/fileBrowser/commands.js +39 -98
  37. package/lib/fileBrowser/contents.d.ts +3 -0
  38. package/lib/fileBrowser/dragAndDrop.d.ts +17 -4
  39. package/lib/fileBrowser/dragAndDrop.js +2 -7
  40. package/lib/fileBrowser/fileBrowser.d.ts +19 -9
  41. package/lib/fileBrowser/fileBrowser.js +68 -216
  42. package/lib/fileBrowser/gitStatus.d.ts +4 -9
  43. package/lib/fileBrowser/gitStatus.js +7 -17
  44. package/lib/fileBrowser/gitignore.d.ts +4 -17
  45. package/lib/fileBrowser/gitignore.js +4 -25
  46. package/lib/fileBrowser/icons.d.ts +7 -17
  47. package/lib/fileBrowser/icons.js +25 -80
  48. package/lib/fileBrowser/index.js +2 -4
  49. package/lib/fileBrowser/widget.d.ts +126 -48
  50. package/lib/fileBrowser/widget.js +89 -4
  51. package/lib/fileTypeIcons/index.js +0 -10
  52. package/lib/git/api.d.ts +5 -13
  53. package/lib/git/api.js +10 -36
  54. package/lib/git/askRequest.d.ts +4 -8
  55. package/lib/git/askRequest.js +6 -20
  56. package/lib/git/commands.d.ts +40 -5
  57. package/lib/git/commands.js +16 -10
  58. package/lib/git/diffModel.js +4 -0
  59. package/lib/git/diffSurface.d.ts +41 -55
  60. package/lib/git/diffSurface.js +42 -117
  61. package/lib/git/diffWidget.d.ts +81 -2
  62. package/lib/git/diffWidget.js +62 -12
  63. package/lib/git/imageDiff.d.ts +5 -6
  64. package/lib/git/imageDiff.js +18 -48
  65. package/lib/git/index.d.ts +0 -3
  66. package/lib/git/index.js +3 -8
  67. package/lib/git/notebookDiff.d.ts +110 -33
  68. package/lib/git/notebookDiff.js +52 -195
  69. package/lib/git/tokens.d.ts +73 -31
  70. package/lib/git/tokens.js +2 -3
  71. package/lib/highlight/index.d.ts +4 -10
  72. package/lib/highlight/index.js +10 -41
  73. package/lib/index.d.ts +0 -9
  74. package/lib/index.js +0 -9
  75. package/lib/launcher/agents.d.ts +55 -51
  76. package/lib/launcher/agents.js +15 -57
  77. package/lib/launcher/availability.d.ts +3 -9
  78. package/lib/launcher/availability.js +3 -9
  79. package/lib/launcher/commands.d.ts +7 -32
  80. package/lib/launcher/commands.js +14 -45
  81. package/lib/launcher/dashboard.d.ts +19 -24
  82. package/lib/launcher/dashboard.js +21 -67
  83. package/lib/launcher/editorRegistry.d.ts +10 -22
  84. package/lib/launcher/editorRegistry.js +14 -18
  85. package/lib/launcher/editors.d.ts +39 -45
  86. package/lib/launcher/editors.js +8 -34
  87. package/lib/launcher/icons.d.ts +0 -12
  88. package/lib/launcher/icons.js +5 -39
  89. package/lib/launcher/index.js +12 -55
  90. package/lib/launcher/invocation.d.ts +4 -10
  91. package/lib/launcher/invocation.js +7 -22
  92. package/lib/launcher/registry.d.ts +9 -7
  93. package/lib/launcher/registry.js +9 -7
  94. package/lib/launcher/tokens.d.ts +10 -22
  95. package/lib/launcher/tokens.js +5 -8
  96. package/lib/menuBar/index.d.ts +3 -10
  97. package/lib/menuBar/index.js +11 -28
  98. package/lib/menus/index.d.ts +3 -9
  99. package/lib/menus/index.js +14 -30
  100. package/lib/omnibox/files.d.ts +2 -4
  101. package/lib/omnibox/files.js +5 -11
  102. package/lib/omnibox/index.d.ts +4 -14
  103. package/lib/omnibox/index.js +9 -27
  104. package/lib/omnibox/model.d.ts +38 -10
  105. package/lib/omnibox/model.js +15 -33
  106. package/lib/omnibox/recents.d.ts +15 -17
  107. package/lib/omnibox/recents.js +12 -17
  108. package/lib/omnibox/tokens.d.ts +5 -10
  109. package/lib/omnibox/tokens.js +2 -6
  110. package/lib/omnibox/widget.d.ts +11 -7
  111. package/lib/omnibox/widget.js +8 -16
  112. package/lib/searchReplace/index.d.ts +4 -20
  113. package/lib/searchReplace/index.js +7 -27
  114. package/lib/showOutput/index.d.ts +3 -12
  115. package/lib/showOutput/index.js +6 -22
  116. package/lib/sidebar/index.d.ts +4 -7
  117. package/lib/sidebar/index.js +5 -12
  118. package/lib/terminalNotifications/index.d.ts +4 -10
  119. package/lib/terminalNotifications/index.js +6 -20
  120. package/lib/terminals/agentTerminals.d.ts +12 -5
  121. package/lib/terminals/agentTerminals.js +25 -44
  122. package/lib/terminals/detection.d.ts +4 -8
  123. package/lib/terminals/detection.js +4 -8
  124. package/lib/terminals/index.d.ts +0 -35
  125. package/lib/terminals/index.js +12 -101
  126. package/lib/terminals/model.d.ts +64 -139
  127. package/lib/terminals/model.js +80 -220
  128. package/lib/terminals/tokens.d.ts +11 -22
  129. package/lib/terminals/tokens.js +2 -2
  130. package/lib/terminals/widget.d.ts +43 -13
  131. package/lib/terminals/widget.js +33 -18
  132. package/lib/topBar/icons.d.ts +3 -8
  133. package/lib/topBar/icons.js +3 -8
  134. package/lib/topBar/index.d.ts +4 -11
  135. package/lib/topBar/index.js +10 -38
  136. package/lib/walkthrough/index.d.ts +4 -9
  137. package/lib/walkthrough/index.js +6 -20
  138. package/lib/walkthrough/panel.d.ts +40 -9
  139. package/lib/walkthrough/panel.js +4 -10
  140. package/package.json +2 -2
  141. package/src/about/icons.ts +0 -5
  142. package/src/about/index.tsx +6 -17
  143. package/src/agentSessions.ts +9 -29
  144. package/src/askAgent/editorSelection.ts +22 -29
  145. package/src/askAgent/icons.ts +2 -3
  146. package/src/askAgent/index.ts +54 -158
  147. package/src/askAgent/popup.tsx +23 -45
  148. package/src/askAgent/prompt.ts +6 -19
  149. package/src/askAgent/queue.ts +13 -24
  150. package/src/askAgent/queuePanel.tsx +21 -46
  151. package/src/askAgent/targetPicker.tsx +5 -15
  152. package/src/askAgent/tokens.ts +32 -46
  153. package/src/commandBar/index.ts +24 -39
  154. package/src/customPanel/index.ts +15 -0
  155. package/src/editorBreadcrumbs/index.ts +10 -6
  156. package/src/editorBreadcrumbs/widget.ts +23 -17
  157. package/src/editorIndent/index.ts +17 -23
  158. package/src/fileBrowser/commands.ts +57 -98
  159. package/src/fileBrowser/contents.ts +3 -0
  160. package/src/fileBrowser/dragAndDrop.ts +17 -7
  161. package/src/fileBrowser/fileBrowser.tsx +84 -223
  162. package/src/fileBrowser/gitStatus.ts +7 -17
  163. package/src/fileBrowser/gitignore.ts +4 -25
  164. package/src/fileBrowser/icons.ts +25 -80
  165. package/src/fileBrowser/index.ts +2 -4
  166. package/src/fileBrowser/widget.tsx +149 -50
  167. package/src/fileTypeIcons/index.ts +0 -10
  168. package/src/git/api.ts +10 -36
  169. package/src/git/askRequest.ts +6 -20
  170. package/src/git/commands.ts +70 -10
  171. package/src/git/diffModel.ts +25 -0
  172. package/src/git/diffSurface.tsx +71 -159
  173. package/src/git/diffWidget.tsx +104 -14
  174. package/src/git/imageDiff.tsx +45 -51
  175. package/src/git/index.ts +3 -8
  176. package/src/git/notebookDiff.tsx +211 -238
  177. package/src/git/tokens.ts +73 -31
  178. package/src/highlight/index.ts +10 -41
  179. package/src/index.ts +0 -9
  180. package/src/launcher/agents.ts +64 -95
  181. package/src/launcher/availability.ts +3 -9
  182. package/src/launcher/commands.ts +14 -51
  183. package/src/launcher/dashboard.tsx +49 -88
  184. package/src/launcher/editorRegistry.ts +21 -29
  185. package/src/launcher/editors.ts +39 -58
  186. package/src/launcher/icons.ts +5 -39
  187. package/src/launcher/index.ts +12 -55
  188. package/src/launcher/invocation.ts +7 -22
  189. package/src/launcher/registry.ts +9 -7
  190. package/src/launcher/tokens.ts +10 -22
  191. package/src/menuBar/index.ts +11 -28
  192. package/src/menus/index.ts +14 -30
  193. package/src/omnibox/files.ts +10 -14
  194. package/src/omnibox/index.ts +9 -27
  195. package/src/omnibox/model.ts +50 -38
  196. package/src/omnibox/recents.ts +17 -22
  197. package/src/omnibox/tokens.ts +5 -10
  198. package/src/omnibox/widget.tsx +14 -19
  199. package/src/searchReplace/index.ts +7 -27
  200. package/src/showOutput/index.ts +6 -22
  201. package/src/sidebar/index.ts +20 -12
  202. package/src/terminalNotifications/index.ts +42 -25
  203. package/src/terminals/agentTerminals.ts +25 -49
  204. package/src/terminals/detection.ts +4 -8
  205. package/src/terminals/index.ts +12 -101
  206. package/src/terminals/model.ts +130 -246
  207. package/src/terminals/tokens.ts +11 -22
  208. package/src/terminals/widget.tsx +48 -31
  209. package/src/topBar/icons.ts +3 -8
  210. package/src/topBar/index.ts +21 -44
  211. package/src/walkthrough/index.ts +6 -20
  212. package/src/walkthrough/panel.ts +40 -10
  213. package/style/about.css +2 -7
  214. package/style/askAgent.css +8 -40
  215. package/style/base.css +9 -45
  216. package/style/chrome.css +108 -308
  217. package/style/commandBar.css +4 -20
  218. package/style/customPanel.css +1 -4
  219. package/style/git.css +22 -184
  220. package/style/highlight.css +1 -3
  221. package/style/launcher.css +6 -70
  222. package/style/omnibox.css +2 -14
  223. package/style/showOutput.css +0 -6
  224. package/style/sidebar.css +29 -9
  225. package/style/tabs.css +5 -13
  226. package/style/terminals.css +6 -53
  227. package/style/topBar.css +2 -22
  228. package/style/walkthrough.css +0 -8
@@ -42,10 +42,26 @@ const ACCORDION_CSS_CLASS = 'jp-xtralab-FileBrowser-accordion';
42
42
 
43
43
  const MOVABLE_SECTION_CLASS = 'jp-movable-section';
44
44
 
45
+ /**
46
+ * The options used to create an {@link XtralabFileBrowser}.
47
+ */
45
48
  interface IXtralabFileBrowserOptions {
49
+ /**
50
+ * The contents manager backing the tree.
51
+ */
46
52
  contentsManager: Contents.IManager;
53
+ /**
54
+ * The document manager used to open files from the tree.
55
+ */
47
56
  docManager: IDocumentManager;
57
+ /**
58
+ * Callback invoked with a file's server path when its row is
59
+ * double-clicked. No double-click handler is installed when absent.
60
+ */
48
61
  onOpenFile?: (serverPath: string) => void;
62
+ /**
63
+ * The application language translator.
64
+ */
49
65
  translator?: ITranslator;
50
66
  }
51
67
 
@@ -56,82 +72,62 @@ interface IXtralabFileBrowserOptions {
56
72
  */
57
73
  export interface IXtralabFileBrowser {
58
74
  /**
59
- * The contents manager backing the tree. Exposed so command handlers can
60
- * issue contents operations (rename, delete, copy, …) against the same
61
- * drive the tree was loaded from.
75
+ * The contents manager backing the tree; command handlers issue rename,
76
+ * delete, copy, … against the same drive.
62
77
  */
63
78
  readonly contentsManager: Contents.IManager;
64
79
 
65
80
  /**
66
- * The toolbar shown above the tree. Plugin code populates it with command
67
- * buttons after the widget is constructed.
81
+ * The toolbar above the tree, populated by plugin code after construction.
68
82
  */
69
83
  readonly toolbar: Toolbar;
70
84
 
71
85
  /**
72
- * Canonical paths of the items currently selected in the tree. Folder
73
- * paths carry a trailing slash; file paths do not.
86
+ * Canonical selected paths; folder paths carry a trailing slash.
74
87
  */
75
88
  readonly selectedPaths: readonly string[];
76
89
 
77
90
  /**
78
- * Emits when the tree's selection changes. Commands that have an
79
- * `isVisible` / `isEnabled` predicate should listen so they re-evaluate.
91
+ * Emits when the tree's selection changes.
80
92
  */
81
93
  readonly selectionChanged: ISignal<IXtralabFileBrowser, readonly string[]>;
82
94
 
83
95
  /**
84
- * Emits when {@link refresh} is called. The React component listens and
85
- * re-fetches the directories that were previously loaded so the tree
86
- * matches the contents on disk again.
96
+ * Emits when {@link refresh} is called.
87
97
  */
88
98
  readonly refreshRequested: ISignal<IXtralabFileBrowser, void>;
89
99
 
90
100
  /**
91
- * Emits when the widget is asked to surface a newly-created path
92
- * (for example, after the toolbar's "new folder" command). The React
93
- * component listens and inserts the path into the model so the user
94
- * sees the new item without a full refresh.
101
+ * Emits a newly-created canonical path so the tree inserts it without a
102
+ * full refresh.
95
103
  */
96
104
  readonly pathAdded: ISignal<IXtralabFileBrowser, string>;
97
105
 
98
106
  /**
99
- * Emits when an external caller asks the tree to scroll to and select
100
- * the given canonical path. The React component listens, lazily loads
101
- * any unloaded ancestor directories, expands them, and selects the
102
- * target. Used by the editor breadcrumbs to jump back to a file or
103
- * folder shown in the breadcrumb trail.
107
+ * Emits a canonical path to load, expand, select, and scroll to. Used by
108
+ * the editor breadcrumbs.
104
109
  */
105
110
  readonly revealRequested: ISignal<IXtralabFileBrowser, string>;
106
111
 
107
112
  /**
108
- * Emits when an external caller asks the tree to return to the
109
- * workspace root: clear any current selection and scroll back to the
110
- * first row. Distinct from {@link revealRequested} because the
111
- * workspace root has no tree row of its own — it cannot be reached
112
- * by passing a path.
113
+ * Emits when the tree should return to the workspace root — the root has
114
+ * no tree row of its own, so it cannot be revealed by path.
113
115
  */
114
116
  readonly rootRequested: ISignal<IXtralabFileBrowser, void>;
115
117
 
116
118
  /**
117
- * Emits when an external caller asks the tree to collapse every
118
- * expanded folder. The React component listens and walks the loaded
119
- * directories, calling `.collapse()` on each expanded one.
119
+ * Emits when every expanded folder should collapse.
120
120
  */
121
121
  readonly collapseAllRequested: ISignal<IXtralabFileBrowser, void>;
122
122
 
123
123
  /**
124
- * Whether the filter box above the tree is shown. Mirrors the default
125
- * file browser's `showFileFilter`: hidden on startup and flipped by the
126
- * toolbar toggle. Also forced to `true` when the tree opens a search
127
- * session on its own — typing a letter while the tree has focus.
124
+ * Whether the filter box above the tree is shown; also forced `true` when
125
+ * the tree opens a search session itself (typing while it has focus).
128
126
  */
129
127
  readonly fileFilterVisible: boolean;
130
128
 
131
129
  /**
132
- * Emits when {@link fileFilterVisible} changes. The React component
133
- * listens to show or hide the filter box; the toggle command listens
134
- * to refresh its toggled state.
130
+ * Emits when {@link fileFilterVisible} changes.
135
131
  */
136
132
  readonly fileFilterVisibleChanged: ISignal<IXtralabFileBrowser, boolean>;
137
133
 
@@ -141,24 +137,19 @@ export interface IXtralabFileBrowser {
141
137
  refresh(): void;
142
138
 
143
139
  /**
144
- * Notify the React component that a new path was created and should
145
- * appear in the tree. `canonicalPath` follows the `@pierre/trees`
146
- * convention: directories carry a trailing slash, files do not.
140
+ * Notify the React component that a new canonical path was created and
141
+ * should appear in the tree.
147
142
  */
148
143
  notifyPathAdded(canonicalPath: string): void;
149
144
 
150
145
  /**
151
- * Ask the tree to reveal {@link canonicalPath}: load and expand any
152
- * unloaded ancestor directories, then select and scroll the target
153
- * into view. `canonicalPath` follows the `@pierre/trees` convention
154
- * (directories carry a trailing slash, files do not). Must be a
155
- * non-empty path — use {@link scrollToRoot} for the root gesture.
146
+ * Reveal a non-empty canonical path: load and expand ancestors, then
147
+ * select and scroll to it. Use {@link scrollToRoot} for the root gesture.
156
148
  */
157
149
  reveal(canonicalPath: string): void;
158
150
 
159
151
  /**
160
- * Ask the tree to return to the workspace root: clear any current
161
- * selection and scroll back to the top of the tree.
152
+ * Return to the workspace root: clear the selection and scroll to the top.
162
153
  */
163
154
  scrollToRoot(): void;
164
155
 
@@ -177,6 +168,10 @@ export interface IXtralabFileBrowser {
177
168
  */
178
169
  toggleFileFilter(): void;
179
170
 
171
+ /**
172
+ * The DOM node of the movable "Files" section, used to locate the panel
173
+ * currently hosting the tree.
174
+ */
180
175
  readonly sectionNode: HTMLElement;
181
176
  }
182
177
 
@@ -228,67 +223,109 @@ export class XtralabFileBrowser
228
223
  layout.addWidget(this._section);
229
224
  }
230
225
 
226
+ /**
227
+ * The contents manager backing the tree.
228
+ */
231
229
  get contentsManager(): Contents.IManager {
232
230
  return this._contentsManager;
233
231
  }
234
232
 
233
+ /**
234
+ * The toolbar above the tree.
235
+ */
235
236
  get toolbar(): Toolbar {
236
237
  return this._toolbar;
237
238
  }
238
239
 
240
+ /**
241
+ * Canonical selected paths; folder paths carry a trailing slash.
242
+ */
239
243
  get selectedPaths(): readonly string[] {
240
244
  return this._selectedPaths;
241
245
  }
242
246
 
247
+ /**
248
+ * A signal emitted when the tree's selection changes.
249
+ */
243
250
  get selectionChanged(): ISignal<this, readonly string[]> {
244
251
  return this._selectionChanged;
245
252
  }
246
253
 
254
+ /**
255
+ * A signal emitted when {@link refresh} is called.
256
+ */
247
257
  get refreshRequested(): ISignal<this, void> {
248
258
  return this._refreshRequested;
249
259
  }
250
260
 
261
+ /**
262
+ * A signal emitting a newly-created canonical path for the tree to insert.
263
+ */
251
264
  get pathAdded(): ISignal<this, string> {
252
265
  return this._pathAdded;
253
266
  }
254
267
 
268
+ /**
269
+ * A signal emitting a canonical path to load, expand, select, and scroll to.
270
+ */
255
271
  get revealRequested(): ISignal<this, string> {
256
272
  return this._revealRequested;
257
273
  }
258
274
 
275
+ /**
276
+ * A signal emitted when the tree should return to the workspace root.
277
+ */
259
278
  get rootRequested(): ISignal<this, void> {
260
279
  return this._rootRequested;
261
280
  }
262
281
 
282
+ /**
283
+ * A signal emitted when every expanded folder should collapse.
284
+ */
263
285
  get collapseAllRequested(): ISignal<this, void> {
264
286
  return this._collapseAllRequested;
265
287
  }
266
288
 
289
+ /**
290
+ * Whether the filter box above the tree is shown.
291
+ */
267
292
  get fileFilterVisible(): boolean {
268
293
  return this._fileFilterVisible;
269
294
  }
270
295
 
296
+ /**
297
+ * A signal emitted when {@link fileFilterVisible} changes.
298
+ */
271
299
  get fileFilterVisibleChanged(): ISignal<this, boolean> {
272
300
  return this._fileFilterVisibleChanged;
273
301
  }
274
302
 
275
303
  /**
276
- * Update the cached selection. Called from the React tree when the
277
- * underlying `@pierre/trees` model emits a selection change.
304
+ * Update the cached selection from the React tree.
278
305
  */
279
306
  updateSelection(paths: readonly string[]): void {
280
307
  this._selectedPaths = paths;
281
308
  this._selectionChanged.emit(paths);
282
309
  }
283
310
 
311
+ /**
312
+ * Trigger a refresh of every loaded directory in the tree.
313
+ */
284
314
  refresh(): void {
285
315
  this._refreshRequested.emit();
286
316
  }
287
317
 
318
+ /**
319
+ * Notify the tree that a new canonical path was created.
320
+ */
288
321
  notifyPathAdded(canonicalPath: string): void {
289
322
  this._pathAdded.emit(canonicalPath);
290
323
  }
291
324
 
325
+ /**
326
+ * Reveal a non-empty canonical path in the tree; use {@link scrollToRoot}
327
+ * for the workspace root, which has no tree row of its own.
328
+ */
292
329
  reveal(canonicalPath: string): void {
293
330
  if (canonicalPath.length === 0) {
294
331
  throw new Error(
@@ -298,14 +335,23 @@ export class XtralabFileBrowser
298
335
  this._revealRequested.emit(canonicalPath);
299
336
  }
300
337
 
338
+ /**
339
+ * Return to the workspace root: clear the selection and scroll to the top.
340
+ */
301
341
  scrollToRoot(): void {
302
342
  this._rootRequested.emit();
303
343
  }
304
344
 
345
+ /**
346
+ * Ask the tree to collapse every currently expanded folder.
347
+ */
305
348
  collapseAll(): void {
306
349
  this._collapseAllRequested.emit();
307
350
  }
308
351
 
352
+ /**
353
+ * Show or hide the filter box above the tree.
354
+ */
309
355
  setFileFilterVisible(visible: boolean): void {
310
356
  if (this._fileFilterVisible === visible) {
311
357
  return;
@@ -314,30 +360,51 @@ export class XtralabFileBrowser
314
360
  this._fileFilterVisibleChanged.emit(visible);
315
361
  }
316
362
 
363
+ /**
364
+ * Toggle the filter box above the tree.
365
+ */
317
366
  toggleFileFilter(): void {
318
367
  this.setFileFilterVisible(!this._fileFilterVisible);
319
368
  }
320
369
 
370
+ /**
371
+ * The DOM node of the movable "Files" section.
372
+ */
321
373
  get sectionNode(): HTMLElement {
322
374
  return this._section.node;
323
375
  }
324
376
 
377
+ /**
378
+ * Whether the panel currently holds no sections, its own tree included.
379
+ */
325
380
  get isEmpty(): boolean {
326
381
  return this._panelLayout.widgets.length === 0;
327
382
  }
328
383
 
384
+ /**
385
+ * A signal emitted when a section is added to or removed from the panel.
386
+ */
329
387
  get contentChanged(): ISignal<this, void> {
330
388
  return this._contentChanged;
331
389
  }
332
390
 
391
+ /**
392
+ * A signal emitting each section entry announced to the move plugin.
393
+ */
333
394
  get sectionAdded(): ISignal<this, ISectionEntry> {
334
395
  return this._sectionAdded;
335
396
  }
336
397
 
398
+ /**
399
+ * The accordion hosting the sections, or `null` while the tree sits alone.
400
+ */
337
401
  get accordionPanel(): AccordionPanel | null {
338
402
  return this._accordion;
339
403
  }
340
404
 
405
+ /**
406
+ * Section widgets hosted from other panels; the tree section is excluded.
407
+ */
341
408
  get sections(): ReadonlyArray<Widget> {
342
409
  if (!this._accordion) {
343
410
  return [];
@@ -361,6 +428,10 @@ export class XtralabFileBrowser
361
428
  : [];
362
429
  }
363
430
 
431
+ /**
432
+ * Detach and return the tree section so the move plugin can re-host it;
433
+ * `null` for any other id or when the section is already away from home.
434
+ */
364
435
  removeSectionById(sectionId: string): Widget | null {
365
436
  if (sectionId !== TREE_SECTION_ID || !this._isSectionHome()) {
366
437
  return null;
@@ -377,6 +448,9 @@ export class XtralabFileBrowser
377
448
  return this._section;
378
449
  }
379
450
 
451
+ /**
452
+ * Re-attach the tree section after a move back to this panel.
453
+ */
380
454
  reinsertSection(widget: Widget): void {
381
455
  if (this._accordion) {
382
456
  this._accordion.insertWidget(0, widget);
@@ -418,6 +492,10 @@ export class XtralabFileBrowser
418
492
  this._contentChanged.emit();
419
493
  }
420
494
 
495
+ /**
496
+ * Remove a hosted section; the accordion is torn down once only the
497
+ * panel's own tree section (or nothing) remains.
498
+ */
421
499
  removeSectionWidget(widget: Widget): void {
422
500
  if (!this._accordion || widget.parent !== this._accordion) {
423
501
  return;
@@ -475,17 +553,35 @@ export class XtralabFileBrowser
475
553
  private _sectionAdded = new Signal<this, ISectionEntry>(this);
476
554
  }
477
555
 
556
+ /**
557
+ * The options used to create an {@link XtralabFileTreeContent}.
558
+ */
478
559
  interface IFileTreeContentOptions {
560
+ /**
561
+ * The contents manager backing the tree.
562
+ */
479
563
  contentsManager: Contents.IManager;
564
+ /**
565
+ * The document manager used to open files from the tree.
566
+ */
480
567
  docManager: IDocumentManager;
568
+ /**
569
+ * Callback invoked with a file's server path when its row is
570
+ * double-clicked. No double-click handler is installed when absent.
571
+ */
481
572
  onOpenFile?: (serverPath: string) => void;
573
+ /**
574
+ * The application language translator.
575
+ */
482
576
  translator?: ITranslator;
577
+ /**
578
+ * The host widget the React tree reports selection and state changes to.
579
+ */
483
580
  browser: XtralabFileBrowser;
484
581
  }
485
582
 
486
583
  /**
487
- * The React-rendered region of the file browser. Lives inside the host
488
- * widget below the toolbar and renders the actual tree.
584
+ * The React-rendered region below the toolbar that hosts the actual tree.
489
585
  */
490
586
  class XtralabFileTreeContent extends ReactWidget {
491
587
  constructor(options: IFileTreeContentOptions) {
@@ -493,6 +589,9 @@ class XtralabFileTreeContent extends ReactWidget {
493
589
  this._options = options;
494
590
  }
495
591
 
592
+ /**
593
+ * Render the file browser React component.
594
+ */
496
595
  protected render(): React.ReactElement {
497
596
  return (
498
597
  <FileBrowserComponent
@@ -25,13 +25,9 @@ function representativePath(
25
25
  if (extension === undefined || extension === '') {
26
26
  return null;
27
27
  }
28
- // Extensions are stored with a leading dot (e.g. `.py`, `.tar.gz`).
29
28
  return `file${extension.startsWith('.') ? extension : `.${extension}`}`;
30
29
  }
31
30
 
32
- /**
33
- * Point a file type's icon at the tree glyph for its extension.
34
- */
35
31
  function applyTreeIcon(fileType: DocumentRegistry.IFileType): void {
36
32
  const path = representativePath(fileType);
37
33
  if (path === null) {
@@ -79,9 +75,6 @@ const EXTRA_FILE_TYPE_EXTENSIONS = [
79
75
  '.wasm'
80
76
  ];
81
77
 
82
- /**
83
- * Register icon-only file types for unclaimed source extensions.
84
- */
85
78
  function registerExtraFileTypes(docRegistry: DocumentRegistry): void {
86
79
  for (const extension of EXTRA_FILE_TYPE_EXTENSIONS) {
87
80
  const icon = getSpecificTreeIcon(`file${extension}`);
@@ -125,7 +118,6 @@ const plugin: JupyterFrontEndPlugin<void> = {
125
118
  applyTreeIcon(fileType);
126
119
  }
127
120
  registerExtraFileTypes(docRegistry);
128
- // Pick up file types registered after this plugin activates.
129
121
  docRegistry.changed.connect((_, args) => {
130
122
  if (
131
123
  args.type === 'fileType' &&
@@ -148,8 +140,6 @@ const plugin: JupyterFrontEndPlugin<void> = {
148
140
  }
149
141
  };
150
142
  setIcon();
151
- // Keep the tab icon right after a rename, and release the listener
152
- // when the document closes.
153
143
  widget.context.pathChanged.connect(setIcon);
154
144
  widget.disposed.connect(() => {
155
145
  widget.context.pathChanged.disconnect(setIcon);
package/src/git/api.ts CHANGED
@@ -9,29 +9,15 @@ import {
9
9
  IGitStatusResult
10
10
  } from './tokens';
11
11
 
12
- /**
13
- * Root URL segment used by the `jupyterlab_git` server extension. Every
14
- * endpoint hangs off this prefix; the `<repoPath>` between it and the
15
- * endpoint suffix is the JupyterLab server-relative path of the git
16
- * repository (URL-encoded). For an empty `repoPath` the URL collapses to
17
- * `/git/<endpoint>` — a shape git's URL routing also accepts.
18
- */
19
12
  const GIT_NAMESPACE = 'git';
20
13
 
21
- /**
22
- * Issue a `POST` against a `jupyterlab_git` endpoint that takes a `<path>`
23
- * prefix (e.g. `/git/<path>/status`). The response body is decoded as JSON;
24
- * non-2xx responses are surfaced via the JupyterLab `ServerConnection`
25
- * machinery so callers can show their `message` field as-is.
26
- */
27
14
  async function postWithPath<T>(
28
15
  endpoint: string,
29
16
  repoPath: string,
30
17
  body: unknown
31
18
  ): Promise<T> {
32
19
  const settings = ServerConnection.makeSettings();
33
- // `URLExt.encodeParts` encodes each path segment but preserves slashes
34
- // between them — the server expects the path to look like a posix path.
20
+ // encodeParts keeps the slashes the server's posix-path routing expects.
35
21
  const encodedPath = repoPath.length > 0 ? URLExt.encodeParts(repoPath) : '';
36
22
  const url = URLExt.join(
37
23
  settings.baseUrl,
@@ -50,7 +36,7 @@ async function postWithPath<T>(
50
36
  try {
51
37
  data = JSON.parse(text) as T;
52
38
  } catch {
53
- // Fall through into the error handling below.
39
+ // Non-JSON bodies still surface via the ResponseError below.
54
40
  }
55
41
  }
56
42
  if (!response.ok) {
@@ -62,18 +48,16 @@ async function postWithPath<T>(
62
48
  }
63
49
 
64
50
  /**
65
- * Fetch `git status --porcelain` for the repository the server resolves at
66
- * `repoPath`. When `repoPath` is the empty string, git resolves the repo
67
- * from the JupyterLab server's root directory.
51
+ * Fetch `git status --porcelain` for the repo at `repoPath` (empty string
52
+ * resolves from the server's root directory).
68
53
  */
69
54
  export async function status(repoPath: string): Promise<IGitStatusResult> {
70
55
  return postWithPath<IGitStatusResult>('status', repoPath, {});
71
56
  }
72
57
 
73
58
  /**
74
- * Fetch a file's contents at a particular git reference. `filename` is the
75
- * file's path relative to the git repository root (matching the `to` field
76
- * of {@link status}'s response).
59
+ * Fetch a file's contents at a git reference; `filename` is relative to the
60
+ * git repository root.
77
61
  */
78
62
  export async function content(
79
63
  repoPath: string,
@@ -88,13 +72,7 @@ export async function content(
88
72
 
89
73
  /**
90
74
  * Expand the porcelain `files` array into one entry per logical change.
91
- * A single porcelain row may map to two `IFileChange` rows (a file that's
92
- * both staged and modified again in the worktree); callers that just want
93
- * a flat list of all changes — without any staged-vs-unstaged grouping —
94
- * can use this helper.
95
- *
96
- * Provided as a manual concat rather than `Array.prototype.flatMap` so we
97
- * don't pin our `tsconfig.lib` to ES2019.
75
+ * Manual concat rather than `flatMap` so `tsconfig.lib` need not be ES2019.
98
76
  */
99
77
  export function expandStatusFiles(files: IGitStatusFile[]): IFileChange[] {
100
78
  const result: IFileChange[] = [];
@@ -107,16 +85,12 @@ export function expandStatusFiles(files: IGitStatusFile[]): IFileChange[] {
107
85
  }
108
86
 
109
87
  /**
110
- * Translate one entry in the porcelain `files` array into the panel's
111
- * preferred shape. A single porcelain entry may represent up to two changes
112
- * (one in the index, one in the worktree); we emit one {@link IFileChange}
113
- * per non-empty side, so a "modified-staged-and-then-modified-again" file
114
- * shows up twice in the panel — once under "Staged Changes" and once under
115
- * "Changes" — matching the layout the user sees in VS Code.
88
+ * Map one porcelain entry to up to two {@link IFileChange} rows — one per
89
+ * non-empty index/worktree side — so a staged-then-modified-again file
90
+ * appears under both groups, as in VS Code.
116
91
  */
117
92
  function porcelainToFileChanges(file: IGitStatusFile): IFileChange[] {
118
93
  const result: IFileChange[] = [];
119
- // Untracked files are reported with `??` and only appear under "Changes".
120
94
  if (file.x === '?' && file.y === '?') {
121
95
  return [
122
96
  {
@@ -9,10 +9,8 @@ import type { IXtralabDiffModel } from './diffWidget';
9
9
  type DiffSide = 'deletions' | 'additions';
10
10
 
11
11
  /**
12
- * Agent-facing name of a diff content source: the special refs get plain
13
- * words, a git ref string is used verbatim, anything else falls back to the
14
- * side name. English on purpose — this ends up in the agent prompt, not in
15
- * the UI.
12
+ * Agent-facing name of a diff content source. English on purpose — this
13
+ * ends up in the agent prompt, not in the UI.
16
14
  */
17
15
  function describeSource(source: unknown, fallback: string): string {
18
16
  if (source === Git.Diff.SpecialRef.WORKING) {
@@ -34,9 +32,6 @@ function sideName(side: DiffSide): string {
34
32
  return side === 'deletions' ? 'old side' : 'new side';
35
33
  }
36
34
 
37
- /**
38
- * Extract lines `startLine`–`endLine` (1-indexed, inclusive) from `text`.
39
- */
40
35
  function sliceLines(text: string, startLine: number, endLine: number): string {
41
36
  return text
42
37
  .split('\n')
@@ -46,14 +41,10 @@ function sliceLines(text: string, startLine: number, endLine: number): string {
46
41
 
47
42
  /**
48
43
  * Build the ask-agent request for a line range selected in a git diff.
49
- *
50
- * The range's `side` decides which file version the line numbers (and the
51
- * embedded snippet) refer to: `deletions` reads from the reference text,
52
- * anything else — including the sideless context rows of a unified diff,
53
- * whose gutter shows new-side numbers — reads from the challenger text. A
54
- * gutter drag that crosses the two split columns has endpoints in different
55
- * line-number spaces, so it is described textually instead of as a numeric
56
- * range.
44
+ * `deletions` ranges index the reference text; other ranges — including
45
+ * sideless unified context rows, whose gutter shows new-side numbers —
46
+ * index the challenger. A drag across the two split columns mixes
47
+ * line-number spaces, so it is described textually instead of numerically.
57
48
  */
58
49
  export function buildDiffAskRequest(options: {
59
50
  model: IXtralabDiffModel;
@@ -97,15 +88,10 @@ export function buildDiffAskRequest(options: {
97
88
  ...base,
98
89
  startLine,
99
90
  endLine,
100
- // Only new-side lines of a working-tree diff index the file on disk;
101
- // old-side and historical line numbers must not be used to highlight
102
- // the working file.
103
91
  linesInWorkingFile:
104
92
  !isOld && model.challenger.source === Git.Diff.SpecialRef.WORKING,
105
93
  text: sliceLines(isOld ? oldText : newText, startLine, endLine),
106
94
  location: `the ${sideName(startSide)} (${ref}) of the current git diff`,
107
- // New-side lines read as the file's current content, so only old-side
108
- // ranges need a clarifying tag in the popup header.
109
95
  ...(isOld ? { note: trans.__('old version') } : {})
110
96
  },
111
97
  anchor