plugins/qmd/skills/add/SKILL.md
Adds a reference collection to qmd. Accepts a GitHub URL, owner/repo shorthand, or a local directory path. Auto-detects file types, sets ignore globs, indexes with AST chunking, embeds, and verifies. Use when adding a new reference codebase or local notes folder for search.
npx skillsauth add ramonclaudio/skills addInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
ultrathink
<role> You are a reference library curator. Your job is to add new collections to qmd: cloning external GitHub repos OR registering existing local directories, detecting their structure, setting ignore globs, indexing them for search, embedding, and verifying they're ready for retrieval. You care about file type detection, mask correctness, ignore patterns, and index health. You execute every step and verify its output before proceeding. </role>!qmd collection list 2>/dev/null || echo "No collections yet"
$ARGUMENTS first token is required and is one of:
https://github.com/owner/repo (or [email protected]:owner/repo.git)owner/repo (e.g. vercel/next.js)/path/...), home-relative (~/path/...), or ././path for cwd-relative. Detected when test -d succeeds OR when the token starts with /, ~/, ./, or ../.$ARGUMENTS containing --name: Override collection name (must match [a-zA-Z0-9_-]+)$ARGUMENTS containing --mask: Skip auto-detection, use provided glob pattern$ARGUMENTS containing --dest: Override clone destination (default: ~/Developer/refs/). GitHub paths only, ignored for local paths.$ARGUMENTS containing --full: Clone with full history (not shallow). GitHub paths only.$ARGUMENTS containing --defer-embed: Skip embedding step, run /qmd:update later$ARGUMENTS containing --dry-run: Preview only. Run Steps 1-3, print plan, exittrash (if available), never rm--dest if provided, otherwise ~/Developer/refs/. Steps reference this as REFS. Final collection path is $REFS/<name>.~/.). REFS and --dest are not used.${XDG_CONFIG_HOME:-~/.config}/qmd/index.yml--dry-run: exit after Step 3. No cloning, no indexing, no embeddingqmd embed), exitLook at the first token of $ARGUMENTS:
GitHub URL (https://github.com/... or [email protected]:...):
github<owner>/<repo><repo> (override with --name)$REFS/<name>Owner/repo shorthand (matches ^[\w.-]+/[\w.-]+$ AND is not an existing directory):
githubhttps://github.com/<owner>/<repo><repo> (override with --name)$REFS/<name>Local directory (token starts with /, ~/, ./, ../, OR test -d <token> succeeds):
localrealpath <token> (or shell expansion for ~)handelize'd ([a-zA-Z0-9_-]+)--dest and --full if provided (warn the user they don't apply to local mode)--name, --mask, --defer-embed, --dry-run apply in both modes.
Print the parsed mode + name + final collection path before proceeding so the user can confirm.
If mode = github:
mkdir -p $REFS
If $REFS/<name> already exists, refresh it to the remote tip. A shallow fetch + reset keeps the read-only mirror shallow and never hits a fast-forward failure:
git -C $REFS/<name> fetch --depth 1 origin HEAD && git -C $REFS/<name> reset --hard FETCH_HEAD
Otherwise, shallow clone (default):
git clone --depth 1 https://github.com/<owner>/<repo> $REFS/<name>
If --full: omit --depth 1.
If mode = local:
Skip cloning entirely. The directory already exists (verified in Step 1). Move directly to Step 3.
If the local directory is a git repo, that's fine — Step 5 still sets a git pull --ff-only update command so /qmd:update will refresh it. If it's not a git repo (e.g., ~/Documents/notes), Step 5 should leave the update command empty so /qmd:update just re-indexes without trying to pull.
If --mask provided, use it and skip to Step 4.
Detect from the repo root:
detected = []
if package.json exists OR any .ts/.tsx files:
detected += "typescript"
if Cargo.toml exists OR any .rs files:
detected += "rust"
if go.mod exists OR any .go files:
detected += "go"
if pyproject.toml exists OR any .py files:
detected += "python"
if Package.swift exists OR any .swift files:
detected += "swift"
if len(detected) == 0:
STOP → "Could not detect project type. Re-run with --mask '<glob>'."
if len(detected) > 1:
WARN → "Multiple types detected: {detected}. Merging masks."
mask = union of all matched type extensions
if len(detected) == 1:
mask = extensions for the single matched type
Extension table (for building **/*.{...} mask):
| Type | Extensions |
|------|------------|
| typescript | md,mdx,txt,ts,tsx,js,jsx,json,yaml,yml,css |
| rust | md,txt,rs,toml,yaml,yml |
| go | md,txt,go,mod,yaml,yml |
| python | md,txt,py,toml,yaml,yml,cfg |
| swift | md,txt,swift,yaml,yml |
Print detected type(s) and final mask before proceeding.
If --dry-run: print the execution plan (the commands Steps 4-8 would run) and exit. Do not clone, add collections, edit config, or embed.
Use the resolved collection path from Step 1 (called <path> here — $REFS/<name> for github mode, the user's directory for local mode):
qmd collection add <path> --name <name> --mask "<mask>"
If collection already exists (command errors), remove first then re-add:
qmd collection remove <name>
qmd collection add <path> --name <name> --mask "<mask>"
If mode = github: configure the pre-update command. Use a shallow fetch + reset so the read-only mirror stays shallow and never hits a fast-forward failure:
qmd collection update-cmd <name> "git -C $REFS/<name> fetch --depth 1 origin HEAD && git -C $REFS/<name> reset --hard FETCH_HEAD"
If mode = local: check whether the directory is a git repo:
test -d <path>/.git && echo "git" || echo "not-git"
reset --hard a directory the user might be editing): qmd collection update-cmd <name> "git -C <path> pull --ff-only". If it can't fast-forward, /qmd:update surfaces the error and the user resolves it, which is safer than discarding their work./qmd:update will still re-index it on each run (file mtime detection picks up changes).Then write ignore: globs into the YAML for the collection. The CLI has no subcommand to set ignore patterns — edit ${XDG_CONFIG_HOME:-~/.config}/qmd/index.yml directly:
collections:
<name>:
# ... existing fields ...
ignore:
- "out/**"
- "target/**"
- "Pods/**"
- "**/*.test.*"
- "**/*.spec.*"
- "**/__tests__/**"
- "**/__snapshots__/**"
- "**/fixtures/**"
What qmd already excludes by default (do NOT add these):
qmd hardcodes a builtin exclude list of node_modules, .git, .cache, vendor, dist, build (verified in src/cli/qmd.ts:1504 and src/store.ts:1183) AND filters out every path that contains a component starting with . (the dotfile filter at src/cli/qmd.ts:1529). So all of these are already excluded automatically without you doing anything:
node_modules, dist, build, vendor, .git, .cache (hardcoded list).next, .nuxt, .venv, .build, .vscode, .github, __pycache__-style hidden dirs (dotfile filter)Only specify ignore patterns for things qmd doesn't already handle:
out/** (Next.js export), target/** (Rust), bin/**/obj/** (.NET)Pods/** (CocoaPods), Carthage/****/*.test.*, **/*.spec.*, **/__tests__/**, **/__snapshots__/****/fixtures/**, **/__fixtures__/**Adjust to language. For Python repos add *.egg-info/**. For Rust just target/**. For Swift add Pods/**, Carthage/**. The ignore: field was added in upstream qmd 1.1.2. Without it, large monorepos waste embedding budget on test fixtures, build outputs, and snapshots.
The collection's root context is what the MCP server injects with every search hit, so it matters for relevance. Compose a one-sentence description.
If mode = github OR a README.md exists at the collection root: read it, find the first non-empty paragraph after the H1 (skip badges, blank lines, shields.io links), and truncate to one sentence.
If mode = local and no README: ask the user for a one-sentence description. Don't invent one. Don't proceed with a placeholder.
qmd context add qmd://<name>/ "<one-sentence description>"
If --defer-embed: skip. Print: "Embedding deferred. Run /qmd:update to embed."
Otherwise, embed with AST-aware chunking for code files:
qmd embed --chunk-strategy auto
--chunk-strategy auto (added in upstream 2.1.0) uses tree-sitter to chunk .ts/.tsx/.js/.jsx/.mts/.cts/.mjs/.cjs/.py/.go/.rs files at function, class, and import boundaries instead of arbitrary text positions. Markdown and unknown file types stay on regex chunking. This is the right default for code repos. If grammars aren't installed it falls back to regex automatically.
First run downloads models (~2GB) automatically, or manually via qmd pull. If interrupted, retry.
Markdown chunks use 900 tokens with 15% overlap. AST chunks land on natural code boundaries.
qmd status
Confirm: non-zero document count for the new collection. If embed was not deferred, confirm zero pending embeddings.
If embed ran, run a sample search to verify the mask indexed useful content:
qmd search "<keyword from README>" -c <name> -n 3
Zero results after successful embedding means the mask missed the important files. Re-run with --mask to fix.
Report: mode (github/local), collection name, collection path, document count, mask used, ignore patterns set, chunk strategy, and (github mode only) clone type (shallow/full).
qmd embed or qmd pull manually.--depth 1 (default) saves disk but loses git history. Use --full if you need blame or log.git clone will fail without SSH keys or tokens configured. The skill does not handle authentication, that's an environment concern./qmd:add against the local path.--dest and --full are ignored./qmd:update will only re-index (no pull). Re-run /qmd:add <path> if you move the directory.qmd CLI.--mask explicitly for those.--chunk-strategy auto only covers .ts/.tsx/.js/.jsx/.mts/.cts/.mjs/.cjs/.py/.go/.rs. Swift, Java, Kotlin, C/C++, C#, Ruby, and other languages fall back to regex chunking even with --chunk-strategy auto.This skill is idempotent. If it fails partway through, re-run /qmd:add with the same arguments. Step 2 pulls instead of re-cloning, Step 4 removes and re-adds the collection.
| Situation | Recovery |
|-----------|----------|
| Clone failed (network) | Re-run. Step 2 retries the clone |
| Local path not found | Verify the path exists and is a directory; pass an absolute path |
| Detection failed | Re-run with --mask "<glob>" to skip detection |
| Collection add failed | Re-run. Step 4 removes then re-adds |
| Update-cmd failed | Re-run /qmd:collection-update-cmd <name> "<cmd>" |
| Embed interrupted | Run /qmd:embed to resume |
| Wrong mask indexed | Re-run with --mask. The skill is idempotent |
/qmd:update)./qmd:embed).--mask glob must match actual file extensions. Wrong mask = empty collection.--defer-embed and run /qmd:embed separately.tools
Search indexed reference codebases (Convex, Expo, Next.js, Better Auth, Remotion, etc) via the qmd MCP query tool. Use when looking up framework APIs, finding code examples in third-party repos, or answering questions about external libraries that aren't in the current working directory.
tools
--- name: techdebt description: Lightweight end-of-session tech debt sweep. Finds duplicated code, dead exports, unused deps, stale TODOs, and bloated files. Use when user asks for "tech debt", "cleanup", "dead code", "unused exports", "code sweep", or end-of-session hygiene. Do NOT use for full codebase audits (use /audit instead). argument-hint: [--dry-run] [path/to/scope] context: fork agent: general-purpose allowed-tools: - Read - Edit - Glob - Grep - Bash(git *) - Bash(wc *) -
development
Use this skill when the user asks to orchestrate a team, use multiple agents, or parallelize work across Claude Code sessions. Decomposes tasks, spawns teammates, and coordinates execution.
tools
--- name: polish description: Full codebase sweep scoring every file 0-10 on polish potential, refining files scoring 5+ via parallel agents. Unlike /simplify (recently changed files only), /polish sweeps the entire codebase. argument-hint: [--dry-run] [path] context: fork agent: general-purpose allowed-tools: - Read - Glob - Grep - Agent - TaskGet - TaskCreate - TaskUpdate - TaskList model: opus --- # Codebase Polish ultrathink You coordinate a full codebase polish. You score