@cannbot-ai/install-helper 1.0.3 → 1.0.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 CHANGED
@@ -5,11 +5,11 @@ import { Command } from "commander";
5
5
 
6
6
  // src/commands/init.ts
7
7
  import { select as select4, Separator as Separator3 } from "@inquirer/prompts";
8
- import chalk6 from "chalk";
8
+ import chalk7 from "chalk";
9
9
 
10
10
  // src/ui/wizard.ts
11
11
  import { select, checkbox, Separator } from "@inquirer/prompts";
12
- import chalk2 from "chalk";
12
+ import chalk3 from "chalk";
13
13
 
14
14
  // src/core/registry.ts
15
15
  import { readdirSync, readFileSync } from "fs";
@@ -48,6 +48,9 @@ function loadPluginsFromYaml() {
48
48
  }
49
49
  } catch {
50
50
  }
51
+ plugins.sort(
52
+ (a, b) => a.displayName < b.displayName ? -1 : a.displayName > b.displayName ? 1 : 0
53
+ );
51
54
  return plugins;
52
55
  }
53
56
  var PLUGIN_REGISTRY = loadPluginsFromYaml();
@@ -545,16 +548,78 @@ function removeInstalledPlugin(pluginId) {
545
548
  }
546
549
 
547
550
  // src/ui/theme.ts
551
+ import chalk2 from "chalk";
548
552
  var selectTheme = {
549
553
  helpMode: "never"
550
554
  };
555
+ function isCJK(code) {
556
+ return code >= 11904 && code <= 40959 || code >= 63744 && code <= 64255 || code >= 65072 && code <= 65103 || code >= 65280 && code <= 65519 || code >= 13312 && code <= 19903 || code >= 131072 && code <= 173791 || code >= 173824 && code <= 177983 || code >= 177984 && code <= 178207 || code >= 178208 && code <= 183983;
557
+ }
558
+ function isEmoji(code) {
559
+ return code >= 127744 && code <= 129791 || code >= 9728 && code <= 10175;
560
+ }
561
+ function getDisplayWidth2(str) {
562
+ let width = 0;
563
+ for (const ch of str) {
564
+ const code = ch.codePointAt(0);
565
+ if (isCJK(code) || isEmoji(code)) {
566
+ width += 2;
567
+ } else {
568
+ width += 1;
569
+ }
570
+ }
571
+ return width;
572
+ }
573
+ function wrapDescription(text) {
574
+ const prefix = " \u{1F4A1} ";
575
+ const indent = " ";
576
+ const cols = process.stdout.columns || 120;
577
+ const maxLen = Math.max(20, cols - getDisplayWidth2(prefix) - 2);
578
+ const tokens = [];
579
+ let i = 0;
580
+ while (i < text.length) {
581
+ const code = text[i].codePointAt(0);
582
+ if (isCJK(code)) {
583
+ tokens.push({ text: text[i], width: 2 });
584
+ i++;
585
+ } else {
586
+ let j = i;
587
+ while (j < text.length) {
588
+ const c = text[j].codePointAt(0);
589
+ if (isCJK(c)) break;
590
+ j++;
591
+ }
592
+ const word = text.slice(i, j);
593
+ tokens.push({ text: word, width: getDisplayWidth2(word) });
594
+ i = j;
595
+ }
596
+ }
597
+ const lines = [];
598
+ let line = "";
599
+ let lineWidth = 0;
600
+ for (const token of tokens) {
601
+ if (lineWidth + token.width > maxLen && line) {
602
+ lines.push(line.trimEnd());
603
+ line = token.text;
604
+ lineWidth = token.width;
605
+ } else {
606
+ line += token.text;
607
+ lineWidth += token.width;
608
+ }
609
+ }
610
+ if (line) lines.push(line.trimEnd());
611
+ return lines.map((l, i2) => chalk2.cyan(i2 === 0 ? prefix + l : indent + l)).join("\n");
612
+ }
551
613
  var checkboxTheme = {
552
614
  icon: {
553
615
  checked: "\x1B[32m\u2611\x1B[22m",
554
616
  unchecked: "\u2610",
555
617
  cursor: "\u276F"
556
618
  },
557
- helpMode: "never"
619
+ helpMode: "never",
620
+ style: {
621
+ description: (text) => wrapDescription(text)
622
+ }
558
623
  };
559
624
 
560
625
  // src/ui/wizard.ts
@@ -629,7 +694,7 @@ async function runWizard() {
629
694
  step = 2;
630
695
  break;
631
696
  }
632
- if (result === CANCEL || result === false) {
697
+ if (result === CANCEL) {
633
698
  return { language: config.language || "zh_CN", tool: selectedTool, level, plugins: [], confirmed: false };
634
699
  }
635
700
  updateConfig({ lastTool: selectedTool, lastLevel: level });
@@ -744,9 +809,10 @@ async function stepPlugins(tool, level) {
744
809
  const isInstalled = installedSet.has(p.id);
745
810
  const suffix = isInstalled ? ` [${t("wizard_already_installed")}]` : "";
746
811
  return {
747
- name: `${p.displayName}${suffix} \u2014 ${p.description}`,
812
+ name: `${chalk3.cyan(p.displayName)}${suffix}`,
748
813
  value: p.id,
749
- checked: false
814
+ checked: false,
815
+ description: p.description
750
816
  };
751
817
  });
752
818
  showOperationHints(true);
@@ -782,11 +848,11 @@ async function stepConfirm(tool, level, plugins) {
782
848
  const displayPath = getConfigRoot(tool, level);
783
849
  const toolName = getToolDisplayName(tool);
784
850
  const levelText = level === "project" ? "project" : "global";
785
- logger.info(t("wizard_confirm_install_format").replace("{count}", chalk2.bold(String(plugins.length))).replace("{tool}", chalk2.green(toolName)).replace("{level}", chalk2.cyan(levelText)));
786
- logger.info(`${t("wizard_install_path")}: ${chalk2.cyan(displayPath)}`);
851
+ logger.info(t("wizard_confirm_install_format").replace("{count}", chalk3.bold(String(plugins.length))).replace("{tool}", chalk3.green(toolName)).replace("{level}", chalk3.cyan(levelText)));
852
+ logger.info(`${t("wizard_install_path")}: ${chalk3.cyan(displayPath)}`);
787
853
  for (const plugin of selectedPlugins) {
788
854
  if (plugin) {
789
- logger.step(` \u2022 ${chalk2.bold(plugin.displayName)}`);
855
+ logger.step(` \u2022 ${chalk3.bold(plugin.displayName)}`);
790
856
  }
791
857
  }
792
858
  logger.blank();
@@ -963,20 +1029,6 @@ function getCachePath() {
963
1029
  return join7(getCannbotConfigDir(), "scan-cache.json");
964
1030
  }
965
1031
  function scanDirectory(dirPath, repoPath, sourcePrefix, skills, seen) {
966
- const selfSkillMd = join7(dirPath, "SKILL.md");
967
- if (existsSync5(selfSkillMd)) {
968
- const frontmatter = parseFrontmatter(selfSkillMd);
969
- if (frontmatter && !seen.has(frontmatter.name)) {
970
- seen.add(frontmatter.name);
971
- skills.push({
972
- id: frontmatter.name,
973
- description: frontmatter.description,
974
- source: sourcePrefix,
975
- filePath: selfSkillMd
976
- });
977
- }
978
- return;
979
- }
980
1032
  for (const entry of safeReaddir(dirPath)) {
981
1033
  const fullPath = join7(dirPath, entry);
982
1034
  if (EXCLUDE_DIRS.has(entry)) continue;
@@ -995,7 +1047,7 @@ function scanDirectory(dirPath, repoPath, sourcePrefix, skills, seen) {
995
1047
  }
996
1048
  continue;
997
1049
  }
998
- scanDirectory(fullPath, repoPath, sourcePrefix, skills, seen);
1050
+ scanDirectory(fullPath, repoPath, sourcePrefix + "/" + entry, skills, seen);
999
1051
  }
1000
1052
  }
