Priority: medium · Bridges "I want a skill that does X" → install. Be aware of API rate-limit caveat (see below).
Problem
`allagents skills add` requires the user to already know the source repository and skill name. There is no discovery mechanism inside the CLI today — users have to browse GitHub manually, ask another tool, or follow a link in a README. `gh skill search ` solves this by hitting the GitHub Code Search API for `SKILL.md` files matching the query and ranking results by relevance. Implementation reference: `cli/cli` `pkg/cmd/skills/search/search.go`.
Rate-limit caveat: unauthenticated Code Search API hits the public rate limit fast (and the `gh skill` team is tracking it in `cli/cli` issue #13293). Authenticated requests get a higher quota; for allagents, the existing `src/core/github-fetch.ts` plumbing should already handle auth.
Current behavior
```bash
$ allagents skill search docs
error: found 1 error
skill search docs
^ Unknown arguments
$ allagents skills search docs
error: found 1 error
search docs
^ Unknown arguments
Today's discovery path is external — `gh search code path:SKILL.md docs` or web search.
```
Expected behavior
```bash
(1) Basic search — ranked by relevance, name matches first
$ allagents skill search terraform
Found 24 skills:
hashicorp/skills terraform-format Format terraform files
hashicorp/skills terraform-validate Run terraform validate
someorg/skills deploy-terraform Deploy a tf module
...
(2) Scope to an owner
$ allagents skill search terraform --owner hashicorp
Found 8 skills:
hashicorp/skills terraform-format Format terraform files
...
(3) Pagination + limit
$ allagents skill search docs --page 2 --limit 10
(4) Interactive selector pipes into install
$ allagents skill search docs
→ TUI selector — pick a row, press Enter → runs `allagents skill add` for that selection
(5) JSON envelope for agent consumers
$ allagents --json skill search docs --limit 5
{
"success": true,
"command": "skill search",
"data": {
"query": "docs",
"items": [
{ "name": "docs-writer", "repo": "someorg/awesome-skills", "path": "skills/docs-writer/SKILL.md", "description": "..." },
...
],
"total": 47,
"truncated": true
}
}
```
Verification gate (must pass before closing)
```bash
set -euo pipefail
bun run build
(1) Help text is wired
allagents skill search --help | grep -q 'owner'
(2) Basic search returns at least one result for a common term (requires auth + network)
allagents --json skill search documentation --limit 5 | jq -e '.data.items | length >= 1'
(3) --owner filter narrows results (asserting subset rather than exact match to keep test stable)
TOTAL=$(allagents --json skill search documentation --limit 50 | jq '.data.items | length')
SCOPED=$(allagents --json skill search documentation --owner github --limit 50 | jq '.data.items | length')
[ "$SCOPED" -le "$TOTAL" ]
(4) Pagination is monotonic — page 2 is a different result set than page 1
P1=$(allagents --json skill search documentation --page 1 --limit 5 | jq -c '.data.items | map(.repo + "/" + .path)')
P2=$(allagents --json skill search documentation --page 2 --limit 5 | jq -c '.data.items | map(.repo + "/" + .path)')
[ "$P1" != "$P2" ]
(5) Min-length validation on query
! allagents skill search a 2>/dev/null
(6) Page/limit validation
! allagents skill search docs --page 0 2>/dev/null
! allagents skill search docs --limit 0 2>/dev/null
(7) Unauthenticated rate-limit hit produces a clear error, not a generic 403/HTML dump
(This is hard to assert deterministically; instead unit-test the error-mapping code.)
```
Checks 1–6 must pass; check 7 is a guideline for the error-mapping unit test.
Implementation notes
- Add `searchCmd` under `skillsCmd` in `src/cli/commands/plugin-skills.ts`.
- Use `src/core/github-fetch.ts` for the API call so existing auth + token handling is reused. Endpoint: `GET /search/code` with a query like `path:SKILL.md filename:SKILL.md `. Optional `user:` qualifier when `--owner` is set.
- Ranking: name matches first, then description matches. Mirror `gh skill search`'s scoring — see `pkg/cmd/skills/search/search.go`.
- Validate args: query ≥ 2 chars (mirrors gh), `--page >= 1`, `--limit >= 1`. Reject invalid owner names with a regex (gh uses a permissive regex; copy it).
- Add `searchMeta` to `src/cli/metadata/plugin-skills.ts` and to the `allCommands` array in `src/cli/agent-help.ts`.
- `jsonFields` (per the json-allowlist issue): at minimum `name`, `repo`, `path`, `description`, `sha`.
- Rate-limit handling: if the API returns 403 with a rate-limit body, emit a clear actionable error — "GitHub Code Search rate limit exceeded; ensure you're authenticated with \`gh auth login\` or set \`GITHUB_TOKEN\`." Don't dump the raw response.
- Interactive selection: build on existing TUI primitives in `src/cli/tui/` (the wizard uses them). Pressing Enter on a row should invoke the install flow (the same path as `skill add`).
Refs
- Reference impl: `cli/cli` `pkg/cmd/skills/search/search.go`.
- Rate-limit prior art: `cli/cli` issue #13293.
- Companion wiki page: `concepts/allagents-vs-gh-skill.md` § "Marketplace integration".
Problem
`allagents skills add` requires the user to already know the source repository and skill name. There is no discovery mechanism inside the CLI today — users have to browse GitHub manually, ask another tool, or follow a link in a README. `gh skill search ` solves this by hitting the GitHub Code Search API for `SKILL.md` files matching the query and ranking results by relevance. Implementation reference: `cli/cli` `pkg/cmd/skills/search/search.go`.
Rate-limit caveat: unauthenticated Code Search API hits the public rate limit fast (and the `gh skill` team is tracking it in `cli/cli` issue #13293). Authenticated requests get a higher quota; for allagents, the existing `src/core/github-fetch.ts` plumbing should already handle auth.
Current behavior
```bash
$ allagents skill search docs
error: found 1 error
skill search docs
^ Unknown arguments
$ allagents skills search docs
error: found 1 error
search docs
^ Unknown arguments
Today's discovery path is external — `gh search code path:SKILL.md docs` or web search.
```
Expected behavior
```bash
(1) Basic search — ranked by relevance, name matches first
$ allagents skill search terraform
Found 24 skills:
hashicorp/skills terraform-format Format terraform files
hashicorp/skills terraform-validate Run terraform validate
someorg/skills deploy-terraform Deploy a tf module
...
(2) Scope to an owner
$ allagents skill search terraform --owner hashicorp
Found 8 skills:
hashicorp/skills terraform-format Format terraform files
...
(3) Pagination + limit
$ allagents skill search docs --page 2 --limit 10
(4) Interactive selector pipes into install
$ allagents skill search docs
→ TUI selector — pick a row, press Enter → runs `allagents skill add` for that selection
(5) JSON envelope for agent consumers
$ allagents --json skill search docs --limit 5
{
"success": true,
"command": "skill search",
"data": {
"query": "docs",
"items": [
{ "name": "docs-writer", "repo": "someorg/awesome-skills", "path": "skills/docs-writer/SKILL.md", "description": "..." },
...
],
"total": 47,
"truncated": true
}
}
```
Verification gate (must pass before closing)
```bash
set -euo pipefail
bun run build
(1) Help text is wired
allagents skill search --help | grep -q 'owner'
(2) Basic search returns at least one result for a common term (requires auth + network)
allagents --json skill search documentation --limit 5 | jq -e '.data.items | length >= 1'
(3) --owner filter narrows results (asserting subset rather than exact match to keep test stable)
TOTAL=$(allagents --json skill search documentation --limit 50 | jq '.data.items | length')
SCOPED=$(allagents --json skill search documentation --owner github --limit 50 | jq '.data.items | length')
[ "$SCOPED" -le "$TOTAL" ]
(4) Pagination is monotonic — page 2 is a different result set than page 1
P1=$(allagents --json skill search documentation --page 1 --limit 5 | jq -c '.data.items | map(.repo + "/" + .path)')
P2=$(allagents --json skill search documentation --page 2 --limit 5 | jq -c '.data.items | map(.repo + "/" + .path)')
[ "$P1" != "$P2" ]
(5) Min-length validation on query
! allagents skill search a 2>/dev/null
(6) Page/limit validation
! allagents skill search docs --page 0 2>/dev/null
! allagents skill search docs --limit 0 2>/dev/null
(7) Unauthenticated rate-limit hit produces a clear error, not a generic 403/HTML dump
(This is hard to assert deterministically; instead unit-test the error-mapping code.)
```
Checks 1–6 must pass; check 7 is a guideline for the error-mapping unit test.
Implementation notes
Refs