dantelabs-agentic-school 1.0.0 → 1.1.1
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.
- package/.claude-plugin/marketplace.json +4 -5
- package/cli/bin/cli.js +31 -8
- package/cli/src/commands/info.js +10 -9
- package/cli/src/commands/install.js +53 -29
- package/cli/src/commands/list.js +17 -16
- package/cli/src/commands/uninstall.js +23 -16
- package/cli/src/i18n/index.js +96 -0
- package/cli/src/i18n/locales/en.js +107 -0
- package/cli/src/i18n/locales/ko.js +107 -0
- package/package.json +1 -1
- package/plugins/common/skills/kie-image-generator/.env.example +4 -0
- package/plugins/common/skills/kie-image-generator/SKILL.md +281 -0
- package/plugins/common/skills/kie-image-generator/references/api_docs.md +358 -0
- package/plugins/common/skills/kie-image-generator/scripts/__pycache__/utils.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/generate_image.py +285 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__init__.py +19 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/__init__.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/flux_kontext.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/gpt4o.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/ideogram.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/imagen.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/nano_banana.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/nano_banana_edit.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/nano_banana_pro.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/seedream.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/seedream_edit.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/flux_kontext.py +36 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/gpt4o.py +36 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/ideogram.py +85 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/imagen.py +48 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/nano_banana.py +40 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/nano_banana_edit.py +55 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/nano_banana_pro.py +47 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/seedream.py +51 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/seedream_edit.py +66 -0
- package/plugins/common/skills/kie-image-generator/scripts/utils.py +706 -0
- package/plugins/common/skills/kie-video-generator/SKILL.md +258 -0
- package/plugins/common/skills/kie-video-generator/references/api_docs.md +202 -0
- package/plugins/common/skills/kie-video-generator/scripts/__pycache__/utils.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-video-generator/scripts/generate_video.py +356 -0
- package/plugins/common/skills/kie-video-generator/scripts/models/__init__.py +4 -0
- package/plugins/common/skills/kie-video-generator/scripts/utils.py +617 -0
|
@@ -14,11 +14,11 @@
|
|
|
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
19
|
"path": "plugins/common",
|
|
20
20
|
"components": {
|
|
21
|
-
"skills": ["auth-manager", "pptx", "pdf", "docx"]
|
|
21
|
+
"skills": ["auth-manager", "pptx", "pdf", "docx", "kie-image-generator", "kie-video-generator"]
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
{
|
|
@@ -78,15 +78,14 @@
|
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
"name": "creative-production",
|
|
81
|
-
"description": "실제 이미지와 비디오를 생성합니다. kie-image-generator, kie-video-generator
|
|
81
|
+
"description": "실제 이미지와 비디오를 생성합니다. common 플러그인의 kie-image-generator, kie-video-generator 스킬을 활용합니다.",
|
|
82
82
|
"version": "1.0.0",
|
|
83
83
|
"path": "plugins/creative-production",
|
|
84
84
|
"components": {
|
|
85
85
|
"agents": ["creative-director", "production-coordinator"],
|
|
86
86
|
"commands": ["create-image", "create-video"],
|
|
87
87
|
"skills": ["image-prompt-guide", "video-production"]
|
|
88
|
-
}
|
|
89
|
-
"externalSkills": ["kie-image-generator", "kie-video-generator"]
|
|
88
|
+
}
|
|
90
89
|
},
|
|
91
90
|
{
|
|
92
91
|
"name": "campaign-orchestration",
|
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('
|
|
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('
|
|
30
|
-
${chalk.gray('
|
|
49
|
+
${chalk.bold(t('cli.examples'))}
|
|
50
|
+
${chalk.gray(t('cli.installAllPlugins'))}
|
|
31
51
|
$ npx dantelabs-agentic-school install
|
|
32
52
|
|
|
33
|
-
${chalk.gray('
|
|
53
|
+
${chalk.gray(t('cli.installSpecificPlugin'))}
|
|
34
54
|
$ npx dantelabs-agentic-school install brand-analytics
|
|
35
55
|
|
|
36
|
-
${chalk.gray('
|
|
56
|
+
${chalk.gray(t('cli.installCustomPath'))}
|
|
37
57
|
$ npx dantelabs-agentic-school install --path ./my-project
|
|
38
58
|
|
|
39
|
-
${chalk.gray('
|
|
59
|
+
${chalk.gray(t('cli.listPlugins'))}
|
|
40
60
|
$ npx dantelabs-agentic-school list
|
|
41
61
|
|
|
42
|
-
${chalk.gray('
|
|
62
|
+
${chalk.gray(t('cli.showPluginInfo'))}
|
|
43
63
|
$ npx dantelabs-agentic-school info brand-analytics
|
|
44
64
|
|
|
45
|
-
${chalk.
|
|
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
|
package/cli/src/commands/info.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { getMarketplaceConfig } 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('
|
|
9
|
-
.option('--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
14
|
const plugin = config.plugins.find((p) => p.name === pluginName);
|
|
14
15
|
|
|
15
16
|
if (!plugin) {
|
|
16
|
-
logger.error(
|
|
17
|
+
logger.error(t('info.pluginNotFound', { name: pluginName }));
|
|
17
18
|
console.log();
|
|
18
|
-
console.log('
|
|
19
|
+
console.log(`${t('common.availablePlugins')}:`);
|
|
19
20
|
config.plugins.forEach((p) => {
|
|
20
21
|
console.log(` - ${chalk.cyan(p.name)}`);
|
|
21
22
|
});
|
|
@@ -40,31 +41,31 @@ export default function infoCommand(program) {
|
|
|
40
41
|
const components = plugin.components || {};
|
|
41
42
|
|
|
42
43
|
if (components.agents?.length) {
|
|
43
|
-
console.log(chalk.bold('
|
|
44
|
+
console.log(chalk.bold(`${t('info.agents')}:`));
|
|
44
45
|
components.agents.forEach((a) => console.log(` - ${a}`));
|
|
45
46
|
console.log();
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
if (components.commands?.length) {
|
|
49
|
-
console.log(chalk.bold('
|
|
50
|
+
console.log(chalk.bold(`${t('info.commands')}:`));
|
|
50
51
|
components.commands.forEach((c) => console.log(` - /${c}`));
|
|
51
52
|
console.log();
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
if (components.skills?.length) {
|
|
55
|
-
console.log(chalk.bold('
|
|
56
|
+
console.log(chalk.bold(`${t('info.skills')}:`));
|
|
56
57
|
components.skills.forEach((s) => console.log(` - ${s}`));
|
|
57
58
|
console.log();
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
if (plugin.externalSkills?.length) {
|
|
61
|
-
console.log(chalk.bold.yellow('
|
|
62
|
+
console.log(chalk.bold.yellow(`${t('info.externalSkillsRequired')}:`));
|
|
62
63
|
plugin.externalSkills.forEach((s) => console.log(` - ${s}`));
|
|
63
64
|
console.log();
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
console.log(
|
|
67
|
-
chalk.gray('
|
|
68
|
+
chalk.gray(`${t('info.installHint')}:`),
|
|
68
69
|
`npx dantelabs-agentic-school install ${pluginName}`
|
|
69
70
|
);
|
|
70
71
|
} 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('
|
|
18
|
-
.option('-p, --path <path>',
|
|
19
|
-
.option('-f, --force', '
|
|
20
|
-
.option('--all', '
|
|
21
|
-
.option('--no-common', '
|
|
22
|
-
.option('--dry-run', '
|
|
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(
|
|
34
|
+
logger.info(`${t('install.installTarget')}: ${chalk.cyan(claudeDir)}`);
|
|
34
35
|
|
|
35
36
|
// Load marketplace config
|
|
36
|
-
spinner.start('
|
|
37
|
+
spinner.start(t('install.loadingRegistry'));
|
|
37
38
|
const config = await getMarketplaceConfig();
|
|
38
|
-
spinner.succeed('
|
|
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:
|
|
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('
|
|
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(
|
|
68
|
+
logger.error(t('install.pluginNotFound', { name: pluginName }));
|
|
66
69
|
console.log();
|
|
67
|
-
console.log('
|
|
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('
|
|
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(
|
|
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(
|
|
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(
|
|
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('
|
|
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(
|
|
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 =
|
|
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(
|
|
159
|
+
spinner.succeed(t('install.installed', { name: chalk.cyan(plugin.name) }));
|
|
147
160
|
} catch (err) {
|
|
148
|
-
spinner.fail(
|
|
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
|
-
|
|
176
|
+
t('install.successMessage', { count: pluginsToInstall.length })
|
|
159
177
|
);
|
|
160
178
|
console.log(
|
|
161
179
|
chalk.gray(
|
|
162
|
-
` ${
|
|
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(
|
|
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('
|
|
192
|
+
console.log(chalk.bold(`${t('install.nextSteps')}:`));
|
|
171
193
|
console.log(
|
|
172
|
-
` 1.
|
|
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.
|
|
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('
|
|
216
|
+
console.log(chalk.yellow(`${t('install.externalSkillsRequired')}:`));
|
|
193
217
|
[...new Set(externalSkills)].forEach((skill) => {
|
|
194
218
|
console.log(` - ${skill}`);
|
|
195
219
|
});
|
package/cli/src/commands/list.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { getMarketplaceConfig } 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('
|
|
10
|
-
.option('--json', '
|
|
11
|
-
.option('-v, --verbose', '
|
|
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();
|
|
@@ -19,7 +20,7 @@ export default function listCommand(program) {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
console.log();
|
|
22
|
-
console.log(chalk.bold.blue('
|
|
23
|
+
console.log(chalk.bold.blue(t('list.title')));
|
|
23
24
|
console.log(chalk.gray('━'.repeat(60)));
|
|
24
25
|
console.log();
|
|
25
26
|
|
|
@@ -34,22 +35,22 @@ export default function listCommand(program) {
|
|
|
34
35
|
const components = plugin.components || {};
|
|
35
36
|
if (components.agents?.length) {
|
|
36
37
|
console.log(
|
|
37
|
-
chalk.gray(`
|
|
38
|
+
chalk.gray(` ${t('common.agents')}: ${components.agents.join(', ')}`)
|
|
38
39
|
);
|
|
39
40
|
}
|
|
40
41
|
if (components.commands?.length) {
|
|
41
42
|
console.log(
|
|
42
|
-
chalk.gray(`
|
|
43
|
+
chalk.gray(` ${t('common.commands')}: /${components.commands.join(', /')}`)
|
|
43
44
|
);
|
|
44
45
|
}
|
|
45
46
|
if (components.skills?.length) {
|
|
46
47
|
console.log(
|
|
47
|
-
chalk.gray(`
|
|
48
|
+
chalk.gray(` ${t('common.skills')}: ${components.skills.join(', ')}`)
|
|
48
49
|
);
|
|
49
50
|
}
|
|
50
51
|
if (plugin.externalSkills?.length) {
|
|
51
52
|
console.log(
|
|
52
|
-
chalk.yellow(`
|
|
53
|
+
chalk.yellow(` ${t('common.external')}: ${plugin.externalSkills.join(', ')}`)
|
|
53
54
|
);
|
|
54
55
|
}
|
|
55
56
|
}
|
|
@@ -73,16 +74,16 @@ export default function listCommand(program) {
|
|
|
73
74
|
|
|
74
75
|
console.log(chalk.gray('━'.repeat(60)));
|
|
75
76
|
console.log(
|
|
76
|
-
chalk.bold('
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
chalk.bold(`${t('common.summary')}:`),
|
|
78
|
+
t('list.summaryText', {
|
|
79
|
+
plugins: config.plugins.length,
|
|
80
|
+
agents: totalAgents,
|
|
81
|
+
commands: totalCommands,
|
|
82
|
+
skills: totalSkills
|
|
83
|
+
})
|
|
81
84
|
);
|
|
82
85
|
console.log();
|
|
83
|
-
console.log(
|
|
84
|
-
chalk.gray(`Install: npx dantelabs-agentic-school install [plugin-name]`)
|
|
85
|
-
);
|
|
86
|
+
console.log(chalk.gray(t('list.installHint')));
|
|
86
87
|
} catch (error) {
|
|
87
88
|
logger.error(error.message);
|
|
88
89
|
process.exit(1);
|
|
@@ -8,14 +8,15 @@ import { getMarketplaceConfig } from '../lib/config.js';
|
|
|
8
8
|
import { uninstallPlugin } from '../lib/installer.js';
|
|
9
9
|
import logger from '../utils/logger.js';
|
|
10
10
|
import { resolvePath } from '../utils/fs-utils.js';
|
|
11
|
+
import { t } from '../i18n/index.js';
|
|
11
12
|
|
|
12
13
|
export default function uninstallCommand(program) {
|
|
13
14
|
program
|
|
14
15
|
.command('uninstall <plugin>')
|
|
15
16
|
.alias('rm')
|
|
16
|
-
.description('
|
|
17
|
-
.option('-p, --path <path>',
|
|
18
|
-
.option('-y, --yes', '
|
|
17
|
+
.description(t('uninstall.description'))
|
|
18
|
+
.option('-p, --path <path>', t('uninstall.optionPath'))
|
|
19
|
+
.option('-y, --yes', t('uninstall.optionYes'))
|
|
19
20
|
.action(async (pluginName, options) => {
|
|
20
21
|
const spinner = ora();
|
|
21
22
|
|
|
@@ -28,12 +29,12 @@ export default function uninstallCommand(program) {
|
|
|
28
29
|
|
|
29
30
|
// Check if .claude directory exists
|
|
30
31
|
if (!existsSync(claudeDir)) {
|
|
31
|
-
logger.error(
|
|
32
|
+
logger.error(t('uninstall.noClaudeDir', { path: targetPath }));
|
|
32
33
|
process.exit(1);
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
// Load marketplace config to get plugin info
|
|
36
|
-
spinner.start('
|
|
37
|
+
spinner.start(t('uninstall.loadingRegistry'));
|
|
37
38
|
const config = await getMarketplaceConfig();
|
|
38
39
|
spinner.stop();
|
|
39
40
|
|
|
@@ -41,9 +42,9 @@ export default function uninstallCommand(program) {
|
|
|
41
42
|
const plugin = config.plugins.find((p) => p.name === pluginName);
|
|
42
43
|
|
|
43
44
|
if (!plugin) {
|
|
44
|
-
logger.error(
|
|
45
|
+
logger.error(t('uninstall.pluginNotFound', { name: pluginName }));
|
|
45
46
|
console.log();
|
|
46
|
-
console.log('
|
|
47
|
+
console.log(`${t('common.availablePlugins')}:`);
|
|
47
48
|
config.plugins.forEach((p) => {
|
|
48
49
|
console.log(` - ${chalk.cyan(p.name)}`);
|
|
49
50
|
});
|
|
@@ -52,22 +53,24 @@ export default function uninstallCommand(program) {
|
|
|
52
53
|
|
|
53
54
|
// Show what will be removed
|
|
54
55
|
console.log();
|
|
55
|
-
console.log(
|
|
56
|
+
console.log(
|
|
57
|
+
chalk.bold(t('uninstall.willRemove', { name: chalk.cyan(plugin.name) }))
|
|
58
|
+
);
|
|
56
59
|
const components = plugin.components || {};
|
|
57
60
|
|
|
58
61
|
if (components.agents?.length) {
|
|
59
62
|
console.log(
|
|
60
|
-
chalk.gray(`
|
|
63
|
+
chalk.gray(` ${t('common.agents')}: ${components.agents.join(', ')}`)
|
|
61
64
|
);
|
|
62
65
|
}
|
|
63
66
|
if (components.commands?.length) {
|
|
64
67
|
console.log(
|
|
65
|
-
chalk.gray(`
|
|
68
|
+
chalk.gray(` ${t('common.commands')}: /${components.commands.join(', /')}`)
|
|
66
69
|
);
|
|
67
70
|
}
|
|
68
71
|
if (components.skills?.length) {
|
|
69
72
|
console.log(
|
|
70
|
-
chalk.gray(`
|
|
73
|
+
chalk.gray(` ${t('common.skills')}: ${components.skills.join(', ')}`)
|
|
71
74
|
);
|
|
72
75
|
}
|
|
73
76
|
console.log();
|
|
@@ -78,29 +81,33 @@ export default function uninstallCommand(program) {
|
|
|
78
81
|
{
|
|
79
82
|
type: 'confirm',
|
|
80
83
|
name: 'confirm',
|
|
81
|
-
message:
|
|
84
|
+
message: t('uninstall.confirmUninstall', { name: plugin.name }),
|
|
82
85
|
default: false
|
|
83
86
|
}
|
|
84
87
|
]);
|
|
85
88
|
|
|
86
89
|
if (!confirm) {
|
|
87
|
-
logger.info('
|
|
90
|
+
logger.info(t('uninstall.uninstallCancelled'));
|
|
88
91
|
return;
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
// Uninstall
|
|
93
|
-
spinner.start(
|
|
96
|
+
spinner.start(t('uninstall.uninstalling', { name: chalk.cyan(plugin.name) }));
|
|
94
97
|
|
|
95
98
|
const results = await uninstallPlugin(plugin, claudeDir);
|
|
96
99
|
|
|
97
|
-
spinner.succeed(
|
|
100
|
+
spinner.succeed(t('uninstall.uninstalled', { name: chalk.cyan(plugin.name) }));
|
|
98
101
|
|
|
99
102
|
// Summary
|
|
100
103
|
console.log();
|
|
101
104
|
console.log(
|
|
102
105
|
chalk.gray(
|
|
103
|
-
|
|
106
|
+
t('uninstall.removedSummary', {
|
|
107
|
+
agents: results.agents,
|
|
108
|
+
commands: results.commands,
|
|
109
|
+
skills: results.skills
|
|
110
|
+
})
|
|
104
111
|
)
|
|
105
112
|
);
|
|
106
113
|
} catch (error) {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internationalization (i18n) module
|
|
3
|
+
* Default language: English (en)
|
|
4
|
+
* Supported languages: en, ko
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import en from './locales/en.js';
|
|
8
|
+
import ko from './locales/ko.js';
|
|
9
|
+
|
|
10
|
+
const locales = { en, ko };
|
|
11
|
+
|
|
12
|
+
// Default language
|
|
13
|
+
let currentLocale = 'en';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Set the current locale
|
|
17
|
+
* @param {string} locale - Locale code (en, ko)
|
|
18
|
+
*/
|
|
19
|
+
export function setLocale(locale) {
|
|
20
|
+
if (locales[locale]) {
|
|
21
|
+
currentLocale = locale;
|
|
22
|
+
} else {
|
|
23
|
+
console.warn(`Locale '${locale}' not supported. Using 'en' as default.`);
|
|
24
|
+
currentLocale = 'en';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the current locale
|
|
30
|
+
* @returns {string} Current locale code
|
|
31
|
+
*/
|
|
32
|
+
export function getLocale() {
|
|
33
|
+
return currentLocale;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get available locales
|
|
38
|
+
* @returns {string[]} Array of locale codes
|
|
39
|
+
*/
|
|
40
|
+
export function getAvailableLocales() {
|
|
41
|
+
return Object.keys(locales);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get translation for a key path
|
|
46
|
+
* @param {string} keyPath - Dot-separated key path (e.g., 'install.description')
|
|
47
|
+
* @param {object} params - Parameters to interpolate
|
|
48
|
+
* @returns {string} Translated string
|
|
49
|
+
*/
|
|
50
|
+
export function t(keyPath, params = {}) {
|
|
51
|
+
const keys = keyPath.split('.');
|
|
52
|
+
let value = locales[currentLocale];
|
|
53
|
+
|
|
54
|
+
for (const key of keys) {
|
|
55
|
+
if (value && typeof value === 'object' && key in value) {
|
|
56
|
+
value = value[key];
|
|
57
|
+
} else {
|
|
58
|
+
// Fallback to English
|
|
59
|
+
value = locales.en;
|
|
60
|
+
for (const k of keys) {
|
|
61
|
+
if (value && typeof value === 'object' && k in value) {
|
|
62
|
+
value = value[k];
|
|
63
|
+
} else {
|
|
64
|
+
return keyPath; // Return key if not found
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (typeof value !== 'string') {
|
|
72
|
+
return keyPath;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Interpolate parameters: {name} -> value
|
|
76
|
+
return value.replace(/\{(\w+)\}/g, (_, key) => {
|
|
77
|
+
return params[key] !== undefined ? params[key] : `{${key}}`;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get all translations for a section
|
|
83
|
+
* @param {string} section - Section name (e.g., 'install', 'list')
|
|
84
|
+
* @returns {object} Section translations
|
|
85
|
+
*/
|
|
86
|
+
export function getSection(section) {
|
|
87
|
+
return locales[currentLocale][section] || locales.en[section] || {};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export default {
|
|
91
|
+
setLocale,
|
|
92
|
+
getLocale,
|
|
93
|
+
getAvailableLocales,
|
|
94
|
+
t,
|
|
95
|
+
getSection
|
|
96
|
+
};
|