agentinit 1.13.3 → 1.14.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/README.md +18 -1
  3. package/dist/agents/Agent.d.ts +5 -1
  4. package/dist/agents/Agent.d.ts.map +1 -1
  5. package/dist/agents/Agent.js +6 -0
  6. package/dist/agents/Agent.js.map +1 -1
  7. package/dist/agents/HermesAgent.d.ts +14 -0
  8. package/dist/agents/HermesAgent.d.ts.map +1 -0
  9. package/dist/agents/HermesAgent.js +64 -0
  10. package/dist/agents/HermesAgent.js.map +1 -0
  11. package/dist/agents/OpenClawAgent.d.ts +14 -0
  12. package/dist/agents/OpenClawAgent.d.ts.map +1 -0
  13. package/dist/agents/OpenClawAgent.js +64 -0
  14. package/dist/agents/OpenClawAgent.js.map +1 -0
  15. package/dist/cli.js +601 -252
  16. package/dist/commands/apply.js +2 -2
  17. package/dist/commands/apply.js.map +1 -1
  18. package/dist/commands/config.js +1 -1
  19. package/dist/commands/config.js.map +1 -1
  20. package/dist/commands/detect.js +1 -1
  21. package/dist/commands/detect.js.map +1 -1
  22. package/dist/commands/init.js +1 -1
  23. package/dist/commands/init.js.map +1 -1
  24. package/dist/commands/plugins.js +140 -51
  25. package/dist/commands/plugins.js.map +1 -1
  26. package/dist/commands/revert.js +1 -1
  27. package/dist/commands/revert.js.map +1 -1
  28. package/dist/commands/rules.js +3 -3
  29. package/dist/commands/rules.js.map +1 -1
  30. package/dist/commands/skills.js +4 -4
  31. package/dist/commands/skills.js.map +1 -1
  32. package/dist/commands/subagents.js +1 -1
  33. package/dist/commands/subagents.js.map +1 -1
  34. package/dist/commands/sync.js +1 -1
  35. package/dist/commands/sync.js.map +1 -1
  36. package/dist/commands/verifyMcp.js +1 -1
  37. package/dist/commands/verifyMcp.js.map +1 -1
  38. package/dist/core/agentDetector.d.ts +8 -2
  39. package/dist/core/agentDetector.d.ts.map +1 -1
  40. package/dist/core/agentDetector.js +32 -4
  41. package/dist/core/agentDetector.js.map +1 -1
  42. package/dist/core/agentManager.d.ts +10 -5
  43. package/dist/core/agentManager.d.ts.map +1 -1
  44. package/dist/core/agentManager.js +25 -9
  45. package/dist/core/agentManager.js.map +1 -1
  46. package/dist/core/mcpClient.js +3 -3
  47. package/dist/core/mcpClient.js.map +1 -1
  48. package/dist/core/pluginManager.d.ts +1 -0
  49. package/dist/core/pluginManager.d.ts.map +1 -1
  50. package/dist/core/pluginManager.js +9 -2
  51. package/dist/core/pluginManager.js.map +1 -1
  52. package/dist/types/index.d.ts +2 -0
  53. package/dist/types/index.d.ts.map +1 -1
  54. package/dist/types/index.js.map +1 -1
  55. package/dist/utils/colors.d.ts +10 -0
  56. package/dist/utils/colors.d.ts.map +1 -0
  57. package/dist/utils/colors.js +27 -0
  58. package/dist/utils/colors.js.map +1 -0
  59. package/dist/utils/logger.d.ts +16 -0
  60. package/dist/utils/logger.d.ts.map +1 -1
  61. package/dist/utils/logger.js +59 -5
  62. package/dist/utils/logger.js.map +1 -1
  63. package/dist/utils/symbols.d.ts +27 -0
  64. package/dist/utils/symbols.d.ts.map +1 -0
  65. package/dist/utils/symbols.js +27 -0
  66. package/dist/utils/symbols.js.map +1 -0
  67. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -8510,6 +8510,74 @@ async function createRelativeSymlink(target, linkPath) {
8510
8510
  var init_fs = __esm(() => {
8511
8511
  });
8512
8512
 
8513
+ // dist/utils/paths.js
8514
+ import {resolve as resolve2, join as join2} from "path";
8515
+ import {homedir} from "os";
8516
+ function getHomeDirectory() {
8517
+ return homedir();
8518
+ }
8519
+ function getPlatform() {
8520
+ switch (process.platform) {
8521
+ case "win32":
8522
+ return "windows";
8523
+ case "darwin":
8524
+ return "darwin";
8525
+ case "linux":
8526
+ return "linux";
8527
+ default:
8528
+ return "linux";
8529
+ }
8530
+ }
8531
+ function expandTilde(path) {
8532
+ if (path.startsWith("~/")) {
8533
+ return join2(getHomeDirectory(), path.slice(2));
8534
+ }
8535
+ if (path === "~") {
8536
+ return getHomeDirectory();
8537
+ }
8538
+ return path;
8539
+ }
8540
+ function getEnvironmentPath(key) {
8541
+ return process.env[key];
8542
+ }
8543
+ function resolveGlobalConfigPath(globalConfigPath, globalConfigPaths) {
8544
+ if (globalConfigPath) {
8545
+ return expandTilde(globalConfigPath);
8546
+ }
8547
+ if (globalConfigPaths) {
8548
+ const platform2 = getPlatform();
8549
+ const platformPath = globalConfigPaths[platform2];
8550
+ if (platformPath) {
8551
+ return expandTilde(platformPath);
8552
+ }
8553
+ }
8554
+ return null;
8555
+ }
8556
+ function getWindowsAppDataPaths() {
8557
+ return {
8558
+ roaming: getEnvironmentPath("APPDATA"),
8559
+ local: getEnvironmentPath("LOCALAPPDATA"),
8560
+ userProfile: getEnvironmentPath("USERPROFILE")
8561
+ };
8562
+ }
8563
+ function resolveEnvironmentVariables(path) {
8564
+ if (getPlatform() === "windows") {
8565
+ const appDataPaths = getWindowsAppDataPaths();
8566
+ return path.replace(/%APPDATA%/g, appDataPaths.roaming || "").replace(/%LOCALAPPDATA%/g, appDataPaths.local || "").replace(/%USERPROFILE%/g, appDataPaths.userProfile || "");
8567
+ }
8568
+ return path;
8569
+ }
8570
+ function getFullGlobalConfigPath(globalConfigPath, globalConfigPaths) {
8571
+ const path = resolveGlobalConfigPath(globalConfigPath, globalConfigPaths);
8572
+ if (!path) {
8573
+ return null;
8574
+ }
8575
+ const resolvedPath = resolveEnvironmentVariables(path);
8576
+ return resolve2(resolvedPath);
8577
+ }
8578
+ var init_paths = __esm(() => {
8579
+ });
8580
+
8513
8581
  // node_modules/kind-of/index.js
8514
8582
  var require_kind_of = __commonJS((exports, module) => {
8515
8583
  var ctorName = function(val) {
@@ -11935,74 +12003,6 @@ var require_gray_matter = __commonJS((exports, module) => {
11935
12003
  module.exports = matter;
11936
12004
  });
11937
12005
 
11938
- // dist/utils/paths.js
11939
- import {resolve as resolve5, join as join2} from "path";
11940
- import {homedir} from "os";
11941
- function getHomeDirectory() {
11942
- return homedir();
11943
- }
11944
- function getPlatform() {
11945
- switch (process.platform) {
11946
- case "win32":
11947
- return "windows";
11948
- case "darwin":
11949
- return "darwin";
11950
- case "linux":
11951
- return "linux";
11952
- default:
11953
- return "linux";
11954
- }
11955
- }
11956
- function expandTilde(path) {
11957
- if (path.startsWith("~/")) {
11958
- return join2(getHomeDirectory(), path.slice(2));
11959
- }
11960
- if (path === "~") {
11961
- return getHomeDirectory();
11962
- }
11963
- return path;
11964
- }
11965
- function getEnvironmentPath(key) {
11966
- return process.env[key];
11967
- }
11968
- function resolveGlobalConfigPath(globalConfigPath, globalConfigPaths) {
11969
- if (globalConfigPath) {
11970
- return expandTilde(globalConfigPath);
11971
- }
11972
- if (globalConfigPaths) {
11973
- const platform2 = getPlatform();
11974
- const platformPath = globalConfigPaths[platform2];
11975
- if (platformPath) {
11976
- return expandTilde(platformPath);
11977
- }
11978
- }
11979
- return null;
11980
- }
11981
- function getWindowsAppDataPaths() {
11982
- return {
11983
- roaming: getEnvironmentPath("APPDATA"),
11984
- local: getEnvironmentPath("LOCALAPPDATA"),
11985
- userProfile: getEnvironmentPath("USERPROFILE")
11986
- };
11987
- }
11988
- function resolveEnvironmentVariables(path) {
11989
- if (getPlatform() === "windows") {
11990
- const appDataPaths = getWindowsAppDataPaths();
11991
- return path.replace(/%APPDATA%/g, appDataPaths.roaming || "").replace(/%LOCALAPPDATA%/g, appDataPaths.local || "").replace(/%USERPROFILE%/g, appDataPaths.userProfile || "");
11992
- }
11993
- return path;
11994
- }
11995
- function getFullGlobalConfigPath(globalConfigPath, globalConfigPaths) {
11996
- const path = resolveGlobalConfigPath(globalConfigPath, globalConfigPaths);
11997
- if (!path) {
11998
- return null;
11999
- }
12000
- const resolvedPath = resolveEnvironmentVariables(path);
12001
- return resolve5(resolvedPath);
12002
- }
12003
- var init_paths = __esm(() => {
12004
- });
12005
-
12006
12006
  // node_modules/contextcalc/dist/lib/index.js
12007
12007
  import {get_encoding} from "tiktoken";
12008
12008
  async function isBinaryFile(filePath) {
@@ -12389,6 +12389,9 @@ class Agent {
12389
12389
  get name() {
12390
12390
  return this.definition.name;
12391
12391
  }
12392
+ getDetectionScope() {
12393
+ return this.definition.detectionScope || "project";
12394
+ }
12392
12395
  get capabilities() {
12393
12396
  return this.definition.capabilities;
12394
12397
  }
@@ -15899,6 +15902,140 @@ var init_CopilotAgent = __esm(() => {
15899
15902
  init_fs();
15900
15903
  });
15901
15904
 
15905
+ // dist/agents/OpenClawAgent.js
15906
+ class OpenClawAgent extends Agent {
15907
+ constructor() {
15908
+ const definition = {
15909
+ id: "openclaw",
15910
+ name: "OpenClaw",
15911
+ capabilities: {
15912
+ mcp: {
15913
+ stdio: false,
15914
+ http: false,
15915
+ sse: false
15916
+ },
15917
+ rules: false,
15918
+ hooks: false,
15919
+ commands: false,
15920
+ subagents: false,
15921
+ statusline: false,
15922
+ skills: true
15923
+ },
15924
+ configFiles: [],
15925
+ nativeConfigPath: ".openclaw/config.json",
15926
+ detectionScope: "environment",
15927
+ skillPaths: {
15928
+ project: ".agents/skills/",
15929
+ global: "~/.openclaw/skills/"
15930
+ },
15931
+ projectStandards: {
15932
+ skills: "agents"
15933
+ }
15934
+ };
15935
+ super(definition);
15936
+ }
15937
+ async detectPresence(_projectPath) {
15938
+ const openClawHome = expandTilde("~/.openclaw");
15939
+ if (!await fileExists(openClawHome)) {
15940
+ return null;
15941
+ }
15942
+ return {
15943
+ agent: this,
15944
+ configPath: openClawHome
15945
+ };
15946
+ }
15947
+ async applyMCPConfig(_projectPath, _servers) {
15948
+ throw new Error("OpenClaw does not support MCP configuration.");
15949
+ }
15950
+ async removeMCPServer(_projectPath, _serverName) {
15951
+ throw new Error("OpenClaw does not support MCP configuration.");
15952
+ }
15953
+ async applyRulesConfig(_configPath, _rules, _existingContent) {
15954
+ throw new Error("OpenClaw does not support rules configuration.");
15955
+ }
15956
+ extractExistingRules(_content) {
15957
+ return [];
15958
+ }
15959
+ extractExistingSections(_content) {
15960
+ return [];
15961
+ }
15962
+ generateRulesContent(_sections) {
15963
+ return "";
15964
+ }
15965
+ }
15966
+ var init_OpenClawAgent = __esm(() => {
15967
+ init_Agent();
15968
+ init_fs();
15969
+ init_paths();
15970
+ });
15971
+
15972
+ // dist/agents/HermesAgent.js
15973
+ class HermesAgent extends Agent {
15974
+ constructor() {
15975
+ const definition = {
15976
+ id: "hermes",
15977
+ name: "Hermes",
15978
+ capabilities: {
15979
+ mcp: {
15980
+ stdio: false,
15981
+ http: false,
15982
+ sse: false
15983
+ },
15984
+ rules: false,
15985
+ hooks: false,
15986
+ commands: false,
15987
+ subagents: false,
15988
+ statusline: false,
15989
+ skills: true
15990
+ },
15991
+ configFiles: [],
15992
+ nativeConfigPath: ".hermes/config.json",
15993
+ detectionScope: "environment",
15994
+ skillPaths: {
15995
+ project: ".agents/skills/",
15996
+ global: "~/.hermes/skills/"
15997
+ },
15998
+ projectStandards: {
15999
+ skills: "agents"
16000
+ }
16001
+ };
16002
+ super(definition);
16003
+ }
16004
+ async detectPresence(_projectPath) {
16005
+ const hermesHome = expandTilde("~/.hermes");
16006
+ if (!await fileExists(hermesHome)) {
16007
+ return null;
16008
+ }
16009
+ return {
16010
+ agent: this,
16011
+ configPath: hermesHome
16012
+ };
16013
+ }
16014
+ async applyMCPConfig(_projectPath, _servers) {
16015
+ throw new Error("Hermes does not support MCP configuration.");
16016
+ }
16017
+ async removeMCPServer(_projectPath, _serverName) {
16018
+ throw new Error("Hermes does not support MCP configuration.");
16019
+ }
16020
+ async applyRulesConfig(_configPath, _rules, _existingContent) {
16021
+ throw new Error("Hermes does not support rules configuration.");
16022
+ }
16023
+ extractExistingRules(_content) {
16024
+ return [];
16025
+ }
16026
+ extractExistingSections(_content) {
16027
+ return [];
16028
+ }
16029
+ generateRulesContent(_sections) {
16030
+ return "";
16031
+ }
16032
+ }
16033
+ var init_HermesAgent = __esm(() => {
16034
+ init_Agent();
16035
+ init_fs();
16036
+ init_paths();
16037
+ });
16038
+
15902
16039
  // dist/agents/AiderAgent.js
15903
16040
  class AiderAgent extends MarkdownRulesAgent {
15904
16041
  constructor() {
@@ -16493,7 +16630,9 @@ class AgentManager {
16493
16630
  new WindsurfAgent,
16494
16631
  new RooCodeAgent,
16495
16632
  new ZedAgent,
16496
- new DroidAgent
16633
+ new DroidAgent,
16634
+ new OpenClawAgent,
16635
+ new HermesAgent
16497
16636
  ];
16498
16637
  }
16499
16638
  getAllAgents() {
@@ -16505,9 +16644,18 @@ class AgentManager {
16505
16644
  getSupportedAgentIds() {
16506
16645
  return this.agents.map((agent) => agent.id);
16507
16646
  }
16508
- async detectAgents(projectPath) {
16647
+ shouldIncludeForDetection(agent, options2) {
16648
+ if (options2.includeEnvironment) {
16649
+ return true;
16650
+ }
16651
+ return agent.getDetectionScope() !== "environment";
16652
+ }
16653
+ async detectAgents(projectPath, options2 = {}) {
16509
16654
  const results = [];
16510
16655
  for (const agent of this.agents) {
16656
+ if (!this.shouldIncludeForDetection(agent, options2)) {
16657
+ continue;
16658
+ }
16511
16659
  const detection = await agent.detectPresence(projectPath);
16512
16660
  if (detection) {
16513
16661
  results.push(detection);
@@ -16515,27 +16663,30 @@ class AgentManager {
16515
16663
  }
16516
16664
  return results;
16517
16665
  }
16518
- async detectAgentById(projectPath, agentId) {
16666
+ async detectAgentById(projectPath, agentId, options2 = {}) {
16519
16667
  const agent = this.getAgentById(agentId);
16520
16668
  if (!agent) {
16521
16669
  return null;
16522
16670
  }
16671
+ if (!this.shouldIncludeForDetection(agent, options2)) {
16672
+ return null;
16673
+ }
16523
16674
  return await agent.detectPresence(projectPath);
16524
16675
  }
16525
- async getPrimaryAgent(projectPath) {
16526
- const detectedAgents = await this.detectAgents(projectPath);
16676
+ async getPrimaryAgent(projectPath, options2 = {}) {
16677
+ const detectedAgents = await this.detectAgents(projectPath, options2);
16527
16678
  return detectedAgents.length > 0 ? detectedAgents[0] : null;
16528
16679
  }
16529
16680
  registerAgent(agent) {
16530
16681
  this.agents = this.agents.filter((existing) => existing.id !== agent.id);
16531
16682
  this.agents.push(agent);
16532
16683
  }
16533
- async hasAnyAgents(projectPath) {
16534
- const detected = await this.detectAgents(projectPath);
16684
+ async hasAnyAgents(projectPath, options2 = {}) {
16685
+ const detected = await this.detectAgents(projectPath, options2);
16535
16686
  return detected.length > 0;
16536
16687
  }
16537
- async getDetectionSummary(projectPath) {
16538
- const detected = await this.detectAgents(projectPath);
16688
+ async getDetectionSummary(projectPath, options2 = {}) {
16689
+ const detected = await this.detectAgents(projectPath, options2);
16539
16690
  if (detected.length === 0) {
16540
16691
  return "No AI coding agents detected in this project.";
16541
16692
  }
@@ -16557,6 +16708,8 @@ var init_agentManager = __esm(() => {
16557
16708
  init_CursorAgent();
16558
16709
  init_DroidAgent();
16559
16710
  init_CopilotAgent();
16711
+ init_OpenClawAgent();
16712
+ init_HermesAgent();
16560
16713
  init_AiderAgent();
16561
16714
  init_ClineAgent();
16562
16715
  init_WindsurfAgent();
@@ -16708,7 +16861,7 @@ __export(exports_pluginManager, {
16708
16861
  }
16709
16862
  });
16710
16863
  import {resolve as resolve7, join as join3, basename as basename2, relative as relative2, dirname as dirname2} from "path";
16711
- import {promises as fs18} from "fs";
16864
+ import {promises as fs20} from "fs";
16712
16865
  import {homedir as homedir3} from "os";
16713
16866
 
16714
16867
  class MarketplacePluginNotFoundError extends Error {
@@ -16743,7 +16896,7 @@ class PluginManager {
16743
16896
  }
16744
16897
  async cleanupLoadedPluginContext(context) {
16745
16898
  if (context?.tempDir) {
16746
- await fs18.rm(context.tempDir, { recursive: true, force: true }).catch(() => {
16899
+ await fs20.rm(context.tempDir, { recursive: true, force: true }).catch(() => {
16747
16900
  });
16748
16901
  }
16749
16902
  }
@@ -16814,6 +16967,12 @@ class PluginManager {
16814
16967
  }
16815
16968
  return `https://github.com/${source.owner}/${source.repo}`;
16816
16969
  }
16970
+ getGitHubFallbackTrust(source) {
16971
+ if (source.owner === "openai" && source.repo === "codex-plugin-cc") {
16972
+ return "verified";
16973
+ }
16974
+ return "unverified";
16975
+ }
16817
16976
  async resolvePreparedPluginDir(pluginDir, source) {
16818
16977
  const claudeMarketplaceManifestPath = join3(pluginDir, ".claude-plugin", "marketplace.json");
16819
16978
  if (!await fileExists(claudeMarketplaceManifestPath)) {
@@ -16894,12 +17053,13 @@ class PluginManager {
16894
17053
  throw error;
16895
17054
  }
16896
17055
  const fallbackUrl = this.formatGitHubRepoUrl(fallbackSource) || fallbackSource.url.replace(/\.git$/, "");
17056
+ const fallbackTrust = this.getGitHubFallbackTrust(fallbackSource);
16897
17057
  resolutionWarnings.push(error.message);
16898
- resolutionWarnings.push(`Marketplace lookup failed; trying unverified GitHub repository ${fallbackUrl} instead.`);
17058
+ resolutionWarnings.push(`Marketplace lookup failed; trying ${fallbackTrust} GitHub repository ${fallbackUrl} instead.`);
16899
17059
  try {
16900
17060
  tempDir = await this.skillsManager.cloneRepo(fallbackSource.url);
16901
17061
  } catch (fallbackError) {
16902
- throw new Error(`${error.message} Tried unverified GitHub repository ${fallbackUrl} but failed: ${fallbackError instanceof Error ? fallbackError.message : "Unknown error"}`);
17062
+ throw new Error(`${error.message} Tried ${fallbackTrust} GitHub repository ${fallbackUrl} but failed: ${fallbackError instanceof Error ? fallbackError.message : "Unknown error"}`);
16903
17063
  }
16904
17064
  effectiveSource = {
16905
17065
  ...fallbackSource,
@@ -17070,10 +17230,10 @@ class PluginManager {
17070
17230
  warnings.push(`Skipped native Claude plugin install because Claude already has "${plugin.name}" installed as ${conflictingKey}.`);
17071
17231
  return { installed, skipped, warnings };
17072
17232
  }
17073
- await fs18.rm(nativeTarget.installPath, { recursive: true, force: true }).catch(() => {
17233
+ await fs20.rm(nativeTarget.installPath, { recursive: true, force: true }).catch(() => {
17074
17234
  });
17075
- await fs18.mkdir(dirname2(nativeTarget.installPath), { recursive: true });
17076
- await fs18.cp(pluginDir, nativeTarget.installPath, { recursive: true, dereference: true });
17235
+ await fs20.mkdir(dirname2(nativeTarget.installPath), { recursive: true });
17236
+ await fs20.cp(pluginDir, nativeTarget.installPath, { recursive: true, dereference: true });
17077
17237
  const now = new Date().toISOString();
17078
17238
  claudeInstalled.plugins[nativeTarget.pluginKey] = [{
17079
17239
  scope: "user",
@@ -17121,7 +17281,7 @@ class PluginManager {
17121
17281
  claudeSettings.enabledPlugins = remainingEnabledPlugins;
17122
17282
  await this.saveClaudeSettings(claudeSettings);
17123
17283
  }
17124
- await fs18.rm(component.installPath, { recursive: true, force: true }).catch(() => {
17284
+ await fs20.rm(component.installPath, { recursive: true, force: true }).catch(() => {
17125
17285
  });
17126
17286
  return true;
17127
17287
  }
@@ -17197,7 +17357,7 @@ class PluginManager {
17197
17357
  const cacheMetaPath = join3(cacheDir, ".agentinit-cache-meta.json");
17198
17358
  if (await fileExists(cacheMetaPath)) {
17199
17359
  try {
17200
- const meta = JSON.parse(await fs18.readFile(cacheMetaPath, "utf8"));
17360
+ const meta = JSON.parse(await fs20.readFile(cacheMetaPath, "utf8"));
17201
17361
  const age = Date.now() - (meta.fetchedAt || 0);
17202
17362
  if (age < registry.cacheTtlMs) {
17203
17363
  return cacheDir;
@@ -17212,22 +17372,22 @@ class PluginManager {
17212
17372
  try {
17213
17373
  await exec("git", ["pull", "--ff-only"], { cwd: cacheDir, timeout: 30000 });
17214
17374
  } catch {
17215
- await fs18.rm(cacheDir, { recursive: true, force: true });
17375
+ await fs20.rm(cacheDir, { recursive: true, force: true });
17216
17376
  await this.cloneMarketplace(registry.repoUrl, cacheDir);
17217
17377
  }
17218
17378
  } else {
17219
17379
  await this.cloneMarketplace(registry.repoUrl, cacheDir);
17220
17380
  }
17221
- await fs18.mkdir(cacheDir, { recursive: true });
17222
- await fs18.writeFile(cacheMetaPath, JSON.stringify({ fetchedAt: Date.now() }));
17381
+ await fs20.mkdir(cacheDir, { recursive: true });
17382
+ await fs20.writeFile(cacheMetaPath, JSON.stringify({ fetchedAt: Date.now() }));
17223
17383
  return cacheDir;
17224
17384
  }
17225
17385
  async cloneMarketplace(repoUrl, dest) {
17226
- await fs18.mkdir(dest, { recursive: true });
17386
+ await fs20.mkdir(dest, { recursive: true });
17227
17387
  const { execFile } = await import("child_process");
17228
17388
  const { promisify } = await import("util");
17229
17389
  const exec = promisify(execFile);
17230
- await fs18.rm(dest, { recursive: true, force: true }).catch(() => {
17390
+ await fs20.rm(dest, { recursive: true, force: true }).catch(() => {
17231
17391
  });
17232
17392
  await exec("git", ["clone", "--depth", "1", repoUrl, dest], { timeout: 60000 });
17233
17393
  }
@@ -17272,7 +17432,7 @@ class PluginManager {
17272
17432
  let version = "0.0.0";
17273
17433
  if (await fileExists(manifestPath)) {
17274
17434
  try {
17275
- const manifest = JSON.parse(await fs18.readFile(manifestPath, "utf8"));
17435
+ const manifest = JSON.parse(await fs20.readFile(manifestPath, "utf8"));
17276
17436
  name = manifest.name || entry;
17277
17437
  description = manifest.description || "";
17278
17438
  version = manifest.version || "0.0.0";
@@ -17282,7 +17442,7 @@ class PluginManager {
17282
17442
  const skillMdPath = join3(entryPath, "SKILL.md");
17283
17443
  if (await fileExists(skillMdPath)) {
17284
17444
  try {
17285
- const parsed = import_gray_matter.default(await fs18.readFile(skillMdPath, "utf8"));
17445
+ const parsed = import_gray_matter.default(await fs20.readFile(skillMdPath, "utf8"));
17286
17446
  if (parsed.data.name)
17287
17447
  name = parsed.data.name;
17288
17448
  if (parsed.data.description)
@@ -17293,7 +17453,7 @@ class PluginManager {
17293
17453
  const mcpPath = join3(entryPath, ".mcp.json");
17294
17454
  if (await fileExists(mcpPath)) {
17295
17455
  try {
17296
- const mcpConfig = JSON.parse(await fs18.readFile(mcpPath, "utf8"));
17456
+ const mcpConfig = JSON.parse(await fs20.readFile(mcpPath, "utf8"));
17297
17457
  const serverNames = Object.keys(mcpConfig.mcpServers || mcpConfig);
17298
17458
  if (serverNames.length > 0) {
17299
17459
  description = `MCP server(s): ${serverNames.join(", ")}`;
@@ -17748,7 +17908,7 @@ ${body.trim()}
17748
17908
  }
17749
17909
  if (!removedSkillPaths.has(skill.path)) {
17750
17910
  try {
17751
- await fs18.rm(skill.path, { recursive: true, force: true });
17911
+ await fs20.rm(skill.path, { recursive: true, force: true });
17752
17912
  removedSkillPaths.add(skill.path);
17753
17913
  } catch {
17754
17914
  details.push(`Could not remove skill path: ${skill.path}`);
@@ -17757,7 +17917,7 @@ ${body.trim()}
17757
17917
  }
17758
17918
  if (skill.canonicalPath && skill.canonicalPath !== skill.path && !removedCanonicalPaths.has(skill.canonicalPath) && !sharedCanonicalPath) {
17759
17919
  try {
17760
- await fs18.rm(skill.canonicalPath, { recursive: true, force: true });
17920
+ await fs20.rm(skill.canonicalPath, { recursive: true, force: true });
17761
17921
  removedCanonicalPaths.add(skill.canonicalPath);
17762
17922
  } catch {
17763
17923
  details.push(`Could not remove canonical skill path: ${skill.canonicalPath}`);
@@ -17880,7 +18040,7 @@ var init_pluginManager = __esm(() => {
17880
18040
 
17881
18041
  // dist/core/skillsManager.js
17882
18042
  import {resolve as resolve8, join as join4, relative as relative3} from "path";
17883
- import {promises as fs20} from "fs";
18043
+ import {promises as fs22} from "fs";
17884
18044
  import {homedir as homedir4, tmpdir} from "os";
17885
18045
  import {execFile} from "child_process";
17886
18046
  import {promisify} from "util";
@@ -18022,14 +18182,14 @@ class SkillsManager {
18022
18182
  return skills;
18023
18183
  }
18024
18184
  async cloneRepo(url) {
18025
- const tempDir = await fs20.mkdtemp(join4(tmpdir(), "agentinit-skills-"));
18026
- await fs20.rm(tempDir, { recursive: true, force: true });
18185
+ const tempDir = await fs22.mkdtemp(join4(tmpdir(), "agentinit-skills-"));
18186
+ await fs22.rm(tempDir, { recursive: true, force: true });
18027
18187
  try {
18028
18188
  await execFileAsync("git", ["clone", "--depth", "1", url, tempDir], {
18029
18189
  timeout: 60000
18030
18190
  });
18031
18191
  } catch (error) {
18032
- await fs20.rm(tempDir, { recursive: true, force: true }).catch(() => {
18192
+ await fs22.rm(tempDir, { recursive: true, force: true }).catch(() => {
18033
18193
  });
18034
18194
  throw new Error(`Failed to clone ${url}: ${error.message}`);
18035
18195
  }
@@ -18123,7 +18283,7 @@ class SkillsManager {
18123
18283
  return { skills, warnings };
18124
18284
  } finally {
18125
18285
  if (tempDir) {
18126
- await fs20.rm(tempDir, { recursive: true, force: true }).catch(() => {
18286
+ await fs22.rm(tempDir, { recursive: true, force: true }).catch(() => {
18127
18287
  });
18128
18288
  }
18129
18289
  }
@@ -18144,26 +18304,26 @@ class SkillsManager {
18144
18304
  async installSkill(skillPath, skillName, targetDir, copy = false) {
18145
18305
  const normalizedSkillName = this.normalizeSkillName(skillName);
18146
18306
  const destPath = this.resolveInstallPath(targetDir, normalizedSkillName);
18147
- await fs20.mkdir(resolve8(targetDir), { recursive: true });
18307
+ await fs22.mkdir(resolve8(targetDir), { recursive: true });
18148
18308
  if (await fileExists(destPath)) {
18149
- await fs20.rm(destPath, { recursive: true, force: true });
18309
+ await fs22.rm(destPath, { recursive: true, force: true });
18150
18310
  }
18151
18311
  if (copy) {
18152
18312
  await this.copyDir(skillPath, destPath);
18153
18313
  } else {
18154
- await fs20.symlink(skillPath, destPath, "dir");
18314
+ await fs22.symlink(skillPath, destPath, "dir");
18155
18315
  }
18156
18316
  return destPath;
18157
18317
  }
18158
18318
  async installSkillFromContent(skillName, skillContent, targetDir) {
18159
18319
  const normalizedSkillName = this.normalizeSkillName(skillName);
18160
18320
  const destPath = this.resolveInstallPath(targetDir, normalizedSkillName);
18161
- await fs20.mkdir(resolve8(targetDir), { recursive: true });
18321
+ await fs22.mkdir(resolve8(targetDir), { recursive: true });
18162
18322
  if (await fileExists(destPath)) {
18163
- await fs20.rm(destPath, { recursive: true, force: true });
18323
+ await fs22.rm(destPath, { recursive: true, force: true });
18164
18324
  }
18165
- await fs20.mkdir(destPath, { recursive: true });
18166
- await fs20.writeFile(join4(destPath, "SKILL.md"), skillContent, "utf8");
18325
+ await fs22.mkdir(destPath, { recursive: true });
18326
+ await fs22.writeFile(join4(destPath, "SKILL.md"), skillContent, "utf8");
18167
18327
  return destPath;
18168
18328
  }
18169
18329
  getCanonicalSkillsDir(projectPath, global3 = false) {
@@ -18241,7 +18401,7 @@ class SkillsManager {
18241
18401
  throw new Error(`Missing canonical path for ${skillName}`);
18242
18402
  }
18243
18403
  await this.cleanAndCreateDirectory(canonicalPath);
18244
- await fs20.writeFile(join4(canonicalPath, "SKILL.md"), skillContent, "utf8");
18404
+ await fs22.writeFile(join4(canonicalPath, "SKILL.md"), skillContent, "utf8");
18245
18405
  if (plan.path === canonicalPath) {
18246
18406
  return plan;
18247
18407
  }
@@ -18278,16 +18438,16 @@ class SkillsManager {
18278
18438
  return this.resolveInstallPath(targetDir, this.normalizeSkillName(skillName));
18279
18439
  }
18280
18440
  async cleanAndCreateDirectory(path) {
18281
- await fs20.rm(path, { recursive: true, force: true }).catch(() => {
18441
+ await fs22.rm(path, { recursive: true, force: true }).catch(() => {
18282
18442
  });
18283
- await fs20.mkdir(path, { recursive: true });
18443
+ await fs22.mkdir(path, { recursive: true });
18284
18444
  }
18285
18445
  isWithinPath(basePath, targetPath) {
18286
18446
  const relativePath = relative3(resolve8(basePath), resolve8(targetPath));
18287
18447
  return relativePath === "" || !relativePath.startsWith("..") && !relativePath.includes("/../") && !relativePath.includes("\\..\\");
18288
18448
  }
18289
18449
  async copyDir(src, dest) {
18290
- await fs20.cp(src, dest, { recursive: true, dereference: true });
18450
+ await fs22.cp(src, dest, { recursive: true, dereference: true });
18291
18451
  }
18292
18452
  async addFromSource(source, projectPath, options2 = {}) {
18293
18453
  const discovered = await this.discoverFromSource(source, projectPath, {
@@ -18376,7 +18536,7 @@ class SkillsManager {
18376
18536
  let isSymlink = false;
18377
18537
  let canonicalPath;
18378
18538
  try {
18379
- const stat = await fs20.lstat(entryPath);
18539
+ const stat = await fs22.lstat(entryPath);
18380
18540
  isSymlink = stat.isSymbolicLink();
18381
18541
  const canonicalBase = this.getCanonicalSkillsDir(projectPath, scope === "global");
18382
18542
  const [resolvedEntryPath, resolvedCanonicalBase] = await Promise.all([
@@ -18442,7 +18602,7 @@ class SkillsManager {
18442
18602
  }
18443
18603
  if (!removedPaths.has(entry.path)) {
18444
18604
  try {
18445
- await fs20.rm(entry.path, { recursive: true, force: true });
18605
+ await fs22.rm(entry.path, { recursive: true, force: true });
18446
18606
  removedPaths.add(entry.path);
18447
18607
  } catch {
18448
18608
  skipped.push({
@@ -18455,7 +18615,7 @@ class SkillsManager {
18455
18615
  if (entry.canonicalPath && entry.canonicalPath !== entry.path && !removedCanonicalPaths.has(entry.canonicalPath)) {
18456
18616
  const stillReferenced = remainingEntries.some((other) => other.name.toLowerCase() === entry.name.toLowerCase() && other.canonicalPath === entry.canonicalPath);
18457
18617
  if (!stillReferenced) {
18458
- await fs20.rm(entry.canonicalPath, { recursive: true, force: true }).catch(() => {
18618
+ await fs22.rm(entry.canonicalPath, { recursive: true, force: true }).catch(() => {
18459
18619
  });
18460
18620
  removedCanonicalPaths.add(entry.canonicalPath);
18461
18621
  }
@@ -19869,7 +20029,7 @@ var require_util3 = __commonJS((exports, module) => {
19869
20029
  var path = jsonPointers ? toQuotedString("/" + escapeJsonPointer(prop)) : toQuotedString(getProperty(prop));
19870
20030
  return joinPaths(currentPath, path);
19871
20031
  };
19872
- var getData = function($data, lvl, paths2) {
20032
+ var getData = function($data, lvl, paths5) {
19873
20033
  var up, jsonPointer, data, matches;
19874
20034
  if ($data === "")
19875
20035
  return "rootData";
@@ -19887,7 +20047,7 @@ var require_util3 = __commonJS((exports, module) => {
19887
20047
  if (jsonPointer == "#") {
19888
20048
  if (up >= lvl)
19889
20049
  throw new Error("Cannot access property/index " + up + " levels up, current level is " + lvl);
19890
- return paths2[lvl - up];
20050
+ return paths5[lvl - up];
19891
20051
  }
19892
20052
  if (up > lvl)
19893
20053
  throw new Error("Cannot access data " + up + " levels up, current level is " + lvl);
@@ -24691,27 +24851,27 @@ var require_windows = __commonJS((exports, module) => {
24691
24851
  return checkPathExt(path, options2);
24692
24852
  };
24693
24853
  var isexe = function(path, options2, cb) {
24694
- fs27.stat(path, function(er, stat) {
24854
+ fs29.stat(path, function(er, stat) {
24695
24855
  cb(er, er ? false : checkStat(stat, path, options2));
24696
24856
  });
24697
24857
  };
24698
24858
  var sync = function(path, options2) {
24699
- return checkStat(fs27.statSync(path), path, options2);
24859
+ return checkStat(fs29.statSync(path), path, options2);
24700
24860
  };
24701
24861
  module.exports = isexe;
24702
24862
  isexe.sync = sync;
24703
- var fs27 = __require("fs");
24863
+ var fs29 = __require("fs");
24704
24864
  });
24705
24865
 
24706
24866
  // node_modules/isexe/mode.js
24707
24867
  var require_mode = __commonJS((exports, module) => {
24708
24868
  var isexe = function(path, options2, cb) {
24709
- fs27.stat(path, function(er, stat) {
24869
+ fs29.stat(path, function(er, stat) {
24710
24870
  cb(er, er ? false : checkStat(stat, options2));
24711
24871
  });
24712
24872
  };
24713
24873
  var sync = function(path, options2) {
24714
- return checkStat(fs27.statSync(path), options2);
24874
+ return checkStat(fs29.statSync(path), options2);
24715
24875
  };
24716
24876
  var checkStat = function(stat, options2) {
24717
24877
  return stat.isFile() && checkMode(stat, options2);
@@ -24731,7 +24891,7 @@ var require_mode = __commonJS((exports, module) => {
24731
24891
  };
24732
24892
  module.exports = isexe;
24733
24893
  isexe.sync = sync;
24734
- var fs27 = __require("fs");
24894
+ var fs29 = __require("fs");
24735
24895
  });
24736
24896
 
24737
24897
  // node_modules/isexe/index.js
@@ -24776,7 +24936,7 @@ var require_isexe = __commonJS((exports, module) => {
24776
24936
  }
24777
24937
  }
24778
24938
  };
24779
- var fs27 = __require("fs");
24939
+ var fs29 = __require("fs");
24780
24940
  var core2;
24781
24941
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
24782
24942
  core2 = require_windows();
@@ -24983,14 +25143,14 @@ var require_readShebang = __commonJS((exports, module) => {
24983
25143
  const buffer = Buffer.alloc(size);
24984
25144
  let fd;
24985
25145
  try {
24986
- fd = fs27.openSync(command, "r");
24987
- fs27.readSync(fd, buffer, 0, size, 0);
24988
- fs27.closeSync(fd);
25146
+ fd = fs29.openSync(command, "r");
25147
+ fs29.readSync(fd, buffer, 0, size, 0);
25148
+ fs29.closeSync(fd);
24989
25149
  } catch (e) {
24990
25150
  }
24991
25151
  return shebangCommand(buffer.toString());
24992
25152
  };
24993
- var fs27 = __require("fs");
25153
+ var fs29 = __require("fs");
24994
25154
  var shebangCommand = require_shebang_command();
24995
25155
  module.exports = readShebang;
24996
25156
  });
@@ -25142,7 +25302,7 @@ var {
25142
25302
  } = import_.default;
25143
25303
 
25144
25304
  // dist/commands/init.js
25145
- import {resolve as resolve4} from "path";
25305
+ import {resolve as resolve5} from "path";
25146
25306
 
25147
25307
  // node_modules/ora/index.js
25148
25308
  import process9 from "node:process";
@@ -26493,7 +26653,45 @@ var bgMagenta = init(45, 49);
26493
26653
  var bgCyan = init(46, 49);
26494
26654
  var bgWhite = init(47, 49);
26495
26655
 
26656
+ // dist/utils/symbols.js
26657
+ var STATUS = {
26658
+ success: "\u2713",
26659
+ error: "\u2717",
26660
+ warning: "\u26A0",
26661
+ info: "\u2139",
26662
+ debug: "\u2022"
26663
+ };
26664
+ var TREE = {
26665
+ branch: "\u251C\u2500",
26666
+ last: "\u2514\u2500"
26667
+ };
26668
+ var BOX = {
26669
+ topLeft: "\u250C",
26670
+ topRight: "\u2510",
26671
+ bottomLeft: "\u2514",
26672
+ bottomRight: "\u2518",
26673
+ horizontal: "\u2500",
26674
+ vertical: "\u2502"
26675
+ };
26676
+
26496
26677
  // dist/utils/logger.js
26678
+ var getTerminalWidth = function() {
26679
+ const columns = process.stdout.columns;
26680
+ return typeof columns === "number" && columns > 0 ? columns : 80;
26681
+ };
26682
+ var truncateText = function(text, maxLength) {
26683
+ if (maxLength <= 0) {
26684
+ return "";
26685
+ }
26686
+ if (text.length <= maxLength) {
26687
+ return text;
26688
+ }
26689
+ if (maxLength <= 3) {
26690
+ return ".".repeat(maxLength);
26691
+ }
26692
+ return `${text.slice(0, maxLength - 3)}...`;
26693
+ };
26694
+
26497
26695
  class Logger {
26498
26696
  static instance;
26499
26697
  static getInstance() {
@@ -26503,22 +26701,22 @@ class Logger {
26503
26701
  return Logger.instance;
26504
26702
  }
26505
26703
  info(message) {
26506
- console.log(cyan("\u2139"), message);
26704
+ console.log(cyan(STATUS.info), message);
26507
26705
  }
26508
26706
  success(message) {
26509
- console.log(green("\u2713"), message);
26707
+ console.log(green(STATUS.success), message);
26510
26708
  }
26511
26709
  warning(message) {
26512
- console.log(yellow("\u26A0"), message);
26710
+ console.log(yellow(STATUS.warning), message);
26513
26711
  }
26514
26712
  warn(message) {
26515
26713
  this.warning(message);
26516
26714
  }
26517
26715
  error(message) {
26518
- console.log(red("\u2717"), message);
26716
+ console.log(red(STATUS.error), message);
26519
26717
  }
26520
26718
  debug(message) {
26521
- console.log(dim("\u2022"), dim(message));
26719
+ console.log(dim(STATUS.debug), dim(message));
26522
26720
  }
26523
26721
  title(message) {
26524
26722
  console.log(bold(cyan(message)));
@@ -26526,6 +26724,30 @@ class Logger {
26526
26724
  subtitle(message) {
26527
26725
  console.log(bold(message));
26528
26726
  }
26727
+ titleBox(message) {
26728
+ const w = getTerminalWidth();
26729
+ if (w < 8) {
26730
+ console.log(bold(cyan(truncateText(message, w))));
26731
+ return;
26732
+ }
26733
+ const maxInner = Math.max(4, w - 2);
26734
+ const inner = Math.min(Math.max(message.length + 4, 40), maxInner);
26735
+ const visibleMessage = truncateText(message, inner - 2);
26736
+ const padR = Math.max(0, inner - visibleMessage.length - 2);
26737
+ console.log(dim(BOX.topLeft + BOX.horizontal.repeat(inner) + BOX.topRight));
26738
+ console.log(dim(BOX.vertical) + " " + bold(cyan(visibleMessage)) + " ".repeat(padR) + " " + dim(BOX.vertical));
26739
+ console.log(dim(BOX.bottomLeft + BOX.horizontal.repeat(inner) + BOX.bottomRight));
26740
+ }
26741
+ section(title) {
26742
+ const w = getTerminalWidth();
26743
+ const lineLen = Math.max(0, w - title.length - 5);
26744
+ console.log("");
26745
+ console.log(bold(`${BOX.horizontal}${BOX.horizontal} ${title} ${BOX.horizontal.repeat(lineLen)}`));
26746
+ }
26747
+ tree(message, isLast) {
26748
+ const connector = isLast ? TREE.last : TREE.branch;
26749
+ console.log(`${connector} ${message}`);
26750
+ }
26529
26751
  }
26530
26752
  var logger = Logger.getInstance();
26531
26753
 
@@ -26534,7 +26756,8 @@ init_fs();
26534
26756
 
26535
26757
  // dist/core/agentDetector.js
26536
26758
  init_fs();
26537
- import {resolve as resolve2} from "path";
26759
+ init_paths();
26760
+ import {isAbsolute, resolve as resolve3} from "path";
26538
26761
 
26539
26762
  class AgentDetector {
26540
26763
  agentConfigs = [
@@ -26545,14 +26768,19 @@ class AgentDetector {
26545
26768
  { name: "codeium", files: [".codeium/config.json"] },
26546
26769
  { name: "codex", files: [".codex/config.toml"] },
26547
26770
  { name: "gemini", files: [".gemini/settings.json"] },
26771
+ { name: "openclaw", files: ["~/.openclaw"], scope: "environment" },
26772
+ { name: "hermes", files: ["~/.hermes"], scope: "environment" },
26548
26773
  { name: "aider", files: [".aider.conf.yml"] },
26549
26774
  { name: "cline", files: [".clinerules"] },
26550
26775
  { name: "roo", files: [".roo/mcp.json"] },
26551
26776
  { name: "zed", files: [".zed/settings.json"] }
26552
26777
  ];
26553
- async detectAgents(projectPath) {
26778
+ async detectAgents(projectPath, options2 = {}) {
26554
26779
  const results = [];
26555
26780
  for (const config of this.agentConfigs) {
26781
+ if (!this.shouldCheckScope(config.scope, options2)) {
26782
+ continue;
26783
+ }
26556
26784
  const detected = await this.checkAgentFiles(projectPath, config.files);
26557
26785
  results.push({
26558
26786
  name: config.name,
@@ -26563,19 +26791,41 @@ class AgentDetector {
26563
26791
  }
26564
26792
  return results;
26565
26793
  }
26794
+ shouldCheckScope(scope, options2) {
26795
+ if (options2.includeEnvironment) {
26796
+ return true;
26797
+ }
26798
+ return scope !== "environment";
26799
+ }
26566
26800
  async checkAgentFiles(projectPath, files) {
26567
26801
  for (const file of files) {
26568
- const fullPath = resolve2(projectPath, file);
26802
+ const fullPath = this.resolveDetectionPath(projectPath, file);
26569
26803
  if (await fileExists(fullPath)) {
26570
26804
  return { found: true, path: fullPath };
26571
26805
  }
26572
26806
  }
26573
26807
  return { found: false };
26574
26808
  }
26575
- async detectAgentByName(projectPath, agentName) {
26809
+ resolveDetectionPath(projectPath, file) {
26810
+ if (file.startsWith("~")) {
26811
+ return expandTilde(file);
26812
+ }
26813
+ if (isAbsolute(file)) {
26814
+ return file;
26815
+ }
26816
+ return resolve3(projectPath, file);
26817
+ }
26818
+ async detectAgentByName(projectPath, agentName, options2 = {}) {
26576
26819
  const config = this.agentConfigs.find((c) => c.name === agentName);
26577
26820
  if (!config)
26578
26821
  return null;
26822
+ if (!this.shouldCheckScope(config.scope, options2)) {
26823
+ return {
26824
+ name: config.name,
26825
+ files: config.files,
26826
+ detected: false
26827
+ };
26828
+ }
26579
26829
  const detected = await this.checkAgentFiles(projectPath, config.files);
26580
26830
  return {
26581
26831
  name: config.name,
@@ -26591,7 +26841,7 @@ class AgentDetector {
26591
26841
 
26592
26842
  // dist/core/stackDetector.js
26593
26843
  init_fs();
26594
- import {resolve as resolve3} from "path";
26844
+ import {resolve as resolve4} from "path";
26595
26845
 
26596
26846
  class StackDetector {
26597
26847
  lockFiles = [
@@ -26637,7 +26887,7 @@ class StackDetector {
26637
26887
  }
26638
26888
  async detectFromLockFiles(projectPath) {
26639
26889
  for (const lockFile of this.lockFiles) {
26640
- const lockPath = resolve3(projectPath, lockFile);
26890
+ const lockPath = resolve4(projectPath, lockFile);
26641
26891
  if (await fileExists(lockPath)) {
26642
26892
  return this.inferStackFromLockFile(projectPath, lockFile);
26643
26893
  }
@@ -26669,7 +26919,7 @@ class StackDetector {
26669
26919
  }
26670
26920
  async detectFromManifests(projectPath) {
26671
26921
  for (const manifest of this.manifestFiles) {
26672
- const manifestPath = resolve3(projectPath, manifest);
26922
+ const manifestPath = resolve4(projectPath, manifest);
26673
26923
  if (await fileExists(manifestPath)) {
26674
26924
  return this.inferStackFromManifest(projectPath, manifest);
26675
26925
  }
@@ -26701,7 +26951,7 @@ class StackDetector {
26701
26951
  }
26702
26952
  async detectFromConfigs(projectPath) {
26703
26953
  for (const config of this.configFiles) {
26704
- const configPath = resolve3(projectPath, config);
26954
+ const configPath = resolve4(projectPath, config);
26705
26955
  if (await fileExists(configPath)) {
26706
26956
  return this.inferStackFromConfig(projectPath, config);
26707
26957
  }
@@ -26760,7 +27010,7 @@ class StackDetector {
26760
27010
  };
26761
27011
  }
26762
27012
  async analyzeJavaScriptProject(projectPath) {
26763
- const packageJsonPath = resolve3(projectPath, "package.json");
27013
+ const packageJsonPath = resolve4(projectPath, "package.json");
26764
27014
  const packageJsonContent = await readFileIfExists(packageJsonPath);
26765
27015
  const info = {
26766
27016
  language: "javascript",
@@ -26775,7 +27025,7 @@ class StackDetector {
26775
27025
  ...packageJson.devDependencies
26776
27026
  };
26777
27027
  info.dependencies = Object.keys(allDeps);
26778
- if (allDeps.typescript || await fileExists(resolve3(projectPath, "tsconfig.json"))) {
27028
+ if (allDeps.typescript || await fileExists(resolve4(projectPath, "tsconfig.json"))) {
26779
27029
  info.language = "typescript";
26780
27030
  }
26781
27031
  if (allDeps.next)
@@ -26792,11 +27042,11 @@ class StackDetector {
26792
27042
  info.framework = "express";
26793
27043
  else if (allDeps.fastify)
26794
27044
  info.framework = "fastify";
26795
- if (await fileExists(resolve3(projectPath, "yarn.lock")))
27045
+ if (await fileExists(resolve4(projectPath, "yarn.lock")))
26796
27046
  info.packageManager = "yarn";
26797
- else if (await fileExists(resolve3(projectPath, "pnpm-lock.yaml")))
27047
+ else if (await fileExists(resolve4(projectPath, "pnpm-lock.yaml")))
26798
27048
  info.packageManager = "pnpm";
26799
- else if (await fileExists(resolve3(projectPath, "bun.lockb")))
27049
+ else if (await fileExists(resolve4(projectPath, "bun.lockb")))
26800
27050
  info.packageManager = "bun";
26801
27051
  else
26802
27052
  info.packageManager = "npm";
@@ -27075,8 +27325,8 @@ This is a {{STACK}} project{{FRAMEWORK_CONTEXT}}. The codebase follows modern de
27075
27325
  // dist/commands/init.js
27076
27326
  async function initCommand(options2) {
27077
27327
  const cwd = process.cwd();
27078
- const agentsPath = resolve4(cwd, "agents.md");
27079
- logger.title("\uD83D\uDE80 AgentInit - Initialize Project");
27328
+ const agentsPath = resolve5(cwd, "agents.md");
27329
+ logger.titleBox("AgentInit Initialize Project");
27080
27330
  if (!options2.force && await fileExists(agentsPath)) {
27081
27331
  const response = await import_prompts.default({
27082
27332
  type: "confirm",
@@ -27153,7 +27403,7 @@ async function initCommand(options2) {
27153
27403
  }
27154
27404
  var getProjectName = function(cwd) {
27155
27405
  try {
27156
- const packageJsonPath = resolve4(cwd, "package.json");
27406
+ const packageJsonPath = resolve5(cwd, "package.json");
27157
27407
  const packageJson = __require(packageJsonPath);
27158
27408
  return packageJson.name || cwd.split("/").pop() || "project";
27159
27409
  } catch {
@@ -27166,7 +27416,7 @@ init_skillsManager();
27166
27416
  init_agentManager();
27167
27417
  async function detectCommand(options2) {
27168
27418
  const cwd = process.cwd();
27169
- logger.title("\uD83D\uDD0D AgentInit - Project Detection");
27419
+ logger.titleBox("AgentInit Project Detection");
27170
27420
  const spinner = ora("Detecting project configuration...").start();
27171
27421
  try {
27172
27422
  const agentDetector3 = new AgentDetector;
@@ -27234,7 +27484,7 @@ import {relative as relative5} from "path";
27234
27484
 
27235
27485
  // dist/core/propagator.js
27236
27486
  var import_gray_matter3 = __toESM(require_gray_matter(), 1);
27237
- import {promises as fs22} from "fs";
27487
+ import {promises as fs24} from "fs";
27238
27488
  import {resolve as resolve9} from "path";
27239
27489
 
27240
27490
  // node_modules/js-yaml/dist/js-yaml.mjs
@@ -30002,7 +30252,7 @@ class Propagator {
30002
30252
  resolvedTargets: []
30003
30253
  };
30004
30254
  const exists = await fileExists(generatedFile.path);
30005
- const existingStats = exists ? await fs22.lstat(generatedFile.path).catch(() => null) : null;
30255
+ const existingStats = exists ? await fs24.lstat(generatedFile.path).catch(() => null) : null;
30006
30256
  const existingContent = exists && !existingStats?.isSymbolicLink() ? await readFileIfExists(generatedFile.path) : null;
30007
30257
  const existingTarget = existingStats?.isSymbolicLink() ? await readSymlinkTarget(generatedFile.path) : null;
30008
30258
  if (options2.managedState && !options2.dryRun) {
@@ -30033,7 +30283,7 @@ class Propagator {
30033
30283
  if (!options2.dryRun) {
30034
30284
  if (generatedFile.kind === "file") {
30035
30285
  if (existingStats?.isSymbolicLink()) {
30036
- await fs22.rm(generatedFile.path, { force: true }).catch(() => {
30286
+ await fs24.rm(generatedFile.path, { force: true }).catch(() => {
30037
30287
  });
30038
30288
  }
30039
30289
  await writeFile(generatedFile.path, generatedFile.content || "");
@@ -30210,14 +30460,14 @@ ${content}
30210
30460
 
30211
30461
  // dist/core/managedState.js
30212
30462
  init_fs();
30213
- import {promises as fs24} from "fs";
30463
+ import {promises as fs26} from "fs";
30214
30464
  import {dirname as dirname3, join as join5, relative as relative4, resolve as resolve10} from "path";
30215
30465
  var toPosixPath = function(value) {
30216
30466
  return value.replace(/\\/g, "/");
30217
30467
  };
30218
30468
  async function pathType(targetPath) {
30219
30469
  try {
30220
- const stat = await fs24.lstat(targetPath);
30470
+ const stat = await fs26.lstat(targetPath);
30221
30471
  if (stat.isSymbolicLink()) {
30222
30472
  return "symlink";
30223
30473
  }
@@ -30227,20 +30477,20 @@ async function pathType(targetPath) {
30227
30477
  }
30228
30478
  }
30229
30479
  async function copyDirectory(src, dest) {
30230
- await fs24.mkdir(dest, { recursive: true });
30231
- const entries = await fs24.readdir(src, { withFileTypes: true });
30480
+ await fs26.mkdir(dest, { recursive: true });
30481
+ const entries = await fs26.readdir(src, { withFileTypes: true });
30232
30482
  for (const entry of entries) {
30233
30483
  const srcPath = join5(src, entry.name);
30234
30484
  const destPath = join5(dest, entry.name);
30235
30485
  if (entry.isDirectory()) {
30236
30486
  await copyDirectory(srcPath, destPath);
30237
30487
  } else if (entry.isSymbolicLink()) {
30238
- const target = await fs24.readlink(srcPath);
30239
- await fs24.mkdir(dirname3(destPath), { recursive: true });
30240
- await fs24.symlink(target, destPath);
30488
+ const target = await fs26.readlink(srcPath);
30489
+ await fs26.mkdir(dirname3(destPath), { recursive: true });
30490
+ await fs26.symlink(target, destPath);
30241
30491
  } else {
30242
- await fs24.mkdir(dirname3(destPath), { recursive: true });
30243
- await fs24.copyFile(srcPath, destPath);
30492
+ await fs26.mkdir(dirname3(destPath), { recursive: true });
30493
+ await fs26.copyFile(srcPath, destPath);
30244
30494
  }
30245
30495
  }
30246
30496
  }
@@ -30249,14 +30499,14 @@ async function copyPath(src, dest) {
30249
30499
  if (!type2) {
30250
30500
  return;
30251
30501
  }
30252
- await fs24.mkdir(dirname3(dest), { recursive: true });
30502
+ await fs26.mkdir(dirname3(dest), { recursive: true });
30253
30503
  if (type2 === "symlink") {
30254
- const target = await fs24.readlink(src);
30255
- await fs24.symlink(target, dest);
30504
+ const target = await fs26.readlink(src);
30505
+ await fs26.symlink(target, dest);
30256
30506
  } else if (type2 === "directory") {
30257
30507
  await copyDirectory(src, dest);
30258
30508
  } else {
30259
- await fs24.copyFile(src, dest);
30509
+ await fs26.copyFile(src, dest);
30260
30510
  }
30261
30511
  }
30262
30512
  var MANAGED_STATE_FILE = "managed-state.json";
@@ -30274,7 +30524,7 @@ class ManagedStateStore {
30274
30524
  const statePath = join5(agentInitDir, MANAGED_STATE_FILE);
30275
30525
  const emptyState = { version: 1, entries: [] };
30276
30526
  try {
30277
- const raw = await fs24.readFile(statePath, "utf8");
30527
+ const raw = await fs26.readFile(statePath, "utf8");
30278
30528
  const parsed = JSON.parse(raw);
30279
30529
  if (!parsed || parsed.version !== 1 || !Array.isArray(parsed.entries)) {
30280
30530
  return new ManagedStateStore(projectPath, emptyState);
@@ -30313,7 +30563,7 @@ class ManagedStateStore {
30313
30563
  }
30314
30564
  if (type2 === "symlink") {
30315
30565
  try {
30316
- const backupLinkTarget = await fs24.readlink(targetPath);
30566
+ const backupLinkTarget = await fs26.readlink(targetPath);
30317
30567
  return { backupLinkTarget };
30318
30568
  } catch {
30319
30569
  return {};
@@ -30355,20 +30605,20 @@ class ManagedStateStore {
30355
30605
  if (this.state.entries.length === 0) {
30356
30606
  return [];
30357
30607
  }
30358
- const paths2 = new Set([
30608
+ const paths5 = new Set([
30359
30609
  ".agentinit/managed-state.json",
30360
30610
  ".agentinit/backups/"
30361
30611
  ]);
30362
30612
  for (const entry of this.state.entries) {
30363
30613
  if (entry.ignorePath) {
30364
- paths2.add(entry.ignorePath);
30614
+ paths5.add(entry.ignorePath);
30365
30615
  }
30366
30616
  }
30367
- return [...paths2];
30617
+ return [...paths5];
30368
30618
  }
30369
30619
  async save() {
30370
- await fs24.mkdir(this.agentInitDir, { recursive: true });
30371
- await fs24.writeFile(this.stateFilePath, JSON.stringify(this.state, null, 2), "utf8");
30620
+ await fs26.mkdir(this.agentInitDir, { recursive: true });
30621
+ await fs26.writeFile(this.stateFilePath, JSON.stringify(this.state, null, 2), "utf8");
30372
30622
  }
30373
30623
  async revertAll(options2 = {}) {
30374
30624
  const summary = {
@@ -30383,29 +30633,29 @@ class ManagedStateStore {
30383
30633
  const backupLinkTarget = entry.backupLinkTarget;
30384
30634
  if (entry.existedBefore && backupLinkTarget !== undefined) {
30385
30635
  if (!options2.dryRun) {
30386
- await fs24.rm(absolutePath, { recursive: true, force: true }).catch(() => {
30636
+ await fs26.rm(absolutePath, { recursive: true, force: true }).catch(() => {
30387
30637
  });
30388
- await fs24.mkdir(dirname3(absolutePath), { recursive: true });
30389
- await fs24.symlink(backupLinkTarget, absolutePath);
30638
+ await fs26.mkdir(dirname3(absolutePath), { recursive: true });
30639
+ await fs26.symlink(backupLinkTarget, absolutePath);
30390
30640
  }
30391
30641
  summary.restored++;
30392
30642
  } else if (entry.existedBefore && backupPath && await fileExists(backupPath)) {
30393
30643
  if (!options2.dryRun) {
30394
- await fs24.rm(absolutePath, { recursive: true, force: true }).catch(() => {
30644
+ await fs26.rm(absolutePath, { recursive: true, force: true }).catch(() => {
30395
30645
  });
30396
30646
  await copyPath(backupPath, absolutePath);
30397
30647
  }
30398
30648
  summary.restored++;
30399
30649
  } else {
30400
30650
  if (!options2.dryRun) {
30401
- await fs24.rm(absolutePath, { recursive: true, force: true }).catch(() => {
30651
+ await fs26.rm(absolutePath, { recursive: true, force: true }).catch(() => {
30402
30652
  });
30403
30653
  }
30404
30654
  summary.removed++;
30405
30655
  }
30406
30656
  if (!options2.keepBackups && backupPath && await fileExists(backupPath)) {
30407
30657
  if (!options2.dryRun) {
30408
- await fs24.rm(backupPath, { recursive: true, force: true }).catch(() => {
30658
+ await fs26.rm(backupPath, { recursive: true, force: true }).catch(() => {
30409
30659
  });
30410
30660
  }
30411
30661
  summary.backupsRemoved++;
@@ -30413,16 +30663,16 @@ class ManagedStateStore {
30413
30663
  }
30414
30664
  if (!options2.dryRun) {
30415
30665
  this.state.entries.length = 0;
30416
- await fs24.rm(this.stateFilePath, { force: true }).catch(() => {
30666
+ await fs26.rm(this.stateFilePath, { force: true }).catch(() => {
30417
30667
  });
30418
30668
  if (!options2.keepBackups) {
30419
- await fs24.rm(this.backupsDir, { recursive: true, force: true }).catch(() => {
30669
+ await fs26.rm(this.backupsDir, { recursive: true, force: true }).catch(() => {
30420
30670
  });
30421
30671
  }
30422
30672
  try {
30423
- const remainingEntries = await fs24.readdir(this.agentInitDir);
30673
+ const remainingEntries = await fs26.readdir(this.agentInitDir);
30424
30674
  if (remainingEntries.length === 0) {
30425
- await fs24.rm(this.agentInitDir, { recursive: true, force: true });
30675
+ await fs26.rm(this.agentInitDir, { recursive: true, force: true });
30426
30676
  }
30427
30677
  } catch {
30428
30678
  }
@@ -30436,7 +30686,7 @@ init_agentManager();
30436
30686
  async function syncCommand(options2) {
30437
30687
  const cwd = process.cwd();
30438
30688
  const agentManager5 = new AgentManager;
30439
- logger.title("\uD83D\uDD04 AgentInit - Sync Configuration");
30689
+ logger.titleBox("AgentInit Sync");
30440
30690
  if (options2.dryRun) {
30441
30691
  logger.info("Running in dry-run mode - no files will be modified");
30442
30692
  }
@@ -38960,7 +39210,7 @@ class MCPVerifier {
38960
39210
  for (const result of results) {
38961
39211
  const { server, status, capabilities, error, connectionTime } = result;
38962
39212
  if (status === "success" && capabilities) {
38963
- output.push(`\u2705 MCP Server: ${server.name} (${server.type.toUpperCase()})`);
39213
+ output.push(`\u2713 MCP Server: ${server.name} (${server.type.toUpperCase()})`);
38964
39214
  output.push(` Status: Connected successfully (${connectionTime}ms)`);
38965
39215
  if (capabilities.serverInfo) {
38966
39216
  output.push(` Version: ${capabilities.serverInfo.version}`);
@@ -39010,10 +39260,10 @@ class MCPVerifier {
39010
39260
  }
39011
39261
  }
39012
39262
  if (capabilities.tools.length === 0 && capabilities.resources.length === 0 && capabilities.prompts.length === 0) {
39013
- output.push(` \u26A0\uFE0F No tools, resources, or prompts available`);
39263
+ output.push(` \u26A0 No tools, resources, or prompts available`);
39014
39264
  }
39015
39265
  } else {
39016
- const statusIcon = status === "timeout" ? "\u23F1\uFE0F" : "\u274C";
39266
+ const statusIcon = status === "timeout" ? "\u29D7" : "\u2717";
39017
39267
  output.push(`${statusIcon} MCP Server: ${server.name} (${server.type.toUpperCase()})`);
39018
39268
  output.push(` Status: ${status === "timeout" ? "Connection timeout" : "Failed"} (${connectionTime || 0}ms)`);
39019
39269
  if (error) {
@@ -39042,7 +39292,7 @@ class MCPVerifier {
39042
39292
  }
39043
39293
 
39044
39294
  // dist/core/gitignoreManager.js
39045
- import {promises as fs27} from "fs";
39295
+ import {promises as fs29} from "fs";
39046
39296
  import {dirname as dirname6, join as join7} from "path";
39047
39297
  var normalizeIgnorePath = function(projectPath, value) {
39048
39298
  const relative6 = value.startsWith(projectPath) ? value.slice(projectPath.length + 1) : value;
@@ -39089,13 +39339,13 @@ var updateManagedBlock = function(existingContent, entries) {
39089
39339
  }
39090
39340
  return content;
39091
39341
  };
39092
- async function updateManagedIgnoreFile(projectPath, paths2, options2 = {}) {
39342
+ async function updateManagedIgnoreFile(projectPath, paths5, options2 = {}) {
39093
39343
  const ignoreFile = options2.local ? join7(".git", "info", "exclude") : ".gitignore";
39094
39344
  const ignoreFilePath = join7(projectPath, ignoreFile);
39095
39345
  if (options2.local) {
39096
39346
  const gitDir = join7(projectPath, ".git");
39097
39347
  try {
39098
- const stat = await fs27.stat(gitDir);
39348
+ const stat = await fs29.stat(gitDir);
39099
39349
  if (!stat.isDirectory()) {
39100
39350
  throw new Error;
39101
39351
  }
@@ -39103,16 +39353,16 @@ async function updateManagedIgnoreFile(projectPath, paths2, options2 = {}) {
39103
39353
  throw new Error("Cannot update .git/info/exclude because this project is not a Git repository");
39104
39354
  }
39105
39355
  }
39106
- const normalizedPaths = [...new Set(paths2.map((path) => normalizeIgnorePath(projectPath, path)).filter(Boolean))].sort();
39356
+ const normalizedPaths = [...new Set(paths5.map((path) => normalizeIgnorePath(projectPath, path)).filter(Boolean))].sort();
39107
39357
  let existingContent = "";
39108
39358
  try {
39109
- existingContent = await fs27.readFile(ignoreFilePath, "utf8");
39359
+ existingContent = await fs29.readFile(ignoreFilePath, "utf8");
39110
39360
  } catch {
39111
39361
  existingContent = "";
39112
39362
  }
39113
39363
  const updatedContent = updateManagedBlock(existingContent, normalizedPaths);
39114
- await fs27.mkdir(dirname6(ignoreFilePath), { recursive: true });
39115
- await fs27.writeFile(ignoreFilePath, updatedContent, "utf8");
39364
+ await fs29.mkdir(dirname6(ignoreFilePath), { recursive: true });
39365
+ await fs29.writeFile(ignoreFilePath, updatedContent, "utf8");
39116
39366
  return ignoreFilePath;
39117
39367
  }
39118
39368
  async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
@@ -39120,7 +39370,7 @@ async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
39120
39370
  const ignoreFilePath = join7(projectPath, ignoreFile);
39121
39371
  let content;
39122
39372
  try {
39123
- content = await fs27.readFile(ignoreFilePath, "utf8");
39373
+ content = await fs29.readFile(ignoreFilePath, "utf8");
39124
39374
  } catch {
39125
39375
  return false;
39126
39376
  }
@@ -39136,13 +39386,13 @@ async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
39136
39386
  const afterBlock = content.slice(endIndex + END_MARKER.length).replace(/^\n+/, "");
39137
39387
  let nextContent = `${beforeBlock}${afterBlock}`.replace(/\n{3,}/g, "\n\n").replace(/^\n+/, "");
39138
39388
  if (nextContent.trim() === "") {
39139
- await fs27.rm(ignoreFilePath, { force: true }).catch(() => {
39389
+ await fs29.rm(ignoreFilePath, { force: true }).catch(() => {
39140
39390
  });
39141
39391
  } else {
39142
39392
  if (!nextContent.endsWith("\n")) {
39143
39393
  nextContent += "\n";
39144
39394
  }
39145
- await fs27.writeFile(ignoreFilePath, nextContent, "utf8");
39395
+ await fs29.writeFile(ignoreFilePath, nextContent, "utf8");
39146
39396
  }
39147
39397
  return true;
39148
39398
  }
@@ -39276,7 +39526,7 @@ async function applyProjectCommand(options2) {
39276
39526
  const cwd = process.cwd();
39277
39527
  const agentManager7 = new AgentManager;
39278
39528
  let managedState3 = null;
39279
- logger.title("\uD83D\uDD27 AgentInit - Apply");
39529
+ logger.titleBox("AgentInit Apply");
39280
39530
  if (options2.dryRun) {
39281
39531
  logger.info("Running in dry-run mode - no files will be modified");
39282
39532
  }
@@ -39400,7 +39650,7 @@ async function applyProjectCommand(options2) {
39400
39650
  }
39401
39651
  async function applyCommand(args) {
39402
39652
  const cwd = process.cwd();
39403
- logger.title("\uD83D\uDD27 AgentInit - Apply Configuration");
39653
+ logger.titleBox("AgentInit Apply Configuration");
39404
39654
  const hasMcpArgs = args.some((arg) => arg.startsWith("--mcp-"));
39405
39655
  const hasRulesArgs = args.some((arg) => arg === "--rules" || arg === "--rule-raw" || arg === "--rules-file" || arg === "--rules-remote");
39406
39656
  const clientArgIndex = args.findIndex((arg) => arg === "--client" || arg === "--agent");
@@ -39805,7 +40055,7 @@ var LEGACY_APPLY_FLAGS = new Set([
39805
40055
  init_agentManager();
39806
40056
  async function verifyMcpCommand(args) {
39807
40057
  const cwd = process.cwd();
39808
- logger.title("\uD83D\uDD0D AgentInit - MCP Verification");
40058
+ logger.titleBox("AgentInit MCP Verification");
39809
40059
  const hasAll = args.includes("--all");
39810
40060
  const mcpNameIndex = args.findIndex((arg) => arg === "--mcp-name");
39811
40061
  const mcpName = mcpNameIndex >= 0 && mcpNameIndex + 1 < args.length ? args[mcpNameIndex + 1] : null;
@@ -40009,7 +40259,7 @@ async function verifyMcpCommand(args) {
40009
40259
  // dist/commands/revert.js
40010
40260
  async function revertCommand(options2) {
40011
40261
  const cwd = process.cwd();
40012
- logger.title("\u21A9\uFE0F AgentInit - Revert");
40262
+ logger.titleBox("AgentInit Revert");
40013
40263
  if (options2.dryRun) {
40014
40264
  logger.info("Running in dry-run mode - no files will be modified");
40015
40265
  }
@@ -40060,8 +40310,8 @@ init_agentManager();
40060
40310
  function registerSkillsCommand(program2) {
40061
40311
  const marketplaceHelp = getMarketplaceIds().join(", ");
40062
40312
  const skills = program2.command("skills").description("Manage agent skills");
40063
- skills.command("add <source>").description("Add skills from a marketplace, GitHub repo, or local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-g, --global", "Install skills globally").option("-a, --agent <agents...>", "Target specific agent(s)").option("-s, --skill <names...>", "Install only specific skills by name").option("-l, --list", "List available skills from the source without installing").option("--copy", "Copy skill files instead of symlinking").option("-y, --yes", "Skip prompts and auto-detect project agents only").action(async (source, options2) => {
40064
- logger.title("\uD83D\uDCE6 AgentInit - Skills");
40313
+ skills.command("add <source>").description("Add skills from a marketplace, GitHub repo, or local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-g, --global", "Install skills globally").option("-a, --agent <agents...>", "Target specific agent(s)").option("-s, --skill <names...>", "Install only specific skills by name").option("-l, --list", "List available skills from the source without installing").option("--copy", "Copy skill files instead of symlinking").option("-y, --yes", "Skip prompts and auto-detect project-configured agents only").action(async (source, options2) => {
40314
+ logger.titleBox("AgentInit Skills");
40065
40315
  const agentManager9 = new AgentManager;
40066
40316
  const skillsManager5 = new SkillsManager(agentManager9);
40067
40317
  if (options2.list) {
@@ -40111,7 +40361,7 @@ function registerSkillsCommand(program2) {
40111
40361
  }
40112
40362
  });
40113
40363
  skills.command("list").alias("ls").description("List installed skills").option("-g, --global", "List only global skills").option("-a, --agent <agents...>", "Filter by specific agent(s)").action(async (options2) => {
40114
- logger.title("\uD83D\uDCE6 AgentInit - Skills");
40364
+ logger.titleBox("AgentInit Skills");
40115
40365
  const agentManager9 = new AgentManager;
40116
40366
  const skillsManager5 = new SkillsManager(agentManager9);
40117
40367
  const installed = await skillsManager5.listInstalled(process.cwd(), {
@@ -40151,7 +40401,7 @@ function registerSkillsCommand(program2) {
40151
40401
  }
40152
40402
  });
40153
40403
  skills.command("remove [names...]").alias("rm").description("Remove installed skills by name").option("-g, --global", "Remove from global scope").option("-a, --agent <agents...>", "Target specific agent(s)").option("-y, --yes", "Skip confirmation prompts").action(async (names, options2) => {
40154
- logger.title("\uD83D\uDCE6 AgentInit - Skills");
40404
+ logger.titleBox("AgentInit Skills");
40155
40405
  if (!names || names.length === 0) {
40156
40406
  if (!options2.yes) {
40157
40407
  logger.error("Please specify skill name(s) to remove.");
@@ -41073,7 +41323,7 @@ var buildAppliedRules = function(sections) {
41073
41323
  function registerRulesCommand(program2) {
41074
41324
  const rules = program2.command("rules").description("Manage agent rules");
41075
41325
  rules.command("add").description("Add rules to agent configuration").option("-t, --template <templates...>", "Rule templates to apply (comma-separated values accepted)").option("-r, --raw <rules...>", "Raw rule strings").option("-f, --file <path>", "Load rules from a file").option("--remote <url>", "Load rules from a remote URL").option("--auth <token>", "Authentication token for remote rules (Bearer token)").option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Apply rules globally").action(async (options2) => {
41076
- logger.title("\uD83D\uDCCF AgentInit - Rules");
41326
+ logger.titleBox("AgentInit Rules");
41077
41327
  const cwd = process.cwd();
41078
41328
  const isGlobal = !!options2.global;
41079
41329
  const templates = [];
@@ -41201,7 +41451,7 @@ function registerRulesCommand(program2) {
41201
41451
  }
41202
41452
  });
41203
41453
  rules.command("list").alias("ls").description("List rules configured for each agent").option("-a, --agent <agents...>", "Filter by specific agent(s)").option("-g, --global", "List global rules").action(async (options2) => {
41204
- logger.title("\uD83D\uDCCF AgentInit - Rules");
41454
+ logger.titleBox("AgentInit Rules");
41205
41455
  const cwd = process.cwd();
41206
41456
  const isGlobal = !!options2.global;
41207
41457
  const agentManager11 = new AgentManager;
@@ -41241,7 +41491,7 @@ function registerRulesCommand(program2) {
41241
41491
  }
41242
41492
  });
41243
41493
  rules.command("remove [names...]").alias("rm").description("Remove rule sections by template ID (e.g. git, write_docs)").option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Remove from global rules").action(async (names, options2) => {
41244
- logger.title("\uD83D\uDCCF AgentInit - Rules");
41494
+ logger.titleBox("AgentInit Rules");
41245
41495
  if (!names || names.length === 0) {
41246
41496
  logger.error("Please specify rule section name(s) to remove.");
41247
41497
  logger.info("Usage: agentinit rules remove <name...>");
@@ -41300,13 +41550,28 @@ function registerRulesCommand(program2) {
41300
41550
  // dist/commands/plugins.js
41301
41551
  var import_prompts3 = __toESM(require_prompts3(), 1);
41302
41552
  import {dirname as dirname8, relative as relative8} from "path";
41553
+
41554
+ // dist/utils/colors.js
41555
+ var colorsEnabled = function() {
41556
+ const env2 = process.env || {};
41557
+ const isTTY2 = !!process.stdout?.isTTY;
41558
+ return !env2.NODE_DISABLE_COLORS && env2.NO_COLOR == null && env2.TERM !== "dumb" && (env2.FORCE_COLOR != null && env2.FORCE_COLOR !== "0" || isTTY2);
41559
+ };
41560
+ function orange(text) {
41561
+ if (!colorsEnabled()) {
41562
+ return text;
41563
+ }
41564
+ return `\x1B[38;5;208m${text}\x1B[39m`;
41565
+ }
41566
+
41567
+ // dist/commands/plugins.js
41303
41568
  init_pluginManager();
41304
41569
  init_agentManager();
41305
41570
  function registerPluginsCommand(program2) {
41306
41571
  const marketplaceHelp = new PluginManager().getMarketplaceIds().join(", ");
41307
41572
  const plugins = program2.command("plugins").description("Install agent-agnostic plugins from any marketplace or source");
41308
- plugins.command("install <source>").description("Install a plugin from <marketplace>/<name>, a GitHub repo, or a local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Install globally").option("--copy-skills", "Copy plugin skills instead of using canonical symlink installs").option("-l, --list", "Preview plugin contents without installing").option("-y, --yes", "Skip confirmation prompts, auto-detect all agents").action(async (source, options2) => {
41309
- logger.title("\uD83D\uDD0C AgentInit - Plugins");
41573
+ plugins.command("install <source>").description("Install a plugin from <marketplace>/<name>, a GitHub repo, or a local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Install globally").option("--copy-skills", "Copy plugin skills instead of using canonical symlink installs").option("-l, --list", "Preview plugin contents without installing").option("-y, --yes", "Skip confirmation prompts, auto-detect project-configured agents").action(async (source, options2) => {
41574
+ logger.titleBox("AgentInit Plugins");
41310
41575
  const agentManager12 = new AgentManager;
41311
41576
  const pluginManager2 = new PluginManager(agentManager12);
41312
41577
  if (options2.list) {
@@ -41422,7 +41687,7 @@ function registerPluginsCommand(program2) {
41422
41687
  }
41423
41688
  });
41424
41689
  plugins.command("search [query]").description("Search marketplace plugins").option("--from <marketplace>", `Which marketplace to search (available: ${marketplaceHelp})`).option("--category <category>", "Filter: official, community").action(async (query, options2) => {
41425
- logger.title("\uD83D\uDD0C AgentInit - Plugin Search");
41690
+ logger.titleBox("AgentInit Plugin Search");
41426
41691
  const pluginManager2 = new PluginManager;
41427
41692
  if (!options2.from) {
41428
41693
  logger.info(`Please specify a marketplace with --from <marketplace>. Available: ${marketplaceHelp}`);
@@ -41463,7 +41728,7 @@ function registerPluginsCommand(program2) {
41463
41728
  }
41464
41729
  });
41465
41730
  plugins.command("list").alias("ls").description("List installed plugins").option("-a, --agent <agents...>", "Filter by specific agent(s)").option("-g, --global", "List global plugins").action(async (options2) => {
41466
- logger.title("\uD83D\uDD0C AgentInit - Installed Plugins");
41731
+ logger.titleBox("AgentInit Installed Plugins");
41467
41732
  const pluginManager2 = new PluginManager;
41468
41733
  const installed = await pluginManager2.listPlugins(process.cwd(), {
41469
41734
  global: options2.global,
@@ -41499,7 +41764,7 @@ function registerPluginsCommand(program2) {
41499
41764
  }
41500
41765
  });
41501
41766
  plugins.command("remove <name>").alias("rm").description("Remove an installed plugin").option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Remove from global scope").option("-y, --yes", "Skip confirmation prompts").action(async (name, options2) => {
41502
- logger.title("\uD83D\uDD0C AgentInit - Remove Plugin");
41767
+ logger.titleBox("AgentInit Remove Plugin");
41503
41768
  const pluginManager2 = new PluginManager;
41504
41769
  const spinner = ora(`Removing plugin "${name}"...`).start();
41505
41770
  try {
@@ -41549,28 +41814,40 @@ var getPortableComponentSummary = function(preview) {
41549
41814
  return parts.length > 0 ? parts.join(", ") : "No portable components";
41550
41815
  };
41551
41816
  var getSourceWarnings = function(warnings) {
41552
- const lines = [];
41817
+ const items = [];
41553
41818
  for (const warning of warnings) {
41554
41819
  const missingMatch = warning.match(/^Plugin "(.+)" not found in (.+) marketplace\.$/);
41555
41820
  if (missingMatch) {
41556
- lines.push(`${missingMatch[2]} marketplace does not contain "${missingMatch[1]}".`);
41821
+ items.push({
41822
+ type: "marketplace-miss",
41823
+ text: `${missingMatch[2]} marketplace does not contain "${missingMatch[1]}".`
41824
+ });
41557
41825
  continue;
41558
41826
  }
41559
- const fallbackMatch = warning.match(/^Marketplace lookup failed; trying unverified GitHub repository (.+) instead\.$/);
41827
+ const fallbackMatch = warning.match(/^Marketplace lookup failed; trying (verified|unverified) GitHub repository (.+) instead\.$/);
41560
41828
  if (fallbackMatch) {
41561
- lines.push(`Falling back to unverified GitHub repository: ${fallbackMatch[1]}`);
41829
+ items.push({
41830
+ type: fallbackMatch[1] === "verified" ? "fallback-verified" : "fallback-unverified",
41831
+ text: `${fallbackMatch[1] === "verified" ? "Verified" : "Unverified"} GitHub repository: ${fallbackMatch[2]}`
41832
+ });
41562
41833
  continue;
41563
41834
  }
41564
41835
  const bundleMatch = warning.match(/^Source "(.+)" is a Claude Code marketplace bundle; using bundled plugin "(.+)"\.$/);
41565
41836
  if (bundleMatch) {
41566
- lines.push(`Claude Code marketplace bundle detected: ${bundleMatch[1]}`);
41567
- lines.push(`Using bundled plugin "${bundleMatch[2]}".`);
41837
+ items.push({
41838
+ type: "bundle-detected",
41839
+ text: `Claude Code marketplace bundle detected: ${bundleMatch[1]}`
41840
+ });
41841
+ items.push({
41842
+ type: "bundle-using",
41843
+ text: `Using bundled plugin "${bundleMatch[2]}".`
41844
+ });
41568
41845
  }
41569
41846
  }
41570
- return lines;
41847
+ return items;
41571
41848
  };
41572
41849
  var getRemainingWarnings = function(warnings) {
41573
- return warnings.filter((warning) => !/^Plugin "(.+)" not found in (.+) marketplace\.$/.test(warning) && !/^Marketplace lookup failed; trying unverified GitHub repository (.+) instead\.$/.test(warning) && !/^Source "(.+)" is a Claude Code marketplace bundle; using bundled plugin "(.+)"\.$/.test(warning) && !/^Hooks \(hooks\/\) are Claude Code-specific$/.test(warning) && !/^Agent definitions \(agents\/\) are Claude Code-specific$/.test(warning) && !/^Claude Code-native plugin components detected \((.+)\);/.test(warning) && !/^Claude Code-native plugin components detected \((.+)\), but no Claude Code target was selected; skipped native install\.$/.test(warning) && warning !== "Reload plugins in Claude Code with /reload-plugins to activate native plugin components.");
41850
+ return warnings.filter((warning) => !/^Plugin "(.+)" not found in (.+) marketplace\.$/.test(warning) && !/^Marketplace lookup failed; trying (verified|unverified) GitHub repository (.+) instead\.$/.test(warning) && !/^Source "(.+)" is a Claude Code marketplace bundle; using bundled plugin "(.+)"\.$/.test(warning) && !/^Hooks \(hooks\/\) are Claude Code-specific$/.test(warning) && !/^Agent definitions \(agents\/\) are Claude Code-specific$/.test(warning) && !/^Claude Code-native plugin components detected \((.+)\);/.test(warning) && !/^Claude Code-native plugin components detected \((.+)\), but no Claude Code target was selected; skipped native install\.$/.test(warning) && warning !== "Reload plugins in Claude Code with /reload-plugins to activate native plugin components.");
41574
41851
  };
41575
41852
  var getNativeCompatibilityWarning = function(previewOrResult) {
41576
41853
  if ("nativePreview" in previewOrResult) {
@@ -41606,33 +41883,67 @@ var renderPluginWarnings = function(previewOrResult, projectPath) {
41606
41883
  const allWarnings = "nativePreview" in previewOrResult ? previewOrResult.plugin.warnings : previewOrResult.warnings;
41607
41884
  const sourceWarnings = getSourceWarnings(previewOrResult.plugin.warnings);
41608
41885
  if (sourceWarnings.length > 0) {
41609
- console.log("");
41610
- logger.subtitle("Source");
41611
- for (const warning of sourceWarnings) {
41612
- logger.warn(` ${warning}`);
41886
+ logger.section("Source");
41887
+ const lastIdx = sourceWarnings.length - 1;
41888
+ for (let i = 0;i < sourceWarnings.length; i++) {
41889
+ const item = sourceWarnings[i];
41890
+ const isLast = i === lastIdx;
41891
+ if (item.type === "marketplace-miss") {
41892
+ logger.tree(yellow("\u26A0") + ` ${item.text}`, isLast);
41893
+ } else if (item.type === "fallback-verified") {
41894
+ logger.tree(green("\u2713") + ` ${item.text}`, isLast);
41895
+ } else if (item.type === "fallback-unverified") {
41896
+ logger.tree(yellow("\u26A0") + ` ${item.text}`, isLast);
41897
+ } else if (item.type === "bundle-detected") {
41898
+ logger.tree(orange("\u2713") + ` ${orange(item.text)}`, isLast);
41899
+ } else if (item.type === "bundle-using") {
41900
+ logger.tree(green("\u2713") + ` ${item.text}`, isLast);
41901
+ }
41613
41902
  }
41614
41903
  }
41615
41904
  const nativeWarning = getNativeCompatibilityWarning(previewOrResult);
41616
41905
  if (nativeWarning) {
41617
- console.log("");
41618
- logger.subtitle("Compatibility");
41619
- logger.warn(` Claude Code-only components detected: ${nativeWarning.features.join(", ")}`);
41906
+ logger.section("Compatibility");
41907
+ const lines = [];
41908
+ lines.push({
41909
+ text: orange("\u26A0") + ` ${orange("Claude Code")}-only components detected: ${dim(nativeWarning.features.join(", "))}`,
41910
+ isLast: false
41911
+ });
41620
41912
  if (nativeWarning.installPath) {
41621
- logger.info(` Claude native install path: ${formatPathForDisplay(nativeWarning.installPath, projectPath)}`);
41913
+ lines.push({
41914
+ text: orange("\u2139") + ` ${orange("Claude")} native install path: ${dim(formatPathForDisplay(nativeWarning.installPath, projectPath))}`,
41915
+ isLast: false
41916
+ });
41622
41917
  }
41623
41918
  if (nativeWarning.skipped) {
41624
- logger.warn(" No Claude Code target selected. Native Claude installation was skipped.");
41919
+ lines.push({
41920
+ text: orange("\u26A0") + ` No ${orange("Claude Code")} target selected. Native installation was skipped.`,
41921
+ isLast: true
41922
+ });
41625
41923
  } else {
41626
- logger.info(" Non-Claude targets install only the portable skills and MCP servers.");
41627
- logger.info("nativePreview" in previewOrResult ? " If you install to Claude Code, reload plugins with /reload-plugins afterward." : " Reload plugins in Claude Code with /reload-plugins after install.");
41924
+ lines.push({
41925
+ text: cyan("\u2139") + " Non-Claude targets install only the portable skills and MCP servers.",
41926
+ isLast: false
41927
+ });
41928
+ const reloadMsg = "nativePreview" in previewOrResult ? ` If you install to ${orange("Claude Code")}, reload plugins with ${bold("/reload-plugins")} afterward.` : ` Reload plugins in ${orange("Claude Code")} with ${bold("/reload-plugins")} after install.`;
41929
+ lines.push({
41930
+ text: orange("\u2139") + reloadMsg,
41931
+ isLast: true
41932
+ });
41933
+ }
41934
+ if (lines.length > 0) {
41935
+ lines[lines.length - 1].isLast = true;
41936
+ }
41937
+ for (const line of lines) {
41938
+ logger.tree(line.text, line.isLast);
41628
41939
  }
41629
41940
  }
41630
41941
  const otherWarnings = getRemainingWarnings(allWarnings);
41631
41942
  if (otherWarnings.length > 0) {
41632
- console.log("");
41633
- logger.subtitle("Warnings");
41634
- for (const warning of otherWarnings) {
41635
- logger.warn(` ${warning}`);
41943
+ logger.section("Warnings");
41944
+ const lastIdx = otherWarnings.length - 1;
41945
+ for (let i = 0;i < otherWarnings.length; i++) {
41946
+ logger.tree(yellow("\u26A0") + ` ${otherWarnings[i]}`, i === lastIdx);
41636
41947
  }
41637
41948
  }
41638
41949
  };
@@ -41646,34 +41957,55 @@ var renderInstalledComponents = function(result, agentManager12, projectPath) {
41646
41957
  skillGroups.set(targetDir, existing);
41647
41958
  }
41648
41959
  if (skillGroups.size > 0) {
41649
- logger.subtitle("Skills");
41650
- for (const [targetDir, data] of skillGroups) {
41651
- logger.info(` ${getAgentLabel([...data.agents], agentManager12)}: ${green(String(data.skillNames.size))} skill(s) -> ${formatPathForDisplay(targetDir, projectPath)}`);
41652
- }
41960
+ logger.section("Skills");
41961
+ const entries = [...skillGroups.entries()];
41653
41962
  const copiedFallbacks = result.skills.installed.filter((item) => item.symlinkFailed);
41963
+ const totalItems = entries.length + (copiedFallbacks.length > 0 ? 1 : 0);
41964
+ let idx = 0;
41965
+ for (const [targetDir, data] of entries) {
41966
+ idx++;
41967
+ const agentLabel = colorAgentLabel([...data.agents], agentManager12);
41968
+ logger.tree(`${agentLabel}: ${green(String(data.skillNames.size))} skill(s) -> ${dim(formatPathForDisplay(targetDir, projectPath))}`, idx === totalItems);
41969
+ }
41654
41970
  if (copiedFallbacks.length > 0) {
41655
- logger.warn(` Symlink creation failed for ${copiedFallbacks.length} skill install(s); copied the files instead.`);
41971
+ logger.tree(yellow("\u26A0") + ` Symlink creation failed for ${copiedFallbacks.length} skill install(s); copied the files instead.`, true);
41656
41972
  }
41657
41973
  }
41658
41974
  if (result.mcpServers.applied.length > 0) {
41659
- logger.subtitle("MCP");
41975
+ logger.section("MCP Servers");
41660
41976
  const byAgent = new Map;
41661
41977
  for (const item of result.mcpServers.applied) {
41662
41978
  const list = byAgent.get(item.agent) || [];
41663
41979
  list.push(item.name);
41664
41980
  byAgent.set(item.agent, list);
41665
41981
  }
41666
- for (const [agent, servers] of byAgent) {
41667
- logger.info(` ${agentManager12.getAgentById(agent)?.name || agent}: ${cyan(String(servers.length))} server(s) [${servers.join(", ")}]`);
41982
+ const entries = [...byAgent.entries()];
41983
+ for (let i = 0;i < entries.length; i++) {
41984
+ const [agent, servers] = entries[i];
41985
+ const agentName = agentManager12.getAgentById(agent)?.name || agent;
41986
+ const coloredName = isClaudeAgent(agent) ? orange(agentName) : agentName;
41987
+ logger.tree(`${coloredName}: ${cyan(String(servers.length))} server(s) [${servers.join(", ")}]`, i === entries.length - 1);
41668
41988
  }
41669
41989
  }
41670
41990
  if (result.nativePlugins.installed.length > 0) {
41671
- logger.subtitle("Native");
41672
- for (const nativePlugin of result.nativePlugins.installed) {
41673
- logger.info(` ${agentManager12.getAgentById(nativePlugin.agent)?.name || nativePlugin.agent}: ${formatPathForDisplay(nativePlugin.installPath, projectPath)}`);
41991
+ logger.section("Native Install");
41992
+ for (let i = 0;i < result.nativePlugins.installed.length; i++) {
41993
+ const nativePlugin = result.nativePlugins.installed[i];
41994
+ const agentName = agentManager12.getAgentById(nativePlugin.agent)?.name || nativePlugin.agent;
41995
+ const coloredName = isClaudeAgent(nativePlugin.agent) ? orange(agentName) : agentName;
41996
+ logger.tree(`${coloredName}: ${dim(formatPathForDisplay(nativePlugin.installPath, projectPath))}`, i === result.nativePlugins.installed.length - 1);
41674
41997
  }
41675
41998
  }
41676
41999
  };
42000
+ var isClaudeAgent = function(agentId) {
42001
+ return agentId === "claude" || agentId.startsWith("claude-");
42002
+ };
42003
+ var colorAgentLabel = function(agentIds, agentManager12) {
42004
+ return agentIds.map((agentId) => {
42005
+ const name = agentManager12.getAgentById(agentId)?.name || agentId;
42006
+ return isClaudeAgent(agentId) ? orange(name) : name;
42007
+ }).join(", ");
42008
+ };
41677
42009
  var buildGlobalPluginGroups = function(agentManager12, projectPath) {
41678
42010
  const dirToAgents = new Map;
41679
42011
  for (const agent of agentManager12.getAllAgents()) {
@@ -41696,6 +42028,25 @@ var buildGlobalPluginGroups = function(agentManager12, projectPath) {
41696
42028
  compatibleAgentNames: []
41697
42029
  }));
41698
42030
  };
42031
+ var getPluginGroupDescription = function(group, preview, projectPath) {
42032
+ const portableSummary = getPortableComponentSummary(preview);
42033
+ if (!preview.nativePreview) {
42034
+ return portableSummary;
42035
+ }
42036
+ const containsClaudeCode = group.agents.some((agent) => agent.id === "claude");
42037
+ if (!containsClaudeCode) {
42038
+ return `${portableSummary}. Skills will be installed here, but Claude-specific components will not be fully available for these agents.`;
42039
+ }
42040
+ const otherAgents = group.agents.filter((agent) => agent.id !== "claude").map((agent) => agent.name);
42041
+ const installPath = formatPathForDisplay(preview.nativePreview.installPath, projectPath);
42042
+ if (otherAgents.length === 0) {
42043
+ return `${portableSummary}. Full plugin support is available in Claude Code; the native plugin installs at ${installPath}.`;
42044
+ }
42045
+ const otherAgentsLabel = otherAgents.join(", ");
42046
+ const shareVerb = otherAgents.length === 1 ? "shares" : "share";
42047
+ const receiveVerb = otherAgents.length === 1 ? "receives" : "receive";
42048
+ return `${portableSummary}. Full plugin support is available in Claude Code; the native plugin installs at ${installPath}. ${otherAgentsLabel} ${shareVerb} this skills directory but only ${receiveVerb} the installed skills.`;
42049
+ };
41699
42050
  async function interactiveAgentSelect(pluginManager2, agentManager12, projectPath, global3, preview) {
41700
42051
  let installGlobal = !!global3;
41701
42052
  let groups = installGlobal ? buildGlobalPluginGroups(agentManager12, projectPath) : (await pluginManager2.groupAgentsBySkillsDir(projectPath, false)).map((group) => ({
@@ -41733,16 +42084,14 @@ async function interactiveAgentSelect(pluginManager2, agentManager12, projectPat
41733
42084
  const response = await import_prompts3.default({
41734
42085
  type: "multiselect",
41735
42086
  name: "groups",
41736
- message: installGlobal ? "Select target global agent skills directories:" : "Select target agent skills directories:",
42087
+ message: installGlobal ? "Select which global agents should receive this plugin:" : "Select which agents should receive this plugin:",
41737
42088
  instructions: false,
41738
42089
  min: 1,
41739
42090
  choices: groups.map((group) => {
41740
- const containsClaude = group.agents.some((agent) => agent.id === "claude");
41741
42091
  const compatible = group.compatibleAgentNames.length > 0 ? dim(` (also compatible: ${group.compatibleAgentNames.join(", ")})`) : "";
41742
- const description = preview.nativePreview ? containsClaude ? `${getPortableComponentSummary(preview)}. Also installs the Claude native plugin at ${formatPathForDisplay(preview.nativePreview.installPath, projectPath)}.` : `${getPortableComponentSummary(preview)} only. Claude-only components remain unavailable for these agents.` : getPortableComponentSummary(preview);
41743
42092
  return {
41744
42093
  title: `${group.displayDir} -> ${getAgentLabel(group.agents.map((agent) => agent.id), agentManager12)}${compatible}`,
41745
- description,
42094
+ description: getPluginGroupDescription(group, preview, projectPath),
41746
42095
  value: group.agents.map((agent) => agent.id),
41747
42096
  selected: true
41748
42097
  };