@deepseek-ai/dsh-tool-pwsh 0.1.5-rc.2 → 0.1.6-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/shell/tool-pwsh/README.md
5
- README.md: e18a2e378bee2c2aaf40e17a9b02f043815d77cd
6
- README.zh.md: 059f3da7fb804453cd168224875e4f53ec30424a
5
+ README.md: a1b8755c50862bb318f72af90f3cdbae158e7746
6
+ README.zh.md: efcf188b31365f6897eb14fb6482c973f23f6a7b
package/README.md CHANGED
@@ -51,7 +51,7 @@ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-a
51
51
 
52
52
  ### Running a command
53
53
 
54
- The tool executes `pwsh -Command <command>` and returns the combined output. Commands run in a fresh pwsh process every call, so state never persists — pass `workdir` instead of `cd`. Paths use native Windows form and environment variables are read with `$env:NAME`. A non-zero exit is reported as `[exit code: N]`; on Windows a force-killed command settles as `[exit code: 1]` without a signal marker, so the agent treats a bare exit 1 after an interruption as a termination, not a command failure. Background runs, output truncation, and the `description`/`timeoutMs`/`workdir` arguments behave exactly as in `dsh-tool-bash`.
54
+ The tool executes `pwsh -Command <command>` and returns the combined output. Commands run in a fresh pwsh process every call, so state never persists — pass `workdir` instead of `cd`. Paths use native Windows form and environment variables are read with `$env:NAME`. A non-zero exit is reported as `[exit code: N]`; on Windows a force-killed command settles as `[exit code: 1]` without a signal marker, so the agent treats a bare exit 1 after an interruption as a termination, not a command failure. Background runs, output truncation, and the `description`/`timeoutMs`/`workdir` arguments behave exactly as in [`dsh-tool-bash`](../tool-bash/README.md#running-long-commands-in-the-background), including job-owned cancellation during asynchronous shell preparation.
55
55
 
56
56
  ### Windows-specific sandbox behavior
57
57
 
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@ kind: "package-reference"
9
9
 
10
10
  ## 概述
11
11
 
12
- `dsh-tool-pwsh` 为 agent 提供 `pwsh` 工具,通过已挂载的 shell 执行器运行 PowerShell 命令——它是 `dsh-tool-bash` 的 Windows 对应物,逐调用镜像。每次调用都运行在全新 pwsh 进程中,因此状态不会保留;`run_in_background` 把长时间运行的命令变成后台任务。命令是 PowerShell 方言:原生 `C:\...` 路径与 `$env:NAME` 变量,不做方言翻译。每次调用都运行在受管 `DSH_*` 环境中;在沙箱执行器下,工具会教授并执行 Windows 特有的语言模式与命名管道约定。请与 `dsh-pwsh-local` 等 PowerShell 执行器以及 `dsh-shell-env` 插件一起挂载。
12
+ `dsh-tool-pwsh` 为 agent(智能体)提供 `pwsh` 工具,通过已挂载的 shell 执行器运行 PowerShell 命令——它是 `dsh-tool-bash` 的 Windows 对应物,逐调用镜像。每次调用都运行在全新 pwsh 进程中,因此状态不会保留;`run_in_background` 把长时间运行的命令变成后台任务。命令是 PowerShell 方言:原生 `C:\...` 路径与 `$env:NAME` 变量,不做方言翻译。每次调用都运行在受管 `DSH_*` 环境中;在沙箱执行器下,工具会向模型说明并强制执行 Windows 特有的语言模式与命名管道约定。请与 `dsh-pwsh-local` 等 PowerShell 执行器以及 `dsh-shell-env` 插件一起挂载。
13
13
 
14
14
  ## 目录
15
15
 
@@ -51,7 +51,7 @@ kind: "package-reference"
51
51
 
52
52
  ### 运行命令
53
53
 
54
- 工具执行 `pwsh -Command <command>` 并返回合并后的输出。命令每次调用都运行在全新 pwsh 进程中,因此状态从不保留——请传 `workdir` 而不是 `cd`。路径使用原生 Windows 形式,环境变量用 `$env:NAME` 读取。非零退出以 `[exit code: N]` 报告;在 Windows 上,强制终止的命令以 `[exit code: 1]` 结算且没有信号标记,因此 agent 把中断后的裸 exit 1 当作终止而非命令失败。后台运行、输出截断以及 `description`/`timeoutMs`/`workdir` 参数的行为与 `dsh-tool-bash` 完全一致。
54
+ 工具执行 `pwsh -Command <command>` 并返回合并后的输出。命令每次调用都运行在全新 pwsh 进程中,因此状态从不保留——请传 `workdir` 而不是 `cd`。路径使用原生 Windows 形式,环境变量用 `$env:NAME` 读取。非零退出以 `[exit code: N]` 报告;在 Windows 上,强制终止的命令以 `[exit code: 1]` 结算且没有信号标记,因此 agent 把中断后的裸 exit 1 当作终止而非命令失败。后台运行、输出截断以及 `description`/`timeoutMs`/`workdir` 参数的行为与 [`dsh-tool-bash`](../tool-bash/README.zh.md#running-long-commands-in-the-background) 完全一致,包括异步 shell 准备过程中由任务负责的取消。
55
55
 
56
56
  ### Windows 特有的沙箱行为
57
57
 
@@ -85,11 +85,11 @@ kind: "package-reference"
85
85
  | [`src/index.ts`](src/index.ts) | 插件入口:工具注册、提示词区段、参数校验、升权、请求组装 |
86
86
  | [`src/background.ts`](src/background.ts) | 把已结算的后台进程映射为通用任务结果词汇 |
87
87
  | [`src/render.ts`](src/render.ts) | 模型侧结果文本:流、标记、截断通知(bash 孪生) |
88
- | — | 不发布运行时不变式伴生入口;执行关系归能力 seam 所有。 |
88
+ | — | 不发布运行时不变式伴生入口;除所属 seam 强制执行的约定外,本包不公开独立的事件序列或可变数据关系。 |
89
89
 
90
90
  ### 渲染与退出标记
91
91
 
92
- renderer 共享 bash 工具的结构与来自 `dsh-shell` 的 `parseExitStatus` 标记约定:干净退出(0、无信号)不产生标记;UI 卡片把退出标记消费为退出状态 pill。Windows 强制终止以 exit 1 结算且没有信号,因此 `[killed by signal: …]` 在那里只存在于 POSIX。`tool:pwsh` 提示词区段(first-party 顺序 1010)教授退出标记约定与「中断后 exit 1」的 Windows 解读。
92
+ 渲染器共享 bash 工具的结构与来自 `dsh-shell` 的 `parseExitStatus` 标记约定:干净退出(0、无信号)不产生标记;UI 卡片把退出标记消费为退出状态 pill。Windows 强制终止以 exit 1 结算且没有信号,因此 `[killed by signal: …]` 仅适用于 POSIX。`tool:pwsh` 提示词区段(first-party 顺序 1010)教授退出标记约定与「中断后 exit 1」的 Windows 解读。
93
93
 
94
94
  </details>
95
95
 
@@ -118,7 +118,7 @@ renderer 共享 bash 工具的结构与来自 `dsh-shell` 的 `parseExitStatus`
118
118
 
119
119
  #### 模型看到什么
120
120
 
121
- 该插件注册 scope 中的每次请求都在 first-party 顺序 1010 处包含以下 pwsh 指引。按 scope 限制工具可以隐藏 schema,却不会移除这个独立注册的区段。
121
+ 该插件注册作用域内的每次请求都在 first-party 顺序 1010 处包含以下 pwsh 指引。按作用域实施的工具限制可以隐藏 schema,却不会移除这个独立注册的区段。
122
122
 
123
123
  ##### Pwsh 指引
124
124
 
@@ -132,13 +132,13 @@ Non-zero exits are reported as `[exit code: N]` markers; investigate failures be
132
132
 
133
133
  #### KV Cache 影响
134
134
 
135
- 只要注册 scope 与提示词文本不变,前缀就保持稳定。插件激活或释放可能使从该提示词区段起的复用失效。
135
+ 只要注册作用域与提示词文本不变,前缀就保持稳定。插件激活或释放可能使从该提示词区段起的复用失效。
136
136
 
137
137
  ### 工具 schema
138
138
 
139
139
  #### 模型看到什么
140
140
 
141
- 模型会看到生成的 [`pwsh` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-pwsh)。按 agent(智能体)scope 限制工具可以移除该 agent 的定义。
141
+ 模型会看到生成的 [`pwsh` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-pwsh)。按 agent 作用域实施的工具限制可以移除该 agent 的定义。
142
142
 
143
143
  #### Token 影响
144
144
 
@@ -152,7 +152,7 @@ Non-zero exits are reported as `[exit code: N]` markers; investigate failures be
152
152
 
153
153
  #### 模型看到什么
154
154
 
155
- renderer 输出依数据而定的 stdout 尾部,再输出可选的 `[stderr]` 和 stderr 尾部。条件行精确为 `[output truncated; full output: <path-or-(unavailable)>]`、`[sandbox: file access denied under <mode> mode]` 加升权提示 `[sandbox: escalation available — …]`(仅在组合声明升权时)、`[timed out after <timeoutMs>ms]`、`[killed by signal: <signal>]` 与 `[exit code: <exitCode>]`(仅非零退出);空正文渲染为 `(no output)`。
155
+ 渲染器输出依数据而定的 stdout 尾部,再输出可选的 `[stderr]` 和 stderr 尾部。条件行精确为 `[output truncated; full output: <path-or-(unavailable)>]`、`[sandbox: file access denied under <mode> mode]` 加升权提示 `[sandbox: escalation available — …]`(仅在组合声明升权时)、`[timed out after <timeoutMs>ms]`、`[killed by signal: <signal>]` 与 `[exit code: <exitCode>]`(仅非零退出);空正文渲染为 `(no output)`。
156
156
 
157
157
  #### Token 影响
158
158
 
@@ -197,7 +197,7 @@ renderer 输出依数据而定的 stdout 尾部,再输出可选的 `[stderr]`
197
197
 
198
198
  这些限制说明工具何时不合适或需要特别小心。它们是当前包约束,不是任务积压。
199
199
 
200
- - **Windows 沙箱下的语言模式与命名管道捕获**——在 [Windows ACL 沙箱](../../sandbox/sandbox-windows-acl/README.zh.md)下,只读 pwsh 以 ConstrainedLanguage 启动,因为其临时目录写拒绝让 PowerShell 的 AppLocker 探测失败关闭:`Add-Type`、非核心 .NET 静态调用(`[System.IO.*]::`、`[math]::`)、COM 对象与反射会以 "only core types" 错误失败,且该模式无法从内部解除。workspace-write 的私有临时目录让探测完成,因此除非宿主策略另有规定,它保持 FullLanguage。两种受限模式都拒绝命名管道打开,因此受限命令内部的管道 stdio spawn 会以 EPERM 失败。工具描述把两条约定都教给模型;完整限制以后端 README 为准。
200
+ - **Windows 沙箱下的语言模式与命名管道捕获**——在 [Windows ACL 沙箱](../../sandbox/sandbox-windows-acl/README.zh.md)下,只读 pwsh 以 ConstrainedLanguage 启动,因为其临时目录写入被拒绝,导致 PowerShell 的 AppLocker 探测失败并按拒绝处理:`Add-Type`、非核心 .NET 静态调用(`[System.IO.*]::`、`[math]::`)、COM 对象与反射会以 "only core types" 错误失败,且该模式无法从内部解除。workspace-write 的私有临时目录让探测完成,因此除非宿主策略另有规定,它保持 FullLanguage。两种受限模式都拒绝命名管道打开,因此受限命令内部的管道 stdio spawn 会以 EPERM 失败。工具描述把两条约定都教给模型;完整限制以后端 README 为准。
201
201
  - **没有持久 shell**——每次调用都启动全新的 `pwsh -Command`;持久 shell 对应物是 [`@deepseek-ai/dsh-tool-pwsh-persistent`](../tool-pwsh-persistent/README.zh.md),它跨调用保持一个按所有者隔离的 pwsh 存活。
202
202
  - **PowerShell 方言约定**——模型必须编写 PowerShell(原生路径、`$env:` 变量),而不是 bash;没有方言翻译。
203
203
  - **会话 cwd 身份未规范化**——workdir 基准就是会话头部 cwd 原样,不像 bash 工具那样以沙箱根规范化身份为准。在约束执行器下,策略的 workspace root 确实被规范化(由共享策略服务完成),因此当原始会话 cwd 与其规范形式不同时,workdir 与约束根可能分叉——这是推迟到共享 shell 工具基座抽取的对齐差距。
package/lib/index.js CHANGED
@@ -29,6 +29,40 @@ function processOutcome(proc) {
29
29
  detail: `exit code: ${proc.exitCode ?? 0}`
30
30
  };
31
31
  }
32
+ /**
33
+ * Adapt asynchronous shell preparation after job admission without exposing a partial process.
34
+ * @param start - starts the process with job-owned cancellation.
35
+ * @param renderOutput - consumes output from a published process.
36
+ * @returns synchronous job hooks whose completion includes preparation and process settlement.
37
+ */
38
+ function processJob(start, renderOutput) {
39
+ const controller = new AbortController();
40
+ let process;
41
+ return {
42
+ cancel: (reason) => {
43
+ if (controller.signal.aborted) return;
44
+ controller.abort(reason);
45
+ process?.kill();
46
+ },
47
+ done: (async () => {
48
+ try {
49
+ process = await start(controller.signal);
50
+ try {
51
+ if (controller.signal.aborted) process.kill();
52
+ } finally {
53
+ await process.done;
54
+ }
55
+ return processOutcome(process);
56
+ } catch (error) {
57
+ return {
58
+ status: controller.signal.aborted && process === void 0 ? "killed" : "failed",
59
+ detail: error instanceof Error ? error.message : String(error)
60
+ };
61
+ }
62
+ })(),
63
+ readOutput: () => process === void 0 ? "" : renderOutput(process)
64
+ };
65
+ }
32
66
  //#endregion
33
67
  //#region lib/types/render.js
34
68
  /**
@@ -388,14 +422,10 @@ function apply(ctx, config = {}) {
388
422
  kind: "pwsh",
389
423
  label: args.command,
390
424
  ...exec.agent ? { owner: exec.agent } : {},
391
- run: () => {
392
- const proc = ctx.shell.start(ctx.shell.resolve(request));
393
- return {
394
- cancel: () => void proc.kill(),
395
- done: proc.done.then(() => processOutcome(proc)),
396
- readOutput: () => renderPwshProcessRead(proc.readOutput(), proc.sandbox, escalationModes)
397
- };
398
- }
425
+ run: () => processJob((signal) => ctx.shell.start(ctx.shell.resolve({
426
+ ...request,
427
+ signal
428
+ })), (proc) => renderPwshProcessRead(proc.readOutput(), proc.sandbox, escalationModes))
399
429
  })
400
430
  };
401
431
  }
@@ -5,6 +5,7 @@
5
5
  * @module @deepseek-ai/dsh-tool-pwsh/background
6
6
  */
7
7
  import type { ShellProcess } from '@deepseek-ai/dsh-shell';
8
+ import type { JobHooks } from '@deepseek-ai/dsh-jobs';
8
9
  /**
9
10
  * Map a settled background process onto the generic task-outcome vocabulary:
10
11
  * `killed` stays `killed` (detail: the signal when one is known), everything
@@ -17,4 +18,11 @@ export declare function processOutcome(proc: ShellProcess): {
17
18
  status: 'completed' | 'killed';
18
19
  detail: string;
19
20
  };
21
+ /**
22
+ * Adapt asynchronous shell preparation after job admission without exposing a partial process.
23
+ * @param start - starts the process with job-owned cancellation.
24
+ * @param renderOutput - consumes output from a published process.
25
+ * @returns synchronous job hooks whose completion includes preparation and process settlement.
26
+ */
27
+ export declare function processJob(start: (signal: AbortSignal) => Promise<ShellProcess>, renderOutput: (process: ShellProcess) => string): JobHooks;
20
28
  //# sourceMappingURL=background.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-tool-pwsh",
3
3
  "description": "Model-facing pwsh tool over the bash executor seam",
4
- "version": "0.1.5-rc.2",
4
+ "version": "0.1.6-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,40 +27,40 @@
27
27
  ],
