@deepseek-ai/dsh-experimental-inspector 0.2.1-alpha.2 → 0.2.1-alpha.4
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.i18n.yaml +2 -2
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/icon.svg +18 -7
- package/lib/index.js +70 -17
- package/lib/types/host/plugin.d.ts +6 -1
- package/lib/worker.js +16 -12
- package/package.json +22 -26
package/README.i18n.yaml
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
en: 6d290aabc543f878
|
|
19
19
|
zh: 7ad283b159ae2c29
|
|
20
20
|
/deepseek-ai-dsh-experimental-inspector/runtime-layout:
|
|
21
|
-
en:
|
|
22
|
-
zh:
|
|
21
|
+
en: 13f495af2fec307d
|
|
22
|
+
zh: ec4bebf24a87ec54
|
|
23
23
|
/deepseek-ai-dsh-experimental-inspector/configuration:
|
|
24
24
|
en: d094842893700446
|
|
25
25
|
zh: 7a7f880ba795948f
|
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ The frontend uses browser runtime adapters and excludes Node-only transports at
|
|
|
48
48
|
<a id="runtime-layout"></a>
|
|
49
49
|
## Runtime layout
|
|
50
50
|
|
|
51
|
-
The Worker never accesses live Cordis objects: the shared Host/Client collector projects them into validated snapshots before transport. Cordis owns plugin composition, `ctx.inspector` registration, bootstrap injection, and disposal. A late-loading Client fetches its bootstrap through an authenticated Host route. Bootstrap transport and source-setup failures warn and retain connection-reset recovery for both injected and fetched startup; invalid bootstrap data or service-registration failures reject startup. Source replacement joins old service-consumer cleanup before claiming another source, and unloading an active plugin cancels its pending bootstrap refresh.
|
|
51
|
+
The Worker never accesses live Cordis objects: the shared Host/Client collector projects them into validated snapshots before transport. Cordis owns plugin composition, `ctx.inspector` registration, bootstrap injection, and disposal. A late-loading Client fetches its bootstrap through an authenticated Host route, which the Host registers before it starts the Worker: a request waits for Worker readiness and then receives the bootstrap, or `503` when startup fails; an aborted request stops waiting. When the platform cannot run the Worker and reports Node's `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM`, such as the browser preview's Worker host, the Host logs one warning and the plugin still starts with only that route, which answers `503`; it provides no `ctx.inspector`, DevTools routes, bootstrap injection, or `devtools://` URL. Any other startup error still rejects the plugin. Bootstrap transport and source-setup failures warn and retain connection-reset recovery for both injected and fetched startup; invalid bootstrap data or service-registration failures reject startup. Source replacement joins old service-consumer cleanup before claiming another source, and unloading an active plugin cancels its pending bootstrap refresh.
|
|
52
52
|
|
|
53
53
|
The Host plugin starts the Worker and connects a dedicated `MessagePort`. The Client uses injected or fetched browser-source parameters to open an authenticated WebSocket directly to the Worker; it receives no DevTools URL. Chrome DevTools connects to the Worker's CDP WebSocket. A private `node:inspector.Session` per DevTools connection attaches from the Worker to the Host main thread, so Host debugging remains available while Host JavaScript is paused.
|
|
54
54
|
|
package/README.zh.md
CHANGED
|
@@ -48,7 +48,7 @@ Host 在相对于应用根目录的 `inspector/devtools/devtools_app.html` 路
|
|
|
48
48
|
<a id="runtime-layout"></a>
|
|
49
49
|
## 运行时布局
|
|
50
50
|
|
|
51
|
-
Worker 不访问实时 Cordis 对象;共享 Host/Client collector 会在传输前把它们投影成已验证快照。Cordis 负责插件组合、注册 `ctx.inspector`、注入 bootstrap 和 dispose(资源释放)。后加载的 Client 通过已鉴权的 Host 路由获取 bootstrap
|
|
51
|
+
Worker 不访问实时 Cordis 对象;共享 Host/Client collector 会在传输前把它们投影成已验证快照。Cordis 负责插件组合、注册 `ctx.inspector`、注入 bootstrap 和 dispose(资源释放)。后加载的 Client 通过已鉴权的 Host 路由获取 bootstrap。Host 在启动 Worker 之前注册该路由,请求会等到 Worker 就绪后返回 bootstrap,启动失败时返回 `503`;请求中止时立即停止等待。当前平台无法运行 Worker 并报告 Node 的 `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM` 时(例如浏览器预览的 Worker host),Host 记录一条警告,插件仍照常启动,只保留该路由并返回 `503`,不提供 `ctx.inspector`、DevTools 路由、bootstrap 注入或 `devtools://` URL;其他任何启动错误仍使插件启动失败。初始注入与主动获取两条路径中,bootstrap 传输或 source 建立失败均记录警告并保留连接重置后的重试;bootstrap 数据非法或服务注册失败则使启动失败。替换 source 会等待旧服务消费者清理完成,再申请新 source;卸载已激活插件会取消其未完成的 bootstrap 刷新。
|
|
52
52
|
|
|
53
53
|
Host 插件启动 Worker 并连接专用 `MessagePort`。Client 使用注入或主动获取的浏览器 source 参数,直接向 Worker 打开带鉴权的 WebSocket,不接收 DevTools URL。Chrome DevTools 连接 Worker 的 CDP WebSocket。每条 DevTools 连接在 Worker 中独占一个连接 Host 主线程的 `node:inspector.Session`,因此 Host JavaScript 暂停时仍可调试 Host。
|
|
54
54
|
|
package/icon.svg
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<g mask="url(#data-lens-cutout)">
|
|
3
|
+
<rect x="11" y="7" width="16" height="16" rx="2" fill="#7FB7FC" fill-opacity="0.55" />
|
|
4
|
+
<rect x="7" y="11" width="17" height="15" rx="2" fill="url(#data-panel)" />
|
|
5
|
+
<path d="M10 15H18M10 18H15" stroke="#FFFFFF" stroke-width="1.5" />
|
|
6
|
+
</g>
|
|
7
|
+
<path d="M26 26L30 30" stroke="#658EFF" stroke-width="3" />
|
|
8
|
+
<circle cx="23" cy="23" r="4.5" stroke="url(#data-lens)" stroke-width="2.5" />
|
|
6
9
|
<defs>
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
+
<mask id="data-lens-cutout" maskUnits="userSpaceOnUse" x="0" y="0" width="36" height="36">
|
|
11
|
+
<rect width="36" height="36" fill="#FFFFFF" />
|
|
12
|
+
<circle cx="23" cy="23" r="3.25" fill="#000000" />
|
|
13
|
+
</mask>
|
|
14
|
+
<linearGradient id="data-panel" x1="9" y1="11" x2="23" y2="26" gradientUnits="userSpaceOnUse">
|
|
15
|
+
<stop stop-color="#6DB9FB" />
|
|
16
|
+
<stop offset="1" stop-color="#3650DE" />
|
|
17
|
+
</linearGradient>
|
|
18
|
+
<linearGradient id="data-lens" x1="19" y1="19" x2="27" y2="27" gradientUnits="userSpaceOnUse">
|
|
19
|
+
<stop stop-color="#45D9E7" />
|
|
20
|
+
<stop offset="1" stop-color="#67C7FE" />
|
|
10
21
|
</linearGradient>
|
|
11
22
|
</defs>
|
|
12
23
|
</svg>
|
package/lib/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { connect } from "node:net";
|
|
4
|
-
import serveStatic from "serve-static";
|
|
5
|
-
import open, { apps } from "open";
|
|
6
4
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
7
5
|
import { tmpdir } from "node:os";
|
|
8
6
|
import { MessageChannel, Worker } from "node:worker_threads";
|
|
@@ -2369,14 +2367,38 @@ async function disposeInspectorResources(disposers, close, message) {
|
|
|
2369
2367
|
//#region lib/types/host/plugin.js
|
|
2370
2368
|
/** Host Cordis plugin for the cross-realm Inspector Worker and full fetch capture. */
|
|
2371
2369
|
const DEVTOOLS_PATH = "/inspector/devtools";
|
|
2372
|
-
/**
|
|
2370
|
+
/** Node's standard code for a feature the running platform cannot provide, such as `worker_threads` in a browser Worker host. */
|
|
2371
|
+
const FEATURE_UNAVAILABLE_ON_PLATFORM = "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM";
|
|
2372
|
+
/**
|
|
2373
|
+
* Start the Worker, expose `ctx.inspector`, and inject the matching Client bootstrap.
|
|
2374
|
+
* The bootstrap route exists before the Worker is ready, so a Client published during startup waits instead of failing.
|
|
2375
|
+
* When the platform cannot run the Worker (`ERR_FEATURE_UNAVAILABLE_ON_PLATFORM`), the plugin warns once and stays active
|
|
2376
|
+
* with only that route, which answers 503; every other startup failure rolls back and rejects the fiber.
|
|
2377
|
+
*/
|
|
2373
2378
|
async function apply$1(ctx, config) {
|
|
2374
2379
|
await ctx.effect(async () => {
|
|
2375
2380
|
const spec = resolveInspectorOptions(config);
|
|
2376
|
-
const
|
|
2381
|
+
const ready = Promise.withResolvers();
|
|
2377
2382
|
const disposers = [];
|
|
2378
|
-
|
|
2383
|
+
let worker;
|
|
2384
|
+
const dispose = () => disposeInspectorResources(disposers, () => worker?.close(), "experimental-inspector: disposal failed");
|
|
2379
2385
|
try {
|
|
2386
|
+
disposers.push(ctx.connection.fetch.register({
|
|
2387
|
+
path: INSPECTOR_BOOTSTRAP_PATH,
|
|
2388
|
+
methods: ["GET"],
|
|
2389
|
+
requestBody: "buffered",
|
|
2390
|
+
fetch: (request) => bootstrapResponse(ready.promise, request.signal)
|
|
2391
|
+
}));
|
|
2392
|
+
const handle = await startInspector(spec).catch((error) => {
|
|
2393
|
+
if (!isUnavailableOnPlatform(error)) throw error;
|
|
2394
|
+
ctx.logger.warn("experimental-inspector: NodeJS Inspector is unavailable on this platform; Host inspection stays disabled", error);
|
|
2395
|
+
});
|
|
2396
|
+
if (handle === void 0) {
|
|
2397
|
+
ready.resolve(void 0);
|
|
2398
|
+
return dispose;
|
|
2399
|
+
}
|
|
2400
|
+
worker = handle;
|
|
2401
|
+
const { default: serveStatic } = await import("serve-static");
|
|
2380
2402
|
disposers.push(publishCordisTree(ctx, handle.source, {
|
|
2381
2403
|
maxNodes: spec.maxCordisNodes,
|
|
2382
2404
|
maxBytes: spec.maxSourceFrameBytes - 4096
|
|
@@ -2389,12 +2411,6 @@ async function apply$1(ctx, config) {
|
|
|
2389
2411
|
value: handle.endpoint.client
|
|
2390
2412
|
});
|
|
2391
2413
|
}));
|
|
2392
|
-
disposers.push(ctx.connection.fetch.register({
|
|
2393
|
-
path: INSPECTOR_BOOTSTRAP_PATH,
|
|
2394
|
-
methods: ["GET"],
|
|
2395
|
-
requestBody: "buffered",
|
|
2396
|
-
fetch: () => Promise.resolve(Response.json(handle.endpoint.client, { headers: { "cache-control": "no-store" } }))
|
|
2397
|
-
}));
|
|
2398
2414
|
const assets = serveStatic(fileURLToPath(new URL("./lib/devtools/", import.meta.resolve("@deepseek-ai/dsh-experimental-inspector/package.json"))), {
|
|
2399
2415
|
index: false,
|
|
2400
2416
|
redirect: false,
|
|
@@ -2484,13 +2500,18 @@ async function apply$1(ctx, config) {
|
|
|
2484
2500
|
}
|
|
2485
2501
|
}));
|
|
2486
2502
|
console.log(`dsh inspector: ${handle.endpoint.devtoolsFrontendUrl}`);
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2503
|
+
ready.resolve(handle.endpoint.client);
|
|
2504
|
+
if (ctx.get("cmdlineArgs")?.get().includes("--inspect")) {
|
|
2505
|
+
const { default: open, apps } = await import("open");
|
|
2506
|
+
await open(handle.endpoint.devtoolsFrontendUrl, {
|
|
2507
|
+
app: { name: apps.chrome },
|
|
2508
|
+
wait: false
|
|
2509
|
+
}).catch((error) => {
|
|
2510
|
+
ctx.logger.error("experimental-inspector: Chrome could not open DevTools", error);
|
|
2511
|
+
});
|
|
2512
|
+
}
|
|
2493
2513
|
} catch (error) {
|
|
2514
|
+
ready.resolve(void 0);
|
|
2494
2515
|
await dispose().catch((cleanupError) => {
|
|
2495
2516
|
ctx.logger.error("experimental-inspector: initialization rollback failed", cleanupError);
|
|
2496
2517
|
});
|
|
@@ -2499,6 +2520,38 @@ async function apply$1(ctx, config) {
|
|
|
2499
2520
|
return dispose;
|
|
2500
2521
|
}, "experimental-inspector: Host Worker");
|
|
2501
2522
|
}
|
|
2523
|
+
/**
|
|
2524
|
+
* Report whether a Worker startup failure means this platform cannot run the Inspector at all.
|
|
2525
|
+
* @param error - Rejection from {@link startInspector}.
|
|
2526
|
+
* @returns True only for Node's `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM` code; messages are never inspected.
|
|
2527
|
+
*/
|
|
2528
|
+
function isUnavailableOnPlatform(error) {
|
|
2529
|
+
return error instanceof Error && "code" in error && error.code === FEATURE_UNAVAILABLE_ON_PLATFORM;
|
|
2530
|
+
}
|
|
2531
|
+
/**
|
|
2532
|
+
* Answer one bootstrap request once Host initialization settles or the browser abandons the request.
|
|
2533
|
+
* @param ready - Resolves with the Client bootstrap, or with undefined after initialization failed or found the platform unavailable.
|
|
2534
|
+
* @param signal - Request signal; an aborted request stops waiting and receives no endpoint.
|
|
2535
|
+
* @returns The bootstrap JSON, or 503 when the Inspector is unavailable or the request was aborted.
|
|
2536
|
+
*/
|
|
2537
|
+
async function bootstrapResponse(ready, signal) {
|
|
2538
|
+
const headers = { "cache-control": "no-store" };
|
|
2539
|
+
const abandoned = Promise.withResolvers();
|
|
2540
|
+
const abandon = () => {
|
|
2541
|
+
abandoned.resolve(void 0);
|
|
2542
|
+
};
|
|
2543
|
+
if (signal.aborted) abandon();
|
|
2544
|
+
else signal.addEventListener("abort", abandon, { once: true });
|
|
2545
|
+
try {
|
|
2546
|
+
const client = await Promise.race([ready, abandoned.promise]);
|
|
2547
|
+
return client === void 0 ? new Response(null, {
|
|
2548
|
+
status: 503,
|
|
2549
|
+
headers
|
|
2550
|
+
}) : Response.json(client, { headers });
|
|
2551
|
+
} finally {
|
|
2552
|
+
signal.removeEventListener("abort", abandon);
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2502
2555
|
//#endregion
|
|
2503
2556
|
//#region lib/types/index.js
|
|
2504
2557
|
/** Repository-facing Host package entry over the mirrored implementation tree. */
|
|
@@ -14,6 +14,11 @@ export interface HostPluginConfig extends Omit<InspectorOptions, 'clientOrigins'
|
|
|
14
14
|
/** Browser origins allowed to open the Client ingest WebSocket. */
|
|
15
15
|
clientOrigins?: string[];
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Start the Worker, expose `ctx.inspector`, and inject the matching Client bootstrap.
|
|
19
|
+
* The bootstrap route exists before the Worker is ready, so a Client published during startup waits instead of failing.
|
|
20
|
+
* When the platform cannot run the Worker (`ERR_FEATURE_UNAVAILABLE_ON_PLATFORM`), the plugin warns once and stays active
|
|
21
|
+
* with only that route, which answers 503; every other startup failure rolls back and rejects the fiber.
|
|
22
|
+
*/
|
|
18
23
|
export declare function apply(ctx: Context, config: HostPluginConfig): Promise<void>;
|
|
19
24
|
//# sourceMappingURL=plugin.d.ts.map
|
package/lib/worker.js
CHANGED
|
@@ -7272,18 +7272,22 @@ controlPort.on("message", (message) => {
|
|
|
7272
7272
|
});
|
|
7273
7273
|
}
|
|
7274
7274
|
});
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7275
|
+
/** Start the Worker server and report readiness, or report the failure and stop. */
|
|
7276
|
+
async function main() {
|
|
7277
|
+
try {
|
|
7278
|
+
runtime = await startInspectorWorker(boot);
|
|
7279
|
+
controlPort.postMessage({
|
|
7280
|
+
type: "ready",
|
|
7281
|
+
...runtime.endpoint
|
|
7282
|
+
});
|
|
7283
|
+
} catch (error) {
|
|
7284
|
+
controlPort.postMessage({
|
|
7285
|
+
type: "failure",
|
|
7286
|
+
message: error instanceof Error ? error.message : String(error)
|
|
7287
|
+
});
|
|
7288
|
+
await stop();
|
|
7289
|
+
}
|
|
7287
7290
|
}
|
|
7291
|
+
main();
|
|
7288
7292
|
//#endregion
|
|
7289
7293
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-experimental-inspector",
|
|
3
3
|
"description": "Experimental cross-realm CDP hub for Host debugging and Client Runtime inspection",
|
|
4
|
-
"version": "0.2.1-alpha.
|
|
4
|
+
"version": "0.2.1-alpha.4",
|
|
5
5
|
"icon": "./icon.svg",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -46,43 +46,39 @@
|
|
|
46
46
|
],
|
|
47
47
|
"license": "MIT",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@deepseek-ai/dsh-app-boot": "0.2.1-alpha.
|
|
50
|
-
"@deepseek-ai/dsh-
|
|
51
|
-
"@deepseek-ai/
|
|
52
|
-
"@deepseek-ai/schemastery": "~3.18.5-alpha.1",
|
|
49
|
+
"@deepseek-ai/dsh-app-boot": "0.2.1-alpha.4",
|
|
50
|
+
"@deepseek-ai/dsh-util-crypto": "0.2.1-alpha.4",
|
|
51
|
+
"@deepseek-ai/schemastery": "~3.18.5-alpha.2",
|
|
53
52
|
"open": "^11.0.2",
|
|
54
53
|
"serve-static": "^2.2.1",
|
|
55
54
|
"ws": "^8.21.3"
|
|
56
55
|
},
|
|
57
56
|
"peerDependencies": {
|
|
58
|
-
"@deepseek-ai/cordis": "~4.0.5-alpha.
|
|
59
|
-
"@deepseek-ai/cordis-plugin-loader": "~1.0.6-alpha.1",
|
|
60
|
-
"@deepseek-ai/dsh-client-modules": "0.2.1-alpha.2",
|
|
61
|
-
"@deepseek-ai/dsh-client-connection": "0.2.1-alpha.2",
|
|
62
|
-
"@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.2"
|
|
57
|
+
"@deepseek-ai/cordis": "~4.0.5-alpha.2"
|
|
63
58
|
},
|
|
64
59
|
"devDependencies": {
|
|
65
60
|
"chrome-devtools-frontend": "1.0.1638082",
|
|
66
61
|
"@types/serve-static": "^2.2.0",
|
|
67
|
-
"@deepseek-ai/dsh-client-test-runtime": "0.2.1-alpha.
|
|
62
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.2.1-alpha.4",
|
|
68
63
|
"@testing-library/react": "^16.3.3",
|
|
69
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-alpha.
|
|
70
|
-
"@
|
|
71
|
-
"@deepseek-ai/dsh-client-
|
|
72
|
-
"@deepseek-ai/dsh-client-
|
|
73
|
-
"@deepseek-ai/dsh-client-
|
|
74
|
-
"@deepseek-ai/dsh-client-ui-
|
|
75
|
-
"@deepseek-ai/dsh-client-
|
|
76
|
-
"@deepseek-ai/dsh-client-locale": "0.2.1-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-alpha.4",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.2.1-alpha.4",
|
|
66
|
+
"@deepseek-ai/dsh-client-shortcuts": "0.2.1-alpha.4",
|
|
67
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-alpha.4",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-alpha.4",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-alpha.4",
|
|
70
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-alpha.4",
|
|
77
71
|
"react": "^18.2.0",
|
|
78
|
-
"@deepseek-ai/cordis": "~4.0.5-alpha.
|
|
79
|
-
"@deepseek-ai/cordis-plugin-include": "~1.0.10-alpha.
|
|
80
|
-
"@deepseek-ai/cordis-plugin-loader": "~1.0.6-alpha.
|
|
81
|
-
"@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.
|
|
82
|
-
"@deepseek-ai/dsh-cmdline": "0.2.1-alpha.
|
|
83
|
-
"@deepseek-ai/dsh-client-connection": "0.2.1-alpha.
|
|
72
|
+
"@deepseek-ai/cordis": "~4.0.5-alpha.2",
|
|
73
|
+
"@deepseek-ai/cordis-plugin-include": "~1.0.10-alpha.2",
|
|
74
|
+
"@deepseek-ai/cordis-plugin-loader": "~1.0.6-alpha.2",
|
|
75
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.4",
|
|
76
|
+
"@deepseek-ai/dsh-cmdline": "0.2.1-alpha.4",
|
|
77
|
+
"@deepseek-ai/dsh-client-connection": "0.2.1-alpha.4",
|
|
84
78
|
"@types/ws": "^8.18.1",
|
|
85
79
|
"playwright": "^1.49.0",
|
|
86
|
-
"tsx": "^4.23.13"
|
|
80
|
+
"tsx": "^4.23.13",
|
|
81
|
+
"@deepseek-ai/dsh-brand": "0.2.1-alpha.4",
|
|
82
|
+
"@deepseek-ai/dsh-client-modules": "0.2.1-alpha.4"
|
|
87
83
|
}
|
|
88
84
|
}
|