@cannbot-ai/install-helper 0.0.1-beta.0 → 0.0.1-beta.2
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 +1 -1
- package/dist/index.js +73 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# install-helper
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Install Helper — CANNBot 交互式安装助手
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@cannbot-ai/install-helper)
|
|
6
6
|
[](https://nodejs.org)
|
package/dist/index.js
CHANGED
|
@@ -232,7 +232,7 @@ async function getCommandVersion(cmd, args = ["--version"]) {
|
|
|
232
232
|
}
|
|
233
233
|
async function getCommandPath(cmd) {
|
|
234
234
|
try {
|
|
235
|
-
const result = await execa("
|
|
235
|
+
const result = await execa("sh", ["-c", `command -v ${cmd}`], { timeout: 5e3 });
|
|
236
236
|
return result.stdout.trim();
|
|
237
237
|
} catch {
|
|
238
238
|
return void 0;
|
|
@@ -929,7 +929,8 @@ async function stepConfirm(tool, level, plugins) {
|
|
|
929
929
|
printBoxTitle("\u786E\u8BA4\u5B89\u88C5");
|
|
930
930
|
const allPlugins = getAllPlugins();
|
|
931
931
|
const selectedPlugins = plugins.map((id) => allPlugins.find((p) => p.id === id));
|
|
932
|
-
|
|
932
|
+
const displayPath = getConfigRoot(tool, level);
|
|
933
|
+
logger.info(`\u5373\u5C06\u5B89\u88C5 ${chalk2.bold(plugins.length)} \u4E2A\u573A\u666F\u5230 ${chalk2.cyan(displayPath)}\uFF1A`);
|
|
933
934
|
for (const plugin of selectedPlugins) {
|
|
934
935
|
if (plugin) {
|
|
935
936
|
logger.step(` \u2022 ${chalk2.bold(plugin.displayName)} ${chalk2.dim(`(${plugin.skills} skills, ${plugin.agents} agents)`)}`);
|
|
@@ -967,8 +968,16 @@ var EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
|
967
968
|
".agents",
|
|
968
969
|
".opencode",
|
|
969
970
|
".claude",
|
|
971
|
+
".claude-plugin",
|
|
970
972
|
"dist",
|
|
971
|
-
"build"
|
|
973
|
+
"build",
|
|
974
|
+
"references",
|
|
975
|
+
"hooks",
|
|
976
|
+
"operators",
|
|
977
|
+
"workflows",
|
|
978
|
+
"tests",
|
|
979
|
+
"docs",
|
|
980
|
+
"scripts"
|
|
972
981
|
]);
|
|
973
982
|
var SKILL_SCAN_DIRS = [
|
|
974
983
|
"ops",
|
|
@@ -1021,7 +1030,7 @@ function parseFrontmatter(filePath) {
|
|
|
1021
1030
|
}
|
|
1022
1031
|
}
|
|
1023
1032
|
if (endIndex === -1) return null;
|
|
1024
|
-
const yamlBlock = lines.slice(1, endIndex).
|
|
1033
|
+
const yamlBlock = lines.slice(1, endIndex).map((l) => l.replace(/\r$/, "")).join("\n");
|
|
1025
1034
|
const parsed = parseYaml(yamlBlock);
|
|
1026
1035
|
if (!parsed || typeof parsed !== "object") return null;
|
|
1027
1036
|
if (!parsed.name || typeof parsed.name !== "string") return null;
|
|
@@ -1043,6 +1052,17 @@ function getCurrentCommit(repoPath) {
|
|
|
1043
1052
|
if (existsSync5(refPath)) {
|
|
1044
1053
|
return readFileSync3(refPath, "utf-8").trim();
|
|
1045
1054
|
}
|
|
1055
|
+
const packedRefsPath = join5(repoPath, ".git", "packed-refs");
|
|
1056
|
+
if (existsSync5(packedRefsPath)) {
|
|
1057
|
+
const packedRefs = readFileSync3(packedRefsPath, "utf-8");
|
|
1058
|
+
const refName = headContent.slice(5);
|
|
1059
|
+
const lines = packedRefs.split("\n");
|
|
1060
|
+
for (const line of lines) {
|
|
1061
|
+
if (line.endsWith(refName)) {
|
|
1062
|
+
return line.split(" ")[0];
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1046
1066
|
}
|
|
1047
1067
|
return headContent;
|
|
1048
1068
|
} catch {
|
|
@@ -1079,6 +1099,20 @@ function getCachePath() {
|
|
|
1079
1099
|
return join5(homeDir, ".cannbot", "scan-cache.json");
|
|
1080
1100
|
}
|
|
1081
1101
|
function scanDirectory(dirPath, repoPath, sourcePrefix, skills, seen) {
|
|
1102
|
+
const selfSkillMd = join5(dirPath, "SKILL.md");
|
|
1103
|
+
if (existsSync5(selfSkillMd)) {
|
|
1104
|
+
const frontmatter = parseFrontmatter(selfSkillMd);
|
|
1105
|
+
if (frontmatter && !seen.has(frontmatter.name)) {
|
|
1106
|
+
seen.add(frontmatter.name);
|
|
1107
|
+
skills.push({
|
|
1108
|
+
id: frontmatter.name,
|
|
1109
|
+
description: frontmatter.description,
|
|
1110
|
+
source: sourcePrefix,
|
|
1111
|
+
filePath: selfSkillMd
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1082
1116
|
for (const entry of safeReaddir(dirPath)) {
|
|
1083
1117
|
const fullPath = join5(dirPath, entry);
|
|
1084
1118
|
if (EXCLUDE_DIRS.has(entry)) continue;
|
|
@@ -1095,6 +1129,7 @@ function scanDirectory(dirPath, repoPath, sourcePrefix, skills, seen) {
|
|
|
1095
1129
|
filePath: skillMd
|
|
1096
1130
|
});
|
|
1097
1131
|
}
|
|
1132
|
+
continue;
|
|
1098
1133
|
}
|
|
1099
1134
|
scanDirectory(fullPath, repoPath, sourcePrefix, skills, seen);
|
|
1100
1135
|
}
|
|
@@ -1192,8 +1227,7 @@ var STATIC_SKILL_CATEGORIES = [
|
|
|
1192
1227
|
{ id: "ascendc-task-focus", description: "\u957F\u4EFB\u52A1\u805A\u7126\u9632\u8FF7\u5931", source: "ops" },
|
|
1193
1228
|
{ id: "tilelang-op-test-design", description: "TileLang \u6D4B\u8BD5\u8BBE\u8BA1", source: "ops" },
|
|
1194
1229
|
{ id: "tilelang-review", description: "TileLang \u4EE3\u7801\u683C\u5F0F\u68C0\u67E5", source: "ops" },
|
|
1195
|
-
{ id: "triton-op-verifier", description: "Triton \u7B97\u5B50\u9A8C\u8BC1", source: "ops" }
|
|
1196
|
-
{ id: "cannbot-skill-reviewer", description: "Skill \u5165\u5E93\u8D28\u91CF\u5BA1\u67E5", source: "infra" }
|
|
1230
|
+
{ id: "triton-op-verifier", description: "Triton \u7B97\u5B50\u9A8C\u8BC1", source: "ops" }
|
|
1197
1231
|
]
|
|
1198
1232
|
},
|
|
1199
1233
|
{
|
|
@@ -1214,7 +1248,7 @@ var STATIC_SKILL_CATEGORIES = [
|
|
|
1214
1248
|
{ id: "cuda2ascend-simt", description: "CUDA \u8FC1\u79FB\u5230 Ascend C SIMT", source: "ops-lab" },
|
|
1215
1249
|
{ id: "ops-direct-invoke-flash", description: "\u4ECE\u96F6\u6784\u5EFA Ascend C \u6838\u51FD\u6570", source: "plugins-official/ops-direct-invoke-flash/skills" },
|
|
1216
1250
|
{ id: "ops-registry-invoke-workflow", description: "\u6CE8\u518C\u8C03\u7528\u5DE5\u4F5C\u6D41", source: "plugins-official/ops-registry-invoke" },
|
|
1217
|
-
{ id: "ops-easyasc-dsl", description: "EasyASC DSL \u7B97\u5B50\u5F00\u53D1", source: "plugins-community/ops-easyasc-dsl" }
|
|
1251
|
+
{ id: "ops-easyasc-dsl", description: "EasyASC DSL \u7B97\u5B50\u5F00\u53D1", source: "plugins-community/ops-easyasc-dsl/skill" }
|
|
1218
1252
|
]
|
|
1219
1253
|
},
|
|
1220
1254
|
{
|
|
@@ -1816,11 +1850,15 @@ async function interactiveSkillSelect() {
|
|
|
1816
1850
|
const category = categories.find((c) => c.id === selectedCategoryId);
|
|
1817
1851
|
if (!category) return [];
|
|
1818
1852
|
printBoxTitle(`\u9009\u62E9\u8981\u5B89\u88C5\u7684 Skills \u2014 ${category.name}`);
|
|
1819
|
-
const
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1853
|
+
const tools = ["opencode", "claude", "trae", "cursor", "copilot"];
|
|
1854
|
+
const levels = ["project", "global"];
|
|
1855
|
+
const installedSkills = [];
|
|
1856
|
+
for (const tk of tools) {
|
|
1857
|
+
for (const l of levels) {
|
|
1858
|
+
const path = l === "project" ? process.cwd() : getConfigRoot(tk, l);
|
|
1859
|
+
installedSkills.push(...getInstalledSkills(tk, l, path));
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1824
1862
|
const installedSet = new Set(installedSkills);
|
|
1825
1863
|
const skillChoices = category.skills.map((skill) => {
|
|
1826
1864
|
const isInstalled = installedSet.has(skill.id);
|
|
@@ -1988,11 +2026,18 @@ function printEnhancedSummary(results, tool, configRoot) {
|
|
|
1988
2026
|
}
|
|
1989
2027
|
|
|
1990
2028
|
// src/commands/init.ts
|
|
1991
|
-
import { existsSync as existsSync10 } from "fs";
|
|
2029
|
+
import { existsSync as existsSync10, readFileSync as readFileSync5 } from "fs";
|
|
1992
2030
|
import { join as join10 } from "path";
|
|
1993
2031
|
async function initCommand() {
|
|
1994
2032
|
const cwd = process.cwd();
|
|
1995
|
-
if (existsSync10(join10(cwd, "package.json")) &&
|
|
2033
|
+
if (existsSync10(join10(cwd, "package.json")) && (() => {
|
|
2034
|
+
try {
|
|
2035
|
+
const pkg = JSON.parse(readFileSync5(join10(cwd, "package.json"), "utf-8"));
|
|
2036
|
+
return pkg.name === "@cannbot-ai/install-helper";
|
|
2037
|
+
} catch {
|
|
2038
|
+
return false;
|
|
2039
|
+
}
|
|
2040
|
+
})()) {
|
|
1996
2041
|
logger.warn("\u5F53\u524D\u76EE\u5F55\u770B\u8D77\u6765\u662F install-helper \u5305\u76EE\u5F55");
|
|
1997
2042
|
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");
|
|
1998
2043
|
logger.info("\u793A\u4F8B\uFF1Acd ~/my-project && install-helper");
|
|
@@ -2390,6 +2435,15 @@ async function installCommand(names, options) {
|
|
|
2390
2435
|
return;
|
|
2391
2436
|
}
|
|
2392
2437
|
if (names.length === 0) {
|
|
2438
|
+
const scanSpinner2 = createSpinner("\u6B63\u5728\u52A0\u8F7D Skills \u5217\u8868...");
|
|
2439
|
+
scanSpinner2.start();
|
|
2440
|
+
try {
|
|
2441
|
+
const scanRepoManager = createRepositoryManager();
|
|
2442
|
+
await scanRepoManager.ensureRepoAndScan();
|
|
2443
|
+
scanSpinner2.succeed("Skills \u5217\u8868\u52A0\u8F7D\u5B8C\u6210");
|
|
2444
|
+
} catch {
|
|
2445
|
+
scanSpinner2.warn("Skills \u5217\u8868\u52A0\u8F7D\u5931\u8D25\uFF0C\u5C06\u4F7F\u7528\u5185\u7F6E\u6570\u636E");
|
|
2446
|
+
}
|
|
2393
2447
|
let tool2;
|
|
2394
2448
|
if (options.tool) {
|
|
2395
2449
|
tool2 = options.tool;
|
|
@@ -2420,7 +2474,8 @@ async function installCommand(names, options) {
|
|
|
2420
2474
|
const repoPath = await repoManager.ensureRepo();
|
|
2421
2475
|
spinner.succeed(t("install_repo_ready"));
|
|
2422
2476
|
logger.info(`${t("skill_install_progress")} ${chalk8.bold(names.length)} \u4E2A Skills...`);
|
|
2423
|
-
const
|
|
2477
|
+
const level2 = options.level || "project";
|
|
2478
|
+
const results = await installSkills(names, tool2, level2, repoPath);
|
|
2424
2479
|
let successCount = 0;
|
|
2425
2480
|
let failCount = 0;
|
|
2426
2481
|
for (const result of results) {
|
|
@@ -2432,7 +2487,7 @@ async function installCommand(names, options) {
|
|
|
2432
2487
|
failCount++;
|
|
2433
2488
|
}
|
|
2434
2489
|
}
|
|
2435
|
-
const configRoot = getConfigRoot(tool2,
|
|
2490
|
+
const configRoot = getConfigRoot(tool2, level2);
|
|
2436
2491
|
logger.blank();
|
|
2437
2492
|
logger.success(`${t("skill_install_done")}: ${chalk8.green(successCount + " \u6210\u529F")}, ${failCount > 0 ? chalk8.red(failCount + " \u5931\u8D25") : chalk8.dim(failCount + " \u5931\u8D25")}`);
|
|
2438
2493
|
logger.blank();
|
|
@@ -2716,7 +2771,7 @@ async function updateCommand(pluginNames, options) {
|
|
|
2716
2771
|
}
|
|
2717
2772
|
}
|
|
2718
2773
|
const repoManager = createRepositoryManager();
|
|
2719
|
-
const updateSpinner = createSpinner(t("update_updating") + "
|
|
2774
|
+
const updateSpinner = createSpinner(t("update_updating") + "...");
|
|
2720
2775
|
updateSpinner.start();
|
|
2721
2776
|
await repoManager.updateRepo();
|
|
2722
2777
|
const repoPath = repoManager.getRepoPath();
|
|
@@ -2853,7 +2908,7 @@ function createCLI() {
|
|
|
2853
2908
|
setLanguage(config.language);
|
|
2854
2909
|
}
|
|
2855
2910
|
const program2 = new Command();
|
|
2856
|
-
program2.name("install-helper").description("
|
|
2911
|
+
program2.name("install-helper").description("Install Helper - Interactive installer for CANN operator development skills").version("0.0.1-beta.2");
|
|
2857
2912
|
program2.command("init", { isDefault: false }).description("Run interactive installation wizard").action(async () => {
|
|
2858
2913
|
await initCommand();
|
|
2859
2914
|
});
|