1001
1053
  function safeReaddir(dir) {
@@ -1665,13 +1717,13 @@ function readAllRecords() {
1665
1717
 
1666
1718
  // src/ui/backup-prompts.ts
1667
1719
  import { select as select2 } from "@inquirer/prompts";
1668
- import chalk3 from "chalk";
1720
+ import chalk4 from "chalk";
1669
1721
  async function showOverwriteWarning(currentPluginName, newPluginName) {
1670
1722
  console.log();
1671
- console.log(chalk3.yellow(` \u26A0\uFE0F ${t("backup_detected")}`));
1723
+ console.log(chalk4.yellow(` \u26A0\uFE0F ${t("backup_detected")}`));
1672
1724
  console.log();
1673
- console.log(` ${t("backup_current")}: ${chalk3.cyan(currentPluginName)}`);
1674
- console.log(` ${t("backup_installing")}: ${chalk3.cyan(newPluginName)}`);
1725
+ console.log(` ${t("backup_current")}: ${chalk4.cyan(currentPluginName)}`);
1726
+ console.log(` ${t("backup_installing")}: ${chalk4.cyan(newPluginName)}`);
1675
1727
  console.log();
1676
1728
  console.log(` ${t("backup_overwrite_warning")}`);
1677
1729
  console.log(` ${t("backup_auto_create")}`);
@@ -1687,7 +1739,7 @@ async function showOverwriteWarning(currentPluginName, newPluginName) {
1687
1739
  }
1688
1740
  async function showRestorePrompt(backups) {
1689
1741
  console.log();
1690
- console.log(chalk3.cyan(` ${t("backup_restore_prompt")}`));
1742
+ console.log(chalk4.cyan(` ${t("backup_restore_prompt")}`));
1691
1743
  console.log();
1692
1744
  const choices = backups.map((b) => ({
1693
1745
  name: `${t("backup_restore")} ${b.pluginName} (${b.backupTime})`,
@@ -1829,7 +1881,7 @@ async function installPlugin(opts) {
1829
1881
  import { existsSync as existsSync10, mkdirSync as mkdirSync5, symlinkSync, unlinkSync as unlinkSync3, readdirSync as readdirSync4, rmdirSync, realpathSync, lstatSync as lstatSync2 } from "fs";
1830
1882
  import { join as join12 } from "path";
1831
1883
  import { select as select3, checkbox as checkbox2, Separator as Separator2 } from "@inquirer/prompts";
1832
- import chalk4 from "chalk";
1884
+ import chalk5 from "chalk";
1833
1885
  import Table from "cli-table3";
1834
1886
  async function installSkills(skillIds, tool, level, repoPath) {
1835
1887
  const configRoot = getConfigRoot(tool, level);
@@ -1905,22 +1957,34 @@ async function uninstallSkills(skillIds, tool, level) {
1905
1957
  }
1906
1958
  return results;
1907
1959
  }
1960
+ var SELECT_ALL = "__select_all__";
1961
+ var SELECT_ALL_CATEGORY = "__select_all_category__";
1962
+ var CONTINUE_SELECT = "__continue_select__";
1908
1963
  async function interactiveSkillSelect(tool, level) {
1909
1964
  const BACK3 = "__back__";
1910
1965
  const CANCEL3 = "__cancel__";
1911
1966
  const categories = getAllCategories();
1967
+ const allSkillIds = getAllSkills().map((s) => s.id);
1968
+ let accumulated = [];
1912
1969
  let step = 0;
1913
1970
  let selectedCategoryId = "";
1914
1971
  while (true) {
1915
1972
  switch (step) {
1916
1973
  case 0: {
1917
- printBoxTitle(t("wizard_step_3_skill_title"));
1974
+ const titleSuffix = accumulated.length > 0 ? `${t("wizard_step_3_skill_title")}\uFF08${t("skill_count_format").replace("{count}", String(accumulated.length))}\uFF09` : t("wizard_step_3_skill_title");
1975
+ printBoxTitle(titleSuffix);
1918
1976
  const categoryChoices = [
1977
+ {
1978
+ name: `>> ${t("skill_select_all").replace("{count}", String(allSkillIds.length))}`,
1979
+ value: SELECT_ALL
1980
+ },
1981
+ new Separator2("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
1919
1982
  ...categories.map((cat) => ({
1920
1983
  name: `> ${cat.name} (${cat.skills.length} skills)`,
1921
1984
  value: cat.id
1922
1985
  })),
1923
1986
  new Separator2("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
1987
+ ...accumulated.length > 0 ? [{ name: `>> ${t("skill_confirm_install_count").replace("{count}", String(accumulated.length))}`, value: "install" }] : [],
1924
1988
  { name: "<- " + t("wizard_back"), value: BACK3 },
1925
1989
  { name: "x " + t("wizard_cancel"), value: CANCEL3 }
1926
1990
  ];
@@ -1934,6 +1998,12 @@ async function interactiveSkillSelect(tool, level) {
1934
1998
  });
1935
1999
  if (selectedCategoryId === BACK3) return "back";
1936
2000
  if (selectedCategoryId === CANCEL3) return "cancel";
2001
+ if (selectedCategoryId === SELECT_ALL) {
2002
+ return allSkillIds;
2003
+ }
2004
+ if (selectedCategoryId === "install") {
2005
+ return accumulated;
2006
+ }
1937
2007
  step = 1;
1938
2008
  break;
1939
2009
  }
@@ -1944,15 +2014,28 @@ async function interactiveSkillSelect(tool, level) {
1944
2014
  const installPath = level === "project" ? process.cwd() : getConfigRoot(tool, level);
1945
2015
  const installedSkills = getInstalledSkills(tool, level, installPath);
1946
2016
  const installedSet = new Set(installedSkills);
1947
- const skillChoices = category.skills.map((skill) => {
1948
- const isInstalled = installedSet.has(skill.id);
1949
- const suffix = isInstalled ? ` [${t("skill_already_installed")}]` : "";
1950
- return {
1951
- name: `${skill.id}${suffix} \u2014 ${skill.description}`,
1952
- value: skill.id,
1953
- checked: false
1954
- };
1955
- });
2017
+ const categorySkillIds = new Set(category.skills.map((s) => s.id));
2018
+ const accumulatedInCategory = new Set(accumulated.filter((id) => categorySkillIds.has(id)));
2019
+ const skillChoices = [
2020
+ {
2021
+ name: `>> ${t("skill_select_all_category")}`,
2022
+ value: SELECT_ALL_CATEGORY,
2023
+ checked: accumulatedInCategory.size === category.skills.length,
2024
+ description: t("skill_select_all_category")
2025
+ },
2026
+ new Separator2("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
2027
+ ...category.skills.map((skill) => {
2028
+ const isInstalled = installedSet.has(skill.id);
2029
+ const isAccumulated = accumulatedInCategory.has(skill.id);
2030
+ const suffix = isInstalled ? ` [${t("skill_already_installed")}]` : isAccumulated ? " [+]" : "";
2031
+ return {
2032
+ name: `${chalk5.cyan(skill.id)}${suffix}`,
2033
+ value: skill.id,
2034
+ checked: isAccumulated,
2035
+ description: skill.description
2036
+ };
2037
+ })
2038
+ ];
1956
2039
  showOperationHints(true);
1957
2040
  const selectedSkills = await checkbox2({
1958
2041
  message: t("skill_select_items"),
@@ -1962,11 +2045,21 @@ async function interactiveSkillSelect(tool, level) {
1962
2045
  theme: checkboxTheme,
1963
2046
  pageSize: 15
1964
2047
  });
1965
- const skillIds = selectedSkills;
2048
+ let skillIds;
2049
+ if (selectedSkills.includes(SELECT_ALL_CATEGORY)) {
2050
+ skillIds = category.skills.map((s) => s.id);
2051
+ } else {
2052
+ skillIds = selectedSkills.filter((id) => id !== SELECT_ALL_CATEGORY);
2053
+ }
1966
2054
  if (skillIds.length === 0) {
1967
- const action = await select3({
1968
- message: t("wizard_no_selection"),
1969
- choices: [
2055
+ accumulated = accumulated.filter((id) => !categorySkillIds.has(id));
2056
+ const action2 = await select3({
2057
+ message: accumulated.length > 0 ? t("skill_continue_or_install").replace("{count}", String(accumulated.length)) : t("wizard_no_selection"),
2058
+ choices: accumulated.length > 0 ? [
2059
+ { name: ">> " + t("skill_confirm_install_count").replace("{count}", String(accumulated.length)), value: "install" },
2060
+ { name: "<- " + t("wizard_back_to_reselect"), value: "back" },
2061
+ { name: "x " + t("wizard_cancel"), value: "cancel" }
2062
+ ] : [
1970
2063
  new Separator2("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
1971
2064
  { name: "<- " + t("wizard_back_to_reselect"), value: "back" },
1972
2065
  { name: "x " + t("wizard_cancel"), value: "cancel" }
@@ -1974,13 +2067,38 @@ async function interactiveSkillSelect(tool, level) {
1974
2067
  loop: false,
1975
2068
  theme: selectTheme
1976
2069
  });
1977
- if (action === "back") {
2070
+ if (action2 === "install") return accumulated;
2071
+ if (action2 === "back") {
1978
2072
  step = 0;
1979
2073
  break;
1980
2074
  }
1981
2075
  return "cancel";
1982
2076
  }
1983
- return skillIds;
2077
+ accumulated = accumulated.filter((id) => !categorySkillIds.has(id));
2078
+ for (const id of skillIds) {
2079
+ if (!accumulated.includes(id)) {
2080
+ accumulated.push(id);
2081
+ }
2082
+ }
2083
+ const action = await select3({
2084
+ message: t("skill_continue_or_install").replace("{count}", String(accumulated.length)),
2085
+ choices: [
2086
+ { name: ">> " + t("skill_confirm_install_count").replace("{count}", String(accumulated.length)), value: "install" },
2087
+ { name: "> " + t("skill_continue_select"), value: CONTINUE_SELECT },
2088
+ new Separator2("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
2089
+ { name: "x " + t("wizard_cancel"), value: "cancel" }
2090
+ ],
2091
+ loop: false,
2092
+ theme: selectTheme
2093
+ });
2094
+ if (action === "install") {
2095
+ return accumulated;
2096
+ }
2097
+ if (action === CONTINUE_SELECT) {
2098
+ step = 0;
2099
+ break;
2100
+ }
2101
+ return "cancel";
1984
2102
  }
1985
2103
  }
1986
2104
  }
@@ -1988,11 +2106,11 @@ async function interactiveSkillSelect(tool, level) {
1988
2106
  function listAllSkills() {
1989
2107
  const categories = getAllCategories();
1990
2108
  console.log();
1991
- console.log(chalk4.bold(` ${t("skill_list_title")}`));
1992
- console.log(chalk4.dim(" " + "\u2500".repeat(60)));
2109
+ console.log(chalk5.bold(` ${t("skill_list_title")}`));
2110
+ console.log(chalk5.dim(" " + "\u2500".repeat(60)));
1993
2111
  for (const category of categories) {
1994
2112
  console.log();
1995
- console.log(chalk4.bold(` ${category.name}`) + chalk4.dim(` (${category.skills.length} skills)`));
2113
+ console.log(chalk5.bold(` ${category.name}`) + chalk5.dim(` (${category.skills.length} skills)`));
1996
2114
  const table = new Table({
1997
2115
  style: { head: [], border: [] },
1998
2116
  colWidths: [35, 45],
@@ -2000,14 +2118,14 @@ function listAllSkills() {
2000
2118
  });
2001
2119
  for (const skill of category.skills) {
2002
2120
  table.push([
2003
- chalk4.cyan(skill.id),
2121
+ chalk5.cyan(skill.id),
2004
2122
  skill.description
2005
2123
  ]);
2006
2124
  }
2007
2125
  console.log(table.toString());
2008
2126
  }
2009
2127
  console.log();
2010
- console.log(chalk4.dim(` ${t("skill_total_count").replace("{count}", String(getAllSkills().length))}`));
2128
+ console.log(chalk5.dim(` ${t("skill_total_count").replace("{count}", String(getAllSkills().length))}`));
2011
2129
  console.log();
2012
2130
  }
2013
2131
  function isSymlink2(path) {
@@ -2019,22 +2137,22 @@ function isSymlink2(path) {
2019
2137
  }
2020
2138
 
2021
2139
  // src/ui/display.ts
2022
- import chalk5 from "chalk";
2140
+ import chalk6 from "chalk";
2023
2141
  import Table2 from "cli-table3";
2024
2142
  function printPluginList(plugins, installed) {
2025
2143
  const table = new Table2({
2026
2144
  head: [
2027
- chalk5.cyan(t("list_id")),
2028
- chalk5.cyan(t("list_name")),
2029
- chalk5.cyan(t("list_status")),
2030
- chalk5.cyan(t("list_skills")),
2031
- chalk5.cyan(t("list_agents"))
2145
+ chalk6.cyan(t("list_id")),
2146
+ chalk6.cyan(t("list_name")),
2147
+ chalk6.cyan(t("list_status")),
2148
+ chalk6.cyan(t("list_skills")),
2149
+ chalk6.cyan(t("list_agents"))
2032
2150
  ],
2033
2151
  style: { head: [], border: [] }
2034
2152
  });
2035
2153
  plugins.forEach((plugin, index) => {
2036
2154
  const isInstalled = installed.has(plugin.id);
2037
- const status = isInstalled ? chalk5.green(`\u2713 ${t("status_installed")}`) : chalk5.dim(`\u2014`);
2155
+ const status = isInstalled ? chalk6.green(`\u2713 ${t("status_installed")}`) : chalk6.dim(`\u2014`);
2038
2156
  table.push([
2039
2157
  String(index + 1),
2040
2158
  plugin.displayName,
@@ -2045,7 +2163,7 @@ function printPluginList(plugins, installed) {
2045
2163
  });
2046
2164
  console.log();
2047
2165
  const countSuffix = t("count_suffix");
2048
- console.log(chalk5.bold(` ${t("list_title")} (${plugins.length}${countSuffix ? " " + countSuffix : ""})`));
2166
+ console.log(chalk6.bold(` ${t("list_title")} (${plugins.length}${countSuffix ? " " + countSuffix : ""})`));
2049
2167
  console.log(table.toString());
2050
2168
  console.log();
2051
2169
  }
@@ -2054,7 +2172,7 @@ function printInstallSummary(results) {
2054
2172
  const totalCount = results.length;
2055
2173
  console.log();
2056
2174
  console.log(
2057
- chalk5.bold(
2175
+ chalk6.bold(
2058
2176
  ` ${t("install_done")}! ${successCount}/${totalCount} ${t("install_success")}`
2059
2177
  )
2060
2178
  );
@@ -2062,10 +2180,10 @@ function printInstallSummary(results) {
2062
2180
  for (const result of results) {
2063
2181
  if (result.success) {
2064
2182
  console.log(
2065
- chalk5.green(" \u2713") + ` ${result.displayName} (${result.skillsCount} skills, ${result.agentsCount} agents)`
2183
+ chalk6.green(" \u2713") + ` ${result.displayName} (${result.skillsCount} skills, ${result.agentsCount} agents)`
2066
2184
  );
2067
2185
  } else {
2068
- console.log(chalk5.red(" \u2717") + ` ${result.displayName}`);
2186
+ console.log(chalk6.red(" \u2717") + ` ${result.displayName}`);
2069
2187
  }
2070
2188
  }
2071
2189
  console.log();
@@ -2080,23 +2198,23 @@ function printEnhancedSummary(results, tool, configRoot) {
2080
2198
  const toolName = getToolDisplayName(tool);
2081
2199
  const countSuffix = t("count_suffix");
2082
2200
  const lines = [
2083
- chalk5.bold(` ${t("install_done")}!`),
2201
+ chalk6.bold(` ${t("install_done")}!`),
2084
2202
  "",
2085
- ` ${chalk5.dim(t("install_installed_to") + ":")} ${configRoot}`,
2086
- ` ${chalk5.dim(t("install_skills_count") + ":")} ${totalSkills}${countSuffix ? " " + countSuffix : ""} ${chalk5.dim("|")} ${chalk5.dim(t("install_agents_count") + ":")} ${totalAgents}${countSuffix ? " " + countSuffix : ""}`,
2203
+ ` ${chalk6.dim(t("install_installed_to") + ":")} ${configRoot}`,
2204
+ ` ${chalk6.dim(t("install_skills_count") + ":")} ${totalSkills}${countSuffix ? " " + countSuffix : ""} ${chalk6.dim("|")} ${chalk6.dim(t("install_agents_count") + ":")} ${totalAgents}${countSuffix ? " " + countSuffix : ""}`,
2087
2205
  "",
2088
- chalk5.bold(` ${t("install_enhanced_next_steps")}:`),
2089
- ` ${chalk5.cyan("1.")} ${t("install_enhanced_launch")}: ${chalk5.green(toolName.toLowerCase())}`,
2090
- ` ${chalk5.cyan("2.")} ${t("install_enhanced_try")}: ${chalk5.green(t("try_prompt"))}`,
2091
- ` ${chalk5.cyan("3.")} ${t("install_enhanced_more")}: ${chalk5.green("install-helper list")}`,
2092
- ` ${chalk5.cyan("4.")} ${t("install_enhanced_check")}: ${chalk5.green("install-helper doctor")}`,
2206
+ chalk6.bold(` ${t("install_enhanced_next_steps")}:`),
2207
+ ` ${chalk6.cyan("1.")} ${t("install_enhanced_launch")}: ${chalk6.green(toolName.toLowerCase())}`,
2208
+ ` ${chalk6.cyan("2.")} ${t("install_enhanced_try")}: ${chalk6.green(t("try_prompt"))}`,
2209
+ ` ${chalk6.cyan("3.")} ${t("install_enhanced_more")}: ${chalk6.green("install-helper list")}`,
2210
+ ` ${chalk6.cyan("4.")} ${t("install_enhanced_check")}: ${chalk6.green("install-helper doctor")}`,
2093
2211
  ""
2094
2212
  ];
2095
2213
  if (successResults.length === 1) {
2096
2214
  const plugin = findPlugin(successResults[0].pluginId);
2097
2215
  const docsPath = plugin ? `${plugin.dir}/quickstart.md` : `${successResults[0].pluginId}/quickstart.md`;
2098
2216
  lines.push(
2099
- ` ${chalk5.dim(t("install_enhanced_docs"))}: ${chalk5.dim(docsPath)}`
2217
+ ` ${chalk6.dim(t("install_enhanced_docs"))}: ${chalk6.dim(docsPath)}`
2100
2218
  );
2101
2219
  }
2102
2220
  console.log();
@@ -2297,7 +2415,7 @@ async function skillInstallFlow() {
2297
2415
  spinner.start();
2298
2416
  const repoPath = await repoManager.ensureRepo();
2299
2417
  spinner.succeed(t("loading_plugin_data_complete"));
2300
- logger.info(`${t("skill_install_progress")} ${t("skill_count_format").replace("{count}", chalk6.bold(String(selectedSkills.length)))}...`);
2418
+ logger.info(`${t("skill_install_progress")} ${t("skill_count_format").replace("{count}", chalk7.bold(String(selectedSkills.length)))}...`);
2301
2419
  const results = await installSkills(selectedSkills, tool, level, repoPath);
2302
2420
  let successCount = 0;
2303
2421
  let failCount = 0;
@@ -2315,10 +2433,10 @@ async function skillInstallFlow() {
2315
2433
  }
2316
2434
  const configRoot = getConfigRoot(tool, level);
2317
2435
  logger.blank();
2318
- logger.success(`${t("skill_install_done")}: ${chalk6.green(t("result_success_format").replace("{count}", String(successCount)))}, ${failCount > 0 ? chalk6.red(t("result_failed_format").replace("{count}", String(failCount))) : chalk6.dim(t("result_failed_format").replace("{count}", String(failCount)))}`);
2436
+ logger.success(`${t("skill_install_done")}: ${chalk7.green(t("result_success_format").replace("{count}", String(successCount)))}, ${failCount > 0 ? chalk7.red(t("result_failed_format").replace("{count}", String(failCount))) : chalk7.dim(t("result_failed_format").replace("{count}", String(failCount)))}`);
2319
2437
  logger.blank();
2320
- logger.info(`${t("install_to")}: ${chalk6.cyan(configRoot + "/skills/")}`);
2321
- logger.info(`${t("start_to_use").replace("{tool}", chalk6.green(tool))}`);
2438
+ logger.info(`${t("install_to")}: ${chalk7.cyan(configRoot + "/skills/")}`);
2439
+ logger.info(`${t("start_to_use").replace("{tool}", chalk7.green(tool))}`);
2322
2440
  logger.blank();
2323
2441
  return "done";
2324
2442
  }
@@ -2340,32 +2458,32 @@ async function listCommand() {
2340
2458
  }
2341
2459
 
2342
2460
  // src/commands/doctor.ts
2343
- import chalk7 from "chalk";
2461
+ import chalk8 from "chalk";
2344
2462
  import { existsSync as existsSync12, readdirSync as readdirSync5, lstatSync as lstatSync3, unlinkSync as unlinkSync4, mkdirSync as mkdirSync6 } from "fs";
2345
2463
  import { join as join14 } from "path";
2346
2464
  async function doctorCommand(options = {}) {
2347
2465
  console.log();
2348
- console.log(chalk7.bold(` ${t("doctor_title")}`));
2349
- console.log(chalk7.dim(" " + "\u2500".repeat(46)));
2466
+ console.log(chalk8.bold(` ${t("doctor_title")}`));
2467
+ console.log(chalk8.dim(" " + "\u2500".repeat(46)));
2350
2468
  let errors = 0;
2351
2469
  let warnings = 0;
2352
2470
  let fixes = 0;
2353
2471
  console.log();
2354
- console.log(chalk7.bold(` ${t("doctor_tools")}`));
2472
+ console.log(chalk8.bold(` ${t("doctor_tools")}`));
2355
2473
  const detectedTools = await detectTools();
2356
2474
  const allTools = getAllTools();
2357
2475
  for (const tool of allTools) {
2358
2476
  const detected = detectedTools.find((d) => d.name === tool);
2359
2477
  if (detected) {
2360
2478
  console.log(
2361
- chalk7.green(" \u2713") + ` ${getToolDisplayName(tool)}${detected.version ? ` v${detected.version}` : ""}`
2479
+ chalk8.green(" \u2713") + ` ${getToolDisplayName(tool)}${detected.version ? ` v${detected.version}` : ""}`
2362
2480
  );
2363
2481
  } else {
2364
- console.log(chalk7.dim(" \u2014") + ` ${getToolDisplayName(tool)} \u2014 ${t("doctor_not_installed")}`);
2482
+ console.log(chalk8.dim(" \u2014") + ` ${getToolDisplayName(tool)} \u2014 ${t("doctor_not_installed")}`);
2365
2483
  }
2366
2484
  }
2367
2485
  console.log();
2368
- console.log(chalk7.bold(` ${t("doctor_plugins")}`));
2486
+ console.log(chalk8.bold(` ${t("doctor_plugins")}`));
2369
2487
  const plugins = getAllPlugins();
2370
2488
  const installed = scanInstalled();
2371
2489
  const installedMap = new Map(installed.map((p) => [p.id, p]));
@@ -2373,14 +2491,14 @@ async function doctorCommand(options = {}) {
2373
2491
  const inst = installedMap.get(plugin.id);
2374
2492
  if (inst) {
2375
2493
  console.log(
2376
- chalk7.green(" \u2713") + ` ${plugin.id.padEnd(30)} ${inst.skillsCount} skills, ${inst.agentsCount} agents`
2494
+ chalk8.green(" \u2713") + ` ${plugin.id.padEnd(30)} ${inst.skillsCount} skills, ${inst.agentsCount} agents`
2377
2495
  );
2378
2496
  } else {
2379
- console.log(chalk7.dim(" \u2014") + ` ${plugin.id.padEnd(30)} \u2014 ${t("doctor_not_installed")}`);
2497
+ console.log(chalk8.dim(" \u2014") + ` ${plugin.id.padEnd(30)} \u2014 ${t("doctor_not_installed")}`);
2380
2498
  }
2381
2499
  }
2382
2500
  console.log();
2383
- console.log(chalk7.bold(` ${t("doctor_links")}`));
2501
+ console.log(chalk8.bold(` ${t("doctor_links")}`));
2384
2502
  const primaryTool = detectedTools[0]?.name || "opencode";
2385
2503
  const configRoot = getConfigRoot(primaryTool, "project");
2386
2504
  const skillsDir = getSkillsDir(configRoot);
@@ -2389,57 +2507,57 @@ async function doctorCommand(options = {}) {
2389
2507
  const brokenLinks = checkBrokenLinks(skillsDir);
2390
2508
  if (brokenLinks === 0) {
2391
2509
  const count = readdirSync5(skillsDir).length;
2392
- console.log(chalk7.green(" \u2713") + ` ${skillsDir} \u2014 ${t("doctor_links_valid").replace("{count}", String(count))}`);
2510
+ console.log(chalk8.green(" \u2713") + ` ${skillsDir} \u2014 ${t("doctor_links_valid").replace("{count}", String(count))}`);
2393
2511
  } else {
2394
- console.log(chalk7.yellow(" \u26A0") + ` ${skillsDir} \u2014 ${t("doctor_broken_links").replace("{count}", String(brokenLinks))}`);
2512
+ console.log(chalk8.yellow(" \u26A0") + ` ${skillsDir} \u2014 ${t("doctor_broken_links").replace("{count}", String(brokenLinks))}`);
2395
2513
  warnings++;
2396
2514
  if (options.fix) {
2397
2515
  const fixed = fixBrokenLinks(skillsDir);
2398
2516
  fixes += fixed;
2399
- console.log(chalk7.green(" \u2713") + ` ${t("doctor_fix_cleaning")}: ${t("doctor_fixed").replace("{count}", String(fixed))}`);
2517
+ console.log(chalk8.green(" \u2713") + ` ${t("doctor_fix_cleaning")}: ${t("doctor_fixed").replace("{count}", String(fixed))}`);
2400
2518
  }
2401
2519
  }
2402
2520
  } else {
2403
- console.log(chalk7.dim(" \u2014") + ` ${skillsDir} \u2014 ${t("doctor_not_exist")}`);
2521
+ console.log(chalk8.dim(" \u2014") + ` ${skillsDir} \u2014 ${t("doctor_not_exist")}`);
2404
2522
  if (options.fix) {
2405
2523
  mkdirSync6(skillsDir, { recursive: true });
2406
2524
  fixes++;
2407
- console.log(chalk7.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: ${t("doctor_created").replace("{path}", skillsDir)}`);
2525
+ console.log(chalk8.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: ${t("doctor_created").replace("{path}", skillsDir)}`);
2408
2526
  }
2409
2527
  }
2410
2528
  if (existsSync12(agentsDir)) {
2411
2529
  const brokenLinks = checkBrokenLinks(agentsDir);
2412
2530
  if (brokenLinks === 0) {
2413
2531
  const count = readdirSync5(agentsDir).length;
2414
- console.log(chalk7.green(" \u2713") + ` ${agentsDir} \u2014 ${t("doctor_links_valid").replace("{count}", String(count))}`);
2532
+ console.log(chalk8.green(" \u2713") + ` ${agentsDir} \u2014 ${t("doctor_links_valid").replace("{count}", String(count))}`);
2415
2533
  } else {
2416
- console.log(chalk7.yellow(" \u26A0") + ` ${agentsDir} \u2014 ${t("doctor_broken_links").replace("{count}", String(brokenLinks))}`);
2534
+ console.log(chalk8.yellow(" \u26A0") + ` ${agentsDir} \u2014 ${t("doctor_broken_links").replace("{count}", String(brokenLinks))}`);
2417
2535
  warnings++;
2418
2536
  if (options.fix) {
2419
2537
  const fixed = fixBrokenLinks(agentsDir);
2420
2538
  fixes += fixed;
2421
- console.log(chalk7.green(" \u2713") + ` ${t("doctor_fix_cleaning")}: ${t("doctor_fixed").replace("{count}", String(fixed))}`);
2539
+ console.log(chalk8.green(" \u2713") + ` ${t("doctor_fix_cleaning")}: ${t("doctor_fixed").replace("{count}", String(fixed))}`);
2422
2540
  }
2423
2541
  }
2424
2542
  } else {
2425
- console.log(chalk7.dim(" \u2014") + ` ${agentsDir} \u2014 ${t("doctor_not_exist")}`);
2543
+ console.log(chalk8.dim(" \u2014") + ` ${agentsDir} \u2014 ${t("doctor_not_exist")}`);
2426
2544
  if (options.fix) {
2427
2545
  mkdirSync6(agentsDir, { recursive: true });
2428
2546
  fixes++;
2429
- console.log(chalk7.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: ${t("doctor_created").replace("{path}", agentsDir)}`);
2547
+ console.log(chalk8.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: ${t("doctor_created").replace("{path}", agentsDir)}`);
2430
2548
  }
2431
2549
  }
2432
2550
  console.log();
2433
- console.log(chalk7.bold(` ${t("doctor_config")}`));
2551
+ console.log(chalk8.bold(` ${t("doctor_config")}`));
2434
2552
  const configFile = getConfigFileName(primaryTool);
2435
2553
  const configPath = join14(process.cwd(), configFile);
2436
2554
  if (existsSync12(configPath)) {
2437
- console.log(chalk7.green(" \u2713") + ` ${configFile} ${t("doctor_config_exists")}`);
2555
+ console.log(chalk8.green(" \u2713") + ` ${configFile} ${t("doctor_config_exists")}`);
2438
2556
  } else {
2439
- console.log(chalk7.dim(" \u2014") + ` ${configFile} ${t("doctor_config_not_exist")}`);
2557
+ console.log(chalk8.dim(" \u2014") + ` ${configFile} ${t("doctor_config_not_exist")}`);
2440
2558
  }
2441
2559
  console.log();
2442
- console.log(chalk7.dim(" " + "\u2500".repeat(46)));
2560
+ console.log(chalk8.dim(" " + "\u2500".repeat(46)));
2443
2561
  if (options.fix && fixes > 0) {
2444
2562
  console.log(
2445
2563
  ` ${t("doctor_result")}: ${t("doctor_result_with_fix").replace("{warnings}", String(warnings)).replace("{errors}", String(errors)).replace("{fixes}", String(fixes))}`
@@ -2495,36 +2613,36 @@ function fixBrokenLinks(dir) {
2495
2613
  }
2496
2614
 
2497
2615
  // src/commands/status.ts
2498
- import chalk8 from "chalk";
2616
+ import chalk9 from "chalk";
2499
2617
  async function statusCommand() {
2500
2618
  const plugins = getAllPlugins();
2501
2619
  const installed = scanInstalled();
2502
2620
  const installedMap = new Map(installed.map((p) => [p.id, p]));
2503
2621
  console.log();
2504
- console.log(chalk8.bold(` ${t("status_title")}`));
2622
+ console.log(chalk9.bold(` ${t("status_title")}`));
2505
2623
  console.log();
2506
2624
  if (installed.length === 0) {
2507
- console.log(chalk8.dim(` ${t("status_none")}`));
2508
- console.log(chalk8.dim(` ${t("status_hint")}`));
2625
+ console.log(chalk9.dim(` ${t("status_none")}`));
2626
+ console.log(chalk9.dim(` ${t("status_hint")}`));
2509
2627
  console.log();
2510
2628
  return;
2511
2629
  }
2512
2630
  for (const inst of installed) {
2513
2631
  console.log(
2514
- chalk8.green(" \u2713") + ` ${inst.displayName}` + chalk8.dim(` (${inst.tool}, ${inst.level})`)
2632
+ chalk9.green(" \u2713") + ` ${inst.displayName}` + chalk9.dim(` (${inst.tool}, ${inst.level})`)
2515
2633
  );
2516
2634
  console.log(
2517
- chalk8.dim(` ${inst.skillsCount} skills, ${inst.agentsCount} agents`)
2635
+ chalk9.dim(` ${inst.skillsCount} skills, ${inst.agentsCount} agents`)
2518
2636
  );
2519
- console.log(chalk8.dim(` ${inst.configRoot}`));
2520
- console.log(chalk8.dim(` ${t("status_install_time")}: ${inst.installTime}`));
2637
+ console.log(chalk9.dim(` ${inst.configRoot}`));
2638
+ console.log(chalk9.dim(` ${t("status_install_time")}: ${inst.installTime}`));
2521
2639
  console.log();
2522
2640
  }
2523
2641
  }
2524
2642
 
2525
2643
  // src/commands/install.ts
2526
2644
  import { confirm } from "@inquirer/prompts";
2527
- import chalk9 from "chalk";
2645
+ import chalk10 from "chalk";
2528
2646
  async function installCommand(names, options) {
2529
2647
  if (options.list) {
2530
2648
  try {
@@ -2535,6 +2653,61 @@ async function installCommand(names, options) {
2535
2653
  listAllSkills();
2536
2654
  return;
2537
2655
  }
2656
+ if (options.all) {
2657
+ const scanSpinner2 = createSpinner(t("loading_skills_list"));
2658
+ scanSpinner2.start();
2659
+ try {
2660
+ const scanRepoManager = createRepositoryManager();
2661
+ await scanRepoManager.ensureRepoAndScan();
2662
+ scanSpinner2.succeed(t("loading_skills_list_complete"));
2663
+ } catch {
2664
+ scanSpinner2.warn(t("loading_skills_list_failed"));
2665
+ }
2666
+ const allSkills = getAllSkills();
2667
+ const skillIds = allSkills.map((s) => s.id);
2668
+ if (skillIds.length === 0) {
2669
+ logger.error(t("install_no_skill_selected"));
2670
+ return;
2671
+ }
2672
+ let tool2;
2673
+ if (options.tool) {
2674
+ tool2 = validateTool(options.tool);
2675
+ } else {
2676
+ const detected = await selectToolWithDetection();
2677
+ if (detected === "back" || detected === "cancel") return;
2678
+ tool2 = detected;
2679
+ }
2680
+ const level2 = options.level ? validateLevel(options.level) : "project";
2681
+ const repoManager = createRepositoryManager();
2682
+ const spinner = createSpinner(t("loading_plugin_data"));
2683
+ spinner.start();
2684
+ const repoPath = await repoManager.ensureRepo();
2685
+ spinner.succeed(t("loading_plugin_data_complete"));
2686
+ logger.info(`${t("skill_all_install_progress").replace("{count}", chalk10.bold(String(skillIds.length)))}`);
2687
+ const results = await installSkills(skillIds, tool2, level2, repoPath);
2688
+ let successCount = 0;
2689
+ let failCount = 0;
2690
+ const total = results.length;
2691
+ for (let i = 0; i < results.length; i++) {
2692
+ const result = results[i];
2693
+ const progress = `[${i + 1}/${total}]`;
2694
+ if (result.success) {
2695
+ logger.success(`${progress} ${result.skillId}`);
2696
+ successCount++;
2697
+ } else {
2698
+ logger.error(`${progress} ${result.skillId}: ${result.error}`);
2699
+ failCount++;
2700
+ }
2701
+ }
2702
+ const configRoot = getConfigRoot(tool2, level2);
2703
+ logger.blank();
2704
+ logger.success(`${t("skill_install_done")}: ${chalk10.green(t("result_success_format").replace("{count}", String(successCount)))}, ${failCount > 0 ? chalk10.red(t("result_failed_format").replace("{count}", String(failCount))) : chalk10.dim(t("result_failed_format").replace("{count}", String(failCount)))}`);
2705
+ logger.blank();
2706
+ logger.info(`${t("install_to")}: ${chalk10.cyan(configRoot + "/skills/")}`);
2707
+ logger.info(`${t("start_to_use").replace("{tool}", chalk10.green(tool2))}`);
2708
+ logger.blank();
2709
+ return;
2710
+ }
2538
2711
  if (names.length === 0) {
2539
2712
  const scanSpinner2 = createSpinner(t("loading_skills_list"));
2540
2713
  scanSpinner2.start();
@@ -2576,7 +2749,7 @@ async function installCommand(names, options) {
2576
2749
  spinner.start();
2577
2750
  const repoPath = await repoManager.ensureRepo();
2578
2751
  spinner.succeed(t("loading_plugin_data_complete"));
2579
- logger.info(`${t("skill_install_progress")} ${t("skill_count_format").replace("{count}", chalk9.bold(String(names.length)))}...`);
2752
+ logger.info(`${t("skill_install_progress")} ${t("skill_count_format").replace("{count}", chalk10.bold(String(names.length)))}...`);
2580
2753
  const results = await installSkills(names, tool2, level2, repoPath);
2581
2754
  let successCount = 0;
2582
2755
  let failCount = 0;
@@ -2594,10 +2767,10 @@ async function installCommand(names, options) {
2594
2767
  }
2595
2768
  const configRoot = getConfigRoot(tool2, level2);
2596
2769
  logger.blank();
2597
- logger.success(`${t("skill_install_done")}: ${chalk9.green(t("result_success_format").replace("{count}", String(successCount)))}, ${failCount > 0 ? chalk9.red(t("result_failed_format").replace("{count}", String(failCount))) : chalk9.dim(t("result_failed_format").replace("{count}", String(failCount)))}`);
2770
+ logger.success(`${t("skill_install_done")}: ${chalk10.green(t("result_success_format").replace("{count}", String(successCount)))}, ${failCount > 0 ? chalk10.red(t("result_failed_format").replace("{count}", String(failCount))) : chalk10.dim(t("result_failed_format").replace("{count}", String(failCount)))}`);
2598
2771
  logger.blank();
2599
- logger.info(`${t("install_to")}: ${chalk9.cyan(configRoot + "/skills/")}`);
2600
- logger.info(`${t("start_to_use").replace("{tool}", chalk9.green(tool2))}`);
2772
+ logger.info(`${t("install_to")}: ${chalk10.cyan(configRoot + "/skills/")}`);
2773
+ logger.info(`${t("start_to_use").replace("{tool}", chalk10.green(tool2))}`);
2601
2774
  logger.blank();
2602
2775
  return;
2603
2776
  }
@@ -2632,7 +2805,7 @@ async function installCommand(names, options) {
2632
2805
  for (const p of allPlugins) {
2633
2806
  logger.step(` ${p.id} (${p.aliases.join(", ")})`);
2634
2807
  }
2635
- logger.info(`${t("available_skills")}: ${chalk9.cyan("install-helper install --list")}`);
2808
+ logger.info(`${t("available_skills")}: ${chalk10.cyan("install-helper install --list")}`);
2636
2809
  return;
2637
2810
  }
2638
2811
  let tool;
@@ -2704,7 +2877,7 @@ async function installCommand(names, options) {
2704
2877
  spinner.start();
2705
2878
  const repoPath = await repoManager.ensureRepo();
2706
2879
  spinner.succeed(t("loading_plugin_data_complete"));
2707
- logger.info(`${t("skill_install_progress")} ${t("skill_count_format").replace("{count}", chalk9.bold(String(skills.length)))}...`);
2880
+ logger.info(`${t("skill_install_progress")} ${t("skill_count_format").replace("{count}", chalk10.bold(String(skills.length)))}...`);
2708
2881
  const results = await installSkills(skills, tool, level, repoPath);
2709
2882
  let successCount = 0;
2710
2883
  let failCount = 0;
@@ -2721,14 +2894,14 @@ async function installCommand(names, options) {
2721
2894
  }
2722
2895
  }
2723
2896
  logger.blank();
2724
- logger.success(`${t("skill_install_done")}: ${chalk9.green(t("result_success_format").replace("{count}", String(successCount)))}, ${failCount > 0 ? chalk9.red(t("result_failed_format").replace("{count}", String(failCount))) : chalk9.dim(t("result_failed_format").replace("{count}", String(failCount)))}`);
2897
+ logger.success(`${t("skill_install_done")}: ${chalk10.green(t("result_success_format").replace("{count}", String(successCount)))}, ${failCount > 0 ? chalk10.red(t("result_failed_format").replace("{count}", String(failCount))) : chalk10.dim(t("result_failed_format").replace("{count}", String(failCount)))}`);
2725
2898
  logger.blank();
2726
- logger.info(`${t("install_to")}: ${chalk9.cyan(getConfigRoot(tool, level) + "/skills/")}`);
2727
- logger.info(`${t("start_to_use").replace("{tool}", chalk9.green(tool))}`);
2899
+ logger.info(`${t("install_to")}: ${chalk10.cyan(getConfigRoot(tool, level) + "/skills/")}`);
2900
+ logger.info(`${t("start_to_use").replace("{tool}", chalk10.green(tool))}`);
2728
2901
  logger.blank();
2729
2902
  }
2730
2903
  }
2731
- async function installPlugins(pluginIds, tool, level, repoPath) {
2904
+ async function installPlugins(pluginIds, tool, level, repoPath, installPath, yes) {
2732
2905
  const results = [];
2733
2906
  const total = pluginIds.length;
2734
2907
  for (let i = 0; i < pluginIds.length; i++) {
@@ -2740,7 +2913,9 @@ async function installPlugins(pluginIds, tool, level, repoPath) {
2740
2913
  pluginId,
2741
2914
  tool,
2742
2915
  level,
2743
- repoPath
2916
+ repoPath,
2917
+ installPath,
2918
+ yes
2744
2919
  });
2745
2920
  if (result.success) {
2746
2921
  spinner.succeed(
@@ -2757,7 +2932,7 @@ async function installPlugins(pluginIds, tool, level, repoPath) {
2757
2932
 
2758
2933
  // src/commands/uninstall.ts
2759
2934
  import { existsSync as existsSync13, unlinkSync as unlinkSync5, rmdirSync as rmdirSync2, readdirSync as readdirSync6, lstatSync as lstatSync4 } from "fs";
2760
- import chalk10 from "chalk";
2935
+ import chalk11 from "chalk";
2761
2936
  async function uninstallCommand(names, options) {
2762
2937
  const tool = options.tool ? validateTool(options.tool) : "opencode";
2763
2938
  const level = options.level ? validateLevel(options.level) : "project";
@@ -2857,7 +3032,7 @@ async function uninstallCommand(names, options) {
2857
3032
  }
2858
3033
  }
2859
3034
  logger.blank();
2860
- logger.success(`${t("skill_uninstall_done")}: ${chalk10.green(t("result_success_format").replace("{count}", String(successCount)))}, ${failCount > 0 ? chalk10.red(t("result_failed_format").replace("{count}", String(failCount))) : chalk10.dim(t("result_failed_format").replace("{count}", String(failCount)))}`);
3035
+ logger.success(`${t("skill_uninstall_done")}: ${chalk11.green(t("result_success_format").replace("{count}", String(successCount)))}, ${failCount > 0 ? chalk11.red(t("result_failed_format").replace("{count}", String(failCount))) : chalk11.dim(t("result_failed_format").replace("{count}", String(failCount)))}`);
2861
3036
  logger.blank();
2862
3037
  }
2863
3038
  }
@@ -2870,7 +3045,7 @@ function isSymlink3(path) {
2870
3045
  }
2871
3046
 
2872
3047
  // src/commands/update.ts
2873
- import chalk11 from "chalk";
3048
+ import chalk12 from "chalk";
2874
3049
  async function updateCommand(pluginNames, options) {
2875
3050
  let tool;
2876
3051
  if (options.tool) {
@@ -2888,7 +3063,7 @@ async function updateCommand(pluginNames, options) {
2888
3063
  pluginsToUpdate = manifests.map((m) => m.team);
2889
3064
  if (pluginsToUpdate.length === 0) {
2890
3065
  logger.info(t("update_no_plugins"));
2891
- logger.info(t("update_install_hint").replace("{cmd}", chalk11.cyan("install-helper install <plugin>")));
3066
+ logger.info(t("update_install_hint").replace("{cmd}", chalk12.cyan("install-helper install <plugin>")));
2892
3067
  return;
2893
3068
  }
2894
3069
  } else {
@@ -2950,42 +3125,42 @@ async function updateCommand(pluginNames, options) {
2950
3125
  }
2951
3126
 
2952
3127
  // src/commands/info.ts
2953
- import chalk12 from "chalk";
3128
+ import chalk13 from "chalk";
2954
3129
  import { existsSync as existsSync14, readdirSync as readdirSync7 } from "fs";
2955
3130
  import { join as join15 } from "path";
2956
3131
  async function infoCommand(pluginName) {
2957
3132
  const plugin = findPlugin(pluginName);
2958
3133
  if (!plugin) {
2959
- console.log(chalk12.red(` ${t("info_not_found")}: ${pluginName}`));
3134
+ console.log(chalk13.red(` ${t("info_not_found")}: ${pluginName}`));
2960
3135
  return;
2961
3136
  }
2962
3137
  const installed = scanInstalled();
2963
3138
  const isInstalled = installed.some((p) => p.id === plugin.id);
2964
- const statusText = isInstalled ? chalk12.green(`\u2713 ${t("status_installed")}`) : chalk12.dim(`\u2014 ${t("status_not_installed")}`);
3139
+ const statusText = isInstalled ? chalk13.green(`\u2713 ${t("status_installed")}`) : chalk13.dim(`\u2014 ${t("status_not_installed")}`);
2965
3140
  console.log();
2966
- console.log(chalk12.bold(` ${plugin.displayName}`));
2967
- console.log(chalk12.dim(" " + "\u2500".repeat(40)));
3141
+ console.log(chalk13.bold(` ${plugin.displayName}`));
3142
+ console.log(chalk13.dim(" " + "\u2500".repeat(40)));
2968
3143
  console.log();
2969
- console.log(` ${chalk12.dim(t("info_description") + ":")} ${plugin.description}`);
2970
- console.log(` ${chalk12.dim("ID:")} ${plugin.id}`);
2971
- console.log(` ${chalk12.dim(t("info_status") + ":")} ${statusText}`);
2972
- console.log(` ${chalk12.dim(t("info_skills") + ":")} ${plugin.skills}`);
2973
- console.log(` ${chalk12.dim(t("info_agents") + ":")} ${plugin.agents}`);
2974
- console.log(` ${chalk12.dim(t("info_aliases") + ":")} ${plugin.aliases.join(", ")}`);
3144
+ console.log(` ${chalk13.dim(t("info_description") + ":")} ${plugin.description}`);
3145
+ console.log(` ${chalk13.dim("ID:")} ${plugin.id}`);
3146
+ console.log(` ${chalk13.dim(t("info_status") + ":")} ${statusText}`);
3147
+ console.log(` ${chalk13.dim(t("info_skills") + ":")} ${plugin.skills}`);
3148
+ console.log(` ${chalk13.dim(t("info_agents") + ":")} ${plugin.agents}`);
3149
+ console.log(` ${chalk13.dim(t("info_aliases") + ":")} ${plugin.aliases.join(", ")}`);
2975
3150
  console.log();
2976
3151
  try {
2977
3152
  const repoManager = createRepositoryManager();
2978
3153
  const repoPath = await repoManager.ensureRepo();
2979
3154
  const quickstartPath = join15(repoPath, plugin.dir, "quickstart.md");
2980
3155
  if (existsSync14(quickstartPath)) {
2981
- console.log(` ${chalk12.dim(t("info_quickstart") + ":")} ${quickstartPath}`);
3156
+ console.log(` ${chalk13.dim(t("info_quickstart") + ":")} ${quickstartPath}`);
2982
3157
  }
2983
3158
  const agentsDir = join15(repoPath, plugin.dir, "agents");
2984
3159
  if (existsSync14(agentsDir)) {
2985
3160
  const agentFiles = readdirSync7(agentsDir).filter((f) => f.endsWith(".md"));
2986
3161
  if (agentFiles.length > 0) {
2987
3162
  console.log();
2988
- console.log(` ${chalk12.bold("Agents:")}`);
3163
+ console.log(` ${chalk13.bold("Agents:")}`);
2989
3164
  for (const agent of agentFiles) {
2990
3165
  console.log(` \u2022 ${agent.replace(".md", "")}`);
2991
3166
  }
@@ -2997,39 +3172,39 @@ async function infoCommand(pluginName) {
2997
3172
  }
2998
3173
 
2999
3174
  // src/commands/lang.ts
3000
- import chalk13 from "chalk";
3175
+ import chalk14 from "chalk";
3001
3176
  async function langCommand(action, value) {
3002
3177
  const config = readConfig();
3003
3178
  if (!action || action === "show") {
3004
3179
  console.log();
3005
- console.log(chalk13.bold(` ${t("lang_title")}`));
3006
- console.log(chalk13.dim(" " + "\u2500".repeat(40)));
3180
+ console.log(chalk14.bold(` ${t("lang_title")}`));
3181
+ console.log(chalk14.dim(" " + "\u2500".repeat(40)));
3007
3182
  console.log();
3008
- console.log(` ${chalk13.dim(t("lang_current") + ":")} ${config.language}`);
3183
+ console.log(` ${chalk14.dim(t("lang_current") + ":")} ${config.language}`);
3009
3184
  console.log();
3010
- console.log(chalk13.dim(` ${t("lang_supported")}`));
3011
- console.log(chalk13.dim(` ${t("lang_usage")}`));
3185
+ console.log(chalk14.dim(` ${t("lang_supported")}`));
3186
+ console.log(chalk14.dim(` ${t("lang_usage")}`));
3012
3187
  console.log();
3013
3188
  return;
3014
3189
  }
3015
3190
  if (action === "set") {
3016
3191
  if (!value) {
3017
- console.log(chalk13.red(` ${t("lang_specify")}`));
3192
+ console.log(chalk14.red(` ${t("lang_specify")}`));
3018
3193
  return;
3019
3194
  }
3020
3195
  if (value !== "zh_CN" && value !== "en_US") {
3021
- console.log(chalk13.red(` ${t("lang_invalid")}`));
3196
+ console.log(chalk14.red(` ${t("lang_invalid")}`));
3022
3197
  return;
3023
3198
  }
3024
3199
  updateConfig({ language: value });
3025
3200
  setLanguage(value);
3026
3201
  console.log();
3027
- console.log(chalk13.green(` \u2713 ${t("lang_set")} ${value}`));
3202
+ console.log(chalk14.green(` \u2713 ${t("lang_set")} ${value}`));
3028
3203
  console.log();
3029
3204
  return;
3030
3205
  }
3031
- console.log(chalk13.red(` ${t("lang_unknown_action")}: ${action}`));
3032
- console.log(chalk13.dim(` ${t("lang_supported_actions")}`));
3206
+ console.log(chalk14.red(` ${t("lang_unknown_action")}: ${action}`));
3207
+ console.log(chalk14.dim(` ${t("lang_supported_actions")}`));
3033
3208
  }
3034
3209
 
3035
3210
  // src/cli.ts
@@ -3039,7 +3214,7 @@ function createCLI() {
3039
3214
  setLanguage(config.language);
3040
3215
  }
3041
3216
  const program2 = new Command();
3042
- program2.name("install-helper").description("CANNBot Install Helper - Interactive installer for CANN operator development skills").version("1.0.3");
3217
+ program2.name("install-helper").description("CANNBot Install Helper - Interactive installer for CANN operator development skills").version("1.0.6");
3043
3218
  program2.command("init", { isDefault: false }).description("Run interactive installation wizard").action(async () => {
3044
3219
  await initCommand();
3045
3220
  });
@@ -3052,7 +3227,7 @@ function createCLI() {
3052
3227
  program2.command("status").description("Show installed plugins").action(async () => {
3053
3228
  await statusCommand();
3054
3229
  });
3055
- program2.command("install [names...]").description("Install plugins or skills (auto-detects type)").option("-t, --tool <tool>", "AI tool (opencode, claude, trae, cursor, copilot)").option("-l, --level <level>", "Install level (project, global)", "project").option("-y, --yes", "Skip confirmation prompts").option("--list", "List all available skills by category").action(async (names, options) => {
3230
+ program2.command("install [names...]").description("Install plugins or skills (auto-detects type)").option("-t, --tool <tool>", "AI tool (opencode, claude, trae, cursor, copilot)").option("-l, --level <level>", "Install level (project, global)", "project").option("-y, --yes", "Skip confirmation prompts").option("-a, --all", "Install ALL available skills").option("--list", "List all available skills by category").action(async (names, options) => {
3056
3231
  await installCommand(names, options);
3057
3232
  });
3058
3233
  program2.command("uninstall <names...>").description("Uninstall plugins or skills (auto-detects type)").option("-t, --tool <tool>", "AI tool (opencode, claude, trae, cursor, copilot)").option("-l, --level <level>", "Install level (project, global)", "project").action(async (names, options) => {