repo-topic-tagger
Skill2 starsChanged 6 months agoApache-2.0View on GitHub
Audit and apply GitHub topic tags for discoverability — proposes tags from code signals, deduplicates against current tags, applies via gh api after explicit approval. Sub-skill of repo-seo-curator.
In this repository43 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- break-glassSkill
- claim-ledgerSkill
- contract-parity-auditSkill
- counterfactual-auditSkill
- design-doc-reviewSkill
- diagram-gen-emergentSkill
- diagram-gen-specSkill
- doc-triageSkill
- explain-workSkill
- feature-implSkill
- finding-triageSkill
- first-party-auditSkill
- gh-token-rotateSkill
- handoffSkill
- implementSkill
- jj-stackSkill
- linear-escalation-triageSkill
- mache-usageSkill
- park-workSkill
- pr-boardSkill
- pr-bucketsSkill
- prior-art-cartographerSkill
- problem-decomposerSkill
- pr-review-kitSkill
- pr-reviewSkill
- pr-suggestionSkill
- readme-restructureSkill
- repo-description-polishSkill
- repo-homepage-setSkill
- repo-social-previewSkill
- review-prepSkill
- review-queueSkill
- reviewSkill
- self-auditSkill
- structural-pr-reviewSkill
- surveySkill
- taskfile-ci-paritySkill
- test-fidelitySkill
- workflow-auditSkill
- work-scopeSkill
- writing-pr-descriptionsSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 132
If --dry-run (default): stop.
- Very specific: line 133
If --apply: print "Apply these N topic changes?
- Distinctive: line 177
One PR-equivalent per repo per pass: Don't bundle topic changes with description or README rewrites — those are separate skills.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- Author: jamestexas — drafted by claude-opus-4-7 (2026-05-16) -->/repo-topic-tagger — GitHub Topic Curation
Apply a curated, discoverability-optimized set of GitHub topics to one or more repositories.
Arguments
$ARGUMENTS
<owner/repo>— one or more target repos (e.g.agentic-research/mache). If omitted, defaults to the repo containing the current working directory.--dry-run(default) — propose changes but do not apply. Always the default. The user must explicitly pass--applyto write.--apply— after presenting the proposal, prompt for approval and callgh apito write the new topic set.--max=N— cap proposed tag count at N (default 12; GitHub allows 20 max).
What this solves
Many of the user's public repos ship with zero topics. This kills discoverability:
- They never surface in GitHub's topic browser (
github.com/topics/<x>) - They never appear in "related repositories" cards
- LLM-based repo discovery tools weight topic metadata heavily
- Human searchers filtering by topic on GitHub never see them
Topics are cheap to set, never break anything, and compound over time as GitHub's index picks them up.
Reference: a good topic set
agentic-research/cloister is the canonical good example:
capnproto, cloudflare-workers, durable-objects, gateway,
hypervisor, mcp, model-context-protocol, rust, typescript, workerdWhy it works:
- Language(s):
rust,typescript - Framework / runtime:
cloudflare-workers,workerd,durable-objects - Substrate / protocol:
capnproto,mcp,model-context-protocol - Problem-space label:
hypervisor,gateway
Ten tags, every one of them is something a real searcher would type.
GitHub topic rules (hard constraints)
The GitHub API will reject violations. Validate before submitting:
- Lowercase only
- Alphanumerics, hyphens,
+,.allowed; no underscores, no spaces - Each topic ≤ 50 chars
- ≤ 20 topics per repo
- Convention: prefer hyphens (
code-intelligence, notcodeintelligence)
Workflow
Phase 1: Inventory
For each target repo:
gh repo view <owner/repo> --json name,description,repositoryTopics,visibility,isFork,isArchived,homepageUrl,primaryLanguage,languagesSkip with a printed reason if:
visibility != PUBLIC(unless user explicitly overrides)isFork == trueisArchived == true
Phase 2: Signal gathering
For each remaining repo, collect signals from the codebase (use gh for remote; if a local clone is available, prefer reading files directly):
- Language metadata —
primaryLanguageand thelanguagesmap. The top 1–3 languages are almost always topics. - Package manifests — detect framework signals:
Cargo.toml→rust, plus notable deps (tokio,axum,serde,tree-sitter,wasmtime, …)package.json→typescriptornodejs, plus framework deps (next,react,hono,workerd,vite, …)go.mod→go, plus deps (cobra,bubbletea,cgo,tree-sitter, …)pyproject.toml/requirements.txt→python, plus deps (fastapi,pytorch,transformers, …)flake.nix/shell.nix→nixDockerfile/docker-compose.yml→dockerapko.yaml/melange.yaml→apko,chainguard.github/workflows/*→ CI signals (usually not topic-worthy alone)
- README + description — extract domain nouns. Look specifically for:
- Protocol names (
mcp,lsp,oauth,webauthn,cms,pkcs7) - System category (
cli,tui,library,framework,daemon,mcp-server) - Problem-space (
observability,vulnerability-scanning,code-intelligence,identity,signing,knowledge-graph)
- Protocol names (
- Project family / org context — the user's ecosystems. If repo is in
agentic-research, proposeagentic-researchandart-ecosystem. If injamestexasand references rosary/mache/ley-line, proposeart-ecosystem. - Existing topics — keep, don't fight. Only remove if actively misleading.
Phase 3: Proposal
Produce a structured proposal per repo:
## <owner/repo>
Description: <current description>
Current topics: <list or "(none)">
Proposed topics (N total):
Language: rust, typescript
Framework: cloudflare-workers, workerd, durable-objects
Protocol: capnproto, mcp, model-context-protocol
Domain: hypervisor, gateway
Ecosystem: agentic-research, art-ecosystem
Add: [list]
Remove: [list, or "(none)"]
Keep: [list]
Rationale: <1–2 sentences>Rationale rules:
- Add ≤
--max(default 12). Quality beats quantity. - Prefer canonical names —
model-context-protocolovermcp-protocol,cloudflare-workersovercf-workers. Checkhttps://github.com/topics/<x>exists if uncertain. - Avoid singletons that only describe this one repo. Topics are for finding kin.
- Avoid promotional adjectives — no
fast,modern,lightweightunless they're an established topic (high-performanceis borderline; usually skip).
Phase 4: Approval
Print the full proposal across all in-scope repos. Then:
- If
--dry-run(default): stop. Output a hint that the user can re-run with--applyto write. - If
--apply: print "Apply these N topic changes? (yes/no)" and wait. Only proceed on explicit affirmative.
Phase 5: Apply
For each approved repo:
gh api -X PUT "repos/<owner>/<repo>/topics" \
-H "Accept: application/vnd.github.mercy-preview+json" \
--input - <<EOF
{"names": ["tag1", "tag2", "..."]}
EOFOr equivalently with field args:
gh api -X PUT "repos/<owner>/<repo>/topics" \
-f "names[]=tag1" -f "names[]=tag2" ...After each call:
- Re-read with
gh repo view <owner/repo> --json repositoryTopicsto confirm - Report success or failure with the exact diff that landed
Phase 6: Report
End with a compact summary:
Applied:
agentic-research/mache — +8 topics, -0
agentic-research/rosary — +9 topics, -0
jamestexas/agents — +5 topics, -0
Skipped:
agentic-research/x-ray — empty repo, no signals to tag
agentic-research/.github — meta-repo, not user-facing
Deferred (no signals / needs human input):
jamestexas/papers — unclear scopeImportant rules
- Default to
--dry-run. The user must explicitly opt in to writes. Topics are public and indexed by third parties. - One PR-equivalent per repo per pass. Don't bundle topic changes with description or README rewrites — those are separate skills.
- Do not touch private repos unless the user explicitly names them. They get no discoverability benefit.
- Do not touch forks or archived repos unless explicitly named.
- If a repo has a working topic set (≥ 5 tags spanning ≥ 3 categories), leave it alone unless the user asked to revise it.
- No emoji in topics. GitHub strips them silently and they're not searchable.
Examples
/repo-topic-tagger agentic-research/mache
→ dry-run proposal for mache only
/repo-topic-tagger agentic-research/mache agentic-research/rosary --apply
→ proposal for both, then prompts for approval, then writes
/repo-topic-tagger
→ uses current working directory's GitHub remote (derived via `gh repo view`)Bulk mode (orgs)
For a whole-org sweep:
gh repo list <owner> --limit 100 --json name,visibility,isFork,isArchived,repositoryTopics \
| jq -r '.[] | select(.visibility=="PUBLIC" and .isFork==false and .isArchived==false) | .name'Iterate, but produce all proposals first, present them as a single document, and only apply after a single batched approval. Do not stream-apply.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

