@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # install-helper
2
2
 
3
- > CANNBot Helper — CANNBot 交互式安装助手
3
+ > Install Helper — CANNBot 交互式安装助手
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@cannbot-ai/install-helper.svg)](https://www.npmjs.com/package/@cannbot-ai/install-helper)
6
6
  [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg)](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("which", [cmd], { timeout: 5e3 });
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
- logger.info(`\u5373\u5C06\u5B89\u88C5 ${chalk2.bold(plugins.length)} \u4E2A\u573A\u666F\u5230 ${chalk2.cyan("." + tool + "/")}\uFF1A`);
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).join("\n").replace(/\r$/, "");
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 installedSkills = getInstalledSkills(
1820
- "opencode",
1821
- "project",
1822
- process.cwd()
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")) && cwd.includes("install-helper")) {
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 results = await installSkills(names, tool2, "project", repoPath);
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, "project");
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") + " cannbot-skills...");
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("CANNBot Helper - Interactive installer for CANN operator development skills").version("0.0.1-beta.0");
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
  });