xtralab 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -73
- package/lib/agentSessions.d.ts +50 -0
- package/lib/agentSessions.js +45 -0
- package/lib/fileBrowser/index.js +5 -1
- package/lib/git/commands.d.ts +12 -13
- package/lib/git/commands.js +7 -28
- package/lib/git/diffProvider.d.ts +8 -0
- package/lib/git/diffProvider.js +314 -0
- package/lib/git/diffSurface.d.ts +115 -0
- package/lib/git/diffSurface.js +342 -0
- package/lib/git/diffWidget.d.ts +8 -13
- package/lib/git/diffWidget.js +65 -311
- package/lib/git/imageDiff.d.ts +23 -0
- package/lib/git/imageDiff.js +256 -0
- package/lib/git/index.d.ts +10 -8
- package/lib/git/index.js +37 -52
- package/lib/index.d.ts +4 -2
- package/lib/index.js +14 -8
- package/lib/launcher/agents.d.ts +1 -1
- package/lib/launcher/agents.js +22 -13
- package/lib/launcher/commands.d.ts +32 -6
- package/lib/launcher/commands.js +81 -57
- package/lib/launcher/dashboard.d.ts +15 -0
- package/lib/launcher/dashboard.js +119 -5
- package/lib/launcher/editorRegistry.d.ts +43 -0
- package/lib/launcher/editorRegistry.js +96 -0
- package/lib/launcher/editors.d.ts +78 -0
- package/lib/launcher/editors.js +110 -0
- package/lib/launcher/icons.d.ts +25 -6
- package/lib/launcher/icons.js +116 -19
- package/lib/launcher/index.d.ts +2 -22
- package/lib/launcher/index.js +48 -25
- package/lib/launcher/registry.d.ts +21 -0
- package/lib/launcher/registry.js +28 -0
- package/lib/launcher/tokens.d.ts +41 -0
- package/lib/launcher/tokens.js +17 -0
- package/lib/terminals/detection.d.ts +11 -0
- package/lib/terminals/detection.js +50 -0
- package/lib/terminals/index.d.ts +27 -0
- package/lib/terminals/index.js +194 -0
- package/lib/terminals/model.d.ts +191 -0
- package/lib/terminals/model.js +418 -0
- package/lib/terminals/widget.d.ts +72 -0
- package/lib/terminals/widget.js +93 -0
- package/lib/topBar/icons.d.ts +13 -0
- package/lib/topBar/icons.js +27 -0
- package/lib/topBar/index.d.ts +16 -0
- package/lib/topBar/index.js +86 -0
- package/package.json +52 -35
- package/schema/launcher.json +56 -1
- package/src/agentSessions.ts +94 -0
- package/src/fileBrowser/index.ts +5 -1
- package/src/git/commands.ts +12 -38
- package/src/git/diffProvider.tsx +462 -0
- package/src/git/diffSurface.tsx +588 -0
- package/src/git/diffWidget.tsx +105 -465
- package/src/git/imageDiff.tsx +469 -0
- package/src/git/index.ts +38 -68
- package/src/index.ts +14 -8
- package/src/launcher/agents.ts +23 -14
- package/src/launcher/commands.ts +98 -60
- package/src/launcher/dashboard.tsx +205 -3
- package/src/launcher/editorRegistry.ts +149 -0
- package/src/launcher/editors.ts +183 -0
- package/src/launcher/icons.ts +120 -20
- package/src/launcher/index.ts +62 -27
- package/src/launcher/registry.ts +33 -0
- package/src/launcher/tokens.ts +51 -0
- package/src/terminals/detection.ts +65 -0
- package/src/terminals/index.ts +222 -0
- package/src/terminals/model.ts +497 -0
- package/src/terminals/widget.tsx +240 -0
- package/src/topBar/icons.ts +30 -0
- package/src/topBar/index.ts +121 -0
- package/style/git.css +267 -266
- package/style/index.css +2 -1
- package/style/index.js +2 -1
- package/style/launcher.css +124 -2
- package/style/terminals.css +235 -0
- package/style/topBar.css +38 -0
- package/lib/git/icons.d.ts +0 -14
- package/lib/git/icons.js +0 -19
- package/lib/git/panel.d.ts +0 -29
- package/lib/git/panel.js +0 -42
- package/lib/git/panelComponent.d.ts +0 -28
- package/lib/git/panelComponent.js +0 -320
- package/lib/statusBar/index.d.ts +0 -14
- package/lib/statusBar/index.js +0 -89
- package/lib/statusBar/widget.d.ts +0 -121
- package/lib/statusBar/widget.js +0 -237
- package/src/git/icons.ts +0 -20
- package/src/git/panel.tsx +0 -56
- package/src/git/panelComponent.tsx +0 -575
- package/src/statusBar/index.ts +0 -115
- package/src/statusBar/widget.tsx +0 -318
- package/style/statusBar.css +0 -95
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# xtralab
|
|
2
2
|
|
|
3
|
-
An opinionated JupyterLab meta-package.
|
|
3
|
+
An opinionated JupyterLab meta-package for use with coding agents.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
git
|
|
5
|
+
It bundles a curated set of JupyterLab extensions, a path-first file browser,
|
|
6
|
+
git diffs rendered by xtralab, an agent launcher, and a quieter default
|
|
7
|
+
workspace.
|
|
7
8
|
|
|
8
9
|

