xtralab 0.15.0 → 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/README.md +65 -30
  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 +29 -19
  36. package/lib/fileBrowser/commands.js +83 -97
  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 +70 -222
  42. package/lib/fileBrowser/gitStatus.d.ts +16 -10
  43. package/lib/fileBrowser/gitStatus.js +31 -30
  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 +141 -48
  50. package/lib/fileBrowser/widget.js +102 -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 +45 -5
  57. package/lib/git/commands.js +20 -13
  58. package/lib/git/diffModel.js +4 -0
  59. package/lib/git/diffPreferences.d.ts +90 -0
  60. package/lib/git/diffPreferences.js +107 -0
  61. package/lib/git/diffProvider.js +10 -2
  62. package/lib/git/diffSurface.d.ts +64 -63
  63. package/lib/git/diffSurface.js +72 -213
  64. package/lib/git/diffTheme.d.ts +7 -0
  65. package/lib/git/diffTheme.js +23 -0
  66. package/lib/git/diffWidget.d.ts +70 -14
  67. package/lib/git/diffWidget.js +100 -94
  68. package/lib/git/imageDiff.d.ts +14 -6
  69. package/lib/git/imageDiff.js +19 -75
  70. package/lib/git/index.d.ts +0 -3
  71. package/lib/git/index.js +44 -10
  72. package/lib/git/notebookDiff.d.ts +110 -33
  73. package/lib/git/notebookDiff.js +55 -197
  74. package/lib/git/tokens.d.ts +73 -31
  75. package/lib/git/tokens.js +2 -3
  76. package/lib/highlight/index.d.ts +4 -10
  77. package/lib/highlight/index.js +10 -41
  78. package/lib/index.d.ts +0 -9
  79. package/lib/index.js +0 -9
  80. package/lib/launcher/agents.d.ts +55 -51
  81. package/lib/launcher/agents.js +15 -57
  82. package/lib/launcher/availability.d.ts +3 -9
  83. package/lib/launcher/availability.js +3 -9
  84. package/lib/launcher/commands.d.ts +7 -32
  85. package/lib/launcher/commands.js +14 -45
  86. package/lib/launcher/dashboard.d.ts +19 -24
  87. package/lib/launcher/dashboard.js +21 -67
  88. package/lib/launcher/editorRegistry.d.ts +10 -22
  89. package/lib/launcher/editorRegistry.js +14 -18
  90. package/lib/launcher/editors.d.ts +39 -45
  91. package/lib/launcher/editors.js +8 -34
  92. package/lib/launcher/icons.d.ts +0 -12
  93. package/lib/launcher/icons.js +5 -39
  94. package/lib/launcher/index.js +12 -55
  95. package/lib/launcher/invocation.d.ts +4 -10
  96. package/lib/launcher/invocation.js +7 -22
  97. package/lib/launcher/registry.d.ts +9 -7
  98. package/lib/launcher/registry.js +9 -7
  99. package/lib/launcher/tokens.d.ts +10 -22
  100. package/lib/launcher/tokens.js +5 -8
  101. package/lib/menuBar/index.d.ts +3 -10
  102. package/lib/menuBar/index.js +11 -28
  103. package/lib/menus/index.d.ts +3 -9
  104. package/lib/menus/index.js +14 -30
  105. package/lib/omnibox/files.d.ts +2 -4
  106. package/lib/omnibox/files.js +5 -11
  107. package/lib/omnibox/index.d.ts +4 -14
  108. package/lib/omnibox/index.js +9 -27
  109. package/lib/omnibox/model.d.ts +38 -10
  110. package/lib/omnibox/model.js +15 -33
  111. package/lib/omnibox/recents.d.ts +15 -17
  112. package/lib/omnibox/recents.js +12 -17
  113. package/lib/omnibox/tokens.d.ts +5 -10
  114. package/lib/omnibox/tokens.js +2 -6
  115. package/lib/omnibox/widget.d.ts +11 -7
  116. package/lib/omnibox/widget.js +8 -16
  117. package/lib/searchReplace/index.d.ts +4 -20
  118. package/lib/searchReplace/index.js +7 -27
  119. package/lib/showOutput/index.d.ts +3 -12
  120. package/lib/showOutput/index.js +6 -22
  121. package/lib/sidebar/index.d.ts +4 -7
  122. package/lib/sidebar/index.js +5 -12
  123. package/lib/terminalNotifications/index.d.ts +4 -10
  124. package/lib/terminalNotifications/index.js +6 -20
  125. package/lib/terminals/agentTerminals.d.ts +12 -5
  126. package/lib/terminals/agentTerminals.js +25 -44
  127. package/lib/terminals/detection.d.ts +4 -8
  128. package/lib/terminals/detection.js +4 -8
  129. package/lib/terminals/index.d.ts +0 -35
  130. package/lib/terminals/index.js +12 -101
  131. package/lib/terminals/model.d.ts +64 -139
  132. package/lib/terminals/model.js +80 -220
  133. package/lib/terminals/tokens.d.ts +11 -22
  134. package/lib/terminals/tokens.js +2 -2
  135. package/lib/terminals/widget.d.ts +43 -13
  136. package/lib/terminals/widget.js +33 -18
  137. package/lib/topBar/icons.d.ts +3 -8
  138. package/lib/topBar/icons.js +3 -8
  139. package/lib/topBar/index.d.ts +4 -11
  140. package/lib/topBar/index.js +10 -38
  141. package/lib/walkthrough/index.d.ts +4 -9
  142. package/lib/walkthrough/index.js +6 -20
  143. package/lib/walkthrough/panel.d.ts +40 -9
  144. package/lib/walkthrough/panel.js +4 -10
  145. package/package.json +5 -3
  146. package/schema/git-diff-preferences.json +42 -0
  147. package/src/about/icons.ts +0 -5
  148. package/src/about/index.tsx +6 -17
  149. package/src/agentSessions.ts +9 -29
  150. package/src/askAgent/editorSelection.ts +22 -29
  151. package/src/askAgent/icons.ts +2 -3
  152. package/src/askAgent/index.ts +54 -158
  153. package/src/askAgent/popup.tsx +23 -45
  154. package/src/askAgent/prompt.ts +6 -19
  155. package/src/askAgent/queue.ts +13 -24
  156. package/src/askAgent/queuePanel.tsx +21 -46
  157. package/src/askAgent/targetPicker.tsx +5 -15
  158. package/src/askAgent/tokens.ts +32 -46
  159. package/src/commandBar/index.ts +24 -39
  160. package/src/customPanel/index.ts +15 -0
  161. package/src/editorBreadcrumbs/index.ts +10 -6
  162. package/src/editorBreadcrumbs/widget.ts +23 -17
  163. package/src/editorIndent/index.ts +17 -23
  164. package/src/fileBrowser/commands.ts +119 -96
  165. package/src/fileBrowser/contents.ts +3 -0
  166. package/src/fileBrowser/dragAndDrop.ts +17 -7
  167. package/src/fileBrowser/fileBrowser.tsx +86 -230
  168. package/src/fileBrowser/gitStatus.ts +36 -33
  169. package/src/fileBrowser/gitignore.ts +4 -25
  170. package/src/fileBrowser/icons.ts +25 -80
  171. package/src/fileBrowser/index.ts +2 -4
  172. package/src/fileBrowser/widget.tsx +171 -50
  173. package/src/fileTypeIcons/index.ts +0 -10
  174. package/src/git/api.ts +10 -36
  175. package/src/git/askRequest.ts +6 -20
  176. package/src/git/commands.ts +83 -11
  177. package/src/git/diffModel.ts +25 -0
  178. package/src/git/diffPreferences.ts +192 -0
  179. package/src/git/diffProvider.tsx +11 -2
  180. package/src/git/diffSurface.tsx +165 -286
  181. package/src/git/diffTheme.ts +24 -0
  182. package/src/git/diffWidget.tsx +194 -134
  183. package/src/git/imageDiff.tsx +56 -84
  184. package/src/git/index.ts +54 -10
  185. package/src/git/notebookDiff.tsx +214 -240
  186. package/src/git/tokens.ts +73 -31
  187. package/src/highlight/index.ts +10 -41
  188. package/src/index.ts +0 -9
  189. package/src/launcher/agents.ts +64 -95
  190. package/src/launcher/availability.ts +3 -9
  191. package/src/launcher/commands.ts +14 -51
  192. package/src/launcher/dashboard.tsx +49 -88
  193. package/src/launcher/editorRegistry.ts +21 -29
  194. package/src/launcher/editors.ts +39 -58
  195. package/src/launcher/icons.ts +5 -39
  196. package/src/launcher/index.ts +12 -55
  197. package/src/launcher/invocation.ts +7 -22
  198. package/src/launcher/registry.ts +9 -7
  199. package/src/launcher/tokens.ts +10 -22
  200. package/src/menuBar/index.ts +11 -28
  201. package/src/menus/index.ts +14 -30
  202. package/src/omnibox/files.ts +10 -14
  203. package/src/omnibox/index.ts +9 -27
  204. package/src/omnibox/model.ts +50 -38
  205. package/src/omnibox/recents.ts +17 -22
  206. package/src/omnibox/tokens.ts +5 -10
  207. package/src/omnibox/widget.tsx +14 -19
  208. package/src/searchReplace/index.ts +7 -27
  209. package/src/showOutput/index.ts +6 -22
  210. package/src/sidebar/index.ts +20 -12
  211. package/src/terminalNotifications/index.ts +42 -25
  212. package/src/terminals/agentTerminals.ts +25 -49
  213. package/src/terminals/detection.ts +4 -8
  214. package/src/terminals/index.ts +12 -101
  215. package/src/terminals/model.ts +130 -246
  216. package/src/terminals/tokens.ts +11 -22
  217. package/src/terminals/widget.tsx +48 -31
  218. package/src/topBar/icons.ts +3 -8
  219. package/src/topBar/index.ts +21 -44
  220. package/src/walkthrough/index.ts +6 -20
  221. package/src/walkthrough/panel.ts +40 -10
  222. package/style/about.css +2 -7
  223. package/style/askAgent.css +8 -40
  224. package/style/base.css +9 -45
  225. package/style/chrome.css +108 -308
  226. package/style/commandBar.css +4 -20
  227. package/style/customPanel.css +1 -4
  228. package/style/git.css +26 -186
  229. package/style/highlight.css +1 -3
  230. package/style/launcher.css +6 -70
  231. package/style/omnibox.css +2 -14
  232. package/style/showOutput.css +0 -6
  233. package/style/sidebar.css +29 -9
  234. package/style/tabs.css +5 -13
  235. package/style/terminals.css +6 -53
  236. package/style/topBar.css +2 -22
  237. package/style/walkthrough.css +0 -8
