@cannbot-ai/install-helper 1.1.13 → 1.1.14
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 +18 -3
- package/dist/index.js +169 -107
- package/dist/index.js.map +1 -1
- package/dist/locales/en_US.json +2 -0
- package/dist/locales/zh_CN.json +2 -0
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -64,64 +64,20 @@ var init_embedded_plugins = __esm({
|
|
|
64
64
|
"direct",
|
|
65
65
|
"kernel"
|
|
66
66
|
],
|
|
67
|
-
skills:
|
|
68
|
-
agents:
|
|
69
|
-
description: "
|
|
70
|
-
version: "
|
|
67
|
+
skills: 0,
|
|
68
|
+
agents: 6,
|
|
69
|
+
description: "skill \u9A71\u52A8\u591A\u89D2\u8272\u76F4\u8C03\u7B97\u5B50\u5F00\u53D1\u5DE5\u4F5C\u6D41\uFF1APM \u8C03\u5EA6 architect/developer/qa \u56E2\u961F\uFF0C8 \u9636\u6BB5 7 CP \u5168\u6D41\u7A0B\uFF0C\u652F\u6301\u9759\u9ED8\u6A21\u5F0F\u4E0E\u7B97\u5B50\u4ED3\u7EE7\u627F\u5B9A\u5236",
|
|
70
|
+
version: "2.0.0",
|
|
71
71
|
configFile: "AGENTS.md",
|
|
72
72
|
configRootConfigLink: false,
|
|
73
|
-
installSkills: [
|
|
74
|
-
{
|
|
75
|
-
dir: "ops",
|
|
76
|
-
skills: [
|
|
77
|
-
"ascendc-tiling-design",
|
|
78
|
-
"npu-arch",
|
|
79
|
-
"ascendc-api-best-practices",
|
|
80
|
-
"ascendc-regbase-best-practice",
|
|
81
|
-
"ascendc-blaze-best-practice",
|
|
82
|
-
"ascendc-blaze-migration",
|
|
83
|
-
"ascendc-mc2-best-practice",
|
|
84
|
-
"ops-precision-standard",
|
|
85
|
-
"ascendc-docs-search",
|
|
86
|
-
"ascendc-env-check",
|
|
87
|
-
"ascendc-precision-debug",
|
|
88
|
-
"ops-profiling",
|
|
89
|
-
"ascendc-direct-invoke-template",
|
|
90
|
-
"torch-ascendc-op-extension",
|
|
91
|
-
"ascendc-runtime-debug",
|
|
92
|
-
"ascendc-crash-debug",
|
|
93
|
-
"ascendc-code-review"
|
|
94
|
-
]
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
dir: "infra",
|
|
98
|
-
skills: [
|
|
99
|
-
"gitcode-toolkit",
|
|
100
|
-
"gitcode-pr-handler",
|
|
101
|
-
"gitcode-issue-gen",
|
|
102
|
-
"gitcode-issue-handler"
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
],
|
|
73
|
+
installSkills: [],
|
|
106
74
|
installAgents: [
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
{
|
|
114
|
-
url: "https://gitcode.com/cann/asc-devkit.git",
|
|
115
|
-
dir: "plugins-official/ops-direct-invoke/asc-devkit",
|
|
116
|
-
configRootLink: false
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
url: "https://gitcode.com/cann/ops-tensor.git",
|
|
120
|
-
dir: "plugins-official/ops-direct-invoke/ops-tensor",
|
|
121
|
-
depth: 1,
|
|
122
|
-
recursive: true,
|
|
123
|
-
configRootLink: false
|
|
124
|
-
}
|
|
75
|
+
"architect",
|
|
76
|
+
"developer",
|
|
77
|
+
"developer-code",
|
|
78
|
+
"developer-doc",
|
|
79
|
+
"developer-test",
|
|
80
|
+
"qa"
|
|
125
81
|
]
|
|
126
82
|
},
|
|
127
83
|
{
|
|
@@ -803,6 +759,8 @@ var init_zh_CN = __esm({
|
|
|
803
759
|
install_skill_not_found: "Skill \u672A\u627E\u5230: {name} (\u5728 {dir})",
|
|
804
760
|
install_skill_failed: "Skill \u5B89\u88C5\u5931\u8D25: {name}",
|
|
805
761
|
install_agent_not_found: "Agent \u672A\u627E\u5230: {name}",
|
|
762
|
+
install_agent_codex_toml_missing: "\u63D2\u4EF6\u672A\u63D0\u4F9B Codex \u9002\u914D\u6587\u4EF6 {path}\uFF0C\u5DF2\u8DF3\u8FC7 agent: {name}",
|
|
763
|
+
error_tool_not_supported: "\u63D2\u4EF6 {plugin} \u7684\u5B89\u88C5\u811A\u672C\u6682\u4E0D\u652F\u6301\u5DE5\u5177 {tool}\uFF08\u4E3A\u907F\u514D\u8BEF\u88C5\u5230\u9ED8\u8BA4\u76EE\u5F55\u5DF2\u4E2D\u6B62\uFF09\uFF0C\u8BF7\u67E5\u770B\u8BE5\u63D2\u4EF6 quickstart.md \u786E\u8BA4\u652F\u6301\u7684\u5DE5\u5177\u5217\u8868",
|
|
806
764
|
install_agent_failed: "Agent \u5B89\u88C5\u5931\u8D25: {name}",
|
|
807
765
|
install_no_skill_selected: "\u672A\u9009\u62E9\u4EFB\u4F55 Skill",
|
|
808
766
|
install_to: "\u5B89\u88C5\u5230",
|
|
@@ -1026,6 +984,8 @@ var init_en_US = __esm({
|
|
|
1026
984
|
install_skill_not_found: "Skill not found: {name} in {dir}",
|
|
1027
985
|
install_skill_failed: "Failed to install skill: {name}",
|
|
1028
986
|
install_agent_not_found: "Agent not found: {name}",
|
|
987
|
+
install_agent_codex_toml_missing: "Codex adapter file {path} not found in plugin, agent skipped: {name}",
|
|
988
|
+
error_tool_not_supported: "Plugin {plugin} does not support tool {tool} yet (aborted to avoid mis-installing into default directories); see the plugin quickstart.md for supported tools",
|
|
1029
989
|
install_agent_failed: "Failed to install agent: {name}",
|
|
1030
990
|
install_no_skill_selected: "No Skill selected",
|
|
1031
991
|
install_to: "Install to",
|
|
@@ -1196,6 +1156,8 @@ function getConfigRoot(tool, level, base) {
|
|
|
1196
1156
|
}
|
|
1197
1157
|
case "cursor":
|
|
1198
1158
|
return join3(home, ".cursor");
|
|
1159
|
+
case "codex":
|
|
1160
|
+
return join3(home, ".codex");
|
|
1199
1161
|
case "copilot":
|
|
1200
1162
|
return join3(home, ".copilot");
|
|
1201
1163
|
case "codearts":
|
|
@@ -1225,6 +1187,8 @@ function getConfigRoot(tool, level, base) {
|
|
|
1225
1187
|
}
|
|
1226
1188
|
case "cursor":
|
|
1227
1189
|
return join3(baseDir, ".cursor");
|
|
1190
|
+
case "codex":
|
|
1191
|
+
return join3(baseDir, ".codex");
|
|
1228
1192
|
case "copilot":
|
|
1229
1193
|
return join3(baseDir, ".github");
|
|
1230
1194
|
case "codearts":
|
|
@@ -1238,12 +1202,18 @@ function getConfigRoot(tool, level, base) {
|
|
|
1238
1202
|
function getConfigFileName(tool) {
|
|
1239
1203
|
return tool === "claude" ? "CLAUDE.md" : "AGENTS.md";
|
|
1240
1204
|
}
|
|
1205
|
+
function getSkillsRoot(tool, level, base) {
|
|
1206
|
+
if (tool === "codex") {
|
|
1207
|
+
if (level === "global") {
|
|
1208
|
+
return join3(homedir(), ".agents", "skills");
|
|
1209
|
+
}
|
|
1210
|
+
return join3(base || process.cwd(), ".agents", "skills");
|
|
1211
|
+
}
|
|
1212
|
+
return join3(getConfigRoot(tool, level, base), "skills");
|
|
1213
|
+
}
|
|
1241
1214
|
function getAgentsFileName(tool) {
|
|
1242
1215
|
return getConfigFileName(tool);
|
|
1243
1216
|
}
|
|
1244
|
-
function getSkillsDir(configRoot) {
|
|
1245
|
-
return join3(configRoot, "skills");
|
|
1246
|
-
}
|
|
1247
1217
|
function getAgentsDir(configRoot) {
|
|
1248
1218
|
return join3(configRoot, "agents");
|
|
1249
1219
|
}
|
|
@@ -1261,7 +1231,7 @@ var init_paths = __esm({
|
|
|
1261
1231
|
"src/utils/paths.ts"() {
|
|
1262
1232
|
"use strict";
|
|
1263
1233
|
init_i18n();
|
|
1264
|
-
VALID_TOOLS = ["opencode", "claude", "trae", "cursor", "copilot", "codearts"];
|
|
1234
|
+
VALID_TOOLS = ["opencode", "claude", "trae", "cursor", "codex", "copilot", "codearts"];
|
|
1265
1235
|
VALID_LEVELS = ["project", "global"];
|
|
1266
1236
|
}
|
|
1267
1237
|
});
|
|
@@ -1333,6 +1303,19 @@ async function detectCursor() {
|
|
|
1333
1303
|
}
|
|
1334
1304
|
return void 0;
|
|
1335
1305
|
}
|
|
1306
|
+
async function detectCodex() {
|
|
1307
|
+
const cmdPath = await getCommandPath("codex");
|
|
1308
|
+
if (cmdPath) {
|
|
1309
|
+
const version = await getCommandVersion("codex");
|
|
1310
|
+
return { name: "codex", version, path: cmdPath };
|
|
1311
|
+
}
|
|
1312
|
+
const home = homedir2();
|
|
1313
|
+
const configDir = join4(home, ".codex");
|
|
1314
|
+
if (existsSync4(configDir)) {
|
|
1315
|
+
return { name: "codex", path: configDir };
|
|
1316
|
+
}
|
|
1317
|
+
return void 0;
|
|
1318
|
+
}
|
|
1336
1319
|
async function detectCopilot() {
|
|
1337
1320
|
const path = await getCommandPath("gh");
|
|
1338
1321
|
if (!path) return void 0;
|
|
@@ -1357,6 +1340,7 @@ async function detectTools() {
|
|
|
1357
1340
|
detectClaude,
|
|
1358
1341
|
detectTrae,
|
|
1359
1342
|
detectCursor,
|
|
1343
|
+
detectCodex,
|
|
1360
1344
|
detectCopilot,
|
|
1361
1345
|
detectCodeArts
|
|
1362
1346
|
];
|
|
@@ -1375,6 +1359,7 @@ function getToolDisplayName(tool) {
|
|
|
1375
1359
|
claude: "Claude Code",
|
|
1376
1360
|
trae: "Trae",
|
|
1377
1361
|
cursor: "Cursor",
|
|
1362
|
+
codex: "Codex",
|
|
1378
1363
|
copilot: "GitHub Copilot",
|
|
1379
1364
|
codearts: "CodeArts"
|
|
1380
1365
|
};
|
|
@@ -1462,7 +1447,7 @@ function scanInstalled() {
|
|
|
1462
1447
|
return installed;
|
|
1463
1448
|
}
|
|
1464
1449
|
function verifyPluginFilesExist(configRoot, manifest, tool, level) {
|
|
1465
|
-
const skillsDir =
|
|
1450
|
+
const skillsDir = getSkillsRoot(tool, level);
|
|
1466
1451
|
const agentsDir = join5(configRoot, "agents");
|
|
1467
1452
|
let hasAnyComponent = false;
|
|
1468
1453
|
if (manifest.installed_skills && manifest.installed_skills.length > 0) {
|
|
@@ -2323,7 +2308,7 @@ var STATIC_SKILL_CATEGORIES = [
|
|
|
2323
2308
|
{ id: "ascendc-blaze-migration", description: "AscendC Matmul \u5BB6\u65CF\u7B49\u4EF7\u8FC1\u79FB\u5230 Blaze", source: "ops" },
|
|
2324
2309
|
{ id: "ascendc-simt-best-practices", description: "SIMT \u6700\u4F73\u5B9E\u8DF5\u4E0E API \u5BFC\u822A", source: "ops" },
|
|
2325
2310
|
{ id: "ascendc-simt-tiling-design", description: "SIMT \u7B97\u5B50\u5207\u5206\u8BBE\u8BA1", source: "ops" },
|
|
2326
|
-
{ id: "torch-ascendc-op-extension", description: "
|
|
2311
|
+
{ id: "torch-ascendc-op-extension", description: "\u7B97\u5B50\u5BF9\u63A5 PyTorch\uFF08kernel \u76F4\u8C03 / aclnn \u6CE8\u518C\u53CC\u8DEF\u7EBF\uFF09", source: "ops" },
|
|
2327
2312
|
{ id: "catlass-op-design", description: "Catlass \u7B97\u5B50\u8BBE\u8BA1", source: "ops" },
|
|
2328
2313
|
{ id: "catlass-op-develop", description: "Catlass \u7B97\u5B50\u5F00\u53D1", source: "ops" },
|
|
2329
2314
|
{ id: "catlass-op-perf-tune", description: "Catlass \u6027\u80FD\u8C03\u4F18", source: "ops" },
|
|
@@ -2772,7 +2757,7 @@ function createRepositoryManager(customPath) {
|
|
|
2772
2757
|
init_registry();
|
|
2773
2758
|
init_manifest();
|
|
2774
2759
|
init_paths();
|
|
2775
|
-
import { existsSync as existsSync14 } from "fs";
|
|
2760
|
+
import { existsSync as existsSync14, readFileSync as readFileSync9 } from "fs";
|
|
2776
2761
|
import { join as join13, basename as basename2 } from "path";
|
|
2777
2762
|
import { execa as execa4, execaSync } from "execa";
|
|
2778
2763
|
|
|
@@ -2821,7 +2806,7 @@ function scanInstalledFiles(pluginId, displayName, tool, level, installPath, con
|
|
|
2821
2806
|
const files = [];
|
|
2822
2807
|
const directories = [];
|
|
2823
2808
|
if (manifest) {
|
|
2824
|
-
const skillsDir =
|
|
2809
|
+
const skillsDir = getSkillsRoot(tool, level, installPath);
|
|
2825
2810
|
if (existsSync11(skillsDir)) {
|
|
2826
2811
|
directories.push(skillsDir);
|
|
2827
2812
|
for (const skillName of manifest.installed_skills || []) {
|
|
@@ -2970,8 +2955,7 @@ function removeSkillsFromRecord(skillIds, tool, level, installPath) {
|
|
|
2970
2955
|
function getInstalledSkills(tool, level, installPath, allowFsScan = true) {
|
|
2971
2956
|
const record = readSkillRecord();
|
|
2972
2957
|
const recordedSkills = record[tool]?.[level]?.[installPath]?.skills || [];
|
|
2973
|
-
const
|
|
2974
|
-
const skillsDir = join10(configRoot, "skills");
|
|
2958
|
+
const skillsDir = getSkillsRoot(tool, level);
|
|
2975
2959
|
const fromRecord = recordedSkills.filter((skillId) => {
|
|
2976
2960
|
const skillPath = join10(skillsDir, skillId);
|
|
2977
2961
|
return existsSync11(skillPath) || isSymlink(skillPath);
|
|
@@ -3002,8 +2986,7 @@ function getLastBatchSkills(tool, level, installPath) {
|
|
|
3002
2986
|
return null;
|
|
3003
2987
|
}
|
|
3004
2988
|
const lastBatch = entry.batches[entry.batches.length - 1];
|
|
3005
|
-
const
|
|
3006
|
-
const skillsDir = join10(configRoot, "skills");
|
|
2989
|
+
const skillsDir = getSkillsRoot(tool, level, installPath);
|
|
3007
2990
|
return lastBatch.skills.filter((skillId) => {
|
|
3008
2991
|
const skillPath = join10(skillsDir, skillId);
|
|
3009
2992
|
return existsSync11(skillPath) || isSymlink(skillPath);
|
|
@@ -3186,7 +3169,7 @@ init_paths();
|
|
|
3186
3169
|
init_fs_helpers();
|
|
3187
3170
|
init_logger();
|
|
3188
3171
|
init_i18n();
|
|
3189
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync5, symlinkSync, realpathSync, readlinkSync, copyFileSync as copyFileSync2, cpSync, writeFileSync as writeFileSync2, rmSync as rmSync3 } from "fs";
|
|
3172
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync5, symlinkSync, realpathSync, readlinkSync, copyFileSync as copyFileSync2, cpSync, writeFileSync as writeFileSync2, rmSync as rmSync3, readFileSync as readFileSync8 } from "fs";
|
|
3190
3173
|
import { join as join12, basename } from "path";
|
|
3191
3174
|
import { execa as execa3 } from "execa";
|
|
3192
3175
|
function installLink(source, target) {
|
|
@@ -3375,7 +3358,7 @@ async function installViaManifest(plugin, repoPath, tool, level, installPath) {
|
|
|
3375
3358
|
const configRoot = getConfigRoot(tool, level, installPath);
|
|
3376
3359
|
const pluginDir = join12(repoPath, plugin.dir);
|
|
3377
3360
|
try {
|
|
3378
|
-
const skillsDir =
|
|
3361
|
+
const skillsDir = getSkillsRoot(tool, level, cwd);
|
|
3379
3362
|
const agentsDir = join12(configRoot, "agents");
|
|
3380
3363
|
mkdirSync5(skillsDir, { recursive: true });
|
|
3381
3364
|
mkdirSync5(agentsDir, { recursive: true });
|
|
@@ -3405,6 +3388,28 @@ async function installViaManifest(plugin, repoPath, tool, level, installPath) {
|
|
|
3405
3388
|
}
|
|
3406
3389
|
}
|
|
3407
3390
|
for (const agentName of plugin.installAgents || []) {
|
|
3391
|
+
if (tool === "codex") {
|
|
3392
|
+
const baseName = agentName.replace(/\.md$/, "");
|
|
3393
|
+
const tomlSource = join12(pluginDir, "agents", "codex", `${baseName}.toml`);
|
|
3394
|
+
if (!existsSync13(tomlSource)) {
|
|
3395
|
+
logger.warn(t("install_agent_codex_toml_missing").replace("{name}", baseName).replace("{path}", tomlSource));
|
|
3396
|
+
continue;
|
|
3397
|
+
}
|
|
3398
|
+
const canonicalMd = join12(pluginDir, "agents", `${baseName}.md`);
|
|
3399
|
+
const canonicalPath = existsSync13(canonicalMd) ? realpathSync(canonicalMd) : canonicalMd;
|
|
3400
|
+
const targetPath2 = join12(agentsDir, `${baseName}.toml`);
|
|
3401
|
+
try {
|
|
3402
|
+
const content = readFileSync8(tomlSource, "utf-8").split("__CANNBOT_AGENT_SOURCE__").join(canonicalPath);
|
|
3403
|
+
if (existsSync13(targetPath2) || isSymlink(targetPath2)) {
|
|
3404
|
+
removePath(targetPath2);
|
|
3405
|
+
}
|
|
3406
|
+
writeFileSync2(targetPath2, content, "utf-8");
|
|
3407
|
+
installedAgents.push(`${baseName}.toml`);
|
|
3408
|
+
} catch {
|
|
3409
|
+
logger.warn(t("install_agent_failed").replace("{name}", `${baseName}.toml`));
|
|
3410
|
+
}
|
|
3411
|
+
continue;
|
|
3412
|
+
}
|
|
3408
3413
|
const agentFile = agentName.endsWith(".md") ? agentName : `${agentName}.md`;
|
|
3409
3414
|
const agentPath = join12(pluginDir, "agents", agentFile);
|
|
3410
3415
|
if (!existsSync13(agentPath)) {
|
|
@@ -3464,6 +3469,14 @@ function findShell() {
|
|
|
3464
3469
|
}
|
|
3465
3470
|
return null;
|
|
3466
3471
|
}
|
|
3472
|
+
function scriptSupportsTool(scriptPath, tool) {
|
|
3473
|
+
try {
|
|
3474
|
+
const scriptContent = readFileSync9(scriptPath, "utf-8");
|
|
3475
|
+
return new RegExp(`\\b${tool}\\b`).test(scriptContent);
|
|
3476
|
+
} catch {
|
|
3477
|
+
return true;
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3467
3480
|
async function installPlugin(opts) {
|
|
3468
3481
|
const plugin = getPluginById(opts.pluginId);
|
|
3469
3482
|
if (!plugin) {
|
|
@@ -3587,6 +3600,16 @@ async function installPlugin(opts) {
|
|
|
3587
3600
|
warnings: []
|
|
3588
3601
|
};
|
|
3589
3602
|
}
|
|
3603
|
+
if (!scriptSupportsTool(scriptPath, opts.tool)) {
|
|
3604
|
+
return {
|
|
3605
|
+
success: false,
|
|
3606
|
+
pluginId: opts.pluginId,
|
|
3607
|
+
skillsCount: 0,
|
|
3608
|
+
agentsCount: 0,
|
|
3609
|
+
errors: [t("error_tool_not_supported").replace("{plugin}", plugin.displayName).replace("{tool}", opts.tool)],
|
|
3610
|
+
warnings: []
|
|
3611
|
+
};
|
|
3612
|
+
}
|
|
3590
3613
|
const args = [opts.level, opts.tool];
|
|
3591
3614
|
if (opts.installPath) {
|
|
3592
3615
|
args.push(opts.installPath);
|
|
@@ -3675,7 +3698,7 @@ init_constants();
|
|
|
3675
3698
|
init_logger();
|
|
3676
3699
|
init_i18n();
|
|
3677
3700
|
import { existsSync as existsSync15, mkdirSync as mkdirSync6, symlinkSync as symlinkSync2, readdirSync as readdirSync6, rmSync as rmSync4, realpathSync as realpathSync2, readlinkSync as readlinkSync2, cpSync as cpSync2 } from "fs";
|
|
3678
|
-
import { join as join14, dirname as dirname5, isAbsolute } from "path";
|
|
3701
|
+
import { join as join14, dirname as dirname5, basename as basename3, isAbsolute } from "path";
|
|
3679
3702
|
import { select as select3, checkbox, Separator as Separator2 } from "@inquirer/prompts";
|
|
3680
3703
|
import chalk5 from "chalk";
|
|
3681
3704
|
import Table from "cli-table3";
|
|
@@ -3683,7 +3706,7 @@ init_theme();
|
|
|
3683
3706
|
import { confirm } from "@inquirer/prompts";
|
|
3684
3707
|
async function installSkills(skillIds, tool, level, repoPath) {
|
|
3685
3708
|
const configRoot = getConfigRoot(tool, level);
|
|
3686
|
-
const skillsDir =
|
|
3709
|
+
const skillsDir = getSkillsRoot(tool, level);
|
|
3687
3710
|
const installPath = level === "project" ? process.cwd() : configRoot;
|
|
3688
3711
|
if (!existsSync15(skillsDir)) {
|
|
3689
3712
|
mkdirSync6(skillsDir, { recursive: true });
|
|
@@ -3749,7 +3772,7 @@ async function installSkills(skillIds, tool, level, repoPath) {
|
|
|
3749
3772
|
}
|
|
3750
3773
|
async function uninstallSkills(skillIds, tool, level) {
|
|
3751
3774
|
const configRoot = getConfigRoot(tool, level);
|
|
3752
|
-
const skillsDir =
|
|
3775
|
+
const skillsDir = getSkillsRoot(tool, level);
|
|
3753
3776
|
const installPath = level === "project" ? process.cwd() : configRoot;
|
|
3754
3777
|
const results = [];
|
|
3755
3778
|
const removedIds = [];
|
|
@@ -3778,6 +3801,16 @@ async function uninstallSkills(skillIds, tool, level) {
|
|
|
3778
3801
|
if (entries.length === 0) {
|
|
3779
3802
|
rmSync4(skillsDir, { recursive: true });
|
|
3780
3803
|
logger.step(` ${t("uninstall_clean_empty_dir")}: skills/`);
|
|
3804
|
+
if (tool === "codex") {
|
|
3805
|
+
const agentsRoot = dirname5(skillsDir);
|
|
3806
|
+
try {
|
|
3807
|
+
if (existsSync15(agentsRoot) && readdirSync6(agentsRoot).length === 0) {
|
|
3808
|
+
rmSync4(agentsRoot, { recursive: true });
|
|
3809
|
+
logger.step(` ${t("uninstall_clean_empty_dir")}: ${basename3(agentsRoot)}/`);
|
|
3810
|
+
}
|
|
3811
|
+
} catch {
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3781
3814
|
}
|
|
3782
3815
|
} catch {
|
|
3783
3816
|
}
|
|
@@ -4287,13 +4320,13 @@ init_config();
|
|
|
4287
4320
|
init_paths();
|
|
4288
4321
|
init_theme();
|
|
4289
4322
|
init_constants();
|
|
4290
|
-
import { existsSync as existsSync16, readFileSync as
|
|
4323
|
+
import { existsSync as existsSync16, readFileSync as readFileSync10 } from "fs";
|
|
4291
4324
|
import { join as join15 } from "path";
|
|
4292
4325
|
async function initCommand() {
|
|
4293
4326
|
const cwd = process.cwd();
|
|
4294
4327
|
if (existsSync16(join15(cwd, "package.json")) && (() => {
|
|
4295
4328
|
try {
|
|
4296
|
-
const pkg = JSON.parse(
|
|
4329
|
+
const pkg = JSON.parse(readFileSync10(join15(cwd, "package.json"), "utf-8"));
|
|
4297
4330
|
return pkg.name === "@cannbot-ai/install-helper";
|
|
4298
4331
|
} catch {
|
|
4299
4332
|
return false;
|
|
@@ -4502,11 +4535,10 @@ async function skillInstallFlow() {
|
|
|
4502
4535
|
failCount++;
|
|
4503
4536
|
}
|
|
4504
4537
|
}
|
|
4505
|
-
const configRoot = getConfigRoot(tool, level);
|
|
4506
4538
|
logger.blank();
|
|
4507
4539
|
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)))}`);
|
|
4508
4540
|
logger.blank();
|
|
4509
|
-
logger.info(`${t("install_to")}: ${chalk7.cyan(
|
|
4541
|
+
logger.info(`${t("install_to")}: ${chalk7.cyan(getSkillsRoot(tool, level))}`);
|
|
4510
4542
|
logger.info(`${t("start_to_use").replace("{tool}", chalk7.green(tool))}`);
|
|
4511
4543
|
logger.blank();
|
|
4512
4544
|
return "done";
|
|
@@ -4590,8 +4622,8 @@ async function doctorCommand(options = {}) {
|
|
|
4590
4622
|
const configRoot = getConfigRoot(primaryTool, "project");
|
|
4591
4623
|
configRootsToCheck.push({ configRoot, tool: primaryTool, level: "project" });
|
|
4592
4624
|
}
|
|
4593
|
-
for (const { configRoot } of configRootsToCheck) {
|
|
4594
|
-
const skillsDir =
|
|
4625
|
+
for (const { configRoot, tool, level } of configRootsToCheck) {
|
|
4626
|
+
const skillsDir = getSkillsRoot(tool, level);
|
|
4595
4627
|
const agentsDir = getAgentsDir(configRoot);
|
|
4596
4628
|
if (existsSync17(skillsDir)) {
|
|
4597
4629
|
const brokenLinks = checkBrokenLinks(skillsDir);
|
|
@@ -4742,7 +4774,6 @@ init_logger();
|
|
|
4742
4774
|
init_i18n();
|
|
4743
4775
|
init_config();
|
|
4744
4776
|
init_paths();
|
|
4745
|
-
import { join as join17 } from "path";
|
|
4746
4777
|
import { confirm as confirm2 } from "@inquirer/prompts";
|
|
4747
4778
|
import chalk10 from "chalk";
|
|
4748
4779
|
async function installCommand(names, options) {
|
|
@@ -4810,11 +4841,10 @@ async function installCommand(names, options) {
|
|
|
4810
4841
|
failCount++;
|
|
4811
4842
|
}
|
|
4812
4843
|
}
|
|
4813
|
-
const configRoot = getConfigRoot(tool2, level2);
|
|
4814
4844
|
logger.blank();
|
|
4815
4845
|
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)))}`);
|
|
4816
4846
|
logger.blank();
|
|
4817
|
-
logger.info(`${t("install_to")}: ${chalk10.cyan(
|
|
4847
|
+
logger.info(`${t("install_to")}: ${chalk10.cyan(getSkillsRoot(tool2, level2))}`);
|
|
4818
4848
|
logger.info(`${t("start_to_use").replace("{tool}", chalk10.green(tool2))}`);
|
|
4819
4849
|
logger.blank();
|
|
4820
4850
|
return;
|
|
@@ -4891,11 +4921,10 @@ async function installCommand(names, options) {
|
|
|
4891
4921
|
failCount++;
|
|
4892
4922
|
}
|
|
4893
4923
|
}
|
|
4894
|
-
const configRoot = getConfigRoot(tool2, level2);
|
|
4895
4924
|
logger.blank();
|
|
4896
4925
|
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)))}`);
|
|
4897
4926
|
logger.blank();
|
|
4898
|
-
logger.info(`${t("install_to")}: ${chalk10.cyan(
|
|
4927
|
+
logger.info(`${t("install_to")}: ${chalk10.cyan(getSkillsRoot(tool2, level2))}`);
|
|
4899
4928
|
logger.info(`${t("start_to_use").replace("{tool}", chalk10.green(tool2))}`);
|
|
4900
4929
|
logger.blank();
|
|
4901
4930
|
return;
|
|
@@ -5037,7 +5066,7 @@ async function installCommand(names, options) {
|
|
|
5037
5066
|
logger.blank();
|
|
5038
5067
|
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)))}`);
|
|
5039
5068
|
logger.blank();
|
|
5040
|
-
logger.info(`${t("install_to")}: ${chalk10.cyan(
|
|
5069
|
+
logger.info(`${t("install_to")}: ${chalk10.cyan(getSkillsRoot(tool, level))}`);
|
|
5041
5070
|
logger.info(`${t("start_to_use").replace("{tool}", chalk10.green(tool))}`);
|
|
5042
5071
|
logger.blank();
|
|
5043
5072
|
}
|
|
@@ -5073,8 +5102,8 @@ async function installPlugins(pluginIds, tool, level, repoPath, installPath, yes
|
|
|
5073
5102
|
|
|
5074
5103
|
// src/commands/uninstall.ts
|
|
5075
5104
|
init_registry();
|
|
5076
|
-
import { existsSync as existsSync18, unlinkSync as unlinkSync6, rmdirSync, readdirSync as readdirSync8, readFileSync as
|
|
5077
|
-
import { resolve, basename as
|
|
5105
|
+
import { existsSync as existsSync18, unlinkSync as unlinkSync6, rmdirSync, readdirSync as readdirSync8, readFileSync as readFileSync11 } from "fs";
|
|
5106
|
+
import { resolve, basename as basename4, sep as sep2, join as join17 } from "path";
|
|
5078
5107
|
import chalk11 from "chalk";
|
|
5079
5108
|
import { select as select5, checkbox as checkbox2, Separator as Separator4, confirm as confirm3 } from "@inquirer/prompts";
|
|
5080
5109
|
init_config();
|
|
@@ -5115,6 +5144,10 @@ async function uninstallCommand(names, options) {
|
|
|
5115
5144
|
skills.push(skill.id);
|
|
5116
5145
|
continue;
|
|
5117
5146
|
}
|
|
5147
|
+
if (readRecord(name)) {
|
|
5148
|
+
plugins.push(name);
|
|
5149
|
+
continue;
|
|
5150
|
+
}
|
|
5118
5151
|
logger.error(`${t("uninstall_not_found")}: ${name}`);
|
|
5119
5152
|
}
|
|
5120
5153
|
await uninstallPlugins(plugins, options.yes || false);
|
|
@@ -5197,7 +5230,7 @@ async function uninstallInteractive(defaultTool, defaultLevel, userSpecifiedTool
|
|
|
5197
5230
|
const allInstalledPlugins = scanInstalled();
|
|
5198
5231
|
const toolsWithPlugins = new Set(allInstalledPlugins.map((p) => `${p.tool}:${p.level}`));
|
|
5199
5232
|
const toolsWithSkills = /* @__PURE__ */ new Set();
|
|
5200
|
-
for (const toolName of
|
|
5233
|
+
for (const toolName of VALID_TOOLS) {
|
|
5201
5234
|
for (const lvl of ["project", "global"]) {
|
|
5202
5235
|
const ip = lvl === "project" ? process.cwd() : getConfigRoot(toolName, lvl);
|
|
5203
5236
|
const skills = getInstalledSkills(toolName, lvl, ip);
|
|
@@ -5353,18 +5386,33 @@ async function uninstallPlugins(pluginIds, batchMode) {
|
|
|
5353
5386
|
}
|
|
5354
5387
|
}
|
|
5355
5388
|
async function uninstallPluginById(pluginId, batchMode) {
|
|
5356
|
-
|
|
5389
|
+
let plugin = findPlugin(pluginId);
|
|
5390
|
+
if (!plugin) {
|
|
5391
|
+
const record2 = readRecord(pluginId);
|
|
5392
|
+
if (record2) {
|
|
5393
|
+
plugin = {
|
|
5394
|
+
id: pluginId,
|
|
5395
|
+
dir: "",
|
|
5396
|
+
displayName: record2.displayName,
|
|
5397
|
+
script: "init.sh",
|
|
5398
|
+
aliases: [],
|
|
5399
|
+
skills: 0,
|
|
5400
|
+
agents: 0,
|
|
5401
|
+
description: ""
|
|
5402
|
+
};
|
|
5403
|
+
}
|
|
5404
|
+
}
|
|
5357
5405
|
if (!plugin) return;
|
|
5358
5406
|
let record = readRecord(plugin.id);
|
|
5359
5407
|
if (!record) {
|
|
5360
5408
|
for (const toolName of VALID_TOOLS) {
|
|
5361
5409
|
for (const lvl of ["project", "global"]) {
|
|
5362
5410
|
const configRoot2 = getConfigRoot(toolName, lvl);
|
|
5363
|
-
const manifestPath =
|
|
5411
|
+
const manifestPath = join17(configRoot2, `${pluginId}-manifest.json`);
|
|
5364
5412
|
if (!existsSync18(manifestPath)) continue;
|
|
5365
5413
|
let manifest = null;
|
|
5366
5414
|
try {
|
|
5367
|
-
manifest = JSON.parse(
|
|
5415
|
+
manifest = JSON.parse(readFileSync11(manifestPath, "utf-8"));
|
|
5368
5416
|
} catch {
|
|
5369
5417
|
continue;
|
|
5370
5418
|
}
|
|
@@ -5377,7 +5425,7 @@ async function uninstallPluginById(pluginId, batchMode) {
|
|
|
5377
5425
|
installPath,
|
|
5378
5426
|
configRoot2,
|
|
5379
5427
|
manifest,
|
|
5380
|
-
plugin.externalRepos?.map((r) =>
|
|
5428
|
+
plugin.externalRepos?.map((r) => basename4(r.dir)),
|
|
5381
5429
|
plugin.configRootConfigLink
|
|
5382
5430
|
);
|
|
5383
5431
|
break;
|
|
@@ -5393,6 +5441,9 @@ async function uninstallPluginById(pluginId, batchMode) {
|
|
|
5393
5441
|
logger.info(`${t("uninstall_in_progress")} ${plugin.displayName}...`);
|
|
5394
5442
|
const configRoot = getConfigRoot(record.tool, record.level);
|
|
5395
5443
|
const allowedBases = [resolve(configRoot), resolve(record.installPath)];
|
|
5444
|
+
if (record.tool === "codex") {
|
|
5445
|
+
allowedBases.push(resolve(getSkillsRoot(record.tool, record.level, record.installPath)));
|
|
5446
|
+
}
|
|
5396
5447
|
const isSafePath = (p) => {
|
|
5397
5448
|
const resolved = resolve(p);
|
|
5398
5449
|
return allowedBases.some((base) => resolved === base || resolved.startsWith(base + sep2));
|
|
@@ -5400,8 +5451,8 @@ async function uninstallPluginById(pluginId, batchMode) {
|
|
|
5400
5451
|
let removedFiles = 0;
|
|
5401
5452
|
let removedDirs = 0;
|
|
5402
5453
|
const configFileName = record.tool === "claude" ? "CLAUDE.md" : "AGENTS.md";
|
|
5403
|
-
const configRootConfigPath =
|
|
5404
|
-
const installPathConfigPath =
|
|
5454
|
+
const configRootConfigPath = join17(configRoot, configFileName);
|
|
5455
|
+
const installPathConfigPath = join17(record.installPath, configFileName);
|
|
5405
5456
|
const extraFiles = [];
|
|
5406
5457
|
if (record.level === "project" && configRootConfigPath !== installPathConfigPath && !record.files.includes(configRootConfigPath) && (existsSync18(configRootConfigPath) || isSymlink(configRootConfigPath))) {
|
|
5407
5458
|
extraFiles.push(configRootConfigPath);
|
|
@@ -5412,7 +5463,7 @@ async function uninstallPluginById(pluginId, batchMode) {
|
|
|
5412
5463
|
try {
|
|
5413
5464
|
if (existsSync18(filePath) || isSymlink(filePath)) {
|
|
5414
5465
|
unlinkSync6(filePath);
|
|
5415
|
-
const name =
|
|
5466
|
+
const name = basename4(filePath);
|
|
5416
5467
|
logger.step(` ${t("uninstall_remove_label")}: ${name}`);
|
|
5417
5468
|
removedFiles++;
|
|
5418
5469
|
}
|
|
@@ -5429,7 +5480,7 @@ async function uninstallPluginById(pluginId, batchMode) {
|
|
|
5429
5480
|
const entries = readdirSync8(dirPath);
|
|
5430
5481
|
if (entries.length === 0) {
|
|
5431
5482
|
rmdirSync(dirPath);
|
|
5432
|
-
const name =
|
|
5483
|
+
const name = basename4(dirPath);
|
|
5433
5484
|
logger.step(` ${t("uninstall_clean_empty_dir")}: ${name}/`);
|
|
5434
5485
|
removedDirs++;
|
|
5435
5486
|
}
|
|
@@ -5437,6 +5488,17 @@ async function uninstallPluginById(pluginId, batchMode) {
|
|
|
5437
5488
|
} catch {
|
|
5438
5489
|
}
|
|
5439
5490
|
}
|
|
5491
|
+
if (record.tool === "codex") {
|
|
5492
|
+
try {
|
|
5493
|
+
const agentsRoot = resolve(getSkillsRoot(record.tool, record.level, record.installPath), "..");
|
|
5494
|
+
if (existsSync18(agentsRoot) && readdirSync8(agentsRoot).length === 0) {
|
|
5495
|
+
rmdirSync(agentsRoot);
|
|
5496
|
+
logger.step(` ${t("uninstall_clean_empty_dir")}: ${basename4(agentsRoot)}/`);
|
|
5497
|
+
removedDirs++;
|
|
5498
|
+
}
|
|
5499
|
+
} catch {
|
|
5500
|
+
}
|
|
5501
|
+
}
|
|
5440
5502
|
deleteRecord(plugin.id);
|
|
5441
5503
|
removeInstalledPlugin(plugin.id);
|
|
5442
5504
|
const backups = findBackups(configRoot);
|
|
@@ -5588,7 +5650,7 @@ async function updateCommand(pluginNames, options) {
|
|
|
5588
5650
|
init_registry();
|
|
5589
5651
|
import chalk13 from "chalk";
|
|
5590
5652
|
import { existsSync as existsSync19, readdirSync as readdirSync9 } from "fs";
|
|
5591
|
-
import { join as
|
|
5653
|
+
import { join as join18 } from "path";
|
|
5592
5654
|
init_manifest();
|
|
5593
5655
|
init_i18n();
|
|
5594
5656
|
async function infoCommand(pluginName) {
|
|
@@ -5615,11 +5677,11 @@ async function infoCommand(pluginName) {
|
|
|
5615
5677
|
try {
|
|
5616
5678
|
const repoManager = createRepositoryManager();
|
|
5617
5679
|
const repoPath = await repoManager.ensureRepo();
|
|
5618
|
-
const quickstartPath =
|
|
5680
|
+
const quickstartPath = join18(repoPath, plugin.dir, "quickstart.md");
|
|
5619
5681
|
if (existsSync19(quickstartPath)) {
|
|
5620
5682
|
console.log(` ${chalk13.dim(t("info_quickstart") + ":")} ${quickstartPath}`);
|
|
5621
5683
|
}
|
|
5622
|
-
const agentsDir =
|
|
5684
|
+
const agentsDir = join18(repoPath, plugin.dir, "agents");
|
|
5623
5685
|
if (existsSync19(agentsDir)) {
|
|
5624
5686
|
const agentFiles = readdirSync9(agentsDir).filter((f) => f.endsWith(".md"));
|
|
5625
5687
|
if (agentFiles.length > 0) {
|
|
@@ -5676,9 +5738,9 @@ async function langCommand(action, value) {
|
|
|
5676
5738
|
// src/cli.ts
|
|
5677
5739
|
init_config();
|
|
5678
5740
|
init_i18n();
|
|
5679
|
-
import { readFileSync as
|
|
5741
|
+
import { readFileSync as readFileSync12, existsSync as existsSync20 } from "fs";
|
|
5680
5742
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
5681
|
-
import { dirname as dirname6, join as
|
|
5743
|
+
import { dirname as dirname6, join as join19 } from "path";
|
|
5682
5744
|
function readVersion() {
|
|
5683
5745
|
try {
|
|
5684
5746
|
if (typeof INSTALL_HELPER_VERSION !== "undefined" && INSTALL_HELPER_VERSION) {
|
|
@@ -5690,13 +5752,13 @@ function readVersion() {
|
|
|
5690
5752
|
const __filename4 = fileURLToPath4(import.meta.url);
|
|
5691
5753
|
const __dirname4 = dirname6(__filename4);
|
|
5692
5754
|
const candidates = [
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5755
|
+
join19(__dirname4, "..", "package.json"),
|
|
5756
|
+
join19(__dirname4, "package.json"),
|
|
5757
|
+
join19(process.cwd(), "package.json")
|
|
5696
5758
|
];
|
|
5697
5759
|
for (const pkgPath of candidates) {
|
|
5698
5760
|
if (existsSync20(pkgPath)) {
|
|
5699
|
-
const pkg = JSON.parse(
|
|
5761
|
+
const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
|
|
5700
5762
|
if (pkg.version && (pkg.name === "@cannbot-ai/install-helper" || pkg.name?.startsWith("@cannbot-ai/install-helper-"))) {
|
|
5701
5763
|
return pkg.version;
|
|
5702
5764
|
}
|
|
@@ -5726,13 +5788,13 @@ function createCLI() {
|
|
|
5726
5788
|
program2.command("status").description("Show installed plugins").action(async () => {
|
|
5727
5789
|
await statusCommand();
|
|
5728
5790
|
});
|
|
5729
|
-
program2.command("install [names...]").description("Install plugins or skills (auto-detects type)").option("-t, --tool <tool>", "AI tool (opencode, claude, trae, cursor, copilot, codearts)").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) => {
|
|
5791
|
+
program2.command("install [names...]").description("Install plugins or skills (auto-detects type)").option("-t, --tool <tool>", "AI tool (opencode, claude, trae, cursor, codex, copilot, codearts)").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) => {
|
|
5730
5792
|
await installCommand(names, options);
|
|
5731
5793
|
});
|
|
5732
|
-
program2.command("uninstall [names...]").description("Uninstall plugins or skills (auto-detects type)").option("-t, --tool <tool>", "AI tool (opencode, claude, trae, cursor, copilot, codearts)").option("-l, --level <level>", "Install level (project, global)", "project").option("-y, --yes", "Skip confirmation prompts").option("-a, --all", "Uninstall ALL installed skills and plugins").option("--recent", "Uninstall the most recently installed skill batch").action(async (names, options) => {
|
|
5794
|
+
program2.command("uninstall [names...]").description("Uninstall plugins or skills (auto-detects type)").option("-t, --tool <tool>", "AI tool (opencode, claude, trae, cursor, codex, copilot, codearts)").option("-l, --level <level>", "Install level (project, global)", "project").option("-y, --yes", "Skip confirmation prompts").option("-a, --all", "Uninstall ALL installed skills and plugins").option("--recent", "Uninstall the most recently installed skill batch").action(async (names, options) => {
|
|
5733
5795
|
await uninstallCommand(names, options);
|
|
5734
5796
|
});
|
|
5735
|
-
program2.command("update [plugins...]").description("Update installed plugins (git pull + reinstall)").option("-t, --tool <tool>", "AI tool (opencode, claude, trae, cursor, copilot, codearts)").option("-l, --level <level>", "Install level (project, global)").option("-y, --yes", "Skip confirmation prompts").action(async (plugins, options) => {
|
|
5797
|
+
program2.command("update [plugins...]").description("Update installed plugins (git pull + reinstall)").option("-t, --tool <tool>", "AI tool (opencode, claude, trae, cursor, codex, copilot, codearts)").option("-l, --level <level>", "Install level (project, global)").option("-y, --yes", "Skip confirmation prompts").action(async (plugins, options) => {
|
|
5736
5798
|
await updateCommand(plugins, options);
|
|
5737
5799
|
});
|
|
5738
5800
|
program2.command("info <plugin>").description("Show plugin details").action(async (plugin) => {
|