@deepseek-ai/dsh-tool-pwsh-persistent 0.1.7-alpha.1 → 0.1.7-rc.1

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-persistent/README.md
5
- README.md: f90442e7e9d8a361a690f66f41a58f1a4fcdd708
6
- README.zh.md: d634e8e42e186318a8733ee9ef2024e2840a857c
5
+ README.md: cd78f224f9f85899cca1f578fd0316c6f4caab2f
6
+ README.zh.md: 53b0b4cdd69ac94556f16621ccd3d9ca205cc6f4
package/README.md CHANGED
@@ -54,7 +54,7 @@ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-a
54
54
 
55
55
  ### What the agent can rely on
56
56
 
57
- Commands share one shell per agent, so cwd, `$env:` variables, functions, and background jobs persist across calls. Results exclude the private completion markers, the shell prompt, and the echoed input line. A non-zero wrapped command appends `[exit code: N]` — the exact native exit code when the command ran a native program, `1` for a terminating PowerShell error. A shell that exits before reporting that status instead appends `[shell exited: code N]`, `[shell killed by signal: SIG]`, or `[shell exited]` (Windows forced termination reports exit 1 without a signal), then resets and tells the agent the next call starts fresh. Long output keeps the earliest retained prefix plus a clipping notice; if the terminal has already dropped that prefix, the result says so explicitly.
57
+ Commands share one shell per agent, so cwd, `$env:` variables, functions, and background jobs persist across calls. Results exclude the private completion markers and the echoed input line. When the shell reads stdin again without having printed the completion marker — an interrupt, a replaced shell, or an interactive foreground child whose stdin wait the provider proves — the call returns the captured partial output, which can end with the backend's own prompt text. A non-zero wrapped command appends `[exit code: N]` — the exact native exit code when the command ran a native program, `1` for a terminating PowerShell error. A shell that exits before reporting that status instead appends `[shell exited: code N]`, `[shell killed by signal: SIG]`, or `[shell exited]` (Windows forced termination reports exit 1 without a signal), then resets and tells the agent the next call starts fresh. Long output keeps the earliest retained prefix plus a clipping notice; if the terminal has already dropped that prefix, the result says so explicitly.
58
58
 
59
59
  ### What can go wrong
60
60
 
@@ -73,7 +73,7 @@ This section explains the design decisions behind the tool and points at the cod
73
73
  ### Design philosophy
74
74
 
75
75
  - **A deliberate twin of `dsh-tool-bash-persistent`.** The session registry, polling loop, and reset contract mirror the persistent bash tool by design ([pwsh persistent PTY Agent Note](../../../.agents/notes/archived/architecture/2026-08-11-pwsh-persistent-pty.md)).
76
- - **Prompt-function readiness.** The tool installs its own `prompt` function that prints a BEL-terminated OSC marker plus a printable prompt; the OSC marker carries the last exit code and the printable prompt settles every command, so a model redefinition of `prompt` degrades readiness to the silence tier.
76
+ - **Backend-owned prompt readiness.** The shell's `prompt` function belongs to the backend: it prints a BEL-terminated OSC marker plus the controlled printable prompt, and that exact prompt text settles every command through the backend's fast path. The tool neither installs nor matches a prompt of its own, so only a model redefinition of `prompt` degrades readiness to the silence tier.
77
77
  - **PSReadLine echo stripped by anchoring.** PowerShell renders submitted input back into the stream; the marker-anchored extraction and a wrapper-source strip remove the echo, and a wrapper that wraps across the terminal width may leave a partial echo in partial-output results.
78
78
  - **Reset, never repair.** Any uncertain state — an explicit `exit`, a timeout, a send failure, an abort — closes the shell and starts the next call fresh.
79
79
 
@@ -81,12 +81,12 @@ This section explains the design decisions behind the tool and points at the cod
81
81
 
82
82
  | File | Role |
83
83
  |---|---|
84
- | [`src/index.ts`](src/index.ts) | Plugin entry: shell registry, prompt setup, command wrapping, scrollback polling, extraction and rendering |
84
+ | [`src/index.ts`](src/index.ts) | Plugin entry: shell registry, command wrapping, scrollback polling, extraction and rendering |
85
85
  | — | No runtime invariant companion is published; the adapter's private owner-to-shell cache has no observable event or data relation. Lifecycle tests prove its cleanup without adding a public API solely for an invariant. |
