@cannbot-ai/install-helper 0.0.2-beta.31 → 0.0.2-beta.33
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/dist/index.js +34 -13
- package/dist/index.js.map +1 -1
- package/dist/locales/en_US.json +2 -2
- package/dist/locales/zh_CN.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1027,8 +1027,12 @@ function parseFrontmatter(filePath) {
|
|
|
1027
1027
|
const parsed = parseYaml2(yamlBlock);
|
|
1028
1028
|
if (!parsed || typeof parsed !== "object") return null;
|
|
1029
1029
|
if (!parsed.name || typeof parsed.name !== "string") return null;
|
|
1030
|
+
const trimmedName = parsed.name.trim();
|
|
1031
|
+
if (!trimmedName || /[\/\\]|\.\./.test(trimmedName) || !/^[a-zA-Z0-9._-]+$/.test(trimmedName)) {
|
|
1032
|
+
return null;
|
|
1033
|
+
}
|
|
1030
1034
|
return {
|
|
1031
|
-
name:
|
|
1035
|
+
name: trimmedName,
|
|
1032
1036
|
description: (parsed.description || "").trim()
|
|
1033
1037
|
};
|
|
1034
1038
|
} catch {
|
|
@@ -1887,9 +1891,18 @@ async function installPlugin(opts) {
|
|
|
1887
1891
|
currentPlugin.pluginId,
|
|
1888
1892
|
currentPlugin.pluginName
|
|
1889
1893
|
);
|
|
1890
|
-
if (backupInfo) {
|
|
1891
|
-
logger.
|
|
1894
|
+
if (!backupInfo) {
|
|
1895
|
+
logger.error(t("backup_failed"));
|
|
1896
|
+
return {
|
|
1897
|
+
success: false,
|
|
1898
|
+
pluginId: opts.pluginId,
|
|
1899
|
+
skillsCount: 0,
|
|
1900
|
+
agentsCount: 0,
|
|
1901
|
+
errors: [t("backup_failed")],
|
|
1902
|
+
warnings: []
|
|
1903
|
+
};
|
|
1892
1904
|
}
|
|
1905
|
+
logger.success(`${t("backup_created")}: ${backupInfo.filePath}`);
|
|
1893
1906
|
}
|
|
1894
1907
|
}
|
|
1895
1908
|
try {
|
|
@@ -1980,10 +1993,11 @@ async function installSkills(skillIds, tool, level, repoPath) {
|
|
|
1980
1993
|
continue;
|
|
1981
1994
|
}
|
|
1982
1995
|
try {
|
|
1996
|
+
const resolvedSource = realpathSync(sourcePath);
|
|
1983
1997
|
if (existsSync11(targetPath) || isSymlink2(targetPath)) {
|
|
1984
1998
|
unlinkSync3(targetPath);
|
|
1985
1999
|
}
|
|
1986
|
-
symlinkSync(
|
|
2000
|
+
symlinkSync(resolvedSource, targetPath);
|
|
1987
2001
|
results.push({ skillId, success: true });
|
|
1988
2002
|
installedIds.push(skillId);
|
|
1989
2003
|
} catch (error) {
|
|
@@ -2229,10 +2243,11 @@ function printPluginList(plugins, installed) {
|
|
|
2229
2243
|
chalk6.cyan(t("list_id")),
|
|
2230
2244
|
chalk6.cyan(t("list_name")),
|
|
2231
2245
|
chalk6.cyan(t("list_status")),
|
|
2232
|
-
chalk6.cyan(t("
|
|
2233
|
-
chalk6.cyan(t("list_agents"))
|
|
2246
|
+
chalk6.cyan(t("list_description"))
|
|
2234
2247
|
],
|
|
2235
|
-
style: { head: [], border: [] }
|
|
2248
|
+
style: { head: [], border: [] },
|
|
2249
|
+
colWidths: [6, 32, 8, 50],
|
|
2250
|
+
wordWrap: true
|
|
2236
2251
|
});
|
|
2237
2252
|
plugins.forEach((plugin, index) => {
|
|
2238
2253
|
const isInstalled = installed.has(plugin.id);
|
|
@@ -2241,8 +2256,7 @@ function printPluginList(plugins, installed) {
|
|
|
2241
2256
|
String(index + 1),
|
|
2242
2257
|
plugin.displayName,
|
|
2243
2258
|
status,
|
|
2244
|
-
|
|
2245
|
-
String(plugin.agents)
|
|
2259
|
+
plugin.description || chalk6.dim("\u2014")
|
|
2246
2260
|
]);
|
|
2247
2261
|
});
|
|
2248
2262
|
console.log();
|
|
@@ -3016,6 +3030,7 @@ async function installPlugins(pluginIds, tool, level, repoPath, installPath, yes
|
|
|
3016
3030
|
|
|
3017
3031
|
// src/commands/uninstall.ts
|
|
3018
3032
|
import { existsSync as existsSync14, unlinkSync as unlinkSync5, rmdirSync as rmdirSync2, readdirSync as readdirSync6, lstatSync as lstatSync4 } from "fs";
|
|
3033
|
+
import { resolve } from "path";
|
|
3019
3034
|
import chalk11 from "chalk";
|
|
3020
3035
|
async function uninstallCommand(names, options) {
|
|
3021
3036
|
const tool = options.tool ? validateTool(options.tool) : "opencode";
|
|
@@ -3045,9 +3060,16 @@ async function uninstallCommand(names, options) {
|
|
|
3045
3060
|
continue;
|
|
3046
3061
|
}
|
|
3047
3062
|
logger.info(`${t("uninstall_in_progress")} ${plugin.displayName}...`);
|
|
3063
|
+
const configRoot = getConfigRoot(record.tool, record.level);
|
|
3064
|
+
const allowedBases = [resolve(configRoot), resolve(record.installPath)];
|
|
3065
|
+
const isSafePath = (p) => {
|
|
3066
|
+
const resolved = resolve(p);
|
|
3067
|
+
return allowedBases.some((base) => resolved === base || resolved.startsWith(base + "/"));
|
|
3068
|
+
};
|
|
3048
3069
|
let removedFiles = 0;
|
|
3049
3070
|
let removedDirs = 0;
|
|
3050
3071
|
for (const filePath of record.files) {
|
|
3072
|
+
if (!isSafePath(filePath)) continue;
|
|
3051
3073
|
try {
|
|
3052
3074
|
if (existsSync14(filePath) || isSymlink3(filePath)) {
|
|
3053
3075
|
unlinkSync5(filePath);
|
|
@@ -3058,11 +3080,10 @@ async function uninstallCommand(names, options) {
|
|
|
3058
3080
|
} catch {
|
|
3059
3081
|
}
|
|
3060
3082
|
}
|
|
3061
|
-
const
|
|
3062
|
-
const sortedDirs = [...record.directories].sort((a, b) => b.length - a.length);
|
|
3083
|
+
const sortedDirs = [...record.directories].filter(isSafePath).sort((a, b) => b.length - a.length);
|
|
3063
3084
|
for (const dirPath of sortedDirs) {
|
|
3064
3085
|
try {
|
|
3065
|
-
if (dirPath === configRoot) {
|
|
3086
|
+
if (resolve(dirPath) === resolve(configRoot)) {
|
|
3066
3087
|
continue;
|
|
3067
3088
|
}
|
|
3068
3089
|
if (existsSync14(dirPath)) {
|
|
@@ -3298,7 +3319,7 @@ function createCLI() {
|
|
|
3298
3319
|
setLanguage(config.language);
|
|
3299
3320
|
}
|
|
3300
3321
|
const program2 = new Command();
|
|
3301
|
-
program2.name("install-helper").description("CANNBot Install Helper - Interactive installer for CANN operator development skills").version("0.0.2-beta.
|
|
3322
|
+
program2.name("install-helper").description("CANNBot Install Helper - Interactive installer for CANN operator development skills").version("0.0.2-beta.33");
|
|
3302
3323
|
program2.command("init", { isDefault: false }).description("Run interactive installation wizard").action(async () => {
|
|
3303
3324
|
await initCommand();
|
|
3304
3325
|
});
|