docs: record the pwsh/bash parity decision and refresh catalogs and bilingual pairs
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-01-pwsh-tool-and-executor.md
|
||||
2026-08-01-pwsh-tool-and-executor.md: fd73e929804045d7b810a587c6f088b2f7cff9cc
|
||||
2026-08-01-pwsh-tool-and-executor.zh.md: f55be1ad0e102311d09b8b7ee1a003778e679cb2
|
||||
2026-08-01-pwsh-tool-and-executor.md: 7206f8ffe6640f8499f8453c40ab5846b23112c6
|
||||
2026-08-01-pwsh-tool-and-executor.zh.md: 5a48adb79fed209d2d2ecb9514fd51538491f04c
|
||||
|
||||
@@ -13,7 +13,7 @@ The harness spoke one shell dialect on every platform: `bash`. Windows hosts cou
|
||||
Two new packages under `packages/bash/`:
|
||||
|
||||
- **`@deepseek-ai/dsh-pwsh-local`** — a local implementation of the `ctx.bash` executor seam over `ctx.subprocess`, mirroring `dsh-bash-local` call-for-call: `resolve()` defaults and caps from config, `run()` fuses the config-clamped timeout with the caller's signal through one deadline, `start()` returns a consuming background handle whose processes belong to the subprocess service. The command string rides as ONE argv element to `pwsh -NoLogo -NoProfile -NonInteractive -Command`, so PowerShell parses it and no shell-quoting layer exists. Executable resolution (`resolvePwshPath`) is a pure function of `(configured, env, platform)`: explicit config first, then Windows probes PowerShell 7's install, PATH entries (quotes stripped), and Windows PowerShell 5.1, else a bare `pwsh` via PATH.
|
||||
- **`@deepseek-ai/dsh-tool-pwsh`** — the minimal model-facing tool over `ctx.bash`, PowerShell-dialect by contract: foreground only, no `run_in_background`, no sandbox escalation, managed `DSH_*` environment (`DSH_HOME`, `DSH_SHELL=1`, `DSH_SESSION_ID`), result markers `[exit code: N]` / `[timed out after …]` / `[killed by signal: …]`, and `terminal`/`generic` UI presenters.
|
||||
- **`@deepseek-ai/dsh-tool-pwsh`** — the model-facing tool over `ctx.bash`, PowerShell-dialect by contract, mirroring `dsh-tool-bash` call-for-call minus the sandbox surface: foreground and `run_in_background` execution through the generic task runtime, managed `DSH_*` environment through the shared [`dsh-bash-env`](../feature/2026-08-02-pwsh-tool-bash-parity.md) registry, and the bash marker/truncation rendering story (a clean exit produces no marker). The parity decision supersedes this note's minimal-profile tool description.
|
||||
|
||||
Windows vitest coverage is deliberately NOT part of this change: the repo's Windows CI lane owns build/static gates, and unit coverage runs on Linux, where both packages' suites run against a real `pwsh` (preinstalled on the GitHub-hosted runners) or self-skip when absent. The vitest `windowsUnsupportedPackages` exclusion narrows from `packages/bash/*` to the bash-requiring packages so the pwsh suites can also run natively on Windows dev machines.
|
||||
|
||||
@@ -30,6 +30,6 @@ The roadmap beyond this decision — defaulting Windows hosts to `pwsh` (bash of
|
||||
## Consequences
|
||||
|
||||
- The bash executor seam gains a second, Windows-native implementation with an identical request/spec contract, so model-facing consumers beyond `tool-pwsh` (hooks bridges, in-process plugins) can run PowerShell without dialect shims.
|
||||
- `tool-pwsh` is the model-visible Windows-first profile: no background tasks or escalation to mislead a model into assuming bash-tool parity, and the prompt guidance pins the `[exit code: N]` contract.
|
||||
- `tool-pwsh` is the model-visible Windows-first shell tool: behaviorally interchangeable with the bash tool for foreground and background work (minus sandbox), with prompt guidance that states the marker contract precisely.
|
||||
- Windows semantics differ where the platform differs: forced termination reports exit 1 with no signal (so `signal`/`killed` status facts are POSIX-only), and PowerShell writes CRLF, which tests normalize.
|
||||
- The CLI gains two workspace dependencies and two tsconfig projects without mounting either plugin — the composition decision stays with the Windows-default proposal.
|
||||
|
||||
@@ -13,7 +13,7 @@ harness 在每个平台只说一种 shell 方言:`bash`。Windows 主机只能
|
||||
在 `packages/bash/` 下新增两个包:
|
||||
|
||||
- **`@deepseek-ai/dsh-pwsh-local`** —— `ctx.bash` 执行器 seam 的本地实现,基于 `ctx.subprocess`,逐调用镜像 `dsh-bash-local`:`resolve()` 从配置默认化并设上限,`run()` 通过一个 deadline 融合配置夹取的超时与调用方信号,`start()` 返回消费式后台句柄,其进程归属于 subprocess 服务。命令字符串作为 ONE argv 元素传给 `pwsh -NoLogo -NoProfile -NonInteractive -Command`,由 PowerShell 解析,不存在 shell 引号层。可执行文件解析(`resolvePwshPath`)是 `(configured, env, platform)` 的纯函数:先显式配置,再在 Windows 上探测 PowerShell 7 安装位置、PATH 条目(剥离引号)与 Windows PowerShell 5.1,否则经 PATH 解析裸 `pwsh`。
|
||||
- **`@deepseek-ai/dsh-tool-pwsh`** —— 基于 `ctx.bash` 的最小面向模型工具,契约是 PowerShell 方言:仅前台,没有 `run_in_background`,没有沙箱升级,受管 `DSH_*` 环境(`DSH_HOME`、`DSH_SHELL=1`、`DSH_SESSION_ID`),结果标记 `[exit code: N]` / `[timed out after …]` / `[killed by signal: …]`,以及 `terminal`/`generic` UI presenter。
|
||||
- **`@deepseek-ai/dsh-tool-pwsh`** —— 基于 `ctx.bash` 的面向模型工具,契约是 PowerShell 方言,逐调用镜像 `dsh-tool-bash`、减去 sandbox 面:经通用任务运行时执行前台与 `run_in_background`,经共享 [`dsh-bash-env`](../feature/2026-08-02-pwsh-tool-bash-parity.md) 注册表管理 `DSH_*` 环境,以及 bash 的 marker/截断渲染故事(干净退出不产生 marker)。parity 决策取代了本 note 的最小画像工具描述。
|
||||
|
||||
Windows vitest 覆盖率刻意不属本次改动:仓库的 Windows CI 通道负责构建/静态门禁,单元覆盖在 Linux 上运行,两个包的套件在那里以真实 `pwsh` 运行(GitHub 托管 runner 预装)或缺失时自行跳过。vitest 的 `windowsUnsupportedPackages` 排除从 `packages/bash/*` 收窄为真正需要 bash 的包,使 pwsh 套件也能在 Windows 开发机上原生运行。
|
||||
|
||||
@@ -30,6 +30,6 @@ Windows vitest 覆盖率刻意不属本次改动:仓库的 Windows CI 通道
|
||||
## 后果
|
||||
|
||||
- bash 执行器 seam 有了第二个、Windows 原生的实现,请求/规范契约一致,因此 `tool-pwsh` 之外的面向模型消费方(hooks 桥、进程内插件)无需方言垫片即可运行 PowerShell。
|
||||
- `tool-pwsh` 是模型可见的 Windows 优先画像:没有后台任务或升级会让模型误以为与 bash 工具对等,提示词指导钉住 `[exit code: N]` 契约。
|
||||
- `tool-pwsh` 是模型可见的 Windows 优先 shell 工具:在前台与后台工作(减 sandbox)上与 bash 工具行为可互换,提示词指导精确陈述 marker 契约。
|
||||
- Windows 语义在平台差异处不同:强制终止报告退出码 1 且无信号(因此 `signal`/`killed` 状态实情仅限 POSIX),PowerShell 输出 CRLF,测试做归一化。
|
||||
- CLI 增加两个 workspace 依赖与两个 tsconfig 工程,但不挂载任一插件——组合决策留给 Windows 默认提案。
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-02-pwsh-tool-bash-parity.md
|
||||
2026-08-02-pwsh-tool-bash-parity.md: 3dcd1e8d4e7e6ea6841695f63012be184fa90f73
|
||||
2026-08-02-pwsh-tool-bash-parity.zh.md: 03aa9ed2109153d2e0426e7b680eb18c91f89aa7
|
||||
@@ -0,0 +1,33 @@
|
||||
# Agent Note: pwsh tool bash parity
|
||||
|
||||
Status: implemented
|
||||
|
||||
English | [中文](2026-08-02-pwsh-tool-bash-parity.zh.md)
|
||||
|
||||
## Problem
|
||||
|
||||
The first Windows-native foundation shipped `dsh-tool-pwsh` as a deliberately minimal profile — foreground only, no background tasks, no managed-environment parity beyond three hardcoded `DSH_*` keys, and a marker story ("always `[exit code: N]`") that diverged from the bash tool's rendering without being declared. Review of that change found the model-visible contract drifting from the implementation: the description promised spill-path reporting the renderer never performed, the README claimed exports that did not exist and rendering the tool did not do, and the tool's own tests pinned the lossy behavior. The minimal profile also left the `DSH_*` contributor seam duplicated-by-absence: plugins contributing environment facts to `ctx.bashEnv` had no effect on pwsh calls.
|
||||
|
||||
## Decision
|
||||
|
||||
`dsh-tool-pwsh` now mirrors `dsh-tool-bash` call-for-call, minus the sandbox surface, and its model-visible text describes exactly that behavior:
|
||||
|
||||
- **Rendering adopts the bash story verbatim**: stdout, a marked `[stderr]` section, truncation notices with spill paths, `(no output)` for an empty body, and exit markers only for non-zero exits — a clean exit produces no marker. The description and the `tool:pwsh` prompt section state this precisely ("Non-zero exits are reported as `[exit code: N]` markers"), deliberately not copying the bash prompt's "every result" phrasing, which its own renderer contradicts.
|
||||
- **`run_in_background` is wired through the generic task runtime** exactly like the bash tool: preflight, owner registration, `task_output`/`task_kill` control, and the same outcome mapping. `pwsh-local`'s already-mirrored `start()` handle backs it.
|
||||
- **The `DSH_*` environment is shared, not duplicated**: `BashEnvRegistry` moved out of `dsh-tool-bash` into a new tool-independent `@deepseek-ai/dsh-bash-env` package (`ctx.bashEnv` + built-ins + the session-persistence contributor), and both shell tools inject it. Contributors apply to pwsh calls exactly as they do to bash calls, resolving the bash tool's `FIXME(bash-env-ownership)`.
|
||||
- **Windows reality is pinned where bash has no analog**: every command runs under a UTF-8 I/O preamble so the Windows PowerShell 5.1 fallback cannot garble non-ASCII output through the UTF-8-decoding collector, and the prompts teach that Windows forced termination settles as exit 1 without a signal marker.
|
||||
- **Out of scope, unchanged**: sandbox escalation (waits for a Windows-confining executor), persistent PTY shells (backends are Linux/macOS-only; ConPTY is roadmap work), and pwsh-specific TUI/GUI presentation (generic/terminal cards stay; a PowerShell-aware terminal card with an exit pill is roadmap work).
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**Keep the minimal profile and fix only the claims.** Rejected: the review's core finding was that text contracts copied from bash drift without the corresponding implementation; a minimal tool plus accurate claims still leaves pwsh calls without background execution, without contributor parity, and with a divergent marker story that must be re-justified forever.
|
||||
|
||||
**Extract a fully shared tool implementation base (abstract shell dialect, two thin leaves).** Considered and deferred: the bash-env extraction and the structural mirror (`render.ts`/`background.ts` twins) are the foundation it would rest on; a full base waits until a third dialect or the persistent-PTY twin makes the abstraction's shape observable.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The bash and pwsh tools are now behaviorally interchangeable for foreground and background shell work (minus sandbox), and the pwsh prompt/description sentences are each backed by the renderer — the reviewer's grep-against-code check passes.
|
||||
- `@deepseek-ai/dsh-bash-env` is a new shipped package; `dsh-tool-bash`'s `dshHome` config moved there, so compositions mounting the shell tools must also mount `bash-env` (the spine bundles do).
|
||||
- Windows-only semantics (CRLF normalization, forced-termination exit-1/signal-null, POSIX-only self-signal) remain pinned by tests as before.
|
||||
- The pwsh tool's per-file coverage gate rides on the scriptable fake-executor suite (`tests/tools.spec.ts`); the real-pwsh integration and Loader-composition suites self-skip where `pwsh` is absent, mirroring the bash suites' division of labor.
|
||||
- The roadmap proposal's parity stage is delivered; its remaining stages are the Windows default composition and pwsh TUI/GUI rendering.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Agent Note: pwsh 工具与 bash 对齐
|
||||
|
||||
Status: implemented
|
||||
|
||||
[English](2026-08-02-pwsh-tool-bash-parity.md) | 中文
|
||||
|
||||
## 问题
|
||||
|
||||
首个 Windows 原生基础交付的 `dsh-tool-pwsh` 是刻意最小的画像——仅前台、无后台任务、受管环境只有三个硬编码 `DSH_*` 键、以及一个未声明就偏离 bash 工具的 marker 故事("恒打 `[exit code: N]`")。对该变更的 review 发现模型可见契约与实现脱节:描述承诺了渲染器从未执行的 spill 路径报告,README 宣称了不存在的导出与工具未做的渲染,工具自己的测试还钉死了有损行为。最小画像还让 `DSH_*` contributor seam 因缺席而重复:向 `ctx.bashEnv` 贡献环境事实的插件对 pwsh 调用毫无作用。
|
||||
|
||||
## 决策
|
||||
|
||||
`dsh-tool-pwsh` 现在逐调用镜像 `dsh-tool-bash`,减去 sandbox 面,其模型可见文本精确描述这一行为:
|
||||
|
||||
- **渲染完全采用 bash 故事**:stdout、带标记的 `[stderr]` 段、带 spill 路径的截断通知、空体渲染 `(no output)`、退出 marker 仅限非零退出——干净退出不产生 marker。描述与 `tool:pwsh` prompt section 精确陈述这一点("Non-zero exits are reported as `[exit code: N]` markers"),刻意不复制 bash prompt 中与其自身渲染矛盾的 "every result" 措辞。
|
||||
- **`run_in_background` 经通用任务运行时接线**,与 bash 工具完全一致:预检、owner 注册、`task_output`/`task_kill` 控制与相同的结果映射。其背后是 `pwsh-local` 早已镜像好的 `start()` 句柄。
|
||||
- **`DSH_*` 环境共享而非复制**:`BashEnvRegistry` 从 `dsh-tool-bash` 迁入新的工具无关包 `@deepseek-ai/dsh-bash-env`(`ctx.bashEnv` + 内置事实 + session-persistence contributor),两个 shell 工具都注入它。contributor 对 pwsh 调用与 bash 调用一视同仁,并消化了 bash 工具的 `FIXME(bash-env-ownership)`。
|
||||
- **Windows 现实在 bash 无对应处钉死**:每条命令都在 UTF-8 I/O preamble 下运行,使 Windows PowerShell 5.1 兜底无法经 UTF-8 解码的 collector 破坏非 ASCII 输出;prompt 教授 Windows 强制终止以无 signal 的 exit 1 结算。
|
||||
- **范围外,不变**:sandbox 升级(等待 Windows-confining 执行器)、持久 PTY shell(后端仅限 Linux/macOS;ConPTY 属路线图)、pwsh 专属 TUI/GUI 呈现(维持 generic/terminal 卡;带退出 pill 的 PowerShell 感知 terminal 卡属路线图)。
|
||||
|
||||
## 备选方案
|
||||
|
||||
**保留最小画像,只修声明。** 否决:review 的核心发现是"从 bash 复制的文本契约在缺少对应实现时会漂移";最小工具加准确声明仍让 pwsh 调用没有后台执行、没有 contributor 对等、并留下一个必须永远重新辩护的偏离 marker 故事。
|
||||
|
||||
**提取完全共享的工具实现基座(抽象 shell 方言,两个薄叶子)。** 考虑后推迟:bash-env 提取与结构镜像(`render.ts`/`background.ts` 孪生)是它要立足的基础;在出现第三种方言或持久 PTY 孪生、让抽象的形态可观察之前,不做完整基座。
|
||||
|
||||
## 后果
|
||||
|
||||
- bash 与 pwsh 工具在前台与后台 shell 工作(减 sandbox)上行为可互换,pwsh 的 prompt/描述句每句都有渲染器背书——reviewer 的"拿代码 grep 对证"检查通过。
|
||||
- `@deepseek-ai/dsh-bash-env` 成为新的交付包;`dsh-tool-bash` 的 `dshHome` 配置迁往那里,因此挂载 shell 工具的组合也必须挂载 `bash-env`(spine bundle 已如此)。
|
||||
- Windows 专属语义(CRLF 归一化、强制终止 exit-1/signal-null、仅 POSIX 的自信号)一如既往由测试钉住。
|
||||
- pwsh 工具的 per-file 覆盖门禁由可脚本化的 fake-executor 套件(`tests/tools.spec.ts`)承担;真实 pwsh 的集成与 Loader 组合套件在无 `pwsh` 的宿主自跳过,与 bash 套件的分工一致。
|
||||
- 路线图提案的 parity 阶段已交付;其余阶段是 Windows 默认组合与 pwsh TUI/GUI 渲染。
|
||||
Reference in New Issue
Block a user