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
package/README.md CHANGED
@@ -2,19 +2,18 @@
2
2
 
3
3
  An opinionated JupyterLab meta-package for coding agents.
4
4
 
5
- xtralab reshapes JupyterLab around terminal coding agents. It bundles a curated
6
- set of extensions, a path-first file browser, rich git diffs, an agent launcher,
7
- a Model Context Protocol server that lets agents drive the app, and a quieter
8
- set of defaults. It builds on [`ajlab`](https://github.com/jtpio/ajlab), the
9
- agent-ready JupyterLab base.
10
-
11
- ![The xtralab workspace: path-first file browser, agent launcher, a side-by-side git diff, and a running Claude Code session](./images/hero.webp)
12
-
13
- The [documentation](https://jtpio.github.io/xtralab/) covers everything in
14
- detail: [installation](https://jtpio.github.io/xtralab/installation/), a
15
- [tour of the features](https://jtpio.github.io/xtralab/getting-started/),
16
- [connecting agents over MCP](https://jtpio.github.io/xtralab/agents/mcp/),
17
- [agent skills](https://jtpio.github.io/xtralab/agents/skills/), and the
5
+ xtralab installs JupyterLab with a set of extensions and defaults for work
6
+ with terminal coding agents: an agent launcher, side-by-side git diffs for
7
+ text files and notebooks, prompts about selected code, and a Model Context
8
+ Protocol server that lets agents drive the app. It builds on
9
+ [`ajlab`](https://github.com/jtpio/ajlab), the agent-ready JupyterLab base.
10
+
11
+ ![The xtralab workspace: file browser, agent launcher, a side-by-side git diff, and a running Claude Code session](./images/hero.webp)
12
+
13
+ See the [documentation](https://jtpio.github.io/xtralab/) for the
14
+ [installation](https://jtpio.github.io/xtralab/installation/), a
15
+ [getting started tutorial](https://jtpio.github.io/xtralab/getting-started/),
16
+ the [features](https://jtpio.github.io/xtralab/features/launcher/), and the
18
17
  [desktop app](https://jtpio.github.io/xtralab/desktop/).
19
18
 
20
19
  ## Install
@@ -24,24 +23,60 @@ pip install xtralab
24
23
  jupyter lab
25
24
  ```
26
25
 
27
- A standalone desktop app (DMG on macOS, AppImage on Linux) ships with every
28
- tagged release on the
29
- [releases page](https://github.com/jtpio/xtralab/releases/latest). The macOS
30
- app is signed and notarized and keeps itself up to date; see the
31
- [desktop app docs](https://jtpio.github.io/xtralab/desktop/) for how it
32
- manages projects and kernels.
26
+ To run xtralab in any folder without installing it, use uv:
27
+
28
+ ```bash
29
+ uvx --from xtralab jupyter-lab
30
+ ```
31
+
32
+ The [installation docs](https://jtpio.github.io/xtralab/installation/) also
33
+ show how to install xtralab as a uv tool or add it to a project.
34
+
35
+ The desktop app (DMG on macOS, AppImage on Linux) is on the
36
+ [releases page](https://github.com/jtpio/xtralab/releases/latest). It
37
+ includes its own Python runtime. See the
38
+ [desktop app docs](https://jtpio.github.io/xtralab/desktop/).
33
39
 
34
40
  ## Highlights
35
41
 
36
- ![The xtralab launcher](./images/launcher.webp)
42
+ ### Agent launcher
43
+
44
+ Start any coding agent installed on your machine, with an optional first
45
+ prompt. The **Changes** list opens the diff of each changed file.
46
+ [Read more](https://jtpio.github.io/xtralab/features/launcher/).
47
+
48
+ <img src="./images/launcher.webp" width="720" alt="The launcher: a prompt box, one button per installed agent, the Open section, and the list of changed files" />
49
+
50
+ ### Git diffs
51
+
52
+ Review changes side by side, for text files and for notebooks, and edit the
53
+ working copy in the diff.
54
+ [Read more](https://jtpio.github.io/xtralab/features/git-diffs/).
55
+
56
+ <img src="./images/diff.webp" width="1000" alt="A side-by-side diff of a Python file, with removed lines on the left and added lines on the right" />
57
+
58
+ ### Ask an agent
59
+
60
+ Select code, type an instruction, and send it to a new or running agent. The
61
+ prompt includes the file path, the line range, and the selected code.
62
+ [Read more](https://jtpio.github.io/xtralab/features/ask-agent/).
63
+
64
+ <img src="./images/ask-agent.webp" width="796" alt="The prompt box below a selected function, with an instruction and one button per agent" />
65
+
66
+ ### Omnibox
67
+
68
+ Search files and commands, or send a prompt to an agent, from one search box
69
+ (<kbd>Cmd/Ctrl</kbd>+<kbd>K</kbd>).
70
+ [Read more](https://jtpio.github.io/xtralab/features/omnibox/).
71
+
72
+ <img src="./images/omnibox.webp" width="642" alt="The omnibox with matching commands, a matching file, and one Ask row per agent" />
73
+
74
+ ### Terminals panel
75
+
76
+ See the agent in each terminal and its latest line of output.
77
+ [Read more](https://jtpio.github.io/xtralab/features/terminals/).
37
78
 
38
- The launcher starts any agent installed on your machine, with an optional
39
- prompt and a **Changes** list that jumps straight into a side-by-side git diff
40
- you can edit in place. Select code in an editor, a notebook, or a diff to send
41
- a prompt about it to a new or already-running agent, or queue prompts while
42
- you read. One omnibox searches files and commands, the Terminals panel shows
43
- which agent runs where, and quieter defaults keep the workspace calm. The
44
- [documentation](https://jtpio.github.io/xtralab/) walks through each of these.
79
+ <img src="./images/terminals.webp" width="451" alt="The Terminals panel with three agent sessions and their latest output" />
45
80
 
46
81
  ## Connecting agents to JupyterLab (MCP)
47
82
 
@@ -54,9 +89,9 @@ xtralab:
54
89
  claude mcp add jupyter -- jupyter-server-mcp-proxy
55
90
  ```
56
91
 
57
- The launcher surfaces the matching command for every agent you have
58
- installed, and the [MCP docs page](https://jtpio.github.io/xtralab/agents/mcp/)
59
- covers the details.
92
+ The launcher shows this command for each installed agent. See the
93
+ [MCP docs](https://jtpio.github.io/xtralab/agents/mcp/) for Codex, GitHub
94
+ Copilot, and other agents.
60
95
 
61
96
  [mcp]: https://github.com/jupyter-ai-contrib/jupyter-server-mcp
62
97
  [mcp-spec]: https://modelcontextprotocol.io
@@ -1,7 +1,2 @@
1
1
  import { LabIcon } from '@jupyterlab/ui-components';
2
- /**
3
- * The project logo mark — `logo.svg` at the repository root, the same file
4
- * the README and the docs site use. The labextension build inlines it as a
5
- * raw string, so the dialog always shows the current artwork.
6
- */
7
2
  export declare const aboutLogoIcon: LabIcon;
@@ -1,10 +1,5 @@
1
1
  import { LabIcon } from '@jupyterlab/ui-components';
2
2
  import logoSvgstr from '../../logo.svg';
3
- /**
4
- * The project logo mark — `logo.svg` at the repository root, the same file
5
- * the README and the docs site use. The labextension build inlines it as a
6
- * raw string, so the dialog always shows the current artwork.
7
- */
8
3
  export const aboutLogoIcon = new LabIcon({
9
4
  name: 'xtralab:about-logo',
10
5
  svgstr: logoSvgstr
@@ -1,13 +1,9 @@
1
1
  import { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
2
  /**
3
- * An "About xtralab" dialog replacing the stock "About JupyterLab" one.
4
- *
5
- * The upstream `@jupyterlab/help-extension:about` plugin is disabled via
6
- * `jupyterlab.disabledExtensions` (package.json), which removes both its
7
- * `help:about` command and its Help menu contribution; this plugin registers
8
- * the same command id and restores the menu entry through its own schema.
9
- * The dialog leads with the xtralab version and keeps the underlying
10
- * JupyterLab version visible underneath.
3
+ * An "About xtralab" dialog replacing the stock "About JupyterLab" one. The
4
+ * upstream plugin is disabled via `jupyterlab.disabledExtensions`, which also
5
+ * removes its Help menu entry; this plugin re-registers `help:about` and
6
+ * restores the menu entry through its own schema.
11
7
  */
12
8
  declare const plugin: JupyterFrontEndPlugin<void>;
13
9
  export default plugin;
@@ -4,24 +4,15 @@ import { ITranslator, nullTranslator } from '@jupyterlab/translation';
4
4
  import * as React from 'react';
5
5
  import { aboutLogoIcon } from './icons';
6
6
  const PLUGIN_ID = 'xtralab:about';
7
- /**
8
- * Upstream command id. Reusing it keeps the Help menu entry (contributed by
9
- * `schema/about.json` at the same rank as upstream), the command palette
10
- * muscle memory, and any external caller of `help:about` working.
11
- */
12
7
  const CommandIDs = {
13
8
  about: 'help:about'
14
9
  };
15
10
  const REPO_URL = 'https://github.com/jtpio/xtralab';
16
11
  /**
17
- * An "About xtralab" dialog replacing the stock "About JupyterLab" one.
18
- *
19
- * The upstream `@jupyterlab/help-extension:about` plugin is disabled via
20
- * `jupyterlab.disabledExtensions` (package.json), which removes both its
21
- * `help:about` command and its Help menu contribution; this plugin registers
22
- * the same command id and restores the menu entry through its own schema.
23
- * The dialog leads with the xtralab version and keeps the underlying
24
- * JupyterLab version visible underneath.
12
+ * An "About xtralab" dialog replacing the stock "About JupyterLab" one. The
13
+ * upstream plugin is disabled via `jupyterlab.disabledExtensions`, which also
14
+ * removes its Help menu entry; this plugin re-registers `help:about` and
15
+ * restores the menu entry through its own schema.
25
16
  */
26
17
  const plugin = {
27
18
  id: PLUGIN_ID,
@@ -41,10 +32,8 @@ const plugin = {
41
32
  }
42
33
  },
43
34
  execute: async () => {
44
- // The settings payload carries the version of the installed
45
- // labextension (read server-side from its package.json), which is
46
- // the release actually running — the page config only knows the
47
- // JupyterLab version. 'N/A' is jupyterlab_server's not-found value.
35
+ // The settings payload carries the installed labextension's version
36
+ // (page config only knows JupyterLab's); 'N/A' is jupyterlab_server's not-found value.
48
37
  const version = await settingRegistry
49
38
  .load(PLUGIN_ID)
50
39
  .then(settings => settings.version === 'N/A' ? '' : settings.version)
@@ -2,28 +2,14 @@ import type { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
2
  import { Token } from '@lumino/coreutils';
3
3
  import { ISignal } from '@lumino/signaling';
4
4
  /**
5
- * A shared map from a terminal session name to the agent command it was
6
- * *launched* with (e.g. `claude`).
7
- *
8
- * This is the optimistic half of the running-agent badge: when the launcher
9
- * (or the terminals panel's `+` menu) starts an agent via a
10
- * `xtralab:start-agent:<id>` command, it records the session here so the
11
- * panel can show the agent's logo immediately, before the server-side
12
- * process detection has had a chance to confirm it. Server detection is the
13
- * authoritative source once it reports on a session; this tag only fills the
14
- * gap right after launch (and serves as a fallback if detection is
15
- * unavailable).
16
- *
17
- * It exists as its own token, provided by a tiny dependency-free plugin,
18
- * specifically so the launcher (the writer) and the terminals panel (the
19
- * reader) can share it without depending on each other — a direct
20
- * launcher↔terminals token pair would form an activation cycle.
5
+ * Shared map from terminal session name to the agent command it was launched
6
+ * with — the optimistic half of the running-agent badge, shown until server
7
+ * detection confirms. Its own token so the launcher (writer) and terminals
8
+ * panel (reader) can share it without an activation cycle.
21
9
  */
22
10
  export interface IAgentSessions {
23
11
  /**
24
- * The agent command a session was launched with, or `null` if we never
25
- * launched an agent into it (e.g. a plain terminal, or one started before
26
- * this ran).
12
+ * The agent command a session was launched with, or `null` if unknown.
27
13
  */
28
14
  get(sessionName: string): string | null;
29
15
  /**
@@ -31,24 +17,18 @@ export interface IAgentSessions {
31
17
  */
32
18
  set(sessionName: string, command: string): void;
33
19
  /**
34
- * Forget a session — called when it shuts down so the map stays bounded.
20
+ * Forget a session so the map stays bounded.
35
21
  */
36
22
  delete(sessionName: string): void;
37
23
  /**
38
- * Emitted with the affected session name whenever a record is added or
39
- * removed, so readers can re-render.
24
+ * Emitted with the session name whenever a record is added or removed.
40
25
  */
41
26
  readonly changed: ISignal<IAgentSessions, string>;
42
27
  }
43
- /**
44
- * DI token for {@link IAgentSessions}. Provided by `xtralab:agent-sessions`;
45
- * consumed (optionally) by both `xtralab:launcher` and `xtralab:terminals`.
46
- */
47
28
  export declare const IAgentSessions: Token<IAgentSessions>;
48
29
  /**
49
- * Provides {@link IAgentSessions}. Deliberately has no dependencies so it can
50
- * sit underneath both the launcher and the terminals panel without creating
51
- * a dependency cycle between them.
30
+ * Provides {@link IAgentSessions}; dependency-free so it can sit underneath
31
+ * both the launcher and the terminals panel.
52
32
  */
53
33
  declare const plugin: JupyterFrontEndPlugin<IAgentSessions>;
54
34
  export default plugin;
@@ -1,9 +1,5 @@
1
1
  import { Token } from '@lumino/coreutils';
2
2
  import { Signal } from '@lumino/signaling';
3
- /**
4
- * DI token for {@link IAgentSessions}. Provided by `xtralab:agent-sessions`;
5
- * consumed (optionally) by both `xtralab:launcher` and `xtralab:terminals`.
6
- */
7
3
  export const IAgentSessions = new Token('xtralab:IAgentSessions', 'A shared map from terminal session name to the agent command it was launched with.');
8
4
  class AgentSessions {
9
5
  constructor() {
@@ -31,9 +27,8 @@ class AgentSessions {
31
27
  }
32
28
  }
33
29
  /**
34
- * Provides {@link IAgentSessions}. Deliberately has no dependencies so it can
35
- * sit underneath both the launcher and the terminals panel without creating
36
- * a dependency cycle between them.
30
+ * Provides {@link IAgentSessions}; dependency-free so it can sit underneath
31
+ * both the launcher and the terminals panel.
37
32
  */
38
33
  const plugin = {
39
34
  id: 'xtralab:agent-sessions',
@@ -3,49 +3,43 @@ import type { EditorView } from '@codemirror/view';
3
3
  import type { Widget } from '@lumino/widgets';
4
4
  import type { IAskAgentRequest } from './tokens';
5
5
  /**
6
- * A CodeMirror view a selection can be asked about, plus the context needed
7
- * to describe it to an agent: the document path and, for notebooks, which
8
- * cell the view belongs to.
6
+ * A CodeMirror view a selection can be asked about, plus the document path
7
+ * and, for notebooks, the owning cell.
9
8
  */
10
9
  interface IEditorTarget {
10
+ /**
11
+ * The CodeMirror view holding the selection.
12
+ */
11
13
  view: EditorView;
14
+ /**
15
+ * The path of the document the view belongs to.
16
+ */
12
17
  path: string;
18
+ /**
19
+ * The index and type of the owning notebook cell; absent for file editors.
20
+ */
13
21
  cell?: {
14
22
  index: number;
15
23
  type: string;
16
24
  };
17
25
  }
18
26
  /**
19
- * Resolve the CodeMirror view a selection in `widget` would live in, or
20
- * `null` when the widget holds no such editor. Two widget shapes are
21
- * recognized:
22
- *
23
- * - a notebook panel, where the active cell carries the editor and
24
- * `activeCellIndex` names its 0-based position in the nbformat `cells`
25
- * array. A rendered markdown cell keeps its (hidden) editor, but a
26
- * selection in the rendered HTML never passes {@link domSelectionInView},
27
- * so no pill appears there; and
28
- * - a document widget whose content is a `FileEditor`. The wrapper is not
29
- * checked with `instanceof DocumentWidget`: `@jupyterlab/docregistry` is
30
- * not a core singleton, so another copy of the class could be in play.
31
- * `FileEditor` and `NotebookPanel` come from singleton packages.
27
+ * Resolve the CodeMirror view a selection in `widget` would live in — the
28
+ * active notebook cell or a `FileEditor` document — or `null`. The wrapper is
29
+ * duck-typed, not `instanceof DocumentWidget`: `@jupyterlab/docregistry` is
30
+ * not a core singleton, unlike `FileEditor` and `NotebookPanel`.
32
31
  */
33
32
  export declare function resolveEditorTarget(widget: Widget | null): IEditorTarget | null;
34
33
  /**
35
- * Whether the current DOM selection lives inside `view`. Guards the
36
- * selection-change listener against selections made elsewhere (a terminal,
37
- * a sidebar, another notebook cell) while the widget owning `view` happens
38
- * to be the shell's current widget.
34
+ * Whether the current DOM selection lives inside `view`; guards against
35
+ * selections made elsewhere while the owning widget is current.
39
36
  */
40
37
  export declare function domSelectionInView(view: EditorView, selection: Selection): boolean;
41
38
  /**
42
39
  * Build an ask-agent request from the current selection in the shell's
43
- * current widget — a file editor or the active notebook cell — or return
44
- * `null` when that widget holds no CodeMirror document editor.
45
- *
46
- * With `allowEmpty`, a collapsed selection falls back to the cursor's line
47
- * (used by the command/shortcut path so it works without a mouse
48
- * selection); otherwise an empty selection yields `null`.
40
+ * current widget, or `null` when it holds no CodeMirror document editor.
41
+ * With `allowEmpty`, a collapsed selection falls back to the cursor's line;
42
+ * otherwise it yields `null`.
49
43
  */
50
44
  export declare function editorAskRequest(app: JupyterFrontEnd, options?: {
51
45
  allowEmpty?: boolean;
@@ -2,19 +2,10 @@ import { CodeMirrorEditor } from '@jupyterlab/codemirror';
2
2
  import { FileEditor } from '@jupyterlab/fileeditor';
3
3
  import { NotebookPanel } from '@jupyterlab/notebook';
4
4
  /**
5
- * Resolve the CodeMirror view a selection in `widget` would live in, or
6
- * `null` when the widget holds no such editor. Two widget shapes are
7
- * recognized:
8
- *
9
- * - a notebook panel, where the active cell carries the editor and
10
- * `activeCellIndex` names its 0-based position in the nbformat `cells`
11
- * array. A rendered markdown cell keeps its (hidden) editor, but a
12
- * selection in the rendered HTML never passes {@link domSelectionInView},
13
- * so no pill appears there; and
14
- * - a document widget whose content is a `FileEditor`. The wrapper is not
15
- * checked with `instanceof DocumentWidget`: `@jupyterlab/docregistry` is
16
- * not a core singleton, so another copy of the class could be in play.
17
- * `FileEditor` and `NotebookPanel` come from singleton packages.
5
+ * Resolve the CodeMirror view a selection in `widget` would live in — the
6
+ * active notebook cell or a `FileEditor` document — or `null`. The wrapper is
7
+ * duck-typed, not `instanceof DocumentWidget`: `@jupyterlab/docregistry` is
8
+ * not a core singleton, unlike `FileEditor` and `NotebookPanel`.
18
9
  */
19
10
  export function resolveEditorTarget(widget) {
20
11
  if (widget instanceof NotebookPanel) {
@@ -36,10 +27,8 @@ export function resolveEditorTarget(widget) {
36
27
  return null;
37
28
  }
38
29
  /**
39
- * Whether the current DOM selection lives inside `view`. Guards the
40
- * selection-change listener against selections made elsewhere (a terminal,
41
- * a sidebar, another notebook cell) while the widget owning `view` happens
42
- * to be the shell's current widget.
30
+ * Whether the current DOM selection lives inside `view`; guards against
31
+ * selections made elsewhere while the owning widget is current.
43
32
  */
44
33
  export function domSelectionInView(view, selection) {
45
34
  var _a;
@@ -49,12 +38,9 @@ export function domSelectionInView(view, selection) {
49
38
  }
50
39
  /**
51
40
  * Build an ask-agent request from the current selection in the shell's
52
- * current widget — a file editor or the active notebook cell — or return
53
- * `null` when that widget holds no CodeMirror document editor.
54
- *
55
- * With `allowEmpty`, a collapsed selection falls back to the cursor's line
56
- * (used by the command/shortcut path so it works without a mouse
57
- * selection); otherwise an empty selection yields `null`.
41
+ * current widget, or `null` when it holds no CodeMirror document editor.
42
+ * With `allowEmpty`, a collapsed selection falls back to the cursor's line;
43
+ * otherwise it yields `null`.
58
44
  */
59
45
  export function editorAskRequest(app, options = {}) {
60
46
  const target = resolveEditorTarget(app.shell.currentWidget);
@@ -75,13 +61,12 @@ export function editorAskRequest(app, options = {}) {
75
61
  text = state.doc.lineAt(main.from).text;
76
62
  }
77
63
  else {
78
- // A selection that ends exactly at the start of a line (the common
79
- // "drag over whole lines" gesture) should not count that line.
64
+ // A selection ending exactly at a line start (the whole-line drag
65
+ // gesture) should not count that line.
80
66
  const endPos = main.to === state.doc.lineAt(main.to).from ? main.to - 1 : main.to;
81
67
  endLine = state.doc.lineAt(endPos).number;
82
68
  text = state.sliceDoc(main.from, main.to);
83
69
  }
84
- // Anchor the popup at the selection head (where the cursor ended up).
85
70
  // `coordsAtPos` returns `null` for positions scrolled out of view.
86
71
  const coords = view.coordsAtPos(main.head);
87
72
  const anchor = coords
@@ -1,7 +1,6 @@
1
1
  import { LabIcon } from '@jupyterlab/ui-components';
2
2
  /**
3
- * Four-point sparkle used by the ask-agent affordances (selection pill,
4
- * command palette entry). Drawn in-repo; the `jp-icon3` class lets the
5
- * active theme recolor the glyph like other JupyterLab UI icons.
3
+ * Four-point sparkle used by the ask-agent affordances; the `jp-icon3`
4
+ * class lets the active theme recolor the glyph.
6
5
  */
7
6
  export declare const askAgentIcon: LabIcon;
@@ -1,8 +1,7 @@
1
1
  import { LabIcon } from '@jupyterlab/ui-components';
2
2
  /**
3
- * Four-point sparkle used by the ask-agent affordances (selection pill,
4
- * command palette entry). Drawn in-repo; the `jp-icon3` class lets the
5
- * active theme recolor the glyph like other JupyterLab UI icons.
3
+ * Four-point sparkle used by the ask-agent affordances; the `jp-icon3`
4
+ * class lets the active theme recolor the glyph.
6
5
  */
7
6
  export const askAgentIcon = new LabIcon({
8
7
  name: 'xtralab:ask-agent',
@@ -1,32 +1,10 @@
1
1
  import { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
2
  import { IAskAgent } from './tokens';
3
3
  /**
4
- * Select code in a file editor (or pick diff lines) and prompt a coding
5
- * agent about it.
6
- *
7
- * The plugin watches the document selection: a non-empty selection inside a
8
- * CodeMirror file editor or notebook cell grows a small floating "Ask agent"
9
- * pill next to the selection. Clicking it (or running `xtralab:ask-agent`,
10
- * bound to Accel+. in editors and notebooks) opens a popup where the user
11
- * types an instruction, picks one of the launcher's agents and picks where
12
- * the prompt goes; submitting either starts that agent in a fresh terminal
13
- * via `xtralab:start-agent:<id>`, or pastes the prompt into an agent already
14
- * running in one of the open terminal sessions (via `IAgentTerminals`; the
15
- * agent CLIs queue prompts that arrive while they are busy). Sends to a
16
- * running agent stay in the background — focus never leaves the editor, and
17
- * a success toast offers to open the terminal. Either way the prompt embeds
18
- * the file path, cell index for notebooks, line range and selected snippet.
19
- *
20
- * The popup's Queue button (or Accel+Enter) defers the send instead: the
21
- * comment lands in a persistent queue, stamped with the popup's selected
22
- * destination — every queued prompt is independent and may aim at a
23
- * different agent or session. A right-sidebar panel reviews the queue
24
- * (edit, retarget, remove) and flushes it in one go, combining prompts that
25
- * share a destination into a single numbered message. The queue survives
26
- * page reloads.
27
- *
28
- * The same popup is provided on the `IAskAgent` token so the git diff
29
- * viewers can open it for a selected diff line range.
4
+ * Prompt a coding agent about selected code: a pill/popup over editor,
5
+ * notebook-cell and git-diff selections sends the instruction to a fresh
6
+ * agent terminal or into a running one, or defers it into a persistent
7
+ * queue reviewed in a right-sidebar panel and flushed as one batch.
30
8
  */
31
9
  declare const plugin: JupyterFrontEndPlugin<IAskAgent>;
32
10
  export default plugin;