@ariasbruno/skillbase 0.2.0 → 1.1.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.
- package/AGENTS.md +7 -6
- package/README.md +67 -61
- package/README_es.md +132 -0
- package/package.json +12 -3
- package/src/cli.js +213 -111
- package/src/config.js +37 -0
- package/src/core.js +128 -88
- package/src/i18n.js +34 -0
- package/src/locales/en.js +104 -0
- package/src/locales/es.js +104 -0
- package/src/manifest.js +8 -12
- package/src/recommendations.js +7 -10
- package/src/styles.js +59 -0
package/src/cli.js
CHANGED
|
@@ -14,75 +14,118 @@ import {
|
|
|
14
14
|
removeSkill,
|
|
15
15
|
updateSkills
|
|
16
16
|
} from './core.js';
|
|
17
|
+
import {
|
|
18
|
+
bold,
|
|
19
|
+
dim,
|
|
20
|
+
dim2,
|
|
21
|
+
text,
|
|
22
|
+
grayLogo,
|
|
23
|
+
cyan,
|
|
24
|
+
yellow,
|
|
25
|
+
green,
|
|
26
|
+
red,
|
|
27
|
+
S_DIAMOND,
|
|
28
|
+
S_BULLET,
|
|
29
|
+
S_CHECK,
|
|
30
|
+
S_POINTER,
|
|
31
|
+
S_WARNING,
|
|
32
|
+
S_BAR,
|
|
33
|
+
S_BAR_START,
|
|
34
|
+
S_BAR_END,
|
|
35
|
+
S_STEP
|
|
36
|
+
} from './styles.js';
|
|
37
|
+
import { createRequire } from 'node:module';
|
|
38
|
+
import { t, setLanguage } from './i18n.js';
|
|
39
|
+
import { getConfig, saveConfig } from './config.js';
|
|
40
|
+
|
|
41
|
+
const require = createRequire(import.meta.url);
|
|
42
|
+
const pkg = require('../package.json');
|
|
43
|
+
|
|
44
|
+
function printLogo() {
|
|
45
|
+
const LOGO_LINES = [
|
|
46
|
+
' ███████╗██╗ ██╗██╗██╗ ██╗ ██████╗ █████╗ ███████╗███████╗',
|
|
47
|
+
' ██╔════╝██║ ██╔╝██║██║ ██║ ██╔══██╗██╔══██╗██╔════╝██╔════╝',
|
|
48
|
+
' ███████╗█████╔╝ ██║██║ ██║ ██████╔╝███████║███████╗█████╗ ',
|
|
49
|
+
' ╚════██║██╔═██╗ ██║██║ ██║ ██╔══██╗██╔══██║╚════██║██╔══╝ ',
|
|
50
|
+
' ███████║██║ ██╗██║███████╗███████╗██████╔╝██║ ██║███████║███████╗',
|
|
51
|
+
' ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝',
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
console.log();
|
|
55
|
+
LOGO_LINES.forEach((line, i) => {
|
|
56
|
+
console.log(grayLogo(line, i));
|
|
57
|
+
});
|
|
58
|
+
console.log(` ${dim2(pkg.description)} ${dim2(`v${pkg.version}`)}`);
|
|
59
|
+
console.log();
|
|
60
|
+
}
|
|
17
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Muestra la ayuda principal de la CLI con el estilo Clack.
|
|
64
|
+
*/
|
|
18
65
|
function printHelp() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Notas:
|
|
59
|
-
- Carpeta global por defecto: ~/.skillbase/skills
|
|
60
|
-
- Puedes cambiarla con SKILLBASE_HOME
|
|
61
|
-
- Las skills de proyecto viven en .agents/skills
|
|
62
|
-
- El manifiesto del proyecto es skillbase.json
|
|
63
|
-
`);
|
|
66
|
+
printLogo();
|
|
67
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('USAGE'))}`);
|
|
68
|
+
console.log(`${cyan(S_BAR)} ${green('skillbase')} ${text('<command> [args] [options]')}`);
|
|
69
|
+
console.log(`${cyan(S_BAR)}`);
|
|
70
|
+
|
|
71
|
+
console.log(`${cyan(S_BAR)} ${bold(t('COMMANDS'))}`);
|
|
72
|
+
const commands = [
|
|
73
|
+
['ls', `[args]`, t('DESC_LS')],
|
|
74
|
+
['init', ``, t('DESC_INIT')],
|
|
75
|
+
['add', `<skill>`, t('DESC_ADD')],
|
|
76
|
+
['install', `[url]`, t('DESC_INSTALL')],
|
|
77
|
+
['remove', `<skill>`, t('DESC_REMOVE')],
|
|
78
|
+
['check', ``, t('DESC_CHECK')],
|
|
79
|
+
['update', `[skill]`, t('DESC_UPDATE')],
|
|
80
|
+
['migrate', ``, t('DESC_MIGRATE')],
|
|
81
|
+
['lang', `<lang>`, t('DESC_LANG')],
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
commands.forEach(([cmd, args, desc]) => {
|
|
85
|
+
const fullCmd = `${bold(cmd.padEnd(8))} ${dim2(args.padEnd(8))}`;
|
|
86
|
+
console.log(`${cyan(S_BAR)} ${fullCmd} ${text(desc)}`);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
console.log(`${cyan(S_BAR)}`);
|
|
90
|
+
console.log(`${cyan(S_BAR)} ${bold(t('OPTIONS'))}`);
|
|
91
|
+
const options = [
|
|
92
|
+
['-r, --remote ', t('OPT_REMOTE')],
|
|
93
|
+
['-f, --force ', t('OPT_FORCE')],
|
|
94
|
+
['-s, --sym ', t('OPT_SYM')],
|
|
95
|
+
['-g, --global ', t('OPT_GLOBAL')],
|
|
96
|
+
['-h, --help ', t('OPT_HELP')],
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
options.forEach(([opt, desc]) => {
|
|
100
|
+
console.log(`${cyan(S_BAR)} ${dim2(opt.padEnd(14))} ${dim2(desc)}`);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
console.log(`${cyan(S_BAR)}`);
|
|
104
|
+
console.log(`${cyan(S_BAR_END)} ${dim2(t('SHORTCUTS'))}\n`);
|
|
64
105
|
}
|
|
65
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Muestra una lista resumida de comandos cuando no se indica ninguno.
|
|
109
|
+
*/
|
|
66
110
|
function printCommandList() {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
Usa "skillbase -h" para ver detalles.`);
|
|
111
|
+
printLogo();
|
|
112
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('COMMANDS_AVAILABLE'))}`);
|
|
113
|
+
|
|
114
|
+
const quickList = [
|
|
115
|
+
['ls', t('DESC_LS_SHORT')],
|
|
116
|
+
['init', t('DESC_INIT_SHORT')],
|
|
117
|
+
['add', t('DESC_ADD_SHORT')],
|
|
118
|
+
['install', t('DESC_INSTALL_SHORT')],
|
|
119
|
+
['migrate', t('DESC_MIGRATE_SHORT')],
|
|
120
|
+
['lang', t('DESC_LANG_SHORT')],
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
quickList.forEach(([cmd, desc]) => {
|
|
124
|
+
console.log(`${cyan(S_BAR)} ${bold(cmd.padEnd(12))} ${dim2(desc)}`);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
console.log(`${cyan(S_BAR)}`);
|
|
128
|
+
console.log(`${cyan(S_BAR_END)} ${dim2(t('USE_HELP', { cmd: yellow('skillbase --help') }))}\n`);
|
|
86
129
|
}
|
|
87
130
|
|
|
88
131
|
function hasFlag(args, ...flags) {
|
|
@@ -96,6 +139,9 @@ function getFlagValue(args, ...flags) {
|
|
|
96
139
|
return null;
|
|
97
140
|
}
|
|
98
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Punto de entrada principal de la CLI.
|
|
144
|
+
*/
|
|
99
145
|
export async function runCLI(argv) {
|
|
100
146
|
const args = argv.slice(2);
|
|
101
147
|
const [rawCommand, maybeSkill] = args;
|
|
@@ -116,73 +162,89 @@ export async function runCLI(argv) {
|
|
|
116
162
|
return;
|
|
117
163
|
}
|
|
118
164
|
|
|
119
|
-
if (command === '-h' || command === '--help') {
|
|
165
|
+
if (command === '-h' || command === '--help' || hasFlag(args, '-h', '--help')) {
|
|
120
166
|
printHelp();
|
|
121
167
|
return;
|
|
122
168
|
}
|
|
123
169
|
|
|
124
170
|
switch (command) {
|
|
125
171
|
case 'ls': {
|
|
126
|
-
const
|
|
127
|
-
if (
|
|
128
|
-
const skills = await
|
|
172
|
+
const showGlobal = hasFlag(args, '--global', '-g');
|
|
173
|
+
if (showGlobal) {
|
|
174
|
+
const skills = await listGlobalSkills();
|
|
129
175
|
if (!skills.length) {
|
|
130
|
-
console.log(
|
|
176
|
+
console.log(`${yellow(S_WARNING)} ${t('LS_GLOBAL_EMPTY', { dir: dim2(getGlobalSkillsDir()) })}`);
|
|
131
177
|
} else {
|
|
132
|
-
console.log(
|
|
133
|
-
skills.forEach((skill) => console.log(
|
|
178
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('LS_GLOBAL_TITLE', { dir: dim2(getGlobalSkillsDir()) }))}`);
|
|
179
|
+
skills.forEach((skill) => console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${text(skill)}`));
|
|
180
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
134
181
|
}
|
|
135
182
|
} else {
|
|
136
|
-
const skills = await
|
|
183
|
+
const skills = await listProjectSkills();
|
|
137
184
|
if (!skills.length) {
|
|
138
|
-
console.log(
|
|
185
|
+
console.log(`${yellow(S_WARNING)} ${t('LS_PROJECT_EMPTY', { dir: dim2(getProjectSkillsDir()) })}`);
|
|
139
186
|
} else {
|
|
140
|
-
console.log(
|
|
141
|
-
skills.forEach((skill) => console.log(
|
|
187
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('LS_PROJECT_TITLE', { dir: dim2(getProjectSkillsDir()) }))}`);
|
|
188
|
+
skills.forEach((skill) => console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${text(skill)}`));
|
|
189
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
142
190
|
}
|
|
143
191
|
}
|
|
144
192
|
return;
|
|
145
193
|
}
|
|
146
194
|
|
|
147
195
|
case 'init': {
|
|
196
|
+
printLogo();
|
|
148
197
|
const result = await initProject({ hard: hasFlag(args, '--hard') });
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
console.log(`Tecnologías detectadas: ${result.technologies.join(', ')}`);
|
|
154
|
-
if (!result.suggested.length) {
|
|
155
|
-
console.log('No se encontraron skills compatibles en ~/.skillbase/skills.');
|
|
198
|
+
|
|
199
|
+
if (result.cancelled) {
|
|
200
|
+
console.log(`${cyan(S_BAR_START)} ${dim2(t('CANCELLED'))}`);
|
|
201
|
+
console.log(`${cyan(S_BAR_END)}`);
|
|
156
202
|
return;
|
|
157
203
|
}
|
|
158
|
-
|
|
159
|
-
|
|
204
|
+
|
|
205
|
+
if (!result.technologies.length) {
|
|
206
|
+
console.log(`${yellow(S_WARNING)} ${t('INIT_NO_STACK')}`);
|
|
160
207
|
return;
|
|
161
208
|
}
|
|
209
|
+
|
|
210
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('INIT_ANALYSIS'))}`);
|
|
211
|
+
result.technologies.forEach((tech) => {
|
|
212
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${text(tech)}`);
|
|
213
|
+
});
|
|
214
|
+
console.log(`${cyan(S_BAR)}`);
|
|
215
|
+
|
|
162
216
|
if (result.installed.length) {
|
|
163
|
-
console.log(
|
|
217
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('INIT_RESUMEN'))}`);
|
|
218
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('INIT_INSTALLED', { list: bold(result.installed.join(', ')) })}`);
|
|
219
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
164
220
|
} else {
|
|
165
|
-
console.log('
|
|
221
|
+
console.log(`${cyan(S_BAR_END)} ${dim2(t('INIT_NONE'))}\n`);
|
|
166
222
|
}
|
|
167
223
|
return;
|
|
168
224
|
}
|
|
169
225
|
|
|
170
226
|
case 'add': {
|
|
171
227
|
if (!maybeSkill) {
|
|
228
|
+
printLogo();
|
|
172
229
|
const result = await addSkillsInteractive({ sym: hasFlag(args, '--sym', '-s') });
|
|
173
230
|
if (result.cancelled) {
|
|
174
|
-
console.log('
|
|
231
|
+
console.log(`${cyan(S_BAR_START)} ${dim2(t('SELECTION_CANCELLED'))}`);
|
|
232
|
+
console.log(`${cyan(S_BAR_END)}`);
|
|
175
233
|
return;
|
|
176
234
|
}
|
|
177
235
|
if (!result.selected.length) {
|
|
178
|
-
console.log('
|
|
236
|
+
console.log(`${cyan(S_BAR_END)} ${dim2(t('ADD_NO_SELECTED'))}\n`);
|
|
179
237
|
return;
|
|
180
238
|
}
|
|
181
|
-
console.log(
|
|
239
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('ADD_RESUMEN'))}`);
|
|
240
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('INIT_INSTALLED', { list: bold(result.selected.join(', ')) })}`);
|
|
241
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
182
242
|
return;
|
|
183
243
|
}
|
|
184
244
|
await addSkill(maybeSkill, { sym: hasFlag(args, '--sym', '-s') });
|
|
185
|
-
console.log(
|
|
245
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('ADD_RESUMEN'))}`);
|
|
246
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('ADD_SUCCESS', { skill: bold(maybeSkill) })}`);
|
|
247
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
186
248
|
return;
|
|
187
249
|
}
|
|
188
250
|
|
|
@@ -192,77 +254,117 @@ export async function runCLI(argv) {
|
|
|
192
254
|
force: hasFlag(args, '--force', '-f'),
|
|
193
255
|
skill: getFlagValue(args, '--skill', '-k')
|
|
194
256
|
});
|
|
195
|
-
console.log(
|
|
257
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('INIT_RESUMEN'))}`);
|
|
258
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('ADD_REMOTE_SUCCESS', { skill: bold(maybeSkill) })}`);
|
|
259
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
196
260
|
return;
|
|
197
261
|
}
|
|
198
262
|
if (maybeSkill && !hasFlag(args, '--remote', '-r')) {
|
|
199
|
-
throw new Error(
|
|
263
|
+
throw new Error(t('INSTALL_ERROR_SINGLE'));
|
|
200
264
|
}
|
|
201
265
|
await installFromManifest({ remote: hasFlag(args, '--remote', '-r'), force: hasFlag(args, '--force', '-f') });
|
|
202
266
|
const manifest = await readManifest();
|
|
203
|
-
console.log(
|
|
267
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('INIT_RESUMEN'))}`);
|
|
268
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('INSTALL_MANIFEST_SUCCESS', { count: bold(manifest.skills.length) })}`);
|
|
269
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
204
270
|
return;
|
|
205
271
|
}
|
|
206
272
|
|
|
207
273
|
case 'remove': {
|
|
208
|
-
if (!maybeSkill) throw new Error('
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
274
|
+
if (!maybeSkill) throw new Error(t('REMOVE_REQUIRED'));
|
|
275
|
+
const isGlobal = hasFlag(args, '-g', '--global');
|
|
276
|
+
await removeSkill(maybeSkill, { global: isGlobal });
|
|
277
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('INIT_RESUMEN'))}`);
|
|
278
|
+
if (isGlobal) {
|
|
279
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('REMOVE_GLOBAL_SUCCESS', { skill: bold(maybeSkill) })}`);
|
|
212
280
|
} else {
|
|
213
|
-
console.log(
|
|
281
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('REMOVE_PROJECT_SUCCESS', { skill: bold(maybeSkill) })}`);
|
|
214
282
|
}
|
|
283
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
215
284
|
return;
|
|
216
285
|
}
|
|
217
286
|
|
|
218
287
|
case 'check': {
|
|
288
|
+
console.log(`${cyan(S_BAR_START)} ${dim2(t('CHECK_SEARCHING'))}`);
|
|
219
289
|
const updates = await checkUpdates({ remoteOnly: hasFlag(args, '--remote', '-r') });
|
|
220
290
|
if (!updates.length) {
|
|
221
|
-
console.log(
|
|
291
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('CHECK_UP_TO_DATE')}`);
|
|
292
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
222
293
|
return;
|
|
223
294
|
}
|
|
224
|
-
console.log('
|
|
295
|
+
console.log(`${cyan(S_BAR)} ${bold(t('CHECK_UPDATES_FOUND'))}`);
|
|
225
296
|
updates.forEach((item) => {
|
|
226
|
-
console.log(
|
|
297
|
+
console.log(`${cyan(S_BAR)} ${yellow(S_POINTER)} ${item.name}: ${dim2(item.current ?? '?')} ${dim2(S_STEP)} ${green(item.latest)} ${dim2(`(${item.source})`)}`);
|
|
227
298
|
});
|
|
299
|
+
console.log(`${cyan(S_BAR)}`);
|
|
300
|
+
console.log(`${cyan(S_BAR_END)} ${dim2(t('CHECK_UPDATE_HINT', { cmd: yellow('skillbase update') }))}\n`);
|
|
228
301
|
return;
|
|
229
302
|
}
|
|
230
303
|
|
|
231
304
|
case 'update': {
|
|
232
305
|
const skill = maybeSkill && !maybeSkill.startsWith('-') ? maybeSkill : null;
|
|
306
|
+
console.log(`${cyan(S_BAR_START)} ${dim2(t('UPDATE_START'))}`);
|
|
233
307
|
await updateSkills({
|
|
234
308
|
skillName: skill,
|
|
235
309
|
remoteOnly: hasFlag(args, '--remote', '-remote', '-r'),
|
|
236
310
|
force: hasFlag(args, '--force', '-f')
|
|
237
311
|
});
|
|
312
|
+
console.log(`${cyan(S_BAR)} ${bold(t('INIT_RESUMEN'))}`);
|
|
238
313
|
if (skill) {
|
|
239
|
-
console.log(
|
|
314
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('UPDATE_SINGLE_SUCCESS', { skill: bold(skill) })}`);
|
|
240
315
|
} else {
|
|
241
|
-
console.log(
|
|
316
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('UPDATE_SUCCESS')}`);
|
|
242
317
|
}
|
|
318
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
243
319
|
return;
|
|
244
320
|
}
|
|
245
321
|
|
|
246
322
|
case 'migrate': {
|
|
247
|
-
const fromProject = hasFlag(args, '--
|
|
323
|
+
const fromProject = hasFlag(args, '--promote', '-p');
|
|
248
324
|
const result = await migrateAgentsSkillsToSkillbase({
|
|
249
325
|
force: hasFlag(args, '--force', '-f'),
|
|
250
326
|
fromProject
|
|
251
327
|
});
|
|
252
|
-
console.log(
|
|
253
|
-
console.log(
|
|
328
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('MIGRATE_TITLE'))}`);
|
|
329
|
+
console.log(`${cyan(S_BAR)} ${dim2(S_POINTER)} ${t('MIGRATE_SOURCE', { dir: dim2(`${result.sourceRoot}/skills`) })}`);
|
|
330
|
+
console.log(`${cyan(S_BAR)} ${dim2(S_POINTER)} ${t('MIGRATE_FOUND', { count: bold(result.totalFound) })}`);
|
|
331
|
+
|
|
254
332
|
if (result.migrated.length) {
|
|
255
|
-
console.log(
|
|
256
|
-
|
|
333
|
+
console.log(`${cyan(S_BAR)}`);
|
|
334
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('MIGRATE_SUCCESS_LIST', { dir: dim2(getGlobalSkillsDir()) })}`);
|
|
335
|
+
result.migrated.forEach((skill) => console.log(`${cyan(S_BAR)} ${dim2('·')} ${text(skill)}`));
|
|
257
336
|
}
|
|
258
337
|
if (result.skipped.length) {
|
|
259
|
-
console.log(
|
|
260
|
-
|
|
338
|
+
console.log(`${cyan(S_BAR)}`);
|
|
339
|
+
console.log(`${cyan(S_BAR)} ${yellow(S_POINTER)} ${t('MIGRATE_SKIPPED_LIST')}`);
|
|
340
|
+
result.skipped.forEach((skill) => console.log(`${cyan(S_BAR)} ${dim2('·')} ${text(skill)}`));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (result.migrated.length) {
|
|
344
|
+
console.log(`${cyan(S_BAR)}`);
|
|
345
|
+
console.log(`${cyan(S_BAR)} ${bold(t('INIT_RESUMEN'))}`);
|
|
346
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('MIGRATE_RESUMEN_SUCCESS', { count: bold(result.migrated.length) })}`);
|
|
347
|
+
console.log(`${cyan(S_BAR)} ${dim2(S_POINTER)} ${t('MIGRATE_RESUMEN_DEST', { dir: bold(getGlobalSkillsDir()) })}`);
|
|
348
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
349
|
+
} else {
|
|
350
|
+
console.log(`${cyan(S_BAR_END)} ${dim2(t('MIGRATE_NONE'))}\n`);
|
|
351
|
+
}
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
case 'lang': {
|
|
356
|
+
if (!maybeSkill || !['en', 'es'].includes(maybeSkill)) {
|
|
357
|
+
throw new Error(t('LANG_INVALID', { lang: maybeSkill || '??' }));
|
|
261
358
|
}
|
|
359
|
+
const config = await getConfig();
|
|
360
|
+
config.lang = maybeSkill;
|
|
361
|
+
saveConfig(config);
|
|
362
|
+
console.log(`${cyan(S_BAR_START)} ${bold(t('LANG_SUCCESS', { lang: maybeSkill === 'es' ? 'Español' : 'English' }))}`);
|
|
363
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
262
364
|
return;
|
|
263
365
|
}
|
|
264
366
|
|
|
265
367
|
default:
|
|
266
|
-
throw new Error(
|
|
368
|
+
throw new Error(t('UNKNOWN_COMMAND', { cmd: command }));
|
|
267
369
|
}
|
|
268
370
|
}
|
package/src/config.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import fsp from 'node:fs/promises';
|
|
1
3
|
import os from 'node:os';
|
|
2
4
|
import path from 'node:path';
|
|
3
5
|
|
|
@@ -5,6 +7,16 @@ export const MANIFEST_FILE = 'skillbase.json';
|
|
|
5
7
|
export const PROJECT_AGENTS_DIR = '.agents';
|
|
6
8
|
export const PROJECT_SKILLS_DIR = 'skills';
|
|
7
9
|
export const DEFAULT_GLOBAL_ROOTNAME = '.skillbase';
|
|
10
|
+
export const CONFIG_FILE = 'config.json';
|
|
11
|
+
|
|
12
|
+
export async function exists(target) {
|
|
13
|
+
try {
|
|
14
|
+
await fsp.access(target);
|
|
15
|
+
return true;
|
|
16
|
+
} catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
8
20
|
|
|
9
21
|
export function getGlobalRootDir() {
|
|
10
22
|
const fromEnv = process.env.SKILLBASE_HOME;
|
|
@@ -16,6 +28,31 @@ export function getGlobalSkillsDir() {
|
|
|
16
28
|
return path.join(getGlobalRootDir(), PROJECT_SKILLS_DIR);
|
|
17
29
|
}
|
|
18
30
|
|
|
31
|
+
export function getGlobalConfigPath() {
|
|
32
|
+
return path.join(getGlobalRootDir(), CONFIG_FILE);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getConfig() {
|
|
36
|
+
const configPath = getGlobalConfigPath();
|
|
37
|
+
try {
|
|
38
|
+
if (fs.existsSync(configPath)) {
|
|
39
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// Omitir errores de lectura
|
|
43
|
+
}
|
|
44
|
+
return { lang: 'en' };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function saveConfig(config) {
|
|
48
|
+
const configPath = getGlobalConfigPath();
|
|
49
|
+
const rootDir = getGlobalRootDir();
|
|
50
|
+
if (!fs.existsSync(rootDir)) {
|
|
51
|
+
fs.mkdirSync(rootDir, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
54
|
+
}
|
|
55
|
+
|
|
19
56
|
export function getProjectRoot(cwd = process.cwd()) {
|
|
20
57
|
return cwd;
|
|
21
58
|
}
|