agent-skills-standard 1.1.1 → 1.2.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/README.md +24 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.js +34 -132
- package/dist/commands/list-skills.d.ts +3 -0
- package/dist/commands/list-skills.js +81 -0
- package/dist/commands/sync.js +1 -5
- package/dist/constants/index.d.ts +4 -1
- package/dist/constants/index.js +12 -1
- package/dist/constants/skills.d.ts +13 -0
- package/dist/constants/skills.js +57 -0
- package/dist/index.js +10 -2
- package/dist/models/config.d.ts +6 -6
- package/dist/services/ConfigService.d.ts +8 -0
- package/dist/services/ConfigService.js +70 -0
- package/dist/services/DetectionService.d.ts +5 -0
- package/dist/services/DetectionService.js +61 -0
- package/dist/services/RegistryService.d.ts +7 -0
- package/dist/services/RegistryService.js +43 -0
- package/dist/utils/github.d.ts +10 -0
- package/dist/utils/github.js +39 -0
- package/dist/utils/project.d.ts +2 -0
- package/dist/utils/project.js +60 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -71,6 +71,30 @@ npx agent-skills-standard sync
|
|
|
71
71
|
|
|
72
72
|
---
|
|
73
73
|
|
|
74
|
+
## ⚙️ Configuration (`.skillsrc`)
|
|
75
|
+
|
|
76
|
+
The `.skillsrc` file allows you to customize how skills are synced to your project.
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
registry: https://github.com/HoangNguyen0403/agent-skills-standard
|
|
80
|
+
agents: [cursor, copilot]
|
|
81
|
+
skills:
|
|
82
|
+
flutter:
|
|
83
|
+
ref: flutter-v1.1.0
|
|
84
|
+
# 🚫 Exclude specific sub-skills from being synced
|
|
85
|
+
exclude: ['getx-navigation']
|
|
86
|
+
# 🔒 Protect local modifications from being overwritten
|
|
87
|
+
custom_overrides: ['bloc-state-management']
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Key Options
|
|
91
|
+
|
|
92
|
+
- **`exclude`**: A list of skill IDs to skip during synchronization. Useful if you want the main framework guidelines but use a different library for a specific sub-task (e.g., excluding `auto-route` if you use `go_router`).
|
|
93
|
+
- **`custom_overrides`**: A list of skill IDs that the CLI should **never** overwrite. Use this when you have modified a standard skill locally to fit your project's unique needs. The CLI will detect these and preserve your local version.
|
|
94
|
+
- **`ref`**: Specify a specific version or tag of the skills from the registry.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
74
98
|
## ✨ Key Features
|
|
75
99
|
|
|
76
100
|
- **🎯 Efficiency First**: Uses a "Search-on-Demand" pattern that only loads information when the AI needs it, saving its "brain power" for your code.
|
package/dist/commands/init.d.ts
CHANGED
package/dist/commands/init.js
CHANGED
|
@@ -7,104 +7,33 @@ exports.InitCommand = void 0;
|
|
|
7
7
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
8
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
9
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
10
|
-
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
11
10
|
const path_1 = __importDefault(require("path"));
|
|
12
11
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
13
12
|
const constants_1 = require("../constants");
|
|
13
|
+
const ConfigService_1 = require("../services/ConfigService");
|
|
14
|
+
const DetectionService_1 = require("../services/DetectionService");
|
|
15
|
+
const RegistryService_1 = require("../services/RegistryService");
|
|
16
|
+
const project_1 = require("../utils/project");
|
|
14
17
|
class InitCommand {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.detectionService = new DetectionService_1.DetectionService();
|
|
20
|
+
this.registryService = new RegistryService_1.RegistryService();
|
|
21
|
+
this.configService = new ConfigService_1.ConfigService();
|
|
22
|
+
}
|
|
15
23
|
async run() {
|
|
16
24
|
const configPath = path_1.default.join(process.cwd(), '.skillsrc');
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
let packageDeps = {};
|
|
20
|
-
if (await fs_extra_1.default.pathExists(packageJsonPath)) {
|
|
21
|
-
try {
|
|
22
|
-
const pkg = await fs_extra_1.default.readJson(packageJsonPath);
|
|
23
|
-
packageDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
24
|
-
}
|
|
25
|
-
catch (e) {
|
|
26
|
-
console.error(picocolors_1.default.red(`❌ Failed to read package.json: ${e instanceof Error ? e.message : String(e)}`));
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// Project detection
|
|
30
|
-
const detectionResults = {};
|
|
31
|
-
for (const framework of constants_1.SUPPORTED_FRAMEWORKS) {
|
|
32
|
-
let detected = false;
|
|
33
|
-
// 1. Check characteristic files
|
|
34
|
-
for (const file of framework.detectionFiles) {
|
|
35
|
-
if (await fs_extra_1.default.pathExists(file)) {
|
|
36
|
-
detected = true;
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// 2. Check dependencies (if not yet detected)
|
|
41
|
-
if (!detected &&
|
|
42
|
-
framework.detectionDependencies &&
|
|
43
|
-
framework.detectionDependencies.length > 0) {
|
|
44
|
-
detected = framework.detectionDependencies.some((dep) => Object.prototype.hasOwnProperty.call(packageDeps, dep));
|
|
45
|
-
}
|
|
46
|
-
detectionResults[framework.id] = detected;
|
|
47
|
-
}
|
|
48
|
-
// Agent detection
|
|
49
|
-
const agentDetection = {};
|
|
50
|
-
for (const agent of constants_1.SUPPORTED_AGENTS) {
|
|
51
|
-
let detected = false;
|
|
52
|
-
for (const file of agent.detectionFiles) {
|
|
53
|
-
if (await fs_extra_1.default.pathExists(file)) {
|
|
54
|
-
detected = true;
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
agentDetection[agent.id] = detected;
|
|
59
|
-
}
|
|
25
|
+
const detectionResults = await this.detectionService.detectFrameworks();
|
|
26
|
+
const agentDetection = await this.detectionService.detectAgents();
|
|
60
27
|
const anyAgentDetected = Object.values(agentDetection).some((d) => d);
|
|
61
|
-
// Helper to determine if an agent should be pre-selected
|
|
62
28
|
const shouldCheck = (id) => anyAgentDetected ? agentDetection[id] : true;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
(0, node_fetch_1.default)(treeUrl, {
|
|
72
|
-
headers: { Accept: 'application/vnd.github.v3+json' },
|
|
73
|
-
}),
|
|
74
|
-
(0, node_fetch_1.default)(metadataUrl),
|
|
75
|
-
]);
|
|
76
|
-
if (metadataRes.ok) {
|
|
77
|
-
metadata = (await metadataRes.json());
|
|
78
|
-
}
|
|
79
|
-
if (treeRes.ok) {
|
|
80
|
-
const treeData = (await treeRes.json());
|
|
81
|
-
const allFiles = treeData.tree || [];
|
|
82
|
-
// Extract top-level folders in skills/
|
|
83
|
-
const categories = new Set();
|
|
84
|
-
allFiles.forEach((f) => {
|
|
85
|
-
if (f.path.startsWith('skills/') && f.type === 'tree') {
|
|
86
|
-
const parts = f.path.split('/');
|
|
87
|
-
if (parts.length === 2) {
|
|
88
|
-
categories.add(parts[1]);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
if (categories.size > 0) {
|
|
93
|
-
supportedCategories = Array.from(categories);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
catch (e) {
|
|
98
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
99
|
-
console.error(picocolors_1.default.red(`❌ Failed to fetch registry metadata or tree: ${msg}`));
|
|
100
|
-
}
|
|
101
|
-
const choices = constants_1.SUPPORTED_FRAMEWORKS.map((f) => {
|
|
102
|
-
const isSupported = supportedCategories.includes(f.id);
|
|
103
|
-
return {
|
|
104
|
-
name: isSupported ? f.name : `${f.name} (Coming Soon)`,
|
|
105
|
-
value: f.id,
|
|
106
|
-
};
|
|
107
|
-
});
|
|
29
|
+
const defaultRegistry = 'https://github.com/HoangNguyen0403/agent-skills-standard';
|
|
30
|
+
const { categories: supportedCategories, metadata } = await this.registryService.discoverRegistry(defaultRegistry);
|
|
31
|
+
const choices = constants_1.SUPPORTED_FRAMEWORKS.map((f) => ({
|
|
32
|
+
name: supportedCategories.includes(f.id)
|
|
33
|
+
? f.name
|
|
34
|
+
: `${f.name} (Coming Soon)`,
|
|
35
|
+
value: f.id,
|
|
36
|
+
}));
|
|
108
37
|
if (await fs_extra_1.default.pathExists(configPath)) {
|
|
109
38
|
const { overwrite } = await inquirer_1.default.prompt([
|
|
110
39
|
{
|
|
@@ -142,56 +71,29 @@ class InitCommand {
|
|
|
142
71
|
type: 'input',
|
|
143
72
|
name: 'registry',
|
|
144
73
|
message: 'Skills Registry URL:',
|
|
145
|
-
default:
|
|
74
|
+
default: defaultRegistry,
|
|
146
75
|
},
|
|
147
76
|
]);
|
|
148
77
|
const framework = answers.framework;
|
|
149
|
-
|
|
150
|
-
const isSupported = supportedCategories.includes(framework);
|
|
151
|
-
if (!isSupported) {
|
|
78
|
+
if (!supportedCategories.includes(framework)) {
|
|
152
79
|
console.log(picocolors_1.default.yellow(`\nNotice: Skills for ${framework} are not yet strictly defined and will be added soon.`));
|
|
153
80
|
console.log(picocolors_1.default.gray('The CLI will still generate rule files with global standards.\n'));
|
|
154
81
|
}
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
custom_overrides: [],
|
|
169
|
-
};
|
|
170
|
-
// Initialize all potential skills from the registry folders we know
|
|
171
|
-
// This will be expanded as more frameworks are added to the repo
|
|
172
|
-
const allKnownCategories = [
|
|
173
|
-
...constants_1.SUPPORTED_FRAMEWORKS.map((f) => f.id),
|
|
174
|
-
...constants_1.SUPPORTED_FRAMEWORKS.flatMap((f) => f.languages),
|
|
175
|
-
];
|
|
176
|
-
for (const skill of [...new Set(allKnownCategories)]) {
|
|
177
|
-
if (neededSkills.has(skill)) {
|
|
178
|
-
const skillMeta = metadata.categories?.[skill];
|
|
179
|
-
let refStr;
|
|
180
|
-
if (skillMeta?.version && skillMeta?.tag_prefix) {
|
|
181
|
-
refStr = `${skillMeta.tag_prefix}${skillMeta.version}`;
|
|
182
|
-
}
|
|
183
|
-
config.skills[skill] = {
|
|
184
|
-
enabled: true,
|
|
185
|
-
ref: refStr,
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
await fs_extra_1.default.writeFile(configPath, js_yaml_1.default.dump(config));
|
|
82
|
+
const config = this.configService.buildInitialConfig(framework, answers.agents, answers.registry, metadata);
|
|
83
|
+
const projectDeps = await (0, project_1.buildProjectDeps)();
|
|
84
|
+
this.configService.applyDependencyExclusions(config, framework, projectDeps);
|
|
85
|
+
const commentHeader = `# Auto-detected configuration generated by agent-skills-standard init
|
|
86
|
+
#
|
|
87
|
+
# Presence in 'skills' list = Active. To disable a skill, remove it from the list.
|
|
88
|
+
# 'exclude': IDs of sub-skills to skip during sync (auto-populated with undetected skills).
|
|
89
|
+
# 'custom_overrides': IDs of skills to PROTECT. Use this if you have modified a standard
|
|
90
|
+
# skill locally and don't want the CLI to overwrite it.
|
|
91
|
+
#
|
|
92
|
+
# Run 'ags list-skills' to view all available skills.
|
|
93
|
+
`;
|
|
94
|
+
await fs_extra_1.default.writeFile(configPath, commentHeader + js_yaml_1.default.dump(config));
|
|
190
95
|
console.log(picocolors_1.default.green('\n✅ Initialized .skillsrc with your preferences!'));
|
|
191
96
|
console.log(picocolors_1.default.gray(` Selected framework: ${framework}`));
|
|
192
|
-
console.log(picocolors_1.default.gray(` Auto-enabled languages: ${Array.from(neededSkills)
|
|
193
|
-
.filter((s) => s !== framework)
|
|
194
|
-
.join(', ') || 'none'}`));
|
|
195
97
|
console.log(picocolors_1.default.cyan('\nNext step: Run `agent-skills-standard sync` to generate rule files.'));
|
|
196
98
|
}
|
|
197
99
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ListSkillsCommand = void 0;
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
12
|
+
const constants_1 = require("../constants");
|
|
13
|
+
const github_1 = require("../utils/github");
|
|
14
|
+
const project_1 = require("../utils/project");
|
|
15
|
+
class ListSkillsCommand {
|
|
16
|
+
async run() {
|
|
17
|
+
const choices = constants_1.SUPPORTED_FRAMEWORKS.map((f) => ({
|
|
18
|
+
name: f.name,
|
|
19
|
+
value: f.id,
|
|
20
|
+
}));
|
|
21
|
+
const { framework } = await inquirer_1.default.prompt([
|
|
22
|
+
{
|
|
23
|
+
type: 'list',
|
|
24
|
+
name: 'framework',
|
|
25
|
+
message: 'Select framework to list available skills for:',
|
|
26
|
+
choices,
|
|
27
|
+
default: choices.find((c) => c.value === constants_1.Framework.Flutter)?.value,
|
|
28
|
+
},
|
|
29
|
+
]);
|
|
30
|
+
const projectDeps = await (0, project_1.buildProjectDeps)();
|
|
31
|
+
console.log(picocolors_1.default.green(`\nAvailable skills for ${framework}:`));
|
|
32
|
+
// Determine registry URL (from .skillsrc or default)
|
|
33
|
+
const defaultRegistry = 'https://github.com/HoangNguyen0403/agent-skills-standard';
|
|
34
|
+
let registryUrl = defaultRegistry;
|
|
35
|
+
const configPath = path_1.default.join(process.cwd(), '.skillsrc');
|
|
36
|
+
if (await fs_extra_1.default.pathExists(configPath)) {
|
|
37
|
+
const raw = await fs_extra_1.default.readFile(configPath, 'utf8');
|
|
38
|
+
const conf = js_yaml_1.default.load(raw);
|
|
39
|
+
if (conf && conf.registry)
|
|
40
|
+
registryUrl = conf.registry;
|
|
41
|
+
}
|
|
42
|
+
// Try to fetch the repo tree to list all skills under skills/<framework>/
|
|
43
|
+
let skillFolders = [];
|
|
44
|
+
try {
|
|
45
|
+
const parsed = (0, github_1.parseRegistryUrl)(registryUrl);
|
|
46
|
+
if (parsed) {
|
|
47
|
+
const treeResult = await (0, github_1.fetchRepoTree)(parsed.owner, parsed.repo);
|
|
48
|
+
if (treeResult && Array.isArray(treeResult.data.tree)) {
|
|
49
|
+
const allFiles = treeResult.data.tree || [];
|
|
50
|
+
skillFolders = Array.from(new Set(allFiles
|
|
51
|
+
.filter((f) => f.path.startsWith(`skills/${framework}/`))
|
|
52
|
+
.map((f) => {
|
|
53
|
+
const parts = f.path.split('/');
|
|
54
|
+
return parts[2];
|
|
55
|
+
})
|
|
56
|
+
.filter(Boolean)));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// ignore network errors and fall back to detection registry
|
|
62
|
+
}
|
|
63
|
+
// Fallback: use detection registry skill ids if we couldn't fetch tree
|
|
64
|
+
const detectSkills = constants_1.SKILL_DETECTION_REGISTRY[framework] || [];
|
|
65
|
+
if (!skillFolders || skillFolders.length === 0) {
|
|
66
|
+
skillFolders = detectSkills.map((s) => s.id);
|
|
67
|
+
}
|
|
68
|
+
// For each discovered skill, show whether it would be detected (if we have rules)
|
|
69
|
+
for (const skillName of skillFolders.sort()) {
|
|
70
|
+
const detectRule = detectSkills.find((x) => x.id === skillName);
|
|
71
|
+
let mark = picocolors_1.default.yellow('no-rule');
|
|
72
|
+
if (detectRule) {
|
|
73
|
+
const present = detectRule.packages.some((p) => projectDeps.has(p));
|
|
74
|
+
mark = present ? picocolors_1.default.green('detected') : picocolors_1.default.gray('not-detected');
|
|
75
|
+
}
|
|
76
|
+
console.log(`- ${skillName} (${mark})`);
|
|
77
|
+
}
|
|
78
|
+
console.log('\nTip: Use the .skillsrc exclude array to disable/enable sub-skills before running sync.');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.ListSkillsCommand = ListSkillsCommand;
|
package/dist/commands/sync.js
CHANGED
|
@@ -27,9 +27,7 @@ class SyncCommand {
|
|
|
27
27
|
// 2. Check for skill updates before syncing
|
|
28
28
|
config = await this.checkForUpdates(config, configPath);
|
|
29
29
|
console.log(picocolors_1.default.cyan(`🚀 Syncing skills from ${config.registry}...`));
|
|
30
|
-
const enabledCategories = Object.
|
|
31
|
-
.filter(([, value]) => value.enabled)
|
|
32
|
-
.map(([key]) => key);
|
|
30
|
+
const enabledCategories = Object.keys(config.skills);
|
|
33
31
|
const skills = await this.assembleFromRemote(enabledCategories, config);
|
|
34
32
|
await this.writeToTargets(skills, config);
|
|
35
33
|
console.log(picocolors_1.default.green('✅ All skills synced successfully!'));
|
|
@@ -83,8 +81,6 @@ class SyncCommand {
|
|
|
83
81
|
const remoteMeta = (await metaRes.json());
|
|
84
82
|
const updates = [];
|
|
85
83
|
for (const [cat, catConfig] of Object.entries(config.skills)) {
|
|
86
|
-
if (!catConfig.enabled)
|
|
87
|
-
continue;
|
|
88
84
|
const remoteCat = remoteMeta.categories?.[cat];
|
|
89
85
|
if (!remoteCat || !remoteCat.version || !remoteCat.tag_prefix)
|
|
90
86
|
continue;
|
|
@@ -7,7 +7,8 @@ export declare enum Agent {
|
|
|
7
7
|
OpenAI = "openai",
|
|
8
8
|
OpenCode = "opencode",
|
|
9
9
|
Gemini = "gemini",
|
|
10
|
-
Roo = "roo"
|
|
10
|
+
Roo = "roo",
|
|
11
|
+
Windsurf = "windsurf"
|
|
11
12
|
}
|
|
12
13
|
export declare enum Framework {
|
|
13
14
|
Flutter = "flutter",
|
|
@@ -18,6 +19,7 @@ export declare enum Framework {
|
|
|
18
19
|
ReactNative = "react-native",
|
|
19
20
|
Angular = "angular"
|
|
20
21
|
}
|
|
22
|
+
export declare const UNIVERSAL_SKILLS: string[];
|
|
21
23
|
export interface AgentDefinition {
|
|
22
24
|
id: Agent;
|
|
23
25
|
name: string;
|
|
@@ -35,3 +37,4 @@ export declare const getAgentDefinition: (id: Agent) => AgentDefinition;
|
|
|
35
37
|
export declare const getFrameworkDefinition: (id: Framework) => FrameworkDefinition;
|
|
36
38
|
export declare const SUPPORTED_AGENTS: AgentDefinition[];
|
|
37
39
|
export declare const SUPPORTED_FRAMEWORKS: FrameworkDefinition[];
|
|
40
|
+
export { SKILL_DETECTION_REGISTRY, SkillDetection } from './skills';
|
package/dist/constants/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SUPPORTED_FRAMEWORKS = exports.SUPPORTED_AGENTS = exports.getFrameworkDefinition = exports.getAgentDefinition = exports.Framework = exports.Agent = void 0;
|
|
3
|
+
exports.SKILL_DETECTION_REGISTRY = exports.SUPPORTED_FRAMEWORKS = exports.SUPPORTED_AGENTS = exports.getFrameworkDefinition = exports.getAgentDefinition = exports.UNIVERSAL_SKILLS = exports.Framework = exports.Agent = void 0;
|
|
4
4
|
var Agent;
|
|
5
5
|
(function (Agent) {
|
|
6
6
|
Agent["Cursor"] = "cursor";
|
|
@@ -12,6 +12,7 @@ var Agent;
|
|
|
12
12
|
Agent["OpenCode"] = "opencode";
|
|
13
13
|
Agent["Gemini"] = "gemini";
|
|
14
14
|
Agent["Roo"] = "roo";
|
|
15
|
+
Agent["Windsurf"] = "windsurf";
|
|
15
16
|
})(Agent || (exports.Agent = Agent = {}));
|
|
16
17
|
var Framework;
|
|
17
18
|
(function (Framework) {
|
|
@@ -23,6 +24,7 @@ var Framework;
|
|
|
23
24
|
Framework["ReactNative"] = "react-native";
|
|
24
25
|
Framework["Angular"] = "angular";
|
|
25
26
|
})(Framework || (exports.Framework = Framework = {}));
|
|
27
|
+
exports.UNIVERSAL_SKILLS = ['common'];
|
|
26
28
|
const getAgentDefinition = (id) => {
|
|
27
29
|
switch (id) {
|
|
28
30
|
case Agent.Cursor:
|
|
@@ -88,6 +90,13 @@ const getAgentDefinition = (id) => {
|
|
|
88
90
|
path: '.roo/skills',
|
|
89
91
|
detectionFiles: ['.roo'],
|
|
90
92
|
};
|
|
93
|
+
case Agent.Windsurf:
|
|
94
|
+
return {
|
|
95
|
+
id,
|
|
96
|
+
name: 'Windsurf',
|
|
97
|
+
path: '.windsurf/skills',
|
|
98
|
+
detectionFiles: ['.windsurf', '.windsurfrules'],
|
|
99
|
+
};
|
|
91
100
|
}
|
|
92
101
|
};
|
|
93
102
|
exports.getAgentDefinition = getAgentDefinition;
|
|
@@ -151,3 +160,5 @@ const getFrameworkDefinition = (id) => {
|
|
|
151
160
|
exports.getFrameworkDefinition = getFrameworkDefinition;
|
|
152
161
|
exports.SUPPORTED_AGENTS = Object.values(Agent).map(exports.getAgentDefinition);
|
|
153
162
|
exports.SUPPORTED_FRAMEWORKS = Object.values(Framework).map(exports.getFrameworkDefinition);
|
|
163
|
+
var skills_1 = require("./skills");
|
|
164
|
+
Object.defineProperty(exports, "SKILL_DETECTION_REGISTRY", { enumerable: true, get: function () { return skills_1.SKILL_DETECTION_REGISTRY; } });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SkillDetection defines how to automatically enable a skill based on project dependencies.
|
|
3
|
+
*/
|
|
4
|
+
export interface SkillDetection {
|
|
5
|
+
/** The skill ID as defined in the registry (e.g., 'riverpod-state-management') */
|
|
6
|
+
id: string;
|
|
7
|
+
/** List of npm or pub packages that indicate this skill is used */
|
|
8
|
+
packages: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Registry of automatic skill detection rules grouped by framework.
|
|
12
|
+
*/
|
|
13
|
+
export declare const SKILL_DETECTION_REGISTRY: Record<string, SkillDetection[]>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SKILL_DETECTION_REGISTRY = void 0;
|
|
4
|
+
const index_1 = require("./index");
|
|
5
|
+
/**
|
|
6
|
+
* Registry of automatic skill detection rules grouped by framework.
|
|
7
|
+
*/
|
|
8
|
+
exports.SKILL_DETECTION_REGISTRY = {
|
|
9
|
+
[index_1.Framework.Flutter]: [
|
|
10
|
+
{
|
|
11
|
+
id: 'riverpod-state-management',
|
|
12
|
+
packages: ['flutter_riverpod', 'riverpod'],
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'bloc-state-management',
|
|
16
|
+
packages: ['flutter_bloc', 'bloc'],
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'auto-route-navigation',
|
|
20
|
+
packages: ['auto_route'],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 'go-router-navigation',
|
|
24
|
+
packages: ['go_router'],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'getx-navigation',
|
|
28
|
+
packages: ['get'],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'getx-state-management',
|
|
32
|
+
packages: ['get'],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'localization',
|
|
36
|
+
packages: ['easy_localization'],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'retrofit-networking',
|
|
40
|
+
packages: ['retrofit'],
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
[index_1.Framework.NestJS]: [
|
|
44
|
+
{
|
|
45
|
+
id: 'caching',
|
|
46
|
+
packages: ['@nestjs/cache-manager', 'cache-manager'],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'database',
|
|
50
|
+
packages: ['@nestjs/typeorm', '@nestjs/prisma', '@nestjs/mongoose'],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: 'security',
|
|
54
|
+
packages: ['@nestjs/passport', 'passport', 'helmet'],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
5
|
const init_1 = require("./commands/init");
|
|
6
|
+
const list_skills_1 = require("./commands/list-skills");
|
|
6
7
|
const sync_1 = require("./commands/sync");
|
|
7
8
|
const program = new commander_1.Command();
|
|
8
9
|
program
|
|
9
10
|
.name('agent-skills-standard')
|
|
10
|
-
.description('A CLI to manage and sync AI agent skills for Cursor, Claude, Copilot, and more.')
|
|
11
|
-
.version('1.
|
|
11
|
+
.description('A CLI to manage and sync AI agent skills for Cursor, Claude, Copilot, Windsurf, and more.')
|
|
12
|
+
.version('1.2.0');
|
|
12
13
|
program
|
|
13
14
|
.command('init')
|
|
14
15
|
.description('Initialize a .skillsrc configuration file interactively')
|
|
@@ -23,4 +24,11 @@ program
|
|
|
23
24
|
const sync = new sync_1.SyncCommand();
|
|
24
25
|
await sync.run();
|
|
25
26
|
});
|
|
27
|
+
program
|
|
28
|
+
.command('list-skills')
|
|
29
|
+
.description('List available framework skills and detection status')
|
|
30
|
+
.action(async () => {
|
|
31
|
+
const cmd = new list_skills_1.ListSkillsCommand();
|
|
32
|
+
await cmd.run();
|
|
33
|
+
});
|
|
26
34
|
program.parse();
|
package/dist/models/config.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
export interface SkillEntry {
|
|
2
|
+
ref?: string;
|
|
3
|
+
exclude?: string[];
|
|
4
|
+
include?: string[];
|
|
5
|
+
}
|
|
1
6
|
export interface SkillConfig {
|
|
2
7
|
registry: string;
|
|
3
8
|
agents: string[];
|
|
4
9
|
skills: {
|
|
5
|
-
[key: string]:
|
|
6
|
-
enabled: boolean;
|
|
7
|
-
ref?: string;
|
|
8
|
-
exclude?: string[];
|
|
9
|
-
include?: string[];
|
|
10
|
-
};
|
|
10
|
+
[key: string]: SkillEntry;
|
|
11
11
|
};
|
|
12
12
|
custom_overrides?: string[];
|
|
13
13
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SkillConfig } from '../models/config';
|
|
2
|
+
import { RegistryMetadata } from '../models/types';
|
|
3
|
+
export declare class ConfigService {
|
|
4
|
+
buildInitialConfig(framework: string, agents: string[], registry: string, metadata: Partial<RegistryMetadata>): SkillConfig;
|
|
5
|
+
private getAllKnownCategories;
|
|
6
|
+
private createSkillEntry;
|
|
7
|
+
applyDependencyExclusions(config: SkillConfig, framework: string, projectDeps: Set<string>): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigService = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
class ConfigService {
|
|
6
|
+
buildInitialConfig(framework, agents, registry, metadata) {
|
|
7
|
+
const selectedFramework = constants_1.SUPPORTED_FRAMEWORKS.find((f) => f.id === framework);
|
|
8
|
+
const neededSkills = new Set();
|
|
9
|
+
constants_1.UNIVERSAL_SKILLS.forEach((s) => neededSkills.add(s));
|
|
10
|
+
neededSkills.add(framework);
|
|
11
|
+
if (selectedFramework) {
|
|
12
|
+
selectedFramework.languages.forEach((l) => neededSkills.add(l));
|
|
13
|
+
}
|
|
14
|
+
// Special cases
|
|
15
|
+
if (framework === constants_1.Framework.NextJS || framework === constants_1.Framework.ReactNative) {
|
|
16
|
+
neededSkills.add(constants_1.Framework.React);
|
|
17
|
+
}
|
|
18
|
+
const frameworkSkills = constants_1.SKILL_DETECTION_REGISTRY[framework] || [];
|
|
19
|
+
frameworkSkills.forEach((s) => neededSkills.add(s.id));
|
|
20
|
+
const config = {
|
|
21
|
+
registry,
|
|
22
|
+
agents,
|
|
23
|
+
skills: {},
|
|
24
|
+
custom_overrides: [],
|
|
25
|
+
};
|
|
26
|
+
const allKnownCategories = this.getAllKnownCategories();
|
|
27
|
+
for (const skill of [...new Set(allKnownCategories)]) {
|
|
28
|
+
if (neededSkills.has(skill)) {
|
|
29
|
+
config.skills[skill] = this.createSkillEntry(skill, metadata);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return config;
|
|
33
|
+
}
|
|
34
|
+
getAllKnownCategories() {
|
|
35
|
+
return [
|
|
36
|
+
...constants_1.UNIVERSAL_SKILLS,
|
|
37
|
+
...constants_1.SUPPORTED_FRAMEWORKS.map((f) => f.id),
|
|
38
|
+
...constants_1.SUPPORTED_FRAMEWORKS.flatMap((f) => f.languages),
|
|
39
|
+
...Object.values(constants_1.SKILL_DETECTION_REGISTRY).flatMap((skills) => skills.map((s) => s.id)),
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
createSkillEntry(skill, metadata) {
|
|
43
|
+
const skillMeta = metadata.categories?.[skill];
|
|
44
|
+
let refStr;
|
|
45
|
+
if (skillMeta?.version && skillMeta?.tag_prefix) {
|
|
46
|
+
refStr = `${skillMeta.tag_prefix}${skillMeta.version}`;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
ref: refStr,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
applyDependencyExclusions(config, framework, projectDeps) {
|
|
53
|
+
const frameworkSkills = constants_1.SKILL_DETECTION_REGISTRY[framework] || [];
|
|
54
|
+
for (const skill of frameworkSkills) {
|
|
55
|
+
const entry = config.skills[skill.id];
|
|
56
|
+
if (!entry)
|
|
57
|
+
continue;
|
|
58
|
+
const used = skill.packages.some((p) => projectDeps.has(p));
|
|
59
|
+
if (!used) {
|
|
60
|
+
const parent = config.skills[framework] || {};
|
|
61
|
+
const excludes = parent.exclude ? [...parent.exclude] : [];
|
|
62
|
+
if (!excludes.includes(skill.id))
|
|
63
|
+
excludes.push(skill.id);
|
|
64
|
+
parent.exclude = excludes;
|
|
65
|
+
config.skills[framework] = parent;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.ConfigService = ConfigService;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DetectionService = void 0;
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
class DetectionService {
|
|
11
|
+
async detectFrameworks() {
|
|
12
|
+
const packageDeps = await this.getPackageDeps();
|
|
13
|
+
const results = {};
|
|
14
|
+
for (const framework of constants_1.SUPPORTED_FRAMEWORKS) {
|
|
15
|
+
let detected = false;
|
|
16
|
+
// 1. Check characteristic files
|
|
17
|
+
for (const file of framework.detectionFiles) {
|
|
18
|
+
if (await fs_extra_1.default.pathExists(path_1.default.join(process.cwd(), file))) {
|
|
19
|
+
detected = true;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// 2. Check dependencies (if not yet detected)
|
|
24
|
+
if (!detected &&
|
|
25
|
+
framework.detectionDependencies &&
|
|
26
|
+
framework.detectionDependencies.length > 0) {
|
|
27
|
+
detected = framework.detectionDependencies.some((dep) => Object.prototype.hasOwnProperty.call(packageDeps, dep));
|
|
28
|
+
}
|
|
29
|
+
results[framework.id] = detected;
|
|
30
|
+
}
|
|
31
|
+
return results;
|
|
32
|
+
}
|
|
33
|
+
async detectAgents() {
|
|
34
|
+
const results = {};
|
|
35
|
+
for (const agent of constants_1.SUPPORTED_AGENTS) {
|
|
36
|
+
let detected = false;
|
|
37
|
+
for (const file of agent.detectionFiles) {
|
|
38
|
+
if (await fs_extra_1.default.pathExists(path_1.default.join(process.cwd(), file))) {
|
|
39
|
+
detected = true;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
results[agent.id] = detected;
|
|
44
|
+
}
|
|
45
|
+
return results;
|
|
46
|
+
}
|
|
47
|
+
async getPackageDeps() {
|
|
48
|
+
const packageJsonPath = path_1.default.join(process.cwd(), 'package.json');
|
|
49
|
+
if (await fs_extra_1.default.pathExists(packageJsonPath)) {
|
|
50
|
+
try {
|
|
51
|
+
const pkg = await fs_extra_1.default.readJson(packageJsonPath);
|
|
52
|
+
return { ...pkg.dependencies, ...pkg.devDependencies };
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.DetectionService = DetectionService;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RegistryService = void 0;
|
|
7
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
8
|
+
const github_1 = require("../utils/github");
|
|
9
|
+
class RegistryService {
|
|
10
|
+
async discoverRegistry(registryUrl) {
|
|
11
|
+
let categories = ['flutter', 'dart'];
|
|
12
|
+
let metadata = {};
|
|
13
|
+
try {
|
|
14
|
+
const parsed = (0, github_1.parseRegistryUrl)(registryUrl);
|
|
15
|
+
if (parsed) {
|
|
16
|
+
const treeResult = await (0, github_1.fetchRepoTree)(parsed.owner, parsed.repo);
|
|
17
|
+
if (treeResult && Array.isArray(treeResult.data.tree)) {
|
|
18
|
+
const allFiles = treeResult.data.tree || [];
|
|
19
|
+
const foundCategories = new Set();
|
|
20
|
+
allFiles.forEach((f) => {
|
|
21
|
+
if (f.path.startsWith('skills/') && f.type === 'tree') {
|
|
22
|
+
const parts = f.path.split('/');
|
|
23
|
+
if (parts.length === 2)
|
|
24
|
+
foundCategories.add(parts[1]);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
if (foundCategories.size > 0)
|
|
28
|
+
categories = Array.from(foundCategories);
|
|
29
|
+
const metaUrl = `https://raw.githubusercontent.com/${parsed.owner}/${parsed.repo}/${treeResult.branch}/skills/metadata.json`;
|
|
30
|
+
const metaRes = await (0, node_fetch_1.default)(metaUrl);
|
|
31
|
+
if (metaRes.ok) {
|
|
32
|
+
metadata = (await metaRes.json());
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Return defaults on error
|
|
39
|
+
}
|
|
40
|
+
return { categories, metadata };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.RegistryService = RegistryService;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GitHubTreeResponse } from '../models/types';
|
|
2
|
+
export declare function parseRegistryUrl(registryUrl: string): {
|
|
3
|
+
owner: string;
|
|
4
|
+
repo: string;
|
|
5
|
+
} | null;
|
|
6
|
+
export declare function fetchRepoTree(owner: string, repo: string, ref?: string): Promise<{
|
|
7
|
+
data: GitHubTreeResponse;
|
|
8
|
+
branch: string;
|
|
9
|
+
} | null>;
|
|
10
|
+
export default fetchRepoTree;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseRegistryUrl = parseRegistryUrl;
|
|
7
|
+
exports.fetchRepoTree = fetchRepoTree;
|
|
8
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
9
|
+
function parseRegistryUrl(registryUrl) {
|
|
10
|
+
const m = registryUrl.match(/github\.com\/([^/]+)\/([^/]+)/i);
|
|
11
|
+
if (!m)
|
|
12
|
+
return null;
|
|
13
|
+
return { owner: m[1], repo: m[2].replace(/\.git$/, '') };
|
|
14
|
+
}
|
|
15
|
+
async function fetchRepoTree(owner, repo, ref) {
|
|
16
|
+
try {
|
|
17
|
+
let branch = ref;
|
|
18
|
+
if (!branch) {
|
|
19
|
+
// Resolve default branch
|
|
20
|
+
const repoRes = await (0, node_fetch_1.default)(`https://api.github.com/repos/${owner}/${repo}`);
|
|
21
|
+
if (!repoRes.ok)
|
|
22
|
+
return null;
|
|
23
|
+
const repoData = (await repoRes.json());
|
|
24
|
+
branch = repoData.default_branch || 'main';
|
|
25
|
+
}
|
|
26
|
+
const treeUrl = `https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}?recursive=1`;
|
|
27
|
+
const res = await (0, node_fetch_1.default)(treeUrl, {
|
|
28
|
+
headers: { Accept: 'application/vnd.github.v3+json' },
|
|
29
|
+
});
|
|
30
|
+
if (!res.ok)
|
|
31
|
+
return null;
|
|
32
|
+
const data = (await res.json());
|
|
33
|
+
return { data, branch };
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.default = fetchRepoTree;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildProjectDeps = buildProjectDeps;
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
async function buildProjectDeps() {
|
|
10
|
+
const set = new Set();
|
|
11
|
+
const packageJsonPath = path_1.default.join(process.cwd(), 'package.json');
|
|
12
|
+
if (await fs_extra_1.default.pathExists(packageJsonPath)) {
|
|
13
|
+
try {
|
|
14
|
+
const pkg = await fs_extra_1.default.readJson(packageJsonPath);
|
|
15
|
+
const deps = {
|
|
16
|
+
...(pkg.dependencies || {}),
|
|
17
|
+
...(pkg.devDependencies || {}),
|
|
18
|
+
};
|
|
19
|
+
for (const k of Object.keys(deps))
|
|
20
|
+
set.add(k);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// ignore
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const pubspecPath = path_1.default.join(process.cwd(), 'pubspec.yaml');
|
|
27
|
+
if (await fs_extra_1.default.pathExists(pubspecPath)) {
|
|
28
|
+
try {
|
|
29
|
+
const loaded = await fs_extra_1.default.readFile(pubspecPath, 'utf8');
|
|
30
|
+
// simple parse: only collect keys inside dependencies/dev_dependencies sections
|
|
31
|
+
const lines = loaded.split(/\r?\n/);
|
|
32
|
+
let currentSection = null;
|
|
33
|
+
let sectionIndent = null;
|
|
34
|
+
for (const line of lines) {
|
|
35
|
+
const sectionMatch = line.match(/^(\s*)(dependencies|dev_dependencies)\s*:/);
|
|
36
|
+
if (sectionMatch) {
|
|
37
|
+
currentSection = sectionMatch[2];
|
|
38
|
+
sectionIndent = sectionMatch[1].length;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (!currentSection || sectionIndent === null)
|
|
42
|
+
continue;
|
|
43
|
+
const entryMatch = line.match(/^(\s*)([a-zA-Z0-9_\-@\\/]+)\s*:/);
|
|
44
|
+
if (!entryMatch)
|
|
45
|
+
continue;
|
|
46
|
+
const indent = entryMatch[1].length;
|
|
47
|
+
const key = entryMatch[2];
|
|
48
|
+
// only include keys that are nested under the current section and are not known non-packages
|
|
49
|
+
if (indent > sectionIndent && key !== 'sdk' && key !== 'flutter') {
|
|
50
|
+
set.add(key);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// ignore
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return set;
|
|
59
|
+
}
|
|
60
|
+
exports.default = buildProjectDeps;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-skills-standard",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A CLI to manage and sync AI agent skills standard for Cursor, Claude, Copilot, and more.",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "A CLI to manage and sync AI agent skills standard for Cursor, Claude, Copilot, Windsurf, and more.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"agent-skills-standard": "dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"commander": "^11.1.0",
|
|
26
26
|
"fs-extra": "^11.2.0",
|
|
27
|
-
"inquirer": "^
|
|
27
|
+
"inquirer": "^8.2.5",
|
|
28
28
|
"js-yaml": "^4.1.0",
|
|
29
29
|
"node-fetch": "^2.7.0",
|
|
30
30
|
"picocolors": "^1.0.0"
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@eslint/js": "^9.39.2",
|
|
34
34
|
"@types/fs-extra": "^11.0.4",
|
|
35
|
-
"@types/inquirer": "^
|
|
35
|
+
"@types/inquirer": "^8.2.5",
|
|
36
36
|
"@types/js-yaml": "^4.0.9",
|
|
37
37
|
"@types/node": "^20.10.5",
|
|
38
38
|
"@types/node-fetch": "^2.6.9",
|