skill-creator 0.0.0 → 1.0.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.
Files changed (145) hide show
  1. package/README.md +148 -19
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +265 -260
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/addContent.d.ts +5 -0
  6. package/dist/commands/addContent.d.ts.map +1 -0
  7. package/dist/commands/addContent.js +74 -0
  8. package/dist/commands/addContent.js.map +1 -0
  9. package/dist/commands/buildIndex.d.ts +5 -0
  10. package/dist/commands/buildIndex.d.ts.map +1 -0
  11. package/dist/commands/buildIndex.js +17 -0
  12. package/dist/commands/buildIndex.js.map +1 -0
  13. package/dist/commands/downloadContext7.d.ts +5 -0
  14. package/dist/commands/downloadContext7.d.ts.map +1 -0
  15. package/dist/commands/downloadContext7.js +62 -0
  16. package/dist/commands/downloadContext7.js.map +1 -0
  17. package/dist/commands/init.d.ts +5 -0
  18. package/dist/commands/init.d.ts.map +1 -0
  19. package/dist/commands/init.js +89 -0
  20. package/dist/commands/init.js.map +1 -0
  21. package/dist/commands/initCc.d.ts +5 -0
  22. package/dist/commands/initCc.d.ts.map +1 -0
  23. package/dist/commands/initCc.js +26 -0
  24. package/dist/commands/initCc.js.map +1 -0
  25. package/dist/commands/listContent.d.ts +5 -0
  26. package/dist/commands/listContent.d.ts.map +1 -0
  27. package/dist/commands/listContent.js +35 -0
  28. package/dist/commands/listContent.js.map +1 -0
  29. package/dist/commands/searchContent.d.ts +5 -0
  30. package/dist/commands/searchContent.d.ts.map +1 -0
  31. package/dist/commands/searchContent.js +98 -0
  32. package/dist/commands/searchContent.js.map +1 -0
  33. package/dist/commands/shared.d.ts +23 -0
  34. package/dist/commands/shared.d.ts.map +1 -0
  35. package/dist/commands/shared.js +92 -0
  36. package/dist/commands/shared.js.map +1 -0
  37. package/dist/commands/updateContext7.d.ts +5 -0
  38. package/dist/commands/updateContext7.d.ts.map +1 -0
  39. package/dist/commands/updateContext7.js +28 -0
  40. package/dist/commands/updateContext7.js.map +1 -0
  41. package/dist/core/autoSearchAdapter.d.ts +42 -0
  42. package/dist/core/autoSearchAdapter.d.ts.map +1 -0
  43. package/dist/core/autoSearchAdapter.js +116 -0
  44. package/dist/core/autoSearchAdapter.js.map +1 -0
  45. package/dist/core/chromaLocalSearch.d.ts +26 -0
  46. package/dist/core/chromaLocalSearch.d.ts.map +1 -0
  47. package/dist/core/chromaLocalSearch.js +212 -0
  48. package/dist/core/chromaLocalSearch.js.map +1 -0
  49. package/dist/core/chromaLocalSimple.d.ts +24 -0
  50. package/dist/core/chromaLocalSimple.d.ts.map +1 -0
  51. package/dist/core/chromaLocalSimple.js +216 -0
  52. package/dist/core/chromaLocalSimple.js.map +1 -0
  53. package/dist/core/chromaSearchAdapter.d.ts +86 -0
  54. package/dist/core/chromaSearchAdapter.d.ts.map +1 -0
  55. package/dist/core/chromaSearchAdapter.js +477 -0
  56. package/dist/core/chromaSearchAdapter.js.map +1 -0
  57. package/dist/core/chromaSearchImproved.d.ts +29 -0
  58. package/dist/core/chromaSearchImproved.d.ts.map +1 -0
  59. package/dist/core/chromaSearchImproved.js +259 -0
  60. package/dist/core/chromaSearchImproved.js.map +1 -0
  61. package/dist/core/chromaServerManager.d.ts +64 -0
  62. package/dist/core/chromaServerManager.d.ts.map +1 -0
  63. package/dist/core/chromaServerManager.js +186 -0
  64. package/dist/core/chromaServerManager.js.map +1 -0
  65. package/dist/core/contentManager.d.ts +1 -0
  66. package/dist/core/contentManager.d.ts.map +1 -1
  67. package/dist/core/contentManager.js +75 -21
  68. package/dist/core/contentManager.js.map +1 -1
  69. package/dist/core/fuseSearch.d.ts +25 -0
  70. package/dist/core/fuseSearch.d.ts.map +1 -0
  71. package/dist/core/fuseSearch.js +198 -0
  72. package/dist/core/fuseSearch.js.map +1 -0
  73. package/dist/core/fuzzySearch.d.ts +66 -0
  74. package/dist/core/fuzzySearch.d.ts.map +1 -0
  75. package/dist/core/fuzzySearch.js +271 -0
  76. package/dist/core/fuzzySearch.js.map +1 -0
  77. package/dist/core/fuzzySearchAdapter.d.ts +33 -0
  78. package/dist/core/fuzzySearchAdapter.d.ts.map +1 -0
  79. package/dist/core/fuzzySearchAdapter.js +185 -0
  80. package/dist/core/fuzzySearchAdapter.js.map +1 -0
  81. package/dist/core/portUtils.d.ts +51 -0
  82. package/dist/core/portUtils.d.ts.map +1 -0
  83. package/dist/core/portUtils.js +120 -0
  84. package/dist/core/portUtils.js.map +1 -0
  85. package/dist/core/runScript.d.ts +1 -1
  86. package/dist/core/runScript.d.ts.map +1 -1
  87. package/dist/core/runScript.js +27 -210
  88. package/dist/core/runScript.js.map +1 -1
  89. package/dist/core/searchAdapter.d.ts +48 -0
  90. package/dist/core/searchAdapter.d.ts.map +1 -0
  91. package/dist/core/searchAdapter.js +6 -0
  92. package/dist/core/searchAdapter.js.map +1 -0
  93. package/dist/core/searchEngineFactory.d.ts +30 -0
  94. package/dist/core/searchEngineFactory.d.ts.map +1 -0
  95. package/dist/core/searchEngineFactory.js +41 -0
  96. package/dist/core/searchEngineFactory.js.map +1 -0
  97. package/dist/core/simpleLocalSearch.d.ts +50 -0
  98. package/dist/core/simpleLocalSearch.d.ts.map +1 -0
  99. package/dist/core/simpleLocalSearch.js +406 -0
  100. package/dist/core/simpleLocalSearch.js.map +1 -0
  101. package/dist/core/skillCreator.d.ts +0 -2
  102. package/dist/core/skillCreator.d.ts.map +1 -1
  103. package/dist/core/skillCreator.js +20 -92
  104. package/dist/core/skillCreator.js.map +1 -1
  105. package/dist/core/unifiedSearch.d.ts +57 -11
  106. package/dist/core/unifiedSearch.d.ts.map +1 -1
  107. package/dist/core/unifiedSearch.js +88 -29
  108. package/dist/core/unifiedSearch.js.map +1 -1
  109. package/dist/index.d.ts +4 -1
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +3 -1
  112. package/dist/index.js.map +1 -1
  113. package/dist/search_format/enhancedFormatter.d.ts +109 -0
  114. package/dist/search_format/enhancedFormatter.d.ts.map +1 -0
  115. package/dist/search_format/enhancedFormatter.js +262 -0
  116. package/dist/search_format/enhancedFormatter.js.map +1 -0
  117. package/dist/search_format/index.d.ts +10 -0
  118. package/dist/search_format/index.d.ts.map +1 -0
  119. package/dist/search_format/index.js +22 -0
  120. package/dist/search_format/index.js.map +1 -0
  121. package/dist/search_format/listFormatter.d.ts +16 -0
  122. package/dist/search_format/listFormatter.d.ts.map +1 -0
  123. package/dist/search_format/listFormatter.js +51 -0
  124. package/dist/search_format/listFormatter.js.map +1 -0
  125. package/dist/search_format/types.d.ts +69 -0
  126. package/dist/search_format/types.d.ts.map +1 -0
  127. package/dist/search_format/types.js +5 -0
  128. package/dist/search_format/types.js.map +1 -0
  129. package/dist/test/testFuzzy.d.ts +3 -0
  130. package/dist/test/testFuzzy.d.ts.map +1 -0
  131. package/dist/test/testFuzzy.js +72 -0
  132. package/dist/test/testFuzzy.js.map +1 -0
  133. package/dist/test-fuzzy.d.ts +6 -0
  134. package/dist/test-fuzzy.d.ts.map +1 -0
  135. package/dist/test-fuzzy.js +65 -0
  136. package/dist/test-fuzzy.js.map +1 -0
  137. package/dist/types/index.d.ts +5 -0
  138. package/dist/types/index.d.ts.map +1 -1
  139. package/dist/utils/package.d.ts +17 -0
  140. package/dist/utils/package.d.ts.map +1 -1
  141. package/dist/utils/package.js +51 -14
  142. package/dist/utils/package.js.map +1 -1
  143. package/package.json +9 -8
  144. package/templates/skill-creator.md +65 -153
  145. package/templates/skill-creator.zh-CN.md +93 -0
