فهرست منبع

fix(web): probe pwsh through the executor's path resolution

The pwsh-terminal e2e probed the bare 'pwsh' literal, which knip flagged as
an unlisted binary. Reuse resolvePwshPath from @deepseek-ai/dsh-pwsh-local
(the judgment the tool-pwsh tests already use), so the probe matches the
executor's own resolution and the reference stays indirect; record mode
skips the lane anyway, so the probe stays inert there. Regenerate the
cordis and config catalogs the seam moves left stale (line-number shifts).
Huanqi Cao 1 ماه پیش
والد
کامیت
838e3c8cd9
5فایلهای تغییر یافته به همراه14 افزوده شده و 6 حذف شده
  1. 1 0
      apps/web/package.json
  2. 8 4
      apps/web/tests/pwsh-terminal.e2e.ts
  3. 1 1
      docs/config-catalog.md
  4. 1 1
      docs/cordis-catalog/services.md
  5. 3 0
      pnpm-lock.yaml

+ 1 - 0
apps/web/package.json

@@ -24,6 +24,7 @@
     "@deepseek-ai/dsh-client-ui-primitives": "workspace:^",
     "@deepseek-ai/dsh-client-ui-slots": "workspace:^",
     "@deepseek-ai/dsh-client-web-react": "workspace:^",
+    "@deepseek-ai/dsh-pwsh-local": "workspace:^",
     "@types/node": "^22.0.0",
     "@types/react": "~18.3.1",
     "@types/react-dom": "~18.3.0",

+ 8 - 4
apps/web/tests/pwsh-terminal.e2e.ts

@@ -16,6 +16,7 @@ import { fileURLToPath } from 'node:url'
 import type { Browser, Page } from 'playwright'
 import { chromium } from 'playwright'
 import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest'
+import { resolvePwshPath } from '@deepseek-ai/dsh-pwsh-local'
 import {
   assertFixtureInventory, captureStableAria, compareOrRefreshGolden,
   fixtureUserPrompts, launchWebScaffold, seedSession, webSnapshotMode,
@@ -33,10 +34,13 @@ const MODE = webSnapshotMode()
 
 // The overlay swaps the shipped bash executor for @deepseek-ai/dsh-pwsh-local;
 // a host without a usable `pwsh` cannot boot it, so the lane self-skips,
-// mirroring the pwshOnly ACP scenarios.
-const HAS_PWSH = spawnSync(
-  'pwsh', ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', 'exit 0'],
-  { stdio: 'ignore' },
+// mirroring the pwshOnly ACP scenarios. The probe follows the executor's own
+// resolution (Program Files installs on Windows are found even when bare
+// `pwsh` is not on PATH), the same judgment the tool-pwsh tests reuse; record
+// mode skips the lane anyway, so the probe stays inert there.
+const HAS_PWSH = MODE === 'record' ? false : spawnSync(
+  resolvePwshPath(), ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', '$true'],
+  { encoding: 'utf8' },
 ).status === 0
 
 describe.skipIf(MODE === 'record' || !HAS_PWSH)('web e2e: pwsh calls render as bash-shaped terminal cards', () => {

+ 1 - 1
docs/config-catalog.md

@@ -1866,7 +1866,7 @@ export interface Config {
 }
 ```
 
-Source: [`packages/bash/tool-pwsh/src/index.ts:41`](../packages/bash/tool-pwsh/src/index.ts)
+Source: [`packages/bash/tool-pwsh/src/index.ts:43`](../packages/bash/tool-pwsh/src/index.ts)
 
 ## `@deepseek-ai/dsh-tool-ralph`
 

+ 1 - 1
docs/cordis-catalog/services.md

@@ -293,7 +293,7 @@ abstract start(spec: BashExecSpec): BashProcess
 
 Types: [BashExecRequest](../core-data-structures/bash.md) · [BashExecSpec](../core-data-structures/bash.md) · [BashProcess](../core-data-structures/bash.md) · [BashRunResult](../core-data-structures/bash.md)
 
-Source: [`packages/bash/bash/src/index.ts:51`](../../packages/bash/bash/src/index.ts)
+Source: [`packages/bash/bash/src/index.ts:53`](../../packages/bash/bash/src/index.ts)
 
 ## `ctx.bashEnv` — `BashEnvRegistry`
 

+ 3 - 0
pnpm-lock.yaml

@@ -520,6 +520,9 @@ importers:
       '@deepseek-ai/dsh-client-web-react':
         specifier: workspace:^
         version: link:../../packages/client/web-react
+      '@deepseek-ai/dsh-pwsh-local':
+        specifier: workspace:^
+        version: link:../../packages/bash/pwsh-local
       '@types/node':
         specifier: ^22.0.0
         version: 22.20.0