86
86
 
87
87
  ### Command flow
88
88
 
89
- A first command spawns the shell through `ctx.terminals.spawn`, installs the `prompt` override, and waits for readiness. Each command is wrapped into one physical line — `Write-Output` of the start marker, the body escaped with backtick escapes into a double-quoted string, and `Write-Output` of the end marker plus the exit status — so PSReadLine's echo of a wrapped line cannot fabricate completion. The tool polls the scrollback in 1,000-line pages until the end marker or a completed prompt appears, extracts the span, strips the echoed wrapper and prompts, and renders it with any status marker. A timeout aborts the deadline, captures the partial output, and resets the shell.
89
+ A first command spawns the shell through `ctx.terminals.spawn`, whose pwsh startup installs the controlled `prompt` function and returns only once the shell reached readiness. Each command is wrapped into one physical line — `Write-Output` of the start marker, the body escaped with backtick escapes into a double-quoted string, and `Write-Output` of the end marker plus the exit status — so PSReadLine's echo of a wrapped line cannot fabricate completion. The tool polls the scrollback in 1,000-line pages until the end marker appears or the send settles as `stdin_read`, extracts the span, strips the echoed wrapper, and renders it with any status marker. A timeout aborts the deadline, captures the partial output, and resets the shell.
90
90
 
91
91
  </details>
92
92
 
@@ -128,7 +128,7 @@ Prefix-stable while the configured description and schema remain unchanged.
128
128
 
129
129
  #### What the model sees
130
130
 
131
- Commands share one shell per Agent, so cwd, `$env:` variables, functions, and background jobs persist across calls. Results exclude private completion markers, the shell prompt, and the echoed input line (PSReadLine renders submitted input back into the stream; the marker-anchored extraction and the wrapper-source strip remove it). A nonzero wrapped command appends `[exit code: N]` — the exact native exit code when the command ran a native program, `1` for a terminating PowerShell error. A shell that exits before reporting that status instead appends `[shell exited: code N]`, `[shell killed by signal: SIG]`, or `[shell exited]` when the backend supplies neither (Windows forced termination reports exit 1 without a signal), then resets and tells the model that the next call starts fresh. Long output keeps the earliest retained prefix plus a clipping notice; if the terminal has already dropped that prefix, the result says so explicitly. Timeout returns bounded partial output, closes the uncertain shell, and reports the reset.
131
+ Commands share one shell per Agent, so cwd, `$env:` variables, functions, and background jobs persist across calls. Results exclude private completion markers and the echoed input line (PSReadLine renders submitted input back into the stream; the marker-anchored extraction and the wrapper-source strip remove it). When the shell reads stdin again without having printed the completion marker — an interrupt, a replaced shell, or an interactive foreground child whose stdin wait the provider proves — the call returns the captured partial output, which can end with the backend's own prompt text. A nonzero wrapped command appends `[exit code: N]` — the exact native exit code when the command ran a native program, `1` for a terminating PowerShell error. A shell that exits before reporting that status instead appends `[shell exited: code N]`, `[shell killed by signal: SIG]`, or `[shell exited]` when the backend supplies neither (Windows forced termination reports exit 1 without a signal), then resets and tells the model that the next call starts fresh. Long output keeps the earliest retained prefix plus a clipping notice; if the terminal has already dropped that prefix, the result says so explicitly. Timeout returns bounded partial output, closes the uncertain shell, and reports the reset.
132
132
 
133
133
  #### Token effect
134
134
 
@@ -149,7 +149,7 @@ These limits define when the tool is a poor fit or needs special care. They are
149
149
  - **Input echo is unavoidable** — PowerShell's PSReadLine renders submitted input back into the terminal stream, and there is no `stty -echo` equivalent. The marker-anchored extraction excludes the echo in complete results; the wrapper-source strip covers fallback paths, but a wrapper that wraps across the terminal width may leave a partial echo in partial-output results, bounded by `maxOutputChars`.
150
150
  - **Raw ESC characters inside model commands are unsupported** — PSReadLine consumes them before execution. The wrapper escapes the control bytes it needs (`[char]27`-built OSC markers, backtick escapes for the body).
151
151
  - **A model redefinition of the `prompt` function removes the readiness marker** — the shell then settles on the silence tier instead of the marker fast path.
