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.
Files changed (2) hide show
  1. package/bin/skillscokac.js +31 -24
  2. package/package.json +1 -1
@@ -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 (fetchSkill also validates, but do it early)
543
- try {
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
- if (!skillName || typeof skillName !== 'string' || skillName.length > 100) {
662
- console.log(chalk.red(' ✗') + chalk.dim(' Invalid skill name in collection'))
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
- try {
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 (fetchSkill also validates, but do it early)
962
- try {
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillscokac",
3
- "version": "1.5.3",
3
+ "version": "1.5.4",
4
4
  "description": "CLI tool to install and manage Claude Code skills from skills.cokac.com",
5
5
  "main": "bin/skillscokac.js",
6
6
  "bin": {