@@ -8,22 +8,9 @@ import type { GitStatusEntry } from '@pierre/trees';
8
8
  */
9
9
  export declare function loadGitignoreMatcher(contentsManager: Contents.IManager): Promise<Ignore | null>;
10
10
  /**
11
- * Build `GitStatusEntry`s for the canonical paths that match the given
12
- * gitignore matcher.
13
- *
14
- * `@pierre/trees` propagates the `ignored` style from a directory entry
15
- * down to every descendant via its internal `ignoredDirectoryPaths` set, so
16
- * we only emit one entry per ignored subtree root: emitting descendants
17
- * would also pollute the library's `directoriesWithChanges` set, causing
18
- * parent directories of nested ignored items to render a "contains git
19
- * status items" dot.
20
- *
21
- * Paths are sorted lexicographically so a directory always precedes its
22
- * descendants, allowing a simple ancestor-suppression check via
23
- * `path.startsWith(dir)`. The trailing slash on canonical directory paths
24
- * (required by `@pierre/trees`, also recognized by `ignore` as the
25
- * "directory" indicator) keeps the prefix check from accidentally matching
26
- * sibling paths that happen to share a name prefix (e.g. `node_modules_old`
27
- * vs `node_modules/`).
11
+ * One `GitStatusEntry` per ignored subtree root: descendant entries would
12
+ * pollute the tree's `directoriesWithChanges` set (bogus dots on parents),
13
+ * and `ignored` already propagates downward. The trailing slash on directory
14
+ * paths keeps the sorted `startsWith` ancestor check off name-prefix siblings.
28
15
  */
