code-ai-installer 1.1.5 → 1.1.6
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/dist/index.js +74 -26
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12,6 +12,52 @@ import { resolveSourceRoot } from "./sourceResolver.js";
|
|
|
12
12
|
import { printBanner } from "./banner.js";
|
|
13
13
|
const program = new Command();
|
|
14
14
|
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
|
+
const WIZARD_TEXT = {
|
|
16
|
+
en: {
|
|
17
|
+
cancelled: "Installation cancelled.",
|
|
18
|
+
selectTemplateLanguage: "Select template language:",
|
|
19
|
+
languageRu: "Russian (ru)",
|
|
20
|
+
languageEn: "English (en)",
|
|
21
|
+
selectAiTarget: "Select AI target:",
|
|
22
|
+
installWhere: "Where should files be installed?",
|
|
23
|
+
currentFolder: "Current folder",
|
|
24
|
+
newFolder: "New folder",
|
|
25
|
+
newFolderName: "New folder name:",
|
|
26
|
+
newFolderNameRequired: "Please provide folder name",
|
|
27
|
+
selectAgents: "Select agents:",
|
|
28
|
+
selectSkills: "Select skills:",
|
|
29
|
+
selectHint: "space: toggle, enter: submit",
|
|
30
|
+
overwritePrompt: "Overwrite existing files?",
|
|
31
|
+
applyPrompt: "Run installation now?",
|
|
32
|
+
strictHintsPrompt: "Enforce strict target-hint adaptation?",
|
|
33
|
+
runDoctor: "Running doctor before install...",
|
|
34
|
+
doctorFailed: "Doctor checks failed. Fix issues and run again.",
|
|
35
|
+
dryRunMode: "Preview mode selected (no file writes).",
|
|
36
|
+
previewCompleted: "Preview completed.",
|
|
37
|
+
},
|
|
38
|
+
ru: {
|
|
39
|
+
cancelled: "Установка отменена.",
|
|
40
|
+
selectTemplateLanguage: "Выбери язык шаблонов:",
|
|
41
|
+
languageRu: "Русский (ru)",
|
|
42
|
+
languageEn: "English (en)",
|
|
43
|
+
selectAiTarget: "Выбери AI для установки:",
|
|
44
|
+
installWhere: "Куда устанавливать?",
|
|
45
|
+
currentFolder: "Текущая папка",
|
|
46
|
+
newFolder: "Новая папка",
|
|
47
|
+
newFolderName: "Название новой папки:",
|
|
48
|
+
newFolderNameRequired: "Укажи название папки",
|
|
49
|
+
selectAgents: "Выбери агентов:",
|
|
50
|
+
selectSkills: "Выбери skills:",
|
|
51
|
+
selectHint: "space: выбрать, enter: подтвердить",
|
|
52
|
+
overwritePrompt: "Перезаписывать существующие файлы?",
|
|
53
|
+
applyPrompt: "Сразу выполнить установку?",
|
|
54
|
+
strictHintsPrompt: "Требовать явные target-hints в agent/skill файлах?",
|
|
55
|
+
runDoctor: "Запускаю doctor перед установкой...",
|
|
56
|
+
doctorFailed: "Doctor не пройден. Исправь ошибки и запусти снова.",
|
|
57
|
+
dryRunMode: "Выбран preview-режим без записи файлов.",
|
|
58
|
+
previewCompleted: "Preview completed.",
|
|
59
|
+
},
|
|
60
|
+
};
|
|
15
61
|
program
|
|
16
62
|
.name("code-ai")
|
|
17
63
|
.description("Install code-ai agents and skills for AI coding assistants")
|
|
@@ -196,21 +242,23 @@ program
|
|
|
196
242
|
*/
|
|
197
243
|
async function runInteractiveWizard() {
|
|
198
244
|
printBanner();
|
|
245
|
+
const bootstrapText = WIZARD_TEXT.en;
|
|
199
246
|
const languageAnswer = await prompts({
|
|
200
247
|
type: "select",
|
|
201
248
|
name: "language",
|
|
202
|
-
message:
|
|
249
|
+
message: bootstrapText.selectTemplateLanguage,
|
|
203
250
|
choices: [
|
|
204
|
-
{ title:
|
|
205
|
-
{ title:
|
|
251
|
+
{ title: bootstrapText.languageEn, value: "en" },
|
|
252
|
+
{ title: bootstrapText.languageRu, value: "ru" },
|
|
206
253
|
],
|
|
207
254
|
initial: 0,
|
|
208
255
|
});
|
|
209
256
|
if (!languageAnswer.language) {
|
|
210
|
-
warn(
|
|
257
|
+
warn(bootstrapText.cancelled);
|
|
211
258
|
return;
|
|
212
259
|
}
|
|
213
260
|
const language = normalizeLanguage(languageAnswer.language);
|
|
261
|
+
const text = WIZARD_TEXT[language];
|
|
214
262
|
const sourceRoot = await resolveSourceRoot({
|
|
215
263
|
cwd: process.cwd(),
|
|
216
264
|
packageRoot,
|
|
@@ -221,7 +269,7 @@ async function runInteractiveWizard() {
|
|
|
221
269
|
const targetAnswer = await prompts({
|
|
222
270
|
type: "select",
|
|
223
271
|
name: "target",
|
|
224
|
-
message:
|
|
272
|
+
message: text.selectAiTarget,
|
|
225
273
|
choices: adapters.map((adapter) => ({
|
|
226
274
|
title: `${adapter.label} (${adapter.id})`,
|
|
227
275
|
value: adapter.id,
|
|
@@ -229,20 +277,20 @@ async function runInteractiveWizard() {
|
|
|
229
277
|
})),
|
|
230
278
|
});
|
|
231
279
|
if (!targetAnswer.target) {
|
|
232
|
-
warn(
|
|
280
|
+
warn(text.cancelled);
|
|
233
281
|
return;
|
|
234
282
|
}
|
|
235
283
|
const destinationModeAnswer = await prompts({
|
|
236
284
|
type: "select",
|
|
237
285
|
name: "mode",
|
|
238
|
-
message:
|
|
286
|
+
message: text.installWhere,
|
|
239
287
|
choices: [
|
|
240
|
-
{ title:
|
|
241
|
-
{ title:
|
|
288
|
+
{ title: text.currentFolder, value: "current" },
|
|
289
|
+
{ title: text.newFolder, value: "new" },
|
|
242
290
|
],
|
|
243
291
|
});
|
|
244
292
|
if (!destinationModeAnswer.mode) {
|
|
245
|
-
warn(
|
|
293
|
+
warn(text.cancelled);
|
|
246
294
|
return;
|
|
247
295
|
}
|
|
248
296
|
let destinationDir = process.cwd();
|
|
@@ -250,11 +298,11 @@ async function runInteractiveWizard() {
|
|
|
250
298
|
const newFolderAnswer = await prompts({
|
|
251
299
|
type: "text",
|
|
252
300
|
name: "folderName",
|
|
253
|
-
message:
|
|
254
|
-
validate: (value) => (value.trim().length === 0 ?
|
|
301
|
+
message: text.newFolderName,
|
|
302
|
+
validate: (value) => (value.trim().length === 0 ? text.newFolderNameRequired : true),
|
|
255
303
|
});
|
|
256
304
|
if (!newFolderAnswer.folderName) {
|
|
257
|
-
warn(
|
|
305
|
+
warn(text.cancelled);
|
|
258
306
|
return;
|
|
259
307
|
}
|
|
260
308
|
destinationDir = path.join(process.cwd(), String(newFolderAnswer.folderName).trim());
|
|
@@ -264,32 +312,32 @@ async function runInteractiveWizard() {
|
|
|
264
312
|
const agentsAnswer = await prompts({
|
|
265
313
|
type: "multiselect",
|
|
266
314
|
name: "selectedAgents",
|
|
267
|
-
message:
|
|
315
|
+
message: text.selectAgents,
|
|
268
316
|
choices: agents.map((agentName) => ({ title: agentName, value: agentName, selected: true })),
|
|
269
317
|
min: 1,
|
|
270
|
-
hint:
|
|
318
|
+
hint: text.selectHint,
|
|
271
319
|
});
|
|
272
320
|
if (!agentsAnswer.selectedAgents || agentsAnswer.selectedAgents.length === 0) {
|
|
273
|
-
warn(
|
|
321
|
+
warn(text.cancelled);
|
|
274
322
|
return;
|
|
275
323
|
}
|
|
276
324
|
const skillsAnswer = await prompts({
|
|
277
325
|
type: "multiselect",
|
|
278
326
|
name: "selectedSkills",
|
|
279
|
-
message:
|
|
327
|
+
message: text.selectSkills,
|
|
280
328
|
choices: skills.map((skillName) => ({ title: skillName, value: skillName, selected: true })),
|
|
281
329
|
min: 1,
|
|
282
|
-
hint:
|
|
330
|
+
hint: text.selectHint,
|
|
283
331
|
});
|
|
284
332
|
if (!skillsAnswer.selectedSkills || skillsAnswer.selectedSkills.length === 0) {
|
|
285
|
-
warn(
|
|
333
|
+
warn(text.cancelled);
|
|
286
334
|
return;
|
|
287
335
|
}
|
|
288
336
|
const optionsAnswer = await prompts([
|
|
289
337
|
{
|
|
290
338
|
type: "toggle",
|
|
291
339
|
name: "overwrite",
|
|
292
|
-
message:
|
|
340
|
+
message: text.overwritePrompt,
|
|
293
341
|
initial: false,
|
|
294
342
|
active: "yes",
|
|
295
343
|
inactive: "no",
|
|
@@ -297,7 +345,7 @@ async function runInteractiveWizard() {
|
|
|
297
345
|
{
|
|
298
346
|
type: "toggle",
|
|
299
347
|
name: "apply",
|
|
300
|
-
message:
|
|
348
|
+
message: text.applyPrompt,
|
|
301
349
|
initial: true,
|
|
302
350
|
active: "yes",
|
|
303
351
|
inactive: "no",
|
|
@@ -305,14 +353,14 @@ async function runInteractiveWizard() {
|
|
|
305
353
|
{
|
|
306
354
|
type: "toggle",
|
|
307
355
|
name: "strictHints",
|
|
308
|
-
message:
|
|
356
|
+
message: text.strictHintsPrompt,
|
|
309
357
|
initial: false,
|
|
310
358
|
active: "yes",
|
|
311
359
|
inactive: "no",
|
|
312
360
|
},
|
|
313
361
|
]);
|
|
314
362
|
const target = targetAnswer.target;
|
|
315
|
-
info(
|
|
363
|
+
info(text.runDoctor);
|
|
316
364
|
const doctor = await runDoctor(sourceRoot, destinationDir, target);
|
|
317
365
|
for (const line of doctor.info) {
|
|
318
366
|
info(line);
|
|
@@ -324,12 +372,12 @@ async function runInteractiveWizard() {
|
|
|
324
372
|
error(line);
|
|
325
373
|
}
|
|
326
374
|
if (doctor.errors.length > 0) {
|
|
327
|
-
throw new Error(
|
|
375
|
+
throw new Error(text.doctorFailed);
|
|
328
376
|
}
|
|
329
377
|
const dryRun = !Boolean(optionsAnswer.apply);
|
|
330
378
|
const overwriteMode = optionsAnswer.overwrite ? "overwrite" : "skip";
|
|
331
379
|
if (dryRun) {
|
|
332
|
-
warn(
|
|
380
|
+
warn(text.dryRunMode);
|
|
333
381
|
}
|
|
334
382
|
const { state, result } = await runInstall({
|
|
335
383
|
target,
|
|
@@ -347,7 +395,7 @@ async function runInteractiveWizard() {
|
|
|
347
395
|
info(`Files planned: ${result.plannedFiles.length}`);
|
|
348
396
|
if (dryRun) {
|
|
349
397
|
info(`Files would write: ${result.writtenFiles.length}`);
|
|
350
|
-
success(
|
|
398
|
+
success(text.previewCompleted);
|
|
351
399
|
}
|
|
352
400
|
else {
|
|
353
401
|
info(`Files written: ${result.writtenFiles.length}`);
|