@michengai/dsh-codex-ui 0.2.48
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/LICENSE +201 -0
- package/README.md +171 -0
- package/README.zh-CN.md +171 -0
- package/assets/icon.png +0 -0
- package/assets/screenshots/conversation.png +0 -0
- package/assets/screenshots/session-menu.png +0 -0
- package/assets/screenshots/settings-about.png +0 -0
- package/assets/screenshots/sidebar.png +0 -0
- package/assets/screenshots/workspace-menu.png +0 -0
- package/cordis.patch.yml +6 -0
- package/dist/client.js +1966 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +312 -0
- package/package.json +102 -0
package/dist/index.d.mts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
//#region src/dependencies.ts
|
|
7
|
+
const MANAGED_DEPENDENCIES = [
|
|
8
|
+
{
|
|
9
|
+
id: "experts",
|
|
10
|
+
packageName: "@michengai/dsh-agency-agents"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: "skills",
|
|
14
|
+
packageName: "@michengai/dsh-skills-manager"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: "archive",
|
|
18
|
+
packageName: "@michengai/dsh-archive-manager"
|
|
19
|
+
}
|
|
20
|
+
];
|
|
21
|
+
function managedDependency(id) {
|
|
22
|
+
return MANAGED_DEPENDENCIES.find((dependency) => dependency.id === id);
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/dependency-manager.ts
|
|
26
|
+
function profileDirectory() {
|
|
27
|
+
if (process.env.DSH_PROFILE_DIR !== void 0) return process.env.DSH_PROFILE_DIR;
|
|
28
|
+
return resolve(homedir(), ".dsh", "profiles", "web");
|
|
29
|
+
}
|
|
30
|
+
async function profileManifest() {
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(await readFile(resolve(profileDirectory(), "package.json"), "utf8"));
|
|
33
|
+
} catch (error) {
|
|
34
|
+
if (error.code === "ENOENT") return {};
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function installedPackageVersion(packageName) {
|
|
39
|
+
try {
|
|
40
|
+
const manifest = JSON.parse(await readFile(resolve(profileDirectory(), "node_modules", ...packageName.split("/"), "package.json"), "utf8"));
|
|
41
|
+
return typeof manifest.version === "string" ? manifest.version : void 0;
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (error.code === "ENOENT") return void 0;
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function npmLatestVersion(packageName) {
|
|
48
|
+
try {
|
|
49
|
+
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, { signal: AbortSignal.timeout(5e3) });
|
|
50
|
+
if (!response.ok) return void 0;
|
|
51
|
+
const manifest = await response.json();
|
|
52
|
+
return typeof manifest.version === "string" ? manifest.version : void 0;
|
|
53
|
+
} catch {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function escapeRegExp(value) {
|
|
58
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
59
|
+
}
|
|
60
|
+
/** 将用户确认的精确版本合并进 Profile 的 pnpm 发布时间保护例外。 */
|
|
61
|
+
function applyReleaseExclude(source, packageName, version) {
|
|
62
|
+
const eol = source.includes("\r\n") ? "\r\n" : "\n";
|
|
63
|
+
const existing = new RegExp(`^ - '${escapeRegExp(packageName)}@([^']*)'\\s*$`, "m").exec(source);
|
|
64
|
+
if (existing !== null) {
|
|
65
|
+
const versions = existing[1].split(/\s*\|\|\s*/).map((item) => item.trim()).filter((item) => item !== "");
|
|
66
|
+
if (versions.includes(version)) return source;
|
|
67
|
+
const next = ` - '${packageName}@${[...versions, version].join(" || ")}'`;
|
|
68
|
+
return `${source.slice(0, existing.index)}${next}${source.slice(existing.index + existing[0].length)}`;
|
|
69
|
+
}
|
|
70
|
+
const entry = ` - '${packageName}@${version}'`;
|
|
71
|
+
const section = /^minimumReleaseAgeExclude:\r?\n(?:(?: |\t).*(?:\r?\n|$))*/m;
|
|
72
|
+
if (section.test(source)) return source.replace(section, (match) => `${match.endsWith("\n") ? match : `${match}${eol}`}${entry}${eol}`);
|
|
73
|
+
return `${source}${source === "" || source.endsWith("\n") ? "" : eol}minimumReleaseAgeExclude:${eol}${entry}${eol}`;
|
|
74
|
+
}
|
|
75
|
+
/** 将用户本次确认的精确版本加入 Profile 的 pnpm 发布时间保护例外。 */
|
|
76
|
+
async function ensureLatestReleaseAllowed(packageName, version) {
|
|
77
|
+
if (versionParts(version) === void 0) throw new Error("npm 返回了无法识别的最新版本。");
|
|
78
|
+
const path = resolve(profileDirectory(), "pnpm-workspace.yaml");
|
|
79
|
+
let source;
|
|
80
|
+
try {
|
|
81
|
+
source = await readFile(path, "utf8");
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (error.code !== "ENOENT") throw error;
|
|
84
|
+
source = "";
|
|
85
|
+
}
|
|
86
|
+
const next = applyReleaseExclude(source, packageName, version);
|
|
87
|
+
if (next !== source) await writeFile(path, next, "utf8");
|
|
88
|
+
}
|
|
89
|
+
function versionParts(version) {
|
|
90
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(version);
|
|
91
|
+
return match === null ? void 0 : [
|
|
92
|
+
Number(match[1]),
|
|
93
|
+
Number(match[2]),
|
|
94
|
+
Number(match[3])
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
function newerVersion(installed, latest) {
|
|
98
|
+
const current = versionParts(installed);
|
|
99
|
+
const candidate = versionParts(latest);
|
|
100
|
+
if (current === void 0 || candidate === void 0) return false;
|
|
101
|
+
return candidate[0] > current[0] || candidate[0] === current[0] && candidate[1] > current[1] || candidate[0] === current[0] && candidate[1] === current[1] && candidate[2] > current[2];
|
|
102
|
+
}
|
|
103
|
+
/** 返回 Web profile 中固定管理插件的实际安装版本与 npm latest 状态。 */
|
|
104
|
+
async function dependencyStatuses() {
|
|
105
|
+
const manifest = await profileManifest();
|
|
106
|
+
return Promise.all(MANAGED_DEPENDENCIES.map(async (dependency) => {
|
|
107
|
+
if ((manifest.dependencies?.[dependency.packageName] ?? manifest.devDependencies?.[dependency.packageName]) === void 0) return {
|
|
108
|
+
...dependency,
|
|
109
|
+
installed: false,
|
|
110
|
+
updateAvailable: false
|
|
111
|
+
};
|
|
112
|
+
const version = await installedPackageVersion(dependency.packageName);
|
|
113
|
+
if (version === void 0) return {
|
|
114
|
+
...dependency,
|
|
115
|
+
installed: false,
|
|
116
|
+
updateAvailable: false
|
|
117
|
+
};
|
|
118
|
+
const latestVersion = await npmLatestVersion(dependency.packageName);
|
|
119
|
+
return {
|
|
120
|
+
...dependency,
|
|
121
|
+
installed: true,
|
|
122
|
+
version,
|
|
123
|
+
latestVersion,
|
|
124
|
+
updateAvailable: latestVersion !== void 0 && newerVersion(version, latestVersion)
|
|
125
|
+
};
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 把当前进程的 CLI 入口收成绝对路径。源码启动时 argv[1] 常是相对路径,
|
|
130
|
+
* 若再把 cwd 切到 dirname(entry),子进程会去错误目录找 bin.ts。
|
|
131
|
+
*/
|
|
132
|
+
function resolveDshCliEntry(entry = process.argv[1], cwd = process.cwd()) {
|
|
133
|
+
if (entry === void 0 || entry === "") throw new Error("无法定位 DSH CLI。请从 DSH 命令启动 Web 服务后重试。");
|
|
134
|
+
if (entry.startsWith("file:")) return fileURLToPath(entry);
|
|
135
|
+
return resolve(cwd, entry);
|
|
136
|
+
}
|
|
137
|
+
function pluginCommandError(stderr) {
|
|
138
|
+
const detail = stderr.replace(/\s+/g, " ").trim();
|
|
139
|
+
if (detail.includes("minimumReleaseAge") || detail.includes("Release age")) return /* @__PURE__ */ new Error("更新被 pnpm 发布时间保护拦截。请确认已写入当前版本白名单后重试。");
|
|
140
|
+
if (detail.includes("EPERM") || detail.includes("EBUSY") || detail.includes("EACCES")) return /* @__PURE__ */ new Error("无法覆盖正在运行的插件文件。请先停止 DSH Web,再点击更新。");
|
|
141
|
+
return /* @__PURE__ */ new Error("从 npm 安装或更新依赖失败。请检查网络、npm registry 或发布时间保护后重试。");
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* 复用启动当前服务的 DSH CLI:它会通过 pnpm 从 npm 安装或更新,并自动维护
|
|
145
|
+
* dsh.profile.bundles,避免浏览器端直接管理 profile 文件。
|
|
146
|
+
*/
|
|
147
|
+
function runDshPlugin(args) {
|
|
148
|
+
const entry = resolveDshCliEntry();
|
|
149
|
+
return new Promise((resolvePromise, reject) => {
|
|
150
|
+
const child = spawn(process.execPath, [
|
|
151
|
+
...process.execArgv,
|
|
152
|
+
entry,
|
|
153
|
+
"plugin",
|
|
154
|
+
"--profile",
|
|
155
|
+
"web",
|
|
156
|
+
...args
|
|
157
|
+
], {
|
|
158
|
+
cwd: process.cwd(),
|
|
159
|
+
env: {
|
|
160
|
+
...process.env,
|
|
161
|
+
CI: "true"
|
|
162
|
+
},
|
|
163
|
+
windowsHide: true,
|
|
164
|
+
stdio: [
|
|
165
|
+
"ignore",
|
|
166
|
+
"ignore",
|
|
167
|
+
"pipe"
|
|
168
|
+
]
|
|
169
|
+
});
|
|
170
|
+
let stderr = "";
|
|
171
|
+
child.stderr?.on("data", (chunk) => {
|
|
172
|
+
stderr += String(chunk);
|
|
173
|
+
});
|
|
174
|
+
child.once("error", () => {
|
|
175
|
+
reject(/* @__PURE__ */ new Error("无法启动 DSH 插件安装命令。请确认 Node.js 与 pnpm 可用后重试。"));
|
|
176
|
+
});
|
|
177
|
+
child.once("exit", (code) => {
|
|
178
|
+
code === 0 ? resolvePromise() : reject(pluginCommandError(stderr));
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/** 仅允许安装固定依赖,避免把浏览器输入转成任意命令。 */
|
|
183
|
+
async function installDependency(id) {
|
|
184
|
+
const dependency = managedDependency(id);
|
|
185
|
+
if (dependency === void 0) throw new Error("不支持安装该依赖。");
|
|
186
|
+
const latestVersion = await npmLatestVersion(dependency.packageName);
|
|
187
|
+
if (latestVersion === void 0) throw new Error("无法获取 npm 最新版本,请检查网络或 npm registry 后重试。");
|
|
188
|
+
await ensureLatestReleaseAllowed(dependency.packageName, latestVersion);
|
|
189
|
+
await runDshPlugin(["add", `${dependency.packageName}@${latestVersion}`]);
|
|
190
|
+
const installed = await installedPackageVersion(dependency.packageName);
|
|
191
|
+
if (installed !== latestVersion) throw new Error(`已请求 ${dependency.packageName}@${latestVersion},但当前仍是 ${installed ?? "未安装"}。请先停止 DSH Web 后再更新。`);
|
|
192
|
+
return dependencyStatuses();
|
|
193
|
+
}
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/host-services.ts
|
|
196
|
+
function requireService(ctx, key, method) {
|
|
197
|
+
const service = ctx.get(key);
|
|
198
|
+
if (service === null || typeof service !== "object" || typeof service[method] !== "function") throw new Error(`michengai-codex-ui 需要宿主服务 “${key}.${String(method)}”`);
|
|
199
|
+
return service;
|
|
200
|
+
}
|
|
201
|
+
/** 在唯一的宿主边界校验服务能力;宿主 API 变更时立即失败,不会静默返回 503。 */
|
|
202
|
+
function hostServices(ctx) {
|
|
203
|
+
return {
|
|
204
|
+
webServer: requireService(ctx, "webServer", "register"),
|
|
205
|
+
sessions: requireService(ctx, "sessions", "get"),
|
|
206
|
+
agents: requireService(ctx, "agents", "get"),
|
|
207
|
+
tools: requireService(ctx, "tools", "schemas")
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/index.ts
|
|
212
|
+
const connectorsEndpoint = "/api/michengai/codex-ui/connectors";
|
|
213
|
+
const dependenciesEndpoint = "/api/michengai/codex-ui/dependencies";
|
|
214
|
+
const inject = [
|
|
215
|
+
"webServer",
|
|
216
|
+
"sessions",
|
|
217
|
+
"agents",
|
|
218
|
+
"tools"
|
|
219
|
+
];
|
|
220
|
+
/** 提供不泄露地址、命令和凭证的连接器目录。 */
|
|
221
|
+
function apply(ctx) {
|
|
222
|
+
const host = hostServices(ctx);
|
|
223
|
+
ctx.effect(() => {
|
|
224
|
+
const disposeConnectors = host.webServer.register({
|
|
225
|
+
kind: "exact",
|
|
226
|
+
path: connectorsEndpoint,
|
|
227
|
+
handler: async (request, response) => {
|
|
228
|
+
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
229
|
+
response.writeHead(405);
|
|
230
|
+
response.end();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
const sessionId = new URL(request.url ?? "/", "http://localhost").searchParams.get("sessionId");
|
|
235
|
+
const scope = sessionId === null ? void 0 : host.agents.get(sessionId);
|
|
236
|
+
const connectors = /* @__PURE__ */ new Map();
|
|
237
|
+
for (const tool of host.tools.schemas(scope)) {
|
|
238
|
+
const match = /^mcp__([A-Za-z0-9_-]+?)__(.+)$/.exec(tool.name);
|
|
239
|
+
if (match === null) continue;
|
|
240
|
+
const [, serverName, toolName] = match;
|
|
241
|
+
const tools = connectors.get(serverName) ?? [];
|
|
242
|
+
tools.push({
|
|
243
|
+
name: toolName,
|
|
244
|
+
description: tool.description ?? ""
|
|
245
|
+
});
|
|
246
|
+
connectors.set(serverName, tools);
|
|
247
|
+
}
|
|
248
|
+
const payload = [...connectors].sort(([a], [b]) => a.localeCompare(b)).map(([name, tools]) => ({
|
|
249
|
+
name,
|
|
250
|
+
tools
|
|
251
|
+
}));
|
|
252
|
+
response.writeHead(200, {
|
|
253
|
+
"content-type": "application/json; charset=utf-8",
|
|
254
|
+
"cache-control": "no-store"
|
|
255
|
+
});
|
|
256
|
+
response.end(request.method === "HEAD" ? void 0 : JSON.stringify({ connectors: payload }));
|
|
257
|
+
} catch {
|
|
258
|
+
response.writeHead(503, {
|
|
259
|
+
"content-type": "application/json; charset=utf-8",
|
|
260
|
+
"cache-control": "no-store"
|
|
261
|
+
});
|
|
262
|
+
response.end(JSON.stringify({ error: "连接器目录暂不可用。" }));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
const disposeDependencies = host.webServer.register({
|
|
267
|
+
kind: "exact",
|
|
268
|
+
path: dependenciesEndpoint,
|
|
269
|
+
handler: async (request, response) => {
|
|
270
|
+
const url = new URL(request.url ?? "/", "http://localhost");
|
|
271
|
+
try {
|
|
272
|
+
if (request.method === "GET") {
|
|
273
|
+
const dependencies = await dependencyStatuses();
|
|
274
|
+
response.writeHead(200, {
|
|
275
|
+
"content-type": "application/json; charset=utf-8",
|
|
276
|
+
"cache-control": "no-store"
|
|
277
|
+
});
|
|
278
|
+
response.end(JSON.stringify({ dependencies }));
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (request.method === "POST") {
|
|
282
|
+
const dependencies = await installDependency(url.searchParams.get("dependency"));
|
|
283
|
+
response.writeHead(200, {
|
|
284
|
+
"content-type": "application/json; charset=utf-8",
|
|
285
|
+
"cache-control": "no-store"
|
|
286
|
+
});
|
|
287
|
+
response.end(JSON.stringify({
|
|
288
|
+
dependencies,
|
|
289
|
+
restartRequired: true
|
|
290
|
+
}));
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
response.writeHead(405);
|
|
294
|
+
response.end();
|
|
295
|
+
} catch (error) {
|
|
296
|
+
const message = error instanceof Error ? error.message : "依赖管理暂不可用。";
|
|
297
|
+
response.writeHead(503, {
|
|
298
|
+
"content-type": "application/json; charset=utf-8",
|
|
299
|
+
"cache-control": "no-store"
|
|
300
|
+
});
|
|
301
|
+
response.end(JSON.stringify({ error: message }));
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
return () => {
|
|
306
|
+
disposeConnectors();
|
|
307
|
+
disposeDependencies();
|
|
308
|
+
};
|
|
309
|
+
}, "michengai-codex-ui: catalogs");
|
|
310
|
+
}
|
|
311
|
+
//#endregion
|
|
312
|
+
export { apply, inject };
|
package/package.json
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@michengai/dsh-codex-ui",
|
|
3
|
+
"version": "0.2.48",
|
|
4
|
+
"description": "以 Codex 风格重构 DSH Web 侧栏的独立客户端插件",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public",
|
|
8
|
+
"registry": "https://registry.npmjs.org/"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/MichengAI/dsh-codex-ui.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/MichengAI/dsh-codex-ui/issues"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/MichengAI/dsh-codex-ui#readme",
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "dist/index.mjs",
|
|
20
|
+
"types": "dist/index.d.mts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.mts",
|
|
24
|
+
"default": "./dist/index.mjs"
|
|
25
|
+
},
|
|
26
|
+
"./client": {
|
|
27
|
+
"default": "./dist/client.js"
|
|
28
|
+
},
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"assets",
|
|
34
|
+
"cordis.patch.yml",
|
|
35
|
+
"LICENSE",
|
|
36
|
+
"README.md",
|
|
37
|
+
"README.zh-CN.md"
|
|
38
|
+
],
|
|
39
|
+
"dsh": {
|
|
40
|
+
"bundle": {
|
|
41
|
+
"patch": "./cordis.patch.yml"
|
|
42
|
+
},
|
|
43
|
+
"client": {
|
|
44
|
+
"inject": [
|
|
45
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
46
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
47
|
+
"@deepseek-ai/dsh-client-locale",
|
|
48
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
49
|
+
"@deepseek-ai/dsh-client-ui-settings-general"
|
|
50
|
+
],
|
|
51
|
+
"platform": "web"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsc --noEmit && tsdown",
|
|
56
|
+
"test": "tsx tests/pinned-sessions.assert.ts && tsx tests/session-manager.assert.ts && tsx tests/workspace-browser.assert.ts && tsx tests/sidebar-search.assert.ts && vitest run tests/client-runtime.integration.spec.ts && tsx tests/settings-integration.assert.ts && tsx tests/about-dependencies.assert.ts && tsx tests/dependency-manager.assert.ts && tsx tests/conversation-visuals.assert.ts && tsx tests/client-bundle.assert.ts && tsx tests/codex-suite.assert.ts"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@deepseek-ai/cordis": ">=4.0.1 <5.0.0",
|
|
60
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.0-rc.0 <0.2.0",
|
|
61
|
+
"@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.0 <0.2.0",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.0-rc.0 <0.2.0",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-layout": ">=0.1.0-rc.0 <0.2.0",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.0-rc.0 <0.2.0",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.0-rc.0 <0.2.0",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-settings-general": ">=0.1.0-rc.0 <0.2.0",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-sidebar": ">=0.1.0-rc.0 <0.2.0",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.0-rc.0 <0.2.0",
|
|
69
|
+
"@michengai/dsh-agency-agents": ">=0.1.3 <0.2.0",
|
|
70
|
+
"@michengai/dsh-skills-manager": ">=0.1.7 <0.2.0",
|
|
71
|
+
"react": "^18.2.0"
|
|
72
|
+
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"@michengai/dsh-agency-agents": { "optional": true },
|
|
75
|
+
"@michengai/dsh-skills-manager": { "optional": true }
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@deepseek-ai/cordis": "4.0.1",
|
|
79
|
+
"@deepseek-ai/dsh-client-locale": "0.1.0-rc.6",
|
|
80
|
+
"@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6",
|
|
81
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.1.0-rc.6",
|
|
82
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.0-rc.6",
|
|
83
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.1.0-rc.6",
|
|
84
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.0-rc.6",
|
|
85
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.6",
|
|
86
|
+
"@deepseek-ai/dsh-client-ui-settings-general": "0.1.0-rc.6",
|
|
87
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "0.1.0-rc.6",
|
|
88
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6",
|
|
89
|
+
"@types/node": "^26.0.0",
|
|
90
|
+
"@types/react": "~18.3.1",
|
|
91
|
+
"react": "^18.3.1",
|
|
92
|
+
"react-dom": "^18.3.1",
|
|
93
|
+
"tsdown": "^0.22.2",
|
|
94
|
+
"tsx": "^4.22.4",
|
|
95
|
+
"typescript": "^6.0.3",
|
|
96
|
+
"vitest": "^4.1.8",
|
|
97
|
+
"jsdom": "^29.1.1"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|