@cannbot-ai/install-helper 0.0.2-beta.10 → 0.0.2-beta.12

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 CHANGED
@@ -145,251 +145,6 @@ import { join as join2 } from "path";
145
145
  import { homedir } from "os";
146
146
  import { join } from "path";
147
147
  import { existsSync } from "fs";
148
- function detectTraeVariant() {
149
- const home = homedir();
150
- if (existsSync(join(home, ".trae-cn"))) return "ide";
151
- if (existsSync(join(home, ".marscode"))) return "plugin";
152
- if (existsSync(join(home, ".traecli"))) return "cli";
153
- return "unknown";
154
- }
155
- function getConfigRoot(tool, level, base) {
156
- const home = homedir();
157
- if (level === "global") {
158
- switch (tool) {
159
- case "opencode":
160
- return join(home, ".config", "opencode");
161
- case "claude":
162
- return join(home, ".claude");
163
- case "trae": {
164
- const variant = detectTraeVariant();
165
- switch (variant) {
166
- case "plugin":
167
- return join(home, ".marscode");
168
- case "cli":
169
- return join(home, ".traecli");
170
- default:
171
- return join(home, ".trae-cn");
172
- }
173
- }
174
- case "cursor":
175
- return join(home, ".cursor");
176
- case "copilot":
177
- return join(home, ".copilot");
178
- }
179
- }
180
- const baseDir = base || process.cwd();
181
- switch (tool) {
182
- case "opencode":
183
- return join(baseDir, ".opencode");
184
- case "claude":
185
- return join(baseDir, ".claude");
186
- case "trae": {
187
- const variant = detectTraeVariant();
188
- switch (variant) {
189
- case "plugin":
190
- return join(baseDir, ".marscode");
191
- case "cli":
192
- return join(baseDir, ".traecli");
193
- default:
194
- return join(baseDir, ".trae");
195
- }
196
- }
197
- case "cursor":
198
- return join(baseDir, ".cursor");
199
- case "copilot":
200
- return join(baseDir, ".github");
201
- }
202
- }
203
- function getConfigFileName(tool) {
204
- return tool === "claude" ? "CLAUDE.md" : "AGENTS.md";
205
- }
206
- function getSkillsDir(configRoot) {
207
- return join(configRoot, "skills");
208
- }
209
- function getAgentsDir(configRoot) {
210
- return join(configRoot, "agents");
211
- }
212
- function getManifestPath(configRoot) {
213
- return join(configRoot, "cannbot-manifest.json");
214
- }
215
- function getCannbotConfigDir() {
216
- return join(homedir(), ".cannbot");
217
- }
218
- function getCannbotRepoPath() {
219
- return join(getCannbotConfigDir(), "repo");
220
- }
221
-
222
- // src/core/detector.ts
223
- async function getCommandVersion(cmd, args = ["--version"]) {
224
- try {
225
- const result = await execa(cmd, args, { timeout: 5e3 });
226
- const output = result.stdout.trim();
227
- const match = output.match(/(\d+\.\d+\.\d+)/);
228
- return match ? match[1] : output.split("\n")[0];
229
- } catch {
230
- return void 0;
231
- }
232
- }
233
- async function getCommandPath(cmd) {
234
- try {
235
- const result = await execa("which", [cmd], { timeout: 5e3 });
236
- return result.stdout.trim();
237
- } catch {
238
- return void 0;
239
- }
240
- }
241
- async function detectOpenCode() {
242
- const path = await getCommandPath("opencode");
243
- if (!path) return void 0;
244
- const version = await getCommandVersion("opencode");
245
- return { name: "opencode", version, path };
246
- }
247
- async function detectClaude() {
248
- const path = await getCommandPath("claude");
249
- if (!path) return void 0;
250
- const version = await getCommandVersion("claude");
251
- return { name: "claude", version, path };
252
- }
253
- async function detectTrae() {
254
- const home = homedir2();
255
- const variant = detectTraeVariant();
256
- let path;
257
- if (variant === "ide" && existsSync2(join2(home, ".trae-cn"))) {
258
- path = join2(home, ".trae-cn");
259
- } else if (variant === "plugin" && existsSync2(join2(home, ".marscode"))) {
260
- path = join2(home, ".marscode");
261
- } else if (variant === "cli" && existsSync2(join2(home, ".traecli"))) {
262
- path = join2(home, ".traecli");
263
- } else if (variant === "unknown") {
264
- const cmdPath = await getCommandPath("trae");
265
- if (cmdPath) path = cmdPath;
266
- }
267
- if (!path) return void 0;
268
- return { name: "trae", version: variant, path };
269
- }
270
- async function detectCursor() {
271
- const path = await getCommandPath("cursor");
272
- if (path) {
273
- const version = await getCommandVersion("cursor");
274
- return { name: "cursor", version, path };
275
- }
276
- if (process.platform === "darwin") {
277
- const appPath = "/Applications/Cursor.app";
278
- if (existsSync2(appPath)) {
279
- return { name: "cursor", path: appPath };
280
- }
281
- }
282
- return void 0;
283
- }
284
- async function detectCopilot() {
285
- const path = await getCommandPath("gh");
286
- if (!path) return void 0;
287
- try {
288
- await execa("gh", ["extension", "list"], { timeout: 5e3 });
289
- return { name: "copilot", path };
290
- } catch {
291
- return void 0;
292
- }
293
- }
294
- async function detectTools() {
295
- const detectors = [
296
- detectOpenCode,
297
- detectClaude,
298
- detectTrae,
299
- detectCursor,
300
- detectCopilot
301
- ];
302
- const results = await Promise.allSettled(detectors.map((d) => d()));
303
- const tools = [];
304
- for (const result of results) {
305
- if (result.status === "fulfilled" && result.value) {
306
- tools.push(result.value);
307
- }
308
- }
309
- return tools;
310
- }
311
- function getToolDisplayName(tool) {
312
- const names = {
313
- opencode: "OpenCode",
314
- claude: "Claude Code",
315
- trae: "Trae",
316
- cursor: "Cursor",
317
- copilot: "GitHub Copilot"
318
- };
319
- return names[tool];
320
- }
321
- function getAllTools() {
322
- return ["opencode", "claude", "trae", "cursor", "copilot"];
323
- }
324
-
325
- // src/core/manifest.ts
326
- import { existsSync as existsSync3, readFileSync } from "fs";
327
- import { join as join3 } from "path";
328
- function readManifest(configRoot) {
329
- const manifestPath = getManifestPath(configRoot);
330
- if (existsSync3(manifestPath)) {
331
- try {
332
- const content = readFileSync(manifestPath, "utf-8");
333
- return JSON.parse(content);
334
- } catch {
335
- }
336
- }
337
- return null;
338
- }
339
- function readAllManifests(configRoot) {
340
- const manifests = [];
341
- const plugins = getAllPlugins();
342
- const standardPath = getManifestPath(configRoot);
343
- if (existsSync3(standardPath)) {
344
- try {
345
- const content = readFileSync(standardPath, "utf-8");
346
- manifests.push(JSON.parse(content));
347
- } catch {
348
- }
349
- }
350
- for (const plugin of plugins) {
351
- const pluginManifestPath = join3(configRoot, `${plugin.id}-manifest.json`);
352
- if (existsSync3(pluginManifestPath)) {
353
- try {
354
- const content = readFileSync(pluginManifestPath, "utf-8");
355
- manifests.push(JSON.parse(content));
356
- } catch {
357
- }
358
- }
359
- }
360
- return manifests;
361
- }
362
- function scanInstalled() {
363
- const plugins = getAllPlugins();
364
- const installed = [];
365
- const tools = ["opencode", "claude", "trae", "cursor", "copilot"];
366
- const levels = ["project", "global"];
367
- for (const tool of tools) {
368
- for (const level of levels) {
369
- const configRoot = getConfigRoot(tool, level);
370
- const manifests = readAllManifests(configRoot);
371
- for (const manifest of manifests) {
372
- const plugin = plugins.find((p) => p.id === manifest.team);
373
- if (!plugin) continue;
374
- const alreadyAdded = installed.some(
375
- (p) => p.id === plugin.id && p.tool === tool && p.level === level
376
- );
377
- if (alreadyAdded) continue;
378
- installed.push({
379
- id: plugin.id,
380
- displayName: plugin.displayName,
381
- tool,
382
- level,
383
- skillsCount: manifest.installed_skills?.length || 0,
384
- agentsCount: manifest.installed_agents?.length || 0,
385
- installTime: manifest.install_time,
386
- configRoot
387
- });
388
- }
389
- }
390
- }
391
- return installed;
392
- }
393
148
 