package/dist/cli.js CHANGED
@@ -4,194 +4,139 @@
4
4
  */
5
5
  import { Command } from 'commander';
6
6
  import gradient from 'gradient-string';
7
- import inquirer from 'inquirer';
8
7
  import { SkillCreator } from './core/skillCreator.js';
9
8
  import { PackageUtils } from './utils/package.js';
10
9
  const program = new Command();
10
+ /**
11
+ * Helper function to create a skill for a package with interactive confirmation
12
+ */
13
+ async function createSkillForPackage(skillDirName, skillDisplayName, scope, force = false) {
14
+ const creator = new SkillCreator();
15
+ // Extract package name from skillDirName if it's in format "package@version"
16
+ // Otherwise, use the skillDirName as is
17
+ const lastAtSignIndex = skillDirName.lastIndexOf('@');
18
+ const packageName = lastAtSignIndex > 0 ? skillDirName.substring(0, lastAtSignIndex) : skillDirName;
19
+ const createOptions = {
20
+ packageName: packageName, // Extract package name from skillDirName
21
+ path: scope === 'user' ? undefined : '.claude/skills',
22
+ storage: scope,
23
+ noInitDocs: true, // Docs are downloaded in a separate step in the new flow
24
+ force: force, // Pass force option to SkillCreator
25
+ };
26
+ console.log(gradient('cyan', 'magenta')('\nšŸš€ Creating skill...'));
27
+ const result = await creator.createSkill(createOptions);
28
+ if (result.created) {
29
+ console.log(gradient('green', 'cyan')(`\nāœ… ${result.message}`));
30
+ console.log(gradient('blue', 'cyan')(`šŸ“ Skill Path: ${result.skillPath}`));
31
+ console.log('\nšŸŽ‰ Skill created successfully!');
32
+ console.log('\nNext steps:');
33
+ console.log(`1. Add content: skill-creator add-skill --pwd "${result.skillPath}" --title "My Note" --content "Your content"`);
34
+ console.log(`2. Search skill: skill-creator search-skill --pwd "${result.skillPath}" "query"`);
35
+ console.log(`3. Download docs: skill-creator download-context7 --pwd "${result.skillPath}" <context7_library_id>`);
36
+ return result.skillPath;
37
+ }
38
+ else {
39
+ throw new Error(result.message || 'Failed to create skill');
40
+ }
41
+ }
11
42
  program
