agentinit 1.15.1 → 1.16.1
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 +16 -2
- package/README.md +1 -1
- package/dist/cli.js +293 -14
- package/dist/commands/plugins.d.ts.map +1 -1
- package/dist/commands/plugins.js +38 -3
- package/dist/commands/plugins.js.map +1 -1
- package/dist/core/pluginManager.d.ts +11 -0
- package/dist/core/pluginManager.d.ts.map +1 -1
- package/dist/core/pluginManager.js +274 -9
- package/dist/core/pluginManager.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [1.16.1](https://github.com/agentinit/agentinit/compare/v1.16.0...v1.16.1) (2026-04-01)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* align Claude native plugin installs with marketplace behavior ([bdfa280](https://github.com/agentinit/agentinit/commit/bdfa2801a9ad933727fd72327cd9b121dfe0a543))
|
|
7
|
+
|
|
8
|
+
# [1.16.0](https://github.com/agentinit/agentinit/compare/v1.15.1...v1.16.0) (2026-04-01)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* restore canonical global plugin target ([fad7b5e](https://github.com/agentinit/agentinit/commit/fad7b5e6a6fe359ed721f388e0991d7774a85bb2))
|
|
14
|
+
|
|
1
15
|
## [1.15.1](https://github.com/agentinit/agentinit/compare/v1.15.0...v1.15.1) (2026-04-01)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -135,7 +149,7 @@
|
|
|
135
149
|
* add OpenClaw as a skills target with shared project installs via `.agents/skills/` and dedicated global installs via `~/.openclaw/skills/`
|
|
136
150
|
* add Hermes as a skills target with shared project installs via `.agents/skills/` and dedicated global installs via `~/.hermes/skills/`
|
|
137
151
|
* warn and fall back to GitHub repos for marketplace misses, marking allowlisted repos like `openai/codex-plugin-cc` as verified
|
|
138
|
-
* install Claude Code-native plugin payloads during `plugins install` when Claude-only components are detected and Claude Code is targeted
|
|
152
|
+
* install Claude Code-native plugin payloads during `plugins install` when Claude-only components are detected and Claude Code is targeted, registering native marketplace metadata under `~/.claude/plugins`
|
|
139
153
|
|
|
140
154
|
### Bug Fixes
|
|
141
155
|
|
|
@@ -145,7 +159,7 @@
|
|
|
145
159
|
* update docs and onboarding to the `mcp add|verify`, `rules add`, and `skills add` command model
|
|
146
160
|
* parse Claude Code marketplace bundle repos like `openai/codex-plugin-cc` when installing portable skills or plugins
|
|
147
161
|
* keep interactive plugin target defaults on all detected agents, warn clearly when Claude-native payloads are skipped, and reuse the previewed remote source during install
|
|
148
|
-
* enable Claude-native plugin payloads in `~/.claude/settings.json`
|
|
162
|
+
* enable Claude-native plugin payloads in `~/.claude/settings.json`, register them in `known_marketplaces.json`, and migrate legacy `agentinit-*` Claude namespaces to native marketplace ids
|
|
149
163
|
|
|
150
164
|
# [1.7.0](https://github.com/agentinit/agentinit/compare/v1.6.0...v1.7.0) (2025-10-17)
|
|
151
165
|
|
package/README.md
CHANGED
|
@@ -263,7 +263,7 @@ agentinit plugins remove code-review
|
|
|
263
263
|
- Implemented marketplaces today include `claude` (Anthropic's Claude plugin marketplace) and `openai` (the OpenAI Codex skills catalog).
|
|
264
264
|
- You can add your own marketplaces with `agentinit config marketplaces add <identifier> <repo-url>`.
|
|
265
265
|
- If a marketplace lookup misses but the source still looks like `owner/repo`, AgentInit warns and tries that GitHub repository directly. Exact repos added with `agentinit config verified-repos add <owner/repo>` are labeled as verified during that fallback.
|
|
266
|
-
- For Claude-format plugins, `plugins install`
|
|
266
|
+
- For Claude-format plugins, `plugins install` installs portable skills and MCP servers for compatible selected agents. If a native Claude Code plugin bundle is also present, AgentInit installs that bundle into `~/.claude/plugins` when `claude` is selected, registers the corresponding Claude marketplace metadata, and skips portable skill fallback for any selected agents that share Claude Code's skills directory. Portable MCP installs still apply to other compatible agents.
|
|
267
267
|
- Claude-native plugin payloads are user-scoped and stored under `~/.claude/plugins`, even when the AgentInit install itself is project-scoped.
|
|
268
268
|
|
|
269
269
|
### `agentinit config`
|
package/dist/cli.js
CHANGED
|
@@ -17312,6 +17312,8 @@ class PluginManager {
|
|
|
17312
17312
|
(async () => !!manifest.commands || await isDirectory(join4(pluginDir, "commands")))(),
|
|
17313
17313
|
(async () => !!manifest.hooks || await isDirectory(join4(pluginDir, "hooks")))(),
|
|
17314
17314
|
(async () => !!manifest.agents || await isDirectory(join4(pluginDir, "agents")))(),
|
|
17315
|
+
isDirectory(join4(pluginDir, "skills")),
|
|
17316
|
+
(async () => !!manifest.mcpServers || await fileExists(join4(pluginDir, ".mcp.json")))(),
|
|
17315
17317
|
isDirectory(join4(pluginDir, "prompts")),
|
|
17316
17318
|
isDirectory(join4(pluginDir, "schemas")),
|
|
17317
17319
|
isDirectory(join4(pluginDir, "scripts")),
|
|
@@ -17321,10 +17323,12 @@ class PluginManager {
|
|
|
17321
17323
|
...featureChecks[0] ? ["commands"] : [],
|
|
17322
17324
|
...featureChecks[1] ? ["hooks"] : [],
|
|
17323
17325
|
...featureChecks[2] ? ["agents"] : [],
|
|
17324
|
-
...featureChecks[3] ? ["
|
|
17325
|
-
...featureChecks[4] ? ["
|
|
17326
|
-
...featureChecks[5] ? ["
|
|
17327
|
-
...featureChecks[6] ? ["
|
|
17326
|
+
...featureChecks[3] ? ["skills"] : [],
|
|
17327
|
+
...featureChecks[4] ? ["mcp servers"] : [],
|
|
17328
|
+
...featureChecks[5] ? ["prompts"] : [],
|
|
17329
|
+
...featureChecks[6] ? ["schemas"] : [],
|
|
17330
|
+
...featureChecks[7] ? ["scripts"] : [],
|
|
17331
|
+
...featureChecks[8] ? ["templates"] : []
|
|
17328
17332
|
];
|
|
17329
17333
|
}
|
|
17330
17334
|
async getClaudeNativeInstallTarget(plugin, pluginDir) {
|
|
@@ -17346,12 +17350,13 @@ class PluginManager {
|
|
|
17346
17350
|
return null;
|
|
17347
17351
|
}
|
|
17348
17352
|
const baseNamespace = plugin.nativeClaudeBundle?.bundleName || plugin.source.marketplace || (plugin.source.owner && plugin.source.repo ? `${plugin.source.owner}-${plugin.source.repo}` : plugin.name);
|
|
17349
|
-
const namespace =
|
|
17353
|
+
const namespace = this.slugifyPluginNamespace(baseNamespace);
|
|
17350
17354
|
const versionDir = this.slugifyPluginNamespace(plugin.version || "0.0.0");
|
|
17351
17355
|
return {
|
|
17352
17356
|
namespace,
|
|
17353
17357
|
pluginKey: `${plugin.name}@${namespace}`,
|
|
17354
17358
|
installPath: join4(homedir4(), ".claude", "plugins", "cache", namespace, plugin.name, versionDir),
|
|
17359
|
+
marketplacePath: getClaudeMarketplaceInstallPath(namespace),
|
|
17355
17360
|
features
|
|
17356
17361
|
};
|
|
17357
17362
|
}
|
|
@@ -17374,6 +17379,24 @@ class PluginManager {
|
|
|
17374
17379
|
async saveClaudeInstalledPlugins(state) {
|
|
17375
17380
|
await writeFile(getClaudeInstalledPluginsPath(), JSON.stringify(state, null, 2));
|
|
17376
17381
|
}
|
|
17382
|
+
async readClaudeKnownMarketplaces() {
|
|
17383
|
+
const content = await readFileIfExists(getClaudeKnownMarketplacesPath());
|
|
17384
|
+
if (!content) {
|
|
17385
|
+
return {};
|
|
17386
|
+
}
|
|
17387
|
+
try {
|
|
17388
|
+
const parsed = JSON.parse(content);
|
|
17389
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
17390
|
+
return {};
|
|
17391
|
+
}
|
|
17392
|
+
return parsed;
|
|
17393
|
+
} catch {
|
|
17394
|
+
return {};
|
|
17395
|
+
}
|
|
17396
|
+
}
|
|
17397
|
+
async saveClaudeKnownMarketplaces(state) {
|
|
17398
|
+
await writeFile(getClaudeKnownMarketplacesPath(), JSON.stringify(state, null, 2));
|
|
17399
|
+
}
|
|
17377
17400
|
async readClaudeSettings() {
|
|
17378
17401
|
const content = await readFileIfExists(getClaudeSettingsPath());
|
|
17379
17402
|
if (!content) {
|
|
@@ -17395,6 +17418,145 @@ class PluginManager {
|
|
|
17395
17418
|
async saveClaudeSettings(state) {
|
|
17396
17419
|
await writeFile(getClaudeSettingsPath(), JSON.stringify(state, null, 2));
|
|
17397
17420
|
}
|
|
17421
|
+
async findClaudeMarketplaceRoot(pluginDir) {
|
|
17422
|
+
let currentDir = resolve7(pluginDir);
|
|
17423
|
+
while (true) {
|
|
17424
|
+
if (await fileExists(join4(currentDir, ".claude-plugin", "marketplace.json"))) {
|
|
17425
|
+
return currentDir;
|
|
17426
|
+
}
|
|
17427
|
+
const parentDir = dirname2(currentDir);
|
|
17428
|
+
if (parentDir === currentDir) {
|
|
17429
|
+
return null;
|
|
17430
|
+
}
|
|
17431
|
+
currentDir = parentDir;
|
|
17432
|
+
}
|
|
17433
|
+
}
|
|
17434
|
+
async readClaudeMarketplaceManifest(marketplaceDir) {
|
|
17435
|
+
const manifestContent = await readFileIfExists(join4(marketplaceDir, ".claude-plugin", "marketplace.json"));
|
|
17436
|
+
if (!manifestContent) {
|
|
17437
|
+
return null;
|
|
17438
|
+
}
|
|
17439
|
+
try {
|
|
17440
|
+
const parsed = JSON.parse(manifestContent);
|
|
17441
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
17442
|
+
return null;
|
|
17443
|
+
}
|
|
17444
|
+
const plugins = Array.isArray(parsed.plugins) ? parsed.plugins.filter((entry) => !!entry && typeof entry === "object" && !Array.isArray(entry)) : [];
|
|
17445
|
+
return {
|
|
17446
|
+
...parsed,
|
|
17447
|
+
plugins
|
|
17448
|
+
};
|
|
17449
|
+
} catch {
|
|
17450
|
+
return null;
|
|
17451
|
+
}
|
|
17452
|
+
}
|
|
17453
|
+
async saveClaudeMarketplaceManifest(marketplaceDir, manifest) {
|
|
17454
|
+
await fs22.mkdir(join4(marketplaceDir, ".claude-plugin"), { recursive: true });
|
|
17455
|
+
await writeFile(join4(marketplaceDir, ".claude-plugin", "marketplace.json"), JSON.stringify(manifest, null, 2));
|
|
17456
|
+
}
|
|
17457
|
+
resolveMarketplaceSourcePath(baseDir, relativePath) {
|
|
17458
|
+
const resolvedPath = resolve7(baseDir, relativePath);
|
|
17459
|
+
const relativePathFromBase = relative2(resolve7(baseDir), resolvedPath);
|
|
17460
|
+
if (relativePathFromBase.startsWith("..") || relativePathFromBase.includes("/../") || relativePathFromBase.includes("\\..\\")) {
|
|
17461
|
+
throw new Error(`Invalid marketplace source path "${relativePath}" in ${baseDir}`);
|
|
17462
|
+
}
|
|
17463
|
+
return resolvedPath;
|
|
17464
|
+
}
|
|
17465
|
+
async readClaudePluginMetadata(pluginDir) {
|
|
17466
|
+
const manifestContent = await readFileIfExists(join4(pluginDir, ".claude-plugin", "plugin.json"));
|
|
17467
|
+
if (!manifestContent) {
|
|
17468
|
+
return {};
|
|
17469
|
+
}
|
|
17470
|
+
try {
|
|
17471
|
+
const manifest = JSON.parse(manifestContent);
|
|
17472
|
+
return {
|
|
17473
|
+
...typeof manifest.description === "string" ? { description: manifest.description } : {},
|
|
17474
|
+
...typeof manifest.version === "string" ? { version: manifest.version } : {},
|
|
17475
|
+
...manifest.author ? { author: manifest.author } : {}
|
|
17476
|
+
};
|
|
17477
|
+
} catch {
|
|
17478
|
+
return {};
|
|
17479
|
+
}
|
|
17480
|
+
}
|
|
17481
|
+
async copyClaudeMarketplacePlugin(sourcePluginDir, marketplacePath, pluginName) {
|
|
17482
|
+
const marketplacePluginPath = join4(marketplacePath, "plugins", pluginName);
|
|
17483
|
+
await fs22.mkdir(dirname2(marketplacePluginPath), { recursive: true });
|
|
17484
|
+
await fs22.rm(marketplacePluginPath, { recursive: true, force: true }).catch(() => {
|
|
17485
|
+
});
|
|
17486
|
+
await fs22.cp(sourcePluginDir, marketplacePluginPath, { recursive: true, dereference: true });
|
|
17487
|
+
return marketplacePluginPath;
|
|
17488
|
+
}
|
|
17489
|
+
getClaudeMarketplaceSource(plugin, marketplaceRoot, marketplacePath) {
|
|
17490
|
+
if (plugin.source.type === "github") {
|
|
17491
|
+
if (plugin.source.owner && plugin.source.repo) {
|
|
17492
|
+
return {
|
|
17493
|
+
source: "github",
|
|
17494
|
+
repo: `${plugin.source.owner}/${plugin.source.repo}`
|
|
17495
|
+
};
|
|
17496
|
+
}
|
|
17497
|
+
if (plugin.source.url) {
|
|
17498
|
+
return {
|
|
17499
|
+
source: "git",
|
|
17500
|
+
url: plugin.source.url
|
|
17501
|
+
};
|
|
17502
|
+
}
|
|
17503
|
+
}
|
|
17504
|
+
if (plugin.source.type === "local") {
|
|
17505
|
+
return {
|
|
17506
|
+
source: "directory",
|
|
17507
|
+
path: resolve7(marketplaceRoot || plugin.source.path || marketplacePath)
|
|
17508
|
+
};
|
|
17509
|
+
}
|
|
17510
|
+
return {
|
|
17511
|
+
source: "directory",
|
|
17512
|
+
path: marketplacePath
|
|
17513
|
+
};
|
|
17514
|
+
}
|
|
17515
|
+
async materializeClaudeMarketplace(plugin, pluginDir, target) {
|
|
17516
|
+
const marketplaceRoot = await this.findClaudeMarketplaceRoot(pluginDir);
|
|
17517
|
+
const marketplaceSource = this.getClaudeMarketplaceSource(plugin, marketplaceRoot, target.marketplacePath);
|
|
17518
|
+
await fs22.mkdir(target.marketplacePath, { recursive: true });
|
|
17519
|
+
const existingManifest = await this.readClaudeMarketplaceManifest(target.marketplacePath);
|
|
17520
|
+
const sourceManifest = marketplaceRoot ? await this.readClaudeMarketplaceManifest(marketplaceRoot) : null;
|
|
17521
|
+
const mergedManifest = {
|
|
17522
|
+
...sourceManifest || {},
|
|
17523
|
+
...existingManifest || {},
|
|
17524
|
+
name: target.namespace
|
|
17525
|
+
};
|
|
17526
|
+
const mergedEntries = new Map;
|
|
17527
|
+
for (const entry of existingManifest?.plugins || []) {
|
|
17528
|
+
if (typeof entry.name === "string" && entry.name) {
|
|
17529
|
+
mergedEntries.set(entry.name, entry);
|
|
17530
|
+
}
|
|
17531
|
+
}
|
|
17532
|
+
if (marketplaceRoot && sourceManifest) {
|
|
17533
|
+
for (const entry of sourceManifest.plugins || []) {
|
|
17534
|
+
if (typeof entry.name !== "string" || !entry.name || typeof entry.source !== "string" || !entry.source) {
|
|
17535
|
+
continue;
|
|
17536
|
+
}
|
|
17537
|
+
const sourcePluginDir = this.resolveMarketplaceSourcePath(marketplaceRoot, entry.source);
|
|
17538
|
+
await this.copyClaudeMarketplacePlugin(sourcePluginDir, target.marketplacePath, entry.name);
|
|
17539
|
+
mergedEntries.set(entry.name, {
|
|
17540
|
+
...entry,
|
|
17541
|
+
source: `./plugins/${entry.name}`
|
|
17542
|
+
});
|
|
17543
|
+
}
|
|
17544
|
+
} else {
|
|
17545
|
+
await this.copyClaudeMarketplacePlugin(pluginDir, target.marketplacePath, plugin.name);
|
|
17546
|
+
const pluginMetadata = await this.readClaudePluginMetadata(pluginDir);
|
|
17547
|
+
mergedEntries.set(plugin.name, {
|
|
17548
|
+
...mergedEntries.get(plugin.name) || {},
|
|
17549
|
+
name: plugin.name,
|
|
17550
|
+
source: `./plugins/${plugin.name}`,
|
|
17551
|
+
...plugin.description ? { description: plugin.description } : {},
|
|
17552
|
+
...plugin.version ? { version: plugin.version } : {},
|
|
17553
|
+
...pluginMetadata
|
|
17554
|
+
});
|
|
17555
|
+
}
|
|
17556
|
+
mergedManifest.plugins = [...mergedEntries.values()].sort((left, right) => (left.name || "").localeCompare(right.name || ""));
|
|
17557
|
+
await this.saveClaudeMarketplaceManifest(target.marketplacePath, mergedManifest);
|
|
17558
|
+
return { source: marketplaceSource };
|
|
17559
|
+
}
|
|
17398
17560
|
async installNativeClaudePlugin(plugin, pluginDir, agents) {
|
|
17399
17561
|
const installed = [];
|
|
17400
17562
|
const skipped = [];
|
|
@@ -17415,7 +17577,8 @@ class PluginManager {
|
|
|
17415
17577
|
}
|
|
17416
17578
|
warnings.push(`Claude Code-native plugin components detected (${featureLabel}); they will only work in Claude Code and install into ~/.claude/plugins.`);
|
|
17417
17579
|
const claudeInstalled = await this.readClaudeInstalledPlugins();
|
|
17418
|
-
const
|
|
17580
|
+
const legacyKeys = Object.keys(claudeInstalled.plugins).filter((key) => key !== nativeTarget.pluginKey && key.startsWith(`${plugin.name}@agentinit-`));
|
|
17581
|
+
const conflictingKey = Object.keys(claudeInstalled.plugins).find((key) => key !== nativeTarget.pluginKey && !legacyKeys.includes(key) && key.startsWith(`${plugin.name}@`));
|
|
17419
17582
|
if (conflictingKey) {
|
|
17420
17583
|
skipped.push({
|
|
17421
17584
|
agent: "claude",
|
|
@@ -17428,6 +17591,7 @@ class PluginManager {
|
|
|
17428
17591
|
});
|
|
17429
17592
|
await fs22.mkdir(dirname2(nativeTarget.installPath), { recursive: true });
|
|
17430
17593
|
await fs22.cp(pluginDir, nativeTarget.installPath, { recursive: true, dereference: true });
|
|
17594
|
+
const marketplace = await this.materializeClaudeMarketplace(plugin, pluginDir, nativeTarget);
|
|
17431
17595
|
const now = new Date().toISOString();
|
|
17432
17596
|
claudeInstalled.plugins[nativeTarget.pluginKey] = [{
|
|
17433
17597
|
scope: "user",
|
|
@@ -17436,13 +17600,42 @@ class PluginManager {
|
|
|
17436
17600
|
installedAt: now,
|
|
17437
17601
|
lastUpdated: now
|
|
17438
17602
|
}];
|
|
17603
|
+
const legacyEntries = legacyKeys.flatMap((key) => claudeInstalled.plugins[key] || []);
|
|
17604
|
+
for (const legacyKey of legacyKeys) {
|
|
17605
|
+
delete claudeInstalled.plugins[legacyKey];
|
|
17606
|
+
}
|
|
17439
17607
|
await this.saveClaudeInstalledPlugins(claudeInstalled);
|
|
17440
17608
|
const claudeSettings = await this.readClaudeSettings();
|
|
17441
17609
|
claudeSettings.enabledPlugins = {
|
|
17442
17610
|
...claudeSettings.enabledPlugins || {},
|
|
17443
17611
|
[nativeTarget.pluginKey]: true
|
|
17444
17612
|
};
|
|
17613
|
+
claudeSettings.extraKnownMarketplaces = {
|
|
17614
|
+
...claudeSettings.extraKnownMarketplaces || {},
|
|
17615
|
+
[nativeTarget.namespace]: {
|
|
17616
|
+
source: marketplace.source
|
|
17617
|
+
}
|
|
17618
|
+
};
|
|
17619
|
+
for (const legacyKey of legacyKeys) {
|
|
17620
|
+
if (claudeSettings.enabledPlugins && legacyKey in claudeSettings.enabledPlugins) {
|
|
17621
|
+
delete claudeSettings.enabledPlugins[legacyKey];
|
|
17622
|
+
}
|
|
17623
|
+
}
|
|
17445
17624
|
await this.saveClaudeSettings(claudeSettings);
|
|
17625
|
+
const knownMarketplaces = await this.readClaudeKnownMarketplaces();
|
|
17626
|
+
knownMarketplaces[nativeTarget.namespace] = {
|
|
17627
|
+
source: marketplace.source,
|
|
17628
|
+
installLocation: nativeTarget.marketplacePath,
|
|
17629
|
+
lastUpdated: now
|
|
17630
|
+
};
|
|
17631
|
+
await this.saveClaudeKnownMarketplaces(knownMarketplaces);
|
|
17632
|
+
for (const entry of legacyEntries) {
|
|
17633
|
+
await fs22.rm(entry.installPath, { recursive: true, force: true }).catch(() => {
|
|
17634
|
+
});
|
|
17635
|
+
}
|
|
17636
|
+
for (const legacyKey of legacyKeys) {
|
|
17637
|
+
warnings.push(`Replaced legacy AgentInit Claude plugin install ${legacyKey} with ${nativeTarget.pluginKey}.`);
|
|
17638
|
+
}
|
|
17446
17639
|
installed.push({
|
|
17447
17640
|
agent: "claude",
|
|
17448
17641
|
pluginKey: nativeTarget.pluginKey,
|
|
@@ -17463,6 +17656,7 @@ class PluginManager {
|
|
|
17463
17656
|
const claudeInstalled = await this.readClaudeInstalledPlugins();
|
|
17464
17657
|
const entries = claudeInstalled.plugins[component.pluginKey] || [];
|
|
17465
17658
|
const remainingEntries = entries.filter((entry) => entry.installPath !== component.installPath);
|
|
17659
|
+
const marketplaceNamespace = component.pluginKey.includes("@") ? component.pluginKey.split("@").slice(1).join("@") : "";
|
|
17466
17660
|
if (remainingEntries.length > 0) {
|
|
17467
17661
|
claudeInstalled.plugins[component.pluginKey] = remainingEntries;
|
|
17468
17662
|
} else {
|
|
@@ -17473,8 +17667,32 @@ class PluginManager {
|
|
|
17473
17667
|
if (claudeSettings.enabledPlugins && component.pluginKey in claudeSettings.enabledPlugins) {
|
|
17474
17668
|
const { [component.pluginKey]: _removed, ...remainingEnabledPlugins } = claudeSettings.enabledPlugins;
|
|
17475
17669
|
claudeSettings.enabledPlugins = remainingEnabledPlugins;
|
|
17476
|
-
await this.saveClaudeSettings(claudeSettings);
|
|
17477
17670
|
}
|
|
17671
|
+
const namespaceStillInstalled = marketplaceNamespace ? Object.keys(claudeInstalled.plugins).some((pluginKey) => pluginKey.endsWith(`@${marketplaceNamespace}`)) : false;
|
|
17672
|
+
if (!namespaceStillInstalled && marketplaceNamespace) {
|
|
17673
|
+
if (claudeSettings.extraKnownMarketplaces && marketplaceNamespace in claudeSettings.extraKnownMarketplaces) {
|
|
17674
|
+
delete claudeSettings.extraKnownMarketplaces[marketplaceNamespace];
|
|
17675
|
+
}
|
|
17676
|
+
const knownMarketplaces = await this.readClaudeKnownMarketplaces();
|
|
17677
|
+
if (marketplaceNamespace in knownMarketplaces) {
|
|
17678
|
+
delete knownMarketplaces[marketplaceNamespace];
|
|
17679
|
+
await this.saveClaudeKnownMarketplaces(knownMarketplaces);
|
|
17680
|
+
}
|
|
17681
|
+
await fs22.rm(getClaudeMarketplaceInstallPath(marketplaceNamespace), { recursive: true, force: true }).catch(() => {
|
|
17682
|
+
});
|
|
17683
|
+
} else if (marketplaceNamespace) {
|
|
17684
|
+
const pluginName = component.pluginKey.split("@")[0] || "";
|
|
17685
|
+
const marketplacePath = getClaudeMarketplaceInstallPath(marketplaceNamespace);
|
|
17686
|
+
const manifest = await this.readClaudeMarketplaceManifest(marketplacePath);
|
|
17687
|
+
if (pluginName && manifest) {
|
|
17688
|
+
manifest.plugins = (manifest.plugins || []).filter((entry) => entry.name !== pluginName);
|
|
17689
|
+
const marketplacePluginPath = join4(marketplacePath, "plugins", pluginName);
|
|
17690
|
+
await fs22.rm(marketplacePluginPath, { recursive: true, force: true }).catch(() => {
|
|
17691
|
+
});
|
|
17692
|
+
await this.saveClaudeMarketplaceManifest(marketplacePath, manifest);
|
|
17693
|
+
}
|
|
17694
|
+
}
|
|
17695
|
+
await this.saveClaudeSettings(claudeSettings);
|
|
17478
17696
|
await fs22.rm(component.installPath, { recursive: true, force: true }).catch(() => {
|
|
17479
17697
|
});
|
|
17480
17698
|
return true;
|
|
@@ -17915,8 +18133,11 @@ ${body.trim()}
|
|
|
17915
18133
|
warnings: plugin.warnings
|
|
17916
18134
|
};
|
|
17917
18135
|
}
|
|
17918
|
-
const
|
|
17919
|
-
const
|
|
18136
|
+
const nativeClaudeTarget = await this.getClaudeNativeInstallTarget(plugin, plugin.resolvedPluginDir);
|
|
18137
|
+
const portableSkillAgents = nativeClaudeTarget ? this.getPortableSkillAgents(agents, projectPath, options2.global) : agents;
|
|
18138
|
+
const portableMcpAgents = nativeClaudeTarget ? agents.filter((agent) => agent.id !== "claude") : agents;
|
|
18139
|
+
const skillResult = await this.installPluginSkills(plugin, projectPath, portableSkillAgents, options2);
|
|
18140
|
+
const mcpResult = await this.applyPluginMcpServers(plugin, projectPath, portableMcpAgents, options2.global);
|
|
17920
18141
|
const nativePluginResult = await this.installNativeClaudePlugin(plugin, plugin.resolvedPluginDir, agents);
|
|
17921
18142
|
const installWarnings = [...plugin.warnings, ...nativePluginResult.warnings];
|
|
17922
18143
|
if (skillResult.installed.length > 0 || mcpResult.applied.length > 0 || nativePluginResult.installed.length > 0) {
|
|
@@ -17981,6 +18202,25 @@ ${body.trim()}
|
|
|
17981
18202
|
}
|
|
17982
18203
|
return { installed, skipped };
|
|
17983
18204
|
}
|
|
18205
|
+
getPortableSkillAgents(agents, projectPath, global3) {
|
|
18206
|
+
const claudeAgent = agents.find((agent) => agent.id === "claude");
|
|
18207
|
+
if (!claudeAgent || !claudeAgent.supportsSkills()) {
|
|
18208
|
+
return agents;
|
|
18209
|
+
}
|
|
18210
|
+
const claudeSkillsDir = claudeAgent.getSkillsDir(projectPath, global3);
|
|
18211
|
+
if (!claudeSkillsDir) {
|
|
18212
|
+
return agents.filter((agent) => agent.id !== "claude");
|
|
18213
|
+
}
|
|
18214
|
+
return agents.filter((agent) => {
|
|
18215
|
+
if (agent.id === "claude") {
|
|
18216
|
+
return false;
|
|
18217
|
+
}
|
|
18218
|
+
if (!agent.supportsSkills()) {
|
|
18219
|
+
return true;
|
|
18220
|
+
}
|
|
18221
|
+
return agent.getSkillsDir(projectPath, global3) !== claudeSkillsDir;
|
|
18222
|
+
});
|
|
18223
|
+
}
|
|
17984
18224
|
async applyPluginMcpServers(plugin, projectPath, agents, global3) {
|
|
17985
18225
|
const applied = [];
|
|
17986
18226
|
const skipped = [];
|
|
@@ -18245,7 +18485,7 @@ ${body.trim()}
|
|
|
18245
18485
|
return { removed: true, details };
|
|
18246
18486
|
}
|
|
18247
18487
|
}
|
|
18248
|
-
var import_gray_matter, getMarketplaceCacheDir, getRegistryPath, getClaudeInstalledPluginsPath, getClaudeSettingsPath;
|
|
18488
|
+
var import_gray_matter, getMarketplaceCacheDir, getRegistryPath, getClaudeInstalledPluginsPath, getClaudeKnownMarketplacesPath, getClaudeMarketplaceInstallPath, getClaudeSettingsPath;
|
|
18249
18489
|
var init_pluginManager = __esm(() => {
|
|
18250
18490
|
import_gray_matter = __toESM(require_gray_matter(), 1);
|
|
18251
18491
|
init_fs();
|
|
@@ -18266,6 +18506,12 @@ var init_pluginManager = __esm(() => {
|
|
|
18266
18506
|
getClaudeInstalledPluginsPath = function() {
|
|
18267
18507
|
return join4(homedir4(), ".claude", "plugins", "installed_plugins.json");
|
|
18268
18508
|
};
|
|
18509
|
+
getClaudeKnownMarketplacesPath = function() {
|
|
18510
|
+
return join4(homedir4(), ".claude", "plugins", "known_marketplaces.json");
|
|
18511
|
+
};
|
|
18512
|
+
getClaudeMarketplaceInstallPath = function(namespace) {
|
|
18513
|
+
return join4(homedir4(), ".claude", "plugins", "marketplaces", namespace);
|
|
18514
|
+
};
|
|
18269
18515
|
getClaudeSettingsPath = function() {
|
|
18270
18516
|
return join4(homedir4(), ".claude", "settings.json");
|
|
18271
18517
|
};
|
|
@@ -41981,7 +42227,8 @@ function registerRulesCommand(program2) {
|
|
|
41981
42227
|
|
|
41982
42228
|
// dist/commands/plugins.js
|
|
41983
42229
|
var import_prompts3 = __toESM(require_prompts3(), 1);
|
|
41984
|
-
import {
|
|
42230
|
+
import {homedir as homedir7} from "os";
|
|
42231
|
+
import {dirname as dirname8, relative as relative8, resolve as resolve13} from "path";
|
|
41985
42232
|
init_pluginManager();
|
|
41986
42233
|
init_agentManager();
|
|
41987
42234
|
init_marketplaceRegistry();
|
|
@@ -42439,13 +42686,45 @@ var buildGlobalPluginGroups = function(agentManager12, projectPath) {
|
|
|
42439
42686
|
existing.push(agent);
|
|
42440
42687
|
dirToAgents.set(skillsDir, existing);
|
|
42441
42688
|
}
|
|
42442
|
-
|
|
42689
|
+
const nativeGroups = Array.from(dirToAgents.entries()).map(([dir, agents]) => ({
|
|
42443
42690
|
dir,
|
|
42444
42691
|
displayDir: formatPathForDisplay(dir, projectPath),
|
|
42445
42692
|
agents,
|
|
42446
42693
|
agentNames: agents.map((agent) => agent.name),
|
|
42447
|
-
compatibleAgentNames: []
|
|
42694
|
+
compatibleAgentNames: [],
|
|
42695
|
+
kind: "native"
|
|
42448
42696
|
}));
|
|
42697
|
+
const canonicalDir = resolve13(homedir7(), ".agents/skills");
|
|
42698
|
+
const sharedAgents = agentManager12.getAllAgents().filter((agent) => agent.supportsSkills() && agent.getProjectSkillsStandard() === "agents" && !!agent.getSkillsDir(projectPath, true));
|
|
42699
|
+
const claudeGroups = nativeGroups.filter((group) => group.agents.some((agent) => agent.id === "claude"));
|
|
42700
|
+
const otherGroups = nativeGroups.filter((group) => !group.agents.some((agent) => agent.id === "claude"));
|
|
42701
|
+
if (sharedAgents.length === 0) {
|
|
42702
|
+
return [...claudeGroups, ...otherGroups];
|
|
42703
|
+
}
|
|
42704
|
+
return [
|
|
42705
|
+
{
|
|
42706
|
+
dir: canonicalDir,
|
|
42707
|
+
displayDir: formatPathForDisplay(canonicalDir, projectPath),
|
|
42708
|
+
agents: sharedAgents,
|
|
42709
|
+
agentNames: sharedAgents.map((agent) => agent.name),
|
|
42710
|
+
compatibleAgentNames: [],
|
|
42711
|
+
kind: "canonical-shared"
|
|
42712
|
+
},
|
|
42713
|
+
...claudeGroups,
|
|
42714
|
+
...otherGroups
|
|
42715
|
+
];
|
|
42716
|
+
};
|
|
42717
|
+
var shouldPreselectPluginGroup = function(group, installGlobal, preview) {
|
|
42718
|
+
if (!installGlobal) {
|
|
42719
|
+
return true;
|
|
42720
|
+
}
|
|
42721
|
+
if (group.kind === "canonical-shared") {
|
|
42722
|
+
return true;
|
|
42723
|
+
}
|
|
42724
|
+
if (preview.nativePreview) {
|
|
42725
|
+
return group.agents.some((agent) => agent.id === preview.nativePreview?.agent);
|
|
42726
|
+
}
|
|
42727
|
+
return false;
|
|
42449
42728
|
};
|
|
42450
42729
|
var getPluginGroupDescription = function(group, preview, projectPath) {
|
|
42451
42730
|
const portableSummary = getPortableComponentSummary(preview);
|
|
@@ -42512,7 +42791,7 @@ async function interactiveAgentSelect(pluginManager2, agentManager12, projectPat
|
|
|
42512
42791
|
title: `${group.displayDir} -> ${getAgentLabel(group.agents.map((agent) => agent.id), agentManager12)}${compatible}`,
|
|
42513
42792
|
description: getPluginGroupDescription(group, preview, projectPath),
|
|
42514
42793
|
value: group.agents.map((agent) => agent.id),
|
|
42515
|
-
selected:
|
|
42794
|
+
selected: shouldPreselectPluginGroup(group, installGlobal, preview)
|
|
42516
42795
|
};
|
|
42517
42796
|
})
|
|
42518
42797
|
});
|
|
@@ -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;AA4BpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkT7D"}
|
package/dist/commands/plugins.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ora from 'ora';
|
|
2
2
|
import prompts from 'prompts';
|
|
3
|
-
import {
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { dirname, relative, resolve } from 'path';
|
|
4
5
|
import { green, dim, bold, cyan, yellow, orange } from '../utils/colors.js';
|
|
5
6
|
import { logger } from '../utils/logger.js';
|
|
6
7
|
import { PluginManager } from '../core/pluginManager.js';
|
|
@@ -530,13 +531,47 @@ function buildGlobalPluginGroups(agentManager, projectPath) {
|
|
|
530
531
|
existing.push(agent);
|
|
531
532
|
dirToAgents.set(skillsDir, existing);
|
|
532
533
|
}
|
|
533
|
-
|
|
534
|
+
const nativeGroups = Array.from(dirToAgents.entries()).map(([dir, agents]) => ({
|
|
534
535
|
dir,
|
|
535
536
|
displayDir: formatPathForDisplay(dir, projectPath),
|
|
536
537
|
agents,
|
|
537
538
|
agentNames: agents.map(agent => agent.name),
|
|
538
539
|
compatibleAgentNames: [],
|
|
540
|
+
kind: 'native',
|
|
539
541
|
}));
|
|
542
|
+
const canonicalDir = resolve(homedir(), '.agents/skills');
|
|
543
|
+
const sharedAgents = agentManager.getAllAgents().filter(agent => agent.supportsSkills() &&
|
|
544
|
+
agent.getProjectSkillsStandard() === 'agents' &&
|
|
545
|
+
!!agent.getSkillsDir(projectPath, true));
|
|
546
|
+
const claudeGroups = nativeGroups.filter(group => group.agents.some(agent => agent.id === 'claude'));
|
|
547
|
+
const otherGroups = nativeGroups.filter(group => !group.agents.some(agent => agent.id === 'claude'));
|
|
548
|
+
if (sharedAgents.length === 0) {
|
|
549
|
+
return [...claudeGroups, ...otherGroups];
|
|
550
|
+
}
|
|
551
|
+
return [
|
|
552
|
+
{
|
|
553
|
+
dir: canonicalDir,
|
|
554
|
+
displayDir: formatPathForDisplay(canonicalDir, projectPath),
|
|
555
|
+
agents: sharedAgents,
|
|
556
|
+
agentNames: sharedAgents.map(agent => agent.name),
|
|
557
|
+
compatibleAgentNames: [],
|
|
558
|
+
kind: 'canonical-shared',
|
|
559
|
+
},
|
|
560
|
+
...claudeGroups,
|
|
561
|
+
...otherGroups,
|
|
562
|
+
];
|
|
563
|
+
}
|
|
564
|
+
function shouldPreselectPluginGroup(group, installGlobal, preview) {
|
|
565
|
+
if (!installGlobal) {
|
|
566
|
+
return true;
|
|
567
|
+
}
|
|
568
|
+
if (group.kind === 'canonical-shared') {
|
|
569
|
+
return true;
|
|
570
|
+
}
|
|
571
|
+
if (preview.nativePreview) {
|
|
572
|
+
return group.agents.some(agent => agent.id === preview.nativePreview?.agent);
|
|
573
|
+
}
|
|
574
|
+
return false;
|
|
540
575
|
}
|
|
541
576
|
function getPluginGroupDescription(group, preview, projectPath) {
|
|
542
577
|
const portableSummary = getPortableComponentSummary(preview);
|
|
@@ -614,7 +649,7 @@ async function interactiveAgentSelect(pluginManager, agentManager, projectPath,
|
|
|
614
649
|
title: `${group.displayDir} -> ${getAgentLabel(group.agents.map(agent => agent.id), agentManager)}${compatible}`,
|
|
615
650
|
description: getPluginGroupDescription(group, preview, projectPath),
|
|
616
651
|
value: group.agents.map(agent => agent.id),
|
|
617
|
-
selected:
|
|
652
|
+
selected: shouldPreselectPluginGroup(group, installGlobal, preview),
|
|
618
653
|
};
|
|
619
654
|
}),
|
|
620
655
|
});
|