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 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` so installed Claude plugins actually activate
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` still installs portable skills and MCP servers for the selected agents. If Claude Code-native components are also present, AgentInit previews that compatibility before target selection. The native plugin payload installs only when `claude` is one of the selected targets; otherwise AgentInit warns that the Claude-only parts were skipped. When the native payload is installed, AgentInit reminds you to run `/reload-plugins`.
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] ? ["prompts"] : [],
17325
- ...featureChecks[4] ? ["schemas"] : [],
17326
- ...featureChecks[5] ? ["scripts"] : [],
17327
- ...featureChecks[6] ? ["templates"] : []
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 = `agentinit-${this.slugifyPluginNamespace(baseNamespace)}`;
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 conflictingKey = Object.keys(claudeInstalled.plugins).find((key) => key !== nativeTarget.pluginKey && key.startsWith(`${plugin.name}@`));
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 skillResult = await this.installPluginSkills(plugin, projectPath, agents, options2);
17919
- const mcpResult = await this.applyPluginMcpServers(plugin, projectPath, agents, options2.global);
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 {dirname as dirname8, relative as relative8} from "path";
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
- return Array.from(dirToAgents.entries()).map(([dir, agents]) => ({
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: true
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;AA0BpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkT7D"}
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"}
@@ -1,6 +1,7 @@
1
1
  import ora from 'ora';
2
2
  import prompts from 'prompts';
3
- import { dirname, relative } from 'path';
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
- return Array.from(dirToAgents.entries()).map(([dir, agents]) => ({
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: true,
652
+ selected: shouldPreselectPluginGroup(group, installGlobal, preview),
618
653
  };
619
654
  }),
620
655
  });