@dreamlogic-ai/cli 2.0.4 → 2.0.6
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/install.js +20 -0
- package/dist/commands/setup-mcp.js +4 -1
- package/dist/commands/update.js +7 -1
- package/dist/index.js +43 -6
- package/dist/lib/agents.js +5 -0
- package/dist/lib/api-client.d.ts +2 -0
- package/dist/lib/api-client.js +5 -1
- package/dist/lib/config.js +24 -11
- package/dist/lib/installer.js +45 -2
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -1
- package/package.json +1 -1
package/dist/commands/install.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import * as clack from "@clack/prompts";
|
|
6
6
|
import { join } from "path";
|
|
7
|
+
import { statfsSync } from "fs";
|
|
7
8
|
import { ApiClient } from "../lib/api-client.js";
|
|
8
9
|
import { getServer, getInstallDir, loadInstalled } from "../lib/config.js";
|
|
9
10
|
import { installSkill } from "../lib/installer.js";
|
|
@@ -110,6 +111,25 @@ export async function installCommand(skillIds, opts) {
|
|
|
110
111
|
return;
|
|
111
112
|
}
|
|
112
113
|
}
|
|
114
|
+
// R4-FIX #8: 安装前检查磁盘空间(可选警告)
|
|
115
|
+
try {
|
|
116
|
+
const totalSize = selectedIds.reduce((sum, id) => {
|
|
117
|
+
const s = skills.find((s) => s.id === id);
|
|
118
|
+
return sum + (s?.package_size || 0);
|
|
119
|
+
}, 0);
|
|
120
|
+
if (totalSize > 0) {
|
|
121
|
+
const installPath = getInstallDir();
|
|
122
|
+
const { mkdirSync } = await import("fs");
|
|
123
|
+
mkdirSync(installPath, { recursive: true });
|
|
124
|
+
const fsStats = statfsSync(installPath);
|
|
125
|
+
const freeSpace = fsStats.bsize * fsStats.bavail;
|
|
126
|
+
// 需要解压后约 2x 空间(压缩包 + 解压内容)
|
|
127
|
+
if (freeSpace < totalSize * 2) {
|
|
128
|
+
ui.warning(`磁盘剩余空间不足: ${ui.fileSize(freeSpace)} 可用, 预计需要 ${ui.fileSize(totalSize * 2)}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch { /* best-effort: statfsSync 可能在某些平台不可用 */ }
|
|
113
133
|
// Install each
|
|
114
134
|
let successCount = 0;
|
|
115
135
|
for (const id of selectedIds) {
|
|
@@ -36,7 +36,7 @@ function getAgents(server, key) {
|
|
|
36
36
|
{
|
|
37
37
|
name: "Claude Desktop",
|
|
38
38
|
configPath: claudeDesktopPath,
|
|
39
|
-
detect: () => existsSync(claudeDesktopPath)
|
|
39
|
+
detect: () => existsSync(claudeDesktopPath), // R4-FIX #4: 只检查配置文件本身,避免父目录误检
|
|
40
40
|
generate: () => ({
|
|
41
41
|
mcpServers: {
|
|
42
42
|
"dreamlogic-skills": {
|
|
@@ -46,6 +46,8 @@ function getAgents(server, key) {
|
|
|
46
46
|
},
|
|
47
47
|
}),
|
|
48
48
|
apply: (newSection) => {
|
|
49
|
+
// R4-FIX #5: read-then-write 存在 TOCTOU 竞态,但此为单用户 CLI 工具,
|
|
50
|
+
// 风险极低。如需更强保护可使用 flock,但当前场景不需要。
|
|
49
51
|
let existing = {};
|
|
50
52
|
if (existsSync(claudeDesktopPath)) {
|
|
51
53
|
try {
|
|
@@ -108,6 +110,7 @@ function getAgents(server, key) {
|
|
|
108
110
|
},
|
|
109
111
|
}),
|
|
110
112
|
apply: (newSection) => {
|
|
113
|
+
// R4-FIX #5: read-then-write TOCTOU — 单用户 CLI 风险极低,添加注释说明
|
|
111
114
|
const path = join(home, ".cursor", "mcp.json");
|
|
112
115
|
let existing = {};
|
|
113
116
|
if (existsSync(path)) {
|
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/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import * as clack from "@clack/prompts";
|
|
|
10
10
|
import { CLI_VERSION, CLI_NAME, CLI_AUTHOR } from "./types.js";
|
|
11
11
|
import { ui } from "./lib/ui.js";
|
|
12
12
|
import { getApiKey } from "./lib/config.js";
|
|
13
|
+
import boxen from "boxen";
|
|
13
14
|
// Commands
|
|
14
15
|
import { loginCommand } from "./commands/login.js";
|
|
15
16
|
import { logoutCommand } from "./commands/logout.js";
|
|
@@ -29,8 +30,15 @@ program
|
|
|
29
30
|
program
|
|
30
31
|
.command("login")
|
|
31
32
|
.description("登录 — 验证 API Key")
|
|
32
|
-
|
|
33
|
-
.
|
|
33
|
+
// R4-FIX #1: API Key 通过 CLI 参数暴露风险警告
|
|
34
|
+
.option("-k, --key <key>", "API Key(⚠️ 不推荐:会暴露在进程列表和 shell 历史中,建议用交互输入或环境变量)")
|
|
35
|
+
.action((opts) => {
|
|
36
|
+
// R4-FIX #1: 清除 process.title 中的敏感参数
|
|
37
|
+
if (opts.key) {
|
|
38
|
+
process.title = "dreamlogic login";
|
|
39
|
+
}
|
|
40
|
+
return loginCommand(opts);
|
|
41
|
+
});
|
|
34
42
|
// ===== logout =====
|
|
35
43
|
program
|
|
36
44
|
.command("logout")
|
|
@@ -134,10 +142,25 @@ program.action(async () => {
|
|
|
134
142
|
// Handle errors gracefully
|
|
135
143
|
program.exitOverride();
|
|
136
144
|
async function main() {
|
|
137
|
-
//
|
|
145
|
+
// R4-FIX #9: TLS 验证禁用 — 醒目安全警告(红色框)
|
|
138
146
|
if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === "0") {
|
|
139
|
-
|
|
140
|
-
|
|
147
|
+
const tlsWarning = [
|
|
148
|
+
"NODE_TLS_REJECT_UNAUTHORIZED=0 已检测到",
|
|
149
|
+
"TLS 证书验证已完全禁用!",
|
|
150
|
+
"",
|
|
151
|
+
"风险:所有 HTTPS 请求均不验证服务器身份,",
|
|
152
|
+
"可能遭受中间人攻击 (MITM)。",
|
|
153
|
+
"",
|
|
154
|
+
"修复:unset NODE_TLS_REJECT_UNAUTHORIZED",
|
|
155
|
+
].join("\n");
|
|
156
|
+
console.log(boxen(tlsWarning, {
|
|
157
|
+
title: "⚠️ 安全警告",
|
|
158
|
+
titleAlignment: "center",
|
|
159
|
+
padding: 1,
|
|
160
|
+
margin: { top: 1, bottom: 1, left: 2, right: 0 },
|
|
161
|
+
borderStyle: "double",
|
|
162
|
+
borderColor: "red",
|
|
163
|
+
}));
|
|
141
164
|
}
|
|
142
165
|
try {
|
|
143
166
|
await program.parseAsync(process.argv);
|
|
@@ -156,7 +179,21 @@ async function main() {
|
|
|
156
179
|
clack.cancel("Cancelled.");
|
|
157
180
|
return;
|
|
158
181
|
}
|
|
159
|
-
|
|
182
|
+
// R4-FIX #10: 错误信息不泄漏内部路径/堆栈
|
|
183
|
+
const knownErrors = ["ECONNREFUSED", "ENOTFOUND", "ETIMEDOUT", "EACCES", "EPERM"];
|
|
184
|
+
const errMsg = err.message || "";
|
|
185
|
+
if (knownErrors.some(code => errMsg.includes(code))) {
|
|
186
|
+
ui.err(`操作失败: ${errMsg}`);
|
|
187
|
+
}
|
|
188
|
+
else if (errMsg.includes("SHA256") || errMsg.includes("Invalid skill ID")) {
|
|
189
|
+
ui.err(errMsg);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
ui.err("发生意外错误,请重试或联系支持。");
|
|
193
|
+
if (process.env.DREAMLOGIC_DEBUG === "1") {
|
|
194
|
+
ui.line(`调试信息: ${errMsg}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
160
197
|
process.exitCode = 1;
|
|
161
198
|
}
|
|
162
199
|
}
|
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/api-client.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export declare class ApiClient {
|
|
|
12
12
|
downloadPackage(filename: string, onProgress?: (downloaded: number, total: number) => void): Promise<{
|
|
13
13
|
buffer: Buffer;
|
|
14
14
|
sha256: string;
|
|
15
|
+
contentLength: number;
|
|
16
|
+
warnLargeDownload: boolean;
|
|
15
17
|
}>;
|
|
16
18
|
/** GET /health — check server connectivity (R2-09: validated) */
|
|
17
19
|
health(): Promise<{
|
package/dist/lib/api-client.js
CHANGED
|
@@ -11,6 +11,8 @@ import { CLI_VERSION } from "../types.js";
|
|
|
11
11
|
const API_TIMEOUT = 30_000; // 30s for API calls
|
|
12
12
|
const DOWNLOAD_TIMEOUT = 300_000; // 5min for downloads
|
|
13
13
|
const MAX_DOWNLOAD_SIZE = 200 * 1024 * 1024; // 200MB
|
|
14
|
+
// R4-FIX #3: 下载预警阈值
|
|
15
|
+
const DOWNLOAD_WARN_SIZE = 50 * 1024 * 1024; // 50MB
|
|
14
16
|
export class ApiClient {
|
|
15
17
|
baseUrl;
|
|
16
18
|
apiKey;
|
|
@@ -81,6 +83,8 @@ export class ApiClient {
|
|
|
81
83
|
if (!Number.isNaN(contentLength) && contentLength > 0 && contentLength > MAX_DOWNLOAD_SIZE) {
|
|
82
84
|
throw new ApiError(`Package too large: ${contentLength} bytes (max ${MAX_DOWNLOAD_SIZE})`, 413);
|
|
83
85
|
}
|
|
86
|
+
// R4-FIX #3: 大包下载预警 — 通过回调通知调用者
|
|
87
|
+
const warnLargeDownload = !Number.isNaN(contentLength) && contentLength > DOWNLOAD_WARN_SIZE;
|
|
84
88
|
const reader = res.body?.getReader();
|
|
85
89
|
if (!reader)
|
|
86
90
|
throw new ApiError("No response body", 500);
|
|
@@ -103,7 +107,7 @@ export class ApiClient {
|
|
|
103
107
|
}
|
|
104
108
|
const buffer = Buffer.concat(chunks);
|
|
105
109
|
const sha256 = createHash("sha256").update(buffer).digest("hex");
|
|
106
|
-
return { buffer, sha256 };
|
|
110
|
+
return { buffer, sha256, contentLength, warnLargeDownload };
|
|
107
111
|
}
|
|
108
112
|
/** GET /health — check server connectivity (R2-09: validated) */
|
|
109
113
|
async health() {
|
package/dist/lib/config.js
CHANGED
|
@@ -4,8 +4,19 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync, statSync } from "fs";
|
|
6
6
|
import { join, resolve } from "path";
|
|
7
|
-
import { homedir } from "os";
|
|
7
|
+
import { homedir, platform } from "os";
|
|
8
8
|
import { CONFIG_DIR_NAME, DEFAULT_SERVER, DEFAULT_INSTALL_DIR_NAME, } from "../types.js";
|
|
9
|
+
// R4-FIX #11: Windows 不支持 Unix 文件权限,跳过 chmod
|
|
10
|
+
const isWin = platform() === "win32";
|
|
11
|
+
/** Platform-safe chmod: 只在 Unix 系统上执行 */
|
|
12
|
+
function safeChmod(path, mode) {
|
|
13
|
+
if (isWin)
|
|
14
|
+
return; // R4-FIX #11: Windows 下跳过
|
|
15
|
+
try {
|
|
16
|
+
chmodSync(path, mode);
|
|
17
|
+
}
|
|
18
|
+
catch { /* best-effort */ }
|
|
19
|
+
}
|
|
9
20
|
/** CFG-01 FIX: Recursively strip prototype pollution keys from parsed JSON */
|
|
10
21
|
function sanitize(obj) {
|
|
11
22
|
if (typeof obj !== "object" || obj === null)
|
|
@@ -61,10 +72,7 @@ export function saveConfig(config) {
|
|
|
61
72
|
ensureConfigDir();
|
|
62
73
|
const path = getConfigPath();
|
|
63
74
|
writeFileSync(path, JSON.stringify(config, null, 2) + "\n", { mode: 0o600 });
|
|
64
|
-
|
|
65
|
-
chmodSync(path, 0o600);
|
|
66
|
-
}
|
|
67
|
-
catch { /* Windows fallback */ }
|
|
75
|
+
safeChmod(path, 0o600);
|
|
68
76
|
}
|
|
69
77
|
/** R1-06: Validate key format from all sources (env, config file) */
|
|
70
78
|
export function getApiKey() {
|
|
@@ -78,8 +86,9 @@ export function getApiKey() {
|
|
|
78
86
|
/** R1-07: Enforce HTTPS (localhost/127.0.0.1 exempt for dev) */
|
|
79
87
|
export function getServer() {
|
|
80
88
|
const url = process.env.DREAMLOGIC_SERVER || loadConfig()?.server || DEFAULT_SERVER;
|
|
81
|
-
// R1-07 + R2-03: HTTPS enforcement (localhost/127.
|
|
82
|
-
|
|
89
|
+
// R1-07 + R2-03 + R4-H06: HTTPS enforcement (localhost/127.x.x.x/[::1] exempt)
|
|
90
|
+
const LOCALHOST_RE = /^http:\/\/(localhost|127(?:\.\d{1,3}){3}|\[::1\]|0\.0\.0\.0)(:[0-9]+)?(\/|$)/i;
|
|
91
|
+
if (!/^https:\/\//i.test(url) && !LOCALHOST_RE.test(url)) {
|
|
83
92
|
throw new Error("Server URL must use HTTPS (http://localhost allowed for dev)");
|
|
84
93
|
}
|
|
85
94
|
return url;
|
|
@@ -103,6 +112,13 @@ export function loadInstalled() {
|
|
|
103
112
|
// R2-13: Basic shape validation
|
|
104
113
|
if (typeof data !== "object" || data === null || Array.isArray(data))
|
|
105
114
|
return {};
|
|
115
|
+
// R4-FIX #12: 兼容旧数据 — 将 number 类型的 installed_at 统一为 ISO string
|
|
116
|
+
for (const key of Object.keys(data)) {
|
|
117
|
+
const entry = data[key];
|
|
118
|
+
if (entry && typeof entry.installed_at === "number") {
|
|
119
|
+
entry.installed_at = new Date(entry.installed_at).toISOString();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
106
122
|
return data;
|
|
107
123
|
}
|
|
108
124
|
catch {
|
|
@@ -114,10 +130,7 @@ export function saveInstalled(registry) {
|
|
|
114
130
|
ensureConfigDir();
|
|
115
131
|
const path = getInstalledPath();
|
|
116
132
|
writeFileSync(path, JSON.stringify(registry, null, 2) + "\n", { mode: 0o600 });
|
|
117
|
-
|
|
118
|
-
chmodSync(path, 0o600);
|
|
119
|
-
}
|
|
120
|
-
catch { /* Windows fallback */ }
|
|
133
|
+
safeChmod(path, 0o600);
|
|
121
134
|
}
|
|
122
135
|
/** R1-13: Zero-fill before overwrite for defense-in-depth */
|
|
123
136
|
export function clearConfig() {
|
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";
|
|
@@ -54,6 +54,10 @@ export async function installSkill(client, skillId, packageFile, expectedSha256,
|
|
|
54
54
|
buffer = result.buffer;
|
|
55
55
|
actualSha256 = result.sha256;
|
|
56
56
|
spinner.succeed(` 已下载 ${ui.fileSize(buffer.length)}`);
|
|
57
|
+
// R4-FIX #3: 大包内存占用警告
|
|
58
|
+
if (result.warnLargeDownload) {
|
|
59
|
+
ui.warning(`包体积较大 (${ui.fileSize(buffer.length)}),内存占用较高`);
|
|
60
|
+
}
|
|
57
61
|
}
|
|
58
62
|
catch (err) {
|
|
59
63
|
spinner.fail(` 下载失败`);
|
|
@@ -176,6 +180,23 @@ export function rollbackSkill(skillId) {
|
|
|
176
180
|
if (backups.length === 0)
|
|
177
181
|
return false;
|
|
178
182
|
const latestBackup = join(installDir, backups[0]);
|
|
183
|
+
// R4-FIX #6: 回滚前验证备份目录完整性
|
|
184
|
+
try {
|
|
185
|
+
const backupStat = statSync(latestBackup);
|
|
186
|
+
if (!backupStat.isDirectory()) {
|
|
187
|
+
ui.warning("备份路径不是有效目录,回滚中止");
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
const backupContents = readdirSync(latestBackup);
|
|
191
|
+
if (backupContents.length === 0) {
|
|
192
|
+
ui.warning("备份目录为空,回滚中止 — 可能备份已损坏");
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
ui.warning("无法验证备份完整性,回滚中止");
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
179
200
|
if (existsSync(skillDir)) {
|
|
180
201
|
rmSync(skillDir, { recursive: true, force: true });
|
|
181
202
|
}
|
|
@@ -244,6 +265,16 @@ function extractZip(buffer, targetDir) {
|
|
|
244
265
|
reject(new Error(`Unsafe path in ZIP: ${entry.fileName}`));
|
|
245
266
|
return;
|
|
246
267
|
}
|
|
268
|
+
// R4-FIX #2: 拒绝 Windows Alternate Data Streams (filename:stream)
|
|
269
|
+
// 排除 Windows 盘符 (如 C:\)
|
|
270
|
+
const pathParts = entryPath.split(sep);
|
|
271
|
+
for (const part of pathParts) {
|
|
272
|
+
if (part.includes(":") && !/^[A-Za-z]:$/.test(part)) {
|
|
273
|
+
zipfile.close();
|
|
274
|
+
reject(new Error(`不安全的路径(可能包含 Windows ADS): ${entry.fileName}`));
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
247
278
|
// INS-02 FIX: Reject symlink entries (external attributes bit 0xA000)
|
|
248
279
|
const externalAttrs = (entry.externalFileAttributes >>> 16) & 0xFFFF;
|
|
249
280
|
const S_IFLNK = 0xA000;
|
|
@@ -309,7 +340,19 @@ function extractZip(buffer, targetDir) {
|
|
|
309
340
|
});
|
|
310
341
|
const writeStream = createWriteStream(fullPath);
|
|
311
342
|
readStream.pipe(countingStream).pipe(writeStream);
|
|
312
|
-
writeStream.on("finish", () =>
|
|
343
|
+
writeStream.on("finish", () => {
|
|
344
|
+
// R4-C01 FIX: Post-write symlink verification (defense-in-depth)
|
|
345
|
+
try {
|
|
346
|
+
if (lstatSync(fullPath).isSymbolicLink()) {
|
|
347
|
+
unlinkSync(fullPath);
|
|
348
|
+
zipfile.close();
|
|
349
|
+
reject(new Error(`Post-extract symlink detected: ${entry.fileName}`));
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
catch { /* stat failed = file doesn't exist, ok to continue */ }
|
|
354
|
+
zipfile.readEntry();
|
|
355
|
+
});
|
|
313
356
|
writeStream.on("error", (e) => { zipfile.close(); reject(e); });
|
|
314
357
|
countingStream.on("error", (e) => { zipfile.close(); reject(e); });
|
|
315
358
|
readStream.on("error", (e) => { zipfile.close(); reject(e); });
|
package/dist/types.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface CliConfig {
|
|
|
22
22
|
}
|
|
23
23
|
export interface InstalledSkill {
|
|
24
24
|
version: string;
|
|
25
|
+
/** R4-FIX #12: 统一为 ISO 8601 字符串 (如 "2025-01-01T00:00:00.000Z") */
|
|
25
26
|
installed_at: string;
|
|
26
27
|
path: string;
|
|
27
28
|
sha256: string;
|
|
@@ -33,6 +34,6 @@ export interface InstalledRegistry {
|
|
|
33
34
|
export declare const DEFAULT_SERVER = "https://skill.dreamlogic-claw.com";
|
|
34
35
|
export declare const DEFAULT_INSTALL_DIR_NAME = "dreamlogic-skills";
|
|
35
36
|
export declare const CONFIG_DIR_NAME = ".dreamlogic";
|
|
36
|
-
export declare const CLI_VERSION = "2.0.
|
|
37
|
+
export declare const CLI_VERSION = "2.0.6";
|
|
37
38
|
export declare const CLI_NAME = "Dreamlogic CLI";
|
|
38
39
|
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.6";
|
|
6
6
|
export const CLI_NAME = "Dreamlogic CLI";
|
|
7
7
|
export const CLI_AUTHOR = "Dreamlogic-ai by MAJORNINE";
|