@michengai/dsh-skills-manager 0.1.16 → 0.1.17
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/lib/client.js +16 -0
- package/lib/core.js +12 -6
- package/lib/index.js +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -55,6 +55,8 @@ window.__ModuleLoader__.load({
|
|
|
55
55
|
"result.done": "上传完成:{names}",
|
|
56
56
|
"result.skipped": "未导入:同名插件已跳过:{names}",
|
|
57
57
|
"result.none": "未导入任何插件。",
|
|
58
|
+
"result.warnings": "警告:{warnings}",
|
|
59
|
+
"warning.backupUncleaned": "旧版本备份未清理: {path}({error})",
|
|
58
60
|
"upload.title": "上传插件",
|
|
59
61
|
"upload.close": "关闭上传弹窗",
|
|
60
62
|
"upload.drop.title": "拖放 SKILL.md 文件到这里",
|
|
@@ -83,7 +85,9 @@ window.__ModuleLoader__.load({
|
|
|
83
85
|
"error.import.invalidName": "无法生成合法 kebab-case 名称(原始名: {name})",
|
|
84
86
|
"error.import.duplicateName": "批量来源中存在多个同名插件: {name}",
|
|
85
87
|
"error.import.failed": "导入失败",
|
|
88
|
+
"error.import.rollbackFailed": "覆盖导入回滚失败,备份保留在: {path}({error})",
|
|
86
89
|
"error.proto.forbidden": "禁止的修改请求(缺少客户端标记)",
|
|
90
|
+
"error.proto.forbiddenHost": "禁止的请求来源(非法 Host)",
|
|
87
91
|
"error.proto.contentType": "请求体必须是 application/json",
|
|
88
92
|
"error.proto.method": "不支持的请求方法",
|
|
89
93
|
"error.proto.unknownAction": "未知操作",
|
|
@@ -138,6 +142,8 @@ window.__ModuleLoader__.load({
|
|
|
138
142
|
"result.done": "Upload complete: {names}",
|
|
139
143
|
"result.skipped": "Not imported: same-name plugins were skipped: {names}",
|
|
140
144
|
"result.none": "Nothing was imported.",
|
|
145
|
+
"result.warnings": "Warning: {warnings}",
|
|
146
|
+
"warning.backupUncleaned": "Old version backup was not cleaned up: {path} ({error})",
|
|
141
147
|
"upload.title": "Upload plugin",
|
|
142
148
|
"upload.close": "Close upload dialog",
|
|
143
149
|
"upload.drop.title": "Drop SKILL.md file here",
|
|
@@ -166,7 +172,9 @@ window.__ModuleLoader__.load({
|
|
|
166
172
|
"error.import.invalidName": "Cannot generate a valid kebab-case name (original name: {name})",
|
|
167
173
|
"error.import.duplicateName": "Batch source contains multiple plugins with the same name: {name}",
|
|
168
174
|
"error.import.failed": "Import failed",
|
|
175
|
+
"error.import.rollbackFailed": "Overwrite import rollback failed; backups kept at: {path} ({error})",
|
|
169
176
|
"error.proto.forbidden": "Forbidden mutation request (missing client marker)",
|
|
177
|
+
"error.proto.forbiddenHost": "Forbidden request origin (invalid host)",
|
|
170
178
|
"error.proto.contentType": "Content type must be application/json",
|
|
171
179
|
"error.proto.method": "Method not allowed",
|
|
172
180
|
"error.proto.unknownAction": "Unknown action",
|
|
@@ -457,6 +465,13 @@ window.__ModuleLoader__.load({
|
|
|
457
465
|
var failedItems = importResult.failed || (importResult.error && importResult.error.failed) || [];
|
|
458
466
|
var skippedNames = (importResult.skipped || []).map(function (item) { return item.name; });
|
|
459
467
|
var failedText = failedItems.map(function (item) { return translateError(t, item); }).join(errorSeparator);
|
|
468
|
+
var warningItems = [];
|
|
469
|
+
(importResult.imported || []).forEach(function (item) {
|
|
470
|
+
if (item.warnings && item.warnings.length) {
|
|
471
|
+
for (var i = 0; i < item.warnings.length; i++) warningItems.push(item.warnings[i]);
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
var warningText = warningItems.map(function (item) { return translateError(t, item); }).join(errorSeparator);
|
|
460
475
|
var resultText;
|
|
461
476
|
if (isImportError) {
|
|
462
477
|
// 顶层聚合错误优先展示已翻译的失败明细;无明细时由 translateError 兜底(含 Error 对象)。
|
|
@@ -470,6 +485,7 @@ window.__ModuleLoader__.load({
|
|
|
470
485
|
} else {
|
|
471
486
|
resultText = t("result.none");
|
|
472
487
|
}
|
|
488
|
+
if (warningText) resultText = resultText + errorSeparator + t("result.warnings", { warnings: warningText });
|
|
473
489
|
nodes.push(h("div", { key: "import-result", className: isImportError || failedItems.length ? "dssm-error" : "dssm-note", role: "status" }, resultText));
|
|
474
490
|
}
|
|
475
491
|
if (uploadOpen) {
|
package/lib/core.js
CHANGED
|
@@ -426,14 +426,16 @@ async function replaceWithCopy(source, dest, isDir, existing = []) {
|
|
|
426
426
|
try {
|
|
427
427
|
await fs.rename(item.backup, item.path);
|
|
428
428
|
} catch (rollbackError) {
|
|
429
|
-
rollbackFailures.push(
|
|
429
|
+
rollbackFailures.push(item.backup);
|
|
430
430
|
}
|
|
431
431
|
}
|
|
432
432
|
if (rollbackFailures.length) {
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
433
|
+
const causeText = String(error && error.message ? error.message : error);
|
|
434
|
+
throw codedError(
|
|
435
|
+
`${causeText};覆盖导入回滚失败,备份保留在: ${rollbackFailures.join("、")}`,
|
|
436
|
+
"error.import.rollbackFailed",
|
|
437
|
+
{ path: rollbackFailures.join("; "), error: causeText },
|
|
438
|
+
);
|
|
437
439
|
}
|
|
438
440
|
throw error;
|
|
439
441
|
}
|
|
@@ -442,7 +444,11 @@ async function replaceWithCopy(source, dest, isDir, existing = []) {
|
|
|
442
444
|
try {
|
|
443
445
|
await fs.rm(item.backup, { recursive: true, force: true });
|
|
444
446
|
} catch (error) {
|
|
445
|
-
warnings.push(
|
|
447
|
+
warnings.push({
|
|
448
|
+
code: "warning.backupUncleaned",
|
|
449
|
+
params: { path: item.backup, error: String(error && error.message ? error.message : error) },
|
|
450
|
+
error: `旧版本备份未清理: ${item.backup}(${String(error && error.message ? error.message : error)})`,
|
|
451
|
+
});
|
|
446
452
|
}
|
|
447
453
|
}
|
|
448
454
|
return warnings;
|
package/lib/index.js
CHANGED
|
@@ -76,7 +76,7 @@ function readBody(req, limit = 1 << 20) {
|
|
|
76
76
|
/** 只允许 loopback Host,避免 DNS rebinding 读取 /state 或改写本地技能。 */
|
|
77
77
|
function validateLoopbackHost(req) {
|
|
78
78
|
const host = String(req.headers.host || "").toLowerCase();
|
|
79
|
-
if (!/^(localhost|127\.0\.0\.1|\[::1\])(:\d+)?$/.test(host)) return { statusCode: 403, code: "error.proto.
|
|
79
|
+
if (!/^(localhost|127\.0\.0\.1|\[::1\])(:\d+)?$/.test(host)) return { statusCode: 403, code: "error.proto.forbiddenHost", error: "forbidden host" };
|
|
80
80
|
return null;
|
|
81
81
|
}
|
|
82
82
|
|
package/package.json
CHANGED