152
- - **There is no interactive stdin during a command** — a foreground command that reads input blocks until the command timeout, which resets the shell.
152
+ - **There is no interactive stdin during a command** — where the provider proves a foreground stdin wait, a child that reads input returns early with partial output and leaves the session open, so that child can consume the next call's command until the call reaches `timeoutMs` and resets the shell. Everywhere else the original call itself runs to `timeoutMs`, which resets the shell.
153
153
  - **SIGTSTP/SIGHUP are unavailable on Windows** (backend-rejected); SIGINT is delivered as a console-wide Ctrl-C input write, which at a prompt cancels the pending line instead of signalling a process.
154
154
  - **Under the Windows ACL sandbox's read-only mode, pwsh starts in ConstrainedLanguage**, which may deny the bootstrap's `[Console]::` encoding pin and prompt marker. Commands can still settle through the printable prompt and silence tier, but non-ASCII output may follow the host code page.
155
155
  - **The BEL-terminated OSC marker remains a readiness signal only** — a BEL event channel to the model stays deferred, aligned with the current implementation.
package/README.zh.md CHANGED
@@ -54,7 +54,7 @@ kind: "package-reference"
54
54
 
55
55
  ### agent 可以依赖什么
56
56
 
57
- 命令共享每个 agent 一个 shell,因此 cwd、`$env:` 变量、函数与后台任务都会跨调用保留。结果排除私有完成标记、shell 提示符与回显的输入行。非零的包装命令追加 `[exit code: N]`——命令运行原生程序时给出确切原生退出码,PowerShell 终止错误则为 `1`。在报告该状态前就退出的 shell 改为追加 `[shell exited: code N]`、`[shell killed by signal: SIG]` 或 `[shell exited]`(Windows 强制终止报告 exit 1 且没有信号),然后重置并告诉 agent 下一次调用从全新状态开始。长输出保留最早的已保留前缀并附裁剪通知;若 terminal 已经丢弃该前缀,结果会明确说明。
57
+ 命令共享每个 agent 一个 shell,因此 cwd、`$env:` 变量、函数与后台任务都会跨调用保留。结果排除私有完成标记与回显的输入行。当 shell 再次读取 stdin 却没有打印完成标记时——一次中断、一个被替换的 shell,或提供方能证明其 stdin 等待的交互式前台子进程——调用返回已捕获的部分输出,其结尾可能是后端自己的提示符文本。非零的包装命令追加 `[exit code: N]`——命令运行原生程序时给出确切原生退出码,PowerShell 终止错误则为 `1`。在报告该状态前就退出的 shell 改为追加 `[shell exited: code N]`、`[shell killed by signal: SIG]` 或 `[shell exited]`(Windows 强制终止报告 exit 1 且没有信号),然后重置并告诉 agent 下一次调用从全新状态开始。长输出保留最早的已保留前缀并附裁剪通知;若 terminal 已经丢弃该前缀,结果会明确说明。
58
58
 
59
59
  ### 可能出什么问题
60
60
 
@@ -73,7 +73,7 @@ kind: "package-reference"
73
73
  ### 设计理念
74
74
 
75
75
  - **`dsh-tool-bash-persistent` 的刻意孪生。** 会话注册表、轮询循环与重置约定按设计镜像持久 bash 工具([pwsh 持久 PTY Agent Note](../../../.agents/notes/archived/architecture/2026-08-11-pwsh-persistent-pty.md))。
76
- - **prompt 函数就绪。** 工具安装自己的 `prompt` 函数,打印 BEL 结尾的 OSC 标记加可打印提示符;OSC 标记携带最后的退出码,可打印提示符让每条命令都能结算,因此模型重定义 `prompt` 会把就绪降级到静默层级。
76
+ - **后端拥有提示符就绪。** shell 的 `prompt` 函数属于后端:它打印 BEL 结尾的 OSC 标记加受控的可打印提示符,该确切提示符文本让每条命令都经由后端快路径结算。工具既不安装也不匹配自己的提示符,因此只有模型重定义 `prompt` 才会把就绪降级到静默层级。
77
77
  - **PSReadLine 回显靠锚定剥离。** PowerShell 会把提交的输入渲染回流中;标记锚定提取与包装源码剥离移除回显,而跨终端宽度换行的包装可能在部分输出结果中留下部分回显。
