xtralab 0.11.0 → 0.12.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 +37 -229
- package/lib/agentSessions.d.ts +6 -2
- package/lib/askAgent/editorSelection.d.ts +53 -0
- package/lib/askAgent/editorSelection.js +95 -0
- package/lib/askAgent/icons.d.ts +7 -0
- package/lib/askAgent/icons.js +15 -0
- package/lib/askAgent/index.d.ts +32 -0
- package/lib/askAgent/index.js +741 -0
- package/lib/askAgent/popup.d.ts +83 -0
- package/lib/askAgent/popup.js +221 -0
- package/lib/askAgent/prompt.d.ts +24 -0
- package/lib/askAgent/prompt.js +116 -0
- package/lib/askAgent/queue.d.ts +93 -0
- package/lib/askAgent/queue.js +207 -0
- package/lib/askAgent/queuePanel.d.ts +76 -0
- package/lib/askAgent/queuePanel.js +188 -0
- package/lib/askAgent/targetPicker.d.ts +58 -0
- package/lib/askAgent/targetPicker.js +74 -0
- package/lib/askAgent/tokens.d.ts +124 -0
- package/lib/askAgent/tokens.js +13 -0
- package/lib/commandBar/index.d.ts +12 -8
- package/lib/commandBar/index.js +58 -41
- package/lib/editorBreadcrumbs/index.js +9 -4
- package/lib/editorBreadcrumbs/widget.d.ts +7 -7
- package/lib/editorBreadcrumbs/widget.js +6 -8
- package/lib/fileBrowser/commands.d.ts +2 -8
- package/lib/fileBrowser/commands.js +39 -30
- package/lib/fileBrowser/contents.d.ts +8 -3
- package/lib/fileBrowser/fileBrowser.d.ts +2 -1
- package/lib/fileBrowser/widget.d.ts +5 -9
- package/lib/fileBrowser/widget.js +1 -1
- package/lib/fileTypeIcons/index.js +5 -2
- package/lib/git/api.d.ts +0 -26
- package/lib/git/api.js +2 -44
- package/lib/git/askRequest.d.ts +23 -0
- package/lib/git/askRequest.js +90 -0
- package/lib/git/commands.d.ts +14 -2
- package/lib/git/commands.js +16 -13
- package/lib/git/diffModel.d.ts +1 -9
- package/lib/git/diffModel.js +1 -1
- package/lib/git/diffProvider.js +8 -3
- package/lib/git/diffSurface.d.ts +19 -2
- package/lib/git/diffSurface.js +64 -18
- package/lib/git/diffTheme.d.ts +0 -4
- package/lib/git/diffTheme.js +1 -1
- package/lib/git/diffWidget.d.ts +9 -0
- package/lib/git/diffWidget.js +38 -10
- package/lib/git/imageDiff.d.ts +17 -4
- package/lib/git/imageDiff.js +90 -30
- package/lib/git/index.js +7 -2
- package/lib/git/notebookDiff.d.ts +10 -67
- package/lib/git/notebookDiff.js +62 -69
- package/lib/git/tokens.d.ts +5 -2
- package/lib/highlight/index.js +12 -8
- package/lib/index.js +2 -0
- package/lib/launcher/agents.d.ts +11 -1
- package/lib/launcher/agents.js +26 -8
- package/lib/launcher/commands.d.ts +6 -2
- package/lib/launcher/dashboard.d.ts +8 -1
- package/lib/launcher/dashboard.js +39 -33
- package/lib/launcher/editorRegistry.js +5 -3
- package/lib/launcher/editors.d.ts +24 -7
- package/lib/launcher/editors.js +14 -5
- package/lib/launcher/icons.d.ts +0 -37
- package/lib/launcher/icons.js +11 -12
- package/lib/launcher/index.js +5 -2
- package/lib/launcher/invocation.d.ts +0 -15
- package/lib/launcher/invocation.js +1 -1
- package/lib/launcher/schemaDefaults.d.ts +3 -1
- package/lib/launcher/schemaDefaults.js +3 -1
- package/lib/mimeData.d.ts +7 -0
- package/lib/mimeData.js +16 -0
- package/lib/omnibox/index.d.ts +4 -0
- package/lib/omnibox/index.js +43 -2
- package/lib/omnibox/model.d.ts +43 -14
- package/lib/omnibox/model.js +117 -14
- package/lib/omnibox/recents.d.ts +65 -0
- package/lib/omnibox/recents.js +109 -0
- package/lib/omnibox/tokens.d.ts +6 -2
- package/lib/omnibox/widget.d.ts +23 -6
- package/lib/omnibox/widget.js +26 -7
- package/lib/showOutput/index.js +15 -18
- package/lib/terminals/agentTerminals.d.ts +63 -0
- package/lib/terminals/agentTerminals.js +157 -0
- package/lib/terminals/index.d.ts +7 -1
- package/lib/terminals/index.js +50 -30
- package/lib/terminals/model.d.ts +11 -2
- package/lib/terminals/model.js +27 -8
- package/lib/terminals/tokens.d.ts +66 -0
- package/lib/terminals/tokens.js +7 -0
- package/lib/terminals/widget.d.ts +3 -6
- package/lib/terminals/widget.js +1 -1
- package/lib/topBar/index.js +3 -3
- package/lib/walkthrough/index.js +14 -3
- package/lib/walkthrough/panel.d.ts +12 -4
- package/lib/walkthrough/panel.js +9 -3
- package/package.json +49 -51
- package/schema/command-bar.json +10 -0
- package/schema/launcher.json +4 -4
- package/schema/omnibox.json +15 -0
- package/src/agentSessions.ts +6 -2
- package/src/askAgent/editorSelection.ts +138 -0
- package/src/askAgent/icons.ts +16 -0
- package/src/askAgent/index.ts +915 -0
- package/src/askAgent/popup.tsx +407 -0
- package/src/askAgent/prompt.ts +144 -0
- package/src/askAgent/queue.ts +269 -0
- package/src/askAgent/queuePanel.tsx +418 -0
- package/src/askAgent/targetPicker.tsx +209 -0
- package/src/askAgent/tokens.ts +139 -0
- package/src/commandBar/index.ts +75 -49
- package/src/editorBreadcrumbs/index.ts +14 -4
- package/src/editorBreadcrumbs/widget.ts +11 -9
- package/src/fileBrowser/commands.ts +45 -31
- package/src/fileBrowser/contents.ts +7 -3
- package/src/fileBrowser/fileBrowser.tsx +1 -1
- package/src/fileBrowser/widget.tsx +5 -3
- package/src/fileTypeIcons/index.ts +6 -3
- package/src/git/api.ts +2 -61
- package/src/git/askRequest.ts +113 -0
- package/src/git/commands.ts +41 -14
- package/src/git/diffModel.ts +1 -1
- package/src/git/diffProvider.tsx +11 -3
- package/src/git/diffSurface.tsx +114 -22
- package/src/git/diffTheme.ts +1 -1
- package/src/git/diffWidget.tsx +54 -7
- package/src/git/imageDiff.tsx +169 -58
- package/src/git/index.ts +10 -2
- package/src/git/notebookDiff.tsx +91 -57
- package/src/git/tokens.ts +4 -2
- package/src/highlight/index.ts +12 -8
- package/src/index.ts +2 -0
- package/src/launcher/agents.ts +31 -7
- package/src/launcher/commands.ts +6 -2
- package/src/launcher/dashboard.tsx +86 -38
- package/src/launcher/editorRegistry.ts +10 -4
- package/src/launcher/editors.ts +34 -9
- package/src/launcher/icons.ts +11 -12
- package/src/launcher/index.ts +5 -2
- package/src/launcher/invocation.ts +1 -1
- package/src/launcher/schemaDefaults.ts +3 -1
- package/src/mimeData.ts +20 -0
- package/src/omnibox/index.ts +48 -1
- package/src/omnibox/model.ts +173 -33
- package/src/omnibox/recents.ts +155 -0
- package/src/omnibox/tokens.ts +6 -2
- package/src/omnibox/widget.tsx +54 -13
- package/src/showOutput/index.ts +20 -23
- package/src/terminals/agentTerminals.ts +238 -0
- package/src/terminals/index.ts +54 -30
- package/src/terminals/model.ts +28 -7
- package/src/terminals/tokens.ts +77 -0
- package/src/terminals/widget.tsx +4 -2
- package/src/topBar/index.ts +12 -6
- package/src/walkthrough/index.ts +19 -4
- package/src/walkthrough/panel.ts +15 -5
- package/style/askAgent.css +544 -0
- package/style/commandBar.css +12 -33
- package/style/git.css +72 -31
- package/style/index.css +1 -0
- package/style/index.js +2 -0
- package/style/topBar.css +4 -4
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
3
|
+
import type { TranslationBundle } from '@jupyterlab/translation';
|
|
3
4
|
import { type FileDiffMetadata } from '@pierre/diffs';
|
|
4
|
-
/**
|
|
5
|
-
* The CSS class added to the root of the notebook diff. Selectors that
|
|
6
|
-
* style cell sections, headers, and the per-cell diff blocks hang off this
|
|
7
|
-
* class.
|
|
8
|
-
*/
|
|
9
|
-
export declare const NOTEBOOK_DIFF_CSS_CLASS = "jp-xtralab-NotebookDiff";
|
|
10
5
|
/**
|
|
11
6
|
* Minimal slice of nbformat 4.x that the diff inspects. Fields we don't
|
|
12
7
|
* read (attachments, e.g.) are intentionally not narrowed — we still pass
|
|
13
8
|
* them around as part of the cell, but we never project them into the diff.
|
|
14
9
|
*/
|
|
15
|
-
|
|
10
|
+
interface INotebookCell {
|
|
16
11
|
cell_type: string;
|
|
17
12
|
id?: string;
|
|
18
13
|
source: string | string[];
|
|
@@ -21,7 +16,7 @@ export interface INotebookCell {
|
|
|
21
16
|
execution_count?: number | null;
|
|
22
17
|
attachments?: Record<string, unknown>;
|
|
23
18
|
}
|
|
24
|
-
|
|
19
|
+
interface INotebookOutput {
|
|
25
20
|
output_type: string;
|
|
26
21
|
data?: Record<string, unknown>;
|
|
27
22
|
text?: string | string[];
|
|
@@ -32,7 +27,7 @@ export interface INotebookOutput {
|
|
|
32
27
|
execution_count?: number | null;
|
|
33
28
|
metadata?: Record<string, unknown>;
|
|
34
29
|
}
|
|
35
|
-
|
|
30
|
+
interface INotebook {
|
|
36
31
|
cells: INotebookCell[];
|
|
37
32
|
metadata: Record<string, unknown>;
|
|
38
33
|
nbformat: number;
|
|
@@ -45,7 +40,7 @@ export interface INotebook {
|
|
|
45
40
|
* carry the same payload but live on separate union members so `Extract`
|
|
46
41
|
* narrowing works on `kind` literals downstream.
|
|
47
42
|
*/
|
|
48
|
-
|
|
43
|
+
type NotebookCellDiff = {
|
|
49
44
|
kind: 'modified';
|
|
50
45
|
oldCell: INotebookCell;
|
|
51
46
|
newCell: INotebookCell;
|
|
@@ -87,63 +82,7 @@ export interface INotebookDiffResult {
|
|
|
87
82
|
*/
|
|
88
83
|
notebookMetadataDiff: FileDiffMetadata | null;
|
|
89
84
|
}
|
|
90
|
-
|
|
91
|
-
* Parse notebook JSON. Returns `null` if the text doesn't parse or doesn't
|
|
92
|
-
* look like a notebook (missing `cells` array). The caller falls back to a
|
|
93
|
-
* raw text diff so a malformed file is still inspectable.
|
|
94
|
-
*/
|
|
95
|
-
export declare function parseNotebook(text: string): INotebook | null;
|
|
96
|
-
/**
|
|
97
|
-
* nbformat allows multiline string fields (`source`, stream `text`,
|
|
98
|
-
* `text/plain` outputs, …) to be either a single string or an array of
|
|
99
|
-
* strings. Normalize to one string so equality checks and diffs see the
|
|
100
|
-
* same shape regardless of how the writer chose to serialize it.
|
|
101
|
-
*/
|
|
102
|
-
export declare function joinMultiline(value: string | string[] | undefined): string;
|
|
103
|
-
export declare function cellSource(cell: INotebookCell): string;
|
|
104
|
-
/**
|
|
105
|
-
* Canonical text representation of a cell's outputs, used both for equality
|
|
106
|
-
* checks and for the per-cell output diff. Stream and `text/plain` data
|
|
107
|
-
* round-trip verbatim; richer mime types (image/png, text/html, …) collapse
|
|
108
|
-
* to a `<mime-type>` placeholder so diffing image bytes doesn't drown the
|
|
109
|
-
* panel in base64 noise.
|
|
110
|
-
*/
|
|
111
|
-
export declare function canonicalOutputs(cell: INotebookCell): string;
|
|
112
|
-
/**
|
|
113
|
-
* Stable JSON of the cell's `metadata` object. Keys are sorted recursively
|
|
114
|
-
* so a writer that re-orders the metadata object doesn't surface as a diff.
|
|
115
|
-
* An empty metadata object returns the empty string so freshly-added cells
|
|
116
|
-
* that carry the default `{}` don't produce a `+{}` placeholder section.
|
|
117
|
-
*/
|
|
118
|
-
export declare function canonicalMetadata(cell: INotebookCell): string;
|
|
119
|
-
/**
|
|
120
|
-
* Stable JSON of the notebook-level metadata bundle (kernelspec, language
|
|
121
|
-
* info, nbformat). We diff the bundle as a single block so the user sees
|
|
122
|
-
* all environment-level changes in one place.
|
|
123
|
-
*/
|
|
124
|
-
export declare function canonicalNotebookMetadata(notebook: INotebook): string;
|
|
125
|
-
/**
|
|
126
|
-
* Equality check used to classify matched cells as `unchanged` vs
|
|
127
|
-
* `modified`. Compares the three things we actually render — type, source,
|
|
128
|
-
* outputs, metadata — using the same canonical representations the diff
|
|
129
|
-
* itself sees, so an "equal" verdict here implies all per-cell diff blocks
|
|
130
|
-
* would be empty.
|
|
131
|
-
*/
|
|
132
|
-
export declare function cellsAreEqual(a: INotebookCell, b: INotebookCell): boolean;
|
|
133
|
-
/**
|
|
134
|
-
* Align cells between two notebook revisions. Cells that carry a stable id
|
|
135
|
-
* (nbformat ≥ 4.5) match on their id; remaining cells fall back to
|
|
136
|
-
* positional matching against the next un-consumed unidentified old cell so
|
|
137
|
-
* older notebooks still produce a sensible diff.
|
|
138
|
-
*
|
|
139
|
-
* Output ordering: entries follow new-file order, with cells that exist
|
|
140
|
-
* only in the old revision appended at the end as `removed`. We don't try
|
|
141
|
-
* to interleave removals at their original position — for typical notebook
|
|
142
|
-
* edits this is more readable than guessing alignment between unrelated
|
|
143
|
-
* insertions and deletions.
|
|
144
|
-
*/
|
|
145
|
-
export declare function alignNotebookCells(oldCells: INotebookCell[], newCells: INotebookCell[]): NotebookCellDiff[];
|
|
146
|
-
export interface IBuildNotebookDiffOptions {
|
|
85
|
+
interface IBuildNotebookDiffOptions {
|
|
147
86
|
oldText: string;
|
|
148
87
|
newText: string;
|
|
149
88
|
}
|
|
@@ -166,6 +105,10 @@ interface INotebookDiffViewProps {
|
|
|
166
105
|
*/
|
|
167
106
|
pierreTheme: boolean;
|
|
168
107
|
rendermime: IRenderMimeRegistry | null;
|
|
108
|
+
/**
|
|
109
|
+
* Translation bundle for user-facing strings.
|
|
110
|
+
*/
|
|
111
|
+
trans: TranslationBundle;
|
|
169
112
|
}
|
|
170
113
|
/**
|
|
171
114
|
* The notebook-level diff view. Lays out cells in a 2-column grid where
|
package/lib/git/notebookDiff.js
CHANGED
|
@@ -11,13 +11,13 @@ import { resolveDiffTheme } from './diffTheme';
|
|
|
11
11
|
* style cell sections, headers, and the per-cell diff blocks hang off this
|
|
12
12
|
* class.
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
const NOTEBOOK_DIFF_CSS_CLASS = 'jp-xtralab-NotebookDiff';
|
|
15
15
|
/**
|
|
16
16
|
* Parse notebook JSON. Returns `null` if the text doesn't parse or doesn't
|
|
17
17
|
* look like a notebook (missing `cells` array). The caller falls back to a
|
|
18
18
|
* raw text diff so a malformed file is still inspectable.
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
function parseNotebook(text) {
|
|
21
21
|
if (text.length === 0) {
|
|
22
22
|
return emptyNotebook();
|
|
23
23
|
}
|
|
@@ -53,13 +53,13 @@ function emptyNotebook() {
|
|
|
53
53
|
* strings. Normalize to one string so equality checks and diffs see the
|
|
54
54
|
* same shape regardless of how the writer chose to serialize it.
|
|
55
55
|
*/
|
|
56
|
-
|
|
56
|
+
function joinMultiline(value) {
|
|
57
57
|
if (value === undefined) {
|
|
58
58
|
return '';
|
|
59
59
|
}
|
|
60
60
|
return Array.isArray(value) ? value.join('') : value;
|
|
61
61
|
}
|
|
62
|
-
|
|
62
|
+
function cellSource(cell) {
|
|
63
63
|
return joinMultiline(cell.source);
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
@@ -69,7 +69,7 @@ export function cellSource(cell) {
|
|
|
69
69
|
* to a `<mime-type>` placeholder so diffing image bytes doesn't drown the
|
|
70
70
|
* panel in base64 noise.
|
|
71
71
|
*/
|
|
72
|
-
|
|
72
|
+
function canonicalOutputs(cell) {
|
|
73
73
|
var _a;
|
|
74
74
|
const outputs = (_a = cell.outputs) !== null && _a !== void 0 ? _a : [];
|
|
75
75
|
if (outputs.length === 0) {
|
|
@@ -132,7 +132,7 @@ function stripAnsi(value) {
|
|
|
132
132
|
* An empty metadata object returns the empty string so freshly-added cells
|
|
133
133
|
* that carry the default `{}` don't produce a `+{}` placeholder section.
|
|
134
134
|
*/
|
|
135
|
-
|
|
135
|
+
function canonicalMetadata(cell) {
|
|
136
136
|
var _a;
|
|
137
137
|
const md = (_a = cell.metadata) !== null && _a !== void 0 ? _a : {};
|
|
138
138
|
if (Object.keys(md).length === 0) {
|
|
@@ -145,7 +145,7 @@ export function canonicalMetadata(cell) {
|
|
|
145
145
|
* info, nbformat). We diff the bundle as a single block so the user sees
|
|
146
146
|
* all environment-level changes in one place.
|
|
147
147
|
*/
|
|
148
|
-
|
|
148
|
+
function canonicalNotebookMetadata(notebook) {
|
|
149
149
|
return stableStringify({
|
|
150
150
|
metadata: notebook.metadata,
|
|
151
151
|
nbformat: notebook.nbformat,
|
|
@@ -155,11 +155,11 @@ export function canonicalNotebookMetadata(notebook) {
|
|
|
155
155
|
function stableStringify(value) {
|
|
156
156
|
return JSON.stringify(value, sortKeysReplacer, 2);
|
|
157
157
|
}
|
|
158
|
-
function sortKeysReplacer(
|
|
158
|
+
function sortKeysReplacer(key, value) {
|
|
159
159
|
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
160
160
|
const sorted = {};
|
|
161
|
-
for (const
|
|
162
|
-
sorted[
|
|
161
|
+
for (const name of Object.keys(value).sort()) {
|
|
162
|
+
sorted[name] = value[name];
|
|
163
163
|
}
|
|
164
164
|
return sorted;
|
|
165
165
|
}
|
|
@@ -172,7 +172,7 @@ function sortKeysReplacer(_key, value) {
|
|
|
172
172
|
* itself sees, so an "equal" verdict here implies all per-cell diff blocks
|
|
173
173
|
* would be empty.
|
|
174
174
|
*/
|
|
175
|
-
|
|
175
|
+
function cellsAreEqual(a, b) {
|
|
176
176
|
return (a.cell_type === b.cell_type &&
|
|
177
177
|
cellSource(a) === cellSource(b) &&
|
|
178
178
|
canonicalOutputs(a) === canonicalOutputs(b) &&
|
|
@@ -190,7 +190,7 @@ export function cellsAreEqual(a, b) {
|
|
|
190
190
|
* edits this is more readable than guessing alignment between unrelated
|
|
191
191
|
* insertions and deletions.
|
|
192
192
|
*/
|
|
193
|
-
|
|
193
|
+
function alignNotebookCells(oldCells, newCells) {
|
|
194
194
|
const oldById = new Map();
|
|
195
195
|
oldCells.forEach((cell, index) => {
|
|
196
196
|
if (cell.id !== undefined && cell.id.length > 0) {
|
|
@@ -544,7 +544,7 @@ function SideBySidePanes(props) {
|
|
|
544
544
|
*/
|
|
545
545
|
function OutputsSection(props) {
|
|
546
546
|
var _a, _b;
|
|
547
|
-
const { entry, rendermime, placement } = props;
|
|
547
|
+
const { entry, rendermime, placement, trans } = props;
|
|
548
548
|
const oldCell = 'oldCell' in entry ? entry.oldCell : null;
|
|
549
549
|
const newCell = 'newCell' in entry ? entry.newCell : null;
|
|
550
550
|
const oldOutputs = (_a = oldCell === null || oldCell === void 0 ? void 0 : oldCell.outputs) !== null && _a !== void 0 ? _a : [];
|
|
@@ -562,9 +562,9 @@ function OutputsSection(props) {
|
|
|
562
562
|
const showOld = placement !== 'right' && hasOld;
|
|
563
563
|
const showNew = placement !== 'left' && hasNew;
|
|
564
564
|
if (rendermime === null) {
|
|
565
|
-
return (React.createElement(SideBySidePanes, { label:
|
|
565
|
+
return (React.createElement(SideBySidePanes, { label: trans.__('Outputs'), hasOld: showOld, hasNew: showNew, oldNode: React.createElement("pre", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-fallbackText` }, oldCell !== null ? canonicalOutputs(oldCell) : ''), newNode: React.createElement("pre", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-fallbackText` }, newCell !== null ? canonicalOutputs(newCell) : '') }));
|
|
566
566
|
}
|
|
567
|
-
return (React.createElement(SideBySidePanes, { label:
|
|
567
|
+
return (React.createElement(SideBySidePanes, { label: trans.__('Outputs'), hasOld: showOld, hasNew: showNew, oldNode: React.createElement(OutputsPreview, { outputs: oldOutputs, rendermime: rendermime }), newNode: React.createElement(OutputsPreview, { outputs: newOutputs, rendermime: rendermime }) }));
|
|
568
568
|
}
|
|
569
569
|
/**
|
|
570
570
|
* Rendered markdown preview section. Sits next to (and below) the markdown
|
|
@@ -572,7 +572,7 @@ function OutputsSection(props) {
|
|
|
572
572
|
* rendered cell looks. Skipped for non-markdown cells.
|
|
573
573
|
*/
|
|
574
574
|
function MarkdownPreviewSection(props) {
|
|
575
|
-
const { entry, rendermime, placement } = props;
|
|
575
|
+
const { entry, rendermime, placement, trans } = props;
|
|
576
576
|
const isMarkdown = referenceCellType(entry) === 'markdown';
|
|
577
577
|
if (!isMarkdown || rendermime === null) {
|
|
578
578
|
return null;
|
|
@@ -584,7 +584,7 @@ function MarkdownPreviewSection(props) {
|
|
|
584
584
|
if (!showOld && !showNew) {
|
|
585
585
|
return null;
|
|
586
586
|
}
|
|
587
|
-
return (React.createElement(SideBySidePanes, { label:
|
|
587
|
+
return (React.createElement(SideBySidePanes, { label: trans.__('Rendered'), hasOld: showOld, hasNew: showNew, oldNode: React.createElement(MarkdownPreview, { source: oldSource, rendermime: rendermime }), newNode: React.createElement(MarkdownPreview, { source: newSource, rendermime: rendermime }) }));
|
|
588
588
|
}
|
|
589
589
|
/**
|
|
590
590
|
* The notebook-level diff view. Lays out cells in a 2-column grid where
|
|
@@ -597,13 +597,13 @@ function MarkdownPreviewSection(props) {
|
|
|
597
597
|
* the orientation clear without a separate column header.
|
|
598
598
|
*/
|
|
599
599
|
export function NotebookDiffView(props) {
|
|
600
|
-
const { diff, dark, pierreTheme, rendermime } = props;
|
|
600
|
+
const { diff, dark, pierreTheme, rendermime, trans } = props;
|
|
601
601
|
const theme = resolveDiffTheme(dark, pierreTheme);
|
|
602
602
|
const summary = React.useMemo(() => summarize(diff.cells), [diff.cells]);
|
|
603
603
|
return (React.createElement("div", { className: NOTEBOOK_DIFF_CSS_CLASS },
|
|
604
|
-
React.createElement(NotebookDiffHeader, { summary: summary }),
|
|
605
|
-
React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-grid` }, diff.cells.map(entry => (React.createElement(CellEntryRow, { key: cellEntryKey(entry), entry: entry, language: diff.language, theme: theme, dark: dark, rendermime: rendermime })))),
|
|
606
|
-
diff.notebookMetadataDiff !== null ? (React.createElement(NotebookMetadataBlock, { metadata: diff.notebookMetadataDiff, theme: theme, dark: dark })) : null));
|
|
604
|
+
React.createElement(NotebookDiffHeader, { summary: summary, trans: trans }),
|
|
605
|
+
React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-grid` }, diff.cells.map(entry => (React.createElement(CellEntryRow, { key: cellEntryKey(entry), entry: entry, language: diff.language, theme: theme, dark: dark, rendermime: rendermime, trans: trans })))),
|
|
606
|
+
diff.notebookMetadataDiff !== null ? (React.createElement(NotebookMetadataBlock, { metadata: diff.notebookMetadataDiff, theme: theme, dark: dark, trans: trans })) : null));
|
|
607
607
|
}
|
|
608
608
|
/**
|
|
609
609
|
* Place a single cell entry into the outer 2-column grid. Modified /
|
|
@@ -614,24 +614,28 @@ export function NotebookDiffView(props) {
|
|
|
614
614
|
* cell was inserted or removed relative to the other side.
|
|
615
615
|
*/
|
|
616
616
|
function CellEntryRow(props) {
|
|
617
|
-
const { entry } = props;
|
|
617
|
+
const { entry, trans } = props;
|
|
618
618
|
if (entry.kind === 'added') {
|
|
619
619
|
return (React.createElement(React.Fragment, null,
|
|
620
|
-
React.createElement(EmptyCellPlaceholder, { side: "old", reason: "added" }),
|
|
620
|
+
React.createElement(EmptyCellPlaceholder, { side: "old", reason: "added", trans: trans }),
|
|
621
621
|
React.createElement(CellDiffBlock, { ...props, placement: "right" })));
|
|
622
622
|
}
|
|
623
623
|
if (entry.kind === 'removed') {
|
|
624
624
|
return (React.createElement(React.Fragment, null,
|
|
625
625
|
React.createElement(CellDiffBlock, { ...props, placement: "left" }),
|
|
626
|
-
React.createElement(EmptyCellPlaceholder, { side: "new", reason: "removed" })));
|
|
626
|
+
React.createElement(EmptyCellPlaceholder, { side: "new", reason: "removed", trans: trans })));
|
|
627
627
|
}
|
|
628
628
|
return React.createElement(CellDiffBlock, { ...props, placement: "full" });
|
|
629
629
|
}
|
|
630
630
|
function EmptyCellPlaceholder(props) {
|
|
631
|
-
const { side, reason } = props;
|
|
632
|
-
const label = reason === 'added'
|
|
631
|
+
const { side, reason, trans } = props;
|
|
632
|
+
const label = reason === 'added'
|
|
633
|
+
? trans.__('cell added on the right')
|
|
634
|
+
: trans.__('cell removed');
|
|
633
635
|
return (React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-empty`, "data-side": side, "aria-label": label },
|
|
634
|
-
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-emptyLabel` }, reason === 'added'
|
|
636
|
+
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-emptyLabel` }, reason === 'added'
|
|
637
|
+
? trans.__('— no cell —')
|
|
638
|
+
: trans.__('— cell removed —'))));
|
|
635
639
|
}
|
|
636
640
|
function summarize(cells) {
|
|
637
641
|
const summary = {
|
|
@@ -646,25 +650,14 @@ function summarize(cells) {
|
|
|
646
650
|
return summary;
|
|
647
651
|
}
|
|
648
652
|
function NotebookDiffHeader(props) {
|
|
649
|
-
const { summary } = props;
|
|
653
|
+
const { summary, trans } = props;
|
|
650
654
|
const total = summary.added + summary.removed + summary.modified + summary.unchanged;
|
|
651
655
|
return (React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-header` },
|
|
652
|
-
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-headerCount` },
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
summary.
|
|
657
|
-
summary.modified,
|
|
658
|
-
" modified")) : null,
|
|
659
|
-
summary.added > 0 ? (React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-stat`, "data-kind": "added" },
|
|
660
|
-
summary.added,
|
|
661
|
-
" added")) : null,
|
|
662
|
-
summary.removed > 0 ? (React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-stat`, "data-kind": "removed" },
|
|
663
|
-
summary.removed,
|
|
664
|
-
" removed")) : null,
|
|
665
|
-
summary.unchanged > 0 ? (React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-stat`, "data-kind": "unchanged" },
|
|
666
|
-
summary.unchanged,
|
|
667
|
-
" unchanged")) : null));
|
|
656
|
+
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-headerCount` }, trans._n('%1 cell', '%1 cells', total)),
|
|
657
|
+
summary.modified > 0 ? (React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-stat`, "data-kind": "modified" }, trans.__('%1 modified', summary.modified))) : null,
|
|
658
|
+
summary.added > 0 ? (React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-stat`, "data-kind": "added" }, trans.__('%1 added', summary.added))) : null,
|
|
659
|
+
summary.removed > 0 ? (React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-stat`, "data-kind": "removed" }, trans.__('%1 removed', summary.removed))) : null,
|
|
660
|
+
summary.unchanged > 0 ? (React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-stat`, "data-kind": "unchanged" }, trans.__('%1 unchanged', summary.unchanged))) : null));
|
|
668
661
|
}
|
|
669
662
|
function cellEntryKey(entry) {
|
|
670
663
|
var _a, _b, _c, _d;
|
|
@@ -678,7 +671,7 @@ function cellEntryKey(entry) {
|
|
|
678
671
|
}
|
|
679
672
|
function CellDiffBlock(props) {
|
|
680
673
|
var _a, _b;
|
|
681
|
-
const { entry, language, theme, dark, rendermime, placement } = props;
|
|
674
|
+
const { entry, language, theme, dark, rendermime, placement, trans } = props;
|
|
682
675
|
// Unchanged cells start collapsed — the user opted out of seeing those
|
|
683
676
|
// sections by virtue of them being unchanged. A toggle lets them peek if
|
|
684
677
|
// they want.
|
|
@@ -698,23 +691,23 @@ function CellDiffBlock(props) {
|
|
|
698
691
|
}
|
|
699
692
|
} },
|
|
700
693
|
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellChevron` }, collapsed ? '▸' : '▾'),
|
|
701
|
-
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellBadge`, "data-kind": entry.kind }, kindBadge(entry.kind)),
|
|
694
|
+
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellBadge`, "data-kind": entry.kind }, kindBadge(entry.kind, trans)),
|
|
702
695
|
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellLabel` },
|
|
703
696
|
indexLabel,
|
|
704
697
|
" \u00B7 ",
|
|
705
698
|
cellType),
|
|
706
|
-
entry.kind === 'unchanged' ? (React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellHint` },
|
|
707
|
-
!collapsed ? (React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellBody` }, entry.kind === 'unchanged' ? (React.createElement(UnchangedCellBody, { entry: entry, rendermime: rendermime })) : (React.createElement(React.Fragment, null,
|
|
708
|
-
subdiffs.map(sub => (React.createElement(CellSubDiff, { key: sub.kind, kind: sub.kind, metadata: sub.metadata, theme: theme, dark: dark, placement: placement }))),
|
|
709
|
-
React.createElement(MarkdownPreviewSection, { entry: entry, rendermime: rendermime, placement: placement }),
|
|
710
|
-
showOutputs ? (React.createElement(OutputsSection, { entry: entry, rendermime: rendermime, placement: placement })) : null,
|
|
699
|
+
entry.kind === 'unchanged' ? (React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellHint` }, trans.__('unchanged'))) : null),
|
|
700
|
+
!collapsed ? (React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellBody` }, entry.kind === 'unchanged' ? (React.createElement(UnchangedCellBody, { entry: entry, rendermime: rendermime, trans: trans })) : (React.createElement(React.Fragment, null,
|
|
701
|
+
subdiffs.map(sub => (React.createElement(CellSubDiff, { key: sub.kind, kind: sub.kind, metadata: sub.metadata, theme: theme, dark: dark, placement: placement, trans: trans }))),
|
|
702
|
+
React.createElement(MarkdownPreviewSection, { entry: entry, rendermime: rendermime, placement: placement, trans: trans }),
|
|
703
|
+
showOutputs ? (React.createElement(OutputsSection, { entry: entry, rendermime: rendermime, placement: placement, trans: trans })) : null,
|
|
711
704
|
subdiffs.length === 0 &&
|
|
712
705
|
!(showOutputs &&
|
|
713
706
|
(('oldCell' in entry && ((_a = entry.oldCell.outputs) === null || _a === void 0 ? void 0 : _a.length)) ||
|
|
714
|
-
('newCell' in entry && ((_b = entry.newCell.outputs) === null || _b === void 0 ? void 0 : _b.length)))) ? (React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellEmpty` },
|
|
707
|
+
('newCell' in entry && ((_b = entry.newCell.outputs) === null || _b === void 0 ? void 0 : _b.length)))) ? (React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellEmpty` }, trans.__('No content differences detected.'))) : null)))) : null));
|
|
715
708
|
}
|
|
716
709
|
function CellSubDiff(props) {
|
|
717
|
-
const { kind, metadata, theme, dark, placement } = props;
|
|
710
|
+
const { kind, metadata, theme, dark, placement, trans } = props;
|
|
718
711
|
// For modified / unchanged cells the diff spans both outer columns, and
|
|
719
712
|
// split mode lets it visually align with the outer old | new lanes. For
|
|
720
713
|
// added / removed cells the diff sits inside a single outer column, so
|
|
@@ -722,7 +715,7 @@ function CellSubDiff(props) {
|
|
|
722
715
|
// column empty.
|
|
723
716
|
const diffStyle = placement === 'full' ? 'split' : 'unified';
|
|
724
717
|
return (React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-subdiff`, "data-section": kind },
|
|
725
|
-
React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-subdiffLabel` }, subdiffLabel(kind)),
|
|
718
|
+
React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-subdiffLabel` }, subdiffLabel(kind, trans)),
|
|
726
719
|
React.createElement(FileDiff, { fileDiff: metadata,
|
|
727
720
|
// See diffWidget.tsx — the worker bootstrap can't resolve through
|
|
728
721
|
// JupyterLab's federation pipeline, so every diff in this extension
|
|
@@ -731,14 +724,14 @@ function CellSubDiff(props) {
|
|
|
731
724
|
disableWorkerPool: true, options: { ...diffLibraryOptions(theme, dark), diffStyle } })));
|
|
732
725
|
}
|
|
733
726
|
function NotebookMetadataBlock(props) {
|
|
734
|
-
const { metadata, theme, dark } = props;
|
|
727
|
+
const { metadata, theme, dark, trans } = props;
|
|
735
728
|
return (React.createElement("section", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cell`, "data-kind": "modified", "data-cell-type": "metadata" },
|
|
736
|
-
React.createElement("header", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellHeader`, "aria-label":
|
|
729
|
+
React.createElement("header", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellHeader`, "aria-label": trans.__('Notebook metadata') },
|
|
737
730
|
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellChevron` }, "\u25BE"),
|
|
738
|
-
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellBadge`, "data-kind": "modified" },
|
|
739
|
-
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellLabel` },
|
|
731
|
+
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellBadge`, "data-kind": "modified" }, trans.__('M')),
|
|
732
|
+
React.createElement("span", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellLabel` }, trans.__('Notebook metadata'))),
|
|
740
733
|
React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-cellBody` },
|
|
741
|
-
React.createElement(CellSubDiff, { kind: "metadata", metadata: metadata, theme: theme, dark: dark, placement: "full" }))));
|
|
734
|
+
React.createElement(CellSubDiff, { kind: "metadata", metadata: metadata, theme: theme, dark: dark, placement: "full", trans: trans }))));
|
|
742
735
|
}
|
|
743
736
|
/**
|
|
744
737
|
* Body for an unchanged cell when the user has expanded it. The cell's
|
|
@@ -750,7 +743,7 @@ function NotebookMetadataBlock(props) {
|
|
|
750
743
|
*/
|
|
751
744
|
function UnchangedCellBody(props) {
|
|
752
745
|
var _a;
|
|
753
|
-
const { entry, rendermime } = props;
|
|
746
|
+
const { entry, rendermime, trans } = props;
|
|
754
747
|
const cell = entry.newCell;
|
|
755
748
|
const source = cellSource(cell);
|
|
756
749
|
const isMarkdown = cell.cell_type === 'markdown';
|
|
@@ -758,9 +751,9 @@ function UnchangedCellBody(props) {
|
|
|
758
751
|
const hasOutputs = outputs.length > 0;
|
|
759
752
|
return (React.createElement(React.Fragment, null,
|
|
760
753
|
isMarkdown && rendermime !== null && source.length > 0 ? (React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-unchangedRendered` },
|
|
761
|
-
React.createElement(MarkdownPreview, { source: source, rendermime: rendermime }))) : (React.createElement("pre", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-unchangedSource` }, source.length > 0 ? source : '(empty cell)')),
|
|
754
|
+
React.createElement(MarkdownPreview, { source: source, rendermime: rendermime }))) : (React.createElement("pre", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-unchangedSource` }, source.length > 0 ? source : trans.__('(empty cell)'))),
|
|
762
755
|
hasOutputs && rendermime !== null ? (React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-unchangedOutputs` },
|
|
763
|
-
React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-subdiffLabel` },
|
|
756
|
+
React.createElement("div", { className: `${NOTEBOOK_DIFF_CSS_CLASS}-subdiffLabel` }, trans.__('Outputs')),
|
|
764
757
|
React.createElement(OutputsPreview, { outputs: outputs, rendermime: rendermime }))) : null));
|
|
765
758
|
}
|
|
766
759
|
function referenceCellType(entry) {
|
|
@@ -784,23 +777,23 @@ function cellIndexLabel(entry) {
|
|
|
784
777
|
}
|
|
785
778
|
return `Cell ${entry.oldIndex + 1} → ${entry.newIndex + 1}`;
|
|
786
779
|
}
|
|
787
|
-
function kindBadge(kind) {
|
|
780
|
+
function kindBadge(kind, trans) {
|
|
788
781
|
switch (kind) {
|
|
789
782
|
case 'added':
|
|
790
|
-
return 'A';
|
|
783
|
+
return trans.__('A');
|
|
791
784
|
case 'removed':
|
|
792
|
-
return 'D';
|
|
785
|
+
return trans.__('D');
|
|
793
786
|
case 'modified':
|
|
794
|
-
return 'M';
|
|
787
|
+
return trans.__('M');
|
|
795
788
|
case 'unchanged':
|
|
796
789
|
return '·';
|
|
797
790
|
}
|
|
798
791
|
}
|
|
799
|
-
function subdiffLabel(kind) {
|
|
792
|
+
function subdiffLabel(kind, trans) {
|
|
800
793
|
switch (kind) {
|
|
801
794
|
case 'source':
|
|
802
|
-
return 'Source';
|
|
795
|
+
return trans.__('Source');
|
|
803
796
|
case 'metadata':
|
|
804
|
-
return 'Metadata';
|
|
797
|
+
return trans.__('Metadata');
|
|
805
798
|
}
|
|
806
799
|
}
|
package/lib/git/tokens.d.ts
CHANGED
|
@@ -17,7 +17,9 @@ export interface IGitStatusFile {
|
|
|
17
17
|
from: string;
|
|
18
18
|
is_binary: boolean | null;
|
|
19
19
|
}
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Response shape of `POST /git/<path>/status`.
|
|
22
|
+
*/
|
|
21
23
|
export interface IGitStatusResult {
|
|
22
24
|
code: number;
|
|
23
25
|
branch: string | null;
|
|
@@ -58,7 +60,7 @@ export interface IGitContentResult {
|
|
|
58
60
|
* changes on top of an already-staged version. The panel models that as two
|
|
59
61
|
* separate entries, one per group.
|
|
60
62
|
*/
|
|
61
|
-
|
|
63
|
+
type FileChangeGroup = 'staged' | 'unstaged';
|
|
62
64
|
/**
|
|
63
65
|
* The user-facing status of a file change. Drives the single-letter badge
|
|
64
66
|
* (M/A/D/R/U/?) shown next to each entry in the panel.
|
|
@@ -76,3 +78,4 @@ export interface IFileChange {
|
|
|
76
78
|
status: FileChangeStatus;
|
|
77
79
|
isBinary: boolean | null;
|
|
78
80
|
}
|
|
81
|
+
export {};
|
package/lib/highlight/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ICommandPalette } from '@jupyterlab/apputils';
|
|
2
2
|
import { CodeMirrorEditor } from '@jupyterlab/codemirror';
|
|
3
3
|
import { IDocumentManager } from '@jupyterlab/docmanager';
|
|
4
|
+
import { FileEditor } from '@jupyterlab/fileeditor';
|
|
4
5
|
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
|
|
5
6
|
import { StateEffect, StateField } from '@codemirror/state';
|
|
6
7
|
import { Decoration, EditorView } from '@codemirror/view';
|
|
@@ -12,7 +13,9 @@ const PLUGIN_ID = 'xtralab:highlight';
|
|
|
12
13
|
*/
|
|
13
14
|
const HIGHLIGHT_LINES_COMMAND = 'xtralab:highlight-lines';
|
|
14
15
|
const CLEAR_HIGHLIGHTS_COMMAND = 'xtralab:clear-highlights';
|
|
15
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* CodeMirror line-decoration class; styled in style/highlight.css.
|
|
18
|
+
*/
|
|
16
19
|
const HIGHLIGHT_LINE_CLASS = 'jp-xtralab-highlightLine';
|
|
17
20
|
/**
|
|
18
21
|
* A CodeMirror effect carrying the 1-indexed, inclusive line range to
|
|
@@ -52,15 +55,16 @@ const highlightField = StateField.define({
|
|
|
52
55
|
provide: field => EditorView.decorations.from(field)
|
|
53
56
|
});
|
|
54
57
|
/**
|
|
55
|
-
* Return the CodeMirror view backing a widget's editor, or `null` when
|
|
56
|
-
* widget is not a CodeMirror-based text editor (a notebook, a terminal,
|
|
57
|
-
* settings editor, …).
|
|
58
|
-
* depend on `@jupyterlab/fileeditor`.
|
|
58
|
+
* Return the CodeMirror view backing a widget's file editor, or `null` when
|
|
59
|
+
* the widget is not a CodeMirror-based text editor (a notebook, a terminal,
|
|
60
|
+
* the settings editor, …).
|
|
59
61
|
*/
|
|
60
62
|
function viewForWidget(widget) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
const content = widget === null || widget === void 0 ? void 0 : widget.content;
|
|
64
|
+
return content instanceof FileEditor &&
|
|
65
|
+
content.editor instanceof CodeMirrorEditor
|
|
66
|
+
? content.editor.editor
|
|
67
|
+
: null;
|
|
64
68
|
}
|
|
65
69
|
/**
|
|
66
70
|
* Coerce a JSON command argument to a positive integer line number, falling
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import agentSessionsPlugin from './agentSessions';
|
|
2
|
+
import askAgentPlugin from './askAgent';
|
|
2
3
|
import commandBarPlugin from './commandBar';
|
|
3
4
|
import fileBrowserPlugin from './fileBrowser';
|
|
4
5
|
import fileTypeIconsPlugin from './fileTypeIcons';
|
|
@@ -27,6 +28,7 @@ import walkthroughPlugin from './walkthrough';
|
|
|
27
28
|
*/
|
|
28
29
|
const plugins = [
|
|
29
30
|
agentSessionsPlugin,
|
|
31
|
+
askAgentPlugin,
|
|
30
32
|
commandBarPlugin,
|
|
31
33
|
editorBreadcrumbsPlugin,
|
|
32
34
|
editorIndentPlugin,
|
package/lib/launcher/agents.d.ts
CHANGED
|
@@ -59,7 +59,12 @@ export interface IAgentSettings {
|
|
|
59
59
|
* palette. Defaults to true.
|
|
60
60
|
*/
|
|
61
61
|
enabled?: boolean;
|
|
62
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* See `IAgent.requireAvailable`. Defaults to true for a built-in agent that
|
|
64
|
+
* still uses its shipped command, and to false once you override the
|
|
65
|
+
* `command` (a user-chosen command — often a shell alias — is trusted and
|
|
66
|
+
* always shown). Set it explicitly to force the check on or off.
|
|
67
|
+
*/
|
|
63
68
|
requireAvailable?: boolean;
|
|
64
69
|
/**
|
|
65
70
|
* See `IAgent.promptArgs`. Pass an empty array to mark the agent as
|
|
@@ -81,5 +86,10 @@ export declare function defaultAgentSettings(): IAgentSettings[];
|
|
|
81
86
|
* their built-in fields unless explicitly overridden; user-only entries are
|
|
82
87
|
* appended. `enabled: false` filters an entry out of the result entirely
|
|
83
88
|
* (so callers don't need to check the flag again).
|
|
89
|
+
*
|
|
90
|
+
* Overriding a built-in agent's `command` also turns its `requireAvailable`
|
|
91
|
+
* off, so the card survives the launcher's `which`-based availability filter
|
|
92
|
+
* even when the new command is a shell alias the server can't resolve. See the
|
|
93
|
+
* built-in branch below for the rationale.
|
|
84
94
|
*/
|
|
85
95
|
export declare function mergeAgents(overrides: IAgentSettings[]): IAgent[];
|
package/lib/launcher/agents.js
CHANGED
|
@@ -6,10 +6,9 @@ import { BUILTIN_AGENT_ICONS } from './icons';
|
|
|
6
6
|
* in `jupyter-ai-contrib/jupyter-ai-acp-client` (which is also where their
|
|
7
7
|
* icons come from), but use the bare CLI names a user would type in a
|
|
8
8
|
* terminal rather than the ACP wrapper binaries that project spawns.
|
|
9
|
-
* Antigravity (Google's agent-first IDE/CLI, `agy`)
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* out at activation time, so the wider list is harmless.
|
|
9
|
+
* Antigravity (Google's agent-first IDE/CLI, `agy`) is the Google agent.
|
|
10
|
+
* Anything not on the user's `$PATH` is filtered out at activation time, so
|
|
11
|
+
* the wider list is harmless.
|
|
13
12
|
*/
|
|
14
13
|
const DEFAULTS = [
|
|
15
14
|
{
|
|
@@ -139,6 +138,11 @@ function resolveIcon(id, iconSvg) {
|
|
|
139
138
|
* their built-in fields unless explicitly overridden; user-only entries are
|
|
140
139
|
* appended. `enabled: false` filters an entry out of the result entirely
|
|
141
140
|
* (so callers don't need to check the flag again).
|
|
141
|
+
*
|
|
142
|
+
* Overriding a built-in agent's `command` also turns its `requireAvailable`
|
|
143
|
+
* off, so the card survives the launcher's `which`-based availability filter
|
|
144
|
+
* even when the new command is a shell alias the server can't resolve. See the
|
|
145
|
+
* built-in branch below for the rationale.
|
|
142
146
|
*/
|
|
143
147
|
export function mergeAgents(overrides) {
|
|
144
148
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
@@ -154,16 +158,30 @@ export function mergeAgents(overrides) {
|
|
|
154
158
|
if (override.enabled === false) {
|
|
155
159
|
continue;
|
|
156
160
|
}
|
|
161
|
+
const command = (_a = override.command) !== null && _a !== void 0 ? _a : base.command;
|
|
157
162
|
merged.push({
|
|
158
163
|
id: base.id,
|
|
159
|
-
label: (
|
|
160
|
-
caption: (
|
|
161
|
-
command
|
|
164
|
+
label: (_b = override.label) !== null && _b !== void 0 ? _b : base.label,
|
|
165
|
+
caption: (_c = override.caption) !== null && _c !== void 0 ? _c : base.caption,
|
|
166
|
+
command,
|
|
162
167
|
icon: override.iconSvg
|
|
163
168
|
? resolveIcon(base.id, override.iconSvg)
|
|
164
169
|
: base.icon,
|
|
165
170
|
rank: (_d = override.rank) !== null && _d !== void 0 ? _d : base.rank,
|
|
166
|
-
|
|
171
|
+
// The availability filter exists to prune xtralab's *built-in* command
|
|
172
|
+
// from the launcher when it isn't installed. Once the user points the
|
|
173
|
+
// agent at their own command — e.g. the `ccm` alias wrapping `claude
|
|
174
|
+
// --effort=max …` — the server's `shutil.which` probe can't see it
|
|
175
|
+
// (aliases and shell functions only exist inside an interactive shell),
|
|
176
|
+
// so keeping the check on would wrongly hide the card. We therefore only
|
|
177
|
+
// require availability while the command is still xtralab's default; a
|
|
178
|
+
// user-chosen command is trusted and always shown. An explicit
|
|
179
|
+
// `requireAvailable` still applies to the unchanged default command, so a
|
|
180
|
+
// user can alias `claude` itself and set `requireAvailable: false` (or
|
|
181
|
+
// force the check back on).
|
|
182
|
+
requireAvailable: command === base.command
|
|
183
|
+
? ((_e = override.requireAvailable) !== null && _e !== void 0 ? _e : base.requireAvailable)
|
|
184
|
+
: false,
|
|
167
185
|
// `null` is the explicit way to opt out of an agent's default prompt
|
|
168
186
|
// support; an absent key keeps the default. `undefined` from `??` is
|
|
169
187
|
// pruned below.
|
|
@@ -40,9 +40,13 @@ export declare function registerAgentCommands(app: JupyterFrontEnd, agents: IAge
|
|
|
40
40
|
*/
|
|
41
41
|
export declare function launchInTerminal(commands: CommandRegistry, options: {
|
|
42
42
|
cwd?: string;
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* The literal command line typed into the fresh terminal.
|
|
45
|
+
*/
|
|
44
46
|
invocation: string;
|
|
45
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Tab/title label applied once the command is sent.
|
|
49
|
+
*/
|
|
46
50
|
label: string;
|
|
47
51
|
onSession?: (sessionName: string) => void;
|
|
48
52
|
}): Promise<MainAreaWidget<ITerminal.ITerminal>>;
|