agentinit 1.16.1 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -16945,6 +16945,13 @@ var init_marketplaceRegistry = __esm(() => {
16945
16945
  CUSTOM_MARKETPLACE_CACHE_TTL_MS = 3600000;
16946
16946
  });
16947
16947
 
16948
+ // dist/types/skills.js
16949
+ var SHARED_SKILLS_TARGET_ID, SHARED_SKILLS_TARGET_NAME;
16950
+ var init_skills = __esm(() => {
16951
+ SHARED_SKILLS_TARGET_ID = "agents";
16952
+ SHARED_SKILLS_TARGET_NAME = "AGENTS.md ecosystem";
16953
+ });
16954
+
16948
16955
  // dist/core/mcpFilter.js
16949
16956
  class MCPFilter {
16950
16957
  static filterForAgent(agent, servers) {
@@ -18518,7 +18525,7 @@ var init_pluginManager = __esm(() => {
18518
18525
  });
18519
18526
 
18520
18527
  // dist/core/skillsManager.js
18521
- import {resolve as resolve8, join as join5, relative as relative3} from "path";
18528
+ import {resolve as resolve8, join as join5, relative as relative3, basename as basename3, dirname as dirname3} from "path";
18522
18529
  import {promises as fs24} from "fs";
18523
18530
  import {homedir as homedir5, tmpdir} from "os";
18524
18531
  import {execFile} from "child_process";
@@ -18526,6 +18533,7 @@ import {promisify} from "util";
18526
18533
 
18527
18534
  class SkillsManager {
18528
18535
  agentManager;
18536
+ preparedSourceContexts = new Map;
18529
18537
  constructor(agentManager3) {
18530
18538
  this.agentManager = agentManager3 || new AgentManager;
18531
18539
  }
@@ -18533,15 +18541,9 @@ class SkillsManager {
18533
18541
  if (source.startsWith(".") || source.startsWith("/") || source.startsWith("~")) {
18534
18542
  return { type: "local", path: source };
18535
18543
  }
18536
- if (source.startsWith("https://github.com/") || source.startsWith("http://github.com/")) {
18537
- const url = source.replace(/\.git$/, "");
18538
- const match = url.match(/github\.com\/([^/]+)\/([^/]+)/);
18539
- return {
18540
- type: "github",
18541
- url: `https://github.com/${match?.[1]}/${match?.[2]}.git`,
18542
- owner: match?.[1],
18543
- repo: match?.[2]
18544
- };
18544
+ const githubUrlSource = this.parseGitHubHttpSource(source);
18545
+ if (githubUrlSource) {
18546
+ return githubUrlSource;
18545
18547
  }
18546
18548
  if (source.startsWith("git@") || source.endsWith(".git")) {
18547
18549
  return { type: "github", url: source };
@@ -18556,6 +18558,10 @@ class SkillsManager {
18556
18558
  pluginName: source
18557
18559
  };
18558
18560
  }
18561
+ const githubShorthandSource = this.parseGitHubShorthandSource(source);
18562
+ if (githubShorthandSource?.subpath) {
18563
+ return githubShorthandSource;
18564
+ }
18559
18565
  const marketplacePrefixMatch = source.match(/^([a-zA-Z0-9._-]+)\/(.+)$/);
18560
18566
  if (marketplacePrefixMatch) {
18561
18567
  const [, marketplaceId, pluginName] = marketplacePrefixMatch;
@@ -18567,14 +18573,8 @@ class SkillsManager {
18567
18573
  };
18568
18574
  }
18569
18575
  }
18570
- if (/^[a-zA-Z0-9._-]+\/[a-zA-Z0-9._-]+$/.test(source)) {
18571
- const [owner, repo] = source.split("/");
18572
- return {
18573
- type: "github",
18574
- url: `https://github.com/${owner}/${repo}.git`,
18575
- owner,
18576
- repo
18577
- };
18576
+ if (githubShorthandSource) {
18577
+ return githubShorthandSource;
18578
18578
  }
18579
18579
  return { type: "local", path: source };
18580
18580
  }
@@ -18613,6 +18613,54 @@ class SkillsManager {
18613
18613
  implicitSkills: []
18614
18614
  };
18615
18615
  }
18616
+ parseGitHubHttpSource(source) {
18617
+ if (!source.startsWith("https://github.com/") && !source.startsWith("http://github.com/")) {
18618
+ return null;
18619
+ }
18620
+ try {
18621
+ const parsedUrl = new URL(source);
18622
+ const segments = parsedUrl.pathname.replace(/\/+$/, "").split("/").filter(Boolean);
18623
+ if (segments.length < 2) {
18624
+ return null;
18625
+ }
18626
+ const [owner, rawRepo, ...rest] = segments;
18627
+ const repo = rawRepo?.replace(/\.git$/, "");
18628
+ if (!owner || !repo) {
18629
+ return null;
18630
+ }
18631
+ let subpath;
18632
+ if (rest[0] === "tree" || rest[0] === "blob") {
18633
+ if (rest.length > 2) {
18634
+ subpath = rest.slice(2).join("/");
18635
+ }
18636
+ } else if (rest.length > 0) {
18637
+ subpath = rest.join("/");
18638
+ }
18639
+ return {
18640
+ type: "github",
18641
+ url: `https://github.com/${owner}/${repo}.git`,
18642
+ owner,
18643
+ repo,
18644
+ ...subpath ? { subpath } : {}
18645
+ };
18646
+ } catch {
18647
+ return null;
18648
+ }
18649
+ }
18650
+ parseGitHubShorthandSource(source) {
18651
+ const githubShorthandMatch = source.match(/^([a-zA-Z0-9._-]+)\/([a-zA-Z0-9._-]+)(?:\/(.+))?$/);
18652
+ if (!githubShorthandMatch) {
18653
+ return null;
18654
+ }
18655
+ const [, owner, repo, subpath] = githubShorthandMatch;
18656
+ return {
18657
+ type: "github",
18658
+ url: `https://github.com/${owner}/${repo}.git`,
18659
+ owner,
18660
+ repo,
18661
+ ...subpath ? { subpath } : {}
18662
+ };
18663
+ }
18616
18664
  async parseSkillMd(filePath) {
18617
18665
  const content = await readFileIfExists(filePath);
18618
18666
  if (!content)
@@ -18628,7 +18676,7 @@ class SkillsManager {
18628
18676
  }
18629
18677
  }
18630
18678
  async discoverSkills(repoPath) {
18631
- const skills = [];
18679
+ const skills2 = [];
18632
18680
  const seen = new Set;
18633
18681
  for (const searchDir of SKILL_SEARCH_DIRS) {
18634
18682
  const fullDir = resolve8(repoPath, searchDir);
@@ -18639,7 +18687,7 @@ class SkillsManager {
18639
18687
  const parsed = await this.parseSkillMd(directSkillMd);
18640
18688
  if (parsed && !seen.has(parsed.name)) {
18641
18689
  seen.add(parsed.name);
18642
- skills.push({ ...parsed, path: resolve8(fullDir) });
18690
+ skills2.push({ ...parsed, path: resolve8(fullDir) });
18643
18691
  }
18644
18692
  }
18645
18693
  const directSkillMdLower = join5(fullDir, "skill.md");
@@ -18647,7 +18695,7 @@ class SkillsManager {
18647
18695
  const parsed = await this.parseSkillMd(directSkillMdLower);
18648
18696
  if (parsed && !seen.has(parsed.name)) {
18649
18697
  seen.add(parsed.name);
18650
- skills.push({ ...parsed, path: resolve8(fullDir) });
18698
+ skills2.push({ ...parsed, path: resolve8(fullDir) });
18651
18699
  }
18652
18700
  }
18653
18701
  if (!await isDirectory(fullDir))
@@ -18665,11 +18713,11 @@ class SkillsManager {
18665
18713
  const parsed = await this.parseSkillMd(skillFile);
18666
18714
  if (parsed && !seen.has(parsed.name)) {
18667
18715
  seen.add(parsed.name);
18668
- skills.push({ ...parsed, path: entryPath });
18716
+ skills2.push({ ...parsed, path: entryPath });
18669
18717
  }
18670
18718
  }
18671
18719
  }
18672
- return skills;
18720
+ return skills2;
18673
18721
  }
18674
18722
  async cloneRepo(url) {
18675
18723
  const tempDir = await fs24.mkdtemp(join5(tmpdir(), "agentinit-skills-"));
@@ -18732,13 +18780,55 @@ class SkillsManager {
18732
18780
  warnings
18733
18781
  };
18734
18782
  }
18735
- async discoverFromSource(source, projectPath, options2 = {}) {
18783
+ async cleanupTempDir(tempDir) {
18784
+ if (!tempDir) {
18785
+ return;
18786
+ }
18787
+ await fs24.rm(tempDir, { recursive: true, force: true }).catch(() => {
18788
+ });
18789
+ }
18790
+ async resolveDiscoveryRoot(repoPath, source, sourceLabel) {
18791
+ const resolvedRepoPath = resolve8(repoPath);
18792
+ if (source.type !== "github" || !source.subpath) {
18793
+ return resolvedRepoPath;
18794
+ }
18795
+ const discoveryRoot = resolve8(resolvedRepoPath, source.subpath);
18796
+ if (!this.isWithinPath(resolvedRepoPath, discoveryRoot)) {
18797
+ throw new Error(`Invalid GitHub source path "${source.subpath}" in ${sourceLabel}`);
18798
+ }
18799
+ if (!await fileExists(discoveryRoot)) {
18800
+ throw new Error(`Source path not found in repository: ${sourceLabel}`);
18801
+ }
18802
+ const [realRepoPath, realDiscoveryRoot] = await Promise.all([
18803
+ resolveRealPathOrSelf(resolvedRepoPath),
18804
+ resolveRealPathOrSelf(discoveryRoot)
18805
+ ]);
18806
+ if (!this.isWithinPath(realRepoPath, realDiscoveryRoot)) {
18807
+ throw new Error(`Invalid GitHub source path "${source.subpath}" in ${sourceLabel}`);
18808
+ }
18809
+ if (await isDirectory(realDiscoveryRoot)) {
18810
+ return realDiscoveryRoot;
18811
+ }
18812
+ if (basename3(realDiscoveryRoot).toLowerCase() === "skill.md") {
18813
+ return dirname3(realDiscoveryRoot);
18814
+ }
18815
+ throw new Error(`GitHub source must reference a skill directory or SKILL.md: ${sourceLabel}`);
18816
+ }
18817
+ async loadDiscoveredSkillsContext(source, projectPath, options2 = {}) {
18736
18818
  const request = this.resolveSourceRequest(source, options2);
18737
18819
  const resolved = request.source;
18738
18820
  let tempDir = null;
18821
+ const cleanup = async () => {
18822
+ await this.cleanupTempDir(tempDir);
18823
+ tempDir = null;
18824
+ };
18739
18825
  try {
18740
18826
  if (resolved.type === "marketplace") {
18741
- return await this.discoverMarketplaceSkills(resolved, projectPath);
18827
+ const discovered = await this.discoverMarketplaceSkills(resolved, projectPath);
18828
+ return {
18829
+ ...discovered,
18830
+ cleanup
18831
+ };
18742
18832
  }
18743
18833
  let repoPath;
18744
18834
  if (resolved.type === "github") {
@@ -18753,30 +18843,71 @@ class SkillsManager {
18753
18843
  throw this.getMissingLocalPathError(source, repoPath);
18754
18844
  }
18755
18845
  }
18756
- let skills = await this.discoverSkills(repoPath);
18846
+ const discoveryRoot = await this.resolveDiscoveryRoot(repoPath, resolved, source);
18847
+ let skills2 = await this.discoverSkills(discoveryRoot);
18757
18848
  let pluginWarnings = [];
18758
- if (skills.length === 0) {
18759
- const pluginBackedSkills = await this.discoverPortablePluginSkills(repoPath, source, resolved, projectPath);
18849
+ if (skills2.length === 0) {
18850
+ const pluginBackedSkills = await this.discoverPortablePluginSkills(discoveryRoot, source, resolved, projectPath);
18760
18851
  if (pluginBackedSkills) {
18761
- skills = pluginBackedSkills.skills;
18852
+ skills2 = pluginBackedSkills.skills;
18762
18853
  pluginWarnings = pluginBackedSkills.warnings;
18763
18854
  }
18764
18855
  }
18765
18856
  if (request.implicitSkills.length > 0) {
18766
18857
  const names = new Set(request.implicitSkills.map((skill) => skill.toLowerCase()));
18767
- skills = skills.filter((skill) => names.has(skill.name.toLowerCase()));
18858
+ skills2 = skills2.filter((skill) => names.has(skill.name.toLowerCase()));
18768
18859
  }
18769
18860
  const warnings = [
18770
18861
  ...pluginWarnings,
18771
18862
  ...request.implicitSkills.length > 0 ? [`Resolved "${source}" from the default skills catalog ${DEFAULT_SKILLS_CATALOG.owner}/${DEFAULT_SKILLS_CATALOG.repo}. Use "./${source}" for a local path.`] : []
18772
18863
  ];
18773
- return { skills, warnings };
18864
+ return { skills: skills2, warnings, cleanup };
18865
+ } catch (error) {
18866
+ await cleanup();
18867
+ throw error;
18868
+ }
18869
+ }
18870
+ async discoverFromSource(source, projectPath, options2 = {}) {
18871
+ const context = await this.loadDiscoveredSkillsContext(source, projectPath, options2);
18872
+ try {
18873
+ return {
18874
+ skills: context.skills,
18875
+ warnings: context.warnings
18876
+ };
18774
18877
  } finally {
18775
- if (tempDir) {
18776
- await fs24.rm(tempDir, { recursive: true, force: true }).catch(() => {
18777
- });
18778
- }
18878
+ await context.cleanup();
18879
+ }
18880
+ }
18881
+ getPreparedSourceKey(source, projectPath, from) {
18882
+ return `${projectPath}\n${from || ""}\n${source}`;
18883
+ }
18884
+ async storePreparedSourceContext(source, projectPath, from, context) {
18885
+ const key = this.getPreparedSourceKey(source, projectPath, from);
18886
+ const existing = this.preparedSourceContexts.get(key);
18887
+ this.preparedSourceContexts.set(key, context);
18888
+ if (existing && existing !== context) {
18889
+ await existing.cleanup();
18890
+ }
18891
+ }
18892
+ takePreparedSourceContext(source, projectPath, from) {
18893
+ const key = this.getPreparedSourceKey(source, projectPath, from);
18894
+ const existing = this.preparedSourceContexts.get(key) || null;
18895
+ if (existing) {
18896
+ this.preparedSourceContexts.delete(key);
18779
18897
  }
18898
+ return existing;
18899
+ }
18900
+ async prepareSource(source, projectPath, options2 = {}) {
18901
+ const context = await this.loadDiscoveredSkillsContext(source, projectPath, options2);
18902
+ await this.storePreparedSourceContext(source, projectPath, options2.from, context);
18903
+ return {
18904
+ skills: context.skills,
18905
+ warnings: context.warnings
18906
+ };
18907
+ }
18908
+ async discardPreparedSource(source, projectPath, options2 = {}) {
18909
+ const context = this.takePreparedSourceContext(source, projectPath, options2.from);
18910
+ await context?.cleanup();
18780
18911
  }
18781
18912
  async getTargetAgents(projectPath, options2) {
18782
18913
  if (options2.agents && options2.agents.length > 0) {
@@ -18905,6 +19036,27 @@ class SkillsManager {
18905
19036
  }
18906
19037
  return plan;
18907
19038
  }
19039
+ async installSkillToCanonicalStore(skillPath, skillName, projectPath, options2 = {}) {
19040
+ const plan = this.getCanonicalInstallPlan(skillName, projectPath, options2);
19041
+ await this.cleanAndCreateDirectory(plan.path);
19042
+ await this.copyDir(skillPath, plan.path);
19043
+ return plan;
19044
+ }
19045
+ async installSkillFromContentToCanonicalStore(skillName, skillContent, projectPath, options2 = {}) {
19046
+ const plan = this.getCanonicalInstallPlan(skillName, projectPath, options2);
19047
+ await this.cleanAndCreateDirectory(plan.path);
19048
+ await fs24.writeFile(join5(plan.path, "SKILL.md"), skillContent, "utf8");
19049
+ return plan;
19050
+ }
19051
+ getCanonicalInstallPlan(skillName, projectPath, options2 = {}) {
19052
+ const normalizedSkillName = this.normalizeSkillName(skillName);
19053
+ const canonicalPath = this.resolveInstallPath(this.getCanonicalSkillsDir(projectPath, options2.global ?? false), normalizedSkillName);
19054
+ return {
19055
+ path: canonicalPath,
19056
+ canonicalPath,
19057
+ mode: "symlink"
19058
+ };
19059
+ }
18908
19060
  normalizeSkillName(skillName) {
18909
19061
  const normalized = skillName.trim();
18910
19062
  if (!normalized) {
@@ -18940,58 +19092,76 @@ class SkillsManager {
18940
19092
  await fs24.cp(src, dest, { recursive: true, dereference: true });
18941
19093
  }
18942
19094
  async addFromSource(source, projectPath, options2 = {}) {
18943
- const discovered = await this.discoverFromSource(source, projectPath, {
19095
+ const context = this.takePreparedSourceContext(source, projectPath, options2.from) || await this.loadDiscoveredSkillsContext(source, projectPath, {
18944
19096
  ...options2.from !== undefined ? { from: options2.from } : {}
18945
19097
  });
18946
- let skills = discovered.skills;
18947
- if (skills.length === 0) {
18948
- return { installed: [], skipped: [], warnings: discovered.warnings };
18949
- }
18950
- if (options2.skills && options2.skills.length > 0) {
18951
- const names = new Set(options2.skills.map((skill) => skill.toLowerCase()));
18952
- skills = skills.filter((skill) => names.has(skill.name.toLowerCase()));
18953
- }
18954
- const agents = await this.getTargetAgents(projectPath, options2);
18955
- if (agents.length === 0) {
18956
- return {
18957
- installed: [],
18958
- skipped: skills.map((skill) => ({ skill, reason: "No target agents found" })),
18959
- warnings: discovered.warnings
18960
- };
18961
- }
18962
- const result = { installed: [], skipped: [], warnings: discovered.warnings };
18963
- const installableAgents = [];
18964
- for (const agent of agents) {
18965
- if (!agent.supportsSkills()) {
18966
- for (const skill of skills) {
18967
- result.skipped.push({ skill, reason: `${agent.name} does not support skills` });
19098
+ try {
19099
+ let skills2 = context.skills;
19100
+ if (skills2.length === 0) {
19101
+ return { installed: [], skipped: [], warnings: context.warnings };
19102
+ }
19103
+ if (options2.skills && options2.skills.length > 0) {
19104
+ const names = new Set(options2.skills.map((skill) => skill.toLowerCase()));
19105
+ skills2 = skills2.filter((skill) => names.has(skill.name.toLowerCase()));
19106
+ }
19107
+ const installToSharedStore = options2.agents?.includes(SHARED_SKILLS_TARGET_ID) ?? false;
19108
+ const agents = await this.getTargetAgents(projectPath, options2);
19109
+ if (agents.length === 0 && !installToSharedStore) {
19110
+ return {
19111
+ installed: [],
19112
+ skipped: skills2.map((skill) => ({ skill, reason: "No target agents found" })),
19113
+ warnings: context.warnings
19114
+ };
19115
+ }
19116
+ const result = { installed: [], skipped: [], warnings: context.warnings };
19117
+ const installableAgents = [];
19118
+ if (installToSharedStore) {
19119
+ for (const skill of skills2) {
19120
+ try {
19121
+ const installOptions = {
19122
+ ...options2.global !== undefined ? { global: options2.global } : {}
19123
+ };
19124
+ const installed = skill.generatedContent ? await this.installSkillFromContentToCanonicalStore(skill.name, skill.generatedContent, projectPath, installOptions) : await this.installSkillToCanonicalStore(skill.path, skill.name, projectPath, installOptions);
19125
+ result.installed.push({ skill, agent: SHARED_SKILLS_TARGET_ID, ...installed });
19126
+ } catch (error) {
19127
+ result.skipped.push({ skill, reason: error.message });
19128
+ }
18968
19129
  }
18969
- continue;
18970
19130
  }
18971
- const skillsDir = agent.getSkillsDir(projectPath, options2.global);
18972
- if (!skillsDir) {
18973
- for (const skill of skills) {
18974
- result.skipped.push({ skill, reason: `No skills directory for ${agent.name}` });
19131
+ for (const agent of agents) {
19132
+ if (!agent.supportsSkills()) {
19133
+ for (const skill of skills2) {
19134
+ result.skipped.push({ skill, reason: `${agent.name} does not support skills` });
19135
+ }
19136
+ continue;
18975
19137
  }
18976
- continue;
19138
+ const skillsDir = agent.getSkillsDir(projectPath, options2.global);
19139
+ if (!skillsDir) {
19140
+ for (const skill of skills2) {
19141
+ result.skipped.push({ skill, reason: `No skills directory for ${agent.name}` });
19142
+ }
19143
+ continue;
19144
+ }
19145
+ installableAgents.push(agent);
18977
19146
  }
18978
- installableAgents.push(agent);
18979
- }
18980
- for (const skill of skills) {
18981
- for (const agent of installableAgents) {
18982
- try {
18983
- const installOptions = {
18984
- ...options2.global !== undefined ? { global: options2.global } : {},
18985
- ...options2.copy !== undefined ? { copy: options2.copy } : {}
18986
- };
18987
- const installed = skill.generatedContent ? await this.installSkillFromContentForAgent(skill.name, skill.generatedContent, agent, projectPath, installOptions) : await this.installSkillForAgent(skill.path, skill.name, agent, projectPath, installOptions);
18988
- result.installed.push({ skill, agent: agent.id, ...installed });
18989
- } catch (error) {
18990
- result.skipped.push({ skill, reason: error.message });
19147
+ for (const skill of skills2) {
19148
+ for (const agent of installableAgents) {
19149
+ try {
19150
+ const installOptions = {
19151
+ ...options2.global !== undefined ? { global: options2.global } : {},
19152
+ ...options2.copy !== undefined ? { copy: options2.copy } : {}
19153
+ };
19154
+ const installed = skill.generatedContent ? await this.installSkillFromContentForAgent(skill.name, skill.generatedContent, agent, projectPath, installOptions) : await this.installSkillForAgent(skill.path, skill.name, agent, projectPath, installOptions);
19155
+ result.installed.push({ skill, agent: agent.id, ...installed });
19156
+ } catch (error) {
19157
+ result.skipped.push({ skill, reason: error.message });
19158
+ }
18991
19159
  }
18992
19160
  }
19161
+ return result;
19162
+ } finally {
19163
+ await context.cleanup();
18993
19164
  }
18994
- return result;
18995
19165
  }
18996
19166
  async listInstalled(projectPath, options2 = {}) {
18997
19167
  const agents = await this.getTargetAgents(projectPath, options2);
@@ -19053,6 +19223,43 @@ class SkillsManager {
19053
19223
  }
19054
19224
  }
19055
19225
  }
19226
+ const includeSharedTarget = !options2.agents || options2.agents.includes(SHARED_SKILLS_TARGET_ID);
19227
+ if (includeSharedTarget) {
19228
+ const scopes = options2.global ? ["global"] : ["project", "global"];
19229
+ const referencedCanonicalPaths = new Set(installed.map((entry) => entry.canonicalPath).filter((value) => !!value).map((value) => resolve8(value)));
19230
+ for (const scope of scopes) {
19231
+ const canonicalDir = this.getCanonicalSkillsDir(projectPath, scope === "global");
19232
+ if (!await fileExists(canonicalDir))
19233
+ continue;
19234
+ const entries = await listFiles(canonicalDir);
19235
+ for (const entry of entries) {
19236
+ const entryPath = join5(canonicalDir, entry);
19237
+ if (!await isDirectory(entryPath))
19238
+ continue;
19239
+ const resolvedEntryPath = resolve8(entryPath);
19240
+ if (referencedCanonicalPaths.has(resolvedEntryPath))
19241
+ continue;
19242
+ const skillMdPath = join5(entryPath, "SKILL.md");
19243
+ const skillMdPathLower = join5(entryPath, "skill.md");
19244
+ const skillFile = await fileExists(skillMdPath) ? skillMdPath : await fileExists(skillMdPathLower) ? skillMdPathLower : null;
19245
+ if (!skillFile)
19246
+ continue;
19247
+ const parsed = await this.parseSkillMd(skillFile);
19248
+ if (!parsed)
19249
+ continue;
19250
+ installed.push({
19251
+ name: parsed.name,
19252
+ description: parsed.description,
19253
+ path: entryPath,
19254
+ canonicalPath: resolvedEntryPath,
19255
+ agent: SHARED_SKILLS_TARGET_ID,
19256
+ scope,
19257
+ isSymlink: false,
19258
+ mode: "symlink"
19259
+ });
19260
+ }
19261
+ }
19262
+ }
19056
19263
  return installed;
19057
19264
  }
19058
19265
  async remove(skillNames, projectPath, options2 = {}) {
@@ -19063,11 +19270,19 @@ class SkillsManager {
19063
19270
  const skipped = [];
19064
19271
  const namesLower = new Set(skillNames.map((n) => n.toLowerCase()));
19065
19272
  const targetAgentIds = new Set(agents.map((agent) => agent.id));
19273
+ if (options2.agents?.includes(SHARED_SKILLS_TARGET_ID) || options2.agents === undefined) {
19274
+ targetAgentIds.add(SHARED_SKILLS_TARGET_ID);
19275
+ }
19066
19276
  const installed = await this.listInstalledForAgents(projectPath, allAgents, options2);
19067
- const scopedInstalled = installed.filter((entry) => options2.global ? entry.scope === "global" : entry.scope === "project");
19277
+ const sharedTargetInstalled = options2.agents?.includes(SHARED_SKILLS_TARGET_ID) ? await this.listInstalledForAgents(projectPath, [], options2) : [];
19278
+ const installedEntries = Array.from(new Map([...installed, ...sharedTargetInstalled].map((entry) => [
19279
+ `${entry.agent}:${entry.scope}:${entry.path}:${entry.name}`,
19280
+ entry
19281
+ ])).values());
19282
+ const scopedInstalled = installedEntries.filter((entry) => options2.global ? entry.scope === "global" : entry.scope === "project");
19068
19283
  const targetedEntries = scopedInstalled.filter((entry) => targetAgentIds.has(entry.agent) && namesLower.has(entry.name.toLowerCase()));
19069
19284
  const targetedKeys = new Set(targetedEntries.map((entry) => `${entry.agent}:${entry.scope}:${entry.path}:${entry.name}`));
19070
- const remainingEntries = installed.filter((entry) => !targetedKeys.has(`${entry.agent}:${entry.scope}:${entry.path}:${entry.name}`));
19285
+ const remainingEntries = installedEntries.filter((entry) => !targetedKeys.has(`${entry.agent}:${entry.scope}:${entry.path}:${entry.name}`));
19071
19286
  const removedPaths = new Set;
19072
19287
  const removedCanonicalPaths = new Set;
19073
19288
  for (const entry of targetedEntries) {
@@ -19127,6 +19342,7 @@ var init_skillsManager = __esm(() => {
19127
19342
  init_fs();
19128
19343
  init_agentManager();
19129
19344
  init_marketplaceRegistry();
19345
+ init_skills();
19130
19346
  execFileAsync = promisify(execFile);
19131
19347
  DEFAULT_SKILLS_CATALOG = {
19132
19348
  owner: "vercel-labs",
@@ -30951,7 +31167,7 @@ ${content}
30951
31167
  // dist/core/managedState.js
30952
31168
  init_fs();
30953
31169
  import {promises as fs28} from "fs";
30954
- import {dirname as dirname3, join as join6, relative as relative4, resolve as resolve10} from "path";
31170
+ import {dirname as dirname4, join as join6, relative as relative4, resolve as resolve10} from "path";
30955
31171
  var toPosixPath = function(value) {
30956
31172
  return value.replace(/\\/g, "/");
30957
31173
  };
@@ -30976,10 +31192,10 @@ async function copyDirectory(src, dest) {
30976
31192
  await copyDirectory(srcPath, destPath);
30977
31193
  } else if (entry.isSymbolicLink()) {
30978
31194
  const target = await fs28.readlink(srcPath);
30979
- await fs28.mkdir(dirname3(destPath), { recursive: true });
31195
+ await fs28.mkdir(dirname4(destPath), { recursive: true });
30980
31196
  await fs28.symlink(target, destPath);
30981
31197
  } else {
30982
- await fs28.mkdir(dirname3(destPath), { recursive: true });
31198
+ await fs28.mkdir(dirname4(destPath), { recursive: true });
30983
31199
  await fs28.copyFile(srcPath, destPath);
30984
31200
  }
30985
31201
  }
@@ -30989,7 +31205,7 @@ async function copyPath(src, dest) {
30989
31205
  if (!type2) {
30990
31206
  return;
30991
31207
  }
30992
- await fs28.mkdir(dirname3(dest), { recursive: true });
31208
+ await fs28.mkdir(dirname4(dest), { recursive: true });
30993
31209
  if (type2 === "symlink") {
30994
31210
  const target = await fs28.readlink(src);
30995
31211
  await fs28.symlink(target, dest);
@@ -31125,7 +31341,7 @@ class ManagedStateStore {
31125
31341
  if (!options2.dryRun) {
31126
31342
  await fs28.rm(absolutePath, { recursive: true, force: true }).catch(() => {
31127
31343
  });
31128
- await fs28.mkdir(dirname3(absolutePath), { recursive: true });
31344
+ await fs28.mkdir(dirname4(absolutePath), { recursive: true });
31129
31345
  await fs28.symlink(backupLinkTarget, absolutePath);
31130
31346
  }
31131
31347
  summary.restored++;
@@ -31507,11 +31723,11 @@ class MCPParser {
31507
31723
  // dist/constants/mcp.js
31508
31724
  import {readFileSync as readFileSync2} from "fs";
31509
31725
  import {fileURLToPath} from "url";
31510
- import {dirname as dirname4, join as join7} from "path";
31726
+ import {dirname as dirname5, join as join7} from "path";
31511
31727
  var getPackageVersion = function() {
31512
31728
  try {
31513
31729
  const __filename2 = fileURLToPath(import.meta.url);
31514
- const __dirname2 = dirname4(__filename2);
31730
+ const __dirname2 = dirname5(__filename2);
31515
31731
  const packageJsonPath = join7(__dirname2, "../../package.json");
31516
31732
  const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
31517
31733
  return packageJson.version || "1.0.0";
@@ -31543,11 +31759,11 @@ import {readFileSync as readFileSync4} from "fs";
31543
31759
 
31544
31760
  // dist/core/rulesTemplateLoader.js
31545
31761
  var toml = __toESM(require_toml(), 1);
31546
- import {resolve as resolve11, dirname as dirname5} from "path";
31762
+ import {resolve as resolve11, dirname as dirname6} from "path";
31547
31763
  import {fileURLToPath as fileURLToPath2} from "url";
31548
31764
  import {readFileSync as readFileSync3, readdirSync, existsSync as existsSync2} from "fs";
31549
31765
  var __filename2 = fileURLToPath2(import.meta.url);
31550
- var __dirname2 = dirname5(__filename2);
31766
+ var __dirname2 = dirname6(__filename2);
31551
31767
 
31552
31768
  class RulesTemplateLoader {
31553
31769
  templatesPath;
@@ -39783,7 +39999,7 @@ class MCPVerifier {
39783
39999
 
39784
40000
  // dist/core/gitignoreManager.js
39785
40001
  import {promises as fs31} from "fs";
39786
- import {dirname as dirname6, join as join8} from "path";
40002
+ import {dirname as dirname7, join as join8} from "path";
39787
40003
  var normalizeIgnorePath = function(projectPath, value) {
39788
40004
  const relative6 = value.startsWith(projectPath) ? value.slice(projectPath.length + 1) : value;
39789
40005
  const normalized = relative6.replace(/\\/g, "/").replace(/^\/+/, "");
@@ -39851,7 +40067,7 @@ async function updateManagedIgnoreFile(projectPath, paths5, options2 = {}) {
39851
40067
  existingContent = "";
39852
40068
  }
39853
40069
  const updatedContent = updateManagedBlock(existingContent, normalizedPaths);
39854
- await fs31.mkdir(dirname6(ignoreFilePath), { recursive: true });
40070
+ await fs31.mkdir(dirname7(ignoreFilePath), { recursive: true });
39855
40071
  await fs31.writeFile(ignoreFilePath, updatedContent, "utf8");
39856
40072
  return ignoreFilePath;
39857
40073
  }
@@ -39893,10 +40109,10 @@ var END_MARKER = "# END AgentInit Generated Files";
39893
40109
  init_agentManager();
39894
40110
  init_skillsManager();
39895
40111
  init_fs();
39896
- import {dirname as dirname7, join as join9} from "path";
40112
+ import {dirname as dirname8, join as join9} from "path";
39897
40113
  async function discoverProjectSkills(projectPath, skillsManager4) {
39898
40114
  const sources = [];
39899
- const skills = new Map;
40115
+ const skills2 = new Map;
39900
40116
  for (const sourceDir of PROJECT_SKILL_SOURCE_DIRS) {
39901
40117
  const absoluteSourceDir = join9(projectPath, sourceDir);
39902
40118
  if (!await fileExists(absoluteSourceDir)) {
@@ -39906,23 +40122,23 @@ async function discoverProjectSkills(projectPath, skillsManager4) {
39906
40122
  const discovered = await skillsManager4.discoverSkills(absoluteSourceDir);
39907
40123
  for (const skill of discovered) {
39908
40124
  const key = skill.name.toLowerCase();
39909
- if (!skills.has(key)) {
39910
- skills.set(key, skill);
40125
+ if (!skills2.has(key)) {
40126
+ skills2.set(key, skill);
39911
40127
  }
39912
40128
  }
39913
40129
  }
39914
40130
  return {
39915
40131
  sources,
39916
- skills: [...skills.values()]
40132
+ skills: [...skills2.values()]
39917
40133
  };
39918
40134
  }
39919
40135
  async function applyProjectSkills(projectPath, targetAgentIds, managedState2, options2 = {}) {
39920
40136
  const agentManager6 = new AgentManager;
39921
40137
  const skillsManager4 = new SkillsManager(agentManager6);
39922
- const { sources, skills } = await discoverProjectSkills(projectPath, skillsManager4);
40138
+ const { sources, skills: skills2 } = await discoverProjectSkills(projectPath, skillsManager4);
39923
40139
  const installed = [];
39924
40140
  const skipped = [];
39925
- if (skills.length === 0) {
40141
+ if (skills2.length === 0) {
39926
40142
  return {
39927
40143
  discovered: 0,
39928
40144
  sources,
@@ -39933,22 +40149,22 @@ async function applyProjectSkills(projectPath, targetAgentIds, managedState2, op
39933
40149
  const targetAgents = targetAgentIds.map((id) => agentManager6.getAgentById(id)).filter((agent) => !!agent);
39934
40150
  if (targetAgents.length === 0) {
39935
40151
  return {
39936
- discovered: skills.length,
40152
+ discovered: skills2.length,
39937
40153
  sources,
39938
40154
  installed,
39939
- skipped: skills.map((skill) => ({ skill, reason: "No target agents found" }))
40155
+ skipped: skills2.map((skill) => ({ skill, reason: "No target agents found" }))
39940
40156
  };
39941
40157
  }
39942
40158
  for (const agent of targetAgents) {
39943
40159
  if (!agent.supportsSkills()) {
39944
- for (const skill of skills) {
40160
+ for (const skill of skills2) {
39945
40161
  skipped.push({ skill, reason: `${agent.name} does not support skills` });
39946
40162
  }
39947
40163
  continue;
39948
40164
  }
39949
40165
  const skillsDir = agent.getSkillsDir(projectPath, false);
39950
40166
  if (!skillsDir) {
39951
- for (const skill of skills) {
40167
+ for (const skill of skills2) {
39952
40168
  skipped.push({ skill, reason: `No skills directory for ${agent.name}` });
39953
40169
  }
39954
40170
  continue;
@@ -39959,7 +40175,7 @@ async function applyProjectSkills(projectPath, targetAgentIds, managedState2, op
39959
40175
  continue;
39960
40176
  if (!agent.getSkillsDir(projectPath, false))
39961
40177
  continue;
39962
- for (const skill of skills) {
40178
+ for (const skill of skills2) {
39963
40179
  try {
39964
40180
  const installOptions = {
39965
40181
  ...options2.copy !== undefined ? { copy: options2.copy } : {}
@@ -39971,7 +40187,7 @@ async function applyProjectSkills(projectPath, targetAgentIds, managedState2, op
39971
40187
  await managedState2.trackGeneratedPath(generatedPath, {
39972
40188
  kind: "directory",
39973
40189
  source: "skills",
39974
- ignorePath: `${dirname7(generatedPath)}/`
40190
+ ignorePath: `${dirname8(generatedPath)}/`
39975
40191
  });
39976
40192
  }
39977
40193
  }
@@ -39983,7 +40199,7 @@ async function applyProjectSkills(projectPath, targetAgentIds, managedState2, op
39983
40199
  }
39984
40200
  }
39985
40201
  return {
39986
- discovered: skills.length,
40202
+ discovered: skills2.length,
39987
40203
  sources,
39988
40204
  installed,
39989
40205
  skipped
@@ -40985,10 +41201,11 @@ import {relative as relative7, resolve as resolve12} from "path";
40985
41201
  init_skillsManager();
40986
41202
  init_marketplaceRegistry();
40987
41203
  init_agentManager();
41204
+ init_skills();
40988
41205
  function registerSkillsCommand(program2) {
40989
41206
  const marketplaceHelp = getMarketplaceIds().join(", ");
40990
- const skills = program2.command("skills").description("Manage agent skills");
40991
- 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) => {
41207
+ const skills3 = program2.command("skills").description("Manage agent skills");
41208
+ skills3.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) => {
40992
41209
  logger.titleBox("AgentInit Skills");
40993
41210
  const agentManager9 = new AgentManager;
40994
41211
  const skillsManager5 = new SkillsManager(agentManager9);
@@ -41006,6 +41223,17 @@ function registerSkillsCommand(program2) {
41006
41223
  }
41007
41224
  return;
41008
41225
  }
41226
+ const verifySpinner = ora("Verifying skill source...").start();
41227
+ try {
41228
+ await skillsManager5.prepareSource(source, process.cwd(), {
41229
+ from: options2.from
41230
+ });
41231
+ verifySpinner.stop();
41232
+ } catch (error) {
41233
+ verifySpinner.fail("Failed to verify skill source");
41234
+ logger.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
41235
+ return;
41236
+ }
41009
41237
  let targetAgents = options2.agent;
41010
41238
  let targetGlobal = options2.global;
41011
41239
  if (!targetAgents && !options2.yes) {
@@ -41014,6 +41242,9 @@ function registerSkillsCommand(program2) {
41014
41242
  global: options2.global
41015
41243
  });
41016
41244
  if (selection?.aborted) {
41245
+ await skillsManager5.discardPreparedSource(source, process.cwd(), {
41246
+ from: options2.from
41247
+ });
41017
41248
  return;
41018
41249
  }
41019
41250
  if (selection?.agents && selection.agents.length > 0) {
@@ -41038,7 +41269,7 @@ function registerSkillsCommand(program2) {
41038
41269
  logger.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
41039
41270
  }
41040
41271
  });
41041
- 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) => {
41272
+ skills3.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) => {
41042
41273
  logger.titleBox("AgentInit Skills");
41043
41274
  const agentManager9 = new AgentManager;
41044
41275
  const skillsManager5 = new SkillsManager(agentManager9);
@@ -41067,7 +41298,7 @@ function registerSkillsCommand(program2) {
41067
41298
  if (skill.mode === "symlink") {
41068
41299
  existing.mode = "symlink";
41069
41300
  }
41070
- existing.agents.add(agentManager9.getAgentById(skill.agent)?.name || skill.agent);
41301
+ existing.agents.add(formatSkillTargetName(agentManager9, skill.agent));
41071
41302
  bySkill.set(key, existing);
41072
41303
  }
41073
41304
  for (const skill of bySkill.values()) {
@@ -41078,7 +41309,7 @@ function registerSkillsCommand(program2) {
41078
41309
  logger.info(` Agents: ${[...skill.agents].join(", ")}`);
41079
41310
  }
41080
41311
  });
41081
- 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) => {
41312
+ skills3.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) => {
41082
41313
  logger.titleBox("AgentInit Skills");
41083
41314
  if (!names || names.length === 0) {
41084
41315
  if (!options2.yes) {
@@ -41162,9 +41393,9 @@ async function resolveInteractiveSkillTargets(skillsManager5, agentManager9, sou
41162
41393
  instructions: false,
41163
41394
  min: 1,
41164
41395
  choices: availableGroups.map((group) => ({
41165
- title: `${group.displayDir} -> ${group.agentNames.join(", ")}${formatCompatibleAgents(group)}`,
41396
+ title: formatSkillGroupTitle(group),
41166
41397
  ...group.description ? { description: group.description } : {},
41167
- value: group.agents.map((agent) => agent.id),
41398
+ value: group.kind === "canonical-shared" ? [SHARED_SKILLS_TARGET_ID] : group.agents.map((agent) => agent.id),
41168
41399
  selected: shouldPreselectSkillGroup(group, installGlobal, detectedGroups.length > 0, recommendedAgentId)
41169
41400
  }))
41170
41401
  });
@@ -41213,15 +41444,23 @@ var buildSkillGroups = function(agents, projectPath, global3) {
41213
41444
  existing.push(agent);
41214
41445
  dirToAgents.set(skillsDir, existing);
41215
41446
  }
41216
- return Array.from(dirToAgents.entries()).map(([dir, groupedAgents]) => ({
41217
- dir,
41218
- displayDir: formatSkillsDir(projectPath, dir),
41219
- agents: groupedAgents,
41220
- agentNames: groupedAgents.map((agent) => agent.name),
41221
- compatibleAgents: [],
41222
- compatibleAgentNames: [],
41223
- kind: "native"
41224
- }));
41447
+ return Array.from(dirToAgents.entries()).map(([dir, groupedAgents]) => {
41448
+ const canonicalShared = resolve12(dir) === getCanonicalSkillsDirForScope(projectPath, !!global3) && groupedAgents.every((agent) => agent.getProjectSkillsStandard() === "agents");
41449
+ return {
41450
+ dir,
41451
+ displayDir: formatSkillsDir(projectPath, dir),
41452
+ agents: groupedAgents,
41453
+ agentNames: groupedAgents.map((agent) => agent.name),
41454
+ compatibleAgents: [],
41455
+ compatibleAgentNames: [],
41456
+ ...canonicalShared ? {
41457
+ description: `Install only into the shared AGENTS.md store. Compatible tools: ${groupedAgents.map((agent) => agent.name).join(", ")}.`,
41458
+ kind: "canonical-shared"
41459
+ } : {
41460
+ kind: "native"
41461
+ }
41462
+ };
41463
+ });
41225
41464
  };
41226
41465
  var prependCanonicalGlobalGroup = function(agentManager9, projectPath, groups) {
41227
41466
  const canonicalDir = getCanonicalGlobalSkillsDir();
@@ -41236,7 +41475,7 @@ var prependCanonicalGlobalGroup = function(agentManager9, projectPath, groups) {
41236
41475
  return [
41237
41476
  {
41238
41477
  ...existingCanonical,
41239
- description: existingCanonical.description || "Canonical shared skills store for the open AGENTS.md ecosystem.",
41478
+ description: existingCanonical.description || `Install only into the shared AGENTS.md store. Compatible tools: ${existingCanonical.agentNames.join(", ")}.`,
41240
41479
  kind: "canonical-shared"
41241
41480
  },
41242
41481
  ...remaining
@@ -41250,7 +41489,7 @@ var prependCanonicalGlobalGroup = function(agentManager9, projectPath, groups) {
41250
41489
  agentNames: sharedAgents.map((agent) => agent.name),
41251
41490
  compatibleAgents: [],
41252
41491
  compatibleAgentNames: [],
41253
- description: "Canonical shared skills store for the open AGENTS.md ecosystem.",
41492
+ description: `Install only into the shared AGENTS.md store. Compatible tools: ${sharedAgents.map((agent) => agent.name).join(", ")}.`,
41254
41493
  kind: "canonical-shared"
41255
41494
  },
41256
41495
  ...groups.map((group) => {
@@ -41288,12 +41527,15 @@ var formatPromptPath = function(path) {
41288
41527
  var getCanonicalGlobalSkillsDir = function() {
41289
41528
  return resolve12(homedir6(), ".agents/skills");
41290
41529
  };
41530
+ var getCanonicalSkillsDirForScope = function(projectPath, global3) {
41531
+ return global3 ? getCanonicalGlobalSkillsDir() : resolve12(projectPath, ".agents/skills");
41532
+ };
41291
41533
  var getCanonicalGlobalSkillsDisplayPath = function() {
41292
41534
  return formatPromptPath(getCanonicalGlobalSkillsDir());
41293
41535
  };
41294
41536
  var describeGlobalSkillGroup = function(group) {
41295
41537
  if (group.kind === "canonical-shared") {
41296
- return group.description;
41538
+ return group.description || `Install only into the shared AGENTS.md store. Compatible tools: ${group.agentNames.join(", ")}.`;
41297
41539
  }
41298
41540
  if (group.agents.every((agent) => agent.getProjectSkillsStandard() === "agents")) {
41299
41541
  return `Native agent directory linked to ${getCanonicalGlobalSkillsDisplayPath()} when symlinks are used.`;
@@ -41303,6 +41545,18 @@ var describeGlobalSkillGroup = function(group) {
41303
41545
  }
41304
41546
  return;
41305
41547
  };
41548
+ var formatSkillGroupTitle = function(group) {
41549
+ if (group.kind === "canonical-shared") {
41550
+ return `${group.displayDir} -> ${SHARED_SKILLS_TARGET_NAME}`;
41551
+ }
41552
+ return `${group.displayDir} -> ${group.agentNames.join(", ")}${formatCompatibleAgents(group)}`;
41553
+ };
41554
+ var formatSkillTargetName = function(agentManager9, agentId) {
41555
+ if (agentId === SHARED_SKILLS_TARGET_ID) {
41556
+ return SHARED_SKILLS_TARGET_NAME;
41557
+ }
41558
+ return agentManager9.getAgentById(agentId)?.name || agentId;
41559
+ };
41306
41560
  var shouldPreselectSkillGroup = function(group, installGlobal, hasDetectedGroups, recommendedAgentId) {
41307
41561
  const includesRecommendedAgent = !!recommendedAgentId && group.agents.some((agent) => agent.id === recommendedAgentId);
41308
41562
  if (!installGlobal) {
@@ -41355,18 +41609,18 @@ var buildSkillsAddCommand = function(source, from, extraArgs) {
41355
41609
  args.push(...extraArgs);
41356
41610
  return args.join(" ");
41357
41611
  };
41358
- var displayDiscoveredSkills = function(skills, warnings) {
41359
- if (skills.length === 0) {
41612
+ var displayDiscoveredSkills = function(skills3, warnings) {
41613
+ if (skills3.length === 0) {
41360
41614
  logger.info("No skills found in the source.");
41361
41615
  for (const warning of warnings) {
41362
41616
  logger.warn(warning);
41363
41617
  }
41364
41618
  return;
41365
41619
  }
41366
- logger.info(`Found ${green(String(skills.length))} skill(s):\n`);
41620
+ logger.info(`Found ${green(String(skills3.length))} skill(s):\n`);
41367
41621
  logger.info(" Name Description");
41368
41622
  logger.info(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
41369
- for (const skill of skills) {
41623
+ for (const skill of skills3) {
41370
41624
  const name = skill.name.padEnd(18);
41371
41625
  logger.info(` ${green(name)} ${skill.description}`);
41372
41626
  }
@@ -41407,7 +41661,7 @@ var displayInstallResult = function(result, spinner, agentManager9, skillsManage
41407
41661
  agents: new Set,
41408
41662
  skills: new Set
41409
41663
  };
41410
- existing.agents.add(agentManager9.getAgentById(item.agent)?.name || item.agent);
41664
+ existing.agents.add(formatSkillTargetName(agentManager9, item.agent));
41411
41665
  existing.skills.add(item.skill.name);
41412
41666
  byPath.set(path, existing);
41413
41667
  }
@@ -42228,7 +42482,7 @@ function registerRulesCommand(program2) {
42228
42482
  // dist/commands/plugins.js
42229
42483
  var import_prompts3 = __toESM(require_prompts3(), 1);
42230
42484
  import {homedir as homedir7} from "os";
42231
- import {dirname as dirname8, relative as relative8, resolve as resolve13} from "path";
42485
+ import {dirname as dirname9, relative as relative8, resolve as resolve13} from "path";
42232
42486
  init_pluginManager();
42233
42487
  init_agentManager();
42234
42488
  init_marketplaceRegistry();
@@ -42616,7 +42870,7 @@ var renderPluginWarnings = function(previewOrResult, projectPath) {
42616
42870
  var renderInstalledComponents = function(result, agentManager12, projectPath) {
42617
42871
  const skillGroups = new Map;
42618
42872
  for (const item of result.skills.installed) {
42619
- const targetDir = dirname8(item.path);
42873
+ const targetDir = dirname9(item.path);
42620
42874
  const existing = skillGroups.get(targetDir) || { agents: new Set, skillNames: new Set };
42621
42875
  existing.agents.add(item.agent);
42622
42876
  existing.skillNames.add(item.name);