28
28
  "license": "MIT",
29
29
  "peerDependencies": {
30
- "@deepseek-ai/dsh-agent": "^0.1.5-rc.2",
31
30
  "@deepseek-ai/cordis": "^4.0.2",
32
- "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2",
33
- "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2",
34
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2",
35
- "@deepseek-ai/dsh-shell": "^0.1.5-rc.2",
36
- "@deepseek-ai/dsh-shell-env": "^0.1.5-rc.2",
37
- "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
38
- "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2",
39
- "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2",
40
- "@deepseek-ai/dsh-llm": "^0.1.5-rc.2"
31
+ "@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
32
+ "@deepseek-ai/dsh-jobs": "^0.1.6-alpha.2",
33
+ "@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
34
+ "@deepseek-ai/dsh-sandbox": "^0.1.6-alpha.2",
35
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.6-alpha.2",
36
+ "@deepseek-ai/dsh-tools": "^0.1.6-alpha.2",
37
+ "@deepseek-ai/dsh-user-approval": "^0.1.6-alpha.2",
38
+ "@deepseek-ai/dsh-shell-env": "^0.1.6-alpha.2",
39
+ "@deepseek-ai/dsh-shell": "^0.1.6-alpha.2",
40
+ "@deepseek-ai/dsh-system-prompt": "^0.1.6-alpha.2"
41
41
  },
