fix(skills): 修复本地 skills 根目录发现#509
Merged
Merged
Conversation
deepcoldy
approved these changes
Jul 17, 2026
deepcoldy
left a comment
Owner
There was a problem hiding this comment.
审查结论:✅ 无阻塞(head ed0aa43)
改动聚焦:discoverLocalSkillCandidates 在输入目录 basename 为 skills(含符号链接两侧判定)时扫描直接子目录,子目录仍走 candidateFromDir → assertPathWithin 防护,dedupeAndSortCandidates 兜住重叠,无新增越界面。
实际验证(本机独立复跑)
pnpm build通过- 新测试隔离跑
test/skill-registry-store.test.ts10/10;skill 相关全部 13 个测试文件 121/121 全绿 - dist 产物真实行为探针 6 场景:
xxx/.claude/skills(bug 场景,修复生效)、尾斜杠、名为skills的符号链接根、repo含skills/子目录(旧行为不变,path 仍为skills/beta)、单 skill 目录(root 早退不变)、直接传repo/skills - 端到端安装:从 skills 根 copy 安装(
skillNames选择)+ 从符号链接根--link安装均正常,join(sourceDir, candidate.path)路径重建正确
事实核对(比 PR 描述还保守)
- 远程 git 扫描实际完全不受影响:git checkout 目录是
sources/<sha256 前 16 位 hex>(sourceId()),basename 永远不可能是skills。PR 描述说「仅当仓库 checkout 根目录本身名为 skills 时」——该条件在 botmux 自身 git 流程中根本不会出现,远程路径零回归风险。
P3(非阻塞,建议后续跟进)
- skills 根内的符号链接技能不会被发现:
listChildDirs用entry.isDirectory()过滤,symlink→dir 的 dirent 返回 false(实测确认:skills 根内gamma-link → 真实 skill 目录被静默跳过)。这是listChildDirs既有行为(repo/skills/扫描同样受影响),非本 PR 引入;但本 PR 主打场景恰是用户手工维护的原生 skills 根(~/.claude/skills),符号链接较常见。后续可对 symlink 条目补statSync判定。
观察(无需处理)
- CLI
botmux skills install <skills根>不带选择且根内多技能时,报错从no_skills_found变为multiple_skills_found:<名单>——错误信息更可诊断,属改进。 - 根目录本身是合法 skill 且名为
skills时仍走 rootCandidate 早退(非 fullDepth),优先级语义不变。
deepcoldy
approved these changes
Jul 17, 2026
deepcoldy
left a comment
Owner
There was a problem hiding this comment.
独立二审结论:无阻塞,可合并(head ed0aa43)。
重点复核:
- Windows 路径:
node:path原生 basename/resolve/join/relative 在反斜杠、尾分隔符及 candidate.path 重建场景语义一致;当前精确匹配skills与既有目录约定一致。 fullDepth:skills 根直接子项与递归扫描重叠时按 path 去重;实测浅层返回alpha,fullDepth 补出nested/beta且无重复。- Dashboard 链路:discover/install 复用同一 local discovery,
.claude/skills自动 link;实测 dashboard discovery 与服务层结果一致。
独立验证:pnpm build 通过;聚焦 dashboard/registry 测试 18/18;vitest run skill 26 个文件 197/197;git diff --check 通过。未发现新增 finding。初审记录的 skills 根内 symlink 子技能跳过属于既有 P3,不阻塞本 PR。
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.
改了什么
skills的目录时,扫描其直接子目录。realpath后路径的 basename,兼容名为skills的符号链接。.claude/skills/<skill>/SKILL.md目录结构的回归测试,并确认非 Skill 子目录会被忽略。为什么
Dashboard/CLI 导入本地 Skill 时,填写
xxxx/.claude/skills无法发现其中的 Skill;填写xxxx/.claude或单个 Skill 目录则可以。原逻辑只会从输入目录继续查找skills/、.agents/skills/、.botmux/skills/,等价于错误地寻找.claude/skills/skills/*。影响面评估
discoverLocalSkillCandidates,会影响 Dashboard 本地导入、botmux skills discover/install,以及无显式 path 的 Git/GitHub 仓库扫描。skills目录时均可受益。skills时新增直接子目录扫描;原有标准repo/skills/<name>、.agents/skills、.botmux/skills行为不变,候选按路径去重。basename,并保留现有跨平台路径解析。实际验证
pnpm build:通过。pnpm exec vitest run --project unit test/skill-registry-store.test.ts test/dashboard-skill-install-request.test.ts test/skill-git-install.test.ts:3 个文件、29 个测试全部通过。pnpm test:共 581 个文件、9291 个测试;9285 通过,6 个失败。失败集中在既有 Linux 进程发现/时序测试:test/session-discovery.smoke.test.ts(当前环境 comm 返回MainThread)test/v3-worker-fence.test.ts(进程发现结果ambiguous)test/v3-cancel-runtime.test.ts(2 个 30 秒超时)