@patricio0312rev/skillset 0.1.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 +29 -0
- package/LICENSE +21 -0
- package/README.md +176 -0
- package/bin/cli.js +37 -0
- package/package.json +55 -0
- package/src/commands/init.js +301 -0
- package/src/index.js +168 -0
- package/src/lib/config.js +200 -0
- package/src/lib/generator.js +166 -0
- package/src/utils/display.js +95 -0
- package/src/utils/readme.js +196 -0
- package/src/utils/tool-specific.js +233 -0
- package/templates/ai-engineering/agent-orchestration-planner/ SKILL.md +266 -0
- package/templates/ai-engineering/cost-latency-optimizer/ SKILL.md +270 -0
- package/templates/ai-engineering/doc-to-vector-dataset-generator/ SKILL.md +239 -0
- package/templates/ai-engineering/evaluation-harness/ SKILL.md +219 -0
- package/templates/ai-engineering/guardrails-safety-filter-builder/ SKILL.md +226 -0
- package/templates/ai-engineering/llm-debugger/ SKILL.md +283 -0
- package/templates/ai-engineering/prompt-regression-tester/ SKILL.md +216 -0
- package/templates/ai-engineering/prompt-template-builder/ SKILL.md +393 -0
- package/templates/ai-engineering/rag-pipeline-builder/ SKILL.md +244 -0
- package/templates/ai-engineering/tool-function-schema-designer/ SKILL.md +219 -0
- package/templates/architecture/adr-writer/ SKILL.md +250 -0
- package/templates/architecture/api-versioning-deprecation-planner/ SKILL.md +331 -0
- package/templates/architecture/domain-model-boundaries-mapper/ SKILL.md +300 -0
- package/templates/architecture/migration-planner/ SKILL.md +376 -0
- package/templates/architecture/performance-budget-setter/ SKILL.md +318 -0
- package/templates/architecture/reliability-strategy-builder/ SKILL.md +286 -0
- package/templates/architecture/rfc-generator/ SKILL.md +362 -0
- package/templates/architecture/scalability-playbook/ SKILL.md +279 -0
- package/templates/architecture/system-design-generator/ SKILL.md +339 -0
- package/templates/architecture/tech-debt-prioritizer/ SKILL.md +329 -0
- package/templates/backend/api-contract-normalizer/ SKILL.md +487 -0
- package/templates/backend/api-endpoint-generator/ SKILL.md +415 -0
- package/templates/backend/auth-module-builder/ SKILL.md +99 -0
- package/templates/backend/background-jobs-designer/ SKILL.md +166 -0
- package/templates/backend/caching-strategist/ SKILL.md +190 -0
- package/templates/backend/error-handling-standardizer/ SKILL.md +174 -0
- package/templates/backend/rate-limiting-abuse-protection/ SKILL.md +147 -0
- package/templates/backend/rbac-permissions-builder/ SKILL.md +158 -0
- package/templates/backend/service-layer-extractor/ SKILL.md +269 -0
- package/templates/backend/webhook-receiver-hardener/ SKILL.md +211 -0
- package/templates/ci-cd/artifact-sbom-publisher/ SKILL.md +236 -0
- package/templates/ci-cd/caching-strategy-optimizer/ SKILL.md +195 -0
- package/templates/ci-cd/deployment-checklist-generator/ SKILL.md +381 -0
- package/templates/ci-cd/github-actions-pipeline-creator/ SKILL.md +348 -0
- package/templates/ci-cd/monorepo-ci-optimizer/ SKILL.md +298 -0
- package/templates/ci-cd/preview-environments-builder/ SKILL.md +187 -0
- package/templates/ci-cd/quality-gates-enforcer/ SKILL.md +342 -0
- package/templates/ci-cd/release-automation-builder/ SKILL.md +281 -0
- package/templates/ci-cd/rollback-workflow-builder/ SKILL.md +372 -0
- package/templates/ci-cd/secrets-env-manager/ SKILL.md +242 -0
- package/templates/db-management/backup-restore-runbook-generator/ SKILL.md +505 -0
- package/templates/db-management/data-integrity-auditor/ SKILL.md +505 -0
- package/templates/db-management/data-retention-archiving-planner/ SKILL.md +430 -0
- package/templates/db-management/data-seeding-fixtures-builder/ SKILL.md +375 -0
- package/templates/db-management/db-performance-watchlist/ SKILL.md +425 -0
- package/templates/db-management/etl-sync-job-builder/ SKILL.md +457 -0
- package/templates/db-management/multi-tenant-safety-checker/ SKILL.md +398 -0
- package/templates/db-management/prisma-migration-assistant/ SKILL.md +379 -0
- package/templates/db-management/schema-consistency-checker/ SKILL.md +440 -0
- package/templates/db-management/sql-query-optimizer/ SKILL.md +324 -0
- package/templates/foundation/changelog-writer/ SKILL.md +431 -0
- package/templates/foundation/code-formatter-installer/ SKILL.md +320 -0
- package/templates/foundation/codebase-summarizer/ SKILL.md +360 -0
- package/templates/foundation/dependency-doctor/ SKILL.md +163 -0
- package/templates/foundation/dev-environment-bootstrapper/ SKILL.md +259 -0
- package/templates/foundation/dev-onboarding-builder/ SKILL.md +556 -0
- package/templates/foundation/docs-starter-kit/ SKILL.md +574 -0
- package/templates/foundation/explaining-code/SKILL.md +13 -0
- package/templates/foundation/git-hygiene-enforcer/ SKILL.md +455 -0
- package/templates/foundation/project-scaffolder/ SKILL.md +65 -0
- package/templates/foundation/project-scaffolder/references/templates.md +126 -0
- package/templates/foundation/repo-structure-linter/ SKILL.md +0 -0
- package/templates/foundation/repo-structure-linter/references/conventions.md +98 -0
- package/templates/frontend/animation-micro-interaction-pack/ SKILL.md +41 -0
- package/templates/frontend/component-scaffold-generator/ SKILL.md +562 -0
- package/templates/frontend/design-to-component-translator/ SKILL.md +547 -0
- package/templates/frontend/form-wizard-builder/ SKILL.md +553 -0
- package/templates/frontend/frontend-refactor-planner/ SKILL.md +37 -0
- package/templates/frontend/i18n-frontend-implementer/ SKILL.md +44 -0
- package/templates/frontend/modal-drawer-system/ SKILL.md +377 -0
- package/templates/frontend/page-layout-builder/ SKILL.md +630 -0
- package/templates/frontend/state-ux-flow-builder/ SKILL.md +23 -0
- package/templates/frontend/table-builder/ SKILL.md +350 -0
- package/templates/performance/alerting-dashboard-builder/ SKILL.md +162 -0
- package/templates/performance/backend-latency-profiler-helper/ SKILL.md +108 -0
- package/templates/performance/caching-cdn-strategy-planner/ SKILL.md +150 -0
- package/templates/performance/capacity-planning-helper/ SKILL.md +242 -0
- package/templates/performance/core-web-vitals-tuner/ SKILL.md +126 -0
- package/templates/performance/incident-runbook-generator/ SKILL.md +162 -0
- package/templates/performance/load-test-scenario-builder/ SKILL.md +256 -0
- package/templates/performance/observability-setup/ SKILL.md +232 -0
- package/templates/performance/postmortem-writer/ SKILL.md +203 -0
- package/templates/performance/structured-logging-standardizer/ SKILL.md +122 -0
- package/templates/security/auth-security-reviewer/ SKILL.md +428 -0
- package/templates/security/dependency-vulnerability-triage/ SKILL.md +495 -0
- package/templates/security/input-validation-sanitization-auditor/ SKILL.md +76 -0
- package/templates/security/pii-redaction-logging-policy-builder/ SKILL.md +65 -0
- package/templates/security/rbac-policy-tester/ SKILL.md +80 -0
- package/templates/security/secrets-scanner/ SKILL.md +462 -0
- package/templates/security/secure-headers-csp-builder/ SKILL.md +404 -0
- package/templates/security/security-incident-playbook-generator/ SKILL.md +76 -0
- package/templates/security/security-pr-checklist-skill/ SKILL.md +62 -0
- package/templates/security/threat-model-generator/ SKILL.md +394 -0
- package/templates/testing/contract-testing-builder/ SKILL.md +492 -0
- package/templates/testing/coverage-strategist/ SKILL.md +436 -0
- package/templates/testing/e2e-test-builder/ SKILL.md +382 -0
- package/templates/testing/flaky-test-detective/ SKILL.md +416 -0
- package/templates/testing/integration-test-builder/ SKILL.md +525 -0
- package/templates/testing/mocking-assistant/ SKILL.md +383 -0
- package/templates/testing/snapshot-test-refactorer/ SKILL.md +375 -0
- package/templates/testing/test-data-factory-builder/ SKILL.md +449 -0
- package/templates/testing/test-reporting-triage-skill/ SKILL.md +469 -0
- package/templates/testing/unit-test-generator/ SKILL.md +548 -0
package/src/index.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SkillSet - Programmatic API
|
|
3
|
+
*
|
|
4
|
+
* This module exports the main functions for use by:
|
|
5
|
+
* - CLI (this package)
|
|
6
|
+
* - VSCode Extension
|
|
7
|
+
* - Other integrations
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { generateSkills } = require('./lib/generator');
|
|
11
|
+
const { TOOLS, DOMAINS } = require('./lib/config');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generate development skills configuration programmatically
|
|
15
|
+
* @param {Object} config - Configuration object
|
|
16
|
+
* @param {string} config.tool - AI tool (claude-code, cursor, copilot, other)
|
|
17
|
+
* @param {string} config.folder - Target folder name
|
|
18
|
+
* @param {string[]} config.domains - List of domains to include
|
|
19
|
+
* @param {string[]} [config.skills] - Optional: specific skills to include
|
|
20
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const skillset = require('@patricio0312rev/skillset');
|
|
24
|
+
*
|
|
25
|
+
* const result = await skillset.generate({
|
|
26
|
+
* tool: 'claude-code',
|
|
27
|
+
* folder: '.claude/skills',
|
|
28
|
+
* domains: ['backend', 'frontend', 'testing'],
|
|
29
|
+
* skills: ['api-endpoint-generator', 'unit-test-generator']
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* console.log(`Generated ${result.skillsGenerated} skills`);
|
|
33
|
+
*/
|
|
34
|
+
async function generate(config) {
|
|
35
|
+
// Validate config
|
|
36
|
+
const validation = validateConfig(config);
|
|
37
|
+
if (!validation.isValid) {
|
|
38
|
+
throw new Error(`Invalid configuration: ${validation.errors.join(', ')}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return await generateSkills(config);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get list of available tools
|
|
46
|
+
* @returns {Object} Tools configuration
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* const tools = skillset.getTools();
|
|
50
|
+
* console.log(Object.keys(tools)); // ['claude-code', 'cursor', 'copilot', 'other']
|
|
51
|
+
*/
|
|
52
|
+
function getTools() {
|
|
53
|
+
return { ...TOOLS };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get list of available domains
|
|
58
|
+
* @returns {Object} Domains configuration
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* const domains = skillset.getDomains();
|
|
62
|
+
* console.log(domains.backend.skills); // ['api-endpoint-generator', ...]
|
|
63
|
+
*/
|
|
64
|
+
function getDomains() {
|
|
65
|
+
return { ...DOMAINS };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get skills for a specific domain
|
|
70
|
+
* @param {string} domain - Domain name
|
|
71
|
+
* @returns {string[]} List of skill names
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* const skills = skillset.getSkillsForDomain('backend');
|
|
75
|
+
* console.log(skills); // ['api-endpoint-generator', 'auth-module-builder', ...]
|
|
76
|
+
*/
|
|
77
|
+
function getSkillsForDomain(domain) {
|
|
78
|
+
return DOMAINS[domain]?.skills || [];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get all available skills across all domains
|
|
83
|
+
* @returns {Object} Object with domain as key and skills array as value
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* const allSkills = skillset.getAllSkills();
|
|
87
|
+
* console.log(allSkills.backend); // ['api-endpoint-generator', ...]
|
|
88
|
+
*/
|
|
89
|
+
function getAllSkills() {
|
|
90
|
+
const result = {};
|
|
91
|
+
Object.entries(DOMAINS).forEach(([domain, info]) => {
|
|
92
|
+
result[domain] = [...info.skills];
|
|
93
|
+
});
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Validate configuration
|
|
99
|
+
* @param {Object} config - Configuration to validate
|
|
100
|
+
* @returns {Object} Validation result with isValid and errors
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* const validation = skillset.validateConfig({
|
|
104
|
+
* tool: 'claude-code',
|
|
105
|
+
* folder: '.claude/skills',
|
|
106
|
+
* domains: ['backend']
|
|
107
|
+
* });
|
|
108
|
+
*
|
|
109
|
+
* if (!validation.isValid) {
|
|
110
|
+
* console.error(validation.errors);
|
|
111
|
+
* }
|
|
112
|
+
*/
|
|
113
|
+
function validateConfig(config) {
|
|
114
|
+
const errors = [];
|
|
115
|
+
|
|
116
|
+
// Validate tool
|
|
117
|
+
if (!config.tool) {
|
|
118
|
+
errors.push('Tool is required');
|
|
119
|
+
} else if (!TOOLS[config.tool]) {
|
|
120
|
+
errors.push(`Invalid tool: ${config.tool}. Valid options: ${Object.keys(TOOLS).join(', ')}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Validate folder
|
|
124
|
+
if (!config.folder) {
|
|
125
|
+
errors.push('Folder is required');
|
|
126
|
+
} else if (typeof config.folder !== 'string') {
|
|
127
|
+
errors.push('Folder must be a string');
|
|
128
|
+
} else if (config.folder.includes(' ')) {
|
|
129
|
+
errors.push('Folder name cannot contain spaces');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Validate domains
|
|
133
|
+
if (!config.domains) {
|
|
134
|
+
errors.push('Domains are required');
|
|
135
|
+
} else if (!Array.isArray(config.domains)) {
|
|
136
|
+
errors.push('Domains must be an array');
|
|
137
|
+
} else if (config.domains.length === 0) {
|
|
138
|
+
errors.push('At least one domain is required');
|
|
139
|
+
} else {
|
|
140
|
+
config.domains.forEach(domain => {
|
|
141
|
+
if (!DOMAINS[domain]) {
|
|
142
|
+
errors.push(`Invalid domain: ${domain}. Valid options: ${Object.keys(DOMAINS).join(', ')}`);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Validate skills if provided
|
|
148
|
+
if (config.skills && !Array.isArray(config.skills)) {
|
|
149
|
+
errors.push('Skills must be an array');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
isValid: errors.length === 0,
|
|
154
|
+
errors
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Export all functions
|
|
159
|
+
module.exports = {
|
|
160
|
+
generate,
|
|
161
|
+
getTools,
|
|
162
|
+
getDomains,
|
|
163
|
+
getSkillsForDomain,
|
|
164
|
+
getAllSkills,
|
|
165
|
+
validateConfig,
|
|
166
|
+
TOOLS,
|
|
167
|
+
DOMAINS
|
|
168
|
+
};
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
const TOOLS = {
|
|
2
|
+
'claude-code': {
|
|
3
|
+
name: 'Claude Code',
|
|
4
|
+
folder: '.claude/skills',
|
|
5
|
+
description: 'Skills with native support',
|
|
6
|
+
fileStructure: 'multi-file',
|
|
7
|
+
fileExtension: 'SKILL.md'
|
|
8
|
+
},
|
|
9
|
+
'copilot': {
|
|
10
|
+
name: 'GitHub Copilot (Agent Skills)',
|
|
11
|
+
folder: '.github/skills',
|
|
12
|
+
description: 'Agent Skills for GitHub Copilot',
|
|
13
|
+
fileStructure: 'multi-file',
|
|
14
|
+
fileExtension: 'SKILL.md',
|
|
15
|
+
fallbackFolder: '.claude/skills'
|
|
16
|
+
},
|
|
17
|
+
'cursor': {
|
|
18
|
+
name: 'Cursor',
|
|
19
|
+
folder: '.cursor/rules',
|
|
20
|
+
description: 'Project Rules for Cursor',
|
|
21
|
+
fileStructure: 'multi-file',
|
|
22
|
+
fileExtension: 'RULE.md'
|
|
23
|
+
},
|
|
24
|
+
'other': {
|
|
25
|
+
name: 'Other AI Tools',
|
|
26
|
+
folder: '.claude/skills',
|
|
27
|
+
description: 'Universal skills format',
|
|
28
|
+
fileStructure: 'multi-file',
|
|
29
|
+
fileExtension: 'SKILL.md'
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const DOMAINS = {
|
|
34
|
+
foundation: {
|
|
35
|
+
name: 'Foundation',
|
|
36
|
+
description: 'Project setup, development environment, and documentation',
|
|
37
|
+
skills: [
|
|
38
|
+
'changelog-writer',
|
|
39
|
+
'code-formatter-installer',
|
|
40
|
+
'codebase-summarizer',
|
|
41
|
+
'dependency-doctor',
|
|
42
|
+
'dev-environment-bootstrapper',
|
|
43
|
+
'dev-onboarding-builder',
|
|
44
|
+
'docs-starter-kit',
|
|
45
|
+
'explaining-code',
|
|
46
|
+
'git-hygiene-enforcer',
|
|
47
|
+
'project-scaffolder',
|
|
48
|
+
'repo-structure-linter'
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
frontend: {
|
|
52
|
+
name: 'Frontend',
|
|
53
|
+
description: 'React, UI components, and user experience',
|
|
54
|
+
skills: [
|
|
55
|
+
'animation-micro-interaction-pack',
|
|
56
|
+
'component-scaffold-generator',
|
|
57
|
+
'design-to-component-translator',
|
|
58
|
+
'form-wizard-builder',
|
|
59
|
+
'frontend-refactor-planner',
|
|
60
|
+
'i18n-frontend-implementer',
|
|
61
|
+
'modal-drawer-system',
|
|
62
|
+
'page-layout-builder',
|
|
63
|
+
'state-ux-flow-builder',
|
|
64
|
+
'table-builder'
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
backend: {
|
|
68
|
+
name: 'Backend',
|
|
69
|
+
description: 'APIs, authentication, and server-side logic',
|
|
70
|
+
skills: [
|
|
71
|
+
'api-contract-normalizer',
|
|
72
|
+
'api-endpoint-generator',
|
|
73
|
+
'auth-module-builder',
|
|
74
|
+
'background-jobs-designer',
|
|
75
|
+
'caching-strategist',
|
|
76
|
+
'error-handling-standardizer',
|
|
77
|
+
'rate-limiting-abuse-protection',
|
|
78
|
+
'rbac-permissions-builder',
|
|
79
|
+
'service-layer-extractor',
|
|
80
|
+
'webhook-receiver-hardener'
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
'ai-engineering': {
|
|
84
|
+
name: 'AI Engineering',
|
|
85
|
+
description: 'LLMs, RAG, agents, and AI systems',
|
|
86
|
+
skills: [
|
|
87
|
+
'agent-orchestration-planner',
|
|
88
|
+
'cost-latency-optimizer',
|
|
89
|
+
'doc-to-vector-dataset-generator',
|
|
90
|
+
'evaluation-harness',
|
|
91
|
+
'guardrails-safety-filter-builder',
|
|
92
|
+
'llm-debugger',
|
|
93
|
+
'prompt-regression-tester',
|
|
94
|
+
'prompt-template-builder',
|
|
95
|
+
'rag-pipeline-builder',
|
|
96
|
+
'tool-function-schema-designer'
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
architecture: {
|
|
100
|
+
name: 'Architecture',
|
|
101
|
+
description: 'System design, scalability, and technical decisions',
|
|
102
|
+
skills: [
|
|
103
|
+
'adr-writer',
|
|
104
|
+
'api-versioning-deprecation-planner',
|
|
105
|
+
'domain-model-boundaries-mapper',
|
|
106
|
+
'migration-planner',
|
|
107
|
+
'performance-budget-setter',
|
|
108
|
+
'reliability-strategy-builder',
|
|
109
|
+
'rfc-generator',
|
|
110
|
+
'scalability-playbook',
|
|
111
|
+
'system-design-generator',
|
|
112
|
+
'tech-debt-prioritizer'
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
'ci-cd': {
|
|
116
|
+
name: 'CI/CD',
|
|
117
|
+
description: 'Automation, deployments, and release management',
|
|
118
|
+
skills: [
|
|
119
|
+
'artifact-sbom-publisher',
|
|
120
|
+
'caching-strategy-optimizer',
|
|
121
|
+
'deployment-checklist-generator',
|
|
122
|
+
'github-actions-pipeline-creator',
|
|
123
|
+
'monorepo-ci-optimizer',
|
|
124
|
+
'preview-environments-builder',
|
|
125
|
+
'quality-gates-enforcer',
|
|
126
|
+
'release-automation-builder',
|
|
127
|
+
'rollback-workflow-builder',
|
|
128
|
+
'secrets-env-manager'
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
'db-management': {
|
|
132
|
+
name: 'Database Management',
|
|
133
|
+
description: 'Migrations, optimization, and data engineering',
|
|
134
|
+
skills: [
|
|
135
|
+
'backup-restore-runbook-generator',
|
|
136
|
+
'data-integrity-auditor',
|
|
137
|
+
'data-retention-archiving-planner',
|
|
138
|
+
'data-seeding-fixtures-builder',
|
|
139
|
+
'db-performance-watchlist',
|
|
140
|
+
'etl-sync-job-builder',
|
|
141
|
+
'multi-tenant-safety-checker',
|
|
142
|
+
'prisma-migration-assistant',
|
|
143
|
+
'schema-consistency-checker',
|
|
144
|
+
'sql-query-optimizer'
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
testing: {
|
|
148
|
+
name: 'Testing',
|
|
149
|
+
description: 'Quality assurance and test coverage',
|
|
150
|
+
skills: [
|
|
151
|
+
'contract-testing-builder',
|
|
152
|
+
'coverage-strategist',
|
|
153
|
+
'e2e-test-builder',
|
|
154
|
+
'flaky-test-detective',
|
|
155
|
+
'integration-test-builder',
|
|
156
|
+
'mocking-assistant',
|
|
157
|
+
'snapshot-test-refactorer',
|
|
158
|
+
'test-data-factory-builder',
|
|
159
|
+
'test-reporting-triage-skill',
|
|
160
|
+
'unit-test-generator'
|
|
161
|
+
]
|
|
162
|
+
},
|
|
163
|
+
security: {
|
|
164
|
+
name: 'Security',
|
|
165
|
+
description: 'Security hardening and privacy protection',
|
|
166
|
+
skills: [
|
|
167
|
+
'auth-security-reviewer',
|
|
168
|
+
'dependency-vulnerability-triage',
|
|
169
|
+
'input-validation-sanitization-auditor',
|
|
170
|
+
'pii-redaction-logging-policy-builder',
|
|
171
|
+
'rbac-policy-tester',
|
|
172
|
+
'secrets-scanner',
|
|
173
|
+
'secure-headers-csp-builder',
|
|
174
|
+
'security-incident-playbook-generator',
|
|
175
|
+
'security-pr-checklist-skill',
|
|
176
|
+
'threat-model-generator'
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
performance: {
|
|
180
|
+
name: 'Performance',
|
|
181
|
+
description: 'Observability, monitoring, and optimization',
|
|
182
|
+
skills: [
|
|
183
|
+
'alerting-dashboard-builder',
|
|
184
|
+
'backend-latency-profiler-helper',
|
|
185
|
+
'caching-cdn-strategy-planner',
|
|
186
|
+
'capacity-planning-helper',
|
|
187
|
+
'core-web-vitals-tuner',
|
|
188
|
+
'incident-runbook-generator',
|
|
189
|
+
'load-test-scenario-builder',
|
|
190
|
+
'observability-setup',
|
|
191
|
+
'postmortem-writer',
|
|
192
|
+
'structured-logging-standardizer'
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
module.exports = {
|
|
198
|
+
TOOLS,
|
|
199
|
+
DOMAINS
|
|
200
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const fs = require("fs-extra");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const { TOOLS, DOMAINS } = require("./config");
|
|
4
|
+
const { generateReadme } = require("../utils/readme");
|
|
5
|
+
const { generateToolSpecificFiles } = require("../utils/tool-specific");
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Main generator function that creates skill configuration
|
|
9
|
+
* @param {Object} config - Configuration object
|
|
10
|
+
* @returns {Promise<Object>} Generation result
|
|
11
|
+
*/
|
|
12
|
+
async function generateSkills(config) {
|
|
13
|
+
const targetDir = path.join(process.cwd(), config.folder);
|
|
14
|
+
const result = {
|
|
15
|
+
success: false,
|
|
16
|
+
targetDir,
|
|
17
|
+
skillsGenerated: 0,
|
|
18
|
+
filesCreated: [],
|
|
19
|
+
errors: [],
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
// Ensure target directory exists
|
|
24
|
+
await fs.ensureDir(targetDir);
|
|
25
|
+
|
|
26
|
+
// Generate domain folders and skill files
|
|
27
|
+
const skillResult = await generateDomainSkills(config, targetDir);
|
|
28
|
+
result.skillsGenerated = skillResult.count;
|
|
29
|
+
result.filesCreated.push(...skillResult.files);
|
|
30
|
+
|
|
31
|
+
// Generate README
|
|
32
|
+
const readmePath = path.join(targetDir, "README.md");
|
|
33
|
+
const readmeContent = generateReadme(config, result);
|
|
34
|
+
await fs.writeFile(readmePath, readmeContent);
|
|
35
|
+
result.filesCreated.push(readmePath);
|
|
36
|
+
|
|
37
|
+
// Generate tool-specific files
|
|
38
|
+
const toolFiles = await generateToolSpecificFiles(
|
|
39
|
+
config,
|
|
40
|
+
targetDir,
|
|
41
|
+
skillResult.skillsList
|
|
42
|
+
);
|
|
43
|
+
result.filesCreated.push(...toolFiles);
|
|
44
|
+
|
|
45
|
+
result.success = true;
|
|
46
|
+
return result;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
result.errors.push(error.message);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Generate domain folders and copy skill files
|
|
55
|
+
* @param {Object} config - Configuration object
|
|
56
|
+
* @param {string} targetDir - Target directory path
|
|
57
|
+
* @returns {Promise<Object>} Result with count and file list
|
|
58
|
+
*/
|
|
59
|
+
async function generateDomainSkills(config, targetDir) {
|
|
60
|
+
let count = 0;
|
|
61
|
+
const files = [];
|
|
62
|
+
const skillsList = [];
|
|
63
|
+
|
|
64
|
+
for (const domain of config.domains) {
|
|
65
|
+
const domainInfo = DOMAINS[domain];
|
|
66
|
+
if (!domainInfo) continue;
|
|
67
|
+
|
|
68
|
+
// Determine which skills to generate
|
|
69
|
+
let skillsToGenerate = domainInfo.skills;
|
|
70
|
+
|
|
71
|
+
// Filter if specific skills were selected
|
|
72
|
+
if (config.skills && config.skills.length > 0) {
|
|
73
|
+
skillsToGenerate = skillsToGenerate.filter((skill) => {
|
|
74
|
+
// Support both "skill-name" and "domain/skill-name" formats
|
|
75
|
+
return (
|
|
76
|
+
config.skills.includes(skill) ||
|
|
77
|
+
config.skills.includes(`${domain}/${skill}`)
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Copy/generate each skill file directly in target directory
|
|
83
|
+
for (const skill of skillsToGenerate) {
|
|
84
|
+
const skillFile = await generateSkillFile(domain, skill, targetDir, config);
|
|
85
|
+
if (skillFile) {
|
|
86
|
+
files.push(skillFile);
|
|
87
|
+
skillsList.push({ domain, skill, file: skillFile });
|
|
88
|
+
count++;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return { count, files, skillsList };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Generate or copy an individual skill file
|
|
98
|
+
* @param {string} domain - Domain name
|
|
99
|
+
* @param {string} skill - Skill name
|
|
100
|
+
* @param {string} domainDir - Domain directory path
|
|
101
|
+
* @param {Object} config - Configuration object
|
|
102
|
+
* @returns {Promise<string|null>} Path to created file or null
|
|
103
|
+
*/
|
|
104
|
+
async function generateSkillFile(domain, skill, domainDir, config) {
|
|
105
|
+
const toolInfo = TOOLS[config.tool];
|
|
106
|
+
const fileExtension = toolInfo.fileExtension || 'SKILL.md';
|
|
107
|
+
|
|
108
|
+
// Source file in templates (always SKILL.md)
|
|
109
|
+
const sourceDir = path.join(
|
|
110
|
+
__dirname,
|
|
111
|
+
"../../templates",
|
|
112
|
+
domain,
|
|
113
|
+
skill
|
|
114
|
+
);
|
|
115
|
+
const sourceFile = path.join(sourceDir, " SKILL.md");
|
|
116
|
+
|
|
117
|
+
// Target file with appropriate extension
|
|
118
|
+
const targetSkillDir = path.join(domainDir, skill);
|
|
119
|
+
const targetFile = path.join(targetSkillDir, fileExtension);
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
// Ensure target skill directory exists
|
|
123
|
+
await fs.ensureDir(targetSkillDir);
|
|
124
|
+
|
|
125
|
+
// Check if template exists
|
|
126
|
+
if (await fs.pathExists(sourceFile)) {
|
|
127
|
+
let content = await fs.readFile(sourceFile, "utf8");
|
|
128
|
+
|
|
129
|
+
// Process content based on tool (e.g., rename SKILL.md to RULE.md for Cursor)
|
|
130
|
+
if (config.tool === 'cursor') {
|
|
131
|
+
// For Cursor, change the filename reference in frontmatter if needed
|
|
132
|
+
content = content.replace(/SKILL\.md/g, 'RULE.md');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
await fs.writeFile(targetFile, content);
|
|
136
|
+
|
|
137
|
+
// Copy references and other folders if they exist
|
|
138
|
+
const referencesDir = path.join(sourceDir, "references");
|
|
139
|
+
if (await fs.pathExists(referencesDir)) {
|
|
140
|
+
const targetReferencesDir = path.join(targetSkillDir, "references");
|
|
141
|
+
await fs.copy(referencesDir, targetReferencesDir);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Copy templates folder if it exists
|
|
145
|
+
const templatesDir = path.join(sourceDir, "templates");
|
|
146
|
+
if (await fs.pathExists(templatesDir)) {
|
|
147
|
+
const targetTemplatesDir = path.join(targetSkillDir, "templates");
|
|
148
|
+
await fs.copy(templatesDir, targetTemplatesDir);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return targetFile;
|
|
152
|
+
} else {
|
|
153
|
+
console.warn(`Warning: Template not found for ${domain}/${skill}`);
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
} catch (error) {
|
|
157
|
+
console.error(`Error generating skill ${skill}:`, error.message);
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
module.exports = {
|
|
163
|
+
generateSkills,
|
|
164
|
+
generateDomainSkills,
|
|
165
|
+
generateSkillFile,
|
|
166
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const chalk = require("chalk");
|
|
2
|
+
|
|
3
|
+
function displayBanner() {
|
|
4
|
+
const version = require("../../package.json").version;
|
|
5
|
+
console.log(
|
|
6
|
+
chalk.cyan(
|
|
7
|
+
"\n" +
|
|
8
|
+
" ╔═══════════════════════════════════════════╗\n" +
|
|
9
|
+
" ║ ║\n" +
|
|
10
|
+
" ║ 📚 SkillSet CLI v" +
|
|
11
|
+
version.padEnd(19) +
|
|
12
|
+
"║\n" +
|
|
13
|
+
" ║ ║\n" +
|
|
14
|
+
" ║ Import development skills for ║\n" +
|
|
15
|
+
" ║ Claude Code, Cursor, Copilot & more ║\n" +
|
|
16
|
+
" ║ ║\n" +
|
|
17
|
+
" ╚═══════════════════════════════════════════╝\n"
|
|
18
|
+
)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function displaySuccess(message) {
|
|
23
|
+
console.log(chalk.green(`\n✓ ${message}\n`));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function displayError(message) {
|
|
27
|
+
console.log(chalk.red(`\n✗ ${message}\n`));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function displayWarning(message) {
|
|
31
|
+
console.log(chalk.yellow(`\n⚠ ${message}\n`));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function displayInfo(message) {
|
|
35
|
+
console.log(chalk.blue(`\nℹ ${message}\n`));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Display content in a nice box with consistent formatting
|
|
40
|
+
* @param {string} title - Box title
|
|
41
|
+
* @param {string} content - Box content
|
|
42
|
+
*/
|
|
43
|
+
function displayBox(title, content) {
|
|
44
|
+
const lines = content.split("\n");
|
|
45
|
+
|
|
46
|
+
// Calculate max width needed
|
|
47
|
+
const contentWidth = Math.max(
|
|
48
|
+
...lines.map((line) => stripAnsi(line).length),
|
|
49
|
+
stripAnsi(title).length
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// Set minimum and maximum width
|
|
53
|
+
const minWidth = 50;
|
|
54
|
+
const maxWidth = 80;
|
|
55
|
+
const width = Math.min(Math.max(contentWidth, minWidth), maxWidth);
|
|
56
|
+
|
|
57
|
+
// Top border
|
|
58
|
+
console.log(chalk.cyan("┌" + "─".repeat(width + 2) + "┐"));
|
|
59
|
+
|
|
60
|
+
// Title
|
|
61
|
+
const titlePadded = title + " ".repeat(width - stripAnsi(title).length);
|
|
62
|
+
console.log(chalk.cyan("│ ") + chalk.bold(titlePadded) + chalk.cyan(" │"));
|
|
63
|
+
|
|
64
|
+
// Separator
|
|
65
|
+
console.log(chalk.cyan("├" + "─".repeat(width + 2) + "┤"));
|
|
66
|
+
|
|
67
|
+
// Content lines
|
|
68
|
+
lines.forEach((line) => {
|
|
69
|
+
const lineLength = stripAnsi(line).length;
|
|
70
|
+
const padding = " ".repeat(width - lineLength);
|
|
71
|
+
console.log(chalk.cyan("│ ") + line + padding + chalk.cyan(" │"));
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Bottom border
|
|
75
|
+
console.log(chalk.cyan("└" + "─".repeat(width + 2) + "┘\n"));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Strip ANSI color codes to get actual string length
|
|
80
|
+
* @param {string} str - String with potential ANSI codes
|
|
81
|
+
* @returns {string} Clean string
|
|
82
|
+
*/
|
|
83
|
+
function stripAnsi(str) {
|
|
84
|
+
// eslint-disable-next-line no-control-regex
|
|
85
|
+
return str.replace(/\x1B\[\d+m/g, "");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
displayBanner,
|
|
90
|
+
displaySuccess,
|
|
91
|
+
displayError,
|
|
92
|
+
displayWarning,
|
|
93
|
+
displayInfo,
|
|
94
|
+
displayBox,
|
|
95
|
+
};
|