42
42
  "dependencies": {
43
43
  "@deepseek-ai/schemastery": "^3.18.2"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@deepseek-ai/cordis": "^4.0.2",
47
- "@deepseek-ai/dsh-agent": "^0.1.5-rc.2",
48
- "@deepseek-ai/dsh-agent-loop": "^0.1.5-rc.2",
49
- "@deepseek-ai/dsh-app-boot": "^0.1.5-rc.2",
50
- "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2",
51
- "@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
52
- "@deepseek-ai/dsh-jobs-local": "^0.1.5-rc.2",
53
- "@deepseek-ai/dsh-loader-smoke": "^0.1.5-rc.2",
54
- "@deepseek-ai/dsh-pwsh-local": "^0.1.5-rc.2",
55
- "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2",
56
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2",
57
- "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2",
58
- "@deepseek-ai/dsh-shell-env": "^0.1.5-rc.2",
59
- "@deepseek-ai/dsh-subprocess-local": "^0.1.5-rc.2",
60
- "@deepseek-ai/dsh-shell": "^0.1.5-rc.2",
61
- "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2",
62
- "@deepseek-ai/dsh-tool-jobs": "^0.1.5-rc.2",
63
- "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2",
64
- "@deepseek-ai/dsh-tools": "^0.1.5-rc.2"
47
+ "@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
48
+ "@deepseek-ai/dsh-app-boot": "^0.1.6-alpha.2",
49
+ "@deepseek-ai/dsh-agent-loop": "^0.1.6-alpha.2",
50
+ "@deepseek-ai/dsh-jobs": "^0.1.6-alpha.2",
51
+ "@deepseek-ai/dsh-jobs-local": "^0.1.6-alpha.2",
52
+ "@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
53
+ "@deepseek-ai/dsh-loader-smoke": "^0.1.6-alpha.2",
54
+ "@deepseek-ai/dsh-pwsh-local": "^0.1.6-alpha.2",
55
+ "@deepseek-ai/dsh-sandbox": "^0.1.6-alpha.2",
56
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.6-alpha.2",
57
+ "@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.2",
58
+ "@deepseek-ai/dsh-shell": "^0.1.6-alpha.2",
59
+ "@deepseek-ai/dsh-shell-env": "^0.1.6-alpha.2",
60
+ "@deepseek-ai/dsh-subprocess-local": "^0.1.6-alpha.2",
61
+ "@deepseek-ai/dsh-system-prompt": "^0.1.6-alpha.2",
62
+ "@deepseek-ai/dsh-tool-jobs": "^0.1.6-alpha.2",
63
+ "@deepseek-ai/dsh-user-approval": "^0.1.6-alpha.2",
64
+ "@deepseek-ai/dsh-tools": "^0.1.6-alpha.2"
65
65
  }
66
66
  }