Repository navigation
fix(commit-message): 尊重已选仓库 repoRoot,修复多仓库工作区下的 not-a-repo - #10
Merged
Merged
Conversation
AI 生成提交信息是唯一没把「已选仓库」(repoRoot) 传到宿主的链路,工作区
根不是仓库时(并列多个仓库)必然失败:
- 宿主半 `commitMessage()`:只用 `cwdOf(payload)`,随后 `summary({ cwd })`
/ `diff({ cwd })` 都不带 repoRoot;而宿主里其余各处 git 调用统一走
`repoRootOf(cwd, payload)`。于是 `git rev-parse --show-toplevel` 在工作区
根上失败 → 409 `not-a-repo`。
- 客户端半 `aiRun()`:手工拼 payload `{ cwd, sessionId, model,
reasoningEffort, prompt }` 时漏了 repoRoot,而其它调用一律走
`Object.assign({}, base, …)`(`base = { cwd, repoRoot }`)。
修复:宿主按 `repoRootOf(cwd, payload)` 解析仓库并把 `{ cwd, repoRoot }`
传给 summary/diff;客户端把 `base` 下传 ChangesPanel 并用于该请求。
回归测试两处,均已在未修复代码上验证为**失败**:
- `tests/api.test.mjs`:工作区 cwd 不是仓库 + repoRoot 指向一个干净仓库
→ 400 `nothing to describe`(修复前 409 `not-a-repo`,因为干净仓库在调
模型前就返回,测试不消耗任何模型调用);不带 repoRoot 时仍 409,守卫
没有被放宽。
- `tests/smoke.mjs`:静态断言 `aiRun` 走 `Object.assign` 且带上
`props.base`,并断言 Panel 确实把 `base` 下传给了 ChangesPanel。
验证:`npm test` **106/106**(原 104/104 基线);真机 DSH 桌面 0.2.0-rc.2
上,同一路由带 repoRoot 由修复前的 409 `not-a-repo` 变为 400
`nothing to describe`,不带 repoRoot 仍为 409。
KannaKuron
approved these changes
Oct 9, 2026
KannaKuron
left a comment
Owner
There was a problem hiding this comment.
Reviewed and verified end to end — LGTM.
宿主侧(src/index.js)
commitMessage()补上的const repoRoot = await repoRootOf(cwd, payload)与其余 30 处调用点完全同构;summary(scope)/diff(scope)走{ cwd, repoRoot },两函数内部各自的repoRootOf直接命中 payload.repoRoot 快路径(还省掉了三次重复 rev-parse)。- 守卫没有被放宽:
repoRootOf零改动,不带 repoRoot 时仍从 cwd 解析、失败仍 409not-a-repo—— 新 api 测试显式断言了这一点。 commitRouteOf(payload)只读 model/sessionId,不受影响;commit-message不在 WRITE_METHODS(只读 git + 调模型),无需登记。
客户端侧(src/client.js)
base恰好是{ cwd, repoRoot }两个键(8448 的 useMemo),Object.assign({}, props.base, {…})不会扩散多余字段;repoRoot 为 undefined 时宿主侧!== undefined检查正确回退。E(ChangesPanel, { …, base: base })与既有 props 传法一致;ChangesPanel 唯一渲染点在 Panel 内,新加的props.base === undefined回退分支实际不可达,纯防御、无害。- 核对了其余 8 处 request 调用全部已是
Object.assign({}, base, …),本 PR 后 aiRun 与家族写法统一;repos / commit-models / commit-efforts 确实本就不该带。
测试
npm test106/106(基线 104 + 本 PR 2 个新测试)。- 独立复现了你声明的「未修复即失败」:checkout main 的 src 两个文件、保留 PR 测试再跑 → 恰好这两个新测试失败(104 pass / 2 fail),恢复后转绿 —— 测试有效性属实。
- api 新测试断言
seen.length === 0(fake stream 零调用)验证了「干净仓库在调模型前返回」的设计,不消耗模型额度,严谨。 - smoke 新测试的切片锚点(
E(ChangesPanel, {/onCommit:)在全文唯一,断言稳健。 - 顺带:本机(有 web profile)
scripts/ssr-check.mjs4 项渲染全绿 —— 印证你在 PR 里说的失败是本机无 profile 的环境问题,不算门槛;本机通过反而额外确认客户端半改动无 SSR 渲染回归。
按仓库惯例 squash merge + 删分支。感谢这份分析扎实的 PR!
KannaKuron
added a commit
that referenced
this pull request
Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
工作区根目录本身不是仓库、其下并列多个仓库时(本机工作区
D:\workspace\chemJobs-project下有ChemJobs、chemjobsapp),仓库选择器一切正常 —— 分支树 / 提交图谱 / 变更 / 普通提交与推送都能用 —— 但点提交框旁的 ✨ AI 生成提交信息必然失败:复现(直接打宿主路由;DSH 桌面 0.2.0-rc.2 / Windows / dsh-ide-git 0.14.3)
也就是说:该仓库本身完全可用,只有 AI 这一条路径拿不到它。
根因:
repoRoot在这条链路上漏了两次repoRoot是「用户在仓库选择器里选中的仓库」。其它所有 git 调用都带着它 —— 宿主侧 20 余处统一await repoRootOf(cwd, payload);客户端侧统一Object.assign({}, base, …),其中base = { cwd, repoRoot }。只有这条链路例外:src/index.js→commitMessage():只取cwdOf(payload),随后的summary({ cwd })/diff({ cwd })都不带repoRoot。src/client.js→aiRun():手工拼 payload{ cwd, sessionId, model, reasoningEffort, prompt }时漏了repoRoot。于是宿主拿工作区根去跑
git rev-parse --show-toplevel→ 不是仓库 → 409not-a-repo。我把客户端全部 9 个
request(...)调用点都过了一遍,漏repoRoot的只有这一处(repos是列仓库、commit-models/commit-efforts是取模型目录,本就不该带;NativePreviewPanel的 diff 在调用前就赋了payload.repoRoot)。改动
commitMessage()先const repoRoot = await repoRootOf(cwd, payload),再把{ cwd, repoRoot }传给summary/diff(与其余各处同一套写法)。Panel把base下传给ChangesPanel;aiRun()改用Object.assign({}, props.base, { … })。测试(都已在未修复代码上验证为失败)
tests/api.test.mjs新增:工作区 cwd 不是仓库 +repoRoot指向一个干净仓库 → 400nothing to describe;不带repoRoot时仍 409not-a-repo(守卫没有被放宽)。刻意选干净仓库:它在调用模型之前就返回,所以测试不消耗任何模型额度。tests/smoke.mjs新增:静态断言aiRun走Object.assign且带上props.base,并断言Panel确实把base下传给了ChangesPanel(没被下传的 prop 读出来是undefined,正是这次漏掉的形状)。对未修复代码:
api侧actual: 409, expected: 400;smoke侧 payload 断言不匹配。修复后两者转绿。验证
npm test106/106(基线 104/104;+2 为本 PR 新增)。repoRoot返回 409not-a-repo;修复后同一请求返回 400nothing to describe(证明已正确解析到所选仓库),不带repoRoot时仍返回 409。scripts/ssr-check.mjs:在未改动的 HEAD 上同样报错(Objects are not valid as a React child,react-dom 从全局 dsh 安装解析而来,本机没有仓库内node_modules),因此这一点不是本改动的证据,也不该算门槛。需要的话我可以按要求搭隔离实例再跑layout-probe/conversation-probe。备注
CHANGELOG 与版本号留给你在发版时填(按 AGENTS.md 的发版纪律);要我补一版条目说一声即可。