78
78
  - **重置,而非修复。** 任何不确定状态——显式 `exit`、超时、发送失败、中止——都会关闭 shell 并让下一次调用从全新状态开始。
79
79
 
@@ -81,12 +81,12 @@ kind: "package-reference"
81
81
 
82
82
  | 文件 | 职责 |
83
83
  |---|---|
84
- | [`src/index.ts`](src/index.ts) | 插件入口:shell 注册表、prompt 设置、命令包装、scrollback 轮询、提取与渲染 |
84
+ | [`src/index.ts`](src/index.ts) | 插件入口:shell 注册表、命令包装、scrollback 轮询、提取与渲染 |
85
85
  | — | 不发布运行时不变式伴生入口;适配器私有的 owner-to-shell 缓存不存在可观察的事件或数据关系。生命周期测试无需仅为不变式增加公共 API 即可验证其清理。 |
86
86
 
87
87
  ### 命令流程
88
88
 
89
- 首条命令通过 `ctx.terminals.spawn` 生成 shell,安装 `prompt` 覆盖,并等待就绪。随后每条命令都包装成一行物理文本——`Write-Output` 起始标记、用反引号转义进双引号字符串的命令体、`Write-Output` 结束标记加退出状态——因此 PSReadLine 对换行包装的回显无法伪造完成。工具以 1,000 行一页轮询 scrollback,直到出现结束标记或完成的提示符,提取区间、剥离回显的包装与提示符,并连同任何状态标记一起渲染。超时会中止截止时间、捕获部分输出并重置 shell。
89
+ 首条命令通过 `ctx.terminals.spawn` 生成 shell,其 pwsh 启动流程安装受控的 `prompt` 函数,并只在该 shell 达到就绪后返回。随后每条命令都包装成一行物理文本——`Write-Output` 起始标记、用反引号转义进双引号字符串的命令体、`Write-Output` 结束标记加退出状态——因此 PSReadLine 对换行包装的回显无法伪造完成。工具以 1,000 行一页轮询 scrollback,直到出现结束标记或该 send 以 `stdin_read` 结算,提取区间、剥离回显的包装,并连同任何状态标记一起渲染。超时会中止截止时间、捕获部分输出并重置 shell。
90
90
 
91
91
  </details>
92
92
 
@@ -128,7 +128,7 @@ kind: "package-reference"
128
128
 
129
129
  #### 模型看到什么
130
130
 
131
- 命令共享每个 agent 一个 shell,因此 cwd、`$env:` 变量、函数与后台任务都会跨调用保留。结果排除私有完成标记、shell 提示词与回显的输入行(PSReadLine 会把提交的输入渲染回流中;标记锚定提取与包装源码剥离会移除它)。非零的包装命令追加 `[exit code: N]`——命令运行原生程序时给出确切原生退出码,PowerShell 终止错误则为 `1`。在报告该状态前就退出的 shell 改为追加 `[shell exited: code N]`、`[shell killed by signal: SIG]`,或后端两者都未提供时的 `[shell exited]`(Windows 强制终止报告 exit 1 且没有信号),然后重置并告诉模型下一次调用从全新状态开始。长输出保留最早的已保留前缀并附裁剪通知;若 terminal 已经丢弃该前缀,结果会明确说明。超时返回有界部分输出、关闭不确定的 shell 并报告重置。
131
+ 命令共享每个 agent 一个 shell,因此 cwd、`$env:` 变量、函数与后台任务都会跨调用保留。结果排除私有完成标记与回显的输入行(PSReadLine 会把提交的输入渲染回流中;标记锚定提取与包装源码剥离会移除它)。当 shell 再次读取 stdin 却没有打印完成标记时——一次中断、一个被替换的 shell,或提供方能证明其 stdin 等待的交互式前台子进程——调用返回已捕获的部分输出,其结尾可能是后端自己的提示符文本。非零的包装命令追加 `[exit code: N]`——命令运行原生程序时给出确切原生退出码,PowerShell 终止错误则为 `1`。在报告该状态前就退出的 shell 改为追加 `[shell exited: code N]`、`[shell killed by signal: SIG]`,或后端两者都未提供时的 `[shell exited]`(Windows 强制终止报告 exit 1 且没有信号),然后重置并告诉模型下一次调用从全新状态开始。长输出保留最早的已保留前缀并附裁剪通知;若 terminal 已经丢弃该前缀,结果会明确说明。超时返回有界部分输出、关闭不确定的 shell 并报告重置。
132
132
 
