code-ai-installer 1.1.4 → 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.
Files changed (79) hide show
  1. package/README.md +4 -0
  2. package/dist/banner.d.ts +4 -0
  3. package/dist/banner.js +35 -0
  4. package/dist/index.js +109 -22
  5. package/dist/sourceResolver.d.ts +2 -0
  6. package/dist/sourceResolver.js +27 -5
  7. package/dist/types.d.ts +1 -0
  8. package/locales/en/.agents/a11y_baseline/SKILL.md +41 -0
  9. package/locales/en/.agents/adr_log/SKILL.md +69 -0
  10. package/locales/en/.agents/api_contract_compliance_review/SKILL.md +18 -0
  11. package/locales/en/.agents/api_contracts/SKILL.md +42 -0
  12. package/locales/en/.agents/architecture_compliance_review/SKILL.md +17 -0
  13. package/locales/en/.agents/architecture_doc/SKILL.md +92 -0
  14. package/locales/en/.agents/board/SKILL.md +43 -0
  15. package/locales/en/.agents/cloud_infrastructure_security/SKILL.md +68 -0
  16. package/locales/en/.agents/code_review_checklist/SKILL.md +47 -0
  17. package/locales/en/.agents/current_state_analysis/SKILL.md +44 -0
  18. package/locales/en/.agents/data_model/SKILL.md +40 -0
  19. package/locales/en/.agents/dependency_supply_chain_review/SKILL.md +20 -0
  20. package/locales/en/.agents/deployment_ci_plan/SKILL.md +51 -0
  21. package/locales/en/.agents/design_intake/SKILL.md +71 -0
  22. package/locales/en/.agents/design_parity_review/SKILL.md +73 -0
  23. package/locales/en/.agents/design_systems/SKILL.md +15 -0
  24. package/locales/en/.agents/dev_reference_snippets/SKILL.md +397 -0
  25. package/locales/en/.agents/docker_kubernetes_architecture/SKILL.md +144 -0
  26. package/locales/en/.agents/es2025_beast_practices/SKILL.md +15 -0
  27. package/locales/en/.agents/gates/SKILL.md +35 -0
  28. package/locales/en/.agents/go_beast_practices/SKILL.md +23 -0
  29. package/locales/en/.agents/handoff/SKILL.md +52 -0
  30. package/locales/en/.agents/k8s_manifests_conventions/SKILL.md +175 -0
  31. package/locales/en/.agents/memory/SKILL.md +29 -0
  32. package/locales/en/.agents/mongodb_mongoose_best_practices/SKILL.md +233 -0
  33. package/locales/en/.agents/node_express_beast_practices/SKILL.md +30 -0
  34. package/locales/en/.agents/observability_logging/SKILL.md +16 -0
  35. package/locales/en/.agents/observability_plan/SKILL.md +38 -0
  36. package/locales/en/.agents/observability_review/SKILL.md +20 -0
  37. package/locales/en/.agents/performance_review_baseline/SKILL.md +17 -0
  38. package/locales/en/.agents/pm_backlog/SKILL.md +32 -0
  39. package/locales/en/.agents/pm_interview/SKILL.md +56 -0
  40. package/locales/en/.agents/pm_prd/SKILL.md +56 -0
  41. package/locales/en/.agents/qa_api_contract_tests/SKILL.md +16 -0
  42. package/locales/en/.agents/qa_e2e_playwright/SKILL.md +0 -0
  43. package/locales/en/.agents/qa_manual_run/SKILL.md +16 -0
  44. package/locales/en/.agents/qa_security_smoke_tests/SKILL.md +14 -0
  45. package/locales/en/.agents/qa_test_plan/SKILL.md +20 -0
  46. package/locales/en/.agents/qa_ui_a11y_smoke/SKILL.md +12 -0
  47. package/locales/en/.agents/react_15_3_wix_iframe/SKILL.md +20 -0
  48. package/locales/en/.agents/react_beast_practices/SKILL.md +29 -0
  49. package/locales/en/.agents/release_gate/SKILL.md +77 -0
  50. package/locales/en/.agents/release_gate_checklist_template/SKILL.md +68 -0
  51. package/locales/en/.agents/review_reference_snippets/SKILL.md +436 -0
  52. package/locales/en/.agents/security_baseline_dev/SKILL.md +16 -0
  53. package/locales/en/.agents/security_review/SKILL.md +55 -0
  54. package/locales/en/.agents/security_review_baseline/SKILL.md +25 -0
  55. package/locales/en/.agents/state_rtk_beast_practices/SKILL.md +15 -0
  56. package/locales/en/.agents/state_zustand_beast_practices/SKILL.md +11 -0
  57. package/locales/en/.agents/styling_css_stack/SKILL.md +12 -0
  58. package/locales/en/.agents/system_design_checklist/SKILL.md +48 -0
  59. package/locales/en/.agents/tanstack_beast_practices/SKILL.md +19 -0
  60. package/locales/en/.agents/tdd_workflow/SKILL.md +34 -0
  61. package/locales/en/.agents/testing_strategy_js/SKILL.md +30 -0
  62. package/locales/en/.agents/tests_quality_review/SKILL.md +18 -0
  63. package/locales/en/.agents/threat_model_baseline/SKILL.md +57 -0
  64. package/locales/en/.agents/tooling_bun_biome/SKILL.md +17 -0
  65. package/locales/en/.agents/typescript_beast_practices/SKILL.md +15 -0
  66. package/locales/en/.agents/ui_a11y_smoke_review/SKILL.md +15 -0
  67. package/locales/en/.agents/ui_inventory/SKILL.md +50 -0
  68. package/locales/en/.agents/ux_discovery/SKILL.md +48 -0
  69. package/locales/en/.agents/ux_spec/SKILL.md +56 -0
  70. package/locales/en/.agents/wix_self_hosted_embedded_script/SKILL.md +88 -0
  71. package/locales/en/AGENTS.md +120 -0
  72. package/locales/en/agents/architect.md +239 -0
  73. package/locales/en/agents/conductor.md +205 -0
  74. package/locales/en/agents/product_manager.md +119 -0
  75. package/locales/en/agents/reviewer.md +200 -0
  76. package/locales/en/agents/senior_full_stack.md +216 -0
  77. package/locales/en/agents/tester.md +186 -0
  78. package/locales/en/agents/ux_ui_designer.md +144 -0
  79. package/package.json +3 -2
