skillshield 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 (167) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +400 -0
  3. package/dist/channels/discord.d.ts +18 -0
  4. package/dist/channels/discord.d.ts.map +1 -0
  5. package/dist/channels/discord.js +275 -0
  6. package/dist/channels/discord.js.map +1 -0
  7. package/dist/channels/index.d.ts +67 -0
  8. package/dist/channels/index.d.ts.map +1 -0
  9. package/dist/channels/index.js +127 -0
  10. package/dist/channels/index.js.map +1 -0
  11. package/dist/channels/slack.d.ts +20 -0
  12. package/dist/channels/slack.d.ts.map +1 -0
  13. package/dist/channels/slack.js +296 -0
  14. package/dist/channels/slack.js.map +1 -0
  15. package/dist/channels/telegram.d.ts +20 -0
  16. package/dist/channels/telegram.d.ts.map +1 -0
  17. package/dist/channels/telegram.js +223 -0
  18. package/dist/channels/telegram.js.map +1 -0
  19. package/dist/channels/whatsapp.d.ts +25 -0
  20. package/dist/channels/whatsapp.d.ts.map +1 -0
  21. package/dist/channels/whatsapp.js +187 -0
  22. package/dist/channels/whatsapp.js.map +1 -0
  23. package/dist/cli/commands/badge.d.ts +11 -0
  24. package/dist/cli/commands/badge.d.ts.map +1 -0
  25. package/dist/cli/commands/badge.js +98 -0
  26. package/dist/cli/commands/badge.js.map +1 -0
  27. package/dist/cli/commands/config.d.ts +3 -0
  28. package/dist/cli/commands/config.d.ts.map +1 -0
  29. package/dist/cli/commands/config.js +140 -0
  30. package/dist/cli/commands/config.js.map +1 -0
  31. package/dist/cli/commands/deploy.d.ts +3 -0
  32. package/dist/cli/commands/deploy.d.ts.map +1 -0
  33. package/dist/cli/commands/deploy.js +56 -0
  34. package/dist/cli/commands/deploy.js.map +1 -0
  35. package/dist/cli/commands/init.d.ts +3 -0
  36. package/dist/cli/commands/init.d.ts.map +1 -0
  37. package/dist/cli/commands/init.js +99 -0
  38. package/dist/cli/commands/init.js.map +1 -0
  39. package/dist/cli/commands/install.d.ts +3 -0
  40. package/dist/cli/commands/install.d.ts.map +1 -0
  41. package/dist/cli/commands/install.js +90 -0
  42. package/dist/cli/commands/install.js.map +1 -0
  43. package/dist/cli/commands/list.d.ts +3 -0
  44. package/dist/cli/commands/list.d.ts.map +1 -0
  45. package/dist/cli/commands/list.js +76 -0
  46. package/dist/cli/commands/list.js.map +1 -0
  47. package/dist/cli/commands/run.d.ts +3 -0
  48. package/dist/cli/commands/run.d.ts.map +1 -0
  49. package/dist/cli/commands/run.js +160 -0
  50. package/dist/cli/commands/run.js.map +1 -0
  51. package/dist/cli/commands/scan.d.ts +3 -0
  52. package/dist/cli/commands/scan.d.ts.map +1 -0
  53. package/dist/cli/commands/scan.js +133 -0
  54. package/dist/cli/commands/scan.js.map +1 -0
  55. package/dist/cli/commands/search.d.ts +3 -0
  56. package/dist/cli/commands/search.d.ts.map +1 -0
  57. package/dist/cli/commands/search.js +56 -0
  58. package/dist/cli/commands/search.js.map +1 -0
  59. package/dist/cli/index.d.ts +3 -0
  60. package/dist/cli/index.d.ts.map +1 -0
  61. package/dist/cli/index.js +70 -0
  62. package/dist/cli/index.js.map +1 -0
  63. package/dist/core/config.d.ts +167 -0
  64. package/dist/core/config.d.ts.map +1 -0
  65. package/dist/core/config.js +398 -0
  66. package/dist/core/config.js.map +1 -0
  67. package/dist/core/parser.d.ts +34 -0
  68. package/dist/core/parser.d.ts.map +1 -0
  69. package/dist/core/parser.js +462 -0
  70. package/dist/core/parser.js.map +1 -0
  71. package/dist/core/runtime.d.ts +68 -0
  72. package/dist/core/runtime.d.ts.map +1 -0
  73. package/dist/core/runtime.js +560 -0
  74. package/dist/core/runtime.js.map +1 -0
  75. package/dist/core/types.d.ts +525 -0
  76. package/dist/core/types.d.ts.map +1 -0
  77. package/dist/core/types.js +44 -0
  78. package/dist/core/types.js.map +1 -0
  79. package/dist/guard/index.d.ts +57 -0
  80. package/dist/guard/index.d.ts.map +1 -0
  81. package/dist/guard/index.js +238 -0
  82. package/dist/guard/index.js.map +1 -0
  83. package/dist/guard/patterns.d.ts +21 -0
  84. package/dist/guard/patterns.d.ts.map +1 -0
  85. package/dist/guard/patterns.js +797 -0
  86. package/dist/guard/patterns.js.map +1 -0
  87. package/dist/hub/index.d.ts +44 -0
  88. package/dist/hub/index.d.ts.map +1 -0
  89. package/dist/hub/index.js +144 -0
  90. package/dist/hub/index.js.map +1 -0
  91. package/dist/hub/registry.d.ts +52 -0
  92. package/dist/hub/registry.d.ts.map +1 -0
  93. package/dist/hub/registry.js +192 -0
  94. package/dist/hub/registry.js.map +1 -0
  95. package/dist/i18n/index.d.ts +19 -0
  96. package/dist/i18n/index.d.ts.map +1 -0
  97. package/dist/i18n/index.js +92 -0
  98. package/dist/i18n/index.js.map +1 -0
  99. package/dist/i18n/locales/en.d.ts +110 -0
  100. package/dist/i18n/locales/en.d.ts.map +1 -0
  101. package/dist/i18n/locales/en.js +123 -0
  102. package/dist/i18n/locales/en.js.map +1 -0
  103. package/dist/i18n/locales/es.d.ts +110 -0
  104. package/dist/i18n/locales/es.d.ts.map +1 -0
  105. package/dist/i18n/locales/es.js +123 -0
  106. package/dist/i18n/locales/es.js.map +1 -0
  107. package/dist/i18n/locales/pt.d.ts +110 -0
  108. package/dist/i18n/locales/pt.d.ts.map +1 -0
  109. package/dist/i18n/locales/pt.js +123 -0
  110. package/dist/i18n/locales/pt.js.map +1 -0
  111. package/dist/i18n/locales/zh.d.ts +110 -0
  112. package/dist/i18n/locales/zh.d.ts.map +1 -0
  113. package/dist/i18n/locales/zh.js +123 -0
  114. package/dist/i18n/locales/zh.js.map +1 -0
  115. package/dist/index.d.ts +168 -0
  116. package/dist/index.d.ts.map +1 -0
  117. package/dist/index.js +275 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/router/index.d.ts +89 -0
  120. package/dist/router/index.d.ts.map +1 -0
  121. package/dist/router/index.js +292 -0
  122. package/dist/router/index.js.map +1 -0
  123. package/dist/router/providers.d.ts +48 -0
  124. package/dist/router/providers.d.ts.map +1 -0
  125. package/dist/router/providers.js +733 -0
  126. package/dist/router/providers.js.map +1 -0
  127. package/dist/runtime/executor.d.ts +96 -0
  128. package/dist/runtime/executor.d.ts.map +1 -0
  129. package/dist/runtime/executor.js +389 -0
  130. package/dist/runtime/executor.js.map +1 -0
  131. package/dist/sandbox/index.d.ts +52 -0
  132. package/dist/sandbox/index.d.ts.map +1 -0
  133. package/dist/sandbox/index.js +248 -0
  134. package/dist/sandbox/index.js.map +1 -0
  135. package/dist/security/skillguard.d.ts +25 -0
  136. package/dist/security/skillguard.d.ts.map +1 -0
  137. package/dist/security/skillguard.js +137 -0
  138. package/dist/security/skillguard.js.map +1 -0
  139. package/dist/tools/index.d.ts +55 -0
  140. package/dist/tools/index.d.ts.map +1 -0
  141. package/dist/tools/index.js +276 -0
  142. package/dist/tools/index.js.map +1 -0
  143. package/dist/tools/web-engine.d.ts +158 -0
  144. package/dist/tools/web-engine.d.ts.map +1 -0
  145. package/dist/tools/web-engine.js +802 -0
  146. package/dist/tools/web-engine.js.map +1 -0
  147. package/dist/tools/web-tools.d.ts +173 -0
  148. package/dist/tools/web-tools.d.ts.map +1 -0
  149. package/dist/tools/web-tools.js +251 -0
  150. package/dist/tools/web-tools.js.map +1 -0
  151. package/dist/utils/errors.d.ts +44 -0
  152. package/dist/utils/errors.d.ts.map +1 -0
  153. package/dist/utils/errors.js +130 -0
  154. package/dist/utils/errors.js.map +1 -0
  155. package/dist/utils/logger.d.ts +28 -0
  156. package/dist/utils/logger.d.ts.map +1 -0
  157. package/dist/utils/logger.js +121 -0
  158. package/dist/utils/logger.js.map +1 -0
  159. package/examples/basic-usage.ts +276 -0
  160. package/examples/code-reviewer.skill.md +83 -0
  161. package/examples/creative-writer.skill.md +80 -0
  162. package/examples/data-analyzer.skill.md +61 -0
  163. package/examples/hello-world.skill.md +36 -0
  164. package/examples/sample-skill.md +156 -0
  165. package/examples/summarizer.skill.md +62 -0
  166. package/examples/translator.skill.md +45 -0
  167. package/package.json +110 -0