133
133
  #### Token 影响
134
134
 
@@ -149,7 +149,7 @@ kind: "package-reference"
149
149
  - **输入回显不可避免**——PowerShell 的 PSReadLine 会把提交的输入渲染回终端流,而且没有 `stty -echo` 等价物。标记锚定提取在完整结果中排除回显;包装源码剥离覆盖回退路径,但跨终端宽度换行的包装可能在部分输出结果中留下部分回显,受 `maxOutputChars` 设界。
150
150
  - **模型命令内的原始 ESC 字符不受支持**——PSReadLine 会在执行前消费它们。包装器会转义它需要的控制字节(`[char]27` 构造的 OSC 标记、正文的反引号转义)。
151
151
  - **模型重定义 `prompt` 函数会移除就绪标记**——shell 随后在静默层级而非标记快路径上结算。
152
- - **命令期间没有交互 stdin**——读取输入的前台命令会一直阻塞到命令超时,随后重置 shell。
152
+ - **命令期间没有交互 stdin**——在提供方能证明前台 stdin 等待之处,读取输入的子进程会提前返回部分输出并保留会话,因此该子进程可能吞掉下一次调用的命令,直到那次调用到达 `timeoutMs` 并重置 shell。其他情况下原调用本身会运行到 `timeoutMs`,随后重置 shell。
153
153
  - **Windows 上 SIGTSTP/SIGHUP 不可用**(后端拒绝);SIGINT 以控制台级 Ctrl-C 输入写入投递,在提示词处会取消待处理行而不是向进程发信号。
154
154
  - **在 Windows ACL 沙箱的只读模式下,pwsh 以 ConstrainedLanguage 启动**,可能拒绝引导的 `[Console]::` 编码固定与 prompt 标记。命令仍可通过可打印提示词与静默层级结算,但非 ASCII 输出可能跟随宿主代码页。
155
155
  - **BEL 结尾的 OSC 标记目前只是就绪信号**——通向模型的 BEL 事件通道仍被推迟,与当前实现保持一致。
