dantelabs-agentic-school 1.0.0 → 1.2.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 (53) hide show
  1. package/.claude-plugin/marketplace.json +11 -53
  2. package/cli/bin/cli.js +31 -8
  3. package/cli/src/commands/info.js +15 -11
  4. package/cli/src/commands/install.js +53 -29
  5. package/cli/src/commands/list.js +28 -22
  6. package/cli/src/commands/uninstall.js +23 -16
  7. package/cli/src/i18n/index.js +96 -0
  8. package/cli/src/i18n/locales/en.js +107 -0
  9. package/cli/src/i18n/locales/ko.js +107 -0
  10. package/cli/src/lib/config.js +116 -1
  11. package/cli/src/lib/installer.js +106 -3
  12. package/package.json +1 -1
  13. package/plugins/brand-analytics/plugin.json +9 -0
  14. package/plugins/campaign-orchestration/plugin.json +9 -0
  15. package/plugins/common/plugin.json +9 -0
  16. package/plugins/common/skills/kie-image-generator/.env.example +4 -0
  17. package/plugins/common/skills/kie-image-generator/SKILL.md +281 -0
  18. package/plugins/common/skills/kie-image-generator/references/api_docs.md +358 -0
  19. package/plugins/common/skills/kie-image-generator/scripts/__pycache__/utils.cpython-313.pyc +0 -0
  20. package/plugins/common/skills/kie-image-generator/scripts/generate_image.py +285 -0
  21. package/plugins/common/skills/kie-image-generator/scripts/models/__init__.py +19 -0
  22. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/__init__.cpython-313.pyc +0 -0
  23. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/flux_kontext.cpython-313.pyc +0 -0
  24. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/gpt4o.cpython-313.pyc +0 -0
  25. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/ideogram.cpython-313.pyc +0 -0
  26. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/imagen.cpython-313.pyc +0 -0
  27. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/nano_banana.cpython-313.pyc +0 -0
  28. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/nano_banana_edit.cpython-313.pyc +0 -0
  29. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/nano_banana_pro.cpython-313.pyc +0 -0
  30. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/seedream.cpython-313.pyc +0 -0
  31. package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/seedream_edit.cpython-313.pyc +0 -0
  32. package/plugins/common/skills/kie-image-generator/scripts/models/flux_kontext.py +36 -0
  33. package/plugins/common/skills/kie-image-generator/scripts/models/gpt4o.py +36 -0
  34. package/plugins/common/skills/kie-image-generator/scripts/models/ideogram.py +85 -0
  35. package/plugins/common/skills/kie-image-generator/scripts/models/imagen.py +48 -0
  36. package/plugins/common/skills/kie-image-generator/scripts/models/nano_banana.py +40 -0
  37. package/plugins/common/skills/kie-image-generator/scripts/models/nano_banana_edit.py +55 -0
  38. package/plugins/common/skills/kie-image-generator/scripts/models/nano_banana_pro.py +47 -0
  39. package/plugins/common/skills/kie-image-generator/scripts/models/seedream.py +51 -0
  40. package/plugins/common/skills/kie-image-generator/scripts/models/seedream_edit.py +66 -0
  41. package/plugins/common/skills/kie-image-generator/scripts/utils.py +706 -0
  42. package/plugins/common/skills/kie-video-generator/SKILL.md +258 -0
  43. package/plugins/common/skills/kie-video-generator/references/api_docs.md +202 -0
  44. package/plugins/common/skills/kie-video-generator/scripts/__pycache__/utils.cpython-313.pyc +0 -0
  45. package/plugins/common/skills/kie-video-generator/scripts/generate_video.py +356 -0
  46. package/plugins/common/skills/kie-video-generator/scripts/models/__init__.py +4 -0
  47. package/plugins/common/skills/kie-video-generator/scripts/utils.py +617 -0
  48. package/plugins/content-creation/plugin.json +9 -0
  49. package/plugins/creative-production/plugin.json +9 -0
  50. package/plugins/customer-segmentation/plugin.json +9 -0
  51. package/plugins/market-research/plugin.json +9 -0
  52. package/plugins/persona-builder/plugin.json +9 -0
  53. package/plugins/social-strategy/plugin.json +9 -0