|
|
9
10
|
|
|
@@ -17,7 +18,7 @@ pip install xtralab
|
|
|
17
18
|
|
|
18
19
|
### As a JupyterLab package
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
Once installed, start JupyterLab the usual way:
|
|
21
22
|
|
|
22
23
|
```bash
|
|
23
24
|
jupyter lab
|
|
@@ -25,81 +26,84 @@ jupyter lab
|
|
|
25
26
|
|
|
26
27
|
### As a desktop app
|
|
27
28
|
|
|
28
|
-
A standalone Electron build
|
|
29
|
-
|
|
30
|
-
[
|
|
31
|
-
|
|
32
|
-
artifacts under the repository's
|
|
29
|
+
A standalone Electron build is also available, packaged as a DMG on macOS and
|
|
30
|
+
an AppImage on Linux. Each tagged release ships installers on the
|
|
31
|
+
[releases page](https://github.com/jtpio/xtralab/releases/latest), and builds
|
|
32
|
+
from `main` are uploaded as workflow artifacts on the
|
|
33
33
|
[Actions tab](https://github.com/jtpio/xtralab/actions). See
|
|
34
|
-
[CONTRIBUTING.md](./CONTRIBUTING.md) for the architecture and local
|
|
35
|
-
instructions.
|
|
34
|
+
[CONTRIBUTING.md](./CONTRIBUTING.md) for the desktop app architecture and local
|
|
35
|
+
build instructions.
|
|
36
36
|
|
|
37
37
|
## What's included
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- `jupyterlab-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- `jupyterlab-cursor-light`, `jupyterlab-cursor-dark`
|
|
46
|
-
- `jupyterlab-day`, `jupyterlab-night` themes
|
|
39
|
+
xtralab builds on [`ajlab`](https://github.com/jtpio/ajlab), the agent-ready
|
|
40
|
+
JupyterLab base. On top of it, xtralab pulls in JupyterLab 4.6+ with
|
|
41
|
+
`jupyterlab-git`, `jupyterlab-lsp`, `jupyterlab-quickopen`, `jupyterlab-vim`,
|
|
42
|
+
and a set of light and dark themes (`jupyterlab-cursor-light`,
|
|
43
|
+
`jupyterlab-cursor-dark`, `jupyterlab-day`, `jupyterlab-night`). See
|
|
44
|
+
[`pyproject.toml`](./pyproject.toml) for the full list and pinned versions.
|
|
47
45
|
|
|
48
|
-
The bundled labextension adds:
|
|
46
|
+
The bundled xtralab labextension then adds:
|
|
49
47
|
|
|
50
48
|
- A path-first file browser in the left sidebar.
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
- Git diffs rendered by xtralab in the `jupyterlab-git` panel, using
|
|
50
|
+
`@pierre/diffs` for text and notebooks and a 2-up / swipe / onion-skin view
|
|
51
|
+
for images.
|
|
52
|
+
- An agent launcher with a prompt box, buttons for the agents installed on your
|
|
53
|
+
machine (Claude, Codex, Antigravity, Copilot, Goose, OpenCode, Kiro, Mistral
|
|
54
|
+
Vibe), a collapsible list of changed files, and an Open row for a terminal,
|
|
55
|
+
notebook, console, or your terminal editor (Neovim or Vim).
|
|
56
|
+
- A Terminals panel listing the running terminal sessions, each badged with the
|
|
57
|
+
agent or editor detected inside it. Open terminal tabs in the main area carry
|
|
58
|
+
the same icon.
|
|
59
|
+
- Sidebar toggle buttons in the top bar for the left and right areas.
|
|
60
|
+
|
|
61
|
+
## Connecting agents to Jupyter (MCP)
|
|
62
|
+
|
|
63
|
+
xtralab runs a [Model Context Protocol][mcp-spec] server inside JupyterLab,
|
|
64
|
+
provided by [`jupyter-server-mcp`][mcp]. To let a coding agent drive JupyterLab
|
|
65
|
+
through it, register the bundled `jupyter-server-mcp-proxy` console script with
|
|
66
|
+
the agent:
|
|
57
67
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
`jupyter_server_config.d/xtralab-lsp.json`:
|
|
68
|
+
```bash
|
|
69
|
+
claude mcp add jupyter -- jupyter-server-mcp-proxy
|
|
70
|
+
codex mcp add jupyter -- jupyter-server-mcp-proxy
|
|
71
|
+
copilot mcp add jupyter -- jupyter-server-mcp-proxy
|
|
72
|
+
```
|
|
64
73
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
Run this from a terminal inside xtralab, so the proxy inherits the server
|
|
75
|
+
environment and discovers the running server automatically. No port is needed,
|
|
76
|
+
and a single registration keeps working across restarts. The launcher also
|
|
77
|
+
surfaces these commands with copy buttons, filtered to the agents you have
|
|
78
|
+
installed.
|
|
69
79
|
|
|
70
|
-
|
|
71
|
-
npm install -g typescript-language-server typescript
|
|
72
|
-
```
|
|
80
|
+
See the [`jupyter-server-mcp` README][mcp] for other MCP clients.
|
|
73
81
|
|
|
74
|
-
|
|
82
|
+
[mcp]: https://github.com/jupyter-ai-contrib/jupyter-server-mcp
|
|
83
|
+
[mcp-spec]: https://modelcontextprotocol.io
|
|
75
84
|
|
|
76
|
-
|
|
77
|
-
from `PATH` at spawn time.
|
|
78
|
-
|
|
79
|
-
### Where binaries are discovered
|
|
85
|
+
## Language servers
|
|
80
86
|
|
|
81
|
-
|
|
82
|
-
- **Desktop app** — the supervisor augments `PATH` with common shim
|
|
83
|
-
locations (`~/.volta/bin`, `~/.npm-global/bin`, `~/.bun/bin`,
|
|
84
|
-
`~/.asdf/shims`, `~/.mise/shims`, `/opt/homebrew/bin`, `/usr/local/bin`,
|
|
85
|
-
…). Set `XTRALAB_EXTRA_PATH` (colon-separated) before launching the app
|
|
86
|
-
to add directories the defaults miss.
|
|
87
|
+
xtralab ships [`jupyterlab-lsp`][lsp] with two language servers pre-registered:
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
- Python, using [`ty`](https://github.com/astral-sh/ty), which is bundled and
|
|
90
|
+
works out of the box.
|
|
91
|
+
- TypeScript and JavaScript, using `typescript-language-server`, which you
|
|
92
|
+
install yourself:
|
|
89
93
|
|
|
90
|
-
|
|
91
|
-
install
|
|
92
|
-
|
|
94
|
+
```bash
|
|
95
|
+
npm install -g typescript-language-server typescript
|
|
96
|
+
```
|
|
93
97
|
|
|
94
|
-
|
|
95
|
-
(typically `~/.jupyter/jupyter_server_config.d/`).
|
|
96
|
-
- **Desktop app (macOS)** —
|
|
97
|
-
`~/Library/Application Support/xtralab/jupyter/config/jupyter_server_config.d/`
|
|
98
|
-
(or `xtralab dev` for local dev builds).
|
|
99
|
-
- **Desktop app (Linux AppImage)** —
|
|
100
|
-
`~/.config/xtralab/jupyter/config/jupyter_server_config.d/`.
|
|
98
|
+
Restart JupyterLab afterwards to pick it up.
|
|
101
99
|
|
|
102
|
-
|
|
100
|
+
To enable another server (bash, yaml, json, pyright, and more), install its
|
|
101
|
+
binary and drop a JSON spec into a `jupyter_server_config.d/` directory. For
|
|
102
|
+
`pip install xtralab`, run `jupyter --paths` to find one (typically
|
|
103
|
+
`~/.jupyter/jupyter_server_config.d/`). For the desktop app, use
|
|
104
|
+
`~/Library/Application Support/xtralab/jupyter/config/jupyter_server_config.d/`
|
|
105
|
+
on macOS or `~/.config/xtralab/jupyter/config/jupyter_server_config.d/` on
|
|
106
|
+
Linux.
|
|
103
107
|
|
|
104
108
|
```json
|
|
105
109
|
{
|
|
@@ -117,15 +121,19 @@ Example (`bash-lsp.json`):
|
|
|
117
121
|
}
|
|
118
122
|
```
|
|
119
123
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
[
|
|
123
|
-
|
|
124
|
+
See the [`jupyterlab-lsp` documentation][lsp-config] for the full spec.
|
|
125
|
+
|
|
126
|
+
[lsp]: https://github.com/jupyter-lsp/jupyterlab-lsp
|
|
127
|
+
[lsp-config]: https://jupyterlab-lsp.readthedocs.io/en/latest/Configuring.html
|
|
124
128
|
|
|
125
129
|
## Customizing the launcher
|
|
126
130
|
|
|
127
|
-
Open `Settings → Settings Editor → xtralab launcher`
|
|
128
|
-
|
|
131
|
+
Open `Settings → Settings Editor → xtralab launcher` to override, hide, or add
|
|
132
|
+
launcher entries. Both lists below merge with xtralab's defaults by `id`.
|
|
133
|
+
|
|
134
|
+
### Agents
|
|
135
|
+
|
|
136
|
+
Edit the `agents` array:
|
|
129
137
|
|
|
130
138
|
```jsonc
|
|
131
139
|
{
|
|
@@ -142,14 +150,43 @@ array. Entries are merged with the defaults by `id`.
|
|
|
142
150
|
}
|
|
143
151
|
```
|
|
144
152
|
|
|
145
|
-
Fields: `id` (required), `label`, `caption`, `command`, `promptArgs` (how
|
|
146
|
-
|
|
147
|
-
|
|
153
|
+
Fields: `id` (required), `label`, `caption`, `command`, `promptArgs` (how the
|
|
154
|
+
prompt is spliced: `[]` for positional, `["--flag"]` for flagged, `null` to opt
|
|
155
|
+
out), `iconSvg`, `rank`, `enabled`, `requireAvailable`.
|
|
156
|
+
|
|
157
|
+
### Editors
|
|
158
|
+
|
|
159
|
+
The **Open** section's terminal-editor tile (Neovim, falling back to Vim) is
|
|
160
|
+
configured the same way through an `editors` array:
|
|
161
|
+
|
|
162
|
+
```jsonc
|
|
163
|
+
{
|
|
164
|
+
"editors": [
|
|
165
|
+
// Hide Neovim so the tile falls back to Vim (or disappears if Vim
|
|
166
|
+
// isn't installed either)
|
|
167
|
+
{ "id": "nvim", "enabled": false },
|
|
168
|
+
|
|
169
|
+
// Add Helix, preferred over the built-ins
|
|
170
|
+
{
|
|
171
|
+
"id": "helix",
|
|
172
|
+
"label": "Helix",
|
|
173
|
+
"command": "hx",
|
|
174
|
+
"rank": -1,
|
|
175
|
+
"iconSvg": "<svg>…</svg>"
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The launcher shows a single tile: the first editor, by `rank`, whose `command`
|
|
182
|
+
is on `PATH`. Disable both built-ins (`nvim`, `vim`) to remove the tile
|
|
183
|
+
entirely. Fields: `id` (required), `label`, `caption`, `command`, `iconSvg`,
|
|
184
|
+
`rank`, `enabled`, `requireAvailable`.
|
|
148
185
|
|
|
149
186
|
## Contributing
|
|
150
187
|
|
|
151
|
-
See [CONTRIBUTING.md](./CONTRIBUTING.md) for the development setup, the
|
|
152
|
-
|
|
188
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for the development setup, the Electron
|
|
189
|
+
desktop app architecture, and the build pipeline.
|
|
153
190
|
|
|
154
191
|
## License
|
|
155
192
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { JupyterFrontEndPlugin } from '@jupyterlab/application';
|
|
2
|
+
import { Token } from '@lumino/coreutils';
|
|
3
|
+
import { ISignal } from '@lumino/signaling';
|
|
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.
|
|
21
|
+
*/
|
|
22
|
+
export interface IAgentSessions {
|
|
23
|
+
/**
|
|
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).
|
|
27
|
+
*/
|
|
28
|
+
get(sessionName: string): string | null;
|
|
29
|
+
/** Record that a session was launched as the given agent command. */
|
|
30
|
+
set(sessionName: string, command: string): void;
|
|
31
|
+
/** Forget a session — called when it shuts down so the map stays bounded. */
|
|
32
|
+
delete(sessionName: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Emitted with the affected session name whenever a record is added or
|
|
35
|
+
* removed, so readers can re-render.
|
|
36
|
+
*/
|
|
37
|
+
readonly changed: ISignal<IAgentSessions, string>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* DI token for {@link IAgentSessions}. Provided by `xtralab:agent-sessions`;
|
|
41
|
+
* consumed (optionally) by both `xtralab:launcher` and `xtralab:terminals`.
|
|
42
|
+
*/
|
|
43
|
+
export declare const IAgentSessions: Token<IAgentSessions>;
|
|
44
|
+
/**
|
|
45
|
+
* Provides {@link IAgentSessions}. Deliberately has no dependencies so it can
|
|
46
|
+
* sit underneath both the launcher and the terminals panel without creating
|
|
47
|
+
* a dependency cycle between them.
|
|
48
|
+
*/
|
|
49
|
+
declare const plugin: JupyterFrontEndPlugin<IAgentSessions>;
|
|
50
|
+
export default plugin;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Token } from '@lumino/coreutils';
|
|
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
|
+
export const IAgentSessions = new Token('xtralab:IAgentSessions', 'A shared map from terminal session name to the agent command it was launched with.');
|
|
8
|
+
class AgentSessions {
|
|
9
|
+
constructor() {
|
|
10
|
+
this._byName = new Map();
|
|
11
|
+
this._changed = new Signal(this);
|
|
12
|
+
}
|
|
13
|
+
get(sessionName) {
|
|
14
|
+
var _a;
|
|
15
|
+
return (_a = this._byName.get(sessionName)) !== null && _a !== void 0 ? _a : null;
|
|
16
|
+
}
|
|
17
|
+
set(sessionName, command) {
|
|
18
|
+
if (this._byName.get(sessionName) === command) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this._byName.set(sessionName, command);
|
|
22
|
+
this._changed.emit(sessionName);
|
|
23
|
+
}
|
|
24
|
+
delete(sessionName) {
|
|
25
|
+
if (this._byName.delete(sessionName)) {
|
|
26
|
+
this._changed.emit(sessionName);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
get changed() {
|
|
30
|
+
return this._changed;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
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.
|
|
37
|
+
*/
|
|
38
|
+
const plugin = {
|
|
39
|
+
id: 'xtralab:agent-sessions',
|
|
40
|
+
description: 'Shared map from terminal session to the agent command it was launched with, used to badge terminal rows with the running agent.',
|
|
41
|
+
autoStart: true,
|
|
42
|
+
provides: IAgentSessions,
|
|
43
|
+
activate: () => new AgentSessions()
|
|
44
|
+
};
|
|
45
|
+
export default plugin;
|
package/lib/fileBrowser/index.js
CHANGED
|
@@ -22,7 +22,11 @@ const plugin = {
|
|
|
22
22
|
void app.commands.execute('docmanager:open', { path: serverPath });
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
|
-
|
|
25
|
+
// Ranks just under the Terminals panel in the left sidebar. The shipped
|
|
26
|
+
// `layout` setting assigns the default ranks (rank only, no area pin),
|
|
27
|
+
// so this browser stays movable via the "Move Widget" context menu; the
|
|
28
|
+
// `rank` here is the in-code fallback for when that setting is absent.
|
|
29
|
+
app.shell.add(browser, 'left', { rank: 2 });
|
|
26
30
|
if (restorer) {
|
|
27
31
|
restorer.add(browser, browser.id);
|
|
28
32
|
}
|
package/lib/git/commands.d.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { JupyterFrontEnd } from '@jupyterlab/application';
|
|
2
|
-
import {
|
|
2
|
+
import { IThemeManager } from '@jupyterlab/apputils';
|
|
3
3
|
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
4
4
|
import { Contents } from '@jupyterlab/services';
|
|
5
5
|
import { createGitDiffWidget, diffWidgetId } from './diffWidget';
|
|
6
|
-
import { GitPanel } from './panel';
|
|
7
6
|
import { IFileChange } from './tokens';
|
|
8
7
|
/**
|
|
9
|
-
* Command IDs exposed by the git
|
|
10
|
-
* {@link
|
|
11
|
-
*
|
|
8
|
+
* Command IDs exposed by the launcher's git diff path. The launcher
|
|
9
|
+
* dashboard's "Changes" section drives {@link CommandIDs.openDiff} to open
|
|
10
|
+
* its own diff tab, independent of `jupyterlab-git` (whose panel reaches
|
|
11
|
+
* the same rendering via the providers in `diffProvider.tsx`).
|
|
12
12
|
*/
|
|
13
13
|
export declare namespace CommandIDs {
|
|
14
|
-
const refresh = "xtralab:git:refresh";
|
|
15
14
|
const openDiff = "xtralab:git:open-diff";
|
|
16
15
|
}
|
|
17
16
|
/**
|
|
@@ -29,9 +28,7 @@ export declare namespace CommandArguments {
|
|
|
29
28
|
}
|
|
30
29
|
export interface IRegisterGitCommandsOptions {
|
|
31
30
|
app: JupyterFrontEnd;
|
|
32
|
-
panel: GitPanel;
|
|
33
31
|
themeManager: IThemeManager | null;
|
|
34
|
-
commandPalette: ICommandPalette | null;
|
|
35
32
|
/**
|
|
36
33
|
* Contents manager used by the diff widget to write hunk-discard
|
|
37
34
|
* results back to the working tree.
|
|
@@ -46,7 +43,10 @@ export interface IRegisterGitCommandsOptions {
|
|
|
46
43
|
rendermime: IRenderMimeRegistry | null;
|
|
47
44
|
/**
|
|
48
45
|
* Called whenever the diff widget mutates the working tree (e.g. after
|
|
49
|
-
* a hunk discard)
|
|
46
|
+
* a hunk discard). The launcher dashboard polls git status on its own
|
|
47
|
+
* cadence and `jupyterlab-git`'s panel auto-refreshes on the contents
|
|
48
|
+
* `fileChanged` signal the save emits, so this is a hook for any extra
|
|
49
|
+
* bookkeeping rather than a required refresh.
|
|
50
50
|
*/
|
|
51
51
|
onChanged: () => void;
|
|
52
52
|
/**
|
|
@@ -63,9 +63,8 @@ export interface IRegisterGitCommandsOptions {
|
|
|
63
63
|
onPinned(widget: ReturnType<typeof createGitDiffWidget>): void;
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
|
-
* Register the git
|
|
67
|
-
*
|
|
68
|
-
* (the commands themselves stay registered for the lifetime of the plugin).
|
|
66
|
+
* Register the launcher's git diff command on the application command
|
|
67
|
+
* registry.
|
|
69
68
|
*/
|
|
70
|
-
export declare function registerGitCommands(options: IRegisterGitCommandsOptions):
|
|
69
|
+
export declare function registerGitCommands(options: IRegisterGitCommandsOptions): void;
|
|
71
70
|
export { diffWidgetId };
|
package/lib/git/commands.js
CHANGED
|
@@ -1,31 +1,21 @@
|
|
|
1
|
-
import { refreshIcon } from '@jupyterlab/ui-components';
|
|
2
1
|
import { createGitDiffWidget, diffWidgetId, updateGitDiffWidget } from './diffWidget';
|
|
3
2
|
/**
|
|
4
|
-
* Command IDs exposed by the git
|
|
5
|
-
* {@link
|
|
6
|
-
*
|
|
3
|
+
* Command IDs exposed by the launcher's git diff path. The launcher
|
|
4
|
+
* dashboard's "Changes" section drives {@link CommandIDs.openDiff} to open
|
|
5
|
+
* its own diff tab, independent of `jupyterlab-git` (whose panel reaches
|
|
6
|
+
* the same rendering via the providers in `diffProvider.tsx`).
|
|
7
7
|
*/
|
|
8
8
|
export var CommandIDs;
|
|
9
9
|
(function (CommandIDs) {
|
|
10
|
-
CommandIDs.refresh = 'xtralab:git:refresh';
|
|
11
10
|
CommandIDs.openDiff = 'xtralab:git:open-diff';
|
|
12
11
|
})(CommandIDs || (CommandIDs = {}));
|
|
13
12
|
/**
|
|
14
|
-
* Register the git
|
|
15
|
-
*
|
|
16
|
-
* (the commands themselves stay registered for the lifetime of the plugin).
|
|
13
|
+
* Register the launcher's git diff command on the application command
|
|
14
|
+
* registry.
|
|
17
15
|
*/
|
|
18
16
|
export function registerGitCommands(options) {
|
|
19
|
-
const { app,
|
|
17
|
+
const { app, themeManager, contentsManager, rendermime, onChanged, trackDiff, findDiff, onPinned } = options;
|
|
20
18
|
const { commands } = app;
|
|
21
|
-
commands.addCommand(CommandIDs.refresh, {
|
|
22
|
-
label: 'Refresh Git Changes',
|
|
23
|
-
caption: 'Refresh the git changes panel',
|
|
24
|
-
icon: refreshIcon,
|
|
25
|
-
execute: () => {
|
|
26
|
-
panel.refresh();
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
19
|
commands.addCommand(CommandIDs.openDiff, {
|
|
30
20
|
label: 'Open Git Diff',
|
|
31
21
|
caption: 'Open a side-by-side diff for a changed file',
|
|
@@ -58,16 +48,5 @@ export function registerGitCommands(options) {
|
|
|
58
48
|
app.shell.activateById(widget.id);
|
|
59
49
|
}
|
|
60
50
|
});
|
|
61
|
-
const paletteItems = commandPalette
|
|
62
|
-
? [
|
|
63
|
-
commandPalette.addItem({
|
|
64
|
-
command: CommandIDs.refresh,
|
|
65
|
-
category: 'Git'
|
|
66
|
-
})
|
|
67
|
-
]
|
|
68
|
-
: [];
|
|
69
|
-
return () => {
|
|
70
|
-
paletteItems.forEach(item => item.dispose());
|
|
71
|
-
};
|
|
72
51
|
}
|
|
73
52
|
export { diffWidgetId };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { JupyterFrontEndPlugin } from '@jupyterlab/application';
|
|
2
|
+
/**
|
|
3
|
+
* Registers xtralab's diff rendering as jupyterlab-git's diff providers:
|
|
4
|
+
* `@pierre/diffs` for text and notebooks, the bundled `<img>`-based view
|
|
5
|
+
* for raster images.
|
|
6
|
+
*/
|
|
7
|
+
declare const diffProviderPlugin: JupyterFrontEndPlugin<void>;
|
|
8
|
+
export default diffProviderPlugin;
|