@elyracode/coding-agent 0.9.26 → 0.9.28
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/CHANGELOG.md +8 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/doctor-cli.d.ts.map +1 -1
- package/dist/cli/doctor-cli.js +22 -0
- package/dist/cli/doctor-cli.js.map +1 -1
- package/dist/core/resource-inspector.d.ts +49 -0
- package/dist/core/resource-inspector.d.ts.map +1 -0
- package/dist/core/resource-inspector.js +175 -0
- package/dist/core/resource-inspector.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/package-browser.d.ts +12 -5
- package/dist/modes/interactive/components/package-browser.d.ts.map +1 -1
- package/dist/modes/interactive/components/package-browser.js +50 -30
- package/dist/modes/interactive/components/package-browser.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +31 -17
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/usage.md +25 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +5 -5
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Package browser: a clean, multi-select list for browsing and
|
|
3
|
-
* Elyra extensions.
|
|
4
|
-
*
|
|
2
|
+
* Package browser: a clean, multi-select list for browsing, installing, and
|
|
3
|
+
* uninstalling Elyra extensions. One mental model: space toggles the change
|
|
4
|
+
* you want — [x] to install a package you don't have, [-] to remove one you
|
|
5
|
+
* do — and enter applies all marked changes. Windowed scrolling, installed
|
|
6
|
+
* markers, and a clear call to run /reload afterwards.
|
|
5
7
|
*/
|
|
6
8
|
import { Container } from "@elyracode/tui";
|
|
7
9
|
export interface PackageBrowserItem {
|
|
@@ -14,15 +16,20 @@ export interface PackageBrowserItem {
|
|
|
14
16
|
/** Whether the package is already installed (shown as a ✓ marker). */
|
|
15
17
|
installed?: boolean;
|
|
16
18
|
}
|
|
19
|
+
export interface PackageBrowserActions {
|
|
20
|
+
/** Package names to install. */
|
|
21
|
+
install: string[];
|
|
22
|
+
/** Package names to uninstall. */
|
|
23
|
+
remove: string[];
|
|
24
|
+
}
|
|
17
25
|
export declare class PackageBrowserComponent extends Container {
|
|
18
26
|
private readonly items;
|
|
19
27
|
private readonly onConfirm;
|
|
20
28
|
private readonly onCancel;
|
|
21
29
|
private readonly list;
|
|
22
30
|
private readonly titleText;
|
|
23
|
-
constructor(items: PackageBrowserItem[], onConfirm: (
|
|
31
|
+
constructor(items: PackageBrowserItem[], onConfirm: (actions: PackageBrowserActions) => void, onCancel: () => void);
|
|
24
32
|
private updateTitle;
|
|
25
33
|
handleInput(keyData: string): void;
|
|
26
|
-
private currentValue;
|
|
27
34
|
}
|
|
28
35
|
//# sourceMappingURL=package-browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-browser.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/package-browser.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"package-browser.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/package-browser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,SAAS,EAA+D,MAAM,gBAAgB,CAAC;AAKxG,MAAM,WAAW,kBAAkB;IAClC,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAsFD,MAAM,WAAW,qBAAqB;IACrC,gCAAgC;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kCAAkC;IAClC,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,qBAAa,uBAAwB,SAAQ,SAAS;IAKpD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAN1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAO;IAEjC,YACkB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,SAAS,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,EACnD,QAAQ,EAAE,MAAM,IAAI,EAuCrC;IAED,OAAO,CAAC,WAAW;IAYnB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAqCjC;CACD"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Package browser: a clean, multi-select list for browsing and
|
|
3
|
-
* Elyra extensions.
|
|
4
|
-
*
|
|
2
|
+
* Package browser: a clean, multi-select list for browsing, installing, and
|
|
3
|
+
* uninstalling Elyra extensions. One mental model: space toggles the change
|
|
4
|
+
* you want — [x] to install a package you don't have, [-] to remove one you
|
|
5
|
+
* do — and enter applies all marked changes. Windowed scrolling, installed
|
|
6
|
+
* markers, and a clear call to run /reload afterwards.
|
|
5
7
|
*/
|
|
6
8
|
import { Container, getKeybindings, Spacer, Text, truncateToWidth, visibleWidth } from "@elyracode/tui";
|
|
7
9
|
import { theme } from "../theme/theme.js";
|
|
@@ -20,7 +22,10 @@ class PackageList {
|
|
|
20
22
|
constructor(items) {
|
|
21
23
|
this.items = items;
|
|
22
24
|
this.selectedIndex = 0;
|
|
25
|
+
/** Marked for install (non-installed items). */
|
|
23
26
|
this.checked = new Set();
|
|
27
|
+
/** Marked for uninstall (installed items). */
|
|
28
|
+
this.toRemove = new Set();
|
|
24
29
|
}
|
|
25
30
|
invalidate() { }
|
|
26
31
|
nameColumnWidth() {
|
|
@@ -39,29 +44,37 @@ class PackageList {
|
|
|
39
44
|
const item = this.items[i];
|
|
40
45
|
if (!item)
|
|
41
46
|
continue;
|
|
42
|
-
lines.push(this.renderRow(item, i === this.selectedIndex,
|
|
47
|
+
lines.push(this.renderRow(item, i === this.selectedIndex, width, nameColumn));
|
|
43
48
|
}
|
|
44
49
|
if (start > 0 || end < this.items.length) {
|
|
45
50
|
lines.push(theme.fg("muted", ` (${this.selectedIndex + 1}/${this.items.length})`));
|
|
46
51
|
}
|
|
47
52
|
return lines;
|
|
48
53
|
}
|
|
49
|
-
renderRow(item, isCursor,
|
|
54
|
+
renderRow(item, isCursor, width, nameColumn) {
|
|
55
|
+
const isChecked = this.checked.has(item.value);
|
|
56
|
+
const isMarkedRemove = this.toRemove.has(item.value);
|
|
50
57
|
const cursor = isCursor ? "→ " : " ";
|
|
51
|
-
const box = isChecked ? "[x] " : "[ ] ";
|
|
58
|
+
const box = isMarkedRemove ? "[-] " : isChecked ? "[x] " : "[ ] ";
|
|
52
59
|
const mark = item.installed ? "✓ " : " ";
|
|
53
60
|
const name = truncateToWidth(item.name, nameColumn, "…", true);
|
|
54
61
|
const used = visibleWidth(cursor) + visibleWidth(box) + visibleWidth(mark) + nameColumn + NAME_GAP;
|
|
55
62
|
const descWidth = width - used - 1;
|
|
56
63
|
const description = descWidth > 6 ? truncateToWidth(item.description, descWidth, "…") : "";
|
|
57
64
|
const cursorPart = isCursor ? theme.fg("accent", cursor) : cursor;
|
|
58
|
-
const boxPart =
|
|
65
|
+
const boxPart = isMarkedRemove
|
|
66
|
+
? theme.fg("error", box)
|
|
67
|
+
: isChecked
|
|
68
|
+
? theme.fg("success", box)
|
|
69
|
+
: theme.fg("dim", box);
|
|
59
70
|
const markPart = item.installed ? theme.fg("success", mark) : mark;
|
|
60
71
|
const namePart = isCursor
|
|
61
72
|
? theme.fg("accent", name)
|
|
62
|
-
:
|
|
63
|
-
? theme.fg("
|
|
64
|
-
:
|
|
73
|
+
: isMarkedRemove
|
|
74
|
+
? theme.fg("error", name)
|
|
75
|
+
: item.installed
|
|
76
|
+
? theme.fg("muted", name)
|
|
77
|
+
: theme.fg("text", name);
|
|
65
78
|
const descPart = description ? theme.fg("muted", `${" ".repeat(NAME_GAP)}${description}`) : "";
|
|
66
79
|
return `${cursorPart}${boxPart}${markPart}${namePart}${descPart}`;
|
|
67
80
|
}
|
|
@@ -82,15 +95,15 @@ export class PackageBrowserComponent extends Container {
|
|
|
82
95
|
this.addChild(new Spacer(1));
|
|
83
96
|
this.addChild(new Text(rawKeyHint("↑↓", "navigate") +
|
|
84
97
|
" " +
|
|
85
|
-
keyHint("app.packages.toggle", "
|
|
98
|
+
keyHint("app.packages.toggle", "mark install/remove") +
|
|
86
99
|
" " +
|
|
87
|
-
keyHint("app.packages.install", "
|
|
100
|
+
keyHint("app.packages.install", "apply") +
|
|
88
101
|
" " +
|
|
89
102
|
keyHint("tui.select.cancel", "cancel"), 1, 0));
|
|
90
103
|
this.addChild(new Spacer(1));
|
|
91
104
|
const hasInstalled = items.some((item) => item.installed);
|
|
92
105
|
const legend = hasInstalled
|
|
93
|
-
? `${theme.fg("success", "\u2713")}${theme.fg("dim", " =
|
|
106
|
+
? `${theme.fg("success", "\u2713")}${theme.fg("dim", " = installed \u00b7 space marks ")}${theme.fg("success", "[x]")}${theme.fg("dim", " install / ")}${theme.fg("error", "[-]")}${theme.fg("dim", " remove \u00b7 changes activate after /reload.")}`
|
|
94
107
|
: theme.fg("dim", "Installed extensions activate after you run /reload.");
|
|
95
108
|
this.addChild(new Text(legend, 1, 0));
|
|
96
109
|
this.addChild(new Spacer(1));
|
|
@@ -98,15 +111,18 @@ export class PackageBrowserComponent extends Container {
|
|
|
98
111
|
this.updateTitle();
|
|
99
112
|
}
|
|
100
113
|
updateTitle() {
|
|
101
|
-
const
|
|
114
|
+
const installCount = this.list.checked.size;
|
|
115
|
+
const removeCount = this.list.toRemove.size;
|
|
102
116
|
const installedCount = this.items.filter((item) => item.installed).length;
|
|
103
117
|
const parts = [];
|
|
104
|
-
if (
|
|
105
|
-
parts.push(`${
|
|
106
|
-
if (
|
|
118
|
+
if (installCount > 0)
|
|
119
|
+
parts.push(`${installCount} to install`);
|
|
120
|
+
if (removeCount > 0)
|
|
121
|
+
parts.push(`${removeCount} to remove`);
|
|
122
|
+
if (parts.length === 0 && installedCount > 0)
|
|
107
123
|
parts.push(`${installedCount} installed`);
|
|
108
124
|
const suffix = parts.length > 0 ? theme.fg("muted", ` (${parts.join(", ")})`) : "";
|
|
109
|
-
this.titleText.setText(theme.fg("accent", theme.bold("
|
|
125
|
+
this.titleText.setText(theme.fg("accent", theme.bold("Extensions")) + suffix);
|
|
110
126
|
}
|
|
111
127
|
handleInput(keyData) {
|
|
112
128
|
const kb = getKeybindings();
|
|
@@ -125,29 +141,33 @@ export class PackageBrowserComponent extends Container {
|
|
|
125
141
|
else if (kb.matches(keyData, "app.packages.toggle")) {
|
|
126
142
|
const item = this.items[this.list.selectedIndex];
|
|
127
143
|
if (item) {
|
|
128
|
-
|
|
129
|
-
|
|
144
|
+
// One mental model: space toggles the change you want. Installed
|
|
145
|
+
// packages toggle a removal mark; others toggle an install mark.
|
|
146
|
+
const set = item.installed ? this.list.toRemove : this.list.checked;
|
|
147
|
+
if (set.has(item.value)) {
|
|
148
|
+
set.delete(item.value);
|
|
130
149
|
}
|
|
131
150
|
else {
|
|
132
|
-
|
|
151
|
+
set.add(item.value);
|
|
133
152
|
}
|
|
134
153
|
this.updateTitle();
|
|
135
154
|
}
|
|
136
155
|
}
|
|
137
156
|
else if (kb.matches(keyData, "app.packages.install")) {
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
this.
|
|
157
|
+
const install = this.items.filter((item) => this.list.checked.has(item.value)).map((item) => item.value);
|
|
158
|
+
const remove = this.items.filter((item) => this.list.toRemove.has(item.value)).map((item) => item.value);
|
|
159
|
+
if (install.length === 0 && remove.length === 0) {
|
|
160
|
+
// Nothing marked: enter installs (or reinstalls) the highlighted row.
|
|
161
|
+
const current = this.items[this.list.selectedIndex];
|
|
162
|
+
if (current)
|
|
163
|
+
this.onConfirm({ install: [current.value], remove: [] });
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
this.onConfirm({ install, remove });
|
|
143
167
|
}
|
|
144
168
|
else if (kb.matches(keyData, "tui.select.cancel")) {
|
|
145
169
|
this.onCancel();
|
|
146
170
|
}
|
|
147
171
|
}
|
|
148
|
-
currentValue() {
|
|
149
|
-
const item = this.items[this.list.selectedIndex];
|
|
150
|
-
return item ? [item.value] : [];
|
|
151
|
-
}
|
|
152
172
|
}
|
|
153
173
|
//# sourceMappingURL=package-browser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-browser.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/package-browser.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Package browser: a clean, multi-select list for browsing and installing\n * Elyra extensions. Supports windowed scrolling, checkbox selection of one or\n * more packages, and a clear call to run /reload after installing.\n */\n\nimport type { Component } from \"@elyracode/tui\";\nimport { Container, getKeybindings, Spacer, Text, truncateToWidth, visibleWidth } from \"@elyracode/tui\";\nimport { theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { keyHint, rawKeyHint } from \"./keybinding-hints.js\";\n\nexport interface PackageBrowserItem {\n\t/** Full package name, e.g. \"@elyracode/stack-tall\". */\n\tvalue: string;\n\t/** Short display name, e.g. \"stack-tall\". */\n\tname: string;\n\t/** One-line description. */\n\tdescription: string;\n\t/** Whether the package is already installed (shown as a ✓ marker). */\n\tinstalled?: boolean;\n}\n\nconst MAX_VISIBLE = 12;\nconst MIN_NAME_COLUMN = 14;\nconst MAX_NAME_COLUMN = 28;\nconst NAME_GAP = 2;\n\n/**\n * Inner scrollable, windowed list with checkbox multi-select.\n * The parent PackageBrowserComponent owns key handling and state mutation;\n * this component is purely presentational.\n */\nclass PackageList implements Component {\n\tselectedIndex = 0;\n\treadonly checked = new Set<string>();\n\n\tconstructor(private readonly items: PackageBrowserItem[]) {}\n\n\tinvalidate(): void {}\n\n\tprivate nameColumnWidth(): number {\n\t\tconst widest = this.items.reduce((max, item) => Math.max(max, visibleWidth(item.name)), 0);\n\t\treturn Math.max(MIN_NAME_COLUMN, Math.min(MAX_NAME_COLUMN, widest));\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.items.length === 0) {\n\t\t\treturn [theme.fg(\"muted\", \" No extensions available\")];\n\t\t}\n\n\t\tconst nameColumn = this.nameColumnWidth();\n\t\tconst start = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(MAX_VISIBLE / 2), this.items.length - MAX_VISIBLE),\n\t\t);\n\t\tconst end = Math.min(start + MAX_VISIBLE, this.items.length);\n\n\t\tconst lines: string[] = [];\n\t\tfor (let i = start; i < end; i++) {\n\t\t\tconst item = this.items[i];\n\t\t\tif (!item) continue;\n\t\t\tlines.push(this.renderRow(item, i === this.selectedIndex, this.checked.has(item.value), width, nameColumn));\n\t\t}\n\n\t\tif (start > 0 || end < this.items.length) {\n\t\t\tlines.push(theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.items.length})`));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\tprivate renderRow(\n\t\titem: PackageBrowserItem,\n\t\tisCursor: boolean,\n\t\tisChecked: boolean,\n\t\twidth: number,\n\t\tnameColumn: number,\n\t): string {\n\t\tconst cursor = isCursor ? \"→ \" : \" \";\n\t\tconst box = isChecked ? \"[x] \" : \"[ ] \";\n\t\tconst mark = item.installed ? \"✓ \" : \" \";\n\t\tconst name = truncateToWidth(item.name, nameColumn, \"…\", true);\n\n\t\tconst used = visibleWidth(cursor) + visibleWidth(box) + visibleWidth(mark) + nameColumn + NAME_GAP;\n\t\tconst descWidth = width - used - 1;\n\t\tconst description = descWidth > 6 ? truncateToWidth(item.description, descWidth, \"…\") : \"\";\n\n\t\tconst cursorPart = isCursor ? theme.fg(\"accent\", cursor) : cursor;\n\t\tconst boxPart = isChecked ? theme.fg(\"success\", box) : theme.fg(\"dim\", box);\n\t\tconst markPart = item.installed ? theme.fg(\"success\", mark) : mark;\n\t\tconst namePart = isCursor\n\t\t\t? theme.fg(\"accent\", name)\n\t\t\t: item.installed\n\t\t\t\t? theme.fg(\"muted\", name)\n\t\t\t\t: theme.fg(\"text\", name);\n\t\tconst descPart = description ? theme.fg(\"muted\", `${\" \".repeat(NAME_GAP)}${description}`) : \"\";\n\n\t\treturn `${cursorPart}${boxPart}${markPart}${namePart}${descPart}`;\n\t}\n}\n\nexport class PackageBrowserComponent extends Container {\n\tprivate readonly list: PackageList;\n\tprivate readonly titleText: Text;\n\n\tconstructor(\n\t\tprivate readonly items: PackageBrowserItem[],\n\t\tprivate readonly onConfirm: (values: string[]) => void,\n\t\tprivate readonly onCancel: () => void,\n\t) {\n\t\tsuper();\n\n\t\tthis.list = new PackageList(items);\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.titleText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.addChild(this.list);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.addChild(\n\t\t\tnew Text(\n\t\t\t\trawKeyHint(\"↑↓\", \"navigate\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"app.packages.toggle\", \"select\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"app.packages.install\", \"install\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\"),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new Spacer(1));\n\t\tconst hasInstalled = items.some((item) => item.installed);\n\t\tconst legend = hasInstalled\n\t\t\t? `${theme.fg(\"success\", \"\\u2713\")}${theme.fg(\"dim\", \" = already installed \\u00b7 installed extensions activate after you run /reload.\")}`\n\t\t\t: theme.fg(\"dim\", \"Installed extensions activate after you run /reload.\");\n\t\tthis.addChild(new Text(legend, 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\tthis.updateTitle();\n\t}\n\n\tprivate updateTitle(): void {\n\t\tconst count = this.list.checked.size;\n\t\tconst installedCount = this.items.filter((item) => item.installed).length;\n\t\tconst parts: string[] = [];\n\t\tif (count > 0) parts.push(`${count} selected`);\n\t\tif (installedCount > 0) parts.push(`${installedCount} installed`);\n\t\tconst suffix = parts.length > 0 ? theme.fg(\"muted\", ` (${parts.join(\", \")})`) : \"\";\n\t\tthis.titleText.setText(theme.fg(\"accent\", theme.bold(\"Install Extensions\")) + suffix);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.list.selectedIndex = this.list.selectedIndex === 0 ? this.items.length - 1 : this.list.selectedIndex - 1;\n\t\t} else if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.list.selectedIndex = this.list.selectedIndex === this.items.length - 1 ? 0 : this.list.selectedIndex + 1;\n\t\t} else if (kb.matches(keyData, \"tui.select.pageUp\")) {\n\t\t\tthis.list.selectedIndex = Math.max(0, this.list.selectedIndex - MAX_VISIBLE);\n\t\t} else if (kb.matches(keyData, \"tui.select.pageDown\")) {\n\t\t\tthis.list.selectedIndex = Math.min(this.items.length - 1, this.list.selectedIndex + MAX_VISIBLE);\n\t\t} else if (kb.matches(keyData, \"app.packages.toggle\")) {\n\t\t\tconst item = this.items[this.list.selectedIndex];\n\t\t\tif (item) {\n\t\t\t\tif (this.list.checked.has(item.value)) {\n\t\t\t\t\tthis.list.checked.delete(item.value);\n\t\t\t\t} else {\n\t\t\t\t\tthis.list.checked.add(item.value);\n\t\t\t\t}\n\t\t\t\tthis.updateTitle();\n\t\t\t}\n\t\t} else if (kb.matches(keyData, \"app.packages.install\")) {\n\t\t\tconst selected =\n\t\t\t\tthis.list.checked.size > 0\n\t\t\t\t\t? this.items.filter((item) => this.list.checked.has(item.value)).map((item) => item.value)\n\t\t\t\t\t: this.currentValue();\n\t\t\tif (selected.length > 0) this.onConfirm(selected);\n\t\t} else if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancel();\n\t\t}\n\t}\n\n\tprivate currentValue(): string[] {\n\t\tconst item = this.items[this.list.selectedIndex];\n\t\treturn item ? [item.value] : [];\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"package-browser.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/package-browser.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Package browser: a clean, multi-select list for browsing, installing, and\n * uninstalling Elyra extensions. One mental model: space toggles the change\n * you want — [x] to install a package you don't have, [-] to remove one you\n * do — and enter applies all marked changes. Windowed scrolling, installed\n * markers, and a clear call to run /reload afterwards.\n */\n\nimport type { Component } from \"@elyracode/tui\";\nimport { Container, getKeybindings, Spacer, Text, truncateToWidth, visibleWidth } from \"@elyracode/tui\";\nimport { theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { keyHint, rawKeyHint } from \"./keybinding-hints.js\";\n\nexport interface PackageBrowserItem {\n\t/** Full package name, e.g. \"@elyracode/stack-tall\". */\n\tvalue: string;\n\t/** Short display name, e.g. \"stack-tall\". */\n\tname: string;\n\t/** One-line description. */\n\tdescription: string;\n\t/** Whether the package is already installed (shown as a ✓ marker). */\n\tinstalled?: boolean;\n}\n\nconst MAX_VISIBLE = 12;\nconst MIN_NAME_COLUMN = 14;\nconst MAX_NAME_COLUMN = 28;\nconst NAME_GAP = 2;\n\n/**\n * Inner scrollable, windowed list with checkbox multi-select.\n * The parent PackageBrowserComponent owns key handling and state mutation;\n * this component is purely presentational.\n */\nclass PackageList implements Component {\n\tselectedIndex = 0;\n\t/** Marked for install (non-installed items). */\n\treadonly checked = new Set<string>();\n\t/** Marked for uninstall (installed items). */\n\treadonly toRemove = new Set<string>();\n\n\tconstructor(private readonly items: PackageBrowserItem[]) {}\n\n\tinvalidate(): void {}\n\n\tprivate nameColumnWidth(): number {\n\t\tconst widest = this.items.reduce((max, item) => Math.max(max, visibleWidth(item.name)), 0);\n\t\treturn Math.max(MIN_NAME_COLUMN, Math.min(MAX_NAME_COLUMN, widest));\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.items.length === 0) {\n\t\t\treturn [theme.fg(\"muted\", \" No extensions available\")];\n\t\t}\n\n\t\tconst nameColumn = this.nameColumnWidth();\n\t\tconst start = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(MAX_VISIBLE / 2), this.items.length - MAX_VISIBLE),\n\t\t);\n\t\tconst end = Math.min(start + MAX_VISIBLE, this.items.length);\n\n\t\tconst lines: string[] = [];\n\t\tfor (let i = start; i < end; i++) {\n\t\t\tconst item = this.items[i];\n\t\t\tif (!item) continue;\n\t\t\tlines.push(this.renderRow(item, i === this.selectedIndex, width, nameColumn));\n\t\t}\n\n\t\tif (start > 0 || end < this.items.length) {\n\t\t\tlines.push(theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.items.length})`));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\tprivate renderRow(item: PackageBrowserItem, isCursor: boolean, width: number, nameColumn: number): string {\n\t\tconst isChecked = this.checked.has(item.value);\n\t\tconst isMarkedRemove = this.toRemove.has(item.value);\n\t\tconst cursor = isCursor ? \"→ \" : \" \";\n\t\tconst box = isMarkedRemove ? \"[-] \" : isChecked ? \"[x] \" : \"[ ] \";\n\t\tconst mark = item.installed ? \"✓ \" : \" \";\n\t\tconst name = truncateToWidth(item.name, nameColumn, \"…\", true);\n\n\t\tconst used = visibleWidth(cursor) + visibleWidth(box) + visibleWidth(mark) + nameColumn + NAME_GAP;\n\t\tconst descWidth = width - used - 1;\n\t\tconst description = descWidth > 6 ? truncateToWidth(item.description, descWidth, \"…\") : \"\";\n\n\t\tconst cursorPart = isCursor ? theme.fg(\"accent\", cursor) : cursor;\n\t\tconst boxPart = isMarkedRemove\n\t\t\t? theme.fg(\"error\", box)\n\t\t\t: isChecked\n\t\t\t\t? theme.fg(\"success\", box)\n\t\t\t\t: theme.fg(\"dim\", box);\n\t\tconst markPart = item.installed ? theme.fg(\"success\", mark) : mark;\n\t\tconst namePart = isCursor\n\t\t\t? theme.fg(\"accent\", name)\n\t\t\t: isMarkedRemove\n\t\t\t\t? theme.fg(\"error\", name)\n\t\t\t\t: item.installed\n\t\t\t\t\t? theme.fg(\"muted\", name)\n\t\t\t\t\t: theme.fg(\"text\", name);\n\t\tconst descPart = description ? theme.fg(\"muted\", `${\" \".repeat(NAME_GAP)}${description}`) : \"\";\n\n\t\treturn `${cursorPart}${boxPart}${markPart}${namePart}${descPart}`;\n\t}\n}\n\nexport interface PackageBrowserActions {\n\t/** Package names to install. */\n\tinstall: string[];\n\t/** Package names to uninstall. */\n\tremove: string[];\n}\n\nexport class PackageBrowserComponent extends Container {\n\tprivate readonly list: PackageList;\n\tprivate readonly titleText: Text;\n\n\tconstructor(\n\t\tprivate readonly items: PackageBrowserItem[],\n\t\tprivate readonly onConfirm: (actions: PackageBrowserActions) => void,\n\t\tprivate readonly onCancel: () => void,\n\t) {\n\t\tsuper();\n\n\t\tthis.list = new PackageList(items);\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.titleText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.addChild(this.list);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.addChild(\n\t\t\tnew Text(\n\t\t\t\trawKeyHint(\"↑↓\", \"navigate\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"app.packages.toggle\", \"mark install/remove\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"app.packages.install\", \"apply\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\"),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new Spacer(1));\n\t\tconst hasInstalled = items.some((item) => item.installed);\n\t\tconst legend = hasInstalled\n\t\t\t? `${theme.fg(\"success\", \"\\u2713\")}${theme.fg(\"dim\", \" = installed \\u00b7 space marks \")}${theme.fg(\"success\", \"[x]\")}${theme.fg(\"dim\", \" install / \")}${theme.fg(\"error\", \"[-]\")}${theme.fg(\"dim\", \" remove \\u00b7 changes activate after /reload.\")}`\n\t\t\t: theme.fg(\"dim\", \"Installed extensions activate after you run /reload.\");\n\t\tthis.addChild(new Text(legend, 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\tthis.updateTitle();\n\t}\n\n\tprivate updateTitle(): void {\n\t\tconst installCount = this.list.checked.size;\n\t\tconst removeCount = this.list.toRemove.size;\n\t\tconst installedCount = this.items.filter((item) => item.installed).length;\n\t\tconst parts: string[] = [];\n\t\tif (installCount > 0) parts.push(`${installCount} to install`);\n\t\tif (removeCount > 0) parts.push(`${removeCount} to remove`);\n\t\tif (parts.length === 0 && installedCount > 0) parts.push(`${installedCount} installed`);\n\t\tconst suffix = parts.length > 0 ? theme.fg(\"muted\", ` (${parts.join(\", \")})`) : \"\";\n\t\tthis.titleText.setText(theme.fg(\"accent\", theme.bold(\"Extensions\")) + suffix);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.list.selectedIndex = this.list.selectedIndex === 0 ? this.items.length - 1 : this.list.selectedIndex - 1;\n\t\t} else if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.list.selectedIndex = this.list.selectedIndex === this.items.length - 1 ? 0 : this.list.selectedIndex + 1;\n\t\t} else if (kb.matches(keyData, \"tui.select.pageUp\")) {\n\t\t\tthis.list.selectedIndex = Math.max(0, this.list.selectedIndex - MAX_VISIBLE);\n\t\t} else if (kb.matches(keyData, \"tui.select.pageDown\")) {\n\t\t\tthis.list.selectedIndex = Math.min(this.items.length - 1, this.list.selectedIndex + MAX_VISIBLE);\n\t\t} else if (kb.matches(keyData, \"app.packages.toggle\")) {\n\t\t\tconst item = this.items[this.list.selectedIndex];\n\t\t\tif (item) {\n\t\t\t\t// One mental model: space toggles the change you want. Installed\n\t\t\t\t// packages toggle a removal mark; others toggle an install mark.\n\t\t\t\tconst set = item.installed ? this.list.toRemove : this.list.checked;\n\t\t\t\tif (set.has(item.value)) {\n\t\t\t\t\tset.delete(item.value);\n\t\t\t\t} else {\n\t\t\t\t\tset.add(item.value);\n\t\t\t\t}\n\t\t\t\tthis.updateTitle();\n\t\t\t}\n\t\t} else if (kb.matches(keyData, \"app.packages.install\")) {\n\t\t\tconst install = this.items.filter((item) => this.list.checked.has(item.value)).map((item) => item.value);\n\t\t\tconst remove = this.items.filter((item) => this.list.toRemove.has(item.value)).map((item) => item.value);\n\t\t\tif (install.length === 0 && remove.length === 0) {\n\t\t\t\t// Nothing marked: enter installs (or reinstalls) the highlighted row.\n\t\t\t\tconst current = this.items[this.list.selectedIndex];\n\t\t\t\tif (current) this.onConfirm({ install: [current.value], remove: [] });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.onConfirm({ install, remove });\n\t\t} else if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancel();\n\t\t}\n\t}\n}\n"]}
|
|
@@ -387,7 +387,7 @@ export declare class InteractiveMode {
|
|
|
387
387
|
private showOAuthLoginSelect;
|
|
388
388
|
private showLoginDialog;
|
|
389
389
|
private handlePackageBrowser;
|
|
390
|
-
private
|
|
390
|
+
private applyPackageChanges;
|
|
391
391
|
private handleReloadCommand;
|
|
392
392
|
private handleExportCommand;
|
|
393
393
|
private getPathCommandArgument;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-mode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAKN,KAAK,YAAY,EAKjB,MAAM,eAAe,CAAC;AAgDvB,OAAO,EAAE,KAAK,mBAAmB,EAAkC,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"interactive-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-mode.ts"],"names":[],"mappings":"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"}
|
|
@@ -56,7 +56,7 @@ import { formatKeyText, keyDisplayText, keyHint, keyText, rawKeyHint } from "./c
|
|
|
56
56
|
import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
57
57
|
import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
58
58
|
import { OAuthSelectorComponent } from "./components/oauth-selector.js";
|
|
59
|
-
import { PackageBrowserComponent } from "./components/package-browser.js";
|
|
59
|
+
import { PackageBrowserComponent, } from "./components/package-browser.js";
|
|
60
60
|
import { RewindSelectorComponent } from "./components/rewind-selector.js";
|
|
61
61
|
import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
|
|
62
62
|
import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
@@ -5600,21 +5600,23 @@ export class InteractiveMode {
|
|
|
5600
5600
|
mk("semantic-index", "Semantic code search: find code by meaning via local embeddings"),
|
|
5601
5601
|
];
|
|
5602
5602
|
this.showSelector((done) => {
|
|
5603
|
-
const browser = new PackageBrowserComponent(items, (
|
|
5603
|
+
const browser = new PackageBrowserComponent(items, (actions) => {
|
|
5604
5604
|
done();
|
|
5605
|
-
void this.
|
|
5605
|
+
void this.applyPackageChanges(actions);
|
|
5606
5606
|
}, () => done());
|
|
5607
5607
|
return { component: browser, focus: browser };
|
|
5608
5608
|
});
|
|
5609
5609
|
}
|
|
5610
|
-
async
|
|
5610
|
+
async applyPackageChanges(actions) {
|
|
5611
5611
|
const installed = [];
|
|
5612
|
+
const removed = [];
|
|
5612
5613
|
const failed = [];
|
|
5613
5614
|
let cancelled = false;
|
|
5615
|
+
const total = actions.install.length + actions.remove.length;
|
|
5614
5616
|
// npm downloads take a while; a blocking install with no visible feedback
|
|
5615
5617
|
// looks like a hang. Replace the editor with a live spinner that shows
|
|
5616
|
-
// per-package progress, and let Escape cancel the remaining
|
|
5617
|
-
const loader = new BorderedLoader(this.ui, theme, "
|
|
5618
|
+
// per-package progress, and let Escape cancel the remaining work.
|
|
5619
|
+
const loader = new BorderedLoader(this.ui, theme, "Updating extensions...");
|
|
5618
5620
|
this.editorContainer.clear();
|
|
5619
5621
|
this.editorContainer.addChild(loader);
|
|
5620
5622
|
this.ui.setFocus(loader);
|
|
@@ -5629,17 +5631,24 @@ export class InteractiveMode {
|
|
|
5629
5631
|
loader.onAbort = () => {
|
|
5630
5632
|
cancelled = true;
|
|
5631
5633
|
};
|
|
5632
|
-
|
|
5634
|
+
const queue = [
|
|
5635
|
+
...actions.install.map((pkgName) => ({ pkgName, action: "install" })),
|
|
5636
|
+
...actions.remove.map((pkgName) => ({ pkgName, action: "remove" })),
|
|
5637
|
+
];
|
|
5638
|
+
for (let i = 0; i < queue.length; i++) {
|
|
5633
5639
|
if (cancelled || loader.signal.aborted) {
|
|
5634
5640
|
cancelled = true;
|
|
5635
5641
|
break;
|
|
5636
5642
|
}
|
|
5637
|
-
const
|
|
5638
|
-
|
|
5643
|
+
const entry = queue[i];
|
|
5644
|
+
if (!entry)
|
|
5645
|
+
continue;
|
|
5646
|
+
const { pkgName, action } = entry;
|
|
5647
|
+
loader.setMessage(`${action === "install" ? "Installing" : "Removing"} ${pkgName} (${i + 1}/${total})...`);
|
|
5639
5648
|
this.ui.requestRender();
|
|
5640
5649
|
try {
|
|
5641
|
-
const result = await execCommand("elyra", [
|
|
5642
|
-
timeout: 120_000,
|
|
5650
|
+
const result = await execCommand("elyra", [action, `npm:${pkgName}`], process.cwd(), {
|
|
5651
|
+
timeout: action === "install" ? 120_000 : 30_000,
|
|
5643
5652
|
signal: loader.signal,
|
|
5644
5653
|
});
|
|
5645
5654
|
if (loader.signal.aborted) {
|
|
@@ -5647,7 +5656,7 @@ export class InteractiveMode {
|
|
|
5647
5656
|
break;
|
|
5648
5657
|
}
|
|
5649
5658
|
if (result.code === 0) {
|
|
5650
|
-
installed.push(pkgName);
|
|
5659
|
+
(action === "install" ? installed : removed).push(pkgName);
|
|
5651
5660
|
}
|
|
5652
5661
|
else {
|
|
5653
5662
|
failed.push(pkgName);
|
|
@@ -5658,15 +5667,20 @@ export class InteractiveMode {
|
|
|
5658
5667
|
}
|
|
5659
5668
|
}
|
|
5660
5669
|
restoreEditor();
|
|
5661
|
-
|
|
5662
|
-
|
|
5670
|
+
const doneParts = [];
|
|
5671
|
+
if (installed.length > 0)
|
|
5672
|
+
doneParts.push(`Installed ${installed.join(", ")}`);
|
|
5673
|
+
if (removed.length > 0)
|
|
5674
|
+
doneParts.push(`Removed ${removed.join(", ")}`);
|
|
5675
|
+
if (doneParts.length > 0) {
|
|
5676
|
+
this.showStatus(`${doneParts.join(". ")}. Run /reload to apply the changes.`);
|
|
5663
5677
|
}
|
|
5664
5678
|
if (failed.length > 0) {
|
|
5665
|
-
this.showError(`Failed to
|
|
5679
|
+
this.showError(`Failed to update ${failed.join(", ")}`);
|
|
5666
5680
|
}
|
|
5667
5681
|
if (cancelled) {
|
|
5668
|
-
const remaining =
|
|
5669
|
-
this.showStatus(`
|
|
5682
|
+
const remaining = total - installed.length - removed.length - failed.length;
|
|
5683
|
+
this.showStatus(`Cancelled${remaining > 0 ? ` (${remaining} package${remaining === 1 ? "" : "s"} skipped)` : ""}.${doneParts.length > 0 ? " Run /reload to apply the completed changes." : ""}`);
|
|
5670
5684
|
}
|
|
5671
5685
|
}
|
|
5672
5686
|
async handleReloadCommand() {
|