@ariasbruno/skillbase 0.1.1 → 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 +11 -5
- package/README.md +68 -60
- package/README_es.md +132 -0
- package/package.json +12 -3
- package/src/cli.js +224 -107
- package/src/config.js +37 -0
- package/src/core.js +135 -89
- 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
|
@@ -3,84 +3,129 @@ import {
|
|
|
3
3
|
addSkill,
|
|
4
4
|
checkUpdates,
|
|
5
5
|
getGlobalSkillsDir,
|
|
6
|
+
getProjectSkillsDir,
|
|
6
7
|
initProject,
|
|
7
8
|
installFromManifest,
|
|
8
9
|
installRemoteSkillRef,
|
|
9
10
|
listGlobalSkills,
|
|
11
|
+
listProjectSkills,
|
|
10
12
|
migrateAgentsSkillsToSkillbase,
|
|
11
13
|
readManifest,
|
|
12
14
|
removeSkill,
|
|
13
15
|
updateSkills
|
|
14
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
|
+
}
|
|
15
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Muestra la ayuda principal de la CLI con el estilo Clack.
|
|
64
|
+
*/
|
|
16
65
|
function printHelp() {
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
Notas:
|
|
57
|
-
- Carpeta global por defecto: ~/.skillbase/skills
|
|
58
|
-
- Puedes cambiarla con SKILLBASE_HOME
|
|
59
|
-
- Las skills de proyecto viven en .agents/skills
|
|
60
|
-
- El manifiesto del proyecto es skillbase.json
|
|
61
|
-
`);
|
|
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`);
|
|
62
105
|
}
|
|
63
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Muestra una lista resumida de comandos cuando no se indica ninguno.
|
|
109
|
+
*/
|
|
64
110
|
function printCommandList() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
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`);
|
|
84
129
|
}
|
|
85
130
|
|
|
86
131
|
function hasFlag(args, ...flags) {
|
|
@@ -94,6 +139,9 @@ function getFlagValue(args, ...flags) {
|
|
|
94
139
|
return null;
|
|
95
140
|
}
|
|
96
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Punto de entrada principal de la CLI.
|
|
144
|
+
*/
|
|
97
145
|
export async function runCLI(argv) {
|
|
98
146
|
const args = argv.slice(2);
|
|
99
147
|
const [rawCommand, maybeSkill] = args;
|
|
@@ -114,60 +162,89 @@ export async function runCLI(argv) {
|
|
|
114
162
|
return;
|
|
115
163
|
}
|
|
116
164
|
|
|
117
|
-
if (command === '-h' || command === '--help') {
|
|
165
|
+
if (command === '-h' || command === '--help' || hasFlag(args, '-h', '--help')) {
|
|
118
166
|
printHelp();
|
|
119
167
|
return;
|
|
120
168
|
}
|
|
121
169
|
|
|
122
170
|
switch (command) {
|
|
123
171
|
case 'ls': {
|
|
124
|
-
const
|
|
125
|
-
if (
|
|
126
|
-
|
|
172
|
+
const showGlobal = hasFlag(args, '--global', '-g');
|
|
173
|
+
if (showGlobal) {
|
|
174
|
+
const skills = await listGlobalSkills();
|
|
175
|
+
if (!skills.length) {
|
|
176
|
+
console.log(`${yellow(S_WARNING)} ${t('LS_GLOBAL_EMPTY', { dir: dim2(getGlobalSkillsDir()) })}`);
|
|
177
|
+
} else {
|
|
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`);
|
|
181
|
+
}
|
|
127
182
|
} else {
|
|
128
|
-
|
|
129
|
-
skills.
|
|
183
|
+
const skills = await listProjectSkills();
|
|
184
|
+
if (!skills.length) {
|
|
185
|
+
console.log(`${yellow(S_WARNING)} ${t('LS_PROJECT_EMPTY', { dir: dim2(getProjectSkillsDir()) })}`);
|
|
186
|
+
} else {
|
|
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`);
|
|
190
|
+
}
|
|
130
191
|
}
|
|
131
192
|
return;
|
|
132
193
|
}
|
|
133
194
|
|
|
134
195
|
case 'init': {
|
|
196
|
+
printLogo();
|
|
135
197
|
const result = await initProject({ hard: hasFlag(args, '--hard') });
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
console.log(`Tecnologías detectadas: ${result.technologies.join(', ')}`);
|
|
141
|
-
if (!result.suggested.length) {
|
|
142
|
-
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)}`);
|
|
143
202
|
return;
|
|
144
203
|
}
|
|
145
|
-
|
|
146
|
-
if (result.
|
|
147
|
-
console.log(
|
|
204
|
+
|
|
205
|
+
if (!result.technologies.length) {
|
|
206
|
+
console.log(`${yellow(S_WARNING)} ${t('INIT_NO_STACK')}`);
|
|
148
207
|
return;
|
|
149
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
|
+
|
|
150
216
|
if (result.installed.length) {
|
|
151
|
-
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`);
|
|
152
220
|
} else {
|
|
153
|
-
console.log('
|
|
221
|
+
console.log(`${cyan(S_BAR_END)} ${dim2(t('INIT_NONE'))}\n`);
|
|
154
222
|
}
|
|
155
223
|
return;
|
|
156
224
|
}
|
|
157
225
|
|
|
158
226
|
case 'add': {
|
|
159
227
|
if (!maybeSkill) {
|
|
228
|
+
printLogo();
|
|
160
229
|
const result = await addSkillsInteractive({ sym: hasFlag(args, '--sym', '-s') });
|
|
161
|
-
if (result.cancelled)
|
|
230
|
+
if (result.cancelled) {
|
|
231
|
+
console.log(`${cyan(S_BAR_START)} ${dim2(t('SELECTION_CANCELLED'))}`);
|
|
232
|
+
console.log(`${cyan(S_BAR_END)}`);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
162
235
|
if (!result.selected.length) {
|
|
163
|
-
console.log('
|
|
236
|
+
console.log(`${cyan(S_BAR_END)} ${dim2(t('ADD_NO_SELECTED'))}\n`);
|
|
164
237
|
return;
|
|
165
238
|
}
|
|
166
|
-
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`);
|
|
167
242
|
return;
|
|
168
243
|
}
|
|
169
244
|
await addSkill(maybeSkill, { sym: hasFlag(args, '--sym', '-s') });
|
|
170
|
-
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`);
|
|
171
248
|
return;
|
|
172
249
|
}
|
|
173
250
|
|
|
@@ -177,77 +254,117 @@ export async function runCLI(argv) {
|
|
|
177
254
|
force: hasFlag(args, '--force', '-f'),
|
|
178
255
|
skill: getFlagValue(args, '--skill', '-k')
|
|
179
256
|
});
|
|
180
|
-
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`);
|
|
181
260
|
return;
|
|
182
261
|
}
|
|
183
262
|
if (maybeSkill && !hasFlag(args, '--remote', '-r')) {
|
|
184
|
-
throw new Error(
|
|
263
|
+
throw new Error(t('INSTALL_ERROR_SINGLE'));
|
|
185
264
|
}
|
|
186
265
|
await installFromManifest({ remote: hasFlag(args, '--remote', '-r'), force: hasFlag(args, '--force', '-f') });
|
|
187
266
|
const manifest = await readManifest();
|
|
188
|
-
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`);
|
|
189
270
|
return;
|
|
190
271
|
}
|
|
191
272
|
|
|
192
273
|
case 'remove': {
|
|
193
|
-
if (!maybeSkill) throw new Error('
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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) })}`);
|
|
197
280
|
} else {
|
|
198
|
-
console.log(
|
|
281
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('REMOVE_PROJECT_SUCCESS', { skill: bold(maybeSkill) })}`);
|
|
199
282
|
}
|
|
283
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
200
284
|
return;
|
|
201
285
|
}
|
|
202
286
|
|
|
203
287
|
case 'check': {
|
|
288
|
+
console.log(`${cyan(S_BAR_START)} ${dim2(t('CHECK_SEARCHING'))}`);
|
|
204
289
|
const updates = await checkUpdates({ remoteOnly: hasFlag(args, '--remote', '-r') });
|
|
205
290
|
if (!updates.length) {
|
|
206
|
-
console.log(
|
|
291
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('CHECK_UP_TO_DATE')}`);
|
|
292
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
207
293
|
return;
|
|
208
294
|
}
|
|
209
|
-
console.log('
|
|
295
|
+
console.log(`${cyan(S_BAR)} ${bold(t('CHECK_UPDATES_FOUND'))}`);
|
|
210
296
|
updates.forEach((item) => {
|
|
211
|
-
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})`)}`);
|
|
212
298
|
});
|
|
299
|
+
console.log(`${cyan(S_BAR)}`);
|
|
300
|
+
console.log(`${cyan(S_BAR_END)} ${dim2(t('CHECK_UPDATE_HINT', { cmd: yellow('skillbase update') }))}\n`);
|
|
213
301
|
return;
|
|
214
302
|
}
|
|
215
303
|
|
|
216
304
|
case 'update': {
|
|
217
305
|
const skill = maybeSkill && !maybeSkill.startsWith('-') ? maybeSkill : null;
|
|
306
|
+
console.log(`${cyan(S_BAR_START)} ${dim2(t('UPDATE_START'))}`);
|
|
218
307
|
await updateSkills({
|
|
219
308
|
skillName: skill,
|
|
220
309
|
remoteOnly: hasFlag(args, '--remote', '-remote', '-r'),
|
|
221
310
|
force: hasFlag(args, '--force', '-f')
|
|
222
311
|
});
|
|
312
|
+
console.log(`${cyan(S_BAR)} ${bold(t('INIT_RESUMEN'))}`);
|
|
223
313
|
if (skill) {
|
|
224
|
-
console.log(
|
|
314
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('UPDATE_SINGLE_SUCCESS', { skill: bold(skill) })}`);
|
|
225
315
|
} else {
|
|
226
|
-
console.log(
|
|
316
|
+
console.log(`${cyan(S_BAR)} ${green(S_CHECK)} ${t('UPDATE_SUCCESS')}`);
|
|
227
317
|
}
|
|
318
|
+
console.log(`${cyan(S_BAR_END)}\n`);
|
|
228
319
|
return;
|
|
229
320
|
}
|
|
230
321
|
|
|
231
322
|
case 'migrate': {
|
|
232
|
-
const fromProject = hasFlag(args, '--
|
|
323
|
+
const fromProject = hasFlag(args, '--promote', '-p');
|
|
233
324
|
const result = await migrateAgentsSkillsToSkillbase({
|
|
234
325
|
force: hasFlag(args, '--force', '-f'),
|
|
235
326
|
fromProject
|
|
236
327
|
});
|
|
237
|
-
console.log(
|
|
238
|
-
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
|
+
|
|
239
332
|
if (result.migrated.length) {
|
|
240
|
-
console.log(
|
|
241
|
-
|
|
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)}`));
|
|
242
336
|
}
|
|
243
337
|
if (result.skipped.length) {
|
|
244
|
-
console.log(
|
|
245
|
-
|
|
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 || '??' }));
|
|
246
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`);
|
|
247
364
|
return;
|
|
248
365
|
}
|
|
249
366
|
|
|
250
367
|
default:
|
|
251
|
-
throw new Error(
|
|
368
|
+
throw new Error(t('UNKNOWN_COMMAND', { cmd: command }));
|
|
252
369
|
}
|
|
253
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
|
}
|