package/lib/index.js CHANGED
@@ -68,7 +68,6 @@ var __disposeResources = (function(SuppressedError) {
68
68
  const TRUNCATED_MESSAGE = "<response clipped><NOTE>To save on context only part of this file has been shown to you. You should retry this tool after you have searched inside the file with Select-String in order to find the line numbers of what you are looking for.</NOTE>";
69
69
  const LOST_PREFIX_MESSAGE = "<response clipped><NOTE>The beginning of this command output was dropped by the terminal scrollback limit. The following text is the earliest retained output.</NOTE>\n";
70
70
  const SHELL_RESET_MESSAGE = "The persistent pwsh shell was reset; the next pwsh call starts from the workspace with a fresh current directory and environment.";
71
- const SHELL_PROMPT = "__DSH_PERSISTENT_PWSH_PROMPT__ ";
72
71
  const TIMEOUT_CODE = "PERSISTENT_PWSH_TIMEOUT";
73
72
  const SCROLLBACK_PAGE_LINES = 1e3;
74
73
  const POLL_INTERVAL_MS = 25;
@@ -100,10 +99,8 @@ function wrapCommand(command, marker) {
100
99
  const body = quoteForPwsh(command);
101
100
  return `Write-Output '${marker.start}'; $LASTEXITCODE = $null; $__s = 1; try { Invoke-Expression "${body}"; $__ok = $? } catch { $__ok = $false }; if ($null -ne $LASTEXITCODE) { $__s = [int]$LASTEXITCODE } else { $__s = if ($__ok) { 0 } else { 1 } }; Write-Output ('${marker.end}' + $__s)`;
102
101
  }
103
- function stripPrompt(text) {
104
- let result = text.replace(/\r?\n$/, "");
105
- while (result.endsWith(SHELL_PROMPT)) result = result.slice(0, -31);
106
- return result.endsWith("\n") ? result.slice(0, -1) : result;
102
+ function trimTrailingNewline(text) {
103
+ return text.replace(/\r?\n$/, "");
107
104
  }
108
105
  function commandOutput(snapshot, marker, wrapper) {
109
106
  const text = snapshot.text;
@@ -120,20 +117,17 @@ function commandOutput(snapshot, marker, wrapper) {
120
117
  exitCode: Number(status)
121
118
  };
122
119
  }
123
- function promptCompleted(result) {
124
- return result.viewport.endsWith(SHELL_PROMPT) || result.viewport.endsWith(`${SHELL_PROMPT}\r\n`) || result.viewport.endsWith(`${SHELL_PROMPT}\n`);
125
- }
126
120
  function partialOutput(snapshot, marker, wrapper, fallback, fallbackTruncated = false) {
127
121
  const startMarker = snapshot.text.lastIndexOf(marker.start);
128
122
  if (startMarker >= 0) return {
129
- text: stripPrompt(snapshot.text.slice(startMarker + marker.start.length).replace(/^\r?\n/, "")),
123
+ text: trimTrailingNewline(snapshot.text.slice(startMarker + marker.start.length).replace(/^\r?\n/, "")),
130
124
  incomplete: false
131
125
  };
132
126
  const fallbackStart = fallback.lastIndexOf(marker.start);
133
127
  const afterStart = fallbackStart < 0 ? fallback : fallback.slice(fallbackStart + marker.start.length).replace(/^\r?\n/, "");
134
128
  const fallbackEnd = afterStart.lastIndexOf(marker.end);
135
129
  return {
136
- text: stripPrompt((fallbackEnd < 0 ? afterStart : afterStart.slice(0, fallbackEnd)).replaceAll(SHELL_PROMPT, "").replaceAll(wrapper, "")),
130
+ text: trimTrailingNewline((fallbackEnd < 0 ? afterStart : afterStart.slice(0, fallbackEnd)).replaceAll(wrapper, "")),
137
131
  incomplete: fallbackTruncated || fallbackStart < 0
138
132
  };
139
133
  }
@@ -191,13 +185,6 @@ async function respondToSessionExit(ctx, shells, owner, id, status, marker, wrap
191
185
  await shells.reset(owner, "persistent pwsh shell exited");
192
186
  return [renderShellExitStatus(renderCaptured(partialOutput(snapshot, marker, wrapped, fallback, fallbackTruncated), config.maxOutputChars), status.exitCode, status.signal), SHELL_RESET_MESSAGE].filter((part) => part.length > 0).join("\n");
193
187
  }
194
- /**
195
- * The pwsh prompt function that overrides the backend bootstrap value with
196
- * this tool's own prompt. `[char]27`/`[char]7` build the OSC bytes at runtime
197
- * because raw ESC characters in submitted input are unreliable under
198
- * PSReadLine.
199
- */
200
- const PWSH_PROMPT_SETUP = "function prompt { [Console]::Write([char]27 + ']133;D;' + [int]$LASTEXITCODE + [char]7); '__DSH_PERSISTENT_PWSH_PROMPT__ ' }";
201
188
  function persistentShells(ctx, config) {
202
189
  const pending = /* @__PURE__ */ new WeakMap();
203
190
  const live = /* @__PURE__ */ new Map();
@@ -242,12 +229,6 @@ function persistentShells(ctx, config) {
242
229
  live.delete(owner);
243
230
  }, "tool-pwsh-persistent owner cache cleanup");
244
231
  }
245
- const result = await ctx.terminals.startSend(owner, spawned.sessionId, {
246
- text: PWSH_PROMPT_SETUP,
247
- submit: true,
248
- signal: combinedSignal
249
- }).done;
250
- if (result.sessionStatus.kind === "exited" || result.waitReason === "timeout") throw new Error("persistent pwsh shell did not accept initialization");
251
232
  return spawned.sessionId;
252
233
  } catch (error) {
253
234
  await reset(owner, "persistent pwsh initialization failed");
@@ -328,7 +309,7 @@ async function executeCommand(ctx, shells, owner, command, config, upstream) {
328
309
  if (complete !== void 0) return renderCaptured(complete, config.maxOutputChars);
329
310
  }
330
311
  if (result.sessionStatus.kind === "exited") return await respondToSessionExit(ctx, shells, owner, id, result.sessionStatus, marker, wrapped, fallback, fallbackTruncated, config);
331
- if (promptCompleted(result)) return renderCaptured(partialOutput(retainedScrollback(ctx, owner, id, latest), marker, wrapped, fallback, fallbackTruncated), config.maxOutputChars);
312
+ if (result.waitReason === "stdin_read") return renderCaptured(partialOutput(retainedScrollback(ctx, owner, id, latest), marker, wrapped, fallback, fallbackTruncated), config.maxOutputChars);
332
313
  await pause();
333
314
  }
334
315
  } catch (e_1) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-tool-pwsh-persistent",
