@cannbot-ai/install-helper 0.0.2-beta.30 → 0.0.2-beta.32
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 +0 -2
- package/dist/config/repository.yaml +1 -0
- package/dist/index.js +183 -99
- package/dist/index.js.map +1 -1
- package/dist/locales/en_US.json +1 -0
- package/dist/locales/zh_CN.json +1 -0
- package/dist/plugins.d/triton-op-generator.yml +0 -1
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { select, checkbox, Separator } from "@inquirer/prompts";
|
|
|
12
12
|
import chalk3 from "chalk";
|
|
13
13
|
|
|
14
14
|
// src/core/registry.ts
|
|
15
|
-
import { readdirSync, readFileSync } from "fs";
|
|
15
|
+
import { readdirSync, readFileSync, existsSync, statSync } from "fs";
|
|
16
16
|
import { join, dirname } from "path";
|
|
17
17
|
import { fileURLToPath } from "url";
|
|
18
18
|
import { parse as parseYaml } from "yaml";
|
|
@@ -54,6 +54,54 @@ function loadPluginsFromYaml() {
|
|
|
54
54
|
return plugins;
|
|
55
55
|
}
|
|
56
56
|
var PLUGIN_REGISTRY = loadPluginsFromYaml();
|
|
57
|
+
var PLUGIN_DIRS = ["plugins-official", "plugins-community"];
|
|
58
|
+
function mergeDynamicPlugins(repoPath) {
|
|
59
|
+
if (!existsSync(repoPath)) return;
|
|
60
|
+
const existingIds = new Set(PLUGIN_REGISTRY.map((p) => p.id));
|
|
61
|
+
const dynamic = [];
|
|
62
|
+
for (const pluginDir of PLUGIN_DIRS) {
|
|
63
|
+
const parent = join(repoPath, pluginDir);
|
|
64
|
+
if (!existsSync(parent)) continue;
|
|
65
|
+
let entries = [];
|
|
66
|
+
try {
|
|
67
|
+
entries = readdirSync(parent);
|
|
68
|
+
} catch {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
const pluginPath = join(parent, entry);
|
|
73
|
+
if (!isDirectory(pluginPath)) continue;
|
|
74
|
+
if (entry === "install-helper") continue;
|
|
75
|
+
const initSh = join(pluginPath, "init.sh");
|
|
76
|
+
if (!existsSync(initSh)) continue;
|
|
77
|
+
const pluginId = entry;
|
|
78
|
+
if (existingIds.has(pluginId)) continue;
|
|
79
|
+
dynamic.push({
|
|
80
|
+
id: pluginId,
|
|
81
|
+
dir: `${pluginDir}/${entry}`,
|
|
82
|
+
displayName: entry,
|
|
83
|
+
script: "init.sh",
|
|
84
|
+
aliases: [],
|
|
85
|
+
skills: 0,
|
|
86
|
+
agents: 0,
|
|
87
|
+
description: ""
|
|
88
|
+
});
|
|
89
|
+
existingIds.add(pluginId);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (dynamic.length > 0) {
|
|
93
|
+
PLUGIN_REGISTRY = [...PLUGIN_REGISTRY, ...dynamic].sort(
|
|
94
|
+
(a, b) => a.displayName < b.displayName ? -1 : a.displayName > b.displayName ? 1 : 0
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function isDirectory(path) {
|
|
99
|
+
try {
|
|
100
|
+
return statSync(path).isDirectory();
|
|
101
|
+
} catch {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
57
105
|
function findPlugin(query) {
|
|
58
106
|
const normalized = query.toLowerCase().trim();
|
|
59
107
|
const exactMatch = PLUGIN_REGISTRY.find(
|
|
@@ -77,14 +125,14 @@ function getPluginById(id) {
|
|
|
77
125
|
|
|
78
126
|
// src/core/detector.ts
|
|
79
127
|
import { execa } from "execa";
|
|
80
|
-
import { existsSync as
|
|
128
|
+
import { existsSync as existsSync3 } from "fs";
|
|
81
129
|
import { homedir as homedir2 } from "os";
|
|
82
130
|
import { join as join4 } from "path";
|
|
83
131
|
|
|
84
132
|
// src/utils/paths.ts
|
|
85
133
|
import { homedir } from "os";
|
|
86
134
|
import { join as join3 } from "path";
|
|
87
|
-
import { existsSync } from "fs";
|
|
135
|
+
import { existsSync as existsSync2 } from "fs";
|
|
88
136
|
|
|
89
137
|
// src/utils/i18n.ts
|
|
90
138
|
import { readFileSync as readFileSync2 } from "fs";
|
|
@@ -138,9 +186,9 @@ function validateLevel(level) {
|
|
|
138
186
|
}
|
|
139
187
|
function detectTraeVariant() {
|
|
140
188
|
const home = homedir();
|
|
141
|
-
if (
|
|
142
|
-
if (
|
|
143
|
-
if (
|
|
189
|
+
if (existsSync2(join3(home, ".trae-cn"))) return "ide";
|
|
190
|
+
if (existsSync2(join3(home, ".marscode"))) return "plugin";
|
|
191
|
+
if (existsSync2(join3(home, ".traecli"))) return "cli";
|
|
144
192
|
return "unknown";
|
|
145
193
|
}
|
|
146
194
|
function getConfigRoot(tool, level, base) {
|
|
@@ -253,11 +301,11 @@ async function detectTrae() {
|
|
|
253
301
|
const home = homedir2();
|
|
254
302
|
const variant = detectTraeVariant();
|
|
255
303
|
let path;
|
|
256
|
-
if (variant === "ide" &&
|
|
304
|
+
if (variant === "ide" && existsSync3(join4(home, ".trae-cn"))) {
|
|
257
305
|
path = join4(home, ".trae-cn");
|
|
258
|
-
} else if (variant === "plugin" &&
|
|
306
|
+
} else if (variant === "plugin" && existsSync3(join4(home, ".marscode"))) {
|
|
259
307
|
path = join4(home, ".marscode");
|
|
260
|
-
} else if (variant === "cli" &&
|
|
308
|
+
} else if (variant === "cli" && existsSync3(join4(home, ".traecli"))) {
|
|
261
309
|
path = join4(home, ".traecli");
|
|
262
310
|
} else if (variant === "unknown") {
|
|
263
311
|
const cmdPath = await getCommandPath("trae");
|
|
@@ -274,7 +322,7 @@ async function detectCursor() {
|
|
|
274
322
|
}
|
|
275
323
|
if (process.platform === "darwin") {
|
|
276
324
|
const appPath = "/Applications/Cursor.app";
|
|
277
|
-
if (
|
|
325
|
+
if (existsSync3(appPath)) {
|
|
278
326
|
return { name: "cursor", path: appPath };
|
|
279
327
|
}
|
|
280
328
|
}
|
|
@@ -322,11 +370,11 @@ function getAllTools() {
|
|
|
322
370
|
}
|
|
323
371
|
|
|
324
372
|
// src/core/manifest.ts
|
|
325
|
-
import { existsSync as
|
|
373
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
|
|
326
374
|
import { join as join5 } from "path";
|
|
327
375
|
function readManifest(configRoot) {
|
|
328
376
|
const manifestPath = getManifestPath(configRoot);
|
|
329
|
-
if (
|
|
377
|
+
if (existsSync4(manifestPath)) {
|
|
330
378
|
try {
|
|
331
379
|
const content = readFileSync3(manifestPath, "utf-8");
|
|
332
380
|
return JSON.parse(content);
|
|
@@ -339,7 +387,7 @@ function readAllManifests(configRoot) {
|
|
|
339
387
|
const manifests = [];
|
|
340
388
|
const plugins = getAllPlugins();
|
|
341
389
|
const standardPath = getManifestPath(configRoot);
|
|
342
|
-
if (
|
|
390
|
+
if (existsSync4(standardPath)) {
|
|
343
391
|
try {
|
|
344
392
|
const content = readFileSync3(standardPath, "utf-8");
|
|
345
393
|
manifests.push(JSON.parse(content));
|
|
@@ -348,7 +396,7 @@ function readAllManifests(configRoot) {
|
|
|
348
396
|
}
|
|
349
397
|
for (const plugin of plugins) {
|
|
350
398
|
const pluginManifestPath = join5(configRoot, `${plugin.id}-manifest.json`);
|
|
351
|
-
if (
|
|
399
|
+
if (existsSync4(pluginManifestPath)) {
|
|
352
400
|
try {
|
|
353
401
|
const content = readFileSync3(pluginManifestPath, "utf-8");
|
|
354
402
|
manifests.push(JSON.parse(content));
|
|
@@ -398,14 +446,14 @@ function verifyPluginFilesExist(configRoot, manifest, tool, level) {
|
|
|
398
446
|
if (manifest.installed_skills && manifest.installed_skills.length > 0) {
|
|
399
447
|
const hasAnySkill = manifest.installed_skills.some((skillId) => {
|
|
400
448
|
const skillPath = join5(skillsDir, skillId);
|
|
401
|
-
return
|
|
449
|
+
return existsSync4(skillPath);
|
|
402
450
|
});
|
|
403
451
|
if (!hasAnySkill) return false;
|
|
404
452
|
}
|
|
405
453
|
if (manifest.installed_agents && manifest.installed_agents.length > 0) {
|
|
406
454
|
const hasAnyAgent = manifest.installed_agents.some((agentId) => {
|
|
407
455
|
const agentPath = join5(agentsDir, agentId);
|
|
408
|
-
return
|
|
456
|
+
return existsSync4(agentPath);
|
|
409
457
|
});
|
|
410
458
|
if (!hasAnyAgent) return false;
|
|
411
459
|
}
|
|
@@ -415,7 +463,7 @@ function verifyPluginFilesExist(configRoot, manifest, tool, level) {
|
|
|
415
463
|
} else {
|
|
416
464
|
agentsMdPath = join5(configRoot, "AGENTS.md");
|
|
417
465
|
}
|
|
418
|
-
if (!
|
|
466
|
+
if (!existsSync4(agentsMdPath)) return false;
|
|
419
467
|
return true;
|
|
420
468
|
}
|
|
421
469
|
|
|
@@ -482,7 +530,7 @@ function showOperationHints(isCheckbox = false) {
|
|
|
482
530
|
}
|
|
483
531
|
|
|
484
532
|
// src/utils/config.ts
|
|
485
|
-
import { existsSync as
|
|
533
|
+
import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync4, writeFileSync } from "fs";
|
|
486
534
|
import { join as join6 } from "path";
|
|
487
535
|
import { homedir as homedir3 } from "os";
|
|
488
536
|
import { parse, stringify } from "yaml";
|
|
@@ -494,7 +542,7 @@ function getConfigPath() {
|
|
|
494
542
|
}
|
|
495
543
|
function readConfig() {
|
|
496
544
|
const configPath = getConfigPath();
|
|
497
|
-
if (!
|
|
545
|
+
if (!existsSync5(configPath)) {
|
|
498
546
|
return {
|
|
499
547
|
language: "zh_CN",
|
|
500
548
|
installedPlugins: []
|
|
@@ -519,7 +567,7 @@ function readConfig() {
|
|
|
519
567
|
}
|
|
520
568
|
function writeConfig(config) {
|
|
521
569
|
const configDir = getConfigDir();
|
|
522
|
-
if (!
|
|
570
|
+
if (!existsSync5(configDir)) {
|
|
523
571
|
mkdirSync(configDir, { recursive: true });
|
|
524
572
|
}
|
|
525
573
|
const configPath = getConfigPath();
|
|
@@ -870,14 +918,14 @@ async function stepConfirm(tool, level, plugins) {
|
|
|
870
918
|
}
|
|
871
919
|
|
|
872
920
|
// src/core/repository.ts
|
|
873
|
-
import { existsSync as
|
|
921
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync6 } from "fs";
|
|
874
922
|
import { join as join8, dirname as dirname4 } from "path";
|
|
875
923
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
876
924
|
import { execa as execa2 } from "execa";
|
|
877
925
|
import { parse as parseYaml3 } from "yaml";
|
|
878
926
|
|
|
879
927
|
// src/core/scanner.ts
|
|
880
|
-
import { existsSync as
|
|
928
|
+
import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync5, statSync as statSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
881
929
|
import { join as join7, dirname as dirname3 } from "path";
|
|
882
930
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
883
931
|
import { parse as parseYaml2 } from "yaml";
|
|
@@ -908,12 +956,12 @@ function loadScanConfig() {
|
|
|
908
956
|
try {
|
|
909
957
|
const config = parseYaml2(readFileSync5(configPath, "utf-8"));
|
|
910
958
|
return {
|
|
911
|
-
skillDirs: config.scanDirs || ["ops", "model", "graph", "infra", "ops-lab"],
|
|
959
|
+
skillDirs: config.scanDirs || ["ops", "model", "graph", "infra", "ops-lab", "runtime"],
|
|
912
960
|
pluginDirs: config.pluginDirs || ["plugins-official", "plugins-community"]
|
|
913
961
|
};
|
|
914
962
|
} catch {
|
|
915
963
|
return {
|
|
916
|
-
skillDirs: ["ops", "model", "graph", "infra", "ops-lab"],
|
|
964
|
+
skillDirs: ["ops", "model", "graph", "infra", "ops-lab", "runtime"],
|
|
917
965
|
pluginDirs: ["plugins-official", "plugins-community"]
|
|
918
966
|
};
|
|
919
967
|
}
|
|
@@ -926,23 +974,37 @@ function scanSkills(repoPath) {
|
|
|
926
974
|
const seen = /* @__PURE__ */ new Set();
|
|
927
975
|
for (const dir of SKILL_SCAN_DIRS) {
|
|
928
976
|
const fullPath = join7(repoPath, dir);
|
|
929
|
-
if (!
|
|
977
|
+
if (!existsSync6(fullPath)) continue;
|
|
930
978
|
scanDirectory(fullPath, repoPath, dir, skills, seen);
|
|
931
979
|
}
|
|
932
980
|
for (const pluginDir of PLUGIN_SCAN_DIRS) {
|
|
933
981
|
const pluginParent = join7(repoPath, pluginDir);
|
|
934
|
-
if (!
|
|
982
|
+
if (!existsSync6(pluginParent)) continue;
|
|
935
983
|
for (const plugin of safeReaddir(pluginParent)) {
|
|
936
984
|
const pluginPath = join7(pluginParent, plugin);
|
|
937
|
-
if (!
|
|
985
|
+
if (!isDirectory2(pluginPath)) continue;
|
|
938
986
|
const skillsDir = join7(pluginPath, "skills");
|
|
939
|
-
if (
|
|
987
|
+
if (existsSync6(skillsDir)) {
|
|
940
988
|
scanDirectory(skillsDir, repoPath, `${pluginDir}/${plugin}/skills`, skills, seen);
|
|
941
989
|
}
|
|
942
990
|
const skillDir = join7(pluginPath, "skill");
|
|
943
|
-
if (
|
|
991
|
+
if (existsSync6(skillDir)) {
|
|
944
992
|
scanDirectory(skillDir, repoPath, `${pluginDir}/${plugin}/skill`, skills, seen);
|
|
945
993
|
}
|
|
994
|
+
const rootSkillMd = join7(pluginPath, "SKILL.md");
|
|
995
|
+
const initSh = join7(pluginPath, "init.sh");
|
|
996
|
+
if (existsSync6(rootSkillMd) && !existsSync6(initSh)) {
|
|
997
|
+
const frontmatter = parseFrontmatter(rootSkillMd);
|
|
998
|
+
if (frontmatter && !seen.has(frontmatter.name)) {
|
|
999
|
+
seen.add(frontmatter.name);
|
|
1000
|
+
skills.push({
|
|
1001
|
+
id: frontmatter.name,
|
|
1002
|
+
description: frontmatter.description,
|
|
1003
|
+
source: `${pluginDir}/${plugin}`,
|
|
1004
|
+
filePath: rootSkillMd
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
946
1008
|
}
|
|
947
1009
|
}
|
|
948
1010
|
return skills;
|
|
@@ -976,15 +1038,15 @@ function parseFrontmatter(filePath) {
|
|
|
976
1038
|
function getCurrentCommit(repoPath) {
|
|
977
1039
|
try {
|
|
978
1040
|
const headFile = join7(repoPath, ".git", "HEAD");
|
|
979
|
-
if (!
|
|
1041
|
+
if (!existsSync6(headFile)) return "unknown";
|
|
980
1042
|
const headContent = readFileSync5(headFile, "utf-8").trim();
|
|
981
1043
|
if (headContent.startsWith("ref: ")) {
|
|
982
1044
|
const refPath = join7(repoPath, ".git", headContent.slice(5));
|
|
983
|
-
if (
|
|
1045
|
+
if (existsSync6(refPath)) {
|
|
984
1046
|
return readFileSync5(refPath, "utf-8").trim();
|
|
985
1047
|
}
|
|
986
1048
|
const packedRefsPath = join7(repoPath, ".git", "packed-refs");
|
|
987
|
-
if (
|
|
1049
|
+
if (existsSync6(packedRefsPath)) {
|
|
988
1050
|
const packedRefs = readFileSync5(packedRefsPath, "utf-8");
|
|
989
1051
|
const refName = headContent.slice(5);
|
|
990
1052
|
const lines = packedRefs.split("\n");
|
|
@@ -1003,7 +1065,7 @@ function getCurrentCommit(repoPath) {
|
|
|
1003
1065
|
function readScanCache() {
|
|
1004
1066
|
try {
|
|
1005
1067
|
const cachePath = getCachePath();
|
|
1006
|
-
if (!
|
|
1068
|
+
if (!existsSync6(cachePath)) return null;
|
|
1007
1069
|
const content = readFileSync5(cachePath, "utf-8");
|
|
1008
1070
|
const cache = JSON.parse(content);
|
|
1009
1071
|
if (!cache.skills || !cache.timestamp) return null;
|
|
@@ -1018,7 +1080,7 @@ function writeScanCache(cache) {
|
|
|
1018
1080
|
try {
|
|
1019
1081
|
const cachePath = getCachePath();
|
|
1020
1082
|
const cacheDir = dirname3(cachePath);
|
|
1021
|
-
if (!
|
|
1083
|
+
if (!existsSync6(cacheDir)) {
|
|
1022
1084
|
mkdirSync2(cacheDir, { recursive: true });
|
|
1023
1085
|
}
|
|
1024
1086
|
writeFileSync2(cachePath, JSON.stringify(cache, null, 2));
|
|
@@ -1032,9 +1094,9 @@ function scanDirectory(dirPath, repoPath, sourcePrefix, skills, seen) {
|
|
|
1032
1094
|
for (const entry of safeReaddir(dirPath)) {
|
|
1033
1095
|
const fullPath = join7(dirPath, entry);
|
|
1034
1096
|
if (EXCLUDE_DIRS.has(entry)) continue;
|
|
1035
|
-
if (!
|
|
1097
|
+
if (!isDirectory2(fullPath)) continue;
|
|
1036
1098
|
const skillMd = join7(fullPath, "SKILL.md");
|
|
1037
|
-
if (
|
|
1099
|
+
if (existsSync6(skillMd)) {
|
|
1038
1100
|
const frontmatter = parseFrontmatter(skillMd);
|
|
1039
1101
|
if (frontmatter && !seen.has(frontmatter.name)) {
|
|
1040
1102
|
seen.add(frontmatter.name);
|
|
@@ -1057,9 +1119,9 @@ function safeReaddir(dir) {
|
|
|
1057
1119
|
return [];
|
|
1058
1120
|
}
|
|
1059
1121
|
}
|
|
1060
|
-
function
|
|
1122
|
+
function isDirectory2(path) {
|
|
1061
1123
|
try {
|
|
1062
|
-
return
|
|
1124
|
+
return statSync2(path).isDirectory();
|
|
1063
1125
|
} catch {
|
|
1064
1126
|
return false;
|
|
1065
1127
|
}
|
|
@@ -1076,6 +1138,7 @@ var CATEGORY_DEFS = [
|
|
|
1076
1138
|
{ id: "tilelang", name: "TileLang \u5F00\u53D1" },
|
|
1077
1139
|
{ id: "triton", name: "Triton \u5F00\u53D1" },
|
|
1078
1140
|
{ id: "model", name: "\u6A21\u578B\u63A8\u7406\u4F18\u5316" },
|
|
1141
|
+
{ id: "runtime", name: "Runtime \u8FC1\u79FB" },
|
|
1079
1142
|
{ id: "graph", name: "\u56FE\u6A21\u5F0F" },
|
|
1080
1143
|
{ id: "platform", name: "\u5E73\u53F0\u5DE5\u5177" },
|
|
1081
1144
|
{ id: "other", name: "\u5176\u4ED6 Skills" }
|
|
@@ -1086,7 +1149,8 @@ function initFromScan(scanned) {
|
|
|
1086
1149
|
dynamicSkills = scanned.map((s) => ({
|
|
1087
1150
|
id: s.id,
|
|
1088
1151
|
description: s.description,
|
|
1089
|
-
source: s.source
|
|
1152
|
+
source: s.source,
|
|
1153
|
+
filePath: s.filePath
|
|
1090
1154
|
}));
|
|
1091
1155
|
initialized = true;
|
|
1092
1156
|
}
|
|
@@ -1162,9 +1226,7 @@ var STATIC_SKILL_CATEGORIES = [
|
|
|
1162
1226
|
{ id: "catlass-op-develop", description: "Catlass \u7B97\u5B50\u5F00\u53D1", source: "ops" },
|
|
1163
1227
|
{ id: "catlass-op-perf-tune", description: "Catlass \u6027\u80FD\u8C03\u4F18", source: "ops" },
|
|
1164
1228
|
{ id: "cuda2ascend-simt", description: "CUDA \u8FC1\u79FB\u5230 Ascend C SIMT", source: "ops-lab" },
|
|
1165
|
-
{ id: "ops-direct-invoke-flash", description: "\u4ECE\u96F6\u6784\u5EFA Ascend C \u6838\u51FD\u6570", source: "plugins-official/ops-direct-invoke-flash/skills" }
|
|
1166
|
-
{ id: "ops-registry-invoke-workflow", description: "\u6CE8\u518C\u8C03\u7528\u5DE5\u4F5C\u6D41", source: "plugins-official/ops-registry-invoke" },
|
|
1167
|
-
{ id: "ops-easyasc-dsl", description: "EasyASC DSL \u7B97\u5B50\u5F00\u53D1", source: "plugins-community/ops-easyasc-dsl/skill" }
|
|
1229
|
+
{ id: "ops-direct-invoke-flash", description: "\u4ECE\u96F6\u6784\u5EFA Ascend C \u6838\u51FD\u6570", source: "plugins-official/ops-direct-invoke-flash/skills" }
|
|
1168
1230
|
]
|
|
1169
1231
|
},
|
|
1170
1232
|
{
|
|
@@ -1221,7 +1283,9 @@ var STATIC_SKILL_CATEGORIES = [
|
|
|
1221
1283
|
{ id: "model-infer-prefetch", description: "\u6743\u91CD\u9884\u53D6\u9002\u914D", source: "model" },
|
|
1222
1284
|
{ id: "model-infer-superkernel", description: "SuperKernel \u9002\u914D", source: "model" },
|
|
1223
1285
|
{ id: "model-infer-precision-debug", description: "NPU \u63A8\u7406\u7CBE\u5EA6\u8BCA\u65AD", source: "model" },
|
|
1224
|
-
{ id: "model-infer-runtime-debug", description: "NPU \u63A8\u7406\u8FD0\u884C\u65F6\u9519\u8BEF\u8BCA\u65AD", source: "model" }
|
|
1286
|
+
{ id: "model-infer-runtime-debug", description: "NPU \u63A8\u7406\u8FD0\u884C\u65F6\u9519\u8BEF\u8BCA\u65AD", source: "model" },
|
|
1287
|
+
{ id: "model-infer-harmony", description: "\u7AEF\u4FA7\u9E3F\u8499 ASR \u91CF\u5316\u8F6C\u6362\u4E0E\u6253\u5305", source: "model" },
|
|
1288
|
+
{ id: "science-model-npu-migration", description: "NPU \u4EE3\u7801\u7EA7\u8FC1\u79FB\uFF08\u73AF\u5883\u95E8\u7981/\u811A\u672C\u9002\u914D/\u7CBE\u5EA6\u6027\u80FD\u5BF9\u6BD4\uFF09", source: "plugins-community/science-model-npu-migration", filePath: "plugins-community/science-model-npu-migration/SKILL.md" }
|
|
1225
1289
|
]
|
|
1226
1290
|
},
|
|
1227
1291
|
{
|
|
@@ -1237,6 +1301,13 @@ var STATIC_SKILL_CATEGORIES = [
|
|
|
1237
1301
|
{ id: "torch-custom-ops-guide", description: "\u81EA\u5B9A\u4E49\u7B97\u5B50\u5165\u56FE\u6307\u5357", source: "graph" }
|
|
1238
1302
|
]
|
|
1239
1303
|
},
|
|
1304
|
+
{
|
|
1305
|
+
id: "runtime",
|
|
1306
|
+
name: "Runtime \u8FC1\u79FB",
|
|
1307
|
+
skills: [
|
|
1308
|
+
{ id: "runtime_migration", description: "CUDA \u5E94\u7528\u8FC1\u79FB\u5230 CANN \u5E73\u53F0\u6307\u5357", source: "runtime" }
|
|
1309
|
+
]
|
|
1310
|
+
},
|
|
1240
1311
|
{
|
|
1241
1312
|
id: "platform",
|
|
1242
1313
|
name: "\u5E73\u53F0\u5DE5\u5177",
|
|
@@ -1331,10 +1402,13 @@ var RepositoryManager = class {
|
|
|
1331
1402
|
this.repoPath = cachedPath;
|
|
1332
1403
|
return cachedPath;
|
|
1333
1404
|
}
|
|
1334
|
-
|
|
1405
|
+
const clonedPath = await this.cloneRepo();
|
|
1406
|
+
return clonedPath;
|
|
1335
1407
|
}
|
|
1336
1408
|
async ensureRepoAndScan() {
|
|
1337
1409
|
const repoPath = await this.ensureRepo();
|
|
1410
|
+
await this.updateRepo();
|
|
1411
|
+
mergeDynamicPlugins(repoPath);
|
|
1338
1412
|
const cache = readScanCache();
|
|
1339
1413
|
if (cache && cache.repoCommit === getCurrentCommit(repoPath)) {
|
|
1340
1414
|
initFromScan(cache.skills);
|
|
@@ -1355,6 +1429,7 @@ var RepositoryManager = class {
|
|
|
1355
1429
|
await execa2("git", ["pull", "--quiet"], { cwd: repoPath, timeout: 3e4 });
|
|
1356
1430
|
} catch {
|
|
1357
1431
|
}
|
|
1432
|
+
mergeDynamicPlugins(repoPath);
|
|
1358
1433
|
}
|
|
1359
1434
|
getRepoPath() {
|
|
1360
1435
|
if (!this.repoPath) {
|
|
@@ -1363,18 +1438,18 @@ var RepositoryManager = class {
|
|
|
1363
1438
|
return this.repoPath;
|
|
1364
1439
|
}
|
|
1365
1440
|
isValidRepo(path) {
|
|
1366
|
-
if (!
|
|
1441
|
+
if (!existsSync7(path)) return false;
|
|
1367
1442
|
const gitDir = join8(path, ".git");
|
|
1368
1443
|
const pluginsDir = join8(path, "plugins-official");
|
|
1369
|
-
return
|
|
1444
|
+
return existsSync7(gitDir) && existsSync7(pluginsDir);
|
|
1370
1445
|
}
|
|
1371
1446
|
async cloneRepo() {
|
|
1372
1447
|
const configDir = getCannbotConfigDir();
|
|
1373
|
-
if (!
|
|
1448
|
+
if (!existsSync7(configDir)) {
|
|
1374
1449
|
mkdirSync3(configDir, { recursive: true });
|
|
1375
1450
|
}
|
|
1376
1451
|
const targetPath = getCannbotRepoPath();
|
|
1377
|
-
if (
|
|
1452
|
+
if (existsSync7(targetPath)) {
|
|
1378
1453
|
if (this.isValidRepo(targetPath)) {
|
|
1379
1454
|
this.repoPath = targetPath;
|
|
1380
1455
|
return targetPath;
|
|
@@ -1400,12 +1475,12 @@ function createRepositoryManager(customPath) {
|
|
|
1400
1475
|
}
|
|
1401
1476
|
|
|
1402
1477
|
// src/core/installer.ts
|
|
1403
|
-
import { existsSync as
|
|
1478
|
+
import { existsSync as existsSync10 } from "fs";
|
|
1404
1479
|
import { join as join11 } from "path";
|
|
1405
1480
|
import { execa as execa3 } from "execa";
|
|
1406
1481
|
|
|
1407
1482
|
// src/core/record.ts
|
|
1408
|
-
import { existsSync as
|
|
1483
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync4, lstatSync, unlinkSync } from "fs";
|
|
1409
1484
|
import { join as join9 } from "path";
|
|
1410
1485
|
function getInstallsDir() {
|
|
1411
1486
|
return join9(getCannbotConfigDir(), "installs");
|
|
@@ -1415,7 +1490,7 @@ function getRecordPath(pluginId) {
|
|
|
1415
1490
|
}
|
|
1416
1491
|
function readRecord(pluginId) {
|
|
1417
1492
|
const recordPath = getRecordPath(pluginId);
|
|
1418
|
-
if (!
|
|
1493
|
+
if (!existsSync8(recordPath)) {
|
|
1419
1494
|
return null;
|
|
1420
1495
|
}
|
|
1421
1496
|
try {
|
|
@@ -1427,7 +1502,7 @@ function readRecord(pluginId) {
|
|
|
1427
1502
|
}
|
|
1428
1503
|
function writeRecord(record) {
|
|
1429
1504
|
const installsDir = getInstallsDir();
|
|
1430
|
-
if (!
|
|
1505
|
+
if (!existsSync8(installsDir)) {
|
|
1431
1506
|
mkdirSync4(installsDir, { recursive: true });
|
|
1432
1507
|
}
|
|
1433
1508
|
const recordPath = getRecordPath(record.pluginId);
|
|
@@ -1435,7 +1510,7 @@ function writeRecord(record) {
|
|
|
1435
1510
|
}
|
|
1436
1511
|
function deleteRecord(pluginId) {
|
|
1437
1512
|
const recordPath = getRecordPath(pluginId);
|
|
1438
|
-
if (
|
|
1513
|
+
if (existsSync8(recordPath)) {
|
|
1439
1514
|
unlinkSync(recordPath);
|
|
1440
1515
|
}
|
|
1441
1516
|
}
|
|
@@ -1444,24 +1519,24 @@ function scanInstalledFiles(pluginId, displayName, tool, level, installPath, con
|
|
|
1444
1519
|
const directories = [];
|
|
1445
1520
|
if (manifest) {
|
|
1446
1521
|
const skillsDir = join9(configRoot, "skills");
|
|
1447
|
-
if (
|
|
1522
|
+
if (existsSync8(skillsDir)) {
|
|
1448
1523
|
directories.push(skillsDir);
|
|
1449
1524
|
for (const skillName of manifest.installed_skills || []) {
|
|
1450
1525
|
const skillPath = join9(skillsDir, skillName);
|
|
1451
|
-
if (
|
|
1526
|
+
if (existsSync8(skillPath) || isSymlink(skillPath)) {
|
|
1452
1527
|
files.push(skillPath);
|
|
1453
1528
|
}
|
|
1454
1529
|
}
|
|
1455
1530
|
}
|
|
1456
1531
|
const agentsDir = join9(configRoot, "agents");
|
|
1457
|
-
if (
|
|
1532
|
+
if (existsSync8(agentsDir)) {
|
|
1458
1533
|
directories.push(agentsDir);
|
|
1459
1534
|
for (const agentName of manifest.installed_agents || []) {
|
|
1460
1535
|
const agentPath = join9(agentsDir, agentName);
|
|
1461
1536
|
const agentPathMd = join9(agentsDir, agentName + ".md");
|
|
1462
|
-
if (
|
|
1537
|
+
if (existsSync8(agentPath) || isSymlink(agentPath)) {
|
|
1463
1538
|
files.push(agentPath);
|
|
1464
|
-
} else if (
|
|
1539
|
+
} else if (existsSync8(agentPathMd) || isSymlink(agentPathMd)) {
|
|
1465
1540
|
files.push(agentPathMd);
|
|
1466
1541
|
}
|
|
1467
1542
|
}
|
|
@@ -1472,16 +1547,16 @@ function scanInstalledFiles(pluginId, displayName, tool, level, installPath, con
|
|
|
1472
1547
|
files.push(workflowsLink);
|
|
1473
1548
|
}
|
|
1474
1549
|
const manifestPath = join9(configRoot, "cannbot-manifest.json");
|
|
1475
|
-
if (
|
|
1550
|
+
if (existsSync8(manifestPath)) {
|
|
1476
1551
|
files.push(manifestPath);
|
|
1477
1552
|
}
|
|
1478
1553
|
const pluginManifestPath = join9(configRoot, `${pluginId}-manifest.json`);
|
|
1479
|
-
if (
|
|
1554
|
+
if (existsSync8(pluginManifestPath)) {
|
|
1480
1555
|
files.push(pluginManifestPath);
|
|
1481
1556
|
}
|
|
1482
1557
|
const configFileName = tool === "claude" ? "CLAUDE.md" : "AGENTS.md";
|
|
1483
1558
|
const configFilePath = level === "project" ? join9(installPath, configFileName) : join9(configRoot, configFileName);
|
|
1484
|
-
if (
|
|
1559
|
+
if (existsSync8(configFilePath)) {
|
|
1485
1560
|
files.push(configFilePath);
|
|
1486
1561
|
}
|
|
1487
1562
|
const repoLinks = ["asc-devkit", "pypto", "tilelang-ascend", "cann-recipes-infer", "cann-samples"];
|
|
@@ -1519,7 +1594,7 @@ function getSkillRecordPath() {
|
|
|
1519
1594
|
}
|
|
1520
1595
|
function readSkillRecord() {
|
|
1521
1596
|
const recordPath = getSkillRecordPath();
|
|
1522
|
-
if (!
|
|
1597
|
+
if (!existsSync8(recordPath)) {
|
|
1523
1598
|
return {};
|
|
1524
1599
|
}
|
|
1525
1600
|
try {
|
|
@@ -1531,7 +1606,7 @@ function readSkillRecord() {
|
|
|
1531
1606
|
}
|
|
1532
1607
|
function writeSkillRecord(record) {
|
|
1533
1608
|
const installsDir = getInstallsDir();
|
|
1534
|
-
if (!
|
|
1609
|
+
if (!existsSync8(installsDir)) {
|
|
1535
1610
|
mkdirSync4(installsDir, { recursive: true });
|
|
1536
1611
|
}
|
|
1537
1612
|
const recordPath = getSkillRecordPath();
|
|
@@ -1576,12 +1651,12 @@ function getInstalledSkills(tool, level, installPath) {
|
|
|
1576
1651
|
const skillsDir = join9(configRoot, "skills");
|
|
1577
1652
|
return recordedSkills.filter((skillId) => {
|
|
1578
1653
|
const skillPath = join9(skillsDir, skillId);
|
|
1579
|
-
return
|
|
1654
|
+
return existsSync8(skillPath) || isSymlink(skillPath);
|
|
1580
1655
|
});
|
|
1581
1656
|
}
|
|
1582
1657
|
|
|
1583
1658
|
// src/core/backup.ts
|
|
1584
|
-
import { existsSync as
|
|
1659
|
+
import { existsSync as existsSync9, copyFileSync, readdirSync as readdirSync3, unlinkSync as unlinkSync2 } from "fs";
|
|
1585
1660
|
import { join as join10 } from "path";
|
|
1586
1661
|
function getAgentsFileName(tool) {
|
|
1587
1662
|
return tool === "claude" ? "CLAUDE.md" : "AGENTS.md";
|
|
@@ -1598,7 +1673,7 @@ function detectCurrentPlugin(configRoot, tool) {
|
|
|
1598
1673
|
}
|
|
1599
1674
|
}
|
|
1600
1675
|
const agentsFile = join10(configRoot, getAgentsFileName(tool));
|
|
1601
|
-
if (!
|
|
1676
|
+
if (!existsSync9(agentsFile)) {
|
|
1602
1677
|
return null;
|
|
1603
1678
|
}
|
|
1604
1679
|
const allRecords = readAllRecords();
|
|
@@ -1617,7 +1692,7 @@ function detectCurrentPlugin(configRoot, tool) {
|
|
|
1617
1692
|
}
|
|
1618
1693
|
function createBackup(configRoot, tool, fromPluginId, fromPluginName) {
|
|
1619
1694
|
const agentsFile = join10(configRoot, getAgentsFileName(tool));
|
|
1620
|
-
if (!
|
|
1695
|
+
if (!existsSync9(agentsFile)) {
|
|
1621
1696
|
return null;
|
|
1622
1697
|
}
|
|
1623
1698
|
const timestamp = formatTimestamp(/* @__PURE__ */ new Date());
|
|
@@ -1636,7 +1711,7 @@ function createBackup(configRoot, tool, fromPluginId, fromPluginName) {
|
|
|
1636
1711
|
}
|
|
1637
1712
|
}
|
|
1638
1713
|
function findBackups(configRoot) {
|
|
1639
|
-
if (!
|
|
1714
|
+
if (!existsSync9(configRoot)) {
|
|
1640
1715
|
return [];
|
|
1641
1716
|
}
|
|
1642
1717
|
const files = readdirSync3(configRoot);
|
|
@@ -1674,7 +1749,7 @@ function restoreBackup(backupPath, configRoot, tool) {
|
|
|
1674
1749
|
}
|
|
1675
1750
|
function deleteBackup(backupPath) {
|
|
1676
1751
|
try {
|
|
1677
|
-
if (
|
|
1752
|
+
if (existsSync9(backupPath)) {
|
|
1678
1753
|
unlinkSync2(backupPath);
|
|
1679
1754
|
return true;
|
|
1680
1755
|
}
|
|
@@ -1767,7 +1842,7 @@ async function installPlugin(opts) {
|
|
|
1767
1842
|
};
|
|
1768
1843
|
}
|
|
1769
1844
|
const scriptPath = join11(opts.repoPath, plugin.dir, plugin.script);
|
|
1770
|
-
if (!
|
|
1845
|
+
if (!existsSync10(scriptPath)) {
|
|
1771
1846
|
return {
|
|
1772
1847
|
success: false,
|
|
1773
1848
|
pluginId: opts.pluginId,
|
|
@@ -1785,7 +1860,7 @@ async function installPlugin(opts) {
|
|
|
1785
1860
|
const configRoot = getConfigRoot(opts.tool, opts.level, opts.installPath);
|
|
1786
1861
|
const agentsFile = join11(configRoot, getAgentsFileName(opts.tool));
|
|
1787
1862
|
let backupInfo = null;
|
|
1788
|
-
if (
|
|
1863
|
+
if (existsSync10(agentsFile)) {
|
|
1789
1864
|
const currentPlugin = detectCurrentPlugin(configRoot, opts.tool);
|
|
1790
1865
|
if (currentPlugin && currentPlugin.pluginId !== opts.pluginId) {
|
|
1791
1866
|
let choice = "overwrite";
|
|
@@ -1878,8 +1953,8 @@ async function installPlugin(opts) {
|
|
|
1878
1953
|
}
|
|
1879
1954
|
|
|
1880
1955
|
// src/core/skill-installer.ts
|
|
1881
|
-
import { existsSync as
|
|
1882
|
-
import { join as join12 } from "path";
|
|
1956
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync5, symlinkSync, unlinkSync as unlinkSync3, readdirSync as readdirSync4, rmdirSync, realpathSync, lstatSync as lstatSync2 } from "fs";
|
|
1957
|
+
import { join as join12, dirname as dirname5 } from "path";
|
|
1883
1958
|
import { select as select3, checkbox as checkbox2, Separator as Separator2 } from "@inquirer/prompts";
|
|
1884
1959
|
import chalk5 from "chalk";
|
|
1885
1960
|
import Table from "cli-table3";
|
|
@@ -1887,7 +1962,7 @@ async function installSkills(skillIds, tool, level, repoPath) {
|
|
|
1887
1962
|
const configRoot = getConfigRoot(tool, level);
|
|
1888
1963
|
const skillsDir = join12(configRoot, "skills");
|
|
1889
1964
|
const installPath = level === "project" ? process.cwd() : configRoot;
|
|
1890
|
-
if (!
|
|
1965
|
+
if (!existsSync11(skillsDir)) {
|
|
1891
1966
|
mkdirSync5(skillsDir, { recursive: true });
|
|
1892
1967
|
}
|
|
1893
1968
|
const results = [];
|
|
@@ -1898,14 +1973,14 @@ async function installSkills(skillIds, tool, level, repoPath) {
|
|
|
1898
1973
|
results.push({ skillId, success: false, error: "Skill not found in registry" });
|
|
1899
1974
|
continue;
|
|
1900
1975
|
}
|
|
1901
|
-
const sourcePath =
|
|
1976
|
+
const sourcePath = resolveSkillSourcePath(skill, repoPath);
|
|
1902
1977
|
const targetPath = join12(skillsDir, skillId);
|
|
1903
|
-
if (!
|
|
1978
|
+
if (!existsSync11(sourcePath)) {
|
|
1904
1979
|
results.push({ skillId, success: false, error: `Source not found: ${sourcePath}` });
|
|
1905
1980
|
continue;
|
|
1906
1981
|
}
|
|
1907
1982
|
try {
|
|
1908
|
-
if (
|
|
1983
|
+
if (existsSync11(targetPath) || isSymlink2(targetPath)) {
|
|
1909
1984
|
unlinkSync3(targetPath);
|
|
1910
1985
|
}
|
|
1911
1986
|
symlinkSync(realpathSync(sourcePath), targetPath);
|
|
@@ -1929,7 +2004,7 @@ async function uninstallSkills(skillIds, tool, level) {
|
|
|
1929
2004
|
for (const skillId of skillIds) {
|
|
1930
2005
|
const targetPath = join12(skillsDir, skillId);
|
|
1931
2006
|
try {
|
|
1932
|
-
if (
|
|
2007
|
+
if (existsSync11(targetPath) || isSymlink2(targetPath)) {
|
|
1933
2008
|
unlinkSync3(targetPath);
|
|
1934
2009
|
results.push({ skillId, success: true });
|
|
1935
2010
|
removedIds.push(skillId);
|
|
@@ -1945,7 +2020,7 @@ async function uninstallSkills(skillIds, tool, level) {
|
|
|
1945
2020
|
if (removedIds.length > 0) {
|
|
1946
2021
|
removeSkillsFromRecord(removedIds, tool, level, installPath);
|
|
1947
2022
|
}
|
|
1948
|
-
if (
|
|
2023
|
+
if (existsSync11(skillsDir)) {
|
|
1949
2024
|
try {
|
|
1950
2025
|
const entries = readdirSync4(skillsDir);
|
|
1951
2026
|
if (entries.length === 0) {
|
|
@@ -2128,6 +2203,15 @@ function listAllSkills() {
|
|
|
2128
2203
|
console.log(chalk5.dim(` ${t("skill_total_count").replace("{count}", String(getAllSkills().length))}`));
|
|
2129
2204
|
console.log();
|
|
2130
2205
|
}
|
|
2206
|
+
function resolveSkillSourcePath(skill, repoPath) {
|
|
2207
|
+
if (skill.filePath) {
|
|
2208
|
+
const absPath = skill.filePath.startsWith("/") ? skill.filePath : join12(repoPath, skill.filePath);
|
|
2209
|
+
if (existsSync11(absPath)) {
|
|
2210
|
+
return dirname5(absPath);
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
return join12(repoPath, skill.source, skill.id);
|
|
2214
|
+
}
|
|
2131
2215
|
function isSymlink2(path) {
|
|
2132
2216
|
try {
|
|
2133
2217
|
return lstatSync2(path).isSymbolicLink();
|
|
@@ -2145,10 +2229,11 @@ function printPluginList(plugins, installed) {
|
|
|
2145
2229
|
chalk6.cyan(t("list_id")),
|
|
2146
2230
|
chalk6.cyan(t("list_name")),
|
|
2147
2231
|
chalk6.cyan(t("list_status")),
|
|
2148
|
-
chalk6.cyan(t("
|
|
2149
|
-
chalk6.cyan(t("list_agents"))
|
|
2232
|
+
chalk6.cyan(t("list_description"))
|
|
2150
2233
|
],
|
|
2151
|
-
style: { head: [], border: [] }
|
|
2234
|
+
style: { head: [], border: [] },
|
|
2235
|
+
colWidths: [6, 32, 8, 50],
|
|
2236
|
+
wordWrap: true
|
|
2152
2237
|
});
|
|
2153
2238
|
plugins.forEach((plugin, index) => {
|
|
2154
2239
|
const isInstalled = installed.has(plugin.id);
|
|
@@ -2157,8 +2242,7 @@ function printPluginList(plugins, installed) {
|
|
|
2157
2242
|
String(index + 1),
|
|
2158
2243
|
plugin.displayName,
|
|
2159
2244
|
status,
|
|
2160
|
-
|
|
2161
|
-
String(plugin.agents)
|
|
2245
|
+
plugin.description || chalk6.dim("\u2014")
|
|
2162
2246
|
]);
|
|
2163
2247
|
});
|
|
2164
2248
|
console.log();
|
|
@@ -2225,13 +2309,13 @@ function printEnhancedSummary(results, tool, configRoot) {
|
|
|
2225
2309
|
}
|
|
2226
2310
|
|
|
2227
2311
|
// src/commands/init.ts
|
|
2228
|
-
import { existsSync as
|
|
2312
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "fs";
|
|
2229
2313
|
import { join as join13 } from "path";
|
|
2230
2314
|
var BACK2 = "__back__";
|
|
2231
2315
|
var CANCEL2 = "__cancel__";
|
|
2232
2316
|
async function initCommand() {
|
|
2233
2317
|
const cwd = process.cwd();
|
|
2234
|
-
if (
|
|
2318
|
+
if (existsSync12(join13(cwd, "package.json")) && (() => {
|
|
2235
2319
|
try {
|
|
2236
2320
|
const pkg = JSON.parse(readFileSync8(join13(cwd, "package.json"), "utf-8"));
|
|
2237
2321
|
return pkg.name === "@cannbot-ai/install-helper";
|
|
@@ -2459,7 +2543,7 @@ async function listCommand() {
|
|
|
2459
2543
|
|
|
2460
2544
|
// src/commands/doctor.ts
|
|
2461
2545
|
import chalk8 from "chalk";
|
|
2462
|
-
import { existsSync as
|
|
2546
|
+
import { existsSync as existsSync13, readdirSync as readdirSync5, lstatSync as lstatSync3, unlinkSync as unlinkSync4, mkdirSync as mkdirSync6 } from "fs";
|
|
2463
2547
|
import { join as join14 } from "path";
|
|
2464
2548
|
async function doctorCommand(options = {}) {
|
|
2465
2549
|
console.log();
|
|
@@ -2503,7 +2587,7 @@ async function doctorCommand(options = {}) {
|
|
|
2503
2587
|
const configRoot = getConfigRoot(primaryTool, "project");
|
|
2504
2588
|
const skillsDir = getSkillsDir(configRoot);
|
|
2505
2589
|
const agentsDir = getAgentsDir(configRoot);
|
|
2506
|
-
if (
|
|
2590
|
+
if (existsSync13(skillsDir)) {
|
|
2507
2591
|
const brokenLinks = checkBrokenLinks(skillsDir);
|
|
2508
2592
|
if (brokenLinks === 0) {
|
|
2509
2593
|
const count = readdirSync5(skillsDir).length;
|
|
@@ -2525,7 +2609,7 @@ async function doctorCommand(options = {}) {
|
|
|
2525
2609
|
console.log(chalk8.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: ${t("doctor_created").replace("{path}", skillsDir)}`);
|
|
2526
2610
|
}
|
|
2527
2611
|
}
|
|
2528
|
-
if (
|
|
2612
|
+
if (existsSync13(agentsDir)) {
|
|
2529
2613
|
const brokenLinks = checkBrokenLinks(agentsDir);
|
|
2530
2614
|
if (brokenLinks === 0) {
|
|
2531
2615
|
const count = readdirSync5(agentsDir).length;
|
|
@@ -2551,7 +2635,7 @@ async function doctorCommand(options = {}) {
|
|
|
2551
2635
|
console.log(chalk8.bold(` ${t("doctor_config")}`));
|
|
2552
2636
|
const configFile = getConfigFileName(primaryTool);
|
|
2553
2637
|
const configPath = join14(process.cwd(), configFile);
|
|
2554
|
-
if (
|
|
2638
|
+
if (existsSync13(configPath)) {
|
|
2555
2639
|
console.log(chalk8.green(" \u2713") + ` ${configFile} ${t("doctor_config_exists")}`);
|
|
2556
2640
|
} else {
|
|
2557
2641
|
console.log(chalk8.dim(" \u2014") + ` ${configFile} ${t("doctor_config_not_exist")}`);
|
|
@@ -2578,7 +2662,7 @@ function checkBrokenLinks(dir) {
|
|
|
2578
2662
|
try {
|
|
2579
2663
|
const stats = lstatSync3(fullPath);
|
|
2580
2664
|
if (stats.isSymbolicLink()) {
|
|
2581
|
-
if (!
|
|
2665
|
+
if (!existsSync13(fullPath)) {
|
|
2582
2666
|
broken++;
|
|
2583
2667
|
}
|
|
2584
2668
|
}
|
|
@@ -2599,7 +2683,7 @@ function fixBrokenLinks(dir) {
|
|
|
2599
2683
|
try {
|
|
2600
2684
|
const stats = lstatSync3(fullPath);
|
|
2601
2685
|
if (stats.isSymbolicLink()) {
|
|
2602
|
-
if (!
|
|
2686
|
+
if (!existsSync13(fullPath)) {
|
|
2603
2687
|
unlinkSync4(fullPath);
|
|
2604
2688
|
fixed++;
|
|
2605
2689
|
}
|
|
@@ -2931,7 +3015,7 @@ async function installPlugins(pluginIds, tool, level, repoPath, installPath, yes
|
|
|
2931
3015
|
}
|
|
2932
3016
|
|
|
2933
3017
|
// src/commands/uninstall.ts
|
|
2934
|
-
import { existsSync as
|
|
3018
|
+
import { existsSync as existsSync14, unlinkSync as unlinkSync5, rmdirSync as rmdirSync2, readdirSync as readdirSync6, lstatSync as lstatSync4 } from "fs";
|
|
2935
3019
|
import chalk11 from "chalk";
|
|
2936
3020
|
async function uninstallCommand(names, options) {
|
|
2937
3021
|
const tool = options.tool ? validateTool(options.tool) : "opencode";
|
|
@@ -2965,7 +3049,7 @@ async function uninstallCommand(names, options) {
|
|
|
2965
3049
|
let removedDirs = 0;
|
|
2966
3050
|
for (const filePath of record.files) {
|
|
2967
3051
|
try {
|
|
2968
|
-
if (
|
|
3052
|
+
if (existsSync14(filePath) || isSymlink3(filePath)) {
|
|
2969
3053
|
unlinkSync5(filePath);
|
|
2970
3054
|
const name = filePath.split("/").pop() || filePath;
|
|
2971
3055
|
logger.step(` ${t("uninstall_remove_label")}: ${name}`);
|
|
@@ -2981,7 +3065,7 @@ async function uninstallCommand(names, options) {
|
|
|
2981
3065
|
if (dirPath === configRoot) {
|
|
2982
3066
|
continue;
|
|
2983
3067
|
}
|
|
2984
|
-
if (
|
|
3068
|
+
if (existsSync14(dirPath)) {
|
|
2985
3069
|
const entries = readdirSync6(dirPath);
|
|
2986
3070
|
if (entries.length === 0) {
|
|
2987
3071
|
rmdirSync2(dirPath);
|
|
@@ -3126,7 +3210,7 @@ async function updateCommand(pluginNames, options) {
|
|
|
3126
3210
|
|
|
3127
3211
|
// src/commands/info.ts
|
|
3128
3212
|
import chalk13 from "chalk";
|
|
3129
|
-
import { existsSync as
|
|
3213
|
+
import { existsSync as existsSync15, readdirSync as readdirSync7 } from "fs";
|
|
3130
3214
|
import { join as join15 } from "path";
|
|
3131
3215
|
async function infoCommand(pluginName) {
|
|
3132
3216
|
const plugin = findPlugin(pluginName);
|
|
@@ -3152,11 +3236,11 @@ async function infoCommand(pluginName) {
|
|
|
3152
3236
|
const repoManager = createRepositoryManager();
|
|
3153
3237
|
const repoPath = await repoManager.ensureRepo();
|
|
3154
3238
|
const quickstartPath = join15(repoPath, plugin.dir, "quickstart.md");
|
|
3155
|
-
if (
|
|
3239
|
+
if (existsSync15(quickstartPath)) {
|
|
3156
3240
|
console.log(` ${chalk13.dim(t("info_quickstart") + ":")} ${quickstartPath}`);
|
|
3157
3241
|
}
|
|
3158
3242
|
const agentsDir = join15(repoPath, plugin.dir, "agents");
|
|
3159
|
-
if (
|
|
3243
|
+
if (existsSync15(agentsDir)) {
|
|
3160
3244
|
const agentFiles = readdirSync7(agentsDir).filter((f) => f.endsWith(".md"));
|
|
3161
3245
|
if (agentFiles.length > 0) {
|
|
3162
3246
|
console.log();
|
|
@@ -3214,7 +3298,7 @@ function createCLI() {
|
|
|
3214
3298
|
setLanguage(config.language);
|
|
3215
3299
|
}
|
|
3216
3300
|
const program2 = new Command();
|
|
3217
|
-
program2.name("install-helper").description("CANNBot Install Helper - Interactive installer for CANN operator development skills").version("0.0.2-beta.
|
|
3301
|
+
program2.name("install-helper").description("CANNBot Install Helper - Interactive installer for CANN operator development skills").version("0.0.2-beta.32");
|
|
3218
3302
|
program2.command("init", { isDefault: false }).description("Run interactive installation wizard").action(async () => {
|
|
3219
3303
|
await initCommand();
|
|
3220
3304
|
});
|