Skip to content

🐛 fix(sdk): grep native 隐藏文件口径对齐 rg 回退 + bash 只读测试去 shell 发现竞态 - #470

Merged
CavinHuang merged 3 commits into
mainfrom
worktree-agent-ad2649b6ea98f353a
Aug 23, 2026
Merged

🐛 fix(sdk): grep native 隐藏文件口径对齐 rg 回退 + bash 只读测试去 shell 发现竞态#470
CavinHuang merged 3 commits into
mainfrom
worktree-agent-ad2649b6ea98f353a

Conversation

@CavinHuang

Copy link
Copy Markdown
Owner

改动

#337 grep native 隐藏文件口径

  • runNativeSearch 给 native 层显式传 hidden: false:native 引擎此前默认搜隐藏文件,搜提交信息/邮箱/分支名时会把 .git/HEAD、packed-refs 当普通文件命中,count/total 虚高、分页错位
  • rg/grep 回退显式排除的 EXCLUDED_DIRS 全部为点前缀目录,ripgrep 语义下 hidden:false 一并跳过它们——native 通道无独立 exclude 参数,此即同等口径;补不变量测试钉住(清单加入非隐藏目录时测试失败即为提醒)
  • 抽出 buildNativeSearchOptions 纯函数,测试直接断言 native 调用参数(hidden/gitignore/mode/offset/max_count/context)

#463 bash 只读测试去 shell 发现竞态

  • 无 natives 二进制时 isReadOnly("git status") 走 parse-unavailable 回退,回退方言取决于 shell 发现结果:Windows CI 慢 runner 上 where.exe 探测逐候选超时会翻进 PowerShell 白名单使断言翻转
  • 分类测试注入确定性 LUME_BASH_PATH(形态匹配即返回、不做存在性检查),结论与 runner 快慢无关;finally 恢复,不影响真实 spawn 测试
  • 注释说明竞态因果链

验证

  • bun run typecheck 绿
  • bun test src/tools/grep.test.ts 6/6 绿
  • bash.test.ts 分类测试绿(durable worker 类测试存在与本改动无关的预存环境 flaky)

Fixes #337
Fixes #463

🤖 Generated with Claude Code

TaTaLiao and others added 2 commits August 23, 2026 01:37
native 层 Rust 侧 options.hidden 默认 true,会把 .git/HEAD、packed-refs
等当普通文件命中:count/total 虚高、分页偏移错位。rg/grep 回退默认跳过
隐藏且显式排除 EXCLUDED_DIRS(全部点前缀),native 通道无独立 exclude
参数,hidden:false 即同等口径。抽出 buildNativeSearchOptions 纯函数并
补参数口径测试。

Fixes #337

Co-Authored-By: Claude Fable <noreply@anthropic.com>
无 natives 时 "git status" 走 parse-unavailable 回退,回退方言取决于
resolveShellInvocation 的解析结果:Windows CI 的 where.exe bash 发现逐
候选 1s 超时,runner 慢时全部超时回退 powershell.exe,"git status" 命中
PowerShell 白名单翻转成 true,断言随 runner 快慢漂移。注入确定性
LUME_BASH_PATH(形态匹配即返回、不做存在性检查)把回退 shell 钉在
bash 形态上,结论与探测快慢无关;finally 恢复原值不影响真实 spawn 测试。

Fixes #463

Co-Authored-By: Claude Fable <noreply@anthropic.com>
@CavinHuang

Copy link
Copy Markdown
Owner Author

Review

结论

Approve。两处修复方向正确、实现干净,核心口径主张经本地 natives 二进制 + 真实 rg 双通道对照实测证实。1 条流程性 P2(不阻塞)+ 2 条 P3 记录。

发现

