skills/docsfy-generate-docs/SKILL.md
Use when the user asks to generate documentation with docsfy, create docs for a repository using docsfy, or mentions docsfy documentation generation for any project
npx skillsauth add myk-org/claude-code-config docsfy-generate-docsInstall 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.
Generate AI-powered documentation for a Git repository using the docsfy CLI. The CLI connects to a docsfy server that clones the repo, plans documentation structure, and generates pages using AI.
DO NOT work around issues. Report them so they get fixed.
When you encounter ANY error, unexpected behavior, or reproducible bug during this workflow:
Determine the source:
https://github.com/myk-org/docsfyhttps://github.com/myk-org/claude-code-configAsk the user: "I encountered [issue]. Should I create a GitHub issue for this in [repo]?"
NEVER work around the issue silently. Do not:
After filing (or if user declines), then proceed with the best available path.
The goal is to fix bugs at the source, not accumulate workarounds.
docsfy --help
If not found: uv tool install docsfy
docsfy health
If health check fails, inform the user that the docsfy server is not reachable and stop. The user may need to:
docsfy-serverdocsfy config showdocsfy config initAlways ask the user — NEVER assume or hardcode provider/model:
| Parameter | Required | How to get |
|-----------|----------|------------|
| Repository URL | Yes | Ask user or infer from current repo's git remote |
| AI Provider | Yes | From docsfy models --json → providers array |
| AI Model | Yes | From docsfy models --json → known_models.<provider> array |
| Branch | No | Default: main |
| Output directory | No | Default: docs/ |
| Force regeneration | No | Only offered when re-generating an existing project |
MANDATORY: Use AskUserQuestion to collect ALL parameters. Never skip a question.
Run both commands (can be parallel):
docsfy list --json
docsfy models --json
From docsfy list --json — check if the current repository + branch has been generated before.
Match by comparing BOTH:
repo_urlbranchIf multiple entries match (same repo, same branch, different provider/model), prefer the one
with the most recent last_generated timestamp.
Only consider entries with status equal to ready. Ignore failed, aborted, or in-progress entries.
URL normalization: Remote URLs may differ in format (SSH [email protected]:org/repo.git
vs HTTPS https://github.com/org/repo.git). Normalize both to owner/repo form before
comparing (strip protocol, host, .git suffix).
Key fields per entry:
{
"name": "project-name",
"branch": "main",
"ai_provider": "cursor",
"ai_model": "gpt-5.4-xhigh-fast",
"repo_url": "https://github.com/org/repo.git",
"status": "ready",
"last_generated": "2026-04-01 20:53:36"
}
From docsfy models --json — get available providers and models (same as before):
{
"providers": ["claude", "gemini", "cursor"],
"default_provider": "cursor",
"default_model": "gpt-5.4-xhigh-fast",
"known_models": {
"claude": ["claude-opus-4-6[1m]"],
"cursor": ["composer-2-fast"]
}
}
Extract providers for provider selection and known_models for model selection.
Note: not all providers may have entries in known_models (e.g., gemini above has no models listed).
Fallback behavior:
docsfy models fails or returns empty/malformed JSON → fall back to hardcoded
providers (claude, gemini, cursor) and free-form model input.docsfy list fails → treat as no previous generation (lose smart defaults
but still use models data for provider/model selection).Model is collected in Round 2 because it depends on the provider selected in Round 1.
If a previous generation exists for this repo + branch:
Show the user what was used before and present smart defaults:
Round 1 — Present:
ai_provider as first option "(Previously used)", then other providersdocs/--force since this is a re-generation of an existing project.
Show when it was last generated: "Last generated: {last_generated}"Round 2 — After provider is selected, present models from known_models.<selected_provider>.
If the user kept the same provider as before, show the previous ai_model as first option "(Previously used)".
Mark default_model as "(Recommended)" if it appears in the list and is different from the previous model.
If known_models does not contain the selected provider or the array is empty,
fall back to free-form model input.
If NO previous generation exists:
Round 1 — Ask for provider (from providers array), repository URL, branch,
output directory. Do NOT offer --force (it does nothing for new generations).
Round 2 — After provider is selected, present that provider's models from
known_models.<selected_provider> as AskUserQuestion options.
If the provider matches default_provider and default_model appears in the list,
mark it as "(Recommended)" in the AskUserQuestion options.
If known_models does not contain the selected provider or the array is empty,
fall back to free-form model input.
If the repository URL does not contain github.com, skip the GitHub Pages setup entirely and treat GitHub Pages as not configured.
If the repository is hosted on GitHub, check if GitHub Pages is configured to serve from docs/ on the target branch:
gh api repos/<owner>/<repo>/pages --jq '.source' 2>/dev/null
Yes → Configure GitHub Pages to serve from docs/ on the target branch:
gh api repos/<owner>/<repo>/pages -X POST -f "source[branch]=<branch>" -f "source[path]=/docs"
No → Skip and continue with generation.
docs/ path: no action needed, continue.Track whether GitHub Pages is confirmed to serve from docs/ on the target branch
(either pre-existing or newly set up) — this is needed for Phase 6.
If Pages is configured but serves from a different path and the user chose not to change it,
treat it as not configured for Phase 6 purposes.
Run the generation command using Bash(run_in_background=true) since it is a long-running blocking operation:
docsfy generate <repo_url> --branch <branch> --provider <provider> --model <model> --watch [--force]
--watch for real-time WebSocket progress--force only if user requested force regenerationrun_in_background=true on the Bash tool so the main conversation is not blocked.
You will be notified when the command completes.When the background command completes, check the output for status ready, error, or aborted.
If generation fails, show the error and ask the user how to proceed.
After generation completes (status: ready), create a local branch to isolate docs changes.
Note: This phase assumes the current working directory is the target repository
(the same repo as <repo_url>). If the user provided a URL for a different
repository, inform them that the docs branch will be created in the current
local repository and confirm before proceeding.
Extract <project_name> from the repo URL: strip any trailing / and .git suffix, then take the last path segment (e.g., docsfy from https://github.com/myk-org/docsfy.git).
Before switching branches, check for uncommitted changes:
git status --porcelain
If the working tree is dirty, inform the user and ask whether to stash changes, abort, or continue.
Create the branch:
git fetch origin <branch>
git checkout -B docs/docsfy-<project_name> origin/<branch>
<branch> is the branch parameter from Phase 1.-B (capital B) to create or reset the branch if it already exists from a previous run.This ensures docs changes are on a separate branch, not directly on the current working branch.
docsfy download <project_name> --branch <branch> --provider <provider> --model <model> --output <output_dir>
<project_name> is the same value extracted in Phase 3.
The download creates a nested subdirectory: <output_dir>/<project>-<branch>-<provider>-<model>/. Verify it exists, then flatten so all files are directly under <output_dir>/:
IMPORTANT: Clear existing content first to prevent silent mv failures (see issue #207).
NESTED_DIR="<output_dir>/<project>-<branch>-<provider>-<model>"
OUTPUT_DIR="<output_dir>"
# Verify nested dir exists
if [ ! -d "$NESTED_DIR" ]; then
echo "Error: Expected directory $NESTED_DIR not found"
exit 1
fi
# Clear old content in output dir (preserve the nested dir itself)
find "$OUTPUT_DIR" -mindepth 1 -maxdepth 1 ! -path "$NESTED_DIR" -exec rm -rf {} +
# Move new content (use dotglob to handle hidden files safely)
shopt -s dotglob
mv "$NESTED_DIR"/* "$OUTPUT_DIR"/
shopt -u dotglob
rm -rf "$NESTED_DIR"
If the nested subdirectory does not exist after download, the project name or parameters may not match what was used during generation — surface the error to the user.
After downloading and flattening, scan ALL generated docs for leaked sensitive content before proceeding.
This phase is MANDATORY — never skip it.
Run Grep searches across all files in <output_dir>/ for these patterns:
| Category | Grep Patterns | Notes |
|----------|--------------|-------|
| Private IPs | 192\.168\., 10\.\d+\.\d+\.\d+, 172\.(1[6-9]\|2[0-9]\|3[01])\. | Internal network addresses |
| Localhost | localhost, 127\.0\.0\.1, 0\.0\.0\.0 | Local-only URLs |
| Home paths | /home/\w+, /Users/\w+ | User-specific filesystem paths |
| Email addresses | [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.(com\|org\|io\|net\|dev) | Real email addresses (ignore [email protected] patterns) |
| API key prefixes | sk-, ghp_, gho_, github_pat_, xoxb-, xoxp- | Known secret prefixes |
| Crypto keys | BEGIN.*PRIVATE, ssh-rsa, ssh-ed25519 | Leaked private/public keys |
| Sensitive keywords | password\s*[:=], secret\s*[:=], token\s*[:=], api[_-]key\s*[:=] | Hardcoded credentials (skip if in code examples showing placeholder values) |
| Env file refs | \.env, credentials\.json, \.pem | References to sensitive files |
How to handle findings:
This phase runs ONLY if GitHub Pages is confirmed to serve from docs/ on the target branch (determined in Phase 1).
Show the user the live documentation URL.
Extract <owner> and <repo> from the repository URL, then construct the URL:
<owner>.github.io (org/user pages site):
https://<owner>.github.io/https://<owner>.github.io/<repo>/Display the URL to the user.
Before asking, check if the README is already simplified.
Read README.md in the repository root. Consider it "already simplified" if ALL of these are true:
## API Reference, ## Configuration,
or ## Detailed Usage with more than 3 subsections eachIf unsure whether the README is already simplified, ask the user rather than deciding autonomously.
If already simplified: display "README already points to docs site — no changes needed." and skip.
If NOT simplified (or no README exists), ask the user:
GitHub Pages is serving your docs. Would you like to simplify the project README to point to the docs site?
Yes → Create a simplified version that keeps ONLY:
Remove all other detailed content (API docs, configuration guides, detailed usage, etc.).
No → Skip and continue.
Ask the user via AskUserQuestion if they want to commit, push, and create a PR for the docs changes:
Options:
If Yes:
<output_dir>/ and README.md (if simplified)docs: generate documentation with docsfy (<provider>/<model>)git push -u origin docs/docsfy-<project_name>gh pr create --title "docs: add generated documentation" --body "Generated with docsfy using <provider>/<model>" --base $(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')If Commit only:
git push -u origin docs/docsfy-<project_name>"If No:
docs/docsfy-<project_name>. Commit when ready."Display:
| Command | Purpose |
|---------|---------|
| docsfy generate <url> --watch | Generate docs with live progress |
| docsfy status <name> | Check generation status |
| docsfy download <name> -o <dir> | Download docs to directory |
| docsfy list | List all projects |
| docsfy abort <name> | Abort active generation |
| docsfy health | Check server connectivity |
| docsfy list --json | List all previously generated projects |
| docsfy models --json | List all providers and their available models |
| docsfy config show | Show server profiles |
| docsfy config init | Set up a new server profile |
| Mistake | Fix |
|---------|-----|
| Hardcoding provider/model | Use docsfy models --json to get providers and models; free-form only on failure |
| Skipping health check | Server must be reachable before generating |
| Using local files instead of repo URL | docsfy works with Git repository URLs |
| Forgetting --watch flag | Always use --watch for real-time progress |
| Downloading before ready | Check status is ready before downloading |
| Leaving nested download folder | Flatten after download — move files to output root |
| Downloading before creating branch | Always create a docs branch before downloading |
| Showing docs link without Pages serving docs/ | Only show docs URL if GitHub Pages serves from docs/ on target branch |
| Skipping security scan | Always scan docs for leaked private data before committing |
| Skipping --force when re-running existing project | When a prior generation exists for this repo+branch, always offer --force |
| Offering --force for new projects | Only offer --force when a matching docsfy list entry exists for this repo+branch |
development
Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.
documentation
Fetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
documentation
Maintain the OpenClaw memory wiki vault with deterministic pages, managed blocks, and source-backed updates.
documentation
Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.