Skip to content

0.11.0 chorography T1:locateCliJs() 硬编码 app.asar/dsh/... 路径,DSH NEXT 布局下 T1 整体不可用(只报「headless 退出码 1:(无输出)」) #578

Closed

Description

@strange2000

现象

Windows 11 + DSH NEXT 2.0.22-next(electron 包名 dsh-desktop-next,内核 0.2.2-rc.1),@modusensus/dsh-mneme 0.11.0。

按文档跑 T1:

dsh-mneme-choro "D:/文档/DSH-Desktop/dsh-orb-cordis" --t1 --module packages-host --apply --model <provider/model>

0.7 秒就返回失败,什么都没做:

{"failed":[{"slug":"packages-host","reason":"headless 退出码 1:(无输出)"}]}

(无输出) 这四个字是关键:子进程根本没起来,所以 stderr 里也没有任何线索,自查成本很高。

定位(lib/wiki/t1.js:110-115)

function locateCliJs(exe) {
  // cli.js 固定在 exe 相对路径的 app.asar 内部。**不能 existsSync 校验**:CLI 进程
  // 是普通 node,没有 asar 支持 stat 不进包内——而 exe 自己(V1 实测)加载这个
  // 路径没问题。位置是安装器定的,直接给出去。
  return join(dirname(exe), "resources", "app.asar", "dsh", "node_modules", "@deepseek-ai", "dsh-desktop-host", "lib", "cli.js");
}

这里假定 asar 内多一层 dsh/。DSH NEXT 的安装不是这个布局——我读 asar 头部解出来的顶层条目是:

node_modules/  assets/  build/  lib/  scripts/  package.json
cordis.patch.yml  desktop-runtime.json  host.cordis.patch.yml

没有 dsh/ 这一层。asar 内 package.json 是 { name: "dsh-desktop-next", version: "2.0.22-next", main: "lib/main.js" },真正能当 headless CLI 用的是:

<install>/resources/app.asar/lib/desktop-cli.js     # --version 输出 0.2.2-rc.1

我把它换上去之后 T1 立刻正常(packages-host 72 秒、4 段 sections、18 条 claims、failed: [])。

顺带一个同类问题:locateDshExe()(:102-108)只认 basename(exe).toLowerCase() === "deepseek harness.exe" 或 %ProgramFiles%\DeepSeek Harness\DeepSeek Harness.exe。DSH NEXT 的 exe 叫 DSH NEXT.exe,两个条件都不满足 → 返回 null。目前只能靠 DSH_EXE 环境变量或 --dsh-exe 兜过去。

影响

  • 在 DSH NEXT 这类布局上,T1 整体不可用(T0 不受影响)。
  • 失败信息是 headless 退出码 1:(无输出),既不指向路径、也不指向 exe,用户基本无法自查。
  • 两处都是「位置由安装器定,直接给出去」,而安装器其实换过布局。

建议修法

  1. 别再硬编码单一路径,改成按优先级探测:

    • 环境变量 DSH_CLI_JS / 已有 DSH_EXE 同款逃生门;
    • resources/app.asar/lib/desktop-cli.js(DSH NEXT 现状);
    • resources/app.asar/dsh/node_modules/@deepseek-ai/dsh-desktop-host/lib/cli.js(旧布局,保留兼容)。

    探测本身不需要 stat 进 asar:asar 头部就是个 JSON(前 8 字节 pickle,后面 {"files":{...}}),读前几百 KB 就能判断 lib/desktop-cli.js 在不在;或者直接读 asar 内的 package.json 拿 bin / main。

  2. locateDshExe() 放宽:除了 DeepSeek Harness.exe,再接受同目录下 process.execPath 所在目录的任意 *.exe(或至少接受 DSH NEXT.exe);保持 DSH_EXE 优先。

  3. 失败时把子进程原始输出带出来:现在 (无输出) 会吞掉一切。哪怕只是把 cmd、拼好的 args、cwd、exit code 一起塞进 reason,自查成本就从「翻源码」降到「看一行日志」。我在本地是靠 createT1({ store, runSession }) 注入自己的 runSession 才定位到的。

环境

  • @modusensus/dsh-mneme 0.11.0
  • DSH NEXT 2.0.22-next(resources/app.asar 内 [email protected],CLI lib/desktop-cli.js 报 0.2.2-rc.1)
  • Windows 11,exe 路径含空格:D:\DSH NEXT\DSH NEXT.exe
  • 记忆库在 exFAT 共享卷 E:/mneme/memory.db(WAL)
  • T0 正常:165 文件 / 11 模块 / 13 文件 27.9 KB,gitBaseline d24375d1293a53c6bbe42098db99ef9359d15a05