package/README.md CHANGED
@@ -47,12 +47,15 @@ code-ai targets
47
47
 
48
48
  # list available agents and skills from current repository
49
49
  code-ai list
50
+ code-ai list --lang en
50
51
 
51
52
  # health checks
52
53
  code-ai doctor --target claude
54
+ code-ai doctor --target claude --lang en
53
55
 
54
56
  # dry-run install (default)
55
57
  code-ai install --target claude --agents conductor,reviewer --skills board,security_review
58
+ code-ai install --target claude --lang en --agents conductor,reviewer --skills board,security_review
56
59
 
57
60
  # install into a newly created folder under current directory
58
61
  code-ai install --target gpt-codex --create-dir my-new-project --agents all --skills all --apply
@@ -99,3 +102,4 @@ code-ai uninstall --target claude --apply
99
102
  - Target aliases are accepted: `copilot`, `codex`, `claude`, `qwen`, `google`, `antigravity`.
100
103
  - If your AI tool requires a custom location, pass `--destination <path>`.
101
104
  - Source templates are resolved automatically: current directory first, bundled package templates second.
105
+ - Template language is selectable via `--lang ru|en` (default: `ru`).
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Prints CODE-AI startup banner with green gradient.
3
+ */
4
+ export declare function printBanner(): void;
package/dist/banner.js ADDED
@@ -0,0 +1,35 @@
1
+ import chalk from "chalk";
2
+ const CODE_AI_ASCII = [
3
+ " ██████╗ ██████╗ ██████╗ ███████╗ █████╗ ██╗",
4
+ " ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔══██╗██║",
5
+ " ██║ ██║ ██║██║ ██║█████╗ ███████║██║",
6
+ " ██║ ██║ ██║██║ ██║██╔══╝ ██╔══██║██║",
7
+ " ╚██████╗╚██████╔╝██████╔╝███████╗ ██║ ██║██║",
8
+ " ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝╚═╝",
9
+ ];
10
+ /**
11
+ * Prints CODE-AI startup banner with green gradient.
12
+ */
13
+ export function printBanner() {
14
+ const width = Math.max(...CODE_AI_ASCII.map((line) => line.length));
15
+ const start = { r: 64, g: 224, b: 128 };
16
+ const end = { r: 16, g: 120, b: 72 };
17
+ for (let row = 0; row < CODE_AI_ASCII.length; row += 1) {
18
+ const line = CODE_AI_ASCII[row];
19
+ let out = "";
20
+ for (let i = 0; i < line.length; i += 1) {
21
+ const ch = line[i];
22
+ if (ch === " ") {
23
+ out += ch;
24
+ continue;
25
+ }
26
+ const t = width <= 1 ? 0 : i / (width - 1);
27
+ const r = Math.round(start.r + (end.r - start.r) * t);
28
+ const g = Math.round(start.g + (end.g - start.g) * t);
29
+ const b = Math.round(start.b + (end.b - start.b) * t);
30
+ out += chalk.rgb(r, g, b)(ch);
31
+ }
32
+ process.stdout.write(`${out}\n`);
33
+ }
34
+ process.stdout.write(`${chalk.green("Code-AI installer wizard")}\n\n`);
35
+ }
package/dist/index.js CHANGED
@@ -9,8 +9,55 @@ import { runInstall, runUninstall } from "./installer.js";
9
9
  import { error, info, success, warn } from "./logger.js";
