Skip to content

fix(skills): 修复本地 skills 根目录发现#509

Merged
deepcoldy merged 1 commit into
masterfrom
fix/local-skill-root-discovery
Jul 18, 2026
Merged

fix(skills): 修复本地 skills 根目录发现#509
deepcoldy merged 1 commit into
masterfrom
fix/local-skill-root-discovery

Conversation

@DeepColds

Copy link
Copy Markdown
Collaborator

改了什么

  • 当本地 Skill 安装源本身就是名为 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 仓库扫描。
  • CLI:不是 Claude 专用;所有原生 Skill 根目录(Claude/Codex/Gemini/Cursor 等)在直接传入末级 skills 目录时均可受益。
  • 远程仓库:仅当仓库 checkout 根目录本身名为 skills 时新增直接子目录扫描;原有标准 repo/skills/<name>.agents/skills.botmux/skills 行为不变,候选按路径去重。
  • 后端/会话类型/平台:不涉及 PTY/Tmux、会话恢复、sandbox 或 IM 路由;路径判断使用 Node 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 秒超时)
  • 单独复跑相关 Skill 测试仍为 29/29 通过;单独复跑前两个无关失败测试仍稳定复现,确认与本 PR 改动无关。

@DeepColds
DeepColds requested a review from deepcoldy as a code owner July 17, 2026 05:28

@deepcoldy deepcoldy left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查结论:✅ 无阻塞(head ed0aa43

改动聚焦:discoverLocalSkillCandidates 在输入目录 basename 为 skills(含符号链接两侧判定)时扫描直接子目录,子目录仍走 candidateFromDirassertPathWithin 防护,dedupeAndSortCandidates 兜住重叠,无新增越界面。

实际验证(本机独立复跑)

  • pnpm build 通过
  • 新测试隔离跑 test/skill-registry-store.test.ts 10/10;skill 相关全部 13 个测试文件 121/121 全绿
  • dist 产物真实行为探针 6 场景:xxx/.claude/skills(bug 场景,修复生效)、尾斜杠、名为 skills 的符号链接根、reposkills/ 子目录(旧行为不变,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 根内的符号链接技能不会被发现listChildDirsentry.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 deepcoldy left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

独立二审结论:无阻塞,可合并(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。

@deepcoldy
deepcoldy merged commit 2e8291f into master Jul 18, 2026
1 check 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

Development

Successfully merging this pull request may close these issues.

2 participants