dsh-zspace 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +11 -1
- package/lib/client/webdav.js +18 -4
- package/lib/prompt.js +3 -2
- package/lib/tools/remove.js +7 -2
- package/lib/tools/status.js +3 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# 变更日志
|
|
2
2
|
|
|
3
|
+
## 0.3.2 — 2026-10-11
|
|
4
|
+
|
|
5
|
+
修正**注入给模型的指南**滞后于工具演进的问题(只影响文档文案,行为不变):
|
|
6
|
+
|
|
7
|
+
- `lib/prompt.js`:补 `zspace_write`;说明两条通道与自动选路(并指向 `zspace_status` 的 `transport` / `webdavProbe`);修正"删除必进回收站"的说法——云中转通道进回收站,**WebDAV 直连通道由 NAS 侧决定**,要确保可找回就先确认通道或临时 `transportMode: relay`。
|
|
8
|
+
- `lib/tools/remove.js`:工具描述与渲染同步标注该通道差异。
|
|
9
|
+
- 起因:收尾复核时发现系统提示里的工具清单还停在 0.1.x(缺 `zspace_write`、把回收站语义写死),会误导每个新会话。
|
|
10
|
+
|
|
11
|
+
## 0.3.1 — 2026-10-07
|
|
12
|
+
|
|
13
|
+
- WebDAV 地址也支持环境变量 `ZS_WEBDAV_URL`:**三个环境变量即可启用直连,零 patch 改动**(避开 profile 层同 id 插两次导致挂载两次的坑);`zspace_status` 报告统一走同一取值。
|
|
14
|
+
- 测试 36 → 37(新增"仅靠环境变量也能启用直连"用例)。
|
|
15
|
+
- README 补 macOS 上给 GUI 进程注入环境变量的做法(`launchctl setenv` + 完全重启桌面端)。
|
|
16
|
+
|
|
3
17
|
## 0.3.0 — 2026-10-07
|
|
4
18
|
|
|
5
19
|
**双通道**:同一网络时直连 NAS 的 WebDAV,跨网络继续走桌面客户端云中转,插件自动选路。工具名与参数**完全不变**(仍是 13 个),既有配置继续可用。
|
package/README.md
CHANGED
|
@@ -44,7 +44,17 @@ dsh plugin --profile desktop add /绝对路径/dsh-zspace-0.1.0.tgz
|
|
|
44
44
|
- `transportMode`:`auto`(默认)/ `webdav`(强制,失败直接报错)/ `relay`(保持旧行为)。
|
|
45
45
|
- 路径映射:NAS 的 `/sata1/my/data/...` ↔ WebDAV 的 `<webdavHomePath>/...`(默认根 `/`);公共空间由 `webdavPublicPath` 指定(默认空=不在 WebDAV 暴露,相关路径自动回到中转)。
|
|
46
46
|
- 极空间要在「系统设置 → 文件服务」里开启 WebDAV(默认端口 `5005`,本机实测可用;`5006` 是自签 HTTPS,证书校验会失败)。
|
|
47
|
-
-
|
|
47
|
+
- **零 patch 配置**:三个环境变量就能启用直连,不需要改任何 patch 文件(避开"同 id 插两次导致挂载两次"的坑):
|
|
48
|
+
`ZS_WEBDAV_URL`(如 `http://<nas-ip>:5005/`)、`ZS_WEBDAV_USER`(NAS 账号)、`ZS_WEBDAV_PASSWORD`。
|
|
49
|
+
插件跑在 DSH Desktop 进程里,所以要让**桌面端**能看到这些变量(macOS):
|
|
50
|
+
```sh
|
|
51
|
+
launchctl setenv ZS_WEBDAV_URL 'http://<nas-ip>:5005/'
|
|
52
|
+
launchctl setenv ZS_WEBDAV_USER '<NAS账号>'
|
|
53
|
+
launchctl setenv ZS_WEBDAV_PASSWORD '<密码>'
|
|
54
|
+
# 然后 Cmd+Q 完全退出 DSH Desktop 再重新打开(launchctl setenv 只影响之后启动的进程)
|
|
55
|
+
```
|
|
56
|
+
想改回只走中转:`launchctl unsetenv ZS_WEBDAV_URL`(或设 `transportMode: relay`)。
|
|
57
|
+
- 密码不写进 patch 文件——patch 是明文,会被备份/截图带走。
|
|
48
58
|
- `zspace_remove` 在 WebDAV 通道下是 NAS 侧的删除语义(是否进回收站由 NAS 决定);要确保进回收站请用 `transportMode: relay`。
|
|
49
59
|
|
|
50
60
|
## 工具
|
package/lib/client/webdav.js
CHANGED
|
@@ -37,6 +37,20 @@ export const PASSWORD_ENV = "ZS_WEBDAV_PASSWORD";
|
|
|
37
37
|
/** Environment variable carrying the WebDAV user name. */
|
|
38
38
|
export const USER_ENV = "ZS_WEBDAV_USER";
|
|
39
39
|
|
|
40
|
+
/** Environment variable carrying the WebDAV base URL. */
|
|
41
|
+
export const URL_ENV = "ZS_WEBDAV_URL";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Effective WebDAV base URL: config first, environment as the fallback, so the
|
|
45
|
+
* fast path can be enabled without touching any patch file.
|
|
46
|
+
*
|
|
47
|
+
* @param {import("../client.js").ZSpaceClient} client - live client.
|
|
48
|
+
* @returns {string} base URL ("" when unset).
|
|
49
|
+
*/
|
|
50
|
+
export function webdavUrl(client) {
|
|
51
|
+
return String(client.webdavUrl || process.env[URL_ENV] || "").trim();
|
|
52
|
+
}
|
|
53
|
+
|
|
40
54
|
export const name = "webdav";
|
|
41
55
|
|
|
42
56
|
/**
|
|
@@ -58,7 +72,7 @@ export function credentials(client) {
|
|
|
58
72
|
* @returns {boolean} true when a URL and complete credentials are configured.
|
|
59
73
|
*/
|
|
60
74
|
export function configured(client) {
|
|
61
|
-
return Boolean(
|
|
75
|
+
return Boolean(webdavUrl(client)) && credentials(client).complete;
|
|
62
76
|
}
|
|
63
77
|
|
|
64
78
|
/**
|
|
@@ -68,7 +82,7 @@ export function configured(client) {
|
|
|
68
82
|
* @returns {string} base URL.
|
|
69
83
|
*/
|
|
70
84
|
function baseUrl(client) {
|
|
71
|
-
return
|
|
85
|
+
return webdavUrl(client).replace(/\/+$/, "");
|
|
72
86
|
}
|
|
73
87
|
|
|
74
88
|
/**
|
|
@@ -281,8 +295,8 @@ export async function nasRoots(client) {
|
|
|
281
295
|
* @returns {Promise<{reachable: boolean, usable: boolean, status?: number, reason: string}>} probe result.
|
|
282
296
|
*/
|
|
283
297
|
export async function probe(client) {
|
|
284
|
-
if (!
|
|
285
|
-
return { reachable: false, usable: false, reason:
|
|
298
|
+
if (!webdavUrl(client)) {
|
|
299
|
+
return { reachable: false, usable: false, reason: `未配置 WebDAV 地址(设置 ${URL_ENV} 或配置项 webdavUrl)` };
|
|
286
300
|
}
|
|
287
301
|
if (!credentials(client).complete) {
|
|
288
302
|
return { reachable: false, usable: false, reason: `缺少 WebDAV 凭据(设置 ${USER_ENV} 与 ${PASSWORD_ENV})` };
|
package/lib/prompt.js
CHANGED
|
@@ -15,12 +15,13 @@ function guideText(config) {
|
|
|
15
15
|
const down = config.downloadDir || "~/Downloads/zspace";
|
|
16
16
|
return [
|
|
17
17
|
"### 极空间 NAS(dsh-zspace)",
|
|
18
|
-
"
|
|
18
|
+
"这台 NAS 有两条通道,插件自动选路:**同一网络时直连 WebDAV**(更快、不依赖桌面客户端),**跨网络时走桌面客户端云中转**。当前在用哪条、以及另一条为什么没选,跑 `zspace_status` 看(它的 transport / webdavProbe 字段)。跨网络只要求桌面客户端保持登录。",
|
|
19
19
|
"- 远程路径写法:`home:`=个人空间根、`public:`=公共空间根、相对路径=相对个人空间、以 `/` 开头=NAS 绝对路径;两个根的真实位置先跑 `zspace_status` 查看。",
|
|
20
20
|
"- 只读:`zspace_ls`(支持 depth 递归)、`zspace_stat`、`zspace_find`(按名称在目录树里遍历查找,受 depth/scanLimit 预算限制,结果里会报告扫了多少项)、`zspace_read`(小文本读入上下文)、`zspace_download`(下载到本机,默认 " +
|
|
21
21
|
down +
|
|
22
22
|
")。",
|
|
23
|
-
"- 写入:`zspace_upload
|
|
23
|
+
"- 写入:`zspace_upload`(本地文件,大文件自动分片,支持中文名)、`zspace_write`(**文本直接写进 NAS**,省掉本地临时文件;默认覆盖,`overwrite: false` 时拒绝覆盖)、`zspace_mkdir`、`zspace_rename`、`zspace_move`、`zspace_copy`、`zspace_remove`(必须显式 confirm=true)。",
|
|
24
24
|
"- 删除/移动/重命名属于破坏性操作:先用 `zspace_ls` 或 `zspace_stat` 核实目标,再执行;批量删除前先向用户确认。",
|
|
25
|
+
"- 删除语义随通道而变:云中转通道进 NAS 回收站;**WebDAV 直连通道由 NAS 侧决定**(通常不进回收站)。要确保可找回,就先用 `zspace_status` 确认当前通道,或临时把 `transportMode` 设为 `relay`。",
|
|
25
26
|
].join("\n");
|
|
26
27
|
}
|
package/lib/tools/remove.js
CHANGED
|
@@ -9,7 +9,7 @@ export function createRemoveTool(ctx) {
|
|
|
9
9
|
return {
|
|
10
10
|
name: "zspace_remove",
|
|
11
11
|
description:
|
|
12
|
-
"Delete files or directories from the 极空间 / ZSpace NAS.
|
|
12
|
+
"Delete files or directories from the 极空间 / ZSpace NAS. On the relay transport they land in the NAS recycle bin; on the direct WebDAV transport the NAS decides (usually permanent) — check zspace_status to see which transport is active. Requires confirm=true so a bulk delete can never be a slip; ask the user before removing anything they did not name explicitly.",
|
|
13
13
|
parameters: {
|
|
14
14
|
paths: { type: "array", required: true, items: { type: "string" }, description: "Paths to delete." },
|
|
15
15
|
confirm: { type: "boolean", required: true, description: "Must be true — explicit confirmation that these paths should be deleted." },
|
|
@@ -24,7 +24,12 @@ export function createRemoveTool(ctx) {
|
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
26
|
call: (args) => ({ card: "generic", title: `zspace_remove ${(args.paths ?? []).length} 项`, kind: "edit" }),
|
|
27
|
-
render: (_args, value) => [
|
|
27
|
+
render: (_args, value) => [
|
|
28
|
+
{
|
|
29
|
+
type: "text",
|
|
30
|
+
text: `已删除 ${value.count} 项(云中转通道进回收站;WebDAV 直连通道由 NAS 侧决定):\n${value.paths.join("\n")}`,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
28
33
|
execute: (args) =>
|
|
29
34
|
guarded(async () => {
|
|
30
35
|
if (args.confirm !== true) {
|
package/lib/tools/status.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { humanSize } from "../format.js";
|
|
8
|
+
import { webdavUrl } from "../client/webdav.js";
|
|
8
9
|
|
|
9
10
|
export function createStatusTool(ctx) {
|
|
10
11
|
const { config, getClient, guarded } = ctx;
|
|
@@ -78,7 +79,7 @@ export function createStatusTool(ctx) {
|
|
|
78
79
|
ok: false,
|
|
79
80
|
baseUrl,
|
|
80
81
|
transport: transport.transport,
|
|
81
|
-
webdavUrl: client
|
|
82
|
+
webdavUrl: webdavUrl(client),
|
|
82
83
|
webdavProbe,
|
|
83
84
|
username: "",
|
|
84
85
|
nasId: "",
|
|
@@ -116,7 +117,7 @@ export function createStatusTool(ctx) {
|
|
|
116
117
|
ok: home.error === "" || publicSpace.error === "",
|
|
117
118
|
baseUrl,
|
|
118
119
|
transport: transport.transport,
|
|
119
|
-
webdavUrl: client
|
|
120
|
+
webdavUrl: webdavUrl(client),
|
|
120
121
|
webdavProbe,
|
|
121
122
|
username: identity.username,
|
|
122
123
|
nasId: identity.nasId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-zspace",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "极空间(ZSpace)NAS plugin for DeepSeek Harness: cross-network agent tools for browsing, searching, reading, uploading and organizing NAS files through the desktop client's relay — no LAN, no WebDAV, no SSH, no Python.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|