skillscokac 1.5.3 → 1.5.4
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/bin/skillscokac.js +31 -24
- package/package.json +1 -1
package/bin/skillscokac.js
CHANGED
|
@@ -25,6 +25,9 @@ const AXIOS_TIMEOUT = 30000 // 30 seconds
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Validate skill name for security
|
|
28
|
+
* @param {string} skillName - The skill name to validate
|
|
29
|
+
* @returns {string} The trimmed and validated skill name
|
|
30
|
+
* @throws {Error} If validation fails
|
|
28
31
|
*/
|
|
29
32
|
function validateSkillName(skillName) {
|
|
30
33
|
if (!skillName || typeof skillName !== 'string') {
|
|
@@ -57,6 +60,20 @@ function validateSkillName(skillName) {
|
|
|
57
60
|
return trimmed
|
|
58
61
|
}
|
|
59
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Validate and handle skill name with consistent error reporting
|
|
65
|
+
* @param {string} skillName - The skill name to validate
|
|
66
|
+
* @returns {string} The validated skill name, or exits process on error
|
|
67
|
+
*/
|
|
68
|
+
function validateSkillNameOrExit(skillName) {
|
|
69
|
+
try {
|
|
70
|
+
return validateSkillName(skillName)
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.log(chalk.red(`✗ ${error.message}`))
|
|
73
|
+
process.exit(1)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
60
77
|
/**
|
|
61
78
|
* Preprocess frontmatter to fix common YAML issues
|
|
62
79
|
* Automatically quotes values that contain special characters
|
|
@@ -222,13 +239,16 @@ function displaySkillInfo(skill) {
|
|
|
222
239
|
|
|
223
240
|
/**
|
|
224
241
|
* Fetch skill from Marketplace and download ZIP
|
|
242
|
+
* @param {string} skillName - The skill name (must be pre-validated)
|
|
243
|
+
* @param {object} options - Options for fetching (silent mode, etc.)
|
|
244
|
+
* @returns {Promise<object>} The skill data
|
|
225
245
|
*/
|
|
226
246
|
async function fetchSkill(skillName, options = {}) {
|
|
227
247
|
const silent = options.silent || false
|
|
228
248
|
const spinner = silent ? null : ora(`Searching for skill: ${skillName}`).start()
|
|
229
249
|
|
|
230
250
|
try {
|
|
231
|
-
// Validate skill name
|
|
251
|
+
// Validate skill name (defensive check, should be validated by caller)
|
|
232
252
|
skillName = validateSkillName(skillName)
|
|
233
253
|
|
|
234
254
|
// Step 1: Get marketplace data to find postId
|
|
@@ -539,13 +559,8 @@ async function installSkill(skill, installType, options = {}) {
|
|
|
539
559
|
* Install skill command handler
|
|
540
560
|
*/
|
|
541
561
|
async function installSkillCommand(skillName) {
|
|
542
|
-
// Validate skill name
|
|
543
|
-
|
|
544
|
-
skillName = validateSkillName(skillName)
|
|
545
|
-
} catch (error) {
|
|
546
|
-
console.log(chalk.red(`✗ ${error.message}`))
|
|
547
|
-
process.exit(1)
|
|
548
|
-
}
|
|
562
|
+
// Validate skill name early with consistent error handling
|
|
563
|
+
skillName = validateSkillNameOrExit(skillName)
|
|
549
564
|
|
|
550
565
|
// Fetch skill
|
|
551
566
|
const skill = await fetchSkill(skillName)
|
|
@@ -658,8 +673,10 @@ async function installCollectionCommand(collectionId) {
|
|
|
658
673
|
const skillName = skillPost.skillName
|
|
659
674
|
|
|
660
675
|
// Validate skill name before processing
|
|
661
|
-
|
|
662
|
-
|
|
676
|
+
try {
|
|
677
|
+
validateSkillName(skillName)
|
|
678
|
+
} catch (error) {
|
|
679
|
+
console.log(chalk.red(' ✗') + chalk.dim(` Invalid skill name: ${error.message}`))
|
|
663
680
|
failCount++
|
|
664
681
|
continue
|
|
665
682
|
}
|
|
@@ -739,13 +756,8 @@ function getSkillsFromDirectory(skillsDir) {
|
|
|
739
756
|
* Remove skill command handler
|
|
740
757
|
*/
|
|
741
758
|
async function removeSkillCommand(skillName, force = false) {
|
|
742
|
-
// Validate skill name
|
|
743
|
-
|
|
744
|
-
skillName = validateSkillName(skillName)
|
|
745
|
-
} catch (error) {
|
|
746
|
-
console.log(chalk.red(`✗ ${error.message}`))
|
|
747
|
-
process.exit(1)
|
|
748
|
-
}
|
|
759
|
+
// Validate skill name with consistent error handling
|
|
760
|
+
skillName = validateSkillNameOrExit(skillName)
|
|
749
761
|
|
|
750
762
|
// Check if skill exists in personal and/or project directories
|
|
751
763
|
const personalSkillDir = path.join(os.homedir(), '.claude', 'skills', skillName)
|
|
@@ -958,13 +970,8 @@ async function removeAllSkillsCommand(force = false) {
|
|
|
958
970
|
* Download skill command handler
|
|
959
971
|
*/
|
|
960
972
|
async function downloadSkillCommand(skillName, downloadPath) {
|
|
961
|
-
// Validate skill name
|
|
962
|
-
|
|
963
|
-
skillName = validateSkillName(skillName)
|
|
964
|
-
} catch (error) {
|
|
965
|
-
console.log(chalk.red(`✗ ${error.message}`))
|
|
966
|
-
process.exit(1)
|
|
967
|
-
}
|
|
973
|
+
// Validate skill name early with consistent error handling
|
|
974
|
+
skillName = validateSkillNameOrExit(skillName)
|
|
968
975
|
|
|
969
976
|
// Use current directory if no path specified
|
|
970
977
|
if (!downloadPath) {
|