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/CHANGELOG.md +14 -0
- package/README.md +49 -311
- package/dist/cli.js +385 -131
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +62 -16
- package/dist/commands/skills.js.map +1 -1
- package/dist/core/skillsManager.d.ts +25 -0
- package/dist/core/skillsManager.d.ts.map +1 -1
- package/dist/core/skillsManager.js +299 -76
- package/dist/core/skillsManager.js.map +1 -1
- package/dist/types/skills.d.ts +3 -0
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/types/skills.js +2 -1
- package/dist/types/skills.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
18537
|
-
|
|
18538
|
-
|
|
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 (
|
|
18571
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18716
|
+
skills2.push({ ...parsed, path: entryPath });
|
|
18669
18717
|
}
|
|
18670
18718
|
}
|
|
18671
18719
|
}
|
|
18672
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
18846
|
+
const discoveryRoot = await this.resolveDiscoveryRoot(repoPath, resolved, source);
|
|
18847
|
+
let skills2 = await this.discoverSkills(discoveryRoot);
|
|
18757
18848
|
let pluginWarnings = [];
|
|
18758
|
-
if (
|
|
18759
|
-
const pluginBackedSkills = await this.discoverPortablePluginSkills(
|
|
18849
|
+
if (skills2.length === 0) {
|
|
18850
|
+
const pluginBackedSkills = await this.discoverPortablePluginSkills(discoveryRoot, source, resolved, projectPath);
|
|
18760
18851
|
if (pluginBackedSkills) {
|
|
18761
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18776
|
-
|
|
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
|
|
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
|
-
|
|
18947
|
-
|
|
18948
|
-
|
|
18949
|
-
|
|
18950
|
-
|
|
18951
|
-
|
|
18952
|
-
|
|
18953
|
-
|
|
18954
|
-
|
|
18955
|
-
|
|
18956
|
-
|
|
18957
|
-
|
|
18958
|
-
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
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
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18979
|
-
|
|
18980
|
-
|
|
18981
|
-
|
|
18982
|
-
|
|
18983
|
-
|
|
18984
|
-
|
|
18985
|
-
|
|
18986
|
-
|
|
18987
|
-
|
|
18988
|
-
|
|
18989
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
31195
|
+
await fs28.mkdir(dirname4(destPath), { recursive: true });
|
|
30980
31196
|
await fs28.symlink(target, destPath);
|
|
30981
31197
|
} else {
|
|
30982
|
-
await fs28.mkdir(
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
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
|
|
40112
|
+
import {dirname as dirname8, join as join9} from "path";
|
|
39897
40113
|
async function discoverProjectSkills(projectPath, skillsManager4) {
|
|
39898
40114
|
const sources = [];
|
|
39899
|
-
const
|
|
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 (!
|
|
39910
|
-
|
|
40125
|
+
if (!skills2.has(key)) {
|
|
40126
|
+
skills2.set(key, skill);
|
|
39911
40127
|
}
|
|
39912
40128
|
}
|
|
39913
40129
|
}
|
|
39914
40130
|
return {
|
|
39915
40131
|
sources,
|
|
39916
|
-
skills: [...
|
|
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 (
|
|
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:
|
|
40152
|
+
discovered: skills2.length,
|
|
39937
40153
|
sources,
|
|
39938
40154
|
installed,
|
|
39939
|
-
skipped:
|
|
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
|
|
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
|
|
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
|
|
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: `${
|
|
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:
|
|
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
|
|
40991
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
41219
|
-
|
|
41220
|
-
|
|
41221
|
-
|
|
41222
|
-
|
|
41223
|
-
|
|
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 ||
|
|
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:
|
|
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(
|
|
41359
|
-
if (
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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);
|