[P2] "Fixes #463" 合并即关闭 issue,正文里的深层问题会失去跟踪载体。 #463 正文明确指出比 flaky 更值得修的一层:isReadOnly 是权限判定,其结论依赖运行时 shell 发现是否超时(resolveWindowsBashPath 首次调用恰逢超时窗口时翻进 PowerShell 方言),测试侧注入只稳住了测试,生产路径的判定非确定性仍在(discoveredWindowsBashPath 缓存写入前的窗口)。建议合并后开 follow-up issue 跟踪实现侧修复(权限判定路径不做带超时的发现,或发现失败时 fail-closed 固定方言),避免 Fixes 自动关单后丢失这部分。

[P3] commit/#337 的动机案例与二进制实测行为不符(不影响修复正确性)。 本地 win32-x64 dist 实测(临时目录造 a.txt/.env/.github/ci.yml/.git/HEAD):hidden=true 时命中 .env.github/ci.yml恒不命中 .git/HEAD——native 二进制对 .git 有独立于 hidden/gitignore 参数的跳过逻辑(rg 开 --hidden 反而会搜 .git/HEAD)。所以 "#337 把 .git/HEAD、packed-refs 当普通文件命中" 的现象在当前 dist 上不可复现;真实缺口是 .env/.github 这类非 .git 点前缀内容,bug 本身存在、修复必要。Rust 源不入库、dist 版本无法核对,记录存疑。

[P3] "同等口径"严格说仅对 rg 回退成立。 GNU grep 回退既不跳 EXCLUDED_DIRS 之外的隐藏项也不尊重 .gitignore(会搜到 .env),三通道在 main 上本就不完全同口径,属预存差异非本 PR 引入。gitignore 维度上 native(gitignore:true) ↔ rg(默认尊重)一致 ✓。

已核实(逐条实证)

  1. hidden 口径等价性(重点 1/2):main 上 buildRgArgs 未开 --hidden(rg 默认跳过一切点前缀文件+目录),六成员 --glob !dir/** 为冗余双保险。实测对照:同目录布局下 rg 默认 = {a.txt},native hidden:false + gitignore:true = {a.txt}结果集完全一致hidden:false 确认同时跳过点前缀文件.env)与目录(.github),不只是目录。TS binding 层 omitUndefined 会剥掉未传字段交 Rust 默认兜底,显式传 false 可靠覆盖默认值。
  2. buildNativeSearchOptions 纯函数(重点 3):PR head 全文与 main 内联版逐字段比对一致,仅新增 hidden:false,无透传漏项('-n' 本就不透传 native,预存)。不变量测试断言强度足够:every(startsWith('.')) + toContain('.git'),未来加入 node_modules 类成员必失败。
  3. env 注入机制(重点 4)LUME_BASH_PATHresolveWindowsBashPath 的 configured 分支优先级最高(压过 CLAUDE_CODE_SHELL/SHELL);normalizeBashPath 纯形态匹配(bash/zsh 结尾正则)确无存在性检查;注入走 configured 提前返回,不触碰 where.exe 发现及其模块级缓存 discoveredWindowsBashPath(该缓存仅在发现路径读写),故 finally 恢复后同文件后续真实 spawn 测试不受残留影响(bun 同文件串行执行)。finally 包裹全部断言,覆盖所有退出路径。生产误设影响面:该 env 是既有产品功能(有专门测试钉住),指向不存在路径时 spawn ENOENT 报错为预存行为,isReadOnly/isConcurrencySafe 判定路径只读无副作用。
  4. 竞态暴露点唯一性(重点 5):核实为真。PS 白名单正则含 git\s+(?:status|log|show)\b,是唯一翻转源;其余断言中重定向命令被入口 /[>\]|>>/正则前置拒绝、powershell 前缀命令被analyzeBashCommand前置拦截(不依赖 shell 发现)、find/sed 批次走skipIf(nativeBashAvailable) 隔离,全部恒定。isConcurrencySafeisReadOnly` 同一函数同一暴露点,一并钉死。
  5. CI(重点 6):checks 4/4 绿。两 commit 各对一个 issue 划分干净;emoji 前缀合规;文案无来源表述;无 scope creep。

@CavinHuang
CavinHuang merged commit bd8c35b into main Aug 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants