dsh-paoding 0.4.0 → 0.4.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.
@@ -234,6 +234,12 @@ doctor 不改任何文件,逐项检查并给出 `✔ 正常 / ⚠ 警告 / ✘
234
234
 
235
235
  `dsh plugin add` 报 pnpm 相关错误:`dsh plugin` 依赖 pnpm 装包。`npm i -g pnpm`(或 `corepack enable`)装好后重试。
236
236
 
237
+ 面板「升级」报 `spawn pnpm ENOENT` 是同一件事的 desktop 形态:desktop profile 的升级不走 dsh 转发器,而是直跑 `pnpm add`,PATH 里没有裸 `pnpm`(pnpm 由 corepack 托管、又没跑过 `corepack enable` 的机器就是这样)即报此错。0.4.1 起升级自动按「裸 pnpm → `corepack pnpm` → PNPM_HOME 常见落位」回落,一般无需处理;更早版本手动升一把即可:
238
+
239
+ ```bash
240
+ cd "${DSH_HOME:-$HOME/.dsh}/profiles/desktop" && corepack pnpm add dsh-paoding@latest
241
+ ```
242
+
237
243
  **装了插件,预设列表里却没有「编排模式 (Orchestrator)」**
238
244
 
239
245
  预设由插件启动时自动生成:先确认装完后**重启过 DSH**;预设在新会话创建时装载,重启后还要新建一个会话才会出现在选择器里。仍没有就查 DSH 日志里 `paoding-config-ui` 的告警(自动生成失败会记日志,可到面板手动「保存并应用」补上),再检查 `ls "${DSH_HOME:-$HOME/.dsh}/.agent-presets/orchestrator"`——目录为空多半是插件运行时的 `$DSH_HOME` 与你以为的家目录不一致(启动 DSH 前显式 `export DSH_HOME=…`)。目录在、宿主又是 0.1.7+ 而选择器里仍没有时,再查 `$DSH_HOME/cordis.patch.yml` 里有无 dsh-paoding 托管块——0.1.7 靠块内声明行发现预设,缺块就到面板点一次「保存并应用」补写(见第 2 节「版本支持与预设落点双轨」)。
@@ -234,6 +234,12 @@ The panel runs the same checks on every save: each Preview / Save & Apply respon
234
234
 
235
235
  `dsh plugin add` fails with a pnpm error: `dsh plugin` relies on pnpm to install packages. Install it (`npm i -g pnpm` or `corepack enable`) and retry.
236
236
 
237
+ The panel's Upgrade button reporting `spawn pnpm ENOENT` is the same problem in its desktop form: desktop-profile upgrades bypass the dsh forwarder and run `pnpm add` directly, which fails the same way when no bare `pnpm` is on PATH (typical for corepack-managed setups that never ran `corepack enable`). Since 0.4.1 the upgrade falls back automatically — bare `pnpm` → `corepack pnpm` → common PNPM_HOME locations — so no action is normally needed; on earlier versions, upgrade manually:
238
+
239
+ ```bash
240
+ cd "${DSH_HOME:-$HOME/.dsh}/profiles/desktop" && corepack pnpm add dsh-paoding@latest
241
+ ```
242
+
237
243
  **The plugin is installed but "编排模式 (Orchestrator)" is not in the preset list**
238
244
 
239
245
  The preset is generated automatically when the plugin starts: first make sure you **restarted DSH** after installing; presets load when a session is created, so after the restart you also need a new session for it to appear in the selector. Still nothing? Check the DSH log for `paoding-config-ui` warnings (a failed auto-generation is logged; apply manually from the panel), then check `ls "${DSH_HOME:-$HOME/.dsh}/.agent-presets/orchestrator"` — an empty directory usually means the plugin's runtime `$DSH_HOME` differs from the home directory you assumed (export `DSH_HOME=…` explicitly before launching DSH). If the directory is there, the host is 0.1.7+, and the selector still shows nothing, check `$DSH_HOME/cordis.patch.yml` for the dsh-paoding managed block — 0.1.7 discovers presets through the declaration rows inside it; if the block is missing, hit Save & Apply once in the panel to write it (see §2 "Version support and the dual preset landing").
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-paoding",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "庖丁 — DSH (DeepSeek Harness) 编排模式安装器:host 感知的角色工具过滤 + Web 设置页可视化配置器",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paoding-config-ui",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "main": "index.mjs",
@@ -13,7 +13,10 @@
13
13
  * profile 目录里直跑 `pnpm add dsh-paoding@<目标版本>`:本包已在 profile
14
14
  * package.json 的 dsh.profile.bundles 清单里,无需 bundle reconcile;用
15
15
  * 精确版本而非 update,避开 pnpm 新鲜度防护 / 镜像 packument 滞后造成的
16
- * 静默空转。
16
+ * 静默空转。pnpm 本身按候选链解析(裸 pnpm → corepack pnpm → PNPM_HOME
17
+ * 常见落位,仅 ENOENT 换下一路)——corepack 管的机器没跑过 corepack
18
+ * enable 时 PATH 里没有裸 pnpm,0.3.8~0.4.0 直 spawn 裸名即报
19
+ * `spawn pnpm ENOENT`(0.4.1 修)。
17
20
  *
18
21
  * 本模块只负责「拿目标版本 → 探测自身 profile → 跑子进程」这一段编排;
19
22
  * profile 名从本文件运行时真实路径反推(registry 安装形态必然位于
@@ -77,7 +80,7 @@ function defaultSpawn(command, args, options, timeoutMs, timeoutLabel) {
77
80
  }, timeoutMs)
78
81
  child.on('error', (err) => {
79
82
  clearTimeout(timer)
80
- resolve({ code: null, output: tailOutput(output), error: String(err?.message ?? err) })
83
+ resolve({ code: null, output: tailOutput(output), error: String(err?.message ?? err), errorCode: err?.code ?? null })
81
84
  })
82
85
  child.on('close', (code) => {
83
86
  clearTimeout(timer)
@@ -128,8 +131,10 @@ function desktopProfileDir() {
128
131
  * node:child_process 的 spawn、Date.now()。
129
132
  * - timeoutMs:升级子进程超时(含 pnpm 下载安装),默认 120s。
130
133
  * - spawnImpl 契约:(command, args, options, timeoutMs, timeoutLabel) →
131
- * Promise resolving { code, output, error? }(同 defaultSpawn 的收敛形状;
132
- * timeoutLabel 仅缺省实现用于超时文案,注入桩可忽略)。
134
+ * Promise resolving { code, output, error?, errorCode? }(同 defaultSpawn
135
+ * 的收敛形状;errorCode 为子进程 spawn 失败的 err.code,如 'ENOENT',
136
+ * desktop 分支据此走 pnpm 候选链回落;timeoutLabel 仅缺省实现用于超时
137
+ * 文案,注入桩可忽略)。
133
138
  * @returns {Promise<object>} 恒不抛错,收敛为:
134
139
  * - { ok: true, upToDate: true, current } 本地已不落后 registry
135
140
  * - { ok: true, version, profile, output, elapsedMs } 升级成功(退出码 0)
@@ -193,19 +198,62 @@ async function doRunUpgrade({ profile, fetchImpl, spawnImpl, timeoutMs, now }) {
193
198
  return { ok: false, error: `desktop profile 目录不存在或未初始化: ${desktopDir}` }
194
199
  }
195
200
  const useShell = process.platform === 'win32'
196
- const command = isDesktop ? (useShell ? 'pnpm.cmd' : 'pnpm') : useShell ? 'dsh.cmd' : 'dsh'
197
201
  const args = isDesktop
198
202
  ? ['add', `dsh-paoding@${targetVersion}`]
199
203
  : ['plugin', '--profile', resolved, 'update', 'dsh-paoding']
200
204
  const run = typeof spawnImpl === 'function' ? spawnImpl : defaultSpawn
201
- const proc = await run(command, args, {
205
+ const spawnOptions = {
202
206
  cwd: isDesktop ? desktopDir : os.tmpdir(),
203
207
  env: process.env,
204
208
  stdio: ['ignore', 'pipe', 'pipe'],
205
209
  shell: useShell,
206
- }, timeoutMs, isDesktop ? 'pnpm add' : 'dsh plugin update')
210
+ }
211
+
212
+ // pnpm/dsh 候选链:spawn ENOENT(命令在 PATH 里不存在)才换下一路,
213
+ // EACCES / 超时 / 退出码非 0 都是真实运行结果,如实返回不换通道。
214
+ // - 裸 pnpm:npm i -g pnpm / homebrew 等常规安装直接命中;
215
+ // - corepack pnpm:corepack 随 node 发行,node 在 PATH 就兜得住,
216
+ // 未 enable 也能即装即用(corepack pnpm add ...);
217
+ // - PNPM_HOME 常见落位(darwin ~/Library/pnpm、linux ~/.local/share/pnpm)
218
+ // 的绝对路径:pnpm 独立安装脚本形态,spawn 绝对路径不依赖 PATH;
219
+ // existsSync 预筛,不存在不浪费一次 spawn。
220
+ // 常规 profile 的 dsh 单候选同走这套循环,ENOENT 也收敛成可读文案。
221
+ const suffix = useShell ? '.cmd' : ''
222
+ const candidates = isDesktop
223
+ ? [
224
+ { command: `pnpm${suffix}`, argsPrefix: [], label: 'pnpm' },
225
+ { command: `corepack${suffix}`, argsPrefix: ['pnpm'], label: 'corepack pnpm' },
226
+ ]
227
+ : [{ command: `dsh${suffix}`, argsPrefix: [], label: 'dsh' }]
228
+ if (isDesktop) {
229
+ const homes = [path.join(os.homedir(), 'Library', 'pnpm'), path.join(os.homedir(), '.local', 'share', 'pnpm')]
230
+ for (const home of homes) {
231
+ const bin = path.join(home, `pnpm${suffix}`)
232
+ if (existsSync(bin)) candidates.push({ command: bin, argsPrefix: [], label: bin })
233
+ }
234
+ }
235
+
236
+ let proc = null
237
+ for (const cand of candidates) {
238
+ proc = await run(cand.command, [...cand.argsPrefix, ...args], spawnOptions, timeoutMs,
239
+ isDesktop ? 'pnpm add' : 'dsh plugin update')
240
+ if (proc?.errorCode !== 'ENOENT') break
241
+ }
207
242
  const output = tailOutput(proc?.output)
208
243
 
244
+ // 全候选 ENOENT:给可操作的出路,不裸抛 spawn xxx ENOENT。
245
+ if (proc?.errorCode === 'ENOENT') {
246
+ const tried = candidates.map((c) => c.label).join(' / ')
247
+ return {
248
+ ok: false,
249
+ error: isDesktop
250
+ ? `未找到可用的 pnpm(已试 ${tried})。可先在终端执行 corepack enable 并重启 DSH 后重试;或手动升级:cd ${desktopDir} && corepack pnpm add dsh-paoding@${targetVersion}`
251
+ : `未找到 dsh 命令(PATH 异常?已试 ${tried}),请检查 dsh 安装后重试`,
252
+ output,
253
+ elapsedMs: elapsedMs(),
254
+ }
255
+ }
256
+
209
257
  // ④ 无磁盘后验(旧 npx 时代读 $DSH_HOME/dsh-paoding 对账的方案已随该目录
210
258
  // 一并废弃):本进程代码不随升级变化,无从对账;成功与否以退出码为准,
211
259
  // 新版本重启 DSH 后生效(preset 由新版启动钩子自动重生成)。