29
16
  export declare function buildIgnoredEntries(matcher: Ignore, canonicalPaths: Iterable<string>): GitStatusEntry[];
@@ -1,9 +1,4 @@
1
1
  import ignore from 'ignore';
2
- /**
3
- * The path of the workspace `.gitignore` file. Loaded relative to the
4
- * Jupyter contents root, which matches the directory the gitignore patterns
5
- * are evaluated against — patterns and tested paths share the same base.
6
- */
7
2
  const GITIGNORE_PATH = '.gitignore';
8
3
  /**
9
4
  * Load the workspace `.gitignore` and return an `ignore` matcher built from
@@ -20,9 +15,6 @@ export async function loadGitignoreMatcher(contentsManager) {
20
15
  });
21
16
  }
22
17
  catch (_a) {
23
- // The most common failure here is `.gitignore` simply not existing.
24
- // Other transient errors (permission denied, server unreachable) are
25
- // also treated as "no matcher" so the file browser still works.
26
18
  return null;
27
19
  }
28
20
  if (model.type !== 'file' || typeof model.content !== 'string') {
@@ -34,23 +26,10 @@ export async function loadGitignoreMatcher(contentsManager) {
34
26
  return ignore().add(model.content);
35
27
  }
36
28
  /**
37
- * Build `GitStatusEntry`s for the canonical paths that match the given
38
- * gitignore matcher.
39
- *
40
- * `@pierre/trees` propagates the `ignored` style from a directory entry
41
- * down to every descendant via its internal `ignoredDirectoryPaths` set, so
42
- * we only emit one entry per ignored subtree root: emitting descendants
43
- * would also pollute the library's `directoriesWithChanges` set, causing
44
- * parent directories of nested ignored items to render a "contains git
45
- * status items" dot.
46
- *
47
- * Paths are sorted lexicographically so a directory always precedes its
48
- * descendants, allowing a simple ancestor-suppression check via
49
- * `path.startsWith(dir)`. The trailing slash on canonical directory paths
50
- * (required by `@pierre/trees`, also recognized by `ignore` as the
51
- * "directory" indicator) keeps the prefix check from accidentally matching
52
- * sibling paths that happen to share a name prefix (e.g. `node_modules_old`
53
- * vs `node_modules/`).
29
+ * One `GitStatusEntry` per ignored subtree root: descendant entries would
30
+ * pollute the tree's `directoriesWithChanges` set (bogus dots on parents),
31
+ * and `ignored` already propagates downward. The trailing slash on directory
32
+ * paths keeps the sorted `startsWith` ancestor check off name-prefix siblings.
54
33
  */
