@skillsmith/cli 0.3.0 → 0.3.2

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 (107) hide show
  1. package/README.md +158 -0
  2. package/assets/skillsmith-skill/SKILL.md +235 -0
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/commands/author/index.d.ts +16 -0
  5. package/dist/src/commands/author/index.d.ts.map +1 -0
  6. package/dist/src/commands/author/index.js +18 -0
  7. package/dist/src/commands/author/index.js.map +1 -0
  8. package/dist/src/commands/author/init.d.ts +47 -0
  9. package/dist/src/commands/author/init.d.ts.map +1 -0
  10. package/dist/src/commands/author/init.js +346 -0
  11. package/dist/src/commands/author/init.js.map +1 -0
  12. package/dist/src/commands/author/mcp-init.d.ts +20 -0
  13. package/dist/src/commands/author/mcp-init.d.ts.map +1 -0
  14. package/dist/src/commands/author/mcp-init.js +183 -0
  15. package/dist/src/commands/author/mcp-init.js.map +1 -0
  16. package/dist/src/commands/author/subagent.d.ts +22 -0
  17. package/dist/src/commands/author/subagent.d.ts.map +1 -0
  18. package/dist/src/commands/author/subagent.js +166 -0
  19. package/dist/src/commands/author/subagent.js.map +1 -0
  20. package/dist/src/commands/author/transform.d.ts +22 -0
  21. package/dist/src/commands/author/transform.d.ts.map +1 -0
  22. package/dist/src/commands/author/transform.js +141 -0
  23. package/dist/src/commands/author/transform.js.map +1 -0
  24. package/dist/src/commands/author/utils.d.ts +27 -0
  25. package/dist/src/commands/author/utils.d.ts.map +1 -0
  26. package/dist/src/commands/author/utils.js +118 -0
  27. package/dist/src/commands/author/utils.js.map +1 -0
  28. package/dist/src/commands/index.d.ts +3 -1
  29. package/dist/src/commands/index.d.ts.map +1 -1
  30. package/dist/src/commands/index.js +6 -1
  31. package/dist/src/commands/index.js.map +1 -1
  32. package/dist/src/commands/install-skill.d.ts +13 -0
  33. package/dist/src/commands/install-skill.d.ts.map +1 -0
  34. package/dist/src/commands/install-skill.js +137 -0
  35. package/dist/src/commands/install-skill.js.map +1 -0
  36. package/dist/src/commands/manage.d.ts +4 -1
  37. package/dist/src/commands/manage.d.ts.map +1 -1
  38. package/dist/src/commands/manage.js +56 -10
  39. package/dist/src/commands/manage.js.map +1 -1
  40. package/dist/src/commands/merge.d.ts +17 -0
  41. package/dist/src/commands/merge.d.ts.map +1 -0
  42. package/dist/src/commands/merge.js +160 -0
  43. package/dist/src/commands/merge.js.map +1 -0
  44. package/dist/src/commands/recommend.d.ts +1 -4
  45. package/dist/src/commands/recommend.d.ts.map +1 -1
  46. package/dist/src/commands/recommend.helpers.d.ts +58 -0
  47. package/dist/src/commands/recommend.helpers.d.ts.map +1 -0
  48. package/dist/src/commands/recommend.helpers.js +428 -0
  49. package/dist/src/commands/recommend.helpers.js.map +1 -0
  50. package/dist/src/commands/recommend.js +50 -372
  51. package/dist/src/commands/recommend.js.map +1 -1
  52. package/dist/src/commands/recommend.types.d.ts +66 -0
  53. package/dist/src/commands/recommend.types.d.ts.map +1 -0
  54. package/dist/src/commands/recommend.types.js +14 -0
  55. package/dist/src/commands/recommend.types.js.map +1 -0
  56. package/dist/src/commands/search.d.ts.map +1 -1
  57. package/dist/src/commands/search.js +133 -18
  58. package/dist/src/commands/search.js.map +1 -1
  59. package/dist/src/commands/sync.d.ts.map +1 -1
  60. package/dist/src/commands/sync.js +6 -46
  61. package/dist/src/commands/sync.js.map +1 -1
  62. package/dist/src/config.d.ts +5 -0
  63. package/dist/src/config.d.ts.map +1 -1
  64. package/dist/src/config.js +7 -0
  65. package/dist/src/config.js.map +1 -1
  66. package/dist/src/import.d.ts +1 -0
  67. package/dist/src/import.d.ts.map +1 -1
  68. package/dist/src/import.js +20 -5
  69. package/dist/src/import.js.map +1 -1
  70. package/dist/src/index.d.ts +1 -0
  71. package/dist/src/index.d.ts.map +1 -1
  72. package/dist/src/index.js +11 -1
  73. package/dist/src/index.js.map +1 -1
  74. package/dist/src/utils/formatters.d.ts +39 -0
  75. package/dist/src/utils/formatters.d.ts.map +1 -0
  76. package/dist/src/utils/formatters.js +69 -0
  77. package/dist/src/utils/formatters.js.map +1 -0
  78. package/dist/src/utils/license.test.js +6 -1
  79. package/dist/src/utils/license.test.js.map +1 -1
  80. package/dist/src/utils/node-version.d.ts +41 -0
  81. package/dist/src/utils/node-version.d.ts.map +1 -0
  82. package/dist/src/utils/node-version.js +123 -0
  83. package/dist/src/utils/node-version.js.map +1 -0
  84. package/dist/tests/author.test.js +45 -45
  85. package/dist/tests/author.test.js.map +1 -1
  86. package/dist/tests/e2e/search.e2e.test.js +62 -6
  87. package/dist/tests/e2e/search.e2e.test.js.map +1 -1
  88. package/dist/tests/e2e/utils/hardcoded-detector.d.ts.map +1 -1
  89. package/dist/tests/e2e/utils/hardcoded-detector.js +44 -3
  90. package/dist/tests/e2e/utils/hardcoded-detector.js.map +1 -1
  91. package/dist/tests/install-skill.test.d.ts +8 -0
  92. package/dist/tests/install-skill.test.d.ts.map +1 -0
  93. package/dist/tests/install-skill.test.js +409 -0
  94. package/dist/tests/install-skill.test.js.map +1 -0
  95. package/dist/tests/manage.test.js +284 -8
  96. package/dist/tests/manage.test.js.map +1 -1
  97. package/dist/tests/node-version.test.d.ts +8 -0
  98. package/dist/tests/node-version.test.d.ts.map +1 -0
  99. package/dist/tests/node-version.test.js +200 -0
  100. package/dist/tests/node-version.test.js.map +1 -0
  101. package/dist/tests/recommend.test.js +94 -0
  102. package/dist/tests/recommend.test.js.map +1 -1
  103. package/package.json +3 -2
  104. package/dist/src/commands/author.d.ts +0 -90
  105. package/dist/src/commands/author.d.ts.map +0 -1
  106. package/dist/src/commands/author.js +0 -902
  107. package/dist/src/commands/author.js.map +0 -1
@@ -0,0 +1,183 @@
1
+ /**
2
+ * SMI-1433: MCP Server Scaffolding
3
+ *
4
+ * Initialize new MCP server projects with proper structure.
5
+ */
6
+ import { Command } from 'commander';
7
+ import { input, confirm } from '@inquirer/prompts';
8
+ import chalk from 'chalk';
9
+ import ora from 'ora';
10
+ import { mkdir, writeFile, stat } from 'fs/promises';
11
+ import { dirname, join, resolve } from 'path';
12
+ import { renderMcpServerTemplates } from '../../templates/index.js';
13
+ import { sanitizeError } from '../../utils/sanitize.js';
14
+ /**
15
+ * SMI-1433: Initialize a new MCP server project
16
+ */
17
+ export async function initMcpServer(name, options) {
18
+ // Interactive prompts if name not provided
19
+ const serverName = name ||
20
+ (await input({
21
+ message: 'MCP server name:',
22
+ validate: (value) => {
23
+ if (!value.trim())
24
+ return 'Name is required';
25
+ if (!/^[a-z][a-z0-9-]*$/.test(value)) {
26
+ return 'Name must be lowercase, start with a letter, and contain only letters, numbers, and hyphens';
27
+ }
28
+ return true;
29
+ },
30
+ }));
31
+ const description = await input({
32
+ message: 'Description:',
33
+ default: `An MCP server for ${serverName}`,
34
+ });
35
+ const author = await input({
36
+ message: 'Author:',
37
+ default: process.env['USER'] || 'author',
38
+ });
39
+ // Parse initial tools if provided
40
+ const initialTools = [];
41
+ const toolNameRegex = /^[a-z][a-z0-9_-]*$/;
42
+ if (options.tools) {
43
+ const toolNames = options.tools
44
+ .split(',')
45
+ .map((t) => t.trim())
46
+ .filter((t) => t.length > 0);
47
+ for (const toolName of toolNames) {
48
+ if (!toolNameRegex.test(toolName)) {
49
+ console.log(chalk.red(`Invalid tool name: ${toolName}. Must be lowercase, start with a letter, and contain only letters, numbers, underscores, and hyphens.`));
50
+ return;
51
+ }
52
+ initialTools.push({
53
+ name: toolName,
54
+ description: `${toolName} tool`,
55
+ parameters: [],
56
+ });
57
+ }
58
+ }
59
+ // Ask about tools if none specified
60
+ if (initialTools.length === 0) {
61
+ const addTools = await confirm({
62
+ message: 'Would you like to define initial tools interactively?',
63
+ default: false,
64
+ });
65
+ if (addTools) {
66
+ let addMore = true;
67
+ while (addMore) {
68
+ const toolName = await input({
69
+ message: 'Tool name:',
70
+ validate: (value) => {
71
+ if (!value.trim())
72
+ return 'Tool name is required';
73
+ if (!/^[a-z][a-z0-9_-]*$/.test(value)) {
74
+ return 'Tool name must be lowercase with letters, numbers, underscores, and hyphens';
75
+ }
76
+ return true;
77
+ },
78
+ });
79
+ const toolDescription = await input({
80
+ message: 'Tool description:',
81
+ default: `${toolName} tool`,
82
+ });
83
+ initialTools.push({
84
+ name: toolName,
85
+ description: toolDescription,
86
+ parameters: [],
87
+ });
88
+ addMore = await confirm({
89
+ message: 'Add another tool?',
90
+ default: false,
91
+ });
92
+ }
93
+ }
94
+ }
95
+ const targetDir = options.output ? resolve(options.output) : resolve('.', serverName);
96
+ // Check if directory already exists
97
+ try {
98
+ await stat(targetDir);
99
+ if (!options.force) {
100
+ const overwrite = await confirm({
101
+ message: `Directory ${targetDir} already exists. Overwrite?`,
102
+ default: false,
103
+ });
104
+ if (!overwrite) {
105
+ console.log(chalk.yellow('Initialization cancelled'));
106
+ return;
107
+ }
108
+ }
109
+ }
110
+ catch {
111
+ // Directory doesn't exist, continue
112
+ }
113
+ const spinner = ora('Creating MCP server...').start();
114
+ try {
115
+ // Generate templates
116
+ const files = renderMcpServerTemplates({
117
+ name: serverName,
118
+ description,
119
+ tools: initialTools,
120
+ author,
121
+ });
122
+ // Create directory structure
123
+ await mkdir(targetDir, { recursive: true });
124
+ await mkdir(join(targetDir, 'src'), { recursive: true });
125
+ await mkdir(join(targetDir, 'src', 'tools'), { recursive: true });
126
+ // Write all files
127
+ for (const [filePath, content] of files) {
128
+ const fullPath = join(targetDir, filePath);
129
+ const dir = dirname(fullPath);
130
+ await mkdir(dir, { recursive: true });
131
+ await writeFile(fullPath, content, 'utf-8');
132
+ }
133
+ spinner.succeed(`Created MCP server at ${targetDir}`);
134
+ console.log(chalk.bold('\nNext steps:'));
135
+ console.log(chalk.dim(` 1. cd ${targetDir}`));
136
+ console.log(chalk.dim(' 2. npm install'));
137
+ console.log(chalk.dim(' 3. npm run dev # Run in development mode'));
138
+ console.log(chalk.dim(' 4. Edit src/tools/ to add your tool implementations'));
139
+ console.log();
140
+ console.log(chalk.bold('Configure in Claude Code:'));
141
+ console.log(chalk.cyan('─'.repeat(50)));
142
+ console.log(chalk.dim(`Add to ~/.claude/settings.json:`));
143
+ console.log(chalk.white(`{
144
+ "mcpServers": {
145
+ "${serverName}": {
146
+ "command": "npx",
147
+ "args": ["tsx", "${join(targetDir, 'src', 'index.ts')}"]
148
+ }
149
+ }
150
+ }`));
151
+ console.log(chalk.cyan('─'.repeat(50)));
152
+ console.log();
153
+ }
154
+ catch (error) {
155
+ spinner.fail(`Failed to create MCP server: ${sanitizeError(error)}`);
156
+ throw error;
157
+ }
158
+ }
159
+ /**
160
+ * Create mcp-init command
161
+ */
162
+ export function createMcpInitCommand() {
163
+ return new Command('mcp-init')
164
+ .description('Scaffold a new MCP server project')
165
+ .argument('[name]', 'MCP server name')
166
+ .option('-o, --output <path>', 'Output directory')
167
+ .option('--tools <tools>', 'Initial tools (comma-separated)')
168
+ .option('--force', 'Overwrite existing directory')
169
+ .action(async (name, opts) => {
170
+ try {
171
+ await initMcpServer(name, {
172
+ output: opts['output'],
173
+ tools: opts['tools'],
174
+ force: opts['force'],
175
+ });
176
+ }
177
+ catch (error) {
178
+ console.error(chalk.red('Error creating MCP server:'), sanitizeError(error));
179
+ process.exit(1);
180
+ }
181
+ });
182
+ }
183
+ //# sourceMappingURL=mcp-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-init.js","sourceRoot":"","sources":["../../../../src/commands/author/mcp-init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * SMI-1389: Subagent Generation Command
3
+ *
4
+ * Generate companion subagent definitions for skills.
5
+ */
6
+ import { Command } from 'commander';
7
+ export interface SubagentOptions {
8
+ output?: string | undefined;
9
+ tools?: string | undefined;
10
+ model?: string | undefined;
11
+ skipClaudeMd?: boolean | undefined;
12
+ force?: boolean | undefined;
13
+ }
14
+ /**
15
+ * SMI-1389: Generate a companion subagent for a skill
16
+ */
17
+ export declare function generateSubagent(skillPath: string, options: SubagentOptions): Promise<void>;
18
+ /**
19
+ * Create subagent command
20
+ */
21
+ export declare function createSubagentCommand(): Command;
22
+ //# sourceMappingURL=subagent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent.d.ts","sourceRoot":"","sources":["../../../../src/commands/author/subagent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAuBnC,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAClC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC5B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAsIjG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAuB/C"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * SMI-1389: Subagent Generation Command
3
+ *
4
+ * Generate companion subagent definitions for skills.
5
+ */
6
+ import { Command } from 'commander';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import { readFile, writeFile, stat } from 'fs/promises';
10
+ import { dirname, join, resolve } from 'path';
11
+ import { SkillParser } from '@skillsmith/core';
12
+ import { renderSubagentTemplate, renderClaudeMdSnippet } from '../../templates/index.js';
13
+ import { sanitizeError } from '../../utils/sanitize.js';
14
+ import { analyzeToolRequirements, formatToolList, parseToolsString, validateTools, } from '../../utils/tool-analyzer.js';
15
+ import { printValidationResult, fileExists, ensureAgentsDirectory, extractTriggerPhrases, validateSubagentDefinition, } from './utils.js';
16
+ /**
17
+ * SMI-1389: Generate a companion subagent for a skill
18
+ */
19
+ export async function generateSubagent(skillPath, options) {
20
+ const spinner = ora('Generating subagent...').start();
21
+ try {
22
+ // Resolve skill path
23
+ let dirPath = resolve(skillPath || '.');
24
+ let skillMdPath;
25
+ // Check if it's a directory or file
26
+ try {
27
+ const stats = await stat(dirPath);
28
+ if (stats.isDirectory()) {
29
+ skillMdPath = join(dirPath, 'SKILL.md');
30
+ }
31
+ else {
32
+ skillMdPath = dirPath;
33
+ dirPath = dirname(dirPath);
34
+ }
35
+ }
36
+ catch {
37
+ // Try adding SKILL.md
38
+ skillMdPath = dirPath.endsWith('.md') ? dirPath : join(dirPath, 'SKILL.md');
39
+ }
40
+ // Read and parse SKILL.md
41
+ spinner.text = 'Reading SKILL.md...';
42
+ const content = await readFile(skillMdPath, 'utf-8');
43
+ const parser = new SkillParser({ requireName: true });
44
+ const { validation, metadata } = parser.parseWithValidation(content);
45
+ if (!validation.valid || !metadata) {
46
+ spinner.fail('SKILL.md validation failed');
47
+ printValidationResult(validation, skillMdPath);
48
+ return;
49
+ }
50
+ // Analyze tool requirements
51
+ spinner.text = 'Analyzing tool requirements...';
52
+ const toolAnalysis = analyzeToolRequirements(content);
53
+ // Override tools if specified
54
+ let tools = toolAnalysis.requiredTools;
55
+ if (options.tools) {
56
+ const customTools = parseToolsString(options.tools);
57
+ const toolValidation = validateTools(customTools);
58
+ if (!toolValidation.valid) {
59
+ spinner.fail(`Unrecognized tools: ${toolValidation.unrecognized.join(', ')}`);
60
+ return;
61
+ }
62
+ tools = customTools;
63
+ }
64
+ // Extract trigger phrases
65
+ const triggerPhrases = extractTriggerPhrases(metadata.description || '');
66
+ // Determine model
67
+ const model = options.model || 'sonnet';
68
+ if (!['sonnet', 'opus', 'haiku'].includes(model)) {
69
+ spinner.fail(`Invalid model: ${model}. Must be sonnet, opus, or haiku.`);
70
+ return;
71
+ }
72
+ // Generate subagent content
73
+ spinner.text = 'Generating subagent definition...';
74
+ const subagentContent = renderSubagentTemplate({
75
+ skillName: metadata.name,
76
+ description: metadata.description || `Specialist for ${metadata.name}`,
77
+ triggerPhrases,
78
+ tools,
79
+ model,
80
+ });
81
+ // Validate generated content
82
+ const subagentValidation = validateSubagentDefinition(subagentContent);
83
+ if (!subagentValidation.valid) {
84
+ spinner.fail('Generated subagent is invalid');
85
+ console.log(chalk.red('\nGeneration errors:'));
86
+ for (const error of subagentValidation.errors) {
87
+ console.log(chalk.red(` - ${error}`));
88
+ }
89
+ return;
90
+ }
91
+ // Ensure agents directory exists
92
+ const agentsDir = await ensureAgentsDirectory(options.output);
93
+ const subagentPath = join(agentsDir, `${metadata.name}-specialist.md`);
94
+ // Check if subagent already exists
95
+ if (await fileExists(subagentPath)) {
96
+ if (!options.force) {
97
+ spinner.warn(`Subagent already exists: ${subagentPath}`);
98
+ console.log(chalk.yellow(' Use --force to overwrite'));
99
+ return;
100
+ }
101
+ }
102
+ // Write subagent file
103
+ await writeFile(subagentPath, subagentContent, 'utf-8');
104
+ spinner.succeed(`Generated subagent: ${subagentPath}`);
105
+ // Show tool analysis
106
+ console.log(chalk.bold('\nTool Analysis:'));
107
+ console.log(chalk.dim(` Model: ${model}`));
108
+ console.log(chalk.dim(` Confidence: ${toolAnalysis.confidence}`));
109
+ console.log(chalk.dim(` Tools: ${formatToolList(tools)}`));
110
+ if (toolAnalysis.detectedPatterns.length > 0) {
111
+ console.log(chalk.dim(' Detected patterns:'));
112
+ for (const pattern of toolAnalysis.detectedPatterns.slice(0, 5)) {
113
+ console.log(chalk.dim(` - ${pattern}`));
114
+ }
115
+ }
116
+ // Generate and display CLAUDE.md snippet
117
+ if (!options.skipClaudeMd) {
118
+ const snippet = renderClaudeMdSnippet({
119
+ skillName: metadata.name,
120
+ description: metadata.description || '',
121
+ triggerPhrases,
122
+ tools,
123
+ model,
124
+ });
125
+ console.log(chalk.bold('\nCLAUDE.md Integration Snippet:'));
126
+ console.log(chalk.cyan('─'.repeat(50)));
127
+ console.log(snippet);
128
+ console.log(chalk.cyan('─'.repeat(50)));
129
+ console.log(chalk.dim('\nAdd this snippet to your project CLAUDE.md to enable delegation.'));
130
+ }
131
+ console.log();
132
+ }
133
+ catch (error) {
134
+ spinner.fail(`Failed to generate subagent: ${sanitizeError(error)}`);
135
+ throw error;
136
+ }
137
+ }
138
+ /**
139
+ * Create subagent command
140
+ */
141
+ export function createSubagentCommand() {
142
+ return new Command('subagent')
143
+ .description('Generate a companion subagent for a skill')
144
+ .argument('[path]', 'Path to skill directory', '.')
145
+ .option('-o, --output <path>', 'Output directory', '~/.claude/agents')
146
+ .option('--tools <tools>', 'Override detected tools (comma-separated)')
147
+ .option('--model <model>', 'Model for subagent: sonnet|opus|haiku', 'sonnet')
148
+ .option('--skip-claude-md', 'Skip CLAUDE.md snippet generation')
149
+ .option('--force', 'Overwrite existing subagent definition')
150
+ .action(async (skillPath, opts) => {
151
+ try {
152
+ await generateSubagent(skillPath, {
153
+ output: opts['output'],
154
+ tools: opts['tools'],
155
+ model: opts['model'],
156
+ skipClaudeMd: opts['skipClaudeMd'],
157
+ force: opts['force'],
158
+ });
159
+ }
160
+ catch (error) {
161
+ console.error(chalk.red('Error generating subagent:'), sanitizeError(error));
162
+ process.exit(1);
163
+ }
164
+ });
165
+ }
166
+ //# sourceMappingURL=subagent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent.js","sourceRoot":"","sources":["../../../../src/commands/author/subagent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AACxF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,8BAA8B,CAAA;AACrC,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,YAAY,CAAA;AAUnB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,SAAiB,EAAE,OAAwB;IAChF,MAAM,OAAO,GAAG,GAAG,CAAC,wBAAwB,CAAC,CAAC,KAAK,EAAE,CAAA;IAErD,IAAI,CAAC;QACH,qBAAqB;QACrB,IAAI,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC,CAAA;QACvC,IAAI,WAAmB,CAAA;QAEvB,oCAAoC;QACpC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAA;YACjC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;YACzC,CAAC;iBAAM,CAAC;gBACN,WAAW,GAAG,OAAO,CAAA;gBACrB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;YAC5B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;YACtB,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;QAC7E,CAAC;QAED,0BAA0B;QAC1B,OAAO,CAAC,IAAI,GAAG,qBAAqB,CAAA;QACpC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QAEpD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;QACrD,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAA;QAEpE,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;YAC1C,qBAAqB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;YAC9C,OAAM;QACR,CAAC;QAED,4BAA4B;QAC5B,OAAO,CAAC,IAAI,GAAG,gCAAgC,CAAA;QAC/C,MAAM,YAAY,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAA;QAErD,8BAA8B;QAC9B,IAAI,KAAK,GAAG,YAAY,CAAC,aAAa,CAAA;QACtC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACnD,MAAM,cAAc,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;YACjD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;gBAC1B,OAAO,CAAC,IAAI,CAAC,uBAAuB,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;gBAC7E,OAAM;YACR,CAAC;YACD,KAAK,GAAG,WAAW,CAAA;QACrB,CAAC;QAED,0BAA0B;QAC1B,MAAM,cAAc,GAAG,qBAAqB,CAAC,QAAQ,CAAC,WAAW,IAAI,EAAE,CAAC,CAAA;QAExE,kBAAkB;QAClB,MAAM,KAAK,GAAI,OAAO,CAAC,KAAqC,IAAI,QAAQ,CAAA;QACxE,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,kBAAkB,KAAK,mCAAmC,CAAC,CAAA;YACxE,OAAM;QACR,CAAC;QAED,4BAA4B;QAC5B,OAAO,CAAC,IAAI,GAAG,mCAAmC,CAAA;QAClD,MAAM,eAAe,GAAG,sBAAsB,CAAC;YAC7C,SAAS,EAAE,QAAQ,CAAC,IAAI;YACxB,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,kBAAkB,QAAQ,CAAC,IAAI,EAAE;YACtE,cAAc;YACd,KAAK;YACL,KAAK;SACN,CAAC,CAAA;QAEF,6BAA6B;QAC7B,MAAM,kBAAkB,GAAG,0BAA0B,CAAC,eAAe,CAAC,CAAA;QACtE,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAA;YAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAA;YAC9C,KAAK,MAAM,KAAK,IAAI,kBAAkB,CAAC,MAAM,EAAE,CAAC;gBAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAA;YACxC,CAAC;YACD,OAAM;QACR,CAAC;QAED,iCAAiC;QACjC,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAA;QAEtE,mCAAmC;QACnC,IAAI,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,4BAA4B,YAAY,EAAE,CAAC,CAAA;gBACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAA;gBACvD,OAAM;YACR,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,MAAM,SAAS,CAAC,YAAY,EAAE,eAAe,EAAE,OAAO,CAAC,CAAA;QAEvD,OAAO,CAAC,OAAO,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAA;QAEtD,qBAAqB;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAA;QAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC,CAAA;QAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,YAAY,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;QAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAC3D,IAAI,YAAY,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAA;YAC9C,KAAK,MAAM,OAAO,IAAI,YAAY,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBAChE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,OAAO,EAAE,CAAC,CAAC,CAAA;YAC5C,CAAC;QACH,CAAC;QAED,yCAAyC;QACzC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,qBAAqB,CAAC;gBACpC,SAAS,EAAE,QAAQ,CAAC,IAAI;gBACxB,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,EAAE;gBACvC,cAAc;gBACd,KAAK;gBACL,KAAK;aACN,CAAC,CAAA;YAEF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAA;YAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACvC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC,CAAA;QAC9F,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAA;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,gCAAgC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACpE,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;SAC3B,WAAW,CAAC,2CAA2C,CAAC;SACxD,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,EAAE,GAAG,CAAC;SAClD,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,EAAE,kBAAkB,CAAC;SACrE,MAAM,CAAC,iBAAiB,EAAE,2CAA2C,CAAC;SACtE,MAAM,CAAC,iBAAiB,EAAE,uCAAuC,EAAE,QAAQ,CAAC;SAC5E,MAAM,CAAC,kBAAkB,EAAE,mCAAmC,CAAC;SAC/D,MAAM,CAAC,SAAS,EAAE,wCAAwC,CAAC;SAC3D,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,IAAkD,EAAE,EAAE;QACtF,IAAI,CAAC;YACH,MAAM,gBAAgB,CAAC,SAAS,EAAE;gBAChC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAuB;gBAC5C,KAAK,EAAE,IAAI,CAAC,OAAO,CAAuB;gBAC1C,KAAK,EAAE,IAAI,CAAC,OAAO,CAAuB;gBAC1C,YAAY,EAAE,IAAI,CAAC,cAAc,CAAwB;gBACzD,KAAK,EAAE,IAAI,CAAC,OAAO,CAAwB;aAC5C,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;YAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * SMI-1390: Transform Command
3
+ *
4
+ * Upgrade existing skills by generating subagent configurations.
5
+ */
6
+ import { Command } from 'commander';
7
+ export interface TransformOptions {
8
+ dryRun?: boolean | undefined;
9
+ force?: boolean | undefined;
10
+ batch?: boolean | undefined;
11
+ tools?: string | undefined;
12
+ model?: string | undefined;
13
+ }
14
+ /**
15
+ * SMI-1390: Transform existing skill by generating subagent (non-destructive)
16
+ */
17
+ export declare function transformSkill(skillPath: string, options: TransformOptions): Promise<void>;
18
+ /**
19
+ * Create transform command
20
+ */
21
+ export declare function createTransformCommand(): Command;
22
+ //# sourceMappingURL=transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../../src/commands/author/transform.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAanC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6GhG;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAuBhD"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * SMI-1390: Transform Command
3
+ *
4
+ * Upgrade existing skills by generating subagent configurations.
5
+ */
6
+ import { Command } from 'commander';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import { readFile, readdir } from 'fs/promises';
10
+ import { join, resolve } from 'path';
11
+ import { homedir } from 'os';
12
+ import { SkillParser } from '@skillsmith/core';
13
+ import { sanitizeError } from '../../utils/sanitize.js';
14
+ import { analyzeToolRequirements, formatToolList } from '../../utils/tool-analyzer.js';
15
+ import { printValidationResult, fileExists } from './utils.js';
16
+ import { generateSubagent } from './subagent.js';
17
+ /**
18
+ * SMI-1390: Transform existing skill by generating subagent (non-destructive)
19
+ */
20
+ export async function transformSkill(skillPath, options) {
21
+ const spinner = ora('Transforming skill...').start();
22
+ try {
23
+ const dirPath = resolve(skillPath || '.');
24
+ // Check if batch mode
25
+ if (options.batch) {
26
+ spinner.text = 'Processing batch...';
27
+ let skillDirs = [];
28
+ // Support comma-separated paths
29
+ if (dirPath.includes(',')) {
30
+ skillDirs = dirPath.split(',').map((p) => resolve(p.trim()));
31
+ }
32
+ else {
33
+ // It's a directory, scan for subdirectories with SKILL.md
34
+ const subdirs = await readdir(dirPath, { withFileTypes: true });
35
+ for (const entry of subdirs) {
36
+ if (entry.isDirectory()) {
37
+ const skillMdPath = join(dirPath, entry.name, 'SKILL.md');
38
+ if (await fileExists(skillMdPath)) {
39
+ skillDirs.push(join(dirPath, entry.name));
40
+ }
41
+ }
42
+ }
43
+ }
44
+ if (skillDirs.length === 0) {
45
+ spinner.warn('No skills found');
46
+ return;
47
+ }
48
+ spinner.succeed(`Batch processing ${skillDirs.length} skills`);
49
+ // Also output to stdout for test assertions (spinner goes to stderr)
50
+ console.log(chalk.green(`Batch processing ${skillDirs.length} skills`));
51
+ // Process each skill
52
+ for (const skillDir of skillDirs) {
53
+ console.log(chalk.dim(`\nProcessing: ${skillDir}`));
54
+ await transformSkill(skillDir, {
55
+ ...options,
56
+ batch: false, // Don't recurse
57
+ });
58
+ }
59
+ return;
60
+ }
61
+ // Single skill transform
62
+ const skillMdPath = join(dirPath, 'SKILL.md');
63
+ if (!(await fileExists(skillMdPath))) {
64
+ spinner.fail(`No SKILL.md found at: ${skillMdPath}`);
65
+ throw new Error(`No SKILL.md found at: ${skillMdPath}`);
66
+ }
67
+ // Read and parse
68
+ spinner.text = 'Reading SKILL.md...';
69
+ const content = await readFile(skillMdPath, 'utf-8');
70
+ const parser = new SkillParser({ requireName: true });
71
+ const { validation, metadata } = parser.parseWithValidation(content);
72
+ if (!validation.valid || !metadata) {
73
+ spinner.fail('SKILL.md validation failed');
74
+ printValidationResult(validation, skillMdPath);
75
+ return;
76
+ }
77
+ // Check if subagent already exists
78
+ const agentsDir = join(homedir(), '.claude', 'agents');
79
+ const subagentPath = join(agentsDir, `${metadata.name}-specialist.md`);
80
+ if (await fileExists(subagentPath)) {
81
+ if (!options.force) {
82
+ spinner.warn(`Subagent already exists: ${subagentPath}`);
83
+ console.log(chalk.yellow(' Use --force to overwrite'));
84
+ return;
85
+ }
86
+ }
87
+ if (options.dryRun) {
88
+ spinner.succeed('Dry run - would generate:');
89
+ // Also output to stdout for test assertions (spinner goes to stderr)
90
+ console.log(chalk.green('Dry run - would generate:'));
91
+ console.log(chalk.dim(` Subagent: ${subagentPath}`));
92
+ console.log(chalk.dim(` Skill: ${metadata.name}`));
93
+ // Show tool analysis
94
+ const toolAnalysis = analyzeToolRequirements(content);
95
+ console.log(chalk.dim(` Required Tools: ${formatToolList(toolAnalysis.requiredTools)}`));
96
+ console.log(chalk.dim(` Confidence: ${toolAnalysis.confidence}`));
97
+ return;
98
+ }
99
+ spinner.stop();
100
+ // Generate subagent using existing function
101
+ await generateSubagent(dirPath, {
102
+ force: options.force,
103
+ tools: options.tools,
104
+ model: options.model,
105
+ skipClaudeMd: false,
106
+ });
107
+ }
108
+ catch (error) {
109
+ spinner.fail(`Failed to transform skill: ${sanitizeError(error)}`);
110
+ throw error;
111
+ }
112
+ }
113
+ /**
114
+ * Create transform command
115
+ */
116
+ export function createTransformCommand() {
117
+ return new Command('transform')
118
+ .description('Upgrade existing skill with subagent configuration')
119
+ .argument('[path]', 'Path to skill directory', '.')
120
+ .option('--dry-run', 'Preview what would be generated')
121
+ .option('--force', 'Overwrite existing subagent')
122
+ .option('--batch', 'Process directory of skills')
123
+ .option('--tools <tools>', 'Override detected tools (comma-separated)')
124
+ .option('--model <model>', 'Model for subagent: sonnet|opus|haiku', 'sonnet')
125
+ .action(async (skillPath, opts) => {
126
+ try {
127
+ await transformSkill(skillPath, {
128
+ dryRun: opts['dryRun'],
129
+ force: opts['force'],
130
+ batch: opts['batch'],
131
+ tools: opts['tools'],
132
+ model: opts['model'],
133
+ });
134
+ }
135
+ catch (error) {
136
+ console.error(chalk.red('Error transforming skill:'), sanitizeError(error));
137
+ process.exit(1);
138
+ }
139
+ });
140
+ }
141
+ //# sourceMappingURL=transform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../../src/commands/author/transform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * SMI-1487: Shared utilities for author commands
3
+ *
4
+ * Common helper functions used across multiple author subcommands.
5
+ */
6
+ import type { ValidationResult } from '@skillsmith/core';
7
+ /**
8
+ * Pretty print validation errors and warnings
9
+ */
10
+ export declare function printValidationResult(result: ValidationResult, filePath: string): void;
11
+ /**
12
+ * Check if file exists
13
+ */
14
+ export declare function fileExists(path: string): Promise<boolean>;
15
+ /**
16
+ * Ensure ~/.claude/agents directory exists
17
+ */
18
+ export declare function ensureAgentsDirectory(customPath?: string): Promise<string>;
19
+ /**
20
+ * SMI-1389: Extract trigger phrases from skill description
21
+ */
22
+ export declare function extractTriggerPhrases(description: string): string[];
23
+ /**
24
+ * SMI-1389: Validate subagent definition structure
25
+ */
26
+ export declare function validateSubagentDefinition(content: string): ValidationResult;
27
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/commands/author/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAwBtF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOhF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBnE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAuC5E"}