@@ -0,0 +1,99 @@
1
+ import chalk from 'chalk';
2
+ import * as fs from 'fs/promises';
3
+ import inquirer from 'inquirer';
4
+ import ora from 'ora';
5
+ import { homedir } from 'os';
6
+ import { resolve } from 'path';
7
+ import { t } from '../../i18n/index.js';
8
+ export function init(program) {
9
+ program
10
+ .command('init')
11
+ .description(chalk.cyan('Initialize SkillKit in your project'))
12
+ .option('--yes', 'Use default values without prompting')
13
+ .action(async (options) => {
14
+ try {
15
+ console.log(chalk.cyan.bold('\n✨ SkillKit Setup Wizard\n'));
16
+ const config = {
17
+ language: 'en',
18
+ provider: 'anthropic',
19
+ model: 'claude-3-5-sonnet',
20
+ apiKey: '',
21
+ registryUrl: 'https://clawhub.ai',
22
+ };
23
+ if (options.yes) {
24
+ // Use defaults
25
+ config.apiKey = process.env.SKILLKIT_API_KEY || '';
26
+ }
27
+ else {
28
+ // Interactive prompts
29
+ const answers = await inquirer.prompt([
30
+ {
31
+ type: 'list',
32
+ name: 'language',
33
+ message: t('init.language'),
34
+ choices: [
35
+ { name: 'English', value: 'en' },
36
+ { name: 'EspaƱol', value: 'es' },
37
+ { name: 'äø­ę–‡', value: 'zh' },
38
+ { name: 'PortuguĆŖs', value: 'pt' },
39
+ ],
40
+ default: 'en',
41
+ },
42
+ {
43
+ type: 'list',
44
+ name: 'provider',
45
+ message: t('init.provider'),
46
+ choices: [
47
+ { name: 'Anthropic (Claude)', value: 'anthropic' },
48
+ { name: 'OpenAI (GPT)', value: 'openai' },
49
+ { name: 'Groq', value: 'groq' },
50
+ ],
51
+ default: 'anthropic',
52
+ },
53
+ {
54
+ type: 'input',
55
+ name: 'apiKey',
56
+ message: t('init.apiKey'),
57
+ mask: '*',
58
+ validate: (input) => input.length > 0 || t('init.apiKeyRequired'),
59
+ },
60
+ ]);
61
+ Object.assign(config, answers);
62
+ }
63
+ // Create ~/.skillkit/
64
+ const spinner = ora(t('init.creating')).start();
65
+ const globalConfigDir = resolve(homedir(), '.skillkit');
66
+ const projectConfigDir = resolve(process.cwd(), '.skillkit');
67
+ await fs.mkdir(globalConfigDir, { recursive: true });
68
+ await fs.mkdir(projectConfigDir, { recursive: true });
69
+ // Write global config
70
+ const globalConfigPath = resolve(globalConfigDir, 'config.json');
71
+ await fs.writeFile(globalConfigPath, JSON.stringify(config, null, 2));
72
+ // Write project config
73
+ const projectConfig = {
74
+ language: config.language,
75
+ provider: config.provider,
76
+ model: config.model,
77
+ };
78
+ const projectConfigPath = resolve(projectConfigDir, 'config.json');
79
+ await fs.writeFile(projectConfigPath, JSON.stringify(projectConfig, null, 2));
80
+ // Create skills directory
81
+ await fs.mkdir(resolve(projectConfigDir, 'skills'), { recursive: true });
82
+ // Create .gitignore
83
+ const gitignorePath = resolve(projectConfigDir, '.gitignore');
84
+ await fs.writeFile(gitignorePath, 'config.json\n.env\n');
85
+ spinner.succeed(chalk.green(t('init.success')));
86
+ console.log(chalk.bold.cyan('\nšŸ“‹ Next Steps:\n'));
87
+ console.log(chalk.gray(` 1. ${t('init.nextSteps1')}`));
88
+ console.log(chalk.gray(` 2. ${t('init.nextSteps2')}`));
89
+ console.log(chalk.gray(` 3. ${t('init.nextSteps3')}`));
90
+ console.log(chalk.gray(` 4. ${t('init.nextSteps4')}`));
91
+ console.log(chalk.gray('\n For help: skillkit --help\n'));
92
+ }
93
+ catch (error) {
94
+ console.error(chalk.red(t('error.initFailed')), error);
95
+ process.exit(1);
96
+ }
97
+ });
98
+ }
99
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function install(program: Command): void;
3
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/install.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,QA+FvC"}
@@ -0,0 +1,90 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { t } from '../../i18n/index.js';
4
+ import { fetchSkill } from '../../hub/index.js';
5
+ import { installSkill as registryInstall } from '../../hub/registry.js';
6
+ import { scanSkill } from '../../runtime/executor.js';
7
+ export function install(program) {
8
+ program
9
+ .command('install <skillRef>')
10
+ .description(chalk.cyan('Install a skill from ClawHub or URL'))
11
+ .option('--force', 'Skip security confirmation')
12
+ .option('--json', 'Output as JSON')
13
+ .action(async (skillRef, options) => {
14
+ try {
15
+ const spinner = ora(t('install.fetching')).start();
16
+ // Fetch skill
17
+ let skillContent;
18
+ let skillName;
19
+ if (skillRef.startsWith('http')) {
20
+ // From URL
21
+ const response = await fetch(skillRef);
22
+ if (!response.ok)
23
+ throw new Error(`HTTP ${response.status}`);
24
+ skillContent = await response.text();
25
+ skillName = new URL(skillRef).pathname.split('/').pop() || 'skill';
26
+ }
27
+ else {
28
+ // From ClawHub
29
+ const result = await fetchSkill(skillRef);
30
+ skillContent = result.content;
31
+ skillName = result.name;
32
+ }
33
+ spinner.succeed(chalk.green(t('install.fetched')));
34
+ // Security scan
35
+ let safeToInstall = true;
36
+ if (!options.force) {
37
+ const scanSpinner = ora(t('install.scanning')).start();
38
+ try {
39
+ const scanResult = await scanSkill(skillContent);
40
+ scanSpinner.succeed();
41
+ if (scanResult.score < 80) {
42
+ console.log(chalk.yellow(`\nāš ļø Security Issues Found (Score: ${Math.round(scanResult.score)}%)\n`));
43
+ scanResult.threats.slice(0, 5).forEach((threat) => {
44
+ const severityColor = threat.severity === 'critical'
45
+ ? chalk.red
46
+ : threat.severity === 'high'
47
+ ? chalk.yellow
48
+ : chalk.blue;
49
+ console.log(` ${severityColor(`[${threat.severity.toUpperCase()}]`)} ${threat.description}`);
50
+ });
51
+ if (scanResult.threats.length > 5) {
52
+ console.log(chalk.gray(` ... and ${scanResult.threats.length - 5} more\n`));
53
+ }
54
+ // Prompt user
55
+ safeToInstall = await new Promise((resolve) => {
56
+ process.stdout.write(chalk.yellow('\nInstall anyway? (yes/no): '));
57
+ process.stdin.once('data', (data) => {
58
+ resolve(data.toString().trim().toLowerCase() === 'yes');
59
+ });
60
+ });
61
+ }
62
+ }
63
+ catch (error) {
64
+ scanSpinner.warn(chalk.yellow(t('install.scanWarning')));
65
+ }
66
+ }
67
+ if (!safeToInstall) {
68
+ console.log(chalk.gray(t('install.cancelled')));
69
+ process.exit(0);
70
+ }
71
+ // Install to local registry
72
+ const installSpinner = ora(t('install.installing')).start();
73
+ const installed = await registryInstall(skillName, skillContent, {
74
+ source: skillRef.startsWith('http') ? skillRef : 'clawhub',
75
+ });
76
+ installSpinner.succeed(chalk.green(`āœ“ ${t('install.installed')}: ${chalk.cyan(installed.name)}`));
77
+ console.log(chalk.dim(`\nšŸ“ Location: ${installed.path}`));
78
+ console.log(chalk.dim(`šŸ“… Installed: ${new Date(installed.installedAt).toLocaleString()}\n`));
79
+ console.log(chalk.dim(`šŸ’” Run with: skillkit run ${skillName}\n`));
80
+ if (options.json) {
81
+ console.log(JSON.stringify(installed, null, 2));
82
+ }
83
+ }
84
+ catch (error) {
85
+ console.error(chalk.red(t('error.installFailed')), error);
86
+ process.exit(1);
87
+ }
88
+ });
89
+ }
90
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/cli/commands/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function list(program: Command): void;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,IAAI,CAAC,OAAO,EAAE,OAAO,QAyFpC"}
@@ -0,0 +1,76 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { t } from '../../i18n/index.js';
4
+ import { listInstalled } from '../../hub/registry.js';
5
+ export function list(program) {
6
+ program
7
+ .command('list')
8
+ .description(chalk.cyan('List installed skills'))
9
+ .option('--json', 'Output as JSON')
10
+ .option('-V, --verbose', 'Show detailed information')
11
+ .action(async (options) => {
12
+ try {
13
+ const spinner = ora(t('list.loading')).start();
14
+ const skills = await listInstalled();
15
+ spinner.stop();
16
+ if (skills.length === 0) {
17
+ console.log(chalk.yellow(`\n${t('list.noSkills')}\n`));
18
+ console.log(chalk.dim('Install your first skill with: skillkit install <skill-name>\n'));
19
+ return;
20
+ }
21
+ console.log(chalk.cyan.bold(`\nšŸ“š Installed Skills (${skills.length})\n`));
22
+ if (options.verbose) {
23
+ // Detailed view
24
+ skills.forEach((skill) => {
25
+ console.log(chalk.bold(skill.name));
26
+ console.log(chalk.gray(` Path: ${skill.path}`));
27
+ console.log(chalk.gray(` Installed: ${new Date(skill.installedAt).toLocaleDateString()}`));
28
+ console.log(chalk.gray(` Source: ${skill.source}`));
29
+ if (skill.securityScore !== undefined) {
30
+ const scoreColor = skill.securityScore >= 80
31
+ ? chalk.green
32
+ : skill.securityScore >= 50
33
+ ? chalk.yellow
34
+ : chalk.red;
35
+ console.log(chalk.gray(` Security: ${scoreColor(Math.round(skill.securityScore) + '%')}`));
36
+ }
37
+ if (skill.usageCount) {
38
+ console.log(chalk.gray(` Uses: ${skill.usageCount}`));
39
+ }
40
+ console.log();
41
+ });
42
+ }
43
+ else {
44
+ // Table view
45
+ console.log(chalk.gray('ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n' +
46
+ '│ Name │ Security │ Last Used │\n' +
47
+ 'ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤'));
48
+ skills.forEach((skill) => {
49
+ const scoreColor = skill.securityScore !== undefined && skill.securityScore >= 80
50
+ ? chalk.green
51
+ : skill.securityScore !== undefined && skill.securityScore >= 50
52
+ ? chalk.yellow
53
+ : chalk.red;
54
+ const scoreBadge = skill.securityScore !== undefined
55
+ ? scoreColor(Math.round(skill.securityScore) + '%')
56
+ : chalk.gray('-');
57
+ const lastUsed = skill.lastUsedAt
58
+ ? new Date(skill.lastUsedAt).toLocaleDateString()
59
+ : '-';
60
+ const name = (skill.name || 'unknown').slice(0, 22).padEnd(22);
61
+ const score = String(scoreBadge).padEnd(8);
62
+ console.log(`│ ${name} │ ${score} │ ${lastUsed.padEnd(20)} │`);
63
+ });
64
+ console.log(chalk.gray('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n'));
65
+ }
66
+ if (options.json) {
67
+ console.log(JSON.stringify(skills, null, 2));
68
+ }
69
+ }
70
+ catch (error) {
71
+ console.error(chalk.red(t('error.listFailed')), error);
72
+ process.exit(1);
73
+ }
74
+ });
75
+ }
76
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function run(program: Command): void;
3
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,QAmKnC"}
@@ -0,0 +1,160 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { t } from '../../i18n/index.js';
4
+ import { scanSkill } from '../../runtime/executor.js';
5
+ import { loadSkill, executeSkill } from '../../runtime/executor.js';
6
+ export function run(program) {
7
+ program
8
+ .command('run <skill>')
9
+ .description(chalk.cyan('Execute a skill with any AI model'))
10
+ .option('--model <model>', 'Model to use (e.g., deepseek-chat, ollama/qwen2.5, gpt-4o)')
11
+ .option('--provider <provider>', 'Force provider (openai, anthropic, deepseek, qwen, ollama, groq)')
12
+ .option('--input <prompt>', 'Input prompt for the skill')
13
+ .option('--no-scan', 'Skip security scan')
14
+ .option('--stream', 'Stream output token by token')
15
+ .option('--channel <type>', 'Run via messaging channel (whatsapp, telegram, discord, slack)')
16
+ .option('--json', 'Output as JSON')
17
+ .option('-V, --verbose', 'Verbose output')
18
+ .action(async (skill, cmdOptions, cmd) => {
19
+ try {
20
+ // Merge subcommand options with parent (global) options
21
+ const parentOpts = cmd.parent?.opts?.() || {};
22
+ const options = { ...parentOpts, ...cmdOptions };
23
+ // Step 1: Security scan (unless --no-scan)
24
+ if (options.noScan !== false) {
25
+ const scanSpinner = ora(t('run.scanning') || 'Scanning for threats...').start();
26
+ try {
27
+ // Load skill first to scan its content
28
+ const content = await loadSkill(skill);
29
+ const scanResult = await scanSkill(content);
30
+ if (scanResult.status === 'BLOCKED') {
31
+ scanSpinner.fail(chalk.red('BLOCKED — Malicious skill detected'));
32
+ console.log(chalk.red(`\n SkillGuard Score: ${scanResult.score}/100`));
33
+ if (scanResult.hash) {
34
+ console.log(chalk.red(` Hash: ${scanResult.hash.slice(0, 16)}...`));
35
+ }
36
+ for (const threat of scanResult.threats) {
37
+ console.log(chalk.red(` [${threat.severity.toUpperCase()}] ${threat.description}`));
38
+ }
39
+ console.log(chalk.yellow('\nThis skill has been blocked for safety. Use --no-scan to override (NOT recommended).'));
40
+ console.log(chalk.gray('This hash has been added to your local blocklist to protect you in the future.'));
41
+ process.exit(1);
42
+ }
43
+ if (scanResult.status === 'REVIEW_REQUIRED') {
44
+ scanSpinner.warn(chalk.yellow(`Security: ${scanResult.score}/100 — review recommended`));
45
+ for (const threat of scanResult.threats) {
46
+ const color = threat.severity === 'CRITICAL' ? chalk.red
47
+ : threat.severity === 'HIGH' ? chalk.yellow
48
+ : chalk.blue;
49
+ console.log(` ${color(`[${threat.severity}]`)} ${threat.description}`);
50
+ }
51
+ if (scanResult.sandboxRecommended) {
52
+ console.log(chalk.cyan('\n TIP: This skill has suspicious patterns. Consider running with --sandbox:'));
53
+ console.log(chalk.cyan(' skillkit run ' + skill + ' --sandbox'));
54
+ }
55
+ if (!options.json) {
56
+ const answer = await new Promise((resolve) => {
57
+ process.stdout.write(chalk.yellow('\nContinue anyway? (yes/no): '));
58
+ process.stdin.once('data', (data) => {
59
+ resolve(data.toString().trim().toLowerCase() === 'yes');
60
+ });
61
+ });
62
+ if (!answer) {
63
+ console.log(chalk.gray('Cancelled'));
64
+ process.exit(0);
65
+ }
66
+ }
67
+ }
68
+ else {
69
+ scanSpinner.succeed(chalk.green(`Security: ${scanResult.score}/100 — safe`));
70
+ }
71
+ }
72
+ catch (error) {
73
+ scanSpinner.warn(chalk.yellow('Security scan skipped (could not read skill)'));
74
+ }
75
+ }
76
+ // Step 2: Load skill
77
+ const loadSpinner = ora(t('run.loading') || 'Loading skill...').start();
78
+ const skillContent = await loadSkill(skill);
79
+ loadSpinner.succeed(chalk.green('Skill loaded'));
80
+ // Step 3: Show execution context
81
+ const modelDisplay = options.model || 'auto-detect';
82
+ const providerDisplay = options.provider || 'auto-detect';
83
+ console.log(chalk.dim(`\n Model: ${modelDisplay}`));
84
+ console.log(chalk.dim(` Provider: ${providerDisplay}`));
85
+ if (options.input) {
86
+ console.log(chalk.dim(` Input: "${options.input.slice(0, 80)}${options.input.length > 80 ? '...' : ''}"`));
87
+ }
88
+ // Step 4: Execute with REAL AI
89
+ const execSpinner = options.stream ? null : ora(t('run.executing') || 'Executing skill...').start();
90
+ if (options.stream) {
91
+ console.log(chalk.cyan.bold('\nšŸ“¤ Output:\n'));
92
+ }
93
+ const startTime = Date.now();
94
+ try {
95
+ const result = await executeSkill({
96
+ content: skillContent,
97
+ input: options.input || '',
98
+ model: options.model,
99
+ provider: options.provider,
100
+ channel: options.channel,
101
+ verbose: options.verbose,
102
+ stream: options.stream,
103
+ });
104
+ if (execSpinner) {
105
+ execSpinner.succeed(chalk.green(t('run.complete') || 'Execution complete'));
106
+ }
107
+ // Show output (non-streaming mode)
108
+ if (!options.stream) {
109
+ console.log(chalk.cyan.bold('\nšŸ“¤ Output:\n'));
110
+ console.log(result.output);
111
+ }
112
+ else {
113
+ console.log(''); // newline after streamed output
114
+ }
115
+ // Show stats
116
+ const elapsed = (Date.now() - startTime) / 1000;
117
+ console.log(chalk.dim(`\nā±ļø Time: ${elapsed.toFixed(2)}s`));
118
+ console.log(chalk.dim(`šŸ¤– Model: ${result.provider}/${result.model}`));
119
+ if (result.tokenUsage) {
120
+ console.log(chalk.dim(`šŸ“Š Tokens: ${result.tokenUsage.input} in / ${result.tokenUsage.output} out`));
121
+ }
122
+ // JSON output
123
+ if (options.json) {
124
+ console.log(JSON.stringify({
125
+ success: true,
126
+ output: result.output,
127
+ model: result.model,
128
+ provider: result.provider,
129
+ tokenUsage: result.tokenUsage,
130
+ duration: result.duration,
131
+ }, null, 2));
132
+ }
133
+ }
134
+ catch (error) {
135
+ if (execSpinner)
136
+ execSpinner.fail(chalk.red(t('run.failed') || 'Execution failed'));
137
+ const msg = error instanceof Error ? error.message : String(error);
138
+ // Helpful error messages
139
+ if (msg.includes('API key')) {
140
+ console.error(chalk.red(`\nāœ— ${msg}`));
141
+ console.log(chalk.yellow('\nTip: Set your API key with:'));
142
+ console.log(chalk.cyan(' export DEEPSEEK_API_KEY=your-key # Free: deepseek.com'));
143
+ console.log(chalk.cyan(' export GROQ_API_KEY=your-key # Free: groq.com'));
144
+ console.log(chalk.cyan(' export ANTHROPIC_API_KEY=your-key # Paid: anthropic.com'));
145
+ console.log(chalk.yellow('\nOr use a free local model:'));
146
+ console.log(chalk.cyan(' skillkit run my-skill.md --model ollama/qwen2.5'));
147
+ }
148
+ else {
149
+ console.error(chalk.red(`\nāœ— ${msg}`));
150
+ }
151
+ process.exit(1);
152
+ }
153
+ }
154
+ catch (error) {
155
+ console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
156
+ process.exit(1);
157
+ }
158
+ });
159
+ }
160
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAapE,MAAM,UAAU,GAAG,CAAC,OAAgB;IAClC,OAAO;SACJ,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;SAC5D,MAAM,CAAC,iBAAiB,EAAE,4DAA4D,CAAC;SACvF,MAAM,CAAC,uBAAuB,EAAE,kEAAkE,CAAC;SACnG,MAAM,CAAC,kBAAkB,EAAE,4BAA4B,CAAC;SACxD,MAAM,CAAC,WAAW,EAAE,oBAAoB,CAAC;SACzC,MAAM,CAAC,UAAU,EAAE,8BAA8B,CAAC;SAClD,MAAM,CAAC,kBAAkB,EAAE,gEAAgE,CAAC;SAC5F,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;SAClC,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,UAAsB,EAAE,GAAQ,EAAE,EAAE;QAChE,IAAI,CAAC;YACH,wDAAwD;YACxD,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;YAC9C,MAAM,OAAO,GAAe,EAAE,GAAG,UAAU,EAAE,GAAG,UAAU,EAAE,CAAC;YAC7D,2CAA2C;YAC3C,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBAC7B,MAAM,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,yBAAyB,CAAC,CAAC,KAAK,EAAE,CAAC;gBAChF,IAAI,CAAC;oBACH,uCAAuC;oBACvC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;oBACvC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;oBAE5C,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;wBACpC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC,CAAC;wBAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,UAAU,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;wBACxE,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;4BACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;wBACvE,CAAC;wBACD,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;4BACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;wBACvF,CAAC;wBACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wFAAwF,CAAC,CAAC,CAAC;wBACpH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC,CAAC;wBAC1G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;oBAED,IAAI,UAAU,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;wBAC5C,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,UAAU,CAAC,KAAK,2BAA2B,CAAC,CAAC,CAAC;wBACzF,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;4BACxC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG;gCACtD,CAAC,CAAC,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;oCAC3C,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;4BACf,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;wBAC1E,CAAC;wBAED,IAAI,UAAU,CAAC,kBAAkB,EAAE,CAAC;4BAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAC,CAAC;4BACzG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,GAAG,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC;wBACpE,CAAC;wBAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;4BAClB,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;gCACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC;gCACpE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;oCAClC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;gCAC1D,CAAC,CAAC,CAAC;4BACL,CAAC,CAAC,CAAC;4BACH,IAAI,CAAC,MAAM,EAAE,CAAC;gCACZ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;gCACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;4BAClB,CAAC;wBACH,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,UAAU,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC;oBAC/E,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,8CAA8C,CAAC,CAAC,CAAC;gBACjF,CAAC;YACH,CAAC;YAED,qBAAqB;YACrB,MAAM,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,kBAAkB,CAAC,CAAC,KAAK,EAAE,CAAC;YACxE,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;YAC5C,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;YAEjD,iCAAiC;YACjC,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC;YACpD,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,YAAY,EAAE,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,eAAe,EAAE,CAAC,CAAC,CAAC;YACzD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC9G,CAAC;YAED,+BAA+B;YAC/B,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,oBAAoB,CAAC,CAAC,KAAK,EAAE,CAAC;YAEpG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACjD,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE7B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;oBAChC,OAAO,EAAE,YAAY;oBACrB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;oBAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB,CAAC,CAAC;gBAEH,IAAI,WAAW,EAAE,CAAC;oBAChB,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,oBAAoB,CAAC,CAAC,CAAC;gBAC9E,CAAC;gBAED,mCAAmC;gBACnC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;oBACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,gCAAgC;gBACnD,CAAC;gBAED,aAAa;gBACb,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;gBAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAEvE,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;oBACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,UAAU,CAAC,KAAK,SAAS,MAAM,CAAC,UAAU,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC;gBACvG,CAAC;gBAED,cAAc;gBACd,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;oBACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;wBACzB,OAAO,EAAE,IAAI;wBACb,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,UAAU,EAAE,MAAM,CAAC,UAAU;wBAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;qBAC1B,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBACf,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,WAAW;oBAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC;gBAEpF,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAEnE,yBAAyB;gBACzB,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC5B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;oBACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC;oBAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC,CAAC;oBACvF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC,CAAC;oBACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC,CAAC;oBACxF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,8BAA8B,CAAC,CAAC,CAAC;oBAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC,CAAC;gBAC/E,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;gBACzC,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function scan(program: Command): void;
3
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,IAAI,CAAC,OAAO,EAAE,OAAO,QAgCpC"}
@@ -0,0 +1,133 @@
1
+ import chalk from 'chalk';
2
+ import * as fs from 'fs/promises';
3
+ import ora from 'ora';
4
+ import { resolve } from 'path';
5
+ import { t } from '../../i18n/index.js';
6
+ import { scanSkill } from '../../runtime/executor.js';
7
+ export function scan(program) {
8
+ program
9
+ .command('scan <path>')
10
+ .description(chalk.cyan('Security audit of a skill file or directory'))
11
+ .option('--json', 'Output as JSON')
12
+ .option('--safe-only', 'Only show safe skills')
13
+ .option('-V, --verbose', 'Verbose output')
14
+ .action(async (path, options) => {
15
+ try {
16
+ const fullPath = resolve(process.cwd(), path);
17
+ const spinner = ora(t('scan.scanning')).start();
18
+ // Determine if path is file or directory
19
+ const stat = await fs.stat(fullPath);
20
+ if (stat.isDirectory()) {
21
+ // Scan directory
22
+ await scanDirectory(fullPath, options);
23
+ }
24
+ else if (stat.isFile()) {
25
+ // Scan single file
26
+ const result = await scanSkill(fullPath);
27
+ spinner.stop();
28
+ displayScanResult(result, fullPath, options);
29
+ }
30
+ else {
31
+ spinner.fail(chalk.red(t('error.invalidPath')));
32
+ process.exit(1);
33
+ }
34
+ }
35
+ catch (error) {
36
+ console.error(chalk.red(t('error.scanFailed')), error);
37
+ process.exit(1);
38
+ }
39
+ });
40
+ }
41
+ async function scanDirectory(dir, options) {
42
+ const files = await fs.readdir(dir, { recursive: true });
43
+ const skillFiles = files.filter((f) => typeof f === 'string' && (f.endsWith('.md') || f.endsWith('.skill')));
44
+ if (skillFiles.length === 0) {
45
+ console.log(chalk.yellow(t('scan.noSkillsFound')));
46
+ return;
47
+ }
48
+ console.log(chalk.cyan.bold(`\nšŸ” Scanning ${skillFiles.length} skills...\n`));
49
+ const results = [];
50
+ for (const file of skillFiles) {
51
+ const spinner = ora(`Scanning ${file}`).start();
52
+ try {
53
+ const filePath = resolve(dir, file);
54
+ const result = await scanSkill(filePath);
55
+ if (!options.safeOnly || result.score >= 80) {
56
+ results.push({ file, result });
57
+ }
58
+ spinner.succeed();
59
+ }
60
+ catch (error) {
61
+ spinner.warn(`Failed to scan ${file}`);
62
+ }
63
+ }
64
+ // Display summary table
65
+ console.log(chalk.bold('\nšŸ“Š Scan Results:\n'));
66
+ console.log(chalk.gray('ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n' +
67
+ '│ Skill │ Score │ Threats │\n' +
68
+ 'ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤'));
69
+ results.forEach(({ file, result }) => {
70
+ const scoreColor = result.score >= 80 ? chalk.green : result.score >= 50 ? chalk.yellow : chalk.red;
71
+ const threatCount = result.threats.length;
72
+ const skillName = file.split('/').pop() || file;
73
+ console.log(`│ ${skillName.padEnd(27)} │ ${scoreColor(String(Math.round(result.score)).padEnd(6))} │ ${String(threatCount).padEnd(12)} │`);
74
+ });
75
+ console.log(chalk.gray('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n'));
76
+ if (options.json) {
77
+ console.log(JSON.stringify(results.map(({ file, result }) => ({
78
+ file,
79
+ score: result.score,
80
+ threats: result.threats,
81
+ })), null, 2));
82
+ }
83
+ }
84
+ function displayScanResult(result, filePath, options) {
85
+ const fileName = filePath.split('/').pop() || filePath;
86
+ // Score badge
87
+ const scoreColor = result.score >= 80 ? chalk.bgGreen : result.score >= 50 ? chalk.bgYellow : chalk.bgRed;
88
+ const scoreLabel = result.score >= 80
89
+ ? 'SAFE'
90
+ : result.score >= 50
91
+ ? 'CAUTION'
92
+ : 'UNSAFE';
93
+ console.log(chalk.bold.cyan(`\nšŸ” Security Scan: ${fileName}\n`));
94
+ console.log(` Overall Score: ${scoreColor.black(` ${Math.round(result.score)} `)} (${scoreLabel})\n`);
95
+ // Threats
96
+ if (result.threats.length > 0) {
97
+ console.log(chalk.bold('āš ļø Detected Threats:\n'));
98
+ result.threats.forEach((threat, idx) => {
99
+ const severityColor = threat.severity === 'critical'
100
+ ? chalk.bgRed.white
101
+ : threat.severity === 'high'
102
+ ? chalk.bgYellow.black
103
+ : chalk.bgBlue.white;
104
+ console.log(` ${idx + 1}. ${severityColor(` ${threat.severity.toUpperCase()} `)}`);
105
+ console.log(` Description: ${threat.description}`);
106
+ console.log(` Line: ${threat.line}\n`);
107
+ });
108
+ }
109
+ else {
110
+ console.log(chalk.green('āœ“ No threats detected\n'));
111
+ }
112
+ // Recommendations
113
+ console.log(chalk.bold('šŸ’” Recommendations:\n'));
114
+ if (result.threats.length === 0) {
115
+ console.log(chalk.green(' āœ“ This skill is safe to use'));
116
+ }
117
+ else {
118
+ const critical = result.threats.filter((t) => t.severity === 'critical').length;
119
+ const high = result.threats.filter((t) => t.severity === 'high').length;
120
+ if (critical > 0) {
121
+ console.log(chalk.red(` āœ— Fix ${critical} critical issue(s) before using`));
122
+ }
123
+ if (high > 0) {
124
+ console.log(chalk.yellow(` ⚠ Review ${high} high-severity issue(s)`));
125
+ }
126
+ console.log(' • Run with --no-scan to bypass (not recommended)');
127
+ console.log(' • Contact the skill author for fixes');
128
+ }
129
+ if (options.json) {
130
+ console.log(JSON.stringify(result, null, 2));
131
+ }
132
+ }
133
+ //# sourceMappingURL=scan.js.map