@cannbot-ai/install-helper 1.0.4 → 1.0.7

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