55
34
  export function buildIgnoredEntries(matcher, canonicalPaths) {
56
35
  const sorted = Array.from(canonicalPaths).sort();
@@ -1,26 +1,16 @@
1
1
  import { LabIcon } from '@jupyterlab/ui-components';
2
2
  import type { FileTreeIconConfig } from '@pierre/trees';
3
3
  /**
4
- * The glyph used as the xtralab file browser's sidebar tab icon. Defined as a
5
- * `LabIcon` (rather than the default `folderIcon` from
6
- * `@jupyterlab/ui-components`) so the xtralab browser is visually distinguishable
7
- * from JupyterLab's built-in file browser, which also lives in the left
8
- * sidebar.
9
- *
10
- * Source: `file-tree` from SVG Repo (https://www.svgrepo.com/svg/371275/file-tree).
11
- * The original `fill="#444"` is replaced with `fill="currentColor"` and the
12
- * root element is given the `jp-icon3` class so the icon picks up JupyterLab's
13
- * theme color and the sidebar's inverse-color painting automatically.
4
+ * Sidebar tab icon, distinct from the core `folderIcon` so the xtralab
5
+ * browser is distinguishable from the built-in one. `file-tree` from SVG Repo
6
+ * (https://www.svgrepo.com/svg/371275/file-tree), refit to follow the theme
7
+ * (`currentColor`, `jp-icon3`) and padded to the size of the stock glyphs.
14
8
  */
15
9
  export declare const xtralabFileBrowserIcon: LabIcon;
16
10
  /**
17
- * Icon configuration for the xtralab file browser. Keeps the default `complete`
18
- * built-in icon set (the colored language icons) and layers a Jupyter notebook
19
- * symbol on top so `.ipynb` files render with the JupyterLab notebook glyph.
20
- *
21
- * `set` must be set explicitly: when a config object includes any custom
22
- * overrides without `set`, `@pierre/trees` defaults `set` to `'none'`, which
23
- * disables the built-in icons entirely.
11
+ * Icon config: the built-in `complete` set plus the Jupyter notebook symbol
12
+ * for `.ipynb`. `set` must be explicit — with any custom overrides present,
13
+ * `@pierre/trees` defaults it to `'none'`, disabling the built-in icons.
24
14
  */
25
15
  export declare const FILE_BROWSER_ICONS: FileTreeIconConfig;
26
16
  /**
@@ -2,36 +2,22 @@ var _a;
2
2
  import { LabIcon, fileIcon } from '@jupyterlab/ui-components';
3
3
  import { createFileTreeIconResolver, getBuiltInSpriteSheet } from '@pierre/trees';
4
4
  /**
5
- * The glyph used as the xtralab file browser's sidebar tab icon. Defined as a
6
- * `LabIcon` (rather than the default `folderIcon` from
7
- * `@jupyterlab/ui-components`) so the xtralab browser is visually distinguishable
8
- * from JupyterLab's built-in file browser, which also lives in the left
9
- * sidebar.
10
- *
11
- * Source: `file-tree` from SVG Repo (https://www.svgrepo.com/svg/371275/file-tree).
12
- * The original `fill="#444"` is replaced with `fill="currentColor"` and the
13
- * root element is given the `jp-icon3` class so the icon picks up JupyterLab's
14
- * theme color and the sidebar's inverse-color painting automatically.
5
+ * Sidebar tab icon, distinct from the core `folderIcon` so the xtralab
6
+ * browser is distinguishable from the built-in one. `file-tree` from SVG Repo
7
+ * (https://www.svgrepo.com/svg/371275/file-tree), refit to follow the theme
8
+ * (`currentColor`, `jp-icon3`) and padded to the size of the stock glyphs.
15
9
  */
16
10
  export const xtralabFileBrowserIcon = new LabIcon({
17
11
  name: 'xtralab:file-browser',
18
- svgstr: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="jp-icon3" fill="currentColor">
12
+ svgstr: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 20 20" class="jp-icon3" fill="currentColor">
19
13
  <path d="M16 10v-4h-11v1h-2v-3h9v-4h-12v4h2v10h3v2h11v-4h-11v1h-2v-5h2v2z"/>
20
14
  </svg>`
21
15
  });
22
16
  /**
23
- * Sprite sheet injected into the `@pierre/trees` shadow DOM. Contains a single
24
- * `<symbol>` for the Jupyter notebook icon, drawn from the JupyterLab core
25
- * notebook icon (`@jupyterlab/ui-components/style/icons/filetype/notebook.svg`).
26
- *
27
- * `@pierre/trees` does not ship a Jupyter token, so `.ipynb` files would
28
- * otherwise fall through to the generic file icon. The symbol id below is
29
- * referenced from `byFileExtension` in {@link FILE_BROWSER_ICONS}.
30
- *
31
- * The orange `#EF6C00` fill is set as a presentation attribute on the inner
32
- * `<g>` so it survives the `fill: currentColor` rule the tree applies on the
33
- * icon container — the inherited color does not override a presentation
34
- * attribute set directly on a child.
17
+ * Sprite sheet injected into the tree's shadow DOM: the JupyterLab notebook
18
+ * glyph, since `@pierre/trees` ships no Jupyter token. The `#EF6C00` fill is
19
+ * a presentation attribute on the inner `<g>` so it survives the tree's
20
+ * `fill: currentColor` rule on the icon container.
35
21
  */
36
22
  const JUPYTER_NOTEBOOK_SPRITE_SHEET = `<svg data-icon-sprite aria-hidden="true" width="0" height="0">
37
23
  <symbol id="jupyter-notebook" viewBox="0 0 22 22">
@@ -42,13 +28,9 @@ const JUPYTER_NOTEBOOK_SPRITE_SHEET = `<svg data-icon-sprite aria-hidden="true"
42
28
  </symbol>
43
29
  </svg>`;
44
30
  /**
45
- * Icon configuration for the xtralab file browser. Keeps the default `complete`
46
- * built-in icon set (the colored language icons) and layers a Jupyter notebook
47
- * symbol on top so `.ipynb` files render with the JupyterLab notebook glyph.
48
- *
49
- * `set` must be set explicitly: when a config object includes any custom
50
- * overrides without `set`, `@pierre/trees` defaults `set` to `'none'`, which
51
- * disables the built-in icons entirely.
31
+ * Icon config: the built-in `complete` set plus the Jupyter notebook symbol
32
+ * for `.ipynb`. `set` must be explicit — with any custom overrides present,
33
+ * `@pierre/trees` defaults it to `'none'`, disabling the built-in icons.
52
34
  */
53
35
  export const FILE_BROWSER_ICONS = {
54
36
  set: 'complete',
@@ -58,39 +40,19 @@ export const FILE_BROWSER_ICONS = {
58
40
  ipynb: 'jupyter-notebook'
59
41
  }
60
42
  };
61
- /**
62
- * Concatenated sprite-sheet text. Combines the built-in sheet for the active
63
- * icon set with our custom Jupyter notebook sheet so {@link extractSymbol}
64
- * can find the body of any symbol the tree itself can render.
65
- */
66
43
  const COMBINED_SPRITE_SHEETS = [
67
44
  getBuiltInSpriteSheet((_a = FILE_BROWSER_ICONS.set) !== null && _a !== void 0 ? _a : 'complete'),
68
45
  JUPYTER_NOTEBOOK_SPRITE_SHEET
69
46
  ].join('\n');
70
- /**
71
- * Resolver instance reused across calls to {@link getTreeIcon}. The resolver
72
- * is pure relative to the icon config, so building it once at module load
73
- * avoids re-walking the icon rules on every diff that opens.
74
- */
75
47
  const treeIconResolver = createFileTreeIconResolver(FILE_BROWSER_ICONS);
76
48
  /**
77
- * Cache of LabIcons keyed by the resolved sprite symbol id (e.g.
78
- * `file-tree-builtin-python`). All Python files share the same icon, so
79
- * caching by symbol id prevents repeated LabIcon registration warnings and
80
- * keeps the JupyterLab icon registry small.
49
+ * LabIcons keyed by resolved symbol id — re-registering a LabIcon under the
50
+ * same name logs warnings.
81
51
  */
82
52
  const TREE_ICON_CACHE = new Map();
83
- /**
84
- * Extract the inner SVG markup and viewBox of the `<symbol>` with the given
85
- * id from {@link COMBINED_SPRITE_SHEETS}. Returns `null` if no matching
86
- * symbol exists, in which case the caller falls back to JupyterLab's default
87
- * file icon.
88
- */
89
53
  function extractSymbol(symbolId) {
90
54
  var _a;
91
- // Match a `<symbol>` whose `id` attribute equals `symbolId` (allowing other
92
- // attributes in any order). The `[\s\S]*?` body is non-greedy so we stop
93
- // at the first matching `</symbol>` even when multiple symbols sit
55
+ // Non-greedy body: stop at the first `</symbol>` when symbols sit
94
56
  // back-to-back in the sheet.
95
57
  const escaped = symbolId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
96
58
  const symbolRegex = new RegExp(`<symbol\\b[^>]*\\bid="${escaped}"[^>]*>([\\s\\S]*?)</symbol>`, 'i');
@@ -105,14 +67,10 @@ function extractSymbol(symbolId) {
105
67
  };
106
68
  }
107
69
  /**
108
- * Fallback colors for the built-in file icons, keyed by the icon token
109
- * `@pierre/trees` resolves for a path (e.g. `python`, `typescript`).
110
- *
111
- * The tree only exposes these as `--trees-file-icon-color-<token>` CSS
112
- * variables scoped to its shadow host, so they resolve to nothing for the
113
- * standalone {@link LabIcon}s {@link getTreeIcon} builds for main-area tabs.
114
- * Mirroring them here lets {@link getBuiltInFileIconColor} bottom out in a
115
- * real color. Each is a `light-dark(…)` pair for dark themes.
70
+ * Fallback colors keyed by the tree's icon token. The tree exposes its colors
71
+ * only as `--trees-file-icon-color-*` vars scoped to its shadow host, so the
72
+ * standalone LabIcons built for main-area tabs need these literals;
73
+ * `light-dark(…)` covers dark themes.
116
74
  */
117
75
  const BUILT_IN_FILE_ICON_COLOR_FALLBACKS = {
118
76
  astro: 'light-dark(#a631be, #d568ea)',
@@ -167,11 +125,8 @@ const BUILT_IN_FILE_ICON_COLOR_FALLBACKS = {
167
125
  zip: 'light-dark(#d47628, #ffa359)'
168
126
  };
169
127
  /**
170
- * Color the file tree would paint for the built-in icon `token`, as a
171
- * self-contained CSS value usable outside the tree's shadow DOM: the tree's
172
- * `--trees-file-icon-color-*` properties when in scope, else the literal from
173
- * {@link BUILT_IN_FILE_ICON_COLOR_FALLBACKS}. Returns `undefined` for unknown
174
- * tokens.
128
+ * The tree's color for `token` as a self-contained CSS value: its CSS vars
129
+ * when in scope, else the mirrored literal. `undefined` for unknown tokens.
175
130
  */
176
131
  function getBuiltInFileIconColor(token) {
177
132
  const fallback = BUILT_IN_FILE_ICON_COLOR_FALLBACKS[token];
@@ -180,9 +135,6 @@ function getBuiltInFileIconColor(token) {
180
135
  }
181
136
  return `var(--trees-file-icon-color-${token}, var(--trees-file-icon-color, ${fallback}))`;
182
137
  }
183
- /**
184
- * Resolve a tree glyph into a standalone `LabIcon`.
185
- */
186
138
  function resolveTreeIcon(filePath) {
187
139
  var _a;
188
140
  const resolved = treeIconResolver.resolveIcon('file-tree-icon-file', filePath);
@@ -196,22 +148,15 @@ function resolveTreeIcon(filePath) {
196
148
  if (symbol === null) {
197
149
  return { icon: null, specific };
198
150
  }
199
- // Built-in language icons paint with `fill="currentColor"` so the colored
200
- // tier of the tree can recolor them by setting `color` on the host
201
- // element. Reproduce that here by setting the same color value as an
202
- // inline `style="color: …"` on the outer `<svg>`. `getBuiltInFileIconColor`
203
- // returns a `var(--trees-…)` chain that bottoms out in `light-dark(…)`,
204
- // which respects the page's `color-scheme` declaration so dark themes pick
205
- // up the brighter variants automatically.
151
+ // Built-in glyphs paint with `fill="currentColor"`; an inline `color`
152
+ // style reproduces the tree's colored tier outside its shadow DOM.
206
153
  const colored = FILE_BROWSER_ICONS.colored === true;
207
154
  const color = colored && resolved.token !== undefined
208
155
  ? getBuiltInFileIconColor(resolved.token)
209
156
  : undefined;
210
157
  const styleAttr = color !== undefined ? ` style="color: ${color};"` : '';
211
- // Prefer a viewBox the resolver supplies (custom sprite overrides may set
212
- // one), then fall back to the symbol's own viewBox so 22x22 sprites like
213
- // the Jupyter notebook glyph render at the right scale rather than being
214
- // cropped to a 16x16 box.
158
+ // Prefer the resolver's viewBox, then the symbol's own, so 22x22 sprites
159
+ // like the notebook glyph aren't cropped to a 16x16 box.
215
160
  const viewBox = (_a = resolved.viewBox) !== null && _a !== void 0 ? _a : symbol.viewBox;
216
161
  const svgstr = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox}"${styleAttr}>${symbol.inner}</svg>`;
217
162
  const icon = new LabIcon({
@@ -31,10 +31,8 @@ const plugin = {
31
31
  },
32
32
  translator: translator !== null && translator !== void 0 ? translator : undefined
33
33
  });
34
- // Ranks just under the Terminals panel in the left sidebar. The shipped
35
- // `layout` setting assigns the default ranks (rank only, no area pin),
36
- // so this browser stays movable via the "Move Widget" context menu; the
37
- // `rank` here is the in-code fallback for when that setting is absent.
34
+ // Rank-only fallback for when the shipped `layout` setting is absent;
35
+ // no area pin, so the browser stays movable via "Move Widget".
38
36
  app.shell.add(browser, 'left', { rank: 2 });
39
37
  if (restorer) {
40
38
  restorer.add(browser, browser.id);
@@ -5,11 +5,28 @@ import { ITranslator } from '@jupyterlab/translation';
5
5
  import { Toolbar } from '@jupyterlab/ui-components';
6
6
  import { ISignal } from '@lumino/signaling';
7
7
  import { AccordionPanel, Widget } from '@lumino/widgets';
8
+ import type { IFileChange } from '../git/tokens';
8
9
  export declare const FILE_BROWSER_ID = "xtralab:file-browser";
10
+ /**
11
+ * The options used to create an {@link XtralabFileBrowser}.
12
+ */
9
13
  interface IXtralabFileBrowserOptions {
14
+ /**
15
+ * The contents manager backing the tree.
16
+ */
10
17
  contentsManager: Contents.IManager;
18
+ /**
19
+ * The document manager used to open files from the tree.
20
+ */
11
21
  docManager: IDocumentManager;
22
+ /**
23
+ * Callback invoked with a file's server path when its row is
24
+ * double-clicked. No double-click handler is installed when absent.
25
+ */
12
26
  onOpenFile?: (serverPath: string) => void;
27
+ /**
28
+ * The application language translator.
29
+ */
13
30
  translator?: ITranslator;
14
31
  }
15
32
  /**
@@ -19,72 +36,57 @@ interface IXtralabFileBrowserOptions {
19
36
  */
20
37
  export interface IXtralabFileBrowser {
21
38
  /**
22
- * The contents manager backing the tree. Exposed so command handlers can
23
- * issue contents operations (rename, delete, copy, …) against the same
24
- * drive the tree was loaded from.
39
+ * The contents manager backing the tree; command handlers issue rename,
40
+ * delete, copy, … against the same drive.
25
41
  */
26
42
  readonly contentsManager: Contents.IManager;
27
43
  /**
28
- * The toolbar shown above the tree. Plugin code populates it with command
29
- * buttons after the widget is constructed.
44
+ * The toolbar above the tree, populated by plugin code after construction.
30
45
  */
31
46
  readonly toolbar: Toolbar;
32
47
  /**
33
- * Canonical paths of the items currently selected in the tree. Folder
34
- * paths carry a trailing slash; file paths do not.
48
+ * Canonical selected paths; folder paths carry a trailing slash.
35
49
  */
36
50
  readonly selectedPaths: readonly string[];
37
51
  /**
38
- * Emits when the tree's selection changes. Commands that have an
39
- * `isVisible` / `isEnabled` predicate should listen so they re-evaluate.
52
+ * Emits when the tree's selection changes.
40
53
  */
41
54
  readonly selectionChanged: ISignal<IXtralabFileBrowser, readonly string[]>;
42
55
  /**
43
- * Emits when {@link refresh} is called. The React component listens and
44
- * re-fetches the directories that were previously loaded so the tree
45
- * matches the contents on disk again.
56
+ * Git changes from the latest status poll, one per staged or unstaged
57
+ * change; paths are repo-relative.
58
+ */
59
+ readonly gitChanges: readonly IFileChange[];
60
+ /**
61
+ * Emits when {@link refresh} is called.
46
62
  */
47
63
  readonly refreshRequested: ISignal<IXtralabFileBrowser, void>;
48
64
  /**
49
- * Emits when the widget is asked to surface a newly-created path
50
- * (for example, after the toolbar's "new folder" command). The React
51
- * component listens and inserts the path into the model so the user
52
- * sees the new item without a full refresh.
65
+ * Emits a newly-created canonical path so the tree inserts it without a
66
+ * full refresh.
53
67
  */
54
68
  readonly pathAdded: ISignal<IXtralabFileBrowser, string>;
55
69
  /**
56
- * Emits when an external caller asks the tree to scroll to and select
57
- * the given canonical path. The React component listens, lazily loads
58
- * any unloaded ancestor directories, expands them, and selects the
59
- * target. Used by the editor breadcrumbs to jump back to a file or
60
- * folder shown in the breadcrumb trail.
70
+ * Emits a canonical path to load, expand, select, and scroll to. Used by
71
+ * the editor breadcrumbs.
61
72
  */
62
73
  readonly revealRequested: ISignal<IXtralabFileBrowser, string>;
63
74
  /**
64
- * Emits when an external caller asks the tree to return to the
65
- * workspace root: clear any current selection and scroll back to the
66
- * first row. Distinct from {@link revealRequested} because the
67
- * workspace root has no tree row of its own — it cannot be reached
68
- * by passing a path.
75
+ * Emits when the tree should return to the workspace root — the root has
76
+ * no tree row of its own, so it cannot be revealed by path.
69
77
  */
70
78
  readonly rootRequested: ISignal<IXtralabFileBrowser, void>;
71
79
  /**
72
- * Emits when an external caller asks the tree to collapse every
73
- * expanded folder. The React component listens and walks the loaded
74
- * directories, calling `.collapse()` on each expanded one.
80
+ * Emits when every expanded folder should collapse.
75
81
  */
76
82
  readonly collapseAllRequested: ISignal<IXtralabFileBrowser, void>;
77
83
  /**
78
- * Whether the filter box above the tree is shown. Mirrors the default
79
- * file browser's `showFileFilter`: hidden on startup and flipped by the
80
- * toolbar toggle. Also forced to `true` when the tree opens a search
81
- * session on its own — typing a letter while the tree has focus.
84
+ * Whether the filter box above the tree is shown; also forced `true` when
85
+ * the tree opens a search session itself (typing while it has focus).
82
86
  */
83
87
  readonly fileFilterVisible: boolean;
84
88
  /**
85
- * Emits when {@link fileFilterVisible} changes. The React component
86
- * listens to show or hide the filter box; the toggle command listens
87
- * to refresh its toggled state.
89
+ * Emits when {@link fileFilterVisible} changes.
88
90
  */
89
91
  readonly fileFilterVisibleChanged: ISignal<IXtralabFileBrowser, boolean>;
90
92
  /**
@@ -92,22 +94,17 @@ export interface IXtralabFileBrowser {
92
94
  */
93
95
  refresh(): void;
94
96
  /**
95
- * Notify the React component that a new path was created and should
96
- * appear in the tree. `canonicalPath` follows the `@pierre/trees`
97
- * convention: directories carry a trailing slash, files do not.
97
+ * Notify the React component that a new canonical path was created and
98
+ * should appear in the tree.
98
99
  */
99
100
  notifyPathAdded(canonicalPath: string): void;
100
101
  /**
101
- * Ask the tree to reveal {@link canonicalPath}: load and expand any
102
- * unloaded ancestor directories, then select and scroll the target
103
- * into view. `canonicalPath` follows the `@pierre/trees` convention
104
- * (directories carry a trailing slash, files do not). Must be a
105
- * non-empty path — use {@link scrollToRoot} for the root gesture.
102
+ * Reveal a non-empty canonical path: load and expand ancestors, then
103
+ * select and scroll to it. Use {@link scrollToRoot} for the root gesture.
106
104
  */
107
105
  reveal(canonicalPath: string): void;
108
106
  /**
109
- * Ask the tree to return to the workspace root: clear any current
110
- * selection and scroll back to the top of the tree.
107
+ * Return to the workspace root: clear the selection and scroll to the top.
111
108
  */
112
109
  scrollToRoot(): void;
113
110
  /**
@@ -122,6 +119,10 @@ export interface IXtralabFileBrowser {
122
119
  * Toggle the filter box above the tree.
123
120
  */
124
121
  toggleFileFilter(): void;
122
+ /**
123
+ * The DOM node of the movable "Files" section, used to locate the panel
124
+ * currently hosting the tree.
125
+ */
125
126
  readonly sectionNode: HTMLElement;
126
127
  }
127
128
  /**
@@ -131,41 +132,128 @@ export interface IXtralabFileBrowser {
131
132
  */
132
133
  export declare class XtralabFileBrowser extends Widget implements IXtralabFileBrowser, IMovableSectionSource, IMovableSectionDestination {
133
134
  constructor(options: IXtralabFileBrowserOptions);
135
+ /**
136
+ * The contents manager backing the tree.
137
+ */
134
138
  get contentsManager(): Contents.IManager;
139
+ /**
140
+ * The toolbar above the tree.
141
+ */
135
142
  get toolbar(): Toolbar;
143
+ /**
144
+ * Canonical selected paths; folder paths carry a trailing slash.
145
+ */
136
146
  get selectedPaths(): readonly string[];
147
+ /**
148
+ * A signal emitted when the tree's selection changes.
149
+ */
137
150
  get selectionChanged(): ISignal<this, readonly string[]>;
151
+ /**
152
+ * Git changes from the latest status poll.
153
+ */
154
+ get gitChanges(): readonly IFileChange[];
155
+ /**
156
+ * A signal emitted when {@link refresh} is called.
157
+ */
138
158
  get refreshRequested(): ISignal<this, void>;
159
+ /**
160
+ * A signal emitting a newly-created canonical path for the tree to insert.
161
+ */
139
162
  get pathAdded(): ISignal<this, string>;
163
+ /**
164
+ * A signal emitting a canonical path to load, expand, select, and scroll to.
165
+ */
140
166
  get revealRequested(): ISignal<this, string>;
167
+ /**
168
+ * A signal emitted when the tree should return to the workspace root.
169
+ */
141
170
  get rootRequested(): ISignal<this, void>;
171
+ /**
172
+ * A signal emitted when every expanded folder should collapse.
173
+ */
142
174
  get collapseAllRequested(): ISignal<this, void>;
175
+ /**
176
+ * Whether the filter box above the tree is shown.
177
+ */
143
178
  get fileFilterVisible(): boolean;
179
+ /**
180
+ * A signal emitted when {@link fileFilterVisible} changes.
181
+ */
144
182
  get fileFilterVisibleChanged(): ISignal<this, boolean>;
145
183
  /**
146
- * Update the cached selection. Called from the React tree when the
147
- * underlying `@pierre/trees` model emits a selection change.
184
+ * Update the cached selection from the React tree.
148
185
  */
149
186
  updateSelection(paths: readonly string[]): void;
187
+ /**
188
+ * Update the cached git changes from the React tree's status poll.
189
+ */
190
+ updateGitChanges(changes: readonly IFileChange[]): void;
191
+ /**
192
+ * Trigger a refresh of every loaded directory in the tree.
193
+ */
150
194
  refresh(): void;
195
+ /**
196
+ * Notify the tree that a new canonical path was created.
197
+ */
151
198
  notifyPathAdded(canonicalPath: string): void;
199
+ /**
200
+ * Reveal a non-empty canonical path in the tree; use {@link scrollToRoot}
201
+ * for the workspace root, which has no tree row of its own.
202
+ */
152
203
  reveal(canonicalPath: string): void;
204
+ /**
205
+ * Return to the workspace root: clear the selection and scroll to the top.
206
+ */
153
207
  scrollToRoot(): void;
208
+ /**
209
+ * Ask the tree to collapse every currently expanded folder.
210
+ */
154
211
  collapseAll(): void;
212
+ /**
213
+ * Show or hide the filter box above the tree.
214
+ */
155
215
  setFileFilterVisible(visible: boolean): void;
216
+ /**
217
+ * Toggle the filter box above the tree.
218
+ */
156
219
  toggleFileFilter(): void;
220
+ /**
221
+ * The DOM node of the movable "Files" section.
222
+ */
157
223
  get sectionNode(): HTMLElement;
224
+ /**
225
+ * Whether the panel currently holds no sections, its own tree included.
226
+ */
158
227
  get isEmpty(): boolean;
228
+ /**
229
+ * A signal emitted when a section is added to or removed from the panel.
230
+ */
159
231
  get contentChanged(): ISignal<this, void>;
232
+ /**
233
+ * A signal emitting each section entry announced to the move plugin.
234
+ */
160
235
  get sectionAdded(): ISignal<this, ISectionEntry>;
236
+ /**
237
+ * The accordion hosting the sections, or `null` while the tree sits alone.
238
+ */
161
239
  get accordionPanel(): AccordionPanel | null;
240
+ /**
241
+ * Section widgets hosted from other panels; the tree section is excluded.
242
+ */
162
243
  get sections(): ReadonlyArray<Widget>;
163
244
  /**
164
245
  * The toolbar is the section's title node: it is the tree's header row at
165
246
  * home, and an accordion host renders it inside the section title.
166
247
  */
167
248
  getSections(): ReadonlyArray<ISectionEntry>;
249
+ /**
250
+ * Detach and return the tree section so the move plugin can re-host it;
251
+ * `null` for any other id or when the section is already away from home.
252
+ */
168
253
  removeSectionById(sectionId: string): Widget | null;
254
+ /**
255
+ * Re-attach the tree section after a move back to this panel.
256
+ */
169
257
  reinsertSection(widget: Widget): void;
170
258
  /**
171
259
  * The move plugin reconciles persisted moves only against sections announced
@@ -176,6 +264,10 @@ export declare class XtralabFileBrowser extends Widget implements IXtralabFileBr
176
264
  * The first hosted section moves the tree into an accordion.
177
265
  */
178
266
  addSection(widget: Widget): void;
267
+ /**
268
+ * Remove a hosted section; the accordion is torn down once only the
269
+ * panel's own tree section (or nothing) remains.
270
+ */
179
271
  removeSectionWidget(widget: Widget): void;
180
272
  private _isSectionHome;
181
273
  /**
@@ -189,6 +281,7 @@ export declare class XtralabFileBrowser extends Widget implements IXtralabFileBr
189
281
  private _translator;
190
282
  private _selectedPaths;
191
283
  private _selectionChanged;
284
+ private _gitChanges;
192
285
  private _refreshRequested;
193
286
  private _pathAdded;
194
287
  private _revealRequested;