Summary
skill search only runs a single content search query. The upstream gh skill search runs 4 parallel queries and merges results. This means our search misses skills where the query matches the file path but not the file content — which is the common case for domain-specific skills (e.g. "cargowise" in plugins/cargowise/skills/code-review/SKILL.md).
Problem
Current query: cargowise filename:SKILL.md path:SKILL.md
This searches for "cargowise" inside SKILL.md files. But domain skills like CargoWise have generic SKILL.md content (e.g. "Deep code review...") — the domain context is in the repo path, not the file content.
Upstream gh skill approach (from cli/cli trunk)
The upstream searchByKeyword function runs up to 4 parallel queries:
- Primary (content):
filename:SKILL.md <query> — searches inside SKILL.md
- Path:
filename:SKILL.md path:<pathTerm> — matches file path (spaces → hyphens)
- Owner (auto-detected):
filename:SKILL.md user:<query> — when query looks like a GitHub username (no explicit --owner set)
- Hyphen (multi-word):
filename:SKILL.md <pathTerm> — when query has spaces, also try hyphenated form ("mcp apps" → "mcp-apps")
Merge priority: path > hyphen > owner > primary content. Then deduplicate by repo/qualifiedName.
Key helper: couldBeOwner(query) — returns true if the query looks like a valid GitHub username (alphanumeric + dashes, ≤ 39 chars). This is what triggers the auto-detected owner search.
Proposal
Match upstream's multi-query approach in src/core/skill-search.ts:
-
Add buildSearchQueries(query, owner) function that returns an array of { q: string, priority: number } objects:
- Priority 1 (highest):
filename:SKILL.md path:<pathTerm> where pathTerm = query.replace(/ /g, '-')
- Priority 2:
filename:SKILL.md <pathTerm> (hyphenated content search, only if query has spaces)
- Priority 3:
filename:SKILL.md user:<query> (only if no explicit --owner and couldBeOwner(query) is true)
- Priority 4 (lowest):
filename:SKILL.md <query> (primary content search)
-
Add couldBeOwner(query) helper — regex ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$ (GitHub username rules)
-
Run queries in parallel using Promise.all / Promise.allSettled. Each query is an independent fetch call to api.github.com/search/code.
-
Merge results by priority order (path > hyphen > owner > primary), then deduplicate by repo + qualifiedName (existing dedup logic).
-
Error handling: if a non-primary query fails, log and continue (don't fail the whole search). Only fail if the primary query fails.
-
Rate limit consideration: 4 parallel requests vs 1. Authenticated = 30 req/min, so 4 parallel is fine. Unauthenticated = 10 req/min — 4 parallel uses 4 of 10. Acceptable.
Scope
src/core/skill-search.ts — add query builder, parallel execution, merge logic
tests/unit/core/skill-search.test.ts — test each query type, merge order, dedup
Why
Without this, searching "cargowise" in WiseTechGlobal returns 0 results despite 37+ CargoWise skills existing at plugins/cargowise/skills/. The path-based search is the primary way users find domain-specific skills.
Summary
skill searchonly runs a single content search query. The upstreamgh skillsearch runs 4 parallel queries and merges results. This means our search misses skills where the query matches the file path but not the file content — which is the common case for domain-specific skills (e.g. "cargowise" inplugins/cargowise/skills/code-review/SKILL.md).Problem
Current query:
cargowise filename:SKILL.md path:SKILL.mdThis searches for "cargowise" inside SKILL.md files. But domain skills like CargoWise have generic SKILL.md content (e.g. "Deep code review...") — the domain context is in the repo path, not the file content.
Upstream
gh skillapproach (fromcli/clitrunk)The upstream
searchByKeywordfunction runs up to 4 parallel queries:filename:SKILL.md <query>— searches inside SKILL.mdfilename:SKILL.md path:<pathTerm>— matches file path (spaces → hyphens)filename:SKILL.md user:<query>— whenquerylooks like a GitHub username (no explicit--ownerset)filename:SKILL.md <pathTerm>— when query has spaces, also try hyphenated form ("mcp apps" → "mcp-apps")Merge priority: path > hyphen > owner > primary content. Then deduplicate by
repo/qualifiedName.Key helper:
couldBeOwner(query)— returns true if the query looks like a valid GitHub username (alphanumeric + dashes, ≤ 39 chars). This is what triggers the auto-detected owner search.Proposal
Match upstream's multi-query approach in
src/core/skill-search.ts:Add
buildSearchQueries(query, owner)function that returns an array of{ q: string, priority: number }objects:filename:SKILL.md path:<pathTerm>wherepathTerm = query.replace(/ /g, '-')filename:SKILL.md <pathTerm>(hyphenated content search, only if query has spaces)filename:SKILL.md user:<query>(only if no explicit--ownerandcouldBeOwner(query)is true)filename:SKILL.md <query>(primary content search)Add
couldBeOwner(query)helper — regex^[a-zA-Z0-9]([a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$(GitHub username rules)Run queries in parallel using
Promise.all/Promise.allSettled. Each query is an independentfetchcall toapi.github.com/search/code.Merge results by priority order (path > hyphen > owner > primary), then deduplicate by
repo + qualifiedName(existing dedup logic).Error handling: if a non-primary query fails, log and continue (don't fail the whole search). Only fail if the primary query fails.
Rate limit consideration: 4 parallel requests vs 1. Authenticated = 30 req/min, so 4 parallel is fine. Unauthenticated = 10 req/min — 4 parallel uses 4 of 10. Acceptable.
Scope
src/core/skill-search.ts— add query builder, parallel execution, merge logictests/unit/core/skill-search.test.ts— test each query type, merge order, dedupWhy
Without this, searching "cargowise" in WiseTechGlobal returns 0 results despite 37+ CargoWise skills existing at
plugins/cargowise/skills/. The path-based search is the primary way users find domain-specific skills.