From e478b680850ff0f5ee4bb26b9413f103f46bfd20 Mon Sep 17 00:00:00 2001 From: jinliyl <6469360+jinliyl@users.noreply.github.com> Date: Fri, 16 Oct 2026 11:32:38 +0800 Subject: [PATCH] fix(dsh): support 0.2.0 RC and current Harness settings (#629) --- integrations/dsh/README.md | 10 +- integrations/dsh/README_ZH.md | 8 +- integrations/dsh/package-lock.json | 795 ++++++++---------- integrations/dsh/package.json | 38 +- integrations/dsh/scripts/test-package.mjs | 170 +++- integrations/dsh/src/client/index.tsx | 256 +++--- integrations/dsh/src/client/styles.ts | 10 +- integrations/dsh/src/index.ts | 2 + integrations/dsh/tests/bundle.test.mjs | 34 +- .../dsh/tests/client-settings.test.mjs | 193 +++++ tests/unit/test_package_versions.py | 2 +- 11 files changed, 834 insertions(+), 684 deletions(-) create mode 100644 integrations/dsh/tests/client-settings.test.mjs diff --git a/integrations/dsh/README.md b/integrations/dsh/README.md index c18dc6f7..d84c4bf6 100644 --- a/integrations/dsh/README.md +++ b/integrations/dsh/README.md @@ -4,7 +4,7 @@ This guide explains how to install, configure, and use `@agentscope-ai/reme-dsh-plugin` with DeepSeek Harness (DSH), including memory guidance injection, the `reme_search` tool, automatic memory, daily consolidation, and the ReMe Status page. -The screenshots record an earlier local integration test against DSH `0.1.5-rc.2`; the current compatibility target is `0.1.7-rc.2`. Both the interface and ReMe guidance are set to English, and the isolated DSH and ReMe workspaces contain only fictional Project Aurora data. No `.env` values, API keys, access tokens, or personal memories appear in the screenshots. +The screenshots record an earlier local integration test against DSH `0.1.5-rc.2`; the supported releases are `0.1.7-rc.2`, `0.2.0-rc.2`, `0.2.1-alpha.2`, and `0.2.1-alpha.4`. Both the interface and ReMe guidance are set to English, and the isolated DSH and ReMe workspaces contain only fictional Project Aurora data. No `.env` values, API keys, access tokens, or personal memories appear in the screenshots. ## 1. How the plugin works @@ -26,12 +26,14 @@ The DSH adapter injects **usage guidance**, not every historical memory. Relevan ## 2. Requirements - ReMe is installed and its configuration exposes the `search`, `auto_memory`, and `auto_dream` jobs. -- DeepSeek Harness `0.1.7-rc.2`. +- DeepSeek Harness `0.1.7-rc.2`, `0.2.0-rc.2`, `0.2.1-alpha.2`, or `0.2.1-alpha.4`. - Node.js `^22.19.0` or `>=24.0.0`, matching the current DSH engine range. - The browser running DSH can reach the configured ReMe HTTP endpoint. Cross-machine deployments must also allow the DSH browser origin. The default ReMe endpoint is `http://127.0.0.1:2333`. ReMe HTTP does not use API-key authentication, so do not expose it directly to an untrusted network. +Peer ranges cover the tested prerelease lines and compatible stable `0.1.x` / `0.2.x` releases. Other prerelease lines require validation before being added; `0.3.x` is excluded. + ## 3. Install and start This package replaces the former `@agentscope-ai/reme/dsh` entry. Remove the combined package before installing the new @@ -100,11 +102,11 @@ Declare the route with `api: openai-completions`, select `LLM_MODEL_NAME` (or an ## 4. Configure ReMe Memory -Open **Plugins → ReMe Memory**. Save changes before starting the next session. Settings are stored in the active DSH profile patch and apply to subsequent requests and captures. A language change affects new sessions; a schedule change immediately reschedules the next consolidation. +Open **Plugins → ReMe bundle → reme-memory → Configure**. Save submits all edits together as one revision-checked atomic update. Save changes before starting the next session. Settings are stored in the active DSH profile patch and apply to subsequent requests and captures. A language change affects new sessions; a schedule change immediately reschedules the next consolidation. On upgrade from the old `settings.yaml`, DSH imports its `reme-memory` section into the ReMe runtime entry. If a profile patch explicitly targets the former `reme-memory-runtime` entry, change that entry ID to `reme-memory`; the enclosing group is now `reme-memory-scope`. -If an earlier upgrade already renamed `settings.yaml` to `settings.yaml.imported` while ReMe's import failed, DSH will not retry that file. Open `settings.yaml.imported` in the DSH home directory, find its `reme-memory` section, and compare those fields with **Plugins → ReMe Memory** in each affected profile. Copy the old values you still want into the form and save; keep any newer profile values. In particular, check `endpoint`, `autoMemoryEnabled`, and `autoDreamEnabled` before using the plugin. Do not rename the backup back to `settings.yaml`, since that would retry imports for unrelated sections too. +If an earlier upgrade already renamed `settings.yaml` to `settings.yaml.imported` while ReMe's import failed, DSH will not retry that file. Open `settings.yaml.imported` in the DSH home directory, find its `reme-memory` section, and compare those fields with **Plugins → ReMe bundle → reme-memory → Configure** in each affected profile. Copy the old values you still want into the form and save; keep any newer profile values. In particular, check `endpoint`, `autoMemoryEnabled`, and `autoDreamEnabled` before using the plugin. Do not rename the backup back to `settings.yaml`, since that would retry imports for unrelated sections too. ![ReMe Memory plugin configuration](./figures/reme-memory-settings.png) diff --git a/integrations/dsh/README_ZH.md b/integrations/dsh/README_ZH.md index 873fa2eb..08262b95 100644 --- a/integrations/dsh/README_ZH.md +++ b/integrations/dsh/README_ZH.md @@ -26,12 +26,14 @@ DSH 启动新会话时,插件向根 Agent 注入一段“如何使用长期记 ## 2. 环境要求 - ReMe Python 服务已安装,且配置中提供 `search`、`auto_memory` 和 `auto_dream` Job。 -- DeepSeek Harness `0.1.7-rc.2`。 +- DeepSeek Harness `0.1.7-rc.2`、`0.2.0-rc.2`、`0.2.1-alpha.2` 或 `0.2.1-alpha.4`。 - Node.js `^22.19.0` 或 `>=24.0.0`,与当前 DSH 的 engine 范围一致。 - DSH 页面能够访问 ReMe HTTP 地址;跨机器部署时还要允许 DSH 页面所在的浏览器 Origin。 ReMe HTTP 服务默认监听 `http://127.0.0.1:2333`,不使用 API Key 认证。因此不建议未经网络隔离直接暴露到公网。 +peer 范围覆盖已测试的预发布系列及兼容的 `0.1.x` / `0.2.x` 正式版本;其他预发布系列需验证后再加入,不包含 `0.3.x`。 + ## 3. 安装与启动 本包替代原来的 `@agentscope-ai/reme/dsh` 入口。安装新的宿主专用插件前,请先移除旧的组合包。 @@ -103,11 +105,11 @@ dsh web --no-open --port 3090 ## 4. ReMe Memory 配置 -进入 **插件 → ReMe Memory**。修改后点击保存;设置存入当前 DSH profile patch,并从后续请求或捕获开始生效。修改 `language` 只影响之后创建的新会话,修改每日计划会重新安排下一次整理。 +进入 **插件 → ReMe 插件包 → reme-memory → 配置**。修改后点击保存,全部字段会作为一次带版本校验的原子更新提交;设置存入当前 DSH profile patch,并从后续请求或捕获开始生效。修改 `language` 只影响之后创建的新会话,修改每日计划会重新安排下一次整理。 从旧版 `settings.yaml` 升级时,DSH 会将其中的 `reme-memory` 设置导入 ReMe 运行条目。如果 profile patch 显式指定了原来的 `reme-memory-runtime` 条目,需要将该条目 ID 改为 `reme-memory`;外层 group 现为 `reme-memory-scope`。 -如果此前升级已将 `settings.yaml` 改名为 `settings.yaml.imported`,但当时 ReMe 设置导入失败,DSH 不会再次导入这个文件。请打开 DSH home 目录中的 `settings.yaml.imported`,找到 `reme-memory` 段,并与每个受影响 profile 的 **插件 → ReMe Memory** 当前设置逐项比较。只将仍需保留的旧值填入表单并保存,保留更新后的 profile 设置。使用插件前尤其要核对 `endpoint`、`autoMemoryEnabled` 和 `autoDreamEnabled`。不要把备份文件改回 `settings.yaml`,否则其他 section 也会再次导入。 +如果此前升级已将 `settings.yaml` 改名为 `settings.yaml.imported`,但当时 ReMe 设置导入失败,DSH 不会再次导入这个文件。请打开 DSH home 目录中的 `settings.yaml.imported`,找到 `reme-memory` 段,并与每个受影响 profile 的 **插件 → ReMe 插件包 → reme-memory → 配置** 当前设置逐项比较。只将仍需保留的旧值填入表单并保存,保留更新后的 profile 设置。使用插件前尤其要核对 `endpoint`、`autoMemoryEnabled` 和 `autoDreamEnabled`。不要把备份文件改回 `settings.yaml`,否则其他 section 也会再次导入。 ![ReMe Memory 插件配置](./figures/reme-memory-settings.png) diff --git a/integrations/dsh/package-lock.json b/integrations/dsh/package-lock.json index 3557a7e4..925ab455 100644 --- a/integrations/dsh/package-lock.json +++ b/integrations/dsh/package-lock.json @@ -1,22 +1,26 @@ { "name": "@agentscope-ai/reme-dsh-plugin", - "version": "0.1.1", + "version": "0.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@agentscope-ai/reme-dsh-plugin", - "version": "0.1.1", + "version": "0.1.2", "license": "Apache-2.0", "devDependencies": { - "@deepseek-ai/cordis": "4.0.4", - "@deepseek-ai/cordis-plugin-loader": "1.0.5", - "@deepseek-ai/dsh-agent": "0.1.7-rc.2", - "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-tools": "0.1.7-rc.2", - "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", - "@deepseek-ai/schemastery": "3.18.4", + "@deepseek-ai/cordis": "4.0.5-alpha.2", + "@deepseek-ai/cordis-plugin-loader": "1.0.6-alpha.2", + "@deepseek-ai/dsh-agent": "0.2.1-alpha.4", + "@deepseek-ai/dsh-client-ui-primitives": "0.2.1-alpha.4", + "@deepseek-ai/dsh-client-ui-settings": "0.2.1-alpha.4", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-sandbox": "0.2.1-alpha.4", + "@deepseek-ai/dsh-scope": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session": "0.2.1-alpha.4", + "@deepseek-ai/dsh-tools": "0.2.1-alpha.4", + "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.4", + "@deepseek-ai/schemastery": "3.18.5-alpha.2", "@eslint/js": "9.39.4", "@types/node": "^22.15.0", "@types/react": "~18.3.1", @@ -26,6 +30,8 @@ "globals": "16.4.0", "prettier": "3.0.0", "react": "^18.2.0", + "react-test-renderer": "^18.3.1", + "semver": "^7.8.5", "typescript": "^5.9.2", "typescript-eslint": "8.59.3" }, @@ -33,12 +39,12 @@ "node": "^22.19.0 || >=24.0.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-tools": "0.1.7-rc.2", - "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", - "@deepseek-ai/schemastery": "~3.18.4" + "@deepseek-ai/cordis": "~4.0.4 || ^4.0.5-alpha.1", + "@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2 || ^0.2.0-rc.2 || ^0.2.1-alpha.2", + "@deepseek-ai/dsh-llm": "^0.1.7-rc.2 || ^0.2.0-rc.2 || ^0.2.1-alpha.2", + "@deepseek-ai/dsh-tools": "^0.1.7-rc.2 || ^0.2.0-rc.2 || ^0.2.1-alpha.2", + "@deepseek-ai/dsh-typert-protocol": "^0.1.7-rc.2 || ^0.2.0-rc.2 || ^0.2.1-alpha.2", + "@deepseek-ai/schemastery": "~3.18.4 || ^3.18.5-alpha.1" }, "peerDependenciesMeta": { "@deepseek-ai/cordis": { @@ -244,14 +250,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", - "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.10.tgz", + "integrity": "sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==", "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.29.7", - "@babel/types": "^7.29.7" + "@babel/types": "^7.29.8" }, "engines": { "node": ">=6.9.0" @@ -289,16 +295,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", - "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.10.tgz", + "integrity": "sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.8", "@babel/helper-globals": "^7.29.7", - "@babel/parser": "^7.29.8", + "@babel/parser": "^7.29.9", "@babel/template": "^7.29.7", "@babel/types": "^7.29.8", "debug": "^4.3.1" @@ -322,21 +328,21 @@ } }, "node_modules/@deepseek-ai/cordis": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@deepseek-ai/cordis/-/cordis-4.0.4.tgz", - "integrity": "sha512-obgyxqWAmFn3Re8kvsuUnyW+ihrz6eJCnJO4fh1cQzDtmPYz/zzVeUkH9R94I0OwSVOocK67Kgakm04j/oQXzg==", + "version": "4.0.5-alpha.2", + "resolved": "https://registry.npmjs.org/@deepseek-ai/cordis/-/cordis-4.0.5-alpha.2.tgz", + "integrity": "sha512-rd5Qp6PNrMk+0saWVMLUaVv08s/WBwf2TXM84ST6tppFqlHS0Yl9l/NwPrA4oVOuS/1BKCYOGlZ6zJRj+JG6IQ==", "dev": true, "license": "MIT", "dependencies": { - "@deepseek-ai/cosmokit": "~1.8.5", + "@deepseek-ai/cosmokit": "~1.8.6-alpha.2", "@standard-schema/spec": "^1.1.0" }, "bin": { "cordis": "bin.js" }, "peerDependencies": { - "@deepseek-ai/cordis-plugin-include": "~1.0.9", - "@deepseek-ai/cordis-plugin-loader": "~1.0.5" + "@deepseek-ai/cordis-plugin-include": "~1.0.10-alpha.2", + "@deepseek-ai/cordis-plugin-loader": "~1.0.6-alpha.2" }, "peerDependenciesMeta": { "@deepseek-ai/cordis-plugin-include": { @@ -347,36 +353,19 @@ } } }, - "node_modules/@deepseek-ai/cordis-plugin-include": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@deepseek-ai/cordis-plugin-include/-/cordis-plugin-include-1.0.9.tgz", - "integrity": "sha512-Xmekm7u5Kpeym6nABL4T1/Mg6aQYFZxsipB0WycmCctvX1DqAv8nCFwRmg2XMx/f7EbZgNEbXQwJfabcMu8zxQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@deepseek-ai/cosmokit": "~1.8.5", - "js-yaml": "^4.1.0" - }, - "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/cordis-plugin-loader": "~1.0.5" - } - }, "node_modules/@deepseek-ai/cordis-plugin-loader": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@deepseek-ai/cordis-plugin-loader/-/cordis-plugin-loader-1.0.5.tgz", - "integrity": "sha512-200huL2ttWcjyeYllvPYn+qMR7I89qy8MhZasbHltPzB/KMrSfsyoCYKdCGc5KqPGj5iJugcmibQzjINMO9I+Q==", + "version": "1.0.6-alpha.2", + "resolved": "https://registry.npmjs.org/@deepseek-ai/cordis-plugin-loader/-/cordis-plugin-loader-1.0.6-alpha.2.tgz", + "integrity": "sha512-ea4WjgWsrUxVJ0UYujTbGgaSIR/mV46myY/s6isYRTQRCmlkyVPGagkTxrRR2c/MqGwwbC4KXxusT4uM7H9BXg==", "dev": true, "license": "MIT", "dependencies": { - "@deepseek-ai/cosmokit": "~1.8.5", - "@deepseek-ai/schemastery": "~3.18.4" + "@deepseek-ai/cosmokit": "~1.8.6-alpha.2", + "@deepseek-ai/schemastery": "~3.18.5-alpha.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "node-addon-require-builtin": "^0.1.6" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "node-addon-require-builtin": "^0.1.9" }, "peerDependenciesMeta": { "node-addon-require-builtin": { @@ -385,29 +374,28 @@ } }, "node_modules/@deepseek-ai/cosmokit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@deepseek-ai/cosmokit/-/cosmokit-1.8.5.tgz", - "integrity": "sha512-LXsrlem9z8dq4sLflj2yuCuYX7KqhdzF5hZly3eZyuTo8d6oDSOXuEgC5DbQWKW+lksm6zmOutQLsP/ma6wR6A==", + "version": "1.8.6-alpha.2", + "resolved": "https://registry.npmjs.org/@deepseek-ai/cosmokit/-/cosmokit-1.8.6-alpha.2.tgz", + "integrity": "sha512-FcxdMUal80CeFURh3lPYsw9TPDMVSGpovWnA3JtTGrBG15XFli4k38z1Egso1lgvifKpIW4Hx42X6UTelLEOAA==", "dev": true, "license": "MIT" }, "node_modules/@deepseek-ai/dsh-agent": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-agent/-/dsh-agent-0.1.7-rc.2.tgz", - "integrity": "sha512-9U/zHZvZqRR5S2FD9fjjAuoMh+WfDan+bE/cLBLSLpqftjZ0FhIlEBK99yonUkNkGemyHiH/lL3jCKYw35ahJA==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-agent/-/dsh-agent-0.2.1-alpha.4.tgz", + "integrity": "sha512-QIL78OhM5csPWkrdGfhUJQr3zdyUd/DZyM4euwUnkMS0BA5Hp21hCWg7N69HY73bqvV20oyU10g5huPtqJHSyQ==", "dev": true, "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-scope": "0.1.7-rc.2", - "@deepseek-ai/dsh-session": "0.1.7-rc.2", - "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", - "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", - "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", - "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", - "@deepseek-ai/dsh-workspace": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-scope": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.4", + "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.4", + "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.4", + "@deepseek-ai/dsh-util-values": "0.2.1-alpha.4", + "@deepseek-ai/dsh-workspace": "0.2.1-alpha.4" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-workspace": { @@ -416,265 +404,293 @@ } }, "node_modules/@deepseek-ai/dsh-brand": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-brand/-/dsh-brand-0.1.7-rc.2.tgz", - "integrity": "sha512-cvcvlNRuiFqZNNqyxdu7wcpiBjd9xa/0MpuhRvee43zBp9uED2p5JolZr5/2EKJf57gYx9k9bedb+Zbyiqnpkw==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-brand/-/dsh-brand-0.2.1-alpha.4.tgz", + "integrity": "sha512-SlrYMisnHPNREhc9jsohRylcZmpQPuzcul7DxUCJNjK08fDUUuzcyrQI7uDjvbw1n34IwYHNNV6o4mrhIIForQ==", "dev": true, "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4" + "@deepseek-ai/cordis": "~4.0.5-alpha.2" } }, "node_modules/@deepseek-ai/dsh-client-ui-primitives": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-client-ui-primitives/-/dsh-client-ui-primitives-0.1.7-rc.2.tgz", - "integrity": "sha512-ymIUil9ivHcIDgaAmF88lOygC7dJ0UsUgdbIvXT5bymPZDzvDJIoorOKhlMsCqPEG1ZawCMVhUatnIPi4xdlMQ==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-client-ui-primitives/-/dsh-client-ui-primitives-0.2.1-alpha.4.tgz", + "integrity": "sha512-nHzG2k7l8UuNG2rcIkzny1ko/fn/mQjiWrSh6wIe6X9d/qQi55Tdo87N3usmwce1akcZrvsXQ27v451tC1gzwA==", "dev": true, "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4" + "@deepseek-ai/cordis": "~4.0.5-alpha.2" } }, - "node_modules/@deepseek-ai/dsh-invariants": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-invariants/-/dsh-invariants-0.1.7-rc.2.tgz", - "integrity": "sha512-GY2lY2TUUH2Qk1ZnrB3Q5+lXSh4webn1kbt5nQfhojVmNbist/f3dJC8JJa7XXOUNvqAgqRN9IZ4egbDZ9LLxQ==", + "node_modules/@deepseek-ai/dsh-client-ui-settings": { + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-client-ui-settings/-/dsh-client-ui-settings-0.2.1-alpha.4.tgz", + "integrity": "sha512-SG6wzQyBmkNUuVt+5Da4tSnGeVVgNE8cJ6Qa6MG4zOJqWnEkJTCIRuOmsN1+7IGcWSNooFG76RGJpO+5uKkDdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.5-alpha.2" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.5-alpha.2" + } + }, + "node_modules/@deepseek-ai/dsh-fs": { + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-fs/-/dsh-fs-0.2.1-alpha.4.tgz", + "integrity": "sha512-K5TK7QxC3fRM8s1Uvfy1O3C4kaybSXOLGFMSb9WLwfTe1QGsq7JZN0v8jmiv3VFA0cFUkTPybz/PokyDtRWvRg==", "dev": true, "license": "MIT", "peer": true, - "dependencies": { - "@deepseek-ai/schemastery": "~3.18.4" - }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-brand": "0.2.1-alpha.4", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-sandbox": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/dsh-llm": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-llm/-/dsh-llm-0.1.7-rc.2.tgz", - "integrity": "sha512-hNT3ovFnbNDQ8g544bh2Q9ORX40aI6Y+jhjer1lETeHS4g0jTjqUUVfARCTA7uAFvHucSBg2rFgbisIktmJCxw==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-llm/-/dsh-llm-0.2.1-alpha.4.tgz", + "integrity": "sha512-rjAT6x0iNUNLgCC3pCNaQxrtQxlcMAAdCh8x27C4PiGCXMaa7kNge8HnjPC3iaZoopSrr5XRBLcyIFmg46Cc+A==", "dev": true, "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "0.1.7-rc.2", - "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", - "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", - "@deepseek-ai/dsh-util-crypto": "0.1.7-rc.2", - "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", - "@deepseek-ai/schemastery": "~3.18.4", - "zod": "^4.4.3" + "@deepseek-ai/dsh-brand": "0.2.1-alpha.4", + "@deepseek-ai/dsh-timeout": "0.2.1-alpha.4", + "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.4", + "@deepseek-ai/dsh-util-crypto": "0.2.1-alpha.4", + "@deepseek-ai/dsh-util-values": "0.2.1-alpha.4", + "@deepseek-ai/schemastery": "~3.18.5-alpha.2", + "zod": "4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4" + "@deepseek-ai/cordis": "~4.0.5-alpha.2" } }, "node_modules/@deepseek-ai/dsh-ptc-runtime": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-ptc-runtime/-/dsh-ptc-runtime-0.1.7-rc.2.tgz", - "integrity": "sha512-zRFwSSUgTpKuFQTVwnuNO4067Gyi//4C4RRLaUntXaHkZv3z1S07f1fTaYwX4+ubIIAuAVeEsczxf6tPgZ8P5g==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-ptc-runtime/-/dsh-ptc-runtime-0.2.1-alpha.4.tgz", + "integrity": "sha512-r+4GYR1UYbr0zyuu9tOO+iJuQvxYjtCJyTHr6YR9UZNJrfbwkrSeqlRIbR1cw5NaIh7dplZK1+a90FHURkrgWA==", "dev": true, "license": "MIT", "peer": true, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-sandbox": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/dsh-sandbox": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-sandbox/-/dsh-sandbox-0.1.7-rc.2.tgz", - "integrity": "sha512-7aP893mtTvnuZfCKD6hUN5gYchi6Wogn4W3mg/rGMvogmhbWgrCs00boJx/eHK4KvVJmEW1e8kO5N+GtsesptA==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-sandbox/-/dsh-sandbox-0.2.1-alpha.4.tgz", + "integrity": "sha512-PRCb2xDAvX609LagauDjLvYFmzYLBO3QYAYXcc7btfiqOdgfeDb7FgstzKjdbz2o31iVdvKUdDK1iFzXjVg6eg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" + "@deepseek-ai/dsh-util-values": "0.2.1-alpha.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-session": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/dsh-sandbox-policy": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-sandbox-policy/-/dsh-sandbox-policy-0.1.7-rc.2.tgz", - "integrity": "sha512-pIhCaOEqYjNoKy/c7dYYgYzK+zp8/FxnEeaBA5e6fTmNROb+/qSFsC4hY3Qu+PVU9IdbH/4fa6TbT2jnqoDPQw==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-sandbox-policy/-/dsh-sandbox-policy-0.2.1-alpha.4.tgz", + "integrity": "sha512-xEfAiquD87cg1aOzdPtFoB82e0P4hzWkVEimwRk1s85ESb8YiV+DRzWLrIGprfi9fKhsxSFFIFnCKgzOKjURuA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@deepseek-ai/schemastery": "~3.18.4", - "zod": "^4.4.3" + "@deepseek-ai/schemastery": "~3.18.5-alpha.2", + "zod": "4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-agent": "0.1.7-rc.2", - "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", - "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", - "@deepseek-ai/dsh-session": "0.1.7-rc.2", - "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", - "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-agent": "0.2.1-alpha.4", + "@deepseek-ai/dsh-sandbox": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.4", + "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/dsh-scope": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-scope/-/dsh-scope-0.1.7-rc.2.tgz", - "integrity": "sha512-rk/OM5ej6/V8pCNczEqQ3BkKx3DuPeFGzNUsEZo8hF+tnkF/EhsxMWSXC/yP/uLKeNkSsVHzjFpaQR0qr0J3gQ==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-scope/-/dsh-scope-0.2.1-alpha.4.tgz", + "integrity": "sha512-oo1AraYsu5D3oYGdKim43HGg0Hf6NbYLmV5LZO8jiDnaXiE+xfNDqI8ARwq049lODJMxP0ONX2hTo5DTG5zjuQ==", "dev": true, "license": "MIT", - "peer": true, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-invariants": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2" } }, "node_modules/@deepseek-ai/dsh-session": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-session/-/dsh-session-0.1.7-rc.2.tgz", - "integrity": "sha512-0dXv1t4Zox/yHkZ4PfPNSBWJfIc72PDqOvjz43EMoHpbmoKTVpit2UpUI+yTtX01e4MVBbDMxBZ95oJW/Oydnw==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-session/-/dsh-session-0.2.1-alpha.4.tgz", + "integrity": "sha512-YMdG+ZdvM+jXFDkfzO+ksCn6YpUFuoN4YuMEIcbSqLnwNo0Q7ba0GJWJEH7oP5v0sCwGtMKQySKSgqBjkUyw+w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@deepseek-ai/dsh-brand": "0.1.7-rc.2", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" + "@deepseek-ai/dsh-brand": "0.2.1-alpha.4", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-util-values": "0.2.1-alpha.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-scope": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-scope": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/dsh-session-projection": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-session-projection/-/dsh-session-projection-0.1.7-rc.2.tgz", - "integrity": "sha512-s5T8oHBEh+GeOTJ+wehD4CGZkTiWgczZZA+NDbfbqUO0k5L+dk0kk3fN+/srAg77rhR7UeeDSR8ZNcpYx/VUdw==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-session-projection/-/dsh-session-projection-0.2.1-alpha.4.tgz", + "integrity": "sha512-+Tm9xJd7ETbcLlolf9wx+Nm2z1O0SFqXermWU3GZ7ffQqo+tRKQ2oEa6NhSS5Mw1wVkY0xuxye5RRnVk3gbb4g==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "zod": "^4.4.3" + "zod": "4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-session": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-session": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/dsh-system-prompt": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-system-prompt/-/dsh-system-prompt-0.1.7-rc.2.tgz", - "integrity": "sha512-vxKcADh7XOuWJOfa0WeEOhvFiUbMOdoK4w6M7KVCI0S99c9ktxrgY4wKdmAxap+nQjwTEPme3QuOlY3Na+cz9w==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-system-prompt/-/dsh-system-prompt-0.2.1-alpha.4.tgz", + "integrity": "sha512-oHk8b0F2ecwrcN58ZtkMkR8FIRTULNSMTkHB1KbOz1LpTYuD6M01VFhWG0FvzZw01xPeuDlbO9wNmYtYi6/RsA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@deepseek-ai/schemastery": "~3.18.4" + "@deepseek-ai/schemastery": "~3.18.5-alpha.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-scope": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-scope": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/dsh-timeout": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-timeout/-/dsh-timeout-0.1.7-rc.2.tgz", - "integrity": "sha512-YunLoLZSF8Ld9eYwyvKoBnxgy3GZrIQpw98HfFS15ZfZlqcFiZcchFhYmStLtUbtX+gjhoeXc8Xz913YbVifNA==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-timeout/-/dsh-timeout-0.2.1-alpha.4.tgz", + "integrity": "sha512-hXCp1YWwDZAaTrNNon3ypb/Z6ZgDNKi/3zdC2JLHb9gU2f7DdSexbvRs37xKfyXO8HhtXDKvp/FUCWvI6rpRlg==", "dev": true, "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4" + "@deepseek-ai/cordis": "~4.0.5-alpha.2" } }, "node_modules/@deepseek-ai/dsh-tools": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-tools/-/dsh-tools-0.1.7-rc.2.tgz", - "integrity": "sha512-c3dTdKnslKxVTgjjPLwMKLqGUMwnZH5P8RUsucMQlWn2GViyFW/+5AIUuZHBjjE6Y7NAYl+lVVE/R4LgTp5KWA==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-tools/-/dsh-tools-0.2.1-alpha.4.tgz", + "integrity": "sha512-oTurHJ91LmlirKbEMyU0K+ES8LYtfJW4MAGrLjSBSaRKrq8eERTWNJafcxlhEKNpTWeUNU7h3OHaX/rqcMmLyA==", "dev": true, "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "0.1.7-rc.2", - "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", - "@deepseek-ai/schemastery": "~3.18.4" + "@deepseek-ai/dsh-brand": "0.2.1-alpha.4", + "@deepseek-ai/dsh-util-values": "0.2.1-alpha.4", + "@deepseek-ai/schemastery": "~3.18.5-alpha.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-agent": "0.1.7-rc.2", - "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-ptc-runtime": "0.1.7-rc.2", - "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", - "@deepseek-ai/dsh-scope": "0.1.7-rc.2", - "@deepseek-ai/dsh-session": "0.1.7-rc.2", - "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", - "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-agent": "0.2.1-alpha.4", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-ptc-runtime": "0.2.1-alpha.4", + "@deepseek-ai/dsh-sandbox": "0.2.1-alpha.4", + "@deepseek-ai/dsh-sandbox-policy": "0.2.1-alpha.4", + "@deepseek-ai/dsh-scope": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session": "0.2.1-alpha.4", + "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.4", + "@deepseek-ai/dsh-user-approval": "0.2.1-alpha.4", + "@deepseek-ai/dsh-working-directory": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/dsh-typert-protocol": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-typert-protocol/-/dsh-typert-protocol-0.1.7-rc.2.tgz", - "integrity": "sha512-oJm03zqMQlvt16Ejw7VWy3/gqlJGrBCZj3Z4KL8ydLJeeTToKIR49WVCxMbJTlH0F9QFljruLtHguA5B99AeUQ==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-typert-protocol/-/dsh-typert-protocol-0.2.1-alpha.4.tgz", + "integrity": "sha512-LBNUgiwbRqhyRNPvaAca++eLAxJ1jmmFJnd3RJAa8pT+oULJgZvqPgr9jVnTfX/P5pQT0p7AMZeelTc7QpQ/OA==", "dev": true, "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "0.1.7-rc.2" + "@deepseek-ai/dsh-brand": "0.2.1-alpha.4", + "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4" + "@deepseek-ai/cordis": "~4.0.5-alpha.2" } }, "node_modules/@deepseek-ai/dsh-user-approval": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-user-approval/-/dsh-user-approval-0.1.7-rc.2.tgz", - "integrity": "sha512-RQ6GB+C4G6VY/eJrFfS89+89DfHFAJ5G1abhmutfKBhZcYSnGNZyPIzpr5mKbl2xNMIhvCJOb9WiFz2fUPW2HA==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-user-approval/-/dsh-user-approval-0.2.1-alpha.4.tgz", + "integrity": "sha512-J6bcZV3rFuQiRDuMej5S/DalSeztfVIFngoGA15M31khb0E74kfrgWUIxvS7pRwy2j1MKz89wR8BbbDzufHTRw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@deepseek-ai/schemastery": "~3.18.4" + "@deepseek-ai/schemastery": "~3.18.5-alpha.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-agent": "0.1.7-rc.2", - "@deepseek-ai/dsh-brand": "0.1.7-rc.2", - "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-scope": "0.1.7-rc.2", - "@deepseek-ai/dsh-session": "0.1.7-rc.2", - "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2" + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-agent": "0.2.1-alpha.4", + "@deepseek-ai/dsh-brand": "0.2.1-alpha.4", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-scope": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session": "0.2.1-alpha.4", + "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/dsh-util-crypto": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-util-crypto/-/dsh-util-crypto-0.1.7-rc.2.tgz", - "integrity": "sha512-BGc55/bSj/1LcDTQ5fpok4U24X9SFyN+TB23/hBlbe2TBUKVuwO8+X5FFKKje2MLO8PWYEDkXv/LrV6jRVKZEg==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-util-crypto/-/dsh-util-crypto-0.2.1-alpha.4.tgz", + "integrity": "sha512-BLMlmD3y+HhTZPGij4viPRFWx8DNdsPNMauUW5XxyE2Iq5KG9ohQ+6xULju/J2Ah9JldVr3XAku7ItDPDk8Mpg==", "dev": true, "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4" + "@deepseek-ai/cordis": "~4.0.5-alpha.2" } }, "node_modules/@deepseek-ai/dsh-util-values": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-util-values/-/dsh-util-values-0.1.7-rc.2.tgz", - "integrity": "sha512-UX8nh5SbtZcPVVEvjd+9PCPcbybA6OpVzJGgFxYn59ao/7QQGyYbByS8KXr+THU5JtqmDDVb9xGUSJaF2IYmeQ==", + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-util-values/-/dsh-util-values-0.2.1-alpha.4.tgz", + "integrity": "sha512-RM3gAmdyUsldAb4AIsU++KYbBY98UvHRCskcHX2bojZ6kefGd1a8P1Yl/Fo+bUWIAHZj/VoA1pnAl7r5e5456A==", "dev": true, "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4" + "@deepseek-ai/cordis": "~4.0.5-alpha.2" + } + }, + "node_modules/@deepseek-ai/dsh-working-directory": { + "version": "0.2.1-alpha.4", + "resolved": "https://registry.npmjs.org/@deepseek-ai/dsh-working-directory/-/dsh-working-directory-0.2.1-alpha.4.tgz", + "integrity": "sha512-VtgMMlvYJ4iOPtpasI+ey6ioBekJy5MLSw3ky6lvLdLnKPmj0zobVOFhldr7KEvZFRizKYN5ktU8D85qKZG9Cg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.5-alpha.2", + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.5-alpha.2", + "@deepseek-ai/dsh-agent": "0.2.1-alpha.4", + "@deepseek-ai/dsh-fs": "0.2.1-alpha.4", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session": "0.2.1-alpha.4", + "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.4", + "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.4" } }, "node_modules/@deepseek-ai/schemastery": { - "version": "3.18.4", - "resolved": "https://registry.npmjs.org/@deepseek-ai/schemastery/-/schemastery-3.18.4.tgz", - "integrity": "sha512-SSXO6tYuyrIqKVbmOnIq0s+riUywYzouFMcnBluHF9n4KMo2G8HvEzhCYj6pj2617/glOjbJuVInJ9hfONsjkg==", + "version": "3.18.5-alpha.2", + "resolved": "https://registry.npmjs.org/@deepseek-ai/schemastery/-/schemastery-3.18.5-alpha.2.tgz", + "integrity": "sha512-W+2TSjdeKOEKqaii9BNpw7ev2Yf8C+J74i/BE/VBx56O7BX0zxV2zQKwRY4ADLTXD5O69iJ+/Skm91/ES7iMgw==", "dev": true, "license": "MIT", "dependencies": { - "@deepseek-ai/cosmokit": "~1.8.5", + "@deepseek-ai/cosmokit": "~1.8.6-alpha.2", "@standard-schema/spec": "^1.1.0" } }, @@ -1227,23 +1243,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -1257,13 +1256,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, "node_modules/@eslint/js": { "version": "9.39.4", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", @@ -1439,9 +1431,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.20.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.4.tgz", - "integrity": "sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==", + "version": "22.20.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.5.tgz", + "integrity": "sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==", "dev": true, "license": "MIT", "dependencies": { @@ -1496,9 +1488,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.10.tgz", - "integrity": "sha512-HpbUakT7xp5miBUywCHf36ZEuAJNklBJDDsGpUIjMzOSmM8ELSfA9Sa/QDPeNeqeoN31u+UTCkL4klCOVvRm4Q==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.12.tgz", + "integrity": "sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg==", "dev": true, "license": "MIT", "engines": { @@ -1749,9 +1741,9 @@ } }, "node_modules/acorn": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", - "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", "dev": true, "license": "MIT", "bin": { @@ -1771,6 +1763,23 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1802,9 +1811,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.11.26", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.26.tgz", - "integrity": "sha512-GLQdD3y6UF8iVuMJl5fHgE4jdn/ua7n+toKfLgNlg3BqQtOZjpy68T8Tup8/wGWZCDlm7KMg7tPb4MPn7oN0TQ==", + "version": "2.11.29", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.29.tgz", + "integrity": "sha512-YeesxhUmR4h5y5V8KF8iBCqJb8YFrBJ++XBTeGcWIaQOYXGN19JM0FoiOjAhwuDoln8owMgXcWBmgHtYSkky2w==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1826,9 +1835,9 @@ } }, "node_modules/browserslist": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.1.tgz", - "integrity": "sha512-AUdjuRyCNGUYtqpqfTmWyM4fXay8yIQhmLnvYe/THMGfT9B/34X7xQd3ifKxwyNPPpowVBjLb+64BN9Rn1mizw==", + "version": "4.29.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz", + "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==", "dev": true, "funding": [ { @@ -1846,9 +1855,9 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.11.25", - "caniuse-lite": "^1.0.30001810", - "electron-to-chromium": "^1.5.438", + "baseline-browser-mapping": "^2.11.26", + "caniuse-lite": "^1.0.30001813", + "electron-to-chromium": "^1.5.439", "node-releases": "^2.0.57", "update-browserslist-db": "^1.3.3" }, @@ -1870,9 +1879,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001812", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001812.tgz", - "integrity": "sha512-qN+QNNBr93TCmFrmte0bBCjSDMuRvt78VlHT99qIGPszm4QsqCX8lnyWUFkHi8B7ZBAPq8SH+UqyXNy/odMdng==", + "version": "1.0.30001816", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001816.tgz", + "integrity": "sha512-+8Yx7BXCoqk6IF8yTicjfUR6D/ldJzdlsodlEOiOSPmhK844WIgk67/zIQaGAOxNkZyyvBlrRFnLvqKIoqbAFw==", "dev": true, "funding": [ { @@ -1989,9 +1998,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.439", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.439.tgz", - "integrity": "sha512-qu6QIPXhsb+CRcAiTMNjR4A1y/7tCYKkKjr5CZXRVih6qkDf79peZ2BpEU3qoDBNCRrcy3Mra3X9nG5oruuA7Q==", + "version": "1.5.457", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.457.tgz", + "integrity": "sha512-RNKsgErRmkzRgC8nOV1wzFhSbfGlYJ6k4LT/aE7oFrDYaQgHhTh5oTp0ZgSbRRybKR8HlZIdCWc38Y+CDTk1Jw==", "dev": true, "license": "ISC" }, @@ -2171,30 +2180,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, "node_modules/espree": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", @@ -2529,6 +2514,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -2646,199 +2638,26 @@ "dev": true, "license": "MIT" }, - "node_modules/node-addon-native-custom-loader": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/node-addon-native-custom-loader/-/node-addon-native-custom-loader-0.1.6.tgz", - "integrity": "sha512-QaW7d8lTcGCXrpNVyFDtID3vrpa7vFdpcY9pql2/9FGFSe7tcSnhQOKZX+1aOWq+pB1d2ZwNnKAdQI5nD9wAXA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=20" - } - }, - "node_modules/node-addon-require-builtin": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/node-addon-require-builtin/-/node-addon-require-builtin-0.1.6.tgz", - "integrity": "sha512-P9ZGMDkloktirLJSggfpxsJ9jog5FItE1Omxpj50UBn3LhD6TS6/yx0jEBXsCGK3P9EtW1EpQVA1QL5gb11GaQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "node-addon-native-custom-loader": "0.1.6" - }, - "engines": { - "node": ">=20" - }, - "optionalDependencies": { - "node-addon-require-builtin-darwin-arm64": "0.1.6", - "node-addon-require-builtin-darwin-x64": "0.1.6", - "node-addon-require-builtin-linux-arm64-gnu": "0.1.6", - "node-addon-require-builtin-linux-x64-gnu": "0.1.6", - "node-addon-require-builtin-win32-arm64-msvc": "0.1.6", - "node-addon-require-builtin-win32-ia32-msvc": "0.1.6", - "node-addon-require-builtin-win32-x64-msvc": "0.1.6" - } - }, - "node_modules/node-addon-require-builtin-darwin-arm64": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/node-addon-require-builtin-darwin-arm64/-/node-addon-require-builtin-darwin-arm64-0.1.6.tgz", - "integrity": "sha512-KpaAh0mDcIScoJs7gD/mjXREcENJ023/DgWW3GrlLXFVzCE6bK6wFrTFpNfnkxZZP8yWsEWOg1o5T+uQ7olgTQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "dependencies": { - "node-addon-native-custom-loader": "0.1.6" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/node-addon-require-builtin-darwin-x64": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/node-addon-require-builtin-darwin-x64/-/node-addon-require-builtin-darwin-x64-0.1.6.tgz", - "integrity": "sha512-lh9o5rCvmkH8MZgBBmhyKzJRc1M1hJzgXLTFzB6iomRXNH9P1DKjN2nAJLmvGrdTij47Wcch1JVnlV5AG0cRCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "dependencies": { - "node-addon-native-custom-loader": "0.1.6" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/node-addon-require-builtin-linux-arm64-gnu": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/node-addon-require-builtin-linux-arm64-gnu/-/node-addon-require-builtin-linux-arm64-gnu-0.1.6.tgz", - "integrity": "sha512-DrQA3aS1LBn4NgrewbZkzSAWdSSRPD/fYO5AkQfvriQ/TQD3E2adB012sZ5eac6p9TAcTjUIYhk395AYVxo4Zw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "dependencies": { - "node-addon-native-custom-loader": "0.1.6" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/node-addon-require-builtin-linux-x64-gnu": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/node-addon-require-builtin-linux-x64-gnu/-/node-addon-require-builtin-linux-x64-gnu-0.1.6.tgz", - "integrity": "sha512-8wCxrFlB2Ld5DhxIm2P+nNFnQ0wjzDE5sXF68EUhLH0X+z313B07TUQFMBKCOkyhZIIBh590dBmhHCuA43No2A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "dependencies": { - "node-addon-native-custom-loader": "0.1.6" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/node-addon-require-builtin-win32-arm64-msvc": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/node-addon-require-builtin-win32-arm64-msvc/-/node-addon-require-builtin-win32-arm64-msvc-0.1.6.tgz", - "integrity": "sha512-NET6DiLnKrK2DHuO4NNN+zJz0CFas+RwpJlGY0d3A3A3tc5dJQqZXgw8DzLOn4cSTAQCaDq6+LbPyYX7jE2F3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "dependencies": { - "node-addon-native-custom-loader": "0.1.6" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/node-addon-require-builtin-win32-ia32-msvc": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/node-addon-require-builtin-win32-ia32-msvc/-/node-addon-require-builtin-win32-ia32-msvc-0.1.6.tgz", - "integrity": "sha512-oj4G51r81kJ3E2t5KknKhBNb8TmTWzc/t9x7jkBF9JeRd+1a0kr99mVJVYwJNxq9d3jpt7dgBdI8mxaomuXOEQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "dependencies": { - "node-addon-native-custom-loader": "0.1.6" - }, - "engines": { - "node": ">=20 <23" - } - }, - "node_modules/node-addon-require-builtin-win32-x64-msvc": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/node-addon-require-builtin-win32-x64-msvc/-/node-addon-require-builtin-win32-x64-msvc-0.1.6.tgz", - "integrity": "sha512-ZQ+6thVzQBOFamW7s3t2YqHsw99EEPBNH1uAjvCx4QfnjFJTsu6I/H3prpN8i6cSt6gjnQtArfWc2LXN2ufcJQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "dependencies": { - "node-addon-native-custom-loader": "0.1.6" - }, - "engines": { - "node": ">=20" - } - }, "node_modules/node-releases": { - "version": "2.0.57", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz", - "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==", + "version": "2.0.59", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.59.tgz", + "integrity": "sha512-5qr2okC4ItAI0hG5SaV0HoYMpnM/Y6+Oqr7AmPYy/2uEoGvS+GbSKLeRxSS1uAdu59yz0ouzcuXievSgg///WA==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -2991,6 +2810,42 @@ "node": ">=0.10.0" } }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-shallow-renderer": { + "version": "16.15.0", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", + "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-test-renderer": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.3.1.tgz", + "integrity": "sha512-KkAgygexHUkQqtvvx/otwxtuFu5cVjfzTCtjXLH9boS19/Nbtg84zS7wIQn39G8IlrhThBpQsMKkq5ZHZIYFXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "react-is": "^18.3.1", + "react-shallow-renderer": "^16.15.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3001,6 +2856,16 @@ "node": ">=4" } }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/semver": { "version": "7.8.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", @@ -3152,9 +3017,9 @@ "license": "MIT" }, "node_modules/update-browserslist-db": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz", - "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", "dev": true, "funding": [ { @@ -3239,9 +3104,9 @@ } }, "node_modules/zod": { - "version": "4.6.5", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.5.tgz", - "integrity": "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", "dev": true, "license": "MIT", "funding": { diff --git a/integrations/dsh/package.json b/integrations/dsh/package.json index 63068e8f..7fc58abc 100644 --- a/integrations/dsh/package.json +++ b/integrations/dsh/package.json @@ -1,6 +1,6 @@ { "name": "@agentscope-ai/reme-dsh-plugin", - "version": "0.1.1", + "version": "0.1.2", "description": "ReMe memory and context integration for DeepSeek Harness", "type": "module", "main": "./dist/index.js", @@ -51,12 +51,12 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "peerDependencies": { - "@deepseek-ai/cordis": "~4.0.4", - "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-tools": "0.1.7-rc.2", - "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", - "@deepseek-ai/schemastery": "~3.18.4" + "@deepseek-ai/cordis": "~4.0.4 || ^4.0.5-alpha.1", + "@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2 || ^0.2.0-rc.2 || ^0.2.1-alpha.2", + "@deepseek-ai/dsh-llm": "^0.1.7-rc.2 || ^0.2.0-rc.2 || ^0.2.1-alpha.2", + "@deepseek-ai/dsh-tools": "^0.1.7-rc.2 || ^0.2.0-rc.2 || ^0.2.1-alpha.2", + "@deepseek-ai/dsh-typert-protocol": "^0.1.7-rc.2 || ^0.2.0-rc.2 || ^0.2.1-alpha.2", + "@deepseek-ai/schemastery": "~3.18.4 || ^3.18.5-alpha.1" }, "peerDependenciesMeta": { "@deepseek-ai/cordis": { @@ -79,14 +79,14 @@ } }, "devDependencies": { - "@deepseek-ai/cordis": "4.0.4", - "@deepseek-ai/cordis-plugin-loader": "1.0.5", - "@deepseek-ai/dsh-agent": "0.1.7-rc.2", - "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2", - "@deepseek-ai/dsh-llm": "0.1.7-rc.2", - "@deepseek-ai/dsh-tools": "0.1.7-rc.2", - "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", - "@deepseek-ai/schemastery": "3.18.4", + "@deepseek-ai/cordis": "4.0.5-alpha.2", + "@deepseek-ai/cordis-plugin-loader": "1.0.6-alpha.2", + "@deepseek-ai/dsh-agent": "0.2.1-alpha.4", + "@deepseek-ai/dsh-client-ui-primitives": "0.2.1-alpha.4", + "@deepseek-ai/dsh-llm": "0.2.1-alpha.4", + "@deepseek-ai/dsh-tools": "0.2.1-alpha.4", + "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.4", + "@deepseek-ai/schemastery": "3.18.5-alpha.2", "@eslint/js": "9.39.4", "@types/node": "^22.15.0", "@types/react": "~18.3.1", @@ -97,7 +97,13 @@ "prettier": "3.0.0", "react": "^18.2.0", "typescript": "^5.9.2", - "typescript-eslint": "8.59.3" + "typescript-eslint": "8.59.3", + "@deepseek-ai/dsh-session": "0.2.1-alpha.4", + "@deepseek-ai/dsh-client-ui-settings": "0.2.1-alpha.4", + "@deepseek-ai/dsh-scope": "0.2.1-alpha.4", + "@deepseek-ai/dsh-sandbox": "0.2.1-alpha.4", + "react-test-renderer": "^18.3.1", + "semver": "^7.8.5" }, "engines": { "node": "^22.19.0 || >=24.0.0" diff --git a/integrations/dsh/scripts/test-package.mjs b/integrations/dsh/scripts/test-package.mjs index 59444823..67884661 100644 --- a/integrations/dsh/scripts/test-package.mjs +++ b/integrations/dsh/scripts/test-package.mjs @@ -1,17 +1,59 @@ import { execFile } from "node:child_process"; import assert from "node:assert/strict"; -import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises"; +import { + cp, + mkdir, + mkdtemp, + readFile, + readdir, + rm, + writeFile, +} from "node:fs/promises"; import { tmpdir } from "node:os"; import path from "node:path"; +import { fileURLToPath } from "node:url"; import { promisify } from "node:util"; const execFileAsync = promisify(execFile); +const root = fileURLToPath(new URL("..", import.meta.url)); +const manifest = JSON.parse( + await readFile(path.join(root, "package.json"), "utf8"), +); const temporaryDirectory = await mkdtemp( path.join(tmpdir(), "reme-dsh-package-"), ); +const releases = [ + { dsh: "0.1.7-rc.2", cordis: "4.0.4", loader: "1.0.5", schema: "3.18.4" }, + { dsh: "0.2.0-rc.2", cordis: "4.0.4", loader: "1.0.5", schema: "3.18.4" }, + { + dsh: "0.2.1-alpha.2", + cordis: "4.0.5-alpha.1", + loader: "1.0.6-alpha.1", + schema: "3.18.5-alpha.1", + }, + { + dsh: "0.2.1-alpha.4", + cordis: "4.0.5-alpha.2", + loader: "1.0.6-alpha.2", + schema: "3.18.5-alpha.2", + }, +]; + +async function run(command, args, cwd) { + try { + return await execFileAsync(command, args, { + cwd, + maxBuffer: 10 * 1024 * 1024, + }); + } catch (error) { + process.stderr.write(error.stdout || ""); + process.stderr.write(error.stderr || ""); + throw error; + } +} try { - const { stdout } = await execFileAsync( + const { stdout } = await run( "npm", [ "pack", @@ -20,7 +62,7 @@ try { "--pack-destination", temporaryDirectory, ], - { cwd: new URL("..", import.meta.url) }, + root, ); const [result] = JSON.parse(stdout); const files = new Set(result.files.map(({ path: file }) => file)); @@ -35,45 +77,91 @@ try { } assert.ok(![...files].some((file) => file.includes("openclaw"))); - const consumerDirectory = path.join(temporaryDirectory, "consumer"); - await mkdir(consumerDirectory); - await writeFile( - path.join(consumerDirectory, "package.json"), - '{"name":"reme-dsh-package-consumer","private":true}\n', - ); - const hostDependencies = [ - "@deepseek-ai/dsh-agent", - "@deepseek-ai/dsh-client-ui-primitives", - "@deepseek-ai/dsh-llm", - "@deepseek-ai/dsh-tools", - "@deepseek-ai/dsh-typert-protocol", - ].map((dependency) => `${dependency}@0.1.7-rc.2`); - await execFileAsync( - "npm", - [ - "install", - "--ignore-scripts", - "--no-audit", - "--no-fund", - path.join(temporaryDirectory, result.filename), - ...hostDependencies, - ], - { cwd: consumerDirectory }, - ); - await execFileAsync( - process.execPath, - [ - "--input-type=module", - "--eval", + for (const release of releases) { + const consumer = path.join(temporaryDirectory, release.dsh); + await mkdir(consumer); + const dependencies = Object.fromEntries( + Object.entries(manifest.devDependencies) + .filter( + ([name]) => + name.startsWith("@deepseek-ai/") || + [ + "typescript", + "esbuild", + "react", + "react-test-renderer", + "semver", + "@types/react", + "@types/node", + ].includes(name), + ) + .map(([name, version]) => [ + name, + name.startsWith("@deepseek-ai/dsh-") ? release.dsh : version, + ]), + ); + Object.assign(dependencies, { + "@deepseek-ai/cordis": release.cordis, + "@deepseek-ai/cordis-plugin-loader": release.loader, + "@deepseek-ai/schemastery": release.schema, + [manifest.name]: path.join(temporaryDirectory, result.filename), + }); + await writeFile( + path.join(consumer, "package.json"), + JSON.stringify({ private: true, type: "module", dependencies }), + ); + // Install as a consumer with normal peer resolution, then check the shipped artifact. + await run( + "npm", [ - 'const plugin = await import("@agentscope-ai/reme-dsh-plugin");', - 'if (typeof plugin.apply !== "function") throw new Error("missing apply export");', - 'if (!Array.isArray(plugin.inject)) throw new Error("missing inject export");', - 'if (plugin.Config === undefined) throw new Error("missing Config export");', - ].join("\n"), - ], - { cwd: consumerDirectory }, - ); + "install", + "--ignore-scripts", + "--no-audit", + "--no-fund", + "--fetch-retries=0", + "--fetch-timeout=30000", + ], + consumer, + ); + await run( + process.execPath, + [ + "--input-type=module", + "--eval", + ` + const plugin = await import(${JSON.stringify(manifest.name)}); + if (typeof plugin.apply !== "function" || !Array.isArray(plugin.inject) || plugin.Config === undefined) + throw new Error("missing Host plugin exports"); + `, + ], + consumer, + ); + + const installed = path.join(consumer, "node_modules", manifest.name); + for (const file of [ + "src", + "tests", + "tsconfig.json", + "scripts/build-client.mjs", + ]) { + await cp(path.join(root, file), path.join(installed, file), { + recursive: true, + }); + } + const testFiles = (await readdir(path.join(installed, "tests"))) + .filter((file) => file.endsWith(".test.mjs")) + .map((file) => path.join("tests", file)); + const tested = await run( + process.execPath, + ["--test", ...testFiles], + installed, + ); + await run("npm", ["run", "build"], installed); + const count = /# tests (\d+)/.exec(tested.stdout)?.[1]; + process.stdout.write( + `DSH ${release.dsh}: packed import, source build, and ${count} tests passed\n`, + ); + } } finally { await rm(temporaryDirectory, { force: true, recursive: true }); } diff --git a/integrations/dsh/src/client/index.tsx b/integrations/dsh/src/client/index.tsx index 4b903237..f8674bd0 100644 --- a/integrations/dsh/src/client/index.tsx +++ b/integrations/dsh/src/client/index.tsx @@ -1,4 +1,5 @@ import { useState, useSyncExternalStore } from "react"; +import type { ConfigForm } from "@deepseek-ai/dsh-client-ui-settings/client"; import type { ReMeSettings } from "../types.js"; import { @@ -32,22 +33,6 @@ const FIELDS = [ type Field = (typeof FIELDS)[number]; type Translator = (key: keyof typeof en) => string; -interface SettingsSnapshot { - status: "loading" | "ready" | "unavailable"; - value: T | undefined; - base: unknown; - user: unknown; - revision: number | undefined; - writable: boolean; -} - -interface SettingsScope { - getSnapshot(): SettingsSnapshot; - subscribe(listener: () => void): () => void; - set(field: string, value: unknown): Promise; - unset(field: string): Promise; -} - interface ClientContext { get(name: string): { rpc: StatusRpc }; effect(factory: () => (() => void) | void, label: string): void; @@ -63,7 +48,7 @@ interface ClientContext { ): () => void; }; configForms: { - get(namespace: string): SettingsScope; + get(namespace: string): ConfigForm; whileServed(namespaces: string[], register: () => () => void): () => void; }; slots: { @@ -92,7 +77,7 @@ interface Draft { } interface ReMeCardProps { - scope: SettingsScope; + scope: ConfigForm; t: Translator; view?: "summary" | "page"; } @@ -101,8 +86,6 @@ const en = { title: "ReMe Memory", description: "Turn conversations into lasting memory and grow your personal knowledge base.", - expand: "Expand ReMe Memory settings", - collapse: "Collapse ReMe Memory settings", loading: "Loading configuration…", unavailable: "ReMe settings are unavailable.", connected: "Connected", @@ -176,8 +159,6 @@ const en = { const zh: typeof en = { title: "ReMe Memory", description: "让对话沉淀为长期记忆,持续构建你的个人知识库。", - expand: "展开 ReMe Memory 设置", - collapse: "收起 ReMe Memory 设置", loading: "正在加载配置…", unavailable: "ReMe 设置不可用。", connected: "已连接", @@ -265,11 +246,11 @@ export function apply(ctx: ClientContext): void { ctx.effect( () => ctx.configForms.whileServed([SETTINGS_NS], () => - ctx.slots.inject("plugins.item", () => + ctx.slots.inject("plugins.row.config", () => ctx.slots.register( { - name: "plugins.item", - id: SETTINGS_NS, + name: "plugins.row.config", + key: "@agentscope-ai/reme-dsh-plugin#reme-memory", label: () => t("title"), locale: NS, inject: () => ({ scope, t }), @@ -307,14 +288,17 @@ function ReMeSettingsCard({ (listener) => scope.subscribe(listener), () => scope.getSnapshot(), ); - const [open, setOpen] = useState(false); - const [draftOverride, setDraft] = useState(); + const [draftOverride, setDraft] = useState<{ + value: Draft; + revision: number | undefined; + }>(); const [resetAll, setResetAll] = useState(false); const [saving, setSaving] = useState(false); const [saveState, setSaveState] = useState<"" | "saved" | "failed">(""); const value = snapshot.value; const draft = - draftOverride ?? (value === undefined ? undefined : draftFrom(value)); + draftOverride?.value ?? + (value === undefined ? undefined : draftFrom(value)); if (view === "summary") return <>{t("description")}; if (snapshot.status === "unavailable") return null; @@ -327,11 +311,10 @@ function ReMeSettingsCard({ const update = (field: K, next: Draft[K]) => { if (value === undefined) return; - setDraft((current) => - current === undefined - ? { ...draftFrom(value), [field]: next } - : { ...current, [field]: next }, - ); + setDraft((current) => ({ + value: { ...(current?.value ?? draftFrom(value)), [field]: next }, + revision: current ? current.revision : snapshot.revision, + })); setResetAll(false); setSaveState(""); }; @@ -341,135 +324,122 @@ function ReMeSettingsCard({ value === undefined || draft === undefined || validation === undefined || + !snapshot.writable || + !dirty || saving ) return; setSaving(true); setSaveState(""); try { - if (resetAll) { - await Promise.all(FIELDS.map((field) => scope.unset(field))); - } else { - await Promise.all( - FIELDS.flatMap((field) => + const ops = resetAll + ? FIELDS.map((field) => ({ op: "unset" as const, path: [field] })) + : FIELDS.flatMap((field) => Object.is(value[field], validation[field]) ? [] - : [scope.set(field, validation[field])], - ), - ); - } - const accepted = scope.getSnapshot().value; - const expected = resetAll ? scope.getSnapshot().base : validation; - const success = - isRecord(expected) && - accepted !== undefined && - FIELDS.every((field) => Object.is(accepted[field], expected[field])); + : [ + { + op: "set" as const, + path: [field], + value: validation[field], + }, + ], + ); + const success = await scope.mutate( + ops, + draftOverride?.revision ?? snapshot.revision, + ); setSaveState(success ? "saved" : "failed"); if (success) { - setDraft(draftFrom(accepted)); + setDraft(undefined); setResetAll(false); } + } catch { + setSaveState("failed"); } finally { setSaving(false); } }; return ( -
- - {open ? ( -
- {snapshot.status === "loading" || - draft === undefined || - value === undefined ? ( -

{t("loading")}

- ) : ( - <> +
+
+ {dirty ?

{t("unsaved")}

: null} + {snapshot.status === "loading" || + draft === undefined || + value === undefined ? ( +

{t("loading")}

+ ) : ( + <> +
- {!snapshot.writable ? ( -

- {t("readOnly")} -

- ) : null} - {validation === undefined ? ( -

- {t("invalid")} -

- ) : null} -
- - - {saveState === "failed" ? ( - - {t("saveFailed")} - - ) : null} - {saveState === "saved" ? ( - {t("saved")} - ) : null} - - - -
- - )} -
- ) : null} + + {!snapshot.writable ? ( +

+ {t("readOnly")} +

+ ) : null} + {validation === undefined ? ( +

+ {t("invalid")} +

+ ) : null} +
+ + + {saveState === "failed" ? ( + {t("saveFailed")} + ) : null} + {saveState === "saved" ? ( + {t("saved")} + ) : null} + + + +
+ + )} +
); } diff --git a/integrations/dsh/src/client/styles.ts b/integrations/dsh/src/client/styles.ts index e3860788..f58f1cc1 100644 --- a/integrations/dsh/src/client/styles.ts +++ b/integrations/dsh/src/client/styles.ts @@ -1,11 +1,9 @@ export const styles = ` -.reme-settings-card{list-style:none;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-3);transition:border-color .16s,background .16s} -.reme-settings-card:hover{border-color:var(--dsw-alias-label-dimmed)}.reme-settings-card.open{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)} -.reme-settings-header{width:100%;appearance:none;border:0;border-radius:12px;background:none;color:inherit;display:flex;align-items:center;gap:12px;padding:14px 16px;text-align:left;font:inherit;cursor:pointer}.reme-settings-header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px} -.reme-settings-title{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.reme-settings-title strong{font-size:15px;font-weight:600;line-height:1.4;color:var(--dsw-alias-label-primary)}.reme-settings-title span,.reme-settings-muted{font-size:13px;line-height:1.5;color:var(--dsw-alias-label-tertiary)} +.reme-settings-fields{min-width:0;margin:0;padding:0;border:0} +.reme-settings-card{border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2)} +.reme-settings-muted{font-size:13px;line-height:1.5;color:var(--dsw-alias-label-tertiary)} .reme-settings-pending{flex:none;border-radius:999px;padding:1px 8px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);font-size:11px;line-height:17px;font-weight:500;white-space:nowrap} -.reme-settings-chevron{width:14px;height:14px;flex:none;color:var(--dsw-alias-label-tertiary);transition:transform .16s;fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.4}.reme-settings-chevron.open{transform:rotate(180deg)} -.reme-settings-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.reme-settings-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:12px 0;border-bottom:1px solid var(--dsw-alias-border-l2)} +.reme-settings-body{padding:0 16px 8px}.reme-settings-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:12px 0;border-bottom:1px solid var(--dsw-alias-border-l2)} .reme-settings-status{flex:1 0 100%;min-width:0;display:flex;align-items:center;gap:8px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}.reme-settings-status+.reme-settings-button{margin-left:auto}.reme-settings-status .endpoint{color:var(--dsw-alias-label-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.reme-settings-dot{width:8px;height:8px;flex:none;border-radius:50%;background:var(--dsw-alias-label-tertiary)}.reme-settings-dot.ok{background:#21a366}.reme-settings-dot.bad{background:var(--dsw-alias-label-error)} .reme-settings-button,.reme-settings-discard,.reme-settings-save{appearance:none;border:1px solid transparent;border-radius:8px;padding:5px 12px;background:none;color:var(--dsw-alias-label-secondary);font:inherit;font-size:13px;line-height:1.5;text-decoration:none;cursor:pointer}.reme-settings-button,.reme-settings-discard{border-color:var(--dsw-alias-border-l2)}.reme-settings-button:hover:not(:disabled),.reme-settings-discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.reme-settings-save{padding-inline:14px;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.reme-settings-button:disabled,.reme-settings-discard:disabled,.reme-settings-save:disabled,.reme-settings-reset:disabled{opacity:.4;cursor:default}.reme-settings-button:focus-visible,.reme-settings-discard:focus-visible,.reme-settings-save:focus-visible,.reme-settings-reset:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px} .reme-settings-section{padding:14px 0 0}.reme-settings-section h4{margin:0;padding-bottom:8px;font-size:13px;font-weight:600;line-height:1.5;color:var(--dsw-alias-label-primary)}.reme-settings-grid{display:flex;flex-direction:column} diff --git a/integrations/dsh/src/index.ts b/integrations/dsh/src/index.ts index 5e0d98e7..fbdc3640 100644 --- a/integrations/dsh/src/index.ts +++ b/integrations/dsh/src/index.ts @@ -1,6 +1,8 @@ import { createUserMessage } from "@deepseek-ai/dsh-llm"; import type { Context } from "@deepseek-ai/cordis"; import type {} from "@deepseek-ai/cordis-plugin-loader"; +import type {} from "@deepseek-ai/dsh-agent"; +import type {} from "@deepseek-ai/dsh-session"; import { ReMeClient } from "./reme/client.js"; import { resolveConfig } from "./config.js"; diff --git a/integrations/dsh/tests/bundle.test.mjs b/integrations/dsh/tests/bundle.test.mjs index abe80059..c7b3f2a9 100644 --- a/integrations/dsh/tests/bundle.test.mjs +++ b/integrations/dsh/tests/bundle.test.mjs @@ -3,6 +3,7 @@ import { readFile } from "node:fs/promises"; import { createRequire } from "node:module"; import test from "node:test"; import vm from "node:vm"; +import semver from "semver"; test("declares one installable DeepSeek Harness plugin", async () => { const manifest = JSON.parse( @@ -24,7 +25,28 @@ test("declares one installable DeepSeek Harness plugin", async () => { "@deepseek-ai/dsh-tools", "@deepseek-ai/dsh-typert-protocol", ]) { - assert.equal(manifest.peerDependencies[dependency], "0.1.7-rc.2"); + for (const version of [ + "0.1.7-rc.2", + "0.2.0-rc.2", + "0.2.1-alpha.2", + "0.2.1-alpha.4", + ]) { + assert.ok( + semver.satisfies(version, manifest.peerDependencies[dependency]), + ); + } + for (const version of [ + "0.1.6", + "0.2.0-rc.1", + "0.2.2-alpha.1", + "0.3.0-alpha.1", + "0.3.0", + ]) { + assert.equal( + semver.satisfies(version, manifest.peerDependencies[dependency]), + false, + ); + } assert.equal(manifest.peerDependenciesMeta[dependency]?.optional, true); } assert.equal(manifest.peerDependencies.openclaw, undefined); @@ -47,14 +69,14 @@ test("builds a lazy DSH browser module for the ReMe settings card", async () => ); assert.match(bundle, /window\.__ModuleLoader__\.load/); assert.match(bundle, /id: "@agentscope-ai\/reme-dsh-plugin"/); - assert.match(bundle, /plugins\.item/); + assert.match(bundle, /plugins\.row\.config/); assert.match(bundle, /reme-status/); assert.match(bundle, /Personal Knowledge Base/); assert.match(statusPage, /个人知识库/); assert.match(bundle, /health_check/); }); -test("registers a visible title for the Plugins page", async () => { +test("registers configuration on the ReMe bundle row", async () => { const bundle = await readFile( new URL("../dist/client.js", import.meta.url), "utf8", @@ -115,7 +137,9 @@ test("registers a visible title for the Plugins page", async () => { }, }; client.apply(ctx); - const item = registrations.find((options) => options.name === "plugins.item"); - assert.equal(item.id, "reme-memory"); + const item = registrations.find( + (options) => options.name === "plugins.row.config", + ); + assert.equal(item.key, "@agentscope-ai/reme-dsh-plugin#reme-memory"); assert.equal(item.label(), "ReMe Memory"); }); diff --git a/integrations/dsh/tests/client-settings.test.mjs b/integrations/dsh/tests/client-settings.test.mjs new file mode 100644 index 00000000..93db8c85 --- /dev/null +++ b/integrations/dsh/tests/client-settings.test.mjs @@ -0,0 +1,193 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import { createRequire } from "node:module"; +import test from "node:test"; +import vm from "node:vm"; +import React from "react"; +import { act, create } from "react-test-renderer"; +import { resolveConfig } from "../dist/config.js"; + +async function editor(mutate) { + let module; + const bundle = await readFile( + new URL("../dist/client.js", import.meta.url), + "utf8", + ); + vm.runInNewContext(bundle, { + URL, + document: { + head: { appendChild() {} }, + createElement: () => ({ dataset: {}, remove() {} }), + }, + window: { + __ModuleLoader__: { + load(value) { + module = value; + }, + }, + }, + }); + const nodeRequire = createRequire(import.meta.url); + const client = module.factory((name) => + name === "@deepseek-ai/dsh-client-ui-primitives" ? {} : nodeRequire(name), + ); + let Component; + let snapshot = { + status: "ready", + value: resolveConfig({}, {}), + base: resolveConfig({}, {}), + revision: 7, + writable: true, + }; + const listeners = new Set(); + const calls = []; + const scope = { + getSnapshot: () => snapshot, + subscribe(listener) { + listeners.add(listener); + return () => listeners.delete(listener); + }, + async mutate(ops, revision) { + calls.push({ ops: JSON.parse(JSON.stringify(ops)), revision }); + const accepted = await mutate(ops, revision); + if (accepted) { + const value = { ...snapshot.value }; + for (const op of ops) + value[op.path[0]] = + op.op === "unset" ? snapshot.base[op.path[0]] : op.value; + update({ value, revision: snapshot.revision + 1 }); + } + return accepted; + }, + }; + function update(next) { + snapshot = { ...snapshot, ...next }; + for (const listener of listeners) listener(); + } + const disposers = []; + client.apply({ + locale: { bind: () => (key) => key, register: () => () => {} }, + configForms: { + get: () => scope, + whileServed: (_names, register) => register(), + }, + slots: { + inject: (_name, register) => register(), + register(options, component) { + if (options.name === "plugins.row.config") Component = component; + return () => {}; + }, + }, + get: () => ({ rpc: {} }), + effect(factory) { + disposers.push(factory()); + }, + }); + let renderer; + act(() => { + renderer = create( + React.createElement(Component, { scope, t: (key) => key, view: "page" }), + ); + }); + return { + calls, + update, + change(index, value) { + act(() => { + const input = renderer.root.findAllByType("input")[index]; + input.props.onChange({ target: { value } }); + }); + }, + button(label) { + return renderer.root + .findAllByType("button") + .find((button) => button.children.includes(label)); + }, + text: () => JSON.stringify(renderer.toJSON()), + close() { + act(() => renderer.unmount()); + for (const dispose of disposers) dispose?.(); + }, + }; +} + +test("saves all edited fields in one revision-fenced mutation", async () => { + const ui = await editor(async () => true); + try { + ui.change(0, "http://memory.test"); + ui.change(1, "8"); + await act(async () => { + await ui.button("save").props.onClick(); + }); + assert.deepEqual(ui.calls, [ + { + ops: [ + { op: "set", path: ["endpoint"], value: "http://memory.test" }, + { op: "set", path: ["searchLimit"], value: 8 }, + ], + revision: 7, + }, + ]); + assert.match(ui.text(), /saved/); + assert.equal(ui.button("save").props.disabled, true); + } finally { + ui.close(); + } +}); + +for (const outcome of ["refused", "transport failure"]) { + test(`preserves edits after ${outcome} and keeps their original revision`, async () => { + const ui = await editor(async () => { + if (outcome === "transport failure") throw new Error("offline"); + return false; + }); + try { + ui.change(0, "http://memory.test"); + act(() => ui.update({ revision: 8 })); + await act(async () => { + await ui.button("save").props.onClick(); + }); + assert.equal(ui.calls[0].revision, 7); + assert.match(ui.text(), /saveFailed/); + assert.match(ui.text(), /http:\/\/memory.test/); + assert.equal(ui.button("save").props.disabled, false); + act(() => ui.button("discard").props.onClick()); + assert.doesNotMatch(ui.text(), /http:\/\/memory.test/); + } finally { + ui.close(); + } + }); +} + +test("resets overrides in one mutation only after Save", async () => { + const ui = await editor(async () => true); + try { + act(() => ui.button("reset").props.onClick()); + assert.equal(ui.calls.length, 0); + await act(async () => { + await ui.button("save").props.onClick(); + }); + assert.equal(ui.calls.length, 1); + assert.equal(ui.calls[0].ops.length, 13); + assert.ok(ui.calls[0].ops.every((op) => op.op === "unset")); + assert.equal(ui.calls[0].revision, 7); + } finally { + ui.close(); + } +}); + +test("read-only configuration cannot be saved", async () => { + const ui = await editor(async () => true); + try { + ui.change(0, "http://memory.test"); + act(() => ui.update({ writable: false })); + await act(async () => { + await ui.button("save").props.onClick(); + }); + assert.equal(ui.calls.length, 0); + assert.equal(ui.button("save").props.disabled, true); + assert.match(ui.text(), /readOnly/); + } finally { + ui.close(); + } +}); diff --git a/tests/unit/test_package_versions.py b/tests/unit/test_package_versions.py index 88f46847..7f451cad 100644 --- a/tests/unit/test_package_versions.py +++ b/tests/unit/test_package_versions.py @@ -75,7 +75,7 @@ def test_typescript_host_plugins_are_independent_packages() -> None: assert manifests["dsh"]["name"] == "@agentscope-ai/reme-dsh-plugin" assert manifests["openclaw"]["name"] == "@agentscope-ai/reme-openclaw-plugin" - assert manifests["dsh"]["version"] == "0.1.1" + assert manifests["dsh"]["version"] == "0.1.2" assert manifests["openclaw"]["version"] == "0.1.1" assert manifests["dsh"].get("dependencies", {}) == {} assert manifests["openclaw"].get("dependencies", {}) == {"typebox": "1.3.19"}