3
3
  "description": "Model-facing owner-scoped persistent PowerShell tool backed by the Harness PTY service",
4
- "version": "0.1.7-alpha.1",
4
+ "version": "0.1.7-rc.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -26,32 +26,32 @@
26
26
  ],
27
27
  "license": "MIT",
28
28
  "peerDependencies": {
29
- "@deepseek-ai/dsh-agent": "^0.1.7-alpha.1",
30
- "@deepseek-ai/dsh-terminal": "^0.1.7-alpha.1",
31
- "@deepseek-ai/dsh-timeout": "^0.1.7-alpha.1",
32
- "@deepseek-ai/dsh-tools": "^0.1.7-alpha.1",
33
- "@deepseek-ai/cordis": "^4.0.3"
29
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.1",
30
+ "@deepseek-ai/dsh-terminal": "0.1.7-rc.1",
31
+ "@deepseek-ai/dsh-timeout": "0.1.7-rc.1",
32
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.1",
33
+ "@deepseek-ai/cordis": "~4.0.4"
34
34
  },
35
35
  "dependencies": {
36
- "@deepseek-ai/schemastery": "^3.18.3"
36
+ "@deepseek-ai/schemastery": "~3.18.4"
37
37
  },
38
38
  "devDependencies": {
39
- "@deepseek-ai/cordis-plugin-include": "^1.0.8",
40
- "@deepseek-ai/cordis-plugin-loader": "^1.0.4",
41
- "@deepseek-ai/dsh-agent": "^0.1.7-alpha.1",
42
- "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.7-alpha.1",
43
- "@deepseek-ai/dsh-llm": "^0.1.7-alpha.1",
44
- "@deepseek-ai/dsh-terminal": "^0.1.7-alpha.1",
45
- "@deepseek-ai/dsh-terminal-bash": "^0.1.7-alpha.1",
46
- "@deepseek-ai/dsh-pwsh-local": "^0.1.7-alpha.1",
47
- "@deepseek-ai/dsh-sandbox": "^0.1.7-alpha.1",
48
- "@deepseek-ai/dsh-session": "^0.1.7-alpha.1",
49
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.7-alpha.1",
50
- "@deepseek-ai/dsh-session-projection": "^0.1.7-alpha.1",
51
- "@deepseek-ai/dsh-subprocess-local": "^0.1.7-alpha.1",
52
- "@deepseek-ai/dsh-system-prompt": "^0.1.7-alpha.1",
53
- "@deepseek-ai/dsh-timeout": "^0.1.7-alpha.1",
54
- "@deepseek-ai/dsh-tools": "^0.1.7-alpha.1",
55
- "@deepseek-ai/cordis": "^4.0.3"
39
+ "@deepseek-ai/cordis-plugin-include": "~1.0.9",
40
+ "@deepseek-ai/cordis-plugin-loader": "~1.0.5",
41
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.1",
42
+ "@deepseek-ai/dsh-agent-loop-testkit": "0.1.7-rc.1",
43
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.1",
44
+ "@deepseek-ai/dsh-terminal": "0.1.7-rc.1",
45
+ "@deepseek-ai/dsh-terminal-bash": "0.1.7-rc.1",
46
+ "@deepseek-ai/dsh-pwsh-local": "0.1.7-rc.1",
47
+ "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.1",
48
+ "@deepseek-ai/dsh-session": "0.1.7-rc.1",
49
+ "@deepseek-ai/dsh-session-projection": "0.1.7-rc.1",
50
+ "@deepseek-ai/dsh-subprocess-local": "0.1.7-rc.1",
51
+ "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.1",
52
+ "@deepseek-ai/dsh-timeout": "0.1.7-rc.1",
53
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.1",
54
+ "@deepseek-ai/dsh-sandbox": "0.1.7-rc.1",
55
+ "@deepseek-ai/cordis": "~4.0.4"
56
56
  }
57
57
  }