@cannbot-ai/install-helper 0.0.2-beta.6 → 0.0.2-beta.8

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
@@ -4,8 +4,8 @@
4
4
  import { Command } from "commander";
5
5
 
6
6
  // src/commands/init.ts
7
- import { select as select3, Separator as Separator3 } from "@inquirer/prompts";
8
- import chalk5 from "chalk";
7
+ import { select as select4, Separator as Separator3 } from "@inquirer/prompts";
8
+ import chalk6 from "chalk";
9
9
 
10
10
  // src/ui/wizard.ts
11
11
  import { select, checkbox, Separator } from "@inquirer/prompts";
@@ -478,10 +478,40 @@ var zh_CN = {
478
478
  status_install_time: "\u5B89\u88C5\u65F6\u95F4",
479
479
  install_installed_to: "\u5B89\u88C5\u5230",
480
480
  install_skills_count: "Skills",
481
- install_agents_count: "Agents"
481
+ install_agents_count: "Agents",
482
+ lang_supported: "\u652F\u6301\u7684\u8BED\u8A00: zh_CN, en_US",
483
+ lang_usage: "\u7528\u6CD5: install-helper lang set <language>",
484
+ lang_specify: "\u8BF7\u6307\u5B9A\u8BED\u8A00: install-helper lang set zh_CN",
485
+ lang_unknown_action: "\u672A\u77E5\u64CD\u4F5C",
486
+ lang_supported_actions: "\u652F\u6301\u7684\u64CD\u4F5C: show, set",
487
+ info_aliases: "\u522B\u540D",
488
+ uninstall_not_found: "\u672A\u627E\u5230",
489
+ uninstall_no_record: "\u672A\u627E\u5230\u5B89\u88C5\u8BB0\u5F55\uFF0C\u53EF\u80FD\u672A\u5B89\u88C5\u6216\u5B89\u88C5\u8BB0\u5F55\u5DF2\u635F\u574F",
490
+ uninstall_no_record_hint: "\u5982\u9700\u5F3A\u5236\u6E05\u7406\uFF0C\u8BF7\u624B\u52A8\u5220\u9664 .opencode/ \u6216 .claude/ \u76EE\u5F55\u4E2D\u7684\u76F8\u5173\u6587\u4EF6",
491
+ uninstall_in_progress: "\u6B63\u5728\u5378\u8F7D",
492
+ uninstall_removed: "\u5DF2\u5378\u8F7D",
493
+ uninstall_files_gone: "\u7684\u6587\u4EF6\u5DF2\u4E0D\u5B58\u5728\uFF0C\u5DF2\u6E05\u7406\u5B89\u88C5\u8BB0\u5F55",
494
+ uninstall_skills_in_progress: "\u6B63\u5728\u5378\u8F7D",
495
+ init_pkg_dir_warn: "\u5F53\u524D\u76EE\u5F55\u770B\u8D77\u6765\u662F install-helper \u5305\u76EE\u5F55",
496
+ init_pkg_dir_hint: "\u8BF7\u5728\u4F60\u7684\u9879\u76EE\u76EE\u5F55\u4E2D\u8FD0\u884C\u6B64\u547D\u4EE4\uFF0C\u800C\u4E0D\u662F\u5728 install-helper \u5B89\u88C5\u76EE\u5F55\u4E2D",
497
+ init_pkg_dir_example: "\u793A\u4F8B\uFF1Acd ~/my-project && install-helper",
498
+ init_cancelled: "\u5DF2\u53D6\u6D88\u5B89\u88C5",
499
+ backup_detected: "\u68C0\u6D4B\u5230\u5F53\u524D\u76EE\u5F55\u5DF2\u5B89\u88C5\u63D2\u4EF6",
500
+ backup_current: "\u5F53\u524D\u5B89\u88C5",
501
+ backup_installing: "\u5373\u5C06\u5B89\u88C5",
502
+ backup_overwrite_warning: "\u7EE7\u7EED\u5B89\u88C5\u5C06\u8986\u76D6\u73B0\u6709\u7684 AGENTS.md \u914D\u7F6E\u6587\u4EF6\u3002",
503
+ backup_auto_create: "\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u521B\u5EFA\u5907\u4EFD\uFF0C\u4EE5\u4FBF\u540E\u7EED\u6062\u590D\u3002",
504
+ backup_overwrite: "\u8986\u76D6\u5B89\u88C5\uFF08\u81EA\u52A8\u5907\u4EFD\uFF09",
505
+ backup_cancel: "\u53D6\u6D88\u5B89\u88C5",
506
+ backup_restore_prompt: "\u68C0\u6D4B\u5230\u5907\u4EFD\u914D\u7F6E\uFF0C\u662F\u5426\u6062\u590D\uFF1F",
507
+ backup_restore: "\u6062\u590D",
508
+ backup_only_uninstall: "\u4EC5\u5378\u8F7D\uFF08\u4E0D\u6062\u590D\uFF09",
509
+ backup_select_action: "\u8BF7\u9009\u62E9\u64CD\u4F5C",
510
+ backup_restore_success: "\u5DF2\u6062\u590D\u914D\u7F6E",
511
+ backup_created: "\u5DF2\u521B\u5EFA\u5907\u4EFD"
482
512
  };
483
513
  var en_US = {
484
- wizard_title: "CANNBot Skills Setup Wizard",
514
+ wizard_title: "CANNBot Install Helper",
485
515
  wizard_detect: "Detecting installed AI coding tools...",
486
516
  wizard_select_tool: "Select AI coding tool",
487
517
  wizard_select_level: "Select install level",
@@ -566,7 +596,37 @@ var en_US = {
566
596
  status_install_time: "Installed at",
567
597
  install_installed_to: "Installed to",
568
598
  install_skills_count: "Skills",
569
- install_agents_count: "Agents"
599
+ install_agents_count: "Agents",
600
+ lang_supported: "Supported languages: zh_CN, en_US",
601
+ lang_usage: "Usage: install-helper lang set <language>",
602
+ lang_specify: "Please specify language: install-helper lang set zh_CN",
603
+ lang_unknown_action: "Unknown action",
604
+ lang_supported_actions: "Supported actions: show, set",
605
+ info_aliases: "Aliases",
606
+ uninstall_not_found: "Not found",
607
+ uninstall_no_record: "No install record found, may not be installed or record is corrupted",
608
+ uninstall_no_record_hint: "For manual cleanup, delete related files in .opencode/ or .claude/ directory",
609
+ uninstall_in_progress: "Uninstalling",
610
+ uninstall_removed: "Uninstalled",
611
+ uninstall_files_gone: " files no longer exist, install record cleaned",
612
+ uninstall_skills_in_progress: "Uninstalling",
613
+ init_pkg_dir_warn: "Current directory appears to be the install-helper package directory",
614
+ init_pkg_dir_hint: "Please run this command in your project directory, not in the install-helper package directory",
615
+ init_pkg_dir_example: "Example: cd ~/my-project && install-helper",
616
+ init_cancelled: "Installation cancelled",
617
+ backup_detected: "Plugin already installed in current directory",
618
+ backup_current: "Currently installed",
619
+ backup_installing: "About to install",
620
+ backup_overwrite_warning: "Continuing will overwrite existing AGENTS.md configuration.",
621
+ backup_auto_create: "System will automatically create backup for future restoration.",
622
+ backup_overwrite: "Overwrite (auto backup)",
623
+ backup_cancel: "Cancel installation",
624
+ backup_restore_prompt: "Backup configuration detected, restore?",
625
+ backup_restore: "Restore",
626
+ backup_only_uninstall: "Uninstall only (no restore)",
627
+ backup_select_action: "Please select an action",
628
+ backup_restore_success: "Configuration restored",
629
+ backup_created: "Backup created"
570
630
  };
571
631
  var currentLang = "zh_CN";
572
632
  function setLanguage(lang) {
@@ -970,7 +1030,7 @@ import { execa as execa2 } from "execa";
970
1030
 
971
1031
  // src/core/scanner.ts
972
1032
  import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync3, statSync, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
973
- import { join as join5, dirname } from "path";
1033
+ import { join as join5 } from "path";
974
1034
  import { parse as parseYaml } from "yaml";
975
1035
  var EXCLUDE_DIRS = /* @__PURE__ */ new Set([
976
1036
  "node_modules",
@@ -1483,8 +1543,8 @@ function createRepositoryManager(customPath) {
1483
1543
  }
1484
1544
 
1485
1545
  // src/core/installer.ts
1486
- import { existsSync as existsSync8 } from "fs";
1487
- import { join as join8 } from "path";
1546
+ import { existsSync as existsSync9 } from "fs";
1547
+ import { join as join9 } from "path";
1488
1548
  import { execa as execa3 } from "execa";
1489
1549
 
1490
1550
  // src/core/record.ts
@@ -1658,6 +1718,179 @@ function getInstalledSkills(tool, level, installPath) {
1658
1718
  return record[tool]?.[level]?.[installPath]?.skills || [];
1659
1719
  }
1660
1720
 
1721
+ // src/core/backup.ts
1722
+ import { existsSync as existsSync8, copyFileSync, readdirSync as readdirSync3, unlinkSync as unlinkSync2 } from "fs";
1723
+ import { join as join8 } from "path";
1724
+ function getAgentsFileName(tool) {
1725
+ return tool === "claude" ? "CLAUDE.md" : "AGENTS.md";
1726
+ }
1727
+ function detectCurrentPlugin(configRoot, tool) {
1728
+ const manifest = readManifest(configRoot);
1729
+ if (manifest?.team) {
1730
+ const plugin = findPlugin(manifest.team);
1731
+ if (plugin) {
1732
+ return {
1733
+ pluginId: plugin.id,
1734
+ pluginName: plugin.displayName
1735
+ };
1736
+ }
1737
+ }
1738
+ const agentsFile = join8(configRoot, getAgentsFileName(tool));
1739
+ if (!existsSync8(agentsFile)) {
1740
+ return null;
1741
+ }
1742
+ const allRecords = readAllRecords();
1743
+ for (const record of allRecords) {
1744
+ if (record.configRoot === configRoot && record.tool === tool) {
1745
+ const plugin = findPlugin(record.pluginId);
1746
+ if (plugin) {
1747
+ return {
1748
+ pluginId: plugin.id,
1749
+ pluginName: plugin.displayName
1750
+ };
1751
+ }
1752
+ }
1753
+ }
1754
+ return null;
1755
+ }
1756
+ function createBackup(configRoot, tool, fromPluginId, fromPluginName) {
1757
+ const agentsFile = join8(configRoot, getAgentsFileName(tool));
1758
+ if (!existsSync8(agentsFile)) {
1759
+ return null;
1760
+ }
1761
+ const timestamp = formatTimestamp(/* @__PURE__ */ new Date());
1762
+ const backupFileName = `${getAgentsFileName(tool)}.cannbot-backup.${fromPluginId}.${timestamp}`;
1763
+ const backupPath = join8(configRoot, backupFileName);
1764
+ try {
1765
+ copyFileSync(agentsFile, backupPath);
1766
+ return {
1767
+ filePath: backupPath,
1768
+ pluginId: fromPluginId,
1769
+ pluginName: fromPluginName,
1770
+ backupTime: timestamp
1771
+ };
1772
+ } catch {
1773
+ return null;
1774
+ }
1775
+ }
1776
+ function findBackups(configRoot) {
1777
+ if (!existsSync8(configRoot)) {
1778
+ return [];
1779
+ }
1780
+ const files = readdirSync3(configRoot);
1781
+ const backups = [];
1782
+ for (const file of files) {
1783
+ if (file.includes(".cannbot-backup.")) {
1784
+ const parts = file.split(".cannbot-backup.");
1785
+ if (parts.length === 2) {
1786
+ const pluginIdAndTime = parts[1];
1787
+ const lastDotIndex = pluginIdAndTime.lastIndexOf(".");
1788
+ if (lastDotIndex > 0) {
1789
+ const pluginId = pluginIdAndTime.substring(0, lastDotIndex);
1790
+ const timestamp = pluginIdAndTime.substring(lastDotIndex + 1);
1791
+ const plugin = findPlugin(pluginId);
1792
+ backups.push({
1793
+ filePath: join8(configRoot, file),
1794
+ pluginId,
1795
+ pluginName: plugin?.displayName || pluginId,
1796
+ backupTime: timestamp
1797
+ });
1798
+ }
1799
+ }
1800
+ }
1801
+ }
1802
+ return backups.sort((a, b) => b.backupTime.localeCompare(a.backupTime));
1803
+ }
1804
+ function restoreBackup(backupPath, configRoot, tool) {
1805
+ try {
1806
+ const agentsFile = join8(configRoot, getAgentsFileName(tool));
1807
+ copyFileSync(backupPath, agentsFile);
1808
+ return true;
1809
+ } catch {
1810
+ return false;
1811
+ }
1812
+ }
1813
+ function deleteBackup(backupPath) {
1814
+ try {
1815
+ if (existsSync8(backupPath)) {
1816
+ unlinkSync2(backupPath);
1817
+ return true;
1818
+ }
1819
+ return false;
1820
+ } catch {
1821
+ return false;
1822
+ }
1823
+ }
1824
+ function formatTimestamp(date) {
1825
+ const year = date.getFullYear();
1826
+ const month = String(date.getMonth() + 1).padStart(2, "0");
1827
+ const day = String(date.getDate()).padStart(2, "0");
1828
+ const hours = String(date.getHours()).padStart(2, "0");
1829
+ const minutes = String(date.getMinutes()).padStart(2, "0");
1830
+ const seconds = String(date.getSeconds()).padStart(2, "0");
1831
+ return `${year}${month}${day}-${hours}${minutes}${seconds}`;
1832
+ }
1833
+ function readAllRecords() {
1834
+ const records = [];
1835
+ const plugins = [
1836
+ "ops-direct-invoke",
1837
+ "ops-direct-invoke-flash",
1838
+ "ops-registry-invoke",
1839
+ "pypto-op-orchestrator",
1840
+ "triton-op-generator",
1841
+ "tilelang-op-orchestrator",
1842
+ "model-infer-optimize",
1843
+ "catlass-op-generator",
1844
+ "ops-code-reviewer",
1845
+ "torch-compile"
1846
+ ];
1847
+ for (const pluginId of plugins) {
1848
+ const record = readRecord(pluginId);
1849
+ if (record) {
1850
+ records.push(record);
1851
+ }
1852
+ }
1853
+ return records;
1854
+ }
1855
+
1856
+ // src/ui/backup-prompts.ts
1857
+ import { select as select2 } from "@inquirer/prompts";
1858
+ import chalk3 from "chalk";
1859
+ async function showOverwriteWarning(currentPluginName, newPluginName) {
1860
+ console.log();
1861
+ console.log(chalk3.yellow(` \u26A0\uFE0F ${t("backup_detected")}`));
1862
+ console.log();
1863
+ console.log(` ${t("backup_current")}: ${chalk3.cyan(currentPluginName)}`);
1864
+ console.log(` ${t("backup_installing")}: ${chalk3.cyan(newPluginName)}`);
1865
+ console.log();
1866
+ console.log(` ${t("backup_overwrite_warning")}`);
1867
+ console.log(` ${t("backup_auto_create")}`);
1868
+ console.log();
1869
+ const choice = await select2({
1870
+ message: t("backup_select_action"),
1871
+ choices: [
1872
+ { name: t("backup_overwrite"), value: "overwrite" },
1873
+ { name: t("backup_cancel"), value: "cancel" }
1874
+ ]
1875
+ });
1876
+ return choice;
1877
+ }
1878
+ async function showRestorePrompt(backups) {
1879
+ console.log();
1880
+ console.log(chalk3.cyan(` ${t("backup_restore_prompt")}`));
1881
+ console.log();
1882
+ const choices = backups.map((b) => ({
1883
+ name: `${t("backup_restore")} ${b.pluginName} (${b.backupTime})`,
1884
+ value: b.filePath
1885
+ }));
1886
+ choices.push({ name: t("backup_only_uninstall"), value: "none" });
1887
+ const choice = await select2({
1888
+ message: t("backup_select_action"),
1889
+ choices
1890
+ });
1891
+ return choice;
1892
+ }
1893
+
1661
1894
  // src/core/installer.ts
1662
1895
  async function installPlugin(opts) {
1663
1896
  const plugin = getPluginById(opts.pluginId);
@@ -1671,8 +1904,8 @@ async function installPlugin(opts) {
1671
1904
  warnings: []
1672
1905
  };
1673
1906
  }
1674
- const scriptPath = join8(opts.repoPath, plugin.dir, plugin.script);
1675
- if (!existsSync8(scriptPath)) {
1907
+ const scriptPath = join9(opts.repoPath, plugin.dir, plugin.script);
1908
+ if (!existsSync9(scriptPath)) {
1676
1909
  return {
1677
1910
  success: false,
1678
1911
  pluginId: opts.pluginId,
@@ -1687,13 +1920,49 @@ async function installPlugin(opts) {
1687
1920
  args.push(opts.installPath);
1688
1921
  }
1689
1922
  const cwd = opts.installPath || process.cwd();
1923
+ const configRoot = getConfigRoot(opts.tool, opts.level, opts.installPath);
1924
+ const agentsFile = join9(configRoot, getAgentsFileName(opts.tool));
1925
+ let backupInfo = null;
1926
+ if (existsSync9(agentsFile)) {
1927
+ const currentPlugin = detectCurrentPlugin(configRoot, opts.tool);
1928
+ if (currentPlugin && currentPlugin.pluginId !== opts.pluginId) {
1929
+ let choice = "overwrite";
1930
+ if (!opts.yes) {
1931
+ choice = await showOverwriteWarning(
1932
+ currentPlugin.pluginName,
1933
+ plugin.displayName
1934
+ );
1935
+ }
1936
+ if (choice === "cancel") {
1937
+ logger.info(t("backup_cancel"));
1938
+ return {
1939
+ success: false,
1940
+ pluginId: opts.pluginId,
1941
+ skillsCount: 0,
1942
+ agentsCount: 0,
1943
+ errors: [t("backup_cancel")],
1944
+ warnings: []
1945
+ };
1946
+ }
1947
+ backupInfo = createBackup(
1948
+ configRoot,
1949
+ opts.tool,
1950
+ currentPlugin.pluginId,
1951
+ currentPlugin.pluginName
1952
+ );
1953
+ if (backupInfo) {
1954
+ logger.success(`${t("backup_created")}: ${backupInfo.filePath}`);
1955
+ }
1956
+ }
1957
+ }
1690
1958
  try {
1691
- await execa3("bash", [scriptPath, ...args], {
1959
+ const execOptions = {
1692
1960
  cwd,
1693
1961
  timeout: 3e5,
1694
- stdio: "pipe"
1695
- });
1696
- const configRoot = getConfigRoot(opts.tool, opts.level, opts.installPath);
1962
+ stdio: "pipe",
1963
+ input: opts.yes ? "y\n" : void 0
1964
+ };
1965
+ await execa3("bash", [scriptPath, ...args], execOptions);
1697
1966
  const manifest = readManifest(configRoot);
1698
1967
  let skillsCount = 0;
1699
1968
  let agentsCount = 0;
@@ -1714,6 +1983,14 @@ async function installPlugin(opts) {
1714
1983
  configRoot,
1715
1984
  manifest
1716
1985
  );
1986
+ if (backupInfo) {
1987
+ record.backup = {
1988
+ filePath: backupInfo.filePath,
1989
+ fromPluginId: backupInfo.pluginId,
1990
+ fromPluginName: backupInfo.pluginName,
1991
+ backupTime: backupInfo.backupTime
1992
+ };
1993
+ }
1717
1994
  writeRecord(record);
1718
1995
  } catch {
1719
1996
  }
@@ -1739,16 +2016,16 @@ async function installPlugin(opts) {
1739
2016
  }
1740
2017
 
1741
2018
  // src/core/skill-installer.ts
1742
- import { existsSync as existsSync9, mkdirSync as mkdirSync5, symlinkSync, unlinkSync as unlinkSync2, readdirSync as readdirSync3, rmdirSync, realpathSync, lstatSync as lstatSync2 } from "fs";
1743
- import { join as join9 } from "path";
1744
- import { select as select2, checkbox as checkbox2, Separator as Separator2 } from "@inquirer/prompts";
1745
- import chalk3 from "chalk";
2019
+ import { existsSync as existsSync10, mkdirSync as mkdirSync5, symlinkSync, unlinkSync as unlinkSync3, readdirSync as readdirSync4, rmdirSync, realpathSync, lstatSync as lstatSync2 } from "fs";
2020
+ import { join as join10 } from "path";
2021
+ import { select as select3, checkbox as checkbox2, Separator as Separator2 } from "@inquirer/prompts";
2022
+ import chalk4 from "chalk";
1746
2023
  import Table from "cli-table3";
1747
2024
  async function installSkills(skillIds, tool, level, repoPath) {
1748
2025
  const configRoot = getConfigRoot(tool, level);
1749
- const skillsDir = join9(configRoot, "skills");
2026
+ const skillsDir = join10(configRoot, "skills");
1750
2027
  const installPath = level === "project" ? process.cwd() : configRoot;
1751
- if (!existsSync9(skillsDir)) {
2028
+ if (!existsSync10(skillsDir)) {
1752
2029
  mkdirSync5(skillsDir, { recursive: true });
1753
2030
  }
1754
2031
  const results = [];
@@ -1759,15 +2036,15 @@ async function installSkills(skillIds, tool, level, repoPath) {
1759
2036
  results.push({ skillId, success: false, error: "Skill not found in registry" });
1760
2037
  continue;
1761
2038
  }
1762
- const sourcePath = join9(repoPath, skill.source, skill.id);
1763
- const targetPath = join9(skillsDir, skillId);
1764
- if (!existsSync9(sourcePath)) {
2039
+ const sourcePath = join10(repoPath, skill.source, skill.id);
2040
+ const targetPath = join10(skillsDir, skillId);
2041
+ if (!existsSync10(sourcePath)) {
1765
2042
  results.push({ skillId, success: false, error: `Source not found: ${sourcePath}` });
1766
2043
  continue;
1767
2044
  }
1768
2045
  try {
1769
- if (existsSync9(targetPath) || isSymlink2(targetPath)) {
1770
- unlinkSync2(targetPath);
2046
+ if (existsSync10(targetPath) || isSymlink2(targetPath)) {
2047
+ unlinkSync3(targetPath);
1771
2048
  }
1772
2049
  symlinkSync(realpathSync(sourcePath), targetPath);
1773
2050
  results.push({ skillId, success: true });
@@ -1783,15 +2060,15 @@ async function installSkills(skillIds, tool, level, repoPath) {
1783
2060
  }
1784
2061
  async function uninstallSkills(skillIds, tool, level) {
1785
2062
  const configRoot = getConfigRoot(tool, level);
1786
- const skillsDir = join9(configRoot, "skills");
2063
+ const skillsDir = join10(configRoot, "skills");
1787
2064
  const installPath = level === "project" ? process.cwd() : configRoot;
1788
2065
  const results = [];
1789
2066
  const removedIds = [];
1790
2067
  for (const skillId of skillIds) {
1791
- const targetPath = join9(skillsDir, skillId);
2068
+ const targetPath = join10(skillsDir, skillId);
1792
2069
  try {
1793
- if (existsSync9(targetPath) || isSymlink2(targetPath)) {
1794
- unlinkSync2(targetPath);
2070
+ if (existsSync10(targetPath) || isSymlink2(targetPath)) {
2071
+ unlinkSync3(targetPath);
1795
2072
  results.push({ skillId, success: true });
1796
2073
  removedIds.push(skillId);
1797
2074
  logger.step(` \u79FB\u9664: ${skillId}`);
@@ -1806,9 +2083,9 @@ async function uninstallSkills(skillIds, tool, level) {
1806
2083
  if (removedIds.length > 0) {
1807
2084
  removeSkillsFromRecord(removedIds, tool, level, installPath);
1808
2085
  }
1809
- if (existsSync9(skillsDir)) {
2086
+ if (existsSync10(skillsDir)) {
1810
2087
  try {
1811
- const entries = readdirSync3(skillsDir);
2088
+ const entries = readdirSync4(skillsDir);
1812
2089
  if (entries.length === 0) {
1813
2090
  rmdirSync(skillsDir);
1814
2091
  logger.step(` \u6E05\u7406\u7A7A\u76EE\u5F55: skills/`);
@@ -1816,9 +2093,9 @@ async function uninstallSkills(skillIds, tool, level) {
1816
2093
  } catch {
1817
2094
  }
1818
2095
  }
1819
- if (existsSync9(configRoot)) {
2096
+ if (existsSync10(configRoot)) {
1820
2097
  try {
1821
- const entries = readdirSync3(configRoot);
2098
+ const entries = readdirSync4(configRoot);
1822
2099
  if (entries.length === 0) {
1823
2100
  rmdirSync(configRoot);
1824
2101
  logger.step(` \u6E05\u7406\u7A7A\u76EE\u5F55: ${configRoot.split("/").pop()}/`);
@@ -1848,7 +2125,7 @@ async function interactiveSkillSelect() {
1848
2125
  { name: "x " + t("wizard_cancel"), value: CANCEL3 }
1849
2126
  ];
1850
2127
  showOperationHints();
1851
- selectedCategoryId = await select2({
2128
+ selectedCategoryId = await select3({
1852
2129
  message: t("skill_select_category"),
1853
2130
  choices: categoryChoices,
1854
2131
  loop: false,
@@ -1894,7 +2171,7 @@ async function interactiveSkillSelect() {
1894
2171
  });
1895
2172
  const skillIds = selectedSkills;
1896
2173
  if (skillIds.length === 0) {
1897
- const action = await select2({
2174
+ const action = await select3({
1898
2175
  message: t("wizard_no_selection"),
1899
2176
  choices: [
1900
2177
  new Separator2("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
@@ -1918,11 +2195,11 @@ async function interactiveSkillSelect() {
1918
2195
  function listAllSkills() {
1919
2196
  const categories = getAllCategories();
1920
2197
  console.log();
1921
- console.log(chalk3.bold(` ${t("skill_list_title")}`));
1922
- console.log(chalk3.dim(" " + "\u2500".repeat(60)));
2198
+ console.log(chalk4.bold(` ${t("skill_list_title")}`));
2199
+ console.log(chalk4.dim(" " + "\u2500".repeat(60)));
1923
2200
  for (const category of categories) {
1924
2201
  console.log();
1925
- console.log(chalk3.bold(` ${category.name}`) + chalk3.dim(` (${category.skills.length} skills)`));
2202
+ console.log(chalk4.bold(` ${category.name}`) + chalk4.dim(` (${category.skills.length} skills)`));
1926
2203
  const table = new Table({
1927
2204
  style: { head: [], border: [] },
1928
2205
  colWidths: [35, 45],
@@ -1930,14 +2207,14 @@ function listAllSkills() {
1930
2207
  });
1931
2208
  for (const skill of category.skills) {
1932
2209
  table.push([
1933
- chalk3.cyan(skill.id),
2210
+ chalk4.cyan(skill.id),
1934
2211
  skill.description
1935
2212
  ]);
1936
2213
  }
1937
2214
  console.log(table.toString());
1938
2215
  }
1939
2216
  console.log();
1940
- console.log(chalk3.dim(` \u5171 ${getAllSkills().length} \u4E2A Skills`));
2217
+ console.log(chalk4.dim(` \u5171 ${getAllSkills().length} \u4E2A Skills`));
1941
2218
  console.log();
1942
2219
  }
1943
2220
  function isSymlink2(path) {
@@ -1949,22 +2226,22 @@ function isSymlink2(path) {
1949
2226
  }
1950
2227
 
1951
2228
  // src/ui/display.ts
1952
- import chalk4 from "chalk";
2229
+ import chalk5 from "chalk";
1953
2230
  import Table2 from "cli-table3";
1954
2231
  function printPluginList(plugins, installed) {
1955
2232
  const table = new Table2({
1956
2233
  head: [
1957
- chalk4.cyan(t("list_id")),
1958
- chalk4.cyan(t("list_name")),
1959
- chalk4.cyan(t("list_status")),
1960
- chalk4.cyan(t("list_skills")),
1961
- chalk4.cyan(t("list_agents"))
2234
+ chalk5.cyan(t("list_id")),
2235
+ chalk5.cyan(t("list_name")),
2236
+ chalk5.cyan(t("list_status")),
2237
+ chalk5.cyan(t("list_skills")),
2238
+ chalk5.cyan(t("list_agents"))
1962
2239
  ],
1963
2240
  style: { head: [], border: [] }
1964
2241
  });
1965
2242
  plugins.forEach((plugin, index) => {
1966
2243
  const isInstalled = installed.has(plugin.id);
1967
- const status = isInstalled ? chalk4.green(`\u2713 ${t("status_installed")}`) : chalk4.dim(`\u2014`);
2244
+ const status = isInstalled ? chalk5.green(`\u2713 ${t("status_installed")}`) : chalk5.dim(`\u2014`);
1968
2245
  table.push([
1969
2246
  String(index + 1),
1970
2247
  plugin.displayName,
@@ -1974,7 +2251,7 @@ function printPluginList(plugins, installed) {
1974
2251
  ]);
1975
2252
  });
1976
2253
  console.log();
1977
- console.log(chalk4.bold(` ${t("list_title")} (${plugins.length} \u4E2A)`));
2254
+ console.log(chalk5.bold(` ${t("list_title")} (${plugins.length} \u4E2A)`));
1978
2255
  console.log(table.toString());
1979
2256
  console.log();
1980
2257
  }
@@ -1983,7 +2260,7 @@ function printInstallSummary(results) {
1983
2260
  const totalCount = results.length;
1984
2261
  console.log();
1985
2262
  console.log(
1986
- chalk4.bold(
2263
+ chalk5.bold(
1987
2264
  ` ${t("install_done")}! ${successCount}/${totalCount} ${t("install_success")}`
1988
2265
  )
1989
2266
  );
@@ -1991,10 +2268,10 @@ function printInstallSummary(results) {
1991
2268
  for (const result of results) {
1992
2269
  if (result.success) {
1993
2270
  console.log(
1994
- chalk4.green(" \u2713") + ` ${result.displayName} (${result.skillsCount} skills, ${result.agentsCount} agents)`
2271
+ chalk5.green(" \u2713") + ` ${result.displayName} (${result.skillsCount} skills, ${result.agentsCount} agents)`
1995
2272
  );
1996
2273
  } else {
1997
- console.log(chalk4.red(" \u2717") + ` ${result.displayName}`);
2274
+ console.log(chalk5.red(" \u2717") + ` ${result.displayName}`);
1998
2275
  }
1999
2276
  }
2000
2277
  console.log();
@@ -2008,21 +2285,21 @@ function printEnhancedSummary(results, tool, configRoot) {
2008
2285
  }
2009
2286
  const toolName = getToolDisplayName(tool);
2010
2287
  const lines = [
2011
- chalk4.bold(` ${t("install_done")}!`),
2288
+ chalk5.bold(` ${t("install_done")}!`),
2012
2289
  "",
2013
- ` ${chalk4.dim(t("install_installed_to") + ":")} ${configRoot}`,
2014
- ` ${chalk4.dim(t("install_skills_count") + ":")} ${totalSkills} \u4E2A ${chalk4.dim("|")} ${chalk4.dim(t("install_agents_count") + ":")} ${totalAgents} \u4E2A`,
2290
+ ` ${chalk5.dim(t("install_installed_to") + ":")} ${configRoot}`,
2291
+ ` ${chalk5.dim(t("install_skills_count") + ":")} ${totalSkills} \u4E2A ${chalk5.dim("|")} ${chalk5.dim(t("install_agents_count") + ":")} ${totalAgents} \u4E2A`,
2015
2292
  "",
2016
- chalk4.bold(` ${t("install_enhanced_next_steps")}:`),
2017
- ` ${chalk4.cyan("1.")} ${t("install_enhanced_launch")}: ${chalk4.green(toolName.toLowerCase())}`,
2018
- ` ${chalk4.cyan("2.")} ${t("install_enhanced_try")}: ${chalk4.green("\u5E2E\u6211\u5F00\u53D1\u4E00\u4E2A Abs \u7B97\u5B50")}`,
2019
- ` ${chalk4.cyan("3.")} ${t("install_enhanced_more")}: ${chalk4.green("install-helper list")}`,
2020
- ` ${chalk4.cyan("4.")} ${t("install_enhanced_check")}: ${chalk4.green("install-helper doctor")}`,
2293
+ chalk5.bold(` ${t("install_enhanced_next_steps")}:`),
2294
+ ` ${chalk5.cyan("1.")} ${t("install_enhanced_launch")}: ${chalk5.green(toolName.toLowerCase())}`,
2295
+ ` ${chalk5.cyan("2.")} ${t("install_enhanced_try")}: ${chalk5.green("\u5E2E\u6211\u5F00\u53D1\u4E00\u4E2A Abs \u7B97\u5B50")}`,
2296
+ ` ${chalk5.cyan("3.")} ${t("install_enhanced_more")}: ${chalk5.green("install-helper list")}`,
2297
+ ` ${chalk5.cyan("4.")} ${t("install_enhanced_check")}: ${chalk5.green("install-helper doctor")}`,
2021
2298
  ""
2022
2299
  ];
2023
2300
  if (successResults.length === 1) {
2024
2301
  lines.push(
2025
- ` ${chalk4.dim(t("install_enhanced_docs"))}: ${chalk4.dim(`plugins-official/${successResults[0].pluginId}/quickstart.md`)}`
2302
+ ` ${chalk5.dim(t("install_enhanced_docs"))}: ${chalk5.dim(`plugins-official/${successResults[0].pluginId}/quickstart.md`)}`
2026
2303
  );
2027
2304
  }
2028
2305
  console.log();
@@ -2033,23 +2310,23 @@ function printEnhancedSummary(results, tool, configRoot) {
2033
2310
  }
2034
2311
 
2035
2312
  // src/commands/init.ts
2036
- import { existsSync as existsSync10, readFileSync as readFileSync5 } from "fs";
2037
- import { join as join10 } from "path";
2313
+ import { existsSync as existsSync11, readFileSync as readFileSync5 } from "fs";
2314
+ import { join as join11 } from "path";
2038
2315
  var BACK2 = "__back__";
2039
2316
  var CANCEL2 = "__cancel__";
2040
2317
  async function initCommand() {
2041
2318
  const cwd = process.cwd();
2042
- if (existsSync10(join10(cwd, "package.json")) && (() => {
2319
+ if (existsSync11(join11(cwd, "package.json")) && (() => {
2043
2320
  try {
2044
- const pkg = JSON.parse(readFileSync5(join10(cwd, "package.json"), "utf-8"));
2321
+ const pkg = JSON.parse(readFileSync5(join11(cwd, "package.json"), "utf-8"));
2045
2322
  return pkg.name === "@cannbot-ai/install-helper";
2046
2323
  } catch {
2047
2324
  return false;
2048
2325
  }
2049
2326
  })()) {
2050
- logger.warn("\u5F53\u524D\u76EE\u5F55\u770B\u8D77\u6765\u662F install-helper \u5305\u76EE\u5F55");
2051
- logger.info("\u8BF7\u5728\u4F60\u7684\u9879\u76EE\u76EE\u5F55\u4E2D\u8FD0\u884C\u6B64\u547D\u4EE4\uFF0C\u800C\u4E0D\u662F\u5728 install-helper \u5B89\u88C5\u76EE\u5F55\u4E2D");
2052
- logger.info("\u793A\u4F8B\uFF1Acd ~/my-project && install-helper");
2327
+ logger.warn(t("init_pkg_dir_warn"));
2328
+ logger.info(t("init_pkg_dir_hint"));
2329
+ logger.info(t("init_pkg_dir_example"));
2053
2330
  return;
2054
2331
  }
2055
2332
  printBanner(t("wizard_title"));
@@ -2109,7 +2386,7 @@ async function selectMode() {
2109
2386
  { name: "x " + t("wizard_cancel"), value: CANCEL3 }
2110
2387
  ];
2111
2388
  showOperationHints();
2112
- const result = await select3({
2389
+ const result = await select4({
2113
2390
  message: t("wizard_select_mode"),
2114
2391
  choices,
2115
2392
  loop: false,
@@ -2122,7 +2399,7 @@ async function pluginInstallFlow() {
2122
2399
  const answers = await runWizard();
2123
2400
  if (!answers.confirmed) {
2124
2401
  if (answers.back) return "back";
2125
- logger.info("\u5DF2\u53D6\u6D88\u5B89\u88C5");
2402
+ logger.info(t("init_cancelled"));
2126
2403
  return "done";
2127
2404
  }
2128
2405
  const repoManager = createRepositoryManager();
@@ -2183,7 +2460,7 @@ async function skillInstallFlow() {
2183
2460
  const result = await selectToolWithDetection();
2184
2461
  if (result === "back") return "back";
2185
2462
  if (result === "cancel") {
2186
- logger.info("\u5DF2\u53D6\u6D88\u5B89\u88C5");
2463
+ logger.info(t("init_cancelled"));
2187
2464
  return "done";
2188
2465
  }
2189
2466
  tool = result;
@@ -2197,7 +2474,7 @@ async function skillInstallFlow() {
2197
2474
  break;
2198
2475
  }
2199
2476
  if (result === CANCEL2) {
2200
- logger.info("\u5DF2\u53D6\u6D88\u5B89\u88C5");
2477
+ logger.info(t("init_cancelled"));
2201
2478
  return "done";
2202
2479
  }
2203
2480
  level = result;
@@ -2211,7 +2488,7 @@ async function skillInstallFlow() {
2211
2488
  break;
2212
2489
  }
2213
2490
  if (selectedSkills === "cancel") {
2214
- logger.info("\u5DF2\u53D6\u6D88\u5B89\u88C5");
2491
+ logger.info(t("init_cancelled"));
2215
2492
  return "done";
2216
2493
  }
2217
2494
  if (selectedSkills.length === 0) {
@@ -2223,7 +2500,7 @@ async function skillInstallFlow() {
2223
2500
  spinner.start();
2224
2501
  const repoPath = await repoManager.ensureRepo();
2225
2502
  spinner.succeed("\u63D2\u4EF6\u6570\u636E\u52A0\u8F7D\u5B8C\u6210");
2226
- logger.info(`${t("skill_install_progress")} ${chalk5.bold(selectedSkills.length)} \u4E2A Skills...`);
2503
+ logger.info(`${t("skill_install_progress")} ${chalk6.bold(selectedSkills.length)} \u4E2A Skills...`);
2227
2504
  const results = await installSkills(selectedSkills, tool, level, repoPath);
2228
2505
  let successCount = 0;
2229
2506
  let failCount = 0;
@@ -2241,10 +2518,10 @@ async function skillInstallFlow() {
2241
2518
  }
2242
2519
  const configRoot = getConfigRoot(tool, level);
2243
2520
  logger.blank();
2244
- logger.success(`${t("skill_install_done")}: ${chalk5.green(successCount + " \u6210\u529F")}, ${failCount > 0 ? chalk5.red(failCount + " \u5931\u8D25") : chalk5.dim(failCount + " \u5931\u8D25")}`);
2521
+ logger.success(`${t("skill_install_done")}: ${chalk6.green(successCount + " \u6210\u529F")}, ${failCount > 0 ? chalk6.red(failCount + " \u5931\u8D25") : chalk6.dim(failCount + " \u5931\u8D25")}`);
2245
2522
  logger.blank();
2246
- logger.info(`\u5B89\u88C5\u5230: ${chalk5.cyan(configRoot + "/skills/")}`);
2247
- logger.info(`\u542F\u52A8 ${chalk5.green(tool)} \u5373\u53EF\u4F7F\u7528`);
2523
+ logger.info(`\u5B89\u88C5\u5230: ${chalk6.cyan(configRoot + "/skills/")}`);
2524
+ logger.info(`\u542F\u52A8 ${chalk6.green(tool)} \u5373\u53EF\u4F7F\u7528`);
2248
2525
  logger.blank();
2249
2526
  return "done";
2250
2527
  }
@@ -2266,32 +2543,32 @@ async function listCommand() {
2266
2543
  }
2267
2544
 
2268
2545
  // src/commands/doctor.ts
2269
- import chalk6 from "chalk";
2270
- import { existsSync as existsSync11, readdirSync as readdirSync4, lstatSync as lstatSync3, unlinkSync as unlinkSync3, mkdirSync as mkdirSync6 } from "fs";
2271
- import { join as join11 } from "path";
2546
+ import chalk7 from "chalk";
2547
+ import { existsSync as existsSync12, readdirSync as readdirSync5, lstatSync as lstatSync3, unlinkSync as unlinkSync4, mkdirSync as mkdirSync6 } from "fs";
2548
+ import { join as join12 } from "path";
2272
2549
  async function doctorCommand(options = {}) {
2273
2550
  console.log();
2274
- console.log(chalk6.bold(` ${t("doctor_title")}`));
2275
- console.log(chalk6.dim(" " + "\u2500".repeat(46)));
2551
+ console.log(chalk7.bold(` ${t("doctor_title")}`));
2552
+ console.log(chalk7.dim(" " + "\u2500".repeat(46)));
2276
2553
  let errors = 0;
2277
2554
  let warnings = 0;
2278
2555
  let fixes = 0;
2279
2556
  console.log();
2280
- console.log(chalk6.bold(` ${t("doctor_tools")}`));
2557
+ console.log(chalk7.bold(` ${t("doctor_tools")}`));
2281
2558
  const detectedTools = await detectTools();
2282
2559
  const allTools = getAllTools();
2283
2560
  for (const tool of allTools) {
2284
2561
  const detected = detectedTools.find((d) => d.name === tool);
2285
2562
  if (detected) {
2286
2563
  console.log(
2287
- chalk6.green(" \u2713") + ` ${getToolDisplayName(tool)}${detected.version ? ` v${detected.version}` : ""}`
2564
+ chalk7.green(" \u2713") + ` ${getToolDisplayName(tool)}${detected.version ? ` v${detected.version}` : ""}`
2288
2565
  );
2289
2566
  } else {
2290
- console.log(chalk6.dim(" \u2014") + ` ${getToolDisplayName(tool)} \u2014 \u672A\u5B89\u88C5`);
2567
+ console.log(chalk7.dim(" \u2014") + ` ${getToolDisplayName(tool)} \u2014 \u672A\u5B89\u88C5`);
2291
2568
  }
2292
2569
  }
2293
2570
  console.log();
2294
- console.log(chalk6.bold(` ${t("doctor_plugins")}`));
2571
+ console.log(chalk7.bold(` ${t("doctor_plugins")}`));
2295
2572
  const plugins = getAllPlugins();
2296
2573
  const installed = scanInstalled();
2297
2574
  const installedMap = new Map(installed.map((p) => [p.id, p]));
@@ -2299,73 +2576,73 @@ async function doctorCommand(options = {}) {
2299
2576
  const inst = installedMap.get(plugin.id);
2300
2577
  if (inst) {
2301
2578
  console.log(
2302
- chalk6.green(" \u2713") + ` ${plugin.id.padEnd(30)} ${inst.skillsCount} skills, ${inst.agentsCount} agents`
2579
+ chalk7.green(" \u2713") + ` ${plugin.id.padEnd(30)} ${inst.skillsCount} skills, ${inst.agentsCount} agents`
2303
2580
  );
2304
2581
  } else {
2305
- console.log(chalk6.dim(" \u2014") + ` ${plugin.id.padEnd(30)} \u2014 \u672A\u5B89\u88C5`);
2582
+ console.log(chalk7.dim(" \u2014") + ` ${plugin.id.padEnd(30)} \u2014 \u672A\u5B89\u88C5`);
2306
2583
  }
2307
2584
  }
2308
2585
  console.log();
2309
- console.log(chalk6.bold(` ${t("doctor_links")}`));
2586
+ console.log(chalk7.bold(` ${t("doctor_links")}`));
2310
2587
  const primaryTool = detectedTools[0]?.name || "opencode";
2311
2588
  const configRoot = getConfigRoot(primaryTool, "project");
2312
2589
  const skillsDir = getSkillsDir(configRoot);
2313
2590
  const agentsDir = getAgentsDir(configRoot);
2314
- if (existsSync11(skillsDir)) {
2591
+ if (existsSync12(skillsDir)) {
2315
2592
  const brokenLinks = checkBrokenLinks(skillsDir);
2316
2593
  if (brokenLinks === 0) {
2317
- const count = readdirSync4(skillsDir).length;
2318
- console.log(chalk6.green(" \u2713") + ` ${skillsDir} \u2014 ${count} \u4E2A\u8F6F\u94FE\u63A5\u5747\u6709\u6548`);
2594
+ const count = readdirSync5(skillsDir).length;
2595
+ console.log(chalk7.green(" \u2713") + ` ${skillsDir} \u2014 ${count} \u4E2A\u8F6F\u94FE\u63A5\u5747\u6709\u6548`);
2319
2596
  } else {
2320
- console.log(chalk6.yellow(" \u26A0") + ` ${skillsDir} \u2014 ${brokenLinks} \u4E2A\u5931\u6548\u94FE\u63A5`);
2597
+ console.log(chalk7.yellow(" \u26A0") + ` ${skillsDir} \u2014 ${brokenLinks} \u4E2A\u5931\u6548\u94FE\u63A5`);
2321
2598
  warnings++;
2322
2599
  if (options.fix) {
2323
2600
  const fixed = fixBrokenLinks(skillsDir);
2324
2601
  fixes += fixed;
2325
- console.log(chalk6.green(" \u2713") + ` ${t("doctor_fix_cleaning")}: \u5DF2\u6E05\u7406 ${fixed} \u4E2A\u5931\u6548\u94FE\u63A5`);
2602
+ console.log(chalk7.green(" \u2713") + ` ${t("doctor_fix_cleaning")}: \u5DF2\u6E05\u7406 ${fixed} \u4E2A\u5931\u6548\u94FE\u63A5`);
2326
2603
  }
2327
2604
  }
2328
2605
  } else {
2329
- console.log(chalk6.dim(" \u2014") + ` ${skillsDir} \u2014 \u4E0D\u5B58\u5728`);
2606
+ console.log(chalk7.dim(" \u2014") + ` ${skillsDir} \u2014 \u4E0D\u5B58\u5728`);
2330
2607
  if (options.fix) {
2331
2608
  mkdirSync6(skillsDir, { recursive: true });
2332
2609
  fixes++;
2333
- console.log(chalk6.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: \u5DF2\u521B\u5EFA ${skillsDir}`);
2610
+ console.log(chalk7.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: \u5DF2\u521B\u5EFA ${skillsDir}`);
2334
2611
  }
2335
2612
  }
2336
- if (existsSync11(agentsDir)) {
2613
+ if (existsSync12(agentsDir)) {
2337
2614
  const brokenLinks = checkBrokenLinks(agentsDir);
2338
2615
  if (brokenLinks === 0) {
2339
- const count = readdirSync4(agentsDir).length;
2340
- console.log(chalk6.green(" \u2713") + ` ${agentsDir} \u2014 ${count} \u4E2A\u8F6F\u94FE\u63A5\u5747\u6709\u6548`);
2616
+ const count = readdirSync5(agentsDir).length;
2617
+ console.log(chalk7.green(" \u2713") + ` ${agentsDir} \u2014 ${count} \u4E2A\u8F6F\u94FE\u63A5\u5747\u6709\u6548`);
2341
2618
  } else {
2342
- console.log(chalk6.yellow(" \u26A0") + ` ${agentsDir} \u2014 ${brokenLinks} \u4E2A\u5931\u6548\u94FE\u63A5`);
2619
+ console.log(chalk7.yellow(" \u26A0") + ` ${agentsDir} \u2014 ${brokenLinks} \u4E2A\u5931\u6548\u94FE\u63A5`);
2343
2620
  warnings++;
2344
2621
  if (options.fix) {
2345
2622
  const fixed = fixBrokenLinks(agentsDir);
2346
2623
  fixes += fixed;
2347
- console.log(chalk6.green(" \u2713") + ` ${t("doctor_fix_cleaning")}: \u5DF2\u6E05\u7406 ${fixed} \u4E2A\u5931\u6548\u94FE\u63A5`);
2624
+ console.log(chalk7.green(" \u2713") + ` ${t("doctor_fix_cleaning")}: \u5DF2\u6E05\u7406 ${fixed} \u4E2A\u5931\u6548\u94FE\u63A5`);
2348
2625
  }
2349
2626
  }
2350
2627
  } else {
2351
- console.log(chalk6.dim(" \u2014") + ` ${agentsDir} \u2014 \u4E0D\u5B58\u5728`);
2628
+ console.log(chalk7.dim(" \u2014") + ` ${agentsDir} \u2014 \u4E0D\u5B58\u5728`);
2352
2629
  if (options.fix) {
2353
2630
  mkdirSync6(agentsDir, { recursive: true });
2354
2631
  fixes++;
2355
- console.log(chalk6.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: \u5DF2\u521B\u5EFA ${agentsDir}`);
2632
+ console.log(chalk7.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: \u5DF2\u521B\u5EFA ${agentsDir}`);
2356
2633
  }
2357
2634
  }
2358
2635
  console.log();
2359
- console.log(chalk6.bold(` ${t("doctor_config")}`));
2636
+ console.log(chalk7.bold(` ${t("doctor_config")}`));
2360
2637
  const configFile = getConfigFileName(primaryTool);
2361
- const configPath = join11(process.cwd(), configFile);
2362
- if (existsSync11(configPath)) {
2363
- console.log(chalk6.green(" \u2713") + ` ${configFile} \u5B58\u5728`);
2638
+ const configPath = join12(process.cwd(), configFile);
2639
+ if (existsSync12(configPath)) {
2640
+ console.log(chalk7.green(" \u2713") + ` ${configFile} \u5B58\u5728`);
2364
2641
  } else {
2365
- console.log(chalk6.dim(" \u2014") + ` ${configFile} \u4E0D\u5B58\u5728`);
2642
+ console.log(chalk7.dim(" \u2014") + ` ${configFile} \u4E0D\u5B58\u5728`);
2366
2643
  }
2367
2644
  console.log();
2368
- console.log(chalk6.dim(" " + "\u2500".repeat(46)));
2645
+ console.log(chalk7.dim(" " + "\u2500".repeat(46)));
2369
2646
  if (options.fix && fixes > 0) {
2370
2647
  console.log(
2371
2648
  ` ${t("doctor_result")}: ${warnings} \u4E2A\u8B66\u544A, ${errors} \u4E2A\u9519\u8BEF, ${fixes} \u9879\u5DF2\u4FEE\u590D`
@@ -2380,13 +2657,13 @@ async function doctorCommand(options = {}) {
2380
2657
  function checkBrokenLinks(dir) {
2381
2658
  let broken = 0;
2382
2659
  try {
2383
- const entries = readdirSync4(dir);
2660
+ const entries = readdirSync5(dir);
2384
2661
  for (const entry of entries) {
2385
- const fullPath = join11(dir, entry);
2662
+ const fullPath = join12(dir, entry);
2386
2663
  try {
2387
2664
  const stats = lstatSync3(fullPath);
2388
2665
  if (stats.isSymbolicLink()) {
2389
- if (!existsSync11(fullPath)) {
2666
+ if (!existsSync12(fullPath)) {
2390
2667
  broken++;
2391
2668
  }
2392
2669
  }
@@ -2401,14 +2678,14 @@ function checkBrokenLinks(dir) {
2401
2678
  function fixBrokenLinks(dir) {
2402
2679
  let fixed = 0;
2403
2680
  try {
2404
- const entries = readdirSync4(dir);
2681
+ const entries = readdirSync5(dir);
2405
2682
  for (const entry of entries) {
2406
- const fullPath = join11(dir, entry);
2683
+ const fullPath = join12(dir, entry);
2407
2684
  try {
2408
2685
  const stats = lstatSync3(fullPath);
2409
2686
  if (stats.isSymbolicLink()) {
2410
- if (!existsSync11(fullPath)) {
2411
- unlinkSync3(fullPath);
2687
+ if (!existsSync12(fullPath)) {
2688
+ unlinkSync4(fullPath);
2412
2689
  fixed++;
2413
2690
  }
2414
2691
  }
@@ -2421,36 +2698,36 @@ function fixBrokenLinks(dir) {
2421
2698
  }
2422
2699
 
2423
2700
  // src/commands/status.ts
2424
- import chalk7 from "chalk";
2701
+ import chalk8 from "chalk";
2425
2702
  async function statusCommand() {
2426
2703
  const plugins = getAllPlugins();
2427
2704
  const installed = scanInstalled();
2428
2705
  const installedMap = new Map(installed.map((p) => [p.id, p]));
2429
2706
  console.log();
2430
- console.log(chalk7.bold(` ${t("status_title")}`));
2707
+ console.log(chalk8.bold(` ${t("status_title")}`));
2431
2708
  console.log();
2432
2709
  if (installed.length === 0) {
2433
- console.log(chalk7.dim(` ${t("status_none")}`));
2434
- console.log(chalk7.dim(` ${t("status_hint")}`));
2710
+ console.log(chalk8.dim(` ${t("status_none")}`));
2711
+ console.log(chalk8.dim(` ${t("status_hint")}`));
2435
2712
  console.log();
2436
2713
  return;
2437
2714
  }
2438
2715
  for (const inst of installed) {
2439
2716
  console.log(
2440
- chalk7.green(" \u2713") + ` ${inst.displayName}` + chalk7.dim(` (${inst.tool}, ${inst.level})`)
2717
+ chalk8.green(" \u2713") + ` ${inst.displayName}` + chalk8.dim(` (${inst.tool}, ${inst.level})`)
2441
2718
  );
2442
2719
  console.log(
2443
- chalk7.dim(` ${inst.skillsCount} skills, ${inst.agentsCount} agents`)
2720
+ chalk8.dim(` ${inst.skillsCount} skills, ${inst.agentsCount} agents`)
2444
2721
  );
2445
- console.log(chalk7.dim(` ${inst.configRoot}`));
2446
- console.log(chalk7.dim(` ${t("status_install_time")}: ${inst.installTime}`));
2722
+ console.log(chalk8.dim(` ${inst.configRoot}`));
2723
+ console.log(chalk8.dim(` ${t("status_install_time")}: ${inst.installTime}`));
2447
2724
  console.log();
2448
2725
  }
2449
2726
  }
2450
2727
 
2451
2728
  // src/commands/install.ts
2452
2729
  import { confirm } from "@inquirer/prompts";
2453
- import chalk8 from "chalk";
2730
+ import chalk9 from "chalk";
2454
2731
  async function installCommand(names, options) {
2455
2732
  if (options.list) {
2456
2733
  try {
@@ -2496,30 +2773,33 @@ async function installCommand(names, options) {
2496
2773
  }
2497
2774
  names = selectedSkills;
2498
2775
  const repoManager = createRepositoryManager();
2499
- const spinner = createSpinner(t("install_cloning"));
2776
+ const spinner = createSpinner("\u6B63\u5728\u52A0\u8F7D\u63D2\u4EF6\u6570\u636E...");
2500
2777
  spinner.start();
2501
2778
  const repoPath = await repoManager.ensureRepo();
2502
- spinner.succeed(t("install_repo_ready"));
2503
- logger.info(`${t("skill_install_progress")} ${chalk8.bold(names.length)} \u4E2A Skills...`);
2779
+ spinner.succeed("\u63D2\u4EF6\u6570\u636E\u52A0\u8F7D\u5B8C\u6210");
2780
+ logger.info(`${t("skill_install_progress")} ${chalk9.bold(names.length)} \u4E2A Skills...`);
2504
2781
  const level2 = options.level || "project";
2505
2782
  const results = await installSkills(names, tool2, level2, repoPath);
2506
2783
  let successCount = 0;
2507
2784
  let failCount = 0;
2508
- for (const result of results) {
2785
+ const total = results.length;
2786
+ for (let i = 0; i < results.length; i++) {
2787
+ const result = results[i];
2788
+ const progress = `[${i + 1}/${total}]`;
2509
2789
  if (result.success) {
2510
- logger.success(`${result.skillId}`);
2790
+ logger.success(`${progress} ${result.skillId}`);
2511
2791
  successCount++;
2512
2792
  } else {
2513
- logger.error(`${result.skillId}: ${result.error}`);
2793
+ logger.error(`${progress} ${result.skillId}: ${result.error}`);
2514
2794
  failCount++;
2515
2795
  }
2516
2796
  }
2517
2797
  const configRoot = getConfigRoot(tool2, level2);
2518
2798
  logger.blank();
2519
- logger.success(`${t("skill_install_done")}: ${chalk8.green(successCount + " \u6210\u529F")}, ${failCount > 0 ? chalk8.red(failCount + " \u5931\u8D25") : chalk8.dim(failCount + " \u5931\u8D25")}`);
2799
+ logger.success(`${t("skill_install_done")}: ${chalk9.green(successCount + " \u6210\u529F")}, ${failCount > 0 ? chalk9.red(failCount + " \u5931\u8D25") : chalk9.dim(failCount + " \u5931\u8D25")}`);
2520
2800
  logger.blank();
2521
- logger.info(`\u5B89\u88C5\u5230: ${chalk8.cyan(configRoot + "/skills/")}`);
2522
- logger.info(`\u542F\u52A8 ${chalk8.green(tool2)} \u5373\u53EF\u4F7F\u7528`);
2801
+ logger.info(`\u5B89\u88C5\u5230: ${chalk9.cyan(configRoot + "/skills/")}`);
2802
+ logger.info(`\u542F\u52A8 ${chalk9.green(tool2)} \u5373\u53EF\u4F7F\u7528`);
2523
2803
  logger.blank();
2524
2804
  return;
2525
2805
  }
@@ -2554,7 +2834,7 @@ async function installCommand(names, options) {
2554
2834
  for (const p of allPlugins) {
2555
2835
  logger.step(` ${p.id} (${p.aliases.join(", ")})`);
2556
2836
  }
2557
- logger.info(`\u53EF\u7528 Skills: ${chalk8.cyan("install-helper install --list")}`);
2837
+ logger.info(`\u53EF\u7528 Skills: ${chalk9.cyan("install-helper install --list")}`);
2558
2838
  return;
2559
2839
  }
2560
2840
  let tool;
@@ -2593,16 +2873,18 @@ async function installCommand(names, options) {
2593
2873
  }
2594
2874
  if (pluginsToInstall.length > 0) {
2595
2875
  const repoManager = createRepositoryManager();
2596
- const spinner = createSpinner(t("install_cloning"));
2876
+ const spinner = createSpinner("\u6B63\u5728\u52A0\u8F7D\u63D2\u4EF6\u6570\u636E...");
2597
2877
  spinner.start();
2598
2878
  const repoPath = await repoManager.ensureRepo();
2599
- spinner.succeed(t("install_repo_ready"));
2879
+ spinner.succeed("\u63D2\u4EF6\u6570\u636E\u52A0\u8F7D\u5B8C\u6210");
2600
2880
  const allPlugins = getAllPlugins();
2601
2881
  const results = await installPlugins(
2602
2882
  pluginsToInstall,
2603
2883
  tool,
2604
2884
  level,
2605
- repoPath
2885
+ repoPath,
2886
+ void 0,
2887
+ options.yes
2606
2888
  );
2607
2889
  const summary = results.map((result) => {
2608
2890
  const plugin = allPlugins.find((p) => p.id === result.pluginId);
@@ -2620,28 +2902,31 @@ async function installCommand(names, options) {
2620
2902
  }
2621
2903
  if (skills.length > 0) {
2622
2904
  const repoManager = createRepositoryManager();
2623
- const spinner = createSpinner(t("install_cloning"));
2905
+ const spinner = createSpinner("\u6B63\u5728\u52A0\u8F7D\u63D2\u4EF6\u6570\u636E...");
2624
2906
  spinner.start();
2625
2907
  const repoPath = await repoManager.ensureRepo();
2626
- spinner.succeed(t("install_repo_ready"));
2627
- logger.info(`${t("skill_install_progress")} ${chalk8.bold(skills.length)} \u4E2A Skills...`);
2908
+ spinner.succeed("\u63D2\u4EF6\u6570\u636E\u52A0\u8F7D\u5B8C\u6210");
2909
+ logger.info(`${t("skill_install_progress")} ${chalk9.bold(skills.length)} \u4E2A Skills...`);
2628
2910
  const results = await installSkills(skills, tool, level, repoPath);
2629
2911
  let successCount = 0;
2630
2912
  let failCount = 0;
2631
- for (const result of results) {
2913
+ const total = results.length;
2914
+ for (let i = 0; i < results.length; i++) {
2915
+ const result = results[i];
2916
+ const progress = `[${i + 1}/${total}]`;
2632
2917
  if (result.success) {
2633
- logger.success(`${result.skillId}`);
2918
+ logger.success(`${progress} ${result.skillId}`);
2634
2919
  successCount++;
2635
2920
  } else {
2636
- logger.error(`${result.skillId}: ${result.error}`);
2921
+ logger.error(`${progress} ${result.skillId}: ${result.error}`);
2637
2922
  failCount++;
2638
2923
  }
2639
2924
  }
2640
2925
  logger.blank();
2641
- logger.success(`${t("skill_install_done")}: ${chalk8.green(successCount + " \u6210\u529F")}, ${failCount > 0 ? chalk8.red(failCount + " \u5931\u8D25") : chalk8.dim(failCount + " \u5931\u8D25")}`);
2926
+ logger.success(`${t("skill_install_done")}: ${chalk9.green(successCount + " \u6210\u529F")}, ${failCount > 0 ? chalk9.red(failCount + " \u5931\u8D25") : chalk9.dim(failCount + " \u5931\u8D25")}`);
2642
2927
  logger.blank();
2643
- logger.info(`\u5B89\u88C5\u5230: ${chalk8.cyan(getConfigRoot(tool, level) + "/skills/")}`);
2644
- logger.info(`\u542F\u52A8 ${chalk8.green(tool)} \u5373\u53EF\u4F7F\u7528`);
2928
+ logger.info(`\u5B89\u88C5\u5230: ${chalk9.cyan(getConfigRoot(tool, level) + "/skills/")}`);
2929
+ logger.info(`\u542F\u52A8 ${chalk9.green(tool)} \u5373\u53EF\u4F7F\u7528`);
2645
2930
  logger.blank();
2646
2931
  }
2647
2932
  }
@@ -2673,8 +2958,8 @@ async function installPlugins(pluginIds, tool, level, repoPath) {
2673
2958
  }
2674
2959
 
2675
2960
  // src/commands/uninstall.ts
2676
- import { existsSync as existsSync12, unlinkSync as unlinkSync4, rmdirSync as rmdirSync2, readdirSync as readdirSync5, lstatSync as lstatSync4 } from "fs";
2677
- import chalk9 from "chalk";
2961
+ import { existsSync as existsSync13, unlinkSync as unlinkSync5, rmdirSync as rmdirSync2, readdirSync as readdirSync6, lstatSync as lstatSync4 } from "fs";
2962
+ import chalk10 from "chalk";
2678
2963
  async function uninstallCommand(names, options) {
2679
2964
  const tool = options.tool || "opencode";
2680
2965
  const level = options.level || "project";
@@ -2691,24 +2976,24 @@ async function uninstallCommand(names, options) {
2691
2976
  skills.push(skill.id);
2692
2977
  continue;
2693
2978
  }
2694
- logger.error(`\u672A\u627E\u5230: ${name}`);
2979
+ logger.error(`${t("uninstall_not_found")}: ${name}`);
2695
2980
  }
2696
2981
  for (const pluginId of plugins) {
2697
2982
  const plugin = findPlugin(pluginId);
2698
2983
  if (!plugin) continue;
2699
2984
  const record = readRecord(plugin.id);
2700
2985
  if (!record) {
2701
- logger.warn(`${plugin.displayName} \u672A\u627E\u5230\u5B89\u88C5\u8BB0\u5F55\uFF0C\u53EF\u80FD\u672A\u5B89\u88C5\u6216\u5B89\u88C5\u8BB0\u5F55\u5DF2\u635F\u574F`);
2702
- logger.info(`\u5982\u9700\u5F3A\u5236\u6E05\u7406\uFF0C\u8BF7\u624B\u52A8\u5220\u9664 .opencode/ \u6216 .claude/ \u76EE\u5F55\u4E2D\u7684\u76F8\u5173\u6587\u4EF6`);
2986
+ logger.warn(`${plugin.displayName} ${t("uninstall_no_record")}`);
2987
+ logger.info(`${t("uninstall_no_record_hint")}`);
2703
2988
  continue;
2704
2989
  }
2705
- logger.info(`\u6B63\u5728\u5378\u8F7D ${plugin.displayName}...`);
2990
+ logger.info(`${t("uninstall_in_progress")} ${plugin.displayName}...`);
2706
2991
  let removedFiles = 0;
2707
2992
  let removedDirs = 0;
2708
2993
  for (const filePath of record.files) {
2709
2994
  try {
2710
- if (existsSync12(filePath) || isSymlink3(filePath)) {
2711
- unlinkSync4(filePath);
2995
+ if (existsSync13(filePath) || isSymlink3(filePath)) {
2996
+ unlinkSync5(filePath);
2712
2997
  const name = filePath.split("/").pop() || filePath;
2713
2998
  logger.step(` \u79FB\u9664: ${name}`);
2714
2999
  removedFiles++;
@@ -2719,8 +3004,8 @@ async function uninstallCommand(names, options) {
2719
3004
  const sortedDirs = [...record.directories].sort((a, b) => b.length - a.length);
2720
3005
  for (const dirPath of sortedDirs) {
2721
3006
  try {
2722
- if (existsSync12(dirPath)) {
2723
- const entries = readdirSync5(dirPath);
3007
+ if (existsSync13(dirPath)) {
3008
+ const entries = readdirSync6(dirPath);
2724
3009
  if (entries.length === 0) {
2725
3010
  rmdirSync2(dirPath);
2726
3011
  const name = dirPath.split("/").pop() || dirPath;
@@ -2733,15 +3018,33 @@ async function uninstallCommand(names, options) {
2733
3018
  }
2734
3019
  deleteRecord(plugin.id);
2735
3020
  removeInstalledPlugin(plugin.id);
3021
+ const configRoot = getConfigRoot(record.tool, record.level);
3022
+ const backups = findBackups(configRoot);
3023
+ const otherBackups = backups.filter((b) => b.pluginId !== pluginId);
3024
+ if (otherBackups.length > 0) {
3025
+ const choice = await showRestorePrompt(otherBackups);
3026
+ if (choice !== "none") {
3027
+ const restored = restoreBackup(choice, configRoot, record.tool);
3028
+ if (restored) {
3029
+ const backupInfo = otherBackups.find((b) => b.filePath === choice);
3030
+ logger.success(`${t("backup_restore_success")}: ${backupInfo?.pluginName || ""}`);
3031
+ deleteBackup(choice);
3032
+ }
3033
+ }
3034
+ }
3035
+ const currentBackups = backups.filter((b) => b.pluginId === pluginId);
3036
+ for (const backup of currentBackups) {
3037
+ deleteBackup(backup.filePath);
3038
+ }
2736
3039
  const totalRemoved = removedFiles + removedDirs;
2737
3040
  if (totalRemoved > 0) {
2738
- logger.success(`\u5DF2\u5378\u8F7D ${plugin.displayName}\uFF08\u79FB\u9664 ${removedFiles} \u4E2A\u6587\u4EF6\uFF0C${removedDirs} \u4E2A\u76EE\u5F55\uFF09`);
3041
+ logger.success(`${t("uninstall_removed")} ${plugin.displayName}\uFF08\u79FB\u9664 ${removedFiles} \u4E2A\u6587\u4EF6\uFF0C${removedDirs} \u4E2A\u76EE\u5F55\uFF09`);
2739
3042
  } else {
2740
- logger.warn(`${plugin.displayName} \u7684\u6587\u4EF6\u5DF2\u4E0D\u5B58\u5728\uFF0C\u5DF2\u6E05\u7406\u5B89\u88C5\u8BB0\u5F55`);
3043
+ logger.warn(`${plugin.displayName}${t("uninstall_files_gone")}`);
2741
3044
  }
2742
3045
  }
2743
3046
  if (skills.length > 0) {
2744
- logger.info(`\u6B63\u5728\u5378\u8F7D ${skills.length} \u4E2A Skills...`);
3047
+ logger.info(`${t("uninstall_skills_in_progress")} ${skills.length} \u4E2A Skills...`);
2745
3048
  const results = await uninstallSkills(skills, tool, level);
2746
3049
  let successCount = 0;
2747
3050
  let failCount = 0;
@@ -2753,7 +3056,7 @@ async function uninstallCommand(names, options) {
2753
3056
  }
2754
3057
  }
2755
3058
  logger.blank();
2756
- logger.success(`${t("skill_uninstall_done")}: ${chalk9.green(successCount + " \u6210\u529F")}, ${failCount > 0 ? chalk9.red(failCount + " \u5931\u8D25") : chalk9.dim(failCount + " \u5931\u8D25")}`);
3059
+ logger.success(`${t("skill_uninstall_done")}: ${chalk10.green(successCount + " \u6210\u529F")}, ${failCount > 0 ? chalk10.red(failCount + " \u5931\u8D25") : chalk10.dim(failCount + " \u5931\u8D25")}`);
2757
3060
  logger.blank();
2758
3061
  }
2759
3062
  }
@@ -2766,7 +3069,7 @@ function isSymlink3(path) {
2766
3069
  }
2767
3070
 
2768
3071
  // src/commands/update.ts
2769
- import chalk10 from "chalk";
3072
+ import chalk11 from "chalk";
2770
3073
  async function updateCommand(pluginNames, options) {
2771
3074
  let tool;
2772
3075
  if (options.tool) {
@@ -2784,7 +3087,7 @@ async function updateCommand(pluginNames, options) {
2784
3087
  pluginsToUpdate = manifests.map((m) => m.team);
2785
3088
  if (pluginsToUpdate.length === 0) {
2786
3089
  logger.info(t("update_no_plugins"));
2787
- logger.info(`\u4F7F\u7528 ${chalk10.cyan("install-helper install <plugin>")} \u5B89\u88C5\u63D2\u4EF6`);
3090
+ logger.info(`\u4F7F\u7528 ${chalk11.cyan("install-helper install <plugin>")} \u5B89\u88C5\u63D2\u4EF6`);
2788
3091
  return;
2789
3092
  }
2790
3093
  } else {
@@ -2846,42 +3149,42 @@ async function updateCommand(pluginNames, options) {
2846
3149
  }
2847
3150
 
2848
3151
  // src/commands/info.ts
2849
- import chalk11 from "chalk";
2850
- import { existsSync as existsSync13, readdirSync as readdirSync6 } from "fs";
2851
- import { join as join12 } from "path";
3152
+ import chalk12 from "chalk";
3153
+ import { existsSync as existsSync14, readdirSync as readdirSync7 } from "fs";
3154
+ import { join as join13 } from "path";
2852
3155
  async function infoCommand(pluginName) {
2853
3156
  const plugin = findPlugin(pluginName);
2854
3157
  if (!plugin) {
2855
- console.log(chalk11.red(` ${t("info_not_found")}: ${pluginName}`));
3158
+ console.log(chalk12.red(` ${t("info_not_found")}: ${pluginName}`));
2856
3159
  return;
2857
3160
  }
2858
3161
  const installed = scanInstalled();
2859
3162
  const isInstalled = installed.some((p) => p.id === plugin.id);
2860
- const statusText = isInstalled ? chalk11.green(`\u2713 ${t("status_installed")}`) : chalk11.dim(`\u2014 ${t("status_not_installed")}`);
3163
+ const statusText = isInstalled ? chalk12.green(`\u2713 ${t("status_installed")}`) : chalk12.dim(`\u2014 ${t("status_not_installed")}`);
2861
3164
  console.log();
2862
- console.log(chalk11.bold(` ${plugin.displayName}`));
2863
- console.log(chalk11.dim(" " + "\u2500".repeat(40)));
3165
+ console.log(chalk12.bold(` ${plugin.displayName}`));
3166
+ console.log(chalk12.dim(" " + "\u2500".repeat(40)));
2864
3167
  console.log();
2865
- console.log(` ${chalk11.dim(t("info_description") + ":")} ${plugin.description}`);
2866
- console.log(` ${chalk11.dim("ID:")} ${plugin.id}`);
2867
- console.log(` ${chalk11.dim(t("info_status") + ":")} ${statusText}`);
2868
- console.log(` ${chalk11.dim(t("info_skills") + ":")} ${plugin.skills}`);
2869
- console.log(` ${chalk11.dim(t("info_agents") + ":")} ${plugin.agents}`);
2870
- console.log(` ${chalk11.dim("\u522B\u540D:")} ${plugin.aliases.join(", ")}`);
3168
+ console.log(` ${chalk12.dim(t("info_description") + ":")} ${plugin.description}`);
3169
+ console.log(` ${chalk12.dim("ID:")} ${plugin.id}`);
3170
+ console.log(` ${chalk12.dim(t("info_status") + ":")} ${statusText}`);
3171
+ console.log(` ${chalk12.dim(t("info_skills") + ":")} ${plugin.skills}`);
3172
+ console.log(` ${chalk12.dim(t("info_agents") + ":")} ${plugin.agents}`);
3173
+ console.log(` ${chalk12.dim(t("info_aliases") + ":")} ${plugin.aliases.join(", ")}`);
2871
3174
  console.log();
2872
3175
  try {
2873
3176
  const repoManager = createRepositoryManager();
2874
3177
  const repoPath = await repoManager.ensureRepo();
2875
- const quickstartPath = join12(repoPath, plugin.dir, "quickstart.md");
2876
- if (existsSync13(quickstartPath)) {
2877
- console.log(` ${chalk11.dim(t("info_quickstart") + ":")} ${quickstartPath}`);
3178
+ const quickstartPath = join13(repoPath, plugin.dir, "quickstart.md");
3179
+ if (existsSync14(quickstartPath)) {
3180
+ console.log(` ${chalk12.dim(t("info_quickstart") + ":")} ${quickstartPath}`);
2878
3181
  }
2879
- const agentsDir = join12(repoPath, plugin.dir, "agents");
2880
- if (existsSync13(agentsDir)) {
2881
- const agentFiles = readdirSync6(agentsDir).filter((f) => f.endsWith(".md"));
3182
+ const agentsDir = join13(repoPath, plugin.dir, "agents");
3183
+ if (existsSync14(agentsDir)) {
3184
+ const agentFiles = readdirSync7(agentsDir).filter((f) => f.endsWith(".md"));
2882
3185
  if (agentFiles.length > 0) {
2883
3186
  console.log();
2884
- console.log(` ${chalk11.bold("Agents:")}`);
3187
+ console.log(` ${chalk12.bold("Agents:")}`);
2885
3188
  for (const agent of agentFiles) {
2886
3189
  console.log(` \u2022 ${agent.replace(".md", "")}`);
2887
3190
  }
@@ -2893,39 +3196,39 @@ async function infoCommand(pluginName) {
2893
3196
  }
2894
3197
 
2895
3198
  // src/commands/lang.ts
2896
- import chalk12 from "chalk";
3199
+ import chalk13 from "chalk";
2897
3200
  async function langCommand(action, value) {
2898
3201
  const config = readConfig();
2899
3202
  if (!action || action === "show") {
2900
3203
  console.log();
2901
- console.log(chalk12.bold(` ${t("lang_title")}`));
2902
- console.log(chalk12.dim(" " + "\u2500".repeat(40)));
3204
+ console.log(chalk13.bold(` ${t("lang_title")}`));
3205
+ console.log(chalk13.dim(" " + "\u2500".repeat(40)));
2903
3206
  console.log();
2904
- console.log(` ${chalk12.dim(t("lang_current") + ":")} ${config.language}`);
3207
+ console.log(` ${chalk13.dim(t("lang_current") + ":")} ${config.language}`);
2905
3208
  console.log();
2906
- console.log(chalk12.dim(" \u652F\u6301\u7684\u8BED\u8A00: zh_CN, en_US"));
2907
- console.log(chalk12.dim(" \u7528\u6CD5: install-helper lang set <language>"));
3209
+ console.log(chalk13.dim(` ${t("lang_supported")}`));
3210
+ console.log(chalk13.dim(` ${t("lang_usage")}`));
2908
3211
  console.log();
2909
3212
  return;
2910
3213
  }
2911
3214
  if (action === "set") {
2912
3215
  if (!value) {
2913
- console.log(chalk12.red(" \u8BF7\u6307\u5B9A\u8BED\u8A00: install-helper lang set zh_CN"));
3216
+ console.log(chalk13.red(` ${t("lang_specify")}`));
2914
3217
  return;
2915
3218
  }
2916
3219
  if (value !== "zh_CN" && value !== "en_US") {
2917
- console.log(chalk12.red(` ${t("lang_invalid")}`));
3220
+ console.log(chalk13.red(` ${t("lang_invalid")}`));
2918
3221
  return;
2919
3222
  }
2920
3223
  updateConfig({ language: value });
2921
3224
  setLanguage(value);
2922
3225
  console.log();
2923
- console.log(chalk12.green(` \u2713 ${t("lang_set")} ${value}`));
3226
+ console.log(chalk13.green(` \u2713 ${t("lang_set")} ${value}`));
2924
3227
  console.log();
2925
3228
  return;
2926
3229
  }
2927
- console.log(chalk12.red(` \u672A\u77E5\u64CD\u4F5C: ${action}`));
2928
- console.log(chalk12.dim(" \u652F\u6301\u7684\u64CD\u4F5C: show, set"));
3230
+ console.log(chalk13.red(` ${t("lang_unknown_action")}: ${action}`));
3231
+ console.log(chalk13.dim(` ${t("lang_supported_actions")}`));
2929
3232
  }
2930
3233
 
2931
3234
  // src/cli.ts
@@ -2935,7 +3238,7 @@ function createCLI() {
2935
3238
  setLanguage(config.language);
2936
3239
  }
2937
3240
  const program2 = new Command();
2938
- program2.name("install-helper").description("Install Helper - Interactive installer for CANN operator development skills").version("0.0.2-beta.6");
3241
+ program2.name("install-helper").description("CANNBot Install Helper - Interactive installer for CANN operator development skills").version("0.0.2-beta.8");
2939
3242
  program2.command("init", { isDefault: false }).description("Run interactive installation wizard").action(async () => {
2940
3243
  await initCommand();
2941
3244
  });