@dreamlogic-ai/cli 2.0.4 → 2.0.5
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/commands/update.js +7 -1
- package/dist/lib/agents.js +5 -0
- package/dist/lib/config.js +3 -2
- package/dist/lib/installer.js +14 -2
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/package.json +1 -1
package/dist/commands/update.js
CHANGED
|
@@ -47,9 +47,15 @@ export async function updateCommand(opts) {
|
|
|
47
47
|
continue;
|
|
48
48
|
}
|
|
49
49
|
const normalizeVer = (v) => v.replace(/^v/, "");
|
|
50
|
-
|
|
50
|
+
const localVer = normalizeVer(local.version);
|
|
51
|
+
const remoteVer = normalizeVer(remote.latest_version);
|
|
52
|
+
if (localVer === remoteVer) {
|
|
51
53
|
ui.line(`${chalk.green("✓")} ${remote.name} ${local.version} — 已是最新`);
|
|
52
54
|
}
|
|
55
|
+
else if (remoteVer < localVer) {
|
|
56
|
+
// R4-C02 FIX: Block version downgrade attacks
|
|
57
|
+
ui.line(`${ui.warn("⚠")} ${remote.name} — 服务器版本 ${remote.latest_version} 低于本地 ${local.version}(可能的降级攻击,已跳过)`);
|
|
58
|
+
}
|
|
53
59
|
else {
|
|
54
60
|
ui.line(`${chalk.yellow("⬆")} ${chalk.bold(remote.name)} ${local.version} → ${chalk.green(remote.latest_version)}`);
|
|
55
61
|
updates.push({
|
package/dist/lib/agents.js
CHANGED
|
@@ -90,6 +90,11 @@ export function registerSkillWithAgents(skillId, skillPath, agents) {
|
|
|
90
90
|
return [{ agent: "all", path: "", status: "error", error: "Invalid skill ID" }];
|
|
91
91
|
}
|
|
92
92
|
const resolvedSkillPath = resolve(skillPath);
|
|
93
|
+
// R4-H02 FIX: Validate skillPath is within user home directory
|
|
94
|
+
const home = homedir();
|
|
95
|
+
if (!resolvedSkillPath.startsWith(resolve(home))) {
|
|
96
|
+
return [{ agent: "all", path: "", status: "error", error: "Skill path must be within home directory" }];
|
|
97
|
+
}
|
|
93
98
|
// Deduplicate by resolved dir (universal agents share .agents/skills)
|
|
94
99
|
const seenDirs = new Set();
|
|
95
100
|
for (const agent of agents) {
|
package/dist/lib/config.js
CHANGED
|
@@ -78,8 +78,9 @@ export function getApiKey() {
|
|
|
78
78
|
/** R1-07: Enforce HTTPS (localhost/127.0.0.1 exempt for dev) */
|
|
79
79
|
export function getServer() {
|
|
80
80
|
const url = process.env.DREAMLOGIC_SERVER || loadConfig()?.server || DEFAULT_SERVER;
|
|
81
|
-
// R1-07 + R2-03: HTTPS enforcement (localhost/127.
|
|
82
|
-
|
|
81
|
+
// R1-07 + R2-03 + R4-H06: HTTPS enforcement (localhost/127.x.x.x/[::1] exempt)
|
|
82
|
+
const LOCALHOST_RE = /^http:\/\/(localhost|127(?:\.\d{1,3}){3}|\[::1\]|0\.0\.0\.0)(:[0-9]+)?(\/|$)/i;
|
|
83
|
+
if (!/^https:\/\//i.test(url) && !LOCALHOST_RE.test(url)) {
|
|
83
84
|
throw new Error("Server URL must use HTTPS (http://localhost allowed for dev)");
|
|
84
85
|
}
|
|
85
86
|
return url;
|
package/dist/lib/installer.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* R1-03: Zip bomb protection (total size + entry count limits)
|
|
7
7
|
* R1-10: SIGINT/SIGTERM cleanup handler
|
|
8
8
|
*/
|
|
9
|
-
import { createWriteStream, existsSync, mkdirSync, readdirSync, renameSync, rmSync, statSync } from "fs";
|
|
9
|
+
import { createWriteStream, existsSync, lstatSync, mkdirSync, readdirSync, renameSync, rmSync, statSync, unlinkSync } from "fs";
|
|
10
10
|
import { join, normalize, resolve as pathResolve, sep } from "path";
|
|
11
11
|
import { Transform as TransformStream } from "stream";
|
|
12
12
|
import yauzl from "yauzl";
|
|
@@ -309,7 +309,19 @@ function extractZip(buffer, targetDir) {
|
|
|
309
309
|
});
|
|
310
310
|
const writeStream = createWriteStream(fullPath);
|
|
311
311
|
readStream.pipe(countingStream).pipe(writeStream);
|
|
312
|
-
writeStream.on("finish", () =>
|
|
312
|
+
writeStream.on("finish", () => {
|
|
313
|
+
// R4-C01 FIX: Post-write symlink verification (defense-in-depth)
|
|
314
|
+
try {
|
|
315
|
+
if (lstatSync(fullPath).isSymbolicLink()) {
|
|
316
|
+
unlinkSync(fullPath);
|
|
317
|
+
zipfile.close();
|
|
318
|
+
reject(new Error(`Post-extract symlink detected: ${entry.fileName}`));
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
catch { /* stat failed = file doesn't exist, ok to continue */ }
|
|
323
|
+
zipfile.readEntry();
|
|
324
|
+
});
|
|
313
325
|
writeStream.on("error", (e) => { zipfile.close(); reject(e); });
|
|
314
326
|
countingStream.on("error", (e) => { zipfile.close(); reject(e); });
|
|
315
327
|
readStream.on("error", (e) => { zipfile.close(); reject(e); });
|
package/dist/types.d.ts
CHANGED
|
@@ -33,6 +33,6 @@ export interface InstalledRegistry {
|
|
|
33
33
|
export declare const DEFAULT_SERVER = "https://skill.dreamlogic-claw.com";
|
|
34
34
|
export declare const DEFAULT_INSTALL_DIR_NAME = "dreamlogic-skills";
|
|
35
35
|
export declare const CONFIG_DIR_NAME = ".dreamlogic";
|
|
36
|
-
export declare const CLI_VERSION = "2.0.
|
|
36
|
+
export declare const CLI_VERSION = "2.0.5";
|
|
37
37
|
export declare const CLI_NAME = "Dreamlogic CLI";
|
|
38
38
|
export declare const CLI_AUTHOR = "Dreamlogic-ai by MAJORNINE";
|
package/dist/types.js
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
export const DEFAULT_SERVER = "https://skill.dreamlogic-claw.com";
|
|
3
3
|
export const DEFAULT_INSTALL_DIR_NAME = "dreamlogic-skills";
|
|
4
4
|
export const CONFIG_DIR_NAME = ".dreamlogic";
|
|
5
|
-
export const CLI_VERSION = "2.0.
|
|
5
|
+
export const CLI_VERSION = "2.0.5";
|
|
6
6
|
export const CLI_NAME = "Dreamlogic CLI";
|
|
7
7
|
export const CLI_AUTHOR = "Dreamlogic-ai by MAJORNINE";
|