394
149
  // src/utils/i18n.ts
395
150
  var zh_CN = {
@@ -454,6 +209,8 @@ var zh_CN = {
454
209
  error_tool_not_found: "\u672A\u68C0\u6D4B\u5230\u4EFB\u4F55 AI \u7F16\u7A0B\u5DE5\u5177",
455
210
  error_plugin_not_found: "\u672A\u627E\u5230\u63D2\u4EF6",
456
211
  error_repo_not_found: "\u4ED3\u5E93\u672A\u627E\u5230",
212
+ error_invalid_tool: "\u6682\u4E0D\u652F\u6301\u7684 AI \u5DE5\u5177: {tool}\n\u652F\u6301\u7684\u5DE5\u5177: {tools}",
213
+ error_invalid_level: "\u6682\u4E0D\u652F\u6301\u7684\u5B89\u88C5\u7EA7\u522B: {level}\n\u652F\u6301\u7684\u7EA7\u522B: {levels}",
457
214
  quick_start: "\u542F\u52A8\u547D\u4EE4",
458
215
  quick_start_hint: "\u8BD5\u8BD5\u8F93\u5165: \u5E2E\u6211\u5F00\u53D1\u4E00\u4E2A Abs \u7B97\u5B50",
459
216
  skill_select_category: "\u9009\u62E9 Skill \u7C7B\u522B",
@@ -589,6 +346,8 @@ var en_US = {
589
346
  error_tool_not_found: "No AI coding tool detected",
590
347
  error_plugin_not_found: "Plugin not found",
591
348
  error_repo_not_found: "Repository not found",
349
+ error_invalid_tool: "Unsupported AI tool: {tool}\nSupported tools: {tools}",
350
+ error_invalid_level: "Unsupported install level: {level}\nSupported levels: {levels}",
592
351
  quick_start: "Launch command",
593
352
  quick_start_hint: "Try: help me develop an Abs operator",
594
353
  skill_select_category: "Select Skill category",
@@ -670,6 +429,279 @@ function t(key) {
670
429
  return currentLang === "zh_CN" ? zh_CN[key] : en_US[key];
671
430
  }
672
431
 
432
+ // src/utils/paths.ts
433
+ var VALID_TOOLS = ["opencode", "claude", "trae", "cursor", "copilot"];
434
+ var VALID_LEVELS = ["project", "global"];
435
+ function validateTool(tool) {
436
+ if (!VALID_TOOLS.includes(tool)) {
437
+ throw new Error(
438
+ t("error_invalid_tool").replace("{tool}", tool).replace("{tools}", VALID_TOOLS.join(", "))
439
+ );
440
+ }
441
+ return tool;
442
+ }
443
+ function validateLevel(level) {
444
+ if (!VALID_LEVELS.includes(level)) {
445
+ throw new Error(
446
+ t("error_invalid_level").replace("{level}", level).replace("{levels}", VALID_LEVELS.join(", "))
447
+ );
448
+ }
449
+ return level;
450
+ }
451
+ function detectTraeVariant() {
452
+ const home = homedir();
453
+ if (existsSync(join(home, ".trae-cn"))) return "ide";
454
+ if (existsSync(join(home, ".marscode"))) return "plugin";
455
+ if (existsSync(join(home, ".traecli"))) return "cli";
456
+ return "unknown";
457
+ }
458
+ function getConfigRoot(tool, level, base) {
459
+ const home = homedir();
460
+ if (level === "global") {
461
+ switch (tool) {
462
+ case "opencode":
463
+ return join(home, ".config", "opencode");
464
+ case "claude":
465
+ return join(home, ".claude");
466
+ case "trae": {
467
+ const variant = detectTraeVariant();
468
+ switch (variant) {
469
+ case "plugin":
470
+ return join(home, ".marscode");
471
+ case "cli":
472
+ return join(home, ".traecli");
473
+ default:
474
+ return join(home, ".trae-cn");
475
+ }
476
+ }
477
+ case "cursor":
478
+ return join(home, ".cursor");
479
+ case "copilot":
480
+ return join(home, ".copilot");
481
+ default:
482
+ throw new Error(
483
+ t("error_invalid_tool").replace("{tool}", tool).replace("{tools}", VALID_TOOLS.join(", "))
484
+ );
485
+ }
486
+ }
487
+ const baseDir = base || process.cwd();
488
+ switch (tool) {
489
+ case "opencode":
490
+ return join(baseDir, ".opencode");
491
+ case "claude":
492
+ return join(baseDir, ".claude");
493
+ case "trae": {
494
+ const variant = detectTraeVariant();
495
+ switch (variant) {
496
+ case "plugin":
497
+ return join(baseDir, ".marscode");
498
+ case "cli":
499
+ return join(baseDir, ".traecli");
500
+ default:
501
+ return join(baseDir, ".trae");
502
+ }
503
+ }
504
+ case "cursor":
505
+ return join(baseDir, ".cursor");
506
+ case "copilot":
507
+ return join(baseDir, ".github");
508
+ default:
509
+ throw new Error(
510
+ t("error_invalid_tool").replace("{tool}", tool).replace("{tools}", VALID_TOOLS.join(", "))
511
+ );
512
+ }
513
+ }
514
+ function getConfigFileName(tool) {
515
+ return tool === "claude" ? "CLAUDE.md" : "AGENTS.md";
516
+ }
517
+ function getSkillsDir(configRoot) {
518
+ return join(configRoot, "skills");
519
+ }
520
+ function getAgentsDir(configRoot) {
521
+ return join(configRoot, "agents");
522
+ }
523
+ function getManifestPath(configRoot) {
524
+ return join(configRoot, "cannbot-manifest.json");
525
+ }
526
+ function getCannbotConfigDir() {
527
+ return join(homedir(), ".cannbot");
528
+ }
529
+ function getCannbotRepoPath() {
530
+ return join(getCannbotConfigDir(), "repo");
531
+ }
532
+
533
+ // src/core/detector.ts
534
+ async function getCommandVersion(cmd, args = ["--version"]) {
535
+ try {
536
+ const result = await execa(cmd, args, { timeout: 5e3 });
537
+ const output = result.stdout.trim();
538
+ const match = output.match(/(\d+\.\d+\.\d+)/);
539
+ return match ? match[1] : output.split("\n")[0];
540
+ } catch {
541
+ return void 0;
542
+ }
543
+ }
544
+ async function getCommandPath(cmd) {
545
+ try {
546
+ const result = await execa("which", [cmd], { timeout: 5e3 });
547
+ return result.stdout.trim();
548
+ } catch {
549
+ return void 0;
550
+ }
551
+ }
552
+ async function detectOpenCode() {
553
+ const path = await getCommandPath("opencode");
554
+ if (!path) return void 0;
555
+ const version = await getCommandVersion("opencode");
556
+ return { name: "opencode", version, path };
557
+ }
558
+ async function detectClaude() {
559
+ const path = await getCommandPath("claude");
560
+ if (!path) return void 0;
561
+ const version = await getCommandVersion("claude");
562
+ return { name: "claude", version, path };
563
+ }
564
+ async function detectTrae() {
565
+ const home = homedir2();
566
+ const variant = detectTraeVariant();
567
+ let path;
568
+ if (variant === "ide" && existsSync2(join2(home, ".trae-cn"))) {
569
+ path = join2(home, ".trae-cn");
570
+ } else if (variant === "plugin" && existsSync2(join2(home, ".marscode"))) {
571
+ path = join2(home, ".marscode");
572
+ } else if (variant === "cli" && existsSync2(join2(home, ".traecli"))) {
573
+ path = join2(home, ".traecli");
574
+ } else if (variant === "unknown") {
575
+ const cmdPath = await getCommandPath("trae");
576
+ if (cmdPath) path = cmdPath;
577
+ }
578
+ if (!path) return void 0;
579
+ return { name: "trae", version: variant, path };
580
+ }
581
+ async function detectCursor() {
582
+ const path = await getCommandPath("cursor");
583
+ if (path) {
584
+ const version = await getCommandVersion("cursor");
585
+ return { name: "cursor", version, path };
586
+ }
587
+ if (process.platform === "darwin") {
588
+ const appPath = "/Applications/Cursor.app";
589
+ if (existsSync2(appPath)) {
590
+ return { name: "cursor", path: appPath };
591
+ }
592
+ }
593
+ return void 0;
594
+ }
595
+ async function detectCopilot() {
596
+ const path = await getCommandPath("gh");
597
+ if (!path) return void 0;
598
+ try {
599
+ await execa("gh", ["extension", "list"], { timeout: 5e3 });
600
+ return { name: "copilot", path };
601
+ } catch {
602
+ return void 0;
603
+ }
604
+ }
605
+ async function detectTools() {
606
+ const detectors = [
607
+ detectOpenCode,
608
+ detectClaude,
609
+ detectTrae,
610
+ detectCursor,
611
+ detectCopilot
612
+ ];
613
+ const results = await Promise.allSettled(detectors.map((d) => d()));
614
+ const tools = [];
615
+ for (const result of results) {
616
+ if (result.status === "fulfilled" && result.value) {
617
+ tools.push(result.value);
618
+ }
619
+ }
620
+ return tools;
621
+ }
622
+ function getToolDisplayName(tool) {
623
+ const names = {
624
+ opencode: "OpenCode",
625
+ claude: "Claude Code",
626
+ trae: "Trae",
627
+ cursor: "Cursor",
628
+ copilot: "GitHub Copilot"
629
+ };
630
+ return names[tool];
631
+ }
632
+ function getAllTools() {
633
+ return ["opencode", "claude", "trae", "cursor", "copilot"];
634
+ }
635
+
636
+ // src/core/manifest.ts
637
+ import { existsSync as existsSync3, readFileSync } from "fs";
638
+ import { join as join3 } from "path";
639
+ function readManifest(configRoot) {
640
+ const manifestPath = getManifestPath(configRoot);
641
+ if (existsSync3(manifestPath)) {
642
+ try {
643
+ const content = readFileSync(manifestPath, "utf-8");
644
+ return JSON.parse(content);
645
+ } catch {
646
+ }
647
+ }
648
+ return null;
649
+ }
650
+ function readAllManifests(configRoot) {
651
+ const manifests = [];
652
+ const plugins = getAllPlugins();
653
+ const standardPath = getManifestPath(configRoot);
654
+ if (existsSync3(standardPath)) {
655
+ try {
656
+ const content = readFileSync(standardPath, "utf-8");
657
+ manifests.push(JSON.parse(content));
658
+ } catch {
659
+ }
660
+ }
661
+ for (const plugin of plugins) {
662
+ const pluginManifestPath = join3(configRoot, `${plugin.id}-manifest.json`);
663
+ if (existsSync3(pluginManifestPath)) {
664
+ try {
665
+ const content = readFileSync(pluginManifestPath, "utf-8");
666
+ manifests.push(JSON.parse(content));
667
+ } catch {
668
+ }
669
+ }
670
+ }
671
+ return manifests;
672
+ }
673
+ function scanInstalled() {
674
+ const plugins = getAllPlugins();
675
+ const installed = [];
676
+ const tools = ["opencode", "claude", "trae", "cursor", "copilot"];
677
+ const levels = ["project", "global"];
678
+ for (const tool of tools) {
679
+ for (const level of levels) {
680
+ const configRoot = getConfigRoot(tool, level);
681
+ const manifests = readAllManifests(configRoot);
682
+ for (const manifest of manifests) {
683
+ const plugin = plugins.find((p) => p.id === manifest.team);
684
+ if (!plugin) continue;
685
+ const alreadyAdded = installed.some(
686
+ (p) => p.id === plugin.id && p.tool === tool && p.level === level
687
+ );
688
+ if (alreadyAdded) continue;
689
+ installed.push({
690
+ id: plugin.id,
691
+ displayName: plugin.displayName,
692
+ tool,
693
+ level,
694
+ skillsCount: manifest.installed_skills?.length || 0,
695
+ agentsCount: manifest.installed_agents?.length || 0,
696
+ installTime: manifest.install_time,
697
+ configRoot
698
+ });
699
+ }
700
+ }
701
+ }
702
+ return installed;
703
+ }
704
+
673
705
  // src/utils/logger.ts
674
706
  import chalk from "chalk";
675
707
  import ora from "ora";
@@ -2772,10 +2804,10 @@ async function installCommand(names, options) {
2772
2804
  }
2773
2805
  let tool2;
2774
2806
  if (options.tool) {
2775
- tool2 = options.tool;
2807
+ tool2 = validateTool(options.tool);
2776
2808
  } else {
2777
2809
  const detected = await selectToolWithDetection();
2778
- if (detected === "back") return;
2810
+ if (detected === "back" || detected === "cancel") return;
2779
2811
  tool2 = detected;
2780
2812
  }
2781
2813
  let step = 1;
@@ -2785,10 +2817,11 @@ async function installCommand(names, options) {
2785
2817
  const selectedSkills = await interactiveSkillSelect();
2786
2818
  if (selectedSkills === "back") {
2787
2819
  const redetected = await selectToolWithDetection();
2788
- if (redetected === "back") return;
2820
+ if (redetected === "back" || redetected === "cancel") return;
2789
2821
  tool2 = redetected;
2790
2822
  break;
2791
2823
  }
2824
+ if (selectedSkills === "cancel") return;
2792
2825
  if (selectedSkills.length === 0) {
2793
2826
  logger.info(t("install_no_skill_selected"));
2794
2827
  return;
@@ -2800,7 +2833,7 @@ async function installCommand(names, options) {
2800
2833
  const repoPath = await repoManager.ensureRepo();
2801
2834
  spinner.succeed("\u63D2\u4EF6\u6570\u636E\u52A0\u8F7D\u5B8C\u6210");
2802
2835
  logger.info(`${t("skill_install_progress")} ${chalk9.bold(names.length)} \u4E2A Skills...`);
2803
- const level2 = options.level || "project";
2836
+ const level2 = options.level ? validateLevel(options.level) : "project";
2804
2837
  const results = await installSkills(names, tool2, level2, repoPath);
2805
2838
  let successCount = 0;
2806
2839
  let failCount = 0;
@@ -2861,13 +2894,13 @@ async function installCommand(names, options) {
2861
2894
  }
2862
2895
  let tool;
2863
2896
  if (options.tool) {
2864
- tool = options.tool;
2897
+ tool = validateTool(options.tool);
2865
2898
  } else {
2866
2899
  const detected = await selectToolWithDetection();
2867
- if (detected === "back") return;
2900
+ if (detected === "back" || detected === "cancel") return;
2868
2901
  tool = detected;
2869
2902
  }
2870
- const level = options.level || "project";
2903
+ const level = options.level ? validateLevel(options.level) : "project";
2871
2904
  if (plugins.length > 0) {
2872
2905
  const configRoot = getConfigRoot(tool, level);
2873
2906
  const manifests = readAllManifests(configRoot);
@@ -2983,8 +3016,8 @@ async function installPlugins(pluginIds, tool, level, repoPath) {
2983
3016
  import { existsSync as existsSync13, unlinkSync as unlinkSync5, rmdirSync as rmdirSync2, readdirSync as readdirSync5, lstatSync as lstatSync4 } from "fs";
2984
3017
  import chalk10 from "chalk";
2985
3018
  async function uninstallCommand(names, options) {
2986
- const tool = options.tool || "opencode";
2987
- const level = options.level || "project";
3019
+ const tool = options.tool ? validateTool(options.tool) : "opencode";
3020
+ const level = options.level ? validateLevel(options.level) : "project";
2988
3021
  const plugins = [];
2989
3022
  const skills = [];
2990
3023
  for (const name of names) {
@@ -3098,13 +3131,13 @@ import chalk11 from "chalk";
3098
3131
  async function updateCommand(pluginNames, options) {
3099
3132
  let tool;
3100
3133
  if (options.tool) {
3101
- tool = options.tool;
3134
+ tool = validateTool(options.tool);
3102
3135
  } else {
3103
3136
  const detected = await selectToolWithDetection();
3104
- if (detected === "back") return;
3137
+ if (detected === "back" || detected === "cancel") return;
3105
3138
  tool = detected;
3106
3139
  }
3107
- const level = options.level || "project";
3140
+ const level = options.level ? validateLevel(options.level) : "project";
3108
3141
  let pluginsToUpdate = [];
3109
3142
  if (pluginNames.length === 0) {
3110
3143
  const configRoot = getConfigRoot(tool, level);
@@ -3263,7 +3296,7 @@ function createCLI() {
3263
3296
  setLanguage(config.language);
3264
3297
  }
3265
3298
  const program2 = new Command();
3266
- program2.name("install-helper").description("CANNBot Install Helper - Interactive installer for CANN operator development skills").version("0.0.2-beta.10");
3299
+ program2.name("install-helper").description("CANNBot Install Helper - Interactive installer for CANN operator development skills").version("0.0.2-beta.12");
3267
3300
  program2.command("init", { isDefault: false }).description("Run interactive installation wizard").action(async () => {
3268
3301
  await initCommand();
3269
3302
  });