10
10
  import { getPlatformAdapters } from "./platforms/adapters.js";
11
11
  import { resolveSourceRoot } from "./sourceResolver.js";
12
+ import { printBanner } from "./banner.js";
12
13
  const program = new Command();
13
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
+ };
14
61
  program
15
62
  .name("code-ai")
16
63
  .description("Install code-ai agents and skills for AI coding assistants")
@@ -29,12 +76,15 @@ program
29
76
  .command("list")
30
77
  .description("List available bundled agents and skills")
31
78
  .option("--project-dir <path>", "Optional custom source root path")
79
+ .option("--lang <lang>", "Template language: ru | en", "ru")
32
80
  .action(async (options) => {
33
81
  try {
82
+ const language = normalizeLanguage(options.lang);
34
83
  const projectDir = await resolveSourceRoot({
35
84
  projectDirOption: options.projectDir,
36
85
  cwd: process.cwd(),
37
86
  packageRoot,
87
+ language,
38
88
  });
39
89
  const catalog = await loadSourceCatalog(projectDir);
40
90
  const agents = listAgentNames(catalog);
@@ -54,13 +104,16 @@ program
54
104
  .requiredOption("--target <id>", "Target AI id")
55
105
  .option("--project-dir <path>", "Optional custom source root path")
56
106
  .option("--destination <path>", "Destination root (default: current directory)")
107
+ .option("--lang <lang>", "Template language: ru | en", "ru")
57
108
  .action(async (options) => {
58
109
  try {
59
110
  const target = normalizeTarget(options.target);
111
+ const language = normalizeLanguage(options.lang);
60
112
  const projectDir = await resolveSourceRoot({
61
113
  projectDirOption: options.projectDir,
62
114
  cwd: process.cwd(),
63
115
  packageRoot,
116
+ language,
64
117
  });
65
118
  const destinationDir = path.resolve(options.destination ?? process.cwd());
66
119
  const report = await runDoctor(projectDir, destinationDir, target);
@@ -93,6 +146,7 @@ program
93
146
  .option("--project-dir <path>", "Optional custom source root path")
94
147
  .option("--destination <path>", "Destination root (default: current directory)")
95
148
  .option("--create-dir <name>", "Create child folder in current directory and install there")
149
+ .option("--lang <lang>", "Template language: ru | en", "ru")
96
150
  .option("--agents <list>", "Comma list of agents or 'all'", "all")
97
151
  .option("--skills <list>", "Comma list of skills or 'all'", "all")
98
152
  .option("--overwrite", "Overwrite existing files", false)
@@ -101,10 +155,12 @@ program
101
155
  .action(async (options) => {
102
156
  try {
103
157
  const target = normalizeTarget(options.target);
158
+ const language = normalizeLanguage(options.lang);
104
159
  const projectDir = await resolveSourceRoot({
105
160
  projectDirOption: options.projectDir,
106
161
  cwd: process.cwd(),
107
162
  packageRoot,
163
+ language,
108
164
  });
109
165
  const baseDestination = path.resolve(options.destination ?? process.cwd());
110
166
  const destinationDir = options.createDir ? path.join(baseDestination, options.createDir) : baseDestination;
@@ -185,16 +241,35 @@ program
185
241
  * Runs interactive installer workflow when no subcommand is provided.
186
242
  */
187
243
  async function runInteractiveWizard() {
244
+ printBanner();
245
+ const bootstrapText = WIZARD_TEXT.en;
246
+ const languageAnswer = await prompts({
247
+ type: "select",
248
+ name: "language",
249
+ message: bootstrapText.selectTemplateLanguage,
250
+ choices: [
251
+ { title: bootstrapText.languageEn, value: "en" },
252
+ { title: bootstrapText.languageRu, value: "ru" },
253
+ ],
254
+ initial: 0,
255
+ });
256
+ if (!languageAnswer.language) {
257
+ warn(bootstrapText.cancelled);
258
+ return;
259
+ }
260
+ const language = normalizeLanguage(languageAnswer.language);
261
+ const text = WIZARD_TEXT[language];
188
262
  const sourceRoot = await resolveSourceRoot({
189
263
  cwd: process.cwd(),
190
264
  packageRoot,
265
+ language,
191
266
  });
192
267
  const catalog = await loadSourceCatalog(sourceRoot);
193
268
  const adapters = getPlatformAdapters();
194
269
  const targetAnswer = await prompts({
195
270
  type: "select",
196
271
  name: "target",
197
- message: "Выбери AI для установки:",
272
+ message: text.selectAiTarget,
198
273
  choices: adapters.map((adapter) => ({
199
274
  title: `${adapter.label} (${adapter.id})`,
200
275
  value: adapter.id,
@@ -202,20 +277,20 @@ async function runInteractiveWizard() {
202
277
  })),
203
278
  });
204
279
  if (!targetAnswer.target) {
205
- warn("Установка отменена.");
280
+ warn(text.cancelled);
206
281
  return;
207
282
  }
208
283
  const destinationModeAnswer = await prompts({
209
284
  type: "select",
210
285
  name: "mode",
211
- message: "Куда устанавливать?",
286
+ message: text.installWhere,
212
287
  choices: [
213
- { title: "Текущая папка", value: "current" },
214
- { title: "Новая папка", value: "new" },
288
+ { title: text.currentFolder, value: "current" },
289
+ { title: text.newFolder, value: "new" },
215
290
  ],
216
291
  });
217
292
  if (!destinationModeAnswer.mode) {
218
- warn("Установка отменена.");
293
+ warn(text.cancelled);
219
294
  return;
220
295
  }
221
296
  let destinationDir = process.cwd();
@@ -223,11 +298,11 @@ async function runInteractiveWizard() {
223
298
  const newFolderAnswer = await prompts({
224
299
  type: "text",
225
300
  name: "folderName",
226
- message: "Название новой папки:",
227
- validate: (value) => (value.trim().length === 0 ? "Укажи название папки" : true),
301
+ message: text.newFolderName,
302
+ validate: (value) => (value.trim().length === 0 ? text.newFolderNameRequired : true),
228
303
  });
229
304
  if (!newFolderAnswer.folderName) {
230
- warn("Установка отменена.");
305
+ warn(text.cancelled);
231
306
  return;
232
307
  }
233
308
  destinationDir = path.join(process.cwd(), String(newFolderAnswer.folderName).trim());
@@ -237,32 +312,32 @@ async function runInteractiveWizard() {
237
312
  const agentsAnswer = await prompts({
238
313
  type: "multiselect",
239
314
  name: "selectedAgents",
240
- message: "Выбери агентов:",
315
+ message: text.selectAgents,
241
316
  choices: agents.map((agentName) => ({ title: agentName, value: agentName, selected: true })),
242
317
  min: 1,
243
- hint: "space: выбрать, enter: подтвердить",
318
+ hint: text.selectHint,
244
319
  });
245
320
  if (!agentsAnswer.selectedAgents || agentsAnswer.selectedAgents.length === 0) {
246
- warn("Установка отменена.");
321
+ warn(text.cancelled);
247
322
  return;
248
323
  }
249
324
  const skillsAnswer = await prompts({
250
325
  type: "multiselect",
251
326
  name: "selectedSkills",
252
- message: "Выбери skills:",
327
+ message: text.selectSkills,
253
328
  choices: skills.map((skillName) => ({ title: skillName, value: skillName, selected: true })),
254
329
  min: 1,
255
- hint: "space: выбрать, enter: подтвердить",
330
+ hint: text.selectHint,
256
331
  });
257
332
  if (!skillsAnswer.selectedSkills || skillsAnswer.selectedSkills.length === 0) {
258
- warn("Установка отменена.");
333
+ warn(text.cancelled);
259
334
  return;
260
335
  }
261
336
  const optionsAnswer = await prompts([
262
337
  {
263
338
  type: "toggle",
264
339
  name: "overwrite",
265
- message: "Перезаписывать существующие файлы?",
340
+ message: text.overwritePrompt,
266
341
  initial: false,
267
342
  active: "yes",
268
343
  inactive: "no",
@@ -270,7 +345,7 @@ async function runInteractiveWizard() {
270
345
  {
271
346
  type: "toggle",
272
347
  name: "apply",
273
- message: "Сразу выполнить установку?",
348
+ message: text.applyPrompt,
274
349
  initial: true,
275
350
  active: "yes",
276
351
  inactive: "no",
@@ -278,14 +353,14 @@ async function runInteractiveWizard() {
278
353
  {
279
354
  type: "toggle",
280
355
  name: "strictHints",
281
- message: "Требовать явные target-hints в agent/skill файлах?",
356
+ message: text.strictHintsPrompt,
282
357
  initial: false,
283
358
  active: "yes",
284
359
  inactive: "no",
285
360
  },
286
361
  ]);
287
362
  const target = targetAnswer.target;
288
- info("Запускаю doctor перед установкой...");
363
+ info(text.runDoctor);
289
364
  const doctor = await runDoctor(sourceRoot, destinationDir, target);
290
365
  for (const line of doctor.info) {
291
366
  info(line);
@@ -297,12 +372,12 @@ async function runInteractiveWizard() {
297
372
  error(line);
298
373
  }
299
374
  if (doctor.errors.length > 0) {
300
- throw new Error("Doctor не пройден. Исправь ошибки и запусти снова.");
375
+ throw new Error(text.doctorFailed);
301
376
  }
302
377
  const dryRun = !Boolean(optionsAnswer.apply);
303
378
  const overwriteMode = optionsAnswer.overwrite ? "overwrite" : "skip";
304
379
  if (dryRun) {
305
- warn("Выбран preview-режим без записи файлов.");
380
+ warn(text.dryRunMode);
306
381
  }
307
382
  const { state, result } = await runInstall({
308
383
  target,
@@ -320,7 +395,7 @@ async function runInteractiveWizard() {
320
395
  info(`Files planned: ${result.plannedFiles.length}`);
321
396
  if (dryRun) {
322
397
  info(`Files would write: ${result.writtenFiles.length}`);
323
- success("Preview completed.");
398
+ success(text.previewCompleted);
324
399
  }
325
400
  else {
326
401
  info(`Files written: ${result.writtenFiles.length}`);
@@ -358,6 +433,18 @@ function normalizeTarget(rawTarget) {
358
433
  }
359
434
  return normalized;
360
435
  }
436
+ /**
437
+ * Normalizes template language code.
438
+ * @param rawLanguage Raw language value.
439
+ * @returns Normalized template language.
440
+ */
441
+ function normalizeLanguage(rawLanguage) {
442
+ const value = rawLanguage.trim().toLowerCase();
443
+ if (value === "ru" || value === "en") {
444
+ return value;
445
+ }
446
+ throw new Error(`Unsupported language '${rawLanguage}'. Use 'ru' or 'en'.`);
447
+ }
361
448
  if (process.argv.length <= 2) {
362
449
  runInteractiveWizard().catch((err) => {
363
450
  error(err.message);
@@ -1,3 +1,4 @@
1
+ import type { TemplateLanguage } from "./types.js";
1
2
  /**
2
3
  * Resolves source root with agent templates.
3
4
  * @param args Resolution arguments.
@@ -7,4 +8,5 @@ export declare function resolveSourceRoot(args: {
7
8
  projectDirOption?: string;
8
9
  cwd: string;
9
10
  packageRoot: string;
11
+ language: TemplateLanguage;
10
12
  }): Promise<string>;
@@ -13,13 +13,23 @@ export async function resolveSourceRoot(args) {
13
13
  }
14
14
  throw new Error(`Invalid --project-dir: ${explicitPath}. Required: AGENTS.md, agents/, and .agents/.`);
15
15
  }
16
+ const bundledPath = getBundledPath(args.packageRoot, args.language);
16
17
  const cwdPath = path.resolve(args.cwd);
17
- if (await isValidSourceRoot(cwdPath)) {
18
- return cwdPath;
18
+ if (args.language === "en") {
19
+ if (await isValidSourceRoot(bundledPath)) {
20
+ return bundledPath;
21
+ }
22
+ if (await isValidSourceRoot(cwdPath)) {
23
+ return cwdPath;
24
+ }
19
25
  }
20
- const bundledPath = path.resolve(args.packageRoot);
21
- if (await isValidSourceRoot(bundledPath)) {
22
- return bundledPath;
26
+ else {
27
+ if (await isValidSourceRoot(cwdPath)) {
28
+ return cwdPath;
29
+ }
30
+ if (await isValidSourceRoot(bundledPath)) {
31
+ return bundledPath;
32
+ }
23
33
  }
24
34
  throw new Error(`Could not find source templates in current directory or bundled package. Checked: ${cwdPath} and ${bundledPath}`);
25
35
  }
@@ -34,3 +44,15 @@ async function isValidSourceRoot(rootDir) {
34
44
  const dotAgentsDir = path.join(rootDir, ".agents");
35
45
  return (await fs.pathExists(orchestratorPath)) && (await fs.pathExists(agentsDir)) && (await fs.pathExists(dotAgentsDir));
36
46
  }
47
+ /**
48
+ * Returns bundled templates root for selected language.
49
+ * @param packageRoot Installed package root.
50
+ * @param language Template language.
51
+ * @returns Absolute bundled source path.
52
+ */
53
+ function getBundledPath(packageRoot, language) {
54
+ if (language === "en") {
55
+ return path.resolve(packageRoot, "locales", "en");
56
+ }
57
+ return path.resolve(packageRoot);
58
+ }
package/dist/types.d.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  * Supported AI target identifiers.
3
3
  */
4
4
  export type TargetId = "vscode-copilot" | "claude" | "qwen-3.5" | "google-antugravity" | "gpt-codex";
5
+ export type TemplateLanguage = "ru" | "en";
5
6
  /**
6
7
  * Defines one source file and destination path copy action.
7
8
  */
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: a11y_baseline
3
+ description: Minimum baseline accessibility for web UI: keyboard navigation, focus management, form labels, ARIA for interactive components, error messages.
4
+ ---
5
+
6
+ #Skill: A11y Baseline (minimum)
7
+
8
+ ## Goal
9
+ Set minimum accessibility requirements that can be tested and implemented in the MVP.
10
+
11
+ ## Exit
12
+ List of a11y requirements for the project + notes on key components.
13
+
14
+ ## Minimum Requirements (MVP)
15
+ 1) **Keyboard navigation**
16
+ - All interactive elements are accessible from the keyboard
17
+ - Tab order is logical
18
+ - No trick traps
19
+
20
+ 2) **Focus states**
21
+ - Visible focus for all interactive elements
22
+ - In modals: focus moves inside and returns back when closed
23
+
24
+ 3) **Forms**
25
+ - Each field has a label (visible or aria-label)
26
+ - Errors are assigned to a field (the error description is read by assistive technologies)
27
+ - Required fields are marked and clear
28
+
29
+ 4) **ARIA (where needed)**
30
+ - Dialog: role="dialog" + aria-modal
31
+ - Tabs, dropdowns, comboboxes - correct roles/attributes (if we use custom ones)
32
+
33
+ 5) **Error messaging**
34
+ - Errors are clear, without “unknown error”
35
+ - There are actions: retry/close/fix
36
+
37
+ ## Receipt for tester
38
+ - You can go through key flows without a mouse
39
+ - In modal, focus does not leak
40
+ - Forms announce label/errors
41
+ - Custom components have ARIA and work with assistive technologies
@@ -0,0 +1,69 @@
1
+ ---
2
+ name:adr_log
3
+ description: Record key architectural decisions (ADR) with trade-offs: Pros/Cons/Alternatives/Decision, status and date.
4
+ ---
5
+
6
+ #Skill: ADR Log
7
+
8
+ ## Goal
9
+ Don’t lose track of “why we did this” and simplify review/support.
10
+
11
+ ## When to use
12
+ - For every non-trivial choice: database, auth, cache, module structure, API format, error strategy, queues, search, deployment, integrations, etc.
13
+
14
+ ## ADR format (required)
15
+ # ADR-XXX: <Name>
16
+
17
+ ## Context
18
+ <why is this necessary, what are the limitations, what hurts>
19
+
20
+ ##Decision
21
+ <what you chose and how exactly>
22
+
23
+ ## Consequences
24
+ ### Positive
25
+ - ...
26
+ ###Negative
27
+ - ...
28
+
29
+ ## Alternatives Considered
30
+ - **A**: ...
31
+ - **B**: ...
32
+
33
+ ##Status
34
+ Proposed / Accepted / Deprecated
35
+
36
+ ##Date
37
+ YYYY-MM-DD
38
+
39
+ ## Requirements (strict)
40
+ - For each ADR there must be explicit Pros/Cons/Alternatives and rationale of choice.
41
+ - If the decision affects security/data/cost, be sure to describe the consequences.
42
+ - ADR should be short and specific: without water, but with key arguments.
43
+
44
+ ## Example (short)
45
+ # ADR-001: Selecting the main database
46
+
47
+ ##Context
48
+ You need to store users/sessions/orders. Transactions and complex queries are needed. Expected growth to 100K users.
49
+
50
+ ##Decision
51
+ We use PostgreSQL as the main database.
52
+
53
+ ## Consequences
54
+ ### Positive
55
+ - ACID transactions
56
+ - Rich queries and indexing
57
+ ###Negative
58
+ - Possible need for scaling during growth
59
+ - Operational costs for administration
60
+
61
+ ## Alternatives Considered
62
+ - **MongoDB**: weaker in transactional/complex join scenarios
63
+ - **DynamoDB**: vendor lock-in, more difficult to test locally
64
+
65
+ ##Status
66
+ Accepted
67
+
68
+ ##Date
69
+ 2025-01-15
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: api_contract_compliance_review
3
+ description: Checking the compliance of the API implementation with contracts: schemes, error codes, validation, authorization, idempotency, pagination.
4
+ ---
5
+
6
+ # Skill: API Contract Compliance Review
7
+
8
+ ## Check
9
+ - Endpoints correspond to API Contracts (method/path/request/response)
10
+ - Errors: status + error_code + safe message
11
+ - Border Validation (422 or accepted policy)
12
+ - 401 vs 403 correct
13
+ - Pagination/filters/sorting are implemented if UX is required
14
+ - Idempotency for risky operations (if it was in the contract/ADR)
15
+
16
+ ## Exit
17
+ - Inconsistencies for each endpoint
18
+ - Recommendations (pointwise)
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: api_contracts
3
+ description: API contracts for UX flows: endpoints, schemas, errors, validation, authorization, perf/scalability considerations, idempotency and integration patterns.
4
+ ---
5
+
6
+ # Skill: API Contracts
7
+
8
+ ## Goal
9
+ Make the API predictable, safe and efficient for the client and tests.
10
+
11
+ ## Inputs
12
+ - UX Spec (screens/actions/states)
13
+ - PRD (acceptance criteria)
14
+ - Roles/permissions
15
+
16
+ ## Exit
17
+ ### General rules
18
+ - Unified error format (error_code, message, details)
19
+ - 401 vs 403 distinguish
20
+ - Validation at boundaries
21
+ - Pagination/filters/sorting - if the UI requires
22
+ - Idempotency for create/risk operations (where needed)
23
+ - Versioning (if the public API is expected to grow)
24
+
25
+ ### For each endpoint
26
+ - Method + Path
27
+ - AuthN/AuthZ: required? roles?
28
+ - Request schema (types + restrictions)
29
+ - Response schema
30
+ - Errors:
31
+ - status
32
+ - error_code
33
+ - safe message
34
+ - Perf/scalability notes:
35
+ - limits, pagination, batch, round-trips minimization
36
+
37
+ ### Integrations
38
+ - Webhooks/external APIs: retry/backoff, signature/verification, idempotency
39
+ - Async if justified (event-driven)
40
+
41
+ ## Trade-offs
42
+ If there are controversial areas (for example, CQRS/async), record them as ADR.
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: architecture_compliance_review
3
+ description: Checking code compliance with architecture/ADR: module boundaries, layers, dependencies, conventions, red flags.
4
+ ---
5
+
6
+ #Skill: Architecture Compliance Review
7
+
8
+ ## Check
9
+ - Compliance with modular boundaries (controller/service/repo or similar)
10
+ - Direction of dependencies (UI does not pull data directly, etc.)
11
+ - Lack of red flags: Big Ball of Mud, God Object, Tight Coupling, Magic
12
+ - New “solutions” are issued ADR (if they affect the database/cache/auth/contracts/integrations)
13
+
14
+ ## Exit
15
+ - Findings (P0/P1/P2)
16
+ - Recommendations for refactoring (pointwise)
17
+ - Is ADR required? (yes/no what to describe)