@@ -14,99 +14,57 @@
14
14
  "plugins": [
15
15
  {
16
16
  "name": "common",
17
- "description": "공통 유틸리티 스킬 모음. 인증 관리, 문서 제작 도구(PPTX, PDF, DOCX) 등 여러 플러그인에서 공통으로 사용하는 기능을 제공합니다.",
17
+ "description": "공통 유틸리티 스킬 모음. 인증 관리, 문서 제작 도구(PPTX, PDF, DOCX), 이미지/비디오 생성(Kie.ai) 등 여러 플러그인에서 공통으로 사용하는 기능을 제공합니다.",
18
18
  "version": "1.0.0",
19
- "path": "plugins/common",
20
- "components": {
21
- "skills": ["auth-manager", "pptx", "pdf", "docx"]
22
- }
19
+ "source": "./plugins/common"
23
20
  },
24
21
  {
25
22
  "name": "brand-analytics",
26
23
  "description": "브랜드 소개서를 분석하여 포지셔닝, SWOT, 경쟁사 분석을 수행합니다.",
27
24
  "version": "1.0.0",
28
- "path": "plugins/brand-analytics",
29
- "components": {
30
- "agents": ["brand-strategist", "competitive-analyst"],
31
- "commands": ["analyze-brand"],
32
- "skills": ["brand-positioning"]
33
- }
25
+ "source": "./plugins/brand-analytics"
34
26
  },
35
27
  {
36
28
  "name": "customer-segmentation",
37
29
  "description": "데이터 기반 고객 세그먼트를 설계하고 정의합니다.",
38
30
  "version": "1.0.0",
39
- "path": "plugins/customer-segmentation",
40
- "components": {
41
- "agents": ["segmentation-architect", "data-analyst"],
42
- "commands": ["create-segments"],
43
- "skills": ["segmentation-framework", "activation-map"]
44
- }
31
+ "source": "./plugins/customer-segmentation"
45
32
  },
46
33
  {
47
34
  "name": "persona-builder",
48
35
  "description": "타겟 세그먼트의 상세 페르소나 카드를 생성합니다.",
49
36
  "version": "1.0.0",
50
- "path": "plugins/persona-builder",
51
- "components": {
52
- "agents": ["persona-architect", "customer-insights-partner"],
53
- "commands": ["build-persona"],
54
- "skills": ["persona-framework"]
55
- }
37
+ "source": "./plugins/persona-builder"
56
38
  },
57
39
  {
58
40
  "name": "social-strategy",
59
41
  "description": "페르소나 기반 채널 선정 및 콘텐츠 전략을 수립합니다.",
60
42
  "version": "1.0.0",
61
- "path": "plugins/social-strategy",
62
- "components": {
63
- "agents": ["social-strategy-director", "channel-analyst"],
64
- "commands": ["plan-channels"],
65
- "skills": ["channel-roadmap", "content-pillars"]
66
- }
43
+ "source": "./plugins/social-strategy"
67
44
  },
68
45
  {
69
46
  "name": "content-creation",
70
47
  "description": "채널별 홍보 카피 및 스크립트를 생성합니다.",
71
48
  "version": "1.0.0",
72
- "path": "plugins/content-creation",
73
- "components": {
74
- "agents": ["copy-strategist", "conversion-copywriter", "script-writer"],
75
- "commands": ["generate-copy", "write-script"],
76
- "skills": ["message-architecture", "hook-formulas"]
77
- }
49
+ "source": "./plugins/content-creation"
78
50
  },
79
51
  {
80
52
  "name": "creative-production",
81
- "description": "실제 이미지와 비디오를 생성합니다. kie-image-generator, kie-video-generator 스킬과 연동됩니다.",
53
+ "description": "실제 이미지와 비디오를 생성합니다. common 플러그인의 kie-image-generator, kie-video-generator 스킬을 활용합니다.",
82
54
  "version": "1.0.0",
83
- "path": "plugins/creative-production",
84
- "components": {
85
- "agents": ["creative-director", "production-coordinator"],
86
- "commands": ["create-image", "create-video"],
87
- "skills": ["image-prompt-guide", "video-production"]
88
- },
89
- "externalSkills": ["kie-image-generator", "kie-video-generator"]
55
+ "source": "./plugins/creative-production"
90
56
  },
91
57
  {
92
58
  "name": "campaign-orchestration",
93
59
  "description": "전체 마케팅 워크플로우를 통합하고 순차 실행합니다.",
94
60
  "version": "1.0.0",
95
- "path": "plugins/campaign-orchestration",
96
- "components": {
97
- "agents": ["campaign-director", "workflow-coordinator"],
98
- "commands": ["run-full-pipeline", "run-phase"],
99
- "skills": ["pipeline-framework"]
100
- }
61
+ "source": "./plugins/campaign-orchestration"
101
62
  },
102
63
  {
103
64
  "name": "market-research",
104
65
  "description": "시장 분석 리포트 및 데이터 시각화를 생성합니다.",
105
66
  "version": "1.0.0",
106
- "path": "plugins/market-research",
107
- "components": {
108
- "skills": ["analysis-reports", "diagram-generator"]
109
- }
67
+ "source": "./plugins/market-research"
110
68
  }
111
69
  ],
112
70
  "categories": [
package/cli/bin/cli.js CHANGED
@@ -6,6 +6,7 @@ import { fileURLToPath } from 'url';
6
6
  import { dirname, join } from 'path';
7
7
  import { readFileSync } from 'fs';
8
8
 
9
+ import { setLocale, t, getAvailableLocales } from '../src/i18n/index.js';
9
10
  import installCommand from '../src/commands/install.js';
10
11
  import listCommand from '../src/commands/list.js';
11
12
  import infoCommand from '../src/commands/info.js';
@@ -19,30 +20,52 @@ const pkg = JSON.parse(
19
20
  readFileSync(join(__dirname, '../../package.json'), 'utf8')
20
21
  );
21
22
 
23
+ // Pre-parse --lang option before commander
24
+ const langIndex = process.argv.findIndex(
25
+ (arg) => arg === '--lang' || arg === '-l'
26
+ );
27
+ if (langIndex !== -1 && process.argv[langIndex + 1]) {
28
+ setLocale(process.argv[langIndex + 1]);
29
+ }
30
+
22
31
  const program = new Command();
23
32
 
24
33
  program
25
34
  .name('dantelabs')
26
- .description('Dante Labs Agentic School - Claude Code Plugin Installer')
35
+ .description(t('cli.description'))
27
36
  .version(pkg.version)
37
+ .option(
38
+ '-l, --lang <locale>',
39
+ `Language (${getAvailableLocales().join(', ')})`,
40
+ 'en'
41
+ )
42
+ .hook('preAction', (thisCommand) => {
43
+ const opts = thisCommand.opts();
44
+ if (opts.lang) {
45
+ setLocale(opts.lang);
46
+ }
47
+ })
28
48
  .addHelpText('after', `
29
- ${chalk.bold('Examples:')}
30
- ${chalk.gray('# Install all plugins')}
49
+ ${chalk.bold(t('cli.examples'))}
50
+ ${chalk.gray(t('cli.installAllPlugins'))}
31
51
  $ npx dantelabs-agentic-school install
32
52
 
33
- ${chalk.gray('# Install specific plugin')}
53
+ ${chalk.gray(t('cli.installSpecificPlugin'))}
34
54
  $ npx dantelabs-agentic-school install brand-analytics
35
55
 
36
- ${chalk.gray('# Install to custom path')}
56
+ ${chalk.gray(t('cli.installCustomPath'))}
37
57
  $ npx dantelabs-agentic-school install --path ./my-project
38
58
 
39
- ${chalk.gray('# List available plugins')}
59
+ ${chalk.gray(t('cli.listPlugins'))}
40
60
  $ npx dantelabs-agentic-school list
41
61
 
42
- ${chalk.gray('# Show plugin info')}
62
+ ${chalk.gray(t('cli.showPluginInfo'))}
43
63
  $ npx dantelabs-agentic-school info brand-analytics
44
64
 
45
- ${chalk.bold('More info:')} https://github.com/dandacompany/dantelabs-agentic-school
65
+ ${chalk.gray('# Korean language')}
66
+ $ npx dantelabs-agentic-school --lang ko list
67
+
68
+ ${chalk.bold(t('cli.moreInfo'))}: https://github.com/dandacompany/dantelabs-agentic-school
46
69
  `);
47
70
 
48
71
  // Register commands
@@ -1,27 +1,31 @@
1
1
  import chalk from 'chalk';
2
- import { getMarketplaceConfig } from '../lib/config.js';
2
+ import { getMarketplaceConfig, enrichPluginWithComponents } from '../lib/config.js';
3
3
  import logger from '../utils/logger.js';
4
+ import { t } from '../i18n/index.js';
4
5
 
5
6
  export default function infoCommand(program) {
6
7
  program
7
8
  .command('info <plugin>')
8
- .description('Show detailed information about a plugin')
9
- .option('--json', 'Output as JSON')
9
+ .description(t('info.description'))
10
+ .option('--json', t('info.optionJson'))
10
11
  .action(async (pluginName, options) => {
11
12
  try {
12
13
  const config = await getMarketplaceConfig();
13
- const plugin = config.plugins.find((p) => p.name === pluginName);
14
+ let plugin = config.plugins.find((p) => p.name === pluginName);
14
15
 
15
16
  if (!plugin) {
16
- logger.error(`Plugin '${pluginName}' not found`);
17
+ logger.error(t('info.pluginNotFound', { name: pluginName }));
17
18
  console.log();
18
- console.log('Available plugins:');
19
+ console.log(`${t('common.availablePlugins')}:`);
19
20
  config.plugins.forEach((p) => {
20
21
  console.log(` - ${chalk.cyan(p.name)}`);
21
22
  });
22
23
  process.exit(1);
23
24
  }
24
25
 
26
+ // Enrich plugin with discovered components
27
+ plugin = await enrichPluginWithComponents(plugin);
28
+
25
29
  if (options.json) {
26
30
  console.log(JSON.stringify(plugin, null, 2));
27
31
  return;
@@ -40,31 +44,31 @@ export default function infoCommand(program) {
40
44
  const components = plugin.components || {};
41
45
 
42
46
  if (components.agents?.length) {
43
- console.log(chalk.bold('Agents:'));
47
+ console.log(chalk.bold(`${t('info.agents')}:`));
44
48
  components.agents.forEach((a) => console.log(` - ${a}`));
45
49
  console.log();
46
50
  }
47
51
 
48
52
  if (components.commands?.length) {
49
- console.log(chalk.bold('Commands:'));
53
+ console.log(chalk.bold(`${t('info.commands')}:`));
50
54
  components.commands.forEach((c) => console.log(` - /${c}`));
51
55
  console.log();
52
56
  }
53
57
 
54
58
  if (components.skills?.length) {
55
- console.log(chalk.bold('Skills:'));
59
+ console.log(chalk.bold(`${t('info.skills')}:`));
56
60
  components.skills.forEach((s) => console.log(` - ${s}`));
57
61
  console.log();
58
62
  }
59
63
 
60
64
  if (plugin.externalSkills?.length) {
61
- console.log(chalk.bold.yellow('External Skills Required:'));
65
+ console.log(chalk.bold.yellow(`${t('info.externalSkillsRequired')}:`));
62
66
  plugin.externalSkills.forEach((s) => console.log(` - ${s}`));
63
67
  console.log();
64
68
  }
65
69
 
66
70
  console.log(
67
- chalk.gray('Install:'),
71
+ chalk.gray(`${t('info.installHint')}:`),
68
72
  `npx dantelabs-agentic-school install ${pluginName}`
69
73
  );
70
74
  } catch (error) {
@@ -9,17 +9,18 @@ import { getMarketplaceConfig, getPluginDependencies } from '../lib/config.js';
9
9
  import { installPlugin } from '../lib/installer.js';
10
10
  import logger from '../utils/logger.js';
11
11
  import { resolvePath } from '../utils/fs-utils.js';
12
+ import { t } from '../i18n/index.js';
12
13
 
13
14
  export default function installCommand(program) {
14
15
  program
15
16
  .command('install [plugin]')
16
17
  .alias('i')
17
- .description('Install plugins to your project')
18
- .option('-p, --path <path>', 'Installation path (default: current directory)')
19
- .option('-f, --force', 'Force overwrite existing files')
20
- .option('--all', 'Install all available plugins')
21
- .option('--no-common', 'Skip common utilities')
22
- .option('--dry-run', 'Show what would be installed without making changes')
18
+ .description(t('install.description'))
19
+ .option('-p, --path <path>', t('install.optionPath'))
20
+ .option('-f, --force', t('install.optionForce'))
21
+ .option('--all', t('install.optionAll'))
22
+ .option('--no-common', t('install.optionNoCommon'))
23
+ .option('--dry-run', t('install.optionDryRun'))
23
24
  .action(async (pluginName, options) => {
24
25
  const spinner = ora();
25
26
 
@@ -30,12 +31,12 @@ export default function installCommand(program) {
30
31
  : process.cwd();
31
32
  const claudeDir = join(targetPath, '.claude');
32
33
 
33
- logger.info(`Installation target: ${chalk.cyan(claudeDir)}`);
34
+ logger.info(`${t('install.installTarget')}: ${chalk.cyan(claudeDir)}`);
34
35
 
35
36
  // Load marketplace config
36
- spinner.start('Loading plugin registry...');
37
+ spinner.start(t('install.loadingRegistry'));
37
38
  const config = await getMarketplaceConfig();
38
- spinner.succeed('Plugin registry loaded');
39
+ spinner.succeed(t('install.registryLoaded'));
39
40
 
40
41
  // Determine which plugins to install
41
42
  let pluginsToInstall = [];
@@ -46,13 +47,15 @@ export default function installCommand(program) {
46
47
  {
47
48
  type: 'confirm',
48
49
  name: 'confirm',
49
- message: `Install all ${config.plugins.length} plugins?`,
50
+ message: t('install.confirmInstallAll', {
51
+ count: config.plugins.length
52
+ }),
50
53
  default: true
51
54
  }
52
55
  ]);
53
56
 
54
57
  if (!confirm) {
55
- logger.info('Installation cancelled');
58
+ logger.info(t('install.installCancelled'));
56
59
  return;
57
60
  }
58
61
 
@@ -62,9 +65,9 @@ export default function installCommand(program) {
62
65
  const plugin = config.plugins.find((p) => p.name === pluginName);
63
66
 
64
67
  if (!plugin) {
65
- logger.error(`Plugin '${pluginName}' not found`);
68
+ logger.error(t('install.pluginNotFound', { name: pluginName }));
66
69
  console.log();
67
- console.log('Available plugins:');
70
+ console.log(`${t('common.availablePlugins')}:`);
68
71
  config.plugins.forEach((p) => {
69
72
  console.log(` - ${chalk.cyan(p.name)}: ${p.description}`);
70
73
  });
@@ -89,7 +92,7 @@ export default function installCommand(program) {
89
92
  // Dry run mode
90
93
  if (options.dryRun) {
91
94
  console.log();
92
- logger.info('Dry run - would install:');
95
+ logger.info(t('install.dryRunTitle'));
93
96
  console.log();
94
97
 
95
98
  for (const plugin of pluginsToInstall) {
@@ -98,23 +101,29 @@ export default function installCommand(program) {
98
101
 
99
102
  if (components.agents?.length) {
100
103
  console.log(
101
- chalk.gray(` Agents: ${components.agents.join(', ')}`)
104
+ chalk.gray(
105
+ ` ${t('common.agents')}: ${components.agents.join(', ')}`
106
+ )
102
107
  );
103
108
  }
104
109
  if (components.commands?.length) {
105
110
  console.log(
106
- chalk.gray(` Commands: /${components.commands.join(', /')}`)
111
+ chalk.gray(
112
+ ` ${t('common.commands')}: /${components.commands.join(', /')}`
113
+ )
107
114
  );
108
115
  }
109
116
  if (components.skills?.length) {
110
117
  console.log(
111
- chalk.gray(` Skills: ${components.skills.join(', ')}`)
118
+ chalk.gray(
119
+ ` ${t('common.skills')}: ${components.skills.join(', ')}`
120
+ )
112
121
  );
113
122
  }
114
123
  console.log();
115
124
  }
116
125
 
117
- console.log(chalk.gray('Run without --dry-run to install.'));
126
+ console.log(chalk.gray(t('install.dryRunFooter')));
118
127
  return;
119
128
  }
120
129
 
@@ -129,13 +138,17 @@ export default function installCommand(program) {
129
138
  let totalSkills = 0;
130
139
 
131
140
  for (const plugin of pluginsToInstall) {
132
- spinner.start(`Installing ${chalk.cyan(plugin.name)}...`);
141
+ spinner.start(t('install.installing', { name: chalk.cyan(plugin.name) }));
133
142
 
134
143
  try {
135
144
  const results = await installPlugin(plugin, claudeDir, {
136
145
  force: options.force,
137
146
  onProgress: (type, name) => {
138
- spinner.text = `Installing ${chalk.cyan(plugin.name)}: ${type} ${name}`;
147
+ spinner.text = t('install.installingComponent', {
148
+ plugin: chalk.cyan(plugin.name),
149
+ type,
150
+ name
151
+ });
139
152
  }
140
153
  });
141
154
 
@@ -143,9 +156,14 @@ export default function installCommand(program) {
143
156
  totalCommands += results.commands;
144
157
  totalSkills += results.skills;
145
158
 
146
- spinner.succeed(`Installed ${chalk.cyan(plugin.name)}`);
159
+ spinner.succeed(t('install.installed', { name: chalk.cyan(plugin.name) }));
147
160
  } catch (err) {
148
- spinner.fail(`Failed to install ${plugin.name}: ${err.message}`);
161
+ spinner.fail(
162
+ t('install.failedToInstall', {
163
+ name: plugin.name,
164
+ error: err.message
165
+ })
166
+ );
149
167
  if (!options.force) {
150
168
  throw err;
151
169
  }
@@ -155,21 +173,25 @@ export default function installCommand(program) {
155
173
  // Summary
156
174
  console.log();
157
175
  logger.success(
158
- `Successfully installed ${pluginsToInstall.length} plugin(s)`
176
+ t('install.successMessage', { count: pluginsToInstall.length })
159
177
  );
160
178
  console.log(
161
179
  chalk.gray(
162
- ` ${totalAgents} agents, ${totalCommands} commands, ${totalSkills} skills`
180
+ ` ${t('install.componentSummary', {
181
+ agents: totalAgents,
182
+ commands: totalCommands,
183
+ skills: totalSkills
184
+ })}`
163
185
  )
164
186
  );
165
187
  console.log();
166
- console.log(`Location: ${chalk.cyan(claudeDir)}`);
188
+ console.log(`${t('common.location')}: ${chalk.cyan(claudeDir)}`);
167
189
 
168
190
  // Show next steps
169
191
  console.log();
170
- console.log(chalk.bold('Next steps:'));
192
+ console.log(chalk.bold(`${t('install.nextSteps')}:`));
171
193
  console.log(
172
- ` 1. Run ${chalk.cyan('claude --help')} to see available commands`
194
+ ` 1. ${t('install.nextStep1', { command: chalk.cyan('claude --help') })}`
173
195
  );
174
196
 
175
197
  // Show example command based on installed plugins
@@ -178,7 +200,9 @@ export default function installCommand(program) {
178
200
  );
179
201
  if (hasAnalyzeBrand) {
180
202
  console.log(
181
- ` 2. Try ${chalk.cyan('/analyze-brand --brand-doc ./your-brand.md')}`
203
+ ` 2. ${t('install.nextStep2', {
204
+ command: chalk.cyan('/analyze-brand --brand-doc ./your-brand.md')
205
+ })}`
182
206
  );
183
207
  }
184
208
 
@@ -189,7 +213,7 @@ export default function installCommand(program) {
189
213
 
190
214
  if (externalSkills.length > 0) {
191
215
  console.log();
192
- console.log(chalk.yellow('External skills required:'));
216
+ console.log(chalk.yellow(`${t('install.externalSkillsRequired')}:`));
193
217
  [...new Set(externalSkills)].forEach((skill) => {
194
218
  console.log(` - ${skill}`);
195
219
  });
@@ -1,29 +1,35 @@
1
1
  import chalk from 'chalk';
2
- import { getMarketplaceConfig } from '../lib/config.js';
2
+ import { getMarketplaceConfig, enrichPluginWithComponents } from '../lib/config.js';
3
3
  import logger from '../utils/logger.js';
4
+ import { t } from '../i18n/index.js';
4
5
 
5
6
  export default function listCommand(program) {
6
7
  program
7
8
  .command('list')
8
9
  .alias('ls')
9
- .description('List all available plugins')
10
- .option('--json', 'Output as JSON')
11
- .option('-v, --verbose', 'Show detailed information')
10
+ .description(t('list.description'))
11
+ .option('--json', t('list.optionJson'))
12
+ .option('-v, --verbose', t('list.optionVerbose'))
12
13
  .action(async (options) => {
13
14
  try {
14
15
  const config = await getMarketplaceConfig();
15
16
 
17
+ // Enrich plugins with discovered components
18
+ const enrichedPlugins = await Promise.all(
19
+ config.plugins.map(p => enrichPluginWithComponents(p))
20
+ );
21
+
16
22
  if (options.json) {
17
- console.log(JSON.stringify(config.plugins, null, 2));
23
+ console.log(JSON.stringify(enrichedPlugins, null, 2));
18
24
  return;
19
25
  }
20
26
 
21
27
  console.log();
22
- console.log(chalk.bold.blue('Dante Labs Agentic School - Available Plugins'));
28
+ console.log(chalk.bold.blue(t('list.title')));
23
29
  console.log(chalk.gray('━'.repeat(60)));
24
30
  console.log();
25
31
 
26
- for (const plugin of config.plugins) {
32
+ for (const plugin of enrichedPlugins) {
27
33
  console.log(
28
34
  chalk.bold.cyan(`${plugin.name}`),
29
35
  chalk.gray(`v${plugin.version}`)
@@ -34,22 +40,22 @@ export default function listCommand(program) {
34
40
  const components = plugin.components || {};
35
41
  if (components.agents?.length) {
36
42
  console.log(
37
- chalk.gray(` Agents: ${components.agents.join(', ')}`)
43
+ chalk.gray(` ${t('common.agents')}: ${components.agents.join(', ')}`)
38
44
  );
39
45
  }
40
46
  if (components.commands?.length) {
41
47
  console.log(
42
- chalk.gray(` Commands: /${components.commands.join(', /')}`)
48
+ chalk.gray(` ${t('common.commands')}: /${components.commands.join(', /')}`)
43
49
  );
44
50
  }
45
51
  if (components.skills?.length) {
46
52
  console.log(
47
- chalk.gray(` Skills: ${components.skills.join(', ')}`)
53
+ chalk.gray(` ${t('common.skills')}: ${components.skills.join(', ')}`)
48
54
  );
49
55
  }
50
56
  if (plugin.externalSkills?.length) {
51
57
  console.log(
52
- chalk.yellow(` External: ${plugin.externalSkills.join(', ')}`)
58
+ chalk.yellow(` ${t('common.external')}: ${plugin.externalSkills.join(', ')}`)
53
59
  );
54
60
  }
55
61
  }
@@ -58,31 +64,31 @@ export default function listCommand(program) {
58
64
  }
59
65
 
60
66
  // Summary
61
- const totalAgents = config.plugins.reduce(
67
+ const totalAgents = enrichedPlugins.reduce(
62
68
  (sum, p) => sum + (p.components?.agents?.length || 0),
63
69
  0
64
70
  );
65
- const totalCommands = config.plugins.reduce(
71
+ const totalCommands = enrichedPlugins.reduce(
66
72
  (sum, p) => sum + (p.components?.commands?.length || 0),
67
73
  0
68
74
  );
69
- const totalSkills = config.plugins.reduce(
75
+ const totalSkills = enrichedPlugins.reduce(
70
76
  (sum, p) => sum + (p.components?.skills?.length || 0),
71
77
  0
72
78
  );
73
79
 
74
80
  console.log(chalk.gray('━'.repeat(60)));
75
81
  console.log(
76
- chalk.bold('Summary:'),
77
- `${config.plugins.length} plugins,`,
78
- `${totalAgents} agents,`,
79
- `${totalCommands} commands,`,
80
- `${totalSkills} skills`
82
+ chalk.bold(`${t('common.summary')}:`),
83
+ t('list.summaryText', {
84
+ plugins: enrichedPlugins.length,
85
+ agents: totalAgents,
86
+ commands: totalCommands,
87
+ skills: totalSkills
88
+ })
81
89
  );
82
90
  console.log();
83
- console.log(
84
- chalk.gray(`Install: npx dantelabs-agentic-school install [plugin-name]`)
85
- );
91
+ console.log(chalk.gray(t('list.installHint')));
86
92
  } catch (error) {
87
93
  logger.error(error.message);
88
94
  process.exit(1);