@lijian-ui/dsh-session-cleaner 0.1.0 → 0.1.2
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.en.md +4 -2
- package/README.md +4 -2
- package/lib/client.js +737 -630
- package/lib/index.js +83 -30
- package/package.json +87 -87
- /package/lib/{index-DdPrDbW6.d.ts → index.d.ts} +0 -0
package/lib/index.js
CHANGED
|
@@ -5,25 +5,48 @@ import * as fs from "fs";
|
|
|
5
5
|
import * as path from "path";
|
|
6
6
|
import { homedir } from "os";
|
|
7
7
|
import { zstdDecompressSync } from "node:zlib";
|
|
8
|
+
|
|
8
9
|
//#region src/session-store.ts
|
|
9
10
|
/**
|
|
10
|
-
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
*
|
|
16
|
-
|
|
17
|
-
*
|
|
18
|
-
|
|
19
|
-
*
|
|
20
|
-
* 删除 = 三处清理:session 目录 + projcache + workspace.json(sessionIds/archivedSessionIds)。
|
|
21
|
-
* 归档/恢复 = 读写 workspace.json 的 global.archivedSessionIds(单真相源与官方打通)。
|
|
22
|
-
*
|
|
23
|
-
* ⚠️ 已知边界:归档/恢复直接改文件,host 内存态不会热更新——插件页面以文件为准(准确),
|
|
24
|
-
* 官方 UI 的隐藏/恢复在 dsh 重启后同步。删除同理(已删除的会话从文件层消失,官方 UI
|
|
25
|
-
* 重启后不再列出)。
|
|
11
|
+
|
|
12
|
+
* dsh 会话 ID ↔ 文件系统目录名 编解码(与 dsh-session-persistence-jsonl 的 encodeSegment 对齐)。
|
|
13
|
+
|
|
14
|
+
* dsh 把 sessionId 中的非 [A-Za-z0-9._-] 字符编码为 ~XXXX(charCode 的 4 位十六进制大写)。
|
|
15
|
+
|
|
16
|
+
* 例如 `im:qq-s5ey:c2c:...` → `im~003Aqq-s5ey~003Ac2c~003A...`。
|
|
17
|
+
|
|
18
|
+
* session-cleaner 扫描文件系统得到编码后的目录名,需要解码回原始 ID 才能与 workspace.json 的 sessionIds 匹配。
|
|
19
|
+
|
|
26
20
|
*/
|
|
21
|
+
function encodeSegment(raw) {
|
|
22
|
+
if (raw.length === 0) return raw;
|
|
23
|
+
if (raw === ".") return "~002E";
|
|
24
|
+
if (raw === "..") return "~002E~002E";
|
|
25
|
+
let out = "";
|
|
26
|
+
for (let i = 0; i < raw.length; i++) {
|
|
27
|
+
const code = raw.charCodeAt(i);
|
|
28
|
+
const ch = String.fromCharCode(code);
|
|
29
|
+
if (ch !== "~" && /^[A-Za-z0-9._-]$/.test(ch)) out += ch;
|
|
30
|
+
else out += "~" + code.toString(16).toUpperCase().padStart(4, "0");
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
function decodeSegment(encoded) {
|
|
35
|
+
let out = "";
|
|
36
|
+
for (let i = 0; i < encoded.length;) {
|
|
37
|
+
if (encoded[i] === "~" && i + 5 <= encoded.length) {
|
|
38
|
+
const hex = encoded.slice(i + 1, i + 5);
|
|
39
|
+
if (/^[0-9A-Fa-f]{4}$/.test(hex)) {
|
|
40
|
+
out += String.fromCharCode(parseInt(hex, 16));
|
|
41
|
+
i += 5;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
out += encoded[i];
|
|
46
|
+
i++;
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
27
50
|
/** dsh 用户数据目录(与桌面壳 buildDshEnv 的 DSH_HOME 保持一致) */
|
|
28
51
|
function dshHome() {
|
|
29
52
|
return process.env.DSH_HOME ?? path.join(homedir(), ".dsh");
|
|
@@ -77,8 +100,11 @@ function writeArchived(archived) {
|
|
|
77
100
|
writeJsonAtomic(workspaceFile(), ws);
|
|
78
101
|
}
|
|
79
102
|
/**
|
|
103
|
+
|
|
80
104
|
* 扫描全部 session(文件层权威)。
|
|
105
|
+
|
|
81
106
|
* 遍历 ~/.dsh/sessions/<workspace>/<sessionId>/,结合 workspace.json 标注状态。
|
|
107
|
+
|
|
82
108
|
*/
|
|
83
109
|
function listSessions() {
|
|
84
110
|
const root = sessionsRoot();
|
|
@@ -86,7 +112,7 @@ function listSessions() {
|
|
|
86
112
|
if (!fs.existsSync(root)) return out;
|
|
87
113
|
const archived = readArchived();
|
|
88
114
|
const ws = readWorkspace();
|
|
89
|
-
const activeIds =
|
|
115
|
+
const activeIds = new Set();
|
|
90
116
|
for (const w of Object.values(ws.tables?.workspaces ?? {})) for (const id of w.sessionIds ?? []) activeIds.add(id);
|
|
91
117
|
for (const workspaceDir of fs.readdirSync(root, { withFileTypes: true })) {
|
|
92
118
|
if (!workspaceDir.isDirectory()) continue;
|
|
@@ -106,13 +132,13 @@ function listSessions() {
|
|
|
106
132
|
continue;
|
|
107
133
|
}
|
|
108
134
|
out.push(stripUndefined({
|
|
109
|
-
id: entry.name,
|
|
135
|
+
id: decodeSegment(entry.name),
|
|
110
136
|
workspaceDir: workspaceDir.name,
|
|
111
137
|
dir,
|
|
112
138
|
sizeBytes,
|
|
113
139
|
mtimeMs,
|
|
114
|
-
archived: archived.has(entry.name),
|
|
115
|
-
active: activeIds.has(entry.name),
|
|
140
|
+
archived: archived.has(decodeSegment(entry.name)),
|
|
141
|
+
active: activeIds.has(decodeSegment(entry.name)),
|
|
116
142
|
title: readSessionTitle(logFile)
|
|
117
143
|
}));
|
|
118
144
|
}
|
|
@@ -136,11 +162,12 @@ function removeFromProjcache(id) {
|
|
|
136
162
|
if (!fs.existsSync(file)) return;
|
|
137
163
|
const data = readJson(file, null);
|
|
138
164
|
if (data === null) return;
|
|
165
|
+
const encodedId = encodeSegment(id);
|
|
139
166
|
const walk = (o) => {
|
|
140
167
|
if (!o || typeof o !== "object") return false;
|
|
141
168
|
let changed = false;
|
|
142
169
|
for (const k of Object.keys(o)) {
|
|
143
|
-
if (String(k).includes(id)) {
|
|
170
|
+
if (String(k).includes(id) || String(k).includes(encodedId)) {
|
|
144
171
|
delete o[k];
|
|
145
172
|
changed = true;
|
|
146
173
|
continue;
|
|
@@ -152,16 +179,21 @@ function removeFromProjcache(id) {
|
|
|
152
179
|
if (walk(data)) writeJsonAtomic(file, data);
|
|
153
180
|
}
|
|
154
181
|
/**
|
|
182
|
+
|
|
155
183
|
* 真删除会话(不可恢复,调用方必须已二次确认):
|
|
184
|
+
|
|
156
185
|
* ① 删会话目录;② 清 projcache;③ 清 workspace.json(sessionIds + archivedSessionIds)。
|
|
186
|
+
|
|
157
187
|
* 返回已删除的目录路径。
|
|
188
|
+
|
|
158
189
|
*/
|
|
159
190
|
function deleteSession(id) {
|
|
160
191
|
const root = sessionsRoot();
|
|
192
|
+
const encodedId = encodeSegment(id);
|
|
161
193
|
let target = null;
|
|
162
194
|
if (fs.existsSync(root)) for (const workspaceDir of fs.readdirSync(root, { withFileTypes: true })) {
|
|
163
195
|
if (!workspaceDir.isDirectory()) continue;
|
|
164
|
-
const dir = path.join(root, workspaceDir.name,
|
|
196
|
+
const dir = path.join(root, workspaceDir.name, encodedId);
|
|
165
197
|
if (fs.existsSync(path.join(dir, "session.jsonl.zstd"))) {
|
|
166
198
|
target = dir;
|
|
167
199
|
break;
|
|
@@ -198,9 +230,13 @@ function unarchiveSession(id) {
|
|
|
198
230
|
return { ok: true };
|
|
199
231
|
}
|
|
200
232
|
/**
|
|
233
|
+
|
|
201
234
|
* 多帧 zstd 解码:dsh 的 session 日志每次追加写一个独立 zstd 帧
|
|
235
|
+
|
|
202
236
|
* (文件里多个 magic 头),Node 的 zstdDecompressSync 只解第一帧——
|
|
237
|
+
|
|
203
238
|
* 必须按 magic 位置逐帧解压拼接。
|
|
239
|
+
|
|
204
240
|
*/
|
|
205
241
|
function zstdDecompressAll(input) {
|
|
206
242
|
const magic = Buffer.from([
|
|
@@ -228,7 +264,8 @@ function zstdDecompressAll(input) {
|
|
|
228
264
|
function readSessionLines(logFile) {
|
|
229
265
|
try {
|
|
230
266
|
if (!fs.existsSync(logFile)) return null;
|
|
231
|
-
|
|
267
|
+
const raw = zstdDecompressAll(fs.readFileSync(logFile));
|
|
268
|
+
return raw.toString("utf8").split("\n").filter(Boolean);
|
|
232
269
|
} catch {
|
|
233
270
|
return null;
|
|
234
271
|
}
|
|
@@ -255,14 +292,15 @@ function extractHeader(lines) {
|
|
|
255
292
|
cwd: header.cwd
|
|
256
293
|
};
|
|
257
294
|
} catch {
|
|
258
|
-
return;
|
|
295
|
+
return void 0;
|
|
259
296
|
}
|
|
260
297
|
}
|
|
261
298
|
/** 从消息事件提取纯文本(宽容解析各种 content 形态) */
|
|
262
299
|
function messageText(message) {
|
|
263
300
|
if (typeof message === "string") return message;
|
|
264
301
|
if (!message || typeof message !== "object") return "";
|
|
265
|
-
const
|
|
302
|
+
const m = message;
|
|
303
|
+
const content = m["content"];
|
|
266
304
|
if (typeof content === "string") return content;
|
|
267
305
|
if (Array.isArray(content)) return content.map((part) => {
|
|
268
306
|
if (typeof part === "string") return part;
|
|
@@ -287,15 +325,19 @@ function readSessionTitle(logFile) {
|
|
|
287
325
|
return extractTitle(lines);
|
|
288
326
|
}
|
|
289
327
|
/**
|
|
328
|
+
|
|
290
329
|
* 读取会话预览:header 元数据 + 最近 N 条用户/助手消息文本。
|
|
330
|
+
|
|
291
331
|
* 找不到文件抛错(调用方转 RPC 错误)。
|
|
332
|
+
|
|
292
333
|
*/
|
|
293
334
|
function previewSession(id, limit = 12) {
|
|
294
335
|
const root = sessionsRoot();
|
|
336
|
+
const encodedId = encodeSegment(id);
|
|
295
337
|
let logFile = null;
|
|
296
338
|
if (fs.existsSync(root)) for (const workspaceDir of fs.readdirSync(root, { withFileTypes: true })) {
|
|
297
339
|
if (!workspaceDir.isDirectory()) continue;
|
|
298
|
-
const candidate = path.join(root, workspaceDir.name,
|
|
340
|
+
const candidate = path.join(root, workspaceDir.name, encodedId, "session.jsonl.zstd");
|
|
299
341
|
if (fs.existsSync(candidate)) {
|
|
300
342
|
logFile = candidate;
|
|
301
343
|
break;
|
|
@@ -331,6 +373,7 @@ function previewSession(id, limit = 12) {
|
|
|
331
373
|
messages: messages.slice(-limit)
|
|
332
374
|
});
|
|
333
375
|
}
|
|
376
|
+
|
|
334
377
|
//#endregion
|
|
335
378
|
//#region src/remote.ts
|
|
336
379
|
const SERVICE = "sessionCleanerRemote";
|
|
@@ -341,8 +384,11 @@ const codec = (typeSymbol) => ({
|
|
|
341
384
|
schema: { parse: (v) => v }
|
|
342
385
|
});
|
|
343
386
|
/**
|
|
387
|
+
|
|
344
388
|
* 注册到 `ctx.typert` 的 host 面契约。
|
|
389
|
+
|
|
345
390
|
* face: 'host' + invocations(client 侧的 $mount 贡献则带 descriptors)。
|
|
391
|
+
|
|
346
392
|
*/
|
|
347
393
|
const CONTRIBUTION = {
|
|
348
394
|
package: PACKAGE,
|
|
@@ -428,8 +474,11 @@ const CONTRIBUTION = {
|
|
|
428
474
|
}
|
|
429
475
|
};
|
|
430
476
|
/**
|
|
477
|
+
|
|
431
478
|
* Remote 服务实现。构造时注册 `sessionCleanerRemote` cordis 服务,
|
|
479
|
+
|
|
432
480
|
* 上面的贡献让 API gateway 能分发四个方法。
|
|
481
|
+
|
|
433
482
|
*/
|
|
434
483
|
var SessionCleanerApi = class extends TypertRemoteService {
|
|
435
484
|
constructor(ctx) {
|
|
@@ -461,6 +510,7 @@ function registerSessionCleanerRemote(ctx) {
|
|
|
461
510
|
new SessionCleanerApi(ctx);
|
|
462
511
|
ctx.effect(() => ctx.get("typert").register(CONTRIBUTION), "session-cleaner: typert contribution");
|
|
463
512
|
}
|
|
513
|
+
|
|
464
514
|
//#endregion
|
|
465
515
|
//#region src/index.ts
|
|
466
516
|
/**
|
|
@@ -493,17 +543,19 @@ function apply(ctx) {
|
|
|
493
543
|
*/
|
|
494
544
|
function installConsoleLoggerExporter(ctx) {
|
|
495
545
|
try {
|
|
496
|
-
ctx.root.logger
|
|
546
|
+
const logger = ctx.root.logger;
|
|
547
|
+
logger?.exporter?.({
|
|
497
548
|
colors: 0,
|
|
498
549
|
export: (message) => {
|
|
499
550
|
const { name = "session-cleaner", type = "log", args = [] } = message;
|
|
500
|
-
const
|
|
551
|
+
const rendered = args.map((arg) => arg instanceof Error ? arg.stack ?? arg.message : typeof arg === "string" ? arg : (() => {
|
|
501
552
|
try {
|
|
502
553
|
return JSON.stringify(arg);
|
|
503
554
|
} catch {
|
|
504
555
|
return String(arg);
|
|
505
556
|
}
|
|
506
|
-
})()).join(" ")
|
|
557
|
+
})()).join(" ");
|
|
558
|
+
const line = `[${name}] ${rendered}`;
|
|
507
559
|
if (type === "error") console.error(line);
|
|
508
560
|
else if (type === "warn") console.warn(line);
|
|
509
561
|
else if (type === "debug") console.debug(line);
|
|
@@ -512,5 +564,6 @@ function installConsoleLoggerExporter(ctx) {
|
|
|
512
564
|
});
|
|
513
565
|
} catch {}
|
|
514
566
|
}
|
|
567
|
+
|
|
515
568
|
//#endregion
|
|
516
|
-
export { Config, apply, inject };
|
|
569
|
+
export { Config, apply, inject };
|
package/package.json
CHANGED
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@lijian-ui/dsh-session-cleaner",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Session management plugin for DeepSeek Harness (dsh): list / delete / archive & restore sessions, with a built-in \"Archived\" group and a delete confirm dialog (real delete, not trash). 为 DeepSeek Harness 提供会话管理:列表 / 真删除(二次确认)/ 归档分组与恢复。",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"main": "lib/index.js",
|
|
8
|
-
"types": "lib/index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./lib/index.d.ts",
|
|
12
|
-
"default": "./lib/index.js"
|
|
13
|
-
},
|
|
14
|
-
"./client": {
|
|
15
|
-
"default": "./lib/client.js"
|
|
16
|
-
},
|
|
17
|
-
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
18
|
-
"./package.json": "./package.json"
|
|
19
|
-
},
|
|
20
|
-
"files": [
|
|
21
|
-
"lib/**/*.js",
|
|
22
|
-
"lib/**/*.d.ts",
|
|
23
|
-
"cordis.patch.yml",
|
|
24
|
-
"README.md",
|
|
25
|
-
"README.en.md",
|
|
26
|
-
"LICENSE"
|
|
27
|
-
],
|
|
28
|
-
"scripts": {
|
|
29
|
-
"build": "tsdown",
|
|
30
|
-
"watch": "tsdown --watch",
|
|
31
|
-
"typecheck": "tsc --noEmit",
|
|
32
|
-
"prepare": "npm run build"
|
|
33
|
-
},
|
|
34
|
-
"keywords": [
|
|
35
|
-
"deepseek-harness",
|
|
36
|
-
"dsh",
|
|
37
|
-
"dsh-plugin",
|
|
38
|
-
"session",
|
|
39
|
-
"session-cleaner",
|
|
40
|
-
"archive",
|
|
41
|
-
"delete",
|
|
42
|
-
"cordis"
|
|
43
|
-
],
|
|
44
|
-
"repository": {
|
|
45
|
-
"type": "git",
|
|
46
|
-
"url": "git+https://github.com/lijian-ui/dsh-session-cleaner.git"
|
|
47
|
-
},
|
|
48
|
-
"dsh": {
|
|
49
|
-
"bundle": {
|
|
50
|
-
"patch": "./cordis.patch.yml"
|
|
51
|
-
},
|
|
52
|
-
"client": {
|
|
53
|
-
"inject": [
|
|
54
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
55
|
-
"@deepseek-ai/dsh-client-locale",
|
|
56
|
-
"@deepseek-ai/dsh-api-gateway"
|
|
57
|
-
],
|
|
58
|
-
"platform": "web",
|
|
59
|
-
"immediately": true
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
"peerDependencies": {
|
|
63
|
-
"@deepseek-ai/cordis": "*",
|
|
64
|
-
"@deepseek-ai/
|
|
65
|
-
"@deepseek-ai/dsh-
|
|
66
|
-
"@deepseek-ai/
|
|
67
|
-
},
|
|
68
|
-
"devDependencies": {
|
|
69
|
-
"@deepseek-ai/cordis": "4.0.1",
|
|
70
|
-
"@deepseek-ai/
|
|
71
|
-
"@deepseek-ai/dsh-
|
|
72
|
-
"@deepseek-ai/dsh-
|
|
73
|
-
"@deepseek-ai/dsh-client-
|
|
74
|
-
"@deepseek-ai/dsh-client-
|
|
75
|
-
"@deepseek-ai/dsh-client-
|
|
76
|
-
"@deepseek-ai/dsh-client-
|
|
77
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6",
|
|
78
|
-
"@deepseek-ai/dsh-
|
|
79
|
-
"@deepseek-ai/dsh-
|
|
80
|
-
"@deepseek-ai/
|
|
81
|
-
"@types/node": "^22.0.0",
|
|
82
|
-
"@types/react": "^18.3.0",
|
|
83
|
-
"react": "^18.2.0",
|
|
84
|
-
"tsdown": "^0.12.0",
|
|
85
|
-
"typescript": "^5.6.0"
|
|
86
|
-
}
|
|
87
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@lijian-ui/dsh-session-cleaner",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Session management plugin for DeepSeek Harness (dsh): list / delete / archive & restore sessions, with a built-in \"Archived\" group and a delete confirm dialog (real delete, not trash). 为 DeepSeek Harness 提供会话管理:列表 / 真删除(二次确认)/ 归档分组与恢复。",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "lib/index.js",
|
|
8
|
+
"types": "lib/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./lib/index.d.ts",
|
|
12
|
+
"default": "./lib/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./client": {
|
|
15
|
+
"default": "./lib/client.js"
|
|
16
|
+
},
|
|
17
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"lib/**/*.js",
|
|
22
|
+
"lib/**/*.d.ts",
|
|
23
|
+
"cordis.patch.yml",
|
|
24
|
+
"README.md",
|
|
25
|
+
"README.en.md",
|
|
26
|
+
"LICENSE"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsdown",
|
|
30
|
+
"watch": "tsdown --watch",
|
|
31
|
+
"typecheck": "tsc --noEmit",
|
|
32
|
+
"prepare": "npm run build"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"deepseek-harness",
|
|
36
|
+
"dsh",
|
|
37
|
+
"dsh-plugin",
|
|
38
|
+
"session",
|
|
39
|
+
"session-cleaner",
|
|
40
|
+
"archive",
|
|
41
|
+
"delete",
|
|
42
|
+
"cordis"
|
|
43
|
+
],
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/lijian-ui/dsh-session-cleaner.git"
|
|
47
|
+
},
|
|
48
|
+
"dsh": {
|
|
49
|
+
"bundle": {
|
|
50
|
+
"patch": "./cordis.patch.yml"
|
|
51
|
+
},
|
|
52
|
+
"client": {
|
|
53
|
+
"inject": [
|
|
54
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
55
|
+
"@deepseek-ai/dsh-client-locale",
|
|
56
|
+
"@deepseek-ai/dsh-api-gateway"
|
|
57
|
+
],
|
|
58
|
+
"platform": "web",
|
|
59
|
+
"immediately": true
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"@deepseek-ai/cordis": "*",
|
|
64
|
+
"@deepseek-ai/dsh-settings": "*",
|
|
65
|
+
"@deepseek-ai/dsh-typert-protocol": "*",
|
|
66
|
+
"@deepseek-ai/schemastery": "*"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@deepseek-ai/cordis": "4.0.1",
|
|
70
|
+
"@deepseek-ai/dsh-api-gateway": "0.1.0-rc.6",
|
|
71
|
+
"@deepseek-ai/dsh-client-connection": "0.1.0-rc.6",
|
|
72
|
+
"@deepseek-ai/dsh-client-locale": "0.1.0-rc.6",
|
|
73
|
+
"@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6",
|
|
74
|
+
"@deepseek-ai/dsh-client-schema-form": "0.1.0-rc.6",
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.6",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.0-rc.6",
|
|
77
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6",
|
|
78
|
+
"@deepseek-ai/dsh-settings": "0.1.0-rc.6",
|
|
79
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.0-rc.6",
|
|
80
|
+
"@deepseek-ai/schemastery": "3.18.1",
|
|
81
|
+
"@types/node": "^22.0.0",
|
|
82
|
+
"@types/react": "^18.3.0",
|
|
83
|
+
"react": "^18.2.0",
|
|
84
|
+
"tsdown": "^0.12.0",
|
|
85
|
+
"typescript": "^5.6.0"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
File without changes
|