Skip to content

skill search: namespace-aware dedup and ranking #390

@christso

Description

@christso

Summary

skill search results collapse namespaced skills with the same base name. For example, skills/kynan/commit and skills/will/commit both have name commit but different namespaces. Currently they collapse into one result because dedup uses bare name only.

Problem

  1. SkillSearchItem has no namespace field — only name (extracted as the parent dir of SKILL.md)
  2. Ranking uses bare name — two skills with same base name but different namespaces tie
  3. No dedup logic exists yet, but when added, it would need namespace awareness

Proposal

Follow the pattern from gh PR #13170:

  1. Add namespace field to SkillSearchItem — extract from path: skills/<namespace>/<name>/SKILL.md → namespace=<namespace>, name=<name>. For non-namespaced paths (skills/<name>/SKILL.md or <name>/SKILL.md), namespace is empty.

  2. Add qualifiedName() helper — returns namespace/name when namespace exists, just name otherwise.

  3. Update ranking — use qualifiedName() instead of bare name for score matching. Exact match on qualifiedName → score 3, prefix → 2, includes → 1.

  4. Add dedup by repo/qualifiedName — before returning results, deduplicate on repo + qualifiedName key. This prevents the same namespaced skill from appearing twice (e.g. if GitHub returns both skills/kynan/commit/SKILL.md and a re-publisher's copy).

  5. Update --json output — include namespace in the JSON fields.

Scope

  • src/core/skill-search.ts only
  • Add namespace to SkillSearchItem interface
  • Update searchSkills mapping to extract namespace from path
  • Add qualifiedName() helper
  • Update rankItems/score to use qualified name
  • Add dedup step before returning
  • Update tests

Why

Without this, searching for "commit" would show one result when there are actually multiple distinct skills named "commit" from different authors. The qualified name (namespace/name) is how gh skill handles this, and it's the agentskills.io convention.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions