agentinit 1.17.1 → 1.18.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/CHANGELOG.md +15 -0
- package/README.md +8 -2
- package/dist/cli.js +307 -207
- package/dist/commands/plugins.d.ts.map +1 -1
- package/dist/commands/plugins.js +194 -145
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +43 -48
- package/dist/commands/skills.js.map +1 -1
- package/dist/core/pluginManager.d.ts +2 -0
- package/dist/core/pluginManager.d.ts.map +1 -1
- package/dist/core/pluginManager.js +7 -1
- package/dist/core/pluginManager.js.map +1 -1
- package/dist/utils/promptUtils.d.ts +26 -0
- package/dist/utils/promptUtils.d.ts.map +1 -0
- package/dist/utils/promptUtils.js +65 -0
- package/dist/utils/promptUtils.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/commands/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/commands/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2b7D"}
|
package/dist/commands/plugins.js
CHANGED
|
@@ -4,6 +4,7 @@ import { homedir } from 'os';
|
|
|
4
4
|
import { dirname, relative, resolve } from 'path';
|
|
5
5
|
import { green, dim, bold, cyan, yellow, orange } from '../utils/colors.js';
|
|
6
6
|
import { logger } from '../utils/logger.js';
|
|
7
|
+
import { promptMultiselect, selectBundlePlugins } from '../utils/promptUtils.js';
|
|
7
8
|
import { MultipleBundlePluginsError, PluginManager } from '../core/pluginManager.js';
|
|
8
9
|
import { AgentManager } from '../core/agentManager.js';
|
|
9
10
|
import { getConfiguredDefaultMarketplaceId, getMarketplaceCategories } from '../core/marketplaceRegistry.js';
|
|
@@ -21,6 +22,7 @@ export function registerPluginsCommand(program) {
|
|
|
21
22
|
.option('-a, --agent <agents...>', 'Target specific agent(s)')
|
|
22
23
|
.option('-g, --global', 'Install globally')
|
|
23
24
|
.option('--copy-skills', 'Copy plugin skills instead of using canonical symlink installs')
|
|
25
|
+
.option('--all', 'Select all bundled plugins when the source contains multiple plugins')
|
|
24
26
|
.option('-l, --list', 'Preview plugin contents without installing')
|
|
25
27
|
.option('-y, --yes', 'Skip confirmation prompts, auto-detect project-configured agents')
|
|
26
28
|
.action(async (source, options) => {
|
|
@@ -61,43 +63,45 @@ export function registerPluginsCommand(program) {
|
|
|
61
63
|
catch (error) {
|
|
62
64
|
if (error instanceof MultipleBundlePluginsError) {
|
|
63
65
|
spinner.stop();
|
|
64
|
-
const selected = await
|
|
66
|
+
const selected = await selectBundlePlugins(error.entries, 'preview', { selectAll: options.all });
|
|
65
67
|
if (!selected) {
|
|
66
68
|
return;
|
|
67
69
|
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
70
|
+
for (const pluginName of selected) {
|
|
71
|
+
const retrySpinner = ora(`Fetching plugin ${pluginName}...`).start();
|
|
72
|
+
try {
|
|
73
|
+
const preview = await pluginManager.inspectPlugin(source, {
|
|
74
|
+
from: options.from,
|
|
75
|
+
pluginName,
|
|
76
|
+
});
|
|
77
|
+
retrySpinner.stop();
|
|
78
|
+
const p = preview.plugin;
|
|
79
|
+
console.log('');
|
|
80
|
+
logger.info(`${bold(p.name)} ${dim(`v${p.version}`)} ${dim(`[${p.format} format]`)}`);
|
|
81
|
+
if (p.description)
|
|
82
|
+
logger.info(` ${p.description}`);
|
|
83
|
+
console.log('');
|
|
84
|
+
if (p.skills.length > 0) {
|
|
85
|
+
logger.info(` ${green('Skills')} (${p.skills.length}):`);
|
|
86
|
+
for (const skill of p.skills) {
|
|
87
|
+
logger.info(` ${green(skill.name)} - ${skill.description}`);
|
|
88
|
+
}
|
|
85
89
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
if (p.mcpServers.length > 0) {
|
|
91
|
+
logger.info(` ${cyan('MCP Servers')} (${p.mcpServers.length}):`);
|
|
92
|
+
for (const mcp of p.mcpServers) {
|
|
93
|
+
logger.info(` ${cyan(mcp.name)} [${mcp.type}]`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (p.skills.length === 0 && p.mcpServers.length === 0) {
|
|
97
|
+
logger.info(' No portable components found (no skills or MCP servers).');
|
|
91
98
|
}
|
|
99
|
+
renderPluginWarnings(preview, process.cwd());
|
|
92
100
|
}
|
|
93
|
-
|
|
94
|
-
|
|
101
|
+
catch (retryError) {
|
|
102
|
+
retrySpinner.fail(`Failed to fetch plugin ${pluginName}`);
|
|
103
|
+
logger.error(`Error: ${retryError instanceof Error ? retryError.message : 'Unknown error'}`);
|
|
95
104
|
}
|
|
96
|
-
renderPluginWarnings(preview, process.cwd());
|
|
97
|
-
}
|
|
98
|
-
catch (retryError) {
|
|
99
|
-
retrySpinner.fail('Failed to fetch plugin');
|
|
100
|
-
logger.error(`Error: ${retryError instanceof Error ? retryError.message : 'Unknown error'}`);
|
|
101
105
|
}
|
|
102
106
|
}
|
|
103
107
|
else {
|
|
@@ -110,35 +114,47 @@ export function registerPluginsCommand(program) {
|
|
|
110
114
|
// Interactive agent selection if not --yes and not --agent
|
|
111
115
|
let agentIds = options.agent;
|
|
112
116
|
let targetGlobal = options.global;
|
|
113
|
-
let
|
|
117
|
+
let selectionPreview = null;
|
|
114
118
|
let previewRendered = false;
|
|
115
|
-
let
|
|
119
|
+
let selectedPluginNames;
|
|
116
120
|
if (!agentIds && !options.yes) {
|
|
117
121
|
const previewSpinner = ora('Inspecting plugin...').start();
|
|
118
122
|
try {
|
|
119
|
-
preview = await pluginManager.preparePluginInstall(source, {
|
|
123
|
+
const preview = await pluginManager.preparePluginInstall(source, {
|
|
120
124
|
from: options.from,
|
|
121
125
|
});
|
|
122
126
|
previewSpinner.stop();
|
|
123
|
-
|
|
127
|
+
selectionPreview = buildPluginSelectionPreview([preview]);
|
|
128
|
+
renderPreparedPluginWarnings([preview], process.cwd());
|
|
124
129
|
previewRendered = true;
|
|
125
130
|
}
|
|
126
131
|
catch (error) {
|
|
127
132
|
if (error instanceof MultipleBundlePluginsError) {
|
|
128
133
|
previewSpinner.stop();
|
|
129
|
-
const selected = await
|
|
134
|
+
const selected = await selectBundlePlugins(error.entries, 'install', { selectAll: options.all });
|
|
130
135
|
if (!selected) {
|
|
131
136
|
return;
|
|
132
137
|
}
|
|
133
|
-
|
|
138
|
+
selectedPluginNames = selected;
|
|
134
139
|
const retrySpinner = ora('Inspecting plugin...').start();
|
|
135
140
|
try {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
const previewsByPlugin = new Map();
|
|
142
|
+
const previewOrder = selectedPluginNames.length > 1
|
|
143
|
+
? [...selectedPluginNames.slice(1), selectedPluginNames[0]]
|
|
144
|
+
: selectedPluginNames;
|
|
145
|
+
for (const pluginName of previewOrder) {
|
|
146
|
+
const preparedPreview = await pluginManager.preparePluginInstall(source, {
|
|
147
|
+
from: options.from,
|
|
148
|
+
pluginName,
|
|
149
|
+
});
|
|
150
|
+
previewsByPlugin.set(pluginName, preparedPreview);
|
|
151
|
+
}
|
|
152
|
+
const previews = selectedPluginNames
|
|
153
|
+
.map(pluginName => previewsByPlugin.get(pluginName))
|
|
154
|
+
.filter((value) => !!value);
|
|
140
155
|
retrySpinner.stop();
|
|
141
|
-
|
|
156
|
+
selectionPreview = buildPluginSelectionPreview(previews);
|
|
157
|
+
renderPreparedPluginWarnings(previews, process.cwd());
|
|
142
158
|
previewRendered = true;
|
|
143
159
|
}
|
|
144
160
|
catch (retryError) {
|
|
@@ -154,7 +170,7 @@ export function registerPluginsCommand(program) {
|
|
|
154
170
|
}
|
|
155
171
|
}
|
|
156
172
|
try {
|
|
157
|
-
const selection = await interactiveAgentSelect(pluginManager, agentManager, process.cwd(), targetGlobal,
|
|
173
|
+
const selection = await interactiveAgentSelect(pluginManager, agentManager, process.cwd(), targetGlobal, selectionPreview);
|
|
158
174
|
if (!selection || selection.aborted || !selection.agents || selection.agents.length === 0) {
|
|
159
175
|
await pluginManager.discardPreparedPlugin(source, { from: options.from });
|
|
160
176
|
logger.info('No agents selected. Aborting.');
|
|
@@ -172,87 +188,98 @@ export function registerPluginsCommand(program) {
|
|
|
172
188
|
}
|
|
173
189
|
}
|
|
174
190
|
// Install
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
});
|
|
185
|
-
const p = result.plugin;
|
|
186
|
-
const totalSkills = result.skills.installed.length;
|
|
187
|
-
const totalMcp = result.mcpServers.applied.length;
|
|
188
|
-
const totalNative = result.nativePlugins.installed.length;
|
|
189
|
-
if (totalSkills === 0 && totalMcp === 0 && totalNative === 0) {
|
|
190
|
-
spinner.warn(`Plugin "${p.name}" has no portable components to install.`);
|
|
191
|
-
if (!previewRendered) {
|
|
192
|
-
renderPluginWarnings(result, process.cwd());
|
|
191
|
+
const pluginsToInstall = selectedPluginNames || [undefined];
|
|
192
|
+
for (const pluginName of pluginsToInstall) {
|
|
193
|
+
const spinner = ora(pluginName ? `Installing plugin ${pluginName}...` : 'Installing plugin...').start();
|
|
194
|
+
try {
|
|
195
|
+
if (pluginName && pluginName !== selectedPluginNames?.[0]) {
|
|
196
|
+
await pluginManager.preparePluginInstall(source, {
|
|
197
|
+
from: options.from,
|
|
198
|
+
pluginName,
|
|
199
|
+
});
|
|
193
200
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
201
|
+
const result = await pluginManager.installPlugin(source, process.cwd(), {
|
|
202
|
+
from: options.from,
|
|
203
|
+
agents: agentIds,
|
|
204
|
+
global: targetGlobal,
|
|
205
|
+
copySkills: options.copySkills,
|
|
206
|
+
yes: options.yes,
|
|
207
|
+
...(pluginName ? { pluginName } : {}),
|
|
208
|
+
});
|
|
209
|
+
const p = result.plugin;
|
|
210
|
+
const totalSkills = result.skills.installed.length;
|
|
211
|
+
const totalMcp = result.mcpServers.applied.length;
|
|
212
|
+
const totalNative = result.nativePlugins.installed.length;
|
|
213
|
+
if (totalSkills === 0 && totalMcp === 0 && totalNative === 0) {
|
|
214
|
+
spinner.warn(`Plugin "${p.name}" has no portable components to install.`);
|
|
215
|
+
if (!previewRendered) {
|
|
216
|
+
renderPluginWarnings(result, process.cwd());
|
|
217
|
+
}
|
|
218
|
+
continue;
|
|
203
219
|
}
|
|
204
|
-
|
|
205
|
-
|
|
220
|
+
spinner.succeed(`Installed plugin ${green(bold(p.name))} ${dim(`v${p.version}`)}`);
|
|
221
|
+
renderInstalledComponents(result, agentManager, process.cwd());
|
|
222
|
+
// Skipped
|
|
223
|
+
if (result.skills.skipped.length > 0 || result.mcpServers.skipped.length > 0 || result.nativePlugins.skipped.length > 0) {
|
|
224
|
+
console.log('');
|
|
225
|
+
for (const s of result.skills.skipped) {
|
|
226
|
+
logger.debug(`Skipped skill ${s.name}: ${s.reason}`);
|
|
227
|
+
}
|
|
228
|
+
for (const s of result.mcpServers.skipped) {
|
|
229
|
+
logger.debug(`Skipped MCP ${s.name}: ${s.reason}`);
|
|
230
|
+
}
|
|
231
|
+
for (const s of result.nativePlugins.skipped) {
|
|
232
|
+
logger.warn(`Skipped native plugin payload for ${s.agent}: ${s.reason}`);
|
|
233
|
+
}
|
|
206
234
|
}
|
|
207
|
-
|
|
208
|
-
|
|
235
|
+
if (!previewRendered) {
|
|
236
|
+
renderPluginWarnings(result, process.cwd());
|
|
209
237
|
}
|
|
238
|
+
logger.success('Plugin installation complete.');
|
|
210
239
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
catch (error) {
|
|
217
|
-
if (error instanceof MultipleBundlePluginsError && !options.yes) {
|
|
218
|
-
spinner.stop();
|
|
219
|
-
const selected = await selectBundlePlugin(error, 'install');
|
|
220
|
-
if (!selected) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
const retrySpinner = ora('Installing plugin...').start();
|
|
224
|
-
try {
|
|
225
|
-
const result = await pluginManager.installPlugin(source, process.cwd(), {
|
|
226
|
-
from: options.from,
|
|
227
|
-
agents: agentIds,
|
|
228
|
-
global: targetGlobal,
|
|
229
|
-
copySkills: options.copySkills,
|
|
230
|
-
yes: options.yes,
|
|
231
|
-
pluginName: selected,
|
|
232
|
-
});
|
|
233
|
-
const p = result.plugin;
|
|
234
|
-
const totalSkills = result.skills.installed.length;
|
|
235
|
-
const totalMcp = result.mcpServers.applied.length;
|
|
236
|
-
const totalNative = result.nativePlugins.installed.length;
|
|
237
|
-
if (totalSkills === 0 && totalMcp === 0 && totalNative === 0) {
|
|
238
|
-
retrySpinner.warn(`Plugin "${p.name}" has no portable components to install.`);
|
|
239
|
-
renderPluginWarnings(result, process.cwd());
|
|
240
|
+
catch (error) {
|
|
241
|
+
if (error instanceof MultipleBundlePluginsError && (options.all || !options.yes)) {
|
|
242
|
+
spinner.stop();
|
|
243
|
+
const selected = await selectBundlePlugins(error.entries, 'install', { selectAll: options.all });
|
|
244
|
+
if (!selected) {
|
|
240
245
|
return;
|
|
241
246
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
247
|
+
for (const selectedName of selected) {
|
|
248
|
+
const retrySpinner = ora(`Installing plugin ${selectedName}...`).start();
|
|
249
|
+
try {
|
|
250
|
+
const result = await pluginManager.installPlugin(source, process.cwd(), {
|
|
251
|
+
from: options.from,
|
|
252
|
+
agents: agentIds,
|
|
253
|
+
global: targetGlobal,
|
|
254
|
+
copySkills: options.copySkills,
|
|
255
|
+
yes: options.yes,
|
|
256
|
+
pluginName: selectedName,
|
|
257
|
+
});
|
|
258
|
+
const p = result.plugin;
|
|
259
|
+
const totalSkills = result.skills.installed.length;
|
|
260
|
+
const totalMcp = result.mcpServers.applied.length;
|
|
261
|
+
const totalNative = result.nativePlugins.installed.length;
|
|
262
|
+
if (totalSkills === 0 && totalMcp === 0 && totalNative === 0) {
|
|
263
|
+
retrySpinner.warn(`Plugin "${p.name}" has no portable components to install.`);
|
|
264
|
+
renderPluginWarnings(result, process.cwd());
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
retrySpinner.succeed(`Installed plugin ${green(bold(p.name))} ${dim(`v${p.version}`)}`);
|
|
268
|
+
renderInstalledComponents(result, agentManager, process.cwd());
|
|
269
|
+
renderPluginWarnings(result, process.cwd());
|
|
270
|
+
logger.success('Plugin installation complete.');
|
|
271
|
+
}
|
|
272
|
+
catch (retryError) {
|
|
273
|
+
retrySpinner.fail(`Failed to install plugin ${selectedName}`);
|
|
274
|
+
logger.error(`Error: ${retryError instanceof Error ? retryError.message : 'Unknown error'}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
246
277
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
logger.error(`Error: ${
|
|
278
|
+
else {
|
|
279
|
+
spinner.fail('Failed to install plugin');
|
|
280
|
+
logger.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
250
281
|
}
|
|
251
282
|
}
|
|
252
|
-
else {
|
|
253
|
-
spinner.fail('Failed to install plugin');
|
|
254
|
-
logger.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
255
|
-
}
|
|
256
283
|
}
|
|
257
284
|
});
|
|
258
285
|
// --- plugins search [query] ---
|
|
@@ -383,22 +410,6 @@ export function registerPluginsCommand(program) {
|
|
|
383
410
|
}
|
|
384
411
|
});
|
|
385
412
|
}
|
|
386
|
-
async function selectBundlePlugin(error, actionLabel) {
|
|
387
|
-
const response = await prompts({
|
|
388
|
-
type: 'select',
|
|
389
|
-
name: 'plugin',
|
|
390
|
-
message: `This repository contains multiple plugins. Select one to ${actionLabel}:`,
|
|
391
|
-
choices: error.entries.map(entry => ({
|
|
392
|
-
title: entry.name,
|
|
393
|
-
value: entry.name,
|
|
394
|
-
})),
|
|
395
|
-
});
|
|
396
|
-
if (!response.plugin) {
|
|
397
|
-
logger.info('Cancelled.');
|
|
398
|
-
return null;
|
|
399
|
-
}
|
|
400
|
-
return response.plugin;
|
|
401
|
-
}
|
|
402
413
|
function formatPathForDisplay(pathValue, projectPath) {
|
|
403
414
|
if (pathValue.startsWith(`${projectPath}/`)) {
|
|
404
415
|
return relative(projectPath, pathValue) || '.';
|
|
@@ -414,16 +425,48 @@ function getAgentLabel(agentIds, agentManager) {
|
|
|
414
425
|
.map(agentId => agentManager.getAgentById(agentId)?.name || agentId)
|
|
415
426
|
.join(', ');
|
|
416
427
|
}
|
|
428
|
+
function buildPluginSelectionPreview(previews) {
|
|
429
|
+
const nativeAgentIds = new Set();
|
|
430
|
+
const nativeFeatures = new Set();
|
|
431
|
+
const nativeInstallPaths = new Set();
|
|
432
|
+
for (const preview of previews) {
|
|
433
|
+
if (!preview.nativePreview) {
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
nativeAgentIds.add(preview.nativePreview.agent);
|
|
437
|
+
nativeInstallPaths.add(preview.nativePreview.installPath);
|
|
438
|
+
for (const feature of preview.nativePreview.features) {
|
|
439
|
+
nativeFeatures.add(feature);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return {
|
|
443
|
+
selectedCount: previews.length,
|
|
444
|
+
skillCount: previews.reduce((total, preview) => total + preview.plugin.skills.length, 0),
|
|
445
|
+
mcpServerCount: previews.reduce((total, preview) => total + preview.plugin.mcpServers.length, 0),
|
|
446
|
+
nativeAgentIds: [...nativeAgentIds],
|
|
447
|
+
nativeFeatures: [...nativeFeatures],
|
|
448
|
+
nativeInstallPaths: [...nativeInstallPaths],
|
|
449
|
+
};
|
|
450
|
+
}
|
|
417
451
|
function getPortableComponentSummary(preview) {
|
|
418
452
|
const parts = [];
|
|
419
|
-
if (preview.
|
|
420
|
-
parts.push(`${preview.
|
|
453
|
+
if (preview.skillCount > 0) {
|
|
454
|
+
parts.push(`${preview.skillCount} skill(s)`);
|
|
421
455
|
}
|
|
422
|
-
if (preview.
|
|
423
|
-
parts.push(`${preview.
|
|
456
|
+
if (preview.mcpServerCount > 0) {
|
|
457
|
+
parts.push(`${preview.mcpServerCount} MCP server(s)`);
|
|
424
458
|
}
|
|
425
459
|
return parts.length > 0 ? parts.join(', ') : 'No portable components';
|
|
426
460
|
}
|
|
461
|
+
function renderPreparedPluginWarnings(previews, projectPath) {
|
|
462
|
+
for (const preview of previews) {
|
|
463
|
+
if (previews.length > 1) {
|
|
464
|
+
console.log('');
|
|
465
|
+
logger.info(`${bold(preview.plugin.name)} ${dim(`v${preview.plugin.version}`)}`);
|
|
466
|
+
}
|
|
467
|
+
renderPluginWarnings(preview, projectPath);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
427
470
|
function getSourceWarnings(warnings) {
|
|
428
471
|
const items = [];
|
|
429
472
|
for (const warning of warnings) {
|
|
@@ -691,36 +734,44 @@ function shouldPreselectPluginGroup(group, installGlobal, preview) {
|
|
|
691
734
|
if (group.kind === 'canonical-shared') {
|
|
692
735
|
return true;
|
|
693
736
|
}
|
|
694
|
-
if (preview.
|
|
695
|
-
return group.agents.some(agent => agent.id
|
|
737
|
+
if (preview.nativeAgentIds.length > 0) {
|
|
738
|
+
return group.agents.some(agent => preview.nativeAgentIds.includes(agent.id));
|
|
696
739
|
}
|
|
697
740
|
return false;
|
|
698
741
|
}
|
|
699
742
|
function getPluginGroupDescription(group, preview, projectPath) {
|
|
700
743
|
const portableSummary = getPortableComponentSummary(preview);
|
|
701
|
-
if (
|
|
744
|
+
if (preview.nativeAgentIds.length === 0) {
|
|
702
745
|
return portableSummary;
|
|
703
746
|
}
|
|
704
|
-
const containsClaudeCode = group.agents.some(agent => agent.id
|
|
747
|
+
const containsClaudeCode = group.agents.some(agent => preview.nativeAgentIds.includes(agent.id));
|
|
705
748
|
if (!containsClaudeCode) {
|
|
706
|
-
return `${portableSummary}.
|
|
749
|
+
return `${portableSummary}. Some selected plugins also include Claude-specific components that will not be fully available for these agents.`;
|
|
707
750
|
}
|
|
708
751
|
const otherAgents = group.agents
|
|
709
|
-
.filter(agent => agent.id
|
|
752
|
+
.filter(agent => !preview.nativeAgentIds.includes(agent.id))
|
|
710
753
|
.map(agent => agent.name);
|
|
711
|
-
const installPath =
|
|
754
|
+
const installPath = preview.nativeInstallPaths.length === 1
|
|
755
|
+
? formatPathForDisplay(preview.nativeInstallPaths[0], projectPath)
|
|
756
|
+
: `~/.claude/plugins (${preview.nativeInstallPaths.length} plugin-specific install paths)`;
|
|
757
|
+
const nativeSummary = preview.nativeFeatures.length > 0
|
|
758
|
+
? ` Native components: ${preview.nativeFeatures.join(', ')}.`
|
|
759
|
+
: '';
|
|
712
760
|
if (otherAgents.length === 0) {
|
|
713
|
-
return `${portableSummary}. Full plugin support is available in Claude Code;
|
|
761
|
+
return `${portableSummary}. Full plugin support is available in Claude Code; native components install at ${installPath}.${nativeSummary}`;
|
|
714
762
|
}
|
|
715
763
|
const otherAgentsLabel = otherAgents.join(', ');
|
|
716
764
|
const shareVerb = otherAgents.length === 1 ? 'shares' : 'share';
|
|
717
765
|
const receiveVerb = otherAgents.length === 1 ? 'receives' : 'receive';
|
|
718
|
-
return `${portableSummary}. Full plugin support is available in Claude Code;
|
|
766
|
+
return `${portableSummary}. Full plugin support is available in Claude Code; native components install at ${installPath}.${nativeSummary} ${otherAgentsLabel} ${shareVerb} this skills directory but only ${receiveVerb} the installed skills.`;
|
|
719
767
|
}
|
|
720
768
|
/**
|
|
721
769
|
* Interactive agent selection grouped by shared skills directory
|
|
722
770
|
*/
|
|
723
771
|
async function interactiveAgentSelect(pluginManager, agentManager, projectPath, global, preview) {
|
|
772
|
+
if (!preview) {
|
|
773
|
+
return { aborted: true };
|
|
774
|
+
}
|
|
724
775
|
let installGlobal = !!global;
|
|
725
776
|
let groups = installGlobal
|
|
726
777
|
? buildGlobalPluginGroups(agentManager, projectPath)
|
|
@@ -756,13 +807,11 @@ async function interactiveAgentSelect(pluginManager, agentManager, projectPath,
|
|
|
756
807
|
logger.warn('No supported agents expose a skills directory.');
|
|
757
808
|
return { aborted: true };
|
|
758
809
|
}
|
|
759
|
-
const response = await
|
|
760
|
-
type: 'multiselect',
|
|
810
|
+
const response = await promptMultiselect({
|
|
761
811
|
name: 'groups',
|
|
762
812
|
message: installGlobal
|
|
763
813
|
? 'Select which global agents should receive this plugin:'
|
|
764
814
|
: 'Select which agents should receive this plugin:',
|
|
765
|
-
instructions: false,
|
|
766
815
|
min: 1,
|
|
767
816
|
choices: groups.map(group => {
|
|
768
817
|
const compatible = group.compatibleAgentNames.length > 0
|