Activity

  1. strange2000 commented on Nov 6, 2026

    @strange2000
    Author

    macOS 侧同现象,且比原报告多一层:路径推导在 macOS 上三处都对不上,所以即使补上 --dsh-exe 也必然失败。

    环境

    • mneme 0.11.0
    • macOS 15.7.1(黑苹果),DSH NEXT 桌面版
    • 仓库侧:dsh-mneme-choro 对本地 git 仓库跑 T0 成功(12 模块 12 页),随后 --t1 --module root --apply

    两段报错

    ① 不加 --dsh-exe(0.11.0 的前置校验先拦住了,提示已经比原报告友好):

    T1 整档不可用(环境级,页状态未动):找不到 DeepSeek Harness 主程序(设 DSH_EXE 环境变量,或用 --dsh-exe 显式指定)
    

    ② 补上 --dsh-exe "/Applications/DSH NEXT.app/Contents/MacOS/DSH NEXT",就变成原报告那句:

    ✗ root — headless 退出码 1:(无输出)
    富化 0 · 失败 1 · 跳过 11       耗时 2s
    

    根因:lib/wiki/t1.js:111-114

    return join(dirname(exe), "resources", "app.asar", "dsh",
                "node_modules", "@deepseek-ai", "dsh-desktop-host", "lib", "cli.js");

    以 macOS 的 exe = /Applications/DSH NEXT.app/Contents/MacOS/DSH NEXT 代入,会得到

    /Applications/DSH NEXT.app/Contents/MacOS/resources/app.asar/dsh/node_modules/...
    

    而实际布局是:

    /Applications/DSH NEXT.app/Contents/Resources/app.asar      ← 大写 R,且在 Contents 下而不是 MacOS 下
    /Applications/DSH NEXT.app/Contents/Resources/app.asar.unpacked
    /Applications/DSH NEXT.app/Contents/Resources/runtime/{arm64,x64}
    /Applications/DSH NEXT.app/Contents/Resources/app/
    

    三处差异:① Resources 大小写;② 目录层级(Contents/Resources vs Contents/MacOS/resources);③ 多一层 dsh/。

    一个可能更需要关注的观察

    我们枚举 app.asar 内的 node_modules/@deepseek-ai/(100+ 个包),没有在最外层看到 dsh-desktop-host;宿主另有 Resources/runtime/x64/primary-runtime 与 Resources/app/ 两层。也就是说 macOS 包里宿主 CLI 的位置可能和 Windows 不同,不只是「路径算错」——修路径之前可能得先确定各平台 CLI 的真实入口。

    建议

    1. locateCliJs 增加候选路径并做存在性校验(注释里写「不能 existsSync 校验」,但正因为不校验,失败只能退化成 (无输出),这是本 issue 难查的主要原因)。
    2. 失败时把实际尝试过的路径打进错误信息(现在 退出码 1:(无输出) 什么线索都没给)。
    3. 若 macOS 侧 CLI 位置确实不同,考虑允许用环境变量直接指定 CLI(DSH_CLI_JS),与 DSH_EXE 并存。

    T0 完全不受影响:模块地图、文件清单、choro_read_page / choro_search 在 macOS 上都正常。

  2. strange2000 commented on Nov 6, 2026

    @strange2000
    Author

    补一条 macOS 的实测:外挂 runner 已经绕过去了,T1 完全能跑,所以这个 issue 的实际影响面可以收窄——它挡的是"开箱即用",不挡能力本身。

    绕开方式(不改 node_modules)

    用插件自带的注入接口自己提供 runSession,把 CLI 换成真实存在的那份:

    const { createStore } = await import(`file:///${MK}/lib/store.js`)
    const { createT1 }     = await import(`file:///${MK}/lib/wiki/t1.js`)
    const store = createStore(DB)
    const t1    = createT1({ store, runSession })   // runSession 自己 spawn headless
    await t1.runT1({ repoRoot: REPO, model: MODEL, moduleSlug: SLUG, dryRun: false })

    关键事实:正确的 CLI 路径是什么

    macOS /Applications/DSH NEXT.app/Contents/Resources/ 下只有:

    app.asar            (单文件,237 MB)
    app.asar.unpacked/
    runtime/{arm64,x64}/
    app/
    

    没有 dsh/ 这一层。而在 app.asar 内部(用 Electron 自己的 fs 读,shell 的 ls 看不见):

    路径 是否存在
    lib/desktop-cli.js ✅ 存在(这就是该用的那个)
    lib/cli.js ✗
    dsh/node_modules/@deepseek-ai/dsh-desktop-host/lib/cli.js ✗

    也就是说 locateCliJs 不是"差几个字符",是多拼了一层目录,落点根本不存在。

    建议(按价值排序)

    1. 候选路径表里加 app.asar/lib/desktop-cli.js —— 一条就够覆盖 macOS 和 Windows 两端(Windows 侧实测同一个相对路径也能用)。
    2. 失败时把实际尝试过的每一个路径打进错误信息,而不是只抛 headless 退出码 1:(无输出)。现在的报错完全无法定位。
    3. 支持 DSH_CLI_JS 环境变量覆盖 —— 用户自己知道真路径时能救急。
    4. 顺带:runT1 成功写入 T1 段落后,.md 的 frontmatter status: 仍停在 skeleton(只有 choro_pages.status 变 enriched)。正文四段是完整的,不影响工具调用,但人肉看文件会误判。

    实测数据(供参考)

    仓库 12 模块,root 单模块 45.6s,12 模块批量 5 分 11 秒,全部 enriched、fail_count 全 0、126 条 claims。runner 与 Windows 的差异只有三处:主程序路径(.app/Contents/MacOS/DSH NEXT,无 .exe)、provider 名、以及从哪拿 API key。

  3. modusensus commented on Nov 11, 2026

    @modusensus
    Member

    修在 #618(其中第 ④ 项:「T1 不再按一种安装布局写死路径」)——CLI 定位不再硬编码 app.asar/dsh/...,DSH NEXT 布局下 T1 可以正常起来了。已随 v0.14.0-beta.1 发布。

    如果 beta.2 上仍复现「headless 退出码 1:(无输出)」,请重开并附上宿主的安装布局(app.asar 打包还是 NEXT 目录式)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions