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