12
43
  .name('skill-creator')
13
44
  .description('Create claude-code-skills with documentation management')
14
45
  .version('2.0.0');
46
+ // Add create-cc-skill command
15
47
  program
16
- .argument('<package_name>', 'Package name to create documentation skill for (e.g., tanstack-router)')
17
- .option('-p, --path <path>', 'Output path (default: current directory)', '.')
18
- .option('-d, --description <description>', 'Description of the skill')
19
- .option('-c, --context7-id <id>', 'Context7 library ID (e.g., /tanstack/router/docs)')
20
- .option('--no-init-docs', 'Skip initial documentation download')
21
- .option('-s, --storage <storage>', 'Where to store the skill', 'project')
22
- .option('--package-version <version>', 'Specific version to use')
23
- .option('--no-interactive', 'Skip interactive prompts')
24
- .option('--search', 'Enable interactive package search')
25
- .action(async (packageName, options, _command) => {
26
- // Validate package name
27
- if (!packageName || packageName.trim().length === 0) {
28
- console.error('āŒ Error: Package name is required');
29
- process.exit(1);
30
- }
31
- console.log(gradient('cyan', 'magenta')('\nšŸ” Searching for package:'));
32
- console.log(gradient('yellow', 'orange')(packageName));
33
- console.log(gradient('cyan', 'magenta')('='.repeat(50)));
34
- let selectedPackage = { name: packageName, version: options.packageVersion };
35
- // If not a valid package name or search is enabled, search for suggestions
36
- if (!PackageUtils.validatePackageName(packageName) || options.search) {
37
- const suggestions = await PackageUtils.suggestPackages(packageName, { limit: 10 });
38
- if (suggestions.length === 0) {
39
- console.error(`āŒ No packages found for "${packageName}"`);
40
- process.exit(1);
41
- }
42
- if (suggestions.length > 1 && !options.noInteractive) {
43
- console.log(`\nšŸ“¦ Found ${suggestions.length} package(s):`);
44
- const choices = suggestions.map((pkg) => ({
45
- name: `${pkg.name} (${pkg.version}) - ${pkg.description.slice(0, 80)}${pkg.description.length > 80 ? '...' : ''}`,
46
- value: pkg.name,
47
- short: pkg.name,
48
- }));
49
- const { selectedPkg } = await inquirer.prompt([
48
+ .command('create-cc-skill')
49
+ .requiredOption('--scope <scope>', 'Storage scope (project or user)')
50
+ .option('--interactive', 'Enable interactive confirmation prompts')
51
+ .option('--force', 'Force overwrite existing files in the skill directory')
52
+ .argument('<skill_dir_name>', 'The name of the skill directory to create')
53
+ .action(async (skillDirName, options) => {
54
+ try {
55
+ const { scope, interactive, force } = options;
56
+ // Import inquirer for interactive prompts
57
+ const { default: inquirer } = await import('inquirer');
58
+ let finalSkillName = skillDirName;
59
+ if (interactive) {
60
+ // 1. ē”®č®¤å­˜å‚Øä½ē½®
61
+ console.log('Skill Creation Configuration:');
62
+ console.log(`- Skill directory name: ${skillDirName}`);
63
+ console.log(`- Storage scope: ${scope}`);
64
+ const { confirmLocation } = await inquirer.prompt([
50
65
  {
51
- type: 'list',
52
- name: 'selectedPkg',
53
- message: 'Select a package:',
54
- choices,
55
- pageSize: 10,
66
+ type: 'confirm',
67
+ name: 'confirmLocation',
68
+ message: `Create skill in ${scope === 'project' ? './.claude/skills/' : '~/.claude/skills/'}?`,
69
+ default: true,
56
70
  },
57
71
  ]);
58
- selectedPackage.name = selectedPkg;
59
- selectedPackage.version = await PackageUtils.getPackageVersion(selectedPkg) || suggestions.find(s => s.name === selectedPkg)?.version;
60
- }
61
- else {
62
- selectedPackage.name = suggestions[0].name;
63
- selectedPackage.version = suggestions[0].version;
64
- }
65
- }
66
- // Get version if not specified
67
- if (!selectedPackage.version) {
68
- selectedPackage.version = await PackageUtils.getPackageVersion(selectedPackage.name);
69
- }
70
- if (!selectedPackage.version) {
71
- console.warn(`āš ļø Could not determine version for ${selectedPackage.name}`);
72
- }
73
- console.log(gradient('green', 'cyan')(`\nāœ… Selected package: ${selectedPackage.name}@${selectedPackage.version || 'latest'}`));
74
- // Ask for storage location if not specified
75
- let storage = options.storage;
76
- let path = options.path;
77
- if (!options.noInteractive && !options.storage) {
78
- const { storageLocation } = await inquirer.prompt([
79
- {
80
- type: 'list',
81
- name: 'storageLocation',
82
- message: 'Where would you like to store this skill?',
83
- choices: [
84
- {
85
- name: 'šŸ“ Current project (./.claude/skills/)',
86
- value: 'project',
87
- },
88
- {
89
- name: 'šŸ  User directory (~/.claude/skills/)',
90
- value: 'user',
91
- },
92
- ],
93
- default: 'project',
94
- },
95
- ]);
96
- storage = storageLocation;
97
- if (storage === 'project' && path === '.') {
98
- const { useDefaultPath } = await inquirer.prompt([
72
+ if (!confirmLocation) {
73
+ console.log('Skill creation cancelled.');
74
+ process.exit(0);
75
+ }
76
+ // 2. čÆ¢é—®ęŠ€čƒ½å‘½å
77
+ const { skillNameConfirmed } = await inquirer.prompt([
99
78
  {
100
79
  type: 'confirm',
101
- name: 'useDefaultPath',
102
- message: 'Use current directory for skill storage?',
80
+ name: 'skillNameConfirmed',
81
+ message: `Use '${skillDirName}' as the skill name?`,
103
82
  default: true,
104
83
  },
105
84
  ]);
106
- if (!useDefaultPath) {
107
- const { customPath } = await inquirer.prompt([
85
+ if (!skillNameConfirmed) {
86
+ const { customSkillName } = await inquirer.prompt([
108
87
  {
109
88
  type: 'input',
110
- name: 'customPath',
111
- message: 'Enter custom path:',
112
- default: './',
89
+ name: 'customSkillName',
90
+ message: 'Enter a new skill name:',
91
+ validate: (input) => input.trim() !== '' || 'Skill name cannot be empty',
113
92
  },
114
93
  ]);
115
- path = customPath;
94
+ finalSkillName = customSkillName.trim();
95
+ }
96
+ // 3. ē”®č®¤ęœ€ē»ˆé…ē½®
97
+ console.log('\nFinal Configuration:');
98
+ console.log(`- Skill directory name: ${skillDirName}`);
99
+ console.log(`- Skill display name: ${finalSkillName}`);
100
+ console.log(`- Storage location: ${scope === 'project' ? './.claude/skills/' : '~/.claude/skills/'}`);
101
+ const { confirmFinal } = await inquirer.prompt([
102
+ {
103
+ type: 'confirm',
104
+ name: 'confirmFinal',
105
+ message: 'Proceed with skill creation?',
106
+ default: true,
107
+ },
108
+ ]);
109
+ if (!confirmFinal) {
110
+ console.log('Skill creation cancelled.');
111
+ process.exit(0);
116
112
  }
117
113
  }
114
+ // Create the skill with confirmed configuration
115
+ const skillPath = await createSkillForPackage(skillDirName, finalSkillName, scope, force);
116
+ console.log(`Skill created successfully at: ${skillPath}`);
118
117
  }
119
- console.log(gradient('cyan', 'magenta')('\nšŸ“ Creating skill...'));
120
- console.log(gradient('cyan', 'magenta')('='.repeat(50)));
121
- const creator = new SkillCreator();
122
- // Create skill folder name
123
- const skillName = PackageUtils.createSkillFolderName(selectedPackage.name, selectedPackage.version ?? '1.0.0');
124
- console.log(`\nšŸ“ Skill folder name: ${skillName}`);
125
- // Create skill
126
- const createOptions = {
127
- packageName: selectedPackage.name,
128
- path,
129
- description: options.description,
130
- context7Id: options.context7Id,
131
- noInitDocs: options.noInitDocs,
132
- storage,
133
- version: selectedPackage.version,
134
- };
135
- const result = await creator.createSkill(createOptions);
136
- // Print result
137
- if (result.created) {
138
- console.log(gradient('green', 'cyan')(`\nāœ… ${result.message}`));
139
- if (result.docsInitialized) {
140
- console.log(`āœ… Documentation downloaded and indexed`);
141
- }
142
- console.log(`\nšŸ“‹ Next steps:`);
143
- console.log(`1. cd ${result.skillPath}`);
144
- console.log(`2. npm install`);
145
- if (!result.docsInitialized) {
146
- console.log(`\nšŸ“š To initialize documentation:`);
147
- console.log(` Option A: Use Context7 (requires MCP)`);
148
- console.log(` - First, resolve library ID with AI help or Context7 search`);
149
- console.log(` - Update config.json with the correct context7_library_id`);
150
- console.log(` - Run: npm run update-context7`);
151
- console.log(`\n Option B: Add documentation manually`);
152
- console.log(` - Run: npm run add -- --title 'Topic' --content 'Your content'`);
153
- }
154
- console.log(`\n3. npm run build-index`);
155
- console.log(`4. npm run search -- --query 'test query'`);
156
- if (options.context7Id) {
157
- console.log(`\nšŸ’” Note: Context7 library ID set to: ${options.context7Id}`);
158
- console.log(` If this is incorrect, edit config.json and update context7_library_id`);
159
- }
160
- }
161
- else {
162
- console.error(`āŒ ${result.message}`);
118
+ catch (error) {
119
+ console.error('Error:', error instanceof Error ? error.message : String(error));
163
120
  process.exit(1);
164
121
  }
165
122
  });
166
- // Add init command to install subagents
123
+ // Add interactive init command
167
124
  program
168
125
  .command('init')
126
+ .description('Install skill-creator as subagent (interactive mode)')
127
+ .action(async () => {
128
+ const { runScript } = await import('./core/runScript.js');
129
+ await runScript('init', []);
130
+ });
131
+ // Add init command to install subagents (non-interactive version)
132
+ program
133
+ .command('init-cc')
169
134
  .description('Install skill-creator as subagent in ~/.claude/agents/')
170
135
  .action(async () => {
171
- const { homedir } = await import('node:os');
172
- const { join } = await import('node:path');
173
- const { mkdirSync, writeFileSync } = await import('node:fs');
174
- const agentsDir = join(homedir(), '.claude', 'agents');
175
- const skillCreatorDir = join(agentsDir, 'skill-creator');
176
- // Create directories
177
- mkdirSync(agentsDir, { recursive: true });
178
- mkdirSync(skillCreatorDir, { recursive: true });
179
- // Create subagent manifest
180
- const manifest = {
181
- name: 'skill-creator',
182
- version: '2.0.0',
183
- description: 'Claude Code skill creation agent',
184
- main: process.cwd(),
185
- commands: [
186
- 'search',
187
- 'get-name',
188
- 'download-context7',
189
- 'addSkill'
190
- ]
191
- };
192
- writeFileSync(join(skillCreatorDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
193
- console.log(gradient('green', 'cyan')('\nāœ… Skill-creator subagent installed successfully!'));
194
- console.log(`šŸ“ Location: ${skillCreatorDir}`);
136
+ const { runScript } = await import('./core/runScript.js');
137
+ // For init-cc, we want the non-interactive version that installs to user directory
138
+ // Use --scope=user for consistency with other CLI commands
139
+ await runScript('init', ['--scope', 'user']);
195
140
  });
196
141
  // Add search command for package searching
197
142
  program
@@ -199,148 +144,205 @@ program
199
144
  .argument('<keywords>', 'Search keywords for npm packages')
200
145
  .option('-l, --limit <limit>', 'Number of results to show', '10')
201
146
  .action(async (keywords, options) => {
202
- // Handle multiple keywords by splitting
203
147
  const query = keywords;
204
- console.log(gradient('cyan', 'magenta')('\nšŸ” Searching npm packages...'));
205
- console.log(gradient('yellow', 'orange')(query));
206
- console.log(gradient('cyan', 'magenta')('='.repeat(50)));
207
148
  const suggestions = await PackageUtils.suggestPackages(query, {
208
- limit: parseInt(options.limit)
209
- });
210
- if (suggestions.length === 0) {
211
- console.error(`āŒ No packages found for "${query}"`);
212
- return;
213
- }
214
- console.log(`\nšŸ“¦ Found ${suggestions.length} package(s):`);
215
- suggestions.forEach((pkg, index) => {
216
- console.log(`\n${index + 1}. ${gradient('green', 'cyan')(pkg.name)} (${pkg.version})`);
217
- console.log(` ${pkg.description.slice(0, 100)}${pkg.description.length > 100 ? '...' : ''}`);
218
- console.log(` šŸ‘¤ ${pkg.publisher} | ⭐ ${pkg.score.toFixed(2)}`);
149
+ limit: parseInt(options.limit),
219
150
  });
151
+ console.log(JSON.stringify(suggestions, null, 2));
220
152
  });
221
- // Add get-name command to generate skill name
153
+ // Add get-info command for package information
222
154
  program
223
- .command('get-name')
224
- .argument('<package_name>', 'Package name')
225
- .option('-v, --version <version>', 'Specific version')
226
- .action(async (packageName, options) => {
227
- const version = options.version || await PackageUtils.getPackageVersion(packageName);
228
- if (!version) {
229
- console.error(`āŒ Could not determine version for ${packageName}`);
155
+ .command('get-info')
156
+ .argument('<package_name>', 'The npm package name to get information for')
157
+ .action(async (packageName) => {
158
+ const packageInfo = await PackageUtils.getPackageInfo(packageName);
159
+ if (!packageInfo) {
160
+ console.error(`āŒ Package "${packageName}" not found or API error occurred.`);
230
161
  process.exit(1);
231
162
  }
232
- const skillName = PackageUtils.createSkillFolderName(packageName, version);
233
- console.log(gradient('green', 'cyan')(`\nāœ… Skill name: ${skillName}`));
234
- console.log(` Package: ${packageName}@${version}`);
163
+ const version = packageInfo.version;
164
+ const skillDirName = PackageUtils.createSkillFolderName(packageName, version);
165
+ const result = {
166
+ skill_dir_name: skillDirName,
167
+ name: packageInfo.name,
168
+ version: version,
169
+ description: packageInfo.description || '',
170
+ keywords: packageInfo.keywords || [],
171
+ license: packageInfo.license || '',
172
+ author: packageInfo.author || '',
173
+ maintainers: packageInfo.maintainers || [],
174
+ homepage: packageInfo.homepage || '',
175
+ repository: {
176
+ url: packageInfo.repository?.url || '',
177
+ type: packageInfo.repository?.type || '',
178
+ },
179
+ bugs: {
180
+ url: packageInfo.bugs?.url || '',
181
+ },
182
+ funding: packageInfo.funding || '',
183
+ scripts: packageInfo.scripts || {},
184
+ engines: packageInfo.engines || {},
185
+ types: packageInfo.types || '',
186
+ dependencies: packageInfo.dependencies || {},
187
+ devDependencies: packageInfo.devDependencies || {},
188
+ time: {
189
+ created: packageInfo.time?.created || '',
190
+ modified: packageInfo.time?.modified || '',
191
+ },
192
+ };
193
+ console.log(JSON.stringify(result, null, 2));
235
194
  });
236
- // Add download-context7 command
195
+ // Add search-skill command
237
196
  program
238
- .command('download-context7')
239
- .argument('<package_name>', 'Package name')
240
- .argument('<context7_id>', 'Context7 library ID')
241
- .option('-f, --force', 'Force update even if up to date')
242
- .option('-s, --storage <storage>', 'Storage location (project|user)', 'project')
243
- .action(async (packageName, context7Id, options) => {
244
- console.log(gradient('cyan', 'magenta')('\nšŸ“„ Downloading Context7 documentation...'));
245
- console.log(`Package: ${packageName}`);
246
- console.log(`Context7 ID: ${context7Id}`);
247
- // Find existing skill
248
- const { join } = await import('node:path');
249
- const { homedir } = await import('node:os');
250
- const baseDir = options.storage === 'user'
251
- ? join(homedir(), '.claude', 'skills')
252
- : join(process.cwd(), '.claude', 'skills');
253
- // Find skill directory
254
- const { readdirSync } = await import('node:fs');
255
- const dirs = readdirSync(baseDir, { withFileTypes: true })
256
- .filter(dirent => dirent.isDirectory())
257
- .map(dirent => dirent.name)
258
- .filter(name => name.includes(packageName.replace(/[^a-z0-9]/gi, '')));
259
- if (dirs.length === 0) {
260
- console.error(`āŒ No skill found for package ${packageName}`);
261
- console.log(`šŸ’” Create a skill first with: skill-creator ${packageName}`);
197
+ .command('search-skill')
198
+ .argument('<query>', 'Search query')
199
+ .option('--pwd <path>', 'Path to the skill directory')
200
+ .option('--package <name>', 'Package name to find skill directory for')
201
+ .option('--mode <mode>', 'Search mode: auto, fuzzy, or chroma', 'auto')
202
+ .option('--list', 'Show simplified list view (basic info only)', false)
203
+ .action(async (query, options) => {
204
+ let skillDir;
205
+ if (options.pwd) {
206
+ skillDir = options.pwd;
207
+ }
208
+ else if (options.package) {
209
+ const { join } = await import('node:path');
210
+ const { homedir } = await import('node:os');
211
+ const { readdirSync, existsSync } = await import('node:fs');
212
+ const findDir = (base) => {
213
+ if (!existsSync(base))
214
+ return undefined;
215
+ const dirs = readdirSync(base, { withFileTypes: true })
216
+ .filter((dirent) => dirent.isDirectory())
217
+ .map((dirent) => dirent.name)
218
+ .filter((name) => name.includes(options.package.replace(/[^a-z0-9]/gi, '')));
219
+ return dirs.length > 0 ? join(base, dirs[0]) : undefined;
220
+ };
221
+ skillDir =
222
+ findDir(join(process.cwd(), '.claude', 'skills')) ||
223
+ findDir(join(homedir(), '.claude', 'skills'));
224
+ }
225
+ if (!skillDir) {
226
+ console.error('āŒ Could not find skill directory. Please provide --pwd or a valid --package.');
262
227
  process.exit(1);
263
228
  }
264
- const skillDir = join(baseDir, dirs[0]);
265
- // Change to skill directory and run update script
229
+ console.log(gradient('cyan', 'magenta')('\nšŸ” Searching in skill...'));
230
+ console.log(`Skill Path: ${skillDir}`);
231
+ console.log(`Query: ${query}`);
266
232
  const { chdir } = await import('node:process');
267
233
  const originalCwd = process.cwd();
268
234
  chdir(skillDir);
269
235
  try {
270
236
  const { runScript } = await import('./core/runScript.js');
271
- const args = ['--force'];
272
- await runScript('update-context7', args);
237
+ const args = ['--query', query];
238
+ if (options.mode !== 'auto')
239
+ args.push('--mode', options.mode);
240
+ if (options.list)
241
+ args.push('--list');
242
+ // Enhanced search is now enabled by default, no need for --enhanced flag
243
+ await runScript('search-skill', args);
273
244
  }
274
245
  finally {
275
246
  chdir(originalCwd);
276
247
  }
277
- console.log(gradient('green', 'cyan')('\nāœ… Documentation downloaded and sliced!'));
278
248
  });
279
- // Add search-in-skill command
249
+ // Add download-context7 command
280
250
  program
281
- .command('search-in-skill')
282
- .argument('<package_name>', 'Package name')
283
- .argument('<query>', 'Search query')
284
- .action(async (packageName, query) => {
285
- console.log(gradient('cyan', 'magenta')('\nšŸ” Searching in skill...'));
286
- console.log(`Package: ${packageName}`);
287
- console.log(`Query: ${query}`);
288
- // Find skill directory
289
- const { join, dirname } = await import('node:path');
290
- const { homedir } = await import('node:os');
291
- const { readdirSync } = await import('node:fs');
292
- const baseDir = join(process.cwd(), '.claude', 'skills');
293
- const dirs = readdirSync(baseDir, { withFileTypes: true })
294
- .filter(dirent => dirent.isDirectory())
295
- .map(dirent => dirent.name)
296
- .filter(name => name.includes(packageName.replace(/[^a-z0-9]/gi, '')));
297
- if (dirs.length === 0) {
298
- console.error(`āŒ No skill found for package ${packageName}`);
251
+ .command('download-context7')
252
+ .argument('<project_id>', 'Context7 library ID')
253
+ .option('--pwd <path>', 'Path to the skill directory')
254
+ .option('--package <name>', 'Package name to find skill directory for')
255
+ .option('-f, --force', 'Force update even if up to date')
256
+ .option('--skip-chroma-indexing', 'Skip automatic ChromaDB index building after download')
257
+ .action(async (projectId, options) => {
258
+ let skillDir;
259
+ if (options.pwd) {
260
+ skillDir = options.pwd;
261
+ }
262
+ else if (options.package) {
263
+ const { join } = await import('node:path');
264
+ const { homedir } = await import('node:os');
265
+ const { readdirSync, existsSync } = await import('node:fs');
266
+ const findDir = (base) => {
267
+ if (!existsSync(base))
268
+ return undefined;
269
+ const dirs = readdirSync(base, { withFileTypes: true })
270
+ .filter((dirent) => dirent.isDirectory())
271
+ .map((dirent) => dirent.name)
272
+ .filter((name) => name.includes(options.package.replace(/[^a-z0-9]/gi, '')));
273
+ return dirs.length > 0 ? join(base, dirs[0]) : undefined;
274
+ };
275
+ skillDir =
276
+ findDir(join(process.cwd(), '.claude', 'skills')) ||
277
+ findDir(join(homedir(), '.claude', 'skills'));
278
+ }
279
+ if (!skillDir) {
280
+ console.error('āŒ Could not find skill directory. Please provide --pwd or a valid --package.');
299
281
  process.exit(1);
300
282
  }
301
- const skillDir = join(baseDir, dirs[0]);
302
- // Change to skill directory and run search script
283
+ console.log(gradient('cyan', 'magenta')('\nšŸ“„ Downloading Context7 documentation...'));
284
+ console.log(`Skill Path: ${skillDir}`);
285
+ console.log(`Context7 ID: ${projectId}`);
303
286
  const { chdir } = await import('node:process');
304
287
  const originalCwd = process.cwd();
305
288
  chdir(skillDir);
306
289
  try {
307
290
  const { runScript } = await import('./core/runScript.js');
308
- const args = ['--query', query];
309
- await runScript('search', args);
291
+ const args = [];
292
+ if (options.force)
293
+ args.push('--force');
294
+ if (options['skip-chroma-indexing'])
295
+ args.push('--skip-chroma-indexing');
296
+ args.push('--project-id', projectId);
297
+ await runScript('download-context7', args);
310
298
  }
311
299
  finally {
312
300
  chdir(originalCwd);
313
301
  }
302
+ console.log(gradient('green', 'cyan')('\nāœ… Documentation downloaded and sliced!'));
314
303
  });
315
- // Add add-skill-content command
304
+ // Add add-skill command
316
305
  program
317
- .command('addSkill')
318
- .argument('<package_name>', 'Package name')
306
+ .command('add-skill')
307
+ .option('--pwd <path>', 'Path to the skill directory')
308
+ .option('--package <name>', 'Package name to find skill directory for')
319
309
  .option('-t, --title <title>', 'Content title')
320
310
  .option('-c, --content <content>', 'Content text')
321
311
  .option('-f, --file <file>', 'Read content from file')
322
- .action(async (packageName, options) => {
312
+ .option('--force', 'Force overwrite existing content')
313
+ .option('--force-append', 'Append content to existing file instead of creating new file')
314
+ .action(async (options) => {
323
315
  if (!options.title && !options.file) {
324
316
  console.error('āŒ Please provide either --title or --file');
325
317
  process.exit(1);
326
318
  }
327
- console.log(gradient('cyan', 'magenta')('\nšŸ“ Adding content to skill...'));
328
- console.log(`Package: ${packageName}`);
329
- // Find skill directory
330
- const { join, dirname } = await import('node:path');
331
- const { homedir } = await import('node:os');
332
- const { readdirSync } = await import('node:fs');
333
- const baseDir = join(process.cwd(), '.claude', 'skills');
334
- const dirs = readdirSync(baseDir, { withFileTypes: true })
335
- .filter(dirent => dirent.isDirectory())
336
- .map(dirent => dirent.name)
337
- .filter(name => name.includes(packageName.replace(/[^a-z0-9]/gi, '')));
338
- if (dirs.length === 0) {
339
- console.error(`āŒ No skill found for package ${packageName}`);
319
+ let skillDir;
320
+ if (options.pwd) {
321
+ skillDir = options.pwd;
322
+ }
323
+ else if (options.package) {
324
+ const { join } = await import('node:path');
325
+ const { homedir } = await import('node:os');
326
+ const { readdirSync, existsSync } = await import('node:fs');
327
+ const findDir = (base) => {
328
+ if (!existsSync(base))
329
+ return undefined;
330
+ const dirs = readdirSync(base, { withFileTypes: true })
331
+ .filter((dirent) => dirent.isDirectory())
332
+ .map((dirent) => dirent.name)
333
+ .filter((name) => name.includes(options.package.replace(/[^a-z0-9]/gi, '')));
334
+ return dirs.length > 0 ? join(base, dirs[0]) : undefined;
335
+ };
336
+ skillDir =
337
+ findDir(join(process.cwd(), '.claude', 'skills')) ||
338
+ findDir(join(homedir(), '.claude', 'skills'));
339
+ }
340
+ if (!skillDir) {
341
+ console.error('āŒ Could not find skill directory. Please provide --pwd or a valid --package.');
340
342
  process.exit(1);
341
343
  }
342
- const skillDir = join(baseDir, dirs[0]);
343
- // Change to skill directory and run add script
344
+ console.log(gradient('cyan', 'magenta')('\nšŸ“ Adding content to skill...'));
345
+ console.log(`Skill Path: ${skillDir}`);
344
346
  const { chdir } = await import('node:process');
345
347
  const originalCwd = process.cwd();
346
348
  chdir(skillDir);
@@ -353,6 +355,10 @@ program
353
355
  args.push('--content', options.content);
354
356
  if (options.file)
355
357
  args.push('--file', options.file);
358
+ if (options.force)
359
+ args.push('--force');
360
+ if (options.forceAppend)
361
+ args.push('--force-append');
356
362
  await runScript('add', args);
357
363
  }
358
364
  finally {
@@ -363,7 +369,7 @@ program
363
369
  // Add sub-commands for script execution
364
370
  program
365
371
  .command('run-script')
366
- .argument('<script>', 'Script to run (search, add, update-context7, build-index, list-content)')
372
+ .argument('<script>', 'Script to run (search, add, download-context7, build-index, list-content)')
367
373
  .allowUnknownOption(true)
368
374
  .action(async (script) => {
369
375
  const { runScript } = await import('./core/runScript.js');
@@ -372,7 +378,6 @@ program
372
378
  // Export for testing
373
379
  export { program };
374
380
  // Run CLI if this file is executed directly
375
- if (import.meta.url === `file://${process.argv[1]}`) {
376
- program.parse();
377
- }
381
+ // Always parse for now since we're using this as the main CLI entry point
382
+ program.parse();
378
383
  //# sourceMappingURL=cli.js.map