---
name: docs-setup
description: |
  Manual skill for managing pre-fetched official documentation for project libraries.
  Use ONLY when user explicitly invokes /docs-setup or says "setup docs",
  "fetch documentation", "update docs", "add library docs", "remove library docs",
  "docs status", or "initialize project docs".
  DO NOT trigger automatically. DO NOT trigger during coding tasks.
allowed-tools:
  - Read
  - Glob
  - Grep
  - Write
  - Bash
  - WebFetch
  - WebSearch
  - mcp__playwright__browser_navigate
  - mcp__playwright__browser_snapshot
  - mcp__playwright__browser_click
  - mcp__playwright__browser_close
  - mcp__playwright__browser_evaluate
  - mcp__playwright__browser_wait_for
  - AskUserQuestion
---

# docs-setup

Manage pre-fetched official documentation for project libraries.

## Subcommands

- `/docs-setup` or `/docs-setup init` — Analyze project dependencies, filter libraries, fetch docs
- `/docs-setup status` — Show current state of fetched docs
- `/docs-setup add <lib>` — Add and fetch docs for a specific library
- `/docs-setup remove <lib>` — Remove docs for a specific library
- `/docs-setup update [lib]` — Re-fetch and update docs (all or specific library)

## Project Type Detection

Scan for dependency files to determine project type:
- **Node.js**: package.json, package-lock.json, pnpm-lock.yaml, yarn.lock
- **Python**: pyproject.toml, requirements.txt, Pipfile, poetry.lock
- **Rust**: Cargo.toml, Cargo.lock
- **Go**: go.mod, go.sum
- **Other**: composer.json (PHP), Gemfile (Ruby), build.gradle (Java/Kotlin)

For **version detection**, prefer lockfiles for exact versions:
- package-lock.json, pnpm-lock.yaml, yarn.lock → exact Node.js versions
- poetry.lock, Pipfile.lock → exact Python versions
- Cargo.lock → exact Rust versions
- go.sum → exact Go versions

Fall back to dependency file version ranges when lockfiles are absent.

## Library Filtering Heuristic

1. Read the well-known-libs skip list from `references/well-known-libs.md` (located in the skill directory — use Glob to find it under `~/.claude/skills/docs-setup/references/`)
2. Exclude libraries that match the skip list (ubiquitous frameworks, utilities, type defs, build tools, linting/testing)
3. Include domain-specific, complex-API, or newer libraries that benefit from pre-fetched docs
4. Present the filtered list to the user for approval with an override option — user can add back excluded libs or remove suggested ones

## Init Flow (`/docs-setup init` or `/docs-setup`)

1. Detect project type and read dependencies
2. Filter libraries using the heuristic
3. Present filtered list for user approval
4. Process approved libraries **one-by-one**:
   a. Find the official docs URL for the library
   b. Confirm docs URL with user
   c. Discover documentation pages (see Page Discovery below)
   d. Present discovered pages grouped by section for user approval
   e. Fetch approved pages
   f. Update state.json
   g. Move to next library

## Page Discovery Workflow

Try these methods in order:

1. **Sitemap**: Fetch `{docs-url}/sitemap.xml` via WebFetch. Parse for documentation page URLs.
2. **Playwright crawl** (if MCP available): Navigate to docs URL, snapshot the page, find sidebar/nav links, extract documentation page URLs. Skip gracefully if Playwright MCP is unavailable.
3. **Manual entry**: As last resort, ask the user to provide documentation URLs.

Group discovered pages by section (e.g., "Getting Started", "API Reference", "Guides"). Present to user for approval — user can select/deselect sections or individual pages.

Populate the `sections` field in state.json from the distinct directory prefixes of discovered page URLs. Derive human-readable names from URL path segments (e.g., `docs/guides` → "Guides").

## Fetching Workflow

For each approved URL:
1. Fetch via WebFetch with this extraction prompt: "Extract the full documentation content. Preserve all code examples, API signatures, parameter descriptions, and return types. Remove navigation, footer, ads. Return clean markdown."
2. Save to `docs/official-docs/{lib}/.../{page-name}.md`, preserving the URL path structure from the documentation site (e.g., `https://orm.drizzle.team/docs/select` → `drizzle-orm/docs/select.md`)
3. Wait 1-2 seconds between fetches to be respectful
4. Log result (success/failure) in state.json

## Update Workflow (`/docs-setup update [lib]`)

1. Re-discover pages from the doc site (sitemap/crawl) — find new pages added since last fetch
2. Re-fetch ALL pages (existing + newly discovered)
3. Compare new content with existing local files — detect diffs
4. Store updated content, overwriting old files
5. Report summary with list of files that have content changes

Example output:
```
Updated drizzle-orm: 47 pages re-fetched, 5 pages changed, 3 new pages found.
Changed files: docs/select.md, docs/insert.md, docs/relations.md, docs/migrate.md, docs/new-feature.md
```

## Version Comparison

- Use full **major.minor.patch** version (e.g., `0.30.1`, `4.1.2`)
- Flag mismatch when the installed version differs from the documented version at any level
- Set status to `"version-mismatch"` in state.json when detected

## state.json Schema

Location: `docs/official-docs/state.json`

```json
{
  "$schema": "docs-setup-state-v1",
  "version": 1,
  "lastUpdated": "2026-03-06T10:30:00Z",
  "projectType": "node",
  "libraries": {
    "drizzle-orm": {
      "installedVersion": "0.30.1",
      "docsVersion": "0.30.1",
      "docsUrl": "https://orm.drizzle.team/docs",
      "fetchedAt": "2026-03-06T10:30:00Z",
      "pageCount": 47,
      "status": "ok",
      "sections": {
        "docs": "Documentation",
        "docs/guides": "Guides"
      },
      "pages": {
        "docs/select": {
          "sourceUrl": "https://orm.drizzle.team/docs/select",
          "localPath": "drizzle-orm/docs/select.md",
          "fetchedAt": "2026-03-06T10:30:00Z",
          "status": "ok"
        }
      }
    }
  }
}
```

Status values: `ok`, `version-mismatch`, `partial` (some pages failed), `error`.
Staleness is derived by docs-use from `fetchedAt` (not stored as status).
Version format: full major.minor.patch (e.g., `"0.30.1"`, `"4.1.2"`).
`sections`: maps directory paths (relative to lib root) to human-readable section names, populated during page discovery.

## Directory Structure

```
project-root/docs/official-docs/
  state.json
  drizzle-orm/
    docs/
      select.md
      insert.md
      relations.md
      joins.md
      ...
  hono/
    docs/
      api/
        routing.md
      guides/
        middleware.md
      ...
```

## Error Handling

- Log failed pages in state.json with `"status": "error"`
- Continue fetching remaining pages after a failure
- Report all failures at the end of the operation
- If Playwright MCP is unavailable, fall back to WebFetch-only discovery (sitemap + manual)
- If a library's docs URL cannot be determined, ask the user

## Notes

- Do not manage .gitignore — leave git decisions to the user
- Create/update state.json on every operation
- state.json is the single source of truth for docs state
