@salesforce/b2c-tooling-sdk 0.0.0-nightly.20260119053920 → 0.0.0-nightly.20260121023856
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/cjs/cli/base-command.d.ts +5 -0
- package/dist/cjs/cli/base-command.js +22 -2
- package/dist/cjs/cli/base-command.js.map +1 -1
- package/dist/cjs/cli/hooks.d.ts +13 -5
- package/dist/cjs/cli/hooks.js.map +1 -1
- package/dist/cjs/config/resolver.d.ts +2 -1
- package/dist/cjs/config/resolver.js +11 -7
- package/dist/cjs/config/resolver.js.map +1 -1
- package/dist/cjs/config/sources/dw-json-source.d.ts +1 -0
- package/dist/cjs/config/sources/dw-json-source.js +1 -0
- package/dist/cjs/config/sources/dw-json-source.js.map +1 -1
- package/dist/cjs/config/sources/index.d.ts +1 -0
- package/dist/cjs/config/sources/index.js +1 -0
- package/dist/cjs/config/sources/index.js.map +1 -1
- package/dist/cjs/config/sources/mobify-source.d.ts +1 -0
- package/dist/cjs/config/sources/mobify-source.js +1 -0
- package/dist/cjs/config/sources/mobify-source.js.map +1 -1
- package/dist/cjs/config/sources/package-json-source.d.ts +14 -0
- package/dist/cjs/config/sources/package-json-source.js +86 -0
- package/dist/cjs/config/sources/package-json-source.js.map +1 -0
- package/dist/cjs/config/types.d.ts +12 -0
- package/dist/cjs/skills/agents.d.ts +41 -0
- package/dist/cjs/skills/agents.js +159 -0
- package/dist/cjs/skills/agents.js.map +1 -0
- package/dist/cjs/skills/github.d.ts +47 -0
- package/dist/cjs/skills/github.js +246 -0
- package/dist/cjs/skills/github.js.map +1 -0
- package/dist/cjs/skills/index.d.ts +42 -0
- package/dist/cjs/skills/index.js +14 -0
- package/dist/cjs/skills/index.js.map +1 -0
- package/dist/cjs/skills/installer.d.ts +34 -0
- package/dist/cjs/skills/installer.js +181 -0
- package/dist/cjs/skills/installer.js.map +1 -0
- package/dist/cjs/skills/parser.d.ts +39 -0
- package/dist/cjs/skills/parser.js +131 -0
- package/dist/cjs/skills/parser.js.map +1 -0
- package/dist/cjs/skills/types.d.ts +134 -0
- package/dist/cjs/skills/types.js +7 -0
- package/dist/cjs/skills/types.js.map +1 -0
- package/dist/esm/cli/base-command.d.ts +5 -0
- package/dist/esm/cli/base-command.js +22 -2
- package/dist/esm/cli/base-command.js.map +1 -1
- package/dist/esm/cli/hooks.d.ts +13 -5
- package/dist/esm/cli/hooks.js.map +1 -1
- package/dist/esm/config/resolver.d.ts +2 -1
- package/dist/esm/config/resolver.js +11 -7
- package/dist/esm/config/resolver.js.map +1 -1
- package/dist/esm/config/sources/dw-json-source.d.ts +1 -0
- package/dist/esm/config/sources/dw-json-source.js +1 -0
- package/dist/esm/config/sources/dw-json-source.js.map +1 -1
- package/dist/esm/config/sources/index.d.ts +1 -0
- package/dist/esm/config/sources/index.js +1 -0
- package/dist/esm/config/sources/index.js.map +1 -1
- package/dist/esm/config/sources/mobify-source.d.ts +1 -0
- package/dist/esm/config/sources/mobify-source.js +1 -0
- package/dist/esm/config/sources/mobify-source.js.map +1 -1
- package/dist/esm/config/sources/package-json-source.d.ts +14 -0
- package/dist/esm/config/sources/package-json-source.js +86 -0
- package/dist/esm/config/sources/package-json-source.js.map +1 -0
- package/dist/esm/config/types.d.ts +12 -0
- package/dist/esm/skills/agents.d.ts +41 -0
- package/dist/esm/skills/agents.js +159 -0
- package/dist/esm/skills/agents.js.map +1 -0
- package/dist/esm/skills/github.d.ts +47 -0
- package/dist/esm/skills/github.js +246 -0
- package/dist/esm/skills/github.js.map +1 -0
- package/dist/esm/skills/index.d.ts +42 -0
- package/dist/esm/skills/index.js +14 -0
- package/dist/esm/skills/index.js.map +1 -0
- package/dist/esm/skills/installer.d.ts +34 -0
- package/dist/esm/skills/installer.js +181 -0
- package/dist/esm/skills/installer.js.map +1 -0
- package/dist/esm/skills/parser.d.ts +39 -0
- package/dist/esm/skills/parser.js +131 -0
- package/dist/esm/skills/parser.js.map +1 -0
- package/dist/esm/skills/types.d.ts +134 -0
- package/dist/esm/skills/types.js +7 -0
- package/dist/esm/skills/types.js.map +1 -0
- package/package.json +12 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2
|
|
4
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
// Agent/IDE utilities
|
|
7
|
+
export { IDE_CONFIGS, ALL_IDE_TYPES, detectInstalledIdes, getSkillInstallPath, getIdeDisplayName, getIdeDocsUrl, } from './agents.js';
|
|
8
|
+
// GitHub/download utilities
|
|
9
|
+
export { getCacheDir, getRelease, listReleases, getCachedArtifact, downloadSkillsArtifact, clearCache, } from './github.js';
|
|
10
|
+
// Skill parsing
|
|
11
|
+
export { parseSkillFrontmatter, scanSkills, filterSkillsByName, findSkillsByName } from './parser.js';
|
|
12
|
+
// Installation
|
|
13
|
+
export { isSkillInstalled, installSkills, removeSkill } from './installer.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyDH,sBAAsB;AACtB,OAAO,EACL,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,4BAA4B;AAC5B,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,gBAAgB;AAChB,OAAO,EAAC,qBAAqB,EAAE,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAC,MAAM,aAAa,CAAC;AAEpG,eAAe;AACf,OAAO,EAAC,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { IdeType, InstallSkillsOptions, InstallSkillsResult, SkillMetadata } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a skill is already installed.
|
|
4
|
+
*
|
|
5
|
+
* @param skillName - Name of the skill
|
|
6
|
+
* @param ide - Target IDE
|
|
7
|
+
* @param options - Installation options
|
|
8
|
+
* @returns true if skill is installed, false otherwise
|
|
9
|
+
*/
|
|
10
|
+
export declare function isSkillInstalled(skillName: string, ide: IdeType, options: {
|
|
11
|
+
global: boolean;
|
|
12
|
+
projectRoot?: string;
|
|
13
|
+
}): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Install skills to target IDE directories.
|
|
16
|
+
*
|
|
17
|
+
* @param skills - Skills to install
|
|
18
|
+
* @param sourceDir - Directory containing extracted skills
|
|
19
|
+
* @param options - Installation options
|
|
20
|
+
* @returns Installation results
|
|
21
|
+
*/
|
|
22
|
+
export declare function installSkills(skills: SkillMetadata[], sourceDir: string, options: InstallSkillsOptions): Promise<InstallSkillsResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Remove an installed skill.
|
|
25
|
+
*
|
|
26
|
+
* @param skillName - Name of the skill to remove
|
|
27
|
+
* @param ide - Target IDE
|
|
28
|
+
* @param options - Installation options
|
|
29
|
+
* @returns true if removed, false if not found
|
|
30
|
+
*/
|
|
31
|
+
export declare function removeSkill(skillName: string, ide: IdeType, options: {
|
|
32
|
+
global: boolean;
|
|
33
|
+
projectRoot?: string;
|
|
34
|
+
}): Promise<boolean>;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2
|
|
4
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'node:fs';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
import { getSkillInstallPath } from './agents.js';
|
|
9
|
+
import { getLogger } from '../logging/logger.js';
|
|
10
|
+
/**
|
|
11
|
+
* Sanitize a skill name to prevent path traversal attacks.
|
|
12
|
+
*
|
|
13
|
+
* @param name - Skill name to sanitize
|
|
14
|
+
* @returns Sanitized name safe for use in file paths
|
|
15
|
+
*/
|
|
16
|
+
function sanitizeName(name) {
|
|
17
|
+
// Remove path separators and null bytes
|
|
18
|
+
let sanitized = name.replace(/[/\\:\0]/g, '');
|
|
19
|
+
// Remove leading/trailing dots and spaces
|
|
20
|
+
sanitized = sanitized.replace(/^[.\s]+|[.\s]+$/g, '');
|
|
21
|
+
// Limit length
|
|
22
|
+
if (sanitized.length > 255) {
|
|
23
|
+
sanitized = sanitized.slice(0, 255);
|
|
24
|
+
}
|
|
25
|
+
return sanitized;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Validate that a path is safely within a base directory.
|
|
29
|
+
*
|
|
30
|
+
* @param targetPath - Path to validate
|
|
31
|
+
* @param baseDir - Base directory that must contain targetPath
|
|
32
|
+
* @returns true if path is safe, false otherwise
|
|
33
|
+
*/
|
|
34
|
+
function isPathSafe(targetPath, baseDir) {
|
|
35
|
+
const resolvedTarget = path.resolve(targetPath);
|
|
36
|
+
const resolvedBase = path.resolve(baseDir);
|
|
37
|
+
// Ensure the target is within the base directory
|
|
38
|
+
return resolvedTarget.startsWith(resolvedBase + path.sep) || resolvedTarget === resolvedBase;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Recursively copy a directory.
|
|
42
|
+
*
|
|
43
|
+
* @param source - Source directory
|
|
44
|
+
* @param target - Target directory
|
|
45
|
+
*/
|
|
46
|
+
async function copyDirectory(source, target) {
|
|
47
|
+
const logger = getLogger();
|
|
48
|
+
let fileCount = 0;
|
|
49
|
+
await fs.promises.mkdir(target, { recursive: true });
|
|
50
|
+
const entries = await fs.promises.readdir(source, { withFileTypes: true });
|
|
51
|
+
for (const entry of entries) {
|
|
52
|
+
const sourcePath = path.join(source, entry.name);
|
|
53
|
+
const targetPath = path.join(target, entry.name);
|
|
54
|
+
if (entry.isDirectory()) {
|
|
55
|
+
fileCount += await copyDirectory(sourcePath, targetPath);
|
|
56
|
+
}
|
|
57
|
+
else if (entry.isFile()) {
|
|
58
|
+
await fs.promises.copyFile(sourcePath, targetPath);
|
|
59
|
+
fileCount++;
|
|
60
|
+
}
|
|
61
|
+
// Skip symlinks and other special files for security
|
|
62
|
+
}
|
|
63
|
+
logger.debug({ source, target, fileCount }, 'Copied directory');
|
|
64
|
+
return fileCount;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if a skill is already installed.
|
|
68
|
+
*
|
|
69
|
+
* @param skillName - Name of the skill
|
|
70
|
+
* @param ide - Target IDE
|
|
71
|
+
* @param options - Installation options
|
|
72
|
+
* @returns true if skill is installed, false otherwise
|
|
73
|
+
*/
|
|
74
|
+
export function isSkillInstalled(skillName, ide, options) {
|
|
75
|
+
const installPath = getSkillInstallPath(ide, skillName, options);
|
|
76
|
+
return fs.existsSync(installPath);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Install skills to target IDE directories.
|
|
80
|
+
*
|
|
81
|
+
* @param skills - Skills to install
|
|
82
|
+
* @param sourceDir - Directory containing extracted skills
|
|
83
|
+
* @param options - Installation options
|
|
84
|
+
* @returns Installation results
|
|
85
|
+
*/
|
|
86
|
+
export async function installSkills(skills, sourceDir, options) {
|
|
87
|
+
const logger = getLogger();
|
|
88
|
+
const result = {
|
|
89
|
+
installed: [],
|
|
90
|
+
skipped: [],
|
|
91
|
+
errors: [],
|
|
92
|
+
};
|
|
93
|
+
for (const skill of skills) {
|
|
94
|
+
const sanitizedName = sanitizeName(skill.name);
|
|
95
|
+
if (sanitizedName !== skill.name) {
|
|
96
|
+
logger.warn({ original: skill.name, sanitized: sanitizedName }, 'Skill name was sanitized');
|
|
97
|
+
}
|
|
98
|
+
// Source path: sourceDir/skills/skill-path/
|
|
99
|
+
const sourcePath = path.join(sourceDir, 'skills', skill.path);
|
|
100
|
+
if (!fs.existsSync(sourcePath)) {
|
|
101
|
+
for (const ide of options.ides) {
|
|
102
|
+
result.errors.push({
|
|
103
|
+
skill: skill.name,
|
|
104
|
+
ide,
|
|
105
|
+
error: `Source directory not found: ${sourcePath}`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
for (const ide of options.ides) {
|
|
111
|
+
try {
|
|
112
|
+
const targetPath = getSkillInstallPath(ide, sanitizedName, {
|
|
113
|
+
global: options.global,
|
|
114
|
+
projectRoot: options.projectRoot,
|
|
115
|
+
});
|
|
116
|
+
// Get the base directory for path safety validation
|
|
117
|
+
const baseDir = path.dirname(targetPath);
|
|
118
|
+
// Validate path safety
|
|
119
|
+
if (!isPathSafe(targetPath, baseDir)) {
|
|
120
|
+
result.errors.push({
|
|
121
|
+
skill: skill.name,
|
|
122
|
+
ide,
|
|
123
|
+
error: 'Path validation failed: potential directory traversal',
|
|
124
|
+
});
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
// Check if already installed
|
|
128
|
+
if (fs.existsSync(targetPath)) {
|
|
129
|
+
if (!options.update) {
|
|
130
|
+
result.skipped.push({
|
|
131
|
+
skill: skill.name,
|
|
132
|
+
ide,
|
|
133
|
+
reason: 'Already installed (use --update to overwrite)',
|
|
134
|
+
});
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
// Remove existing for update
|
|
138
|
+
await fs.promises.rm(targetPath, { recursive: true });
|
|
139
|
+
}
|
|
140
|
+
// Copy skill directory
|
|
141
|
+
await copyDirectory(sourcePath, targetPath);
|
|
142
|
+
result.installed.push({
|
|
143
|
+
skill: skill.name,
|
|
144
|
+
ide,
|
|
145
|
+
path: targetPath,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
result.errors.push({
|
|
150
|
+
skill: skill.name,
|
|
151
|
+
ide,
|
|
152
|
+
error: error instanceof Error ? error.message : String(error),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
logger.debug({
|
|
158
|
+
installed: result.installed.length,
|
|
159
|
+
skipped: result.skipped.length,
|
|
160
|
+
errors: result.errors.length,
|
|
161
|
+
}, 'Installation complete');
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Remove an installed skill.
|
|
166
|
+
*
|
|
167
|
+
* @param skillName - Name of the skill to remove
|
|
168
|
+
* @param ide - Target IDE
|
|
169
|
+
* @param options - Installation options
|
|
170
|
+
* @returns true if removed, false if not found
|
|
171
|
+
*/
|
|
172
|
+
export async function removeSkill(skillName, ide, options) {
|
|
173
|
+
const sanitizedName = sanitizeName(skillName);
|
|
174
|
+
const installPath = getSkillInstallPath(ide, sanitizedName, options);
|
|
175
|
+
if (!fs.existsSync(installPath)) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
await fs.promises.rm(installPath, { recursive: true });
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../../src/skills/installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { SkillMetadata, SkillSet } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse simple YAML-like frontmatter from SKILL.md content.
|
|
4
|
+
* Only supports basic key: value pairs (name and description).
|
|
5
|
+
*
|
|
6
|
+
* @param content - File content with frontmatter
|
|
7
|
+
* @returns Parsed frontmatter or null if invalid
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseSkillFrontmatter(content: string): {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
} | null;
|
|
13
|
+
/**
|
|
14
|
+
* Scan a directory for skills and extract their metadata.
|
|
15
|
+
*
|
|
16
|
+
* @param skillsDir - Path to extracted skills directory (e.g., ~/.cache/b2c-cli/skills/v0.1.0/b2c/skills/)
|
|
17
|
+
* @param skillSet - The skill set being scanned ('b2c' or 'b2c-cli')
|
|
18
|
+
* @returns Array of skill metadata
|
|
19
|
+
*/
|
|
20
|
+
export declare function scanSkills(skillsDir: string, skillSet: SkillSet): Promise<SkillMetadata[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Filter skills by name.
|
|
23
|
+
*
|
|
24
|
+
* @param skills - All available skills
|
|
25
|
+
* @param names - Skill names to include (if provided)
|
|
26
|
+
* @returns Filtered skills
|
|
27
|
+
*/
|
|
28
|
+
export declare function filterSkillsByName(skills: SkillMetadata[], names?: string[]): SkillMetadata[];
|
|
29
|
+
/**
|
|
30
|
+
* Find skills that match the given names, returning any that weren't found.
|
|
31
|
+
*
|
|
32
|
+
* @param skills - Available skills
|
|
33
|
+
* @param names - Requested skill names
|
|
34
|
+
* @returns Object with matched skills and names not found
|
|
35
|
+
*/
|
|
36
|
+
export declare function findSkillsByName(skills: SkillMetadata[], names: string[]): {
|
|
37
|
+
found: SkillMetadata[];
|
|
38
|
+
notFound: string[];
|
|
39
|
+
};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2
|
|
4
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'node:fs';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
import { getLogger } from '../logging/logger.js';
|
|
9
|
+
/**
|
|
10
|
+
* Parse simple YAML-like frontmatter from SKILL.md content.
|
|
11
|
+
* Only supports basic key: value pairs (name and description).
|
|
12
|
+
*
|
|
13
|
+
* @param content - File content with frontmatter
|
|
14
|
+
* @returns Parsed frontmatter or null if invalid
|
|
15
|
+
*/
|
|
16
|
+
export function parseSkillFrontmatter(content) {
|
|
17
|
+
// Match frontmatter between --- delimiters
|
|
18
|
+
const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
19
|
+
if (!match) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const frontmatter = match[1];
|
|
23
|
+
const result = {};
|
|
24
|
+
// Parse simple key: value lines
|
|
25
|
+
for (const line of frontmatter.split('\n')) {
|
|
26
|
+
const keyValueMatch = line.match(/^(\w+):\s*(.+)$/);
|
|
27
|
+
if (keyValueMatch) {
|
|
28
|
+
const [, key, value] = keyValueMatch;
|
|
29
|
+
if (key === 'name') {
|
|
30
|
+
result.name = value.trim();
|
|
31
|
+
}
|
|
32
|
+
else if (key === 'description') {
|
|
33
|
+
result.description = value.trim();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!result.name || !result.description) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return { name: result.name, description: result.description };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Scan a directory for skills and extract their metadata.
|
|
44
|
+
*
|
|
45
|
+
* @param skillsDir - Path to extracted skills directory (e.g., ~/.cache/b2c-cli/skills/v0.1.0/b2c/skills/)
|
|
46
|
+
* @param skillSet - The skill set being scanned ('b2c' or 'b2c-cli')
|
|
47
|
+
* @returns Array of skill metadata
|
|
48
|
+
*/
|
|
49
|
+
export async function scanSkills(skillsDir, skillSet) {
|
|
50
|
+
const logger = getLogger();
|
|
51
|
+
const skills = [];
|
|
52
|
+
// The extracted structure should be: skillsDir/skills/skill-name/SKILL.md
|
|
53
|
+
// Find the skills subdirectory
|
|
54
|
+
const skillsSubdir = path.join(skillsDir, 'skills');
|
|
55
|
+
if (!fs.existsSync(skillsSubdir)) {
|
|
56
|
+
logger.debug({ skillsDir, skillsSubdir }, 'Skills subdirectory not found');
|
|
57
|
+
return skills;
|
|
58
|
+
}
|
|
59
|
+
const entries = await fs.promises.readdir(skillsSubdir, { withFileTypes: true });
|
|
60
|
+
for (const entry of entries) {
|
|
61
|
+
if (!entry.isDirectory()) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const skillDir = path.join(skillsSubdir, entry.name);
|
|
65
|
+
const skillPath = path.join(skillDir, 'SKILL.md');
|
|
66
|
+
if (!fs.existsSync(skillPath)) {
|
|
67
|
+
logger.debug({ skillDir }, 'No SKILL.md found, skipping');
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const content = await fs.promises.readFile(skillPath, 'utf-8');
|
|
72
|
+
const frontmatter = parseSkillFrontmatter(content);
|
|
73
|
+
if (!frontmatter) {
|
|
74
|
+
logger.warn({ skillPath }, 'Invalid frontmatter in SKILL.md');
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
// Check for references directory
|
|
78
|
+
const referencesDir = path.join(skillDir, 'references');
|
|
79
|
+
const hasReferences = fs.existsSync(referencesDir);
|
|
80
|
+
skills.push({
|
|
81
|
+
name: frontmatter.name,
|
|
82
|
+
description: frontmatter.description,
|
|
83
|
+
skillSet,
|
|
84
|
+
path: entry.name, // Relative path within skills directory
|
|
85
|
+
hasReferences,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
logger.warn({ skillPath, error }, 'Failed to parse SKILL.md');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
logger.debug({ count: skills.length, skillSet }, 'Scanned skills');
|
|
93
|
+
return skills;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Filter skills by name.
|
|
97
|
+
*
|
|
98
|
+
* @param skills - All available skills
|
|
99
|
+
* @param names - Skill names to include (if provided)
|
|
100
|
+
* @returns Filtered skills
|
|
101
|
+
*/
|
|
102
|
+
export function filterSkillsByName(skills, names) {
|
|
103
|
+
if (!names || names.length === 0) {
|
|
104
|
+
return skills;
|
|
105
|
+
}
|
|
106
|
+
const nameSet = new Set(names);
|
|
107
|
+
return skills.filter((skill) => nameSet.has(skill.name));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Find skills that match the given names, returning any that weren't found.
|
|
111
|
+
*
|
|
112
|
+
* @param skills - Available skills
|
|
113
|
+
* @param names - Requested skill names
|
|
114
|
+
* @returns Object with matched skills and names not found
|
|
115
|
+
*/
|
|
116
|
+
export function findSkillsByName(skills, names) {
|
|
117
|
+
const skillMap = new Map(skills.map((s) => [s.name, s]));
|
|
118
|
+
const found = [];
|
|
119
|
+
const notFound = [];
|
|
120
|
+
for (const name of names) {
|
|
121
|
+
const skill = skillMap.get(name);
|
|
122
|
+
if (skill) {
|
|
123
|
+
found.push(skill);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
notFound.push(name);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return { found, notFound };
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/skills/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported IDE types for skill installation.
|
|
3
|
+
*/
|
|
4
|
+
export type IdeType = 'claude-code' | 'cursor' | 'windsurf' | 'vscode' | 'codex' | 'opencode' | 'manual';
|
|
5
|
+
/**
|
|
6
|
+
* Skill set categories matching the plugins directory structure.
|
|
7
|
+
*/
|
|
8
|
+
export type SkillSet = 'b2c' | 'b2c-cli';
|
|
9
|
+
/**
|
|
10
|
+
* IDE path configuration for skill installation.
|
|
11
|
+
*/
|
|
12
|
+
export interface IdePaths {
|
|
13
|
+
/** Relative path for project-level installation (e.g., '.claude/skills') */
|
|
14
|
+
projectDir: string;
|
|
15
|
+
/** Absolute path for global/user-level installation (e.g., '~/.claude/skills') */
|
|
16
|
+
globalDir: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* IDE configuration including paths and display name.
|
|
20
|
+
*/
|
|
21
|
+
export interface IdeConfig {
|
|
22
|
+
/** IDE identifier */
|
|
23
|
+
id: IdeType;
|
|
24
|
+
/** Human-readable display name */
|
|
25
|
+
displayName: string;
|
|
26
|
+
/** Installation paths */
|
|
27
|
+
paths: IdePaths;
|
|
28
|
+
/** Function to detect if IDE is installed */
|
|
29
|
+
detectInstalled: () => Promise<boolean>;
|
|
30
|
+
/** Optional documentation URL for skill configuration */
|
|
31
|
+
docsUrl?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Skill metadata extracted from SKILL.md frontmatter.
|
|
35
|
+
*/
|
|
36
|
+
export interface SkillMetadata {
|
|
37
|
+
/** Skill identifier from frontmatter name field */
|
|
38
|
+
name: string;
|
|
39
|
+
/** Skill description from frontmatter */
|
|
40
|
+
description: string;
|
|
41
|
+
/** Skill set this skill belongs to (b2c or b2c-cli) */
|
|
42
|
+
skillSet: SkillSet;
|
|
43
|
+
/** Relative path within the skills archive */
|
|
44
|
+
path: string;
|
|
45
|
+
/** Whether this skill has a references/ subdirectory */
|
|
46
|
+
hasReferences: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* GitHub release information.
|
|
50
|
+
*/
|
|
51
|
+
export interface ReleaseInfo {
|
|
52
|
+
/** Git tag name (e.g., 'v0.1.0') */
|
|
53
|
+
tagName: string;
|
|
54
|
+
/** Version number without 'v' prefix */
|
|
55
|
+
version: string;
|
|
56
|
+
/** ISO date string when release was published */
|
|
57
|
+
publishedAt: string;
|
|
58
|
+
/** Download URL for b2c-skills.zip asset, or null if not present */
|
|
59
|
+
b2cSkillsAssetUrl: string | null;
|
|
60
|
+
/** Download URL for b2c-cli-skills.zip asset, or null if not present */
|
|
61
|
+
b2cCliSkillsAssetUrl: string | null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Options for downloading skills artifacts.
|
|
65
|
+
*/
|
|
66
|
+
export interface DownloadSkillsOptions {
|
|
67
|
+
/** Specific release version to download (default: 'latest') */
|
|
68
|
+
version?: string;
|
|
69
|
+
/** Custom cache directory (default: ~/.cache/b2c-cli/skills/) */
|
|
70
|
+
cacheDir?: string;
|
|
71
|
+
/** Force re-download even if cached */
|
|
72
|
+
forceDownload?: boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Options for installing skills.
|
|
76
|
+
*/
|
|
77
|
+
export interface InstallSkillsOptions {
|
|
78
|
+
/** Specific skill names to install (default: all skills in skillset) */
|
|
79
|
+
skills?: string[];
|
|
80
|
+
/** Target IDEs to install to */
|
|
81
|
+
ides: IdeType[];
|
|
82
|
+
/** Install to global/user directory instead of project */
|
|
83
|
+
global: boolean;
|
|
84
|
+
/** Overwrite existing skills */
|
|
85
|
+
update: boolean;
|
|
86
|
+
/** Project root for project-level installations */
|
|
87
|
+
projectRoot?: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Result of a single skill installation.
|
|
91
|
+
*/
|
|
92
|
+
export interface SkillInstallation {
|
|
93
|
+
skill: string;
|
|
94
|
+
ide: IdeType;
|
|
95
|
+
path: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Reason for skipping a skill installation.
|
|
99
|
+
*/
|
|
100
|
+
export interface SkillSkipped {
|
|
101
|
+
skill: string;
|
|
102
|
+
ide: IdeType;
|
|
103
|
+
reason: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Error during skill installation.
|
|
107
|
+
*/
|
|
108
|
+
export interface SkillError {
|
|
109
|
+
skill: string;
|
|
110
|
+
ide: IdeType;
|
|
111
|
+
error: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Result of installing skills.
|
|
115
|
+
*/
|
|
116
|
+
export interface InstallSkillsResult {
|
|
117
|
+
/** Successfully installed skills */
|
|
118
|
+
installed: SkillInstallation[];
|
|
119
|
+
/** Skipped skills (already exist, no update flag) */
|
|
120
|
+
skipped: SkillSkipped[];
|
|
121
|
+
/** Failed installations */
|
|
122
|
+
errors: SkillError[];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Cached artifact metadata stored in manifest.json.
|
|
126
|
+
*/
|
|
127
|
+
export interface CachedArtifact {
|
|
128
|
+
/** Version of the cached artifact */
|
|
129
|
+
version: string;
|
|
130
|
+
/** Path to the extracted skills directory */
|
|
131
|
+
path: string;
|
|
132
|
+
/** ISO date string when artifact was downloaded */
|
|
133
|
+
downloadedAt: string;
|
|
134
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/skills/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/b2c-tooling-sdk",
|
|
3
|
-
"version": "0.0.0-nightly.
|
|
3
|
+
"version": "0.0.0-nightly.20260121023856",
|
|
4
4
|
"description": "Core tooling library for Salesforce Commerce Cloud B2C CLI",
|
|
5
5
|
"author": "Charles Lavery",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -199,6 +199,17 @@
|
|
|
199
199
|
"types": "./dist/cjs/discovery/index.d.ts",
|
|
200
200
|
"default": "./dist/cjs/discovery/index.js"
|
|
201
201
|
}
|
|
202
|
+
},
|
|
203
|
+
"./skills": {
|
|
204
|
+
"development": "./src/skills/index.ts",
|
|
205
|
+
"import": {
|
|
206
|
+
"types": "./dist/esm/skills/index.d.ts",
|
|
207
|
+
"default": "./dist/esm/skills/index.js"
|
|
208
|
+
},
|
|
209
|
+
"require": {
|
|
210
|
+
"types": "./dist/cjs/skills/index.d.ts",
|
|
211
|
+
"default": "./dist/cjs/skills/index.js"
|
|
212
|
+
}
|
|
202
213
|
}
|
|
203
214
|
},
|
|
204
215
|
"main": "./dist/cjs/index.js",
|