xtralab 0.5.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 -78
- package/lib/agentSessions.d.ts +50 -0
- package/lib/agentSessions.js +45 -0
- package/lib/fileBrowser/index.js +5 -1
- package/lib/git/imageDiff.js +80 -8
- package/lib/index.d.ts +3 -2
- package/lib/index.js +11 -6
- 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 +36 -33
- package/schema/launcher.json +56 -1
- package/src/agentSessions.ts +94 -0
- package/src/fileBrowser/index.ts +5 -1
- package/src/git/imageDiff.tsx +127 -26
- package/src/index.ts +11 -6
- 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 +109 -0
- 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/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/statusBar/index.ts +0 -115
- package/src/statusBar/widget.tsx +0 -318
- package/style/statusBar.css +0 -95
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { LabIcon, textEditorIcon } from '@jupyterlab/ui-components';
|
|
2
|
+
import { BUILTIN_EDITOR_ICONS } from './icons';
|
|
3
|
+
/**
|
|
4
|
+
* Built-in editor candidates in preference order. The launcher shows the first
|
|
5
|
+
* one whose command resolves on the server's `$PATH`, so Neovim wins over Vim
|
|
6
|
+
* when both are installed. Users override, disable, or extend this list
|
|
7
|
+
* through the `editors` setting; see {@link mergeEditors}.
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULTS = [
|
|
10
|
+
{
|
|
11
|
+
id: 'nvim',
|
|
12
|
+
label: 'Neovim',
|
|
13
|
+
caption: 'Open Neovim in a new terminal.',
|
|
14
|
+
command: 'nvim',
|
|
15
|
+
icon: BUILTIN_EDITOR_ICONS.nvim,
|
|
16
|
+
rank: 0,
|
|
17
|
+
requireAvailable: true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'vim',
|
|
21
|
+
label: 'Vim',
|
|
22
|
+
caption: 'Open Vim in a new terminal.',
|
|
23
|
+
command: 'vim',
|
|
24
|
+
icon: BUILTIN_EDITOR_ICONS.vim,
|
|
25
|
+
rank: 1,
|
|
26
|
+
requireAvailable: true
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
function resolveEditorIcon(id, iconSvg) {
|
|
30
|
+
var _a;
|
|
31
|
+
if (iconSvg) {
|
|
32
|
+
return new LabIcon({
|
|
33
|
+
name: `xtralab:editor-custom-${id}`,
|
|
34
|
+
svgstr: iconSvg
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return (_a = BUILTIN_EDITOR_ICONS[id]) !== null && _a !== void 0 ? _a : textEditorIcon;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Merge xtralab's built-in editors with the user's `editors` settings. Built-in
|
|
41
|
+
* entries keep their fields unless explicitly overridden; user-only entries are
|
|
42
|
+
* appended. `enabled: false` filters an entry out of the result entirely (so
|
|
43
|
+
* callers don't need to re-check the flag). The result is sorted by rank, which
|
|
44
|
+
* is also the launcher's tile-preference order. Mirrors `mergeAgents`.
|
|
45
|
+
*/
|
|
46
|
+
export function mergeEditors(overrides) {
|
|
47
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
48
|
+
const overrideById = new Map(overrides.map(entry => [entry.id, entry]));
|
|
49
|
+
const merged = [];
|
|
50
|
+
for (const base of DEFAULTS) {
|
|
51
|
+
const override = overrideById.get(base.id);
|
|
52
|
+
if (!override) {
|
|
53
|
+
merged.push({ ...base });
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
overrideById.delete(base.id);
|
|
57
|
+
if (override.enabled === false) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
merged.push({
|
|
61
|
+
id: base.id,
|
|
62
|
+
label: (_a = override.label) !== null && _a !== void 0 ? _a : base.label,
|
|
63
|
+
caption: (_b = override.caption) !== null && _b !== void 0 ? _b : base.caption,
|
|
64
|
+
command: (_c = override.command) !== null && _c !== void 0 ? _c : base.command,
|
|
65
|
+
icon: override.iconSvg
|
|
66
|
+
? resolveEditorIcon(base.id, override.iconSvg)
|
|
67
|
+
: base.icon,
|
|
68
|
+
rank: (_d = override.rank) !== null && _d !== void 0 ? _d : base.rank,
|
|
69
|
+
requireAvailable: (_e = override.requireAvailable) !== null && _e !== void 0 ? _e : base.requireAvailable
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// What remains in `overrideById` are ids that don't match a built-in — treat
|
|
73
|
+
// them as new editors the user is adding. Skip disabled ones; the settings
|
|
74
|
+
// schema validates the shape, so missing fields just fall back here.
|
|
75
|
+
let nextRank = merged.reduce((max, editor) => Math.max(max, editor.rank), -1) + 1;
|
|
76
|
+
for (const entry of overrideById.values()) {
|
|
77
|
+
if (entry.enabled === false) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const label = (_f = entry.label) !== null && _f !== void 0 ? _f : entry.id;
|
|
81
|
+
const command = (_g = entry.command) !== null && _g !== void 0 ? _g : entry.id;
|
|
82
|
+
merged.push({
|
|
83
|
+
id: entry.id,
|
|
84
|
+
label,
|
|
85
|
+
caption: (_h = entry.caption) !== null && _h !== void 0 ? _h : `Open ${label} in a new terminal.`,
|
|
86
|
+
command,
|
|
87
|
+
icon: resolveEditorIcon(entry.id, entry.iconSvg),
|
|
88
|
+
rank: (_j = entry.rank) !== null && _j !== void 0 ? _j : nextRank++,
|
|
89
|
+
requireAvailable: (_k = entry.requireAvailable) !== null && _k !== void 0 ? _k : true
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
merged.sort((a, b) => a.rank - b.rank);
|
|
93
|
+
return merged;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Pick the single editor tile to show, given the merged editor list and the
|
|
97
|
+
* set of commands known to be on `$PATH` (from the launcher's availability
|
|
98
|
+
* probe). Returns the first candidate, by rank, that is either available or
|
|
99
|
+
* opts out of the check (`requireAvailable: false`) — Neovim before Vim by
|
|
100
|
+
* default — or `null` when none qualifies.
|
|
101
|
+
*
|
|
102
|
+
* When `available` is `null` (the endpoint couldn't be reached), a
|
|
103
|
+
* `requireAvailable` editor is not shown; an entry with
|
|
104
|
+
* `requireAvailable: false` is shown regardless.
|
|
105
|
+
*/
|
|
106
|
+
export function resolveEditor(editors, available) {
|
|
107
|
+
var _a;
|
|
108
|
+
return ((_a = editors.find(editor => !editor.requireAvailable ||
|
|
109
|
+
(available !== null && available.has(editor.command)))) !== null && _a !== void 0 ? _a : null);
|
|
110
|
+
}
|
package/lib/launcher/icons.d.ts
CHANGED
|
@@ -1,29 +1,41 @@
|
|
|
1
1
|
import { LabIcon } from '@jupyterlab/ui-components';
|
|
2
2
|
/**
|
|
3
|
-
* Brand icons for the agent launcher cards.
|
|
3
|
+
* Brand icons for the agent launcher cards. Most marks are taken verbatim
|
|
4
4
|
* from `jupyter-ai-contrib/jupyter-ai-acp-client`
|
|
5
|
-
* (`jupyter_ai_acp_client/static/*.svg`, BSD-3-Clause)
|
|
6
|
-
*
|
|
5
|
+
* (`jupyter_ai_acp_client/static/*.svg`, BSD-3-Clause); Antigravity post-dates
|
|
6
|
+
* that set, so its mark is the official glyph from `@lobehub/icons-static-svg`
|
|
7
|
+
* (MIT) — we ship the brand-colored `antigravity-color` variant so Antigravity
|
|
8
|
+
* reads as a multi-color Google mark, occupying the slot the Gemini icon used
|
|
9
|
+
* to fill before the upstream Gemini CLI sunset. Small adjustments are applied
|
|
10
|
+
* to play nicely with JupyterLab themes:
|
|
7
11
|
* - Monochrome marks (Codex, Copilot, Goose) use `currentColor` so they
|
|
8
12
|
* inherit the surrounding launcher card's text color rather than
|
|
9
13
|
* hard-coding black, which disappears on the dark theme.
|
|
10
14
|
* - The Goose mark upstream is rendered on a white rounded rect; we drop
|
|
11
15
|
* the rect so the silhouette can sit on the launcher card directly.
|
|
12
16
|
* - SVG ids that would collide if two copies of the same artwork ended up
|
|
13
|
-
* on the page (gradient/mask defs) are namespaced under
|
|
17
|
+
* on the page (gradient/mask/filter defs) are namespaced under
|
|
18
|
+
* `xtralab-…`.
|
|
14
19
|
*
|
|
15
|
-
* Brand-colored icons (
|
|
20
|
+
* Brand-colored icons (Antigravity, Claude, Kiro, Mistral Vibe, OpenCode) keep
|
|
16
21
|
* their upstream colors; the dark/light contrast of the launcher card behind
|
|
17
22
|
* them is the same as on `jupyter-ai-acp-client`.
|
|
23
|
+
*
|
|
24
|
+
* The Vim and Neovim marks belong to the launcher's "Open" editor tile rather
|
|
25
|
+
* than the agent grid. They are the brand silhouettes from Simple Icons
|
|
26
|
+
* (https://simpleicons.org, CC0), each filled with its brand green so the mark
|
|
27
|
+
* reads on both the light and dark themes.
|
|
18
28
|
*/
|
|
29
|
+
export declare const antigravityIcon: LabIcon;
|
|
19
30
|
export declare const claudeIcon: LabIcon;
|
|
20
31
|
export declare const codexIcon: LabIcon;
|
|
21
32
|
export declare const copilotIcon: LabIcon;
|
|
22
|
-
export declare const geminiIcon: LabIcon;
|
|
23
33
|
export declare const gooseIcon: LabIcon;
|
|
24
34
|
export declare const kiroIcon: LabIcon;
|
|
25
35
|
export declare const mistralVibeIcon: LabIcon;
|
|
26
36
|
export declare const opencodeIcon: LabIcon;
|
|
37
|
+
export declare const neovimIcon: LabIcon;
|
|
38
|
+
export declare const vimIcon: LabIcon;
|
|
27
39
|
/**
|
|
28
40
|
* Built-in icons keyed by the agent's id, used to resolve the icon for an
|
|
29
41
|
* agent declared without an inline `iconSvg` override (i.e. one of xtralab's
|
|
@@ -31,3 +43,10 @@ export declare const opencodeIcon: LabIcon;
|
|
|
31
43
|
* `iconSvg` or fall back to the generic terminal icon.
|
|
32
44
|
*/
|
|
33
45
|
export declare const BUILTIN_AGENT_ICONS: Record<string, LabIcon>;
|
|
46
|
+
/**
|
|
47
|
+
* Built-in icons keyed by the editor's id, used to resolve the icon for a
|
|
48
|
+
* built-in editor (Neovim, Vim) declared without an inline `iconSvg`. Custom
|
|
49
|
+
* editors added via settings can supply their own `iconSvg` or fall back to
|
|
50
|
+
* the generic text-editor icon.
|
|
51
|
+
*/
|
|
52
|
+
export declare const BUILTIN_EDITOR_ICONS: Record<string, LabIcon>;
|
package/lib/launcher/icons.js
CHANGED
|
@@ -1,21 +1,109 @@
|
|
|
1
1
|
import { LabIcon } from '@jupyterlab/ui-components';
|
|
2
2
|
/**
|
|
3
|
-
* Brand icons for the agent launcher cards.
|
|
3
|
+
* Brand icons for the agent launcher cards. Most marks are taken verbatim
|
|
4
4
|
* from `jupyter-ai-contrib/jupyter-ai-acp-client`
|
|
5
|
-
* (`jupyter_ai_acp_client/static/*.svg`, BSD-3-Clause)
|
|
6
|
-
*
|
|
5
|
+
* (`jupyter_ai_acp_client/static/*.svg`, BSD-3-Clause); Antigravity post-dates
|
|
6
|
+
* that set, so its mark is the official glyph from `@lobehub/icons-static-svg`
|
|
7
|
+
* (MIT) — we ship the brand-colored `antigravity-color` variant so Antigravity
|
|
8
|
+
* reads as a multi-color Google mark, occupying the slot the Gemini icon used
|
|
9
|
+
* to fill before the upstream Gemini CLI sunset. Small adjustments are applied
|
|
10
|
+
* to play nicely with JupyterLab themes:
|
|
7
11
|
* - Monochrome marks (Codex, Copilot, Goose) use `currentColor` so they
|
|
8
12
|
* inherit the surrounding launcher card's text color rather than
|
|
9
13
|
* hard-coding black, which disappears on the dark theme.
|
|
10
14
|
* - The Goose mark upstream is rendered on a white rounded rect; we drop
|
|
11
15
|
* the rect so the silhouette can sit on the launcher card directly.
|
|
12
16
|
* - SVG ids that would collide if two copies of the same artwork ended up
|
|
13
|
-
* on the page (gradient/mask defs) are namespaced under
|
|
17
|
+
* on the page (gradient/mask/filter defs) are namespaced under
|
|
18
|
+
* `xtralab-…`.
|
|
14
19
|
*
|
|
15
|
-
* Brand-colored icons (
|
|
20
|
+
* Brand-colored icons (Antigravity, Claude, Kiro, Mistral Vibe, OpenCode) keep
|
|
16
21
|
* their upstream colors; the dark/light contrast of the launcher card behind
|
|
17
22
|
* them is the same as on `jupyter-ai-acp-client`.
|
|
23
|
+
*
|
|
24
|
+
* The Vim and Neovim marks belong to the launcher's "Open" editor tile rather
|
|
25
|
+
* than the agent grid. They are the brand silhouettes from Simple Icons
|
|
26
|
+
* (https://simpleicons.org, CC0), each filled with its brand green so the mark
|
|
27
|
+
* reads on both the light and dark themes.
|
|
18
28
|
*/
|
|
29
|
+
export const antigravityIcon = new LabIcon({
|
|
30
|
+
name: 'xtralab:agent-antigravity',
|
|
31
|
+
svgstr: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
|
32
|
+
<mask id="xtralab-antigravity-mask" height="23" maskUnits="userSpaceOnUse" width="24" x="0" y="1">
|
|
33
|
+
<path d="M21.751 22.607c1.34 1.005 3.35.335 1.508-1.508C17.73 15.74 18.904 1 12.037 1 5.17 1 6.342 15.74.815 21.1c-2.01 2.009.167 2.511 1.507 1.506 5.192-3.517 4.857-9.714 9.715-9.714 4.857 0 4.522 6.197 9.714 9.715z" fill="#fff"/>
|
|
34
|
+
</mask>
|
|
35
|
+
<g mask="url(#xtralab-antigravity-mask)">
|
|
36
|
+
<g filter="url(#xtralab-antigravity-blur-1)">
|
|
37
|
+
<path d="M-1.018-3.992c-.408 3.591 2.686 6.89 6.91 7.37 4.225.48 7.98-2.043 8.387-5.633.408-3.59-2.686-6.89-6.91-7.37-4.225-.479-7.98 2.043-8.387 5.633z" fill="#FFE432"/>
|
|
38
|
+
</g>
|
|
39
|
+
<g filter="url(#xtralab-antigravity-blur-2)">
|
|
40
|
+
<path d="M15.269 7.747c1.058 4.557 5.691 7.374 10.348 6.293 4.657-1.082 7.575-5.653 6.516-10.21-1.058-4.556-5.691-7.374-10.348-6.292-4.657 1.082-7.575 5.653-6.516 10.21z" fill="#FC413D"/>
|
|
41
|
+
</g>
|
|
42
|
+
<g filter="url(#xtralab-antigravity-blur-3)">
|
|
43
|
+
<path d="M-12.443 10.804c1.338 4.703 7.36 7.11 13.453 5.378 6.092-1.733 9.947-6.95 8.61-11.652C8.282-.173 2.26-2.58-3.833-.848-9.925.884-13.78 6.1-12.443 10.804z" fill="#00B95C"/>
|
|
44
|
+
</g>
|
|
45
|
+
<g filter="url(#xtralab-antigravity-blur-4)">
|
|
46
|
+
<path d="M-12.443 10.804c1.338 4.703 7.36 7.11 13.453 5.378 6.092-1.733 9.947-6.95 8.61-11.652C8.282-.173 2.26-2.58-3.833-.848-9.925.884-13.78 6.1-12.443 10.804z" fill="#00B95C"/>
|
|
47
|
+
</g>
|
|
48
|
+
<g filter="url(#xtralab-antigravity-blur-5)">
|
|
49
|
+
<path d="M-7.608 14.703c3.352 3.424 9.126 3.208 12.896-.483 3.77-3.69 4.108-9.459.756-12.883C2.69-2.087-3.083-1.871-6.853 1.82c-3.77 3.69-4.108 9.458-.755 12.883z" fill="#00B95C"/>
|
|
50
|
+
</g>
|
|
51
|
+
<g filter="url(#xtralab-antigravity-blur-6)">
|
|
52
|
+
<path d="M9.932 27.617c1.04 4.482 5.384 7.303 9.7 6.3 4.316-1.002 6.971-5.448 5.93-9.93-1.04-4.483-5.384-7.304-9.7-6.301-4.316 1.002-6.971 5.448-5.93 9.93z" fill="#3186FF"/>
|
|
53
|
+
</g>
|
|
54
|
+
<g filter="url(#xtralab-antigravity-blur-7)">
|
|
55
|
+
<path d="M2.572-8.185C.392-3.329 2.778 2.472 7.9 4.771c5.122 2.3 11.042.227 13.222-4.63 2.18-4.855-.205-10.656-5.327-12.955-5.122-2.3-11.042-.227-13.222 4.63z" fill="#FBBC04"/>
|
|
56
|
+
</g>
|
|
57
|
+
<g filter="url(#xtralab-antigravity-blur-8)">
|
|
58
|
+
<path d="M-3.267 38.686c-5.277-2.072 3.742-19.117 5.984-24.83 2.243-5.712 8.34-8.664 13.616-6.592 5.278 2.071 11.533 13.482 9.29 19.195-2.242 5.713-23.613 14.298-28.89 12.227z" fill="#3186FF"/>
|
|
59
|
+
</g>
|
|
60
|
+
<g filter="url(#xtralab-antigravity-blur-9)">
|
|
61
|
+
<path d="M28.71 17.471c-1.413 1.649-5.1.808-8.236-1.878-3.135-2.687-4.531-6.201-3.118-7.85 1.412-1.649 5.1-.808 8.235 1.878s4.532 6.2 3.119 7.85z" fill="#749BFF"/>
|
|
62
|
+
</g>
|
|
63
|
+
<g filter="url(#xtralab-antigravity-blur-10)">
|
|
64
|
+
<path d="M18.163 9.077c5.81 3.93 12.502 4.19 14.946.577 2.443-3.612-.287-9.727-6.098-13.658-5.81-3.931-12.502-4.19-14.946-.577-2.443 3.612.287 9.727 6.098 13.658z" fill="#FC413D"/>
|
|
65
|
+
</g>
|
|
66
|
+
<g filter="url(#xtralab-antigravity-blur-11)">
|
|
67
|
+
<path d="M-.915 2.684c-1.44 3.473-.97 6.967 1.05 7.804 2.02.837 4.824-1.3 6.264-4.772 1.44-3.473.97-6.967-1.05-7.804-2.02-.837-4.824 1.3-6.264 4.772z" fill="#FFEE48"/>
|
|
68
|
+
</g>
|
|
69
|
+
</g>
|
|
70
|
+
<defs>
|
|
71
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="17.587" id="xtralab-antigravity-blur-1" width="19.838" x="-3.288" y="-11.917">
|
|
72
|
+
<feGaussianBlur stdDeviation="1.117"/>
|
|
73
|
+
</filter>
|
|
74
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="38.565" id="xtralab-antigravity-blur-2" width="38.9" x="4.251" y="-13.493">
|
|
75
|
+
<feGaussianBlur stdDeviation="5.4"/>
|
|
76
|
+
</filter>
|
|
77
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="36.517" id="xtralab-antigravity-blur-3" width="40.955" x="-21.889" y="-10.592">
|
|
78
|
+
<feGaussianBlur stdDeviation="4.591"/>
|
|
79
|
+
</filter>
|
|
80
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="36.517" id="xtralab-antigravity-blur-4" width="40.955" x="-21.889" y="-10.592">
|
|
81
|
+
<feGaussianBlur stdDeviation="4.591"/>
|
|
82
|
+
</filter>
|
|
83
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="36.595" id="xtralab-antigravity-blur-5" width="36.632" x="-19.099" y="-10.278">
|
|
84
|
+
<feGaussianBlur stdDeviation="4.591"/>
|
|
85
|
+
</filter>
|
|
86
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="34.087" id="xtralab-antigravity-blur-6" width="33.533" x=".981" y="8.758">
|
|
87
|
+
<feGaussianBlur stdDeviation="4.363"/>
|
|
88
|
+
</filter>
|
|
89
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="35.276" id="xtralab-antigravity-blur-7" width="35.978" x="-6.143" y="-21.659">
|
|
90
|
+
<feGaussianBlur stdDeviation="3.954"/>
|
|
91
|
+
</filter>
|
|
92
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="46.523" id="xtralab-antigravity-blur-8" width="45.114" x="-11.96" y="-.46">
|
|
93
|
+
<feGaussianBlur stdDeviation="3.531"/>
|
|
94
|
+
</filter>
|
|
95
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="24.054" id="xtralab-antigravity-blur-9" width="25.094" x="10.485" y=".58">
|
|
96
|
+
<feGaussianBlur stdDeviation="3.159"/>
|
|
97
|
+
</filter>
|
|
98
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="30.007" id="xtralab-antigravity-blur-10" width="33.508" x="5.833" y="-12.467">
|
|
99
|
+
<feGaussianBlur stdDeviation="2.669"/>
|
|
100
|
+
</filter>
|
|
101
|
+
<filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="26.151" id="xtralab-antigravity-blur-11" width="22.194" x="-8.355" y="-8.876">
|
|
102
|
+
<feGaussianBlur stdDeviation="3.303"/>
|
|
103
|
+
</filter>
|
|
104
|
+
</defs>
|
|
105
|
+
</svg>`
|
|
106
|
+
});
|
|
19
107
|
export const claudeIcon = new LabIcon({
|
|
20
108
|
name: 'xtralab:agent-claude',
|
|
21
109
|
svgstr: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 1200">
|
|
@@ -35,19 +123,6 @@ export const copilotIcon = new LabIcon({
|
|
|
35
123
|
<path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"/>
|
|
36
124
|
</svg>`
|
|
37
125
|
});
|
|
38
|
-
export const geminiIcon = new LabIcon({
|
|
39
|
-
name: 'xtralab:agent-gemini',
|
|
40
|
-
svgstr: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none">
|
|
41
|
-
<path d="M16 8.016A8.522 8.522 0 008.016 16h-.032A8.521 8.521 0 000 8.016v-.032A8.521 8.521 0 007.984 0h.032A8.522 8.522 0 0016 7.984v.032z" fill="url(#xtralab-gemini-radial)"/>
|
|
42
|
-
<defs>
|
|
43
|
-
<radialGradient id="xtralab-gemini-radial" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(16.1326 5.4553 -43.70045 129.2322 1.588 6.503)">
|
|
44
|
-
<stop offset=".067" stop-color="#9168C0"/>
|
|
45
|
-
<stop offset=".343" stop-color="#5684D1"/>
|
|
46
|
-
<stop offset=".672" stop-color="#1BA1E3"/>
|
|
47
|
-
</radialGradient>
|
|
48
|
-
</defs>
|
|
49
|
-
</svg>`
|
|
50
|
-
});
|
|
51
126
|
export const gooseIcon = new LabIcon({
|
|
52
127
|
name: 'xtralab:agent-goose',
|
|
53
128
|
svgstr: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048">
|
|
@@ -95,6 +170,18 @@ export const opencodeIcon = new LabIcon({
|
|
|
95
170
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M384 416H128V96H384V416ZM320 160H192V352H320V160Z" fill="white"/>
|
|
96
171
|
</svg>`
|
|
97
172
|
});
|
|
173
|
+
export const neovimIcon = new LabIcon({
|
|
174
|
+
name: 'xtralab:editor-neovim',
|
|
175
|
+
svgstr: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#57A143">
|
|
176
|
+
<path d="M2.214 4.954v13.615L7.655 24V10.314L3.312 3.845 2.214 4.954zm4.999 17.98l-4.557-4.548V5.136l.59-.596 3.967 5.908v12.485zm14.573-4.457l-.862.937-4.24-6.376V0l5.068 5.092.034 13.385zM7.431.001l12.998 19.835-3.637 3.637L3.787 3.683 7.43 0z"/>
|
|
177
|
+
</svg>`
|
|
178
|
+
});
|
|
179
|
+
export const vimIcon = new LabIcon({
|
|
180
|
+
name: 'xtralab:editor-vim',
|
|
181
|
+
svgstr: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#019733">
|
|
182
|
+
<path d="M24 11.986h-.027l-4.318-4.318 4.303-4.414V1.461l-.649-.648h-8.198l-.66.605v1.045L12.015.027V0L12 .014 11.986 0v.027l-1.29 1.291-.538-.539H2.035l-.638.692v1.885l.616.616h.72v5.31L.027 11.987H0L.014 12 0 12.014h.027l2.706 2.706v6.467l.907.523h2.322l1.857-1.904 4.166 4.166V24l.015-.014.014.014v-.028l2.51-2.509h.485c.111 0 .211-.07.25-.179l.146-.426c.028-.084.012-.172-.037-.239l1.462-1.462-.612 1.962c-.043.141.036.289.177.332.025.008.052.012.078.012h1.824c.106-.001.201-.064.243-.163l.165-.394c.025-.065.024-.138-.004-.203-.027-.065-.08-.116-.146-.142-.029-.012-.062-.019-.097-.02h-.075l.84-2.644h1.232l-1.016 3.221c-.043.141.036.289.176.332.025.008.052.012.079.012h2.002c.11 0 .207-.066.248-.17l.164-.428c.051-.138-.021-.29-.158-.341-.029-.011-.06-.017-.091-.017h-.145l1.131-3.673c.027-.082.012-.173-.039-.24l-.375-.504-.003-.005c-.051-.064-.127-.102-.209-.102h-1.436c-.071 0-.141.03-.19.081l-.4.439h-.624l-.042-.046 4.445-4.445H24L23.986 12l.014-.014zM9.838 21.139l1.579-4.509h-.501l.297-.304h1.659l-1.563 4.555h.623l-.079.258H9.838zm3.695-7.516l.15.151-.269.922-.225.226h-.969l-.181-.181.311-.871.288-.247h.895zM5.59 20.829H3.877l-.262-.15V3.091H2.379l-.1-.1V1.815l.143-.154h7.371l.213.214v1.108l-.142.173H8.785v8.688l8.807-8.688h-2.086l-.175-.188V1.805l.121-.111h7.49l.132.133v1.07L12.979 13.25h-.373c-.015-.001-.028 0-.042.001l-.02.003c-.045.01-.086.03-.119.06l-.343.295-.004.003c-.033.031-.059.069-.073.111l-.296.83-6.119 6.276zm14.768-3.952l.474-.519h1.334l.309.415-1.265 4.107h.493l-.08.209H19.84l1.124-3.564h-2.015l-1.077 3.391h.424l-.073.174h-1.605l1.107-3.548h-2.096l-1.062 3.339h.436l-.072.209H13.27l1.514-4.46H14.198l.091-.271h1.65l.519.537h.906l.491-.554h1.061l.489.535h.953z"/>
|
|
183
|
+
</svg>`
|
|
184
|
+
});
|
|
98
185
|
/**
|
|
99
186
|
* Built-in icons keyed by the agent's id, used to resolve the icon for an
|
|
100
187
|
* agent declared without an inline `iconSvg` override (i.e. one of xtralab's
|
|
@@ -102,12 +189,22 @@ export const opencodeIcon = new LabIcon({
|
|
|
102
189
|
* `iconSvg` or fall back to the generic terminal icon.
|
|
103
190
|
*/
|
|
104
191
|
export const BUILTIN_AGENT_ICONS = {
|
|
192
|
+
antigravity: antigravityIcon,
|
|
105
193
|
claude: claudeIcon,
|
|
106
194
|
codex: codexIcon,
|
|
107
195
|
copilot: copilotIcon,
|
|
108
|
-
gemini: geminiIcon,
|
|
109
196
|
goose: gooseIcon,
|
|
110
197
|
kiro: kiroIcon,
|
|
111
198
|
'mistral-vibe': mistralVibeIcon,
|
|
112
199
|
opencode: opencodeIcon
|
|
113
200
|
};
|
|
201
|
+
/**
|
|
202
|
+
* Built-in icons keyed by the editor's id, used to resolve the icon for a
|
|
203
|
+
* built-in editor (Neovim, Vim) declared without an inline `iconSvg`. Custom
|
|
204
|
+
* editors added via settings can supply their own `iconSvg` or fall back to
|
|
205
|
+
* the generic text-editor icon.
|
|
206
|
+
*/
|
|
207
|
+
export const BUILTIN_EDITOR_ICONS = {
|
|
208
|
+
nvim: neovimIcon,
|
|
209
|
+
vim: vimIcon
|
|
210
|
+
};
|
package/lib/launcher/index.d.ts
CHANGED
|
@@ -1,23 +1,3 @@
|
|
|
1
1
|
import { JupyterFrontEndPlugin } from '@jupyterlab/application';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* (which is disabled via `package.json`'s `jupyterlab.disabledExtensions`)
|
|
5
|
-
* with an agent-focused dashboard: an optional initial prompt, a row of
|
|
6
|
-
* agent buttons (Claude, Codex, Gemini, …), and a collapsible list of
|
|
7
|
-
* changed files (clickable into the diff viewer) below them. Clicking an
|
|
8
|
-
* agent opens a fresh terminal and pipes the agent's command into it; if
|
|
9
|
-
* the prompt textarea is non-empty, the prompt is shell-quoted and
|
|
10
|
-
* spliced into the launch line per the agent's `promptArgs` recipe.
|
|
11
|
-
*
|
|
12
|
-
* The agent list is the merge of xtralab's defaults with the user's
|
|
13
|
-
* `xtralab:launcher` settings, then filtered by a server-side `which`
|
|
14
|
-
* check so users only see agents that are actually installed. Agents with
|
|
15
|
-
* `requireAvailable: false` (e.g. shell aliases) skip the filter.
|
|
16
|
-
*
|
|
17
|
-
* The plugin deliberately does NOT provide the `ILauncher` token: other
|
|
18
|
-
* extensions register notebook/console/terminal cards on it as a side
|
|
19
|
-
* effect, which would defeat the point of the agent-only launcher. If an
|
|
20
|
-
* extension needs to surface itself, we'll add it here explicitly.
|
|
21
|
-
*/
|
|
22
|
-
declare const plugin: JupyterFrontEndPlugin<void>;
|
|
23
|
-
export default plugin;
|
|
2
|
+
declare const plugins: JupyterFrontEndPlugin<unknown>[];
|
|
3
|
+
export default plugins;
|
package/lib/launcher/index.js
CHANGED
|
@@ -4,16 +4,20 @@ import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
|
4
4
|
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
|
|
5
5
|
import { launcherIcon } from '@jupyterlab/ui-components';
|
|
6
6
|
import { find } from '@lumino/algorithm';
|
|
7
|
+
import { IAgentSessions } from '../agentSessions';
|
|
7
8
|
import { mergeAgents } from './agents';
|
|
8
9
|
import { fetchAvailableCommands } from './availability';
|
|
9
10
|
import { CREATE_LAUNCHER_COMMAND, registerAgentCommands } from './commands';
|
|
10
11
|
import { LauncherDashboard } from './dashboard';
|
|
12
|
+
import { editorRegistryPlugin, IEditorRegistry } from './editorRegistry';
|
|
13
|
+
import { AgentRegistry } from './registry';
|
|
14
|
+
import { IAgentRegistry } from './tokens';
|
|
11
15
|
const PLUGIN_ID = 'xtralab:launcher';
|
|
12
16
|
/**
|
|
13
17
|
* The xtralab launcher plugin. Replaces the stock JupyterLab launcher
|
|
14
18
|
* (which is disabled via `package.json`'s `jupyterlab.disabledExtensions`)
|
|
15
19
|
* with an agent-focused dashboard: an optional initial prompt, a row of
|
|
16
|
-
* agent buttons (Claude, Codex,
|
|
20
|
+
* agent buttons (Claude, Codex, Antigravity, …), and a collapsible list of
|
|
17
21
|
* changed files (clickable into the diff viewer) below them. Clicking an
|
|
18
22
|
* agent opens a fresh terminal and pipes the agent's command into it; if
|
|
19
23
|
* the prompt textarea is non-empty, the prompt is shell-quoted and
|
|
@@ -33,23 +37,40 @@ const plugin = {
|
|
|
33
37
|
id: PLUGIN_ID,
|
|
34
38
|
description: 'An agent-focused launcher that replaces the default JupyterLab launcher.',
|
|
35
39
|
autoStart: true,
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
provides: IAgentRegistry,
|
|
41
|
+
optional: [
|
|
42
|
+
ILabShell,
|
|
43
|
+
ICommandPalette,
|
|
44
|
+
ISettingRegistry,
|
|
45
|
+
ITranslator,
|
|
46
|
+
IAgentSessions,
|
|
47
|
+
IEditorRegistry
|
|
48
|
+
],
|
|
49
|
+
activate: async (app, labShell, palette, settingRegistry, translator, agentSessions, editorRegistry) => {
|
|
38
50
|
const { commands, shell } = app;
|
|
39
51
|
const trans = (translator !== null && translator !== void 0 ? translator : nullTranslator).load('jupyterlab');
|
|
40
|
-
// The
|
|
41
|
-
//
|
|
42
|
-
|
|
52
|
+
// The shared agent registry this plugin provides on `IAgentRegistry`.
|
|
53
|
+
// It holds the active agent list (updated whenever settings change), so
|
|
54
|
+
// every freshly-created launcher widget — and any other plugin that
|
|
55
|
+
// consumes the token, e.g. the terminals panel — renders the latest list.
|
|
56
|
+
const registry = new AgentRegistry();
|
|
43
57
|
// Track command registrations so a settings change can wipe them
|
|
44
58
|
// before re-registering — without this the command palette would
|
|
45
59
|
// accumulate stale entries when the agent list shrinks.
|
|
46
60
|
let registered = null;
|
|
47
61
|
const applyAgents = async (overrides) => {
|
|
48
62
|
const agents = mergeAgents(overrides);
|
|
49
|
-
|
|
63
|
+
// Probe the server's `$PATH` so we only surface agents that are actually
|
|
64
|
+
// installed. Agents with `requireAvailable: false` opt out (their command
|
|
65
|
+
// may be a shell alias that `which` can't see) and are kept regardless.
|
|
66
|
+
const probe = Array.from(new Set(agents
|
|
67
|
+
.filter(agent => agent.requireAvailable)
|
|
68
|
+
.map(agent => agent.command)));
|
|
69
|
+
const available = await fetchAvailableCommands(probe);
|
|
70
|
+
const filtered = filterAgents(agents, available);
|
|
50
71
|
registered === null || registered === void 0 ? void 0 : registered.dispose();
|
|
51
|
-
registered = registerAgentCommands(app, filtered);
|
|
52
|
-
|
|
72
|
+
registered = registerAgentCommands(app, filtered, agentSessions);
|
|
73
|
+
registry.setAgents(filtered);
|
|
53
74
|
};
|
|
54
75
|
const readOverrides = (settings) => {
|
|
55
76
|
const raw = settings.composite.agents;
|
|
@@ -81,6 +102,7 @@ const plugin = {
|
|
|
81
102
|
commands.addCommand(CREATE_LAUNCHER_COMMAND, {
|
|
82
103
|
label: trans.__('New Launcher'),
|
|
83
104
|
execute: (args) => {
|
|
105
|
+
var _a;
|
|
84
106
|
const id = Private.nextId();
|
|
85
107
|
const onAgentLaunch = (item) => {
|
|
86
108
|
// When an agent command returns a Widget that ends up in the main
|
|
@@ -95,7 +117,9 @@ const plugin = {
|
|
|
95
117
|
};
|
|
96
118
|
const launcher = new LauncherDashboard({
|
|
97
119
|
commands,
|
|
98
|
-
agents:
|
|
120
|
+
agents: registry.agents,
|
|
121
|
+
editor: (_a = editorRegistry === null || editorRegistry === void 0 ? void 0 : editorRegistry.current) !== null && _a !== void 0 ? _a : null,
|
|
122
|
+
agentSessions,
|
|
99
123
|
onAgentLaunch,
|
|
100
124
|
// Empty repoPath/cwd matches the JupyterLab convention used by
|
|
101
125
|
// the git panel and the stock launcher: let the server resolve
|
|
@@ -153,25 +177,20 @@ const plugin = {
|
|
|
153
177
|
return commands.execute(CREATE_LAUNCHER_COMMAND, { ref });
|
|
154
178
|
});
|
|
155
179
|
}
|
|
180
|
+
return registry;
|
|
156
181
|
}
|
|
157
182
|
};
|
|
158
183
|
/**
|
|
159
|
-
* Drop agents whose command isn't on `$PATH`, except
|
|
160
|
-
*
|
|
161
|
-
*
|
|
184
|
+
* Drop agents whose command isn't on `$PATH`, except entries that opt out via
|
|
185
|
+
* `requireAvailable: false` (e.g. shell aliases the user wants surfaced
|
|
186
|
+
* regardless). `available` is the resolved set from
|
|
187
|
+
* {@link fetchAvailableCommands}.
|
|
162
188
|
*
|
|
163
|
-
*
|
|
164
|
-
* the input unchanged — better to show an unreachable agent than
|
|
165
|
-
* the entire launcher because the server extension didn't load.
|
|
189
|
+
* When `available` is `null` (the endpoint couldn't be reached) we fail open
|
|
190
|
+
* and return the input unchanged — better to show an unreachable agent than
|
|
191
|
+
* to hide the entire launcher because the server extension didn't load.
|
|
166
192
|
*/
|
|
167
|
-
|
|
168
|
-
const commands = agents
|
|
169
|
-
.filter(agent => agent.requireAvailable)
|
|
170
|
-
.map(agent => agent.command);
|
|
171
|
-
if (commands.length === 0) {
|
|
172
|
-
return agents;
|
|
173
|
-
}
|
|
174
|
-
const available = await fetchAvailableCommands(commands);
|
|
193
|
+
function filterAgents(agents, available) {
|
|
175
194
|
if (!available) {
|
|
176
195
|
return agents;
|
|
177
196
|
}
|
|
@@ -188,4 +207,8 @@ var Private;
|
|
|
188
207
|
}
|
|
189
208
|
Private.nextId = nextId;
|
|
190
209
|
})(Private || (Private = {}));
|
|
191
|
-
|
|
210
|
+
const plugins = [
|
|
211
|
+
plugin,
|
|
212
|
+
editorRegistryPlugin
|
|
213
|
+
];
|
|
214
|
+
export default plugins;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ISignal } from '@lumino/signaling';
|
|
2
|
+
import type { IAgent } from './agents';
|
|
3
|
+
import type { IAgentRegistry } from './tokens';
|
|
4
|
+
/**
|
|
5
|
+
* The concrete {@link IAgentRegistry} the launcher plugin provides on the
|
|
6
|
+
* `IAgentRegistry` token. Holds the active agent list and re-emits `changed`
|
|
7
|
+
* whenever the launcher recomputes it (on a settings change). The launcher
|
|
8
|
+
* is the only writer, so the write side ({@link setAgents}) is kept off the
|
|
9
|
+
* shared token.
|
|
10
|
+
*/
|
|
11
|
+
export declare class AgentRegistry implements IAgentRegistry {
|
|
12
|
+
get agents(): IAgent[];
|
|
13
|
+
get changed(): ISignal<IAgentRegistry, void>;
|
|
14
|
+
/**
|
|
15
|
+
* Replace the agent list and notify observers. Called by the launcher
|
|
16
|
+
* after merging the user's settings and filtering by availability.
|
|
17
|
+
*/
|
|
18
|
+
setAgents(agents: IAgent[]): void;
|
|
19
|
+
private _agents;
|
|
20
|
+
private _changed;
|
|
21
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Signal } from '@lumino/signaling';
|
|
2
|
+
/**
|
|
3
|
+
* The concrete {@link IAgentRegistry} the launcher plugin provides on the
|
|
4
|
+
* `IAgentRegistry` token. Holds the active agent list and re-emits `changed`
|
|
5
|
+
* whenever the launcher recomputes it (on a settings change). The launcher
|
|
6
|
+
* is the only writer, so the write side ({@link setAgents}) is kept off the
|
|
7
|
+
* shared token.
|
|
8
|
+
*/
|
|
9
|
+
export class AgentRegistry {
|
|
10
|
+
constructor() {
|
|
11
|
+
this._agents = [];
|
|
12
|
+
this._changed = new Signal(this);
|
|
13
|
+
}
|
|
14
|
+
get agents() {
|
|
15
|
+
return this._agents;
|
|
16
|
+
}
|
|
17
|
+
get changed() {
|
|
18
|
+
return this._changed;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Replace the agent list and notify observers. Called by the launcher
|
|
22
|
+
* after merging the user's settings and filtering by availability.
|
|
23
|
+
*/
|
|
24
|
+
setAgents(agents) {
|
|
25
|
+
this._agents = agents;
|
|
26
|
+
this._changed.emit();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Token } from '@lumino/coreutils';
|
|
2
|
+
import type { ISignal } from '@lumino/signaling';
|
|
3
|
+
import type { IAgent } from './agents';
|
|
4
|
+
/**
|
|
5
|
+
* A read-only, observable view of the launcher's available agents.
|
|
6
|
+
*
|
|
7
|
+
* The launcher plugin owns the agent list — xtralab's defaults merged with
|
|
8
|
+
* the user's `xtralab:launcher` settings, then filtered by a server-side
|
|
9
|
+
* `which` check — and registers an `xtralab:start-agent:<id>` command for
|
|
10
|
+
* each entry. This token shares that list, and (via {@link agentCommandId})
|
|
11
|
+
* the command id that launches each agent, so other plugins can surface the
|
|
12
|
+
* same agents without re-deriving the list or duplicating the icons. The
|
|
13
|
+
* terminals panel uses it to build its "new terminal" dropdown.
|
|
14
|
+
*/
|
|
15
|
+
export interface IAgentRegistry {
|
|
16
|
+
/**
|
|
17
|
+
* The current agents, already filtered by availability and sorted by
|
|
18
|
+
* rank — the same array the launcher renders.
|
|
19
|
+
*/
|
|
20
|
+
readonly agents: IAgent[];
|
|
21
|
+
/**
|
|
22
|
+
* Emitted whenever {@link agents} changes (e.g. the user edits the
|
|
23
|
+
* launcher settings). Consumers that cache the list should re-read it
|
|
24
|
+
* here; consumers that read it on demand can ignore the signal.
|
|
25
|
+
*/
|
|
26
|
+
readonly changed: ISignal<IAgentRegistry, void>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* DI token for {@link IAgentRegistry}. Provided by `xtralab:launcher` and
|
|
30
|
+
* consumed — optionally, so the panel still works when the launcher is
|
|
31
|
+
* disabled — by `xtralab:terminals`.
|
|
32
|
+
*/
|
|
33
|
+
export declare const IAgentRegistry: Token<IAgentRegistry>;
|
|
34
|
+
/**
|
|
35
|
+
* The JupyterLab command id that launches a given agent in a new terminal.
|
|
36
|
+
* Defined here — in the shared contract module rather than the launcher's
|
|
37
|
+
* command-registration internals — so the launcher (which registers the
|
|
38
|
+
* commands) and any consumer (which references them, e.g. in a menu) agree
|
|
39
|
+
* on the id.
|
|
40
|
+
*/
|
|
41
|
+
export declare function agentCommandId(agentId: string): string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Token } from '@lumino/coreutils';
|
|
2
|
+
/**
|
|
3
|
+
* DI token for {@link IAgentRegistry}. Provided by `xtralab:launcher` and
|
|
4
|
+
* consumed — optionally, so the panel still works when the launcher is
|
|
5
|
+
* disabled — by `xtralab:terminals`.
|
|
6
|
+
*/
|
|
7
|
+
export const IAgentRegistry = new Token('xtralab:IAgentRegistry', 'A read-only, observable view of the launcher agents, shared so other plugins can offer the same agent list and icons.');
|
|
8
|
+
/**
|
|
9
|
+
* The JupyterLab command id that launches a given agent in a new terminal.
|
|
10
|
+
* Defined here — in the shared contract module rather than the launcher's
|
|
11
|
+
* command-registration internals — so the launcher (which registers the
|
|
12
|
+
* commands) and any consumer (which references them, e.g. in a menu) agree
|
|
13
|
+
* on the id.
|
|
14
|
+
*/
|
|
15
|
+
export function agentCommandId(agentId) {
|
|
16
|
+
return `xtralab:start-agent:${agentId}`;
|
|
17
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ask the xtralab server which of `commands` is currently running inside each
|
|
3
|
+
* open terminal session. Resolves to a map from session name to the matched
|
|
4
|
+
* agent command, or `null` for a session sitting at its prompt.
|
|
5
|
+
*
|
|
6
|
+
* On any failure (endpoint missing on an older server, network error,
|
|
7
|
+
* malformed response) the whole result is `null` — callers should treat that
|
|
8
|
+
* as "detection unavailable" and fall back to the optimistic launch tags
|
|
9
|
+
* rather than clearing any badges.
|
|
10
|
+
*/
|
|
11
|
+
export declare function fetchRunningAgents(commands: string[]): Promise<Record<string, string | null> | null>;
|